From b30ba5a92be8e6597c0ff9e890d669f4d071d602 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 24 Aug 2011 07:50:13 +0000 Subject: Upcoming TIP implementation: Full support for Unicode 6.0 --- generic/tcl.decls | 10 +- generic/tcl.h | 2 +- generic/tclBinary.c | 13 +- generic/tclCmdMZ.c | 22 ++- generic/tclDecls.h | 20 +-- generic/tclEncoding.c | 49 ++++-- generic/tclExecute.c | 2 +- generic/tclParse.c | 13 +- generic/tclScan.c | 16 +- generic/tclStringObj.c | 8 +- generic/tclUniData.c | 437 ++++++++++++++++++++++++++++++++++++++++++++++++- generic/tclUtf.c | 258 ++++++++++++++++++++++------- tests/encoding.test | 9 +- tests/string.test | 8 +- tests/utf.test | 43 ++++- tools/uniParse.tcl | 40 +++-- 16 files changed, 795 insertions(+), 155 deletions(-) diff --git a/generic/tcl.decls b/generic/tcl.decls index 30a2aca..0d1dfdf 100644 --- a/generic/tcl.decls +++ b/generic/tcl.decls @@ -1148,16 +1148,16 @@ declare 319 { Tcl_QueuePosition position) } declare 320 { - Tcl_UniChar Tcl_UniCharAtIndex(const char *src, int index) + int Tcl_UniCharAtIndex(const char *src, int index) } declare 321 { - Tcl_UniChar Tcl_UniCharToLower(int ch) + int Tcl_UniCharToLower(int ch) } declare 322 { - Tcl_UniChar Tcl_UniCharToTitle(int ch) + int Tcl_UniCharToTitle(int ch) } declare 323 { - Tcl_UniChar Tcl_UniCharToUpper(int ch) + int Tcl_UniCharToUpper(int ch) } declare 324 { int Tcl_UniCharToUtf(int ch, char *buf) @@ -1351,7 +1351,7 @@ declare 380 { int Tcl_GetCharLength(Tcl_Obj *objPtr) } declare 381 { - Tcl_UniChar Tcl_GetUniChar(Tcl_Obj *objPtr, int index) + int Tcl_GetUniChar(Tcl_Obj *objPtr, int index) } declare 382 { Tcl_UniChar *Tcl_GetUnicode(Tcl_Obj *objPtr) diff --git a/generic/tcl.h b/generic/tcl.h index 7370516..611e74e 100644 --- a/generic/tcl.h +++ b/generic/tcl.h @@ -2162,7 +2162,7 @@ typedef struct Tcl_EncodingType { */ #ifndef TCL_UTF_MAX -#define TCL_UTF_MAX 3 +#define TCL_UTF_MAX 4 #endif /* diff --git a/generic/tclBinary.c b/generic/tclBinary.c index 0a340f2..6379fe8 100644 --- a/generic/tclBinary.c +++ b/generic/tclBinary.c @@ -425,7 +425,7 @@ SetByteArrayFromAny( const char *src, *srcEnd; unsigned char *dst; ByteArray *byteArrayPtr; - Tcl_UniChar ch; + Tcl_UniChar ch = 0; if (objPtr->typePtr != &tclByteArrayType) { src = TclGetStringFromObj(objPtr, &length); @@ -433,8 +433,11 @@ SetByteArrayFromAny( byteArrayPtr = ckalloc(BYTEARRAY_SIZE(length)); for (dst = byteArrayPtr->bytes; src < srcEnd; ) { - src += Tcl_UtfToUniChar(src, &ch); - *dst++ = UCHAR(ch); + int n = Tcl_UtfToUniChar(src, &ch); + if (n) { + src += n; + *dst++ = UCHAR(ch); + } } byteArrayPtr->used = dst - byteArrayPtr->bytes; @@ -1209,7 +1212,7 @@ BinaryFormatCmd( badField: { - Tcl_UniChar ch; + Tcl_UniChar ch = 0; char buf[TCL_UTF_MAX + 1]; Tcl_UtfToUniChar(errorString, &ch); @@ -1578,7 +1581,7 @@ BinaryScanCmd( badField: { - Tcl_UniChar ch; + Tcl_UniChar ch = 0; char buf[TCL_UTF_MAX + 1]; Tcl_UtfToUniChar(errorString, &ch); diff --git a/generic/tclCmdMZ.c b/generic/tclCmdMZ.c index e7c7152..42b2847 100644 --- a/generic/tclCmdMZ.c +++ b/generic/tclCmdMZ.c @@ -283,7 +283,7 @@ Tcl_RegexpObjCmd( */ if ((offset == 0) || ((offset > 0) && - (Tcl_GetUniChar(objPtr, offset-1) == (Tcl_UniChar) '\n'))) { + (Tcl_GetUniChar(objPtr, offset-1) == '\n'))) { eflags = 0; } else { eflags = TCL_REG_NOTBOL; @@ -465,7 +465,7 @@ Tcl_RegsubObjCmd( Tcl_RegExp regExpr; Tcl_RegExpInfo info; Tcl_Obj *resultPtr, *subPtr, *objPtr, *startIndex = NULL; - Tcl_UniChar ch, *wsrc, *wfirstChar, *wstring, *wsubspec, *wend; + Tcl_UniChar ch = 0, *wsrc, *wfirstChar, *wstring, *wsubspec, *wend; static const char *const options[] = { "-all", "-nocase", "-expanded", @@ -1011,7 +1011,7 @@ Tcl_SplitObjCmd( int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { - Tcl_UniChar ch; + Tcl_UniChar ch = 0; int len; const char *splitChars; const char *stringPtr; @@ -1096,7 +1096,7 @@ Tcl_SplitObjCmd( } else { const char *element, *p, *splitEnd; int splitLen; - Tcl_UniChar splitChar; + Tcl_UniChar splitChar = 0; /* * Normal case: split on any of a given set of characters. Discard @@ -1425,7 +1425,7 @@ StringIsCmd( Tcl_Obj *const objv[]) /* Argument objects. */ { const char *string1, *end, *stop; - Tcl_UniChar ch; + Tcl_UniChar ch = 0; int (*chcomp)(int) = NULL; /* The UniChar comparison function. */ int i, failat = 0, result = 1, strict = 0, index, length1, length2; Tcl_Obj *objPtr, *failVarObj = NULL; @@ -1710,8 +1710,14 @@ StringIsCmd( } end = string1 + length1; for (; string1 < end; string1 += length2, failat++) { + int fullchar; length2 = TclUtfToUniChar(string1, &ch); - if (!chcomp(ch)) { + fullchar = ch; + if (!length2) { + length2 = TclUtfToUniChar(string1, &ch); + fullchar = (((fullchar & 0x3ff) << 10) | (ch & 0x3ff)) + 0x10000; + } + if (!chcomp(fullchar)) { result = 0; break; } @@ -2363,7 +2369,7 @@ StringStartCmd( int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { - Tcl_UniChar ch; + Tcl_UniChar ch = 0; const char *p, *string; int cur, index, length, numChars; @@ -2424,7 +2430,7 @@ StringEndCmd( int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { - Tcl_UniChar ch; + Tcl_UniChar ch = 0; const char *p, *end, *string; int cur, index, length, numChars; diff --git a/generic/tclDecls.h b/generic/tclDecls.h index 1df7e14..54e426b 100644 --- a/generic/tclDecls.h +++ b/generic/tclDecls.h @@ -945,13 +945,13 @@ EXTERN void Tcl_ThreadAlert(Tcl_ThreadId threadId); EXTERN void Tcl_ThreadQueueEvent(Tcl_ThreadId threadId, Tcl_Event *evPtr, Tcl_QueuePosition position); /* 320 */ -EXTERN Tcl_UniChar Tcl_UniCharAtIndex(const char *src, int index); +EXTERN int Tcl_UniCharAtIndex(const char *src, int index); /* 321 */ -EXTERN Tcl_UniChar Tcl_UniCharToLower(int ch); +EXTERN int Tcl_UniCharToLower(int ch); /* 322 */ -EXTERN Tcl_UniChar Tcl_UniCharToTitle(int ch); +EXTERN int Tcl_UniCharToTitle(int ch); /* 323 */ -EXTERN Tcl_UniChar Tcl_UniCharToUpper(int ch); +EXTERN int Tcl_UniCharToUpper(int ch); /* 324 */ EXTERN int Tcl_UniCharToUtf(int ch, char *buf); /* 325 */ @@ -1103,7 +1103,7 @@ EXTERN void Tcl_SetUnicodeObj(Tcl_Obj *objPtr, /* 380 */ EXTERN int Tcl_GetCharLength(Tcl_Obj *objPtr); /* 381 */ -EXTERN Tcl_UniChar Tcl_GetUniChar(Tcl_Obj *objPtr, int index); +EXTERN int Tcl_GetUniChar(Tcl_Obj *objPtr, int index); /* 382 */ EXTERN Tcl_UniChar * Tcl_GetUnicode(Tcl_Obj *objPtr); /* 383 */ @@ -2162,10 +2162,10 @@ typedef struct TclStubs { Tcl_Obj * (*tcl_SetVar2Ex) (Tcl_Interp *interp, const char *part1, const char *part2, Tcl_Obj *newValuePtr, int flags); /* 317 */ void (*tcl_ThreadAlert) (Tcl_ThreadId threadId); /* 318 */ void (*tcl_ThreadQueueEvent) (Tcl_ThreadId threadId, Tcl_Event *evPtr, Tcl_QueuePosition position); /* 319 */ - Tcl_UniChar (*tcl_UniCharAtIndex) (const char *src, int index); /* 320 */ - Tcl_UniChar (*tcl_UniCharToLower) (int ch); /* 321 */ - Tcl_UniChar (*tcl_UniCharToTitle) (int ch); /* 322 */ - Tcl_UniChar (*tcl_UniCharToUpper) (int ch); /* 323 */ + int (*tcl_UniCharAtIndex) (const char *src, int index); /* 320 */ + int (*tcl_UniCharToLower) (int ch); /* 321 */ + int (*tcl_UniCharToTitle) (int ch); /* 322 */ + int (*tcl_UniCharToUpper) (int ch); /* 323 */ int (*tcl_UniCharToUtf) (int ch, char *buf); /* 324 */ CONST84_RETURN char * (*tcl_UtfAtIndex) (const char *src, int index); /* 325 */ int (*tcl_UtfCharComplete) (const char *src, int length); /* 326 */ @@ -2223,7 +2223,7 @@ typedef struct TclStubs { Tcl_Obj * (*tcl_NewUnicodeObj) (const Tcl_UniChar *unicode, int numChars); /* 378 */ void (*tcl_SetUnicodeObj) (Tcl_Obj *objPtr, const Tcl_UniChar *unicode, int numChars); /* 379 */ int (*tcl_GetCharLength) (Tcl_Obj *objPtr); /* 380 */ - Tcl_UniChar (*tcl_GetUniChar) (Tcl_Obj *objPtr, int index); /* 381 */ + int (*tcl_GetUniChar) (Tcl_Obj *objPtr, int index); /* 381 */ Tcl_UniChar * (*tcl_GetUnicode) (Tcl_Obj *objPtr); /* 382 */ Tcl_Obj * (*tcl_GetRange) (Tcl_Obj *objPtr, int first, int last); /* 383 */ void (*tcl_AppendUnicodeToObj) (Tcl_Obj *objPtr, const Tcl_UniChar *unicode, int length); /* 384 */ diff --git a/generic/tclEncoding.c b/generic/tclEncoding.c index 15411d8..987d2ae 100644 --- a/generic/tclEncoding.c +++ b/generic/tclEncoding.c @@ -2261,8 +2261,11 @@ UtfToUtfProc( const char *srcStart, *srcEnd, *srcClose; const char *dstStart, *dstEnd; int result, numChars; - Tcl_UniChar ch; + Tcl_UniChar *chPtr = (Tcl_UniChar *) statePtr; + if (flags & TCL_ENCODING_START) { + *chPtr = 0; + } result = TCL_OK; srcStart = src; @@ -2311,12 +2314,14 @@ UtfToUtfProc( * incomplete char its byts are made to represent themselves. */ - ch = (unsigned char) *src; + *chPtr = (unsigned char) *src; src += 1; - dst += Tcl_UniCharToUtf(ch, dst); + dst += Tcl_UniCharToUtf(*chPtr, dst); } else { - src += Tcl_UtfToUniChar(src, &ch); - dst += Tcl_UniCharToUtf(ch, dst); + int n = Tcl_UtfToUniChar(src, chPtr); + src += n; + if (!n) numChars--; + dst += Tcl_UniCharToUtf(*chPtr, dst); } } @@ -2372,8 +2377,11 @@ UnicodeToUtfProc( const char *srcStart, *srcEnd; const char *dstEnd, *dstStart; int result, numChars; - Tcl_UniChar ch; + Tcl_UniChar *chPtr = (Tcl_UniChar *) statePtr; + if (flags & TCL_ENCODING_START) { + *chPtr = 0; + } result = TCL_OK; if ((srcLen % sizeof(Tcl_UniChar)) != 0) { result = TCL_CONVERT_MULTIBYTE; @@ -2398,11 +2406,13 @@ UnicodeToUtfProc( * Tcl_UniChar-size data. */ - ch = *(Tcl_UniChar *)src; - if (ch && ch < 0x80) { - *dst++ = (ch & 0xFF); + *chPtr = *(Tcl_UniChar *)src; + if (*chPtr && *chPtr < 0x80) { + *dst++ = (*chPtr & 0xFF); } else { - dst += Tcl_UniCharToUtf(ch, dst); + int n = Tcl_UniCharToUtf(*chPtr, dst); + dst += n; + if (!n) --numChars;/* Don't count high surrogates */ } src += sizeof(Tcl_UniChar); } @@ -2459,8 +2469,11 @@ UtfToUnicodeProc( { const char *srcStart, *srcEnd, *srcClose, *dstStart, *dstEnd; int result, numChars; - Tcl_UniChar ch; + Tcl_UniChar *chPtr = (Tcl_UniChar *) statePtr; + if (flags & TCL_ENCODING_START) { + *chPtr = 0; + } srcStart = src; srcEnd = src + srcLen; srcClose = srcEnd; @@ -2486,7 +2499,7 @@ UtfToUnicodeProc( result = TCL_CONVERT_NOSPACE; break; } - src += TclUtfToUniChar(src, &ch); + src += TclUtfToUniChar(src, chPtr); /* * Need to handle this in a way that won't cause misalignment by @@ -2495,11 +2508,11 @@ UtfToUnicodeProc( */ #ifdef WORDS_BIGENDIAN - *dst++ = (ch >> 8); - *dst++ = (ch & 0xFF); + *dst++ = (*chPtr >> 8); + *dst++ = (*chPtr & 0xFF); #else - *dst++ = (ch & 0xFF); - *dst++ = (ch >> 8); + *dst++ = (*chPtr & 0xFF); + *dst++ = (*chPtr >> 8); #endif } *srcReadPtr = src - srcStart; @@ -2556,7 +2569,7 @@ TableToUtfProc( const char *srcStart, *srcEnd; const char *dstEnd, *dstStart, *prefixBytes; int result, byte, numChars; - Tcl_UniChar ch; + Tcl_UniChar ch = 0; const unsigned short *const *toUnicode; const unsigned short *pageZero; TableEncodingData *dataPtr = clientData; @@ -2665,7 +2678,7 @@ TableFromUtfProc( { const char *srcStart, *srcEnd, *srcClose; const char *dstStart, *dstEnd, *prefixBytes; - Tcl_UniChar ch; + Tcl_UniChar ch = 0; int result, len, word, numChars; TableEncodingData *dataPtr = clientData; const unsigned short *const *fromUnicode; diff --git a/generic/tclExecute.c b/generic/tclExecute.c index 691c8d7..2df935b 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -4557,7 +4557,7 @@ TEBCresume( valuePtr->bytes+index, 1); } else { char buf[TCL_UTF_MAX]; - Tcl_UniChar ch = Tcl_GetUniChar(valuePtr, index); + int ch = Tcl_GetUniChar(valuePtr, index); /* * This could be: Tcl_NewUnicodeObj((const Tcl_UniChar *)&ch, 1) diff --git a/generic/tclParse.c b/generic/tclParse.c index 3c984bf..66a1575 100644 --- a/generic/tclParse.c +++ b/generic/tclParse.c @@ -808,7 +808,7 @@ TclParseBackslash( * written there. */ { register const char *p = src+1; - Tcl_UniChar unichar; + Tcl_UniChar unichar = 0; int result; int count; char buf[TCL_UTF_MAX]; @@ -958,6 +958,15 @@ TclParseBackslash( if (readPtr != NULL) { *readPtr = count; } + if ((result & 0xF800) == 0xD800) { + /* If result is a surrogate, Tcl_UniCharToUtf will try to + * handle that especially, but we don't want that here. + */ + dst[2] = (char) ((result | 0x80) & 0xBF); + dst[1] = (char) (((result >> 6) | 0x80) & 0xBF); + dst[0] = (char) ((result >> 12) | 0xE0); + return 3; + } return Tcl_UniCharToUtf(result, dst); } @@ -1356,7 +1365,7 @@ Tcl_ParseVarName( register const char *src; unsigned char c; int varIndex, offset; - Tcl_UniChar ch; + Tcl_UniChar ch = 0; unsigned array; if ((numBytes == 0) || (start == NULL)) { diff --git a/generic/tclScan.c b/generic/tclScan.c index d21bfaf..0a6f49f 100644 --- a/generic/tclScan.c +++ b/generic/tclScan.c @@ -72,7 +72,7 @@ BuildCharSet( CharSet *cset, const char *format) /* Points to first char of set. */ { - Tcl_UniChar ch, start; + Tcl_UniChar ch = 0, start; int offset, nranges; const char *end; @@ -257,7 +257,7 @@ ValidateFormat( { int gotXpg, gotSequential, value, i, flags; char *end; - Tcl_UniChar ch; + Tcl_UniChar ch = 0; int objIndex, xpgSize, nspace = numVars; int *nassign = TclStackAlloc(interp, nspace * sizeof(int)); char buf[TCL_UTF_MAX+1]; @@ -570,7 +570,7 @@ Tcl_ScanObjCmd( char op = 0; int width, underflow = 0; Tcl_WideInt wideValue; - Tcl_UniChar ch, sch; + Tcl_UniChar ch = 0, sch = 0; Tcl_Obj **objs = NULL, *objPtr = NULL; int flags; char buf[513]; /* Temporary buffer to hold scanned number @@ -870,9 +870,15 @@ Tcl_ScanObjCmd( * Scan a single Unicode character. */ - string += Tcl_UtfToUniChar(string, &sch); + offset = Tcl_UtfToUniChar(string, &sch); + i = (int)sch; + if (!offset) { + offset = Tcl_UtfToUniChar(string, &sch); + i = (((i<<10) & 0x0FFC00) + 0x10000) + (sch & 0x3FF); + } + string += offset; if (!(flags & SCAN_SUPPRESS)) { - objPtr = Tcl_NewIntObj((int)sch); + objPtr = Tcl_NewIntObj(i); Tcl_IncrRefCount(objPtr); CLANG_ASSERT(objs); objs[objIndex++] = objPtr; diff --git a/generic/tclStringObj.c b/generic/tclStringObj.c index 993a694..5838c0f 100644 --- a/generic/tclStringObj.c +++ b/generic/tclStringObj.c @@ -531,7 +531,7 @@ Tcl_GetCharLength( *---------------------------------------------------------------------- */ -Tcl_UniChar +int Tcl_GetUniChar( Tcl_Obj *objPtr, /* The object to get the Unicode charater * from. */ @@ -548,7 +548,7 @@ Tcl_GetUniChar( if (TclIsPureByteArray(objPtr)) { unsigned char *bytes = Tcl_GetByteArrayFromObj(objPtr, NULL); - return (Tcl_UniChar) bytes[index]; + return (int) bytes[index]; } /* @@ -572,7 +572,7 @@ Tcl_GetUniChar( FillUnicodeRep(objPtr); stringPtr = GET_STRING(objPtr); } - return stringPtr->unicode[index]; + return (int) stringPtr->unicode[index]; } /* @@ -1708,6 +1708,7 @@ Tcl_AppendFormatToObj( const char *span = format, *msg, *errCode; int numBytes = 0, objIndex = 0, gotXpg = 0, gotSequential = 0; int originalLength, limit; + Tcl_UniChar ch = 0; static const char *mixedXPG = "cannot mix \"%\" and \"%n$\" conversion specifiers"; static const char *const badIndex[2] = { @@ -1732,7 +1733,6 @@ Tcl_AppendFormatToObj( int width, gotPrecision, precision, useShort, useWide, useBig; int newXpg, numChars, allocSegment = 0, segmentLimit, segmentNumBytes; Tcl_Obj *segment; - Tcl_UniChar ch; int step = Tcl_UtfToUniChar(format, &ch); format += step; diff --git a/generic/tclUniData.c b/generic/tclUniData.c index 6cff83a..c5343da 100644 --- a/generic/tclUniData.c +++ b/generic/tclUniData.c @@ -151,7 +151,247 @@ static const unsigned short pageMap[] = { 42, 42, 291, 42, 291, 42, 42, 292, 56, 293, 294, 295, 42, 42, 296, 297, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 298, 299, 42, 300, 42, 301, 302, 303, 304, 305, 306, 42, 42, 42, 307, 308, 2, 309, 310, 311, - 312, 313, 314 + 312, 313, 314, 315, 316, 317, 56, 42, 42, 42, 247, 318, 319, 320, 321, + 322, 56, 323, 324, 56, 56, 56, 56, 140, 42, 325, 56, 312, 326, 327, + 56, 328, 42, 329, 56, 330, 331, 332, 42, 333, 334, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 335, 336, 337, 56, 56, 56, 56, 56, 338, 339, 56, + 56, 56, 56, 56, 56, 340, 341, 342, 343, 56, 56, 56, 56, 42, 344, 345, + 346, 56, 56, 56, 56, 42, 42, 347, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 348, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 349, 350, 351, 352, 156, 353, 354, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 355, 56, 56, 56, 56, 320, 320, 320, 356, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 355, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 357, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 358, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 146, 146, 146, 146, + 146, 146, 146, 238, 146, 359, 146, 360, 361, 362, 363, 56, 146, 146, + 364, 56, 56, 56, 56, 56, 146, 146, 365, 366, 56, 56, 56, 56, 367, 368, + 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 367, 368, 380, + 370, 381, 382, 383, 374, 384, 385, 386, 387, 388, 389, 390, 391, 392, + 393, 394, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 146, 395, 146, 146, 237, 396, 397, 56, + 398, 399, 146, 400, 401, 56, 56, 402, 403, 401, 404, 56, 56, 56, 56, + 56, 146, 405, 146, 406, 237, 146, 407, 408, 146, 249, 409, 146, 146, + 146, 146, 410, 146, 363, 323, 411, 56, 56, 56, 412, 413, 414, 415, + 56, 146, 146, 416, 56, 146, 146, 146, 237, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 232, 56, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 123, 42, 42, + 42, 42, 42, 42, 333, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 333 }; /* @@ -723,7 +963,189 @@ static const unsigned char groupMap[] = { 46, 46, 46, 46, 46, 46, 0, 0, 46, 46, 46, 46, 46, 46, 0, 0, 46, 46, 46, 46, 46, 46, 0, 0, 46, 46, 46, 0, 0, 0, 4, 4, 7, 11, 14, 4, 4, 0, 14, 7, 7, 7, 7, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 14, - 14, 0, 0 + 14, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 46, 46, 0, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 3, 3, 14, 0, 0, 0, 0, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 0, 0, 0, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, + 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, + 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, + 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, 117, + 18, 18, 18, 18, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 18, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 85, 0, 0, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 18, 18, 18, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 117, 46, 46, 46, 46, 46, 46, 46, 46, 117, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 3, 46, 46, 46, 46, 0, 0, + 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 3, 117, 117, 117, 117, 117, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 166, 166, 166, 166, 166, 166, 166, 166, + 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, + 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, + 166, 166, 166, 166, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, + 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, + 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, + 167, 167, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 0, 0, 46, 0, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 0, 46, 46, 0, 0, 0, 46, 0, 0, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 0, 3, 18, 18, 18, 18, 18, 18, 18, 18, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 18, 18, 18, 18, 18, 18, 0, 0, 0, 3, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 0, 0, 0, 0, 0, 3, 46, 85, 85, 85, 0, 85, 85, 0, 0, 0, 0, 0, 85, + 85, 85, 85, 46, 46, 46, 46, 0, 46, 46, 46, 0, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 0, 0, 0, 0, 85, 85, 85, 0, 0, 0, 0, 85, 18, 18, 18, + 18, 18, 18, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 0, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 18, 18, 3, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 0, 0, 18, 18, 18, 18, 18, 18, 18, 18, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 0, + 0, 0, 18, 18, 18, 18, 18, 18, 18, 18, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 0, 115, + 85, 115, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, + 85, 85, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 115, 115, + 115, 85, 85, 85, 85, 115, 115, 85, 85, 3, 3, 17, 3, 3, 3, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 117, 117, + 117, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 0, 0, 0, 0, + 0, 0, 0, 46, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, + 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 115, 115, 85, 85, 85, + 14, 14, 14, 115, 115, 115, 115, 115, 115, 17, 17, 17, 17, 17, 17, 17, + 17, 85, 85, 85, 85, 85, 85, 85, 85, 14, 14, 85, 85, 85, 85, 85, 85, + 85, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 85, 85, 85, + 85, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 14, + 14, 85, 85, 85, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 99, + 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 99, 0, 99, 99, 0, 0, 99, 0, 0, 99, 99, 0, 0, 99, 99, 99, 99, 0, 99, + 99, 99, 99, 99, 99, 99, 99, 15, 15, 15, 15, 0, 15, 0, 15, 15, 15, 15, + 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 99, + 99, 0, 99, 99, 99, 99, 0, 0, 99, 99, 99, 99, 99, 99, 99, 99, 0, 99, + 99, 99, 99, 99, 99, 99, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 99, + 99, 0, 99, 99, 99, 99, 0, 99, 99, 99, 99, 99, 0, 99, 0, 0, 0, 99, 99, + 99, 99, 99, 99, 99, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 99, + 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 99, 99, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 99, 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, 15, 15, 15, 15, 15, 15, 0, 0, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 7, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 7, 15, + 15, 15, 15, 15, 15, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 7, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 7, 15, 15, 15, 15, 15, 15, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 7, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 7, 15, 15, 15, 15, + 15, 15, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 7, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 7, 15, 15, 15, 15, 15, 15, 99, 99, 99, 99, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, + 7, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 7, 15, 15, 15, 15, 15, 15, 99, + 15, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, + 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 0, 0, 0, 0, 0, 0, 0, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, + 14, 14, 14, 14, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 14, 14, 14, 14, 14, 0, + 14, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 0, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 0, 14, 14, 14, 14, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, + 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 0, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 14, 14, 14, 0, 14, 0, 14, + 0, 14, 0, 14, 14, 14, 0, 14, 14, 14, 14, 14, 14, 0, 0, 14, 14, 14, + 14, 0, 14, 0, 0, 14, 14, 14, 14, 0, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, + 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 }; /* @@ -767,7 +1189,7 @@ static const int groups[] = { 13, 14, -246316991, -274694079, -270729151, 917569, 917634, 524362, 524426, 852061, 852125, -352026559, -124977087, -351502271, 353730690, 353632386, -353238975, -352223167, -353337279, -353304511, -354385855, - 238026882, -1157758911, -1385430975, 18, 17 + 238026882, -1157758911, -1385430975, 18, 17, 1310785, 1310850 }; /* @@ -775,7 +1197,8 @@ static const int groups[] = { * Unicode character. */ -#define UNICODE_CATEGORY_MASK 0X1F +#define UNICODE_CATEGORY_MASK 0x1F +#define UNICODE_OUT_OF_RANGE 0x2FA20u enum { UNASSIGNED, @@ -817,13 +1240,13 @@ enum { */ #define GetCaseType(info) (((info) & 0xE0) >> 5) -#define GetCategory(info) ((info) & 0x1F) +#define GetCategory(ch) (GetUniCharInfo(ch) & UNICODE_CATEGORY_MASK) #define GetDelta(info) (((info) > 0) ? ((info) >> 15) : (~(~((info)) >> 15))) /* * This macro extracts the information about a character from the - * Unicode character tables. + * Unicode character tables. It may only be used for (unsigned) ch < UNICODE_OUT_OF_RANGE */ -#define GetUniCharInfo(ch) (groups[groupMap[(pageMap[(((int)(ch)) & 0xffff) >> OFFSET_BITS] << OFFSET_BITS) | ((ch) & ((1 << OFFSET_BITS)-1))]]) +#define GetUniCharInfo(ch) (groups[groupMap[(pageMap[((int)(ch)) >> OFFSET_BITS] << OFFSET_BITS) | ((ch) & ((1 << OFFSET_BITS)-1))]]) diff --git a/generic/tclUtf.c b/generic/tclUtf.c index ab26779..5819bcd 100644 --- a/generic/tclUtf.c +++ b/generic/tclUtf.c @@ -122,6 +122,11 @@ UtfCount( return 3; } #if TCL_UTF_MAX > 3 +#if TCL_UTF_MAX == 4 + if (ch <= 0x10FFFF) { + return 4; + } +#else if (ch <= 0x1FFFFF) { return 4; } @@ -132,6 +137,7 @@ UtfCount( return 6; } #endif +#endif return 3; } @@ -173,6 +179,23 @@ Tcl_UniCharToUtf( return 2; } if (ch <= 0xFFFF) { +#if TCL_UTF_MAX == 4 + if ((ch & 0xF800) == 0xD800) { + if (ch & 0x0400) { + /* Low surrogate */ + buf[3] = (char) ((ch | 0x80) & 0xBF); + buf[2] |= (char) (((ch >> 6) | 0x80) & 0x8F); + return 4; + } else { + /* High surrogate */ + ch += 0x40; + buf[2] = (char) (((ch << 4) | 0x80) & 0xB0); + buf[1] = (char) (((ch >> 2) | 0x80) & 0xBF); + buf[0] = (char) (((ch >> 8) | 0xF0) & 0xF7); + return 0; + } + } +#endif three: buf[2] = (char) ((ch | 0x80) & 0xBF); buf[1] = (char) (((ch >> 6) | 0x80) & 0xBF); @@ -181,6 +204,15 @@ Tcl_UniCharToUtf( } #if TCL_UTF_MAX > 3 +#if TCL_UTF_MAX == 4 + if (ch <= 0x10FFFF) { + buf[3] = (char) ((ch | 0x80) & 0xBF); + buf[2] = (char) (((ch >> 6) | 0x80) & 0xBF); + buf[1] = (char) (((ch >> 12) | 0x80) & 0xBF); + buf[0] = (char) ((ch >> 18) | 0xF0); + return 4; + } +#else if (ch <= 0x1FFFFF) { buf[3] = (char) ((ch | 0x80) & 0xBF); buf[2] = (char) (((ch >> 6) | 0x80) & 0xBF); @@ -206,6 +238,7 @@ Tcl_UniCharToUtf( return 6; } #endif +#endif } ch = 0xFFFD; @@ -282,6 +315,16 @@ Tcl_UniCharToUtfDString( * *chPtr is filled with the Tcl_UniChar, and the return value is the * number of bytes from the UTF-8 string that were consumed. * + * If TCL_UTF_MAX == 4, special handling of Surrogate pairs is done: + * + * If the UTF-8 string represents a character outside of the BMP, the + * first call to this function will fill *chPtr with the high surrogate + * and generate a return value of 0. Calling Tcl_UtfToUniChar again + * will produce the low surrogate and a return value of 4. Because *chPtr + * is used to remember whether the high surrogate is already produced, it + * is recommended to initialize the variable it points to as 0 before + * the first call to Tcl_UtfToUniChar is done. + * * Side effects: * None. * @@ -345,8 +388,40 @@ Tcl_UtfToUniChar( *chPtr = (Tcl_UniChar) byte; return 1; +#if TCL_UTF_MAX == 4 + } else if (byte < 0xF8) { + if (((src[1] & 0xC0) == 0x80) && ((src[2] & 0xC0) == 0x80) && ((src[3] & 0xC0) == 0x80)) { + Tcl_UniChar surrogate; + /* + * Four-byte-character lead byte followed by three trail bytes. + */ + + byte = (((byte & 0x07) << 18) | ((src[1] & 0x3F) << 12) + | ((src[2] & 0x3F) << 6) | (src[3] & 0x3F)) - 0x10000; + surrogate = 0xD800 + (byte >> 10); + if (byte & 0x100000) { + /* out of range, < 0x10000 or > 0x10ffff */ + } else if (*chPtr != surrogate) { + /* produce high surrogate, but don't advance source pointer */ + *chPtr = surrogate; + return 0; + } else { + /* produce low surrogate, and advance source pointer */ + *chPtr = (Tcl_UniChar) (0xDC00 | (byte & 0x3FF)); + return 4; + } + } + + /* + * A four-byte-character lead-byte not followed by three trail-bytes + * or representing a character < 0x10000 or > 0x10ffff represents itself. + */ + + *chPtr = (Tcl_UniChar) byte; + return 1; +#endif } -#if TCL_UTF_MAX > 3 +#if TCL_UTF_MAX > 4 { int ch, total, trail; @@ -401,7 +476,7 @@ Tcl_UtfToUniCharDString( * appended to this previously initialized * DString. */ { - Tcl_UniChar *w, *wString; + Tcl_UniChar ch, *w, *wString; const char *p, *end; int oldLength; @@ -423,8 +498,8 @@ Tcl_UtfToUniCharDString( w = wString; end = src + length; for (p = src; p < end; ) { - p += TclUtfToUniChar(p, w); - w++; + p += TclUtfToUniChar(p, &ch); + *w++ = ch; } *w = '\0'; Tcl_DStringSetLength(dsPtr, @@ -488,7 +563,7 @@ Tcl_NumUtfChars( int length) /* The length of the string in bytes, or -1 * for strlen(string). */ { - Tcl_UniChar ch; + Tcl_UniChar ch = 0; register Tcl_UniChar *chPtr = &ch; register int i; @@ -548,7 +623,7 @@ Tcl_UtfFindFirst( int ch) /* The Tcl_UniChar to search for. */ { int len; - Tcl_UniChar find; + Tcl_UniChar find = 0; while (1) { len = TclUtfToUniChar(src, &find); @@ -587,7 +662,7 @@ Tcl_UtfFindLast( int ch) /* The Tcl_UniChar to search for. */ { int len; - Tcl_UniChar find; + Tcl_UniChar find = 0; const char *last; last = NULL; @@ -627,8 +702,7 @@ const char * Tcl_UtfNext( const char *src) /* The current location in the string. */ { - Tcl_UniChar ch; - + Tcl_UniChar ch = 0; return src + TclUtfToUniChar(src, &ch); } @@ -700,16 +774,25 @@ Tcl_UtfPrev( *--------------------------------------------------------------------------- */ -Tcl_UniChar +int Tcl_UniCharAtIndex( register const char *src, /* The UTF-8 string to dereference. */ register int index) /* The position of the desired character. */ { - Tcl_UniChar ch = 0; - - while (index >= 0) { - index--; - src += TclUtfToUniChar(src, &ch); + Tcl_UniChar unichar = 0; + int bytes; + int ch = 0; + + while (index-- >= 0) { + bytes = TclUtfToUniChar(src, &unichar); + ch = unichar; + if (!bytes) { + /* TclUtfToUniChar only returns 0 for chars > 0xffff ! */ + bytes = TclUtfToUniChar(src, &unichar); + /* Combine surrogates */ + ch = (((ch & 0x3ff) << 10) | (unichar & 0x3ff)) + 0x10000; + } + src += bytes; } return ch; } @@ -736,11 +819,16 @@ Tcl_UtfAtIndex( register const char *src, /* The UTF-8 string. */ register int index) /* The position of the desired character. */ { - Tcl_UniChar ch; + Tcl_UniChar ch = 0; + int len; while (index > 0) { - index--; - src += TclUtfToUniChar(src, &ch); + index--; + len = TclUtfToUniChar(src, &ch); + if (!len) { + len = TclUtfToUniChar(src, &ch); + } + src += len; } return src; } @@ -820,7 +908,8 @@ int Tcl_UtfToUpper( char *str) /* String to convert in place. */ { - Tcl_UniChar ch, upChar; + Tcl_UniChar ch = 0; + int upChar; char *src, *dst; int bytes; @@ -831,7 +920,14 @@ Tcl_UtfToUpper( src = dst = str; while (*src) { bytes = TclUtfToUniChar(src, &ch); - upChar = Tcl_UniCharToUpper(ch); + upChar = ch; + if (!bytes) { + /* TclUtfToUniChar only returns 0 for chars > 0xffff ! */ + bytes = TclUtfToUniChar(src, &ch); + /* Combine surrogates */ + upChar = (((upChar & 0x3ff) << 10) | (ch & 0x3ff)) + 0x10000; + } + upChar = Tcl_UniCharToUpper(upChar); /* * To keep badly formed Utf strings from getting inflated by the @@ -873,7 +969,8 @@ int Tcl_UtfToLower( char *str) /* String to convert in place. */ { - Tcl_UniChar ch, lowChar; + Tcl_UniChar ch = 0; + int lowChar; char *src, *dst; int bytes; @@ -884,7 +981,14 @@ Tcl_UtfToLower( src = dst = str; while (*src) { bytes = TclUtfToUniChar(src, &ch); - lowChar = Tcl_UniCharToLower(ch); + lowChar = ch; + if (!bytes) { + /* TclUtfToUniChar only returns 0 for chars > 0xffff ! */ + bytes = TclUtfToUniChar(src, &ch); + /* Combine surrogates */ + lowChar = (((lowChar & 0x3ff) << 10) | (ch & 0x3ff)) + 0x10000; + } + lowChar = Tcl_UniCharToLower(lowChar); /* * To keep badly formed Utf strings from getting inflated by the @@ -927,7 +1031,8 @@ int Tcl_UtfToTitle( char *str) /* String to convert in place. */ { - Tcl_UniChar ch, titleChar, lowChar; + Tcl_UniChar ch = 0; + int titleChar, lowChar; char *src, *dst; int bytes; @@ -940,7 +1045,14 @@ Tcl_UtfToTitle( if (*src) { bytes = TclUtfToUniChar(src, &ch); - titleChar = Tcl_UniCharToTitle(ch); + titleChar = ch; + if (!bytes) { + /* TclUtfToUniChar only returns 0 for chars > 0xffff ! */ + bytes = TclUtfToUniChar(src, &ch); + /* Combine surrogates */ + titleChar = (((titleChar & 0x3ff) << 10) | (ch & 0x3ff)) + 0x10000; + } + titleChar = Tcl_UniCharToTitle(titleChar); if (bytes < UtfCount(titleChar)) { memcpy(dst, src, (size_t) bytes); @@ -952,7 +1064,14 @@ Tcl_UtfToTitle( } while (*src) { bytes = TclUtfToUniChar(src, &ch); - lowChar = Tcl_UniCharToLower(ch); + lowChar = ch; + if (!bytes) { + /* TclUtfToUniChar only returns 0 for chars > 0xffff ! */ + bytes = TclUtfToUniChar(src, &ch); + /* Combine surrogates */ + lowChar = (((lowChar & 0x3ff) << 10) | (ch & 0x3ff)) + 0x10000; + } + lowChar = Tcl_UniCharToLower(lowChar); if (bytes < UtfCount(lowChar)) { memcpy(dst, src, (size_t) bytes); @@ -1036,7 +1155,7 @@ Tcl_UtfNcmp( const char *ct, /* UTF string cs is compared to. */ unsigned long numChars) /* Number of UTF chars to compare. */ { - Tcl_UniChar ch1, ch2; + Tcl_UniChar ch1 = 0, ch2 = 0; /* * Cannot use 'memcmp(cs, ct, n);' as byte representation of \u0000 (the @@ -1084,7 +1203,7 @@ Tcl_UtfNcasecmp( const char *ct, /* UTF string cs is compared to. */ unsigned long numChars) /* Number of UTF chars to compare. */ { - Tcl_UniChar ch1, ch2; + Tcl_UniChar ch1 = 0, ch2 = 0; while (numChars-- > 0) { /* * n must be interpreted as chars, not bytes. @@ -1120,14 +1239,14 @@ Tcl_UtfNcasecmp( *---------------------------------------------------------------------- */ -Tcl_UniChar +int Tcl_UniCharToUpper( int ch) /* Unicode character to convert. */ { - int info = GetUniCharInfo(ch); + int info = (ch < UNICODE_OUT_OF_RANGE) ? GetUniCharInfo(ch) : 0; if (GetCaseType(info) & 0x04) { - return (Tcl_UniChar) (ch - GetDelta(info)); + return ch - GetDelta(info); } else { return ch; } @@ -1149,14 +1268,14 @@ Tcl_UniCharToUpper( *---------------------------------------------------------------------- */ -Tcl_UniChar +int Tcl_UniCharToLower( int ch) /* Unicode character to convert. */ { - int info = GetUniCharInfo(ch); + int info = (ch < UNICODE_OUT_OF_RANGE) ? GetUniCharInfo(ch) : 0; if (GetCaseType(info) & 0x02) { - return (Tcl_UniChar) (ch + GetDelta(info)); + return ch + GetDelta(info); } else { return ch; } @@ -1178,11 +1297,11 @@ Tcl_UniCharToLower( *---------------------------------------------------------------------- */ -Tcl_UniChar +int Tcl_UniCharToTitle( int ch) /* Unicode character to convert. */ { - int info = GetUniCharInfo(ch); + int info = (ch < UNICODE_OUT_OF_RANGE) ? GetUniCharInfo(ch) : 0; int mode = GetCaseType(info); if (mode & 0x1) { @@ -1192,7 +1311,7 @@ Tcl_UniCharToTitle( return (Tcl_UniChar) (ch + ((mode & 0x4) ? -1 : 1)); } else if (mode == 0x4) { - return (Tcl_UniChar) (ch - GetDelta(info)); + return ch - GetDelta(info); } else { return ch; } @@ -1329,9 +1448,10 @@ int Tcl_UniCharIsAlnum( int ch) /* Unicode character to test. */ { - register int category = (GetUniCharInfo(ch) & UNICODE_CATEGORY_MASK); - - return (((ALPHA_BITS | DIGIT_BITS) >> category) & 1); + if (ch > UNICODE_OUT_OF_RANGE) { + return 0; + } + return (((ALPHA_BITS | DIGIT_BITS) >> GetCategory(ch)) & 1); } /* @@ -1354,8 +1474,10 @@ int Tcl_UniCharIsAlpha( int ch) /* Unicode character to test. */ { - register int category = (GetUniCharInfo(ch) & UNICODE_CATEGORY_MASK); - return ((ALPHA_BITS >> category) & 1); + if (ch > UNICODE_OUT_OF_RANGE) { + return 0; + } + return ((ALPHA_BITS >> GetCategory(ch)) & 1); } /* @@ -1378,7 +1500,10 @@ int Tcl_UniCharIsControl( int ch) /* Unicode character to test. */ { - return ((GetUniCharInfo(ch) & UNICODE_CATEGORY_MASK) == CONTROL); + if (ch > UNICODE_OUT_OF_RANGE) { + return 0; + } + return (GetCategory(ch) == CONTROL); } /* @@ -1401,7 +1526,10 @@ int Tcl_UniCharIsDigit( int ch) /* Unicode character to test. */ { - return (GetUniCharInfo(ch)&UNICODE_CATEGORY_MASK) == DECIMAL_DIGIT_NUMBER; + if (ch > UNICODE_OUT_OF_RANGE) { + return 0; + } + return (GetCategory(ch) == DECIMAL_DIGIT_NUMBER); } /* @@ -1424,8 +1552,10 @@ int Tcl_UniCharIsGraph( int ch) /* Unicode character to test. */ { - register int category = (GetUniCharInfo(ch) & UNICODE_CATEGORY_MASK); - return (((PRINT_BITS >> category) & 1) && ((unsigned char) ch != ' ')); + if ((ch == ' ') || (ch > UNICODE_OUT_OF_RANGE)) { + return (ch >= 0xE0100u) && (ch <= 0xE01EFu); + } + return ((PRINT_BITS >> GetCategory(ch)) & 1); } /* @@ -1448,7 +1578,10 @@ int Tcl_UniCharIsLower( int ch) /* Unicode character to test. */ { - return ((GetUniCharInfo(ch) & UNICODE_CATEGORY_MASK) == LOWERCASE_LETTER); + if (ch > UNICODE_OUT_OF_RANGE) { + return 0; + } + return (GetCategory(ch) == LOWERCASE_LETTER); } /* @@ -1471,8 +1604,10 @@ int Tcl_UniCharIsPrint( int ch) /* Unicode character to test. */ { - register int category = (GetUniCharInfo(ch) & UNICODE_CATEGORY_MASK); - return ((PRINT_BITS >> category) & 1); + if (ch > UNICODE_OUT_OF_RANGE) { + return (ch >= 0xE0100u) && (ch <= 0xE01EFu); + } + return ((PRINT_BITS >> GetCategory(ch)) & 1); } /* @@ -1495,8 +1630,10 @@ int Tcl_UniCharIsPunct( int ch) /* Unicode character to test. */ { - register int category = (GetUniCharInfo(ch) & UNICODE_CATEGORY_MASK); - return ((PUNCT_BITS >> category) & 1); + if (ch > UNICODE_OUT_OF_RANGE) { + return 0; + } + return ((PUNCT_BITS >> GetCategory(ch)) & 1); } /* @@ -1519,8 +1656,6 @@ int Tcl_UniCharIsSpace( int ch) /* Unicode character to test. */ { - register int category; - /* * If the character is within the first 127 characters, just use the * standard C function, otherwise consult the Unicode table. @@ -1528,9 +1663,10 @@ Tcl_UniCharIsSpace( if (ch < 0x80) { return TclIsSpaceProc((char)ch); + } else if (ch > UNICODE_OUT_OF_RANGE) { + return 0; } else { - category = (GetUniCharInfo(ch) & UNICODE_CATEGORY_MASK); - return ((SPACE_BITS >> category) & 1); + return ((SPACE_BITS >> GetCategory(ch)) & 1); } } @@ -1554,7 +1690,10 @@ int Tcl_UniCharIsUpper( int ch) /* Unicode character to test. */ { - return ((GetUniCharInfo(ch) & UNICODE_CATEGORY_MASK) == UPPERCASE_LETTER); + if (ch > UNICODE_OUT_OF_RANGE) { + return 0; + } + return (GetCategory(ch) == UPPERCASE_LETTER); } /* @@ -1577,9 +1716,10 @@ int Tcl_UniCharIsWordChar( int ch) /* Unicode character to test. */ { - register int category = (GetUniCharInfo(ch) & UNICODE_CATEGORY_MASK); - - return (((ALPHA_BITS | DIGIT_BITS | CONNECTOR_BITS) >> category) & 1); + if (ch > UNICODE_OUT_OF_RANGE) { + return 0; + } + return (((ALPHA_BITS | DIGIT_BITS | CONNECTOR_BITS) >> GetCategory(ch)) & 1); } /* @@ -1613,7 +1753,7 @@ Tcl_UniCharCaseMatch( * characters. */ int nocase) /* 0 for case sensitive, 1 for insensitive */ { - Tcl_UniChar ch1, p; + Tcl_UniChar ch1 = 0, p; while (1) { p = *uniPattern; diff --git a/tests/encoding.test b/tests/encoding.test index a4f8449..d14d8f0 100644 --- a/tests/encoding.test +++ b/tests/encoding.test @@ -327,9 +327,14 @@ test encoding-16.1 {UnicodeToUtfProc} { set val [encoding convertfrom unicode NN] list $val [format %x [scan $val %c]] } "\u4e4e 4e4e" +test encoding-16.2 {UnicodeToUtfProc} -constraints utf16 -body { + set val [encoding convertfrom unicode "\xd8\xd8\xdc\xdc"] + list $val [format %x [scan $val %c]] +} -result "\U460dc 460dc" -test encoding-17.1 {UtfToUnicodeProc} { -} {} +test encoding-17.1 {UtfToUnicodeProc} -constraints utf16 -body { + encoding convertto unicode "\U460dc" +} -result "\xd8\xd8\xdc\xdc" test encoding-18.1 {TableToUtfProc} { } {} diff --git a/tests/string.test b/tests/string.test index 1a62a66..73640bf 100644 --- a/tests/string.test +++ b/tests/string.test @@ -571,12 +571,12 @@ test string-6.85 {string is control} { } 0 test string-6.86 {string is graph} { ## graph is any print char, except space - list [string is gra -fail var "0123abc!@#\$\u0100 "] $var -} {0 12} + list [string is gra -fail var "0123abc!@#\$\u0100\UE0100\UE01EF "] $var +} {0 14} test string-6.87 {string is print} { ## basically any printable char - list [string is print -fail var "0123abc!@#\$\u0100 \u0010"] $var -} {0 13} + list [string is print -fail var "0123abc!@#\$\u0100 \UE0100\UE01EF\u0010"] $var +} {0 15} test string-6.88 {string is punct} { ## any graph char that isn't alnum list [string is punct -fail var "_!@#\u00beq0"] $var diff --git a/tests/utf.test b/tests/utf.test index 64b5cd4..04bf9f2 100644 --- a/tests/utf.test +++ b/tests/utf.test @@ -15,6 +15,10 @@ if {[lsearch [namespace children] ::tcltest] == -1} { catch {unset x} +# Some tests require support for utf16 + +testConstraint utf16 [expr {[format %c 0x010000] != [bytestring "\xef\xbf\xbd"]}] + test utf-1.1 {Tcl_UniCharToUtf: 1 byte sequences} { set x \x01 } [bytestring "\x01"] @@ -27,10 +31,13 @@ test utf-1.3 {Tcl_UniCharToUtf: 2 byte sequences} { test utf-1.4 {Tcl_UniCharToUtf: 3 byte sequences} { set x "\u4e4e" } [bytestring "\xe4\xb9\x8e"] -test utf-1.5 {Tcl_UniCharToUtf: overflowed Tcl_UniChar} { +test utf-1.5 {Tcl_UniCharToUtf: 4 byte sequences} -constraints utf16 -body { + set x "\U014e4e" +} -result [bytestring "\xf0\x94\xb9\x8e"] +test utf-1.6 {Tcl_UniCharToUtf: overflowed Tcl_UniChar} { format %c 0x110000 } [bytestring "\xef\xbf\xbd"] -test utf-1.6 {Tcl_UniCharToUtf: negative Tcl_UniChar} { +test utf-1.7 {Tcl_UniCharToUtf: negative Tcl_UniChar} { format %c -1 } [bytestring "\xef\xbf\xbd"] @@ -55,9 +62,21 @@ test utf-2.6 {Tcl_UtfToUniChar: lead (3-byte) followed by 1 trail} { test utf-2.7 {Tcl_UtfToUniChar: lead (3-byte) followed by 2 trail} { string length [bytestring "\xE4\xb9\x8e"] } {1} -test utf-2.8 {Tcl_UtfToUniChar: longer UTF sequences not supported} { - string length [bytestring "\xF4\xA2\xA2\xA2"] +test utf-2.8 {Tcl_UtfToUniChar: lead (4-byte) followed by 3 trail} -constraints utf16 -body { + string length [bytestring "\xF0\x90\x80\x80"] +} -result {1} +test utf-2.9 {Tcl_UtfToUniChar: lead (4-byte) followed by 3 trail} -constraints utf16 -body { + string length [bytestring "\xF4\x8F\xBF\xBF"] +} -result {1} +test utf-2.10 {Tcl_UtfToUniChar: lead (4-byte) followed by 3 trail, underflow} { + string length [bytestring "\xF0\x8F\xBF\xBF"] } {4} +test utf-2.11 {Tcl_UtfToUniChar: lead (4-byte) followed by 3 trail, overflow} { + string length [bytestring "\xF4\x90\x80\x80"] +} {4} +test utf-2.12 {Tcl_UtfToUniChar: longer UTF sequences not supported} { + string length [bytestring "\xF8\xA2\xA2\xA2\xA2"] +} {5} test utf-3.1 {Tcl_UtfCharComplete} { } {} @@ -190,8 +209,16 @@ bsCheck \Ua1 161 bsCheck \U4e21 20001 bsCheck \U004e21 20001 bsCheck \U00004e21 20001 -bsCheck \U00110000 65533 -bsCheck \Uffffffff 65533 +bsCheck \U0000004e21 78 +if {[testConstraint utf16]} { + bsCheck \U00110000 69632 + bsCheck \U01100000 69632 + bsCheck \U11000000 69632 + bsCheck \U0010FFFF 1114111 + bsCheck \U010FFFF0 1114111 + bsCheck \U10FFFF00 1114111 + bsCheck \UFFFFFFFF 1048575 +} test utf-11.1 {Tcl_UtfToUpper} { string toupper {} @@ -259,8 +286,8 @@ test utf-16.1 {Tcl_UniCharToLower, negative delta} { string tolower aA } aa test utf-16.2 {Tcl_UniCharToLower, positive delta} { - string tolower \u0178\u00ff\uA78D -} \u00ff\u00ff\u0265 + string tolower \u0178\u00ff\uA78D\U10400 +} \u00ff\u00ff\u0265\U10428 test utf-17.1 {Tcl_UniCharToLower, no delta} { string tolower ! diff --git a/tools/uniParse.tcl b/tools/uniParse.tcl index 8576f9d..cce2138 100644 --- a/tools/uniParse.tcl +++ b/tools/uniParse.tcl @@ -44,17 +44,17 @@ proc uni::getValue {items index} { # Extract character info set category [lindex $items 2] - if {[scan [lindex $items 12] %4x toupper] == 1} { + if {[scan [lindex $items 12] %6x toupper] == 1} { set toupper [expr {$index - $toupper}] } else { set toupper {} } - if {[scan [lindex $items 13] %4x tolower] == 1} { + if {[scan [lindex $items 13] %6x tolower] == 1} { set tolower [expr {$tolower - $index}] } else { set tolower {} } - if {[scan [lindex $items 14] %4x totitle] == 1} { + if {[scan [lindex $items 14] %6x totitle] == 1} { set totitle [expr {$index - $totitle}] } else { set totitle {} @@ -101,25 +101,30 @@ proc uni::buildTables {data} { variable pMap {} variable pages {} variable groups {{0,,,}} + variable next 0 set info {} ;# temporary page info set mask [expr {(1 << $shift) - 1}] - set next 0 - foreach line [split $data \n] { if {$line eq ""} { - set line "FFFF;;Cn;0;ON;;;;;N;;;;;\n" + if {!($next & $mask)} { + # next character is already on page boundary + continue + } + # fill remaining page + set line [format %X [expr {($next-1)|$mask}]] + append line ";;Cn;0;ON;;;;;N;;;;;\n" } set items [split $line \;] scan [lindex $items 0] %x index - if {$index > 0xFFFF} then { - # Ignore non-BMP characters, as long as Tcl doesn't support them + if {$index >= 0xE0000} then { + # Ignore those characters, as they don't have case variants anyway continue } - set index [format 0x%0.4x $index] + set index [format %d $index] set gIndex [getGroup [getValue $items $index]] @@ -167,6 +172,7 @@ proc uni::main {} { variable groups variable shift variable titleCount + variable next if {$argc != 2} { puts stderr "\nusage: $argv0 \n" @@ -178,7 +184,7 @@ proc uni::main {} { buildTables $data puts "X = [llength $pMap] Y= [llength $pages] A= [llength $groups]" - set size [expr {[llength $pMap] + [llength $pages]*(1<<$shift)}] + set size [expr {[llength $pMap]*2 + [llength $pages]*(1<<$shift)}] puts "shift = $shift, space = $size" puts "title case count = $titleCount" @@ -316,15 +322,17 @@ static const int groups\[\] = {" } } puts $f $line - puts $f "}; + puts -nonewline $f "}; /* * The following constants are used to determine the category of a * Unicode character. */ -#define UNICODE_CATEGORY_MASK 0X1F - +#define UNICODE_CATEGORY_MASK 0x1F +#define UNICODE_OUT_OF_RANGE " + puts $f [format 0x%Xu $next] + puts $f " enum { UNASSIGNED, UPPERCASE_LETTER, @@ -365,15 +373,15 @@ enum { */ #define GetCaseType(info) (((info) & 0xE0) >> 5) -#define GetCategory(info) ((info) & 0x1F) +#define GetCategory(ch) (GetUniCharInfo(ch) & UNICODE_CATEGORY_MASK) #define GetDelta(info) (((info) > 0) ? ((info) >> 15) : (~(~((info)) >> 15))) /* * This macro extracts the information about a character from the - * Unicode character tables. + * Unicode character tables. It may only be used for (unsigned) ch < UNICODE_OUT_OF_RANGE */ -#define GetUniCharInfo(ch) (groups\[groupMap\[(pageMap\[(((int)(ch)) & 0xffff) >> OFFSET_BITS\] << OFFSET_BITS) | ((ch) & ((1 << OFFSET_BITS)-1))\]\]) +#define GetUniCharInfo(ch) (groups\[groupMap\[(pageMap\[((int)(ch)) >> OFFSET_BITS\] << OFFSET_BITS) | ((ch) & ((1 << OFFSET_BITS)-1))\]\]) " close $f -- cgit v0.12 From 39ad9eb8f353ef5355a28d18349f6319bf9fcc9c Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 24 Aug 2011 08:32:39 +0000 Subject: fix tests utf-2.8 and utf-2.9 --- generic/tclUtf.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/generic/tclUtf.c b/generic/tclUtf.c index 5819bcd..14061df 100644 --- a/generic/tclUtf.c +++ b/generic/tclUtf.c @@ -564,8 +564,7 @@ Tcl_NumUtfChars( * for strlen(string). */ { Tcl_UniChar ch = 0; - register Tcl_UniChar *chPtr = &ch; - register int i; + register int i, n; /* * The separate implementations are faster. @@ -577,18 +576,23 @@ Tcl_NumUtfChars( i = 0; if (length < 0) { while (*src != '\0') { - src += TclUtfToUniChar(src, chPtr); + n = TclUtfToUniChar(src, &ch); + if (!n) { + n = Tcl_UtfToUniChar(src, &ch); + } + src += n; i++; } } else { - register int n; - while (length > 0) { if (UCHAR(*src) < 0xC0) { length--; src++; } else { - n = Tcl_UtfToUniChar(src, chPtr); + n = Tcl_UtfToUniChar(src, &ch); + if (!n) { + n = Tcl_UtfToUniChar(src, &ch); + } length -= n; src += n; } @@ -823,7 +827,7 @@ Tcl_UtfAtIndex( int len; while (index > 0) { - index--; + index--; len = TclUtfToUniChar(src, &ch); if (!len) { len = TclUtfToUniChar(src, &ch); -- cgit v0.12 From 21d8621d11bcad78438d51a17dd685e4c8c3c557 Mon Sep 17 00:00:00 2001 From: dkf Date: Sun, 7 Jul 2013 11:15:08 +0000 Subject: Added a mechanism for discovering the "type" of a command. --- generic/tclBasic.c | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++- generic/tclCmdIL.c | 47 ++++++++++++++++++++++++++ generic/tclEnsemble.c | 41 +++++++++++------------ generic/tclInt.h | 15 +++++++++ generic/tclInterp.c | 33 ++++++++---------- generic/tclNamesp.c | 10 +++--- generic/tclOO.c | 29 +++++++--------- 7 files changed, 203 insertions(+), 64 deletions(-) diff --git a/generic/tclBasic.c b/generic/tclBasic.c index b2a505a..94697b2 100644 --- a/generic/tclBasic.c +++ b/generic/tclBasic.c @@ -74,7 +74,18 @@ typedef struct { } CancelInfo; static Tcl_HashTable cancelTable; static int cancelTableInitialized = 0; /* 0 means not yet initialized. */ -TCL_DECLARE_MUTEX(cancelLock) +TCL_DECLARE_MUTEX(cancelLock); + +/* + * Table used to map command implementation functions to a human-readable type + * name, for [info type]. The keys in the table are function addresses, and + * the values in the table are static char* containing strings in Tcl's + * internal encoding (almost UTF-8). + */ + +static Tcl_HashTable commandTypeTable; +static int commandTypeInit = 0; +TCL_DECLARE_MUTEX(commandTypeLock); /* * Declarations for managing contexts for non-recursive coroutines. Contexts @@ -430,6 +441,13 @@ TclFinalizeEvaluation(void) cancelTableInitialized = 0; } Tcl_MutexUnlock(&cancelLock); + + Tcl_MutexLock(&commandTypeLock); + if (commandTypeInit) { + Tcl_DeleteHashTable(&commandTypeTable); + commandTypeInit = 0; + } + Tcl_MutexUnlock(&commandTypeLock); } /* @@ -507,6 +525,16 @@ Tcl_CreateInterp(void) Tcl_MutexUnlock(&cancelLock); } + if (commandTypeInit == 0) { + TclRegisterCommandTypeName(TclObjInterpProc, "proc"); + TclRegisterCommandTypeName(TclEnsembleImplementationCmd, "ensemble"); + TclRegisterCommandTypeName(TclAliasObjCmd, "alias"); + TclRegisterCommandTypeName(TclSlaveObjCmd, "slave"); + TclRegisterCommandTypeName(TclInvokeImportedCmd, "import"); + TclRegisterCommandTypeName(TclOOPublicObjectCmd, "object"); + TclRegisterCommandTypeName(TclOOPrivateObjectCmd, "privateObject"); + } + /* * Initialize support for namespaces and create the global namespace * (whose name is ""; an alias is "::"). This also initializes the Tcl @@ -995,6 +1023,68 @@ DeleteOpCmdClientData( } /* + * --------------------------------------------------------------------- + * + * TclRegisterCommandTypeName, TclGetCommandTypeName -- + * + * Command type registration and lookup mechanism. Everything is keyed by + * the Tcl_ObjCmdProc for the command, and that is used as the *key* into + * the hash table that maps to constant strings that are names. (It is + * recommended that those names be ASCII.) + * + * --------------------------------------------------------------------- + */ + +void +TclRegisterCommandTypeName( + Tcl_ObjCmdProc *implementationProc, + const char *nameStr) +{ + Tcl_HashEntry *hPtr; + + Tcl_MutexLock(&commandTypeLock); + if (commandTypeInit == 0) { + Tcl_InitHashTable(&commandTypeTable, TCL_ONE_WORD_KEYS); + commandTypeInit = 1; + } + if (nameStr != NULL) { + int isNew; + + hPtr = Tcl_CreateHashEntry(&commandTypeTable, + (void *) implementationProc, &isNew); + Tcl_SetHashValue(hPtr, (void *) nameStr); + } else { + hPtr = Tcl_FindHashEntry(&commandTypeTable, + (void *) implementationProc); + if (hPtr != NULL) { + Tcl_DeleteHashEntry(hPtr); + } + } + Tcl_MutexUnlock(&commandTypeLock); +} + +const char * +TclGetCommandTypeName( + Tcl_Command command) +{ + Command *cmdPtr = (Command *) command; + const char *name = "native"; + + Tcl_MutexLock(&commandTypeLock); + if (commandTypeInit) { + Tcl_HashEntry *hPtr = Tcl_FindHashEntry(&commandTypeTable, + (void *) cmdPtr->objProc); + + if (hPtr && Tcl_GetHashValue(hPtr)) { + name = (const char *) Tcl_GetHashValue(hPtr); + } + } + Tcl_MutexUnlock(&commandTypeLock); + + return name; +} + +/* *---------------------------------------------------------------------- * * TclHideUnsafeCommands -- diff --git a/generic/tclCmdIL.c b/generic/tclCmdIL.c index 0e33392..1b6f9c1 100644 --- a/generic/tclCmdIL.c +++ b/generic/tclCmdIL.c @@ -146,6 +146,8 @@ static int InfoScriptCmd(ClientData dummy, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); static int InfoSharedlibCmd(ClientData dummy, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); +static int InfoTypeCmd(ClientData dummy, Tcl_Interp *interp, + int objc, Tcl_Obj *const objv[]); static int InfoTclVersionCmd(ClientData dummy, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); static SortElement * MergeLists(SortElement *leftPtr, SortElement *rightPtr, @@ -184,6 +186,7 @@ static const EnsembleImplMap defaultInfoMap[] = { {"script", InfoScriptCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0}, {"sharedlibextension", InfoSharedlibCmd, TclCompileBasic0ArgCmd, NULL, NULL, 0}, {"tclversion", InfoTclVersionCmd, TclCompileBasic0ArgCmd, NULL, NULL, 0}, + {"type", InfoTypeCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0}, {"vars", TclInfoVarsCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0}, {NULL, NULL, NULL, NULL, NULL, 0} }; @@ -2141,6 +2144,50 @@ InfoTclVersionCmd( /* *---------------------------------------------------------------------- * + * InfoTypeCmd -- + * + * Called to implement the "info type" command that returns the type of a + * given command. Handles the following syntax: + * + * info type cmdName + * + * Results: + * Returns TCL_OK if successful and TCL_ERROR if there is an error. + * + * Side effects: + * Returns a type name. If there is an error, the result is an error + * message. + * + *---------------------------------------------------------------------- + */ + +static int +InfoTypeCmd( + ClientData dummy, /* Not used. */ + Tcl_Interp *interp, /* Current interpreter. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument objects. */ +{ + Tcl_Command command; + + if (objc != 2) { + Tcl_WrongNumArgs(interp, 1, objv, "commandName"); + return TCL_ERROR; + } + command = Tcl_FindCommand(interp, Tcl_GetString(objv[1]), NULL, + TCL_LEAVE_ERR_MSG); + if (command == NULL) { + return TCL_ERROR; + } + + Tcl_SetObjResult(interp, + Tcl_NewStringObj(TclGetCommandTypeName(command), -1)); + return TCL_OK; +} + +/* + *---------------------------------------------------------------------- + * * Tcl_JoinObjCmd -- * * This procedure is invoked to process the "join" Tcl command. See the diff --git a/generic/tclEnsemble.c b/generic/tclEnsemble.c index 813e056..e81fa1b 100644 --- a/generic/tclEnsemble.c +++ b/generic/tclEnsemble.c @@ -21,8 +21,6 @@ static inline Tcl_Obj * NewNsObj(Tcl_Namespace *namespacePtr); static inline int EnsembleUnknownCallback(Tcl_Interp *interp, EnsembleConfig *ensemblePtr, int objc, Tcl_Obj *const objv[], Tcl_Obj **prefixObjPtr); -static int NsEnsembleImplementationCmd(ClientData clientData, - Tcl_Interp *interp,int objc,Tcl_Obj *const objv[]); static int NsEnsembleImplementationCmdNR(ClientData clientData, Tcl_Interp *interp,int objc,Tcl_Obj *const objv[]); static void BuildEnsembleConfig(EnsembleConfig *ensemblePtr); @@ -687,7 +685,7 @@ Tcl_CreateEnsemble( ensemblePtr->parameterList = NULL; ensemblePtr->unknownHandler = NULL; ensemblePtr->token = Tcl_NRCreateCommand(interp, name, - NsEnsembleImplementationCmd, NsEnsembleImplementationCmdNR, + TclEnsembleImplementationCmd, NsEnsembleImplementationCmdNR, ensemblePtr, DeleteEnsembleConfig); ensemblePtr->next = (EnsembleConfig *) nsPtr->ensembles; nsPtr->ensembles = (Tcl_Ensemble *) ensemblePtr; @@ -738,7 +736,7 @@ Tcl_SetEnsembleSubcommandList( EnsembleConfig *ensemblePtr; Tcl_Obj *oldList; - if (cmdPtr->objProc != NsEnsembleImplementationCmd) { + if (cmdPtr->objProc != TclEnsembleImplementationCmd) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "command is not an ensemble", -1)); Tcl_SetErrorCode(interp, "TCL", "ENSEMBLE", "NOT_ENSEMBLE", NULL); @@ -814,7 +812,7 @@ Tcl_SetEnsembleParameterList( Tcl_Obj *oldList; int length; - if (cmdPtr->objProc != NsEnsembleImplementationCmd) { + if (cmdPtr->objProc != TclEnsembleImplementationCmd) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "command is not an ensemble", -1)); Tcl_SetErrorCode(interp, "TCL", "ENSEMBLE", "NOT_ENSEMBLE", NULL); @@ -890,7 +888,7 @@ Tcl_SetEnsembleMappingDict( EnsembleConfig *ensemblePtr; Tcl_Obj *oldDict; - if (cmdPtr->objProc != NsEnsembleImplementationCmd) { + if (cmdPtr->objProc != TclEnsembleImplementationCmd) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "command is not an ensemble", -1)); Tcl_SetErrorCode(interp, "TCL", "ENSEMBLE", "NOT_ENSEMBLE", NULL); @@ -989,7 +987,7 @@ Tcl_SetEnsembleUnknownHandler( EnsembleConfig *ensemblePtr; Tcl_Obj *oldList; - if (cmdPtr->objProc != NsEnsembleImplementationCmd) { + if (cmdPtr->objProc != TclEnsembleImplementationCmd) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "command is not an ensemble", -1)); Tcl_SetErrorCode(interp, "TCL", "ENSEMBLE", "NOT_ENSEMBLE", NULL); @@ -1055,7 +1053,7 @@ Tcl_SetEnsembleFlags( EnsembleConfig *ensemblePtr; int wasCompiled; - if (cmdPtr->objProc != NsEnsembleImplementationCmd) { + if (cmdPtr->objProc != TclEnsembleImplementationCmd) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "command is not an ensemble", -1)); Tcl_SetErrorCode(interp, "TCL", "ENSEMBLE", "NOT_ENSEMBLE", NULL); @@ -1131,7 +1129,7 @@ Tcl_GetEnsembleSubcommandList( Command *cmdPtr = (Command *) token; EnsembleConfig *ensemblePtr; - if (cmdPtr->objProc != NsEnsembleImplementationCmd) { + if (cmdPtr->objProc != TclEnsembleImplementationCmd) { if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "command is not an ensemble", -1)); @@ -1173,7 +1171,7 @@ Tcl_GetEnsembleParameterList( Command *cmdPtr = (Command *) token; EnsembleConfig *ensemblePtr; - if (cmdPtr->objProc != NsEnsembleImplementationCmd) { + if (cmdPtr->objProc != TclEnsembleImplementationCmd) { if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "command is not an ensemble", -1)); @@ -1215,7 +1213,7 @@ Tcl_GetEnsembleMappingDict( Command *cmdPtr = (Command *) token; EnsembleConfig *ensemblePtr; - if (cmdPtr->objProc != NsEnsembleImplementationCmd) { + if (cmdPtr->objProc != TclEnsembleImplementationCmd) { if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "command is not an ensemble", -1)); @@ -1256,7 +1254,7 @@ Tcl_GetEnsembleUnknownHandler( Command *cmdPtr = (Command *) token; EnsembleConfig *ensemblePtr; - if (cmdPtr->objProc != NsEnsembleImplementationCmd) { + if (cmdPtr->objProc != TclEnsembleImplementationCmd) { if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "command is not an ensemble", -1)); @@ -1297,7 +1295,7 @@ Tcl_GetEnsembleFlags( Command *cmdPtr = (Command *) token; EnsembleConfig *ensemblePtr; - if (cmdPtr->objProc != NsEnsembleImplementationCmd) { + if (cmdPtr->objProc != TclEnsembleImplementationCmd) { if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "command is not an ensemble", -1)); @@ -1338,7 +1336,7 @@ Tcl_GetEnsembleNamespace( Command *cmdPtr = (Command *) token; EnsembleConfig *ensemblePtr; - if (cmdPtr->objProc != NsEnsembleImplementationCmd) { + if (cmdPtr->objProc != TclEnsembleImplementationCmd) { if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "command is not an ensemble", -1)); @@ -1388,7 +1386,7 @@ Tcl_FindEnsemble( return NULL; } - if (cmdPtr->objProc != NsEnsembleImplementationCmd) { + if (cmdPtr->objProc != TclEnsembleImplementationCmd) { /* * Reuse existing infrastructure for following import link chains * rather than duplicating it. @@ -1396,7 +1394,8 @@ Tcl_FindEnsemble( cmdPtr = (Command *) TclGetOriginalCommand((Tcl_Command) cmdPtr); - if (cmdPtr == NULL || cmdPtr->objProc != NsEnsembleImplementationCmd){ + if (cmdPtr == NULL + || cmdPtr->objProc != TclEnsembleImplementationCmd) { if (flags & TCL_LEAVE_ERR_MSG) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "\"%s\" is not an ensemble command", @@ -1434,11 +1433,11 @@ Tcl_IsEnsemble( { Command *cmdPtr = (Command *) token; - if (cmdPtr->objProc == NsEnsembleImplementationCmd) { + if (cmdPtr->objProc == TclEnsembleImplementationCmd) { return 1; } cmdPtr = (Command *) TclGetOriginalCommand((Tcl_Command) cmdPtr); - if (cmdPtr == NULL || cmdPtr->objProc != NsEnsembleImplementationCmd) { + if (cmdPtr == NULL || cmdPtr->objProc != TclEnsembleImplementationCmd) { return 0; } return 1; @@ -1609,7 +1608,7 @@ TclMakeEnsemble( /* *---------------------------------------------------------------------- * - * NsEnsembleImplementationCmd -- + * TclEnsembleImplementationCmd -- * * Implements an ensemble of commands (being those exported by a * namespace other than the global namespace) as a command with the same @@ -1628,8 +1627,8 @@ TclMakeEnsemble( *---------------------------------------------------------------------- */ -static int -NsEnsembleImplementationCmd( +int +TclEnsembleImplementationCmd( ClientData clientData, Tcl_Interp *interp, int objc, diff --git a/generic/tclInt.h b/generic/tclInt.h index b940225..ce8ef8f 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -3096,6 +3096,10 @@ MODULE_SCOPE int TclTrimLeft(const char *bytes, int numBytes, const char *trim, int numTrim); MODULE_SCOPE int TclTrimRight(const char *bytes, int numBytes, const char *trim, int numTrim); +MODULE_SCOPE const char*TclGetCommandTypeName(Tcl_Command command); +MODULE_SCOPE void TclRegisterCommandTypeName( + Tcl_ObjCmdProc *implementationProc, + const char *nameStr); MODULE_SCOPE int TclUtfCasecmp(const char *cs, const char *ct); MODULE_SCOPE Tcl_Obj * TclpNativeToNormalized(ClientData clientData); MODULE_SCOPE Tcl_Obj * TclpFilesystemPathType(Tcl_Obj *pathPtr); @@ -3886,6 +3890,17 @@ MODULE_SCOPE unsigned TclHashObjKey(Tcl_HashTable *tablePtr, void *keyPtr); MODULE_SCOPE int TclFullFinalizationRequested(void); /* + * Just for the purposes of command-type registration. + */ + +MODULE_SCOPE Tcl_ObjCmdProc TclEnsembleImplementationCmd; +MODULE_SCOPE Tcl_ObjCmdProc TclAliasObjCmd; +MODULE_SCOPE Tcl_ObjCmdProc TclSlaveObjCmd; +MODULE_SCOPE Tcl_ObjCmdProc TclInvokeImportedCmd; +MODULE_SCOPE Tcl_ObjCmdProc TclOOPublicObjectCmd; +MODULE_SCOPE Tcl_ObjCmdProc TclOOPrivateObjectCmd; + +/* *---------------------------------------------------------------- * Macros used by the Tcl core to create and release Tcl objects. * TclNewObj(objPtr) creates a new object denoting an empty string. diff --git a/generic/tclInterp.c b/generic/tclInterp.c index 1a4297b..fe218ff 100644 --- a/generic/tclInterp.c +++ b/generic/tclInterp.c @@ -222,9 +222,6 @@ static int AliasDelete(Tcl_Interp *interp, static int AliasDescribe(Tcl_Interp *interp, Tcl_Interp *slaveInterp, Tcl_Obj *objPtr); static int AliasList(Tcl_Interp *interp, Tcl_Interp *slaveInterp); -static int AliasObjCmd(ClientData dummy, - Tcl_Interp *currentInterp, int objc, - Tcl_Obj *const objv[]); static int AliasNRCmd(ClientData dummy, Tcl_Interp *currentInterp, int objc, Tcl_Obj *const objv[]); @@ -257,8 +254,6 @@ static int SlaveInvokeHidden(Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); static int SlaveMarkTrusted(Tcl_Interp *interp, Tcl_Interp *slaveInterp); -static int SlaveObjCmd(ClientData dummy, Tcl_Interp *interp, - int objc, Tcl_Obj *const objv[]); static void SlaveObjCmdDeleteProc(ClientData clientData); static int SlaveRecursionLimit(Tcl_Interp *interp, Tcl_Interp *slaveInterp, int objc, @@ -1390,7 +1385,7 @@ TclPreventAliasLoop( * create or rename the command. */ - if (cmdPtr->objProc != AliasObjCmd) { + if (cmdPtr->objProc != TclAliasObjCmd) { return TCL_OK; } @@ -1445,7 +1440,7 @@ TclPreventAliasLoop( * Otherwise we do not have a loop. */ - if (aliasCmdPtr->objProc != AliasObjCmd) { + if (aliasCmdPtr->objProc != TclAliasObjCmd) { return TCL_OK; } nextAliasPtr = aliasCmdPtr->objClientData; @@ -1511,12 +1506,12 @@ AliasCreate( if (slaveInterp == masterInterp) { aliasPtr->slaveCmd = Tcl_NRCreateCommand(slaveInterp, - TclGetString(namePtr), AliasObjCmd, AliasNRCmd, aliasPtr, + TclGetString(namePtr), TclAliasObjCmd, AliasNRCmd, aliasPtr, AliasObjCmdDeleteProc); } else { - aliasPtr->slaveCmd = Tcl_CreateObjCommand(slaveInterp, - TclGetString(namePtr), AliasObjCmd, aliasPtr, - AliasObjCmdDeleteProc); + aliasPtr->slaveCmd = Tcl_CreateObjCommand(slaveInterp, + TclGetString(namePtr), TclAliasObjCmd, aliasPtr, + AliasObjCmdDeleteProc); } if (TclPreventAliasLoop(interp, slaveInterp, @@ -1752,7 +1747,7 @@ AliasList( /* *---------------------------------------------------------------------- * - * AliasObjCmd -- + * TclAliasObjCmd -- * * This is the function that services invocations of aliases in a slave * interpreter. One such command exists for each alias. When invoked, @@ -1835,8 +1830,8 @@ AliasNRCmd( return Tcl_NREvalObj(interp, listPtr, flags); } -static int -AliasObjCmd( +int +TclAliasObjCmd( ClientData clientData, /* Alias record. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ @@ -2373,7 +2368,7 @@ SlaveCreate( slavePtr->slaveEntryPtr = hPtr; slavePtr->slaveInterp = slaveInterp; slavePtr->interpCmd = Tcl_CreateObjCommand(masterInterp, path, - SlaveObjCmd, slaveInterp, SlaveObjCmdDeleteProc); + TclSlaveObjCmd, slaveInterp, SlaveObjCmdDeleteProc); Tcl_InitHashTable(&slavePtr->aliasTable, TCL_STRING_KEYS); Tcl_SetHashValue(hPtr, slavePtr); Tcl_SetVar(slaveInterp, "tcl_interactive", "0", TCL_GLOBAL_ONLY); @@ -2441,7 +2436,7 @@ SlaveCreate( /* *---------------------------------------------------------------------- * - * SlaveObjCmd -- + * TclSlaveObjCmd -- * * Command to manipulate an interpreter, e.g. to send commands to it to * be evaluated. One such command exists for each slave interpreter. @@ -2455,8 +2450,8 @@ SlaveCreate( *---------------------------------------------------------------------- */ -static int -SlaveObjCmd( +int +TclSlaveObjCmd( ClientData clientData, /* Slave interpreter. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ @@ -2478,7 +2473,7 @@ SlaveObjCmd( }; if (slaveInterp == NULL) { - Tcl_Panic("SlaveObjCmd: interpreter has been deleted"); + Tcl_Panic("TclSlaveObjCmd: interpreter has been deleted"); } if (objc < 2) { diff --git a/generic/tclNamesp.c b/generic/tclNamesp.c index aed623a..cc2f953 100644 --- a/generic/tclNamesp.c +++ b/generic/tclNamesp.c @@ -89,8 +89,6 @@ static char * EstablishErrorInfoTraces(ClientData clientData, static void FreeNsNameInternalRep(Tcl_Obj *objPtr); static int GetNamespaceFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, Tcl_Namespace **nsPtrPtr); -static int InvokeImportedCmd(ClientData clientData, - Tcl_Interp *interp,int objc,Tcl_Obj *const objv[]); static int InvokeImportedNRCmd(ClientData clientData, Tcl_Interp *interp,int objc,Tcl_Obj *const objv[]); static int NamespaceChildrenCmd(ClientData dummy, @@ -1693,7 +1691,7 @@ DoImport( dataPtr = ckalloc(sizeof(ImportedCmdData)); importedCmd = Tcl_NRCreateCommand(interp, Tcl_DStringValue(&ds), - InvokeImportedCmd, InvokeImportedNRCmd, dataPtr, + TclInvokeImportedCmd, InvokeImportedNRCmd, dataPtr, DeleteImportedCmd); dataPtr->realCmdPtr = cmdPtr; dataPtr->selfPtr = (Command *) importedCmd; @@ -1914,7 +1912,7 @@ TclGetOriginalCommand( /* *---------------------------------------------------------------------- * - * InvokeImportedCmd -- + * TclInvokeImportedCmd -- * * Invoked by Tcl whenever the user calls an imported command that was * created by Tcl_Import. Finds the "real" command (in another @@ -1945,8 +1943,8 @@ InvokeImportedNRCmd( return Tcl_NRCmdSwap(interp, (Tcl_Command) realCmdPtr, objc, objv, 0); } -static int -InvokeImportedCmd( +int +TclInvokeImportedCmd( ClientData clientData, /* Points to the imported command's * ImportedCmdData structure. */ Tcl_Interp *interp, /* Current interpreter. */ diff --git a/generic/tclOO.c b/generic/tclOO.c index cb22de6..1138c99 100644 --- a/generic/tclOO.c +++ b/generic/tclOO.c @@ -84,15 +84,9 @@ static void ReleaseClassContents(Tcl_Interp *interp,Object *oPtr); static inline void SquelchCachedName(Object *oPtr); static void SquelchedNsFirst(ClientData clientData); -static int PublicObjectCmd(ClientData clientData, - Tcl_Interp *interp, int objc, - Tcl_Obj *const *objv); static int PublicNRObjectCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv); -static int PrivateObjectCmd(ClientData clientData, - Tcl_Interp *interp, int objc, - Tcl_Obj *const *objv); static int PrivateNRObjectCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv); @@ -650,10 +644,11 @@ AllocObject( if (!nameStr) { oPtr->command = Tcl_CreateObjCommand(interp, - oPtr->namespacePtr->fullName, PublicObjectCmd, oPtr, NULL); + oPtr->namespacePtr->fullName, TclOOPublicObjectCmd, oPtr, + NULL); } else if (nameStr[0] == ':' && nameStr[1] == ':') { oPtr->command = Tcl_CreateObjCommand(interp, nameStr, - PublicObjectCmd, oPtr, NULL); + TclOOPublicObjectCmd, oPtr, NULL); } else { Tcl_DString buffer; @@ -663,7 +658,7 @@ AllocObject( TclDStringAppendLiteral(&buffer, "::"); Tcl_DStringAppend(&buffer, nameStr, -1); oPtr->command = Tcl_CreateObjCommand(interp, - Tcl_DStringValue(&buffer), PublicObjectCmd, oPtr, NULL); + Tcl_DStringValue(&buffer), TclOOPublicObjectCmd, oPtr, NULL); Tcl_DStringFree(&buffer); } @@ -692,7 +687,7 @@ AllocObject( cmdPtr->hPtr = Tcl_CreateHashEntry(&cmdPtr->nsPtr->cmdTable, "my", &ignored); cmdPtr->refCount = 1; - cmdPtr->objProc = PrivateObjectCmd; + cmdPtr->objProc = TclOOPrivateObjectCmd; cmdPtr->deleteProc = MyDeleted; cmdPtr->objClientData = cmdPtr->deleteData = oPtr; cmdPtr->proc = TclInvokeObjectCommand; @@ -2368,7 +2363,7 @@ Tcl_ObjectSetMetadata( /* * ---------------------------------------------------------------------- * - * PublicObjectCmd, PrivateObjectCmd, TclOOInvokeObject -- + * TclOOPublicObjectCmd, TclOOPrivateObjectCmd, TclOOInvokeObject -- * * Main entry point for object invokations. The Public* and Private* * wrapper functions (implementations of both object instance commands @@ -2378,8 +2373,8 @@ Tcl_ObjectSetMetadata( * ---------------------------------------------------------------------- */ -static int -PublicObjectCmd( +int +TclOOPublicObjectCmd( ClientData clientData, Tcl_Interp *interp, int objc, @@ -2399,8 +2394,8 @@ PublicNRObjectCmd( NULL); } -static int -PrivateObjectCmd( +int +TclOOPrivateObjectCmd( ClientData clientData, Tcl_Interp *interp, int objc, @@ -2784,9 +2779,9 @@ Tcl_GetObjectFromObj( if (cmdPtr == NULL) { goto notAnObject; } - if (cmdPtr->objProc != PublicObjectCmd) { + if (cmdPtr->objProc != TclOOPublicObjectCmd) { cmdPtr = (Command *) TclGetOriginalCommand((Tcl_Command) cmdPtr); - if (cmdPtr == NULL || cmdPtr->objProc != PublicObjectCmd) { + if (cmdPtr == NULL || cmdPtr->objProc != TclOOPublicObjectCmd) { goto notAnObject; } } -- cgit v0.12 From 82132b6c4c3b3779d75abdb7283c82bc90012d82 Mon Sep 17 00:00:00 2001 From: dkf Date: Wed, 10 Jul 2013 13:45:52 +0000 Subject: Some documentation. --- doc/CrtObjCmd.3 | 29 ++++++++++++++++++++++++++++- doc/info.n | 30 ++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 1 deletion(-) diff --git a/doc/CrtObjCmd.3 b/doc/CrtObjCmd.3 index faf8b74..16e7c92 100644 --- a/doc/CrtObjCmd.3 +++ b/doc/CrtObjCmd.3 @@ -8,7 +8,7 @@ .TH Tcl_CreateObjCommand 3 8.0 Tcl "Tcl Library Procedures" .BS .SH NAME -Tcl_CreateObjCommand, Tcl_DeleteCommand, Tcl_DeleteCommandFromToken, Tcl_GetCommandInfo, Tcl_GetCommandInfoFromToken, Tcl_SetCommandInfo, Tcl_SetCommandInfoFromToken, Tcl_GetCommandName, Tcl_GetCommandFullName, Tcl_GetCommandFromObj \- implement new commands in C +Tcl_CreateObjCommand, Tcl_DeleteCommand, Tcl_DeleteCommandFromToken, Tcl_GetCommandInfo, Tcl_GetCommandInfoFromToken, Tcl_SetCommandInfo, Tcl_SetCommandInfoFromToken, Tcl_GetCommandName, Tcl_GetCommandFullName, Tcl_GetCommandFromObj Tcl_RegisterCommandTypeName, Tcl_GetCommandTypeName \- implement new commands in C .SH SYNOPSIS .nf \fB#include \fR @@ -42,6 +42,14 @@ void .sp Tcl_Command \fBTcl_GetCommandFromObj\fR(\fIinterp, objPtr\fR) +.sp +.VS "info type feature" +void +\fBTcl_RegisterCommandTypeName\fR(\fIproc, typeName\fR) +.sp +const char * +\fBTcl_GetCommandTypeName\fR(\fItoken\fR) +.VE "info type feature" .SH ARGUMENTS .AS Tcl_CmdDeleteProc *deleteProc in/out .AP Tcl_Interp *interp in @@ -65,6 +73,9 @@ Pointer to structure containing various information about a Tcl command. .AP Tcl_Obj *objPtr in Value containing the name of a Tcl command. +.AP "const char" *typeName in +Indicates the name of the type of command implementation associated +with a particular \fIproc\fR, or NULL to break the association. .BE .SH DESCRIPTION .PP @@ -296,6 +307,22 @@ is appended to the value specified by \fIobjPtr\fR. specified by the name in a \fBTcl_Obj\fR. The command name is resolved relative to the current namespace. Returns NULL if the command is not found. +.PP +.VS "info type feature" +\fBTcl_RegisterCommandTypeName\fR is used to associate a name (the +\fItypeName\fR argument) with a particular implementation function so that it +can then be looked up with \fBTcl_GetCommandTypeName\fR, which in turn is +called with a command token that information is wanted for and which returns +the name of the type that was registered for the implementation function used +for that command. (The lookup functionality is surfaced virtually directly in Tcl via +\fBinfo type\fR.) If there is no function registered for a particular +function, the result will be the string literal +.QW \fBnative\fR . +The registration of a name can be undone by registering a mapping to NULL +instead. The result from \fBTcl_GetCommandTypeName\fR will be exactly that +string which was registered, and not a copy; use of a compile-time constant +string is \fIstrongly recommended\fR. +.VE "info type feature" .SH "SEE ALSO" Tcl_CreateCommand(3), Tcl_ResetResult(3), Tcl_SetObjResult(3) .SH KEYWORDS diff --git a/doc/info.n b/doc/info.n index e65a083..59ee1a2 100644 --- a/doc/info.n +++ b/doc/info.n @@ -377,6 +377,36 @@ string is returned. Returns the value of the global variable \fBtcl_version\fR; see the \fBtclvars\fR manual entry for more information. .TP +\fBinfo type \fIcommandName\fR +.VS "info type feature" +Returns a description of the kind of command named by \fIcommandName\fR. The +supported types are: +.RS +.IP \fBalias\fR +Indicates that \fIcommandName\fR was created by \fBinterp alias\fR. +.IP \fBensemble\fR +Indicates that \fIcommandName\fR was created by \fBnamespace ensemble\fR. +.IP \fBimport\fR +Indicates that \fIcommandName\fR was created by \fBnamespace import\fR. +.IP \fBnative\fR +Indicates that \fIcommandName\fR was created by the \fBTcl_CreateObjProc\fR +interface directly without further registration of the type of command. +.IP \fBobject\fR +Indicates that \fIcommandName\fR is the public command that represents an +instance of \fBoo::object\fR or one of its subclasses. +.IP \fBprivateObject\fR +Indicates that \fIcommandName\fR is the private command (\fBmy\fR by default) +that represents an instance of \fBoo::object\fR or one of its subclasses. +.IP \fBproc\fR +Indicates that \fIcommandName\fR was created by \fBproc\fR. +.IP \fBslave\fR +Indicates that \fIcommandName\fR was created by \fBinterp create\fR. +.PP +There may be other registered types as well; this is a set that is extensible +at the implementation level with \fBTcl_RegisterCommandTypeName\fR. +.RE +.VE "info type feature" +.TP \fBinfo vars\fR ?\fIpattern\fR? . If \fIpattern\fR is not specified, -- cgit v0.12 From afd4d17b3c5167c365d4072b61c93a80aacafad1 Mon Sep 17 00:00:00 2001 From: dkf Date: Tue, 16 Jul 2013 14:12:40 +0000 Subject: Changed subcommand name following community feedback. --- doc/CrtObjCmd.3 | 10 ++++----- doc/info.n | 60 +++++++++++++++++++++++++++--------------------------- generic/tclCmdIL.c | 14 ++++++------- 3 files changed, 42 insertions(+), 42 deletions(-) diff --git a/doc/CrtObjCmd.3 b/doc/CrtObjCmd.3 index 16e7c92..149d2f6 100644 --- a/doc/CrtObjCmd.3 +++ b/doc/CrtObjCmd.3 @@ -43,13 +43,13 @@ void Tcl_Command \fBTcl_GetCommandFromObj\fR(\fIinterp, objPtr\fR) .sp -.VS "info type feature" +.VS "info cmdtype feature" void \fBTcl_RegisterCommandTypeName\fR(\fIproc, typeName\fR) .sp const char * \fBTcl_GetCommandTypeName\fR(\fItoken\fR) -.VE "info type feature" +.VE "info cmdtype feature" .SH ARGUMENTS .AS Tcl_CmdDeleteProc *deleteProc in/out .AP Tcl_Interp *interp in @@ -308,21 +308,21 @@ specified by the name in a \fBTcl_Obj\fR. The command name is resolved relative to the current namespace. Returns NULL if the command is not found. .PP -.VS "info type feature" +.VS "info cmdtype feature" \fBTcl_RegisterCommandTypeName\fR is used to associate a name (the \fItypeName\fR argument) with a particular implementation function so that it can then be looked up with \fBTcl_GetCommandTypeName\fR, which in turn is called with a command token that information is wanted for and which returns the name of the type that was registered for the implementation function used for that command. (The lookup functionality is surfaced virtually directly in Tcl via -\fBinfo type\fR.) If there is no function registered for a particular +\fBinfo cmdtype\fR.) If there is no function registered for a particular function, the result will be the string literal .QW \fBnative\fR . The registration of a name can be undone by registering a mapping to NULL instead. The result from \fBTcl_GetCommandTypeName\fR will be exactly that string which was registered, and not a copy; use of a compile-time constant string is \fIstrongly recommended\fR. -.VE "info type feature" +.VE "info cmdtype feature" .SH "SEE ALSO" Tcl_CreateCommand(3), Tcl_ResetResult(3), Tcl_SetObjResult(3) .SH KEYWORDS diff --git a/doc/info.n b/doc/info.n index 59ee1a2..42fe6c3 100644 --- a/doc/info.n +++ b/doc/info.n @@ -45,6 +45,36 @@ described in \fBCLASS INTROSPECTION\fR below. Returns a count of the total number of commands that have been invoked in this interpreter. .TP +\fBinfo cmdtype \fIcommandName\fR +.VS "info cmdtype feature" +Returns a description of the kind of command named by \fIcommandName\fR. The +supported types are: +.RS +.IP \fBalias\fR +Indicates that \fIcommandName\fR was created by \fBinterp alias\fR. +.IP \fBensemble\fR +Indicates that \fIcommandName\fR was created by \fBnamespace ensemble\fR. +.IP \fBimport\fR +Indicates that \fIcommandName\fR was created by \fBnamespace import\fR. +.IP \fBnative\fR +Indicates that \fIcommandName\fR was created by the \fBTcl_CreateObjProc\fR +interface directly without further registration of the type of command. +.IP \fBobject\fR +Indicates that \fIcommandName\fR is the public command that represents an +instance of \fBoo::object\fR or one of its subclasses. +.IP \fBprivateObject\fR +Indicates that \fIcommandName\fR is the private command (\fBmy\fR by default) +that represents an instance of \fBoo::object\fR or one of its subclasses. +.IP \fBproc\fR +Indicates that \fIcommandName\fR was created by \fBproc\fR. +.IP \fBslave\fR +Indicates that \fIcommandName\fR was created by \fBinterp create\fR. +.PP +There may be other registered types as well; this is a set that is extensible +at the implementation level with \fBTcl_RegisterCommandTypeName\fR. +.RE +.VE "info cmdtype feature" +.TP \fBinfo commands \fR?\fIpattern\fR? . If \fIpattern\fR is not specified, @@ -377,36 +407,6 @@ string is returned. Returns the value of the global variable \fBtcl_version\fR; see the \fBtclvars\fR manual entry for more information. .TP -\fBinfo type \fIcommandName\fR -.VS "info type feature" -Returns a description of the kind of command named by \fIcommandName\fR. The -supported types are: -.RS -.IP \fBalias\fR -Indicates that \fIcommandName\fR was created by \fBinterp alias\fR. -.IP \fBensemble\fR -Indicates that \fIcommandName\fR was created by \fBnamespace ensemble\fR. -.IP \fBimport\fR -Indicates that \fIcommandName\fR was created by \fBnamespace import\fR. -.IP \fBnative\fR -Indicates that \fIcommandName\fR was created by the \fBTcl_CreateObjProc\fR -interface directly without further registration of the type of command. -.IP \fBobject\fR -Indicates that \fIcommandName\fR is the public command that represents an -instance of \fBoo::object\fR or one of its subclasses. -.IP \fBprivateObject\fR -Indicates that \fIcommandName\fR is the private command (\fBmy\fR by default) -that represents an instance of \fBoo::object\fR or one of its subclasses. -.IP \fBproc\fR -Indicates that \fIcommandName\fR was created by \fBproc\fR. -.IP \fBslave\fR -Indicates that \fIcommandName\fR was created by \fBinterp create\fR. -.PP -There may be other registered types as well; this is a set that is extensible -at the implementation level with \fBTcl_RegisterCommandTypeName\fR. -.RE -.VE "info type feature" -.TP \fBinfo vars\fR ?\fIpattern\fR? . If \fIpattern\fR is not specified, diff --git a/generic/tclCmdIL.c b/generic/tclCmdIL.c index 1b6f9c1..b99b9e2 100644 --- a/generic/tclCmdIL.c +++ b/generic/tclCmdIL.c @@ -146,7 +146,7 @@ static int InfoScriptCmd(ClientData dummy, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); static int InfoSharedlibCmd(ClientData dummy, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); -static int InfoTypeCmd(ClientData dummy, Tcl_Interp *interp, +static int InfoCmdTypeCmd(ClientData dummy, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); static int InfoTclVersionCmd(ClientData dummy, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); @@ -166,6 +166,7 @@ static const EnsembleImplMap defaultInfoMap[] = { {"args", InfoArgsCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0}, {"body", InfoBodyCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0}, {"cmdcount", InfoCmdCountCmd, TclCompileBasic0ArgCmd, NULL, NULL, 0}, + {"cmdtype", InfoCmdTypeCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0}, {"commands", InfoCommandsCmd, TclCompileInfoCommandsCmd, NULL, NULL, 0}, {"complete", InfoCompleteCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0}, {"coroutine", TclInfoCoroutineCmd, TclCompileInfoCoroutineCmd, NULL, NULL, 0}, @@ -186,7 +187,6 @@ static const EnsembleImplMap defaultInfoMap[] = { {"script", InfoScriptCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0}, {"sharedlibextension", InfoSharedlibCmd, TclCompileBasic0ArgCmd, NULL, NULL, 0}, {"tclversion", InfoTclVersionCmd, TclCompileBasic0ArgCmd, NULL, NULL, 0}, - {"type", InfoTypeCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0}, {"vars", TclInfoVarsCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0}, {NULL, NULL, NULL, NULL, NULL, 0} }; @@ -2144,12 +2144,12 @@ InfoTclVersionCmd( /* *---------------------------------------------------------------------- * - * InfoTypeCmd -- + * InfoCmdTypeCmd -- * - * Called to implement the "info type" command that returns the type of a - * given command. Handles the following syntax: + * Called to implement the "info cmdtype" command that returns the type + * of a given command. Handles the following syntax: * - * info type cmdName + * info cmdtype cmdName * * Results: * Returns TCL_OK if successful and TCL_ERROR if there is an error. @@ -2162,7 +2162,7 @@ InfoTclVersionCmd( */ static int -InfoTypeCmd( +InfoCmdTypeCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ -- cgit v0.12 From a6c0992f472a7690735859d61d05cd042ecd43c1 Mon Sep 17 00:00:00 2001 From: dkf Date: Wed, 31 Jul 2013 20:03:43 +0000 Subject: Added tests --- tests/info.test | 95 ++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 88 insertions(+), 7 deletions(-) diff --git a/tests/info.test b/tests/info.test index 3057dd2..ef6bba9 100644 --- a/tests/info.test +++ b/tests/info.test @@ -33,7 +33,7 @@ namespace eval test_ns_info1 { proc p {x} {return "x=$x"} proc q {{y 27} {z {}}} {return "y=$y"} } - + test info-1.1 {info args option} { proc t1 {a bbb c} {return foo} info args t1 @@ -110,7 +110,7 @@ test info-2.6 {info body option, returning list bodies} { proc testinfocmdcount {} { set x [info cmdcount] set y 12345 - set z [info cm] + set z [info cmdc] expr {$z-$x} } test info-3.1 {info cmdcount compiled} { @@ -119,7 +119,7 @@ test info-3.1 {info cmdcount compiled} { test info-3.2 {info cmdcount evaled} -body { set x [info cmdcount] set y 12345 - set z [info cm] + set z [info cmdc] expr {$z-$x} } -cleanup {unset x y z} -result 4 test info-3.3 {info cmdcount evaled} -body [info body testinfocmdcount] -cleanup {unset x y z} -result 4 @@ -678,16 +678,16 @@ test info-21.1 {miscellaneous error conditions} -returnCodes error -body { } -result {wrong # args: should be "info subcommand ?arg ...?"} test info-21.2 {miscellaneous error conditions} -returnCodes error -body { info gorp -} -result {unknown or ambiguous subcommand "gorp": must be args, body, class, cmdcount, commands, complete, coroutine, default, errorstack, exists, frame, functions, globals, hostname, level, library, loaded, locals, nameofexecutable, object, patchlevel, procs, script, sharedlibextension, tclversion, or vars} +} -result {unknown or ambiguous subcommand "gorp": must be args, body, class, cmdcount, cmdtype, commands, complete, coroutine, default, errorstack, exists, frame, functions, globals, hostname, level, library, loaded, locals, nameofexecutable, object, patchlevel, procs, script, sharedlibextension, tclversion, or vars} test info-21.3 {miscellaneous error conditions} -returnCodes error -body { info c -} -result {unknown or ambiguous subcommand "c": must be args, body, class, cmdcount, commands, complete, coroutine, default, errorstack, exists, frame, functions, globals, hostname, level, library, loaded, locals, nameofexecutable, object, patchlevel, procs, script, sharedlibextension, tclversion, or vars} +} -result {unknown or ambiguous subcommand "c": must be args, body, class, cmdcount, cmdtype, commands, complete, coroutine, default, errorstack, exists, frame, functions, globals, hostname, level, library, loaded, locals, nameofexecutable, object, patchlevel, procs, script, sharedlibextension, tclversion, or vars} test info-21.4 {miscellaneous error conditions} -returnCodes error -body { info l -} -result {unknown or ambiguous subcommand "l": must be args, body, class, cmdcount, commands, complete, coroutine, default, errorstack, exists, frame, functions, globals, hostname, level, library, loaded, locals, nameofexecutable, object, patchlevel, procs, script, sharedlibextension, tclversion, or vars} +} -result {unknown or ambiguous subcommand "l": must be args, body, class, cmdcount, cmdtype, commands, complete, coroutine, default, errorstack, exists, frame, functions, globals, hostname, level, library, loaded, locals, nameofexecutable, object, patchlevel, procs, script, sharedlibextension, tclversion, or vars} test info-21.5 {miscellaneous error conditions} -returnCodes error -body { info s -} -result {unknown or ambiguous subcommand "s": must be args, body, class, cmdcount, commands, complete, coroutine, default, errorstack, exists, frame, functions, globals, hostname, level, library, loaded, locals, nameofexecutable, object, patchlevel, procs, script, sharedlibextension, tclversion, or vars} +} -result {unknown or ambiguous subcommand "s": must be args, body, class, cmdcount, cmdtype, commands, complete, coroutine, default, errorstack, exists, frame, functions, globals, hostname, level, library, loaded, locals, nameofexecutable, object, patchlevel, procs, script, sharedlibextension, tclversion, or vars} ## # ### ### ### ######### ######### ######### @@ -2396,6 +2396,87 @@ test info-33.35 {{*}, literal, simple, bytecompiled} -body { } -result {type source line 2389 file info.test cmd {info frame 0} proc ::foo::bar level 0} # ------------------------------------------------------------------------- +namespace eval ::testinfocmdtype { + apply {cmds { + foreach c $cmds {rename $c {}} + } ::testinfocmdtype} [info commands ::testinfocmdtype::*] +} +test info-40.1 {info cmdtype: syntax} -body { + info cmdtype +} -returnCodes error -result {wrong # args: should be "info cmdtype commandName"} +test info-40.2 {info cmdtype: syntax} -body { + info cmdtype foo bar +} -returnCodes error -result {wrong # args: should be "info cmdtype commandName"} +test info-40.3 {info cmdtype: no such command} -body { + info cmdtype ::testinfocmdtype::foo +} -returnCodes error -result {unknown command "::testinfocmdtype::foo"} +test info-40.4 {info cmdtype: native commands} -body { + info cmdtype ::if +} -result native +test info-40.5 {info cmdtype: native commands} -body { + info cmdtype ::puts +} -result native +test info-40.6 {info cmdtype: native commands} -body { + info cmdtype ::yield +} -result native +test info-40.7 {info cmdtype: procedures} -setup { + proc ::testinfocmdtype::someproc {} {} +} -body { + info cmdtype ::testinfocmdtype::someproc +} -cleanup { + rename ::testinfocmdtype::someproc {} +} -result proc +test info-40.8 {info cmdtype: aliases} -setup { + interp alias {} ::testinfocmdtype::somealias {} ::puts +} -body { + info cmdtype ::testinfocmdtype::somealias +} -cleanup { + rename ::testinfocmdtype::somealias {} +} -result alias +test info-40.9 {info cmdtype: imports} -setup { + namespace eval ::testinfocmdtype { + namespace eval foo { + proc bar {} {} + namespace export bar + } + namespace import foo::bar + } +} -body { + info cmdtype ::testinfocmdtype::bar +} -cleanup { + rename ::testinfocmdtype::bar {} + namespace delete ::testinfocmdtype::foo +} -result import +test info-40.10 {info cmdtype: slaves} -setup { + apply {i { + rename $i ::testinfocmdtype::slave + variable ::testinfocmdtype::slave $i + }} [interp create] +} -body { + info cmdtype ::testinfocmdtype::slave +} -cleanup { + interp delete $::testinfocmdtype::slave +} -result slave +test info-40.11 {info cmdtype: objects} -setup { + apply {{} { + oo::object create obj + } ::testinfocmdtype} +} -body { + info cmdtype ::testinfocmdtype::obj +} -cleanup { + ::testinfocmdtype::obj destroy +} -result object +test info-40.12 {info cmdtype: objects} -setup { + apply {{} { + oo::object create obj + } ::testinfocmdtype} +} -body { + info cmdtype [info object namespace ::testinfocmdtype::obj]::my +} -cleanup { + ::testinfocmdtype::obj destroy +} -result privateObject + +# ------------------------------------------------------------------------- unset -nocomplain res # cleanup -- cgit v0.12 From f8e147cb73f34eb486c128a840ceddacdee2677b Mon Sep 17 00:00:00 2001 From: dkf Date: Thu, 1 Aug 2013 06:44:24 +0000 Subject: Improving the test suite for [info cmdtype]. --- tests/info.test | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/tests/info.test b/tests/info.test index ef6bba9..f3517f9 100644 --- a/tests/info.test +++ b/tests/info.test @@ -2475,6 +2475,34 @@ test info-40.12 {info cmdtype: objects} -setup { } -cleanup { ::testinfocmdtype::obj destroy } -result privateObject +test info-40.13 {info cmdtype: ensembles} -setup { + namespace eval ::testinfocmdtype { + namespace eval ensmbl { + proc bar {} {} + namespace export * + namespace ensemble create + } + } +} -body { + info cmdtype ::testinfocmdtype::ensmbl +} -cleanup { + namespace delete ::testinfocmdtype::ensmbl +} -result ensemble +test info-40.14 {info cmdtype: dynamic behavior} -setup { + proc ::testinfocmdtype::foo {} {} +} -body { + namespace eval ::testinfocmdtype { + list [catch {info cmdtype foo}] [catch {info cmdtype bar}] \ + [namespace which foo] [rename foo bar] [namespace which bar] \ + [catch {info cmdtype foo}] [catch {info cmdtype bar}] + } +} -cleanup { + namespace eval ::testinfocmdtype { + catch {rename foo {}} + catch {rename bar {}} + } +} -result {0 1 ::testinfocmdtype::foo {} ::testinfocmdtype::bar 1 0} +namespace delete ::testinfocmdtype # ------------------------------------------------------------------------- unset -nocomplain res -- cgit v0.12 From f370c68d92b4669981b3fa2574a2e32fa1911595 Mon Sep 17 00:00:00 2001 From: dkf Date: Thu, 1 Aug 2013 13:21:04 +0000 Subject: Support type discovery in coroutines. --- generic/tclBasic.c | 8 ++++++-- generic/tclZlib.c | 6 ++++++ tests/info.test | 20 ++++++++++++++++++-- 3 files changed, 30 insertions(+), 4 deletions(-) diff --git a/generic/tclBasic.c b/generic/tclBasic.c index 3dfb639..97cdc51 100644 --- a/generic/tclBasic.c +++ b/generic/tclBasic.c @@ -533,6 +533,7 @@ Tcl_CreateInterp(void) TclRegisterCommandTypeName(TclInvokeImportedCmd, "import"); TclRegisterCommandTypeName(TclOOPublicObjectCmd, "object"); TclRegisterCommandTypeName(TclOOPrivateObjectCmd, "privateObject"); + TclRegisterCommandTypeName(TclNRInterpCoroutine, "coroutine"); } /* @@ -1068,12 +1069,15 @@ TclGetCommandTypeName( Tcl_Command command) { Command *cmdPtr = (Command *) command; + void *procPtr = cmdPtr->objProc; const char *name = "native"; + if (procPtr == NULL) { + procPtr = cmdPtr->nreProc; + } Tcl_MutexLock(&commandTypeLock); if (commandTypeInit) { - Tcl_HashEntry *hPtr = Tcl_FindHashEntry(&commandTypeTable, - (void *) cmdPtr->objProc); + Tcl_HashEntry *hPtr = Tcl_FindHashEntry(&commandTypeTable, procPtr); if (hPtr && Tcl_GetHashValue(hPtr)) { name = (const char *) Tcl_GetHashValue(hPtr); diff --git a/generic/tclZlib.c b/generic/tclZlib.c index 9bceb4c..4907b45 100644 --- a/generic/tclZlib.c +++ b/generic/tclZlib.c @@ -3868,6 +3868,12 @@ TclZlibInit( Tcl_RegisterConfig(interp, "zlib", cfg, "iso8859-1"); /* + * Allow command type introspection to do something sensible with streams. + */ + + TclRegisterCommandTypeName(ZlibStreamCmd, "zlibStream"); + + /* * Formally provide the package as a Tcl built-in. */ diff --git a/tests/info.test b/tests/info.test index f3517f9..7cd6678 100644 --- a/tests/info.test +++ b/tests/info.test @@ -19,9 +19,9 @@ if {{::tcltest} ni [namespace children]} { package require tcltest 2 namespace import -force ::tcltest::* } - ::tcltest::loadTestedCommands catch [list package require -exact Tcltest [info patchlevel]] +testConstraint zlib [llength [info commands zlib]] # Set up namespaces needed to test operation of "info args", "info body", # "info default", and "info procs" with imported procedures. @@ -2488,7 +2488,23 @@ test info-40.13 {info cmdtype: ensembles} -setup { } -cleanup { namespace delete ::testinfocmdtype::ensmbl } -result ensemble -test info-40.14 {info cmdtype: dynamic behavior} -setup { +test info-40.14 {info cmdtype: zlib streams} -constraints zlib -setup { + namespace eval ::testinfocmdtype { + rename [zlib stream gzip] zstream + } +} -body { + info cmdtype ::testinfocmdtype::zstream +} -cleanup { + ::testinfocmdtype::zstream close +} -result zlibStream +test info-40.15 {info cmdtype: coroutines} -setup { + coroutine ::testinfocmdtype::coro eval yield +} -body { + info cmdtype ::testinfocmdtype::coro +} -cleanup { + ::testinfocmdtype::coro +} -result coroutine +test info-40.16 {info cmdtype: dynamic behavior} -setup { proc ::testinfocmdtype::foo {} {} } -body { namespace eval ::testinfocmdtype { -- cgit v0.12 From f96b9f2783963a84c437d1d8abc468d88eac3396 Mon Sep 17 00:00:00 2001 From: dkf Date: Thu, 1 Aug 2013 13:27:37 +0000 Subject: And documentation --- doc/info.n | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/info.n b/doc/info.n index 42fe6c3..819991f 100644 --- a/doc/info.n +++ b/doc/info.n @@ -52,6 +52,8 @@ supported types are: .RS .IP \fBalias\fR Indicates that \fIcommandName\fR was created by \fBinterp alias\fR. +.IP \fBcoroutine\fR +Indicates that \fIcommandName\fR was created by \fBcoroutine\fR. .IP \fBensemble\fR Indicates that \fIcommandName\fR was created by \fBnamespace ensemble\fR. .IP \fBimport\fR @@ -69,6 +71,8 @@ that represents an instance of \fBoo::object\fR or one of its subclasses. Indicates that \fIcommandName\fR was created by \fBproc\fR. .IP \fBslave\fR Indicates that \fIcommandName\fR was created by \fBinterp create\fR. +.IP \fBzlibStream\fR +Indicates that \fIcommandName\fR was created by \fBzlib stream\fR. .PP There may be other registered types as well; this is a set that is extensible at the implementation level with \fBTcl_RegisterCommandTypeName\fR. -- cgit v0.12 From 96dd5baf98be0ff9470e8547c9b3c8905c225621 Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Mon, 1 Sep 2014 07:15:40 +0000 Subject: Adding the ability for the Tcl core to build self-contained Zip-based executables * Integrated a pure-C implementation of ZipVfs * Modified Tcl_AppInit() to look for a zipvfs mounted on the executable --- changes | 2 + generic/tcl.decls | 16 + generic/tclDecls.h | 17 + generic/tclMain.c | 6 + generic/tclStubInit.c | 3 + generic/tclZipVfs.c | 2429 ++++++++++++++++++++++++++++++++++++++++++++ unix/Makefile.in | 15 +- unix/tclAppInit.c | 27 +- win/Makefile.in | 13 +- win/makefile.bc | 1 + win/makefile.vc | 4 + win/tclAppInit.c | 22 + win/tclkit.exe.manifest.in | 51 + win/tclkit.rc | 82 ++ 14 files changed, 2684 insertions(+), 4 deletions(-) create mode 100755 generic/tclZipVfs.c create mode 100644 win/tclkit.exe.manifest.in create mode 100644 win/tclkit.rc diff --git a/changes b/changes index ba0854b..8f11f4b 100644 --- a/changes +++ b/changes @@ -8452,3 +8452,5 @@ include ::oo::class (fellows) 2014-08-25 (TIP 429) New command [string cat] (leitgeb,ferrieux) --- Released 8.6.2, August 27, 2014 --- http://core.tcl.tk/tcl/ for details + +2014-08-29 (TIP TBD) Added a C Implementation of ZipVFS to provide Tcl/Wishkit building capbilities in the core (hypnotoad) \ No newline at end of file diff --git a/generic/tcl.decls b/generic/tcl.decls index 1829249..8352afa 100644 --- a/generic/tcl.decls +++ b/generic/tcl.decls @@ -2326,6 +2326,22 @@ declare 630 { # ----- BASELINE -- FOR -- 8.6.0 ----- # +# ZipVfs +declare 631 { + int Tcl_Zvfs_Init(Tcl_Interp *interp) +} + +declare 632 { + int Tcl_Zvfs_Mount( + Tcl_Interp *interp, + CONST char *zArchive, + CONST char *zMountPoint + ) +} + +declare 633 { + int Tcl_Zvfs_Umount(CONST char *zArchive) +} ############################################################################## # Define the platform specific public Tcl interface. These functions are only diff --git a/generic/tclDecls.h b/generic/tclDecls.h index 91c0add..75dd554 100644 --- a/generic/tclDecls.h +++ b/generic/tclDecls.h @@ -1815,6 +1815,14 @@ EXTERN int Tcl_FSUnloadFile(Tcl_Interp *interp, EXTERN void Tcl_ZlibStreamSetCompressionDictionary( Tcl_ZlibStream zhandle, Tcl_Obj *compressionDictionaryObj); +/* 631 */ +EXTERN int Tcl_Zvfs_Init(Tcl_Interp *interp); +/* 632 */ +EXTERN int Tcl_Zvfs_Mount(Tcl_Interp *interp, + CONST char *zArchive, + CONST char *zMountPoint); +/* 633 */ +EXTERN int Tcl_Zvfs_Umount(CONST char *zArchive); typedef struct { const struct TclPlatStubs *tclPlatStubs; @@ -2481,6 +2489,9 @@ typedef struct TclStubs { void * (*tcl_FindSymbol) (Tcl_Interp *interp, Tcl_LoadHandle handle, const char *symbol); /* 628 */ int (*tcl_FSUnloadFile) (Tcl_Interp *interp, Tcl_LoadHandle handlePtr); /* 629 */ void (*tcl_ZlibStreamSetCompressionDictionary) (Tcl_ZlibStream zhandle, Tcl_Obj *compressionDictionaryObj); /* 630 */ + int (*tcl_Zvfs_Init) (Tcl_Interp *interp); /* 631 */ + int (*tcl_Zvfs_Mount) (Tcl_Interp *interp, CONST char *zArchive, CONST char *zMountPoint); /* 632 */ + int (*tcl_Zvfs_Umount) (CONST char *zArchive); /* 633 */ } TclStubs; extern const TclStubs *tclStubsPtr; @@ -3773,6 +3784,12 @@ extern const TclStubs *tclStubsPtr; (tclStubsPtr->tcl_FSUnloadFile) /* 629 */ #define Tcl_ZlibStreamSetCompressionDictionary \ (tclStubsPtr->tcl_ZlibStreamSetCompressionDictionary) /* 630 */ +#define Tcl_Zvfs_Init \ + (tclStubsPtr->tcl_Zvfs_Init) /* 631 */ +#define Tcl_Zvfs_Mount \ + (tclStubsPtr->tcl_Zvfs_Mount) /* 632 */ +#define Tcl_Zvfs_Umount \ + (tclStubsPtr->tcl_Zvfs_Umount) /* 633 */ #endif /* defined(USE_TCL_STUBS) */ diff --git a/generic/tclMain.c b/generic/tclMain.c index 360f5e9..0bf2e8d 100644 --- a/generic/tclMain.c +++ b/generic/tclMain.c @@ -382,6 +382,12 @@ Tcl_MainEx( */ Tcl_Preserve(interp); + + /* + * Check if this shell has an attached VFS + */ + CONST char *cp=Tcl_GetNameOfExecutable(); + if (appInitProc(interp) != TCL_OK) { chan = Tcl_GetStdChannel(TCL_STDERR); if (chan) { diff --git a/generic/tclStubInit.c b/generic/tclStubInit.c index 7a84cba..b061ba6 100644 --- a/generic/tclStubInit.c +++ b/generic/tclStubInit.c @@ -1412,6 +1412,9 @@ const TclStubs tclStubs = { Tcl_FindSymbol, /* 628 */ Tcl_FSUnloadFile, /* 629 */ Tcl_ZlibStreamSetCompressionDictionary, /* 630 */ + Tcl_Zvfs_Init, /* 631 */ + Tcl_Zvfs_Mount, /* 632 */ + Tcl_Zvfs_Umount, /* 633 */ }; /* !END!: Do not edit above this line. */ diff --git a/generic/tclZipVfs.c b/generic/tclZipVfs.c new file mode 100755 index 0000000..0456b4a --- /dev/null +++ b/generic/tclZipVfs.c @@ -0,0 +1,2429 @@ +/* +** Copyright (c) 2000 D. Richard Hipp +** Copyright (c) 2007 PDQ Interfaces Inc. +** Copyright (c) 2013 Sean Woods +** +** This file is now released under the BSD style license +** outlined in the included file license.terms. +** +************************************************************************* +** A ZIP archive virtual filesystem for Tcl. +** +** This package of routines enables Tcl to use a Zip file as +** a virtual file system. Each of the content files of the Zip +** archive appears as a real file to Tcl. +** +** Well, almost... Actually, the virtual file system is limited +** in a number of ways. The only things you can do are "stat" +** and "read" file content files. You cannot use "cd". +** But it turns out that "stat" +** and "read" are sufficient for most purposes. +** +** This version has been modified to run under Tcl 8.6 +** +*/ +#include "tcl.h" +#include +#include +#include +#include +#include +#include + +#ifdef TCL_FILESYSTEM_VERSION_1 +#define USE_TCL_VFS 1 +#endif + +/* +** Size of the decompression input buffer +*/ +#define COMPR_BUF_SIZE 8192 +static int maptolower=0; +static int openarch=0; /* Set to 1 when opening archive. */ + +/* +** All static variables are collected into a structure named "local". +** That way, it is clear in the code when we are using a static +** variable because its name begins with "local.". +*/ +static struct { + Tcl_HashTable fileHash; /* One entry for each file in the ZVFS. The + ** The key is the virtual filename. The data + ** an an instance of the ZvfsFile structure. */ + Tcl_HashTable archiveHash; /* One entry for each archive. Key is the name. + ** data is the ZvfsArchive structure */ + int isInit; /* True after initialization */ +} local; + +/* +** Each ZIP archive file that is mounted is recorded as an instance +** of this structure +*/ +typedef struct ZvfsArchive { + char *zName; /* Name of the archive */ + char *zMountPoint; /* Where this archive is mounted */ + struct ZvfsFile *pFiles; /* List of files in that archive */ +} ZvfsArchive; + +/* +** Particulars about each virtual file are recorded in an instance +** of the following structure. +*/ +typedef struct ZvfsFile { + char *zName; /* The full pathname of the virtual file */ + ZvfsArchive *pArchive; /* The ZIP archive holding this file data */ + int iOffset; /* Offset into the ZIP archive of the data */ + int nByte; /* Uncompressed size of the virtual file */ + int nByteCompr; /* Compressed size of the virtual file */ + time_t timestamp; /* Modification time */ + int isdir; /* Set to 2 if directory, or 1 if mount */ + int depth; /* Number of slashes in path. */ + int permissions; /* File permissions. */ + struct ZvfsFile *pNext; /* Next file in the same archive */ + struct ZvfsFile *pNextName; /* A doubly-linked list of files with the same */ + struct ZvfsFile *pPrevName; /* name. Only the first is in local.fileHash */ +} ZvfsFile; + +/* +** Information about each file within a ZIP archive is stored in +** an instance of the following structure. A list of these structures +** forms a table of contents for the archive. +*/ +typedef struct ZFile ZFile; +struct ZFile { + char *zName; /* Name of the file */ + int isSpecial; /* Not really a file in the ZIP archive */ + int dosTime; /* Modification time (DOS format) */ + int dosDate; /* Modification date (DOS format) */ + int iOffset; /* Offset into the ZIP archive of the data */ + int nByte; /* Uncompressed size of the virtual file */ + int nByteCompr; /* Compressed size of the virtual file */ + int nExtra; /* Extra space in the TOC header */ + int iCRC; /* Cyclic Redundancy Check of the data */ + int permissions; /* File permissions. */ + int flags; /* Deletion = bit 0. */ + ZFile *pNext; /* Next file in the same archive */ +}; + +EXTERN int Tcl_Zvfs_Mount(Tcl_Interp *interp,CONST char *zArchive,CONST char *zMountPoint); +EXTERN int Tcl_Zvfs_Umount(CONST char *zArchive); +EXTERN int Tcl_Zvfs_Init(Tcl_Interp *interp); +EXTERN int Tcl_Zvfs_SafeInit(Tcl_Interp *interp); +/* +** Macros to read 16-bit and 32-bit big-endian integers into the +** native format of this local processor. B is an array of +** characters and the integer begins at the N-th character of +** the array. +*/ +#define INT16(B, N) (B[N] + (B[N+1]<<8)) +#define INT32(B, N) (INT16(B,N) + (B[N+2]<<16) + (B[N+3]<<24)) + +/* +** Write a 16- or 32-bit integer as little-endian into the given buffer. +*/ +static void put16(char *z, int v){ + z[0] = v & 0xff; + z[1] = (v>>8) & 0xff; +} +static void put32(char *z, int v){ + z[0] = v & 0xff; + z[1] = (v>>8) & 0xff; + z[2] = (v>>16) & 0xff; + z[3] = (v>>24) & 0xff; +} + +/* +** Make a new ZFile structure with space to hold a name of the number of +** characters given. Return a pointer to the new structure. +*/ +static ZFile *newZFile(int nName, ZFile **ppList){ + ZFile *pNew; + + pNew = (ZFile*)Tcl_Alloc( sizeof(*pNew) + nName + 1 ); + memset(pNew, 0, sizeof(*pNew)); + pNew->zName = (char*)&pNew[1]; + pNew->pNext = *ppList; + *ppList = pNew; + return pNew; +} + +/* +** Delete an entire list of ZFile structures +*/ +static void deleteZFileList(ZFile *pList){ + ZFile *pNext; + while( pList ){ + pNext = pList->pNext; + Tcl_Free((char*)pList); + pList = pNext; + } +} + +/* Convert DOS time to unix time. */ +static void UnixTimeDate(struct tm *tm, int *dosDate, int *dosTime){ + *dosDate = ((((tm->tm_year-80)<<9)&0xfe00) | (((tm->tm_mon+1)<<5)&0x1e0) | (tm->tm_mday&0x1f)); + *dosTime = (((tm->tm_hour<<11)&0xf800) | ((tm->tm_min<<5)&0x7e0) | (tm->tm_sec&0x1f)); +} + +/* Convert DOS time to unix time. */ +static time_t DosTimeDate(int dosDate, int dosTime){ + time_t now; + struct tm *tm; + now=time(NULL); + tm = localtime(&now); + tm->tm_year=(((dosDate&0xfe00)>>9) + 80); + tm->tm_mon=((dosDate&0x1e0)>>5); + tm->tm_mday=(dosDate & 0x1f); + tm->tm_hour=(dosTime&0xf800)>>11; + tm->tm_min=(dosTime&0x7e0)>>5; + tm->tm_sec=(dosTime&0x1f); + return mktime(tm); +} + +/* +** Translate a DOS time and date stamp into a human-readable string. +*/ +static void translateDosTimeDate(char *zStr, int dosDate, int dosTime){ + static char *zMonth[] = { "nil", + "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", + }; + + sprintf(zStr, "%02d-%s-%d %02d:%02d:%02d", + dosDate & 0x1f, + zMonth[ ((dosDate&0x1e0)>>5) ], + ((dosDate&0xfe00)>>9) + 1980, + (dosTime&0xf800)>>11, + (dosTime&0x7e)>>5, + dosTime&0x1f + ); +} + +/* Return count of char ch in str */ +int strchrcnt(char *str, char ch) { + int cnt=0; + char *cp=str; + while ((cp=strchr(cp,ch))) { cp++; cnt++; } + return cnt; +} + + +/* +** Concatenate zTail onto zRoot to form a pathname. zRoot will begin +** with "/". After concatenation, simplify the pathname be removing +** unnecessary ".." and "." directories. Under windows, make all +** characters lower case. +** +** Resulting pathname is returned. Space to hold the returned path is +** obtained form Tcl_Alloc() and should be freed by the calling function. +*/ +static char *CanonicalPath(const char *zRoot, const char *zTail){ + char *zPath; + int i, j, c; + +#ifdef __WIN32__ + if( isalpha(zTail[0]) && zTail[1]==':' ){ zTail += 2; } + if( zTail[0]=='\\' ){ zRoot = ""; zTail++; } +#endif + if( zTail[0]=='/' ){ zRoot = ""; zTail++; } + zPath = Tcl_Alloc( strlen(zRoot) + strlen(zTail) + 2 ); + if( zPath==0 ) return 0; + if (zTail[0]) { + sprintf(zPath, "%s/%s", zRoot, zTail); + } else { + strcpy(zPath, zRoot); + } + for(i=j=0; (c = zPath[i])!=0; i++){ +#ifdef __WIN32__ + if( isupper(c) ) { if (maptolower) c = tolower(c); } + else if( c=='\\' ) c = '/'; +#endif + if( c=='/' ){ + int c2 = zPath[i+1]; + if( c2=='/' ) continue; + if( c2=='.' ){ + int c3 = zPath[i+2]; + if( c3=='/' || c3==0 ){ + i++; + continue; + } + if( c3=='.' && (zPath[i+3]=='.' || zPath[i+3]==0) ){ + i += 2; + while( j>0 && zPath[j-1]!='/' ){ j--; } + continue; + } + } + } + zPath[j++] = c; + } + if( j==0 ){ zPath[j++] = '/'; } +// if (j>1 && zPath[j-1] == '/') j--; + zPath[j] = 0; + return zPath; +} + +/* +** Construct an absolute pathname where memory is obtained from Tcl_Alloc +** that means the same file as the pathname given. +*/ +static char *AbsolutePath(const char *zRelative){ + Tcl_DString pwd; + char *zResult; + int len; + Tcl_DStringInit(&pwd); + if (zRelative[0] == '~' && zRelative[1] == '/') { + /* TODO: do this for all paths??? */ + if (Tcl_TranslateFileName(0, zRelative, &pwd) != NULL) { + zResult = CanonicalPath( "", Tcl_DStringValue(&pwd)); + goto done; + } + } else if( zRelative[0] != '/'){ +#ifdef __WIN32__ + if(!(zRelative[0]=='\\' || (zRelative[0] && zRelative[1] == ':'))) { + /*Tcl_GetCwd(0, &pwd); */ + } +#else + Tcl_GetCwd(0, &pwd); +#endif + } + zResult = CanonicalPath( Tcl_DStringValue(&pwd), zRelative); +done: + Tcl_DStringFree(&pwd); + len=strlen(zResult); + if (len > 0 && zResult[len-1] == '/') + zResult[len-1] = 0; + return zResult; +} + +int ZvfsReadTOCStart( + Tcl_Interp *interp, /* Leave error messages in this interpreter */ + Tcl_Channel chan, + ZFile **pList, + int *iStart +) { + char *zArchiveName = 0; /* A copy of zArchive */ + int nFile; /* Number of files in the archive */ + int iPos; /* Current position in the archive file */ + ZvfsArchive *pArchive; /* The ZIP archive being mounted */ + Tcl_HashEntry *pEntry; /* Hash table entry */ + int isNew; /* Flag to tell use when a hash entry is new */ + unsigned char zBuf[100]; /* Space into which to read from the ZIP archive */ + Tcl_HashSearch zSearch; /* Search all mount points */ + ZFile *p; + int zipStart; + + if (!chan) { + return TCL_ERROR; + } + if (Tcl_SetChannelOption(interp, chan, "-translation", "binary") != TCL_OK){ + return TCL_ERROR; + } + if (Tcl_SetChannelOption(interp, chan, "-encoding", "binary") != TCL_OK) { + return TCL_ERROR; + } + + /* Read the "End Of Central Directory" record from the end of the + ** ZIP archive. + */ + iPos = Tcl_Seek(chan, -22, SEEK_END); + Tcl_Read(chan, zBuf, 22); + if (memcmp(zBuf, "\120\113\05\06", 4)) { + /* Tcl_AppendResult(interp, "not a ZIP archive", NULL); */ + return TCL_BREAK; + } + + /* Compute the starting location of the directory for the ZIP archive + ** in iPos then seek to that location. + */ + zipStart = iPos; + nFile = INT16(zBuf,8); + iPos -= INT32(zBuf,12); + Tcl_Seek(chan, iPos, SEEK_SET); + + while(1) { + int lenName; /* Length of the next filename */ + int lenExtra; /* Length of "extra" data for next file */ + int iData; /* Offset to start of file data */ + int dosTime; + int dosDate; + int isdir; + ZvfsFile *pZvfs; /* A new virtual file */ + char *zFullPath; /* Full pathname of the virtual file */ + char zName[1024]; /* Space to hold the filename */ + + if (nFile-- <= 0 ){ + break; + } + /* Read the next directory entry. Extract the size of the filename, + ** the size of the "extra" information, and the offset into the archive + ** file of the file data. + */ + Tcl_Read(chan, zBuf, 46); + if (memcmp(zBuf, "\120\113\01\02", 4)) { + Tcl_AppendResult(interp, "ill-formed central directory entry", NULL); + return TCL_ERROR; + } + lenName = INT16(zBuf,28); + lenExtra = INT16(zBuf,30) + INT16(zBuf,32); + iData = INT32(zBuf,42); + if (iDatazName, lenName); + p->zName[lenName] = 0; + if (lenName>0 && p->zName[lenName-1] == '/') { + p->isSpecial = 1; + } + p->dosDate = INT16(zBuf, 14); + p->dosTime = INT16(zBuf, 12); + p->nByteCompr = INT32(zBuf, 20); + p->nByte = INT32(zBuf, 24); + p->nExtra = INT32(zBuf, 28); + p->iCRC = INT32(zBuf, 32); + + if (nFile < 0) + break; + + /* Skip over the extra information so that the next read will be from + ** the beginning of the next directory entry. + */ + Tcl_Seek(chan, lenExtra, SEEK_CUR); + } + *iStart = zipStart; + return TCL_OK; +} + +int ZvfsReadTOC( + Tcl_Interp *interp, /* Leave error messages in this interpreter */ + Tcl_Channel chan, + ZFile **pList +) { + int iStart; + return ZvfsReadTOCStart( interp, chan, pList, &iStart); +} + +/* +** Read a ZIP archive and make entries in the virutal file hash table for all +** content files of that ZIP archive. Also initialize the ZVFS if this +** routine has not been previously called. +*/ +int Tcl_Zvfs_Mount( + Tcl_Interp *interp, /* Leave error messages in this interpreter */ + CONST char *zArchive, /* The ZIP archive file */ + CONST char *zMountPoint /* Mount contents at this directory */ +){ + Tcl_Channel chan; /* Used for reading the ZIP archive file */ + char *zArchiveName = 0; /* A copy of zArchive */ + char *zTrueName = 0; /* A copy of zMountPoint */ + int nFile; /* Number of files in the archive */ + int iPos; /* Current position in the archive file */ + ZvfsArchive *pArchive; /* The ZIP archive being mounted */ + Tcl_HashEntry *pEntry; /* Hash table entry */ + int isNew; /* Flag to tell use when a hash entry is new */ + unsigned char zBuf[100]; /* Space into which to read from the ZIP archive */ + Tcl_HashSearch zSearch; /* Search all mount points */ + unsigned int startZip; + + if( !local.isInit ) return TCL_ERROR; + /* If null archive name, return all current mounts. */ + if (!zArchive) { + Tcl_DString dStr; + Tcl_DStringInit(&dStr); + pEntry=Tcl_FirstHashEntry(&local.archiveHash,&zSearch); + while (pEntry) { + if (pArchive = Tcl_GetHashValue(pEntry)) { + Tcl_DStringAppendElement(&dStr, pArchive->zName); + Tcl_DStringAppendElement(&dStr, pArchive->zMountPoint); + } + pEntry=Tcl_NextHashEntry(&zSearch); + } + Tcl_DStringResult(interp, &dStr); + return TCL_OK; + } + /* If null mount, return mount point. */ + // TODO: cleanup allocations of Absolute() path. + if (!zMountPoint) { + zTrueName=AbsolutePath(zArchive); + pEntry = Tcl_FindHashEntry(&local.archiveHash,zTrueName); + if (pEntry) { + if (pArchive = Tcl_GetHashValue(pEntry)) { + Tcl_AppendResult(interp, pArchive->zMountPoint, 0); + } + } + Tcl_Free(zTrueName); + return TCL_OK; + } + chan = Tcl_OpenFileChannel(interp, zArchive, "r", 0); + if (!chan) { + return TCL_ERROR; + } + if (Tcl_SetChannelOption(interp, chan, "-translation", "binary") != TCL_OK){ + return TCL_ERROR; + } + if (Tcl_SetChannelOption(interp, chan, "-encoding", "binary") != TCL_OK) { + return TCL_ERROR; + } + + /* Read the "End Of Central Directory" record from the end of the + ** ZIP archive. + */ + iPos = Tcl_Seek(chan, -22, SEEK_END); + Tcl_Read(chan, zBuf, 22); + if (memcmp(zBuf, "\120\113\05\06", 4)) { + Tcl_AppendResult(interp, "not a ZIP archive", NULL); + return TCL_ERROR; + } + + /* Construct the archive record + */ + zArchiveName = AbsolutePath(zArchive); + pEntry = Tcl_CreateHashEntry(&local.archiveHash, zArchiveName, &isNew); + if( !isNew ){ + pArchive = Tcl_GetHashValue(pEntry); + Tcl_AppendResult(interp, "already mounted at ", pArchive->zMountPoint, 0); + Tcl_Free(zArchiveName); + Tcl_Close(interp, chan); + return TCL_ERROR; + } + if (!*zMountPoint) { + /* Empty string is the special case of mounting on itself. */ + zMountPoint = zTrueName = AbsolutePath(zArchive); + } + pArchive = (ZvfsArchive*)Tcl_Alloc(sizeof(*pArchive) + strlen(zMountPoint)+1); + pArchive->zName = zArchiveName; + pArchive->zMountPoint = (char*)&pArchive[1]; + strcpy(pArchive->zMountPoint, zMountPoint); + pArchive->pFiles = 0; + Tcl_SetHashValue(pEntry, pArchive); + + /* Compute the starting location of the directory for the ZIP archive + ** in iPos then seek to that location. + */ + nFile = INT16(zBuf,8); + iPos -= INT32(zBuf,12); + Tcl_Seek(chan, iPos, SEEK_SET); + startZip = iPos; + + while(1) { + int lenName; /* Length of the next filename */ + int lenExtra; /* Length of "extra" data for next file */ + int iData; /* Offset to start of file data */ + int dosTime; + int dosDate; + int isdir; + ZvfsFile *pZvfs; /* A new virtual file */ + char *zFullPath; /* Full pathname of the virtual file */ + char zName[1024]; /* Space to hold the filename */ + + if (nFile-- <= 0 ){ + isdir = 1; + zFullPath = CanonicalPath(zMountPoint, ""); + iData = startZip; + goto addentry; + } + /* Read the next directory entry. Extract the size of the filename, + ** the size of the "extra" information, and the offset into the archive + ** file of the file data. + */ + Tcl_Read(chan, zBuf, 46); + if (memcmp(zBuf, "\120\113\01\02", 4)) { + Tcl_AppendResult(interp, "ill-formed central directory entry", NULL); + if (zTrueName) + Tcl_Free(zTrueName); + return TCL_ERROR; + } + lenName = INT16(zBuf,28); + lenExtra = INT16(zBuf,30) + INT16(zBuf,32); + iData = INT32(zBuf,42); + + + /* If the virtual filename is too big to fit in zName[], then skip + ** this file + */ + if( lenName >= sizeof(zName) ){ + Tcl_Seek(chan, lenName + lenExtra, SEEK_CUR); + continue; + } + + /* Construct an entry in local.fileHash for this virtual file. + */ + Tcl_Read(chan, zName, lenName); + isdir=0; + if (lenName>0 && zName[lenName-1] == '/') { + lenName--; + isdir=2; + } + zName[lenName] = 0; + zFullPath = CanonicalPath(zMountPoint, zName); +addentry: + pZvfs = (ZvfsFile*)Tcl_Alloc( sizeof(*pZvfs) ); + pZvfs->zName = zFullPath; + pZvfs->pArchive = pArchive; + pZvfs->isdir = isdir; + pZvfs->depth=strchrcnt(zFullPath,'/'); + pZvfs->iOffset = iData; + if (iDatatimestamp = DosTimeDate(dosDate, dosTime); + pZvfs->nByte = INT32(zBuf, 24); + pZvfs->nByteCompr = INT32(zBuf, 20); + pZvfs->pNext = pArchive->pFiles; + pZvfs->permissions = (0xffff&(INT32(zBuf, 38) >> 16)); + pArchive->pFiles = pZvfs; + pEntry = Tcl_CreateHashEntry(&local.fileHash, zFullPath, &isNew); + if( isNew ){ + pZvfs->pNextName = 0; + }else{ + ZvfsFile *pOld = (ZvfsFile*)Tcl_GetHashValue(pEntry); + pOld->pPrevName = pZvfs; + pZvfs->pNextName = pOld; + } + pZvfs->pPrevName = 0; + Tcl_SetHashValue(pEntry, (ClientData) pZvfs); + + if (nFile < 0) + break; + + /* Skip over the extra information so that the next read will be from + ** the beginning of the next directory entry. + */ + Tcl_Seek(chan, lenExtra, SEEK_CUR); + } + Tcl_Close(interp, chan); +done: + if (zTrueName) + Tcl_Free(zTrueName); + return TCL_OK; +} + +/* +** Locate the ZvfsFile structure that corresponds to the file named. +** Return NULL if there is no such ZvfsFile. +*/ +static ZvfsFile *ZvfsLookup(char *zFilename){ + char *zTrueName; + Tcl_HashEntry *pEntry; + ZvfsFile *pFile; + + if( local.isInit==0 ) return 0; + zTrueName = AbsolutePath(zFilename); + pEntry = Tcl_FindHashEntry(&local.fileHash, zTrueName); + pFile = pEntry ? Tcl_GetHashValue(pEntry) : 0; + Tcl_Free(zTrueName); + return pFile; +} + +static int ZvfsLookupMount(char *zFilename){ + char *zTrueName; + Tcl_HashEntry *pEntry; /* Hash table entry */ + Tcl_HashSearch zSearch; /* Search all mount points */ + ZvfsArchive *pArchive; /* The ZIP archive being mounted */ + int match=0; + if( local.isInit==0 ) return 0; + zTrueName = AbsolutePath(zFilename); + pEntry=Tcl_FirstHashEntry(&local.archiveHash,&zSearch); + while (pEntry) { + if (pArchive = Tcl_GetHashValue(pEntry)) { + if (!strcmp(pArchive->zMountPoint,zTrueName)) { + match=1; + break; + } + } + pEntry=Tcl_NextHashEntry(&zSearch); + } + Tcl_Free(zTrueName); + return match; +} + + +/* +** Unmount all the files in the given ZIP archive. +*/ +int Tcl_Zvfs_Umount(CONST char *zArchive){ + char *zArchiveName; + ZvfsArchive *pArchive; + ZvfsFile *pFile, *pNextFile; + Tcl_HashEntry *pEntry; + + zArchiveName = AbsolutePath(zArchive); + pEntry = Tcl_FindHashEntry(&local.archiveHash, zArchiveName); + Tcl_Free(zArchiveName); + if( pEntry==0 ) return 0; + pArchive = Tcl_GetHashValue(pEntry); + Tcl_DeleteHashEntry(pEntry); + Tcl_Free(pArchive->zName); + for(pFile=pArchive->pFiles; pFile; pFile=pNextFile){ + pNextFile = pFile->pNext; + if( pFile->pNextName ){ + pFile->pNextName->pPrevName = pFile->pPrevName; + } + if( pFile->pPrevName ){ + pFile->pPrevName->pNextName = pFile->pNextName; + }else{ + pEntry = Tcl_FindHashEntry(&local.fileHash, pFile->zName); + if( pEntry==0 ){ + /* This should never happen */ + }else if( pFile->pNextName ){ + Tcl_SetHashValue(pEntry, pFile->pNextName); + }else{ + Tcl_DeleteHashEntry(pEntry); + } + } + Tcl_Free(pFile->zName); + Tcl_Free((char*)pFile); + } + return 1; +} + +static void Zvfs_Unmount(CONST char *zArchive){ + Tcl_Zvfs_Umount(zArchive); +} + +/* +** zvfs::mount Zip-archive-name mount-point +** +** Create a new mount point on the given ZIP archive. After this +** command executes, files contained in the ZIP archive will appear +** to Tcl to be regular files at the mount point. +** +** With no mount-point, return mount point for archive. +** With no archive, return all archive/mount pairs. +** If mount-point is specified as an empty string, mount on file path. +** +*/ +static int ZvfsMountCmd( + ClientData clientData, /* Client data for this command */ + Tcl_Interp *interp, /* The interpreter used to report errors */ + int argc, /* Number of arguments */ + CONST char *argv[] /* Values of all arguments */ +){ + if( argc>3 ){ + Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], + " ? ZIP-FILE ? MOUNT-POINT ? ?\"", 0); + return TCL_ERROR; + } + return Tcl_Zvfs_Mount(interp, argc>1?argv[1]:0, argc>2?argv[2]:0); +} + +/* +** zvfs::unmount Zip-archive-name +** +** Undo the effects of zvfs::mount. +*/ +static int ZvfsUnmountCmd( + ClientData clientData, /* Client data for this command */ + Tcl_Interp *interp, /* The interpreter used to report errors */ + int argc, /* Number of arguments */ + CONST char *argv[] /* Values of all arguments */ +){ + ZvfsArchive *pArchive; /* The ZIP archive being mounted */ + Tcl_HashEntry *pEntry; /* Hash table entry */ + Tcl_HashSearch zSearch; /* Search all mount points */ + + if( argc!=2 ){ + Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], + " ZIP-FILE\"", 0); + return TCL_ERROR; + } + if (Tcl_Zvfs_Umount(argv[1])) { + return TCL_OK; + } + + if( !local.isInit ) return TCL_ERROR; + pEntry=Tcl_FirstHashEntry(&local.archiveHash,&zSearch); + while (pEntry) { + if (((pArchive = Tcl_GetHashValue(pEntry))) + && pArchive->zMountPoint[0] + && (strcmp(pArchive->zMountPoint, argv[1]) == 0)) { + if (Tcl_Zvfs_Umount(pArchive->zName)) { + return TCL_OK; + } + break; + } + pEntry=Tcl_NextHashEntry(&zSearch); + } + + Tcl_AppendResult( interp, "unknown zvfs mount point or file: ", argv[1], 0); + return TCL_ERROR; +} + +/* +** zvfs::exists filename +** +** Return TRUE if the given filename exists in the ZVFS and FALSE if +** it does not. +*/ +static int ZvfsExistsObjCmd( + ClientData clientData, /* Client data for this command */ + Tcl_Interp *interp, /* The interpreter used to report errors */ + int objc, /* Number of arguments */ + Tcl_Obj *CONST* objv /* Values of all arguments */ +){ + char *zFilename; + if( objc!=2 ){ + Tcl_WrongNumArgs(interp, 1, objv, "FILENAME"); + return TCL_ERROR; + } + zFilename = Tcl_GetString(objv[1]); + Tcl_SetBooleanObj( Tcl_GetObjResult(interp), ZvfsLookup(zFilename)!=0); + return TCL_OK; +} + +/* +** zvfs::info filename +** +** Return information about the given file in the ZVFS. The information +** consists of (1) the name of the ZIP archive that contains the file, +** (2) the size of the file after decompressions, (3) the compressed +** size of the file, and (4) the offset of the compressed data in the archive. +** +** Note: querying the mount point gives the start of zip data offset in +** (4), which can be used to truncate the zip info off an executable. +*/ +static int ZvfsInfoObjCmd( + ClientData clientData, /* Client data for this command */ + Tcl_Interp *interp, /* The interpreter used to report errors */ + int objc, /* Number of arguments */ + Tcl_Obj *const* objv /* Values of all arguments */ +){ + char *zFilename; + ZvfsFile *pFile; + if( objc!=2 ){ + Tcl_WrongNumArgs(interp, 1, objv, "FILENAME"); + return TCL_ERROR; + } + zFilename = Tcl_GetString(objv[1]); + pFile = ZvfsLookup(zFilename); + if( pFile ){ + Tcl_Obj *pResult = Tcl_GetObjResult(interp); + Tcl_ListObjAppendElement(interp, pResult, + Tcl_NewStringObj(pFile->pArchive->zName, -1)); + Tcl_ListObjAppendElement(interp, pResult, Tcl_NewIntObj(pFile->nByte)); + Tcl_ListObjAppendElement(interp, pResult, Tcl_NewIntObj(pFile->nByteCompr)); + Tcl_ListObjAppendElement(interp, pResult, Tcl_NewIntObj(pFile->iOffset)); + } + return TCL_OK; +} + +/* +** zvfs::list +** +** Return a list of all files in the ZVFS. The order of the names +** in the list is arbitrary. +*/ +static int ZvfsListObjCmd( + ClientData clientData, /* Client data for this command */ + Tcl_Interp *interp, /* The interpreter used to report errors */ + int objc, /* Number of arguments */ + Tcl_Obj *const* objv /* Values of all arguments */ +){ + char *zPattern = 0; + Tcl_RegExp pRegexp = 0; + Tcl_HashEntry *pEntry; + Tcl_HashSearch sSearch; + Tcl_Obj *pResult = Tcl_GetObjResult(interp); + + if( objc>3 ){ + Tcl_WrongNumArgs(interp, 1, objv, "?(-glob|-regexp)? ?PATTERN?"); + return TCL_ERROR; + } + if( local.isInit==0 ) return TCL_OK; + if( objc==3 ){ + int n; + char *zSwitch = Tcl_GetStringFromObj(objv[1], &n); + if( n>=2 && strncmp(zSwitch,"-glob",n)==0 ){ + zPattern = Tcl_GetString(objv[2]); + }else if( n>=2 && strncmp(zSwitch,"-regexp",n)==0 ){ + pRegexp = Tcl_RegExpCompile(interp, Tcl_GetString(objv[2])); + if( pRegexp==0 ) return TCL_ERROR; + }else{ + Tcl_AppendResult(interp, "unknown option: ", zSwitch, 0); + return TCL_ERROR; + } + }else if( objc==2 ){ + zPattern = Tcl_GetString(objv[1]); + } + if( zPattern ){ + for(pEntry = Tcl_FirstHashEntry(&local.fileHash, &sSearch); + pEntry; + pEntry = Tcl_NextHashEntry(&sSearch) + ){ + ZvfsFile *pFile = Tcl_GetHashValue(pEntry); + char *z = pFile->zName; + if( Tcl_StringCaseMatch(z, zPattern,1) ){ + Tcl_ListObjAppendElement(interp, pResult, Tcl_NewStringObj(z, -1)); + } + } + }else if( pRegexp ){ + for(pEntry = Tcl_FirstHashEntry(&local.fileHash, &sSearch); + pEntry; + pEntry = Tcl_NextHashEntry(&sSearch) + ){ + ZvfsFile *pFile = Tcl_GetHashValue(pEntry); + char *z = pFile->zName; + if( Tcl_RegExpExec(interp, pRegexp, z, z) ){ + Tcl_ListObjAppendElement(interp, pResult, Tcl_NewStringObj(z, -1)); + } + } + }else{ + for(pEntry = Tcl_FirstHashEntry(&local.fileHash, &sSearch); + pEntry; + pEntry = Tcl_NextHashEntry(&sSearch) + ){ + ZvfsFile *pFile = Tcl_GetHashValue(pEntry); + char *z = pFile->zName; + Tcl_ListObjAppendElement(interp, pResult, Tcl_NewStringObj(z, -1)); + } + } + return TCL_OK; +} + +/* +** Whenever a ZVFS file is opened, an instance of this structure is +** attached to the open channel where it will be available to the +** ZVFS I/O routines below. All state information about an open +** ZVFS file is held in this structure. +*/ +typedef struct ZvfsChannelInfo { + unsigned int nByte; /* number of bytes of read uncompressed data */ + unsigned int nByteCompr; /* number of bytes of unread compressed data */ + unsigned int nData; /* total number of bytes of compressed data */ + int readSoFar; /* Number of bytes read so far */ + long startOfData; /* File position of start of data in ZIP archive */ + int isCompressed; /* True data is compressed */ + Tcl_Channel chan; /* Open to the archive file */ + unsigned char *zBuf; /* buffer used by the decompressor */ + z_stream stream; /* state of the decompressor */ +} ZvfsChannelInfo; + + +/* +** This routine is called as an exit handler. If we do not set +** ZvfsChannelInfo.chan to NULL, then Tcl_Close() will be called on +** that channel twice when Tcl_Exit runs. This will lead to a +** core dump. +*/ +static void vfsExit(void *pArg){ + ZvfsChannelInfo *pInfo = (ZvfsChannelInfo*)pArg; + pInfo->chan = 0; +} + +/* +** This routine is called when the ZVFS channel is closed +*/ +static int vfsClose( + ClientData instanceData, /* A ZvfsChannelInfo structure */ + Tcl_Interp *interp /* The TCL interpreter */ +){ + ZvfsChannelInfo* pInfo = (ZvfsChannelInfo*)instanceData; + + if( pInfo->zBuf ){ + Tcl_Free(pInfo->zBuf); + inflateEnd(&pInfo->stream); + } + if( pInfo->chan ){ + Tcl_Close(interp, pInfo->chan); + Tcl_DeleteExitHandler(vfsExit, pInfo); + } + Tcl_Free((char*)pInfo); + return TCL_OK; +} + +/* +** The TCL I/O system calls this function to actually read information +** from a ZVFS file. +*/ +static int vfsInput ( + ClientData instanceData, /* The channel to read from */ + char *buf, /* Buffer to fill */ + int toRead, /* Requested number of bytes */ + int *pErrorCode /* Location of error flag */ +){ + ZvfsChannelInfo* pInfo = (ZvfsChannelInfo*) instanceData; + + if( toRead > pInfo->nByte ){ + toRead = pInfo->nByte; + } + if( toRead == 0 ){ + return 0; + } + if( pInfo->isCompressed ){ + int err = Z_OK; + z_stream *stream = &pInfo->stream; + stream->next_out = buf; + stream->avail_out = toRead; + while (stream->avail_out) { + if (!stream->avail_in) { + int len = pInfo->nByteCompr; + if (len > COMPR_BUF_SIZE) { + len = COMPR_BUF_SIZE; + } + len = Tcl_Read(pInfo->chan, pInfo->zBuf, len); + pInfo->nByteCompr -= len; + stream->next_in = pInfo->zBuf; + stream->avail_in = len; + } + err = inflate(stream, Z_NO_FLUSH); + if (err) break; + } + if (err == Z_STREAM_END) { + if ((stream->avail_out != 0)) { + *pErrorCode = err; /* premature end */ + return -1; + } + }else if( err ){ + *pErrorCode = err; /* some other zlib error */ + return -1; + } + }else{ + toRead = Tcl_Read(pInfo->chan, buf, toRead); + } + pInfo->nByte -= toRead; + pInfo->readSoFar += toRead; + *pErrorCode = 0; + return toRead; +} + +/* +** Write to a ZVFS file. ZVFS files are always read-only, so this routine +** always returns an error. +*/ +static int vfsOutput( + ClientData instanceData, /* The channel to write to */ + CONST char *buf, /* Data to be stored. */ + int toWrite, /* Number of bytes to write. */ + int *pErrorCode /* Location of error flag. */ +){ + *pErrorCode = EINVAL; + return -1; +} + +/* +** Move the file pointer so that the next byte read will be "offset". +*/ +static int vfsSeek( + ClientData instanceData, /* The file structure */ + long offset, /* Offset to seek to */ + int mode, /* One of SEEK_CUR, SEEK_SET or SEEK_END */ + int *pErrorCode /* Write the error code here */ +){ + ZvfsChannelInfo* pInfo = (ZvfsChannelInfo*) instanceData; + + switch( mode ){ + case SEEK_CUR: { + offset += pInfo->readSoFar; + break; + } + case SEEK_END: { + offset += pInfo->readSoFar + pInfo->nByte; + break; + } + default: { + /* Do nothing */ + break; + } + } + if (offset < 0) offset = 0; + if( !pInfo->isCompressed ){ + Tcl_Seek(pInfo->chan, offset + pInfo->startOfData, SEEK_SET); + pInfo->nByte = pInfo->nData; + pInfo->readSoFar = offset; + }else{ + if( offsetreadSoFar ){ + z_stream *stream = &pInfo->stream; + inflateEnd(stream); + stream->zalloc = (alloc_func)0; + stream->zfree = (free_func)0; + stream->opaque = (voidpf)0; + stream->avail_in = 2; + stream->next_in = pInfo->zBuf; + pInfo->zBuf[0] = 0x78; + pInfo->zBuf[1] = 0x01; + inflateInit(&pInfo->stream); + Tcl_Seek(pInfo->chan, pInfo->startOfData, SEEK_SET); + pInfo->nByte += pInfo->readSoFar; + pInfo->nByteCompr = pInfo->nData; + pInfo->readSoFar = 0; + } + while( pInfo->readSoFar < offset ){ + int toRead, errCode; + char zDiscard[100]; + toRead = offset - pInfo->readSoFar; + if( toRead>sizeof(zDiscard) ) toRead = sizeof(zDiscard); + vfsInput(instanceData, zDiscard, toRead, &errCode); + } + } + return pInfo->readSoFar; +} + +/* +** Handle events on the channel. ZVFS files do not generate events, +** so this is a no-op. +*/ +static void vfsWatchChannel( + ClientData instanceData, /* Channel to watch */ + int mask /* Events of interest */ +){ + return; +} + +/* +** Called to retrieve the underlying file handle for this ZVFS file. +** As the ZVFS file has no underlying file handle, this is a no-op. +*/ +static int vfsGetFile( + ClientData instanceData, /* Channel to query */ + int direction, /* Direction of interest */ + ClientData* handlePtr /* Space to the handle into */ +){ + return TCL_ERROR; +} + +/* +** This structure describes the channel type structure for +** access to the ZVFS. +*/ +static Tcl_ChannelType vfsChannelType = { + "vfs", /* Type name. */ + NULL, /* Set blocking/nonblocking behaviour. NULL'able */ + vfsClose, /* Close channel, clean instance data */ + vfsInput, /* Handle read request */ + vfsOutput, /* Handle write request */ + vfsSeek, /* Move location of access point. NULL'able */ + NULL, /* Set options. NULL'able */ + NULL, /* Get options. NULL'able */ + vfsWatchChannel, /* Initialize notifier */ + vfsGetFile /* Get OS handle from the channel. */ +}; + +/* +** This routine attempts to do an open of a file. Check to see +** if the file is located in the ZVFS. If so, then open a channel +** for reading the file. If not, return NULL. +*/ +static Tcl_Channel ZvfsFileOpen( + Tcl_Interp *interp, /* The TCL interpreter doing the open */ + char *zFilename, /* Name of the file to open */ + char *modeString, /* Mode string for the open (ignored) */ + int permissions /* Permissions for a newly created file (ignored) */ +){ + ZvfsFile *pFile; + ZvfsChannelInfo *pInfo; + Tcl_Channel chan; + static int count = 1; + char zName[50]; + unsigned char zBuf[50]; + + pFile = ZvfsLookup(zFilename); + if( pFile==0 ) return NULL; + openarch=1; + chan = Tcl_OpenFileChannel(interp, pFile->pArchive->zName, "r", 0); + openarch=0; + if( chan==0 ){ + return 0; + } + if( Tcl_SetChannelOption(interp, chan, "-translation", "binary") + || Tcl_SetChannelOption(interp, chan, "-encoding", "binary") + ){ + /* this should never happen */ + Tcl_Close(0, chan); + return 0; + } + Tcl_Seek(chan, pFile->iOffset, SEEK_SET); + Tcl_Read(chan, zBuf, 30); + if( memcmp(zBuf, "\120\113\03\04", 4) ){ + if( interp ){ + Tcl_AppendResult(interp, "local header mismatch: ", NULL); + } + Tcl_Close(interp, chan); + return 0; + } + pInfo = (ZvfsChannelInfo*)Tcl_Alloc( sizeof(*pInfo) ); + pInfo->chan = chan; + Tcl_CreateExitHandler(vfsExit, pInfo); + pInfo->isCompressed = INT16(zBuf, 8); + if( pInfo->isCompressed ){ + z_stream *stream = &pInfo->stream; + pInfo->zBuf = Tcl_Alloc(COMPR_BUF_SIZE); + stream->zalloc = (alloc_func)0; + stream->zfree = (free_func)0; + stream->opaque = (voidpf)0; + stream->avail_in = 2; + stream->next_in = pInfo->zBuf; + pInfo->zBuf[0] = 0x78; + pInfo->zBuf[1] = 0x01; + inflateInit(&pInfo->stream); + }else{ + pInfo->zBuf = 0; + } + pInfo->nByte = INT32(zBuf,22); + pInfo->nByteCompr = pInfo->nData = INT32(zBuf,18); + pInfo->readSoFar = 0; + Tcl_Seek(chan, INT16(zBuf,26)+INT16(zBuf,28), SEEK_CUR); + pInfo->startOfData = Tcl_Tell(chan); + sprintf(zName,"vfs_%x_%x",((int)pFile)>>12,count++); + chan = Tcl_CreateChannel(&vfsChannelType, zName, + (ClientData)pInfo, TCL_READABLE); + return chan; +} + +/* +** This routine does a stat() system call for a ZVFS file. +*/ +static int ZvfsFileStat(char *path, struct stat *buf){ + ZvfsFile *pFile; + + pFile = ZvfsLookup(path); + if( pFile==0 ){ + return -1; + } + memset(buf, 0, sizeof(*buf)); + if (pFile->isdir) + buf->st_mode = 040555; + else + buf->st_mode = (0100000|pFile->permissions); + buf->st_ino = 0; + buf->st_size = pFile->nByte; + buf->st_mtime = pFile->timestamp; + buf->st_ctime = pFile->timestamp; + buf->st_atime = pFile->timestamp; + return 0; +} + +/* +** This routine does an access() system call for a ZVFS file. +*/ +static int ZvfsFileAccess(char *path, int mode){ + ZvfsFile *pFile; + + if( mode & 3 ){ + return -1; + } + pFile = ZvfsLookup(path); + if( pFile==0 ){ + return -1; + } + return 0; +} + +#ifndef USE_TCL_VFS + +/* +** This TCL procedure can be used to copy a file. The built-in +** "file copy" command of TCL bypasses the I/O system and does not +** work with zvfs. You have to use a procedure like the following +** instead. +*/ +static char zFileCopy[] = +"proc zvfs::filecopy {from to {outtype binary}} {\n" +" set f [open $from r]\n" +" if {[catch {\n" +" fconfigure $f -translation binary\n" +" set t [open $to w]\n" +" } msg]} {\n" +" close $f\n" +" error $msg\n" +" }\n" +" if {[catch {\n" +" fconfigure $t -translation $outtype\n" +" set size [file size $from]\n" +" for {set i 0} {$i<$size} {incr i 40960} {\n" +" puts -nonewline $t [read $f 40960]\n" +" }\n" +" } msg]} {\n" +" close $f\n" +" close $t\n" +" error $msg\n" +" }\n" +" close $f\n" +" close $t\n" +"}\n" +; + +#else + +Tcl_Channel Tobe_FSOpenFileChannelProc + _ANSI_ARGS_((Tcl_Interp *interp, Tcl_Obj *pathPtr, + int mode, int permissions)) { + static int inopen=0; + Tcl_Channel chan; + if (inopen) { + puts("recursive zvfs open"); + return NULL; + } + inopen = 1; + /* if (mode != O_RDONLY) return NULL; */ + chan = ZvfsFileOpen(interp, Tcl_GetString(pathPtr), 0, + permissions); + inopen = 0; + return chan; +} + +/* +** This routine does a stat() system call for a ZVFS file. +*/ +int Tobe_FSStatProc _ANSI_ARGS_((Tcl_Obj *pathPtr, struct stat *buf)) { + + return ZvfsFileStat(Tcl_GetString(pathPtr), buf); +} + +/* +** This routine does an access() system call for a ZVFS file. +*/ +int Tobe_FSAccessProc _ANSI_ARGS_((Tcl_Obj *pathPtr, int mode)) { + return ZvfsFileAccess(Tcl_GetString(pathPtr), mode); +} + + +/* Tcl_Obj* Tobe_FSFilesystemSeparatorProc + _ANSI_ARGS_((Tcl_Obj *pathPtr)) { + return Tcl_NewStringObj("/",-1);; +} */ +/* Function to process a +* 'Tobe_FSMatchInDirectory()'. If not +* implemented, then glob and recursive +* copy functionality will be lacking in +* the filesystem. */ +int Tobe_FSMatchInDirectoryProc _ANSI_ARGS_((Tcl_Interp* interp, + Tcl_Obj *result, Tcl_Obj *pathPtr, CONST char *pattern, + Tcl_GlobTypeData * types)) { + Tcl_HashEntry *pEntry; + Tcl_HashSearch sSearch; + int scnt, len, l, dirglob, dirmnt; + char *zPattern = NULL, *zp=Tcl_GetStringFromObj(pathPtr,&len);; + if (!zp) return TCL_ERROR; + if (pattern != NULL) { + l=strlen(pattern); + if (!zp) + zPattern=strdup(pattern); + else { + zPattern=(char*)malloc(len+l+3); + sprintf(zPattern,"%s%s%s", zp, zp[len-1]=='/'?"":"/",pattern); + } + scnt=strchrcnt(zPattern,'/'); + } + dirglob = (types && types->type && (types->type&TCL_GLOB_TYPE_DIR)); + dirmnt = (types && types->type && (types->type&TCL_GLOB_TYPE_MOUNT)); + if (strcmp(zp, "/") == 0 && strcmp(zPattern, ".*") == 0) { + } + for(pEntry = Tcl_FirstHashEntry(&local.fileHash, &sSearch); + pEntry; + pEntry = Tcl_NextHashEntry(&sSearch) + ){ + ZvfsFile *pFile = Tcl_GetHashValue(pEntry); + char *z = pFile->zName; + if (zPattern != NULL) { + if( Tcl_StringCaseMatch(z, zPattern, 0) == 0 || + (scnt!=pFile->depth /* && !dirglob */ )) { // TODO: ??? + continue; + } + } else { + if (strcmp(zp, z)) + continue; + } + if (dirmnt) { + if (pFile->isdir != 1) + continue; + } else if (dirglob) { + if (!pFile->isdir) + continue; + } else if (types && !(types->type&TCL_GLOB_TYPE_DIR)) { + if (pFile->isdir) + continue; + } + Tcl_ListObjAppendElement(interp, result, Tcl_NewStringObj(z, -1)); + } + if (zPattern) + free(zPattern); + return TCL_OK; +} + +/* Function to check whether a path is in +* this filesystem. This is the most +* important filesystem procedure. */ +int Tobe_FSPathInFilesystemProc _ANSI_ARGS_((Tcl_Obj *pathPtr, + ClientData *clientDataPtr)) { + ZvfsFile *zFile; + char *path=Tcl_GetString(pathPtr); +// if (ZvfsLookupMount(path)!=0) +// return TCL_OK; + // TODO: also check this is the archive. + if (openarch) + return -1; + zFile = ZvfsLookup(path); + if (zFile!=NULL && strcmp(path,zFile->pArchive->zName)) + return TCL_OK; + return -1; +} + +Tcl_Obj *Tobe_FSListVolumesProc _ANSI_ARGS_((void)) { + Tcl_HashEntry *pEntry; /* Hash table entry */ + Tcl_HashSearch zSearch; /* Search all mount points */ + ZvfsArchive *pArchive; /* The ZIP archive being mounted */ + Tcl_Obj *pVols=NULL, *pVol; + pEntry=Tcl_FirstHashEntry(&local.archiveHash,&zSearch); + while (pEntry) { + if (pArchive = Tcl_GetHashValue(pEntry)) { + if (!pVols) { + pVols=Tcl_NewListObj(0,0); + Tcl_IncrRefCount(pVols); + } + pVol=Tcl_NewStringObj(pArchive->zMountPoint,-1); + Tcl_IncrRefCount(pVol); + Tcl_ListObjAppendElement(NULL, pVols,pVol); + Tcl_DecrRefCount(pVol); + } + pEntry=Tcl_NextHashEntry(&zSearch); + } + return pVols; +} + +int Tobe_FSChdirProc _ANSI_ARGS_((Tcl_Obj *pathPtr)) { + /* Someday, we should actually check if this is a valid path. */ + return TCL_OK; +} + +CONST char** Tobe_FSFileAttrStringsProc _ANSI_ARGS_((Tcl_Obj *pathPtr, + Tcl_Obj** objPtrRef)) { + Tcl_Obj *listPtr; + Tcl_Interp *interp = NULL; + char *path=Tcl_GetString(pathPtr); +#ifdef __WIN32__ + static CONST char *attrs[] = { "-archive", "-hidden", "-readonly", "-system", "-shortname", 0 }; +#else + static CONST char *attrs[] = { "-group", "-owner", "-permissions", 0 }; +#endif + if (ZvfsLookup(path)==0) + return NULL; + return attrs; +} + +int Tobe_FSFileAttrsGetProc _ANSI_ARGS_((Tcl_Interp *interp, + int index, Tcl_Obj *pathPtr, + Tcl_Obj **objPtrRef)) { + + char *path=Tcl_GetString(pathPtr); + char buf[50]; + ZvfsFile *zFile; + if ((zFile = ZvfsLookup(path))==0) + return TCL_ERROR; + + switch (index) { +#ifdef __WIN32__ + + case 0: /* -archive */ + *objPtrRef = Tcl_NewStringObj("0", -1); break; + case 1: /* -hidden */ + *objPtrRef = Tcl_NewStringObj("0", -1); break; + case 2: /* -readonly */ + *objPtrRef = Tcl_NewStringObj("", -1); break; + case 3: /* -system */ + *objPtrRef = Tcl_NewStringObj("", -1); break; + case 4: /* -shortname */ + *objPtrRef = Tcl_NewStringObj("", -1); +#else + case 0: /* -group */ + *objPtrRef = Tcl_NewStringObj("", -1); break; + case 1: /* -owner */ + *objPtrRef = Tcl_NewStringObj("", -1); break; + case 2: /* -permissions */ + sprintf(buf, "%03o", zFile->permissions); + *objPtrRef = Tcl_NewStringObj(buf, -1); break; +#endif + } + + return TCL_OK; +} + +/****************************************************/ + +// At some point, some of the following might get implemented? + +#if 1 +#define Tobe_FSFilesystemSeparatorProc 0 +#define Tobe_FSLoadFileProc 0 +#define Tobe_FSUnloadFileProc 0 +#define Tobe_FSGetCwdProc 0 +#define Tobe_FSGetCwdProc 0 +#define Tobe_FSCreateDirectoryProc 0 +#define Tobe_FSDeleteFileProc 0 +#define Tobe_FSCopyDirectoryProc 0 +#define Tobe_FSCopyFileProc 0 +#define Tobe_FSRemoveDirectoryProc 0 +#define Tobe_FSFileAttrsSetProc 0 +#define Tobe_FSNormalizePathProc 0 +#define Tobe_FSUtimeProc 0 +#define Tobe_FSRenameFileProc 0 +#define Tobe_FSCreateInternalRepProc 0 +#define Tobe_FSInternalToNormalizedProc 0 +#define Tobe_FSDupInternalRepProc 0 +#define Tobe_FSFreeInternalRepProc 0 +#define Tobe_FSFilesystemPathTypeProc 0 +#define Tobe_FSLinkProc 0 +#else + +/* Function to process a +* 'Tobe_FSLoadFile()' call. If not +* implemented, Tcl will fall back on +* a copy to native-temp followed by a +* Tobe_FSLoadFile on that temporary copy. */ +int Tobe_FSLoadFileProc _ANSI_ARGS_((Tcl_Interp * interp, + Tcl_Obj *pathPtr, char * sym1, char * sym2, + Tcl_PackageInitProc ** proc1Ptr, + Tcl_PackageInitProc ** proc2Ptr, + ClientData * clientDataPtr)) { return 0; } + + +/* Function to unload a previously +* successfully loaded file. If load was +* implemented, then this should also be +* implemented, if there is any cleanup +* action required. */ +void Tobe_FSUnloadFileProc _ANSI_ARGS_((ClientData clientData)) { + return; +} + +Tcl_Obj* Tobe_FSGetCwdProc _ANSI_ARGS_((Tcl_Interp *interp)) { return 0; } +int Tobe_FSCreateDirectoryProc _ANSI_ARGS_((Tcl_Obj *pathPtr)) { return 0; } +int Tobe_FSDeleteFileProc _ANSI_ARGS_((Tcl_Obj *pathPtr)) { return 0; } +int Tobe_FSCopyDirectoryProc _ANSI_ARGS_((Tcl_Obj *srcPathPtr, + Tcl_Obj *destPathPtr, Tcl_Obj **errorPtr)) { return 0; } +int Tobe_FSCopyFileProc _ANSI_ARGS_((Tcl_Obj *srcPathPtr, + Tcl_Obj *destPathPtr)) { return 0; } +int Tobe_FSRemoveDirectoryProc _ANSI_ARGS_((Tcl_Obj *pathPtr, + int recursive, Tcl_Obj **errorPtr)) { return 0; } +int Tobe_FSRenameFileProc _ANSI_ARGS_((Tcl_Obj *srcPathPtr, + Tcl_Obj *destPathPtr)) { return 0; } +/* We have to declare the utime structure here. */ +int Tobe_FSUtimeProc _ANSI_ARGS_((Tcl_Obj *pathPtr, + struct utimbuf *tval)) { return 0; } +int Tobe_FSNormalizePathProc _ANSI_ARGS_((Tcl_Interp *interp, + Tcl_Obj *pathPtr, int nextCheckpoint)) { return 0; } +int Tobe_FSFileAttrsSetProc _ANSI_ARGS_((Tcl_Interp *interp, + int index, Tcl_Obj *pathPtr, + Tcl_Obj *objPtr)) { return 0; } +Tcl_Obj* Tobe_FSLinkProc _ANSI_ARGS_((Tcl_Obj *pathPtr)) { return 0; } +Tcl_Obj* Tobe_FSFilesystemPathTypeProc + _ANSI_ARGS_((Tcl_Obj *pathPtr)) { return 0; } +void Tobe_FSFreeInternalRepProc _ANSI_ARGS_((ClientData clientData)) { return; } +ClientData Tobe_FSDupInternalRepProc + _ANSI_ARGS_((ClientData clientData)) { return 0; } +Tcl_Obj* Tobe_FSInternalToNormalizedProc + _ANSI_ARGS_((ClientData clientData)) { return 0; } +ClientData Tobe_FSCreateInternalRepProc _ANSI_ARGS_((Tcl_Obj *pathPtr)) { + return 0; +} + +#endif + + +static Tcl_Filesystem Tobe_Filesystem = { + "tobe", /* The name of the filesystem. */ + sizeof(Tcl_Filesystem), /* Length of this structure, so future + * binary compatibility can be assured. */ + TCL_FILESYSTEM_VERSION_1, + /* Version of the filesystem type. */ + Tobe_FSPathInFilesystemProc, + /* Function to check whether a path is in + * this filesystem. This is the most + * important filesystem procedure. */ + Tobe_FSDupInternalRepProc, + /* Function to duplicate internal fs rep. May + * be NULL (but then fs is less efficient). */ + Tobe_FSFreeInternalRepProc, + /* Function to free internal fs rep. Must + * be implemented, if internal representations + * need freeing, otherwise it can be NULL. */ + Tobe_FSInternalToNormalizedProc, + /* Function to convert internal representation + * to a normalized path. Only required if + * the fs creates pure path objects with no + * string/path representation. */ + Tobe_FSCreateInternalRepProc, + /* Function to create a filesystem-specific + * internal representation. May be NULL + * if paths have no internal representation, + * or if the Tobe_FSPathInFilesystemProc + * for this filesystem always immediately + * creates an internal representation for + * paths it accepts. */ + Tobe_FSNormalizePathProc, + /* Function to normalize a path. Should + * be implemented for all filesystems + * which can have multiple string + * representations for the same path + * object. */ + Tobe_FSFilesystemPathTypeProc, + /* Function to determine the type of a + * path in this filesystem. May be NULL. */ + Tobe_FSFilesystemSeparatorProc, + /* Function to return the separator + * character(s) for this filesystem. Must + * be implemented. */ + Tobe_FSStatProc, + /* + * Function to process a 'Tobe_FSStat()' + * call. Must be implemented for any + * reasonable filesystem. + */ + Tobe_FSAccessProc, + /* + * Function to process a 'Tobe_FSAccess()' + * call. Must be implemented for any + * reasonable filesystem. + */ + Tobe_FSOpenFileChannelProc, + /* + * Function to process a + * 'Tobe_FSOpenFileChannel()' call. Must be + * implemented for any reasonable + * filesystem. + */ + Tobe_FSMatchInDirectoryProc, + /* Function to process a + * 'Tobe_FSMatchInDirectory()'. If not + * implemented, then glob and recursive + * copy functionality will be lacking in + * the filesystem. */ + Tobe_FSUtimeProc, + /* Function to process a + * 'Tobe_FSUtime()' call. Required to + * allow setting (not reading) of times + * with 'file mtime', 'file atime' and + * the open-r/open-w/fcopy implementation + * of 'file copy'. */ + Tobe_FSLinkProc, + /* Function to process a + * 'Tobe_FSLink()' call. Should be + * implemented only if the filesystem supports + * links. */ + Tobe_FSListVolumesProc, + /* Function to list any filesystem volumes + * added by this filesystem. Should be + * implemented only if the filesystem adds + * volumes at the head of the filesystem. */ + Tobe_FSFileAttrStringsProc, + /* Function to list all attributes strings + * which are valid for this filesystem. + * If not implemented the filesystem will + * not support the 'file attributes' command. + * This allows arbitrary additional information + * to be attached to files in the filesystem. */ + Tobe_FSFileAttrsGetProc, + /* Function to process a + * 'Tobe_FSFileAttrsGet()' call, used by + * 'file attributes'. */ + Tobe_FSFileAttrsSetProc, + /* Function to process a + * 'Tobe_FSFileAttrsSet()' call, used by + * 'file attributes'. */ + Tobe_FSCreateDirectoryProc, + /* Function to process a + * 'Tobe_FSCreateDirectory()' call. Should + * be implemented unless the FS is + * read-only. */ + Tobe_FSRemoveDirectoryProc, + /* Function to process a + * 'Tobe_FSRemoveDirectory()' call. Should + * be implemented unless the FS is + * read-only. */ + Tobe_FSDeleteFileProc, + /* Function to process a + * 'Tobe_FSDeleteFile()' call. Should + * be implemented unless the FS is + * read-only. */ + Tobe_FSCopyFileProc, + /* Function to process a + * 'Tobe_FSCopyFile()' call. If not + * implemented Tcl will fall back + * on open-r, open-w and fcopy as + * a copying mechanism. */ + Tobe_FSRenameFileProc, + /* Function to process a + * 'Tobe_FSRenameFile()' call. If not + * implemented, Tcl will fall back on + * a copy and delete mechanism. */ + Tobe_FSCopyDirectoryProc, + /* Function to process a + * 'Tobe_FSCopyDirectory()' call. If + * not implemented, Tcl will fall back + * on a recursive create-dir, file copy + * mechanism. */ + Tobe_FSLoadFileProc, + /* Function to process a + * 'Tobe_FSLoadFile()' call. If not + * implemented, Tcl will fall back on + * a copy to native-temp followed by a + * Tobe_FSLoadFile on that temporary copy. */ + Tobe_FSUnloadFileProc, + /* Function to unload a previously + * successfully loaded file. If load was + * implemented, then this should also be + * implemented, if there is any cleanup + * action required. */ + Tobe_FSGetCwdProc, + /* + * Function to process a 'Tobe_FSGetCwd()' + * call. Most filesystems need not + * implement this. It will usually only be + * called once, if 'getcwd' is called + * before 'chdir'. May be NULL. + */ + Tobe_FSChdirProc, + /* + * Function to process a 'Tobe_FSChdir()' + * call. If filesystems do not implement + * this, it will be emulated by a series of + * directory access checks. Otherwise, + * virtual filesystems which do implement + * it need only respond with a positive + * return result if the dirName is a valid + * directory in their filesystem. They + * need not remember the result, since that + * will be automatically remembered for use + * by GetCwd. Real filesystems should + * carry out the correct action (i.e. call + * the correct system 'chdir' api). If not + * implemented, then 'cd' and 'pwd' will + * fail inside the filesystem. + */ +}; + +#endif + +////////////////////////////////////////////////////////////// + +void (*Zvfs_PostInit)(Tcl_Interp *)=0; +static int ZvfsAppendObjCmd( void *NotUsed, Tcl_Interp *interp, int objc, Tcl_Obj *const* objv); +static int ZvfsAddObjCmd( void *NotUsed, Tcl_Interp *interp, int objc, Tcl_Obj *const* objv); +static int ZvfsDumpObjCmd( void *NotUsed, Tcl_Interp *interp, int objc, Tcl_Obj *const* objv); +static int ZvfsStartObjCmd( void *NotUsed, Tcl_Interp *interp, int objc, Tcl_Obj *const* objv); + +/* +** Initialize the ZVFS system. +*/ +int Zvfs_doInit(Tcl_Interp *interp, int safe){ + int n; +#ifdef USE_TCL_STUBS + if( Tcl_InitStubs(interp,"8.0",0)==0 ){ + return TCL_ERROR; + } +#endif + Tcl_StaticPackage(interp, "zvfs", Tcl_Zvfs_Init, Tcl_Zvfs_SafeInit); + if (!safe) { + Tcl_CreateCommand(interp, "zvfs::mount", ZvfsMountCmd, 0, 0); + Tcl_CreateCommand(interp, "zvfs::unmount", ZvfsUnmountCmd, 0, 0); + Tcl_CreateObjCommand(interp, "zvfs::append", ZvfsAppendObjCmd, 0, 0); + Tcl_CreateObjCommand(interp, "zvfs::add", ZvfsAddObjCmd, 0, 0); + } + Tcl_CreateObjCommand(interp, "zvfs::exists", ZvfsExistsObjCmd, 0, 0); + Tcl_CreateObjCommand(interp, "zvfs::info", ZvfsInfoObjCmd, 0, 0); + Tcl_CreateObjCommand(interp, "zvfs::list", ZvfsListObjCmd, 0, 0); + Tcl_CreateObjCommand(interp, "zvfs::dump", ZvfsDumpObjCmd, 0, 0); + Tcl_CreateObjCommand(interp, "zvfs::start", ZvfsStartObjCmd, 0, 0); + Tcl_SetVar(interp, "::zvfs::auto_ext", ".tcl .tk .itcl .htcl .txt .c .h .tht", TCL_GLOBAL_ONLY); +/* Tcl_CreateObjCommand(interp, "zip::open", ZipOpenObjCmd, 0, 0); */ +#ifndef USE_TCL_VFS + Tcl_GlobalEval(interp, zFileCopy); +#endif + if( !local.isInit ){ + /* One-time initialization of the ZVFS */ +#ifdef USE_TCL_VFS + n = Tcl_FSRegister(0, &Tobe_Filesystem); +#else + extern void TclAccessInsertProc(); + extern void TclStatInsertProc(); + extern void TclOpenFileChannelInsertProc(); + TclAccessInsertProc(ZvfsFileAccess); + TclStatInsertProc(ZvfsFileStat); + TclOpenFileChannelInsertProc(ZvfsFileOpen); +#endif + Tcl_InitHashTable(&local.fileHash, TCL_STRING_KEYS); + Tcl_InitHashTable(&local.archiveHash, TCL_STRING_KEYS); + local.isInit = 1; + } + if (Zvfs_PostInit) Zvfs_PostInit(interp); + return TCL_OK; +} + +int Tcl_Zvfs_Init(Tcl_Interp *interp){ + return Zvfs_doInit(interp,0); +} + +int Tcl_Zvfs_SafeInit(Tcl_Interp *interp){ + return Zvfs_doInit(interp,1); +} + + +/************************************************************************/ +/************************************************************************/ +/************************************************************************/ + +/* +** Implement the zvfs::dump command +** +** zvfs::dump ARCHIVE +** +** Each entry in the list returned is of the following form: +** +** {FILENAME DATE-TIME SPECIAL-FLAG OFFSET SIZE COMPRESSED-SIZE} +** +*/ +static int ZvfsDumpObjCmd( + void *NotUsed, /* Client data for this command */ + Tcl_Interp *interp, /* The interpreter used to report errors */ + int objc, /* Number of arguments */ + Tcl_Obj *const* objv /* Values of all arguments */ +){ + char *zFilename; + Tcl_Channel chan; + ZFile *pList; + int rc; + Tcl_Obj *pResult; + + if( objc!=2 ){ + Tcl_WrongNumArgs(interp, 1, objv, "FILENAME"); + return TCL_ERROR; + } + zFilename = Tcl_GetString(objv[1]); + chan = Tcl_OpenFileChannel(interp, zFilename, "r", 0); + if( chan==0 ) return TCL_ERROR; + rc = ZvfsReadTOC(interp, chan, &pList); + if( rc==TCL_ERROR ){ + deleteZFileList(pList); + return rc; + } + Tcl_Close(interp, chan); + pResult = Tcl_GetObjResult(interp); + while( pList ){ + Tcl_Obj *pEntry = Tcl_NewObj(); + ZFile *pNext; + char zDateTime[100]; + Tcl_ListObjAppendElement(interp, pEntry, Tcl_NewStringObj(pList->zName,-1)); + translateDosTimeDate(zDateTime, pList->dosDate, pList->dosTime); + Tcl_ListObjAppendElement(interp, pEntry, Tcl_NewStringObj(zDateTime, -1)); + Tcl_ListObjAppendElement(interp, pEntry, Tcl_NewIntObj(pList->isSpecial)); + Tcl_ListObjAppendElement(interp, pEntry, Tcl_NewIntObj(pList->iOffset)); + Tcl_ListObjAppendElement(interp, pEntry, Tcl_NewIntObj(pList->nByte)); + Tcl_ListObjAppendElement(interp, pEntry, Tcl_NewIntObj(pList->nByteCompr)); + Tcl_ListObjAppendElement(interp, pResult, pEntry); + pNext = pList->pNext; + Tcl_Free((char*)pList); + pList = pList->pNext; + } + return TCL_OK; +} + +/* +** Write a file record into a ZIP archive at the current position of +** the write cursor for channel "chan". Add a ZFile record for the file +** to *ppList. If an error occurs, leave an error message on interp +** and return TCL_ERROR. Otherwise return TCL_OK. +*/ +static int writeFile( + Tcl_Interp *interp, /* Leave an error message here */ + Tcl_Channel out, /* Write the file here */ + Tcl_Channel in, /* Read data from this file */ + char *zSrc, /* Name the new ZIP file entry this */ + char *zDest, /* Name the new ZIP file entry this */ + ZFile **ppList /* Put a ZFile struct for the new file here */ +){ + z_stream stream; + ZFile *p; + int iEndOfData; + int nameLen; + int skip; + int toOut; + char zHdr[30]; + char zInBuf[100000]; + char zOutBuf[100000]; + struct tm *tm; + time_t now; + struct stat stat; + + /* Create a new ZFile structure for this file. + * TODO: fill in date/time etc. + */ + nameLen = strlen(zDest); + p = newZFile(nameLen, ppList); + strcpy(p->zName, zDest); + p->isSpecial = 0; + Tcl_Stat(zSrc, &stat); + now=stat.st_mtime; + tm = localtime(&now); + UnixTimeDate(tm, &p->dosDate, &p->dosTime); + p->iOffset = Tcl_Tell(out); + p->nByte = 0; + p->nByteCompr = 0; + p->nExtra = 0; + p->iCRC = 0; + p->permissions = stat.st_mode; + + /* Fill in as much of the header as we know. + */ + put32(&zHdr[0], 0x04034b50); + put16(&zHdr[4], 0x0014); + put16(&zHdr[6], 0); + put16(&zHdr[8], 8); + put16(&zHdr[10], p->dosTime); + put16(&zHdr[12], p->dosDate); + put16(&zHdr[26], nameLen); + put16(&zHdr[28], 0); + + /* Write the header and filename. + */ + Tcl_Write(out, zHdr, 30); + Tcl_Write(out, zDest, nameLen); + + /* The first two bytes that come out of the deflate compressor are + ** some kind of header that ZIP does not use. So skip the first two + ** output bytes. + */ + skip = 2; + + /* Write the compressed file. Compute the CRC as we progress. + */ + stream.zalloc = (alloc_func)0; + stream.zfree = (free_func)0; + stream.opaque = 0; + stream.avail_in = 0; + stream.next_in = zInBuf; + stream.avail_out = sizeof(zOutBuf); + stream.next_out = zOutBuf; +#if 1 + deflateInit(&stream, 9); +#else + { + int i, err, WSIZE = 0x8000, windowBits, level=6; + for (i = ((unsigned)WSIZE), windowBits = 0; i != 1; i >>= 1, ++windowBits); + err = deflateInit2(&stream, level, Z_DEFLATED, -windowBits, 8, 0); + + } +#endif + p->iCRC = crc32(0, 0, 0); + while( !Tcl_Eof(in) ){ + if( stream.avail_in==0 ){ + int amt = Tcl_Read(in, zInBuf, sizeof(zInBuf)); + if( amt<=0 ) break; + p->iCRC = crc32(p->iCRC, zInBuf, amt); + stream.avail_in = amt; + stream.next_in = zInBuf; + } + deflate(&stream, 0); + toOut = sizeof(zOutBuf) - stream.avail_out; + if( toOut>skip ){ + Tcl_Write(out, &zOutBuf[skip], toOut - skip); + skip = 0; + }else{ + skip -= toOut; + } + stream.avail_out = sizeof(zOutBuf); + stream.next_out = zOutBuf; + } + do{ + stream.avail_out = sizeof(zOutBuf); + stream.next_out = zOutBuf; + deflate(&stream, Z_FINISH); + toOut = sizeof(zOutBuf) - stream.avail_out; + if( toOut>skip ){ + Tcl_Write(out, &zOutBuf[skip], toOut - skip); + skip = 0; + }else{ + skip -= toOut; + } + }while( stream.avail_out==0 ); + p->nByte = stream.total_in; + p->nByteCompr = stream.total_out - 2; + deflateEnd(&stream); + Tcl_Flush(out); + + /* Remember were we are in the file. Then go back and write the + ** header, now that we know the compressed file size. + */ + iEndOfData = Tcl_Tell(out); + Tcl_Seek(out, p->iOffset, SEEK_SET); + put32(&zHdr[14], p->iCRC); + put32(&zHdr[18], p->nByteCompr); + put32(&zHdr[22], p->nByte); + Tcl_Write(out, zHdr, 30); + Tcl_Seek(out, iEndOfData, SEEK_SET); + + /* Close the input file. + */ + Tcl_Close(interp, in); + + /* Finished! + */ + return TCL_OK; +} + +/* +** The arguments are two lists of ZFile structures sorted by iOffset. +** Either or both list may be empty. This routine merges the two +** lists together into a single sorted list and returns a pointer +** to the head of the unified list. +** +** This is part of the merge-sort algorithm. +*/ +static ZFile *mergeZFiles(ZFile *pLeft, ZFile *pRight){ + ZFile fakeHead; + ZFile *pTail; + + pTail = &fakeHead; + while( pLeft && pRight ){ + ZFile *p; + if( pLeft->iOffset <= pRight->iOffset ){ + p = pLeft; + pLeft = p->pNext; + }else{ + p = pRight; + pRight = p->pNext; + } + pTail->pNext = p; + pTail = p; + } + if( pLeft ){ + pTail->pNext = pLeft; + }else if( pRight ){ + pTail->pNext = pRight; + }else{ + pTail->pNext = 0; + } + return fakeHead.pNext; +} + +/* +** Sort a ZFile list so in accending order by iOffset. +*/ +static ZFile *sortZFiles(ZFile *pList){ +# define NBIN 30 + int i; + ZFile *p; + ZFile *aBin[NBIN+1]; + + for(i=0; i<=NBIN; i++) aBin[i] = 0; + while( pList ){ + p = pList; + pList = p->pNext; + p->pNext = 0; + for(i=0; ipNext){ + if( pList->isSpecial ) continue; + put32(&zBuf[0], 0x02014b50); + put16(&zBuf[4], 0x0317); + put16(&zBuf[6], 0x0014); + put16(&zBuf[8], 0); + put16(&zBuf[10], pList->nByte>pList->nByteCompr ? 0x0008 : 0x0000); + put16(&zBuf[12], pList->dosTime); + put16(&zBuf[14], pList->dosDate); + put32(&zBuf[16], pList->iCRC); + put32(&zBuf[20], pList->nByteCompr); + put32(&zBuf[24], pList->nByte); + put16(&zBuf[28], strlen(pList->zName)); + put16(&zBuf[30], 0); + put16(&zBuf[32], pList->nExtra); + put16(&zBuf[34], 1); + put16(&zBuf[36], 0); + put32(&zBuf[38], pList->permissions<<16); + put32(&zBuf[42], pList->iOffset); + Tcl_Write(chan, zBuf, 46); + Tcl_Write(chan, pList->zName, strlen(pList->zName)); + for(i=pList->nExtra; i>0; i-=40){ + int toWrite = i<40 ? i : 40; + Tcl_Write(chan," ",toWrite); + } + nEntry++; + } + iTocEnd = Tcl_Tell(chan); + put32(&zBuf[0], 0x06054b50); + put16(&zBuf[4], 0); + put16(&zBuf[6], 0); + put16(&zBuf[8], nEntry); + put16(&zBuf[10], nEntry); + put32(&zBuf[12], iTocEnd - iTocStart); + put32(&zBuf[16], iTocStart); + put16(&zBuf[20], 0); + Tcl_Write(chan, zBuf, 22); + Tcl_Flush(chan); +} + + +/* +** Implementation of the zvfs::append command. +** +** zvfs::append ARCHIVE (SOURCE DESTINATION)* +** +** This command reads SOURCE files and appends them (using the name +** DESTINATION) to the zip archive named ARCHIVE. A new zip archive +** is created if it does not already exist. If ARCHIVE refers to a +** file which exists but is not a zip archive, then this command +** turns ARCHIVE into a zip archive by appending the necessary +** records and the table of contents. Treat all files as binary. +** +** Note: No dup checking is done, so multiple occurances of the +** same file is allowed. +*/ +static int ZvfsAppendObjCmd( + void *NotUsed, /* Client data for this command */ + Tcl_Interp *interp, /* The interpreter used to report errors */ + int objc, /* Number of arguments */ + Tcl_Obj *const* objv /* Values of all arguments */ +){ + char *zArchive; + Tcl_Channel chan; + ZFile *pList = NULL, *pToc; + int rc = TCL_OK, i; + + /* Open the archive and read the table of contents + */ + if( objc<2 || (objc&1)!=0 ){ + Tcl_WrongNumArgs(interp, 1, objv, "ARCHIVE (SRC DEST)+"); + return TCL_ERROR; + } + + zArchive = Tcl_GetString(objv[1]); + chan = Tcl_OpenFileChannel(interp, zArchive, "r+", 0644); + if( chan==0 ) { + chan = Tcl_OpenFileChannel(interp, zArchive, "w+", 0644); + } + if( chan==0 ) return TCL_ERROR; + if( Tcl_SetChannelOption(interp, chan, "-translation", "binary") + || Tcl_SetChannelOption(interp, chan, "-encoding", "binary") + ){ + /* this should never happen */ + Tcl_Close(0, chan); + return TCL_ERROR; + } + + if (Tcl_Seek(chan, 0, SEEK_END) == 0) { + /* Null file is ok, we're creating new one. */ + } else { + Tcl_Seek(chan, 0, SEEK_SET); + rc = ZvfsReadTOC(interp, chan, &pList); + if( rc==TCL_ERROR ){ + deleteZFileList(pList); + Tcl_Close(interp, chan); + return rc; + } else rc=TCL_OK; + } + + /* Move the file pointer to the start of + ** the table of contents. + */ + for(pToc=pList; pToc; pToc=pToc->pNext){ + if( pToc->isSpecial && strcmp(pToc->zName,"*TOC*")==0 ) break; + } + if( pToc ){ + Tcl_Seek(chan, pToc->iOffset, SEEK_SET); + }else{ + Tcl_Seek(chan, 0, SEEK_END); + } + + /* Add new files to the end of the archive. + */ + for(i=2; rc==TCL_OK && i p)) { + p = NULL; + } + return p; +} + +/* +** Implementation of the zvfs::add command. +** +** zvfs::add ?-fconfigure optpairs? ARCHIVE FILE1 FILE2 ... +** +** This command is similar to append in that it adds files to the zip +** archive named ARCHIVE, however file names are relative the current directory. +** In addition, fconfigure is used to apply option pairs to set upon opening +** of each file. Otherwise, default translation is allowed +** for those file extensions listed in the ::zvfs::auto_ext var. +** Binary translation will be used for unknown extensions. +** +** NOTE Use '-fconfigure {}' to use auto translation for all. +*/ +static int ZvfsAddObjCmd( + void *NotUsed, /* Client data for this command */ + Tcl_Interp *interp, /* The interpreter used to report errors */ + int objc, /* Number of arguments */ + Tcl_Obj *CONST* objv /* Values of all arguments */ +){ + char *zArchive; + Tcl_Channel chan; + ZFile *pList = NULL, *pToc; + int rc = TCL_OK, i, j, oLen; + char *zOpts = NULL; + Tcl_Obj *confOpts = NULL; + int tobjc; + Tcl_Obj **tobjv; + Tcl_Obj *varObj = NULL; + + /* Open the archive and read the table of contents + */ + if (objc>3) { + zOpts = Tcl_GetStringFromObj(objv[1], &oLen); + if (!strncmp("-fconfigure", zOpts, oLen)) { + confOpts = objv[2]; + if (TCL_OK != Tcl_ListObjGetElements(interp, confOpts, &tobjc, &tobjv) || (tobjc%2)) { + return TCL_ERROR; + } + objc -= 2; + objv += 2; + } + } + if( objc==2) { + return TCL_OK; + } + + if( objc<3) { + Tcl_WrongNumArgs(interp, 1, objv, "?-fconfigure OPTPAIRS? ARCHIVE FILE1 FILE2 .."); + return TCL_ERROR; + } + zArchive = Tcl_GetString(objv[1]); + chan = Tcl_OpenFileChannel(interp, zArchive, "r+", 0644); + if( chan==0 ) { + chan = Tcl_OpenFileChannel(interp, zArchive, "w+", 0644); + } + if( chan==0 ) return TCL_ERROR; + if( Tcl_SetChannelOption(interp, chan, "-translation", "binary") + || Tcl_SetChannelOption(interp, chan, "-encoding", "binary") + ){ + /* this should never happen */ + Tcl_Close(0, chan); + return TCL_ERROR; + } + + if (Tcl_Seek(chan, 0, SEEK_END) == 0) { + /* Null file is ok, we're creating new one. */ + } else { + Tcl_Seek(chan, 0, SEEK_SET); + rc = ZvfsReadTOC(interp, chan, &pList); + if( rc==TCL_ERROR ){ + deleteZFileList(pList); + Tcl_Close(interp, chan); + return rc; + } else rc=TCL_OK; + } + + /* Move the file pointer to the start of + ** the table of contents. + */ + for(pToc=pList; pToc; pToc=pToc->pNext){ + if( pToc->isSpecial && strcmp(pToc->zName,"*TOC*")==0 ) break; + } + if( pToc ){ + Tcl_Seek(chan, pToc->iOffset, SEEK_SET); + }else{ + Tcl_Seek(chan, 0, SEEK_END); + } + + /* Add new files to the end of the archive. + */ + for(i=2; rc==TCL_OK && i=tobjc) { + ext = NULL; + } + + } + } + if (ext == NULL) { + if (( Tcl_SetChannelOption(interp, in, "-translation", "binary") + || Tcl_SetChannelOption(interp, in, "-encoding", "binary")) + ) { + /* this should never happen */ + Tcl_Close(0, in); + rc = TCL_ERROR; + break; + } + } + } else { + for (j=0; j> ${TCLKIT_EXE} + # Must be empty so it doesn't conflict with rule for ${TCL_EXE} above ${NATIVE_TCLSH}: @@ -1319,6 +1329,9 @@ tclUtf.o: $(GENERIC_DIR)/tclUtf.c $(GENERIC_DIR)/tclUniData.c tclVar.o: $(GENERIC_DIR)/tclVar.c $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclVar.c +tclZipVfs.o: $(GENERIC_DIR)/tclZipVfs.c + $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclZipVfs.c + tclZlib.o: $(GENERIC_DIR)/tclZlib.c $(CC) -c $(CC_SWITCHES) $(ZLIB_INCLUDE) $(GENERIC_DIR)/tclZlib.c diff --git a/unix/tclAppInit.c b/unix/tclAppInit.c index 9bbc88b..cdfff59 100644 --- a/unix/tclAppInit.c +++ b/unix/tclAppInit.c @@ -15,7 +15,7 @@ #undef BUILD_tcl #undef STATIC_BUILD #include "tcl.h" - +#include "tclInt.h" #ifdef TCL_TEST extern Tcl_PackageInitProc Tcltest_Init; extern Tcl_PackageInitProc Tcltest_SafeInit; @@ -108,6 +108,29 @@ int Tcl_AppInit( Tcl_Interp *interp) /* Interpreter for application. */ { + CONST char *cp=Tcl_GetNameOfExecutable(); + /* We have to initialize the virtual filesystem before calling + ** Tcl_Init(). Otherwise, Tcl_Init() will not be able to find + ** its startup script files. + */ + Tcl_Zvfs_Init(interp); + if(!Tcl_Zvfs_Mount(interp, cp, "/zvfs")) { + Tcl_Obj *vfsinitscript=Tcl_NewStringObj("/zvfs/main.tcl",-1); + Tcl_Obj *vfstcllib=Tcl_NewStringObj("/zvfs/tcl8.6",-1); + + Tcl_IncrRefCount(vfsinitscript); + Tcl_IncrRefCount(vfstcllib); + + if(Tcl_FSAccess(vfsinitscript,F_OK)==0) { + Tcl_SetStartupScript(vfsinitscript,NULL); + } + if(Tcl_FSAccess(vfstcllib,F_OK)==0) { + Tcl_SetVar2(interp, "env", "TCL_LIBRARY", Tcl_GetString(vfstcllib), TCL_GLOBAL_ONLY); + } + Tcl_DecrRefCount(vfsinitscript); + Tcl_DecrRefCount(vfstcllib); + } + if ((Tcl_Init)(interp) == TCL_ERROR) { return TCL_ERROR; } @@ -124,7 +147,7 @@ Tcl_AppInit( } Tcl_StaticPackage(interp, "Tcltest", Tcltest_Init, Tcltest_SafeInit); #endif /* TCL_TEST */ - + /* * Call the init procedures for included packages. Each call should look * like this: diff --git a/win/Makefile.in b/win/Makefile.in index 150f5b8..b883e8a 100644 --- a/win/Makefile.in +++ b/win/Makefile.in @@ -145,6 +145,7 @@ SHARED_LIBRARIES = $(TCL_DLL_FILE) @ZLIB_DLL_FILE@ STATIC_LIBRARIES = $(TCL_LIB_FILE) TCLSH = tclsh$(VER)${EXESUFFIX} +TCLKIT = tclkit$(VER)${EXESUFFIX} CAT32 = cat32$(EXEEXT) MAN2TCL = man2tcl$(EXEEXT) @@ -294,7 +295,8 @@ GENERIC_OBJS = \ tclUtf.$(OBJEXT) \ tclUtil.$(OBJEXT) \ tclVar.$(OBJEXT) \ - tclZlib.$(OBJEXT) + tclZlib.$(OBJEXT) \ + tclZipVfs.$(OBJEXT) TOMMATH_OBJS = \ bncore.${OBJEXT} \ @@ -422,6 +424,15 @@ $(TCLSH): $(TCLSH_OBJS) @LIBRARIES@ $(TCL_STUB_LIB_FILE) tclsh.$(RES) tclsh.$(RES) $(CC_EXENAME) $(LDFLAGS_CONSOLE) @VC_MANIFEST_EMBED_EXE@ +$(TCLKIT): $(TCLSH_OBJS) @LIBRARIES@ ${TCL_OBJS} tclsh.$(RES) + $(CC) $(CFLAGS) ${TCL_OBJS} $(TCLSH_OBJS) $(LIBS) \ + tclsh.$(RES) $(CC_EXENAME) $(LDFLAGS_CONSOLE) + PWD=`pwd` + rm -f tclkit.zip + cp $(TCLSH) $(TCLKIT) + cd $(SCRIPT_INSTALL_DIR) ; zip -rAq ${PWD}/tclkit.zip tcl8 tcl8.6 + $(CAT32) tclkit.zip >> $(TCLKIT) + cat32.$(OBJEXT): cat.c $(CC) -c $(CC_SWITCHES) @DEPARG@ $(CC_OBJNAME) diff --git a/win/makefile.bc b/win/makefile.bc index a962bc6..e005979 100644 --- a/win/makefile.bc +++ b/win/makefile.bc @@ -275,6 +275,7 @@ TCLOBJS = \ $(TMPDIR)\tclWinSock.obj \ $(TMPDIR)\tclWinThrd.obj \ $(TMPDIR)\tclWinTime.obj \ + $(TMP_DIR)\tclZipVfs.obj \ $(TMPDIR)\tclZlib.obj TCLSTUBOBJS = \ diff --git a/win/makefile.vc b/win/makefile.vc index e5f6c9b..43644cc 100644 --- a/win/makefile.vc +++ b/win/makefile.vc @@ -343,6 +343,7 @@ COREOBJS = \ $(TMP_DIR)\tclUtf.obj \ $(TMP_DIR)\tclUtil.obj \ $(TMP_DIR)\tclVar.obj \ + $(TMP_DIR)\tclZipVfs.obj \ $(TMP_DIR)\tclZlib.obj ZLIBOBJS = \ @@ -931,6 +932,9 @@ $(TMP_DIR)\tclTestObj.obj: $(GENERICDIR)\tclTestObj.c $(TMP_DIR)\tclWinTest.obj: $(WINDIR)\tclWinTest.c $(cc32) $(TCL_CFLAGS) -Fo$@ $? +$(TMP_DIR)\tclZipVfs.obj: $(GENERICDIR)\tclZipVfs.c + $(cc32) $(TCL_CFLAGS) -I$(COMPATDIR)\zlib -DBUILD_tcl -Fo$@ $? + $(TMP_DIR)\tclZlib.obj: $(GENERICDIR)\tclZlib.c $(cc32) $(TCL_CFLAGS) -I$(COMPATDIR)\zlib -DBUILD_tcl -Fo$@ $? diff --git a/win/tclAppInit.c b/win/tclAppInit.c index a6c1a67..3cfd662 100644 --- a/win/tclAppInit.c +++ b/win/tclAppInit.c @@ -15,6 +15,7 @@ */ #include "tcl.h" +#include "tclInt.h" #define WIN32_LEAN_AND_MEAN #include #undef WIN32_LEAN_AND_MEAN @@ -151,6 +152,27 @@ int Tcl_AppInit( Tcl_Interp *interp) /* Interpreter for application. */ { + CONST char *cp=Tcl_GetNameOfExecutable(); + /* We have to initialize the virtual filesystem before calling + ** Tcl_Init(). Otherwise, Tcl_Init() will not be able to find + ** its startup script files. + */ + Tcl_Zvfs_Init(interp); + if(!Tcl_Zvfs_Mount(interp, cp, "/zvfs")) { + Tcl_Obj *vfsinitscript=Tcl_NewStringObj("/zvfs/main.tcl",-1); + Tcl_Obj *vfstcllib=Tcl_NewStringObj("/zvfs/tcl8.6",-1); + + Tcl_IncrRefCount(vfsinitscript); + if(Tcl_FSAccess(vfsinitscript,F_OK)==0) { + Tcl_SetStartupScript(vfsinitscript,NULL); + } + //Tcl_DecrRefCount(vfsinitscript); + if(Tcl_FSAccess(vfstcllib,F_OK)==0) { + Tcl_SetVar2(interp, "env", "TCL_LIBRARY", Tcl_GetString(vfstcllib), TCL_GLOBAL_ONLY); + } + Tcl_DecrRefCount(vfstcllib); + } + if ((Tcl_Init)(interp) == TCL_ERROR) { return TCL_ERROR; } diff --git a/win/tclkit.exe.manifest.in b/win/tclkit.exe.manifest.in new file mode 100644 index 0000000..13c1d24 --- /dev/null +++ b/win/tclkit.exe.manifest.in @@ -0,0 +1,51 @@ + + + + Tcl self-contained executable (tclkit) + + + + + + + + + + + + + + + + + + + + + + true + + + + + + + + diff --git a/win/tclkit.rc b/win/tclkit.rc new file mode 100644 index 0000000..ebe37e1 --- /dev/null +++ b/win/tclkit.rc @@ -0,0 +1,82 @@ +// +// Version Resource Script +// + +#include +#include + +// +// build-up the name suffix that defines the type of build this is. +// +#if TCL_THREADS +#define SUFFIX_THREADS "t" +#else +#define SUFFIX_THREADS "" +#endif + +#if STATIC_BUILD +#define SUFFIX_STATIC "s" +#else +#define SUFFIX_STATIC "" +#endif + +#if DEBUG && !UNCHECKED +#define SUFFIX_DEBUG "g" +#else +#define SUFFIX_DEBUG "" +#endif + +#define SUFFIX SUFFIX_THREADS SUFFIX_STATIC SUFFIX_DEBUG + + +LANGUAGE 0x9, 0x1 /* LANG_ENGLISH, SUBLANG_DEFAULT */ + +VS_VERSION_INFO VERSIONINFO + FILEVERSION TCL_MAJOR_VERSION,TCL_MINOR_VERSION,TCL_RELEASE_LEVEL,TCL_RELEASE_SERIAL + PRODUCTVERSION TCL_MAJOR_VERSION,TCL_MINOR_VERSION,TCL_RELEASE_LEVEL,TCL_RELEASE_SERIAL + FILEFLAGSMASK 0x3fL +#ifdef DEBUG + FILEFLAGS VS_FF_DEBUG +#else + FILEFLAGS 0x0L +#endif + FILEOS VOS__WINDOWS32 + FILETYPE VFT_APP + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "FileDescription", "Tclkit Application\0" + VALUE "OriginalFilename", "tclkit" STRINGIFY(TCL_MAJOR_VERSION) STRINGIFY(TCL_MINOR_VERSION) SUFFIX ".exe\0" + VALUE "CompanyName", "ActiveState Corporation\0" + VALUE "FileVersion", TCL_PATCH_LEVEL + VALUE "LegalCopyright", "Copyright \251 2000 by ActiveState Corporation, et al\0" + VALUE "ProductName", "Tcl " TCL_VERSION " for Windows\0" + VALUE "ProductVersion", TCL_PATCH_LEVEL + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END + +// +// Icon +// + +tclsh ICON DISCARDABLE "tclsh.ico" + +// +// This is needed for Windows 8.1 onwards. +// + +#ifndef RT_MANIFEST +#define RT_MANIFEST 24 +#endif +#ifndef CREATEPROCESS_MANIFEST_RESOURCE_ID +#define CREATEPROCESS_MANIFEST_RESOURCE_ID 1 +#endif +CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "tclkit.exe.manifest" -- cgit v0.12 From eb664a3d72c2a03a6237b20db543d344517f3e83 Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Mon, 1 Sep 2014 09:36:58 +0000 Subject: Tweak the Windows implementation of Tcl_AppInit() to match Unix --- win/tclAppInit.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/win/tclAppInit.c b/win/tclAppInit.c index 3cfd662..7edd455 100644 --- a/win/tclAppInit.c +++ b/win/tclAppInit.c @@ -163,13 +163,15 @@ Tcl_AppInit( Tcl_Obj *vfstcllib=Tcl_NewStringObj("/zvfs/tcl8.6",-1); Tcl_IncrRefCount(vfsinitscript); + Tcl_IncrRefCount(vfstcllib); + if(Tcl_FSAccess(vfsinitscript,F_OK)==0) { Tcl_SetStartupScript(vfsinitscript,NULL); } - //Tcl_DecrRefCount(vfsinitscript); if(Tcl_FSAccess(vfstcllib,F_OK)==0) { Tcl_SetVar2(interp, "env", "TCL_LIBRARY", Tcl_GetString(vfstcllib), TCL_GLOBAL_ONLY); } + Tcl_DecrRefCount(vfsinitscript); Tcl_DecrRefCount(vfstcllib); } -- cgit v0.12 From d1536b7378b5014b664c0b5c91919f9be5a4253f Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Mon, 1 Sep 2014 09:41:09 +0000 Subject: Tweaks to the Windows makefile. --- win/Makefile.in | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/win/Makefile.in b/win/Makefile.in index b883e8a..07c8db1 100644 --- a/win/Makefile.in +++ b/win/Makefile.in @@ -424,14 +424,16 @@ $(TCLSH): $(TCLSH_OBJS) @LIBRARIES@ $(TCL_STUB_LIB_FILE) tclsh.$(RES) tclsh.$(RES) $(CC_EXENAME) $(LDFLAGS_CONSOLE) @VC_MANIFEST_EMBED_EXE@ -$(TCLKIT): $(TCLSH_OBJS) @LIBRARIES@ ${TCL_OBJS} tclsh.$(RES) +tclkit: $(TCLKIT) + +$(TCLKIT): $(TCLSH_OBJS) @LIBRARIES@ ${TCL_OBJS} $(CAT32) tclsh.$(RES) $(CC) $(CFLAGS) ${TCL_OBJS} $(TCLSH_OBJS) $(LIBS) \ tclsh.$(RES) $(CC_EXENAME) $(LDFLAGS_CONSOLE) PWD=`pwd` rm -f tclkit.zip cp $(TCLSH) $(TCLKIT) - cd $(SCRIPT_INSTALL_DIR) ; zip -rAq ${PWD}/tclkit.zip tcl8 tcl8.6 - $(CAT32) tclkit.zip >> $(TCLKIT) + cd ${prefix}/lib ; zip -rq ${PWD}/tclkit.zip tcl8 tcl8.6 + cat tclkit.zip >> $(TCLKIT) cat32.$(OBJEXT): cat.c $(CC) -c $(CC_SWITCHES) @DEPARG@ $(CC_OBJNAME) @@ -878,6 +880,6 @@ html-tk: $(TCLSH) .PHONY: install-doc install-private-headers test test-tcl runtest shell .PHONY: gdb depend cleanhelp clean distclean packages install-packages .PHONY: test-packages clean-packages distclean-packages genstubs html -.PHONY: html-tcl html-tk +.PHONY: html-tcl html-tk tclkit # DO NOT DELETE THIS LINE -- make depend depends on it. -- cgit v0.12 From 78b3c04320aac05d5acdc2a424df7f898de7bc6a Mon Sep 17 00:00:00 2001 From: dkf Date: Mon, 1 Sep 2014 10:45:41 +0000 Subject: Bring the source more into line with Tcl style. --- generic/tclZipVfs.c | 4365 +++++++++++++++++++++++++++------------------------ 1 file changed, 2326 insertions(+), 2039 deletions(-) diff --git a/generic/tclZipVfs.c b/generic/tclZipVfs.c index 0456b4a..a774648 100755 --- a/generic/tclZipVfs.c +++ b/generic/tclZipVfs.c @@ -1,27 +1,25 @@ /* -** Copyright (c) 2000 D. Richard Hipp -** Copyright (c) 2007 PDQ Interfaces Inc. -** Copyright (c) 2013 Sean Woods -** -** This file is now released under the BSD style license -** outlined in the included file license.terms. -** -************************************************************************* -** A ZIP archive virtual filesystem for Tcl. -** -** This package of routines enables Tcl to use a Zip file as -** a virtual file system. Each of the content files of the Zip -** archive appears as a real file to Tcl. -** -** Well, almost... Actually, the virtual file system is limited -** in a number of ways. The only things you can do are "stat" -** and "read" file content files. You cannot use "cd". -** But it turns out that "stat" -** and "read" are sufficient for most purposes. -** -** This version has been modified to run under Tcl 8.6 -** -*/ + * Copyright (c) 2000 D. Richard Hipp + * Copyright (c) 2007 PDQ Interfaces Inc. + * Copyright (c) 2013 Sean Woods + * + * This file is now released under the BSD style license outlined in the + * included file license.terms. + * + ************************************************************************ + * A ZIP archive virtual filesystem for Tcl. + * + * This package of routines enables Tcl to use a Zip file as a virtual file + * system. Each of the content files of the Zip archive appears as a real + * file to Tcl. + * + * Well, almost... Actually, the virtual file system is limited in a number + * of ways. The only things you can do are "stat" and "read" file content + * files. You cannot use "cd". But it turns out that "stat" and "read" are + * sufficient for most purposes. + * + * This version has been modified to run under Tcl 8.6 + */ #include "tcl.h" #include #include @@ -35,1192 +33,1385 @@ #endif /* -** Size of the decompression input buffer -*/ -#define COMPR_BUF_SIZE 8192 + * Size of the decompression input buffer + */ +#define COMPR_BUF_SIZE 8192 static int maptolower=0; -static int openarch=0; /* Set to 1 when opening archive. */ +static int openarch=0; /* Set to 1 when opening archive. */ /* -** All static variables are collected into a structure named "local". -** That way, it is clear in the code when we are using a static -** variable because its name begins with "local.". -*/ + * All static variables are collected into a structure named "local". That + * way, it is clear in the code when we are using a static variable because + * its name begins with "local.". + */ static struct { - Tcl_HashTable fileHash; /* One entry for each file in the ZVFS. The - ** The key is the virtual filename. The data - ** an an instance of the ZvfsFile structure. */ - Tcl_HashTable archiveHash; /* One entry for each archive. Key is the name. - ** data is the ZvfsArchive structure */ - int isInit; /* True after initialization */ + Tcl_HashTable fileHash; /* One entry for each file in the ZVFS. The + * key is the virtual filename. The data is an + * instance of the ZvfsFile structure. */ + Tcl_HashTable archiveHash; /* One entry for each archive. Key is the + * name. The data is the ZvfsArchive + * structure. */ + int isInit; /* True after initialization */ } local; /* -** Each ZIP archive file that is mounted is recorded as an instance -** of this structure -*/ + * Each ZIP archive file that is mounted is recorded as an instance of this + * structure + */ typedef struct ZvfsArchive { - char *zName; /* Name of the archive */ - char *zMountPoint; /* Where this archive is mounted */ - struct ZvfsFile *pFiles; /* List of files in that archive */ + char *zName; /* Name of the archive */ + char *zMountPoint; /* Where this archive is mounted */ + struct ZvfsFile *pFiles; /* List of files in that archive */ } ZvfsArchive; /* -** Particulars about each virtual file are recorded in an instance -** of the following structure. -*/ + * Particulars about each virtual file are recorded in an instance of the + * following structure. + */ typedef struct ZvfsFile { - char *zName; /* The full pathname of the virtual file */ - ZvfsArchive *pArchive; /* The ZIP archive holding this file data */ - int iOffset; /* Offset into the ZIP archive of the data */ - int nByte; /* Uncompressed size of the virtual file */ - int nByteCompr; /* Compressed size of the virtual file */ - time_t timestamp; /* Modification time */ - int isdir; /* Set to 2 if directory, or 1 if mount */ - int depth; /* Number of slashes in path. */ - int permissions; /* File permissions. */ - struct ZvfsFile *pNext; /* Next file in the same archive */ - struct ZvfsFile *pNextName; /* A doubly-linked list of files with the same */ - struct ZvfsFile *pPrevName; /* name. Only the first is in local.fileHash */ + char *zName; /* The full pathname of the virtual file */ + ZvfsArchive *pArchive; /* The ZIP archive holding this file data */ + int iOffset; /* Offset into the ZIP archive of the data */ + int nByte; /* Uncompressed size of the virtual file */ + int nByteCompr; /* Compressed size of the virtual file */ + time_t timestamp; /* Modification time */ + int isdir; /* Set to 2 if directory, or 1 if mount */ + int depth; /* Number of slashes in path. */ + int permissions; /* File permissions. */ + struct ZvfsFile *pNext; /* Next file in the same archive */ + struct ZvfsFile *pNextName; /* A doubly-linked list of files with the + * _same_ name. Only the first is in + * local.fileHash */ + struct ZvfsFile *pPrevName; } ZvfsFile; /* -** Information about each file within a ZIP archive is stored in -** an instance of the following structure. A list of these structures -** forms a table of contents for the archive. -*/ + * Information about each file within a ZIP archive is stored in an instance + * of the following structure. A list of these structures forms a table of + * contents for the archive. + */ typedef struct ZFile ZFile; struct ZFile { - char *zName; /* Name of the file */ - int isSpecial; /* Not really a file in the ZIP archive */ - int dosTime; /* Modification time (DOS format) */ - int dosDate; /* Modification date (DOS format) */ - int iOffset; /* Offset into the ZIP archive of the data */ - int nByte; /* Uncompressed size of the virtual file */ - int nByteCompr; /* Compressed size of the virtual file */ - int nExtra; /* Extra space in the TOC header */ - int iCRC; /* Cyclic Redundancy Check of the data */ - int permissions; /* File permissions. */ - int flags; /* Deletion = bit 0. */ - ZFile *pNext; /* Next file in the same archive */ + char *zName; /* Name of the file */ + int isSpecial; /* Not really a file in the ZIP archive */ + int dosTime; /* Modification time (DOS format) */ + int dosDate; /* Modification date (DOS format) */ + int iOffset; /* Offset into the ZIP archive of the data */ + int nByte; /* Uncompressed size of the virtual file */ + int nByteCompr; /* Compressed size of the virtual file */ + int nExtra; /* Extra space in the TOC header */ + int iCRC; /* Cyclic Redundancy Check of the data */ + int permissions; /* File permissions. */ + int flags; /* Deletion = bit 0. */ + ZFile *pNext; /* Next file in the same archive */ }; -EXTERN int Tcl_Zvfs_Mount(Tcl_Interp *interp,CONST char *zArchive,CONST char *zMountPoint); -EXTERN int Tcl_Zvfs_Umount(CONST char *zArchive); +EXTERN int Tcl_Zvfs_Mount(Tcl_Interp *interp,const char *zArchive,const char *zMountPoint); +EXTERN int Tcl_Zvfs_Umount(const char *zArchive); EXTERN int Tcl_Zvfs_Init(Tcl_Interp *interp); EXTERN int Tcl_Zvfs_SafeInit(Tcl_Interp *interp); + /* -** Macros to read 16-bit and 32-bit big-endian integers into the -** native format of this local processor. B is an array of -** characters and the integer begins at the N-th character of -** the array. -*/ + * Macros to read 16-bit and 32-bit big-endian integers into the native format + * of this local processor. B is an array of characters and the integer + * begins at the N-th character of the array. + */ #define INT16(B, N) (B[N] + (B[N+1]<<8)) #define INT32(B, N) (INT16(B,N) + (B[N+2]<<16) + (B[N+3]<<24)) /* -** Write a 16- or 32-bit integer as little-endian into the given buffer. -*/ -static void put16(char *z, int v){ - z[0] = v & 0xff; - z[1] = (v>>8) & 0xff; + * Write a 16- or 32-bit integer as little-endian into the given buffer. + */ +static void +put16( + char *z, + int v) +{ + z[0] = v & 0xff; + z[1] = (v>>8) & 0xff; } -static void put32(char *z, int v){ - z[0] = v & 0xff; - z[1] = (v>>8) & 0xff; - z[2] = (v>>16) & 0xff; - z[3] = (v>>24) & 0xff; +static void +put32( + char *z, + int v) +{ + z[0] = v & 0xff; + z[1] = (v>>8) & 0xff; + z[2] = (v>>16) & 0xff; + z[3] = (v>>24) & 0xff; } - + /* -** Make a new ZFile structure with space to hold a name of the number of -** characters given. Return a pointer to the new structure. -*/ -static ZFile *newZFile(int nName, ZFile **ppList){ - ZFile *pNew; - - pNew = (ZFile*)Tcl_Alloc( sizeof(*pNew) + nName + 1 ); - memset(pNew, 0, sizeof(*pNew)); - pNew->zName = (char*)&pNew[1]; - pNew->pNext = *ppList; - *ppList = pNew; - return pNew; + * Make a new ZFile structure with space to hold a name of the number of + * characters given. Return a pointer to the new structure. + */ +static ZFile * +newZFile( + int nName, + ZFile **ppList) +{ + ZFile *pNew = Tcl_Alloc( sizeof(*pNew) + nName + 1 ); + + memset(pNew, 0, sizeof(*pNew)); + pNew->zName = (char*)&pNew[1]; + pNew->pNext = *ppList; + *ppList = pNew; + return pNew; } /* -** Delete an entire list of ZFile structures -*/ -static void deleteZFileList(ZFile *pList){ - ZFile *pNext; - while( pList ){ - pNext = pList->pNext; - Tcl_Free((char*)pList); - pList = pNext; - } + * Delete an entire list of ZFile structures + */ +static void +deleteZFileList( + ZFile *pList) +{ + ZFile *pNext; + + while( pList ){ + pNext = pList->pNext; + Tcl_Free((char*)pList); + pList = pNext; + } } /* Convert DOS time to unix time. */ -static void UnixTimeDate(struct tm *tm, int *dosDate, int *dosTime){ - *dosDate = ((((tm->tm_year-80)<<9)&0xfe00) | (((tm->tm_mon+1)<<5)&0x1e0) | (tm->tm_mday&0x1f)); - *dosTime = (((tm->tm_hour<<11)&0xf800) | ((tm->tm_min<<5)&0x7e0) | (tm->tm_sec&0x1f)); +static void +UnixTimeDate( + struct tm *tm, + int *dosDate, + int *dosTime) +{ + *dosDate = ((((tm->tm_year-80)<<9)&0xfe00) | (((tm->tm_mon+1)<<5)&0x1e0) + | (tm->tm_mday&0x1f)); + *dosTime = (((tm->tm_hour<<11)&0xf800) | ((tm->tm_min<<5)&0x7e0) + | (tm->tm_sec&0x1f)); } /* Convert DOS time to unix time. */ -static time_t DosTimeDate(int dosDate, int dosTime){ - time_t now; - struct tm *tm; - now=time(NULL); - tm = localtime(&now); - tm->tm_year=(((dosDate&0xfe00)>>9) + 80); - tm->tm_mon=((dosDate&0x1e0)>>5); - tm->tm_mday=(dosDate & 0x1f); - tm->tm_hour=(dosTime&0xf800)>>11; - tm->tm_min=(dosTime&0x7e0)>>5; - tm->tm_sec=(dosTime&0x1f); - return mktime(tm); +static time_t +DosTimeDate( + int dosDate, + int dosTime) +{ + time_t now; + struct tm *tm; + + now = time(NULL); + tm = localtime(&now); + tm->tm_year = (((dosDate&0xfe00)>>9) + 80); + tm->tm_mon = ((dosDate&0x1e0)>>5); + tm->tm_mday = (dosDate & 0x1f); + tm->tm_hour = (dosTime&0xf800)>>11; + tm->tm_min = (dosTime&0x7e0)>>5; + tm->tm_sec = (dosTime&0x1f); + return mktime(tm); } /* -** Translate a DOS time and date stamp into a human-readable string. -*/ -static void translateDosTimeDate(char *zStr, int dosDate, int dosTime){ - static char *zMonth[] = { "nil", - "Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", - }; + * Translate a DOS time and date stamp into a human-readable string. + */ +static void +translateDosTimeDate( + char *zStr, + int dosDate, + int dosTime){ + static char *zMonth[] = { "nil", + "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", + }; - sprintf(zStr, "%02d-%s-%d %02d:%02d:%02d", - dosDate & 0x1f, - zMonth[ ((dosDate&0x1e0)>>5) ], - ((dosDate&0xfe00)>>9) + 1980, - (dosTime&0xf800)>>11, - (dosTime&0x7e)>>5, - dosTime&0x1f - ); + sprintf(zStr, "%02d-%s-%d %02d:%02d:%02d", + dosDate & 0x1f, + zMonth[ ((dosDate&0x1e0)>>5) ], + ((dosDate&0xfe00)>>9) + 1980, + (dosTime&0xf800)>>11, + (dosTime&0x7e)>>5, + dosTime&0x1f); } /* Return count of char ch in str */ -int strchrcnt(char *str, char ch) { - int cnt=0; - char *cp=str; - while ((cp=strchr(cp,ch))) { cp++; cnt++; } - return cnt; -} - +int +strchrcnt( + char *str, + char ch) +{ + int cnt = 0; + char *cp = str; + while ((cp = strchr(cp,ch)) != NULL) { + cp++; + cnt++; + } + return cnt; +} + /* -** Concatenate zTail onto zRoot to form a pathname. zRoot will begin -** with "/". After concatenation, simplify the pathname be removing -** unnecessary ".." and "." directories. Under windows, make all -** characters lower case. -** -** Resulting pathname is returned. Space to hold the returned path is -** obtained form Tcl_Alloc() and should be freed by the calling function. -*/ -static char *CanonicalPath(const char *zRoot, const char *zTail){ - char *zPath; - int i, j, c; + * Concatenate zTail onto zRoot to form a pathname. zRoot will begin with + * "/". After concatenation, simplify the pathname be removing unnecessary + * ".." and "." directories. Under windows, make all characters lower case. + * + * Resulting pathname is returned. Space to hold the returned path is + * obtained form Tcl_Alloc() and should be freed by the calling function. + */ +static char * +CanonicalPath( + const char *zRoot, + const char *zTail) +{ + char *zPath; + int i, j, c; #ifdef __WIN32__ - if( isalpha(zTail[0]) && zTail[1]==':' ){ zTail += 2; } - if( zTail[0]=='\\' ){ zRoot = ""; zTail++; } + if( isalpha(zTail[0]) && zTail[1]==':' ){ + zTail += 2; + } + if( zTail[0]=='\\' ){ + zRoot = ""; + zTail++; + } #endif - if( zTail[0]=='/' ){ zRoot = ""; zTail++; } - zPath = Tcl_Alloc( strlen(zRoot) + strlen(zTail) + 2 ); - if( zPath==0 ) return 0; - if (zTail[0]) { - sprintf(zPath, "%s/%s", zRoot, zTail); - } else { - strcpy(zPath, zRoot); - } - for(i=j=0; (c = zPath[i])!=0; i++){ + if( zTail[0]=='/' ){ + zRoot = ""; + zTail++; + } + zPath = Tcl_Alloc( strlen(zRoot) + strlen(zTail) + 2 ); + if( zPath==0 ) { + return 0; + } + if (zTail[0]) { + sprintf(zPath, "%s/%s", zRoot, zTail); + } else { + strcpy(zPath, zRoot); + } + for(i=j=0; (c = zPath[i])!=0; i++){ #ifdef __WIN32__ - if( isupper(c) ) { if (maptolower) c = tolower(c); } - else if( c=='\\' ) c = '/'; + if( isupper(c) ) { + if (maptolower) { + c = tolower(c); + } + } else if( c=='\\' ) { + c = '/'; + } #endif - if( c=='/' ){ - int c2 = zPath[i+1]; - if( c2=='/' ) continue; - if( c2=='.' ){ - int c3 = zPath[i+2]; - if( c3=='/' || c3==0 ){ - i++; - continue; - } - if( c3=='.' && (zPath[i+3]=='.' || zPath[i+3]==0) ){ - i += 2; - while( j>0 && zPath[j-1]!='/' ){ j--; } - continue; - } - } - } - zPath[j++] = c; - } - if( j==0 ){ zPath[j++] = '/'; } -// if (j>1 && zPath[j-1] == '/') j--; - zPath[j] = 0; - return zPath; + if( c=='/' ){ + int c2 = zPath[i+1]; + if( c2=='/' ) { + continue; + } + if( c2=='.' ){ + int c3 = zPath[i+2]; + if( c3=='/' || c3==0 ){ + i++; + continue; + } + if( c3=='.' && (zPath[i+3]=='.' || zPath[i+3]==0) ){ + i += 2; + while( j>0 && zPath[j-1]!='/' ){ + j--; + } + continue; + } + } + } + zPath[j++] = c; + } + if( j==0 ){ + zPath[j++] = '/'; + } + /* if (j>1 && zPath[j-1] == '/') j--; */ + zPath[j] = 0; + return zPath; } /* -** Construct an absolute pathname where memory is obtained from Tcl_Alloc -** that means the same file as the pathname given. -*/ -static char *AbsolutePath(const char *zRelative){ - Tcl_DString pwd; - char *zResult; - int len; - Tcl_DStringInit(&pwd); - if (zRelative[0] == '~' && zRelative[1] == '/') { - /* TODO: do this for all paths??? */ - if (Tcl_TranslateFileName(0, zRelative, &pwd) != NULL) { - zResult = CanonicalPath( "", Tcl_DStringValue(&pwd)); - goto done; - } - } else if( zRelative[0] != '/'){ + * Construct an absolute pathname where memory is obtained from Tcl_Alloc that + * means the same file as the pathname given. + */ +static char * +AbsolutePath( + const char *zRelative) +{ + Tcl_DString pwd; + char *zResult; + int len; + + Tcl_DStringInit(&pwd); + if (zRelative[0] == '~' && zRelative[1] == '/') { + /* TODO: do this for all paths??? */ + if (Tcl_TranslateFileName(0, zRelative, &pwd) != NULL) { + zResult = CanonicalPath( "", Tcl_DStringValue(&pwd)); + goto done; + } + } else if( zRelative[0] != '/'){ #ifdef __WIN32__ - if(!(zRelative[0]=='\\' || (zRelative[0] && zRelative[1] == ':'))) { - /*Tcl_GetCwd(0, &pwd); */ - } + if(!(zRelative[0]=='\\' || (zRelative[0] && zRelative[1] == ':'))) { + /*Tcl_GetCwd(0, &pwd); */ + } #else - Tcl_GetCwd(0, &pwd); + Tcl_GetCwd(0, &pwd); #endif - } - zResult = CanonicalPath( Tcl_DStringValue(&pwd), zRelative); -done: - Tcl_DStringFree(&pwd); - len=strlen(zResult); - if (len > 0 && zResult[len-1] == '/') - zResult[len-1] = 0; - return zResult; + } + zResult = CanonicalPath( Tcl_DStringValue(&pwd), zRelative); + done: + Tcl_DStringFree(&pwd); + len = strlen(zResult); + if (len > 0 && zResult[len-1] == '/') { + zResult[len-1] = 0; + } + return zResult; } -int ZvfsReadTOCStart( - Tcl_Interp *interp, /* Leave error messages in this interpreter */ - Tcl_Channel chan, - ZFile **pList, - int *iStart -) { - char *zArchiveName = 0; /* A copy of zArchive */ - int nFile; /* Number of files in the archive */ - int iPos; /* Current position in the archive file */ - ZvfsArchive *pArchive; /* The ZIP archive being mounted */ - Tcl_HashEntry *pEntry; /* Hash table entry */ - int isNew; /* Flag to tell use when a hash entry is new */ - unsigned char zBuf[100]; /* Space into which to read from the ZIP archive */ - Tcl_HashSearch zSearch; /* Search all mount points */ - ZFile *p; - int zipStart; - - if (!chan) { - return TCL_ERROR; - } - if (Tcl_SetChannelOption(interp, chan, "-translation", "binary") != TCL_OK){ - return TCL_ERROR; - } - if (Tcl_SetChannelOption(interp, chan, "-encoding", "binary") != TCL_OK) { - return TCL_ERROR; - } - - /* Read the "End Of Central Directory" record from the end of the - ** ZIP archive. - */ - iPos = Tcl_Seek(chan, -22, SEEK_END); - Tcl_Read(chan, zBuf, 22); - if (memcmp(zBuf, "\120\113\05\06", 4)) { - /* Tcl_AppendResult(interp, "not a ZIP archive", NULL); */ - return TCL_BREAK; - } - - /* Compute the starting location of the directory for the ZIP archive - ** in iPos then seek to that location. - */ - zipStart = iPos; - nFile = INT16(zBuf,8); - iPos -= INT32(zBuf,12); - Tcl_Seek(chan, iPos, SEEK_SET); - - while(1) { - int lenName; /* Length of the next filename */ - int lenExtra; /* Length of "extra" data for next file */ - int iData; /* Offset to start of file data */ - int dosTime; - int dosDate; - int isdir; - ZvfsFile *pZvfs; /* A new virtual file */ - char *zFullPath; /* Full pathname of the virtual file */ - char zName[1024]; /* Space to hold the filename */ - - if (nFile-- <= 0 ){ - break; +int +ZvfsReadTOCStart( + Tcl_Interp *interp, /* Leave error messages in this interpreter */ + Tcl_Channel chan, + ZFile **pList, + int *iStart) +{ + char *zArchiveName = 0; /* A copy of zArchive */ + int nFile; /* Number of files in the archive */ + int iPos; /* Current position in the archive file */ + ZvfsArchive *pArchive; /* The ZIP archive being mounted */ + Tcl_HashEntry *pEntry; /* Hash table entry */ + int isNew; /* Flag to tell use when a hash entry is + * new */ + unsigned char zBuf[100]; /* Space into which to read from the ZIP + * archive */ + Tcl_HashSearch zSearch; /* Search all mount points */ + ZFile *p; + int zipStart; + + if (!chan) { + return TCL_ERROR; } - /* Read the next directory entry. Extract the size of the filename, - ** the size of the "extra" information, and the offset into the archive - ** file of the file data. - */ - Tcl_Read(chan, zBuf, 46); - if (memcmp(zBuf, "\120\113\01\02", 4)) { - Tcl_AppendResult(interp, "ill-formed central directory entry", NULL); - return TCL_ERROR; - } - lenName = INT16(zBuf,28); - lenExtra = INT16(zBuf,30) + INT16(zBuf,32); - iData = INT32(zBuf,42); - if (iDatazName, lenName); - p->zName[lenName] = 0; - if (lenName>0 && p->zName[lenName-1] == '/') { - p->isSpecial = 1; - } - p->dosDate = INT16(zBuf, 14); - p->dosTime = INT16(zBuf, 12); - p->nByteCompr = INT32(zBuf, 20); - p->nByte = INT32(zBuf, 24); - p->nExtra = INT32(zBuf, 28); - p->iCRC = INT32(zBuf, 32); - - if (nFile < 0) - break; + if (Tcl_SetChannelOption(interp, chan, "-translation", + "binary") != TCL_OK){ + return TCL_ERROR; + } + if (Tcl_SetChannelOption(interp, chan, "-encoding", "binary") != TCL_OK) { + return TCL_ERROR; + } + + /* + * Read the "End Of Central Directory" record from the end of the ZIP + * archive. + */ + + iPos = Tcl_Seek(chan, -22, SEEK_END); + Tcl_Read(chan, zBuf, 22); + if (memcmp(zBuf, "\120\113\05\06", 4)) { + /* Tcl_AppendResult(interp, "not a ZIP archive", NULL); */ + return TCL_BREAK; + } + + /* + * Compute the starting location of the directory for the ZIP archive in + * iPos then seek to that location. + */ + + zipStart = iPos; + nFile = INT16(zBuf,8); + iPos -= INT32(zBuf,12); + Tcl_Seek(chan, iPos, SEEK_SET); + + while(1) { + int lenName; /* Length of the next filename */ + int lenExtra; /* Length of "extra" data for next file */ + int iData; /* Offset to start of file data */ + int dosTime; + int dosDate; + int isdir; + ZvfsFile *pZvfs; /* A new virtual file */ + char *zFullPath; /* Full pathname of the virtual file */ + char zName[1024]; /* Space to hold the filename */ + + if (nFile-- <= 0 ){ + break; + } + + /* + * Read the next directory entry. Extract the size of the filename, + * the size of the "extra" information, and the offset into the + * archive file of the file data. + */ + + Tcl_Read(chan, zBuf, 46); + if (memcmp(zBuf, "\120\113\01\02", 4)) { + Tcl_AppendResult(interp, "ill-formed central directory entry", + NULL); + return TCL_ERROR; + } + lenName = INT16(zBuf,28); + lenExtra = INT16(zBuf,30) + INT16(zBuf,32); + iData = INT32(zBuf,42); + if (iDatazName, lenName); + p->zName[lenName] = 0; + if (lenName>0 && p->zName[lenName-1] == '/') { + p->isSpecial = 1; + } + p->dosDate = INT16(zBuf, 14); + p->dosTime = INT16(zBuf, 12); + p->nByteCompr = INT32(zBuf, 20); + p->nByte = INT32(zBuf, 24); + p->nExtra = INT32(zBuf, 28); + p->iCRC = INT32(zBuf, 32); + + if (nFile < 0) { + break; + } + + /* + * Skip over the extra information so that the next read will be from + * the beginning of the next directory entry. + */ + + Tcl_Seek(chan, lenExtra, SEEK_CUR); + } + *iStart = zipStart; + return TCL_OK; } -int ZvfsReadTOC( - Tcl_Interp *interp, /* Leave error messages in this interpreter */ - Tcl_Channel chan, - ZFile **pList -) { +int +ZvfsReadTOC( + Tcl_Interp *interp, /* Leave error messages in this interpreter */ + Tcl_Channel chan, + ZFile **pList) +{ int iStart; + return ZvfsReadTOCStart( interp, chan, pList, &iStart); } /* -** Read a ZIP archive and make entries in the virutal file hash table for all -** content files of that ZIP archive. Also initialize the ZVFS if this -** routine has not been previously called. -*/ -int Tcl_Zvfs_Mount( - Tcl_Interp *interp, /* Leave error messages in this interpreter */ - CONST char *zArchive, /* The ZIP archive file */ - CONST char *zMountPoint /* Mount contents at this directory */ -){ - Tcl_Channel chan; /* Used for reading the ZIP archive file */ - char *zArchiveName = 0; /* A copy of zArchive */ - char *zTrueName = 0; /* A copy of zMountPoint */ - int nFile; /* Number of files in the archive */ - int iPos; /* Current position in the archive file */ - ZvfsArchive *pArchive; /* The ZIP archive being mounted */ - Tcl_HashEntry *pEntry; /* Hash table entry */ - int isNew; /* Flag to tell use when a hash entry is new */ - unsigned char zBuf[100]; /* Space into which to read from the ZIP archive */ - Tcl_HashSearch zSearch; /* Search all mount points */ - unsigned int startZip; - - if( !local.isInit ) return TCL_ERROR; - /* If null archive name, return all current mounts. */ - if (!zArchive) { - Tcl_DString dStr; - Tcl_DStringInit(&dStr); - pEntry=Tcl_FirstHashEntry(&local.archiveHash,&zSearch); - while (pEntry) { - if (pArchive = Tcl_GetHashValue(pEntry)) { - Tcl_DStringAppendElement(&dStr, pArchive->zName); - Tcl_DStringAppendElement(&dStr, pArchive->zMountPoint); - } - pEntry=Tcl_NextHashEntry(&zSearch); + * Read a ZIP archive and make entries in the virutal file hash table for all + * content files of that ZIP archive. Also initialize the ZVFS if this + * routine has not been previously called. + */ +int +Tcl_Zvfs_Mount( + Tcl_Interp *interp, /* Leave error messages in this interpreter */ + const char *zArchive, /* The ZIP archive file */ + const char *zMountPoint) /* Mount contents at this directory */ +{ + Tcl_Channel chan; /* Used for reading the ZIP archive file */ + char *zArchiveName = 0; /* A copy of zArchive */ + char *zTrueName = 0; /* A copy of zMountPoint */ + int nFile; /* Number of files in the archive */ + int iPos; /* Current position in the archive file */ + ZvfsArchive *pArchive; /* The ZIP archive being mounted */ + Tcl_HashEntry *pEntry; /* Hash table entry */ + int isNew; /* Flag to tell use when a hash entry is + * new */ + unsigned char zBuf[100]; /* Space into which to read from the ZIP + * archive */ + Tcl_HashSearch zSearch; /* Search all mount points */ + unsigned int startZip; + + if( !local.isInit ) { + return TCL_ERROR; } - Tcl_DStringResult(interp, &dStr); - return TCL_OK; - } - /* If null mount, return mount point. */ - // TODO: cleanup allocations of Absolute() path. - if (!zMountPoint) { - zTrueName=AbsolutePath(zArchive); - pEntry = Tcl_FindHashEntry(&local.archiveHash,zTrueName); - if (pEntry) { - if (pArchive = Tcl_GetHashValue(pEntry)) { - Tcl_AppendResult(interp, pArchive->zMountPoint, 0); - } + + /* + * If null archive name, return all current mounts. + */ + + if (!zArchive) { + Tcl_DString dStr; + + Tcl_DStringInit(&dStr); + pEntry=Tcl_FirstHashEntry(&local.archiveHash,&zSearch); + while (pEntry) { + if (pArchive = Tcl_GetHashValue(pEntry)) { + Tcl_DStringAppendElement(&dStr, pArchive->zName); + Tcl_DStringAppendElement(&dStr, pArchive->zMountPoint); + } + pEntry=Tcl_NextHashEntry(&zSearch); + } + Tcl_DStringResult(interp, &dStr); + return TCL_OK; } - Tcl_Free(zTrueName); - return TCL_OK; - } - chan = Tcl_OpenFileChannel(interp, zArchive, "r", 0); - if (!chan) { - return TCL_ERROR; - } - if (Tcl_SetChannelOption(interp, chan, "-translation", "binary") != TCL_OK){ - return TCL_ERROR; - } - if (Tcl_SetChannelOption(interp, chan, "-encoding", "binary") != TCL_OK) { - return TCL_ERROR; - } - - /* Read the "End Of Central Directory" record from the end of the - ** ZIP archive. - */ - iPos = Tcl_Seek(chan, -22, SEEK_END); - Tcl_Read(chan, zBuf, 22); - if (memcmp(zBuf, "\120\113\05\06", 4)) { - Tcl_AppendResult(interp, "not a ZIP archive", NULL); - return TCL_ERROR; - } - /* Construct the archive record - */ - zArchiveName = AbsolutePath(zArchive); - pEntry = Tcl_CreateHashEntry(&local.archiveHash, zArchiveName, &isNew); - if( !isNew ){ - pArchive = Tcl_GetHashValue(pEntry); - Tcl_AppendResult(interp, "already mounted at ", pArchive->zMountPoint, 0); - Tcl_Free(zArchiveName); - Tcl_Close(interp, chan); - return TCL_ERROR; - } - if (!*zMountPoint) { - /* Empty string is the special case of mounting on itself. */ - zMountPoint = zTrueName = AbsolutePath(zArchive); - } - pArchive = (ZvfsArchive*)Tcl_Alloc(sizeof(*pArchive) + strlen(zMountPoint)+1); - pArchive->zName = zArchiveName; - pArchive->zMountPoint = (char*)&pArchive[1]; - strcpy(pArchive->zMountPoint, zMountPoint); - pArchive->pFiles = 0; - Tcl_SetHashValue(pEntry, pArchive); - - /* Compute the starting location of the directory for the ZIP archive - ** in iPos then seek to that location. - */ - nFile = INT16(zBuf,8); - iPos -= INT32(zBuf,12); - Tcl_Seek(chan, iPos, SEEK_SET); - startZip = iPos; - - while(1) { - int lenName; /* Length of the next filename */ - int lenExtra; /* Length of "extra" data for next file */ - int iData; /* Offset to start of file data */ - int dosTime; - int dosDate; - int isdir; - ZvfsFile *pZvfs; /* A new virtual file */ - char *zFullPath; /* Full pathname of the virtual file */ - char zName[1024]; /* Space to hold the filename */ - - if (nFile-- <= 0 ){ - isdir = 1; - zFullPath = CanonicalPath(zMountPoint, ""); - iData = startZip; - goto addentry; - } - /* Read the next directory entry. Extract the size of the filename, - ** the size of the "extra" information, and the offset into the archive - ** file of the file data. - */ - Tcl_Read(chan, zBuf, 46); - if (memcmp(zBuf, "\120\113\01\02", 4)) { - Tcl_AppendResult(interp, "ill-formed central directory entry", NULL); - if (zTrueName) - Tcl_Free(zTrueName); - return TCL_ERROR; - } - lenName = INT16(zBuf,28); - lenExtra = INT16(zBuf,30) + INT16(zBuf,32); - iData = INT32(zBuf,42); - - - /* If the virtual filename is too big to fit in zName[], then skip - ** this file - */ - if( lenName >= sizeof(zName) ){ - Tcl_Seek(chan, lenName + lenExtra, SEEK_CUR); - continue; - } - - /* Construct an entry in local.fileHash for this virtual file. - */ - Tcl_Read(chan, zName, lenName); - isdir=0; - if (lenName>0 && zName[lenName-1] == '/') { - lenName--; - isdir=2; - } - zName[lenName] = 0; - zFullPath = CanonicalPath(zMountPoint, zName); -addentry: - pZvfs = (ZvfsFile*)Tcl_Alloc( sizeof(*pZvfs) ); - pZvfs->zName = zFullPath; - pZvfs->pArchive = pArchive; - pZvfs->isdir = isdir; - pZvfs->depth=strchrcnt(zFullPath,'/'); - pZvfs->iOffset = iData; - if (iDatatimestamp = DosTimeDate(dosDate, dosTime); - pZvfs->nByte = INT32(zBuf, 24); - pZvfs->nByteCompr = INT32(zBuf, 20); - pZvfs->pNext = pArchive->pFiles; - pZvfs->permissions = (0xffff&(INT32(zBuf, 38) >> 16)); - pArchive->pFiles = pZvfs; - pEntry = Tcl_CreateHashEntry(&local.fileHash, zFullPath, &isNew); - if( isNew ){ - pZvfs->pNextName = 0; - }else{ - ZvfsFile *pOld = (ZvfsFile*)Tcl_GetHashValue(pEntry); - pOld->pPrevName = pZvfs; - pZvfs->pNextName = pOld; + /* + * If null mount, return mount point. + */ + + /*TODO: cleanup allocations of Absolute() path.*/ + if (!zMountPoint) { + zTrueName=AbsolutePath(zArchive); + pEntry = Tcl_FindHashEntry(&local.archiveHash,zTrueName); + if (pEntry) { + if (pArchive = Tcl_GetHashValue(pEntry)) { + Tcl_AppendResult(interp, pArchive->zMountPoint, 0); + } + } + Tcl_Free(zTrueName); + return TCL_OK; + } + chan = Tcl_OpenFileChannel(interp, zArchive, "r", 0); + if (!chan) { + return TCL_ERROR; + } + if (Tcl_SetChannelOption(interp, chan, "-translation", "binary") != TCL_OK){ + return TCL_ERROR; + } + if (Tcl_SetChannelOption(interp, chan, "-encoding", "binary") != TCL_OK) { + return TCL_ERROR; } - pZvfs->pPrevName = 0; - Tcl_SetHashValue(pEntry, (ClientData) pZvfs); - if (nFile < 0) - break; + /* + * Read the "End Of Central Directory" record from the end of the ZIP + * archive. + */ - /* Skip over the extra information so that the next read will be from - ** the beginning of the next directory entry. - */ - Tcl_Seek(chan, lenExtra, SEEK_CUR); - } - Tcl_Close(interp, chan); -done: - if (zTrueName) - Tcl_Free(zTrueName); - return TCL_OK; + iPos = Tcl_Seek(chan, -22, SEEK_END); + Tcl_Read(chan, zBuf, 22); + if (memcmp(zBuf, "\120\113\05\06", 4)) { + Tcl_AppendResult(interp, "not a ZIP archive", NULL); + return TCL_ERROR; + } + + /* + * Construct the archive record. + */ + + zArchiveName = AbsolutePath(zArchive); + pEntry = Tcl_CreateHashEntry(&local.archiveHash, zArchiveName, &isNew); + if( !isNew ){ + pArchive = Tcl_GetHashValue(pEntry); + Tcl_AppendResult(interp, "already mounted at ", pArchive->zMountPoint, + 0); + Tcl_Free(zArchiveName); + Tcl_Close(interp, chan); + return TCL_ERROR; + } + + /* + * Empty string is the special case of mounting on itself. + */ + + if (!*zMountPoint) { + zMountPoint = zTrueName = AbsolutePath(zArchive); + } + + pArchive = Tcl_Alloc(sizeof(*pArchive) + strlen(zMountPoint)+1); + pArchive->zName = zArchiveName; + pArchive->zMountPoint = (char*)&pArchive[1]; + strcpy(pArchive->zMountPoint, zMountPoint); + pArchive->pFiles = 0; + Tcl_SetHashValue(pEntry, pArchive); + + /* + * Compute the starting location of the directory for the ZIP archive in + * iPos then seek to that location. + */ + + nFile = INT16(zBuf,8); + iPos -= INT32(zBuf,12); + Tcl_Seek(chan, iPos, SEEK_SET); + startZip = iPos; + + while(1) { + int lenName; /* Length of the next filename */ + int lenExtra; /* Length of "extra" data for next file */ + int iData; /* Offset to start of file data */ + int dosTime; + int dosDate; + int isdir; + ZvfsFile *pZvfs; /* A new virtual file */ + char *zFullPath; /* Full pathname of the virtual file */ + char zName[1024]; /* Space to hold the filename */ + + if (nFile-- <= 0 ){ + isdir = 1; + zFullPath = CanonicalPath(zMountPoint, ""); + iData = startZip; + goto addentry; + } + + /* + * Read the next directory entry. Extract the size of the filename, + * the size of the "extra" information, and the offset into the + * archive file of the file data. + */ + + Tcl_Read(chan, zBuf, 46); + if (memcmp(zBuf, "\120\113\01\02", 4)) { + Tcl_AppendResult(interp, "ill-formed central directory entry", + NULL); + if (zTrueName) { + Tcl_Free(zTrueName); + } + return TCL_ERROR; + } + lenName = INT16(zBuf,28); + lenExtra = INT16(zBuf,30) + INT16(zBuf,32); + iData = INT32(zBuf,42); + + /* + * If the virtual filename is too big to fit in zName[], then skip + * this file + */ + + if( lenName >= sizeof(zName) ){ + Tcl_Seek(chan, lenName + lenExtra, SEEK_CUR); + continue; + } + + /* + * Construct an entry in local.fileHash for this virtual file. + */ + + Tcl_Read(chan, zName, lenName); + isdir=0; + if (lenName>0 && zName[lenName-1] == '/') { + lenName--; + isdir=2; + } + zName[lenName] = 0; + zFullPath = CanonicalPath(zMountPoint, zName); + addentry: + pZvfs = (ZvfsFile*)Tcl_Alloc( sizeof(*pZvfs) ); + pZvfs->zName = zFullPath; + pZvfs->pArchive = pArchive; + pZvfs->isdir = isdir; + pZvfs->depth=strchrcnt(zFullPath,'/'); + pZvfs->iOffset = iData; + if (iDatatimestamp = DosTimeDate(dosDate, dosTime); + pZvfs->nByte = INT32(zBuf, 24); + pZvfs->nByteCompr = INT32(zBuf, 20); + pZvfs->pNext = pArchive->pFiles; + pZvfs->permissions = (0xffff&(INT32(zBuf, 38) >> 16)); + pArchive->pFiles = pZvfs; + pEntry = Tcl_CreateHashEntry(&local.fileHash, zFullPath, &isNew); + if( isNew ){ + pZvfs->pNextName = 0; + } else { + ZvfsFile *pOld = Tcl_GetHashValue(pEntry); + + pOld->pPrevName = pZvfs; + pZvfs->pNextName = pOld; + } + pZvfs->pPrevName = 0; + Tcl_SetHashValue(pEntry, pZvfs); + + if (nFile < 0) { + break; + } + + /* + * Skip over the extra information so that the next read will be from + * the beginning of the next directory entry. + */ + + Tcl_Seek(chan, lenExtra, SEEK_CUR); + } + Tcl_Close(interp, chan); + done: + if (zTrueName) { + Tcl_Free(zTrueName); + } + return TCL_OK; } /* -** Locate the ZvfsFile structure that corresponds to the file named. -** Return NULL if there is no such ZvfsFile. -*/ -static ZvfsFile *ZvfsLookup(char *zFilename){ - char *zTrueName; - Tcl_HashEntry *pEntry; - ZvfsFile *pFile; - - if( local.isInit==0 ) return 0; - zTrueName = AbsolutePath(zFilename); - pEntry = Tcl_FindHashEntry(&local.fileHash, zTrueName); - pFile = pEntry ? Tcl_GetHashValue(pEntry) : 0; - Tcl_Free(zTrueName); - return pFile; -} + * Locate the ZvfsFile structure that corresponds to the file named. Return + * NULL if there is no such ZvfsFile. + */ +static ZvfsFile * +ZvfsLookup( + char *zFilename) +{ + char *zTrueName; + Tcl_HashEntry *pEntry; + ZvfsFile *pFile; -static int ZvfsLookupMount(char *zFilename){ - char *zTrueName; - Tcl_HashEntry *pEntry; /* Hash table entry */ - Tcl_HashSearch zSearch; /* Search all mount points */ - ZvfsArchive *pArchive; /* The ZIP archive being mounted */ - int match=0; - if( local.isInit==0 ) return 0; - zTrueName = AbsolutePath(zFilename); - pEntry=Tcl_FirstHashEntry(&local.archiveHash,&zSearch); - while (pEntry) { - if (pArchive = Tcl_GetHashValue(pEntry)) { - if (!strcmp(pArchive->zMountPoint,zTrueName)) { - match=1; - break; - } + if( local.isInit==0 ) { + return 0; } - pEntry=Tcl_NextHashEntry(&zSearch); - } - Tcl_Free(zTrueName); - return match; + zTrueName = AbsolutePath(zFilename); + pEntry = Tcl_FindHashEntry(&local.fileHash, zTrueName); + pFile = pEntry ? Tcl_GetHashValue(pEntry) : 0; + Tcl_Free(zTrueName); + return pFile; } +static int +ZvfsLookupMount( + char *zFilename) +{ + char *zTrueName; + Tcl_HashEntry *pEntry; /* Hash table entry */ + Tcl_HashSearch zSearch; /* Search all mount points */ + ZvfsArchive *pArchive; /* The ZIP archive being mounted */ + int match=0; + + if( local.isInit==0 ) { + return 0; + } + zTrueName = AbsolutePath(zFilename); + pEntry=Tcl_FirstHashEntry(&local.archiveHash,&zSearch); + while (pEntry) { + if (pArchive = Tcl_GetHashValue(pEntry)) { + if (!strcmp(pArchive->zMountPoint,zTrueName)) { + match=1; + break; + } + } + pEntry=Tcl_NextHashEntry(&zSearch); + } + Tcl_Free(zTrueName); + return match; +} /* -** Unmount all the files in the given ZIP archive. -*/ -int Tcl_Zvfs_Umount(CONST char *zArchive){ - char *zArchiveName; - ZvfsArchive *pArchive; - ZvfsFile *pFile, *pNextFile; - Tcl_HashEntry *pEntry; - - zArchiveName = AbsolutePath(zArchive); - pEntry = Tcl_FindHashEntry(&local.archiveHash, zArchiveName); - Tcl_Free(zArchiveName); - if( pEntry==0 ) return 0; - pArchive = Tcl_GetHashValue(pEntry); - Tcl_DeleteHashEntry(pEntry); - Tcl_Free(pArchive->zName); - for(pFile=pArchive->pFiles; pFile; pFile=pNextFile){ - pNextFile = pFile->pNext; - if( pFile->pNextName ){ - pFile->pNextName->pPrevName = pFile->pPrevName; - } - if( pFile->pPrevName ){ - pFile->pPrevName->pNextName = pFile->pNextName; - }else{ - pEntry = Tcl_FindHashEntry(&local.fileHash, pFile->zName); - if( pEntry==0 ){ - /* This should never happen */ - }else if( pFile->pNextName ){ - Tcl_SetHashValue(pEntry, pFile->pNextName); - }else{ - Tcl_DeleteHashEntry(pEntry); - } - } - Tcl_Free(pFile->zName); - Tcl_Free((char*)pFile); - } - return 1; + * Unmount all the files in the given ZIP archive. + */ +int +Tcl_Zvfs_Umount( + const char *zArchive) +{ + char *zArchiveName; + ZvfsArchive *pArchive; + ZvfsFile *pFile, *pNextFile; + Tcl_HashEntry *pEntry; + + zArchiveName = AbsolutePath(zArchive); + pEntry = Tcl_FindHashEntry(&local.archiveHash, zArchiveName); + Tcl_Free(zArchiveName); + if( pEntry==0 ) { + return 0; + } + pArchive = Tcl_GetHashValue(pEntry); + Tcl_DeleteHashEntry(pEntry); + Tcl_Free(pArchive->zName); + for(pFile=pArchive->pFiles; pFile; pFile=pNextFile){ + pNextFile = pFile->pNext; + if( pFile->pNextName ){ + pFile->pNextName->pPrevName = pFile->pPrevName; + } + if( pFile->pPrevName ){ + pFile->pPrevName->pNextName = pFile->pNextName; + }else{ + pEntry = Tcl_FindHashEntry(&local.fileHash, pFile->zName); + if( pEntry==0 ){ + Tcl_Panic("This should never happen"); + }else if( pFile->pNextName ){ + Tcl_SetHashValue(pEntry, pFile->pNextName); + }else{ + Tcl_DeleteHashEntry(pEntry); + } + } + Tcl_Free(pFile->zName); + Tcl_Free((char*)pFile); + } + return 1; } -static void Zvfs_Unmount(CONST char *zArchive){ +static void +Zvfs_Unmount( + const char *zArchive) +{ Tcl_Zvfs_Umount(zArchive); } /* -** zvfs::mount Zip-archive-name mount-point -** -** Create a new mount point on the given ZIP archive. After this -** command executes, files contained in the ZIP archive will appear -** to Tcl to be regular files at the mount point. -** -** With no mount-point, return mount point for archive. -** With no archive, return all archive/mount pairs. -** If mount-point is specified as an empty string, mount on file path. -** -*/ -static int ZvfsMountCmd( - ClientData clientData, /* Client data for this command */ - Tcl_Interp *interp, /* The interpreter used to report errors */ - int argc, /* Number of arguments */ - CONST char *argv[] /* Values of all arguments */ -){ - if( argc>3 ){ - Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], - " ? ZIP-FILE ? MOUNT-POINT ? ?\"", 0); - return TCL_ERROR; - } - return Tcl_Zvfs_Mount(interp, argc>1?argv[1]:0, argc>2?argv[2]:0); + * zvfs::mount Zip-archive-name mount-point + * + * Create a new mount point on the given ZIP archive. After this command + * executes, files contained in the ZIP archive will appear to Tcl to be + * regular files at the mount point. + * + * With no mount-point, return mount point for archive. With no archive, + * return all archive/mount pairs. If mount-point is specified as an empty + * string, mount on file path. + */ +static int +ZvfsMountCmd( + ClientData clientData, /* Client data for this command */ + Tcl_Interp *interp, /* The interpreter used to report errors */ + int argc, /* Number of arguments */ + const char *argv[]) /* Values of all arguments */ +{ + /*TODO: Convert to Tcl_Obj API!*/ + if( argc>3 ){ + Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], + " ? ZIP-FILE ? MOUNT-POINT ? ?\"", 0); + return TCL_ERROR; + } + return Tcl_Zvfs_Mount(interp, argc>1?argv[1]:0, argc>2?argv[2]:0); } /* -** zvfs::unmount Zip-archive-name -** -** Undo the effects of zvfs::mount. -*/ -static int ZvfsUnmountCmd( - ClientData clientData, /* Client data for this command */ - Tcl_Interp *interp, /* The interpreter used to report errors */ - int argc, /* Number of arguments */ - CONST char *argv[] /* Values of all arguments */ -){ - ZvfsArchive *pArchive; /* The ZIP archive being mounted */ - Tcl_HashEntry *pEntry; /* Hash table entry */ - Tcl_HashSearch zSearch; /* Search all mount points */ + * zvfs::unmount Zip-archive-name + * + * Undo the effects of zvfs::mount. + */ +static int +ZvfsUnmountCmd( + ClientData clientData, /* Client data for this command */ + Tcl_Interp *interp, /* The interpreter used to report errors */ + int argc, /* Number of arguments */ + const char *argv[]) /* Values of all arguments */ +{ + ZvfsArchive *pArchive; /* The ZIP archive being mounted */ + Tcl_HashEntry *pEntry; /* Hash table entry */ + Tcl_HashSearch zSearch; /* Search all mount points */ if( argc!=2 ){ - Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], - " ZIP-FILE\"", 0); - return TCL_ERROR; + Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], + " ZIP-FILE\"", 0); + return TCL_ERROR; } if (Tcl_Zvfs_Umount(argv[1])) { - return TCL_OK; + return TCL_OK; } - if( !local.isInit ) return TCL_ERROR; + if( !local.isInit ) { + return TCL_ERROR; + } pEntry=Tcl_FirstHashEntry(&local.archiveHash,&zSearch); while (pEntry) { - if (((pArchive = Tcl_GetHashValue(pEntry))) - && pArchive->zMountPoint[0] - && (strcmp(pArchive->zMountPoint, argv[1]) == 0)) { - if (Tcl_Zvfs_Umount(pArchive->zName)) { - return TCL_OK; - } - break; - } - pEntry=Tcl_NextHashEntry(&zSearch); - } - - Tcl_AppendResult( interp, "unknown zvfs mount point or file: ", argv[1], 0); + if (((pArchive = Tcl_GetHashValue(pEntry))) + && pArchive->zMountPoint[0] + && (strcmp(pArchive->zMountPoint, argv[1]) == 0)) { + if (Tcl_Zvfs_Umount(pArchive->zName)) { + return TCL_OK; + } + break; + } + pEntry=Tcl_NextHashEntry(&zSearch); + } + + Tcl_AppendResult(interp, "unknown zvfs mount point or file: ", argv[1], 0); return TCL_ERROR; } /* -** zvfs::exists filename -** -** Return TRUE if the given filename exists in the ZVFS and FALSE if -** it does not. -*/ -static int ZvfsExistsObjCmd( - ClientData clientData, /* Client data for this command */ - Tcl_Interp *interp, /* The interpreter used to report errors */ - int objc, /* Number of arguments */ - Tcl_Obj *CONST* objv /* Values of all arguments */ -){ - char *zFilename; - if( objc!=2 ){ - Tcl_WrongNumArgs(interp, 1, objv, "FILENAME"); - return TCL_ERROR; - } - zFilename = Tcl_GetString(objv[1]); - Tcl_SetBooleanObj( Tcl_GetObjResult(interp), ZvfsLookup(zFilename)!=0); - return TCL_OK; + * zvfs::exists filename + * + * Return TRUE if the given filename exists in the ZVFS and FALSE if it does + * not. + */ +static int +ZvfsExistsObjCmd( + ClientData clientData, /* Client data for this command */ + Tcl_Interp *interp, /* The interpreter used to report errors */ + int objc, /* Number of arguments */ + Tcl_Obj *const* objv) /* Values of all arguments */ +{ + char *zFilename; + + if( objc!=2 ){ + Tcl_WrongNumArgs(interp, 1, objv, "FILENAME"); + return TCL_ERROR; + } + zFilename = Tcl_GetString(objv[1]); + Tcl_SetBooleanObj( Tcl_GetObjResult(interp), ZvfsLookup(zFilename)!=0); + return TCL_OK; } /* -** zvfs::info filename -** -** Return information about the given file in the ZVFS. The information -** consists of (1) the name of the ZIP archive that contains the file, -** (2) the size of the file after decompressions, (3) the compressed -** size of the file, and (4) the offset of the compressed data in the archive. -** -** Note: querying the mount point gives the start of zip data offset in -** (4), which can be used to truncate the zip info off an executable. -*/ -static int ZvfsInfoObjCmd( - ClientData clientData, /* Client data for this command */ - Tcl_Interp *interp, /* The interpreter used to report errors */ - int objc, /* Number of arguments */ - Tcl_Obj *const* objv /* Values of all arguments */ -){ - char *zFilename; - ZvfsFile *pFile; - if( objc!=2 ){ - Tcl_WrongNumArgs(interp, 1, objv, "FILENAME"); - return TCL_ERROR; - } - zFilename = Tcl_GetString(objv[1]); - pFile = ZvfsLookup(zFilename); - if( pFile ){ - Tcl_Obj *pResult = Tcl_GetObjResult(interp); - Tcl_ListObjAppendElement(interp, pResult, - Tcl_NewStringObj(pFile->pArchive->zName, -1)); - Tcl_ListObjAppendElement(interp, pResult, Tcl_NewIntObj(pFile->nByte)); - Tcl_ListObjAppendElement(interp, pResult, Tcl_NewIntObj(pFile->nByteCompr)); - Tcl_ListObjAppendElement(interp, pResult, Tcl_NewIntObj(pFile->iOffset)); - } - return TCL_OK; + * zvfs::info filename + * + * Return information about the given file in the ZVFS. The information + * consists of (1) the name of the ZIP archive that contains the file, (2) the + * size of the file after decompressions, (3) the compressed size of the file, + * and (4) the offset of the compressed data in the archive. + * + * Note: querying the mount point gives the start of zip data offset in (4), + * which can be used to truncate the zip info off an executable. + */ +static int +ZvfsInfoObjCmd( + ClientData clientData, /* Client data for this command */ + Tcl_Interp *interp, /* The interpreter used to report errors */ + int objc, /* Number of arguments */ + Tcl_Obj *const* objv) /* Values of all arguments */ +{ + char *zFilename; + ZvfsFile *pFile; + + if( objc!=2 ){ + Tcl_WrongNumArgs(interp, 1, objv, "FILENAME"); + return TCL_ERROR; + } + zFilename = Tcl_GetString(objv[1]); + pFile = ZvfsLookup(zFilename); + if( pFile ){ + Tcl_Obj *pResult = Tcl_GetObjResult(interp); + + Tcl_ListObjAppendElement(interp, pResult, + Tcl_NewStringObj(pFile->pArchive->zName, -1)); + Tcl_ListObjAppendElement(interp, pResult, + Tcl_NewIntObj(pFile->nByte)); + Tcl_ListObjAppendElement(interp, pResult, + Tcl_NewIntObj(pFile->nByteCompr)); + Tcl_ListObjAppendElement(interp, pResult, + Tcl_NewIntObj(pFile->iOffset)); + } + return TCL_OK; } /* -** zvfs::list -** -** Return a list of all files in the ZVFS. The order of the names -** in the list is arbitrary. -*/ -static int ZvfsListObjCmd( - ClientData clientData, /* Client data for this command */ - Tcl_Interp *interp, /* The interpreter used to report errors */ - int objc, /* Number of arguments */ - Tcl_Obj *const* objv /* Values of all arguments */ -){ - char *zPattern = 0; - Tcl_RegExp pRegexp = 0; - Tcl_HashEntry *pEntry; - Tcl_HashSearch sSearch; - Tcl_Obj *pResult = Tcl_GetObjResult(interp); - - if( objc>3 ){ - Tcl_WrongNumArgs(interp, 1, objv, "?(-glob|-regexp)? ?PATTERN?"); - return TCL_ERROR; - } - if( local.isInit==0 ) return TCL_OK; - if( objc==3 ){ - int n; - char *zSwitch = Tcl_GetStringFromObj(objv[1], &n); - if( n>=2 && strncmp(zSwitch,"-glob",n)==0 ){ - zPattern = Tcl_GetString(objv[2]); - }else if( n>=2 && strncmp(zSwitch,"-regexp",n)==0 ){ - pRegexp = Tcl_RegExpCompile(interp, Tcl_GetString(objv[2])); - if( pRegexp==0 ) return TCL_ERROR; + * zvfs::list + * + * Return a list of all files in the ZVFS. The order of the names in the list + * is arbitrary. + */ +static int +ZvfsListObjCmd( + ClientData clientData, /* Client data for this command */ + Tcl_Interp *interp, /* The interpreter used to report errors */ + int objc, /* Number of arguments */ + Tcl_Obj *const* objv) /* Values of all arguments */ +{ + char *zPattern = 0; + Tcl_RegExp pRegexp = 0; + Tcl_HashEntry *pEntry; + Tcl_HashSearch sSearch; + Tcl_Obj *pResult = Tcl_GetObjResult(interp); + + if( objc>3 ){ + Tcl_WrongNumArgs(interp, 1, objv, "?(-glob|-regexp)? ?PATTERN?"); + return TCL_ERROR; + } + if( local.isInit==0 ) { + return TCL_OK; + } + if( objc==3 ){ + int n; + char *zSwitch = Tcl_GetStringFromObj(objv[1], &n); + + if( n>=2 && strncmp(zSwitch,"-glob",n)==0 ){ + zPattern = Tcl_GetString(objv[2]); + }else if( n>=2 && strncmp(zSwitch,"-regexp",n)==0 ){ + pRegexp = Tcl_RegExpCompile(interp, Tcl_GetString(objv[2])); + if( pRegexp==0 ) { + return TCL_ERROR; + } + }else{ + Tcl_AppendResult(interp, "unknown option: ", zSwitch, 0); + return TCL_ERROR; + } + } else if( objc==2 ){ + zPattern = Tcl_GetString(objv[1]); + } + if( zPattern ){ + for(pEntry = Tcl_FirstHashEntry(&local.fileHash, &sSearch); + pEntry; pEntry = Tcl_NextHashEntry(&sSearch)){ + ZvfsFile *pFile = Tcl_GetHashValue(pEntry); + char *z = pFile->zName; + + if( Tcl_StringCaseMatch(z, zPattern,1) ){ + Tcl_ListObjAppendElement(interp, pResult, + Tcl_NewStringObj(z, -1)); + } + } + }else if( pRegexp ){ + for(pEntry = Tcl_FirstHashEntry(&local.fileHash, &sSearch); + pEntry; pEntry = Tcl_NextHashEntry(&sSearch)){ + ZvfsFile *pFile = Tcl_GetHashValue(pEntry); + char *z = pFile->zName; + + if( Tcl_RegExpExec(interp, pRegexp, z, z) ){ + Tcl_ListObjAppendElement(interp, pResult, + Tcl_NewStringObj(z, -1)); + } + } }else{ - Tcl_AppendResult(interp, "unknown option: ", zSwitch, 0); - return TCL_ERROR; + for(pEntry = Tcl_FirstHashEntry(&local.fileHash, &sSearch); + pEntry; pEntry = Tcl_NextHashEntry(&sSearch)){ + ZvfsFile *pFile = Tcl_GetHashValue(pEntry); + char *z = pFile->zName; + + Tcl_ListObjAppendElement(interp, pResult, + Tcl_NewStringObj(z, -1)); + } } - }else if( objc==2 ){ - zPattern = Tcl_GetString(objv[1]); - } - if( zPattern ){ - for(pEntry = Tcl_FirstHashEntry(&local.fileHash, &sSearch); - pEntry; - pEntry = Tcl_NextHashEntry(&sSearch) - ){ - ZvfsFile *pFile = Tcl_GetHashValue(pEntry); - char *z = pFile->zName; - if( Tcl_StringCaseMatch(z, zPattern,1) ){ - Tcl_ListObjAppendElement(interp, pResult, Tcl_NewStringObj(z, -1)); - } - } - }else if( pRegexp ){ - for(pEntry = Tcl_FirstHashEntry(&local.fileHash, &sSearch); - pEntry; - pEntry = Tcl_NextHashEntry(&sSearch) - ){ - ZvfsFile *pFile = Tcl_GetHashValue(pEntry); - char *z = pFile->zName; - if( Tcl_RegExpExec(interp, pRegexp, z, z) ){ - Tcl_ListObjAppendElement(interp, pResult, Tcl_NewStringObj(z, -1)); - } - } - }else{ - for(pEntry = Tcl_FirstHashEntry(&local.fileHash, &sSearch); - pEntry; - pEntry = Tcl_NextHashEntry(&sSearch) - ){ - ZvfsFile *pFile = Tcl_GetHashValue(pEntry); - char *z = pFile->zName; - Tcl_ListObjAppendElement(interp, pResult, Tcl_NewStringObj(z, -1)); - } - } - return TCL_OK; + return TCL_OK; } /* -** Whenever a ZVFS file is opened, an instance of this structure is -** attached to the open channel where it will be available to the -** ZVFS I/O routines below. All state information about an open -** ZVFS file is held in this structure. -*/ + * Whenever a ZVFS file is opened, an instance of this structure is attached + * to the open channel where it will be available to the ZVFS I/O routines + * below. All state information about an open ZVFS file is held in this + * structure. + */ typedef struct ZvfsChannelInfo { - unsigned int nByte; /* number of bytes of read uncompressed data */ - unsigned int nByteCompr; /* number of bytes of unread compressed data */ - unsigned int nData; /* total number of bytes of compressed data */ - int readSoFar; /* Number of bytes read so far */ - long startOfData; /* File position of start of data in ZIP archive */ - int isCompressed; /* True data is compressed */ - Tcl_Channel chan; /* Open to the archive file */ - unsigned char *zBuf; /* buffer used by the decompressor */ - z_stream stream; /* state of the decompressor */ + unsigned int nByte; /* number of bytes of read uncompressed + * data */ + unsigned int nByteCompr; /* number of bytes of unread compressed + * data */ + unsigned int nData; /* total number of bytes of compressed data */ + int readSoFar; /* Number of bytes read so far */ + long startOfData; /* File position of start of data in ZIP + * archive */ + int isCompressed; /* True data is compressed */ + Tcl_Channel chan; /* Open to the archive file */ + unsigned char *zBuf; /* buffer used by the decompressor */ + z_stream stream; /* state of the decompressor */ } ZvfsChannelInfo; - /* -** This routine is called as an exit handler. If we do not set -** ZvfsChannelInfo.chan to NULL, then Tcl_Close() will be called on -** that channel twice when Tcl_Exit runs. This will lead to a -** core dump. -*/ -static void vfsExit(void *pArg){ - ZvfsChannelInfo *pInfo = (ZvfsChannelInfo*)pArg; - pInfo->chan = 0; + * This routine is called as an exit handler. If we do not set + * ZvfsChannelInfo.chan to NULL, then Tcl_Close() will be called on that + * channel twice when Tcl_Exit runs. This will lead to a core dump. + */ +static void +vfsExit( + void *pArg) +{ + ZvfsChannelInfo *pInfo = pArg; + + pInfo->chan = 0; } /* -** This routine is called when the ZVFS channel is closed -*/ -static int vfsClose( - ClientData instanceData, /* A ZvfsChannelInfo structure */ - Tcl_Interp *interp /* The TCL interpreter */ -){ - ZvfsChannelInfo* pInfo = (ZvfsChannelInfo*)instanceData; - - if( pInfo->zBuf ){ - Tcl_Free(pInfo->zBuf); - inflateEnd(&pInfo->stream); - } - if( pInfo->chan ){ - Tcl_Close(interp, pInfo->chan); - Tcl_DeleteExitHandler(vfsExit, pInfo); - } - Tcl_Free((char*)pInfo); - return TCL_OK; + * This routine is called when the ZVFS channel is closed + */ +static int +vfsClose( + ClientData instanceData, /* A ZvfsChannelInfo structure */ + Tcl_Interp *interp) /* The TCL interpreter */ +{ + ZvfsChannelInfo* pInfo = instanceData; + + if( pInfo->zBuf ){ + Tcl_Free(pInfo->zBuf); + inflateEnd(&pInfo->stream); + } + if( pInfo->chan ){ + Tcl_Close(interp, pInfo->chan); + Tcl_DeleteExitHandler(vfsExit, pInfo); + } + Tcl_Free((char*)pInfo); + return TCL_OK; } /* -** The TCL I/O system calls this function to actually read information -** from a ZVFS file. -*/ -static int vfsInput ( - ClientData instanceData, /* The channel to read from */ - char *buf, /* Buffer to fill */ - int toRead, /* Requested number of bytes */ - int *pErrorCode /* Location of error flag */ -){ - ZvfsChannelInfo* pInfo = (ZvfsChannelInfo*) instanceData; - - if( toRead > pInfo->nByte ){ - toRead = pInfo->nByte; - } - if( toRead == 0 ){ - return 0; - } - if( pInfo->isCompressed ){ - int err = Z_OK; - z_stream *stream = &pInfo->stream; - stream->next_out = buf; - stream->avail_out = toRead; - while (stream->avail_out) { - if (!stream->avail_in) { - int len = pInfo->nByteCompr; - if (len > COMPR_BUF_SIZE) { - len = COMPR_BUF_SIZE; - } - len = Tcl_Read(pInfo->chan, pInfo->zBuf, len); - pInfo->nByteCompr -= len; - stream->next_in = pInfo->zBuf; - stream->avail_in = len; - } - err = inflate(stream, Z_NO_FLUSH); - if (err) break; - } - if (err == Z_STREAM_END) { - if ((stream->avail_out != 0)) { - *pErrorCode = err; /* premature end */ - return -1; - } - }else if( err ){ - *pErrorCode = err; /* some other zlib error */ - return -1; - } - }else{ - toRead = Tcl_Read(pInfo->chan, buf, toRead); - } - pInfo->nByte -= toRead; - pInfo->readSoFar += toRead; - *pErrorCode = 0; - return toRead; + * The TCL I/O system calls this function to actually read information from a + * ZVFS file. + */ +static int +vfsInput( + ClientData instanceData, /* The channel to read from */ + char *buf, /* Buffer to fill */ + int toRead, /* Requested number of bytes */ + int *pErrorCode) /* Location of error flag */ +{ + ZvfsChannelInfo* pInfo = instanceData; + + if( toRead > pInfo->nByte ){ + toRead = pInfo->nByte; + } + if( toRead == 0 ){ + return 0; + } + if( pInfo->isCompressed ){ + int err = Z_OK; + z_stream *stream = &pInfo->stream; + + stream->next_out = buf; + stream->avail_out = toRead; + while (stream->avail_out) { + if (!stream->avail_in) { + int len = pInfo->nByteCompr; + + if (len > COMPR_BUF_SIZE) { + len = COMPR_BUF_SIZE; + } + len = Tcl_Read(pInfo->chan, pInfo->zBuf, len); + pInfo->nByteCompr -= len; + stream->next_in = pInfo->zBuf; + stream->avail_in = len; + } + err = inflate(stream, Z_NO_FLUSH); + if (err) { + break; + } + } + if (err == Z_STREAM_END) { + if ((stream->avail_out != 0)) { + *pErrorCode = err; /* premature end */ + return -1; + } + }else if( err ){ + *pErrorCode = err; /* some other zlib error */ + return -1; + } + }else{ + toRead = Tcl_Read(pInfo->chan, buf, toRead); + } + pInfo->nByte -= toRead; + pInfo->readSoFar += toRead; + *pErrorCode = 0; + return toRead; } /* -** Write to a ZVFS file. ZVFS files are always read-only, so this routine -** always returns an error. -*/ -static int vfsOutput( - ClientData instanceData, /* The channel to write to */ - CONST char *buf, /* Data to be stored. */ - int toWrite, /* Number of bytes to write. */ - int *pErrorCode /* Location of error flag. */ -){ - *pErrorCode = EINVAL; - return -1; + * Write to a ZVFS file. ZVFS files are always read-only, so this routine + * always returns an error. + */ +static int +vfsOutput( + ClientData instanceData, /* The channel to write to */ + const char *buf, /* Data to be stored. */ + int toWrite, /* Number of bytes to write. */ + int *pErrorCode) /* Location of error flag. */ +{ + *pErrorCode = EINVAL; + return -1; } /* -** Move the file pointer so that the next byte read will be "offset". -*/ -static int vfsSeek( - ClientData instanceData, /* The file structure */ - long offset, /* Offset to seek to */ - int mode, /* One of SEEK_CUR, SEEK_SET or SEEK_END */ - int *pErrorCode /* Write the error code here */ -){ - ZvfsChannelInfo* pInfo = (ZvfsChannelInfo*) instanceData; - - switch( mode ){ - case SEEK_CUR: { - offset += pInfo->readSoFar; - break; - } - case SEEK_END: { - offset += pInfo->readSoFar + pInfo->nByte; - break; - } - default: { - /* Do nothing */ - break; - } - } - if (offset < 0) offset = 0; - if( !pInfo->isCompressed ){ - Tcl_Seek(pInfo->chan, offset + pInfo->startOfData, SEEK_SET); - pInfo->nByte = pInfo->nData; - pInfo->readSoFar = offset; - }else{ - if( offsetreadSoFar ){ - z_stream *stream = &pInfo->stream; - inflateEnd(stream); - stream->zalloc = (alloc_func)0; - stream->zfree = (free_func)0; - stream->opaque = (voidpf)0; - stream->avail_in = 2; - stream->next_in = pInfo->zBuf; - pInfo->zBuf[0] = 0x78; - pInfo->zBuf[1] = 0x01; - inflateInit(&pInfo->stream); - Tcl_Seek(pInfo->chan, pInfo->startOfData, SEEK_SET); - pInfo->nByte += pInfo->readSoFar; - pInfo->nByteCompr = pInfo->nData; - pInfo->readSoFar = 0; - } - while( pInfo->readSoFar < offset ){ - int toRead, errCode; - char zDiscard[100]; - toRead = offset - pInfo->readSoFar; - if( toRead>sizeof(zDiscard) ) toRead = sizeof(zDiscard); - vfsInput(instanceData, zDiscard, toRead, &errCode); - } - } - return pInfo->readSoFar; + * Move the file pointer so that the next byte read will be "offset". + */ +static int +vfsSeek( + ClientData instanceData, /* The file structure */ + long offset, /* Offset to seek to */ + int mode, /* One of SEEK_CUR, SEEK_SET or SEEK_END */ + int *pErrorCode) /* Write the error code here */ +{ + ZvfsChannelInfo* pInfo = instanceData; + + switch( mode ){ + case SEEK_CUR: + offset += pInfo->readSoFar; + break; + case SEEK_END: + offset += pInfo->readSoFar + pInfo->nByte; + break; + default: + /* Do nothing */ + break; + } + if (offset < 0) { + offset = 0; + } + if( !pInfo->isCompressed ){ + Tcl_Seek(pInfo->chan, offset + pInfo->startOfData, SEEK_SET); + pInfo->nByte = pInfo->nData; + pInfo->readSoFar = offset; + }else{ + if( offsetreadSoFar ){ + z_stream *stream = &pInfo->stream; + + inflateEnd(stream); + stream->zalloc = (alloc_func)0; + stream->zfree = (free_func)0; + stream->opaque = (voidpf)0; + stream->avail_in = 2; + stream->next_in = pInfo->zBuf; + pInfo->zBuf[0] = 0x78; + pInfo->zBuf[1] = 0x01; + inflateInit(&pInfo->stream); + Tcl_Seek(pInfo->chan, pInfo->startOfData, SEEK_SET); + pInfo->nByte += pInfo->readSoFar; + pInfo->nByteCompr = pInfo->nData; + pInfo->readSoFar = 0; + } + while( pInfo->readSoFar < offset ){ + int toRead, errCode; + char zDiscard[100]; + + toRead = offset - pInfo->readSoFar; + if( toRead>sizeof(zDiscard) ) { + toRead = sizeof(zDiscard); + } + vfsInput(instanceData, zDiscard, toRead, &errCode); + } + } + return pInfo->readSoFar; } /* -** Handle events on the channel. ZVFS files do not generate events, -** so this is a no-op. -*/ -static void vfsWatchChannel( - ClientData instanceData, /* Channel to watch */ - int mask /* Events of interest */ -){ - return; + * Handle events on the channel. ZVFS files do not generate events, so this + * is a no-op. + */ +static void +vfsWatchChannel( + ClientData instanceData, /* Channel to watch */ + int mask) /* Events of interest */ +{ + return; } /* -** Called to retrieve the underlying file handle for this ZVFS file. -** As the ZVFS file has no underlying file handle, this is a no-op. -*/ -static int vfsGetFile( - ClientData instanceData, /* Channel to query */ - int direction, /* Direction of interest */ - ClientData* handlePtr /* Space to the handle into */ -){ - return TCL_ERROR; + * Called to retrieve the underlying file handle for this ZVFS file. As the + * ZVFS file has no underlying file handle, this is a no-op. + */ +static int +vfsGetFile( + ClientData instanceData, /* Channel to query */ + int direction, /* Direction of interest */ + ClientData* handlePtr) /* Space to the handle into */ +{ + return TCL_ERROR; } /* -** This structure describes the channel type structure for -** access to the ZVFS. -*/ + * This structure describes the channel type structure for access to the ZVFS. + */ static Tcl_ChannelType vfsChannelType = { - "vfs", /* Type name. */ - NULL, /* Set blocking/nonblocking behaviour. NULL'able */ - vfsClose, /* Close channel, clean instance data */ - vfsInput, /* Handle read request */ - vfsOutput, /* Handle write request */ - vfsSeek, /* Move location of access point. NULL'able */ - NULL, /* Set options. NULL'able */ - NULL, /* Get options. NULL'able */ - vfsWatchChannel, /* Initialize notifier */ - vfsGetFile /* Get OS handle from the channel. */ + "vfs", /* Type name. */ + NULL, /* Set blocking/nonblocking behaviour. + * NULL'able */ + vfsClose, /* Close channel, clean instance data */ + vfsInput, /* Handle read request */ + vfsOutput, /* Handle write request */ + vfsSeek, /* Move location of access point. NULL'able */ + NULL, /* Set options. NULL'able */ + NULL, /* Get options. NULL'able */ + vfsWatchChannel, /* Initialize notifier */ + vfsGetFile /* Get OS handle from the channel. */ }; /* -** This routine attempts to do an open of a file. Check to see -** if the file is located in the ZVFS. If so, then open a channel -** for reading the file. If not, return NULL. -*/ -static Tcl_Channel ZvfsFileOpen( - Tcl_Interp *interp, /* The TCL interpreter doing the open */ - char *zFilename, /* Name of the file to open */ - char *modeString, /* Mode string for the open (ignored) */ - int permissions /* Permissions for a newly created file (ignored) */ -){ - ZvfsFile *pFile; - ZvfsChannelInfo *pInfo; - Tcl_Channel chan; - static int count = 1; - char zName[50]; - unsigned char zBuf[50]; - - pFile = ZvfsLookup(zFilename); - if( pFile==0 ) return NULL; - openarch=1; - chan = Tcl_OpenFileChannel(interp, pFile->pArchive->zName, "r", 0); - openarch=0; - if( chan==0 ){ - return 0; - } - if( Tcl_SetChannelOption(interp, chan, "-translation", "binary") - || Tcl_SetChannelOption(interp, chan, "-encoding", "binary") - ){ - /* this should never happen */ - Tcl_Close(0, chan); - return 0; - } - Tcl_Seek(chan, pFile->iOffset, SEEK_SET); - Tcl_Read(chan, zBuf, 30); - if( memcmp(zBuf, "\120\113\03\04", 4) ){ - if( interp ){ - Tcl_AppendResult(interp, "local header mismatch: ", NULL); + * This routine attempts to do an open of a file. Check to see if the file is + * located in the ZVFS. If so, then open a channel for reading the file. If + * not, return NULL. + */ +static Tcl_Channel +ZvfsFileOpen( + Tcl_Interp *interp, /* The TCL interpreter doing the open */ + char *zFilename, /* Name of the file to open */ + char *modeString, /* Mode string for the open (ignored) */ + int permissions) /* Permissions for a newly created file + * (ignored). */ +{ + ZvfsFile *pFile; + ZvfsChannelInfo *pInfo; + Tcl_Channel chan; + static int count = 1; + char zName[50]; + unsigned char zBuf[50]; + + pFile = ZvfsLookup(zFilename); + if( pFile==0 ) { + return NULL; } - Tcl_Close(interp, chan); - return 0; - } - pInfo = (ZvfsChannelInfo*)Tcl_Alloc( sizeof(*pInfo) ); - pInfo->chan = chan; - Tcl_CreateExitHandler(vfsExit, pInfo); - pInfo->isCompressed = INT16(zBuf, 8); - if( pInfo->isCompressed ){ - z_stream *stream = &pInfo->stream; - pInfo->zBuf = Tcl_Alloc(COMPR_BUF_SIZE); - stream->zalloc = (alloc_func)0; - stream->zfree = (free_func)0; - stream->opaque = (voidpf)0; - stream->avail_in = 2; - stream->next_in = pInfo->zBuf; - pInfo->zBuf[0] = 0x78; - pInfo->zBuf[1] = 0x01; - inflateInit(&pInfo->stream); - }else{ - pInfo->zBuf = 0; - } - pInfo->nByte = INT32(zBuf,22); - pInfo->nByteCompr = pInfo->nData = INT32(zBuf,18); - pInfo->readSoFar = 0; - Tcl_Seek(chan, INT16(zBuf,26)+INT16(zBuf,28), SEEK_CUR); - pInfo->startOfData = Tcl_Tell(chan); - sprintf(zName,"vfs_%x_%x",((int)pFile)>>12,count++); - chan = Tcl_CreateChannel(&vfsChannelType, zName, - (ClientData)pInfo, TCL_READABLE); - return chan; + openarch=1; + chan = Tcl_OpenFileChannel(interp, pFile->pArchive->zName, "r", 0); + openarch=0; + if( chan==0 ){ + return 0; + } + if (Tcl_SetChannelOption(interp, chan, "-translation", "binary") + || Tcl_SetChannelOption(interp, chan, "-encoding", "binary")){ + /* this should never happen */ + Tcl_Close(0, chan); + return 0; + } + Tcl_Seek(chan, pFile->iOffset, SEEK_SET); + Tcl_Read(chan, zBuf, 30); + if( memcmp(zBuf, "\120\113\03\04", 4) ){ + if( interp ){ + Tcl_AppendResult(interp, "local header mismatch: ", NULL); + } + Tcl_Close(interp, chan); + return 0; + } + pInfo = Tcl_Alloc( sizeof(*pInfo) ); + pInfo->chan = chan; + Tcl_CreateExitHandler(vfsExit, pInfo); + pInfo->isCompressed = INT16(zBuf, 8); + if( pInfo->isCompressed ){ + z_stream *stream = &pInfo->stream; + + pInfo->zBuf = Tcl_Alloc(COMPR_BUF_SIZE); + stream->zalloc = (alloc_func)0; + stream->zfree = (free_func)0; + stream->opaque = (voidpf)0; + stream->avail_in = 2; + stream->next_in = pInfo->zBuf; + pInfo->zBuf[0] = 0x78; + pInfo->zBuf[1] = 0x01; + inflateInit(&pInfo->stream); + }else{ + pInfo->zBuf = 0; + } + pInfo->nByte = INT32(zBuf,22); + pInfo->nByteCompr = pInfo->nData = INT32(zBuf,18); + pInfo->readSoFar = 0; + Tcl_Seek(chan, INT16(zBuf,26)+INT16(zBuf,28), SEEK_CUR); + pInfo->startOfData = Tcl_Tell(chan); + sprintf(zName,"vfs_%x_%x",((int)pFile)>>12,count++); + chan = Tcl_CreateChannel(&vfsChannelType, zName, + (ClientData)pInfo, TCL_READABLE); + return chan; } /* -** This routine does a stat() system call for a ZVFS file. -*/ -static int ZvfsFileStat(char *path, struct stat *buf){ - ZvfsFile *pFile; + * This routine does a stat() system call for a ZVFS file. + */ +static int +ZvfsFileStat( + char *path, + struct stat *buf) +{ + ZvfsFile *pFile; - pFile = ZvfsLookup(path); - if( pFile==0 ){ - return -1; - } - memset(buf, 0, sizeof(*buf)); - if (pFile->isdir) - buf->st_mode = 040555; - else - buf->st_mode = (0100000|pFile->permissions); - buf->st_ino = 0; - buf->st_size = pFile->nByte; - buf->st_mtime = pFile->timestamp; - buf->st_ctime = pFile->timestamp; - buf->st_atime = pFile->timestamp; - return 0; + pFile = ZvfsLookup(path); + if( pFile==0 ){ + return -1; + } + memset(buf, 0, sizeof(*buf)); + if (pFile->isdir) { + buf->st_mode = 040555; + } else { + buf->st_mode = (0100000|pFile->permissions); + } + buf->st_ino = 0; + buf->st_size = pFile->nByte; + buf->st_mtime = pFile->timestamp; + buf->st_ctime = pFile->timestamp; + buf->st_atime = pFile->timestamp; + return 0; } /* -** This routine does an access() system call for a ZVFS file. -*/ -static int ZvfsFileAccess(char *path, int mode){ - ZvfsFile *pFile; + * This routine does an access() system call for a ZVFS file. + */ +static int +ZvfsFileAccess( + char *path, + int mode) +{ + ZvfsFile *pFile; - if( mode & 3 ){ - return -1; - } - pFile = ZvfsLookup(path); - if( pFile==0 ){ - return -1; - } - return 0; + if( mode & 3 ){ + return -1; + } + pFile = ZvfsLookup(path); + if( pFile==0 ){ + return -1; + } + return 0; } #ifndef USE_TCL_VFS /* -** This TCL procedure can be used to copy a file. The built-in -** "file copy" command of TCL bypasses the I/O system and does not -** work with zvfs. You have to use a procedure like the following -** instead. -*/ + * This TCL procedure can be used to copy a file. The built-in "file copy" + * command of TCL bypasses the I/O system and does not work with zvfs. You + * have to use a procedure like the following instead. + */ static char zFileCopy[] = "proc zvfs::filecopy {from to {outtype binary}} {\n" " set f [open $from r]\n" @@ -1249,149 +1440,187 @@ static char zFileCopy[] = #else -Tcl_Channel Tobe_FSOpenFileChannelProc - _ANSI_ARGS_((Tcl_Interp *interp, Tcl_Obj *pathPtr, - int mode, int permissions)) { - static int inopen=0; - Tcl_Channel chan; - if (inopen) { - puts("recursive zvfs open"); - return NULL; - } - inopen = 1; - /* if (mode != O_RDONLY) return NULL; */ - chan = ZvfsFileOpen(interp, Tcl_GetString(pathPtr), 0, - permissions); - inopen = 0; - return chan; +Tcl_Channel +Tobe_FSOpenFileChannelProc( + Tcl_Interp *interp, + Tcl_Obj *pathPtr, + int mode, + int permissions) +{ + static int inopen=0; + Tcl_Channel chan; + if (inopen) { + puts("recursive zvfs open"); + return NULL; + } + inopen = 1; + /* if (mode != O_RDONLY) return NULL; */ + chan = ZvfsFileOpen(interp, Tcl_GetString(pathPtr), 0, permissions); + inopen = 0; + return chan; +} + +/* + * This routine does a stat() system call for a ZVFS file. + */ +int +Tobe_FSStatProc( + Tcl_Obj *pathPtr, + struct stat *buf) +{ + return ZvfsFileStat(Tcl_GetString(pathPtr), buf); +} + +/* + * This routine does an access() system call for a ZVFS file. + */ +int +Tobe_FSAccessProc( + Tcl_Obj *pathPtr, + int mode) +{ + return ZvfsFileAccess(Tcl_GetString(pathPtr), mode); } +/* Tcl_Obj* Tobe_FSFilesystemSeparatorProc(Tcl_Obj *pathPtr) { + return Tcl_NewStringObj("/",-1);; +} */ + /* -** This routine does a stat() system call for a ZVFS file. -*/ -int Tobe_FSStatProc _ANSI_ARGS_((Tcl_Obj *pathPtr, struct stat *buf)) { - - return ZvfsFileStat(Tcl_GetString(pathPtr), buf); + * Function to process a 'Tobe_FSMatchInDirectory()'. If not implemented, + * then glob and recursive copy functionality will be lacking in the + * filesystem. + */ +int +Tobe_FSMatchInDirectoryProc( + Tcl_Interp* interp, + Tcl_Obj *result, + Tcl_Obj *pathPtr, + const char *pattern, + Tcl_GlobTypeData * types) +{ + Tcl_HashEntry *pEntry; + Tcl_HashSearch sSearch; + int scnt, len, l, dirglob, dirmnt; + char *zPattern = NULL, *zp=Tcl_GetStringFromObj(pathPtr,&len); + + if (!zp) { + return TCL_ERROR; + } + if (pattern != NULL) { + l=strlen(pattern); + if (!zp) { + zPattern=strdup(pattern); + } else { + zPattern=(char*)malloc(len+l+3); + sprintf(zPattern,"%s%s%s", zp, zp[len-1]=='/'?"":"/",pattern); + } + scnt=strchrcnt(zPattern,'/'); + } + dirglob = (types && types->type && (types->type&TCL_GLOB_TYPE_DIR)); + dirmnt = (types && types->type && (types->type&TCL_GLOB_TYPE_MOUNT)); + if (strcmp(zp, "/") == 0 && strcmp(zPattern, ".*") == 0) { + /*TODO: What goes here?*/ + } + for(pEntry = Tcl_FirstHashEntry(&local.fileHash, &sSearch); + pEntry; pEntry = Tcl_NextHashEntry(&sSearch)){ + ZvfsFile *pFile = Tcl_GetHashValue(pEntry); + char *z = pFile->zName; + + if (zPattern != NULL) { + if( Tcl_StringCaseMatch(z, zPattern, 0) == 0 || + (scnt!=pFile->depth /* && !dirglob */ )) { // TODO: ??? + continue; + } + } else { + if (strcmp(zp, z)) { + continue; + } + } + if (dirmnt) { + if (pFile->isdir != 1) { + continue; + } + } else if (dirglob) { + if (!pFile->isdir) { + continue; + } + } else if (types && !(types->type&TCL_GLOB_TYPE_DIR)) { + if (pFile->isdir) { + continue; + } + } + Tcl_ListObjAppendElement(interp, result, Tcl_NewStringObj(z, -1)); + } + if (zPattern) { + free(zPattern); + } + return TCL_OK; } /* -** This routine does an access() system call for a ZVFS file. -*/ -int Tobe_FSAccessProc _ANSI_ARGS_((Tcl_Obj *pathPtr, int mode)) { - return ZvfsFileAccess(Tcl_GetString(pathPtr), mode); -} - - -/* Tcl_Obj* Tobe_FSFilesystemSeparatorProc - _ANSI_ARGS_((Tcl_Obj *pathPtr)) { - return Tcl_NewStringObj("/",-1);; -} */ -/* Function to process a -* 'Tobe_FSMatchInDirectory()'. If not -* implemented, then glob and recursive -* copy functionality will be lacking in -* the filesystem. */ -int Tobe_FSMatchInDirectoryProc _ANSI_ARGS_((Tcl_Interp* interp, - Tcl_Obj *result, Tcl_Obj *pathPtr, CONST char *pattern, - Tcl_GlobTypeData * types)) { - Tcl_HashEntry *pEntry; - Tcl_HashSearch sSearch; - int scnt, len, l, dirglob, dirmnt; - char *zPattern = NULL, *zp=Tcl_GetStringFromObj(pathPtr,&len);; - if (!zp) return TCL_ERROR; - if (pattern != NULL) { - l=strlen(pattern); - if (!zp) - zPattern=strdup(pattern); - else { - zPattern=(char*)malloc(len+l+3); - sprintf(zPattern,"%s%s%s", zp, zp[len-1]=='/'?"":"/",pattern); - } - scnt=strchrcnt(zPattern,'/'); - } - dirglob = (types && types->type && (types->type&TCL_GLOB_TYPE_DIR)); - dirmnt = (types && types->type && (types->type&TCL_GLOB_TYPE_MOUNT)); - if (strcmp(zp, "/") == 0 && strcmp(zPattern, ".*") == 0) { - } - for(pEntry = Tcl_FirstHashEntry(&local.fileHash, &sSearch); - pEntry; - pEntry = Tcl_NextHashEntry(&sSearch) - ){ - ZvfsFile *pFile = Tcl_GetHashValue(pEntry); - char *z = pFile->zName; - if (zPattern != NULL) { - if( Tcl_StringCaseMatch(z, zPattern, 0) == 0 || - (scnt!=pFile->depth /* && !dirglob */ )) { // TODO: ??? - continue; - } - } else { - if (strcmp(zp, z)) - continue; - } - if (dirmnt) { - if (pFile->isdir != 1) - continue; - } else if (dirglob) { - if (!pFile->isdir) - continue; - } else if (types && !(types->type&TCL_GLOB_TYPE_DIR)) { - if (pFile->isdir) - continue; - } - Tcl_ListObjAppendElement(interp, result, Tcl_NewStringObj(z, -1)); - } - if (zPattern) - free(zPattern); - return TCL_OK; -} + * Function to check whether a path is in this filesystem. This is the most + * important filesystem procedure. + */ +int +Tobe_FSPathInFilesystemProc( + Tcl_Obj *pathPtr, + ClientData *clientDataPtr) +{ + ZvfsFile *zFile; + char *path=Tcl_GetString(pathPtr); -/* Function to check whether a path is in -* this filesystem. This is the most -* important filesystem procedure. */ -int Tobe_FSPathInFilesystemProc _ANSI_ARGS_((Tcl_Obj *pathPtr, - ClientData *clientDataPtr)) { - ZvfsFile *zFile; - char *path=Tcl_GetString(pathPtr); // if (ZvfsLookupMount(path)!=0) // return TCL_OK; - // TODO: also check this is the archive. - if (openarch) - return -1; - zFile = ZvfsLookup(path); - if (zFile!=NULL && strcmp(path,zFile->pArchive->zName)) - return TCL_OK; - return -1; +// // TODO: also check this is the archive. + if (openarch) { + return -1; + } + zFile = ZvfsLookup(path); + if (zFile!=NULL && strcmp(path,zFile->pArchive->zName)) { + return TCL_OK; + } + return -1; } -Tcl_Obj *Tobe_FSListVolumesProc _ANSI_ARGS_((void)) { - Tcl_HashEntry *pEntry; /* Hash table entry */ - Tcl_HashSearch zSearch; /* Search all mount points */ - ZvfsArchive *pArchive; /* The ZIP archive being mounted */ - Tcl_Obj *pVols=NULL, *pVol; - pEntry=Tcl_FirstHashEntry(&local.archiveHash,&zSearch); - while (pEntry) { - if (pArchive = Tcl_GetHashValue(pEntry)) { - if (!pVols) { - pVols=Tcl_NewListObj(0,0); - Tcl_IncrRefCount(pVols); - } - pVol=Tcl_NewStringObj(pArchive->zMountPoint,-1); - Tcl_IncrRefCount(pVol); - Tcl_ListObjAppendElement(NULL, pVols,pVol); - Tcl_DecrRefCount(pVol); - } - pEntry=Tcl_NextHashEntry(&zSearch); - } - return pVols; +Tcl_Obj * +Tobe_FSListVolumesProc(void) +{ + Tcl_HashEntry *pEntry; /* Hash table entry */ + Tcl_HashSearch zSearch; /* Search all mount points */ + ZvfsArchive *pArchive; /* The ZIP archive being mounted */ + Tcl_Obj *pVols=NULL, *pVol; + + pEntry=Tcl_FirstHashEntry(&local.archiveHash,&zSearch); + while (pEntry) { + if (pArchive = Tcl_GetHashValue(pEntry)) { + if (!pVols) { + pVols=Tcl_NewListObj(0,0); + Tcl_IncrRefCount(pVols); + } + pVol=Tcl_NewStringObj(pArchive->zMountPoint,-1); + Tcl_IncrRefCount(pVol); + Tcl_ListObjAppendElement(NULL, pVols,pVol); + Tcl_DecrRefCount(pVol); + } + pEntry=Tcl_NextHashEntry(&zSearch); + } + return pVols; } -int Tobe_FSChdirProc _ANSI_ARGS_((Tcl_Obj *pathPtr)) { - /* Someday, we should actually check if this is a valid path. */ - return TCL_OK; +int +Tobe_FSChdirProc( + Tcl_Obj *pathPtr) +{ + /* Someday, we should actually check if this is a valid path. */ + return TCL_OK; } -CONST char** Tobe_FSFileAttrStringsProc _ANSI_ARGS_((Tcl_Obj *pathPtr, - Tcl_Obj** objPtrRef)) { +const char ** +Tobe_FSFileAttrStringsProc( + Tcl_Obj *pathPtr, + Tcl_Obj** objPtrRef) +{ Tcl_Obj *listPtr; Tcl_Interp *interp = NULL; char *path=Tcl_GetString(pathPtr); @@ -1400,45 +1629,49 @@ CONST char** Tobe_FSFileAttrStringsProc _ANSI_ARGS_((Tcl_Obj *pathPtr, #else static CONST char *attrs[] = { "-group", "-owner", "-permissions", 0 }; #endif - if (ZvfsLookup(path)==0) - return NULL; + if (ZvfsLookup(path)==0) { + return NULL; + } return attrs; } -int Tobe_FSFileAttrsGetProc _ANSI_ARGS_((Tcl_Interp *interp, - int index, Tcl_Obj *pathPtr, - Tcl_Obj **objPtrRef)) { - +int +Tobe_FSFileAttrsGetProc( + Tcl_Interp *interp, + int index, + Tcl_Obj *pathPtr, + Tcl_Obj **objPtrRef) +{ char *path=Tcl_GetString(pathPtr); char buf[50]; ZvfsFile *zFile; + if ((zFile = ZvfsLookup(path))==0) - return TCL_ERROR; + return TCL_ERROR; switch (index) { #ifdef __WIN32__ - - case 0: /* -archive */ - *objPtrRef = Tcl_NewStringObj("0", -1); break; - case 1: /* -hidden */ - *objPtrRef = Tcl_NewStringObj("0", -1); break; - case 2: /* -readonly */ - *objPtrRef = Tcl_NewStringObj("", -1); break; - case 3: /* -system */ - *objPtrRef = Tcl_NewStringObj("", -1); break; - case 4: /* -shortname */ - *objPtrRef = Tcl_NewStringObj("", -1); + case 0: /* -archive */ + *objPtrRef = Tcl_NewStringObj("0", -1); break; + case 1: /* -hidden */ + *objPtrRef = Tcl_NewStringObj("0", -1); break; + case 2: /* -readonly */ + *objPtrRef = Tcl_NewStringObj("", -1); break; + case 3: /* -system */ + *objPtrRef = Tcl_NewStringObj("", -1); break; + case 4: /* -shortname */ + *objPtrRef = Tcl_NewStringObj("", -1); #else - case 0: /* -group */ - *objPtrRef = Tcl_NewStringObj("", -1); break; - case 1: /* -owner */ - *objPtrRef = Tcl_NewStringObj("", -1); break; - case 2: /* -permissions */ - sprintf(buf, "%03o", zFile->permissions); - *objPtrRef = Tcl_NewStringObj(buf, -1); break; + case 0: /* -group */ + *objPtrRef = Tcl_NewStringObj("", -1); break; + case 1: /* -owner */ + *objPtrRef = Tcl_NewStringObj("", -1); break; + case 2: /* -permissions */ + sprintf(buf, "%03o", zFile->permissions); + *objPtrRef = Tcl_NewStringObj(buf, -1); break; #endif } - + return TCL_OK; } @@ -1466,234 +1699,185 @@ int Tobe_FSFileAttrsGetProc _ANSI_ARGS_((Tcl_Interp *interp, #define Tobe_FSDupInternalRepProc 0 #define Tobe_FSFreeInternalRepProc 0 #define Tobe_FSFilesystemPathTypeProc 0 -#define Tobe_FSLinkProc 0 +#define Tobe_FSLinkProc 0 #else -/* Function to process a -* 'Tobe_FSLoadFile()' call. If not -* implemented, Tcl will fall back on -* a copy to native-temp followed by a -* Tobe_FSLoadFile on that temporary copy. */ -int Tobe_FSLoadFileProc _ANSI_ARGS_((Tcl_Interp * interp, - Tcl_Obj *pathPtr, char * sym1, char * sym2, - Tcl_PackageInitProc ** proc1Ptr, - Tcl_PackageInitProc ** proc2Ptr, - ClientData * clientDataPtr)) { return 0; } - - -/* Function to unload a previously -* successfully loaded file. If load was -* implemented, then this should also be -* implemented, if there is any cleanup -* action required. */ -void Tobe_FSUnloadFileProc _ANSI_ARGS_((ClientData clientData)) { - return; +/* + * Function to process a 'Tobe_FSLoadFile()' call. If not implemented, Tcl + * will fall back on a copy to native-temp followed by a Tobe_FSLoadFile on + * that temporary copy. + */ +int +Tobe_FSLoadFileProc( + Tcl_Interp * interp, + Tcl_Obj *pathPtr, + char * sym1, + char * sym2, + Tcl_PackageInitProc ** proc1Ptr, + Tcl_PackageInitProc ** proc2Ptr, + ClientData * clientDataPtr) +{ + return 0; } -Tcl_Obj* Tobe_FSGetCwdProc _ANSI_ARGS_((Tcl_Interp *interp)) { return 0; } -int Tobe_FSCreateDirectoryProc _ANSI_ARGS_((Tcl_Obj *pathPtr)) { return 0; } -int Tobe_FSDeleteFileProc _ANSI_ARGS_((Tcl_Obj *pathPtr)) { return 0; } -int Tobe_FSCopyDirectoryProc _ANSI_ARGS_((Tcl_Obj *srcPathPtr, - Tcl_Obj *destPathPtr, Tcl_Obj **errorPtr)) { return 0; } -int Tobe_FSCopyFileProc _ANSI_ARGS_((Tcl_Obj *srcPathPtr, - Tcl_Obj *destPathPtr)) { return 0; } -int Tobe_FSRemoveDirectoryProc _ANSI_ARGS_((Tcl_Obj *pathPtr, - int recursive, Tcl_Obj **errorPtr)) { return 0; } -int Tobe_FSRenameFileProc _ANSI_ARGS_((Tcl_Obj *srcPathPtr, - Tcl_Obj *destPathPtr)) { return 0; } +/* + * Function to unload a previously successfully loaded file. If load was + * implemented, then this should also be implemented, if there is any cleanup + * action required. + */ +void Tobe_FSUnloadFileProc(ClientData clientData) { return; } +Tcl_Obj* Tobe_FSGetCwdProc(Tcl_Interp *interp) { return 0; } +int Tobe_FSCreateDirectoryProc(Tcl_Obj *pathPtr) { return 0; } +int Tobe_FSDeleteFileProc(Tcl_Obj *pathPtr) { return 0; } +int Tobe_FSCopyDirectoryProc(Tcl_Obj *srcPathPtr, Tcl_Obj *destPathPtr, + Tcl_Obj **errorPtr) { return 0; } +int Tobe_FSCopyFileProc(Tcl_Obj *srcPathPtr, + Tcl_Obj *destPathPtr) { return 0; } +int Tobe_FSRemoveDirectoryProc(Tcl_Obj *pathPtr, int recursive, + Tcl_Obj **errorPtr) { return 0; } +int Tobe_FSRenameFileProc(Tcl_Obj *srcPathPtr, + Tcl_Obj *destPathPtr) { return 0; } /* We have to declare the utime structure here. */ -int Tobe_FSUtimeProc _ANSI_ARGS_((Tcl_Obj *pathPtr, - struct utimbuf *tval)) { return 0; } -int Tobe_FSNormalizePathProc _ANSI_ARGS_((Tcl_Interp *interp, - Tcl_Obj *pathPtr, int nextCheckpoint)) { return 0; } -int Tobe_FSFileAttrsSetProc _ANSI_ARGS_((Tcl_Interp *interp, - int index, Tcl_Obj *pathPtr, - Tcl_Obj *objPtr)) { return 0; } -Tcl_Obj* Tobe_FSLinkProc _ANSI_ARGS_((Tcl_Obj *pathPtr)) { return 0; } -Tcl_Obj* Tobe_FSFilesystemPathTypeProc - _ANSI_ARGS_((Tcl_Obj *pathPtr)) { return 0; } -void Tobe_FSFreeInternalRepProc _ANSI_ARGS_((ClientData clientData)) { return; } -ClientData Tobe_FSDupInternalRepProc - _ANSI_ARGS_((ClientData clientData)) { return 0; } -Tcl_Obj* Tobe_FSInternalToNormalizedProc - _ANSI_ARGS_((ClientData clientData)) { return 0; } -ClientData Tobe_FSCreateInternalRepProc _ANSI_ARGS_((Tcl_Obj *pathPtr)) { - return 0; -} - +int Tobe_FSUtimeProc(Tcl_Obj *pathPtr, struct utimbuf *tval) { return 0; } +int Tobe_FSNormalizePathProc(Tcl_Interp *interp, Tcl_Obj *pathPtr, + int nextCheckpoint) { return 0; } +int Tobe_FSFileAttrsSetProc(Tcl_Interp *interp, int index, Tcl_Obj *pathPtr, + Tcl_Obj *objPtr) { return 0; } +Tcl_Obj* Tobe_FSLinkProc(Tcl_Obj *pathPtr) { return 0; } +Tcl_Obj* Tobe_FSFilesystemPathTypeProc(Tcl_Obj *pathPtr) { return 0; } +void Tobe_FSFreeInternalRepProc(ClientData clientData) { return; } +ClientData Tobe_FSDupInternalRepProc(ClientData clientData) { return 0; } +Tcl_Obj* Tobe_FSInternalToNormalizedProc(ClientData clientData) { return 0; } +ClientData Tobe_FSCreateInternalRepProc(Tcl_Obj *pathPtr) { return 0; } #endif - static Tcl_Filesystem Tobe_Filesystem = { - "tobe", /* The name of the filesystem. */ - sizeof(Tcl_Filesystem), /* Length of this structure, so future - * binary compatibility can be assured. */ - TCL_FILESYSTEM_VERSION_1, - /* Version of the filesystem type. */ - Tobe_FSPathInFilesystemProc, - /* Function to check whether a path is in - * this filesystem. This is the most - * important filesystem procedure. */ - Tobe_FSDupInternalRepProc, - /* Function to duplicate internal fs rep. May - * be NULL (but then fs is less efficient). */ - Tobe_FSFreeInternalRepProc, - /* Function to free internal fs rep. Must - * be implemented, if internal representations - * need freeing, otherwise it can be NULL. */ + "tobe", /* The name of the filesystem. */ + sizeof(Tcl_Filesystem), /* Length of this structure, so future binary + * compatibility can be assured. */ + TCL_FILESYSTEM_VERSION_1, /* Version of the filesystem type. */ + Tobe_FSPathInFilesystemProc,/* Function to check whether a path is in this + * filesystem. This is the most important + * filesystem procedure. */ + Tobe_FSDupInternalRepProc, /* Function to duplicate internal fs rep. May + * be NULL (but then fs is less efficient). */ + Tobe_FSFreeInternalRepProc, /* Function to free internal fs rep. Must be + * implemented, if internal representations + * need freeing, otherwise it can be NULL. */ Tobe_FSInternalToNormalizedProc, - /* Function to convert internal representation - * to a normalized path. Only required if - * the fs creates pure path objects with no - * string/path representation. */ + /* Function to convert internal representation + * to a normalized path. Only required if the + * fs creates pure path objects with no + * string/path representation. */ Tobe_FSCreateInternalRepProc, - /* Function to create a filesystem-specific - * internal representation. May be NULL - * if paths have no internal representation, - * or if the Tobe_FSPathInFilesystemProc - * for this filesystem always immediately - * creates an internal representation for - * paths it accepts. */ - Tobe_FSNormalizePathProc, - /* Function to normalize a path. Should - * be implemented for all filesystems - * which can have multiple string - * representations for the same path - * object. */ + /* Function to create a filesystem-specific + * internal representation. May be NULL if + * paths have no internal representation, or + * if the Tobe_FSPathInFilesystemProc for this + * filesystem always immediately creates an + * internal representation for paths it + * accepts. */ + Tobe_FSNormalizePathProc, /* Function to normalize a path. Should be + * implemented for all filesystems which can + * have multiple string representations for + * the same path object. */ Tobe_FSFilesystemPathTypeProc, - /* Function to determine the type of a - * path in this filesystem. May be NULL. */ + /* Function to determine the type of a path in + * this filesystem. May be NULL. */ Tobe_FSFilesystemSeparatorProc, - /* Function to return the separator - * character(s) for this filesystem. Must - * be implemented. */ - Tobe_FSStatProc, - /* - * Function to process a 'Tobe_FSStat()' - * call. Must be implemented for any - * reasonable filesystem. - */ - Tobe_FSAccessProc, - /* - * Function to process a 'Tobe_FSAccess()' - * call. Must be implemented for any - * reasonable filesystem. - */ - Tobe_FSOpenFileChannelProc, - /* - * Function to process a - * 'Tobe_FSOpenFileChannel()' call. Must be - * implemented for any reasonable - * filesystem. - */ - Tobe_FSMatchInDirectoryProc, - /* Function to process a - * 'Tobe_FSMatchInDirectory()'. If not - * implemented, then glob and recursive - * copy functionality will be lacking in - * the filesystem. */ - Tobe_FSUtimeProc, - /* Function to process a - * 'Tobe_FSUtime()' call. Required to - * allow setting (not reading) of times - * with 'file mtime', 'file atime' and - * the open-r/open-w/fcopy implementation - * of 'file copy'. */ - Tobe_FSLinkProc, - /* Function to process a - * 'Tobe_FSLink()' call. Should be - * implemented only if the filesystem supports - * links. */ - Tobe_FSListVolumesProc, - /* Function to list any filesystem volumes - * added by this filesystem. Should be - * implemented only if the filesystem adds - * volumes at the head of the filesystem. */ - Tobe_FSFileAttrStringsProc, - /* Function to list all attributes strings - * which are valid for this filesystem. - * If not implemented the filesystem will - * not support the 'file attributes' command. - * This allows arbitrary additional information - * to be attached to files in the filesystem. */ - Tobe_FSFileAttrsGetProc, - /* Function to process a - * 'Tobe_FSFileAttrsGet()' call, used by - * 'file attributes'. */ - Tobe_FSFileAttrsSetProc, - /* Function to process a - * 'Tobe_FSFileAttrsSet()' call, used by - * 'file attributes'. */ - Tobe_FSCreateDirectoryProc, - /* Function to process a - * 'Tobe_FSCreateDirectory()' call. Should - * be implemented unless the FS is - * read-only. */ - Tobe_FSRemoveDirectoryProc, - /* Function to process a - * 'Tobe_FSRemoveDirectory()' call. Should - * be implemented unless the FS is - * read-only. */ - Tobe_FSDeleteFileProc, - /* Function to process a - * 'Tobe_FSDeleteFile()' call. Should - * be implemented unless the FS is - * read-only. */ - Tobe_FSCopyFileProc, - /* Function to process a - * 'Tobe_FSCopyFile()' call. If not - * implemented Tcl will fall back - * on open-r, open-w and fcopy as - * a copying mechanism. */ - Tobe_FSRenameFileProc, - /* Function to process a - * 'Tobe_FSRenameFile()' call. If not - * implemented, Tcl will fall back on - * a copy and delete mechanism. */ - Tobe_FSCopyDirectoryProc, - /* Function to process a - * 'Tobe_FSCopyDirectory()' call. If - * not implemented, Tcl will fall back - * on a recursive create-dir, file copy - * mechanism. */ - Tobe_FSLoadFileProc, - /* Function to process a - * 'Tobe_FSLoadFile()' call. If not - * implemented, Tcl will fall back on - * a copy to native-temp followed by a - * Tobe_FSLoadFile on that temporary copy. */ - Tobe_FSUnloadFileProc, - /* Function to unload a previously - * successfully loaded file. If load was - * implemented, then this should also be - * implemented, if there is any cleanup - * action required. */ - Tobe_FSGetCwdProc, - /* - * Function to process a 'Tobe_FSGetCwd()' - * call. Most filesystems need not - * implement this. It will usually only be - * called once, if 'getcwd' is called - * before 'chdir'. May be NULL. - */ - Tobe_FSChdirProc, - /* - * Function to process a 'Tobe_FSChdir()' - * call. If filesystems do not implement - * this, it will be emulated by a series of - * directory access checks. Otherwise, - * virtual filesystems which do implement - * it need only respond with a positive - * return result if the dirName is a valid - * directory in their filesystem. They - * need not remember the result, since that - * will be automatically remembered for use - * by GetCwd. Real filesystems should - * carry out the correct action (i.e. call - * the correct system 'chdir' api). If not - * implemented, then 'cd' and 'pwd' will - * fail inside the filesystem. - */ + /* Function to return the separator + * character(s) for this filesystem. Must be + * implemented. */ + Tobe_FSStatProc, /* Function to process a 'Tobe_FSStat()' call. + * Must be implemented for any reasonable + * filesystem. */ + Tobe_FSAccessProc, /* Function to process a 'Tobe_FSAccess()' + * call. Must be implemented for any + * reasonable filesystem. */ + Tobe_FSOpenFileChannelProc, /* Function to process a + * 'Tobe_FSOpenFileChannel()' call. Must be + * implemented for any reasonable + * filesystem. */ + Tobe_FSMatchInDirectoryProc,/* Function to process a + * 'Tobe_FSMatchInDirectory()'. If not + * implemented, then glob and recursive copy + * functionality will be lacking in the + * filesystem. */ + Tobe_FSUtimeProc, /* Function to process a 'Tobe_FSUtime()' + * call. Required to allow setting (not + * reading) of times with 'file mtime', 'file + * atime' and the open-r/open-w/fcopy + * implementation of 'file copy'. */ + Tobe_FSLinkProc, /* Function to process a 'Tobe_FSLink()' call. + * Should be implemented only if the + * filesystem supports links. */ + Tobe_FSListVolumesProc, /* Function to list any filesystem volumes + * added by this filesystem. Should be + * implemented only if the filesystem adds + * volumes at the head of the filesystem. */ + Tobe_FSFileAttrStringsProc, /* Function to list all attributes strings + * which are valid for this filesystem. If + * not implemented the filesystem will not + * support the 'file attributes' command. + * This allows arbitrary additional + * information to be attached to files in the + * filesystem. */ + Tobe_FSFileAttrsGetProc, /* Function to process a + * 'Tobe_FSFileAttrsGet()' call, used by 'file + * attributes'. */ + Tobe_FSFileAttrsSetProc, /* Function to process a + * 'Tobe_FSFileAttrsSet()' call, used by 'file + * attributes'. */ + Tobe_FSCreateDirectoryProc, /* Function to process a + * 'Tobe_FSCreateDirectory()' call. Should be + * implemented unless the FS is read-only. */ + Tobe_FSRemoveDirectoryProc, /* Function to process a + * 'Tobe_FSRemoveDirectory()' call. Should be + * implemented unless the FS is read-only. */ + Tobe_FSDeleteFileProc, /* Function to process a 'Tobe_FSDeleteFile()' + * call. Should be implemented unless the FS + * is read-only. */ + Tobe_FSCopyFileProc, /* Function to process a 'Tobe_FSCopyFile()' + * call. If not implemented Tcl will fall + * back on open-r, open-w and fcopy as a + * copying mechanism. */ + Tobe_FSRenameFileProc, /* Function to process a 'Tobe_FSRenameFile()' + * call. If not implemented, Tcl will fall + * back on a copy and delete mechanism. */ + Tobe_FSCopyDirectoryProc, /* Function to process a + * 'Tobe_FSCopyDirectory()' call. If not + * implemented, Tcl will fall back on a + * recursive create-dir, file copy + * mechanism. */ + Tobe_FSLoadFileProc, /* Function to process a 'Tobe_FSLoadFile()' + * call. If not implemented, Tcl will fall + * back on a copy to native-temp followed by a + * Tobe_FSLoadFile on that temporary copy. */ + Tobe_FSUnloadFileProc, /* Function to unload a previously + * successfully loaded file. If load was + * implemented, then this should also be + * implemented, if there is any cleanup action + * required. */ + Tobe_FSGetCwdProc, /* Function to process a 'Tobe_FSGetCwd()' + * call. Most filesystems need not implement + * this. It will usually only be called once, + * if 'getcwd' is called before 'chdir'. May + * be NULL. */ + Tobe_FSChdirProc, /* Function to process a 'Tobe_FSChdir()' + * call. If filesystems do not implement this, + * it will be emulated by a series of + * directory access checks. Otherwise, virtual + * filesystems which do implement it need only + * respond with a positive return result if + * the dirName is a valid directory in their + * filesystem. They need not remember the + * result, since that will be automatically + * remembered for use by GetCwd. Real + * filesystems should carry out the correct + * action (i.e. call the correct system + * 'chdir' api). If not implemented, then 'cd' + * and 'pwd' will fail inside the + * filesystem. */ }; #endif @@ -1707,490 +1891,562 @@ static int ZvfsDumpObjCmd( void *NotUsed, Tcl_Interp *interp, int objc, Tcl_Obj static int ZvfsStartObjCmd( void *NotUsed, Tcl_Interp *interp, int objc, Tcl_Obj *const* objv); /* -** Initialize the ZVFS system. -*/ -int Zvfs_doInit(Tcl_Interp *interp, int safe){ - int n; + * Initialize the ZVFS system. + */ +int +Zvfs_doInit( + Tcl_Interp *interp, + int safe) +{ + int n; #ifdef USE_TCL_STUBS - if( Tcl_InitStubs(interp,"8.0",0)==0 ){ - return TCL_ERROR; - } + if( Tcl_InitStubs(interp,"8.0",0)==0 ){ + return TCL_ERROR; + } #endif - Tcl_StaticPackage(interp, "zvfs", Tcl_Zvfs_Init, Tcl_Zvfs_SafeInit); - if (!safe) { - Tcl_CreateCommand(interp, "zvfs::mount", ZvfsMountCmd, 0, 0); - Tcl_CreateCommand(interp, "zvfs::unmount", ZvfsUnmountCmd, 0, 0); - Tcl_CreateObjCommand(interp, "zvfs::append", ZvfsAppendObjCmd, 0, 0); - Tcl_CreateObjCommand(interp, "zvfs::add", ZvfsAddObjCmd, 0, 0); - } - Tcl_CreateObjCommand(interp, "zvfs::exists", ZvfsExistsObjCmd, 0, 0); - Tcl_CreateObjCommand(interp, "zvfs::info", ZvfsInfoObjCmd, 0, 0); - Tcl_CreateObjCommand(interp, "zvfs::list", ZvfsListObjCmd, 0, 0); - Tcl_CreateObjCommand(interp, "zvfs::dump", ZvfsDumpObjCmd, 0, 0); - Tcl_CreateObjCommand(interp, "zvfs::start", ZvfsStartObjCmd, 0, 0); - Tcl_SetVar(interp, "::zvfs::auto_ext", ".tcl .tk .itcl .htcl .txt .c .h .tht", TCL_GLOBAL_ONLY); -/* Tcl_CreateObjCommand(interp, "zip::open", ZipOpenObjCmd, 0, 0); */ + Tcl_StaticPackage(interp, "zvfs", Tcl_Zvfs_Init, Tcl_Zvfs_SafeInit); + if (!safe) { + Tcl_CreateCommand(interp, "zvfs::mount", ZvfsMountCmd, 0, 0); + Tcl_CreateCommand(interp, "zvfs::unmount", ZvfsUnmountCmd, 0, 0); + Tcl_CreateObjCommand(interp, "zvfs::append", ZvfsAppendObjCmd, 0, 0); + Tcl_CreateObjCommand(interp, "zvfs::add", ZvfsAddObjCmd, 0, 0); + } + Tcl_CreateObjCommand(interp, "zvfs::exists", ZvfsExistsObjCmd, 0, 0); + Tcl_CreateObjCommand(interp, "zvfs::info", ZvfsInfoObjCmd, 0, 0); + Tcl_CreateObjCommand(interp, "zvfs::list", ZvfsListObjCmd, 0, 0); + Tcl_CreateObjCommand(interp, "zvfs::dump", ZvfsDumpObjCmd, 0, 0); + Tcl_CreateObjCommand(interp, "zvfs::start", ZvfsStartObjCmd, 0, 0); + Tcl_SetVar(interp, "::zvfs::auto_ext", ".tcl .tk .itcl .htcl .txt .c .h .tht", TCL_GLOBAL_ONLY); + /* Tcl_CreateObjCommand(interp, "zip::open", ZipOpenObjCmd, 0, 0); */ #ifndef USE_TCL_VFS - Tcl_GlobalEval(interp, zFileCopy); + Tcl_GlobalEval(interp, zFileCopy); #endif - if( !local.isInit ){ - /* One-time initialization of the ZVFS */ + if( !local.isInit ){ + /* One-time initialization of the ZVFS */ #ifdef USE_TCL_VFS - n = Tcl_FSRegister(0, &Tobe_Filesystem); + n = Tcl_FSRegister(0, &Tobe_Filesystem); #else - extern void TclAccessInsertProc(); - extern void TclStatInsertProc(); - extern void TclOpenFileChannelInsertProc(); - TclAccessInsertProc(ZvfsFileAccess); - TclStatInsertProc(ZvfsFileStat); - TclOpenFileChannelInsertProc(ZvfsFileOpen); + extern void TclAccessInsertProc(); + extern void TclStatInsertProc(); + extern void TclOpenFileChannelInsertProc(); + + TclAccessInsertProc(ZvfsFileAccess); + TclStatInsertProc(ZvfsFileStat); + TclOpenFileChannelInsertProc(ZvfsFileOpen); #endif - Tcl_InitHashTable(&local.fileHash, TCL_STRING_KEYS); - Tcl_InitHashTable(&local.archiveHash, TCL_STRING_KEYS); - local.isInit = 1; - } - if (Zvfs_PostInit) Zvfs_PostInit(interp); - return TCL_OK; + Tcl_InitHashTable(&local.fileHash, TCL_STRING_KEYS); + Tcl_InitHashTable(&local.archiveHash, TCL_STRING_KEYS); + local.isInit = 1; + } + if (Zvfs_PostInit) { + Zvfs_PostInit(interp); + } + return TCL_OK; } -int Tcl_Zvfs_Init(Tcl_Interp *interp){ - return Zvfs_doInit(interp,0); +int +Tcl_Zvfs_Init( + Tcl_Interp *interp) +{ + return Zvfs_doInit(interp,0); } -int Tcl_Zvfs_SafeInit(Tcl_Interp *interp){ - return Zvfs_doInit(interp,1); +int +Tcl_Zvfs_SafeInit( + Tcl_Interp *interp) +{ + return Zvfs_doInit(interp,1); } - /************************************************************************/ /************************************************************************/ /************************************************************************/ /* -** Implement the zvfs::dump command -** -** zvfs::dump ARCHIVE -** -** Each entry in the list returned is of the following form: -** -** {FILENAME DATE-TIME SPECIAL-FLAG OFFSET SIZE COMPRESSED-SIZE} -** -*/ -static int ZvfsDumpObjCmd( - void *NotUsed, /* Client data for this command */ - Tcl_Interp *interp, /* The interpreter used to report errors */ - int objc, /* Number of arguments */ - Tcl_Obj *const* objv /* Values of all arguments */ -){ - char *zFilename; - Tcl_Channel chan; - ZFile *pList; - int rc; - Tcl_Obj *pResult; - - if( objc!=2 ){ - Tcl_WrongNumArgs(interp, 1, objv, "FILENAME"); - return TCL_ERROR; - } - zFilename = Tcl_GetString(objv[1]); - chan = Tcl_OpenFileChannel(interp, zFilename, "r", 0); - if( chan==0 ) return TCL_ERROR; - rc = ZvfsReadTOC(interp, chan, &pList); - if( rc==TCL_ERROR ){ - deleteZFileList(pList); - return rc; - } - Tcl_Close(interp, chan); - pResult = Tcl_GetObjResult(interp); - while( pList ){ - Tcl_Obj *pEntry = Tcl_NewObj(); - ZFile *pNext; - char zDateTime[100]; - Tcl_ListObjAppendElement(interp, pEntry, Tcl_NewStringObj(pList->zName,-1)); - translateDosTimeDate(zDateTime, pList->dosDate, pList->dosTime); - Tcl_ListObjAppendElement(interp, pEntry, Tcl_NewStringObj(zDateTime, -1)); - Tcl_ListObjAppendElement(interp, pEntry, Tcl_NewIntObj(pList->isSpecial)); - Tcl_ListObjAppendElement(interp, pEntry, Tcl_NewIntObj(pList->iOffset)); - Tcl_ListObjAppendElement(interp, pEntry, Tcl_NewIntObj(pList->nByte)); - Tcl_ListObjAppendElement(interp, pEntry, Tcl_NewIntObj(pList->nByteCompr)); - Tcl_ListObjAppendElement(interp, pResult, pEntry); - pNext = pList->pNext; - Tcl_Free((char*)pList); - pList = pList->pNext; - } - return TCL_OK; + * Implement the zvfs::dump command + * + * zvfs::dump ARCHIVE + * + * Each entry in the list returned is of the following form: + * + * {FILENAME DATE-TIME SPECIAL-FLAG OFFSET SIZE COMPRESSED-SIZE} + */ +static int +ZvfsDumpObjCmd( + void *NotUsed, /* Client data for this command */ + Tcl_Interp *interp, /* The interpreter used to report errors */ + int objc, /* Number of arguments */ + Tcl_Obj *const* objv) /* Values of all arguments */ +{ + char *zFilename; + Tcl_Channel chan; + ZFile *pList; + int rc; + Tcl_Obj *pResult; + + if( objc!=2 ){ + Tcl_WrongNumArgs(interp, 1, objv, "FILENAME"); + return TCL_ERROR; + } + zFilename = Tcl_GetString(objv[1]); + chan = Tcl_OpenFileChannel(interp, zFilename, "r", 0); + if( chan==0 ) { + return TCL_ERROR; + } + rc = ZvfsReadTOC(interp, chan, &pList); + if( rc==TCL_ERROR ){ + deleteZFileList(pList); + return rc; + } + Tcl_Close(interp, chan); + pResult = Tcl_GetObjResult(interp); + while( pList ){ + Tcl_Obj *pEntry = Tcl_NewObj(); + ZFile *pNext; + char zDateTime[100]; + + Tcl_ListObjAppendElement(interp, pEntry, + Tcl_NewStringObj(pList->zName,-1)); + translateDosTimeDate(zDateTime, pList->dosDate, pList->dosTime); + Tcl_ListObjAppendElement(interp, pEntry, + Tcl_NewStringObj(zDateTime, -1)); + Tcl_ListObjAppendElement(interp, pEntry, + Tcl_NewIntObj(pList->isSpecial)); + Tcl_ListObjAppendElement(interp, pEntry, + Tcl_NewIntObj(pList->iOffset)); + Tcl_ListObjAppendElement(interp, pEntry, Tcl_NewIntObj(pList->nByte)); + Tcl_ListObjAppendElement(interp, pEntry, + Tcl_NewIntObj(pList->nByteCompr)); + Tcl_ListObjAppendElement(interp, pResult, pEntry); + pNext = pList->pNext; + Tcl_Free((char*)pList); + pList = pList->pNext; + } + return TCL_OK; } /* -** Write a file record into a ZIP archive at the current position of -** the write cursor for channel "chan". Add a ZFile record for the file -** to *ppList. If an error occurs, leave an error message on interp -** and return TCL_ERROR. Otherwise return TCL_OK. -*/ -static int writeFile( - Tcl_Interp *interp, /* Leave an error message here */ - Tcl_Channel out, /* Write the file here */ - Tcl_Channel in, /* Read data from this file */ - char *zSrc, /* Name the new ZIP file entry this */ - char *zDest, /* Name the new ZIP file entry this */ - ZFile **ppList /* Put a ZFile struct for the new file here */ -){ - z_stream stream; - ZFile *p; - int iEndOfData; - int nameLen; - int skip; - int toOut; - char zHdr[30]; - char zInBuf[100000]; - char zOutBuf[100000]; - struct tm *tm; - time_t now; - struct stat stat; - - /* Create a new ZFile structure for this file. - * TODO: fill in date/time etc. - */ - nameLen = strlen(zDest); - p = newZFile(nameLen, ppList); - strcpy(p->zName, zDest); - p->isSpecial = 0; - Tcl_Stat(zSrc, &stat); - now=stat.st_mtime; - tm = localtime(&now); - UnixTimeDate(tm, &p->dosDate, &p->dosTime); - p->iOffset = Tcl_Tell(out); - p->nByte = 0; - p->nByteCompr = 0; - p->nExtra = 0; - p->iCRC = 0; - p->permissions = stat.st_mode; - - /* Fill in as much of the header as we know. - */ - put32(&zHdr[0], 0x04034b50); - put16(&zHdr[4], 0x0014); - put16(&zHdr[6], 0); - put16(&zHdr[8], 8); - put16(&zHdr[10], p->dosTime); - put16(&zHdr[12], p->dosDate); - put16(&zHdr[26], nameLen); - put16(&zHdr[28], 0); - - /* Write the header and filename. - */ - Tcl_Write(out, zHdr, 30); - Tcl_Write(out, zDest, nameLen); - - /* The first two bytes that come out of the deflate compressor are - ** some kind of header that ZIP does not use. So skip the first two - ** output bytes. - */ - skip = 2; - - /* Write the compressed file. Compute the CRC as we progress. - */ - stream.zalloc = (alloc_func)0; - stream.zfree = (free_func)0; - stream.opaque = 0; - stream.avail_in = 0; - stream.next_in = zInBuf; - stream.avail_out = sizeof(zOutBuf); - stream.next_out = zOutBuf; + * Write a file record into a ZIP archive at the current position of the write + * cursor for channel "chan". Add a ZFile record for the file to *ppList. If + * an error occurs, leave an error message on interp and return TCL_ERROR. + * Otherwise return TCL_OK. + */ +static int +writeFile( + Tcl_Interp *interp, /* Leave an error message here */ + Tcl_Channel out, /* Write the file here */ + Tcl_Channel in, /* Read data from this file */ + char *zSrc, /* Name the new ZIP file entry this */ + char *zDest, /* Name the new ZIP file entry this */ + ZFile **ppList) /* Put a ZFile struct for the new file here */ +{ + z_stream stream; + ZFile *p; + int iEndOfData; + int nameLen; + int skip; + int toOut; + char zHdr[30]; + char zInBuf[100000]; + char zOutBuf[100000]; + struct tm *tm; + time_t now; + struct stat stat; + + /* + * Create a new ZFile structure for this file. + * TODO: fill in date/time etc. + */ + nameLen = strlen(zDest); + p = newZFile(nameLen, ppList); + strcpy(p->zName, zDest); + p->isSpecial = 0; + Tcl_Stat(zSrc, &stat); + now=stat.st_mtime; + tm = localtime(&now); + UnixTimeDate(tm, &p->dosDate, &p->dosTime); + p->iOffset = Tcl_Tell(out); + p->nByte = 0; + p->nByteCompr = 0; + p->nExtra = 0; + p->iCRC = 0; + p->permissions = stat.st_mode; + + /* + * Fill in as much of the header as we know. + */ + + put32(&zHdr[0], 0x04034b50); + put16(&zHdr[4], 0x0014); + put16(&zHdr[6], 0); + put16(&zHdr[8], 8); + put16(&zHdr[10], p->dosTime); + put16(&zHdr[12], p->dosDate); + put16(&zHdr[26], nameLen); + put16(&zHdr[28], 0); + + /* + * Write the header and filename. + */ + + Tcl_Write(out, zHdr, 30); + Tcl_Write(out, zDest, nameLen); + + /* + * The first two bytes that come out of the deflate compressor are some + * kind of header that ZIP does not use. So skip the first two output + * bytes. + */ + + skip = 2; + + /* + * Write the compressed file. Compute the CRC as we progress. + */ + + stream.zalloc = (alloc_func)0; + stream.zfree = (free_func)0; + stream.opaque = 0; + stream.avail_in = 0; + stream.next_in = zInBuf; + stream.avail_out = sizeof(zOutBuf); + stream.next_out = zOutBuf; #if 1 - deflateInit(&stream, 9); + deflateInit(&stream, 9); #else - { - int i, err, WSIZE = 0x8000, windowBits, level=6; - for (i = ((unsigned)WSIZE), windowBits = 0; i != 1; i >>= 1, ++windowBits); - err = deflateInit2(&stream, level, Z_DEFLATED, -windowBits, 8, 0); + { + int i, err, WSIZE = 0x8000, windowBits, level=6; - } + for (i = ((unsigned)WSIZE), windowBits = 0; i != 1; i >>= 1, ++windowBits); + err = deflateInit2(&stream, level, Z_DEFLATED, -windowBits, 8, 0); + } #endif - p->iCRC = crc32(0, 0, 0); - while( !Tcl_Eof(in) ){ - if( stream.avail_in==0 ){ - int amt = Tcl_Read(in, zInBuf, sizeof(zInBuf)); - if( amt<=0 ) break; - p->iCRC = crc32(p->iCRC, zInBuf, amt); - stream.avail_in = amt; - stream.next_in = zInBuf; - } - deflate(&stream, 0); - toOut = sizeof(zOutBuf) - stream.avail_out; - if( toOut>skip ){ - Tcl_Write(out, &zOutBuf[skip], toOut - skip); - skip = 0; - }else{ - skip -= toOut; + + p->iCRC = crc32(0, 0, 0); + while( !Tcl_Eof(in) ){ + if( stream.avail_in==0 ){ + int amt = Tcl_Read(in, zInBuf, sizeof(zInBuf)); + + if( amt<=0 ) { + break; + } + p->iCRC = crc32(p->iCRC, zInBuf, amt); + stream.avail_in = amt; + stream.next_in = zInBuf; + } + deflate(&stream, 0); + toOut = sizeof(zOutBuf) - stream.avail_out; + if( toOut>skip ){ + Tcl_Write(out, &zOutBuf[skip], toOut - skip); + skip = 0; + }else{ + skip -= toOut; + } + stream.avail_out = sizeof(zOutBuf); + stream.next_out = zOutBuf; } - stream.avail_out = sizeof(zOutBuf); - stream.next_out = zOutBuf; - } - do{ - stream.avail_out = sizeof(zOutBuf); - stream.next_out = zOutBuf; - deflate(&stream, Z_FINISH); - toOut = sizeof(zOutBuf) - stream.avail_out; - if( toOut>skip ){ - Tcl_Write(out, &zOutBuf[skip], toOut - skip); - skip = 0; - }else{ - skip -= toOut; - } - }while( stream.avail_out==0 ); - p->nByte = stream.total_in; - p->nByteCompr = stream.total_out - 2; - deflateEnd(&stream); - Tcl_Flush(out); - - /* Remember were we are in the file. Then go back and write the - ** header, now that we know the compressed file size. - */ - iEndOfData = Tcl_Tell(out); - Tcl_Seek(out, p->iOffset, SEEK_SET); - put32(&zHdr[14], p->iCRC); - put32(&zHdr[18], p->nByteCompr); - put32(&zHdr[22], p->nByte); - Tcl_Write(out, zHdr, 30); - Tcl_Seek(out, iEndOfData, SEEK_SET); - - /* Close the input file. - */ - Tcl_Close(interp, in); - - /* Finished! - */ - return TCL_OK; + do{ + stream.avail_out = sizeof(zOutBuf); + stream.next_out = zOutBuf; + deflate(&stream, Z_FINISH); + toOut = sizeof(zOutBuf) - stream.avail_out; + if( toOut>skip ){ + Tcl_Write(out, &zOutBuf[skip], toOut - skip); + skip = 0; + }else{ + skip -= toOut; + } + }while( stream.avail_out==0 ); + p->nByte = stream.total_in; + p->nByteCompr = stream.total_out - 2; + deflateEnd(&stream); + Tcl_Flush(out); + + /* + * Remember were we are in the file. Then go back and write the header, + * now that we know the compressed file size. + */ + + iEndOfData = Tcl_Tell(out); + Tcl_Seek(out, p->iOffset, SEEK_SET); + put32(&zHdr[14], p->iCRC); + put32(&zHdr[18], p->nByteCompr); + put32(&zHdr[22], p->nByte); + Tcl_Write(out, zHdr, 30); + Tcl_Seek(out, iEndOfData, SEEK_SET); + + /* + * Close the input file. + */ + + Tcl_Close(interp, in); + return TCL_OK; } /* -** The arguments are two lists of ZFile structures sorted by iOffset. -** Either or both list may be empty. This routine merges the two -** lists together into a single sorted list and returns a pointer -** to the head of the unified list. -** -** This is part of the merge-sort algorithm. -*/ -static ZFile *mergeZFiles(ZFile *pLeft, ZFile *pRight){ - ZFile fakeHead; - ZFile *pTail; - - pTail = &fakeHead; - while( pLeft && pRight ){ - ZFile *p; - if( pLeft->iOffset <= pRight->iOffset ){ - p = pLeft; - pLeft = p->pNext; + * The arguments are two lists of ZFile structures sorted by iOffset. Either + * or both list may be empty. This routine merges the two lists together into + * a single sorted list and returns a pointer to the head of the unified list. + * + * This is part of the merge-sort algorithm. + */ +static ZFile * +mergeZFiles( + ZFile *pLeft, + ZFile *pRight) +{ + ZFile fakeHead; + ZFile *pTail; + + pTail = &fakeHead; + while( pLeft && pRight ){ + ZFile *p; + + if( pLeft->iOffset <= pRight->iOffset ){ + p = pLeft; + pLeft = p->pNext; + }else{ + p = pRight; + pRight = p->pNext; + } + pTail->pNext = p; + pTail = p; + } + if( pLeft ){ + pTail->pNext = pLeft; + }else if( pRight ){ + pTail->pNext = pRight; }else{ - p = pRight; - pRight = p->pNext; - } - pTail->pNext = p; - pTail = p; - } - if( pLeft ){ - pTail->pNext = pLeft; - }else if( pRight ){ - pTail->pNext = pRight; - }else{ - pTail->pNext = 0; - } - return fakeHead.pNext; + pTail->pNext = 0; + } + return fakeHead.pNext; } /* -** Sort a ZFile list so in accending order by iOffset. -*/ -static ZFile *sortZFiles(ZFile *pList){ -# define NBIN 30 - int i; - ZFile *p; - ZFile *aBin[NBIN+1]; - - for(i=0; i<=NBIN; i++) aBin[i] = 0; - while( pList ){ - p = pList; - pList = p->pNext; - p->pNext = 0; - for(i=0; ipNext; + p->pNext = 0; + for(i=0; ipNext){ - if( pList->isSpecial ) continue; - put32(&zBuf[0], 0x02014b50); - put16(&zBuf[4], 0x0317); - put16(&zBuf[6], 0x0014); - put16(&zBuf[8], 0); - put16(&zBuf[10], pList->nByte>pList->nByteCompr ? 0x0008 : 0x0000); - put16(&zBuf[12], pList->dosTime); - put16(&zBuf[14], pList->dosDate); - put32(&zBuf[16], pList->iCRC); - put32(&zBuf[20], pList->nByteCompr); - put32(&zBuf[24], pList->nByte); - put16(&zBuf[28], strlen(pList->zName)); - put16(&zBuf[30], 0); - put16(&zBuf[32], pList->nExtra); - put16(&zBuf[34], 1); - put16(&zBuf[36], 0); - put32(&zBuf[38], pList->permissions<<16); - put32(&zBuf[42], pList->iOffset); - Tcl_Write(chan, zBuf, 46); - Tcl_Write(chan, pList->zName, strlen(pList->zName)); - for(i=pList->nExtra; i>0; i-=40){ - int toWrite = i<40 ? i : 40; - Tcl_Write(chan," ",toWrite); - } - nEntry++; - } - iTocEnd = Tcl_Tell(chan); - put32(&zBuf[0], 0x06054b50); - put16(&zBuf[4], 0); - put16(&zBuf[6], 0); - put16(&zBuf[8], nEntry); - put16(&zBuf[10], nEntry); - put32(&zBuf[12], iTocEnd - iTocStart); - put32(&zBuf[16], iTocStart); - put16(&zBuf[20], 0); - Tcl_Write(chan, zBuf, 22); - Tcl_Flush(chan); + * Write a ZIP archive table of contents to the given channel. + */ +static void +writeTOC( + Tcl_Channel chan, + ZFile *pList) +{ + int iTocStart, iTocEnd; + int nEntry = 0; + int i; + char zBuf[100]; + + iTocStart = Tcl_Tell(chan); + for(; pList; pList=pList->pNext){ + if( pList->isSpecial ) { + continue; + } + put32(&zBuf[0], 0x02014b50); + put16(&zBuf[4], 0x0317); + put16(&zBuf[6], 0x0014); + put16(&zBuf[8], 0); + put16(&zBuf[10], pList->nByte>pList->nByteCompr ? 0x0008 : 0x0000); + put16(&zBuf[12], pList->dosTime); + put16(&zBuf[14], pList->dosDate); + put32(&zBuf[16], pList->iCRC); + put32(&zBuf[20], pList->nByteCompr); + put32(&zBuf[24], pList->nByte); + put16(&zBuf[28], strlen(pList->zName)); + put16(&zBuf[30], 0); + put16(&zBuf[32], pList->nExtra); + put16(&zBuf[34], 1); + put16(&zBuf[36], 0); + put32(&zBuf[38], pList->permissions<<16); + put32(&zBuf[42], pList->iOffset); + Tcl_Write(chan, zBuf, 46); + Tcl_Write(chan, pList->zName, strlen(pList->zName)); + for(i=pList->nExtra; i>0; i-=40){ + int toWrite = i<40 ? i : 40; + + /* CAREFUL! String below is intentionally 40 spaces! */ + Tcl_Write(chan," ", + toWrite); + } + nEntry++; + } + iTocEnd = Tcl_Tell(chan); + put32(&zBuf[0], 0x06054b50); + put16(&zBuf[4], 0); + put16(&zBuf[6], 0); + put16(&zBuf[8], nEntry); + put16(&zBuf[10], nEntry); + put32(&zBuf[12], iTocEnd - iTocStart); + put32(&zBuf[16], iTocStart); + put16(&zBuf[20], 0); + Tcl_Write(chan, zBuf, 22); + Tcl_Flush(chan); } - /* -** Implementation of the zvfs::append command. -** -** zvfs::append ARCHIVE (SOURCE DESTINATION)* -** -** This command reads SOURCE files and appends them (using the name -** DESTINATION) to the zip archive named ARCHIVE. A new zip archive -** is created if it does not already exist. If ARCHIVE refers to a -** file which exists but is not a zip archive, then this command -** turns ARCHIVE into a zip archive by appending the necessary -** records and the table of contents. Treat all files as binary. -** -** Note: No dup checking is done, so multiple occurances of the -** same file is allowed. -*/ -static int ZvfsAppendObjCmd( - void *NotUsed, /* Client data for this command */ - Tcl_Interp *interp, /* The interpreter used to report errors */ - int objc, /* Number of arguments */ - Tcl_Obj *const* objv /* Values of all arguments */ -){ - char *zArchive; - Tcl_Channel chan; - ZFile *pList = NULL, *pToc; - int rc = TCL_OK, i; - - /* Open the archive and read the table of contents - */ - if( objc<2 || (objc&1)!=0 ){ - Tcl_WrongNumArgs(interp, 1, objv, "ARCHIVE (SRC DEST)+"); - return TCL_ERROR; - } - - zArchive = Tcl_GetString(objv[1]); - chan = Tcl_OpenFileChannel(interp, zArchive, "r+", 0644); - if( chan==0 ) { - chan = Tcl_OpenFileChannel(interp, zArchive, "w+", 0644); - } - if( chan==0 ) return TCL_ERROR; - if( Tcl_SetChannelOption(interp, chan, "-translation", "binary") - || Tcl_SetChannelOption(interp, chan, "-encoding", "binary") - ){ - /* this should never happen */ - Tcl_Close(0, chan); - return TCL_ERROR; - } - - if (Tcl_Seek(chan, 0, SEEK_END) == 0) { - /* Null file is ok, we're creating new one. */ - } else { - Tcl_Seek(chan, 0, SEEK_SET); - rc = ZvfsReadTOC(interp, chan, &pList); - if( rc==TCL_ERROR ){ - deleteZFileList(pList); - Tcl_Close(interp, chan); - return rc; - } else rc=TCL_OK; - } - - /* Move the file pointer to the start of - ** the table of contents. - */ - for(pToc=pList; pToc; pToc=pToc->pNext){ - if( pToc->isSpecial && strcmp(pToc->zName,"*TOC*")==0 ) break; - } - if( pToc ){ - Tcl_Seek(chan, pToc->iOffset, SEEK_SET); - }else{ - Tcl_Seek(chan, 0, SEEK_END); - } - - /* Add new files to the end of the archive. - */ - for(i=2; rc==TCL_OK && ipNext){ + if( pToc->isSpecial && strcmp(pToc->zName,"*TOC*")==0 ) { + break; + } + } + if( pToc ){ + Tcl_Seek(chan, pToc->iOffset, SEEK_SET); + }else{ + Tcl_Seek(chan, 0, SEEK_END); + } + + /* + * Add new files to the end of the archive. + */ + + for(i=2; rc==TCL_OK && i p)) { p = NULL; @@ -2209,175 +2466,192 @@ GetExtension( CONST char *name) } /* -** Implementation of the zvfs::add command. -** -** zvfs::add ?-fconfigure optpairs? ARCHIVE FILE1 FILE2 ... -** -** This command is similar to append in that it adds files to the zip -** archive named ARCHIVE, however file names are relative the current directory. -** In addition, fconfigure is used to apply option pairs to set upon opening -** of each file. Otherwise, default translation is allowed -** for those file extensions listed in the ::zvfs::auto_ext var. -** Binary translation will be used for unknown extensions. -** -** NOTE Use '-fconfigure {}' to use auto translation for all. -*/ -static int ZvfsAddObjCmd( - void *NotUsed, /* Client data for this command */ - Tcl_Interp *interp, /* The interpreter used to report errors */ - int objc, /* Number of arguments */ - Tcl_Obj *CONST* objv /* Values of all arguments */ -){ - char *zArchive; - Tcl_Channel chan; - ZFile *pList = NULL, *pToc; - int rc = TCL_OK, i, j, oLen; - char *zOpts = NULL; - Tcl_Obj *confOpts = NULL; - int tobjc; - Tcl_Obj **tobjv; - Tcl_Obj *varObj = NULL; - - /* Open the archive and read the table of contents - */ - if (objc>3) { - zOpts = Tcl_GetStringFromObj(objv[1], &oLen); - if (!strncmp("-fconfigure", zOpts, oLen)) { - confOpts = objv[2]; - if (TCL_OK != Tcl_ListObjGetElements(interp, confOpts, &tobjc, &tobjv) || (tobjc%2)) { - return TCL_ERROR; - } - objc -= 2; - objv += 2; - } - } - if( objc==2) { - return TCL_OK; - } - - if( objc<3) { - Tcl_WrongNumArgs(interp, 1, objv, "?-fconfigure OPTPAIRS? ARCHIVE FILE1 FILE2 .."); - return TCL_ERROR; - } - zArchive = Tcl_GetString(objv[1]); - chan = Tcl_OpenFileChannel(interp, zArchive, "r+", 0644); - if( chan==0 ) { - chan = Tcl_OpenFileChannel(interp, zArchive, "w+", 0644); - } - if( chan==0 ) return TCL_ERROR; - if( Tcl_SetChannelOption(interp, chan, "-translation", "binary") - || Tcl_SetChannelOption(interp, chan, "-encoding", "binary") - ){ - /* this should never happen */ - Tcl_Close(0, chan); - return TCL_ERROR; - } - - if (Tcl_Seek(chan, 0, SEEK_END) == 0) { - /* Null file is ok, we're creating new one. */ - } else { - Tcl_Seek(chan, 0, SEEK_SET); - rc = ZvfsReadTOC(interp, chan, &pList); - if( rc==TCL_ERROR ){ - deleteZFileList(pList); - Tcl_Close(interp, chan); - return rc; - } else rc=TCL_OK; - } - - /* Move the file pointer to the start of - ** the table of contents. - */ - for(pToc=pList; pToc; pToc=pToc->pNext){ - if( pToc->isSpecial && strcmp(pToc->zName,"*TOC*")==0 ) break; - } - if( pToc ){ - Tcl_Seek(chan, pToc->iOffset, SEEK_SET); - }else{ - Tcl_Seek(chan, 0, SEEK_END); - } - - /* Add new files to the end of the archive. - */ - for(i=2; rc==TCL_OK && i=tobjc) { - ext = NULL; - } + if (objc>3) { + zOpts = Tcl_GetStringFromObj(objv[1], &oLen); + if (!strncmp("-fconfigure", zOpts, oLen)) { + confOpts = objv[2]; + if (TCL_OK != Tcl_ListObjGetElements(interp, confOpts, + &tobjc, &tobjv) || (tobjc%2)) { + return TCL_ERROR; } + objc -= 2; + objv += 2; } - if (ext == NULL) { - if (( Tcl_SetChannelOption(interp, in, "-translation", "binary") - || Tcl_SetChannelOption(interp, in, "-encoding", "binary")) - ) { - /* this should never happen */ - Tcl_Close(0, in); - rc = TCL_ERROR; + } + if( objc==2) { + return TCL_OK; + } + + if( objc<3) { + Tcl_WrongNumArgs(interp, 1, objv, + "?-fconfigure OPTPAIRS? ARCHIVE FILE1 FILE2 .."); + return TCL_ERROR; + } + zArchive = Tcl_GetString(objv[1]); + chan = Tcl_OpenFileChannel(interp, zArchive, "r+", 0644); + if( chan==0 ) { + chan = Tcl_OpenFileChannel(interp, zArchive, "w+", 0644); + } + if( chan==0 ) return TCL_ERROR; + if (Tcl_SetChannelOption(interp, chan, "-translation", "binary") + || Tcl_SetChannelOption(interp, chan, "-encoding", "binary")){ + /* this should never happen */ + Tcl_Close(0, chan); + return TCL_ERROR; + } + + if (Tcl_Seek(chan, 0, SEEK_END) == 0) { + /* Null file is ok, we're creating new one. */ + } else { + Tcl_Seek(chan, 0, SEEK_SET); + rc = ZvfsReadTOC(interp, chan, &pList); + if( rc==TCL_ERROR ){ + deleteZFileList(pList); + Tcl_Close(interp, chan); + return rc; + } + rc=TCL_OK; + } + + /* + * Move the file pointer to the start of the table of contents. + */ + + for(pToc=pList; pToc; pToc=pToc->pNext){ + if( pToc->isSpecial && strcmp(pToc->zName, "*TOC*")==0 ) { break; - } } - } else { - for (j=0; jiOffset, SEEK_SET); + }else{ + Tcl_Seek(chan, 0, SEEK_END); + } + + /* + * Add new files to the end of the archive. + */ + + for(i=2; rc==TCL_OK && i=tobjc) { + ext = NULL; + } + } + } + if (ext == NULL) { + if (Tcl_SetChannelOption(interp, in, "-translation", "binary") + || Tcl_SetChannelOption(interp, in, "-encoding", + "binary")) { + /* this should never happen */ + Tcl_Close(0, in); + rc = TCL_ERROR; + break; + } + } + } else { + for (j=0; j Date: Mon, 1 Sep 2014 13:51:59 +0000 Subject: Squelch most warnings. --- generic/tclZipVfs.c | 555 ++++++++++++++++++++++++++-------------------------- 1 file changed, 277 insertions(+), 278 deletions(-) diff --git a/generic/tclZipVfs.c b/generic/tclZipVfs.c index a774648..8b1fc3b 100755 --- a/generic/tclZipVfs.c +++ b/generic/tclZipVfs.c @@ -21,6 +21,7 @@ * This version has been modified to run under Tcl 8.6 */ #include "tcl.h" +#include #include #include #include @@ -36,8 +37,8 @@ * Size of the decompression input buffer */ #define COMPR_BUF_SIZE 8192 -static int maptolower=0; -static int openarch=0; /* Set to 1 when opening archive. */ +/*TODO: use thread-local as appropriate*/ +static int openarch = 0; /* Set to 1 when opening archive. */ /* * All static variables are collected into a structure named "local". That @@ -150,7 +151,7 @@ newZFile( int nName, ZFile **ppList) { - ZFile *pNew = Tcl_Alloc( sizeof(*pNew) + nName + 1 ); + ZFile *pNew = (void *) Tcl_Alloc(sizeof(*pNew) + nName + 1); memset(pNew, 0, sizeof(*pNew)); pNew->zName = (char*)&pNew[1]; @@ -263,51 +264,50 @@ CanonicalPath( int i, j, c; #ifdef __WIN32__ - if( isalpha(zTail[0]) && zTail[1]==':' ){ + if (isalpha(zTail[0]) && zTail[1] == ':') { zTail += 2; } - if( zTail[0]=='\\' ){ + if (zTail[0] == '\\') { zRoot = ""; zTail++; } #endif - if( zTail[0]=='/' ){ + if (zTail[0] == '/') { zRoot = ""; zTail++; } - zPath = Tcl_Alloc( strlen(zRoot) + strlen(zTail) + 2 ); - if( zPath==0 ) { - return 0; - } + zPath = Tcl_Alloc(strlen(zRoot) + strlen(zTail) + 2); if (zTail[0]) { sprintf(zPath, "%s/%s", zRoot, zTail); } else { strcpy(zPath, zRoot); } - for(i=j=0; (c = zPath[i])!=0; i++){ + for (i=j=0 ; (c = zPath[i]) != 0 ; i++) { #ifdef __WIN32__ - if( isupper(c) ) { + if (isupper(c)) { if (maptolower) { c = tolower(c); } - } else if( c=='\\' ) { + } else if (c == '\\') { c = '/'; } #endif - if( c=='/' ){ + if (c == '/') { int c2 = zPath[i+1]; - if( c2=='/' ) { + + if (c2 == '/') { continue; } - if( c2=='.' ){ + if (c2 == '.') { int c3 = zPath[i+2]; - if( c3=='/' || c3==0 ){ + + if (c3 == '/' || c3 == 0) { i++; continue; } - if( c3=='.' && (zPath[i+3]=='.' || zPath[i+3]==0) ){ + if (c3 == '.' && (zPath[i+3] == '.' || zPath[i+3] == 0)) { i += 2; - while( j>0 && zPath[j-1]!='/' ){ + while (j > 0 && zPath[j-1] != '/') { j--; } continue; @@ -316,7 +316,7 @@ CanonicalPath( } zPath[j++] = c; } - if( j==0 ){ + if (j == 0) { zPath[j++] = '/'; } /* if (j>1 && zPath[j-1] == '/') j--; */ @@ -340,19 +340,19 @@ AbsolutePath( if (zRelative[0] == '~' && zRelative[1] == '/') { /* TODO: do this for all paths??? */ if (Tcl_TranslateFileName(0, zRelative, &pwd) != NULL) { - zResult = CanonicalPath( "", Tcl_DStringValue(&pwd)); + zResult = CanonicalPath("", Tcl_DStringValue(&pwd)); goto done; } - } else if( zRelative[0] != '/'){ + } else if (zRelative[0] != '/') { #ifdef __WIN32__ - if(!(zRelative[0]=='\\' || (zRelative[0] && zRelative[1] == ':'))) { + if (!(zRelative[0]=='\\' || (zRelative[0] && zRelative[1] == ':'))) { /*Tcl_GetCwd(0, &pwd); */ } #else Tcl_GetCwd(0, &pwd); #endif } - zResult = CanonicalPath( Tcl_DStringValue(&pwd), zRelative); + zResult = CanonicalPath(Tcl_DStringValue(&pwd), zRelative); done: Tcl_DStringFree(&pwd); len = strlen(zResult); @@ -369,16 +369,10 @@ ZvfsReadTOCStart( ZFile **pList, int *iStart) { - char *zArchiveName = 0; /* A copy of zArchive */ int nFile; /* Number of files in the archive */ int iPos; /* Current position in the archive file */ - ZvfsArchive *pArchive; /* The ZIP archive being mounted */ - Tcl_HashEntry *pEntry; /* Hash table entry */ - int isNew; /* Flag to tell use when a hash entry is - * new */ unsigned char zBuf[100]; /* Space into which to read from the ZIP * archive */ - Tcl_HashSearch zSearch; /* Search all mount points */ ZFile *p; int zipStart; @@ -399,7 +393,7 @@ ZvfsReadTOCStart( */ iPos = Tcl_Seek(chan, -22, SEEK_END); - Tcl_Read(chan, zBuf, 22); + Tcl_Read(chan, (char *) zBuf, 22); if (memcmp(zBuf, "\120\113\05\06", 4)) { /* Tcl_AppendResult(interp, "not a ZIP archive", NULL); */ return TCL_BREAK; @@ -415,18 +409,12 @@ ZvfsReadTOCStart( iPos -= INT32(zBuf,12); Tcl_Seek(chan, iPos, SEEK_SET); - while(1) { + while (1) { int lenName; /* Length of the next filename */ int lenExtra; /* Length of "extra" data for next file */ int iData; /* Offset to start of file data */ - int dosTime; - int dosDate; - int isdir; - ZvfsFile *pZvfs; /* A new virtual file */ - char *zFullPath; /* Full pathname of the virtual file */ - char zName[1024]; /* Space to hold the filename */ - if (nFile-- <= 0 ){ + if (nFile-- <= 0) { break; } @@ -436,7 +424,7 @@ ZvfsReadTOCStart( * archive file of the file data. */ - Tcl_Read(chan, zBuf, 46); + Tcl_Read(chan, (char *) zBuf, 46); if (memcmp(zBuf, "\120\113\01\02", 4)) { Tcl_AppendResult(interp, "ill-formed central directory entry", NULL); @@ -445,7 +433,7 @@ ZvfsReadTOCStart( lenName = INT16(zBuf,28); lenExtra = INT16(zBuf,30) + INT16(zBuf,32); iData = INT32(zBuf,42); - if (iDatazName, lenName); p->zName[lenName] = 0; - if (lenName>0 && p->zName[lenName-1] == '/') { + if (lenName > 0 && p->zName[lenName-1] == '/') { p->isSpecial = 1; } p->dosDate = INT16(zBuf, 14); @@ -489,7 +477,7 @@ ZvfsReadTOC( { int iStart; - return ZvfsReadTOCStart( interp, chan, pList, &iStart); + return ZvfsReadTOCStart(interp, chan, pList, &iStart); } /* @@ -517,7 +505,7 @@ Tcl_Zvfs_Mount( Tcl_HashSearch zSearch; /* Search all mount points */ unsigned int startZip; - if( !local.isInit ) { + if (!local.isInit) { return TCL_ERROR; } @@ -529,13 +517,14 @@ Tcl_Zvfs_Mount( Tcl_DString dStr; Tcl_DStringInit(&dStr); - pEntry=Tcl_FirstHashEntry(&local.archiveHash,&zSearch); + pEntry = Tcl_FirstHashEntry(&local.archiveHash,&zSearch); while (pEntry) { - if (pArchive = Tcl_GetHashValue(pEntry)) { + pArchive = Tcl_GetHashValue(pEntry); + if (pArchive) { Tcl_DStringAppendElement(&dStr, pArchive->zName); Tcl_DStringAppendElement(&dStr, pArchive->zMountPoint); } - pEntry=Tcl_NextHashEntry(&zSearch); + pEntry = Tcl_NextHashEntry(&zSearch); } Tcl_DStringResult(interp, &dStr); return TCL_OK; @@ -547,10 +536,11 @@ Tcl_Zvfs_Mount( /*TODO: cleanup allocations of Absolute() path.*/ if (!zMountPoint) { - zTrueName=AbsolutePath(zArchive); - pEntry = Tcl_FindHashEntry(&local.archiveHash,zTrueName); + zTrueName = AbsolutePath(zArchive); + pEntry = Tcl_FindHashEntry(&local.archiveHash, zTrueName); if (pEntry) { - if (pArchive = Tcl_GetHashValue(pEntry)) { + pArchive = Tcl_GetHashValue(pEntry); + if (pArchive) { Tcl_AppendResult(interp, pArchive->zMountPoint, 0); } } @@ -574,7 +564,7 @@ Tcl_Zvfs_Mount( */ iPos = Tcl_Seek(chan, -22, SEEK_END); - Tcl_Read(chan, zBuf, 22); + Tcl_Read(chan, (char *) zBuf, 22); if (memcmp(zBuf, "\120\113\05\06", 4)) { Tcl_AppendResult(interp, "not a ZIP archive", NULL); return TCL_ERROR; @@ -586,7 +576,7 @@ Tcl_Zvfs_Mount( zArchiveName = AbsolutePath(zArchive); pEntry = Tcl_CreateHashEntry(&local.archiveHash, zArchiveName, &isNew); - if( !isNew ){ + if (!isNew) { pArchive = Tcl_GetHashValue(pEntry); Tcl_AppendResult(interp, "already mounted at ", pArchive->zMountPoint, 0); @@ -603,9 +593,9 @@ Tcl_Zvfs_Mount( zMountPoint = zTrueName = AbsolutePath(zArchive); } - pArchive = Tcl_Alloc(sizeof(*pArchive) + strlen(zMountPoint)+1); + pArchive = (void *) Tcl_Alloc(sizeof(*pArchive) + strlen(zMountPoint)+1); pArchive->zName = zArchiveName; - pArchive->zMountPoint = (char*)&pArchive[1]; + pArchive->zMountPoint = (char *) &pArchive[1]; strcpy(pArchive->zMountPoint, zMountPoint); pArchive->pFiles = 0; Tcl_SetHashValue(pEntry, pArchive); @@ -615,12 +605,12 @@ Tcl_Zvfs_Mount( * iPos then seek to that location. */ - nFile = INT16(zBuf,8); - iPos -= INT32(zBuf,12); + nFile = INT16(zBuf, 8); + iPos -= INT32(zBuf, 12); Tcl_Seek(chan, iPos, SEEK_SET); startZip = iPos; - while(1) { + while (1) { int lenName; /* Length of the next filename */ int lenExtra; /* Length of "extra" data for next file */ int iData; /* Offset to start of file data */ @@ -631,7 +621,7 @@ Tcl_Zvfs_Mount( char *zFullPath; /* Full pathname of the virtual file */ char zName[1024]; /* Space to hold the filename */ - if (nFile-- <= 0 ){ + if (nFile-- <= 0) { isdir = 1; zFullPath = CanonicalPath(zMountPoint, ""); iData = startZip; @@ -644,7 +634,7 @@ Tcl_Zvfs_Mount( * archive file of the file data. */ - Tcl_Read(chan, zBuf, 46); + Tcl_Read(chan, (char *) zBuf, 46); if (memcmp(zBuf, "\120\113\01\02", 4)) { Tcl_AppendResult(interp, "ill-formed central directory entry", NULL); @@ -653,16 +643,16 @@ Tcl_Zvfs_Mount( } return TCL_ERROR; } - lenName = INT16(zBuf,28); - lenExtra = INT16(zBuf,30) + INT16(zBuf,32); - iData = INT32(zBuf,42); + lenName = INT16(zBuf, 28); + lenExtra = INT16(zBuf, 30) + INT16(zBuf, 32); + iData = INT32(zBuf, 42); /* * If the virtual filename is too big to fit in zName[], then skip * this file */ - if( lenName >= sizeof(zName) ){ + if (lenName >= sizeof(zName)) { Tcl_Seek(chan, lenName + lenExtra, SEEK_CUR); continue; } @@ -672,21 +662,21 @@ Tcl_Zvfs_Mount( */ Tcl_Read(chan, zName, lenName); - isdir=0; - if (lenName>0 && zName[lenName-1] == '/') { + isdir = 0; + if (lenName > 0 && zName[lenName-1] == '/') { lenName--; - isdir=2; + isdir = 2; } zName[lenName] = 0; zFullPath = CanonicalPath(zMountPoint, zName); addentry: - pZvfs = (ZvfsFile*)Tcl_Alloc( sizeof(*pZvfs) ); + pZvfs = (void *) Tcl_Alloc(sizeof(*pZvfs)); pZvfs->zName = zFullPath; pZvfs->pArchive = pArchive; pZvfs->isdir = isdir; - pZvfs->depth=strchrcnt(zFullPath,'/'); + pZvfs->depth = strchrcnt(zFullPath, '/'); pZvfs->iOffset = iData; - if (iDatanByte = INT32(zBuf, 24); pZvfs->nByteCompr = INT32(zBuf, 20); pZvfs->pNext = pArchive->pFiles; - pZvfs->permissions = (0xffff&(INT32(zBuf, 38) >> 16)); + pZvfs->permissions = 0xffff & (INT32(zBuf, 38) >> 16); pArchive->pFiles = pZvfs; pEntry = Tcl_CreateHashEntry(&local.fileHash, zFullPath, &isNew); - if( isNew ){ + if (isNew) { pZvfs->pNextName = 0; } else { ZvfsFile *pOld = Tcl_GetHashValue(pEntry); @@ -721,7 +711,7 @@ Tcl_Zvfs_Mount( Tcl_Seek(chan, lenExtra, SEEK_CUR); } Tcl_Close(interp, chan); - done: + if (zTrueName) { Tcl_Free(zTrueName); } @@ -740,7 +730,7 @@ ZvfsLookup( Tcl_HashEntry *pEntry; ZvfsFile *pFile; - if( local.isInit==0 ) { + if (local.isInit == 0) { return 0; } zTrueName = AbsolutePath(zFilename); @@ -760,19 +750,20 @@ ZvfsLookupMount( ZvfsArchive *pArchive; /* The ZIP archive being mounted */ int match=0; - if( local.isInit==0 ) { + if (local.isInit == 0) { return 0; } zTrueName = AbsolutePath(zFilename); - pEntry=Tcl_FirstHashEntry(&local.archiveHash,&zSearch); + pEntry = Tcl_FirstHashEntry(&local.archiveHash, &zSearch); while (pEntry) { - if (pArchive = Tcl_GetHashValue(pEntry)) { - if (!strcmp(pArchive->zMountPoint,zTrueName)) { - match=1; + pArchive = Tcl_GetHashValue(pEntry); + if (pArchive) { + if (!strcmp(pArchive->zMountPoint, zTrueName)) { + match = 1; break; } } - pEntry=Tcl_NextHashEntry(&zSearch); + pEntry = Tcl_NextHashEntry(&zSearch); } Tcl_Free(zTrueName); return match; @@ -793,31 +784,31 @@ Tcl_Zvfs_Umount( zArchiveName = AbsolutePath(zArchive); pEntry = Tcl_FindHashEntry(&local.archiveHash, zArchiveName); Tcl_Free(zArchiveName); - if( pEntry==0 ) { + if (pEntry == 0) { return 0; } pArchive = Tcl_GetHashValue(pEntry); Tcl_DeleteHashEntry(pEntry); Tcl_Free(pArchive->zName); - for(pFile=pArchive->pFiles; pFile; pFile=pNextFile){ + for(pFile=pArchive->pFiles ; pFile; pFile=pNextFile) { pNextFile = pFile->pNext; - if( pFile->pNextName ){ + if (pFile->pNextName) { pFile->pNextName->pPrevName = pFile->pPrevName; } - if( pFile->pPrevName ){ + if (pFile->pPrevName) { pFile->pPrevName->pNextName = pFile->pNextName; - }else{ + } else { pEntry = Tcl_FindHashEntry(&local.fileHash, pFile->zName); - if( pEntry==0 ){ + if (pEntry == 0) { Tcl_Panic("This should never happen"); - }else if( pFile->pNextName ){ + } else if (pFile->pNextName) { Tcl_SetHashValue(pEntry, pFile->pNextName); - }else{ + } else { Tcl_DeleteHashEntry(pEntry); } } Tcl_Free(pFile->zName); - Tcl_Free((char*)pFile); + Tcl_Free((void *) pFile); } return 1; } @@ -848,12 +839,12 @@ ZvfsMountCmd( const char *argv[]) /* Values of all arguments */ { /*TODO: Convert to Tcl_Obj API!*/ - if( argc>3 ){ + if (argc > 3) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " ? ZIP-FILE ? MOUNT-POINT ? ?\"", 0); return TCL_ERROR; } - return Tcl_Zvfs_Mount(interp, argc>1?argv[1]:0, argc>2?argv[2]:0); + return Tcl_Zvfs_Mount(interp, argc>1?argv[1]:NULL, argc>2?argv[2]:NULL); } /* @@ -872,7 +863,7 @@ ZvfsUnmountCmd( Tcl_HashEntry *pEntry; /* Hash table entry */ Tcl_HashSearch zSearch; /* Search all mount points */ - if( argc!=2 ){ + if (argc != 2) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " ZIP-FILE\"", 0); return TCL_ERROR; @@ -881,23 +872,24 @@ ZvfsUnmountCmd( return TCL_OK; } - if( !local.isInit ) { + if (!local.isInit) { return TCL_ERROR; } - pEntry=Tcl_FirstHashEntry(&local.archiveHash,&zSearch); + pEntry = Tcl_FirstHashEntry(&local.archiveHash,&zSearch); while (pEntry) { - if (((pArchive = Tcl_GetHashValue(pEntry))) - && pArchive->zMountPoint[0] + pArchive = Tcl_GetHashValue(pEntry); + if (pArchive && pArchive->zMountPoint[0] && (strcmp(pArchive->zMountPoint, argv[1]) == 0)) { if (Tcl_Zvfs_Umount(pArchive->zName)) { return TCL_OK; } break; } - pEntry=Tcl_NextHashEntry(&zSearch); + pEntry = Tcl_NextHashEntry(&zSearch); } - Tcl_AppendResult(interp, "unknown zvfs mount point or file: ", argv[1], 0); + Tcl_AppendResult(interp, "unknown zvfs mount point or file: ", argv[1], + NULL); return TCL_ERROR; } @@ -916,12 +908,12 @@ ZvfsExistsObjCmd( { char *zFilename; - if( objc!=2 ){ + if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "FILENAME"); return TCL_ERROR; } zFilename = Tcl_GetString(objv[1]); - Tcl_SetBooleanObj( Tcl_GetObjResult(interp), ZvfsLookup(zFilename)!=0); + Tcl_SetBooleanObj(Tcl_GetObjResult(interp), ZvfsLookup(zFilename)!=0); return TCL_OK; } @@ -946,13 +938,13 @@ ZvfsInfoObjCmd( char *zFilename; ZvfsFile *pFile; - if( objc!=2 ){ + if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "FILENAME"); return TCL_ERROR; } zFilename = Tcl_GetString(objv[1]); pFile = ZvfsLookup(zFilename); - if( pFile ){ + if (pFile) { Tcl_Obj *pResult = Tcl_GetObjResult(interp); Tcl_ListObjAppendElement(interp, pResult, @@ -986,55 +978,60 @@ ZvfsListObjCmd( Tcl_HashSearch sSearch; Tcl_Obj *pResult = Tcl_GetObjResult(interp); - if( objc>3 ){ + if (objc > 3) { Tcl_WrongNumArgs(interp, 1, objv, "?(-glob|-regexp)? ?PATTERN?"); return TCL_ERROR; } - if( local.isInit==0 ) { + if (local.isInit == 0) { return TCL_OK; } - if( objc==3 ){ + if (objc == 3) { int n; char *zSwitch = Tcl_GetStringFromObj(objv[1], &n); - if( n>=2 && strncmp(zSwitch,"-glob",n)==0 ){ + if (n >= 2 && strncmp(zSwitch,"-glob",n) == 0) { zPattern = Tcl_GetString(objv[2]); - }else if( n>=2 && strncmp(zSwitch,"-regexp",n)==0 ){ + } else if (n >= 2 && strncmp(zSwitch,"-regexp",n) == 0) { pRegexp = Tcl_RegExpCompile(interp, Tcl_GetString(objv[2])); - if( pRegexp==0 ) { + if (pRegexp == 0) { return TCL_ERROR; } - }else{ + } else { Tcl_AppendResult(interp, "unknown option: ", zSwitch, 0); return TCL_ERROR; } - } else if( objc==2 ){ + } else if (objc == 2) { zPattern = Tcl_GetString(objv[1]); } - if( zPattern ){ - for(pEntry = Tcl_FirstHashEntry(&local.fileHash, &sSearch); + + /* + * Do the listing. + */ + + if (zPattern) { + for (pEntry = Tcl_FirstHashEntry(&local.fileHash, &sSearch); pEntry; pEntry = Tcl_NextHashEntry(&sSearch)){ ZvfsFile *pFile = Tcl_GetHashValue(pEntry); char *z = pFile->zName; - if( Tcl_StringCaseMatch(z, zPattern,1) ){ + if (Tcl_StringCaseMatch(z, zPattern, 1)) { Tcl_ListObjAppendElement(interp, pResult, Tcl_NewStringObj(z, -1)); } } - }else if( pRegexp ){ + } else if (pRegexp) { for(pEntry = Tcl_FirstHashEntry(&local.fileHash, &sSearch); pEntry; pEntry = Tcl_NextHashEntry(&sSearch)){ ZvfsFile *pFile = Tcl_GetHashValue(pEntry); char *z = pFile->zName; - if( Tcl_RegExpExec(interp, pRegexp, z, z) ){ + if (Tcl_RegExpExec(interp, pRegexp, z, z)) { Tcl_ListObjAppendElement(interp, pResult, Tcl_NewStringObj(z, -1)); } } - }else{ - for(pEntry = Tcl_FirstHashEntry(&local.fileHash, &sSearch); + } else { + for (pEntry = Tcl_FirstHashEntry(&local.fileHash, &sSearch); pEntry; pEntry = Tcl_NextHashEntry(&sSearch)){ ZvfsFile *pFile = Tcl_GetHashValue(pEntry); char *z = pFile->zName; @@ -1091,15 +1088,15 @@ vfsClose( { ZvfsChannelInfo* pInfo = instanceData; - if( pInfo->zBuf ){ - Tcl_Free(pInfo->zBuf); + if (pInfo->zBuf) { + Tcl_Free((void *) pInfo->zBuf); inflateEnd(&pInfo->stream); } - if( pInfo->chan ){ + if (pInfo->chan) { Tcl_Close(interp, pInfo->chan); Tcl_DeleteExitHandler(vfsExit, pInfo); } - Tcl_Free((char*)pInfo); + Tcl_Free((void *) pInfo); return TCL_OK; } @@ -1116,17 +1113,17 @@ vfsInput( { ZvfsChannelInfo* pInfo = instanceData; - if( toRead > pInfo->nByte ){ + if (toRead > pInfo->nByte) { toRead = pInfo->nByte; } - if( toRead == 0 ){ + if (toRead == 0) { return 0; } - if( pInfo->isCompressed ){ + if (pInfo->isCompressed) { int err = Z_OK; z_stream *stream = &pInfo->stream; - stream->next_out = buf; + stream->next_out = (unsigned char *) buf; stream->avail_out = toRead; while (stream->avail_out) { if (!stream->avail_in) { @@ -1135,7 +1132,7 @@ vfsInput( if (len > COMPR_BUF_SIZE) { len = COMPR_BUF_SIZE; } - len = Tcl_Read(pInfo->chan, pInfo->zBuf, len); + len = Tcl_Read(pInfo->chan, (char *) pInfo->zBuf, len); pInfo->nByteCompr -= len; stream->next_in = pInfo->zBuf; stream->avail_in = len; @@ -1146,15 +1143,15 @@ vfsInput( } } if (err == Z_STREAM_END) { - if ((stream->avail_out != 0)) { + if (stream->avail_out != 0) { *pErrorCode = err; /* premature end */ return -1; } - }else if( err ){ + }else if (err) { *pErrorCode = err; /* some other zlib error */ return -1; } - }else{ + } else { toRead = Tcl_Read(pInfo->chan, buf, toRead); } pInfo->nByte -= toRead; @@ -1190,7 +1187,7 @@ vfsSeek( { ZvfsChannelInfo* pInfo = instanceData; - switch( mode ){ + switch (mode) { case SEEK_CUR: offset += pInfo->readSoFar; break; @@ -1204,12 +1201,12 @@ vfsSeek( if (offset < 0) { offset = 0; } - if( !pInfo->isCompressed ){ + if (!pInfo->isCompressed) { Tcl_Seek(pInfo->chan, offset + pInfo->startOfData, SEEK_SET); pInfo->nByte = pInfo->nData; pInfo->readSoFar = offset; - }else{ - if( offsetreadSoFar ){ + } else { + if (offset < pInfo->readSoFar) { z_stream *stream = &pInfo->stream; inflateEnd(stream); @@ -1226,12 +1223,12 @@ vfsSeek( pInfo->nByteCompr = pInfo->nData; pInfo->readSoFar = 0; } - while( pInfo->readSoFar < offset ){ + while (pInfo->readSoFar < offset) { int toRead, errCode; char zDiscard[100]; toRead = offset - pInfo->readSoFar; - if( toRead>sizeof(zDiscard) ) { + if (toRead > sizeof(zDiscard)) { toRead = sizeof(zDiscard); } vfsInput(instanceData, zDiscard, toRead, &errCode); @@ -1303,13 +1300,13 @@ ZvfsFileOpen( unsigned char zBuf[50]; pFile = ZvfsLookup(zFilename); - if( pFile==0 ) { + if (pFile == 0) { return NULL; } - openarch=1; + openarch = 1; chan = Tcl_OpenFileChannel(interp, pFile->pArchive->zName, "r", 0); - openarch=0; - if( chan==0 ){ + openarch = 0; + if (chan == 0) { return 0; } if (Tcl_SetChannelOption(interp, chan, "-translation", "binary") @@ -1319,41 +1316,40 @@ ZvfsFileOpen( return 0; } Tcl_Seek(chan, pFile->iOffset, SEEK_SET); - Tcl_Read(chan, zBuf, 30); - if( memcmp(zBuf, "\120\113\03\04", 4) ){ - if( interp ){ + Tcl_Read(chan, (char *) zBuf, 30); + if (memcmp(zBuf, "\120\113\03\04", 4)) { + if (interp) { Tcl_AppendResult(interp, "local header mismatch: ", NULL); } Tcl_Close(interp, chan); return 0; } - pInfo = Tcl_Alloc( sizeof(*pInfo) ); + pInfo = (void *) Tcl_Alloc(sizeof(*pInfo)); pInfo->chan = chan; Tcl_CreateExitHandler(vfsExit, pInfo); pInfo->isCompressed = INT16(zBuf, 8); - if( pInfo->isCompressed ){ + if (pInfo->isCompressed) { z_stream *stream = &pInfo->stream; - pInfo->zBuf = Tcl_Alloc(COMPR_BUF_SIZE); - stream->zalloc = (alloc_func)0; - stream->zfree = (free_func)0; - stream->opaque = (voidpf)0; + pInfo->zBuf = (void *) Tcl_Alloc(COMPR_BUF_SIZE); + stream->zalloc = NULL; + stream->zfree = NULL; + stream->opaque = NULL; stream->avail_in = 2; stream->next_in = pInfo->zBuf; pInfo->zBuf[0] = 0x78; pInfo->zBuf[1] = 0x01; inflateInit(&pInfo->stream); - }else{ + } else { pInfo->zBuf = 0; } - pInfo->nByte = INT32(zBuf,22); - pInfo->nByteCompr = pInfo->nData = INT32(zBuf,18); + pInfo->nByte = INT32(zBuf, 22); + pInfo->nByteCompr = pInfo->nData = INT32(zBuf, 18); pInfo->readSoFar = 0; - Tcl_Seek(chan, INT16(zBuf,26)+INT16(zBuf,28), SEEK_CUR); + Tcl_Seek(chan, INT16(zBuf, 26) + INT16(zBuf, 28), SEEK_CUR); pInfo->startOfData = Tcl_Tell(chan); - sprintf(zName,"vfs_%x_%x",((int)pFile)>>12,count++); - chan = Tcl_CreateChannel(&vfsChannelType, zName, - (ClientData)pInfo, TCL_READABLE); + sprintf(zName, "vfs_%lx_%x", ((ptrdiff_t)pFile)>>12, count++); + chan = Tcl_CreateChannel(&vfsChannelType, zName, pInfo, TCL_READABLE); return chan; } @@ -1368,7 +1364,7 @@ ZvfsFileStat( ZvfsFile *pFile; pFile = ZvfsLookup(path); - if( pFile==0 ){ + if (pFile == 0) { return -1; } memset(buf, 0, sizeof(*buf)); @@ -1395,11 +1391,11 @@ ZvfsFileAccess( { ZvfsFile *pFile; - if( mode & 3 ){ + if (mode & 3) { return -1; } pFile = ZvfsLookup(path); - if( pFile==0 ){ + if (pFile == 0) { return -1; } return 0; @@ -1449,6 +1445,7 @@ Tobe_FSOpenFileChannelProc( { static int inopen=0; Tcl_Channel chan; + if (inopen) { puts("recursive zvfs open"); return NULL; @@ -1508,28 +1505,29 @@ Tobe_FSMatchInDirectoryProc( return TCL_ERROR; } if (pattern != NULL) { - l=strlen(pattern); + l = strlen(pattern); if (!zp) { - zPattern=strdup(pattern); + zPattern = Tcl_Alloc(len + 1); + memcpy(zPattern, pattern, len + 1); } else { - zPattern=(char*)malloc(len+l+3); - sprintf(zPattern,"%s%s%s", zp, zp[len-1]=='/'?"":"/",pattern); + zPattern = Tcl_Alloc(len + l + 3); + sprintf(zPattern, "%s%s%s", zp, zp[len-1]=='/'?"":"/", pattern); } - scnt=strchrcnt(zPattern,'/'); + scnt = strchrcnt(zPattern, '/'); } dirglob = (types && types->type && (types->type&TCL_GLOB_TYPE_DIR)); dirmnt = (types && types->type && (types->type&TCL_GLOB_TYPE_MOUNT)); if (strcmp(zp, "/") == 0 && strcmp(zPattern, ".*") == 0) { /*TODO: What goes here?*/ } - for(pEntry = Tcl_FirstHashEntry(&local.fileHash, &sSearch); + for (pEntry = Tcl_FirstHashEntry(&local.fileHash, &sSearch); pEntry; pEntry = Tcl_NextHashEntry(&sSearch)){ ZvfsFile *pFile = Tcl_GetHashValue(pEntry); char *z = pFile->zName; if (zPattern != NULL) { - if( Tcl_StringCaseMatch(z, zPattern, 0) == 0 || - (scnt!=pFile->depth /* && !dirglob */ )) { // TODO: ??? + if (Tcl_StringCaseMatch(z, zPattern, 0) == 0 || + (scnt != pFile->depth /* && !dirglob */)) { // TODO: ??? continue; } } else { @@ -1545,7 +1543,7 @@ Tobe_FSMatchInDirectoryProc( if (!pFile->isdir) { continue; } - } else if (types && !(types->type&TCL_GLOB_TYPE_DIR)) { + } else if (types && !(types->type & TCL_GLOB_TYPE_DIR)) { if (pFile->isdir) { continue; } @@ -1553,7 +1551,7 @@ Tobe_FSMatchInDirectoryProc( Tcl_ListObjAppendElement(interp, result, Tcl_NewStringObj(z, -1)); } if (zPattern) { - free(zPattern); + Tcl_Free(zPattern); } return TCL_OK; } @@ -1568,7 +1566,7 @@ Tobe_FSPathInFilesystemProc( ClientData *clientDataPtr) { ZvfsFile *zFile; - char *path=Tcl_GetString(pathPtr); + char *path = Tcl_GetString(pathPtr); // if (ZvfsLookupMount(path)!=0) // return TCL_OK; @@ -1577,7 +1575,7 @@ Tobe_FSPathInFilesystemProc( return -1; } zFile = ZvfsLookup(path); - if (zFile!=NULL && strcmp(path,zFile->pArchive->zName)) { + if (zFile != NULL && strcmp(path, zFile->pArchive->zName)) { return TCL_OK; } return -1; @@ -1589,21 +1587,20 @@ Tobe_FSListVolumesProc(void) Tcl_HashEntry *pEntry; /* Hash table entry */ Tcl_HashSearch zSearch; /* Search all mount points */ ZvfsArchive *pArchive; /* The ZIP archive being mounted */ - Tcl_Obj *pVols=NULL, *pVol; + Tcl_Obj *pVols = NULL, *pVol; - pEntry=Tcl_FirstHashEntry(&local.archiveHash,&zSearch); + pEntry = Tcl_FirstHashEntry(&local.archiveHash,&zSearch); while (pEntry) { - if (pArchive = Tcl_GetHashValue(pEntry)) { + pArchive = Tcl_GetHashValue(pEntry); + if (pArchive) { if (!pVols) { - pVols=Tcl_NewListObj(0,0); + pVols = Tcl_NewListObj(0, 0); Tcl_IncrRefCount(pVols); } - pVol=Tcl_NewStringObj(pArchive->zMountPoint,-1); - Tcl_IncrRefCount(pVol); - Tcl_ListObjAppendElement(NULL, pVols,pVol); - Tcl_DecrRefCount(pVol); + pVol = Tcl_NewStringObj(pArchive->zMountPoint, -1); + Tcl_ListObjAppendElement(NULL, pVols, pVol); } - pEntry=Tcl_NextHashEntry(&zSearch); + pEntry = Tcl_NextHashEntry(&zSearch); } return pVols; } @@ -1616,20 +1613,22 @@ Tobe_FSChdirProc( return TCL_OK; } -const char ** +const char * const* Tobe_FSFileAttrStringsProc( Tcl_Obj *pathPtr, Tcl_Obj** objPtrRef) { - Tcl_Obj *listPtr; - Tcl_Interp *interp = NULL; - char *path=Tcl_GetString(pathPtr); + char *path = Tcl_GetString(pathPtr); #ifdef __WIN32__ - static CONST char *attrs[] = { "-archive", "-hidden", "-readonly", "-system", "-shortname", 0 }; + static const char *attrs[] = { + "-archive", "-hidden", "-readonly", "-system", "-shortname", 0 + }; #else - static CONST char *attrs[] = { "-group", "-owner", "-permissions", 0 }; + static const char *attrs[] = { + "-group", "-owner", "-permissions", 0 + }; #endif - if (ZvfsLookup(path)==0) { + if (ZvfsLookup(path) == 0) { return NULL; } return attrs; @@ -1642,12 +1641,13 @@ Tobe_FSFileAttrsGetProc( Tcl_Obj *pathPtr, Tcl_Obj **objPtrRef) { - char *path=Tcl_GetString(pathPtr); + char *path = Tcl_GetString(pathPtr); char buf[50]; - ZvfsFile *zFile; + ZvfsFile *zFile = ZvfsLookup(path); - if ((zFile = ZvfsLookup(path))==0) + if (zFile == 0) { return TCL_ERROR; + } switch (index) { #ifdef __WIN32__ @@ -1884,11 +1884,11 @@ static Tcl_Filesystem Tobe_Filesystem = { ////////////////////////////////////////////////////////////// -void (*Zvfs_PostInit)(Tcl_Interp *)=0; -static int ZvfsAppendObjCmd( void *NotUsed, Tcl_Interp *interp, int objc, Tcl_Obj *const* objv); -static int ZvfsAddObjCmd( void *NotUsed, Tcl_Interp *interp, int objc, Tcl_Obj *const* objv); -static int ZvfsDumpObjCmd( void *NotUsed, Tcl_Interp *interp, int objc, Tcl_Obj *const* objv); -static int ZvfsStartObjCmd( void *NotUsed, Tcl_Interp *interp, int objc, Tcl_Obj *const* objv); +void (*Zvfs_PostInit)(Tcl_Interp *) = 0; +static int ZvfsAppendObjCmd(void *NotUsed, Tcl_Interp *interp, int objc, Tcl_Obj *const* objv); +static int ZvfsAddObjCmd(void *NotUsed, Tcl_Interp *interp, int objc, Tcl_Obj *const* objv); +static int ZvfsDumpObjCmd(void *NotUsed, Tcl_Interp *interp, int objc, Tcl_Obj *const* objv); +static int ZvfsStartObjCmd(void *NotUsed, Tcl_Interp *interp, int objc, Tcl_Obj *const* objv); /* * Initialize the ZVFS system. @@ -1900,7 +1900,7 @@ Zvfs_doInit( { int n; #ifdef USE_TCL_STUBS - if( Tcl_InitStubs(interp,"8.0",0)==0 ){ + if (Tcl_InitStubs(interp, "8.0", 0) == 0) { return TCL_ERROR; } #endif @@ -1916,12 +1916,13 @@ Zvfs_doInit( Tcl_CreateObjCommand(interp, "zvfs::list", ZvfsListObjCmd, 0, 0); Tcl_CreateObjCommand(interp, "zvfs::dump", ZvfsDumpObjCmd, 0, 0); Tcl_CreateObjCommand(interp, "zvfs::start", ZvfsStartObjCmd, 0, 0); - Tcl_SetVar(interp, "::zvfs::auto_ext", ".tcl .tk .itcl .htcl .txt .c .h .tht", TCL_GLOBAL_ONLY); + Tcl_SetVar(interp, "::zvfs::auto_ext", + ".tcl .tk .itcl .htcl .txt .c .h .tht", TCL_GLOBAL_ONLY); /* Tcl_CreateObjCommand(interp, "zip::open", ZipOpenObjCmd, 0, 0); */ #ifndef USE_TCL_VFS Tcl_GlobalEval(interp, zFileCopy); #endif - if( !local.isInit ){ + if (!local.isInit) { /* One-time initialization of the ZVFS */ #ifdef USE_TCL_VFS n = Tcl_FSRegister(0, &Tobe_Filesystem); @@ -1948,14 +1949,14 @@ int Tcl_Zvfs_Init( Tcl_Interp *interp) { - return Zvfs_doInit(interp,0); + return Zvfs_doInit(interp, 0); } int Tcl_Zvfs_SafeInit( Tcl_Interp *interp) { - return Zvfs_doInit(interp,1); + return Zvfs_doInit(interp, 1); } /************************************************************************/ @@ -1984,23 +1985,23 @@ ZvfsDumpObjCmd( int rc; Tcl_Obj *pResult; - if( objc!=2 ){ + if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "FILENAME"); return TCL_ERROR; } zFilename = Tcl_GetString(objv[1]); chan = Tcl_OpenFileChannel(interp, zFilename, "r", 0); - if( chan==0 ) { + if (chan == 0) { return TCL_ERROR; } rc = ZvfsReadTOC(interp, chan, &pList); - if( rc==TCL_ERROR ){ + if (rc == TCL_ERROR) { deleteZFileList(pList); return rc; } Tcl_Close(interp, chan); pResult = Tcl_GetObjResult(interp); - while( pList ){ + while (pList) { Tcl_Obj *pEntry = Tcl_NewObj(); ZFile *pNext; char zDateTime[100]; @@ -2019,7 +2020,7 @@ ZvfsDumpObjCmd( Tcl_NewIntObj(pList->nByteCompr)); Tcl_ListObjAppendElement(interp, pResult, pEntry); pNext = pList->pNext; - Tcl_Free((char*)pList); + Tcl_Free((void *) pList); pList = pList->pNext; } return TCL_OK; @@ -2062,7 +2063,7 @@ writeFile( strcpy(p->zName, zDest); p->isSpecial = 0; Tcl_Stat(zSrc, &stat); - now=stat.st_mtime; + now = stat.st_mtime; tm = localtime(&now); UnixTimeDate(tm, &p->dosDate, &p->dosTime); p->iOffset = Tcl_Tell(out); @@ -2104,13 +2105,13 @@ writeFile( * Write the compressed file. Compute the CRC as we progress. */ - stream.zalloc = (alloc_func)0; - stream.zfree = (free_func)0; + stream.zalloc = NULL; + stream.zfree = NULL; stream.opaque = 0; stream.avail_in = 0; - stream.next_in = zInBuf; + stream.next_in = (unsigned char *) zInBuf; stream.avail_out = sizeof(zOutBuf); - stream.next_out = zOutBuf; + stream.next_out = (unsigned char *) zOutBuf; #if 1 deflateInit(&stream, 9); #else @@ -2123,40 +2124,42 @@ writeFile( #endif p->iCRC = crc32(0, 0, 0); - while( !Tcl_Eof(in) ){ - if( stream.avail_in==0 ){ + while (!Tcl_Eof(in)) { + if (stream.avail_in == 0) { int amt = Tcl_Read(in, zInBuf, sizeof(zInBuf)); - if( amt<=0 ) { + if (amt <= 0) { break; } - p->iCRC = crc32(p->iCRC, zInBuf, amt); + p->iCRC = crc32(p->iCRC, (unsigned char *) zInBuf, amt); stream.avail_in = amt; - stream.next_in = zInBuf; + stream.next_in = (unsigned char *) zInBuf; } deflate(&stream, 0); toOut = sizeof(zOutBuf) - stream.avail_out; - if( toOut>skip ){ + if (toOut > skip) { Tcl_Write(out, &zOutBuf[skip], toOut - skip); skip = 0; - }else{ + } else { skip -= toOut; } stream.avail_out = sizeof(zOutBuf); - stream.next_out = zOutBuf; + stream.next_out = (unsigned char *) zOutBuf; } + do{ stream.avail_out = sizeof(zOutBuf); - stream.next_out = zOutBuf; + stream.next_out = (unsigned char *) zOutBuf; deflate(&stream, Z_FINISH); toOut = sizeof(zOutBuf) - stream.avail_out; - if( toOut>skip ){ + if (toOut > skip) { Tcl_Write(out, &zOutBuf[skip], toOut - skip); skip = 0; - }else{ + } else { skip -= toOut; } - }while( stream.avail_out==0 ); + } while (stream.avail_out == 0); + p->nByte = stream.total_in; p->nByteCompr = stream.total_out - 2; deflateEnd(&stream); @@ -2199,24 +2202,24 @@ mergeZFiles( ZFile *pTail; pTail = &fakeHead; - while( pLeft && pRight ){ + while (pLeft && pRight) { ZFile *p; - if( pLeft->iOffset <= pRight->iOffset ){ + if (pLeft->iOffset <= pRight->iOffset) { p = pLeft; pLeft = p->pNext; - }else{ + } else { p = pRight; pRight = p->pNext; } pTail->pNext = p; pTail = p; } - if( pLeft ){ + if (pLeft) { pTail->pNext = pLeft; - }else if( pRight ){ + } else if (pRight) { pTail->pNext = pRight; - }else{ + } else { pTail->pNext = 0; } return fakeHead.pNext; @@ -2234,22 +2237,22 @@ sortZFiles( ZFile *p; ZFile *aBin[NBIN+1]; - for(i=0; i<=NBIN; i++) { + for (i=0; i<=NBIN; i++) { aBin[i] = 0; } - while( pList ){ + while (pList) { p = pList; pList = p->pNext; p->pNext = 0; - for(i=0; ipNext){ - if( pList->isSpecial ) { + for (; pList; pList=pList->pNext) { + if (pList->isSpecial) { continue; } put32(&zBuf[0], 0x02014b50); @@ -2294,7 +2297,7 @@ writeTOC( put32(&zBuf[42], pList->iOffset); Tcl_Write(chan, zBuf, 46); Tcl_Write(chan, pList->zName, strlen(pList->zName)); - for(i=pList->nExtra; i>0; i-=40){ + for (i=pList->nExtra; i>0; i-=40) { int toWrite = i<40 ? i : 40; /* CAREFUL! String below is intentionally 40 spaces! */ @@ -2347,20 +2350,20 @@ ZvfsAppendObjCmd( * Open the archive and read the table of contents */ - if( objc<2 || (objc&1)!=0 ){ + if (objc<2 || (objc&1)!=0) { Tcl_WrongNumArgs(interp, 1, objv, "ARCHIVE (SRC DEST)+"); return TCL_ERROR; } zArchive = Tcl_GetString(objv[1]); chan = Tcl_OpenFileChannel(interp, zArchive, "r+", 0644); - if( chan==0 ) { + if (chan == 0) { chan = Tcl_OpenFileChannel(interp, zArchive, "w+", 0644); - if( chan==0 ) { + if (chan == 0) { return TCL_ERROR; } } - if(Tcl_SetChannelOption(interp, chan, "-translation", "binary") + if (Tcl_SetChannelOption(interp, chan, "-translation", "binary") || Tcl_SetChannelOption(interp, chan, "-encoding", "binary")){ /* this should never happen */ Tcl_Close(0, chan); @@ -2371,27 +2374,25 @@ ZvfsAppendObjCmd( /* Null file is ok, we're creating new one. */ } else { Tcl_Seek(chan, 0, SEEK_SET); - rc = ZvfsReadTOC(interp, chan, &pList); - if( rc==TCL_ERROR ){ + if (ZvfsReadTOC(interp, chan, &pList) == TCL_ERROR) { deleteZFileList(pList); Tcl_Close(interp, chan); - return rc; - } else { - rc=TCL_OK; + return TCL_ERROR; } + rc = TCL_OK; } /* * Move the file pointer to the start of the table of contents. */ - for(pToc=pList; pToc; pToc=pToc->pNext){ - if( pToc->isSpecial && strcmp(pToc->zName,"*TOC*")==0 ) { + for (pToc=pList; pToc; pToc=pToc->pNext) { + if (pToc->isSpecial && strcmp(pToc->zName, "*TOC*") == 0) { break; } } - if( pToc ){ + if (pToc) { Tcl_Seek(chan, pToc->iOffset, SEEK_SET); - }else{ + } else { Tcl_Seek(chan, 0, SEEK_END); } @@ -2399,7 +2400,7 @@ ZvfsAppendObjCmd( * Add new files to the end of the archive. */ - for(i=2; rc==TCL_OK && i3) { + if (objc > 3) { zOpts = Tcl_GetStringFromObj(objv[1], &oLen); if (!strncmp("-fconfigure", zOpts, oLen)) { confOpts = objv[2]; @@ -2512,21 +2513,24 @@ ZvfsAddObjCmd( objv += 2; } } - if( objc==2) { + if (objc == 2) { return TCL_OK; } - if( objc<3) { + if (objc < 3) { Tcl_WrongNumArgs(interp, 1, objv, "?-fconfigure OPTPAIRS? ARCHIVE FILE1 FILE2 .."); return TCL_ERROR; } + zArchive = Tcl_GetString(objv[1]); chan = Tcl_OpenFileChannel(interp, zArchive, "r+", 0644); - if( chan==0 ) { + if (chan == 0) { chan = Tcl_OpenFileChannel(interp, zArchive, "w+", 0644); + if (chan == 0) { + return TCL_ERROR; + } } - if( chan==0 ) return TCL_ERROR; if (Tcl_SetChannelOption(interp, chan, "-translation", "binary") || Tcl_SetChannelOption(interp, chan, "-encoding", "binary")){ /* this should never happen */ @@ -2538,27 +2542,26 @@ ZvfsAddObjCmd( /* Null file is ok, we're creating new one. */ } else { Tcl_Seek(chan, 0, SEEK_SET); - rc = ZvfsReadTOC(interp, chan, &pList); - if( rc==TCL_ERROR ){ + if (ZvfsReadTOC(interp, chan, &pList) == TCL_ERROR) { deleteZFileList(pList); Tcl_Close(interp, chan); - return rc; + return TCL_ERROR; } - rc=TCL_OK; + rc = TCL_OK; } /* * Move the file pointer to the start of the table of contents. */ - for(pToc=pList; pToc; pToc=pToc->pNext){ - if( pToc->isSpecial && strcmp(pToc->zName, "*TOC*")==0 ) { + for (pToc=pList; pToc; pToc=pToc->pNext) { + if (pToc->isSpecial && strcmp(pToc->zName, "*TOC*") == 0) { break; } } - if( pToc ){ + if (pToc) { Tcl_Seek(chan, pToc->iOffset, SEEK_SET); - }else{ + } else { Tcl_Seek(chan, 0, SEEK_END); } @@ -2566,22 +2569,25 @@ ZvfsAddObjCmd( * Add new files to the end of the archive. */ - for(i=2; rc==TCL_OK && i=tobjc) { + if (j >= tobjc) { ext = NULL; } } @@ -2654,26 +2660,20 @@ ZvfsStartObjCmd( { char *zArchive; Tcl_Channel chan; - ZFile *pList = NULL, *pToc; - int rc = TCL_OK, i, j, oLen; - char *zOpts = NULL; - Tcl_Obj *confOpts = NULL; - int tobjc; - Tcl_Obj **tobjv; - Tcl_Obj *varObj = NULL; + ZFile *pList = NULL; int zipStart; /* * Open the archive and read the table of contents */ - if( objc != 2) { + if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "ARCHIVE"); return TCL_ERROR; } zArchive = Tcl_GetString(objv[1]); chan = Tcl_OpenFileChannel(interp, zArchive, "r", 0644); - if( chan==0 ) { + if (chan == 0) { return TCL_ERROR; } if (Tcl_SetChannelOption(interp, chan, "-translation", "binary") @@ -2689,8 +2689,7 @@ ZvfsStartObjCmd( } Tcl_Seek(chan, 0, SEEK_SET); - rc = ZvfsReadTOCStart(interp, chan, &pList, &zipStart); - if( rc!=TCL_OK ){ + if (ZvfsReadTOCStart(interp, chan, &pList, &zipStart) != TCL_OK) { deleteZFileList(pList); Tcl_Close(interp, chan); Tcl_AppendResult(interp, "not an archive", 0); -- cgit v0.12 From 1d9824ec60bc37945dfde4597fe763ed78bba999 Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Mon, 1 Sep 2014 23:23:37 +0000 Subject: Tweaking the Makefile instructions for Tclkits under unix --- unix/Makefile.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/unix/Makefile.in b/unix/Makefile.in index d41e0d9..a228497 100644 --- a/unix/Makefile.in +++ b/unix/Makefile.in @@ -654,7 +654,7 @@ ${TCLKIT_EXE}: ${TCLSH_OBJS} ${TCL_LIB_FILE} ${LIBS} @EXTRA_TCLSH_LIBS@ \ ${CC_SEARCH_FLAGS} -o ${TCLKIT_EXE} PWD=`pwd` - cd $(SCRIPT_INSTALL_DIR) ; zip -rAq ${PWD}/tclkit.zip tcl8 tcl8.6 + cd ${prefix}/lib ; zip -rAq ${PWD}/tclkit.zip tcl8 tcl8.6 cat tclkit.zip >> ${TCLKIT_EXE} # Must be empty so it doesn't conflict with rule for ${TCL_EXE} above -- cgit v0.12 From 811d367c49b7c02192b14be4301f9066dd7fe95e Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Tue, 2 Sep 2014 11:04:53 +0000 Subject: Rather than make a special executable, tclkits are now a copy of tclsh with an attached zip file --- unix/Makefile.in | 7 +++---- win/Makefile.in | 8 +++----- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/unix/Makefile.in b/unix/Makefile.in index a228497..bb6af0c 100644 --- a/unix/Makefile.in +++ b/unix/Makefile.in @@ -649,12 +649,11 @@ ${TCL_EXE}: ${TCLSH_OBJS} ${TCL_LIB_FILE} ${TCL_STUB_LIB_FILE} @TCL_BUILD_LIB_SPEC@ ${TCL_STUB_LIB_FILE} ${LIBS} @EXTRA_TCLSH_LIBS@ \ ${CC_SEARCH_FLAGS} -o ${TCL_EXE} -${TCLKIT_EXE}: ${TCLSH_OBJS} ${TCL_LIB_FILE} - ${CC} ${CFLAGS} ${LDFLAGS} ${OBJS} ${TCLSH_OBJS} \ - ${LIBS} @EXTRA_TCLSH_LIBS@ \ - ${CC_SEARCH_FLAGS} -o ${TCLKIT_EXE} +${TCLKIT_EXE}: ${TCL_EXE} + rm -f tclkit.zip PWD=`pwd` cd ${prefix}/lib ; zip -rAq ${PWD}/tclkit.zip tcl8 tcl8.6 + cp -f ${TCL_EXE} ${TCLKIT_EXE} cat tclkit.zip >> ${TCLKIT_EXE} # Must be empty so it doesn't conflict with rule for ${TCL_EXE} above diff --git a/win/Makefile.in b/win/Makefile.in index 07c8db1..f302ed6 100644 --- a/win/Makefile.in +++ b/win/Makefile.in @@ -426,13 +426,11 @@ $(TCLSH): $(TCLSH_OBJS) @LIBRARIES@ $(TCL_STUB_LIB_FILE) tclsh.$(RES) tclkit: $(TCLKIT) -$(TCLKIT): $(TCLSH_OBJS) @LIBRARIES@ ${TCL_OBJS} $(CAT32) tclsh.$(RES) - $(CC) $(CFLAGS) ${TCL_OBJS} $(TCLSH_OBJS) $(LIBS) \ - tclsh.$(RES) $(CC_EXENAME) $(LDFLAGS_CONSOLE) - PWD=`pwd` +$(TCLKIT): $(TCLSH) rm -f tclkit.zip - cp $(TCLSH) $(TCLKIT) + PWD=`pwd` cd ${prefix}/lib ; zip -rq ${PWD}/tclkit.zip tcl8 tcl8.6 + cp -f $(TCLSH) $(TCLKIT) cat tclkit.zip >> $(TCLKIT) cat32.$(OBJEXT): cat.c -- cgit v0.12 From 8c90b3ae99f9acb04b46875ed09def2dcf9641f3 Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Tue, 2 Sep 2014 15:21:23 +0000 Subject: Patch to make the default behavior for Tcl under Windows to embed the Zlib sources rather than add a dependency to a dynamic zlib.dll --- win/configure | 6546 ++++++++++++++++++++++++++++-------------------------- win/configure.in | 24 +- 2 files changed, 3361 insertions(+), 3209 deletions(-) diff --git a/win/configure b/win/configure index cf2b201..d8ee198 100755 --- a/win/configure +++ b/win/configure @@ -1,81 +1,423 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.59. +# Generated by GNU Autoconf 2.68. +# +# +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, +# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software +# Foundation, Inc. +# # -# Copyright (C) 2003 Free Software Foundation, Inc. # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. -## --------------------- ## -## M4sh Initialization. ## -## --------------------- ## +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## -# Be Bourne compatible -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: - # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' -elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then - set -o posix + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac fi -DUALCASE=1; export DUALCASE # for MKS sh -# Support unset when possible. -if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then - as_unset=unset -else - as_unset=false + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } fi -# Work around bugs in pre-3.0 UWIN ksh. -$as_unset ENV MAIL MAILPATH +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. -for as_var in \ - LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ - LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ - LC_TELEPHONE LC_TIME +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +if test "x$CONFIG_SHELL" = x; then + as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi +" + as_required="as_fn_return () { (exit \$1); } +as_fn_success () { as_fn_return 0; } +as_fn_failure () { as_fn_return 1; } +as_fn_ret_success () { return 0; } +as_fn_ret_failure () { return 1; } + +exitcode=0 +as_fn_success || { exitcode=1; echo as_fn_success failed.; } +as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } +as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } +as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } +if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : + +else + exitcode=1; echo positional parameters were not saved. +fi +test x\$exitcode = x0 || exit 1" + as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO + as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO + eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && + test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 +test \$(( 1 + 1 )) = 2 || exit 1" + if (eval "$as_required") 2>/dev/null; then : + as_have_required=yes +else + as_have_required=no +fi + if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : + +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_found=false +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do - if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then - eval $as_var=C; export $as_var + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + as_found=: + case $as_dir in #( + /*) + for as_base in sh bash ksh sh5; do + # Try only shells that exist, to save several forks. + as_shell=$as_dir/$as_base + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : + CONFIG_SHELL=$as_shell as_have_required=yes + if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : + break 2 +fi +fi + done;; + esac + as_found=false +done +$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : + CONFIG_SHELL=$SHELL as_have_required=yes +fi; } +IFS=$as_save_IFS + + + if test "x$CONFIG_SHELL" != x; then : + # We cannot yet assume a decent shell, so we have to provide a + # neutralization value for shells without unset; and this also + # works around shells that cannot unset nonexistent variables. + # Preserve -v and -x to the replacement shell. + BASH_ENV=/dev/null + ENV=/dev/null + (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV + export CONFIG_SHELL + case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; + esac + exec "$CONFIG_SHELL" $as_opts "$as_myself" ${1+"$@"} +fi + + if test x$as_have_required = xno; then : + $as_echo "$0: This script requires a shell more modern than all" + $as_echo "$0: the shells that I found on your system." + if test x${ZSH_VERSION+set} = xset ; then + $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" + $as_echo "$0: be upgraded to zsh 4.3.4 or later." else - $as_unset $as_var + $as_echo "$0: Please tell bug-autoconf@gnu.org about your system, +$0: including any error possibly output before this +$0: message. Then install a modern shell, or manually run +$0: the script under such a shell if you do have one." fi -done + exit 1 +fi +fi +fi +SHELL=${CONFIG_SHELL-/bin/sh} +export SHELL +# Unset more variables known to interfere with behavior of common tools. +CLICOLOR_FORCE= GREP_OPTIONS= +unset CLICOLOR_FORCE GREP_OPTIONS + +## --------------------- ## +## M4sh Shell Functions. ## +## --------------------- ## +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status -# Required to use basename. -if expr a : '\(a\)' >/dev/null 2>&1; then +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi -if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi -# Name of the executable. -as_me=`$as_basename "$0" || +as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)$' \| \ - . : '\(.\)' 2>/dev/null || -echo X/"$0" | - sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } - /^X\/\(\/\/\)$/{ s//\1/; q; } - /^X\/\(\/\).*/{ s//\1/; q; } - s/.*/./; q'` - + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` -# PATH needs CR, and LINENO needs CR and PATH. # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' @@ -83,146 +425,107 @@ as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits -# The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then - echo "#! /bin/sh" >conf$$.sh - echo "exit 0" >>conf$$.sh - chmod +x conf$$.sh - if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then - PATH_SEPARATOR=';' - else - PATH_SEPARATOR=: - fi - rm -f conf$$.sh -fi - - - as_lineno_1=$LINENO - as_lineno_2=$LINENO - as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` - test "x$as_lineno_1" != "x$as_lineno_2" && - test "x$as_lineno_3" = "x$as_lineno_2" || { - # Find who we are. Look in the path if we contain no path at all - # relative or not. - case $0 in - *[\\/]* ) as_myself=$0 ;; - *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break -done - - ;; - esac - # We did not find ourselves, most probably we were run as `sh COMMAND' - # in which case we are not to be found in the path. - if test "x$as_myself" = x; then - as_myself=$0 - fi - if test ! -f "$as_myself"; then - { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2 - { (exit 1); exit 1; }; } - fi - case $CONFIG_SHELL in - '') - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for as_base in sh bash ksh sh5; do - case $as_dir in - /*) - if ("$as_dir/$as_base" -c ' - as_lineno_1=$LINENO - as_lineno_2=$LINENO - as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` - test "x$as_lineno_1" != "x$as_lineno_2" && - test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then - $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } - $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } - CONFIG_SHELL=$as_dir/$as_base - export CONFIG_SHELL - exec "$CONFIG_SHELL" "$0" ${1+"$@"} - fi;; - esac - done -done -;; - esac - # Create $as_me.lineno as a copy of $as_myself, but with $LINENO - # uniformly replaced by the line number. The first 'sed' inserts a - # line-number line before each line; the second 'sed' does the real - # work. The second script uses 'N' to pair each line-number line - # with the numbered line, and appends trailing '-' during - # substitution so that $LINENO is not a special case at line end. - # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the - # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) - sed '=' <$as_myself | + as_lineno_1=$LINENO as_lineno_1a=$LINENO + as_lineno_2=$LINENO as_lineno_2a=$LINENO + eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && + test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { + # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno N - s,$,-, - : loop - s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop - s,-$,, - s,^['$as_cr_digits']*\n,, + s/-\n.*// ' >$as_me.lineno && - chmod +x $as_me.lineno || - { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 - { (exit 1); exit 1; }; } + chmod +x "$as_me.lineno" || + { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the - # original and so on. Autoconf is especially sensible to this). - . ./$as_me.lineno + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" # Exit status is that of the last command. exit } - -case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in - *c*,-n*) ECHO_N= ECHO_C=' -' ECHO_T=' ' ;; - *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; - *) ECHO_N= ECHO_C='\c' ECHO_T= ;; +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; esac -if expr a : '\(a\)' >/dev/null 2>&1; then - as_expr=expr +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file else - as_expr=false + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null fi - -rm -f conf$$ conf$$.exe conf$$.file -echo >conf$$.file -if ln -s conf$$.file conf$$ 2>/dev/null; then - # We could just check for DJGPP; but this test a) works b) is more generic - # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). - if test -f conf$$.exe; then - # Don't use ln at all; we don't have any links - as_ln_s='cp -p' - else +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -p' fi -elif ln conf$$.file conf$$ 2>/dev/null; then - as_ln_s=ln else as_ln_s='cp -p' fi -rm -f conf$$ conf$$.exe conf$$.file +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then - as_mkdir_p=: + as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi -as_executable_p="test -f" +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in #( + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" @@ -231,38 +534,25 @@ as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" -# IFS -# We need space, tab and new line, in precisely that order. -as_nl=' -' -IFS=" $as_nl" - -# CDPATH. -$as_unset CDPATH - +test -n "$DJDIR" || exec 7<&0 &1 # Name of the host. -# hostname on some systems (SVR3.2, Linux) returns a bogus exit status, +# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` -exec 6>&1 - # # Initializations. # ac_default_prefix=/usr/local +ac_clean_files= ac_config_libobj_dir=. +LIBOBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= -SHELL=${CONFIG_SHELL-/bin/sh} - -# Maximum number of lines to put in a shell here document. -# This variable seems obsolete. It should probably be removed, and -# only ac_max_sed_lines should be used. -: ${ac_max_here_lines=38} # Identity of this package. PACKAGE_NAME= @@ -270,51 +560,214 @@ PACKAGE_TARNAME= PACKAGE_VERSION= PACKAGE_STRING= PACKAGE_BUGREPORT= +PACKAGE_URL= ac_unique_file="../generic/tcl.h" # Factoring default headers for most tests. ac_includes_default="\ #include -#if HAVE_SYS_TYPES_H +#ifdef HAVE_SYS_TYPES_H # include #endif -#if HAVE_SYS_STAT_H +#ifdef HAVE_SYS_STAT_H # include #endif -#if STDC_HEADERS +#ifdef STDC_HEADERS # include # include #else -# if HAVE_STDLIB_H +# ifdef HAVE_STDLIB_H # include # endif #endif -#if HAVE_STRING_H -# if !STDC_HEADERS && HAVE_MEMORY_H +#ifdef HAVE_STRING_H +# if !defined STDC_HEADERS && defined HAVE_MEMORY_H # include # endif # include #endif -#if HAVE_STRINGS_H +#ifdef HAVE_STRINGS_H # include #endif -#if HAVE_INTTYPES_H +#ifdef HAVE_INTTYPES_H # include -#else -# if HAVE_STDINT_H -# include -# endif #endif -#if HAVE_UNISTD_H +#ifdef HAVE_STDINT_H +# include +#endif +#ifdef HAVE_UNISTD_H # include #endif" -ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CPP EGREP AR ac_ct_AR RANLIB ac_ct_RANLIB RC ac_ct_RC SET_MAKE TCL_THREADS CYGPATH CELIB_DIR DL_LIBS CFLAGS_DEBUG CFLAGS_OPTIMIZE CFLAGS_WARNING ZLIB_DLL_FILE ZLIB_LIBS ZLIB_OBJS CFLAGS_DEFAULT LDFLAGS_DEFAULT VC_MANIFEST_EMBED_DLL VC_MANIFEST_EMBED_EXE TCL_WIN_VERSION MACHINE TCL_VERSION TCL_MAJOR_VERSION TCL_MINOR_VERSION TCL_PATCH_LEVEL PKG_CFG_ARGS TCL_EXE TCL_LIB_FILE TCL_LIB_FLAG TCL_STATIC_LIB_FILE TCL_STATIC_LIB_FLAG TCL_IMPORT_LIB_FILE TCL_IMPORT_LIB_FLAG TCL_LIB_SPEC TCL_STUB_LIB_FILE TCL_STUB_LIB_FLAG TCL_STUB_LIB_SPEC TCL_STUB_LIB_PATH TCL_INCLUDE_SPEC TCL_BUILD_STUB_LIB_SPEC TCL_BUILD_STUB_LIB_PATH TCL_DLL_FILE TCL_SRC_DIR TCL_BIN_DIR TCL_DBGX CFG_TCL_SHARED_LIB_SUFFIX CFG_TCL_UNSHARED_LIB_SUFFIX CFG_TCL_EXPORT_FILE_SUFFIX EXTRA_CFLAGS DEPARG CC_OBJNAME CC_EXENAME LDFLAGS_DEBUG LDFLAGS_OPTIMIZE LDFLAGS_CONSOLE LDFLAGS_WINDOW STLIB_LD SHLIB_LD SHLIB_LD_LIBS SHLIB_CFLAGS SHLIB_SUFFIX TCL_SHARED_BUILD LIBS_GUI DLLSUFFIX LIBPREFIX LIBSUFFIX EXESUFFIX LIBRARIES MAKE_LIB MAKE_STUB_LIB POST_MAKE_LIB MAKE_DLL MAKE_EXE TCL_BUILD_LIB_SPEC TCL_LD_SEARCH_FLAGS TCL_NEEDS_EXP_FILE TCL_BUILD_EXP_FILE TCL_EXP_FILE TCL_LIB_VERSIONS_OK TCL_PACKAGE_PATH TCL_DDE_VERSION TCL_DDE_MAJOR_VERSION TCL_DDE_MINOR_VERSION TCL_REG_VERSION TCL_REG_MAJOR_VERSION TCL_REG_MINOR_VERSION RC_OUT RC_TYPE RC_INCLUDE RC_DEFINE RC_DEFINES RES LIBOBJS LTLIBOBJS' +ac_subst_vars='LTLIBOBJS +LIBOBJS +RES +RC_DEFINES +RC_DEFINE +RC_INCLUDE +RC_TYPE +RC_OUT +TCL_REG_MINOR_VERSION +TCL_REG_MAJOR_VERSION +TCL_REG_VERSION +TCL_DDE_MINOR_VERSION +TCL_DDE_MAJOR_VERSION +TCL_DDE_VERSION +TCL_PACKAGE_PATH +TCL_LIB_VERSIONS_OK +TCL_EXP_FILE +TCL_BUILD_EXP_FILE +TCL_NEEDS_EXP_FILE +TCL_LD_SEARCH_FLAGS +TCL_BUILD_LIB_SPEC +MAKE_EXE +MAKE_DLL +POST_MAKE_LIB +MAKE_STUB_LIB +MAKE_LIB +LIBRARIES +EXESUFFIX +LIBSUFFIX +LIBPREFIX +DLLSUFFIX +LIBS_GUI +TCL_SHARED_BUILD +SHLIB_SUFFIX +SHLIB_CFLAGS +SHLIB_LD_LIBS +SHLIB_LD +STLIB_LD +LDFLAGS_WINDOW +LDFLAGS_CONSOLE +LDFLAGS_OPTIMIZE +LDFLAGS_DEBUG +CC_EXENAME +CC_OBJNAME +DEPARG +EXTRA_CFLAGS +CFG_TCL_EXPORT_FILE_SUFFIX +CFG_TCL_UNSHARED_LIB_SUFFIX +CFG_TCL_SHARED_LIB_SUFFIX +TCL_DBGX +TCL_BIN_DIR +TCL_SRC_DIR +TCL_DLL_FILE +TCL_BUILD_STUB_LIB_PATH +TCL_BUILD_STUB_LIB_SPEC +TCL_INCLUDE_SPEC +TCL_STUB_LIB_PATH +TCL_STUB_LIB_SPEC +TCL_STUB_LIB_FLAG +TCL_STUB_LIB_FILE +TCL_LIB_SPEC +TCL_IMPORT_LIB_FLAG +TCL_IMPORT_LIB_FILE +TCL_STATIC_LIB_FLAG +TCL_STATIC_LIB_FILE +TCL_LIB_FLAG +TCL_LIB_FILE +TCL_EXE +PKG_CFG_ARGS +TCL_PATCH_LEVEL +TCL_MINOR_VERSION +TCL_MAJOR_VERSION +TCL_VERSION +MACHINE +TCL_WIN_VERSION +VC_MANIFEST_EMBED_EXE +VC_MANIFEST_EMBED_DLL +LDFLAGS_DEFAULT +CFLAGS_DEFAULT +ZLIB_LIBS +ZLIB_OBJS +CFLAGS_WARNING +CFLAGS_OPTIMIZE +CFLAGS_DEBUG +DL_LIBS +CELIB_DIR +CYGPATH +TCL_THREADS +SET_MAKE +RC +RANLIB +AR +EGREP +GREP +CPP +OBJEXT +EXEEXT +ac_ct_CC +CPPFLAGS +LDFLAGS +CFLAGS +CC +target_alias +host_alias +build_alias +LIBS +ECHO_T +ECHO_N +ECHO_C +DEFS +mandir +localedir +libdir +psdir +pdfdir +dvidir +htmldir +infodir +docdir +oldincludedir +includedir +localstatedir +sharedstatedir +sysconfdir +datadir +datarootdir +libexecdir +sbindir +bindir +program_transform_name +prefix +exec_prefix +PACKAGE_URL +PACKAGE_BUGREPORT +PACKAGE_STRING +PACKAGE_VERSION +PACKAGE_TARNAME +PACKAGE_NAME +PATH_SEPARATOR +SHELL' ac_subst_files='' +ac_user_opts=' +enable_option_checking +enable_threads +with_encoding +enable_shared +enable_64bit +enable_wince +with_celib +with_zlib +enable_symbols +enable_embedded_manifest +' + ac_precious_vars='build_alias +host_alias +target_alias +CC +CFLAGS +LDFLAGS +LIBS +CPPFLAGS +CPP' + # Initialize some variables set by options. ac_init_help= ac_init_version=false +ac_unrecognized_opts= +ac_unrecognized_sep= # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null @@ -337,34 +790,49 @@ x_libraries=NONE # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. +# (The list follows the same order as the GNU Coding Standards.) bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' -datadir='${prefix}/share' +datarootdir='${prefix}/share' +datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' -libdir='${exec_prefix}/lib' includedir='${prefix}/include' oldincludedir='/usr/include' -infodir='${prefix}/info' -mandir='${prefix}/man' +docdir='${datarootdir}/doc/${PACKAGE}' +infodir='${datarootdir}/info' +htmldir='${docdir}' +dvidir='${docdir}' +pdfdir='${docdir}' +psdir='${docdir}' +libdir='${exec_prefix}/lib' +localedir='${datarootdir}/locale' +mandir='${datarootdir}/man' ac_prev= +ac_dashdash= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then - eval "$ac_prev=\$ac_option" + eval $ac_prev=\$ac_option ac_prev= continue fi - ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'` + case $ac_option in + *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *=) ac_optarg= ;; + *) ac_optarg=yes ;; + esac # Accept the important Cygnus configure options, so we can diagnose typos. - case $ac_option in + case $ac_dashdash$ac_option in + --) + ac_dashdash=yes ;; -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; @@ -386,33 +854,59 @@ do --config-cache | -C) cache_file=config.cache ;; - -datadir | --datadir | --datadi | --datad | --data | --dat | --da) + -datadir | --datadir | --datadi | --datad) ac_prev=datadir ;; - -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ - | --da=*) + -datadir=* | --datadir=* | --datadi=* | --datad=*) datadir=$ac_optarg ;; + -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ + | --dataroo | --dataro | --datar) + ac_prev=datarootdir ;; + -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ + | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) + datarootdir=$ac_optarg ;; + -disable-* | --disable-*) - ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. - expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && - { echo "$as_me: error: invalid feature name: $ac_feature" >&2 - { (exit 1); exit 1; }; } - ac_feature=`echo $ac_feature | sed 's/-/_/g'` - eval "enable_$ac_feature=no" ;; + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=no ;; + + -docdir | --docdir | --docdi | --doc | --do) + ac_prev=docdir ;; + -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) + docdir=$ac_optarg ;; + + -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) + ac_prev=dvidir ;; + -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) + dvidir=$ac_optarg ;; -enable-* | --enable-*) - ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. - expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && - { echo "$as_me: error: invalid feature name: $ac_feature" >&2 - { (exit 1); exit 1; }; } - ac_feature=`echo $ac_feature | sed 's/-/_/g'` - case $ac_option in - *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; - *) ac_optarg=yes ;; + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; esac - eval "enable_$ac_feature='$ac_optarg'" ;; + eval enable_$ac_useropt=\$ac_optarg ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ @@ -439,6 +933,12 @@ do -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; + -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) + ac_prev=htmldir ;; + -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ + | --ht=*) + htmldir=$ac_optarg ;; + -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; @@ -463,13 +963,16 @@ do | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; + -localedir | --localedir | --localedi | --localed | --locale) + ac_prev=localedir ;; + -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) + localedir=$ac_optarg ;; + -localstatedir | --localstatedir | --localstatedi | --localstated \ - | --localstate | --localstat | --localsta | --localst \ - | --locals | --local | --loca | --loc | --lo) + | --localstate | --localstat | --localsta | --localst | --locals) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ - | --localstate=* | --localstat=* | --localsta=* | --localst=* \ - | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) + | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) @@ -534,6 +1037,16 @@ do | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; + -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) + ac_prev=pdfdir ;; + -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) + pdfdir=$ac_optarg ;; + + -psdir | --psdir | --psdi | --psd | --ps) + ac_prev=psdir ;; + -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) + psdir=$ac_optarg ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; @@ -584,26 +1097,36 @@ do ac_init_version=: ;; -with-* | --with-*) - ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. - expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && - { echo "$as_me: error: invalid package name: $ac_package" >&2 - { (exit 1); exit 1; }; } - ac_package=`echo $ac_package| sed 's/-/_/g'` - case $ac_option in - *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; - *) ac_optarg=yes ;; + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" + ac_unrecognized_sep=', ';; esac - eval "with_$ac_package='$ac_optarg'" ;; + eval with_$ac_useropt=\$ac_optarg ;; -without-* | --without-*) - ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` + ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. - expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && - { echo "$as_me: error: invalid package name: $ac_package" >&2 - { (exit 1); exit 1; }; } - ac_package=`echo $ac_package | sed 's/-/_/g'` - eval "with_$ac_package=no" ;; + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=no ;; --x) # Obsolete; use --with-x. @@ -623,27 +1146,26 @@ do | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; - -*) { echo "$as_me: error: unrecognized option: $ac_option -Try \`$0 --help' for more information." >&2 - { (exit 1); exit 1; }; } + -*) as_fn_error $? "unrecognized option: \`$ac_option' +Try \`$0 --help' for more information" ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. - expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && - { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 - { (exit 1); exit 1; }; } - ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` - eval "$ac_envvar='$ac_optarg'" + case $ac_envvar in #( + '' | [0-9]* | *[!_$as_cr_alnum]* ) + as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; + esac + eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. - echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && - echo "$as_me: WARNING: invalid host type: $ac_option" >&2 - : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} + $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" ;; esac @@ -651,31 +1173,36 @@ done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` - { echo "$as_me: error: missing argument to $ac_option" >&2 - { (exit 1); exit 1; }; } + as_fn_error $? "missing argument to $ac_option" fi -# Be sure to have absolute paths. -for ac_var in exec_prefix prefix -do - eval ac_val=$`echo $ac_var` - case $ac_val in - [\\/$]* | ?:[\\/]* | NONE | '' ) ;; - *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 - { (exit 1); exit 1; }; };; +if test -n "$ac_unrecognized_opts"; then + case $enable_option_checking in + no) ;; + fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; + *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; esac -done +fi -# Be sure to have absolute paths. -for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \ - localstatedir libdir includedir oldincludedir infodir mandir +# Check all directory arguments for consistency. +for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ + libdir localedir mandir do - eval ac_val=$`echo $ac_var` + eval ac_val=\$$ac_var + # Remove trailing slashes. case $ac_val in - [\\/$]* | ?:[\\/]* ) ;; - *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 - { (exit 1); exit 1; }; };; + */ ) + ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` + eval $ac_var=\$ac_val;; esac + # Be sure to have absolute directory names. + case $ac_val in + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + esac + as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" done # There might be people who depend on the old broken behavior: `$host' @@ -689,8 +1216,8 @@ target=$target_alias if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe - echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. - If a cross compiler is detected then cross compile mode will be used." >&2 + $as_echo "$as_me: WARNING: if you wanted to set the --build type, don't use --host. + If a cross compiler is detected then cross compile mode will be used" >&2 elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi @@ -702,74 +1229,72 @@ test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null +ac_pwd=`pwd` && test -n "$ac_pwd" && +ac_ls_di=`ls -di .` && +ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || + as_fn_error $? "working directory cannot be determined" +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + as_fn_error $? "pwd does not report name of working directory" + + # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes - # Try the directory containing this script, then its parent. - ac_confdir=`(dirname "$0") 2>/dev/null || -$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$0" : 'X\(//\)[^/]' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)' \| \ - . : '\(.\)' 2>/dev/null || -echo X"$0" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } - /^X\(\/\/\)[^/].*/{ s//\1/; q; } - /^X\(\/\/\)$/{ s//\1/; q; } - /^X\(\/\).*/{ s//\1/; q; } - s/.*/./; q'` + # Try the directory containing this script, then the parent directory. + ac_confdir=`$as_dirname -- "$as_myself" || +$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_myself" : 'X\(//\)[^/]' \| \ + X"$as_myself" : 'X\(//\)$' \| \ + X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_myself" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` srcdir=$ac_confdir - if test ! -r $srcdir/$ac_unique_file; then + if test ! -r "$srcdir/$ac_unique_file"; then srcdir=.. fi else ac_srcdir_defaulted=no fi -if test ! -r $srcdir/$ac_unique_file; then - if test "$ac_srcdir_defaulted" = yes; then - { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2 - { (exit 1); exit 1; }; } - else - { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 - { (exit 1); exit 1; }; } - fi -fi -(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null || - { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2 - { (exit 1); exit 1; }; } -srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'` -ac_env_build_alias_set=${build_alias+set} -ac_env_build_alias_value=$build_alias -ac_cv_env_build_alias_set=${build_alias+set} -ac_cv_env_build_alias_value=$build_alias -ac_env_host_alias_set=${host_alias+set} -ac_env_host_alias_value=$host_alias -ac_cv_env_host_alias_set=${host_alias+set} -ac_cv_env_host_alias_value=$host_alias -ac_env_target_alias_set=${target_alias+set} -ac_env_target_alias_value=$target_alias -ac_cv_env_target_alias_set=${target_alias+set} -ac_cv_env_target_alias_value=$target_alias -ac_env_CC_set=${CC+set} -ac_env_CC_value=$CC -ac_cv_env_CC_set=${CC+set} -ac_cv_env_CC_value=$CC -ac_env_CFLAGS_set=${CFLAGS+set} -ac_env_CFLAGS_value=$CFLAGS -ac_cv_env_CFLAGS_set=${CFLAGS+set} -ac_cv_env_CFLAGS_value=$CFLAGS -ac_env_LDFLAGS_set=${LDFLAGS+set} -ac_env_LDFLAGS_value=$LDFLAGS -ac_cv_env_LDFLAGS_set=${LDFLAGS+set} -ac_cv_env_LDFLAGS_value=$LDFLAGS -ac_env_CPPFLAGS_set=${CPPFLAGS+set} -ac_env_CPPFLAGS_value=$CPPFLAGS -ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set} -ac_cv_env_CPPFLAGS_value=$CPPFLAGS -ac_env_CPP_set=${CPP+set} -ac_env_CPP_value=$CPP -ac_cv_env_CPP_set=${CPP+set} -ac_cv_env_CPP_value=$CPP +if test ! -r "$srcdir/$ac_unique_file"; then + test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." + as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" +fi +ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +ac_abs_confdir=`( + cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" + pwd)` +# When building in place, set srcdir=. +if test "$ac_abs_confdir" = "$ac_pwd"; then + srcdir=. +fi +# Remove unnecessary trailing slashes from srcdir. +# Double slashes in file names in object file debugging info +# mess up M-x gdb in Emacs. +case $srcdir in +*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +esac +for ac_var in $ac_precious_vars; do + eval ac_env_${ac_var}_set=\${${ac_var}+set} + eval ac_env_${ac_var}_value=\$${ac_var} + eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} + eval ac_cv_env_${ac_var}_value=\$${ac_var} +done # # Report the --help message. @@ -792,20 +1317,17 @@ Configuration: --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit - -q, --quiet, --silent do not print \`checking...' messages + -q, --quiet, --silent do not print \`checking ...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] -_ACEOF - - cat <<_ACEOF Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX - [$ac_default_prefix] + [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX - [PREFIX] + [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify @@ -815,18 +1337,25 @@ for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: - --bindir=DIR user executables [EPREFIX/bin] - --sbindir=DIR system admin executables [EPREFIX/sbin] - --libexecdir=DIR program executables [EPREFIX/libexec] - --datadir=DIR read-only architecture-independent data [PREFIX/share] - --sysconfdir=DIR read-only single-machine data [PREFIX/etc] - --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] - --localstatedir=DIR modifiable single-machine data [PREFIX/var] - --libdir=DIR object code libraries [EPREFIX/lib] - --includedir=DIR C header files [PREFIX/include] - --oldincludedir=DIR C header files for non-gcc [/usr/include] - --infodir=DIR info documentation [PREFIX/info] - --mandir=DIR man documentation [PREFIX/man] + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --infodir=DIR info documentation [DATAROOTDIR/info] + --localedir=DIR locale-dependent data [DATAROOTDIR/locale] + --mandir=DIR man documentation [DATAROOTDIR/man] + --docdir=DIR documentation root [DATAROOTDIR/doc/PACKAGE] + --htmldir=DIR html documentation [DOCDIR] + --dvidir=DIR dvi documentation [DOCDIR] + --pdfdir=DIR pdf documentation [DOCDIR] + --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF @@ -838,6 +1367,7 @@ if test -n "$ac_init_help"; then cat <<\_ACEOF Optional Features: + --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --enable-threads build with threads (default: on) @@ -853,168 +1383,393 @@ Optional Packages: --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-encoding encoding for configuration values --with-celib=DIR use Windows/CE support library from DIR + --with-zlib use Native Zlib library Some influential environment variables: CC C compiler command CFLAGS C compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory - CPPFLAGS C/C++ preprocessor flags, e.g. -I if you have - headers in a nonstandard directory + LIBS libraries to pass to the linker, e.g. -l + CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if + you have headers in a nonstandard directory CPP C preprocessor Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. +Report bugs to the package provider. _ACEOF +ac_status=$? fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. - ac_popdir=`pwd` for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue - test -d $ac_dir || continue + test -d "$ac_dir" || + { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || + continue ac_builddir=. -if test "$ac_dir" != .; then - ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` - # A "../" for each directory in $ac_dir_suffix. - ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` -else - ac_dir_suffix= ac_top_builddir= -fi +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix case $srcdir in - .) # No --srcdir option. We are building in place. + .) # We are building in place. ac_srcdir=. - if test -z "$ac_top_builddir"; then - ac_top_srcdir=. - else - ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` - fi ;; - [\\/]* | ?:[\\/]* ) # Absolute path. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; - ac_top_srcdir=$srcdir ;; - *) # Relative path. - ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix - ac_top_srcdir=$ac_top_builddir$srcdir ;; -esac - -# Do not use `cd foo && pwd` to compute absolute paths, because -# the directories may not exist. -case `pwd` in -.) ac_abs_builddir="$ac_dir";; -*) - case "$ac_dir" in - .) ac_abs_builddir=`pwd`;; - [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; - *) ac_abs_builddir=`pwd`/"$ac_dir";; - esac;; -esac -case $ac_abs_builddir in -.) ac_abs_top_builddir=${ac_top_builddir}.;; -*) - case ${ac_top_builddir}. in - .) ac_abs_top_builddir=$ac_abs_builddir;; - [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; - *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; - esac;; -esac -case $ac_abs_builddir in -.) ac_abs_srcdir=$ac_srcdir;; -*) - case $ac_srcdir in - .) ac_abs_srcdir=$ac_abs_builddir;; - [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; - *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; - esac;; -esac -case $ac_abs_builddir in -.) ac_abs_top_srcdir=$ac_top_srcdir;; -*) - case $ac_top_srcdir in - .) ac_abs_top_srcdir=$ac_abs_builddir;; - [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; - *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; - esac;; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac - - cd $ac_dir - # Check for guested configure; otherwise get Cygnus style configure. - if test -f $ac_srcdir/configure.gnu; then - echo - $SHELL $ac_srcdir/configure.gnu --help=recursive - elif test -f $ac_srcdir/configure; then - echo - $SHELL $ac_srcdir/configure --help=recursive - elif test -f $ac_srcdir/configure.ac || - test -f $ac_srcdir/configure.in; then - echo - $ac_configure --help +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + cd "$ac_dir" || { ac_status=$?; continue; } + # Check for guested configure. + if test -f "$ac_srcdir/configure.gnu"; then + echo && + $SHELL "$ac_srcdir/configure.gnu" --help=recursive + elif test -f "$ac_srcdir/configure"; then + echo && + $SHELL "$ac_srcdir/configure" --help=recursive else - echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 - fi - cd $ac_popdir + $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi || ac_status=$? + cd "$ac_pwd" || { ac_status=$?; break; } done fi -test -n "$ac_init_help" && exit 0 +test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF +configure +generated by GNU Autoconf 2.68 -Copyright (C) 2003 Free Software Foundation, Inc. +Copyright (C) 2010 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF - exit 0 + exit fi -exec 5>config.log -cat >&5 <<_ACEOF -This file contains any messages produced by compilers while -running configure, to aid debugging if configure makes a mistake. - -It was created by $as_me, which was -generated by GNU Autoconf 2.59. Invocation command line was - $ $0 $@ +## ------------------------ ## +## Autoconf initialization. ## +## ------------------------ ## -_ACEOF +# ac_fn_c_try_compile LINENO +# -------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_compile () { -cat <<_ASUNAME -## --------- ## -## Platform. ## -## --------- ## + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 -hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` -uname -m = `(uname -m) 2>/dev/null || echo unknown` -uname -r = `(uname -r) 2>/dev/null || echo unknown` -uname -s = `(uname -s) 2>/dev/null || echo unknown` -uname -v = `(uname -v) 2>/dev/null || echo unknown` + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval -/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` -/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` +} # ac_fn_c_try_compile -/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` -/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` -/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` -hostinfo = `(hostinfo) 2>/dev/null || echo unknown` -/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` -/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` -/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` +# ac_fn_c_try_cpp LINENO +# ---------------------- +# Try to preprocess conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_cpp () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } > conftest.i && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 -_ASUNAME + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - echo "PATH: $as_dir" -done +} # ac_fn_c_try_cpp -} >&5 +# ac_fn_c_try_run LINENO +# ---------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes +# that executables *can* be run. +ac_fn_c_try_run () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then : + ac_retval=0 +else + $as_echo "$as_me: program exited with status $ac_status" >&5 + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 -cat >&5 <<_ACEOF + ac_retval=$ac_status +fi + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_run + +# ac_fn_c_check_decl LINENO SYMBOL VAR INCLUDES +# --------------------------------------------- +# Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR +# accordingly. +ac_fn_c_check_decl () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + as_decl_name=`echo $2|sed 's/ *(.*//'` + as_decl_use=`echo $2|sed -e 's/(/((/' -e 's/)/) 0&/' -e 's/,/) 0& (/g'` + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $as_decl_name is declared" >&5 +$as_echo_n "checking whether $as_decl_name is declared... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +#ifndef $as_decl_name +#ifdef __cplusplus + (void) $as_decl_use; +#else + (void) $as_decl_name; +#endif +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_decl + +# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists and can be compiled using the include files in +# INCLUDES, setting the cache variable VAR accordingly. +ac_fn_c_check_header_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_header_compile + +# ac_fn_c_check_type LINENO TYPE VAR INCLUDES +# ------------------------------------------- +# Tests whether TYPE exists after having included INCLUDES, setting cache +# variable VAR accordingly. +ac_fn_c_check_type () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=no" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +if (sizeof ($2)) + return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +if (sizeof (($2))) + return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + eval "$3=yes" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_type +cat >config.log <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by $as_me, which was +generated by GNU Autoconf 2.68. Invocation command line was + + $ $0 $@ + +_ACEOF +exec 5>>config.log +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + $as_echo "PATH: $as_dir" + done +IFS=$as_save_IFS + +} >&5 + +cat >&5 <<_ACEOF ## ----------- ## @@ -1032,7 +1787,6 @@ _ACEOF ac_configure_args= ac_configure_args0= ac_configure_args1= -ac_sep= ac_must_keep_next=false for ac_pass in 1 2 do @@ -1043,13 +1797,13 @@ do -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; - *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) - ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + *\'*) + ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in - 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; + 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; 2) - ac_configure_args1="$ac_configure_args1 '$ac_arg'" + as_fn_append ac_configure_args1 " '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else @@ -1065,104 +1819,115 @@ do -* ) ac_must_keep_next=true ;; esac fi - ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'" - # Get rid of the leading space. - ac_sep=" " + as_fn_append ac_configure_args " '$ac_arg'" ;; esac done done -$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } -$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; } +{ ac_configure_args0=; unset ac_configure_args0;} +{ ac_configure_args1=; unset ac_configure_args1;} # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. -# WARNING: Be sure not to use single quotes in there, as some shells, -# such as our DU 5.0 friend, will then `close' the trap. +# WARNING: Use '\'' to represent an apostrophe within the trap. +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo - cat <<\_ASBOX -## ---------------- ## + $as_echo "## ---------------- ## ## Cache variables. ## -## ---------------- ## -_ASBOX +## ---------------- ##" echo # The following way of writing the cache mishandles newlines in values, -{ +( + for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done (set) 2>&1 | - case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in - *ac_space=\ *) + case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( + *${as_nl}ac_space=\ *) sed -n \ - "s/'"'"'/'"'"'\\\\'"'"''"'"'/g; - s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p" - ;; + "s/'\''/'\''\\\\'\'''\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" + ;; #( *) - sed -n \ - "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; - esac; -} + esac | + sort +) echo - cat <<\_ASBOX -## ----------------- ## + $as_echo "## ----------------- ## ## Output variables. ## -## ----------------- ## -_ASBOX +## ----------------- ##" echo for ac_var in $ac_subst_vars do - eval ac_val=$`echo $ac_var` - echo "$ac_var='"'"'$ac_val'"'"'" + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then - cat <<\_ASBOX -## ------------- ## -## Output files. ## -## ------------- ## -_ASBOX + $as_echo "## ------------------- ## +## File substitutions. ## +## ------------------- ##" echo for ac_var in $ac_subst_files do - eval ac_val=$`echo $ac_var` - echo "$ac_var='"'"'$ac_val'"'"'" + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then - cat <<\_ASBOX -## ----------- ## + $as_echo "## ----------- ## ## confdefs.h. ## -## ----------- ## -_ASBOX +## ----------- ##" echo - sed "/^$/d" confdefs.h | sort + cat confdefs.h echo fi test "$ac_signal" != 0 && - echo "$as_me: caught signal $ac_signal" - echo "$as_me: exit $exit_status" + $as_echo "$as_me: caught signal $ac_signal" + $as_echo "$as_me: exit $exit_status" } >&5 - rm -f core *.core && - rm -rf conftest* confdefs* conf$$* $ac_clean_files && + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status - ' 0 +' 0 for ac_signal in 1 2 13 15; do - trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal + trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. -rm -rf conftest* confdefs.h -# AIX cpp loses on an empty file, so make sure it contains at least a newline. -echo >confdefs.h +rm -f -r conftest* confdefs.h + +$as_echo "/* confdefs.h */" > confdefs.h # Predefined preprocessor variables. @@ -1170,112 +1935,137 @@ cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF - cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF - cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF - cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF - cat >>confdefs.h <<_ACEOF #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF +cat >>confdefs.h <<_ACEOF +#define PACKAGE_URL "$PACKAGE_URL" +_ACEOF + # Let the site file select an alternate cache file if it wants to. -# Prefer explicitly selected file to automatically selected ones. -if test -z "$CONFIG_SITE"; then - if test "x$prefix" != xNONE; then - CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" - else - CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" - fi +# Prefer an explicitly selected file to automatically selected ones. +ac_site_file1=NONE +ac_site_file2=NONE +if test -n "$CONFIG_SITE"; then + # We do not want a PATH search for config.site. + case $CONFIG_SITE in #(( + -*) ac_site_file1=./$CONFIG_SITE;; + */*) ac_site_file1=$CONFIG_SITE;; + *) ac_site_file1=./$CONFIG_SITE;; + esac +elif test "x$prefix" != xNONE; then + ac_site_file1=$prefix/share/config.site + ac_site_file2=$prefix/etc/config.site +else + ac_site_file1=$ac_default_prefix/share/config.site + ac_site_file2=$ac_default_prefix/etc/config.site fi -for ac_site_file in $CONFIG_SITE; do - if test -r "$ac_site_file"; then - { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 -echo "$as_me: loading site script $ac_site_file" >&6;} +for ac_site_file in "$ac_site_file1" "$ac_site_file2" +do + test "x$ac_site_file" = xNONE && continue + if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 +$as_echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 - . "$ac_site_file" + . "$ac_site_file" \ + || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "failed to load site script $ac_site_file +See \`config.log' for more details" "$LINENO" 5 ; } fi done if test -r "$cache_file"; then - # Some versions of bash will fail to source /dev/null (special - # files actually), so we avoid doing that. - if test -f "$cache_file"; then - { echo "$as_me:$LINENO: loading cache $cache_file" >&5 -echo "$as_me: loading cache $cache_file" >&6;} + # Some versions of bash will fail to source /dev/null (special files + # actually), so we avoid doing that. DJGPP emulates it as a regular file. + if test /dev/null != "$cache_file" && test -f "$cache_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 +$as_echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in - [\\/]* | ?:[\\/]* ) . $cache_file;; - *) . ./$cache_file;; + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; esac fi else - { echo "$as_me:$LINENO: creating cache $cache_file" >&5 -echo "$as_me: creating cache $cache_file" >&6;} + { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 +$as_echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false -for ac_var in `(set) 2>&1 | - sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do +for ac_var in $ac_precious_vars; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set - eval ac_old_val="\$ac_cv_env_${ac_var}_value" - eval ac_new_val="\$ac_env_${ac_var}_value" + eval ac_old_val=\$ac_cv_env_${ac_var}_value + eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) - { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 -echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) - { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 -echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then - { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 -echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} - { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 -echo "$as_me: former value: $ac_old_val" >&2;} - { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 -echo "$as_me: current value: $ac_new_val" >&2;} - ac_cache_corrupted=: + # differences in whitespace do not lead to failure. + ac_old_val_w=`echo x $ac_old_val` + ac_new_val_w=`echo x $ac_new_val` + if test "$ac_old_val_w" != "$ac_new_val_w"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 +$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + ac_cache_corrupted=: + else + { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 +$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} + eval $ac_var=\$ac_old_val + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 +$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 +$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in - *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) - ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. - *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; + *) as_fn_append ac_configure_args " '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then - { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 -echo "$as_me: error: changes in the environment can compromise the build" >&2;} - { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 -echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} - { (exit 1); exit 1; }; } + { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 +$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} + as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 fi +## -------------------- ## +## Main body of script. ## +## -------------------- ## ac_ext=c ac_cpp='$CPP $CPPFLAGS' @@ -1286,23 +2076,6 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu - - - - - - - - - - - - - - - - - # The following define is needed when building with Cygwin since newer # versions of autoconf incorrectly set SHELL to /bin/bash instead of # /bin/sh. The bash shell seems to suffer from some strange failures. @@ -1362,10 +2135,10 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. @@ -1375,35 +2148,37 @@ for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="${ac_tool_prefix}gcc" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done -done + done +IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then - echo "$as_me:$LINENO: result: $CC" >&5 -echo "${ECHO_T}$CC" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } fi + fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_ac_ct_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. @@ -1413,39 +2188,50 @@ for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="gcc" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done -done + done +IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then - echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 -echo "${ECHO_T}$ac_ct_CC" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } fi - CC=$ac_ct_CC + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. @@ -1455,77 +2241,37 @@ for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="${ac_tool_prefix}cc" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done -done + done +IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then - echo "$as_me:$LINENO: result: $CC" >&5 -echo "${ECHO_T}$CC" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - -fi -if test -z "$ac_cv_prog_CC"; then - ac_ct_CC=$CC - # Extract the first word of "cc", so it can be a program name with args. -set dummy cc; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_ac_ct_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$ac_ct_CC"; then - ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_CC="cc" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -fi -fi -ac_ct_CC=$ac_cv_prog_ac_ct_CC -if test -n "$ac_ct_CC"; then - echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 -echo "${ECHO_T}$ac_ct_CC" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } fi - CC=$ac_ct_CC -else - CC="$ac_cv_prog_CC" -fi + fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. @@ -1536,18 +2282,19 @@ for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done -done + done +IFS=$as_save_IFS if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. @@ -1565,24 +2312,25 @@ fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then - echo "$as_me:$LINENO: result: $CC" >&5 -echo "${ECHO_T}$CC" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } fi + fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then - for ac_prog in cl + for ac_prog in cl.exe do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. @@ -1592,39 +2340,41 @@ for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done -done + done +IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then - echo "$as_me:$LINENO: result: $CC" >&5 -echo "${ECHO_T}$CC" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } fi + test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC - for ac_prog in cl + for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_ac_ct_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. @@ -1634,66 +2384,78 @@ for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="$ac_prog" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done -done + done +IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then - echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 -echo "${ECHO_T}$ac_ct_CC" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } fi + test -n "$ac_ct_CC" && break done - CC=$ac_ct_CC + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi fi fi -test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH -See \`config.log' for more details." >&5 -echo "$as_me: error: no acceptable C compiler found in \$PATH -See \`config.log' for more details." >&2;} - { (exit 1); exit 1; }; } +test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "no acceptable C compiler found in \$PATH +See \`config.log' for more details" "$LINENO" 5 ; } # Provide some information about the compiler. -echo "$as_me:$LINENO:" \ - "checking for C compiler version" >&5 -ac_compiler=`set X $ac_compile; echo $2` -{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version &5\"") >&5 - (eval $ac_compiler --version &5) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } -{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v &5\"") >&5 - (eval $ac_compiler -v &5) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } -{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V &5\"") >&5 - (eval $ac_compiler -V &5) 2>&5 +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF +cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int @@ -1705,112 +2467,108 @@ main () } _ACEOF ac_clean_files_save=$ac_clean_files -ac_clean_files="$ac_clean_files a.out a.exe b.out" +ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. -echo "$as_me:$LINENO: checking for C compiler default output file name" >&5 -echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6 -ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` -if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5 - (eval $ac_link_default) 2>&5 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 +$as_echo_n "checking whether the C compiler works... " >&6; } +ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` + +# The possible output files: +ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" + +ac_rmfiles= +for ac_file in $ac_files +do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + * ) ac_rmfiles="$ac_rmfiles $ac_file";; + esac +done +rm -f $ac_rmfiles + +if { { ac_try="$ac_link_default" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link_default") 2>&5 ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; then - # Find the output, starting from the most likely. This scheme is -# not robust to junk in `.', hence go to wildcards (a.*) only as a last -# resort. - -# Be careful to initialize this variable, since it used to be cached. -# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile. -ac_cv_exeext= -# b.out is created by i960 compilers. -for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. +# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' +# in a Makefile. We should not override ac_cv_exeext if it was cached, +# so that the user can short-circuit this test for compilers unknown to +# Autoconf. +for ac_file in $ac_files '' do test -f "$ac_file" || continue case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) - ;; - conftest.$ac_ext ) - # This is the source file. + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) - ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` - # FIXME: I believe we export ac_cv_exeext for Libtool, - # but it would be cool to find out if it's true. Does anybody - # maintain Libtool? --akim. - export ac_cv_exeext + if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; + then :; else + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + fi + # We set ac_cv_exeext here because the later test for it is not + # safe: cross compilers may not add the suffix if given an `-o' + # argument, so we may need to know it at that point already. + # Even if this section looks crufty: it has the advantage of + # actually working. break;; * ) break;; esac done +test "$ac_cv_exeext" = no && ac_cv_exeext= + else - echo "$as_me: failed program was:" >&5 + ac_file='' +fi +if test -z "$ac_file"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +$as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 -{ { echo "$as_me:$LINENO: error: C compiler cannot create executables -See \`config.log' for more details." >&5 -echo "$as_me: error: C compiler cannot create executables -See \`config.log' for more details." >&2;} - { (exit 77); exit 77; }; } +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "C compiler cannot create executables +See \`config.log' for more details" "$LINENO" 5 ; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } fi - +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 +$as_echo_n "checking for C compiler default output file name... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 +$as_echo "$ac_file" >&6; } ac_exeext=$ac_cv_exeext -echo "$as_me:$LINENO: result: $ac_file" >&5 -echo "${ECHO_T}$ac_file" >&6 - -# Check the compiler produces executables we can run. If not, either -# the compiler is broken, or we cross compile. -echo "$as_me:$LINENO: checking whether the C compiler works" >&5 -echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6 -# FIXME: These cross compiler hacks should be removed for Autoconf 3.0 -# If not cross compiling, check that we can run a simple program. -if test "$cross_compiling" != yes; then - if { ac_try='./$ac_file' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - cross_compiling=no - else - if test "$cross_compiling" = maybe; then - cross_compiling=yes - else - { { echo "$as_me:$LINENO: error: cannot run C compiled programs. -If you meant to cross compile, use \`--host'. -See \`config.log' for more details." >&5 -echo "$as_me: error: cannot run C compiled programs. -If you meant to cross compile, use \`--host'. -See \`config.log' for more details." >&2;} - { (exit 1); exit 1; }; } - fi - fi -fi -echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6 -rm -f a.out a.exe conftest$ac_cv_exeext b.out +rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save -# Check the compiler produces executables we can run. If not, either -# the compiler is broken, or we cross compile. -echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 -echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6 -echo "$as_me:$LINENO: result: $cross_compiling" >&5 -echo "${ECHO_T}$cross_compiling" >&6 - -echo "$as_me:$LINENO: checking for suffix of executables" >&5 -echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6 -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 +$as_echo_n "checking for suffix of executables... " >&6; } +if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; then + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with @@ -1818,88 +2576,141 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;; + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` - export ac_cv_exeext break;; * ) break;; esac done else - { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link -See \`config.log' for more details." >&5 -echo "$as_me: error: cannot compute suffix of executables: cannot compile and link -See \`config.log' for more details." >&2;} - { (exit 1); exit 1; }; } + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details" "$LINENO" 5 ; } fi - -rm -f conftest$ac_cv_exeext -echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 -echo "${ECHO_T}$ac_cv_exeext" >&6 +rm -f conftest conftest$ac_cv_exeext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 +$as_echo "$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT -echo "$as_me:$LINENO: checking for suffix of object files" >&5 -echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6 -if test "${ac_cv_objext+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF +cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ - +#include int main () { +FILE *f = fopen ("conftest.out", "w"); + return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF -rm -f conftest.o conftest.obj -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 +ac_clean_files="$ac_clean_files conftest.out" +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 +$as_echo_n "checking whether we are cross compiling... " >&6; } +if test "$cross_compiling" != yes; then + { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; then - for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;; - *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` - break;; - esac -done -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile -See \`config.log' for more details." >&5 -echo "$as_me: error: cannot compute suffix of object files: cannot compile -See \`config.log' for more details." >&2;} - { (exit 1); exit 1; }; } -fi - -rm -f conftest.$ac_cv_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 -echo "${ECHO_T}$ac_cv_objext" >&6 -OBJEXT=$ac_cv_objext -ac_objext=$OBJEXT -echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 -echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6 -if test "${ac_cv_c_compiler_gnu+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if { ac_try='./conftest$ac_cv_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details" "$LINENO" 5 ; } + fi + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 +$as_echo "$cross_compiling" >&6; } + +rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 +$as_echo_n "checking for suffix of object files... " >&6; } +if ${ac_cv_objext+:} false; then : + $as_echo_n "(cached) " >&6 else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} _ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF +rm -f conftest.o conftest.obj +if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + for ac_file in conftest.o conftest.obj conftest.*; do + test -f "$ac_file" || continue; + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of object files: cannot compile +See \`config.log' for more details" "$LINENO" 5 ; } +fi +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 +$as_echo "$ac_cv_objext" >&6; } +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 +$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } +if ${ac_cv_c_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int @@ -1913,55 +2724,34 @@ main () return 0; } _ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then +if ac_fn_c_try_compile "$LINENO"; then : ac_compiler_gnu=yes else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_compiler_gnu=no + ac_compiler_gnu=no fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi -echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 -echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6 -GCC=`test $ac_compiler_gnu = yes && echo yes` +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 +$as_echo "$ac_cv_c_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GCC=yes +else + GCC= +fi ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS -CFLAGS="-g" -echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 -echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6 -if test "${ac_cv_prog_cc_g+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 +$as_echo_n "checking whether $CC accepts -g... " >&6; } +if ${ac_cv_prog_cc_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int @@ -1972,39 +2762,49 @@ main () return 0; } _ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then +if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 + CFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ -ac_cv_prog_cc_g=no + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag fi -echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 -echo "${ECHO_T}$ac_cv_prog_cc_g" >&6 +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 +$as_echo "$ac_cv_prog_cc_g" >&6; } if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then @@ -2020,18 +2820,14 @@ else CFLAGS= fi fi -echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5 -echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6 -if test "${ac_cv_prog_cc_stdc+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 +$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } +if ${ac_cv_prog_cc_c89+:} false; then : + $as_echo_n "(cached) " >&6 else - ac_cv_prog_cc_stdc=no + ac_cv_prog_cc_c89=no ac_save_CC=$CC -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF +cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include @@ -2059,12 +2855,17 @@ static char *f (char * (*g) (char **, int), char **p, ...) /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated - as 'x'. The following induces an error, until -std1 is added to get + as 'x'. The following induces an error, until -std is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something - that's true only with -std1. */ + that's true only with -std. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; @@ -2079,205 +2880,37 @@ return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; return 0; } _ACEOF -# Don't try gcc -ansi; that turns off useful extensions and -# breaks some systems' header files. -# AIX -qlanglvl=ansi -# Ultrix and OSF/1 -std1 -# HP-UX 10.20 and later -Ae -# HP-UX older versions -Aa -D_HPUX_SOURCE -# SVR4 -Xc -D__EXTENSIONS__ -for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" - rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_prog_cc_stdc=$ac_arg -break -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_c89=$ac_arg fi -rm -f conftest.err conftest.$ac_objext +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break done -rm -f conftest.$ac_ext conftest.$ac_objext +rm -f conftest.$ac_ext CC=$ac_save_CC fi - -case "x$ac_cv_prog_cc_stdc" in - x|xno) - echo "$as_me:$LINENO: result: none needed" >&5 -echo "${ECHO_T}none needed" >&6 ;; +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; + xno) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; *) - echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5 -echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6 - CC="$CC $ac_cv_prog_cc_stdc" ;; + CC="$CC $ac_cv_prog_cc_c89" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 +$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; esac +if test "x$ac_cv_prog_cc_c89" != xno; then : -# Some people use a C++ compiler to compile C. Since we use `exit', -# in C++ we need to declare it. In case someone uses the same compiler -# for both compiling C and C++ we need to have the C++ compiler decide -# the declaration of exit, since it's the most demanding environment. -cat >conftest.$ac_ext <<_ACEOF -#ifndef __cplusplus - choke me -#endif -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - for ac_declaration in \ - '' \ - 'extern "C" void std::exit (int) throw (); using std::exit;' \ - 'extern "C" void std::exit (int); using std::exit;' \ - 'extern "C" void exit (int) throw ();' \ - 'extern "C" void exit (int);' \ - 'void exit (int);' -do - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_declaration -#include -int -main () -{ -exit (42); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - : -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -continue -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_declaration -int -main () -{ -exit (42); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - break -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -done -rm -f conftest* -if test -n "$ac_declaration"; then - echo '#ifdef __cplusplus' >>confdefs.h - echo $ac_declaration >>confdefs.h - echo '#endif' >>confdefs.h fi -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' @@ -2285,18 +2918,14 @@ ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $ ac_compiler_gnu=$ac_cv_c_compiler_gnu -echo "$as_me:$LINENO: checking for inline" >&5 -echo $ECHO_N "checking for inline... $ECHO_C" >&6 -if test "${ac_cv_c_inline+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline" >&5 +$as_echo_n "checking for inline... " >&6; } +if ${ac_cv_c_inline+:} false; then : + $as_echo_n "(cached) " >&6 else ac_cv_c_inline=no for ac_kw in inline __inline__ __inline; do - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifndef __cplusplus typedef int foo_t; @@ -2305,41 +2934,16 @@ $ac_kw foo_t foo () {return 0; } #endif _ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_c_inline=$ac_kw; break -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_c_inline=$ac_kw fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + test "$ac_cv_c_inline" != no && break done fi -echo "$as_me:$LINENO: result: $ac_cv_c_inline" >&5 -echo "${ECHO_T}$ac_cv_c_inline" >&6 - +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_inline" >&5 +$as_echo "$ac_cv_c_inline" >&6; } case $ac_cv_c_inline in inline | yes) ;; @@ -2361,15 +2965,15 @@ ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu -echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 -echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 +$as_echo_n "checking how to run the C preprocessor... " >&6; } # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then - if test "${ac_cv_prog_CPP+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + if ${ac_cv_prog_CPP+:} false; then : + $as_echo_n "(cached) " >&6 else # Double quotes because CPP needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" @@ -2383,11 +2987,7 @@ do # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include @@ -2396,78 +2996,34 @@ cat >>conftest.$ac_ext <<_ACEOF #endif Syntax error _ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - : -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 +if ac_fn_c_try_cpp "$LINENO"; then : +else # Broken: fails on valid input. continue fi -rm -f conftest.err conftest.$ac_ext +rm -f conftest.err conftest.i conftest.$ac_ext - # OK, works on sane cases. Now check whether non-existent headers + # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then +if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - # Passes both tests. ac_preproc_ok=: break fi -rm -f conftest.err conftest.$ac_ext +rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.err conftest.$ac_ext -if $ac_preproc_ok; then +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : break fi @@ -2479,8 +3035,8 @@ fi else ac_cv_prog_CPP=$CPP fi -echo "$as_me:$LINENO: result: $CPP" >&5 -echo "${ECHO_T}$CPP" >&6 +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 +$as_echo "$CPP" >&6; } ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do @@ -2490,11 +3046,7 @@ do # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include @@ -2503,85 +3055,40 @@ cat >>conftest.$ac_ext <<_ACEOF #endif Syntax error _ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - : -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 +if ac_fn_c_try_cpp "$LINENO"; then : +else # Broken: fails on valid input. continue fi -rm -f conftest.err conftest.$ac_ext +rm -f conftest.err conftest.i conftest.$ac_ext - # OK, works on sane cases. Now check whether non-existent headers + # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then +if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - # Passes both tests. ac_preproc_ok=: break fi -rm -f conftest.err conftest.$ac_ext +rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.err conftest.$ac_ext -if $ac_preproc_ok; then - : +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + else - { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check -See \`config.log' for more details." >&5 -echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check -See \`config.log' for more details." >&2;} - { (exit 1); exit 1; }; } + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details" "$LINENO" 5 ; } fi ac_ext=c @@ -2591,31 +3098,142 @@ ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $ ac_compiler_gnu=$ac_cv_c_compiler_gnu -echo "$as_me:$LINENO: checking for egrep" >&5 -echo $ECHO_N "checking for egrep... $ECHO_C" >&6 -if test "${ac_cv_prog_egrep+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 +$as_echo_n "checking for grep that handles long lines and -e... " >&6; } +if ${ac_cv_path_GREP+:} false; then : + $as_echo_n "(cached) " >&6 else - if echo a | (grep -E '(a|b)') >/dev/null 2>&1 - then ac_cv_prog_egrep='grep -E' - else ac_cv_prog_egrep='egrep' + if test -z "$GREP"; then + ac_path_GREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in grep ggrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue +# Check for GNU ac_path_GREP and select it if it is found. + # Check for GNU $ac_path_GREP +case `"$ac_path_GREP" --version 2>&1` in +*GNU*) + ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'GREP' >> "conftest.nl" + "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_GREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_GREP="$ac_path_GREP" + ac_path_GREP_max=$ac_count fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_GREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_GREP"; then + as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_GREP=$GREP +fi + fi -echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5 -echo "${ECHO_T}$ac_cv_prog_egrep" >&6 - EGREP=$ac_cv_prog_egrep +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 +$as_echo "$ac_cv_path_GREP" >&6; } + GREP="$ac_cv_path_GREP" -echo "$as_me:$LINENO: checking for ANSI C header files" >&5 -echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6 -if test "${ac_cv_header_stdc+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 +$as_echo_n "checking for egrep... " >&6; } +if ${ac_cv_path_EGREP+:} false; then : + $as_echo_n "(cached) " >&6 else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF + if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 + then ac_cv_path_EGREP="$GREP -E" + else + if test -z "$EGREP"; then + ac_path_EGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in egrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue +# Check for GNU ac_path_EGREP and select it if it is found. + # Check for GNU $ac_path_EGREP +case `"$ac_path_EGREP" --version 2>&1` in +*GNU*) + ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'EGREP' >> "conftest.nl" + "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_EGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_EGREP="$ac_path_EGREP" + ac_path_EGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_EGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_EGREP"; then + as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_EGREP=$EGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 +$as_echo "$ac_cv_path_EGREP" >&6; } + EGREP="$ac_cv_path_EGREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 +$as_echo_n "checking for ANSI C header files... " >&6; } +if ${ac_cv_header_stdc+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include @@ -2630,51 +3248,23 @@ main () return 0; } _ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then +if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_stdc=yes else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_header_stdc=no + ac_cv_header_stdc=no fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "memchr" >/dev/null 2>&1; then - : + $EGREP "memchr" >/dev/null 2>&1; then : + else ac_cv_header_stdc=no fi @@ -2684,18 +3274,14 @@ fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "free" >/dev/null 2>&1; then - : + $EGREP "free" >/dev/null 2>&1; then : + else ac_cv_header_stdc=no fi @@ -2705,16 +3291,13 @@ fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. - if test "$cross_compiling" = yes; then + if test "$cross_compiling" = yes; then : : else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include +#include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) @@ -2734,41 +3317,26 @@ main () for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) - exit(2); - exit (0); + return 2; + return 0; } _ACEOF -rm -f conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - : -else - echo "$as_me: program exited with status $ac_status" >&5 -echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 +if ac_fn_c_try_run "$LINENO"; then : -( exit $ac_status ) -ac_cv_header_stdc=no +else + ac_cv_header_stdc=no fi -rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext fi + fi fi -echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 -echo "${ECHO_T}$ac_cv_header_stdc" >&6 +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 +$as_echo "$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then -cat >>confdefs.h <<\_ACEOF -#define STDC_HEADERS 1 -_ACEOF +$as_echo "#define STDC_HEADERS 1" >>confdefs.h fi @@ -2776,10 +3344,10 @@ fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args. set dummy ${ac_tool_prefix}ar; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_AR+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AR+:} false; then : + $as_echo_n "(cached) " >&6 else if test -n "$AR"; then ac_cv_prog_AR="$AR" # Let the user override the test. @@ -2789,35 +3357,37 @@ for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_AR="${ac_tool_prefix}ar" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done -done + done +IFS=$as_save_IFS fi fi AR=$ac_cv_prog_AR if test -n "$AR"; then - echo "$as_me:$LINENO: result: $AR" >&5 -echo "${ECHO_T}$AR" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 +$as_echo "$AR" >&6; } else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } fi + fi if test -z "$ac_cv_prog_AR"; then ac_ct_AR=$AR # Extract the first word of "ar", so it can be a program name with args. set dummy ar; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_ac_ct_AR+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_AR+:} false; then : + $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_AR"; then ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. @@ -2827,27 +3397,38 @@ for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_AR="ar" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done -done + done +IFS=$as_save_IFS fi fi ac_ct_AR=$ac_cv_prog_ac_ct_AR if test -n "$ac_ct_AR"; then - echo "$as_me:$LINENO: result: $ac_ct_AR" >&5 -echo "${ECHO_T}$ac_ct_AR" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 +$as_echo "$ac_ct_AR" >&6; } else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } fi - AR=$ac_ct_AR + if test "x$ac_ct_AR" = x; then + AR="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + AR=$ac_ct_AR + fi else AR="$ac_cv_prog_AR" fi @@ -2855,10 +3436,10 @@ fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. set dummy ${ac_tool_prefix}ranlib; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_RANLIB+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 else if test -n "$RANLIB"; then ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. @@ -2868,35 +3449,37 @@ for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done -done + done +IFS=$as_save_IFS fi fi RANLIB=$ac_cv_prog_RANLIB if test -n "$RANLIB"; then - echo "$as_me:$LINENO: result: $RANLIB" >&5 -echo "${ECHO_T}$RANLIB" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 +$as_echo "$RANLIB" >&6; } else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } fi + fi if test -z "$ac_cv_prog_RANLIB"; then ac_ct_RANLIB=$RANLIB # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_RANLIB"; then ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. @@ -2906,27 +3489,38 @@ for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_RANLIB="ranlib" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done -done + done +IFS=$as_save_IFS fi fi ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB if test -n "$ac_ct_RANLIB"; then - echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5 -echo "${ECHO_T}$ac_ct_RANLIB" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 +$as_echo "$ac_ct_RANLIB" >&6; } else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } fi - RANLIB=$ac_ct_RANLIB + if test "x$ac_ct_RANLIB" = x; then + RANLIB="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + RANLIB=$ac_ct_RANLIB + fi else RANLIB="$ac_cv_prog_RANLIB" fi @@ -2934,10 +3528,10 @@ fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}windres", so it can be a program name with args. set dummy ${ac_tool_prefix}windres; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_RC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_RC+:} false; then : + $as_echo_n "(cached) " >&6 else if test -n "$RC"; then ac_cv_prog_RC="$RC" # Let the user override the test. @@ -2947,35 +3541,37 @@ for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_RC="${ac_tool_prefix}windres" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done -done + done +IFS=$as_save_IFS fi fi RC=$ac_cv_prog_RC if test -n "$RC"; then - echo "$as_me:$LINENO: result: $RC" >&5 -echo "${ECHO_T}$RC" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RC" >&5 +$as_echo "$RC" >&6; } else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } fi + fi if test -z "$ac_cv_prog_RC"; then ac_ct_RC=$RC # Extract the first word of "windres", so it can be a program name with args. set dummy windres; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_ac_ct_RC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_RC+:} false; then : + $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_RC"; then ac_cv_prog_ac_ct_RC="$ac_ct_RC" # Let the user override the test. @@ -2985,27 +3581,38 @@ for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_RC="windres" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done -done + done +IFS=$as_save_IFS fi fi ac_ct_RC=$ac_cv_prog_ac_ct_RC if test -n "$ac_ct_RC"; then - echo "$as_me:$LINENO: result: $ac_ct_RC" >&5 -echo "${ECHO_T}$ac_ct_RC" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RC" >&5 +$as_echo "$ac_ct_RC" >&6; } else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } fi - RC=$ac_ct_RC + if test "x$ac_ct_RC" = x; then + RC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + RC=$ac_ct_RC + fi else RC="$ac_cv_prog_RC" fi @@ -3015,32 +3622,34 @@ fi # Checks to see if the make program sets the $MAKE variable. #-------------------------------------------------------------------- -echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5 -echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6 -set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y,:./+-,___p_,'` -if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } +set x ${MAKE-make} +ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` +if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : + $as_echo_n "(cached) " >&6 else cat >conftest.make <<\_ACEOF +SHELL = /bin/sh all: - @echo 'ac_maketemp="$(MAKE)"' + @echo '@@@%%%=$(MAKE)=@@@%%%' _ACEOF -# GNU make sometimes prints "make[1]: Entering...", which would confuse us. -eval `${MAKE-make} -f conftest.make 2>/dev/null | grep temp=` -if test -n "$ac_maketemp"; then - eval ac_cv_prog_make_${ac_make}_set=yes -else - eval ac_cv_prog_make_${ac_make}_set=no -fi +# GNU make sometimes prints "make[1]: Entering ...", which would confuse us. +case `${MAKE-make} -f conftest.make 2>/dev/null` in + *@@@%%%=?*=@@@%%%*) + eval ac_cv_prog_make_${ac_make}_set=yes;; + *) + eval ac_cv_prog_make_${ac_make}_set=no;; +esac rm -f conftest.make fi -if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then - echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6 +if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } SET_MAKE= else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } SET_MAKE="MAKE=${MAKE-make}" fi @@ -3057,34 +3666,30 @@ fi #-------------------------------------------------------------------- - echo "$as_me:$LINENO: checking for building with threads" >&5 -echo $ECHO_N "checking for building with threads... $ECHO_C" >&6 - # Check whether --enable-threads or --disable-threads was given. -if test "${enable_threads+set}" = set; then - enableval="$enable_threads" - tcl_ok=$enableval + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for building with threads" >&5 +$as_echo_n "checking for building with threads... " >&6; } + # Check whether --enable-threads was given. +if test "${enable_threads+set}" = set; then : + enableval=$enable_threads; tcl_ok=$enableval else tcl_ok=yes -fi; +fi + if test "$tcl_ok" = "yes"; then - echo "$as_me:$LINENO: result: yes (default)" >&5 -echo "${ECHO_T}yes (default)" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes (default)" >&5 +$as_echo "yes (default)" >&6; } TCL_THREADS=1 - cat >>confdefs.h <<\_ACEOF -#define TCL_THREADS 1 -_ACEOF + $as_echo "#define TCL_THREADS 1" >>confdefs.h # USE_THREAD_ALLOC tells us to try the special thread-based # allocator that significantly reduces lock contention - cat >>confdefs.h <<\_ACEOF -#define USE_THREAD_ALLOC 1 -_ACEOF + $as_echo "#define USE_THREAD_ALLOC 1" >>confdefs.h else TCL_THREADS=0 - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } fi @@ -3095,11 +3700,11 @@ echo "${ECHO_T}no" >&6 -# Check whether --with-encoding or --without-encoding was given. -if test "${with_encoding+set}" = set; then - withval="$with_encoding" - with_tcencoding=${withval} -fi; +# Check whether --with-encoding was given. +if test "${with_encoding+set}" = set; then : + withval=$with_encoding; with_tcencoding=${withval} +fi + if test x"${with_tcencoding}" != x ; then cat >>confdefs.h <<_ACEOF @@ -3108,9 +3713,7 @@ _ACEOF else # Default encoding on windows is not "iso8859-1" - cat >>confdefs.h <<\_ACEOF -#define TCL_CFGVAL_ENCODING "cp1252" -_ACEOF + $as_echo "#define TCL_CFGVAL_ENCODING \"cp1252\"" >>confdefs.h fi @@ -3121,15 +3724,15 @@ _ACEOF #-------------------------------------------------------------------- - echo "$as_me:$LINENO: checking how to build libraries" >&5 -echo $ECHO_N "checking how to build libraries... $ECHO_C" >&6 - # Check whether --enable-shared or --disable-shared was given. -if test "${enable_shared+set}" = set; then - enableval="$enable_shared" - tcl_ok=$enableval + { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to build libraries" >&5 +$as_echo_n "checking how to build libraries... " >&6; } + # Check whether --enable-shared was given. +if test "${enable_shared+set}" = set; then : + enableval=$enable_shared; tcl_ok=$enableval else tcl_ok=yes -fi; +fi + if test "${enable_shared+set}" = set; then enableval="$enable_shared" @@ -3139,17 +3742,15 @@ fi; fi if test "$tcl_ok" = "yes" ; then - echo "$as_me:$LINENO: result: shared" >&5 -echo "${ECHO_T}shared" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: shared" >&5 +$as_echo "shared" >&6; } SHARED_BUILD=1 else - echo "$as_me:$LINENO: result: static" >&5 -echo "${ECHO_T}static" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: static" >&5 +$as_echo "static" >&6; } SHARED_BUILD=0 -cat >>confdefs.h <<\_ACEOF -#define STATIC_BUILD 1 -_ACEOF +$as_echo "#define STATIC_BUILD 1" >>confdefs.h fi @@ -3161,70 +3762,15 @@ _ACEOF #-------------------------------------------------------------------- # On IRIX 5.3, sys/types and inttypes.h are conflicting. - - - - - - - - - for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ inttypes.h stdint.h unistd.h -do -as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` -echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default - -#include <$ac_header> -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - eval "$as_ac_Header=yes" -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -eval "$as_ac_Header=no" -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 -if test `eval echo '${'$as_ac_Header'}'` = yes; then +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default +" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi @@ -3236,59 +3782,57 @@ done # Step 0: Enable 64 bit support? - echo "$as_me:$LINENO: checking if 64bit support is requested" >&5 -echo $ECHO_N "checking if 64bit support is requested... $ECHO_C" >&6 - # Check whether --enable-64bit or --disable-64bit was given. -if test "${enable_64bit+set}" = set; then - enableval="$enable_64bit" - do64bit=$enableval + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if 64bit support is requested" >&5 +$as_echo_n "checking if 64bit support is requested... " >&6; } + # Check whether --enable-64bit was given. +if test "${enable_64bit+set}" = set; then : + enableval=$enable_64bit; do64bit=$enableval else do64bit=no -fi; - echo "$as_me:$LINENO: result: $do64bit" >&5 -echo "${ECHO_T}$do64bit" >&6 +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $do64bit" >&5 +$as_echo "$do64bit" >&6; } # Cross-compiling options for Windows/CE builds - echo "$as_me:$LINENO: checking if Windows/CE build is requested" >&5 -echo $ECHO_N "checking if Windows/CE build is requested... $ECHO_C" >&6 - # Check whether --enable-wince or --disable-wince was given. -if test "${enable_wince+set}" = set; then - enableval="$enable_wince" - doWince=$enableval + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if Windows/CE build is requested" >&5 +$as_echo_n "checking if Windows/CE build is requested... " >&6; } + # Check whether --enable-wince was given. +if test "${enable_wince+set}" = set; then : + enableval=$enable_wince; doWince=$enableval else doWince=no -fi; - echo "$as_me:$LINENO: result: $doWince" >&5 -echo "${ECHO_T}$doWince" >&6 +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $doWince" >&5 +$as_echo "$doWince" >&6; } - echo "$as_me:$LINENO: checking for Windows/CE celib directory" >&5 -echo $ECHO_N "checking for Windows/CE celib directory... $ECHO_C" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Windows/CE celib directory" >&5 +$as_echo_n "checking for Windows/CE celib directory... " >&6; } -# Check whether --with-celib or --without-celib was given. -if test "${with_celib+set}" = set; then - withval="$with_celib" - CELIB_DIR=$withval +# Check whether --with-celib was given. +if test "${with_celib+set}" = set; then : + withval=$with_celib; CELIB_DIR=$withval else CELIB_DIR=NO_CELIB -fi; - echo "$as_me:$LINENO: result: $CELIB_DIR" >&5 -echo "${ECHO_T}$CELIB_DIR" >&6 +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CELIB_DIR" >&5 +$as_echo "$CELIB_DIR" >&6; } # Set some defaults (may get changed below) EXTRA_CFLAGS="" -cat >>confdefs.h <<\_ACEOF -#define MODULE_SCOPE extern -_ACEOF +$as_echo "#define MODULE_SCOPE extern" >>confdefs.h # Extract the first word of "cygpath", so it can be a program name with args. set dummy cygpath; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_CYGPATH+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CYGPATH+:} false; then : + $as_echo_n "(cached) " >&6 else if test -n "$CYGPATH"; then ac_cv_prog_CYGPATH="$CYGPATH" # Let the user override the test. @@ -3298,28 +3842,30 @@ for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CYGPATH="cygpath -w" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done -done + done +IFS=$as_save_IFS test -z "$ac_cv_prog_CYGPATH" && ac_cv_prog_CYGPATH="echo" fi fi CYGPATH=$ac_cv_prog_CYGPATH if test -n "$CYGPATH"; then - echo "$as_me:$LINENO: result: $CYGPATH" >&5 -echo "${ECHO_T}$CYGPATH" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CYGPATH" >&5 +$as_echo "$CYGPATH" >&6; } else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } fi + SHLIB_SUFFIX=".dll" # MACHINE is IX86 for LINK, but this is used by the manifest, @@ -3328,16 +3874,12 @@ fi if test "$GCC" = "yes"; then - echo "$as_me:$LINENO: checking for cross-compile version of gcc" >&5 -echo $ECHO_N "checking for cross-compile version of gcc... $ECHO_C" >&6 -if test "${ac_cv_cross+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for cross-compile version of gcc" >&5 +$as_echo_n "checking for cross-compile version of gcc... " >&6; } +if ${ac_cv_cross+:} false; then : + $as_echo_n "(cached) " >&6 else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifndef _WIN32 @@ -3352,40 +3894,16 @@ main () return 0; } _ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then +if ac_fn_c_try_compile "$LINENO"; then : ac_cv_cross=no else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_cross=yes + ac_cv_cross=yes fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi -echo "$as_me:$LINENO: result: $ac_cv_cross" >&5 -echo "${ECHO_T}$ac_cv_cross" >&6 +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cross" >&5 +$as_echo "$ac_cv_cross" >&6; } if test "$ac_cv_cross" = "yes"; then case "$do64bit" in @@ -3420,20 +3938,20 @@ echo "${ECHO_T}$ac_cv_cross" >&6 echo "101 \"name\"" >> $conftest echo "END" >> $conftest - echo "$as_me:$LINENO: checking for Windows native path bug in windres" >&5 -echo $ECHO_N "checking for Windows native path bug in windres... $ECHO_C" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Windows native path bug in windres" >&5 +$as_echo_n "checking for Windows native path bug in windres... " >&6; } cyg_conftest=`$CYGPATH $conftest` if { ac_try='$RC -o conftest.res.o $cyg_conftest' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5 (eval $ac_try) 2>&5 ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } ; then - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; } ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } else - echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } CYGPATH=echo fi conftest= @@ -3451,16 +3969,12 @@ echo "${ECHO_T}yes" >&6 if test "${GCC}" = "yes" ; then extra_cflags="-pipe" extra_ldflags="-pipe -static-libgcc" - echo "$as_me:$LINENO: checking for mingw32 version of gcc" >&5 -echo $ECHO_N "checking for mingw32 version of gcc... $ECHO_C" >&6 -if test "${ac_cv_win32+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for mingw32 version of gcc" >&5 +$as_echo_n "checking for mingw32 version of gcc... " >&6; } +if ${ac_cv_win32+:} false; then : + $as_echo_n "(cached) " >&6 else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef _WIN32 @@ -3475,57 +3989,73 @@ main () return 0; } _ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then +if ac_fn_c_try_compile "$LINENO"; then : ac_cv_win32=no else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_win32=yes + ac_cv_win32=yes fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi -echo "$as_me:$LINENO: result: $ac_cv_win32" >&5 -echo "${ECHO_T}$ac_cv_win32" >&6 +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_win32" >&5 +$as_echo "$ac_cv_win32" >&6; } if test "$ac_cv_win32" != "yes"; then - { { echo "$as_me:$LINENO: error: ${CC} cannot produce win32 executables." >&5 -echo "$as_me: error: ${CC} cannot produce win32 executables." >&2;} - { (exit 1); exit 1; }; } + as_fn_error $? "${CC} cannot produce win32 executables." "$LINENO" 5 fi hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -mwindows -municode -Dmain=xxmain" - echo "$as_me:$LINENO: checking for working -municode linker flag" >&5 -echo $ECHO_N "checking for working -municode linker flag... $ECHO_C" >&6 -if test "${ac_cv_municode+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working -municode linker flag" >&5 +$as_echo_n "checking for working -municode linker flag... " >&6; } +if ${ac_cv_municode+:} false; then : + $as_echo_n "(cached) " >&6 else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF + +# ac_fn_c_try_link LINENO +# ----------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_link () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest$ac_exeext + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information + # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would + # interfere with the next link command; also delete a directory that is + # left behind by Apple's compiler. We do this before executing the actions. + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_link +cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include @@ -3539,41 +4069,17 @@ main () return 0; } _ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then +if ac_fn_c_try_link "$LINENO"; then : ac_cv_municode=yes else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_municode=no + ac_cv_municode=no fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext fi -echo "$as_me:$LINENO: result: $ac_cv_municode" >&5 -echo "${ECHO_T}$ac_cv_municode" >&6 +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_municode" >&5 +$as_echo "$ac_cv_municode" >&6; } CFLAGS=$hold_cflags if test "$ac_cv_municode" = "yes" ; then extra_ldflags="$extra_ldflags -municode" @@ -3582,8 +4088,8 @@ echo "${ECHO_T}$ac_cv_municode" >&6 fi fi - echo "$as_me:$LINENO: checking compiler flags" >&5 -echo $ECHO_N "checking compiler flags... $ECHO_C" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking compiler flags" >&5 +$as_echo_n "checking compiler flags... " >&6; } if test "${GCC}" = "yes" ; then SHLIB_LD="" SHLIB_LD_LIBS='${LIBS}' @@ -3604,23 +4110,20 @@ echo $ECHO_N "checking compiler flags... $ECHO_C" >&6 if test "${SHARED_BUILD}" = "0" ; then # static - echo "$as_me:$LINENO: result: using static flags" >&5 -echo "${ECHO_T}using static flags" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: using static flags" >&5 +$as_echo "using static flags" >&6; } runtime= LIBRARIES="\${STATIC_LIBRARIES}" EXESUFFIX="s\${DBGX}.exe" else # dynamic - echo "$as_me:$LINENO: result: using shared flags" >&5 -echo "${ECHO_T}using shared flags" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: using shared flags" >&5 +$as_echo "using shared flags" >&6; } # ad-hoc check to see if CC supports -shared. if "${CC}" -shared 2>&1 | egrep ': -shared not supported' >/dev/null; then - { { echo "$as_me:$LINENO: error: ${CC} does not support the -shared option. - You will need to upgrade to a newer version of the toolchain." >&5 -echo "$as_me: error: ${CC} does not support the -shared option. - You will need to upgrade to a newer version of the toolchain." >&2;} - { (exit 1); exit 1; }; } + as_fn_error $? "${CC} does not support the -shared option. + You will need to upgrade to a newer version of the toolchain." "$LINENO" 5 fi runtime= @@ -3674,20 +4177,16 @@ echo "$as_me: error: ${CC} does not support the -shared option. case "$do64bit" in amd64|x64|yes) MACHINE="AMD64" ; # assume AMD64 as default 64-bit build - echo "$as_me:$LINENO: result: Using 64-bit $MACHINE mode" >&5 -echo "${ECHO_T} Using 64-bit $MACHINE mode" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: Using 64-bit $MACHINE mode" >&5 +$as_echo " Using 64-bit $MACHINE mode" >&6; } ;; ia64) MACHINE="IA64" - echo "$as_me:$LINENO: result: Using 64-bit $MACHINE mode" >&5 -echo "${ECHO_T} Using 64-bit $MACHINE mode" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: Using 64-bit $MACHINE mode" >&5 +$as_echo " Using 64-bit $MACHINE mode" >&6; } ;; *) - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifndef _WIN64 @@ -3702,57 +4201,33 @@ main () return 0; } _ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then +if ac_fn_c_try_compile "$LINENO"; then : tcl_win_64bit=yes else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -tcl_win_64bit=no + tcl_win_64bit=no fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test "$tcl_win_64bit" = "yes" ; then do64bit=amd64 MACHINE="AMD64" - echo "$as_me:$LINENO: result: Using 64-bit $MACHINE mode" >&5 -echo "${ECHO_T} Using 64-bit $MACHINE mode" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: Using 64-bit $MACHINE mode" >&5 +$as_echo " Using 64-bit $MACHINE mode" >&6; } fi ;; esac else if test "${SHARED_BUILD}" = "0" ; then # static - echo "$as_me:$LINENO: result: using static flags" >&5 -echo "${ECHO_T}using static flags" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: using static flags" >&5 +$as_echo "using static flags" >&6; } runtime=-MT LIBRARIES="\${STATIC_LIBRARIES}" EXESUFFIX="s\${DBGX}.exe" else # dynamic - echo "$as_me:$LINENO: result: using shared flags" >&5 -echo "${ECHO_T}using shared flags" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: using shared flags" >&5 +$as_echo "using shared flags" >&6; } runtime=-MD # Add SHLIB_LD_LIBS to the Make rule, not here. LIBRARIES="\${SHARED_LIBRARIES}" @@ -3785,14 +4260,14 @@ echo "${ECHO_T}using shared flags" >&6 ;; esac if test ! -d "${PATH64}" ; then - { echo "$as_me:$LINENO: WARNING: Could not find 64-bit $MACHINE SDK to enable 64bit mode" >&5 -echo "$as_me: WARNING: Could not find 64-bit $MACHINE SDK to enable 64bit mode" >&2;} - { echo "$as_me:$LINENO: WARNING: Ensure latest Platform SDK is installed" >&5 -echo "$as_me: WARNING: Ensure latest Platform SDK is installed" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Could not find 64-bit $MACHINE SDK to enable 64bit mode" >&5 +$as_echo "$as_me: WARNING: Could not find 64-bit $MACHINE SDK to enable 64bit mode" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Ensure latest Platform SDK is installed" >&5 +$as_echo "$as_me: WARNING: Ensure latest Platform SDK is installed" >&2;} do64bit="no" else - echo "$as_me:$LINENO: result: Using 64-bit $MACHINE mode" >&5 -echo "${ECHO_T} Using 64-bit $MACHINE mode" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: Using 64-bit $MACHINE mode" >&5 +$as_echo " Using 64-bit $MACHINE mode" >&6; } fi fi @@ -3803,64 +4278,9 @@ echo "${ECHO_T} Using 64-bit $MACHINE mode" >&6 # TEA_PATH_NOSPACE to avoid this issue. # Check if _WIN64 is already recognized, and if so we don't # need to modify CC. - echo "$as_me:$LINENO: checking whether _WIN64 is declared" >&5 -echo $ECHO_N "checking whether _WIN64 is declared... $ECHO_C" >&6 -if test "${ac_cv_have_decl__WIN64+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -int -main () -{ -#ifndef _WIN64 - char *p = (char *) _WIN64; -#endif - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_have_decl__WIN64=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 + ac_fn_c_check_decl "$LINENO" "_WIN64" "ac_cv_have_decl__WIN64" "$ac_includes_default" +if test "x$ac_cv_have_decl__WIN64" = xyes; then : -ac_cv_have_decl__WIN64=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_have_decl__WIN64" >&5 -echo "${ECHO_T}$ac_cv_have_decl__WIN64" >&6 -if test $ac_cv_have_decl__WIN64 = yes; then - : else CC="\"${PATH64}/cl.exe\" -I\"${MSSDK}/Include\" \ -I\"${MSSDK}/Include/crt\" \ @@ -3928,15 +4348,11 @@ fi SDKROOT=`echo "$SDKROOT" | sed -e 's!\\\!/!g'` CELIB_DIR=`echo "$CELIB_DIR" | sed -e 's!\\\!/!g'` if test ! -d "${CELIB_DIR}/inc"; then - { { echo "$as_me:$LINENO: error: Invalid celib directory \"${CELIB_DIR}\"" >&5 -echo "$as_me: error: Invalid celib directory \"${CELIB_DIR}\"" >&2;} - { (exit 1); exit 1; }; } + as_fn_error $? "Invalid celib directory \"${CELIB_DIR}\"" "$LINENO" 5 fi if test ! -d "${SDKROOT}/${OSVERSION}/${PLATFORM}/Lib/${TARGETCPU}"\ -o ! -d "${WCEROOT}/EVC/${OSVERSION}/bin"; then - { { echo "$as_me:$LINENO: error: could not find PocketPC SDK or target compiler to enable WinCE mode $CEVERSION,$TARGETCPU,$ARCH,$PLATFORM" >&5 -echo "$as_me: error: could not find PocketPC SDK or target compiler to enable WinCE mode $CEVERSION,$TARGETCPU,$ARCH,$PLATFORM" >&2;} - { (exit 1); exit 1; }; } + as_fn_error $? "could not find PocketPC SDK or target compiler to enable WinCE mode $CEVERSION,$TARGETCPU,$ARCH,$PLATFORM" "$LINENO" 5 else CEINCLUDE="${SDKROOT}/${OSVERSION}/${PLATFORM}/include" if test -d "${CEINCLUDE}/${TARGETCPU}" ; then @@ -4032,26 +4448,20 @@ _ACEOF fi if test "$do64bit" != "no" ; then - cat >>confdefs.h <<\_ACEOF -#define TCL_CFG_DO64BIT 1 -_ACEOF + $as_echo "#define TCL_CFG_DO64BIT 1" >>confdefs.h fi if test "${GCC}" = "yes" ; then - echo "$as_me:$LINENO: checking for SEH support in compiler" >&5 -echo $ECHO_N "checking for SEH support in compiler... $ECHO_C" >&6 -if test "${tcl_cv_seh+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for SEH support in compiler" >&5 +$as_echo_n "checking for SEH support in compiler... " >&6; } +if ${tcl_cv_seh+:} false; then : + $as_echo_n "(cached) " >&6 else - if test "$cross_compiling" = yes; then + if test "$cross_compiling" = yes; then : tcl_cv_seh=no else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #define WIN32_LEAN_AND_MEAN @@ -4070,37 +4480,22 @@ cat >>conftest.$ac_ext <<_ACEOF } _ACEOF -rm -f conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then +if ac_fn_c_try_run "$LINENO"; then : tcl_cv_seh=yes else - echo "$as_me: program exited with status $ac_status" >&5 -echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -( exit $ac_status ) -tcl_cv_seh=no + tcl_cv_seh=no fi -rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext fi + fi -echo "$as_me:$LINENO: result: $tcl_cv_seh" >&5 -echo "${ECHO_T}$tcl_cv_seh" >&6 +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_seh" >&5 +$as_echo "$tcl_cv_seh" >&6; } if test "$tcl_cv_seh" = "no" ; then -cat >>confdefs.h <<\_ACEOF -#define HAVE_NO_SEH 1 -_ACEOF +$as_echo "#define HAVE_NO_SEH 1" >>confdefs.h fi @@ -4110,16 +4505,12 @@ _ACEOF # with Cygwin's version as of 2002-04-10, define it to be int, # sufficient for getting the current code to work. # - echo "$as_me:$LINENO: checking for EXCEPTION_DISPOSITION support in include files" >&5 -echo $ECHO_N "checking for EXCEPTION_DISPOSITION support in include files... $ECHO_C" >&6 -if test "${tcl_cv_eh_disposition+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for EXCEPTION_DISPOSITION support in include files" >&5 +$as_echo_n "checking for EXCEPTION_DISPOSITION support in include files... " >&6; } +if ${tcl_cv_eh_disposition+:} false; then : + $as_echo_n "(cached) " >&6 else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ # define WIN32_LEAN_AND_MEAN @@ -4136,45 +4527,19 @@ main () return 0; } _ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then +if ac_fn_c_try_compile "$LINENO"; then : tcl_cv_eh_disposition=yes else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -tcl_cv_eh_disposition=no + tcl_cv_eh_disposition=no fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi -echo "$as_me:$LINENO: result: $tcl_cv_eh_disposition" >&5 -echo "${ECHO_T}$tcl_cv_eh_disposition" >&6 +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_eh_disposition" >&5 +$as_echo "$tcl_cv_eh_disposition" >&6; } if test "$tcl_cv_eh_disposition" = "no" ; then -cat >>confdefs.h <<\_ACEOF -#define EXCEPTION_DISPOSITION int -_ACEOF +$as_echo "#define EXCEPTION_DISPOSITION int" >>confdefs.h fi @@ -4182,16 +4547,12 @@ _ACEOF # even if VOID has already been #defined. The win32api # used by mingw and cygwin is known to do this. - echo "$as_me:$LINENO: checking for winnt.h that ignores VOID define" >&5 -echo $ECHO_N "checking for winnt.h that ignores VOID define... $ECHO_C" >&6 -if test "${tcl_cv_winnt_ignore_void+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for winnt.h that ignores VOID define" >&5 +$as_echo_n "checking for winnt.h that ignores VOID define... " >&6; } +if ${tcl_cv_winnt_ignore_void+:} false; then : + $as_echo_n "(cached) " >&6 else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #define VOID void @@ -4211,45 +4572,19 @@ main () return 0; } _ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then +if ac_fn_c_try_compile "$LINENO"; then : tcl_cv_winnt_ignore_void=yes else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -tcl_cv_winnt_ignore_void=no + tcl_cv_winnt_ignore_void=no fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi -echo "$as_me:$LINENO: result: $tcl_cv_winnt_ignore_void" >&5 -echo "${ECHO_T}$tcl_cv_winnt_ignore_void" >&6 +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_winnt_ignore_void" >&5 +$as_echo "$tcl_cv_winnt_ignore_void" >&6; } if test "$tcl_cv_winnt_ignore_void" = "yes" ; then -cat >>confdefs.h <<\_ACEOF -#define HAVE_WINNT_IGNORE_VOID 1 -_ACEOF +$as_echo "#define HAVE_WINNT_IGNORE_VOID 1" >>confdefs.h fi @@ -4257,16 +4592,12 @@ _ACEOF # This is used to stop gcc from printing a compiler # warning when initializing a union member. - echo "$as_me:$LINENO: checking for cast to union support" >&5 -echo $ECHO_N "checking for cast to union support... $ECHO_C" >&6 -if test "${tcl_cv_cast_to_union+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for cast to union support" >&5 +$as_echo_n "checking for cast to union support... " >&6; } +if ${tcl_cv_cast_to_union+:} false; then : + $as_echo_n "(cached) " >&6 else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int @@ -4280,45 +4611,19 @@ main () return 0; } _ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then +if ac_fn_c_try_compile "$LINENO"; then : tcl_cv_cast_to_union=yes else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -tcl_cv_cast_to_union=no + tcl_cv_cast_to_union=no fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi -echo "$as_me:$LINENO: result: $tcl_cv_cast_to_union" >&5 -echo "${ECHO_T}$tcl_cv_cast_to_union" >&6 +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_cast_to_union" >&5 +$as_echo "$tcl_cv_cast_to_union" >&6; } if test "$tcl_cv_cast_to_union" = "yes"; then -cat >>confdefs.h <<\_ACEOF -#define HAVE_CAST_TO_UNION 1 -_ACEOF +$as_echo "#define HAVE_CAST_TO_UNION 1" >>confdefs.h fi fi @@ -4345,7 +4650,7 @@ esac # as we just assume that the platform hasn't got a usable z.lib #------------------------------------------------------------------------ -if test "${enable_shared+set}" = "set"; then +if test "${enable_shared+set}" = "set"; then : enableval="$enable_shared" tcl_ok=$enableval @@ -4356,311 +4661,130 @@ else fi -if test "$tcl_ok" = "yes"; then +# Check whether --with-zlib was given. +if test "${with_zlib+set}" = set; then : + withval=$with_zlib; with_zlib=$withval +else + with_zlib=NO_ZLIB - ZLIB_DLL_FILE=\${ZLIB_DLL_FILE} +fi - if test "$do64bit" = "yes"; then +if test "with_zlib" = "NO_ZLIB"; then : + ZLIB_OBJS=\${ZLIB_OBJS} - if test "$GCC" == "yes"; then +elif test "$tcl_ok" != "yes"; then : + ZLIB_OBJS=\${ZLIB_OBJS} - ZLIB_LIBS=\${ZLIB_DIR}/win64/libz.dll.a +elif test "$do64bit" = "yes"; then : + ZLIB_OBJS=\${ZLIB_OBJS} +elif test "$with_zlib" = "yes" ; then : + ZLIB_LIBS=\${ZLIB_DIR}/win32/zdll.lib else - - ZLIB_LIBS=\${ZLIB_DIR}/win64/zdll.lib + ZLIB_LIBS=$with_zlib fi +$as_echo "#define HAVE_ZLIB 1" >>confdefs.h -else - - ZLIB_LIBS=\${ZLIB_DIR}/win32/zdll.lib +ac_fn_c_check_type "$LINENO" "intptr_t" "ac_cv_type_intptr_t" "$ac_includes_default" +if test "x$ac_cv_type_intptr_t" = xyes; then : -fi +$as_echo "#define HAVE_INTPTR_T 1" >>confdefs.h else - ZLIB_OBJS=\${ZLIB_OBJS} - - -fi - - -cat >>confdefs.h <<\_ACEOF -#define HAVE_ZLIB 1 -_ACEOF - - -echo "$as_me:$LINENO: checking for intptr_t" >&5 -echo $ECHO_N "checking for intptr_t... $ECHO_C" >&6 -if test "${ac_cv_type_intptr_t+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pointer-size signed integer type" >&5 +$as_echo_n "checking for pointer-size signed integer type... " >&6; } +if ${tcl_cv_intptr_t+:} false; then : + $as_echo_n "(cached) " >&6 else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF + + for tcl_cv_intptr_t in "int" "long" "long long" none; do + if test "$tcl_cv_intptr_t" != none; then + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_includes_default int main () { -if ((intptr_t *) 0) - return 0; -if (sizeof (intptr_t)) - return 0; +static int test_array [1 - 2 * !(sizeof (void *) <= sizeof ($tcl_cv_intptr_t))]; +test_array [0] = 0 + ; return 0; } _ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_type_intptr_t=yes +if ac_fn_c_try_compile "$LINENO"; then : + tcl_ok=yes else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_type_intptr_t=no + tcl_ok=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + test "$tcl_ok" = yes && break; fi + done fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_intptr_t" >&5 +$as_echo "$tcl_cv_intptr_t" >&6; } + if test "$tcl_cv_intptr_t" != none; then + +cat >>confdefs.h <<_ACEOF +#define intptr_t $tcl_cv_intptr_t +_ACEOF + + fi + fi -echo "$as_me:$LINENO: result: $ac_cv_type_intptr_t" >&5 -echo "${ECHO_T}$ac_cv_type_intptr_t" >&6 -if test $ac_cv_type_intptr_t = yes; then +ac_fn_c_check_type "$LINENO" "uintptr_t" "ac_cv_type_uintptr_t" "$ac_includes_default" +if test "x$ac_cv_type_uintptr_t" = xyes; then : -cat >>confdefs.h <<\_ACEOF -#define HAVE_INTPTR_T 1 -_ACEOF + +$as_echo "#define HAVE_UINTPTR_T 1" >>confdefs.h else - echo "$as_me:$LINENO: checking for pointer-size signed integer type" >&5 -echo $ECHO_N "checking for pointer-size signed integer type... $ECHO_C" >&6 -if test "${tcl_cv_intptr_t+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pointer-size unsigned integer type" >&5 +$as_echo_n "checking for pointer-size unsigned integer type... " >&6; } +if ${tcl_cv_uintptr_t+:} false; then : + $as_echo_n "(cached) " >&6 else - for tcl_cv_intptr_t in "int" "long" "long long" none; do - if test "$tcl_cv_intptr_t" != none; then - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF + for tcl_cv_uintptr_t in "unsigned int" "unsigned long" "unsigned long long" \ + none; do + if test "$tcl_cv_uintptr_t" != none; then + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_includes_default int main () { -static int test_array [1 - 2 * !(sizeof (void *) <= sizeof ($tcl_cv_intptr_t))]; +static int test_array [1 - 2 * !(sizeof (void *) <= sizeof ($tcl_cv_uintptr_t))]; test_array [0] = 0 ; return 0; } _ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then +if ac_fn_c_try_compile "$LINENO"; then : tcl_ok=yes else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -tcl_ok=no + tcl_ok=no fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext test "$tcl_ok" = yes && break; fi done fi -echo "$as_me:$LINENO: result: $tcl_cv_intptr_t" >&5 -echo "${ECHO_T}$tcl_cv_intptr_t" >&6 - if test "$tcl_cv_intptr_t" != none; then +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_uintptr_t" >&5 +$as_echo "$tcl_cv_uintptr_t" >&6; } + if test "$tcl_cv_uintptr_t" != none; then cat >>confdefs.h <<_ACEOF -#define intptr_t $tcl_cv_intptr_t -_ACEOF - - fi - -fi - -echo "$as_me:$LINENO: checking for uintptr_t" >&5 -echo $ECHO_N "checking for uintptr_t... $ECHO_C" >&6 -if test "${ac_cv_type_uintptr_t+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -int -main () -{ -if ((uintptr_t *) 0) - return 0; -if (sizeof (uintptr_t)) - return 0; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_type_uintptr_t=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_type_uintptr_t=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_type_uintptr_t" >&5 -echo "${ECHO_T}$ac_cv_type_uintptr_t" >&6 -if test $ac_cv_type_uintptr_t = yes; then - - -cat >>confdefs.h <<\_ACEOF -#define HAVE_UINTPTR_T 1 -_ACEOF - -else - - echo "$as_me:$LINENO: checking for pointer-size unsigned integer type" >&5 -echo $ECHO_N "checking for pointer-size unsigned integer type... $ECHO_C" >&6 -if test "${tcl_cv_uintptr_t+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - - for tcl_cv_uintptr_t in "unsigned int" "unsigned long" "unsigned long long" \ - none; do - if test "$tcl_cv_uintptr_t" != none; then - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -int -main () -{ -static int test_array [1 - 2 * !(sizeof (void *) <= sizeof ($tcl_cv_uintptr_t))]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - tcl_ok=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -tcl_ok=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext - test "$tcl_ok" = yes && break; fi - done -fi -echo "$as_me:$LINENO: result: $tcl_cv_uintptr_t" >&5 -echo "${ECHO_T}$tcl_cv_uintptr_t" >&6 - if test "$tcl_cv_uintptr_t" != none; then - -cat >>confdefs.h <<_ACEOF -#define uintptr_t $tcl_cv_uintptr_t +#define uintptr_t $tcl_cv_uintptr_t _ACEOF fi @@ -4676,16 +4800,12 @@ fi # missing from winbase.h. This is known to be # a problem with VC++ 5.2. -echo "$as_me:$LINENO: checking for FINDEX_INFO_LEVELS in winbase.h" >&5 -echo $ECHO_N "checking for FINDEX_INFO_LEVELS in winbase.h... $ECHO_C" >&6 -if test "${tcl_cv_findex_enums+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for FINDEX_INFO_LEVELS in winbase.h" >&5 +$as_echo_n "checking for FINDEX_INFO_LEVELS in winbase.h... " >&6; } +if ${tcl_cv_findex_enums+:} false; then : + $as_echo_n "(cached) " >&6 else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #define WIN32_LEAN_AND_MEAN @@ -4703,60 +4823,30 @@ main () return 0; } _ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then +if ac_fn_c_try_compile "$LINENO"; then : tcl_cv_findex_enums=yes else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -tcl_cv_findex_enums=no + tcl_cv_findex_enums=no fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi -echo "$as_me:$LINENO: result: $tcl_cv_findex_enums" >&5 -echo "${ECHO_T}$tcl_cv_findex_enums" >&6 +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_findex_enums" >&5 +$as_echo "$tcl_cv_findex_enums" >&6; } if test "$tcl_cv_findex_enums" = "no"; then -cat >>confdefs.h <<\_ACEOF -#define HAVE_NO_FINDEX_ENUMS 1 -_ACEOF +$as_echo "#define HAVE_NO_FINDEX_ENUMS 1" >>confdefs.h fi # See if the compiler supports intrinsics. -echo "$as_me:$LINENO: checking for intrinsics support in compiler" >&5 -echo $ECHO_N "checking for intrinsics support in compiler... $ECHO_C" >&6 -if test "${tcl_cv_intrinsics+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for intrinsics support in compiler" >&5 +$as_echo_n "checking for intrinsics support in compiler... " >&6; } +if ${tcl_cv_intrinsics+:} false; then : + $as_echo_n "(cached) " >&6 else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #define WIN32_LEAN_AND_MEAN @@ -4774,61 +4864,31 @@ main () return 0; } _ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then +if ac_fn_c_try_link "$LINENO"; then : tcl_cv_intrinsics=yes else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -tcl_cv_intrinsics=no + tcl_cv_intrinsics=no fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext fi -echo "$as_me:$LINENO: result: $tcl_cv_intrinsics" >&5 -echo "${ECHO_T}$tcl_cv_intrinsics" >&6 +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_intrinsics" >&5 +$as_echo "$tcl_cv_intrinsics" >&6; } if test "$tcl_cv_intrinsics" = "yes"; then -cat >>confdefs.h <<\_ACEOF -#define HAVE_INTRIN_H 1 -_ACEOF +$as_echo "#define HAVE_INTRIN_H 1" >>confdefs.h fi # See if the header file is present -echo "$as_me:$LINENO: checking for wspiapi.h" >&5 -echo $ECHO_N "checking for wspiapi.h... $ECHO_C" >&6 -if test "${tcl_cv_wspiapi_h+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for wspiapi.h" >&5 +$as_echo_n "checking for wspiapi.h... " >&6; } +if ${tcl_cv_wspiapi_h+:} false; then : + $as_echo_n "(cached) " >&6 else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include @@ -4841,45 +4901,19 @@ main () return 0; } _ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then +if ac_fn_c_try_compile "$LINENO"; then : tcl_cv_wspiapi_h=yes else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -tcl_cv_wspiapi_h=no + tcl_cv_wspiapi_h=no fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi -echo "$as_me:$LINENO: result: $tcl_cv_wspiapi_h" >&5 -echo "${ECHO_T}$tcl_cv_wspiapi_h" >&6 +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_wspiapi_h" >&5 +$as_echo "$tcl_cv_wspiapi_h" >&6; } if test "$tcl_cv_wspiapi_h" = "yes"; then -cat >>confdefs.h <<\_ACEOF -#define HAVE_WSPIAPI_H 1 -_ACEOF +$as_echo "#define HAVE_WSPIAPI_H 1" >>confdefs.h fi @@ -4887,16 +4921,12 @@ fi # missing from winbase.h. This is known to be # a problem with VC++ 5.2. -echo "$as_me:$LINENO: checking for FINDEX_INFO_LEVELS in winbase.h" >&5 -echo $ECHO_N "checking for FINDEX_INFO_LEVELS in winbase.h... $ECHO_C" >&6 -if test "${tcl_cv_findex_enums+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for FINDEX_INFO_LEVELS in winbase.h" >&5 +$as_echo_n "checking for FINDEX_INFO_LEVELS in winbase.h... " >&6; } +if ${tcl_cv_findex_enums+:} false; then : + $as_echo_n "(cached) " >&6 else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #define WIN32_LEAN_AND_MEAN @@ -4914,45 +4944,19 @@ main () return 0; } _ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then +if ac_fn_c_try_compile "$LINENO"; then : tcl_cv_findex_enums=yes else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -tcl_cv_findex_enums=no + tcl_cv_findex_enums=no fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi -echo "$as_me:$LINENO: result: $tcl_cv_findex_enums" >&5 -echo "${ECHO_T}$tcl_cv_findex_enums" >&6 +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_findex_enums" >&5 +$as_echo "$tcl_cv_findex_enums" >&6; } if test "$tcl_cv_findex_enums" = "no"; then -cat >>confdefs.h <<\_ACEOF -#define HAVE_NO_FINDEX_ENUMS 1 -_ACEOF +$as_echo "#define HAVE_NO_FINDEX_ENUMS 1" >>confdefs.h fi @@ -4963,39 +4967,35 @@ fi #-------------------------------------------------------------------- - echo "$as_me:$LINENO: checking for build with symbols" >&5 -echo $ECHO_N "checking for build with symbols... $ECHO_C" >&6 - # Check whether --enable-symbols or --disable-symbols was given. -if test "${enable_symbols+set}" = set; then - enableval="$enable_symbols" - tcl_ok=$enableval + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for build with symbols" >&5 +$as_echo_n "checking for build with symbols... " >&6; } + # Check whether --enable-symbols was given. +if test "${enable_symbols+set}" = set; then : + enableval=$enable_symbols; tcl_ok=$enableval else tcl_ok=no -fi; +fi + # FIXME: Currently, LDFLAGS_DEFAULT is not used, it should work like CFLAGS_DEFAULT. if test "$tcl_ok" = "no"; then CFLAGS_DEFAULT='$(CFLAGS_OPTIMIZE)' LDFLAGS_DEFAULT='$(LDFLAGS_OPTIMIZE)' DBGX="" -cat >>confdefs.h <<\_ACEOF -#define NDEBUG 1 -_ACEOF +$as_echo "#define NDEBUG 1" >>confdefs.h - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } - cat >>confdefs.h <<\_ACEOF -#define TCL_CFG_OPTIMIZED 1 -_ACEOF + $as_echo "#define TCL_CFG_OPTIMIZED 1" >>confdefs.h else CFLAGS_DEFAULT='$(CFLAGS_DEBUG)' LDFLAGS_DEFAULT='$(LDFLAGS_DEBUG)' DBGX=g if test "$tcl_ok" = "yes"; then - echo "$as_me:$LINENO: result: yes (standard debugging)" >&5 -echo "${ECHO_T}yes (standard debugging)" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes (standard debugging)" >&5 +$as_echo "yes (standard debugging)" >&6; } fi fi @@ -5003,32 +5003,26 @@ echo "${ECHO_T}yes (standard debugging)" >&6 if test "$tcl_ok" = "mem" -o "$tcl_ok" = "all"; then -cat >>confdefs.h <<\_ACEOF -#define TCL_MEM_DEBUG 1 -_ACEOF +$as_echo "#define TCL_MEM_DEBUG 1" >>confdefs.h fi if test "$tcl_ok" = "compile" -o "$tcl_ok" = "all"; then -cat >>confdefs.h <<\_ACEOF -#define TCL_COMPILE_DEBUG 1 -_ACEOF +$as_echo "#define TCL_COMPILE_DEBUG 1" >>confdefs.h -cat >>confdefs.h <<\_ACEOF -#define TCL_COMPILE_STATS 1 -_ACEOF +$as_echo "#define TCL_COMPILE_STATS 1" >>confdefs.h fi if test "$tcl_ok" != "yes" -a "$tcl_ok" != "no"; then if test "$tcl_ok" = "all"; then - echo "$as_me:$LINENO: result: enabled symbols mem compile debugging" >&5 -echo "${ECHO_T}enabled symbols mem compile debugging" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: enabled symbols mem compile debugging" >&5 +$as_echo "enabled symbols mem compile debugging" >&6; } else - echo "$as_me:$LINENO: result: enabled $tcl_ok debugging" >&5 -echo "${ECHO_T}enabled $tcl_ok debugging" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: enabled $tcl_ok debugging" >&5 +$as_echo "enabled $tcl_ok debugging" >&6; } fi fi @@ -5040,15 +5034,15 @@ TCL_DBGX=${DBGX} #-------------------------------------------------------------------- - echo "$as_me:$LINENO: checking whether to embed manifest" >&5 -echo $ECHO_N "checking whether to embed manifest... $ECHO_C" >&6 - # Check whether --enable-embedded-manifest or --disable-embedded-manifest was given. -if test "${enable_embedded_manifest+set}" = set; then - enableval="$enable_embedded_manifest" - embed_ok=$enableval + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to embed manifest" >&5 +$as_echo_n "checking whether to embed manifest... " >&6; } + # Check whether --enable-embedded-manifest was given. +if test "${enable_embedded_manifest+set}" = set; then : + enableval=$enable_embedded_manifest; embed_ok=$enableval else embed_ok=yes -fi; +fi + VC_MANIFEST_EMBED_DLL= VC_MANIFEST_EMBED_EXE= @@ -5056,11 +5050,7 @@ fi; if test "$embed_ok" = "yes" -a "${SHARED_BUILD}" = "1" \ -a "$GCC" != "yes" ; then # Add the magic to embed the manifest into the dll/exe - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #if defined(_MSC_VER) && _MSC_VER >= 1400 @@ -5069,7 +5059,7 @@ print("manifest needed") _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "manifest needed" >/dev/null 2>&1; then + $EGREP "manifest needed" >/dev/null 2>&1; then : # Could do a CHECK_PROG for mt, but should always be with MSVC8+ # Could add 'if test -f' check, but manifest should be created @@ -5088,8 +5078,8 @@ fi rm -f conftest* fi - echo "$as_me:$LINENO: result: $result" >&5 -echo "${ECHO_T}$result" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $result" >&5 +$as_echo "$result" >&6; } @@ -5275,7 +5265,8 @@ TCL_WIN_VERSION="$TCL_VERSION.$TCL_RELEASE_LEVEL.`echo $TCL_PATCH_LEVEL | tr -d - ac_config_files="$ac_config_files Makefile tclConfig.sh tcl.hpj tclsh.exe.manifest" +ac_config_files="$ac_config_files Makefile tclConfig.sh tcl.hpj tclsh.exe.manifest" + cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure @@ -5294,39 +5285,70 @@ _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. -# So, don't put newlines in cache variables' values. +# So, we kill variables containing newlines. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. -{ +( + for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + (set) 2>&1 | - case `(ac_space=' '; set | grep ac_space) 2>&1` in - *ac_space=\ *) - # `set' does not quote correctly, so add quotes (double-quote - # substitution turns \\\\ into \\, and sed turns \\ into \). + case $as_nl`(ac_space=' '; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + # `set' does not quote correctly, so add quotes: double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \. sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" - ;; + ;; #( *) # `set' quotes correctly as required by POSIX, so do not add quotes. - sed -n \ - "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; - esac; -} | + esac | + sort +) | sed ' + /^ac_cv_env_/b end t clear - : clear + :clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end - /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ - : end' >>confcache -if diff $cache_file confcache >/dev/null 2>&1; then :; else - if test -w $cache_file; then - test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file" - cat confcache >$cache_file + s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + :end' >>confcache +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else + if test -w "$cache_file"; then + if test "x$cache_file" != "x/dev/null"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 +$as_echo "$as_me: updating cache $cache_file" >&6;} + if test ! -f "$cache_file" || test -h "$cache_file"; then + cat confcache >"$cache_file" + else + case $cache_file in #( + */* | ?:*) + mv -f confcache "$cache_file"$$ && + mv -f "$cache_file"$$ "$cache_file" ;; #( + *) + mv -f confcache "$cache_file" ;; + esac + fi + fi else - echo "not updating unwritable cache $cache_file" + { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 +$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache @@ -5335,63 +5357,55 @@ test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' -# VPATH may cause trouble with some makes, so we remove $(srcdir), -# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and -# trailing colons and then remove the whole line if VPATH becomes empty -# (actually we leave an empty line to preserve line numbers). -if test "x$srcdir" = x.; then - ac_vpsub='/^[ ]*VPATH[ ]*=/{ -s/:*\$(srcdir):*/:/; -s/:*\${srcdir}:*/:/; -s/:*@srcdir@:*/:/; -s/^\([^=]*=[ ]*\):*/\1/; -s/:*$//; -s/^[^=]*=[ ]*$//; -}' -fi - # Transform confdefs.h into DEFS. # Protect against shell expansion while executing Makefile rules. # Protect against Makefile macro expansion. # # If the first sed substitution is executed (which looks for macros that -# take arguments), then we branch to the quote section. Otherwise, +# take arguments), then branch to the quote section. Otherwise, # look for a macro that doesn't take arguments. -cat >confdef2opt.sed <<\_ACEOF +ac_script=' +:mline +/\\$/{ + N + s,\\\n,, + b mline +} t clear -: clear -s,^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\),-D\1=\2,g +:clear +s/^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\)/-D\1=\2/g t quote -s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\),-D\1=\2,g +s/^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)/-D\1=\2/g t quote -d -: quote -s,[ `~#$^&*(){}\\|;'"<>?],\\&,g -s,\[,\\&,g -s,\],\\&,g -s,\$,$$,g -p -_ACEOF -# We use echo to avoid assuming a particular line-breaking character. -# The extra dot is to prevent the shell from consuming trailing -# line-breaks from the sub-command output. A line-break within -# single-quotes doesn't work because, if this script is created in a -# platform that uses two characters for line-breaks (e.g., DOS), tr -# would break. -ac_LF_and_DOT=`echo; echo .` -DEFS=`sed -n -f confdef2opt.sed confdefs.h | tr "$ac_LF_and_DOT" ' .'` -rm -f confdef2opt.sed +b any +:quote +s/[ `~#$^&*(){}\\|;'\''"<>?]/\\&/g +s/\[/\\&/g +s/\]/\\&/g +s/\$/$$/g +H +:any +${ + g + s/^\n// + s/\n/ /g + p +} +' +DEFS=`sed -n "$ac_script" confdefs.h` ac_libobjs= ac_ltlibobjs= +U= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. - ac_i=`echo "$ac_i" | - sed 's/\$U\././;s/\.o$//;s/\.obj$//'` - # 2. Add them. - ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext" - ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo' + ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' + ac_i=`$as_echo "$ac_i" | sed "$ac_script"` + # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR + # will be set to the directory where LIBOBJS objects are built. + as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" + as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs @@ -5399,12 +5413,14 @@ LTLIBOBJS=$ac_ltlibobjs -: ${CONFIG_STATUS=./config.status} +: "${CONFIG_STATUS=./config.status}" +ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" -{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 -echo "$as_me: creating $CONFIG_STATUS" >&6;} -cat >$CONFIG_STATUS <<_ACEOF +{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 +$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} +as_write_fail=0 +cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. @@ -5414,81 +5430,253 @@ cat >$CONFIG_STATUS <<_ACEOF debug=false ac_cs_recheck=false ac_cs_silent=false -SHELL=\${CONFIG_SHELL-$SHELL} -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF -## --------------------- ## -## M4sh Initialization. ## -## --------------------- ## - -# Be Bourne compatible -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: - # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' -elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then - set -o posix + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac fi -DUALCASE=1; export DUALCASE # for MKS sh -# Support unset when possible. -if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then - as_unset=unset -else - as_unset=false + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' fi +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS -# Work around bugs in pre-3.0 UWIN ksh. -$as_unset ENV MAIL MAILPATH + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. -for as_var in \ - LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ - LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ - LC_TELEPHONE LC_TIME -do - if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then - eval $as_var=C; export $as_var - else - $as_unset $as_var +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi -done + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status -# Required to use basename. -if expr a : '\(a\)' >/dev/null 2>&1; then +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi -if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi -# Name of the executable. -as_me=`$as_basename "$0" || +as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)$' \| \ - . : '\(.\)' 2>/dev/null || -echo X/"$0" | - sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } - /^X\/\(\/\/\)$/{ s//\1/; q; } - /^X\/\(\/\).*/{ s//\1/; q; } - s/.*/./; q'` + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` - -# PATH needs CR, and LINENO needs CR and PATH. # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' @@ -5496,148 +5684,123 @@ as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits -# The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then - echo "#! /bin/sh" >conf$$.sh - echo "exit 0" >>conf$$.sh - chmod +x conf$$.sh - if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then - PATH_SEPARATOR=';' - else - PATH_SEPARATOR=: - fi - rm -f conf$$.sh -fi - - - as_lineno_1=$LINENO - as_lineno_2=$LINENO - as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` - test "x$as_lineno_1" != "x$as_lineno_2" && - test "x$as_lineno_3" = "x$as_lineno_2" || { - # Find who we are. Look in the path if we contain no path at all - # relative or not. - case $0 in - *[\\/]* ) as_myself=$0 ;; - *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break -done - - ;; - esac - # We did not find ourselves, most probably we were run as `sh COMMAND' - # in which case we are not to be found in the path. - if test "x$as_myself" = x; then - as_myself=$0 - fi - if test ! -f "$as_myself"; then - { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5 -echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;} - { (exit 1); exit 1; }; } - fi - case $CONFIG_SHELL in - '') - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for as_base in sh bash ksh sh5; do - case $as_dir in - /*) - if ("$as_dir/$as_base" -c ' - as_lineno_1=$LINENO - as_lineno_2=$LINENO - as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` - test "x$as_lineno_1" != "x$as_lineno_2" && - test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then - $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } - $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } - CONFIG_SHELL=$as_dir/$as_base - export CONFIG_SHELL - exec "$CONFIG_SHELL" "$0" ${1+"$@"} - fi;; - esac - done -done -;; - esac - - # Create $as_me.lineno as a copy of $as_myself, but with $LINENO - # uniformly replaced by the line number. The first 'sed' inserts a - # line-number line before each line; the second 'sed' does the real - # work. The second script uses 'N' to pair each line-number line - # with the numbered line, and appends trailing '-' during - # substitution so that $LINENO is not a special case at line end. - # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the - # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) - sed '=' <$as_myself | - sed ' - N - s,$,-, - : loop - s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, - t loop - s,-$,, - s,^['$as_cr_digits']*\n,, - ' >$as_me.lineno && - chmod +x $as_me.lineno || - { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5 -echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;} - { (exit 1); exit 1; }; } - - # Don't try to exec as it changes $[0], causing all sort of problems - # (the dirname of $[0] is not the place where we might find the - # original and so on. Autoconf is especially sensible to this). - . ./$as_me.lineno - # Exit status is that of the last command. - exit -} - - -case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in - *c*,-n*) ECHO_N= ECHO_C=' -' ECHO_T=' ' ;; - *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; - *) ECHO_N= ECHO_C='\c' ECHO_T= ;; +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; esac -if expr a : '\(a\)' >/dev/null 2>&1; then - as_expr=expr +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file else - as_expr=false + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null fi - -rm -f conf$$ conf$$.exe conf$$.file -echo >conf$$.file -if ln -s conf$$.file conf$$ 2>/dev/null; then - # We could just check for DJGPP; but this test a) works b) is more generic - # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). - if test -f conf$$.exe; then - # Don't use ln at all; we don't have any links - as_ln_s='cp -p' - else +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -p' fi -elif ln conf$$.file conf$$ 2>/dev/null; then - as_ln_s=ln else as_ln_s='cp -p' fi -rm -f conf$$ conf$$.exe conf$$.file +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p if mkdir -p . 2>/dev/null; then - as_mkdir_p=: + as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi -as_executable_p="test -f" +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in #( + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" @@ -5646,31 +5809,20 @@ as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" -# IFS -# We need space, tab and new line, in precisely that order. -as_nl=' -' -IFS=" $as_nl" - -# CDPATH. -$as_unset CDPATH - exec 6>&1 - -# Open the log real soon, to keep \$[0] and so on meaningful, and to +## ----------------------------------- ## +## Main body of $CONFIG_STATUS script. ## +## ----------------------------------- ## +_ASEOF +test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# Save the log message, to keep $0 and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their -# values after options handling. Logging --version etc. is OK. -exec 5>>config.log -{ - echo - sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX -## Running $as_me. ## -_ASBOX -} >&5 -cat >&5 <<_CSEOF - +# values after options handling. +ac_log=" This file was extended by $as_me, which was -generated by GNU Autoconf 2.59. Invocation command line was +generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS @@ -5678,124 +5830,116 @@ generated by GNU Autoconf 2.59. Invocation command line was CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ -_CSEOF -echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5 -echo >&5 +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + _ACEOF -# Files that config.status was made for. -if test -n "$ac_config_files"; then - echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS -fi +case $ac_config_files in *" +"*) set x $ac_config_files; shift; ac_config_files=$*;; +esac -if test -n "$ac_config_headers"; then - echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS -fi -if test -n "$ac_config_links"; then - echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS -fi -if test -n "$ac_config_commands"; then - echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS -fi +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# Files that config.status was made for. +config_files="$ac_config_files" -cat >>$CONFIG_STATUS <<\_ACEOF +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ac_cs_usage="\ -\`$as_me' instantiates files from templates according to the -current configuration. +\`$as_me' instantiates files and other configuration actions +from templates according to the current configuration. Unless the files +and actions are specified as TAGs, all are instantiated by default. -Usage: $0 [OPTIONS] [FILE]... +Usage: $0 [OPTION]... [TAG]... -h, --help print this help, then exit - -V, --version print version number, then exit - -q, --quiet do not print progress messages + -V, --version print version number and configuration settings, then exit + --config print configuration, then exit + -q, --quiet, --silent + do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions - --file=FILE[:TEMPLATE] - instantiate the configuration file FILE + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE Configuration files: $config_files -Report bugs to ." -_ACEOF +Report bugs to the package provider." -cat >>$CONFIG_STATUS <<_ACEOF +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ config.status -configured by $0, generated by GNU Autoconf 2.59, - with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\" +configured by $0, generated by GNU Autoconf 2.68, + with options \\"\$ac_cs_config\\" -Copyright (C) 2003 Free Software Foundation, Inc. +Copyright (C) 2010 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." -srcdir=$srcdir + +ac_pwd='$ac_pwd' +srcdir='$srcdir' +test -n "\$AWK" || AWK=awk _ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF -# If no file are specified by the user, then we need to provide default -# value. By we need to know if files were specified by the user. +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# The default lists apply if the user does not specify any file. ac_need_defaults=: while test $# != 0 do case $1 in - --*=*) - ac_option=`expr "x$1" : 'x\([^=]*\)='` - ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'` + --*=?*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; - -*) + --*=) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg= + ac_shift=: + ;; + *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; - *) # This is not an option, so the user has probably given explicit - # arguments. - ac_option=$1 - ac_need_defaults=false;; esac case $ac_option in # Handling of the options. -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; - --version | --vers* | -V ) - echo "$ac_cs_version"; exit 0 ;; - --he | --h) - # Conflict between --help and --header - { { echo "$as_me:$LINENO: error: ambiguous option: $1 -Try \`$0 --help' for more information." >&5 -echo "$as_me: error: ambiguous option: $1 -Try \`$0 --help' for more information." >&2;} - { (exit 1); exit 1; }; };; - --help | --hel | -h ) - echo "$ac_cs_usage"; exit 0 ;; - --debug | --d* | -d ) + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + $as_echo "$ac_cs_version"; exit ;; + --config | --confi | --conf | --con | --co | --c ) + $as_echo "$ac_cs_config"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift - CONFIG_FILES="$CONFIG_FILES $ac_optarg" - ac_need_defaults=false;; - --header | --heade | --head | --hea ) - $ac_shift - CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg" + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + '') as_fn_error $? "missing file argument" ;; + esac + as_fn_append CONFIG_FILES " '$ac_optarg'" ac_need_defaults=false;; + --he | --h | --help | --hel | -h ) + $as_echo "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. - -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1 -Try \`$0 --help' for more information." >&5 -echo "$as_me: error: unrecognized option: $1 -Try \`$0 --help' for more information." >&2;} - { (exit 1); exit 1; }; } ;; + -*) as_fn_error $? "unrecognized option: \`$1' +Try \`$0 --help' for more information." ;; - *) ac_config_targets="$ac_config_targets $1" ;; + *) as_fn_append ac_config_targets " $1" + ac_need_defaults=false ;; esac shift @@ -5809,33 +5953,47 @@ if $ac_cs_silent; then fi _ACEOF -cat >>$CONFIG_STATUS <<_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then - echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6 - exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + shift + \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 + CONFIG_SHELL='$SHELL' + export CONFIG_SHELL + exec "\$@" fi _ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + $as_echo "$ac_log" +} >&5 +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 - - -cat >>$CONFIG_STATUS <<\_ACEOF +# Handling of arguments. for ac_config_target in $ac_config_targets do - case "$ac_config_target" in - # Handling of arguments. - "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;; - "tclConfig.sh" ) CONFIG_FILES="$CONFIG_FILES tclConfig.sh" ;; - "tcl.hpj" ) CONFIG_FILES="$CONFIG_FILES tcl.hpj" ;; - "tclsh.exe.manifest" ) CONFIG_FILES="$CONFIG_FILES tclsh.exe.manifest" ;; - *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 -echo "$as_me: error: invalid argument: $ac_config_target" >&2;} - { (exit 1); exit 1; }; };; + case $ac_config_target in + "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "tclConfig.sh") CONFIG_FILES="$CONFIG_FILES tclConfig.sh" ;; + "tcl.hpj") CONFIG_FILES="$CONFIG_FILES tcl.hpj" ;; + "tclsh.exe.manifest") CONFIG_FILES="$CONFIG_FILES tclsh.exe.manifest" ;; + + *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5 ;; esac done + # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely @@ -5845,420 +6003,414 @@ if $ac_need_defaults; then fi # Have a temporary directory for convenience. Make it in the build tree -# simply because there is no reason to put it here, and in addition, +# simply because there is no reason against having it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. -# Create a temporary directory, and hook for its removal unless debugging. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. $debug || { - trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0 - trap '{ (exit 1); exit 1; }' 1 2 13 15 + tmp= ac_tmp= + trap 'exit_status=$? + : "${ac_tmp:=$tmp}" + { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status +' 0 + trap 'as_fn_exit 1' 1 2 13 15 } - # Create a (secure) tmp directory for tmp files. { - tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` && - test -n "$tmp" && test -d "$tmp" + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -d "$tmp" } || { - tmp=./confstat$$-$RANDOM - (umask 077 && mkdir $tmp) -} || + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 +ac_tmp=$tmp + +# Set up the scripts for CONFIG_FILES section. +# No need to generate them if there are no CONFIG_FILES. +# This happens for instance with `./config.status config.h'. +if test -n "$CONFIG_FILES"; then + + +ac_cr=`echo X | tr X '\015'` +# On cygwin, bash can eat \r inside `` if the user requested igncr. +# But we know of no other shell where ac_cr would be empty at this +# point, so we can use a bashism as a fallback. +if test "x$ac_cr" = x; then + eval ac_cr=\$\'\\r\' +fi +ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` +if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then + ac_cs_awk_cr='\\r' +else + ac_cs_awk_cr=$ac_cr +fi + +echo 'BEGIN {' >"$ac_tmp/subs1.awk" && +_ACEOF + + +{ + echo "cat >conf$$subs.awk <<_ACEOF" && + echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && + echo "_ACEOF" +} >conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 +ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + . ./conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + + ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` + if test $ac_delim_n = $ac_delim_num; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done +rm -f conf$$subs.sh + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && +_ACEOF +sed -n ' +h +s/^/S["/; s/!.*/"]=/ +p +g +s/^[^!]*!// +:repl +t repl +s/'"$ac_delim"'$// +t delim +:nl +h +s/\(.\{148\}\)..*/\1/ +t more1 +s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ +p +n +b repl +:more1 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t nl +:delim +h +s/\(.\{148\}\)..*/\1/ +t more2 +s/["\\]/\\&/g; s/^/"/; s/$/"/ +p +b +:more2 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t delim +' >$CONFIG_STATUS || ac_write_fail=1 +rm -f conf$$subs.awk +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +_ACAWK +cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && + for (key in S) S_is_set[key] = 1 + FS = "" + +} { - echo "$me: cannot create a temporary directory in ." >&2 - { (exit 1); exit 1; } + line = $ 0 + nfields = split(line, field, "@") + substed = 0 + len = length(field[1]) + for (i = 2; i < nfields; i++) { + key = field[i] + keylen = length(key) + if (S_is_set[key]) { + value = S[key] + line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) + len += length(value) + length(field[++i]) + substed = 1 + } else + len += 1 + keylen + } + + print line } +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then + sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" +else + cat +fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ + || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 _ACEOF -cat >>$CONFIG_STATUS <<_ACEOF +# VPATH may cause trouble with some makes, so we remove sole $(srcdir), +# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ +h +s/// +s/^/:/ +s/[ ]*$/:/ +s/:\$(srcdir):/:/g +s/:\${srcdir}:/:/g +s/:@srcdir@:/:/g +s/^:*// +s/:*$// +x +s/\(=[ ]*\).*/\1/ +G +s/\n// +s/^[^=]*=[ ]*$// +}' +fi -# -# CONFIG_FILES section. -# +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +fi # test -n "$CONFIG_FILES" -# No need to generate the scripts if there are no CONFIG_FILES. -# This happens for instance when ./config.status config.h -if test -n "\$CONFIG_FILES"; then - # Protect against being on the right side of a sed subst in config.status. - sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g; - s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF -s,@SHELL@,$SHELL,;t t -s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t -s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t -s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t -s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t -s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t -s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t -s,@exec_prefix@,$exec_prefix,;t t -s,@prefix@,$prefix,;t t -s,@program_transform_name@,$program_transform_name,;t t -s,@bindir@,$bindir,;t t -s,@sbindir@,$sbindir,;t t -s,@libexecdir@,$libexecdir,;t t -s,@datadir@,$datadir,;t t -s,@sysconfdir@,$sysconfdir,;t t -s,@sharedstatedir@,$sharedstatedir,;t t -s,@localstatedir@,$localstatedir,;t t -s,@libdir@,$libdir,;t t -s,@includedir@,$includedir,;t t -s,@oldincludedir@,$oldincludedir,;t t -s,@infodir@,$infodir,;t t -s,@mandir@,$mandir,;t t -s,@build_alias@,$build_alias,;t t -s,@host_alias@,$host_alias,;t t -s,@target_alias@,$target_alias,;t t -s,@DEFS@,$DEFS,;t t -s,@ECHO_C@,$ECHO_C,;t t -s,@ECHO_N@,$ECHO_N,;t t -s,@ECHO_T@,$ECHO_T,;t t -s,@LIBS@,$LIBS,;t t -s,@CC@,$CC,;t t -s,@CFLAGS@,$CFLAGS,;t t -s,@LDFLAGS@,$LDFLAGS,;t t -s,@CPPFLAGS@,$CPPFLAGS,;t t -s,@ac_ct_CC@,$ac_ct_CC,;t t -s,@EXEEXT@,$EXEEXT,;t t -s,@OBJEXT@,$OBJEXT,;t t -s,@CPP@,$CPP,;t t -s,@EGREP@,$EGREP,;t t -s,@AR@,$AR,;t t -s,@ac_ct_AR@,$ac_ct_AR,;t t -s,@RANLIB@,$RANLIB,;t t -s,@ac_ct_RANLIB@,$ac_ct_RANLIB,;t t -s,@RC@,$RC,;t t -s,@ac_ct_RC@,$ac_ct_RC,;t t -s,@SET_MAKE@,$SET_MAKE,;t t -s,@TCL_THREADS@,$TCL_THREADS,;t t -s,@CYGPATH@,$CYGPATH,;t t -s,@CELIB_DIR@,$CELIB_DIR,;t t -s,@DL_LIBS@,$DL_LIBS,;t t -s,@CFLAGS_DEBUG@,$CFLAGS_DEBUG,;t t -s,@CFLAGS_OPTIMIZE@,$CFLAGS_OPTIMIZE,;t t -s,@CFLAGS_WARNING@,$CFLAGS_WARNING,;t t -s,@ZLIB_DLL_FILE@,$ZLIB_DLL_FILE,;t t -s,@ZLIB_LIBS@,$ZLIB_LIBS,;t t -s,@ZLIB_OBJS@,$ZLIB_OBJS,;t t -s,@CFLAGS_DEFAULT@,$CFLAGS_DEFAULT,;t t -s,@LDFLAGS_DEFAULT@,$LDFLAGS_DEFAULT,;t t -s,@VC_MANIFEST_EMBED_DLL@,$VC_MANIFEST_EMBED_DLL,;t t -s,@VC_MANIFEST_EMBED_EXE@,$VC_MANIFEST_EMBED_EXE,;t t -s,@TCL_WIN_VERSION@,$TCL_WIN_VERSION,;t t -s,@MACHINE@,$MACHINE,;t t -s,@TCL_VERSION@,$TCL_VERSION,;t t -s,@TCL_MAJOR_VERSION@,$TCL_MAJOR_VERSION,;t t -s,@TCL_MINOR_VERSION@,$TCL_MINOR_VERSION,;t t -s,@TCL_PATCH_LEVEL@,$TCL_PATCH_LEVEL,;t t -s,@PKG_CFG_ARGS@,$PKG_CFG_ARGS,;t t -s,@TCL_EXE@,$TCL_EXE,;t t -s,@TCL_LIB_FILE@,$TCL_LIB_FILE,;t t -s,@TCL_LIB_FLAG@,$TCL_LIB_FLAG,;t t -s,@TCL_STATIC_LIB_FILE@,$TCL_STATIC_LIB_FILE,;t t -s,@TCL_STATIC_LIB_FLAG@,$TCL_STATIC_LIB_FLAG,;t t -s,@TCL_IMPORT_LIB_FILE@,$TCL_IMPORT_LIB_FILE,;t t -s,@TCL_IMPORT_LIB_FLAG@,$TCL_IMPORT_LIB_FLAG,;t t -s,@TCL_LIB_SPEC@,$TCL_LIB_SPEC,;t t -s,@TCL_STUB_LIB_FILE@,$TCL_STUB_LIB_FILE,;t t -s,@TCL_STUB_LIB_FLAG@,$TCL_STUB_LIB_FLAG,;t t -s,@TCL_STUB_LIB_SPEC@,$TCL_STUB_LIB_SPEC,;t t -s,@TCL_STUB_LIB_PATH@,$TCL_STUB_LIB_PATH,;t t -s,@TCL_INCLUDE_SPEC@,$TCL_INCLUDE_SPEC,;t t -s,@TCL_BUILD_STUB_LIB_SPEC@,$TCL_BUILD_STUB_LIB_SPEC,;t t -s,@TCL_BUILD_STUB_LIB_PATH@,$TCL_BUILD_STUB_LIB_PATH,;t t -s,@TCL_DLL_FILE@,$TCL_DLL_FILE,;t t -s,@TCL_SRC_DIR@,$TCL_SRC_DIR,;t t -s,@TCL_BIN_DIR@,$TCL_BIN_DIR,;t t -s,@TCL_DBGX@,$TCL_DBGX,;t t -s,@CFG_TCL_SHARED_LIB_SUFFIX@,$CFG_TCL_SHARED_LIB_SUFFIX,;t t -s,@CFG_TCL_UNSHARED_LIB_SUFFIX@,$CFG_TCL_UNSHARED_LIB_SUFFIX,;t t -s,@CFG_TCL_EXPORT_FILE_SUFFIX@,$CFG_TCL_EXPORT_FILE_SUFFIX,;t t -s,@EXTRA_CFLAGS@,$EXTRA_CFLAGS,;t t -s,@DEPARG@,$DEPARG,;t t -s,@CC_OBJNAME@,$CC_OBJNAME,;t t -s,@CC_EXENAME@,$CC_EXENAME,;t t -s,@LDFLAGS_DEBUG@,$LDFLAGS_DEBUG,;t t -s,@LDFLAGS_OPTIMIZE@,$LDFLAGS_OPTIMIZE,;t t -s,@LDFLAGS_CONSOLE@,$LDFLAGS_CONSOLE,;t t -s,@LDFLAGS_WINDOW@,$LDFLAGS_WINDOW,;t t -s,@STLIB_LD@,$STLIB_LD,;t t -s,@SHLIB_LD@,$SHLIB_LD,;t t -s,@SHLIB_LD_LIBS@,$SHLIB_LD_LIBS,;t t -s,@SHLIB_CFLAGS@,$SHLIB_CFLAGS,;t t -s,@SHLIB_SUFFIX@,$SHLIB_SUFFIX,;t t -s,@TCL_SHARED_BUILD@,$TCL_SHARED_BUILD,;t t -s,@LIBS_GUI@,$LIBS_GUI,;t t -s,@DLLSUFFIX@,$DLLSUFFIX,;t t -s,@LIBPREFIX@,$LIBPREFIX,;t t -s,@LIBSUFFIX@,$LIBSUFFIX,;t t -s,@EXESUFFIX@,$EXESUFFIX,;t t -s,@LIBRARIES@,$LIBRARIES,;t t -s,@MAKE_LIB@,$MAKE_LIB,;t t -s,@MAKE_STUB_LIB@,$MAKE_STUB_LIB,;t t -s,@POST_MAKE_LIB@,$POST_MAKE_LIB,;t t -s,@MAKE_DLL@,$MAKE_DLL,;t t -s,@MAKE_EXE@,$MAKE_EXE,;t t -s,@TCL_BUILD_LIB_SPEC@,$TCL_BUILD_LIB_SPEC,;t t -s,@TCL_LD_SEARCH_FLAGS@,$TCL_LD_SEARCH_FLAGS,;t t -s,@TCL_NEEDS_EXP_FILE@,$TCL_NEEDS_EXP_FILE,;t t -s,@TCL_BUILD_EXP_FILE@,$TCL_BUILD_EXP_FILE,;t t -s,@TCL_EXP_FILE@,$TCL_EXP_FILE,;t t -s,@TCL_LIB_VERSIONS_OK@,$TCL_LIB_VERSIONS_OK,;t t -s,@TCL_PACKAGE_PATH@,$TCL_PACKAGE_PATH,;t t -s,@TCL_DDE_VERSION@,$TCL_DDE_VERSION,;t t -s,@TCL_DDE_MAJOR_VERSION@,$TCL_DDE_MAJOR_VERSION,;t t -s,@TCL_DDE_MINOR_VERSION@,$TCL_DDE_MINOR_VERSION,;t t -s,@TCL_REG_VERSION@,$TCL_REG_VERSION,;t t -s,@TCL_REG_MAJOR_VERSION@,$TCL_REG_MAJOR_VERSION,;t t -s,@TCL_REG_MINOR_VERSION@,$TCL_REG_MINOR_VERSION,;t t -s,@RC_OUT@,$RC_OUT,;t t -s,@RC_TYPE@,$RC_TYPE,;t t -s,@RC_INCLUDE@,$RC_INCLUDE,;t t -s,@RC_DEFINE@,$RC_DEFINE,;t t -s,@RC_DEFINES@,$RC_DEFINES,;t t -s,@RES@,$RES,;t t -s,@LIBOBJS@,$LIBOBJS,;t t -s,@LTLIBOBJS@,$LTLIBOBJS,;t t -CEOF -_ACEOF +eval set X " :F $CONFIG_FILES " +shift +for ac_tag +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5 ;; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift - cat >>$CONFIG_STATUS <<\_ACEOF - # Split the substitutions into bite-sized pieces for seds with - # small command number limits, like on Digital OSF/1 and HP-UX. - ac_max_sed_lines=48 - ac_sed_frag=1 # Number of current file. - ac_beg=1 # First line for current file. - ac_end=$ac_max_sed_lines # Line after last line for current file. - ac_more_lines=: - ac_sed_cmds= - while $ac_more_lines; do - if test $ac_beg -gt 1; then - sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag - else - sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag - fi - if test ! -s $tmp/subs.frag; then - ac_more_lines=false - else - # The purpose of the label and of the branching condition is to - # speed up the sed processing (if there are no `@' at all, there - # is no need to browse any of the substitutions). - # These are the two extra sed commands mentioned above. - (echo ':t - /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed - if test -z "$ac_sed_cmds"; then - ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed" - else - ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed" - fi - ac_sed_frag=`expr $ac_sed_frag + 1` - ac_beg=$ac_end - ac_end=`expr $ac_end + $ac_max_sed_lines` + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$ac_tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5 ;; + esac + case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac + as_fn_append ac_file_inputs " '$ac_f'" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input='Generated from '` + $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' + `' by configure.' + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 +$as_echo "$as_me: creating $ac_file" >&6;} fi - done - if test -z "$ac_sed_cmds"; then - ac_sed_cmds=cat - fi -fi # test -n "$CONFIG_FILES" + # Neutralize special characters interpreted by sed in replacement strings. + case $configure_input in #( + *\&* | *\|* | *\\* ) + ac_sed_conf_input=`$as_echo "$configure_input" | + sed 's/[\\\\&|]/\\\\&/g'`;; #( + *) ac_sed_conf_input=$configure_input;; + esac -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF -for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue - # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". - case $ac_file in - - | *:- | *:-:* ) # input from stdin - cat >$tmp/stdin - ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` - ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; - *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` - ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; - * ) ac_file_in=$ac_file.in ;; + case $ac_tag in + *:-:* | *:-) cat >"$ac_tmp/stdin" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; + esac + ;; esac - # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories. - ac_dir=`(dirname "$ac_file") 2>/dev/null || + ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ - X"$ac_file" : 'X\(/\)' \| \ - . : '\(.\)' 2>/dev/null || -echo X"$ac_file" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } - /^X\(\/\/\)[^/].*/{ s//\1/; q; } - /^X\(\/\/\)$/{ s//\1/; q; } - /^X\(\/\).*/{ s//\1/; q; } - s/.*/./; q'` - { if $as_mkdir_p; then - mkdir -p "$ac_dir" - else - as_dir="$ac_dir" - as_dirs= - while test ! -d "$as_dir"; do - as_dirs="$as_dir $as_dirs" - as_dir=`(dirname "$as_dir") 2>/dev/null || -$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$as_dir" : 'X\(//\)[^/]' \| \ - X"$as_dir" : 'X\(//\)$' \| \ - X"$as_dir" : 'X\(/\)' \| \ - . : '\(.\)' 2>/dev/null || -echo X"$as_dir" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } - /^X\(\/\/\)[^/].*/{ s//\1/; q; } - /^X\(\/\/\)$/{ s//\1/; q; } - /^X\(\/\).*/{ s//\1/; q; } - s/.*/./; q'` - done - test ! -n "$as_dirs" || mkdir $as_dirs - fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 -echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} - { (exit 1); exit 1; }; }; } - + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir="$ac_dir"; as_fn_mkdir_p ac_builddir=. -if test "$ac_dir" != .; then - ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` - # A "../" for each directory in $ac_dir_suffix. - ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` -else - ac_dir_suffix= ac_top_builddir= -fi +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix case $srcdir in - .) # No --srcdir option. We are building in place. + .) # We are building in place. ac_srcdir=. - if test -z "$ac_top_builddir"; then - ac_top_srcdir=. - else - ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` - fi ;; - [\\/]* | ?:[\\/]* ) # Absolute path. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; - ac_top_srcdir=$srcdir ;; - *) # Relative path. - ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix - ac_top_srcdir=$ac_top_builddir$srcdir ;; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix -# Do not use `cd foo && pwd` to compute absolute paths, because -# the directories may not exist. -case `pwd` in -.) ac_abs_builddir="$ac_dir";; -*) - case "$ac_dir" in - .) ac_abs_builddir=`pwd`;; - [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; - *) ac_abs_builddir=`pwd`/"$ac_dir";; - esac;; -esac -case $ac_abs_builddir in -.) ac_abs_top_builddir=${ac_top_builddir}.;; -*) - case ${ac_top_builddir}. in - .) ac_abs_top_builddir=$ac_abs_builddir;; - [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; - *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; - esac;; -esac -case $ac_abs_builddir in -.) ac_abs_srcdir=$ac_srcdir;; -*) - case $ac_srcdir in - .) ac_abs_srcdir=$ac_abs_builddir;; - [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; - *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; - esac;; -esac -case $ac_abs_builddir in -.) ac_abs_top_srcdir=$ac_top_srcdir;; -*) - case $ac_top_srcdir in - .) ac_abs_top_srcdir=$ac_abs_builddir;; - [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; - *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; - esac;; -esac + case $ac_mode in + :F) + # + # CONFIG_FILE + # +_ACEOF - if test x"$ac_file" != x-; then - { echo "$as_me:$LINENO: creating $ac_file" >&5 -echo "$as_me: creating $ac_file" >&6;} - rm -f "$ac_file" - fi - # Let's still pretend it is `configure' which instantiates (i.e., don't - # use $as_me), people would be surprised to read: - # /* config.h. Generated by config.status. */ - if test x"$ac_file" = x-; then - configure_input= - else - configure_input="$ac_file. " - fi - configure_input=$configure_input"Generated from `echo $ac_file_in | - sed 's,.*/,,'` by configure." - - # First look for the input files in the build tree, otherwise in the - # src tree. - ac_file_inputs=`IFS=: - for f in $ac_file_in; do - case $f in - -) echo $tmp/stdin ;; - [\\/$]*) - # Absolute (can't be DOS-style, as IFS=:) - test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 -echo "$as_me: error: cannot find input file: $f" >&2;} - { (exit 1); exit 1; }; } - echo "$f";; - *) # Relative - if test -f "$f"; then - # Build tree - echo "$f" - elif test -f "$srcdir/$f"; then - # Source tree - echo "$srcdir/$f" - else - # /dev/null tree - { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 -echo "$as_me: error: cannot find input file: $f" >&2;} - { (exit 1); exit 1; }; } - fi;; - esac - done` || { (exit 1); exit 1; } +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= +ac_sed_dataroot=' +/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p' +case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + ac_datarootdir_hack=' + s&@datadir@&$datadir&g + s&@docdir@&$docdir&g + s&@infodir@&$infodir&g + s&@localedir@&$localedir&g + s&@mandir@&$mandir&g + s&\\\${datarootdir}&$datarootdir&g' ;; +esac _ACEOF -cat >>$CONFIG_STATUS <<_ACEOF - sed "$ac_vpsub + +# Neutralize VPATH when `$srcdir' = `.'. +# Shell code in configure.ac might set extrasub. +# FIXME: do we really want to maintain this feature? +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_sed_extra="$ac_vpsub $extrasub _ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b -s,@configure_input@,$configure_input,;t t -s,@srcdir@,$ac_srcdir,;t t -s,@abs_srcdir@,$ac_abs_srcdir,;t t -s,@top_srcdir@,$ac_top_srcdir,;t t -s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t -s,@builddir@,$ac_builddir,;t t -s,@abs_builddir@,$ac_abs_builddir,;t t -s,@top_builddir@,$ac_top_builddir,;t t -s,@abs_top_builddir@,$ac_abs_top_builddir,;t t -" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out - rm -f $tmp/stdin - if test x"$ac_file" != x-; then - mv $tmp/out $ac_file - else - cat $tmp/out - rm -f $tmp/out - fi +s|@configure_input@|$ac_sed_conf_input|;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@top_build_prefix@&$ac_top_build_prefix&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +$ac_datarootdir_hack +" +eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ + >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ + "$ac_tmp/out"`; test -z "$ac_out"; } && + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&5 +$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&2;} + + rm -f "$ac_tmp/stdin" + case $ac_file in + -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; + *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; + esac \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + ;; -done -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF -{ (exit 0); exit 0; } + esac + +done # for ac_tag + + +as_fn_exit 0 _ACEOF -chmod +x $CONFIG_STATUS ac_clean_files=$ac_clean_files_save +test $ac_write_fail = 0 || + as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 + # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. @@ -6278,7 +6430,11 @@ if test "$no_create" != yes; then exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. - $ac_cs_success || { (exit 1); exit 1; } + $ac_cs_success || as_fn_exit 1 +fi +if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 +$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi diff --git a/win/configure.in b/win/configure.in index aa47505..01366f5 100644 --- a/win/configure.in +++ b/win/configure.in @@ -126,20 +126,16 @@ AS_IF([test "${enable_shared+set}" = "set"], [ ], [ tcl_ok=yes ]) -AS_IF([test "$tcl_ok" = "yes"], [ - AC_SUBST(ZLIB_DLL_FILE,[\${ZLIB_DLL_FILE}]) - AS_IF([test "$do64bit" = "yes"], [ - AS_IF([test "$GCC" == "yes"],[ - AC_SUBST(ZLIB_LIBS,[\${ZLIB_DIR}/win64/libz.dll.a]) - ], [ - AC_SUBST(ZLIB_LIBS,[\${ZLIB_DIR}/win64/zdll.lib]) - ]) - ], [ - AC_SUBST(ZLIB_LIBS,[\${ZLIB_DIR}/win32/zdll.lib]) - ]) -], [ - AC_SUBST(ZLIB_OBJS,[\${ZLIB_OBJS}]) -]) +AC_ARG_WITH(zlib, [ --with-zlib use Native Zlib library], + with_zlib=$withval, with_zlib=NO_ZLIB +) +AS_IF( + [test "with_zlib" = "NO_ZLIB"], [AC_SUBST(ZLIB_OBJS,[\${ZLIB_OBJS}])], + [test "$tcl_ok" != "yes"], [AC_SUBST(ZLIB_OBJS,[\${ZLIB_OBJS}])], + [test "$do64bit" = "yes"], [AC_SUBST(ZLIB_OBJS,[\${ZLIB_OBJS}])], + [test "$with_zlib" = "yes"] , [AC_SUBST(ZLIB_LIBS,[\${ZLIB_DIR}/win32/zdll.lib])], + [AC_SUBST(ZLIB_LIBS,[$with_zlib])] +) AC_DEFINE(HAVE_ZLIB, 1, [Is there an installed zlib?]) AC_CHECK_TYPE([intptr_t], [ -- cgit v0.12 From cd9922f497673e31b6fffa759cff4c869927b7fb Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Tue, 2 Sep 2014 18:30:23 +0000 Subject: Pared down tclZipVfs to eliminate #ifdef branches that we don't have to worry about with a modern Tcl. Replaced dummy calls to VFS with NULL Where practical, replaced string-based Tcl IO calls with their new obj-based successors. (Tcl_FSOpenChannel, Tcl_FSStat, etc) Eliminated compiler warnings under Windows --- generic/tclZipVfs.c | 360 +++++++++++++--------------------------------------- 1 file changed, 86 insertions(+), 274 deletions(-) diff --git a/generic/tclZipVfs.c b/generic/tclZipVfs.c index 8b1fc3b..9b377c0 100755 --- a/generic/tclZipVfs.c +++ b/generic/tclZipVfs.c @@ -29,10 +29,6 @@ #include #include -#ifdef TCL_FILESYSTEM_VERSION_1 -#define USE_TCL_VFS 1 -#endif - /* * Size of the decompression input buffer */ @@ -285,9 +281,7 @@ CanonicalPath( for (i=j=0 ; (c = zPath[i]) != 0 ; i++) { #ifdef __WIN32__ if (isupper(c)) { - if (maptolower) { - c = tolower(c); - } + c = tolower(c); } else if (c == '\\') { c = '/'; } @@ -411,7 +405,7 @@ ZvfsReadTOCStart( while (1) { int lenName; /* Length of the next filename */ - int lenExtra; /* Length of "extra" data for next file */ + int lenExtra=0; /* Length of "extra" data for next file */ int iData; /* Offset to start of file data */ if (nFile-- <= 0) { @@ -612,7 +606,7 @@ Tcl_Zvfs_Mount( while (1) { int lenName; /* Length of the next filename */ - int lenExtra; /* Length of "extra" data for next file */ + int lenExtra=0; /* Length of "extra" data for next file */ int iData; /* Offset to start of file data */ int dosTime; int dosDate; @@ -740,35 +734,6 @@ ZvfsLookup( return pFile; } -static int -ZvfsLookupMount( - char *zFilename) -{ - char *zTrueName; - Tcl_HashEntry *pEntry; /* Hash table entry */ - Tcl_HashSearch zSearch; /* Search all mount points */ - ZvfsArchive *pArchive; /* The ZIP archive being mounted */ - int match=0; - - if (local.isInit == 0) { - return 0; - } - zTrueName = AbsolutePath(zFilename); - pEntry = Tcl_FirstHashEntry(&local.archiveHash, &zSearch); - while (pEntry) { - pArchive = Tcl_GetHashValue(pEntry); - if (pArchive) { - if (!strcmp(pArchive->zMountPoint, zTrueName)) { - match = 1; - break; - } - } - pEntry = Tcl_NextHashEntry(&zSearch); - } - Tcl_Free(zTrueName); - return match; -} - /* * Unmount all the files in the given ZIP archive. */ @@ -813,13 +778,6 @@ Tcl_Zvfs_Umount( return 1; } -static void -Zvfs_Unmount( - const char *zArchive) -{ - Tcl_Zvfs_Umount(zArchive); -} - /* * zvfs::mount Zip-archive-name mount-point * @@ -832,19 +790,19 @@ Zvfs_Unmount( * string, mount on file path. */ static int -ZvfsMountCmd( +ZvfsMountObjCmd( ClientData clientData, /* Client data for this command */ Tcl_Interp *interp, /* The interpreter used to report errors */ - int argc, /* Number of arguments */ - const char *argv[]) /* Values of all arguments */ + int objc, /* Number of arguments */ + Tcl_Obj *const* objv) /* Values of all arguments */ { /*TODO: Convert to Tcl_Obj API!*/ - if (argc > 3) { - Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], + if (objc > 3) { + Tcl_AppendResult(interp, "wrong # args: should be \"", Tcl_GetString(objv[0]), " ? ZIP-FILE ? MOUNT-POINT ? ?\"", 0); return TCL_ERROR; } - return Tcl_Zvfs_Mount(interp, argc>1?argv[1]:NULL, argc>2?argv[2]:NULL); + return Tcl_Zvfs_Mount(interp, objc>1?Tcl_GetString(objv[1]):NULL, objc>2?Tcl_GetString(objv[2]):NULL); } /* @@ -853,33 +811,33 @@ ZvfsMountCmd( * Undo the effects of zvfs::mount. */ static int -ZvfsUnmountCmd( +ZvfsUnmountObjCmd( ClientData clientData, /* Client data for this command */ Tcl_Interp *interp, /* The interpreter used to report errors */ - int argc, /* Number of arguments */ - const char *argv[]) /* Values of all arguments */ + int objc, /* Number of arguments */ + Tcl_Obj *const* objv) /* Values of all arguments */ { ZvfsArchive *pArchive; /* The ZIP archive being mounted */ Tcl_HashEntry *pEntry; /* Hash table entry */ Tcl_HashSearch zSearch; /* Search all mount points */ - - if (argc != 2) { - Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], + char *zFilename; + if (objc != 2) { + Tcl_AppendResult(interp, "wrong # args: should be \"", Tcl_GetString(objv[0]), " ZIP-FILE\"", 0); return TCL_ERROR; } - if (Tcl_Zvfs_Umount(argv[1])) { - return TCL_OK; - } - if (!local.isInit) { return TCL_ERROR; } + zFilename=Tcl_GetString(objv[1]); + if (Tcl_Zvfs_Umount(zFilename)) { + return TCL_OK; + } pEntry = Tcl_FirstHashEntry(&local.archiveHash,&zSearch); while (pEntry) { pArchive = Tcl_GetHashValue(pEntry); if (pArchive && pArchive->zMountPoint[0] - && (strcmp(pArchive->zMountPoint, argv[1]) == 0)) { + && (strcmp(pArchive->zMountPoint, zFilename) == 0)) { if (Tcl_Zvfs_Umount(pArchive->zName)) { return TCL_OK; } @@ -888,7 +846,7 @@ ZvfsUnmountCmd( pEntry = Tcl_NextHashEntry(&zSearch); } - Tcl_AppendResult(interp, "unknown zvfs mount point or file: ", argv[1], + Tcl_AppendResult(interp, "unknown zvfs mount point or file: ", zFilename, NULL); return TCL_ERROR; } @@ -1348,7 +1306,7 @@ ZvfsFileOpen( pInfo->readSoFar = 0; Tcl_Seek(chan, INT16(zBuf, 26) + INT16(zBuf, 28), SEEK_CUR); pInfo->startOfData = Tcl_Tell(chan); - sprintf(zName, "vfs_%lx_%x", ((ptrdiff_t)pFile)>>12, count++); + sprintf(zName, "zvfs_%x",count++); chan = Tcl_CreateChannel(&vfsChannelType, zName, pInfo, TCL_READABLE); return chan; } @@ -1357,10 +1315,11 @@ ZvfsFileOpen( * This routine does a stat() system call for a ZVFS file. */ static int -ZvfsFileStat( - char *path, - struct stat *buf) +Tobe_FSStatProc( + Tcl_Obj *pathObj, + Tcl_StatBuf *buf) { + char *path=Tcl_GetString(pathObj); ZvfsFile *pFile; pFile = ZvfsLookup(path); @@ -1385,10 +1344,11 @@ ZvfsFileStat( * This routine does an access() system call for a ZVFS file. */ static int -ZvfsFileAccess( - char *path, +Tobe_FSAccessProc( + Tcl_Obj *pathPtr, int mode) { + char *path=Tcl_GetString(pathPtr); ZvfsFile *pFile; if (mode & 3) { @@ -1401,41 +1361,6 @@ ZvfsFileAccess( return 0; } -#ifndef USE_TCL_VFS - -/* - * This TCL procedure can be used to copy a file. The built-in "file copy" - * command of TCL bypasses the I/O system and does not work with zvfs. You - * have to use a procedure like the following instead. - */ -static char zFileCopy[] = -"proc zvfs::filecopy {from to {outtype binary}} {\n" -" set f [open $from r]\n" -" if {[catch {\n" -" fconfigure $f -translation binary\n" -" set t [open $to w]\n" -" } msg]} {\n" -" close $f\n" -" error $msg\n" -" }\n" -" if {[catch {\n" -" fconfigure $t -translation $outtype\n" -" set size [file size $from]\n" -" for {set i 0} {$i<$size} {incr i 40960} {\n" -" puts -nonewline $t [read $f 40960]\n" -" }\n" -" } msg]} {\n" -" close $f\n" -" close $t\n" -" error $msg\n" -" }\n" -" close $f\n" -" close $t\n" -"}\n" -; - -#else - Tcl_Channel Tobe_FSOpenFileChannelProc( Tcl_Interp *interp, @@ -1457,31 +1382,9 @@ Tobe_FSOpenFileChannelProc( return chan; } -/* - * This routine does a stat() system call for a ZVFS file. - */ -int -Tobe_FSStatProc( - Tcl_Obj *pathPtr, - struct stat *buf) -{ - return ZvfsFileStat(Tcl_GetString(pathPtr), buf); -} - -/* - * This routine does an access() system call for a ZVFS file. - */ -int -Tobe_FSAccessProc( - Tcl_Obj *pathPtr, - int mode) -{ - return ZvfsFileAccess(Tcl_GetString(pathPtr), mode); -} - -/* Tcl_Obj* Tobe_FSFilesystemSeparatorProc(Tcl_Obj *pathPtr) { +Tcl_Obj* Tobe_FSFilesystemSeparatorProc(Tcl_Obj *pathPtr) { return Tcl_NewStringObj("/",-1);; -} */ +} /* * Function to process a 'Tobe_FSMatchInDirectory()'. If not implemented, @@ -1567,10 +1470,7 @@ Tobe_FSPathInFilesystemProc( { ZvfsFile *zFile; char *path = Tcl_GetString(pathPtr); - -// if (ZvfsLookupMount(path)!=0) -// return TCL_OK; -// // TODO: also check this is the archive. + if (openarch) { return -1; } @@ -1605,14 +1505,6 @@ Tobe_FSListVolumesProc(void) return pVols; } -int -Tobe_FSChdirProc( - Tcl_Obj *pathPtr) -{ - /* Someday, we should actually check if this is a valid path. */ - return TCL_OK; -} - const char * const* Tobe_FSFileAttrStringsProc( Tcl_Obj *pathPtr, @@ -1642,7 +1534,9 @@ Tobe_FSFileAttrsGetProc( Tcl_Obj **objPtrRef) { char *path = Tcl_GetString(pathPtr); +#ifndef __WIN32__ char buf[50]; +#endif ZvfsFile *zFile = ZvfsLookup(path); if (zFile == 0) { @@ -1677,79 +1571,15 @@ Tobe_FSFileAttrsGetProc( /****************************************************/ -// At some point, some of the following might get implemented? - -#if 1 -#define Tobe_FSFilesystemSeparatorProc 0 -#define Tobe_FSLoadFileProc 0 -#define Tobe_FSUnloadFileProc 0 -#define Tobe_FSGetCwdProc 0 -#define Tobe_FSGetCwdProc 0 -#define Tobe_FSCreateDirectoryProc 0 -#define Tobe_FSDeleteFileProc 0 -#define Tobe_FSCopyDirectoryProc 0 -#define Tobe_FSCopyFileProc 0 -#define Tobe_FSRemoveDirectoryProc 0 -#define Tobe_FSFileAttrsSetProc 0 -#define Tobe_FSNormalizePathProc 0 -#define Tobe_FSUtimeProc 0 -#define Tobe_FSRenameFileProc 0 -#define Tobe_FSCreateInternalRepProc 0 -#define Tobe_FSInternalToNormalizedProc 0 -#define Tobe_FSDupInternalRepProc 0 -#define Tobe_FSFreeInternalRepProc 0 -#define Tobe_FSFilesystemPathTypeProc 0 -#define Tobe_FSLinkProc 0 -#else - -/* - * Function to process a 'Tobe_FSLoadFile()' call. If not implemented, Tcl - * will fall back on a copy to native-temp followed by a Tobe_FSLoadFile on - * that temporary copy. - */ -int -Tobe_FSLoadFileProc( - Tcl_Interp * interp, - Tcl_Obj *pathPtr, - char * sym1, - char * sym2, - Tcl_PackageInitProc ** proc1Ptr, - Tcl_PackageInitProc ** proc2Ptr, - ClientData * clientDataPtr) -{ - return 0; -} - /* * Function to unload a previously successfully loaded file. If load was * implemented, then this should also be implemented, if there is any cleanup * action required. */ -void Tobe_FSUnloadFileProc(ClientData clientData) { return; } -Tcl_Obj* Tobe_FSGetCwdProc(Tcl_Interp *interp) { return 0; } -int Tobe_FSCreateDirectoryProc(Tcl_Obj *pathPtr) { return 0; } -int Tobe_FSDeleteFileProc(Tcl_Obj *pathPtr) { return 0; } -int Tobe_FSCopyDirectoryProc(Tcl_Obj *srcPathPtr, Tcl_Obj *destPathPtr, - Tcl_Obj **errorPtr) { return 0; } -int Tobe_FSCopyFileProc(Tcl_Obj *srcPathPtr, - Tcl_Obj *destPathPtr) { return 0; } -int Tobe_FSRemoveDirectoryProc(Tcl_Obj *pathPtr, int recursive, - Tcl_Obj **errorPtr) { return 0; } -int Tobe_FSRenameFileProc(Tcl_Obj *srcPathPtr, - Tcl_Obj *destPathPtr) { return 0; } /* We have to declare the utime structure here. */ int Tobe_FSUtimeProc(Tcl_Obj *pathPtr, struct utimbuf *tval) { return 0; } -int Tobe_FSNormalizePathProc(Tcl_Interp *interp, Tcl_Obj *pathPtr, - int nextCheckpoint) { return 0; } int Tobe_FSFileAttrsSetProc(Tcl_Interp *interp, int index, Tcl_Obj *pathPtr, Tcl_Obj *objPtr) { return 0; } -Tcl_Obj* Tobe_FSLinkProc(Tcl_Obj *pathPtr) { return 0; } -Tcl_Obj* Tobe_FSFilesystemPathTypeProc(Tcl_Obj *pathPtr) { return 0; } -void Tobe_FSFreeInternalRepProc(ClientData clientData) { return; } -ClientData Tobe_FSDupInternalRepProc(ClientData clientData) { return 0; } -Tcl_Obj* Tobe_FSInternalToNormalizedProc(ClientData clientData) { return 0; } -ClientData Tobe_FSCreateInternalRepProc(Tcl_Obj *pathPtr) { return 0; } -#endif static Tcl_Filesystem Tobe_Filesystem = { "tobe", /* The name of the filesystem. */ @@ -1759,17 +1589,17 @@ static Tcl_Filesystem Tobe_Filesystem = { Tobe_FSPathInFilesystemProc,/* Function to check whether a path is in this * filesystem. This is the most important * filesystem procedure. */ - Tobe_FSDupInternalRepProc, /* Function to duplicate internal fs rep. May + NULL, /* Function to duplicate internal fs rep. May * be NULL (but then fs is less efficient). */ - Tobe_FSFreeInternalRepProc, /* Function to free internal fs rep. Must be + NULL, /* Function to free internal fs rep. Must be * implemented, if internal representations * need freeing, otherwise it can be NULL. */ - Tobe_FSInternalToNormalizedProc, + NULL, /* Function to convert internal representation * to a normalized path. Only required if the * fs creates pure path objects with no * string/path representation. */ - Tobe_FSCreateInternalRepProc, + NULL, /* Function to create a filesystem-specific * internal representation. May be NULL if * paths have no internal representation, or @@ -1777,11 +1607,11 @@ static Tcl_Filesystem Tobe_Filesystem = { * filesystem always immediately creates an * internal representation for paths it * accepts. */ - Tobe_FSNormalizePathProc, /* Function to normalize a path. Should be + NULL, /* Function to normalize a path. Should be * implemented for all filesystems which can * have multiple string representations for * the same path object. */ - Tobe_FSFilesystemPathTypeProc, + NULL, /* Function to determine the type of a path in * this filesystem. May be NULL. */ Tobe_FSFilesystemSeparatorProc, @@ -1808,7 +1638,7 @@ static Tcl_Filesystem Tobe_Filesystem = { * reading) of times with 'file mtime', 'file * atime' and the open-r/open-w/fcopy * implementation of 'file copy'. */ - Tobe_FSLinkProc, /* Function to process a 'Tobe_FSLink()' call. + NULL, /* Function to process a 'Tobe_FSLink()' call. * Should be implemented only if the * filesystem supports links. */ Tobe_FSListVolumesProc, /* Function to list any filesystem volumes @@ -1828,42 +1658,42 @@ static Tcl_Filesystem Tobe_Filesystem = { Tobe_FSFileAttrsSetProc, /* Function to process a * 'Tobe_FSFileAttrsSet()' call, used by 'file * attributes'. */ - Tobe_FSCreateDirectoryProc, /* Function to process a + NULL, /* Function to process a * 'Tobe_FSCreateDirectory()' call. Should be * implemented unless the FS is read-only. */ - Tobe_FSRemoveDirectoryProc, /* Function to process a + NULL, /* Function to process a * 'Tobe_FSRemoveDirectory()' call. Should be * implemented unless the FS is read-only. */ - Tobe_FSDeleteFileProc, /* Function to process a 'Tobe_FSDeleteFile()' + NULL, /* Function to process a 'Tobe_FSDeleteFile()' * call. Should be implemented unless the FS * is read-only. */ - Tobe_FSCopyFileProc, /* Function to process a 'Tobe_FSCopyFile()' + NULL, /* Function to process a 'Tobe_FSCopyFile()' * call. If not implemented Tcl will fall * back on open-r, open-w and fcopy as a * copying mechanism. */ - Tobe_FSRenameFileProc, /* Function to process a 'Tobe_FSRenameFile()' + NULL, /* Function to process a 'Tobe_FSRenameFile()' * call. If not implemented, Tcl will fall * back on a copy and delete mechanism. */ - Tobe_FSCopyDirectoryProc, /* Function to process a + NULL, /* Function to process a * 'Tobe_FSCopyDirectory()' call. If not * implemented, Tcl will fall back on a * recursive create-dir, file copy * mechanism. */ - Tobe_FSLoadFileProc, /* Function to process a 'Tobe_FSLoadFile()' + NULL, /* Function to process a 'Tobe_FSLoadFile()' * call. If not implemented, Tcl will fall * back on a copy to native-temp followed by a * Tobe_FSLoadFile on that temporary copy. */ - Tobe_FSUnloadFileProc, /* Function to unload a previously + NULL, /* Function to unload a previously * successfully loaded file. If load was * implemented, then this should also be * implemented, if there is any cleanup action * required. */ - Tobe_FSGetCwdProc, /* Function to process a 'Tobe_FSGetCwd()' + NULL, /* Function to process a 'Tobe_FSGetCwd()' * call. Most filesystems need not implement * this. It will usually only be called once, * if 'getcwd' is called before 'chdir'. May * be NULL. */ - Tobe_FSChdirProc, /* Function to process a 'Tobe_FSChdir()' + NULL, /* Function to process a 'Tobe_FSChdir()' * call. If filesystems do not implement this, * it will be emulated by a series of * directory access checks. Otherwise, virtual @@ -1880,8 +1710,6 @@ static Tcl_Filesystem Tobe_Filesystem = { * filesystem. */ }; -#endif - ////////////////////////////////////////////////////////////// void (*Zvfs_PostInit)(Tcl_Interp *) = 0; @@ -1898,7 +1726,6 @@ Zvfs_doInit( Tcl_Interp *interp, int safe) { - int n; #ifdef USE_TCL_STUBS if (Tcl_InitStubs(interp, "8.0", 0) == 0) { return TCL_ERROR; @@ -1906,8 +1733,8 @@ Zvfs_doInit( #endif Tcl_StaticPackage(interp, "zvfs", Tcl_Zvfs_Init, Tcl_Zvfs_SafeInit); if (!safe) { - Tcl_CreateCommand(interp, "zvfs::mount", ZvfsMountCmd, 0, 0); - Tcl_CreateCommand(interp, "zvfs::unmount", ZvfsUnmountCmd, 0, 0); + Tcl_CreateObjCommand(interp, "zvfs::mount", ZvfsMountObjCmd, 0, 0); + Tcl_CreateObjCommand(interp, "zvfs::unmount", ZvfsUnmountObjCmd, 0, 0); Tcl_CreateObjCommand(interp, "zvfs::append", ZvfsAppendObjCmd, 0, 0); Tcl_CreateObjCommand(interp, "zvfs::add", ZvfsAddObjCmd, 0, 0); } @@ -1919,22 +1746,12 @@ Zvfs_doInit( Tcl_SetVar(interp, "::zvfs::auto_ext", ".tcl .tk .itcl .htcl .txt .c .h .tht", TCL_GLOBAL_ONLY); /* Tcl_CreateObjCommand(interp, "zip::open", ZipOpenObjCmd, 0, 0); */ -#ifndef USE_TCL_VFS - Tcl_GlobalEval(interp, zFileCopy); -#endif + if (!local.isInit) { /* One-time initialization of the ZVFS */ -#ifdef USE_TCL_VFS - n = Tcl_FSRegister(0, &Tobe_Filesystem); -#else - extern void TclAccessInsertProc(); - extern void TclStatInsertProc(); - extern void TclOpenFileChannelInsertProc(); - - TclAccessInsertProc(ZvfsFileAccess); - TclStatInsertProc(ZvfsFileStat); - TclOpenFileChannelInsertProc(ZvfsFileOpen); -#endif + if(Tcl_FSRegister(NULL, &Tobe_Filesystem)) { + return TCL_ERROR; + } Tcl_InitHashTable(&local.fileHash, TCL_STRING_KEYS); Tcl_InitHashTable(&local.archiveHash, TCL_STRING_KEYS); local.isInit = 1; @@ -1979,7 +1796,7 @@ ZvfsDumpObjCmd( int objc, /* Number of arguments */ Tcl_Obj *const* objv) /* Values of all arguments */ { - char *zFilename; + Tcl_Obj *zFilenameObj; Tcl_Channel chan; ZFile *pList; int rc; @@ -1989,8 +1806,8 @@ ZvfsDumpObjCmd( Tcl_WrongNumArgs(interp, 1, objv, "FILENAME"); return TCL_ERROR; } - zFilename = Tcl_GetString(objv[1]); - chan = Tcl_OpenFileChannel(interp, zFilename, "r", 0); + zFilenameObj=objv[1]; + chan = Tcl_FSOpenFileChannel(interp, zFilenameObj, "r", 0); if (chan == 0) { return TCL_ERROR; } @@ -2021,7 +1838,7 @@ ZvfsDumpObjCmd( Tcl_ListObjAppendElement(interp, pResult, pEntry); pNext = pList->pNext; Tcl_Free((void *) pList); - pList = pList->pNext; + pList = pNext; } return TCL_OK; } @@ -2037,10 +1854,12 @@ writeFile( Tcl_Interp *interp, /* Leave an error message here */ Tcl_Channel out, /* Write the file here */ Tcl_Channel in, /* Read data from this file */ - char *zSrc, /* Name the new ZIP file entry this */ - char *zDest, /* Name the new ZIP file entry this */ + Tcl_Obj *zSrcPtr, /* Name the new ZIP file entry this */ + Tcl_Obj *zDestPtr, /* Name the new ZIP file entry this */ ZFile **ppList) /* Put a ZFile struct for the new file here */ { + char *zDest=Tcl_GetString(zDestPtr); + z_stream stream; ZFile *p; int iEndOfData; @@ -2052,7 +1871,7 @@ writeFile( char zOutBuf[100000]; struct tm *tm; time_t now; - struct stat stat; + Tcl_StatBuf stat; /* * Create a new ZFile structure for this file. @@ -2062,7 +1881,7 @@ writeFile( p = newZFile(nameLen, ppList); strcpy(p->zName, zDest); p->isSpecial = 0; - Tcl_Stat(zSrc, &stat); + Tcl_FSStat(zSrcPtr, &stat); now = stat.st_mtime; tm = localtime(&now); UnixTimeDate(tm, &p->dosDate, &p->dosTime); @@ -2112,16 +1931,8 @@ writeFile( stream.next_in = (unsigned char *) zInBuf; stream.avail_out = sizeof(zOutBuf); stream.next_out = (unsigned char *) zOutBuf; -#if 1 deflateInit(&stream, 9); -#else - { - int i, err, WSIZE = 0x8000, windowBits, level=6; - for (i = ((unsigned)WSIZE), windowBits = 0; i != 1; i >>= 1, ++windowBits); - err = deflateInit2(&stream, level, Z_DEFLATED, -windowBits, 8, 0); - } -#endif p->iCRC = crc32(0, 0, 0); while (!Tcl_Eof(in)) { @@ -2341,7 +2152,7 @@ ZvfsAppendObjCmd( int objc, /* Number of arguments */ Tcl_Obj *const* objv) /* Values of all arguments */ { - char *zArchive; + Tcl_Obj *zArchiveObj; Tcl_Channel chan; ZFile *pList = NULL, *pToc; int rc = TCL_OK, i; @@ -2355,10 +2166,10 @@ ZvfsAppendObjCmd( return TCL_ERROR; } - zArchive = Tcl_GetString(objv[1]); - chan = Tcl_OpenFileChannel(interp, zArchive, "r+", 0644); + zArchiveObj=objv[1]; + chan = Tcl_FSOpenFileChannel(interp, zArchiveObj, "r+", 0644); if (chan == 0) { - chan = Tcl_OpenFileChannel(interp, zArchive, "w+", 0644); + chan = Tcl_FSOpenFileChannel(interp, zArchiveObj, "w+", 0644); if (chan == 0) { return TCL_ERROR; } @@ -2401,15 +2212,15 @@ ZvfsAppendObjCmd( */ for (i=2; rc==TCL_OK && i Date: Tue, 2 Sep 2014 20:16:54 +0000 Subject: Added a hac^H^H^Hpatch from ferrieux to mask around the exit hang on windows until the issues are fixed at the core level. --- generic/tclEvent.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/generic/tclEvent.c b/generic/tclEvent.c index 941d566..3bb6c62 100644 --- a/generic/tclEvent.c +++ b/generic/tclEvent.c @@ -1299,18 +1299,19 @@ Tcl_FinalizeThread(void) TclFinalizeAsync(); TclFinalizeThreadObjects(); } - - /* - * Blow away all thread local storage blocks. - * - * Note that Tcl API allows creation of threads which do not use any Tcl - * interp or other Tcl subsytems. Those threads might, however, use thread - * local storage, so we must unconditionally finalize it. - * - * Fix [Bug #571002] - */ - - TclFinalizeThreadData(); + if (!TclInExit()) { + /* + * Blow away all thread local storage blocks. + * + * Note that Tcl API allows creation of threads which do not use any Tcl + * interp or other Tcl subsytems. Those threads might, however, use thread + * local storage, so we must unconditionally finalize it. + * + * Fix [Bug #571002] + */ + + TclFinalizeThreadData(); + } } /* -- cgit v0.12 From 8ca1a78b1a5befabf5e8d8e27bd5d80fb6ab9582 Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Tue, 2 Sep 2014 20:26:50 +0000 Subject: Revised patch (per ferrieux) --- generic/tclEvent.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generic/tclEvent.c b/generic/tclEvent.c index 3bb6c62..a7cd467 100644 --- a/generic/tclEvent.c +++ b/generic/tclEvent.c @@ -1299,7 +1299,7 @@ Tcl_FinalizeThread(void) TclFinalizeAsync(); TclFinalizeThreadObjects(); } - if (!TclInExit()) { + if (TclFullFinalizationRequested()) { /* * Blow away all thread local storage blocks. * -- cgit v0.12 From 06547a29be3e6ccdecc327ce843d939bea668600 Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Tue, 2 Sep 2014 21:16:20 +0000 Subject: Fix for the cases where a dynamic build is used --- win/configure | 41 ++++++++++++++++++++++++++++++++--------- win/configure.in | 24 +++++++++++++++++++----- 2 files changed, 51 insertions(+), 14 deletions(-) diff --git a/win/configure b/win/configure index d8ee198..4414f2d 100755 --- a/win/configure +++ b/win/configure @@ -678,8 +678,9 @@ VC_MANIFEST_EMBED_EXE VC_MANIFEST_EMBED_DLL LDFLAGS_DEFAULT CFLAGS_DEFAULT -ZLIB_LIBS ZLIB_OBJS +ZLIB_LIBS +ZLIB_DLL_FILE CFLAGS_WARNING CFLAGS_OPTIMIZE CFLAGS_DEBUG @@ -4669,20 +4670,42 @@ else fi -if test "with_zlib" = "NO_ZLIB"; then : - ZLIB_OBJS=\${ZLIB_OBJS} +if test "$tcl_ok" = "yes"; then : -elif test "$tcl_ok" != "yes"; then : - ZLIB_OBJS=\${ZLIB_OBJS} + ZLIB_DLL_FILE=\${ZLIB_DLL_FILE} -elif test "$do64bit" = "yes"; then : - ZLIB_OBJS=\${ZLIB_OBJS} +fi +tcl_no_zlib_dll=no +if test "$with_zlib" = "NO_ZLIB"; then : + tcl_no_zlib_dll=yes +elif test "$tcl_ok" != "yes"; then : + tcl_no_zlib_dll=yes +elif test "$do64bit" = "yes"; then : + tcl_no_zlib_dll=yes elif test "$with_zlib" = "yes" ; then : - ZLIB_LIBS=\${ZLIB_DIR}/win32/zdll.lib + + ZLIB_DLL_FILE=\${ZLIB_DLL_FILE} + + ZLIB_LIBS=\${ZLIB_DIR}/win32/zdll.lib + else - ZLIB_LIBS=$with_zlib + + ZLIB_DLL_FILE=${with_zlib} + + ZLIB_LIBS=$with_zlib + + + +fi +if test "$tcl_no_zlib_dll" = "yes"; then : + + ZLIB_OBJS=\${ZLIB_OBJS} + + ZLIB_DLL_FILE="" + + ZLIB_LIBS="" fi diff --git a/win/configure.in b/win/configure.in index 01366f5..dec470a 100644 --- a/win/configure.in +++ b/win/configure.in @@ -129,13 +129,27 @@ AS_IF([test "${enable_shared+set}" = "set"], [ AC_ARG_WITH(zlib, [ --with-zlib use Native Zlib library], with_zlib=$withval, with_zlib=NO_ZLIB ) +AS_IF([test "$tcl_ok" = "yes"], [ + AC_SUBST(ZLIB_DLL_FILE,[\${ZLIB_DLL_FILE}]) +]) +tcl_no_zlib_dll=no AS_IF( - [test "with_zlib" = "NO_ZLIB"], [AC_SUBST(ZLIB_OBJS,[\${ZLIB_OBJS}])], - [test "$tcl_ok" != "yes"], [AC_SUBST(ZLIB_OBJS,[\${ZLIB_OBJS}])], - [test "$do64bit" = "yes"], [AC_SUBST(ZLIB_OBJS,[\${ZLIB_OBJS}])], - [test "$with_zlib" = "yes"] , [AC_SUBST(ZLIB_LIBS,[\${ZLIB_DIR}/win32/zdll.lib])], - [AC_SUBST(ZLIB_LIBS,[$with_zlib])] + [test "$with_zlib" = "NO_ZLIB"], [tcl_no_zlib_dll=yes], + [test "$tcl_ok" != "yes"], [tcl_no_zlib_dll=yes], + [test "$do64bit" = "yes"], [tcl_no_zlib_dll=yes], + [test "$with_zlib" = "yes"] , [ + AC_SUBST(ZLIB_DLL_FILE,[\${ZLIB_DLL_FILE}]) + AC_SUBST(ZLIB_LIBS,[\${ZLIB_DIR}/win32/zdll.lib]) + ], [ + AC_SUBST(ZLIB_DLL_FILE,[${with_zlib}]) + AC_SUBST(ZLIB_LIBS,[$with_zlib]) + ] ) +AS_IF([test "$tcl_no_zlib_dll" = "yes"], [ + AC_SUBST(ZLIB_OBJS,[\${ZLIB_OBJS}]) + AC_SUBST(ZLIB_DLL_FILE,[""]) + AC_SUBST(ZLIB_LIBS,[""]) +]) AC_DEFINE(HAVE_ZLIB, 1, [Is there an installed zlib?]) AC_CHECK_TYPE([intptr_t], [ -- cgit v0.12 From 6c2512bc35c2c94e80f3bac2dc723147db4d6461 Mon Sep 17 00:00:00 2001 From: dkf Date: Wed, 3 Sep 2014 10:24:53 +0000 Subject: Clean up of docs, import basic text from comments in code, format. --- doc/zvfs.n | 153 +++++++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 114 insertions(+), 39 deletions(-) diff --git a/doc/zvfs.n b/doc/zvfs.n index ba33fb6..f2ad9aa 100644 --- a/doc/zvfs.n +++ b/doc/zvfs.n @@ -1,39 +1,114 @@ -'\" -'\" Copyright (c) 2014 Sean Woods -'\" -'\" See the file "license.terms" for information on usage and redistribution -'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" -.TH zvfs n 0.1 Zvfs "Zvfs Commands" -.so man.macros -.BS -'\" Note: do not modify the .SH NAME line immediately below! -.SH NAME -http \- Client-side implementation of the HTTP/1.1 protocol -.SH SYNOPSIS -\fBpackage require zvfs ?0.1?\fR -.sp -\fB::zvfs::mount \fIZIPFILE \fIMOUNTPOINT\fR ...? -.sp -\fB::zvfs::unmount \fIZIPFILE\fR ...? -.sp -\fB::zvfs::append ?\fI\-option value\fR ...? -.sp -\fB::zvfs::add ?\fI\-option value\fR ...? -.sp -\fB::zvfs::exists ?\fI\-option value\fR ...? -.sp -\fB::zvfs::info ?\fI\-option value\fR ...? -.sp -\fB::zvfs::list ?\fI\-option value\fR ...? -.sp -\fB::zvfs::dump ?\fI\-option value\fR ...? -.sp -\fB::zvfs::start ?\fI\-option value\fR ...? -.BE -.SH DESCRIPTION -.PP -The \fBzvfs\fR package provides tcl with the ability to manipulate -the contents of a zip file archive as a virtual file system. -.PP -The \fB::zvfs::mount\fR procedure mounts a zipfile as a VFS. \ No newline at end of file +'\" +'\" Copyright (c) 2014 Sean Woods +'\" +'\" See the file "license.terms" for information on usage and redistribution +'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. +'\" +.TH zvfs n 0.1 Zvfs "Zvfs Commands" +.so man.macros +.BS +'\" Note: do not modify the .SH NAME line immediately below! +.SH NAME +zvfs \- Mount and work with ZIP files within Tcl +.SH SYNOPSIS +.nf +\fBpackage require zvfs \fR?\fB0.1\fR? +.sp +\fB::zvfs::add\fR ?\fB\-fconfigure \fIoptpairs...\fR? \fIarchive file1\fR ?\fIfile2 ...\fR? +\fB::zvfs::append\fR \fIarchive\fR ?\fIsource destination\fR? ?\fIsource destination...\fR? +\fB::zvfs::dump\fR \fIzipfile\fR +\fB::zvfs::exists\fR \fIfilename\fR +\fB::zvfs::info\fR \fIfile\fR +\fB::zvfs::list\fR ?\fB\-glob\fR|\fB\-regexp\fR? ?\fIpattern\fR? +\fB::zvfs::mount ?\fIarchive\fR? ?\fImountpoint\fR? +\fB::zvfs::start\fR \fIzipfile\fR +\fB::zvfs::unmount \fIarchive\fR +.fi +.BE +.SH DESCRIPTION +.PP +The \fBzvfs\fR package provides tcl with the ability to manipulate +the contents of a zip file archive as a virtual file system. +.TP +\fB::zvfs::mount ?\fIarchive\fR? ?\fImountpoint\fR? +. +The \fB::zvfs::mount\fR procedure mounts a zipfile as a VFS. +After this command +executes, files contained in the ZIP archive, \fIarchive\fR, will appear to Tcl to be +regular files at the mount point. +.RS +.PP +With no \fImountpoint\fR, returns the mount point for \fIarchive\fR. With no \fIarchive\fR, +return all archive/mount pairs. If \fImountpoint\fR is specified as an empty +string, mount on file path. +.RE +.TP +\fB::zvfs::unmount \fIarchive\fR +. +Unmounts a previously mounted zip, \fIarchive\fR. +.TP +\fB::zvfs::append\fR \fIarchive\fR ?\fIsource destination\fR? ?\fIsource destination...\fR? +. +This command reads \fIsource\fR files and appends them (using the name +\fIdestination\fR) to the zip archive named \fIarchive\fR. A new zip archive is created +if it does not already exist. If \fIarchive\fR refers to a file which exists but +is not a zip archive, then this command turns \fIarchive\fR into a zip archive by +appending the necessary records and the table of contents. Treat all files +as binary. +.RS +.PP +Note: No duplicate checking is done, so multiple occurances of the same file is +allowed. +.RE +.TP +\fB::zvfs::add\fR ?\fB\-fconfigure \fIoptpairs...\fR? \fIarchive file1\fR ?\fIfile2 ...\fR? +. +This command is similar to \fBzvfs::append\fR in that it adds files to the zip archive +named \fIarchive\fR, however file names are relative the current directory. In +addition, \fBfconfigure\fR is used to apply option pairs to set upon opening of +each file. Otherwise, default translation is allowed for those file +extensions listed in the \fB::zvfs::auto_ext\fR variable. Binary translation will be +used for unknown extensions. +.RS +.PP +NOTE: Use +.QW "\fB\-fconfigure {}\fR" +to use auto translation for all. +.RE +.TP +\fB::zvfs::exists\fR \fIfilename\fR +. +Return TRUE if the given filename exists in the mounted ZVFS and FALSE if it does +not. +.TP +\fB::zvfs::info\fR \fIfile\fR +. +Return information about the given file in the mounted ZVFS. The information +consists of (1) the name of the ZIP archive that contains the file, (2) the +size of the file after decompressions, (3) the compressed size of the file, +and (4) the offset of the compressed data in the archive. +.RS +.PP +Note: querying the mount point gives the start of zip data offset in (4), +which can be used to truncate the zip info off an executable. +.RE +.TP +\fB::zvfs::list\fR ?\fB\-glob\fR|\fB\-regexp\fR? ?\fIpattern\fR? +. +Return a list of all files in the mounted ZVFS. The order of the names in the list +is arbitrary. +.TP +\fB::zvfs::dump\fR \fIzipfile\fR +. +Describe the contents of a zip. +.TP +\fB::zvfs::start\fR \fIzipfile\fR +. +This command strips returns the offset of zip data. +.SH "SEE ALSO" +tclsh(1), file(n), zlib(n) +.SH "KEYWORDS" +compress, filesystem, zip +'\" Local Variables: +'\" mode: nroff +'\" End: -- cgit v0.12 From 8d1d673760dab89fb53dc4ef0f4366c432e80bd5 Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Wed, 3 Sep 2014 10:50:06 +0000 Subject: Backported dkf's documentation effort to the main core_zip_vfs branch --- doc/tclsh.1 | 9 +++++ doc/zvfs.n | 114 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 123 insertions(+) create mode 100644 doc/zvfs.n diff --git a/doc/tclsh.1 b/doc/tclsh.1 index 6ed5eb6..25d97c5 100644 --- a/doc/tclsh.1 +++ b/doc/tclsh.1 @@ -143,6 +143,15 @@ incomplete commands. .SH "STANDARD CHANNELS" .PP See \fBTcl_StandardChannels\fR for more explanations. +.SH ZIPVFS +.PP +When a zipfile is concatenated to the end of a \fBtclsh\fR, on +startup the contents of the zip archive will be mounted as the +virtual file system /zvfs. If a top level directory tcl8.6 is +present in the zip archive, it will become the directory loaded +as env(TCL_LIBRARY). If a file named \fBmain.tcl\fR is present +in the top level directory of the zip archive, it will be sourced +instead of the shell's normal command line handing. .SH "SEE ALSO" auto_path(n), encoding(n), env(n), fconfigure(n) .SH KEYWORDS diff --git a/doc/zvfs.n b/doc/zvfs.n new file mode 100644 index 0000000..f2ad9aa --- /dev/null +++ b/doc/zvfs.n @@ -0,0 +1,114 @@ +'\" +'\" Copyright (c) 2014 Sean Woods +'\" +'\" See the file "license.terms" for information on usage and redistribution +'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. +'\" +.TH zvfs n 0.1 Zvfs "Zvfs Commands" +.so man.macros +.BS +'\" Note: do not modify the .SH NAME line immediately below! +.SH NAME +zvfs \- Mount and work with ZIP files within Tcl +.SH SYNOPSIS +.nf +\fBpackage require zvfs \fR?\fB0.1\fR? +.sp +\fB::zvfs::add\fR ?\fB\-fconfigure \fIoptpairs...\fR? \fIarchive file1\fR ?\fIfile2 ...\fR? +\fB::zvfs::append\fR \fIarchive\fR ?\fIsource destination\fR? ?\fIsource destination...\fR? +\fB::zvfs::dump\fR \fIzipfile\fR +\fB::zvfs::exists\fR \fIfilename\fR +\fB::zvfs::info\fR \fIfile\fR +\fB::zvfs::list\fR ?\fB\-glob\fR|\fB\-regexp\fR? ?\fIpattern\fR? +\fB::zvfs::mount ?\fIarchive\fR? ?\fImountpoint\fR? +\fB::zvfs::start\fR \fIzipfile\fR +\fB::zvfs::unmount \fIarchive\fR +.fi +.BE +.SH DESCRIPTION +.PP +The \fBzvfs\fR package provides tcl with the ability to manipulate +the contents of a zip file archive as a virtual file system. +.TP +\fB::zvfs::mount ?\fIarchive\fR? ?\fImountpoint\fR? +. +The \fB::zvfs::mount\fR procedure mounts a zipfile as a VFS. +After this command +executes, files contained in the ZIP archive, \fIarchive\fR, will appear to Tcl to be +regular files at the mount point. +.RS +.PP +With no \fImountpoint\fR, returns the mount point for \fIarchive\fR. With no \fIarchive\fR, +return all archive/mount pairs. If \fImountpoint\fR is specified as an empty +string, mount on file path. +.RE +.TP +\fB::zvfs::unmount \fIarchive\fR +. +Unmounts a previously mounted zip, \fIarchive\fR. +.TP +\fB::zvfs::append\fR \fIarchive\fR ?\fIsource destination\fR? ?\fIsource destination...\fR? +. +This command reads \fIsource\fR files and appends them (using the name +\fIdestination\fR) to the zip archive named \fIarchive\fR. A new zip archive is created +if it does not already exist. If \fIarchive\fR refers to a file which exists but +is not a zip archive, then this command turns \fIarchive\fR into a zip archive by +appending the necessary records and the table of contents. Treat all files +as binary. +.RS +.PP +Note: No duplicate checking is done, so multiple occurances of the same file is +allowed. +.RE +.TP +\fB::zvfs::add\fR ?\fB\-fconfigure \fIoptpairs...\fR? \fIarchive file1\fR ?\fIfile2 ...\fR? +. +This command is similar to \fBzvfs::append\fR in that it adds files to the zip archive +named \fIarchive\fR, however file names are relative the current directory. In +addition, \fBfconfigure\fR is used to apply option pairs to set upon opening of +each file. Otherwise, default translation is allowed for those file +extensions listed in the \fB::zvfs::auto_ext\fR variable. Binary translation will be +used for unknown extensions. +.RS +.PP +NOTE: Use +.QW "\fB\-fconfigure {}\fR" +to use auto translation for all. +.RE +.TP +\fB::zvfs::exists\fR \fIfilename\fR +. +Return TRUE if the given filename exists in the mounted ZVFS and FALSE if it does +not. +.TP +\fB::zvfs::info\fR \fIfile\fR +. +Return information about the given file in the mounted ZVFS. The information +consists of (1) the name of the ZIP archive that contains the file, (2) the +size of the file after decompressions, (3) the compressed size of the file, +and (4) the offset of the compressed data in the archive. +.RS +.PP +Note: querying the mount point gives the start of zip data offset in (4), +which can be used to truncate the zip info off an executable. +.RE +.TP +\fB::zvfs::list\fR ?\fB\-glob\fR|\fB\-regexp\fR? ?\fIpattern\fR? +. +Return a list of all files in the mounted ZVFS. The order of the names in the list +is arbitrary. +.TP +\fB::zvfs::dump\fR \fIzipfile\fR +. +Describe the contents of a zip. +.TP +\fB::zvfs::start\fR \fIzipfile\fR +. +This command strips returns the offset of zip data. +.SH "SEE ALSO" +tclsh(1), file(n), zlib(n) +.SH "KEYWORDS" +compress, filesystem, zip +'\" Local Variables: +'\" mode: nroff +'\" End: -- cgit v0.12 From b6f9bc7ca80044ec0d8f106974a7adb0544a339f Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Wed, 3 Sep 2014 20:41:12 +0000 Subject: More tweaks to makefiles --- unix/Makefile.in | 1 - win/Makefile.in | 13 ++++++++----- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/unix/Makefile.in b/unix/Makefile.in index 8f260d0..f9d713d 100644 --- a/unix/Makefile.in +++ b/unix/Makefile.in @@ -654,7 +654,6 @@ null.zip: zip null.zip .empty ${TCLKIT_EXE}: ${TCL_EXE} null.zip - rm -f tclkit.zip PWD=`pwd` cp -f ${TCL_EXE} ${TCLKIT_EXE} cat null.zip >> ${TCLKIT_EXE} diff --git a/win/Makefile.in b/win/Makefile.in index f302ed6..d99e204 100644 --- a/win/Makefile.in +++ b/win/Makefile.in @@ -426,12 +426,15 @@ $(TCLSH): $(TCLSH_OBJS) @LIBRARIES@ $(TCL_STUB_LIB_FILE) tclsh.$(RES) tclkit: $(TCLKIT) -$(TCLKIT): $(TCLSH) - rm -f tclkit.zip +null.zip: + touch .empty + zip null.zip .empty + +$(TCLKIT): $(TCLSH) null.zip PWD=`pwd` - cd ${prefix}/lib ; zip -rq ${PWD}/tclkit.zip tcl8 tcl8.6 - cp -f $(TCLSH) $(TCLKIT) - cat tclkit.zip >> $(TCLKIT) + cp -f $(WISH) $(TCLKIT) + cat null.zip >> $(TCLKIT) + cd ${prefix}/lib ; zip -rAq ${PWD}/$(TCLKIT) tcl8 tcl8.6 cat32.$(OBJEXT): cat.c $(CC) -c $(CC_SWITCHES) @DEPARG@ $(CC_OBJNAME) -- cgit v0.12 From 4691bea988bc3a8d8eb072348163aa2e17c69b85 Mon Sep 17 00:00:00 2001 From: tne Date: Wed, 3 Sep 2014 22:03:08 +0000 Subject: Typo Fix --- win/Makefile.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/win/Makefile.in b/win/Makefile.in index d99e204..0874147 100644 --- a/win/Makefile.in +++ b/win/Makefile.in @@ -432,7 +432,7 @@ null.zip: $(TCLKIT): $(TCLSH) null.zip PWD=`pwd` - cp -f $(WISH) $(TCLKIT) + cp -f $(TCLSH) $(TCLKIT) cat null.zip >> $(TCLKIT) cd ${prefix}/lib ; zip -rAq ${PWD}/$(TCLKIT) tcl8 tcl8.6 -- cgit v0.12 From b992e62207d7ecfeeacc81983c34cad57423930d Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Thu, 4 Sep 2014 00:30:04 +0000 Subject: Re-engineered the windows kitbuilding process to produce a standalone executable (in a similar process as tcltest is made). The kit specific functions of tclAppInit have been wrapped around define macros, and are only active if TCL_KIT is defined. (Which is only done when building the tclkit executable) --- generic/tclZipVfs.c | 3 +++ win/Makefile.in | 14 +++++++++++--- win/tclAppInit.c | 10 +++++++--- 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/generic/tclZipVfs.c b/generic/tclZipVfs.c index 7baf469..ed2ddcc 100755 --- a/generic/tclZipVfs.c +++ b/generic/tclZipVfs.c @@ -1785,7 +1785,10 @@ int Tcl_Zvfs_Boot(Tcl_Interp *interp) { Tcl_IncrRefCount(vfstklib); if(Tcl_FSAccess(vfsinitscript,F_OK)==0) { + /* Startup script should be set before calling Tcl_AppInit */ Tcl_SetStartupScript(vfsinitscript,NULL); + } else { + Tcl_SetStartupScript(NULL,NULL); } if(Tcl_FSAccess(vfstcllib,F_OK)==0) { Tcl_SetVar2(interp, "env", "TCL_LIBRARY", Tcl_GetString(vfstcllib), TCL_GLOBAL_ONLY); diff --git a/win/Makefile.in b/win/Makefile.in index 0874147..3e44cff 100644 --- a/win/Makefile.in +++ b/win/Makefile.in @@ -392,6 +392,9 @@ STUB_OBJS = \ TCLSH_OBJS = tclAppInit.$(OBJEXT) +TCLKIT_OBJS = tclKitInit.$(OBJEXT) + + ZLIB_OBJS = \ adler32.$(OBJEXT) \ compress.$(OBJEXT) \ @@ -428,11 +431,13 @@ tclkit: $(TCLKIT) null.zip: touch .empty - zip null.zip .empty + zip -q null.zip .empty -$(TCLKIT): $(TCLSH) null.zip +$(TCLKIT): $(TCLKIT_OBJS) @LIBRARIES@ $(TCL_STUB_LIB_FILE) tclsh.$(RES) null.zip + $(CC) $(CFLAGS) $(TCLKIT_OBJS) $(TCL_LIB_FILE) $(TCL_STUB_LIB_FILE) $(LIBS) \ + tclsh.$(RES) $(CC_EXENAME) $(LDFLAGS_CONSOLE) + @VC_MANIFEST_EMBED_EXE@ PWD=`pwd` - cp -f $(TCLSH) $(TCLKIT) cat null.zip >> $(TCLKIT) cd ${prefix}/lib ; zip -rAq ${PWD}/$(TCLKIT) tcl8 tcl8.6 @@ -499,6 +504,9 @@ testMain.${OBJEXT}: tclAppInit.c tclMain2.${OBJEXT}: tclMain.c $(CC) -c $(CC_SWITCHES) -DBUILD_tcl -DTCL_ASCII_MAIN @DEPARG@ $(CC_OBJNAME) +tclKitInit.$(OBJEXT): tclAppInit.c + $(CC) -c $(CC_SWITCHES) -DTCL_KIT @DEPARG@ $(CC_OBJNAME) + # TIP #59, embedding of configuration information into the binary library. # # Part of Tcl's configuration information are the paths where it was installed diff --git a/win/tclAppInit.c b/win/tclAppInit.c index a8eac66..c6b3b44 100644 --- a/win/tclAppInit.c +++ b/win/tclAppInit.c @@ -15,7 +15,6 @@ */ #include "tcl.h" -#include "tclInt.h" #define WIN32_LEAN_AND_MEAN #include #undef WIN32_LEAN_AND_MEAN @@ -124,7 +123,11 @@ _tmain( #ifdef TCL_LOCAL_MAIN_HOOK TCL_LOCAL_MAIN_HOOK(&argc, &argv); #endif - +#if defined TCL_KIT + /* This voodoo ensures that Tcl_Main does not eat the first argument */ + Tcl_FindExecutable(argv[0]); + Tcl_SetStartupScript(Tcl_NewStringObj("/zvfs/main.tcl",-1),NULL); +#endif Tcl_Main(argc, argv, TCL_LOCAL_APPINIT); return 0; /* Needed only to prevent compiler warning. */ } @@ -152,8 +155,9 @@ int Tcl_AppInit( Tcl_Interp *interp) /* Interpreter for application. */ { +#if defined TCL_KIT Tcl_Zvfs_Boot(interp); - +#endif if ((Tcl_Init)(interp) == TCL_ERROR) { return TCL_ERROR; } -- cgit v0.12 From 703177e26a844971a0376dd6feb70d586a8bae97 Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Thu, 4 Sep 2014 01:22:20 +0000 Subject: Adapted the Unix startup process to ifdef out the KIT specific behaviors. tclkit is now build as a standalone exectuble. --- unix/Makefile.in | 18 +++++++++++++----- unix/tclAppInit.c | 11 +++++++++-- 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/unix/Makefile.in b/unix/Makefile.in index f9d713d..8f77687 100644 --- a/unix/Makefile.in +++ b/unix/Makefile.in @@ -285,6 +285,9 @@ ${AC_FLAGS} ${PROTO_FLAGS} ${EXTRA_CFLAGS} @EXTRA_CC_SWITCHES@ TCLSH_OBJS = tclAppInit.o +TCLKIT_OBJS = tclKitInit.o + + TCLTEST_OBJS = tclTestInit.o tclTest.o tclTestObj.o tclTestProcBodyObj.o \ tclThreadTest.o tclUnixTest.o @@ -648,19 +651,24 @@ ${TCL_EXE}: ${TCLSH_OBJS} ${TCL_LIB_FILE} ${TCL_STUB_LIB_FILE} ${CC} ${CFLAGS} ${LDFLAGS} ${TCLSH_OBJS} \ @TCL_BUILD_LIB_SPEC@ ${TCL_STUB_LIB_FILE} ${LIBS} @EXTRA_TCLSH_LIBS@ \ ${CC_SEARCH_FLAGS} -o ${TCL_EXE} + +# Must be empty so it doesn't conflict with rule for ${TCL_EXE} above +${NATIVE_TCLSH}: null.zip: touch .empty zip null.zip .empty -${TCLKIT_EXE}: ${TCL_EXE} null.zip +${TCLKIT_EXE}: ${TCL_LIB_FILE} ${TCL_STUB_LIB_FILE} null.zip + $(CC) -c $(APP_CC_SWITCHES) \ + -DTCL_KIT $(UNIX_DIR)/tclAppInit.c -o tclKitInit.o + ${CC} ${CFLAGS} ${LDFLAGS} tclKitInit.o \ + @TCL_BUILD_LIB_SPEC@ ${TCL_STUB_LIB_FILE} ${LIBS} @EXTRA_TCLSH_LIBS@ \ + ${CC_SEARCH_FLAGS} -o ${TCLKIT_EXE} PWD=`pwd` cp -f ${TCL_EXE} ${TCLKIT_EXE} cat null.zip >> ${TCLKIT_EXE} cd ${prefix}/lib ; zip -rAq ${PWD}/${TCLKIT_EXE} tcl8 tcl8.6 - -# Must be empty so it doesn't conflict with rule for ${TCL_EXE} above -${NATIVE_TCLSH}: Makefile: $(UNIX_DIR)/Makefile.in $(DLTEST_DIR)/Makefile.in $(SHELL) config.status @@ -1035,7 +1043,7 @@ xtTestInit.o: $(UNIX_DIR)/tclAppInit.c ${TCL_EXE} @if test -f tclAppInit.sav ; then \ mv tclAppInit.sav tclAppInit.o; \ fi; - + # Object files used on all Unix systems: REGHDRS=$(GENERIC_DIR)/regex.h $(GENERIC_DIR)/regguts.h \ diff --git a/unix/tclAppInit.c b/unix/tclAppInit.c index 95dc38e..acd6aa1 100644 --- a/unix/tclAppInit.c +++ b/unix/tclAppInit.c @@ -80,7 +80,12 @@ main( #ifdef TCL_LOCAL_MAIN_HOOK TCL_LOCAL_MAIN_HOOK(&argc, &argv); #endif - +#ifdef TCL_KIT + printf("Running Kit Mode\n"); + /* This voodoo ensures that Tcl_Main does not eat the first argument */ + Tcl_FindExecutable(argv[0]); + Tcl_SetStartupScript(Tcl_NewStringObj("/zvfs/main.tcl",-1),NULL); +#endif Tcl_Main(argc, argv, TCL_LOCAL_APPINIT); return 0; /* Needed only to prevent compiler warning. */ } @@ -108,8 +113,10 @@ int Tcl_AppInit( Tcl_Interp *interp) /* Interpreter for application. */ { +#ifdef TCL_KIT Tcl_Zvfs_Boot(interp); - +#endif + if ((Tcl_Init)(interp) == TCL_ERROR) { return TCL_ERROR; } -- cgit v0.12 From 295272b73c55a78fda55d5fa34edaa20fcc7f14c Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Thu, 4 Sep 2014 01:23:45 +0000 Subject: Removed some debugging code of mine... --- unix/tclAppInit.c | 1 - 1 file changed, 1 deletion(-) diff --git a/unix/tclAppInit.c b/unix/tclAppInit.c index acd6aa1..55e0452 100644 --- a/unix/tclAppInit.c +++ b/unix/tclAppInit.c @@ -81,7 +81,6 @@ main( TCL_LOCAL_MAIN_HOOK(&argc, &argv); #endif #ifdef TCL_KIT - printf("Running Kit Mode\n"); /* This voodoo ensures that Tcl_Main does not eat the first argument */ Tcl_FindExecutable(argv[0]); Tcl_SetStartupScript(Tcl_NewStringObj("/zvfs/main.tcl",-1),NULL); -- cgit v0.12 From a813938befa49293741ca51da80f5bb0eb24ae36 Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Thu, 4 Sep 2014 01:27:55 +0000 Subject: Removed a typo --- unix/Makefile.in | 1 - 1 file changed, 1 deletion(-) diff --git a/unix/Makefile.in b/unix/Makefile.in index 8f77687..9310753 100644 --- a/unix/Makefile.in +++ b/unix/Makefile.in @@ -666,7 +666,6 @@ ${TCLKIT_EXE}: ${TCL_LIB_FILE} ${TCL_STUB_LIB_FILE} null.zip @TCL_BUILD_LIB_SPEC@ ${TCL_STUB_LIB_FILE} ${LIBS} @EXTRA_TCLSH_LIBS@ \ ${CC_SEARCH_FLAGS} -o ${TCLKIT_EXE} PWD=`pwd` - cp -f ${TCL_EXE} ${TCLKIT_EXE} cat null.zip >> ${TCLKIT_EXE} cd ${prefix}/lib ; zip -rAq ${PWD}/${TCLKIT_EXE} tcl8 tcl8.6 -- cgit v0.12 From 3bd1370dbc61266dbec306b5333d22c4c11d81e0 Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Sat, 6 Sep 2014 00:58:23 +0000 Subject: New build process for Tcl kits in Unix (Windows port to follow...) Rather than force a "make install" to build the vfs, the tclkit now performs it's own "install" to a subdirectory (using destdir) to collect the files it needs for its vfs. tclkits no longer link to the tcl library. Instead, all of the obj files that are used to assemble the lib are instead packed into the executable. Thus, "make tclkit" produces the tclkit. That's it. No dlls. No tclsh. Makes no other mark on the file system save the bare essentials it needs. It uses the same variables in the makefile as the tcl libraries, so as they are updated so too is tclkit. Zlib files are *always* build for tclkits. Tclkits can never rely on the presence of zlib on the systems in which they will be installed. --- generic/tcl.decls | 2 +- generic/tclDecls.h | 6 ++-- generic/tclZipVfs.c | 37 ++++++++++++++++++----- unix/Makefile.in | 33 +++++++++++++------- unix/tclKitInit.c | 86 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 143 insertions(+), 21 deletions(-) create mode 100644 unix/tclKitInit.c diff --git a/generic/tcl.decls b/generic/tcl.decls index 5b0220e..c24898e 100644 --- a/generic/tcl.decls +++ b/generic/tcl.decls @@ -2328,7 +2328,7 @@ declare 630 { # ZipVfs declare 631 { - int Tcl_Zvfs_Boot(Tcl_Interp *interp) +int Tcl_Zvfs_Boot(Tcl_Interp *interp,const char *vfsmountpoint,const char *initscript) } ############################################################################## diff --git a/generic/tclDecls.h b/generic/tclDecls.h index 06b46f0..65d940d 100644 --- a/generic/tclDecls.h +++ b/generic/tclDecls.h @@ -1816,7 +1816,9 @@ EXTERN void Tcl_ZlibStreamSetCompressionDictionary( Tcl_ZlibStream zhandle, Tcl_Obj *compressionDictionaryObj); /* 631 */ -EXTERN int Tcl_Zvfs_Boot(Tcl_Interp *interp); +EXTERN int Tcl_Zvfs_Boot(Tcl_Interp *interp, + const char *vfsmountpoint, + const char *initscript); typedef struct { const struct TclPlatStubs *tclPlatStubs; @@ -2483,7 +2485,7 @@ typedef struct TclStubs { void * (*tcl_FindSymbol) (Tcl_Interp *interp, Tcl_LoadHandle handle, const char *symbol); /* 628 */ int (*tcl_FSUnloadFile) (Tcl_Interp *interp, Tcl_LoadHandle handlePtr); /* 629 */ void (*tcl_ZlibStreamSetCompressionDictionary) (Tcl_ZlibStream zhandle, Tcl_Obj *compressionDictionaryObj); /* 630 */ - int (*tcl_Zvfs_Boot) (Tcl_Interp *interp); /* 631 */ + int (*tcl_Zvfs_Boot) (Tcl_Interp *interp, const char *vfsmountpoint, const char *initscript); /* 631 */ } TclStubs; extern const TclStubs *tclStubsPtr; diff --git a/generic/tclZipVfs.c b/generic/tclZipVfs.c index ed2ddcc..dc96313 100755 --- a/generic/tclZipVfs.c +++ b/generic/tclZipVfs.c @@ -1765,9 +1765,10 @@ Zvfs_doInit( /* ** Boot a shell, mount the executable's VFS, detect main.tcl */ -int Tcl_Zvfs_Boot(Tcl_Interp *interp) { - +int Tcl_Zvfs_Boot(Tcl_Interp *interp,const char *vfsmountpoint,const char *initscript) { CONST char *cp=Tcl_GetNameOfExecutable(); + char filepath[256]; + /* We have to initialize the virtual filesystem before calling ** Tcl_Init(). Otherwise, Tcl_Init() will not be able to find ** its startup script files. @@ -1775,11 +1776,23 @@ int Tcl_Zvfs_Boot(Tcl_Interp *interp) { if(Zvfs_doInit(interp, 0)) { return TCL_ERROR; } - if(!Tcl_Zvfs_Mount(interp, cp, "/zvfs")) { - Tcl_Obj *vfsinitscript=Tcl_NewStringObj("/zvfs/main.tcl",-1); - Tcl_Obj *vfstcllib=Tcl_NewStringObj("/zvfs/tcl8.6",-1); - Tcl_Obj *vfstklib=Tcl_NewStringObj("/zvfs/tk8.6",-1); - + if(!Tcl_Zvfs_Mount(interp, cp, vfsmountpoint)) { + Tcl_Obj *vfsinitscript; + Tcl_Obj *vfstcllib; + Tcl_Obj *vfstklib; + + + strcpy(filepath,vfsmountpoint); + strcat(filepath,"/"); + strcat(filepath,initscript); + vfsinitscript=Tcl_NewStringObj(filepath,-1); + strcpy(filepath,vfsmountpoint); + strcat(filepath,"/tcl8.6"); + vfstcllib=Tcl_NewStringObj(filepath,-1); + strcpy(filepath,vfsmountpoint); + strcat(filepath,"/tk8.6"); + vfstklib=Tcl_NewStringObj(filepath,-1); + Tcl_IncrRefCount(vfsinitscript); Tcl_IncrRefCount(vfstcllib); Tcl_IncrRefCount(vfstklib); @@ -1790,17 +1803,27 @@ int Tcl_Zvfs_Boot(Tcl_Interp *interp) { } else { Tcl_SetStartupScript(NULL,NULL); } + + if(Tcl_FSAccess(vfsinitscript,F_OK)==0) { + /* Startup script should be set before calling Tcl_AppInit */ + Tcl_SetStartupScript(vfsinitscript,NULL); + } else { + Tcl_SetStartupScript(NULL,NULL); + } if(Tcl_FSAccess(vfstcllib,F_OK)==0) { Tcl_SetVar2(interp, "env", "TCL_LIBRARY", Tcl_GetString(vfstcllib), TCL_GLOBAL_ONLY); } if(Tcl_FSAccess(vfstklib,F_OK)==0) { Tcl_SetVar2(interp, "env", "TK_LIBRARY", Tcl_GetString(vfstklib), TCL_GLOBAL_ONLY); } + Tcl_DecrRefCount(vfsinitscript); Tcl_DecrRefCount(vfstcllib); + Tcl_DecrRefCount(vfstklib); } return TCL_OK; } + int Tcl_Zvfs_Init( diff --git a/unix/Makefile.in b/unix/Makefile.in index 9310753..30e7109 100644 --- a/unix/Makefile.in +++ b/unix/Makefile.in @@ -285,9 +285,6 @@ ${AC_FLAGS} ${PROTO_FLAGS} ${EXTRA_CFLAGS} @EXTRA_CC_SWITCHES@ TCLSH_OBJS = tclAppInit.o -TCLKIT_OBJS = tclKitInit.o - - TCLTEST_OBJS = tclTestInit.o tclTest.o tclTestObj.o tclTestProcBodyObj.o \ tclThreadTest.o tclUnixTest.o @@ -363,6 +360,8 @@ ZLIB_OBJS = Zadler32.o Zcompress.o Zcrc32.o Zdeflate.o Zinfback.o \ TCL_OBJS = ${GENERIC_OBJS} ${UNIX_OBJS} ${NOTIFY_OBJS} ${COMPAT_OBJS} \ ${OO_OBJS} @DL_OBJS@ @PLAT_OBJS@ +TCLKIT_OBJS = tclKitInit.o + OBJS = ${TCL_OBJS} ${TOMMATH_OBJS} @DTRACE_OBJ@ @ZLIB_OBJS@ TCL_DECLS = \ @@ -555,6 +554,7 @@ UNIX_HDRS = \ UNIX_SRCS = \ $(UNIX_DIR)/tclAppInit.c \ + $(UNIX_DIR)/tclKitInit.c \ $(UNIX_DIR)/tclUnixChan.c \ $(UNIX_DIR)/tclUnixEvent.c \ $(UNIX_DIR)/tclUnixFCmd.c \ @@ -612,6 +612,9 @@ ZLIB_SRCS = \ SRCS = $(GENERIC_SRCS) $(TOMMATH_SRCS) $(UNIX_SRCS) $(NOTIFY_SRCS) \ $(OO_SRCS) $(STUB_SRCS) @PLAT_SRCS@ @ZLIB_SRCS@ +PWD=`pwd` +VFS_INSTALL_DIR=${PWD}/tclkit.vfs/tcl8.6 + #-------------------------------------------------------------------------- # Start of rules #-------------------------------------------------------------------------- @@ -659,15 +662,21 @@ null.zip: touch .empty zip null.zip .empty -${TCLKIT_EXE}: ${TCL_LIB_FILE} ${TCL_STUB_LIB_FILE} null.zip - $(CC) -c $(APP_CC_SWITCHES) \ - -DTCL_KIT $(UNIX_DIR)/tclAppInit.c -o tclKitInit.o - ${CC} ${CFLAGS} ${LDFLAGS} tclKitInit.o \ - @TCL_BUILD_LIB_SPEC@ ${TCL_STUB_LIB_FILE} ${LIBS} @EXTRA_TCLSH_LIBS@ \ +# Rather than force an install, pack the files we need into a +# file system under our control +tclkit.vfs: + make install-libraries DESTDIR=tclkit.vfs + make install-tzdata DESTDIR=tclkit.vfs + make install-packages DESTDIR=tclkit.vfs + +# Assemble all of the tcl sources into a single executable +${TCLKIT_EXE}: ${TCLKIT_OBJS} ${TCL_OBJS} ${TOMMATH_OBJS} ${ZLIB_OBJS} null.zip tclkit.vfs + ${CC} ${CFLAGS} ${LDFLAGS} \ + ${TCLKIT_OBJS} ${TCL_OBJS} ${TOMMATH_OBJS} ${ZLIB_OBJS} \ + ${LIBS} @EXTRA_TCLSH_LIBS@ \ ${CC_SEARCH_FLAGS} -o ${TCLKIT_EXE} - PWD=`pwd` cat null.zip >> ${TCLKIT_EXE} - cd ${prefix}/lib ; zip -rAq ${PWD}/${TCLKIT_EXE} tcl8 tcl8.6 + cd tclkit.vfs${prefix}/lib ; zip -rAq ${UNIX_DIR}/${TCLKIT_EXE} . Makefile: $(UNIX_DIR)/Makefile.in $(DLTEST_DIR)/Makefile.in $(SHELL) config.status @@ -676,7 +685,9 @@ Makefile: $(UNIX_DIR)/Makefile.in $(DLTEST_DIR)/Makefile.in clean: clean-packages rm -f *.a *.o libtcl* core errs *~ \#* TAGS *.E a.out \ - errors ${TCL_EXE} ${TCLTEST_EXE} lib.exp Tcl @DTRACE_HDR@ + errors ${TCL_EXE} ${TCLTEST_EXE} lib.exp Tcl @DTRACE_HDR@ \ + ${TCLKIT_EXE} + rm -rf tclkit.vfs null.zip cd dltest ; $(MAKE) clean distclean: distclean-packages clean diff --git a/unix/tclKitInit.c b/unix/tclKitInit.c new file mode 100644 index 0000000..96861de --- /dev/null +++ b/unix/tclKitInit.c @@ -0,0 +1,86 @@ +/* +** This file implements the main routine for a standalone Tcl/Tk shell. +*/ +#include +#include "tclInt.h" +#define TCLKIT_INIT "main.tcl" +#define TCLKIT_VFSMOUNT "/zvfs" + +#define TCL_LOCAL_APPINIT Tclkit_AppInit +MODULE_SCOPE int TCL_LOCAL_APPINIT(Tcl_Interp *); +MODULE_SCOPE int main(int, char **); + +/* +** This routine runs first. +*/ +int main(int argc, char **argv){ + Tcl_FindExecutable(argv[0]); + Tcl_SetStartupScript(Tcl_NewStringObj("noop",-1),NULL); + Tcl_Main(argc,argv,&Tclkit_AppInit); + return TCL_OK; +} + + +/* + *---------------------------------------------------------------------- + * + * Tclkit_AppInit -- + * + * This procedure performs application-specific initialization. Most + * applications, especially those that incorporate additional packages, + * will have their own version of this procedure. + * + * Results: + * Returns a standard Tcl completion code, and leaves an error message in + * the interp's result if an error occurs. + * + * Side effects: + * Depends on the startup script. + * + *---------------------------------------------------------------------- + */ + +int +Tclkit_AppInit( + Tcl_Interp *interp) /* Interpreter for application. */ +{ + Tcl_Zvfs_Boot(interp,TCLKIT_VFSMOUNT,TCLKIT_INIT); + + if ((Tcl_Init)(interp) == TCL_ERROR) { + return TCL_ERROR; + } + + /* + * Call the init procedures for included packages. Each call should look + * like this: + * + * if (Mod_Init(interp) == TCL_ERROR) { + * return TCL_ERROR; + * } + * + * where "Mod" is the name of the module. (Dynamically-loadable packages + * should have the same entry-point name.) + */ + + /* + * Call Tcl_CreateCommand for application-specific commands, if they + * weren't already created by the init procedures called above. + */ + + /* + * Specify a user-specific startup file to invoke if the application is + * run interactively. Typically the startup file is "~/.apprc" where "app" + * is the name of the application. If this line is deleted then no + * user-specific startup file will be run under any conditions. + */ + +#ifdef DJGPP + (Tcl_ObjSetVar2)(interp, Tcl_NewStringObj("tcl_rcFileName", -1), NULL, + Tcl_NewStringObj("~/tclsh.rc", -1), TCL_GLOBAL_ONLY); +#else + (Tcl_ObjSetVar2)(interp, Tcl_NewStringObj("tcl_rcFileName", -1), NULL, + Tcl_NewStringObj("~/.tclshrc", -1), TCL_GLOBAL_ONLY); +#endif + + return TCL_OK; +} \ No newline at end of file -- cgit v0.12 From 0008ed9ea4c5bf8c010649489a28c86839ebdf0c Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Sat, 6 Sep 2014 01:21:54 +0000 Subject: Preliminary checkin for Windows tclkit builds --- unix/tclAppInit.c | 14 +-- win/Makefile.in | 16 ++- win/tclAppInit.c | 9 +- win/tclKitInit.c | 324 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 339 insertions(+), 24 deletions(-) create mode 100644 win/tclKitInit.c diff --git a/unix/tclAppInit.c b/unix/tclAppInit.c index 55e0452..9bbc88b 100644 --- a/unix/tclAppInit.c +++ b/unix/tclAppInit.c @@ -15,7 +15,7 @@ #undef BUILD_tcl #undef STATIC_BUILD #include "tcl.h" -#include "tclInt.h" + #ifdef TCL_TEST extern Tcl_PackageInitProc Tcltest_Init; extern Tcl_PackageInitProc Tcltest_SafeInit; @@ -80,11 +80,7 @@ main( #ifdef TCL_LOCAL_MAIN_HOOK TCL_LOCAL_MAIN_HOOK(&argc, &argv); #endif -#ifdef TCL_KIT - /* This voodoo ensures that Tcl_Main does not eat the first argument */ - Tcl_FindExecutable(argv[0]); - Tcl_SetStartupScript(Tcl_NewStringObj("/zvfs/main.tcl",-1),NULL); -#endif + Tcl_Main(argc, argv, TCL_LOCAL_APPINIT); return 0; /* Needed only to prevent compiler warning. */ } @@ -112,10 +108,6 @@ int Tcl_AppInit( Tcl_Interp *interp) /* Interpreter for application. */ { -#ifdef TCL_KIT - Tcl_Zvfs_Boot(interp); -#endif - if ((Tcl_Init)(interp) == TCL_ERROR) { return TCL_ERROR; } @@ -132,7 +124,7 @@ Tcl_AppInit( } Tcl_StaticPackage(interp, "Tcltest", Tcltest_Init, Tcltest_SafeInit); #endif /* TCL_TEST */ - + /* * Call the init procedures for included packages. Each call should look * like this: diff --git a/win/Makefile.in b/win/Makefile.in index 3e44cff..e85cc16 100644 --- a/win/Makefile.in +++ b/win/Makefile.in @@ -433,13 +433,19 @@ null.zip: touch .empty zip -q null.zip .empty -$(TCLKIT): $(TCLKIT_OBJS) @LIBRARIES@ $(TCL_STUB_LIB_FILE) tclsh.$(RES) null.zip - $(CC) $(CFLAGS) $(TCLKIT_OBJS) $(TCL_LIB_FILE) $(TCL_STUB_LIB_FILE) $(LIBS) \ - tclsh.$(RES) $(CC_EXENAME) $(LDFLAGS_CONSOLE) +# Rather than force an install, pack the files we need into a +# file system under our control +tclkit.vfs: + make install-libraries DESTDIR=tclkit.vfs + make install-tzdata DESTDIR=tclkit.vfs + make install-packages DESTDIR=tclkit.vfs + +$(TCLKIT): $(TCLKIT_OBJS) $(TCL_OBJS) $(TOMMATH_OBJS) $(ZLIB_OBJS) tclsh.$(RES) null.zip tclkit.vfs + $(CC) $(CFLAGS) $(TCLKIT_OBJS) $(TCL_OBJS) $(TOMMATH_OBJS) $(ZLIB_OBJS) \ + $(LIBS) tclsh.$(RES) $(CC_EXENAME) $(LDFLAGS_CONSOLE) @VC_MANIFEST_EMBED_EXE@ - PWD=`pwd` cat null.zip >> $(TCLKIT) - cd ${prefix}/lib ; zip -rAq ${PWD}/$(TCLKIT) tcl8 tcl8.6 + cd tclkit.vfs${prefix}/lib ; zip -rAq $(WIN_DIR)/$(TCLKIT) tcl8 tcl8.6 cat32.$(OBJEXT): cat.c $(CC) -c $(CC_SWITCHES) @DEPARG@ $(CC_OBJNAME) diff --git a/win/tclAppInit.c b/win/tclAppInit.c index c6b3b44..a6c1a67 100644 --- a/win/tclAppInit.c +++ b/win/tclAppInit.c @@ -123,11 +123,7 @@ _tmain( #ifdef TCL_LOCAL_MAIN_HOOK TCL_LOCAL_MAIN_HOOK(&argc, &argv); #endif -#if defined TCL_KIT - /* This voodoo ensures that Tcl_Main does not eat the first argument */ - Tcl_FindExecutable(argv[0]); - Tcl_SetStartupScript(Tcl_NewStringObj("/zvfs/main.tcl",-1),NULL); -#endif + Tcl_Main(argc, argv, TCL_LOCAL_APPINIT); return 0; /* Needed only to prevent compiler warning. */ } @@ -155,9 +151,6 @@ int Tcl_AppInit( Tcl_Interp *interp) /* Interpreter for application. */ { -#if defined TCL_KIT - Tcl_Zvfs_Boot(interp); -#endif if ((Tcl_Init)(interp) == TCL_ERROR) { return TCL_ERROR; } diff --git a/win/tclKitInit.c b/win/tclKitInit.c new file mode 100644 index 0000000..69a298c --- /dev/null +++ b/win/tclKitInit.c @@ -0,0 +1,324 @@ +/* + * tclAppInit.c -- + * + * Provides a default version of the main program and TclKit_AppInit + * procedure for tclsh and other Tcl-based applications (without Tk). + * Note that this program must be built in Win32 console mode to work + * properly. + * + * Copyright (c) 1993 The Regents of the University of California. + * Copyright (c) 1994-1997 Sun Microsystems, Inc. + * Copyright (c) 1998-1999 Scriptics Corporation. + * + * See the file "license.terms" for information on usage and redistribution of + * this file, and for a DISCLAIMER OF ALL WARRANTIES. + */ + +#include "tcl.h" +#define WIN32_LEAN_AND_MEAN +#include +#undef WIN32_LEAN_AND_MEAN +#include +#include +#include + +extern Tcl_PackageInitProc Registry_Init; +extern Tcl_PackageInitProc Dde_Init; +extern Tcl_PackageInitProc Dde_SafeInit; + +#ifdef TCL_BROKEN_MAINARGS +int _CRT_glob = 0; +static void setargv(int *argcPtr, TCHAR ***argvPtr); +#endif /* TCL_BROKEN_MAINARGS */ + +/* + * The following #if block allows you to change the AppInit function by using + * a #define of TCL_LOCAL_APPINIT instead of rewriting this entire file. The + * #if checks for that #define and uses TclKit_AppInit if it does not exist. + */ +#define TCLKIT_INIT "main.tcl" +#define TCLKIT_VFSMOUNT "/zvfs" +#ifndef TCL_LOCAL_APPINIT +#define TCL_LOCAL_APPINIT TclKit_AppInit +#endif +#ifndef MODULE_SCOPE +# define MODULE_SCOPE extern +#endif +MODULE_SCOPE int TCL_LOCAL_APPINIT(Tcl_Interp *); + +/* + * The following #if block allows you to change how Tcl finds the startup + * script, prime the library or encoding paths, fiddle with the argv, etc., + * without needing to rewrite Tcl_Main() + */ + +#ifdef TCL_LOCAL_MAIN_HOOK +MODULE_SCOPE int TCL_LOCAL_MAIN_HOOK(int *argc, TCHAR ***argv); +#endif + +/* + *---------------------------------------------------------------------- + * + * main -- + * + * This is the main program for the application. + * + * Results: + * None: Tcl_Main never returns here, so this procedure never returns + * either. + * + * Side effects: + * Just about anything, since from here we call arbitrary Tcl code. + * + *---------------------------------------------------------------------- + */ + +#ifdef TCL_BROKEN_MAINARGS +int +main( + int argc, /* Number of command-line arguments. */ + char *dummy[]) /* Not used. */ +{ + TCHAR **argv; +#else +int +_tmain( + int argc, /* Number of command-line arguments. */ + TCHAR *argv[]) /* Values of command-line arguments. */ +{ +#endif + TCHAR *p; + + /* + * Set up the default locale to be standard "C" locale so parsing is + * performed correctly. + */ + + setlocale(LC_ALL, "C"); + +#ifdef TCL_BROKEN_MAINARGS + /* + * Get our args from the c-runtime. Ignore command line. + */ + + setargv(&argc, &argv); +#endif + + /* + * Forward slashes substituted for backslashes. + */ + + for (p = argv[0]; *p != '\0'; p++) { + if (*p == '\\') { + *p = '/'; + } + } + +#ifdef TCL_LOCAL_MAIN_HOOK + TCL_LOCAL_MAIN_HOOK(&argc, &argv); +#endif + /* This voodoo ensures that Tcl_Main does not eat the first argument */ + Tcl_FindExecutable(argv[0]); + Tcl_SetStartupScript(Tcl_NewStringObj("noop",-1),NULL); + Tcl_Main(argc, argv, TCL_LOCAL_APPINIT); + return 0; /* Needed only to prevent compiler warning. */ +} + +/* + *---------------------------------------------------------------------- + * + * TclKit_AppInit -- + * + * This procedure performs application-specific initialization. Most + * applications, especially those that incorporate additional packages, + * will have their own version of this procedure. + * + * Results: + * Returns a standard Tcl completion code, and leaves an error message in + * the interp's result if an error occurs. + * + * Side effects: + * Depends on the startup script. + * + *---------------------------------------------------------------------- + */ + +int +TclKit_AppInit( + Tcl_Interp *interp) /* Interpreter for application. */ +{ + Tcl_Zvfs_Boot(interp,TCLKIT_VFSMOUNT,TCLKIT_INIT); + if ((Tcl_Init)(interp) == TCL_ERROR) { + return TCL_ERROR; + } + + if (Registry_Init(interp) == TCL_ERROR) { + return TCL_ERROR; + } + Tcl_StaticPackage(interp, "registry", Registry_Init, NULL); + + if (Dde_Init(interp) == TCL_ERROR) { + return TCL_ERROR; + } + Tcl_StaticPackage(interp, "dde", Dde_Init, Dde_SafeInit); + + /* + * Call the init procedures for included packages. Each call should look + * like this: + * + * if (Mod_Init(interp) == TCL_ERROR) { + * return TCL_ERROR; + * } + * + * where "Mod" is the name of the module. (Dynamically-loadable packages + * should have the same entry-point name.) + */ + + /* + * Call Tcl_CreateCommand for application-specific commands, if they + * weren't already created by the init procedures called above. + */ + + /* + * Specify a user-specific startup file to invoke if the application is + * run interactively. Typically the startup file is "~/.apprc" where "app" + * is the name of the application. If this line is deleted then no + * user-specific startup file will be run under any conditions. + */ + + (Tcl_ObjSetVar2)(interp, Tcl_NewStringObj("tcl_rcFileName", -1), NULL, + Tcl_NewStringObj("~/tclshrc.tcl", -1), TCL_GLOBAL_ONLY); + return TCL_OK; +} + +/* + *------------------------------------------------------------------------- + * + * setargv -- + * + * Parse the Windows command line string into argc/argv. Done here + * because we don't trust the builtin argument parser in crt0. Windows + * applications are responsible for breaking their command line into + * arguments. + * + * 2N backslashes + quote -> N backslashes + begin quoted string + * 2N + 1 backslashes + quote -> literal + * N backslashes + non-quote -> literal + * quote + quote in a quoted string -> single quote + * quote + quote not in quoted string -> empty string + * quote -> begin quoted string + * + * Results: + * Fills argcPtr with the number of arguments and argvPtr with the array + * of arguments. + * + * Side effects: + * Memory allocated. + * + *-------------------------------------------------------------------------- + */ + +#ifdef TCL_BROKEN_MAINARGS +static void +setargv( + int *argcPtr, /* Filled with number of argument strings. */ + TCHAR ***argvPtr) /* Filled with argument strings (malloc'd). */ +{ + TCHAR *cmdLine, *p, *arg, *argSpace; + TCHAR **argv; + int argc, size, inquote, copy, slashes; + + cmdLine = GetCommandLine(); + + /* + * Precompute an overly pessimistic guess at the number of arguments in + * the command line by counting non-space spans. + */ + + size = 2; + for (p = cmdLine; *p != '\0'; p++) { + if ((*p == ' ') || (*p == '\t')) { /* INTL: ISO space. */ + size++; + while ((*p == ' ') || (*p == '\t')) { /* INTL: ISO space. */ + p++; + } + if (*p == '\0') { + break; + } + } + } + + /* Make sure we don't call ckalloc through the (not yet initialized) stub table */ + #undef Tcl_Alloc + #undef Tcl_DbCkalloc + + argSpace = ckalloc(size * sizeof(char *) + + (_tcslen(cmdLine) * sizeof(TCHAR)) + sizeof(TCHAR)); + argv = (TCHAR **) argSpace; + argSpace += size * (sizeof(char *)/sizeof(TCHAR)); + size--; + + p = cmdLine; + for (argc = 0; argc < size; argc++) { + argv[argc] = arg = argSpace; + while ((*p == ' ') || (*p == '\t')) { /* INTL: ISO space. */ + p++; + } + if (*p == '\0') { + break; + } + + inquote = 0; + slashes = 0; + while (1) { + copy = 1; + while (*p == '\\') { + slashes++; + p++; + } + if (*p == '"') { + if ((slashes & 1) == 0) { + copy = 0; + if ((inquote) && (p[1] == '"')) { + p++; + copy = 1; + } else { + inquote = !inquote; + } + } + slashes >>= 1; + } + + while (slashes) { + *arg = '\\'; + arg++; + slashes--; + } + + if ((*p == '\0') || (!inquote && + ((*p == ' ') || (*p == '\t')))) { /* INTL: ISO space. */ + break; + } + if (copy != 0) { + *arg = *p; + arg++; + } + p++; + } + *arg = '\0'; + argSpace = arg + 1; + } + argv[argc] = NULL; + + *argcPtr = argc; + *argvPtr = argv; +} +#endif /* TCL_BROKEN_MAINARGS */ + +/* + * Local Variables: + * mode: c + * c-basic-offset: 4 + * fill-column: 78 + * End: + */ -- cgit v0.12 From 71e02d5298ef4a81b4aa0494ee1ba7d8f433391d Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Sat, 6 Sep 2014 11:41:26 +0000 Subject: Created a designated bootloader for Tclkits under windows On windows, tclkits build a private VFS instead of relying on make install Added a tool to build the tcl kit's VFS, as well as index the bundled packages --- library/http/http.tcl | 2 +- tools/mkVfs.tcl | 109 +++++++++ win/Makefile.in | 35 +-- win/tclKitInit.c | 649 +++++++++++++++++++++++++------------------------- 4 files changed, 454 insertions(+), 341 deletions(-) create mode 100644 tools/mkVfs.tcl diff --git a/library/http/http.tcl b/library/http/http.tcl index a6b2bfd..afa9458 100644 --- a/library/http/http.tcl +++ b/library/http/http.tcl @@ -12,7 +12,7 @@ package require Tcl 8.6 # Keep this in sync with pkgIndex.tcl and with the install directories in # Makefiles package provide http 2.8.8 - +puts [list LOADED [info script]] namespace eval http { # Allow resourcing to not clobber existing data diff --git a/tools/mkVfs.tcl b/tools/mkVfs.tcl new file mode 100644 index 0000000..c7bf17b --- /dev/null +++ b/tools/mkVfs.tcl @@ -0,0 +1,109 @@ +proc cat fname { + set fname [open $fname r] + set data [read $fname] + close $fname + return $data +} + +proc pkgIndexDir {root fout d1} { + + puts [format {%*sIndexing %s} [expr {4 * [info level]}] {} \ + [file tail $d1]] + set idx [string length $root] + foreach ftail [glob -directory $d1 -nocomplain -tails *] { + set f [file join $d1 $ftail] + if {[file isdirectory $f] && [string compare CVS $ftail]} { + pkgIndexDir $root $fout $f + } elseif {[file tail $f] eq "pkgIndex.tcl"} { + puts $fout "set dir \$HERE[string range $d1 $idx end]" + puts $fout [cat $f] + } + } +} + +### +# Script to build the VFS file system +### +proc copyDir {d1 d2} { + + puts [format {%*sCreating %s} [expr {4 * [info level]}] {} \ + [file tail $d2]] + + file delete -force -- $d2 + file mkdir $d2 + + foreach ftail [glob -directory $d1 -nocomplain -tails *] { + set f [file join $d1 $ftail] + if {[file isdirectory $f] && [string compare CVS $ftail]} { + copyDir $f [file join $d2 $ftail] + } elseif {[file isfile $f]} { + file copy -force $f [file join $d2 $ftail] + if {$::tcl_platform(platform) eq {unix}} { + file attributes [file join $d2 $ftail] -permissions 0644 + } else { + file attributes [file join $d2 $ftail] -readonly 1 + } + } + } + + if {$::tcl_platform(platform) eq {unix}} { + file attributes $d2 -permissions 0755 + } else { + file attributes $d2 -readonly 1 + } +} + +if {[llength $argv] < 3} { + puts "Usage: VFS_ROOT TCLSRC_ROOT PLATFORM" + exit 1 +} +set TCL_SCRIPT_DIR [lindex $argv 0] +set TCLSRC_ROOT [lindex $argv 1] +set PLATFORM [lindex $argv 2] + +puts "Building [file tail $TCL_SCRIPT_DIR] for $PLATFORM" +copyDir ${TCLSRC_ROOT}/library ${TCL_SCRIPT_DIR} + +if {$PLATFORM == "windows"} { + set ddedll [glob -nocomplain ${TCLSRC_ROOT}/win/tcldde*.dll] + puts "DDE DLL $ddedll" + if {$ddedll != {}} { + file copy $ddedll ${TCL_SCRIPT_DIR}/dde + } + set regdll [glob -nocomplain ${TCLSRC_ROOT}/win/tclreg*.dll] + puts "REG DLL $ddedll" + if {$regdll != {}} { + file copy $regdll ${TCL_SCRIPT_DIR}/reg + } +} else { + # Remove the dde and reg package paths + file delete -force ${TCL_SCRIPT_DIR}/dde + file delete -force ${TCL_SCRIPT_DIR}/reg +} + +# For the following packages, cat their pkgIndex files to tclIndex +file attributes ${TCL_SCRIPT_DIR}/tclIndex -readonly 0 +set fout [open ${TCL_SCRIPT_DIR}/tclIndex a] +puts $fout {# +# MANIFEST OF INCLUDED PACKAGES +# +set HERE $dir +} +pkgIndexDir ${TCL_SCRIPT_DIR} $fout ${TCL_SCRIPT_DIR} +close $fout +exit 0 +puts $fout { +# Save Tcl the trouble of hunting for these packages +} +set ddedll [glob -nocomplain ${TCLSRC_ROOT}/win/tcldde*.dll] +puts "DDE DLL $ddedll" +if {$ddedll != {}} { + puts $fout [cat ${TCL_SCRIPT_DIR}/dde/pkgIndex.tcl] +} +set regdll [glob -nocomplain ${TCLSRC_ROOT}/win/tclreg*.dll] +puts "REG DLL $ddedll" +if {$regdll != {}} { + puts $fout [cat ${TCL_SCRIPT_DIR}/reg/pkgIndex.tcl] +} +close $fout +file attributes ${TCL_SCRIPT_DIR}/tclIndex -readonly 1 diff --git a/win/Makefile.in b/win/Makefile.in index e85cc16..ec824cc 100644 --- a/win/Makefile.in +++ b/win/Makefile.in @@ -103,6 +103,10 @@ COMPAT_DIR = $(TOP_DIR)/compat PKGS_DIR = $(TOP_DIR)/pkgs ZLIB_DIR = $(COMPAT_DIR)/zlib +VFS_SCRIPT_INSTALL_DIR = $(WIN_DIR)/tclvfs.zip/tcl$(VERSION) +VFS_PKG_INSTALL_DIR = $(WIN_DIR)/tclvfs.zip/lib + + # Converts a POSIX path to a Windows native path. CYGPATH = @CYGPATH@ @@ -392,9 +396,6 @@ STUB_OBJS = \ TCLSH_OBJS = tclAppInit.$(OBJEXT) -TCLKIT_OBJS = tclKitInit.$(OBJEXT) - - ZLIB_OBJS = \ adler32.$(OBJEXT) \ compress.$(OBJEXT) \ @@ -410,6 +411,10 @@ ZLIB_OBJS = \ TCL_OBJS = ${GENERIC_OBJS} $(TOMMATH_OBJS) ${WIN_OBJS} @ZLIB_OBJS@ +TCLKIT_OBJS = tclKitInit.$(OBJEXT) \ + ${GENERIC_OBJS} $(TOMMATH_OBJS) ${WIN_OBJS} ${ZLIB_OBJS} + + TCL_DOCS = "$(ROOT_DIR_NATIVE)"/doc/*.[13n] all: binaries libraries doc packages @@ -435,17 +440,17 @@ null.zip: # Rather than force an install, pack the files we need into a # file system under our control -tclkit.vfs: - make install-libraries DESTDIR=tclkit.vfs - make install-tzdata DESTDIR=tclkit.vfs - make install-packages DESTDIR=tclkit.vfs - -$(TCLKIT): $(TCLKIT_OBJS) $(TCL_OBJS) $(TOMMATH_OBJS) $(ZLIB_OBJS) tclsh.$(RES) null.zip tclkit.vfs - $(CC) $(CFLAGS) $(TCLKIT_OBJS) $(TCL_OBJS) $(TOMMATH_OBJS) $(ZLIB_OBJS) \ - $(LIBS) tclsh.$(RES) $(CC_EXENAME) $(LDFLAGS_CONSOLE) +tclkit.vfs: $(TCLSH) $(DDE_DLL_FILE) $(REG_DLL_FILE) + @echo "Building VFS File system in tclkit.vfs" + @$(TCL_EXE) "$(ROOT_DIR)/tools/mkVfs.tcl" \ + "$(WIN_DIR)/tclkit.vfs/tcl$(VERSION)" "$(ROOT_DIR)" windows + +$(TCLKIT): $(TCLKIT_OBJS) @LIBRARIES@ $(TCL_STUB_LIB_FILE) tclsh.$(RES) null.zip tclkit.vfs + $(CC) $(CFLAGS) -DSTATIC_BUILD -UUSE_STUBS $(TCLKIT_OBJS) $(LIBS) \ + tclsh.$(RES) $(CC_EXENAME) $(LDFLAGS_CONSOLE) @VC_MANIFEST_EMBED_EXE@ cat null.zip >> $(TCLKIT) - cd tclkit.vfs${prefix}/lib ; zip -rAq $(WIN_DIR)/$(TCLKIT) tcl8 tcl8.6 + cd tclkit.vfs ; zip -rAq $(WIN_DIR)/$(TCLKIT) . cat32.$(OBJEXT): cat.c $(CC) -c $(CC_SWITCHES) @DEPARG@ $(CC_OBJNAME) @@ -510,9 +515,6 @@ testMain.${OBJEXT}: tclAppInit.c tclMain2.${OBJEXT}: tclMain.c $(CC) -c $(CC_SWITCHES) -DBUILD_tcl -DTCL_ASCII_MAIN @DEPARG@ $(CC_OBJNAME) -tclKitInit.$(OBJEXT): tclAppInit.c - $(CC) -c $(CC_SWITCHES) -DTCL_KIT @DEPARG@ $(CC_OBJNAME) - # TIP #59, embedding of configuration information into the binary library. # # Part of Tcl's configuration information are the paths where it was installed @@ -762,8 +764,9 @@ cleanhelp: clean: cleanhelp clean-packages $(RM) *.lib *.a *.exp *.dll *.$(RES) *.${OBJEXT} *~ \#* TAGS a.out - $(RM) $(TCLSH) $(CAT32) + $(RM) $(TCLSH) $(CAT32) $(TCLKIT) null.zip $(RM) *.pch *.ilk *.pdb + $(RMDIR) tclkit.vfs distclean: distclean-packages clean $(RM) Makefile config.status config.cache config.log tclConfig.sh \ diff --git a/win/tclKitInit.c b/win/tclKitInit.c index 69a298c..9531ab5 100644 --- a/win/tclKitInit.c +++ b/win/tclKitInit.c @@ -1,324 +1,325 @@ -/* - * tclAppInit.c -- - * - * Provides a default version of the main program and TclKit_AppInit - * procedure for tclsh and other Tcl-based applications (without Tk). - * Note that this program must be built in Win32 console mode to work - * properly. - * - * Copyright (c) 1993 The Regents of the University of California. - * Copyright (c) 1994-1997 Sun Microsystems, Inc. - * Copyright (c) 1998-1999 Scriptics Corporation. - * - * See the file "license.terms" for information on usage and redistribution of - * this file, and for a DISCLAIMER OF ALL WARRANTIES. - */ - -#include "tcl.h" -#define WIN32_LEAN_AND_MEAN -#include -#undef WIN32_LEAN_AND_MEAN -#include -#include -#include - -extern Tcl_PackageInitProc Registry_Init; -extern Tcl_PackageInitProc Dde_Init; -extern Tcl_PackageInitProc Dde_SafeInit; - -#ifdef TCL_BROKEN_MAINARGS -int _CRT_glob = 0; -static void setargv(int *argcPtr, TCHAR ***argvPtr); -#endif /* TCL_BROKEN_MAINARGS */ - -/* - * The following #if block allows you to change the AppInit function by using - * a #define of TCL_LOCAL_APPINIT instead of rewriting this entire file. The - * #if checks for that #define and uses TclKit_AppInit if it does not exist. - */ -#define TCLKIT_INIT "main.tcl" -#define TCLKIT_VFSMOUNT "/zvfs" -#ifndef TCL_LOCAL_APPINIT -#define TCL_LOCAL_APPINIT TclKit_AppInit -#endif -#ifndef MODULE_SCOPE -# define MODULE_SCOPE extern -#endif -MODULE_SCOPE int TCL_LOCAL_APPINIT(Tcl_Interp *); - -/* - * The following #if block allows you to change how Tcl finds the startup - * script, prime the library or encoding paths, fiddle with the argv, etc., - * without needing to rewrite Tcl_Main() - */ - -#ifdef TCL_LOCAL_MAIN_HOOK -MODULE_SCOPE int TCL_LOCAL_MAIN_HOOK(int *argc, TCHAR ***argv); -#endif - -/* - *---------------------------------------------------------------------- - * - * main -- - * - * This is the main program for the application. - * - * Results: - * None: Tcl_Main never returns here, so this procedure never returns - * either. - * - * Side effects: - * Just about anything, since from here we call arbitrary Tcl code. - * - *---------------------------------------------------------------------- - */ - -#ifdef TCL_BROKEN_MAINARGS -int -main( - int argc, /* Number of command-line arguments. */ - char *dummy[]) /* Not used. */ -{ - TCHAR **argv; -#else -int -_tmain( - int argc, /* Number of command-line arguments. */ - TCHAR *argv[]) /* Values of command-line arguments. */ -{ -#endif - TCHAR *p; - - /* - * Set up the default locale to be standard "C" locale so parsing is - * performed correctly. - */ - - setlocale(LC_ALL, "C"); - -#ifdef TCL_BROKEN_MAINARGS - /* - * Get our args from the c-runtime. Ignore command line. - */ - - setargv(&argc, &argv); -#endif - - /* - * Forward slashes substituted for backslashes. - */ - - for (p = argv[0]; *p != '\0'; p++) { - if (*p == '\\') { - *p = '/'; - } - } - -#ifdef TCL_LOCAL_MAIN_HOOK - TCL_LOCAL_MAIN_HOOK(&argc, &argv); -#endif - /* This voodoo ensures that Tcl_Main does not eat the first argument */ - Tcl_FindExecutable(argv[0]); - Tcl_SetStartupScript(Tcl_NewStringObj("noop",-1),NULL); - Tcl_Main(argc, argv, TCL_LOCAL_APPINIT); - return 0; /* Needed only to prevent compiler warning. */ -} - -/* - *---------------------------------------------------------------------- - * - * TclKit_AppInit -- - * - * This procedure performs application-specific initialization. Most - * applications, especially those that incorporate additional packages, - * will have their own version of this procedure. - * - * Results: - * Returns a standard Tcl completion code, and leaves an error message in - * the interp's result if an error occurs. - * - * Side effects: - * Depends on the startup script. - * - *---------------------------------------------------------------------- - */ - -int -TclKit_AppInit( - Tcl_Interp *interp) /* Interpreter for application. */ -{ - Tcl_Zvfs_Boot(interp,TCLKIT_VFSMOUNT,TCLKIT_INIT); - if ((Tcl_Init)(interp) == TCL_ERROR) { - return TCL_ERROR; - } - - if (Registry_Init(interp) == TCL_ERROR) { - return TCL_ERROR; - } - Tcl_StaticPackage(interp, "registry", Registry_Init, NULL); - - if (Dde_Init(interp) == TCL_ERROR) { - return TCL_ERROR; - } - Tcl_StaticPackage(interp, "dde", Dde_Init, Dde_SafeInit); - - /* - * Call the init procedures for included packages. Each call should look - * like this: - * - * if (Mod_Init(interp) == TCL_ERROR) { - * return TCL_ERROR; - * } - * - * where "Mod" is the name of the module. (Dynamically-loadable packages - * should have the same entry-point name.) - */ - - /* - * Call Tcl_CreateCommand for application-specific commands, if they - * weren't already created by the init procedures called above. - */ - - /* - * Specify a user-specific startup file to invoke if the application is - * run interactively. Typically the startup file is "~/.apprc" where "app" - * is the name of the application. If this line is deleted then no - * user-specific startup file will be run under any conditions. - */ - - (Tcl_ObjSetVar2)(interp, Tcl_NewStringObj("tcl_rcFileName", -1), NULL, - Tcl_NewStringObj("~/tclshrc.tcl", -1), TCL_GLOBAL_ONLY); - return TCL_OK; -} - -/* - *------------------------------------------------------------------------- - * - * setargv -- - * - * Parse the Windows command line string into argc/argv. Done here - * because we don't trust the builtin argument parser in crt0. Windows - * applications are responsible for breaking their command line into - * arguments. - * - * 2N backslashes + quote -> N backslashes + begin quoted string - * 2N + 1 backslashes + quote -> literal - * N backslashes + non-quote -> literal - * quote + quote in a quoted string -> single quote - * quote + quote not in quoted string -> empty string - * quote -> begin quoted string - * - * Results: - * Fills argcPtr with the number of arguments and argvPtr with the array - * of arguments. - * - * Side effects: - * Memory allocated. - * - *-------------------------------------------------------------------------- - */ - -#ifdef TCL_BROKEN_MAINARGS -static void -setargv( - int *argcPtr, /* Filled with number of argument strings. */ - TCHAR ***argvPtr) /* Filled with argument strings (malloc'd). */ -{ - TCHAR *cmdLine, *p, *arg, *argSpace; - TCHAR **argv; - int argc, size, inquote, copy, slashes; - - cmdLine = GetCommandLine(); - - /* - * Precompute an overly pessimistic guess at the number of arguments in - * the command line by counting non-space spans. - */ - - size = 2; - for (p = cmdLine; *p != '\0'; p++) { - if ((*p == ' ') || (*p == '\t')) { /* INTL: ISO space. */ - size++; - while ((*p == ' ') || (*p == '\t')) { /* INTL: ISO space. */ - p++; - } - if (*p == '\0') { - break; - } - } - } - - /* Make sure we don't call ckalloc through the (not yet initialized) stub table */ - #undef Tcl_Alloc - #undef Tcl_DbCkalloc - - argSpace = ckalloc(size * sizeof(char *) - + (_tcslen(cmdLine) * sizeof(TCHAR)) + sizeof(TCHAR)); - argv = (TCHAR **) argSpace; - argSpace += size * (sizeof(char *)/sizeof(TCHAR)); - size--; - - p = cmdLine; - for (argc = 0; argc < size; argc++) { - argv[argc] = arg = argSpace; - while ((*p == ' ') || (*p == '\t')) { /* INTL: ISO space. */ - p++; - } - if (*p == '\0') { - break; - } - - inquote = 0; - slashes = 0; - while (1) { - copy = 1; - while (*p == '\\') { - slashes++; - p++; - } - if (*p == '"') { - if ((slashes & 1) == 0) { - copy = 0; - if ((inquote) && (p[1] == '"')) { - p++; - copy = 1; - } else { - inquote = !inquote; - } - } - slashes >>= 1; - } - - while (slashes) { - *arg = '\\'; - arg++; - slashes--; - } - - if ((*p == '\0') || (!inquote && - ((*p == ' ') || (*p == '\t')))) { /* INTL: ISO space. */ - break; - } - if (copy != 0) { - *arg = *p; - arg++; - } - p++; - } - *arg = '\0'; - argSpace = arg + 1; - } - argv[argc] = NULL; - - *argcPtr = argc; - *argvPtr = argv; -} -#endif /* TCL_BROKEN_MAINARGS */ - -/* - * Local Variables: - * mode: c - * c-basic-offset: 4 - * fill-column: 78 - * End: - */ +/* + * tclAppInit.c -- + * + * Provides a default version of the main program and TclKit_AppInit + * procedure for tclsh and other Tcl-based applications (without Tk). + * Note that this program must be built in Win32 console mode to work + * properly. + * + * Copyright (c) 1993 The Regents of the University of California. + * Copyright (c) 1994-1997 Sun Microsystems, Inc. + * Copyright (c) 1998-1999 Scriptics Corporation. + * + * See the file "license.terms" for information on usage and redistribution of + * this file, and for a DISCLAIMER OF ALL WARRANTIES. + */ + +#include "tclWinInt.h" + +#define WIN32_LEAN_AND_MEAN +#include +#undef WIN32_LEAN_AND_MEAN +#include +#include +#include + +extern Tcl_PackageInitProc Registry_Init; +extern Tcl_PackageInitProc Dde_Init; +extern Tcl_PackageInitProc Dde_SafeInit; + +#ifdef TCL_BROKEN_MAINARGS +int _CRT_glob = 0; +static void setargv(int *argcPtr, TCHAR ***argvPtr); +#endif /* TCL_BROKEN_MAINARGS */ + +/* + * The following #if block allows you to change the AppInit function by using + * a #define of TCL_LOCAL_APPINIT instead of rewriting this entire file. The + * #if checks for that #define and uses TclKit_AppInit if it does not exist. + */ +#define TCLKIT_INIT "main.tcl" +#define TCLKIT_VFSMOUNT "/zvfs" +#ifndef TCL_LOCAL_APPINIT +#define TCL_LOCAL_APPINIT TclKit_AppInit +#endif +#ifndef MODULE_SCOPE +# define MODULE_SCOPE extern +#endif +MODULE_SCOPE int TCL_LOCAL_APPINIT(Tcl_Interp *); + +/* + * The following #if block allows you to change how Tcl finds the startup + * script, prime the library or encoding paths, fiddle with the argv, etc., + * without needing to rewrite Tcl_Main() + */ + +#ifdef TCL_LOCAL_MAIN_HOOK +MODULE_SCOPE int TCL_LOCAL_MAIN_HOOK(int *argc, TCHAR ***argv); +#endif + +/* + *---------------------------------------------------------------------- + * + * main -- + * + * This is the main program for the application. + * + * Results: + * None: Tcl_Main never returns here, so this procedure never returns + * either. + * + * Side effects: + * Just about anything, since from here we call arbitrary Tcl code. + * + *---------------------------------------------------------------------- + */ + +#ifdef TCL_BROKEN_MAINARGS +int +main( + int argc, /* Number of command-line arguments. */ + char *dummy[]) /* Not used. */ +{ + TCHAR **argv; +#else +int +_tmain( + int argc, /* Number of command-line arguments. */ + TCHAR *argv[]) /* Values of command-line arguments. */ +{ +#endif + TCHAR *p; + + /* + * Set up the default locale to be standard "C" locale so parsing is + * performed correctly. + */ + + setlocale(LC_ALL, "C"); + +#ifdef TCL_BROKEN_MAINARGS + /* + * Get our args from the c-runtime. Ignore command line. + */ + + setargv(&argc, &argv); +#endif + + /* + * Forward slashes substituted for backslashes. + */ + + for (p = argv[0]; *p != '\0'; p++) { + if (*p == '\\') { + *p = '/'; + } + } + +#ifdef TCL_LOCAL_MAIN_HOOK + TCL_LOCAL_MAIN_HOOK(&argc, &argv); +#endif + /* This voodoo ensures that Tcl_Main does not eat the first argument */ + Tcl_FindExecutable(argv[0]); + Tcl_SetStartupScript(Tcl_NewStringObj("noop",-1),NULL); + Tcl_Main(argc, argv, TCL_LOCAL_APPINIT); + return 0; /* Needed only to prevent compiler warning. */ +} + +/* + *---------------------------------------------------------------------- + * + * TclKit_AppInit -- + * + * This procedure performs application-specific initialization. Most + * applications, especially those that incorporate additional packages, + * will have their own version of this procedure. + * + * Results: + * Returns a standard Tcl completion code, and leaves an error message in + * the interp's result if an error occurs. + * + * Side effects: + * Depends on the startup script. + * + *---------------------------------------------------------------------- + */ + +int +TclKit_AppInit( + Tcl_Interp *interp) /* Interpreter for application. */ +{ + Tcl_Zvfs_Boot(interp,TCLKIT_VFSMOUNT,TCLKIT_INIT); + if ((Tcl_Init)(interp) == TCL_ERROR) { + return TCL_ERROR; + } + +// if (Registry_Init(interp) == TCL_ERROR) { +// return TCL_ERROR; +// } +// Tcl_StaticPackage(interp, "registry", Registry_Init, NULL); +// +// if (Dde_Init(interp) == TCL_ERROR) { +// return TCL_ERROR; +// } +// Tcl_StaticPackage(interp, "dde", Dde_Init, Dde_SafeInit); + + /* + * Call the init procedures for included packages. Each call should look + * like this: + * + * if (Mod_Init(interp) == TCL_ERROR) { + * return TCL_ERROR; + * } + * + * where "Mod" is the name of the module. (Dynamically-loadable packages + * should have the same entry-point name.) + */ + + /* + * Call Tcl_CreateCommand for application-specific commands, if they + * weren't already created by the init procedures called above. + */ + + /* + * Specify a user-specific startup file to invoke if the application is + * run interactively. Typically the startup file is "~/.apprc" where "app" + * is the name of the application. If this line is deleted then no + * user-specific startup file will be run under any conditions. + */ + + (Tcl_ObjSetVar2)(interp, Tcl_NewStringObj("tcl_rcFileName", -1), NULL, + Tcl_NewStringObj("~/tclshrc.tcl", -1), TCL_GLOBAL_ONLY); + return TCL_OK; +} + +/* + *------------------------------------------------------------------------- + * + * setargv -- + * + * Parse the Windows command line string into argc/argv. Done here + * because we don't trust the builtin argument parser in crt0. Windows + * applications are responsible for breaking their command line into + * arguments. + * + * 2N backslashes + quote -> N backslashes + begin quoted string + * 2N + 1 backslashes + quote -> literal + * N backslashes + non-quote -> literal + * quote + quote in a quoted string -> single quote + * quote + quote not in quoted string -> empty string + * quote -> begin quoted string + * + * Results: + * Fills argcPtr with the number of arguments and argvPtr with the array + * of arguments. + * + * Side effects: + * Memory allocated. + * + *-------------------------------------------------------------------------- + */ + +#ifdef TCL_BROKEN_MAINARGS +static void +setargv( + int *argcPtr, /* Filled with number of argument strings. */ + TCHAR ***argvPtr) /* Filled with argument strings (malloc'd). */ +{ + TCHAR *cmdLine, *p, *arg, *argSpace; + TCHAR **argv; + int argc, size, inquote, copy, slashes; + + cmdLine = GetCommandLine(); + + /* + * Precompute an overly pessimistic guess at the number of arguments in + * the command line by counting non-space spans. + */ + + size = 2; + for (p = cmdLine; *p != '\0'; p++) { + if ((*p == ' ') || (*p == '\t')) { /* INTL: ISO space. */ + size++; + while ((*p == ' ') || (*p == '\t')) { /* INTL: ISO space. */ + p++; + } + if (*p == '\0') { + break; + } + } + } + + /* Make sure we don't call ckalloc through the (not yet initialized) stub table */ + #undef Tcl_Alloc + #undef Tcl_DbCkalloc + + argSpace = ckalloc(size * sizeof(char *) + + (_tcslen(cmdLine) * sizeof(TCHAR)) + sizeof(TCHAR)); + argv = (TCHAR **) argSpace; + argSpace += size * (sizeof(char *)/sizeof(TCHAR)); + size--; + + p = cmdLine; + for (argc = 0; argc < size; argc++) { + argv[argc] = arg = argSpace; + while ((*p == ' ') || (*p == '\t')) { /* INTL: ISO space. */ + p++; + } + if (*p == '\0') { + break; + } + + inquote = 0; + slashes = 0; + while (1) { + copy = 1; + while (*p == '\\') { + slashes++; + p++; + } + if (*p == '"') { + if ((slashes & 1) == 0) { + copy = 0; + if ((inquote) && (p[1] == '"')) { + p++; + copy = 1; + } else { + inquote = !inquote; + } + } + slashes >>= 1; + } + + while (slashes) { + *arg = '\\'; + arg++; + slashes--; + } + + if ((*p == '\0') || (!inquote && + ((*p == ' ') || (*p == '\t')))) { /* INTL: ISO space. */ + break; + } + if (copy != 0) { + *arg = *p; + arg++; + } + p++; + } + *arg = '\0'; + argSpace = arg + 1; + } + argv[argc] = NULL; + + *argcPtr = argc; + *argvPtr = argv; +} +#endif /* TCL_BROKEN_MAINARGS */ + +/* + * Local Variables: + * mode: c + * c-basic-offset: 4 + * fill-column: 78 + * End: + */ -- cgit v0.12 From 4e331e27f8b8efdb66a423a5a35d7f522508777f Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Tue, 9 Sep 2014 06:54:36 +0000 Subject: Added the tclkit binaries to install --- unix/Makefile.in | 4 +++- win/Makefile.in | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/unix/Makefile.in b/unix/Makefile.in index 30e7109..95a9bff 100644 --- a/unix/Makefile.in +++ b/unix/Makefile.in @@ -621,7 +621,7 @@ VFS_INSTALL_DIR=${PWD}/tclkit.vfs/tcl8.6 all: binaries libraries doc packages -binaries: ${LIB_FILE} ${TCL_EXE} +binaries: ${LIB_FILE} ${TCL_EXE} ${TCLKIT_EXE} libraries: @@ -831,6 +831,8 @@ install-binaries: binaries @chmod 555 "$(DLL_INSTALL_DIR)/$(LIB_FILE)" @echo "Installing ${TCL_EXE} as $(BIN_INSTALL_DIR)/tclsh$(VERSION)${EXE_SUFFIX}" @$(INSTALL_PROGRAM) ${TCL_EXE} "$(BIN_INSTALL_DIR)/tclsh$(VERSION)${EXE_SUFFIX}" + @echo "Installing ${TCLKIT_EXE} as $(BIN_INSTALL_DIR)/tclkit$(VERSION)${EXE_SUFFIX}" + @$(INSTALL_PROGRAM) ${TCLKIT_EXE} "$(BIN_INSTALL_DIR)/tclkit$(VERSION)${EXE_SUFFIX}" @echo "Installing tclConfig.sh to $(CONFIG_INSTALL_DIR)/" @$(INSTALL_DATA) tclConfig.sh "$(CONFIG_INSTALL_DIR)/tclConfig.sh" @echo "Installing tclooConfig.sh to $(CONFIG_INSTALL_DIR)/" diff --git a/win/Makefile.in b/win/Makefile.in index ec824cc..6fdbacf 100644 --- a/win/Makefile.in +++ b/win/Makefile.in @@ -421,7 +421,7 @@ all: binaries libraries doc packages tcltest: $(TCLSH) $(TEST_DLL_FILE) -binaries: $(TCL_STUB_LIB_FILE) @LIBRARIES@ $(DDE_DLL_FILE) $(REG_DLL_FILE) $(TCLSH) +binaries: $(TCL_STUB_LIB_FILE) @LIBRARIES@ $(DDE_DLL_FILE) $(REG_DLL_FILE) $(TCLSH) $(TCLKIT) libraries: @@ -599,7 +599,7 @@ install-binaries: binaries else true; \ fi; \ done; - @for i in $(TCL_DLL_FILE) $(ZLIB_DLL_FILE) $(TCLSH); \ + @for i in $(TCL_DLL_FILE) $(ZLIB_DLL_FILE) $(TCLSH) $(TCLKIT); \ do \ if [ -f $$i ]; then \ echo "Installing $$i to $(BIN_INSTALL_DIR)/"; \ -- cgit v0.12 From 9f12483ed2ebaafdba526e66348417fc76ab4692 Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Tue, 9 Sep 2014 07:55:45 +0000 Subject: Instead of statically compiling the Tclkit executable straight from .o files, generate a static library (libtclkit.a), and compile against that. --- unix/Makefile.in | 26 +- unix/configure | 20821 +++++++++++++++------------------------------------- unix/configure.in | 5 + unix/tcl.m4 | 10 + 4 files changed, 6086 insertions(+), 14776 deletions(-) diff --git a/unix/Makefile.in b/unix/Makefile.in index 95a9bff..7d9b82d 100644 --- a/unix/Makefile.in +++ b/unix/Makefile.in @@ -168,6 +168,7 @@ INSTALL_DATA_DIR = ${INSTALL} -d -m 755 EXE_SUFFIX = @EXEEXT@ TCL_EXE = tclsh${EXE_SUFFIX} TCLKIT_EXE = tclkit${EXE_SUFFIX} +TCLKIT_LIB = tclkit${EXE_SUFFIX} TCLTEST_EXE = tcltest${EXE_SUFFIX} NATIVE_TCLSH = @TCLSH_PROG@ @@ -203,6 +204,9 @@ BUILD_DLTEST = @BUILD_DLTEST@ TCL_LIB_FILE = @TCL_LIB_FILE@ #TCL_LIB_FILE = libtcl.a +TCL_KIT_LIB_FILE = @TCL_KIT_LIB_FILE@ +#TCL_KIT_LIB_FILE = libtclkit.a + # Generic lib name used in rules that apply to tcl and tk LIB_FILE = ${TCL_LIB_FILE} @@ -640,6 +644,17 @@ ${STUB_LIB_FILE}: ${STUB_LIB_OBJS} rm -f $@ @MAKE_STUB_LIB@ + +${TCL_KIT_LIB_FILE}: ${TCL_OBJS} ${TOMMATH_OBJS} ${ZLIB_OBJS} + rm -f $@ + @MAKE_KIT_LIB@ + + #${SHLIB_LD} $@ ${TCL_OBJS} ${TOMMATH_OBJS} ${ZLIB_OBJS} ; ${RANLIB} $@ + #${CC} ${CFLAGS} ${LDFLAGS} \ + # ${TCL_OBJS} ${TOMMATH_OBJS} ${ZLIB_OBJS} \ + # ${CC_SEARCH_FLAGS} -o ${TCL_KIT_LIB_FILE} + + # Make target which outputs the list of the .o contained in the Tcl lib useful # to build a single big shared library containing Tcl and other extensions. # Used for the Tcl Plugin. -- dl @@ -668,11 +683,12 @@ tclkit.vfs: make install-libraries DESTDIR=tclkit.vfs make install-tzdata DESTDIR=tclkit.vfs make install-packages DESTDIR=tclkit.vfs - + # Assemble all of the tcl sources into a single executable -${TCLKIT_EXE}: ${TCLKIT_OBJS} ${TCL_OBJS} ${TOMMATH_OBJS} ${ZLIB_OBJS} null.zip tclkit.vfs +${TCLKIT_EXE}: ${TCLKIT_OBJS} ${TCL_KIT_LIB_FILE} null.zip tclkit.vfs ${CC} ${CFLAGS} ${LDFLAGS} \ - ${TCLKIT_OBJS} ${TCL_OBJS} ${TOMMATH_OBJS} ${ZLIB_OBJS} \ + ${TCLKIT_OBJS} \ + @TCL_BUILD_LIB_SPEC@ ${TCL_KIT_LIB_FILE} \ ${LIBS} @EXTRA_TCLSH_LIBS@ \ ${CC_SEARCH_FLAGS} -o ${TCLKIT_EXE} cat null.zip >> ${TCLKIT_EXE} @@ -842,6 +858,10 @@ install-binaries: binaries echo "Installing $(STUB_LIB_FILE) to $(LIB_INSTALL_DIR)/"; \ @INSTALL_STUB_LIB@ ; \ fi + @if test "$(TCL_KIT_LIB_FILE)" != "" ; then \ + echo "Installing $(TCL_KIT_LIB_FILE) to $(LIB_INSTALL_DIR)/"; \ + @INSTALL_KIT_LIB@ ; \ + fi @EXTRA_INSTALL_BINARIES@ @echo "Installing pkg-config file to $(LIB_INSTALL_DIR)/pkgconfig/" @$(INSTALL_DATA_DIR) $(LIB_INSTALL_DIR)/pkgconfig diff --git a/unix/configure b/unix/configure index a82c692..2740498 100755 --- a/unix/configure +++ b/unix/configure @@ -1,81 +1,459 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.59 for tcl 8.6. +# Generated by GNU Autoconf 2.69 for tcl 8.6. +# +# +# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. +# # -# Copyright (C) 2003 Free Software Foundation, Inc. # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. -## --------------------- ## -## M4sh Initialization. ## -## --------------------- ## +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## -# Be Bourne compatible -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: - # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' -elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then - set -o posix + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac fi -DUALCASE=1; export DUALCASE # for MKS sh -# Support unset when possible. -if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then - as_unset=unset -else - as_unset=false + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' fi +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS -# Work around bugs in pre-3.0 UWIN ksh. -$as_unset ENV MAIL MAILPATH + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. -for as_var in \ - LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ - LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ - LC_TELEPHONE LC_TIME +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +# Use a proper internal environment variable to ensure we don't fall + # into an infinite loop, continuously re-executing ourselves. + if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then + _as_can_reexec=no; export _as_can_reexec; + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +as_fn_exit 255 + fi + # We don't want this to propagate to other subprocesses. + { _as_can_reexec=; unset _as_can_reexec;} +if test "x$CONFIG_SHELL" = x; then + as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi +" + as_required="as_fn_return () { (exit \$1); } +as_fn_success () { as_fn_return 0; } +as_fn_failure () { as_fn_return 1; } +as_fn_ret_success () { return 0; } +as_fn_ret_failure () { return 1; } + +exitcode=0 +as_fn_success || { exitcode=1; echo as_fn_success failed.; } +as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } +as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } +as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } +if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : + +else + exitcode=1; echo positional parameters were not saved. +fi +test x\$exitcode = x0 || exit 1 +test -x / || exit 1" + as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO + as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO + eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && + test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 +test \$(( 1 + 1 )) = 2 || exit 1" + if (eval "$as_required") 2>/dev/null; then : + as_have_required=yes +else + as_have_required=no +fi + if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : + +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_found=false +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do - if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then - eval $as_var=C; export $as_var + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + as_found=: + case $as_dir in #( + /*) + for as_base in sh bash ksh sh5; do + # Try only shells that exist, to save several forks. + as_shell=$as_dir/$as_base + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : + CONFIG_SHELL=$as_shell as_have_required=yes + if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : + break 2 +fi +fi + done;; + esac + as_found=false +done +$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : + CONFIG_SHELL=$SHELL as_have_required=yes +fi; } +IFS=$as_save_IFS + + + if test "x$CONFIG_SHELL" != x; then : + export CONFIG_SHELL + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +exit 255 +fi + + if test x$as_have_required = xno; then : + $as_echo "$0: This script requires a shell more modern than all" + $as_echo "$0: the shells that I found on your system." + if test x${ZSH_VERSION+set} = xset ; then + $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" + $as_echo "$0: be upgraded to zsh 4.3.4 or later." else - $as_unset $as_var + $as_echo "$0: Please tell bug-autoconf@gnu.org about your system, +$0: including any error possibly output before this +$0: message. Then install a modern shell, or manually run +$0: the script under such a shell if you do have one." fi -done + exit 1 +fi +fi +fi +SHELL=${CONFIG_SHELL-/bin/sh} +export SHELL +# Unset more variables known to interfere with behavior of common tools. +CLICOLOR_FORCE= GREP_OPTIONS= +unset CLICOLOR_FORCE GREP_OPTIONS + +## --------------------- ## +## M4sh Shell Functions. ## +## --------------------- ## +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error -# Required to use basename. -if expr a : '\(a\)' >/dev/null 2>&1; then +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi -if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi -# Name of the executable. -as_me=`$as_basename "$0" || +as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)$' \| \ - . : '\(.\)' 2>/dev/null || -echo X/"$0" | - sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } - /^X\/\(\/\/\)$/{ s//\1/; q; } - /^X\/\(\/\).*/{ s//\1/; q; } - s/.*/./; q'` - + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` -# PATH needs CR, and LINENO needs CR and PATH. # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' @@ -83,146 +461,91 @@ as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits -# The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then - echo "#! /bin/sh" >conf$$.sh - echo "exit 0" >>conf$$.sh - chmod +x conf$$.sh - if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then - PATH_SEPARATOR=';' - else - PATH_SEPARATOR=: - fi - rm -f conf$$.sh -fi - - - as_lineno_1=$LINENO - as_lineno_2=$LINENO - as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` - test "x$as_lineno_1" != "x$as_lineno_2" && - test "x$as_lineno_3" = "x$as_lineno_2" || { - # Find who we are. Look in the path if we contain no path at all - # relative or not. - case $0 in - *[\\/]* ) as_myself=$0 ;; - *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break -done - - ;; - esac - # We did not find ourselves, most probably we were run as `sh COMMAND' - # in which case we are not to be found in the path. - if test "x$as_myself" = x; then - as_myself=$0 - fi - if test ! -f "$as_myself"; then - { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2 - { (exit 1); exit 1; }; } - fi - case $CONFIG_SHELL in - '') - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for as_base in sh bash ksh sh5; do - case $as_dir in - /*) - if ("$as_dir/$as_base" -c ' - as_lineno_1=$LINENO - as_lineno_2=$LINENO - as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` - test "x$as_lineno_1" != "x$as_lineno_2" && - test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then - $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } - $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } - CONFIG_SHELL=$as_dir/$as_base - export CONFIG_SHELL - exec "$CONFIG_SHELL" "$0" ${1+"$@"} - fi;; - esac - done -done -;; - esac - # Create $as_me.lineno as a copy of $as_myself, but with $LINENO - # uniformly replaced by the line number. The first 'sed' inserts a - # line-number line before each line; the second 'sed' does the real - # work. The second script uses 'N' to pair each line-number line - # with the numbered line, and appends trailing '-' during - # substitution so that $LINENO is not a special case at line end. - # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the - # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) - sed '=' <$as_myself | + as_lineno_1=$LINENO as_lineno_1a=$LINENO + as_lineno_2=$LINENO as_lineno_2a=$LINENO + eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && + test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { + # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno N - s,$,-, - : loop - s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop - s,-$,, - s,^['$as_cr_digits']*\n,, + s/-\n.*// ' >$as_me.lineno && - chmod +x $as_me.lineno || - { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 - { (exit 1); exit 1; }; } + chmod +x "$as_me.lineno" || + { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } + # If we had to re-execute with $CONFIG_SHELL, we're ensured to have + # already done that, so ensure we don't try to do so again and fall + # in an infinite loop. This has already happened in practice. + _as_can_reexec=no; export _as_can_reexec # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the - # original and so on. Autoconf is especially sensible to this). - . ./$as_me.lineno + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" # Exit status is that of the last command. exit } - -case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in - *c*,-n*) ECHO_N= ECHO_C=' -' ECHO_T=' ' ;; - *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; - *) ECHO_N= ECHO_C='\c' ECHO_T= ;; +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; esac -if expr a : '\(a\)' >/dev/null 2>&1; then - as_expr=expr +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file else - as_expr=false + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null fi - -rm -f conf$$ conf$$.exe conf$$.file -echo >conf$$.file -if ln -s conf$$.file conf$$ 2>/dev/null; then - # We could just check for DJGPP; but this test a) works b) is more generic - # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). - if test -f conf$$.exe; then - # Don't use ln at all; we don't have any links - as_ln_s='cp -p' - else +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -pR' fi -elif ln conf$$.file conf$$ 2>/dev/null; then - as_ln_s=ln else - as_ln_s='cp -p' + as_ln_s='cp -pR' fi -rm -f conf$$ conf$$.exe conf$$.file +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then - as_mkdir_p=: + as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi -as_executable_p="test -f" +as_test_x='test -x' +as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" @@ -231,38 +554,25 @@ as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" -# IFS -# We need space, tab and new line, in precisely that order. -as_nl=' -' -IFS=" $as_nl" - -# CDPATH. -$as_unset CDPATH - +test -n "$DJDIR" || exec 7<&0 &1 # Name of the host. -# hostname on some systems (SVR3.2, Linux) returns a bogus exit status, +# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` -exec 6>&1 - # # Initializations. # ac_default_prefix=/usr/local +ac_clean_files= ac_config_libobj_dir=. +LIBOBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= -SHELL=${CONFIG_SHELL-/bin/sh} - -# Maximum number of lines to put in a shell here document. -# This variable seems obsolete. It should probably be removed, and -# only ac_max_sed_lines should be used. -: ${ac_max_here_lines=38} # Identity of this package. PACKAGE_NAME='tcl' @@ -270,50 +580,215 @@ PACKAGE_TARNAME='tcl' PACKAGE_VERSION='8.6' PACKAGE_STRING='tcl 8.6' PACKAGE_BUGREPORT='' +PACKAGE_URL='' # Factoring default headers for most tests. ac_includes_default="\ #include -#if HAVE_SYS_TYPES_H +#ifdef HAVE_SYS_TYPES_H # include #endif -#if HAVE_SYS_STAT_H +#ifdef HAVE_SYS_STAT_H # include #endif -#if STDC_HEADERS +#ifdef STDC_HEADERS # include # include #else -# if HAVE_STDLIB_H +# ifdef HAVE_STDLIB_H # include # endif #endif -#if HAVE_STRING_H -# if !STDC_HEADERS && HAVE_MEMORY_H +#ifdef HAVE_STRING_H +# if !defined STDC_HEADERS && defined HAVE_MEMORY_H # include # endif # include #endif -#if HAVE_STRINGS_H +#ifdef HAVE_STRINGS_H # include #endif -#if HAVE_INTTYPES_H +#ifdef HAVE_INTTYPES_H # include -#else -# if HAVE_STDINT_H -# include -# endif #endif -#if HAVE_UNISTD_H +#ifdef HAVE_STDINT_H +# include +#endif +#ifdef HAVE_UNISTD_H # include #endif" -ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS MAN_FLAGS CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CPP EGREP TCL_THREADS TCLSH_PROG ZLIB_OBJS ZLIB_SRCS ZLIB_INCLUDE RANLIB ac_ct_RANLIB AR ac_ct_AR LIBOBJS TCL_LIBS DL_LIBS DL_OBJS PLAT_OBJS PLAT_SRCS LDAIX_SRC CFLAGS_DEBUG CFLAGS_OPTIMIZE CFLAGS_WARNING LDFLAGS_DEBUG LDFLAGS_OPTIMIZE CC_SEARCH_FLAGS LD_SEARCH_FLAGS STLIB_LD SHLIB_LD TCL_SHLIB_LD_EXTRAS TK_SHLIB_LD_EXTRAS SHLIB_LD_LIBS SHLIB_CFLAGS SHLIB_SUFFIX MAKE_LIB MAKE_STUB_LIB INSTALL_LIB DLL_INSTALL_DIR INSTALL_STUB_LIB CFLAGS_DEFAULT LDFLAGS_DEFAULT DTRACE TCL_VERSION TCL_MAJOR_VERSION TCL_MINOR_VERSION TCL_PATCH_LEVEL TCL_YEAR PKG_CFG_ARGS TCL_LIB_FILE TCL_LIB_FLAG TCL_LIB_SPEC TCL_STUB_LIB_FILE TCL_STUB_LIB_FLAG TCL_STUB_LIB_SPEC TCL_STUB_LIB_PATH TCL_INCLUDE_SPEC TCL_BUILD_STUB_LIB_SPEC TCL_BUILD_STUB_LIB_PATH TCL_SRC_DIR CFG_TCL_SHARED_LIB_SUFFIX CFG_TCL_UNSHARED_LIB_SUFFIX TCL_SHARED_BUILD LD_LIBRARY_PATH_VAR TCL_BUILD_LIB_SPEC TCL_LIB_VERSIONS_OK TCL_SHARED_LIB_SUFFIX TCL_UNSHARED_LIB_SUFFIX TCL_HAS_LONGLONG INSTALL_TZDATA DTRACE_SRC DTRACE_HDR DTRACE_OBJ MAKEFILE_SHELL BUILD_DLTEST TCL_PACKAGE_PATH TCL_MODULE_PATH TCL_LIBRARY PRIVATE_INCLUDE_DIR HTML_DIR PACKAGE_DIR EXTRA_CC_SWITCHES EXTRA_APP_CC_SWITCHES EXTRA_INSTALL EXTRA_INSTALL_BINARIES EXTRA_BUILD_HTML EXTRA_TCLSH_LIBS DLTEST_LD DLTEST_SUFFIX' +ac_subst_vars='DLTEST_SUFFIX +DLTEST_LD +EXTRA_TCLSH_LIBS +EXTRA_BUILD_HTML +EXTRA_INSTALL_BINARIES +EXTRA_INSTALL +EXTRA_APP_CC_SWITCHES +EXTRA_CC_SWITCHES +PACKAGE_DIR +HTML_DIR +PRIVATE_INCLUDE_DIR +TCL_LIBRARY +TCL_MODULE_PATH +TCL_PACKAGE_PATH +BUILD_DLTEST +MAKEFILE_SHELL +DTRACE_OBJ +DTRACE_HDR +DTRACE_SRC +INSTALL_TZDATA +TCL_HAS_LONGLONG +TCL_UNSHARED_LIB_SUFFIX +TCL_SHARED_LIB_SUFFIX +TCL_LIB_VERSIONS_OK +TCL_BUILD_LIB_SPEC +LD_LIBRARY_PATH_VAR +TCL_SHARED_BUILD +CFG_TCL_UNSHARED_LIB_SUFFIX +CFG_TCL_SHARED_LIB_SUFFIX +TCL_SRC_DIR +TCL_BUILD_STUB_LIB_PATH +TCL_BUILD_STUB_LIB_SPEC +TCL_INCLUDE_SPEC +TCL_KIT_LIB_FILE +TCL_STUB_LIB_PATH +TCL_STUB_LIB_SPEC +TCL_STUB_LIB_FLAG +TCL_STUB_LIB_FILE +TCL_LIB_SPEC +TCL_LIB_FLAG +TCL_LIB_FILE +PKG_CFG_ARGS +TCL_YEAR +TCL_PATCH_LEVEL +TCL_MINOR_VERSION +TCL_MAJOR_VERSION +TCL_VERSION +DTRACE +LDFLAGS_DEFAULT +CFLAGS_DEFAULT +INSTALL_KIT_LIB +INSTALL_STUB_LIB +DLL_INSTALL_DIR +INSTALL_LIB +MAKE_STUB_LIB +MAKE_KIT_LIB +MAKE_LIB +SHLIB_SUFFIX +SHLIB_CFLAGS +SHLIB_LD_LIBS +TK_SHLIB_LD_EXTRAS +TCL_SHLIB_LD_EXTRAS +SHLIB_LD +STLIB_LD +LD_SEARCH_FLAGS +CC_SEARCH_FLAGS +LDFLAGS_OPTIMIZE +LDFLAGS_DEBUG +CFLAGS_WARNING +CFLAGS_OPTIMIZE +CFLAGS_DEBUG +LDAIX_SRC +PLAT_SRCS +PLAT_OBJS +DL_OBJS +DL_LIBS +TCL_LIBS +LIBOBJS +AR +RANLIB +ZLIB_INCLUDE +ZLIB_SRCS +ZLIB_OBJS +TCLSH_PROG +TCL_THREADS +EGREP +GREP +CPP +OBJEXT +EXEEXT +ac_ct_CC +CPPFLAGS +LDFLAGS +CFLAGS +CC +MAN_FLAGS +target_alias +host_alias +build_alias +LIBS +ECHO_T +ECHO_N +ECHO_C +DEFS +mandir +localedir +libdir +psdir +pdfdir +dvidir +htmldir +infodir +docdir +oldincludedir +includedir +localstatedir +sharedstatedir +sysconfdir +datadir +datarootdir +libexecdir +sbindir +bindir +program_transform_name +prefix +exec_prefix +PACKAGE_URL +PACKAGE_BUGREPORT +PACKAGE_STRING +PACKAGE_VERSION +PACKAGE_TARNAME +PACKAGE_NAME +PATH_SEPARATOR +SHELL' ac_subst_files='' +ac_user_opts=' +enable_option_checking +enable_man_symlinks +enable_man_compression +enable_man_suffix +enable_threads +with_encoding +enable_shared +enable_64bit +enable_64bit_vis +enable_rpath +enable_corefoundation +enable_load +enable_symbols +enable_langinfo +enable_dll_unloading +with_tzdata +enable_dtrace +enable_framework +' + ac_precious_vars='build_alias +host_alias +target_alias +CC +CFLAGS +LDFLAGS +LIBS +CPPFLAGS +CPP' + # Initialize some variables set by options. ac_init_help= ac_init_version=false +ac_unrecognized_opts= +ac_unrecognized_sep= # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null @@ -336,34 +811,49 @@ x_libraries=NONE # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. +# (The list follows the same order as the GNU Coding Standards.) bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' -datadir='${prefix}/share' +datarootdir='${prefix}/share' +datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' -libdir='${exec_prefix}/lib' includedir='${prefix}/include' oldincludedir='/usr/include' -infodir='${prefix}/info' -mandir='${prefix}/man' +docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' +infodir='${datarootdir}/info' +htmldir='${docdir}' +dvidir='${docdir}' +pdfdir='${docdir}' +psdir='${docdir}' +libdir='${exec_prefix}/lib' +localedir='${datarootdir}/locale' +mandir='${datarootdir}/man' ac_prev= +ac_dashdash= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then - eval "$ac_prev=\$ac_option" + eval $ac_prev=\$ac_option ac_prev= continue fi - ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'` + case $ac_option in + *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *=) ac_optarg= ;; + *) ac_optarg=yes ;; + esac # Accept the important Cygnus configure options, so we can diagnose typos. - case $ac_option in + case $ac_dashdash$ac_option in + --) + ac_dashdash=yes ;; -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; @@ -385,33 +875,59 @@ do --config-cache | -C) cache_file=config.cache ;; - -datadir | --datadir | --datadi | --datad | --data | --dat | --da) + -datadir | --datadir | --datadi | --datad) ac_prev=datadir ;; - -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ - | --da=*) + -datadir=* | --datadir=* | --datadi=* | --datad=*) datadir=$ac_optarg ;; + -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ + | --dataroo | --dataro | --datar) + ac_prev=datarootdir ;; + -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ + | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) + datarootdir=$ac_optarg ;; + -disable-* | --disable-*) - ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. - expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && - { echo "$as_me: error: invalid feature name: $ac_feature" >&2 - { (exit 1); exit 1; }; } - ac_feature=`echo $ac_feature | sed 's/-/_/g'` - eval "enable_$ac_feature=no" ;; + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=no ;; + + -docdir | --docdir | --docdi | --doc | --do) + ac_prev=docdir ;; + -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) + docdir=$ac_optarg ;; + + -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) + ac_prev=dvidir ;; + -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) + dvidir=$ac_optarg ;; -enable-* | --enable-*) - ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. - expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && - { echo "$as_me: error: invalid feature name: $ac_feature" >&2 - { (exit 1); exit 1; }; } - ac_feature=`echo $ac_feature | sed 's/-/_/g'` - case $ac_option in - *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; - *) ac_optarg=yes ;; + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; esac - eval "enable_$ac_feature='$ac_optarg'" ;; + eval enable_$ac_useropt=\$ac_optarg ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ @@ -438,6 +954,12 @@ do -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; + -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) + ac_prev=htmldir ;; + -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ + | --ht=*) + htmldir=$ac_optarg ;; + -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; @@ -462,13 +984,16 @@ do | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; + -localedir | --localedir | --localedi | --localed | --locale) + ac_prev=localedir ;; + -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) + localedir=$ac_optarg ;; + -localstatedir | --localstatedir | --localstatedi | --localstated \ - | --localstate | --localstat | --localsta | --localst \ - | --locals | --local | --loca | --loc | --lo) + | --localstate | --localstat | --localsta | --localst | --locals) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ - | --localstate=* | --localstat=* | --localsta=* | --localst=* \ - | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) + | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) @@ -533,6 +1058,16 @@ do | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; + -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) + ac_prev=pdfdir ;; + -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) + pdfdir=$ac_optarg ;; + + -psdir | --psdir | --psdi | --psd | --ps) + ac_prev=psdir ;; + -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) + psdir=$ac_optarg ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; @@ -583,26 +1118,36 @@ do ac_init_version=: ;; -with-* | --with-*) - ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. - expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && - { echo "$as_me: error: invalid package name: $ac_package" >&2 - { (exit 1); exit 1; }; } - ac_package=`echo $ac_package| sed 's/-/_/g'` - case $ac_option in - *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; - *) ac_optarg=yes ;; + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" + ac_unrecognized_sep=', ';; esac - eval "with_$ac_package='$ac_optarg'" ;; + eval with_$ac_useropt=\$ac_optarg ;; -without-* | --without-*) - ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` + ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. - expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && - { echo "$as_me: error: invalid package name: $ac_package" >&2 - { (exit 1); exit 1; }; } - ac_package=`echo $ac_package | sed 's/-/_/g'` - eval "with_$ac_package=no" ;; + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=no ;; --x) # Obsolete; use --with-x. @@ -622,27 +1167,26 @@ do | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; - -*) { echo "$as_me: error: unrecognized option: $ac_option -Try \`$0 --help' for more information." >&2 - { (exit 1); exit 1; }; } + -*) as_fn_error $? "unrecognized option: \`$ac_option' +Try \`$0 --help' for more information" ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. - expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && - { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 - { (exit 1); exit 1; }; } - ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` - eval "$ac_envvar='$ac_optarg'" + case $ac_envvar in #( + '' | [0-9]* | *[!_$as_cr_alnum]* ) + as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; + esac + eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. - echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && - echo "$as_me: WARNING: invalid host type: $ac_option" >&2 - : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} + $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" ;; esac @@ -650,31 +1194,36 @@ done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` - { echo "$as_me: error: missing argument to $ac_option" >&2 - { (exit 1); exit 1; }; } + as_fn_error $? "missing argument to $ac_option" fi -# Be sure to have absolute paths. -for ac_var in exec_prefix prefix -do - eval ac_val=$`echo $ac_var` - case $ac_val in - [\\/$]* | ?:[\\/]* | NONE | '' ) ;; - *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 - { (exit 1); exit 1; }; };; +if test -n "$ac_unrecognized_opts"; then + case $enable_option_checking in + no) ;; + fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; + *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; esac -done +fi -# Be sure to have absolute paths. -for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \ - localstatedir libdir includedir oldincludedir infodir mandir +# Check all directory arguments for consistency. +for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ + libdir localedir mandir do - eval ac_val=$`echo $ac_var` + eval ac_val=\$$ac_var + # Remove trailing slashes. + case $ac_val in + */ ) + ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` + eval $ac_var=\$ac_val;; + esac + # Be sure to have absolute directory names. case $ac_val in - [\\/$]* | ?:[\\/]* ) ;; - *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 - { (exit 1); exit 1; }; };; + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac + as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" done # There might be people who depend on the old broken behavior: `$host' @@ -688,8 +1237,6 @@ target=$target_alias if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe - echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. - If a cross compiler is detected then cross compile mode will be used." >&2 elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi @@ -701,74 +1248,72 @@ test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null +ac_pwd=`pwd` && test -n "$ac_pwd" && +ac_ls_di=`ls -di .` && +ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || + as_fn_error $? "working directory cannot be determined" +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + as_fn_error $? "pwd does not report name of working directory" + + # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes - # Try the directory containing this script, then its parent. - ac_confdir=`(dirname "$0") 2>/dev/null || -$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$0" : 'X\(//\)[^/]' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)' \| \ - . : '\(.\)' 2>/dev/null || -echo X"$0" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } - /^X\(\/\/\)[^/].*/{ s//\1/; q; } - /^X\(\/\/\)$/{ s//\1/; q; } - /^X\(\/\).*/{ s//\1/; q; } - s/.*/./; q'` + # Try the directory containing this script, then the parent directory. + ac_confdir=`$as_dirname -- "$as_myself" || +$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_myself" : 'X\(//\)[^/]' \| \ + X"$as_myself" : 'X\(//\)$' \| \ + X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_myself" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` srcdir=$ac_confdir - if test ! -r $srcdir/$ac_unique_file; then + if test ! -r "$srcdir/$ac_unique_file"; then srcdir=.. fi else ac_srcdir_defaulted=no fi -if test ! -r $srcdir/$ac_unique_file; then - if test "$ac_srcdir_defaulted" = yes; then - { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2 - { (exit 1); exit 1; }; } - else - { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 - { (exit 1); exit 1; }; } - fi -fi -(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null || - { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2 - { (exit 1); exit 1; }; } -srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'` -ac_env_build_alias_set=${build_alias+set} -ac_env_build_alias_value=$build_alias -ac_cv_env_build_alias_set=${build_alias+set} -ac_cv_env_build_alias_value=$build_alias -ac_env_host_alias_set=${host_alias+set} -ac_env_host_alias_value=$host_alias -ac_cv_env_host_alias_set=${host_alias+set} -ac_cv_env_host_alias_value=$host_alias -ac_env_target_alias_set=${target_alias+set} -ac_env_target_alias_value=$target_alias -ac_cv_env_target_alias_set=${target_alias+set} -ac_cv_env_target_alias_value=$target_alias -ac_env_CC_set=${CC+set} -ac_env_CC_value=$CC -ac_cv_env_CC_set=${CC+set} -ac_cv_env_CC_value=$CC -ac_env_CFLAGS_set=${CFLAGS+set} -ac_env_CFLAGS_value=$CFLAGS -ac_cv_env_CFLAGS_set=${CFLAGS+set} -ac_cv_env_CFLAGS_value=$CFLAGS -ac_env_LDFLAGS_set=${LDFLAGS+set} -ac_env_LDFLAGS_value=$LDFLAGS -ac_cv_env_LDFLAGS_set=${LDFLAGS+set} -ac_cv_env_LDFLAGS_value=$LDFLAGS -ac_env_CPPFLAGS_set=${CPPFLAGS+set} -ac_env_CPPFLAGS_value=$CPPFLAGS -ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set} -ac_cv_env_CPPFLAGS_value=$CPPFLAGS -ac_env_CPP_set=${CPP+set} -ac_env_CPP_value=$CPP -ac_cv_env_CPP_set=${CPP+set} -ac_cv_env_CPP_value=$CPP +if test ! -r "$srcdir/$ac_unique_file"; then + test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." + as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" +fi +ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +ac_abs_confdir=`( + cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" + pwd)` +# When building in place, set srcdir=. +if test "$ac_abs_confdir" = "$ac_pwd"; then + srcdir=. +fi +# Remove unnecessary trailing slashes from srcdir. +# Double slashes in file names in object file debugging info +# mess up M-x gdb in Emacs. +case $srcdir in +*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +esac +for ac_var in $ac_precious_vars; do + eval ac_env_${ac_var}_set=\${${ac_var}+set} + eval ac_env_${ac_var}_value=\$${ac_var} + eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} + eval ac_cv_env_${ac_var}_value=\$${ac_var} +done # # Report the --help message. @@ -791,20 +1336,17 @@ Configuration: --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit - -q, --quiet, --silent do not print \`checking...' messages + -q, --quiet, --silent do not print \`checking ...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] -_ACEOF - - cat <<_ACEOF Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX - [$ac_default_prefix] + [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX - [PREFIX] + [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify @@ -814,18 +1356,25 @@ for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: - --bindir=DIR user executables [EPREFIX/bin] - --sbindir=DIR system admin executables [EPREFIX/sbin] - --libexecdir=DIR program executables [EPREFIX/libexec] - --datadir=DIR read-only architecture-independent data [PREFIX/share] - --sysconfdir=DIR read-only single-machine data [PREFIX/etc] - --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] - --localstatedir=DIR modifiable single-machine data [PREFIX/var] - --libdir=DIR object code libraries [EPREFIX/lib] - --includedir=DIR C header files [PREFIX/include] - --oldincludedir=DIR C header files for non-gcc [/usr/include] - --infodir=DIR info documentation [PREFIX/info] - --mandir=DIR man documentation [PREFIX/man] + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --infodir=DIR info documentation [DATAROOTDIR/info] + --localedir=DIR locale-dependent data [DATAROOTDIR/locale] + --mandir=DIR man documentation [DATAROOTDIR/man] + --docdir=DIR documentation root [DATAROOTDIR/doc/tcl] + --htmldir=DIR html documentation [DOCDIR] + --dvidir=DIR dvi documentation [DOCDIR] + --pdfdir=DIR pdf documentation [DOCDIR] + --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF @@ -839,6 +1388,7 @@ if test -n "$ac_init_help"; then cat <<\_ACEOF Optional Features: + --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --enable-man-symlinks use symlinks for the manpages (default: off) @@ -876,162 +1426,595 @@ Some influential environment variables: CFLAGS C compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory - CPPFLAGS C/C++ preprocessor flags, e.g. -I if you have - headers in a nonstandard directory + LIBS libraries to pass to the linker, e.g. -l + CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if + you have headers in a nonstandard directory CPP C preprocessor Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. +Report bugs to the package provider. _ACEOF +ac_status=$? fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. - ac_popdir=`pwd` for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue - test -d $ac_dir || continue + test -d "$ac_dir" || + { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || + continue ac_builddir=. -if test "$ac_dir" != .; then - ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` - # A "../" for each directory in $ac_dir_suffix. - ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` -else - ac_dir_suffix= ac_top_builddir= -fi +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix case $srcdir in - .) # No --srcdir option. We are building in place. + .) # We are building in place. ac_srcdir=. - if test -z "$ac_top_builddir"; then - ac_top_srcdir=. - else - ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` - fi ;; - [\\/]* | ?:[\\/]* ) # Absolute path. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; - ac_top_srcdir=$srcdir ;; - *) # Relative path. - ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix - ac_top_srcdir=$ac_top_builddir$srcdir ;; -esac - -# Do not use `cd foo && pwd` to compute absolute paths, because -# the directories may not exist. -case `pwd` in -.) ac_abs_builddir="$ac_dir";; -*) - case "$ac_dir" in - .) ac_abs_builddir=`pwd`;; - [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; - *) ac_abs_builddir=`pwd`/"$ac_dir";; - esac;; -esac -case $ac_abs_builddir in -.) ac_abs_top_builddir=${ac_top_builddir}.;; -*) - case ${ac_top_builddir}. in - .) ac_abs_top_builddir=$ac_abs_builddir;; - [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; - *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; - esac;; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac -case $ac_abs_builddir in -.) ac_abs_srcdir=$ac_srcdir;; -*) - case $ac_srcdir in - .) ac_abs_srcdir=$ac_abs_builddir;; - [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; - *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; - esac;; -esac -case $ac_abs_builddir in -.) ac_abs_top_srcdir=$ac_top_srcdir;; -*) - case $ac_top_srcdir in - .) ac_abs_top_srcdir=$ac_abs_builddir;; - [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; - *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; - esac;; -esac - - cd $ac_dir - # Check for guested configure; otherwise get Cygnus style configure. - if test -f $ac_srcdir/configure.gnu; then - echo - $SHELL $ac_srcdir/configure.gnu --help=recursive - elif test -f $ac_srcdir/configure; then - echo - $SHELL $ac_srcdir/configure --help=recursive - elif test -f $ac_srcdir/configure.ac || - test -f $ac_srcdir/configure.in; then - echo - $ac_configure --help +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + cd "$ac_dir" || { ac_status=$?; continue; } + # Check for guested configure. + if test -f "$ac_srcdir/configure.gnu"; then + echo && + $SHELL "$ac_srcdir/configure.gnu" --help=recursive + elif test -f "$ac_srcdir/configure"; then + echo && + $SHELL "$ac_srcdir/configure" --help=recursive else - echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 - fi - cd $ac_popdir + $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi || ac_status=$? + cd "$ac_pwd" || { ac_status=$?; break; } done fi -test -n "$ac_init_help" && exit 0 +test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF tcl configure 8.6 -generated by GNU Autoconf 2.59 +generated by GNU Autoconf 2.69 -Copyright (C) 2003 Free Software Foundation, Inc. +Copyright (C) 2012 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF - exit 0 + exit fi -exec 5>config.log -cat >&5 <<_ACEOF -This file contains any messages produced by compilers while -running configure, to aid debugging if configure makes a mistake. - -It was created by tcl $as_me 8.6, which was -generated by GNU Autoconf 2.59. Invocation command line was - $ $0 $@ +## ------------------------ ## +## Autoconf initialization. ## +## ------------------------ ## -_ACEOF +# ac_fn_c_try_compile LINENO +# -------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_compile () { -cat <<_ASUNAME -## --------- ## -## Platform. ## -## --------- ## + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 -hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` -uname -m = `(uname -m) 2>/dev/null || echo unknown` -uname -r = `(uname -r) 2>/dev/null || echo unknown` -uname -s = `(uname -s) 2>/dev/null || echo unknown` -uname -v = `(uname -v) 2>/dev/null || echo unknown` + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval -/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` -/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` +} # ac_fn_c_try_compile -/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` -/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` -/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` -hostinfo = `(hostinfo) 2>/dev/null || echo unknown` -/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` -/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` -/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` +# ac_fn_c_try_link LINENO +# ----------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_link () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest$ac_exeext + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + test -x conftest$ac_exeext + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information + # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would + # interfere with the next link command; also delete a directory that is + # left behind by Apple's compiler. We do this before executing the actions. + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_link + +# ac_fn_c_try_cpp LINENO +# ---------------------- +# Try to preprocess conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_cpp () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } > conftest.i && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 -_ASUNAME + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - echo "PATH: $as_dir" -done +} # ac_fn_c_try_cpp -} >&5 +# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists, giving a warning if it cannot be compiled using +# the include files in INCLUDES and setting the cache variable VAR +# accordingly. +ac_fn_c_check_header_mongrel () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if eval \${$3+:} false; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +else + # Is the header compilable? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 +$as_echo_n "checking $2 usability... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_header_compiler=yes +else + ac_header_compiler=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 +$as_echo "$ac_header_compiler" >&6; } + +# Is the header present? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 +$as_echo_n "checking $2 presence... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <$2> +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + ac_header_preproc=yes +else + ac_header_preproc=no +fi +rm -f conftest.err conftest.i conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 +$as_echo "$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( + yes:no: ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 +$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} + ;; + no:yes:* ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 +$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 +$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 +$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 +$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} + ;; +esac + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=\$ac_header_compiler" +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_header_mongrel + +# ac_fn_c_try_run LINENO +# ---------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes +# that executables *can* be run. +ac_fn_c_try_run () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then : + ac_retval=0 +else + $as_echo "$as_me: program exited with status $ac_status" >&5 + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=$ac_status +fi + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_run + +# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists and can be compiled using the include files in +# INCLUDES, setting the cache variable VAR accordingly. +ac_fn_c_check_header_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_header_compile + +# ac_fn_c_check_func LINENO FUNC VAR +# ---------------------------------- +# Tests whether FUNC exists, setting the cache variable VAR accordingly +ac_fn_c_check_func () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +/* Define $2 to an innocuous variant, in case declares $2. + For example, HP-UX 11i declares gettimeofday. */ +#define $2 innocuous_$2 + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $2 (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $2 + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $2 (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$2 || defined __stub___$2 +choke me +#endif + +int +main () +{ +return $2 (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_func + +# ac_fn_c_check_type LINENO TYPE VAR INCLUDES +# ------------------------------------------- +# Tests whether TYPE exists after having included INCLUDES, setting cache +# variable VAR accordingly. +ac_fn_c_check_type () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=no" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +if (sizeof ($2)) + return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +if (sizeof (($2))) + return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + eval "$3=yes" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_type + +# ac_fn_c_check_member LINENO AGGR MEMBER VAR INCLUDES +# ---------------------------------------------------- +# Tries to find if the field MEMBER exists in type AGGR, after including +# INCLUDES, setting cache variable VAR accordingly. +ac_fn_c_check_member () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2.$3" >&5 +$as_echo_n "checking for $2.$3... " >&6; } +if eval \${$4+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$5 +int +main () +{ +static $2 ac_aggr; +if (ac_aggr.$3) +return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$4=yes" +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$5 +int +main () +{ +static $2 ac_aggr; +if (sizeof ac_aggr.$3) +return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$4=yes" +else + eval "$4=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$4 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_member +cat >config.log <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by tcl $as_me 8.6, which was +generated by GNU Autoconf 2.69. Invocation command line was + + $ $0 $@ + +_ACEOF +exec 5>>config.log +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + $as_echo "PATH: $as_dir" + done +IFS=$as_save_IFS + +} >&5 cat >&5 <<_ACEOF @@ -1051,7 +2034,6 @@ _ACEOF ac_configure_args= ac_configure_args0= ac_configure_args1= -ac_sep= ac_must_keep_next=false for ac_pass in 1 2 do @@ -1062,13 +2044,13 @@ do -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; - *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) - ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + *\'*) + ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in - 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; + 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; 2) - ac_configure_args1="$ac_configure_args1 '$ac_arg'" + as_fn_append ac_configure_args1 " '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else @@ -1084,104 +2066,115 @@ do -* ) ac_must_keep_next=true ;; esac fi - ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'" - # Get rid of the leading space. - ac_sep=" " + as_fn_append ac_configure_args " '$ac_arg'" ;; esac done done -$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } -$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; } +{ ac_configure_args0=; unset ac_configure_args0;} +{ ac_configure_args1=; unset ac_configure_args1;} # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. -# WARNING: Be sure not to use single quotes in there, as some shells, -# such as our DU 5.0 friend, will then `close' the trap. +# WARNING: Use '\'' to represent an apostrophe within the trap. +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo - cat <<\_ASBOX -## ---------------- ## + $as_echo "## ---------------- ## ## Cache variables. ## -## ---------------- ## -_ASBOX +## ---------------- ##" echo # The following way of writing the cache mishandles newlines in values, -{ +( + for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done (set) 2>&1 | - case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in - *ac_space=\ *) + case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( + *${as_nl}ac_space=\ *) sed -n \ - "s/'"'"'/'"'"'\\\\'"'"''"'"'/g; - s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p" - ;; + "s/'\''/'\''\\\\'\'''\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" + ;; #( *) - sed -n \ - "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; - esac; -} + esac | + sort +) echo - cat <<\_ASBOX -## ----------------- ## + $as_echo "## ----------------- ## ## Output variables. ## -## ----------------- ## -_ASBOX +## ----------------- ##" echo for ac_var in $ac_subst_vars do - eval ac_val=$`echo $ac_var` - echo "$ac_var='"'"'$ac_val'"'"'" + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then - cat <<\_ASBOX -## ------------- ## -## Output files. ## -## ------------- ## -_ASBOX + $as_echo "## ------------------- ## +## File substitutions. ## +## ------------------- ##" echo for ac_var in $ac_subst_files do - eval ac_val=$`echo $ac_var` - echo "$ac_var='"'"'$ac_val'"'"'" + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then - cat <<\_ASBOX -## ----------- ## + $as_echo "## ----------- ## ## confdefs.h. ## -## ----------- ## -_ASBOX +## ----------- ##" echo - sed "/^$/d" confdefs.h | sort + cat confdefs.h echo fi test "$ac_signal" != 0 && - echo "$as_me: caught signal $ac_signal" - echo "$as_me: exit $exit_status" + $as_echo "$as_me: caught signal $ac_signal" + $as_echo "$as_me: exit $exit_status" } >&5 - rm -f core *.core && - rm -rf conftest* confdefs* conf$$* $ac_clean_files && + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status - ' 0 +' 0 for ac_signal in 1 2 13 15; do - trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal + trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. -rm -rf conftest* confdefs.h -# AIX cpp loses on an empty file, so make sure it contains at least a newline. -echo >confdefs.h +rm -f -r conftest* confdefs.h + +$as_echo "/* confdefs.h */" > confdefs.h # Predefined preprocessor variables. @@ -1189,112 +2182,137 @@ cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF - cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF - cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF - cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF - cat >>confdefs.h <<_ACEOF #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF +cat >>confdefs.h <<_ACEOF +#define PACKAGE_URL "$PACKAGE_URL" +_ACEOF + # Let the site file select an alternate cache file if it wants to. -# Prefer explicitly selected file to automatically selected ones. -if test -z "$CONFIG_SITE"; then - if test "x$prefix" != xNONE; then - CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" - else - CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" - fi +# Prefer an explicitly selected file to automatically selected ones. +ac_site_file1=NONE +ac_site_file2=NONE +if test -n "$CONFIG_SITE"; then + # We do not want a PATH search for config.site. + case $CONFIG_SITE in #(( + -*) ac_site_file1=./$CONFIG_SITE;; + */*) ac_site_file1=$CONFIG_SITE;; + *) ac_site_file1=./$CONFIG_SITE;; + esac +elif test "x$prefix" != xNONE; then + ac_site_file1=$prefix/share/config.site + ac_site_file2=$prefix/etc/config.site +else + ac_site_file1=$ac_default_prefix/share/config.site + ac_site_file2=$ac_default_prefix/etc/config.site fi -for ac_site_file in $CONFIG_SITE; do - if test -r "$ac_site_file"; then - { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 -echo "$as_me: loading site script $ac_site_file" >&6;} +for ac_site_file in "$ac_site_file1" "$ac_site_file2" +do + test "x$ac_site_file" = xNONE && continue + if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 +$as_echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 - . "$ac_site_file" + . "$ac_site_file" \ + || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "failed to load site script $ac_site_file +See \`config.log' for more details" "$LINENO" 5; } fi done if test -r "$cache_file"; then - # Some versions of bash will fail to source /dev/null (special - # files actually), so we avoid doing that. - if test -f "$cache_file"; then - { echo "$as_me:$LINENO: loading cache $cache_file" >&5 -echo "$as_me: loading cache $cache_file" >&6;} + # Some versions of bash will fail to source /dev/null (special files + # actually), so we avoid doing that. DJGPP emulates it as a regular file. + if test /dev/null != "$cache_file" && test -f "$cache_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 +$as_echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in - [\\/]* | ?:[\\/]* ) . $cache_file;; - *) . ./$cache_file;; + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; esac fi else - { echo "$as_me:$LINENO: creating cache $cache_file" >&5 -echo "$as_me: creating cache $cache_file" >&6;} + { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 +$as_echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false -for ac_var in `(set) 2>&1 | - sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do +for ac_var in $ac_precious_vars; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set - eval ac_old_val="\$ac_cv_env_${ac_var}_value" - eval ac_new_val="\$ac_env_${ac_var}_value" + eval ac_old_val=\$ac_cv_env_${ac_var}_value + eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) - { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 -echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) - { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 -echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then - { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 -echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} - { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 -echo "$as_me: former value: $ac_old_val" >&2;} - { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 -echo "$as_me: current value: $ac_new_val" >&2;} - ac_cache_corrupted=: + # differences in whitespace do not lead to failure. + ac_old_val_w=`echo x $ac_old_val` + ac_new_val_w=`echo x $ac_new_val` + if test "$ac_old_val_w" != "$ac_new_val_w"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 +$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + ac_cache_corrupted=: + else + { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 +$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} + eval $ac_var=\$ac_old_val + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 +$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 +$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in - *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) - ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. - *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; + *) as_fn_append ac_configure_args " '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then - { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 -echo "$as_me: error: changes in the environment can compromise the build" >&2;} - { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 -echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} - { (exit 1); exit 1; }; } + { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 +$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} + as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 fi +## -------------------- ## +## Main body of script. ## +## -------------------- ## ac_ext=c ac_cpp='$CPP $CPPFLAGS' @@ -1307,31 +2325,6 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu - - - - - - - - - - - - - - - - - - - - - - - - - TCL_VERSION=8.6 TCL_MAJOR_VERSION=8 TCL_MINOR_VERSION=6 @@ -1382,62 +2375,60 @@ TCL_SRC_DIR="`cd "$srcdir"/..; pwd`" #------------------------------------------------------------------------ - echo "$as_me:$LINENO: checking whether to use symlinks for manpages" >&5 -echo $ECHO_N "checking whether to use symlinks for manpages... $ECHO_C" >&6 - # Check whether --enable-man-symlinks or --disable-man-symlinks was given. -if test "${enable_man_symlinks+set}" = set; then - enableval="$enable_man_symlinks" - test "$enableval" != "no" && MAN_FLAGS="$MAN_FLAGS --symlinks" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use symlinks for manpages" >&5 +$as_echo_n "checking whether to use symlinks for manpages... " >&6; } + # Check whether --enable-man-symlinks was given. +if test "${enable_man_symlinks+set}" = set; then : + enableval=$enable_man_symlinks; test "$enableval" != "no" && MAN_FLAGS="$MAN_FLAGS --symlinks" else enableval="no" -fi; - echo "$as_me:$LINENO: result: $enableval" >&5 -echo "${ECHO_T}$enableval" >&6 - - echo "$as_me:$LINENO: checking whether to compress the manpages" >&5 -echo $ECHO_N "checking whether to compress the manpages... $ECHO_C" >&6 - # Check whether --enable-man-compression or --disable-man-compression was given. -if test "${enable_man_compression+set}" = set; then - enableval="$enable_man_compression" - case $enableval in - yes) { { echo "$as_me:$LINENO: error: missing argument to --enable-man-compression" >&5 -echo "$as_me: error: missing argument to --enable-man-compression" >&2;} - { (exit 1); exit 1; }; };; +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enableval" >&5 +$as_echo "$enableval" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to compress the manpages" >&5 +$as_echo_n "checking whether to compress the manpages... " >&6; } + # Check whether --enable-man-compression was given. +if test "${enable_man_compression+set}" = set; then : + enableval=$enable_man_compression; case $enableval in + yes) as_fn_error $? "missing argument to --enable-man-compression" "$LINENO" 5;; no) ;; *) MAN_FLAGS="$MAN_FLAGS --compress $enableval";; esac else enableval="no" -fi; - echo "$as_me:$LINENO: result: $enableval" >&5 -echo "${ECHO_T}$enableval" >&6 +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enableval" >&5 +$as_echo "$enableval" >&6; } if test "$enableval" != "no"; then - echo "$as_me:$LINENO: checking for compressed file suffix" >&5 -echo $ECHO_N "checking for compressed file suffix... $ECHO_C" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for compressed file suffix" >&5 +$as_echo_n "checking for compressed file suffix... " >&6; } touch TeST $enableval TeST Z=`ls TeST* | sed 's/^....//'` rm -f TeST* MAN_FLAGS="$MAN_FLAGS --extension $Z" - echo "$as_me:$LINENO: result: $Z" >&5 -echo "${ECHO_T}$Z" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $Z" >&5 +$as_echo "$Z" >&6; } fi - echo "$as_me:$LINENO: checking whether to add a package name suffix for the manpages" >&5 -echo $ECHO_N "checking whether to add a package name suffix for the manpages... $ECHO_C" >&6 - # Check whether --enable-man-suffix or --disable-man-suffix was given. -if test "${enable_man_suffix+set}" = set; then - enableval="$enable_man_suffix" - case $enableval in + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to add a package name suffix for the manpages" >&5 +$as_echo_n "checking whether to add a package name suffix for the manpages... " >&6; } + # Check whether --enable-man-suffix was given. +if test "${enable_man_suffix+set}" = set; then : + enableval=$enable_man_suffix; case $enableval in yes) enableval="tcl" MAN_FLAGS="$MAN_FLAGS --suffix $enableval";; no) ;; *) MAN_FLAGS="$MAN_FLAGS --suffix $enableval";; esac else enableval="no" -fi; - echo "$as_me:$LINENO: result: $enableval" >&5 -echo "${ECHO_T}$enableval" >&6 +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enableval" >&5 +$as_echo "$enableval" >&6; } @@ -1460,10 +2451,10 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. @@ -1473,35 +2464,37 @@ for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}gcc" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done -done + done +IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then - echo "$as_me:$LINENO: result: $CC" >&5 -echo "${ECHO_T}$CC" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } fi + fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_ac_ct_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. @@ -1511,39 +2504,50 @@ for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="gcc" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done -done + done +IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then - echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 -echo "${ECHO_T}$ac_ct_CC" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } fi - CC=$ac_ct_CC + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. @@ -1553,77 +2557,37 @@ for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}cc" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done -done + done +IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then - echo "$as_me:$LINENO: result: $CC" >&5 -echo "${ECHO_T}$CC" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } fi + + fi fi -if test -z "$ac_cv_prog_CC"; then - ac_ct_CC=$CC +if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_ac_ct_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$ac_ct_CC"; then - ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_CC="cc" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -fi -fi -ac_ct_CC=$ac_cv_prog_ac_ct_CC -if test -n "$ac_ct_CC"; then - echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 -echo "${ECHO_T}$ac_ct_CC" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - - CC=$ac_ct_CC -else - CC="$ac_cv_prog_CC" -fi - -fi -if test -z "$CC"; then - # Extract the first word of "cc", so it can be a program name with args. -set dummy cc; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. @@ -1634,18 +2598,19 @@ for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done -done + done +IFS=$as_save_IFS if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. @@ -1663,24 +2628,25 @@ fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then - echo "$as_me:$LINENO: result: $CC" >&5 -echo "${ECHO_T}$CC" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } fi + fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then - for ac_prog in cl + for ac_prog in cl.exe do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. @@ -1690,39 +2656,41 @@ for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done -done + done +IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then - echo "$as_me:$LINENO: result: $CC" >&5 -echo "${ECHO_T}$CC" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } fi + test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC - for ac_prog in cl + for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_ac_ct_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. @@ -1732,66 +2700,78 @@ for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="$ac_prog" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done -done + done +IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then - echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 -echo "${ECHO_T}$ac_ct_CC" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } fi + test -n "$ac_ct_CC" && break done - CC=$ac_ct_CC + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi fi fi -test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH -See \`config.log' for more details." >&5 -echo "$as_me: error: no acceptable C compiler found in \$PATH -See \`config.log' for more details." >&2;} - { (exit 1); exit 1; }; } +test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "no acceptable C compiler found in \$PATH +See \`config.log' for more details" "$LINENO" 5; } # Provide some information about the compiler. -echo "$as_me:$LINENO:" \ - "checking for C compiler version" >&5 -ac_compiler=`set X $ac_compile; echo $2` -{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version &5\"") >&5 - (eval $ac_compiler --version &5) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } -{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v &5\"") >&5 - (eval $ac_compiler -v &5) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } -{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V &5\"") >&5 - (eval $ac_compiler -V &5) 2>&5 +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF +cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int @@ -1803,112 +2783,108 @@ main () } _ACEOF ac_clean_files_save=$ac_clean_files -ac_clean_files="$ac_clean_files a.out a.exe b.out" +ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. -echo "$as_me:$LINENO: checking for C compiler default output file name" >&5 -echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6 -ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` -if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5 - (eval $ac_link_default) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; then - # Find the output, starting from the most likely. This scheme is -# not robust to junk in `.', hence go to wildcards (a.*) only as a last -# resort. - -# Be careful to initialize this variable, since it used to be cached. -# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile. -ac_cv_exeext= -# b.out is created by i960 compilers. -for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 +$as_echo_n "checking whether the C compiler works... " >&6; } +ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` + +# The possible output files: +ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" + +ac_rmfiles= +for ac_file in $ac_files +do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + * ) ac_rmfiles="$ac_rmfiles $ac_file";; + esac +done +rm -f $ac_rmfiles + +if { { ac_try="$ac_link_default" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link_default") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. +# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' +# in a Makefile. We should not override ac_cv_exeext if it was cached, +# so that the user can short-circuit this test for compilers unknown to +# Autoconf. +for ac_file in $ac_files '' do test -f "$ac_file" || continue case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) - ;; - conftest.$ac_ext ) - # This is the source file. + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) - ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` - # FIXME: I believe we export ac_cv_exeext for Libtool, - # but it would be cool to find out if it's true. Does anybody - # maintain Libtool? --akim. - export ac_cv_exeext + if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; + then :; else + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + fi + # We set ac_cv_exeext here because the later test for it is not + # safe: cross compilers may not add the suffix if given an `-o' + # argument, so we may need to know it at that point already. + # Even if this section looks crufty: it has the advantage of + # actually working. break;; * ) break;; esac done +test "$ac_cv_exeext" = no && ac_cv_exeext= + else - echo "$as_me: failed program was:" >&5 + ac_file='' +fi +if test -z "$ac_file"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +$as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 -{ { echo "$as_me:$LINENO: error: C compiler cannot create executables -See \`config.log' for more details." >&5 -echo "$as_me: error: C compiler cannot create executables -See \`config.log' for more details." >&2;} - { (exit 77); exit 77; }; } +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "C compiler cannot create executables +See \`config.log' for more details" "$LINENO" 5; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } fi - +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 +$as_echo_n "checking for C compiler default output file name... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 +$as_echo "$ac_file" >&6; } ac_exeext=$ac_cv_exeext -echo "$as_me:$LINENO: result: $ac_file" >&5 -echo "${ECHO_T}$ac_file" >&6 - -# Check the compiler produces executables we can run. If not, either -# the compiler is broken, or we cross compile. -echo "$as_me:$LINENO: checking whether the C compiler works" >&5 -echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6 -# FIXME: These cross compiler hacks should be removed for Autoconf 3.0 -# If not cross compiling, check that we can run a simple program. -if test "$cross_compiling" != yes; then - if { ac_try='./$ac_file' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - cross_compiling=no - else - if test "$cross_compiling" = maybe; then - cross_compiling=yes - else - { { echo "$as_me:$LINENO: error: cannot run C compiled programs. -If you meant to cross compile, use \`--host'. -See \`config.log' for more details." >&5 -echo "$as_me: error: cannot run C compiled programs. -If you meant to cross compile, use \`--host'. -See \`config.log' for more details." >&2;} - { (exit 1); exit 1; }; } - fi - fi -fi -echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6 -rm -f a.out a.exe conftest$ac_cv_exeext b.out +rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save -# Check the compiler produces executables we can run. If not, either -# the compiler is broken, or we cross compile. -echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 -echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6 -echo "$as_me:$LINENO: result: $cross_compiling" >&5 -echo "${ECHO_T}$cross_compiling" >&6 - -echo "$as_me:$LINENO: checking for suffix of executables" >&5 -echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6 -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 +$as_echo_n "checking for suffix of executables... " >&6; } +if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; then + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with @@ -1916,38 +2892,90 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;; + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` - export ac_cv_exeext break;; * ) break;; esac done else - { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link -See \`config.log' for more details." >&5 -echo "$as_me: error: cannot compute suffix of executables: cannot compile and link -See \`config.log' for more details." >&2;} - { (exit 1); exit 1; }; } + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details" "$LINENO" 5; } fi - -rm -f conftest$ac_cv_exeext -echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 -echo "${ECHO_T}$ac_cv_exeext" >&6 +rm -f conftest conftest$ac_cv_exeext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 +$as_echo "$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT -echo "$as_me:$LINENO: checking for suffix of object files" >&5 -echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6 -if test "${ac_cv_objext+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +FILE *f = fopen ("conftest.out", "w"); + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} _ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF +ac_clean_files="$ac_clean_files conftest.out" +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 +$as_echo_n "checking whether we are cross compiling... " >&6; } +if test "$cross_compiling" != yes; then + { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if { ac_try='./conftest$ac_cv_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details" "$LINENO" 5; } + fi + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 +$as_echo "$cross_compiling" >&6; } + +rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 +$as_echo_n "checking for suffix of object files... " >&6; } +if ${ac_cv_objext+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int @@ -1959,45 +2987,46 @@ main () } _ACEOF rm -f conftest.o conftest.obj -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; then - for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do +if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + for ac_file in conftest.o conftest.obj conftest.*; do + test -f "$ac_file" || continue; case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;; + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else - echo "$as_me: failed program was:" >&5 + $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 -{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile -See \`config.log' for more details." >&5 -echo "$as_me: error: cannot compute suffix of object files: cannot compile -See \`config.log' for more details." >&2;} - { (exit 1); exit 1; }; } +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of object files: cannot compile +See \`config.log' for more details" "$LINENO" 5; } fi - rm -f conftest.$ac_cv_objext conftest.$ac_ext fi -echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 -echo "${ECHO_T}$ac_cv_objext" >&6 +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 +$as_echo "$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT -echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 -echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6 -if test "${ac_cv_c_compiler_gnu+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 +$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } +if ${ac_cv_c_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int @@ -2011,55 +3040,34 @@ main () return 0; } _ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then +if ac_fn_c_try_compile "$LINENO"; then : ac_compiler_gnu=yes else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_compiler_gnu=no + ac_compiler_gnu=no fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi -echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 -echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6 -GCC=`test $ac_compiler_gnu = yes && echo yes` +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 +$as_echo "$ac_cv_c_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GCC=yes +else + GCC= +fi ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS -CFLAGS="-g" -echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 -echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6 -if test "${ac_cv_prog_cc_g+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 +$as_echo_n "checking whether $CC accepts -g... " >&6; } +if ${ac_cv_prog_cc_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int @@ -2070,39 +3078,49 @@ main () return 0; } _ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then +if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 + CFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ -ac_cv_prog_cc_g=no + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag fi -echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 -echo "${ECHO_T}$ac_cv_prog_cc_g" >&6 +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 +$as_echo "$ac_cv_prog_cc_g" >&6; } if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then @@ -2118,23 +3136,18 @@ else CFLAGS= fi fi -echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5 -echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6 -if test "${ac_cv_prog_cc_stdc+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 +$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } +if ${ac_cv_prog_cc_c89+:} false; then : + $as_echo_n "(cached) " >&6 else - ac_cv_prog_cc_stdc=no + ac_cv_prog_cc_c89=no ac_save_CC=$CC -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF +cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include -#include -#include +struct stat; /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); @@ -2157,12 +3170,17 @@ static char *f (char * (*g) (char **, int), char **p, ...) /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated - as 'x'. The following induces an error, until -std1 is added to get + as 'x'. The following induces an error, until -std is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something - that's true only with -std1. */ + that's true only with -std. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; @@ -2177,205 +3195,37 @@ return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; return 0; } _ACEOF -# Don't try gcc -ansi; that turns off useful extensions and -# breaks some systems' header files. -# AIX -qlanglvl=ansi -# Ultrix and OSF/1 -std1 -# HP-UX 10.20 and later -Ae -# HP-UX older versions -Aa -D_HPUX_SOURCE -# SVR4 -Xc -D__EXTENSIONS__ -for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" - rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_prog_cc_stdc=$ac_arg -break -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_c89=$ac_arg fi -rm -f conftest.err conftest.$ac_objext +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break done -rm -f conftest.$ac_ext conftest.$ac_objext +rm -f conftest.$ac_ext CC=$ac_save_CC fi - -case "x$ac_cv_prog_cc_stdc" in - x|xno) - echo "$as_me:$LINENO: result: none needed" >&5 -echo "${ECHO_T}none needed" >&6 ;; +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; + xno) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; *) - echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5 -echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6 - CC="$CC $ac_cv_prog_cc_stdc" ;; + CC="$CC $ac_cv_prog_cc_c89" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 +$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; esac - -# Some people use a C++ compiler to compile C. Since we use `exit', -# in C++ we need to declare it. In case someone uses the same compiler -# for both compiling C and C++ we need to have the C++ compiler decide -# the declaration of exit, since it's the most demanding environment. -cat >conftest.$ac_ext <<_ACEOF -#ifndef __cplusplus - choke me -#endif -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - for ac_declaration in \ - '' \ - 'extern "C" void std::exit (int) throw (); using std::exit;' \ - 'extern "C" void std::exit (int); using std::exit;' \ - 'extern "C" void exit (int) throw ();' \ - 'extern "C" void exit (int);' \ - 'void exit (int);' -do - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_declaration -#include -int -main () -{ -exit (42); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - : -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -continue -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_declaration -int -main () -{ -exit (42); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - break -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 +if test "x$ac_cv_prog_cc_c89" != xno; then : fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -done -rm -f conftest* -if test -n "$ac_declaration"; then - echo '#ifdef __cplusplus' >>confdefs.h - echo $ac_declaration >>confdefs.h - echo '#endif' >>confdefs.h -fi - -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' @@ -2383,18 +3233,14 @@ ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $ ac_compiler_gnu=$ac_cv_c_compiler_gnu -echo "$as_me:$LINENO: checking for inline" >&5 -echo $ECHO_N "checking for inline... $ECHO_C" >&6 -if test "${ac_cv_c_inline+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline" >&5 +$as_echo_n "checking for inline... " >&6; } +if ${ac_cv_c_inline+:} false; then : + $as_echo_n "(cached) " >&6 else ac_cv_c_inline=no for ac_kw in inline __inline__ __inline; do - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifndef __cplusplus typedef int foo_t; @@ -2403,41 +3249,16 @@ $ac_kw foo_t foo () {return 0; } #endif _ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_c_inline=$ac_kw; break -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_c_inline=$ac_kw fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + test "$ac_cv_c_inline" != no && break done fi -echo "$as_me:$LINENO: result: $ac_cv_c_inline" >&5 -echo "${ECHO_T}$ac_cv_c_inline" >&6 - +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_inline" >&5 +$as_echo "$ac_cv_c_inline" >&6; } case $ac_cv_c_inline in inline | yes) ;; @@ -2469,15 +3290,15 @@ ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu -echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 -echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 +$as_echo_n "checking how to run the C preprocessor... " >&6; } # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then - if test "${ac_cv_prog_CPP+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + if ${ac_cv_prog_CPP+:} false; then : + $as_echo_n "(cached) " >&6 else # Double quotes because CPP needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" @@ -2491,11 +3312,7 @@ do # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include @@ -2504,78 +3321,34 @@ cat >>conftest.$ac_ext <<_ACEOF #endif Syntax error _ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - : -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 +if ac_fn_c_try_cpp "$LINENO"; then : +else # Broken: fails on valid input. continue fi -rm -f conftest.err conftest.$ac_ext +rm -f conftest.err conftest.i conftest.$ac_ext - # OK, works on sane cases. Now check whether non-existent headers + # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then +if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - # Passes both tests. ac_preproc_ok=: break fi -rm -f conftest.err conftest.$ac_ext +rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.err conftest.$ac_ext -if $ac_preproc_ok; then +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : break fi @@ -2587,8 +3360,8 @@ fi else ac_cv_prog_CPP=$CPP fi -echo "$as_me:$LINENO: result: $CPP" >&5 -echo "${ECHO_T}$CPP" >&6 +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 +$as_echo "$CPP" >&6; } ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do @@ -2598,11 +3371,7 @@ do # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include @@ -2611,85 +3380,40 @@ cat >>conftest.$ac_ext <<_ACEOF #endif Syntax error _ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - : -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 +if ac_fn_c_try_cpp "$LINENO"; then : +else # Broken: fails on valid input. continue fi -rm -f conftest.err conftest.$ac_ext +rm -f conftest.err conftest.i conftest.$ac_ext - # OK, works on sane cases. Now check whether non-existent headers + # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then +if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - # Passes both tests. ac_preproc_ok=: break fi -rm -f conftest.err conftest.$ac_ext +rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.err conftest.$ac_ext -if $ac_preproc_ok; then - : +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + else - { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check -See \`config.log' for more details." >&5 -echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check -See \`config.log' for more details." >&2;} - { (exit 1); exit 1; }; } + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details" "$LINENO" 5; } fi ac_ext=c @@ -2699,31 +3423,142 @@ ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $ ac_compiler_gnu=$ac_cv_c_compiler_gnu -echo "$as_me:$LINENO: checking for egrep" >&5 -echo $ECHO_N "checking for egrep... $ECHO_C" >&6 -if test "${ac_cv_prog_egrep+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 +$as_echo_n "checking for grep that handles long lines and -e... " >&6; } +if ${ac_cv_path_GREP+:} false; then : + $as_echo_n "(cached) " >&6 else - if echo a | (grep -E '(a|b)') >/dev/null 2>&1 - then ac_cv_prog_egrep='grep -E' - else ac_cv_prog_egrep='egrep' + if test -z "$GREP"; then + ac_path_GREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in grep ggrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_GREP" || continue +# Check for GNU ac_path_GREP and select it if it is found. + # Check for GNU $ac_path_GREP +case `"$ac_path_GREP" --version 2>&1` in +*GNU*) + ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'GREP' >> "conftest.nl" + "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_GREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_GREP="$ac_path_GREP" + ac_path_GREP_max=$ac_count fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_GREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_GREP"; then + as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_GREP=$GREP +fi + fi -echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5 -echo "${ECHO_T}$ac_cv_prog_egrep" >&6 - EGREP=$ac_cv_prog_egrep +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 +$as_echo "$ac_cv_path_GREP" >&6; } + GREP="$ac_cv_path_GREP" -echo "$as_me:$LINENO: checking for ANSI C header files" >&5 -echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6 -if test "${ac_cv_header_stdc+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 +$as_echo_n "checking for egrep... " >&6; } +if ${ac_cv_path_EGREP+:} false; then : + $as_echo_n "(cached) " >&6 else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF + if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 + then ac_cv_path_EGREP="$GREP -E" + else + if test -z "$EGREP"; then + ac_path_EGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in egrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_EGREP" || continue +# Check for GNU ac_path_EGREP and select it if it is found. + # Check for GNU $ac_path_EGREP +case `"$ac_path_EGREP" --version 2>&1` in +*GNU*) + ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'EGREP' >> "conftest.nl" + "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_EGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_EGREP="$ac_path_EGREP" + ac_path_EGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_EGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_EGREP"; then + as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_EGREP=$EGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 +$as_echo "$ac_cv_path_EGREP" >&6; } + EGREP="$ac_cv_path_EGREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 +$as_echo_n "checking for ANSI C header files... " >&6; } +if ${ac_cv_header_stdc+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include @@ -2738,51 +3573,23 @@ main () return 0; } _ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then +if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_stdc=yes else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_header_stdc=no + ac_cv_header_stdc=no fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "memchr" >/dev/null 2>&1; then - : + $EGREP "memchr" >/dev/null 2>&1; then : + else ac_cv_header_stdc=no fi @@ -2792,18 +3599,14 @@ fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "free" >/dev/null 2>&1; then - : + $EGREP "free" >/dev/null 2>&1; then : + else ac_cv_header_stdc=no fi @@ -2813,16 +3616,13 @@ fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. - if test "$cross_compiling" = yes; then + if test "$cross_compiling" = yes; then : : else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include +#include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) @@ -2842,109 +3642,39 @@ main () for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) - exit(2); - exit (0); + return 2; + return 0; } _ACEOF -rm -f conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - : -else - echo "$as_me: program exited with status $ac_status" >&5 -echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 +if ac_fn_c_try_run "$LINENO"; then : -( exit $ac_status ) -ac_cv_header_stdc=no +else + ac_cv_header_stdc=no fi -rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext fi + fi fi -echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 -echo "${ECHO_T}$ac_cv_header_stdc" >&6 +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 +$as_echo "$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then -cat >>confdefs.h <<\_ACEOF -#define STDC_HEADERS 1 -_ACEOF +$as_echo "#define STDC_HEADERS 1" >>confdefs.h fi # On IRIX 5.3, sys/types and inttypes.h are conflicting. - - - - - - - - - for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ inttypes.h stdint.h unistd.h -do -as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` -echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default - -#include <$ac_header> -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - eval "$as_ac_Header=yes" -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -eval "$as_ac_Header=no" -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 -if test `eval echo '${'$as_ac_Header'}'` = yes; then +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default +" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi @@ -2953,17 +3683,13 @@ done - echo "$as_me:$LINENO: checking dirent.h" >&5 -echo $ECHO_N "checking dirent.h... $ECHO_C" >&6 -if test "${tcl_cv_dirent_h+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking dirent.h" >&5 +$as_echo_n "checking dirent.h... " >&6; } +if ${tcl_cv_dirent_h+:} false; then : + $as_echo_n "(cached) " >&6 else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include @@ -2993,1817 +3719,489 @@ closedir(d); return 0; } _ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then +if ac_fn_c_try_link "$LINENO"; then : tcl_cv_dirent_h=yes else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -tcl_cv_dirent_h=no + tcl_cv_dirent_h=no fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext fi -echo "$as_me:$LINENO: result: $tcl_cv_dirent_h" >&5 -echo "${ECHO_T}$tcl_cv_dirent_h" >&6 +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_dirent_h" >&5 +$as_echo "$tcl_cv_dirent_h" >&6; } if test $tcl_cv_dirent_h = no; then -cat >>confdefs.h <<\_ACEOF -#define NO_DIRENT_H 1 -_ACEOF +$as_echo "#define NO_DIRENT_H 1" >>confdefs.h fi - if test "${ac_cv_header_float_h+set}" = set; then - echo "$as_me:$LINENO: checking for float.h" >&5 -echo $ECHO_N "checking for float.h... $ECHO_C" >&6 -if test "${ac_cv_header_float_h+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -fi -echo "$as_me:$LINENO: result: $ac_cv_header_float_h" >&5 -echo "${ECHO_T}$ac_cv_header_float_h" >&6 -else - # Is the header compilable? -echo "$as_me:$LINENO: checking float.h usability" >&5 -echo $ECHO_N "checking float.h usability... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -#include -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_header_compiler=yes + ac_fn_c_check_header_mongrel "$LINENO" "float.h" "ac_cv_header_float_h" "$ac_includes_default" +if test "x$ac_cv_header_float_h" = xyes; then : + else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 -ac_header_compiler=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -echo "${ECHO_T}$ac_header_compiler" >&6 +$as_echo "#define NO_FLOAT_H 1" >>confdefs.h -# Is the header present? -echo "$as_me:$LINENO: checking float.h presence" >&5 -echo $ECHO_N "checking float.h presence... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -_ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes fi -if test -z "$ac_cpp_err"; then - ac_header_preproc=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - ac_header_preproc=no -fi -rm -f conftest.err conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -echo "${ECHO_T}$ac_header_preproc" >&6 -# So? What about this header? -case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in - yes:no: ) - { echo "$as_me:$LINENO: WARNING: float.h: accepted by the compiler, rejected by the preprocessor!" >&5 -echo "$as_me: WARNING: float.h: accepted by the compiler, rejected by the preprocessor!" >&2;} - { echo "$as_me:$LINENO: WARNING: float.h: proceeding with the compiler's result" >&5 -echo "$as_me: WARNING: float.h: proceeding with the compiler's result" >&2;} - ac_header_preproc=yes - ;; - no:yes:* ) - { echo "$as_me:$LINENO: WARNING: float.h: present but cannot be compiled" >&5 -echo "$as_me: WARNING: float.h: present but cannot be compiled" >&2;} - { echo "$as_me:$LINENO: WARNING: float.h: check for missing prerequisite headers?" >&5 -echo "$as_me: WARNING: float.h: check for missing prerequisite headers?" >&2;} - { echo "$as_me:$LINENO: WARNING: float.h: see the Autoconf documentation" >&5 -echo "$as_me: WARNING: float.h: see the Autoconf documentation" >&2;} - { echo "$as_me:$LINENO: WARNING: float.h: section \"Present But Cannot Be Compiled\"" >&5 -echo "$as_me: WARNING: float.h: section \"Present But Cannot Be Compiled\"" >&2;} - { echo "$as_me:$LINENO: WARNING: float.h: proceeding with the preprocessor's result" >&5 -echo "$as_me: WARNING: float.h: proceeding with the preprocessor's result" >&2;} - { echo "$as_me:$LINENO: WARNING: float.h: in the future, the compiler will take precedence" >&5 -echo "$as_me: WARNING: float.h: in the future, the compiler will take precedence" >&2;} - ( - cat <<\_ASBOX -## ------------------------------ ## -## Report this to the tcl lists. ## -## ------------------------------ ## -_ASBOX - ) | - sed "s/^/$as_me: WARNING: /" >&2 - ;; -esac -echo "$as_me:$LINENO: checking for float.h" >&5 -echo $ECHO_N "checking for float.h... $ECHO_C" >&6 -if test "${ac_cv_header_float_h+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_cv_header_float_h=$ac_header_preproc -fi -echo "$as_me:$LINENO: result: $ac_cv_header_float_h" >&5 -echo "${ECHO_T}$ac_cv_header_float_h" >&6 + ac_fn_c_check_header_mongrel "$LINENO" "values.h" "ac_cv_header_values_h" "$ac_includes_default" +if test "x$ac_cv_header_values_h" = xyes; then : -fi -if test $ac_cv_header_float_h = yes; then - : else -cat >>confdefs.h <<\_ACEOF -#define NO_FLOAT_H 1 -_ACEOF +$as_echo "#define NO_VALUES_H 1" >>confdefs.h fi - if test "${ac_cv_header_values_h+set}" = set; then - echo "$as_me:$LINENO: checking for values.h" >&5 -echo $ECHO_N "checking for values.h... $ECHO_C" >&6 -if test "${ac_cv_header_values_h+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -fi -echo "$as_me:$LINENO: result: $ac_cv_header_values_h" >&5 -echo "${ECHO_T}$ac_cv_header_values_h" >&6 -else - # Is the header compilable? -echo "$as_me:$LINENO: checking values.h usability" >&5 -echo $ECHO_N "checking values.h usability... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -#include -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_header_compiler=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 + ac_fn_c_check_header_mongrel "$LINENO" "limits.h" "ac_cv_header_limits_h" "$ac_includes_default" +if test "x$ac_cv_header_limits_h" = xyes; then : -ac_header_compiler=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -echo "${ECHO_T}$ac_header_compiler" >&6 +$as_echo "#define HAVE_LIMITS_H 1" >>confdefs.h -# Is the header present? -echo "$as_me:$LINENO: checking values.h presence" >&5 -echo $ECHO_N "checking values.h presence... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -_ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - ac_header_preproc=yes else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - ac_header_preproc=no +$as_echo "#define NO_LIMITS_H 1" >>confdefs.h + fi -rm -f conftest.err conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -echo "${ECHO_T}$ac_header_preproc" >&6 -# So? What about this header? -case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in - yes:no: ) - { echo "$as_me:$LINENO: WARNING: values.h: accepted by the compiler, rejected by the preprocessor!" >&5 -echo "$as_me: WARNING: values.h: accepted by the compiler, rejected by the preprocessor!" >&2;} - { echo "$as_me:$LINENO: WARNING: values.h: proceeding with the compiler's result" >&5 -echo "$as_me: WARNING: values.h: proceeding with the compiler's result" >&2;} - ac_header_preproc=yes - ;; - no:yes:* ) - { echo "$as_me:$LINENO: WARNING: values.h: present but cannot be compiled" >&5 -echo "$as_me: WARNING: values.h: present but cannot be compiled" >&2;} - { echo "$as_me:$LINENO: WARNING: values.h: check for missing prerequisite headers?" >&5 -echo "$as_me: WARNING: values.h: check for missing prerequisite headers?" >&2;} - { echo "$as_me:$LINENO: WARNING: values.h: see the Autoconf documentation" >&5 -echo "$as_me: WARNING: values.h: see the Autoconf documentation" >&2;} - { echo "$as_me:$LINENO: WARNING: values.h: section \"Present But Cannot Be Compiled\"" >&5 -echo "$as_me: WARNING: values.h: section \"Present But Cannot Be Compiled\"" >&2;} - { echo "$as_me:$LINENO: WARNING: values.h: proceeding with the preprocessor's result" >&5 -echo "$as_me: WARNING: values.h: proceeding with the preprocessor's result" >&2;} - { echo "$as_me:$LINENO: WARNING: values.h: in the future, the compiler will take precedence" >&5 -echo "$as_me: WARNING: values.h: in the future, the compiler will take precedence" >&2;} - ( - cat <<\_ASBOX -## ------------------------------ ## -## Report this to the tcl lists. ## -## ------------------------------ ## -_ASBOX - ) | - sed "s/^/$as_me: WARNING: /" >&2 - ;; -esac -echo "$as_me:$LINENO: checking for values.h" >&5 -echo $ECHO_N "checking for values.h... $ECHO_C" >&6 -if test "${ac_cv_header_values_h+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + + ac_fn_c_check_header_mongrel "$LINENO" "stdlib.h" "ac_cv_header_stdlib_h" "$ac_includes_default" +if test "x$ac_cv_header_stdlib_h" = xyes; then : + tcl_ok=1 else - ac_cv_header_values_h=$ac_header_preproc + tcl_ok=0 fi -echo "$as_me:$LINENO: result: $ac_cv_header_values_h" >&5 -echo "${ECHO_T}$ac_cv_header_values_h" >&6 -fi -if test $ac_cv_header_values_h = yes; then - : -else -cat >>confdefs.h <<\_ACEOF -#define NO_VALUES_H 1 + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + _ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "strtol" >/dev/null 2>&1; then : +else + tcl_ok=0 fi +rm -f conftest* - - if test "${ac_cv_header_limits_h+set}" = set; then - echo "$as_me:$LINENO: checking for limits.h" >&5 -echo $ECHO_N "checking for limits.h... $ECHO_C" >&6 -if test "${ac_cv_header_limits_h+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -fi -echo "$as_me:$LINENO: result: $ac_cv_header_limits_h" >&5 -echo "${ECHO_T}$ac_cv_header_limits_h" >&6 -else - # Is the header compilable? -echo "$as_me:$LINENO: checking limits.h usability" >&5 -echo $ECHO_N "checking limits.h usability... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -$ac_includes_default -#include +#include + _ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_header_compiler=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "strtoul" >/dev/null 2>&1; then : -ac_header_compiler=no +else + tcl_ok=0 fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -echo "${ECHO_T}$ac_header_compiler" >&6 +rm -f conftest* -# Is the header present? -echo "$as_me:$LINENO: checking limits.h presence" >&5 -echo $ECHO_N "checking limits.h presence... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#include +#include + _ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "strtod" >/dev/null 2>&1; then : + else - ac_cpp_err=yes + tcl_ok=0 fi -if test -z "$ac_cpp_err"; then - ac_header_preproc=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 +rm -f conftest* - ac_header_preproc=no -fi -rm -f conftest.err conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -echo "${ECHO_T}$ac_header_preproc" >&6 + if test $tcl_ok = 0; then -# So? What about this header? -case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in - yes:no: ) - { echo "$as_me:$LINENO: WARNING: limits.h: accepted by the compiler, rejected by the preprocessor!" >&5 -echo "$as_me: WARNING: limits.h: accepted by the compiler, rejected by the preprocessor!" >&2;} - { echo "$as_me:$LINENO: WARNING: limits.h: proceeding with the compiler's result" >&5 -echo "$as_me: WARNING: limits.h: proceeding with the compiler's result" >&2;} - ac_header_preproc=yes - ;; - no:yes:* ) - { echo "$as_me:$LINENO: WARNING: limits.h: present but cannot be compiled" >&5 -echo "$as_me: WARNING: limits.h: present but cannot be compiled" >&2;} - { echo "$as_me:$LINENO: WARNING: limits.h: check for missing prerequisite headers?" >&5 -echo "$as_me: WARNING: limits.h: check for missing prerequisite headers?" >&2;} - { echo "$as_me:$LINENO: WARNING: limits.h: see the Autoconf documentation" >&5 -echo "$as_me: WARNING: limits.h: see the Autoconf documentation" >&2;} - { echo "$as_me:$LINENO: WARNING: limits.h: section \"Present But Cannot Be Compiled\"" >&5 -echo "$as_me: WARNING: limits.h: section \"Present But Cannot Be Compiled\"" >&2;} - { echo "$as_me:$LINENO: WARNING: limits.h: proceeding with the preprocessor's result" >&5 -echo "$as_me: WARNING: limits.h: proceeding with the preprocessor's result" >&2;} - { echo "$as_me:$LINENO: WARNING: limits.h: in the future, the compiler will take precedence" >&5 -echo "$as_me: WARNING: limits.h: in the future, the compiler will take precedence" >&2;} - ( - cat <<\_ASBOX -## ------------------------------ ## -## Report this to the tcl lists. ## -## ------------------------------ ## -_ASBOX - ) | - sed "s/^/$as_me: WARNING: /" >&2 - ;; -esac -echo "$as_me:$LINENO: checking for limits.h" >&5 -echo $ECHO_N "checking for limits.h... $ECHO_C" >&6 -if test "${ac_cv_header_limits_h+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 +$as_echo "#define NO_STDLIB_H 1" >>confdefs.h + + fi + ac_fn_c_check_header_mongrel "$LINENO" "string.h" "ac_cv_header_string_h" "$ac_includes_default" +if test "x$ac_cv_header_string_h" = xyes; then : + tcl_ok=1 else - ac_cv_header_limits_h=$ac_header_preproc + tcl_ok=0 fi -echo "$as_me:$LINENO: result: $ac_cv_header_limits_h" >&5 -echo "${ECHO_T}$ac_cv_header_limits_h" >&6 -fi -if test $ac_cv_header_limits_h = yes; then -cat >>confdefs.h <<\_ACEOF -#define HAVE_LIMITS_H 1 + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + _ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "strstr" >/dev/null 2>&1; then : else + tcl_ok=0 +fi +rm -f conftest* + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include -cat >>confdefs.h <<\_ACEOF -#define NO_LIMITS_H 1 _ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "strerror" >/dev/null 2>&1; then : +else + tcl_ok=0 fi +rm -f conftest* - if test "${ac_cv_header_stdlib_h+set}" = set; then - echo "$as_me:$LINENO: checking for stdlib.h" >&5 -echo $ECHO_N "checking for stdlib.h... $ECHO_C" >&6 -if test "${ac_cv_header_stdlib_h+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -fi -echo "$as_me:$LINENO: result: $ac_cv_header_stdlib_h" >&5 -echo "${ECHO_T}$ac_cv_header_stdlib_h" >&6 -else - # Is the header compilable? -echo "$as_me:$LINENO: checking stdlib.h usability" >&5 -echo $ECHO_N "checking stdlib.h usability... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -#include -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_header_compiler=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 + # See also memmove check below for a place where NO_STRING_H can be + # set and why. -ac_header_compiler=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -echo "${ECHO_T}$ac_header_compiler" >&6 + if test $tcl_ok = 0; then -# Is the header present? -echo "$as_me:$LINENO: checking stdlib.h presence" >&5 -echo $ECHO_N "checking stdlib.h presence... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -_ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - ac_header_preproc=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 +$as_echo "#define NO_STRING_H 1" >>confdefs.h - ac_header_preproc=no -fi -rm -f conftest.err conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -echo "${ECHO_T}$ac_header_preproc" >&6 + fi -# So? What about this header? -case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in - yes:no: ) - { echo "$as_me:$LINENO: WARNING: stdlib.h: accepted by the compiler, rejected by the preprocessor!" >&5 -echo "$as_me: WARNING: stdlib.h: accepted by the compiler, rejected by the preprocessor!" >&2;} - { echo "$as_me:$LINENO: WARNING: stdlib.h: proceeding with the compiler's result" >&5 -echo "$as_me: WARNING: stdlib.h: proceeding with the compiler's result" >&2;} - ac_header_preproc=yes - ;; - no:yes:* ) - { echo "$as_me:$LINENO: WARNING: stdlib.h: present but cannot be compiled" >&5 -echo "$as_me: WARNING: stdlib.h: present but cannot be compiled" >&2;} - { echo "$as_me:$LINENO: WARNING: stdlib.h: check for missing prerequisite headers?" >&5 -echo "$as_me: WARNING: stdlib.h: check for missing prerequisite headers?" >&2;} - { echo "$as_me:$LINENO: WARNING: stdlib.h: see the Autoconf documentation" >&5 -echo "$as_me: WARNING: stdlib.h: see the Autoconf documentation" >&2;} - { echo "$as_me:$LINENO: WARNING: stdlib.h: section \"Present But Cannot Be Compiled\"" >&5 -echo "$as_me: WARNING: stdlib.h: section \"Present But Cannot Be Compiled\"" >&2;} - { echo "$as_me:$LINENO: WARNING: stdlib.h: proceeding with the preprocessor's result" >&5 -echo "$as_me: WARNING: stdlib.h: proceeding with the preprocessor's result" >&2;} - { echo "$as_me:$LINENO: WARNING: stdlib.h: in the future, the compiler will take precedence" >&5 -echo "$as_me: WARNING: stdlib.h: in the future, the compiler will take precedence" >&2;} - ( - cat <<\_ASBOX -## ------------------------------ ## -## Report this to the tcl lists. ## -## ------------------------------ ## -_ASBOX - ) | - sed "s/^/$as_me: WARNING: /" >&2 - ;; -esac -echo "$as_me:$LINENO: checking for stdlib.h" >&5 -echo $ECHO_N "checking for stdlib.h... $ECHO_C" >&6 -if test "${ac_cv_header_stdlib_h+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_cv_header_stdlib_h=$ac_header_preproc -fi -echo "$as_me:$LINENO: result: $ac_cv_header_stdlib_h" >&5 -echo "${ECHO_T}$ac_cv_header_stdlib_h" >&6 + ac_fn_c_check_header_mongrel "$LINENO" "sys/wait.h" "ac_cv_header_sys_wait_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_wait_h" = xyes; then : -fi -if test $ac_cv_header_stdlib_h = yes; then - tcl_ok=1 else - tcl_ok=0 + +$as_echo "#define NO_SYS_WAIT_H 1" >>confdefs.h + fi - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include + ac_fn_c_check_header_mongrel "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default" +if test "x$ac_cv_header_dlfcn_h" = xyes; then : -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "strtol" >/dev/null 2>&1; then - : else - tcl_ok=0 -fi -rm -f conftest* - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include +$as_echo "#define NO_DLFCN_H 1" >>confdefs.h -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "strtoul" >/dev/null 2>&1; then - : -else - tcl_ok=0 fi -rm -f conftest* - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include + + # OS/390 lacks sys/param.h (and doesn't need it, by chance). + for ac_header in sys/param.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "sys/param.h" "ac_cv_header_sys_param_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_param_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_SYS_PARAM_H 1 _ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "strtod" >/dev/null 2>&1; then - : -else - tcl_ok=0 + fi -rm -f conftest* - if test $tcl_ok = 0; then +done -cat >>confdefs.h <<\_ACEOF -#define NO_STDLIB_H 1 -_ACEOF - fi - if test "${ac_cv_header_string_h+set}" = set; then - echo "$as_me:$LINENO: checking for string.h" >&5 -echo $ECHO_N "checking for string.h... $ECHO_C" >&6 -if test "${ac_cv_header_string_h+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -fi -echo "$as_me:$LINENO: result: $ac_cv_header_string_h" >&5 -echo "${ECHO_T}$ac_cv_header_string_h" >&6 + +#-------------------------------------------------------------------- +# Determines the correct executable file extension (.exe) +#-------------------------------------------------------------------- + + + +#------------------------------------------------------------------------ +# If we're using GCC, see if the compiler understands -pipe. If so, use it. +# It makes compiling go faster. (This is only a performance feature.) +#------------------------------------------------------------------------ + +if test -z "$no_pipe" && test -n "$GCC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if the compiler understands -pipe" >&5 +$as_echo_n "checking if the compiler understands -pipe... " >&6; } +if ${tcl_cv_cc_pipe+:} false; then : + $as_echo_n "(cached) " >&6 else - # Is the header compilable? -echo "$as_me:$LINENO: checking string.h usability" >&5 -echo $ECHO_N "checking string.h usability... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF + + hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -pipe" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -$ac_includes_default -#include -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_header_compiler=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 -ac_header_compiler=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -echo "${ECHO_T}$ac_header_compiler" >&6 +int +main () +{ -# Is the header present? -echo "$as_me:$LINENO: checking string.h presence" >&5 -echo $ECHO_N "checking string.h presence... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include + ; + return 0; +} _ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi +if ac_fn_c_try_compile "$LINENO"; then : + tcl_cv_cc_pipe=yes else - ac_cpp_err=yes + tcl_cv_cc_pipe=no fi -if test -z "$ac_cpp_err"; then - ac_header_preproc=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_header_preproc=no +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + CFLAGS=$hold_cflags fi -rm -f conftest.err conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -echo "${ECHO_T}$ac_header_preproc" >&6 - -# So? What about this header? -case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in - yes:no: ) - { echo "$as_me:$LINENO: WARNING: string.h: accepted by the compiler, rejected by the preprocessor!" >&5 -echo "$as_me: WARNING: string.h: accepted by the compiler, rejected by the preprocessor!" >&2;} - { echo "$as_me:$LINENO: WARNING: string.h: proceeding with the compiler's result" >&5 -echo "$as_me: WARNING: string.h: proceeding with the compiler's result" >&2;} - ac_header_preproc=yes - ;; - no:yes:* ) - { echo "$as_me:$LINENO: WARNING: string.h: present but cannot be compiled" >&5 -echo "$as_me: WARNING: string.h: present but cannot be compiled" >&2;} - { echo "$as_me:$LINENO: WARNING: string.h: check for missing prerequisite headers?" >&5 -echo "$as_me: WARNING: string.h: check for missing prerequisite headers?" >&2;} - { echo "$as_me:$LINENO: WARNING: string.h: see the Autoconf documentation" >&5 -echo "$as_me: WARNING: string.h: see the Autoconf documentation" >&2;} - { echo "$as_me:$LINENO: WARNING: string.h: section \"Present But Cannot Be Compiled\"" >&5 -echo "$as_me: WARNING: string.h: section \"Present But Cannot Be Compiled\"" >&2;} - { echo "$as_me:$LINENO: WARNING: string.h: proceeding with the preprocessor's result" >&5 -echo "$as_me: WARNING: string.h: proceeding with the preprocessor's result" >&2;} - { echo "$as_me:$LINENO: WARNING: string.h: in the future, the compiler will take precedence" >&5 -echo "$as_me: WARNING: string.h: in the future, the compiler will take precedence" >&2;} - ( - cat <<\_ASBOX -## ------------------------------ ## -## Report this to the tcl lists. ## -## ------------------------------ ## -_ASBOX - ) | - sed "s/^/$as_me: WARNING: /" >&2 - ;; -esac -echo "$as_me:$LINENO: checking for string.h" >&5 -echo $ECHO_N "checking for string.h... $ECHO_C" >&6 -if test "${ac_cv_header_string_h+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_cv_header_string_h=$ac_header_preproc +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_cc_pipe" >&5 +$as_echo "$tcl_cv_cc_pipe" >&6; } + if test $tcl_cv_cc_pipe = yes; then + CFLAGS="$CFLAGS -pipe" + fi fi -echo "$as_me:$LINENO: result: $ac_cv_header_string_h" >&5 -echo "${ECHO_T}$ac_cv_header_string_h" >&6 -fi -if test $ac_cv_header_string_h = yes; then - tcl_ok=1 +#------------------------------------------------------------------------ +# Threads support +#------------------------------------------------------------------------ + + + # Check whether --enable-threads was given. +if test "${enable_threads+set}" = set; then : + enableval=$enable_threads; tcl_ok=$enableval else - tcl_ok=0 + tcl_ok=yes fi - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include + if test "${TCL_THREADS}" = 1; then + tcl_threaded_core=1; + fi -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "strstr" >/dev/null 2>&1; then - : -else - tcl_ok=0 -fi -rm -f conftest* + if test "$tcl_ok" = "yes" -o "${TCL_THREADS}" = 1; then + TCL_THREADS=1 + # USE_THREAD_ALLOC tells us to try the special thread-based + # allocator that significantly reduces lock contention - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include +$as_echo "#define USE_THREAD_ALLOC 1" >>confdefs.h -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "strerror" >/dev/null 2>&1; then - : -else - tcl_ok=0 -fi -rm -f conftest* +$as_echo "#define _REENTRANT 1" >>confdefs.h - # See also memmove check below for a place where NO_STRING_H can be - # set and why. + if test "`uname -s`" = "SunOS" ; then - if test $tcl_ok = 0; then +$as_echo "#define _POSIX_PTHREAD_SEMANTICS 1" >>confdefs.h -cat >>confdefs.h <<\_ACEOF -#define NO_STRING_H 1 -_ACEOF + fi - fi +$as_echo "#define _THREAD_SAFE 1" >>confdefs.h - if test "${ac_cv_header_sys_wait_h+set}" = set; then - echo "$as_me:$LINENO: checking for sys/wait.h" >&5 -echo $ECHO_N "checking for sys/wait.h... $ECHO_C" >&6 -if test "${ac_cv_header_sys_wait_h+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -fi -echo "$as_me:$LINENO: result: $ac_cv_header_sys_wait_h" >&5 -echo "${ECHO_T}$ac_cv_header_sys_wait_h" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_mutex_init in -lpthread" >&5 +$as_echo_n "checking for pthread_mutex_init in -lpthread... " >&6; } +if ${ac_cv_lib_pthread_pthread_mutex_init+:} false; then : + $as_echo_n "(cached) " >&6 else - # Is the header compilable? -echo "$as_me:$LINENO: checking sys/wait.h usability" >&5 -echo $ECHO_N "checking sys/wait.h usability... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF + ac_check_lib_save_LIBS=$LIBS +LIBS="-lpthread $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -$ac_includes_default -#include -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_header_compiler=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 -ac_header_compiler=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -echo "${ECHO_T}$ac_header_compiler" >&6 - -# Is the header present? -echo "$as_me:$LINENO: checking sys/wait.h presence" >&5 -echo $ECHO_N "checking sys/wait.h presence... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char pthread_mutex_init (); +int +main () +{ +return pthread_mutex_init (); + ; + return 0; +} _ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_pthread_pthread_mutex_init=yes else - ac_cpp_err=yes + ac_cv_lib_pthread_pthread_mutex_init=no fi -if test -z "$ac_cpp_err"; then - ac_header_preproc=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_header_preproc=no +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS fi -rm -f conftest.err conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -echo "${ECHO_T}$ac_header_preproc" >&6 - -# So? What about this header? -case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in - yes:no: ) - { echo "$as_me:$LINENO: WARNING: sys/wait.h: accepted by the compiler, rejected by the preprocessor!" >&5 -echo "$as_me: WARNING: sys/wait.h: accepted by the compiler, rejected by the preprocessor!" >&2;} - { echo "$as_me:$LINENO: WARNING: sys/wait.h: proceeding with the compiler's result" >&5 -echo "$as_me: WARNING: sys/wait.h: proceeding with the compiler's result" >&2;} - ac_header_preproc=yes - ;; - no:yes:* ) - { echo "$as_me:$LINENO: WARNING: sys/wait.h: present but cannot be compiled" >&5 -echo "$as_me: WARNING: sys/wait.h: present but cannot be compiled" >&2;} - { echo "$as_me:$LINENO: WARNING: sys/wait.h: check for missing prerequisite headers?" >&5 -echo "$as_me: WARNING: sys/wait.h: check for missing prerequisite headers?" >&2;} - { echo "$as_me:$LINENO: WARNING: sys/wait.h: see the Autoconf documentation" >&5 -echo "$as_me: WARNING: sys/wait.h: see the Autoconf documentation" >&2;} - { echo "$as_me:$LINENO: WARNING: sys/wait.h: section \"Present But Cannot Be Compiled\"" >&5 -echo "$as_me: WARNING: sys/wait.h: section \"Present But Cannot Be Compiled\"" >&2;} - { echo "$as_me:$LINENO: WARNING: sys/wait.h: proceeding with the preprocessor's result" >&5 -echo "$as_me: WARNING: sys/wait.h: proceeding with the preprocessor's result" >&2;} - { echo "$as_me:$LINENO: WARNING: sys/wait.h: in the future, the compiler will take precedence" >&5 -echo "$as_me: WARNING: sys/wait.h: in the future, the compiler will take precedence" >&2;} - ( - cat <<\_ASBOX -## ------------------------------ ## -## Report this to the tcl lists. ## -## ------------------------------ ## -_ASBOX - ) | - sed "s/^/$as_me: WARNING: /" >&2 - ;; -esac -echo "$as_me:$LINENO: checking for sys/wait.h" >&5 -echo $ECHO_N "checking for sys/wait.h... $ECHO_C" >&6 -if test "${ac_cv_header_sys_wait_h+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pthread_pthread_mutex_init" >&5 +$as_echo "$ac_cv_lib_pthread_pthread_mutex_init" >&6; } +if test "x$ac_cv_lib_pthread_pthread_mutex_init" = xyes; then : + tcl_ok=yes else - ac_cv_header_sys_wait_h=$ac_header_preproc + tcl_ok=no fi -echo "$as_me:$LINENO: result: $ac_cv_header_sys_wait_h" >&5 -echo "${ECHO_T}$ac_cv_header_sys_wait_h" >&6 -fi -if test $ac_cv_header_sys_wait_h = yes; then - : + if test "$tcl_ok" = "no"; then + # Check a little harder for __pthread_mutex_init in the same + # library, as some systems hide it there until pthread.h is + # defined. We could alternatively do an AC_TRY_COMPILE with + # pthread.h, but that will work with libpthread really doesn't + # exist, like AIX 4.2. [Bug: 4359] + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for __pthread_mutex_init in -lpthread" >&5 +$as_echo_n "checking for __pthread_mutex_init in -lpthread... " >&6; } +if ${ac_cv_lib_pthread___pthread_mutex_init+:} false; then : + $as_echo_n "(cached) " >&6 else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lpthread $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ -cat >>confdefs.h <<\_ACEOF -#define NO_SYS_WAIT_H 1 +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char __pthread_mutex_init (); +int +main () +{ +return __pthread_mutex_init (); + ; + return 0; +} _ACEOF - -fi - - - if test "${ac_cv_header_dlfcn_h+set}" = set; then - echo "$as_me:$LINENO: checking for dlfcn.h" >&5 -echo $ECHO_N "checking for dlfcn.h... $ECHO_C" >&6 -if test "${ac_cv_header_dlfcn_h+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -fi -echo "$as_me:$LINENO: result: $ac_cv_header_dlfcn_h" >&5 -echo "${ECHO_T}$ac_cv_header_dlfcn_h" >&6 -else - # Is the header compilable? -echo "$as_me:$LINENO: checking dlfcn.h usability" >&5 -echo $ECHO_N "checking dlfcn.h usability... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -#include -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_header_compiler=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_header_compiler=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -echo "${ECHO_T}$ac_header_compiler" >&6 - -# Is the header present? -echo "$as_me:$LINENO: checking dlfcn.h presence" >&5 -echo $ECHO_N "checking dlfcn.h presence... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -_ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - ac_header_preproc=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_header_preproc=no -fi -rm -f conftest.err conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -echo "${ECHO_T}$ac_header_preproc" >&6 - -# So? What about this header? -case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in - yes:no: ) - { echo "$as_me:$LINENO: WARNING: dlfcn.h: accepted by the compiler, rejected by the preprocessor!" >&5 -echo "$as_me: WARNING: dlfcn.h: accepted by the compiler, rejected by the preprocessor!" >&2;} - { echo "$as_me:$LINENO: WARNING: dlfcn.h: proceeding with the compiler's result" >&5 -echo "$as_me: WARNING: dlfcn.h: proceeding with the compiler's result" >&2;} - ac_header_preproc=yes - ;; - no:yes:* ) - { echo "$as_me:$LINENO: WARNING: dlfcn.h: present but cannot be compiled" >&5 -echo "$as_me: WARNING: dlfcn.h: present but cannot be compiled" >&2;} - { echo "$as_me:$LINENO: WARNING: dlfcn.h: check for missing prerequisite headers?" >&5 -echo "$as_me: WARNING: dlfcn.h: check for missing prerequisite headers?" >&2;} - { echo "$as_me:$LINENO: WARNING: dlfcn.h: see the Autoconf documentation" >&5 -echo "$as_me: WARNING: dlfcn.h: see the Autoconf documentation" >&2;} - { echo "$as_me:$LINENO: WARNING: dlfcn.h: section \"Present But Cannot Be Compiled\"" >&5 -echo "$as_me: WARNING: dlfcn.h: section \"Present But Cannot Be Compiled\"" >&2;} - { echo "$as_me:$LINENO: WARNING: dlfcn.h: proceeding with the preprocessor's result" >&5 -echo "$as_me: WARNING: dlfcn.h: proceeding with the preprocessor's result" >&2;} - { echo "$as_me:$LINENO: WARNING: dlfcn.h: in the future, the compiler will take precedence" >&5 -echo "$as_me: WARNING: dlfcn.h: in the future, the compiler will take precedence" >&2;} - ( - cat <<\_ASBOX -## ------------------------------ ## -## Report this to the tcl lists. ## -## ------------------------------ ## -_ASBOX - ) | - sed "s/^/$as_me: WARNING: /" >&2 - ;; -esac -echo "$as_me:$LINENO: checking for dlfcn.h" >&5 -echo $ECHO_N "checking for dlfcn.h... $ECHO_C" >&6 -if test "${ac_cv_header_dlfcn_h+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_cv_header_dlfcn_h=$ac_header_preproc -fi -echo "$as_me:$LINENO: result: $ac_cv_header_dlfcn_h" >&5 -echo "${ECHO_T}$ac_cv_header_dlfcn_h" >&6 - -fi -if test $ac_cv_header_dlfcn_h = yes; then - : -else - -cat >>confdefs.h <<\_ACEOF -#define NO_DLFCN_H 1 -_ACEOF - -fi - - - - # OS/390 lacks sys/param.h (and doesn't need it, by chance). - -for ac_header in sys/param.h -do -as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 -else - # Is the header compilable? -echo "$as_me:$LINENO: checking $ac_header usability" >&5 -echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -#include <$ac_header> -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_header_compiler=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_header_compiler=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -echo "${ECHO_T}$ac_header_compiler" >&6 - -# Is the header present? -echo "$as_me:$LINENO: checking $ac_header presence" >&5 -echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include <$ac_header> -_ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - ac_header_preproc=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_header_preproc=no -fi -rm -f conftest.err conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -echo "${ECHO_T}$ac_header_preproc" >&6 - -# So? What about this header? -case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in - yes:no: ) - { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 -echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 -echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} - ac_header_preproc=yes - ;; - no:yes:* ) - { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 -echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 -echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 -echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 -echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 -echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} - ( - cat <<\_ASBOX -## ------------------------------ ## -## Report this to the tcl lists. ## -## ------------------------------ ## -_ASBOX - ) | - sed "s/^/$as_me: WARNING: /" >&2 - ;; -esac -echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_pthread___pthread_mutex_init=yes else - eval "$as_ac_Header=\$ac_header_preproc" -fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 - + ac_cv_lib_pthread___pthread_mutex_init=no fi -if test `eval echo '${'$as_ac_Header'}'` = yes; then - cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF - +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS fi - -done - - - -#-------------------------------------------------------------------- -# Determines the correct executable file extension (.exe) -#-------------------------------------------------------------------- - - - -#------------------------------------------------------------------------ -# If we're using GCC, see if the compiler understands -pipe. If so, use it. -# It makes compiling go faster. (This is only a performance feature.) -#------------------------------------------------------------------------ - -if test -z "$no_pipe" && test -n "$GCC"; then - echo "$as_me:$LINENO: checking if the compiler understands -pipe" >&5 -echo $ECHO_N "checking if the compiler understands -pipe... $ECHO_C" >&6 -if test "${tcl_cv_cc_pipe+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - - hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -pipe" - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - tcl_cv_cc_pipe=yes +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pthread___pthread_mutex_init" >&5 +$as_echo "$ac_cv_lib_pthread___pthread_mutex_init" >&6; } +if test "x$ac_cv_lib_pthread___pthread_mutex_init" = xyes; then : + tcl_ok=yes else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -tcl_cv_cc_pipe=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext - CFLAGS=$hold_cflags -fi -echo "$as_me:$LINENO: result: $tcl_cv_cc_pipe" >&5 -echo "${ECHO_T}$tcl_cv_cc_pipe" >&6 - if test $tcl_cv_cc_pipe = yes; then - CFLAGS="$CFLAGS -pipe" - fi + tcl_ok=no fi -#------------------------------------------------------------------------ -# Threads support -#------------------------------------------------------------------------ - - - # Check whether --enable-threads or --disable-threads was given. -if test "${enable_threads+set}" = set; then - enableval="$enable_threads" - tcl_ok=$enableval -else - tcl_ok=yes -fi; - - if test "${TCL_THREADS}" = 1; then - tcl_threaded_core=1; - fi - - if test "$tcl_ok" = "yes" -o "${TCL_THREADS}" = 1; then - TCL_THREADS=1 - # USE_THREAD_ALLOC tells us to try the special thread-based - # allocator that significantly reduces lock contention - -cat >>confdefs.h <<\_ACEOF -#define USE_THREAD_ALLOC 1 -_ACEOF - - -cat >>confdefs.h <<\_ACEOF -#define _REENTRANT 1 -_ACEOF - - if test "`uname -s`" = "SunOS" ; then - -cat >>confdefs.h <<\_ACEOF -#define _POSIX_PTHREAD_SEMANTICS 1 -_ACEOF - fi -cat >>confdefs.h <<\_ACEOF -#define _THREAD_SAFE 1 -_ACEOF - - echo "$as_me:$LINENO: checking for pthread_mutex_init in -lpthread" >&5 -echo $ECHO_N "checking for pthread_mutex_init in -lpthread... $ECHO_C" >&6 -if test "${ac_cv_lib_pthread_pthread_mutex_init+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + if test "$tcl_ok" = "yes"; then + # The space is needed + THREADS_LIBS=" -lpthread" + else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_mutex_init in -lpthreads" >&5 +$as_echo_n "checking for pthread_mutex_init in -lpthreads... " >&6; } +if ${ac_cv_lib_pthreads_pthread_mutex_init+:} false; then : + $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS -LIBS="-lpthread $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF +LIBS="-lpthreads $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -/* Override any gcc2 internal prototype to avoid an error. */ +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ char pthread_mutex_init (); int main () { -pthread_mutex_init (); +return pthread_mutex_init (); ; return 0; } _ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_lib_pthread_pthread_mutex_init=yes +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_pthreads_pthread_mutex_init=yes else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_lib_pthread_pthread_mutex_init=no + ac_cv_lib_pthreads_pthread_mutex_init=no fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -echo "$as_me:$LINENO: result: $ac_cv_lib_pthread_pthread_mutex_init" >&5 -echo "${ECHO_T}$ac_cv_lib_pthread_pthread_mutex_init" >&6 -if test $ac_cv_lib_pthread_pthread_mutex_init = yes; then +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pthreads_pthread_mutex_init" >&5 +$as_echo "$ac_cv_lib_pthreads_pthread_mutex_init" >&6; } +if test "x$ac_cv_lib_pthreads_pthread_mutex_init" = xyes; then : tcl_ok=yes else tcl_ok=no fi - if test "$tcl_ok" = "no"; then - # Check a little harder for __pthread_mutex_init in the same - # library, as some systems hide it there until pthread.h is - # defined. We could alternatively do an AC_TRY_COMPILE with - # pthread.h, but that will work with libpthread really doesn't - # exist, like AIX 4.2. [Bug: 4359] - echo "$as_me:$LINENO: checking for __pthread_mutex_init in -lpthread" >&5 -echo $ECHO_N "checking for __pthread_mutex_init in -lpthread... $ECHO_C" >&6 -if test "${ac_cv_lib_pthread___pthread_mutex_init+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + if test "$tcl_ok" = "yes"; then + # The space is needed + THREADS_LIBS=" -lpthreads" + else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_mutex_init in -lc" >&5 +$as_echo_n "checking for pthread_mutex_init in -lc... " >&6; } +if ${ac_cv_lib_c_pthread_mutex_init+:} false; then : + $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS -LIBS="-lpthread $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF +LIBS="-lc $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -/* Override any gcc2 internal prototype to avoid an error. */ +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char __pthread_mutex_init (); +char pthread_mutex_init (); int main () { -__pthread_mutex_init (); +return pthread_mutex_init (); ; return 0; } _ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_lib_pthread___pthread_mutex_init=yes +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_c_pthread_mutex_init=yes else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_lib_pthread___pthread_mutex_init=no + ac_cv_lib_c_pthread_mutex_init=no fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -echo "$as_me:$LINENO: result: $ac_cv_lib_pthread___pthread_mutex_init" >&5 -echo "${ECHO_T}$ac_cv_lib_pthread___pthread_mutex_init" >&6 -if test $ac_cv_lib_pthread___pthread_mutex_init = yes; then +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_c_pthread_mutex_init" >&5 +$as_echo "$ac_cv_lib_c_pthread_mutex_init" >&6; } +if test "x$ac_cv_lib_c_pthread_mutex_init" = xyes; then : tcl_ok=yes else tcl_ok=no fi - fi - - if test "$tcl_ok" = "yes"; then - # The space is needed - THREADS_LIBS=" -lpthread" - else - echo "$as_me:$LINENO: checking for pthread_mutex_init in -lpthreads" >&5 -echo $ECHO_N "checking for pthread_mutex_init in -lpthreads... $ECHO_C" >&6 -if test "${ac_cv_lib_pthreads_pthread_mutex_init+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + if test "$tcl_ok" = "no"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_mutex_init in -lc_r" >&5 +$as_echo_n "checking for pthread_mutex_init in -lc_r... " >&6; } +if ${ac_cv_lib_c_r_pthread_mutex_init+:} false; then : + $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS -LIBS="-lpthreads $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF +LIBS="-lc_r $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -/* Override any gcc2 internal prototype to avoid an error. */ +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ char pthread_mutex_init (); int main () { -pthread_mutex_init (); +return pthread_mutex_init (); ; return 0; } _ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_lib_pthreads_pthread_mutex_init=yes +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_c_r_pthread_mutex_init=yes else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_lib_pthreads_pthread_mutex_init=no + ac_cv_lib_c_r_pthread_mutex_init=no fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -echo "$as_me:$LINENO: result: $ac_cv_lib_pthreads_pthread_mutex_init" >&5 -echo "${ECHO_T}$ac_cv_lib_pthreads_pthread_mutex_init" >&6 -if test $ac_cv_lib_pthreads_pthread_mutex_init = yes; then - tcl_ok=yes -else - tcl_ok=no -fi - - if test "$tcl_ok" = "yes"; then - # The space is needed - THREADS_LIBS=" -lpthreads" - else - echo "$as_me:$LINENO: checking for pthread_mutex_init in -lc" >&5 -echo $ECHO_N "checking for pthread_mutex_init in -lc... $ECHO_C" >&6 -if test "${ac_cv_lib_c_pthread_mutex_init+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lc $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char pthread_mutex_init (); -int -main () -{ -pthread_mutex_init (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_lib_c_pthread_mutex_init=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_lib_c_pthread_mutex_init=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -echo "$as_me:$LINENO: result: $ac_cv_lib_c_pthread_mutex_init" >&5 -echo "${ECHO_T}$ac_cv_lib_c_pthread_mutex_init" >&6 -if test $ac_cv_lib_c_pthread_mutex_init = yes; then - tcl_ok=yes -else - tcl_ok=no -fi - - if test "$tcl_ok" = "no"; then - echo "$as_me:$LINENO: checking for pthread_mutex_init in -lc_r" >&5 -echo $ECHO_N "checking for pthread_mutex_init in -lc_r... $ECHO_C" >&6 -if test "${ac_cv_lib_c_r_pthread_mutex_init+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lc_r $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char pthread_mutex_init (); -int -main () -{ -pthread_mutex_init (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_lib_c_r_pthread_mutex_init=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_lib_c_r_pthread_mutex_init=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -echo "$as_me:$LINENO: result: $ac_cv_lib_c_r_pthread_mutex_init" >&5 -echo "${ECHO_T}$ac_cv_lib_c_r_pthread_mutex_init" >&6 -if test $ac_cv_lib_c_r_pthread_mutex_init = yes; then +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_c_r_pthread_mutex_init" >&5 +$as_echo "$ac_cv_lib_c_r_pthread_mutex_init" >&6; } +if test "x$ac_cv_lib_c_r_pthread_mutex_init" = xyes; then : tcl_ok=yes else tcl_ok=no @@ -4814,8 +4212,8 @@ fi THREADS_LIBS=" -pthread" else TCL_THREADS=0 - { echo "$as_me:$LINENO: WARNING: Don't know how to find pthread lib on your system - you must disable thread support or edit the LIBS in the Makefile..." >&5 -echo "$as_me: WARNING: Don't know how to find pthread lib on your system - you must disable thread support or edit the LIBS in the Makefile..." >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Don't know how to find pthread lib on your system - you must disable thread support or edit the LIBS in the Makefile..." >&5 +$as_echo "$as_me: WARNING: Don't know how to find pthread lib on your system - you must disable thread support or edit the LIBS in the Makefile..." >&2;} fi fi fi @@ -4826,104 +4224,13 @@ echo "$as_me: WARNING: Don't know how to find pthread lib on your system - you m ac_saved_libs=$LIBS LIBS="$LIBS $THREADS_LIBS" - - -for ac_func in pthread_attr_setstacksize pthread_atfork -do -as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` -echo "$as_me:$LINENO: checking for $ac_func" >&5 -echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 -if eval "test \"\${$as_ac_var+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -/* Define $ac_func to an innocuous variant, in case declares $ac_func. - For example, HP-UX 11i declares gettimeofday. */ -#define $ac_func innocuous_$ac_func - -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char $ac_func (); below. - Prefer to if __STDC__ is defined, since - exists even on freestanding compilers. */ - -#ifdef __STDC__ -# include -#else -# include -#endif - -#undef $ac_func - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -{ -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char $ac_func (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_$ac_func) || defined (__stub___$ac_func) -choke me -#else -char (*f) () = $ac_func; -#endif -#ifdef __cplusplus -} -#endif - -int -main () -{ -return f != $ac_func; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - eval "$as_ac_var=yes" -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -eval "$as_ac_var=no" -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 -if test `eval echo '${'$as_ac_var'}'` = yes; then + for ac_func in pthread_attr_setstacksize pthread_atfork +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi @@ -4934,24 +4241,22 @@ done TCL_THREADS=0 fi # Do checking message here to not mess up interleaved configure output - echo "$as_me:$LINENO: checking for building with threads" >&5 -echo $ECHO_N "checking for building with threads... $ECHO_C" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for building with threads" >&5 +$as_echo_n "checking for building with threads... " >&6; } if test "${TCL_THREADS}" = 1; then -cat >>confdefs.h <<\_ACEOF -#define TCL_THREADS 1 -_ACEOF +$as_echo "#define TCL_THREADS 1" >>confdefs.h if test "${tcl_threaded_core}" = 1; then - echo "$as_me:$LINENO: result: yes (threaded core)" >&5 -echo "${ECHO_T}yes (threaded core)" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes (threaded core)" >&5 +$as_echo "yes (threaded core)" >&6; } else - echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } fi else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } fi @@ -4963,11 +4268,11 @@ echo "${ECHO_T}no" >&6 -# Check whether --with-encoding or --without-encoding was given. -if test "${with_encoding+set}" = set; then - withval="$with_encoding" - with_tcencoding=${withval} -fi; +# Check whether --with-encoding was given. +if test "${with_encoding+set}" = set; then : + withval=$with_encoding; with_tcencoding=${withval} +fi + if test x"${with_tcencoding}" != x ; then @@ -4977,9 +4282,7 @@ _ACEOF else -cat >>confdefs.h <<\_ACEOF -#define TCL_CFGVAL_ENCODING "iso8859-1" -_ACEOF +$as_echo "#define TCL_CFGVAL_ENCODING \"iso8859-1\"" >>confdefs.h fi @@ -4996,161 +4299,44 @@ _ACEOF # right (and it must appear before "-lm"). #-------------------------------------------------------------------- - echo "$as_me:$LINENO: checking for sin" >&5 -echo $ECHO_N "checking for sin... $ECHO_C" >&6 -if test "${ac_cv_func_sin+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -/* Define sin to an innocuous variant, in case declares sin. - For example, HP-UX 11i declares gettimeofday. */ -#define sin innocuous_sin - -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char sin (); below. - Prefer to if __STDC__ is defined, since - exists even on freestanding compilers. */ - -#ifdef __STDC__ -# include -#else -# include -#endif - -#undef sin - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -{ -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char sin (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_sin) || defined (__stub___sin) -choke me -#else -char (*f) () = sin; -#endif -#ifdef __cplusplus -} -#endif - -int -main () -{ -return f != sin; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_func_sin=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_func_sin=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_func_sin" >&5 -echo "${ECHO_T}$ac_cv_func_sin" >&6 -if test $ac_cv_func_sin = yes; then + ac_fn_c_check_func "$LINENO" "sin" "ac_cv_func_sin" +if test "x$ac_cv_func_sin" = xyes; then : MATH_LIBS="" else MATH_LIBS="-lm" fi - echo "$as_me:$LINENO: checking for main in -lieee" >&5 -echo $ECHO_N "checking for main in -lieee... $ECHO_C" >&6 -if test "${ac_cv_lib_ieee_main+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lieee" >&5 +$as_echo_n "checking for main in -lieee... " >&6; } +if ${ac_cv_lib_ieee_main+:} false; then : + $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lieee $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF +cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { -main (); +return main (); ; return 0; } _ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then +if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_ieee_main=yes else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_lib_ieee_main=no + ac_cv_lib_ieee_main=no fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -echo "$as_me:$LINENO: result: $ac_cv_lib_ieee_main" >&5 -echo "${ECHO_T}$ac_cv_lib_ieee_main" >&6 -if test $ac_cv_lib_ieee_main = yes; then +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ieee_main" >&5 +$as_echo "$ac_cv_lib_ieee_main" >&6; } +if test "x$ac_cv_lib_ieee_main" = xyes; then : MATH_LIBS="-lieee $MATH_LIBS" fi @@ -5160,211 +4346,45 @@ fi # needs net/errno.h to define the socket-related error codes. #-------------------------------------------------------------------- - echo "$as_me:$LINENO: checking for main in -linet" >&5 -echo $ECHO_N "checking for main in -linet... $ECHO_C" >&6 -if test "${ac_cv_lib_inet_main+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -linet" >&5 +$as_echo_n "checking for main in -linet... " >&6; } +if ${ac_cv_lib_inet_main+:} false; then : + $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-linet $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF +cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { -main (); +return main (); ; return 0; } _ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then +if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_inet_main=yes else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_lib_inet_main=no + ac_cv_lib_inet_main=no fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -echo "$as_me:$LINENO: result: $ac_cv_lib_inet_main" >&5 -echo "${ECHO_T}$ac_cv_lib_inet_main" >&6 -if test $ac_cv_lib_inet_main = yes; then +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_inet_main" >&5 +$as_echo "$ac_cv_lib_inet_main" >&6; } +if test "x$ac_cv_lib_inet_main" = xyes; then : LIBS="$LIBS -linet" fi - if test "${ac_cv_header_net_errno_h+set}" = set; then - echo "$as_me:$LINENO: checking for net/errno.h" >&5 -echo $ECHO_N "checking for net/errno.h... $ECHO_C" >&6 -if test "${ac_cv_header_net_errno_h+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -fi -echo "$as_me:$LINENO: result: $ac_cv_header_net_errno_h" >&5 -echo "${ECHO_T}$ac_cv_header_net_errno_h" >&6 -else - # Is the header compilable? -echo "$as_me:$LINENO: checking net/errno.h usability" >&5 -echo $ECHO_N "checking net/errno.h usability... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -#include -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_header_compiler=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_header_compiler=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -echo "${ECHO_T}$ac_header_compiler" >&6 - -# Is the header present? -echo "$as_me:$LINENO: checking net/errno.h presence" >&5 -echo $ECHO_N "checking net/errno.h presence... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -_ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - ac_header_preproc=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_header_preproc=no -fi -rm -f conftest.err conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -echo "${ECHO_T}$ac_header_preproc" >&6 - -# So? What about this header? -case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in - yes:no: ) - { echo "$as_me:$LINENO: WARNING: net/errno.h: accepted by the compiler, rejected by the preprocessor!" >&5 -echo "$as_me: WARNING: net/errno.h: accepted by the compiler, rejected by the preprocessor!" >&2;} - { echo "$as_me:$LINENO: WARNING: net/errno.h: proceeding with the compiler's result" >&5 -echo "$as_me: WARNING: net/errno.h: proceeding with the compiler's result" >&2;} - ac_header_preproc=yes - ;; - no:yes:* ) - { echo "$as_me:$LINENO: WARNING: net/errno.h: present but cannot be compiled" >&5 -echo "$as_me: WARNING: net/errno.h: present but cannot be compiled" >&2;} - { echo "$as_me:$LINENO: WARNING: net/errno.h: check for missing prerequisite headers?" >&5 -echo "$as_me: WARNING: net/errno.h: check for missing prerequisite headers?" >&2;} - { echo "$as_me:$LINENO: WARNING: net/errno.h: see the Autoconf documentation" >&5 -echo "$as_me: WARNING: net/errno.h: see the Autoconf documentation" >&2;} - { echo "$as_me:$LINENO: WARNING: net/errno.h: section \"Present But Cannot Be Compiled\"" >&5 -echo "$as_me: WARNING: net/errno.h: section \"Present But Cannot Be Compiled\"" >&2;} - { echo "$as_me:$LINENO: WARNING: net/errno.h: proceeding with the preprocessor's result" >&5 -echo "$as_me: WARNING: net/errno.h: proceeding with the preprocessor's result" >&2;} - { echo "$as_me:$LINENO: WARNING: net/errno.h: in the future, the compiler will take precedence" >&5 -echo "$as_me: WARNING: net/errno.h: in the future, the compiler will take precedence" >&2;} - ( - cat <<\_ASBOX -## ------------------------------ ## -## Report this to the tcl lists. ## -## ------------------------------ ## -_ASBOX - ) | - sed "s/^/$as_me: WARNING: /" >&2 - ;; -esac -echo "$as_me:$LINENO: checking for net/errno.h" >&5 -echo $ECHO_N "checking for net/errno.h... $ECHO_C" >&6 -if test "${ac_cv_header_net_errno_h+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_cv_header_net_errno_h=$ac_header_preproc -fi -echo "$as_me:$LINENO: result: $ac_cv_header_net_errno_h" >&5 -echo "${ECHO_T}$ac_cv_header_net_errno_h" >&6 - -fi -if test $ac_cv_header_net_errno_h = yes; then + ac_fn_c_check_header_mongrel "$LINENO" "net/errno.h" "ac_cv_header_net_errno_h" "$ac_includes_default" +if test "x$ac_cv_header_net_errno_h" = xyes; then : -cat >>confdefs.h <<\_ACEOF -#define HAVE_NET_ERRNO_H 1 -_ACEOF +$as_echo "#define HAVE_NET_ERRNO_H 1" >>confdefs.h fi @@ -5389,264 +4409,58 @@ fi #-------------------------------------------------------------------- tcl_checkBoth=0 - echo "$as_me:$LINENO: checking for connect" >&5 -echo $ECHO_N "checking for connect... $ECHO_C" >&6 -if test "${ac_cv_func_connect+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + ac_fn_c_check_func "$LINENO" "connect" "ac_cv_func_connect" +if test "x$ac_cv_func_connect" = xyes; then : + tcl_checkSocket=0 else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -/* Define connect to an innocuous variant, in case declares connect. - For example, HP-UX 11i declares gettimeofday. */ -#define connect innocuous_connect - -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char connect (); below. - Prefer to if __STDC__ is defined, since - exists even on freestanding compilers. */ + tcl_checkSocket=1 +fi -#ifdef __STDC__ -# include -#else -# include -#endif + if test "$tcl_checkSocket" = 1; then + ac_fn_c_check_func "$LINENO" "setsockopt" "ac_cv_func_setsockopt" +if test "x$ac_cv_func_setsockopt" = xyes; then : -#undef connect +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for setsockopt in -lsocket" >&5 +$as_echo_n "checking for setsockopt in -lsocket... " >&6; } +if ${ac_cv_lib_socket_setsockopt+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsocket $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -{ -#endif -/* We use char because int might match the return type of a gcc2 +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ -char connect (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_connect) || defined (__stub___connect) -choke me -#else -char (*f) () = connect; -#endif #ifdef __cplusplus -} +extern "C" #endif - +char setsockopt (); int main () { -return f != connect; +return setsockopt (); ; return 0; } _ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_func_connect=yes +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_socket_setsockopt=yes else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_func_connect=no + ac_cv_lib_socket_setsockopt=no fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS fi -echo "$as_me:$LINENO: result: $ac_cv_func_connect" >&5 -echo "${ECHO_T}$ac_cv_func_connect" >&6 -if test $ac_cv_func_connect = yes; then - tcl_checkSocket=0 +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_setsockopt" >&5 +$as_echo "$ac_cv_lib_socket_setsockopt" >&6; } +if test "x$ac_cv_lib_socket_setsockopt" = xyes; then : + LIBS="$LIBS -lsocket" else - tcl_checkSocket=1 -fi - - if test "$tcl_checkSocket" = 1; then - echo "$as_me:$LINENO: checking for setsockopt" >&5 -echo $ECHO_N "checking for setsockopt... $ECHO_C" >&6 -if test "${ac_cv_func_setsockopt+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -/* Define setsockopt to an innocuous variant, in case declares setsockopt. - For example, HP-UX 11i declares gettimeofday. */ -#define setsockopt innocuous_setsockopt - -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char setsockopt (); below. - Prefer to if __STDC__ is defined, since - exists even on freestanding compilers. */ - -#ifdef __STDC__ -# include -#else -# include -#endif - -#undef setsockopt - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -{ -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char setsockopt (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_setsockopt) || defined (__stub___setsockopt) -choke me -#else -char (*f) () = setsockopt; -#endif -#ifdef __cplusplus -} -#endif - -int -main () -{ -return f != setsockopt; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_func_setsockopt=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_func_setsockopt=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_func_setsockopt" >&5 -echo "${ECHO_T}$ac_cv_func_setsockopt" >&6 -if test $ac_cv_func_setsockopt = yes; then - : -else - echo "$as_me:$LINENO: checking for setsockopt in -lsocket" >&5 -echo $ECHO_N "checking for setsockopt in -lsocket... $ECHO_C" >&6 -if test "${ac_cv_lib_socket_setsockopt+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lsocket $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char setsockopt (); -int -main () -{ -setsockopt (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_lib_socket_setsockopt=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_lib_socket_setsockopt=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -echo "$as_me:$LINENO: result: $ac_cv_lib_socket_setsockopt" >&5 -echo "${ECHO_T}$ac_cv_lib_socket_setsockopt" >&6 -if test $ac_cv_lib_socket_setsockopt = yes; then - LIBS="$LIBS -lsocket" -else - tcl_checkBoth=1 + tcl_checkBoth=1 fi fi @@ -5655,261 +4469,55 @@ fi if test "$tcl_checkBoth" = 1; then tk_oldLibs=$LIBS LIBS="$LIBS -lsocket -lnsl" - echo "$as_me:$LINENO: checking for accept" >&5 -echo $ECHO_N "checking for accept... $ECHO_C" >&6 -if test "${ac_cv_func_accept+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -/* Define accept to an innocuous variant, in case declares accept. - For example, HP-UX 11i declares gettimeofday. */ -#define accept innocuous_accept - -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char accept (); below. - Prefer to if __STDC__ is defined, since - exists even on freestanding compilers. */ - -#ifdef __STDC__ -# include -#else -# include -#endif - -#undef accept - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -{ -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char accept (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_accept) || defined (__stub___accept) -choke me -#else -char (*f) () = accept; -#endif -#ifdef __cplusplus -} -#endif - -int -main () -{ -return f != accept; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_func_accept=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_func_accept=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_func_accept" >&5 -echo "${ECHO_T}$ac_cv_func_accept" >&6 -if test $ac_cv_func_accept = yes; then + ac_fn_c_check_func "$LINENO" "accept" "ac_cv_func_accept" +if test "x$ac_cv_func_accept" = xyes; then : tcl_checkNsl=0 else LIBS=$tk_oldLibs fi fi - echo "$as_me:$LINENO: checking for gethostbyname" >&5 -echo $ECHO_N "checking for gethostbyname... $ECHO_C" >&6 -if test "${ac_cv_func_gethostbyname+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -/* Define gethostbyname to an innocuous variant, in case declares gethostbyname. - For example, HP-UX 11i declares gettimeofday. */ -#define gethostbyname innocuous_gethostbyname - -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char gethostbyname (); below. - Prefer to if __STDC__ is defined, since - exists even on freestanding compilers. */ - -#ifdef __STDC__ -# include -#else -# include -#endif - -#undef gethostbyname - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -{ -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char gethostbyname (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_gethostbyname) || defined (__stub___gethostbyname) -choke me -#else -char (*f) () = gethostbyname; -#endif -#ifdef __cplusplus -} -#endif - -int -main () -{ -return f != gethostbyname; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_func_gethostbyname=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 + ac_fn_c_check_func "$LINENO" "gethostbyname" "ac_cv_func_gethostbyname" +if test "x$ac_cv_func_gethostbyname" = xyes; then : -ac_cv_func_gethostbyname=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_func_gethostbyname" >&5 -echo "${ECHO_T}$ac_cv_func_gethostbyname" >&6 -if test $ac_cv_func_gethostbyname = yes; then - : else - echo "$as_me:$LINENO: checking for gethostbyname in -lnsl" >&5 -echo $ECHO_N "checking for gethostbyname in -lnsl... $ECHO_C" >&6 -if test "${ac_cv_lib_nsl_gethostbyname+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyname in -lnsl" >&5 +$as_echo_n "checking for gethostbyname in -lnsl... " >&6; } +if ${ac_cv_lib_nsl_gethostbyname+:} false; then : + $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lnsl $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF +cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -/* Override any gcc2 internal prototype to avoid an error. */ +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ char gethostbyname (); int main () { -gethostbyname (); +return gethostbyname (); ; return 0; } _ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then +if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_nsl_gethostbyname=yes else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_lib_nsl_gethostbyname=no + ac_cv_lib_nsl_gethostbyname=no fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -echo "$as_me:$LINENO: result: $ac_cv_lib_nsl_gethostbyname" >&5 -echo "${ECHO_T}$ac_cv_lib_nsl_gethostbyname" >&6 -if test $ac_cv_lib_nsl_gethostbyname = yes; then +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nsl_gethostbyname" >&5 +$as_echo "$ac_cv_lib_nsl_gethostbyname" >&6; } +if test "x$ac_cv_lib_nsl_gethostbyname" = xyes; then : LIBS="$LIBS -lnsl" fi @@ -5921,15 +4529,15 @@ fi LIBS="$LIBS$THREADS_LIBS" - echo "$as_me:$LINENO: checking how to build libraries" >&5 -echo $ECHO_N "checking how to build libraries... $ECHO_C" >&6 - # Check whether --enable-shared or --disable-shared was given. -if test "${enable_shared+set}" = set; then - enableval="$enable_shared" - tcl_ok=$enableval + { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to build libraries" >&5 +$as_echo_n "checking how to build libraries... " >&6; } + # Check whether --enable-shared was given. +if test "${enable_shared+set}" = set; then : + enableval=$enable_shared; tcl_ok=$enableval else tcl_ok=yes -fi; +fi + if test "${enable_shared+set}" = set; then enableval="$enable_shared" @@ -5939,17 +4547,15 @@ fi; fi if test "$tcl_ok" = "yes" ; then - echo "$as_me:$LINENO: result: shared" >&5 -echo "${ECHO_T}shared" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: shared" >&5 +$as_echo "shared" >&6; } SHARED_BUILD=1 else - echo "$as_me:$LINENO: result: static" >&5 -echo "${ECHO_T}static" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: static" >&5 +$as_echo "static" >&6; } SHARED_BUILD=0 -cat >>confdefs.h <<\_ACEOF -#define STATIC_BUILD 1 -_ACEOF +$as_echo "#define STATIC_BUILD 1" >>confdefs.h fi @@ -5961,10 +4567,10 @@ _ACEOF #-------------------------------------------------------------------- - echo "$as_me:$LINENO: checking for tclsh" >&5 -echo $ECHO_N "checking for tclsh... $ECHO_C" >&6 - if test "${ac_cv_path_tclsh+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for tclsh" >&5 +$as_echo_n "checking for tclsh... " >&6; } + if ${ac_cv_path_tclsh+:} false; then : + $as_echo_n "(cached) " >&6 else search_path=`echo ${PATH} | sed -e 's/:/ /g'` @@ -5985,13 +4591,13 @@ fi if test -f "$ac_cv_path_tclsh" ; then TCLSH_PROG="$ac_cv_path_tclsh" - echo "$as_me:$LINENO: result: $TCLSH_PROG" >&5 -echo "${ECHO_T}$TCLSH_PROG" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $TCLSH_PROG" >&5 +$as_echo "$TCLSH_PROG" >&6; } else # It is not an error if an installed version of Tcl can't be located. TCLSH_PROG="" - echo "$as_me:$LINENO: result: No tclsh found on PATH" >&5 -echo "${ECHO_T}No tclsh found on PATH" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: No tclsh found on PATH" >&5 +$as_echo "No tclsh found on PATH" >&6; } fi @@ -6004,351 +4610,89 @@ fi #------------------------------------------------------------------------ zlib_ok=yes -if test "${ac_cv_header_zlib_h+set}" = set; then - echo "$as_me:$LINENO: checking for zlib.h" >&5 -echo $ECHO_N "checking for zlib.h... $ECHO_C" >&6 -if test "${ac_cv_header_zlib_h+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -fi -echo "$as_me:$LINENO: result: $ac_cv_header_zlib_h" >&5 -echo "${ECHO_T}$ac_cv_header_zlib_h" >&6 -else - # Is the header compilable? -echo "$as_me:$LINENO: checking zlib.h usability" >&5 -echo $ECHO_N "checking zlib.h usability... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -#include -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_header_compiler=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 +ac_fn_c_check_header_mongrel "$LINENO" "zlib.h" "ac_cv_header_zlib_h" "$ac_includes_default" +if test "x$ac_cv_header_zlib_h" = xyes; then : -ac_header_compiler=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -echo "${ECHO_T}$ac_header_compiler" >&6 + ac_fn_c_check_type "$LINENO" "gz_header" "ac_cv_type_gz_header" "#include +" +if test "x$ac_cv_type_gz_header" = xyes; then : -# Is the header present? -echo "$as_me:$LINENO: checking zlib.h presence" >&5 -echo $ECHO_N "checking zlib.h presence... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -_ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi else - ac_cpp_err=yes + zlib_ok=no fi -if test -z "$ac_cpp_err"; then - ac_header_preproc=yes + else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - ac_header_preproc=no + zlib_ok=no fi -rm -f conftest.err conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -echo "${ECHO_T}$ac_header_preproc" >&6 -# So? What about this header? -case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in - yes:no: ) - { echo "$as_me:$LINENO: WARNING: zlib.h: accepted by the compiler, rejected by the preprocessor!" >&5 -echo "$as_me: WARNING: zlib.h: accepted by the compiler, rejected by the preprocessor!" >&2;} - { echo "$as_me:$LINENO: WARNING: zlib.h: proceeding with the compiler's result" >&5 -echo "$as_me: WARNING: zlib.h: proceeding with the compiler's result" >&2;} - ac_header_preproc=yes - ;; - no:yes:* ) - { echo "$as_me:$LINENO: WARNING: zlib.h: present but cannot be compiled" >&5 -echo "$as_me: WARNING: zlib.h: present but cannot be compiled" >&2;} - { echo "$as_me:$LINENO: WARNING: zlib.h: check for missing prerequisite headers?" >&5 -echo "$as_me: WARNING: zlib.h: check for missing prerequisite headers?" >&2;} - { echo "$as_me:$LINENO: WARNING: zlib.h: see the Autoconf documentation" >&5 -echo "$as_me: WARNING: zlib.h: see the Autoconf documentation" >&2;} - { echo "$as_me:$LINENO: WARNING: zlib.h: section \"Present But Cannot Be Compiled\"" >&5 -echo "$as_me: WARNING: zlib.h: section \"Present But Cannot Be Compiled\"" >&2;} - { echo "$as_me:$LINENO: WARNING: zlib.h: proceeding with the preprocessor's result" >&5 -echo "$as_me: WARNING: zlib.h: proceeding with the preprocessor's result" >&2;} - { echo "$as_me:$LINENO: WARNING: zlib.h: in the future, the compiler will take precedence" >&5 -echo "$as_me: WARNING: zlib.h: in the future, the compiler will take precedence" >&2;} - ( - cat <<\_ASBOX -## ------------------------------ ## -## Report this to the tcl lists. ## -## ------------------------------ ## -_ASBOX - ) | - sed "s/^/$as_me: WARNING: /" >&2 - ;; -esac -echo "$as_me:$LINENO: checking for zlib.h" >&5 -echo $ECHO_N "checking for zlib.h... $ECHO_C" >&6 -if test "${ac_cv_header_zlib_h+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_cv_header_zlib_h=$ac_header_preproc -fi -echo "$as_me:$LINENO: result: $ac_cv_header_zlib_h" >&5 -echo "${ECHO_T}$ac_cv_header_zlib_h" >&6 -fi -if test $ac_cv_header_zlib_h = yes; then +if test $zlib_ok = yes; then : - echo "$as_me:$LINENO: checking for gz_header" >&5 -echo $ECHO_N "checking for gz_header... $ECHO_C" >&6 -if test "${ac_cv_type_gz_header+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing deflateSetHeader" >&5 +$as_echo_n "checking for library containing deflateSetHeader... " >&6; } +if ${ac_cv_search_deflateSetHeader+:} false; then : + $as_echo_n "(cached) " >&6 else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#include +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char deflateSetHeader (); int main () { -if ((gz_header *) 0) - return 0; -if (sizeof (gz_header)) - return 0; +return deflateSetHeader (); ; return 0; } _ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_type_gz_header=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_type_gz_header=no +for ac_lib in '' z; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_deflateSetHeader=$ac_res fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_deflateSetHeader+:} false; then : + break fi -echo "$as_me:$LINENO: result: $ac_cv_type_gz_header" >&5 -echo "${ECHO_T}$ac_cv_type_gz_header" >&6 -if test $ac_cv_type_gz_header = yes; then - : +done +if ${ac_cv_search_deflateSetHeader+:} false; then : + else - zlib_ok=no + ac_cv_search_deflateSetHeader=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_deflateSetHeader" >&5 +$as_echo "$ac_cv_search_deflateSetHeader" >&6; } +ac_res=$ac_cv_search_deflateSetHeader +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" else - zlib_ok=no + zlib_ok=no + fi +fi +if test $zlib_ok = no; then : -if test $zlib_ok = yes; then - - echo "$as_me:$LINENO: checking for library containing deflateSetHeader" >&5 -echo $ECHO_N "checking for library containing deflateSetHeader... $ECHO_C" >&6 -if test "${ac_cv_search_deflateSetHeader+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_func_search_save_LIBS=$LIBS -ac_cv_search_deflateSetHeader=no -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char deflateSetHeader (); -int -main () -{ -deflateSetHeader (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_search_deflateSetHeader="none required" -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -if test "$ac_cv_search_deflateSetHeader" = no; then - for ac_lib in z; do - LIBS="-l$ac_lib $ac_func_search_save_LIBS" - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char deflateSetHeader (); -int -main () -{ -deflateSetHeader (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_search_deflateSetHeader="-l$ac_lib" -break -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - done -fi -LIBS=$ac_func_search_save_LIBS -fi -echo "$as_me:$LINENO: result: $ac_cv_search_deflateSetHeader" >&5 -echo "${ECHO_T}$ac_cv_search_deflateSetHeader" >&6 -if test "$ac_cv_search_deflateSetHeader" != no; then - test "$ac_cv_search_deflateSetHeader" = "none required" || LIBS="$ac_cv_search_deflateSetHeader $LIBS" - -else - - zlib_ok=no - -fi - -fi - -if test $zlib_ok = no; then - - ZLIB_OBJS=\${ZLIB_OBJS} + ZLIB_OBJS=\${ZLIB_OBJS} ZLIB_SRCS=\${ZLIB_SRCS} @@ -6357,10 +4701,7 @@ if test $zlib_ok = no; then fi - -cat >>confdefs.h <<\_ACEOF -#define HAVE_ZLIB 1 -_ACEOF +$as_echo "#define HAVE_ZLIB 1" >>confdefs.h #-------------------------------------------------------------------- @@ -6372,10 +4713,10 @@ _ACEOF if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. set dummy ${ac_tool_prefix}ranlib; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_RANLIB+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 else if test -n "$RANLIB"; then ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. @@ -6385,35 +4726,37 @@ for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done -done + done +IFS=$as_save_IFS fi fi RANLIB=$ac_cv_prog_RANLIB if test -n "$RANLIB"; then - echo "$as_me:$LINENO: result: $RANLIB" >&5 -echo "${ECHO_T}$RANLIB" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 +$as_echo "$RANLIB" >&6; } else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } fi + fi if test -z "$ac_cv_prog_RANLIB"; then ac_ct_RANLIB=$RANLIB # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_RANLIB"; then ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. @@ -6423,28 +4766,38 @@ for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_RANLIB="ranlib" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done -done + done +IFS=$as_save_IFS - test -z "$ac_cv_prog_ac_ct_RANLIB" && ac_cv_prog_ac_ct_RANLIB=":" fi fi ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB if test -n "$ac_ct_RANLIB"; then - echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5 -echo "${ECHO_T}$ac_ct_RANLIB" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 +$as_echo "$ac_ct_RANLIB" >&6; } else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } fi - RANLIB=$ac_ct_RANLIB + if test "x$ac_ct_RANLIB" = x; then + RANLIB=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + RANLIB=$ac_ct_RANLIB + fi else RANLIB="$ac_cv_prog_RANLIB" fi @@ -6453,52 +4806,47 @@ fi # Step 0.a: Enable 64 bit support? - echo "$as_me:$LINENO: checking if 64bit support is requested" >&5 -echo $ECHO_N "checking if 64bit support is requested... $ECHO_C" >&6 - # Check whether --enable-64bit or --disable-64bit was given. -if test "${enable_64bit+set}" = set; then - enableval="$enable_64bit" - do64bit=$enableval + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if 64bit support is requested" >&5 +$as_echo_n "checking if 64bit support is requested... " >&6; } + # Check whether --enable-64bit was given. +if test "${enable_64bit+set}" = set; then : + enableval=$enable_64bit; do64bit=$enableval else do64bit=no -fi; - echo "$as_me:$LINENO: result: $do64bit" >&5 -echo "${ECHO_T}$do64bit" >&6 +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $do64bit" >&5 +$as_echo "$do64bit" >&6; } # Step 0.b: Enable Solaris 64 bit VIS support? - echo "$as_me:$LINENO: checking if 64bit Sparc VIS support is requested" >&5 -echo $ECHO_N "checking if 64bit Sparc VIS support is requested... $ECHO_C" >&6 - # Check whether --enable-64bit-vis or --disable-64bit-vis was given. -if test "${enable_64bit_vis+set}" = set; then - enableval="$enable_64bit_vis" - do64bitVIS=$enableval + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if 64bit Sparc VIS support is requested" >&5 +$as_echo_n "checking if 64bit Sparc VIS support is requested... " >&6; } + # Check whether --enable-64bit-vis was given. +if test "${enable_64bit_vis+set}" = set; then : + enableval=$enable_64bit_vis; do64bitVIS=$enableval else do64bitVIS=no -fi; - echo "$as_me:$LINENO: result: $do64bitVIS" >&5 -echo "${ECHO_T}$do64bitVIS" >&6 +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $do64bitVIS" >&5 +$as_echo "$do64bitVIS" >&6; } # Force 64bit on with VIS - if test "$do64bitVIS" = "yes"; then + if test "$do64bitVIS" = "yes"; then : do64bit=yes fi - # Step 0.c: Check if visibility support is available. Do this here so # that platform specific alternatives can be used below if this fails. - echo "$as_me:$LINENO: checking if compiler supports visibility \"hidden\"" >&5 -echo $ECHO_N "checking if compiler supports visibility \"hidden\"... $ECHO_C" >&6 -if test "${tcl_cv_cc_visibility_hidden+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if compiler supports visibility \"hidden\"" >&5 +$as_echo_n "checking if compiler supports visibility \"hidden\"... " >&6; } +if ${tcl_cv_cc_visibility_hidden+:} false; then : + $as_echo_n "(cached) " >&6 else hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -Werror" - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ extern __attribute__((__visibility__("hidden"))) void f(void); @@ -6511,79 +4859,50 @@ f(); return 0; } _ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then +if ac_fn_c_try_link "$LINENO"; then : tcl_cv_cc_visibility_hidden=yes else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -tcl_cv_cc_visibility_hidden=no + tcl_cv_cc_visibility_hidden=no fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext CFLAGS=$hold_cflags fi -echo "$as_me:$LINENO: result: $tcl_cv_cc_visibility_hidden" >&5 -echo "${ECHO_T}$tcl_cv_cc_visibility_hidden" >&6 - if test $tcl_cv_cc_visibility_hidden = yes; then +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_cc_visibility_hidden" >&5 +$as_echo "$tcl_cv_cc_visibility_hidden" >&6; } + if test $tcl_cv_cc_visibility_hidden = yes; then : -cat >>confdefs.h <<\_ACEOF -#define MODULE_SCOPE extern __attribute__((__visibility__("hidden"))) -_ACEOF +$as_echo "#define MODULE_SCOPE extern __attribute__((__visibility__(\"hidden\")))" >>confdefs.h -cat >>confdefs.h <<\_ACEOF -#define HAVE_HIDDEN 1 -_ACEOF +$as_echo "#define HAVE_HIDDEN 1" >>confdefs.h fi - # Step 0.d: Disable -rpath support? - echo "$as_me:$LINENO: checking if rpath support is requested" >&5 -echo $ECHO_N "checking if rpath support is requested... $ECHO_C" >&6 - # Check whether --enable-rpath or --disable-rpath was given. -if test "${enable_rpath+set}" = set; then - enableval="$enable_rpath" - doRpath=$enableval + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if rpath support is requested" >&5 +$as_echo_n "checking if rpath support is requested... " >&6; } + # Check whether --enable-rpath was given. +if test "${enable_rpath+set}" = set; then : + enableval=$enable_rpath; doRpath=$enableval else doRpath=yes -fi; - echo "$as_me:$LINENO: result: $doRpath" >&5 -echo "${ECHO_T}$doRpath" >&6 +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $doRpath" >&5 +$as_echo "$doRpath" >&6; } # Step 1: set the variable "system" to hold the name and version number # for the system. - echo "$as_me:$LINENO: checking system version" >&5 -echo $ECHO_N "checking system version... $ECHO_C" >&6 -if test "${tcl_cv_sys_version+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking system version" >&5 +$as_echo_n "checking system version... " >&6; } +if ${tcl_cv_sys_version+:} false; then : + $as_echo_n "(cached) " >&6 else if test -f /usr/lib/NextStep/software_version; then @@ -6591,8 +4910,8 @@ else else tcl_cv_sys_version=`uname -s`-`uname -r` if test "$?" -ne 0 ; then - { echo "$as_me:$LINENO: WARNING: can't find uname command" >&5 -echo "$as_me: WARNING: can't find uname command" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: can't find uname command" >&5 +$as_echo "$as_me: WARNING: can't find uname command" >&2;} tcl_cv_sys_version=unknown else # Special check for weird MP-RAS system (uname returns weird @@ -6608,79 +4927,51 @@ echo "$as_me: WARNING: can't find uname command" >&2;} fi fi -echo "$as_me:$LINENO: result: $tcl_cv_sys_version" >&5 -echo "${ECHO_T}$tcl_cv_sys_version" >&6 +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_sys_version" >&5 +$as_echo "$tcl_cv_sys_version" >&6; } system=$tcl_cv_sys_version # Step 2: check for existence of -ldl library. This is needed because # Linux can use either -ldl or -ldld for dynamic loading. - echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5 -echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6 -if test "${ac_cv_lib_dl_dlopen+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 +$as_echo_n "checking for dlopen in -ldl... " >&6; } +if ${ac_cv_lib_dl_dlopen+:} false; then : + $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF +cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -/* Override any gcc2 internal prototype to avoid an error. */ +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ char dlopen (); int main () { -dlopen (); +return dlopen (); ; return 0; } _ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then +if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dl_dlopen=yes else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_lib_dl_dlopen=no + ac_cv_lib_dl_dlopen=no fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5 -echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6 -if test $ac_cv_lib_dl_dlopen = yes; then +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 +$as_echo "$ac_cv_lib_dl_dlopen" >&6; } +if test "x$ac_cv_lib_dl_dlopen" = xyes; then : have_dl=yes else have_dl=no @@ -6706,7 +4997,7 @@ fi ECHO_VERSION='`echo ${VERSION}`' TCL_LIB_VERSIONS_OK=ok CFLAGS_DEBUG=-g - if test "$GCC" = yes; then + if test "$GCC" = yes; then : CFLAGS_OPTIMIZE=-O2 CFLAGS_WARNING="-Wall" @@ -6717,14 +5008,13 @@ else CFLAGS_WARNING="" fi - if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args. set dummy ${ac_tool_prefix}ar; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_AR+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AR+:} false; then : + $as_echo_n "(cached) " >&6 else if test -n "$AR"; then ac_cv_prog_AR="$AR" # Let the user override the test. @@ -6734,35 +5024,37 @@ for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AR="${ac_tool_prefix}ar" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done -done + done +IFS=$as_save_IFS fi fi AR=$ac_cv_prog_AR if test -n "$AR"; then - echo "$as_me:$LINENO: result: $AR" >&5 -echo "${ECHO_T}$AR" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 +$as_echo "$AR" >&6; } else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } fi + fi if test -z "$ac_cv_prog_AR"; then ac_ct_AR=$AR # Extract the first word of "ar", so it can be a program name with args. set dummy ar; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_ac_ct_AR+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_AR+:} false; then : + $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_AR"; then ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. @@ -6772,27 +5064,38 @@ for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_AR="ar" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done -done + done +IFS=$as_save_IFS fi fi ac_ct_AR=$ac_cv_prog_ac_ct_AR if test -n "$ac_ct_AR"; then - echo "$as_me:$LINENO: result: $ac_ct_AR" >&5 -echo "${ECHO_T}$ac_ct_AR" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 +$as_echo "$ac_ct_AR" >&6; } else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } fi - AR=$ac_ct_AR + if test "x$ac_ct_AR" = x; then + AR="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + AR=$ac_ct_AR + fi else AR="$ac_cv_prog_AR" fi @@ -6802,13 +5105,12 @@ fi PLAT_OBJS="" PLAT_SRCS="" LDAIX_SRC="" - if test x"${SHLIB_VERSION}" = x; then + if test x"${SHLIB_VERSION}" = x; then : SHLIB_VERSION="1.0" fi - case $system in AIX-*) - if test "${TCL_THREADS}" = "1" -a "$GCC" != "yes"; then + if test "${TCL_THREADS}" = "1" -a "$GCC" != "yes"; then : # AIX requires the _r compiler when gcc isn't being used case "${CC}" in @@ -6820,11 +5122,10 @@ fi CC=`echo "$CC" | sed -e 's/^\([^ ]*\)/\1_r/'` ;; esac - echo "$as_me:$LINENO: result: Using $CC for compiling with threads" >&5 -echo "${ECHO_T}Using $CC for compiling with threads" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: Using $CC for compiling with threads" >&5 +$as_echo "Using $CC for compiling with threads" >&6; } fi - LIBS="$LIBS -lc" SHLIB_CFLAGS="" SHLIB_SUFFIX=".so" @@ -6837,12 +5138,12 @@ fi LDAIX_SRC='$(UNIX_DIR)/ldAix' # Check to enable 64-bit flags for compiler/linker - if test "$do64bit" = yes; then + if test "$do64bit" = yes; then : - if test "$GCC" = yes; then + if test "$GCC" = yes; then : - { echo "$as_me:$LINENO: WARNING: 64bit mode not supported with GCC on $system" >&5 -echo "$as_me: WARNING: 64bit mode not supported with GCC on $system" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 64bit mode not supported with GCC on $system" >&5 +$as_echo "$as_me: WARNING: 64bit mode not supported with GCC on $system" >&2;} else @@ -6855,17 +5156,15 @@ else fi - fi - - if test "`uname -m`" = ia64; then + if test "`uname -m`" = ia64; then : # AIX-5 uses ELF style dynamic libraries on IA-64, but not PPC SHLIB_LD="/usr/ccs/bin/ld -G -z text" # AIX-5 has dl* in libc.so DL_LIBS="" - if test "$GCC" = yes; then + if test "$GCC" = yes; then : CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}' @@ -6874,12 +5173,11 @@ else CC_SEARCH_FLAGS='-R${LIB_RUNTIME_DIR}' fi - LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}' else - if test "$GCC" = yes; then + if test "$GCC" = yes; then : SHLIB_LD='${CC} -shared -Wl,-bexpall' @@ -6889,14 +5187,12 @@ else LDFLAGS="$LDFLAGS -brtl" fi - SHLIB_LD="${SHLIB_LD} ${SHLIB_LD_FLAGS}" DL_LIBS="-ldl" CC_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}' LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} fi - ;; BeOS*) SHLIB_CFLAGS="-fPIC" @@ -6910,71 +5206,43 @@ fi # -lsocket, even if the network functions are in -lnet which # is always linked to, for compatibility. #----------------------------------------------------------- - echo "$as_me:$LINENO: checking for inet_ntoa in -lbind" >&5 -echo $ECHO_N "checking for inet_ntoa in -lbind... $ECHO_C" >&6 -if test "${ac_cv_lib_bind_inet_ntoa+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for inet_ntoa in -lbind" >&5 +$as_echo_n "checking for inet_ntoa in -lbind... " >&6; } +if ${ac_cv_lib_bind_inet_ntoa+:} false; then : + $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lbind $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF +cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -/* Override any gcc2 internal prototype to avoid an error. */ +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ char inet_ntoa (); int main () { -inet_ntoa (); +return inet_ntoa (); ; return 0; } _ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then +if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_bind_inet_ntoa=yes else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_lib_bind_inet_ntoa=no + ac_cv_lib_bind_inet_ntoa=no fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -echo "$as_me:$LINENO: result: $ac_cv_lib_bind_inet_ntoa" >&5 -echo "${ECHO_T}$ac_cv_lib_bind_inet_ntoa" >&6 -if test $ac_cv_lib_bind_inet_ntoa = yes; then +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_bind_inet_ntoa" >&5 +$as_echo "$ac_cv_lib_bind_inet_ntoa" >&6; } +if test "x$ac_cv_lib_bind_inet_ntoa" = xyes; then : LIBS="$LIBS -lbind -lsocket" fi @@ -7011,16 +5279,12 @@ fi TCL_NEEDS_EXP_FILE=1 TCL_EXPORT_FILE_SUFFIX='${VERSION}\$\{DBGX\}.dll.a' SHLIB_LD_LIBS="${SHLIB_LD_LIBS} -Wl,--out-implib,\$@.a" - echo "$as_me:$LINENO: checking for Cygwin version of gcc" >&5 -echo $ECHO_N "checking for Cygwin version of gcc... $ECHO_C" >&6 -if test "${ac_cv_cygwin+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Cygwin version of gcc" >&5 +$as_echo_n "checking for Cygwin version of gcc... " >&6; } +if ${ac_cv_cygwin+:} false; then : + $as_echo_n "(cached) " >&6 else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __CYGWIN__ @@ -7035,49 +5299,21 @@ main () return 0; } _ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then +if ac_fn_c_try_compile "$LINENO"; then : ac_cv_cygwin=no else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_cygwin=yes + ac_cv_cygwin=yes fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi -echo "$as_me:$LINENO: result: $ac_cv_cygwin" >&5 -echo "${ECHO_T}$ac_cv_cygwin" >&6 +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cygwin" >&5 +$as_echo "$ac_cv_cygwin" >&6; } if test "$ac_cv_cygwin" = "no"; then - { { echo "$as_me:$LINENO: error: ${CC} is not a cygwin compiler." >&5 -echo "$as_me: error: ${CC} is not a cygwin compiler." >&2;} - { (exit 1); exit 1; }; } + as_fn_error $? "${CC} is not a cygwin compiler." "$LINENO" 5 fi if test "x${TCL_THREADS}" = "x0"; then - { { echo "$as_me:$LINENO: error: CYGWIN compile is only supported with --enable-threads" >&5 -echo "$as_me: error: CYGWIN compile is only supported with --enable-threads" >&2;} - { (exit 1); exit 1; }; } + as_fn_error $? "CYGWIN compile is only supported with --enable-threads" "$LINENO" 5 fi do64bit_ok=yes if test "x${SHARED_BUILD}" = "x1"; then @@ -7107,71 +5343,43 @@ echo "$as_me: error: CYGWIN compile is only supported with --enable-threads" >&2 SHLIB_LD='${CC} -shared ${CFLAGS} ${LDFLAGS}' DL_OBJS="tclLoadDl.o" DL_LIBS="-lroot" - echo "$as_me:$LINENO: checking for inet_ntoa in -lnetwork" >&5 -echo $ECHO_N "checking for inet_ntoa in -lnetwork... $ECHO_C" >&6 -if test "${ac_cv_lib_network_inet_ntoa+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for inet_ntoa in -lnetwork" >&5 +$as_echo_n "checking for inet_ntoa in -lnetwork... " >&6; } +if ${ac_cv_lib_network_inet_ntoa+:} false; then : + $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lnetwork $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF +cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -/* Override any gcc2 internal prototype to avoid an error. */ +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ char inet_ntoa (); int main () { -inet_ntoa (); +return inet_ntoa (); ; return 0; } _ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then +if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_network_inet_ntoa=yes else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_lib_network_inet_ntoa=no + ac_cv_lib_network_inet_ntoa=no fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -echo "$as_me:$LINENO: result: $ac_cv_lib_network_inet_ntoa" >&5 -echo "${ECHO_T}$ac_cv_lib_network_inet_ntoa" >&6 -if test $ac_cv_lib_network_inet_ntoa = yes; then +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_network_inet_ntoa" >&5 +$as_echo "$ac_cv_lib_network_inet_ntoa" >&6; } +if test "x$ac_cv_lib_network_inet_ntoa" = xyes; then : LIBS="$LIBS -lnetwork" fi @@ -7179,18 +5387,14 @@ fi HP-UX-*.11.*) # Use updated header definitions where possible -cat >>confdefs.h <<\_ACEOF -#define _XOPEN_SOURCE_EXTENDED 1 -_ACEOF +$as_echo "#define _XOPEN_SOURCE_EXTENDED 1" >>confdefs.h -cat >>confdefs.h <<\_ACEOF -#define _XOPEN_SOURCE 1 -_ACEOF +$as_echo "#define _XOPEN_SOURCE 1" >>confdefs.h LIBS="$LIBS -lxnet" # Use the XOPEN network library - if test "`uname -m`" = ia64; then + if test "`uname -m`" = ia64; then : SHLIB_SUFFIX=".so" @@ -7199,78 +5403,49 @@ else SHLIB_SUFFIX=".sl" fi - - echo "$as_me:$LINENO: checking for shl_load in -ldld" >&5 -echo $ECHO_N "checking for shl_load in -ldld... $ECHO_C" >&6 -if test "${ac_cv_lib_dld_shl_load+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5 +$as_echo_n "checking for shl_load in -ldld... " >&6; } +if ${ac_cv_lib_dld_shl_load+:} false; then : + $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF +cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -/* Override any gcc2 internal prototype to avoid an error. */ +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ char shl_load (); int main () { -shl_load (); +return shl_load (); ; return 0; } _ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then +if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dld_shl_load=yes else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_lib_dld_shl_load=no + ac_cv_lib_dld_shl_load=no fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -echo "$as_me:$LINENO: result: $ac_cv_lib_dld_shl_load" >&5 -echo "${ECHO_T}$ac_cv_lib_dld_shl_load" >&6 -if test $ac_cv_lib_dld_shl_load = yes; then +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5 +$as_echo "$ac_cv_lib_dld_shl_load" >&6; } +if test "x$ac_cv_lib_dld_shl_load" = xyes; then : tcl_ok=yes else tcl_ok=no fi - if test "$tcl_ok" = yes; then + if test "$tcl_ok" = yes; then : SHLIB_CFLAGS="+z" SHLIB_LD="ld -b" @@ -7282,8 +5457,7 @@ fi LD_LIBRARY_PATH_VAR="SHLIB_PATH" fi - - if test "$GCC" = yes; then + if test "$GCC" = yes; then : SHLIB_LD='${CC} -shared' LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} @@ -7294,30 +5468,28 @@ else fi - # Users may want PA-RISC 1.1/2.0 portable code - needs HP cc #CFLAGS="$CFLAGS +DAportable" # Check to enable 64-bit flags for compiler/linker - if test "$do64bit" = "yes"; then + if test "$do64bit" = "yes"; then : - if test "$GCC" = yes; then + if test "$GCC" = yes; then : case `${CC} -dumpmachine` in hppa64*) # 64-bit gcc in use. Fix flags for GNU ld. do64bit_ok=yes SHLIB_LD='${CC} -shared' - if test $doRpath = yes; then + if test $doRpath = yes; then : CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' fi - LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} ;; *) - { echo "$as_me:$LINENO: WARNING: 64bit mode not supported with GCC on $system" >&5 -echo "$as_me: WARNING: 64bit mode not supported with GCC on $system" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 64bit mode not supported with GCC on $system" >&5 +$as_echo "$as_me: WARNING: 64bit mode not supported with GCC on $system" >&2;} ;; esac @@ -7329,82 +5501,52 @@ else fi - -fi - ;; +fi ;; HP-UX-*.08.*|HP-UX-*.09.*|HP-UX-*.10.*) SHLIB_SUFFIX=".sl" - echo "$as_me:$LINENO: checking for shl_load in -ldld" >&5 -echo $ECHO_N "checking for shl_load in -ldld... $ECHO_C" >&6 -if test "${ac_cv_lib_dld_shl_load+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5 +$as_echo_n "checking for shl_load in -ldld... " >&6; } +if ${ac_cv_lib_dld_shl_load+:} false; then : + $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF +cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -/* Override any gcc2 internal prototype to avoid an error. */ +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ char shl_load (); int main () { -shl_load (); +return shl_load (); ; return 0; } _ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then +if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dld_shl_load=yes else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_lib_dld_shl_load=no + ac_cv_lib_dld_shl_load=no fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -echo "$as_me:$LINENO: result: $ac_cv_lib_dld_shl_load" >&5 -echo "${ECHO_T}$ac_cv_lib_dld_shl_load" >&6 -if test $ac_cv_lib_dld_shl_load = yes; then +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5 +$as_echo "$ac_cv_lib_dld_shl_load" >&6; } +if test "x$ac_cv_lib_dld_shl_load" = xyes; then : tcl_ok=yes else tcl_ok=no fi - if test "$tcl_ok" = yes; then + if test "$tcl_ok" = yes; then : SHLIB_CFLAGS="+z" SHLIB_LD="ld -b" @@ -7416,28 +5558,24 @@ fi LD_SEARCH_FLAGS='+s +b ${LIB_RUNTIME_DIR}:.' LD_LIBRARY_PATH_VAR="SHLIB_PATH" -fi - ;; +fi ;; IRIX-5.*) SHLIB_CFLAGS="" SHLIB_LD="ld -shared -rdata_shared" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" - case $LIBOBJS in - "mkstemp.$ac_objext" | \ - *" mkstemp.$ac_objext" | \ - "mkstemp.$ac_objext "* | \ + case " $LIBOBJS " in *" mkstemp.$ac_objext "* ) ;; - *) LIBOBJS="$LIBOBJS mkstemp.$ac_objext" ;; + *) LIBOBJS="$LIBOBJS mkstemp.$ac_objext" + ;; esac - if test $doRpath = yes; then + if test $doRpath = yes; then : CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}' fi - ;; IRIX-6.*) SHLIB_CFLAGS="" @@ -7445,21 +5583,18 @@ fi SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" - case $LIBOBJS in - "mkstemp.$ac_objext" | \ - *" mkstemp.$ac_objext" | \ - "mkstemp.$ac_objext "* | \ + case " $LIBOBJS " in *" mkstemp.$ac_objext "* ) ;; - *) LIBOBJS="$LIBOBJS mkstemp.$ac_objext" ;; + *) LIBOBJS="$LIBOBJS mkstemp.$ac_objext" + ;; esac - if test $doRpath = yes; then + if test $doRpath = yes; then : CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}' fi - - if test "$GCC" = yes; then + if test "$GCC" = yes; then : CFLAGS="$CFLAGS -mabi=n32" LDFLAGS="$LDFLAGS -mabi=n32" @@ -7478,7 +5613,6 @@ else LDFLAGS="$LDFLAGS -n32" fi - ;; IRIX64-6.*) SHLIB_CFLAGS="" @@ -7486,29 +5620,26 @@ fi SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" - case $LIBOBJS in - "mkstemp.$ac_objext" | \ - *" mkstemp.$ac_objext" | \ - "mkstemp.$ac_objext "* | \ + case " $LIBOBJS " in *" mkstemp.$ac_objext "* ) ;; - *) LIBOBJS="$LIBOBJS mkstemp.$ac_objext" ;; + *) LIBOBJS="$LIBOBJS mkstemp.$ac_objext" + ;; esac - if test $doRpath = yes; then + if test $doRpath = yes; then : CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}' fi - # Check to enable 64-bit flags for compiler/linker - if test "$do64bit" = yes; then + if test "$do64bit" = yes; then : - if test "$GCC" = yes; then + if test "$GCC" = yes; then : - { echo "$as_me:$LINENO: WARNING: 64bit mode not supported by gcc" >&5 -echo "$as_me: WARNING: 64bit mode not supported by gcc" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 64bit mode not supported by gcc" >&5 +$as_echo "$as_me: WARNING: 64bit mode not supported by gcc" >&2;} else @@ -7519,9 +5650,7 @@ else fi - fi - ;; Linux*|GNU*|NetBSD-Debian) SHLIB_CFLAGS="-fPIC" @@ -7537,31 +5666,25 @@ fi DL_OBJS="tclLoadDl.o" DL_LIBS="-ldl" LDFLAGS="$LDFLAGS -Wl,--export-dynamic" - if test $doRpath = yes; then + if test $doRpath = yes; then : CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' fi - LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} - if test "`uname -m`" = "alpha"; then + if test "`uname -m`" = "alpha"; then : CFLAGS="$CFLAGS -mieee" fi + if test $do64bit = yes; then : - if test $do64bit = yes; then - - echo "$as_me:$LINENO: checking if compiler accepts -m64 flag" >&5 -echo $ECHO_N "checking if compiler accepts -m64 flag... $ECHO_C" >&6 -if test "${tcl_cv_cc_m64+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if compiler accepts -m64 flag" >&5 +$as_echo_n "checking if compiler accepts -m64 flag... " >&6; } +if ${tcl_cv_cc_m64+:} false; then : + $as_echo_n "(cached) " >&6 else hold_cflags=$CFLAGS CFLAGS="$CFLAGS -m64" - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int @@ -7572,62 +5695,35 @@ main () return 0; } _ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then +if ac_fn_c_try_link "$LINENO"; then : tcl_cv_cc_m64=yes else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -tcl_cv_cc_m64=no + tcl_cv_cc_m64=no fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext CFLAGS=$hold_cflags fi -echo "$as_me:$LINENO: result: $tcl_cv_cc_m64" >&5 -echo "${ECHO_T}$tcl_cv_cc_m64" >&6 - if test $tcl_cv_cc_m64 = yes; then +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_cc_m64" >&5 +$as_echo "$tcl_cv_cc_m64" >&6; } + if test $tcl_cv_cc_m64 = yes; then : CFLAGS="$CFLAGS -m64" do64bit_ok=yes fi - fi - # The combo of gcc + glibc has a bug related to inlining of # functions like strtod(). The -fno-builtin flag should address # this problem but it does not work. The -fno-inline flag is kind # of overkill but it works. Disable inlining only when one of the # files in compat/*.c is being linked in. - if test x"${USE_COMPAT}" != x; then + if test x"${USE_COMPAT}" != x; then : CFLAGS="$CFLAGS -fno-inline" fi - ;; Lynx*) SHLIB_CFLAGS="-fPIC" @@ -7637,12 +5733,11 @@ fi DL_OBJS="tclLoadDl.o" DL_LIBS="-mshared -ldl" LD_FLAGS="-Wl,--export-dynamic" - if test $doRpath = yes; then + if test $doRpath = yes; then : CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' fi - ;; MP-RAS-02*) SHLIB_CFLAGS="-K PIC" @@ -7681,11 +5776,10 @@ fi SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" - if test $doRpath = yes; then + if test $doRpath = yes; then : CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' fi - LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.${SHLIB_VERSION}' LDFLAGS="-Wl,-export-dynamic" @@ -7702,7 +5796,7 @@ fi CFLAGS_OPTIMIZE="-O2" ;; esac - if test "${TCL_THREADS}" = "1"; then + if test "${TCL_THREADS}" = "1"; then : # On OpenBSD: Compile with -pthread # Don't link with -lpthread @@ -7710,7 +5804,6 @@ fi CFLAGS="$CFLAGS -pthread" fi - # OpenBSD doesn't do version numbers with dots. UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a' TCL_LIB_VERSIONS_OK=nodots @@ -7723,13 +5816,12 @@ fi DL_OBJS="tclLoadDl.o" DL_LIBS="" LDFLAGS="$LDFLAGS -export-dynamic" - if test $doRpath = yes; then + if test $doRpath = yes; then : CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' fi - LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} - if test "${TCL_THREADS}" = "1"; then + if test "${TCL_THREADS}" = "1"; then : # The -pthread needs to go in the CFLAGS, not LIBS LIBS=`echo $LIBS | sed s/-pthread//` @@ -7737,7 +5829,6 @@ fi LDFLAGS="$LDFLAGS -pthread" fi - ;; FreeBSD-*) # This configuration from FreeBSD Ports. @@ -7748,20 +5839,18 @@ fi DL_OBJS="tclLoadDl.o" DL_LIBS="" LDFLAGS="" - if test $doRpath = yes; then + if test $doRpath = yes; then : CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' fi - - if test "${TCL_THREADS}" = "1"; then + if test "${TCL_THREADS}" = "1"; then : # The -pthread needs to go in the LDFLAGS, not LIBS LIBS=`echo $LIBS | sed s/-pthread//` CFLAGS="$CFLAGS $PTHREAD_CFLAGS" LDFLAGS="$LDFLAGS $PTHREAD_LIBS" fi - case $system in FreeBSD-3.*) # Version numbers are dot-stripped by system policy. @@ -7784,23 +5873,19 @@ fi CFLAGS="`echo " ${CFLAGS}" | \ awk 'BEGIN {FS=" +-";ORS=" "}; {for (i=2;i<=NF;i++) \ if (!($i~/^(isysroot|mmacosx-version-min)/)) print "-"$i}'`" - if test $do64bit = yes; then + if test $do64bit = yes; then : case `arch` in ppc) - echo "$as_me:$LINENO: checking if compiler accepts -arch ppc64 flag" >&5 -echo $ECHO_N "checking if compiler accepts -arch ppc64 flag... $ECHO_C" >&6 -if test "${tcl_cv_cc_arch_ppc64+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if compiler accepts -arch ppc64 flag" >&5 +$as_echo_n "checking if compiler accepts -arch ppc64 flag... " >&6; } +if ${tcl_cv_cc_arch_ppc64+:} false; then : + $as_echo_n "(cached) " >&6 else hold_cflags=$CFLAGS CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5" - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int @@ -7811,62 +5896,33 @@ main () return 0; } _ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then +if ac_fn_c_try_link "$LINENO"; then : tcl_cv_cc_arch_ppc64=yes else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -tcl_cv_cc_arch_ppc64=no + tcl_cv_cc_arch_ppc64=no fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext CFLAGS=$hold_cflags fi -echo "$as_me:$LINENO: result: $tcl_cv_cc_arch_ppc64" >&5 -echo "${ECHO_T}$tcl_cv_cc_arch_ppc64" >&6 - if test $tcl_cv_cc_arch_ppc64 = yes; then +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_cc_arch_ppc64" >&5 +$as_echo "$tcl_cv_cc_arch_ppc64" >&6; } + if test $tcl_cv_cc_arch_ppc64 = yes; then : CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5" do64bit_ok=yes -fi -;; +fi;; i386) - echo "$as_me:$LINENO: checking if compiler accepts -arch x86_64 flag" >&5 -echo $ECHO_N "checking if compiler accepts -arch x86_64 flag... $ECHO_C" >&6 -if test "${tcl_cv_cc_arch_x86_64+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if compiler accepts -arch x86_64 flag" >&5 +$as_echo_n "checking if compiler accepts -arch x86_64 flag... " >&6; } +if ${tcl_cv_cc_arch_x86_64+:} false; then : + $as_echo_n "(cached) " >&6 else hold_cflags=$CFLAGS CFLAGS="$CFLAGS -arch x86_64" - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int @@ -7877,79 +5933,48 @@ main () return 0; } _ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then +if ac_fn_c_try_link "$LINENO"; then : tcl_cv_cc_arch_x86_64=yes else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -tcl_cv_cc_arch_x86_64=no + tcl_cv_cc_arch_x86_64=no fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext CFLAGS=$hold_cflags fi -echo "$as_me:$LINENO: result: $tcl_cv_cc_arch_x86_64" >&5 -echo "${ECHO_T}$tcl_cv_cc_arch_x86_64" >&6 - if test $tcl_cv_cc_arch_x86_64 = yes; then +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_cc_arch_x86_64" >&5 +$as_echo "$tcl_cv_cc_arch_x86_64" >&6; } + if test $tcl_cv_cc_arch_x86_64 = yes; then : CFLAGS="$CFLAGS -arch x86_64" do64bit_ok=yes -fi -;; +fi;; *) - { echo "$as_me:$LINENO: WARNING: Don't know how enable 64-bit on architecture \`arch\`" >&5 -echo "$as_me: WARNING: Don't know how enable 64-bit on architecture \`arch\`" >&2;};; + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Don't know how enable 64-bit on architecture \`arch\`" >&5 +$as_echo "$as_me: WARNING: Don't know how enable 64-bit on architecture \`arch\`" >&2;};; esac else # Check for combined 32-bit and 64-bit fat build if echo "$CFLAGS " |grep -E -q -- '-arch (ppc64|x86_64) ' \ - && echo "$CFLAGS " |grep -E -q -- '-arch (ppc|i386) '; then + && echo "$CFLAGS " |grep -E -q -- '-arch (ppc|i386) '; then : fat_32_64=yes fi - fi - SHLIB_LD='${CC} -dynamiclib ${CFLAGS} ${LDFLAGS}' - echo "$as_me:$LINENO: checking if ld accepts -single_module flag" >&5 -echo $ECHO_N "checking if ld accepts -single_module flag... $ECHO_C" >&6 -if test "${tcl_cv_ld_single_module+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if ld accepts -single_module flag" >&5 +$as_echo_n "checking if ld accepts -single_module flag... " >&6; } +if ${tcl_cv_ld_single_module+:} false; then : + $as_echo_n "(cached) " >&6 else hold_ldflags=$LDFLAGS LDFLAGS="$LDFLAGS -dynamiclib -Wl,-single_module" - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int @@ -7960,71 +5985,41 @@ int i; return 0; } _ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then +if ac_fn_c_try_link "$LINENO"; then : tcl_cv_ld_single_module=yes else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -tcl_cv_ld_single_module=no + tcl_cv_ld_single_module=no fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext LDFLAGS=$hold_ldflags fi -echo "$as_me:$LINENO: result: $tcl_cv_ld_single_module" >&5 -echo "${ECHO_T}$tcl_cv_ld_single_module" >&6 - if test $tcl_cv_ld_single_module = yes; then +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_ld_single_module" >&5 +$as_echo "$tcl_cv_ld_single_module" >&6; } + if test $tcl_cv_ld_single_module = yes; then : SHLIB_LD="${SHLIB_LD} -Wl,-single_module" fi - SHLIB_SUFFIX=".dylib" DL_OBJS="tclLoadDyld.o" DL_LIBS="" # Don't use -prebind when building for Mac OS X 10.4 or later only: if test "`echo "${MACOSX_DEPLOYMENT_TARGET}" | awk -F '10\\.' '{print int($2)}'`" -lt 4 -a \ - "`echo "${CPPFLAGS}" | awk -F '-mmacosx-version-min=10\\.' '{print int($2)}'`" -lt 4; then + "`echo "${CPPFLAGS}" | awk -F '-mmacosx-version-min=10\\.' '{print int($2)}'`" -lt 4; then : LDFLAGS="$LDFLAGS -prebind" fi - LDFLAGS="$LDFLAGS -headerpad_max_install_names" - echo "$as_me:$LINENO: checking if ld accepts -search_paths_first flag" >&5 -echo $ECHO_N "checking if ld accepts -search_paths_first flag... $ECHO_C" >&6 -if test "${tcl_cv_ld_search_paths_first+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if ld accepts -search_paths_first flag" >&5 +$as_echo_n "checking if ld accepts -search_paths_first flag... " >&6; } +if ${tcl_cv_ld_search_paths_first+:} false; then : + $as_echo_n "(cached) " >&6 else hold_ldflags=$LDFLAGS LDFLAGS="$LDFLAGS -Wl,-search_paths_first" - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int @@ -8035,88 +6030,58 @@ int i; return 0; } _ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then +if ac_fn_c_try_link "$LINENO"; then : tcl_cv_ld_search_paths_first=yes else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -tcl_cv_ld_search_paths_first=no + tcl_cv_ld_search_paths_first=no fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext LDFLAGS=$hold_ldflags fi -echo "$as_me:$LINENO: result: $tcl_cv_ld_search_paths_first" >&5 -echo "${ECHO_T}$tcl_cv_ld_search_paths_first" >&6 - if test $tcl_cv_ld_search_paths_first = yes; then +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_ld_search_paths_first" >&5 +$as_echo "$tcl_cv_ld_search_paths_first" >&6; } + if test $tcl_cv_ld_search_paths_first = yes; then : LDFLAGS="$LDFLAGS -Wl,-search_paths_first" fi + if test "$tcl_cv_cc_visibility_hidden" != yes; then : - if test "$tcl_cv_cc_visibility_hidden" != yes; then - -cat >>confdefs.h <<\_ACEOF -#define MODULE_SCOPE __private_extern__ -_ACEOF +$as_echo "#define MODULE_SCOPE __private_extern__" >>confdefs.h fi - CC_SEARCH_FLAGS="" LD_SEARCH_FLAGS="" LD_LIBRARY_PATH_VAR="DYLD_LIBRARY_PATH" -cat >>confdefs.h <<\_ACEOF -#define MAC_OSX_TCL 1 -_ACEOF +$as_echo "#define MAC_OSX_TCL 1" >>confdefs.h PLAT_OBJS='${MAC_OSX_OBJS}' PLAT_SRCS='${MAC_OSX_SRCS}' - echo "$as_me:$LINENO: checking whether to use CoreFoundation" >&5 -echo $ECHO_N "checking whether to use CoreFoundation... $ECHO_C" >&6 - # Check whether --enable-corefoundation or --disable-corefoundation was given. -if test "${enable_corefoundation+set}" = set; then - enableval="$enable_corefoundation" - tcl_corefoundation=$enableval + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use CoreFoundation" >&5 +$as_echo_n "checking whether to use CoreFoundation... " >&6; } + # Check whether --enable-corefoundation was given. +if test "${enable_corefoundation+set}" = set; then : + enableval=$enable_corefoundation; tcl_corefoundation=$enableval else tcl_corefoundation=yes -fi; - echo "$as_me:$LINENO: result: $tcl_corefoundation" >&5 -echo "${ECHO_T}$tcl_corefoundation" >&6 - if test $tcl_corefoundation = yes; then +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_corefoundation" >&5 +$as_echo "$tcl_corefoundation" >&6; } + if test $tcl_corefoundation = yes; then : - echo "$as_me:$LINENO: checking for CoreFoundation.framework" >&5 -echo $ECHO_N "checking for CoreFoundation.framework... $ECHO_C" >&6 -if test "${tcl_cv_lib_corefoundation+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for CoreFoundation.framework" >&5 +$as_echo_n "checking for CoreFoundation.framework... " >&6; } +if ${tcl_cv_lib_corefoundation+:} false; then : + $as_echo_n "(cached) " >&6 else hold_libs=$LIBS - if test "$fat_32_64" = yes; then + if test "$fat_32_64" = yes; then : for v in CFLAGS CPPFLAGS LDFLAGS; do # On Tiger there is no 64-bit CF, so remove 64-bit @@ -8126,13 +6091,8 @@ else eval 'hold_'$v'="$'$v'";'$v'="`echo "$'$v' "|sed -e "s/-arch ppc64 / /g" -e "s/-arch x86_64 / /g"`"' done fi - LIBS="$LIBS -framework CoreFoundation" - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int @@ -8143,77 +6103,45 @@ CFBundleRef b = CFBundleGetMainBundle(); return 0; } _ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then +if ac_fn_c_try_link "$LINENO"; then : tcl_cv_lib_corefoundation=yes else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -tcl_cv_lib_corefoundation=no + tcl_cv_lib_corefoundation=no fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - if test "$fat_32_64" = yes; then +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if test "$fat_32_64" = yes; then : for v in CFLAGS CPPFLAGS LDFLAGS; do eval $v'="$hold_'$v'"' done fi - LIBS=$hold_libs fi -echo "$as_me:$LINENO: result: $tcl_cv_lib_corefoundation" >&5 -echo "${ECHO_T}$tcl_cv_lib_corefoundation" >&6 - if test $tcl_cv_lib_corefoundation = yes; then +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_lib_corefoundation" >&5 +$as_echo "$tcl_cv_lib_corefoundation" >&6; } + if test $tcl_cv_lib_corefoundation = yes; then : LIBS="$LIBS -framework CoreFoundation" -cat >>confdefs.h <<\_ACEOF -#define HAVE_COREFOUNDATION 1 -_ACEOF +$as_echo "#define HAVE_COREFOUNDATION 1" >>confdefs.h else tcl_corefoundation=no fi + if test "$fat_32_64" = yes -a $tcl_corefoundation = yes; then : - if test "$fat_32_64" = yes -a $tcl_corefoundation = yes; then - - echo "$as_me:$LINENO: checking for 64-bit CoreFoundation" >&5 -echo $ECHO_N "checking for 64-bit CoreFoundation... $ECHO_C" >&6 -if test "${tcl_cv_lib_corefoundation_64+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for 64-bit CoreFoundation" >&5 +$as_echo_n "checking for 64-bit CoreFoundation... " >&6; } +if ${tcl_cv_lib_corefoundation_64+:} false; then : + $as_echo_n "(cached) " >&6 else for v in CFLAGS CPPFLAGS LDFLAGS; do eval 'hold_'$v'="$'$v'";'$v'="`echo "$'$v' "|sed -e "s/-arch ppc / /g" -e "s/-arch i386 / /g"`"' done - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int @@ -8224,60 +6152,31 @@ CFBundleRef b = CFBundleGetMainBundle(); return 0; } _ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then +if ac_fn_c_try_link "$LINENO"; then : tcl_cv_lib_corefoundation_64=yes else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -tcl_cv_lib_corefoundation_64=no + tcl_cv_lib_corefoundation_64=no fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext for v in CFLAGS CPPFLAGS LDFLAGS; do eval $v'="$hold_'$v'"' done fi -echo "$as_me:$LINENO: result: $tcl_cv_lib_corefoundation_64" >&5 -echo "${ECHO_T}$tcl_cv_lib_corefoundation_64" >&6 - if test $tcl_cv_lib_corefoundation_64 = no; then +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_lib_corefoundation_64" >&5 +$as_echo "$tcl_cv_lib_corefoundation_64" >&6; } + if test $tcl_cv_lib_corefoundation_64 = no; then : -cat >>confdefs.h <<\_ACEOF -#define NO_COREFOUNDATION_64 1 -_ACEOF +$as_echo "#define NO_COREFOUNDATION_64 1" >>confdefs.h LDFLAGS="$LDFLAGS -Wl,-no_arch_warnings" fi - fi - fi - ;; NEXTSTEP-*) SHLIB_CFLAGS="" @@ -8293,9 +6192,7 @@ fi SHLIB_LD_LIBS="" CFLAGS_OPTIMIZE="" # Optimizer is buggy -cat >>confdefs.h <<\_ACEOF -#define _OE_SOCKETS 1 -_ACEOF +$as_echo "#define _OE_SOCKETS 1" >>confdefs.h ;; OSF1-1.0|OSF1-1.1|OSF1-1.2) @@ -8313,14 +6210,13 @@ _ACEOF OSF1-1.*) # OSF/1 1.3 from OSF using ELF, and derivatives, including AD2 SHLIB_CFLAGS="-fPIC" - if test "$SHARED_BUILD" = 1; then + if test "$SHARED_BUILD" = 1; then : SHLIB_LD="ld -shared" else SHLIB_LD="ld -non_shared" fi - SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" @@ -8331,7 +6227,7 @@ fi OSF1-V*) # Digital OSF/1 SHLIB_CFLAGS="" - if test "$SHARED_BUILD" = 1; then + if test "$SHARED_BUILD" = 1; then : SHLIB_LD='ld -shared -expect_unresolved "*"' @@ -8340,30 +6236,27 @@ else SHLIB_LD='ld -non_shared -expect_unresolved "*"' fi - SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" - if test $doRpath = yes; then + if test $doRpath = yes; then : CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}' fi - - if test "$GCC" = yes; then + if test "$GCC" = yes; then : CFLAGS="$CFLAGS -mieee" else CFLAGS="$CFLAGS -DHAVE_TZSET -std1 -ieee" fi - # see pthread_intro(3) for pthread support on osf1, k.furukawa - if test "${TCL_THREADS}" = 1; then + if test "${TCL_THREADS}" = 1; then : CFLAGS="$CFLAGS -DHAVE_PTHREAD_ATTR_SETSTACKSIZE" CFLAGS="$CFLAGS -DTCL_THREAD_STACK_MIN=PTHREAD_STACK_MIN*64" LIBS=`echo $LIBS | sed s/-lpthreads//` - if test "$GCC" = yes; then + if test "$GCC" = yes; then : LIBS="$LIBS -lpthread -lmach -lexc" @@ -8374,9 +6267,7 @@ else fi - fi - ;; QNX-6*) # QNX RTP @@ -8395,7 +6286,7 @@ fi # Note, dlopen is available only on SCO 3.2.5 and greater. However, # this test works, since "uname -s" was non-standard in 3.2.4 and # below. - if test "$GCC" = yes; then + if test "$GCC" = yes; then : SHLIB_CFLAGS="-fPIC -melf" LDFLAGS="$LDFLAGS -melf -Wl,-Bexport" @@ -8406,7 +6297,6 @@ else LDFLAGS="$LDFLAGS -belf -Wl,-Bexport" fi - SHLIB_LD="ld -G" SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" @@ -8451,21 +6341,17 @@ fi # won't define thread-safe library routines. -cat >>confdefs.h <<\_ACEOF -#define _REENTRANT 1 -_ACEOF +$as_echo "#define _REENTRANT 1" >>confdefs.h -cat >>confdefs.h <<\_ACEOF -#define _POSIX_PTHREAD_SEMANTICS 1 -_ACEOF +$as_echo "#define _POSIX_PTHREAD_SEMANTICS 1" >>confdefs.h SHLIB_CFLAGS="-KPIC" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="-ldl" - if test "$GCC" = yes; then + if test "$GCC" = yes; then : SHLIB_LD='${CC} -shared' CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}' @@ -8478,37 +6364,32 @@ else LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} fi - ;; SunOS-5*) # Note: If _REENTRANT isn't defined, then Solaris # won't define thread-safe library routines. -cat >>confdefs.h <<\_ACEOF -#define _REENTRANT 1 -_ACEOF +$as_echo "#define _REENTRANT 1" >>confdefs.h -cat >>confdefs.h <<\_ACEOF -#define _POSIX_PTHREAD_SEMANTICS 1 -_ACEOF +$as_echo "#define _POSIX_PTHREAD_SEMANTICS 1" >>confdefs.h SHLIB_CFLAGS="-KPIC" # Check to enable 64-bit flags for compiler/linker - if test "$do64bit" = yes; then + if test "$do64bit" = yes; then : arch=`isainfo` - if test "$arch" = "sparcv9 sparc"; then + if test "$arch" = "sparcv9 sparc"; then : - if test "$GCC" = yes; then + if test "$GCC" = yes; then : - if test "`${CC} -dumpversion | awk -F. '{print $1}'`" -lt 3; then + if test "`${CC} -dumpversion | awk -F. '{print $1}'`" -lt 3; then : - { echo "$as_me:$LINENO: WARNING: 64bit mode not supported with GCC < 3.2 on $system" >&5 -echo "$as_me: WARNING: 64bit mode not supported with GCC < 3.2 on $system" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 64bit mode not supported with GCC < 3.2 on $system" >&5 +$as_echo "$as_me: WARNING: 64bit mode not supported with GCC < 3.2 on $system" >&2;} else @@ -8519,11 +6400,10 @@ else fi - else do64bit_ok=yes - if test "$do64bitVIS" = yes; then + if test "$do64bitVIS" = yes; then : CFLAGS="$CFLAGS -xarch=v9a" LDFLAGS_ARCH="-xarch=v9a" @@ -8534,17 +6414,15 @@ else LDFLAGS_ARCH="-xarch=v9" fi - # Solaris 64 uses this as well #LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH_64" fi - else - if test "$arch" = "amd64 i386"; then + if test "$arch" = "amd64 i386"; then : - if test "$GCC" = yes; then + if test "$GCC" = yes; then : case $system in SunOS-5.1[1-9]*|SunOS-5.[2-9][0-9]*) @@ -8552,8 +6430,8 @@ else CFLAGS="$CFLAGS -m64" LDFLAGS="$LDFLAGS -m64";; *) - { echo "$as_me:$LINENO: WARNING: 64bit mode not supported with GCC on $system" >&5 -echo "$as_me: WARNING: 64bit mode not supported with GCC on $system" >&2;};; + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 64bit mode not supported with GCC on $system" >&5 +$as_echo "$as_me: WARNING: 64bit mode not supported with GCC on $system" >&2;};; esac else @@ -8570,169 +6448,32 @@ else fi - else - { echo "$as_me:$LINENO: WARNING: 64bit mode not supported for $arch" >&5 -echo "$as_me: WARNING: 64bit mode not supported for $arch" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 64bit mode not supported for $arch" >&5 +$as_echo "$as_me: WARNING: 64bit mode not supported for $arch" >&2;} fi - fi - fi - #-------------------------------------------------------------------- # On Solaris 5.x i386 with the sunpro compiler we need to link # with sunmath to get floating point rounding control #-------------------------------------------------------------------- - if test "$GCC" = yes; then + if test "$GCC" = yes; then : use_sunmath=no else arch=`isainfo` - echo "$as_me:$LINENO: checking whether to use -lsunmath for fp rounding control" >&5 -echo $ECHO_N "checking whether to use -lsunmath for fp rounding control... $ECHO_C" >&6 - if test "$arch" = "amd64 i386" -o "$arch" = "i386"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use -lsunmath for fp rounding control" >&5 +$as_echo_n "checking whether to use -lsunmath for fp rounding control... " >&6; } + if test "$arch" = "amd64 i386" -o "$arch" = "i386"; then : - echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } MATH_LIBS="-lsunmath $MATH_LIBS" - if test "${ac_cv_header_sunmath_h+set}" = set; then - echo "$as_me:$LINENO: checking for sunmath.h" >&5 -echo $ECHO_N "checking for sunmath.h... $ECHO_C" >&6 -if test "${ac_cv_header_sunmath_h+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -fi -echo "$as_me:$LINENO: result: $ac_cv_header_sunmath_h" >&5 -echo "${ECHO_T}$ac_cv_header_sunmath_h" >&6 -else - # Is the header compilable? -echo "$as_me:$LINENO: checking sunmath.h usability" >&5 -echo $ECHO_N "checking sunmath.h usability... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -#include -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_header_compiler=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_header_compiler=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -echo "${ECHO_T}$ac_header_compiler" >&6 - -# Is the header present? -echo "$as_me:$LINENO: checking sunmath.h presence" >&5 -echo $ECHO_N "checking sunmath.h presence... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -_ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - ac_header_preproc=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_header_preproc=no -fi -rm -f conftest.err conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -echo "${ECHO_T}$ac_header_preproc" >&6 - -# So? What about this header? -case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in - yes:no: ) - { echo "$as_me:$LINENO: WARNING: sunmath.h: accepted by the compiler, rejected by the preprocessor!" >&5 -echo "$as_me: WARNING: sunmath.h: accepted by the compiler, rejected by the preprocessor!" >&2;} - { echo "$as_me:$LINENO: WARNING: sunmath.h: proceeding with the compiler's result" >&5 -echo "$as_me: WARNING: sunmath.h: proceeding with the compiler's result" >&2;} - ac_header_preproc=yes - ;; - no:yes:* ) - { echo "$as_me:$LINENO: WARNING: sunmath.h: present but cannot be compiled" >&5 -echo "$as_me: WARNING: sunmath.h: present but cannot be compiled" >&2;} - { echo "$as_me:$LINENO: WARNING: sunmath.h: check for missing prerequisite headers?" >&5 -echo "$as_me: WARNING: sunmath.h: check for missing prerequisite headers?" >&2;} - { echo "$as_me:$LINENO: WARNING: sunmath.h: see the Autoconf documentation" >&5 -echo "$as_me: WARNING: sunmath.h: see the Autoconf documentation" >&2;} - { echo "$as_me:$LINENO: WARNING: sunmath.h: section \"Present But Cannot Be Compiled\"" >&5 -echo "$as_me: WARNING: sunmath.h: section \"Present But Cannot Be Compiled\"" >&2;} - { echo "$as_me:$LINENO: WARNING: sunmath.h: proceeding with the preprocessor's result" >&5 -echo "$as_me: WARNING: sunmath.h: proceeding with the preprocessor's result" >&2;} - { echo "$as_me:$LINENO: WARNING: sunmath.h: in the future, the compiler will take precedence" >&5 -echo "$as_me: WARNING: sunmath.h: in the future, the compiler will take precedence" >&2;} - ( - cat <<\_ASBOX -## ------------------------------ ## -## Report this to the tcl lists. ## -## ------------------------------ ## -_ASBOX - ) | - sed "s/^/$as_me: WARNING: /" >&2 - ;; -esac -echo "$as_me:$LINENO: checking for sunmath.h" >&5 -echo $ECHO_N "checking for sunmath.h... $ECHO_C" >&6 -if test "${ac_cv_header_sunmath_h+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_cv_header_sunmath_h=$ac_header_preproc -fi -echo "$as_me:$LINENO: result: $ac_cv_header_sunmath_h" >&5 -echo "${ECHO_T}$ac_cv_header_sunmath_h" >&6 + ac_fn_c_check_header_mongrel "$LINENO" "sunmath.h" "ac_cv_header_sunmath_h" "$ac_includes_default" +if test "x$ac_cv_header_sunmath_h" = xyes; then : fi @@ -8741,26 +6482,24 @@ fi else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } use_sunmath=no fi - fi - SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="-ldl" - if test "$GCC" = yes; then + if test "$GCC" = yes; then : SHLIB_LD='${CC} -shared' CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}' LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} - if test "$do64bit_ok" = yes; then + if test "$do64bit_ok" = yes; then : - if test "$arch" = "sparcv9 sparc"; then + if test "$arch" = "sparcv9 sparc"; then : # We need to specify -static-libgcc or we need to # add the path to the sparv9 libgcc. @@ -8771,26 +6510,22 @@ fi #CC_SEARCH_FLAGS="${CC_SEARCH_FLAGS},-R,$v9gcclibdir" else - if test "$arch" = "amd64 i386"; then + if test "$arch" = "amd64 i386"; then : SHLIB_LD="$SHLIB_LD -m64 -static-libgcc" fi - fi - fi - else - if test "$use_sunmath" = yes; then + if test "$use_sunmath" = yes; then : textmode=textoff else textmode=text fi - case $system in SunOS-5.[1-9][0-9]*|SunOS-5.[7-9]) SHLIB_LD="\${CC} -G -z $textmode \${LDFLAGS}";; @@ -8801,7 +6536,6 @@ fi LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}' fi - ;; UNIX_SV* | UnixWare-5*) SHLIB_CFLAGS="-KPIC" @@ -8812,19 +6546,15 @@ fi DL_LIBS="-ldl" # Some UNIX_SV* systems (unixware 1.1.2 for example) have linkers # that don't grok the -Bexport option. Test that it does. - echo "$as_me:$LINENO: checking for ld accepts -Bexport flag" >&5 -echo $ECHO_N "checking for ld accepts -Bexport flag... $ECHO_C" >&6 -if test "${tcl_cv_ld_Bexport+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld accepts -Bexport flag" >&5 +$as_echo_n "checking for ld accepts -Bexport flag... " >&6; } +if ${tcl_cv_ld_Bexport+:} false; then : + $as_echo_n "(cached) " >&6 else hold_ldflags=$LDFLAGS LDFLAGS="$LDFLAGS -Wl,-Bexport" - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int @@ -8835,93 +6565,63 @@ int i; return 0; } _ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then +if ac_fn_c_try_link "$LINENO"; then : tcl_cv_ld_Bexport=yes else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -tcl_cv_ld_Bexport=no + tcl_cv_ld_Bexport=no fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext LDFLAGS=$hold_ldflags fi -echo "$as_me:$LINENO: result: $tcl_cv_ld_Bexport" >&5 -echo "${ECHO_T}$tcl_cv_ld_Bexport" >&6 - if test $tcl_cv_ld_Bexport = yes; then +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_ld_Bexport" >&5 +$as_echo "$tcl_cv_ld_Bexport" >&6; } + if test $tcl_cv_ld_Bexport = yes; then : LDFLAGS="$LDFLAGS -Wl,-Bexport" fi - CC_SEARCH_FLAGS="" LD_SEARCH_FLAGS="" ;; esac - if test "$do64bit" = yes -a "$do64bit_ok" = no; then + if test "$do64bit" = yes -a "$do64bit_ok" = no; then : - { echo "$as_me:$LINENO: WARNING: 64bit support being disabled -- don't know magic for this platform" >&5 -echo "$as_me: WARNING: 64bit support being disabled -- don't know magic for this platform" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 64bit support being disabled -- don't know magic for this platform" >&5 +$as_echo "$as_me: WARNING: 64bit support being disabled -- don't know magic for this platform" >&2;} fi + if test "$do64bit" = yes -a "$do64bit_ok" = yes; then : - if test "$do64bit" = yes -a "$do64bit_ok" = yes; then - -cat >>confdefs.h <<\_ACEOF -#define TCL_CFG_DO64BIT 1 -_ACEOF +$as_echo "#define TCL_CFG_DO64BIT 1" >>confdefs.h fi - # Step 4: disable dynamic loading if requested via a command-line switch. - # Check whether --enable-load or --disable-load was given. -if test "${enable_load+set}" = set; then - enableval="$enable_load" - tcl_ok=$enableval + # Check whether --enable-load was given. +if test "${enable_load+set}" = set; then : + enableval=$enable_load; tcl_ok=$enableval else tcl_ok=yes -fi; - if test "$tcl_ok" = no; then - DL_OBJS="" fi + if test "$tcl_ok" = no; then : + DL_OBJS="" +fi - if test "x$DL_OBJS" != x; then + if test "x$DL_OBJS" != x; then : BUILD_DLTEST="\$(DLTEST_TARGETS)" else - { echo "$as_me:$LINENO: WARNING: Can't figure out how to do dynamic loading or shared libraries on this system." >&5 -echo "$as_me: WARNING: Can't figure out how to do dynamic loading or shared libraries on this system." >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Can't figure out how to do dynamic loading or shared libraries on this system." >&5 +$as_echo "$as_me: WARNING: Can't figure out how to do dynamic loading or shared libraries on this system." >&2;} SHLIB_CFLAGS="" SHLIB_LD="" SHLIB_SUFFIX="" @@ -8933,14 +6633,13 @@ echo "$as_me: WARNING: Can't figure out how to do dynamic loading or shared libr BUILD_DLTEST="" fi - LDFLAGS="$LDFLAGS $LDFLAGS_ARCH" # If we're running gcc, then change the C flags for compiling shared # libraries to the right flags for gcc, instead of those for the # standard manufacturer compiler. - if test "$DL_OBJS" != "tclLoadNone.o" -a "$GCC" = yes; then + if test "$DL_OBJS" != "tclLoadNone.o" -a "$GCC" = yes; then : case $system in AIX-*) ;; @@ -8954,35 +6653,29 @@ fi esac fi - - if test "$tcl_cv_cc_visibility_hidden" != yes; then + if test "$tcl_cv_cc_visibility_hidden" != yes; then : -cat >>confdefs.h <<\_ACEOF -#define MODULE_SCOPE extern -_ACEOF +$as_echo "#define MODULE_SCOPE extern" >>confdefs.h fi - - if test "$SHARED_LIB_SUFFIX" = ""; then + if test "$SHARED_LIB_SUFFIX" = ""; then : SHARED_LIB_SUFFIX='${VERSION}${SHLIB_SUFFIX}' fi - - if test "$UNSHARED_LIB_SUFFIX" = ""; then + if test "$UNSHARED_LIB_SUFFIX" = ""; then : UNSHARED_LIB_SUFFIX='${VERSION}.a' fi - DLL_INSTALL_DIR="\$(LIB_INSTALL_DIR)" - if test "${SHARED_BUILD}" = 1 -a "${SHLIB_SUFFIX}" != ""; then + if test "${SHARED_BUILD}" = 1 -a "${SHLIB_SUFFIX}" != ""; then : LIB_SUFFIX=${SHARED_LIB_SUFFIX} MAKE_LIB='${SHLIB_LD} -o $@ ${OBJS} ${SHLIB_LD_LIBS} ${TCL_SHLIB_LD_EXTRAS} ${TK_SHLIB_LD_EXTRAS} ${LD_SEARCH_FLAGS}' - if test "${SHLIB_SUFFIX}" = ".dll"; then + if test "${SHLIB_SUFFIX}" = ".dll"; then : INSTALL_LIB='$(INSTALL_LIBRARY) $(LIB_FILE) "$(BIN_INSTALL_DIR)/$(LIB_FILE)"' DLL_INSTALL_DIR="\$(BIN_INSTALL_DIR)" @@ -8993,12 +6686,11 @@ else fi - else LIB_SUFFIX=${UNSHARED_LIB_SUFFIX} - if test "$RANLIB" = ""; then + if test "$RANLIB" = ""; then : MAKE_LIB='$(STLIB_LD) $@ ${OBJS}' INSTALL_LIB='$(INSTALL_LIBRARY) $(LIB_FILE) "$(LIB_INSTALL_DIR)/$(LIB_FILE)"' @@ -9010,12 +6702,22 @@ else fi - fi + if test "$RANLIB" = ""; then : + + MAKE_KIT_LIB='$(STLIB_LD) $@ ${TCL_OBJS} ${TOMMATH_OBJS} ${ZLIB_OBJS}' + INSTALL_KIT_LIB='$(INSTALL_LIBRARY) $(TCL_KIT_LIB_FILE) "$(LIB_INSTALL_DIR)/$(TCL_KIT_LIB_FILE)"' + +else + + MAKE_KIT_LIB='${STLIB_LD} $@ ${TCL_OBJS} ${TOMMATH_OBJS} ${ZLIB_OBJS} ; ${RANLIB} $@' + INSTALL_KIT_LIB='$(INSTALL_LIBRARY) $(TCL_KIT_LIB_FILE) "$(LIB_INSTALL_DIR)/$(TCL_KIT_LIB_FILE)" ; (cd "$(LIB_INSTALL_DIR)" ; $(RANLIB) $(TCL_KIT_LIB_FILE))' + +fi # Stub lib does not depend on shared/static configuration - if test "$RANLIB" = ""; then + if test "$RANLIB" = ""; then : MAKE_STUB_LIB='${STLIB_LD} $@ ${STUB_LIB_OBJS}' INSTALL_STUB_LIB='$(INSTALL_LIBRARY) $(STUB_LIB_FILE) "$(LIB_INSTALL_DIR)/$(STUB_LIB_FILE)"' @@ -9027,31 +6729,25 @@ else fi - # Define TCL_LIBS now that we know what DL_LIBS is. # The trick here is that we don't want to change the value of TCL_LIBS if # it is already set when tclConfig.sh had been loaded by Tk. - if test "x${TCL_LIBS}" = x; then + if test "x${TCL_LIBS}" = x; then : TCL_LIBS="${DL_LIBS} ${LIBS} ${MATH_LIBS}" fi - # See if the compiler supports casting to a union type. # This is used to stop gcc from printing a compiler # warning when initializing a union member. - echo "$as_me:$LINENO: checking for cast to union support" >&5 -echo $ECHO_N "checking for cast to union support... $ECHO_C" >&6 -if test "${tcl_cv_cast_to_union+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for cast to union support" >&5 +$as_echo_n "checking for cast to union support... " >&6; } +if ${tcl_cv_cast_to_union+:} false; then : + $as_echo_n "(cached) " >&6 else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int @@ -9065,45 +6761,19 @@ main () return 0; } _ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then +if ac_fn_c_try_compile "$LINENO"; then : tcl_cv_cast_to_union=yes else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -tcl_cv_cast_to_union=no + tcl_cv_cast_to_union=no fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi -echo "$as_me:$LINENO: result: $tcl_cv_cast_to_union" >&5 -echo "${ECHO_T}$tcl_cv_cast_to_union" >&6 +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_cast_to_union" >&5 +$as_echo "$tcl_cv_cast_to_union" >&6; } if test "$tcl_cv_cast_to_union" = "yes"; then -cat >>confdefs.h <<\_ACEOF -#define HAVE_CAST_TO_UNION 1 -_ACEOF +$as_echo "#define HAVE_CAST_TO_UNION 1" >>confdefs.h fi @@ -9149,38 +6819,36 @@ _ACEOF - echo "$as_me:$LINENO: checking for build with symbols" >&5 -echo $ECHO_N "checking for build with symbols... $ECHO_C" >&6 - # Check whether --enable-symbols or --disable-symbols was given. -if test "${enable_symbols+set}" = set; then - enableval="$enable_symbols" - tcl_ok=$enableval + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for build with symbols" >&5 +$as_echo_n "checking for build with symbols... " >&6; } + # Check whether --enable-symbols was given. +if test "${enable_symbols+set}" = set; then : + enableval=$enable_symbols; tcl_ok=$enableval else tcl_ok=no -fi; +fi + # FIXME: Currently, LDFLAGS_DEFAULT is not used, it should work like CFLAGS_DEFAULT. DBGX="" if test "$tcl_ok" = "no"; then CFLAGS_DEFAULT='$(CFLAGS_OPTIMIZE)' LDFLAGS_DEFAULT='$(LDFLAGS_OPTIMIZE)' -cat >>confdefs.h <<\_ACEOF -#define NDEBUG 1 -_ACEOF +$as_echo "#define NDEBUG 1" >>confdefs.h - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } -cat >>confdefs.h <<\_ACEOF -#define TCL_CFG_OPTIMIZED 1 -_ACEOF +$as_echo "#define TCL_CFG_OPTIMIZED 1" >>confdefs.h else CFLAGS_DEFAULT='$(CFLAGS_DEBUG)' LDFLAGS_DEFAULT='$(LDFLAGS_DEBUG)' if test "$tcl_ok" = "yes"; then - echo "$as_me:$LINENO: result: yes (standard debugging)" >&5 -echo "${ECHO_T}yes (standard debugging)" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes (standard debugging)" >&5 +$as_echo "yes (standard debugging)" >&6; } fi fi @@ -9188,45 +6856,35 @@ echo "${ECHO_T}yes (standard debugging)" >&6 if test "$tcl_ok" = "mem" -o "$tcl_ok" = "all"; then -cat >>confdefs.h <<\_ACEOF -#define TCL_MEM_DEBUG 1 -_ACEOF +$as_echo "#define TCL_MEM_DEBUG 1" >>confdefs.h fi if test "$tcl_ok" = "compile" -o "$tcl_ok" = "all"; then -cat >>confdefs.h <<\_ACEOF -#define TCL_COMPILE_DEBUG 1 -_ACEOF +$as_echo "#define TCL_COMPILE_DEBUG 1" >>confdefs.h -cat >>confdefs.h <<\_ACEOF -#define TCL_COMPILE_STATS 1 -_ACEOF +$as_echo "#define TCL_COMPILE_STATS 1" >>confdefs.h fi if test "$tcl_ok" != "yes" -a "$tcl_ok" != "no"; then if test "$tcl_ok" = "all"; then - echo "$as_me:$LINENO: result: enabled symbols mem compile debugging" >&5 -echo "${ECHO_T}enabled symbols mem compile debugging" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: enabled symbols mem compile debugging" >&5 +$as_echo "enabled symbols mem compile debugging" >&6; } else - echo "$as_me:$LINENO: result: enabled $tcl_ok debugging" >&5 -echo "${ECHO_T}enabled $tcl_ok debugging" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: enabled $tcl_ok debugging" >&5 +$as_echo "enabled $tcl_ok debugging" >&6; } fi fi -cat >>confdefs.h <<\_ACEOF -#define TCL_TOMMATH 1 -_ACEOF +$as_echo "#define TCL_TOMMATH 1" >>confdefs.h -cat >>confdefs.h <<\_ACEOF -#define MP_PREC 4 -_ACEOF +$as_echo "#define MP_PREC 4" >>confdefs.h #-------------------------------------------------------------------- @@ -9234,18 +6892,14 @@ _ACEOF #-------------------------------------------------------------------- - echo "$as_me:$LINENO: checking for required early compiler flags" >&5 -echo $ECHO_N "checking for required early compiler flags... $ECHO_C" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for required early compiler flags" >&5 +$as_echo_n "checking for required early compiler flags... " >&6; } tcl_flags="" - if test "${tcl_cv_flag__isoc99_source+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + if ${tcl_cv_flag__isoc99_source+:} false; then : + $as_echo_n "(cached) " >&6 else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int @@ -9256,38 +6910,10 @@ char *p = (char *)strtoll; char *q = (char *)strtoull; return 0; } _ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then +if ac_fn_c_try_compile "$LINENO"; then : tcl_cv_flag__isoc99_source=no else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #define _ISOC99_SOURCE 1 #include @@ -9299,58 +6925,28 @@ char *p = (char *)strtoll; char *q = (char *)strtoull; return 0; } _ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then +if ac_fn_c_try_compile "$LINENO"; then : tcl_cv_flag__isoc99_source=yes else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -tcl_cv_flag__isoc99_source=no + tcl_cv_flag__isoc99_source=no fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if test "x${tcl_cv_flag__isoc99_source}" = "xyes" ; then -cat >>confdefs.h <<\_ACEOF -#define _ISOC99_SOURCE 1 -_ACEOF +$as_echo "#define _ISOC99_SOURCE 1" >>confdefs.h tcl_flags="$tcl_flags _ISOC99_SOURCE" fi - if test "${tcl_cv_flag__largefile64_source+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + if ${tcl_cv_flag__largefile64_source+:} false; then : + $as_echo_n "(cached) " >&6 else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int @@ -9361,38 +6957,10 @@ struct stat64 buf; int i = stat64("/", &buf); return 0; } _ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then +if ac_fn_c_try_compile "$LINENO"; then : tcl_cv_flag__largefile64_source=no else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #define _LARGEFILE64_SOURCE 1 #include @@ -9404,58 +6972,28 @@ struct stat64 buf; int i = stat64("/", &buf); return 0; } _ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then +if ac_fn_c_try_compile "$LINENO"; then : tcl_cv_flag__largefile64_source=yes else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -tcl_cv_flag__largefile64_source=no + tcl_cv_flag__largefile64_source=no fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if test "x${tcl_cv_flag__largefile64_source}" = "xyes" ; then -cat >>confdefs.h <<\_ACEOF -#define _LARGEFILE64_SOURCE 1 -_ACEOF +$as_echo "#define _LARGEFILE64_SOURCE 1" >>confdefs.h tcl_flags="$tcl_flags _LARGEFILE64_SOURCE" fi - if test "${tcl_cv_flag__largefile_source64+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + if ${tcl_cv_flag__largefile_source64+:} false; then : + $as_echo_n "(cached) " >&6 else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int @@ -9466,38 +7004,10 @@ char *p = (char *)open64; return 0; } _ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then +if ac_fn_c_try_compile "$LINENO"; then : tcl_cv_flag__largefile_source64=no else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #define _LARGEFILE_SOURCE64 1 #include @@ -9509,72 +7019,42 @@ char *p = (char *)open64; return 0; } _ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then +if ac_fn_c_try_compile "$LINENO"; then : tcl_cv_flag__largefile_source64=yes else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -tcl_cv_flag__largefile_source64=no + tcl_cv_flag__largefile_source64=no fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if test "x${tcl_cv_flag__largefile_source64}" = "xyes" ; then -cat >>confdefs.h <<\_ACEOF -#define _LARGEFILE_SOURCE64 1 -_ACEOF +$as_echo "#define _LARGEFILE_SOURCE64 1" >>confdefs.h tcl_flags="$tcl_flags _LARGEFILE_SOURCE64" fi if test "x${tcl_flags}" = "x" ; then - echo "$as_me:$LINENO: result: none" >&5 -echo "${ECHO_T}none" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5 +$as_echo "none" >&6; } else - echo "$as_me:$LINENO: result: ${tcl_flags}" >&5 -echo "${ECHO_T}${tcl_flags}" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${tcl_flags}" >&5 +$as_echo "${tcl_flags}" >&6; } fi - echo "$as_me:$LINENO: checking for 64-bit integer type" >&5 -echo $ECHO_N "checking for 64-bit integer type... $ECHO_C" >&6 - if test "${tcl_cv_type_64bit+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for 64-bit integer type" >&5 +$as_echo_n "checking for 64-bit integer type... " >&6; } + if ${tcl_cv_type_64bit+:} false; then : + $as_echo_n "(cached) " >&6 else tcl_cv_type_64bit=none # See if the compiler knows natively about __int64 - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int @@ -9585,44 +7065,16 @@ __int64 value = (__int64) 0; return 0; } _ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then +if ac_fn_c_try_compile "$LINENO"; then : tcl_type_64bit=__int64 else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -tcl_type_64bit="long long" + tcl_type_64bit="long long" fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext # See if we should use long anyway Note that we substitute in the # type that is our current guess for a 64-bit type inside this check # program, so it should be modified only carefully... - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int @@ -9635,66 +7087,35 @@ switch (0) { return 0; } _ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then +if ac_fn_c_try_compile "$LINENO"; then : tcl_cv_type_64bit=${tcl_type_64bit} -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if test "${tcl_cv_type_64bit}" = none ; then -cat >>confdefs.h <<\_ACEOF -#define TCL_WIDE_INT_IS_LONG 1 -_ACEOF +$as_echo "#define TCL_WIDE_INT_IS_LONG 1" >>confdefs.h - echo "$as_me:$LINENO: result: using long" >&5 -echo "${ECHO_T}using long" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: using long" >&5 +$as_echo "using long" >&6; } else cat >>confdefs.h <<_ACEOF #define TCL_WIDE_INT_TYPE ${tcl_cv_type_64bit} _ACEOF - echo "$as_me:$LINENO: result: ${tcl_cv_type_64bit}" >&5 -echo "${ECHO_T}${tcl_cv_type_64bit}" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${tcl_cv_type_64bit}" >&5 +$as_echo "${tcl_cv_type_64bit}" >&6; } # Now check for auxiliary declarations - echo "$as_me:$LINENO: checking for struct dirent64" >&5 -echo $ECHO_N "checking for struct dirent64... $ECHO_C" >&6 -if test "${tcl_cv_struct_dirent64+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for struct dirent64" >&5 +$as_echo_n "checking for struct dirent64... " >&6; } +if ${tcl_cv_struct_dirent64+:} false; then : + $as_echo_n "(cached) " >&6 else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include @@ -9706,58 +7127,28 @@ struct dirent64 p; return 0; } _ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then +if ac_fn_c_try_compile "$LINENO"; then : tcl_cv_struct_dirent64=yes else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -tcl_cv_struct_dirent64=no + tcl_cv_struct_dirent64=no fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi -echo "$as_me:$LINENO: result: $tcl_cv_struct_dirent64" >&5 -echo "${ECHO_T}$tcl_cv_struct_dirent64" >&6 +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_struct_dirent64" >&5 +$as_echo "$tcl_cv_struct_dirent64" >&6; } if test "x${tcl_cv_struct_dirent64}" = "xyes" ; then -cat >>confdefs.h <<\_ACEOF -#define HAVE_STRUCT_DIRENT64 1 -_ACEOF +$as_echo "#define HAVE_STRUCT_DIRENT64 1" >>confdefs.h fi - echo "$as_me:$LINENO: checking for struct stat64" >&5 -echo $ECHO_N "checking for struct stat64... $ECHO_C" >&6 -if test "${tcl_cv_struct_stat64+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for struct stat64" >&5 +$as_echo_n "checking for struct stat64... " >&6; } +if ${tcl_cv_struct_stat64+:} false; then : + $as_echo_n "(cached) " >&6 else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int @@ -9769,161 +7160,40 @@ struct stat64 p; return 0; } _ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then +if ac_fn_c_try_compile "$LINENO"; then : tcl_cv_struct_stat64=yes else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -tcl_cv_struct_stat64=no + tcl_cv_struct_stat64=no fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi -echo "$as_me:$LINENO: result: $tcl_cv_struct_stat64" >&5 -echo "${ECHO_T}$tcl_cv_struct_stat64" >&6 +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_struct_stat64" >&5 +$as_echo "$tcl_cv_struct_stat64" >&6; } if test "x${tcl_cv_struct_stat64}" = "xyes" ; then -cat >>confdefs.h <<\_ACEOF -#define HAVE_STRUCT_STAT64 1 -_ACEOF +$as_echo "#define HAVE_STRUCT_STAT64 1" >>confdefs.h fi - - -for ac_func in open64 lseek64 -do -as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` -echo "$as_me:$LINENO: checking for $ac_func" >&5 -echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 -if eval "test \"\${$as_ac_var+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -/* Define $ac_func to an innocuous variant, in case declares $ac_func. - For example, HP-UX 11i declares gettimeofday. */ -#define $ac_func innocuous_$ac_func - -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char $ac_func (); below. - Prefer to if __STDC__ is defined, since - exists even on freestanding compilers. */ - -#ifdef __STDC__ -# include -#else -# include -#endif - -#undef $ac_func - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -{ -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char $ac_func (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_$ac_func) || defined (__stub___$ac_func) -choke me -#else -char (*f) () = $ac_func; -#endif -#ifdef __cplusplus -} -#endif - -int -main () -{ -return f != $ac_func; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - eval "$as_ac_var=yes" -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -eval "$as_ac_var=no" -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 -if test `eval echo '${'$as_ac_var'}'` = yes; then + for ac_func in open64 lseek64 +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done - echo "$as_me:$LINENO: checking for off64_t" >&5 -echo $ECHO_N "checking for off64_t... $ECHO_C" >&6 - if test "${tcl_cv_type_off64_t+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for off64_t" >&5 +$as_echo_n "checking for off64_t... " >&6; } + if ${tcl_cv_type_off64_t+:} false; then : + $as_echo_n "(cached) " >&6 else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int @@ -9935,51 +7205,25 @@ off64_t offset; return 0; } _ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then +if ac_fn_c_try_compile "$LINENO"; then : tcl_cv_type_off64_t=yes else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -tcl_cv_type_off64_t=no + tcl_cv_type_off64_t=no fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if test "x${tcl_cv_type_off64_t}" = "xyes" && \ test "x${ac_cv_func_lseek64}" = "xyes" && \ test "x${ac_cv_func_open64}" = "xyes" ; then -cat >>confdefs.h <<\_ACEOF -#define HAVE_TYPE_OFF64_T 1 -_ACEOF +$as_echo "#define HAVE_TYPE_OFF64_T 1" >>confdefs.h - echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } fi fi @@ -9989,235 +7233,229 @@ echo "${ECHO_T}no" >&6 # Tcl_UniChar strings to memcmp on big-endian systems. #-------------------------------------------------------------------- -echo "$as_me:$LINENO: checking whether byte ordering is bigendian" >&5 -echo $ECHO_N "checking whether byte ordering is bigendian... $ECHO_C" >&6 -if test "${ac_cv_c_bigendian+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5 +$as_echo_n "checking whether byte ordering is bigendian... " >&6; } +if ${ac_cv_c_bigendian+:} false; then : + $as_echo_n "(cached) " >&6 else - # See if sys/param.h defines the BYTE_ORDER macro. -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF + ac_cv_c_bigendian=unknown + # See if we're dealing with a universal compiler. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifndef __APPLE_CC__ + not a universal capable compiler + #endif + typedef int dummy; + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + + # Check for potential -arch flags. It is not universal unless + # there are at least two -arch flags with different values. + ac_arch= + ac_prev= + for ac_word in $CC $CFLAGS $CPPFLAGS $LDFLAGS; do + if test -n "$ac_prev"; then + case $ac_word in + i?86 | x86_64 | ppc | ppc64) + if test -z "$ac_arch" || test "$ac_arch" = "$ac_word"; then + ac_arch=$ac_word + else + ac_cv_c_bigendian=universal + break + fi + ;; + esac + ac_prev= + elif test "x$ac_word" = "x-arch"; then + ac_prev=arch + fi + done +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + if test $ac_cv_c_bigendian = unknown; then + # See if sys/param.h defines the BYTE_ORDER macro. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include -#include + #include int main () { -#if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN - bogus endian macros -#endif +#if ! (defined BYTE_ORDER && defined BIG_ENDIAN \ + && defined LITTLE_ENDIAN && BYTE_ORDER && BIG_ENDIAN \ + && LITTLE_ENDIAN) + bogus endian macros + #endif ; return 0; } _ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then +if ac_fn_c_try_compile "$LINENO"; then : # It does; now see whether it defined to BIG_ENDIAN or not. -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include -#include + #include int main () { #if BYTE_ORDER != BIG_ENDIAN - not big endian -#endif + not big endian + #endif ; return 0; } _ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then +if ac_fn_c_try_compile "$LINENO"; then : ac_cv_c_bigendian=yes else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_c_bigendian=no + ac_cv_c_bigendian=no fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -# It does not; compile a test program. -if test "$cross_compiling" = yes; then - # try to guess the endianness by grepping values into an object file - ac_cv_c_bigendian=unknown - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + fi + if test $ac_cv_c_bigendian = unknown; then + # See if defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris). + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -short ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 }; -short ascii_ii[] = { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 }; -void _ascii () { char *s = (char *) ascii_mm; s = (char *) ascii_ii; } -short ebcdic_ii[] = { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 }; -short ebcdic_mm[] = { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 }; -void _ebcdic () { char *s = (char *) ebcdic_mm; s = (char *) ebcdic_ii; } +#include + int main () { - _ascii (); _ebcdic (); +#if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN) + bogus endian macros + #endif + ; return 0; } _ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - if grep BIGenDianSyS conftest.$ac_objext >/dev/null ; then +if ac_fn_c_try_compile "$LINENO"; then : + # It does; now see whether it defined to _BIG_ENDIAN or not. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +int +main () +{ +#ifndef _BIG_ENDIAN + not big endian + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : ac_cv_c_bigendian=yes +else + ac_cv_c_bigendian=no fi -if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then - if test "$ac_cv_c_bigendian" = unknown; then - ac_cv_c_bigendian=no - else - # finding both strings is unlikely to happen, but who knows? - ac_cv_c_bigendian=unknown - fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + fi + if test $ac_cv_c_bigendian = unknown; then + # Compile a test program. + if test "$cross_compiling" = yes; then : + # Try to guess by grepping values from an object file. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +short int ascii_mm[] = + { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 }; + short int ascii_ii[] = + { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 }; + int use_ascii (int i) { + return ascii_mm[i] + ascii_ii[i]; + } + short int ebcdic_ii[] = + { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 }; + short int ebcdic_mm[] = + { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 }; + int use_ebcdic (int i) { + return ebcdic_mm[i] + ebcdic_ii[i]; + } + extern int foo; +int +main () +{ +return use_ascii (foo) == use_ebcdic (foo); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + if grep BIGenDianSyS conftest.$ac_objext >/dev/null; then + ac_cv_c_bigendian=yes + fi + if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then + if test "$ac_cv_c_bigendian" = unknown; then + ac_cv_c_bigendian=no + else + # finding both strings is unlikely to happen, but who knows? + ac_cv_c_bigendian=unknown + fi + fi fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ +$ac_includes_default int main () { - /* Are we little or big endian? From Harbison&Steele. */ - union - { - long l; - char c[sizeof (long)]; - } u; - u.l = 1; - exit (u.c[sizeof (long) - 1] == 1); + + /* Are we little or big endian? From Harbison&Steele. */ + union + { + long int l; + char c[sizeof (long int)]; + } u; + u.l = 1; + return u.c[sizeof (long int) - 1] == 1; + + ; + return 0; } _ACEOF -rm -f conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then +if ac_fn_c_try_run "$LINENO"; then : ac_cv_c_bigendian=no else - echo "$as_me: program exited with status $ac_status" >&5 -echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -( exit $ac_status ) -ac_cv_c_bigendian=yes -fi -rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext + ac_cv_c_bigendian=yes fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + + fi fi -echo "$as_me:$LINENO: result: $ac_cv_c_bigendian" >&5 -echo "${ECHO_T}$ac_cv_c_bigendian" >&6 -case $ac_cv_c_bigendian in - yes) +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_bigendian" >&5 +$as_echo "$ac_cv_c_bigendian" >&6; } + case $ac_cv_c_bigendian in #( + yes) + $as_echo "#define WORDS_BIGENDIAN 1" >>confdefs.h +;; #( + no) + ;; #( + universal) -cat >>confdefs.h <<\_ACEOF -#define WORDS_BIGENDIAN 1 -_ACEOF - ;; - no) - ;; - *) - { { echo "$as_me:$LINENO: error: unknown endianness -presetting ac_cv_c_bigendian=no (or yes) will help" >&5 -echo "$as_me: error: unknown endianness -presetting ac_cv_c_bigendian=no (or yes) will help" >&2;} - { (exit 1); exit 1; }; } ;; -esac +$as_echo "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h + + ;; #( + *) + as_fn_error $? "unknown endianness + presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;; + esac #-------------------------------------------------------------------- @@ -10226,110 +7464,17 @@ esac #-------------------------------------------------------------------- # Check if Posix compliant getcwd exists, if not we'll use getwd. - for ac_func in getcwd -do -as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` -echo "$as_me:$LINENO: checking for $ac_func" >&5 -echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 -if eval "test \"\${$as_ac_var+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -/* Define $ac_func to an innocuous variant, in case declares $ac_func. - For example, HP-UX 11i declares gettimeofday. */ -#define $ac_func innocuous_$ac_func - -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char $ac_func (); below. - Prefer to if __STDC__ is defined, since - exists even on freestanding compilers. */ - -#ifdef __STDC__ -# include -#else -# include -#endif - -#undef $ac_func - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -{ -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char $ac_func (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_$ac_func) || defined (__stub___$ac_func) -choke me -#else -char (*f) () = $ac_func; -#endif -#ifdef __cplusplus -} -#endif - -int -main () -{ -return f != $ac_func; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - eval "$as_ac_var=yes" -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -eval "$as_ac_var=no" -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 -if test `eval echo '${'$as_ac_var'}'` = yes; then +do : + ac_fn_c_check_func "$LINENO" "getcwd" "ac_cv_func_getcwd" +if test "x$ac_cv_func_getcwd" = xyes; then : cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +#define HAVE_GETCWD 1 _ACEOF else -cat >>confdefs.h <<\_ACEOF -#define USEGETWD 1 -_ACEOF +$as_echo "#define USEGETWD 1" >>confdefs.h fi done @@ -10337,7726 +7482,2343 @@ done # Nb: if getcwd uses popen and pwd(1) (like SunOS 4) we should really # define USEGETWD even if the posix getcwd exists. Add a test ? +ac_fn_c_check_func "$LINENO" "mkstemp" "ac_cv_func_mkstemp" +if test "x$ac_cv_func_mkstemp" = xyes; then : + $as_echo "#define HAVE_MKSTEMP 1" >>confdefs.h +else + case " $LIBOBJS " in + *" mkstemp.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS mkstemp.$ac_objext" + ;; +esac +fi +ac_fn_c_check_func "$LINENO" "opendir" "ac_cv_func_opendir" +if test "x$ac_cv_func_opendir" = xyes; then : + $as_echo "#define HAVE_OPENDIR 1" >>confdefs.h -for ac_func in mkstemp opendir strtol waitpid -do -as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` -echo "$as_me:$LINENO: checking for $ac_func" >&5 -echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 -if eval "test \"\${$as_ac_var+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -/* Define $ac_func to an innocuous variant, in case declares $ac_func. - For example, HP-UX 11i declares gettimeofday. */ -#define $ac_func innocuous_$ac_func - -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char $ac_func (); below. - Prefer to if __STDC__ is defined, since - exists even on freestanding compilers. */ - -#ifdef __STDC__ -# include -#else -# include -#endif +else + case " $LIBOBJS " in + *" opendir.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS opendir.$ac_objext" + ;; +esac -#undef $ac_func +fi -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -{ -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char $ac_func (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_$ac_func) || defined (__stub___$ac_func) -choke me -#else -char (*f) () = $ac_func; -#endif -#ifdef __cplusplus -} -#endif +ac_fn_c_check_func "$LINENO" "strtol" "ac_cv_func_strtol" +if test "x$ac_cv_func_strtol" = xyes; then : + $as_echo "#define HAVE_STRTOL 1" >>confdefs.h -int -main () -{ -return f != $ac_func; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - eval "$as_ac_var=yes" else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 + case " $LIBOBJS " in + *" strtol.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS strtol.$ac_objext" + ;; +esac -eval "$as_ac_var=no" -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 -if test `eval echo '${'$as_ac_var'}'` = yes; then - cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 -_ACEOF + +ac_fn_c_check_func "$LINENO" "waitpid" "ac_cv_func_waitpid" +if test "x$ac_cv_func_waitpid" = xyes; then : + $as_echo "#define HAVE_WAITPID 1" >>confdefs.h else - case $LIBOBJS in - "$ac_func.$ac_objext" | \ - *" $ac_func.$ac_objext" | \ - "$ac_func.$ac_objext "* | \ - *" $ac_func.$ac_objext "* ) ;; - *) LIBOBJS="$LIBOBJS $ac_func.$ac_objext" ;; + case " $LIBOBJS " in + *" waitpid.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS waitpid.$ac_objext" + ;; esac fi -done -echo "$as_me:$LINENO: checking for strerror" >&5 -echo $ECHO_N "checking for strerror... $ECHO_C" >&6 -if test "${ac_cv_func_strerror+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -/* Define strerror to an innocuous variant, in case declares strerror. - For example, HP-UX 11i declares gettimeofday. */ -#define strerror innocuous_strerror +ac_fn_c_check_func "$LINENO" "strerror" "ac_cv_func_strerror" +if test "x$ac_cv_func_strerror" = xyes; then : -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char strerror (); below. - Prefer to if __STDC__ is defined, since - exists even on freestanding compilers. */ +else -#ifdef __STDC__ -# include -#else -# include -#endif +$as_echo "#define NO_STRERROR 1" >>confdefs.h -#undef strerror +fi -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -{ -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char strerror (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_strerror) || defined (__stub___strerror) -choke me -#else -char (*f) () = strerror; -#endif -#ifdef __cplusplus -} -#endif +ac_fn_c_check_func "$LINENO" "getwd" "ac_cv_func_getwd" +if test "x$ac_cv_func_getwd" = xyes; then : -int -main () -{ -return f != strerror; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_func_strerror=yes else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 -ac_cv_func_strerror=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext +$as_echo "#define NO_GETWD 1" >>confdefs.h + fi -echo "$as_me:$LINENO: result: $ac_cv_func_strerror" >&5 -echo "${ECHO_T}$ac_cv_func_strerror" >&6 -if test $ac_cv_func_strerror = yes; then - : + +ac_fn_c_check_func "$LINENO" "wait3" "ac_cv_func_wait3" +if test "x$ac_cv_func_wait3" = xyes; then : + else -cat >>confdefs.h <<\_ACEOF -#define NO_STRERROR 1 -_ACEOF +$as_echo "#define NO_WAIT3 1" >>confdefs.h fi -echo "$as_me:$LINENO: checking for getwd" >&5 -echo $ECHO_N "checking for getwd... $ECHO_C" >&6 -if test "${ac_cv_func_getwd+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 +ac_fn_c_check_func "$LINENO" "uname" "ac_cv_func_uname" +if test "x$ac_cv_func_uname" = xyes; then : + else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -/* Define getwd to an innocuous variant, in case declares getwd. - For example, HP-UX 11i declares gettimeofday. */ -#define getwd innocuous_getwd -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char getwd (); below. - Prefer to if __STDC__ is defined, since - exists even on freestanding compilers. */ +$as_echo "#define NO_UNAME 1" >>confdefs.h -#ifdef __STDC__ -# include -#else -# include -#endif +fi -#undef getwd -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -{ -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char getwd (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_getwd) || defined (__stub___getwd) -choke me -#else -char (*f) () = getwd; -#endif -#ifdef __cplusplus -} -#endif +if test "`uname -s`" = "Darwin" && test "${TCL_THREADS}" = 1 && \ + test "`uname -r | awk -F. '{print $1}'`" -lt 7; then + # prior to Darwin 7, realpath is not threadsafe, so don't + # use it when threads are enabled, c.f. bug # 711232 + ac_cv_func_realpath=no +fi +ac_fn_c_check_func "$LINENO" "realpath" "ac_cv_func_realpath" +if test "x$ac_cv_func_realpath" = xyes; then : -int -main () -{ -return f != getwd; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_func_getwd=yes else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 -ac_cv_func_getwd=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext +$as_echo "#define NO_REALPATH 1" >>confdefs.h + fi -echo "$as_me:$LINENO: result: $ac_cv_func_getwd" >&5 -echo "${ECHO_T}$ac_cv_func_getwd" >&6 -if test $ac_cv_func_getwd = yes; then - : -else -cat >>confdefs.h <<\_ACEOF -#define NO_GETWD 1 + + + NEED_FAKE_RFC2553=0 + for ac_func in getnameinfo getaddrinfo freeaddrinfo gai_strerror +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF +else + NEED_FAKE_RFC2553=1 fi +done + + ac_fn_c_check_type "$LINENO" "struct addrinfo" "ac_cv_type_struct_addrinfo" " +#include +#include +#include +#include + +" +if test "x$ac_cv_type_struct_addrinfo" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_STRUCT_ADDRINFO 1 +_ACEOF + -echo "$as_me:$LINENO: checking for wait3" >&5 -echo $ECHO_N "checking for wait3... $ECHO_C" >&6 -if test "${ac_cv_func_wait3+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ + NEED_FAKE_RFC2553=1 +fi +ac_fn_c_check_type "$LINENO" "struct in6_addr" "ac_cv_type_struct_in6_addr" " +#include +#include +#include +#include + +" +if test "x$ac_cv_type_struct_in6_addr" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_STRUCT_IN6_ADDR 1 _ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -/* Define wait3 to an innocuous variant, in case declares wait3. - For example, HP-UX 11i declares gettimeofday. */ -#define wait3 innocuous_wait3 -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char wait3 (); below. - Prefer to if __STDC__ is defined, since - exists even on freestanding compilers. */ -#ifdef __STDC__ -# include -#else -# include -#endif +else + NEED_FAKE_RFC2553=1 +fi +ac_fn_c_check_type "$LINENO" "struct sockaddr_in6" "ac_cv_type_struct_sockaddr_in6" " +#include +#include +#include +#include -#undef wait3 +" +if test "x$ac_cv_type_struct_sockaddr_in6" = xyes; then : -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -{ -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char wait3 (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_wait3) || defined (__stub___wait3) -choke me -#else -char (*f) () = wait3; -#endif -#ifdef __cplusplus -} -#endif +cat >>confdefs.h <<_ACEOF +#define HAVE_STRUCT_SOCKADDR_IN6 1 +_ACEOF -int -main () -{ -return f != wait3; - ; - return 0; -} + +else + NEED_FAKE_RFC2553=1 +fi +ac_fn_c_check_type "$LINENO" "struct sockaddr_storage" "ac_cv_type_struct_sockaddr_storage" " +#include +#include +#include +#include + +" +if test "x$ac_cv_type_struct_sockaddr_storage" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_STRUCT_SOCKADDR_STORAGE 1 _ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_func_wait3=yes + + else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 + NEED_FAKE_RFC2553=1 +fi + +if test "x$NEED_FAKE_RFC2553" = "x1"; then + +$as_echo "#define NEED_FAKE_RFC2553 1" >>confdefs.h + + case " $LIBOBJS " in + *" fake-rfc2553.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS fake-rfc2553.$ac_objext" + ;; +esac + + ac_fn_c_check_func "$LINENO" "strlcpy" "ac_cv_func_strlcpy" +if test "x$ac_cv_func_strlcpy" = xyes; then : -ac_cv_func_wait3=no fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext + fi -echo "$as_me:$LINENO: result: $ac_cv_func_wait3" >&5 -echo "${ECHO_T}$ac_cv_func_wait3" >&6 -if test $ac_cv_func_wait3 = yes; then - : -else -cat >>confdefs.h <<\_ACEOF -#define NO_WAIT3 1 -_ACEOF -fi +#-------------------------------------------------------------------- +# Look for thread-safe variants of some library functions. +#-------------------------------------------------------------------- -echo "$as_me:$LINENO: checking for uname" >&5 -echo $ECHO_N "checking for uname... $ECHO_C" >&6 -if test "${ac_cv_func_uname+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 +if test "${TCL_THREADS}" = 1; then + ac_fn_c_check_func "$LINENO" "getpwuid_r" "ac_cv_func_getpwuid_r" +if test "x$ac_cv_func_getpwuid_r" = xyes; then : + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for getpwuid_r with 5 args" >&5 +$as_echo_n "checking for getpwuid_r with 5 args... " >&6; } +if ${tcl_cv_api_getpwuid_r_5+:} false; then : + $as_echo_n "(cached) " >&6 else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -/* Define uname to an innocuous variant, in case declares uname. - For example, HP-UX 11i declares gettimeofday. */ -#define uname innocuous_uname -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char uname (); below. - Prefer to if __STDC__ is defined, since - exists even on freestanding compilers. */ + #include + #include -#ifdef __STDC__ -# include -#else -# include -#endif +int +main () +{ -#undef uname + uid_t uid; + struct passwd pw, *pwp; + char buf[512]; + int buflen = 512; -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -{ -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char uname (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_uname) || defined (__stub___uname) -choke me -#else -char (*f) () = uname; -#endif -#ifdef __cplusplus + (void) getpwuid_r(uid, &pw, buf, buflen, &pwp); + + ; + return 0; } -#endif +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + tcl_cv_api_getpwuid_r_5=yes +else + tcl_cv_api_getpwuid_r_5=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_api_getpwuid_r_5" >&5 +$as_echo "$tcl_cv_api_getpwuid_r_5" >&6; } + tcl_ok=$tcl_cv_api_getpwuid_r_5 + if test "$tcl_ok" = yes; then + +$as_echo "#define HAVE_GETPWUID_R_5 1" >>confdefs.h + + else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for getpwuid_r with 4 args" >&5 +$as_echo_n "checking for getpwuid_r with 4 args... " >&6; } +if ${tcl_cv_api_getpwuid_r_4+:} false; then : + $as_echo_n "(cached) " >&6 +else + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #include + #include int main () { -return f != uname; + + uid_t uid; + struct passwd pw; + char buf[512]; + int buflen = 512; + + (void)getpwnam_r(uid, &pw, buf, buflen); + ; return 0; } _ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_func_uname=yes +if ac_fn_c_try_compile "$LINENO"; then : + tcl_cv_api_getpwuid_r_4=yes else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_func_uname=no + tcl_cv_api_getpwuid_r_4=no fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi -echo "$as_me:$LINENO: result: $ac_cv_func_uname" >&5 -echo "${ECHO_T}$ac_cv_func_uname" >&6 -if test $ac_cv_func_uname = yes; then - : -else +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_api_getpwuid_r_4" >&5 +$as_echo "$tcl_cv_api_getpwuid_r_4" >&6; } + tcl_ok=$tcl_cv_api_getpwuid_r_4 + if test "$tcl_ok" = yes; then -cat >>confdefs.h <<\_ACEOF -#define NO_UNAME 1 -_ACEOF +$as_echo "#define HAVE_GETPWUID_R_4 1" >>confdefs.h -fi + fi + fi + if test "$tcl_ok" = yes; then +$as_echo "#define HAVE_GETPWUID_R 1" >>confdefs.h + + fi -if test "`uname -s`" = "Darwin" && test "${TCL_THREADS}" = 1 && \ - test "`uname -r | awk -F. '{print $1}'`" -lt 7; then - # prior to Darwin 7, realpath is not threadsafe, so don't - # use it when threads are enabled, c.f. bug # 711232 - ac_cv_func_realpath=no fi -echo "$as_me:$LINENO: checking for realpath" >&5 -echo $ECHO_N "checking for realpath... $ECHO_C" >&6 -if test "${ac_cv_func_realpath+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -/* Define realpath to an innocuous variant, in case declares realpath. - For example, HP-UX 11i declares gettimeofday. */ -#define realpath innocuous_realpath -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char realpath (); below. - Prefer to if __STDC__ is defined, since - exists even on freestanding compilers. */ + ac_fn_c_check_func "$LINENO" "getpwnam_r" "ac_cv_func_getpwnam_r" +if test "x$ac_cv_func_getpwnam_r" = xyes; then : -#ifdef __STDC__ -# include -#else -# include -#endif + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for getpwnam_r with 5 args" >&5 +$as_echo_n "checking for getpwnam_r with 5 args... " >&6; } +if ${tcl_cv_api_getpwnam_r_5+:} false; then : + $as_echo_n "(cached) " >&6 +else -#undef realpath + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -{ -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char realpath (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_realpath) || defined (__stub___realpath) -choke me -#else -char (*f) () = realpath; -#endif -#ifdef __cplusplus -} -#endif + #include + #include int main () { -return f != realpath; + + char *name; + struct passwd pw, *pwp; + char buf[512]; + int buflen = 512; + + (void) getpwnam_r(name, &pw, buf, buflen, &pwp); + ; return 0; } _ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_func_realpath=yes +if ac_fn_c_try_compile "$LINENO"; then : + tcl_cv_api_getpwnam_r_5=yes else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_func_realpath=no + tcl_cv_api_getpwnam_r_5=no fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi -echo "$as_me:$LINENO: result: $ac_cv_func_realpath" >&5 -echo "${ECHO_T}$ac_cv_func_realpath" >&6 -if test $ac_cv_func_realpath = yes; then - : -else - -cat >>confdefs.h <<\_ACEOF -#define NO_REALPATH 1 -_ACEOF +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_api_getpwnam_r_5" >&5 +$as_echo "$tcl_cv_api_getpwnam_r_5" >&6; } + tcl_ok=$tcl_cv_api_getpwnam_r_5 + if test "$tcl_ok" = yes; then -fi +$as_echo "#define HAVE_GETPWNAM_R_5 1" >>confdefs.h + else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for getpwnam_r with 4 args" >&5 +$as_echo_n "checking for getpwnam_r with 4 args... " >&6; } +if ${tcl_cv_api_getpwnam_r_4+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ - NEED_FAKE_RFC2553=0 + #include + #include +int +main () +{ + char *name; + struct passwd pw; + char buf[512]; + int buflen = 512; + (void)getpwnam_r(name, &pw, buf, buflen); -for ac_func in getnameinfo getaddrinfo freeaddrinfo gai_strerror -do -as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` -echo "$as_me:$LINENO: checking for $ac_func" >&5 -echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 -if eval "test \"\${$as_ac_var+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -/* Define $ac_func to an innocuous variant, in case declares $ac_func. - For example, HP-UX 11i declares gettimeofday. */ -#define $ac_func innocuous_$ac_func - -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char $ac_func (); below. - Prefer to if __STDC__ is defined, since - exists even on freestanding compilers. */ - -#ifdef __STDC__ -# include -#else -# include -#endif - -#undef $ac_func - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -{ -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char $ac_func (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_$ac_func) || defined (__stub___$ac_func) -choke me -#else -char (*f) () = $ac_func; -#endif -#ifdef __cplusplus -} -#endif - -int -main () -{ -return f != $ac_func; ; return 0; } _ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - eval "$as_ac_var=yes" +if ac_fn_c_try_compile "$LINENO"; then : + tcl_cv_api_getpwnam_r_4=yes else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -eval "$as_ac_var=no" + tcl_cv_api_getpwnam_r_4=no fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 -if test `eval echo '${'$as_ac_var'}'` = yes; then - cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 -_ACEOF +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_api_getpwnam_r_4" >&5 +$as_echo "$tcl_cv_api_getpwnam_r_4" >&6; } + tcl_ok=$tcl_cv_api_getpwnam_r_4 + if test "$tcl_ok" = yes; then + +$as_echo "#define HAVE_GETPWNAM_R_4 1" >>confdefs.h + + fi + fi + if test "$tcl_ok" = yes; then + +$as_echo "#define HAVE_GETPWNAM_R 1" >>confdefs.h + + fi -else - NEED_FAKE_RFC2553=1 fi -done - echo "$as_me:$LINENO: checking for struct addrinfo" >&5 -echo $ECHO_N "checking for struct addrinfo... $ECHO_C" >&6 -if test "${ac_cv_type_struct_addrinfo+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + ac_fn_c_check_func "$LINENO" "getgrgid_r" "ac_cv_func_getgrgid_r" +if test "x$ac_cv_func_getgrgid_r" = xyes; then : + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for getgrgid_r with 5 args" >&5 +$as_echo_n "checking for getgrgid_r with 5 args... " >&6; } +if ${tcl_cv_api_getgrgid_r_5+:} false; then : + $as_echo_n "(cached) " >&6 else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -#include -#include -#include + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + #include + #include int main () { -if ((struct addrinfo *) 0) - return 0; -if (sizeof (struct addrinfo)) - return 0; + + gid_t gid; + struct group gr, *grp; + char buf[512]; + int buflen = 512; + + (void) getgrgid_r(gid, &gr, buf, buflen, &grp); + ; return 0; } _ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_type_struct_addrinfo=yes +if ac_fn_c_try_compile "$LINENO"; then : + tcl_cv_api_getgrgid_r_5=yes else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_type_struct_addrinfo=no + tcl_cv_api_getgrgid_r_5=no fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi -echo "$as_me:$LINENO: result: $ac_cv_type_struct_addrinfo" >&5 -echo "${ECHO_T}$ac_cv_type_struct_addrinfo" >&6 -if test $ac_cv_type_struct_addrinfo = yes; then - -cat >>confdefs.h <<_ACEOF -#define HAVE_STRUCT_ADDRINFO 1 -_ACEOF +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_api_getgrgid_r_5" >&5 +$as_echo "$tcl_cv_api_getgrgid_r_5" >&6; } + tcl_ok=$tcl_cv_api_getgrgid_r_5 + if test "$tcl_ok" = yes; then +$as_echo "#define HAVE_GETGRGID_R_5 1" >>confdefs.h + else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for getgrgid_r with 4 args" >&5 +$as_echo_n "checking for getgrgid_r with 4 args... " >&6; } +if ${tcl_cv_api_getgrgid_r_4+:} false; then : + $as_echo_n "(cached) " >&6 else - NEED_FAKE_RFC2553=1 -fi -echo "$as_me:$LINENO: checking for struct in6_addr" >&5 -echo $ECHO_N "checking for struct in6_addr... $ECHO_C" >&6 -if test "${ac_cv_type_struct_in6_addr+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -#include -#include -#include + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + #include + #include int main () { -if ((struct in6_addr *) 0) - return 0; -if (sizeof (struct in6_addr)) - return 0; + + gid_t gid; + struct group gr; + char buf[512]; + int buflen = 512; + + (void)getgrgid_r(gid, &gr, buf, buflen); + ; return 0; } _ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_type_struct_in6_addr=yes +if ac_fn_c_try_compile "$LINENO"; then : + tcl_cv_api_getgrgid_r_4=yes else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_type_struct_in6_addr=no + tcl_cv_api_getgrgid_r_4=no fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi -echo "$as_me:$LINENO: result: $ac_cv_type_struct_in6_addr" >&5 -echo "${ECHO_T}$ac_cv_type_struct_in6_addr" >&6 -if test $ac_cv_type_struct_in6_addr = yes; then +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_api_getgrgid_r_4" >&5 +$as_echo "$tcl_cv_api_getgrgid_r_4" >&6; } + tcl_ok=$tcl_cv_api_getgrgid_r_4 + if test "$tcl_ok" = yes; then -cat >>confdefs.h <<_ACEOF -#define HAVE_STRUCT_IN6_ADDR 1 -_ACEOF +$as_echo "#define HAVE_GETGRGID_R_4 1" >>confdefs.h + + fi + fi + if test "$tcl_ok" = yes; then +$as_echo "#define HAVE_GETGRGID_R 1" >>confdefs.h + + fi -else - NEED_FAKE_RFC2553=1 fi -echo "$as_me:$LINENO: checking for struct sockaddr_in6" >&5 -echo $ECHO_N "checking for struct sockaddr_in6... $ECHO_C" >&6 -if test "${ac_cv_type_struct_sockaddr_in6+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + + ac_fn_c_check_func "$LINENO" "getgrnam_r" "ac_cv_func_getgrnam_r" +if test "x$ac_cv_func_getgrnam_r" = xyes; then : + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for getgrnam_r with 5 args" >&5 +$as_echo_n "checking for getgrnam_r with 5 args... " >&6; } +if ${tcl_cv_api_getgrnam_r_5+:} false; then : + $as_echo_n "(cached) " >&6 else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -#include -#include -#include + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + #include + #include int main () { -if ((struct sockaddr_in6 *) 0) - return 0; -if (sizeof (struct sockaddr_in6)) - return 0; + + char *name; + struct group gr, *grp; + char buf[512]; + int buflen = 512; + + (void) getgrnam_r(name, &gr, buf, buflen, &grp); + ; return 0; } _ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_type_struct_sockaddr_in6=yes +if ac_fn_c_try_compile "$LINENO"; then : + tcl_cv_api_getgrnam_r_5=yes else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_type_struct_sockaddr_in6=no + tcl_cv_api_getgrnam_r_5=no fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi -echo "$as_me:$LINENO: result: $ac_cv_type_struct_sockaddr_in6" >&5 -echo "${ECHO_T}$ac_cv_type_struct_sockaddr_in6" >&6 -if test $ac_cv_type_struct_sockaddr_in6 = yes; then - -cat >>confdefs.h <<_ACEOF -#define HAVE_STRUCT_SOCKADDR_IN6 1 -_ACEOF +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_api_getgrnam_r_5" >&5 +$as_echo "$tcl_cv_api_getgrnam_r_5" >&6; } + tcl_ok=$tcl_cv_api_getgrnam_r_5 + if test "$tcl_ok" = yes; then +$as_echo "#define HAVE_GETGRNAM_R_5 1" >>confdefs.h + else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for getgrnam_r with 4 args" >&5 +$as_echo_n "checking for getgrnam_r with 4 args... " >&6; } +if ${tcl_cv_api_getgrnam_r_4+:} false; then : + $as_echo_n "(cached) " >&6 else - NEED_FAKE_RFC2553=1 -fi -echo "$as_me:$LINENO: checking for struct sockaddr_storage" >&5 -echo $ECHO_N "checking for struct sockaddr_storage... $ECHO_C" >&6 -if test "${ac_cv_type_struct_sockaddr_storage+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -#include -#include -#include + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + #include + #include int main () { -if ((struct sockaddr_storage *) 0) - return 0; -if (sizeof (struct sockaddr_storage)) - return 0; + + char *name; + struct group gr; + char buf[512]; + int buflen = 512; + + (void)getgrnam_r(name, &gr, buf, buflen); + ; return 0; } _ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_type_struct_sockaddr_storage=yes +if ac_fn_c_try_compile "$LINENO"; then : + tcl_cv_api_getgrnam_r_4=yes else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_type_struct_sockaddr_storage=no + tcl_cv_api_getgrnam_r_4=no fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi -echo "$as_me:$LINENO: result: $ac_cv_type_struct_sockaddr_storage" >&5 -echo "${ECHO_T}$ac_cv_type_struct_sockaddr_storage" >&6 -if test $ac_cv_type_struct_sockaddr_storage = yes; then +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_api_getgrnam_r_4" >&5 +$as_echo "$tcl_cv_api_getgrnam_r_4" >&6; } + tcl_ok=$tcl_cv_api_getgrnam_r_4 + if test "$tcl_ok" = yes; then -cat >>confdefs.h <<_ACEOF -#define HAVE_STRUCT_SOCKADDR_STORAGE 1 -_ACEOF +$as_echo "#define HAVE_GETGRNAM_R_4 1" >>confdefs.h + + fi + fi + if test "$tcl_ok" = yes; then +$as_echo "#define HAVE_GETGRNAM_R 1" >>confdefs.h + + fi -else - NEED_FAKE_RFC2553=1 fi -if test "x$NEED_FAKE_RFC2553" = "x1"; then + if test "`uname -s`" = "Darwin" && \ + test "`uname -r | awk -F. '{print $1}'`" -gt 5; then + # Starting with Darwin 6 (Mac OSX 10.2), gethostbyX + # are actually MT-safe as they always return pointers + # from TSD instead of static storage. -cat >>confdefs.h <<\_ACEOF -#define NEED_FAKE_RFC2553 1 -_ACEOF +$as_echo "#define HAVE_MTSAFE_GETHOSTBYNAME 1" >>confdefs.h - case $LIBOBJS in - "fake-rfc2553.$ac_objext" | \ - *" fake-rfc2553.$ac_objext" | \ - "fake-rfc2553.$ac_objext "* | \ - *" fake-rfc2553.$ac_objext "* ) ;; - *) LIBOBJS="$LIBOBJS fake-rfc2553.$ac_objext" ;; -esac - echo "$as_me:$LINENO: checking for strlcpy" >&5 -echo $ECHO_N "checking for strlcpy... $ECHO_C" >&6 -if test "${ac_cv_func_strlcpy+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -/* Define strlcpy to an innocuous variant, in case declares strlcpy. - For example, HP-UX 11i declares gettimeofday. */ -#define strlcpy innocuous_strlcpy +$as_echo "#define HAVE_MTSAFE_GETHOSTBYADDR 1" >>confdefs.h -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char strlcpy (); below. - Prefer to if __STDC__ is defined, since - exists even on freestanding compilers. */ -#ifdef __STDC__ -# include -#else -# include -#endif + elif test "`uname -s`" = "HP-UX" && \ + test "`uname -r|sed -e 's|B\.||' -e 's|\..*$||'`" -gt 10; then + # Starting with HPUX 11.00 (we believe), gethostbyX + # are actually MT-safe as they always return pointers + # from TSD instead of static storage. -#undef strlcpy +$as_echo "#define HAVE_MTSAFE_GETHOSTBYNAME 1" >>confdefs.h -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -{ -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char strlcpy (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_strlcpy) || defined (__stub___strlcpy) -choke me -#else -char (*f) () = strlcpy; -#endif -#ifdef __cplusplus -} -#endif + +$as_echo "#define HAVE_MTSAFE_GETHOSTBYADDR 1" >>confdefs.h + + + else + ac_fn_c_check_func "$LINENO" "gethostbyname_r" "ac_cv_func_gethostbyname_r" +if test "x$ac_cv_func_gethostbyname_r" = xyes; then : + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyname_r with 6 args" >&5 +$as_echo_n "checking for gethostbyname_r with 6 args... " >&6; } +if ${tcl_cv_api_gethostbyname_r_6+:} false; then : + $as_echo_n "(cached) " >&6 +else + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #include int main () { -return f != strlcpy; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_func_strlcpy=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_func_strlcpy=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_func_strlcpy" >&5 -echo "${ECHO_T}$ac_cv_func_strlcpy" >&6 - -fi - - -#-------------------------------------------------------------------- -# Look for thread-safe variants of some library functions. -#-------------------------------------------------------------------- - -if test "${TCL_THREADS}" = 1; then - echo "$as_me:$LINENO: checking for getpwuid_r" >&5 -echo $ECHO_N "checking for getpwuid_r... $ECHO_C" >&6 -if test "${ac_cv_func_getpwuid_r+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -/* Define getpwuid_r to an innocuous variant, in case declares getpwuid_r. - For example, HP-UX 11i declares gettimeofday. */ -#define getpwuid_r innocuous_getpwuid_r - -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char getpwuid_r (); below. - Prefer to if __STDC__ is defined, since - exists even on freestanding compilers. */ - -#ifdef __STDC__ -# include -#else -# include -#endif -#undef getpwuid_r + char *name; + struct hostent *he, *res; + char buffer[2048]; + int buflen = 2048; + int h_errnop; -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -{ -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char getpwuid_r (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_getpwuid_r) || defined (__stub___getpwuid_r) -choke me -#else -char (*f) () = getpwuid_r; -#endif -#ifdef __cplusplus -} -#endif + (void) gethostbyname_r(name, he, buffer, buflen, &res, &h_errnop); -int -main () -{ -return f != getpwuid_r; ; return 0; } _ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_func_getpwuid_r=yes +if ac_fn_c_try_compile "$LINENO"; then : + tcl_cv_api_gethostbyname_r_6=yes else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_func_getpwuid_r=no + tcl_cv_api_gethostbyname_r_6=no fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi -echo "$as_me:$LINENO: result: $ac_cv_func_getpwuid_r" >&5 -echo "${ECHO_T}$ac_cv_func_getpwuid_r" >&6 -if test $ac_cv_func_getpwuid_r = yes; then +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_api_gethostbyname_r_6" >&5 +$as_echo "$tcl_cv_api_gethostbyname_r_6" >&6; } + tcl_ok=$tcl_cv_api_gethostbyname_r_6 + if test "$tcl_ok" = yes; then - echo "$as_me:$LINENO: checking for getpwuid_r with 5 args" >&5 -echo $ECHO_N "checking for getpwuid_r with 5 args... $ECHO_C" >&6 -if test "${tcl_cv_api_getpwuid_r_5+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 +$as_echo "#define HAVE_GETHOSTBYNAME_R_6 1" >>confdefs.h + + else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyname_r with 5 args" >&5 +$as_echo_n "checking for gethostbyname_r with 5 args... " >&6; } +if ${tcl_cv_api_gethostbyname_r_5+:} false; then : + $as_echo_n "(cached) " >&6 else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ - #include - #include + #include int main () { - uid_t uid; - struct passwd pw, *pwp; - char buf[512]; - int buflen = 512; + char *name; + struct hostent *he; + char buffer[2048]; + int buflen = 2048; + int h_errnop; - (void) getpwuid_r(uid, &pw, buf, buflen, &pwp); + (void) gethostbyname_r(name, he, buffer, buflen, &h_errnop); ; return 0; } _ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - tcl_cv_api_getpwuid_r_5=yes +if ac_fn_c_try_compile "$LINENO"; then : + tcl_cv_api_gethostbyname_r_5=yes else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -tcl_cv_api_getpwuid_r_5=no + tcl_cv_api_gethostbyname_r_5=no fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi -echo "$as_me:$LINENO: result: $tcl_cv_api_getpwuid_r_5" >&5 -echo "${ECHO_T}$tcl_cv_api_getpwuid_r_5" >&6 - tcl_ok=$tcl_cv_api_getpwuid_r_5 - if test "$tcl_ok" = yes; then +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_api_gethostbyname_r_5" >&5 +$as_echo "$tcl_cv_api_gethostbyname_r_5" >&6; } + tcl_ok=$tcl_cv_api_gethostbyname_r_5 + if test "$tcl_ok" = yes; then -cat >>confdefs.h <<\_ACEOF -#define HAVE_GETPWUID_R_5 1 -_ACEOF +$as_echo "#define HAVE_GETHOSTBYNAME_R_5 1" >>confdefs.h - else - echo "$as_me:$LINENO: checking for getpwuid_r with 4 args" >&5 -echo $ECHO_N "checking for getpwuid_r with 4 args... $ECHO_C" >&6 -if test "${tcl_cv_api_getpwuid_r_4+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyname_r with 3 args" >&5 +$as_echo_n "checking for gethostbyname_r with 3 args... " >&6; } +if ${tcl_cv_api_gethostbyname_r_3+:} false; then : + $as_echo_n "(cached) " >&6 else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ - #include - #include + #include int main () { - uid_t uid; - struct passwd pw; - char buf[512]; - int buflen = 512; + char *name; + struct hostent *he; + struct hostent_data data; - (void)getpwnam_r(uid, &pw, buf, buflen); + (void) gethostbyname_r(name, he, &data); ; return 0; } _ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - tcl_cv_api_getpwuid_r_4=yes +if ac_fn_c_try_compile "$LINENO"; then : + tcl_cv_api_gethostbyname_r_3=yes else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -tcl_cv_api_getpwuid_r_4=no + tcl_cv_api_gethostbyname_r_3=no fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi -echo "$as_me:$LINENO: result: $tcl_cv_api_getpwuid_r_4" >&5 -echo "${ECHO_T}$tcl_cv_api_getpwuid_r_4" >&6 - tcl_ok=$tcl_cv_api_getpwuid_r_4 - if test "$tcl_ok" = yes; then +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_api_gethostbyname_r_3" >&5 +$as_echo "$tcl_cv_api_gethostbyname_r_3" >&6; } + tcl_ok=$tcl_cv_api_gethostbyname_r_3 + if test "$tcl_ok" = yes; then -cat >>confdefs.h <<\_ACEOF -#define HAVE_GETPWUID_R_4 1 -_ACEOF +$as_echo "#define HAVE_GETHOSTBYNAME_R_3 1" >>confdefs.h + fi fi fi if test "$tcl_ok" = yes; then -cat >>confdefs.h <<\_ACEOF -#define HAVE_GETPWUID_R 1 -_ACEOF +$as_echo "#define HAVE_GETHOSTBYNAME_R 1" >>confdefs.h fi fi - echo "$as_me:$LINENO: checking for getpwnam_r" >&5 -echo $ECHO_N "checking for getpwnam_r... $ECHO_C" >&6 -if test "${ac_cv_func_getpwnam_r+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -/* Define getpwnam_r to an innocuous variant, in case declares getpwnam_r. - For example, HP-UX 11i declares gettimeofday. */ -#define getpwnam_r innocuous_getpwnam_r - -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char getpwnam_r (); below. - Prefer to if __STDC__ is defined, since - exists even on freestanding compilers. */ - -#ifdef __STDC__ -# include -#else -# include -#endif - -#undef getpwnam_r - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -{ -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char getpwnam_r (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_getpwnam_r) || defined (__stub___getpwnam_r) -choke me -#else -char (*f) () = getpwnam_r; -#endif -#ifdef __cplusplus -} -#endif - -int -main () -{ -return f != getpwnam_r; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_func_getpwnam_r=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_func_getpwnam_r=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_func_getpwnam_r" >&5 -echo "${ECHO_T}$ac_cv_func_getpwnam_r" >&6 -if test $ac_cv_func_getpwnam_r = yes; then + ac_fn_c_check_func "$LINENO" "gethostbyaddr_r" "ac_cv_func_gethostbyaddr_r" +if test "x$ac_cv_func_gethostbyaddr_r" = xyes; then : - echo "$as_me:$LINENO: checking for getpwnam_r with 5 args" >&5 -echo $ECHO_N "checking for getpwnam_r with 5 args... $ECHO_C" >&6 -if test "${tcl_cv_api_getpwnam_r_5+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyaddr_r with 7 args" >&5 +$as_echo_n "checking for gethostbyaddr_r with 7 args... " >&6; } +if ${tcl_cv_api_gethostbyaddr_r_7+:} false; then : + $as_echo_n "(cached) " >&6 else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ - #include - #include + #include int main () { - char *name; - struct passwd pw, *pwp; - char buf[512]; - int buflen = 512; + char *addr; + int length; + int type; + struct hostent *result; + char buffer[2048]; + int buflen = 2048; + int h_errnop; - (void) getpwnam_r(name, &pw, buf, buflen, &pwp); + (void) gethostbyaddr_r(addr, length, type, result, buffer, buflen, + &h_errnop); ; return 0; } _ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - tcl_cv_api_getpwnam_r_5=yes +if ac_fn_c_try_compile "$LINENO"; then : + tcl_cv_api_gethostbyaddr_r_7=yes else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -tcl_cv_api_getpwnam_r_5=no + tcl_cv_api_gethostbyaddr_r_7=no fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi -echo "$as_me:$LINENO: result: $tcl_cv_api_getpwnam_r_5" >&5 -echo "${ECHO_T}$tcl_cv_api_getpwnam_r_5" >&6 - tcl_ok=$tcl_cv_api_getpwnam_r_5 +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_api_gethostbyaddr_r_7" >&5 +$as_echo "$tcl_cv_api_gethostbyaddr_r_7" >&6; } + tcl_ok=$tcl_cv_api_gethostbyaddr_r_7 if test "$tcl_ok" = yes; then -cat >>confdefs.h <<\_ACEOF -#define HAVE_GETPWNAM_R_5 1 -_ACEOF +$as_echo "#define HAVE_GETHOSTBYADDR_R_7 1" >>confdefs.h else - echo "$as_me:$LINENO: checking for getpwnam_r with 4 args" >&5 -echo $ECHO_N "checking for getpwnam_r with 4 args... $ECHO_C" >&6 -if test "${tcl_cv_api_getpwnam_r_4+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyaddr_r with 8 args" >&5 +$as_echo_n "checking for gethostbyaddr_r with 8 args... " >&6; } +if ${tcl_cv_api_gethostbyaddr_r_8+:} false; then : + $as_echo_n "(cached) " >&6 else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ - #include - #include + #include int main () { - char *name; - struct passwd pw; - char buf[512]; - int buflen = 512; + char *addr; + int length; + int type; + struct hostent *result, *resultp; + char buffer[2048]; + int buflen = 2048; + int h_errnop; - (void)getpwnam_r(name, &pw, buf, buflen); + (void) gethostbyaddr_r(addr, length, type, result, buffer, buflen, + &resultp, &h_errnop); ; return 0; } _ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - tcl_cv_api_getpwnam_r_4=yes +if ac_fn_c_try_compile "$LINENO"; then : + tcl_cv_api_gethostbyaddr_r_8=yes else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -tcl_cv_api_getpwnam_r_4=no + tcl_cv_api_gethostbyaddr_r_8=no fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi -echo "$as_me:$LINENO: result: $tcl_cv_api_getpwnam_r_4" >&5 -echo "${ECHO_T}$tcl_cv_api_getpwnam_r_4" >&6 - tcl_ok=$tcl_cv_api_getpwnam_r_4 +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_api_gethostbyaddr_r_8" >&5 +$as_echo "$tcl_cv_api_gethostbyaddr_r_8" >&6; } + tcl_ok=$tcl_cv_api_gethostbyaddr_r_8 if test "$tcl_ok" = yes; then -cat >>confdefs.h <<\_ACEOF -#define HAVE_GETPWNAM_R_4 1 -_ACEOF +$as_echo "#define HAVE_GETHOSTBYADDR_R_8 1" >>confdefs.h fi fi if test "$tcl_ok" = yes; then -cat >>confdefs.h <<\_ACEOF -#define HAVE_GETPWNAM_R 1 -_ACEOF +$as_echo "#define HAVE_GETHOSTBYADDR_R 1" >>confdefs.h fi fi - echo "$as_me:$LINENO: checking for getgrgid_r" >&5 -echo $ECHO_N "checking for getgrgid_r... $ECHO_C" >&6 -if test "${ac_cv_func_getgrgid_r+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ + fi +fi + +#--------------------------------------------------------------------------- +# Check for serial port interface. +# +# termios.h is present on all POSIX systems. +# sys/ioctl.h is almost always present, though what it contains +# is system-specific. +# sys/modem.h is needed on HP-UX. +#--------------------------------------------------------------------------- + +for ac_header in termios.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "termios.h" "ac_cv_header_termios_h" "$ac_includes_default" +if test "x$ac_cv_header_termios_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_TERMIOS_H 1 _ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -/* Define getgrgid_r to an innocuous variant, in case declares getgrgid_r. - For example, HP-UX 11i declares gettimeofday. */ -#define getgrgid_r innocuous_getgrgid_r -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char getgrgid_r (); below. - Prefer to if __STDC__ is defined, since - exists even on freestanding compilers. */ +fi -#ifdef __STDC__ -# include -#else -# include -#endif +done -#undef getgrgid_r +for ac_header in sys/ioctl.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "sys/ioctl.h" "ac_cv_header_sys_ioctl_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_ioctl_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_SYS_IOCTL_H 1 +_ACEOF -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -{ -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char getgrgid_r (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_getgrgid_r) || defined (__stub___getgrgid_r) -choke me -#else -char (*f) () = getgrgid_r; -#endif -#ifdef __cplusplus -} -#endif +fi + +done + +for ac_header in sys/modem.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "sys/modem.h" "ac_cv_header_sys_modem_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_modem_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_SYS_MODEM_H 1 +_ACEOF + +fi + +done + + +#-------------------------------------------------------------------- +# Include sys/select.h if it exists and if it supplies things +# that appear to be useful and aren't already in sys/types.h. +# This appears to be true only on the RS/6000 under AIX. Some +# systems like OSF/1 have a sys/select.h that's of no use, and +# other systems like SCO UNIX have a sys/select.h that's +# pernicious. If "fd_set" isn't defined anywhere then set a +# special flag. +#-------------------------------------------------------------------- + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fd_set in sys/types" >&5 +$as_echo_n "checking for fd_set in sys/types... " >&6; } +if ${tcl_cv_type_fd_set+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include int main () { -return f != getgrgid_r; +fd_set readMask, writeMask; ; return 0; } _ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_func_getgrgid_r=yes +if ac_fn_c_try_compile "$LINENO"; then : + tcl_cv_type_fd_set=yes else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_func_getgrgid_r=no + tcl_cv_type_fd_set=no fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi -echo "$as_me:$LINENO: result: $ac_cv_func_getgrgid_r" >&5 -echo "${ECHO_T}$ac_cv_func_getgrgid_r" >&6 -if test $ac_cv_func_getgrgid_r = yes; then - - echo "$as_me:$LINENO: checking for getgrgid_r with 5 args" >&5 -echo $ECHO_N "checking for getgrgid_r with 5 args... $ECHO_C" >&6 -if test "${tcl_cv_api_getgrgid_r_5+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_type_fd_set" >&5 +$as_echo "$tcl_cv_type_fd_set" >&6; } +tcl_ok=$tcl_cv_type_fd_set +if test $tcl_ok = no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fd_mask in sys/select" >&5 +$as_echo_n "checking for fd_mask in sys/select... " >&6; } +if ${tcl_cv_grep_fd_mask+:} false; then : + $as_echo_n "(cached) " >&6 else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ +#include - #include - #include +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "fd_mask" >/dev/null 2>&1; then : + tcl_cv_grep_fd_mask=present +else + tcl_cv_grep_fd_mask=missing +fi +rm -f conftest* -int -main () -{ +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_grep_fd_mask" >&5 +$as_echo "$tcl_cv_grep_fd_mask" >&6; } + if test $tcl_cv_grep_fd_mask = present; then - gid_t gid; - struct group gr, *grp; - char buf[512]; - int buflen = 512; +$as_echo "#define HAVE_SYS_SELECT_H 1" >>confdefs.h - (void) getgrgid_r(gid, &gr, buf, buflen, &grp); + tcl_ok=yes + fi +fi +if test $tcl_ok = no; then - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - tcl_cv_api_getgrgid_r_5=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 +$as_echo "#define NO_FD_SET 1" >>confdefs.h -tcl_cv_api_getgrgid_r_5=no fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $tcl_cv_api_getgrgid_r_5" >&5 -echo "${ECHO_T}$tcl_cv_api_getgrgid_r_5" >&6 - tcl_ok=$tcl_cv_api_getgrgid_r_5 - if test "$tcl_ok" = yes; then -cat >>confdefs.h <<\_ACEOF -#define HAVE_GETGRGID_R_5 1 -_ACEOF +#------------------------------------------------------------------------------ +# Find out all about time handling differences. +#------------------------------------------------------------------------------ - else - echo "$as_me:$LINENO: checking for getgrgid_r with 4 args" >&5 -echo $ECHO_N "checking for getgrgid_r with 4 args... $ECHO_C" >&6 -if test "${tcl_cv_api_getgrgid_r_4+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ + for ac_header in sys/time.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "sys/time.h" "ac_cv_header_sys_time_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_time_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_SYS_TIME_H 1 _ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - #include - #include +fi + +done + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether time.h and sys/time.h may both be included" >&5 +$as_echo_n "checking whether time.h and sys/time.h may both be included... " >&6; } +if ${ac_cv_header_time+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include int main () { - - gid_t gid; - struct group gr; - char buf[512]; - int buflen = 512; - - (void)getgrgid_r(gid, &gr, buf, buflen); - +if ((struct tm *) 0) +return 0; ; return 0; } _ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - tcl_cv_api_getgrgid_r_4=yes +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_header_time=yes else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -tcl_cv_api_getgrgid_r_4=no + ac_cv_header_time=no fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi -echo "$as_me:$LINENO: result: $tcl_cv_api_getgrgid_r_4" >&5 -echo "${ECHO_T}$tcl_cv_api_getgrgid_r_4" >&6 - tcl_ok=$tcl_cv_api_getgrgid_r_4 - if test "$tcl_ok" = yes; then +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_time" >&5 +$as_echo "$ac_cv_header_time" >&6; } +if test $ac_cv_header_time = yes; then -cat >>confdefs.h <<\_ACEOF -#define HAVE_GETGRGID_R_4 1 -_ACEOF +$as_echo "#define TIME_WITH_SYS_TIME 1" >>confdefs.h - fi - fi - if test "$tcl_ok" = yes; then +fi -cat >>confdefs.h <<\_ACEOF -#define HAVE_GETGRGID_R 1 -_ACEOF - fi + for ac_func in gmtime_r localtime_r mktime +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF fi +done - echo "$as_me:$LINENO: checking for getgrnam_r" >&5 -echo $ECHO_N "checking for getgrnam_r... $ECHO_C" >&6 -if test "${ac_cv_func_getgrnam_r+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking tm_tzadj in struct tm" >&5 +$as_echo_n "checking tm_tzadj in struct tm... " >&6; } +if ${tcl_cv_member_tm_tzadj+:} false; then : + $as_echo_n "(cached) " >&6 else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -/* Define getgrnam_r to an innocuous variant, in case declares getgrnam_r. - For example, HP-UX 11i declares gettimeofday. */ -#define getgrnam_r innocuous_getgrnam_r -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char getgrnam_r (); below. - Prefer to if __STDC__ is defined, since - exists even on freestanding compilers. */ + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +struct tm tm; tm.tm_tzadj; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + tcl_cv_member_tm_tzadj=yes +else + tcl_cv_member_tm_tzadj=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_member_tm_tzadj" >&5 +$as_echo "$tcl_cv_member_tm_tzadj" >&6; } + if test $tcl_cv_member_tm_tzadj = yes ; then -#ifdef __STDC__ -# include -#else -# include -#endif +$as_echo "#define HAVE_TM_TZADJ 1" >>confdefs.h -#undef getgrnam_r + fi -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -{ -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char getgrnam_r (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_getgrnam_r) || defined (__stub___getgrnam_r) -choke me -#else -char (*f) () = getgrnam_r; -#endif -#ifdef __cplusplus -} -#endif + { $as_echo "$as_me:${as_lineno-$LINENO}: checking tm_gmtoff in struct tm" >&5 +$as_echo_n "checking tm_gmtoff in struct tm... " >&6; } +if ${tcl_cv_member_tm_gmtoff+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include int main () { -return f != getgrnam_r; +struct tm tm; tm.tm_gmtoff; ; return 0; } _ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_func_getgrnam_r=yes +if ac_fn_c_try_compile "$LINENO"; then : + tcl_cv_member_tm_gmtoff=yes else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_func_getgrnam_r=no + tcl_cv_member_tm_gmtoff=no fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi -echo "$as_me:$LINENO: result: $ac_cv_func_getgrnam_r" >&5 -echo "${ECHO_T}$ac_cv_func_getgrnam_r" >&6 -if test $ac_cv_func_getgrnam_r = yes; then +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_member_tm_gmtoff" >&5 +$as_echo "$tcl_cv_member_tm_gmtoff" >&6; } + if test $tcl_cv_member_tm_gmtoff = yes ; then - echo "$as_me:$LINENO: checking for getgrnam_r with 5 args" >&5 -echo $ECHO_N "checking for getgrnam_r with 5 args... $ECHO_C" >&6 -if test "${tcl_cv_api_getgrnam_r_5+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else +$as_echo "#define HAVE_TM_GMTOFF 1" >>confdefs.h - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ + fi - #include - #include + # + # Its important to include time.h in this check, as some systems + # (like convex) have timezone functions, etc. + # + { $as_echo "$as_me:${as_lineno-$LINENO}: checking long timezone variable" >&5 +$as_echo_n "checking long timezone variable... " >&6; } +if ${tcl_cv_timezone_long+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include int main () { - - char *name; - struct group gr, *grp; - char buf[512]; - int buflen = 512; - - (void) getgrnam_r(name, &gr, buf, buflen, &grp); - +extern long timezone; + timezone += 1; + exit (0); ; return 0; } _ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - tcl_cv_api_getgrnam_r_5=yes +if ac_fn_c_try_compile "$LINENO"; then : + tcl_cv_timezone_long=yes else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -tcl_cv_api_getgrnam_r_5=no + tcl_cv_timezone_long=no fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi -echo "$as_me:$LINENO: result: $tcl_cv_api_getgrnam_r_5" >&5 -echo "${ECHO_T}$tcl_cv_api_getgrnam_r_5" >&6 - tcl_ok=$tcl_cv_api_getgrnam_r_5 - if test "$tcl_ok" = yes; then +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_timezone_long" >&5 +$as_echo "$tcl_cv_timezone_long" >&6; } + if test $tcl_cv_timezone_long = yes ; then -cat >>confdefs.h <<\_ACEOF -#define HAVE_GETGRNAM_R_5 1 -_ACEOF +$as_echo "#define HAVE_TIMEZONE_VAR 1" >>confdefs.h else - echo "$as_me:$LINENO: checking for getgrnam_r with 4 args" >&5 -echo $ECHO_N "checking for getgrnam_r with 4 args... $ECHO_C" >&6 -if test "${tcl_cv_api_getgrnam_r_4+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + # + # On some systems (eg IRIX 6.2), timezone is a time_t and not a long. + # + { $as_echo "$as_me:${as_lineno-$LINENO}: checking time_t timezone variable" >&5 +$as_echo_n "checking time_t timezone variable... " >&6; } +if ${tcl_cv_timezone_time+:} false; then : + $as_echo_n "(cached) " >&6 else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ - - #include - #include - +#include int main () { - - char *name; - struct group gr; - char buf[512]; - int buflen = 512; - - (void)getgrnam_r(name, &gr, buf, buflen); - +extern time_t timezone; + timezone += 1; + exit (0); ; return 0; } _ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - tcl_cv_api_getgrnam_r_4=yes +if ac_fn_c_try_compile "$LINENO"; then : + tcl_cv_timezone_time=yes else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -tcl_cv_api_getgrnam_r_4=no + tcl_cv_timezone_time=no fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi -echo "$as_me:$LINENO: result: $tcl_cv_api_getgrnam_r_4" >&5 -echo "${ECHO_T}$tcl_cv_api_getgrnam_r_4" >&6 - tcl_ok=$tcl_cv_api_getgrnam_r_4 - if test "$tcl_ok" = yes; then +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_timezone_time" >&5 +$as_echo "$tcl_cv_timezone_time" >&6; } + if test $tcl_cv_timezone_time = yes ; then -cat >>confdefs.h <<\_ACEOF -#define HAVE_GETGRNAM_R_4 1 -_ACEOF +$as_echo "#define HAVE_TIMEZONE_VAR 1" >>confdefs.h fi fi - if test "$tcl_ok" = yes; then -cat >>confdefs.h <<\_ACEOF -#define HAVE_GETGRNAM_R 1 -_ACEOF - fi - -fi +#-------------------------------------------------------------------- +# Some systems (e.g., IRIX 4.0.5) lack some fields in struct stat. But +# we might be able to use fstatfs instead. Some systems (OpenBSD?) also +# lack blkcnt_t. +#-------------------------------------------------------------------- - if test "`uname -s`" = "Darwin" && \ - test "`uname -r | awk -F. '{print $1}'`" -gt 5; then - # Starting with Darwin 6 (Mac OSX 10.2), gethostbyX - # are actually MT-safe as they always return pointers - # from TSD instead of static storage. +if test "$ac_cv_cygwin" != "yes"; then + ac_fn_c_check_member "$LINENO" "struct stat" "st_blocks" "ac_cv_member_struct_stat_st_blocks" "$ac_includes_default" +if test "x$ac_cv_member_struct_stat_st_blocks" = xyes; then : -cat >>confdefs.h <<\_ACEOF -#define HAVE_MTSAFE_GETHOSTBYNAME 1 +cat >>confdefs.h <<_ACEOF +#define HAVE_STRUCT_STAT_ST_BLOCKS 1 _ACEOF -cat >>confdefs.h <<\_ACEOF -#define HAVE_MTSAFE_GETHOSTBYADDR 1 +fi +ac_fn_c_check_member "$LINENO" "struct stat" "st_blksize" "ac_cv_member_struct_stat_st_blksize" "$ac_includes_default" +if test "x$ac_cv_member_struct_stat_st_blksize" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_STRUCT_STAT_ST_BLKSIZE 1 _ACEOF - elif test "`uname -s`" = "HP-UX" && \ - test "`uname -r|sed -e 's|B\.||' -e 's|\..*$||'`" -gt 10; then - # Starting with HPUX 11.00 (we believe), gethostbyX - # are actually MT-safe as they always return pointers - # from TSD instead of static storage. +fi + +fi +ac_fn_c_check_type "$LINENO" "blkcnt_t" "ac_cv_type_blkcnt_t" "$ac_includes_default" +if test "x$ac_cv_type_blkcnt_t" = xyes; then : -cat >>confdefs.h <<\_ACEOF -#define HAVE_MTSAFE_GETHOSTBYNAME 1 +cat >>confdefs.h <<_ACEOF +#define HAVE_BLKCNT_T 1 _ACEOF -cat >>confdefs.h <<\_ACEOF -#define HAVE_MTSAFE_GETHOSTBYADDR 1 -_ACEOF +fi +ac_fn_c_check_func "$LINENO" "fstatfs" "ac_cv_func_fstatfs" +if test "x$ac_cv_func_fstatfs" = xyes; then : - else - echo "$as_me:$LINENO: checking for gethostbyname_r" >&5 -echo $ECHO_N "checking for gethostbyname_r... $ECHO_C" >&6 -if test "${ac_cv_func_gethostbyname_r+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -/* Define gethostbyname_r to an innocuous variant, in case declares gethostbyname_r. - For example, HP-UX 11i declares gettimeofday. */ -#define gethostbyname_r innocuous_gethostbyname_r -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char gethostbyname_r (); below. - Prefer to if __STDC__ is defined, since - exists even on freestanding compilers. */ +$as_echo "#define NO_FSTATFS 1" >>confdefs.h -#ifdef __STDC__ -# include -#else -# include -#endif +fi -#undef gethostbyname_r -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -{ -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char gethostbyname_r (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_gethostbyname_r) || defined (__stub___gethostbyname_r) -choke me -#else -char (*f) () = gethostbyname_r; -#endif -#ifdef __cplusplus -} -#endif +#-------------------------------------------------------------------- +# Some system have no memcmp or it does not work with 8 bit data, this +# checks it and add memcmp.o to LIBOBJS if needed +#-------------------------------------------------------------------- +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working memcmp" >&5 +$as_echo_n "checking for working memcmp... " >&6; } +if ${ac_cv_func_memcmp_working+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + ac_cv_func_memcmp_working=no +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default int main () { -return f != gethostbyname_r; + + /* Some versions of memcmp are not 8-bit clean. */ + char c0 = '\100', c1 = '\200', c2 = '\201'; + if (memcmp(&c0, &c2, 1) >= 0 || memcmp(&c1, &c2, 1) >= 0) + return 1; + + /* The Next x86 OpenStep bug shows up only when comparing 16 bytes + or more and with at least one buffer not starting on a 4-byte boundary. + William Lewis provided this test program. */ + { + char foo[21]; + char bar[21]; + int i; + for (i = 0; i < 4; i++) + { + char *a = foo + i; + char *b = bar + i; + strcpy (a, "--------01111111"); + strcpy (b, "--------10000000"); + if (memcmp (a, b, 16) >= 0) + return 1; + } + return 0; + } + ; return 0; } _ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_func_gethostbyname_r=yes +if ac_fn_c_try_run "$LINENO"; then : + ac_cv_func_memcmp_working=yes else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_func_gethostbyname_r=no + ac_cv_func_memcmp_working=no fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext fi -echo "$as_me:$LINENO: result: $ac_cv_func_gethostbyname_r" >&5 -echo "${ECHO_T}$ac_cv_func_gethostbyname_r" >&6 -if test $ac_cv_func_gethostbyname_r = yes; then - - echo "$as_me:$LINENO: checking for gethostbyname_r with 6 args" >&5 -echo $ECHO_N "checking for gethostbyname_r with 6 args... $ECHO_C" >&6 -if test "${tcl_cv_api_gethostbyname_r_6+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_memcmp_working" >&5 +$as_echo "$ac_cv_func_memcmp_working" >&6; } +test $ac_cv_func_memcmp_working = no && case " $LIBOBJS " in + *" memcmp.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS memcmp.$ac_objext" + ;; +esac - #include -int -main () -{ - char *name; - struct hostent *he, *res; - char buffer[2048]; - int buflen = 2048; - int h_errnop; +#-------------------------------------------------------------------- +# Some system like SunOS 4 and other BSD like systems have no memmove +# (we assume they have bcopy instead). {The replacement define is in +# compat/string.h} +#-------------------------------------------------------------------- - (void) gethostbyname_r(name, he, buffer, buflen, &res, &h_errnop); +ac_fn_c_check_func "$LINENO" "memmove" "ac_cv_func_memmove" +if test "x$ac_cv_func_memmove" = xyes; then : - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - tcl_cv_api_gethostbyname_r_6=yes else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 -tcl_cv_api_gethostbyname_r_6=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $tcl_cv_api_gethostbyname_r_6" >&5 -echo "${ECHO_T}$tcl_cv_api_gethostbyname_r_6" >&6 - tcl_ok=$tcl_cv_api_gethostbyname_r_6 - if test "$tcl_ok" = yes; then -cat >>confdefs.h <<\_ACEOF -#define HAVE_GETHOSTBYNAME_R_6 1 -_ACEOF +$as_echo "#define NO_MEMMOVE 1" >>confdefs.h - else - echo "$as_me:$LINENO: checking for gethostbyname_r with 5 args" >&5 -echo $ECHO_N "checking for gethostbyname_r with 5 args... $ECHO_C" >&6 -if test "${tcl_cv_api_gethostbyname_r_5+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ +$as_echo "#define NO_STRING_H 1" >>confdefs.h - #include +fi -int -main () -{ - char *name; - struct hostent *he; - char buffer[2048]; - int buflen = 2048; - int h_errnop; +#-------------------------------------------------------------------- +# On some systems strstr is broken: it returns a pointer even even if +# the original string is empty. +#-------------------------------------------------------------------- - (void) gethostbyname_r(name, he, buffer, buflen, &h_errnop); - ; - return 0; + ac_fn_c_check_func "$LINENO" "strstr" "ac_cv_func_strstr" +if test "x$ac_cv_func_strstr" = xyes; then : + tcl_ok=1 +else + tcl_ok=0 +fi + + if test "$tcl_ok" = 1; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking proper strstr implementation" >&5 +$as_echo_n "checking proper strstr implementation... " >&6; } +if ${tcl_cv_strstr_unbroken+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + tcl_cv_strstr_unbroken=unknown +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +int main() { + extern int strstr(); + exit(strstr("\0test", "test") ? 1 : 0); } _ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - tcl_cv_api_gethostbyname_r_5=yes +if ac_fn_c_try_run "$LINENO"; then : + tcl_cv_strstr_unbroken=ok else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -tcl_cv_api_gethostbyname_r_5=no + tcl_cv_strstr_unbroken=broken fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext fi -echo "$as_me:$LINENO: result: $tcl_cv_api_gethostbyname_r_5" >&5 -echo "${ECHO_T}$tcl_cv_api_gethostbyname_r_5" >&6 - tcl_ok=$tcl_cv_api_gethostbyname_r_5 - if test "$tcl_ok" = yes; then - -cat >>confdefs.h <<\_ACEOF -#define HAVE_GETHOSTBYNAME_R_5 1 -_ACEOF +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_strstr_unbroken" >&5 +$as_echo "$tcl_cv_strstr_unbroken" >&6; } + if test "$tcl_cv_strstr_unbroken" = "ok"; then + tcl_ok=1 else - echo "$as_me:$LINENO: checking for gethostbyname_r with 3 args" >&5 -echo $ECHO_N "checking for gethostbyname_r with 3 args... $ECHO_C" >&6 -if test "${tcl_cv_api_gethostbyname_r_3+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else + tcl_ok=0 + fi + fi + if test "$tcl_ok" = 0; then + case " $LIBOBJS " in + *" strstr.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS strstr.$ac_objext" + ;; +esac - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ + USE_COMPAT=1 + fi - #include -int -main () -{ +#-------------------------------------------------------------------- +# Check for strtoul function. This is tricky because under some +# versions of AIX strtoul returns an incorrect terminator +# pointer for the string "0". +#-------------------------------------------------------------------- - char *name; - struct hostent *he; - struct hostent_data data; - (void) gethostbyname_r(name, he, &data); + ac_fn_c_check_func "$LINENO" "strtoul" "ac_cv_func_strtoul" +if test "x$ac_cv_func_strtoul" = xyes; then : + tcl_ok=1 +else + tcl_ok=0 +fi - ; - return 0; + if test "$tcl_ok" = 1; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking proper strtoul implementation" >&5 +$as_echo_n "checking proper strtoul implementation... " >&6; } +if ${tcl_cv_strtoul_unbroken+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + tcl_cv_strtoul_unbroken=unknown +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +int main() { + extern int strtoul(); + char *term, *string = "0"; + exit(strtoul(string,&term,0) != 0 || term != string+1); } _ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - tcl_cv_api_gethostbyname_r_3=yes +if ac_fn_c_try_run "$LINENO"; then : + tcl_cv_strtoul_unbroken=ok else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -tcl_cv_api_gethostbyname_r_3=no + tcl_cv_strtoul_unbroken=broken fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext fi -echo "$as_me:$LINENO: result: $tcl_cv_api_gethostbyname_r_3" >&5 -echo "${ECHO_T}$tcl_cv_api_gethostbyname_r_3" >&6 - tcl_ok=$tcl_cv_api_gethostbyname_r_3 - if test "$tcl_ok" = yes; then - -cat >>confdefs.h <<\_ACEOF -#define HAVE_GETHOSTBYNAME_R_3 1 -_ACEOF - fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_strtoul_unbroken" >&5 +$as_echo "$tcl_cv_strtoul_unbroken" >&6; } + if test "$tcl_cv_strtoul_unbroken" = "ok"; then + tcl_ok=1 + else + tcl_ok=0 fi fi - if test "$tcl_ok" = yes; then - -cat >>confdefs.h <<\_ACEOF -#define HAVE_GETHOSTBYNAME_R 1 -_ACEOF + if test "$tcl_ok" = 0; then + case " $LIBOBJS " in + *" strtoul.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS strtoul.$ac_objext" + ;; +esac + USE_COMPAT=1 fi + +#-------------------------------------------------------------------- +# Check for the strtod function. This is tricky because in some +# versions of Linux strtod mis-parses strings starting with "+". +#-------------------------------------------------------------------- + + + ac_fn_c_check_func "$LINENO" "strtod" "ac_cv_func_strtod" +if test "x$ac_cv_func_strtod" = xyes; then : + tcl_ok=1 +else + tcl_ok=0 fi - echo "$as_me:$LINENO: checking for gethostbyaddr_r" >&5 -echo $ECHO_N "checking for gethostbyaddr_r... $ECHO_C" >&6 -if test "${ac_cv_func_gethostbyaddr_r+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + if test "$tcl_ok" = 1; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking proper strtod implementation" >&5 +$as_echo_n "checking proper strtod implementation... " >&6; } +if ${tcl_cv_strtod_unbroken+:} false; then : + $as_echo_n "(cached) " >&6 else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -/* Define gethostbyaddr_r to an innocuous variant, in case declares gethostbyaddr_r. - For example, HP-UX 11i declares gettimeofday. */ -#define gethostbyaddr_r innocuous_gethostbyaddr_r - -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char gethostbyaddr_r (); below. - Prefer to if __STDC__ is defined, since - exists even on freestanding compilers. */ - -#ifdef __STDC__ -# include -#else -# include -#endif - -#undef gethostbyaddr_r - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -{ -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char gethostbyaddr_r (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_gethostbyaddr_r) || defined (__stub___gethostbyaddr_r) -choke me -#else -char (*f) () = gethostbyaddr_r; -#endif -#ifdef __cplusplus -} -#endif - -int -main () -{ -return f != gethostbyaddr_r; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_func_gethostbyaddr_r=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_func_gethostbyaddr_r=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_func_gethostbyaddr_r" >&5 -echo "${ECHO_T}$ac_cv_func_gethostbyaddr_r" >&6 -if test $ac_cv_func_gethostbyaddr_r = yes; then - - echo "$as_me:$LINENO: checking for gethostbyaddr_r with 7 args" >&5 -echo $ECHO_N "checking for gethostbyaddr_r with 7 args... $ECHO_C" >&6 -if test "${tcl_cv_api_gethostbyaddr_r_7+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + if test "$cross_compiling" = yes; then : + tcl_cv_strtod_unbroken=unknown else - - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ - - #include - -int -main () -{ - - char *addr; - int length; - int type; - struct hostent *result; - char buffer[2048]; - int buflen = 2048; - int h_errnop; - - (void) gethostbyaddr_r(addr, length, type, result, buffer, buflen, - &h_errnop); - - ; - return 0; +int main() { + extern double strtod(); + char *term, *string = " +69"; + exit(strtod(string,&term) != 69 || term != string+4); } _ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - tcl_cv_api_gethostbyaddr_r_7=yes +if ac_fn_c_try_run "$LINENO"; then : + tcl_cv_strtod_unbroken=ok else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -tcl_cv_api_gethostbyaddr_r_7=no + tcl_cv_strtod_unbroken=broken fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext fi -echo "$as_me:$LINENO: result: $tcl_cv_api_gethostbyaddr_r_7" >&5 -echo "${ECHO_T}$tcl_cv_api_gethostbyaddr_r_7" >&6 - tcl_ok=$tcl_cv_api_gethostbyaddr_r_7 - if test "$tcl_ok" = yes; then - -cat >>confdefs.h <<\_ACEOF -#define HAVE_GETHOSTBYADDR_R_7 1 -_ACEOF - - else - echo "$as_me:$LINENO: checking for gethostbyaddr_r with 8 args" >&5 -echo $ECHO_N "checking for gethostbyaddr_r with 8 args... $ECHO_C" >&6 -if test "${tcl_cv_api_gethostbyaddr_r_8+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - - #include - -int -main () -{ - char *addr; - int length; - int type; - struct hostent *result, *resultp; - char buffer[2048]; - int buflen = 2048; - int h_errnop; - - (void) gethostbyaddr_r(addr, length, type, result, buffer, buflen, - &resultp, &h_errnop); - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - tcl_cv_api_gethostbyaddr_r_8=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -tcl_cv_api_gethostbyaddr_r_8=no fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $tcl_cv_api_gethostbyaddr_r_8" >&5 -echo "${ECHO_T}$tcl_cv_api_gethostbyaddr_r_8" >&6 - tcl_ok=$tcl_cv_api_gethostbyaddr_r_8 - if test "$tcl_ok" = yes; then - -cat >>confdefs.h <<\_ACEOF -#define HAVE_GETHOSTBYADDR_R_8 1 -_ACEOF - +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_strtod_unbroken" >&5 +$as_echo "$tcl_cv_strtod_unbroken" >&6; } + if test "$tcl_cv_strtod_unbroken" = "ok"; then + tcl_ok=1 + else + tcl_ok=0 fi fi - if test "$tcl_ok" = yes; then - -cat >>confdefs.h <<\_ACEOF -#define HAVE_GETHOSTBYADDR_R 1 -_ACEOF - - fi - -fi + if test "$tcl_ok" = 0; then + case " $LIBOBJS " in + *" strtod.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS strtod.$ac_objext" + ;; +esac + USE_COMPAT=1 fi -fi - -#--------------------------------------------------------------------------- -# Check for serial port interface. -# -# termios.h is present on all POSIX systems. -# sys/ioctl.h is almost always present, though what it contains -# is system-specific. -# sys/modem.h is needed on HP-UX. -#--------------------------------------------------------------------------- -for ac_header in termios.h -do -as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 -else - # Is the header compilable? -echo "$as_me:$LINENO: checking $ac_header usability" >&5 -echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -#include <$ac_header> -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_header_compiler=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 +#-------------------------------------------------------------------- +# Under Solaris 2.4, strtod returns the wrong value for the +# terminating character under some conditions. Check for this +# and if the problem exists use a substitute procedure +# "fixstrtod" that corrects the error. +#-------------------------------------------------------------------- -ac_header_compiler=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -echo "${ECHO_T}$ac_header_compiler" >&6 -# Is the header present? -echo "$as_me:$LINENO: checking $ac_header presence" >&5 -echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include <$ac_header> -_ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - ac_header_preproc=yes + ac_fn_c_check_func "$LINENO" "strtod" "ac_cv_func_strtod" +if test "x$ac_cv_func_strtod" = xyes; then : + tcl_strtod=1 else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_header_preproc=no + tcl_strtod=0 fi -rm -f conftest.err conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -echo "${ECHO_T}$ac_header_preproc" >&6 -# So? What about this header? -case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in - yes:no: ) - { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 -echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 -echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} - ac_header_preproc=yes - ;; - no:yes:* ) - { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 -echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 -echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 -echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 -echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 -echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} - ( - cat <<\_ASBOX -## ------------------------------ ## -## Report this to the tcl lists. ## -## ------------------------------ ## -_ASBOX - ) | - sed "s/^/$as_me: WARNING: /" >&2 - ;; -esac -echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + if test "$tcl_strtod" = 1; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Solaris2.4/Tru64 strtod bugs" >&5 +$as_echo_n "checking for Solaris2.4/Tru64 strtod bugs... " >&6; } +if ${tcl_cv_strtod_buggy+:} false; then : + $as_echo_n "(cached) " >&6 else - eval "$as_ac_Header=\$ac_header_preproc" -fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 - -fi -if test `eval echo '${'$as_ac_Header'}'` = yes; then - cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF - -fi - -done - -for ac_header in sys/ioctl.h -do -as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 -else - # Is the header compilable? -echo "$as_me:$LINENO: checking $ac_header usability" >&5 -echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -#include <$ac_header> -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_header_compiler=yes + if test "$cross_compiling" = yes; then : + tcl_cv_strtod_buggy=buggy else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_header_compiler=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -echo "${ECHO_T}$ac_header_compiler" >&6 - -# Is the header present? -echo "$as_me:$LINENO: checking $ac_header presence" >&5 -echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#include <$ac_header> -_ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - ac_header_preproc=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_header_preproc=no -fi -rm -f conftest.err conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -echo "${ECHO_T}$ac_header_preproc" >&6 - -# So? What about this header? -case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in - yes:no: ) - { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 -echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 -echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} - ac_header_preproc=yes - ;; - no:yes:* ) - { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 -echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 -echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 -echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 -echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 -echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} - ( - cat <<\_ASBOX -## ------------------------------ ## -## Report this to the tcl lists. ## -## ------------------------------ ## -_ASBOX - ) | - sed "s/^/$as_me: WARNING: /" >&2 - ;; -esac -echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - eval "$as_ac_Header=\$ac_header_preproc" -fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 - -fi -if test `eval echo '${'$as_ac_Header'}'` = yes; then - cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF - -fi -done - - -for ac_header in sys/modem.h -do -as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 -else - # Is the header compilable? -echo "$as_me:$LINENO: checking $ac_header usability" >&5 -echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -#include <$ac_header> -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_header_compiler=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_header_compiler=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -echo "${ECHO_T}$ac_header_compiler" >&6 - -# Is the header present? -echo "$as_me:$LINENO: checking $ac_header presence" >&5 -echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include <$ac_header> -_ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - ac_header_preproc=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_header_preproc=no -fi -rm -f conftest.err conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -echo "${ECHO_T}$ac_header_preproc" >&6 - -# So? What about this header? -case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in - yes:no: ) - { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 -echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 -echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} - ac_header_preproc=yes - ;; - no:yes:* ) - { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 -echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 -echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 -echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 -echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 -echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} - ( - cat <<\_ASBOX -## ------------------------------ ## -## Report this to the tcl lists. ## -## ------------------------------ ## -_ASBOX - ) | - sed "s/^/$as_me: WARNING: /" >&2 - ;; -esac -echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - eval "$as_ac_Header=\$ac_header_preproc" -fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 - -fi -if test `eval echo '${'$as_ac_Header'}'` = yes; then - cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF - -fi - -done - - -#-------------------------------------------------------------------- -# Include sys/select.h if it exists and if it supplies things -# that appear to be useful and aren't already in sys/types.h. -# This appears to be true only on the RS/6000 under AIX. Some -# systems like OSF/1 have a sys/select.h that's of no use, and -# other systems like SCO UNIX have a sys/select.h that's -# pernicious. If "fd_set" isn't defined anywhere then set a -# special flag. -#-------------------------------------------------------------------- - -echo "$as_me:$LINENO: checking for fd_set in sys/types" >&5 -echo $ECHO_N "checking for fd_set in sys/types... $ECHO_C" >&6 -if test "${tcl_cv_type_fd_set+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -int -main () -{ -fd_set readMask, writeMask; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - tcl_cv_type_fd_set=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -tcl_cv_type_fd_set=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $tcl_cv_type_fd_set" >&5 -echo "${ECHO_T}$tcl_cv_type_fd_set" >&6 -tcl_ok=$tcl_cv_type_fd_set -if test $tcl_ok = no; then - echo "$as_me:$LINENO: checking for fd_mask in sys/select" >&5 -echo $ECHO_N "checking for fd_mask in sys/select... $ECHO_C" >&6 -if test "${tcl_cv_grep_fd_mask+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "fd_mask" >/dev/null 2>&1; then - tcl_cv_grep_fd_mask=present -else - tcl_cv_grep_fd_mask=missing -fi -rm -f conftest* - -fi -echo "$as_me:$LINENO: result: $tcl_cv_grep_fd_mask" >&5 -echo "${ECHO_T}$tcl_cv_grep_fd_mask" >&6 - if test $tcl_cv_grep_fd_mask = present; then - -cat >>confdefs.h <<\_ACEOF -#define HAVE_SYS_SELECT_H 1 -_ACEOF - - tcl_ok=yes - fi -fi -if test $tcl_ok = no; then - -cat >>confdefs.h <<\_ACEOF -#define NO_FD_SET 1 -_ACEOF - -fi - -#------------------------------------------------------------------------------ -# Find out all about time handling differences. -#------------------------------------------------------------------------------ - - - -for ac_header in sys/time.h -do -as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 -else - # Is the header compilable? -echo "$as_me:$LINENO: checking $ac_header usability" >&5 -echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -#include <$ac_header> -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_header_compiler=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_header_compiler=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -echo "${ECHO_T}$ac_header_compiler" >&6 - -# Is the header present? -echo "$as_me:$LINENO: checking $ac_header presence" >&5 -echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include <$ac_header> -_ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - ac_header_preproc=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_header_preproc=no -fi -rm -f conftest.err conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -echo "${ECHO_T}$ac_header_preproc" >&6 - -# So? What about this header? -case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in - yes:no: ) - { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 -echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 -echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} - ac_header_preproc=yes - ;; - no:yes:* ) - { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 -echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 -echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 -echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 -echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 -echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} - ( - cat <<\_ASBOX -## ------------------------------ ## -## Report this to the tcl lists. ## -## ------------------------------ ## -_ASBOX - ) | - sed "s/^/$as_me: WARNING: /" >&2 - ;; -esac -echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - eval "$as_ac_Header=\$ac_header_preproc" -fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 - -fi -if test `eval echo '${'$as_ac_Header'}'` = yes; then - cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF - -fi - -done - - echo "$as_me:$LINENO: checking whether time.h and sys/time.h may both be included" >&5 -echo $ECHO_N "checking whether time.h and sys/time.h may both be included... $ECHO_C" >&6 -if test "${ac_cv_header_time+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -#include -#include - -int -main () -{ -if ((struct tm *) 0) -return 0; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_header_time=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_header_time=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_header_time" >&5 -echo "${ECHO_T}$ac_cv_header_time" >&6 -if test $ac_cv_header_time = yes; then - -cat >>confdefs.h <<\_ACEOF -#define TIME_WITH_SYS_TIME 1 -_ACEOF - -fi - - - - - -for ac_func in gmtime_r localtime_r mktime -do -as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` -echo "$as_me:$LINENO: checking for $ac_func" >&5 -echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 -if eval "test \"\${$as_ac_var+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -/* Define $ac_func to an innocuous variant, in case declares $ac_func. - For example, HP-UX 11i declares gettimeofday. */ -#define $ac_func innocuous_$ac_func - -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char $ac_func (); below. - Prefer to if __STDC__ is defined, since - exists even on freestanding compilers. */ - -#ifdef __STDC__ -# include -#else -# include -#endif - -#undef $ac_func - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -{ -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char $ac_func (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_$ac_func) || defined (__stub___$ac_func) -choke me -#else -char (*f) () = $ac_func; -#endif -#ifdef __cplusplus -} -#endif - -int -main () -{ -return f != $ac_func; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - eval "$as_ac_var=yes" -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -eval "$as_ac_var=no" -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 -if test `eval echo '${'$as_ac_var'}'` = yes; then - cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 -_ACEOF - -fi -done - - - echo "$as_me:$LINENO: checking tm_tzadj in struct tm" >&5 -echo $ECHO_N "checking tm_tzadj in struct tm... $ECHO_C" >&6 -if test "${tcl_cv_member_tm_tzadj+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -int -main () -{ -struct tm tm; tm.tm_tzadj; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - tcl_cv_member_tm_tzadj=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -tcl_cv_member_tm_tzadj=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $tcl_cv_member_tm_tzadj" >&5 -echo "${ECHO_T}$tcl_cv_member_tm_tzadj" >&6 - if test $tcl_cv_member_tm_tzadj = yes ; then - -cat >>confdefs.h <<\_ACEOF -#define HAVE_TM_TZADJ 1 -_ACEOF - - fi - - echo "$as_me:$LINENO: checking tm_gmtoff in struct tm" >&5 -echo $ECHO_N "checking tm_gmtoff in struct tm... $ECHO_C" >&6 -if test "${tcl_cv_member_tm_gmtoff+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -int -main () -{ -struct tm tm; tm.tm_gmtoff; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - tcl_cv_member_tm_gmtoff=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -tcl_cv_member_tm_gmtoff=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $tcl_cv_member_tm_gmtoff" >&5 -echo "${ECHO_T}$tcl_cv_member_tm_gmtoff" >&6 - if test $tcl_cv_member_tm_gmtoff = yes ; then - -cat >>confdefs.h <<\_ACEOF -#define HAVE_TM_GMTOFF 1 -_ACEOF - - fi - - # - # Its important to include time.h in this check, as some systems - # (like convex) have timezone functions, etc. - # - echo "$as_me:$LINENO: checking long timezone variable" >&5 -echo $ECHO_N "checking long timezone variable... $ECHO_C" >&6 -if test "${tcl_cv_timezone_long+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -int -main () -{ -extern long timezone; - timezone += 1; - exit (0); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - tcl_cv_timezone_long=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -tcl_cv_timezone_long=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $tcl_cv_timezone_long" >&5 -echo "${ECHO_T}$tcl_cv_timezone_long" >&6 - if test $tcl_cv_timezone_long = yes ; then - -cat >>confdefs.h <<\_ACEOF -#define HAVE_TIMEZONE_VAR 1 -_ACEOF - - else - # - # On some systems (eg IRIX 6.2), timezone is a time_t and not a long. - # - echo "$as_me:$LINENO: checking time_t timezone variable" >&5 -echo $ECHO_N "checking time_t timezone variable... $ECHO_C" >&6 -if test "${tcl_cv_timezone_time+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -int -main () -{ -extern time_t timezone; - timezone += 1; - exit (0); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - tcl_cv_timezone_time=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -tcl_cv_timezone_time=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $tcl_cv_timezone_time" >&5 -echo "${ECHO_T}$tcl_cv_timezone_time" >&6 - if test $tcl_cv_timezone_time = yes ; then - -cat >>confdefs.h <<\_ACEOF -#define HAVE_TIMEZONE_VAR 1 -_ACEOF - - fi - fi - - -#-------------------------------------------------------------------- -# Some systems (e.g., IRIX 4.0.5) lack some fields in struct stat. But -# we might be able to use fstatfs instead. Some systems (OpenBSD?) also -# lack blkcnt_t. -#-------------------------------------------------------------------- - -if test "$ac_cv_cygwin" != "yes"; then - echo "$as_me:$LINENO: checking for struct stat.st_blocks" >&5 -echo $ECHO_N "checking for struct stat.st_blocks... $ECHO_C" >&6 -if test "${ac_cv_member_struct_stat_st_blocks+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -int -main () -{ -static struct stat ac_aggr; -if (ac_aggr.st_blocks) -return 0; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_member_struct_stat_st_blocks=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -int -main () -{ -static struct stat ac_aggr; -if (sizeof ac_aggr.st_blocks) -return 0; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_member_struct_stat_st_blocks=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_member_struct_stat_st_blocks=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_member_struct_stat_st_blocks" >&5 -echo "${ECHO_T}$ac_cv_member_struct_stat_st_blocks" >&6 -if test $ac_cv_member_struct_stat_st_blocks = yes; then - -cat >>confdefs.h <<_ACEOF -#define HAVE_STRUCT_STAT_ST_BLOCKS 1 -_ACEOF - - -fi -echo "$as_me:$LINENO: checking for struct stat.st_blksize" >&5 -echo $ECHO_N "checking for struct stat.st_blksize... $ECHO_C" >&6 -if test "${ac_cv_member_struct_stat_st_blksize+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -int -main () -{ -static struct stat ac_aggr; -if (ac_aggr.st_blksize) -return 0; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_member_struct_stat_st_blksize=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -int -main () -{ -static struct stat ac_aggr; -if (sizeof ac_aggr.st_blksize) -return 0; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_member_struct_stat_st_blksize=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_member_struct_stat_st_blksize=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_member_struct_stat_st_blksize" >&5 -echo "${ECHO_T}$ac_cv_member_struct_stat_st_blksize" >&6 -if test $ac_cv_member_struct_stat_st_blksize = yes; then - -cat >>confdefs.h <<_ACEOF -#define HAVE_STRUCT_STAT_ST_BLKSIZE 1 -_ACEOF - - -fi - -fi -echo "$as_me:$LINENO: checking for blkcnt_t" >&5 -echo $ECHO_N "checking for blkcnt_t... $ECHO_C" >&6 -if test "${ac_cv_type_blkcnt_t+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -int -main () -{ -if ((blkcnt_t *) 0) - return 0; -if (sizeof (blkcnt_t)) - return 0; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_type_blkcnt_t=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_type_blkcnt_t=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_type_blkcnt_t" >&5 -echo "${ECHO_T}$ac_cv_type_blkcnt_t" >&6 -if test $ac_cv_type_blkcnt_t = yes; then - -cat >>confdefs.h <<_ACEOF -#define HAVE_BLKCNT_T 1 -_ACEOF - - -fi - -echo "$as_me:$LINENO: checking for fstatfs" >&5 -echo $ECHO_N "checking for fstatfs... $ECHO_C" >&6 -if test "${ac_cv_func_fstatfs+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -/* Define fstatfs to an innocuous variant, in case declares fstatfs. - For example, HP-UX 11i declares gettimeofday. */ -#define fstatfs innocuous_fstatfs - -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char fstatfs (); below. - Prefer to if __STDC__ is defined, since - exists even on freestanding compilers. */ - -#ifdef __STDC__ -# include -#else -# include -#endif - -#undef fstatfs - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -{ -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char fstatfs (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_fstatfs) || defined (__stub___fstatfs) -choke me -#else -char (*f) () = fstatfs; -#endif -#ifdef __cplusplus -} -#endif - -int -main () -{ -return f != fstatfs; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_func_fstatfs=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_func_fstatfs=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_func_fstatfs" >&5 -echo "${ECHO_T}$ac_cv_func_fstatfs" >&6 -if test $ac_cv_func_fstatfs = yes; then - : -else - -cat >>confdefs.h <<\_ACEOF -#define NO_FSTATFS 1 -_ACEOF - -fi - - -#-------------------------------------------------------------------- -# Some system have no memcmp or it does not work with 8 bit data, this -# checks it and add memcmp.o to LIBOBJS if needed -#-------------------------------------------------------------------- - -echo "$as_me:$LINENO: checking for working memcmp" >&5 -echo $ECHO_N "checking for working memcmp... $ECHO_C" >&6 -if test "${ac_cv_func_memcmp_working+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test "$cross_compiling" = yes; then - ac_cv_func_memcmp_working=no -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -int -main () -{ - - /* Some versions of memcmp are not 8-bit clean. */ - char c0 = 0x40, c1 = 0x80, c2 = 0x81; - if (memcmp(&c0, &c2, 1) >= 0 || memcmp(&c1, &c2, 1) >= 0) - exit (1); - - /* The Next x86 OpenStep bug shows up only when comparing 16 bytes - or more and with at least one buffer not starting on a 4-byte boundary. - William Lewis provided this test program. */ - { - char foo[21]; - char bar[21]; - int i; - for (i = 0; i < 4; i++) - { - char *a = foo + i; - char *b = bar + i; - strcpy (a, "--------01111111"); - strcpy (b, "--------10000000"); - if (memcmp (a, b, 16) >= 0) - exit (1); - } - exit (0); - } - - ; - return 0; -} -_ACEOF -rm -f conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_func_memcmp_working=yes -else - echo "$as_me: program exited with status $ac_status" >&5 -echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -( exit $ac_status ) -ac_cv_func_memcmp_working=no -fi -rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext -fi -fi -echo "$as_me:$LINENO: result: $ac_cv_func_memcmp_working" >&5 -echo "${ECHO_T}$ac_cv_func_memcmp_working" >&6 -test $ac_cv_func_memcmp_working = no && case $LIBOBJS in - "memcmp.$ac_objext" | \ - *" memcmp.$ac_objext" | \ - "memcmp.$ac_objext "* | \ - *" memcmp.$ac_objext "* ) ;; - *) LIBOBJS="$LIBOBJS memcmp.$ac_objext" ;; -esac - - - -#-------------------------------------------------------------------- -# Some system like SunOS 4 and other BSD like systems have no memmove -# (we assume they have bcopy instead). {The replacement define is in -# compat/string.h} -#-------------------------------------------------------------------- - -echo "$as_me:$LINENO: checking for memmove" >&5 -echo $ECHO_N "checking for memmove... $ECHO_C" >&6 -if test "${ac_cv_func_memmove+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -/* Define memmove to an innocuous variant, in case declares memmove. - For example, HP-UX 11i declares gettimeofday. */ -#define memmove innocuous_memmove - -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char memmove (); below. - Prefer to if __STDC__ is defined, since - exists even on freestanding compilers. */ - -#ifdef __STDC__ -# include -#else -# include -#endif - -#undef memmove - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -{ -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char memmove (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_memmove) || defined (__stub___memmove) -choke me -#else -char (*f) () = memmove; -#endif -#ifdef __cplusplus -} -#endif - -int -main () -{ -return f != memmove; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_func_memmove=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_func_memmove=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_func_memmove" >&5 -echo "${ECHO_T}$ac_cv_func_memmove" >&6 -if test $ac_cv_func_memmove = yes; then - : -else - - -cat >>confdefs.h <<\_ACEOF -#define NO_MEMMOVE 1 -_ACEOF - - -cat >>confdefs.h <<\_ACEOF -#define NO_STRING_H 1 -_ACEOF - -fi - - -#-------------------------------------------------------------------- -# On some systems strstr is broken: it returns a pointer even even if -# the original string is empty. -#-------------------------------------------------------------------- - - - echo "$as_me:$LINENO: checking for strstr" >&5 -echo $ECHO_N "checking for strstr... $ECHO_C" >&6 -if test "${ac_cv_func_strstr+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -/* Define strstr to an innocuous variant, in case declares strstr. - For example, HP-UX 11i declares gettimeofday. */ -#define strstr innocuous_strstr - -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char strstr (); below. - Prefer to if __STDC__ is defined, since - exists even on freestanding compilers. */ - -#ifdef __STDC__ -# include -#else -# include -#endif - -#undef strstr - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -{ -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char strstr (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_strstr) || defined (__stub___strstr) -choke me -#else -char (*f) () = strstr; -#endif -#ifdef __cplusplus -} -#endif - -int -main () -{ -return f != strstr; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_func_strstr=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_func_strstr=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_func_strstr" >&5 -echo "${ECHO_T}$ac_cv_func_strstr" >&6 -if test $ac_cv_func_strstr = yes; then - tcl_ok=1 -else - tcl_ok=0 -fi - - if test "$tcl_ok" = 1; then - echo "$as_me:$LINENO: checking proper strstr implementation" >&5 -echo $ECHO_N "checking proper strstr implementation... $ECHO_C" >&6 -if test "${tcl_cv_strstr_unbroken+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test "$cross_compiling" = yes; then - tcl_cv_strstr_unbroken=unknown -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -int main() { - extern int strstr(); - exit(strstr("\0test", "test") ? 1 : 0); -} -_ACEOF -rm -f conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - tcl_cv_strstr_unbroken=ok -else - echo "$as_me: program exited with status $ac_status" >&5 -echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -( exit $ac_status ) -tcl_cv_strstr_unbroken=broken -fi -rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext -fi -fi -echo "$as_me:$LINENO: result: $tcl_cv_strstr_unbroken" >&5 -echo "${ECHO_T}$tcl_cv_strstr_unbroken" >&6 - if test "$tcl_cv_strstr_unbroken" = "ok"; then - tcl_ok=1 - else - tcl_ok=0 - fi - fi - if test "$tcl_ok" = 0; then - case $LIBOBJS in - "strstr.$ac_objext" | \ - *" strstr.$ac_objext" | \ - "strstr.$ac_objext "* | \ - *" strstr.$ac_objext "* ) ;; - *) LIBOBJS="$LIBOBJS strstr.$ac_objext" ;; -esac - - USE_COMPAT=1 - fi - - -#-------------------------------------------------------------------- -# Check for strtoul function. This is tricky because under some -# versions of AIX strtoul returns an incorrect terminator -# pointer for the string "0". -#-------------------------------------------------------------------- - - - echo "$as_me:$LINENO: checking for strtoul" >&5 -echo $ECHO_N "checking for strtoul... $ECHO_C" >&6 -if test "${ac_cv_func_strtoul+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -/* Define strtoul to an innocuous variant, in case declares strtoul. - For example, HP-UX 11i declares gettimeofday. */ -#define strtoul innocuous_strtoul - -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char strtoul (); below. - Prefer to if __STDC__ is defined, since - exists even on freestanding compilers. */ - -#ifdef __STDC__ -# include -#else -# include -#endif - -#undef strtoul - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -{ -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char strtoul (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_strtoul) || defined (__stub___strtoul) -choke me -#else -char (*f) () = strtoul; -#endif -#ifdef __cplusplus -} -#endif - -int -main () -{ -return f != strtoul; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_func_strtoul=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_func_strtoul=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_func_strtoul" >&5 -echo "${ECHO_T}$ac_cv_func_strtoul" >&6 -if test $ac_cv_func_strtoul = yes; then - tcl_ok=1 -else - tcl_ok=0 -fi - - if test "$tcl_ok" = 1; then - echo "$as_me:$LINENO: checking proper strtoul implementation" >&5 -echo $ECHO_N "checking proper strtoul implementation... $ECHO_C" >&6 -if test "${tcl_cv_strtoul_unbroken+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test "$cross_compiling" = yes; then - tcl_cv_strtoul_unbroken=unknown -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -int main() { - extern int strtoul(); - char *term, *string = "0"; - exit(strtoul(string,&term,0) != 0 || term != string+1); -} -_ACEOF -rm -f conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - tcl_cv_strtoul_unbroken=ok -else - echo "$as_me: program exited with status $ac_status" >&5 -echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -( exit $ac_status ) -tcl_cv_strtoul_unbroken=broken -fi -rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext -fi -fi -echo "$as_me:$LINENO: result: $tcl_cv_strtoul_unbroken" >&5 -echo "${ECHO_T}$tcl_cv_strtoul_unbroken" >&6 - if test "$tcl_cv_strtoul_unbroken" = "ok"; then - tcl_ok=1 - else - tcl_ok=0 - fi - fi - if test "$tcl_ok" = 0; then - case $LIBOBJS in - "strtoul.$ac_objext" | \ - *" strtoul.$ac_objext" | \ - "strtoul.$ac_objext "* | \ - *" strtoul.$ac_objext "* ) ;; - *) LIBOBJS="$LIBOBJS strtoul.$ac_objext" ;; -esac - - USE_COMPAT=1 - fi - - -#-------------------------------------------------------------------- -# Check for the strtod function. This is tricky because in some -# versions of Linux strtod mis-parses strings starting with "+". -#-------------------------------------------------------------------- - - - echo "$as_me:$LINENO: checking for strtod" >&5 -echo $ECHO_N "checking for strtod... $ECHO_C" >&6 -if test "${ac_cv_func_strtod+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -/* Define strtod to an innocuous variant, in case declares strtod. - For example, HP-UX 11i declares gettimeofday. */ -#define strtod innocuous_strtod - -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char strtod (); below. - Prefer to if __STDC__ is defined, since - exists even on freestanding compilers. */ - -#ifdef __STDC__ -# include -#else -# include -#endif - -#undef strtod - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -{ -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char strtod (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_strtod) || defined (__stub___strtod) -choke me -#else -char (*f) () = strtod; -#endif -#ifdef __cplusplus -} -#endif - -int -main () -{ -return f != strtod; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_func_strtod=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_func_strtod=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_func_strtod" >&5 -echo "${ECHO_T}$ac_cv_func_strtod" >&6 -if test $ac_cv_func_strtod = yes; then - tcl_ok=1 -else - tcl_ok=0 -fi - - if test "$tcl_ok" = 1; then - echo "$as_me:$LINENO: checking proper strtod implementation" >&5 -echo $ECHO_N "checking proper strtod implementation... $ECHO_C" >&6 -if test "${tcl_cv_strtod_unbroken+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test "$cross_compiling" = yes; then - tcl_cv_strtod_unbroken=unknown -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -int main() { - extern double strtod(); - char *term, *string = " +69"; - exit(strtod(string,&term) != 69 || term != string+4); -} -_ACEOF -rm -f conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - tcl_cv_strtod_unbroken=ok -else - echo "$as_me: program exited with status $ac_status" >&5 -echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -( exit $ac_status ) -tcl_cv_strtod_unbroken=broken -fi -rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext -fi -fi -echo "$as_me:$LINENO: result: $tcl_cv_strtod_unbroken" >&5 -echo "${ECHO_T}$tcl_cv_strtod_unbroken" >&6 - if test "$tcl_cv_strtod_unbroken" = "ok"; then - tcl_ok=1 - else - tcl_ok=0 - fi - fi - if test "$tcl_ok" = 0; then - case $LIBOBJS in - "strtod.$ac_objext" | \ - *" strtod.$ac_objext" | \ - "strtod.$ac_objext "* | \ - *" strtod.$ac_objext "* ) ;; - *) LIBOBJS="$LIBOBJS strtod.$ac_objext" ;; -esac - - USE_COMPAT=1 - fi - - -#-------------------------------------------------------------------- -# Under Solaris 2.4, strtod returns the wrong value for the -# terminating character under some conditions. Check for this -# and if the problem exists use a substitute procedure -# "fixstrtod" that corrects the error. -#-------------------------------------------------------------------- - - - echo "$as_me:$LINENO: checking for strtod" >&5 -echo $ECHO_N "checking for strtod... $ECHO_C" >&6 -if test "${ac_cv_func_strtod+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -/* Define strtod to an innocuous variant, in case declares strtod. - For example, HP-UX 11i declares gettimeofday. */ -#define strtod innocuous_strtod - -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char strtod (); below. - Prefer to if __STDC__ is defined, since - exists even on freestanding compilers. */ - -#ifdef __STDC__ -# include -#else -# include -#endif - -#undef strtod - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -{ -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char strtod (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_strtod) || defined (__stub___strtod) -choke me -#else -char (*f) () = strtod; -#endif -#ifdef __cplusplus -} -#endif - -int -main () -{ -return f != strtod; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_func_strtod=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_func_strtod=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_func_strtod" >&5 -echo "${ECHO_T}$ac_cv_func_strtod" >&6 -if test $ac_cv_func_strtod = yes; then - tcl_strtod=1 -else - tcl_strtod=0 -fi - - if test "$tcl_strtod" = 1; then - echo "$as_me:$LINENO: checking for Solaris2.4/Tru64 strtod bugs" >&5 -echo $ECHO_N "checking for Solaris2.4/Tru64 strtod bugs... $ECHO_C" >&6 -if test "${tcl_cv_strtod_buggy+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - - if test "$cross_compiling" = yes; then - tcl_cv_strtod_buggy=buggy -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - - extern double strtod(); - int main() { - char *infString="Inf", *nanString="NaN", *spaceString=" "; - char *term; - double value; - value = strtod(infString, &term); - if ((term != infString) && (term[-1] == 0)) { - exit(1); - } - value = strtod(nanString, &term); - if ((term != nanString) && (term[-1] == 0)) { - exit(1); - } - value = strtod(spaceString, &term); - if (term == (spaceString+1)) { - exit(1); - } - exit(0); - } -_ACEOF -rm -f conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - tcl_cv_strtod_buggy=ok -else - echo "$as_me: program exited with status $ac_status" >&5 -echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -( exit $ac_status ) -tcl_cv_strtod_buggy=buggy -fi -rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext -fi -fi -echo "$as_me:$LINENO: result: $tcl_cv_strtod_buggy" >&5 -echo "${ECHO_T}$tcl_cv_strtod_buggy" >&6 - if test "$tcl_cv_strtod_buggy" = buggy; then - case $LIBOBJS in - "fixstrtod.$ac_objext" | \ - *" fixstrtod.$ac_objext" | \ - "fixstrtod.$ac_objext "* | \ - *" fixstrtod.$ac_objext "* ) ;; - *) LIBOBJS="$LIBOBJS fixstrtod.$ac_objext" ;; -esac - - USE_COMPAT=1 - -cat >>confdefs.h <<\_ACEOF -#define strtod fixstrtod -_ACEOF - - fi - fi - - -#-------------------------------------------------------------------- -# Check for various typedefs and provide substitutes if -# they don't exist. -#-------------------------------------------------------------------- - -echo "$as_me:$LINENO: checking for mode_t" >&5 -echo $ECHO_N "checking for mode_t... $ECHO_C" >&6 -if test "${ac_cv_type_mode_t+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -int -main () -{ -if ((mode_t *) 0) - return 0; -if (sizeof (mode_t)) - return 0; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_type_mode_t=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_type_mode_t=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_type_mode_t" >&5 -echo "${ECHO_T}$ac_cv_type_mode_t" >&6 -if test $ac_cv_type_mode_t = yes; then - : -else - -cat >>confdefs.h <<_ACEOF -#define mode_t int -_ACEOF - -fi - -echo "$as_me:$LINENO: checking for pid_t" >&5 -echo $ECHO_N "checking for pid_t... $ECHO_C" >&6 -if test "${ac_cv_type_pid_t+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -int -main () -{ -if ((pid_t *) 0) - return 0; -if (sizeof (pid_t)) - return 0; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_type_pid_t=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_type_pid_t=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_type_pid_t" >&5 -echo "${ECHO_T}$ac_cv_type_pid_t" >&6 -if test $ac_cv_type_pid_t = yes; then - : -else - -cat >>confdefs.h <<_ACEOF -#define pid_t int -_ACEOF - -fi - -echo "$as_me:$LINENO: checking for size_t" >&5 -echo $ECHO_N "checking for size_t... $ECHO_C" >&6 -if test "${ac_cv_type_size_t+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -int -main () -{ -if ((size_t *) 0) - return 0; -if (sizeof (size_t)) - return 0; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_type_size_t=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_type_size_t=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_type_size_t" >&5 -echo "${ECHO_T}$ac_cv_type_size_t" >&6 -if test $ac_cv_type_size_t = yes; then - : -else - -cat >>confdefs.h <<_ACEOF -#define size_t unsigned -_ACEOF - -fi - -echo "$as_me:$LINENO: checking for uid_t in sys/types.h" >&5 -echo $ECHO_N "checking for uid_t in sys/types.h... $ECHO_C" >&6 -if test "${ac_cv_type_uid_t+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "uid_t" >/dev/null 2>&1; then - ac_cv_type_uid_t=yes -else - ac_cv_type_uid_t=no -fi -rm -f conftest* - -fi -echo "$as_me:$LINENO: result: $ac_cv_type_uid_t" >&5 -echo "${ECHO_T}$ac_cv_type_uid_t" >&6 -if test $ac_cv_type_uid_t = no; then - -cat >>confdefs.h <<\_ACEOF -#define uid_t int -_ACEOF - - -cat >>confdefs.h <<\_ACEOF -#define gid_t int -_ACEOF - -fi - - -echo "$as_me:$LINENO: checking for socklen_t" >&5 -echo $ECHO_N "checking for socklen_t... $ECHO_C" >&6 -if test "${tcl_cv_type_socklen_t+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - - #include - #include - -int -main () -{ - - socklen_t foo; - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - tcl_cv_type_socklen_t=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -tcl_cv_type_socklen_t=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $tcl_cv_type_socklen_t" >&5 -echo "${ECHO_T}$tcl_cv_type_socklen_t" >&6 -if test $tcl_cv_type_socklen_t = no; then - -cat >>confdefs.h <<\_ACEOF -#define socklen_t int -_ACEOF - -fi - -echo "$as_me:$LINENO: checking for intptr_t" >&5 -echo $ECHO_N "checking for intptr_t... $ECHO_C" >&6 -if test "${ac_cv_type_intptr_t+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -int -main () -{ -if ((intptr_t *) 0) - return 0; -if (sizeof (intptr_t)) - return 0; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_type_intptr_t=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_type_intptr_t=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_type_intptr_t" >&5 -echo "${ECHO_T}$ac_cv_type_intptr_t" >&6 -if test $ac_cv_type_intptr_t = yes; then - - -cat >>confdefs.h <<\_ACEOF -#define HAVE_INTPTR_T 1 -_ACEOF - -else - - echo "$as_me:$LINENO: checking for pointer-size signed integer type" >&5 -echo $ECHO_N "checking for pointer-size signed integer type... $ECHO_C" >&6 -if test "${tcl_cv_intptr_t+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - - for tcl_cv_intptr_t in "int" "long" "long long" none; do - if test "$tcl_cv_intptr_t" != none; then - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -int -main () -{ -static int test_array [1 - 2 * !(sizeof (void *) <= sizeof ($tcl_cv_intptr_t))]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - tcl_ok=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -tcl_ok=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext - test "$tcl_ok" = yes && break; fi - done -fi -echo "$as_me:$LINENO: result: $tcl_cv_intptr_t" >&5 -echo "${ECHO_T}$tcl_cv_intptr_t" >&6 - if test "$tcl_cv_intptr_t" != none; then - -cat >>confdefs.h <<_ACEOF -#define intptr_t $tcl_cv_intptr_t -_ACEOF - - fi - -fi - -echo "$as_me:$LINENO: checking for uintptr_t" >&5 -echo $ECHO_N "checking for uintptr_t... $ECHO_C" >&6 -if test "${ac_cv_type_uintptr_t+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -int -main () -{ -if ((uintptr_t *) 0) - return 0; -if (sizeof (uintptr_t)) - return 0; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_type_uintptr_t=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_type_uintptr_t=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_type_uintptr_t" >&5 -echo "${ECHO_T}$ac_cv_type_uintptr_t" >&6 -if test $ac_cv_type_uintptr_t = yes; then - - -cat >>confdefs.h <<\_ACEOF -#define HAVE_UINTPTR_T 1 -_ACEOF - -else - - echo "$as_me:$LINENO: checking for pointer-size unsigned integer type" >&5 -echo $ECHO_N "checking for pointer-size unsigned integer type... $ECHO_C" >&6 -if test "${tcl_cv_uintptr_t+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - - for tcl_cv_uintptr_t in "unsigned int" "unsigned long" "unsigned long long" \ - none; do - if test "$tcl_cv_uintptr_t" != none; then - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -int -main () -{ -static int test_array [1 - 2 * !(sizeof (void *) <= sizeof ($tcl_cv_uintptr_t))]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - tcl_ok=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -tcl_ok=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext - test "$tcl_ok" = yes && break; fi - done -fi -echo "$as_me:$LINENO: result: $tcl_cv_uintptr_t" >&5 -echo "${ECHO_T}$tcl_cv_uintptr_t" >&6 - if test "$tcl_cv_uintptr_t" != none; then - -cat >>confdefs.h <<_ACEOF -#define uintptr_t $tcl_cv_uintptr_t -_ACEOF - - fi - -fi - - -#-------------------------------------------------------------------- -# If a system doesn't have an opendir function (man, that's old!) -# then we have to supply a different version of dirent.h which -# is compatible with the substitute version of opendir that's -# provided. This version only works with V7-style directories. -#-------------------------------------------------------------------- - -echo "$as_me:$LINENO: checking for opendir" >&5 -echo $ECHO_N "checking for opendir... $ECHO_C" >&6 -if test "${ac_cv_func_opendir+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -/* Define opendir to an innocuous variant, in case declares opendir. - For example, HP-UX 11i declares gettimeofday. */ -#define opendir innocuous_opendir - -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char opendir (); below. - Prefer to if __STDC__ is defined, since - exists even on freestanding compilers. */ - -#ifdef __STDC__ -# include -#else -# include -#endif - -#undef opendir - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -{ -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char opendir (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_opendir) || defined (__stub___opendir) -choke me -#else -char (*f) () = opendir; -#endif -#ifdef __cplusplus -} -#endif - -int -main () -{ -return f != opendir; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_func_opendir=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_func_opendir=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_func_opendir" >&5 -echo "${ECHO_T}$ac_cv_func_opendir" >&6 -if test $ac_cv_func_opendir = yes; then - : -else - -cat >>confdefs.h <<\_ACEOF -#define USE_DIRENT2_H 1 -_ACEOF - -fi - - -#-------------------------------------------------------------------- -# The check below checks whether defines the type -# "union wait" correctly. It's needed because of weirdness in -# HP-UX where "union wait" is defined in both the BSD and SYS-V -# environments. Checking the usability of WIFEXITED seems to do -# the trick. -#-------------------------------------------------------------------- - -echo "$as_me:$LINENO: checking union wait" >&5 -echo $ECHO_N "checking union wait... $ECHO_C" >&6 -if test "${tcl_cv_union_wait+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -#include -int -main () -{ - -union wait x; -WIFEXITED(x); /* Generates compiler error if WIFEXITED - * uses an int. */ - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - tcl_cv_union_wait=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -tcl_cv_union_wait=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $tcl_cv_union_wait" >&5 -echo "${ECHO_T}$tcl_cv_union_wait" >&6 -if test $tcl_cv_union_wait = no; then - -cat >>confdefs.h <<\_ACEOF -#define NO_UNION_WAIT 1 -_ACEOF - -fi - -#-------------------------------------------------------------------- -# Check whether there is an strncasecmp function on this system. -# This is a bit tricky because under SCO it's in -lsocket and -# under Sequent Dynix it's in -linet. -#-------------------------------------------------------------------- - -echo "$as_me:$LINENO: checking for strncasecmp" >&5 -echo $ECHO_N "checking for strncasecmp... $ECHO_C" >&6 -if test "${ac_cv_func_strncasecmp+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -/* Define strncasecmp to an innocuous variant, in case declares strncasecmp. - For example, HP-UX 11i declares gettimeofday. */ -#define strncasecmp innocuous_strncasecmp - -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char strncasecmp (); below. - Prefer to if __STDC__ is defined, since - exists even on freestanding compilers. */ - -#ifdef __STDC__ -# include -#else -# include -#endif - -#undef strncasecmp - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -{ -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char strncasecmp (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_strncasecmp) || defined (__stub___strncasecmp) -choke me -#else -char (*f) () = strncasecmp; -#endif -#ifdef __cplusplus -} -#endif - -int -main () -{ -return f != strncasecmp; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_func_strncasecmp=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_func_strncasecmp=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_func_strncasecmp" >&5 -echo "${ECHO_T}$ac_cv_func_strncasecmp" >&6 -if test $ac_cv_func_strncasecmp = yes; then - tcl_ok=1 -else - tcl_ok=0 -fi - -if test "$tcl_ok" = 0; then - echo "$as_me:$LINENO: checking for strncasecmp in -lsocket" >&5 -echo $ECHO_N "checking for strncasecmp in -lsocket... $ECHO_C" >&6 -if test "${ac_cv_lib_socket_strncasecmp+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lsocket $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char strncasecmp (); -int -main () -{ -strncasecmp (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_lib_socket_strncasecmp=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_lib_socket_strncasecmp=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -echo "$as_me:$LINENO: result: $ac_cv_lib_socket_strncasecmp" >&5 -echo "${ECHO_T}$ac_cv_lib_socket_strncasecmp" >&6 -if test $ac_cv_lib_socket_strncasecmp = yes; then - tcl_ok=1 -else - tcl_ok=0 -fi - -fi -if test "$tcl_ok" = 0; then - echo "$as_me:$LINENO: checking for strncasecmp in -linet" >&5 -echo $ECHO_N "checking for strncasecmp in -linet... $ECHO_C" >&6 -if test "${ac_cv_lib_inet_strncasecmp+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-linet $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char strncasecmp (); -int -main () -{ -strncasecmp (); - ; - return 0; -} + extern double strtod(); + int main() { + char *infString="Inf", *nanString="NaN", *spaceString=" "; + char *term; + double value; + value = strtod(infString, &term); + if ((term != infString) && (term[-1] == 0)) { + exit(1); + } + value = strtod(nanString, &term); + if ((term != nanString) && (term[-1] == 0)) { + exit(1); + } + value = strtod(spaceString, &term); + if (term == (spaceString+1)) { + exit(1); + } + exit(0); + } _ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_lib_inet_strncasecmp=yes +if ac_fn_c_try_run "$LINENO"; then : + tcl_cv_strtod_buggy=ok else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_cv_lib_inet_strncasecmp=no -fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS + tcl_cv_strtod_buggy=buggy fi -echo "$as_me:$LINENO: result: $ac_cv_lib_inet_strncasecmp" >&5 -echo "${ECHO_T}$ac_cv_lib_inet_strncasecmp" >&6 -if test $ac_cv_lib_inet_strncasecmp = yes; then - tcl_ok=1 -else - tcl_ok=0 +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi -if test "$tcl_ok" = 0; then - case $LIBOBJS in - "strncasecmp.$ac_objext" | \ - *" strncasecmp.$ac_objext" | \ - "strncasecmp.$ac_objext "* | \ - *" strncasecmp.$ac_objext "* ) ;; - *) LIBOBJS="$LIBOBJS strncasecmp.$ac_objext" ;; +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_strtod_buggy" >&5 +$as_echo "$tcl_cv_strtod_buggy" >&6; } + if test "$tcl_cv_strtod_buggy" = buggy; then + case " $LIBOBJS " in + *" fixstrtod.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS fixstrtod.$ac_objext" + ;; esac - USE_COMPAT=1 -fi + USE_COMPAT=1 + +$as_echo "#define strtod fixstrtod" >>confdefs.h + + fi + fi + #-------------------------------------------------------------------- -# The code below deals with several issues related to gettimeofday: -# 1. Some systems don't provide a gettimeofday function at all -# (set NO_GETTOD if this is the case). -# 2. See if gettimeofday is declared in the header file. -# if not, set the GETTOD_NOT_DECLARED flag so that tclPort.h can -# declare it. +# Check for various typedefs and provide substitutes if +# they don't exist. #-------------------------------------------------------------------- -echo "$as_me:$LINENO: checking for gettimeofday" >&5 -echo $ECHO_N "checking for gettimeofday... $ECHO_C" >&6 -if test "${ac_cv_func_gettimeofday+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 +ac_fn_c_check_type "$LINENO" "mode_t" "ac_cv_type_mode_t" "$ac_includes_default" +if test "x$ac_cv_type_mode_t" = xyes; then : + else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -/* Define gettimeofday to an innocuous variant, in case declares gettimeofday. - For example, HP-UX 11i declares gettimeofday. */ -#define gettimeofday innocuous_gettimeofday -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char gettimeofday (); below. - Prefer to if __STDC__ is defined, since - exists even on freestanding compilers. */ +cat >>confdefs.h <<_ACEOF +#define mode_t int +_ACEOF -#ifdef __STDC__ -# include -#else -# include -#endif +fi -#undef gettimeofday +ac_fn_c_check_type "$LINENO" "pid_t" "ac_cv_type_pid_t" "$ac_includes_default" +if test "x$ac_cv_type_pid_t" = xyes; then : -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -{ -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char gettimeofday (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_gettimeofday) || defined (__stub___gettimeofday) -choke me -#else -char (*f) () = gettimeofday; -#endif -#ifdef __cplusplus -} -#endif +else -int -main () -{ -return f != gettimeofday; - ; - return 0; -} +cat >>confdefs.h <<_ACEOF +#define pid_t int _ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_func_gettimeofday=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 -ac_cv_func_gettimeofday=no fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_func_gettimeofday" >&5 -echo "${ECHO_T}$ac_cv_func_gettimeofday" >&6 -if test $ac_cv_func_gettimeofday = yes; then - : -else +ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default" +if test "x$ac_cv_type_size_t" = xyes; then : -cat >>confdefs.h <<\_ACEOF -#define NO_GETTOD 1 -_ACEOF +else +cat >>confdefs.h <<_ACEOF +#define size_t unsigned int +_ACEOF fi -echo "$as_me:$LINENO: checking for gettimeofday declaration" >&5 -echo $ECHO_N "checking for gettimeofday declaration... $ECHO_C" >&6 -if test "${tcl_cv_grep_gettimeofday+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for uid_t in sys/types.h" >&5 +$as_echo_n "checking for uid_t in sys/types.h... " >&6; } +if ${ac_cv_type_uid_t+:} false; then : + $as_echo_n "(cached) " >&6 else - - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#include +#include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "gettimeofday" >/dev/null 2>&1; then - tcl_cv_grep_gettimeofday=present + $EGREP "uid_t" >/dev/null 2>&1; then : + ac_cv_type_uid_t=yes else - tcl_cv_grep_gettimeofday=missing + ac_cv_type_uid_t=no fi rm -f conftest* fi -echo "$as_me:$LINENO: result: $tcl_cv_grep_gettimeofday" >&5 -echo "${ECHO_T}$tcl_cv_grep_gettimeofday" >&6 -if test $tcl_cv_grep_gettimeofday = missing ; then - -cat >>confdefs.h <<\_ACEOF -#define GETTOD_NOT_DECLARED 1 -_ACEOF - -fi - -#-------------------------------------------------------------------- -# The following code checks to see whether it is possible to get -# signed chars on this platform. This is needed in order to -# properly generate sign-extended ints from character values. -#-------------------------------------------------------------------- +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_uid_t" >&5 +$as_echo "$ac_cv_type_uid_t" >&6; } +if test $ac_cv_type_uid_t = no; then +$as_echo "#define uid_t int" >>confdefs.h -echo "$as_me:$LINENO: checking whether char is unsigned" >&5 -echo $ECHO_N "checking whether char is unsigned... $ECHO_C" >&6 -if test "${ac_cv_c_char_unsigned+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -int -main () -{ -static int test_array [1 - 2 * !(((char) -1) < 0)]; -test_array [0] = 0 - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_c_char_unsigned=no -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 +$as_echo "#define gid_t int" >>confdefs.h -ac_cv_c_char_unsigned=yes -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi -echo "$as_me:$LINENO: result: $ac_cv_c_char_unsigned" >&5 -echo "${ECHO_T}$ac_cv_c_char_unsigned" >&6 -if test $ac_cv_c_char_unsigned = yes && test "$GCC" != yes; then - cat >>confdefs.h <<\_ACEOF -#define __CHAR_UNSIGNED__ 1 -_ACEOF -fi -echo "$as_me:$LINENO: checking signed char declarations" >&5 -echo $ECHO_N "checking signed char declarations... $ECHO_C" >&6 -if test "${tcl_cv_char_signed+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for socklen_t" >&5 +$as_echo_n "checking for socklen_t... " >&6; } +if ${tcl_cv_type_socklen_t+:} false; then : + $as_echo_n "(cached) " >&6 else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ + #include + #include + int main () { - signed char *p; - p = 0; + socklen_t foo; ; return 0; } _ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - tcl_cv_char_signed=yes +if ac_fn_c_try_compile "$LINENO"; then : + tcl_cv_type_socklen_t=yes else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -tcl_cv_char_signed=no + tcl_cv_type_socklen_t=no fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi -echo "$as_me:$LINENO: result: $tcl_cv_char_signed" >&5 -echo "${ECHO_T}$tcl_cv_char_signed" >&6 -if test $tcl_cv_char_signed = yes; then +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_type_socklen_t" >&5 +$as_echo "$tcl_cv_type_socklen_t" >&6; } +if test $tcl_cv_type_socklen_t = no; then -cat >>confdefs.h <<\_ACEOF -#define HAVE_SIGNED_CHAR 1 -_ACEOF +$as_echo "#define socklen_t int" >>confdefs.h fi -#-------------------------------------------------------------------- -# Does putenv() copy or not? We need to know to avoid memory leaks. -#-------------------------------------------------------------------- +ac_fn_c_check_type "$LINENO" "intptr_t" "ac_cv_type_intptr_t" "$ac_includes_default" +if test "x$ac_cv_type_intptr_t" = xyes; then : + + +$as_echo "#define HAVE_INTPTR_T 1" >>confdefs.h -echo "$as_me:$LINENO: checking for a putenv() that copies the buffer" >&5 -echo $ECHO_N "checking for a putenv() that copies the buffer... $ECHO_C" >&6 -if test "${tcl_cv_putenv_copy+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 else - if test "$cross_compiling" = yes; then - tcl_cv_putenv_copy=no + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pointer-size signed integer type" >&5 +$as_echo_n "checking for pointer-size signed integer type... " >&6; } +if ${tcl_cv_intptr_t+:} false; then : + $as_echo_n "(cached) " >&6 else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - #include - #define OURVAR "havecopy=yes" - int main (int argc, char *argv[]) - { - char *foo, *bar; - foo = (char *)strdup(OURVAR); - putenv(foo); - strcpy((char *)(strchr(foo, '=') + 1), "no"); - bar = getenv("havecopy"); - if (!strcmp(bar, "no")) { - /* doesnt copy */ - return 0; - } else { - /* does copy */ - return 1; - } - } + for tcl_cv_intptr_t in "int" "long" "long long" none; do + if test "$tcl_cv_intptr_t" != none; then + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +static int test_array [1 - 2 * !(sizeof (void *) <= sizeof ($tcl_cv_intptr_t))]; +test_array [0] = 0; +return test_array [0]; + ; + return 0; +} _ACEOF -rm -f conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - tcl_cv_putenv_copy=no +if ac_fn_c_try_compile "$LINENO"; then : + tcl_ok=yes else - echo "$as_me: program exited with status $ac_status" >&5 -echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -( exit $ac_status ) -tcl_cv_putenv_copy=yes -fi -rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext + tcl_ok=no fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + test "$tcl_ok" = yes && break; fi + done fi -echo "$as_me:$LINENO: result: $tcl_cv_putenv_copy" >&5 -echo "${ECHO_T}$tcl_cv_putenv_copy" >&6 -if test $tcl_cv_putenv_copy = yes; then +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_intptr_t" >&5 +$as_echo "$tcl_cv_intptr_t" >&6; } + if test "$tcl_cv_intptr_t" != none; then -cat >>confdefs.h <<\_ACEOF -#define HAVE_PUTENV_THAT_COPIES 1 +cat >>confdefs.h <<_ACEOF +#define intptr_t $tcl_cv_intptr_t _ACEOF -fi - -#-------------------------------------------------------------------- -# Check for support of nl_langinfo function -#-------------------------------------------------------------------- - - - # Check whether --enable-langinfo or --disable-langinfo was given. -if test "${enable_langinfo+set}" = set; then - enableval="$enable_langinfo" - langinfo_ok=$enableval -else - langinfo_ok=yes -fi; - - HAVE_LANGINFO=0 - if test "$langinfo_ok" = "yes"; then - if test "${ac_cv_header_langinfo_h+set}" = set; then - echo "$as_me:$LINENO: checking for langinfo.h" >&5 -echo $ECHO_N "checking for langinfo.h... $ECHO_C" >&6 -if test "${ac_cv_header_langinfo_h+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -fi -echo "$as_me:$LINENO: result: $ac_cv_header_langinfo_h" >&5 -echo "${ECHO_T}$ac_cv_header_langinfo_h" >&6 -else - # Is the header compilable? -echo "$as_me:$LINENO: checking langinfo.h usability" >&5 -echo $ECHO_N "checking langinfo.h usability... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -#include -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_header_compiler=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 + fi -ac_header_compiler=no fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -echo "${ECHO_T}$ac_header_compiler" >&6 -# Is the header present? -echo "$as_me:$LINENO: checking langinfo.h presence" >&5 -echo $ECHO_N "checking langinfo.h presence... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -_ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - ac_header_preproc=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 +ac_fn_c_check_type "$LINENO" "uintptr_t" "ac_cv_type_uintptr_t" "$ac_includes_default" +if test "x$ac_cv_type_uintptr_t" = xyes; then : - ac_header_preproc=no -fi -rm -f conftest.err conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -echo "${ECHO_T}$ac_header_preproc" >&6 -# So? What about this header? -case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in - yes:no: ) - { echo "$as_me:$LINENO: WARNING: langinfo.h: accepted by the compiler, rejected by the preprocessor!" >&5 -echo "$as_me: WARNING: langinfo.h: accepted by the compiler, rejected by the preprocessor!" >&2;} - { echo "$as_me:$LINENO: WARNING: langinfo.h: proceeding with the compiler's result" >&5 -echo "$as_me: WARNING: langinfo.h: proceeding with the compiler's result" >&2;} - ac_header_preproc=yes - ;; - no:yes:* ) - { echo "$as_me:$LINENO: WARNING: langinfo.h: present but cannot be compiled" >&5 -echo "$as_me: WARNING: langinfo.h: present but cannot be compiled" >&2;} - { echo "$as_me:$LINENO: WARNING: langinfo.h: check for missing prerequisite headers?" >&5 -echo "$as_me: WARNING: langinfo.h: check for missing prerequisite headers?" >&2;} - { echo "$as_me:$LINENO: WARNING: langinfo.h: see the Autoconf documentation" >&5 -echo "$as_me: WARNING: langinfo.h: see the Autoconf documentation" >&2;} - { echo "$as_me:$LINENO: WARNING: langinfo.h: section \"Present But Cannot Be Compiled\"" >&5 -echo "$as_me: WARNING: langinfo.h: section \"Present But Cannot Be Compiled\"" >&2;} - { echo "$as_me:$LINENO: WARNING: langinfo.h: proceeding with the preprocessor's result" >&5 -echo "$as_me: WARNING: langinfo.h: proceeding with the preprocessor's result" >&2;} - { echo "$as_me:$LINENO: WARNING: langinfo.h: in the future, the compiler will take precedence" >&5 -echo "$as_me: WARNING: langinfo.h: in the future, the compiler will take precedence" >&2;} - ( - cat <<\_ASBOX -## ------------------------------ ## -## Report this to the tcl lists. ## -## ------------------------------ ## -_ASBOX - ) | - sed "s/^/$as_me: WARNING: /" >&2 - ;; -esac -echo "$as_me:$LINENO: checking for langinfo.h" >&5 -echo $ECHO_N "checking for langinfo.h... $ECHO_C" >&6 -if test "${ac_cv_header_langinfo_h+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_cv_header_langinfo_h=$ac_header_preproc -fi -echo "$as_me:$LINENO: result: $ac_cv_header_langinfo_h" >&5 -echo "${ECHO_T}$ac_cv_header_langinfo_h" >&6 +$as_echo "#define HAVE_UINTPTR_T 1" >>confdefs.h -fi -if test $ac_cv_header_langinfo_h = yes; then - langinfo_ok=yes else - langinfo_ok=no -fi - - fi - echo "$as_me:$LINENO: checking whether to use nl_langinfo" >&5 -echo $ECHO_N "checking whether to use nl_langinfo... $ECHO_C" >&6 - if test "$langinfo_ok" = "yes"; then - if test "${tcl_cv_langinfo_h+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pointer-size unsigned integer type" >&5 +$as_echo_n "checking for pointer-size unsigned integer type... " >&6; } +if ${tcl_cv_uintptr_t+:} false; then : + $as_echo_n "(cached) " >&6 else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF + for tcl_cv_uintptr_t in "unsigned int" "unsigned long" "unsigned long long" \ + none; do + if test "$tcl_cv_uintptr_t" != none; then + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#include +$ac_includes_default int main () { -nl_langinfo(CODESET); +static int test_array [1 - 2 * !(sizeof (void *) <= sizeof ($tcl_cv_uintptr_t))]; +test_array [0] = 0; +return test_array [0]; + ; return 0; } _ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - tcl_cv_langinfo_h=yes +if ac_fn_c_try_compile "$LINENO"; then : + tcl_ok=yes else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -tcl_cv_langinfo_h=no + tcl_ok=no fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + test "$tcl_ok" = yes && break; fi + done fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_uintptr_t" >&5 +$as_echo "$tcl_cv_uintptr_t" >&6; } + if test "$tcl_cv_uintptr_t" != none; then - echo "$as_me:$LINENO: result: $tcl_cv_langinfo_h" >&5 -echo "${ECHO_T}$tcl_cv_langinfo_h" >&6 - if test $tcl_cv_langinfo_h = yes; then - -cat >>confdefs.h <<\_ACEOF -#define HAVE_LANGINFO 1 +cat >>confdefs.h <<_ACEOF +#define uintptr_t $tcl_cv_uintptr_t _ACEOF - fi - else - echo "$as_me:$LINENO: result: $langinfo_ok" >&5 -echo "${ECHO_T}$langinfo_ok" >&6 fi +fi + #-------------------------------------------------------------------- -# Check for support of chflags and mkstemps functions +# If a system doesn't have an opendir function (man, that's old!) +# then we have to supply a different version of dirent.h which +# is compatible with the substitute version of opendir that's +# provided. This version only works with V7-style directories. #-------------------------------------------------------------------- +ac_fn_c_check_func "$LINENO" "opendir" "ac_cv_func_opendir" +if test "x$ac_cv_func_opendir" = xyes; then : +else -for ac_func in chflags mkstemps -do -as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` -echo "$as_me:$LINENO: checking for $ac_func" >&5 -echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 -if eval "test \"\${$as_ac_var+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -/* Define $ac_func to an innocuous variant, in case declares $ac_func. - For example, HP-UX 11i declares gettimeofday. */ -#define $ac_func innocuous_$ac_func +$as_echo "#define USE_DIRENT2_H 1" >>confdefs.h -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char $ac_func (); below. - Prefer to if __STDC__ is defined, since - exists even on freestanding compilers. */ +fi -#ifdef __STDC__ -# include -#else -# include -#endif -#undef $ac_func +#-------------------------------------------------------------------- +# The check below checks whether defines the type +# "union wait" correctly. It's needed because of weirdness in +# HP-UX where "union wait" is defined in both the BSD and SYS-V +# environments. Checking the usability of WIFEXITED seems to do +# the trick. +#-------------------------------------------------------------------- -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -{ -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char $ac_func (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_$ac_func) || defined (__stub___$ac_func) -choke me -#else -char (*f) () = $ac_func; -#endif -#ifdef __cplusplus -} -#endif +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking union wait" >&5 +$as_echo_n "checking union wait... " >&6; } +if ${tcl_cv_union_wait+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include int main () { -return f != $ac_func; + +union wait x; +WIFEXITED(x); /* Generates compiler error if WIFEXITED + * uses an int. */ + ; return 0; } _ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - eval "$as_ac_var=yes" +if ac_fn_c_try_link "$LINENO"; then : + tcl_cv_union_wait=yes else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -eval "$as_ac_var=no" + tcl_cv_union_wait=no fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 -if test `eval echo '${'$as_ac_var'}'` = yes; then - cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 -_ACEOF +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_union_wait" >&5 +$as_echo "$tcl_cv_union_wait" >&6; } +if test $tcl_cv_union_wait = no; then -fi -done +$as_echo "#define NO_UNION_WAIT 1" >>confdefs.h +fi #-------------------------------------------------------------------- -# Check for support of isnan() function or macro +# Check whether there is an strncasecmp function on this system. +# This is a bit tricky because under SCO it's in -lsocket and +# under Sequent Dynix it's in -linet. #-------------------------------------------------------------------- -echo "$as_me:$LINENO: checking isnan" >&5 -echo $ECHO_N "checking isnan... $ECHO_C" >&6 -if test "${tcl_cv_isnan+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 +ac_fn_c_check_func "$LINENO" "strncasecmp" "ac_cv_func_strncasecmp" +if test "x$ac_cv_func_strncasecmp" = xyes; then : + tcl_ok=1 else + tcl_ok=0 +fi - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF +if test "$tcl_ok" = 0; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for strncasecmp in -lsocket" >&5 +$as_echo_n "checking for strncasecmp in -lsocket... " >&6; } +if ${ac_cv_lib_socket_strncasecmp+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsocket $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#include + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char strncasecmp (); int main () { - -isnan(0.0); /* Generates an error if isnan is missing */ - +return strncasecmp (); ; return 0; } _ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - tcl_cv_isnan=yes +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_socket_strncasecmp=yes else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -tcl_cv_isnan=no + ac_cv_lib_socket_strncasecmp=no fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS fi -echo "$as_me:$LINENO: result: $tcl_cv_isnan" >&5 -echo "${ECHO_T}$tcl_cv_isnan" >&6 -if test $tcl_cv_isnan = no; then - -cat >>confdefs.h <<\_ACEOF -#define NO_ISNAN 1 -_ACEOF - +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_strncasecmp" >&5 +$as_echo "$ac_cv_lib_socket_strncasecmp" >&6; } +if test "x$ac_cv_lib_socket_strncasecmp" = xyes; then : + tcl_ok=1 +else + tcl_ok=0 fi -#-------------------------------------------------------------------- -# Darwin specific API checks and defines -#-------------------------------------------------------------------- - -if test "`uname -s`" = "Darwin" ; then - -for ac_func in getattrlist -do -as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` -echo "$as_me:$LINENO: checking for $ac_func" >&5 -echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 -if eval "test \"\${$as_ac_var+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF +fi +if test "$tcl_ok" = 0; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for strncasecmp in -linet" >&5 +$as_echo_n "checking for strncasecmp in -linet... " >&6; } +if ${ac_cv_lib_inet_strncasecmp+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-linet $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -/* Define $ac_func to an innocuous variant, in case declares $ac_func. - For example, HP-UX 11i declares gettimeofday. */ -#define $ac_func innocuous_$ac_func - -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char $ac_func (); below. - Prefer to if __STDC__ is defined, since - exists even on freestanding compilers. */ - -#ifdef __STDC__ -# include -#else -# include -#endif -#undef $ac_func - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -{ -#endif -/* We use char because int might match the return type of a gcc2 +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ -char $ac_func (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_$ac_func) || defined (__stub___$ac_func) -choke me -#else -char (*f) () = $ac_func; -#endif #ifdef __cplusplus -} +extern "C" #endif - +char strncasecmp (); int main () { -return f != $ac_func; +return strncasecmp (); ; return 0; } _ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - eval "$as_ac_var=yes" +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_inet_strncasecmp=yes else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -eval "$as_ac_var=no" + ac_cv_lib_inet_strncasecmp=no fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 -if test `eval echo '${'$as_ac_var'}'` = yes; then - cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 -_ACEOF - +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_inet_strncasecmp" >&5 +$as_echo "$ac_cv_lib_inet_strncasecmp" >&6; } +if test "x$ac_cv_lib_inet_strncasecmp" = xyes; then : + tcl_ok=1 +else + tcl_ok=0 fi -done +fi +if test "$tcl_ok" = 0; then + case " $LIBOBJS " in + *" strncasecmp.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS strncasecmp.$ac_objext" + ;; +esac -for ac_header in copyfile.h -do -as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + USE_COMPAT=1 fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 -else - # Is the header compilable? -echo "$as_me:$LINENO: checking $ac_header usability" >&5 -echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -#include <$ac_header> -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_header_compiler=yes + +#-------------------------------------------------------------------- +# The code below deals with several issues related to gettimeofday: +# 1. Some systems don't provide a gettimeofday function at all +# (set NO_GETTOD if this is the case). +# 2. See if gettimeofday is declared in the header file. +# if not, set the GETTOD_NOT_DECLARED flag so that tclPort.h can +# declare it. +#-------------------------------------------------------------------- + +ac_fn_c_check_func "$LINENO" "gettimeofday" "ac_cv_func_gettimeofday" +if test "x$ac_cv_func_gettimeofday" = xyes; then : + else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 -ac_header_compiler=no + +$as_echo "#define NO_GETTOD 1" >>confdefs.h + + fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -echo "${ECHO_T}$ac_header_compiler" >&6 -# Is the header present? -echo "$as_me:$LINENO: checking $ac_header presence" >&5 -echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for gettimeofday declaration" >&5 +$as_echo_n "checking for gettimeofday declaration... " >&6; } +if ${tcl_cv_grep_gettimeofday+:} false; then : + $as_echo_n "(cached) " >&6 +else + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#include <$ac_header> +#include + _ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "gettimeofday" >/dev/null 2>&1; then : + tcl_cv_grep_gettimeofday=present else - ac_cpp_err=yes + tcl_cv_grep_gettimeofday=missing fi -if test -z "$ac_cpp_err"; then - ac_header_preproc=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 +rm -f conftest* - ac_header_preproc=no fi -rm -f conftest.err conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -echo "${ECHO_T}$ac_header_preproc" >&6 +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_grep_gettimeofday" >&5 +$as_echo "$tcl_cv_grep_gettimeofday" >&6; } +if test $tcl_cv_grep_gettimeofday = missing ; then -# So? What about this header? -case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in - yes:no: ) - { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 -echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 -echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} - ac_header_preproc=yes - ;; - no:yes:* ) - { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 -echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 -echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 -echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 -echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 -echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} - ( - cat <<\_ASBOX -## ------------------------------ ## -## Report this to the tcl lists. ## -## ------------------------------ ## -_ASBOX - ) | - sed "s/^/$as_me: WARNING: /" >&2 - ;; -esac -echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 +$as_echo "#define GETTOD_NOT_DECLARED 1" >>confdefs.h + +fi + +#-------------------------------------------------------------------- +# The following code checks to see whether it is possible to get +# signed chars on this platform. This is needed in order to +# properly generate sign-extended ints from character values. +#-------------------------------------------------------------------- + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether char is unsigned" >&5 +$as_echo_n "checking whether char is unsigned... " >&6; } +if ${ac_cv_c_char_unsigned+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +static int test_array [1 - 2 * !(((char) -1) < 0)]; +test_array [0] = 0; +return test_array [0]; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_c_char_unsigned=no else - eval "$as_ac_Header=\$ac_header_preproc" + ac_cv_c_char_unsigned=yes fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 - +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi -if test `eval echo '${'$as_ac_Header'}'` = yes; then - cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_char_unsigned" >&5 +$as_echo "$ac_cv_c_char_unsigned" >&6; } +if test $ac_cv_c_char_unsigned = yes && test "$GCC" != yes; then + $as_echo "#define __CHAR_UNSIGNED__ 1" >>confdefs.h fi -done - +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking signed char declarations" >&5 +$as_echo_n "checking signed char declarations... " >&6; } +if ${tcl_cv_char_signed+:} false; then : + $as_echo_n "(cached) " >&6 +else -for ac_func in copyfile -do -as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` -echo "$as_me:$LINENO: checking for $ac_func" >&5 -echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 -if eval "test \"\${$as_ac_var+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -/* Define $ac_func to an innocuous variant, in case declares $ac_func. - For example, HP-UX 11i declares gettimeofday. */ -#define $ac_func innocuous_$ac_func - -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char $ac_func (); below. - Prefer to if __STDC__ is defined, since - exists even on freestanding compilers. */ - -#ifdef __STDC__ -# include -#else -# include -#endif - -#undef $ac_func - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -{ -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char $ac_func (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_$ac_func) || defined (__stub___$ac_func) -choke me -#else -char (*f) () = $ac_func; -#endif -#ifdef __cplusplus -} -#endif int main () { -return f != $ac_func; + + signed char *p; + p = 0; + ; return 0; } _ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - eval "$as_ac_var=yes" +if ac_fn_c_try_compile "$LINENO"; then : + tcl_cv_char_signed=yes else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -eval "$as_ac_var=no" + tcl_cv_char_signed=no fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 -if test `eval echo '${'$as_ac_var'}'` = yes; then - cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 -_ACEOF +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_char_signed" >&5 +$as_echo "$tcl_cv_char_signed" >&6; } +if test $tcl_cv_char_signed = yes; then + +$as_echo "#define HAVE_SIGNED_CHAR 1" >>confdefs.h fi -done - if test $tcl_corefoundation = yes; then +#-------------------------------------------------------------------- +# Does putenv() copy or not? We need to know to avoid memory leaks. +#-------------------------------------------------------------------- -for ac_header in libkern/OSAtomic.h -do -as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a putenv() that copies the buffer" >&5 +$as_echo_n "checking for a putenv() that copies the buffer... " >&6; } +if ${tcl_cv_putenv_copy+:} false; then : + $as_echo_n "(cached) " >&6 else - # Is the header compilable? -echo "$as_me:$LINENO: checking $ac_header usability" >&5 -echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -#include <$ac_header> -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_header_compiler=yes + + if test "$cross_compiling" = yes; then : + tcl_cv_putenv_copy=no else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ -ac_header_compiler=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -echo "${ECHO_T}$ac_header_compiler" >&6 + #include + #define OURVAR "havecopy=yes" + int main (int argc, char *argv[]) + { + char *foo, *bar; + foo = (char *)strdup(OURVAR); + putenv(foo); + strcpy((char *)(strchr(foo, '=') + 1), "no"); + bar = getenv("havecopy"); + if (!strcmp(bar, "no")) { + /* doesnt copy */ + return 0; + } else { + /* does copy */ + return 1; + } + } -# Is the header present? -echo "$as_me:$LINENO: checking $ac_header presence" >&5 -echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include <$ac_header> _ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi +if ac_fn_c_try_run "$LINENO"; then : + tcl_cv_putenv_copy=no else - ac_cpp_err=yes + tcl_cv_putenv_copy=yes fi -if test -z "$ac_cpp_err"; then - ac_header_preproc=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_header_preproc=no +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext fi -rm -f conftest.err conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -echo "${ECHO_T}$ac_header_preproc" >&6 -# So? What about this header? -case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in - yes:no: ) - { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 -echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 -echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} - ac_header_preproc=yes - ;; - no:yes:* ) - { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 -echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 -echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 -echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 -echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 -echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} - ( - cat <<\_ASBOX -## ------------------------------ ## -## Report this to the tcl lists. ## -## ------------------------------ ## -_ASBOX - ) | - sed "s/^/$as_me: WARNING: /" >&2 - ;; -esac -echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - eval "$as_ac_Header=\$ac_header_preproc" fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_putenv_copy" >&5 +$as_echo "$tcl_cv_putenv_copy" >&6; } +if test $tcl_cv_putenv_copy = yes; then -fi -if test `eval echo '${'$as_ac_Header'}'` = yes; then - cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF +$as_echo "#define HAVE_PUTENV_THAT_COPIES 1" >>confdefs.h fi -done +#-------------------------------------------------------------------- +# Check for support of nl_langinfo function +#-------------------------------------------------------------------- -for ac_func in OSSpinLockLock -do -as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` -echo "$as_me:$LINENO: checking for $ac_func" >&5 -echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 -if eval "test \"\${$as_ac_var+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -/* Define $ac_func to an innocuous variant, in case declares $ac_func. - For example, HP-UX 11i declares gettimeofday. */ -#define $ac_func innocuous_$ac_func + # Check whether --enable-langinfo was given. +if test "${enable_langinfo+set}" = set; then : + enableval=$enable_langinfo; langinfo_ok=$enableval +else + langinfo_ok=yes +fi -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char $ac_func (); below. - Prefer to if __STDC__ is defined, since - exists even on freestanding compilers. */ -#ifdef __STDC__ -# include -#else -# include -#endif + HAVE_LANGINFO=0 + if test "$langinfo_ok" = "yes"; then + ac_fn_c_check_header_mongrel "$LINENO" "langinfo.h" "ac_cv_header_langinfo_h" "$ac_includes_default" +if test "x$ac_cv_header_langinfo_h" = xyes; then : + langinfo_ok=yes +else + langinfo_ok=no +fi -#undef $ac_func -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -{ -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char $ac_func (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_$ac_func) || defined (__stub___$ac_func) -choke me -#else -char (*f) () = $ac_func; -#endif -#ifdef __cplusplus -} -#endif + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use nl_langinfo" >&5 +$as_echo_n "checking whether to use nl_langinfo... " >&6; } + if test "$langinfo_ok" = "yes"; then + if ${tcl_cv_langinfo_h+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include int main () { -return f != $ac_func; +nl_langinfo(CODESET); ; return 0; } _ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - eval "$as_ac_var=yes" +if ac_fn_c_try_compile "$LINENO"; then : + tcl_cv_langinfo_h=yes else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -eval "$as_ac_var=no" + tcl_cv_langinfo_h=no fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 -if test `eval echo '${'$as_ac_var'}'` = yes; then + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_langinfo_h" >&5 +$as_echo "$tcl_cv_langinfo_h" >&6; } + if test $tcl_cv_langinfo_h = yes; then + +$as_echo "#define HAVE_LANGINFO 1" >>confdefs.h + + fi + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $langinfo_ok" >&5 +$as_echo "$langinfo_ok" >&6; } + fi + + +#-------------------------------------------------------------------- +# Check for support of chflags and mkstemps functions +#-------------------------------------------------------------------- + +for ac_func in chflags mkstemps +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done - fi -cat >>confdefs.h <<\_ACEOF -#define USE_VFORK 1 -_ACEOF +#-------------------------------------------------------------------- +# Check for support of isnan() function or macro +#-------------------------------------------------------------------- +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking isnan" >&5 +$as_echo_n "checking isnan... " >&6; } +if ${tcl_cv_isnan+:} false; then : + $as_echo_n "(cached) " >&6 +else -cat >>confdefs.h <<\_ACEOF -#define TCL_DEFAULT_ENCODING "utf-8" -_ACEOF + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +isnan(0.0); /* Generates an error if isnan is missing */ -cat >>confdefs.h <<\_ACEOF -#define TCL_LOAD_FROM_MEMORY 1 + ; + return 0; +} _ACEOF +if ac_fn_c_try_link "$LINENO"; then : + tcl_cv_isnan=yes +else + tcl_cv_isnan=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_isnan" >&5 +$as_echo "$tcl_cv_isnan" >&6; } +if test $tcl_cv_isnan = no; then +$as_echo "#define NO_ISNAN 1" >>confdefs.h -cat >>confdefs.h <<\_ACEOF -#define TCL_WIDE_CLICKS 1 -_ACEOF +fi +#-------------------------------------------------------------------- +# Darwin specific API checks and defines +#-------------------------------------------------------------------- + +if test "`uname -s`" = "Darwin" ; then + for ac_func in getattrlist +do : + ac_fn_c_check_func "$LINENO" "getattrlist" "ac_cv_func_getattrlist" +if test "x$ac_cv_func_getattrlist" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_GETATTRLIST 1 +_ACEOF -for ac_header in AvailabilityMacros.h -do -as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 -else - # Is the header compilable? -echo "$as_me:$LINENO: checking $ac_header usability" >&5 -echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ +done + + for ac_header in copyfile.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "copyfile.h" "ac_cv_header_copyfile_h" "$ac_includes_default" +if test "x$ac_cv_header_copyfile_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_COPYFILE_H 1 _ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -#include <$ac_header> + +fi + +done + + for ac_func in copyfile +do : + ac_fn_c_check_func "$LINENO" "copyfile" "ac_cv_func_copyfile" +if test "x$ac_cv_func_copyfile" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_COPYFILE 1 _ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_header_compiler=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 -ac_header_compiler=no fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -echo "${ECHO_T}$ac_header_compiler" >&6 +done -# Is the header present? -echo "$as_me:$LINENO: checking $ac_header presence" >&5 -echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ + if test $tcl_corefoundation = yes; then + for ac_header in libkern/OSAtomic.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "libkern/OSAtomic.h" "ac_cv_header_libkern_OSAtomic_h" "$ac_includes_default" +if test "x$ac_cv_header_libkern_OSAtomic_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBKERN_OSATOMIC_H 1 _ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include <$ac_header> + +fi + +done + + for ac_func in OSSpinLockLock +do : + ac_fn_c_check_func "$LINENO" "OSSpinLockLock" "ac_cv_func_OSSpinLockLock" +if test "x$ac_cv_func_OSSpinLockLock" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_OSSPINLOCKLOCK 1 _ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes + fi -if test -z "$ac_cpp_err"; then - ac_header_preproc=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 +done + + fi + +$as_echo "#define USE_VFORK 1" >>confdefs.h + + +$as_echo "#define TCL_DEFAULT_ENCODING \"utf-8\"" >>confdefs.h + - ac_header_preproc=no -fi -rm -f conftest.err conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -echo "${ECHO_T}$ac_header_preproc" >&6 +$as_echo "#define TCL_LOAD_FROM_MEMORY 1" >>confdefs.h -# So? What about this header? -case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in - yes:no: ) - { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 -echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 -echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} - ac_header_preproc=yes - ;; - no:yes:* ) - { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 -echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 -echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 -echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 -echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 -echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} - ( - cat <<\_ASBOX -## ------------------------------ ## -## Report this to the tcl lists. ## -## ------------------------------ ## -_ASBOX - ) | - sed "s/^/$as_me: WARNING: /" >&2 - ;; -esac -echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - eval "$as_ac_Header=\$ac_header_preproc" -fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 -fi -if test `eval echo '${'$as_ac_Header'}'` = yes; then +$as_echo "#define TCL_WIDE_CLICKS 1" >>confdefs.h + + for ac_header in AvailabilityMacros.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "AvailabilityMacros.h" "ac_cv_header_AvailabilityMacros_h" "$ac_includes_default" +if test "x$ac_cv_header_AvailabilityMacros_h" = xyes; then : cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +#define HAVE_AVAILABILITYMACROS_H 1 _ACEOF fi @@ -18064,18 +9826,14 @@ fi done if test "$ac_cv_header_AvailabilityMacros_h" = yes; then - echo "$as_me:$LINENO: checking if weak import is available" >&5 -echo $ECHO_N "checking if weak import is available... $ECHO_C" >&6 -if test "${tcl_cv_cc_weak_import+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if weak import is available" >&5 +$as_echo_n "checking if weak import is available... " >&6; } +if ${tcl_cv_cc_weak_import+:} false; then : + $as_echo_n "(cached) " >&6 else hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -Werror" - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ @@ -18095,60 +9853,30 @@ rand(); return 0; } _ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then +if ac_fn_c_try_link "$LINENO"; then : tcl_cv_cc_weak_import=yes else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -tcl_cv_cc_weak_import=no + tcl_cv_cc_weak_import=no fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext CFLAGS=$hold_cflags fi -echo "$as_me:$LINENO: result: $tcl_cv_cc_weak_import" >&5 -echo "${ECHO_T}$tcl_cv_cc_weak_import" >&6 +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_cc_weak_import" >&5 +$as_echo "$tcl_cv_cc_weak_import" >&6; } if test $tcl_cv_cc_weak_import = yes; then -cat >>confdefs.h <<\_ACEOF -#define HAVE_WEAK_IMPORT 1 -_ACEOF +$as_echo "#define HAVE_WEAK_IMPORT 1" >>confdefs.h fi - echo "$as_me:$LINENO: checking if Darwin SUSv3 extensions are available" >&5 -echo $ECHO_N "checking if Darwin SUSv3 extensions are available... $ECHO_C" >&6 -if test "${tcl_cv_cc_darwin_c_source+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if Darwin SUSv3 extensions are available" >&5 +$as_echo_n "checking if Darwin SUSv3 extensions are available... " >&6; } +if ${tcl_cv_cc_darwin_c_source+:} false; then : + $as_echo_n "(cached) " >&6 else hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -Werror" - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ @@ -18169,45 +9897,19 @@ main () return 0; } _ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then +if ac_fn_c_try_compile "$LINENO"; then : tcl_cv_cc_darwin_c_source=yes else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -tcl_cv_cc_darwin_c_source=no + tcl_cv_cc_darwin_c_source=no fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext CFLAGS=$hold_cflags fi -echo "$as_me:$LINENO: result: $tcl_cv_cc_darwin_c_source" >&5 -echo "${ECHO_T}$tcl_cv_cc_darwin_c_source" >&6 +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_cc_darwin_c_source" >&5 +$as_echo "$tcl_cv_cc_darwin_c_source" >&6; } if test $tcl_cv_cc_darwin_c_source = yes; then -cat >>confdefs.h <<\_ACEOF -#define _DARWIN_C_SOURCE 1 -_ACEOF +$as_echo "#define _DARWIN_C_SOURCE 1" >>confdefs.h fi fi @@ -18223,17 +9925,13 @@ fi # Check for support of fts functions (readdir replacement) #-------------------------------------------------------------------- -echo "$as_me:$LINENO: checking for fts" >&5 -echo $ECHO_N "checking for fts... $ECHO_C" >&6 -if test "${tcl_cv_api_fts+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fts" >&5 +$as_echo_n "checking for fts... " >&6; } +if ${tcl_cv_api_fts+:} false; then : + $as_echo_n "(cached) " >&6 else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include @@ -18252,45 +9950,19 @@ main () return 0; } _ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then +if ac_fn_c_try_link "$LINENO"; then : tcl_cv_api_fts=yes else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -tcl_cv_api_fts=no + tcl_cv_api_fts=no fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext fi -echo "$as_me:$LINENO: result: $tcl_cv_api_fts" >&5 -echo "${ECHO_T}$tcl_cv_api_fts" >&6 +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_api_fts" >&5 +$as_echo "$tcl_cv_api_fts" >&6; } if test $tcl_cv_api_fts = yes; then -cat >>confdefs.h <<\_ACEOF -#define HAVE_FTS 1 -_ACEOF +$as_echo "#define HAVE_FTS 1" >>confdefs.h fi @@ -18301,300 +9973,24 @@ fi #-------------------------------------------------------------------- - -for ac_header in sys/ioctl.h -do -as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 -else - # Is the header compilable? -echo "$as_me:$LINENO: checking $ac_header usability" >&5 -echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -#include <$ac_header> -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_header_compiler=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_header_compiler=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -echo "${ECHO_T}$ac_header_compiler" >&6 - -# Is the header present? -echo "$as_me:$LINENO: checking $ac_header presence" >&5 -echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include <$ac_header> -_ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - ac_header_preproc=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_header_preproc=no -fi -rm -f conftest.err conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -echo "${ECHO_T}$ac_header_preproc" >&6 - -# So? What about this header? -case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in - yes:no: ) - { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 -echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 -echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} - ac_header_preproc=yes - ;; - no:yes:* ) - { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 -echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 -echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 -echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 -echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 -echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} - ( - cat <<\_ASBOX -## ------------------------------ ## -## Report this to the tcl lists. ## -## ------------------------------ ## -_ASBOX - ) | - sed "s/^/$as_me: WARNING: /" >&2 - ;; -esac -echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - eval "$as_ac_Header=\$ac_header_preproc" -fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 - -fi -if test `eval echo '${'$as_ac_Header'}'` = yes; then + for ac_header in sys/ioctl.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "sys/ioctl.h" "ac_cv_header_sys_ioctl_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_ioctl_h" = xyes; then : cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +#define HAVE_SYS_IOCTL_H 1 _ACEOF fi done - -for ac_header in sys/filio.h -do -as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 -else - # Is the header compilable? -echo "$as_me:$LINENO: checking $ac_header usability" >&5 -echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -#include <$ac_header> -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_header_compiler=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_header_compiler=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -echo "${ECHO_T}$ac_header_compiler" >&6 - -# Is the header present? -echo "$as_me:$LINENO: checking $ac_header presence" >&5 -echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include <$ac_header> -_ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - ac_header_preproc=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_header_preproc=no -fi -rm -f conftest.err conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -echo "${ECHO_T}$ac_header_preproc" >&6 - -# So? What about this header? -case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in - yes:no: ) - { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 -echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 -echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} - ac_header_preproc=yes - ;; - no:yes:* ) - { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 -echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 -echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 -echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 -echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 -echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} - ( - cat <<\_ASBOX -## ------------------------------ ## -## Report this to the tcl lists. ## -## ------------------------------ ## -_ASBOX - ) | - sed "s/^/$as_me: WARNING: /" >&2 - ;; -esac -echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - eval "$as_ac_Header=\$ac_header_preproc" -fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 - -fi -if test `eval echo '${'$as_ac_Header'}'` = yes; then + for ac_header in sys/filio.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "sys/filio.h" "ac_cv_header_sys_filio_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_filio_h" = xyes; then : cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +#define HAVE_SYS_FILIO_H 1 _ACEOF fi @@ -18602,10 +9998,10 @@ fi done - echo "$as_me:$LINENO: checking system version" >&5 -echo $ECHO_N "checking system version... $ECHO_C" >&6 -if test "${tcl_cv_sys_version+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking system version" >&5 +$as_echo_n "checking system version... " >&6; } +if ${tcl_cv_sys_version+:} false; then : + $as_echo_n "(cached) " >&6 else if test -f /usr/lib/NextStep/software_version; then @@ -18613,8 +10009,8 @@ else else tcl_cv_sys_version=`uname -s`-`uname -r` if test "$?" -ne 0 ; then - { echo "$as_me:$LINENO: WARNING: can't find uname command" >&5 -echo "$as_me: WARNING: can't find uname command" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: can't find uname command" >&5 +$as_echo "$as_me: WARNING: can't find uname command" >&2;} tcl_cv_sys_version=unknown else # Special check for weird MP-RAS system (uname returns weird @@ -18630,58 +10026,52 @@ echo "$as_me: WARNING: can't find uname command" >&2;} fi fi -echo "$as_me:$LINENO: result: $tcl_cv_sys_version" >&5 -echo "${ECHO_T}$tcl_cv_sys_version" >&6 +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_sys_version" >&5 +$as_echo "$tcl_cv_sys_version" >&6; } system=$tcl_cv_sys_version - echo "$as_me:$LINENO: checking FIONBIO vs. O_NONBLOCK for nonblocking I/O" >&5 -echo $ECHO_N "checking FIONBIO vs. O_NONBLOCK for nonblocking I/O... $ECHO_C" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking FIONBIO vs. O_NONBLOCK for nonblocking I/O" >&5 +$as_echo_n "checking FIONBIO vs. O_NONBLOCK for nonblocking I/O... " >&6; } case $system in OSF*) -cat >>confdefs.h <<\_ACEOF -#define USE_FIONBIO 1 -_ACEOF +$as_echo "#define USE_FIONBIO 1" >>confdefs.h - echo "$as_me:$LINENO: result: FIONBIO" >&5 -echo "${ECHO_T}FIONBIO" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: FIONBIO" >&5 +$as_echo "FIONBIO" >&6; } ;; SunOS-4*) -cat >>confdefs.h <<\_ACEOF -#define USE_FIONBIO 1 -_ACEOF +$as_echo "#define USE_FIONBIO 1" >>confdefs.h - echo "$as_me:$LINENO: result: FIONBIO" >&5 -echo "${ECHO_T}FIONBIO" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: FIONBIO" >&5 +$as_echo "FIONBIO" >&6; } ;; *) - echo "$as_me:$LINENO: result: O_NONBLOCK" >&5 -echo "${ECHO_T}O_NONBLOCK" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: O_NONBLOCK" >&5 +$as_echo "O_NONBLOCK" >&6; } ;; esac #------------------------------------------------------------------------ -echo "$as_me:$LINENO: checking whether to use dll unloading" >&5 -echo $ECHO_N "checking whether to use dll unloading... $ECHO_C" >&6 -# Check whether --enable-dll-unloading or --disable-dll-unloading was given. -if test "${enable_dll_unloading+set}" = set; then - enableval="$enable_dll_unloading" - tcl_ok=$enableval +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use dll unloading" >&5 +$as_echo_n "checking whether to use dll unloading... " >&6; } +# Check whether --enable-dll-unloading was given. +if test "${enable_dll_unloading+set}" = set; then : + enableval=$enable_dll_unloading; tcl_ok=$enableval else tcl_ok=yes -fi; +fi + if test $tcl_ok = yes; then -cat >>confdefs.h <<\_ACEOF -#define TCL_UNLOAD_DLLS 1 -_ACEOF +$as_echo "#define TCL_UNLOAD_DLLS 1" >>confdefs.h fi -echo "$as_me:$LINENO: result: $tcl_ok" >&5 -echo "${ECHO_T}$tcl_ok" >&6 +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_ok" >&5 +$as_echo "$tcl_ok" >&6; } #------------------------------------------------------------------------ # Check whether the timezone data is supplied by the OS or has @@ -18689,31 +10079,31 @@ echo "${ECHO_T}$tcl_ok" >&6 # be overriden on the configure command line either way. #------------------------------------------------------------------------ -echo "$as_me:$LINENO: checking for timezone data" >&5 -echo $ECHO_N "checking for timezone data... $ECHO_C" >&6 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for timezone data" >&5 +$as_echo_n "checking for timezone data... " >&6; } -# Check whether --with-tzdata or --without-tzdata was given. -if test "${with_tzdata+set}" = set; then - withval="$with_tzdata" - tcl_ok=$withval +# Check whether --with-tzdata was given. +if test "${with_tzdata+set}" = set; then : + withval=$with_tzdata; tcl_ok=$withval else tcl_ok=auto -fi; +fi + # # Any directories that get added here must also be added to the # search path in ::tcl::clock::Initialize (library/clock.tcl). # case $tcl_ok in no) - echo "$as_me:$LINENO: result: supplied by OS vendor" >&5 -echo "${ECHO_T}supplied by OS vendor" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: supplied by OS vendor" >&5 +$as_echo "supplied by OS vendor" >&6; } ;; yes) # nothing to do here ;; auto*) - if test "${tcl_cv_dir_zoneinfo+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + if ${tcl_cv_dir_zoneinfo+:} false; then : + $as_echo_n "(cached) " >&6 else for dir in /usr/share/zoneinfo \ @@ -18730,22 +10120,20 @@ fi if test -n "$tcl_cv_dir_zoneinfo"; then tcl_ok=no - echo "$as_me:$LINENO: result: $dir" >&5 -echo "${ECHO_T}$dir" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $dir" >&5 +$as_echo "$dir" >&6; } else tcl_ok=yes fi ;; *) - { { echo "$as_me:$LINENO: error: invalid argument: $tcl_ok" >&5 -echo "$as_me: error: invalid argument: $tcl_ok" >&2;} - { (exit 1); exit 1; }; } + as_fn_error $? "invalid argument: $tcl_ok" "$LINENO" 5 ;; esac if test $tcl_ok = yes then - echo "$as_me:$LINENO: result: supplied by Tcl" >&5 -echo "${ECHO_T}supplied by Tcl" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: supplied by Tcl" >&5 +$as_echo "supplied by Tcl" >&6; } INSTALL_TZDATA=install-tzdata fi @@ -18753,152 +10141,16 @@ fi # DTrace support #-------------------------------------------------------------------- -# Check whether --enable-dtrace or --disable-dtrace was given. -if test "${enable_dtrace+set}" = set; then - enableval="$enable_dtrace" - tcl_ok=$enableval +# Check whether --enable-dtrace was given. +if test "${enable_dtrace+set}" = set; then : + enableval=$enable_dtrace; tcl_ok=$enableval else tcl_ok=no -fi; -if test $tcl_ok = yes; then - if test "${ac_cv_header_sys_sdt_h+set}" = set; then - echo "$as_me:$LINENO: checking for sys/sdt.h" >&5 -echo $ECHO_N "checking for sys/sdt.h... $ECHO_C" >&6 -if test "${ac_cv_header_sys_sdt_h+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -fi -echo "$as_me:$LINENO: result: $ac_cv_header_sys_sdt_h" >&5 -echo "${ECHO_T}$ac_cv_header_sys_sdt_h" >&6 -else - # Is the header compilable? -echo "$as_me:$LINENO: checking sys/sdt.h usability" >&5 -echo $ECHO_N "checking sys/sdt.h usability... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -#include -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_header_compiler=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -ac_header_compiler=no -fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -echo "${ECHO_T}$ac_header_compiler" >&6 - -# Is the header present? -echo "$as_me:$LINENO: checking sys/sdt.h presence" >&5 -echo $ECHO_N "checking sys/sdt.h presence... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -_ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes fi -if test -z "$ac_cpp_err"; then - ac_header_preproc=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_header_preproc=no -fi -rm -f conftest.err conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -echo "${ECHO_T}$ac_header_preproc" >&6 - -# So? What about this header? -case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in - yes:no: ) - { echo "$as_me:$LINENO: WARNING: sys/sdt.h: accepted by the compiler, rejected by the preprocessor!" >&5 -echo "$as_me: WARNING: sys/sdt.h: accepted by the compiler, rejected by the preprocessor!" >&2;} - { echo "$as_me:$LINENO: WARNING: sys/sdt.h: proceeding with the compiler's result" >&5 -echo "$as_me: WARNING: sys/sdt.h: proceeding with the compiler's result" >&2;} - ac_header_preproc=yes - ;; - no:yes:* ) - { echo "$as_me:$LINENO: WARNING: sys/sdt.h: present but cannot be compiled" >&5 -echo "$as_me: WARNING: sys/sdt.h: present but cannot be compiled" >&2;} - { echo "$as_me:$LINENO: WARNING: sys/sdt.h: check for missing prerequisite headers?" >&5 -echo "$as_me: WARNING: sys/sdt.h: check for missing prerequisite headers?" >&2;} - { echo "$as_me:$LINENO: WARNING: sys/sdt.h: see the Autoconf documentation" >&5 -echo "$as_me: WARNING: sys/sdt.h: see the Autoconf documentation" >&2;} - { echo "$as_me:$LINENO: WARNING: sys/sdt.h: section \"Present But Cannot Be Compiled\"" >&5 -echo "$as_me: WARNING: sys/sdt.h: section \"Present But Cannot Be Compiled\"" >&2;} - { echo "$as_me:$LINENO: WARNING: sys/sdt.h: proceeding with the preprocessor's result" >&5 -echo "$as_me: WARNING: sys/sdt.h: proceeding with the preprocessor's result" >&2;} - { echo "$as_me:$LINENO: WARNING: sys/sdt.h: in the future, the compiler will take precedence" >&5 -echo "$as_me: WARNING: sys/sdt.h: in the future, the compiler will take precedence" >&2;} - ( - cat <<\_ASBOX -## ------------------------------ ## -## Report this to the tcl lists. ## -## ------------------------------ ## -_ASBOX - ) | - sed "s/^/$as_me: WARNING: /" >&2 - ;; -esac -echo "$as_me:$LINENO: checking for sys/sdt.h" >&5 -echo $ECHO_N "checking for sys/sdt.h... $ECHO_C" >&6 -if test "${ac_cv_header_sys_sdt_h+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_cv_header_sys_sdt_h=$ac_header_preproc -fi -echo "$as_me:$LINENO: result: $ac_cv_header_sys_sdt_h" >&5 -echo "${ECHO_T}$ac_cv_header_sys_sdt_h" >&6 -fi -if test $ac_cv_header_sys_sdt_h = yes; then +if test $tcl_ok = yes; then + ac_fn_c_check_header_mongrel "$LINENO" "sys/sdt.h" "ac_cv_header_sys_sdt_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_sdt_h" = xyes; then : tcl_ok=yes else tcl_ok=no @@ -18909,10 +10161,10 @@ fi if test $tcl_ok = yes; then # Extract the first word of "dtrace", so it can be a program name with args. set dummy dtrace; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_path_DTRACE+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_DTRACE+:} false; then : + $as_echo_n "(cached) " >&6 else case $DTRACE in [\\/]* | ?:[\\/]*) @@ -18925,38 +10177,37 @@ for as_dir in $as_dummy do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_DTRACE="$as_dir/$ac_word$ac_exec_ext" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done -done + done +IFS=$as_save_IFS ;; esac fi DTRACE=$ac_cv_path_DTRACE - if test -n "$DTRACE"; then - echo "$as_me:$LINENO: result: $DTRACE" >&5 -echo "${ECHO_T}$DTRACE" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DTRACE" >&5 +$as_echo "$DTRACE" >&6; } else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } fi + test -z "$ac_cv_path_DTRACE" && tcl_ok=no fi -echo "$as_me:$LINENO: checking whether to enable DTrace support" >&5 -echo $ECHO_N "checking whether to enable DTrace support... $ECHO_C" >&6 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable DTrace support" >&5 +$as_echo_n "checking whether to enable DTrace support... " >&6; } MAKEFILE_SHELL='/bin/sh' if test $tcl_ok = yes; then -cat >>confdefs.h <<\_ACEOF -#define USE_DTRACE 1 -_ACEOF +$as_echo "#define USE_DTRACE 1" >>confdefs.h DTRACE_SRC="\${DTRACE_SRC}" DTRACE_HDR="\${DTRACE_HDR}" @@ -18974,24 +10225,20 @@ _ACEOF fi fi fi -echo "$as_me:$LINENO: result: $tcl_ok" >&5 -echo "${ECHO_T}$tcl_ok" >&6 +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_ok" >&5 +$as_echo "$tcl_ok" >&6; } #-------------------------------------------------------------------- # The check below checks whether the cpuid instruction is usable. #-------------------------------------------------------------------- -echo "$as_me:$LINENO: checking whether the cpuid instruction is usable" >&5 -echo $ECHO_N "checking whether the cpuid instruction is usable... $ECHO_C" >&6 -if test "${tcl_cv_cpuid+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the cpuid instruction is usable" >&5 +$as_echo_n "checking whether the cpuid instruction is usable... " >&6; } +if ${tcl_cv_cpuid+:} false; then : + $as_echo_n "(cached) " >&6 else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int @@ -19010,45 +10257,19 @@ main () return 0; } _ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then +if ac_fn_c_try_link "$LINENO"; then : tcl_cv_cpuid=yes else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -tcl_cv_cpuid=no + tcl_cv_cpuid=no fi -rm -f conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext fi -echo "$as_me:$LINENO: result: $tcl_cv_cpuid" >&5 -echo "${ECHO_T}$tcl_cv_cpuid" >&6 +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_cpuid" >&5 +$as_echo "$tcl_cv_cpuid" >&6; } if test $tcl_cv_cpuid = yes; then -cat >>confdefs.h <<\_ACEOF -#define HAVE_CPUID 1 -_ACEOF +$as_echo "#define HAVE_CPUID 1" >>confdefs.h fi @@ -19067,6 +10288,10 @@ eval "TCL_LIB_FILE=libtcl${LIB_SUFFIX}" eval "TCL_LIB_FILE=${TCL_LIB_FILE}" +eval "TCL_KIT_LIB_FILE=libtclkit${UNSHARED_LIB_SUFFIX}" +eval "TCL_KIT_LIB_FILE=${TCL_KIT_LIB_FILE}" + + TCL_LIBRARY='$(prefix)/lib/tcl$(VERSION)' PRIVATE_INCLUDE_DIR='$(includedir)' HTML_DIR='$(DISTDIR)/html' @@ -19079,38 +10304,38 @@ HTML_DIR='$(DISTDIR)/html' if test "`uname -s`" = "Darwin" ; then if test "`uname -s`" = "Darwin" ; then - echo "$as_me:$LINENO: checking how to package libraries" >&5 -echo $ECHO_N "checking how to package libraries... $ECHO_C" >&6 - # Check whether --enable-framework or --disable-framework was given. -if test "${enable_framework+set}" = set; then - enableval="$enable_framework" - enable_framework=$enableval + { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to package libraries" >&5 +$as_echo_n "checking how to package libraries... " >&6; } + # Check whether --enable-framework was given. +if test "${enable_framework+set}" = set; then : + enableval=$enable_framework; enable_framework=$enableval else enable_framework=no -fi; +fi + if test $enable_framework = yes; then if test $SHARED_BUILD = 0; then - { echo "$as_me:$LINENO: WARNING: Frameworks can only be built if --enable-shared is yes" >&5 -echo "$as_me: WARNING: Frameworks can only be built if --enable-shared is yes" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Frameworks can only be built if --enable-shared is yes" >&5 +$as_echo "$as_me: WARNING: Frameworks can only be built if --enable-shared is yes" >&2;} enable_framework=no fi if test $tcl_corefoundation = no; then - { echo "$as_me:$LINENO: WARNING: Frameworks can only be used when CoreFoundation is available" >&5 -echo "$as_me: WARNING: Frameworks can only be used when CoreFoundation is available" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Frameworks can only be used when CoreFoundation is available" >&5 +$as_echo "$as_me: WARNING: Frameworks can only be used when CoreFoundation is available" >&2;} enable_framework=no fi fi if test $enable_framework = yes; then - echo "$as_me:$LINENO: result: framework" >&5 -echo "${ECHO_T}framework" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: framework" >&5 +$as_echo "framework" >&6; } FRAMEWORK_BUILD=1 else if test $SHARED_BUILD = 1; then - echo "$as_me:$LINENO: result: shared library" >&5 -echo "${ECHO_T}shared library" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: shared library" >&5 +$as_echo "shared library" >&6; } else - echo "$as_me:$LINENO: result: static library" >&5 -echo "${ECHO_T}static library" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: static library" >&5 +$as_echo "static library" >&6; } fi FRAMEWORK_BUILD=0 fi @@ -19122,20 +10347,18 @@ echo "${ECHO_T}static library" >&6 TCL_SHLIB_LD_EXTRAS="${TCL_SHLIB_LD_EXTRAS}"' -sectcreate __TEXT __info_plist Tcl-Info.plist' EXTRA_TCLSH_LIBS='-sectcreate __TEXT __info_plist Tclsh-Info.plist' EXTRA_APP_CC_SWITCHES='-mdynamic-no-pic' - ac_config_files="$ac_config_files Tcl-Info.plist:../macosx/Tcl-Info.plist.in Tclsh-Info.plist:../macosx/Tclsh-Info.plist.in" + ac_config_files="$ac_config_files Tcl-Info.plist:../macosx/Tcl-Info.plist.in Tclsh-Info.plist:../macosx/Tclsh-Info.plist.in" TCL_YEAR="`date +%Y`" fi if test "$FRAMEWORK_BUILD" = "1" ; then -cat >>confdefs.h <<\_ACEOF -#define TCL_FRAMEWORK 1 -_ACEOF +$as_echo "#define TCL_FRAMEWORK 1" >>confdefs.h # Construct a fake local framework structure to make linking with # '-framework Tcl' and running of tcltest work - ac_config_commands="$ac_config_commands Tcl.framework" + ac_config_commands="$ac_config_commands Tcl.framework" LD_LIBRARY_PATH_VAR="DYLD_FRAMEWORK_PATH" # default install directory for bundled packages @@ -19295,7 +10518,8 @@ TCL_SHARED_BUILD=${SHARED_BUILD} - ac_config_files="$ac_config_files Makefile:../unix/Makefile.in dltest/Makefile:../unix/dltest/Makefile.in tclConfig.sh:../unix/tclConfig.sh.in tcl.pc:../unix/tcl.pc.in" + +ac_config_files="$ac_config_files Makefile:../unix/Makefile.in dltest/Makefile:../unix/dltest/Makefile.in tclConfig.sh:../unix/tclConfig.sh.in tcl.pc:../unix/tcl.pc.in" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure @@ -19315,39 +10539,70 @@ _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. -# So, don't put newlines in cache variables' values. +# So, we kill variables containing newlines. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. -{ +( + for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + (set) 2>&1 | - case `(ac_space=' '; set | grep ac_space) 2>&1` in - *ac_space=\ *) - # `set' does not quote correctly, so add quotes (double-quote - # substitution turns \\\\ into \\, and sed turns \\ into \). + case $as_nl`(ac_space=' '; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + # `set' does not quote correctly, so add quotes: double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \. sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" - ;; + ;; #( *) # `set' quotes correctly as required by POSIX, so do not add quotes. - sed -n \ - "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; - esac; -} | + esac | + sort +) | sed ' + /^ac_cv_env_/b end t clear - : clear + :clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end - /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ - : end' >>confcache -if diff $cache_file confcache >/dev/null 2>&1; then :; else - if test -w $cache_file; then - test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file" - cat confcache >$cache_file + s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + :end' >>confcache +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else + if test -w "$cache_file"; then + if test "x$cache_file" != "x/dev/null"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 +$as_echo "$as_me: updating cache $cache_file" >&6;} + if test ! -f "$cache_file" || test -h "$cache_file"; then + cat confcache >"$cache_file" + else + case $cache_file in #( + */* | ?:*) + mv -f confcache "$cache_file"$$ && + mv -f "$cache_file"$$ "$cache_file" ;; #( + *) + mv -f confcache "$cache_file" ;; + esac + fi + fi else - echo "not updating unwritable cache $cache_file" + { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 +$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache @@ -19356,63 +10611,56 @@ test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' -# VPATH may cause trouble with some makes, so we remove $(srcdir), -# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and -# trailing colons and then remove the whole line if VPATH becomes empty -# (actually we leave an empty line to preserve line numbers). -if test "x$srcdir" = x.; then - ac_vpsub='/^[ ]*VPATH[ ]*=/{ -s/:*\$(srcdir):*/:/; -s/:*\${srcdir}:*/:/; -s/:*@srcdir@:*/:/; -s/^\([^=]*=[ ]*\):*/\1/; -s/:*$//; -s/^[^=]*=[ ]*$//; -}' -fi - # Transform confdefs.h into DEFS. # Protect against shell expansion while executing Makefile rules. # Protect against Makefile macro expansion. # # If the first sed substitution is executed (which looks for macros that -# take arguments), then we branch to the quote section. Otherwise, +# take arguments), then branch to the quote section. Otherwise, # look for a macro that doesn't take arguments. -cat >confdef2opt.sed <<\_ACEOF +ac_script=' +:mline +/\\$/{ + N + s,\\\n,, + b mline +} t clear -: clear -s,^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\),-D\1=\2,g +:clear +s/^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\)/-D\1=\2/g t quote -s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\),-D\1=\2,g +s/^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)/-D\1=\2/g t quote -d -: quote -s,[ `~#$^&*(){}\\|;'"<>?],\\&,g -s,\[,\\&,g -s,\],\\&,g -s,\$,$$,g -p -_ACEOF -# We use echo to avoid assuming a particular line-breaking character. -# The extra dot is to prevent the shell from consuming trailing -# line-breaks from the sub-command output. A line-break within -# single-quotes doesn't work because, if this script is created in a -# platform that uses two characters for line-breaks (e.g., DOS), tr -# would break. -ac_LF_and_DOT=`echo; echo .` -DEFS=`sed -n -f confdef2opt.sed confdefs.h | tr "$ac_LF_and_DOT" ' .'` -rm -f confdef2opt.sed +b any +:quote +s/[ `~#$^&*(){}\\|;'\''"<>?]/\\&/g +s/\[/\\&/g +s/\]/\\&/g +s/\$/$$/g +H +:any +${ + g + s/^\n// + s/\n/ /g + p +} +' +DEFS=`sed -n "$ac_script" confdefs.h` CFLAGS="${CFLAGS} ${CPPFLAGS}"; CPPFLAGS="" -: ${CONFIG_STATUS=./config.status} + +: "${CONFIG_STATUS=./config.status}" +ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" -{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 -echo "$as_me: creating $CONFIG_STATUS" >&6;} -cat >$CONFIG_STATUS <<_ACEOF +{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 +$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} +as_write_fail=0 +cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. @@ -19422,81 +10670,253 @@ cat >$CONFIG_STATUS <<_ACEOF debug=false ac_cs_recheck=false ac_cs_silent=false -SHELL=\${CONFIG_SHELL-$SHELL} -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF -## --------------------- ## -## M4sh Initialization. ## -## --------------------- ## -# Be Bourne compatible -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: - # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' -elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then - set -o posix + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac fi -DUALCASE=1; export DUALCASE # for MKS sh -# Support unset when possible. -if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then - as_unset=unset -else - as_unset=false + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } fi -# Work around bugs in pre-3.0 UWIN ksh. -$as_unset ENV MAIL MAILPATH +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. -for as_var in \ - LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ - LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ - LC_TELEPHONE LC_TIME -do - if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then - eval $as_var=C; export $as_var - else - $as_unset $as_var +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi -done + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + -# Required to use basename. -if expr a : '\(a\)' >/dev/null 2>&1; then +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi -if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi -# Name of the executable. -as_me=`$as_basename "$0" || +as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)$' \| \ - . : '\(.\)' 2>/dev/null || -echo X/"$0" | - sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } - /^X\/\(\/\/\)$/{ s//\1/; q; } - /^X\/\(\/\).*/{ s//\1/; q; } - s/.*/./; q'` + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` - -# PATH needs CR, and LINENO needs CR and PATH. # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' @@ -19504,148 +10924,111 @@ as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits -# The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then - echo "#! /bin/sh" >conf$$.sh - echo "exit 0" >>conf$$.sh - chmod +x conf$$.sh - if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then - PATH_SEPARATOR=';' - else - PATH_SEPARATOR=: - fi - rm -f conf$$.sh -fi - - - as_lineno_1=$LINENO - as_lineno_2=$LINENO - as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` - test "x$as_lineno_1" != "x$as_lineno_2" && - test "x$as_lineno_3" = "x$as_lineno_2" || { - # Find who we are. Look in the path if we contain no path at all - # relative or not. - case $0 in - *[\\/]* ) as_myself=$0 ;; - *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break -done - - ;; - esac - # We did not find ourselves, most probably we were run as `sh COMMAND' - # in which case we are not to be found in the path. - if test "x$as_myself" = x; then - as_myself=$0 - fi - if test ! -f "$as_myself"; then - { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5 -echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;} - { (exit 1); exit 1; }; } - fi - case $CONFIG_SHELL in - '') - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for as_base in sh bash ksh sh5; do - case $as_dir in - /*) - if ("$as_dir/$as_base" -c ' - as_lineno_1=$LINENO - as_lineno_2=$LINENO - as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` - test "x$as_lineno_1" != "x$as_lineno_2" && - test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then - $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } - $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } - CONFIG_SHELL=$as_dir/$as_base - export CONFIG_SHELL - exec "$CONFIG_SHELL" "$0" ${1+"$@"} - fi;; - esac - done -done -;; - esac - - # Create $as_me.lineno as a copy of $as_myself, but with $LINENO - # uniformly replaced by the line number. The first 'sed' inserts a - # line-number line before each line; the second 'sed' does the real - # work. The second script uses 'N' to pair each line-number line - # with the numbered line, and appends trailing '-' during - # substitution so that $LINENO is not a special case at line end. - # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the - # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) - sed '=' <$as_myself | - sed ' - N - s,$,-, - : loop - s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, - t loop - s,-$,, - s,^['$as_cr_digits']*\n,, - ' >$as_me.lineno && - chmod +x $as_me.lineno || - { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5 -echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;} - { (exit 1); exit 1; }; } - - # Don't try to exec as it changes $[0], causing all sort of problems - # (the dirname of $[0] is not the place where we might find the - # original and so on. Autoconf is especially sensible to this). - . ./$as_me.lineno - # Exit status is that of the last command. - exit -} - - -case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in - *c*,-n*) ECHO_N= ECHO_C=' -' ECHO_T=' ' ;; - *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; - *) ECHO_N= ECHO_C='\c' ECHO_T= ;; +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; esac -if expr a : '\(a\)' >/dev/null 2>&1; then - as_expr=expr +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file else - as_expr=false + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null fi - -rm -f conf$$ conf$$.exe conf$$.file -echo >conf$$.file -if ln -s conf$$.file conf$$ 2>/dev/null; then - # We could just check for DJGPP; but this test a) works b) is more generic - # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). - if test -f conf$$.exe; then - # Don't use ln at all; we don't have any links - as_ln_s='cp -p' - else +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -pR' fi -elif ln conf$$.file conf$$ 2>/dev/null; then - as_ln_s=ln else - as_ln_s='cp -p' + as_ln_s='cp -pR' fi -rm -f conf$$ conf$$.exe conf$$.file +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + +} # as_fn_mkdir_p if mkdir -p . 2>/dev/null; then - as_mkdir_p=: + as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi -as_executable_p="test -f" + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +as_test_x='test -x' +as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" @@ -19654,31 +11037,20 @@ as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" -# IFS -# We need space, tab and new line, in precisely that order. -as_nl=' -' -IFS=" $as_nl" - -# CDPATH. -$as_unset CDPATH - exec 6>&1 - -# Open the log real soon, to keep \$[0] and so on meaningful, and to +## ----------------------------------- ## +## Main body of $CONFIG_STATUS script. ## +## ----------------------------------- ## +_ASEOF +test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# Save the log message, to keep $0 and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their -# values after options handling. Logging --version etc. is OK. -exec 5>>config.log -{ - echo - sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX -## Running $as_me. ## -_ASBOX -} >&5 -cat >&5 <<_CSEOF - +# values after options handling. +ac_log=" This file was extended by tcl $as_me 8.6, which was -generated by GNU Autoconf 2.59. Invocation command line was +generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS @@ -19686,43 +11058,41 @@ generated by GNU Autoconf 2.59. Invocation command line was CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ -_CSEOF -echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5 -echo >&5 +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + _ACEOF -# Files that config.status was made for. -if test -n "$ac_config_files"; then - echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS -fi +case $ac_config_files in *" +"*) set x $ac_config_files; shift; ac_config_files=$*;; +esac -if test -n "$ac_config_headers"; then - echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS -fi -if test -n "$ac_config_links"; then - echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS -fi -if test -n "$ac_config_commands"; then - echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS -fi +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# Files that config.status was made for. +config_files="$ac_config_files" +config_commands="$ac_config_commands" -cat >>$CONFIG_STATUS <<\_ACEOF +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ac_cs_usage="\ -\`$as_me' instantiates files from templates according to the -current configuration. +\`$as_me' instantiates files and other configuration actions +from templates according to the current configuration. Unless the files +and actions are specified as TAGs, all are instantiated by default. -Usage: $0 [OPTIONS] [FILE]... +Usage: $0 [OPTION]... [TAG]... -h, --help print this help, then exit - -V, --version print version number, then exit - -q, --quiet do not print progress messages + -V, --version print version number and configuration settings, then exit + --config print configuration, then exit + -q, --quiet, --silent + do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions - --file=FILE[:TEMPLATE] - instantiate the configuration file FILE + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE Configuration files: $config_files @@ -19730,83 +11100,78 @@ $config_files Configuration commands: $config_commands -Report bugs to ." -_ACEOF +Report bugs to the package provider." -cat >>$CONFIG_STATUS <<_ACEOF +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ tcl config.status 8.6 -configured by $0, generated by GNU Autoconf 2.59, - with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\" +configured by $0, generated by GNU Autoconf 2.69, + with options \\"\$ac_cs_config\\" -Copyright (C) 2003 Free Software Foundation, Inc. +Copyright (C) 2012 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." -srcdir=$srcdir + +ac_pwd='$ac_pwd' +srcdir='$srcdir' +test -n "\$AWK" || AWK=awk _ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF -# If no file are specified by the user, then we need to provide default -# value. By we need to know if files were specified by the user. +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# The default lists apply if the user does not specify any file. ac_need_defaults=: while test $# != 0 do case $1 in - --*=*) - ac_option=`expr "x$1" : 'x\([^=]*\)='` - ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'` + --*=?*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + --*=) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg= ac_shift=: ;; - -*) + *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; - *) # This is not an option, so the user has probably given explicit - # arguments. - ac_option=$1 - ac_need_defaults=false;; esac case $ac_option in # Handling of the options. -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; - --version | --vers* | -V ) - echo "$ac_cs_version"; exit 0 ;; - --he | --h) - # Conflict between --help and --header - { { echo "$as_me:$LINENO: error: ambiguous option: $1 -Try \`$0 --help' for more information." >&5 -echo "$as_me: error: ambiguous option: $1 -Try \`$0 --help' for more information." >&2;} - { (exit 1); exit 1; }; };; - --help | --hel | -h ) - echo "$ac_cs_usage"; exit 0 ;; - --debug | --d* | -d ) + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + $as_echo "$ac_cs_version"; exit ;; + --config | --confi | --conf | --con | --co | --c ) + $as_echo "$ac_cs_config"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift - CONFIG_FILES="$CONFIG_FILES $ac_optarg" - ac_need_defaults=false;; - --header | --heade | --head | --hea ) - $ac_shift - CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg" + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + '') as_fn_error $? "missing file argument" ;; + esac + as_fn_append CONFIG_FILES " '$ac_optarg'" ac_need_defaults=false;; + --he | --h | --help | --hel | -h ) + $as_echo "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. - -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1 -Try \`$0 --help' for more information." >&5 -echo "$as_me: error: unrecognized option: $1 -Try \`$0 --help' for more information." >&2;} - { (exit 1); exit 1; }; } ;; + -*) as_fn_error $? "unrecognized option: \`$1' +Try \`$0 --help' for more information." ;; - *) ac_config_targets="$ac_config_targets $1" ;; + *) as_fn_append ac_config_targets " $1" + ac_need_defaults=false ;; esac shift @@ -19820,43 +11185,55 @@ if $ac_cs_silent; then fi _ACEOF -cat >>$CONFIG_STATUS <<_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then - echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6 - exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + shift + \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 + CONFIG_SHELL='$SHELL' + export CONFIG_SHELL + exec "\$@" fi _ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + $as_echo "$ac_log" +} >&5 -cat >>$CONFIG_STATUS <<_ACEOF +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # -# INIT-COMMANDS section. +# INIT-COMMANDS # - VERSION=${TCL_VERSION} _ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 - -cat >>$CONFIG_STATUS <<\_ACEOF +# Handling of arguments. for ac_config_target in $ac_config_targets do - case "$ac_config_target" in - # Handling of arguments. - "Tcl-Info.plist" ) CONFIG_FILES="$CONFIG_FILES Tcl-Info.plist:../macosx/Tcl-Info.plist.in" ;; - "Tclsh-Info.plist" ) CONFIG_FILES="$CONFIG_FILES Tclsh-Info.plist:../macosx/Tclsh-Info.plist.in" ;; - "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile:../unix/Makefile.in" ;; - "dltest/Makefile" ) CONFIG_FILES="$CONFIG_FILES dltest/Makefile:../unix/dltest/Makefile.in" ;; - "tclConfig.sh" ) CONFIG_FILES="$CONFIG_FILES tclConfig.sh:../unix/tclConfig.sh.in" ;; - "tcl.pc" ) CONFIG_FILES="$CONFIG_FILES tcl.pc:../unix/tcl.pc.in" ;; - "Tcl.framework" ) CONFIG_COMMANDS="$CONFIG_COMMANDS Tcl.framework" ;; - *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 -echo "$as_me: error: invalid argument: $ac_config_target" >&2;} - { (exit 1); exit 1; }; };; + case $ac_config_target in + "Tcl-Info.plist") CONFIG_FILES="$CONFIG_FILES Tcl-Info.plist:../macosx/Tcl-Info.plist.in" ;; + "Tclsh-Info.plist") CONFIG_FILES="$CONFIG_FILES Tclsh-Info.plist:../macosx/Tclsh-Info.plist.in" ;; + "Tcl.framework") CONFIG_COMMANDS="$CONFIG_COMMANDS Tcl.framework" ;; + "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile:../unix/Makefile.in" ;; + "dltest/Makefile") CONFIG_FILES="$CONFIG_FILES dltest/Makefile:../unix/dltest/Makefile.in" ;; + "tclConfig.sh") CONFIG_FILES="$CONFIG_FILES tclConfig.sh:../unix/tclConfig.sh.in" ;; + "tcl.pc") CONFIG_FILES="$CONFIG_FILES tcl.pc:../unix/tcl.pc.in" ;; + + *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac done + # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely @@ -19867,533 +11244,427 @@ if $ac_need_defaults; then fi # Have a temporary directory for convenience. Make it in the build tree -# simply because there is no reason to put it here, and in addition, +# simply because there is no reason against having it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. -# Create a temporary directory, and hook for its removal unless debugging. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. $debug || { - trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0 - trap '{ (exit 1); exit 1; }' 1 2 13 15 + tmp= ac_tmp= + trap 'exit_status=$? + : "${ac_tmp:=$tmp}" + { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status +' 0 + trap 'as_fn_exit 1' 1 2 13 15 } - # Create a (secure) tmp directory for tmp files. { - tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` && - test -n "$tmp" && test -d "$tmp" + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -d "$tmp" } || { - tmp=./confstat$$-$RANDOM - (umask 077 && mkdir $tmp) -} || + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 +ac_tmp=$tmp + +# Set up the scripts for CONFIG_FILES section. +# No need to generate them if there are no CONFIG_FILES. +# This happens for instance with `./config.status config.h'. +if test -n "$CONFIG_FILES"; then + + +ac_cr=`echo X | tr X '\015'` +# On cygwin, bash can eat \r inside `` if the user requested igncr. +# But we know of no other shell where ac_cr would be empty at this +# point, so we can use a bashism as a fallback. +if test "x$ac_cr" = x; then + eval ac_cr=\$\'\\r\' +fi +ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` +if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then + ac_cs_awk_cr='\\r' +else + ac_cs_awk_cr=$ac_cr +fi + +echo 'BEGIN {' >"$ac_tmp/subs1.awk" && +_ACEOF + + { - echo "$me: cannot create a temporary directory in ." >&2 - { (exit 1); exit 1; } + echo "cat >conf$$subs.awk <<_ACEOF" && + echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && + echo "_ACEOF" +} >conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 +ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + . ./conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + + ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` + if test $ac_delim_n = $ac_delim_num; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done +rm -f conf$$subs.sh + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && +_ACEOF +sed -n ' +h +s/^/S["/; s/!.*/"]=/ +p +g +s/^[^!]*!// +:repl +t repl +s/'"$ac_delim"'$// +t delim +:nl +h +s/\(.\{148\}\)..*/\1/ +t more1 +s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ +p +n +b repl +:more1 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t nl +:delim +h +s/\(.\{148\}\)..*/\1/ +t more2 +s/["\\]/\\&/g; s/^/"/; s/$/"/ +p +b +:more2 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t delim +' >$CONFIG_STATUS || ac_write_fail=1 +rm -f conf$$subs.awk +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +_ACAWK +cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && + for (key in S) S_is_set[key] = 1 + FS = "" + +} +{ + line = $ 0 + nfields = split(line, field, "@") + substed = 0 + len = length(field[1]) + for (i = 2; i < nfields; i++) { + key = field[i] + keylen = length(key) + if (S_is_set[key]) { + value = S[key] + line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) + len += length(value) + length(field[++i]) + substed = 1 + } else + len += 1 + keylen + } + + print line } +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then + sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" +else + cat +fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ + || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 _ACEOF -cat >>$CONFIG_STATUS <<_ACEOF +# VPATH may cause trouble with some makes, so we remove sole $(srcdir), +# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ +h +s/// +s/^/:/ +s/[ ]*$/:/ +s/:\$(srcdir):/:/g +s/:\${srcdir}:/:/g +s/:@srcdir@:/:/g +s/^:*// +s/:*$// +x +s/\(=[ ]*\).*/\1/ +G +s/\n// +s/^[^=]*=[ ]*$// +}' +fi -# -# CONFIG_FILES section. -# +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +fi # test -n "$CONFIG_FILES" -# No need to generate the scripts if there are no CONFIG_FILES. -# This happens for instance when ./config.status config.h -if test -n "\$CONFIG_FILES"; then - # Protect against being on the right side of a sed subst in config.status. - sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g; - s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF -s,@SHELL@,$SHELL,;t t -s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t -s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t -s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t -s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t -s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t -s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t -s,@exec_prefix@,$exec_prefix,;t t -s,@prefix@,$prefix,;t t -s,@program_transform_name@,$program_transform_name,;t t -s,@bindir@,$bindir,;t t -s,@sbindir@,$sbindir,;t t -s,@libexecdir@,$libexecdir,;t t -s,@datadir@,$datadir,;t t -s,@sysconfdir@,$sysconfdir,;t t -s,@sharedstatedir@,$sharedstatedir,;t t -s,@localstatedir@,$localstatedir,;t t -s,@libdir@,$libdir,;t t -s,@includedir@,$includedir,;t t -s,@oldincludedir@,$oldincludedir,;t t -s,@infodir@,$infodir,;t t -s,@mandir@,$mandir,;t t -s,@build_alias@,$build_alias,;t t -s,@host_alias@,$host_alias,;t t -s,@target_alias@,$target_alias,;t t -s,@DEFS@,$DEFS,;t t -s,@ECHO_C@,$ECHO_C,;t t -s,@ECHO_N@,$ECHO_N,;t t -s,@ECHO_T@,$ECHO_T,;t t -s,@LIBS@,$LIBS,;t t -s,@MAN_FLAGS@,$MAN_FLAGS,;t t -s,@CC@,$CC,;t t -s,@CFLAGS@,$CFLAGS,;t t -s,@LDFLAGS@,$LDFLAGS,;t t -s,@CPPFLAGS@,$CPPFLAGS,;t t -s,@ac_ct_CC@,$ac_ct_CC,;t t -s,@EXEEXT@,$EXEEXT,;t t -s,@OBJEXT@,$OBJEXT,;t t -s,@CPP@,$CPP,;t t -s,@EGREP@,$EGREP,;t t -s,@TCL_THREADS@,$TCL_THREADS,;t t -s,@TCLSH_PROG@,$TCLSH_PROG,;t t -s,@ZLIB_OBJS@,$ZLIB_OBJS,;t t -s,@ZLIB_SRCS@,$ZLIB_SRCS,;t t -s,@ZLIB_INCLUDE@,$ZLIB_INCLUDE,;t t -s,@RANLIB@,$RANLIB,;t t -s,@ac_ct_RANLIB@,$ac_ct_RANLIB,;t t -s,@AR@,$AR,;t t -s,@ac_ct_AR@,$ac_ct_AR,;t t -s,@LIBOBJS@,$LIBOBJS,;t t -s,@TCL_LIBS@,$TCL_LIBS,;t t -s,@DL_LIBS@,$DL_LIBS,;t t -s,@DL_OBJS@,$DL_OBJS,;t t -s,@PLAT_OBJS@,$PLAT_OBJS,;t t -s,@PLAT_SRCS@,$PLAT_SRCS,;t t -s,@LDAIX_SRC@,$LDAIX_SRC,;t t -s,@CFLAGS_DEBUG@,$CFLAGS_DEBUG,;t t -s,@CFLAGS_OPTIMIZE@,$CFLAGS_OPTIMIZE,;t t -s,@CFLAGS_WARNING@,$CFLAGS_WARNING,;t t -s,@LDFLAGS_DEBUG@,$LDFLAGS_DEBUG,;t t -s,@LDFLAGS_OPTIMIZE@,$LDFLAGS_OPTIMIZE,;t t -s,@CC_SEARCH_FLAGS@,$CC_SEARCH_FLAGS,;t t -s,@LD_SEARCH_FLAGS@,$LD_SEARCH_FLAGS,;t t -s,@STLIB_LD@,$STLIB_LD,;t t -s,@SHLIB_LD@,$SHLIB_LD,;t t -s,@TCL_SHLIB_LD_EXTRAS@,$TCL_SHLIB_LD_EXTRAS,;t t -s,@TK_SHLIB_LD_EXTRAS@,$TK_SHLIB_LD_EXTRAS,;t t -s,@SHLIB_LD_LIBS@,$SHLIB_LD_LIBS,;t t -s,@SHLIB_CFLAGS@,$SHLIB_CFLAGS,;t t -s,@SHLIB_SUFFIX@,$SHLIB_SUFFIX,;t t -s,@MAKE_LIB@,$MAKE_LIB,;t t -s,@MAKE_STUB_LIB@,$MAKE_STUB_LIB,;t t -s,@INSTALL_LIB@,$INSTALL_LIB,;t t -s,@DLL_INSTALL_DIR@,$DLL_INSTALL_DIR,;t t -s,@INSTALL_STUB_LIB@,$INSTALL_STUB_LIB,;t t -s,@CFLAGS_DEFAULT@,$CFLAGS_DEFAULT,;t t -s,@LDFLAGS_DEFAULT@,$LDFLAGS_DEFAULT,;t t -s,@DTRACE@,$DTRACE,;t t -s,@TCL_VERSION@,$TCL_VERSION,;t t -s,@TCL_MAJOR_VERSION@,$TCL_MAJOR_VERSION,;t t -s,@TCL_MINOR_VERSION@,$TCL_MINOR_VERSION,;t t -s,@TCL_PATCH_LEVEL@,$TCL_PATCH_LEVEL,;t t -s,@TCL_YEAR@,$TCL_YEAR,;t t -s,@PKG_CFG_ARGS@,$PKG_CFG_ARGS,;t t -s,@TCL_LIB_FILE@,$TCL_LIB_FILE,;t t -s,@TCL_LIB_FLAG@,$TCL_LIB_FLAG,;t t -s,@TCL_LIB_SPEC@,$TCL_LIB_SPEC,;t t -s,@TCL_STUB_LIB_FILE@,$TCL_STUB_LIB_FILE,;t t -s,@TCL_STUB_LIB_FLAG@,$TCL_STUB_LIB_FLAG,;t t -s,@TCL_STUB_LIB_SPEC@,$TCL_STUB_LIB_SPEC,;t t -s,@TCL_STUB_LIB_PATH@,$TCL_STUB_LIB_PATH,;t t -s,@TCL_INCLUDE_SPEC@,$TCL_INCLUDE_SPEC,;t t -s,@TCL_BUILD_STUB_LIB_SPEC@,$TCL_BUILD_STUB_LIB_SPEC,;t t -s,@TCL_BUILD_STUB_LIB_PATH@,$TCL_BUILD_STUB_LIB_PATH,;t t -s,@TCL_SRC_DIR@,$TCL_SRC_DIR,;t t -s,@CFG_TCL_SHARED_LIB_SUFFIX@,$CFG_TCL_SHARED_LIB_SUFFIX,;t t -s,@CFG_TCL_UNSHARED_LIB_SUFFIX@,$CFG_TCL_UNSHARED_LIB_SUFFIX,;t t -s,@TCL_SHARED_BUILD@,$TCL_SHARED_BUILD,;t t -s,@LD_LIBRARY_PATH_VAR@,$LD_LIBRARY_PATH_VAR,;t t -s,@TCL_BUILD_LIB_SPEC@,$TCL_BUILD_LIB_SPEC,;t t -s,@TCL_LIB_VERSIONS_OK@,$TCL_LIB_VERSIONS_OK,;t t -s,@TCL_SHARED_LIB_SUFFIX@,$TCL_SHARED_LIB_SUFFIX,;t t -s,@TCL_UNSHARED_LIB_SUFFIX@,$TCL_UNSHARED_LIB_SUFFIX,;t t -s,@TCL_HAS_LONGLONG@,$TCL_HAS_LONGLONG,;t t -s,@INSTALL_TZDATA@,$INSTALL_TZDATA,;t t -s,@DTRACE_SRC@,$DTRACE_SRC,;t t -s,@DTRACE_HDR@,$DTRACE_HDR,;t t -s,@DTRACE_OBJ@,$DTRACE_OBJ,;t t -s,@MAKEFILE_SHELL@,$MAKEFILE_SHELL,;t t -s,@BUILD_DLTEST@,$BUILD_DLTEST,;t t -s,@TCL_PACKAGE_PATH@,$TCL_PACKAGE_PATH,;t t -s,@TCL_MODULE_PATH@,$TCL_MODULE_PATH,;t t -s,@TCL_LIBRARY@,$TCL_LIBRARY,;t t -s,@PRIVATE_INCLUDE_DIR@,$PRIVATE_INCLUDE_DIR,;t t -s,@HTML_DIR@,$HTML_DIR,;t t -s,@PACKAGE_DIR@,$PACKAGE_DIR,;t t -s,@EXTRA_CC_SWITCHES@,$EXTRA_CC_SWITCHES,;t t -s,@EXTRA_APP_CC_SWITCHES@,$EXTRA_APP_CC_SWITCHES,;t t -s,@EXTRA_INSTALL@,$EXTRA_INSTALL,;t t -s,@EXTRA_INSTALL_BINARIES@,$EXTRA_INSTALL_BINARIES,;t t -s,@EXTRA_BUILD_HTML@,$EXTRA_BUILD_HTML,;t t -s,@EXTRA_TCLSH_LIBS@,$EXTRA_TCLSH_LIBS,;t t -s,@DLTEST_LD@,$DLTEST_LD,;t t -s,@DLTEST_SUFFIX@,$DLTEST_SUFFIX,;t t -CEOF -_ACEOF +eval set X " :F $CONFIG_FILES :C $CONFIG_COMMANDS" +shift +for ac_tag +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift - cat >>$CONFIG_STATUS <<\_ACEOF - # Split the substitutions into bite-sized pieces for seds with - # small command number limits, like on Digital OSF/1 and HP-UX. - ac_max_sed_lines=48 - ac_sed_frag=1 # Number of current file. - ac_beg=1 # First line for current file. - ac_end=$ac_max_sed_lines # Line after last line for current file. - ac_more_lines=: - ac_sed_cmds= - while $ac_more_lines; do - if test $ac_beg -gt 1; then - sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag - else - sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag - fi - if test ! -s $tmp/subs.frag; then - ac_more_lines=false - else - # The purpose of the label and of the branching condition is to - # speed up the sed processing (if there are no `@' at all, there - # is no need to browse any of the substitutions). - # These are the two extra sed commands mentioned above. - (echo ':t - /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed - if test -z "$ac_sed_cmds"; then - ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed" - else - ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed" - fi - ac_sed_frag=`expr $ac_sed_frag + 1` - ac_beg=$ac_end - ac_end=`expr $ac_end + $ac_max_sed_lines` + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$ac_tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; + esac + case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac + as_fn_append ac_file_inputs " '$ac_f'" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input='Generated from '` + $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' + `' by configure.' + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 +$as_echo "$as_me: creating $ac_file" >&6;} fi - done - if test -z "$ac_sed_cmds"; then - ac_sed_cmds=cat - fi -fi # test -n "$CONFIG_FILES" + # Neutralize special characters interpreted by sed in replacement strings. + case $configure_input in #( + *\&* | *\|* | *\\* ) + ac_sed_conf_input=`$as_echo "$configure_input" | + sed 's/[\\\\&|]/\\\\&/g'`;; #( + *) ac_sed_conf_input=$configure_input;; + esac -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF -for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue - # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". - case $ac_file in - - | *:- | *:-:* ) # input from stdin - cat >$tmp/stdin - ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` - ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; - *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` - ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; - * ) ac_file_in=$ac_file.in ;; + case $ac_tag in + *:-:* | *:-) cat >"$ac_tmp/stdin" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; + esac + ;; esac - # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories. - ac_dir=`(dirname "$ac_file") 2>/dev/null || + ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ - X"$ac_file" : 'X\(/\)' \| \ - . : '\(.\)' 2>/dev/null || -echo X"$ac_file" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } - /^X\(\/\/\)[^/].*/{ s//\1/; q; } - /^X\(\/\/\)$/{ s//\1/; q; } - /^X\(\/\).*/{ s//\1/; q; } - s/.*/./; q'` - { if $as_mkdir_p; then - mkdir -p "$ac_dir" - else - as_dir="$ac_dir" - as_dirs= - while test ! -d "$as_dir"; do - as_dirs="$as_dir $as_dirs" - as_dir=`(dirname "$as_dir") 2>/dev/null || -$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$as_dir" : 'X\(//\)[^/]' \| \ - X"$as_dir" : 'X\(//\)$' \| \ - X"$as_dir" : 'X\(/\)' \| \ - . : '\(.\)' 2>/dev/null || -echo X"$as_dir" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } - /^X\(\/\/\)[^/].*/{ s//\1/; q; } - /^X\(\/\/\)$/{ s//\1/; q; } - /^X\(\/\).*/{ s//\1/; q; } - s/.*/./; q'` - done - test ! -n "$as_dirs" || mkdir $as_dirs - fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 -echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} - { (exit 1); exit 1; }; }; } - + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir="$ac_dir"; as_fn_mkdir_p ac_builddir=. -if test "$ac_dir" != .; then - ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` - # A "../" for each directory in $ac_dir_suffix. - ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` -else - ac_dir_suffix= ac_top_builddir= -fi +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix case $srcdir in - .) # No --srcdir option. We are building in place. + .) # We are building in place. ac_srcdir=. - if test -z "$ac_top_builddir"; then - ac_top_srcdir=. - else - ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` - fi ;; - [\\/]* | ?:[\\/]* ) # Absolute path. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; - ac_top_srcdir=$srcdir ;; - *) # Relative path. - ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix - ac_top_srcdir=$ac_top_builddir$srcdir ;; -esac - -# Do not use `cd foo && pwd` to compute absolute paths, because -# the directories may not exist. -case `pwd` in -.) ac_abs_builddir="$ac_dir";; -*) - case "$ac_dir" in - .) ac_abs_builddir=`pwd`;; - [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; - *) ac_abs_builddir=`pwd`/"$ac_dir";; - esac;; -esac -case $ac_abs_builddir in -.) ac_abs_top_builddir=${ac_top_builddir}.;; -*) - case ${ac_top_builddir}. in - .) ac_abs_top_builddir=$ac_abs_builddir;; - [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; - *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; - esac;; -esac -case $ac_abs_builddir in -.) ac_abs_srcdir=$ac_srcdir;; -*) - case $ac_srcdir in - .) ac_abs_srcdir=$ac_abs_builddir;; - [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; - *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; - esac;; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac -case $ac_abs_builddir in -.) ac_abs_top_srcdir=$ac_top_srcdir;; -*) - case $ac_top_srcdir in - .) ac_abs_top_srcdir=$ac_abs_builddir;; - [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; - *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; - esac;; +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= +ac_sed_dataroot=' +/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p' +case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + ac_datarootdir_hack=' + s&@datadir@&$datadir&g + s&@docdir@&$docdir&g + s&@infodir@&$infodir&g + s&@localedir@&$localedir&g + s&@mandir@&$mandir&g + s&\\\${datarootdir}&$datarootdir&g' ;; esac - - - - if test x"$ac_file" != x-; then - { echo "$as_me:$LINENO: creating $ac_file" >&5 -echo "$as_me: creating $ac_file" >&6;} - rm -f "$ac_file" - fi - # Let's still pretend it is `configure' which instantiates (i.e., don't - # use $as_me), people would be surprised to read: - # /* config.h. Generated by config.status. */ - if test x"$ac_file" = x-; then - configure_input= - else - configure_input="$ac_file. " - fi - configure_input=$configure_input"Generated from `echo $ac_file_in | - sed 's,.*/,,'` by configure." - - # First look for the input files in the build tree, otherwise in the - # src tree. - ac_file_inputs=`IFS=: - for f in $ac_file_in; do - case $f in - -) echo $tmp/stdin ;; - [\\/$]*) - # Absolute (can't be DOS-style, as IFS=:) - test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 -echo "$as_me: error: cannot find input file: $f" >&2;} - { (exit 1); exit 1; }; } - echo "$f";; - *) # Relative - if test -f "$f"; then - # Build tree - echo "$f" - elif test -f "$srcdir/$f"; then - # Source tree - echo "$srcdir/$f" - else - # /dev/null tree - { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 -echo "$as_me: error: cannot find input file: $f" >&2;} - { (exit 1); exit 1; }; } - fi;; - esac - done` || { (exit 1); exit 1; } _ACEOF -cat >>$CONFIG_STATUS <<_ACEOF - sed "$ac_vpsub + +# Neutralize VPATH when `$srcdir' = `.'. +# Shell code in configure.ac might set extrasub. +# FIXME: do we really want to maintain this feature? +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_sed_extra="$ac_vpsub $extrasub _ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b -s,@configure_input@,$configure_input,;t t -s,@srcdir@,$ac_srcdir,;t t -s,@abs_srcdir@,$ac_abs_srcdir,;t t -s,@top_srcdir@,$ac_top_srcdir,;t t -s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t -s,@builddir@,$ac_builddir,;t t -s,@abs_builddir@,$ac_abs_builddir,;t t -s,@top_builddir@,$ac_top_builddir,;t t -s,@abs_top_builddir@,$ac_abs_top_builddir,;t t -" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out - rm -f $tmp/stdin - if test x"$ac_file" != x-; then - mv $tmp/out $ac_file - else - cat $tmp/out - rm -f $tmp/out - fi - -done -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF - -# -# CONFIG_COMMANDS section. -# -for ac_file in : $CONFIG_COMMANDS; do test "x$ac_file" = x: && continue - ac_dest=`echo "$ac_file" | sed 's,:.*,,'` - ac_source=`echo "$ac_file" | sed 's,[^:]*:,,'` - ac_dir=`(dirname "$ac_dest") 2>/dev/null || -$as_expr X"$ac_dest" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$ac_dest" : 'X\(//\)[^/]' \| \ - X"$ac_dest" : 'X\(//\)$' \| \ - X"$ac_dest" : 'X\(/\)' \| \ - . : '\(.\)' 2>/dev/null || -echo X"$ac_dest" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } - /^X\(\/\/\)[^/].*/{ s//\1/; q; } - /^X\(\/\/\)$/{ s//\1/; q; } - /^X\(\/\).*/{ s//\1/; q; } - s/.*/./; q'` - { if $as_mkdir_p; then - mkdir -p "$ac_dir" - else - as_dir="$ac_dir" - as_dirs= - while test ! -d "$as_dir"; do - as_dirs="$as_dir $as_dirs" - as_dir=`(dirname "$as_dir") 2>/dev/null || -$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$as_dir" : 'X\(//\)[^/]' \| \ - X"$as_dir" : 'X\(//\)$' \| \ - X"$as_dir" : 'X\(/\)' \| \ - . : '\(.\)' 2>/dev/null || -echo X"$as_dir" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } - /^X\(\/\/\)[^/].*/{ s//\1/; q; } - /^X\(\/\/\)$/{ s//\1/; q; } - /^X\(\/\).*/{ s//\1/; q; } - s/.*/./; q'` - done - test ! -n "$as_dirs" || mkdir $as_dirs - fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 -echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} - { (exit 1); exit 1; }; }; } - - ac_builddir=. - -if test "$ac_dir" != .; then - ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` - # A "../" for each directory in $ac_dir_suffix. - ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` -else - ac_dir_suffix= ac_top_builddir= -fi +s|@configure_input@|$ac_sed_conf_input|;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@top_build_prefix@&$ac_top_build_prefix&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +$ac_datarootdir_hack +" +eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ + >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ + "$ac_tmp/out"`; test -z "$ac_out"; } && + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&5 +$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&2;} + + rm -f "$ac_tmp/stdin" + case $ac_file in + -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; + *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; + esac \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + ;; -case $srcdir in - .) # No --srcdir option. We are building in place. - ac_srcdir=. - if test -z "$ac_top_builddir"; then - ac_top_srcdir=. - else - ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` - fi ;; - [\\/]* | ?:[\\/]* ) # Absolute path. - ac_srcdir=$srcdir$ac_dir_suffix; - ac_top_srcdir=$srcdir ;; - *) # Relative path. - ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix - ac_top_srcdir=$ac_top_builddir$srcdir ;; -esac -# Do not use `cd foo && pwd` to compute absolute paths, because -# the directories may not exist. -case `pwd` in -.) ac_abs_builddir="$ac_dir";; -*) - case "$ac_dir" in - .) ac_abs_builddir=`pwd`;; - [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; - *) ac_abs_builddir=`pwd`/"$ac_dir";; - esac;; -esac -case $ac_abs_builddir in -.) ac_abs_top_builddir=${ac_top_builddir}.;; -*) - case ${ac_top_builddir}. in - .) ac_abs_top_builddir=$ac_abs_builddir;; - [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; - *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; - esac;; -esac -case $ac_abs_builddir in -.) ac_abs_srcdir=$ac_srcdir;; -*) - case $ac_srcdir in - .) ac_abs_srcdir=$ac_abs_builddir;; - [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; - *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; - esac;; -esac -case $ac_abs_builddir in -.) ac_abs_top_srcdir=$ac_top_srcdir;; -*) - case $ac_top_srcdir in - .) ac_abs_top_srcdir=$ac_abs_builddir;; - [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; - *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; - esac;; -esac + :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 +$as_echo "$as_me: executing $ac_file commands" >&6;} + ;; + esac - { echo "$as_me:$LINENO: executing $ac_dest commands" >&5 -echo "$as_me: executing $ac_dest commands" >&6;} - case $ac_dest in - Tcl.framework ) n=Tcl && + case $ac_file$ac_mode in + "Tcl.framework":C) n=Tcl && f=$n.framework && v=Versions/$VERSION && rm -rf $f && mkdir -p $f/$v/Resources && ln -s $v/$n $v/Resources $f && ln -s ../../../$n $f/$v && ln -s ../../../../$n-Info.plist $f/$v/Resources/Info.plist && unset n f v ;; + esac -done -_ACEOF +done # for ac_tag -cat >>$CONFIG_STATUS <<\_ACEOF -{ (exit 0); exit 0; } +as_fn_exit 0 _ACEOF -chmod +x $CONFIG_STATUS ac_clean_files=$ac_clean_files_save +test $ac_write_fail = 0 || + as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 + # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. @@ -20413,7 +11684,11 @@ if test "$no_create" != yes; then exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. - $ac_cs_success || { (exit 1); exit 1; } + $ac_cs_success || as_fn_exit 1 +fi +if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 +$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi diff --git a/unix/configure.in b/unix/configure.in index 85bd7ee..7a15fb7 100644 --- a/unix/configure.in +++ b/unix/configure.in @@ -793,6 +793,10 @@ eval "TCL_LIB_FILE=libtcl${LIB_SUFFIX}" eval "TCL_LIB_FILE=${TCL_LIB_FILE}" +eval "TCL_KIT_LIB_FILE=libtclkit${UNSHARED_LIB_SUFFIX}" +eval "TCL_KIT_LIB_FILE=${TCL_KIT_LIB_FILE}" + + TCL_LIBRARY='$(prefix)/lib/tcl$(VERSION)' PRIVATE_INCLUDE_DIR='$(includedir)' HTML_DIR='$(DISTDIR)/html' @@ -937,6 +941,7 @@ AC_SUBST(TCL_STUB_LIB_FILE) AC_SUBST(TCL_STUB_LIB_FLAG) AC_SUBST(TCL_STUB_LIB_SPEC) AC_SUBST(TCL_STUB_LIB_PATH) +AC_SUBST(TCL_KIT_LIB_FILE) AC_SUBST(TCL_INCLUDE_SPEC) AC_SUBST(TCL_BUILD_STUB_LIB_SPEC) AC_SUBST(TCL_BUILD_STUB_LIB_PATH) diff --git a/unix/tcl.m4 b/unix/tcl.m4 index 3ca65d8..88f2b81 100644 --- a/unix/tcl.m4 +++ b/unix/tcl.m4 @@ -2060,6 +2060,14 @@ dnl # preprocessing tests use only CPPFLAGS. ]) ]) + AS_IF([test "$RANLIB" = ""], [ + MAKE_KIT_LIB='$(STLIB_LD) [$]@ ${TCL_OBJS} ${TOMMATH_OBJS} ${ZLIB_OBJS}' + INSTALL_KIT_LIB='$(INSTALL_LIBRARY) $(TCL_KIT_LIB_FILE) "$(LIB_INSTALL_DIR)/$(TCL_KIT_LIB_FILE)"' + ], [ + MAKE_KIT_LIB='${STLIB_LD} [$]@ ${TCL_OBJS} ${TOMMATH_OBJS} ${ZLIB_OBJS} ; ${RANLIB} [$]@' + INSTALL_KIT_LIB='$(INSTALL_LIBRARY) $(TCL_KIT_LIB_FILE) "$(LIB_INSTALL_DIR)/$(TCL_KIT_LIB_FILE)" ; (cd "$(LIB_INSTALL_DIR)" ; $(RANLIB) $(TCL_KIT_LIB_FILE))' + ]) + # Stub lib does not depend on shared/static configuration AS_IF([test "$RANLIB" = ""], [ MAKE_STUB_LIB='${STLIB_LD} [$]@ ${STUB_LIB_OBJS}' @@ -2126,10 +2134,12 @@ dnl # preprocessing tests use only CPPFLAGS. [What is the default extension for shared libraries?]) AC_SUBST(MAKE_LIB) + AC_SUBST(MAKE_KIT_LIB) AC_SUBST(MAKE_STUB_LIB) AC_SUBST(INSTALL_LIB) AC_SUBST(DLL_INSTALL_DIR) AC_SUBST(INSTALL_STUB_LIB) + AC_SUBST(INSTALL_KIT_LIB) AC_SUBST(RANLIB) ]) -- cgit v0.12 From ab35383fda8fe297152230b0f3778eb992d015d7 Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Tue, 9 Sep 2014 13:59:09 +0000 Subject: Add Static library link instructions to tclConfig.sh --- unix/Makefile.in | 6 ------ unix/configure | 46 +++++++++++++++++++++++++++++++++++++++------- unix/configure.in | 41 ++++++++++++++++++++++++++++++++++------- unix/tclConfig.sh.in | 28 ++++++++++++++++++++++++++++ 4 files changed, 101 insertions(+), 20 deletions(-) diff --git a/unix/Makefile.in b/unix/Makefile.in index 7d9b82d..c66cc0a 100644 --- a/unix/Makefile.in +++ b/unix/Makefile.in @@ -649,12 +649,6 @@ ${TCL_KIT_LIB_FILE}: ${TCL_OBJS} ${TOMMATH_OBJS} ${ZLIB_OBJS} rm -f $@ @MAKE_KIT_LIB@ - #${SHLIB_LD} $@ ${TCL_OBJS} ${TOMMATH_OBJS} ${ZLIB_OBJS} ; ${RANLIB} $@ - #${CC} ${CFLAGS} ${LDFLAGS} \ - # ${TCL_OBJS} ${TOMMATH_OBJS} ${ZLIB_OBJS} \ - # ${CC_SEARCH_FLAGS} -o ${TCL_KIT_LIB_FILE} - - # Make target which outputs the list of the .o contained in the Tcl lib useful # to build a single big shared library containing Tcl and other extensions. # Used for the Tcl Plugin. -- dl diff --git a/unix/configure b/unix/configure index 2740498..a5f318e 100755 --- a/unix/configure +++ b/unix/configure @@ -642,20 +642,25 @@ TCL_HAS_LONGLONG TCL_UNSHARED_LIB_SUFFIX TCL_SHARED_LIB_SUFFIX TCL_LIB_VERSIONS_OK -TCL_BUILD_LIB_SPEC LD_LIBRARY_PATH_VAR TCL_SHARED_BUILD CFG_TCL_UNSHARED_LIB_SUFFIX CFG_TCL_SHARED_LIB_SUFFIX TCL_SRC_DIR -TCL_BUILD_STUB_LIB_PATH -TCL_BUILD_STUB_LIB_SPEC TCL_INCLUDE_SPEC +TCL_BUILD_KIT_LIB_PATH +TCL_BUILD_KIT_LIB_SPEC +TCL_KIT_LIB_PATH +TCL_KIT_LIB_SPEC +TCL_KIT_LIB_FLAG TCL_KIT_LIB_FILE +TCL_BUILD_STUB_LIB_PATH +TCL_BUILD_STUB_LIB_SPEC TCL_STUB_LIB_PATH TCL_STUB_LIB_SPEC TCL_STUB_LIB_FLAG TCL_STUB_LIB_FILE +TCL_BUILD_LIB_SPEC TCL_LIB_SPEC TCL_LIB_FLAG TCL_LIB_FILE @@ -10288,10 +10293,6 @@ eval "TCL_LIB_FILE=libtcl${LIB_SUFFIX}" eval "TCL_LIB_FILE=${TCL_LIB_FILE}" -eval "TCL_KIT_LIB_FILE=libtclkit${UNSHARED_LIB_SUFFIX}" -eval "TCL_KIT_LIB_FILE=${TCL_KIT_LIB_FILE}" - - TCL_LIBRARY='$(prefix)/lib/tcl$(VERSION)' PRIVATE_INCLUDE_DIR='$(includedir)' HTML_DIR='$(DISTDIR)/html' @@ -10428,6 +10429,29 @@ fi #-------------------------------------------------------------------- # The statements below define various symbols relating to Tcl +# core vfs and kit support. +#-------------------------------------------------------------------- + +eval "TCL_KIT_LIB_FILE=libtclkit${UNSHARED_LIB_SUFFIX}" +eval "TCL_KIT_LIB_FILE=${TCL_KIT_LIB_FILE}" + +eval "TCL_KIT_LIB_FILE=libtclkit${TCL_UNSHARED_LIB_SUFFIX}" +eval "TCL_KIT_LIB_FILE=\"${TCL_KIT_LIB_FILE}\"" +eval "TCL_KIT_LIB_DIR=${libdir}" + +if test "${TCL_LIB_VERSIONS_OK}" = "ok"; then + TCL_KIT_LIB_FLAG="-ltclkit${TCL_VERSION}" +else + TCL_KIT_LIB_FLAG="-ltclkit`echo ${TCL_VERSION} | tr -d .`" +fi + +TCL_BUILD_KIT_LIB_SPEC="-L`pwd | sed -e 's/ /\\\\ /g'` ${TCL_KIT_LIB_FLAG}" +TCL_KIT_LIB_SPEC="-L${TCL_KIT_LIB_DIR} ${TCL_KIT_LIB_FLAG}" +TCL_BUILD_KIT_LIB_PATH="`pwd`/${TCL_KIT_LIB_FILE}" +TCL_KIT_LIB_PATH="${TCL_KIT_LIB_DIR}/${TCL_KIT_LIB_FILE}" + +#-------------------------------------------------------------------- +# The statements below define various symbols relating to Tcl # stub support. #-------------------------------------------------------------------- @@ -10519,6 +10543,14 @@ TCL_SHARED_BUILD=${SHARED_BUILD} + + + + + + + + ac_config_files="$ac_config_files Makefile:../unix/Makefile.in dltest/Makefile:../unix/dltest/Makefile.in tclConfig.sh:../unix/tclConfig.sh.in tcl.pc:../unix/tcl.pc.in" cat >confcache <<\_ACEOF diff --git a/unix/configure.in b/unix/configure.in index 7a15fb7..bc7bdef 100644 --- a/unix/configure.in +++ b/unix/configure.in @@ -793,10 +793,6 @@ eval "TCL_LIB_FILE=libtcl${LIB_SUFFIX}" eval "TCL_LIB_FILE=${TCL_LIB_FILE}" -eval "TCL_KIT_LIB_FILE=libtclkit${UNSHARED_LIB_SUFFIX}" -eval "TCL_KIT_LIB_FILE=${TCL_KIT_LIB_FILE}" - - TCL_LIBRARY='$(prefix)/lib/tcl$(VERSION)' PRIVATE_INCLUDE_DIR='$(includedir)' HTML_DIR='$(DISTDIR)/html' @@ -897,6 +893,29 @@ fi #-------------------------------------------------------------------- # The statements below define various symbols relating to Tcl +# core vfs and kit support. +#-------------------------------------------------------------------- + +eval "TCL_KIT_LIB_FILE=libtclkit${UNSHARED_LIB_SUFFIX}" +eval "TCL_KIT_LIB_FILE=${TCL_KIT_LIB_FILE}" + +eval "TCL_KIT_LIB_FILE=libtclkit${TCL_UNSHARED_LIB_SUFFIX}" +eval "TCL_KIT_LIB_FILE=\"${TCL_KIT_LIB_FILE}\"" +eval "TCL_KIT_LIB_DIR=${libdir}" + +if test "${TCL_LIB_VERSIONS_OK}" = "ok"; then + TCL_KIT_LIB_FLAG="-ltclkit${TCL_VERSION}" +else + TCL_KIT_LIB_FLAG="-ltclkit`echo ${TCL_VERSION} | tr -d .`" +fi + +TCL_BUILD_KIT_LIB_SPEC="-L`pwd | sed -e 's/ /\\\\ /g'` ${TCL_KIT_LIB_FLAG}" +TCL_KIT_LIB_SPEC="-L${TCL_KIT_LIB_DIR} ${TCL_KIT_LIB_FLAG}" +TCL_BUILD_KIT_LIB_PATH="`pwd`/${TCL_KIT_LIB_FILE}" +TCL_KIT_LIB_PATH="${TCL_KIT_LIB_DIR}/${TCL_KIT_LIB_FILE}" + +#-------------------------------------------------------------------- +# The statements below define various symbols relating to Tcl # stub support. #-------------------------------------------------------------------- @@ -937,15 +956,24 @@ AC_SUBST(PKG_CFG_ARGS) AC_SUBST(TCL_LIB_FILE) AC_SUBST(TCL_LIB_FLAG) AC_SUBST(TCL_LIB_SPEC) +AC_SUBST(TCL_BUILD_LIB_SPEC) + AC_SUBST(TCL_STUB_LIB_FILE) AC_SUBST(TCL_STUB_LIB_FLAG) AC_SUBST(TCL_STUB_LIB_SPEC) AC_SUBST(TCL_STUB_LIB_PATH) -AC_SUBST(TCL_KIT_LIB_FILE) -AC_SUBST(TCL_INCLUDE_SPEC) AC_SUBST(TCL_BUILD_STUB_LIB_SPEC) AC_SUBST(TCL_BUILD_STUB_LIB_PATH) +AC_SUBST(TCL_KIT_LIB_FILE) +AC_SUBST(TCL_KIT_LIB_FLAG) +AC_SUBST(TCL_KIT_LIB_SPEC) +AC_SUBST(TCL_KIT_LIB_PATH) +AC_SUBST(TCL_BUILD_KIT_LIB_SPEC) +AC_SUBST(TCL_BUILD_KIT_LIB_PATH) + +AC_SUBST(TCL_INCLUDE_SPEC) + AC_SUBST(TCL_SRC_DIR) AC_SUBST(CFG_TCL_SHARED_LIB_SUFFIX) AC_SUBST(CFG_TCL_UNSHARED_LIB_SUFFIX) @@ -953,7 +981,6 @@ AC_SUBST(CFG_TCL_UNSHARED_LIB_SUFFIX) AC_SUBST(TCL_SHARED_BUILD) AC_SUBST(LD_LIBRARY_PATH_VAR) -AC_SUBST(TCL_BUILD_LIB_SPEC) AC_SUBST(TCL_LIB_VERSIONS_OK) AC_SUBST(TCL_SHARED_LIB_SUFFIX) diff --git a/unix/tclConfig.sh.in b/unix/tclConfig.sh.in index b58e9fd..976bd7f 100644 --- a/unix/tclConfig.sh.in +++ b/unix/tclConfig.sh.in @@ -39,6 +39,9 @@ TCL_SHARED_BUILD=@TCL_SHARED_BUILD@ # The name of the Tcl library (may be either a .a file or a shared library): TCL_LIB_FILE='@TCL_LIB_FILE@' +# The name of the static Tcl library (intended for kits): +TCL_KIT_LIB_FILE='@TCL_KIT_LIB_FILE@' + # Additional libraries to use when linking Tcl. TCL_LIBS='@TCL_LIBS@' @@ -142,6 +145,31 @@ TCL_SRC_DIR='@TCL_SRC_DIR@' # the "exec_prefix" directory, if it is different. TCL_PACKAGE_PATH='@TCL_PACKAGE_PATH@' +# Core VFS Kit Support +TCL_SUPPORT_KITS=1 + +# The name of the Tcl kit library (.a): +TCL_KIT_LIB_FILE='@TCL_KIT_LIB_FILE@' + +# -l flag to pass to the linker to pick up the Tcl kit library +TCL_KIT_LIB_FLAG='@TCL_KIT_LIB_FLAG@' + +# String to pass to linker to pick up the Tcl kit library from its +# build directory. +TCL_BUILD_KIT_LIB_SPEC='@TCL_BUILD_KIT_LIB_SPEC@' + +# String to pass to linker to pick up the Tcl kit library from its +# installed directory. +TCL_KIT_LIB_SPEC='@TCL_KIT_LIB_SPEC@' + +# Path to the Tcl kit library in the build directory. +TCL_BUILD_KIT_LIB_PATH='@TCL_BUILD_KIT_LIB_PATH@' + +# Path to the Tcl kit library in the install directory. +TCL_KIT_LIB_PATH='@TCL_KIT_LIB_PATH@' + +# END VFS SUPPORT + # Tcl supports stub. TCL_SUPPORTS_STUBS=1 -- cgit v0.12 From 627a5bfa7394225c69b765ba58c42fc7850a8157 Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Tue, 9 Sep 2014 14:47:12 +0000 Subject: Instead of statically link the tclkit executable, pack the tcl dll in the VFS --- tools/mkVfs.tcl | 16 +++++++++++----- unix/Makefile.in | 21 +++++++++++++-------- win/Makefile.in | 2 +- 3 files changed, 25 insertions(+), 14 deletions(-) diff --git a/tools/mkVfs.tcl b/tools/mkVfs.tcl index c7bf17b..c796f8a 100644 --- a/tools/mkVfs.tcl +++ b/tools/mkVfs.tcl @@ -53,14 +53,20 @@ proc copyDir {d1 d2} { } } -if {[llength $argv] < 3} { - puts "Usage: VFS_ROOT TCLSRC_ROOT PLATFORM" +if {[llength $argv] < 4} { + puts "Usage: VFS_ROOT TCLSRC_ROOT PLATFORM TCLDLL" exit 1 } -set TCL_SCRIPT_DIR [lindex $argv 0] -set TCLSRC_ROOT [lindex $argv 1] -set PLATFORM [lindex $argv 2] +set VFSROOT [lindex $argv 0] +set VERSION [lindex $argv 1] +set TCLSRC_ROOT [lindex $argv 2] +set PLATFORM [lindex $argv 3] +set TCLDLL [lindex $argv 4] +file mkdir [file join $VFSROOT bin] +file copy -force $TCLDLL [file join $VFSROOT bin $TCLDLL] + +set TCL_SCRIPT_DIR [file join $VFSROOT tcl$VERSION] puts "Building [file tail $TCL_SCRIPT_DIR] for $PLATFORM" copyDir ${TCLSRC_ROOT}/library ${TCL_SCRIPT_DIR} diff --git a/unix/Makefile.in b/unix/Makefile.in index 30e7109..bce12bd 100644 --- a/unix/Makefile.in +++ b/unix/Makefile.in @@ -588,6 +588,8 @@ MAC_OSX_SRCS = \ CYGWIN_SRCS = \ $(TOP_DIR)/win/tclWinError.c +TCLKIT_SRCS = $(UNIX_DIR)/tclKitInit.c + DTRACE_HDR = tclDTrace.h DTRACE_SRC = $(GENERIC_DIR)/tclDTrace.d @@ -610,7 +612,7 @@ ZLIB_SRCS = \ # things like "make depend". SRCS = $(GENERIC_SRCS) $(TOMMATH_SRCS) $(UNIX_SRCS) $(NOTIFY_SRCS) \ - $(OO_SRCS) $(STUB_SRCS) @PLAT_SRCS@ @ZLIB_SRCS@ + $(OO_SRCS) $(STUB_SRCS) @PLAT_SRCS@ @ZLIB_SRCS@ $TCLKIT_SRCS PWD=`pwd` VFS_INSTALL_DIR=${PWD}/tclkit.vfs/tcl8.6 @@ -665,18 +667,18 @@ null.zip: # Rather than force an install, pack the files we need into a # file system under our control tclkit.vfs: - make install-libraries DESTDIR=tclkit.vfs - make install-tzdata DESTDIR=tclkit.vfs - make install-packages DESTDIR=tclkit.vfs + @echo "Building VFS File system in tclkit.vfs" + @$(TCL_EXE) "$(TOP_DIR)/tools/mkVfs.tcl" \ + "$(UNIX_DIR)/tclkit.vfs" "$(VERSION)" "$(TOP_DIR)" unix ${TCL_LIB_FILE} # Assemble all of the tcl sources into a single executable -${TCLKIT_EXE}: ${TCLKIT_OBJS} ${TCL_OBJS} ${TOMMATH_OBJS} ${ZLIB_OBJS} null.zip tclkit.vfs +${TCLKIT_EXE}: ${TCL_EXE} $(TCLKIT_OBJS) ${TCL_LIB_FILE} ${TCL_STUB_LIB_FILE} ${ZLIB_OBJS} null.zip tclkit.vfs ${CC} ${CFLAGS} ${LDFLAGS} \ - ${TCLKIT_OBJS} ${TCL_OBJS} ${TOMMATH_OBJS} ${ZLIB_OBJS} \ - ${LIBS} @EXTRA_TCLSH_LIBS@ \ + $(TCLKIT_OBJS) ${ZLIB_OBJS} \ + @TCL_BUILD_LIB_SPEC@ ${TCL_STUB_LIB_FILE} ${LIBS} @EXTRA_TCLSH_LIBS@ \ ${CC_SEARCH_FLAGS} -o ${TCLKIT_EXE} cat null.zip >> ${TCLKIT_EXE} - cd tclkit.vfs${prefix}/lib ; zip -rAq ${UNIX_DIR}/${TCLKIT_EXE} . + cd tclkit.vfs ; zip -rAq ${UNIX_DIR}/${TCLKIT_EXE} . Makefile: $(UNIX_DIR)/Makefile.in $(DLTEST_DIR)/Makefile.in $(SHELL) config.status @@ -1195,6 +1197,9 @@ tclIORChan.o: $(GENERIC_DIR)/tclIORChan.c $(IOHDR) tclIORTrans.o: $(GENERIC_DIR)/tclIORTrans.c $(IOHDR) $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclIORTrans.c +tclKitInit.o: $(UNIX_DIR)/tclKitInit.c + $(CC) -c $(APP_CC_SWITCHES) $(UNIX_DIR)/tclKitInit.c + tclLink.o: $(GENERIC_DIR)/tclLink.c $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclLink.c diff --git a/win/Makefile.in b/win/Makefile.in index ec824cc..bf3e303 100644 --- a/win/Makefile.in +++ b/win/Makefile.in @@ -443,7 +443,7 @@ null.zip: tclkit.vfs: $(TCLSH) $(DDE_DLL_FILE) $(REG_DLL_FILE) @echo "Building VFS File system in tclkit.vfs" @$(TCL_EXE) "$(ROOT_DIR)/tools/mkVfs.tcl" \ - "$(WIN_DIR)/tclkit.vfs/tcl$(VERSION)" "$(ROOT_DIR)" windows + "$(WIN_DIR)/tclkit.vfs" "$(VERSION)" "$(ROOT_DIR)" windows $(TCL_LIB_FILE) $(TCLKIT): $(TCLKIT_OBJS) @LIBRARIES@ $(TCL_STUB_LIB_FILE) tclsh.$(RES) null.zip tclkit.vfs $(CC) $(CFLAGS) -DSTATIC_BUILD -UUSE_STUBS $(TCLKIT_OBJS) $(LIBS) \ -- cgit v0.12 From 39145d45d1ef517387a8247804f7ccb8fa811174 Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Tue, 9 Sep 2014 15:02:11 +0000 Subject: Add tclkit to "make all" and install --- unix/Makefile.in | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/unix/Makefile.in b/unix/Makefile.in index bce12bd..c5c3fa6 100644 --- a/unix/Makefile.in +++ b/unix/Makefile.in @@ -623,7 +623,7 @@ VFS_INSTALL_DIR=${PWD}/tclkit.vfs/tcl8.6 all: binaries libraries doc packages -binaries: ${LIB_FILE} ${TCL_EXE} +binaries: ${LIB_FILE} ${TCL_EXE} ${TCLKIT_EXE} libraries: @@ -677,6 +677,7 @@ ${TCLKIT_EXE}: ${TCL_EXE} $(TCLKIT_OBJS) ${TCL_LIB_FILE} ${TCL_STUB_LIB_FILE} $ $(TCLKIT_OBJS) ${ZLIB_OBJS} \ @TCL_BUILD_LIB_SPEC@ ${TCL_STUB_LIB_FILE} ${LIBS} @EXTRA_TCLSH_LIBS@ \ ${CC_SEARCH_FLAGS} -o ${TCLKIT_EXE} + cp -f ${TCLKIT_EXE} ${TCLKIT_EXE}.raw cat null.zip >> ${TCLKIT_EXE} cd tclkit.vfs ; zip -rAq ${UNIX_DIR}/${TCLKIT_EXE} . @@ -833,6 +834,8 @@ install-binaries: binaries @chmod 555 "$(DLL_INSTALL_DIR)/$(LIB_FILE)" @echo "Installing ${TCL_EXE} as $(BIN_INSTALL_DIR)/tclsh$(VERSION)${EXE_SUFFIX}" @$(INSTALL_PROGRAM) ${TCL_EXE} "$(BIN_INSTALL_DIR)/tclsh$(VERSION)${EXE_SUFFIX}" + @echo "Installing ${TCLKIT_EXE} as $(BIN_INSTALL_DIR)/tclkit$(VERSION)${EXE_SUFFIX}" + @$(INSTALL_PROGRAM) ${TCLKIT_EXE} "$(BIN_INSTALL_DIR)/tclkit$(VERSION)${EXE_SUFFIX}" @echo "Installing tclConfig.sh to $(CONFIG_INSTALL_DIR)/" @$(INSTALL_DATA) tclConfig.sh "$(CONFIG_INSTALL_DIR)/tclConfig.sh" @echo "Installing tclooConfig.sh to $(CONFIG_INSTALL_DIR)/" -- cgit v0.12 From 99d72ae8921b1f93943f485fedc93d03e285509b Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Tue, 9 Sep 2014 15:09:23 +0000 Subject: Added the "run tcl dll from vfs" magic to windows --- win/Makefile.in | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/win/Makefile.in b/win/Makefile.in index bf3e303..6d74cdb 100644 --- a/win/Makefile.in +++ b/win/Makefile.in @@ -411,8 +411,7 @@ ZLIB_OBJS = \ TCL_OBJS = ${GENERIC_OBJS} $(TOMMATH_OBJS) ${WIN_OBJS} @ZLIB_OBJS@ -TCLKIT_OBJS = tclKitInit.$(OBJEXT) \ - ${GENERIC_OBJS} $(TOMMATH_OBJS) ${WIN_OBJS} ${ZLIB_OBJS} +TCLKIT_OBJS = tclKitInit.$(OBJEXT) ${ZLIB_OBJS} TCL_DOCS = "$(ROOT_DIR_NATIVE)"/doc/*.[13n] @@ -446,7 +445,7 @@ tclkit.vfs: $(TCLSH) $(DDE_DLL_FILE) $(REG_DLL_FILE) "$(WIN_DIR)/tclkit.vfs" "$(VERSION)" "$(ROOT_DIR)" windows $(TCL_LIB_FILE) $(TCLKIT): $(TCLKIT_OBJS) @LIBRARIES@ $(TCL_STUB_LIB_FILE) tclsh.$(RES) null.zip tclkit.vfs - $(CC) $(CFLAGS) -DSTATIC_BUILD -UUSE_STUBS $(TCLKIT_OBJS) $(LIBS) \ + $(CC) $(CFLAGS) $(TCLKIT_OBJS) $(TCL_LIB_FILE) $(TCL_STUB_LIB_FILE) $(LIBS) \ tclsh.$(RES) $(CC_EXENAME) $(LDFLAGS_CONSOLE) @VC_MANIFEST_EMBED_EXE@ cat null.zip >> $(TCLKIT) -- cgit v0.12 From ee30b1c0abf416e9e6b409e713c1309f2de7eb1b Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Fri, 12 Sep 2014 16:03:20 +0000 Subject: Developed an improved bootloader built around TclSetPreInitScript. The new bootloader now mounts the VFS before the interpreter is initialized, and gives it enough hints to point to the VFS for init.tcl and main.tcl (If present) Also, Tcl_ZVfs_Boot now takes and additional argument: the name of the file to mount. As the difference between a normal shell and a zvfs enabled shell is one again, several lines of code, the example shells is folded back into tclAppInit.c and controlled with macros. The ZVFS commands are now loaded in as a static package. Removed the Stubs entry for Tcl_Boot_ZVFS, it's now intended that shells build their own copy of tclZipVfs.o --- generic/tcl.decls | 5 -- generic/tclDecls.h | 7 --- generic/tclInt.h | 1 + generic/tclStubInit.c | 1 - generic/tclZipVfs.c | 123 +++++++++++++++++++++++++++++++------------------- tools/mkVfs.tcl | 6 +-- unix/Makefile.in | 44 ++++++++++++++---- unix/tclAppInit.c | 20 ++++++-- win/Makefile.in | 41 +++++++++++++---- win/tclAppInit.c | 20 +++++++- 10 files changed, 182 insertions(+), 86 deletions(-) diff --git a/generic/tcl.decls b/generic/tcl.decls index c24898e..1829249 100644 --- a/generic/tcl.decls +++ b/generic/tcl.decls @@ -2326,11 +2326,6 @@ declare 630 { # ----- BASELINE -- FOR -- 8.6.0 ----- # -# ZipVfs -declare 631 { -int Tcl_Zvfs_Boot(Tcl_Interp *interp,const char *vfsmountpoint,const char *initscript) -} - ############################################################################## # Define the platform specific public Tcl interface. These functions are only diff --git a/generic/tclDecls.h b/generic/tclDecls.h index 65d940d..91c0add 100644 --- a/generic/tclDecls.h +++ b/generic/tclDecls.h @@ -1815,10 +1815,6 @@ EXTERN int Tcl_FSUnloadFile(Tcl_Interp *interp, EXTERN void Tcl_ZlibStreamSetCompressionDictionary( Tcl_ZlibStream zhandle, Tcl_Obj *compressionDictionaryObj); -/* 631 */ -EXTERN int Tcl_Zvfs_Boot(Tcl_Interp *interp, - const char *vfsmountpoint, - const char *initscript); typedef struct { const struct TclPlatStubs *tclPlatStubs; @@ -2485,7 +2481,6 @@ typedef struct TclStubs { void * (*tcl_FindSymbol) (Tcl_Interp *interp, Tcl_LoadHandle handle, const char *symbol); /* 628 */ int (*tcl_FSUnloadFile) (Tcl_Interp *interp, Tcl_LoadHandle handlePtr); /* 629 */ void (*tcl_ZlibStreamSetCompressionDictionary) (Tcl_ZlibStream zhandle, Tcl_Obj *compressionDictionaryObj); /* 630 */ - int (*tcl_Zvfs_Boot) (Tcl_Interp *interp, const char *vfsmountpoint, const char *initscript); /* 631 */ } TclStubs; extern const TclStubs *tclStubsPtr; @@ -3778,8 +3773,6 @@ extern const TclStubs *tclStubsPtr; (tclStubsPtr->tcl_FSUnloadFile) /* 629 */ #define Tcl_ZlibStreamSetCompressionDictionary \ (tclStubsPtr->tcl_ZlibStreamSetCompressionDictionary) /* 630 */ -#define Tcl_Zvfs_Boot \ - (tclStubsPtr->tcl_Zvfs_Boot) /* 631 */ #endif /* defined(USE_TCL_STUBS) */ diff --git a/generic/tclInt.h b/generic/tclInt.h index 6bf1ef9..6a4e354 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -3153,6 +3153,7 @@ MODULE_SCOPE double TclpWideClicksToNanoseconds(Tcl_WideInt clicks); #endif MODULE_SCOPE Tcl_Obj * TclDisassembleByteCodeObj(Tcl_Obj *objPtr); MODULE_SCOPE int TclZlibInit(Tcl_Interp *interp); +MODULE_SCOPE int TclZvfsInit(Tcl_Interp *interp); MODULE_SCOPE void * TclpThreadCreateKey(void); MODULE_SCOPE void TclpThreadDeleteKey(void *keyPtr); MODULE_SCOPE void TclpThreadSetMasterTSD(void *tsdKeyPtr, void *ptr); diff --git a/generic/tclStubInit.c b/generic/tclStubInit.c index ace1766..7a84cba 100644 --- a/generic/tclStubInit.c +++ b/generic/tclStubInit.c @@ -1412,7 +1412,6 @@ const TclStubs tclStubs = { Tcl_FindSymbol, /* 628 */ Tcl_FSUnloadFile, /* 629 */ Tcl_ZlibStreamSetCompressionDictionary, /* 630 */ - Tcl_Zvfs_Boot, /* 631 */ }; /* !END!: Do not edit above this line. */ diff --git a/generic/tclZipVfs.c b/generic/tclZipVfs.c index dc96313..15f38bd 100755 --- a/generic/tclZipVfs.c +++ b/generic/tclZipVfs.c @@ -1,7 +1,7 @@ /* * Copyright (c) 2000 D. Richard Hipp * Copyright (c) 2007 PDQ Interfaces Inc. - * Copyright (c) 2013 Sean Woods + * Copyright (c) 2013-2014 Sean Woods * * This file is now released under the BSD style license outlined in the * included file license.terms. @@ -105,7 +105,7 @@ struct ZFile { EXTERN int Tcl_Zvfs_Mount(Tcl_Interp *interp,const char *zArchive,const char *zMountPoint); EXTERN int Tcl_Zvfs_Umount(const char *zArchive); -EXTERN int Tcl_Zvfs_Init(Tcl_Interp *interp); +EXTERN int TclZvfsInit(Tcl_Interp *interp); EXTERN int Tcl_Zvfs_SafeInit(Tcl_Interp *interp); /* @@ -534,7 +534,7 @@ Tcl_Zvfs_Mount( pEntry = Tcl_FindHashEntry(&local.archiveHash, zTrueName); if (pEntry) { pArchive = Tcl_GetHashValue(pEntry); - if (pArchive) { + if (pArchive && interp) { Tcl_AppendResult(interp, pArchive->zMountPoint, 0); } } @@ -560,7 +560,7 @@ Tcl_Zvfs_Mount( iPos = Tcl_Seek(chan, -22, SEEK_END); Tcl_Read(chan, (char *) zBuf, 22); if (memcmp(zBuf, "\120\113\05\06", 4)) { - Tcl_AppendResult(interp, "not a ZIP archive", NULL); + if(interp) Tcl_AppendResult(interp, "not a ZIP archive", NULL); return TCL_ERROR; } @@ -572,8 +572,9 @@ Tcl_Zvfs_Mount( pEntry = Tcl_CreateHashEntry(&local.archiveHash, zArchiveName, &isNew); if (!isNew) { pArchive = Tcl_GetHashValue(pEntry); - Tcl_AppendResult(interp, "already mounted at ", pArchive->zMountPoint, - 0); + if (interp) { + Tcl_AppendResult(interp, "already mounted at ", pArchive->zMountPoint,0); + } Tcl_Free(zArchiveName); Tcl_Close(interp, chan); return TCL_ERROR; @@ -630,12 +631,13 @@ Tcl_Zvfs_Mount( Tcl_Read(chan, (char *) zBuf, 46); if (memcmp(zBuf, "\120\113\01\02", 4)) { - Tcl_AppendResult(interp, "ill-formed central directory entry", - NULL); - if (zTrueName) { - Tcl_Free(zTrueName); - } - return TCL_ERROR; + if(interp) { + Tcl_AppendResult(interp, "ill-formed central directory entry",NULL); + } + if (zTrueName) { + Tcl_Free(zTrueName); + } + return TCL_ERROR; } lenName = INT16(zBuf, 28); lenExtra = INT16(zBuf, 30) + INT16(zBuf, 32); @@ -1718,6 +1720,18 @@ static int ZvfsAddObjCmd(void *NotUsed, Tcl_Interp *interp, int objc, Tcl_Obj *c static int ZvfsDumpObjCmd(void *NotUsed, Tcl_Interp *interp, int objc, Tcl_Obj *const* objv); static int ZvfsStartObjCmd(void *NotUsed, Tcl_Interp *interp, int objc, Tcl_Obj *const* objv); +static int Zvfs_Common_Init(Tcl_Interp *interp) { + if (local.isInit) return TCL_OK; + /* One-time initialization of the ZVFS */ + if(Tcl_FSRegister(interp, &Tobe_Filesystem)) { + return TCL_ERROR; + } + Tcl_InitHashTable(&local.fileHash, TCL_STRING_KEYS); + Tcl_InitHashTable(&local.archiveHash, TCL_STRING_KEYS); + local.isInit = 1; + return TCL_OK; +} + /* * Initialize the ZVFS system. */ @@ -1731,7 +1745,7 @@ Zvfs_doInit( return TCL_ERROR; } #endif - Tcl_StaticPackage(interp, "zvfs", Tcl_Zvfs_Init, Tcl_Zvfs_SafeInit); + Tcl_StaticPackage(interp, "zvfs", TclZvfsInit, Tcl_Zvfs_SafeInit); if (!safe) { Tcl_CreateObjCommand(interp, "zvfs::mount", ZvfsMountObjCmd, 0, 0); Tcl_CreateObjCommand(interp, "zvfs::unmount", ZvfsUnmountObjCmd, 0, 0); @@ -1746,16 +1760,10 @@ Zvfs_doInit( Tcl_SetVar(interp, "::zvfs::auto_ext", ".tcl .tk .itcl .htcl .txt .c .h .tht", TCL_GLOBAL_ONLY); /* Tcl_CreateObjCommand(interp, "zip::open", ZipOpenObjCmd, 0, 0); */ - - if (!local.isInit) { - /* One-time initialization of the ZVFS */ - if(Tcl_FSRegister(NULL, &Tobe_Filesystem)) { - return TCL_ERROR; - } - Tcl_InitHashTable(&local.fileHash, TCL_STRING_KEYS); - Tcl_InitHashTable(&local.archiveHash, TCL_STRING_KEYS); - local.isInit = 1; + if(Zvfs_Common_Init(interp)) { + return TCL_ERROR; } + if (Zvfs_PostInit) { Zvfs_PostInit(interp); } @@ -1765,43 +1773,58 @@ Zvfs_doInit( /* ** Boot a shell, mount the executable's VFS, detect main.tcl */ -int Tcl_Zvfs_Boot(Tcl_Interp *interp,const char *vfsmountpoint,const char *initscript) { - CONST char *cp=Tcl_GetNameOfExecutable(); - char filepath[256]; - +int Tcl_Zvfs_Boot(const char *archive,const char *vfsmountpoint,const char *initscript) { + FILE *fout; + Zvfs_Common_Init(NULL); + if(!vfsmountpoint) { + vfsmountpoint="/zvfs"; + } + if(!initscript) { + initscript="main.tcl"; + } /* We have to initialize the virtual filesystem before calling ** Tcl_Init(). Otherwise, Tcl_Init() will not be able to find ** its startup script files. */ - if(Zvfs_doInit(interp, 0)) { - return TCL_ERROR; - } - if(!Tcl_Zvfs_Mount(interp, cp, vfsmountpoint)) { + if(!Tcl_Zvfs_Mount(NULL, archive, vfsmountpoint)) { + Tcl_DString filepath; + Tcl_DString preinit; + Tcl_Obj *vfsinitscript; Tcl_Obj *vfstcllib; Tcl_Obj *vfstklib; + Tcl_Obj *vfspreinit; + Tcl_DStringInit(&filepath); + Tcl_DStringInit(&preinit); + + Tcl_DStringInit(&filepath); + Tcl_DStringAppend(&filepath,vfsmountpoint,-1); + Tcl_DStringAppend(&filepath,"/",-1); + Tcl_DStringAppend(&filepath,initscript,-1); + vfsinitscript=Tcl_NewStringObj(Tcl_DStringValue(&filepath),-1); + Tcl_DStringFree(&filepath); - strcpy(filepath,vfsmountpoint); - strcat(filepath,"/"); - strcat(filepath,initscript); - vfsinitscript=Tcl_NewStringObj(filepath,-1); - strcpy(filepath,vfsmountpoint); - strcat(filepath,"/tcl8.6"); - vfstcllib=Tcl_NewStringObj(filepath,-1); - strcpy(filepath,vfsmountpoint); - strcat(filepath,"/tk8.6"); - vfstklib=Tcl_NewStringObj(filepath,-1); - + Tcl_DStringInit(&filepath); + Tcl_DStringAppend(&filepath,vfsmountpoint,-1); + Tcl_DStringAppend(&filepath,"/tcl8.6",-1); + vfstcllib=Tcl_NewStringObj(Tcl_DStringValue(&filepath),-1); + Tcl_DStringFree(&filepath); + + Tcl_DStringInit(&filepath); + Tcl_DStringAppend(&filepath,vfsmountpoint,-1); + Tcl_DStringAppend(&filepath,"/tk8.6",-1); + vfstklib=Tcl_NewStringObj(Tcl_DStringValue(&filepath),-1); + Tcl_DStringFree(&filepath); + Tcl_IncrRefCount(vfsinitscript); Tcl_IncrRefCount(vfstcllib); Tcl_IncrRefCount(vfstklib); if(Tcl_FSAccess(vfsinitscript,F_OK)==0) { /* Startup script should be set before calling Tcl_AppInit */ + fprintf(fout,"%s\n",Tcl_GetString(vfsinitscript)); Tcl_SetStartupScript(vfsinitscript,NULL); - } else { - Tcl_SetStartupScript(NULL,NULL); } if(Tcl_FSAccess(vfsinitscript,F_OK)==0) { @@ -1811,12 +1834,18 @@ int Tcl_Zvfs_Boot(Tcl_Interp *interp,const char *vfsmountpoint,const char *inits Tcl_SetStartupScript(NULL,NULL); } if(Tcl_FSAccess(vfstcllib,F_OK)==0) { - Tcl_SetVar2(interp, "env", "TCL_LIBRARY", Tcl_GetString(vfstcllib), TCL_GLOBAL_ONLY); + Tcl_DStringAppend(&preinit,"\nset tcl_library ",-1); + Tcl_DStringAppendElement(&preinit,Tcl_GetString(vfstcllib)); } if(Tcl_FSAccess(vfstklib,F_OK)==0) { - Tcl_SetVar2(interp, "env", "TK_LIBRARY", Tcl_GetString(vfstklib), TCL_GLOBAL_ONLY); + Tcl_DStringAppend(&preinit,"\nset tk_library ",-1); + Tcl_DStringAppendElement(&preinit,Tcl_GetString(vfstklib)); } - + vfspreinit=Tcl_NewStringObj(Tcl_DStringValue(&preinit),-1); + /* NOTE: We never decr this refcount, lest the contents of the script be deallocated */ + Tcl_IncrRefCount(vfspreinit); + TclSetPreInitScript(Tcl_GetString(vfspreinit)); + Tcl_DecrRefCount(vfsinitscript); Tcl_DecrRefCount(vfstcllib); Tcl_DecrRefCount(vfstklib); @@ -1826,7 +1855,7 @@ int Tcl_Zvfs_Boot(Tcl_Interp *interp,const char *vfsmountpoint,const char *inits int -Tcl_Zvfs_Init( +TclZvfsInit( Tcl_Interp *interp) { return Zvfs_doInit(interp, 0); diff --git a/tools/mkVfs.tcl b/tools/mkVfs.tcl index c7bf17b..83eb9e6 100644 --- a/tools/mkVfs.tcl +++ b/tools/mkVfs.tcl @@ -15,7 +15,7 @@ proc pkgIndexDir {root fout d1} { if {[file isdirectory $f] && [string compare CVS $ftail]} { pkgIndexDir $root $fout $f } elseif {[file tail $f] eq "pkgIndex.tcl"} { - puts $fout "set dir \$HERE[string range $d1 $idx end]" + puts $fout "set dir \${VFSROOT}[string range $d1 $idx end]" puts $fout [cat $f] } } @@ -87,7 +87,7 @@ set fout [open ${TCL_SCRIPT_DIR}/tclIndex a] puts $fout {# # MANIFEST OF INCLUDED PACKAGES # -set HERE $dir +set VFSROOT $dir } pkgIndexDir ${TCL_SCRIPT_DIR} $fout ${TCL_SCRIPT_DIR} close $fout @@ -96,12 +96,10 @@ puts $fout { # Save Tcl the trouble of hunting for these packages } set ddedll [glob -nocomplain ${TCLSRC_ROOT}/win/tcldde*.dll] -puts "DDE DLL $ddedll" if {$ddedll != {}} { puts $fout [cat ${TCL_SCRIPT_DIR}/dde/pkgIndex.tcl] } set regdll [glob -nocomplain ${TCLSRC_ROOT}/win/tclreg*.dll] -puts "REG DLL $ddedll" if {$regdll != {}} { puts $fout [cat ${TCL_SCRIPT_DIR}/reg/pkgIndex.tcl] } diff --git a/unix/Makefile.in b/unix/Makefile.in index c66cc0a..c98f6ce 100644 --- a/unix/Makefile.in +++ b/unix/Makefile.in @@ -312,7 +312,7 @@ GENERIC_OBJS = regcomp.o regexec.o regfree.o regerror.o tclAlloc.o \ tclResolve.o tclResult.o tclScan.o tclStringObj.o \ tclStrToD.o tclThread.o \ tclThreadAlloc.o tclThreadJoin.o tclThreadStorage.o tclStubInit.o \ - tclTimer.o tclTrace.o tclUtf.o tclUtil.o tclVar.o tclZlib.o tclZipVfs.o \ + tclTimer.o tclTrace.o tclUtf.o tclUtil.o tclVar.o tclZlib.o \ tclTomMathInterface.o OO_OBJS = tclOO.o tclOOBasic.o tclOOCall.o tclOODefineCmds.o tclOOInfo.o \ @@ -364,7 +364,7 @@ ZLIB_OBJS = Zadler32.o Zcompress.o Zcrc32.o Zdeflate.o Zinfback.o \ TCL_OBJS = ${GENERIC_OBJS} ${UNIX_OBJS} ${NOTIFY_OBJS} ${COMPAT_OBJS} \ ${OO_OBJS} @DL_OBJS@ @PLAT_OBJS@ -TCLKIT_OBJS = tclKitInit.o +TCLKIT_OBJS = tclKitInit.o tclZipVfs.o OBJS = ${TCL_OBJS} ${TOMMATH_OBJS} @DTRACE_OBJ@ @ZLIB_OBJS@ @@ -558,7 +558,6 @@ UNIX_HDRS = \ UNIX_SRCS = \ $(UNIX_DIR)/tclAppInit.c \ - $(UNIX_DIR)/tclKitInit.c \ $(UNIX_DIR)/tclUnixChan.c \ $(UNIX_DIR)/tclUnixEvent.c \ $(UNIX_DIR)/tclUnixFCmd.c \ @@ -674,19 +673,41 @@ null.zip: # Rather than force an install, pack the files we need into a # file system under our control tclkit.vfs: - make install-libraries DESTDIR=tclkit.vfs - make install-tzdata DESTDIR=tclkit.vfs - make install-packages DESTDIR=tclkit.vfs + @echo "Building VFS File system in tclkit.vfs" + @$(TCL_EXE) "$(TOP_DIR)/tools/mkVfs.tcl" \ + "$(UNIX_DIR)/tclkit.vfs/tcl$(VERSION)" "$(TOP_DIR)" unix # Assemble all of the tcl sources into a single executable -${TCLKIT_EXE}: ${TCLKIT_OBJS} ${TCL_KIT_LIB_FILE} null.zip tclkit.vfs +${TCLKIT_EXE}: + +# Builds an executable directly from the Tcl sources +tclkit-direct: ${TCLKIT_OBJS} ${OBJS} ${ZLIB_OBJS} null.zip tclkit.vfs + ${CC} ${CFLAGS} ${LDFLAGS} \ + ${TCLKIT_OBJS} ${OBJS} ${ZLIB_OBJS} \ + ${LIBS} @EXTRA_TCLSH_LIBS@ \ + ${CC_SEARCH_FLAGS} -o ${TCLKIT_EXE} + cat null.zip >> ${TCLKIT_EXE} + cd tclkit.vfs ; zip -rAq ${UNIX_DIR}/${TCLKIT_EXE} . + +# Builds an executable linked to the Tcl dynamic library +tclkit-dynamic: ${TCLKIT_OBJS} ${TCL_LIB_FILE} ${TCL_STUB_LIB_FILE} null.zip tclkit.vfs + ${CC} ${CFLAGS} ${LDFLAGS} \ + ${TCLKIT_OBJS} \ + @TCL_BUILD_LIB_SPEC@ \ + ${LIBS} @EXTRA_TCLSH_LIBS@ \ + ${CC_SEARCH_FLAGS} -o ${TCLKIT_EXE} + cat null.zip >> ${TCLKIT_EXE} + cd tclkit.vfs ; zip -rAq ${UNIX_DIR}/${TCLKIT_EXE} . + +# Builds a tcl static library, as well as an executable linked to the Tcl static library +tclkit-kitlib: ${TCLKIT_OBJS} ${TCL_KIT_LIB_FILE} null.zip tclkit.vfs ${CC} ${CFLAGS} ${LDFLAGS} \ ${TCLKIT_OBJS} \ - @TCL_BUILD_LIB_SPEC@ ${TCL_KIT_LIB_FILE} \ + @TCL_BUILD_KIT_LIB_SPEC@ \ ${LIBS} @EXTRA_TCLSH_LIBS@ \ ${CC_SEARCH_FLAGS} -o ${TCLKIT_EXE} cat null.zip >> ${TCLKIT_EXE} - cd tclkit.vfs${prefix}/lib ; zip -rAq ${UNIX_DIR}/${TCLKIT_EXE} . + cd tclkit.vfs ; zip -rAq ${UNIX_DIR}/${TCLKIT_EXE} . Makefile: $(UNIX_DIR)/Makefile.in $(DLTEST_DIR)/Makefile.in $(SHELL) config.status @@ -1070,6 +1091,10 @@ xtTestInit.o: $(UNIX_DIR)/tclAppInit.c ${TCL_EXE} mv tclAppInit.sav tclAppInit.o; \ fi; +tclKitInit.o: $(UNIX_DIR)/tclAppInit.c ${TCL_EXE} + $(CC) -c $(APP_CC_SWITCHES) \ + -DTCL_ZIPVFS $(UNIX_DIR)/tclAppInit.c -o tclKitInit.o + # Object files used on all Unix systems: REGHDRS=$(GENERIC_DIR)/regex.h $(GENERIC_DIR)/regguts.h \ @@ -2171,6 +2196,7 @@ BUILD_HTML = \ .PHONY: install-tzdata install-msgs .PHONY: packages configure-packages test-packages clean-packages .PHONY: dist-packages distclean-packages install-packages +.PHONY: tclkit-direct tclkit-dynamic tclkit-kitlib #-------------------------------------------------------------------------- # DO NOT DELETE THIS LINE -- make depend depends on it. diff --git a/unix/tclAppInit.c b/unix/tclAppInit.c index 9bbc88b..4df6387 100644 --- a/unix/tclAppInit.c +++ b/unix/tclAppInit.c @@ -40,7 +40,10 @@ extern Tcl_PackageInitProc Tclxttest_Init; #endif MODULE_SCOPE int TCL_LOCAL_APPINIT(Tcl_Interp *); MODULE_SCOPE int main(int, char **); - +#ifdef TCL_ZIPVFS + MODULE_SCOPE int Tcl_Zvfs_Boot(const char *,const char *,const char *); + MODULE_SCOPE int TclZvfsInit(Tcl_Interp *); +#endif /* TCL_ZIPVFS */ /* * The following #if block allows you to change how Tcl finds the startup * script, prime the library or encoding paths, fiddle with the argv, etc., @@ -80,7 +83,13 @@ main( #ifdef TCL_LOCAL_MAIN_HOOK TCL_LOCAL_MAIN_HOOK(&argc, &argv); #endif - +#ifdef TCL_ZIPVFS + #define TCLKIT_INIT "main.tcl" + #define TCLKIT_VFSMOUNT "/zvfs" + Tcl_FindExecutable(argv[0]); + CONST char *cp=Tcl_GetNameOfExecutable(); + Tcl_Zvfs_Boot(cp,TCLKIT_VFSMOUNT,TCLKIT_INIT); +#endif Tcl_Main(argc, argv, TCL_LOCAL_APPINIT); return 0; /* Needed only to prevent compiler warning. */ } @@ -111,7 +120,12 @@ Tcl_AppInit( if ((Tcl_Init)(interp) == TCL_ERROR) { return TCL_ERROR; } - +#ifdef TCL_ZIPVFS + /* Load the ZipVfs package */ + if (TclZvfsInit(interp) == TCL_ERROR) { + return TCL_ERROR; + } +#endif #ifdef TCL_XT_TEST if (Tclxttest_Init(interp) == TCL_ERROR) { return TCL_ERROR; diff --git a/win/Makefile.in b/win/Makefile.in index 6fdbacf..0b52640 100644 --- a/win/Makefile.in +++ b/win/Makefile.in @@ -299,9 +299,8 @@ GENERIC_OBJS = \ tclUtf.$(OBJEXT) \ tclUtil.$(OBJEXT) \ tclVar.$(OBJEXT) \ - tclZlib.$(OBJEXT) \ - tclZipVfs.$(OBJEXT) - + tclZlib.$(OBJEXT) + TOMMATH_OBJS = \ bncore.${OBJEXT} \ bn_reverse.${OBJEXT} \ @@ -411,9 +410,7 @@ ZLIB_OBJS = \ TCL_OBJS = ${GENERIC_OBJS} $(TOMMATH_OBJS) ${WIN_OBJS} @ZLIB_OBJS@ -TCLKIT_OBJS = tclKitInit.$(OBJEXT) \ - ${GENERIC_OBJS} $(TOMMATH_OBJS) ${WIN_OBJS} ${ZLIB_OBJS} - +TCLKIT_OBJS = tclKitInit.$(OBJEXT) tclZipVfs.$(OBJEXT) TCL_DOCS = "$(ROOT_DIR_NATIVE)"/doc/*.[13n] @@ -445,8 +442,31 @@ tclkit.vfs: $(TCLSH) $(DDE_DLL_FILE) $(REG_DLL_FILE) @$(TCL_EXE) "$(ROOT_DIR)/tools/mkVfs.tcl" \ "$(WIN_DIR)/tclkit.vfs/tcl$(VERSION)" "$(ROOT_DIR)" windows -$(TCLKIT): $(TCLKIT_OBJS) @LIBRARIES@ $(TCL_STUB_LIB_FILE) tclsh.$(RES) null.zip tclkit.vfs - $(CC) $(CFLAGS) -DSTATIC_BUILD -UUSE_STUBS $(TCLKIT_OBJS) $(LIBS) \ +$(TCLKIT): tclkit-direct + +# Builds an executable directly from the Tcl sources +tclkit-direct: $(TCLKIT_OBJS) ${GENERIC_OBJS} $(TOMMATH_OBJS) ${WIN_OBJS} ${ZLIB_OBJS} @LIBRARIES@ $(TCL_STUB_LIB_FILE) tclsh.$(RES) null.zip tclkit.vfs + rm *.$(OBJEXT) + $(CC) $(CFLAGS) -DSTATIC_BUILD -UUSE_STUBS $(TCLKIT_OBJS) \ + ${GENERIC_OBJS} $(TOMMATH_OBJS) ${WIN_OBJS} ${ZLIB_OBJS} \ + $(LIBS) \ + tclsh.$(RES) $(CC_EXENAME) $(LDFLAGS_CONSOLE) + @VC_MANIFEST_EMBED_EXE@ + rm *.$(OBJEXT) + cat null.zip >> $(TCLKIT) + cd tclkit.vfs ; zip -rAq $(WIN_DIR)/$(TCLKIT) . + + +# Builds an executable linked to the Tcl dynamic library +tclkit-dynamic: $(TCLKIT_OBJS) @LIBRARIES@ $(TCL_STUB_LIB_FILE) tclsh.$(RES) null.zip tclkit.vfs + $(CC) $(CFLAGS) $(TCLKIT_OBJS) $(TCL_LIB_FILE) $(TCL_STUB_LIB_FILE) $(LIBS) \ + tclsh.$(RES) $(CC_EXENAME) $(LDFLAGS_CONSOLE) + @VC_MANIFEST_EMBED_EXE@ + cat null.zip >> $(TCLKIT) + cd tclkit.vfs ; zip -rAq $(WIN_DIR)/$(TCLKIT) . + +tclkit-kitlib: $(TCLKIT_OBJS) @LIBRARIES@ $(TCL_STUB_LIB_FILE) tclsh.$(RES) null.zip tclkit.vfs + $(CC) $(CFLAGS) $(TCLKIT_OBJS) $(TCL_LIB_FILE) $(TCL_STUB_LIB_FILE) $(LIBS) \ tclsh.$(RES) $(CC_EXENAME) $(LDFLAGS_CONSOLE) @VC_MANIFEST_EMBED_EXE@ cat null.zip >> $(TCLKIT) @@ -515,6 +535,9 @@ testMain.${OBJEXT}: tclAppInit.c tclMain2.${OBJEXT}: tclMain.c $(CC) -c $(CC_SWITCHES) -DBUILD_tcl -DTCL_ASCII_MAIN @DEPARG@ $(CC_OBJNAME) +tclKitInit.${OBJEXT}: tclAppInit.c + $(CC) -c $(CC_SWITCHES) -DTCL_ZIPVFS @DEPARG@ $(CC_OBJNAME) + # TIP #59, embedding of configuration information into the binary library. # # Part of Tcl's configuration information are the paths where it was installed @@ -899,5 +922,7 @@ html-tk: $(TCLSH) .PHONY: gdb depend cleanhelp clean distclean packages install-packages .PHONY: test-packages clean-packages distclean-packages genstubs html .PHONY: html-tcl html-tk tclkit +.PHONY: tclkit-direct tclkit-dynamic tclkit-kitlib + # DO NOT DELETE THIS LINE -- make depend depends on it. diff --git a/win/tclAppInit.c b/win/tclAppInit.c index a6c1a67..6f49afa 100644 --- a/win/tclAppInit.c +++ b/win/tclAppInit.c @@ -27,6 +27,11 @@ extern Tcl_PackageInitProc Tcltest_Init; extern Tcl_PackageInitProc Tcltest_SafeInit; #endif /* TCL_TEST */ +#ifdef TCL_ZIPVFS + MODULE_SCOPE int Tcl_Zvfs_Boot(const char *,const char *,const char *); + MODULE_SCOPE int TclZvfsInit(Tcl_Interp *); +#endif /* TCL_ZIPVFS */ + #if defined(STATIC_BUILD) && TCL_USE_STATIC_PACKAGES extern Tcl_PackageInitProc Registry_Init; extern Tcl_PackageInitProc Dde_Init; @@ -123,7 +128,13 @@ _tmain( #ifdef TCL_LOCAL_MAIN_HOOK TCL_LOCAL_MAIN_HOOK(&argc, &argv); #endif - +#ifdef TCL_ZIPVFS + #define TCLKIT_INIT "main.tcl" + #define TCLKIT_VFSMOUNT "/zvfs" + Tcl_FindExecutable(argv[0]); + CONST char *cp=Tcl_GetNameOfExecutable(); + Tcl_Zvfs_Boot(cp,TCLKIT_VFSMOUNT,TCLKIT_INIT); +#endif Tcl_Main(argc, argv, TCL_LOCAL_APPINIT); return 0; /* Needed only to prevent compiler warning. */ } @@ -154,7 +165,12 @@ Tcl_AppInit( if ((Tcl_Init)(interp) == TCL_ERROR) { return TCL_ERROR; } - +#ifdef TCL_ZIPVFS + /* Load the ZipVfs package */ + if (TclZvfsInit(interp) == TCL_ERROR) { + return TCL_ERROR; + } +#endif #if defined(STATIC_BUILD) && TCL_USE_STATIC_PACKAGES if (Registry_Init(interp) == TCL_ERROR) { return TCL_ERROR; -- cgit v0.12 From c003b95ed4a2c757d79b8161e72d50f32ea6e9d5 Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Fri, 12 Sep 2014 16:13:00 +0000 Subject: Backing out code that inserted a debug statement into the http package --- library/http/http.tcl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/http/http.tcl b/library/http/http.tcl index afa9458..a6b2bfd 100644 --- a/library/http/http.tcl +++ b/library/http/http.tcl @@ -12,7 +12,7 @@ package require Tcl 8.6 # Keep this in sync with pkgIndex.tcl and with the install directories in # Makefiles package provide http 2.8.8 -puts [list LOADED [info script]] + namespace eval http { # Allow resourcing to not clobber existing data -- cgit v0.12 From b25f4f5272e7987bb9a914c4dd414c095b1769ed Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Mon, 15 Sep 2014 09:44:39 +0000 Subject: The unix build has been pared down to the minimum hooks required to build a VFS enabled Tclsh with a simple compile flag. Modified the BC and Visual Studio makefiles for Windows, but these are untested. The default for Tcl is now to build a static or dynamic shell in the same way it would build a static or dynamic shell for Tclsh. Controlled by the --enable-shared flag. Note however that ZLib is compiled in to every VFS enabled shell. (Rather than rely on a dylib.) The "direct" build is maintained in the Makefile, mostly as a h(istor|yster)ical reference. The technique is not portable to Windows, and may not work outside of OSX. --- unix/Makefile.in | 40 +- unix/configure | 20975 +++++++++++++++++++++++++++++++++++++--------------- unix/configure.in | 36 +- unix/tcl.m4 | 10 - win/makefile.bc | 15 +- win/makefile.vc | 22 +- 6 files changed, 14876 insertions(+), 6222 deletions(-) diff --git a/unix/Makefile.in b/unix/Makefile.in index c98f6ce..7523fca 100644 --- a/unix/Makefile.in +++ b/unix/Makefile.in @@ -168,7 +168,6 @@ INSTALL_DATA_DIR = ${INSTALL} -d -m 755 EXE_SUFFIX = @EXEEXT@ TCL_EXE = tclsh${EXE_SUFFIX} TCLKIT_EXE = tclkit${EXE_SUFFIX} -TCLKIT_LIB = tclkit${EXE_SUFFIX} TCLTEST_EXE = tcltest${EXE_SUFFIX} NATIVE_TCLSH = @TCLSH_PROG@ @@ -204,9 +203,6 @@ BUILD_DLTEST = @BUILD_DLTEST@ TCL_LIB_FILE = @TCL_LIB_FILE@ #TCL_LIB_FILE = libtcl.a -TCL_KIT_LIB_FILE = @TCL_KIT_LIB_FILE@ -#TCL_KIT_LIB_FILE = libtclkit.a - # Generic lib name used in rules that apply to tcl and tk LIB_FILE = ${TCL_LIB_FILE} @@ -469,7 +465,6 @@ GENERIC_SRCS = \ $(GENERIC_DIR)/tclUtil.c \ $(GENERIC_DIR)/tclVar.c \ $(GENERIC_DIR)/tclAssembly.c \ - $(GENERIC_DIR)/tclZipVfs.obj \ $(GENERIC_DIR)/tclZlib.c OO_SRCS = \ @@ -615,9 +610,6 @@ ZLIB_SRCS = \ SRCS = $(GENERIC_SRCS) $(TOMMATH_SRCS) $(UNIX_SRCS) $(NOTIFY_SRCS) \ $(OO_SRCS) $(STUB_SRCS) @PLAT_SRCS@ @ZLIB_SRCS@ -PWD=`pwd` -VFS_INSTALL_DIR=${PWD}/tclkit.vfs/tcl8.6 - #-------------------------------------------------------------------------- # Start of rules #-------------------------------------------------------------------------- @@ -642,11 +634,6 @@ ${STUB_LIB_FILE}: ${STUB_LIB_OBJS} fi rm -f $@ @MAKE_STUB_LIB@ - - -${TCL_KIT_LIB_FILE}: ${TCL_OBJS} ${TOMMATH_OBJS} ${ZLIB_OBJS} - rm -f $@ - @MAKE_KIT_LIB@ # Make target which outputs the list of the .o contained in the Tcl lib useful # to build a single big shared library containing Tcl and other extensions. @@ -677,20 +664,8 @@ tclkit.vfs: @$(TCL_EXE) "$(TOP_DIR)/tools/mkVfs.tcl" \ "$(UNIX_DIR)/tclkit.vfs/tcl$(VERSION)" "$(TOP_DIR)" unix -# Assemble all of the tcl sources into a single executable -${TCLKIT_EXE}: - -# Builds an executable directly from the Tcl sources -tclkit-direct: ${TCLKIT_OBJS} ${OBJS} ${ZLIB_OBJS} null.zip tclkit.vfs - ${CC} ${CFLAGS} ${LDFLAGS} \ - ${TCLKIT_OBJS} ${OBJS} ${ZLIB_OBJS} \ - ${LIBS} @EXTRA_TCLSH_LIBS@ \ - ${CC_SEARCH_FLAGS} -o ${TCLKIT_EXE} - cat null.zip >> ${TCLKIT_EXE} - cd tclkit.vfs ; zip -rAq ${UNIX_DIR}/${TCLKIT_EXE} . - # Builds an executable linked to the Tcl dynamic library -tclkit-dynamic: ${TCLKIT_OBJS} ${TCL_LIB_FILE} ${TCL_STUB_LIB_FILE} null.zip tclkit.vfs +${TCLKIT_EXE}: ${TCLKIT_OBJS} ${TCL_LIB_FILE} ${TCL_STUB_LIB_FILE} null.zip tclkit.vfs ${CC} ${CFLAGS} ${LDFLAGS} \ ${TCLKIT_OBJS} \ @TCL_BUILD_LIB_SPEC@ \ @@ -699,11 +674,10 @@ tclkit-dynamic: ${TCLKIT_OBJS} ${TCL_LIB_FILE} ${TCL_STUB_LIB_FILE} null.zip tcl cat null.zip >> ${TCLKIT_EXE} cd tclkit.vfs ; zip -rAq ${UNIX_DIR}/${TCLKIT_EXE} . -# Builds a tcl static library, as well as an executable linked to the Tcl static library -tclkit-kitlib: ${TCLKIT_OBJS} ${TCL_KIT_LIB_FILE} null.zip tclkit.vfs +# Builds an executable directly from the Tcl sources +tclkit-direct: ${TCLKIT_OBJS} ${OBJS} ${ZLIB_OBJS} null.zip tclkit.vfs ${CC} ${CFLAGS} ${LDFLAGS} \ - ${TCLKIT_OBJS} \ - @TCL_BUILD_KIT_LIB_SPEC@ \ + ${TCLKIT_OBJS} ${OBJS} ${ZLIB_OBJS} \ ${LIBS} @EXTRA_TCLSH_LIBS@ \ ${CC_SEARCH_FLAGS} -o ${TCLKIT_EXE} cat null.zip >> ${TCLKIT_EXE} @@ -873,10 +847,6 @@ install-binaries: binaries echo "Installing $(STUB_LIB_FILE) to $(LIB_INSTALL_DIR)/"; \ @INSTALL_STUB_LIB@ ; \ fi - @if test "$(TCL_KIT_LIB_FILE)" != "" ; then \ - echo "Installing $(TCL_KIT_LIB_FILE) to $(LIB_INSTALL_DIR)/"; \ - @INSTALL_KIT_LIB@ ; \ - fi @EXTRA_INSTALL_BINARIES@ @echo "Installing pkg-config file to $(LIB_INSTALL_DIR)/pkgconfig/" @$(INSTALL_DATA_DIR) $(LIB_INSTALL_DIR)/pkgconfig @@ -2196,7 +2166,7 @@ BUILD_HTML = \ .PHONY: install-tzdata install-msgs .PHONY: packages configure-packages test-packages clean-packages .PHONY: dist-packages distclean-packages install-packages -.PHONY: tclkit-direct tclkit-dynamic tclkit-kitlib +.PHONY: tclkit-direct #-------------------------------------------------------------------------- # DO NOT DELETE THIS LINE -- make depend depends on it. diff --git a/unix/configure b/unix/configure index a5f318e..a82c692 100755 --- a/unix/configure +++ b/unix/configure @@ -1,459 +1,81 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for tcl 8.6. -# -# -# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. -# +# Generated by GNU Autoconf 2.59 for tcl 8.6. # +# Copyright (C) 2003 Free Software Foundation, Inc. # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. -## -------------------- ## -## M4sh Initialization. ## -## -------------------- ## +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## -# Be more Bourne compatible -DUALCASE=1; export DUALCASE # for MKS sh -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : +# Be Bourne compatible +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: - # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' - setopt NO_GLOB_SUBST -else - case `(set -o) 2>/dev/null` in #( - *posix*) : - set -o posix ;; #( - *) : - ;; -esac -fi - - -as_nl=' -' -export as_nl -# Printing a long string crashes Solaris 7 /usr/bin/printf. -as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo -# Prefer a ksh shell builtin over an external printf program on Solaris, -# but without wasting forks for bash or zsh. -if test -z "$BASH_VERSION$ZSH_VERSION" \ - && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='print -r --' - as_echo_n='print -rn --' -elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='printf %s\n' - as_echo_n='printf %s' -else - if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then - as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' - as_echo_n='/usr/ucb/echo -n' - else - as_echo_body='eval expr "X$1" : "X\\(.*\\)"' - as_echo_n_body='eval - arg=$1; - case $arg in #( - *"$as_nl"*) - expr "X$arg" : "X\\(.*\\)$as_nl"; - arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; - esac; - expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" - ' - export as_echo_n_body - as_echo_n='sh -c $as_echo_n_body as_echo' - fi - export as_echo_body - as_echo='sh -c $as_echo_body as_echo' +elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then + set -o posix fi +DUALCASE=1; export DUALCASE # for MKS sh -# The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then - PATH_SEPARATOR=: - (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { - (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || - PATH_SEPARATOR=';' - } +# Support unset when possible. +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false fi -# IFS -# We need space, tab and new line, in precisely that order. Quoting is -# there to prevent editors from complaining about space-tab. -# (If _AS_PATH_WALK were called with IFS unset, it would disable word -# splitting by setting IFS to empty value.) -IFS=" "" $as_nl" - -# Find who we are. Look in the path if we contain no directory separator. -as_myself= -case $0 in #(( - *[\\/]* ) as_myself=$0 ;; - *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break - done -IFS=$as_save_IFS - - ;; -esac -# We did not find ourselves, most probably we were run as `sh COMMAND' -# in which case we are not to be found in the path. -if test "x$as_myself" = x; then - as_myself=$0 -fi -if test ! -f "$as_myself"; then - $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 - exit 1 -fi - -# Unset variables that we do not need and which cause bugs (e.g. in -# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" -# suppresses any "Segmentation fault" message there. '((' could -# trigger a bug in pdksh 5.2.14. -for as_var in BASH_ENV ENV MAIL MAILPATH -do eval test x\${$as_var+set} = xset \ - && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : -done +# Work around bugs in pre-3.0 UWIN ksh. +$as_unset ENV MAIL MAILPATH PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. -LC_ALL=C -export LC_ALL -LANGUAGE=C -export LANGUAGE - -# CDPATH. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH - -# Use a proper internal environment variable to ensure we don't fall - # into an infinite loop, continuously re-executing ourselves. - if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then - _as_can_reexec=no; export _as_can_reexec; - # We cannot yet assume a decent shell, so we have to provide a -# neutralization value for shells without unset; and this also -# works around shells that cannot unset nonexistent variables. -# Preserve -v and -x to the replacement shell. -BASH_ENV=/dev/null -ENV=/dev/null -(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV -case $- in # (((( - *v*x* | *x*v* ) as_opts=-vx ;; - *v* ) as_opts=-v ;; - *x* ) as_opts=-x ;; - * ) as_opts= ;; -esac -exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} -# Admittedly, this is quite paranoid, since all the known shells bail -# out after a failed `exec'. -$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 -as_fn_exit 255 - fi - # We don't want this to propagate to other subprocesses. - { _as_can_reexec=; unset _as_can_reexec;} -if test "x$CONFIG_SHELL" = x; then - as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : - emulate sh - NULLCMD=: - # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which - # is contrary to our usage. Disable this feature. - alias -g '\${1+\"\$@\"}'='\"\$@\"' - setopt NO_GLOB_SUBST -else - case \`(set -o) 2>/dev/null\` in #( - *posix*) : - set -o posix ;; #( - *) : - ;; -esac -fi -" - as_required="as_fn_return () { (exit \$1); } -as_fn_success () { as_fn_return 0; } -as_fn_failure () { as_fn_return 1; } -as_fn_ret_success () { return 0; } -as_fn_ret_failure () { return 1; } - -exitcode=0 -as_fn_success || { exitcode=1; echo as_fn_success failed.; } -as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } -as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } -as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } -if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : - -else - exitcode=1; echo positional parameters were not saved. -fi -test x\$exitcode = x0 || exit 1 -test -x / || exit 1" - as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO - as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO - eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && - test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 -test \$(( 1 + 1 )) = 2 || exit 1" - if (eval "$as_required") 2>/dev/null; then : - as_have_required=yes -else - as_have_required=no -fi - if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : - -else - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -as_found=false -for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +for as_var in \ + LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ + LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ + LC_TELEPHONE LC_TIME do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - as_found=: - case $as_dir in #( - /*) - for as_base in sh bash ksh sh5; do - # Try only shells that exist, to save several forks. - as_shell=$as_dir/$as_base - if { test -f "$as_shell" || test -f "$as_shell.exe"; } && - { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : - CONFIG_SHELL=$as_shell as_have_required=yes - if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : - break 2 -fi -fi - done;; - esac - as_found=false -done -$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && - { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : - CONFIG_SHELL=$SHELL as_have_required=yes -fi; } -IFS=$as_save_IFS - - - if test "x$CONFIG_SHELL" != x; then : - export CONFIG_SHELL - # We cannot yet assume a decent shell, so we have to provide a -# neutralization value for shells without unset; and this also -# works around shells that cannot unset nonexistent variables. -# Preserve -v and -x to the replacement shell. -BASH_ENV=/dev/null -ENV=/dev/null -(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV -case $- in # (((( - *v*x* | *x*v* ) as_opts=-vx ;; - *v* ) as_opts=-v ;; - *x* ) as_opts=-x ;; - * ) as_opts= ;; -esac -exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} -# Admittedly, this is quite paranoid, since all the known shells bail -# out after a failed `exec'. -$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 -exit 255 -fi - - if test x$as_have_required = xno; then : - $as_echo "$0: This script requires a shell more modern than all" - $as_echo "$0: the shells that I found on your system." - if test x${ZSH_VERSION+set} = xset ; then - $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" - $as_echo "$0: be upgraded to zsh 4.3.4 or later." + if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var else - $as_echo "$0: Please tell bug-autoconf@gnu.org about your system, -$0: including any error possibly output before this -$0: message. Then install a modern shell, or manually run -$0: the script under such a shell if you do have one." - fi - exit 1 -fi -fi -fi -SHELL=${CONFIG_SHELL-/bin/sh} -export SHELL -# Unset more variables known to interfere with behavior of common tools. -CLICOLOR_FORCE= GREP_OPTIONS= -unset CLICOLOR_FORCE GREP_OPTIONS - -## --------------------- ## -## M4sh Shell Functions. ## -## --------------------- ## -# as_fn_unset VAR -# --------------- -# Portably unset VAR. -as_fn_unset () -{ - { eval $1=; unset $1;} -} -as_unset=as_fn_unset - -# as_fn_set_status STATUS -# ----------------------- -# Set $? to STATUS, without forking. -as_fn_set_status () -{ - return $1 -} # as_fn_set_status - -# as_fn_exit STATUS -# ----------------- -# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. -as_fn_exit () -{ - set +e - as_fn_set_status $1 - exit $1 -} # as_fn_exit - -# as_fn_mkdir_p -# ------------- -# Create "$as_dir" as a directory, including parents if necessary. -as_fn_mkdir_p () -{ - - case $as_dir in #( - -*) as_dir=./$as_dir;; - esac - test -d "$as_dir" || eval $as_mkdir_p || { - as_dirs= - while :; do - case $as_dir in #( - *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( - *) as_qdir=$as_dir;; - esac - as_dirs="'$as_qdir' $as_dirs" - as_dir=`$as_dirname -- "$as_dir" || -$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$as_dir" : 'X\(//\)[^/]' \| \ - X"$as_dir" : 'X\(//\)$' \| \ - X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$as_dir" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - test -d "$as_dir" && break - done - test -z "$as_dirs" || eval "mkdir $as_dirs" - } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" - - -} # as_fn_mkdir_p - -# as_fn_executable_p FILE -# ----------------------- -# Test if FILE is an executable regular file. -as_fn_executable_p () -{ - test -f "$1" && test -x "$1" -} # as_fn_executable_p -# as_fn_append VAR VALUE -# ---------------------- -# Append the text in VALUE to the end of the definition contained in VAR. Take -# advantage of any shell optimizations that allow amortized linear growth over -# repeated appends, instead of the typical quadratic growth present in naive -# implementations. -if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : - eval 'as_fn_append () - { - eval $1+=\$2 - }' -else - as_fn_append () - { - eval $1=\$$1\$2 - } -fi # as_fn_append - -# as_fn_arith ARG... -# ------------------ -# Perform arithmetic evaluation on the ARGs, and store the result in the -# global $as_val. Take advantage of shells that can avoid forks. The arguments -# must be portable across $(()) and expr. -if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : - eval 'as_fn_arith () - { - as_val=$(( $* )) - }' -else - as_fn_arith () - { - as_val=`expr "$@" || test $? -eq 1` - } -fi # as_fn_arith - - -# as_fn_error STATUS ERROR [LINENO LOG_FD] -# ---------------------------------------- -# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are -# provided, also output the error to LOG_FD, referencing LINENO. Then exit the -# script with STATUS, using 1 if that was 0. -as_fn_error () -{ - as_status=$1; test $as_status -eq 0 && as_status=1 - if test "$4"; then - as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + $as_unset $as_var fi - $as_echo "$as_me: error: $2" >&2 - as_fn_exit $as_status -} # as_fn_error +done -if expr a : '\(a\)' >/dev/null 2>&1 && - test "X`expr 00001 : '.*\(...\)'`" = X001; then +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1; then as_expr=expr else as_expr=false fi -if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then +if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi -if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then - as_dirname=dirname -else - as_dirname=false -fi -as_me=`$as_basename -- "$0" || +# Name of the executable. +as_me=`$as_basename "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X/"$0" | - sed '/^.*\/\([^/][^/]*\)\/*$/{ - s//\1/ - q - } - /^X\/\(\/\/\)$/{ - s//\1/ - q - } - /^X\/\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` + X"$0" : 'X\(/\)$' \| \ + . : '\(.\)' 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } + /^X\/\(\/\/\)$/{ s//\1/; q; } + /^X\/\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + +# PATH needs CR, and LINENO needs CR and PATH. # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' @@ -461,91 +83,146 @@ as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" || { + # Find who we are. Look in the path if we contain no path at all + # relative or not. + case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done + + ;; + esac + # We did not find ourselves, most probably we were run as `sh COMMAND' + # in which case we are not to be found in the path. + if test "x$as_myself" = x; then + as_myself=$0 + fi + if test ! -f "$as_myself"; then + { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2 + { (exit 1); exit 1; }; } + fi + case $CONFIG_SHELL in + '') + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for as_base in sh bash ksh sh5; do + case $as_dir in + /*) + if ("$as_dir/$as_base" -c ' + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then + $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } + $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } + CONFIG_SHELL=$as_dir/$as_base + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$0" ${1+"$@"} + fi;; + esac + done +done +;; + esac - as_lineno_1=$LINENO as_lineno_1a=$LINENO - as_lineno_2=$LINENO as_lineno_2a=$LINENO - eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && - test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { - # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) - sed -n ' - p - /[$]LINENO/= - ' <$as_myself | + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line before each line; the second 'sed' does the real + # work. The second script uses 'N' to pair each line-number line + # with the numbered line, and appends trailing '-' during + # substitution so that $LINENO is not a special case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) + sed '=' <$as_myself | sed ' - s/[$]LINENO.*/&-/ - t lineno - b - :lineno N - :loop - s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + s,$,-, + : loop + s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, t loop - s/-\n.*// + s,-$,, + s,^['$as_cr_digits']*\n,, ' >$as_me.lineno && - chmod +x "$as_me.lineno" || - { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } + chmod +x $as_me.lineno || + { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 + { (exit 1); exit 1; }; } - # If we had to re-execute with $CONFIG_SHELL, we're ensured to have - # already done that, so ensure we don't try to do so again and fall - # in an infinite loop. This has already happened in practice. - _as_can_reexec=no; export _as_can_reexec # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the - # original and so on. Autoconf is especially sensitive to this). - . "./$as_me.lineno" + # original and so on. Autoconf is especially sensible to this). + . ./$as_me.lineno # Exit status is that of the last command. exit } -ECHO_C= ECHO_N= ECHO_T= -case `echo -n x` in #((((( --n*) - case `echo 'xy\c'` in - *c*) ECHO_T=' ';; # ECHO_T is single tab character. - xy) ECHO_C='\c';; - *) echo `echo ksh88 bug on AIX 6.1` > /dev/null - ECHO_T=' ';; - esac;; -*) - ECHO_N='-n';; + +case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in + *c*,-n*) ECHO_N= ECHO_C=' +' ECHO_T=' ' ;; + *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; + *) ECHO_N= ECHO_C='\c' ECHO_T= ;; esac -rm -f conf$$ conf$$.exe conf$$.file -if test -d conf$$.dir; then - rm -f conf$$.dir/conf$$.file +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr else - rm -f conf$$.dir - mkdir conf$$.dir 2>/dev/null + as_expr=false fi -if (echo >conf$$.file) 2>/dev/null; then - if ln -s conf$$.file conf$$ 2>/dev/null; then - as_ln_s='ln -s' - # ... but there are two gotchas: - # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. - # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. - # In both cases, we have to default to `cp -pR'. - ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || - as_ln_s='cp -pR' - elif ln conf$$.file conf$$ 2>/dev/null; then - as_ln_s=ln + +rm -f conf$$ conf$$.exe conf$$.file +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + # We could just check for DJGPP; but this test a) works b) is more generic + # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). + if test -f conf$$.exe; then + # Don't use ln at all; we don't have any links + as_ln_s='cp -p' else - as_ln_s='cp -pR' + as_ln_s='ln -s' fi +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln else - as_ln_s='cp -pR' + as_ln_s='cp -p' fi -rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file -rmdir conf$$.dir 2>/dev/null +rm -f conf$$ conf$$.exe conf$$.file if mkdir -p . 2>/dev/null; then - as_mkdir_p='mkdir -p "$as_dir"' + as_mkdir_p=: else test -d ./-p && rmdir ./-p as_mkdir_p=false fi -as_test_x='test -x' -as_executable_p=as_fn_executable_p +as_executable_p="test -f" # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" @@ -554,25 +231,38 @@ as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" -test -n "$DJDIR" || exec 7<&0 &1 +# IFS +# We need space, tab and new line, in precisely that order. +as_nl=' +' +IFS=" $as_nl" + +# CDPATH. +$as_unset CDPATH + # Name of the host. -# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, +# hostname on some systems (SVR3.2, Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` +exec 6>&1 + # # Initializations. # ac_default_prefix=/usr/local -ac_clean_files= ac_config_libobj_dir=. -LIBOBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} + +# Maximum number of lines to put in a shell here document. +# This variable seems obsolete. It should probably be removed, and +# only ac_max_sed_lines should be used. +: ${ac_max_here_lines=38} # Identity of this package. PACKAGE_NAME='tcl' @@ -580,220 +270,50 @@ PACKAGE_TARNAME='tcl' PACKAGE_VERSION='8.6' PACKAGE_STRING='tcl 8.6' PACKAGE_BUGREPORT='' -PACKAGE_URL='' # Factoring default headers for most tests. ac_includes_default="\ #include -#ifdef HAVE_SYS_TYPES_H +#if HAVE_SYS_TYPES_H # include #endif -#ifdef HAVE_SYS_STAT_H +#if HAVE_SYS_STAT_H # include #endif -#ifdef STDC_HEADERS +#if STDC_HEADERS # include # include #else -# ifdef HAVE_STDLIB_H +# if HAVE_STDLIB_H # include # endif #endif -#ifdef HAVE_STRING_H -# if !defined STDC_HEADERS && defined HAVE_MEMORY_H +#if HAVE_STRING_H +# if !STDC_HEADERS && HAVE_MEMORY_H # include # endif # include #endif -#ifdef HAVE_STRINGS_H +#if HAVE_STRINGS_H # include #endif -#ifdef HAVE_INTTYPES_H +#if HAVE_INTTYPES_H # include +#else +# if HAVE_STDINT_H +# include +# endif #endif -#ifdef HAVE_STDINT_H -# include -#endif -#ifdef HAVE_UNISTD_H +#if HAVE_UNISTD_H # include #endif" -ac_subst_vars='DLTEST_SUFFIX -DLTEST_LD -EXTRA_TCLSH_LIBS -EXTRA_BUILD_HTML -EXTRA_INSTALL_BINARIES -EXTRA_INSTALL -EXTRA_APP_CC_SWITCHES -EXTRA_CC_SWITCHES -PACKAGE_DIR -HTML_DIR -PRIVATE_INCLUDE_DIR -TCL_LIBRARY -TCL_MODULE_PATH -TCL_PACKAGE_PATH -BUILD_DLTEST -MAKEFILE_SHELL -DTRACE_OBJ -DTRACE_HDR -DTRACE_SRC -INSTALL_TZDATA -TCL_HAS_LONGLONG -TCL_UNSHARED_LIB_SUFFIX -TCL_SHARED_LIB_SUFFIX -TCL_LIB_VERSIONS_OK -LD_LIBRARY_PATH_VAR -TCL_SHARED_BUILD -CFG_TCL_UNSHARED_LIB_SUFFIX -CFG_TCL_SHARED_LIB_SUFFIX -TCL_SRC_DIR -TCL_INCLUDE_SPEC -TCL_BUILD_KIT_LIB_PATH -TCL_BUILD_KIT_LIB_SPEC -TCL_KIT_LIB_PATH -TCL_KIT_LIB_SPEC -TCL_KIT_LIB_FLAG -TCL_KIT_LIB_FILE -TCL_BUILD_STUB_LIB_PATH -TCL_BUILD_STUB_LIB_SPEC -TCL_STUB_LIB_PATH -TCL_STUB_LIB_SPEC -TCL_STUB_LIB_FLAG -TCL_STUB_LIB_FILE -TCL_BUILD_LIB_SPEC -TCL_LIB_SPEC -TCL_LIB_FLAG -TCL_LIB_FILE -PKG_CFG_ARGS -TCL_YEAR -TCL_PATCH_LEVEL -TCL_MINOR_VERSION -TCL_MAJOR_VERSION -TCL_VERSION -DTRACE -LDFLAGS_DEFAULT -CFLAGS_DEFAULT -INSTALL_KIT_LIB -INSTALL_STUB_LIB -DLL_INSTALL_DIR -INSTALL_LIB -MAKE_STUB_LIB -MAKE_KIT_LIB -MAKE_LIB -SHLIB_SUFFIX -SHLIB_CFLAGS -SHLIB_LD_LIBS -TK_SHLIB_LD_EXTRAS -TCL_SHLIB_LD_EXTRAS -SHLIB_LD -STLIB_LD -LD_SEARCH_FLAGS -CC_SEARCH_FLAGS -LDFLAGS_OPTIMIZE -LDFLAGS_DEBUG -CFLAGS_WARNING -CFLAGS_OPTIMIZE -CFLAGS_DEBUG -LDAIX_SRC -PLAT_SRCS -PLAT_OBJS -DL_OBJS -DL_LIBS -TCL_LIBS -LIBOBJS -AR -RANLIB -ZLIB_INCLUDE -ZLIB_SRCS -ZLIB_OBJS -TCLSH_PROG -TCL_THREADS -EGREP -GREP -CPP -OBJEXT -EXEEXT -ac_ct_CC -CPPFLAGS -LDFLAGS -CFLAGS -CC -MAN_FLAGS -target_alias -host_alias -build_alias -LIBS -ECHO_T -ECHO_N -ECHO_C -DEFS -mandir -localedir -libdir -psdir -pdfdir -dvidir -htmldir -infodir -docdir -oldincludedir -includedir -localstatedir -sharedstatedir -sysconfdir -datadir -datarootdir -libexecdir -sbindir -bindir -program_transform_name -prefix -exec_prefix -PACKAGE_URL -PACKAGE_BUGREPORT -PACKAGE_STRING -PACKAGE_VERSION -PACKAGE_TARNAME -PACKAGE_NAME -PATH_SEPARATOR -SHELL' +ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS MAN_FLAGS CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CPP EGREP TCL_THREADS TCLSH_PROG ZLIB_OBJS ZLIB_SRCS ZLIB_INCLUDE RANLIB ac_ct_RANLIB AR ac_ct_AR LIBOBJS TCL_LIBS DL_LIBS DL_OBJS PLAT_OBJS PLAT_SRCS LDAIX_SRC CFLAGS_DEBUG CFLAGS_OPTIMIZE CFLAGS_WARNING LDFLAGS_DEBUG LDFLAGS_OPTIMIZE CC_SEARCH_FLAGS LD_SEARCH_FLAGS STLIB_LD SHLIB_LD TCL_SHLIB_LD_EXTRAS TK_SHLIB_LD_EXTRAS SHLIB_LD_LIBS SHLIB_CFLAGS SHLIB_SUFFIX MAKE_LIB MAKE_STUB_LIB INSTALL_LIB DLL_INSTALL_DIR INSTALL_STUB_LIB CFLAGS_DEFAULT LDFLAGS_DEFAULT DTRACE TCL_VERSION TCL_MAJOR_VERSION TCL_MINOR_VERSION TCL_PATCH_LEVEL TCL_YEAR PKG_CFG_ARGS TCL_LIB_FILE TCL_LIB_FLAG TCL_LIB_SPEC TCL_STUB_LIB_FILE TCL_STUB_LIB_FLAG TCL_STUB_LIB_SPEC TCL_STUB_LIB_PATH TCL_INCLUDE_SPEC TCL_BUILD_STUB_LIB_SPEC TCL_BUILD_STUB_LIB_PATH TCL_SRC_DIR CFG_TCL_SHARED_LIB_SUFFIX CFG_TCL_UNSHARED_LIB_SUFFIX TCL_SHARED_BUILD LD_LIBRARY_PATH_VAR TCL_BUILD_LIB_SPEC TCL_LIB_VERSIONS_OK TCL_SHARED_LIB_SUFFIX TCL_UNSHARED_LIB_SUFFIX TCL_HAS_LONGLONG INSTALL_TZDATA DTRACE_SRC DTRACE_HDR DTRACE_OBJ MAKEFILE_SHELL BUILD_DLTEST TCL_PACKAGE_PATH TCL_MODULE_PATH TCL_LIBRARY PRIVATE_INCLUDE_DIR HTML_DIR PACKAGE_DIR EXTRA_CC_SWITCHES EXTRA_APP_CC_SWITCHES EXTRA_INSTALL EXTRA_INSTALL_BINARIES EXTRA_BUILD_HTML EXTRA_TCLSH_LIBS DLTEST_LD DLTEST_SUFFIX' ac_subst_files='' -ac_user_opts=' -enable_option_checking -enable_man_symlinks -enable_man_compression -enable_man_suffix -enable_threads -with_encoding -enable_shared -enable_64bit -enable_64bit_vis -enable_rpath -enable_corefoundation -enable_load -enable_symbols -enable_langinfo -enable_dll_unloading -with_tzdata -enable_dtrace -enable_framework -' - ac_precious_vars='build_alias -host_alias -target_alias -CC -CFLAGS -LDFLAGS -LIBS -CPPFLAGS -CPP' - # Initialize some variables set by options. ac_init_help= ac_init_version=false -ac_unrecognized_opts= -ac_unrecognized_sep= # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null @@ -816,49 +336,34 @@ x_libraries=NONE # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. -# (The list follows the same order as the GNU Coding Standards.) bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' -datarootdir='${prefix}/share' -datadir='${datarootdir}' +datadir='${prefix}/share' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' +libdir='${exec_prefix}/lib' includedir='${prefix}/include' oldincludedir='/usr/include' -docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' -infodir='${datarootdir}/info' -htmldir='${docdir}' -dvidir='${docdir}' -pdfdir='${docdir}' -psdir='${docdir}' -libdir='${exec_prefix}/lib' -localedir='${datarootdir}/locale' -mandir='${datarootdir}/man' +infodir='${prefix}/info' +mandir='${prefix}/man' ac_prev= -ac_dashdash= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then - eval $ac_prev=\$ac_option + eval "$ac_prev=\$ac_option" ac_prev= continue fi - case $ac_option in - *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; - *=) ac_optarg= ;; - *) ac_optarg=yes ;; - esac + ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'` # Accept the important Cygnus configure options, so we can diagnose typos. - case $ac_dashdash$ac_option in - --) - ac_dashdash=yes ;; + case $ac_option in -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; @@ -880,59 +385,33 @@ do --config-cache | -C) cache_file=config.cache ;; - -datadir | --datadir | --datadi | --datad) + -datadir | --datadir | --datadi | --datad | --data | --dat | --da) ac_prev=datadir ;; - -datadir=* | --datadir=* | --datadi=* | --datad=*) + -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ + | --da=*) datadir=$ac_optarg ;; - -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ - | --dataroo | --dataro | --datar) - ac_prev=datarootdir ;; - -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ - | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) - datarootdir=$ac_optarg ;; - -disable-* | --disable-*) - ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. - expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid feature name: $ac_useropt" - ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` - case $ac_user_opts in - *" -"enable_$ac_useropt" -"*) ;; - *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" - ac_unrecognized_sep=', ';; - esac - eval enable_$ac_useropt=no ;; - - -docdir | --docdir | --docdi | --doc | --do) - ac_prev=docdir ;; - -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) - docdir=$ac_optarg ;; - - -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) - ac_prev=dvidir ;; - -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) - dvidir=$ac_optarg ;; + expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/-/_/g'` + eval "enable_$ac_feature=no" ;; -enable-* | --enable-*) - ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. - expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid feature name: $ac_useropt" - ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` - case $ac_user_opts in - *" -"enable_$ac_useropt" -"*) ;; - *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" - ac_unrecognized_sep=', ';; + expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/-/_/g'` + case $ac_option in + *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; + *) ac_optarg=yes ;; esac - eval enable_$ac_useropt=\$ac_optarg ;; + eval "enable_$ac_feature='$ac_optarg'" ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ @@ -959,12 +438,6 @@ do -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; - -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) - ac_prev=htmldir ;; - -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ - | --ht=*) - htmldir=$ac_optarg ;; - -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; @@ -989,16 +462,13 @@ do | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; - -localedir | --localedir | --localedi | --localed | --locale) - ac_prev=localedir ;; - -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) - localedir=$ac_optarg ;; - -localstatedir | --localstatedir | --localstatedi | --localstated \ - | --localstate | --localstat | --localsta | --localst | --locals) + | --localstate | --localstat | --localsta | --localst \ + | --locals | --local | --loca | --loc | --lo) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ - | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) + | --localstate=* | --localstat=* | --localsta=* | --localst=* \ + | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) @@ -1063,16 +533,6 @@ do | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; - -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) - ac_prev=pdfdir ;; - -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) - pdfdir=$ac_optarg ;; - - -psdir | --psdir | --psdi | --psd | --ps) - ac_prev=psdir ;; - -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) - psdir=$ac_optarg ;; - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; @@ -1123,36 +583,26 @@ do ac_init_version=: ;; -with-* | --with-*) - ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. - expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid package name: $ac_useropt" - ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` - case $ac_user_opts in - *" -"with_$ac_useropt" -"*) ;; - *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" - ac_unrecognized_sep=', ';; + expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package| sed 's/-/_/g'` + case $ac_option in + *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; + *) ac_optarg=yes ;; esac - eval with_$ac_useropt=\$ac_optarg ;; + eval "with_$ac_package='$ac_optarg'" ;; -without-* | --without-*) - ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` + ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. - expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid package name: $ac_useropt" - ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` - case $ac_user_opts in - *" -"with_$ac_useropt" -"*) ;; - *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" - ac_unrecognized_sep=', ';; - esac - eval with_$ac_useropt=no ;; + expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package | sed 's/-/_/g'` + eval "with_$ac_package=no" ;; --x) # Obsolete; use --with-x. @@ -1172,26 +622,27 @@ do | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; - -*) as_fn_error $? "unrecognized option: \`$ac_option' -Try \`$0 --help' for more information" + -*) { echo "$as_me: error: unrecognized option: $ac_option +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; } ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. - case $ac_envvar in #( - '' | [0-9]* | *[!_$as_cr_alnum]* ) - as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; - esac - eval $ac_envvar=\$ac_optarg + expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 + { (exit 1); exit 1; }; } + ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` + eval "$ac_envvar='$ac_optarg'" export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. - $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && - $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 - : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" + echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} ;; esac @@ -1199,36 +650,31 @@ done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` - as_fn_error $? "missing argument to $ac_option" -fi - -if test -n "$ac_unrecognized_opts"; then - case $enable_option_checking in - no) ;; - fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; - *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; - esac + { echo "$as_me: error: missing argument to $ac_option" >&2 + { (exit 1); exit 1; }; } fi -# Check all directory arguments for consistency. -for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ - datadir sysconfdir sharedstatedir localstatedir includedir \ - oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ - libdir localedir mandir +# Be sure to have absolute paths. +for ac_var in exec_prefix prefix do - eval ac_val=\$$ac_var - # Remove trailing slashes. + eval ac_val=$`echo $ac_var` case $ac_val in - */ ) - ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` - eval $ac_var=\$ac_val;; + [\\/$]* | ?:[\\/]* | NONE | '' ) ;; + *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 + { (exit 1); exit 1; }; };; esac - # Be sure to have absolute directory names. +done + +# Be sure to have absolute paths. +for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \ + localstatedir libdir includedir oldincludedir infodir mandir +do + eval ac_val=$`echo $ac_var` case $ac_val in - [\\/$]* | ?:[\\/]* ) continue;; - NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + [\\/$]* | ?:[\\/]* ) ;; + *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 + { (exit 1); exit 1; }; };; esac - as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" done # There might be people who depend on the old broken behavior: `$host' @@ -1242,6 +688,8 @@ target=$target_alias if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe + echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. + If a cross compiler is detected then cross compile mode will be used." >&2 elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi @@ -1253,72 +701,74 @@ test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null -ac_pwd=`pwd` && test -n "$ac_pwd" && -ac_ls_di=`ls -di .` && -ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || - as_fn_error $? "working directory cannot be determined" -test "X$ac_ls_di" = "X$ac_pwd_ls_di" || - as_fn_error $? "pwd does not report name of working directory" - - # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes - # Try the directory containing this script, then the parent directory. - ac_confdir=`$as_dirname -- "$as_myself" || -$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$as_myself" : 'X\(//\)[^/]' \| \ - X"$as_myself" : 'X\(//\)$' \| \ - X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$as_myself" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` + # Try the directory containing this script, then its parent. + ac_confdir=`(dirname "$0") 2>/dev/null || +$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$0" : 'X\(//\)[^/]' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$0" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` srcdir=$ac_confdir - if test ! -r "$srcdir/$ac_unique_file"; then + if test ! -r $srcdir/$ac_unique_file; then srcdir=.. fi else ac_srcdir_defaulted=no fi -if test ! -r "$srcdir/$ac_unique_file"; then - test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." - as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" -fi -ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" -ac_abs_confdir=`( - cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" - pwd)` -# When building in place, set srcdir=. -if test "$ac_abs_confdir" = "$ac_pwd"; then - srcdir=. -fi -# Remove unnecessary trailing slashes from srcdir. -# Double slashes in file names in object file debugging info -# mess up M-x gdb in Emacs. -case $srcdir in -*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; -esac -for ac_var in $ac_precious_vars; do - eval ac_env_${ac_var}_set=\${${ac_var}+set} - eval ac_env_${ac_var}_value=\$${ac_var} - eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} - eval ac_cv_env_${ac_var}_value=\$${ac_var} -done +if test ! -r $srcdir/$ac_unique_file; then + if test "$ac_srcdir_defaulted" = yes; then + { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2 + { (exit 1); exit 1; }; } + else + { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 + { (exit 1); exit 1; }; } + fi +fi +(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null || + { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2 + { (exit 1); exit 1; }; } +srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'` +ac_env_build_alias_set=${build_alias+set} +ac_env_build_alias_value=$build_alias +ac_cv_env_build_alias_set=${build_alias+set} +ac_cv_env_build_alias_value=$build_alias +ac_env_host_alias_set=${host_alias+set} +ac_env_host_alias_value=$host_alias +ac_cv_env_host_alias_set=${host_alias+set} +ac_cv_env_host_alias_value=$host_alias +ac_env_target_alias_set=${target_alias+set} +ac_env_target_alias_value=$target_alias +ac_cv_env_target_alias_set=${target_alias+set} +ac_cv_env_target_alias_value=$target_alias +ac_env_CC_set=${CC+set} +ac_env_CC_value=$CC +ac_cv_env_CC_set=${CC+set} +ac_cv_env_CC_value=$CC +ac_env_CFLAGS_set=${CFLAGS+set} +ac_env_CFLAGS_value=$CFLAGS +ac_cv_env_CFLAGS_set=${CFLAGS+set} +ac_cv_env_CFLAGS_value=$CFLAGS +ac_env_LDFLAGS_set=${LDFLAGS+set} +ac_env_LDFLAGS_value=$LDFLAGS +ac_cv_env_LDFLAGS_set=${LDFLAGS+set} +ac_cv_env_LDFLAGS_value=$LDFLAGS +ac_env_CPPFLAGS_set=${CPPFLAGS+set} +ac_env_CPPFLAGS_value=$CPPFLAGS +ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set} +ac_cv_env_CPPFLAGS_value=$CPPFLAGS +ac_env_CPP_set=${CPP+set} +ac_env_CPP_value=$CPP +ac_cv_env_CPP_set=${CPP+set} +ac_cv_env_CPP_value=$CPP # # Report the --help message. @@ -1341,17 +791,20 @@ Configuration: --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit - -q, --quiet, --silent do not print \`checking ...' messages + -q, --quiet, --silent do not print \`checking...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] +_ACEOF + + cat <<_ACEOF Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX - [$ac_default_prefix] + [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX - [PREFIX] + [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify @@ -1361,25 +814,18 @@ for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: - --bindir=DIR user executables [EPREFIX/bin] - --sbindir=DIR system admin executables [EPREFIX/sbin] - --libexecdir=DIR program executables [EPREFIX/libexec] - --sysconfdir=DIR read-only single-machine data [PREFIX/etc] - --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] - --localstatedir=DIR modifiable single-machine data [PREFIX/var] - --libdir=DIR object code libraries [EPREFIX/lib] - --includedir=DIR C header files [PREFIX/include] - --oldincludedir=DIR C header files for non-gcc [/usr/include] - --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] - --datadir=DIR read-only architecture-independent data [DATAROOTDIR] - --infodir=DIR info documentation [DATAROOTDIR/info] - --localedir=DIR locale-dependent data [DATAROOTDIR/locale] - --mandir=DIR man documentation [DATAROOTDIR/man] - --docdir=DIR documentation root [DATAROOTDIR/doc/tcl] - --htmldir=DIR html documentation [DOCDIR] - --dvidir=DIR dvi documentation [DOCDIR] - --pdfdir=DIR pdf documentation [DOCDIR] - --psdir=DIR ps documentation [DOCDIR] + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --datadir=DIR read-only architecture-independent data [PREFIX/share] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --infodir=DIR info documentation [PREFIX/info] + --mandir=DIR man documentation [PREFIX/man] _ACEOF cat <<\_ACEOF @@ -1393,7 +839,6 @@ if test -n "$ac_init_help"; then cat <<\_ACEOF Optional Features: - --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --enable-man-symlinks use symlinks for the manpages (default: off) @@ -1431,593 +876,160 @@ Some influential environment variables: CFLAGS C compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory - LIBS libraries to pass to the linker, e.g. -l - CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if - you have headers in a nonstandard directory + CPPFLAGS C/C++ preprocessor flags, e.g. -I if you have + headers in a nonstandard directory CPP C preprocessor Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. -Report bugs to the package provider. _ACEOF -ac_status=$? fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. + ac_popdir=`pwd` for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue - test -d "$ac_dir" || - { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || - continue + test -d $ac_dir || continue ac_builddir=. -case "$ac_dir" in -.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; -*) - ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` - # A ".." for each directory in $ac_dir_suffix. - ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` - case $ac_top_builddir_sub in - "") ac_top_builddir_sub=. ac_top_build_prefix= ;; - *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; - esac ;; -esac -ac_abs_top_builddir=$ac_pwd -ac_abs_builddir=$ac_pwd$ac_dir_suffix -# for backward compatibility: -ac_top_builddir=$ac_top_build_prefix +if test "$ac_dir" != .; then + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A "../" for each directory in $ac_dir_suffix. + ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` +else + ac_dir_suffix= ac_top_builddir= +fi case $srcdir in - .) # We are building in place. + .) # No --srcdir option. We are building in place. ac_srcdir=. - ac_top_srcdir=$ac_top_builddir_sub - ac_abs_top_srcdir=$ac_pwd ;; - [\\/]* | ?:[\\/]* ) # Absolute name. + if test -z "$ac_top_builddir"; then + ac_top_srcdir=. + else + ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` + fi ;; + [\\/]* | ?:[\\/]* ) # Absolute path. ac_srcdir=$srcdir$ac_dir_suffix; - ac_top_srcdir=$srcdir - ac_abs_top_srcdir=$srcdir ;; - *) # Relative name. - ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix - ac_top_srcdir=$ac_top_build_prefix$srcdir - ac_abs_top_srcdir=$ac_pwd/$srcdir ;; + ac_top_srcdir=$srcdir ;; + *) # Relative path. + ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_builddir$srcdir ;; +esac + +# Do not use `cd foo && pwd` to compute absolute paths, because +# the directories may not exist. +case `pwd` in +.) ac_abs_builddir="$ac_dir";; +*) + case "$ac_dir" in + .) ac_abs_builddir=`pwd`;; + [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; + *) ac_abs_builddir=`pwd`/"$ac_dir";; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_builddir=${ac_top_builddir}.;; +*) + case ${ac_top_builddir}. in + .) ac_abs_top_builddir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; + *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; + esac;; esac -ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix - - cd "$ac_dir" || { ac_status=$?; continue; } - # Check for guested configure. - if test -f "$ac_srcdir/configure.gnu"; then - echo && - $SHELL "$ac_srcdir/configure.gnu" --help=recursive - elif test -f "$ac_srcdir/configure"; then - echo && - $SHELL "$ac_srcdir/configure" --help=recursive +case $ac_abs_builddir in +.) ac_abs_srcdir=$ac_srcdir;; +*) + case $ac_srcdir in + .) ac_abs_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; + *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_srcdir=$ac_top_srcdir;; +*) + case $ac_top_srcdir in + .) ac_abs_top_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; + *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; + esac;; +esac + + cd $ac_dir + # Check for guested configure; otherwise get Cygnus style configure. + if test -f $ac_srcdir/configure.gnu; then + echo + $SHELL $ac_srcdir/configure.gnu --help=recursive + elif test -f $ac_srcdir/configure; then + echo + $SHELL $ac_srcdir/configure --help=recursive + elif test -f $ac_srcdir/configure.ac || + test -f $ac_srcdir/configure.in; then + echo + $ac_configure --help else - $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 - fi || ac_status=$? - cd "$ac_pwd" || { ac_status=$?; break; } + echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi + cd $ac_popdir done fi -test -n "$ac_init_help" && exit $ac_status +test -n "$ac_init_help" && exit 0 if $ac_init_version; then cat <<\_ACEOF tcl configure 8.6 -generated by GNU Autoconf 2.69 +generated by GNU Autoconf 2.59 -Copyright (C) 2012 Free Software Foundation, Inc. +Copyright (C) 2003 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF - exit + exit 0 fi +exec 5>config.log +cat >&5 <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by tcl $as_me 8.6, which was +generated by GNU Autoconf 2.59. Invocation command line was -## ------------------------ ## -## Autoconf initialization. ## -## ------------------------ ## + $ $0 $@ -# ac_fn_c_try_compile LINENO -# -------------------------- -# Try to compile conftest.$ac_ext, and return whether this succeeded. -ac_fn_c_try_compile () +_ACEOF { - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - rm -f conftest.$ac_objext - if { { ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_compile") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - grep -v '^ *+' conftest.err >conftest.er1 - cat conftest.er1 >&5 - mv -f conftest.er1 conftest.err - fi - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then : - ac_retval=0 -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## - ac_retval=1 -fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` -} # ac_fn_c_try_compile +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` -# ac_fn_c_try_link LINENO -# ----------------------- -# Try to link conftest.$ac_ext, and return whether this succeeded. -ac_fn_c_try_link () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - rm -f conftest.$ac_objext conftest$ac_exeext - if { { ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_link") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - grep -v '^ *+' conftest.err >conftest.er1 - cat conftest.er1 >&5 - mv -f conftest.er1 conftest.err - fi - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && { - test "$cross_compiling" = yes || - test -x conftest$ac_exeext - }; then : - ac_retval=0 -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=1 -fi - # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information - # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would - # interfere with the next link command; also delete a directory that is - # left behind by Apple's compiler. We do this before executing the actions. - rm -rf conftest.dSYM conftest_ipa8_conftest.oo - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval - -} # ac_fn_c_try_link - -# ac_fn_c_try_cpp LINENO -# ---------------------- -# Try to preprocess conftest.$ac_ext, and return whether this succeeded. -ac_fn_c_try_cpp () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - if { { ac_try="$ac_cpp conftest.$ac_ext" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - grep -v '^ *+' conftest.err >conftest.er1 - cat conftest.er1 >&5 - mv -f conftest.er1 conftest.err - fi - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } > conftest.i && { - test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || - test ! -s conftest.err - }; then : - ac_retval=0 -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +hostinfo = `(hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` - ac_retval=1 -fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval +_ASUNAME -} # ac_fn_c_try_cpp - -# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES -# ------------------------------------------------------- -# Tests whether HEADER exists, giving a warning if it cannot be compiled using -# the include files in INCLUDES and setting the cache variable VAR -# accordingly. -ac_fn_c_check_header_mongrel () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - if eval \${$3+:} false; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -$as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : - $as_echo_n "(cached) " >&6 -fi -eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -else - # Is the header compilable? -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 -$as_echo_n "checking $2 usability... " >&6; } -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -#include <$2> -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_header_compiler=yes -else - ac_header_compiler=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 -$as_echo "$ac_header_compiler" >&6; } - -# Is the header present? -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 -$as_echo_n "checking $2 presence... " >&6; } -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <$2> -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - ac_header_preproc=yes -else - ac_header_preproc=no -fi -rm -f conftest.err conftest.i conftest.$ac_ext -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 -$as_echo "$ac_header_preproc" >&6; } - -# So? What about this header? -case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( - yes:no: ) - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 -$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 -$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} - ;; - no:yes:* ) - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 -$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 -$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 -$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 -$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 -$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} - ;; -esac - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -$as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : - $as_echo_n "(cached) " >&6 -else - eval "$3=\$ac_header_compiler" -fi -eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - -} # ac_fn_c_check_header_mongrel - -# ac_fn_c_try_run LINENO -# ---------------------- -# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes -# that executables *can* be run. -ac_fn_c_try_run () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - if { { ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' - { { case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; }; then : - ac_retval=0 -else - $as_echo "$as_me: program exited with status $ac_status" >&5 - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=$ac_status -fi - rm -rf conftest.dSYM conftest_ipa8_conftest.oo - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval - -} # ac_fn_c_try_run - -# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES -# ------------------------------------------------------- -# Tests whether HEADER exists and can be compiled using the include files in -# INCLUDES, setting the cache variable VAR accordingly. -ac_fn_c_check_header_compile () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -$as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -#include <$2> -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - eval "$3=yes" -else - eval "$3=no" -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - -} # ac_fn_c_check_header_compile - -# ac_fn_c_check_func LINENO FUNC VAR -# ---------------------------------- -# Tests whether FUNC exists, setting the cache variable VAR accordingly -ac_fn_c_check_func () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -$as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -/* Define $2 to an innocuous variant, in case declares $2. - For example, HP-UX 11i declares gettimeofday. */ -#define $2 innocuous_$2 - -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char $2 (); below. - Prefer to if __STDC__ is defined, since - exists even on freestanding compilers. */ - -#ifdef __STDC__ -# include -#else -# include -#endif - -#undef $2 - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char $2 (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined __stub_$2 || defined __stub___$2 -choke me -#endif - -int -main () -{ -return $2 (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - eval "$3=yes" -else - eval "$3=no" -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -fi -eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - -} # ac_fn_c_check_func - -# ac_fn_c_check_type LINENO TYPE VAR INCLUDES -# ------------------------------------------- -# Tests whether TYPE exists after having included INCLUDES, setting cache -# variable VAR accordingly. -ac_fn_c_check_type () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -$as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : - $as_echo_n "(cached) " >&6 -else - eval "$3=no" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -int -main () -{ -if (sizeof ($2)) - return 0; - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -int -main () -{ -if (sizeof (($2))) - return 0; - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - -else - eval "$3=yes" -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - -} # ac_fn_c_check_type - -# ac_fn_c_check_member LINENO AGGR MEMBER VAR INCLUDES -# ---------------------------------------------------- -# Tries to find if the field MEMBER exists in type AGGR, after including -# INCLUDES, setting cache variable VAR accordingly. -ac_fn_c_check_member () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2.$3" >&5 -$as_echo_n "checking for $2.$3... " >&6; } -if eval \${$4+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$5 -int -main () -{ -static $2 ac_aggr; -if (ac_aggr.$3) -return 0; - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - eval "$4=yes" -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$5 -int -main () -{ -static $2 ac_aggr; -if (sizeof ac_aggr.$3) -return 0; - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - eval "$4=yes" -else - eval "$4=no" -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -eval ac_res=\$$4 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - -} # ac_fn_c_check_member -cat >config.log <<_ACEOF -This file contains any messages produced by compilers while -running configure, to aid debugging if configure makes a mistake. - -It was created by tcl $as_me 8.6, which was -generated by GNU Autoconf 2.69. Invocation command line was - - $ $0 $@ - -_ACEOF -exec 5>>config.log -{ -cat <<_ASUNAME -## --------- ## -## Platform. ## -## --------- ## - -hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` -uname -m = `(uname -m) 2>/dev/null || echo unknown` -uname -r = `(uname -r) 2>/dev/null || echo unknown` -uname -s = `(uname -s) 2>/dev/null || echo unknown` -uname -v = `(uname -v) 2>/dev/null || echo unknown` - -/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` -/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` - -/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` -/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` -/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` -/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` -/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` -/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` -/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` - -_ASUNAME - -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - $as_echo "PATH: $as_dir" - done -IFS=$as_save_IFS +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + echo "PATH: $as_dir" +done } >&5 @@ -2039,6 +1051,7 @@ _ACEOF ac_configure_args= ac_configure_args0= ac_configure_args1= +ac_sep= ac_must_keep_next=false for ac_pass in 1 2 do @@ -2049,13 +1062,13 @@ do -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; - *\'*) - ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) + ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in - 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; + 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; 2) - as_fn_append ac_configure_args1 " '$ac_arg'" + ac_configure_args1="$ac_configure_args1 '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else @@ -2071,115 +1084,104 @@ do -* ) ac_must_keep_next=true ;; esac fi - as_fn_append ac_configure_args " '$ac_arg'" + ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'" + # Get rid of the leading space. + ac_sep=" " ;; esac done done -{ ac_configure_args0=; unset ac_configure_args0;} -{ ac_configure_args1=; unset ac_configure_args1;} +$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } +$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; } # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. -# WARNING: Use '\'' to represent an apostrophe within the trap. -# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. +# WARNING: Be sure not to use single quotes in there, as some shells, +# such as our DU 5.0 friend, will then `close' the trap. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo - $as_echo "## ---------------- ## + cat <<\_ASBOX +## ---------------- ## ## Cache variables. ## -## ---------------- ##" +## ---------------- ## +_ASBOX echo # The following way of writing the cache mishandles newlines in values, -( - for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do - eval ac_val=\$$ac_var - case $ac_val in #( - *${as_nl}*) - case $ac_var in #( - *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 -$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; - esac - case $ac_var in #( - _ | IFS | as_nl) ;; #( - BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( - *) { eval $ac_var=; unset $ac_var;} ;; - esac ;; - esac - done +{ (set) 2>&1 | - case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( - *${as_nl}ac_space=\ *) + case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in + *ac_space=\ *) sed -n \ - "s/'\''/'\''\\\\'\'''\''/g; - s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" - ;; #( + "s/'"'"'/'"'"'\\\\'"'"''"'"'/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p" + ;; *) - sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + sed -n \ + "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" ;; - esac | - sort -) + esac; +} echo - $as_echo "## ----------------- ## + cat <<\_ASBOX +## ----------------- ## ## Output variables. ## -## ----------------- ##" +## ----------------- ## +_ASBOX echo for ac_var in $ac_subst_vars do - eval ac_val=\$$ac_var - case $ac_val in - *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; - esac - $as_echo "$ac_var='\''$ac_val'\''" + eval ac_val=$`echo $ac_var` + echo "$ac_var='"'"'$ac_val'"'"'" done | sort echo if test -n "$ac_subst_files"; then - $as_echo "## ------------------- ## -## File substitutions. ## -## ------------------- ##" + cat <<\_ASBOX +## ------------- ## +## Output files. ## +## ------------- ## +_ASBOX echo for ac_var in $ac_subst_files do - eval ac_val=\$$ac_var - case $ac_val in - *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; - esac - $as_echo "$ac_var='\''$ac_val'\''" + eval ac_val=$`echo $ac_var` + echo "$ac_var='"'"'$ac_val'"'"'" done | sort echo fi if test -s confdefs.h; then - $as_echo "## ----------- ## + cat <<\_ASBOX +## ----------- ## ## confdefs.h. ## -## ----------- ##" +## ----------- ## +_ASBOX echo - cat confdefs.h + sed "/^$/d" confdefs.h | sort echo fi test "$ac_signal" != 0 && - $as_echo "$as_me: caught signal $ac_signal" - $as_echo "$as_me: exit $exit_status" + echo "$as_me: caught signal $ac_signal" + echo "$as_me: exit $exit_status" } >&5 - rm -f core *.core core.conftest.* && - rm -f -r conftest* confdefs* conf$$* $ac_clean_files && + rm -f core *.core && + rm -rf conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status -' 0 + ' 0 for ac_signal in 1 2 13 15; do - trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal + trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. -rm -f -r conftest* confdefs.h - -$as_echo "/* confdefs.h */" > confdefs.h +rm -rf conftest* confdefs.h +# AIX cpp loses on an empty file, so make sure it contains at least a newline. +echo >confdefs.h # Predefined preprocessor variables. @@ -2187,137 +1189,112 @@ cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF + cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF + cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF + cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF -cat >>confdefs.h <<_ACEOF -#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" -_ACEOF cat >>confdefs.h <<_ACEOF -#define PACKAGE_URL "$PACKAGE_URL" +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF # Let the site file select an alternate cache file if it wants to. -# Prefer an explicitly selected file to automatically selected ones. -ac_site_file1=NONE -ac_site_file2=NONE -if test -n "$CONFIG_SITE"; then - # We do not want a PATH search for config.site. - case $CONFIG_SITE in #(( - -*) ac_site_file1=./$CONFIG_SITE;; - */*) ac_site_file1=$CONFIG_SITE;; - *) ac_site_file1=./$CONFIG_SITE;; - esac -elif test "x$prefix" != xNONE; then - ac_site_file1=$prefix/share/config.site - ac_site_file2=$prefix/etc/config.site -else - ac_site_file1=$ac_default_prefix/share/config.site - ac_site_file2=$ac_default_prefix/etc/config.site +# Prefer explicitly selected file to automatically selected ones. +if test -z "$CONFIG_SITE"; then + if test "x$prefix" != xNONE; then + CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" + else + CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" + fi fi -for ac_site_file in "$ac_site_file1" "$ac_site_file2" -do - test "x$ac_site_file" = xNONE && continue - if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 -$as_echo "$as_me: loading site script $ac_site_file" >&6;} +for ac_site_file in $CONFIG_SITE; do + if test -r "$ac_site_file"; then + { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 +echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 - . "$ac_site_file" \ - || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "failed to load site script $ac_site_file -See \`config.log' for more details" "$LINENO" 5; } + . "$ac_site_file" fi done if test -r "$cache_file"; then - # Some versions of bash will fail to source /dev/null (special files - # actually), so we avoid doing that. DJGPP emulates it as a regular file. - if test /dev/null != "$cache_file" && test -f "$cache_file"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 -$as_echo "$as_me: loading cache $cache_file" >&6;} + # Some versions of bash will fail to source /dev/null (special + # files actually), so we avoid doing that. + if test -f "$cache_file"; then + { echo "$as_me:$LINENO: loading cache $cache_file" >&5 +echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in - [\\/]* | ?:[\\/]* ) . "$cache_file";; - *) . "./$cache_file";; + [\\/]* | ?:[\\/]* ) . $cache_file;; + *) . ./$cache_file;; esac fi else - { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 -$as_echo "$as_me: creating cache $cache_file" >&6;} + { echo "$as_me:$LINENO: creating cache $cache_file" >&5 +echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false -for ac_var in $ac_precious_vars; do +for ac_var in `(set) 2>&1 | + sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set - eval ac_old_val=\$ac_cv_env_${ac_var}_value - eval ac_new_val=\$ac_env_${ac_var}_value + eval ac_old_val="\$ac_cv_env_${ac_var}_value" + eval ac_new_val="\$ac_env_${ac_var}_value" case $ac_old_set,$ac_new_set in set,) - { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 -$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) - { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 -$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 +echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then - # differences in whitespace do not lead to failure. - ac_old_val_w=`echo x $ac_old_val` - ac_new_val_w=`echo x $ac_new_val` - if test "$ac_old_val_w" != "$ac_new_val_w"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 -$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} - ac_cache_corrupted=: - else - { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 -$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} - eval $ac_var=\$ac_old_val - fi - { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 -$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 -$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} + { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 +echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 +echo "$as_me: former value: $ac_old_val" >&2;} + { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 +echo "$as_me: current value: $ac_new_val" >&2;} + ac_cache_corrupted=: fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in - *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) + ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. - *) as_fn_append ac_configure_args " '$ac_arg'" ;; + *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then - { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 -$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} - as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 + { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 +echo "$as_me: error: changes in the environment can compromise the build" >&2;} + { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 +echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} + { (exit 1); exit 1; }; } fi -## -------------------- ## -## Main body of script. ## -## -------------------- ## ac_ext=c ac_cpp='$CPP $CPPFLAGS' @@ -2330,6 +1307,31 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + + + + + + + + + + + + + + + + + + + + + + + TCL_VERSION=8.6 TCL_MAJOR_VERSION=8 TCL_MINOR_VERSION=6 @@ -2380,60 +1382,62 @@ TCL_SRC_DIR="`cd "$srcdir"/..; pwd`" #------------------------------------------------------------------------ - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use symlinks for manpages" >&5 -$as_echo_n "checking whether to use symlinks for manpages... " >&6; } - # Check whether --enable-man-symlinks was given. -if test "${enable_man_symlinks+set}" = set; then : - enableval=$enable_man_symlinks; test "$enableval" != "no" && MAN_FLAGS="$MAN_FLAGS --symlinks" + echo "$as_me:$LINENO: checking whether to use symlinks for manpages" >&5 +echo $ECHO_N "checking whether to use symlinks for manpages... $ECHO_C" >&6 + # Check whether --enable-man-symlinks or --disable-man-symlinks was given. +if test "${enable_man_symlinks+set}" = set; then + enableval="$enable_man_symlinks" + test "$enableval" != "no" && MAN_FLAGS="$MAN_FLAGS --symlinks" else enableval="no" -fi - - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enableval" >&5 -$as_echo "$enableval" >&6; } - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to compress the manpages" >&5 -$as_echo_n "checking whether to compress the manpages... " >&6; } - # Check whether --enable-man-compression was given. -if test "${enable_man_compression+set}" = set; then : - enableval=$enable_man_compression; case $enableval in - yes) as_fn_error $? "missing argument to --enable-man-compression" "$LINENO" 5;; +fi; + echo "$as_me:$LINENO: result: $enableval" >&5 +echo "${ECHO_T}$enableval" >&6 + + echo "$as_me:$LINENO: checking whether to compress the manpages" >&5 +echo $ECHO_N "checking whether to compress the manpages... $ECHO_C" >&6 + # Check whether --enable-man-compression or --disable-man-compression was given. +if test "${enable_man_compression+set}" = set; then + enableval="$enable_man_compression" + case $enableval in + yes) { { echo "$as_me:$LINENO: error: missing argument to --enable-man-compression" >&5 +echo "$as_me: error: missing argument to --enable-man-compression" >&2;} + { (exit 1); exit 1; }; };; no) ;; *) MAN_FLAGS="$MAN_FLAGS --compress $enableval";; esac else enableval="no" -fi - - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enableval" >&5 -$as_echo "$enableval" >&6; } +fi; + echo "$as_me:$LINENO: result: $enableval" >&5 +echo "${ECHO_T}$enableval" >&6 if test "$enableval" != "no"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for compressed file suffix" >&5 -$as_echo_n "checking for compressed file suffix... " >&6; } + echo "$as_me:$LINENO: checking for compressed file suffix" >&5 +echo $ECHO_N "checking for compressed file suffix... $ECHO_C" >&6 touch TeST $enableval TeST Z=`ls TeST* | sed 's/^....//'` rm -f TeST* MAN_FLAGS="$MAN_FLAGS --extension $Z" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $Z" >&5 -$as_echo "$Z" >&6; } + echo "$as_me:$LINENO: result: $Z" >&5 +echo "${ECHO_T}$Z" >&6 fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to add a package name suffix for the manpages" >&5 -$as_echo_n "checking whether to add a package name suffix for the manpages... " >&6; } - # Check whether --enable-man-suffix was given. -if test "${enable_man_suffix+set}" = set; then : - enableval=$enable_man_suffix; case $enableval in + echo "$as_me:$LINENO: checking whether to add a package name suffix for the manpages" >&5 +echo $ECHO_N "checking whether to add a package name suffix for the manpages... $ECHO_C" >&6 + # Check whether --enable-man-suffix or --disable-man-suffix was given. +if test "${enable_man_suffix+set}" = set; then + enableval="$enable_man_suffix" + case $enableval in yes) enableval="tcl" MAN_FLAGS="$MAN_FLAGS --suffix $enableval";; no) ;; *) MAN_FLAGS="$MAN_FLAGS --suffix $enableval";; esac else enableval="no" -fi - - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enableval" >&5 -$as_echo "$enableval" >&6; } +fi; + echo "$as_me:$LINENO: result: $enableval" >&5 +echo "${ECHO_T}$enableval" >&6 @@ -2456,10 +1460,10 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : - $as_echo_n "(cached) " >&6 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. @@ -2469,37 +1473,35 @@ for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}gcc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done - done -IFS=$as_save_IFS +done fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 fi - fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_CC+:} false; then : - $as_echo_n "(cached) " >&6 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. @@ -2509,50 +1511,39 @@ for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="gcc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done - done -IFS=$as_save_IFS +done fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 -$as_echo "$ac_ct_CC" >&6; } + echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6 else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 fi - if test "x$ac_ct_CC" = x; then - CC="" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - CC=$ac_ct_CC - fi + CC=$ac_ct_CC else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : - $as_echo_n "(cached) " >&6 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. @@ -2562,40 +1553,80 @@ for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}cc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done - done -IFS=$as_save_IFS +done fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 fi - - fi fi -if test -z "$CC"; then +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : - $as_echo_n "(cached) " >&6 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + CC=$ac_ct_CC +else + CC="$ac_cv_prog_CC" +fi + +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -2603,19 +1634,18 @@ for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done - done -IFS=$as_save_IFS +done if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. @@ -2633,25 +1663,24 @@ fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 fi - fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then - for ac_prog in cl.exe + for ac_prog in cl do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : - $as_echo_n "(cached) " >&6 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. @@ -2661,41 +1690,39 @@ for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done - done -IFS=$as_save_IFS +done fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 fi - test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC - for ac_prog in cl.exe + for ac_prog in cl do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_CC+:} false; then : - $as_echo_n "(cached) " >&6 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. @@ -2705,78 +1732,66 @@ for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done - done -IFS=$as_save_IFS +done fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 -$as_echo "$ac_ct_CC" >&6; } + echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6 else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 fi - test -n "$ac_ct_CC" && break done - if test "x$ac_ct_CC" = x; then - CC="" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - CC=$ac_ct_CC - fi + CC=$ac_ct_CC fi fi -test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "no acceptable C compiler found in \$PATH -See \`config.log' for more details" "$LINENO" 5; } +test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&5 +echo "$as_me: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } # Provide some information about the compiler. -$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 -set X $ac_compile -ac_compiler=$2 -for ac_option in --version -v -V -qversion; do - { { ac_try="$ac_compiler $ac_option >&5" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_compiler $ac_option >&5") 2>conftest.err +echo "$as_me:$LINENO:" \ + "checking for C compiler version" >&5 +ac_compiler=`set X $ac_compile; echo $2` +{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version &5\"") >&5 + (eval $ac_compiler --version &5) 2>&5 ac_status=$? - if test -s conftest.err; then - sed '10a\ -... rest of stderr output deleted ... - 10q' conftest.err >conftest.er1 - cat conftest.er1 >&5 - fi - rm -f conftest.er1 conftest.err - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } -done + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v &5\"") >&5 + (eval $ac_compiler -v &5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V &5\"") >&5 + (eval $ac_compiler -V &5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } -cat confdefs.h - <<_ACEOF >conftest.$ac_ext +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int @@ -2788,108 +1803,112 @@ main () } _ACEOF ac_clean_files_save=$ac_clean_files -ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" +ac_clean_files="$ac_clean_files a.out a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 -$as_echo_n "checking whether the C compiler works... " >&6; } -ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` - -# The possible output files: -ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" - -ac_rmfiles= -for ac_file in $ac_files -do - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; - * ) ac_rmfiles="$ac_rmfiles $ac_file";; - esac -done -rm -f $ac_rmfiles - -if { { ac_try="$ac_link_default" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_link_default") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then : - # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. -# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' -# in a Makefile. We should not override ac_cv_exeext if it was cached, -# so that the user can short-circuit this test for compilers unknown to -# Autoconf. -for ac_file in $ac_files '' +echo "$as_me:$LINENO: checking for C compiler default output file name" >&5 +echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6 +ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` +if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5 + (eval $ac_link_default) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # Find the output, starting from the most likely. This scheme is +# not robust to junk in `.', hence go to wildcards (a.*) only as a last +# resort. + +# Be careful to initialize this variable, since it used to be cached. +# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile. +ac_cv_exeext= +# b.out is created by i960 compilers. +for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out do test -f "$ac_file" || continue case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) + ;; + conftest.$ac_ext ) + # This is the source file. ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) - if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; - then :; else - ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` - fi - # We set ac_cv_exeext here because the later test for it is not - # safe: cross compilers may not add the suffix if given an `-o' - # argument, so we may need to know it at that point already. - # Even if this section looks crufty: it has the advantage of - # actually working. + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + # FIXME: I believe we export ac_cv_exeext for Libtool, + # but it would be cool to find out if it's true. Does anybody + # maintain Libtool? --akim. + export ac_cv_exeext break;; * ) break;; esac done -test "$ac_cv_exeext" = no && ac_cv_exeext= - else - ac_file='' -fi -if test -z "$ac_file"; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -$as_echo "$as_me: failed program was:" >&5 + echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 -{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error 77 "C compiler cannot create executables -See \`config.log' for more details" "$LINENO" 5; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } +{ { echo "$as_me:$LINENO: error: C compiler cannot create executables +See \`config.log' for more details." >&5 +echo "$as_me: error: C compiler cannot create executables +See \`config.log' for more details." >&2;} + { (exit 77); exit 77; }; } fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 -$as_echo_n "checking for C compiler default output file name... " >&6; } -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 -$as_echo "$ac_file" >&6; } + ac_exeext=$ac_cv_exeext +echo "$as_me:$LINENO: result: $ac_file" >&5 +echo "${ECHO_T}$ac_file" >&6 + +# Check the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +echo "$as_me:$LINENO: checking whether the C compiler works" >&5 +echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6 +# FIXME: These cross compiler hacks should be removed for Autoconf 3.0 +# If not cross compiling, check that we can run a simple program. +if test "$cross_compiling" != yes; then + if { ac_try='./$ac_file' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { echo "$as_me:$LINENO: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } + fi + fi +fi +echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 -rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out +rm -f a.out a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 -$as_echo_n "checking for suffix of executables... " >&6; } -if { { ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_link") 2>&5 +# Check the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 +echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6 +echo "$as_me:$LINENO: result: $cross_compiling" >&5 +echo "${ECHO_T}$cross_compiling" >&6 + +echo "$as_me:$LINENO: checking for suffix of executables" >&5 +echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6 +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then : + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with @@ -2897,90 +1916,38 @@ $as_echo "$ac_try_echo"; } >&5 for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + export ac_cv_exeext break;; * ) break;; esac done else - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "cannot compute suffix of executables: cannot compile and link -See \`config.log' for more details" "$LINENO" 5; } + { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } fi -rm -f conftest conftest$ac_cv_exeext -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 -$as_echo "$ac_cv_exeext" >&6; } + +rm -f conftest$ac_cv_exeext +echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 +echo "${ECHO_T}$ac_cv_exeext" >&6 rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -int -main () -{ -FILE *f = fopen ("conftest.out", "w"); - return ferror (f) || fclose (f) != 0; - - ; - return 0; -} -_ACEOF -ac_clean_files="$ac_clean_files conftest.out" -# Check that the compiler produces executables we can run. If not, either -# the compiler is broken, or we cross compile. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 -$as_echo_n "checking whether we are cross compiling... " >&6; } -if test "$cross_compiling" != yes; then - { { ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } - if { ac_try='./conftest$ac_cv_exeext' - { { case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; }; then - cross_compiling=no - else - if test "$cross_compiling" = maybe; then - cross_compiling=yes - else - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "cannot run C compiled programs. -If you meant to cross compile, use \`--host'. -See \`config.log' for more details" "$LINENO" 5; } - fi - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 -$as_echo "$cross_compiling" >&6; } - -rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out -ac_clean_files=$ac_clean_files_save -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 -$as_echo_n "checking for suffix of object files... " >&6; } -if ${ac_cv_objext+:} false; then : - $as_echo_n "(cached) " >&6 +echo "$as_me:$LINENO: checking for suffix of object files" >&5 +echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6 +if test "${ac_cv_objext+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int @@ -2992,46 +1959,45 @@ main () } _ACEOF rm -f conftest.o conftest.obj -if { { ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_compile") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then : - for ac_file in conftest.o conftest.obj conftest.*; do - test -f "$ac_file" || continue; +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else - $as_echo "$as_me: failed program was:" >&5 + echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 -{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "cannot compute suffix of object files: cannot compile -See \`config.log' for more details" "$LINENO" 5; } +{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute suffix of object files: cannot compile +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } fi + rm -f conftest.$ac_cv_objext conftest.$ac_ext fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 -$as_echo "$ac_cv_objext" >&6; } +echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 +echo "${ECHO_T}$ac_cv_objext" >&6 OBJEXT=$ac_cv_objext ac_objext=$OBJEXT -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 -$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } -if ${ac_cv_c_compiler_gnu+:} false; then : - $as_echo_n "(cached) " >&6 +echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 +echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6 +if test "${ac_cv_c_compiler_gnu+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int @@ -3045,49 +2011,55 @@ main () return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then ac_compiler_gnu=yes else - ac_compiler_gnu=no + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_compiler_gnu=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 -$as_echo "$ac_cv_c_compiler_gnu" >&6; } -if test $ac_compiler_gnu = yes; then - GCC=yes -else - GCC= -fi +echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 +echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6 +GCC=`test $ac_compiler_gnu = yes && echo yes` ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 -$as_echo_n "checking whether $CC accepts -g... " >&6; } -if ${ac_cv_prog_cc_g+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_save_c_werror_flag=$ac_c_werror_flag - ac_c_werror_flag=yes - ac_cv_prog_cc_g=no - CFLAGS="-g" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} +CFLAGS="-g" +echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 +echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6 +if test "${ac_cv_prog_cc_g+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_prog_cc_g=yes -else - CFLAGS="" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int @@ -3098,34 +2070,39 @@ main () return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_prog_cc_g=yes else - ac_c_werror_flag=$ac_save_c_werror_flag - CFLAGS="-g" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_prog_cc_g=yes +ac_cv_prog_cc_g=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - ac_c_werror_flag=$ac_save_c_werror_flag -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 -$as_echo "$ac_cv_prog_cc_g" >&6; } +echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 +echo "${ECHO_T}$ac_cv_prog_cc_g" >&6 if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then @@ -3141,18 +2118,23 @@ else CFLAGS= fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 -$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } -if ${ac_cv_prog_cc_c89+:} false; then : - $as_echo_n "(cached) " >&6 +echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5 +echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6 +if test "${ac_cv_prog_cc_stdc+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 else - ac_cv_prog_cc_c89=no + ac_cv_prog_cc_stdc=no ac_save_CC=$CC -cat confdefs.h - <<_ACEOF >conftest.$ac_ext +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include -struct stat; +#include +#include /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); @@ -3175,17 +2157,12 @@ static char *f (char * (*g) (char **, int), char **p, ...) /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated - as 'x'. The following induces an error, until -std is added to get + as 'x'. The following induces an error, until -std1 is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something - that's true only with -std. */ + that's true only with -std1. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; -/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters - inside strings and character constants. */ -#define FOO(x) 'x' -int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; - int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; @@ -3200,37 +2177,205 @@ return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; return 0; } _ACEOF -for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ - -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +# Don't try gcc -ansi; that turns off useful extensions and +# breaks some systems' header files. +# AIX -qlanglvl=ansi +# Ultrix and OSF/1 -std1 +# HP-UX 10.20 and later -Ae +# HP-UX older versions -Aa -D_HPUX_SOURCE +# SVR4 -Xc -D__EXTENSIONS__ +for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" - if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_prog_cc_c89=$ac_arg + rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_prog_cc_stdc=$ac_arg +break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + fi -rm -f core conftest.err conftest.$ac_objext - test "x$ac_cv_prog_cc_c89" != "xno" && break +rm -f conftest.err conftest.$ac_objext done -rm -f conftest.$ac_ext +rm -f conftest.$ac_ext conftest.$ac_objext CC=$ac_save_CC fi -# AC_CACHE_VAL -case "x$ac_cv_prog_cc_c89" in - x) - { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 -$as_echo "none needed" >&6; } ;; - xno) - { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 -$as_echo "unsupported" >&6; } ;; + +case "x$ac_cv_prog_cc_stdc" in + x|xno) + echo "$as_me:$LINENO: result: none needed" >&5 +echo "${ECHO_T}none needed" >&6 ;; *) - CC="$CC $ac_cv_prog_cc_c89" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 -$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; + echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5 +echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6 + CC="$CC $ac_cv_prog_cc_stdc" ;; esac -if test "x$ac_cv_prog_cc_c89" != xno; then : +# Some people use a C++ compiler to compile C. Since we use `exit', +# in C++ we need to declare it. In case someone uses the same compiler +# for both compiling C and C++ we need to have the C++ compiler decide +# the declaration of exit, since it's the most demanding environment. +cat >conftest.$ac_ext <<_ACEOF +#ifndef __cplusplus + choke me +#endif +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + for ac_declaration in \ + '' \ + 'extern "C" void std::exit (int) throw (); using std::exit;' \ + 'extern "C" void std::exit (int); using std::exit;' \ + 'extern "C" void exit (int) throw ();' \ + 'extern "C" void exit (int);' \ + 'void exit (int);' +do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_declaration +#include +int +main () +{ +exit (42); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +continue +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_declaration +int +main () +{ +exit (42); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +done +rm -f conftest* +if test -n "$ac_declaration"; then + echo '#ifdef __cplusplus' >>confdefs.h + echo $ac_declaration >>confdefs.h + echo '#endif' >>confdefs.h fi +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' @@ -3238,14 +2383,18 @@ ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $ ac_compiler_gnu=$ac_cv_c_compiler_gnu -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline" >&5 -$as_echo_n "checking for inline... " >&6; } -if ${ac_cv_c_inline+:} false; then : - $as_echo_n "(cached) " >&6 +echo "$as_me:$LINENO: checking for inline" >&5 +echo $ECHO_N "checking for inline... $ECHO_C" >&6 +if test "${ac_cv_c_inline+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_c_inline=no for ac_kw in inline __inline__ __inline; do - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifndef __cplusplus typedef int foo_t; @@ -3254,16 +2403,41 @@ $ac_kw foo_t foo () {return 0; } #endif _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_c_inline=$ac_kw +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_c_inline=$ac_kw; break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - test "$ac_cv_c_inline" != no && break +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext done fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_inline" >&5 -$as_echo "$ac_cv_c_inline" >&6; } +echo "$as_me:$LINENO: result: $ac_cv_c_inline" >&5 +echo "${ECHO_T}$ac_cv_c_inline" >&6 + case $ac_cv_c_inline in inline | yes) ;; @@ -3295,15 +2469,15 @@ ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 -$as_echo_n "checking how to run the C preprocessor... " >&6; } +echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 +echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6 # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then - if ${ac_cv_prog_CPP+:} false; then : - $as_echo_n "(cached) " >&6 + if test "${ac_cv_prog_CPP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 else # Double quotes because CPP needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" @@ -3317,7 +2491,11 @@ do # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ # include @@ -3326,34 +2504,78 @@ do #endif Syntax error _ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + : else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + # Broken: fails on valid input. continue fi -rm -f conftest.err conftest.i conftest.$ac_ext +rm -f conftest.err conftest.$ac_ext - # OK, works on sane cases. Now check whether nonexistent headers + # OK, works on sane cases. Now check whether non-existent headers # can be detected and how. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then # Broken: success on invalid input. continue else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + # Passes both tests. ac_preproc_ok=: break fi -rm -f conftest.err conftest.i conftest.$ac_ext +rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.i conftest.err conftest.$ac_ext -if $ac_preproc_ok; then : +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then break fi @@ -3365,8 +2587,8 @@ fi else ac_cv_prog_CPP=$CPP fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 -$as_echo "$CPP" >&6; } +echo "$as_me:$LINENO: result: $CPP" >&5 +echo "${ECHO_T}$CPP" >&6 ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do @@ -3376,7 +2598,11 @@ do # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ # include @@ -3385,40 +2611,85 @@ do #endif Syntax error _ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + : else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + # Broken: fails on valid input. continue fi -rm -f conftest.err conftest.i conftest.$ac_ext +rm -f conftest.err conftest.$ac_ext - # OK, works on sane cases. Now check whether nonexistent headers + # OK, works on sane cases. Now check whether non-existent headers # can be detected and how. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - # Broken: success on invalid input. -continue -else +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + # Broken: success on invalid input. +continue +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + # Passes both tests. ac_preproc_ok=: break fi -rm -f conftest.err conftest.i conftest.$ac_ext +rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.i conftest.err conftest.$ac_ext -if $ac_preproc_ok; then : - +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + : else - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "C preprocessor \"$CPP\" fails sanity check -See \`config.log' for more details" "$LINENO" 5; } + { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details." >&5 +echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } fi ac_ext=c @@ -3428,142 +2699,31 @@ ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $ ac_compiler_gnu=$ac_cv_c_compiler_gnu -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 -$as_echo_n "checking for grep that handles long lines and -e... " >&6; } -if ${ac_cv_path_GREP+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -z "$GREP"; then - ac_path_GREP_found=false - # Loop through the user's path and test for each of PROGNAME-LIST - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in grep ggrep; do - for ac_exec_ext in '' $ac_executable_extensions; do - ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" - as_fn_executable_p "$ac_path_GREP" || continue -# Check for GNU ac_path_GREP and select it if it is found. - # Check for GNU $ac_path_GREP -case `"$ac_path_GREP" --version 2>&1` in -*GNU*) - ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; -*) - ac_count=0 - $as_echo_n 0123456789 >"conftest.in" - while : - do - cat "conftest.in" "conftest.in" >"conftest.tmp" - mv "conftest.tmp" "conftest.in" - cp "conftest.in" "conftest.nl" - $as_echo 'GREP' >> "conftest.nl" - "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break - diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break - as_fn_arith $ac_count + 1 && ac_count=$as_val - if test $ac_count -gt ${ac_path_GREP_max-0}; then - # Best one so far, save it but keep looking for a better one - ac_cv_path_GREP="$ac_path_GREP" - ac_path_GREP_max=$ac_count - fi - # 10*(2^10) chars as input seems more than enough - test $ac_count -gt 10 && break - done - rm -f conftest.in conftest.tmp conftest.nl conftest.out;; -esac - - $ac_path_GREP_found && break 3 - done - done - done -IFS=$as_save_IFS - if test -z "$ac_cv_path_GREP"; then - as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 - fi -else - ac_cv_path_GREP=$GREP -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 -$as_echo "$ac_cv_path_GREP" >&6; } - GREP="$ac_cv_path_GREP" - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 -$as_echo_n "checking for egrep... " >&6; } -if ${ac_cv_path_EGREP+:} false; then : - $as_echo_n "(cached) " >&6 +echo "$as_me:$LINENO: checking for egrep" >&5 +echo $ECHO_N "checking for egrep... $ECHO_C" >&6 +if test "${ac_cv_prog_egrep+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 else - if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 - then ac_cv_path_EGREP="$GREP -E" - else - if test -z "$EGREP"; then - ac_path_EGREP_found=false - # Loop through the user's path and test for each of PROGNAME-LIST - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in egrep; do - for ac_exec_ext in '' $ac_executable_extensions; do - ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" - as_fn_executable_p "$ac_path_EGREP" || continue -# Check for GNU ac_path_EGREP and select it if it is found. - # Check for GNU $ac_path_EGREP -case `"$ac_path_EGREP" --version 2>&1` in -*GNU*) - ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; -*) - ac_count=0 - $as_echo_n 0123456789 >"conftest.in" - while : - do - cat "conftest.in" "conftest.in" >"conftest.tmp" - mv "conftest.tmp" "conftest.in" - cp "conftest.in" "conftest.nl" - $as_echo 'EGREP' >> "conftest.nl" - "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break - diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break - as_fn_arith $ac_count + 1 && ac_count=$as_val - if test $ac_count -gt ${ac_path_EGREP_max-0}; then - # Best one so far, save it but keep looking for a better one - ac_cv_path_EGREP="$ac_path_EGREP" - ac_path_EGREP_max=$ac_count + if echo a | (grep -E '(a|b)') >/dev/null 2>&1 + then ac_cv_prog_egrep='grep -E' + else ac_cv_prog_egrep='egrep' fi - # 10*(2^10) chars as input seems more than enough - test $ac_count -gt 10 && break - done - rm -f conftest.in conftest.tmp conftest.nl conftest.out;; -esac - - $ac_path_EGREP_found && break 3 - done - done - done -IFS=$as_save_IFS - if test -z "$ac_cv_path_EGREP"; then - as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 - fi -else - ac_cv_path_EGREP=$EGREP fi - - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 -$as_echo "$ac_cv_path_EGREP" >&6; } - EGREP="$ac_cv_path_EGREP" +echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5 +echo "${ECHO_T}$ac_cv_prog_egrep" >&6 + EGREP=$ac_cv_prog_egrep -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 -$as_echo_n "checking for ANSI C header files... " >&6; } -if ${ac_cv_header_stdc+:} false; then : - $as_echo_n "(cached) " >&6 +echo "$as_me:$LINENO: checking for ANSI C header files" >&5 +echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6 +if test "${ac_cv_header_stdc+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include @@ -3578,23 +2738,51 @@ main () return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then ac_cv_header_stdc=yes else - ac_cv_header_stdc=no + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_header_stdc=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "memchr" >/dev/null 2>&1; then : - + $EGREP "memchr" >/dev/null 2>&1; then + : else ac_cv_header_stdc=no fi @@ -3604,14 +2792,18 @@ fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "free" >/dev/null 2>&1; then : - + $EGREP "free" >/dev/null 2>&1; then + : else ac_cv_header_stdc=no fi @@ -3621,13 +2813,16 @@ fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. - if test "$cross_compiling" = yes; then : + if test "$cross_compiling" = yes; then : else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include -#include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) @@ -3647,39 +2842,109 @@ main () for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) - return 2; - return 0; + exit(2); + exit (0); } _ACEOF -if ac_fn_c_try_run "$LINENO"; then : - +rm -f conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : else - ac_cv_header_stdc=no + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_header_stdc=no fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext +rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi - fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 -$as_echo "$ac_cv_header_stdc" >&6; } +echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 +echo "${ECHO_T}$ac_cv_header_stdc" >&6 if test $ac_cv_header_stdc = yes; then -$as_echo "#define STDC_HEADERS 1" >>confdefs.h +cat >>confdefs.h <<\_ACEOF +#define STDC_HEADERS 1 +_ACEOF fi # On IRIX 5.3, sys/types and inttypes.h are conflicting. + + + + + + + + + for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ inttypes.h stdint.h unistd.h -do : - as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` -ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default -" -if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_Header=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +eval "$as_ac_Header=no" +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi @@ -3688,13 +2953,17 @@ done - { $as_echo "$as_me:${as_lineno-$LINENO}: checking dirent.h" >&5 -$as_echo_n "checking dirent.h... " >&6; } -if ${tcl_cv_dirent_h+:} false; then : - $as_echo_n "(cached) " >&6 + echo "$as_me:$LINENO: checking dirent.h" >&5 +echo $ECHO_N "checking dirent.h... $ECHO_C" >&6 +if test "${tcl_cv_dirent_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include @@ -3724,352 +2993,1596 @@ closedir(d); return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then tcl_cv_dirent_h=yes else - tcl_cv_dirent_h=no + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +tcl_cv_dirent_h=no fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_dirent_h" >&5 -$as_echo "$tcl_cv_dirent_h" >&6; } +echo "$as_me:$LINENO: result: $tcl_cv_dirent_h" >&5 +echo "${ECHO_T}$tcl_cv_dirent_h" >&6 if test $tcl_cv_dirent_h = no; then -$as_echo "#define NO_DIRENT_H 1" >>confdefs.h +cat >>confdefs.h <<\_ACEOF +#define NO_DIRENT_H 1 +_ACEOF fi - ac_fn_c_check_header_mongrel "$LINENO" "float.h" "ac_cv_header_float_h" "$ac_includes_default" -if test "x$ac_cv_header_float_h" = xyes; then : - + if test "${ac_cv_header_float_h+set}" = set; then + echo "$as_me:$LINENO: checking for float.h" >&5 +echo $ECHO_N "checking for float.h... $ECHO_C" >&6 +if test "${ac_cv_header_float_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: $ac_cv_header_float_h" >&5 +echo "${ECHO_T}$ac_cv_header_float_h" >&6 else + # Is the header compilable? +echo "$as_me:$LINENO: checking float.h usability" >&5 +echo $ECHO_N "checking float.h usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 -$as_echo "#define NO_FLOAT_H 1" >>confdefs.h - +ac_header_compiler=no fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 +# Is the header present? +echo "$as_me:$LINENO: checking float.h presence" >&5 +echo $ECHO_N "checking float.h presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 - ac_fn_c_check_header_mongrel "$LINENO" "values.h" "ac_cv_header_values_h" "$ac_includes_default" -if test "x$ac_cv_header_values_h" = xyes; then : + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: float.h: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: float.h: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: float.h: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: float.h: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: float.h: present but cannot be compiled" >&5 +echo "$as_me: WARNING: float.h: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: float.h: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: float.h: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: float.h: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: float.h: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: float.h: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: float.h: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: float.h: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: float.h: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: float.h: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: float.h: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +## ------------------------------ ## +## Report this to the tcl lists. ## +## ------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for float.h" >&5 +echo $ECHO_N "checking for float.h... $ECHO_C" >&6 +if test "${ac_cv_header_float_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 else - -$as_echo "#define NO_VALUES_H 1" >>confdefs.h + ac_cv_header_float_h=$ac_header_preproc +fi +echo "$as_me:$LINENO: result: $ac_cv_header_float_h" >&5 +echo "${ECHO_T}$ac_cv_header_float_h" >&6 fi +if test $ac_cv_header_float_h = yes; then + : +else +cat >>confdefs.h <<\_ACEOF +#define NO_FLOAT_H 1 +_ACEOF - ac_fn_c_check_header_mongrel "$LINENO" "limits.h" "ac_cv_header_limits_h" "$ac_includes_default" -if test "x$ac_cv_header_limits_h" = xyes; then : +fi -$as_echo "#define HAVE_LIMITS_H 1" >>confdefs.h + if test "${ac_cv_header_values_h+set}" = set; then + echo "$as_me:$LINENO: checking for values.h" >&5 +echo $ECHO_N "checking for values.h... $ECHO_C" >&6 +if test "${ac_cv_header_values_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: $ac_cv_header_values_h" >&5 +echo "${ECHO_T}$ac_cv_header_values_h" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking values.h usability" >&5 +echo $ECHO_N "checking values.h usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 -$as_echo "#define NO_LIMITS_H 1" >>confdefs.h +ac_header_compiler=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 +# Is the header present? +echo "$as_me:$LINENO: checking values.h presence" >&5 +echo $ECHO_N "checking values.h presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 - ac_fn_c_check_header_mongrel "$LINENO" "stdlib.h" "ac_cv_header_stdlib_h" "$ac_includes_default" -if test "x$ac_cv_header_stdlib_h" = xyes; then : - tcl_ok=1 +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: values.h: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: values.h: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: values.h: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: values.h: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: values.h: present but cannot be compiled" >&5 +echo "$as_me: WARNING: values.h: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: values.h: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: values.h: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: values.h: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: values.h: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: values.h: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: values.h: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: values.h: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: values.h: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: values.h: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: values.h: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +## ------------------------------ ## +## Report this to the tcl lists. ## +## ------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for values.h" >&5 +echo $ECHO_N "checking for values.h... $ECHO_C" >&6 +if test "${ac_cv_header_values_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 else - tcl_ok=0 + ac_cv_header_values_h=$ac_header_preproc fi +echo "$as_me:$LINENO: result: $ac_cv_header_values_h" >&5 +echo "${ECHO_T}$ac_cv_header_values_h" >&6 +fi +if test $ac_cv_header_values_h = yes; then + : +else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include - +cat >>confdefs.h <<\_ACEOF +#define NO_VALUES_H 1 _ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "strtol" >/dev/null 2>&1; then : -else - tcl_ok=0 fi -rm -f conftest* - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include + if test "${ac_cv_header_limits_h+set}" = set; then + echo "$as_me:$LINENO: checking for limits.h" >&5 +echo $ECHO_N "checking for limits.h... $ECHO_C" >&6 +if test "${ac_cv_header_limits_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: $ac_cv_header_limits_h" >&5 +echo "${ECHO_T}$ac_cv_header_limits_h" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking limits.h usability" >&5 +echo $ECHO_N "checking limits.h usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ _ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "strtoul" >/dev/null 2>&1; then : - +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes else - tcl_ok=0 + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no fi -rm -f conftest* +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 - cat confdefs.h - <<_ACEOF >conftest.$ac_ext +# Is the header present? +echo "$as_me:$LINENO: checking limits.h presence" >&5 +echo $ECHO_N "checking limits.h presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ -#include - +#include _ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "strtod" >/dev/null 2>&1; then : - +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi else - tcl_ok=0 + ac_cpp_err=yes fi -rm -f conftest* - - if test $tcl_ok = 0; then +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 -$as_echo "#define NO_STDLIB_H 1" >>confdefs.h + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 - fi - ac_fn_c_check_header_mongrel "$LINENO" "string.h" "ac_cv_header_string_h" "$ac_includes_default" -if test "x$ac_cv_header_string_h" = xyes; then : - tcl_ok=1 +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: limits.h: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: limits.h: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: limits.h: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: limits.h: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: limits.h: present but cannot be compiled" >&5 +echo "$as_me: WARNING: limits.h: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: limits.h: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: limits.h: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: limits.h: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: limits.h: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: limits.h: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: limits.h: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: limits.h: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: limits.h: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: limits.h: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: limits.h: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +## ------------------------------ ## +## Report this to the tcl lists. ## +## ------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for limits.h" >&5 +echo $ECHO_N "checking for limits.h... $ECHO_C" >&6 +if test "${ac_cv_header_limits_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 else - tcl_ok=0 + ac_cv_header_limits_h=$ac_header_preproc fi +echo "$as_me:$LINENO: result: $ac_cv_header_limits_h" >&5 +echo "${ECHO_T}$ac_cv_header_limits_h" >&6 +fi +if test $ac_cv_header_limits_h = yes; then - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include - +cat >>confdefs.h <<\_ACEOF +#define HAVE_LIMITS_H 1 _ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "strstr" >/dev/null 2>&1; then : else - tcl_ok=0 -fi -rm -f conftest* - - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include +cat >>confdefs.h <<\_ACEOF +#define NO_LIMITS_H 1 _ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "strerror" >/dev/null 2>&1; then : -else - tcl_ok=0 fi -rm -f conftest* - - - # See also memmove check below for a place where NO_STRING_H can be - # set and why. - - if test $tcl_ok = 0; then - -$as_echo "#define NO_STRING_H 1" >>confdefs.h - - fi - ac_fn_c_check_header_mongrel "$LINENO" "sys/wait.h" "ac_cv_header_sys_wait_h" "$ac_includes_default" -if test "x$ac_cv_header_sys_wait_h" = xyes; then : + if test "${ac_cv_header_stdlib_h+set}" = set; then + echo "$as_me:$LINENO: checking for stdlib.h" >&5 +echo $ECHO_N "checking for stdlib.h... $ECHO_C" >&6 +if test "${ac_cv_header_stdlib_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: $ac_cv_header_stdlib_h" >&5 +echo "${ECHO_T}$ac_cv_header_stdlib_h" >&6 else + # Is the header compilable? +echo "$as_me:$LINENO: checking stdlib.h usability" >&5 +echo $ECHO_N "checking stdlib.h usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 -$as_echo "#define NO_SYS_WAIT_H 1" >>confdefs.h - +ac_header_compiler=no fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 - - ac_fn_c_check_header_mongrel "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default" -if test "x$ac_cv_header_dlfcn_h" = xyes; then : - +# Is the header present? +echo "$as_me:$LINENO: checking stdlib.h presence" >&5 +echo $ECHO_N "checking stdlib.h presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 -$as_echo "#define NO_DLFCN_H 1" >>confdefs.h + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: stdlib.h: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: stdlib.h: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: stdlib.h: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: stdlib.h: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: stdlib.h: present but cannot be compiled" >&5 +echo "$as_me: WARNING: stdlib.h: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: stdlib.h: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: stdlib.h: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: stdlib.h: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: stdlib.h: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: stdlib.h: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: stdlib.h: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: stdlib.h: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: stdlib.h: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: stdlib.h: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: stdlib.h: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +## ------------------------------ ## +## Report this to the tcl lists. ## +## ------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for stdlib.h" >&5 +echo $ECHO_N "checking for stdlib.h... $ECHO_C" >&6 +if test "${ac_cv_header_stdlib_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_header_stdlib_h=$ac_header_preproc fi +echo "$as_me:$LINENO: result: $ac_cv_header_stdlib_h" >&5 +echo "${ECHO_T}$ac_cv_header_stdlib_h" >&6 +fi +if test $ac_cv_header_stdlib_h = yes; then + tcl_ok=1 +else + tcl_ok=0 +fi - # OS/390 lacks sys/param.h (and doesn't need it, by chance). - for ac_header in sys/param.h -do : - ac_fn_c_check_header_mongrel "$LINENO" "sys/param.h" "ac_cv_header_sys_param_h" "$ac_includes_default" -if test "x$ac_cv_header_sys_param_h" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_SYS_PARAM_H 1 + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ _ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "strtol" >/dev/null 2>&1; then + : +else + tcl_ok=0 fi +rm -f conftest* -done - + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "strtoul" >/dev/null 2>&1; then + : +else + tcl_ok=0 +fi +rm -f conftest* -#-------------------------------------------------------------------- -# Determines the correct executable file extension (.exe) -#-------------------------------------------------------------------- + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "strtod" >/dev/null 2>&1; then + : +else + tcl_ok=0 +fi +rm -f conftest* + if test $tcl_ok = 0; then -#------------------------------------------------------------------------ -# If we're using GCC, see if the compiler understands -pipe. If so, use it. -# It makes compiling go faster. (This is only a performance feature.) -#------------------------------------------------------------------------ +cat >>confdefs.h <<\_ACEOF +#define NO_STDLIB_H 1 +_ACEOF -if test -z "$no_pipe" && test -n "$GCC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if the compiler understands -pipe" >&5 -$as_echo_n "checking if the compiler understands -pipe... " >&6; } -if ${tcl_cv_cc_pipe+:} false; then : - $as_echo_n "(cached) " >&6 + fi + if test "${ac_cv_header_string_h+set}" = set; then + echo "$as_me:$LINENO: checking for string.h" >&5 +echo $ECHO_N "checking for string.h... $ECHO_C" >&6 +if test "${ac_cv_header_string_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: $ac_cv_header_string_h" >&5 +echo "${ECHO_T}$ac_cv_header_string_h" >&6 else - - hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -pipe" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + # Is the header compilable? +echo "$as_me:$LINENO: checking string.h usability" >&5 +echo $ECHO_N "checking string.h usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ +$ac_includes_default +#include +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 -int -main () -{ +ac_header_compiler=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 - ; - return 0; -} +# Is the header present? +echo "$as_me:$LINENO: checking string.h presence" >&5 +echo $ECHO_N "checking string.h presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - tcl_cv_cc_pipe=yes +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi else - tcl_cv_cc_pipe=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - CFLAGS=$hold_cflags -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_cc_pipe" >&5 -$as_echo "$tcl_cv_cc_pipe" >&6; } - if test $tcl_cv_cc_pipe = yes; then - CFLAGS="$CFLAGS -pipe" - fi + ac_cpp_err=yes fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 -#------------------------------------------------------------------------ -# Threads support -#------------------------------------------------------------------------ + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: string.h: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: string.h: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: string.h: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: string.h: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: string.h: present but cannot be compiled" >&5 +echo "$as_me: WARNING: string.h: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: string.h: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: string.h: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: string.h: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: string.h: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: string.h: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: string.h: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: string.h: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: string.h: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: string.h: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: string.h: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +## ------------------------------ ## +## Report this to the tcl lists. ## +## ------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for string.h" >&5 +echo $ECHO_N "checking for string.h... $ECHO_C" >&6 +if test "${ac_cv_header_string_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_header_string_h=$ac_header_preproc +fi +echo "$as_me:$LINENO: result: $ac_cv_header_string_h" >&5 +echo "${ECHO_T}$ac_cv_header_string_h" >&6 - # Check whether --enable-threads was given. -if test "${enable_threads+set}" = set; then : - enableval=$enable_threads; tcl_ok=$enableval +fi +if test $ac_cv_header_string_h = yes; then + tcl_ok=1 else - tcl_ok=yes + tcl_ok=0 fi - if test "${TCL_THREADS}" = 1; then - tcl_threaded_core=1; - fi + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include - if test "$tcl_ok" = "yes" -o "${TCL_THREADS}" = 1; then - TCL_THREADS=1 - # USE_THREAD_ALLOC tells us to try the special thread-based - # allocator that significantly reduces lock contention +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "strstr" >/dev/null 2>&1; then + : +else + tcl_ok=0 +fi +rm -f conftest* -$as_echo "#define USE_THREAD_ALLOC 1" >>confdefs.h + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "strerror" >/dev/null 2>&1; then + : +else + tcl_ok=0 +fi +rm -f conftest* -$as_echo "#define _REENTRANT 1" >>confdefs.h - if test "`uname -s`" = "SunOS" ; then + # See also memmove check below for a place where NO_STRING_H can be + # set and why. -$as_echo "#define _POSIX_PTHREAD_SEMANTICS 1" >>confdefs.h + if test $tcl_ok = 0; then - fi +cat >>confdefs.h <<\_ACEOF +#define NO_STRING_H 1 +_ACEOF -$as_echo "#define _THREAD_SAFE 1" >>confdefs.h + fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_mutex_init in -lpthread" >&5 -$as_echo_n "checking for pthread_mutex_init in -lpthread... " >&6; } -if ${ac_cv_lib_pthread_pthread_mutex_init+:} false; then : - $as_echo_n "(cached) " >&6 + if test "${ac_cv_header_sys_wait_h+set}" = set; then + echo "$as_me:$LINENO: checking for sys/wait.h" >&5 +echo $ECHO_N "checking for sys/wait.h... $ECHO_C" >&6 +if test "${ac_cv_header_sys_wait_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: $ac_cv_header_sys_wait_h" >&5 +echo "${ECHO_T}$ac_cv_header_sys_wait_h" >&6 else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lpthread $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext + # Is the header compilable? +echo "$as_me:$LINENO: checking sys/wait.h usability" >&5 +echo $ECHO_N "checking sys/wait.h usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ +$ac_includes_default +#include +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char pthread_mutex_init (); -int -main () -{ -return pthread_mutex_init (); - ; - return 0; -} +ac_header_compiler=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking sys/wait.h presence" >&5 +echo $ECHO_N "checking sys/wait.h presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ _ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_pthread_pthread_mutex_init=yes +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi else - ac_cv_lib_pthread_pthread_mutex_init=no + ac_cpp_err=yes fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pthread_pthread_mutex_init" >&5 -$as_echo "$ac_cv_lib_pthread_pthread_mutex_init" >&6; } -if test "x$ac_cv_lib_pthread_pthread_mutex_init" = xyes; then : - tcl_ok=yes +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: sys/wait.h: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: sys/wait.h: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: sys/wait.h: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: sys/wait.h: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: sys/wait.h: present but cannot be compiled" >&5 +echo "$as_me: WARNING: sys/wait.h: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: sys/wait.h: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: sys/wait.h: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: sys/wait.h: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: sys/wait.h: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: sys/wait.h: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: sys/wait.h: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: sys/wait.h: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: sys/wait.h: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: sys/wait.h: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: sys/wait.h: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +## ------------------------------ ## +## Report this to the tcl lists. ## +## ------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for sys/wait.h" >&5 +echo $ECHO_N "checking for sys/wait.h... $ECHO_C" >&6 +if test "${ac_cv_header_sys_wait_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 else - tcl_ok=no + ac_cv_header_sys_wait_h=$ac_header_preproc fi +echo "$as_me:$LINENO: result: $ac_cv_header_sys_wait_h" >&5 +echo "${ECHO_T}$ac_cv_header_sys_wait_h" >&6 - if test "$tcl_ok" = "no"; then - # Check a little harder for __pthread_mutex_init in the same - # library, as some systems hide it there until pthread.h is - # defined. We could alternatively do an AC_TRY_COMPILE with - # pthread.h, but that will work with libpthread really doesn't - # exist, like AIX 4.2. [Bug: 4359] - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for __pthread_mutex_init in -lpthread" >&5 -$as_echo_n "checking for __pthread_mutex_init in -lpthread... " >&6; } -if ${ac_cv_lib_pthread___pthread_mutex_init+:} false; then : - $as_echo_n "(cached) " >&6 +fi +if test $ac_cv_header_sys_wait_h = yes; then + : else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lpthread $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" +cat >>confdefs.h <<\_ACEOF +#define NO_SYS_WAIT_H 1 +_ACEOF + +fi + + + if test "${ac_cv_header_dlfcn_h+set}" = set; then + echo "$as_me:$LINENO: checking for dlfcn.h" >&5 +echo $ECHO_N "checking for dlfcn.h... $ECHO_C" >&6 +if test "${ac_cv_header_dlfcn_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: $ac_cv_header_dlfcn_h" >&5 +echo "${ECHO_T}$ac_cv_header_dlfcn_h" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking dlfcn.h usability" >&5 +echo $ECHO_N "checking dlfcn.h usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking dlfcn.h presence" >&5 +echo $ECHO_N "checking dlfcn.h presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: dlfcn.h: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: dlfcn.h: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: dlfcn.h: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: dlfcn.h: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: dlfcn.h: present but cannot be compiled" >&5 +echo "$as_me: WARNING: dlfcn.h: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: dlfcn.h: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: dlfcn.h: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: dlfcn.h: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: dlfcn.h: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: dlfcn.h: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: dlfcn.h: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: dlfcn.h: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: dlfcn.h: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: dlfcn.h: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: dlfcn.h: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +## ------------------------------ ## +## Report this to the tcl lists. ## +## ------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for dlfcn.h" >&5 +echo $ECHO_N "checking for dlfcn.h... $ECHO_C" >&6 +if test "${ac_cv_header_dlfcn_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_header_dlfcn_h=$ac_header_preproc +fi +echo "$as_me:$LINENO: result: $ac_cv_header_dlfcn_h" >&5 +echo "${ECHO_T}$ac_cv_header_dlfcn_h" >&6 + +fi +if test $ac_cv_header_dlfcn_h = yes; then + : +else + +cat >>confdefs.h <<\_ACEOF +#define NO_DLFCN_H 1 +_ACEOF + +fi + + + + # OS/390 lacks sys/param.h (and doesn't need it, by chance). + +for ac_header in sys/param.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +## ------------------------------ ## +## Report this to the tcl lists. ## +## ------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + + +#-------------------------------------------------------------------- +# Determines the correct executable file extension (.exe) +#-------------------------------------------------------------------- + + + +#------------------------------------------------------------------------ +# If we're using GCC, see if the compiler understands -pipe. If so, use it. +# It makes compiling go faster. (This is only a performance feature.) +#------------------------------------------------------------------------ + +if test -z "$no_pipe" && test -n "$GCC"; then + echo "$as_me:$LINENO: checking if the compiler understands -pipe" >&5 +echo $ECHO_N "checking if the compiler understands -pipe... $ECHO_C" >&6 +if test "${tcl_cv_cc_pipe+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + + hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -pipe" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + tcl_cv_cc_pipe=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +tcl_cv_cc_pipe=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + CFLAGS=$hold_cflags +fi +echo "$as_me:$LINENO: result: $tcl_cv_cc_pipe" >&5 +echo "${ECHO_T}$tcl_cv_cc_pipe" >&6 + if test $tcl_cv_cc_pipe = yes; then + CFLAGS="$CFLAGS -pipe" + fi +fi + +#------------------------------------------------------------------------ +# Threads support +#------------------------------------------------------------------------ + + + # Check whether --enable-threads or --disable-threads was given. +if test "${enable_threads+set}" = set; then + enableval="$enable_threads" + tcl_ok=$enableval +else + tcl_ok=yes +fi; + + if test "${TCL_THREADS}" = 1; then + tcl_threaded_core=1; + fi + + if test "$tcl_ok" = "yes" -o "${TCL_THREADS}" = 1; then + TCL_THREADS=1 + # USE_THREAD_ALLOC tells us to try the special thread-based + # allocator that significantly reduces lock contention + +cat >>confdefs.h <<\_ACEOF +#define USE_THREAD_ALLOC 1 +_ACEOF + + +cat >>confdefs.h <<\_ACEOF +#define _REENTRANT 1 +_ACEOF + + if test "`uname -s`" = "SunOS" ; then + +cat >>confdefs.h <<\_ACEOF +#define _POSIX_PTHREAD_SEMANTICS 1 +_ACEOF + + fi + +cat >>confdefs.h <<\_ACEOF +#define _THREAD_SAFE 1 +_ACEOF + + echo "$as_me:$LINENO: checking for pthread_mutex_init in -lpthread" >&5 +echo $ECHO_N "checking for pthread_mutex_init in -lpthread... $ECHO_C" >&6 +if test "${ac_cv_lib_pthread_pthread_mutex_init+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lpthread $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char pthread_mutex_init (); +int +main () +{ +pthread_mutex_init (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_pthread_pthread_mutex_init=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_pthread_pthread_mutex_init=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_pthread_pthread_mutex_init" >&5 +echo "${ECHO_T}$ac_cv_lib_pthread_pthread_mutex_init" >&6 +if test $ac_cv_lib_pthread_pthread_mutex_init = yes; then + tcl_ok=yes +else + tcl_ok=no +fi + + if test "$tcl_ok" = "no"; then + # Check a little harder for __pthread_mutex_init in the same + # library, as some systems hide it there until pthread.h is + # defined. We could alternatively do an AC_TRY_COMPILE with + # pthread.h, but that will work with libpthread really doesn't + # exist, like AIX 4.2. [Bug: 4359] + echo "$as_me:$LINENO: checking for __pthread_mutex_init in -lpthread" >&5 +echo $ECHO_N "checking for __pthread_mutex_init in -lpthread... $ECHO_C" >&6 +if test "${ac_cv_lib_pthread___pthread_mutex_init+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lpthread $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" #endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ char __pthread_mutex_init (); int main () { -return __pthread_mutex_init (); +__pthread_mutex_init (); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then ac_cv_lib_pthread___pthread_mutex_init=yes else - ac_cv_lib_pthread___pthread_mutex_init=no + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_pthread___pthread_mutex_init=no fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pthread___pthread_mutex_init" >&5 -$as_echo "$ac_cv_lib_pthread___pthread_mutex_init" >&6; } -if test "x$ac_cv_lib_pthread___pthread_mutex_init" = xyes; then : +echo "$as_me:$LINENO: result: $ac_cv_lib_pthread___pthread_mutex_init" >&5 +echo "${ECHO_T}$ac_cv_lib_pthread___pthread_mutex_init" >&6 +if test $ac_cv_lib_pthread___pthread_mutex_init = yes; then tcl_ok=yes else tcl_ok=no @@ -4081,43 +4594,71 @@ fi # The space is needed THREADS_LIBS=" -lpthread" else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_mutex_init in -lpthreads" >&5 -$as_echo_n "checking for pthread_mutex_init in -lpthreads... " >&6; } -if ${ac_cv_lib_pthreads_pthread_mutex_init+:} false; then : - $as_echo_n "(cached) " >&6 + echo "$as_me:$LINENO: checking for pthread_mutex_init in -lpthreads" >&5 +echo $ECHO_N "checking for pthread_mutex_init in -lpthreads... $ECHO_C" >&6 +if test "${ac_cv_lib_pthreads_pthread_mutex_init+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lpthreads $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ +/* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ char pthread_mutex_init (); int main () { -return pthread_mutex_init (); +pthread_mutex_init (); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then ac_cv_lib_pthreads_pthread_mutex_init=yes else - ac_cv_lib_pthreads_pthread_mutex_init=no + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_pthreads_pthread_mutex_init=no fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pthreads_pthread_mutex_init" >&5 -$as_echo "$ac_cv_lib_pthreads_pthread_mutex_init" >&6; } -if test "x$ac_cv_lib_pthreads_pthread_mutex_init" = xyes; then : +echo "$as_me:$LINENO: result: $ac_cv_lib_pthreads_pthread_mutex_init" >&5 +echo "${ECHO_T}$ac_cv_lib_pthreads_pthread_mutex_init" >&6 +if test $ac_cv_lib_pthreads_pthread_mutex_init = yes; then tcl_ok=yes else tcl_ok=no @@ -4127,86 +4668,142 @@ fi # The space is needed THREADS_LIBS=" -lpthreads" else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_mutex_init in -lc" >&5 -$as_echo_n "checking for pthread_mutex_init in -lc... " >&6; } -if ${ac_cv_lib_c_pthread_mutex_init+:} false; then : - $as_echo_n "(cached) " >&6 + echo "$as_me:$LINENO: checking for pthread_mutex_init in -lc" >&5 +echo $ECHO_N "checking for pthread_mutex_init in -lc... $ECHO_C" >&6 +if test "${ac_cv_lib_c_pthread_mutex_init+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lc $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ +/* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ char pthread_mutex_init (); int main () { -return pthread_mutex_init (); +pthread_mutex_init (); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then ac_cv_lib_c_pthread_mutex_init=yes else - ac_cv_lib_c_pthread_mutex_init=no + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_c_pthread_mutex_init=no fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_c_pthread_mutex_init" >&5 -$as_echo "$ac_cv_lib_c_pthread_mutex_init" >&6; } -if test "x$ac_cv_lib_c_pthread_mutex_init" = xyes; then : +echo "$as_me:$LINENO: result: $ac_cv_lib_c_pthread_mutex_init" >&5 +echo "${ECHO_T}$ac_cv_lib_c_pthread_mutex_init" >&6 +if test $ac_cv_lib_c_pthread_mutex_init = yes; then tcl_ok=yes else tcl_ok=no fi if test "$tcl_ok" = "no"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_mutex_init in -lc_r" >&5 -$as_echo_n "checking for pthread_mutex_init in -lc_r... " >&6; } -if ${ac_cv_lib_c_r_pthread_mutex_init+:} false; then : - $as_echo_n "(cached) " >&6 + echo "$as_me:$LINENO: checking for pthread_mutex_init in -lc_r" >&5 +echo $ECHO_N "checking for pthread_mutex_init in -lc_r... $ECHO_C" >&6 +if test "${ac_cv_lib_c_r_pthread_mutex_init+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lc_r $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ +/* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ char pthread_mutex_init (); int main () { -return pthread_mutex_init (); +pthread_mutex_init (); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then ac_cv_lib_c_r_pthread_mutex_init=yes else - ac_cv_lib_c_r_pthread_mutex_init=no + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_c_r_pthread_mutex_init=no fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_c_r_pthread_mutex_init" >&5 -$as_echo "$ac_cv_lib_c_r_pthread_mutex_init" >&6; } -if test "x$ac_cv_lib_c_r_pthread_mutex_init" = xyes; then : +echo "$as_me:$LINENO: result: $ac_cv_lib_c_r_pthread_mutex_init" >&5 +echo "${ECHO_T}$ac_cv_lib_c_r_pthread_mutex_init" >&6 +if test $ac_cv_lib_c_r_pthread_mutex_init = yes; then tcl_ok=yes else tcl_ok=no @@ -4217,8 +4814,8 @@ fi THREADS_LIBS=" -pthread" else TCL_THREADS=0 - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Don't know how to find pthread lib on your system - you must disable thread support or edit the LIBS in the Makefile..." >&5 -$as_echo "$as_me: WARNING: Don't know how to find pthread lib on your system - you must disable thread support or edit the LIBS in the Makefile..." >&2;} + { echo "$as_me:$LINENO: WARNING: Don't know how to find pthread lib on your system - you must disable thread support or edit the LIBS in the Makefile..." >&5 +echo "$as_me: WARNING: Don't know how to find pthread lib on your system - you must disable thread support or edit the LIBS in the Makefile..." >&2;} fi fi fi @@ -4229,13 +4826,104 @@ $as_echo "$as_me: WARNING: Don't know how to find pthread lib on your system - y ac_saved_libs=$LIBS LIBS="$LIBS $THREADS_LIBS" - for ac_func in pthread_attr_setstacksize pthread_atfork -do : - as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` -ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" -if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + + +for ac_func in pthread_attr_setstacksize pthread_atfork +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 +if eval "test \"\${$as_ac_var+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case declares $ac_func. + For example, HP-UX 11i declares gettimeofday. */ +#define $ac_func innocuous_$ac_func + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $ac_func + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +char (*f) () = $ac_func; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != $ac_func; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +eval "$as_ac_var=no" +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 +if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi @@ -4246,22 +4934,24 @@ done TCL_THREADS=0 fi # Do checking message here to not mess up interleaved configure output - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for building with threads" >&5 -$as_echo_n "checking for building with threads... " >&6; } + echo "$as_me:$LINENO: checking for building with threads" >&5 +echo $ECHO_N "checking for building with threads... $ECHO_C" >&6 if test "${TCL_THREADS}" = 1; then -$as_echo "#define TCL_THREADS 1" >>confdefs.h +cat >>confdefs.h <<\_ACEOF +#define TCL_THREADS 1 +_ACEOF if test "${tcl_threaded_core}" = 1; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes (threaded core)" >&5 -$as_echo "yes (threaded core)" >&6; } + echo "$as_me:$LINENO: result: yes (threaded core)" >&5 +echo "${ECHO_T}yes (threaded core)" >&6 else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 fi else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 fi @@ -4273,11 +4963,11 @@ $as_echo "no" >&6; } -# Check whether --with-encoding was given. -if test "${with_encoding+set}" = set; then : - withval=$with_encoding; with_tcencoding=${withval} -fi - +# Check whether --with-encoding or --without-encoding was given. +if test "${with_encoding+set}" = set; then + withval="$with_encoding" + with_tcencoding=${withval} +fi; if test x"${with_tcencoding}" != x ; then @@ -4287,7 +4977,9 @@ _ACEOF else -$as_echo "#define TCL_CFGVAL_ENCODING \"iso8859-1\"" >>confdefs.h +cat >>confdefs.h <<\_ACEOF +#define TCL_CFGVAL_ENCODING "iso8859-1" +_ACEOF fi @@ -4304,44 +4996,161 @@ $as_echo "#define TCL_CFGVAL_ENCODING \"iso8859-1\"" >>confdefs.h # right (and it must appear before "-lm"). #-------------------------------------------------------------------- - ac_fn_c_check_func "$LINENO" "sin" "ac_cv_func_sin" -if test "x$ac_cv_func_sin" = xyes; then : + echo "$as_me:$LINENO: checking for sin" >&5 +echo $ECHO_N "checking for sin... $ECHO_C" >&6 +if test "${ac_cv_func_sin+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define sin to an innocuous variant, in case declares sin. + For example, HP-UX 11i declares gettimeofday. */ +#define sin innocuous_sin + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char sin (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef sin + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char sin (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_sin) || defined (__stub___sin) +choke me +#else +char (*f) () = sin; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != sin; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_sin=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_func_sin=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_func_sin" >&5 +echo "${ECHO_T}$ac_cv_func_sin" >&6 +if test $ac_cv_func_sin = yes; then MATH_LIBS="" else MATH_LIBS="-lm" fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lieee" >&5 -$as_echo_n "checking for main in -lieee... " >&6; } -if ${ac_cv_lib_ieee_main+:} false; then : - $as_echo_n "(cached) " >&6 + echo "$as_me:$LINENO: checking for main in -lieee" >&5 +echo $ECHO_N "checking for main in -lieee... $ECHO_C" >&6 +if test "${ac_cv_lib_ieee_main+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lieee $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { -return main (); +main (); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then ac_cv_lib_ieee_main=yes else - ac_cv_lib_ieee_main=no + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_ieee_main=no fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ieee_main" >&5 -$as_echo "$ac_cv_lib_ieee_main" >&6; } -if test "x$ac_cv_lib_ieee_main" = xyes; then : +echo "$as_me:$LINENO: result: $ac_cv_lib_ieee_main" >&5 +echo "${ECHO_T}$ac_cv_lib_ieee_main" >&6 +if test $ac_cv_lib_ieee_main = yes; then MATH_LIBS="-lieee $MATH_LIBS" fi @@ -4351,45 +5160,211 @@ fi # needs net/errno.h to define the socket-related error codes. #-------------------------------------------------------------------- - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -linet" >&5 -$as_echo_n "checking for main in -linet... " >&6; } -if ${ac_cv_lib_inet_main+:} false; then : - $as_echo_n "(cached) " >&6 + echo "$as_me:$LINENO: checking for main in -linet" >&5 +echo $ECHO_N "checking for main in -linet... $ECHO_C" >&6 +if test "${ac_cv_lib_inet_main+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-linet $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { -return main (); +main (); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then ac_cv_lib_inet_main=yes else - ac_cv_lib_inet_main=no + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_inet_main=no fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_inet_main" >&5 -$as_echo "$ac_cv_lib_inet_main" >&6; } -if test "x$ac_cv_lib_inet_main" = xyes; then : +echo "$as_me:$LINENO: result: $ac_cv_lib_inet_main" >&5 +echo "${ECHO_T}$ac_cv_lib_inet_main" >&6 +if test $ac_cv_lib_inet_main = yes; then LIBS="$LIBS -linet" fi - ac_fn_c_check_header_mongrel "$LINENO" "net/errno.h" "ac_cv_header_net_errno_h" "$ac_includes_default" -if test "x$ac_cv_header_net_errno_h" = xyes; then : + if test "${ac_cv_header_net_errno_h+set}" = set; then + echo "$as_me:$LINENO: checking for net/errno.h" >&5 +echo $ECHO_N "checking for net/errno.h... $ECHO_C" >&6 +if test "${ac_cv_header_net_errno_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: $ac_cv_header_net_errno_h" >&5 +echo "${ECHO_T}$ac_cv_header_net_errno_h" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking net/errno.h usability" >&5 +echo $ECHO_N "checking net/errno.h usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking net/errno.h presence" >&5 +echo $ECHO_N "checking net/errno.h presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: net/errno.h: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: net/errno.h: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: net/errno.h: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: net/errno.h: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: net/errno.h: present but cannot be compiled" >&5 +echo "$as_me: WARNING: net/errno.h: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: net/errno.h: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: net/errno.h: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: net/errno.h: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: net/errno.h: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: net/errno.h: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: net/errno.h: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: net/errno.h: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: net/errno.h: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: net/errno.h: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: net/errno.h: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +## ------------------------------ ## +## Report this to the tcl lists. ## +## ------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for net/errno.h" >&5 +echo $ECHO_N "checking for net/errno.h... $ECHO_C" >&6 +if test "${ac_cv_header_net_errno_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_header_net_errno_h=$ac_header_preproc +fi +echo "$as_me:$LINENO: result: $ac_cv_header_net_errno_h" >&5 +echo "${ECHO_T}$ac_cv_header_net_errno_h" >&6 + +fi +if test $ac_cv_header_net_errno_h = yes; then -$as_echo "#define HAVE_NET_ERRNO_H 1" >>confdefs.h +cat >>confdefs.h <<\_ACEOF +#define HAVE_NET_ERRNO_H 1 +_ACEOF fi @@ -4414,115 +5389,527 @@ fi #-------------------------------------------------------------------- tcl_checkBoth=0 - ac_fn_c_check_func "$LINENO" "connect" "ac_cv_func_connect" -if test "x$ac_cv_func_connect" = xyes; then : - tcl_checkSocket=0 + echo "$as_me:$LINENO: checking for connect" >&5 +echo $ECHO_N "checking for connect... $ECHO_C" >&6 +if test "${ac_cv_func_connect+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 else - tcl_checkSocket=1 -fi + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define connect to an innocuous variant, in case declares connect. + For example, HP-UX 11i declares gettimeofday. */ +#define connect innocuous_connect - if test "$tcl_checkSocket" = 1; then - ac_fn_c_check_func "$LINENO" "setsockopt" "ac_cv_func_setsockopt" -if test "x$ac_cv_func_setsockopt" = xyes; then : +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char connect (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ -else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for setsockopt in -lsocket" >&5 -$as_echo_n "checking for setsockopt in -lsocket... " >&6; } -if ${ac_cv_lib_socket_setsockopt+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lsocket $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ +#undef connect + +/* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" +{ #endif -char setsockopt (); +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char connect (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_connect) || defined (__stub___connect) +choke me +#else +char (*f) () = connect; +#endif +#ifdef __cplusplus +} +#endif + int main () { -return setsockopt (); +return f != connect; ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_socket_setsockopt=yes +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_connect=yes else - ac_cv_lib_socket_setsockopt=no + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_func_connect=no fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_setsockopt" >&5 -$as_echo "$ac_cv_lib_socket_setsockopt" >&6; } -if test "x$ac_cv_lib_socket_setsockopt" = xyes; then : - LIBS="$LIBS -lsocket" +echo "$as_me:$LINENO: result: $ac_cv_func_connect" >&5 +echo "${ECHO_T}$ac_cv_func_connect" >&6 +if test $ac_cv_func_connect = yes; then + tcl_checkSocket=0 else - tcl_checkBoth=1 -fi - + tcl_checkSocket=1 fi - fi - if test "$tcl_checkBoth" = 1; then - tk_oldLibs=$LIBS - LIBS="$LIBS -lsocket -lnsl" - ac_fn_c_check_func "$LINENO" "accept" "ac_cv_func_accept" -if test "x$ac_cv_func_accept" = xyes; then : - tcl_checkNsl=0 + if test "$tcl_checkSocket" = 1; then + echo "$as_me:$LINENO: checking for setsockopt" >&5 +echo $ECHO_N "checking for setsockopt... $ECHO_C" >&6 +if test "${ac_cv_func_setsockopt+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 else - LIBS=$tk_oldLibs -fi + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define setsockopt to an innocuous variant, in case declares setsockopt. + For example, HP-UX 11i declares gettimeofday. */ +#define setsockopt innocuous_setsockopt - fi - ac_fn_c_check_func "$LINENO" "gethostbyname" "ac_cv_func_gethostbyname" -if test "x$ac_cv_func_gethostbyname" = xyes; then : +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char setsockopt (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ -else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyname in -lnsl" >&5 -$as_echo_n "checking for gethostbyname in -lnsl... " >&6; } -if ${ac_cv_lib_nsl_gethostbyname+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lnsl $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ +#undef setsockopt + +/* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" +{ #endif -char gethostbyname (); +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char setsockopt (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_setsockopt) || defined (__stub___setsockopt) +choke me +#else +char (*f) () = setsockopt; +#endif +#ifdef __cplusplus +} +#endif + int main () { -return gethostbyname (); +return f != setsockopt; ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_nsl_gethostbyname=yes +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_setsockopt=yes else - ac_cv_lib_nsl_gethostbyname=no + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_func_setsockopt=no fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_func_setsockopt" >&5 +echo "${ECHO_T}$ac_cv_func_setsockopt" >&6 +if test $ac_cv_func_setsockopt = yes; then + : +else + echo "$as_me:$LINENO: checking for setsockopt in -lsocket" >&5 +echo $ECHO_N "checking for setsockopt in -lsocket... $ECHO_C" >&6 +if test "${ac_cv_lib_socket_setsockopt+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsocket $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char setsockopt (); +int +main () +{ +setsockopt (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_socket_setsockopt=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_socket_setsockopt=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_socket_setsockopt" >&5 +echo "${ECHO_T}$ac_cv_lib_socket_setsockopt" >&6 +if test $ac_cv_lib_socket_setsockopt = yes; then + LIBS="$LIBS -lsocket" +else + tcl_checkBoth=1 +fi + +fi + + fi + if test "$tcl_checkBoth" = 1; then + tk_oldLibs=$LIBS + LIBS="$LIBS -lsocket -lnsl" + echo "$as_me:$LINENO: checking for accept" >&5 +echo $ECHO_N "checking for accept... $ECHO_C" >&6 +if test "${ac_cv_func_accept+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define accept to an innocuous variant, in case declares accept. + For example, HP-UX 11i declares gettimeofday. */ +#define accept innocuous_accept + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char accept (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef accept + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char accept (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_accept) || defined (__stub___accept) +choke me +#else +char (*f) () = accept; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != accept; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_accept=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_func_accept=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_func_accept" >&5 +echo "${ECHO_T}$ac_cv_func_accept" >&6 +if test $ac_cv_func_accept = yes; then + tcl_checkNsl=0 +else + LIBS=$tk_oldLibs +fi + + fi + echo "$as_me:$LINENO: checking for gethostbyname" >&5 +echo $ECHO_N "checking for gethostbyname... $ECHO_C" >&6 +if test "${ac_cv_func_gethostbyname+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define gethostbyname to an innocuous variant, in case declares gethostbyname. + For example, HP-UX 11i declares gettimeofday. */ +#define gethostbyname innocuous_gethostbyname + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char gethostbyname (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef gethostbyname + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char gethostbyname (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_gethostbyname) || defined (__stub___gethostbyname) +choke me +#else +char (*f) () = gethostbyname; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != gethostbyname; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_gethostbyname=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_func_gethostbyname=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_func_gethostbyname" >&5 +echo "${ECHO_T}$ac_cv_func_gethostbyname" >&6 +if test $ac_cv_func_gethostbyname = yes; then + : +else + echo "$as_me:$LINENO: checking for gethostbyname in -lnsl" >&5 +echo $ECHO_N "checking for gethostbyname in -lnsl... $ECHO_C" >&6 +if test "${ac_cv_lib_nsl_gethostbyname+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lnsl $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char gethostbyname (); +int +main () +{ +gethostbyname (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_nsl_gethostbyname=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_nsl_gethostbyname=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nsl_gethostbyname" >&5 -$as_echo "$ac_cv_lib_nsl_gethostbyname" >&6; } -if test "x$ac_cv_lib_nsl_gethostbyname" = xyes; then : +echo "$as_me:$LINENO: result: $ac_cv_lib_nsl_gethostbyname" >&5 +echo "${ECHO_T}$ac_cv_lib_nsl_gethostbyname" >&6 +if test $ac_cv_lib_nsl_gethostbyname = yes; then LIBS="$LIBS -lnsl" fi @@ -4534,15 +5921,15 @@ fi LIBS="$LIBS$THREADS_LIBS" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to build libraries" >&5 -$as_echo_n "checking how to build libraries... " >&6; } - # Check whether --enable-shared was given. -if test "${enable_shared+set}" = set; then : - enableval=$enable_shared; tcl_ok=$enableval + echo "$as_me:$LINENO: checking how to build libraries" >&5 +echo $ECHO_N "checking how to build libraries... $ECHO_C" >&6 + # Check whether --enable-shared or --disable-shared was given. +if test "${enable_shared+set}" = set; then + enableval="$enable_shared" + tcl_ok=$enableval else tcl_ok=yes -fi - +fi; if test "${enable_shared+set}" = set; then enableval="$enable_shared" @@ -4552,15 +5939,17 @@ fi fi if test "$tcl_ok" = "yes" ; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: shared" >&5 -$as_echo "shared" >&6; } + echo "$as_me:$LINENO: result: shared" >&5 +echo "${ECHO_T}shared" >&6 SHARED_BUILD=1 else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: static" >&5 -$as_echo "static" >&6; } + echo "$as_me:$LINENO: result: static" >&5 +echo "${ECHO_T}static" >&6 SHARED_BUILD=0 -$as_echo "#define STATIC_BUILD 1" >>confdefs.h +cat >>confdefs.h <<\_ACEOF +#define STATIC_BUILD 1 +_ACEOF fi @@ -4572,10 +5961,10 @@ $as_echo "#define STATIC_BUILD 1" >>confdefs.h #-------------------------------------------------------------------- - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for tclsh" >&5 -$as_echo_n "checking for tclsh... " >&6; } - if ${ac_cv_path_tclsh+:} false; then : - $as_echo_n "(cached) " >&6 + echo "$as_me:$LINENO: checking for tclsh" >&5 +echo $ECHO_N "checking for tclsh... $ECHO_C" >&6 + if test "${ac_cv_path_tclsh+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 else search_path=`echo ${PATH} | sed -e 's/:/ /g'` @@ -4596,13 +5985,13 @@ fi if test -f "$ac_cv_path_tclsh" ; then TCLSH_PROG="$ac_cv_path_tclsh" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $TCLSH_PROG" >&5 -$as_echo "$TCLSH_PROG" >&6; } + echo "$as_me:$LINENO: result: $TCLSH_PROG" >&5 +echo "${ECHO_T}$TCLSH_PROG" >&6 else # It is not an error if an installed version of Tcl can't be located. TCLSH_PROG="" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: No tclsh found on PATH" >&5 -$as_echo "No tclsh found on PATH" >&6; } + echo "$as_me:$LINENO: result: No tclsh found on PATH" >&5 +echo "${ECHO_T}No tclsh found on PATH" >&6 fi @@ -4615,113 +6004,378 @@ fi #------------------------------------------------------------------------ zlib_ok=yes -ac_fn_c_check_header_mongrel "$LINENO" "zlib.h" "ac_cv_header_zlib_h" "$ac_includes_default" -if test "x$ac_cv_header_zlib_h" = xyes; then : +if test "${ac_cv_header_zlib_h+set}" = set; then + echo "$as_me:$LINENO: checking for zlib.h" >&5 +echo $ECHO_N "checking for zlib.h... $ECHO_C" >&6 +if test "${ac_cv_header_zlib_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: $ac_cv_header_zlib_h" >&5 +echo "${ECHO_T}$ac_cv_header_zlib_h" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking zlib.h usability" >&5 +echo $ECHO_N "checking zlib.h usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 - ac_fn_c_check_type "$LINENO" "gz_header" "ac_cv_type_gz_header" "#include -" -if test "x$ac_cv_type_gz_header" = xyes; then : +ac_header_compiler=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 +# Is the header present? +echo "$as_me:$LINENO: checking zlib.h presence" >&5 +echo $ECHO_N "checking zlib.h presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi else - zlib_ok=no + ac_cpp_err=yes fi - +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 - zlib_ok=no + ac_header_preproc=no fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: zlib.h: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: zlib.h: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: zlib.h: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: zlib.h: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: zlib.h: present but cannot be compiled" >&5 +echo "$as_me: WARNING: zlib.h: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: zlib.h: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: zlib.h: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: zlib.h: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: zlib.h: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: zlib.h: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: zlib.h: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: zlib.h: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: zlib.h: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: zlib.h: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: zlib.h: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +## ------------------------------ ## +## Report this to the tcl lists. ## +## ------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for zlib.h" >&5 +echo $ECHO_N "checking for zlib.h... $ECHO_C" >&6 +if test "${ac_cv_header_zlib_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_header_zlib_h=$ac_header_preproc +fi +echo "$as_me:$LINENO: result: $ac_cv_header_zlib_h" >&5 +echo "${ECHO_T}$ac_cv_header_zlib_h" >&6 -if test $zlib_ok = yes; then : +fi +if test $ac_cv_header_zlib_h = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing deflateSetHeader" >&5 -$as_echo_n "checking for library containing deflateSetHeader... " >&6; } -if ${ac_cv_search_deflateSetHeader+:} false; then : - $as_echo_n "(cached) " >&6 + echo "$as_me:$LINENO: checking for gz_header" >&5 +echo $ECHO_N "checking for gz_header... $ECHO_C" >&6 +if test "${ac_cv_type_gz_header+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 else - ac_func_search_save_LIBS=$LIBS -cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ +#include -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char deflateSetHeader (); int main () { -return deflateSetHeader (); +if ((gz_header *) 0) + return 0; +if (sizeof (gz_header)) + return 0; ; return 0; } _ACEOF -for ac_lib in '' z; do - if test -z "$ac_lib"; then - ac_res="none required" - else - ac_res=-l$ac_lib - LIBS="-l$ac_lib $ac_func_search_save_LIBS" - fi - if ac_fn_c_try_link "$LINENO"; then : - ac_cv_search_deflateSetHeader=$ac_res +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_type_gz_header=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_type_gz_header=no fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext - if ${ac_cv_search_deflateSetHeader+:} false; then : - break +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi -done -if ${ac_cv_search_deflateSetHeader+:} false; then : - +echo "$as_me:$LINENO: result: $ac_cv_type_gz_header" >&5 +echo "${ECHO_T}$ac_cv_type_gz_header" >&6 +if test $ac_cv_type_gz_header = yes; then + : else - ac_cv_search_deflateSetHeader=no -fi -rm conftest.$ac_ext -LIBS=$ac_func_search_save_LIBS + zlib_ok=no fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_deflateSetHeader" >&5 -$as_echo "$ac_cv_search_deflateSetHeader" >&6; } -ac_res=$ac_cv_search_deflateSetHeader -if test "$ac_res" != no; then : - test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" else - zlib_ok=no - -fi - + zlib_ok=no fi -if test $zlib_ok = no; then : - ZLIB_OBJS=\${ZLIB_OBJS} - - ZLIB_SRCS=\${ZLIB_SRCS} - - ZLIB_INCLUDE=-I\${ZLIB_DIR} - - -fi -$as_echo "#define HAVE_ZLIB 1" >>confdefs.h +if test $zlib_ok = yes; then + echo "$as_me:$LINENO: checking for library containing deflateSetHeader" >&5 +echo $ECHO_N "checking for library containing deflateSetHeader... $ECHO_C" >&6 +if test "${ac_cv_search_deflateSetHeader+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_func_search_save_LIBS=$LIBS +ac_cv_search_deflateSetHeader=no +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ -#-------------------------------------------------------------------- -# The statements below define a collection of compile flags. This -# macro depends on the value of SHARED_BUILD, and should be called -# after SC_ENABLE_SHARED checks the configure switches. +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char deflateSetHeader (); +int +main () +{ +deflateSetHeader (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_search_deflateSetHeader="none required" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +if test "$ac_cv_search_deflateSetHeader" = no; then + for ac_lib in z; do + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char deflateSetHeader (); +int +main () +{ +deflateSetHeader (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_search_deflateSetHeader="-l$ac_lib" +break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + done +fi +LIBS=$ac_func_search_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_search_deflateSetHeader" >&5 +echo "${ECHO_T}$ac_cv_search_deflateSetHeader" >&6 +if test "$ac_cv_search_deflateSetHeader" != no; then + test "$ac_cv_search_deflateSetHeader" = "none required" || LIBS="$ac_cv_search_deflateSetHeader $LIBS" + +else + + zlib_ok=no + +fi + +fi + +if test $zlib_ok = no; then + + ZLIB_OBJS=\${ZLIB_OBJS} + + ZLIB_SRCS=\${ZLIB_SRCS} + + ZLIB_INCLUDE=-I\${ZLIB_DIR} + + +fi + + +cat >>confdefs.h <<\_ACEOF +#define HAVE_ZLIB 1 +_ACEOF + + +#-------------------------------------------------------------------- +# The statements below define a collection of compile flags. This +# macro depends on the value of SHARED_BUILD, and should be called +# after SC_ENABLE_SHARED checks the configure switches. #-------------------------------------------------------------------- if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. set dummy ${ac_tool_prefix}ranlib; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_RANLIB+:} false; then : - $as_echo_n "(cached) " >&6 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_RANLIB+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$RANLIB"; then ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. @@ -4731,37 +6385,35 @@ for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done - done -IFS=$as_save_IFS +done fi fi RANLIB=$ac_cv_prog_RANLIB if test -n "$RANLIB"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 -$as_echo "$RANLIB" >&6; } + echo "$as_me:$LINENO: result: $RANLIB" >&5 +echo "${ECHO_T}$RANLIB" >&6 else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 fi - fi if test -z "$ac_cv_prog_RANLIB"; then ac_ct_RANLIB=$RANLIB # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : - $as_echo_n "(cached) " >&6 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_RANLIB"; then ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. @@ -4771,38 +6423,28 @@ for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_RANLIB="ranlib" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done - done -IFS=$as_save_IFS +done + test -z "$ac_cv_prog_ac_ct_RANLIB" && ac_cv_prog_ac_ct_RANLIB=":" fi fi ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB if test -n "$ac_ct_RANLIB"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 -$as_echo "$ac_ct_RANLIB" >&6; } + echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5 +echo "${ECHO_T}$ac_ct_RANLIB" >&6 else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 fi - if test "x$ac_ct_RANLIB" = x; then - RANLIB=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - RANLIB=$ac_ct_RANLIB - fi + RANLIB=$ac_ct_RANLIB else RANLIB="$ac_cv_prog_RANLIB" fi @@ -4811,47 +6453,52 @@ fi # Step 0.a: Enable 64 bit support? - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if 64bit support is requested" >&5 -$as_echo_n "checking if 64bit support is requested... " >&6; } - # Check whether --enable-64bit was given. -if test "${enable_64bit+set}" = set; then : - enableval=$enable_64bit; do64bit=$enableval + echo "$as_me:$LINENO: checking if 64bit support is requested" >&5 +echo $ECHO_N "checking if 64bit support is requested... $ECHO_C" >&6 + # Check whether --enable-64bit or --disable-64bit was given. +if test "${enable_64bit+set}" = set; then + enableval="$enable_64bit" + do64bit=$enableval else do64bit=no -fi - - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $do64bit" >&5 -$as_echo "$do64bit" >&6; } +fi; + echo "$as_me:$LINENO: result: $do64bit" >&5 +echo "${ECHO_T}$do64bit" >&6 # Step 0.b: Enable Solaris 64 bit VIS support? - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if 64bit Sparc VIS support is requested" >&5 -$as_echo_n "checking if 64bit Sparc VIS support is requested... " >&6; } - # Check whether --enable-64bit-vis was given. -if test "${enable_64bit_vis+set}" = set; then : - enableval=$enable_64bit_vis; do64bitVIS=$enableval + echo "$as_me:$LINENO: checking if 64bit Sparc VIS support is requested" >&5 +echo $ECHO_N "checking if 64bit Sparc VIS support is requested... $ECHO_C" >&6 + # Check whether --enable-64bit-vis or --disable-64bit-vis was given. +if test "${enable_64bit_vis+set}" = set; then + enableval="$enable_64bit_vis" + do64bitVIS=$enableval else do64bitVIS=no -fi - - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $do64bitVIS" >&5 -$as_echo "$do64bitVIS" >&6; } +fi; + echo "$as_me:$LINENO: result: $do64bitVIS" >&5 +echo "${ECHO_T}$do64bitVIS" >&6 # Force 64bit on with VIS - if test "$do64bitVIS" = "yes"; then : + if test "$do64bitVIS" = "yes"; then do64bit=yes fi + # Step 0.c: Check if visibility support is available. Do this here so # that platform specific alternatives can be used below if this fails. - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if compiler supports visibility \"hidden\"" >&5 -$as_echo_n "checking if compiler supports visibility \"hidden\"... " >&6; } -if ${tcl_cv_cc_visibility_hidden+:} false; then : - $as_echo_n "(cached) " >&6 + echo "$as_me:$LINENO: checking if compiler supports visibility \"hidden\"" >&5 +echo $ECHO_N "checking if compiler supports visibility \"hidden\"... $ECHO_C" >&6 +if test "${tcl_cv_cc_visibility_hidden+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 else hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -Werror" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ extern __attribute__((__visibility__("hidden"))) void f(void); @@ -4864,50 +6511,79 @@ f(); return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then tcl_cv_cc_visibility_hidden=yes else - tcl_cv_cc_visibility_hidden=no + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +tcl_cv_cc_visibility_hidden=no fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext CFLAGS=$hold_cflags fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_cc_visibility_hidden" >&5 -$as_echo "$tcl_cv_cc_visibility_hidden" >&6; } - if test $tcl_cv_cc_visibility_hidden = yes; then : +echo "$as_me:$LINENO: result: $tcl_cv_cc_visibility_hidden" >&5 +echo "${ECHO_T}$tcl_cv_cc_visibility_hidden" >&6 + if test $tcl_cv_cc_visibility_hidden = yes; then -$as_echo "#define MODULE_SCOPE extern __attribute__((__visibility__(\"hidden\")))" >>confdefs.h +cat >>confdefs.h <<\_ACEOF +#define MODULE_SCOPE extern __attribute__((__visibility__("hidden"))) +_ACEOF -$as_echo "#define HAVE_HIDDEN 1" >>confdefs.h +cat >>confdefs.h <<\_ACEOF +#define HAVE_HIDDEN 1 +_ACEOF fi + # Step 0.d: Disable -rpath support? - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if rpath support is requested" >&5 -$as_echo_n "checking if rpath support is requested... " >&6; } - # Check whether --enable-rpath was given. -if test "${enable_rpath+set}" = set; then : - enableval=$enable_rpath; doRpath=$enableval + echo "$as_me:$LINENO: checking if rpath support is requested" >&5 +echo $ECHO_N "checking if rpath support is requested... $ECHO_C" >&6 + # Check whether --enable-rpath or --disable-rpath was given. +if test "${enable_rpath+set}" = set; then + enableval="$enable_rpath" + doRpath=$enableval else doRpath=yes -fi - - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $doRpath" >&5 -$as_echo "$doRpath" >&6; } +fi; + echo "$as_me:$LINENO: result: $doRpath" >&5 +echo "${ECHO_T}$doRpath" >&6 # Step 1: set the variable "system" to hold the name and version number # for the system. - { $as_echo "$as_me:${as_lineno-$LINENO}: checking system version" >&5 -$as_echo_n "checking system version... " >&6; } -if ${tcl_cv_sys_version+:} false; then : - $as_echo_n "(cached) " >&6 + echo "$as_me:$LINENO: checking system version" >&5 +echo $ECHO_N "checking system version... $ECHO_C" >&6 +if test "${tcl_cv_sys_version+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -f /usr/lib/NextStep/software_version; then @@ -4915,8 +6591,8 @@ else else tcl_cv_sys_version=`uname -s`-`uname -r` if test "$?" -ne 0 ; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: can't find uname command" >&5 -$as_echo "$as_me: WARNING: can't find uname command" >&2;} + { echo "$as_me:$LINENO: WARNING: can't find uname command" >&5 +echo "$as_me: WARNING: can't find uname command" >&2;} tcl_cv_sys_version=unknown else # Special check for weird MP-RAS system (uname returns weird @@ -4932,51 +6608,79 @@ $as_echo "$as_me: WARNING: can't find uname command" >&2;} fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_sys_version" >&5 -$as_echo "$tcl_cv_sys_version" >&6; } +echo "$as_me:$LINENO: result: $tcl_cv_sys_version" >&5 +echo "${ECHO_T}$tcl_cv_sys_version" >&6 system=$tcl_cv_sys_version # Step 2: check for existence of -ldl library. This is needed because # Linux can use either -ldl or -ldld for dynamic loading. - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 -$as_echo_n "checking for dlopen in -ldl... " >&6; } -if ${ac_cv_lib_dl_dlopen+:} false; then : - $as_echo_n "(cached) " >&6 + echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5 +echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6 +if test "${ac_cv_lib_dl_dlopen+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ +/* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ char dlopen (); int main () { -return dlopen (); +dlopen (); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then ac_cv_lib_dl_dlopen=yes else - ac_cv_lib_dl_dlopen=no + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_dl_dlopen=no fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 -$as_echo "$ac_cv_lib_dl_dlopen" >&6; } -if test "x$ac_cv_lib_dl_dlopen" = xyes; then : +echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5 +echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6 +if test $ac_cv_lib_dl_dlopen = yes; then have_dl=yes else have_dl=no @@ -5002,7 +6706,7 @@ fi ECHO_VERSION='`echo ${VERSION}`' TCL_LIB_VERSIONS_OK=ok CFLAGS_DEBUG=-g - if test "$GCC" = yes; then : + if test "$GCC" = yes; then CFLAGS_OPTIMIZE=-O2 CFLAGS_WARNING="-Wall" @@ -5013,13 +6717,14 @@ else CFLAGS_WARNING="" fi + if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args. set dummy ${ac_tool_prefix}ar; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_AR+:} false; then : - $as_echo_n "(cached) " >&6 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_AR+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$AR"; then ac_cv_prog_AR="$AR" # Let the user override the test. @@ -5029,37 +6734,35 @@ for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AR="${ac_tool_prefix}ar" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done - done -IFS=$as_save_IFS +done fi fi AR=$ac_cv_prog_AR if test -n "$AR"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 -$as_echo "$AR" >&6; } + echo "$as_me:$LINENO: result: $AR" >&5 +echo "${ECHO_T}$AR" >&6 else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 fi - fi if test -z "$ac_cv_prog_AR"; then ac_ct_AR=$AR # Extract the first word of "ar", so it can be a program name with args. set dummy ar; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_AR+:} false; then : - $as_echo_n "(cached) " >&6 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_AR+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_AR"; then ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. @@ -5069,38 +6772,27 @@ for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_AR="ar" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done - done -IFS=$as_save_IFS +done fi fi ac_ct_AR=$ac_cv_prog_ac_ct_AR if test -n "$ac_ct_AR"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 -$as_echo "$ac_ct_AR" >&6; } + echo "$as_me:$LINENO: result: $ac_ct_AR" >&5 +echo "${ECHO_T}$ac_ct_AR" >&6 else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 fi - if test "x$ac_ct_AR" = x; then - AR="" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - AR=$ac_ct_AR - fi + AR=$ac_ct_AR else AR="$ac_cv_prog_AR" fi @@ -5110,12 +6802,13 @@ fi PLAT_OBJS="" PLAT_SRCS="" LDAIX_SRC="" - if test x"${SHLIB_VERSION}" = x; then : + if test x"${SHLIB_VERSION}" = x; then SHLIB_VERSION="1.0" fi + case $system in AIX-*) - if test "${TCL_THREADS}" = "1" -a "$GCC" != "yes"; then : + if test "${TCL_THREADS}" = "1" -a "$GCC" != "yes"; then # AIX requires the _r compiler when gcc isn't being used case "${CC}" in @@ -5127,10 +6820,11 @@ fi CC=`echo "$CC" | sed -e 's/^\([^ ]*\)/\1_r/'` ;; esac - { $as_echo "$as_me:${as_lineno-$LINENO}: result: Using $CC for compiling with threads" >&5 -$as_echo "Using $CC for compiling with threads" >&6; } + echo "$as_me:$LINENO: result: Using $CC for compiling with threads" >&5 +echo "${ECHO_T}Using $CC for compiling with threads" >&6 fi + LIBS="$LIBS -lc" SHLIB_CFLAGS="" SHLIB_SUFFIX=".so" @@ -5143,12 +6837,12 @@ fi LDAIX_SRC='$(UNIX_DIR)/ldAix' # Check to enable 64-bit flags for compiler/linker - if test "$do64bit" = yes; then : + if test "$do64bit" = yes; then - if test "$GCC" = yes; then : + if test "$GCC" = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 64bit mode not supported with GCC on $system" >&5 -$as_echo "$as_me: WARNING: 64bit mode not supported with GCC on $system" >&2;} + { echo "$as_me:$LINENO: WARNING: 64bit mode not supported with GCC on $system" >&5 +echo "$as_me: WARNING: 64bit mode not supported with GCC on $system" >&2;} else @@ -5161,15 +6855,17 @@ else fi + fi - if test "`uname -m`" = ia64; then : + + if test "`uname -m`" = ia64; then # AIX-5 uses ELF style dynamic libraries on IA-64, but not PPC SHLIB_LD="/usr/ccs/bin/ld -G -z text" # AIX-5 has dl* in libc.so DL_LIBS="" - if test "$GCC" = yes; then : + if test "$GCC" = yes; then CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}' @@ -5178,11 +6874,12 @@ else CC_SEARCH_FLAGS='-R${LIB_RUNTIME_DIR}' fi + LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}' else - if test "$GCC" = yes; then : + if test "$GCC" = yes; then SHLIB_LD='${CC} -shared -Wl,-bexpall' @@ -5192,12 +6889,14 @@ else LDFLAGS="$LDFLAGS -brtl" fi + SHLIB_LD="${SHLIB_LD} ${SHLIB_LD_FLAGS}" DL_LIBS="-ldl" CC_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}' LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} fi + ;; BeOS*) SHLIB_CFLAGS="-fPIC" @@ -5211,43 +6910,71 @@ fi # -lsocket, even if the network functions are in -lnet which # is always linked to, for compatibility. #----------------------------------------------------------- - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for inet_ntoa in -lbind" >&5 -$as_echo_n "checking for inet_ntoa in -lbind... " >&6; } -if ${ac_cv_lib_bind_inet_ntoa+:} false; then : - $as_echo_n "(cached) " >&6 + echo "$as_me:$LINENO: checking for inet_ntoa in -lbind" >&5 +echo $ECHO_N "checking for inet_ntoa in -lbind... $ECHO_C" >&6 +if test "${ac_cv_lib_bind_inet_ntoa+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lbind $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ +/* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ char inet_ntoa (); int main () { -return inet_ntoa (); +inet_ntoa (); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then ac_cv_lib_bind_inet_ntoa=yes else - ac_cv_lib_bind_inet_ntoa=no + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_bind_inet_ntoa=no fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_bind_inet_ntoa" >&5 -$as_echo "$ac_cv_lib_bind_inet_ntoa" >&6; } -if test "x$ac_cv_lib_bind_inet_ntoa" = xyes; then : +echo "$as_me:$LINENO: result: $ac_cv_lib_bind_inet_ntoa" >&5 +echo "${ECHO_T}$ac_cv_lib_bind_inet_ntoa" >&6 +if test $ac_cv_lib_bind_inet_ntoa = yes; then LIBS="$LIBS -lbind -lsocket" fi @@ -5284,12 +7011,16 @@ fi TCL_NEEDS_EXP_FILE=1 TCL_EXPORT_FILE_SUFFIX='${VERSION}\$\{DBGX\}.dll.a' SHLIB_LD_LIBS="${SHLIB_LD_LIBS} -Wl,--out-implib,\$@.a" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Cygwin version of gcc" >&5 -$as_echo_n "checking for Cygwin version of gcc... " >&6; } -if ${ac_cv_cygwin+:} false; then : - $as_echo_n "(cached) " >&6 + echo "$as_me:$LINENO: checking for Cygwin version of gcc" >&5 +echo $ECHO_N "checking for Cygwin version of gcc... $ECHO_C" >&6 +if test "${ac_cv_cygwin+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __CYGWIN__ @@ -5304,21 +7035,49 @@ main () return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then ac_cv_cygwin=no else - ac_cv_cygwin=yes + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_cygwin=yes fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cygwin" >&5 -$as_echo "$ac_cv_cygwin" >&6; } +echo "$as_me:$LINENO: result: $ac_cv_cygwin" >&5 +echo "${ECHO_T}$ac_cv_cygwin" >&6 if test "$ac_cv_cygwin" = "no"; then - as_fn_error $? "${CC} is not a cygwin compiler." "$LINENO" 5 + { { echo "$as_me:$LINENO: error: ${CC} is not a cygwin compiler." >&5 +echo "$as_me: error: ${CC} is not a cygwin compiler." >&2;} + { (exit 1); exit 1; }; } fi if test "x${TCL_THREADS}" = "x0"; then - as_fn_error $? "CYGWIN compile is only supported with --enable-threads" "$LINENO" 5 + { { echo "$as_me:$LINENO: error: CYGWIN compile is only supported with --enable-threads" >&5 +echo "$as_me: error: CYGWIN compile is only supported with --enable-threads" >&2;} + { (exit 1); exit 1; }; } fi do64bit_ok=yes if test "x${SHARED_BUILD}" = "x1"; then @@ -5348,43 +7107,71 @@ $as_echo "$ac_cv_cygwin" >&6; } SHLIB_LD='${CC} -shared ${CFLAGS} ${LDFLAGS}' DL_OBJS="tclLoadDl.o" DL_LIBS="-lroot" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for inet_ntoa in -lnetwork" >&5 -$as_echo_n "checking for inet_ntoa in -lnetwork... " >&6; } -if ${ac_cv_lib_network_inet_ntoa+:} false; then : - $as_echo_n "(cached) " >&6 + echo "$as_me:$LINENO: checking for inet_ntoa in -lnetwork" >&5 +echo $ECHO_N "checking for inet_ntoa in -lnetwork... $ECHO_C" >&6 +if test "${ac_cv_lib_network_inet_ntoa+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lnetwork $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ +/* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ char inet_ntoa (); int main () { -return inet_ntoa (); +inet_ntoa (); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then ac_cv_lib_network_inet_ntoa=yes else - ac_cv_lib_network_inet_ntoa=no + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_network_inet_ntoa=no fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_network_inet_ntoa" >&5 -$as_echo "$ac_cv_lib_network_inet_ntoa" >&6; } -if test "x$ac_cv_lib_network_inet_ntoa" = xyes; then : +echo "$as_me:$LINENO: result: $ac_cv_lib_network_inet_ntoa" >&5 +echo "${ECHO_T}$ac_cv_lib_network_inet_ntoa" >&6 +if test $ac_cv_lib_network_inet_ntoa = yes; then LIBS="$LIBS -lnetwork" fi @@ -5392,14 +7179,18 @@ fi HP-UX-*.11.*) # Use updated header definitions where possible -$as_echo "#define _XOPEN_SOURCE_EXTENDED 1" >>confdefs.h +cat >>confdefs.h <<\_ACEOF +#define _XOPEN_SOURCE_EXTENDED 1 +_ACEOF -$as_echo "#define _XOPEN_SOURCE 1" >>confdefs.h +cat >>confdefs.h <<\_ACEOF +#define _XOPEN_SOURCE 1 +_ACEOF LIBS="$LIBS -lxnet" # Use the XOPEN network library - if test "`uname -m`" = ia64; then : + if test "`uname -m`" = ia64; then SHLIB_SUFFIX=".so" @@ -5408,49 +7199,78 @@ else SHLIB_SUFFIX=".sl" fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5 -$as_echo_n "checking for shl_load in -ldld... " >&6; } -if ${ac_cv_lib_dld_shl_load+:} false; then : - $as_echo_n "(cached) " >&6 + + echo "$as_me:$LINENO: checking for shl_load in -ldld" >&5 +echo $ECHO_N "checking for shl_load in -ldld... $ECHO_C" >&6 +if test "${ac_cv_lib_dld_shl_load+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ +/* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ char shl_load (); int main () { -return shl_load (); +shl_load (); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then ac_cv_lib_dld_shl_load=yes else - ac_cv_lib_dld_shl_load=no + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_dld_shl_load=no fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5 -$as_echo "$ac_cv_lib_dld_shl_load" >&6; } -if test "x$ac_cv_lib_dld_shl_load" = xyes; then : +echo "$as_me:$LINENO: result: $ac_cv_lib_dld_shl_load" >&5 +echo "${ECHO_T}$ac_cv_lib_dld_shl_load" >&6 +if test $ac_cv_lib_dld_shl_load = yes; then tcl_ok=yes else tcl_ok=no fi - if test "$tcl_ok" = yes; then : + if test "$tcl_ok" = yes; then SHLIB_CFLAGS="+z" SHLIB_LD="ld -b" @@ -5462,7 +7282,8 @@ fi LD_LIBRARY_PATH_VAR="SHLIB_PATH" fi - if test "$GCC" = yes; then : + + if test "$GCC" = yes; then SHLIB_LD='${CC} -shared' LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} @@ -5473,28 +7294,30 @@ else fi + # Users may want PA-RISC 1.1/2.0 portable code - needs HP cc #CFLAGS="$CFLAGS +DAportable" # Check to enable 64-bit flags for compiler/linker - if test "$do64bit" = "yes"; then : + if test "$do64bit" = "yes"; then - if test "$GCC" = yes; then : + if test "$GCC" = yes; then case `${CC} -dumpmachine` in hppa64*) # 64-bit gcc in use. Fix flags for GNU ld. do64bit_ok=yes SHLIB_LD='${CC} -shared' - if test $doRpath = yes; then : + if test $doRpath = yes; then CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' fi + LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} ;; *) - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 64bit mode not supported with GCC on $system" >&5 -$as_echo "$as_me: WARNING: 64bit mode not supported with GCC on $system" >&2;} + { echo "$as_me:$LINENO: WARNING: 64bit mode not supported with GCC on $system" >&5 +echo "$as_me: WARNING: 64bit mode not supported with GCC on $system" >&2;} ;; esac @@ -5506,52 +7329,82 @@ else fi -fi ;; + +fi + ;; HP-UX-*.08.*|HP-UX-*.09.*|HP-UX-*.10.*) SHLIB_SUFFIX=".sl" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5 -$as_echo_n "checking for shl_load in -ldld... " >&6; } -if ${ac_cv_lib_dld_shl_load+:} false; then : - $as_echo_n "(cached) " >&6 + echo "$as_me:$LINENO: checking for shl_load in -ldld" >&5 +echo $ECHO_N "checking for shl_load in -ldld... $ECHO_C" >&6 +if test "${ac_cv_lib_dld_shl_load+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ +/* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ char shl_load (); int main () { -return shl_load (); +shl_load (); ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then ac_cv_lib_dld_shl_load=yes else - ac_cv_lib_dld_shl_load=no + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_dld_shl_load=no fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5 -$as_echo "$ac_cv_lib_dld_shl_load" >&6; } -if test "x$ac_cv_lib_dld_shl_load" = xyes; then : +echo "$as_me:$LINENO: result: $ac_cv_lib_dld_shl_load" >&5 +echo "${ECHO_T}$ac_cv_lib_dld_shl_load" >&6 +if test $ac_cv_lib_dld_shl_load = yes; then tcl_ok=yes else tcl_ok=no fi - if test "$tcl_ok" = yes; then : + if test "$tcl_ok" = yes; then SHLIB_CFLAGS="+z" SHLIB_LD="ld -b" @@ -5563,24 +7416,28 @@ fi LD_SEARCH_FLAGS='+s +b ${LIB_RUNTIME_DIR}:.' LD_LIBRARY_PATH_VAR="SHLIB_PATH" -fi ;; +fi + ;; IRIX-5.*) SHLIB_CFLAGS="" SHLIB_LD="ld -shared -rdata_shared" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" - case " $LIBOBJS " in + case $LIBOBJS in + "mkstemp.$ac_objext" | \ + *" mkstemp.$ac_objext" | \ + "mkstemp.$ac_objext "* | \ *" mkstemp.$ac_objext "* ) ;; - *) LIBOBJS="$LIBOBJS mkstemp.$ac_objext" - ;; + *) LIBOBJS="$LIBOBJS mkstemp.$ac_objext" ;; esac - if test $doRpath = yes; then : + if test $doRpath = yes; then CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}' fi + ;; IRIX-6.*) SHLIB_CFLAGS="" @@ -5588,18 +7445,21 @@ fi SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" - case " $LIBOBJS " in + case $LIBOBJS in + "mkstemp.$ac_objext" | \ + *" mkstemp.$ac_objext" | \ + "mkstemp.$ac_objext "* | \ *" mkstemp.$ac_objext "* ) ;; - *) LIBOBJS="$LIBOBJS mkstemp.$ac_objext" - ;; + *) LIBOBJS="$LIBOBJS mkstemp.$ac_objext" ;; esac - if test $doRpath = yes; then : + if test $doRpath = yes; then CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}' fi - if test "$GCC" = yes; then : + + if test "$GCC" = yes; then CFLAGS="$CFLAGS -mabi=n32" LDFLAGS="$LDFLAGS -mabi=n32" @@ -5618,6 +7478,7 @@ else LDFLAGS="$LDFLAGS -n32" fi + ;; IRIX64-6.*) SHLIB_CFLAGS="" @@ -5625,26 +7486,29 @@ fi SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" - case " $LIBOBJS " in + case $LIBOBJS in + "mkstemp.$ac_objext" | \ + *" mkstemp.$ac_objext" | \ + "mkstemp.$ac_objext "* | \ *" mkstemp.$ac_objext "* ) ;; - *) LIBOBJS="$LIBOBJS mkstemp.$ac_objext" - ;; + *) LIBOBJS="$LIBOBJS mkstemp.$ac_objext" ;; esac - if test $doRpath = yes; then : + if test $doRpath = yes; then CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}' fi + # Check to enable 64-bit flags for compiler/linker - if test "$do64bit" = yes; then : + if test "$do64bit" = yes; then - if test "$GCC" = yes; then : + if test "$GCC" = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 64bit mode not supported by gcc" >&5 -$as_echo "$as_me: WARNING: 64bit mode not supported by gcc" >&2;} + { echo "$as_me:$LINENO: WARNING: 64bit mode not supported by gcc" >&5 +echo "$as_me: WARNING: 64bit mode not supported by gcc" >&2;} else @@ -5655,7 +7519,9 @@ else fi + fi + ;; Linux*|GNU*|NetBSD-Debian) SHLIB_CFLAGS="-fPIC" @@ -5671,25 +7537,31 @@ fi DL_OBJS="tclLoadDl.o" DL_LIBS="-ldl" LDFLAGS="$LDFLAGS -Wl,--export-dynamic" - if test $doRpath = yes; then : + if test $doRpath = yes; then CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' fi + LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} - if test "`uname -m`" = "alpha"; then : + if test "`uname -m`" = "alpha"; then CFLAGS="$CFLAGS -mieee" fi - if test $do64bit = yes; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if compiler accepts -m64 flag" >&5 -$as_echo_n "checking if compiler accepts -m64 flag... " >&6; } -if ${tcl_cv_cc_m64+:} false; then : - $as_echo_n "(cached) " >&6 + if test $do64bit = yes; then + + echo "$as_me:$LINENO: checking if compiler accepts -m64 flag" >&5 +echo $ECHO_N "checking if compiler accepts -m64 flag... $ECHO_C" >&6 +if test "${tcl_cv_cc_m64+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 else hold_cflags=$CFLAGS CFLAGS="$CFLAGS -m64" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int @@ -5700,35 +7572,62 @@ main () return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then tcl_cv_cc_m64=yes else - tcl_cv_cc_m64=no + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +tcl_cv_cc_m64=no fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext CFLAGS=$hold_cflags fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_cc_m64" >&5 -$as_echo "$tcl_cv_cc_m64" >&6; } - if test $tcl_cv_cc_m64 = yes; then : +echo "$as_me:$LINENO: result: $tcl_cv_cc_m64" >&5 +echo "${ECHO_T}$tcl_cv_cc_m64" >&6 + if test $tcl_cv_cc_m64 = yes; then CFLAGS="$CFLAGS -m64" do64bit_ok=yes fi + fi + # The combo of gcc + glibc has a bug related to inlining of # functions like strtod(). The -fno-builtin flag should address # this problem but it does not work. The -fno-inline flag is kind # of overkill but it works. Disable inlining only when one of the # files in compat/*.c is being linked in. - if test x"${USE_COMPAT}" != x; then : + if test x"${USE_COMPAT}" != x; then CFLAGS="$CFLAGS -fno-inline" fi + ;; Lynx*) SHLIB_CFLAGS="-fPIC" @@ -5738,11 +7637,12 @@ fi DL_OBJS="tclLoadDl.o" DL_LIBS="-mshared -ldl" LD_FLAGS="-Wl,--export-dynamic" - if test $doRpath = yes; then : + if test $doRpath = yes; then CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' fi + ;; MP-RAS-02*) SHLIB_CFLAGS="-K PIC" @@ -5781,10 +7681,11 @@ fi SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" - if test $doRpath = yes; then : + if test $doRpath = yes; then CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' fi + LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.${SHLIB_VERSION}' LDFLAGS="-Wl,-export-dynamic" @@ -5801,7 +7702,7 @@ fi CFLAGS_OPTIMIZE="-O2" ;; esac - if test "${TCL_THREADS}" = "1"; then : + if test "${TCL_THREADS}" = "1"; then # On OpenBSD: Compile with -pthread # Don't link with -lpthread @@ -5809,6 +7710,7 @@ fi CFLAGS="$CFLAGS -pthread" fi + # OpenBSD doesn't do version numbers with dots. UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a' TCL_LIB_VERSIONS_OK=nodots @@ -5821,12 +7723,13 @@ fi DL_OBJS="tclLoadDl.o" DL_LIBS="" LDFLAGS="$LDFLAGS -export-dynamic" - if test $doRpath = yes; then : + if test $doRpath = yes; then CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' fi + LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} - if test "${TCL_THREADS}" = "1"; then : + if test "${TCL_THREADS}" = "1"; then # The -pthread needs to go in the CFLAGS, not LIBS LIBS=`echo $LIBS | sed s/-pthread//` @@ -5834,6 +7737,7 @@ fi LDFLAGS="$LDFLAGS -pthread" fi + ;; FreeBSD-*) # This configuration from FreeBSD Ports. @@ -5844,18 +7748,20 @@ fi DL_OBJS="tclLoadDl.o" DL_LIBS="" LDFLAGS="" - if test $doRpath = yes; then : + if test $doRpath = yes; then CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' fi - if test "${TCL_THREADS}" = "1"; then : + + if test "${TCL_THREADS}" = "1"; then # The -pthread needs to go in the LDFLAGS, not LIBS LIBS=`echo $LIBS | sed s/-pthread//` CFLAGS="$CFLAGS $PTHREAD_CFLAGS" LDFLAGS="$LDFLAGS $PTHREAD_LIBS" fi + case $system in FreeBSD-3.*) # Version numbers are dot-stripped by system policy. @@ -5878,19 +7784,23 @@ fi CFLAGS="`echo " ${CFLAGS}" | \ awk 'BEGIN {FS=" +-";ORS=" "}; {for (i=2;i<=NF;i++) \ if (!($i~/^(isysroot|mmacosx-version-min)/)) print "-"$i}'`" - if test $do64bit = yes; then : + if test $do64bit = yes; then case `arch` in ppc) - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if compiler accepts -arch ppc64 flag" >&5 -$as_echo_n "checking if compiler accepts -arch ppc64 flag... " >&6; } -if ${tcl_cv_cc_arch_ppc64+:} false; then : - $as_echo_n "(cached) " >&6 + echo "$as_me:$LINENO: checking if compiler accepts -arch ppc64 flag" >&5 +echo $ECHO_N "checking if compiler accepts -arch ppc64 flag... $ECHO_C" >&6 +if test "${tcl_cv_cc_arch_ppc64+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 else hold_cflags=$CFLAGS CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int @@ -5901,33 +7811,62 @@ main () return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then tcl_cv_cc_arch_ppc64=yes else - tcl_cv_cc_arch_ppc64=no + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +tcl_cv_cc_arch_ppc64=no fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext CFLAGS=$hold_cflags fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_cc_arch_ppc64" >&5 -$as_echo "$tcl_cv_cc_arch_ppc64" >&6; } - if test $tcl_cv_cc_arch_ppc64 = yes; then : +echo "$as_me:$LINENO: result: $tcl_cv_cc_arch_ppc64" >&5 +echo "${ECHO_T}$tcl_cv_cc_arch_ppc64" >&6 + if test $tcl_cv_cc_arch_ppc64 = yes; then CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5" do64bit_ok=yes -fi;; +fi +;; i386) - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if compiler accepts -arch x86_64 flag" >&5 -$as_echo_n "checking if compiler accepts -arch x86_64 flag... " >&6; } -if ${tcl_cv_cc_arch_x86_64+:} false; then : - $as_echo_n "(cached) " >&6 + echo "$as_me:$LINENO: checking if compiler accepts -arch x86_64 flag" >&5 +echo $ECHO_N "checking if compiler accepts -arch x86_64 flag... $ECHO_C" >&6 +if test "${tcl_cv_cc_arch_x86_64+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 else hold_cflags=$CFLAGS CFLAGS="$CFLAGS -arch x86_64" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int @@ -5938,48 +7877,79 @@ main () return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then tcl_cv_cc_arch_x86_64=yes else - tcl_cv_cc_arch_x86_64=no + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +tcl_cv_cc_arch_x86_64=no fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext CFLAGS=$hold_cflags fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_cc_arch_x86_64" >&5 -$as_echo "$tcl_cv_cc_arch_x86_64" >&6; } - if test $tcl_cv_cc_arch_x86_64 = yes; then : +echo "$as_me:$LINENO: result: $tcl_cv_cc_arch_x86_64" >&5 +echo "${ECHO_T}$tcl_cv_cc_arch_x86_64" >&6 + if test $tcl_cv_cc_arch_x86_64 = yes; then CFLAGS="$CFLAGS -arch x86_64" do64bit_ok=yes -fi;; +fi +;; *) - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Don't know how enable 64-bit on architecture \`arch\`" >&5 -$as_echo "$as_me: WARNING: Don't know how enable 64-bit on architecture \`arch\`" >&2;};; + { echo "$as_me:$LINENO: WARNING: Don't know how enable 64-bit on architecture \`arch\`" >&5 +echo "$as_me: WARNING: Don't know how enable 64-bit on architecture \`arch\`" >&2;};; esac else # Check for combined 32-bit and 64-bit fat build if echo "$CFLAGS " |grep -E -q -- '-arch (ppc64|x86_64) ' \ - && echo "$CFLAGS " |grep -E -q -- '-arch (ppc|i386) '; then : + && echo "$CFLAGS " |grep -E -q -- '-arch (ppc|i386) '; then fat_32_64=yes fi + fi + SHLIB_LD='${CC} -dynamiclib ${CFLAGS} ${LDFLAGS}' - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if ld accepts -single_module flag" >&5 -$as_echo_n "checking if ld accepts -single_module flag... " >&6; } -if ${tcl_cv_ld_single_module+:} false; then : - $as_echo_n "(cached) " >&6 + echo "$as_me:$LINENO: checking if ld accepts -single_module flag" >&5 +echo $ECHO_N "checking if ld accepts -single_module flag... $ECHO_C" >&6 +if test "${tcl_cv_ld_single_module+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 else hold_ldflags=$LDFLAGS LDFLAGS="$LDFLAGS -dynamiclib -Wl,-single_module" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int @@ -5990,41 +7960,71 @@ int i; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then tcl_cv_ld_single_module=yes else - tcl_cv_ld_single_module=no + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +tcl_cv_ld_single_module=no fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext LDFLAGS=$hold_ldflags fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_ld_single_module" >&5 -$as_echo "$tcl_cv_ld_single_module" >&6; } - if test $tcl_cv_ld_single_module = yes; then : +echo "$as_me:$LINENO: result: $tcl_cv_ld_single_module" >&5 +echo "${ECHO_T}$tcl_cv_ld_single_module" >&6 + if test $tcl_cv_ld_single_module = yes; then SHLIB_LD="${SHLIB_LD} -Wl,-single_module" fi + SHLIB_SUFFIX=".dylib" DL_OBJS="tclLoadDyld.o" DL_LIBS="" # Don't use -prebind when building for Mac OS X 10.4 or later only: if test "`echo "${MACOSX_DEPLOYMENT_TARGET}" | awk -F '10\\.' '{print int($2)}'`" -lt 4 -a \ - "`echo "${CPPFLAGS}" | awk -F '-mmacosx-version-min=10\\.' '{print int($2)}'`" -lt 4; then : + "`echo "${CPPFLAGS}" | awk -F '-mmacosx-version-min=10\\.' '{print int($2)}'`" -lt 4; then LDFLAGS="$LDFLAGS -prebind" fi + LDFLAGS="$LDFLAGS -headerpad_max_install_names" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if ld accepts -search_paths_first flag" >&5 -$as_echo_n "checking if ld accepts -search_paths_first flag... " >&6; } -if ${tcl_cv_ld_search_paths_first+:} false; then : - $as_echo_n "(cached) " >&6 + echo "$as_me:$LINENO: checking if ld accepts -search_paths_first flag" >&5 +echo $ECHO_N "checking if ld accepts -search_paths_first flag... $ECHO_C" >&6 +if test "${tcl_cv_ld_search_paths_first+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 else hold_ldflags=$LDFLAGS LDFLAGS="$LDFLAGS -Wl,-search_paths_first" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int @@ -6035,58 +8035,88 @@ int i; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then tcl_cv_ld_search_paths_first=yes else - tcl_cv_ld_search_paths_first=no + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +tcl_cv_ld_search_paths_first=no fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext LDFLAGS=$hold_ldflags fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_ld_search_paths_first" >&5 -$as_echo "$tcl_cv_ld_search_paths_first" >&6; } - if test $tcl_cv_ld_search_paths_first = yes; then : +echo "$as_me:$LINENO: result: $tcl_cv_ld_search_paths_first" >&5 +echo "${ECHO_T}$tcl_cv_ld_search_paths_first" >&6 + if test $tcl_cv_ld_search_paths_first = yes; then LDFLAGS="$LDFLAGS -Wl,-search_paths_first" fi - if test "$tcl_cv_cc_visibility_hidden" != yes; then : + if test "$tcl_cv_cc_visibility_hidden" != yes; then -$as_echo "#define MODULE_SCOPE __private_extern__" >>confdefs.h + +cat >>confdefs.h <<\_ACEOF +#define MODULE_SCOPE __private_extern__ +_ACEOF fi + CC_SEARCH_FLAGS="" LD_SEARCH_FLAGS="" LD_LIBRARY_PATH_VAR="DYLD_LIBRARY_PATH" -$as_echo "#define MAC_OSX_TCL 1" >>confdefs.h +cat >>confdefs.h <<\_ACEOF +#define MAC_OSX_TCL 1 +_ACEOF PLAT_OBJS='${MAC_OSX_OBJS}' PLAT_SRCS='${MAC_OSX_SRCS}' - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use CoreFoundation" >&5 -$as_echo_n "checking whether to use CoreFoundation... " >&6; } - # Check whether --enable-corefoundation was given. -if test "${enable_corefoundation+set}" = set; then : - enableval=$enable_corefoundation; tcl_corefoundation=$enableval + echo "$as_me:$LINENO: checking whether to use CoreFoundation" >&5 +echo $ECHO_N "checking whether to use CoreFoundation... $ECHO_C" >&6 + # Check whether --enable-corefoundation or --disable-corefoundation was given. +if test "${enable_corefoundation+set}" = set; then + enableval="$enable_corefoundation" + tcl_corefoundation=$enableval else tcl_corefoundation=yes -fi - - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_corefoundation" >&5 -$as_echo "$tcl_corefoundation" >&6; } - if test $tcl_corefoundation = yes; then : +fi; + echo "$as_me:$LINENO: result: $tcl_corefoundation" >&5 +echo "${ECHO_T}$tcl_corefoundation" >&6 + if test $tcl_corefoundation = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for CoreFoundation.framework" >&5 -$as_echo_n "checking for CoreFoundation.framework... " >&6; } -if ${tcl_cv_lib_corefoundation+:} false; then : - $as_echo_n "(cached) " >&6 + echo "$as_me:$LINENO: checking for CoreFoundation.framework" >&5 +echo $ECHO_N "checking for CoreFoundation.framework... $ECHO_C" >&6 +if test "${tcl_cv_lib_corefoundation+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 else hold_libs=$LIBS - if test "$fat_32_64" = yes; then : + if test "$fat_32_64" = yes; then for v in CFLAGS CPPFLAGS LDFLAGS; do # On Tiger there is no 64-bit CF, so remove 64-bit @@ -6096,8 +8126,13 @@ else eval 'hold_'$v'="$'$v'";'$v'="`echo "$'$v' "|sed -e "s/-arch ppc64 / /g" -e "s/-arch x86_64 / /g"`"' done fi + LIBS="$LIBS -framework CoreFoundation" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int @@ -6108,45 +8143,77 @@ CFBundleRef b = CFBundleGetMainBundle(); return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then tcl_cv_lib_corefoundation=yes else - tcl_cv_lib_corefoundation=no + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +tcl_cv_lib_corefoundation=no fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - if test "$fat_32_64" = yes; then : +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if test "$fat_32_64" = yes; then for v in CFLAGS CPPFLAGS LDFLAGS; do eval $v'="$hold_'$v'"' done fi + LIBS=$hold_libs fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_lib_corefoundation" >&5 -$as_echo "$tcl_cv_lib_corefoundation" >&6; } - if test $tcl_cv_lib_corefoundation = yes; then : +echo "$as_me:$LINENO: result: $tcl_cv_lib_corefoundation" >&5 +echo "${ECHO_T}$tcl_cv_lib_corefoundation" >&6 + if test $tcl_cv_lib_corefoundation = yes; then LIBS="$LIBS -framework CoreFoundation" -$as_echo "#define HAVE_COREFOUNDATION 1" >>confdefs.h +cat >>confdefs.h <<\_ACEOF +#define HAVE_COREFOUNDATION 1 +_ACEOF else tcl_corefoundation=no fi - if test "$fat_32_64" = yes -a $tcl_corefoundation = yes; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for 64-bit CoreFoundation" >&5 -$as_echo_n "checking for 64-bit CoreFoundation... " >&6; } -if ${tcl_cv_lib_corefoundation_64+:} false; then : - $as_echo_n "(cached) " >&6 + if test "$fat_32_64" = yes -a $tcl_corefoundation = yes; then + + echo "$as_me:$LINENO: checking for 64-bit CoreFoundation" >&5 +echo $ECHO_N "checking for 64-bit CoreFoundation... $ECHO_C" >&6 +if test "${tcl_cv_lib_corefoundation_64+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 else for v in CFLAGS CPPFLAGS LDFLAGS; do eval 'hold_'$v'="$'$v'";'$v'="`echo "$'$v' "|sed -e "s/-arch ppc / /g" -e "s/-arch i386 / /g"`"' done - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int @@ -6157,31 +8224,60 @@ CFBundleRef b = CFBundleGetMainBundle(); return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then tcl_cv_lib_corefoundation_64=yes else - tcl_cv_lib_corefoundation_64=no + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +tcl_cv_lib_corefoundation_64=no fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext for v in CFLAGS CPPFLAGS LDFLAGS; do eval $v'="$hold_'$v'"' done fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_lib_corefoundation_64" >&5 -$as_echo "$tcl_cv_lib_corefoundation_64" >&6; } - if test $tcl_cv_lib_corefoundation_64 = no; then : +echo "$as_me:$LINENO: result: $tcl_cv_lib_corefoundation_64" >&5 +echo "${ECHO_T}$tcl_cv_lib_corefoundation_64" >&6 + if test $tcl_cv_lib_corefoundation_64 = no; then -$as_echo "#define NO_COREFOUNDATION_64 1" >>confdefs.h +cat >>confdefs.h <<\_ACEOF +#define NO_COREFOUNDATION_64 1 +_ACEOF LDFLAGS="$LDFLAGS -Wl,-no_arch_warnings" fi + fi + fi + ;; NEXTSTEP-*) SHLIB_CFLAGS="" @@ -6197,7 +8293,9 @@ fi SHLIB_LD_LIBS="" CFLAGS_OPTIMIZE="" # Optimizer is buggy -$as_echo "#define _OE_SOCKETS 1" >>confdefs.h +cat >>confdefs.h <<\_ACEOF +#define _OE_SOCKETS 1 +_ACEOF ;; OSF1-1.0|OSF1-1.1|OSF1-1.2) @@ -6215,13 +8313,14 @@ $as_echo "#define _OE_SOCKETS 1" >>confdefs.h OSF1-1.*) # OSF/1 1.3 from OSF using ELF, and derivatives, including AD2 SHLIB_CFLAGS="-fPIC" - if test "$SHARED_BUILD" = 1; then : + if test "$SHARED_BUILD" = 1; then SHLIB_LD="ld -shared" else SHLIB_LD="ld -non_shared" fi + SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" @@ -6232,7 +8331,7 @@ fi OSF1-V*) # Digital OSF/1 SHLIB_CFLAGS="" - if test "$SHARED_BUILD" = 1; then : + if test "$SHARED_BUILD" = 1; then SHLIB_LD='ld -shared -expect_unresolved "*"' @@ -6241,27 +8340,30 @@ else SHLIB_LD='ld -non_shared -expect_unresolved "*"' fi + SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" - if test $doRpath = yes; then : + if test $doRpath = yes; then CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}' LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}' fi - if test "$GCC" = yes; then : + + if test "$GCC" = yes; then CFLAGS="$CFLAGS -mieee" else CFLAGS="$CFLAGS -DHAVE_TZSET -std1 -ieee" fi + # see pthread_intro(3) for pthread support on osf1, k.furukawa - if test "${TCL_THREADS}" = 1; then : + if test "${TCL_THREADS}" = 1; then CFLAGS="$CFLAGS -DHAVE_PTHREAD_ATTR_SETSTACKSIZE" CFLAGS="$CFLAGS -DTCL_THREAD_STACK_MIN=PTHREAD_STACK_MIN*64" LIBS=`echo $LIBS | sed s/-lpthreads//` - if test "$GCC" = yes; then : + if test "$GCC" = yes; then LIBS="$LIBS -lpthread -lmach -lexc" @@ -6272,7 +8374,9 @@ else fi + fi + ;; QNX-6*) # QNX RTP @@ -6291,7 +8395,7 @@ fi # Note, dlopen is available only on SCO 3.2.5 and greater. However, # this test works, since "uname -s" was non-standard in 3.2.4 and # below. - if test "$GCC" = yes; then : + if test "$GCC" = yes; then SHLIB_CFLAGS="-fPIC -melf" LDFLAGS="$LDFLAGS -melf -Wl,-Bexport" @@ -6302,6 +8406,7 @@ else LDFLAGS="$LDFLAGS -belf -Wl,-Bexport" fi + SHLIB_LD="ld -G" SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" @@ -6346,17 +8451,21 @@ fi # won't define thread-safe library routines. -$as_echo "#define _REENTRANT 1" >>confdefs.h +cat >>confdefs.h <<\_ACEOF +#define _REENTRANT 1 +_ACEOF -$as_echo "#define _POSIX_PTHREAD_SEMANTICS 1" >>confdefs.h +cat >>confdefs.h <<\_ACEOF +#define _POSIX_PTHREAD_SEMANTICS 1 +_ACEOF SHLIB_CFLAGS="-KPIC" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="-ldl" - if test "$GCC" = yes; then : + if test "$GCC" = yes; then SHLIB_LD='${CC} -shared' CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}' @@ -6369,32 +8478,37 @@ else LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} fi + ;; SunOS-5*) # Note: If _REENTRANT isn't defined, then Solaris # won't define thread-safe library routines. -$as_echo "#define _REENTRANT 1" >>confdefs.h +cat >>confdefs.h <<\_ACEOF +#define _REENTRANT 1 +_ACEOF -$as_echo "#define _POSIX_PTHREAD_SEMANTICS 1" >>confdefs.h +cat >>confdefs.h <<\_ACEOF +#define _POSIX_PTHREAD_SEMANTICS 1 +_ACEOF SHLIB_CFLAGS="-KPIC" # Check to enable 64-bit flags for compiler/linker - if test "$do64bit" = yes; then : + if test "$do64bit" = yes; then arch=`isainfo` - if test "$arch" = "sparcv9 sparc"; then : + if test "$arch" = "sparcv9 sparc"; then - if test "$GCC" = yes; then : + if test "$GCC" = yes; then - if test "`${CC} -dumpversion | awk -F. '{print $1}'`" -lt 3; then : + if test "`${CC} -dumpversion | awk -F. '{print $1}'`" -lt 3; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 64bit mode not supported with GCC < 3.2 on $system" >&5 -$as_echo "$as_me: WARNING: 64bit mode not supported with GCC < 3.2 on $system" >&2;} + { echo "$as_me:$LINENO: WARNING: 64bit mode not supported with GCC < 3.2 on $system" >&5 +echo "$as_me: WARNING: 64bit mode not supported with GCC < 3.2 on $system" >&2;} else @@ -6405,10 +8519,11 @@ else fi + else do64bit_ok=yes - if test "$do64bitVIS" = yes; then : + if test "$do64bitVIS" = yes; then CFLAGS="$CFLAGS -xarch=v9a" LDFLAGS_ARCH="-xarch=v9a" @@ -6419,15 +8534,17 @@ else LDFLAGS_ARCH="-xarch=v9" fi + # Solaris 64 uses this as well #LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH_64" fi + else - if test "$arch" = "amd64 i386"; then : + if test "$arch" = "amd64 i386"; then - if test "$GCC" = yes; then : + if test "$GCC" = yes; then case $system in SunOS-5.1[1-9]*|SunOS-5.[2-9][0-9]*) @@ -6435,8 +8552,8 @@ else CFLAGS="$CFLAGS -m64" LDFLAGS="$LDFLAGS -m64";; *) - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 64bit mode not supported with GCC on $system" >&5 -$as_echo "$as_me: WARNING: 64bit mode not supported with GCC on $system" >&2;};; + { echo "$as_me:$LINENO: WARNING: 64bit mode not supported with GCC on $system" >&5 +echo "$as_me: WARNING: 64bit mode not supported with GCC on $system" >&2;};; esac else @@ -6453,32 +8570,169 @@ else fi + else - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 64bit mode not supported for $arch" >&5 -$as_echo "$as_me: WARNING: 64bit mode not supported for $arch" >&2;} + { echo "$as_me:$LINENO: WARNING: 64bit mode not supported for $arch" >&5 +echo "$as_me: WARNING: 64bit mode not supported for $arch" >&2;} fi + fi + fi + #-------------------------------------------------------------------- # On Solaris 5.x i386 with the sunpro compiler we need to link # with sunmath to get floating point rounding control #-------------------------------------------------------------------- - if test "$GCC" = yes; then : + if test "$GCC" = yes; then use_sunmath=no else arch=`isainfo` - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use -lsunmath for fp rounding control" >&5 -$as_echo_n "checking whether to use -lsunmath for fp rounding control... " >&6; } - if test "$arch" = "amd64 i386" -o "$arch" = "i386"; then : + echo "$as_me:$LINENO: checking whether to use -lsunmath for fp rounding control" >&5 +echo $ECHO_N "checking whether to use -lsunmath for fp rounding control... $ECHO_C" >&6 + if test "$arch" = "amd64 i386" -o "$arch" = "i386"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 MATH_LIBS="-lsunmath $MATH_LIBS" - ac_fn_c_check_header_mongrel "$LINENO" "sunmath.h" "ac_cv_header_sunmath_h" "$ac_includes_default" -if test "x$ac_cv_header_sunmath_h" = xyes; then : + if test "${ac_cv_header_sunmath_h+set}" = set; then + echo "$as_me:$LINENO: checking for sunmath.h" >&5 +echo $ECHO_N "checking for sunmath.h... $ECHO_C" >&6 +if test "${ac_cv_header_sunmath_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: $ac_cv_header_sunmath_h" >&5 +echo "${ECHO_T}$ac_cv_header_sunmath_h" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking sunmath.h usability" >&5 +echo $ECHO_N "checking sunmath.h usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking sunmath.h presence" >&5 +echo $ECHO_N "checking sunmath.h presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: sunmath.h: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: sunmath.h: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: sunmath.h: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: sunmath.h: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: sunmath.h: present but cannot be compiled" >&5 +echo "$as_me: WARNING: sunmath.h: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: sunmath.h: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: sunmath.h: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: sunmath.h: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: sunmath.h: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: sunmath.h: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: sunmath.h: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: sunmath.h: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: sunmath.h: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: sunmath.h: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: sunmath.h: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +## ------------------------------ ## +## Report this to the tcl lists. ## +## ------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for sunmath.h" >&5 +echo $ECHO_N "checking for sunmath.h... $ECHO_C" >&6 +if test "${ac_cv_header_sunmath_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_header_sunmath_h=$ac_header_preproc +fi +echo "$as_me:$LINENO: result: $ac_cv_header_sunmath_h" >&5 +echo "${ECHO_T}$ac_cv_header_sunmath_h" >&6 fi @@ -6487,24 +8741,26 @@ fi else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 use_sunmath=no fi + fi + SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="-ldl" - if test "$GCC" = yes; then : + if test "$GCC" = yes; then SHLIB_LD='${CC} -shared' CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}' LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} - if test "$do64bit_ok" = yes; then : + if test "$do64bit_ok" = yes; then - if test "$arch" = "sparcv9 sparc"; then : + if test "$arch" = "sparcv9 sparc"; then # We need to specify -static-libgcc or we need to # add the path to the sparv9 libgcc. @@ -6515,22 +8771,26 @@ fi #CC_SEARCH_FLAGS="${CC_SEARCH_FLAGS},-R,$v9gcclibdir" else - if test "$arch" = "amd64 i386"; then : + if test "$arch" = "amd64 i386"; then SHLIB_LD="$SHLIB_LD -m64 -static-libgcc" fi + fi + fi + else - if test "$use_sunmath" = yes; then : + if test "$use_sunmath" = yes; then textmode=textoff else textmode=text fi + case $system in SunOS-5.[1-9][0-9]*|SunOS-5.[7-9]) SHLIB_LD="\${CC} -G -z $textmode \${LDFLAGS}";; @@ -6541,6 +8801,7 @@ fi LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}' fi + ;; UNIX_SV* | UnixWare-5*) SHLIB_CFLAGS="-KPIC" @@ -6551,15 +8812,19 @@ fi DL_LIBS="-ldl" # Some UNIX_SV* systems (unixware 1.1.2 for example) have linkers # that don't grok the -Bexport option. Test that it does. - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld accepts -Bexport flag" >&5 -$as_echo_n "checking for ld accepts -Bexport flag... " >&6; } -if ${tcl_cv_ld_Bexport+:} false; then : - $as_echo_n "(cached) " >&6 + echo "$as_me:$LINENO: checking for ld accepts -Bexport flag" >&5 +echo $ECHO_N "checking for ld accepts -Bexport flag... $ECHO_C" >&6 +if test "${tcl_cv_ld_Bexport+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 else hold_ldflags=$LDFLAGS LDFLAGS="$LDFLAGS -Wl,-Bexport" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int @@ -6570,63 +8835,93 @@ int i; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then tcl_cv_ld_Bexport=yes else - tcl_cv_ld_Bexport=no + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +tcl_cv_ld_Bexport=no fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext LDFLAGS=$hold_ldflags fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_ld_Bexport" >&5 -$as_echo "$tcl_cv_ld_Bexport" >&6; } - if test $tcl_cv_ld_Bexport = yes; then : +echo "$as_me:$LINENO: result: $tcl_cv_ld_Bexport" >&5 +echo "${ECHO_T}$tcl_cv_ld_Bexport" >&6 + if test $tcl_cv_ld_Bexport = yes; then LDFLAGS="$LDFLAGS -Wl,-Bexport" fi + CC_SEARCH_FLAGS="" LD_SEARCH_FLAGS="" ;; esac - if test "$do64bit" = yes -a "$do64bit_ok" = no; then : + if test "$do64bit" = yes -a "$do64bit_ok" = no; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 64bit support being disabled -- don't know magic for this platform" >&5 -$as_echo "$as_me: WARNING: 64bit support being disabled -- don't know magic for this platform" >&2;} + { echo "$as_me:$LINENO: WARNING: 64bit support being disabled -- don't know magic for this platform" >&5 +echo "$as_me: WARNING: 64bit support being disabled -- don't know magic for this platform" >&2;} fi - if test "$do64bit" = yes -a "$do64bit_ok" = yes; then : + if test "$do64bit" = yes -a "$do64bit_ok" = yes; then -$as_echo "#define TCL_CFG_DO64BIT 1" >>confdefs.h + +cat >>confdefs.h <<\_ACEOF +#define TCL_CFG_DO64BIT 1 +_ACEOF fi + # Step 4: disable dynamic loading if requested via a command-line switch. - # Check whether --enable-load was given. -if test "${enable_load+set}" = set; then : - enableval=$enable_load; tcl_ok=$enableval + # Check whether --enable-load or --disable-load was given. +if test "${enable_load+set}" = set; then + enableval="$enable_load" + tcl_ok=$enableval else tcl_ok=yes -fi - - if test "$tcl_ok" = no; then : +fi; + if test "$tcl_ok" = no; then DL_OBJS="" fi - if test "x$DL_OBJS" != x; then : + + if test "x$DL_OBJS" != x; then BUILD_DLTEST="\$(DLTEST_TARGETS)" else - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Can't figure out how to do dynamic loading or shared libraries on this system." >&5 -$as_echo "$as_me: WARNING: Can't figure out how to do dynamic loading or shared libraries on this system." >&2;} + { echo "$as_me:$LINENO: WARNING: Can't figure out how to do dynamic loading or shared libraries on this system." >&5 +echo "$as_me: WARNING: Can't figure out how to do dynamic loading or shared libraries on this system." >&2;} SHLIB_CFLAGS="" SHLIB_LD="" SHLIB_SUFFIX="" @@ -6638,13 +8933,14 @@ $as_echo "$as_me: WARNING: Can't figure out how to do dynamic loading or shared BUILD_DLTEST="" fi + LDFLAGS="$LDFLAGS $LDFLAGS_ARCH" # If we're running gcc, then change the C flags for compiling shared # libraries to the right flags for gcc, instead of those for the # standard manufacturer compiler. - if test "$DL_OBJS" != "tclLoadNone.o" -a "$GCC" = yes; then : + if test "$DL_OBJS" != "tclLoadNone.o" -a "$GCC" = yes; then case $system in AIX-*) ;; @@ -6658,29 +8954,35 @@ fi esac fi - if test "$tcl_cv_cc_visibility_hidden" != yes; then : + + if test "$tcl_cv_cc_visibility_hidden" != yes; then -$as_echo "#define MODULE_SCOPE extern" >>confdefs.h +cat >>confdefs.h <<\_ACEOF +#define MODULE_SCOPE extern +_ACEOF fi - if test "$SHARED_LIB_SUFFIX" = ""; then : + + if test "$SHARED_LIB_SUFFIX" = ""; then SHARED_LIB_SUFFIX='${VERSION}${SHLIB_SUFFIX}' fi - if test "$UNSHARED_LIB_SUFFIX" = ""; then : + + if test "$UNSHARED_LIB_SUFFIX" = ""; then UNSHARED_LIB_SUFFIX='${VERSION}.a' fi + DLL_INSTALL_DIR="\$(LIB_INSTALL_DIR)" - if test "${SHARED_BUILD}" = 1 -a "${SHLIB_SUFFIX}" != ""; then : + if test "${SHARED_BUILD}" = 1 -a "${SHLIB_SUFFIX}" != ""; then LIB_SUFFIX=${SHARED_LIB_SUFFIX} MAKE_LIB='${SHLIB_LD} -o $@ ${OBJS} ${SHLIB_LD_LIBS} ${TCL_SHLIB_LD_EXTRAS} ${TK_SHLIB_LD_EXTRAS} ${LD_SEARCH_FLAGS}' - if test "${SHLIB_SUFFIX}" = ".dll"; then : + if test "${SHLIB_SUFFIX}" = ".dll"; then INSTALL_LIB='$(INSTALL_LIBRARY) $(LIB_FILE) "$(BIN_INSTALL_DIR)/$(LIB_FILE)"' DLL_INSTALL_DIR="\$(BIN_INSTALL_DIR)" @@ -6691,11 +8993,12 @@ else fi + else LIB_SUFFIX=${UNSHARED_LIB_SUFFIX} - if test "$RANLIB" = ""; then : + if test "$RANLIB" = ""; then MAKE_LIB='$(STLIB_LD) $@ ${OBJS}' INSTALL_LIB='$(INSTALL_LIBRARY) $(LIB_FILE) "$(LIB_INSTALL_DIR)/$(LIB_FILE)"' @@ -6707,22 +9010,12 @@ else fi -fi - - if test "$RANLIB" = ""; then : - - MAKE_KIT_LIB='$(STLIB_LD) $@ ${TCL_OBJS} ${TOMMATH_OBJS} ${ZLIB_OBJS}' - INSTALL_KIT_LIB='$(INSTALL_LIBRARY) $(TCL_KIT_LIB_FILE) "$(LIB_INSTALL_DIR)/$(TCL_KIT_LIB_FILE)"' - -else - - MAKE_KIT_LIB='${STLIB_LD} $@ ${TCL_OBJS} ${TOMMATH_OBJS} ${ZLIB_OBJS} ; ${RANLIB} $@' - INSTALL_KIT_LIB='$(INSTALL_LIBRARY) $(TCL_KIT_LIB_FILE) "$(LIB_INSTALL_DIR)/$(TCL_KIT_LIB_FILE)" ; (cd "$(LIB_INSTALL_DIR)" ; $(RANLIB) $(TCL_KIT_LIB_FILE))' fi + # Stub lib does not depend on shared/static configuration - if test "$RANLIB" = ""; then : + if test "$RANLIB" = ""; then MAKE_STUB_LIB='${STLIB_LD} $@ ${STUB_LIB_OBJS}' INSTALL_STUB_LIB='$(INSTALL_LIBRARY) $(STUB_LIB_FILE) "$(LIB_INSTALL_DIR)/$(STUB_LIB_FILE)"' @@ -6734,25 +9027,31 @@ else fi + # Define TCL_LIBS now that we know what DL_LIBS is. # The trick here is that we don't want to change the value of TCL_LIBS if # it is already set when tclConfig.sh had been loaded by Tk. - if test "x${TCL_LIBS}" = x; then : + if test "x${TCL_LIBS}" = x; then TCL_LIBS="${DL_LIBS} ${LIBS} ${MATH_LIBS}" fi + # See if the compiler supports casting to a union type. # This is used to stop gcc from printing a compiler # warning when initializing a union member. - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for cast to union support" >&5 -$as_echo_n "checking for cast to union support... " >&6; } -if ${tcl_cv_cast_to_union+:} false; then : - $as_echo_n "(cached) " >&6 + echo "$as_me:$LINENO: checking for cast to union support" >&5 +echo $ECHO_N "checking for cast to union support... $ECHO_C" >&6 +if test "${tcl_cv_cast_to_union+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int @@ -6766,19 +9065,45 @@ main () return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then tcl_cv_cast_to_union=yes else - tcl_cv_cast_to_union=no + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +tcl_cv_cast_to_union=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_cast_to_union" >&5 -$as_echo "$tcl_cv_cast_to_union" >&6; } +echo "$as_me:$LINENO: result: $tcl_cv_cast_to_union" >&5 +echo "${ECHO_T}$tcl_cv_cast_to_union" >&6 if test "$tcl_cv_cast_to_union" = "yes"; then -$as_echo "#define HAVE_CAST_TO_UNION 1" >>confdefs.h +cat >>confdefs.h <<\_ACEOF +#define HAVE_CAST_TO_UNION 1 +_ACEOF fi @@ -6824,36 +9149,38 @@ _ACEOF - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for build with symbols" >&5 -$as_echo_n "checking for build with symbols... " >&6; } - # Check whether --enable-symbols was given. -if test "${enable_symbols+set}" = set; then : - enableval=$enable_symbols; tcl_ok=$enableval + echo "$as_me:$LINENO: checking for build with symbols" >&5 +echo $ECHO_N "checking for build with symbols... $ECHO_C" >&6 + # Check whether --enable-symbols or --disable-symbols was given. +if test "${enable_symbols+set}" = set; then + enableval="$enable_symbols" + tcl_ok=$enableval else tcl_ok=no -fi - +fi; # FIXME: Currently, LDFLAGS_DEFAULT is not used, it should work like CFLAGS_DEFAULT. DBGX="" if test "$tcl_ok" = "no"; then CFLAGS_DEFAULT='$(CFLAGS_OPTIMIZE)' LDFLAGS_DEFAULT='$(LDFLAGS_OPTIMIZE)' -$as_echo "#define NDEBUG 1" >>confdefs.h +cat >>confdefs.h <<\_ACEOF +#define NDEBUG 1 +_ACEOF - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 -$as_echo "#define TCL_CFG_OPTIMIZED 1" >>confdefs.h +cat >>confdefs.h <<\_ACEOF +#define TCL_CFG_OPTIMIZED 1 +_ACEOF else CFLAGS_DEFAULT='$(CFLAGS_DEBUG)' LDFLAGS_DEFAULT='$(LDFLAGS_DEBUG)' if test "$tcl_ok" = "yes"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes (standard debugging)" >&5 -$as_echo "yes (standard debugging)" >&6; } + echo "$as_me:$LINENO: result: yes (standard debugging)" >&5 +echo "${ECHO_T}yes (standard debugging)" >&6 fi fi @@ -6861,35 +9188,45 @@ $as_echo "yes (standard debugging)" >&6; } if test "$tcl_ok" = "mem" -o "$tcl_ok" = "all"; then -$as_echo "#define TCL_MEM_DEBUG 1" >>confdefs.h +cat >>confdefs.h <<\_ACEOF +#define TCL_MEM_DEBUG 1 +_ACEOF fi if test "$tcl_ok" = "compile" -o "$tcl_ok" = "all"; then -$as_echo "#define TCL_COMPILE_DEBUG 1" >>confdefs.h +cat >>confdefs.h <<\_ACEOF +#define TCL_COMPILE_DEBUG 1 +_ACEOF -$as_echo "#define TCL_COMPILE_STATS 1" >>confdefs.h +cat >>confdefs.h <<\_ACEOF +#define TCL_COMPILE_STATS 1 +_ACEOF fi if test "$tcl_ok" != "yes" -a "$tcl_ok" != "no"; then if test "$tcl_ok" = "all"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: enabled symbols mem compile debugging" >&5 -$as_echo "enabled symbols mem compile debugging" >&6; } + echo "$as_me:$LINENO: result: enabled symbols mem compile debugging" >&5 +echo "${ECHO_T}enabled symbols mem compile debugging" >&6 else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: enabled $tcl_ok debugging" >&5 -$as_echo "enabled $tcl_ok debugging" >&6; } + echo "$as_me:$LINENO: result: enabled $tcl_ok debugging" >&5 +echo "${ECHO_T}enabled $tcl_ok debugging" >&6 fi fi -$as_echo "#define TCL_TOMMATH 1" >>confdefs.h +cat >>confdefs.h <<\_ACEOF +#define TCL_TOMMATH 1 +_ACEOF -$as_echo "#define MP_PREC 4" >>confdefs.h +cat >>confdefs.h <<\_ACEOF +#define MP_PREC 4 +_ACEOF #-------------------------------------------------------------------- @@ -6897,14 +9234,18 @@ $as_echo "#define MP_PREC 4" >>confdefs.h #-------------------------------------------------------------------- - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for required early compiler flags" >&5 -$as_echo_n "checking for required early compiler flags... " >&6; } + echo "$as_me:$LINENO: checking for required early compiler flags" >&5 +echo $ECHO_N "checking for required early compiler flags... $ECHO_C" >&6 tcl_flags="" - if ${tcl_cv_flag__isoc99_source+:} false; then : - $as_echo_n "(cached) " >&6 + if test "${tcl_cv_flag__isoc99_source+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int @@ -6915,10 +9256,38 @@ char *p = (char *)strtoll; char *q = (char *)strtoull; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then tcl_cv_flag__isoc99_source=no else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #define _ISOC99_SOURCE 1 #include @@ -6930,28 +9299,58 @@ char *p = (char *)strtoll; char *q = (char *)strtoull; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then tcl_cv_flag__isoc99_source=yes else - tcl_cv_flag__isoc99_source=no + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +tcl_cv_flag__isoc99_source=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi if test "x${tcl_cv_flag__isoc99_source}" = "xyes" ; then -$as_echo "#define _ISOC99_SOURCE 1" >>confdefs.h +cat >>confdefs.h <<\_ACEOF +#define _ISOC99_SOURCE 1 +_ACEOF tcl_flags="$tcl_flags _ISOC99_SOURCE" fi - if ${tcl_cv_flag__largefile64_source+:} false; then : - $as_echo_n "(cached) " >&6 + if test "${tcl_cv_flag__largefile64_source+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int @@ -6962,10 +9361,38 @@ struct stat64 buf; int i = stat64("/", &buf); return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then tcl_cv_flag__largefile64_source=no else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #define _LARGEFILE64_SOURCE 1 #include @@ -6977,28 +9404,58 @@ struct stat64 buf; int i = stat64("/", &buf); return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then tcl_cv_flag__largefile64_source=yes else - tcl_cv_flag__largefile64_source=no + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +tcl_cv_flag__largefile64_source=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi if test "x${tcl_cv_flag__largefile64_source}" = "xyes" ; then -$as_echo "#define _LARGEFILE64_SOURCE 1" >>confdefs.h +cat >>confdefs.h <<\_ACEOF +#define _LARGEFILE64_SOURCE 1 +_ACEOF tcl_flags="$tcl_flags _LARGEFILE64_SOURCE" fi - if ${tcl_cv_flag__largefile_source64+:} false; then : - $as_echo_n "(cached) " >&6 + if test "${tcl_cv_flag__largefile_source64+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int @@ -7009,10 +9466,38 @@ char *p = (char *)open64; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then tcl_cv_flag__largefile_source64=no else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #define _LARGEFILE_SOURCE64 1 #include @@ -7024,42 +9509,72 @@ char *p = (char *)open64; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then tcl_cv_flag__largefile_source64=yes else - tcl_cv_flag__largefile_source64=no + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +tcl_cv_flag__largefile_source64=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi if test "x${tcl_cv_flag__largefile_source64}" = "xyes" ; then -$as_echo "#define _LARGEFILE_SOURCE64 1" >>confdefs.h +cat >>confdefs.h <<\_ACEOF +#define _LARGEFILE_SOURCE64 1 +_ACEOF tcl_flags="$tcl_flags _LARGEFILE_SOURCE64" fi if test "x${tcl_flags}" = "x" ; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5 -$as_echo "none" >&6; } + echo "$as_me:$LINENO: result: none" >&5 +echo "${ECHO_T}none" >&6 else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${tcl_flags}" >&5 -$as_echo "${tcl_flags}" >&6; } + echo "$as_me:$LINENO: result: ${tcl_flags}" >&5 +echo "${ECHO_T}${tcl_flags}" >&6 fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for 64-bit integer type" >&5 -$as_echo_n "checking for 64-bit integer type... " >&6; } - if ${tcl_cv_type_64bit+:} false; then : - $as_echo_n "(cached) " >&6 + echo "$as_me:$LINENO: checking for 64-bit integer type" >&5 +echo $ECHO_N "checking for 64-bit integer type... $ECHO_C" >&6 + if test "${tcl_cv_type_64bit+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 else tcl_cv_type_64bit=none # See if the compiler knows natively about __int64 - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int @@ -7070,16 +9585,44 @@ __int64 value = (__int64) 0; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then tcl_type_64bit=__int64 else - tcl_type_64bit="long long" + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +tcl_type_64bit="long long" fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext # See if we should use long anyway Note that we substitute in the # type that is our current guess for a 64-bit type inside this check # program, so it should be modified only carefully... - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int @@ -7092,35 +9635,66 @@ switch (0) { return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then tcl_cv_type_64bit=${tcl_type_64bit} +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi if test "${tcl_cv_type_64bit}" = none ; then -$as_echo "#define TCL_WIDE_INT_IS_LONG 1" >>confdefs.h +cat >>confdefs.h <<\_ACEOF +#define TCL_WIDE_INT_IS_LONG 1 +_ACEOF - { $as_echo "$as_me:${as_lineno-$LINENO}: result: using long" >&5 -$as_echo "using long" >&6; } + echo "$as_me:$LINENO: result: using long" >&5 +echo "${ECHO_T}using long" >&6 else cat >>confdefs.h <<_ACEOF #define TCL_WIDE_INT_TYPE ${tcl_cv_type_64bit} _ACEOF - { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${tcl_cv_type_64bit}" >&5 -$as_echo "${tcl_cv_type_64bit}" >&6; } + echo "$as_me:$LINENO: result: ${tcl_cv_type_64bit}" >&5 +echo "${ECHO_T}${tcl_cv_type_64bit}" >&6 # Now check for auxiliary declarations - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for struct dirent64" >&5 -$as_echo_n "checking for struct dirent64... " >&6; } -if ${tcl_cv_struct_dirent64+:} false; then : - $as_echo_n "(cached) " >&6 + echo "$as_me:$LINENO: checking for struct dirent64" >&5 +echo $ECHO_N "checking for struct dirent64... $ECHO_C" >&6 +if test "${tcl_cv_struct_dirent64+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include @@ -7132,28 +9706,58 @@ struct dirent64 p; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then tcl_cv_struct_dirent64=yes else - tcl_cv_struct_dirent64=no + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +tcl_cv_struct_dirent64=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_struct_dirent64" >&5 -$as_echo "$tcl_cv_struct_dirent64" >&6; } +echo "$as_me:$LINENO: result: $tcl_cv_struct_dirent64" >&5 +echo "${ECHO_T}$tcl_cv_struct_dirent64" >&6 if test "x${tcl_cv_struct_dirent64}" = "xyes" ; then -$as_echo "#define HAVE_STRUCT_DIRENT64 1" >>confdefs.h +cat >>confdefs.h <<\_ACEOF +#define HAVE_STRUCT_DIRENT64 1 +_ACEOF fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for struct stat64" >&5 -$as_echo_n "checking for struct stat64... " >&6; } -if ${tcl_cv_struct_stat64+:} false; then : - $as_echo_n "(cached) " >&6 + echo "$as_me:$LINENO: checking for struct stat64" >&5 +echo $ECHO_N "checking for struct stat64... $ECHO_C" >&6 +if test "${tcl_cv_struct_stat64+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int @@ -7165,40 +9769,161 @@ struct stat64 p; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then tcl_cv_struct_stat64=yes else - tcl_cv_struct_stat64=no + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +tcl_cv_struct_stat64=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_struct_stat64" >&5 -$as_echo "$tcl_cv_struct_stat64" >&6; } +echo "$as_me:$LINENO: result: $tcl_cv_struct_stat64" >&5 +echo "${ECHO_T}$tcl_cv_struct_stat64" >&6 if test "x${tcl_cv_struct_stat64}" = "xyes" ; then -$as_echo "#define HAVE_STRUCT_STAT64 1" >>confdefs.h +cat >>confdefs.h <<\_ACEOF +#define HAVE_STRUCT_STAT64 1 +_ACEOF fi - for ac_func in open64 lseek64 -do : - as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` -ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" -if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + + +for ac_func in open64 lseek64 +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 +if eval "test \"\${$as_ac_var+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case declares $ac_func. + For example, HP-UX 11i declares gettimeofday. */ +#define $ac_func innocuous_$ac_func + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $ac_func + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +char (*f) () = $ac_func; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != $ac_func; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +eval "$as_ac_var=no" +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 +if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for off64_t" >&5 -$as_echo_n "checking for off64_t... " >&6; } - if ${tcl_cv_type_off64_t+:} false; then : - $as_echo_n "(cached) " >&6 + echo "$as_me:$LINENO: checking for off64_t" >&5 +echo $ECHO_N "checking for off64_t... $ECHO_C" >&6 + if test "${tcl_cv_type_off64_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int @@ -7210,25 +9935,51 @@ off64_t offset; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then tcl_cv_type_off64_t=yes else - tcl_cv_type_off64_t=no + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +tcl_cv_type_off64_t=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi if test "x${tcl_cv_type_off64_t}" = "xyes" && \ test "x${ac_cv_func_lseek64}" = "xyes" && \ test "x${ac_cv_func_open64}" = "xyes" ; then -$as_echo "#define HAVE_TYPE_OFF64_T 1" >>confdefs.h +cat >>confdefs.h <<\_ACEOF +#define HAVE_TYPE_OFF64_T 1 +_ACEOF - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 fi fi @@ -7238,229 +9989,235 @@ $as_echo "no" >&6; } # Tcl_UniChar strings to memcmp on big-endian systems. #-------------------------------------------------------------------- - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5 -$as_echo_n "checking whether byte ordering is bigendian... " >&6; } -if ${ac_cv_c_bigendian+:} false; then : - $as_echo_n "(cached) " >&6 +echo "$as_me:$LINENO: checking whether byte ordering is bigendian" >&5 +echo $ECHO_N "checking whether byte ordering is bigendian... $ECHO_C" >&6 +if test "${ac_cv_c_bigendian+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 else - ac_cv_c_bigendian=unknown - # See if we're dealing with a universal compiler. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#ifndef __APPLE_CC__ - not a universal capable compiler - #endif - typedef int dummy; - -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - - # Check for potential -arch flags. It is not universal unless - # there are at least two -arch flags with different values. - ac_arch= - ac_prev= - for ac_word in $CC $CFLAGS $CPPFLAGS $LDFLAGS; do - if test -n "$ac_prev"; then - case $ac_word in - i?86 | x86_64 | ppc | ppc64) - if test -z "$ac_arch" || test "$ac_arch" = "$ac_word"; then - ac_arch=$ac_word - else - ac_cv_c_bigendian=universal - break - fi - ;; - esac - ac_prev= - elif test "x$ac_word" = "x-arch"; then - ac_prev=arch - fi - done -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - if test $ac_cv_c_bigendian = unknown; then - # See if sys/param.h defines the BYTE_ORDER macro. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + # See if sys/param.h defines the BYTE_ORDER macro. +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include - #include +#include int main () { -#if ! (defined BYTE_ORDER && defined BIG_ENDIAN \ - && defined LITTLE_ENDIAN && BYTE_ORDER && BIG_ENDIAN \ - && LITTLE_ENDIAN) - bogus endian macros - #endif +#if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN + bogus endian macros +#endif ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then # It does; now see whether it defined to BIG_ENDIAN or not. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include - #include +#include int main () { #if BYTE_ORDER != BIG_ENDIAN - not big endian - #endif + not big endian +#endif ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_c_bigendian=yes +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_c_bigendian=yes else - ac_cv_c_bigendian=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - fi - if test $ac_cv_c_bigendian = unknown; then - # See if defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris). - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 -int -main () -{ -#if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN) - bogus endian macros - #endif +ac_cv_c_bigendian=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 - ; - return 0; -} +# It does not; compile a test program. +if test "$cross_compiling" = yes; then + # try to guess the endianness by grepping values into an object file + ac_cv_c_bigendian=unknown + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - # It does; now see whether it defined to _BIG_ENDIAN or not. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ -#include - +short ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 }; +short ascii_ii[] = { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 }; +void _ascii () { char *s = (char *) ascii_mm; s = (char *) ascii_ii; } +short ebcdic_ii[] = { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 }; +short ebcdic_mm[] = { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 }; +void _ebcdic () { char *s = (char *) ebcdic_mm; s = (char *) ebcdic_ii; } int main () { -#ifndef _BIG_ENDIAN - not big endian - #endif - + _ascii (); _ebcdic (); ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + if grep BIGenDianSyS conftest.$ac_objext >/dev/null ; then ac_cv_c_bigendian=yes -else - ac_cv_c_bigendian=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then + if test "$ac_cv_c_bigendian" = unknown; then + ac_cv_c_bigendian=no + else + # finding both strings is unlikely to happen, but who knows? + ac_cv_c_bigendian=unknown + fi fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - fi - if test $ac_cv_c_bigendian = unknown; then - # Compile a test program. - if test "$cross_compiling" = yes; then : - # Try to guess by grepping values from an object file. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -short int ascii_mm[] = - { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 }; - short int ascii_ii[] = - { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 }; - int use_ascii (int i) { - return ascii_mm[i] + ascii_ii[i]; - } - short int ebcdic_ii[] = - { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 }; - short int ebcdic_mm[] = - { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 }; - int use_ebcdic (int i) { - return ebcdic_mm[i] + ebcdic_ii[i]; - } - extern int foo; +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 -int -main () -{ -return use_ascii (foo) == use_ebcdic (foo); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - if grep BIGenDianSyS conftest.$ac_objext >/dev/null; then - ac_cv_c_bigendian=yes - fi - if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then - if test "$ac_cv_c_bigendian" = unknown; then - ac_cv_c_bigendian=no - else - # finding both strings is unlikely to happen, but who knows? - ac_cv_c_bigendian=unknown - fi - fi fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ -$ac_includes_default int main () { - - /* Are we little or big endian? From Harbison&Steele. */ - union - { - long int l; - char c[sizeof (long int)]; - } u; - u.l = 1; - return u.c[sizeof (long int) - 1] == 1; - - ; - return 0; + /* Are we little or big endian? From Harbison&Steele. */ + union + { + long l; + char c[sizeof (long)]; + } u; + u.l = 1; + exit (u.c[sizeof (long) - 1] == 1); } _ACEOF -if ac_fn_c_try_run "$LINENO"; then : +rm -f conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then ac_cv_c_bigendian=no else - ac_cv_c_bigendian=yes + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_c_bigendian=yes fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext +rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi - - fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_bigendian" >&5 -$as_echo "$ac_cv_c_bigendian" >&6; } - case $ac_cv_c_bigendian in #( - yes) - $as_echo "#define WORDS_BIGENDIAN 1" >>confdefs.h -;; #( - no) - ;; #( - universal) - -$as_echo "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_c_bigendian" >&5 +echo "${ECHO_T}$ac_cv_c_bigendian" >&6 +case $ac_cv_c_bigendian in + yes) - ;; #( - *) - as_fn_error $? "unknown endianness - presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;; - esac +cat >>confdefs.h <<\_ACEOF +#define WORDS_BIGENDIAN 1 +_ACEOF + ;; + no) + ;; + *) + { { echo "$as_me:$LINENO: error: unknown endianness +presetting ac_cv_c_bigendian=no (or yes) will help" >&5 +echo "$as_me: error: unknown endianness +presetting ac_cv_c_bigendian=no (or yes) will help" >&2;} + { (exit 1); exit 1; }; } ;; +esac #-------------------------------------------------------------------- @@ -7469,2361 +10226,7837 @@ $as_echo "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h #-------------------------------------------------------------------- # Check if Posix compliant getcwd exists, if not we'll use getwd. + for ac_func in getcwd -do : - ac_fn_c_check_func "$LINENO" "getcwd" "ac_cv_func_getcwd" -if test "x$ac_cv_func_getcwd" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_GETCWD 1 +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 +if eval "test \"\${$as_ac_var+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ _ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case declares $ac_func. + For example, HP-UX 11i declares gettimeofday. */ +#define $ac_func innocuous_$ac_func -else - -$as_echo "#define USEGETWD 1" >>confdefs.h +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ -fi -done +#ifdef __STDC__ +# include +#else +# include +#endif -# Nb: if getcwd uses popen and pwd(1) (like SunOS 4) we should really -# define USEGETWD even if the posix getcwd exists. Add a test ? +#undef $ac_func -ac_fn_c_check_func "$LINENO" "mkstemp" "ac_cv_func_mkstemp" -if test "x$ac_cv_func_mkstemp" = xyes; then : - $as_echo "#define HAVE_MKSTEMP 1" >>confdefs.h +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +char (*f) () = $ac_func; +#endif +#ifdef __cplusplus +} +#endif +int +main () +{ +return f != $ac_func; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_var=yes" else - case " $LIBOBJS " in - *" mkstemp.$ac_objext "* ) ;; - *) LIBOBJS="$LIBOBJS mkstemp.$ac_objext" - ;; -esac + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 +eval "$as_ac_var=no" fi - -ac_fn_c_check_func "$LINENO" "opendir" "ac_cv_func_opendir" -if test "x$ac_cv_func_opendir" = xyes; then : - $as_echo "#define HAVE_OPENDIR 1" >>confdefs.h - -else - case " $LIBOBJS " in - *" opendir.$ac_objext "* ) ;; - *) LIBOBJS="$LIBOBJS opendir.$ac_objext" - ;; -esac - +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext fi - -ac_fn_c_check_func "$LINENO" "strtol" "ac_cv_func_strtol" -if test "x$ac_cv_func_strtol" = xyes; then : - $as_echo "#define HAVE_STRTOL 1" >>confdefs.h +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF else - case " $LIBOBJS " in - *" strtol.$ac_objext "* ) ;; - *) LIBOBJS="$LIBOBJS strtol.$ac_objext" - ;; -esac + +cat >>confdefs.h <<\_ACEOF +#define USEGETWD 1 +_ACEOF fi +done -ac_fn_c_check_func "$LINENO" "waitpid" "ac_cv_func_waitpid" -if test "x$ac_cv_func_waitpid" = xyes; then : - $as_echo "#define HAVE_WAITPID 1" >>confdefs.h +# Nb: if getcwd uses popen and pwd(1) (like SunOS 4) we should really +# define USEGETWD even if the posix getcwd exists. Add a test ? -else - case " $LIBOBJS " in - *" waitpid.$ac_objext "* ) ;; - *) LIBOBJS="$LIBOBJS waitpid.$ac_objext" - ;; -esac -fi -ac_fn_c_check_func "$LINENO" "strerror" "ac_cv_func_strerror" -if test "x$ac_cv_func_strerror" = xyes; then : -else +for ac_func in mkstemp opendir strtol waitpid +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 +if eval "test \"\${$as_ac_var+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case declares $ac_func. + For example, HP-UX 11i declares gettimeofday. */ +#define $ac_func innocuous_$ac_func -$as_echo "#define NO_STRERROR 1" >>confdefs.h +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ -fi +#ifdef __STDC__ +# include +#else +# include +#endif -ac_fn_c_check_func "$LINENO" "getwd" "ac_cv_func_getwd" -if test "x$ac_cv_func_getwd" = xyes; then : +#undef $ac_func -else +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +char (*f) () = $ac_func; +#endif +#ifdef __cplusplus +} +#endif -$as_echo "#define NO_GETWD 1" >>confdefs.h +int +main () +{ +return f != $ac_func; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 +eval "$as_ac_var=no" fi - -ac_fn_c_check_func "$LINENO" "wait3" "ac_cv_func_wait3" -if test "x$ac_cv_func_wait3" = xyes; then : +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF else - -$as_echo "#define NO_WAIT3 1" >>confdefs.h + case $LIBOBJS in + "$ac_func.$ac_objext" | \ + *" $ac_func.$ac_objext" | \ + "$ac_func.$ac_objext "* | \ + *" $ac_func.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS $ac_func.$ac_objext" ;; +esac fi +done -ac_fn_c_check_func "$LINENO" "uname" "ac_cv_func_uname" -if test "x$ac_cv_func_uname" = xyes; then : +echo "$as_me:$LINENO: checking for strerror" >&5 +echo $ECHO_N "checking for strerror... $ECHO_C" >&6 +if test "${ac_cv_func_strerror+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define strerror to an innocuous variant, in case declares strerror. + For example, HP-UX 11i declares gettimeofday. */ +#define strerror innocuous_strerror -$as_echo "#define NO_UNAME 1" >>confdefs.h +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char strerror (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ -fi +#ifdef __STDC__ +# include +#else +# include +#endif +#undef strerror -if test "`uname -s`" = "Darwin" && test "${TCL_THREADS}" = 1 && \ - test "`uname -r | awk -F. '{print $1}'`" -lt 7; then - # prior to Darwin 7, realpath is not threadsafe, so don't - # use it when threads are enabled, c.f. bug # 711232 - ac_cv_func_realpath=no -fi -ac_fn_c_check_func "$LINENO" "realpath" "ac_cv_func_realpath" -if test "x$ac_cv_func_realpath" = xyes; then : +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char strerror (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_strerror) || defined (__stub___strerror) +choke me +#else +char (*f) () = strerror; +#endif +#ifdef __cplusplus +} +#endif +int +main () +{ +return f != strerror; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_strerror=yes else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 -$as_echo "#define NO_REALPATH 1" >>confdefs.h - +ac_cv_func_strerror=no fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_func_strerror" >&5 +echo "${ECHO_T}$ac_cv_func_strerror" >&6 +if test $ac_cv_func_strerror = yes; then + : +else - - - NEED_FAKE_RFC2553=0 - for ac_func in getnameinfo getaddrinfo freeaddrinfo gai_strerror -do : - as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` -ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" -if eval test \"x\$"$as_ac_var"\" = x"yes"; then : - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +cat >>confdefs.h <<\_ACEOF +#define NO_STRERROR 1 _ACEOF -else - NEED_FAKE_RFC2553=1 fi -done - ac_fn_c_check_type "$LINENO" "struct addrinfo" "ac_cv_type_struct_addrinfo" " -#include -#include -#include -#include +echo "$as_me:$LINENO: checking for getwd" >&5 +echo $ECHO_N "checking for getwd... $ECHO_C" >&6 +if test "${ac_cv_func_getwd+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define getwd to an innocuous variant, in case declares getwd. + For example, HP-UX 11i declares gettimeofday. */ +#define getwd innocuous_getwd -" -if test "x$ac_cv_type_struct_addrinfo" = xyes; then : +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char getwd (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ -cat >>confdefs.h <<_ACEOF -#define HAVE_STRUCT_ADDRINFO 1 -_ACEOF +#ifdef __STDC__ +# include +#else +# include +#endif +#undef getwd -else - NEED_FAKE_RFC2553=1 -fi -ac_fn_c_check_type "$LINENO" "struct in6_addr" "ac_cv_type_struct_in6_addr" " -#include -#include -#include -#include - -" -if test "x$ac_cv_type_struct_in6_addr" = xyes; then : +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char getwd (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_getwd) || defined (__stub___getwd) +choke me +#else +char (*f) () = getwd; +#endif +#ifdef __cplusplus +} +#endif -cat >>confdefs.h <<_ACEOF -#define HAVE_STRUCT_IN6_ADDR 1 +int +main () +{ +return f != getwd; + ; + return 0; +} _ACEOF - - +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_getwd=yes else - NEED_FAKE_RFC2553=1 -fi -ac_fn_c_check_type "$LINENO" "struct sockaddr_in6" "ac_cv_type_struct_sockaddr_in6" " -#include -#include -#include -#include - -" -if test "x$ac_cv_type_struct_sockaddr_in6" = xyes; then : - -cat >>confdefs.h <<_ACEOF -#define HAVE_STRUCT_SOCKADDR_IN6 1 -_ACEOF - + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 -else - NEED_FAKE_RFC2553=1 +ac_cv_func_getwd=no fi -ac_fn_c_check_type "$LINENO" "struct sockaddr_storage" "ac_cv_type_struct_sockaddr_storage" " -#include -#include -#include -#include - -" -if test "x$ac_cv_type_struct_sockaddr_storage" = xyes; then : - -cat >>confdefs.h <<_ACEOF -#define HAVE_STRUCT_SOCKADDR_STORAGE 1 -_ACEOF - - -else - NEED_FAKE_RFC2553=1 +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext fi +echo "$as_me:$LINENO: result: $ac_cv_func_getwd" >&5 +echo "${ECHO_T}$ac_cv_func_getwd" >&6 +if test $ac_cv_func_getwd = yes; then + : +else -if test "x$NEED_FAKE_RFC2553" = "x1"; then - -$as_echo "#define NEED_FAKE_RFC2553 1" >>confdefs.h - - case " $LIBOBJS " in - *" fake-rfc2553.$ac_objext "* ) ;; - *) LIBOBJS="$LIBOBJS fake-rfc2553.$ac_objext" - ;; -esac - - ac_fn_c_check_func "$LINENO" "strlcpy" "ac_cv_func_strlcpy" -if test "x$ac_cv_func_strlcpy" = xyes; then : - -fi +cat >>confdefs.h <<\_ACEOF +#define NO_GETWD 1 +_ACEOF fi +echo "$as_me:$LINENO: checking for wait3" >&5 +echo $ECHO_N "checking for wait3... $ECHO_C" >&6 +if test "${ac_cv_func_wait3+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define wait3 to an innocuous variant, in case declares wait3. + For example, HP-UX 11i declares gettimeofday. */ +#define wait3 innocuous_wait3 -#-------------------------------------------------------------------- -# Look for thread-safe variants of some library functions. -#-------------------------------------------------------------------- - -if test "${TCL_THREADS}" = 1; then - ac_fn_c_check_func "$LINENO" "getpwuid_r" "ac_cv_func_getpwuid_r" -if test "x$ac_cv_func_getpwuid_r" = xyes; then : +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char wait3 (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for getpwuid_r with 5 args" >&5 -$as_echo_n "checking for getpwuid_r with 5 args... " >&6; } -if ${tcl_cv_api_getpwuid_r_5+:} false; then : - $as_echo_n "(cached) " >&6 -else +#ifdef __STDC__ +# include +#else +# include +#endif - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ +#undef wait3 - #include - #include +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char wait3 (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_wait3) || defined (__stub___wait3) +choke me +#else +char (*f) () = wait3; +#endif +#ifdef __cplusplus +} +#endif int main () { - - uid_t uid; - struct passwd pw, *pwp; - char buf[512]; - int buflen = 512; - - (void) getpwuid_r(uid, &pw, buf, buflen, &pwp); - +return f != wait3; ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - tcl_cv_api_getpwuid_r_5=yes +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_wait3=yes else - tcl_cv_api_getpwuid_r_5=no + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_func_wait3=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_api_getpwuid_r_5" >&5 -$as_echo "$tcl_cv_api_getpwuid_r_5" >&6; } - tcl_ok=$tcl_cv_api_getpwuid_r_5 - if test "$tcl_ok" = yes; then +echo "$as_me:$LINENO: result: $ac_cv_func_wait3" >&5 +echo "${ECHO_T}$ac_cv_func_wait3" >&6 +if test $ac_cv_func_wait3 = yes; then + : +else + +cat >>confdefs.h <<\_ACEOF +#define NO_WAIT3 1 +_ACEOF -$as_echo "#define HAVE_GETPWUID_R_5 1" >>confdefs.h +fi - else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for getpwuid_r with 4 args" >&5 -$as_echo_n "checking for getpwuid_r with 4 args... " >&6; } -if ${tcl_cv_api_getpwuid_r_4+:} false; then : - $as_echo_n "(cached) " >&6 +echo "$as_me:$LINENO: checking for uname" >&5 +echo $ECHO_N "checking for uname... $ECHO_C" >&6 +if test "${ac_cv_func_uname+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 else - - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ +/* Define uname to an innocuous variant, in case declares uname. + For example, HP-UX 11i declares gettimeofday. */ +#define uname innocuous_uname - #include - #include +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char uname (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ -int -main () -{ +#ifdef __STDC__ +# include +#else +# include +#endif - uid_t uid; - struct passwd pw; - char buf[512]; - int buflen = 512; +#undef uname - (void)getpwnam_r(uid, &pw, buf, buflen); +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char uname (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_uname) || defined (__stub___uname) +choke me +#else +char (*f) () = uname; +#endif +#ifdef __cplusplus +} +#endif +int +main () +{ +return f != uname; ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - tcl_cv_api_getpwuid_r_4=yes +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_uname=yes else - tcl_cv_api_getpwuid_r_4=no + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_func_uname=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_api_getpwuid_r_4" >&5 -$as_echo "$tcl_cv_api_getpwuid_r_4" >&6; } - tcl_ok=$tcl_cv_api_getpwuid_r_4 - if test "$tcl_ok" = yes; then - -$as_echo "#define HAVE_GETPWUID_R_4 1" >>confdefs.h +echo "$as_me:$LINENO: result: $ac_cv_func_uname" >&5 +echo "${ECHO_T}$ac_cv_func_uname" >&6 +if test $ac_cv_func_uname = yes; then + : +else - fi - fi - if test "$tcl_ok" = yes; then +cat >>confdefs.h <<\_ACEOF +#define NO_UNAME 1 +_ACEOF -$as_echo "#define HAVE_GETPWUID_R 1" >>confdefs.h +fi - fi +if test "`uname -s`" = "Darwin" && test "${TCL_THREADS}" = 1 && \ + test "`uname -r | awk -F. '{print $1}'`" -lt 7; then + # prior to Darwin 7, realpath is not threadsafe, so don't + # use it when threads are enabled, c.f. bug # 711232 + ac_cv_func_realpath=no fi +echo "$as_me:$LINENO: checking for realpath" >&5 +echo $ECHO_N "checking for realpath... $ECHO_C" >&6 +if test "${ac_cv_func_realpath+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define realpath to an innocuous variant, in case declares realpath. + For example, HP-UX 11i declares gettimeofday. */ +#define realpath innocuous_realpath - ac_fn_c_check_func "$LINENO" "getpwnam_r" "ac_cv_func_getpwnam_r" -if test "x$ac_cv_func_getpwnam_r" = xyes; then : +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char realpath (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for getpwnam_r with 5 args" >&5 -$as_echo_n "checking for getpwnam_r with 5 args... " >&6; } -if ${tcl_cv_api_getpwnam_r_5+:} false; then : - $as_echo_n "(cached) " >&6 -else +#ifdef __STDC__ +# include +#else +# include +#endif - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ +#undef realpath - #include - #include +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char realpath (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_realpath) || defined (__stub___realpath) +choke me +#else +char (*f) () = realpath; +#endif +#ifdef __cplusplus +} +#endif int main () { - - char *name; - struct passwd pw, *pwp; - char buf[512]; - int buflen = 512; - - (void) getpwnam_r(name, &pw, buf, buflen, &pwp); - +return f != realpath; ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - tcl_cv_api_getpwnam_r_5=yes +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_realpath=yes else - tcl_cv_api_getpwnam_r_5=no + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_func_realpath=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_api_getpwnam_r_5" >&5 -$as_echo "$tcl_cv_api_getpwnam_r_5" >&6; } - tcl_ok=$tcl_cv_api_getpwnam_r_5 - if test "$tcl_ok" = yes; then +echo "$as_me:$LINENO: result: $ac_cv_func_realpath" >&5 +echo "${ECHO_T}$ac_cv_func_realpath" >&6 +if test $ac_cv_func_realpath = yes; then + : +else -$as_echo "#define HAVE_GETPWNAM_R_5 1" >>confdefs.h +cat >>confdefs.h <<\_ACEOF +#define NO_REALPATH 1 +_ACEOF - else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for getpwnam_r with 4 args" >&5 -$as_echo_n "checking for getpwnam_r with 4 args... " >&6; } -if ${tcl_cv_api_getpwnam_r_4+:} false; then : - $as_echo_n "(cached) " >&6 -else +fi - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - #include - #include -int -main () -{ + NEED_FAKE_RFC2553=0 - char *name; - struct passwd pw; - char buf[512]; - int buflen = 512; - (void)getpwnam_r(name, &pw, buf, buflen); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - tcl_cv_api_getpwnam_r_4=yes -else - tcl_cv_api_getpwnam_r_4=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_api_getpwnam_r_4" >&5 -$as_echo "$tcl_cv_api_getpwnam_r_4" >&6; } - tcl_ok=$tcl_cv_api_getpwnam_r_4 - if test "$tcl_ok" = yes; then - -$as_echo "#define HAVE_GETPWNAM_R_4 1" >>confdefs.h - - fi - fi - if test "$tcl_ok" = yes; then - -$as_echo "#define HAVE_GETPWNAM_R 1" >>confdefs.h - - fi -fi +for ac_func in getnameinfo getaddrinfo freeaddrinfo gai_strerror +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 +if eval "test \"\${$as_ac_var+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case declares $ac_func. + For example, HP-UX 11i declares gettimeofday. */ +#define $ac_func innocuous_$ac_func - ac_fn_c_check_func "$LINENO" "getgrgid_r" "ac_cv_func_getgrgid_r" -if test "x$ac_cv_func_getgrgid_r" = xyes; then : +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for getgrgid_r with 5 args" >&5 -$as_echo_n "checking for getgrgid_r with 5 args... " >&6; } -if ${tcl_cv_api_getgrgid_r_5+:} false; then : - $as_echo_n "(cached) " >&6 -else +#ifdef __STDC__ +# include +#else +# include +#endif - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ +#undef $ac_func - #include - #include +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +char (*f) () = $ac_func; +#endif +#ifdef __cplusplus +} +#endif int main () { - - gid_t gid; - struct group gr, *grp; - char buf[512]; - int buflen = 512; - - (void) getgrgid_r(gid, &gr, buf, buflen, &grp); - +return f != $ac_func; ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - tcl_cv_api_getgrgid_r_5=yes +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_var=yes" else - tcl_cv_api_getgrgid_r_5=no + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +eval "$as_ac_var=no" fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_api_getgrgid_r_5" >&5 -$as_echo "$tcl_cv_api_getgrgid_r_5" >&6; } - tcl_ok=$tcl_cv_api_getgrgid_r_5 - if test "$tcl_ok" = yes; then - -$as_echo "#define HAVE_GETGRGID_R_5 1" >>confdefs.h +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF - else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for getgrgid_r with 4 args" >&5 -$as_echo_n "checking for getgrgid_r with 4 args... " >&6; } -if ${tcl_cv_api_getgrgid_r_4+:} false; then : - $as_echo_n "(cached) " >&6 else + NEED_FAKE_RFC2553=1 +fi +done - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + echo "$as_me:$LINENO: checking for struct addrinfo" >&5 +echo $ECHO_N "checking for struct addrinfo... $ECHO_C" >&6 +if test "${ac_cv_type_struct_addrinfo+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ - #include - #include +#include +#include +#include +#include + int main () { - - gid_t gid; - struct group gr; - char buf[512]; - int buflen = 512; - - (void)getgrgid_r(gid, &gr, buf, buflen); - +if ((struct addrinfo *) 0) + return 0; +if (sizeof (struct addrinfo)) + return 0; ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - tcl_cv_api_getgrgid_r_4=yes +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_type_struct_addrinfo=yes else - tcl_cv_api_getgrgid_r_4=no + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_type_struct_addrinfo=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_api_getgrgid_r_4" >&5 -$as_echo "$tcl_cv_api_getgrgid_r_4" >&6; } - tcl_ok=$tcl_cv_api_getgrgid_r_4 - if test "$tcl_ok" = yes; then - -$as_echo "#define HAVE_GETGRGID_R_4 1" >>confdefs.h - - fi - fi - if test "$tcl_ok" = yes; then +echo "$as_me:$LINENO: result: $ac_cv_type_struct_addrinfo" >&5 +echo "${ECHO_T}$ac_cv_type_struct_addrinfo" >&6 +if test $ac_cv_type_struct_addrinfo = yes; then -$as_echo "#define HAVE_GETGRGID_R 1" >>confdefs.h +cat >>confdefs.h <<_ACEOF +#define HAVE_STRUCT_ADDRINFO 1 +_ACEOF - fi +else + NEED_FAKE_RFC2553=1 fi - - ac_fn_c_check_func "$LINENO" "getgrnam_r" "ac_cv_func_getgrnam_r" -if test "x$ac_cv_func_getgrnam_r" = xyes; then : - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for getgrnam_r with 5 args" >&5 -$as_echo_n "checking for getgrnam_r with 5 args... " >&6; } -if ${tcl_cv_api_getgrnam_r_5+:} false; then : - $as_echo_n "(cached) " >&6 +echo "$as_me:$LINENO: checking for struct in6_addr" >&5 +echo $ECHO_N "checking for struct in6_addr... $ECHO_C" >&6 +if test "${ac_cv_type_struct_in6_addr+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 else - - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ - #include - #include +#include +#include +#include +#include + int main () { - - char *name; - struct group gr, *grp; - char buf[512]; - int buflen = 512; - - (void) getgrnam_r(name, &gr, buf, buflen, &grp); - +if ((struct in6_addr *) 0) + return 0; +if (sizeof (struct in6_addr)) + return 0; ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - tcl_cv_api_getgrnam_r_5=yes +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_type_struct_in6_addr=yes else - tcl_cv_api_getgrnam_r_5=no + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_type_struct_in6_addr=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_api_getgrnam_r_5" >&5 -$as_echo "$tcl_cv_api_getgrnam_r_5" >&6; } - tcl_ok=$tcl_cv_api_getgrnam_r_5 - if test "$tcl_ok" = yes; then +echo "$as_me:$LINENO: result: $ac_cv_type_struct_in6_addr" >&5 +echo "${ECHO_T}$ac_cv_type_struct_in6_addr" >&6 +if test $ac_cv_type_struct_in6_addr = yes; then + +cat >>confdefs.h <<_ACEOF +#define HAVE_STRUCT_IN6_ADDR 1 +_ACEOF -$as_echo "#define HAVE_GETGRNAM_R_5 1" >>confdefs.h - else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for getgrnam_r with 4 args" >&5 -$as_echo_n "checking for getgrnam_r with 4 args... " >&6; } -if ${tcl_cv_api_getgrnam_r_4+:} false; then : - $as_echo_n "(cached) " >&6 else - - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + NEED_FAKE_RFC2553=1 +fi +echo "$as_me:$LINENO: checking for struct sockaddr_in6" >&5 +echo $ECHO_N "checking for struct sockaddr_in6... $ECHO_C" >&6 +if test "${ac_cv_type_struct_sockaddr_in6+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ - #include - #include +#include +#include +#include +#include + int main () { - - char *name; - struct group gr; - char buf[512]; - int buflen = 512; - - (void)getgrnam_r(name, &gr, buf, buflen); - +if ((struct sockaddr_in6 *) 0) + return 0; +if (sizeof (struct sockaddr_in6)) + return 0; ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - tcl_cv_api_getgrnam_r_4=yes +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_type_struct_sockaddr_in6=yes else - tcl_cv_api_getgrnam_r_4=no + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_type_struct_sockaddr_in6=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_api_getgrnam_r_4" >&5 -$as_echo "$tcl_cv_api_getgrnam_r_4" >&6; } - tcl_ok=$tcl_cv_api_getgrnam_r_4 - if test "$tcl_ok" = yes; then - -$as_echo "#define HAVE_GETGRNAM_R_4 1" >>confdefs.h - - fi - fi - if test "$tcl_ok" = yes; then +echo "$as_me:$LINENO: result: $ac_cv_type_struct_sockaddr_in6" >&5 +echo "${ECHO_T}$ac_cv_type_struct_sockaddr_in6" >&6 +if test $ac_cv_type_struct_sockaddr_in6 = yes; then -$as_echo "#define HAVE_GETGRNAM_R 1" >>confdefs.h +cat >>confdefs.h <<_ACEOF +#define HAVE_STRUCT_SOCKADDR_IN6 1 +_ACEOF - fi +else + NEED_FAKE_RFC2553=1 fi - - if test "`uname -s`" = "Darwin" && \ - test "`uname -r | awk -F. '{print $1}'`" -gt 5; then - # Starting with Darwin 6 (Mac OSX 10.2), gethostbyX - # are actually MT-safe as they always return pointers - # from TSD instead of static storage. - -$as_echo "#define HAVE_MTSAFE_GETHOSTBYNAME 1" >>confdefs.h - - -$as_echo "#define HAVE_MTSAFE_GETHOSTBYADDR 1" >>confdefs.h - - - elif test "`uname -s`" = "HP-UX" && \ - test "`uname -r|sed -e 's|B\.||' -e 's|\..*$||'`" -gt 10; then - # Starting with HPUX 11.00 (we believe), gethostbyX - # are actually MT-safe as they always return pointers - # from TSD instead of static storage. - -$as_echo "#define HAVE_MTSAFE_GETHOSTBYNAME 1" >>confdefs.h - - -$as_echo "#define HAVE_MTSAFE_GETHOSTBYADDR 1" >>confdefs.h - - - else - ac_fn_c_check_func "$LINENO" "gethostbyname_r" "ac_cv_func_gethostbyname_r" -if test "x$ac_cv_func_gethostbyname_r" = xyes; then : - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyname_r with 6 args" >&5 -$as_echo_n "checking for gethostbyname_r with 6 args... " >&6; } -if ${tcl_cv_api_gethostbyname_r_6+:} false; then : - $as_echo_n "(cached) " >&6 +echo "$as_me:$LINENO: checking for struct sockaddr_storage" >&5 +echo $ECHO_N "checking for struct sockaddr_storage... $ECHO_C" >&6 +if test "${ac_cv_type_struct_sockaddr_storage+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 else - - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ - #include +#include +#include +#include +#include + int main () { - - char *name; - struct hostent *he, *res; - char buffer[2048]; - int buflen = 2048; - int h_errnop; - - (void) gethostbyname_r(name, he, buffer, buflen, &res, &h_errnop); - +if ((struct sockaddr_storage *) 0) + return 0; +if (sizeof (struct sockaddr_storage)) + return 0; ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - tcl_cv_api_gethostbyname_r_6=yes +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_type_struct_sockaddr_storage=yes else - tcl_cv_api_gethostbyname_r_6=no + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_type_struct_sockaddr_storage=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_api_gethostbyname_r_6" >&5 -$as_echo "$tcl_cv_api_gethostbyname_r_6" >&6; } - tcl_ok=$tcl_cv_api_gethostbyname_r_6 - if test "$tcl_ok" = yes; then +echo "$as_me:$LINENO: result: $ac_cv_type_struct_sockaddr_storage" >&5 +echo "${ECHO_T}$ac_cv_type_struct_sockaddr_storage" >&6 +if test $ac_cv_type_struct_sockaddr_storage = yes; then -$as_echo "#define HAVE_GETHOSTBYNAME_R_6 1" >>confdefs.h +cat >>confdefs.h <<_ACEOF +#define HAVE_STRUCT_SOCKADDR_STORAGE 1 +_ACEOF - else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyname_r with 5 args" >&5 -$as_echo_n "checking for gethostbyname_r with 5 args... " >&6; } -if ${tcl_cv_api_gethostbyname_r_5+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ +else + NEED_FAKE_RFC2553=1 +fi - #include +if test "x$NEED_FAKE_RFC2553" = "x1"; then -int -main () -{ +cat >>confdefs.h <<\_ACEOF +#define NEED_FAKE_RFC2553 1 +_ACEOF - char *name; - struct hostent *he; - char buffer[2048]; - int buflen = 2048; - int h_errnop; + case $LIBOBJS in + "fake-rfc2553.$ac_objext" | \ + *" fake-rfc2553.$ac_objext" | \ + "fake-rfc2553.$ac_objext "* | \ + *" fake-rfc2553.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS fake-rfc2553.$ac_objext" ;; +esac - (void) gethostbyname_r(name, he, buffer, buflen, &h_errnop); + echo "$as_me:$LINENO: checking for strlcpy" >&5 +echo $ECHO_N "checking for strlcpy... $ECHO_C" >&6 +if test "${ac_cv_func_strlcpy+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define strlcpy to an innocuous variant, in case declares strlcpy. + For example, HP-UX 11i declares gettimeofday. */ +#define strlcpy innocuous_strlcpy + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char strlcpy (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef strlcpy +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char strlcpy (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_strlcpy) || defined (__stub___strlcpy) +choke me +#else +char (*f) () = strlcpy; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != strlcpy; ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - tcl_cv_api_gethostbyname_r_5=yes +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_strlcpy=yes else - tcl_cv_api_gethostbyname_r_5=no + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_func_strlcpy=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_api_gethostbyname_r_5" >&5 -$as_echo "$tcl_cv_api_gethostbyname_r_5" >&6; } - tcl_ok=$tcl_cv_api_gethostbyname_r_5 - if test "$tcl_ok" = yes; then +echo "$as_me:$LINENO: result: $ac_cv_func_strlcpy" >&5 +echo "${ECHO_T}$ac_cv_func_strlcpy" >&6 -$as_echo "#define HAVE_GETHOSTBYNAME_R_5 1" >>confdefs.h +fi - else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyname_r with 3 args" >&5 -$as_echo_n "checking for gethostbyname_r with 3 args... " >&6; } -if ${tcl_cv_api_gethostbyname_r_3+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext +#-------------------------------------------------------------------- +# Look for thread-safe variants of some library functions. +#-------------------------------------------------------------------- + +if test "${TCL_THREADS}" = 1; then + echo "$as_me:$LINENO: checking for getpwuid_r" >&5 +echo $ECHO_N "checking for getpwuid_r... $ECHO_C" >&6 +if test "${ac_cv_func_getpwuid_r+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ +/* Define getpwuid_r to an innocuous variant, in case declares getpwuid_r. + For example, HP-UX 11i declares gettimeofday. */ +#define getpwuid_r innocuous_getpwuid_r - #include +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char getpwuid_r (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ -int -main () -{ +#ifdef __STDC__ +# include +#else +# include +#endif - char *name; - struct hostent *he; - struct hostent_data data; +#undef getpwuid_r - (void) gethostbyname_r(name, he, &data); +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char getpwuid_r (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_getpwuid_r) || defined (__stub___getpwuid_r) +choke me +#else +char (*f) () = getpwuid_r; +#endif +#ifdef __cplusplus +} +#endif +int +main () +{ +return f != getpwuid_r; ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - tcl_cv_api_gethostbyname_r_3=yes +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_getpwuid_r=yes else - tcl_cv_api_gethostbyname_r_3=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_api_gethostbyname_r_3" >&5 -$as_echo "$tcl_cv_api_gethostbyname_r_3" >&6; } - tcl_ok=$tcl_cv_api_gethostbyname_r_3 - if test "$tcl_ok" = yes; then - -$as_echo "#define HAVE_GETHOSTBYNAME_R_3 1" >>confdefs.h - - fi - fi - fi - if test "$tcl_ok" = yes; then - -$as_echo "#define HAVE_GETHOSTBYNAME_R 1" >>confdefs.h - - fi + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 +ac_cv_func_getpwuid_r=no fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_func_getpwuid_r" >&5 +echo "${ECHO_T}$ac_cv_func_getpwuid_r" >&6 +if test $ac_cv_func_getpwuid_r = yes; then - ac_fn_c_check_func "$LINENO" "gethostbyaddr_r" "ac_cv_func_gethostbyaddr_r" -if test "x$ac_cv_func_gethostbyaddr_r" = xyes; then : - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyaddr_r with 7 args" >&5 -$as_echo_n "checking for gethostbyaddr_r with 7 args... " >&6; } -if ${tcl_cv_api_gethostbyaddr_r_7+:} false; then : - $as_echo_n "(cached) " >&6 + echo "$as_me:$LINENO: checking for getpwuid_r with 5 args" >&5 +echo $ECHO_N "checking for getpwuid_r with 5 args... $ECHO_C" >&6 +if test "${tcl_cv_api_getpwuid_r_5+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ - #include + #include + #include int main () { - char *addr; - int length; - int type; - struct hostent *result; - char buffer[2048]; - int buflen = 2048; - int h_errnop; + uid_t uid; + struct passwd pw, *pwp; + char buf[512]; + int buflen = 512; - (void) gethostbyaddr_r(addr, length, type, result, buffer, buflen, - &h_errnop); + (void) getpwuid_r(uid, &pw, buf, buflen, &pwp); ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - tcl_cv_api_gethostbyaddr_r_7=yes +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + tcl_cv_api_getpwuid_r_5=yes else - tcl_cv_api_gethostbyaddr_r_7=no + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +tcl_cv_api_getpwuid_r_5=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_api_gethostbyaddr_r_7" >&5 -$as_echo "$tcl_cv_api_gethostbyaddr_r_7" >&6; } - tcl_ok=$tcl_cv_api_gethostbyaddr_r_7 +echo "$as_me:$LINENO: result: $tcl_cv_api_getpwuid_r_5" >&5 +echo "${ECHO_T}$tcl_cv_api_getpwuid_r_5" >&6 + tcl_ok=$tcl_cv_api_getpwuid_r_5 if test "$tcl_ok" = yes; then -$as_echo "#define HAVE_GETHOSTBYADDR_R_7 1" >>confdefs.h +cat >>confdefs.h <<\_ACEOF +#define HAVE_GETPWUID_R_5 1 +_ACEOF else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyaddr_r with 8 args" >&5 -$as_echo_n "checking for gethostbyaddr_r with 8 args... " >&6; } -if ${tcl_cv_api_gethostbyaddr_r_8+:} false; then : - $as_echo_n "(cached) " >&6 + echo "$as_me:$LINENO: checking for getpwuid_r with 4 args" >&5 +echo $ECHO_N "checking for getpwuid_r with 4 args... $ECHO_C" >&6 +if test "${tcl_cv_api_getpwuid_r_4+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ - #include + #include + #include int main () { - char *addr; - int length; - int type; - struct hostent *result, *resultp; - char buffer[2048]; - int buflen = 2048; - int h_errnop; + uid_t uid; + struct passwd pw; + char buf[512]; + int buflen = 512; - (void) gethostbyaddr_r(addr, length, type, result, buffer, buflen, - &resultp, &h_errnop); + (void)getpwnam_r(uid, &pw, buf, buflen); ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - tcl_cv_api_gethostbyaddr_r_8=yes +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + tcl_cv_api_getpwuid_r_4=yes else - tcl_cv_api_gethostbyaddr_r_8=no + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +tcl_cv_api_getpwuid_r_4=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_api_gethostbyaddr_r_8" >&5 -$as_echo "$tcl_cv_api_gethostbyaddr_r_8" >&6; } - tcl_ok=$tcl_cv_api_gethostbyaddr_r_8 +echo "$as_me:$LINENO: result: $tcl_cv_api_getpwuid_r_4" >&5 +echo "${ECHO_T}$tcl_cv_api_getpwuid_r_4" >&6 + tcl_ok=$tcl_cv_api_getpwuid_r_4 if test "$tcl_ok" = yes; then -$as_echo "#define HAVE_GETHOSTBYADDR_R_8 1" >>confdefs.h +cat >>confdefs.h <<\_ACEOF +#define HAVE_GETPWUID_R_4 1 +_ACEOF fi fi if test "$tcl_ok" = yes; then -$as_echo "#define HAVE_GETHOSTBYADDR_R 1" >>confdefs.h - - fi - -fi - - fi -fi - -#--------------------------------------------------------------------------- -# Check for serial port interface. -# -# termios.h is present on all POSIX systems. -# sys/ioctl.h is almost always present, though what it contains -# is system-specific. -# sys/modem.h is needed on HP-UX. -#--------------------------------------------------------------------------- - -for ac_header in termios.h -do : - ac_fn_c_check_header_mongrel "$LINENO" "termios.h" "ac_cv_header_termios_h" "$ac_includes_default" -if test "x$ac_cv_header_termios_h" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_TERMIOS_H 1 +cat >>confdefs.h <<\_ACEOF +#define HAVE_GETPWUID_R 1 _ACEOF -fi - -done - -for ac_header in sys/ioctl.h -do : - ac_fn_c_check_header_mongrel "$LINENO" "sys/ioctl.h" "ac_cv_header_sys_ioctl_h" "$ac_includes_default" -if test "x$ac_cv_header_sys_ioctl_h" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_SYS_IOCTL_H 1 -_ACEOF + fi fi -done - -for ac_header in sys/modem.h -do : - ac_fn_c_check_header_mongrel "$LINENO" "sys/modem.h" "ac_cv_header_sys_modem_h" "$ac_includes_default" -if test "x$ac_cv_header_sys_modem_h" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_SYS_MODEM_H 1 + echo "$as_me:$LINENO: checking for getpwnam_r" >&5 +echo $ECHO_N "checking for getpwnam_r... $ECHO_C" >&6 +if test "${ac_cv_func_getpwnam_r+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ _ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define getpwnam_r to an innocuous variant, in case declares getpwnam_r. + For example, HP-UX 11i declares gettimeofday. */ +#define getpwnam_r innocuous_getpwnam_r -fi - -done +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char getpwnam_r (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ +#ifdef __STDC__ +# include +#else +# include +#endif -#-------------------------------------------------------------------- -# Include sys/select.h if it exists and if it supplies things -# that appear to be useful and aren't already in sys/types.h. -# This appears to be true only on the RS/6000 under AIX. Some -# systems like OSF/1 have a sys/select.h that's of no use, and -# other systems like SCO UNIX have a sys/select.h that's -# pernicious. If "fd_set" isn't defined anywhere then set a -# special flag. -#-------------------------------------------------------------------- +#undef getpwnam_r -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fd_set in sys/types" >&5 -$as_echo_n "checking for fd_set in sys/types... " >&6; } -if ${tcl_cv_type_fd_set+:} false; then : - $as_echo_n "(cached) " >&6 -else +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char getpwnam_r (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_getpwnam_r) || defined (__stub___getpwnam_r) +choke me +#else +char (*f) () = getpwnam_r; +#endif +#ifdef __cplusplus +} +#endif - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include int main () { -fd_set readMask, writeMask; +return f != getpwnam_r; ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - tcl_cv_type_fd_set=yes +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_getpwnam_r=yes else - tcl_cv_type_fd_set=no + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_func_getpwnam_r=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_type_fd_set" >&5 -$as_echo "$tcl_cv_type_fd_set" >&6; } -tcl_ok=$tcl_cv_type_fd_set -if test $tcl_ok = no; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fd_mask in sys/select" >&5 -$as_echo_n "checking for fd_mask in sys/select... " >&6; } -if ${tcl_cv_grep_fd_mask+:} false; then : - $as_echo_n "(cached) " >&6 +echo "$as_me:$LINENO: result: $ac_cv_func_getpwnam_r" >&5 +echo "${ECHO_T}$ac_cv_func_getpwnam_r" >&6 +if test $ac_cv_func_getpwnam_r = yes; then + + echo "$as_me:$LINENO: checking for getpwnam_r with 5 args" >&5 +echo $ECHO_N "checking for getpwnam_r with 5 args... $ECHO_C" >&6 +if test "${tcl_cv_api_getpwnam_r_5+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ -#include -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "fd_mask" >/dev/null 2>&1; then : - tcl_cv_grep_fd_mask=present -else - tcl_cv_grep_fd_mask=missing -fi -rm -f conftest* + #include + #include -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_grep_fd_mask" >&5 -$as_echo "$tcl_cv_grep_fd_mask" >&6; } - if test $tcl_cv_grep_fd_mask = present; then - -$as_echo "#define HAVE_SYS_SELECT_H 1" >>confdefs.h - - tcl_ok=yes - fi -fi -if test $tcl_ok = no; then - -$as_echo "#define NO_FD_SET 1" >>confdefs.h - -fi +int +main () +{ -#------------------------------------------------------------------------------ -# Find out all about time handling differences. -#------------------------------------------------------------------------------ + char *name; + struct passwd pw, *pwp; + char buf[512]; + int buflen = 512; + (void) getpwnam_r(name, &pw, buf, buflen, &pwp); - for ac_header in sys/time.h -do : - ac_fn_c_check_header_mongrel "$LINENO" "sys/time.h" "ac_cv_header_sys_time_h" "$ac_includes_default" -if test "x$ac_cv_header_sys_time_h" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_SYS_TIME_H 1 + ; + return 0; +} _ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + tcl_cv_api_getpwnam_r_5=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 +tcl_cv_api_getpwnam_r_5=no fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $tcl_cv_api_getpwnam_r_5" >&5 +echo "${ECHO_T}$tcl_cv_api_getpwnam_r_5" >&6 + tcl_ok=$tcl_cv_api_getpwnam_r_5 + if test "$tcl_ok" = yes; then -done +cat >>confdefs.h <<\_ACEOF +#define HAVE_GETPWNAM_R_5 1 +_ACEOF - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether time.h and sys/time.h may both be included" >&5 -$as_echo_n "checking whether time.h and sys/time.h may both be included... " >&6; } -if ${ac_cv_header_time+:} false; then : - $as_echo_n "(cached) " >&6 + else + echo "$as_me:$LINENO: checking for getpwnam_r with 4 args" >&5 +echo $ECHO_N "checking for getpwnam_r with 4 args... $ECHO_C" >&6 +if test "${tcl_cv_api_getpwnam_r_4+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ -#include -#include -#include + + #include + #include int main () { -if ((struct tm *) 0) -return 0; + + char *name; + struct passwd pw; + char buf[512]; + int buflen = 512; + + (void)getpwnam_r(name, &pw, buf, buflen); + ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_header_time=yes +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + tcl_cv_api_getpwnam_r_4=yes else - ac_cv_header_time=no + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +tcl_cv_api_getpwnam_r_4=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_time" >&5 -$as_echo "$ac_cv_header_time" >&6; } -if test $ac_cv_header_time = yes; then - -$as_echo "#define TIME_WITH_SYS_TIME 1" >>confdefs.h +echo "$as_me:$LINENO: result: $tcl_cv_api_getpwnam_r_4" >&5 +echo "${ECHO_T}$tcl_cv_api_getpwnam_r_4" >&6 + tcl_ok=$tcl_cv_api_getpwnam_r_4 + if test "$tcl_ok" = yes; then -fi +cat >>confdefs.h <<\_ACEOF +#define HAVE_GETPWNAM_R_4 1 +_ACEOF + fi + fi + if test "$tcl_ok" = yes; then - for ac_func in gmtime_r localtime_r mktime -do : - as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` -ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" -if eval test \"x\$"$as_ac_var"\" = x"yes"; then : - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +cat >>confdefs.h <<\_ACEOF +#define HAVE_GETPWNAM_R 1 _ACEOF -fi -done + fi +fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking tm_tzadj in struct tm" >&5 -$as_echo_n "checking tm_tzadj in struct tm... " >&6; } -if ${tcl_cv_member_tm_tzadj+:} false; then : - $as_echo_n "(cached) " >&6 + echo "$as_me:$LINENO: checking for getgrgid_r" >&5 +echo $ECHO_N "checking for getgrgid_r... $ECHO_C" >&6 +if test "${ac_cv_func_getgrgid_r+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 else - - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -int -main () -{ -struct tm tm; tm.tm_tzadj; - ; - return 0; -} + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - tcl_cv_member_tm_tzadj=yes -else - tcl_cv_member_tm_tzadj=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_member_tm_tzadj" >&5 -$as_echo "$tcl_cv_member_tm_tzadj" >&6; } - if test $tcl_cv_member_tm_tzadj = yes ; then +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define getgrgid_r to an innocuous variant, in case declares getgrgid_r. + For example, HP-UX 11i declares gettimeofday. */ +#define getgrgid_r innocuous_getgrgid_r -$as_echo "#define HAVE_TM_TZADJ 1" >>confdefs.h +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char getgrgid_r (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ - fi +#ifdef __STDC__ +# include +#else +# include +#endif - { $as_echo "$as_me:${as_lineno-$LINENO}: checking tm_gmtoff in struct tm" >&5 -$as_echo_n "checking tm_gmtoff in struct tm... " >&6; } -if ${tcl_cv_member_tm_gmtoff+:} false; then : - $as_echo_n "(cached) " >&6 -else +#undef getgrgid_r + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char getgrgid_r (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_getgrgid_r) || defined (__stub___getgrgid_r) +choke me +#else +char (*f) () = getgrgid_r; +#endif +#ifdef __cplusplus +} +#endif - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include int main () { -struct tm tm; tm.tm_gmtoff; +return f != getgrgid_r; ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - tcl_cv_member_tm_gmtoff=yes +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_getgrgid_r=yes else - tcl_cv_member_tm_gmtoff=no + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_func_getgrgid_r=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_member_tm_gmtoff" >&5 -$as_echo "$tcl_cv_member_tm_gmtoff" >&6; } - if test $tcl_cv_member_tm_gmtoff = yes ; then - -$as_echo "#define HAVE_TM_GMTOFF 1" >>confdefs.h +echo "$as_me:$LINENO: result: $ac_cv_func_getgrgid_r" >&5 +echo "${ECHO_T}$ac_cv_func_getgrgid_r" >&6 +if test $ac_cv_func_getgrgid_r = yes; then - fi - - # - # Its important to include time.h in this check, as some systems - # (like convex) have timezone functions, etc. - # - { $as_echo "$as_me:${as_lineno-$LINENO}: checking long timezone variable" >&5 -$as_echo_n "checking long timezone variable... " >&6; } -if ${tcl_cv_timezone_long+:} false; then : - $as_echo_n "(cached) " >&6 + echo "$as_me:$LINENO: checking for getgrgid_r with 5 args" >&5 +echo $ECHO_N "checking for getgrgid_r with 5 args... $ECHO_C" >&6 +if test "${tcl_cv_api_getgrgid_r_5+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ -#include + + #include + #include + int main () { -extern long timezone; - timezone += 1; - exit (0); + + gid_t gid; + struct group gr, *grp; + char buf[512]; + int buflen = 512; + + (void) getgrgid_r(gid, &gr, buf, buflen, &grp); + ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - tcl_cv_timezone_long=yes +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + tcl_cv_api_getgrgid_r_5=yes else - tcl_cv_timezone_long=no + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +tcl_cv_api_getgrgid_r_5=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_timezone_long" >&5 -$as_echo "$tcl_cv_timezone_long" >&6; } - if test $tcl_cv_timezone_long = yes ; then +echo "$as_me:$LINENO: result: $tcl_cv_api_getgrgid_r_5" >&5 +echo "${ECHO_T}$tcl_cv_api_getgrgid_r_5" >&6 + tcl_ok=$tcl_cv_api_getgrgid_r_5 + if test "$tcl_ok" = yes; then -$as_echo "#define HAVE_TIMEZONE_VAR 1" >>confdefs.h +cat >>confdefs.h <<\_ACEOF +#define HAVE_GETGRGID_R_5 1 +_ACEOF else - # - # On some systems (eg IRIX 6.2), timezone is a time_t and not a long. - # - { $as_echo "$as_me:${as_lineno-$LINENO}: checking time_t timezone variable" >&5 -$as_echo_n "checking time_t timezone variable... " >&6; } -if ${tcl_cv_timezone_time+:} false; then : - $as_echo_n "(cached) " >&6 + echo "$as_me:$LINENO: checking for getgrgid_r with 4 args" >&5 +echo $ECHO_N "checking for getgrgid_r with 4 args... $ECHO_C" >&6 +if test "${tcl_cv_api_getgrgid_r_4+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ -#include + + #include + #include + int main () { -extern time_t timezone; - timezone += 1; - exit (0); + + gid_t gid; + struct group gr; + char buf[512]; + int buflen = 512; + + (void)getgrgid_r(gid, &gr, buf, buflen); + ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - tcl_cv_timezone_time=yes +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + tcl_cv_api_getgrgid_r_4=yes else - tcl_cv_timezone_time=no + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +tcl_cv_api_getgrgid_r_4=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_timezone_time" >&5 -$as_echo "$tcl_cv_timezone_time" >&6; } - if test $tcl_cv_timezone_time = yes ; then +echo "$as_me:$LINENO: result: $tcl_cv_api_getgrgid_r_4" >&5 +echo "${ECHO_T}$tcl_cv_api_getgrgid_r_4" >&6 + tcl_ok=$tcl_cv_api_getgrgid_r_4 + if test "$tcl_ok" = yes; then -$as_echo "#define HAVE_TIMEZONE_VAR 1" >>confdefs.h +cat >>confdefs.h <<\_ACEOF +#define HAVE_GETGRGID_R_4 1 +_ACEOF fi fi + if test "$tcl_ok" = yes; then - -#-------------------------------------------------------------------- -# Some systems (e.g., IRIX 4.0.5) lack some fields in struct stat. But -# we might be able to use fstatfs instead. Some systems (OpenBSD?) also -# lack blkcnt_t. -#-------------------------------------------------------------------- - -if test "$ac_cv_cygwin" != "yes"; then - ac_fn_c_check_member "$LINENO" "struct stat" "st_blocks" "ac_cv_member_struct_stat_st_blocks" "$ac_includes_default" -if test "x$ac_cv_member_struct_stat_st_blocks" = xyes; then : - -cat >>confdefs.h <<_ACEOF -#define HAVE_STRUCT_STAT_ST_BLOCKS 1 +cat >>confdefs.h <<\_ACEOF +#define HAVE_GETGRGID_R 1 _ACEOF + fi fi -ac_fn_c_check_member "$LINENO" "struct stat" "st_blksize" "ac_cv_member_struct_stat_st_blksize" "$ac_includes_default" -if test "x$ac_cv_member_struct_stat_st_blksize" = xyes; then : -cat >>confdefs.h <<_ACEOF -#define HAVE_STRUCT_STAT_ST_BLKSIZE 1 + echo "$as_me:$LINENO: checking for getgrnam_r" >&5 +echo $ECHO_N "checking for getgrnam_r... $ECHO_C" >&6 +if test "${ac_cv_func_getgrnam_r+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ _ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define getgrnam_r to an innocuous variant, in case declares getgrnam_r. + For example, HP-UX 11i declares gettimeofday. */ +#define getgrnam_r innocuous_getgrnam_r +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char getgrnam_r (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ -fi +#ifdef __STDC__ +# include +#else +# include +#endif -fi -ac_fn_c_check_type "$LINENO" "blkcnt_t" "ac_cv_type_blkcnt_t" "$ac_includes_default" -if test "x$ac_cv_type_blkcnt_t" = xyes; then : +#undef getgrnam_r -cat >>confdefs.h <<_ACEOF -#define HAVE_BLKCNT_T 1 -_ACEOF +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char getgrnam_r (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_getgrnam_r) || defined (__stub___getgrnam_r) +choke me +#else +char (*f) () = getgrnam_r; +#endif +#ifdef __cplusplus +} +#endif +int +main () +{ +return f != getgrnam_r; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_getgrnam_r=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 +ac_cv_func_getgrnam_r=no fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_func_getgrnam_r" >&5 +echo "${ECHO_T}$ac_cv_func_getgrnam_r" >&6 +if test $ac_cv_func_getgrnam_r = yes; then -ac_fn_c_check_func "$LINENO" "fstatfs" "ac_cv_func_fstatfs" -if test "x$ac_cv_func_fstatfs" = xyes; then : - + echo "$as_me:$LINENO: checking for getgrnam_r with 5 args" >&5 +echo $ECHO_N "checking for getgrnam_r with 5 args... $ECHO_C" >&6 +if test "${tcl_cv_api_getgrnam_r_5+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 else -$as_echo "#define NO_FSTATFS 1" >>confdefs.h - -fi + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + #include + #include -#-------------------------------------------------------------------- -# Some system have no memcmp or it does not work with 8 bit data, this -# checks it and add memcmp.o to LIBOBJS if needed -#-------------------------------------------------------------------- +int +main () +{ + + char *name; + struct group gr, *grp; + char buf[512]; + int buflen = 512; + + (void) getgrnam_r(name, &gr, buf, buflen, &grp); -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working memcmp" >&5 -$as_echo_n "checking for working memcmp... " >&6; } -if ${ac_cv_func_memcmp_working+:} false; then : - $as_echo_n "(cached) " >&6 + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + tcl_cv_api_getgrnam_r_5=yes else - if test "$cross_compiling" = yes; then : - ac_cv_func_memcmp_working=no + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +tcl_cv_api_getgrnam_r_5=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $tcl_cv_api_getgrnam_r_5" >&5 +echo "${ECHO_T}$tcl_cv_api_getgrnam_r_5" >&6 + tcl_ok=$tcl_cv_api_getgrnam_r_5 + if test "$tcl_ok" = yes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_GETGRNAM_R_5 1 +_ACEOF + + else + echo "$as_me:$LINENO: checking for getgrnam_r with 4 args" >&5 +echo $ECHO_N "checking for getgrnam_r with 4 args... $ECHO_C" >&6 +if test "${tcl_cv_api_getgrnam_r_4+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ -$ac_includes_default + + #include + #include + int main () { - /* Some versions of memcmp are not 8-bit clean. */ - char c0 = '\100', c1 = '\200', c2 = '\201'; - if (memcmp(&c0, &c2, 1) >= 0 || memcmp(&c1, &c2, 1) >= 0) - return 1; + char *name; + struct group gr; + char buf[512]; + int buflen = 512; - /* The Next x86 OpenStep bug shows up only when comparing 16 bytes - or more and with at least one buffer not starting on a 4-byte boundary. - William Lewis provided this test program. */ - { - char foo[21]; - char bar[21]; - int i; - for (i = 0; i < 4; i++) - { - char *a = foo + i; - char *b = bar + i; - strcpy (a, "--------01111111"); - strcpy (b, "--------10000000"); - if (memcmp (a, b, 16) >= 0) - return 1; - } - return 0; - } + (void)getgrnam_r(name, &gr, buf, buflen); ; return 0; } _ACEOF -if ac_fn_c_try_run "$LINENO"; then : - ac_cv_func_memcmp_working=yes +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + tcl_cv_api_getgrnam_r_4=yes else - ac_cv_func_memcmp_working=no + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +tcl_cv_api_getgrnam_r_4=no fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi +echo "$as_me:$LINENO: result: $tcl_cv_api_getgrnam_r_4" >&5 +echo "${ECHO_T}$tcl_cv_api_getgrnam_r_4" >&6 + tcl_ok=$tcl_cv_api_getgrnam_r_4 + if test "$tcl_ok" = yes; then -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_memcmp_working" >&5 -$as_echo "$ac_cv_func_memcmp_working" >&6; } -test $ac_cv_func_memcmp_working = no && case " $LIBOBJS " in - *" memcmp.$ac_objext "* ) ;; - *) LIBOBJS="$LIBOBJS memcmp.$ac_objext" - ;; -esac +cat >>confdefs.h <<\_ACEOF +#define HAVE_GETGRNAM_R_4 1 +_ACEOF + fi + fi + if test "$tcl_ok" = yes; then +cat >>confdefs.h <<\_ACEOF +#define HAVE_GETGRNAM_R 1 +_ACEOF -#-------------------------------------------------------------------- -# Some system like SunOS 4 and other BSD like systems have no memmove -# (we assume they have bcopy instead). {The replacement define is in -# compat/string.h} -#-------------------------------------------------------------------- + fi -ac_fn_c_check_func "$LINENO" "memmove" "ac_cv_func_memmove" -if test "x$ac_cv_func_memmove" = xyes; then : +fi -else + if test "`uname -s`" = "Darwin" && \ + test "`uname -r | awk -F. '{print $1}'`" -gt 5; then + # Starting with Darwin 6 (Mac OSX 10.2), gethostbyX + # are actually MT-safe as they always return pointers + # from TSD instead of static storage. +cat >>confdefs.h <<\_ACEOF +#define HAVE_MTSAFE_GETHOSTBYNAME 1 +_ACEOF -$as_echo "#define NO_MEMMOVE 1" >>confdefs.h +cat >>confdefs.h <<\_ACEOF +#define HAVE_MTSAFE_GETHOSTBYADDR 1 +_ACEOF -$as_echo "#define NO_STRING_H 1" >>confdefs.h -fi + elif test "`uname -s`" = "HP-UX" && \ + test "`uname -r|sed -e 's|B\.||' -e 's|\..*$||'`" -gt 10; then + # Starting with HPUX 11.00 (we believe), gethostbyX + # are actually MT-safe as they always return pointers + # from TSD instead of static storage. +cat >>confdefs.h <<\_ACEOF +#define HAVE_MTSAFE_GETHOSTBYNAME 1 +_ACEOF -#-------------------------------------------------------------------- -# On some systems strstr is broken: it returns a pointer even even if -# the original string is empty. -#-------------------------------------------------------------------- +cat >>confdefs.h <<\_ACEOF +#define HAVE_MTSAFE_GETHOSTBYADDR 1 +_ACEOF - ac_fn_c_check_func "$LINENO" "strstr" "ac_cv_func_strstr" -if test "x$ac_cv_func_strstr" = xyes; then : - tcl_ok=1 -else - tcl_ok=0 -fi - if test "$tcl_ok" = 1; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking proper strstr implementation" >&5 -$as_echo_n "checking proper strstr implementation... " >&6; } -if ${tcl_cv_strstr_unbroken+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test "$cross_compiling" = yes; then : - tcl_cv_strstr_unbroken=unknown + else + echo "$as_me:$LINENO: checking for gethostbyname_r" >&5 +echo $ECHO_N "checking for gethostbyname_r... $ECHO_C" >&6 +if test "${ac_cv_func_gethostbyname_r+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ -int main() { - extern int strstr(); - exit(strstr("\0test", "test") ? 1 : 0); +/* Define gethostbyname_r to an innocuous variant, in case declares gethostbyname_r. + For example, HP-UX 11i declares gettimeofday. */ +#define gethostbyname_r innocuous_gethostbyname_r + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char gethostbyname_r (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef gethostbyname_r + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char gethostbyname_r (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_gethostbyname_r) || defined (__stub___gethostbyname_r) +choke me +#else +char (*f) () = gethostbyname_r; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != gethostbyname_r; + ; + return 0; } _ACEOF -if ac_fn_c_try_run "$LINENO"; then : - tcl_cv_strstr_unbroken=ok +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_gethostbyname_r=yes else - tcl_cv_strstr_unbroken=broken + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_func_gethostbyname_r=no fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext fi +echo "$as_me:$LINENO: result: $ac_cv_func_gethostbyname_r" >&5 +echo "${ECHO_T}$ac_cv_func_gethostbyname_r" >&6 +if test $ac_cv_func_gethostbyname_r = yes; then -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_strstr_unbroken" >&5 -$as_echo "$tcl_cv_strstr_unbroken" >&6; } - if test "$tcl_cv_strstr_unbroken" = "ok"; then - tcl_ok=1 - else - tcl_ok=0 - fi - fi - if test "$tcl_ok" = 0; then - case " $LIBOBJS " in - *" strstr.$ac_objext "* ) ;; - *) LIBOBJS="$LIBOBJS strstr.$ac_objext" - ;; -esac + echo "$as_me:$LINENO: checking for gethostbyname_r with 6 args" >&5 +echo $ECHO_N "checking for gethostbyname_r with 6 args... $ECHO_C" >&6 +if test "${tcl_cv_api_gethostbyname_r_6+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else - USE_COMPAT=1 - fi + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + #include -#-------------------------------------------------------------------- -# Check for strtoul function. This is tricky because under some -# versions of AIX strtoul returns an incorrect terminator -# pointer for the string "0". -#-------------------------------------------------------------------- +int +main () +{ + char *name; + struct hostent *he, *res; + char buffer[2048]; + int buflen = 2048; + int h_errnop; - ac_fn_c_check_func "$LINENO" "strtoul" "ac_cv_func_strtoul" -if test "x$ac_cv_func_strtoul" = xyes; then : - tcl_ok=1 -else - tcl_ok=0 -fi + (void) gethostbyname_r(name, he, buffer, buflen, &res, &h_errnop); - if test "$tcl_ok" = 1; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking proper strtoul implementation" >&5 -$as_echo_n "checking proper strtoul implementation... " >&6; } -if ${tcl_cv_strtoul_unbroken+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test "$cross_compiling" = yes; then : - tcl_cv_strtoul_unbroken=unknown -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -int main() { - extern int strtoul(); - char *term, *string = "0"; - exit(strtoul(string,&term,0) != 0 || term != string+1); + ; + return 0; } _ACEOF -if ac_fn_c_try_run "$LINENO"; then : - tcl_cv_strtoul_unbroken=ok +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + tcl_cv_api_gethostbyname_r_6=yes else - tcl_cv_strtoul_unbroken=broken + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +tcl_cv_api_gethostbyname_r_6=no fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi +echo "$as_me:$LINENO: result: $tcl_cv_api_gethostbyname_r_6" >&5 +echo "${ECHO_T}$tcl_cv_api_gethostbyname_r_6" >&6 + tcl_ok=$tcl_cv_api_gethostbyname_r_6 + if test "$tcl_ok" = yes; then -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_strtoul_unbroken" >&5 -$as_echo "$tcl_cv_strtoul_unbroken" >&6; } - if test "$tcl_cv_strtoul_unbroken" = "ok"; then - tcl_ok=1 - else - tcl_ok=0 - fi - fi - if test "$tcl_ok" = 0; then - case " $LIBOBJS " in - *" strtoul.$ac_objext "* ) ;; - *) LIBOBJS="$LIBOBJS strtoul.$ac_objext" - ;; -esac +cat >>confdefs.h <<\_ACEOF +#define HAVE_GETHOSTBYNAME_R_6 1 +_ACEOF - USE_COMPAT=1 - fi + else + echo "$as_me:$LINENO: checking for gethostbyname_r with 5 args" >&5 +echo $ECHO_N "checking for gethostbyname_r with 5 args... $ECHO_C" >&6 +if test "${tcl_cv_api_gethostbyname_r_5+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ -#-------------------------------------------------------------------- -# Check for the strtod function. This is tricky because in some -# versions of Linux strtod mis-parses strings starting with "+". -#-------------------------------------------------------------------- + #include +int +main () +{ - ac_fn_c_check_func "$LINENO" "strtod" "ac_cv_func_strtod" -if test "x$ac_cv_func_strtod" = xyes; then : - tcl_ok=1 -else - tcl_ok=0 -fi + char *name; + struct hostent *he; + char buffer[2048]; + int buflen = 2048; + int h_errnop; - if test "$tcl_ok" = 1; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking proper strtod implementation" >&5 -$as_echo_n "checking proper strtod implementation... " >&6; } -if ${tcl_cv_strtod_unbroken+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test "$cross_compiling" = yes; then : - tcl_cv_strtod_unbroken=unknown -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + (void) gethostbyname_r(name, he, buffer, buflen, &h_errnop); + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + tcl_cv_api_gethostbyname_r_5=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +tcl_cv_api_gethostbyname_r_5=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $tcl_cv_api_gethostbyname_r_5" >&5 +echo "${ECHO_T}$tcl_cv_api_gethostbyname_r_5" >&6 + tcl_ok=$tcl_cv_api_gethostbyname_r_5 + if test "$tcl_ok" = yes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_GETHOSTBYNAME_R_5 1 +_ACEOF + + else + echo "$as_me:$LINENO: checking for gethostbyname_r with 3 args" >&5 +echo $ECHO_N "checking for gethostbyname_r with 3 args... $ECHO_C" >&6 +if test "${tcl_cv_api_gethostbyname_r_3+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ -int main() { - extern double strtod(); - char *term, *string = " +69"; - exit(strtod(string,&term) != 69 || term != string+4); + + #include + +int +main () +{ + + char *name; + struct hostent *he; + struct hostent_data data; + + (void) gethostbyname_r(name, he, &data); + + ; + return 0; } _ACEOF -if ac_fn_c_try_run "$LINENO"; then : - tcl_cv_strtod_unbroken=ok +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + tcl_cv_api_gethostbyname_r_3=yes else - tcl_cv_strtod_unbroken=broken + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +tcl_cv_api_gethostbyname_r_3=no fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi +echo "$as_me:$LINENO: result: $tcl_cv_api_gethostbyname_r_3" >&5 +echo "${ECHO_T}$tcl_cv_api_gethostbyname_r_3" >&6 + tcl_ok=$tcl_cv_api_gethostbyname_r_3 + if test "$tcl_ok" = yes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_GETHOSTBYNAME_R_3 1 +_ACEOF + + fi + fi + fi + if test "$tcl_ok" = yes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_GETHOSTBYNAME_R 1 +_ACEOF + + fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_strtod_unbroken" >&5 -$as_echo "$tcl_cv_strtod_unbroken" >&6; } - if test "$tcl_cv_strtod_unbroken" = "ok"; then - tcl_ok=1 - else - tcl_ok=0 + + echo "$as_me:$LINENO: checking for gethostbyaddr_r" >&5 +echo $ECHO_N "checking for gethostbyaddr_r... $ECHO_C" >&6 +if test "${ac_cv_func_gethostbyaddr_r+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define gethostbyaddr_r to an innocuous variant, in case declares gethostbyaddr_r. + For example, HP-UX 11i declares gettimeofday. */ +#define gethostbyaddr_r innocuous_gethostbyaddr_r + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char gethostbyaddr_r (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef gethostbyaddr_r + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char gethostbyaddr_r (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_gethostbyaddr_r) || defined (__stub___gethostbyaddr_r) +choke me +#else +char (*f) () = gethostbyaddr_r; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != gethostbyaddr_r; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_gethostbyaddr_r=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_func_gethostbyaddr_r=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_func_gethostbyaddr_r" >&5 +echo "${ECHO_T}$ac_cv_func_gethostbyaddr_r" >&6 +if test $ac_cv_func_gethostbyaddr_r = yes; then + + echo "$as_me:$LINENO: checking for gethostbyaddr_r with 7 args" >&5 +echo $ECHO_N "checking for gethostbyaddr_r with 7 args... $ECHO_C" >&6 +if test "${tcl_cv_api_gethostbyaddr_r_7+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + + #include + +int +main () +{ + + char *addr; + int length; + int type; + struct hostent *result; + char buffer[2048]; + int buflen = 2048; + int h_errnop; + + (void) gethostbyaddr_r(addr, length, type, result, buffer, buflen, + &h_errnop); + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + tcl_cv_api_gethostbyaddr_r_7=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +tcl_cv_api_gethostbyaddr_r_7=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $tcl_cv_api_gethostbyaddr_r_7" >&5 +echo "${ECHO_T}$tcl_cv_api_gethostbyaddr_r_7" >&6 + tcl_ok=$tcl_cv_api_gethostbyaddr_r_7 + if test "$tcl_ok" = yes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_GETHOSTBYADDR_R_7 1 +_ACEOF + + else + echo "$as_me:$LINENO: checking for gethostbyaddr_r with 8 args" >&5 +echo $ECHO_N "checking for gethostbyaddr_r with 8 args... $ECHO_C" >&6 +if test "${tcl_cv_api_gethostbyaddr_r_8+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + + #include + +int +main () +{ + + char *addr; + int length; + int type; + struct hostent *result, *resultp; + char buffer[2048]; + int buflen = 2048; + int h_errnop; + + (void) gethostbyaddr_r(addr, length, type, result, buffer, buflen, + &resultp, &h_errnop); + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + tcl_cv_api_gethostbyaddr_r_8=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +tcl_cv_api_gethostbyaddr_r_8=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $tcl_cv_api_gethostbyaddr_r_8" >&5 +echo "${ECHO_T}$tcl_cv_api_gethostbyaddr_r_8" >&6 + tcl_ok=$tcl_cv_api_gethostbyaddr_r_8 + if test "$tcl_ok" = yes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_GETHOSTBYADDR_R_8 1 +_ACEOF + fi fi - if test "$tcl_ok" = 0; then - case " $LIBOBJS " in - *" strtod.$ac_objext "* ) ;; - *) LIBOBJS="$LIBOBJS strtod.$ac_objext" - ;; -esac + if test "$tcl_ok" = yes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_GETHOSTBYADDR_R 1 +_ACEOF - USE_COMPAT=1 fi +fi -#-------------------------------------------------------------------- -# Under Solaris 2.4, strtod returns the wrong value for the -# terminating character under some conditions. Check for this -# and if the problem exists use a substitute procedure -# "fixstrtod" that corrects the error. -#-------------------------------------------------------------------- + fi +fi + +#--------------------------------------------------------------------------- +# Check for serial port interface. +# +# termios.h is present on all POSIX systems. +# sys/ioctl.h is almost always present, though what it contains +# is system-specific. +# sys/modem.h is needed on HP-UX. +#--------------------------------------------------------------------------- - ac_fn_c_check_func "$LINENO" "strtod" "ac_cv_func_strtod" -if test "x$ac_cv_func_strtod" = xyes; then : - tcl_strtod=1 +for ac_header in termios.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 else - tcl_strtod=0 + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +## ------------------------------ ## +## Report this to the tcl lists. ## +## ------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +for ac_header in sys/ioctl.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +## ------------------------------ ## +## Report this to the tcl lists. ## +## ------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +for ac_header in sys/modem.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +## ------------------------------ ## +## Report this to the tcl lists. ## +## ------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +#-------------------------------------------------------------------- +# Include sys/select.h if it exists and if it supplies things +# that appear to be useful and aren't already in sys/types.h. +# This appears to be true only on the RS/6000 under AIX. Some +# systems like OSF/1 have a sys/select.h that's of no use, and +# other systems like SCO UNIX have a sys/select.h that's +# pernicious. If "fd_set" isn't defined anywhere then set a +# special flag. +#-------------------------------------------------------------------- + +echo "$as_me:$LINENO: checking for fd_set in sys/types" >&5 +echo $ECHO_N "checking for fd_set in sys/types... $ECHO_C" >&6 +if test "${tcl_cv_type_fd_set+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +int +main () +{ +fd_set readMask, writeMask; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + tcl_cv_type_fd_set=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +tcl_cv_type_fd_set=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $tcl_cv_type_fd_set" >&5 +echo "${ECHO_T}$tcl_cv_type_fd_set" >&6 +tcl_ok=$tcl_cv_type_fd_set +if test $tcl_ok = no; then + echo "$as_me:$LINENO: checking for fd_mask in sys/select" >&5 +echo $ECHO_N "checking for fd_mask in sys/select... $ECHO_C" >&6 +if test "${tcl_cv_grep_fd_mask+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "fd_mask" >/dev/null 2>&1; then + tcl_cv_grep_fd_mask=present +else + tcl_cv_grep_fd_mask=missing +fi +rm -f conftest* + +fi +echo "$as_me:$LINENO: result: $tcl_cv_grep_fd_mask" >&5 +echo "${ECHO_T}$tcl_cv_grep_fd_mask" >&6 + if test $tcl_cv_grep_fd_mask = present; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_SYS_SELECT_H 1 +_ACEOF + + tcl_ok=yes + fi +fi +if test $tcl_ok = no; then + +cat >>confdefs.h <<\_ACEOF +#define NO_FD_SET 1 +_ACEOF + +fi + +#------------------------------------------------------------------------------ +# Find out all about time handling differences. +#------------------------------------------------------------------------------ + + + +for ac_header in sys/time.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +## ------------------------------ ## +## Report this to the tcl lists. ## +## ------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + echo "$as_me:$LINENO: checking whether time.h and sys/time.h may both be included" >&5 +echo $ECHO_N "checking whether time.h and sys/time.h may both be included... $ECHO_C" >&6 +if test "${ac_cv_header_time+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include + +int +main () +{ +if ((struct tm *) 0) +return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_header_time=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_header_time=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_header_time" >&5 +echo "${ECHO_T}$ac_cv_header_time" >&6 +if test $ac_cv_header_time = yes; then + +cat >>confdefs.h <<\_ACEOF +#define TIME_WITH_SYS_TIME 1 +_ACEOF + +fi + + + + + +for ac_func in gmtime_r localtime_r mktime +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 +if eval "test \"\${$as_ac_var+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case declares $ac_func. + For example, HP-UX 11i declares gettimeofday. */ +#define $ac_func innocuous_$ac_func + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $ac_func + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +char (*f) () = $ac_func; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != $ac_func; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +eval "$as_ac_var=no" +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + + echo "$as_me:$LINENO: checking tm_tzadj in struct tm" >&5 +echo $ECHO_N "checking tm_tzadj in struct tm... $ECHO_C" >&6 +if test "${tcl_cv_member_tm_tzadj+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +int +main () +{ +struct tm tm; tm.tm_tzadj; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + tcl_cv_member_tm_tzadj=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +tcl_cv_member_tm_tzadj=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $tcl_cv_member_tm_tzadj" >&5 +echo "${ECHO_T}$tcl_cv_member_tm_tzadj" >&6 + if test $tcl_cv_member_tm_tzadj = yes ; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_TM_TZADJ 1 +_ACEOF + + fi + + echo "$as_me:$LINENO: checking tm_gmtoff in struct tm" >&5 +echo $ECHO_N "checking tm_gmtoff in struct tm... $ECHO_C" >&6 +if test "${tcl_cv_member_tm_gmtoff+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +int +main () +{ +struct tm tm; tm.tm_gmtoff; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + tcl_cv_member_tm_gmtoff=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +tcl_cv_member_tm_gmtoff=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $tcl_cv_member_tm_gmtoff" >&5 +echo "${ECHO_T}$tcl_cv_member_tm_gmtoff" >&6 + if test $tcl_cv_member_tm_gmtoff = yes ; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_TM_GMTOFF 1 +_ACEOF + + fi + + # + # Its important to include time.h in this check, as some systems + # (like convex) have timezone functions, etc. + # + echo "$as_me:$LINENO: checking long timezone variable" >&5 +echo $ECHO_N "checking long timezone variable... $ECHO_C" >&6 +if test "${tcl_cv_timezone_long+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +int +main () +{ +extern long timezone; + timezone += 1; + exit (0); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + tcl_cv_timezone_long=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +tcl_cv_timezone_long=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $tcl_cv_timezone_long" >&5 +echo "${ECHO_T}$tcl_cv_timezone_long" >&6 + if test $tcl_cv_timezone_long = yes ; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_TIMEZONE_VAR 1 +_ACEOF + + else + # + # On some systems (eg IRIX 6.2), timezone is a time_t and not a long. + # + echo "$as_me:$LINENO: checking time_t timezone variable" >&5 +echo $ECHO_N "checking time_t timezone variable... $ECHO_C" >&6 +if test "${tcl_cv_timezone_time+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +int +main () +{ +extern time_t timezone; + timezone += 1; + exit (0); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + tcl_cv_timezone_time=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +tcl_cv_timezone_time=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $tcl_cv_timezone_time" >&5 +echo "${ECHO_T}$tcl_cv_timezone_time" >&6 + if test $tcl_cv_timezone_time = yes ; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_TIMEZONE_VAR 1 +_ACEOF + + fi + fi + + +#-------------------------------------------------------------------- +# Some systems (e.g., IRIX 4.0.5) lack some fields in struct stat. But +# we might be able to use fstatfs instead. Some systems (OpenBSD?) also +# lack blkcnt_t. +#-------------------------------------------------------------------- + +if test "$ac_cv_cygwin" != "yes"; then + echo "$as_me:$LINENO: checking for struct stat.st_blocks" >&5 +echo $ECHO_N "checking for struct stat.st_blocks... $ECHO_C" >&6 +if test "${ac_cv_member_struct_stat_st_blocks+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +static struct stat ac_aggr; +if (ac_aggr.st_blocks) +return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_member_struct_stat_st_blocks=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +static struct stat ac_aggr; +if (sizeof ac_aggr.st_blocks) +return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_member_struct_stat_st_blocks=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_member_struct_stat_st_blocks=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_member_struct_stat_st_blocks" >&5 +echo "${ECHO_T}$ac_cv_member_struct_stat_st_blocks" >&6 +if test $ac_cv_member_struct_stat_st_blocks = yes; then + +cat >>confdefs.h <<_ACEOF +#define HAVE_STRUCT_STAT_ST_BLOCKS 1 +_ACEOF + + +fi +echo "$as_me:$LINENO: checking for struct stat.st_blksize" >&5 +echo $ECHO_N "checking for struct stat.st_blksize... $ECHO_C" >&6 +if test "${ac_cv_member_struct_stat_st_blksize+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +static struct stat ac_aggr; +if (ac_aggr.st_blksize) +return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_member_struct_stat_st_blksize=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +static struct stat ac_aggr; +if (sizeof ac_aggr.st_blksize) +return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_member_struct_stat_st_blksize=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_member_struct_stat_st_blksize=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_member_struct_stat_st_blksize" >&5 +echo "${ECHO_T}$ac_cv_member_struct_stat_st_blksize" >&6 +if test $ac_cv_member_struct_stat_st_blksize = yes; then + +cat >>confdefs.h <<_ACEOF +#define HAVE_STRUCT_STAT_ST_BLKSIZE 1 +_ACEOF + + +fi + +fi +echo "$as_me:$LINENO: checking for blkcnt_t" >&5 +echo $ECHO_N "checking for blkcnt_t... $ECHO_C" >&6 +if test "${ac_cv_type_blkcnt_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +if ((blkcnt_t *) 0) + return 0; +if (sizeof (blkcnt_t)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_type_blkcnt_t=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_type_blkcnt_t=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_type_blkcnt_t" >&5 +echo "${ECHO_T}$ac_cv_type_blkcnt_t" >&6 +if test $ac_cv_type_blkcnt_t = yes; then + +cat >>confdefs.h <<_ACEOF +#define HAVE_BLKCNT_T 1 +_ACEOF + + +fi + +echo "$as_me:$LINENO: checking for fstatfs" >&5 +echo $ECHO_N "checking for fstatfs... $ECHO_C" >&6 +if test "${ac_cv_func_fstatfs+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define fstatfs to an innocuous variant, in case declares fstatfs. + For example, HP-UX 11i declares gettimeofday. */ +#define fstatfs innocuous_fstatfs + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char fstatfs (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef fstatfs + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char fstatfs (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_fstatfs) || defined (__stub___fstatfs) +choke me +#else +char (*f) () = fstatfs; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != fstatfs; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_fstatfs=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_func_fstatfs=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_func_fstatfs" >&5 +echo "${ECHO_T}$ac_cv_func_fstatfs" >&6 +if test $ac_cv_func_fstatfs = yes; then + : +else + +cat >>confdefs.h <<\_ACEOF +#define NO_FSTATFS 1 +_ACEOF + +fi + + +#-------------------------------------------------------------------- +# Some system have no memcmp or it does not work with 8 bit data, this +# checks it and add memcmp.o to LIBOBJS if needed +#-------------------------------------------------------------------- + +echo "$as_me:$LINENO: checking for working memcmp" >&5 +echo $ECHO_N "checking for working memcmp... $ECHO_C" >&6 +if test "${ac_cv_func_memcmp_working+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then + ac_cv_func_memcmp_working=no +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ + + /* Some versions of memcmp are not 8-bit clean. */ + char c0 = 0x40, c1 = 0x80, c2 = 0x81; + if (memcmp(&c0, &c2, 1) >= 0 || memcmp(&c1, &c2, 1) >= 0) + exit (1); + + /* The Next x86 OpenStep bug shows up only when comparing 16 bytes + or more and with at least one buffer not starting on a 4-byte boundary. + William Lewis provided this test program. */ + { + char foo[21]; + char bar[21]; + int i; + for (i = 0; i < 4; i++) + { + char *a = foo + i; + char *b = bar + i; + strcpy (a, "--------01111111"); + strcpy (b, "--------10000000"); + if (memcmp (a, b, 16) >= 0) + exit (1); + } + exit (0); + } + + ; + return 0; +} +_ACEOF +rm -f conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_memcmp_working=yes +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_func_memcmp_working=no +fi +rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +fi +echo "$as_me:$LINENO: result: $ac_cv_func_memcmp_working" >&5 +echo "${ECHO_T}$ac_cv_func_memcmp_working" >&6 +test $ac_cv_func_memcmp_working = no && case $LIBOBJS in + "memcmp.$ac_objext" | \ + *" memcmp.$ac_objext" | \ + "memcmp.$ac_objext "* | \ + *" memcmp.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS memcmp.$ac_objext" ;; +esac + + + +#-------------------------------------------------------------------- +# Some system like SunOS 4 and other BSD like systems have no memmove +# (we assume they have bcopy instead). {The replacement define is in +# compat/string.h} +#-------------------------------------------------------------------- + +echo "$as_me:$LINENO: checking for memmove" >&5 +echo $ECHO_N "checking for memmove... $ECHO_C" >&6 +if test "${ac_cv_func_memmove+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define memmove to an innocuous variant, in case declares memmove. + For example, HP-UX 11i declares gettimeofday. */ +#define memmove innocuous_memmove + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char memmove (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef memmove + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char memmove (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_memmove) || defined (__stub___memmove) +choke me +#else +char (*f) () = memmove; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != memmove; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_memmove=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_func_memmove=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_func_memmove" >&5 +echo "${ECHO_T}$ac_cv_func_memmove" >&6 +if test $ac_cv_func_memmove = yes; then + : +else + + +cat >>confdefs.h <<\_ACEOF +#define NO_MEMMOVE 1 +_ACEOF + + +cat >>confdefs.h <<\_ACEOF +#define NO_STRING_H 1 +_ACEOF + +fi + + +#-------------------------------------------------------------------- +# On some systems strstr is broken: it returns a pointer even even if +# the original string is empty. +#-------------------------------------------------------------------- + + + echo "$as_me:$LINENO: checking for strstr" >&5 +echo $ECHO_N "checking for strstr... $ECHO_C" >&6 +if test "${ac_cv_func_strstr+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define strstr to an innocuous variant, in case declares strstr. + For example, HP-UX 11i declares gettimeofday. */ +#define strstr innocuous_strstr + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char strstr (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef strstr + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char strstr (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_strstr) || defined (__stub___strstr) +choke me +#else +char (*f) () = strstr; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != strstr; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_strstr=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_func_strstr=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_func_strstr" >&5 +echo "${ECHO_T}$ac_cv_func_strstr" >&6 +if test $ac_cv_func_strstr = yes; then + tcl_ok=1 +else + tcl_ok=0 +fi + + if test "$tcl_ok" = 1; then + echo "$as_me:$LINENO: checking proper strstr implementation" >&5 +echo $ECHO_N "checking proper strstr implementation... $ECHO_C" >&6 +if test "${tcl_cv_strstr_unbroken+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then + tcl_cv_strstr_unbroken=unknown +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +int main() { + extern int strstr(); + exit(strstr("\0test", "test") ? 1 : 0); +} +_ACEOF +rm -f conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + tcl_cv_strstr_unbroken=ok +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +tcl_cv_strstr_unbroken=broken +fi +rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +fi +echo "$as_me:$LINENO: result: $tcl_cv_strstr_unbroken" >&5 +echo "${ECHO_T}$tcl_cv_strstr_unbroken" >&6 + if test "$tcl_cv_strstr_unbroken" = "ok"; then + tcl_ok=1 + else + tcl_ok=0 + fi + fi + if test "$tcl_ok" = 0; then + case $LIBOBJS in + "strstr.$ac_objext" | \ + *" strstr.$ac_objext" | \ + "strstr.$ac_objext "* | \ + *" strstr.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS strstr.$ac_objext" ;; +esac + + USE_COMPAT=1 + fi + + +#-------------------------------------------------------------------- +# Check for strtoul function. This is tricky because under some +# versions of AIX strtoul returns an incorrect terminator +# pointer for the string "0". +#-------------------------------------------------------------------- + + + echo "$as_me:$LINENO: checking for strtoul" >&5 +echo $ECHO_N "checking for strtoul... $ECHO_C" >&6 +if test "${ac_cv_func_strtoul+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define strtoul to an innocuous variant, in case declares strtoul. + For example, HP-UX 11i declares gettimeofday. */ +#define strtoul innocuous_strtoul + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char strtoul (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef strtoul + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char strtoul (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_strtoul) || defined (__stub___strtoul) +choke me +#else +char (*f) () = strtoul; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != strtoul; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_strtoul=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_func_strtoul=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_func_strtoul" >&5 +echo "${ECHO_T}$ac_cv_func_strtoul" >&6 +if test $ac_cv_func_strtoul = yes; then + tcl_ok=1 +else + tcl_ok=0 +fi + + if test "$tcl_ok" = 1; then + echo "$as_me:$LINENO: checking proper strtoul implementation" >&5 +echo $ECHO_N "checking proper strtoul implementation... $ECHO_C" >&6 +if test "${tcl_cv_strtoul_unbroken+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then + tcl_cv_strtoul_unbroken=unknown +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +int main() { + extern int strtoul(); + char *term, *string = "0"; + exit(strtoul(string,&term,0) != 0 || term != string+1); +} +_ACEOF +rm -f conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + tcl_cv_strtoul_unbroken=ok +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +tcl_cv_strtoul_unbroken=broken +fi +rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +fi +echo "$as_me:$LINENO: result: $tcl_cv_strtoul_unbroken" >&5 +echo "${ECHO_T}$tcl_cv_strtoul_unbroken" >&6 + if test "$tcl_cv_strtoul_unbroken" = "ok"; then + tcl_ok=1 + else + tcl_ok=0 + fi + fi + if test "$tcl_ok" = 0; then + case $LIBOBJS in + "strtoul.$ac_objext" | \ + *" strtoul.$ac_objext" | \ + "strtoul.$ac_objext "* | \ + *" strtoul.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS strtoul.$ac_objext" ;; +esac + + USE_COMPAT=1 + fi + + +#-------------------------------------------------------------------- +# Check for the strtod function. This is tricky because in some +# versions of Linux strtod mis-parses strings starting with "+". +#-------------------------------------------------------------------- + + + echo "$as_me:$LINENO: checking for strtod" >&5 +echo $ECHO_N "checking for strtod... $ECHO_C" >&6 +if test "${ac_cv_func_strtod+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define strtod to an innocuous variant, in case declares strtod. + For example, HP-UX 11i declares gettimeofday. */ +#define strtod innocuous_strtod + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char strtod (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef strtod + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char strtod (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_strtod) || defined (__stub___strtod) +choke me +#else +char (*f) () = strtod; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != strtod; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_strtod=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_func_strtod=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_func_strtod" >&5 +echo "${ECHO_T}$ac_cv_func_strtod" >&6 +if test $ac_cv_func_strtod = yes; then + tcl_ok=1 +else + tcl_ok=0 +fi + + if test "$tcl_ok" = 1; then + echo "$as_me:$LINENO: checking proper strtod implementation" >&5 +echo $ECHO_N "checking proper strtod implementation... $ECHO_C" >&6 +if test "${tcl_cv_strtod_unbroken+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then + tcl_cv_strtod_unbroken=unknown +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +int main() { + extern double strtod(); + char *term, *string = " +69"; + exit(strtod(string,&term) != 69 || term != string+4); +} +_ACEOF +rm -f conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + tcl_cv_strtod_unbroken=ok +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +tcl_cv_strtod_unbroken=broken +fi +rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +fi +echo "$as_me:$LINENO: result: $tcl_cv_strtod_unbroken" >&5 +echo "${ECHO_T}$tcl_cv_strtod_unbroken" >&6 + if test "$tcl_cv_strtod_unbroken" = "ok"; then + tcl_ok=1 + else + tcl_ok=0 + fi + fi + if test "$tcl_ok" = 0; then + case $LIBOBJS in + "strtod.$ac_objext" | \ + *" strtod.$ac_objext" | \ + "strtod.$ac_objext "* | \ + *" strtod.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS strtod.$ac_objext" ;; +esac + + USE_COMPAT=1 + fi + + +#-------------------------------------------------------------------- +# Under Solaris 2.4, strtod returns the wrong value for the +# terminating character under some conditions. Check for this +# and if the problem exists use a substitute procedure +# "fixstrtod" that corrects the error. +#-------------------------------------------------------------------- + + + echo "$as_me:$LINENO: checking for strtod" >&5 +echo $ECHO_N "checking for strtod... $ECHO_C" >&6 +if test "${ac_cv_func_strtod+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define strtod to an innocuous variant, in case declares strtod. + For example, HP-UX 11i declares gettimeofday. */ +#define strtod innocuous_strtod + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char strtod (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef strtod + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char strtod (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_strtod) || defined (__stub___strtod) +choke me +#else +char (*f) () = strtod; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != strtod; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_strtod=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_func_strtod=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_func_strtod" >&5 +echo "${ECHO_T}$ac_cv_func_strtod" >&6 +if test $ac_cv_func_strtod = yes; then + tcl_strtod=1 +else + tcl_strtod=0 +fi + + if test "$tcl_strtod" = 1; then + echo "$as_me:$LINENO: checking for Solaris2.4/Tru64 strtod bugs" >&5 +echo $ECHO_N "checking for Solaris2.4/Tru64 strtod bugs... $ECHO_C" >&6 +if test "${tcl_cv_strtod_buggy+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + + if test "$cross_compiling" = yes; then + tcl_cv_strtod_buggy=buggy +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + + extern double strtod(); + int main() { + char *infString="Inf", *nanString="NaN", *spaceString=" "; + char *term; + double value; + value = strtod(infString, &term); + if ((term != infString) && (term[-1] == 0)) { + exit(1); + } + value = strtod(nanString, &term); + if ((term != nanString) && (term[-1] == 0)) { + exit(1); + } + value = strtod(spaceString, &term); + if (term == (spaceString+1)) { + exit(1); + } + exit(0); + } +_ACEOF +rm -f conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + tcl_cv_strtod_buggy=ok +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +tcl_cv_strtod_buggy=buggy +fi +rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +fi +echo "$as_me:$LINENO: result: $tcl_cv_strtod_buggy" >&5 +echo "${ECHO_T}$tcl_cv_strtod_buggy" >&6 + if test "$tcl_cv_strtod_buggy" = buggy; then + case $LIBOBJS in + "fixstrtod.$ac_objext" | \ + *" fixstrtod.$ac_objext" | \ + "fixstrtod.$ac_objext "* | \ + *" fixstrtod.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS fixstrtod.$ac_objext" ;; +esac + + USE_COMPAT=1 + +cat >>confdefs.h <<\_ACEOF +#define strtod fixstrtod +_ACEOF + + fi + fi + + +#-------------------------------------------------------------------- +# Check for various typedefs and provide substitutes if +# they don't exist. +#-------------------------------------------------------------------- + +echo "$as_me:$LINENO: checking for mode_t" >&5 +echo $ECHO_N "checking for mode_t... $ECHO_C" >&6 +if test "${ac_cv_type_mode_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +if ((mode_t *) 0) + return 0; +if (sizeof (mode_t)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_type_mode_t=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_type_mode_t=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_type_mode_t" >&5 +echo "${ECHO_T}$ac_cv_type_mode_t" >&6 +if test $ac_cv_type_mode_t = yes; then + : +else + +cat >>confdefs.h <<_ACEOF +#define mode_t int +_ACEOF + +fi + +echo "$as_me:$LINENO: checking for pid_t" >&5 +echo $ECHO_N "checking for pid_t... $ECHO_C" >&6 +if test "${ac_cv_type_pid_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +if ((pid_t *) 0) + return 0; +if (sizeof (pid_t)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_type_pid_t=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_type_pid_t=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_type_pid_t" >&5 +echo "${ECHO_T}$ac_cv_type_pid_t" >&6 +if test $ac_cv_type_pid_t = yes; then + : +else + +cat >>confdefs.h <<_ACEOF +#define pid_t int +_ACEOF + +fi + +echo "$as_me:$LINENO: checking for size_t" >&5 +echo $ECHO_N "checking for size_t... $ECHO_C" >&6 +if test "${ac_cv_type_size_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +if ((size_t *) 0) + return 0; +if (sizeof (size_t)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_type_size_t=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_type_size_t=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_type_size_t" >&5 +echo "${ECHO_T}$ac_cv_type_size_t" >&6 +if test $ac_cv_type_size_t = yes; then + : +else + +cat >>confdefs.h <<_ACEOF +#define size_t unsigned +_ACEOF + +fi + +echo "$as_me:$LINENO: checking for uid_t in sys/types.h" >&5 +echo $ECHO_N "checking for uid_t in sys/types.h... $ECHO_C" >&6 +if test "${ac_cv_type_uid_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "uid_t" >/dev/null 2>&1; then + ac_cv_type_uid_t=yes +else + ac_cv_type_uid_t=no +fi +rm -f conftest* + +fi +echo "$as_me:$LINENO: result: $ac_cv_type_uid_t" >&5 +echo "${ECHO_T}$ac_cv_type_uid_t" >&6 +if test $ac_cv_type_uid_t = no; then + +cat >>confdefs.h <<\_ACEOF +#define uid_t int +_ACEOF + + +cat >>confdefs.h <<\_ACEOF +#define gid_t int +_ACEOF + +fi + + +echo "$as_me:$LINENO: checking for socklen_t" >&5 +echo $ECHO_N "checking for socklen_t... $ECHO_C" >&6 +if test "${tcl_cv_type_socklen_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + + #include + #include + +int +main () +{ + + socklen_t foo; + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + tcl_cv_type_socklen_t=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +tcl_cv_type_socklen_t=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $tcl_cv_type_socklen_t" >&5 +echo "${ECHO_T}$tcl_cv_type_socklen_t" >&6 +if test $tcl_cv_type_socklen_t = no; then + +cat >>confdefs.h <<\_ACEOF +#define socklen_t int +_ACEOF + +fi + +echo "$as_me:$LINENO: checking for intptr_t" >&5 +echo $ECHO_N "checking for intptr_t... $ECHO_C" >&6 +if test "${ac_cv_type_intptr_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +if ((intptr_t *) 0) + return 0; +if (sizeof (intptr_t)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_type_intptr_t=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_type_intptr_t=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_type_intptr_t" >&5 +echo "${ECHO_T}$ac_cv_type_intptr_t" >&6 +if test $ac_cv_type_intptr_t = yes; then + + +cat >>confdefs.h <<\_ACEOF +#define HAVE_INTPTR_T 1 +_ACEOF + +else + + echo "$as_me:$LINENO: checking for pointer-size signed integer type" >&5 +echo $ECHO_N "checking for pointer-size signed integer type... $ECHO_C" >&6 +if test "${tcl_cv_intptr_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + + for tcl_cv_intptr_t in "int" "long" "long long" none; do + if test "$tcl_cv_intptr_t" != none; then + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +static int test_array [1 - 2 * !(sizeof (void *) <= sizeof ($tcl_cv_intptr_t))]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + tcl_ok=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +tcl_ok=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + test "$tcl_ok" = yes && break; fi + done +fi +echo "$as_me:$LINENO: result: $tcl_cv_intptr_t" >&5 +echo "${ECHO_T}$tcl_cv_intptr_t" >&6 + if test "$tcl_cv_intptr_t" != none; then + +cat >>confdefs.h <<_ACEOF +#define intptr_t $tcl_cv_intptr_t +_ACEOF + + fi + +fi + +echo "$as_me:$LINENO: checking for uintptr_t" >&5 +echo $ECHO_N "checking for uintptr_t... $ECHO_C" >&6 +if test "${ac_cv_type_uintptr_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +if ((uintptr_t *) 0) + return 0; +if (sizeof (uintptr_t)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_type_uintptr_t=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_type_uintptr_t=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_type_uintptr_t" >&5 +echo "${ECHO_T}$ac_cv_type_uintptr_t" >&6 +if test $ac_cv_type_uintptr_t = yes; then + + +cat >>confdefs.h <<\_ACEOF +#define HAVE_UINTPTR_T 1 +_ACEOF + +else + + echo "$as_me:$LINENO: checking for pointer-size unsigned integer type" >&5 +echo $ECHO_N "checking for pointer-size unsigned integer type... $ECHO_C" >&6 +if test "${tcl_cv_uintptr_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + + for tcl_cv_uintptr_t in "unsigned int" "unsigned long" "unsigned long long" \ + none; do + if test "$tcl_cv_uintptr_t" != none; then + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +static int test_array [1 - 2 * !(sizeof (void *) <= sizeof ($tcl_cv_uintptr_t))]; +test_array [0] = 0 + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + tcl_ok=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +tcl_ok=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + test "$tcl_ok" = yes && break; fi + done +fi +echo "$as_me:$LINENO: result: $tcl_cv_uintptr_t" >&5 +echo "${ECHO_T}$tcl_cv_uintptr_t" >&6 + if test "$tcl_cv_uintptr_t" != none; then + +cat >>confdefs.h <<_ACEOF +#define uintptr_t $tcl_cv_uintptr_t +_ACEOF + + fi + +fi + + +#-------------------------------------------------------------------- +# If a system doesn't have an opendir function (man, that's old!) +# then we have to supply a different version of dirent.h which +# is compatible with the substitute version of opendir that's +# provided. This version only works with V7-style directories. +#-------------------------------------------------------------------- + +echo "$as_me:$LINENO: checking for opendir" >&5 +echo $ECHO_N "checking for opendir... $ECHO_C" >&6 +if test "${ac_cv_func_opendir+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define opendir to an innocuous variant, in case declares opendir. + For example, HP-UX 11i declares gettimeofday. */ +#define opendir innocuous_opendir + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char opendir (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef opendir + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char opendir (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_opendir) || defined (__stub___opendir) +choke me +#else +char (*f) () = opendir; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != opendir; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_opendir=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_func_opendir=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_func_opendir" >&5 +echo "${ECHO_T}$ac_cv_func_opendir" >&6 +if test $ac_cv_func_opendir = yes; then + : +else + +cat >>confdefs.h <<\_ACEOF +#define USE_DIRENT2_H 1 +_ACEOF + +fi + + +#-------------------------------------------------------------------- +# The check below checks whether defines the type +# "union wait" correctly. It's needed because of weirdness in +# HP-UX where "union wait" is defined in both the BSD and SYS-V +# environments. Checking the usability of WIFEXITED seems to do +# the trick. +#-------------------------------------------------------------------- + +echo "$as_me:$LINENO: checking union wait" >&5 +echo $ECHO_N "checking union wait... $ECHO_C" >&6 +if test "${tcl_cv_union_wait+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +int +main () +{ + +union wait x; +WIFEXITED(x); /* Generates compiler error if WIFEXITED + * uses an int. */ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + tcl_cv_union_wait=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +tcl_cv_union_wait=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $tcl_cv_union_wait" >&5 +echo "${ECHO_T}$tcl_cv_union_wait" >&6 +if test $tcl_cv_union_wait = no; then + +cat >>confdefs.h <<\_ACEOF +#define NO_UNION_WAIT 1 +_ACEOF + +fi + +#-------------------------------------------------------------------- +# Check whether there is an strncasecmp function on this system. +# This is a bit tricky because under SCO it's in -lsocket and +# under Sequent Dynix it's in -linet. +#-------------------------------------------------------------------- + +echo "$as_me:$LINENO: checking for strncasecmp" >&5 +echo $ECHO_N "checking for strncasecmp... $ECHO_C" >&6 +if test "${ac_cv_func_strncasecmp+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define strncasecmp to an innocuous variant, in case declares strncasecmp. + For example, HP-UX 11i declares gettimeofday. */ +#define strncasecmp innocuous_strncasecmp + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char strncasecmp (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef strncasecmp + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char strncasecmp (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_strncasecmp) || defined (__stub___strncasecmp) +choke me +#else +char (*f) () = strncasecmp; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != strncasecmp; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_strncasecmp=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_func_strncasecmp=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_func_strncasecmp" >&5 +echo "${ECHO_T}$ac_cv_func_strncasecmp" >&6 +if test $ac_cv_func_strncasecmp = yes; then + tcl_ok=1 +else + tcl_ok=0 +fi + +if test "$tcl_ok" = 0; then + echo "$as_me:$LINENO: checking for strncasecmp in -lsocket" >&5 +echo $ECHO_N "checking for strncasecmp in -lsocket... $ECHO_C" >&6 +if test "${ac_cv_lib_socket_strncasecmp+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsocket $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char strncasecmp (); +int +main () +{ +strncasecmp (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_socket_strncasecmp=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_socket_strncasecmp=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_socket_strncasecmp" >&5 +echo "${ECHO_T}$ac_cv_lib_socket_strncasecmp" >&6 +if test $ac_cv_lib_socket_strncasecmp = yes; then + tcl_ok=1 +else + tcl_ok=0 +fi + +fi +if test "$tcl_ok" = 0; then + echo "$as_me:$LINENO: checking for strncasecmp in -linet" >&5 +echo $ECHO_N "checking for strncasecmp in -linet... $ECHO_C" >&6 +if test "${ac_cv_lib_inet_strncasecmp+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-linet $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char strncasecmp (); +int +main () +{ +strncasecmp (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_inet_strncasecmp=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_inet_strncasecmp=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_inet_strncasecmp" >&5 +echo "${ECHO_T}$ac_cv_lib_inet_strncasecmp" >&6 +if test $ac_cv_lib_inet_strncasecmp = yes; then + tcl_ok=1 +else + tcl_ok=0 +fi + +fi +if test "$tcl_ok" = 0; then + case $LIBOBJS in + "strncasecmp.$ac_objext" | \ + *" strncasecmp.$ac_objext" | \ + "strncasecmp.$ac_objext "* | \ + *" strncasecmp.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS strncasecmp.$ac_objext" ;; +esac + + USE_COMPAT=1 +fi + +#-------------------------------------------------------------------- +# The code below deals with several issues related to gettimeofday: +# 1. Some systems don't provide a gettimeofday function at all +# (set NO_GETTOD if this is the case). +# 2. See if gettimeofday is declared in the header file. +# if not, set the GETTOD_NOT_DECLARED flag so that tclPort.h can +# declare it. +#-------------------------------------------------------------------- + +echo "$as_me:$LINENO: checking for gettimeofday" >&5 +echo $ECHO_N "checking for gettimeofday... $ECHO_C" >&6 +if test "${ac_cv_func_gettimeofday+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define gettimeofday to an innocuous variant, in case declares gettimeofday. + For example, HP-UX 11i declares gettimeofday. */ +#define gettimeofday innocuous_gettimeofday + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char gettimeofday (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef gettimeofday + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char gettimeofday (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_gettimeofday) || defined (__stub___gettimeofday) +choke me +#else +char (*f) () = gettimeofday; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != gettimeofday; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_gettimeofday=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_func_gettimeofday=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_func_gettimeofday" >&5 +echo "${ECHO_T}$ac_cv_func_gettimeofday" >&6 +if test $ac_cv_func_gettimeofday = yes; then + : +else + + +cat >>confdefs.h <<\_ACEOF +#define NO_GETTOD 1 +_ACEOF + + fi - if test "$tcl_strtod" = 1; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Solaris2.4/Tru64 strtod bugs" >&5 -$as_echo_n "checking for Solaris2.4/Tru64 strtod bugs... " >&6; } -if ${tcl_cv_strtod_buggy+:} false; then : - $as_echo_n "(cached) " >&6 +echo "$as_me:$LINENO: checking for gettimeofday declaration" >&5 +echo $ECHO_N "checking for gettimeofday declaration... $ECHO_C" >&6 +if test "${tcl_cv_grep_gettimeofday+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 else - if test "$cross_compiling" = yes; then : - tcl_cv_strtod_buggy=buggy -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ +#include - extern double strtod(); - int main() { - char *infString="Inf", *nanString="NaN", *spaceString=" "; - char *term; - double value; - value = strtod(infString, &term); - if ((term != infString) && (term[-1] == 0)) { - exit(1); - } - value = strtod(nanString, &term); - if ((term != nanString) && (term[-1] == 0)) { - exit(1); - } - value = strtod(spaceString, &term); - if (term == (spaceString+1)) { - exit(1); - } - exit(0); - } _ACEOF -if ac_fn_c_try_run "$LINENO"; then : - tcl_cv_strtod_buggy=ok +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "gettimeofday" >/dev/null 2>&1; then + tcl_cv_grep_gettimeofday=present else - tcl_cv_strtod_buggy=buggy -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext + tcl_cv_grep_gettimeofday=missing fi +rm -f conftest* fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_strtod_buggy" >&5 -$as_echo "$tcl_cv_strtod_buggy" >&6; } - if test "$tcl_cv_strtod_buggy" = buggy; then - case " $LIBOBJS " in - *" fixstrtod.$ac_objext "* ) ;; - *) LIBOBJS="$LIBOBJS fixstrtod.$ac_objext" - ;; -esac - - USE_COMPAT=1 - -$as_echo "#define strtod fixstrtod" >>confdefs.h +echo "$as_me:$LINENO: result: $tcl_cv_grep_gettimeofday" >&5 +echo "${ECHO_T}$tcl_cv_grep_gettimeofday" >&6 +if test $tcl_cv_grep_gettimeofday = missing ; then - fi - fi +cat >>confdefs.h <<\_ACEOF +#define GETTOD_NOT_DECLARED 1 +_ACEOF +fi #-------------------------------------------------------------------- -# Check for various typedefs and provide substitutes if -# they don't exist. +# The following code checks to see whether it is possible to get +# signed chars on this platform. This is needed in order to +# properly generate sign-extended ints from character values. #-------------------------------------------------------------------- -ac_fn_c_check_type "$LINENO" "mode_t" "ac_cv_type_mode_t" "$ac_includes_default" -if test "x$ac_cv_type_mode_t" = xyes; then : +echo "$as_me:$LINENO: checking whether char is unsigned" >&5 +echo $ECHO_N "checking whether char is unsigned... $ECHO_C" >&6 +if test "${ac_cv_c_char_unsigned+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +static int test_array [1 - 2 * !(((char) -1) < 0)]; +test_array [0] = 0 -cat >>confdefs.h <<_ACEOF -#define mode_t int + ; + return 0; +} _ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_c_char_unsigned=no +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 +ac_cv_c_char_unsigned=yes +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi +echo "$as_me:$LINENO: result: $ac_cv_c_char_unsigned" >&5 +echo "${ECHO_T}$ac_cv_c_char_unsigned" >&6 +if test $ac_cv_c_char_unsigned = yes && test "$GCC" != yes; then + cat >>confdefs.h <<\_ACEOF +#define __CHAR_UNSIGNED__ 1 +_ACEOF -ac_fn_c_check_type "$LINENO" "pid_t" "ac_cv_type_pid_t" "$ac_includes_default" -if test "x$ac_cv_type_pid_t" = xyes; then : +fi +echo "$as_me:$LINENO: checking signed char declarations" >&5 +echo $ECHO_N "checking signed char declarations... $ECHO_C" >&6 +if test "${tcl_cv_char_signed+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 else -cat >>confdefs.h <<_ACEOF -#define pid_t int + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ _ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ -fi +int +main () +{ -ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default" -if test "x$ac_cv_type_size_t" = xyes; then : + signed char *p; + p = 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + tcl_cv_char_signed=yes else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 -cat >>confdefs.h <<_ACEOF -#define size_t unsigned int +tcl_cv_char_signed=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $tcl_cv_char_signed" >&5 +echo "${ECHO_T}$tcl_cv_char_signed" >&6 +if test $tcl_cv_char_signed = yes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_SIGNED_CHAR 1 _ACEOF fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for uid_t in sys/types.h" >&5 -$as_echo_n "checking for uid_t in sys/types.h... " >&6; } -if ${ac_cv_type_uid_t+:} false; then : - $as_echo_n "(cached) " >&6 +#-------------------------------------------------------------------- +# Does putenv() copy or not? We need to know to avoid memory leaks. +#-------------------------------------------------------------------- + +echo "$as_me:$LINENO: checking for a putenv() that copies the buffer" >&5 +echo $ECHO_N "checking for a putenv() that copies the buffer... $ECHO_C" >&6 +if test "${tcl_cv_putenv_copy+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + + if test "$cross_compiling" = yes; then + tcl_cv_putenv_copy=no else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ -#include + + #include + #define OURVAR "havecopy=yes" + int main (int argc, char *argv[]) + { + char *foo, *bar; + foo = (char *)strdup(OURVAR); + putenv(foo); + strcpy((char *)(strchr(foo, '=') + 1), "no"); + bar = getenv("havecopy"); + if (!strcmp(bar, "no")) { + /* doesnt copy */ + return 0; + } else { + /* does copy */ + return 1; + } + } _ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "uid_t" >/dev/null 2>&1; then : - ac_cv_type_uid_t=yes +rm -f conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + tcl_cv_putenv_copy=no else - ac_cv_type_uid_t=no -fi -rm -f conftest* + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 +( exit $ac_status ) +tcl_cv_putenv_copy=yes fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_uid_t" >&5 -$as_echo "$ac_cv_type_uid_t" >&6; } -if test $ac_cv_type_uid_t = no; then - -$as_echo "#define uid_t int" >>confdefs.h - +rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +fi +echo "$as_me:$LINENO: result: $tcl_cv_putenv_copy" >&5 +echo "${ECHO_T}$tcl_cv_putenv_copy" >&6 +if test $tcl_cv_putenv_copy = yes; then -$as_echo "#define gid_t int" >>confdefs.h +cat >>confdefs.h <<\_ACEOF +#define HAVE_PUTENV_THAT_COPIES 1 +_ACEOF fi +#-------------------------------------------------------------------- +# Check for support of nl_langinfo function +#-------------------------------------------------------------------- + -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for socklen_t" >&5 -$as_echo_n "checking for socklen_t... " >&6; } -if ${tcl_cv_type_socklen_t+:} false; then : - $as_echo_n "(cached) " >&6 + # Check whether --enable-langinfo or --disable-langinfo was given. +if test "${enable_langinfo+set}" = set; then + enableval="$enable_langinfo" + langinfo_ok=$enableval else + langinfo_ok=yes +fi; - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + HAVE_LANGINFO=0 + if test "$langinfo_ok" = "yes"; then + if test "${ac_cv_header_langinfo_h+set}" = set; then + echo "$as_me:$LINENO: checking for langinfo.h" >&5 +echo $ECHO_N "checking for langinfo.h... $ECHO_C" >&6 +if test "${ac_cv_header_langinfo_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: $ac_cv_header_langinfo_h" >&5 +echo "${ECHO_T}$ac_cv_header_langinfo_h" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking langinfo.h usability" >&5 +echo $ECHO_N "checking langinfo.h usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ +$ac_includes_default +#include +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 - #include - #include - -int -main () -{ - - socklen_t foo; +ac_header_compiler=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 - ; - return 0; -} +# Is the header present? +echo "$as_me:$LINENO: checking langinfo.h presence" >&5 +echo $ECHO_N "checking langinfo.h presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - tcl_cv_type_socklen_t=yes +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi else - tcl_cv_type_socklen_t=no + ac_cpp_err=yes fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_type_socklen_t" >&5 -$as_echo "$tcl_cv_type_socklen_t" >&6; } -if test $tcl_cv_type_socklen_t = no; then - -$as_echo "#define socklen_t int" >>confdefs.h +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + ac_header_preproc=no fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 -ac_fn_c_check_type "$LINENO" "intptr_t" "ac_cv_type_intptr_t" "$ac_includes_default" -if test "x$ac_cv_type_intptr_t" = xyes; then : - - -$as_echo "#define HAVE_INTPTR_T 1" >>confdefs.h +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: langinfo.h: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: langinfo.h: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: langinfo.h: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: langinfo.h: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: langinfo.h: present but cannot be compiled" >&5 +echo "$as_me: WARNING: langinfo.h: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: langinfo.h: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: langinfo.h: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: langinfo.h: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: langinfo.h: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: langinfo.h: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: langinfo.h: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: langinfo.h: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: langinfo.h: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: langinfo.h: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: langinfo.h: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +## ------------------------------ ## +## Report this to the tcl lists. ## +## ------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for langinfo.h" >&5 +echo $ECHO_N "checking for langinfo.h... $ECHO_C" >&6 +if test "${ac_cv_header_langinfo_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_header_langinfo_h=$ac_header_preproc +fi +echo "$as_me:$LINENO: result: $ac_cv_header_langinfo_h" >&5 +echo "${ECHO_T}$ac_cv_header_langinfo_h" >&6 +fi +if test $ac_cv_header_langinfo_h = yes; then + langinfo_ok=yes else + langinfo_ok=no +fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pointer-size signed integer type" >&5 -$as_echo_n "checking for pointer-size signed integer type... " >&6; } -if ${tcl_cv_intptr_t+:} false; then : - $as_echo_n "(cached) " >&6 + + fi + echo "$as_me:$LINENO: checking whether to use nl_langinfo" >&5 +echo $ECHO_N "checking whether to use nl_langinfo... $ECHO_C" >&6 + if test "$langinfo_ok" = "yes"; then + if test "${tcl_cv_langinfo_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 else - for tcl_cv_intptr_t in "int" "long" "long long" none; do - if test "$tcl_cv_intptr_t" != none; then - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ -$ac_includes_default +#include int main () { -static int test_array [1 - 2 * !(sizeof (void *) <= sizeof ($tcl_cv_intptr_t))]; -test_array [0] = 0; -return test_array [0]; - +nl_langinfo(CODESET); ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - tcl_ok=yes +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + tcl_cv_langinfo_h=yes else - tcl_ok=no + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +tcl_cv_langinfo_h=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - test "$tcl_ok" = yes && break; fi - done +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_intptr_t" >&5 -$as_echo "$tcl_cv_intptr_t" >&6; } - if test "$tcl_cv_intptr_t" != none; then -cat >>confdefs.h <<_ACEOF -#define intptr_t $tcl_cv_intptr_t + echo "$as_me:$LINENO: result: $tcl_cv_langinfo_h" >&5 +echo "${ECHO_T}$tcl_cv_langinfo_h" >&6 + if test $tcl_cv_langinfo_h = yes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_LANGINFO 1 _ACEOF + fi + else + echo "$as_me:$LINENO: result: $langinfo_ok" >&5 +echo "${ECHO_T}$langinfo_ok" >&6 fi -fi -ac_fn_c_check_type "$LINENO" "uintptr_t" "ac_cv_type_uintptr_t" "$ac_includes_default" -if test "x$ac_cv_type_uintptr_t" = xyes; then : +#-------------------------------------------------------------------- +# Check for support of chflags and mkstemps functions +#-------------------------------------------------------------------- -$as_echo "#define HAVE_UINTPTR_T 1" >>confdefs.h -else +for ac_func in chflags mkstemps +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 +if eval "test \"\${$as_ac_var+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case declares $ac_func. + For example, HP-UX 11i declares gettimeofday. */ +#define $ac_func innocuous_$ac_func - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pointer-size unsigned integer type" >&5 -$as_echo_n "checking for pointer-size unsigned integer type... " >&6; } -if ${tcl_cv_uintptr_t+:} false; then : - $as_echo_n "(cached) " >&6 -else +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $ac_func + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +char (*f) () = $ac_func; +#endif +#ifdef __cplusplus +} +#endif - for tcl_cv_uintptr_t in "unsigned int" "unsigned long" "unsigned long long" \ - none; do - if test "$tcl_cv_uintptr_t" != none; then - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$ac_includes_default int main () { -static int test_array [1 - 2 * !(sizeof (void *) <= sizeof ($tcl_cv_uintptr_t))]; -test_array [0] = 0; -return test_array [0]; - +return f != $ac_func; ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - tcl_ok=yes +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_var=yes" else - tcl_ok=no + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +eval "$as_ac_var=no" fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - test "$tcl_ok" = yes && break; fi - done +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_uintptr_t" >&5 -$as_echo "$tcl_cv_uintptr_t" >&6; } - if test "$tcl_cv_uintptr_t" != none; then - -cat >>confdefs.h <<_ACEOF -#define uintptr_t $tcl_cv_uintptr_t +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF - fi - -fi - - -#-------------------------------------------------------------------- -# If a system doesn't have an opendir function (man, that's old!) -# then we have to supply a different version of dirent.h which -# is compatible with the substitute version of opendir that's -# provided. This version only works with V7-style directories. -#-------------------------------------------------------------------- - -ac_fn_c_check_func "$LINENO" "opendir" "ac_cv_func_opendir" -if test "x$ac_cv_func_opendir" = xyes; then : - -else - -$as_echo "#define USE_DIRENT2_H 1" >>confdefs.h - fi +done #-------------------------------------------------------------------- -# The check below checks whether defines the type -# "union wait" correctly. It's needed because of weirdness in -# HP-UX where "union wait" is defined in both the BSD and SYS-V -# environments. Checking the usability of WIFEXITED seems to do -# the trick. +# Check for support of isnan() function or macro #-------------------------------------------------------------------- -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking union wait" >&5 -$as_echo_n "checking union wait... " >&6; } -if ${tcl_cv_union_wait+:} false; then : - $as_echo_n "(cached) " >&6 +echo "$as_me:$LINENO: checking isnan" >&5 +echo $ECHO_N "checking isnan... $ECHO_C" >&6 +if test "${tcl_cv_isnan+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ -#include -#include +#include int main () { -union wait x; -WIFEXITED(x); /* Generates compiler error if WIFEXITED - * uses an int. */ +isnan(0.0); /* Generates an error if isnan is missing */ ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : - tcl_cv_union_wait=yes +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + tcl_cv_isnan=yes else - tcl_cv_union_wait=no + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +tcl_cv_isnan=no fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_union_wait" >&5 -$as_echo "$tcl_cv_union_wait" >&6; } -if test $tcl_cv_union_wait = no; then +echo "$as_me:$LINENO: result: $tcl_cv_isnan" >&5 +echo "${ECHO_T}$tcl_cv_isnan" >&6 +if test $tcl_cv_isnan = no; then -$as_echo "#define NO_UNION_WAIT 1" >>confdefs.h +cat >>confdefs.h <<\_ACEOF +#define NO_ISNAN 1 +_ACEOF fi #-------------------------------------------------------------------- -# Check whether there is an strncasecmp function on this system. -# This is a bit tricky because under SCO it's in -lsocket and -# under Sequent Dynix it's in -linet. +# Darwin specific API checks and defines #-------------------------------------------------------------------- -ac_fn_c_check_func "$LINENO" "strncasecmp" "ac_cv_func_strncasecmp" -if test "x$ac_cv_func_strncasecmp" = xyes; then : - tcl_ok=1 -else - tcl_ok=0 -fi +if test "`uname -s`" = "Darwin" ; then -if test "$tcl_ok" = 0; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for strncasecmp in -lsocket" >&5 -$as_echo_n "checking for strncasecmp in -lsocket... " >&6; } -if ${ac_cv_lib_socket_strncasecmp+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lsocket $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext +for ac_func in getattrlist +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 +if eval "test \"\${$as_ac_var+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case declares $ac_func. + For example, HP-UX 11i declares gettimeofday. */ +#define $ac_func innocuous_$ac_func -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $ac_func + +/* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" +{ #endif -char strncasecmp (); +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +char (*f) () = $ac_func; +#endif +#ifdef __cplusplus +} +#endif + int main () { -return strncasecmp (); +return f != $ac_func; ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_socket_strncasecmp=yes +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_var=yes" else - ac_cv_lib_socket_strncasecmp=no + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +eval "$as_ac_var=no" fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_strncasecmp" >&5 -$as_echo "$ac_cv_lib_socket_strncasecmp" >&6; } -if test "x$ac_cv_lib_socket_strncasecmp" = xyes; then : - tcl_ok=1 -else - tcl_ok=0 +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + fi +done + +for ac_header in copyfile.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 fi -if test "$tcl_ok" = 0; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for strncasecmp in -linet" >&5 -$as_echo_n "checking for strncasecmp in -linet... " >&6; } -if ${ac_cv_lib_inet_strncasecmp+:} false; then : - $as_echo_n "(cached) " >&6 +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 else - ac_check_lib_save_LIBS=$LIBS -LIBS="-linet $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char strncasecmp (); -int -main () -{ -return strncasecmp (); - ; - return 0; -} +$ac_includes_default +#include <$ac_header> _ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_inet_strncasecmp=yes -else - ac_cv_lib_inet_strncasecmp=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_inet_strncasecmp" >&5 -$as_echo "$ac_cv_lib_inet_strncasecmp" >&6; } -if test "x$ac_cv_lib_inet_strncasecmp" = xyes; then : - tcl_ok=1 +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes else - tcl_ok=0 -fi - -fi -if test "$tcl_ok" = 0; then - case " $LIBOBJS " in - *" strncasecmp.$ac_objext "* ) ;; - *) LIBOBJS="$LIBOBJS strncasecmp.$ac_objext" - ;; -esac + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 - USE_COMPAT=1 +ac_header_compiler=no fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 -#-------------------------------------------------------------------- -# The code below deals with several issues related to gettimeofday: -# 1. Some systems don't provide a gettimeofday function at all -# (set NO_GETTOD if this is the case). -# 2. See if gettimeofday is declared in the header file. -# if not, set the GETTOD_NOT_DECLARED flag so that tclPort.h can -# declare it. -#-------------------------------------------------------------------- - -ac_fn_c_check_func "$LINENO" "gettimeofday" "ac_cv_func_gettimeofday" -if test "x$ac_cv_func_gettimeofday" = xyes; then : - +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi else - - -$as_echo "#define NO_GETTOD 1" >>confdefs.h - - + ac_cpp_err=yes fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for gettimeofday declaration" >&5 -$as_echo_n "checking for gettimeofday declaration... " >&6; } -if ${tcl_cv_grep_gettimeofday+:} false; then : - $as_echo_n "(cached) " >&6 +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "gettimeofday" >/dev/null 2>&1; then : - tcl_cv_grep_gettimeofday=present +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +## ------------------------------ ## +## Report this to the tcl lists. ## +## ------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 else - tcl_cv_grep_gettimeofday=missing + eval "$as_ac_Header=\$ac_header_preproc" fi -rm -f conftest* +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_grep_gettimeofday" >&5 -$as_echo "$tcl_cv_grep_gettimeofday" >&6; } -if test $tcl_cv_grep_gettimeofday = missing ; then - -$as_echo "#define GETTOD_NOT_DECLARED 1" >>confdefs.h +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF fi -#-------------------------------------------------------------------- -# The following code checks to see whether it is possible to get -# signed chars on this platform. This is needed in order to -# properly generate sign-extended ints from character values. -#-------------------------------------------------------------------- +done -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether char is unsigned" >&5 -$as_echo_n "checking whether char is unsigned... " >&6; } -if ${ac_cv_c_char_unsigned+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$ac_includes_default -int -main () -{ -static int test_array [1 - 2 * !(((char) -1) < 0)]; -test_array [0] = 0; -return test_array [0]; - ; - return 0; -} +for ac_func in copyfile +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 +if eval "test \"\${$as_ac_var+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_c_char_unsigned=no -else - ac_cv_c_char_unsigned=yes -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_char_unsigned" >&5 -$as_echo "$ac_cv_c_char_unsigned" >&6; } -if test $ac_cv_c_char_unsigned = yes && test "$GCC" != yes; then - $as_echo "#define __CHAR_UNSIGNED__ 1" >>confdefs.h +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case declares $ac_func. + For example, HP-UX 11i declares gettimeofday. */ +#define $ac_func innocuous_$ac_func -fi +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking signed char declarations" >&5 -$as_echo_n "checking signed char declarations... " >&6; } -if ${tcl_cv_char_signed+:} false; then : - $as_echo_n "(cached) " >&6 -else +#ifdef __STDC__ +# include +#else +# include +#endif - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ +#undef $ac_func + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +char (*f) () = $ac_func; +#endif +#ifdef __cplusplus +} +#endif int main () { - - signed char *p; - p = 0; - +return f != $ac_func; ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - tcl_cv_char_signed=yes +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_var=yes" else - tcl_cv_char_signed=no + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +eval "$as_ac_var=no" fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_char_signed" >&5 -$as_echo "$tcl_cv_char_signed" >&6; } -if test $tcl_cv_char_signed = yes; then - -$as_echo "#define HAVE_SIGNED_CHAR 1" >>confdefs.h +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF fi +done -#-------------------------------------------------------------------- -# Does putenv() copy or not? We need to know to avoid memory leaks. -#-------------------------------------------------------------------- - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a putenv() that copies the buffer" >&5 -$as_echo_n "checking for a putenv() that copies the buffer... " >&6; } -if ${tcl_cv_putenv_copy+:} false; then : - $as_echo_n "(cached) " >&6 -else + if test $tcl_corefoundation = yes; then - if test "$cross_compiling" = yes; then : - tcl_cv_putenv_copy=no +for ac_header in libkern/OSAtomic.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 - #include - #define OURVAR "havecopy=yes" - int main (int argc, char *argv[]) - { - char *foo, *bar; - foo = (char *)strdup(OURVAR); - putenv(foo); - strcpy((char *)(strchr(foo, '=') + 1), "no"); - bar = getenv("havecopy"); - if (!strcmp(bar, "no")) { - /* doesnt copy */ - return 0; - } else { - /* does copy */ - return 1; - } - } +ac_header_compiler=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ _ACEOF -if ac_fn_c_try_run "$LINENO"; then : - tcl_cv_putenv_copy=no +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi else - tcl_cv_putenv_copy=yes + ac_cpp_err=yes fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +## ------------------------------ ## +## Report this to the tcl lists. ## +## ------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_putenv_copy" >&5 -$as_echo "$tcl_cv_putenv_copy" >&6; } -if test $tcl_cv_putenv_copy = yes; then +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 -$as_echo "#define HAVE_PUTENV_THAT_COPIES 1" >>confdefs.h +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF fi -#-------------------------------------------------------------------- -# Check for support of nl_langinfo function -#-------------------------------------------------------------------- +done - # Check whether --enable-langinfo was given. -if test "${enable_langinfo+set}" = set; then : - enableval=$enable_langinfo; langinfo_ok=$enableval -else - langinfo_ok=yes -fi +for ac_func in OSSpinLockLock +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 +if eval "test \"\${$as_ac_var+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case declares $ac_func. + For example, HP-UX 11i declares gettimeofday. */ +#define $ac_func innocuous_$ac_func +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ - HAVE_LANGINFO=0 - if test "$langinfo_ok" = "yes"; then - ac_fn_c_check_header_mongrel "$LINENO" "langinfo.h" "ac_cv_header_langinfo_h" "$ac_includes_default" -if test "x$ac_cv_header_langinfo_h" = xyes; then : - langinfo_ok=yes -else - langinfo_ok=no -fi +#ifdef __STDC__ +# include +#else +# include +#endif +#undef $ac_func - fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use nl_langinfo" >&5 -$as_echo_n "checking whether to use nl_langinfo... " >&6; } - if test "$langinfo_ok" = "yes"; then - if ${tcl_cv_langinfo_h+:} false; then : - $as_echo_n "(cached) " >&6 -else +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +char (*f) () = $ac_func; +#endif +#ifdef __cplusplus +} +#endif - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include int main () { -nl_langinfo(CODESET); +return f != $ac_func; ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - tcl_cv_langinfo_h=yes +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_var=yes" else - tcl_cv_langinfo_h=no + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +eval "$as_ac_var=no" fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext fi - - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_langinfo_h" >&5 -$as_echo "$tcl_cv_langinfo_h" >&6; } - if test $tcl_cv_langinfo_h = yes; then - -$as_echo "#define HAVE_LANGINFO 1" >>confdefs.h - - fi - else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $langinfo_ok" >&5 -$as_echo "$langinfo_ok" >&6; } - fi - - -#-------------------------------------------------------------------- -# Check for support of chflags and mkstemps functions -#-------------------------------------------------------------------- - -for ac_func in chflags mkstemps -do : - as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` -ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" -if eval test \"x\$"$as_ac_var"\" = x"yes"; then : +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 +if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done + fi -#-------------------------------------------------------------------- -# Check for support of isnan() function or macro -#-------------------------------------------------------------------- - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking isnan" >&5 -$as_echo_n "checking isnan... " >&6; } -if ${tcl_cv_isnan+:} false; then : - $as_echo_n "(cached) " >&6 -else - - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -int -main () -{ - -isnan(0.0); /* Generates an error if isnan is missing */ - - ; - return 0; -} +cat >>confdefs.h <<\_ACEOF +#define USE_VFORK 1 _ACEOF -if ac_fn_c_try_link "$LINENO"; then : - tcl_cv_isnan=yes -else - tcl_cv_isnan=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_isnan" >&5 -$as_echo "$tcl_cv_isnan" >&6; } -if test $tcl_cv_isnan = no; then - -$as_echo "#define NO_ISNAN 1" >>confdefs.h - -fi -#-------------------------------------------------------------------- -# Darwin specific API checks and defines -#-------------------------------------------------------------------- -if test "`uname -s`" = "Darwin" ; then - for ac_func in getattrlist -do : - ac_fn_c_check_func "$LINENO" "getattrlist" "ac_cv_func_getattrlist" -if test "x$ac_cv_func_getattrlist" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_GETATTRLIST 1 +cat >>confdefs.h <<\_ACEOF +#define TCL_DEFAULT_ENCODING "utf-8" _ACEOF -fi -done - for ac_header in copyfile.h -do : - ac_fn_c_check_header_mongrel "$LINENO" "copyfile.h" "ac_cv_header_copyfile_h" "$ac_includes_default" -if test "x$ac_cv_header_copyfile_h" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_COPYFILE_H 1 +cat >>confdefs.h <<\_ACEOF +#define TCL_LOAD_FROM_MEMORY 1 _ACEOF -fi - -done - for ac_func in copyfile -do : - ac_fn_c_check_func "$LINENO" "copyfile" "ac_cv_func_copyfile" -if test "x$ac_cv_func_copyfile" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_COPYFILE 1 +cat >>confdefs.h <<\_ACEOF +#define TCL_WIDE_CLICKS 1 _ACEOF -fi -done - if test $tcl_corefoundation = yes; then - for ac_header in libkern/OSAtomic.h -do : - ac_fn_c_check_header_mongrel "$LINENO" "libkern/OSAtomic.h" "ac_cv_header_libkern_OSAtomic_h" "$ac_includes_default" -if test "x$ac_cv_header_libkern_OSAtomic_h" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBKERN_OSATOMIC_H 1 +for ac_header in AvailabilityMacros.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ _ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 +ac_header_compiler=no fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 -done - - for ac_func in OSSpinLockLock -do : - ac_fn_c_check_func "$LINENO" "OSSpinLockLock" "ac_cv_func_OSSpinLockLock" -if test "x$ac_cv_func_OSSpinLockLock" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_OSSPINLOCKLOCK 1 +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ _ACEOF - +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes fi -done - - fi - -$as_echo "#define USE_VFORK 1" >>confdefs.h - - -$as_echo "#define TCL_DEFAULT_ENCODING \"utf-8\"" >>confdefs.h - - -$as_echo "#define TCL_LOAD_FROM_MEMORY 1" >>confdefs.h +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 -$as_echo "#define TCL_WIDE_CLICKS 1" >>confdefs.h +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +## ------------------------------ ## +## Report this to the tcl lists. ## +## ------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 - for ac_header in AvailabilityMacros.h -do : - ac_fn_c_check_header_mongrel "$LINENO" "AvailabilityMacros.h" "ac_cv_header_AvailabilityMacros_h" "$ac_includes_default" -if test "x$ac_cv_header_AvailabilityMacros_h" = xyes; then : +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF -#define HAVE_AVAILABILITYMACROS_H 1 +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi @@ -9831,14 +18064,18 @@ fi done if test "$ac_cv_header_AvailabilityMacros_h" = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if weak import is available" >&5 -$as_echo_n "checking if weak import is available... " >&6; } -if ${tcl_cv_cc_weak_import+:} false; then : - $as_echo_n "(cached) " >&6 + echo "$as_me:$LINENO: checking if weak import is available" >&5 +echo $ECHO_N "checking if weak import is available... $ECHO_C" >&6 +if test "${tcl_cv_cc_weak_import+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 else hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -Werror" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ @@ -9858,30 +18095,60 @@ rand(); return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then tcl_cv_cc_weak_import=yes else - tcl_cv_cc_weak_import=no + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +tcl_cv_cc_weak_import=no fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext CFLAGS=$hold_cflags fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_cc_weak_import" >&5 -$as_echo "$tcl_cv_cc_weak_import" >&6; } +echo "$as_me:$LINENO: result: $tcl_cv_cc_weak_import" >&5 +echo "${ECHO_T}$tcl_cv_cc_weak_import" >&6 if test $tcl_cv_cc_weak_import = yes; then -$as_echo "#define HAVE_WEAK_IMPORT 1" >>confdefs.h +cat >>confdefs.h <<\_ACEOF +#define HAVE_WEAK_IMPORT 1 +_ACEOF fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if Darwin SUSv3 extensions are available" >&5 -$as_echo_n "checking if Darwin SUSv3 extensions are available... " >&6; } -if ${tcl_cv_cc_darwin_c_source+:} false; then : - $as_echo_n "(cached) " >&6 + echo "$as_me:$LINENO: checking if Darwin SUSv3 extensions are available" >&5 +echo $ECHO_N "checking if Darwin SUSv3 extensions are available... $ECHO_C" >&6 +if test "${tcl_cv_cc_darwin_c_source+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 else hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -Werror" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ @@ -9902,19 +18169,45 @@ main () return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then tcl_cv_cc_darwin_c_source=yes else - tcl_cv_cc_darwin_c_source=no + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +tcl_cv_cc_darwin_c_source=no fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext CFLAGS=$hold_cflags fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_cc_darwin_c_source" >&5 -$as_echo "$tcl_cv_cc_darwin_c_source" >&6; } +echo "$as_me:$LINENO: result: $tcl_cv_cc_darwin_c_source" >&5 +echo "${ECHO_T}$tcl_cv_cc_darwin_c_source" >&6 if test $tcl_cv_cc_darwin_c_source = yes; then -$as_echo "#define _DARWIN_C_SOURCE 1" >>confdefs.h +cat >>confdefs.h <<\_ACEOF +#define _DARWIN_C_SOURCE 1 +_ACEOF fi fi @@ -9930,13 +18223,17 @@ fi # Check for support of fts functions (readdir replacement) #-------------------------------------------------------------------- -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fts" >&5 -$as_echo_n "checking for fts... " >&6; } -if ${tcl_cv_api_fts+:} false; then : - $as_echo_n "(cached) " >&6 +echo "$as_me:$LINENO: checking for fts" >&5 +echo $ECHO_N "checking for fts... $ECHO_C" >&6 +if test "${tcl_cv_api_fts+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include @@ -9955,19 +18252,45 @@ main () return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then tcl_cv_api_fts=yes else - tcl_cv_api_fts=no + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +tcl_cv_api_fts=no fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_api_fts" >&5 -$as_echo "$tcl_cv_api_fts" >&6; } +echo "$as_me:$LINENO: result: $tcl_cv_api_fts" >&5 +echo "${ECHO_T}$tcl_cv_api_fts" >&6 if test $tcl_cv_api_fts = yes; then -$as_echo "#define HAVE_FTS 1" >>confdefs.h +cat >>confdefs.h <<\_ACEOF +#define HAVE_FTS 1 +_ACEOF fi @@ -9978,24 +18301,300 @@ fi #-------------------------------------------------------------------- - for ac_header in sys/ioctl.h -do : - ac_fn_c_check_header_mongrel "$LINENO" "sys/ioctl.h" "ac_cv_header_sys_ioctl_h" "$ac_includes_default" -if test "x$ac_cv_header_sys_ioctl_h" = xyes; then : + +for ac_header in sys/ioctl.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +## ------------------------------ ## +## Report this to the tcl lists. ## +## ------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF -#define HAVE_SYS_IOCTL_H 1 +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done - for ac_header in sys/filio.h -do : - ac_fn_c_check_header_mongrel "$LINENO" "sys/filio.h" "ac_cv_header_sys_filio_h" "$ac_includes_default" -if test "x$ac_cv_header_sys_filio_h" = xyes; then : + +for ac_header in sys/filio.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +## ------------------------------ ## +## Report this to the tcl lists. ## +## ------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF -#define HAVE_SYS_FILIO_H 1 +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi @@ -10003,10 +18602,10 @@ fi done - { $as_echo "$as_me:${as_lineno-$LINENO}: checking system version" >&5 -$as_echo_n "checking system version... " >&6; } -if ${tcl_cv_sys_version+:} false; then : - $as_echo_n "(cached) " >&6 + echo "$as_me:$LINENO: checking system version" >&5 +echo $ECHO_N "checking system version... $ECHO_C" >&6 +if test "${tcl_cv_sys_version+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -f /usr/lib/NextStep/software_version; then @@ -10014,8 +18613,8 @@ else else tcl_cv_sys_version=`uname -s`-`uname -r` if test "$?" -ne 0 ; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: can't find uname command" >&5 -$as_echo "$as_me: WARNING: can't find uname command" >&2;} + { echo "$as_me:$LINENO: WARNING: can't find uname command" >&5 +echo "$as_me: WARNING: can't find uname command" >&2;} tcl_cv_sys_version=unknown else # Special check for weird MP-RAS system (uname returns weird @@ -10031,52 +18630,58 @@ $as_echo "$as_me: WARNING: can't find uname command" >&2;} fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_sys_version" >&5 -$as_echo "$tcl_cv_sys_version" >&6; } +echo "$as_me:$LINENO: result: $tcl_cv_sys_version" >&5 +echo "${ECHO_T}$tcl_cv_sys_version" >&6 system=$tcl_cv_sys_version - { $as_echo "$as_me:${as_lineno-$LINENO}: checking FIONBIO vs. O_NONBLOCK for nonblocking I/O" >&5 -$as_echo_n "checking FIONBIO vs. O_NONBLOCK for nonblocking I/O... " >&6; } + echo "$as_me:$LINENO: checking FIONBIO vs. O_NONBLOCK for nonblocking I/O" >&5 +echo $ECHO_N "checking FIONBIO vs. O_NONBLOCK for nonblocking I/O... $ECHO_C" >&6 case $system in OSF*) -$as_echo "#define USE_FIONBIO 1" >>confdefs.h +cat >>confdefs.h <<\_ACEOF +#define USE_FIONBIO 1 +_ACEOF - { $as_echo "$as_me:${as_lineno-$LINENO}: result: FIONBIO" >&5 -$as_echo "FIONBIO" >&6; } + echo "$as_me:$LINENO: result: FIONBIO" >&5 +echo "${ECHO_T}FIONBIO" >&6 ;; SunOS-4*) -$as_echo "#define USE_FIONBIO 1" >>confdefs.h +cat >>confdefs.h <<\_ACEOF +#define USE_FIONBIO 1 +_ACEOF - { $as_echo "$as_me:${as_lineno-$LINENO}: result: FIONBIO" >&5 -$as_echo "FIONBIO" >&6; } + echo "$as_me:$LINENO: result: FIONBIO" >&5 +echo "${ECHO_T}FIONBIO" >&6 ;; *) - { $as_echo "$as_me:${as_lineno-$LINENO}: result: O_NONBLOCK" >&5 -$as_echo "O_NONBLOCK" >&6; } + echo "$as_me:$LINENO: result: O_NONBLOCK" >&5 +echo "${ECHO_T}O_NONBLOCK" >&6 ;; esac #------------------------------------------------------------------------ -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use dll unloading" >&5 -$as_echo_n "checking whether to use dll unloading... " >&6; } -# Check whether --enable-dll-unloading was given. -if test "${enable_dll_unloading+set}" = set; then : - enableval=$enable_dll_unloading; tcl_ok=$enableval +echo "$as_me:$LINENO: checking whether to use dll unloading" >&5 +echo $ECHO_N "checking whether to use dll unloading... $ECHO_C" >&6 +# Check whether --enable-dll-unloading or --disable-dll-unloading was given. +if test "${enable_dll_unloading+set}" = set; then + enableval="$enable_dll_unloading" + tcl_ok=$enableval else tcl_ok=yes -fi - +fi; if test $tcl_ok = yes; then -$as_echo "#define TCL_UNLOAD_DLLS 1" >>confdefs.h +cat >>confdefs.h <<\_ACEOF +#define TCL_UNLOAD_DLLS 1 +_ACEOF fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_ok" >&5 -$as_echo "$tcl_ok" >&6; } +echo "$as_me:$LINENO: result: $tcl_ok" >&5 +echo "${ECHO_T}$tcl_ok" >&6 #------------------------------------------------------------------------ # Check whether the timezone data is supplied by the OS or has @@ -10084,31 +18689,31 @@ $as_echo "$tcl_ok" >&6; } # be overriden on the configure command line either way. #------------------------------------------------------------------------ -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for timezone data" >&5 -$as_echo_n "checking for timezone data... " >&6; } +echo "$as_me:$LINENO: checking for timezone data" >&5 +echo $ECHO_N "checking for timezone data... $ECHO_C" >&6 -# Check whether --with-tzdata was given. -if test "${with_tzdata+set}" = set; then : - withval=$with_tzdata; tcl_ok=$withval +# Check whether --with-tzdata or --without-tzdata was given. +if test "${with_tzdata+set}" = set; then + withval="$with_tzdata" + tcl_ok=$withval else tcl_ok=auto -fi - +fi; # # Any directories that get added here must also be added to the # search path in ::tcl::clock::Initialize (library/clock.tcl). # case $tcl_ok in no) - { $as_echo "$as_me:${as_lineno-$LINENO}: result: supplied by OS vendor" >&5 -$as_echo "supplied by OS vendor" >&6; } + echo "$as_me:$LINENO: result: supplied by OS vendor" >&5 +echo "${ECHO_T}supplied by OS vendor" >&6 ;; yes) # nothing to do here ;; auto*) - if ${tcl_cv_dir_zoneinfo+:} false; then : - $as_echo_n "(cached) " >&6 + if test "${tcl_cv_dir_zoneinfo+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 else for dir in /usr/share/zoneinfo \ @@ -10125,20 +18730,22 @@ fi if test -n "$tcl_cv_dir_zoneinfo"; then tcl_ok=no - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $dir" >&5 -$as_echo "$dir" >&6; } + echo "$as_me:$LINENO: result: $dir" >&5 +echo "${ECHO_T}$dir" >&6 else tcl_ok=yes fi ;; *) - as_fn_error $? "invalid argument: $tcl_ok" "$LINENO" 5 + { { echo "$as_me:$LINENO: error: invalid argument: $tcl_ok" >&5 +echo "$as_me: error: invalid argument: $tcl_ok" >&2;} + { (exit 1); exit 1; }; } ;; esac if test $tcl_ok = yes then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: supplied by Tcl" >&5 -$as_echo "supplied by Tcl" >&6; } + echo "$as_me:$LINENO: result: supplied by Tcl" >&5 +echo "${ECHO_T}supplied by Tcl" >&6 INSTALL_TZDATA=install-tzdata fi @@ -10146,16 +18753,152 @@ fi # DTrace support #-------------------------------------------------------------------- -# Check whether --enable-dtrace was given. -if test "${enable_dtrace+set}" = set; then : - enableval=$enable_dtrace; tcl_ok=$enableval +# Check whether --enable-dtrace or --disable-dtrace was given. +if test "${enable_dtrace+set}" = set; then + enableval="$enable_dtrace" + tcl_ok=$enableval else tcl_ok=no +fi; +if test $tcl_ok = yes; then + if test "${ac_cv_header_sys_sdt_h+set}" = set; then + echo "$as_me:$LINENO: checking for sys/sdt.h" >&5 +echo $ECHO_N "checking for sys/sdt.h... $ECHO_C" >&6 +if test "${ac_cv_header_sys_sdt_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: $ac_cv_header_sys_sdt_h" >&5 +echo "${ECHO_T}$ac_cv_header_sys_sdt_h" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking sys/sdt.h usability" >&5 +echo $ECHO_N "checking sys/sdt.h usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 -if test $tcl_ok = yes; then - ac_fn_c_check_header_mongrel "$LINENO" "sys/sdt.h" "ac_cv_header_sys_sdt_h" "$ac_includes_default" -if test "x$ac_cv_header_sys_sdt_h" = xyes; then : +# Is the header present? +echo "$as_me:$LINENO: checking sys/sdt.h presence" >&5 +echo $ECHO_N "checking sys/sdt.h presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: sys/sdt.h: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: sys/sdt.h: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: sys/sdt.h: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: sys/sdt.h: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: sys/sdt.h: present but cannot be compiled" >&5 +echo "$as_me: WARNING: sys/sdt.h: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: sys/sdt.h: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: sys/sdt.h: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: sys/sdt.h: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: sys/sdt.h: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: sys/sdt.h: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: sys/sdt.h: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: sys/sdt.h: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: sys/sdt.h: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: sys/sdt.h: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: sys/sdt.h: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +## ------------------------------ ## +## Report this to the tcl lists. ## +## ------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for sys/sdt.h" >&5 +echo $ECHO_N "checking for sys/sdt.h... $ECHO_C" >&6 +if test "${ac_cv_header_sys_sdt_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_header_sys_sdt_h=$ac_header_preproc +fi +echo "$as_me:$LINENO: result: $ac_cv_header_sys_sdt_h" >&5 +echo "${ECHO_T}$ac_cv_header_sys_sdt_h" >&6 + +fi +if test $ac_cv_header_sys_sdt_h = yes; then tcl_ok=yes else tcl_ok=no @@ -10166,10 +18909,10 @@ fi if test $tcl_ok = yes; then # Extract the first word of "dtrace", so it can be a program name with args. set dummy dtrace; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_DTRACE+:} false; then : - $as_echo_n "(cached) " >&6 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_path_DTRACE+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 else case $DTRACE in [\\/]* | ?:[\\/]*) @@ -10182,37 +18925,38 @@ for as_dir in $as_dummy do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_DTRACE="$as_dir/$ac_word$ac_exec_ext" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done - done -IFS=$as_save_IFS +done ;; esac fi DTRACE=$ac_cv_path_DTRACE + if test -n "$DTRACE"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DTRACE" >&5 -$as_echo "$DTRACE" >&6; } + echo "$as_me:$LINENO: result: $DTRACE" >&5 +echo "${ECHO_T}$DTRACE" >&6 else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 fi - test -z "$ac_cv_path_DTRACE" && tcl_ok=no fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable DTrace support" >&5 -$as_echo_n "checking whether to enable DTrace support... " >&6; } +echo "$as_me:$LINENO: checking whether to enable DTrace support" >&5 +echo $ECHO_N "checking whether to enable DTrace support... $ECHO_C" >&6 MAKEFILE_SHELL='/bin/sh' if test $tcl_ok = yes; then -$as_echo "#define USE_DTRACE 1" >>confdefs.h +cat >>confdefs.h <<\_ACEOF +#define USE_DTRACE 1 +_ACEOF DTRACE_SRC="\${DTRACE_SRC}" DTRACE_HDR="\${DTRACE_HDR}" @@ -10230,20 +18974,24 @@ $as_echo "#define USE_DTRACE 1" >>confdefs.h fi fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_ok" >&5 -$as_echo "$tcl_ok" >&6; } +echo "$as_me:$LINENO: result: $tcl_ok" >&5 +echo "${ECHO_T}$tcl_ok" >&6 #-------------------------------------------------------------------- # The check below checks whether the cpuid instruction is usable. #-------------------------------------------------------------------- -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the cpuid instruction is usable" >&5 -$as_echo_n "checking whether the cpuid instruction is usable... " >&6; } -if ${tcl_cv_cpuid+:} false; then : - $as_echo_n "(cached) " >&6 +echo "$as_me:$LINENO: checking whether the cpuid instruction is usable" >&5 +echo $ECHO_N "checking whether the cpuid instruction is usable... $ECHO_C" >&6 +if test "${tcl_cv_cpuid+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int @@ -10262,19 +19010,45 @@ main () return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then tcl_cv_cpuid=yes else - tcl_cv_cpuid=no + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +tcl_cv_cpuid=no fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_cpuid" >&5 -$as_echo "$tcl_cv_cpuid" >&6; } +echo "$as_me:$LINENO: result: $tcl_cv_cpuid" >&5 +echo "${ECHO_T}$tcl_cv_cpuid" >&6 if test $tcl_cv_cpuid = yes; then -$as_echo "#define HAVE_CPUID 1" >>confdefs.h +cat >>confdefs.h <<\_ACEOF +#define HAVE_CPUID 1 +_ACEOF fi @@ -10305,38 +19079,38 @@ HTML_DIR='$(DISTDIR)/html' if test "`uname -s`" = "Darwin" ; then if test "`uname -s`" = "Darwin" ; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to package libraries" >&5 -$as_echo_n "checking how to package libraries... " >&6; } - # Check whether --enable-framework was given. -if test "${enable_framework+set}" = set; then : - enableval=$enable_framework; enable_framework=$enableval + echo "$as_me:$LINENO: checking how to package libraries" >&5 +echo $ECHO_N "checking how to package libraries... $ECHO_C" >&6 + # Check whether --enable-framework or --disable-framework was given. +if test "${enable_framework+set}" = set; then + enableval="$enable_framework" + enable_framework=$enableval else enable_framework=no -fi - +fi; if test $enable_framework = yes; then if test $SHARED_BUILD = 0; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Frameworks can only be built if --enable-shared is yes" >&5 -$as_echo "$as_me: WARNING: Frameworks can only be built if --enable-shared is yes" >&2;} + { echo "$as_me:$LINENO: WARNING: Frameworks can only be built if --enable-shared is yes" >&5 +echo "$as_me: WARNING: Frameworks can only be built if --enable-shared is yes" >&2;} enable_framework=no fi if test $tcl_corefoundation = no; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Frameworks can only be used when CoreFoundation is available" >&5 -$as_echo "$as_me: WARNING: Frameworks can only be used when CoreFoundation is available" >&2;} + { echo "$as_me:$LINENO: WARNING: Frameworks can only be used when CoreFoundation is available" >&5 +echo "$as_me: WARNING: Frameworks can only be used when CoreFoundation is available" >&2;} enable_framework=no fi fi if test $enable_framework = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: framework" >&5 -$as_echo "framework" >&6; } + echo "$as_me:$LINENO: result: framework" >&5 +echo "${ECHO_T}framework" >&6 FRAMEWORK_BUILD=1 else if test $SHARED_BUILD = 1; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: shared library" >&5 -$as_echo "shared library" >&6; } + echo "$as_me:$LINENO: result: shared library" >&5 +echo "${ECHO_T}shared library" >&6 else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: static library" >&5 -$as_echo "static library" >&6; } + echo "$as_me:$LINENO: result: static library" >&5 +echo "${ECHO_T}static library" >&6 fi FRAMEWORK_BUILD=0 fi @@ -10348,18 +19122,20 @@ $as_echo "static library" >&6; } TCL_SHLIB_LD_EXTRAS="${TCL_SHLIB_LD_EXTRAS}"' -sectcreate __TEXT __info_plist Tcl-Info.plist' EXTRA_TCLSH_LIBS='-sectcreate __TEXT __info_plist Tclsh-Info.plist' EXTRA_APP_CC_SWITCHES='-mdynamic-no-pic' - ac_config_files="$ac_config_files Tcl-Info.plist:../macosx/Tcl-Info.plist.in Tclsh-Info.plist:../macosx/Tclsh-Info.plist.in" + ac_config_files="$ac_config_files Tcl-Info.plist:../macosx/Tcl-Info.plist.in Tclsh-Info.plist:../macosx/Tclsh-Info.plist.in" TCL_YEAR="`date +%Y`" fi if test "$FRAMEWORK_BUILD" = "1" ; then -$as_echo "#define TCL_FRAMEWORK 1" >>confdefs.h +cat >>confdefs.h <<\_ACEOF +#define TCL_FRAMEWORK 1 +_ACEOF # Construct a fake local framework structure to make linking with # '-framework Tcl' and running of tcltest work - ac_config_commands="$ac_config_commands Tcl.framework" + ac_config_commands="$ac_config_commands Tcl.framework" LD_LIBRARY_PATH_VAR="DYLD_FRAMEWORK_PATH" # default install directory for bundled packages @@ -10429,29 +19205,6 @@ fi #-------------------------------------------------------------------- # The statements below define various symbols relating to Tcl -# core vfs and kit support. -#-------------------------------------------------------------------- - -eval "TCL_KIT_LIB_FILE=libtclkit${UNSHARED_LIB_SUFFIX}" -eval "TCL_KIT_LIB_FILE=${TCL_KIT_LIB_FILE}" - -eval "TCL_KIT_LIB_FILE=libtclkit${TCL_UNSHARED_LIB_SUFFIX}" -eval "TCL_KIT_LIB_FILE=\"${TCL_KIT_LIB_FILE}\"" -eval "TCL_KIT_LIB_DIR=${libdir}" - -if test "${TCL_LIB_VERSIONS_OK}" = "ok"; then - TCL_KIT_LIB_FLAG="-ltclkit${TCL_VERSION}" -else - TCL_KIT_LIB_FLAG="-ltclkit`echo ${TCL_VERSION} | tr -d .`" -fi - -TCL_BUILD_KIT_LIB_SPEC="-L`pwd | sed -e 's/ /\\\\ /g'` ${TCL_KIT_LIB_FLAG}" -TCL_KIT_LIB_SPEC="-L${TCL_KIT_LIB_DIR} ${TCL_KIT_LIB_FLAG}" -TCL_BUILD_KIT_LIB_PATH="`pwd`/${TCL_KIT_LIB_FILE}" -TCL_KIT_LIB_PATH="${TCL_KIT_LIB_DIR}/${TCL_KIT_LIB_FILE}" - -#-------------------------------------------------------------------- -# The statements below define various symbols relating to Tcl # stub support. #-------------------------------------------------------------------- @@ -10542,16 +19295,7 @@ TCL_SHARED_BUILD=${SHARED_BUILD} - - - - - - - - - -ac_config_files="$ac_config_files Makefile:../unix/Makefile.in dltest/Makefile:../unix/dltest/Makefile.in tclConfig.sh:../unix/tclConfig.sh.in tcl.pc:../unix/tcl.pc.in" + ac_config_files="$ac_config_files Makefile:../unix/Makefile.in dltest/Makefile:../unix/dltest/Makefile.in tclConfig.sh:../unix/tclConfig.sh.in tcl.pc:../unix/tcl.pc.in" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure @@ -10571,70 +19315,39 @@ _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. -# So, we kill variables containing newlines. +# So, don't put newlines in cache variables' values. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. -( - for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do - eval ac_val=\$$ac_var - case $ac_val in #( - *${as_nl}*) - case $ac_var in #( - *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 -$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; - esac - case $ac_var in #( - _ | IFS | as_nl) ;; #( - BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( - *) { eval $ac_var=; unset $ac_var;} ;; - esac ;; - esac - done - +{ (set) 2>&1 | - case $as_nl`(ac_space=' '; set) 2>&1` in #( - *${as_nl}ac_space=\ *) - # `set' does not quote correctly, so add quotes: double-quote - # substitution turns \\\\ into \\, and sed turns \\ into \. + case `(ac_space=' '; set | grep ac_space) 2>&1` in + *ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \). sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" - ;; #( + ;; *) # `set' quotes correctly as required by POSIX, so do not add quotes. - sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + sed -n \ + "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" ;; - esac | - sort -) | + esac; +} | sed ' - /^ac_cv_env_/b end t clear - :clear + : clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end - s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ - :end' >>confcache -if diff "$cache_file" confcache >/dev/null 2>&1; then :; else - if test -w "$cache_file"; then - if test "x$cache_file" != "x/dev/null"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 -$as_echo "$as_me: updating cache $cache_file" >&6;} - if test ! -f "$cache_file" || test -h "$cache_file"; then - cat confcache >"$cache_file" - else - case $cache_file in #( - */* | ?:*) - mv -f confcache "$cache_file"$$ && - mv -f "$cache_file"$$ "$cache_file" ;; #( - *) - mv -f confcache "$cache_file" ;; - esac - fi - fi + /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + : end' >>confcache +if diff $cache_file confcache >/dev/null 2>&1; then :; else + if test -w $cache_file; then + test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file" + cat confcache >$cache_file else - { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 -$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} + echo "not updating unwritable cache $cache_file" fi fi rm -f confcache @@ -10643,56 +19356,63 @@ test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' +# VPATH may cause trouble with some makes, so we remove $(srcdir), +# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=/{ +s/:*\$(srcdir):*/:/; +s/:*\${srcdir}:*/:/; +s/:*@srcdir@:*/:/; +s/^\([^=]*=[ ]*\):*/\1/; +s/:*$//; +s/^[^=]*=[ ]*$//; +}' +fi + # Transform confdefs.h into DEFS. # Protect against shell expansion while executing Makefile rules. # Protect against Makefile macro expansion. # # If the first sed substitution is executed (which looks for macros that -# take arguments), then branch to the quote section. Otherwise, +# take arguments), then we branch to the quote section. Otherwise, # look for a macro that doesn't take arguments. -ac_script=' -:mline -/\\$/{ - N - s,\\\n,, - b mline -} +cat >confdef2opt.sed <<\_ACEOF t clear -:clear -s/^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\)/-D\1=\2/g +: clear +s,^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\),-D\1=\2,g t quote -s/^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)/-D\1=\2/g +s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\),-D\1=\2,g t quote -b any -:quote -s/[ `~#$^&*(){}\\|;'\''"<>?]/\\&/g -s/\[/\\&/g -s/\]/\\&/g -s/\$/$$/g -H -:any -${ - g - s/^\n// - s/\n/ /g - p -} -' -DEFS=`sed -n "$ac_script" confdefs.h` +d +: quote +s,[ `~#$^&*(){}\\|;'"<>?],\\&,g +s,\[,\\&,g +s,\],\\&,g +s,\$,$$,g +p +_ACEOF +# We use echo to avoid assuming a particular line-breaking character. +# The extra dot is to prevent the shell from consuming trailing +# line-breaks from the sub-command output. A line-break within +# single-quotes doesn't work because, if this script is created in a +# platform that uses two characters for line-breaks (e.g., DOS), tr +# would break. +ac_LF_and_DOT=`echo; echo .` +DEFS=`sed -n -f confdef2opt.sed confdefs.h | tr "$ac_LF_and_DOT" ' .'` +rm -f confdef2opt.sed CFLAGS="${CFLAGS} ${CPPFLAGS}"; CPPFLAGS="" - -: "${CONFIG_STATUS=./config.status}" -ac_write_fail=0 +: ${CONFIG_STATUS=./config.status} ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" -{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 -$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} -as_write_fail=0 -cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 +{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 +echo "$as_me: creating $CONFIG_STATUS" >&6;} +cat >$CONFIG_STATUS <<_ACEOF #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. @@ -10702,253 +19422,81 @@ cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 debug=false ac_cs_recheck=false ac_cs_silent=false - SHELL=\${CONFIG_SHELL-$SHELL} -export SHELL -_ASEOF -cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 -## -------------------- ## -## M4sh Initialization. ## -## -------------------- ## - -# Be more Bourne compatible -DUALCASE=1; export DUALCASE # for MKS sh -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be Bourne compatible +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: - # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' - setopt NO_GLOB_SUBST -else - case `(set -o) 2>/dev/null` in #( - *posix*) : - set -o posix ;; #( - *) : - ;; -esac -fi - - -as_nl=' -' -export as_nl -# Printing a long string crashes Solaris 7 /usr/bin/printf. -as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo -# Prefer a ksh shell builtin over an external printf program on Solaris, -# but without wasting forks for bash or zsh. -if test -z "$BASH_VERSION$ZSH_VERSION" \ - && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='print -r --' - as_echo_n='print -rn --' -elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='printf %s\n' - as_echo_n='printf %s' -else - if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then - as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' - as_echo_n='/usr/ucb/echo -n' - else - as_echo_body='eval expr "X$1" : "X\\(.*\\)"' - as_echo_n_body='eval - arg=$1; - case $arg in #( - *"$as_nl"*) - expr "X$arg" : "X\\(.*\\)$as_nl"; - arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; - esac; - expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" - ' - export as_echo_n_body - as_echo_n='sh -c $as_echo_n_body as_echo' - fi - export as_echo_body - as_echo='sh -c $as_echo_body as_echo' -fi - -# The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then - PATH_SEPARATOR=: - (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { - (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || - PATH_SEPARATOR=';' - } +elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then + set -o posix fi +DUALCASE=1; export DUALCASE # for MKS sh +# Support unset when possible. +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# Work around bugs in pre-3.0 UWIN ksh. +$as_unset ENV MAIL MAILPATH +PS1='$ ' +PS2='> ' +PS4='+ ' -# IFS -# We need space, tab and new line, in precisely that order. Quoting is -# there to prevent editors from complaining about space-tab. -# (If _AS_PATH_WALK were called with IFS unset, it would disable word -# splitting by setting IFS to empty value.) -IFS=" "" $as_nl" - -# Find who we are. Look in the path if we contain no directory separator. -as_myself= -case $0 in #(( - *[\\/]* ) as_myself=$0 ;; - *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break - done -IFS=$as_save_IFS - - ;; -esac -# We did not find ourselves, most probably we were run as `sh COMMAND' -# in which case we are not to be found in the path. -if test "x$as_myself" = x; then - as_myself=$0 -fi -if test ! -f "$as_myself"; then - $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 - exit 1 -fi - -# Unset variables that we do not need and which cause bugs (e.g. in -# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" -# suppresses any "Segmentation fault" message there. '((' could -# trigger a bug in pdksh 5.2.14. -for as_var in BASH_ENV ENV MAIL MAILPATH -do eval test x\${$as_var+set} = xset \ - && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : -done -PS1='$ ' -PS2='> ' -PS4='+ ' - -# NLS nuisances. -LC_ALL=C -export LC_ALL -LANGUAGE=C -export LANGUAGE - -# CDPATH. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH - - -# as_fn_error STATUS ERROR [LINENO LOG_FD] -# ---------------------------------------- -# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are -# provided, also output the error to LOG_FD, referencing LINENO. Then exit the -# script with STATUS, using 1 if that was 0. -as_fn_error () -{ - as_status=$1; test $as_status -eq 0 && as_status=1 - if test "$4"; then - as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 - fi - $as_echo "$as_me: error: $2" >&2 - as_fn_exit $as_status -} # as_fn_error - - -# as_fn_set_status STATUS -# ----------------------- -# Set $? to STATUS, without forking. -as_fn_set_status () -{ - return $1 -} # as_fn_set_status - -# as_fn_exit STATUS -# ----------------- -# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. -as_fn_exit () -{ - set +e - as_fn_set_status $1 - exit $1 -} # as_fn_exit - -# as_fn_unset VAR -# --------------- -# Portably unset VAR. -as_fn_unset () -{ - { eval $1=; unset $1;} -} -as_unset=as_fn_unset -# as_fn_append VAR VALUE -# ---------------------- -# Append the text in VALUE to the end of the definition contained in VAR. Take -# advantage of any shell optimizations that allow amortized linear growth over -# repeated appends, instead of the typical quadratic growth present in naive -# implementations. -if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : - eval 'as_fn_append () - { - eval $1+=\$2 - }' -else - as_fn_append () - { - eval $1=\$$1\$2 - } -fi # as_fn_append - -# as_fn_arith ARG... -# ------------------ -# Perform arithmetic evaluation on the ARGs, and store the result in the -# global $as_val. Take advantage of shells that can avoid forks. The arguments -# must be portable across $(()) and expr. -if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : - eval 'as_fn_arith () - { - as_val=$(( $* )) - }' -else - as_fn_arith () - { - as_val=`expr "$@" || test $? -eq 1` - } -fi # as_fn_arith - +# NLS nuisances. +for as_var in \ + LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ + LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ + LC_TELEPHONE LC_TIME +do + if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + $as_unset $as_var + fi +done -if expr a : '\(a\)' >/dev/null 2>&1 && - test "X`expr 00001 : '.*\(...\)'`" = X001; then +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1; then as_expr=expr else as_expr=false fi -if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then +if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi -if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then - as_dirname=dirname -else - as_dirname=false -fi -as_me=`$as_basename -- "$0" || +# Name of the executable. +as_me=`$as_basename "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X/"$0" | - sed '/^.*\/\([^/][^/]*\)\/*$/{ - s//\1/ - q - } - /^X\/\(\/\/\)$/{ - s//\1/ - q - } - /^X\/\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` + X"$0" : 'X\(/\)$' \| \ + . : '\(.\)' 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } + /^X\/\(\/\/\)$/{ s//\1/; q; } + /^X\/\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + +# PATH needs CR, and LINENO needs CR and PATH. # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' @@ -10956,111 +19504,148 @@ as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits -ECHO_C= ECHO_N= ECHO_T= -case `echo -n x` in #((((( --n*) - case `echo 'xy\c'` in - *c*) ECHO_T=' ';; # ECHO_T is single tab character. - xy) ECHO_C='\c';; - *) echo `echo ksh88 bug on AIX 6.1` > /dev/null - ECHO_T=' ';; - esac;; -*) - ECHO_N='-n';; -esac - -rm -f conf$$ conf$$.exe conf$$.file -if test -d conf$$.dir; then - rm -f conf$$.dir/conf$$.file -else - rm -f conf$$.dir - mkdir conf$$.dir 2>/dev/null -fi -if (echo >conf$$.file) 2>/dev/null; then - if ln -s conf$$.file conf$$ 2>/dev/null; then - as_ln_s='ln -s' - # ... but there are two gotchas: - # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. - # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. - # In both cases, we have to default to `cp -pR'. - ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || - as_ln_s='cp -pR' - elif ln conf$$.file conf$$ 2>/dev/null; then - as_ln_s=ln +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' else - as_ln_s='cp -pR' + PATH_SEPARATOR=: fi -else - as_ln_s='cp -pR' + rm -f conf$$.sh fi -rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file -rmdir conf$$.dir 2>/dev/null -# as_fn_mkdir_p -# ------------- -# Create "$as_dir" as a directory, including parents if necessary. -as_fn_mkdir_p () -{ + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" || { + # Find who we are. Look in the path if we contain no path at all + # relative or not. + case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done - case $as_dir in #( - -*) as_dir=./$as_dir;; + ;; esac - test -d "$as_dir" || eval $as_mkdir_p || { - as_dirs= - while :; do - case $as_dir in #( - *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( - *) as_qdir=$as_dir;; - esac - as_dirs="'$as_qdir' $as_dirs" - as_dir=`$as_dirname -- "$as_dir" || -$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$as_dir" : 'X\(//\)[^/]' \| \ - X"$as_dir" : 'X\(//\)$' \| \ - X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$as_dir" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - test -d "$as_dir" && break - done - test -z "$as_dirs" || eval "mkdir $as_dirs" - } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + # We did not find ourselves, most probably we were run as `sh COMMAND' + # in which case we are not to be found in the path. + if test "x$as_myself" = x; then + as_myself=$0 + fi + if test ! -f "$as_myself"; then + { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5 +echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;} + { (exit 1); exit 1; }; } + fi + case $CONFIG_SHELL in + '') + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for as_base in sh bash ksh sh5; do + case $as_dir in + /*) + if ("$as_dir/$as_base" -c ' + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then + $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } + $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } + CONFIG_SHELL=$as_dir/$as_base + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$0" ${1+"$@"} + fi;; + esac + done +done +;; + esac + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line before each line; the second 'sed' does the real + # work. The second script uses 'N' to pair each line-number line + # with the numbered line, and appends trailing '-' during + # substitution so that $LINENO is not a special case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) + sed '=' <$as_myself | + sed ' + N + s,$,-, + : loop + s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, + t loop + s,-$,, + s,^['$as_cr_digits']*\n,, + ' >$as_me.lineno && + chmod +x $as_me.lineno || + { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5 +echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;} + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensible to this). + . ./$as_me.lineno + # Exit status is that of the last command. + exit +} + + +case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in + *c*,-n*) ECHO_N= ECHO_C=' +' ECHO_T=' ' ;; + *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; + *) ECHO_N= ECHO_C='\c' ECHO_T= ;; +esac + +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi +rm -f conf$$ conf$$.exe conf$$.file +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + # We could just check for DJGPP; but this test a) works b) is more generic + # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). + if test -f conf$$.exe; then + # Don't use ln at all; we don't have any links + as_ln_s='cp -p' + else + as_ln_s='ln -s' + fi +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.file -} # as_fn_mkdir_p if mkdir -p . 2>/dev/null; then - as_mkdir_p='mkdir -p "$as_dir"' + as_mkdir_p=: else test -d ./-p && rmdir ./-p as_mkdir_p=false fi - -# as_fn_executable_p FILE -# ----------------------- -# Test if FILE is an executable regular file. -as_fn_executable_p () -{ - test -f "$1" && test -x "$1" -} # as_fn_executable_p -as_test_x='test -x' -as_executable_p=as_fn_executable_p +as_executable_p="test -f" # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" @@ -11069,20 +19654,31 @@ as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" +# IFS +# We need space, tab and new line, in precisely that order. +as_nl=' +' +IFS=" $as_nl" + +# CDPATH. +$as_unset CDPATH + exec 6>&1 -## ----------------------------------- ## -## Main body of $CONFIG_STATUS script. ## -## ----------------------------------- ## -_ASEOF -test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -# Save the log message, to keep $0 and so on meaningful, and to + +# Open the log real soon, to keep \$[0] and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their -# values after options handling. -ac_log=" +# values after options handling. Logging --version etc. is OK. +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX +} >&5 +cat >&5 <<_CSEOF + This file was extended by tcl $as_me 8.6, which was -generated by GNU Autoconf 2.69. Invocation command line was +generated by GNU Autoconf 2.59. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS @@ -11090,41 +19686,43 @@ generated by GNU Autoconf 2.69. Invocation command line was CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ -on `(hostname || uname -n) 2>/dev/null | sed 1q` -" - +_CSEOF +echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5 +echo >&5 _ACEOF -case $ac_config_files in *" -"*) set x $ac_config_files; shift; ac_config_files=$*;; -esac +# Files that config.status was made for. +if test -n "$ac_config_files"; then + echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS +fi +if test -n "$ac_config_headers"; then + echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS +fi +if test -n "$ac_config_links"; then + echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS +fi -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -# Files that config.status was made for. -config_files="$ac_config_files" -config_commands="$ac_config_commands" +if test -n "$ac_config_commands"; then + echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS +fi -_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ac_cs_usage="\ -\`$as_me' instantiates files and other configuration actions -from templates according to the current configuration. Unless the files -and actions are specified as TAGs, all are instantiated by default. +\`$as_me' instantiates files from templates according to the +current configuration. -Usage: $0 [OPTION]... [TAG]... +Usage: $0 [OPTIONS] [FILE]... -h, --help print this help, then exit - -V, --version print version number and configuration settings, then exit - --config print configuration, then exit - -q, --quiet, --silent - do not print progress messages + -V, --version print version number, then exit + -q, --quiet do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions - --file=FILE[:TEMPLATE] - instantiate the configuration file FILE + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE Configuration files: $config_files @@ -11132,78 +19730,83 @@ $config_files Configuration commands: $config_commands -Report bugs to the package provider." - +Report bugs to ." _ACEOF -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" + +cat >>$CONFIG_STATUS <<_ACEOF ac_cs_version="\\ tcl config.status 8.6 -configured by $0, generated by GNU Autoconf 2.69, - with options \\"\$ac_cs_config\\" +configured by $0, generated by GNU Autoconf 2.59, + with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\" -Copyright (C) 2012 Free Software Foundation, Inc. +Copyright (C) 2003 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." - -ac_pwd='$ac_pwd' -srcdir='$srcdir' -test -n "\$AWK" || AWK=awk +srcdir=$srcdir _ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -# The default lists apply if the user does not specify any file. +cat >>$CONFIG_STATUS <<\_ACEOF +# If no file are specified by the user, then we need to provide default +# value. By we need to know if files were specified by the user. ac_need_defaults=: while test $# != 0 do case $1 in - --*=?*) - ac_option=`expr "X$1" : 'X\([^=]*\)='` - ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` - ac_shift=: - ;; - --*=) - ac_option=`expr "X$1" : 'X\([^=]*\)='` - ac_optarg= + --*=*) + ac_option=`expr "x$1" : 'x\([^=]*\)='` + ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'` ac_shift=: ;; - *) + -*) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; + *) # This is not an option, so the user has probably given explicit + # arguments. + ac_option=$1 + ac_need_defaults=false;; esac case $ac_option in # Handling of the options. +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; - --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) - $as_echo "$ac_cs_version"; exit ;; - --config | --confi | --conf | --con | --co | --c ) - $as_echo "$ac_cs_config"; exit ;; - --debug | --debu | --deb | --de | --d | -d ) + --version | --vers* | -V ) + echo "$ac_cs_version"; exit 0 ;; + --he | --h) + # Conflict between --help and --header + { { echo "$as_me:$LINENO: error: ambiguous option: $1 +Try \`$0 --help' for more information." >&5 +echo "$as_me: error: ambiguous option: $1 +Try \`$0 --help' for more information." >&2;} + { (exit 1); exit 1; }; };; + --help | --hel | -h ) + echo "$ac_cs_usage"; exit 0 ;; + --debug | --d* | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift - case $ac_optarg in - *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; - '') as_fn_error $? "missing file argument" ;; - esac - as_fn_append CONFIG_FILES " '$ac_optarg'" + CONFIG_FILES="$CONFIG_FILES $ac_optarg" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg" ac_need_defaults=false;; - --he | --h | --help | --hel | -h ) - $as_echo "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. - -*) as_fn_error $? "unrecognized option: \`$1' -Try \`$0 --help' for more information." ;; + -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&5 +echo "$as_me: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&2;} + { (exit 1); exit 1; }; } ;; - *) as_fn_append ac_config_targets " $1" - ac_need_defaults=false ;; + *) ac_config_targets="$ac_config_targets $1" ;; esac shift @@ -11217,55 +19820,43 @@ if $ac_cs_silent; then fi _ACEOF -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +cat >>$CONFIG_STATUS <<_ACEOF if \$ac_cs_recheck; then - set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion - shift - \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 - CONFIG_SHELL='$SHELL' - export CONFIG_SHELL - exec "\$@" + echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6 + exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion fi _ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -exec 5>>config.log -{ - echo - sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX -## Running $as_me. ## -_ASBOX - $as_echo "$ac_log" -} >&5 -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +cat >>$CONFIG_STATUS <<_ACEOF # -# INIT-COMMANDS +# INIT-COMMANDS section. # + VERSION=${TCL_VERSION} _ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -# Handling of arguments. + +cat >>$CONFIG_STATUS <<\_ACEOF for ac_config_target in $ac_config_targets do - case $ac_config_target in - "Tcl-Info.plist") CONFIG_FILES="$CONFIG_FILES Tcl-Info.plist:../macosx/Tcl-Info.plist.in" ;; - "Tclsh-Info.plist") CONFIG_FILES="$CONFIG_FILES Tclsh-Info.plist:../macosx/Tclsh-Info.plist.in" ;; - "Tcl.framework") CONFIG_COMMANDS="$CONFIG_COMMANDS Tcl.framework" ;; - "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile:../unix/Makefile.in" ;; - "dltest/Makefile") CONFIG_FILES="$CONFIG_FILES dltest/Makefile:../unix/dltest/Makefile.in" ;; - "tclConfig.sh") CONFIG_FILES="$CONFIG_FILES tclConfig.sh:../unix/tclConfig.sh.in" ;; - "tcl.pc") CONFIG_FILES="$CONFIG_FILES tcl.pc:../unix/tcl.pc.in" ;; - - *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; + case "$ac_config_target" in + # Handling of arguments. + "Tcl-Info.plist" ) CONFIG_FILES="$CONFIG_FILES Tcl-Info.plist:../macosx/Tcl-Info.plist.in" ;; + "Tclsh-Info.plist" ) CONFIG_FILES="$CONFIG_FILES Tclsh-Info.plist:../macosx/Tclsh-Info.plist.in" ;; + "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile:../unix/Makefile.in" ;; + "dltest/Makefile" ) CONFIG_FILES="$CONFIG_FILES dltest/Makefile:../unix/dltest/Makefile.in" ;; + "tclConfig.sh" ) CONFIG_FILES="$CONFIG_FILES tclConfig.sh:../unix/tclConfig.sh.in" ;; + "tcl.pc" ) CONFIG_FILES="$CONFIG_FILES tcl.pc:../unix/tcl.pc.in" ;; + "Tcl.framework" ) CONFIG_COMMANDS="$CONFIG_COMMANDS Tcl.framework" ;; + *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 +echo "$as_me: error: invalid argument: $ac_config_target" >&2;} + { (exit 1); exit 1; }; };; esac done - # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely @@ -11276,427 +19867,533 @@ if $ac_need_defaults; then fi # Have a temporary directory for convenience. Make it in the build tree -# simply because there is no reason against having it here, and in addition, +# simply because there is no reason to put it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. -# Hook for its removal unless debugging. -# Note that there is a small window in which the directory will not be cleaned: -# after its creation but before its name has been assigned to `$tmp'. +# Create a temporary directory, and hook for its removal unless debugging. $debug || { - tmp= ac_tmp= - trap 'exit_status=$? - : "${ac_tmp:=$tmp}" - { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status -' 0 - trap 'as_fn_exit 1' 1 2 13 15 + trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0 + trap '{ (exit 1); exit 1; }' 1 2 13 15 } + # Create a (secure) tmp directory for tmp files. { - tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && - test -d "$tmp" + tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` && + test -n "$tmp" && test -d "$tmp" } || { - tmp=./conf$$-$RANDOM - (umask 077 && mkdir "$tmp") -} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 -ac_tmp=$tmp - -# Set up the scripts for CONFIG_FILES section. -# No need to generate them if there are no CONFIG_FILES. -# This happens for instance with `./config.status config.h'. -if test -n "$CONFIG_FILES"; then - - -ac_cr=`echo X | tr X '\015'` -# On cygwin, bash can eat \r inside `` if the user requested igncr. -# But we know of no other shell where ac_cr would be empty at this -# point, so we can use a bashism as a fallback. -if test "x$ac_cr" = x; then - eval ac_cr=\$\'\\r\' -fi -ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` -if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then - ac_cs_awk_cr='\\r' -else - ac_cs_awk_cr=$ac_cr -fi - -echo 'BEGIN {' >"$ac_tmp/subs1.awk" && -_ACEOF - - + tmp=./confstat$$-$RANDOM + (umask 077 && mkdir $tmp) +} || { - echo "cat >conf$$subs.awk <<_ACEOF" && - echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && - echo "_ACEOF" -} >conf$$subs.sh || - as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 -ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` -ac_delim='%!_!# ' -for ac_last_try in false false false false false :; do - . ./conf$$subs.sh || - as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 - - ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` - if test $ac_delim_n = $ac_delim_num; then - break - elif $ac_last_try; then - as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 - else - ac_delim="$ac_delim!$ac_delim _$ac_delim!! " - fi -done -rm -f conf$$subs.sh - -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && -_ACEOF -sed -n ' -h -s/^/S["/; s/!.*/"]=/ -p -g -s/^[^!]*!// -:repl -t repl -s/'"$ac_delim"'$// -t delim -:nl -h -s/\(.\{148\}\)..*/\1/ -t more1 -s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ -p -n -b repl -:more1 -s/["\\]/\\&/g; s/^/"/; s/$/"\\/ -p -g -s/.\{148\}// -t nl -:delim -h -s/\(.\{148\}\)..*/\1/ -t more2 -s/["\\]/\\&/g; s/^/"/; s/$/"/ -p -b -:more2 -s/["\\]/\\&/g; s/^/"/; s/$/"\\/ -p -g -s/.\{148\}// -t delim -' >$CONFIG_STATUS || ac_write_fail=1 -rm -f conf$$subs.awk -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -_ACAWK -cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && - for (key in S) S_is_set[key] = 1 - FS = "" - -} -{ - line = $ 0 - nfields = split(line, field, "@") - substed = 0 - len = length(field[1]) - for (i = 2; i < nfields; i++) { - key = field[i] - keylen = length(key) - if (S_is_set[key]) { - value = S[key] - line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) - len += length(value) + length(field[++i]) - substed = 1 - } else - len += 1 + keylen - } - - print line + echo "$me: cannot create a temporary directory in ." >&2 + { (exit 1); exit 1; } } -_ACAWK -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then - sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" -else - cat -fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ - || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 _ACEOF -# VPATH may cause trouble with some makes, so we remove sole $(srcdir), -# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and -# trailing colons and then remove the whole line if VPATH becomes empty -# (actually we leave an empty line to preserve line numbers). -if test "x$srcdir" = x.; then - ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ -h -s/// -s/^/:/ -s/[ ]*$/:/ -s/:\$(srcdir):/:/g -s/:\${srcdir}:/:/g -s/:@srcdir@:/:/g -s/^:*// -s/:*$// -x -s/\(=[ ]*\).*/\1/ -G -s/\n// -s/^[^=]*=[ ]*$// -}' -fi - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -fi # test -n "$CONFIG_FILES" +cat >>$CONFIG_STATUS <<_ACEOF +# +# CONFIG_FILES section. +# -eval set X " :F $CONFIG_FILES :C $CONFIG_COMMANDS" -shift -for ac_tag -do - case $ac_tag in - :[FHLC]) ac_mode=$ac_tag; continue;; - esac - case $ac_mode$ac_tag in - :[FHL]*:*);; - :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; - :[FH]-) ac_tag=-:-;; - :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; - esac - ac_save_IFS=$IFS - IFS=: - set x $ac_tag - IFS=$ac_save_IFS - shift - ac_file=$1 - shift +# No need to generate the scripts if there are no CONFIG_FILES. +# This happens for instance when ./config.status config.h +if test -n "\$CONFIG_FILES"; then + # Protect against being on the right side of a sed subst in config.status. + sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g; + s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF +s,@SHELL@,$SHELL,;t t +s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t +s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t +s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t +s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t +s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t +s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t +s,@exec_prefix@,$exec_prefix,;t t +s,@prefix@,$prefix,;t t +s,@program_transform_name@,$program_transform_name,;t t +s,@bindir@,$bindir,;t t +s,@sbindir@,$sbindir,;t t +s,@libexecdir@,$libexecdir,;t t +s,@datadir@,$datadir,;t t +s,@sysconfdir@,$sysconfdir,;t t +s,@sharedstatedir@,$sharedstatedir,;t t +s,@localstatedir@,$localstatedir,;t t +s,@libdir@,$libdir,;t t +s,@includedir@,$includedir,;t t +s,@oldincludedir@,$oldincludedir,;t t +s,@infodir@,$infodir,;t t +s,@mandir@,$mandir,;t t +s,@build_alias@,$build_alias,;t t +s,@host_alias@,$host_alias,;t t +s,@target_alias@,$target_alias,;t t +s,@DEFS@,$DEFS,;t t +s,@ECHO_C@,$ECHO_C,;t t +s,@ECHO_N@,$ECHO_N,;t t +s,@ECHO_T@,$ECHO_T,;t t +s,@LIBS@,$LIBS,;t t +s,@MAN_FLAGS@,$MAN_FLAGS,;t t +s,@CC@,$CC,;t t +s,@CFLAGS@,$CFLAGS,;t t +s,@LDFLAGS@,$LDFLAGS,;t t +s,@CPPFLAGS@,$CPPFLAGS,;t t +s,@ac_ct_CC@,$ac_ct_CC,;t t +s,@EXEEXT@,$EXEEXT,;t t +s,@OBJEXT@,$OBJEXT,;t t +s,@CPP@,$CPP,;t t +s,@EGREP@,$EGREP,;t t +s,@TCL_THREADS@,$TCL_THREADS,;t t +s,@TCLSH_PROG@,$TCLSH_PROG,;t t +s,@ZLIB_OBJS@,$ZLIB_OBJS,;t t +s,@ZLIB_SRCS@,$ZLIB_SRCS,;t t +s,@ZLIB_INCLUDE@,$ZLIB_INCLUDE,;t t +s,@RANLIB@,$RANLIB,;t t +s,@ac_ct_RANLIB@,$ac_ct_RANLIB,;t t +s,@AR@,$AR,;t t +s,@ac_ct_AR@,$ac_ct_AR,;t t +s,@LIBOBJS@,$LIBOBJS,;t t +s,@TCL_LIBS@,$TCL_LIBS,;t t +s,@DL_LIBS@,$DL_LIBS,;t t +s,@DL_OBJS@,$DL_OBJS,;t t +s,@PLAT_OBJS@,$PLAT_OBJS,;t t +s,@PLAT_SRCS@,$PLAT_SRCS,;t t +s,@LDAIX_SRC@,$LDAIX_SRC,;t t +s,@CFLAGS_DEBUG@,$CFLAGS_DEBUG,;t t +s,@CFLAGS_OPTIMIZE@,$CFLAGS_OPTIMIZE,;t t +s,@CFLAGS_WARNING@,$CFLAGS_WARNING,;t t +s,@LDFLAGS_DEBUG@,$LDFLAGS_DEBUG,;t t +s,@LDFLAGS_OPTIMIZE@,$LDFLAGS_OPTIMIZE,;t t +s,@CC_SEARCH_FLAGS@,$CC_SEARCH_FLAGS,;t t +s,@LD_SEARCH_FLAGS@,$LD_SEARCH_FLAGS,;t t +s,@STLIB_LD@,$STLIB_LD,;t t +s,@SHLIB_LD@,$SHLIB_LD,;t t +s,@TCL_SHLIB_LD_EXTRAS@,$TCL_SHLIB_LD_EXTRAS,;t t +s,@TK_SHLIB_LD_EXTRAS@,$TK_SHLIB_LD_EXTRAS,;t t +s,@SHLIB_LD_LIBS@,$SHLIB_LD_LIBS,;t t +s,@SHLIB_CFLAGS@,$SHLIB_CFLAGS,;t t +s,@SHLIB_SUFFIX@,$SHLIB_SUFFIX,;t t +s,@MAKE_LIB@,$MAKE_LIB,;t t +s,@MAKE_STUB_LIB@,$MAKE_STUB_LIB,;t t +s,@INSTALL_LIB@,$INSTALL_LIB,;t t +s,@DLL_INSTALL_DIR@,$DLL_INSTALL_DIR,;t t +s,@INSTALL_STUB_LIB@,$INSTALL_STUB_LIB,;t t +s,@CFLAGS_DEFAULT@,$CFLAGS_DEFAULT,;t t +s,@LDFLAGS_DEFAULT@,$LDFLAGS_DEFAULT,;t t +s,@DTRACE@,$DTRACE,;t t +s,@TCL_VERSION@,$TCL_VERSION,;t t +s,@TCL_MAJOR_VERSION@,$TCL_MAJOR_VERSION,;t t +s,@TCL_MINOR_VERSION@,$TCL_MINOR_VERSION,;t t +s,@TCL_PATCH_LEVEL@,$TCL_PATCH_LEVEL,;t t +s,@TCL_YEAR@,$TCL_YEAR,;t t +s,@PKG_CFG_ARGS@,$PKG_CFG_ARGS,;t t +s,@TCL_LIB_FILE@,$TCL_LIB_FILE,;t t +s,@TCL_LIB_FLAG@,$TCL_LIB_FLAG,;t t +s,@TCL_LIB_SPEC@,$TCL_LIB_SPEC,;t t +s,@TCL_STUB_LIB_FILE@,$TCL_STUB_LIB_FILE,;t t +s,@TCL_STUB_LIB_FLAG@,$TCL_STUB_LIB_FLAG,;t t +s,@TCL_STUB_LIB_SPEC@,$TCL_STUB_LIB_SPEC,;t t +s,@TCL_STUB_LIB_PATH@,$TCL_STUB_LIB_PATH,;t t +s,@TCL_INCLUDE_SPEC@,$TCL_INCLUDE_SPEC,;t t +s,@TCL_BUILD_STUB_LIB_SPEC@,$TCL_BUILD_STUB_LIB_SPEC,;t t +s,@TCL_BUILD_STUB_LIB_PATH@,$TCL_BUILD_STUB_LIB_PATH,;t t +s,@TCL_SRC_DIR@,$TCL_SRC_DIR,;t t +s,@CFG_TCL_SHARED_LIB_SUFFIX@,$CFG_TCL_SHARED_LIB_SUFFIX,;t t +s,@CFG_TCL_UNSHARED_LIB_SUFFIX@,$CFG_TCL_UNSHARED_LIB_SUFFIX,;t t +s,@TCL_SHARED_BUILD@,$TCL_SHARED_BUILD,;t t +s,@LD_LIBRARY_PATH_VAR@,$LD_LIBRARY_PATH_VAR,;t t +s,@TCL_BUILD_LIB_SPEC@,$TCL_BUILD_LIB_SPEC,;t t +s,@TCL_LIB_VERSIONS_OK@,$TCL_LIB_VERSIONS_OK,;t t +s,@TCL_SHARED_LIB_SUFFIX@,$TCL_SHARED_LIB_SUFFIX,;t t +s,@TCL_UNSHARED_LIB_SUFFIX@,$TCL_UNSHARED_LIB_SUFFIX,;t t +s,@TCL_HAS_LONGLONG@,$TCL_HAS_LONGLONG,;t t +s,@INSTALL_TZDATA@,$INSTALL_TZDATA,;t t +s,@DTRACE_SRC@,$DTRACE_SRC,;t t +s,@DTRACE_HDR@,$DTRACE_HDR,;t t +s,@DTRACE_OBJ@,$DTRACE_OBJ,;t t +s,@MAKEFILE_SHELL@,$MAKEFILE_SHELL,;t t +s,@BUILD_DLTEST@,$BUILD_DLTEST,;t t +s,@TCL_PACKAGE_PATH@,$TCL_PACKAGE_PATH,;t t +s,@TCL_MODULE_PATH@,$TCL_MODULE_PATH,;t t +s,@TCL_LIBRARY@,$TCL_LIBRARY,;t t +s,@PRIVATE_INCLUDE_DIR@,$PRIVATE_INCLUDE_DIR,;t t +s,@HTML_DIR@,$HTML_DIR,;t t +s,@PACKAGE_DIR@,$PACKAGE_DIR,;t t +s,@EXTRA_CC_SWITCHES@,$EXTRA_CC_SWITCHES,;t t +s,@EXTRA_APP_CC_SWITCHES@,$EXTRA_APP_CC_SWITCHES,;t t +s,@EXTRA_INSTALL@,$EXTRA_INSTALL,;t t +s,@EXTRA_INSTALL_BINARIES@,$EXTRA_INSTALL_BINARIES,;t t +s,@EXTRA_BUILD_HTML@,$EXTRA_BUILD_HTML,;t t +s,@EXTRA_TCLSH_LIBS@,$EXTRA_TCLSH_LIBS,;t t +s,@DLTEST_LD@,$DLTEST_LD,;t t +s,@DLTEST_SUFFIX@,$DLTEST_SUFFIX,;t t +CEOF - case $ac_mode in - :L) ac_source=$1;; - :[FH]) - ac_file_inputs= - for ac_f - do - case $ac_f in - -) ac_f="$ac_tmp/stdin";; - *) # Look for the file first in the build tree, then in the source tree - # (if the path is not absolute). The absolute path cannot be DOS-style, - # because $ac_f cannot contain `:'. - test -f "$ac_f" || - case $ac_f in - [\\/$]*) false;; - *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; - esac || - as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; - esac - case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac - as_fn_append ac_file_inputs " '$ac_f'" - done +_ACEOF - # Let's still pretend it is `configure' which instantiates (i.e., don't - # use $as_me), people would be surprised to read: - # /* config.h. Generated by config.status. */ - configure_input='Generated from '` - $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' - `' by configure.' - if test x"$ac_file" != x-; then - configure_input="$ac_file. $configure_input" - { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 -$as_echo "$as_me: creating $ac_file" >&6;} + cat >>$CONFIG_STATUS <<\_ACEOF + # Split the substitutions into bite-sized pieces for seds with + # small command number limits, like on Digital OSF/1 and HP-UX. + ac_max_sed_lines=48 + ac_sed_frag=1 # Number of current file. + ac_beg=1 # First line for current file. + ac_end=$ac_max_sed_lines # Line after last line for current file. + ac_more_lines=: + ac_sed_cmds= + while $ac_more_lines; do + if test $ac_beg -gt 1; then + sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag + else + sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag fi - # Neutralize special characters interpreted by sed in replacement strings. - case $configure_input in #( - *\&* | *\|* | *\\* ) - ac_sed_conf_input=`$as_echo "$configure_input" | - sed 's/[\\\\&|]/\\\\&/g'`;; #( - *) ac_sed_conf_input=$configure_input;; - esac + if test ! -s $tmp/subs.frag; then + ac_more_lines=false + else + # The purpose of the label and of the branching condition is to + # speed up the sed processing (if there are no `@' at all, there + # is no need to browse any of the substitutions). + # These are the two extra sed commands mentioned above. + (echo ':t + /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed + if test -z "$ac_sed_cmds"; then + ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed" + else + ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed" + fi + ac_sed_frag=`expr $ac_sed_frag + 1` + ac_beg=$ac_end + ac_end=`expr $ac_end + $ac_max_sed_lines` + fi + done + if test -z "$ac_sed_cmds"; then + ac_sed_cmds=cat + fi +fi # test -n "$CONFIG_FILES" - case $ac_tag in - *:-:* | *:-) cat >"$ac_tmp/stdin" \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; - esac - ;; +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF +for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case $ac_file in + - | *:- | *:-:* ) # input from stdin + cat >$tmp/stdin + ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + * ) ac_file_in=$ac_file.in ;; esac - ac_dir=`$as_dirname -- "$ac_file" || + # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories. + ac_dir=`(dirname "$ac_file") 2>/dev/null || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ - X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$ac_file" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - as_dir="$ac_dir"; as_fn_mkdir_p + X"$ac_file" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + { if $as_mkdir_p; then + mkdir -p "$ac_dir" + else + as_dir="$ac_dir" + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`(dirname "$as_dir") 2>/dev/null || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 +echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} + { (exit 1); exit 1; }; }; } + ac_builddir=. -case "$ac_dir" in -.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; -*) - ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` - # A ".." for each directory in $ac_dir_suffix. - ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` - case $ac_top_builddir_sub in - "") ac_top_builddir_sub=. ac_top_build_prefix= ;; - *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; - esac ;; -esac -ac_abs_top_builddir=$ac_pwd -ac_abs_builddir=$ac_pwd$ac_dir_suffix -# for backward compatibility: -ac_top_builddir=$ac_top_build_prefix +if test "$ac_dir" != .; then + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A "../" for each directory in $ac_dir_suffix. + ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` +else + ac_dir_suffix= ac_top_builddir= +fi case $srcdir in - .) # We are building in place. + .) # No --srcdir option. We are building in place. ac_srcdir=. - ac_top_srcdir=$ac_top_builddir_sub - ac_abs_top_srcdir=$ac_pwd ;; - [\\/]* | ?:[\\/]* ) # Absolute name. + if test -z "$ac_top_builddir"; then + ac_top_srcdir=. + else + ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` + fi ;; + [\\/]* | ?:[\\/]* ) # Absolute path. ac_srcdir=$srcdir$ac_dir_suffix; - ac_top_srcdir=$srcdir - ac_abs_top_srcdir=$srcdir ;; - *) # Relative name. - ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix - ac_top_srcdir=$ac_top_build_prefix$srcdir - ac_abs_top_srcdir=$ac_pwd/$srcdir ;; + ac_top_srcdir=$srcdir ;; + *) # Relative path. + ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_builddir$srcdir ;; +esac + +# Do not use `cd foo && pwd` to compute absolute paths, because +# the directories may not exist. +case `pwd` in +.) ac_abs_builddir="$ac_dir";; +*) + case "$ac_dir" in + .) ac_abs_builddir=`pwd`;; + [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; + *) ac_abs_builddir=`pwd`/"$ac_dir";; + esac;; esac -ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix - - - case $ac_mode in - :F) - # - # CONFIG_FILE - # - -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -# If the template does not know about datarootdir, expand it. -# FIXME: This hack should be removed a few years after 2.60. -ac_datarootdir_hack=; ac_datarootdir_seen= -ac_sed_dataroot=' -/datarootdir/ { - p - q -} -/@datadir@/p -/@docdir@/p -/@infodir@/p -/@localedir@/p -/@mandir@/p' -case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in -*datarootdir*) ac_datarootdir_seen=yes;; -*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 -$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 - ac_datarootdir_hack=' - s&@datadir@&$datadir&g - s&@docdir@&$docdir&g - s&@infodir@&$infodir&g - s&@localedir@&$localedir&g - s&@mandir@&$mandir&g - s&\\\${datarootdir}&$datarootdir&g' ;; +case $ac_abs_builddir in +.) ac_abs_top_builddir=${ac_top_builddir}.;; +*) + case ${ac_top_builddir}. in + .) ac_abs_top_builddir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; + *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_srcdir=$ac_srcdir;; +*) + case $ac_srcdir in + .) ac_abs_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; + *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_srcdir=$ac_top_srcdir;; +*) + case $ac_top_srcdir in + .) ac_abs_top_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; + *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; + esac;; esac -_ACEOF -# Neutralize VPATH when `$srcdir' = `.'. -# Shell code in configure.ac might set extrasub. -# FIXME: do we really want to maintain this feature? -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -ac_sed_extra="$ac_vpsub + + + if test x"$ac_file" != x-; then + { echo "$as_me:$LINENO: creating $ac_file" >&5 +echo "$as_me: creating $ac_file" >&6;} + rm -f "$ac_file" + fi + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + if test x"$ac_file" = x-; then + configure_input= + else + configure_input="$ac_file. " + fi + configure_input=$configure_input"Generated from `echo $ac_file_in | + sed 's,.*/,,'` by configure." + + # First look for the input files in the build tree, otherwise in the + # src tree. + ac_file_inputs=`IFS=: + for f in $ac_file_in; do + case $f in + -) echo $tmp/stdin ;; + [\\/$]*) + # Absolute (can't be DOS-style, as IFS=:) + test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + echo "$f";; + *) # Relative + if test -f "$f"; then + # Build tree + echo "$f" + elif test -f "$srcdir/$f"; then + # Source tree + echo "$srcdir/$f" + else + # /dev/null tree + { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + fi;; + esac + done` || { (exit 1); exit 1; } +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF + sed "$ac_vpsub $extrasub _ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +cat >>$CONFIG_STATUS <<\_ACEOF :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b -s|@configure_input@|$ac_sed_conf_input|;t t -s&@top_builddir@&$ac_top_builddir_sub&;t t -s&@top_build_prefix@&$ac_top_build_prefix&;t t -s&@srcdir@&$ac_srcdir&;t t -s&@abs_srcdir@&$ac_abs_srcdir&;t t -s&@top_srcdir@&$ac_top_srcdir&;t t -s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t -s&@builddir@&$ac_builddir&;t t -s&@abs_builddir@&$ac_abs_builddir&;t t -s&@abs_top_builddir@&$ac_abs_top_builddir&;t t -$ac_datarootdir_hack -" -eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ - >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 - -test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && - { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && - { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ - "$ac_tmp/out"`; test -z "$ac_out"; } && - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' -which seems to be undefined. Please make sure it is defined" >&5 -$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' -which seems to be undefined. Please make sure it is defined" >&2;} - - rm -f "$ac_tmp/stdin" - case $ac_file in - -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; - *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; - esac \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 - ;; +s,@configure_input@,$configure_input,;t t +s,@srcdir@,$ac_srcdir,;t t +s,@abs_srcdir@,$ac_abs_srcdir,;t t +s,@top_srcdir@,$ac_top_srcdir,;t t +s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t +s,@builddir@,$ac_builddir,;t t +s,@abs_builddir@,$ac_abs_builddir,;t t +s,@top_builddir@,$ac_top_builddir,;t t +s,@abs_top_builddir@,$ac_abs_top_builddir,;t t +" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out + rm -f $tmp/stdin + if test x"$ac_file" != x-; then + mv $tmp/out $ac_file + else + cat $tmp/out + rm -f $tmp/out + fi +done +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF - :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 -$as_echo "$as_me: executing $ac_file commands" >&6;} - ;; - esac +# +# CONFIG_COMMANDS section. +# +for ac_file in : $CONFIG_COMMANDS; do test "x$ac_file" = x: && continue + ac_dest=`echo "$ac_file" | sed 's,:.*,,'` + ac_source=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_dir=`(dirname "$ac_dest") 2>/dev/null || +$as_expr X"$ac_dest" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_dest" : 'X\(//\)[^/]' \| \ + X"$ac_dest" : 'X\(//\)$' \| \ + X"$ac_dest" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$ac_dest" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + { if $as_mkdir_p; then + mkdir -p "$ac_dir" + else + as_dir="$ac_dir" + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`(dirname "$as_dir") 2>/dev/null || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 +echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} + { (exit 1); exit 1; }; }; } + + ac_builddir=. + +if test "$ac_dir" != .; then + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A "../" for each directory in $ac_dir_suffix. + ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` +else + ac_dir_suffix= ac_top_builddir= +fi + +case $srcdir in + .) # No --srcdir option. We are building in place. + ac_srcdir=. + if test -z "$ac_top_builddir"; then + ac_top_srcdir=. + else + ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` + fi ;; + [\\/]* | ?:[\\/]* ) # Absolute path. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir ;; + *) # Relative path. + ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_builddir$srcdir ;; +esac + +# Do not use `cd foo && pwd` to compute absolute paths, because +# the directories may not exist. +case `pwd` in +.) ac_abs_builddir="$ac_dir";; +*) + case "$ac_dir" in + .) ac_abs_builddir=`pwd`;; + [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; + *) ac_abs_builddir=`pwd`/"$ac_dir";; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_builddir=${ac_top_builddir}.;; +*) + case ${ac_top_builddir}. in + .) ac_abs_top_builddir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; + *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_srcdir=$ac_srcdir;; +*) + case $ac_srcdir in + .) ac_abs_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; + *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_srcdir=$ac_top_srcdir;; +*) + case $ac_top_srcdir in + .) ac_abs_top_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; + *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; + esac;; +esac - case $ac_file$ac_mode in - "Tcl.framework":C) n=Tcl && + { echo "$as_me:$LINENO: executing $ac_dest commands" >&5 +echo "$as_me: executing $ac_dest commands" >&6;} + case $ac_dest in + Tcl.framework ) n=Tcl && f=$n.framework && v=Versions/$VERSION && rm -rf $f && mkdir -p $f/$v/Resources && ln -s $v/$n $v/Resources $f && ln -s ../../../$n $f/$v && ln -s ../../../../$n-Info.plist $f/$v/Resources/Info.plist && unset n f v ;; - esac -done # for ac_tag +done +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF -as_fn_exit 0 +{ (exit 0); exit 0; } _ACEOF +chmod +x $CONFIG_STATUS ac_clean_files=$ac_clean_files_save -test $ac_write_fail = 0 || - as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 - # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. @@ -11716,11 +20413,7 @@ if test "$no_create" != yes; then exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. - $ac_cs_success || as_fn_exit 1 -fi -if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 -$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} + $ac_cs_success || { (exit 1); exit 1; } fi diff --git a/unix/configure.in b/unix/configure.in index bc7bdef..85bd7ee 100644 --- a/unix/configure.in +++ b/unix/configure.in @@ -893,29 +893,6 @@ fi #-------------------------------------------------------------------- # The statements below define various symbols relating to Tcl -# core vfs and kit support. -#-------------------------------------------------------------------- - -eval "TCL_KIT_LIB_FILE=libtclkit${UNSHARED_LIB_SUFFIX}" -eval "TCL_KIT_LIB_FILE=${TCL_KIT_LIB_FILE}" - -eval "TCL_KIT_LIB_FILE=libtclkit${TCL_UNSHARED_LIB_SUFFIX}" -eval "TCL_KIT_LIB_FILE=\"${TCL_KIT_LIB_FILE}\"" -eval "TCL_KIT_LIB_DIR=${libdir}" - -if test "${TCL_LIB_VERSIONS_OK}" = "ok"; then - TCL_KIT_LIB_FLAG="-ltclkit${TCL_VERSION}" -else - TCL_KIT_LIB_FLAG="-ltclkit`echo ${TCL_VERSION} | tr -d .`" -fi - -TCL_BUILD_KIT_LIB_SPEC="-L`pwd | sed -e 's/ /\\\\ /g'` ${TCL_KIT_LIB_FLAG}" -TCL_KIT_LIB_SPEC="-L${TCL_KIT_LIB_DIR} ${TCL_KIT_LIB_FLAG}" -TCL_BUILD_KIT_LIB_PATH="`pwd`/${TCL_KIT_LIB_FILE}" -TCL_KIT_LIB_PATH="${TCL_KIT_LIB_DIR}/${TCL_KIT_LIB_FILE}" - -#-------------------------------------------------------------------- -# The statements below define various symbols relating to Tcl # stub support. #-------------------------------------------------------------------- @@ -956,24 +933,14 @@ AC_SUBST(PKG_CFG_ARGS) AC_SUBST(TCL_LIB_FILE) AC_SUBST(TCL_LIB_FLAG) AC_SUBST(TCL_LIB_SPEC) -AC_SUBST(TCL_BUILD_LIB_SPEC) - AC_SUBST(TCL_STUB_LIB_FILE) AC_SUBST(TCL_STUB_LIB_FLAG) AC_SUBST(TCL_STUB_LIB_SPEC) AC_SUBST(TCL_STUB_LIB_PATH) +AC_SUBST(TCL_INCLUDE_SPEC) AC_SUBST(TCL_BUILD_STUB_LIB_SPEC) AC_SUBST(TCL_BUILD_STUB_LIB_PATH) -AC_SUBST(TCL_KIT_LIB_FILE) -AC_SUBST(TCL_KIT_LIB_FLAG) -AC_SUBST(TCL_KIT_LIB_SPEC) -AC_SUBST(TCL_KIT_LIB_PATH) -AC_SUBST(TCL_BUILD_KIT_LIB_SPEC) -AC_SUBST(TCL_BUILD_KIT_LIB_PATH) - -AC_SUBST(TCL_INCLUDE_SPEC) - AC_SUBST(TCL_SRC_DIR) AC_SUBST(CFG_TCL_SHARED_LIB_SUFFIX) AC_SUBST(CFG_TCL_UNSHARED_LIB_SUFFIX) @@ -981,6 +948,7 @@ AC_SUBST(CFG_TCL_UNSHARED_LIB_SUFFIX) AC_SUBST(TCL_SHARED_BUILD) AC_SUBST(LD_LIBRARY_PATH_VAR) +AC_SUBST(TCL_BUILD_LIB_SPEC) AC_SUBST(TCL_LIB_VERSIONS_OK) AC_SUBST(TCL_SHARED_LIB_SUFFIX) diff --git a/unix/tcl.m4 b/unix/tcl.m4 index 88f2b81..3ca65d8 100644 --- a/unix/tcl.m4 +++ b/unix/tcl.m4 @@ -2060,14 +2060,6 @@ dnl # preprocessing tests use only CPPFLAGS. ]) ]) - AS_IF([test "$RANLIB" = ""], [ - MAKE_KIT_LIB='$(STLIB_LD) [$]@ ${TCL_OBJS} ${TOMMATH_OBJS} ${ZLIB_OBJS}' - INSTALL_KIT_LIB='$(INSTALL_LIBRARY) $(TCL_KIT_LIB_FILE) "$(LIB_INSTALL_DIR)/$(TCL_KIT_LIB_FILE)"' - ], [ - MAKE_KIT_LIB='${STLIB_LD} [$]@ ${TCL_OBJS} ${TOMMATH_OBJS} ${ZLIB_OBJS} ; ${RANLIB} [$]@' - INSTALL_KIT_LIB='$(INSTALL_LIBRARY) $(TCL_KIT_LIB_FILE) "$(LIB_INSTALL_DIR)/$(TCL_KIT_LIB_FILE)" ; (cd "$(LIB_INSTALL_DIR)" ; $(RANLIB) $(TCL_KIT_LIB_FILE))' - ]) - # Stub lib does not depend on shared/static configuration AS_IF([test "$RANLIB" = ""], [ MAKE_STUB_LIB='${STLIB_LD} [$]@ ${STUB_LIB_OBJS}' @@ -2134,12 +2126,10 @@ dnl # preprocessing tests use only CPPFLAGS. [What is the default extension for shared libraries?]) AC_SUBST(MAKE_LIB) - AC_SUBST(MAKE_KIT_LIB) AC_SUBST(MAKE_STUB_LIB) AC_SUBST(INSTALL_LIB) AC_SUBST(DLL_INSTALL_DIR) AC_SUBST(INSTALL_STUB_LIB) - AC_SUBST(INSTALL_KIT_LIB) AC_SUBST(RANLIB) ]) diff --git a/win/makefile.bc b/win/makefile.bc index e005979..57bfda0 100644 --- a/win/makefile.bc +++ b/win/makefile.bc @@ -159,6 +159,7 @@ TCLPLUGINDLLNAME = $(NAMEPREFIX)$(VERSION)p$(DBGX).dll TCLPLUGINDLL = $(OUTDIR)\$(TCLPLUGINDLLNAME) TCLSH = $(OUTDIR)\$(NAMEPREFIX)sh$(VERSION)$(DBGX).exe TCLSHP = $(OUTDIR)\$(NAMEPREFIX)shp$(VERSION)$(DBGX).exe +TCLKIT = $(OUTDIR)\$(NAMEPREFIX)kit$(VERSION)$(DBGX).exe TCLREGDLLNAME = $(NAMEPREFIX)reg$(REGVERSION)$(DBGX).dll TCLREGDLL = $(OUTDIR)\$(TCLREGDLLNAME) TCLDDEDLLNAME = $(NAMEPREFIX)dde$(DDEVERSION)$(DBGX).dll @@ -177,6 +178,10 @@ INCLUDE_INSTALL_DIR = $(INSTALLDIR)\include TCLSHOBJS = \ $(TMPDIR)\tclAppInit.obj +TCLKITOBJS = \ + $(TMP_DIR)\tclZipVfs.obj \ + $(TMPDIR)\tclKitInit.obj + TCLTESTOBJS = \ $(TMPDIR)\tclTest.obj \ $(TMPDIR)\tclTestObj.obj \ @@ -275,7 +280,6 @@ TCLOBJS = \ $(TMPDIR)\tclWinSock.obj \ $(TMPDIR)\tclWinThrd.obj \ $(TMPDIR)\tclWinTime.obj \ - $(TMP_DIR)\tclZipVfs.obj \ $(TMPDIR)\tclZlib.obj TCLSTUBOBJS = \ @@ -392,6 +396,11 @@ $(TCLTEST): $(TCLTESTOBJS) $(TCLLIB) $(TMPDIR)\$(NAMEPREFIX)sh.res $(TCLTESTOBJS), $@, -x, $(LNLIBS) $(TCLLIB),, $(TMPDIR)\$(NAMEPREFIX)sh.res ! +$(TCLKIT): $(TCLKITOBJS) $(TCLLIB) $(TMPDIR)\$(NAMEPREFIX)sh.res + $(link32) $(ldebug) -S:2400000 $(LNFLAGS) $(LNFLAGS_CONS) $(TOOLS32)\lib\c0x32 @&&! + $(TCLSHOBJS), $@, -x, $(LNLIBS) $(TCLLIB),, $(TMPDIR)\$(NAMEPREFIX)sh.res +! + $(TCLDDEDLL): $(TMPDIR)\tclWinDde.obj $(TCLSTUBLIB) $(link32) $(ldebug) $(LNFLAGS) $(LNFLAGS_DLL) $(TOOLS32)\lib\c0d32 \ $(TMPDIR)\tclWinDde.obj, $@, -x, $(LNLIBS) $(TCLSTUBLIB),, \ @@ -512,6 +521,10 @@ $(TMP_DIR)\tclPkgConfig.obj: $(GENERICDIR)\tclPkgConfig.c $(TMPDIR)\tclAppInit.obj : $(WINDIR)\tclAppInit.c $(cc32) $(TCL_CFLAGS) -o$(TMPDIR)\$@ $? +$(TMPDIR)\tclKitInit.obj : $(WINDIR)\tclAppInit.c + $(cc32) $(TCL_CFLAGS) -DDTCL_ZIPVFS -o$(TMPDIR)\$@ $? + + # The following objects should be built using the stub interfaces # tclWinReg: Produces errors in ANSI mode diff --git a/win/makefile.vc b/win/makefile.vc index 43644cc..832f6bd 100644 --- a/win/makefile.vc +++ b/win/makefile.vc @@ -209,6 +209,9 @@ TCLSTUBLIB = $(OUT_DIR)\$(TCLSTUBLIBNAME) TCLSHNAME = $(PROJECT)sh$(VERSION)$(SUFX).exe TCLSH = $(OUT_DIR)\$(TCLSHNAME) +TCLKITNAME = $(PROJECT)kit$(VERSION)$(SUFX).exe +TCLKIT = $(OUT_DIR)\$(TCLSHNAME) + TCLREGLIBNAME = $(PROJECT)reg$(REGVERSION)$(SUFX:t=).$(EXT) TCLREGLIB = $(OUT_DIR)\$(TCLREGLIBNAME) @@ -244,6 +247,18 @@ TCLSHOBJS = \ !endif $(TMP_DIR)\tclsh.res +TCLKITOBJS = \ + $(TMP_DIR)\tclKitInit.obj \ + $(TMP_DIR)\tclZipVfs.obj \ +!if !$(STATIC_BUILD) +!if $(TCL_USE_STATIC_PACKAGES) + $(TMP_DIR)\tclWinReg.obj \ + $(TMP_DIR)\tclWinDde.obj \ +!endif +!endif + $(TMP_DIR)\tclsh.res + + TCLTESTOBJS = \ $(TMP_DIR)\tclTest.obj \ $(TMP_DIR)\tclTestObj.obj \ @@ -343,7 +358,6 @@ COREOBJS = \ $(TMP_DIR)\tclUtf.obj \ $(TMP_DIR)\tclUtil.obj \ $(TMP_DIR)\tclVar.obj \ - $(TMP_DIR)\tclZipVfs.obj \ $(TMP_DIR)\tclZlib.obj ZLIBOBJS = \ @@ -957,6 +971,12 @@ $(TMP_DIR)\tclAppInit.obj: $(WINDIR)\tclAppInit.c -DTCL_USE_STATIC_PACKAGES=$(TCL_USE_STATIC_PACKAGES) \ -Fo$@ $? +$(TMP_DIR)\tclKitInit.obj: $(WINDIR)\tclAppInit.c + $(cc32) $(TCL_CFLAGS) \ + -DTCL_USE_STATIC_PACKAGES=$(TCL_USE_STATIC_PACKAGES) \ + -DTCL_ZIPVFS \ + -Fo$@ $? + ### The following objects should be built using the stub interfaces ### *ALL* extensions need to built with -DTCL_THREADS=1 -- cgit v0.12 From a684c1a281bc1a3c98249e6aa961fa57498dd9a7 Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Mon, 15 Sep 2014 10:04:50 +0000 Subject: Modified the makefile to produce a distinct name for a kit depending on whether it was compiled statically or dynamically. This allows builders to run and install successive builds of Tcl both statically and dynamically. --- unix/Makefile.in | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/unix/Makefile.in b/unix/Makefile.in index 7523fca..ba81ecc 100644 --- a/unix/Makefile.in +++ b/unix/Makefile.in @@ -109,6 +109,7 @@ CFLAGS = @CFLAGS_DEFAULT@ @CFLAGS@ LDFLAGS_DEBUG = @LDFLAGS_DEBUG@ LDFLAGS_OPTIMIZE = @LDFLAGS_OPTIMIZE@ LDFLAGS = @LDFLAGS_DEFAULT@ @LDFLAGS@ +SHARED_BUILD = @TCL_SHARED_BUILD@ # To disable ANSI-C procedure prototypes reverse the comment characters on the # following lines: @@ -167,7 +168,13 @@ INSTALL_DATA_DIR = ${INSTALL} -d -m 755 # Do not use SHELL_ENV for NATIVE_TCLSH unless it is the tclsh being built. EXE_SUFFIX = @EXEEXT@ TCL_EXE = tclsh${EXE_SUFFIX} -TCLKIT_EXE = tclkit${EXE_SUFFIX} +ifeq ($(SHARED_BUILD),0) +TCLKIT_BASE = tclkits +else +TCLKIT_BASE = tclkitd +endif +TCLKIT_EXE = ${TCLKIT_BASE}${EXE_SUFFIX} + TCLTEST_EXE = tcltest${EXE_SUFFIX} NATIVE_TCLSH = @TCLSH_PROG@ @@ -675,7 +682,7 @@ ${TCLKIT_EXE}: ${TCLKIT_OBJS} ${TCL_LIB_FILE} ${TCL_STUB_LIB_FILE} null.zip tclk cd tclkit.vfs ; zip -rAq ${UNIX_DIR}/${TCLKIT_EXE} . # Builds an executable directly from the Tcl sources -tclkit-direct: ${TCLKIT_OBJS} ${OBJS} ${ZLIB_OBJS} null.zip tclkit.vfs +tclkit-static: ${TCLKIT_OBJS} ${OBJS} ${ZLIB_OBJS} null.zip tclkit.vfs ${CC} ${CFLAGS} ${LDFLAGS} \ ${TCLKIT_OBJS} ${OBJS} ${ZLIB_OBJS} \ ${LIBS} @EXTRA_TCLSH_LIBS@ \ @@ -836,8 +843,8 @@ install-binaries: binaries @chmod 555 "$(DLL_INSTALL_DIR)/$(LIB_FILE)" @echo "Installing ${TCL_EXE} as $(BIN_INSTALL_DIR)/tclsh$(VERSION)${EXE_SUFFIX}" @$(INSTALL_PROGRAM) ${TCL_EXE} "$(BIN_INSTALL_DIR)/tclsh$(VERSION)${EXE_SUFFIX}" - @echo "Installing ${TCLKIT_EXE} as $(BIN_INSTALL_DIR)/tclkit$(VERSION)${EXE_SUFFIX}" - @$(INSTALL_PROGRAM) ${TCLKIT_EXE} "$(BIN_INSTALL_DIR)/tclkit$(VERSION)${EXE_SUFFIX}" + @echo "Installing ${TCLKIT_EXE} as $(BIN_INSTALL_DIR)/${TCLKIT_BASE}$(VERSION)${EXE_SUFFIX}" + @$(INSTALL_PROGRAM) ${TCLKIT_EXE} "$(BIN_INSTALL_DIR)/${TCLKIT_BASE}$(VERSION)${EXE_SUFFIX}" @echo "Installing tclConfig.sh to $(CONFIG_INSTALL_DIR)/" @$(INSTALL_DATA) tclConfig.sh "$(CONFIG_INSTALL_DIR)/tclConfig.sh" @echo "Installing tclooConfig.sh to $(CONFIG_INSTALL_DIR)/" @@ -2166,7 +2173,7 @@ BUILD_HTML = \ .PHONY: install-tzdata install-msgs .PHONY: packages configure-packages test-packages clean-packages .PHONY: dist-packages distclean-packages install-packages -.PHONY: tclkit-direct +.PHONY: tclkit-static #-------------------------------------------------------------------------- # DO NOT DELETE THIS LINE -- make depend depends on it. -- cgit v0.12 From 4b8398a6ed8396348a2cbcd0da5a47bf42756fab Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Mon, 15 Sep 2014 14:59:20 +0000 Subject: Removed non-working code from the end of the mkVfs.tcl script --- tools/mkVfs.tcl | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/tools/mkVfs.tcl b/tools/mkVfs.tcl index 83eb9e6..bc6f3aa 100644 --- a/tools/mkVfs.tcl +++ b/tools/mkVfs.tcl @@ -91,17 +91,3 @@ set VFSROOT $dir } pkgIndexDir ${TCL_SCRIPT_DIR} $fout ${TCL_SCRIPT_DIR} close $fout -exit 0 -puts $fout { -# Save Tcl the trouble of hunting for these packages -} -set ddedll [glob -nocomplain ${TCLSRC_ROOT}/win/tcldde*.dll] -if {$ddedll != {}} { - puts $fout [cat ${TCL_SCRIPT_DIR}/dde/pkgIndex.tcl] -} -set regdll [glob -nocomplain ${TCLSRC_ROOT}/win/tclreg*.dll] -if {$regdll != {}} { - puts $fout [cat ${TCL_SCRIPT_DIR}/reg/pkgIndex.tcl] -} -close $fout -file attributes ${TCL_SCRIPT_DIR}/tclIndex -readonly 1 -- cgit v0.12 From ff7a13136dd5b09e8e2dee557447b05336329fc5 Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Tue, 16 Sep 2014 23:07:44 +0000 Subject: Added a "make tclkit" to makefile Removed debugging fprintf --- generic/tclZipVfs.c | 2 -- unix/Makefile.in | 6 ++++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/generic/tclZipVfs.c b/generic/tclZipVfs.c index 15f38bd..7839648 100755 --- a/generic/tclZipVfs.c +++ b/generic/tclZipVfs.c @@ -1774,7 +1774,6 @@ Zvfs_doInit( ** Boot a shell, mount the executable's VFS, detect main.tcl */ int Tcl_Zvfs_Boot(const char *archive,const char *vfsmountpoint,const char *initscript) { - FILE *fout; Zvfs_Common_Init(NULL); if(!vfsmountpoint) { vfsmountpoint="/zvfs"; @@ -1823,7 +1822,6 @@ int Tcl_Zvfs_Boot(const char *archive,const char *vfsmountpoint,const char *init if(Tcl_FSAccess(vfsinitscript,F_OK)==0) { /* Startup script should be set before calling Tcl_AppInit */ - fprintf(fout,"%s\n",Tcl_GetString(vfsinitscript)); Tcl_SetStartupScript(vfsinitscript,NULL); } diff --git a/unix/Makefile.in b/unix/Makefile.in index ba81ecc..757f313 100644 --- a/unix/Makefile.in +++ b/unix/Makefile.in @@ -670,7 +670,9 @@ tclkit.vfs: @echo "Building VFS File system in tclkit.vfs" @$(TCL_EXE) "$(TOP_DIR)/tools/mkVfs.tcl" \ "$(UNIX_DIR)/tclkit.vfs/tcl$(VERSION)" "$(TOP_DIR)" unix - + +tclkit: ${TCLKIT_EXE} + # Builds an executable linked to the Tcl dynamic library ${TCLKIT_EXE}: ${TCLKIT_OBJS} ${TCL_LIB_FILE} ${TCL_STUB_LIB_FILE} null.zip tclkit.vfs ${CC} ${CFLAGS} ${LDFLAGS} \ @@ -2173,7 +2175,7 @@ BUILD_HTML = \ .PHONY: install-tzdata install-msgs .PHONY: packages configure-packages test-packages clean-packages .PHONY: dist-packages distclean-packages install-packages -.PHONY: tclkit-static +.PHONY: tclkit-static tclkit #-------------------------------------------------------------------------- # DO NOT DELETE THIS LINE -- make depend depends on it. -- cgit v0.12 From 2e0b2484a98701ffab53bda837e16ee86829fc6b Mon Sep 17 00:00:00 2001 From: tne Date: Wed, 17 Sep 2014 08:31:21 +0000 Subject: Removed non-working tclkit-direct makefile technique --- win/Makefile.in | 23 ++++++----------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/win/Makefile.in b/win/Makefile.in index 0b52640..113f87a 100644 --- a/win/Makefile.in +++ b/win/Makefile.in @@ -442,7 +442,12 @@ tclkit.vfs: $(TCLSH) $(DDE_DLL_FILE) $(REG_DLL_FILE) @$(TCL_EXE) "$(ROOT_DIR)/tools/mkVfs.tcl" \ "$(WIN_DIR)/tclkit.vfs/tcl$(VERSION)" "$(ROOT_DIR)" windows -$(TCLKIT): tclkit-direct +$(TCLKIT): $(TCLKIT_OBJS) @LIBRARIES@ $(TCL_STUB_LIB_FILE) tclsh.$(RES) null.zip tclkit.vfs + $(CC) $(CFLAGS) $(TCLKIT_OBJS) $(TCL_LIB_FILE) $(TCL_STUB_LIB_FILE) $(LIBS) \ + tclsh.$(RES) $(CC_EXENAME) $(LDFLAGS_CONSOLE) + @VC_MANIFEST_EMBED_EXE@ + cat null.zip >> $(TCLKIT) + cd tclkit.vfs ; zip -rAq $(WIN_DIR)/$(TCLKIT) . # Builds an executable directly from the Tcl sources tclkit-direct: $(TCLKIT_OBJS) ${GENERIC_OBJS} $(TOMMATH_OBJS) ${WIN_OBJS} ${ZLIB_OBJS} @LIBRARIES@ $(TCL_STUB_LIB_FILE) tclsh.$(RES) null.zip tclkit.vfs @@ -456,22 +461,6 @@ tclkit-direct: $(TCLKIT_OBJS) ${GENERIC_OBJS} $(TOMMATH_OBJS) ${WIN_OBJS} ${ZLI cat null.zip >> $(TCLKIT) cd tclkit.vfs ; zip -rAq $(WIN_DIR)/$(TCLKIT) . - -# Builds an executable linked to the Tcl dynamic library -tclkit-dynamic: $(TCLKIT_OBJS) @LIBRARIES@ $(TCL_STUB_LIB_FILE) tclsh.$(RES) null.zip tclkit.vfs - $(CC) $(CFLAGS) $(TCLKIT_OBJS) $(TCL_LIB_FILE) $(TCL_STUB_LIB_FILE) $(LIBS) \ - tclsh.$(RES) $(CC_EXENAME) $(LDFLAGS_CONSOLE) - @VC_MANIFEST_EMBED_EXE@ - cat null.zip >> $(TCLKIT) - cd tclkit.vfs ; zip -rAq $(WIN_DIR)/$(TCLKIT) . - -tclkit-kitlib: $(TCLKIT_OBJS) @LIBRARIES@ $(TCL_STUB_LIB_FILE) tclsh.$(RES) null.zip tclkit.vfs - $(CC) $(CFLAGS) $(TCLKIT_OBJS) $(TCL_LIB_FILE) $(TCL_STUB_LIB_FILE) $(LIBS) \ - tclsh.$(RES) $(CC_EXENAME) $(LDFLAGS_CONSOLE) - @VC_MANIFEST_EMBED_EXE@ - cat null.zip >> $(TCLKIT) - cd tclkit.vfs ; zip -rAq $(WIN_DIR)/$(TCLKIT) . - cat32.$(OBJEXT): cat.c $(CC) -c $(CC_SWITCHES) @DEPARG@ $(CC_OBJNAME) -- cgit v0.12 From ebebb29be9f0d9bf86391ccc015e0f1a97d3b39b Mon Sep 17 00:00:00 2001 From: tne Date: Wed, 17 Sep 2014 08:33:16 +0000 Subject: Walked back modifications to tclConfig.sh.in (Builds don't require them anymore) --- unix/tclConfig.sh.in | 28 ---------------------------- 1 file changed, 28 deletions(-) diff --git a/unix/tclConfig.sh.in b/unix/tclConfig.sh.in index 976bd7f..b58e9fd 100644 --- a/unix/tclConfig.sh.in +++ b/unix/tclConfig.sh.in @@ -39,9 +39,6 @@ TCL_SHARED_BUILD=@TCL_SHARED_BUILD@ # The name of the Tcl library (may be either a .a file or a shared library): TCL_LIB_FILE='@TCL_LIB_FILE@' -# The name of the static Tcl library (intended for kits): -TCL_KIT_LIB_FILE='@TCL_KIT_LIB_FILE@' - # Additional libraries to use when linking Tcl. TCL_LIBS='@TCL_LIBS@' @@ -145,31 +142,6 @@ TCL_SRC_DIR='@TCL_SRC_DIR@' # the "exec_prefix" directory, if it is different. TCL_PACKAGE_PATH='@TCL_PACKAGE_PATH@' -# Core VFS Kit Support -TCL_SUPPORT_KITS=1 - -# The name of the Tcl kit library (.a): -TCL_KIT_LIB_FILE='@TCL_KIT_LIB_FILE@' - -# -l flag to pass to the linker to pick up the Tcl kit library -TCL_KIT_LIB_FLAG='@TCL_KIT_LIB_FLAG@' - -# String to pass to linker to pick up the Tcl kit library from its -# build directory. -TCL_BUILD_KIT_LIB_SPEC='@TCL_BUILD_KIT_LIB_SPEC@' - -# String to pass to linker to pick up the Tcl kit library from its -# installed directory. -TCL_KIT_LIB_SPEC='@TCL_KIT_LIB_SPEC@' - -# Path to the Tcl kit library in the build directory. -TCL_BUILD_KIT_LIB_PATH='@TCL_BUILD_KIT_LIB_PATH@' - -# Path to the Tcl kit library in the install directory. -TCL_KIT_LIB_PATH='@TCL_KIT_LIB_PATH@' - -# END VFS SUPPORT - # Tcl supports stub. TCL_SUPPORTS_STUBS=1 -- cgit v0.12 From cfd9edb0fe18c9cc71f548a037e8d308494269c4 Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Sun, 19 Oct 2014 20:03:00 +0000 Subject: Update the zipvfs implementation with additional code from both Odie and Dennis LaBelle's FreeWrap. Split the boot loader code out of tclZipVfs.c and into its own File. Altered the structure of tclZipVfs.c to better mirror that which is distributed in Odie and FreeWrap to make popping and swapping improvements easier. --- generic/tclBootVfs.h | 24 + generic/tclZipVfs.c | 2837 +++++++++++++++++------------------------------ generic/tclZipVfsBoot.c | 86 ++ unix/Makefile.in | 7 +- unix/tclAppInit.c | 7 +- win/Makefile.in | 2 +- win/tclAppInit.c | 8 +- 7 files changed, 1154 insertions(+), 1817 deletions(-) create mode 100644 generic/tclBootVfs.h create mode 100644 generic/tclZipVfsBoot.c diff --git a/generic/tclBootVfs.h b/generic/tclBootVfs.h new file mode 100644 index 0000000..1cb7c23 --- /dev/null +++ b/generic/tclBootVfs.h @@ -0,0 +1,24 @@ +#include +#include "tclInt.h" +#include "tclFileSystem.h" + +#ifndef MODULE_SCOPE +# define MODULE_SCOPE extern +#endif + +#define TCLVFSBOOT_INIT "main.tcl" +#define TCLVFSBOOT_MOUNT "/zvfs" + +/* Make sure the stubbed variants of those are never used. */ +#undef Tcl_ObjSetVar2 +#undef Tcl_NewStringObj +#undef Tk_Init +#undef Tk_MainEx +#undef Tk_SafeInit + +MODULE_SCOPE int Tcl_Zvfs_Boot(const char *,const char *,const char *); +MODULE_SCOPE int Zvfs_Init(Tcl_Interp *); +MODULE_SCOPE int Zvfs_SafeInit(Tcl_Interp *); +MODULE_SCOPE int Tclkit_Packages_Init(Tcl_Interp *); + + diff --git a/generic/tclZipVfs.c b/generic/tclZipVfs.c index 7839648..c9160ba 100755 --- a/generic/tclZipVfs.c +++ b/generic/tclZipVfs.c @@ -1,256 +1,309 @@ /* - * Copyright (c) 2000 D. Richard Hipp - * Copyright (c) 2007 PDQ Interfaces Inc. - * Copyright (c) 2013-2014 Sean Woods - * - * This file is now released under the BSD style license outlined in the - * included file license.terms. - * - ************************************************************************ - * A ZIP archive virtual filesystem for Tcl. - * - * This package of routines enables Tcl to use a Zip file as a virtual file - * system. Each of the content files of the Zip archive appears as a real - * file to Tcl. - * - * Well, almost... Actually, the virtual file system is limited in a number - * of ways. The only things you can do are "stat" and "read" file content - * files. You cannot use "cd". But it turns out that "stat" and "read" are - * sufficient for most purposes. - * - * This version has been modified to run under Tcl 8.6 - */ -#include "tcl.h" -#include +** Copyright (c) 2000 D. Richard Hipp +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public +** License as published by the Free Software Foundation; either +** version 2 of the License, or (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +** General Public License for more details. +** +** You should have received a copy of the GNU General Public +** License along with this library; if not, write to the +** Free Software Foundation, Inc., 59 Temple Place - Suite 330, +** Boston, MA 02111-1307, USA. +** +** Author contact information: +** drh@hwaci.com +** http://www.hwaci.com/drh/ +** +************************************************************************* +** A ZIP archive virtual filesystem for Tcl. +** +** This package of routines enables Tcl to use a Zip file as +** a virtual file system. Each of the content files of the Zip +** archive appears as a real file to Tcl. +** +** Modified to use Tcl VFS hooks by Peter MacDonald +** peter@pdqi.com +** http://pdqi.com +** +** @(#) $Id: zvfs.c,v 1.1.1.1 2002/01/27 17:44:02 cvs Exp $ +** +** Revison Date Author Description +** ------- ------------- ----------------- ---------------------------------------------- +** Jan 8, 2006 Dennis R. LaBelle Modified to support encrypted files +** +** Dec 16, 2009 Dennis R. LaBelle Corrected Tobe_FSMatchInDirectoryProc() for +** proper operation of glob command on ZVFS files +** under TCL 8.5. +** Oct 19, 2014 Sean D. Woods Corrected Tobe_FSMatchInDirectoryProc() to work around +** issues resolving global file paths under Windows. +** Wrapped FreeWrap specific calls inside of macros. +** Wrapped calls that implement encryption inside of macros. (The supporting +** library for this is part of Zip, and not distributed with Tcl.) +** Reconciled this edition of Zvfs with parallel work on the Odie project. +*/ + #include #include #include #include #include #include +#include +#include "tcl.h" + +#undef ZIPVFSCRYPT +#ifdef ZIPVFSCRYPT +/* Some modifications to support encrypted files */ +#define update_keys zp_update_keys +#define init_keys zp_init_keys +#define decrypt_byte zp_decrypt_byte + +/* some prototype definitions */ +extern void init_keys(char *pwd); +extern int update_keys(int c); +extern unsigned char decrypt_byte(); +extern char *getPwdKey(char *keybuf); +extern const unsigned long *crc_32_tab; +#endif + +/* End of modifications to support encrypted files. */ /* - * Size of the decompression input buffer - */ -#define COMPR_BUF_SIZE 8192 -/*TODO: use thread-local as appropriate*/ +** Size of the decompression input buffer +*/ +#define COMPR_BUF_SIZE 32768 static int openarch = 0; /* Set to 1 when opening archive. */ +static int maptolower=0; /* - * All static variables are collected into a structure named "local". That - * way, it is clear in the code when we are using a static variable because - * its name begins with "local.". - */ +** All static variables are collected into a structure named "local". +** That way, it is clear in the code when we are using a static +** variable because its name begins with "local.". +*/ static struct { - Tcl_HashTable fileHash; /* One entry for each file in the ZVFS. The - * key is the virtual filename. The data is an - * instance of the ZvfsFile structure. */ - Tcl_HashTable archiveHash; /* One entry for each archive. Key is the - * name. The data is the ZvfsArchive - * structure. */ - int isInit; /* True after initialization */ + Tcl_HashTable fileHash; /* One entry for each file in the ZVFS. The + ** The key is the virtual filename. The data + ** an an instance of the ZvfsFile structure. */ + Tcl_HashTable archiveHash; /* One entry for each archive. Key is the name. + ** data is the ZvfsArchive structure */ + int isInit; /* True after initialization */ + char *firstMount; /* The path to to the first mounted file. */ } local; /* - * Each ZIP archive file that is mounted is recorded as an instance of this - * structure - */ +** Each ZIP archive file that is mounted is recorded as an instance +** of this structure +*/ typedef struct ZvfsArchive { - char *zName; /* Name of the archive */ - char *zMountPoint; /* Where this archive is mounted */ - struct ZvfsFile *pFiles; /* List of files in that archive */ + char *zName; /* Name of the archive */ + char *zMountPoint; /* Where this archive is mounted */ + struct ZvfsFile *pFiles; /* List of files in that archive */ } ZvfsArchive; /* - * Particulars about each virtual file are recorded in an instance of the - * following structure. - */ +** Particulars about each virtual file are recorded in an instance +** of the following structure. +*/ typedef struct ZvfsFile { - char *zName; /* The full pathname of the virtual file */ - ZvfsArchive *pArchive; /* The ZIP archive holding this file data */ - int iOffset; /* Offset into the ZIP archive of the data */ - int nByte; /* Uncompressed size of the virtual file */ - int nByteCompr; /* Compressed size of the virtual file */ - time_t timestamp; /* Modification time */ - int isdir; /* Set to 2 if directory, or 1 if mount */ - int depth; /* Number of slashes in path. */ - int permissions; /* File permissions. */ - struct ZvfsFile *pNext; /* Next file in the same archive */ - struct ZvfsFile *pNextName; /* A doubly-linked list of files with the - * _same_ name. Only the first is in - * local.fileHash */ - struct ZvfsFile *pPrevName; + char *zName; /* The full pathname of the virtual file */ + ZvfsArchive *pArchive; /* The ZIP archive holding this file data */ + int iOffset; /* Offset into the ZIP archive of the data */ + int nByte; /* Uncompressed size of the virtual file */ + int nByteCompr; /* Compressed size of the virtual file */ + int isdir; /* Set to 1 if directory */ + int depth; /* Number of slashes in path. */ + int timestamp; /* Modification time */ + int permissions; /* File permissions. */ + struct ZvfsFile *pNext; /* Next file in the same archive */ + struct ZvfsFile *pNextName; /* A doubly-linked list of files with the same */ + struct ZvfsFile *pPrevName; /* name. Only the first is in local.fileHash */ + /* The following would be used for writable zips. */ + int nExtra; /* Extra space in the TOC header */ + int isSpecial; /* Not really a file in the ZIP archive */ + int dosTime; /* Modification time (DOS format) */ + int dosDate; /* Modification date (DOS format) */ + int iCRC; /* Cyclic Redundancy Check of the data */ } ZvfsFile; /* - * Information about each file within a ZIP archive is stored in an instance - * of the following structure. A list of these structures forms a table of - * contents for the archive. - */ -typedef struct ZFile ZFile; -struct ZFile { - char *zName; /* Name of the file */ - int isSpecial; /* Not really a file in the ZIP archive */ - int dosTime; /* Modification time (DOS format) */ - int dosDate; /* Modification date (DOS format) */ - int iOffset; /* Offset into the ZIP archive of the data */ - int nByte; /* Uncompressed size of the virtual file */ - int nByteCompr; /* Compressed size of the virtual file */ - int nExtra; /* Extra space in the TOC header */ - int iCRC; /* Cyclic Redundancy Check of the data */ - int permissions; /* File permissions. */ - int flags; /* Deletion = bit 0. */ - ZFile *pNext; /* Next file in the same archive */ -}; - -EXTERN int Tcl_Zvfs_Mount(Tcl_Interp *interp,const char *zArchive,const char *zMountPoint); -EXTERN int Tcl_Zvfs_Umount(const char *zArchive); -EXTERN int TclZvfsInit(Tcl_Interp *interp); -EXTERN int Tcl_Zvfs_SafeInit(Tcl_Interp *interp); - -/* - * Macros to read 16-bit and 32-bit big-endian integers into the native format - * of this local processor. B is an array of characters and the integer - * begins at the N-th character of the array. - */ +** Macros to read 16-bit and 32-bit big-endian integers into the +** native format of this local processor. B is an array of +** characters and the integer begins at the N-th character of +** the array. +*/ #define INT16(B, N) (B[N] + (B[N+1]<<8)) #define INT32(B, N) (INT16(B,N) + (B[N+2]<<16) + (B[N+3]<<24)) /* - * Write a 16- or 32-bit integer as little-endian into the given buffer. - */ -static void -put16( - char *z, - int v) -{ - z[0] = v & 0xff; - z[1] = (v>>8) & 0xff; +** Write a 16- or 32-bit integer as little-endian into the given buffer. +*/ +static void put16(char *z, int v){ + z[0] = v & 0xff; + z[1] = (v>>8) & 0xff; } -static void -put32( - char *z, - int v) -{ - z[0] = v & 0xff; - z[1] = (v>>8) & 0xff; - z[2] = (v>>16) & 0xff; - z[3] = (v>>24) & 0xff; +static void put32(char *z, int v){ + z[0] = v & 0xff; + z[1] = (v>>8) & 0xff; + z[2] = (v>>16) & 0xff; + z[3] = (v>>24) & 0xff; } -/* - * Make a new ZFile structure with space to hold a name of the number of - * characters given. Return a pointer to the new structure. - */ -static ZFile * -newZFile( - int nName, - ZFile **ppList) -{ - ZFile *pNew = (void *) Tcl_Alloc(sizeof(*pNew) + nName + 1); - - memset(pNew, 0, sizeof(*pNew)); - pNew->zName = (char*)&pNew[1]; - pNew->pNext = *ppList; - *ppList = pNew; - return pNew; -} - -/* - * Delete an entire list of ZFile structures - */ -static void -deleteZFileList( - ZFile *pList) -{ - ZFile *pNext; - - while( pList ){ - pNext = pList->pNext; - Tcl_Free((char*)pList); - pList = pNext; - } -} - -/* Convert DOS time to unix time. */ -static void -UnixTimeDate( - struct tm *tm, - int *dosDate, - int *dosTime) -{ - *dosDate = ((((tm->tm_year-80)<<9)&0xfe00) | (((tm->tm_mon+1)<<5)&0x1e0) - | (tm->tm_mday&0x1f)); - *dosTime = (((tm->tm_hour<<11)&0xf800) | ((tm->tm_min<<5)&0x7e0) - | (tm->tm_sec&0x1f)); -} - /* Convert DOS time to unix time. */ -static time_t -DosTimeDate( - int dosDate, - int dosTime) -{ - time_t now; - struct tm *tm; - - now = time(NULL); - tm = localtime(&now); - tm->tm_year = (((dosDate&0xfe00)>>9) + 80); - tm->tm_mon = ((dosDate&0x1e0)>>5); - tm->tm_mday = (dosDate & 0x1f); - tm->tm_hour = (dosTime&0xf800)>>11; - tm->tm_min = (dosTime&0x7e0)>>5; - tm->tm_sec = (dosTime&0x1f); - return mktime(tm); +static time_t DosTimeDate(int dosDate, int dosTime){ + time_t now; + struct tm *tm; + now=time(NULL); + tm = localtime(&now); + tm->tm_year=(((dosDate&0xfe00)>>9) + 80); + tm->tm_mon=((dosDate&0x1e0)>>5)-1; + tm->tm_mday=(dosDate & 0x1f); + tm->tm_hour=(dosTime&0xf800)>>11; + tm->tm_min=(dosTime&0x7e)>>5; + tm->tm_sec=(dosTime&0x1f); + return mktime(tm); } /* - * Translate a DOS time and date stamp into a human-readable string. - */ -static void -translateDosTimeDate( - char *zStr, - int dosDate, - int dosTime){ - static char *zMonth[] = { "nil", - "Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", - }; +** Translate a DOS time and date stamp into a human-readable string. +*/ +static void translateDosTimeDate(char *zStr, int dosDate, int dosTime){ + static char *zMonth[] = { "nil", + "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", + }; - sprintf(zStr, "%02d-%s-%d %02d:%02d:%02d", - dosDate & 0x1f, - zMonth[ ((dosDate&0x1e0)>>5) ], - ((dosDate&0xfe00)>>9) + 1980, - (dosTime&0xf800)>>11, - (dosTime&0x7e)>>5, - dosTime&0x1f); + sprintf(zStr, "%02d-%s-%d %02d:%02d:%02d", + dosDate & 0x1f, + zMonth[ ((dosDate&0x1e0)>>5) ], + ((dosDate&0xfe00)>>9) + 1980, + (dosTime&0xf800)>>11, + (dosTime&0x7e)>>5, + dosTime&0x1f + ); } /* Return count of char ch in str */ -int -strchrcnt( - char *str, - char ch) -{ - int cnt = 0; - char *cp = str; +int strchrcnt(char *str, char ch) { + int cnt=0; + char *cp=str; + while ((cp=strchr(cp,ch))) { cp++; cnt++; } + return cnt; +} + +#ifdef FREEWRAP +/* +** Concatenate zTail onto zRoot to form a pathname. zRoot will begin +** with "/". After concatenation, simplify the pathname be removing +** unnecessary ".." and "." directories. Under windows, make all +** characters lower case. +** +** Resulting pathname is returned. Space to hold the returned path is +** obtained from Tcl_Alloc() and should be freed by the calling function. +*/ +static char *CanonicalPath(const char *zRoot, const char *zTail){ + char *zPath; + int i, j, c; - while ((cp = strchr(cp,ch)) != NULL) { - cp++; - cnt++; +#ifdef __WIN32__ + if( isalpha(zTail[0]) && zTail[1]==':' ){ zTail += 2; } + if( zTail[0]=='\\' ){ zRoot = ""; zTail++; } + if( zTail[0]=='\\' ){ zRoot = "/"; zTail++; } // account for UNC style path +#endif + if( zTail[0]=='/' ){ zRoot = ""; zTail++; } + if( zTail[0]=='/' ){ zRoot = "/"; zTail++; } // account for UNC style path + zPath = (void *)Tcl_Alloc( strlen(zRoot) + strlen(zTail) + 2 ); + if( zPath==0 ) return 0; + sprintf(zPath, "%s/%s", zRoot, zTail); + for(i=j=0; (c = zPath[i])!=0; i++){ +#ifdef __WIN32__ + if( isupper(c) ) { if (maptolower) c = tolower(c); } + else if( c=='\\' ) c = '/'; +#endif + if( c=='/' ){ + int c2 = zPath[i+1]; + if( c2=='/' ) continue; + if( c2=='.' ){ + int c3 = zPath[i+2]; + if( c3=='/' || c3==0 ){ + i++; + continue; + } + if( c3=='.' && (zPath[i+3]=='.' || zPath[i+3]==0) ){ + i += 2; + while( j>0 && zPath[j-1]!='/' ){ j--; } + continue; + } + } + } + zPath[j++] = c; + } + if( j==0 ){ zPath[j++] = '/'; } + zPath[j] = 0; + return zPath; +} +/* +** Construct an absolute pathname in memory obtained from Tcl_Alloc +** that means the same file as the pathname given. +** +** Under windows, all backslash (\) charaters are converted to foward +** slash (/) and all upper case letters are converted to lower case. +** The drive letter (if present) is preserved. +*/ +static char *AbsolutePath(const char *z){ + Tcl_DString pwd; + char *zResult; + Tcl_DStringInit(&pwd); + if( *z!='/' +#ifdef __WIN32__ + && *z!='\\' && (!isalpha(*z) || z[1]!=':') +#endif + ){ + /* Case 1: "z" is a relative path. So prepend the current working + ** directory in order to generate an absolute path. Note that the + ** CanonicalPath() function takes care of converting upper to lower + ** case and (\) to (/) under windows. + */ + Tcl_GetCwd(0, &pwd); + zResult = CanonicalPath( Tcl_DStringValue(&pwd), z); + Tcl_DStringFree(&pwd); + } else { + /* Case 2: "z" is an absolute path already. We just need to make + ** a copy of it. Under windows, we need to convert upper to lower + ** case and (\) into (/) on the copy. + */ + zResult = (void *)Tcl_Alloc( strlen(z) + 1 ); + if( zResult==0 ) return 0; + strcpy(zResult, z); +#ifdef __WIN32__ + { + int i, c; + for(i=0; (c=zResult[i])!=0; i++){ + if( isupper(c) ) { + // zResult[i] = tolower(c); + } + else if( c=='\\' ) zResult[i] = '/'; + } } - return cnt; +#endif + } + return zResult; } - +#else /* - * Concatenate zTail onto zRoot to form a pathname. zRoot will begin with - * "/". After concatenation, simplify the pathname be removing unnecessary - * ".." and "." directories. Under windows, make all characters lower case. - * - * Resulting pathname is returned. Space to hold the returned path is - * obtained form Tcl_Alloc() and should be freed by the calling function. - */ +** Concatenate zTail onto zRoot to form a pathname. zRoot will begin +** with "/". After concatenation, simplify the pathname be removing +** unnecessary ".." and "." directories. Under windows, make all +** characters lower case. +** +** Resulting pathname is returned. Space to hold the returned path is +** obtained from Tcl_Alloc() and should be freed by the calling function. +*/ static char * CanonicalPath( const char *zRoot, @@ -317,7 +370,6 @@ CanonicalPath( zPath[j] = 0; return zPath; } - /* * Construct an absolute pathname where memory is obtained from Tcl_Alloc that * means the same file as the pathname given. @@ -346,6 +398,7 @@ AbsolutePath( Tcl_GetCwd(0, &pwd); #endif } + zResult = CanonicalPath(Tcl_DStringValue(&pwd), zRelative); done: Tcl_DStringFree(&pwd); @@ -355,136 +408,18 @@ AbsolutePath( } return zResult; } - -int -ZvfsReadTOCStart( - Tcl_Interp *interp, /* Leave error messages in this interpreter */ - Tcl_Channel chan, - ZFile **pList, - int *iStart) -{ - int nFile; /* Number of files in the archive */ - int iPos; /* Current position in the archive file */ - unsigned char zBuf[100]; /* Space into which to read from the ZIP - * archive */ - ZFile *p; - int zipStart; - - if (!chan) { - return TCL_ERROR; - } - if (Tcl_SetChannelOption(interp, chan, "-translation", - "binary") != TCL_OK){ - return TCL_ERROR; - } - if (Tcl_SetChannelOption(interp, chan, "-encoding", "binary") != TCL_OK) { - return TCL_ERROR; - } - - /* - * Read the "End Of Central Directory" record from the end of the ZIP - * archive. - */ - - iPos = Tcl_Seek(chan, -22, SEEK_END); - Tcl_Read(chan, (char *) zBuf, 22); - if (memcmp(zBuf, "\120\113\05\06", 4)) { - /* Tcl_AppendResult(interp, "not a ZIP archive", NULL); */ - return TCL_BREAK; - } - - /* - * Compute the starting location of the directory for the ZIP archive in - * iPos then seek to that location. - */ - - zipStart = iPos; - nFile = INT16(zBuf,8); - iPos -= INT32(zBuf,12); - Tcl_Seek(chan, iPos, SEEK_SET); - - while (1) { - int lenName; /* Length of the next filename */ - int lenExtra=0; /* Length of "extra" data for next file */ - int iData; /* Offset to start of file data */ - - if (nFile-- <= 0) { - break; - } - - /* - * Read the next directory entry. Extract the size of the filename, - * the size of the "extra" information, and the offset into the - * archive file of the file data. - */ - - Tcl_Read(chan, (char *) zBuf, 46); - if (memcmp(zBuf, "\120\113\01\02", 4)) { - Tcl_AppendResult(interp, "ill-formed central directory entry", - NULL); - return TCL_ERROR; - } - lenName = INT16(zBuf,28); - lenExtra = INT16(zBuf,30) + INT16(zBuf,32); - iData = INT32(zBuf,42); - if (iData < zipStart) { - zipStart = iData; - } - - p = newZFile(lenName, pList); - if (!p) { - break; - } - - Tcl_Read(chan, p->zName, lenName); - p->zName[lenName] = 0; - if (lenName > 0 && p->zName[lenName-1] == '/') { - p->isSpecial = 1; - } - p->dosDate = INT16(zBuf, 14); - p->dosTime = INT16(zBuf, 12); - p->nByteCompr = INT32(zBuf, 20); - p->nByte = INT32(zBuf, 24); - p->nExtra = INT32(zBuf, 28); - p->iCRC = INT32(zBuf, 32); - - if (nFile < 0) { - break; - } - - /* - * Skip over the extra information so that the next read will be from - * the beginning of the next directory entry. - */ - - Tcl_Seek(chan, lenExtra, SEEK_CUR); - } - *iStart = zipStart; - return TCL_OK; -} - -int -ZvfsReadTOC( - Tcl_Interp *interp, /* Leave error messages in this interpreter */ - Tcl_Channel chan, - ZFile **pList) -{ - int iStart; - - return ZvfsReadTOCStart(interp, chan, pList, &iStart); -} +#endif /* - * Read a ZIP archive and make entries in the virutal file hash table for all - * content files of that ZIP archive. Also initialize the ZVFS if this - * routine has not been previously called. - */ -int -Tcl_Zvfs_Mount( - Tcl_Interp *interp, /* Leave error messages in this interpreter */ - const char *zArchive, /* The ZIP archive file */ - const char *zMountPoint) /* Mount contents at this directory */ -{ +** Read a ZIP archive and make entries in the virutal file hash table for all +** content files of that ZIP archive. Also initialize the ZVFS if this +** routine has not been previously called. +*/ +int Zvfs_Mount( + Tcl_Interp *interp, /* Leave error messages in this interpreter */ + const char *zArchive, /* The ZIP archive file */ + const char *zMountPoint /* Mount contents at this directory */ +) { Tcl_Channel chan; /* Used for reading the ZIP archive file */ char *zArchiveName = 0; /* A copy of zArchive */ char *zTrueName = 0; /* A copy of zMountPoint */ @@ -538,7 +473,7 @@ Tcl_Zvfs_Mount( Tcl_AppendResult(interp, pArchive->zMountPoint, 0); } } - Tcl_Free(zTrueName); + Tcl_Free((char *)zTrueName); return TCL_OK; } chan = Tcl_OpenFileChannel(interp, zArchive, "r", 0); @@ -688,7 +623,6 @@ Tcl_Zvfs_Mount( pZvfs->pNextName = 0; } else { ZvfsFile *pOld = Tcl_GetHashValue(pEntry); - pOld->pPrevName = pZvfs; pZvfs->pNextName = pOld; } @@ -715,34 +649,28 @@ Tcl_Zvfs_Mount( } /* - * Locate the ZvfsFile structure that corresponds to the file named. Return - * NULL if there is no such ZvfsFile. - */ -static ZvfsFile * -ZvfsLookup( - char *zFilename) -{ - char *zTrueName; - Tcl_HashEntry *pEntry; - ZvfsFile *pFile; - - if (local.isInit == 0) { - return 0; - } - zTrueName = AbsolutePath(zFilename); - pEntry = Tcl_FindHashEntry(&local.fileHash, zTrueName); - pFile = pEntry ? Tcl_GetHashValue(pEntry) : 0; - Tcl_Free(zTrueName); - return pFile; +** Locate the ZvfsFile structure that corresponds to the file named. +** Return NULL if there is no such ZvfsFile. +*/ +static ZvfsFile *ZvfsLookup(char *zFilename){ + char *zTrueName; + Tcl_HashEntry *pEntry; + ZvfsFile *pFile; + + if( local.isInit==0 ) return 0; + zTrueName = AbsolutePath(zFilename); + pEntry = Tcl_FindHashEntry(&local.fileHash, zTrueName); + pFile = pEntry ? Tcl_GetHashValue(pEntry) : 0; + Tcl_Free(zTrueName); + return pFile; } /* - * Unmount all the files in the given ZIP archive. - */ -int -Tcl_Zvfs_Umount( - const char *zArchive) -{ +** Unmount all the files in the given ZIP archive. +*/ +static int Zvfs_Unmount( + const char *zArchive +) { char *zArchiveName; ZvfsArchive *pArchive; ZvfsFile *pFile, *pNextFile; @@ -804,7 +732,7 @@ ZvfsMountObjCmd( " ? ZIP-FILE ? MOUNT-POINT ? ?\"", 0); return TCL_ERROR; } - return Tcl_Zvfs_Mount(interp, objc>1?Tcl_GetString(objv[1]):NULL, objc>2?Tcl_GetString(objv[2]):NULL); + return Zvfs_Mount(interp, objc>1?Tcl_GetString(objv[1]):NULL, objc>2?Tcl_GetString(objv[2]):NULL); } /* @@ -832,7 +760,7 @@ ZvfsUnmountObjCmd( return TCL_ERROR; } zFilename=Tcl_GetString(objv[1]); - if (Tcl_Zvfs_Umount(zFilename)) { + if (Zvfs_Unmount(zFilename)) { return TCL_OK; } pEntry = Tcl_FirstHashEntry(&local.archiveHash,&zSearch); @@ -840,7 +768,7 @@ ZvfsUnmountObjCmd( pArchive = Tcl_GetHashValue(pEntry); if (pArchive && pArchive->zMountPoint[0] && (strcmp(pArchive->zMountPoint, zFilename) == 0)) { - if (Tcl_Zvfs_Umount(pArchive->zName)) { + if (Zvfs_Unmount(pArchive->zName)) { return TCL_OK; } break; @@ -1004,324 +932,392 @@ ZvfsListObjCmd( } /* - * Whenever a ZVFS file is opened, an instance of this structure is attached - * to the open channel where it will be available to the ZVFS I/O routines - * below. All state information about an open ZVFS file is held in this - * structure. - */ +** Whenever a ZVFS file is opened, an instance of this structure is +** attached to the open channel where it will be available to the +** ZVFS I/O routines below. All state information about an open +** ZVFS file is held in this structure. +*/ typedef struct ZvfsChannelInfo { - unsigned int nByte; /* number of bytes of read uncompressed - * data */ - unsigned int nByteCompr; /* number of bytes of unread compressed - * data */ - unsigned int nData; /* total number of bytes of compressed data */ - int readSoFar; /* Number of bytes read so far */ - long startOfData; /* File position of start of data in ZIP - * archive */ - int isCompressed; /* True data is compressed */ - Tcl_Channel chan; /* Open to the archive file */ - unsigned char *zBuf; /* buffer used by the decompressor */ - z_stream stream; /* state of the decompressor */ + unsigned long nByte; /* number of bytes of uncompressed data */ + unsigned long nByteCompr; /* number of bytes of unread compressed data */ + unsigned long nData; /* total number of bytes of compressed data */ + unsigned long readSoFar; /* position of next byte to be read from the channel */ + long startOfData; /* File position of start of data in ZIP archive */ + Tcl_Channel chan; /* Open file handle to the archive file */ + unsigned char *zBuf; /* buffer used by the decompressor */ + unsigned char *uBuf; /* pointer to the uncompressed, unencrypted data */ + z_stream stream; /* state of the decompressor */ + int isEncrypted; /* file is encrypted */ + int isCompressed; /* True data is compressed */ } ZvfsChannelInfo; /* - * This routine is called as an exit handler. If we do not set - * ZvfsChannelInfo.chan to NULL, then Tcl_Close() will be called on that - * channel twice when Tcl_Exit runs. This will lead to a core dump. - */ -static void -vfsExit( - void *pArg) -{ - ZvfsChannelInfo *pInfo = pArg; - - pInfo->chan = 0; +** This routine is called as an exit handler. If we do not set +** ZvfsChannelInfo.chan to NULL, then Tcl_Close() will be called on +** that channel a second time when Tcl_Exit runs. This will lead to a +** core dump. +*/ +static void vfsExit(void *pArg){ + ZvfsChannelInfo *pInfo = (ZvfsChannelInfo*)pArg; + pInfo->chan = 0; } /* - * This routine is called when the ZVFS channel is closed - */ -static int -vfsClose( - ClientData instanceData, /* A ZvfsChannelInfo structure */ - Tcl_Interp *interp) /* The TCL interpreter */ -{ - ZvfsChannelInfo* pInfo = instanceData; +** This routine is called when the ZVFS channel is closed +*/ +static int vfsClose( + ClientData instanceData, /* A ZvfsChannelInfo structure */ + Tcl_Interp *interp /* The TCL interpreter */ +){ + ZvfsChannelInfo* pInfo = (ZvfsChannelInfo*)instanceData; + + if( pInfo->zBuf ){ + Tcl_Free((char *)pInfo->zBuf); + Tcl_Free((char *)pInfo->uBuf); + inflateEnd(&pInfo->stream); + } + if( pInfo->chan ){ + Tcl_Close(interp, pInfo->chan); + Tcl_DeleteExitHandler(vfsExit, pInfo); + } + Tcl_Free((char*)pInfo); + return TCL_OK; +} - if (pInfo->zBuf) { - Tcl_Free((void *) pInfo->zBuf); - inflateEnd(&pInfo->stream); - } - if (pInfo->chan) { - Tcl_Close(interp, pInfo->chan); - Tcl_DeleteExitHandler(vfsExit, pInfo); - } - Tcl_Free((void *) pInfo); - return TCL_OK; +static int vfsInput ( + ClientData instanceData, /* The channel to read from */ + char *buf, /* Buffer to fill */ + int toRead, /* Requested number of bytes */ + int *pErrorCode /* Location of error flag */ +){ /* The TCL I/O system calls this function to actually read information + * from a ZVFS file. + */ + ZvfsChannelInfo* pInfo = (ZvfsChannelInfo*) instanceData; + unsigned long nextpos; + + nextpos = pInfo->readSoFar + toRead; + if (nextpos > pInfo->nByte) { + toRead = pInfo->nByte - pInfo->readSoFar; + nextpos = pInfo->nByte; + } + if( toRead == 0 ) + return 0; + + memcpy(buf, pInfo->uBuf + pInfo->readSoFar, toRead); + + pInfo->readSoFar = nextpos; + *pErrorCode = 0; + + return toRead; } -/* - * The TCL I/O system calls this function to actually read information from a - * ZVFS file. - */ -static int -vfsInput( - ClientData instanceData, /* The channel to read from */ - char *buf, /* Buffer to fill */ - int toRead, /* Requested number of bytes */ - int *pErrorCode) /* Location of error flag */ -{ - ZvfsChannelInfo* pInfo = instanceData; - if (toRead > pInfo->nByte) { - toRead = pInfo->nByte; - } - if (toRead == 0) { - return 0; +static int vfsRead ( + ClientData instanceData, /* The channel to read from */ + char *buf, /* Buffer to fill */ + int toRead, /* Requested number of bytes */ + int *pErrorCode /* Location of error flag */ + ){ /* Read and decompress all data for the associated file into the specified buffer */ + ZvfsChannelInfo* pInfo = (ZvfsChannelInfo*) instanceData; + unsigned char encryptHdr[12]; + int C; + int temp; + int i; + int len; + char pwdbuf[20]; + + if( (unsigned long)toRead > pInfo->nByte ){ + toRead = pInfo->nByte; + } + if( toRead == 0 ){ + return 0; + } + if (pInfo->isEncrypted) { +#ifdef ZIPVFSCRYPT + + /* Make preparations to decrypt the data. */ + + /* Read and decrypt the encryption header. */ + crc_32_tab = get_crc_table(); + init_keys(getPwdKey(pwdbuf)); + len = Tcl_Read(pInfo->chan, encryptHdr, sizeof(encryptHdr)); + if (len == sizeof(encryptHdr)) { + for (i = 0; i < sizeof(encryptHdr); ++i) { + C = encryptHdr[i] ^ decrypt_byte(); + update_keys(C); + } + + } +#endif + + } + if( pInfo->isCompressed ){ + int err = Z_OK; + z_stream *stream = &pInfo->stream; + stream->next_out = buf; + stream->avail_out = toRead; + while (stream->avail_out) { + if (!stream->avail_in) { + len = pInfo->nByteCompr; + if (len > COMPR_BUF_SIZE) { + len = COMPR_BUF_SIZE; + } + len = Tcl_Read(pInfo->chan, pInfo->zBuf, len); +#ifdef ZIPVFSCRYPT + + if (pInfo->isEncrypted) { + /* Decrypt the bytes we have just read. */ + for (i = 0; i < len; ++i) { + C = pInfo->zBuf[i]; + temp = C ^ decrypt_byte(); + update_keys(temp); + pInfo->zBuf[i] = temp; + } + } +#endif + pInfo->nByteCompr -= len; + stream->next_in = pInfo->zBuf; + stream->avail_in = len; + } + err = inflate(stream, Z_NO_FLUSH); + if (err) break; } - if (pInfo->isCompressed) { - int err = Z_OK; - z_stream *stream = &pInfo->stream; - - stream->next_out = (unsigned char *) buf; - stream->avail_out = toRead; - while (stream->avail_out) { - if (!stream->avail_in) { - int len = pInfo->nByteCompr; - - if (len > COMPR_BUF_SIZE) { - len = COMPR_BUF_SIZE; + if (err == Z_STREAM_END) { + if ((stream->avail_out != 0)) { + *pErrorCode = err; /* premature end */ + return -1; + } + }else if( err ){ + *pErrorCode = err; /* some other zlib error */ + return -1; + } + }else{ + toRead = Tcl_Read(pInfo->chan, buf, toRead); +#ifdef ZIPVFSCRYPT + if (pInfo->isEncrypted) { + /* Decrypt the bytes we have just read. */ + for (i = 0; i < toRead; ++i) { + C = buf[i]; + temp = C ^ decrypt_byte(); + update_keys(temp); + buf[i] = temp; } - len = Tcl_Read(pInfo->chan, (char *) pInfo->zBuf, len); - pInfo->nByteCompr -= len; - stream->next_in = pInfo->zBuf; - stream->avail_in = len; - } - err = inflate(stream, Z_NO_FLUSH); - if (err) { - break; - } - } - if (err == Z_STREAM_END) { - if (stream->avail_out != 0) { - *pErrorCode = err; /* premature end */ - return -1; - } - }else if (err) { - *pErrorCode = err; /* some other zlib error */ - return -1; } - } else { - toRead = Tcl_Read(pInfo->chan, buf, toRead); - } - pInfo->nByte -= toRead; - pInfo->readSoFar += toRead; - *pErrorCode = 0; - return toRead; +#endif + } + pInfo->nByte = toRead; + pInfo->readSoFar = 0; + *pErrorCode = 0; + return toRead; } /* - * Write to a ZVFS file. ZVFS files are always read-only, so this routine - * always returns an error. - */ -static int -vfsOutput( - ClientData instanceData, /* The channel to write to */ - const char *buf, /* Data to be stored. */ - int toWrite, /* Number of bytes to write. */ - int *pErrorCode) /* Location of error flag. */ -{ - *pErrorCode = EINVAL; - return -1; +** Write to a ZVFS file. ZVFS files are always read-only, so this routine +** always returns an error. +*/ +static int vfsOutput( + ClientData instanceData, /* The channel to write to */ + CONST char *buf, /* Data to be stored. */ + int toWrite, /* Number of bytes to write. */ + int *pErrorCode /* Location of error flag. */ +){ + *pErrorCode = EINVAL; + return -1; } -/* - * Move the file pointer so that the next byte read will be "offset". - */ -static int -vfsSeek( - ClientData instanceData, /* The file structure */ - long offset, /* Offset to seek to */ - int mode, /* One of SEEK_CUR, SEEK_SET or SEEK_END */ - int *pErrorCode) /* Write the error code here */ -{ - ZvfsChannelInfo* pInfo = instanceData; - - switch (mode) { - case SEEK_CUR: - offset += pInfo->readSoFar; - break; - case SEEK_END: - offset += pInfo->readSoFar + pInfo->nByte; - break; - default: - /* Do nothing */ - break; +static int vfsSeek( + ClientData instanceData, /* The file structure */ + long offset, /* Offset to seek to */ + int mode, /* One of SEEK_CUR, SEEK_SET or SEEK_END */ + int *pErrorCode /* Write the error code here */ +){ /* Move the file pointer so that the next byte read will be "offset". */ + + ZvfsChannelInfo* pInfo = (ZvfsChannelInfo*) instanceData; + + switch( mode ){ + case SEEK_CUR: { + offset += pInfo->readSoFar; + break; } - if (offset < 0) { - offset = 0; + case SEEK_END: { + offset += pInfo->nByte - 1; + break; } - if (!pInfo->isCompressed) { - Tcl_Seek(pInfo->chan, offset + pInfo->startOfData, SEEK_SET); - pInfo->nByte = pInfo->nData; - pInfo->readSoFar = offset; - } else { - if (offset < pInfo->readSoFar) { - z_stream *stream = &pInfo->stream; - - inflateEnd(stream); - stream->zalloc = (alloc_func)0; - stream->zfree = (free_func)0; - stream->opaque = (voidpf)0; - stream->avail_in = 2; - stream->next_in = pInfo->zBuf; - pInfo->zBuf[0] = 0x78; - pInfo->zBuf[1] = 0x01; - inflateInit(&pInfo->stream); - Tcl_Seek(pInfo->chan, pInfo->startOfData, SEEK_SET); - pInfo->nByte += pInfo->readSoFar; - pInfo->nByteCompr = pInfo->nData; - pInfo->readSoFar = 0; - } - while (pInfo->readSoFar < offset) { - int toRead, errCode; - char zDiscard[100]; - - toRead = offset - pInfo->readSoFar; - if (toRead > sizeof(zDiscard)) { - toRead = sizeof(zDiscard); - } - vfsInput(instanceData, zDiscard, toRead, &errCode); - } + default: { + /* Do nothing */ + break; } - return pInfo->readSoFar; + } +/* Don't seek past end of data */ +if (pInfo->nByte < (unsigned long)offset) + return -1; + +/* Don't seek before the start of data */ +if (offset < 0) + return -1; + +pInfo->readSoFar = (unsigned long)offset; +return pInfo->readSoFar; } /* - * Handle events on the channel. ZVFS files do not generate events, so this - * is a no-op. - */ -static void -vfsWatchChannel( - ClientData instanceData, /* Channel to watch */ - int mask) /* Events of interest */ -{ - return; +** Handle events on the channel. ZVFS files do not generate events, +** so this is a no-op. +*/ +static void vfsWatchChannel( + ClientData instanceData, /* Channel to watch */ + int mask /* Events of interest */ +){ + return; } /* - * Called to retrieve the underlying file handle for this ZVFS file. As the - * ZVFS file has no underlying file handle, this is a no-op. - */ -static int -vfsGetFile( - ClientData instanceData, /* Channel to query */ - int direction, /* Direction of interest */ - ClientData* handlePtr) /* Space to the handle into */ -{ - return TCL_ERROR; +** Called to retrieve the underlying file handle for this ZVFS file. +** As the ZVFS file has no underlying file handle, this is a no-op. +*/ +static int vfsGetFile( + ClientData instanceData, /* Channel to query */ + int direction, /* Direction of interest */ + ClientData* handlePtr /* Space to the handle into */ +){ + return TCL_ERROR; } /* - * This structure describes the channel type structure for access to the ZVFS. - */ +** This structure describes the channel type structure for +** access to the ZVFS. +*/ static Tcl_ChannelType vfsChannelType = { - "vfs", /* Type name. */ - NULL, /* Set blocking/nonblocking behaviour. - * NULL'able */ - vfsClose, /* Close channel, clean instance data */ - vfsInput, /* Handle read request */ - vfsOutput, /* Handle write request */ - vfsSeek, /* Move location of access point. NULL'able */ - NULL, /* Set options. NULL'able */ - NULL, /* Get options. NULL'able */ - vfsWatchChannel, /* Initialize notifier */ - vfsGetFile /* Get OS handle from the channel. */ + "vfs", /* Type name. */ + NULL, /* Set blocking/nonblocking behaviour. NULL'able */ + vfsClose, /* Close channel, clean instance data */ + vfsInput, /* Handle read request */ + vfsOutput, /* Handle write request */ + vfsSeek, /* Move location of access point. NULL'able */ + NULL, /* Set options. NULL'able */ + NULL, /* Get options. NULL'able */ + vfsWatchChannel, /* Initialize notifier */ + vfsGetFile /* Get OS handle from the channel. */ }; /* - * This routine attempts to do an open of a file. Check to see if the file is - * located in the ZVFS. If so, then open a channel for reading the file. If - * not, return NULL. - */ -static Tcl_Channel -ZvfsFileOpen( - Tcl_Interp *interp, /* The TCL interpreter doing the open */ - char *zFilename, /* Name of the file to open */ - char *modeString, /* Mode string for the open (ignored) */ - int permissions) /* Permissions for a newly created file - * (ignored). */ -{ - ZvfsFile *pFile; - ZvfsChannelInfo *pInfo; - Tcl_Channel chan; - static int count = 1; - char zName[50]; - unsigned char zBuf[50]; - - pFile = ZvfsLookup(zFilename); - if (pFile == 0) { - return NULL; - } - openarch = 1; - chan = Tcl_OpenFileChannel(interp, pFile->pArchive->zName, "r", 0); - openarch = 0; - if (chan == 0) { - return 0; - } - if (Tcl_SetChannelOption(interp, chan, "-translation", "binary") - || Tcl_SetChannelOption(interp, chan, "-encoding", "binary")){ - /* this should never happen */ - Tcl_Close(0, chan); - return 0; - } - Tcl_Seek(chan, pFile->iOffset, SEEK_SET); - Tcl_Read(chan, (char *) zBuf, 30); - if (memcmp(zBuf, "\120\113\03\04", 4)) { - if (interp) { - Tcl_AppendResult(interp, "local header mismatch: ", NULL); - } - Tcl_Close(interp, chan); - return 0; - } - pInfo = (void *) Tcl_Alloc(sizeof(*pInfo)); - pInfo->chan = chan; - Tcl_CreateExitHandler(vfsExit, pInfo); - pInfo->isCompressed = INT16(zBuf, 8); - if (pInfo->isCompressed) { - z_stream *stream = &pInfo->stream; - - pInfo->zBuf = (void *) Tcl_Alloc(COMPR_BUF_SIZE); - stream->zalloc = NULL; - stream->zfree = NULL; - stream->opaque = NULL; - stream->avail_in = 2; - stream->next_in = pInfo->zBuf; - pInfo->zBuf[0] = 0x78; - pInfo->zBuf[1] = 0x01; - inflateInit(&pInfo->stream); - } else { - pInfo->zBuf = 0; +** This routine attempts to do an open of a file. Check to see +** if the file is located in the ZVFS. If so, then open a channel +** for reading the file. If not, return NULL. +*/ +static Tcl_Channel ZvfsFileOpen( + Tcl_Interp *interp, /* The TCL interpreter doing the open */ + char *zFilename, /* Name of the file to open */ + char *modeString, /* Mode string for the open (ignored) */ + int permissions /* Permissions for a newly created file (ignored) */ +){ + ZvfsFile *pFile; + ZvfsChannelInfo *pInfo; + Tcl_Channel chan; + static int count = 1; + char zName[50]; + unsigned char zBuf[50]; + int errCode; + + pFile = ZvfsLookup(zFilename); + if( pFile==0 ) { + return NULL; + } + openarch = 1; + chan = Tcl_OpenFileChannel(interp, pFile->pArchive->zName, "r", 0); + openarch = 0; + + if (local.firstMount == NULL) { + local.firstMount = pFile->pArchive->zName; + } + if( chan==0 ){ + return 0; + } + if( Tcl_SetChannelOption(interp, chan, "-translation", "binary") + || Tcl_SetChannelOption(interp, chan, "-encoding", "binary") + ){ + /* this should never happen */ + Tcl_Close(0, chan); + return 0; + } + Tcl_Seek(chan, pFile->iOffset, SEEK_SET); + Tcl_Read(chan, zBuf, 30); + if( memcmp(zBuf, "\120\113\03\04", 4) ){ + if( interp ){ + Tcl_AppendResult(interp, "local header mismatch: ", NULL); } - pInfo->nByte = INT32(zBuf, 22); - pInfo->nByteCompr = pInfo->nData = INT32(zBuf, 18); + Tcl_Close(interp, chan); + return 0; + } + pInfo = (ZvfsChannelInfo*)Tcl_Alloc( sizeof(*pInfo) ); + pInfo->chan = chan; + Tcl_CreateExitHandler(vfsExit, pInfo); +#ifdef ZIPVFSCRYPT + pInfo->isEncrypted = zBuf[6] & 1; + if (pFile->pArchive->zName == local.firstMount) { + /* FreeWrap specific. + We are opening a file from the executable. + All such files must be encrypted. + */ + if (!pInfo->isEncrypted) { + /* The file is not encrypted. + Someone must have tampered with the application. + Let's exit the program. + */ + printf("This application has an unauthorized modification. Exiting immediately\n"); + exit(-10); + } + } +#endif + pInfo->isCompressed = INT16(zBuf, 8); + if (pInfo->isCompressed ){ + z_stream *stream = &pInfo->stream; + pInfo->zBuf = (void *)Tcl_Alloc(COMPR_BUF_SIZE); + stream->zalloc = (alloc_func)0; + stream->zfree = (free_func)0; + stream->opaque = (voidpf)0; + stream->avail_in = 2; + stream->next_in = pInfo->zBuf; + pInfo->zBuf[0] = 0x78; + pInfo->zBuf[1] = 0x01; + inflateInit(&pInfo->stream); + } else { + pInfo->zBuf = 0; + } + pInfo->nByte = INT32(zBuf,22); + pInfo->nByteCompr = pInfo->nData = INT32(zBuf,18); + pInfo->readSoFar = 0; + Tcl_Seek(chan, INT16(zBuf,26)+INT16(zBuf,28), SEEK_CUR); + pInfo->startOfData = Tcl_Tell(chan); + sprintf(zName,"vfs_%x_%x",((int)pFile)>>12,count++); + chan = Tcl_CreateChannel(&vfsChannelType, zName, + (ClientData)pInfo, TCL_READABLE); + + pInfo->uBuf = (void *)Tcl_Alloc(pInfo->nByte); + /* Read and decompress the file contents */ + if (pInfo->uBuf) { + pInfo->uBuf[0] = 0; + vfsRead(pInfo, pInfo->uBuf, pInfo->nByte, &errCode); pInfo->readSoFar = 0; - Tcl_Seek(chan, INT16(zBuf, 26) + INT16(zBuf, 28), SEEK_CUR); - pInfo->startOfData = Tcl_Tell(chan); - sprintf(zName, "zvfs_%x",count++); - chan = Tcl_CreateChannel(&vfsChannelType, zName, pInfo, TCL_READABLE); - return chan; + } + + return chan; +} + +Tcl_Channel Tobe_FSOpenFileChannelProc + _ANSI_ARGS_((Tcl_Interp *interp, Tcl_Obj *pathPtr, + int mode, int permissions)) { + int len; + /* if (mode != O_RDONLY) return NULL; */ + return ZvfsFileOpen(interp, Tcl_GetStringFromObj(pathPtr,&len), 0, + permissions); } /* - * This routine does a stat() system call for a ZVFS file. - */ -static int -Tobe_FSStatProc( - Tcl_Obj *pathObj, - Tcl_StatBuf *buf) -{ - char *path=Tcl_GetString(pathObj); +** This routine does a stat() system call for a ZVFS file. +*/ +int Tobe_FSStatProc _ANSI_ARGS_((Tcl_Obj *pathPtr, Tcl_StatBuf *buf)) { + char *path=Tcl_GetString(pathPtr); ZvfsFile *pFile; pFile = ZvfsLookup(path); @@ -1343,13 +1339,10 @@ Tobe_FSStatProc( } /* - * This routine does an access() system call for a ZVFS file. - */ -static int -Tobe_FSAccessProc( - Tcl_Obj *pathPtr, - int mode) -{ +** This routine does an access() system call for a ZVFS file. +*/ +int Tobe_FSAccessProc _ANSI_ARGS_((Tcl_Obj *pathPtr, int mode)) { + int len; char *path=Tcl_GetString(pathPtr); ZvfsFile *pFile; @@ -1360,116 +1353,139 @@ Tobe_FSAccessProc( if (pFile == 0) { return -1; } - return 0; -} - -Tcl_Channel -Tobe_FSOpenFileChannelProc( - Tcl_Interp *interp, - Tcl_Obj *pathPtr, - int mode, - int permissions) -{ - static int inopen=0; - Tcl_Channel chan; - - if (inopen) { - puts("recursive zvfs open"); - return NULL; - } - inopen = 1; - /* if (mode != O_RDONLY) return NULL; */ - chan = ZvfsFileOpen(interp, Tcl_GetString(pathPtr), 0, permissions); - inopen = 0; - return chan; + return 0; } Tcl_Obj* Tobe_FSFilesystemSeparatorProc(Tcl_Obj *pathPtr) { return Tcl_NewStringObj("/",-1);; } -/* - * Function to process a 'Tobe_FSMatchInDirectory()'. If not implemented, - * then glob and recursive copy functionality will be lacking in the - * filesystem. - */ -int -Tobe_FSMatchInDirectoryProc( +/* Function to process a +* 'Tobe_FSMatchInDirectory()'. If not +* implemented, then glob and recursive +* copy functionality will be lacking in +* the filesystem. */ +int Tobe_FSMatchInDirectoryProc ( Tcl_Interp* interp, Tcl_Obj *result, Tcl_Obj *pathPtr, const char *pattern, - Tcl_GlobTypeData * types) -{ + Tcl_GlobTypeData * types +) { Tcl_HashEntry *pEntry; Tcl_HashSearch sSearch; - int scnt, len, l, dirglob, dirmnt; - char *zPattern = NULL, *zp=Tcl_GetStringFromObj(pathPtr,&len); - - if (!zp) { - return TCL_ERROR; + int scnt=0, pathlen=0, patternlen=0, dirglob=0, fileglob=0, mntglob=0; + int nullpattern=(pattern == NULL || (*pattern=='\0')); + char *zPattern = NULL; + char *zp=NULL; + + if(types && types->type) { + dirglob = (types->type&TCL_GLOB_TYPE_DIR); + fileglob = (types->type & TCL_GLOB_TYPE_FILE); + mntglob = (types->type&TCL_GLOB_TYPE_MOUNT); } - if (pattern != NULL) { - l = strlen(pattern); - if (!zp) { - zPattern = Tcl_Alloc(len + 1); - memcpy(zPattern, pattern, len + 1); - } else { - zPattern = Tcl_Alloc(len + l + 3); - sprintf(zPattern, "%s%s%s", zp, zp[len-1]=='/'?"":"/", pattern); - } - scnt = strchrcnt(zPattern, '/'); + if(!nullpattern) { + patternlen=strlen(pattern); } - dirglob = (types && types->type && (types->type&TCL_GLOB_TYPE_DIR)); - dirmnt = (types && types->type && (types->type&TCL_GLOB_TYPE_MOUNT)); - if (strcmp(zp, "/") == 0 && strcmp(zPattern, ".*") == 0) { - /*TODO: What goes here?*/ + if(pathPtr) { + zp=Tcl_GetStringFromObj(pathPtr,&pathlen); +#ifdef __WIN32__ + if (isalpha(zp[0]) && zp[1]==':') { + zp+=2; + } +#endif } - for (pEntry = Tcl_FirstHashEntry(&local.fileHash, &sSearch); - pEntry; pEntry = Tcl_NextHashEntry(&sSearch)){ - ZvfsFile *pFile = Tcl_GetHashValue(pEntry); - char *z = pFile->zName; - - if (zPattern != NULL) { - if (Tcl_StringCaseMatch(z, zPattern, 0) == 0 || - (scnt != pFile->depth /* && !dirglob */)) { // TODO: ??? - continue; - } - } else { - if (strcmp(zp, z)) { - continue; - } - } - if (dirmnt) { - if (pFile->isdir != 1) { - continue; - } - } else if (dirglob) { - if (!pFile->isdir) { - continue; - } - } else if (types && !(types->type & TCL_GLOB_TYPE_DIR)) { - if (pFile->isdir) { - continue; - } - } - Tcl_ListObjAppendElement(interp, result, Tcl_NewStringObj(z, -1)); + if(mntglob) { return TCL_OK; } + if (mntglob) { + /* Look for a directory mount */ + Tcl_HashEntry *pEntry; /* Hash table entry */ + Tcl_HashSearch zSearch; /* Search all mount points */ + ZvfsArchive *pArchive; /* The ZIP archive being mounted */ + Tcl_Obj *pVols=0, *pVol; + char mountpt[200]; + int i=1; + mountpt[0]='/'; + if(pathPtr) { + for(i=1;izMountPoint; + Tcl_Obj *pTail=NULL; + int match=0; + match=(strcmp(mountpt, z)==0); + if(!match) continue; + pTail=Tcl_NewStringObj(z, -1); + Tcl_ListObjAppendElement(interp, result, pTail); + //Tcl_DecrRefCount(pTail); + } + } + } else { + int idx=0; + if(!zp && nullpattern) { + zPattern=NULL; + } else { + Tcl_DString dTempPath; + Tcl_DStringInit(&dTempPath); + zPattern=(char*)Tcl_Alloc(pathlen+patternlen+3); + memset(zPattern,0,pathlen+patternlen+3); + if(zp) { + Tcl_DStringAppend(&dTempPath,zp,-1); + } + if (zp && !nullpattern) { + if (pathlen > 1 || zPattern[0] != '/') { + Tcl_DStringAppend(&dTempPath,"/",-1); + idx++; + } + } + if (!nullpattern) { + Tcl_DStringAppend(&dTempPath,pattern,patternlen); + } + zPattern=strdup(Tcl_DStringValue(&dTempPath)); + Tcl_DStringFree(&dTempPath); + scnt = strchrcnt(zPattern, '/'); + } + for ( + pEntry = Tcl_FirstHashEntry(&local.fileHash, &sSearch); + pEntry; + pEntry = Tcl_NextHashEntry(&sSearch) + ){ + ZvfsFile *pFile = Tcl_GetHashValue(pEntry); + if(pFile) { + char *z = pFile->zName; + Tcl_Obj *pTail=NULL; + int match=0; + if (dirglob && !pFile->isdir) continue; + if (fileglob && pFile->isdir) continue; + if(scnt != pFile->depth) continue; + match=Tcl_StringCaseMatch(z, zPattern, 0); + if(!match) continue; + pTail=Tcl_NewStringObj(z, -1); + Tcl_ListObjAppendElement(interp, result, pTail); + } + } } +done: if (zPattern) { - Tcl_Free(zPattern); + free(zPattern); } return TCL_OK; } -/* - * Function to check whether a path is in this filesystem. This is the most - * important filesystem procedure. - */ -int -Tobe_FSPathInFilesystemProc( - Tcl_Obj *pathPtr, - ClientData *clientDataPtr) -{ +/* Function to check whether a path is in +* this filesystem. This is the most +* important filesystem procedure. */ +int Tobe_FSPathInFilesystemProc _ANSI_ARGS_((Tcl_Obj *pathPtr, + ClientData *clientDataPtr)) { ZvfsFile *zFile; char *path = Tcl_GetString(pathPtr); @@ -1483,30 +1499,37 @@ Tobe_FSPathInFilesystemProc( return -1; } -Tcl_Obj * -Tobe_FSListVolumesProc(void) -{ - Tcl_HashEntry *pEntry; /* Hash table entry */ - Tcl_HashSearch zSearch; /* Search all mount points */ - ZvfsArchive *pArchive; /* The ZIP archive being mounted */ - Tcl_Obj *pVols = NULL, *pVol; - - pEntry = Tcl_FirstHashEntry(&local.archiveHash,&zSearch); +Tcl_Obj *Tobe_FSListVolumesProc _ANSI_ARGS_((void)) { + Tcl_HashEntry *pEntry; /* Hash table entry */ + Tcl_HashSearch zSearch; /* Search all mount points */ + ZvfsArchive *pArchive; /* The ZIP archive being mounted */ + Tcl_Obj *pVols=0, *pVol; + char mountpt[200]; + + pEntry=Tcl_FirstHashEntry(&local.archiveHash,&zSearch); while (pEntry) { pArchive = Tcl_GetHashValue(pEntry); if (pArchive) { if (!pVols) { - pVols = Tcl_NewListObj(0, 0); + pVols=Tcl_NewListObj(0,0); Tcl_IncrRefCount(pVols); } - pVol = Tcl_NewStringObj(pArchive->zMountPoint, -1); - Tcl_ListObjAppendElement(NULL, pVols, pVol); + sprintf(mountpt, "zvfs:%s", pArchive->zMountPoint); + pVol=Tcl_NewStringObj(mountpt,-1); + Tcl_IncrRefCount(pVol); + Tcl_ListObjAppendElement(NULL, pVols,pVol); + /* Tcl_AppendResult(interp,pArchive->zMountPoint," ",pArchive->zName," ",0);*/ } - pEntry = Tcl_NextHashEntry(&zSearch); + pEntry=Tcl_NextHashEntry(&zSearch); } return pVols; } +int Tobe_FSChdirProc _ANSI_ARGS_((Tcl_Obj *pathPtr)) { + /* Someday, we should actually check if this is a valid path. */ + return TCL_OK; +} + const char * const* Tobe_FSFileAttrStringsProc( Tcl_Obj *pathPtr, @@ -1515,11 +1538,11 @@ Tobe_FSFileAttrStringsProc( char *path = Tcl_GetString(pathPtr); #ifdef __WIN32__ static const char *attrs[] = { - "-archive", "-hidden", "-readonly", "-system", "-shortname", 0 + "uncompsize", "compsize", "offset", "mount", "archive","-archive", "-hidden", "-readonly", "-system", "-shortname", 0 }; #else static const char *attrs[] = { - "-group", "-owner", "-permissions", 0 + "uncompsize", "compsize", "offset", "mount", "archive","-group", "-owner", "-permissions", 0 }; #endif if (ZvfsLookup(path) == 0) { @@ -1528,1090 +1551,286 @@ Tobe_FSFileAttrStringsProc( return attrs; } -int -Tobe_FSFileAttrsGetProc( - Tcl_Interp *interp, - int index, - Tcl_Obj *pathPtr, - Tcl_Obj **objPtrRef) -{ - char *path = Tcl_GetString(pathPtr); -#ifndef __WIN32__ - char buf[50]; -#endif - ZvfsFile *zFile = ZvfsLookup(path); - - if (zFile == 0) { +int Tobe_FSFileAttrsGetProc _ANSI_ARGS_((Tcl_Interp *interp, + int index, Tcl_Obj *pathPtr, + Tcl_Obj **objPtrRef)) { + char *zFilename; + ZvfsFile *pFile; + zFilename = Tcl_GetString(pathPtr); + pFile = ZvfsLookup(zFilename); + if(!pFile) return TCL_ERROR; - } - - switch (index) { + switch (index) { + case 0: + *objPtrRef=Tcl_NewIntObj(pFile->nByteCompr); + return TCL_OK; + case 1: + *objPtrRef= Tcl_NewIntObj(pFile->nByte); + return TCL_OK; + case 2: + *objPtrRef= Tcl_NewIntObj(pFile->nByte); + return TCL_OK; + case 3: + *objPtrRef= Tcl_NewStringObj(pFile->pArchive->zMountPoint,-1); + return TCL_OK; + case 4: + *objPtrRef= Tcl_NewStringObj(pFile->pArchive->zName,-1); + return TCL_OK; #ifdef __WIN32__ - case 0: /* -archive */ + case 5: /* -archive */ *objPtrRef = Tcl_NewStringObj("0", -1); break; - case 1: /* -hidden */ + case 6: /* -hidden */ *objPtrRef = Tcl_NewStringObj("0", -1); break; - case 2: /* -readonly */ + case 7: /* -readonly */ *objPtrRef = Tcl_NewStringObj("", -1); break; - case 3: /* -system */ + case 8: /* -system */ *objPtrRef = Tcl_NewStringObj("", -1); break; - case 4: /* -shortname */ + case 9: /* -shortname */ *objPtrRef = Tcl_NewStringObj("", -1); #else - case 0: /* -group */ + case 5: /* -group */ *objPtrRef = Tcl_NewStringObj("", -1); break; - case 1: /* -owner */ + case 6: /* -owner */ *objPtrRef = Tcl_NewStringObj("", -1); break; - case 2: /* -permissions */ - sprintf(buf, "%03o", zFile->permissions); - *objPtrRef = Tcl_NewStringObj(buf, -1); break; -#endif + case 7: /* -permissions */ { + char buf[32]; + sprintf(buf, "%03o", pFile->permissions); + *objPtrRef = Tcl_NewStringObj(buf, -1); break; } +#endif + default: + return TCL_ERROR; + } + return TCL_OK; +} +int Tobe_FSFileAttrsSetProc _ANSI_ARGS_((Tcl_Interp *interp, + int index, Tcl_Obj *pathPtr, + Tcl_Obj *objPtr)) { return TCL_ERROR; } - return TCL_OK; +Tcl_Obj* Tobe_FSFilesystemPathTypeProc + _ANSI_ARGS_((Tcl_Obj *pathPtr)) { + return Tcl_NewStringObj("zip",-1); } /****************************************************/ -/* - * Function to unload a previously successfully loaded file. If load was - * implemented, then this should also be implemented, if there is any cleanup - * action required. - */ -/* We have to declare the utime structure here. */ -int Tobe_FSUtimeProc(Tcl_Obj *pathPtr, struct utimbuf *tval) { return 0; } -int Tobe_FSFileAttrsSetProc(Tcl_Interp *interp, int index, Tcl_Obj *pathPtr, - Tcl_Obj *objPtr) { return 0; } - static Tcl_Filesystem Tobe_Filesystem = { - "tobe", /* The name of the filesystem. */ - sizeof(Tcl_Filesystem), /* Length of this structure, so future binary - * compatibility can be assured. */ - TCL_FILESYSTEM_VERSION_1, /* Version of the filesystem type. */ - Tobe_FSPathInFilesystemProc,/* Function to check whether a path is in this - * filesystem. This is the most important - * filesystem procedure. */ - NULL, /* Function to duplicate internal fs rep. May - * be NULL (but then fs is less efficient). */ - NULL, /* Function to free internal fs rep. Must be - * implemented, if internal representations - * need freeing, otherwise it can be NULL. */ + "zvfs", /* The name of the filesystem. */ + sizeof(Tcl_Filesystem), /* Length of this structure, so future + * binary compatibility can be assured. */ + TCL_FILESYSTEM_VERSION_1, + /* Version of the filesystem type. */ + Tobe_FSPathInFilesystemProc, + /* Function to check whether a path is in + * this filesystem. This is the most + * important filesystem procedure. */ + NULL, + /* Function to duplicate internal fs rep. May + * be NULL (but then fs is less efficient). */ + NULL, + /* Function to free internal fs rep. Must + * be implemented, if internal representations + * need freeing, otherwise it can be NULL. */ NULL, - /* Function to convert internal representation - * to a normalized path. Only required if the - * fs creates pure path objects with no - * string/path representation. */ + /* Function to convert internal representation + * to a normalized path. Only required if + * the fs creates pure path objects with no + * string/path representation. */ NULL, - /* Function to create a filesystem-specific - * internal representation. May be NULL if - * paths have no internal representation, or - * if the Tobe_FSPathInFilesystemProc for this - * filesystem always immediately creates an - * internal representation for paths it - * accepts. */ - NULL, /* Function to normalize a path. Should be - * implemented for all filesystems which can - * have multiple string representations for - * the same path object. */ + /* Function to create a filesystem-specific + * internal representation. May be NULL + * if paths have no internal representation, + * or if the Tobe_FSPathInFilesystemProc + * for this filesystem always immediately + * creates an internal representation for + * paths it accepts. */ NULL, - /* Function to determine the type of a path in - * this filesystem. May be NULL. */ + /* Tobe_FSNormalizePathProc (Not needed) + * Function to normalize a path. Should + * be implemented for all filesystems + * which can have multiple string + * representations for the same path + * object. */ + Tobe_FSFilesystemPathTypeProc, + /* Function to determine the type of a + * path in this filesystem. May be NULL. */ Tobe_FSFilesystemSeparatorProc, - /* Function to return the separator - * character(s) for this filesystem. Must be - * implemented. */ - Tobe_FSStatProc, /* Function to process a 'Tobe_FSStat()' call. - * Must be implemented for any reasonable - * filesystem. */ - Tobe_FSAccessProc, /* Function to process a 'Tobe_FSAccess()' - * call. Must be implemented for any - * reasonable filesystem. */ - Tobe_FSOpenFileChannelProc, /* Function to process a - * 'Tobe_FSOpenFileChannel()' call. Must be - * implemented for any reasonable - * filesystem. */ - Tobe_FSMatchInDirectoryProc,/* Function to process a - * 'Tobe_FSMatchInDirectory()'. If not - * implemented, then glob and recursive copy - * functionality will be lacking in the - * filesystem. */ - Tobe_FSUtimeProc, /* Function to process a 'Tobe_FSUtime()' - * call. Required to allow setting (not - * reading) of times with 'file mtime', 'file - * atime' and the open-r/open-w/fcopy - * implementation of 'file copy'. */ - NULL, /* Function to process a 'Tobe_FSLink()' call. - * Should be implemented only if the - * filesystem supports links. */ - Tobe_FSListVolumesProc, /* Function to list any filesystem volumes - * added by this filesystem. Should be - * implemented only if the filesystem adds - * volumes at the head of the filesystem. */ - Tobe_FSFileAttrStringsProc, /* Function to list all attributes strings - * which are valid for this filesystem. If - * not implemented the filesystem will not - * support the 'file attributes' command. - * This allows arbitrary additional - * information to be attached to files in the - * filesystem. */ - Tobe_FSFileAttrsGetProc, /* Function to process a - * 'Tobe_FSFileAttrsGet()' call, used by 'file - * attributes'. */ - Tobe_FSFileAttrsSetProc, /* Function to process a - * 'Tobe_FSFileAttrsSet()' call, used by 'file - * attributes'. */ - NULL, /* Function to process a - * 'Tobe_FSCreateDirectory()' call. Should be - * implemented unless the FS is read-only. */ - NULL, /* Function to process a - * 'Tobe_FSRemoveDirectory()' call. Should be - * implemented unless the FS is read-only. */ - NULL, /* Function to process a 'Tobe_FSDeleteFile()' - * call. Should be implemented unless the FS - * is read-only. */ - NULL, /* Function to process a 'Tobe_FSCopyFile()' - * call. If not implemented Tcl will fall - * back on open-r, open-w and fcopy as a - * copying mechanism. */ - NULL, /* Function to process a 'Tobe_FSRenameFile()' - * call. If not implemented, Tcl will fall - * back on a copy and delete mechanism. */ - NULL, /* Function to process a - * 'Tobe_FSCopyDirectory()' call. If not - * implemented, Tcl will fall back on a - * recursive create-dir, file copy - * mechanism. */ - NULL, /* Function to process a 'Tobe_FSLoadFile()' - * call. If not implemented, Tcl will fall - * back on a copy to native-temp followed by a - * Tobe_FSLoadFile on that temporary copy. */ - NULL, /* Function to unload a previously - * successfully loaded file. If load was - * implemented, then this should also be - * implemented, if there is any cleanup action - * required. */ - NULL, /* Function to process a 'Tobe_FSGetCwd()' - * call. Most filesystems need not implement - * this. It will usually only be called once, - * if 'getcwd' is called before 'chdir'. May - * be NULL. */ - NULL, /* Function to process a 'Tobe_FSChdir()' - * call. If filesystems do not implement this, - * it will be emulated by a series of - * directory access checks. Otherwise, virtual - * filesystems which do implement it need only - * respond with a positive return result if - * the dirName is a valid directory in their - * filesystem. They need not remember the - * result, since that will be automatically - * remembered for use by GetCwd. Real - * filesystems should carry out the correct - * action (i.e. call the correct system - * 'chdir' api). If not implemented, then 'cd' - * and 'pwd' will fail inside the - * filesystem. */ + /* Function to return the separator + * character(s) for this filesystem. Must + * be implemented. */ + Tobe_FSStatProc, + /* + * Function to process a 'Tobe_FSStat()' + * call. Must be implemented for any + * reasonable filesystem. + */ + Tobe_FSAccessProc, + /* + * Function to process a 'Tobe_FSAccess()' + * call. Must be implemented for any + * reasonable filesystem. + */ + Tobe_FSOpenFileChannelProc, + /* + * Function to process a + * 'Tobe_FSOpenFileChannel()' call. Must be + * implemented for any reasonable + * filesystem. + */ + Tobe_FSMatchInDirectoryProc, + /* Function to process a + * 'Tobe_FSMatchInDirectory()'. If not + * implemented, then glob and recursive + * copy functionality will be lacking in + * the filesystem. */ + NULL, + /* Function to process a + * 'Tobe_FSUtime()' call. Required to + * allow setting (not reading) of times + * with 'file mtime', 'file atime' and + * the open-r/open-w/fcopy implementation + * of 'file copy'. */ + NULL, + /* Function to process a + * 'Tobe_FSLink()' call. Should be + * implemented only if the filesystem supports + * links. */ + Tobe_FSListVolumesProc, + /* Function to list any filesystem volumes + * added by this filesystem. Should be + * implemented only if the filesystem adds + * volumes at the head of the filesystem. */ + Tobe_FSFileAttrStringsProc, + /* Function to list all attributes strings + * which are valid for this filesystem. + * If not implemented the filesystem will + * not support the 'file attributes' command. + * This allows arbitrary additional information + * to be attached to files in the filesystem. */ + Tobe_FSFileAttrsGetProc, + /* Function to process a + * 'Tobe_FSFileAttrsGet()' call, used by + * 'file attributes'. */ + Tobe_FSFileAttrsSetProc, + /* Function to process a + * 'Tobe_FSFileAttrsSet()' call, used by + * 'file attributes'. */ + NULL, + /* Function to process a + * 'Tobe_FSCreateDirectory()' call. Should + * be implemented unless the FS is + * read-only. */ + NULL, + /* Function to process a + * 'Tobe_FSRemoveDirectory()' call. Should + * be implemented unless the FS is + * read-only. */ + NULL, + /* Function to process a + * 'Tobe_FSDeleteFile()' call. Should + * be implemented unless the FS is + * read-only. */ + NULL, + /* Function to process a + * 'Tobe_FSCopyFile()' call. If not + * implemented Tcl will fall back + * on open-r, open-w and fcopy as + * a copying mechanism. */ + NULL, + /* Function to process a + * 'Tobe_FSRenameFile()' call. If not + * implemented, Tcl will fall back on + * a copy and delete mechanism. */ + NULL, + /* Function to process a + * 'Tobe_FSCopyDirectory()' call. If + * not implemented, Tcl will fall back + * on a recursive create-dir, file copy + * mechanism. */ + NULL, + /* Function to process a + * 'Tobe_FSLoadFile()' call. If not + * implemented, Tcl will fall back on + * a copy to native-temp followed by a + * Tobe_FSLoadFile on that temporary copy. */ + NULL, + /* Function to unload a previously + * successfully loaded file. If load was + * implemented, then this should also be + * implemented, if there is any cleanup + * action required. */ + NULL, + /* + * Function to process a 'Tobe_FSGetCwd()' + * call. Most filesystems need not + * implement this. It will usually only be + * called once, if 'getcwd' is called + * before 'chdir'. May be NULL. + */ + NULL, + /* + * Function to process a 'Tobe_FSChdir()' + * call. If filesystems do not implement + * this, it will be emulated by a series of + * directory access checks. Otherwise, + * virtual filesystems which do implement + * it need only respond with a positive + * return result if the dirName is a valid + * directory in their filesystem. They + * need not remember the result, since that + * will be automatically remembered for use + * by GetCwd. Real filesystems should + * carry out the correct action (i.e. call + * the correct system 'chdir' api). If not + * implemented, then 'cd' and 'pwd' will + * fail inside the filesystem. + */ }; -////////////////////////////////////////////////////////////// - -void (*Zvfs_PostInit)(Tcl_Interp *) = 0; -static int ZvfsAppendObjCmd(void *NotUsed, Tcl_Interp *interp, int objc, Tcl_Obj *const* objv); -static int ZvfsAddObjCmd(void *NotUsed, Tcl_Interp *interp, int objc, Tcl_Obj *const* objv); -static int ZvfsDumpObjCmd(void *NotUsed, Tcl_Interp *interp, int objc, Tcl_Obj *const* objv); -static int ZvfsStartObjCmd(void *NotUsed, Tcl_Interp *interp, int objc, Tcl_Obj *const* objv); +void (*Zvfs_PostInit)(Tcl_Interp *)=0; -static int Zvfs_Common_Init(Tcl_Interp *interp) { - if (local.isInit) return TCL_OK; - /* One-time initialization of the ZVFS */ - if(Tcl_FSRegister(interp, &Tobe_Filesystem)) { - return TCL_ERROR; +int Zvfs_Common_Init(Tcl_Interp *interp) { + if( !local.isInit ){ + /* One-time initialization of the ZVFS */ + Tcl_FSRegister(0, &Tobe_Filesystem); + Tcl_InitHashTable(&local.fileHash, TCL_STRING_KEYS); + Tcl_InitHashTable(&local.archiveHash, TCL_STRING_KEYS); + local.isInit = 1; } - Tcl_InitHashTable(&local.fileHash, TCL_STRING_KEYS); - Tcl_InitHashTable(&local.archiveHash, TCL_STRING_KEYS); - local.isInit = 1; return TCL_OK; } -/* - * Initialize the ZVFS system. - */ -int -Zvfs_doInit( - Tcl_Interp *interp, - int safe) -{ +int Zvfs_Init(Tcl_Interp *interp){ + int n; #ifdef USE_TCL_STUBS - if (Tcl_InitStubs(interp, "8.0", 0) == 0) { - return TCL_ERROR; - } -#endif - Tcl_StaticPackage(interp, "zvfs", TclZvfsInit, Tcl_Zvfs_SafeInit); - if (!safe) { - Tcl_CreateObjCommand(interp, "zvfs::mount", ZvfsMountObjCmd, 0, 0); - Tcl_CreateObjCommand(interp, "zvfs::unmount", ZvfsUnmountObjCmd, 0, 0); - Tcl_CreateObjCommand(interp, "zvfs::append", ZvfsAppendObjCmd, 0, 0); - Tcl_CreateObjCommand(interp, "zvfs::add", ZvfsAddObjCmd, 0, 0); - } - Tcl_CreateObjCommand(interp, "zvfs::exists", ZvfsExistsObjCmd, 0, 0); - Tcl_CreateObjCommand(interp, "zvfs::info", ZvfsInfoObjCmd, 0, 0); - Tcl_CreateObjCommand(interp, "zvfs::list", ZvfsListObjCmd, 0, 0); - Tcl_CreateObjCommand(interp, "zvfs::dump", ZvfsDumpObjCmd, 0, 0); - Tcl_CreateObjCommand(interp, "zvfs::start", ZvfsStartObjCmd, 0, 0); - Tcl_SetVar(interp, "::zvfs::auto_ext", - ".tcl .tk .itcl .htcl .txt .c .h .tht", TCL_GLOBAL_ONLY); - /* Tcl_CreateObjCommand(interp, "zip::open", ZipOpenObjCmd, 0, 0); */ - if(Zvfs_Common_Init(interp)) { - return TCL_ERROR; - } - - if (Zvfs_PostInit) { - Zvfs_PostInit(interp); - } - return TCL_OK; -} - -/* -** Boot a shell, mount the executable's VFS, detect main.tcl -*/ -int Tcl_Zvfs_Boot(const char *archive,const char *vfsmountpoint,const char *initscript) { - Zvfs_Common_Init(NULL); - if(!vfsmountpoint) { - vfsmountpoint="/zvfs"; - } - if(!initscript) { - initscript="main.tcl"; - } - /* We have to initialize the virtual filesystem before calling - ** Tcl_Init(). Otherwise, Tcl_Init() will not be able to find - ** its startup script files. - */ - if(!Tcl_Zvfs_Mount(NULL, archive, vfsmountpoint)) { - Tcl_DString filepath; - Tcl_DString preinit; - - Tcl_Obj *vfsinitscript; - Tcl_Obj *vfstcllib; - Tcl_Obj *vfstklib; - Tcl_Obj *vfspreinit; - - Tcl_DStringInit(&filepath); - Tcl_DStringInit(&preinit); - - Tcl_DStringInit(&filepath); - Tcl_DStringAppend(&filepath,vfsmountpoint,-1); - Tcl_DStringAppend(&filepath,"/",-1); - Tcl_DStringAppend(&filepath,initscript,-1); - vfsinitscript=Tcl_NewStringObj(Tcl_DStringValue(&filepath),-1); - Tcl_DStringFree(&filepath); - - Tcl_DStringInit(&filepath); - Tcl_DStringAppend(&filepath,vfsmountpoint,-1); - Tcl_DStringAppend(&filepath,"/tcl8.6",-1); - vfstcllib=Tcl_NewStringObj(Tcl_DStringValue(&filepath),-1); - Tcl_DStringFree(&filepath); - - Tcl_DStringInit(&filepath); - Tcl_DStringAppend(&filepath,vfsmountpoint,-1); - Tcl_DStringAppend(&filepath,"/tk8.6",-1); - vfstklib=Tcl_NewStringObj(Tcl_DStringValue(&filepath),-1); - Tcl_DStringFree(&filepath); - - Tcl_IncrRefCount(vfsinitscript); - Tcl_IncrRefCount(vfstcllib); - Tcl_IncrRefCount(vfstklib); - - if(Tcl_FSAccess(vfsinitscript,F_OK)==0) { - /* Startup script should be set before calling Tcl_AppInit */ - Tcl_SetStartupScript(vfsinitscript,NULL); - } - - if(Tcl_FSAccess(vfsinitscript,F_OK)==0) { - /* Startup script should be set before calling Tcl_AppInit */ - Tcl_SetStartupScript(vfsinitscript,NULL); - } else { - Tcl_SetStartupScript(NULL,NULL); - } - if(Tcl_FSAccess(vfstcllib,F_OK)==0) { - Tcl_DStringAppend(&preinit,"\nset tcl_library ",-1); - Tcl_DStringAppendElement(&preinit,Tcl_GetString(vfstcllib)); - } - if(Tcl_FSAccess(vfstklib,F_OK)==0) { - Tcl_DStringAppend(&preinit,"\nset tk_library ",-1); - Tcl_DStringAppendElement(&preinit,Tcl_GetString(vfstklib)); - } - vfspreinit=Tcl_NewStringObj(Tcl_DStringValue(&preinit),-1); - /* NOTE: We never decr this refcount, lest the contents of the script be deallocated */ - Tcl_IncrRefCount(vfspreinit); - TclSetPreInitScript(Tcl_GetString(vfspreinit)); - - Tcl_DecrRefCount(vfsinitscript); - Tcl_DecrRefCount(vfstcllib); - Tcl_DecrRefCount(vfstklib); + if( Tcl_InitStubs(interp,"8.0",0)==0 ){ + return TCL_ERROR; } +#endif + Tcl_PkgProvide(interp, "zvfs", "1.0"); + Zvfs_Common_Init(interp); + Tcl_CreateObjCommand(interp, "zvfs::mount", ZvfsMountObjCmd, 0, 0); + Tcl_CreateObjCommand(interp, "zvfs::unmount", ZvfsUnmountObjCmd, 0, 0); + Tcl_CreateObjCommand(interp, "zvfs::exists", ZvfsExistsObjCmd, 0, 0); + Tcl_CreateObjCommand(interp, "zvfs::info", ZvfsInfoObjCmd, 0, 0); + Tcl_CreateObjCommand(interp, "zvfs::list", ZvfsListObjCmd, 0, 0); + if (Zvfs_PostInit) Zvfs_PostInit(interp); return TCL_OK; } - - -int -TclZvfsInit( - Tcl_Interp *interp) -{ - return Zvfs_doInit(interp, 0); -} - -int -Tcl_Zvfs_SafeInit( - Tcl_Interp *interp) -{ - return Zvfs_doInit(interp, 1); -} - -/************************************************************************/ -/************************************************************************/ -/************************************************************************/ - -/* - * Implement the zvfs::dump command - * - * zvfs::dump ARCHIVE - * - * Each entry in the list returned is of the following form: - * - * {FILENAME DATE-TIME SPECIAL-FLAG OFFSET SIZE COMPRESSED-SIZE} - */ -static int -ZvfsDumpObjCmd( - void *NotUsed, /* Client data for this command */ - Tcl_Interp *interp, /* The interpreter used to report errors */ - int objc, /* Number of arguments */ - Tcl_Obj *const* objv) /* Values of all arguments */ -{ - Tcl_Obj *zFilenameObj; - Tcl_Channel chan; - ZFile *pList; - int rc; - Tcl_Obj *pResult; - - if (objc != 2) { - Tcl_WrongNumArgs(interp, 1, objv, "FILENAME"); - return TCL_ERROR; - } - zFilenameObj=objv[1]; - chan = Tcl_FSOpenFileChannel(interp, zFilenameObj, "r", 0); - if (chan == 0) { - return TCL_ERROR; - } - rc = ZvfsReadTOC(interp, chan, &pList); - if (rc == TCL_ERROR) { - deleteZFileList(pList); - return rc; - } - Tcl_Close(interp, chan); - pResult = Tcl_GetObjResult(interp); - while (pList) { - Tcl_Obj *pEntry = Tcl_NewObj(); - ZFile *pNext; - char zDateTime[100]; - - Tcl_ListObjAppendElement(interp, pEntry, - Tcl_NewStringObj(pList->zName,-1)); - translateDosTimeDate(zDateTime, pList->dosDate, pList->dosTime); - Tcl_ListObjAppendElement(interp, pEntry, - Tcl_NewStringObj(zDateTime, -1)); - Tcl_ListObjAppendElement(interp, pEntry, - Tcl_NewIntObj(pList->isSpecial)); - Tcl_ListObjAppendElement(interp, pEntry, - Tcl_NewIntObj(pList->iOffset)); - Tcl_ListObjAppendElement(interp, pEntry, Tcl_NewIntObj(pList->nByte)); - Tcl_ListObjAppendElement(interp, pEntry, - Tcl_NewIntObj(pList->nByteCompr)); - Tcl_ListObjAppendElement(interp, pResult, pEntry); - pNext = pList->pNext; - Tcl_Free((void *) pList); - pList = pNext; - } - return TCL_OK; -} - -/* - * Write a file record into a ZIP archive at the current position of the write - * cursor for channel "chan". Add a ZFile record for the file to *ppList. If - * an error occurs, leave an error message on interp and return TCL_ERROR. - * Otherwise return TCL_OK. - */ -static int -writeFile( - Tcl_Interp *interp, /* Leave an error message here */ - Tcl_Channel out, /* Write the file here */ - Tcl_Channel in, /* Read data from this file */ - Tcl_Obj *zSrcPtr, /* Name the new ZIP file entry this */ - Tcl_Obj *zDestPtr, /* Name the new ZIP file entry this */ - ZFile **ppList) /* Put a ZFile struct for the new file here */ -{ - char *zDest=Tcl_GetString(zDestPtr); - - z_stream stream; - ZFile *p; - int iEndOfData; - int nameLen; - int skip; - int toOut; - char zHdr[30]; - char zInBuf[100000]; - char zOutBuf[100000]; - struct tm *tm; - time_t now; - Tcl_StatBuf stat; - - /* - * Create a new ZFile structure for this file. - * TODO: fill in date/time etc. - */ - nameLen = strlen(zDest); - p = newZFile(nameLen, ppList); - strcpy(p->zName, zDest); - p->isSpecial = 0; - Tcl_FSStat(zSrcPtr, &stat); - now = stat.st_mtime; - tm = localtime(&now); - UnixTimeDate(tm, &p->dosDate, &p->dosTime); - p->iOffset = Tcl_Tell(out); - p->nByte = 0; - p->nByteCompr = 0; - p->nExtra = 0; - p->iCRC = 0; - p->permissions = stat.st_mode; - - /* - * Fill in as much of the header as we know. - */ - - put32(&zHdr[0], 0x04034b50); - put16(&zHdr[4], 0x0014); - put16(&zHdr[6], 0); - put16(&zHdr[8], 8); - put16(&zHdr[10], p->dosTime); - put16(&zHdr[12], p->dosDate); - put16(&zHdr[26], nameLen); - put16(&zHdr[28], 0); - - /* - * Write the header and filename. - */ - - Tcl_Write(out, zHdr, 30); - Tcl_Write(out, zDest, nameLen); - - /* - * The first two bytes that come out of the deflate compressor are some - * kind of header that ZIP does not use. So skip the first two output - * bytes. - */ - - skip = 2; - - /* - * Write the compressed file. Compute the CRC as we progress. - */ - - stream.zalloc = NULL; - stream.zfree = NULL; - stream.opaque = 0; - stream.avail_in = 0; - stream.next_in = (unsigned char *) zInBuf; - stream.avail_out = sizeof(zOutBuf); - stream.next_out = (unsigned char *) zOutBuf; - deflateInit(&stream, 9); - - - p->iCRC = crc32(0, 0, 0); - while (!Tcl_Eof(in)) { - if (stream.avail_in == 0) { - int amt = Tcl_Read(in, zInBuf, sizeof(zInBuf)); - - if (amt <= 0) { - break; - } - p->iCRC = crc32(p->iCRC, (unsigned char *) zInBuf, amt); - stream.avail_in = amt; - stream.next_in = (unsigned char *) zInBuf; - } - deflate(&stream, 0); - toOut = sizeof(zOutBuf) - stream.avail_out; - if (toOut > skip) { - Tcl_Write(out, &zOutBuf[skip], toOut - skip); - skip = 0; - } else { - skip -= toOut; - } - stream.avail_out = sizeof(zOutBuf); - stream.next_out = (unsigned char *) zOutBuf; - } - - do{ - stream.avail_out = sizeof(zOutBuf); - stream.next_out = (unsigned char *) zOutBuf; - deflate(&stream, Z_FINISH); - toOut = sizeof(zOutBuf) - stream.avail_out; - if (toOut > skip) { - Tcl_Write(out, &zOutBuf[skip], toOut - skip); - skip = 0; - } else { - skip -= toOut; - } - } while (stream.avail_out == 0); - - p->nByte = stream.total_in; - p->nByteCompr = stream.total_out - 2; - deflateEnd(&stream); - Tcl_Flush(out); - - /* - * Remember were we are in the file. Then go back and write the header, - * now that we know the compressed file size. - */ - - iEndOfData = Tcl_Tell(out); - Tcl_Seek(out, p->iOffset, SEEK_SET); - put32(&zHdr[14], p->iCRC); - put32(&zHdr[18], p->nByteCompr); - put32(&zHdr[22], p->nByte); - Tcl_Write(out, zHdr, 30); - Tcl_Seek(out, iEndOfData, SEEK_SET); - - /* - * Close the input file. - */ - - Tcl_Close(interp, in); - return TCL_OK; -} - -/* - * The arguments are two lists of ZFile structures sorted by iOffset. Either - * or both list may be empty. This routine merges the two lists together into - * a single sorted list and returns a pointer to the head of the unified list. - * - * This is part of the merge-sort algorithm. - */ -static ZFile * -mergeZFiles( - ZFile *pLeft, - ZFile *pRight) -{ - ZFile fakeHead; - ZFile *pTail; - - pTail = &fakeHead; - while (pLeft && pRight) { - ZFile *p; - - if (pLeft->iOffset <= pRight->iOffset) { - p = pLeft; - pLeft = p->pNext; - } else { - p = pRight; - pRight = p->pNext; - } - pTail->pNext = p; - pTail = p; - } - if (pLeft) { - pTail->pNext = pLeft; - } else if (pRight) { - pTail->pNext = pRight; - } else { - pTail->pNext = 0; - } - return fakeHead.pNext; -} - -/* - * Sort a ZFile list so in accending order by iOffset. - */ -static ZFile * -sortZFiles( - ZFile *pList) -{ -#define NBIN 30 - int i; - ZFile *p; - ZFile *aBin[NBIN+1]; - - for (i=0; i<=NBIN; i++) { - aBin[i] = 0; - } - while (pList) { - p = pList; - pList = p->pNext; - p->pNext = 0; - for (i=0; ipNext) { - if (pList->isSpecial) { - continue; - } - put32(&zBuf[0], 0x02014b50); - put16(&zBuf[4], 0x0317); - put16(&zBuf[6], 0x0014); - put16(&zBuf[8], 0); - put16(&zBuf[10], pList->nByte>pList->nByteCompr ? 0x0008 : 0x0000); - put16(&zBuf[12], pList->dosTime); - put16(&zBuf[14], pList->dosDate); - put32(&zBuf[16], pList->iCRC); - put32(&zBuf[20], pList->nByteCompr); - put32(&zBuf[24], pList->nByte); - put16(&zBuf[28], strlen(pList->zName)); - put16(&zBuf[30], 0); - put16(&zBuf[32], pList->nExtra); - put16(&zBuf[34], 1); - put16(&zBuf[36], 0); - put32(&zBuf[38], pList->permissions<<16); - put32(&zBuf[42], pList->iOffset); - Tcl_Write(chan, zBuf, 46); - Tcl_Write(chan, pList->zName, strlen(pList->zName)); - for (i=pList->nExtra; i>0; i-=40) { - int toWrite = i<40 ? i : 40; - - /* CAREFUL! String below is intentionally 40 spaces! */ - Tcl_Write(chan," ", - toWrite); - } - nEntry++; - } - iTocEnd = Tcl_Tell(chan); - put32(&zBuf[0], 0x06054b50); - put16(&zBuf[4], 0); - put16(&zBuf[6], 0); - put16(&zBuf[8], nEntry); - put16(&zBuf[10], nEntry); - put32(&zBuf[12], iTocEnd - iTocStart); - put32(&zBuf[16], iTocStart); - put16(&zBuf[20], 0); - Tcl_Write(chan, zBuf, 22); - Tcl_Flush(chan); -} - -/* - * Implementation of the zvfs::append command. - * - * zvfs::append ARCHIVE (SOURCE DESTINATION)* - * - * This command reads SOURCE files and appends them (using the name - * DESTINATION) to the zip archive named ARCHIVE. A new zip archive is created - * if it does not already exist. If ARCHIVE refers to a file which exists but - * is not a zip archive, then this command turns ARCHIVE into a zip archive by - * appending the necessary records and the table of contents. Treat all files - * as binary. - * - * Note: No dup checking is done, so multiple occurances of the same file is - * allowed. - */ -static int -ZvfsAppendObjCmd( - void *NotUsed, /* Client data for this command */ - Tcl_Interp *interp, /* The interpreter used to report errors */ - int objc, /* Number of arguments */ - Tcl_Obj *const* objv) /* Values of all arguments */ -{ - Tcl_Obj *zArchiveObj; - Tcl_Channel chan; - ZFile *pList = NULL, *pToc; - int rc = TCL_OK, i; - - /* - * Open the archive and read the table of contents - */ - - if (objc<2 || (objc&1)!=0) { - Tcl_WrongNumArgs(interp, 1, objv, "ARCHIVE (SRC DEST)+"); - return TCL_ERROR; - } - - zArchiveObj=objv[1]; - chan = Tcl_FSOpenFileChannel(interp, zArchiveObj, "r+", 0644); - if (chan == 0) { - chan = Tcl_FSOpenFileChannel(interp, zArchiveObj, "w+", 0644); - if (chan == 0) { - return TCL_ERROR; - } - } - if (Tcl_SetChannelOption(interp, chan, "-translation", "binary") - || Tcl_SetChannelOption(interp, chan, "-encoding", "binary")){ - /* this should never happen */ - Tcl_Close(0, chan); - return TCL_ERROR; - } - - if (Tcl_Seek(chan, 0, SEEK_END) == 0) { - /* Null file is ok, we're creating new one. */ - } else { - Tcl_Seek(chan, 0, SEEK_SET); - if (ZvfsReadTOC(interp, chan, &pList) == TCL_ERROR) { - deleteZFileList(pList); - Tcl_Close(interp, chan); - return TCL_ERROR; - } - rc = TCL_OK; - } - - /* - * Move the file pointer to the start of the table of contents. - */ - for (pToc=pList; pToc; pToc=pToc->pNext) { - if (pToc->isSpecial && strcmp(pToc->zName, "*TOC*") == 0) { - break; - } - } - if (pToc) { - Tcl_Seek(chan, pToc->iOffset, SEEK_SET); - } else { - Tcl_Seek(chan, 0, SEEK_END); - } - - /* - * Add new files to the end of the archive. - */ - - for (i=2; rc==TCL_OK && i p)) { - p = NULL; - } - return p; -} - -/* - * Implementation of the zvfs::add command. - * - * zvfs::add ?-fconfigure optpairs? ARCHIVE FILE1 FILE2 ... - * - * This command is similar to append in that it adds files to the zip archive - * named ARCHIVE, however file names are relative the current directory. In - * addition, fconfigure is used to apply option pairs to set upon opening of - * each file. Otherwise, default translation is allowed for those file - * extensions listed in the ::zvfs::auto_ext var. Binary translation will be - * used for unknown extensions. - * - * NOTE Use '-fconfigure {}' to use auto translation for all. - */ -static int -ZvfsAddObjCmd( - void *NotUsed, /* Client data for this command */ - Tcl_Interp *interp, /* The interpreter used to report errors */ - int objc, /* Number of arguments */ - Tcl_Obj *const* objv) /* Values of all arguments */ -{ - Tcl_Obj *zArchiveObj; - Tcl_Channel chan; - ZFile *pList = NULL, *pToc; - int rc = TCL_OK, i, j, oLen; - char *zOpts = NULL; - Tcl_Obj *confOpts = NULL; - int tobjc; - Tcl_Obj **tobjv; - Tcl_Obj *varObj = NULL; - - /* - * Open the archive and read the table of contents - */ - - if (objc > 3) { - zOpts = Tcl_GetStringFromObj(objv[1], &oLen); - if (!strncmp("-fconfigure", zOpts, oLen)) { - confOpts = objv[2]; - if (TCL_OK != Tcl_ListObjGetElements(interp, confOpts, - &tobjc, &tobjv) || (tobjc%2)) { - return TCL_ERROR; - } - objc -= 2; - objv += 2; - } - } - if (objc == 2) { - return TCL_OK; - } - - if (objc < 3) { - Tcl_WrongNumArgs(interp, 1, objv, - "?-fconfigure OPTPAIRS? ARCHIVE FILE1 FILE2 .."); - return TCL_ERROR; - } - - zArchiveObj = objv[1]; - chan = Tcl_FSOpenFileChannel(interp, zArchiveObj, "r+", 0644); - if (chan == 0) { - chan = Tcl_FSOpenFileChannel(interp, zArchiveObj, "w+", 0644); - if (chan == 0) { - return TCL_ERROR; - } - } - if (Tcl_SetChannelOption(interp, chan, "-translation", "binary") - || Tcl_SetChannelOption(interp, chan, "-encoding", "binary")){ - /* this should never happen */ - Tcl_Close(0, chan); - return TCL_ERROR; - } - - if (Tcl_Seek(chan, 0, SEEK_END) == 0) { - /* Null file is ok, we're creating new one. */ - } else { - Tcl_Seek(chan, 0, SEEK_SET); - if (ZvfsReadTOC(interp, chan, &pList) == TCL_ERROR) { - deleteZFileList(pList); - Tcl_Close(interp, chan); - return TCL_ERROR; - } - rc = TCL_OK; - } - - /* - * Move the file pointer to the start of the table of contents. - */ - - for (pToc=pList; pToc; pToc=pToc->pNext) { - if (pToc->isSpecial && strcmp(pToc->zName, "*TOC*") == 0) { - break; - } - } - if (pToc) { - Tcl_Seek(chan, pToc->iOffset, SEEK_SET); - } else { - Tcl_Seek(chan, 0, SEEK_END); - } - - /* - * Add new files to the end of the archive. - */ - - for (i=2; rc==TCL_OK && i= tobjc) { - ext = NULL; - } - } - } - if (ext == NULL) { - if (Tcl_SetChannelOption(interp, in, "-translation", "binary") - || Tcl_SetChannelOption(interp, in, "-encoding", - "binary")) { - /* this should never happen */ - Tcl_Close(0, in); - rc = TCL_ERROR; - break; - } - } - } else { - for (j=0; j +#include "tclInt.h" +#include "tclFileSystem.h" + +int Zvfs_Common_Init(Tcl_Interp *); +int Zvfs_Mount(Tcl_Interp *,CONST char *,CONST char *); + + +/* +** Boot a shell, mount the executable's VFS, detect main.tcl +*/ +int Tcl_Zvfs_Boot(const char *archive,const char *vfsmountpoint,const char *initscript) { + Zvfs_Common_Init(NULL); + if(!vfsmountpoint) { + vfsmountpoint="/zvfs"; + } + if(!initscript) { + initscript="main.tcl"; + } + /* We have to initialize the virtual filesystem before calling + ** Tcl_Init(). Otherwise, Tcl_Init() will not be able to find + ** its startup script files. + */ + if(!Zvfs_Mount(NULL, archive, vfsmountpoint)) { + Tcl_DString filepath; + Tcl_DString preinit; + + Tcl_Obj *vfsinitscript; + Tcl_Obj *vfstcllib; + Tcl_Obj *vfstklib; + Tcl_Obj *vfspreinit; + Tcl_DStringInit(&filepath); + Tcl_DStringInit(&preinit); + + Tcl_DStringInit(&filepath); + Tcl_DStringAppend(&filepath,vfsmountpoint,-1); + Tcl_DStringAppend(&filepath,"/",-1); + Tcl_DStringAppend(&filepath,initscript,-1); + vfsinitscript=Tcl_NewStringObj(Tcl_DStringValue(&filepath),-1); + Tcl_DStringFree(&filepath); + + Tcl_DStringInit(&filepath); + Tcl_DStringAppend(&filepath,vfsmountpoint,-1); + Tcl_DStringAppend(&filepath,"/boot/tcl",-1); + vfstcllib=Tcl_NewStringObj(Tcl_DStringValue(&filepath),-1); + Tcl_DStringFree(&filepath); + + Tcl_DStringInit(&filepath); + Tcl_DStringAppend(&filepath,vfsmountpoint,-1); + Tcl_DStringAppend(&filepath,"/boot/tk",-1); + vfstklib=Tcl_NewStringObj(Tcl_DStringValue(&filepath),-1); + Tcl_DStringFree(&filepath); + + Tcl_IncrRefCount(vfsinitscript); + Tcl_IncrRefCount(vfstcllib); + Tcl_IncrRefCount(vfstklib); + + if(Tcl_FSAccess(vfsinitscript,F_OK)==0) { + /* Startup script should be set before calling Tcl_AppInit */ + Tcl_SetStartupScript(vfsinitscript,NULL); + } + /* Record the mountpoint for scripts to refer back to */ + Tcl_DStringAppend(&preinit,"\nset ::tcl_boot_vfs ",-1); + Tcl_DStringAppendElement(&preinit,vfsmountpoint); + Tcl_DStringAppend(&preinit,"\nset ::SRCDIR ",-1); + Tcl_DStringAppendElement(&preinit,vfsmountpoint); + + if(Tcl_FSAccess(vfstcllib,F_OK)==0) { + Tcl_DStringAppend(&preinit,"\nset tcl_library ",-1); + Tcl_DStringAppendElement(&preinit,Tcl_GetString(vfstcllib)); + } + if(Tcl_FSAccess(vfstklib,F_OK)==0) { + Tcl_DStringAppend(&preinit,"\nset tk_library ",-1); + Tcl_DStringAppendElement(&preinit,Tcl_GetString(vfstklib)); + } + vfspreinit=Tcl_NewStringObj(Tcl_DStringValue(&preinit),-1); + /* NOTE: We never decr this refcount, lest the contents of the script be deallocated */ + Tcl_IncrRefCount(vfspreinit); + TclSetPreInitScript(Tcl_GetString(vfspreinit)); + + Tcl_DecrRefCount(vfsinitscript); + Tcl_DecrRefCount(vfstcllib); + Tcl_DecrRefCount(vfstklib); + } + return TCL_OK; +} diff --git a/unix/Makefile.in b/unix/Makefile.in index bbe0ae5..a9c74b1 100644 --- a/unix/Makefile.in +++ b/unix/Makefile.in @@ -367,7 +367,7 @@ ZLIB_OBJS = Zadler32.o Zcompress.o Zcrc32.o Zdeflate.o Zinfback.o \ TCL_OBJS = ${GENERIC_OBJS} ${UNIX_OBJS} ${NOTIFY_OBJS} ${COMPAT_OBJS} \ ${OO_OBJS} @DL_OBJS@ @PLAT_OBJS@ -TCLKIT_OBJS = tclKitInit.o tclZipVfs.o +TCLKIT_OBJS = tclKitInit.o tclZipVfs.o tclZipVfsBoot.o OBJS = ${TCL_OBJS} ${TOMMATH_OBJS} @DTRACE_OBJ@ @ZLIB_OBJS@ @@ -670,7 +670,7 @@ null.zip: tclkit.vfs: @echo "Building VFS File system in tclkit.vfs" @$(TCL_EXE) "$(TOP_DIR)/tools/mkVfs.tcl" \ - "$(UNIX_DIR)/tclkit.vfs/tcl$(VERSION)" "$(TOP_DIR)" unix + "$(UNIX_DIR)/tclkit.vfs/boot/tcl" "$(TOP_DIR)" unix tclkit: ${TCLKIT_EXE} @@ -1376,6 +1376,9 @@ tclVar.o: $(GENERIC_DIR)/tclVar.c tclZipVfs.o: $(GENERIC_DIR)/tclZipVfs.c $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclZipVfs.c +tclZipVfsBoot.o: $(GENERIC_DIR)/tclZipVfsBoot.c + $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclZipVfsBoot.c + tclZlib.o: $(GENERIC_DIR)/tclZlib.c $(CC) -c $(CC_SWITCHES) $(ZLIB_INCLUDE) $(GENERIC_DIR)/tclZlib.c diff --git a/unix/tclAppInit.c b/unix/tclAppInit.c index 4df6387..1be1ce3 100644 --- a/unix/tclAppInit.c +++ b/unix/tclAppInit.c @@ -42,7 +42,9 @@ MODULE_SCOPE int TCL_LOCAL_APPINIT(Tcl_Interp *); MODULE_SCOPE int main(int, char **); #ifdef TCL_ZIPVFS MODULE_SCOPE int Tcl_Zvfs_Boot(const char *,const char *,const char *); - MODULE_SCOPE int TclZvfsInit(Tcl_Interp *); + MODULE_SCOPE int Zvfs_Init(Tcl_Interp *); + MODULE_SCOPE int Zvfs_SafeInit(Tcl_Interp *); + #endif /* TCL_ZIPVFS */ /* * The following #if block allows you to change how Tcl finds the startup @@ -122,7 +124,8 @@ Tcl_AppInit( } #ifdef TCL_ZIPVFS /* Load the ZipVfs package */ - if (TclZvfsInit(interp) == TCL_ERROR) { + Tcl_StaticPackage(interp, "zvfs", Zvfs_Init, Zvfs_SafeInit); + if(Zvfs_Init(interp) == TCL_ERROR) { return TCL_ERROR; } #endif diff --git a/win/Makefile.in b/win/Makefile.in index d667c51..745fa58 100644 --- a/win/Makefile.in +++ b/win/Makefile.in @@ -411,7 +411,7 @@ ZLIB_OBJS = \ TCL_OBJS = ${GENERIC_OBJS} $(TOMMATH_OBJS) ${WIN_OBJS} @ZLIB_OBJS@ -TCLKIT_OBJS = tclKitInit.$(OBJEXT) tclZipVfs.$(OBJEXT) +TCLKIT_OBJS = tclKitInit.$(OBJEXT) tclZipVfs.$(OBJEXT) tclZipVfsBoot.$(OBJEXT) TCL_DOCS = "$(ROOT_DIR_NATIVE)"/doc/*.[13n] diff --git a/win/tclAppInit.c b/win/tclAppInit.c index 6f49afa..7fd4c32 100644 --- a/win/tclAppInit.c +++ b/win/tclAppInit.c @@ -29,7 +29,8 @@ extern Tcl_PackageInitProc Tcltest_SafeInit; #ifdef TCL_ZIPVFS MODULE_SCOPE int Tcl_Zvfs_Boot(const char *,const char *,const char *); - MODULE_SCOPE int TclZvfsInit(Tcl_Interp *); + MODULE_SCOPE int Zvfs_Init(Tcl_Interp *); + MODULE_SCOPE int Zvfs_SafeInit(Tcl_Interp *); #endif /* TCL_ZIPVFS */ #if defined(STATIC_BUILD) && TCL_USE_STATIC_PACKAGES @@ -167,8 +168,9 @@ Tcl_AppInit( } #ifdef TCL_ZIPVFS /* Load the ZipVfs package */ - if (TclZvfsInit(interp) == TCL_ERROR) { - return TCL_ERROR; + Tcl_StaticPackage(interp, "zvfs", Zvfs_Init, Zvfs_SafeInit); + if(Zvfs_Init(interp) == TCL_ERROR) { + return TCL_ERROR; } #endif #if defined(STATIC_BUILD) && TCL_USE_STATIC_PACKAGES -- cgit v0.12 From 2b022e697945f65efc1e421e0149ec206434e353 Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Sun, 19 Oct 2014 20:20:09 +0000 Subject: Added a "_bare" stage to capture the kit executable before the VFS is wrapped to it. --- unix/Makefile.in | 17 +++++++++++------ win/Makefile.in | 12 ++++++++---- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/unix/Makefile.in b/unix/Makefile.in index a9c74b1..16721a9 100644 --- a/unix/Makefile.in +++ b/unix/Makefile.in @@ -674,15 +674,20 @@ tclkit.vfs: tclkit: ${TCLKIT_EXE} -# Builds an executable linked to the Tcl dynamic library -${TCLKIT_EXE}: ${TCLKIT_OBJS} ${TCL_LIB_FILE} ${TCL_STUB_LIB_FILE} null.zip tclkit.vfs +${TCLKIT_BASE}_bare: ${TCLKIT_OBJS} ${TCL_LIB_FILE} ${TCL_STUB_LIB_FILE} ${CC} ${CFLAGS} ${LDFLAGS} \ ${TCLKIT_OBJS} \ @TCL_BUILD_LIB_SPEC@ \ ${LIBS} @EXTRA_TCLSH_LIBS@ \ - ${CC_SEARCH_FLAGS} -o ${TCLKIT_EXE} - cat null.zip >> ${TCLKIT_EXE} - cd tclkit.vfs ; zip -rAq ${UNIX_DIR}/${TCLKIT_EXE} . + ${CC_SEARCH_FLAGS} -o ${TCLKIT_BASE}_bare + + +# Builds an executable linked to the Tcl dynamic library +${TCLKIT_EXE}: ${TCLKIT_BASE}_bare null.zip tclkit.vfs + cp -f ${TCLKIT_BASE}_bare ${TCLKIT_BASE}.zip + cat null.zip >> ${TCLKIT_BASE}.zip + cd tclkit.vfs ; zip -rAq ${UNIX_DIR}/${TCLKIT_BASE}.zip . + mv ${TCLKIT_BASE}.zip ${TCLKIT_EXE} # Builds an executable directly from the Tcl sources tclkit-static: ${TCLKIT_OBJS} ${OBJS} ${ZLIB_OBJS} null.zip tclkit.vfs @@ -701,7 +706,7 @@ Makefile: $(UNIX_DIR)/Makefile.in $(DLTEST_DIR)/Makefile.in clean: clean-packages rm -f *.a *.o libtcl* core errs *~ \#* TAGS *.E a.out \ errors ${TCL_EXE} ${TCLTEST_EXE} lib.exp Tcl @DTRACE_HDR@ \ - ${TCLKIT_EXE} + ${TCLKIT_EXE} tclkit* rm -rf tclkit.vfs null.zip cd dltest ; $(MAKE) clean diff --git a/win/Makefile.in b/win/Makefile.in index 745fa58..0fba203 100644 --- a/win/Makefile.in +++ b/win/Makefile.in @@ -443,12 +443,16 @@ tclkit.vfs: $(TCLSH) $(DDE_DLL_FILE) $(REG_DLL_FILE) @$(TCL_EXE) "$(ROOT_DIR)/tools/mkVfs.tcl" \ "$(WIN_DIR)/tclkit.vfs/tcl$(VERSION)" "$(ROOT_DIR)" windows -$(TCLKIT): $(TCLKIT_OBJS) @LIBRARIES@ $(TCL_STUB_LIB_FILE) tclsh.$(RES) null.zip tclkit.vfs +tclkit_bare: $(TCLKIT_OBJS) @LIBRARIES@ $(TCL_STUB_LIB_FILE) tclsh.$(RES) $(CC) $(CFLAGS) $(TCLKIT_OBJS) $(TCL_LIB_FILE) $(TCL_STUB_LIB_FILE) $(LIBS) \ tclsh.$(RES) $(CC_EXENAME) $(LDFLAGS_CONSOLE) @VC_MANIFEST_EMBED_EXE@ - cat null.zip >> $(TCLKIT) - cd tclkit.vfs ; zip -rAq $(WIN_DIR)/$(TCLKIT) . + +$(TCLKIT): tclkit_bare null.zip tclkit.vfs + cp tclkit_bare tclkit.zip + cat null.zip >> tclkit.zip + cd tclkit.vfs ; zip -rAq $(WIN_DIR)/tclkit.zip . + mv tclkit.zip $(TCLKIT) # Builds an executable directly from the Tcl sources tclkit-direct: $(TCLKIT_OBJS) ${GENERIC_OBJS} $(TOMMATH_OBJS) ${WIN_OBJS} ${ZLIB_OBJS} @LIBRARIES@ $(TCL_STUB_LIB_FILE) tclsh.$(RES) null.zip tclkit.vfs @@ -778,7 +782,7 @@ cleanhelp: clean: cleanhelp clean-packages $(RM) *.lib *.a *.exp *.dll *.$(RES) *.${OBJEXT} *~ \#* TAGS a.out $(RM) $(TCLSH) $(CAT32) $(TCLKIT) null.zip - $(RM) *.pch *.ilk *.pdb + $(RM) *.pch *.ilk *.pdb tclkit* $(RMDIR) tclkit.vfs distclean: distclean-packages clean -- cgit v0.12 From 963de5ae2a73c26d2f1faabe43cbc6eb2c066b97 Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Mon, 20 Oct 2014 01:20:54 +0000 Subject: Added thread mutex/release calls around the potentially contested regions of the code: Mounting a file system Unmounting a file system Reading data from an archive file The mutexes, as implemented, allow only one thread at a time access to the innards of ZipVfs. It does not try to handle the cases where two archives may be open by two different threads. (One will still have to wait until the other has finished.) Removed all of the compiler warnings under Unix (Still have to test the code under Windows.) --- generic/tclZipVfs.c | 94 ++++++++++++++++++++++------------------------------- 1 file changed, 39 insertions(+), 55 deletions(-) diff --git a/generic/tclZipVfs.c b/generic/tclZipVfs.c index c9160ba..d4f8f68 100755 --- a/generic/tclZipVfs.c +++ b/generic/tclZipVfs.c @@ -57,6 +57,8 @@ #include #include "tcl.h" +TCL_DECLARE_MUTEX(ArchiveFileAccess) + #undef ZIPVFSCRYPT #ifdef ZIPVFSCRYPT /* Some modifications to support encrypted files */ @@ -79,8 +81,9 @@ extern const unsigned long *crc_32_tab; */ #define COMPR_BUF_SIZE 32768 static int openarch = 0; /* Set to 1 when opening archive. */ +#ifdef __WIN32__ static int maptolower=0; - +#endif /* ** All static variables are collected into a structure named "local". ** That way, it is clear in the code when we are using a static @@ -140,19 +143,6 @@ typedef struct ZvfsFile { #define INT16(B, N) (B[N] + (B[N+1]<<8)) #define INT32(B, N) (INT16(B,N) + (B[N+2]<<16) + (B[N+3]<<24)) -/* -** Write a 16- or 32-bit integer as little-endian into the given buffer. -*/ -static void put16(char *z, int v){ - z[0] = v & 0xff; - z[1] = (v>>8) & 0xff; -} -static void put32(char *z, int v){ - z[0] = v & 0xff; - z[1] = (v>>8) & 0xff; - z[2] = (v>>16) & 0xff; - z[3] = (v>>24) & 0xff; -} /* Convert DOS time to unix time. */ static time_t DosTimeDate(int dosDate, int dosTime){ @@ -169,25 +159,6 @@ static time_t DosTimeDate(int dosDate, int dosTime){ return mktime(tm); } -/* -** Translate a DOS time and date stamp into a human-readable string. -*/ -static void translateDosTimeDate(char *zStr, int dosDate, int dosTime){ - static char *zMonth[] = { "nil", - "Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", - }; - - sprintf(zStr, "%02d-%s-%d %02d:%02d:%02d", - dosDate & 0x1f, - zMonth[ ((dosDate&0x1e0)>>5) ], - ((dosDate&0xfe00)>>9) + 1980, - (dosTime&0xf800)>>11, - (dosTime&0x7e)>>5, - dosTime&0x1f - ); -} - /* Return count of char ch in str */ int strchrcnt(char *str, char ch) { int cnt=0; @@ -476,15 +447,17 @@ int Zvfs_Mount( Tcl_Free((char *)zTrueName); return TCL_OK; } + Tcl_MutexLock(&ArchiveFileAccess); chan = Tcl_OpenFileChannel(interp, zArchive, "r", 0); if (!chan) { - return TCL_ERROR; + Tcl_MutexUnlock(&ArchiveFileAccess); + return TCL_ERROR; } if (Tcl_SetChannelOption(interp, chan, "-translation", "binary") != TCL_OK){ - return TCL_ERROR; + goto closeReleaseDie; } if (Tcl_SetChannelOption(interp, chan, "-encoding", "binary") != TCL_OK) { - return TCL_ERROR; + goto closeReleaseDie; } /* @@ -496,7 +469,7 @@ int Zvfs_Mount( Tcl_Read(chan, (char *) zBuf, 22); if (memcmp(zBuf, "\120\113\05\06", 4)) { if(interp) Tcl_AppendResult(interp, "not a ZIP archive", NULL); - return TCL_ERROR; + goto closeReleaseDie; } /* @@ -510,9 +483,7 @@ int Zvfs_Mount( if (interp) { Tcl_AppendResult(interp, "already mounted at ", pArchive->zMountPoint,0); } - Tcl_Free(zArchiveName); - Tcl_Close(interp, chan); - return TCL_ERROR; + goto closeReleaseDie; } /* @@ -641,11 +612,16 @@ int Zvfs_Mount( Tcl_Seek(chan, lenExtra, SEEK_CUR); } Tcl_Close(interp, chan); - if (zTrueName) { Tcl_Free(zTrueName); } + Tcl_MutexUnlock(&ArchiveFileAccess); return TCL_OK; + +closeReleaseDie: + Tcl_Close(interp, chan); + Tcl_MutexUnlock(&ArchiveFileAccess); + return TCL_ERROR; } /* @@ -682,6 +658,7 @@ static int Zvfs_Unmount( if (pEntry == 0) { return 0; } + Tcl_MutexLock(&ArchiveFileAccess); pArchive = Tcl_GetHashValue(pEntry); Tcl_DeleteHashEntry(pEntry); Tcl_Free(pArchive->zName); @@ -705,6 +682,7 @@ static int Zvfs_Unmount( Tcl_Free(pFile->zName); Tcl_Free((void *) pFile); } + Tcl_MutexUnlock(&ArchiveFileAccess); return 1; } @@ -980,6 +958,7 @@ static int vfsClose( Tcl_Close(interp, pInfo->chan); Tcl_DeleteExitHandler(vfsExit, pInfo); } + Tcl_MutexUnlock(&ArchiveFileAccess); Tcl_Free((char*)pInfo); return TCL_OK; } @@ -1019,12 +998,14 @@ static int vfsRead ( int *pErrorCode /* Location of error flag */ ){ /* Read and decompress all data for the associated file into the specified buffer */ ZvfsChannelInfo* pInfo = (ZvfsChannelInfo*) instanceData; + int len; +#ifdef ZIPVFSCRYPT unsigned char encryptHdr[12]; int C; int temp; int i; - int len; char pwdbuf[20]; +#endif if( (unsigned long)toRead > pInfo->nByte ){ toRead = pInfo->nByte; @@ -1054,7 +1035,7 @@ static int vfsRead ( if( pInfo->isCompressed ){ int err = Z_OK; z_stream *stream = &pInfo->stream; - stream->next_out = buf; + stream->next_out = (unsigned char *)buf; stream->avail_out = toRead; while (stream->avail_out) { if (!stream->avail_in) { @@ -1062,7 +1043,7 @@ static int vfsRead ( if (len > COMPR_BUF_SIZE) { len = COMPR_BUF_SIZE; } - len = Tcl_Read(pInfo->chan, pInfo->zBuf, len); + len = Tcl_Read(pInfo->chan, (char *)pInfo->zBuf, len); #ifdef ZIPVFSCRYPT if (pInfo->isEncrypted) { @@ -1224,6 +1205,8 @@ static Tcl_Channel ZvfsFileOpen( return NULL; } openarch = 1; + + Tcl_MutexLock(&ArchiveFileAccess); chan = Tcl_OpenFileChannel(interp, pFile->pArchive->zName, "r", 0); openarch = 0; @@ -1231,23 +1214,22 @@ static Tcl_Channel ZvfsFileOpen( local.firstMount = pFile->pArchive->zName; } if( chan==0 ){ + Tcl_MutexUnlock(&ArchiveFileAccess); return 0; } if( Tcl_SetChannelOption(interp, chan, "-translation", "binary") || Tcl_SetChannelOption(interp, chan, "-encoding", "binary") ){ /* this should never happen */ - Tcl_Close(0, chan); - return 0; + goto closeReleaseDie; } Tcl_Seek(chan, pFile->iOffset, SEEK_SET); - Tcl_Read(chan, zBuf, 30); + Tcl_Read(chan, (char *)zBuf, 30); if( memcmp(zBuf, "\120\113\03\04", 4) ){ if( interp ){ Tcl_AppendResult(interp, "local header mismatch: ", NULL); } - Tcl_Close(interp, chan); - return 0; + goto closeReleaseDie; } pInfo = (ZvfsChannelInfo*)Tcl_Alloc( sizeof(*pInfo) ); pInfo->chan = chan; @@ -1297,11 +1279,17 @@ static Tcl_Channel ZvfsFileOpen( /* Read and decompress the file contents */ if (pInfo->uBuf) { pInfo->uBuf[0] = 0; - vfsRead(pInfo, pInfo->uBuf, pInfo->nByte, &errCode); + vfsRead(pInfo, (char *)pInfo->uBuf, pInfo->nByte, &errCode); pInfo->readSoFar = 0; } return chan; + +closeReleaseDie: + Tcl_Close(interp, chan); + Tcl_MutexUnlock(&ArchiveFileAccess); + return NULL; + } Tcl_Channel Tobe_FSOpenFileChannelProc @@ -1342,7 +1330,6 @@ int Tobe_FSStatProc _ANSI_ARGS_((Tcl_Obj *pathPtr, Tcl_StatBuf *buf)) { ** This routine does an access() system call for a ZVFS file. */ int Tobe_FSAccessProc _ANSI_ARGS_((Tcl_Obj *pathPtr, int mode)) { - int len; char *path=Tcl_GetString(pathPtr); ZvfsFile *pFile; @@ -1401,7 +1388,6 @@ int Tobe_FSMatchInDirectoryProc ( Tcl_HashEntry *pEntry; /* Hash table entry */ Tcl_HashSearch zSearch; /* Search all mount points */ ZvfsArchive *pArchive; /* The ZIP archive being mounted */ - Tcl_Obj *pVols=0, *pVol; char mountpt[200]; int i=1; mountpt[0]='/'; @@ -1474,7 +1460,7 @@ int Tobe_FSMatchInDirectoryProc ( } } } -done: + if (zPattern) { free(zPattern); } @@ -1801,7 +1787,6 @@ int Zvfs_Common_Init(Tcl_Interp *interp) { } int Zvfs_Init(Tcl_Interp *interp){ - int n; #ifdef USE_TCL_STUBS if( Tcl_InitStubs(interp,"8.0",0)==0 ){ return TCL_ERROR; @@ -1819,7 +1804,6 @@ int Zvfs_Init(Tcl_Interp *interp){ } int Zvfs_SafeInit(Tcl_Interp *interp){ - int n; #ifdef USE_TCL_STUBS if( Tcl_InitStubs(interp,"8.0",0)==0 ){ return TCL_ERROR; -- cgit v0.12 From 307bb5f72d17a66308509ba1001fc8ca502100c8 Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Mon, 20 Oct 2014 01:23:11 +0000 Subject: Removed the dual ported canonical path mapping scheme to allow Odie and FreeWrap to coexist. The results of both functions were functionally identical. --- generic/tclZipVfs.c | 100 ---------------------------------------------------- 1 file changed, 100 deletions(-) diff --git a/generic/tclZipVfs.c b/generic/tclZipVfs.c index d4f8f68..80230c3 100755 --- a/generic/tclZipVfs.c +++ b/generic/tclZipVfs.c @@ -167,105 +167,6 @@ int strchrcnt(char *str, char ch) { return cnt; } -#ifdef FREEWRAP -/* -** Concatenate zTail onto zRoot to form a pathname. zRoot will begin -** with "/". After concatenation, simplify the pathname be removing -** unnecessary ".." and "." directories. Under windows, make all -** characters lower case. -** -** Resulting pathname is returned. Space to hold the returned path is -** obtained from Tcl_Alloc() and should be freed by the calling function. -*/ -static char *CanonicalPath(const char *zRoot, const char *zTail){ - char *zPath; - int i, j, c; - -#ifdef __WIN32__ - if( isalpha(zTail[0]) && zTail[1]==':' ){ zTail += 2; } - if( zTail[0]=='\\' ){ zRoot = ""; zTail++; } - if( zTail[0]=='\\' ){ zRoot = "/"; zTail++; } // account for UNC style path -#endif - if( zTail[0]=='/' ){ zRoot = ""; zTail++; } - if( zTail[0]=='/' ){ zRoot = "/"; zTail++; } // account for UNC style path - zPath = (void *)Tcl_Alloc( strlen(zRoot) + strlen(zTail) + 2 ); - if( zPath==0 ) return 0; - sprintf(zPath, "%s/%s", zRoot, zTail); - for(i=j=0; (c = zPath[i])!=0; i++){ -#ifdef __WIN32__ - if( isupper(c) ) { if (maptolower) c = tolower(c); } - else if( c=='\\' ) c = '/'; -#endif - if( c=='/' ){ - int c2 = zPath[i+1]; - if( c2=='/' ) continue; - if( c2=='.' ){ - int c3 = zPath[i+2]; - if( c3=='/' || c3==0 ){ - i++; - continue; - } - if( c3=='.' && (zPath[i+3]=='.' || zPath[i+3]==0) ){ - i += 2; - while( j>0 && zPath[j-1]!='/' ){ j--; } - continue; - } - } - } - zPath[j++] = c; - } - if( j==0 ){ zPath[j++] = '/'; } - zPath[j] = 0; - return zPath; -} -/* -** Construct an absolute pathname in memory obtained from Tcl_Alloc -** that means the same file as the pathname given. -** -** Under windows, all backslash (\) charaters are converted to foward -** slash (/) and all upper case letters are converted to lower case. -** The drive letter (if present) is preserved. -*/ -static char *AbsolutePath(const char *z){ - Tcl_DString pwd; - char *zResult; - Tcl_DStringInit(&pwd); - if( *z!='/' -#ifdef __WIN32__ - && *z!='\\' && (!isalpha(*z) || z[1]!=':') -#endif - ){ - /* Case 1: "z" is a relative path. So prepend the current working - ** directory in order to generate an absolute path. Note that the - ** CanonicalPath() function takes care of converting upper to lower - ** case and (\) to (/) under windows. - */ - Tcl_GetCwd(0, &pwd); - zResult = CanonicalPath( Tcl_DStringValue(&pwd), z); - Tcl_DStringFree(&pwd); - } else { - /* Case 2: "z" is an absolute path already. We just need to make - ** a copy of it. Under windows, we need to convert upper to lower - ** case and (\) into (/) on the copy. - */ - zResult = (void *)Tcl_Alloc( strlen(z) + 1 ); - if( zResult==0 ) return 0; - strcpy(zResult, z); -#ifdef __WIN32__ - { - int i, c; - for(i=0; (c=zResult[i])!=0; i++){ - if( isupper(c) ) { - // zResult[i] = tolower(c); - } - else if( c=='\\' ) zResult[i] = '/'; - } - } -#endif - } - return zResult; -} -#else /* ** Concatenate zTail onto zRoot to form a pathname. zRoot will begin ** with "/". After concatenation, simplify the pathname be removing @@ -379,7 +280,6 @@ AbsolutePath( } return zResult; } -#endif /* ** Read a ZIP archive and make entries in the virutal file hash table for all -- cgit v0.12 From b2164040ac3124d35041c71e5ba733563db32443 Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Mon, 20 Oct 2014 19:59:19 +0000 Subject: Renamed "tclkit" to "tclzsh" Removed tclzsh from "make binaries". (It the user wants it, they have to ask for it. It requires a working Tclsh and an exernal Zip) --- unix/Makefile.in | 58 ++++++++++++++++++++++++++++---------------------------- win/Makefile.in | 50 ++++++++++++++++++++++++------------------------ 2 files changed, 54 insertions(+), 54 deletions(-) diff --git a/unix/Makefile.in b/unix/Makefile.in index 16721a9..918e9fc 100644 --- a/unix/Makefile.in +++ b/unix/Makefile.in @@ -169,11 +169,11 @@ INSTALL_DATA_DIR = ${INSTALL} -d -m 755 EXE_SUFFIX = @EXEEXT@ TCL_EXE = tclsh${EXE_SUFFIX} ifeq ($(SHARED_BUILD),0) -TCLKIT_BASE = tclkits +TCLZSH_BASE = tclzshs else -TCLKIT_BASE = tclkitd +TCLZSH_BASE = tclzshd endif -TCLKIT_EXE = ${TCLKIT_BASE}${EXE_SUFFIX} +TCLZSH_EXE = ${TCLZSH_BASE}${EXE_SUFFIX} TCLTEST_EXE = tcltest${EXE_SUFFIX} NATIVE_TCLSH = @TCLSH_PROG@ @@ -367,7 +367,7 @@ ZLIB_OBJS = Zadler32.o Zcompress.o Zcrc32.o Zdeflate.o Zinfback.o \ TCL_OBJS = ${GENERIC_OBJS} ${UNIX_OBJS} ${NOTIFY_OBJS} ${COMPAT_OBJS} \ ${OO_OBJS} @DL_OBJS@ @PLAT_OBJS@ -TCLKIT_OBJS = tclKitInit.o tclZipVfs.o tclZipVfsBoot.o +TCLZSH_OBJS = tclZipShInit.o tclZipVfs.o tclZipVfsBoot.o OBJS = ${TCL_OBJS} ${TOMMATH_OBJS} @DTRACE_OBJ@ @ZLIB_OBJS@ @@ -624,7 +624,7 @@ SRCS = $(GENERIC_SRCS) $(TOMMATH_SRCS) $(UNIX_SRCS) $(NOTIFY_SRCS) \ all: binaries libraries doc packages -binaries: ${LIB_FILE} ${TCL_EXE} ${TCLKIT_EXE} +binaries: ${LIB_FILE} ${TCL_EXE} libraries: @@ -667,36 +667,36 @@ null.zip: # Rather than force an install, pack the files we need into a # file system under our control -tclkit.vfs: - @echo "Building VFS File system in tclkit.vfs" +tclzsh.vfs: + @echo "Building VFS File system in tclzsh.vfs" @$(TCL_EXE) "$(TOP_DIR)/tools/mkVfs.tcl" \ - "$(UNIX_DIR)/tclkit.vfs/boot/tcl" "$(TOP_DIR)" unix + "$(UNIX_DIR)/tclzsh.vfs/boot/tcl" "$(TOP_DIR)" unix -tclkit: ${TCLKIT_EXE} +tclzsh: ${TCLZSH_EXE} -${TCLKIT_BASE}_bare: ${TCLKIT_OBJS} ${TCL_LIB_FILE} ${TCL_STUB_LIB_FILE} +${TCLZSH_BASE}_bare: ${TCLZSH_OBJS} ${TCL_LIB_FILE} ${TCL_STUB_LIB_FILE} ${CC} ${CFLAGS} ${LDFLAGS} \ - ${TCLKIT_OBJS} \ + ${TCLZSH_OBJS} \ @TCL_BUILD_LIB_SPEC@ \ ${LIBS} @EXTRA_TCLSH_LIBS@ \ - ${CC_SEARCH_FLAGS} -o ${TCLKIT_BASE}_bare + ${CC_SEARCH_FLAGS} -o ${TCLZSH_BASE}_bare # Builds an executable linked to the Tcl dynamic library -${TCLKIT_EXE}: ${TCLKIT_BASE}_bare null.zip tclkit.vfs - cp -f ${TCLKIT_BASE}_bare ${TCLKIT_BASE}.zip - cat null.zip >> ${TCLKIT_BASE}.zip - cd tclkit.vfs ; zip -rAq ${UNIX_DIR}/${TCLKIT_BASE}.zip . - mv ${TCLKIT_BASE}.zip ${TCLKIT_EXE} +${TCLZSH_EXE}: ${TCLZSH_BASE}_bare null.zip tclzsh.vfs + cp -f ${TCLZSH_BASE}_bare ${TCLZSH_BASE}.zip + cat null.zip >> ${TCLZSH_BASE}.zip + cd tclzsh.vfs ; zip -rAq ${UNIX_DIR}/${TCLZSH_BASE}.zip . + mv ${TCLZSH_BASE}.zip ${TCLZSH_EXE} # Builds an executable directly from the Tcl sources -tclkit-static: ${TCLKIT_OBJS} ${OBJS} ${ZLIB_OBJS} null.zip tclkit.vfs +tclzsh-static: ${TCLZSH_OBJS} ${OBJS} ${ZLIB_OBJS} null.zip tclzsh.vfs ${CC} ${CFLAGS} ${LDFLAGS} \ - ${TCLKIT_OBJS} ${OBJS} ${ZLIB_OBJS} \ + ${TCLZSH_OBJS} ${OBJS} ${ZLIB_OBJS} \ ${LIBS} @EXTRA_TCLSH_LIBS@ \ - ${CC_SEARCH_FLAGS} -o ${TCLKIT_EXE} - cat null.zip >> ${TCLKIT_EXE} - cd tclkit.vfs ; zip -rAq ${UNIX_DIR}/${TCLKIT_EXE} . + ${CC_SEARCH_FLAGS} -o ${TCLZSH_EXE} + cat null.zip >> ${TCLZSH_EXE} + cd tclzsh.vfs ; zip -rAq ${UNIX_DIR}/${TCLZSH_EXE} . Makefile: $(UNIX_DIR)/Makefile.in $(DLTEST_DIR)/Makefile.in $(SHELL) config.status @@ -706,8 +706,8 @@ Makefile: $(UNIX_DIR)/Makefile.in $(DLTEST_DIR)/Makefile.in clean: clean-packages rm -f *.a *.o libtcl* core errs *~ \#* TAGS *.E a.out \ errors ${TCL_EXE} ${TCLTEST_EXE} lib.exp Tcl @DTRACE_HDR@ \ - ${TCLKIT_EXE} tclkit* - rm -rf tclkit.vfs null.zip + ${TCLZSH_EXE} tclzsh* + rm -rf tclzsh.vfs null.zip cd dltest ; $(MAKE) clean distclean: distclean-packages clean @@ -851,8 +851,8 @@ install-binaries: binaries @chmod 555 "$(DLL_INSTALL_DIR)/$(LIB_FILE)" @echo "Installing ${TCL_EXE} as $(BIN_INSTALL_DIR)/tclsh$(VERSION)${EXE_SUFFIX}" @$(INSTALL_PROGRAM) ${TCL_EXE} "$(BIN_INSTALL_DIR)/tclsh$(VERSION)${EXE_SUFFIX}" - @echo "Installing ${TCLKIT_EXE} as $(BIN_INSTALL_DIR)/${TCLKIT_BASE}$(VERSION)${EXE_SUFFIX}" - @$(INSTALL_PROGRAM) ${TCLKIT_EXE} "$(BIN_INSTALL_DIR)/${TCLKIT_BASE}$(VERSION)${EXE_SUFFIX}" + @echo "Installing ${TCLZSH_EXE} as $(BIN_INSTALL_DIR)/${TCLZSH_BASE}$(VERSION)${EXE_SUFFIX}" + @$(INSTALL_PROGRAM) ${TCLZSH_EXE} "$(BIN_INSTALL_DIR)/${TCLZSH_BASE}$(VERSION)${EXE_SUFFIX}" @echo "Installing tclConfig.sh to $(CONFIG_INSTALL_DIR)/" @$(INSTALL_DATA) tclConfig.sh "$(CONFIG_INSTALL_DIR)/tclConfig.sh" @echo "Installing tclooConfig.sh to $(CONFIG_INSTALL_DIR)/" @@ -1076,9 +1076,9 @@ xtTestInit.o: $(UNIX_DIR)/tclAppInit.c ${TCL_EXE} mv tclAppInit.sav tclAppInit.o; \ fi; -tclKitInit.o: $(UNIX_DIR)/tclAppInit.c ${TCL_EXE} +tclZipShInit.o: $(UNIX_DIR)/tclAppInit.c ${TCL_EXE} $(CC) -c $(APP_CC_SWITCHES) \ - -DTCL_ZIPVFS $(UNIX_DIR)/tclAppInit.c -o tclKitInit.o + -DTCL_ZIPVFS $(UNIX_DIR)/tclAppInit.c -o tclZipShInit.o # Object files used on all Unix systems: @@ -2186,7 +2186,7 @@ BUILD_HTML = \ .PHONY: install-tzdata install-msgs .PHONY: packages configure-packages test-packages clean-packages .PHONY: dist-packages distclean-packages install-packages -.PHONY: tclkit-static tclkit +.PHONY: tclzsh-static tclzsh #-------------------------------------------------------------------------- # DO NOT DELETE THIS LINE -- make depend depends on it. diff --git a/win/Makefile.in b/win/Makefile.in index 0fba203..6877938 100644 --- a/win/Makefile.in +++ b/win/Makefile.in @@ -149,7 +149,7 @@ SHARED_LIBRARIES = $(TCL_DLL_FILE) @ZLIB_DLL_FILE@ STATIC_LIBRARIES = $(TCL_LIB_FILE) TCLSH = tclsh$(VER)${EXESUFFIX} -TCLKIT = tclkit$(VER)${EXESUFFIX} +TCLZSH = tclzsh$(VER)${EXESUFFIX} CAT32 = cat32$(EXEEXT) MAN2TCL = man2tcl$(EXEEXT) @@ -411,7 +411,7 @@ ZLIB_OBJS = \ TCL_OBJS = ${GENERIC_OBJS} $(TOMMATH_OBJS) ${WIN_OBJS} @ZLIB_OBJS@ -TCLKIT_OBJS = tclKitInit.$(OBJEXT) tclZipVfs.$(OBJEXT) tclZipVfsBoot.$(OBJEXT) +TCLZSH_OBJS = tclZipShInit.$(OBJEXT) tclZipVfs.$(OBJEXT) tclZipVfsBoot.$(OBJEXT) TCL_DOCS = "$(ROOT_DIR_NATIVE)"/doc/*.[13n] @@ -419,7 +419,7 @@ all: binaries libraries doc packages tcltest: $(TCLSH) $(TEST_DLL_FILE) -binaries: $(TCL_STUB_LIB_FILE) @LIBRARIES@ $(DDE_DLL_FILE) $(REG_DLL_FILE) $(TCLSH) $(TCLKIT) +binaries: $(TCL_STUB_LIB_FILE) @LIBRARIES@ $(DDE_DLL_FILE) $(REG_DLL_FILE) $(TCLSH) libraries: @@ -430,7 +430,7 @@ $(TCLSH): $(TCLSH_OBJS) @LIBRARIES@ $(TCL_STUB_LIB_FILE) tclsh.$(RES) tclsh.$(RES) $(CC_EXENAME) $(LDFLAGS_CONSOLE) @VC_MANIFEST_EMBED_EXE@ -tclkit: $(TCLKIT) +tclzsh: $(TCLZSH) null.zip: touch .empty @@ -438,33 +438,33 @@ null.zip: # Rather than force an install, pack the files we need into a # file system under our control -tclkit.vfs: $(TCLSH) $(DDE_DLL_FILE) $(REG_DLL_FILE) - @echo "Building VFS File system in tclkit.vfs" +tclzsh.vfs: $(TCLSH) $(DDE_DLL_FILE) $(REG_DLL_FILE) + @echo "Building VFS File system in tclzsh.vfs" @$(TCL_EXE) "$(ROOT_DIR)/tools/mkVfs.tcl" \ - "$(WIN_DIR)/tclkit.vfs/tcl$(VERSION)" "$(ROOT_DIR)" windows + "$(WIN_DIR)/tclzsh.vfs/tcl$(VERSION)" "$(ROOT_DIR)" windows -tclkit_bare: $(TCLKIT_OBJS) @LIBRARIES@ $(TCL_STUB_LIB_FILE) tclsh.$(RES) - $(CC) $(CFLAGS) $(TCLKIT_OBJS) $(TCL_LIB_FILE) $(TCL_STUB_LIB_FILE) $(LIBS) \ +tclzsh_bare: $(TCLZSH_OBJS) @LIBRARIES@ $(TCL_STUB_LIB_FILE) tclsh.$(RES) + $(CC) $(CFLAGS) $(TCLZSH_OBJS) $(TCL_LIB_FILE) $(TCL_STUB_LIB_FILE) $(LIBS) \ tclsh.$(RES) $(CC_EXENAME) $(LDFLAGS_CONSOLE) @VC_MANIFEST_EMBED_EXE@ -$(TCLKIT): tclkit_bare null.zip tclkit.vfs - cp tclkit_bare tclkit.zip - cat null.zip >> tclkit.zip - cd tclkit.vfs ; zip -rAq $(WIN_DIR)/tclkit.zip . - mv tclkit.zip $(TCLKIT) +$(TCLZSH): tclzsh_bare null.zip tclzsh.vfs + cp tclzsh_bare tclzsh.zip + cat null.zip >> tclzsh.zip + cd tclzsh.vfs ; zip -rAq $(WIN_DIR)/tclzsh.zip . + mv tclzsh.zip $(TCLZSH) # Builds an executable directly from the Tcl sources -tclkit-direct: $(TCLKIT_OBJS) ${GENERIC_OBJS} $(TOMMATH_OBJS) ${WIN_OBJS} ${ZLIB_OBJS} @LIBRARIES@ $(TCL_STUB_LIB_FILE) tclsh.$(RES) null.zip tclkit.vfs +tclzsh-direct: $(TCLZSH_OBJS) ${GENERIC_OBJS} $(TOMMATH_OBJS) ${WIN_OBJS} ${ZLIB_OBJS} @LIBRARIES@ $(TCL_STUB_LIB_FILE) tclsh.$(RES) null.zip tclzsh.vfs rm *.$(OBJEXT) - $(CC) $(CFLAGS) -DSTATIC_BUILD -UUSE_STUBS $(TCLKIT_OBJS) \ + $(CC) $(CFLAGS) -DSTATIC_BUILD -UUSE_STUBS $(TCLZSH_OBJS) \ ${GENERIC_OBJS} $(TOMMATH_OBJS) ${WIN_OBJS} ${ZLIB_OBJS} \ $(LIBS) \ tclsh.$(RES) $(CC_EXENAME) $(LDFLAGS_CONSOLE) @VC_MANIFEST_EMBED_EXE@ rm *.$(OBJEXT) - cat null.zip >> $(TCLKIT) - cd tclkit.vfs ; zip -rAq $(WIN_DIR)/$(TCLKIT) . + cat null.zip >> $(TCLZSH) + cd tclzsh.vfs ; zip -rAq $(WIN_DIR)/$(TCLZSH) . cat32.$(OBJEXT): cat.c $(CC) -c $(CC_SWITCHES) @DEPARG@ $(CC_OBJNAME) @@ -529,7 +529,7 @@ testMain.${OBJEXT}: tclAppInit.c tclMain2.${OBJEXT}: tclMain.c $(CC) -c $(CC_SWITCHES) -DBUILD_tcl -DTCL_ASCII_MAIN @DEPARG@ $(CC_OBJNAME) -tclKitInit.${OBJEXT}: tclAppInit.c +tclZipShInit.${OBJEXT}: tclAppInit.c $(CC) -c $(CC_SWITCHES) -DTCL_ZIPVFS @DEPARG@ $(CC_OBJNAME) # TIP #59, embedding of configuration information into the binary library. @@ -616,7 +616,7 @@ install-binaries: binaries else true; \ fi; \ done; - @for i in $(TCL_DLL_FILE) $(ZLIB_DLL_FILE) $(TCLSH) $(TCLKIT); \ + @for i in $(TCL_DLL_FILE) $(ZLIB_DLL_FILE) $(TCLSH) $(TCLZSH); \ do \ if [ -f $$i ]; then \ echo "Installing $$i to $(BIN_INSTALL_DIR)/"; \ @@ -781,9 +781,9 @@ cleanhelp: clean: cleanhelp clean-packages $(RM) *.lib *.a *.exp *.dll *.$(RES) *.${OBJEXT} *~ \#* TAGS a.out - $(RM) $(TCLSH) $(CAT32) $(TCLKIT) null.zip - $(RM) *.pch *.ilk *.pdb tclkit* - $(RMDIR) tclkit.vfs + $(RM) $(TCLSH) $(CAT32) $(TCLZSH) null.zip + $(RM) *.pch *.ilk *.pdb tclzsh* + $(RMDIR) tclzsh.vfs distclean: distclean-packages clean $(RM) Makefile config.status config.cache config.log tclConfig.sh \ @@ -915,8 +915,8 @@ html-tk: $(TCLSH) .PHONY: install-doc install-private-headers test test-tcl runtest shell .PHONY: gdb depend cleanhelp clean distclean packages install-packages .PHONY: test-packages clean-packages distclean-packages genstubs html -.PHONY: html-tcl html-tk tclkit -.PHONY: tclkit-direct tclkit-dynamic tclkit-kitlib +.PHONY: html-tcl html-tk tclzsh +.PHONY: tclzsh-direct tclzsh-dynamic tclzsh-kitlib # DO NOT DELETE THIS LINE -- make depend depends on it. -- cgit v0.12 From 6826dbab466f01f5d52b4ff477e810297aa96991 Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Mon, 20 Oct 2014 20:54:05 +0000 Subject: Added the zipfile::encode routine from Tcllib, and a rudimentary zipfile decode as a package "zvfstools" --- library/zvfstools/pkgIndex.tcl | 2 + library/zvfstools/zvfstools.tcl | 309 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 311 insertions(+) create mode 100644 library/zvfstools/pkgIndex.tcl create mode 100644 library/zvfstools/zvfstools.tcl diff --git a/library/zvfstools/pkgIndex.tcl b/library/zvfstools/pkgIndex.tcl new file mode 100644 index 0000000..23a8040 --- /dev/null +++ b/library/zvfstools/pkgIndex.tcl @@ -0,0 +1,2 @@ +if {![package vsatisfies [package provide zvfs] 1.0]} {return} +package ifneeded zvfstools 0.1 [list source [file join $dir zvfstools.tcl]] diff --git a/library/zvfstools/zvfstools.tcl b/library/zvfstools/zvfstools.tcl new file mode 100644 index 0000000..05119c6 --- /dev/null +++ b/library/zvfstools/zvfstools.tcl @@ -0,0 +1,309 @@ +# -*- tcl -*- +# ### ### ### ######### ######### ######### +## Copyright (c) 2008-2009 ActiveState Software Inc. +## Andreas Kupries +## Copyright (C) 2009 Pat Thoyts +## Copyright (C) 2014 Sean Woods +## +## BSD License +## +# Package providing commands for: +# * the generation of a zip archive, +# * building a zip archive from a file system +# * building a file system from a zip archive + +package require Tcl 8.6 +package require zvfs 1.0 +# Cop +# +# Create ZIP archives in Tcl. +# +# Create a zipkit using mkzip filename.zkit -zipkit -directory xyz.vfs +# or a zipfile using mkzip filename.zip -directory dirname -exclude "*~" +# + +proc ::zvfs::setbinary chan { + fconfigure $chan \ + -encoding binary \ + -translation binary \ + -eofchar {} + +} + +# zip::timet_to_dos +# +# Convert a unix timestamp into a DOS timestamp for ZIP times. +# +# DOS timestamps are 32 bits split into bit regions as follows: +# 24 16 8 0 +# +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ +# |Y|Y|Y|Y|Y|Y|Y|m| |m|m|m|d|d|d|d|d| |h|h|h|h|h|m|m|m| |m|m|m|s|s|s|s|s| +# +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ +# +proc ::zvfs::timet_to_dos {time_t} { + set s [clock format $time_t -format {%Y %m %e %k %M %S}] + scan $s {%d %d %d %d %d %d} year month day hour min sec + expr {(($year-1980) << 25) | ($month << 21) | ($day << 16) + | ($hour << 11) | ($min << 5) | ($sec >> 1)} +} + +# zip::pop -- +# +# Pop an element from a list +# +proc ::zvfs::pop {varname {nth 0}} { + upvar $varname args + set r [lindex $args $nth] + set args [lreplace $args $nth $nth] + return $r +} + +# zip::walk -- +# +# Walk a directory tree rooted at 'path'. The excludes list can be +# a set of glob expressions to match against files and to avoid. +# The match arg is internal. +# eg: walk library {CVS/* *~ .#*} to exclude CVS and emacs cruft. +# +proc ::zvfs::walk {base {excludes ""} {match *} {path {}}} { + set result {} + set imatch [file join $path $match] + set files [glob -nocomplain -tails -types f -directory $base $imatch] + foreach file $files { + set excluded 0 + foreach glob $excludes { + if {[string match $glob $file]} { + set excluded 1 + break + } + } + if {!$excluded} {lappend result $file} + } + foreach dir [glob -nocomplain -tails -types d -directory $base $imatch] { + set subdir [walk $base $excludes $match $dir] + if {[llength $subdir]>0} { + set result [concat $result [list $dir] $subdir] + } + } + return $result +} + +# zvfs::add_file_to_archive -- +# +# Add a single file to a zip archive. The zipchan channel should +# already be open and binary. You may provide a comment for the +# file The return value is the central directory record that +# will need to be used when finalizing the zip archive. +# +# FIX ME: should handle the current offset for non-seekable channels +# +proc ::zvfs::add_file_to_archive {zipchan base path {comment ""}} { + set fullpath [file join $base $path] + set mtime [timet_to_dos [file mtime $fullpath]] + if {[file isdirectory $fullpath]} { + append path / + } + set utfpath [encoding convertto utf-8 $path] + set utfcomment [encoding convertto utf-8 $comment] + set flags [expr {(1<<11)}] ;# utf-8 comment and path + set method 0 ;# store 0, deflate 8 + set attr 0 ;# text or binary (default binary) + set version 20 ;# minumum version req'd to extract + set extra "" + set crc 0 + set size 0 + set csize 0 + set data "" + set seekable [expr {[tell $zipchan] != -1}] + if {[file isdirectory $fullpath]} { + set attrex 0x41ff0010 ;# 0o040777 (drwxrwxrwx) + } elseif {[file executable $fullpath]} { + set attrex 0x81ff0080 ;# 0o100777 (-rwxrwxrwx) + } else { + set attrex 0x81b60020 ;# 0o100666 (-rw-rw-rw-) + if {[file extension $fullpath] in {".tcl" ".txt" ".c"}} { + set attr 1 ;# text + } + } + + if {[file isfile $fullpath]} { + set size [file size $fullpath] + if {!$seekable} {set flags [expr {$flags | (1 << 3)}]} + } + + set offset [tell $zipchan] + set local [binary format a4sssiiiiss PK\03\04 \ + $version $flags $method $mtime $crc $csize $size \ + [string length $utfpath] [string length $extra]] + append local $utfpath $extra + puts -nonewline $zipchan $local + + if {[file isfile $fullpath]} { + # If the file is under 2MB then zip in one chunk, otherwize we use + # streaming to avoid requiring excess memory. This helps to prevent + # storing re-compressed data that may be larger than the source when + # handling PNG or JPEG or nested ZIP files. + if {$size < 0x00200000} { + set fin [::open $fullpath rb] + setbinary $fin + set data [::read $fin] + set crc [::zlib crc32 $data] + set cdata [::zlib deflate $data] + if {[string length $cdata] < $size} { + set method 8 + set data $cdata + } + close $fin + set csize [string length $data] + puts -nonewline $zipchan $data + } else { + set method 8 + set fin [::open $fullpath rb] + setbinary $fin + set zlib [::zlib stream deflate] + while {![eof $fin]} { + set data [read $fin 4096] + set crc [zlib crc32 $data $crc] + $zlib put $data + if {[string length [set zdata [$zlib get]]]} { + incr csize [string length $zdata] + puts -nonewline $zipchan $zdata + } + } + close $fin + $zlib finalize + set zdata [$zlib get] + incr csize [string length $zdata] + puts -nonewline $zipchan $zdata + $zlib close + } + + if {$seekable} { + # update the header if the output is seekable + set local [binary format a4sssiiii PK\03\04 \ + $version $flags $method $mtime $crc $csize $size] + set current [tell $zipchan] + seek $zipchan $offset + puts -nonewline $zipchan $local + seek $zipchan $current + } else { + # Write a data descriptor record + set ddesc [binary format a4iii PK\7\8 $crc $csize $size] + puts -nonewline $zipchan $ddesc + } + } + + set hdr [binary format a4ssssiiiisssssii PK\01\02 0x0317 \ + $version $flags $method $mtime $crc $csize $size \ + [string length $utfpath] [string length $extra]\ + [string length $utfcomment] 0 $attr $attrex $offset] + append hdr $utfpath $extra $utfcomment + return $hdr +} + +# zvfs::mkzip -- +# +# Create a zip archive in 'filename'. If a file already exists it will be +# overwritten by a new file. If '-directory' is used, the new zip archive +# will be rooted in the provided directory. +# -runtime can be used to specify a prefix file. For instance, +# zip myzip -runtime unzipsfx.exe -directory subdir +# will create a self-extracting zip archive from the subdir/ folder. +# The -comment parameter specifies an optional comment for the archive. +# +# eg: zip my.zip -directory Subdir -runtime unzipsfx.exe *.txt +# +proc ::zvfs::mkzip {filename args} { + array set opts { + -zipkit 0 -runtime "" -comment "" -directory "" + -exclude {CVS/* */CVS/* *~ ".#*" "*/.#*"} + } + + while {[string match -* [set option [lindex $args 0]]]} { + switch -exact -- $option { + -zipkit { set opts(-zipkit) 1 } + -comment { set opts(-comment) [encoding convertto utf-8 [pop args 1]] } + -runtime { set opts(-runtime) [pop args 1] } + -directory {set opts(-directory) [file normalize [pop args 1]] } + -exclude {set opts(-exclude) [pop args 1] } + -- { pop args ; break } + default { + break + } + } + pop args + } + + set zf [::open $filename wb] + setbinary $zf + if {$opts(-runtime) ne ""} { + set rt [::open $opts(-runtime) rb] + setbinary $rt + fcopy $rt $zf + close $rt + } elseif {$opts(-zipkit)} { + set zkd "#!/usr/bin/env tclkit\n\# This is a zip-based Tcl Module\n" + append zkd "package require vfs::zip\n" + append zkd "vfs::zip::Mount \[info script\] \[info script\]\n" + append zkd "if {\[file exists \[file join \[info script\] main.tcl\]\]} \{\n" + append zkd " source \[file join \[info script\] main.tcl\]\n" + append zkd "\}\n" + append zkd \x1A + puts -nonewline $zf $zkd + } + + set count 0 + set cd "" + + if {$opts(-directory) ne ""} { + set paths [walk $opts(-directory) $opts(-exclude)] + } else { + set paths [glob -nocomplain {*}$args] + } + foreach path $paths { + puts $path + append cd [add_file_to_archive $zf $opts(-directory) $path] + incr count + } + set cdoffset [tell $zf] + set endrec [binary format a4ssssiis PK\05\06 0 0 \ + $count $count [string length $cd] $cdoffset\ + [string length $opts(-comment)]] + append endrec $opts(-comment) + puts -nonewline $zf $cd + puts -nonewline $zf $endrec + close $zf + + return +} + +### +# Decode routines +### +proc ::zvfs::copy_file {zipbase destbase file} { + set l [string length $zipbase] + set relname [string trimleft [string range $file $l end] /] + if {[file isdirectory $file]} { + foreach sfile [glob -nocomplain $file/*] { + file mkdir [file join $destbase $relname] + copy_file $zipbase $destbase $sfile + } + return + } + file copy -force $file [file join $destbase $relname] +} + +# ### ### ### ######### ######### ######### +## Convenience command, decode and copy to dir +proc ::zvfs::unzip {in out} { + set root /ziptmp#[incr ::zvfs::count] + zvfs::mount $in $root + set out [file normalize $out] + foreach file [glob $root/*] { + copy_file $root $out $file + } + zvfs::unmount $in + return +} + +package provide zvfstools 0.1 -- cgit v0.12 From 9171dde34641416c1530c7a8ba9aa49ca267a55c Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Tue, 21 Oct 2014 01:04:07 +0000 Subject: Replaced calls to zip with calls to the new pure-tcl zipfile encoder embedded in zvfstools. Fixed a bug in the encoder for zvfstools. It was exporting files, but not directories. This lack of directories was causing the bootloader to miss that /zvfs/boot/tcl/init.tcl existed, because it was checking for the existance of /zvfs/boot/tcl. I compared the archives created by zvfstools::mkzip to the archives created by zip, and the difference came down to the fact that zip did create TOC entries for directories and zvfstools::mkzip was failing to do so. (So I'm pretty sure the new behavior is "standard.") --- library/zvfstools/zvfstools.tcl | 28 ++++++++++++++++++++-------- tools/mkzip.tcl | 6 ++++++ unix/Makefile.in | 15 +++++---------- win/Makefile.in | 12 ++++++------ 4 files changed, 37 insertions(+), 24 deletions(-) create mode 100644 tools/mkzip.tcl diff --git a/library/zvfstools/zvfstools.tcl b/library/zvfstools/zvfstools.tcl index 05119c6..f755283 100644 --- a/library/zvfstools/zvfstools.tcl +++ b/library/zvfstools/zvfstools.tcl @@ -80,6 +80,7 @@ proc ::zvfs::walk {base {excludes ""} {match *} {path {}}} { if {!$excluded} {lappend result $file} } foreach dir [glob -nocomplain -tails -types d -directory $base $imatch] { + lappend result $dir set subdir [walk $base $excludes $match $dir] if {[llength $subdir]>0} { set result [concat $result [list $dir] $subdir] @@ -137,7 +138,7 @@ proc ::zvfs::add_file_to_archive {zipchan base path {comment ""}} { [string length $utfpath] [string length $extra]] append local $utfpath $extra puts -nonewline $zipchan $local - + if {[file isfile $fullpath]} { # If the file is under 2MB then zip in one chunk, otherwize we use # streaming to avoid requiring excess memory. This helps to prevent @@ -242,12 +243,24 @@ proc ::zvfs::mkzip {filename args} { fcopy $rt $zf close $rt } elseif {$opts(-zipkit)} { - set zkd "#!/usr/bin/env tclkit\n\# This is a zip-based Tcl Module\n" - append zkd "package require vfs::zip\n" - append zkd "vfs::zip::Mount \[info script\] \[info script\]\n" - append zkd "if {\[file exists \[file join \[info script\] main.tcl\]\]} \{\n" - append zkd " source \[file join \[info script\] main.tcl\]\n" - append zkd "\}\n" + set zkd {#!/usr/bin/env tclsh +# This is a zip-based Tcl Module +if {![package vsatisfies [package provide zvfs] 1.0]} { + package require vfs::zip + vfs::zip::Mount [info script] [info script] +} else { + zvfs::mount [info script] [info script] +} +# Load any CLIP file present +if {[file exists [file join [info script] pkgIndex.tcl]] } { + set dir [info script] + source [file join [info script] pkgIndex.tcl] +} +# Run any main.tcl present +if {[file exists [file join [info script] main.tcl]] } { + source [file join [info script] main.tcl] +} + } append zkd \x1A puts -nonewline $zf $zkd } @@ -261,7 +274,6 @@ proc ::zvfs::mkzip {filename args} { set paths [glob -nocomplain {*}$args] } foreach path $paths { - puts $path append cd [add_file_to_archive $zf $opts(-directory) $path] incr count } diff --git a/tools/mkzip.tcl b/tools/mkzip.tcl new file mode 100644 index 0000000..e53bae3 --- /dev/null +++ b/tools/mkzip.tcl @@ -0,0 +1,6 @@ +### +# Wrapper to allow access to Tcl's zvfs::mkzip command from Makefiles +### +package require zvfs +source [file join [file dirname [file normalize [info script]]] .. library zvfstools zvfstools.tcl] +zvfs::mkzip {*}$argv diff --git a/unix/Makefile.in b/unix/Makefile.in index 918e9fc..b635c0a 100644 --- a/unix/Makefile.in +++ b/unix/Makefile.in @@ -661,10 +661,6 @@ ${TCL_EXE}: ${TCLSH_OBJS} ${TCL_LIB_FILE} ${TCL_STUB_LIB_FILE} # Must be empty so it doesn't conflict with rule for ${TCL_EXE} above ${NATIVE_TCLSH}: -null.zip: - touch .empty - zip null.zip .empty - # Rather than force an install, pack the files we need into a # file system under our control tclzsh.vfs: @@ -681,13 +677,12 @@ ${TCLZSH_BASE}_bare: ${TCLZSH_OBJS} ${TCL_LIB_FILE} ${TCL_STUB_LIB_FILE} ${LIBS} @EXTRA_TCLSH_LIBS@ \ ${CC_SEARCH_FLAGS} -o ${TCLZSH_BASE}_bare - # Builds an executable linked to the Tcl dynamic library -${TCLZSH_EXE}: ${TCLZSH_BASE}_bare null.zip tclzsh.vfs - cp -f ${TCLZSH_BASE}_bare ${TCLZSH_BASE}.zip - cat null.zip >> ${TCLZSH_BASE}.zip - cd tclzsh.vfs ; zip -rAq ${UNIX_DIR}/${TCLZSH_BASE}.zip . - mv ${TCLZSH_BASE}.zip ${TCLZSH_EXE} +${TCLZSH_EXE}: ${TCLZSH_BASE}_bare tclzsh.vfs + ./${TCLZSH_BASE}_bare ../tools/mkzip.tcl ${TCLZSH_EXE} \ + -runtime ${TCLZSH_BASE}_bare \ + -directory tclzsh.vfs + chmod a+x ${TCLZSH_EXE} # Builds an executable directly from the Tcl sources tclzsh-static: ${TCLZSH_OBJS} ${OBJS} ${ZLIB_OBJS} null.zip tclzsh.vfs diff --git a/win/Makefile.in b/win/Makefile.in index 6877938..0b34570 100644 --- a/win/Makefile.in +++ b/win/Makefile.in @@ -441,18 +441,18 @@ null.zip: tclzsh.vfs: $(TCLSH) $(DDE_DLL_FILE) $(REG_DLL_FILE) @echo "Building VFS File system in tclzsh.vfs" @$(TCL_EXE) "$(ROOT_DIR)/tools/mkVfs.tcl" \ - "$(WIN_DIR)/tclzsh.vfs/tcl$(VERSION)" "$(ROOT_DIR)" windows + "$(WIN_DIR)/tclzsh.vfs/boot/tcl" "$(ROOT_DIR)" windows tclzsh_bare: $(TCLZSH_OBJS) @LIBRARIES@ $(TCL_STUB_LIB_FILE) tclsh.$(RES) $(CC) $(CFLAGS) $(TCLZSH_OBJS) $(TCL_LIB_FILE) $(TCL_STUB_LIB_FILE) $(LIBS) \ tclsh.$(RES) $(CC_EXENAME) $(LDFLAGS_CONSOLE) @VC_MANIFEST_EMBED_EXE@ -$(TCLZSH): tclzsh_bare null.zip tclzsh.vfs - cp tclzsh_bare tclzsh.zip - cat null.zip >> tclzsh.zip - cd tclzsh.vfs ; zip -rAq $(WIN_DIR)/tclzsh.zip . - mv tclzsh.zip $(TCLZSH) +$(TCLZSH): tclzsh_bare tclzsh.vfs + ./${TCLZSH_BASE}_bare ../tools/mkzip.tcl ${TCLZSH_EXE} \ + -runtime ${TCLZSH_BASE}_bare \ + -directory tclzsh.vfs + chmod a+x ${TCLZSH_EXE} # Builds an executable directly from the Tcl sources tclzsh-direct: $(TCLZSH_OBJS) ${GENERIC_OBJS} $(TOMMATH_OBJS) ${WIN_OBJS} ${ZLIB_OBJS} @LIBRARIES@ $(TCL_STUB_LIB_FILE) tclsh.$(RES) null.zip tclzsh.vfs -- cgit v0.12 From bdc43f824155a8ac53c6e6d3c332f4776dd81c9e Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Tue, 21 Oct 2014 01:11:22 +0000 Subject: Tweaked zvfstools to always allows the zvfs::mkzip command, and defer the check for the rest of the zvfs tools until the first call to zvfs::unzip --- library/zvfstools/pkgIndex.tcl | 1 - library/zvfstools/zvfstools.tcl | 6 ++++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/library/zvfstools/pkgIndex.tcl b/library/zvfstools/pkgIndex.tcl index 23a8040..824d5b3 100644 --- a/library/zvfstools/pkgIndex.tcl +++ b/library/zvfstools/pkgIndex.tcl @@ -1,2 +1 @@ -if {![package vsatisfies [package provide zvfs] 1.0]} {return} package ifneeded zvfstools 0.1 [list source [file join $dir zvfstools.tcl]] diff --git a/library/zvfstools/zvfstools.tcl b/library/zvfstools/zvfstools.tcl index f755283..26f17c4 100644 --- a/library/zvfstools/zvfstools.tcl +++ b/library/zvfstools/zvfstools.tcl @@ -13,7 +13,6 @@ # * building a file system from a zip archive package require Tcl 8.6 -package require zvfs 1.0 # Cop # # Create ZIP archives in Tcl. @@ -307,7 +306,11 @@ proc ::zvfs::copy_file {zipbase destbase file} { # ### ### ### ######### ######### ######### ## Convenience command, decode and copy to dir +## This routine relies on zvfs::mount, so we only load +## it when the zvfs package is present +## proc ::zvfs::unzip {in out} { + package require zvfs 1.0 set root /ziptmp#[incr ::zvfs::count] zvfs::mount $in $root set out [file normalize $out] @@ -317,5 +320,4 @@ proc ::zvfs::unzip {in out} { zvfs::unmount $in return } - package provide zvfstools 0.1 -- cgit v0.12 From 6b423f0d9ebf71415e7d74789128eb873a77ef3a Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Tue, 21 Oct 2014 01:20:10 +0000 Subject: Fixes to allow a standard tclsh build to do the zip file encoding, instead of having to do it all through the zip enabled shell. --- library/zvfstools/zvfstools.tcl | 2 ++ tools/mkzip.tcl | 1 - unix/Makefile.in | 4 ++-- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/library/zvfstools/zvfstools.tcl b/library/zvfstools/zvfstools.tcl index 26f17c4..274d5a1 100644 --- a/library/zvfstools/zvfstools.tcl +++ b/library/zvfstools/zvfstools.tcl @@ -21,6 +21,8 @@ package require Tcl 8.6 # or a zipfile using mkzip filename.zip -directory dirname -exclude "*~" # +namespace eval ::zvfs {} + proc ::zvfs::setbinary chan { fconfigure $chan \ -encoding binary \ diff --git a/tools/mkzip.tcl b/tools/mkzip.tcl index e53bae3..ba10908 100644 --- a/tools/mkzip.tcl +++ b/tools/mkzip.tcl @@ -1,6 +1,5 @@ ### # Wrapper to allow access to Tcl's zvfs::mkzip command from Makefiles ### -package require zvfs source [file join [file dirname [file normalize [info script]]] .. library zvfstools zvfstools.tcl] zvfs::mkzip {*}$argv diff --git a/unix/Makefile.in b/unix/Makefile.in index b635c0a..0819197 100644 --- a/unix/Makefile.in +++ b/unix/Makefile.in @@ -624,7 +624,7 @@ SRCS = $(GENERIC_SRCS) $(TOMMATH_SRCS) $(UNIX_SRCS) $(NOTIFY_SRCS) \ all: binaries libraries doc packages -binaries: ${LIB_FILE} ${TCL_EXE} +binaries: ${LIB_FILE} ${TCL_EXE} ${TCLZSH_EXE} libraries: @@ -679,7 +679,7 @@ ${TCLZSH_BASE}_bare: ${TCLZSH_OBJS} ${TCL_LIB_FILE} ${TCL_STUB_LIB_FILE} # Builds an executable linked to the Tcl dynamic library ${TCLZSH_EXE}: ${TCLZSH_BASE}_bare tclzsh.vfs - ./${TCLZSH_BASE}_bare ../tools/mkzip.tcl ${TCLZSH_EXE} \ + @$(TCL_EXE) ../tools/mkzip.tcl ${TCLZSH_EXE} \ -runtime ${TCLZSH_BASE}_bare \ -directory tclzsh.vfs chmod a+x ${TCLZSH_EXE} -- cgit v0.12 From 85442c797ca8332eedf0a57984b72eb987eacb06 Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Thu, 13 Nov 2014 14:30:26 +0000 Subject: Tweak to delete the tclzsh.vfs directory before the rm -rf tclvfs* statement in "make clean" --- unix/Makefile.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/unix/Makefile.in b/unix/Makefile.in index 0819197..119bf9a 100644 --- a/unix/Makefile.in +++ b/unix/Makefile.in @@ -699,10 +699,10 @@ Makefile: $(UNIX_DIR)/Makefile.in $(DLTEST_DIR)/Makefile.in # $(SHELL) config.status clean: clean-packages + rm -rf tclzsh.vfs null.zip rm -f *.a *.o libtcl* core errs *~ \#* TAGS *.E a.out \ errors ${TCL_EXE} ${TCLTEST_EXE} lib.exp Tcl @DTRACE_HDR@ \ ${TCLZSH_EXE} tclzsh* - rm -rf tclzsh.vfs null.zip cd dltest ; $(MAKE) clean distclean: distclean-packages clean -- cgit v0.12 From 3b50f8bcd682651d5ea2b8c0d5ba72b800a1b268 Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Thu, 13 Nov 2014 14:58:01 +0000 Subject: Removed _ANSI_ARGS_ macros. They were not compiling in Tk for some reason today... --- generic/tclZipVfs.c | 46 +++++++++++++++++++++++++++++----------------- 1 file changed, 29 insertions(+), 17 deletions(-) diff --git a/generic/tclZipVfs.c b/generic/tclZipVfs.c index 80230c3..e1dea4f 100755 --- a/generic/tclZipVfs.c +++ b/generic/tclZipVfs.c @@ -1192,9 +1192,12 @@ closeReleaseDie: } -Tcl_Channel Tobe_FSOpenFileChannelProc - _ANSI_ARGS_((Tcl_Interp *interp, Tcl_Obj *pathPtr, - int mode, int permissions)) { +Tcl_Channel Tobe_FSOpenFileChannelProc ( + Tcl_Interp *interp, + Tcl_Obj *pathPtr, + int mode, + int permissions +) { int len; /* if (mode != O_RDONLY) return NULL; */ return ZvfsFileOpen(interp, Tcl_GetStringFromObj(pathPtr,&len), 0, @@ -1204,7 +1207,10 @@ Tcl_Channel Tobe_FSOpenFileChannelProc /* ** This routine does a stat() system call for a ZVFS file. */ -int Tobe_FSStatProc _ANSI_ARGS_((Tcl_Obj *pathPtr, Tcl_StatBuf *buf)) { +int Tobe_FSStatProc ( + Tcl_Obj *pathPtr, + Tcl_StatBuf *buf +) { char *path=Tcl_GetString(pathPtr); ZvfsFile *pFile; @@ -1229,7 +1235,7 @@ int Tobe_FSStatProc _ANSI_ARGS_((Tcl_Obj *pathPtr, Tcl_StatBuf *buf)) { /* ** This routine does an access() system call for a ZVFS file. */ -int Tobe_FSAccessProc _ANSI_ARGS_((Tcl_Obj *pathPtr, int mode)) { +int Tobe_FSAccessProc (Tcl_Obj *pathPtr, int mode) { char *path=Tcl_GetString(pathPtr); ZvfsFile *pFile; @@ -1370,8 +1376,10 @@ int Tobe_FSMatchInDirectoryProc ( /* Function to check whether a path is in * this filesystem. This is the most * important filesystem procedure. */ -int Tobe_FSPathInFilesystemProc _ANSI_ARGS_((Tcl_Obj *pathPtr, - ClientData *clientDataPtr)) { +int Tobe_FSPathInFilesystemProc ( + Tcl_Obj *pathPtr, + ClientData *clientDataPtr +) { ZvfsFile *zFile; char *path = Tcl_GetString(pathPtr); @@ -1385,7 +1393,7 @@ int Tobe_FSPathInFilesystemProc _ANSI_ARGS_((Tcl_Obj *pathPtr, return -1; } -Tcl_Obj *Tobe_FSListVolumesProc _ANSI_ARGS_((void)) { +Tcl_Obj *Tobe_FSListVolumesProc (void) { Tcl_HashEntry *pEntry; /* Hash table entry */ Tcl_HashSearch zSearch; /* Search all mount points */ ZvfsArchive *pArchive; /* The ZIP archive being mounted */ @@ -1411,7 +1419,7 @@ Tcl_Obj *Tobe_FSListVolumesProc _ANSI_ARGS_((void)) { return pVols; } -int Tobe_FSChdirProc _ANSI_ARGS_((Tcl_Obj *pathPtr)) { +int Tobe_FSChdirProc (Tcl_Obj *pathPtr) { /* Someday, we should actually check if this is a valid path. */ return TCL_OK; } @@ -1437,9 +1445,12 @@ Tobe_FSFileAttrStringsProc( return attrs; } -int Tobe_FSFileAttrsGetProc _ANSI_ARGS_((Tcl_Interp *interp, - int index, Tcl_Obj *pathPtr, - Tcl_Obj **objPtrRef)) { +int Tobe_FSFileAttrsGetProc ( + Tcl_Interp *interp, + int index, + Tcl_Obj *pathPtr, + Tcl_Obj **objPtrRef +) { char *zFilename; ZvfsFile *pFile; zFilename = Tcl_GetString(pathPtr); @@ -1489,12 +1500,13 @@ int Tobe_FSFileAttrsGetProc _ANSI_ARGS_((Tcl_Interp *interp, } return TCL_OK; } -int Tobe_FSFileAttrsSetProc _ANSI_ARGS_((Tcl_Interp *interp, - int index, Tcl_Obj *pathPtr, - Tcl_Obj *objPtr)) { return TCL_ERROR; } +int Tobe_FSFileAttrsSetProc ( + Tcl_Interp *interp, + int index, + Tcl_Obj *pathPtr, + Tcl_Obj *objPtr) { return TCL_ERROR; } -Tcl_Obj* Tobe_FSFilesystemPathTypeProc - _ANSI_ARGS_((Tcl_Obj *pathPtr)) { +Tcl_Obj* Tobe_FSFilesystemPathTypeProc (Tcl_Obj *pathPtr) { return Tcl_NewStringObj("zip",-1); } -- cgit v0.12 From 9cbfbd034eadccd7a7b0e8dbca255772563e12a1 Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Thu, 13 Nov 2014 15:50:08 +0000 Subject: Add a mode for injecting the TkDll into the VFS --- tools/mkVfs.tcl | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tools/mkVfs.tcl b/tools/mkVfs.tcl index bc6f3aa..e670775 100644 --- a/tools/mkVfs.tcl +++ b/tools/mkVfs.tcl @@ -60,6 +60,8 @@ if {[llength $argv] < 3} { set TCL_SCRIPT_DIR [lindex $argv 0] set TCLSRC_ROOT [lindex $argv 1] set PLATFORM [lindex $argv 2] +set TKDLL [lindex $argv 3] +set TKVER [lindex $argv 4] puts "Building [file tail $TCL_SCRIPT_DIR] for $PLATFORM" copyDir ${TCLSRC_ROOT}/library ${TCL_SCRIPT_DIR} @@ -89,5 +91,9 @@ puts $fout {# # set VFSROOT $dir } +if {$TKDLL ne {} && [file exists $TKDLL]} { + file copy $TKDLL ${TCL_SCRIPT_DIR} + puts $fout [list package ifneeded Tk $TKVER "load \$dir $TKDLL"] +} pkgIndexDir ${TCL_SCRIPT_DIR} $fout ${TCL_SCRIPT_DIR} close $fout -- cgit v0.12 From 59490956934d2a83726ccbf16c5ce01fe269156a Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Sat, 15 Nov 2014 00:12:00 +0000 Subject: For the feature branch we now enable Zip file functions for all shells in Unix, and explicitly name a new executable "basekit", which is a statically linked tclsh with an attached library VFS --- unix/Makefile.in | 58 +++++++++++++++++++------------------------------------ unix/tclAppInit.c | 12 +++--------- 2 files changed, 23 insertions(+), 47 deletions(-) diff --git a/unix/Makefile.in b/unix/Makefile.in index 119bf9a..291f73b 100644 --- a/unix/Makefile.in +++ b/unix/Makefile.in @@ -168,12 +168,7 @@ INSTALL_DATA_DIR = ${INSTALL} -d -m 755 # Do not use SHELL_ENV for NATIVE_TCLSH unless it is the tclsh being built. EXE_SUFFIX = @EXEEXT@ TCL_EXE = tclsh${EXE_SUFFIX} -ifeq ($(SHARED_BUILD),0) -TCLZSH_BASE = tclzshs -else -TCLZSH_BASE = tclzshd -endif -TCLZSH_EXE = ${TCLZSH_BASE}${EXE_SUFFIX} +BASEKIT_EXE = basekit${EXE_SUFFIX} TCLTEST_EXE = tcltest${EXE_SUFFIX} NATIVE_TCLSH = @TCLSH_PROG@ @@ -290,7 +285,7 @@ LIBS = @TCL_LIBS@ DEPEND_SWITCHES = ${CFLAGS} -I${UNIX_DIR} -I${GENERIC_DIR} \ ${AC_FLAGS} ${PROTO_FLAGS} ${EXTRA_CFLAGS} @EXTRA_CC_SWITCHES@ -TCLSH_OBJS = tclAppInit.o +TCLSH_OBJS = tclAppInit.o tclZipVfs.o tclZipVfsBoot.o TCLTEST_OBJS = tclTestInit.o tclTest.o tclTestObj.o tclTestProcBodyObj.o \ tclThreadTest.o tclUnixTest.o @@ -367,8 +362,6 @@ ZLIB_OBJS = Zadler32.o Zcompress.o Zcrc32.o Zdeflate.o Zinfback.o \ TCL_OBJS = ${GENERIC_OBJS} ${UNIX_OBJS} ${NOTIFY_OBJS} ${COMPAT_OBJS} \ ${OO_OBJS} @DL_OBJS@ @PLAT_OBJS@ -TCLZSH_OBJS = tclZipShInit.o tclZipVfs.o tclZipVfsBoot.o - OBJS = ${TCL_OBJS} ${TOMMATH_OBJS} @DTRACE_OBJ@ @ZLIB_OBJS@ TCL_DECLS = \ @@ -624,7 +617,7 @@ SRCS = $(GENERIC_SRCS) $(TOMMATH_SRCS) $(UNIX_SRCS) $(NOTIFY_SRCS) \ all: binaries libraries doc packages -binaries: ${LIB_FILE} ${TCL_EXE} ${TCLZSH_EXE} +binaries: ${LIB_FILE} ${TCL_EXE} ${BASEKIT_EXE} libraries: @@ -663,35 +656,24 @@ ${NATIVE_TCLSH}: # Rather than force an install, pack the files we need into a # file system under our control -tclzsh.vfs: - @echo "Building VFS File system in tclzsh.vfs" +basekit.vfs: + @echo "Building VFS File system in basekit.vfs" @$(TCL_EXE) "$(TOP_DIR)/tools/mkVfs.tcl" \ - "$(UNIX_DIR)/tclzsh.vfs/boot/tcl" "$(TOP_DIR)" unix + "$(UNIX_DIR)/basekit.vfs/boot/tcl" "$(TOP_DIR)" unix -tclzsh: ${TCLZSH_EXE} +# Builds an executable directly from the Tcl sources +${BASEKIT_EXE}: ${TCLSH_OBJS} ${OBJS} ${ZLIB_OBJS} basekit.vfs -${TCLZSH_BASE}_bare: ${TCLZSH_OBJS} ${TCL_LIB_FILE} ${TCL_STUB_LIB_FILE} ${CC} ${CFLAGS} ${LDFLAGS} \ - ${TCLZSH_OBJS} \ - @TCL_BUILD_LIB_SPEC@ \ + ${TCLSH_OBJS} ${OBJS} ${ZLIB_OBJS} \ ${LIBS} @EXTRA_TCLSH_LIBS@ \ - ${CC_SEARCH_FLAGS} -o ${TCLZSH_BASE}_bare + ${CC_SEARCH_FLAGS} -o ${BASEKIT_EXE}_bare + @echo zipping... + @$(TCL_EXE) ../tools/mkzip.tcl ${BASEKIT_EXE} \ + -runtime ${BASEKIT_EXE}_bare \ + -directory basekit.vfs + chmod a+x ${BASEKIT_EXE} -# Builds an executable linked to the Tcl dynamic library -${TCLZSH_EXE}: ${TCLZSH_BASE}_bare tclzsh.vfs - @$(TCL_EXE) ../tools/mkzip.tcl ${TCLZSH_EXE} \ - -runtime ${TCLZSH_BASE}_bare \ - -directory tclzsh.vfs - chmod a+x ${TCLZSH_EXE} - -# Builds an executable directly from the Tcl sources -tclzsh-static: ${TCLZSH_OBJS} ${OBJS} ${ZLIB_OBJS} null.zip tclzsh.vfs - ${CC} ${CFLAGS} ${LDFLAGS} \ - ${TCLZSH_OBJS} ${OBJS} ${ZLIB_OBJS} \ - ${LIBS} @EXTRA_TCLSH_LIBS@ \ - ${CC_SEARCH_FLAGS} -o ${TCLZSH_EXE} - cat null.zip >> ${TCLZSH_EXE} - cd tclzsh.vfs ; zip -rAq ${UNIX_DIR}/${TCLZSH_EXE} . Makefile: $(UNIX_DIR)/Makefile.in $(DLTEST_DIR)/Makefile.in $(SHELL) config.status @@ -699,10 +681,10 @@ Makefile: $(UNIX_DIR)/Makefile.in $(DLTEST_DIR)/Makefile.in # $(SHELL) config.status clean: clean-packages - rm -rf tclzsh.vfs null.zip + rm -rf basekit.vfs null.zip rm -f *.a *.o libtcl* core errs *~ \#* TAGS *.E a.out \ errors ${TCL_EXE} ${TCLTEST_EXE} lib.exp Tcl @DTRACE_HDR@ \ - ${TCLZSH_EXE} tclzsh* + ${BASEKIT_EXE} basekit* cd dltest ; $(MAKE) clean distclean: distclean-packages clean @@ -846,8 +828,9 @@ install-binaries: binaries @chmod 555 "$(DLL_INSTALL_DIR)/$(LIB_FILE)" @echo "Installing ${TCL_EXE} as $(BIN_INSTALL_DIR)/tclsh$(VERSION)${EXE_SUFFIX}" @$(INSTALL_PROGRAM) ${TCL_EXE} "$(BIN_INSTALL_DIR)/tclsh$(VERSION)${EXE_SUFFIX}" - @echo "Installing ${TCLZSH_EXE} as $(BIN_INSTALL_DIR)/${TCLZSH_BASE}$(VERSION)${EXE_SUFFIX}" - @$(INSTALL_PROGRAM) ${TCLZSH_EXE} "$(BIN_INSTALL_DIR)/${TCLZSH_BASE}$(VERSION)${EXE_SUFFIX}" + @echo "Installing ${BASEKIT_EXE} as $(BIN_INSTALL_DIR)/${BASEKIT_EXE}$(VERSION)${EXE_SUFFIX}" + @$(INSTALL_PROGRAM) ${BASEKIT_EXE} "$(BIN_INSTALL_DIR)/${BASEKIT_EXE}$(VERSION)${EXE_SUFFIX}" + @echo "Installing tclConfig.sh to $(CONFIG_INSTALL_DIR)/" @$(INSTALL_DATA) tclConfig.sh "$(CONFIG_INSTALL_DIR)/tclConfig.sh" @echo "Installing tclooConfig.sh to $(CONFIG_INSTALL_DIR)/" @@ -2181,7 +2164,6 @@ BUILD_HTML = \ .PHONY: install-tzdata install-msgs .PHONY: packages configure-packages test-packages clean-packages .PHONY: dist-packages distclean-packages install-packages -.PHONY: tclzsh-static tclzsh #-------------------------------------------------------------------------- # DO NOT DELETE THIS LINE -- make depend depends on it. diff --git a/unix/tclAppInit.c b/unix/tclAppInit.c index 1be1ce3..4b5d1f6 100644 --- a/unix/tclAppInit.c +++ b/unix/tclAppInit.c @@ -40,12 +40,10 @@ extern Tcl_PackageInitProc Tclxttest_Init; #endif MODULE_SCOPE int TCL_LOCAL_APPINIT(Tcl_Interp *); MODULE_SCOPE int main(int, char **); -#ifdef TCL_ZIPVFS - MODULE_SCOPE int Tcl_Zvfs_Boot(const char *,const char *,const char *); - MODULE_SCOPE int Zvfs_Init(Tcl_Interp *); - MODULE_SCOPE int Zvfs_SafeInit(Tcl_Interp *); +MODULE_SCOPE int Tcl_Zvfs_Boot(const char *,const char *,const char *); +MODULE_SCOPE int Zvfs_Init(Tcl_Interp *); +MODULE_SCOPE int Zvfs_SafeInit(Tcl_Interp *); -#endif /* TCL_ZIPVFS */ /* * The following #if block allows you to change how Tcl finds the startup * script, prime the library or encoding paths, fiddle with the argv, etc., @@ -85,13 +83,11 @@ main( #ifdef TCL_LOCAL_MAIN_HOOK TCL_LOCAL_MAIN_HOOK(&argc, &argv); #endif -#ifdef TCL_ZIPVFS #define TCLKIT_INIT "main.tcl" #define TCLKIT_VFSMOUNT "/zvfs" Tcl_FindExecutable(argv[0]); CONST char *cp=Tcl_GetNameOfExecutable(); Tcl_Zvfs_Boot(cp,TCLKIT_VFSMOUNT,TCLKIT_INIT); -#endif Tcl_Main(argc, argv, TCL_LOCAL_APPINIT); return 0; /* Needed only to prevent compiler warning. */ } @@ -122,13 +118,11 @@ Tcl_AppInit( if ((Tcl_Init)(interp) == TCL_ERROR) { return TCL_ERROR; } -#ifdef TCL_ZIPVFS /* Load the ZipVfs package */ Tcl_StaticPackage(interp, "zvfs", Zvfs_Init, Zvfs_SafeInit); if(Zvfs_Init(interp) == TCL_ERROR) { return TCL_ERROR; } -#endif #ifdef TCL_XT_TEST if (Tclxttest_Init(interp) == TCL_ERROR) { return TCL_ERROR; -- cgit v0.12 From ded95f89d34b0a06df4a2faed54558431643170f Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Mon, 17 Nov 2014 15:04:05 +0000 Subject: Added the zvfstools file to the installer --- unix/Makefile.in | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/unix/Makefile.in b/unix/Makefile.in index 291f73b..be769a4 100644 --- a/unix/Makefile.in +++ b/unix/Makefile.in @@ -617,7 +617,7 @@ SRCS = $(GENERIC_SRCS) $(TOMMATH_SRCS) $(UNIX_SRCS) $(NOTIFY_SRCS) \ all: binaries libraries doc packages -binaries: ${LIB_FILE} ${TCL_EXE} ${BASEKIT_EXE} +binaries: ${LIB_FILE} ${TCL_EXE} ${BASEKIT_EXE}_bare basekit.zip libraries: @@ -661,6 +661,10 @@ basekit.vfs: @$(TCL_EXE) "$(TOP_DIR)/tools/mkVfs.tcl" \ "$(UNIX_DIR)/basekit.vfs/boot/tcl" "$(TOP_DIR)" unix +basekit.zip: basekit.vfs + @$(TCL_EXE) ../tools/mkzip.tcl basekit.zip \ + -directory basekit.vfs + # Builds an executable directly from the Tcl sources ${BASEKIT_EXE}: ${TCLSH_OBJS} ${OBJS} ${ZLIB_OBJS} basekit.vfs @@ -828,8 +832,12 @@ install-binaries: binaries @chmod 555 "$(DLL_INSTALL_DIR)/$(LIB_FILE)" @echo "Installing ${TCL_EXE} as $(BIN_INSTALL_DIR)/tclsh$(VERSION)${EXE_SUFFIX}" @$(INSTALL_PROGRAM) ${TCL_EXE} "$(BIN_INSTALL_DIR)/tclsh$(VERSION)${EXE_SUFFIX}" - @echo "Installing ${BASEKIT_EXE} as $(BIN_INSTALL_DIR)/${BASEKIT_EXE}$(VERSION)${EXE_SUFFIX}" - @$(INSTALL_PROGRAM) ${BASEKIT_EXE} "$(BIN_INSTALL_DIR)/${BASEKIT_EXE}$(VERSION)${EXE_SUFFIX}" + @echo "Installing ${BASEKIT_EXE}_bare as $(BIN_INSTALL_DIR)/${BASEKIT_EXE}$(VERSION)${EXE_SUFFIX}" + @$(INSTALL_PROGRAM) ${BASEKIT_EXE}_bare "$(BIN_INSTALL_DIR)/${BASEKIT_EXE}$(VERSION)${EXE_SUFFIX}" + + @echo "Installing basekit.zip as $(BIN_INSTALL_DIR)/basekit$(VERSION).zip" + @$(INSTALL_PROGRAM) basekit.zip "$(BIN_INSTALL_DIR)/basekit$(VERSION).zip" + @echo "Installing tclConfig.sh to $(CONFIG_INSTALL_DIR)/" @$(INSTALL_DATA) tclConfig.sh "$(CONFIG_INSTALL_DIR)/tclConfig.sh" @@ -890,6 +898,9 @@ install-libraries: libraries @echo "Installing package platform::shell 1.1.4 as a Tcl Module"; @$(INSTALL_DATA) $(TOP_DIR)/library/platform/shell.tcl "$(SCRIPT_INSTALL_DIR)"/../tcl8/8.4/platform/shell-1.1.4.tm; + @echo "Installing package zvfstools 0.1 as a Tcl Module"; + @$(INSTALL_DATA) $(TOP_DIR)/library/zvfstools/zvfstools.tcl "$(SCRIPT_INSTALL_DIR)"/../tcl8/8.6/zvfstools-0.1.tm; + @echo "Installing encoding files to $(SCRIPT_INSTALL_DIR)/encoding/"; @for i in $(TOP_DIR)/library/encoding/*.enc ; do \ $(INSTALL_DATA) $$i "$(SCRIPT_INSTALL_DIR)"/encoding; \ -- cgit v0.12 From dd60d528143a4f125200655aee2defc814066401 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Sat, 17 Jan 2015 18:40:19 +0000 Subject: apply contributed patch which fixes a segfault --- generic/tclCmdMZ.c | 4 ++++ generic/tclStringObj.c | 31 ++++++++++++++++++++++++------- 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/generic/tclCmdMZ.c b/generic/tclCmdMZ.c index 4ed353e..58196a3 100644 --- a/generic/tclCmdMZ.c +++ b/generic/tclCmdMZ.c @@ -1085,6 +1085,10 @@ Tcl_SplitObjCmd( for ( ; stringPtr < end; stringPtr += len) { len = TclUtfToUniChar(stringPtr, &ch); + + if (!len) { + continue; + } /* * Assume Tcl_UniChar is an integral type... diff --git a/generic/tclStringObj.c b/generic/tclStringObj.c index 2df6dd8..0ae5a7c 100644 --- a/generic/tclStringObj.c +++ b/generic/tclStringObj.c @@ -672,6 +672,7 @@ Tcl_GetRange( { Tcl_Obj *newObjPtr; /* The Tcl object to find the range of. */ String *stringPtr; + int i, firstoffset = 0, lastoffset = 0; /* * Optimize the case where we're really dealing with a bytearray object @@ -716,7 +717,17 @@ Tcl_GetRange( stringPtr = GET_STRING(objPtr); } - return Tcl_NewUnicodeObj(stringPtr->unicode + first, last-first+1); + for (i = 0; i <= last + lastoffset + firstoffset; i++) { + if ((stringPtr->unicode[i] & 0xfc00) == 0xd800) { + if (i < first + firstoffset) { + firstoffset++; + } else { + lastoffset++; + } + } + } + + return Tcl_NewUnicodeObj(stringPtr->unicode + first + firstoffset, last-first+1 + lastoffset + firstoffset); } /* @@ -2866,8 +2877,8 @@ ExtendUnicodeRepWithString( int numAppendChars) { String *stringPtr = GET_STRING(objPtr); - int needed, numOrigChars = 0; - Tcl_UniChar *dst; + int incr, needed, numOrigChars = 0; + Tcl_UniChar *dst, unichar = 0; if (stringPtr->hasUnicode) { numOrigChars = stringPtr->numChars; @@ -2890,7 +2901,12 @@ ExtendUnicodeRepWithString( numAppendChars = 0; } for (dst=stringPtr->unicode + numOrigChars; numAppendChars-- > 0; dst++) { - bytes += TclUtfToUniChar(bytes, dst); + bytes += (incr = TclUtfToUniChar(bytes, &unichar)); + *dst = unichar; + if (!incr) { + bytes += TclUtfToUniChar(bytes, &unichar); + *++dst = unichar; + } } *dst = 0; } @@ -3095,7 +3111,7 @@ ExtendStringRepWithUnicode( * Pre-condition: this is the "string" Tcl_ObjType. */ - int i, origLength, size = 0; + int incr, i, origLength, size = 0, offset = 0; char *dst, buf[TCL_UTF_MAX]; String *stringPtr = GET_STRING(objPtr); @@ -3121,8 +3137,9 @@ ExtendStringRepWithUnicode( goto copyBytes; } - for (i = 0; i < numChars && size >= 0; i++) { - size += Tcl_UniCharToUtf((int) unicode[i], buf); + for (i = 0; i < numChars + offset && size >= 0; i++) { + size += (incr = Tcl_UniCharToUtf((int) unicode[i], buf)); + if (!incr) offset++; } if (size < 0) { Tcl_Panic("max size for a Tcl value (%d bytes) exceeded", INT_MAX); -- cgit v0.12 From adceea62b6fc04fb2a4d41dd0a31adb3011c3147 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Sun, 21 Jun 2015 22:29:11 +0000 Subject: Branch for androwish, as help to keep track on which android-specific changes could be included into the core without harm. --- Android.mk | 202 ++++ debian/changelog | 23 + debian/compat | 1 + debian/control | 37 + debian/copyright | 141 +++ debian/rules | 131 ++ debian/sdltcl8.6-dev.dirs | 2 + debian/sdltcl8.6-dev.files | 2 + debian/sdltcl8.6-doc.files | 2 + debian/sdltcl8.6.files | 18 + debian/shlibs.local | 1 + generic/tclEncoding.c | 10 + generic/tclIOUtil.c | 74 +- generic/tclInt.decls | 12 + generic/tclIntDecls.h | 19 + generic/tclMain.c | 146 ++- generic/tclPkgConfig.c | 20 + generic/tclStubInit.c | 9 + generic/zcrypt.h | 131 ++ generic/zipfs.c | 2867 ++++++++++++++++++++++++++++++++++++++++++++ generic/zipfs.h | 43 + pkgs/Android.mk | 1 + tcl-config.mk | 60 + unix/Makefile.in | 11 +- unix/tclLoadDl.c | 40 +- unix/tclUnixFCmd.c | 21 + unix/tclUnixInit.c | 5 + unix/tclUnixPort.h | 2 + unix/tclUnixTime.c | 5 +- win/Makefile.in | 5 +- 30 files changed, 4027 insertions(+), 14 deletions(-) create mode 100644 Android.mk create mode 100644 debian/changelog create mode 100644 debian/compat create mode 100644 debian/control create mode 100644 debian/copyright create mode 100755 debian/rules create mode 100644 debian/sdltcl8.6-dev.dirs create mode 100644 debian/sdltcl8.6-dev.files create mode 100644 debian/sdltcl8.6-doc.files create mode 100644 debian/sdltcl8.6.files create mode 100644 debian/shlibs.local create mode 100644 generic/zcrypt.h create mode 100644 generic/zipfs.c create mode 100644 generic/zipfs.h create mode 100644 pkgs/Android.mk create mode 100644 tcl-config.mk diff --git a/Android.mk b/Android.mk new file mode 100644 index 0000000..9d8ce27 --- /dev/null +++ b/Android.mk @@ -0,0 +1,202 @@ +LOCAL_PATH := $(call my-dir) + +########################### +# +# Tcl shared library +# +########################### + +include $(CLEAR_VARS) + +tcl_path := $(LOCAL_PATH) + +include $(tcl_path)/tcl-config.mk + +LOCAL_MODULE := tcl + +LOCAL_ARM_MODE := arm + +LOCAL_C_INCLUDES := $(tcl_includes) $(LOCAL_PATH)/libtommath + +LOCAL_EXPORT_C_INCLUDES := $(LOCAL_C_INCLUDES) + +LOCAL_SRC_FILES := \ + libtommath/bncore.c \ + libtommath/bn_reverse.c \ + libtommath/bn_fast_s_mp_mul_digs.c \ + libtommath/bn_fast_s_mp_sqr.c \ + libtommath/bn_mp_add.c \ + libtommath/bn_mp_add_d.c \ + libtommath/bn_mp_and.c \ + libtommath/bn_mp_clamp.c \ + libtommath/bn_mp_clear.c \ + libtommath/bn_mp_clear_multi.c \ + libtommath/bn_mp_cmp.c \ + libtommath/bn_mp_cmp_d.c \ + libtommath/bn_mp_cmp_mag.c \ + libtommath/bn_mp_copy.c \ + libtommath/bn_mp_cnt_lsb.c \ + libtommath/bn_mp_count_bits.c \ + libtommath/bn_mp_div.c \ + libtommath/bn_mp_div_d.c \ + libtommath/bn_mp_div_2.c \ + libtommath/bn_mp_div_2d.c \ + libtommath/bn_mp_div_3.c \ + libtommath/bn_mp_exch.c \ + libtommath/bn_mp_expt_d.c \ + libtommath/bn_mp_grow.c \ + libtommath/bn_mp_init.c \ + libtommath/bn_mp_init_copy.c \ + libtommath/bn_mp_init_multi.c \ + libtommath/bn_mp_init_set.c \ + libtommath/bn_mp_init_set_int.c \ + libtommath/bn_mp_init_size.c \ + libtommath/bn_mp_karatsuba_mul.c \ + libtommath/bn_mp_karatsuba_sqr.c \ + libtommath/bn_mp_lshd.c \ + libtommath/bn_mp_mod.c \ + libtommath/bn_mp_mod_2d.c \ + libtommath/bn_mp_mul.c \ + libtommath/bn_mp_mul_2.c \ + libtommath/bn_mp_mul_2d.c \ + libtommath/bn_mp_mul_d.c \ + libtommath/bn_mp_neg.c \ + libtommath/bn_mp_or.c \ + libtommath/bn_mp_radix_size.c \ + libtommath/bn_mp_radix_smap.c \ + libtommath/bn_mp_read_radix.c \ + libtommath/bn_mp_rshd.c \ + libtommath/bn_mp_set.c \ + libtommath/bn_mp_set_int.c \ + libtommath/bn_mp_shrink.c \ + libtommath/bn_mp_sqr.c \ + libtommath/bn_mp_sqrt.c \ + libtommath/bn_mp_sub.c \ + libtommath/bn_mp_sub_d.c \ + libtommath/bn_mp_to_unsigned_bin.c \ + libtommath/bn_mp_to_unsigned_bin_n.c \ + libtommath/bn_mp_toom_mul.c \ + libtommath/bn_mp_toom_sqr.c \ + libtommath/bn_mp_toradix_n.c \ + libtommath/bn_mp_unsigned_bin_size.c \ + libtommath/bn_mp_xor.c \ + libtommath/bn_mp_zero.c \ + libtommath/bn_s_mp_add.c \ + libtommath/bn_s_mp_mul_digs.c \ + libtommath/bn_s_mp_sqr.c \ + libtommath/bn_s_mp_sub.c \ + generic/regcomp.c \ + generic/regexec.c \ + generic/regfree.c \ + generic/regerror.c \ + generic/tclAlloc.c \ + generic/tclAssembly.c \ + generic/tclAsync.c \ + generic/tclBasic.c \ + generic/tclBinary.c \ + generic/tclCkalloc.c \ + generic/tclClock.c \ + generic/tclCmdAH.c \ + generic/tclCmdIL.c \ + generic/tclCmdMZ.c \ + generic/tclCompCmds.c \ + generic/tclCompCmdsGR.c \ + generic/tclCompCmdsSZ.c \ + generic/tclCompExpr.c \ + generic/tclCompile.c \ + generic/tclConfig.c \ + generic/tclDate.c \ + generic/tclDictObj.c \ + generic/tclDisassemble.c \ + generic/tclEncoding.c \ + generic/tclEnsemble.c \ + generic/tclEnv.c \ + generic/tclEvent.c \ + generic/tclExecute.c \ + generic/tclFCmd.c \ + generic/tclFileName.c \ + generic/tclGet.c \ + generic/tclHash.c \ + generic/tclHistory.c \ + generic/tclIndexObj.c \ + generic/tclInterp.c \ + generic/tclIO.c \ + generic/tclIOCmd.c \ + generic/tclIOGT.c \ + generic/tclIOSock.c \ + generic/tclIOUtil.c \ + generic/tclIORChan.c \ + generic/tclIORTrans.c \ + generic/tclLink.c \ + generic/tclListObj.c \ + generic/tclLiteral.c \ + generic/tclLoad.c \ + generic/tclMain.c \ + generic/tclNamesp.c \ + generic/tclNotify.c \ + generic/tclObj.c \ + generic/tclOptimize.c \ + generic/tclPanic.c \ + generic/tclParse.c \ + generic/tclPathObj.c \ + generic/tclPipe.c \ + generic/tclPkg.c \ + generic/tclPkgConfig.c \ + generic/tclPosixStr.c \ + generic/tclPreserve.c \ + generic/tclProc.c \ + generic/tclRegexp.c \ + generic/tclResolve.c \ + generic/tclResult.c \ + generic/tclScan.c \ + generic/tclStubInit.c \ + generic/tclStringObj.c \ + generic/tclStrToD.c \ + generic/tclThread.c \ + generic/tclThreadAlloc.c \ + generic/tclThreadJoin.c \ + generic/tclThreadStorage.c \ + generic/tclTimer.c \ + generic/tclTomMathInterface.c \ + generic/tclTrace.c \ + generic/tclUtil.c \ + generic/tclUtf.c \ + generic/tclVar.c \ + generic/tclZlib.c \ + generic/tclOO.c \ + generic/tclOOBasic.c \ + generic/tclOOCall.c \ + generic/tclOODefineCmds.c \ + generic/tclOOInfo.c \ + generic/tclOOMethod.c \ + generic/tclOOStubInit.c \ + generic/tclStubLib.c \ + generic/tclTomMathStubLib.c \ + generic/tclOOStubLib.c \ + generic/zipfs.c \ + unix/tclAppInit.c \ + unix/tclLoadDl.c \ + unix/tclUnixChan.c \ + unix/tclUnixCompat.c \ + unix/tclUnixEvent.c \ + unix/tclUnixFCmd.c \ + unix/tclUnixFile.c \ + unix/tclUnixInit.c \ + unix/tclUnixNotfy.c \ + unix/tclUnixPipe.c \ + unix/tclUnixSock.c \ + unix/tclUnixTest.c \ + unix/tclUnixThrd.c \ + unix/tclUnixTime.c + +LOCAL_CFLAGS := $(tcl_cflags) \ + -DPACKAGE_NAME="\"tcl\"" \ + -DPACKAGE_VERSION="\"8.6\"" \ + -DBUILD_tcl=1 \ + -Dmain=tclsh \ + -O2 + +LOCAL_LDLIBS := -ldl -lz -llog + +include $(BUILD_SHARED_LIBRARY) + diff --git a/debian/changelog b/debian/changelog new file mode 100644 index 0000000..caad3ba --- /dev/null +++ b/debian/changelog @@ -0,0 +1,23 @@ +sdltcl8.6 (8.6.4-1) unstable; urgency=low + + * Update to 8.6.4 + + -- Christian Werner Thu, 12 Mar 2015 22:00:00 +0100 + +sdltcl8.6 (8.6.3-1) unstable; urgency=low + + * Update to 8.6.3 + + -- Christian Werner Wed, 12 Nov 2014 20:00:00 +0100 + +sdltcl8.6 (8.6.2-1) unstable; urgency=low + + * Update to 8.6.2 + + -- Christian Werner Thu, 28 Aug 2014 07:10:10 +0200 + +sdltcl8.6 (8.6.1-1) unstable; urgency=low + + * Initial packaging + + -- Christian Werner Sat, 05 Apr 2014 14:44:48 +0200 diff --git a/debian/compat b/debian/compat new file mode 100644 index 0000000..7ed6ff8 --- /dev/null +++ b/debian/compat @@ -0,0 +1 @@ +5 diff --git a/debian/control b/debian/control new file mode 100644 index 0000000..3434297 --- /dev/null +++ b/debian/control @@ -0,0 +1,37 @@ +Source: sdltcl8.6 +Section: libs +Priority: optional +Maintainer: +Build-Depends: debhelper (>= 5.0.0), quilt +Standards-Version: 3.8.3 +Homepage: http://www.tcl.tk/ + +Package: sdltcl8.6 +Section: interpreters +Priority: optional +Architecture: any +Depends: ${shlibs:Depends} +Description: Tcl (the Tool Command Language) v8.6 - run-time files + Tcl is a powerful, easy to use, embeddable, cross-platform interpreted + scripting language. This package contains everything you need to run + Tcl scripts and Tcl-enabled apps. This version includes thread support. + +Package: sdltcl8.6-doc +Section: doc +Priority: optional +Architecture: all +Suggests: sdltcl8.6 +Description: Tcl (the Tool Command Language) v8.6 - manual pages + Tcl is a powerful, easy-to-use, embeddable, cross-platform interpreted + scripting language. This package contains the man pages for Tcl commands. + +Package: sdltcl8.6-dev +Section: devel +Priority: optional +Architecture: any +Depends: sdltcl8.6 (= ${binary:Version}) +Suggests: sdltcl8.6-doc +Description: Tcl (the Tool Command Language) v8.6 - development files + Tcl is a powerful, easy-to-use, embeddable, cross-platform interpreted + scripting language. This package contains the headers and libraries + needed to embed or extend Tcl. diff --git a/debian/copyright b/debian/copyright new file mode 100644 index 0000000..075c312 --- /dev/null +++ b/debian/copyright @@ -0,0 +1,141 @@ +This package was originally debianized by David Engel +from sources obtained at http://prdownloads.sourceforge.net/tcl + +List of copyright holders mentioned in individual files: + +Copyright 1983, 1988-1994 The Regents of the University of California +Copyright 1991-1999 Karl Lehenbauer and Mark Diekhans +Copyright 1992-1996 Free Software Foundation, Inc. +Copyright 1993-1994 Lockheed Missle & Space Company, AI Center +Copyright 1993-1997 Bell Labs Innovations for Lucent Technologies +Copyright 1993-1997 Lucent Technologies +Copyright 1994-1998 Sun Microsystems, Inc. +Copyright 1995 General Electric Company +Copyright 1995 Dave Nebinger +Copyright 1995-1997 Roger E. Critchlow Jr +Copyright 1996 Lucent Technologies and Jim Ingham +Copyright 1997-2000 Ajuba Solutions +Copyright 1998-2000 Scriptics Corporation +Copyright 1998-1999 Henry Spencer +Copyright 1998 Paul Duffin +Copyright 1998 Mark Harrison +Copyright 1999 America Online, Inc. +Copyright 1999-2000 Andreas Kupries +Copyright 2000-2001 ActiveState Corporation, et al +Copyright 2001 ActiveState Tool Corp. +Copyright 2001-2002 Apple Computer, Inc. +Copyright 2001-2002 ActiveState Corporation +Copyright 2001-2002 Vincent Darley +Copyright 2001-2002 Donal K. Fellows +Copyright 2001-2003 Kevin B. Kenny +Copyright 2001-2002 David Gravereaux +Contributions from Don Porter, NIST, 2002-2003. (not subject to US copyright) +Copyright 2005 Tcl Core Team +Copyright 2005 Daniel A. Steffen + +Copyright: + +This software is copyrighted by the Regents of the University of +California, Sun Microsystems, Inc., Scriptics Corporation, +and other parties. The following terms apply to all files associated +with the software unless explicitly disclaimed in individual files. + +The authors hereby grant permission to use, copy, modify, distribute, +and license this software and its documentation for any purpose, provided +that existing copyright notices are retained in all copies and that this +notice is included verbatim in any distributions. No written agreement, +license, or royalty fee is required for any of the authorized uses. +Modifications to this software may be copyrighted by their authors +and need not follow the licensing terms described here, provided that +the new terms are clearly indicated on the first page of each file where +they apply. + +IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY +FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES +ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY +DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE +IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE +NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR +MODIFICATIONS. + +GOVERNMENT USE: If you are acquiring this software on behalf of the +U.S. government, the Government shall have only "Restricted Rights" +in the software and related documentation as defined in the Federal +Acquisition Regulations (FARs) in Clause 52.227.19 (c) (2). If you +are acquiring the software on behalf of the Department of Defense, the +software shall be classified as "Commercial Computer Software" and the +Government shall have only "Restricted Rights" as defined in Clause +252.227-7013 (c) (1) of DFARs. Notwithstanding the foregoing, the +authors grant the U.S. Government and others acting in its behalf +permission to use and distribute the software in accordance with the +terms specified in this license. + +Several files are distributed under other conditions: + +compat/strftime.c: +/* + * strftime.c -- + * + * This file contains a modified version of the BSD 4.4 strftime + * function. + * + * This file is a modified version of the strftime.c file from the BSD 4.4 + * source. See the copyright notice below for details on redistribution + * restrictions. The "license.terms" file does not apply to this file. + * + * Changes 2002 Copyright (c) 2002 ActiveState Corporation. + * + * RCS: @(#) $Id: strftime.c,v 1.10.2.3 2005/11/04 18:18:04 kennykb Exp $ + */ + +/* + * Copyright (c) 1989 The Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +compat/dlfcn.h and unix/tclLoadAix.c: + * This file is subject to the following copyright notice, which is + * different from the notice used elsewhere in Tcl but rougly + * equivalent in meaning. + * + * Copyright (c) 1992,1993,1995,1996, Jens-Uwe Mager, Helios Software GmbH + * Not derived from licensed software. + * + * Permission is granted to freely use, copy, modify, and redistribute + * this software, provided that the author is not construed to be liable + * for any results of using the software, alterations are clearly marked + * as such, and this notice is not modified. + diff --git a/debian/rules b/debian/rules new file mode 100755 index 0000000..7a0214c --- /dev/null +++ b/debian/rules @@ -0,0 +1,131 @@ +#!/usr/bin/make -f +# debian/rules that uses debhelper. + +# Uncomment this to turn on verbose mode. +#export DH_VERBOSE=1 + +DEB_HOST_GNU_TYPE := $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE) +DEB_BUILD_GNU_TYPE := $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE) + +export QUILT_PATCHES := debian/patches + +v = 8.6 + +ifneq (,$(findstring debug,$(DEB_BUILD_OPTIONS))) +CFLAGS=-g -O0 +else +# See bug #446335 +CFLAGS=-g -O2 -fno-unit-at-a-time +endif + +CFLAGS+=-DZIPFS_IN_TCL=1 + +unpatch: + dh_testdir + quilt pop -a || test $$? = 2 + rm -rf patch-stamp .pc + +patch: patch-stamp +patch-stamp: + dh_testdir + quilt push -a || test $$? = 2 + touch patch-stamp + +build: build-stamp +build-stamp: patch-stamp + dh_testdir +# So so ugly but it works... + touch generic/tclStubInit.c + cd unix && \ + CFLAGS="$(CFLAGS)" \ + ac_cv_func_strtod=yes \ + tcl_cv_strtod_buggy=1 \ + ./configure --host=$(DEB_HOST_GNU_TYPE) \ + --build=$(DEB_BUILD_GNU_TYPE) \ + --prefix=/opt/sdltk86 \ + --includedir=/opt/sdltk86/include \ + --enable-shared \ + --mandir=/opt/sdltk86/man \ + --enable-man-symlinks \ + --enable-man-compression=gzip \ + --enable-threads \ + --without-tzdata && \ + touch ../generic/tclStubInit.c && \ + $(MAKE) +# Build the static library. + cd unix && \ + ar cr libtcl$(v).a *.o && \ + ar d libtcl$(v).a tclAppInit.o && \ + ranlib libtcl$(v).a + touch build-stamp + +clean: clean-patched unpatch + dh_testdir + dh_testroot + dh_clean + +clean-patched: + dh_testdir + dh_testroot + rm -f build-stamp install-stamp + cd unix && [ ! -f Makefile ] || $(MAKE) distclean +# Remove forgotten files + rm -f tests/pkg/pkga.so unix/config.log unix/Tcltest.so + +install: install-stamp +install-stamp: build-stamp + dh_testdir + dh_testroot + dh_clean -k + dh_installdirs + cd unix && \ + GZIP=-9 \ + $(MAKE) INSTALL_ROOT=`pwd`/../debian/tmp \ + MAN_INSTALL_DIR=`pwd`/../debian/tmp/opt/sdltk86/man \ + install install-private-headers install-packages +# Fix up the libraries. + cp unix/libtcl$(v).a debian/tmp/opt/sdltk86/lib + touch install-stamp + +# Build architecture-independent files here. +binary-indep: build install + dh_testdir -i + dh_testroot -i + dh_movefiles -i + dh_installdocs -i + dh_installchangelogs -i ChangeLog + dh_compress -i + dh_fixperms -i + dh_installdeb -i + dh_gencontrol -i + dh_md5sums -i + dh_builddeb -i + +# Build architecture-dependent files here. +binary-arch: build install + dh_testdir -a + dh_testroot -a + dh_movefiles -a +# now, fix up file locations for .sh + mv debian/sdltcl$(v)/opt/sdltk86/lib/tclConfig.sh \ + debian/sdltcl$(v)-dev/opt/sdltk86/lib + dh_installdocs -a + dh_installmenu -a + dh_installchangelogs -a ChangeLog + dh_fixperms -a + dh_strip -a + dh_compress -a + dh_makeshlibs -a -V 'sdltcl$(v) (>= 8.6.2)' -XTcltest + dh_installdeb -a + dh_shlibdeps -a -ldebian/sdltcl$(v)/opt/sdltk86/lib + dh_gencontrol -a + dh_md5sums -a + dh_builddeb -a + +source diff: + @echo >&2 'source and diff are obsolete - use dpkg-source -b'; false + +binary: binary-indep binary-arch + +.PHONY: patch unpatch clean-patched build clean binary-indep binary-arch binary install + diff --git a/debian/sdltcl8.6-dev.dirs b/debian/sdltcl8.6-dev.dirs new file mode 100644 index 0000000..4de4819 --- /dev/null +++ b/debian/sdltcl8.6-dev.dirs @@ -0,0 +1,2 @@ +opt/sdltk86/lib +opt/sdltk86/include diff --git a/debian/sdltcl8.6-dev.files b/debian/sdltcl8.6-dev.files new file mode 100644 index 0000000..5cd0878 --- /dev/null +++ b/debian/sdltcl8.6-dev.files @@ -0,0 +1,2 @@ +opt/sdltk86/include +opt/sdltk86/lib/*.a diff --git a/debian/sdltcl8.6-doc.files b/debian/sdltcl8.6-doc.files new file mode 100644 index 0000000..56ca7e7 --- /dev/null +++ b/debian/sdltcl8.6-doc.files @@ -0,0 +1,2 @@ +opt/sdltk86/man/man3 +opt/sdltk86/man/mann diff --git a/debian/sdltcl8.6.files b/debian/sdltcl8.6.files new file mode 100644 index 0000000..501d10a --- /dev/null +++ b/debian/sdltcl8.6.files @@ -0,0 +1,18 @@ +opt/sdltk86/bin +opt/sdltk86/lib/tcl8 +opt/sdltk86/lib/tcl8/* +opt/sdltk86/lib/tcl8.6 +opt/sdltk86/lib/tcl8.6/* +opt/sdltk86/lib/*.so +opt/sdltk86/lib/*.sh +opt/sdltk86/lib/itcl* +opt/sdltk86/lib/itcl*/* +opt/sdltk86/lib/pkgconfig +opt/sdltk86/lib/pkgconfig/* +opt/sdltk86/lib/sqlite* +opt/sdltk86/lib/sqlite*/* +opt/sdltk86/lib/tdbc* +opt/sdltk86/lib/tdbc*/* +opt/sdltk86/lib/thread* +opt/sdltk86/lib/thread*/* +opt/sdltk86/man/man1 diff --git a/debian/shlibs.local b/debian/shlibs.local new file mode 100644 index 0000000..7da5dd4 --- /dev/null +++ b/debian/shlibs.local @@ -0,0 +1 @@ +libtcl8.6 1 diff --git a/generic/tclEncoding.c b/generic/tclEncoding.c index a7ef199..35caf11 100644 --- a/generic/tclEncoding.c +++ b/generic/tclEncoding.c @@ -496,7 +496,11 @@ FillEncodingFileMap(void) Tcl_Obj *directory, *matchFileList = Tcl_NewObj(); Tcl_Obj **filev; Tcl_GlobTypeData readableFiles = { +#ifdef ZIPFS_IN_TCL + TCL_GLOB_TYPE_FILE | TCL_GLOB_TYPE_DIR, TCL_GLOB_PERM_R, NULL, NULL +#else TCL_GLOB_TYPE_FILE, TCL_GLOB_PERM_R, NULL, NULL +#endif }; Tcl_ListObjIndex(NULL, searchPath, i, &directory); @@ -508,7 +512,13 @@ FillEncodingFileMap(void) Tcl_ListObjGetElements(NULL, matchFileList, &numFiles, &filev); for (j=0; jnextPtr) { +#ifdef ZIPFS_IN_TCL + if (fsRecPtr->fsPtr == &zipfsFilesystem) { + ClientData clientData = NULL; + /* + * Allow mounted zipfs filesystem to overtake entire normalisation. + * This is needed on unix for mounts on symlinks right below root. + */ + + if (fsRecPtr->fsPtr->pathInFilesystemProc != NULL) { + if (fsRecPtr->fsPtr->pathInFilesystemProc(pathPtr, + &clientData)!=-1) { + TclFSSetPathDetails(pathPtr, fsRecPtr->fsPtr, clientData); + break; + } + } + continue; + } +#endif if (fsRecPtr->fsPtr != &tclNativeFilesystem) { continue; } @@ -1423,6 +1455,11 @@ TclFSNormalizeToUniquePath( if (fsRecPtr->fsPtr == &tclNativeFilesystem) { continue; } +#ifdef ZIPFS_IN_TCL + if (fsRecPtr->fsPtr == &zipfsFilesystem) { + continue; + } +#endif if (fsRecPtr->fsPtr->normalizePathProc != NULL) { startAt = fsRecPtr->fsPtr->normalizePathProc(interp, pathPtr, @@ -2890,15 +2927,32 @@ int Tcl_FSChdir( Tcl_Obj *pathPtr) { - const Tcl_Filesystem *fsPtr; + ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&fsDataKey); + const Tcl_Filesystem *fsPtr, *oldFsPtr = NULL; int retVal = -1; + if (tsdPtr->cwdPathPtr != NULL) { + oldFsPtr = Tcl_FSGetFileSystemForPath(tsdPtr->cwdPathPtr); + } if (Tcl_FSGetNormalizedPath(NULL, pathPtr) == NULL) { Tcl_SetErrno(ENOENT); return retVal; } fsPtr = Tcl_FSGetFileSystemForPath(pathPtr); + + if ((fsPtr != NULL) && (fsPtr != &tclNativeFilesystem)) { + /* + * Watch out for tilde substitution. + * Only valid in native filesystem. + */ + char *name = Tcl_GetString(pathPtr); + + if ((name != NULL) && (*name == '~')) { + fsPtr = &tclNativeFilesystem; + } + } + if (fsPtr != NULL) { if (fsPtr->chdirProc != NULL) { /* @@ -3009,6 +3063,14 @@ Tcl_FSChdir( } else { FsUpdateCwd(normDirName, NULL); } + + /* + * If the filesystem changed between old and new cwd + * force filesystem refresh on path objects. + */ + if (oldFsPtr != NULL && fsPtr != oldFsPtr) { + Tcl_FSMountsChanged(NULL); + } } return retVal; diff --git a/generic/tclInt.decls b/generic/tclInt.decls index 9f7b106..6298708 100644 --- a/generic/tclInt.decls +++ b/generic/tclInt.decls @@ -1012,6 +1012,18 @@ declare 251 { int TclRegisterLiteral(void *envPtr, char *bytes, int length, int flags) } + +declare 252 { + int Tclzipfs_Init(Tcl_Interp *interp) +} +declare 253 { + int Tclzipfs_Mount(Tcl_Interp *interp, const char *zipname, + const char *mntpt, const char *passwd) +} +declare 254 { + int Tclzipfs_Unmount(Tcl_Interp *interp, const char *zipname) +} + ############################################################################## diff --git a/generic/tclIntDecls.h b/generic/tclIntDecls.h index f95f999..3e74bbb 100644 --- a/generic/tclIntDecls.h +++ b/generic/tclIntDecls.h @@ -617,6 +617,16 @@ EXTERN void TclSetSlaveCancelFlags(Tcl_Interp *interp, int flags, /* 251 */ EXTERN int TclRegisterLiteral(void *envPtr, char *bytes, int length, int flags); +/* 252 */ +EXTERN int Tclzipfs_Init(Tcl_Interp *interp); +/* 253 */ +EXTERN int Tclzipfs_Mount(Tcl_Interp *interp, + const char *zipname, const char *mntpt, + const char *passwd); +/* 254 */ +EXTERN int Tclzipfs_Unmount(Tcl_Interp *interp, + const char *zipname); + typedef struct TclIntStubs { int magic; @@ -874,6 +884,9 @@ typedef struct TclIntStubs { char * (*tclDoubleDigits) (double dv, int ndigits, int flags, int *decpt, int *signum, char **endPtr); /* 249 */ void (*tclSetSlaveCancelFlags) (Tcl_Interp *interp, int flags, int force); /* 250 */ int (*tclRegisterLiteral) (void *envPtr, char *bytes, int length, int flags); /* 251 */ + int (*tclzipfs_Init) (Tcl_Interp *interp); /* 252 */ + int (*tclzipfs_Mount) (Tcl_Interp *interp, const char *zipname, const char *mntpt, const char *passwd); /* 253 */ + int (*tclzipfs_Unmount) (Tcl_Interp *interp, const char *zipname); /* 254 */ } TclIntStubs; extern const TclIntStubs *tclIntStubsPtr; @@ -1305,6 +1318,12 @@ extern const TclIntStubs *tclIntStubsPtr; (tclIntStubsPtr->tclSetSlaveCancelFlags) /* 250 */ #define TclRegisterLiteral \ (tclIntStubsPtr->tclRegisterLiteral) /* 251 */ +#define Tclzipfs_Init \ + (tclIntStubsPtr->tclzipfs_Init) /* 252 */ +#define Tclzipfs_Mount \ + (tclIntStubsPtr->tclzipfs_Mount) /* 253 */ +#define Tclzipfs_Unmount \ + (tclIntStubsPtr->tclzipfs_Unmount) /* 254 */ #endif /* defined(USE_TCL_STUBS) */ diff --git a/generic/tclMain.c b/generic/tclMain.c index 360f5e9..2c40c3f 100644 --- a/generic/tclMain.c +++ b/generic/tclMain.c @@ -34,6 +34,10 @@ #include "tclInt.h" +#ifdef ZIPFS_IN_TCL +#include "zipfs.h" +#endif + /* * The default prompt used when the user has not overridden it. */ @@ -51,6 +55,7 @@ # define TCHAR char # define TEXT(arg) arg # define _tcscmp strcmp +# define _tcsncmp strncmp #endif /* @@ -308,10 +313,16 @@ Tcl_MainEx( { Tcl_Obj *path, *resultPtr, *argvPtr, *appName; const char *encodingName = NULL; - int code, exitCode = 0; + int code, length, exitCode = 0; Tcl_MainLoopProc *mainLoopProc; Tcl_Channel chan; InteractiveState is; + const char *zipFile = NULL; + Tcl_Obj *zipval = NULL; + int autoRun = 1; +#ifdef ZIPFS_IN_TCL + int zipOk = TCL_ERROR; +#endif TclpSetInitialEncodings(); TclpFindExecutable((const char *)argv[0]); @@ -344,6 +355,24 @@ Tcl_MainEx( Tcl_DecrRefCount(value); argc -= 3; argv += 3; + } else if (argc > 2) { + length = strlen((char *) argv[1]); + if ((length >= 2) && + (0 == _tcsncmp(TEXT("-zip"), argv[1], length))) { + argc--; + argv++; + if ((argc > 1) && (argv[1][0] != (TCHAR) '-')) { + zipval = NewNativeObj(argv[1], -1); + zipFile = Tcl_GetString(zipval); + autoRun = 0; + argc--; + argv++; + } + } else if ('-' != argv[1][0]) { + Tcl_SetStartupScript(NewNativeObj(argv[1], -1), NULL); + argc--; + argv++; + } } else if ((argc > 1) && ('-' != argv[1][0])) { Tcl_SetStartupScript(NewNativeObj(argv[1], -1), NULL); argc--; @@ -377,6 +406,51 @@ Tcl_MainEx( Tcl_SetVar2Ex(interp, "tcl_interactive", NULL, Tcl_NewIntObj(!path && is.tty), TCL_GLOBAL_ONLY); +#ifdef ZIPFS_IN_TCL + zipOk = Tclzipfs_Init(interp); + if (zipOk == TCL_OK) { + int relax = 0; + + if (zipFile == NULL) { + relax = 1; +#ifdef ANDROID + zipFile = getenv("PACKAGE_CODE_PATH"); + if (zipFile == NULL) { + zipFile = Tcl_GetNameOfExecutable(); + } +#else + zipFile = Tcl_GetNameOfExecutable(); +#endif + } + if (zipFile != NULL) { + zipOk = Tclzipfs_Mount(interp, zipFile, "", NULL); + if (!relax && (zipOk != TCL_OK)) { + exitCode = 1; + goto done; + } + } else { + zipOk = TCL_ERROR; + } + Tcl_ResetResult(interp); + } + if (zipOk == TCL_OK) { + char *tcl_lib = "/assets/tcl" TCL_VERSION; + char *tcl_pkg = "/assets"; + + Tcl_SetVar2(interp, "env", "TCL_LIBRARY", tcl_lib, TCL_GLOBAL_ONLY); + Tcl_SetVar(interp, "tcl_libPath", tcl_lib, TCL_GLOBAL_ONLY); + Tcl_SetVar(interp, "tcl_library", tcl_lib, TCL_GLOBAL_ONLY); + Tcl_SetVar(interp, "tcl_pkgPath", tcl_pkg, TCL_GLOBAL_ONLY); + Tcl_SetVar(interp, "auto_path", tcl_lib, + TCL_GLOBAL_ONLY | TCL_LIST_ELEMENT); + + } +#endif + if (zipval != NULL) { + Tcl_DecrRefCount(zipval); + zipval = NULL; + } + /* * Invoke application-specific initialization. */ @@ -406,6 +480,76 @@ Tcl_MainEx( Tcl_CreateExitHandler(FreeMainInterp, interp); } +#ifdef ZIPFS_IN_TCL + /* + * Setup auto loading info to point to mounted ZIP file. + */ + + if (zipOk == TCL_OK) { + char *tcl_lib = "/assets/tcl" TCL_VERSION; + char *tcl_pkg = "/assets"; + + Tcl_SetVar(interp, "tcl_libPath", tcl_lib, TCL_GLOBAL_ONLY); + Tcl_SetVar(interp, "tcl_library", tcl_lib, TCL_GLOBAL_ONLY); + Tcl_SetVar(interp, "tcl_pkgPath", tcl_pkg, TCL_GLOBAL_ONLY); + + /* + * We need to re-init encoding (after initializing Tcl), + * otherwise "encoding system" will return "identity" + */ + + TclpSetInitialEncodings(); + } + + /* + * Set embedded application startup file, if any. + */ + + if ((zipOk == TCL_OK) && autoRun) { + char *filename; + Tcl_Channel chan; + + filename = "/assets/app/main.tcl"; + chan = Tcl_OpenFileChannel(NULL, filename, "r", 0); + if (chan != (Tcl_Channel) NULL) { + Tcl_Obj *arg; + + Tcl_Close(NULL, chan); + + /* + * Push back script file to argv, if any. + */ + if ((arg = Tcl_GetStartupScript(NULL)) != NULL) { + Tcl_Obj *v, *no; + + no = Tcl_NewStringObj("argv", 4); + v = Tcl_ObjGetVar2(interp, no, NULL, TCL_GLOBAL_ONLY); + if (v != NULL) { + Tcl_Obj **objv, *nv; + int objc, i; + + objc = 0; + Tcl_ListObjGetElements(NULL, v, &objc, &objv); + nv = Tcl_NewListObj(1, &arg); + for (i = 0; i < objc; i++) { + Tcl_ListObjAppendElement(NULL, nv, objv[i]); + } + Tcl_IncrRefCount(nv); + if (Tcl_ObjSetVar2(interp, no, NULL, nv, TCL_GLOBAL_ONLY) + != NULL) { + Tcl_GlobalEval(interp, "incr argc"); + } + Tcl_DecrRefCount(nv); + } + Tcl_DecrRefCount(no); + } + Tcl_SetStartupScript(Tcl_NewStringObj(filename, -1), NULL); + Tcl_SetVar(interp, "argv0", filename, TCL_GLOBAL_ONLY); + Tcl_SetVar(interp, "tcl_interactive", "0", TCL_GLOBAL_ONLY); + } + } +#endif + /* * Invoke the script specified on the command line, if any. Must fetch it * again, as the appInitProc might have reset it. diff --git a/generic/tclPkgConfig.c b/generic/tclPkgConfig.c index 466d535..3f8178e 100644 --- a/generic/tclPkgConfig.c +++ b/generic/tclPkgConfig.c @@ -100,19 +100,35 @@ static Tcl_Config const cfg[] = { /* Runtime paths to various stuff */ +#ifdef ANDROID + {"libdir,runtime", ""}, + {"bindir,runtime", ""}, + {"scriptdir,runtime", ""}, + {"includedir,runtime", ""}, + {"docdir,runtime", ""}, +#else {"libdir,runtime", CFG_RUNTIME_LIBDIR}, {"bindir,runtime", CFG_RUNTIME_BINDIR}, {"scriptdir,runtime", CFG_RUNTIME_SCRDIR}, {"includedir,runtime", CFG_RUNTIME_INCDIR}, {"docdir,runtime", CFG_RUNTIME_DOCDIR}, +#endif /* Installation paths to various stuff */ +#ifdef ANDROID + {"libdir,install", ""}, + {"bindir,install", ""}, + {"scriptdir,install", ""}, + {"includedir,install", ""}, + {"docdir,install", ""}, +#else {"libdir,install", CFG_INSTALL_LIBDIR}, {"bindir,install", CFG_INSTALL_BINDIR}, {"scriptdir,install", CFG_INSTALL_SCRDIR}, {"includedir,install", CFG_INSTALL_INCDIR}, {"docdir,install", CFG_INSTALL_DOCDIR}, +#endif /* Last entry, closes the array */ {NULL, NULL} @@ -123,6 +139,10 @@ TclInitEmbeddedConfigurationInformation( Tcl_Interp *interp) /* Interpreter the configuration command is * registered in. */ { +#if defined(ANDROID) && !defined(TCL_CFGVAL_ENCODING) +#define TCL_CFGVAL_ENCODING "utf-8" +#endif + Tcl_RegisterConfig(interp, "tcl", cfg, TCL_CFGVAL_ENCODING); } diff --git a/generic/tclStubInit.c b/generic/tclStubInit.c index 7a84cba..d3e0afa 100644 --- a/generic/tclStubInit.c +++ b/generic/tclStubInit.c @@ -560,6 +560,15 @@ static const TclIntStubs tclIntStubs = { TclDoubleDigits, /* 249 */ TclSetSlaveCancelFlags, /* 250 */ TclRegisterLiteral, /* 251 */ +#ifdef ZIPFS_IN_TCL + Tclzipfs_Init, /* 252 */ + Tclzipfs_Mount, /* 253 */ + Tclzipfs_Unmount, /* 254 */ +#else + 0, /* 252 */ + 0, /* 253 */ + 0, /* 254 */ +#endif }; static const TclIntPlatStubs tclIntPlatStubs = { diff --git a/generic/zcrypt.h b/generic/zcrypt.h new file mode 100644 index 0000000..eb9865b --- /dev/null +++ b/generic/zcrypt.h @@ -0,0 +1,131 @@ +/* crypt.h -- base code for crypt/uncrypt ZIPfile + + + Version 1.01e, February 12th, 2005 + + Copyright (C) 1998-2005 Gilles Vollant + + This code is a modified version of crypting code in Infozip distribution + + The encryption/decryption parts of this source code (as opposed to the + non-echoing password parts) were originally written in Europe. The + whole source package can be freely distributed, including from the USA. + (Prior to January 2000, re-export from the US was a violation of US law.) + + This encryption code is a direct transcription of the algorithm from + Roger Schlafly, described by Phil Katz in the file appnote.txt. This + file (appnote.txt) is distributed with the PKZIP program (even in the + version without encryption capabilities). + + If you don't need crypting in your application, just define symbols + NOCRYPT and NOUNCRYPT. + + This code support the "Traditional PKWARE Encryption". + + The new AES encryption added on Zip format by Winzip (see the page + http://www.winzip.com/aes_info.htm ) and PKWare PKZip 5.x Strong + Encryption is not supported. +*/ + +#define CRC32(c, b) ((*(pcrc_32_tab+(((int)(c) ^ (b)) & 0xff))) ^ ((c) >> 8)) + +/*********************************************************************** + * Return the next byte in the pseudo-random sequence + */ +static int decrypt_byte(unsigned long* pkeys, const unsigned int* pcrc_32_tab) +{ + unsigned temp; /* POTENTIAL BUG: temp*(temp^1) may overflow in an + * unpredictable manner on 16-bit systems; not a problem + * with any known compiler so far, though */ + + temp = ((unsigned)(*(pkeys+2)) & 0xffff) | 2; + return (int)(((temp * (temp ^ 1)) >> 8) & 0xff); +} + +/*********************************************************************** + * Update the encryption keys with the next byte of plain text + */ +static int update_keys(unsigned long* pkeys,const unsigned int* pcrc_32_tab,int c) +{ + (*(pkeys+0)) = CRC32((*(pkeys+0)), c); + (*(pkeys+1)) += (*(pkeys+0)) & 0xff; + (*(pkeys+1)) = (*(pkeys+1)) * 134775813L + 1; + { + register int keyshift = (int)((*(pkeys+1)) >> 24); + (*(pkeys+2)) = CRC32((*(pkeys+2)), keyshift); + } + return c; +} + + +/*********************************************************************** + * Initialize the encryption keys and the random header according to + * the given password. + */ +static void init_keys(const char* passwd,unsigned long* pkeys,const unsigned int* pcrc_32_tab) +{ + *(pkeys+0) = 305419896L; + *(pkeys+1) = 591751049L; + *(pkeys+2) = 878082192L; + while (*passwd != '\0') { + update_keys(pkeys,pcrc_32_tab,(int)*passwd); + passwd++; + } +} + +#define zdecode(pkeys,pcrc_32_tab,c) \ + (update_keys(pkeys,pcrc_32_tab,c ^= decrypt_byte(pkeys,pcrc_32_tab))) + +#define zencode(pkeys,pcrc_32_tab,c,t) \ + (t=decrypt_byte(pkeys,pcrc_32_tab), update_keys(pkeys,pcrc_32_tab,c), t^(c)) + +#ifdef INCLUDECRYPTINGCODE_IFCRYPTALLOWED + +#define RAND_HEAD_LEN 12 + /* "last resort" source for second part of crypt seed pattern */ +# ifndef ZCR_SEED2 +# define ZCR_SEED2 3141592654UL /* use PI as default pattern */ +# endif + +static int crypthead(const char* passwd, /* password string */ + unsigned char* buf, /* where to write header */ + int bufSize, + unsigned long* pkeys, + const unsigned int* pcrc_32_tab, + unsigned long crcForCrypting) +{ + int n; /* index in random header */ + int t; /* temporary */ + int c; /* random byte */ + unsigned char header[RAND_HEAD_LEN-2]; /* random header */ + static unsigned calls = 0; /* ensure different random header each time */ + + if (bufSize> 7) & 0xff; + header[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, c, t); + } + /* Encrypt random header (last two bytes is high word of crc) */ + init_keys(passwd, pkeys, pcrc_32_tab); + for (n = 0; n < RAND_HEAD_LEN-2; n++) + { + buf[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, header[n], t); + } + buf[n++] = (unsigned char)zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 16) & 0xff, t); + buf[n++] = (unsigned char)zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 24) & 0xff, t); + return n; +} + +#endif diff --git a/generic/zipfs.c b/generic/zipfs.c new file mode 100644 index 0000000..ec58d9f --- /dev/null +++ b/generic/zipfs.c @@ -0,0 +1,2867 @@ +#if !defined(_WIN32) && !defined(_WIN64) +#include +#endif +#include +#include +#include +#include +#include +#include +#ifdef HAVE_ZLIB +#include "zlib.h" +#include "zcrypt.h" +#endif +#include "tclInt.h" +#include "tclFileSystem.h" +#include "zipfs.h" + +#ifdef HAVE_ZLIB + +#define ZIP_SIG_LEN 4 + +#define ZIP_LOCAL_HEADER_SIG 0x04034b50 +#define ZIP_LOCAL_HEADER_LEN 30 +#define ZIP_LOCAL_SIG_OFFS 0 +#define ZIP_LOCAL_VERSION_OFFS 4 +#define ZIP_LOCAL_FLAGS_OFFS 6 +#define ZIP_LOCAL_COMPMETH_OFFS 8 +#define ZIP_LOCAL_MTIME_OFFS 10 +#define ZIP_LOCAL_MDATE_OFFS 12 +#define ZIP_LOCAL_CRC32_OFFS 14 +#define ZIP_LOCAL_COMPLEN_OFFS 18 +#define ZIP_LOCAL_UNCOMPLEN_OFFS 22 +#define ZIP_LOCAL_PATHLEN_OFFS 26 +#define ZIP_LOCAL_EXTRALEN_OFFS 28 + +#define ZIP_CENTRAL_HEADER_SIG 0x02014b50 +#define ZIP_CENTRAL_HEADER_LEN 46 +#define ZIP_CENTRAL_SIG_OFFS 0 +#define ZIP_CENTRAL_VERSIONMADE_OFFS 4 +#define ZIP_CENTRAL_VERSION_OFFS 6 +#define ZIP_CENTRAL_FLAGS_OFFS 8 +#define ZIP_CENTRAL_COMPMETH_OFFS 10 +#define ZIP_CENTRAL_MTIME_OFFS 12 +#define ZIP_CENTRAL_MDATE_OFFS 14 +#define ZIP_CENTRAL_CRC32_OFFS 16 +#define ZIP_CENTRAL_COMPLEN_OFFS 20 +#define ZIP_CENTRAL_UNCOMPLEN_OFFS 24 +#define ZIP_CENTRAL_PATHLEN_OFFS 28 +#define ZIP_CENTRAL_EXTRALEN_OFFS 30 +#define ZIP_CENTRAL_FCOMMENTLEN_OFFS 32 +#define ZIP_CENTRAL_DISKFILE_OFFS 34 +#define ZIP_CENTRAL_IATTR_OFFS 36 +#define ZIP_CENTRAL_EATTR_OFFS 38 +#define ZIP_CENTRAL_LOCALHDR_OFFS 42 + +#define ZIP_CENTRAL_END_SIG 0x06054b50 +#define ZIP_CENTRAL_END_LEN 22 +#define ZIP_CENTRAL_END_SIG_OFFS 0 +#define ZIP_CENTRAL_DISKNO_OFFS 4 +#define ZIP_CENTRAL_DISKDIR_OFFS 6 +#define ZIP_CENTRAL_ENTS_OFFS 8 +#define ZIP_CENTRAL_TOTALENTS_OFFS 10 +#define ZIP_CENTRAL_DIRSIZE_OFFS 12 +#define ZIP_CENTRAL_DIRSTART_OFFS 16 +#define ZIP_CENTRAL_COMMENTLEN_OFFS 20 + +#define ZIP_MIN_VERSION 20 +#define ZIP_COMPMETH_STORED 0 +#define ZIP_COMPMETH_DEFLATED 8 + +#define ZIP_PASSWORD_END_SIG 0x5a5a4b50 + +#define zip_read_int(p) \ + ((p)[0] | ((p)[1] << 8) | ((p)[2] << 16) | ((p)[3] << 24)) +#define zip_read_short(p) \ + ((p)[0] | ((p)[1] << 8)) + +#define zip_write_int(p, v) \ + (p)[0] = (v) & 0xff; (p)[1] = ((v) >> 8) & 0xff; \ + (p)[2] = ((v) >> 16) & 0xff; (p)[3] = ((v) >> 24) & 0xff; +#define zip_write_short(p, v) \ + (p)[0] = (v) & 0xff; (p)[1] = ((v) >> 8) & 0xff; + +#if defined(_WIN32) || defined(_WIN64) +static CONST char alpha[] = + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; +#endif + +#if !defined(_WIN32) && !defined(_WIN64) +#ifndef HAVE_LOCALTIME_R +TCL_DECLARE_MUTEX(localtimeMutex) +#endif +#endif + +typedef struct ZipFile { + char *name; /* Archive name */ + Tcl_Channel chan; /* Channel handle or NULL */ + unsigned char *data; /* Memory mapped or malloc'ed file */ + long length; /* Length of memory mapped file */ + unsigned char *tofree; /* Non-NULL if malloc'ed file */ + int nfiles; /* Number of files in archive */ + int baseoffs; /* Archive start */ + int baseoffsp; /* Password start */ + int centoffs; /* Archive directory start */ + char pwbuf[264]; /* Password buffer */ +#if defined(_WIN32) || defined(_WIN64) + HANDLE mh; +#endif + int nopen; /* Number of open files on archive */ + struct ZipEntry *entries; /* List of files in archive */ + struct ZipEntry *topents; /* List of top-level dirs in archive */ + int mntptlen; /* Length of mount point */ + char mntpt[1]; /* Mount point */ +} ZipFile; + +typedef struct ZipEntry { + char *name; /* The full pathname of the virtual file */ + ZipFile *zipfile; /* The ZIP file holding this virtual file */ + long offset; /* Data offset into memory mapped ZIP file */ + int nbyte; /* Uncompressed size of the virtual file */ + int nbytecompr; /* Compressed size of the virtual file */ + int cmeth; /* Compress method */ + int isdir; /* Set to 1 if directory */ + int depth; /* Number of slashes in path. */ + int crc32; /* CRC-32 */ + int timestamp; /* Modification time */ + int isenc; /* True if data is encrypted */ + unsigned char *data; /* File data if written */ + struct ZipEntry *next; /* Next file in the same archive */ + struct ZipEntry *tnext; /* Next top-level dir in archive */ +} ZipEntry; + +typedef struct ZipChannel { + ZipFile *zipfile; /* The ZIP file holding this channel */ + ZipEntry *zipentry; /* Pointer back to virtual file */ + unsigned long nmax; /* Max. size for write */ + unsigned long nbyte; /* Number of bytes of uncompressed data */ + unsigned long nread; /* Pos of next byte to be read from the channel */ + unsigned char *ubuf; /* Pointer to the uncompressed data */ + int iscompr; /* True if data is compressed */ + int isdir; /* Set to 1 if directory */ + int isenc; /* True if data is encrypted */ + int iswr; /* True if open for writing */ + unsigned long keys[3]; /* Key for decryption */ +} ZipChannel; + +static struct { + int initialized; /* True when initialized */ + int lock; /* RW lock, see below */ + int waiters; /* RW lock, see below */ + int wrmax; /* Maximum write size of a file */ + Tcl_HashTable fileHash; /* File name to ZipEntry mapping */ + Tcl_HashTable zipHash; /* Mount to ZipFile mapping */ +} ZipFS = { + 0, 0, 0, 0, +}; + +/* POSIX like rwlock (multiple reader, single writer) */ + +TCL_DECLARE_MUTEX(ZipFSMutex) +static Tcl_Condition ZipFSCond; + +static void +ReadLock(void) +{ + Tcl_MutexLock(&ZipFSMutex); + while (ZipFS.lock < 0) { + ZipFS.waiters++; + Tcl_ConditionWait(&ZipFSCond, &ZipFSMutex, NULL); + ZipFS.waiters--; + } + ZipFS.lock++; + Tcl_MutexUnlock(&ZipFSMutex); +} + +static void +WriteLock(void) +{ + Tcl_MutexLock(&ZipFSMutex); + while (ZipFS.lock != 0) { + ZipFS.waiters++; + Tcl_ConditionWait(&ZipFSCond, &ZipFSMutex, NULL); + ZipFS.waiters--; + } + ZipFS.lock = -1; + Tcl_MutexUnlock(&ZipFSMutex); +} + +static void +Unlock(void) +{ + Tcl_MutexLock(&ZipFSMutex); + if (ZipFS.lock > 0) { + --ZipFS.lock; + } else if (ZipFS.lock < 0) { + ZipFS.lock = 0; + } + if ((ZipFS.lock == 0) && (ZipFS.waiters > 0)) { + Tcl_ConditionNotify(&ZipFSCond); + } + Tcl_MutexUnlock(&ZipFSMutex); +} + +static CONST char pwrot[16] = { + 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, + 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0 +}; + +static CONST unsigned int crc32tab[256] = { + 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, + 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, + 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, + 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, + 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, + 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, + 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, + 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, + 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, + 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, + 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, + 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, + 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, + 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, + 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, + 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, + 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, + 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, + 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, + 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, + 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, + 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, + 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, + 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, + 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, + 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, + 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, + 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344, + 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, + 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, + 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, + 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, + 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, + 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, + 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, + 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, + 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, + 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, + 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, + 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, + 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, + 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, + 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, + 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, + 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, + 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, + 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, + 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, + 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, + 0x2d02ef8d, +}; + +static time_t +DosTimeDate(int dosDate, int dosTime) +{ + time_t now; + struct tm *tmp, tm; + + now = time(NULL); +#if defined(_WIN32) || defined(_WIN64) + tmp = localtime(&now); + tm = *tmp; +#else +#ifdef HAVE_LOCALTIME_R + tmp = &tm; + localtime_r(&now, tmp); +#else + Tcl_MutexLock(&localtimeMutex); + tmp = localtime(&now); + tm = *tmp; + Tcl_MutexUnlock(&localtimeMutex); +#endif +#endif + tm.tm_year = (((dosDate & 0xfe00) >> 9) + 80); + tm.tm_mon = ((dosDate & 0x1e0) >> 5) - 1; + tm.tm_mday = dosDate & 0x1f; + tm.tm_hour = (dosTime & 0xf800) >> 11; + tm.tm_min = (dosTime & 0x7e) >> 5; + tm.tm_sec = (dosTime & 0x1f) << 1; + return mktime(&tm); +} + +static int +ToDosTime(time_t when) +{ + struct tm *tmp, tm; + +#if defined(_WIN32) || defined(_WIN64) + tmp = localtime(&when); + tm = *tmp; +#else +#ifdef HAVE_LOCALTIME_R + tmp = &tm; + localtime_r(&when, tmp); +#else + Tcl_MutexLock(&localtimeMutex); + tmp = localtime(&when); + tm = *tmp; + Tcl_MutexUnlock(&localtimeMutex); +#endif +#endif + return (tm.tm_hour << 11) | (tm.tm_min << 5) | (tm.tm_sec >> 1); +} + +static int +ToDosDate(time_t when) +{ + struct tm *tmp, tm; + +#if defined(_WIN32) || defined(_WIN64) + tmp = localtime(&when); + tm = *tmp; +#else +#ifdef HAVE_LOCALTIME_R + tmp = &tm; + localtime_r(&when, tmp); +#else + Tcl_MutexLock(&localtimeMutex); + tmp = localtime(&when); + tm = *tmp; + Tcl_MutexUnlock(&localtimeMutex); +#endif +#endif + return ((tm.tm_year - 80) << 9) | ((tm.tm_mon + 1) << 5) | tm.tm_mday; +} + +static int +CountSlashes(CONST char *string) +{ + int count = 0; + CONST char *p = string; + + while (*p != '\0') { + if (*p == '/') { + count++; + } + p++; + } + return count; +} + +static char * +CanonicalPath(CONST char *root, CONST char *tail, Tcl_DString *dsPtr) +{ + char *path; + int i, j, c, isunc = 0; + +#if defined(_WIN32) || defined(_WIN64) + if ((tail[0] != '\0') && (strchr(alpha, tail[0]) != NULL) && + (tail[1] == ':')) { + tail += 2; + } + /* UNC style path */ + if (tail[0] == '\\') { + root = ""; + ++tail; + } + if (tail[0] == '\\') { + root = "/"; + ++tail; + } +#endif + /* UNC style path */ + if ((root[0] == '/') && (root[1] == '/')) { + isunc = 1; + } + if (tail[0] == '/') { + root = ""; + ++tail; + isunc = 0; + } + if (tail[0] == '/') { + root = "/"; + ++tail; + isunc = 1; + } + i = strlen(root); + j = strlen(tail); + Tcl_DStringSetLength(dsPtr, i + j + 1); + path = Tcl_DStringValue(dsPtr); + memcpy(path, root, i); + path[i++] = '/'; + memcpy(path + i, tail, j); +#if defined(_WIN32) || defined(_WIN64) + for (i = 0; path[i] != '\0'; i++) { + if (path[i] == '\\') { + path[i] = '/'; + } + } +#endif + for (i = j = 0; (c = path[i]) != '\0'; i++) { + if (c == '/') { + int c2 = path[i + 1]; + + if (c2 == '/') { + continue; + } + if (c2 == '.') { + int c3 = path[i + 2]; + + if ((c3 == '/') || (c3 == '\0')) { + i++; + continue; + } + if ((c3 == '.') && + ((path[i + 3] == '/') || (path [i + 3] == '\0'))) { + i += 2; + while ((j > 0) && (path[j - 1] != '/')) { + j--; + } + if (j > isunc) { + --j; + while ((j > 1 + isunc) && (path[j - 2] == '/')) { + j--; + } + } + continue; + } + } + } + path[j++] = c; + } + if (j == 0) { + path[j++] = '/'; + } + path[j] = 0; + Tcl_DStringSetLength(dsPtr, j); + return Tcl_DStringValue(dsPtr); +} + +static char * +AbsolutePath(CONST char *path, Tcl_DString *dsPtr) +{ + char *result; + + if (*path == '~') { + Tcl_DStringAppend(dsPtr, path, -1); + return Tcl_DStringValue(dsPtr); + } + if ((*path != '/') +#if defined(_WIN32) || defined(_WIN64) + && (*path != '\\') && + (((*path != '\0') && (strchr(alpha, *path) == NULL)) || + (path[1] != ':')) +#endif + ) { + Tcl_DString pwd; + + /* relative path */ + Tcl_DStringInit(&pwd); + Tcl_GetCwd(NULL, &pwd); + result = Tcl_DStringValue(&pwd); +#if defined(_WIN32) || defined(_WIN64) + if ((result[0] != '\0') && (strchr(alpha, result[0]) != NULL) && + (result[1] == ':')) { + result += 2; + } +#endif + result = CanonicalPath(result, path, dsPtr); + Tcl_DStringFree(&pwd); + } else { + /* absolute path */ + result = CanonicalPath("", path, dsPtr); + } + return result; +} + +static ZipEntry * +ZipFSLookup(char *filename) +{ + char *realname; + Tcl_HashEntry *hPtr; + ZipEntry *z; + Tcl_DString ds; + + Tcl_DStringInit(&ds); + realname = AbsolutePath(filename, &ds); + hPtr = Tcl_FindHashEntry(&ZipFS.fileHash, realname); + z = hPtr ? (ZipEntry *) Tcl_GetHashValue(hPtr) : NULL; + Tcl_DStringFree(&ds); + return z; +} + +#ifdef NEVER_USED +static int +ZipFSLookupMount(char *filename) +{ + char *realname; + Tcl_HashEntry *hPtr; + Tcl_HashSearch search; + ZipFile *zf; + Tcl_DString ds; + int match = 0; + + Tcl_DStringInit(&ds); + realname = AbsolutePath(filename, &ds); + hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); + while (hPtr != NULL) { + if ((zf = (ZipFile *) Tcl_GetHashValue(hPtr)) != NULL) { + if (strcmp(zf->mntpt, realname) == 0) { + match = 1; + break; + } + } + hPtr = Tcl_NextHashEntry(&search); + } + Tcl_DStringFree(&ds); + return match; +} +#endif + +static void +ZipFSCloseArchive(Tcl_Interp *interp, ZipFile *zf) +{ +#if defined(_WIN32) || defined(_WIN64) + if ((zf->data != NULL) && (zf->tofree == NULL)) { + UnmapViewOfFile(zf->data); + zf->data = NULL; + } + if (zf->mh != INVALID_HANDLE_VALUE) { + CloseHandle(zf->mh); + } +#else + if ((zf->data != MAP_FAILED) && (zf->tofree == NULL)) { + munmap(zf->data, zf->length); + zf->data = MAP_FAILED; + } +#endif + if (zf->tofree != NULL) { + Tcl_Free((char *) zf->tofree); + zf->tofree = NULL; + } + Tcl_Close(interp, zf->chan); + zf->chan = NULL; +} + +static int +ZipFSOpenArchive(Tcl_Interp *interp, CONST char *zipname, int needZip, + ZipFile *zf) +{ + int i; + ClientData handle; + unsigned char *p, *q; + +#if defined(_WIN32) || defined(_WIN64) + zf->data = NULL; + zf->mh = INVALID_HANDLE_VALUE; +#else + zf->data = MAP_FAILED; +#endif + zf->length = 0; + zf->nfiles = 0; + zf->baseoffs = zf->baseoffsp = 0; + zf->tofree = NULL; + zf->pwbuf[0] = 0; + zf->chan = Tcl_OpenFileChannel(interp, zipname, "r", 0); + if (zf->chan == NULL) { + return TCL_ERROR; + } + if (Tcl_GetChannelHandle(zf->chan, TCL_READABLE, &handle) != TCL_OK) { + if (Tcl_SetChannelOption(interp, zf->chan, "-translation", "binary") + != TCL_OK) { + goto error; + } + if (Tcl_SetChannelOption(interp, zf->chan, "-encoding", "binary") + != TCL_OK) { + goto error; + } + zf->length = Tcl_Seek(zf->chan, 0, SEEK_END); + if ((zf->length <= 0) || (zf->length > 64 * 1024 * 1024)) { + if (interp) { + Tcl_SetObjResult(interp, + Tcl_NewStringObj("illegal file size", -1)); + } + goto error; + } + Tcl_Seek(zf->chan, 0, SEEK_SET); + zf->tofree = zf->data = (unsigned char *) Tcl_Alloc(zf->length); + i = Tcl_Read(zf->chan, (char *) zf->data, zf->length); + if (i != zf->length) { + if (interp) { + Tcl_SetObjResult(interp, + Tcl_NewStringObj("file read error", -1)); + } + goto error; + } + Tcl_Close(interp, zf->chan); + zf->chan = NULL; + } else { +#if defined(_WIN32) || defined(_WIN64) + zf->length = GetFileSize((HANDLE) handle, 0); + if ((zf->length == INVALID_FILE_SIZE) || + (zf->length < ZIP_CENTRAL_END_LEN)) { + if (interp != NULL) { + Tcl_SetObjResult(interp, + Tcl_NewStringObj("invalid file size", -1)); + } + goto error; + } + zf->mh = CreateFileMapping((HANDLE) handle, 0, PAGE_READONLY, 0, + zf->length, 0); + if (zf->mh == INVALID_HANDLE_VALUE) { + if (interp != NULL) { + Tcl_SetObjResult(interp, + Tcl_NewStringObj("file mapping failed", -1)); + } + goto error; + } + zf->data = MapViewOfFile(zf->mh, FILE_MAP_READ, 0, 0, zf->length); + if (zf->data == NULL) { + if (interp != NULL) { + Tcl_SetObjResult(interp, + Tcl_NewStringObj("file mapping failed", -1)); + } + goto error; + } +#else + zf->length = lseek((int) (long) handle, 0, SEEK_END); + if ((zf->length == -1) || (zf->length < ZIP_CENTRAL_END_LEN)) { + if (interp != NULL) { + Tcl_SetObjResult(interp, + Tcl_NewStringObj("invalid file size", -1)); + } + goto error; + } + lseek((int) (long) handle, 0, SEEK_SET); + zf->data = (unsigned char *) mmap(0, zf->length, PROT_READ, + MAP_FILE | MAP_PRIVATE, + (int) (long) handle, 0); + if (zf->data == MAP_FAILED) { + if (interp != NULL) { + Tcl_SetObjResult(interp, + Tcl_NewStringObj("file mapping failed", -1)); + } + goto error; + } +#endif + } + p = zf->data + zf->length - ZIP_CENTRAL_END_LEN; + while (p >= zf->data) { + if (*p == (ZIP_CENTRAL_END_SIG & 0xFF)) { + if (zip_read_int(p) == ZIP_CENTRAL_END_SIG) { + break; + } + p -= ZIP_SIG_LEN; + } else { + --p; + } + } + if (p < zf->data) { + if (!needZip) { + zf->baseoffs = zf->baseoffsp = zf->length; + return TCL_OK; + } + if (interp != NULL) { + Tcl_SetObjResult(interp, + Tcl_NewStringObj("wrong end signature", -1)); + } + goto error; + } + zf->nfiles = zip_read_short(p + ZIP_CENTRAL_ENTS_OFFS); + if (zf->nfiles == 0) { + if (!needZip) { + zf->baseoffs = zf->baseoffsp = zf->length; + return TCL_OK; + } + if (interp != NULL) { + Tcl_SetObjResult(interp, + Tcl_NewStringObj("empty archive", -1)); + } + goto error; + } + q = zf->data + zip_read_int(p + ZIP_CENTRAL_DIRSTART_OFFS); + p -= zip_read_int(p + ZIP_CENTRAL_DIRSIZE_OFFS); + if ((p < zf->data) || (p > (zf->data + zf->length)) || + (q < zf->data) || (q > (zf->data + zf->length))) { + if (!needZip) { + zf->baseoffs = zf->baseoffsp = zf->length; + return TCL_OK; + } + if (interp != NULL) { + Tcl_SetObjResult(interp, + Tcl_NewStringObj("archive directory not found", -1)); + } + goto error; + } + zf->baseoffs = zf->baseoffsp = p - q; + zf->centoffs = p - zf->data; + q = p; + for (i = 0; i < zf->nfiles; i++) { + int pathlen, comlen, extra; + + if ((q + ZIP_CENTRAL_HEADER_LEN) > (zf->data + zf->length)) { + if (interp != NULL) { + Tcl_SetObjResult(interp, + Tcl_NewStringObj("wrong header length", -1)); + } + goto error; + } + if (zip_read_int(q) != ZIP_CENTRAL_HEADER_SIG) { + if (interp != NULL) { + Tcl_SetObjResult(interp, + Tcl_NewStringObj("wrong header signature", -1)); + } + goto error; + } + pathlen = zip_read_short(q + ZIP_CENTRAL_PATHLEN_OFFS); + comlen = zip_read_short(q + ZIP_CENTRAL_FCOMMENTLEN_OFFS); + extra = zip_read_short(q + ZIP_CENTRAL_EXTRALEN_OFFS); + q += pathlen + comlen + extra + ZIP_CENTRAL_HEADER_LEN; + } + q = zf->data + zf->baseoffs; + if ((zf->baseoffs >= 6) && + (zip_read_int(q - 4) == ZIP_PASSWORD_END_SIG)) { + i = q[-5]; + if (q - 5 - i > zf->data) { + zf->pwbuf[0] = i; + memcpy(zf->pwbuf + 1, q - 5 - i, i); + zf->baseoffsp -= i ? (5 + i) : 0; + } + } + return TCL_OK; + +error: + ZipFSCloseArchive(interp, zf); + return TCL_ERROR; +} + +int +Zipfs_Mount(Tcl_Interp *interp, CONST char *zipname, CONST char *mntpt, + CONST char *passwd) +{ + char *realname; + int i, pwlen, isNew; + ZipFile *zf, zf0; + ZipEntry *z; + Tcl_HashEntry *hPtr; + Tcl_DString ds, fpBuf; + unsigned char *q; + + ReadLock(); + if (!ZipFS.initialized) { + if (interp != NULL) { + Tcl_SetObjResult(interp, + Tcl_NewStringObj("not initialized", -1)); + } + Unlock(); + return TCL_ERROR; + } + if (zipname == NULL) { + Tcl_HashSearch search; + int ret = TCL_OK; + + i = 0; + hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); + while (hPtr != NULL) { + if ((zf = (ZipFile *) Tcl_GetHashValue(hPtr)) != NULL) { + if (interp != NULL) { + Tcl_AppendElement(interp, zf->mntpt); + Tcl_AppendElement(interp, zf->name); + } + ++i; + } + hPtr = Tcl_NextHashEntry(&search); + } + if (interp == NULL) { + ret = (i > 0) ? TCL_OK : TCL_BREAK; + } + Unlock(); + return ret; + } + if (mntpt == NULL) { + if (interp == NULL) { + Unlock(); + return TCL_OK; + } + Tcl_DStringInit(&ds); + hPtr = Tcl_FindHashEntry(&ZipFS.zipHash, AbsolutePath(zipname, &ds)); + if (hPtr != NULL) { + if ((zf = Tcl_GetHashValue(hPtr)) != NULL) { + Tcl_SetObjResult(interp, Tcl_NewStringObj(zf->mntpt, -1)); + } + } + Unlock(); + Tcl_DStringFree(&ds); + return TCL_OK; + } + Unlock(); + pwlen = 0; + if (passwd != NULL) { + pwlen = strlen(passwd); + if ((pwlen > 255) || (strchr(passwd, 0xff) != NULL)) { + if (interp) { + Tcl_SetObjResult(interp, + Tcl_NewStringObj("illegal password", -1)); + } + return TCL_ERROR; + } + } + if (ZipFSOpenArchive(interp, zipname, 1, &zf0) != TCL_OK) { + return TCL_ERROR; + } + Tcl_DStringInit(&ds); + realname = AbsolutePath(zipname, &ds); + WriteLock(); + hPtr = Tcl_CreateHashEntry(&ZipFS.zipHash, realname, &isNew); + Tcl_DStringSetLength(&ds, 0); + if (!isNew) { + zf = (ZipFile *) Tcl_GetHashValue(hPtr); + if (interp != NULL) { + Tcl_AppendResult(interp, "already mounted at ", zf->mntpt, + (char *) NULL); + } + goto error; + } + if (strcmp(mntpt, "/") == 0) { + mntpt = ""; + } + zf = (ZipFile *) Tcl_Alloc(sizeof (*zf) + strlen(mntpt) + 1); + *zf = zf0; + zf->name = Tcl_GetHashKey(&ZipFS.zipHash, hPtr); + strcpy(zf->mntpt, mntpt); + zf->mntptlen = strlen(zf->mntpt); + zf->entries = NULL; + zf->topents = NULL; + zf->nopen = 0; + Tcl_SetHashValue(hPtr, (ClientData) zf); + if ((zf->pwbuf[0] == 0) && pwlen) { + int k = 0; + + i = pwlen; + zf->pwbuf[k++] = i; + while (i > 0) { + zf->pwbuf[k] = (passwd[i - 1] & 0x0f) | + pwrot[(passwd[i - 1] >> 4) & 0x0f]; + k++; + i--; + } + zf->pwbuf[k] = '\0'; + } + if (mntpt[0] != '\0') { + z = (ZipEntry *) Tcl_Alloc(sizeof (*z)); + z->name = NULL; + z->tnext = NULL; + z->depth = CountSlashes(mntpt); + z->zipfile = zf; + z->isdir = 1; + z->isenc = 0; + z->offset = zf->baseoffs; + z->crc32 = 0; + z->timestamp = 0; + z->nbyte = z->nbytecompr = 0; + z->cmeth = ZIP_COMPMETH_STORED; + z->data = NULL; + hPtr = Tcl_CreateHashEntry(&ZipFS.fileHash, mntpt, &isNew); + if (!isNew) { + /* skip it */ + Tcl_Free((char *) z); + } else { + Tcl_SetHashValue(hPtr, (ClientData) z); + z->name = Tcl_GetHashKey(&ZipFS.fileHash, hPtr); + z->next = zf->entries; + zf->entries = z; + } + } + q = zf->data + zf->centoffs; + Tcl_DStringInit(&fpBuf); + for (i = 0; i < zf->nfiles; i++) { + int pathlen, comlen, extra, isdir = 0, dosTime, dosDate, nbcompr, offs; + unsigned char *lq, *gq = NULL; + char *fullpath, *path; + + pathlen = zip_read_short(q + ZIP_CENTRAL_PATHLEN_OFFS); + comlen = zip_read_short(q + ZIP_CENTRAL_FCOMMENTLEN_OFFS); + extra = zip_read_short(q + ZIP_CENTRAL_EXTRALEN_OFFS); + Tcl_DStringSetLength(&ds, 0); + Tcl_DStringAppend(&ds, (char *) q + ZIP_CENTRAL_HEADER_LEN, pathlen); + path = Tcl_DStringValue(&ds); + if ((pathlen > 0) && (path[pathlen - 1] == '/')) { + Tcl_DStringSetLength(&ds, pathlen - 1); + path = Tcl_DStringValue(&ds); + isdir = 1; + } + if ((strcmp(path, ".") == 0) || (strcmp(path, "..") == 0)) { + goto nextent; + } + lq = zf->data + zf->baseoffs + + zip_read_int(q + ZIP_CENTRAL_LOCALHDR_OFFS); + if ((lq < zf->data) || (lq > (zf->data + zf->length))) { + goto nextent; + } + nbcompr = zip_read_int(lq + ZIP_LOCAL_COMPLEN_OFFS); + if (!isdir && (nbcompr == 0) && + (zip_read_int(lq + ZIP_LOCAL_UNCOMPLEN_OFFS) == 0) && + (zip_read_int(lq + ZIP_LOCAL_CRC32_OFFS) == 0)) { + gq = q; + nbcompr = zip_read_int(gq + ZIP_CENTRAL_COMPLEN_OFFS); + } + offs = (lq - zf->data) + + ZIP_LOCAL_HEADER_LEN + + zip_read_short(lq + ZIP_LOCAL_PATHLEN_OFFS) + + zip_read_short(lq + ZIP_LOCAL_EXTRALEN_OFFS); + if ((offs + nbcompr) > zf->length) { + goto nextent; + } + if (!isdir && (mntpt[0] == '\0') && !CountSlashes(path)) { + goto nextent; + } + Tcl_DStringSetLength(&fpBuf, 0); + fullpath = CanonicalPath(mntpt, path, &fpBuf); + z = (ZipEntry *) Tcl_Alloc(sizeof (*z)); + z->name = NULL; + z->tnext = NULL; + z->depth = CountSlashes(fullpath); + z->zipfile = zf; + z->isdir = isdir; + z->isenc = (zip_read_short(lq + ZIP_LOCAL_FLAGS_OFFS) & 1) + && (nbcompr > 12); + z->offset = offs; + if (gq != NULL) { + z->crc32 = zip_read_int(gq + ZIP_CENTRAL_CRC32_OFFS); + dosDate = zip_read_short(gq + ZIP_CENTRAL_MDATE_OFFS); + dosTime = zip_read_short(gq + ZIP_CENTRAL_MTIME_OFFS); + z->timestamp = DosTimeDate(dosDate, dosTime); + z->nbyte = zip_read_int(gq + ZIP_CENTRAL_UNCOMPLEN_OFFS); + z->cmeth = zip_read_short(gq + ZIP_CENTRAL_COMPMETH_OFFS); + } else { + z->crc32 = zip_read_int(lq + ZIP_LOCAL_CRC32_OFFS); + dosDate = zip_read_short(lq + ZIP_LOCAL_MDATE_OFFS); + dosTime = zip_read_short(lq + ZIP_LOCAL_MTIME_OFFS); + z->timestamp = DosTimeDate(dosDate, dosTime); + z->nbyte = zip_read_int(lq + ZIP_LOCAL_UNCOMPLEN_OFFS); + z->cmeth = zip_read_short(lq + ZIP_LOCAL_COMPMETH_OFFS); + } + z->nbytecompr = nbcompr; + z->data = NULL; + hPtr = Tcl_CreateHashEntry(&ZipFS.fileHash, fullpath, &isNew); + if (!isNew) { + /* skip it */ + Tcl_Free((char *) z); + } else { + Tcl_SetHashValue(hPtr, (ClientData) z); + z->name = Tcl_GetHashKey(&ZipFS.fileHash, hPtr); + z->next = zf->entries; + zf->entries = z; + if (isdir && (mntpt[0] == '\0') && (z->depth == 1)) { + z->tnext = zf->topents; + zf->topents = z; + } + if (!z->isdir && (z->depth > 1)) { + char *dir, *end; + ZipEntry *zd; + + Tcl_DStringSetLength(&ds, strlen(z->name) + 8); + Tcl_DStringSetLength(&ds, 0); + Tcl_DStringAppend(&ds, z->name, -1); + dir = Tcl_DStringValue(&ds); + end = strrchr(dir, '/'); + while ((end != NULL) && (end != dir)) { + Tcl_DStringSetLength(&ds, end - dir); + hPtr = Tcl_FindHashEntry(&ZipFS.fileHash, dir); + if (hPtr != NULL) { + break; + } + zd = (ZipEntry *) Tcl_Alloc(sizeof (*zd)); + zd->name = NULL; + zd->tnext = NULL; + zd->depth = CountSlashes(dir); + zd->zipfile = zf; + zd->isdir = 1; + zd->isenc = 0; + zd->offset = z->offset; + zd->crc32 = 0; + zd->timestamp = z->timestamp; + zd->nbyte = zd->nbytecompr = 0; + zd->cmeth = ZIP_COMPMETH_STORED; + zd->data = NULL; + hPtr = Tcl_CreateHashEntry(&ZipFS.fileHash, dir, &isNew); + if (!isNew) { + /* should never happen but skip it */ + Tcl_Free((char *) zd); + } else { + Tcl_SetHashValue(hPtr, (ClientData) zd); + zd->name = Tcl_GetHashKey(&ZipFS.fileHash, hPtr); + zd->next = zf->entries; + zf->entries = zd; + if ((mntpt[0] == '\0') && (zd->depth == 1)) { + zd->tnext = zf->topents; + zf->topents = zd; + } + } + end = strrchr(dir, '/'); + } + } + } +nextent: + q += pathlen + comlen + extra + ZIP_CENTRAL_HEADER_LEN; + } + Tcl_DStringFree(&fpBuf); + Tcl_DStringFree(&ds); + Unlock(); + Tcl_FSMountsChanged(NULL); + return TCL_OK; + +error: + Tcl_DStringFree(&ds); + Unlock(); + ZipFSCloseArchive(interp, zf); + Tcl_Free((char *) zf); + return TCL_ERROR; +} + +int +Zipfs_Unmount(Tcl_Interp *interp, CONST char *zipname) +{ + char *realname; + ZipFile *zf; + ZipEntry *z, *znext; + Tcl_HashEntry *hPtr; + Tcl_DString ds; + int ret = TCL_OK, unmounted = 0; + + Tcl_DStringInit(&ds); + realname = AbsolutePath(zipname, &ds); + WriteLock(); + if (!ZipFS.initialized) { + goto done; + } + hPtr = Tcl_FindHashEntry(&ZipFS.zipHash, realname); + if (hPtr == NULL) { + /* does not report error */ + goto done; + } + zf = (ZipFile *) Tcl_GetHashValue(hPtr); + if (zf->nopen > 0) { + if (interp != NULL) { + Tcl_SetObjResult(interp, + Tcl_NewStringObj("filesystem is busy", -1)); + } + ret = TCL_ERROR; + goto done; + } + Tcl_DeleteHashEntry(hPtr); + for (z = zf->entries; z; z = znext) { + znext = z->next; + hPtr = Tcl_FindHashEntry(&ZipFS.fileHash, z->name); + if (hPtr) { + Tcl_DeleteHashEntry(hPtr); + } + if (z->data != NULL) { + Tcl_Free((char *) z->data); + } + Tcl_Free((char *) z); + } + ZipFSCloseArchive(interp, zf); + Tcl_Free((char *) zf); + unmounted = 1; +done: + Unlock(); + Tcl_DStringFree(&ds); + if (unmounted) { + Tcl_FSMountsChanged(NULL); + } + return ret; +} + +static int +ZipFSMountCmd(ClientData clientData, Tcl_Interp *interp, + int argc, CONST char **argv) +{ + if (argc > 4) { + Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], + " ?zipfile ?mountpoint? ?password???\"", 0); + return TCL_ERROR; + } + return Zipfs_Mount(interp, (argc > 1) ? argv[1] : NULL, + (argc > 2) ? argv[2] : NULL, + (argc > 3) ? argv[3] : NULL); +} + +static int +ZipFSUnmountCmd(ClientData clientData, Tcl_Interp *interp, + int argc, CONST char **argv) +{ + if (argc != 2) { + Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], + " zipfile\"", (char *) NULL); + return TCL_ERROR; + } + return Zipfs_Unmount(interp, argv[1]); +} + +static int +ZipFSMkKeyCmd(ClientData clientData, Tcl_Interp *interp, + int argc, CONST char **argv) +{ + int len, i = 0; + char pwbuf[264]; + + if (argc != 2) { + Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], + " password\"", (char *) NULL); + return TCL_ERROR; + } + len = strlen(argv[1]); + if (len == 0) { + return TCL_OK; + } + if ((len > 255) || (strchr(argv[1], 0xff) != NULL)) { + Tcl_SetObjResult(interp, + Tcl_NewStringObj("illegal password", -1)); + return TCL_ERROR; + } + while (len > 0) { + int ch = argv[1][len - 1]; + + pwbuf[i] = (ch & 0x0f) | pwrot[(ch >> 4) & 0x0f]; + i++; + len--; + } + pwbuf[i] = i; + ++i; + pwbuf[i++] = (char) ZIP_PASSWORD_END_SIG; + pwbuf[i++] = (char) (ZIP_PASSWORD_END_SIG >> 8); + pwbuf[i++] = (char) (ZIP_PASSWORD_END_SIG >> 16); + pwbuf[i++] = (char) (ZIP_PASSWORD_END_SIG >> 24); + pwbuf[i] = '\0'; + Tcl_AppendResult(interp, pwbuf, (char *) NULL); + return TCL_OK; +} + +static int +ZipAddFile(Tcl_Interp *interp, CONST char *path, Tcl_Channel out, + CONST char *passwd, char *buf, int bufsize, Tcl_HashTable *fileHash) +{ + Tcl_Channel in; + Tcl_HashEntry *hPtr; + ZipEntry *z; + z_stream stream; + CONST char *zpath; + int nbyte, nbytecompr, len, crc, flush, pos[3], zpathlen, olen; + int mtime = 0, isNew, align = 0, cmeth; + unsigned long keys[3], keys0[3]; + char obuf[4096]; + + zpath = path; + while (zpath != NULL && zpath[0] == '/') { + zpath++; + } + if ((zpath == NULL) || (zpath[0] == '\0')) { + return TCL_OK; + } + zpathlen = strlen(zpath); + if (zpathlen + ZIP_CENTRAL_HEADER_LEN > bufsize) { + Tcl_AppendResult(interp, "path too long for \"", path, "\"", + (char *) NULL); + return TCL_ERROR; + } + in = Tcl_OpenFileChannel(interp, path, "r", 0); + if ((in == NULL) || + (Tcl_SetChannelOption(interp, in, "-translation", "binary") + != TCL_OK) || + (Tcl_SetChannelOption(interp, in, "-encoding", "binary") + != TCL_OK)) { +#if defined(_WIN32) || defined(_WIN64) + /* hopefully a directory */ + if (strcmp("permission denied", Tcl_PosixError(interp)) == 0) { + Tcl_Close(interp, in); + return TCL_OK; + } +#endif + Tcl_Close(interp, in); + return TCL_ERROR; + } else { + Tcl_Obj *pathObj = Tcl_NewStringObj(path, -1); + Tcl_StatBuf statBuf; + + Tcl_IncrRefCount(pathObj); + if (Tcl_FSStat(pathObj, &statBuf) != -1) { + mtime = statBuf.st_mtime; + } + Tcl_DecrRefCount(pathObj); + } + Tcl_ResetResult(interp); + crc = 0; + nbyte = nbytecompr = 0; + while ((len = Tcl_Read(in, buf, bufsize)) > 0) { + crc = crc32(crc, (unsigned char *) buf, len); + nbyte += len; + } + if (len == -1) { + if (nbyte == 0) { + if (strcmp("illegal operation on a directory", + Tcl_PosixError(interp)) == 0) { + Tcl_Close(interp, in); + return TCL_OK; + } + } + Tcl_AppendResult(interp, "read error on \"", path, "\"", + (char *) NULL); + Tcl_Close(interp, in); + return TCL_ERROR; + } + if (Tcl_Seek(in, 0, SEEK_SET) == -1) { + Tcl_AppendResult(interp, "seek error on \"", path, "\"", + (char *) NULL); + Tcl_Close(interp, in); + return TCL_ERROR; + } + pos[0] = Tcl_Tell(out); + memset(buf, '\0', ZIP_LOCAL_HEADER_LEN); + memcpy(buf + ZIP_LOCAL_HEADER_LEN, zpath, zpathlen); + len = zpathlen + ZIP_LOCAL_HEADER_LEN; + if (Tcl_Write(out, buf, len) != len) { +wrerr: + Tcl_AppendResult(interp, "write error", (char *) NULL); + Tcl_Close(interp, in); + return TCL_ERROR; + } + if ((len + pos[0]) & 3) { + char abuf[8]; + + /* + * Align payload to next 4-byte boundary using a dummy extra + * entry similar to the zipalign tool from Android's SDK. + */ + align = 4 + ((len + pos[0]) & 3); + zip_write_short(abuf, 0xffff); + zip_write_short(abuf + 2, align - 4); + zip_write_int(abuf + 4, 0x03020100); + if (Tcl_Write(out, abuf, align) != align) { + goto wrerr; + } + } + if (passwd != NULL) { + int i, ch, tmp; + unsigned char kvbuf[24]; + Tcl_Obj *ret; + + init_keys(passwd, keys, crc32tab); + for (i = 0; i < 12 - 2; i++) { + if (Tcl_Eval(interp, "expr int(rand() * 256) % 256") != TCL_OK) { + Tcl_AppendResult(interp, "PRNG error", (char *) NULL); + Tcl_Close(interp, in); + return TCL_ERROR; + } + ret = Tcl_GetObjResult(interp); + if (Tcl_GetIntFromObj(interp, ret, &ch) != TCL_OK) { + Tcl_Close(interp, in); + return TCL_ERROR; + } + kvbuf[i + 12] = (unsigned char) zencode(keys, crc32tab, ch, tmp); + } + Tcl_ResetResult(interp); + init_keys(passwd, keys, crc32tab); + for (i = 0; i < 12 - 2; i++) { + kvbuf[i] = (unsigned char) zencode(keys, crc32tab, + kvbuf[i + 12], tmp); + } + kvbuf[i++] = (unsigned char) zencode(keys, crc32tab, crc >> 16, tmp); + kvbuf[i++] = (unsigned char) zencode(keys, crc32tab, crc >> 24, tmp); + len = Tcl_Write(out, (char *) kvbuf, 12); + memset(kvbuf, 0, 24); + if (len != 12) { + Tcl_AppendResult(interp, "write error", (char *) NULL); + Tcl_Close(interp, in); + return TCL_ERROR; + } + memcpy(keys0, keys, sizeof (keys0)); + nbytecompr += 12; + } + Tcl_Flush(out); + pos[2] = Tcl_Tell(out); + cmeth = ZIP_COMPMETH_DEFLATED; + memset(&stream, 0, sizeof (stream)); + stream.zalloc = Z_NULL; + stream.zfree = Z_NULL; + stream.opaque = Z_NULL; + if (deflateInit2(&stream, 9, Z_DEFLATED, -15, 8, Z_DEFAULT_STRATEGY) + != Z_OK) { + Tcl_AppendResult(interp, "compression init error on \"", path, "\"", + (char *) NULL); + Tcl_Close(interp, in); + return TCL_ERROR; + } + do { + len = Tcl_Read(in, buf, bufsize); + if (len == -1) { + Tcl_AppendResult(interp, "read error on \"", path, "\"", + (char *) NULL); + deflateEnd(&stream); + Tcl_Close(interp, in); + return TCL_ERROR; + } + stream.avail_in = len; + stream.next_in = (unsigned char *) buf; + flush = Tcl_Eof(in) ? Z_FINISH : Z_NO_FLUSH; + do { + stream.avail_out = sizeof (obuf); + stream.next_out = (unsigned char *) obuf; + len = deflate(&stream, flush); + if (len == Z_STREAM_ERROR) { + Tcl_AppendResult(interp, "deflate error on \"", path, "\"", + (char *) NULL); + deflateEnd(&stream); + Tcl_Close(interp, in); + return TCL_ERROR; + } + olen = sizeof (obuf) - stream.avail_out; + if (passwd != NULL) { + int i, tmp; + + for (i = 0; i < olen; i++) { + obuf[i] = (char) zencode(keys, crc32tab, obuf[i], tmp); + } + } + if (olen && (Tcl_Write(out, obuf, olen) != olen)) { + Tcl_AppendResult(interp, "write error", (char *) NULL); + deflateEnd(&stream); + Tcl_Close(interp, in); + return TCL_ERROR; + } + nbytecompr += olen; + } while (stream.avail_out == 0); + } while (flush != Z_FINISH); + deflateEnd(&stream); + Tcl_Flush(out); + pos[1] = Tcl_Tell(out); + if (nbyte - nbytecompr <= 0) { + /* + * Compressed file larger than input, + * write it again uncompressed. + */ + if ((int) Tcl_Seek(in, 0, SEEK_SET) != 0) { + goto seekErr; + } + if ((int) Tcl_Seek(out, pos[2], SEEK_SET) != pos[2]) { +seekErr: + Tcl_Close(interp, in); + Tcl_AppendResult(interp, "seek error", (char *) NULL); + return TCL_ERROR; + } + nbytecompr = (passwd != NULL) ? 12 : 0; + while (1) { + len = Tcl_Read(in, buf, bufsize); + if (len == -1) { + Tcl_AppendResult(interp, "read error on \"", path, "\"", + (char *) NULL); + Tcl_Close(interp, in); + return TCL_ERROR; + } else if (len == 0) { + break; + } + if (passwd != NULL) { + int i, tmp; + + for (i = 0; i < len; i++) { + buf[i] = (char) zencode(keys0, crc32tab, buf[i], tmp); + } + } + if (Tcl_Write(out, buf, len) != len) { + Tcl_AppendResult(interp, "write error", (char *) NULL); + Tcl_Close(interp, in); + return TCL_ERROR; + } + nbytecompr += len; + } + cmeth = ZIP_COMPMETH_STORED; + Tcl_Flush(out); + pos[1] = Tcl_Tell(out); + Tcl_TruncateChannel(out, pos[1]); + } + Tcl_Close(interp, in); + + z = (ZipEntry *) Tcl_Alloc(sizeof (*z)); + z->name = NULL; + z->tnext = NULL; + z->depth = 0; + z->zipfile = NULL; + z->isdir = 0; + z->isenc = (passwd != NULL) ? 1 : 0; + z->offset = pos[0]; + z->crc32 = crc; + z->timestamp = mtime; + z->nbyte = nbyte; + z->nbytecompr = nbytecompr; + z->cmeth = cmeth; + z->data = NULL; + hPtr = Tcl_CreateHashEntry(fileHash, zpath, &isNew); + if (!isNew) { + Tcl_AppendResult(interp, "not unique path name \"", path, "\"", + (char *) NULL); + Tcl_Free((char *) z); + return TCL_ERROR; + } else { + Tcl_SetHashValue(hPtr, (ClientData) z); + z->name = Tcl_GetHashKey(fileHash, hPtr); + z->next = NULL; + } + + /* + * Write final local header information. + */ + zip_write_int(buf + ZIP_LOCAL_SIG_OFFS, ZIP_LOCAL_HEADER_SIG); + zip_write_short(buf + ZIP_LOCAL_VERSION_OFFS, ZIP_MIN_VERSION); + zip_write_short(buf + ZIP_LOCAL_FLAGS_OFFS, z->isenc); + zip_write_short(buf + ZIP_LOCAL_COMPMETH_OFFS, z->cmeth); + zip_write_short(buf + ZIP_LOCAL_MTIME_OFFS, ToDosTime(z->timestamp)); + zip_write_short(buf + ZIP_LOCAL_MDATE_OFFS, ToDosDate(z->timestamp)); + zip_write_int(buf + ZIP_LOCAL_CRC32_OFFS, z->crc32); + zip_write_int(buf + ZIP_LOCAL_COMPLEN_OFFS, z->nbytecompr); + zip_write_int(buf + ZIP_LOCAL_UNCOMPLEN_OFFS, z->nbyte); + zip_write_short(buf + ZIP_LOCAL_PATHLEN_OFFS, zpathlen); + zip_write_short(buf + ZIP_LOCAL_EXTRALEN_OFFS, align); + if ((int) Tcl_Seek(out, pos[0], SEEK_SET) != pos[0]) { + Tcl_DeleteHashEntry(hPtr); + Tcl_Free((char *) z); + Tcl_AppendResult(interp, "seek error", (char *) NULL); + return TCL_ERROR; + } + if (Tcl_Write(out, buf, ZIP_LOCAL_HEADER_LEN) != ZIP_LOCAL_HEADER_LEN) { + Tcl_DeleteHashEntry(hPtr); + Tcl_Free((char *) z); + Tcl_AppendResult(interp, "write error", (char *) NULL); + return TCL_ERROR; + } + Tcl_Flush(out); + if ((int) Tcl_Seek(out, pos[1], SEEK_SET) != pos[1]) { + Tcl_DeleteHashEntry(hPtr); + Tcl_Free((char *) z); + Tcl_AppendResult(interp, "seek error", (char *) NULL); + return TCL_ERROR; + } + return TCL_OK; +} + +static int +ZipFSMkZipOrImgCmd(ClientData clientData, Tcl_Interp *interp, + int isImg, int argc, CONST char **argv) +{ + Tcl_Channel out; + int len = 0, pwlen = 0, i, ret = TCL_ERROR, largc, pos[3]; + CONST char **largv; + Tcl_DString ds; + ZipEntry *z; + Tcl_HashEntry *hPtr; + Tcl_HashSearch search; + Tcl_HashTable fileHash; + char pwbuf[264], buf[4096]; + + if ((argc < 3) || (argc > (isImg ? 5 : 4))) { + Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], + " outfile indir ?password?", + isImg ? " ?infile?\"" : "\"", (char *) NULL); + return TCL_ERROR; + } + pwbuf[0] = 0; + if (argc > 3) { + pwlen = strlen(argv[3]); + if ((pwlen > 255) || (strchr(argv[1], 0xff) != NULL)) { + Tcl_AppendResult(interp, "illegal password", (char *) NULL); + return TCL_ERROR; + } + } + Tcl_DStringInit(&ds); + Tcl_DStringAppendElement(&ds, "::zipfs::find"); + Tcl_DStringAppendElement(&ds, argv[2]); + if (Tcl_Eval(interp, Tcl_DStringValue(&ds)) != TCL_OK) { + Tcl_DStringFree(&ds); + return TCL_ERROR; + } + Tcl_DStringFree(&ds); + if (Tcl_SplitList(interp, Tcl_GetStringResult(interp), &largc, &largv) + != TCL_OK) { + return TCL_ERROR; + } + Tcl_ResetResult(interp); + if (largc == 0) { + Tcl_Free((char *) largv); + Tcl_AppendResult(interp, "empty archive", (char *) NULL); + return TCL_ERROR; + } + out = Tcl_OpenFileChannel(interp, argv[1], "w", 0755); + if ((out == NULL) || + (Tcl_SetChannelOption(interp, out, "-translation", "binary") + != TCL_OK) || + (Tcl_SetChannelOption(interp, out, "-encoding", "binary") + != TCL_OK)) { + Tcl_Close(interp, out); + Tcl_Free((char *) largv); + return TCL_ERROR; + } + if (isImg) { + ZipFile zf0; + + if (ZipFSOpenArchive(interp, (argc > 4) ? argv[4] : + Tcl_GetNameOfExecutable(), 0, &zf0) != TCL_OK) { + Tcl_Close(interp, out); + Tcl_Free((char *) largv); + return TCL_ERROR; + } + if (pwlen && (argc > 3)) { + i = 0; + len = pwlen; + while (len > 0) { + int ch = argv[3][len - 1]; + + pwbuf[i] = (ch & 0x0f) | pwrot[(ch >> 4) & 0x0f]; + i++; + len--; + } + pwbuf[i] = i; + ++i; + pwbuf[i++] = (char) ZIP_PASSWORD_END_SIG; + pwbuf[i++] = (char) (ZIP_PASSWORD_END_SIG >> 8); + pwbuf[i++] = (char) (ZIP_PASSWORD_END_SIG >> 16); + pwbuf[i++] = (char) (ZIP_PASSWORD_END_SIG >> 24); + pwbuf[i] = '\0'; + } + i = Tcl_Write(out, (char *) zf0.data, zf0.baseoffsp); + if (i != zf0.baseoffsp) { + Tcl_AppendResult(interp, "write error", (char *) NULL); + Tcl_Close(interp, out); + Tcl_Free((char *) largv); + ZipFSCloseArchive(interp, &zf0); + return TCL_ERROR; + } + ZipFSCloseArchive(interp, &zf0); + len = strlen(pwbuf); + if (len > 0) { + i = Tcl_Write(out, pwbuf, len); + if (i != len) { + Tcl_AppendResult(interp, "write error", (char *) NULL); + Tcl_Close(interp, out); + Tcl_Free((char *) largv); + return TCL_ERROR; + } + } + memset(pwbuf, 0, sizeof (pwbuf)); + Tcl_Flush(out); + } + Tcl_InitHashTable(&fileHash, TCL_STRING_KEYS); + pos[0] = Tcl_Tell(out); + for (i = 0; i < largc; i++) { + if (ZipAddFile(interp, largv[i], out, (pwlen > 0) ? argv[3] : NULL, + buf, sizeof (buf), &fileHash) + != TCL_OK) { + goto done; + } + } + pos[1] = Tcl_Tell(out); + hPtr = Tcl_FirstHashEntry(&fileHash, &search); + i = 0; + while (hPtr != NULL) { + z = (ZipEntry *) Tcl_GetHashValue(hPtr); + len = strlen(z->name); + zip_write_int(buf + ZIP_CENTRAL_SIG_OFFS, ZIP_CENTRAL_HEADER_SIG); + zip_write_short(buf + ZIP_CENTRAL_VERSIONMADE_OFFS, ZIP_MIN_VERSION); + zip_write_short(buf + ZIP_CENTRAL_VERSION_OFFS, ZIP_MIN_VERSION); + zip_write_short(buf + ZIP_CENTRAL_FLAGS_OFFS, z->isenc ? 1 : 0); + zip_write_short(buf + ZIP_CENTRAL_COMPMETH_OFFS, z->cmeth); + zip_write_short(buf + ZIP_CENTRAL_MTIME_OFFS, ToDosTime(z->timestamp)); + zip_write_short(buf + ZIP_CENTRAL_MDATE_OFFS, ToDosDate(z->timestamp)); + zip_write_int(buf + ZIP_CENTRAL_CRC32_OFFS, z->crc32); + zip_write_int(buf + ZIP_CENTRAL_COMPLEN_OFFS, z->nbytecompr); + zip_write_int(buf + ZIP_CENTRAL_UNCOMPLEN_OFFS, z->nbyte); + zip_write_short(buf + ZIP_CENTRAL_PATHLEN_OFFS, len); + zip_write_short(buf + ZIP_CENTRAL_EXTRALEN_OFFS, 0); + zip_write_short(buf + ZIP_CENTRAL_FCOMMENTLEN_OFFS, 0); + zip_write_short(buf + ZIP_CENTRAL_DISKFILE_OFFS, 0); + zip_write_short(buf + ZIP_CENTRAL_IATTR_OFFS, 0); + zip_write_int(buf + ZIP_CENTRAL_EATTR_OFFS, 0); + zip_write_int(buf + ZIP_CENTRAL_LOCALHDR_OFFS, z->offset - pos[0]); + memcpy(buf + ZIP_CENTRAL_HEADER_LEN, z->name, len); + len += ZIP_CENTRAL_HEADER_LEN; + if (Tcl_Write(out, buf, len) != len) { + Tcl_AppendResult(interp, "write error", (char *) NULL); + goto done; + } + hPtr = Tcl_NextHashEntry(&search); + ++i; + } + Tcl_Flush(out); + pos[2] = Tcl_Tell(out); + zip_write_int(buf + ZIP_CENTRAL_END_SIG_OFFS, ZIP_CENTRAL_END_SIG); + zip_write_short(buf + ZIP_CENTRAL_DISKNO_OFFS, 0); + zip_write_short(buf + ZIP_CENTRAL_DISKDIR_OFFS, 0); + zip_write_short(buf + ZIP_CENTRAL_ENTS_OFFS, i); + zip_write_short(buf + ZIP_CENTRAL_TOTALENTS_OFFS, i); + zip_write_int(buf + ZIP_CENTRAL_DIRSIZE_OFFS, pos[2] - pos[1]); + zip_write_int(buf + ZIP_CENTRAL_DIRSTART_OFFS, pos[1] - pos[0]); + zip_write_short(buf + ZIP_CENTRAL_COMMENTLEN_OFFS, 0); + if (Tcl_Write(out, buf, ZIP_CENTRAL_END_LEN) != ZIP_CENTRAL_END_LEN) { + Tcl_AppendResult(interp, "write error", (char *) NULL); + goto done; + } + Tcl_Flush(out); + ret = TCL_OK; +done: + Tcl_Free((char *) largv); + Tcl_Close(interp, out); + hPtr = Tcl_FirstHashEntry(&fileHash, &search); + while (hPtr != NULL) { + z = (ZipEntry *) Tcl_GetHashValue(hPtr); + Tcl_Free((char *) z); + Tcl_DeleteHashEntry(hPtr); + hPtr = Tcl_FirstHashEntry(&fileHash, &search); + } + Tcl_DeleteHashTable(&fileHash); + return ret; +} + +static int +ZipFSMkZipCmd(ClientData clientData, Tcl_Interp *interp, + int argc, CONST char **argv) +{ + return ZipFSMkZipOrImgCmd(clientData, interp, 0, argc, argv); +} + +static int +ZipFSMkImgCmd(ClientData clientData, Tcl_Interp *interp, + int argc, CONST char **argv) +{ + return ZipFSMkZipOrImgCmd(clientData, interp, 1, argc, argv); +} + +static int +ZipFSExistsObjCmd(ClientData clientData, Tcl_Interp *interp, + int objc, Tcl_Obj *CONST objv[]) +{ + char *filename; + int exists; + + if (objc != 2) { + Tcl_WrongNumArgs(interp, 1, objv, "filename"); + return TCL_ERROR; + } + filename = Tcl_GetStringFromObj(objv[1], 0); + ReadLock(); + exists = ZipFSLookup(filename) != NULL; + Unlock(); + Tcl_SetBooleanObj(Tcl_GetObjResult(interp), exists); + return TCL_OK; +} + +static int +ZipFSInfoObjCmd(ClientData clientData, Tcl_Interp *interp, + int objc, Tcl_Obj *CONST objv[]) +{ + char *filename; + ZipEntry *z; + + if (objc != 2) { + Tcl_WrongNumArgs(interp, 1, objv, "filename"); + return TCL_ERROR; + } + filename = Tcl_GetStringFromObj(objv[1], 0); + ReadLock(); + z = ZipFSLookup(filename); + if (z != NULL) { + Tcl_Obj *result = Tcl_GetObjResult(interp); + + Tcl_ListObjAppendElement(interp, result, + Tcl_NewStringObj(z->zipfile->name, -1)); + Tcl_ListObjAppendElement(interp, result, Tcl_NewIntObj(z->nbyte)); + Tcl_ListObjAppendElement(interp, result, Tcl_NewIntObj(z->nbytecompr)); + Tcl_ListObjAppendElement(interp, result, Tcl_NewIntObj(z->offset)); + } + Unlock(); + return TCL_OK; +} + +static int +ZipFSListObjCmd(ClientData clientData, Tcl_Interp *interp, + int objc, Tcl_Obj *CONST objv[]) +{ + char *pattern = NULL; + Tcl_RegExp regexp = NULL; + Tcl_HashEntry *hPtr; + Tcl_HashSearch search; + Tcl_Obj *result = Tcl_GetObjResult(interp); + + if (objc > 3) { + Tcl_WrongNumArgs(interp, 1, objv, "?(-glob|-regexp)? ?pattern?"); + return TCL_ERROR; + } + if (objc == 3) { + int n; + char *what = Tcl_GetStringFromObj(objv[1], &n); + + if ((n >= 2) && (strncmp(what, "-glob", n) == 0)) { + pattern = Tcl_GetString(objv[2]); + } else if ((n >= 2) && (strncmp(what, "-regexp", n) == 0)) { + regexp = Tcl_RegExpCompile(interp, Tcl_GetString(objv[2])); + if (regexp == NULL) { + return TCL_ERROR; + } + } else { + Tcl_AppendResult(interp, "unknown option: ", what, (char *) NULL); + return TCL_ERROR; + } + } else if (objc == 2) { + pattern = Tcl_GetStringFromObj(objv[1], 0); + } + ReadLock(); + if (pattern != NULL) { + for (hPtr = Tcl_FirstHashEntry(&ZipFS.fileHash, &search); + hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) { + ZipEntry *z = (ZipEntry *) Tcl_GetHashValue(hPtr); + + if (Tcl_StringMatch(z->name, pattern)) { + Tcl_ListObjAppendElement(interp, result, + Tcl_NewStringObj(z->name, -1)); + } + } + } else if (regexp != NULL) { + for (hPtr = Tcl_FirstHashEntry(&ZipFS.fileHash, &search); + hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) { + ZipEntry *z = (ZipEntry *) Tcl_GetHashValue(hPtr); + + if (Tcl_RegExpExec(interp, regexp, z->name, z->name)) { + Tcl_ListObjAppendElement(interp, result, + Tcl_NewStringObj(z->name, -1)); + } + } + } else { + for (hPtr = Tcl_FirstHashEntry(&ZipFS.fileHash, &search); + hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) { + ZipEntry *z = (ZipEntry *) Tcl_GetHashValue(hPtr); + + Tcl_ListObjAppendElement(interp, result, + Tcl_NewStringObj(z->name, -1)); + } + } + Unlock(); + return TCL_OK; +} + +static int +ZipChannelClose(ClientData instanceData, Tcl_Interp *interp) +{ + ZipChannel *info = (ZipChannel *) instanceData; + + if (info->iscompr && (info->ubuf != NULL)) { + Tcl_Free((char *) info->ubuf); + info->ubuf = NULL; + } + if (info->isenc) { + info->isenc = 0; + memset(info->keys, 0, sizeof (info->keys)); + } + if (info->iswr) { + ZipEntry *z = info->zipentry; + unsigned char *newdata; + + newdata = + (unsigned char *) Tcl_Realloc((char *) info->ubuf, info->nread); + if (newdata != NULL) { + if (z->data != NULL) { + Tcl_Free((char *) z->data); + } + z->data = newdata; + z->nbyte = z->nbytecompr = info->nbyte; + z->cmeth = ZIP_COMPMETH_STORED; + z->timestamp = time(NULL); + z->isdir = 0; + z->isenc = 0; + z->offset = 0; + z->crc32 = 0; + } else { + Tcl_Free((char *) info->ubuf); + } + } + WriteLock(); + info->zipfile->nopen--; + Unlock(); + Tcl_Free((char *) info); + return TCL_OK; +} + +static int +ZipChannelRead(ClientData instanceData, char *buf, int toRead, int *errloc) +{ + ZipChannel *info = (ZipChannel *) instanceData; + unsigned long nextpos; + + if (info->isdir) { + *errloc = EISDIR; + return -1; + } + nextpos = info->nread + toRead; + if (nextpos > info->nbyte) { + toRead = info->nbyte - info->nread; + nextpos = info->nbyte; + } + if (toRead == 0) { + return 0; + } + if (info->isenc) { + int i, ch; + + for (i = 0; i < toRead; i++) { + ch = info->ubuf[i + info->nread]; + buf[i] = zdecode(info->keys, crc32tab, ch); + } + } else { + memcpy(buf, info->ubuf + info->nread, toRead); + } + info->nread = nextpos; + *errloc = 0; + return toRead; +} + +static int +ZipChannelWrite(ClientData instanceData, CONST char *buf, + int toWrite, int *errloc) +{ + ZipChannel *info = (ZipChannel *) instanceData; + unsigned long nextpos; + + if (!info->iswr) { + *errloc = EINVAL; + return -1; + } + nextpos = info->nread + toWrite; + if (nextpos > info->nmax) { + toWrite = info->nmax - info->nread; + nextpos = info->nmax; + } + if (toWrite == 0) { + return 0; + } + memcpy(info->ubuf + info->nread, buf, toWrite); + info->nread = nextpos; + if (info->nread > info->nbyte) { + info->nbyte = info->nread; + } + *errloc = 0; + return toWrite; +} + +static int +ZipChannelSeek(ClientData instanceData, long offset, int mode, int *errloc) +{ + ZipChannel *info = (ZipChannel *) instanceData; + + if (info->isdir) { + *errloc = EINVAL; + return -1; + } + switch (mode) { + case SEEK_CUR: + offset += info->nread; + break; + case SEEK_END: + offset += info->nbyte; + break; + case SEEK_SET: + break; + default: + *errloc = EINVAL; + return -1; + } + if (info->iswr) { + if (offset > info->nmax) { + *errloc = EINVAL; + return -1; + } + if (offset > info->nbyte) { + info->nbyte = offset; + } + } else if (offset > info->nbyte) { + *errloc = EINVAL; + return -1; + } + if (offset < 0) { + *errloc = EINVAL; + return -1; + } + info->nread = (unsigned long) offset; + return info->nread; +} + +static void +ZipChannelWatchChannel(ClientData instanceData, int mask) +{ + return; +} +static int +ZipChannelGetFile(ClientData instanceData, int direction, + ClientData *handlePtr) +{ + return TCL_ERROR; +} + +static Tcl_ChannelType ZipChannelType = { + "zip", /* Type name. */ +#ifdef TCL_CHANNEL_VERSION_4 + TCL_CHANNEL_VERSION_4, + ZipChannelClose, /* Close channel, clean instance data */ + ZipChannelRead, /* Handle read request */ + ZipChannelWrite, /* Handle write request */ + ZipChannelSeek, /* Move location of access point, NULL'able */ + NULL, /* Set options, NULL'able */ + NULL, /* Get options, NULL'able */ + ZipChannelWatchChannel, /* Initialize notifier */ + ZipChannelGetFile, /* Get OS handle from the channel */ + NULL, /* 2nd version of close channel, NULL'able */ + NULL, /* Set blocking mode for raw channel, NULL'able */ + NULL, /* Function to flush channel, NULL'able */ + NULL, /* Function to handle event, NULL'able */ + NULL, /* Wide seek function, NULL'able */ + NULL, /* Thread action function, NULL'able */ +#else + NULL, /* Set blocking/nonblocking behaviour, NULL'able */ + ZipChannelClose, /* Close channel, clean instance data */ + ZipChannelRead, /* Handle read request */ + ZipChannelWrite, /* Handle write request */ + ZipChannelSeek, /* Move location of access point, NULL'able */ + NULL, /* Set options, NULL'able */ + NULL, /* Get options, NULL'able */ + ZipChannelWatchChannel, /* Initialize notifier */ + ZipChannelGetFile, /* Get OS handle from the channel */ +#endif +}; + +static Tcl_Channel +ZipChannelOpen(Tcl_Interp *interp, char *filename, int mode, int permissions) +{ + ZipEntry *z; + ZipChannel *info; + static int count = 1; + int i, ch, trunc, wr, flags = 0; + char cname[128]; + + if ((mode & O_APPEND) || + ((ZipFS.wrmax <= 0) && (mode & (O_WRONLY | O_RDWR)))) { + if (interp != NULL) { + Tcl_SetObjResult(interp, Tcl_NewStringObj("unsupported open mode", -1)); + } + return NULL; + } + WriteLock(); + z = ZipFSLookup(filename); + if (z == NULL) { + if (interp != NULL) { + Tcl_SetObjResult(interp, Tcl_NewStringObj("file not found", -1)); + } + goto error; + } + trunc = (mode & O_TRUNC) != 0; + wr = (mode & (O_WRONLY | O_RDWR)) != 0; + if ((z->cmeth != ZIP_COMPMETH_STORED) && + (z->cmeth != ZIP_COMPMETH_DEFLATED)) { + if (interp != NULL) { + Tcl_SetObjResult(interp, + Tcl_NewStringObj("unsupported compression method", -1)); + } + goto error; + } + if (wr && z->isdir) { + if (interp != NULL) { + Tcl_SetObjResult(interp, + Tcl_NewStringObj("unsupported file type", -1)); + } + goto error; + } + if (!trunc) { + flags |= TCL_READABLE; + if (z->isenc && (z->zipfile->pwbuf[0] == 0)) { + if (interp != NULL) { + Tcl_SetObjResult(interp, + Tcl_NewStringObj("decryption failed", -1)); + } + goto error; + } else if (wr && (z->data == NULL) && (z->nbyte > ZipFS.wrmax)) { + if (interp != NULL) { + Tcl_SetObjResult(interp, + Tcl_NewStringObj("file too large", -1)); + } + goto error; + } + } else { + flags = TCL_WRITABLE; + } + info = (ZipChannel *) Tcl_Alloc (sizeof (*info)); + info->zipfile = z->zipfile; + info->zipentry = z; + info->nread = 0; + if (wr) { + flags |= TCL_WRITABLE; + info->iswr = 1; + info->isdir = 0; + info->nmax = ZipFS.wrmax; + info->iscompr = 0; + info->isenc = 0; + info->ubuf = (unsigned char *) Tcl_Alloc(info->nmax); + memset(info->ubuf, 0, info->nmax); + if (trunc) { + info->nbyte = 0; + } else { + if (z->data != NULL) { + i = z->nbyte; + if (i > info->nmax) { + i = info->nmax; + } + memcpy(info->ubuf, z->data, i); + info->nbyte = i; + } else { + unsigned char *zbuf = z->zipfile->data + z->offset; + + if (z->isenc) { + int len = z->zipfile->pwbuf[0]; + char pwbuf[260]; + + for (i = 0; i < len; i++) { + ch = z->zipfile->pwbuf[len - i]; + pwbuf[i] = (ch & 0x0f) | pwrot[(ch >> 4) & 0x0f]; + } + pwbuf[i] = '\0'; + init_keys(pwbuf, info->keys, crc32tab); + memset(pwbuf, 0, sizeof (pwbuf)); + for (i = 0; i < 12; i++) { + ch = info->ubuf[i]; + zdecode(info->keys, crc32tab, ch); + } + zbuf += i; + } + if (z->cmeth == ZIP_COMPMETH_DEFLATED) { + z_stream stream; + int err; + unsigned char *cbuf = NULL; + + memset(&stream, 0, sizeof (stream)); + stream.zalloc = Z_NULL; + stream.zfree = Z_NULL; + stream.opaque = Z_NULL; + stream.avail_in = z->nbytecompr; + if (z->isenc) { + stream.avail_in -= 12; + cbuf = (unsigned char *) Tcl_Alloc(stream.avail_in); + for (i = 0; i < stream.avail_in; i++) { + ch = info->ubuf[i]; + cbuf[i] = zdecode(info->keys, crc32tab, ch); + } + stream.next_in = cbuf; + } else { + stream.next_in = zbuf; + } + stream.next_out = info->ubuf; + stream.avail_out = info->nmax; + if (inflateInit2(&stream, -15) != Z_OK) { + goto cerror0; + } + err = inflate(&stream, Z_SYNC_FLUSH); + inflateEnd(&stream); + if ((err == Z_STREAM_END) || + ((err == Z_OK) && (stream.avail_in == 0))) { + if (cbuf != NULL) { + memset(info->keys, 0, sizeof (info->keys)); + Tcl_Free((char *) cbuf); + } + goto wrapchan; + } +cerror0: + if (cbuf != NULL) { + memset(info->keys, 0, sizeof (info->keys)); + Tcl_Free((char *) cbuf); + } + if (info->ubuf != NULL) { + Tcl_Free((char *) info->ubuf); + } + Tcl_Free((char *) info); + if (interp != NULL) { + Tcl_SetObjResult(interp, + Tcl_NewStringObj("decompression error", -1)); + } + goto error; + } else if (z->isenc) { + for (i = 0; i < z->nbyte - 12; i++) { + ch = zbuf[i]; + info->ubuf[i] = zdecode(info->keys, crc32tab, ch); + } + } else { + memcpy(info->ubuf, zbuf, z->nbyte); + } + memset(info->keys, 0, sizeof (info->keys)); + goto wrapchan; + } + } + } else if (z->data != NULL) { + flags |= TCL_READABLE; + info->iswr = 0; + info->iscompr = 0; + info->isdir = 0; + info->isenc = 0; + info->nbyte = z->nbyte; + info->nmax = 0; + info->ubuf = z->data; + } else { + flags |= TCL_READABLE; + info->iswr = 0; + info->iscompr = z->cmeth == ZIP_COMPMETH_DEFLATED; + info->ubuf = z->zipfile->data + z->offset; + info->isdir = z->isdir; + info->isenc = z->isenc; + info->nbyte = z->nbyte; + info->nmax = 0; + if (info->isenc) { + int len = z->zipfile->pwbuf[0]; + char pwbuf[260]; + + for (i = 0; i < len; i++) { + ch = z->zipfile->pwbuf[len - i]; + pwbuf[i] = (ch & 0x0f) | pwrot[(ch >> 4) & 0x0f]; + } + pwbuf[i] = '\0'; + init_keys(pwbuf, info->keys, crc32tab); + memset(pwbuf, 0, sizeof (pwbuf)); + for (i = 0; i < 12; i++) { + ch = info->ubuf[i]; + zdecode(info->keys, crc32tab, ch); + } + info->ubuf += i; + } + if (info->iscompr) { + z_stream stream; + int err; + unsigned char *ubuf = NULL; + + memset(&stream, 0, sizeof (stream)); + stream.zalloc = Z_NULL; + stream.zfree = Z_NULL; + stream.opaque = Z_NULL; + stream.avail_in = z->nbytecompr; + if (info->isenc) { + stream.avail_in -= 12; + ubuf = (unsigned char *) Tcl_Alloc(stream.avail_in); + for (i = 0; i < stream.avail_in; i++) { + ch = info->ubuf[i]; + ubuf[i] = zdecode(info->keys, crc32tab, ch); + } + stream.next_in = ubuf; + } else { + stream.next_in = info->ubuf; + } + stream.next_out = info->ubuf = + (unsigned char *) Tcl_Alloc(info->nbyte); + stream.avail_out = info->nbyte; + if (inflateInit2(&stream, -15) != Z_OK) { + goto cerror; + } + err = inflate(&stream, Z_SYNC_FLUSH); + inflateEnd(&stream); + if ((err == Z_STREAM_END) || + ((err == Z_OK) && (stream.avail_in == 0))) { + if (ubuf != NULL) { + info->isenc = 0; + memset(info->keys, 0, sizeof (info->keys)); + Tcl_Free((char *) ubuf); + } + goto wrapchan; + } +cerror: + if (ubuf != NULL) { + info->isenc = 0; + memset(info->keys, 0, sizeof (info->keys)); + Tcl_Free((char *) ubuf); + } + if (info->ubuf != NULL) { + Tcl_Free((char *) info->ubuf); + } + Tcl_Free((char *) info); + if (interp != NULL) { + Tcl_SetObjResult(interp, + Tcl_NewStringObj("decompression error", -1)); + } + goto error; + } + } +wrapchan: + sprintf(cname, "zipfs_%lx_%d", (unsigned long) z->offset, count++); + z->zipfile->nopen++; + Unlock(); + return Tcl_CreateChannel(&ZipChannelType, cname, (ClientData) info, flags); + +error: + Unlock(); + return NULL; +} + +static int +ZipEntryStat(char *path, Tcl_StatBuf *buf) +{ + ZipEntry *z; + int ret = -1; + + ReadLock(); + z = ZipFSLookup(path); + if (z == NULL) { + goto done; + } + memset(buf, 0, sizeof (Tcl_StatBuf)); + if (z->isdir) { + buf->st_mode = S_IFDIR | 0555; + } else { + buf->st_mode = S_IFREG | 0555; + } + buf->st_size = z->nbyte; + buf->st_mtime = z->timestamp; + buf->st_ctime = z->timestamp; + buf->st_atime = z->timestamp; + ret = 0; +done: + Unlock(); + return ret; +} + +static int +ZipEntryAccess(char *path, int mode) +{ + ZipEntry *z; + + if (mode & 3) { + return -1; + } + ReadLock(); + z = ZipFSLookup(path); + Unlock(); + return (z != NULL) ? 0 : -1; +} + +static Tcl_Channel +Zip_FSOpenFileChannelProc(Tcl_Interp *interp, Tcl_Obj *pathPtr, + int mode, int permissions) +{ + int len; + + return ZipChannelOpen(interp, Tcl_GetStringFromObj(pathPtr, &len), + mode, permissions); +} + +static int +Zip_FSStatProc(Tcl_Obj *pathPtr, Tcl_StatBuf *buf) +{ + int len; + + return ZipEntryStat(Tcl_GetStringFromObj(pathPtr, &len), buf); +} + +static int +Zip_FSAccessProc(Tcl_Obj *pathPtr, int mode) +{ + int len; + + return ZipEntryAccess(Tcl_GetStringFromObj(pathPtr, &len), mode); +} + +static Tcl_Obj * +Zip_FSFilesystemSeparatorProc(Tcl_Obj *pathPtr) +{ + return Tcl_NewStringObj("/", -1); +} + +static int +Zip_FSMatchInDirectoryProc(Tcl_Interp* interp, Tcl_Obj *result, + Tcl_Obj *pathPtr, CONST char *pattern, + Tcl_GlobTypeData *types) +{ + Tcl_HashEntry *hPtr; + Tcl_HashSearch search; + int scnt, len, l, dirOnly = -1, prefixLen, strip = 0; + char *pat, *prefix, *path; +#if defined(_WIN32) || defined(_WIN64) + char drivePrefix[3]; +#endif + Tcl_DString ds, dsPref; + +#if defined(_WIN32) || defined(_WIN64) + if ((pattern != NULL) && (pattern[0] != '\0') && + (strchr(alpha, pattern[0]) != NULL) && (pattern[1] == ':')) { + pattern += 2; + } +#endif + if (types != NULL) { + dirOnly = (types->type & TCL_GLOB_TYPE_DIR) == TCL_GLOB_TYPE_DIR; + } + Tcl_DStringInit(&ds); + Tcl_DStringInit(&dsPref); + prefix = Tcl_GetStringFromObj(pathPtr, &prefixLen); + Tcl_DStringAppend(&dsPref, prefix, prefixLen); + prefix = Tcl_DStringValue(&dsPref); + path = AbsolutePath(prefix, &ds); + len = Tcl_DStringLength(&ds); + if (strcmp(prefix, path) == 0) { + prefix = NULL; + } else { +#if defined(_WIN32) || defined(_WIN64) + if ((strchr(alpha, prefix[0]) != NULL) && (prefix[1] == ':')) { + if (strcmp(prefix + 2, path) == 0) { + strncpy(drivePrefix, prefix, 3); + drivePrefix[2] = '\0'; + prefix = drivePrefix; + } + } else { + strip = len + 1; + } +#else + strip = len + 1; +#endif + } + if (prefix != NULL) { +#if defined(_WIN32) || defined(_WIN64) + if (prefix == drivePrefix) { + Tcl_DStringSetLength(&dsPref, 0); + Tcl_DStringAppend(&dsPref, drivePrefix, -1); + prefixLen = Tcl_DStringLength(&dsPref); + } else { + Tcl_DStringAppend(&dsPref, "/", 1); + prefixLen++; + } + prefix = Tcl_DStringValue(&dsPref); +#else + Tcl_DStringAppend(&dsPref, "/", 1); + prefixLen++; + prefix = Tcl_DStringValue(&dsPref); +#endif + } + ReadLock(); + if ((types != NULL) && (types->type == TCL_GLOB_TYPE_MOUNT)) { + l = CountSlashes(path); + if (path[len - 1] == '/') { + len--; + } else { + l++; + } + if ((pattern == NULL) || (pattern[0] == '\0')) { + pattern = "*"; + } + hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); + while (hPtr != NULL) { + ZipFile *zf = (ZipFile *) Tcl_GetHashValue(hPtr); + + if (zf->mntptlen == 0) { + ZipEntry *z = zf->topents; + + while (z != NULL) { + int lenz = strlen(z->name); + + if ((lenz > len + 1) && + (strncmp(z->name, path, len) == 0) && + (z->name[len] == '/') && + (CountSlashes(z->name) == l) && + Tcl_StringCaseMatch(z->name + len + 1, pattern, 0)) { + if (prefix != NULL) { + Tcl_DStringAppend(&dsPref, z->name, lenz); + Tcl_ListObjAppendElement(NULL, result, + Tcl_NewStringObj(Tcl_DStringValue(&dsPref), + Tcl_DStringLength(&dsPref))); + Tcl_DStringSetLength(&dsPref, prefixLen); + } else { + Tcl_ListObjAppendElement(NULL, result, + Tcl_NewStringObj(z->name, lenz)); + } + } + z = z->tnext; + } + } else if ((zf->mntptlen > len + 1) && + (strncmp(zf->mntpt, path, len) == 0) && + (zf->mntpt[len] == '/') && + (CountSlashes(zf->mntpt) == l) && + Tcl_StringCaseMatch(zf->mntpt + len + 1, pattern, 0)) { + if (prefix != NULL) { + Tcl_DStringAppend(&dsPref, zf->mntpt, zf->mntptlen); + Tcl_ListObjAppendElement(NULL, result, + Tcl_NewStringObj(Tcl_DStringValue(&dsPref), + Tcl_DStringLength(&dsPref))); + Tcl_DStringSetLength(&dsPref, prefixLen); + } else { + Tcl_ListObjAppendElement(NULL, result, + Tcl_NewStringObj(zf->mntpt, zf->mntptlen)); + } + } + hPtr = Tcl_NextHashEntry(&search); + } + goto end; + } + if ((pattern == NULL) || (pattern[0] == '\0')) { + hPtr = Tcl_FindHashEntry(&ZipFS.fileHash, path); + if (hPtr != NULL) { + ZipEntry *z = (ZipEntry *) Tcl_GetHashValue(hPtr); + + if ((dirOnly < 0) || + (!dirOnly && !z->isdir) || + (dirOnly && z->isdir)) { + if (prefix != NULL) { + Tcl_DStringAppend(&dsPref, z->name, -1); + Tcl_ListObjAppendElement(NULL, result, + Tcl_NewStringObj(Tcl_DStringValue(&dsPref), + Tcl_DStringLength(&dsPref))); + Tcl_DStringSetLength(&dsPref, prefixLen); + } else { + Tcl_ListObjAppendElement(NULL, result, + Tcl_NewStringObj(z->name, -1)); + } + } + } + goto end; + } + l = strlen(pattern); + pat = Tcl_Alloc(len + l + 2); + memcpy(pat, path, len); + while ((len > 1) && (pat[len - 1] == '/')) { + --len; + } + if ((len > 1) || (pat[0] != '/')) { + pat[len] = '/'; + ++len; + } + memcpy(pat + len, pattern, l + 1); + scnt = CountSlashes(pat); + for (hPtr = Tcl_FirstHashEntry(&ZipFS.fileHash, &search); + hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) { + ZipEntry *z = (ZipEntry *) Tcl_GetHashValue(hPtr); + + if ((dirOnly >= 0) && + ((dirOnly && !z->isdir) || (!dirOnly && z->isdir))) { + continue; + } + if ((z->depth == scnt) && Tcl_StringCaseMatch(z->name, pat, 0)) { + if (prefix != NULL) { + Tcl_DStringAppend(&dsPref, z->name + strip, -1); + Tcl_ListObjAppendElement(NULL, result, + Tcl_NewStringObj(Tcl_DStringValue(&dsPref), + Tcl_DStringLength(&dsPref))); + Tcl_DStringSetLength(&dsPref, prefixLen); + } else { + Tcl_ListObjAppendElement(NULL, result, + Tcl_NewStringObj(z->name + strip, -1)); + } + } + } + Tcl_Free(pat); +end: + Unlock(); + Tcl_DStringFree(&dsPref); + Tcl_DStringFree(&ds); + return TCL_OK; +} + +static int +Zip_FSNormalizePathProc(Tcl_Interp *interp, Tcl_Obj *pathPtr, + int nextCheckpoint) +{ + char *path; + Tcl_DString ds; + int len; + + path = Tcl_GetStringFromObj(pathPtr, &len); + Tcl_DStringInit(&ds); + path = AbsolutePath(path, &ds); + nextCheckpoint = Tcl_DStringLength(&ds); + Tcl_SetStringObj(pathPtr, Tcl_DStringValue(&ds), + Tcl_DStringLength(&ds)); + Tcl_DStringFree(&ds); + return nextCheckpoint; +} + +static int +Zip_FSPathInFilesystemProc(Tcl_Obj *pathPtr, ClientData *clientDataPtr) +{ + Tcl_HashEntry *hPtr; + Tcl_HashSearch search; + ZipFile *zf; + int ret = -1, len; + char *path; + Tcl_DString ds; + + path = Tcl_GetStringFromObj(pathPtr, &len); + Tcl_DStringInit(&ds); + path = AbsolutePath(path, &ds); + len = Tcl_DStringLength(&ds); +#if defined(_WIN32) || defined(_WIN64) + if (len && (strchr(alpha, path[0]) != NULL) && (path[1] == ':')) { + path += 2; + len -= 2; + } +#endif + ReadLock(); + hPtr = Tcl_FindHashEntry(&ZipFS.fileHash, path); + if (hPtr != NULL) { + ret = TCL_OK; + goto endloop; + } + hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); + while (hPtr != NULL) { + zf = (ZipFile *) Tcl_GetHashValue(hPtr); + if (zf->mntptlen == 0) { + ZipEntry *z = zf->topents; + + while (z != NULL) { + int lenz = strlen(z->name); + + if ((len >= lenz) && + (strncmp(path, z->name, lenz) == 0)) { + ret = TCL_OK; + goto endloop; + } + z = z->tnext; + } + } else if ((len >= zf->mntptlen) && + (strncmp(path, zf->mntpt, zf->mntptlen) == 0)) { + ret = TCL_OK; + goto endloop; + } + hPtr = Tcl_NextHashEntry(&search); + } +endloop: + Unlock(); + Tcl_DStringFree(&ds); + return ret; +} + +static Tcl_Obj * +Zip_FSListVolumesProc(void) +{ + Tcl_HashEntry *hPtr; + Tcl_HashSearch search; + ZipFile *zf; + Tcl_Obj *vols = Tcl_NewObj(), *vol; + + ReadLock(); + hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); + while (hPtr != NULL) { + zf = (ZipFile *) Tcl_GetHashValue(hPtr); + vol = Tcl_NewStringObj(zf->mntpt, zf->mntptlen); + Tcl_ListObjAppendList(NULL, vols, vol); + Tcl_DecrRefCount(vol); + hPtr = Tcl_NextHashEntry(&search); + } + Unlock(); + return vols; +} + +static int +Zip_FSChdirProc(Tcl_Obj *pathPtr) +{ + int len; + char *path; + Tcl_DString ds; + ZipEntry *z; + int ret = TCL_OK; + + path = Tcl_GetStringFromObj(pathPtr, &len); + Tcl_DStringInit(&ds); + path = AbsolutePath(path, &ds); + ReadLock(); + z = ZipFSLookup(path); + if ((z == NULL) || !z->isdir) { + Tcl_SetErrno(ENOENT); + ret = -1; + } + Unlock(); + Tcl_DStringFree(&ds); + return ret; +} + +static CONST char *CONST86 * +Zip_FSFileAttrStringsProc(Tcl_Obj *pathPtr, Tcl_Obj** objPtrRef) +{ + static CONST char *attrs[] = { + "-uncompsize", + "-compsize", + "-offset", + "-mount", + "-archive", + "-permissions", + NULL, + }; + + return attrs; +} + +static int +Zip_FSFileAttrsGetProc(Tcl_Interp *interp, int index, Tcl_Obj *pathPtr, + Tcl_Obj **objPtrRef) +{ + int len, ret = TCL_OK; + char *path; + ZipEntry *z; + + path = Tcl_GetStringFromObj(pathPtr, &len); + ReadLock(); + z = ZipFSLookup(path); + if (z == NULL) { + if (interp != NULL) { + Tcl_SetObjResult(interp, Tcl_NewStringObj("file not found", -1)); + } + ret = TCL_ERROR; + goto done; + } + switch (index) { + case 0: + *objPtrRef = Tcl_NewIntObj(z->nbyte); + goto done; + case 1: + *objPtrRef= Tcl_NewIntObj(z->nbytecompr); + goto done; + case 2: + *objPtrRef= Tcl_NewLongObj(z->offset); + goto done; + case 3: + *objPtrRef= Tcl_NewStringObj(z->zipfile->mntpt, -1); + goto done; + case 4: + *objPtrRef= Tcl_NewStringObj(z->zipfile->name, -1); + goto done; + case 5: + *objPtrRef= Tcl_NewStringObj("0555", -1); + goto done; + } + if (interp != NULL) { + Tcl_SetObjResult(interp, Tcl_NewStringObj("unknown attribute", -1)); + } + ret = TCL_ERROR; +done: + Unlock(); + return ret; +} + +static int +Zip_FSFileAttrsSetProc(Tcl_Interp *interp, int index, Tcl_Obj *pathPtr, + Tcl_Obj *objPtr) +{ + if (interp != NULL) { + Tcl_SetObjResult(interp, Tcl_NewStringObj("unsupported operation", -1)); + } + return TCL_ERROR; +} + + +static Tcl_Obj * +Zip_FSFilesystemPathTypeProc(Tcl_Obj *pathPtr) +{ + return Tcl_NewStringObj("zip", -1); +} + +#ifndef ANDROID +static int +Zip_FSLoadFile(Tcl_Interp *interp, Tcl_Obj *path, Tcl_LoadHandle *loadHandle, + Tcl_FSUnloadFileProc **unloadProcPtr, int flags) +{ + Tcl_FSLoadFileProc2 *loadFileProc; + Tcl_Obj *altPath = NULL; + int ret = -1; + + if (Tcl_FSAccess(path, R_OK) == 0) { + /* + * EXDEV should trigger loading by copying to temp store. + */ + Tcl_SetErrno(EXDEV); + return ret; + } else { + Tcl_Obj *objs[2] = { NULL, NULL }; + + objs[1] = TclPathPart(interp, path, TCL_PATH_DIRNAME); + if ((objs[1] != NULL) && (Zip_FSAccessProc(objs[1], R_OK) == 0)) { + /* + * Shared object is not in ZIP but its path prefix is, + * thus try to load from directory where the executable + * came from. + */ + TclDecrRefCount(objs[1]); + objs[1] = TclPathPart(interp, path, TCL_PATH_TAIL); + objs[0] = TclPathPart(interp, TclGetObjNameOfExecutable(), + TCL_PATH_DIRNAME); + if (objs[0] != NULL) { + altPath = TclJoinPath(2, objs); + if (altPath != NULL) { + Tcl_IncrRefCount(altPath); + if (Tcl_FSAccess(altPath, R_OK) == 0) { + path = altPath; + } + } + } + } + if (objs[0] != NULL) { + Tcl_DecrRefCount(objs[0]); + } + if (objs[1] != NULL) { + Tcl_DecrRefCount(objs[1]); + } + } + loadFileProc = (Tcl_FSLoadFileProc2 *) tclNativeFilesystem.loadFileProc; + if (loadFileProc != NULL) { + ret = loadFileProc(interp, path, loadHandle, unloadProcPtr, flags); + } else { + Tcl_SetErrno(ENOENT); + } + if (altPath != NULL) { + Tcl_DecrRefCount(altPath); + } + return ret; +} +#endif + +Tcl_Filesystem zipfsFilesystem = { + "zipfs", + sizeof (Tcl_Filesystem), + TCL_FILESYSTEM_VERSION_2, + Zip_FSPathInFilesystemProc, + NULL, /* dupInternalRepProc */ + NULL, /* freeInternalRepProc */ + NULL, /* internalToNormalizedProc */ + NULL, /* createInternalRepProc */ + Zip_FSNormalizePathProc, + Zip_FSFilesystemPathTypeProc, + Zip_FSFilesystemSeparatorProc, + Zip_FSStatProc, + Zip_FSAccessProc, + Zip_FSOpenFileChannelProc, + Zip_FSMatchInDirectoryProc, + NULL, /* utimeProc */ + NULL, /* linkProc */ + Zip_FSListVolumesProc, + Zip_FSFileAttrStringsProc, + Zip_FSFileAttrsGetProc, + Zip_FSFileAttrsSetProc, + NULL, /* createDirectoryProc */ + NULL, /* removeDirectoryProc */ + NULL, /* deleteFileProc */ + NULL, /* copyFileProc */ + NULL, /* renameFileProc */ + NULL, /* copyDirectoryProc */ + NULL, /* lstatProc */ +#ifdef ANDROID + NULL, /* loadFileProc */ +#else + (Tcl_FSLoadFileProc *) Zip_FSLoadFile, +#endif + NULL, /* getCwdProc */ + Zip_FSChdirProc, +}; + +#endif /* HAVE_ZLIB */ + +static int +Zipfs_doInit(Tcl_Interp *interp, int safe) +{ +#ifdef HAVE_ZLIB + static CONST char findproc[] = + "proc ::zipfs::find d {\n" + " set ret {}\n" + " foreach f [glob -directory $d -tails -nocomplain * .*] {\n" + " if {$f eq \".\" || $f eq \"..\"} {\n" + " continue\n" + " }\n" + " set f [file join $d $f]\n" + " lappend ret $f\n" + " foreach f [::zipfs::find $f] {\n" + " lappend ret $f\n" + " }\n" + " }\n" + " return [lsort $ret]\n" + "}\n"; + +#ifdef USE_TCL_STUBS + if (Tcl_InitStubs(interp, "8.0", 0) == NULL) { + return TCL_ERROR; + } +#endif + /* one-time initialization */ + WriteLock(); + if (!ZipFS.initialized) { + static const Tcl_Time t = { 0, 0 }; + + /* inflate condition */ + Tcl_MutexLock(&ZipFSMutex); + Tcl_ConditionWait(&ZipFSCond, &ZipFSMutex, &t); + Tcl_MutexUnlock(&ZipFSMutex); +#ifdef ANDROID + /* force loadFileProc to native one */ + zipfsFilesystem.loadFileProc = tclNativeFilesystem.loadFileProc; +#endif + Tcl_FSRegister(NULL, &zipfsFilesystem); + Tcl_InitHashTable(&ZipFS.fileHash, TCL_STRING_KEYS); + Tcl_InitHashTable(&ZipFS.zipHash, TCL_STRING_KEYS); + ZipFS.initialized = 1; +#if defined(ZIPFS_IN_TCL) || defined(ZIPFS_IN_TK) + Tcl_StaticPackage(interp, "zipfs", Zipfs_Init, Zipfs_SafeInit); +#endif + } + Unlock(); +#if !defined(ZIPFS_IN_TCL) && !defined(ZIPFS_IN_TK) + Tcl_PkgProvide(interp, "zipfs", "1.0"); +#endif + if (!safe) { + Tcl_CreateCommand(interp, "::zipfs::mount", ZipFSMountCmd, 0, 0); + Tcl_CreateCommand(interp, "::zipfs::unmount", ZipFSUnmountCmd, 0, 0); + Tcl_CreateCommand(interp, "::zipfs::mkkey", ZipFSMkKeyCmd, 0, 0); + Tcl_CreateCommand(interp, "::zipfs::mkimg", ZipFSMkImgCmd, 0, 0); + Tcl_CreateCommand(interp, "::zipfs::mkzip", ZipFSMkZipCmd, 0, 0); + Tcl_GlobalEval(interp, findproc); + } + Tcl_CreateObjCommand(interp, "::zipfs::exists", ZipFSExistsObjCmd, 0, 0); + Tcl_CreateObjCommand(interp, "::zipfs::info", ZipFSInfoObjCmd, 0, 0); + Tcl_CreateObjCommand(interp, "::zipfs::list", ZipFSListObjCmd, 0, 0); + if (!safe) { + Tcl_LinkVar(interp, "::zipfs::wrmax", (char *) &ZipFS.wrmax, + TCL_LINK_INT); + } + return TCL_OK; +#else + if (interp != NULL) { + Tcl_SetObjResult(interp, Tcl_NewStringObj("no zlib available", -1)); + } + return TCL_ERROR; +#endif +} + +int +Zipfs_Init(Tcl_Interp *interp) +{ + return Zipfs_doInit(interp, 0); +} + +int +Zipfs_SafeInit(Tcl_Interp *interp) +{ + return Zipfs_doInit(interp, 1); +} + +#ifndef HAVE_ZLIB + +int +Zipfs_Mount(Tcl_Interp *interp, CONST char *zipname, CONST char *mntpt, + CONST char *passwd) +{ + return Zipfs_doInit(interp, 1); +} + +int +Zipfs_Unmount(Tcl_Interp *interp, CONST char *zipname) +{ + return Zipfs_doInit(interp, 1); +} + +#endif + +/* + * Local Variables: + * mode: c + * c-basic-offset: 4 + * fill-column: 78 + * End: + */ diff --git a/generic/zipfs.h b/generic/zipfs.h new file mode 100644 index 0000000..587fed8 --- /dev/null +++ b/generic/zipfs.h @@ -0,0 +1,43 @@ +#ifndef _ZIPFS_H +#define _ZIPFS_H + +#ifdef ZIPFS_IN_TK +#include "tkInt.h" +#define Zipfs_Mount Tkzipfs_Mount +#define Zipfs_Unmount Tkzipfs_Unmount +#define Zipfs_Init Tkzipfs_Init +#define Zipfs_SafeInit Tkzipfs_SafeInit +#endif + +#ifdef ZIPFS_IN_TCL +#include "tclPort.h" +#define Zipfs_Mount Tclzipfs_Mount +#define Zipfs_Unmount Tclzipfs_Unmount +#define Zipfs_Init Tclzipfs_Init +#define Zipfs_SafeInit Tclzipfs_SafeInit +#endif + +#ifndef EXTERN +#define EXTERN extern +#endif + +#ifdef BUILD_tcl +#undef EXTERN +#define EXTERN +#endif + +EXTERN int Zipfs_Mount(Tcl_Interp *interp, CONST char *zipname, + CONST char *mntpt, CONST char *passwd); +EXTERN int Zipfs_Unmount(Tcl_Interp *interp, CONST char *mountname); +EXTERN int Zipfs_Init(Tcl_Interp *interp); +EXTERN int Zipfs_SafeInit(Tcl_Interp *interp); + +#endif + +/* + * Local Variables: + * mode: c + * c-basic-offset: 4 + * fill-column: 78 + * End: + */ diff --git a/pkgs/Android.mk b/pkgs/Android.mk new file mode 100644 index 0000000..5053e7d --- /dev/null +++ b/pkgs/Android.mk @@ -0,0 +1 @@ +include $(call all-subdir-makefiles) diff --git a/tcl-config.mk b/tcl-config.mk new file mode 100644 index 0000000..ae14b6b --- /dev/null +++ b/tcl-config.mk @@ -0,0 +1,60 @@ +tcl_includes := $(tcl_path)/generic $(tcl_path)/unix + +tcl_cflags := \ + -DHAVE_SYS_SELECT_H=1 \ + -DHAVE_LIMITS_H=1 \ + -DHAVE_UNISTD_H=1 \ + -DHAVE_SYS_PARAM_H=1 \ + -D_LARGEFILE64_SOURCE=1 \ + -DTCL_WIDE_INT_TYPE="long long" \ + -DTCL_SHLIB_EXT="\".so\"" \ + -DHAVE_CAST_TO_UNION=1 \ + -DHAVE_GETCWD=1 \ + -DHAVE_OPENDIR=1 \ + -DHAVE_MKSTEMP=1 \ + -DHAVE_MKSTEMPS=1 \ + -DHAVE_STRSTR=1 \ + -DHAVE_STRTOL=1 \ + -DHAVE_STRTOLL=1 \ + -DHAVE_STRTOULL=1 \ + -DHAVE_TMPNAM=1 \ + -DHAVE_WAITPID=1 \ + -DHAVE_STRUCT_ADDRINFO=1 \ + -DHAVE_STRUCT_IN6_ADDR=1 \ + -DHAVE_STRUCT_SOCKADDR_IN6=1 \ + -DHAVE_STRUCT_SOCKADDR_STORAGE=1 \ + -DUSE_TERMIOS=1 \ + -DHAVE_MKTIME=1 \ + -DUSE_INTERP_ERRORLINE=1 \ + -DHAVE_SYS_TIME_H=1 \ + -DTIME_WITH_SYS_TIME=1 \ + -DHAVE_TM_ZONE=1 \ + -DHAVE_GMTIME_R=1 \ + -DHAVE_LOCALTIME_R=1 \ + -DHAVE_TM_GMTOFF=1 \ + -DHAVE_TIMEZONE_VAR=1 \ + -DHAVE_ST_BLKSIZE=1 \ + -DSTDC_HEADERS=1 \ + -DHAVE_INTPTR_T=1 \ + -DHAVE_UINTPTR_T=1 \ + -DHAVE_SIGNED_CHAR=1 \ + -DHAVE_SYS_IOCTL_H=1 \ + -DHAVE_MEMCPY=1 \ + -DHAVE_MEMMOVE=1 \ + -DVOID=void \ + -DNO_UNION_WAIT=1 \ + -DHAVE_ZLIB=1 \ + -DMP_PREC=4 \ + -DTCL_TOMMATH=1 \ + -D_REENTRANT=1 \ + -D_THREADSAFE=1 \ + -DTCL_THREADS=1 \ + -DTCL_PTHREAD_ATFORK=1 \ + -DUSE_THREAD_ALLOC=1 \ + -DTCL_CFGVAL_ENCODING="\"utf-8\"" \ + -DTCL_UNLOAD_DLLS=1 \ + -DTCL_CFG_OPTIMIZED=1 \ + -DZIPFS_IN_TCL=1 \ + -DTCL_PACKAGE_PATH="\"/assets\"" \ + -DTCL_LIBRARY="\"/assets/tcl8.6\"" + diff --git a/unix/Makefile.in b/unix/Makefile.in index 18c90fa..eb1ba3c 100644 --- a/unix/Makefile.in +++ b/unix/Makefile.in @@ -308,7 +308,7 @@ GENERIC_OBJS = regcomp.o regexec.o regfree.o regerror.o tclAlloc.o \ tclStrToD.o tclThread.o \ tclThreadAlloc.o tclThreadJoin.o tclThreadStorage.o tclStubInit.o \ tclTimer.o tclTrace.o tclUtf.o tclUtil.o tclVar.o tclZlib.o \ - tclTomMathInterface.o + tclTomMathInterface.o zipfs.o OO_OBJS = tclOO.o tclOOBasic.o tclOOCall.o tclOODefineCmds.o tclOOInfo.o \ tclOOMethod.o tclOOStubInit.o @@ -382,7 +382,8 @@ GENERIC_HDRS = \ $(GENERIC_DIR)/tclPatch.h \ $(GENERIC_DIR)/tclPlatDecls.h \ $(GENERIC_DIR)/tclPort.h \ - $(GENERIC_DIR)/tclRegexp.h + $(GENERIC_DIR)/tclRegexp.h \ + $(GENERIC_DIR)/zipfs.h GENERIC_SRCS = \ $(GENERIC_DIR)/regcomp.c \ @@ -463,7 +464,8 @@ GENERIC_SRCS = \ $(GENERIC_DIR)/tclUtil.c \ $(GENERIC_DIR)/tclVar.c \ $(GENERIC_DIR)/tclAssembly.c \ - $(GENERIC_DIR)/tclZlib.c + $(GENERIC_DIR)/tclZlib.c \ + $(GENERIC_DIR)/zipfs.c OO_SRCS = \ $(GENERIC_DIR)/tclOO.c \ @@ -1321,6 +1323,9 @@ tclVar.o: $(GENERIC_DIR)/tclVar.c tclZlib.o: $(GENERIC_DIR)/tclZlib.c $(CC) -c $(CC_SWITCHES) $(ZLIB_INCLUDE) $(GENERIC_DIR)/tclZlib.c +zipfs.o: $(GENERIC_DIR)/zipfs.c + $(CC) -c $(CC_SWITCHES) $(ZLIB_INCLUDE) $(GENERIC_DIR)/zipfs.c + tclTest.o: $(GENERIC_DIR)/tclTest.c $(IOHDR) $(TCLREHDRS) $(CC) -c $(APP_CC_SWITCHES) $(GENERIC_DIR)/tclTest.c diff --git a/unix/tclLoadDl.c b/unix/tclLoadDl.c index dc711f8..3376d94 100644 --- a/unix/tclLoadDl.c +++ b/unix/tclLoadDl.c @@ -97,7 +97,11 @@ TclpDlopen( } else { dlopenflags |= RTLD_NOW; } - handle = dlopen(native, dlopenflags); + if (native == NULL) { + handle = NULL; + } else { + handle = dlopen(native, dlopenflags); + } if (handle == NULL) { /* * Let the OS loader examine the binary search path for whatever @@ -115,7 +119,41 @@ TclpDlopen( handle = dlopen(native, dlopenflags); Tcl_DStringFree(&ds); } +#ifdef ANDROID + /* + * If not an absolute or relative path, try to load + * from $INTERNAL_STORAGE/../lib (the place where the + * system has installed bundled .so files from the .APK) + */ + if (handle == NULL) { + native = Tcl_GetString(pathPtr); + if ((native != NULL) && (strchr(native, '/') == NULL)) { + char *storage = getenv("INTERNAL_STORAGE"); + Tcl_DString ds2; + if ((storage != NULL) && (storage[0] != '\0')) { + Tcl_DStringInit(&ds2); + Tcl_DStringAppend(&ds2, storage, -1); + Tcl_DStringAppend(&ds2, "/../lib/", -1); + Tcl_DStringAppend(&ds2, native, -1); + handle = dlopen(Tcl_DStringValue(&ds2), RTLD_NOW | RTLD_GLOBAL); + Tcl_DStringFree(&ds2); + } + if (handle == NULL) { + storage = getenv("TK_TCL_WISH_LD_LIBS"); + if ((storage != NULL) && (storage[0] != '\0')) { + Tcl_DStringInit(&ds2); + Tcl_DStringAppend(&ds2, storage, -1); + Tcl_DStringAppend(&ds2, "/", -1); + Tcl_DStringAppend(&ds2, native, -1); + handle = + dlopen(Tcl_DStringValue(&ds2), RTLD_NOW | RTLD_GLOBAL); + Tcl_DStringFree(&ds2); + } + } + } + } + #endif if (handle == NULL) { /* * Write the string to a variable first to work around a compiler bug diff --git a/unix/tclUnixFCmd.c b/unix/tclUnixFCmd.c index 3b1b6ca..0193dae 100644 --- a/unix/tclUnixFCmd.c +++ b/unix/tclUnixFCmd.c @@ -465,6 +465,9 @@ DoCopyFile( /* Used to determine filetype. */ { Tcl_StatBuf dstStatBuf; +#ifdef ANDROID + int ret; +#endif if (S_ISDIR(statBufPtr->st_mode)) { errno = EISDIR; @@ -520,7 +523,15 @@ DoCopyFile( if (mkfifo(dst, statBufPtr->st_mode) < 0) { /* INTL: Native. */ return TCL_ERROR; } +#ifdef ANDROID + ret = CopyFileAtts(src, dst, statBufPtr); + if (ret != TCL_OK && errno == EPERM) { + ret = TCL_OK; + } + return ret; +#else return CopyFileAtts(src, dst, statBufPtr); +#endif default: return TclUnixCopyFile(src, dst, statBufPtr, 0); } @@ -629,6 +640,11 @@ TclUnixCopyFile( return TCL_ERROR; } if (!dontCopyAtts && CopyFileAtts(src, dst, statBufPtr) == TCL_ERROR) { +#ifdef ANDROID + if (errno == EPERM) { + return TCL_OK; + } +#endif /* * The copy succeeded, but setting the permissions failed, so be in a * consistent state, we remove the file that was created by the copy. @@ -1203,6 +1219,11 @@ TraversalCopy( Tcl_DStringValue(dstPtr), statBufPtr) == TCL_OK) { return TCL_OK; } +#ifdef ANDROID + if (errno == EPERM) { + return TCL_OK; + } +#endif break; } diff --git a/unix/tclUnixInit.c b/unix/tclUnixInit.c index 520c8e5..927b1a6 100644 --- a/unix/tclUnixInit.c +++ b/unix/tclUnixInit.c @@ -541,6 +541,11 @@ TclpInitLibraryPath( */ str = defaultLibraryDir; +#ifdef ZIPFS_IN_TCL + if (Tclzipfs_Mount(NULL, NULL, NULL, NULL) == TCL_OK) { + str = ""; + } +#endif } if (str[0] != '\0') { objPtr = Tcl_NewStringObj(str, -1); diff --git a/unix/tclUnixPort.h b/unix/tclUnixPort.h index 123abec..6558332 100644 --- a/unix/tclUnixPort.h +++ b/unix/tclUnixPort.h @@ -447,9 +447,11 @@ extern int gettimeofday(struct timeval *tp, *--------------------------------------------------------------------------- */ +#ifndef ANDROID #ifndef L_tmpnam # define L_tmpnam 100 #endif +#endif /* *--------------------------------------------------------------------------- diff --git a/unix/tclUnixTime.c b/unix/tclUnixTime.c index 315bcf9..19cafe6 100644 --- a/unix/tclUnixTime.c +++ b/unix/tclUnixTime.c @@ -529,7 +529,10 @@ static void CleanupMemory( ClientData ignored) { - ckfree(lastTZ); + if (lastTZ != NULL) { + ckfree(lastTZ); + lastTZ = NULL; + } } /* diff --git a/win/Makefile.in b/win/Makefile.in index 168da2e..13a3e0c 100644 --- a/win/Makefile.in +++ b/win/Makefile.in @@ -296,7 +296,8 @@ GENERIC_OBJS = \ tclUtf.$(OBJEXT) \ tclUtil.$(OBJEXT) \ tclVar.$(OBJEXT) \ - tclZlib.$(OBJEXT) + tclZlib.$(OBJEXT) \ + zipfs.$(OBJEXT) TOMMATH_OBJS = \ bncore.${OBJEXT} \ @@ -741,7 +742,7 @@ clean: cleanhelp clean-packages distclean: distclean-packages clean $(RM) Makefile config.status config.cache config.log tclConfig.sh \ - tcl.hpj config.status.lineno + tcl.hpj config.status.lineno tclsh.exe.manifest # # Bundled package targets -- cgit v0.12 From d68207f7ca77f987f9c8d2c8400c089b2c976604 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 15 Jul 2015 09:31:11 +0000 Subject: Remove unused local variables. Now unix/tclUnixTime.c is idential in "androwish" compared to "novem". (Yes, those functions are planned to be removed in Tcl 9.0!) --- unix/tclUnixTime.c | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/unix/tclUnixTime.c b/unix/tclUnixTime.c index 240bc91..470b122 100644 --- a/unix/tclUnixTime.c +++ b/unix/tclUnixTime.c @@ -17,25 +17,6 @@ #endif /* - * TclpGetDate is coded to return a pointer to a 'struct tm'. For thread - * safety, this structure must be in thread-specific data. The 'tmKey' - * variable is the key to this buffer. - */ - -static Tcl_ThreadDataKey tmKey; -typedef struct ThreadSpecificData { - struct tm gmtime_buf; - struct tm localtime_buf; -} ThreadSpecificData; - -/* - * If we fall back on the thread-unsafe versions of gmtime and localtime, use - * this mutex to try to protect them. - */ - -TCL_DECLARE_MUTEX(tmMutex) - -/* * Static functions declared in this file. */ -- cgit v0.12 From 6e0d4b67612beec4f87f531f87878314a26db669 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Mon, 24 Aug 2015 07:58:42 +0000 Subject: Remove unused internal stub entries as well. --- generic/tclInt.decls | 18 ++-- generic/tclIntPlatDecls.h | 32 +++---- win/tclWinTime.c | 222 ---------------------------------------------- 3 files changed, 23 insertions(+), 249 deletions(-) diff --git a/generic/tclInt.decls b/generic/tclInt.decls index 27245f1..9f990f7 100644 --- a/generic/tclInt.decls +++ b/generic/tclInt.decls @@ -534,7 +534,7 @@ declare 132 { int TclpHasSockets(Tcl_Interp *interp) } # Removed in androwish -#declare 133 { +# declare 133 { # struct tm *TclpGetDate(const time_t *time, int useGMT) #} # Removed in 8.5 @@ -750,6 +750,8 @@ declare 179 { # const char *file, int line) #} +# TclpGmtime and TclpLocaltime promoted to the generic interface from unix + # Removed in androwish #declare 182 { # struct tm *TclpLocaltime(const time_t *clock) @@ -1218,12 +1220,14 @@ declare 10 unix { } # Slots 11 and 12 are forwarders for functions that were promoted to # generic Stubs -declare 11 unix { - struct tm *TclpLocaltime_unix(const time_t *clock) -} -declare 12 unix { - struct tm *TclpGmtime_unix(const time_t *clock) -} +# Removed in androwish +#declare 11 unix { +# struct tm *TclpLocaltime_unix(const time_t *clock) +#} +# Removed in androwish +#declare 12 unix { +# struct tm *TclpGmtime_unix(const time_t *clock) +#} declare 13 unix { char *TclpInetNtoa(struct in_addr addr) } diff --git a/generic/tclIntPlatDecls.h b/generic/tclIntPlatDecls.h index ac06787..b7a44d8 100644 --- a/generic/tclIntPlatDecls.h +++ b/generic/tclIntPlatDecls.h @@ -73,10 +73,8 @@ EXTERN int TclUnixWaitForFile(int fd, int mask, int timeout); EXTERN TclFile TclpCreateTempFile(const char *contents); /* 10 */ EXTERN Tcl_DirEntry * TclpReaddir(DIR *dir); -/* 11 */ -EXTERN struct tm * TclpLocaltime_unix(const time_t *clock); -/* 12 */ -EXTERN struct tm * TclpGmtime_unix(const time_t *clock); +/* Slot 11 is reserved */ +/* Slot 12 is reserved */ /* 13 */ EXTERN char * TclpInetNtoa(struct in_addr addr); /* 14 */ @@ -207,10 +205,8 @@ EXTERN int TclUnixWaitForFile(int fd, int mask, int timeout); EXTERN TclFile TclpCreateTempFile(const char *contents); /* 10 */ EXTERN Tcl_DirEntry * TclpReaddir(DIR *dir); -/* 11 */ -EXTERN struct tm * TclpLocaltime_unix(const time_t *clock); -/* 12 */ -EXTERN struct tm * TclpGmtime_unix(const time_t *clock); +/* Slot 11 is reserved */ +/* Slot 12 is reserved */ /* 13 */ EXTERN char * TclpInetNtoa(struct in_addr addr); /* 14 */ @@ -270,8 +266,8 @@ typedef struct TclIntPlatStubs { int (*tclUnixWaitForFile) (int fd, int mask, int timeout); /* 8 */ TclFile (*tclpCreateTempFile) (const char *contents); /* 9 */ Tcl_DirEntry * (*tclpReaddir) (DIR *dir); /* 10 */ - struct tm * (*tclpLocaltime_unix) (const time_t *clock); /* 11 */ - struct tm * (*tclpGmtime_unix) (const time_t *clock); /* 12 */ + void (*reserved11)(void); + void (*reserved12)(void); char * (*tclpInetNtoa) (struct in_addr addr); /* 13 */ int (*tclUnixCopyFile) (const char *src, const char *dst, const Tcl_StatBuf *statBufPtr, int dontCopyAtts); /* 14 */ void (*reserved15)(void); @@ -336,8 +332,8 @@ typedef struct TclIntPlatStubs { int (*tclUnixWaitForFile) (int fd, int mask, int timeout); /* 8 */ TclFile (*tclpCreateTempFile) (const char *contents); /* 9 */ Tcl_DirEntry * (*tclpReaddir) (DIR *dir); /* 10 */ - struct tm * (*tclpLocaltime_unix) (const time_t *clock); /* 11 */ - struct tm * (*tclpGmtime_unix) (const time_t *clock); /* 12 */ + void (*reserved11)(void); + void (*reserved12)(void); char * (*tclpInetNtoa) (struct in_addr addr); /* 13 */ int (*tclUnixCopyFile) (const char *src, const char *dst, const Tcl_StatBuf *statBufPtr, int dontCopyAtts); /* 14 */ int (*tclMacOSXGetFileAttribute) (Tcl_Interp *interp, int objIndex, Tcl_Obj *fileName, Tcl_Obj **attributePtrPtr); /* 15 */ @@ -393,10 +389,8 @@ extern const TclIntPlatStubs *tclIntPlatStubsPtr; (tclIntPlatStubsPtr->tclpCreateTempFile) /* 9 */ #define TclpReaddir \ (tclIntPlatStubsPtr->tclpReaddir) /* 10 */ -#define TclpLocaltime_unix \ - (tclIntPlatStubsPtr->tclpLocaltime_unix) /* 11 */ -#define TclpGmtime_unix \ - (tclIntPlatStubsPtr->tclpGmtime_unix) /* 12 */ +/* Slot 11 is reserved */ +/* Slot 12 is reserved */ #define TclpInetNtoa \ (tclIntPlatStubsPtr->tclpInetNtoa) /* 13 */ #define TclUnixCopyFile \ @@ -504,10 +498,8 @@ extern const TclIntPlatStubs *tclIntPlatStubsPtr; (tclIntPlatStubsPtr->tclpCreateTempFile) /* 9 */ #define TclpReaddir \ (tclIntPlatStubsPtr->tclpReaddir) /* 10 */ -#define TclpLocaltime_unix \ - (tclIntPlatStubsPtr->tclpLocaltime_unix) /* 11 */ -#define TclpGmtime_unix \ - (tclIntPlatStubsPtr->tclpGmtime_unix) /* 12 */ +/* Slot 11 is reserved */ +/* Slot 12 is reserved */ #define TclpInetNtoa \ (tclIntPlatStubsPtr->tclpInetNtoa) /* 13 */ #define TclUnixCopyFile \ diff --git a/win/tclWinTime.c b/win/tclWinTime.c index 7045c72..97e1f41 100644 --- a/win/tclWinTime.c +++ b/win/tclWinTime.c @@ -113,7 +113,6 @@ static TimeInfo timeInfo = { * Declarations for functions defined later in this file. */ -static struct tm * ComputeGMT(const time_t *tp); static void StopCalibration(ClientData clientData); static DWORD WINAPI CalibrationThread(LPVOID arg); static void UpdateTimeEachSecond(void); @@ -489,227 +488,6 @@ StopCalibration( /* *---------------------------------------------------------------------- * - * TclpGetDate -- - * - * This function converts between seconds and struct tm. If useGMT is - * true, then the returned date will be in Greenwich Mean Time (GMT). - * Otherwise, it will be in the local time zone. - * - * Results: - * Returns a static tm structure. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -struct tm * -TclpGetDate( - const time_t *t, - int useGMT) -{ - struct tm *tmPtr; - time_t time; - - if (!useGMT) { - tzset(); - - /* - * If we are in the valid range, let the C run-time library handle it. - * Otherwise we need to fake it. Note that this algorithm ignores - * daylight savings time before the epoch. - */ - - /* - * Hm, Borland's localtime manages to return NULL under certain - * circumstances (e.g. wintime.test, test 1.2). Nobody tests for this, - * since 'localtime' isn't supposed to do this, possibly leading to - * crashes. - * - * Patch: We only call this function if we are at least one day into - * the epoch, else we handle it ourselves (like we do for times < 0). - * H. Giese, June 2003 - */ - -#ifdef __BORLANDC__ -#define LOCALTIME_VALIDITY_BOUNDARY SECSPERDAY -#else -#define LOCALTIME_VALIDITY_BOUNDARY 0 -#endif - - if (*t >= LOCALTIME_VALIDITY_BOUNDARY) { - return TclpLocaltime(t); - } - - time = *t - timezone; - - /* - * If we aren't near to overflowing the long, just add the bias and - * use the normal calculation. Otherwise we will need to adjust the - * result at the end. - */ - - if (*t < (LONG_MAX - 2*SECSPERDAY) && *t > (LONG_MIN + 2*SECSPERDAY)) { - tmPtr = ComputeGMT(&time); - } else { - tmPtr = ComputeGMT(t); - - tzset(); - - /* - * Add the bias directly to the tm structure to avoid overflow. - * Propagate seconds overflow into minutes, hours and days. - */ - - time = tmPtr->tm_sec - timezone; - tmPtr->tm_sec = (int)(time % 60); - if (tmPtr->tm_sec < 0) { - tmPtr->tm_sec += 60; - time -= 60; - } - - time = tmPtr->tm_min + time/60; - tmPtr->tm_min = (int)(time % 60); - if (tmPtr->tm_min < 0) { - tmPtr->tm_min += 60; - time -= 60; - } - - time = tmPtr->tm_hour + time/60; - tmPtr->tm_hour = (int)(time % 24); - if (tmPtr->tm_hour < 0) { - tmPtr->tm_hour += 24; - time -= 24; - } - - time /= 24; - tmPtr->tm_mday += (int)time; - tmPtr->tm_yday += (int)time; - tmPtr->tm_wday = (tmPtr->tm_wday + (int)time) % 7; - } - } else { - tmPtr = ComputeGMT(t); - } - return tmPtr; -} - -/* - *---------------------------------------------------------------------- - * - * ComputeGMT -- - * - * This function computes GMT given the number of seconds since the epoch - * (midnight Jan 1 1970). - * - * Results: - * Returns a (per thread) statically allocated struct tm. - * - * Side effects: - * Updates the values of the static struct tm. - * - *---------------------------------------------------------------------- - */ - -static struct tm * -ComputeGMT( - const time_t *tp) -{ - struct tm *tmPtr; - long tmp, rem; - int isLeap; - const int *days; - ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); - - tmPtr = &tsdPtr->tm; - - /* - * Compute the 4 year span containing the specified time. - */ - - tmp = (long)(*tp / SECSPER4YEAR); - rem = (long)(*tp % SECSPER4YEAR); - - /* - * Correct for weird mod semantics so the remainder is always positive. - */ - - if (rem < 0) { - tmp--; - rem += SECSPER4YEAR; - } - - /* - * Compute the year after 1900 by taking the 4 year span and adjusting for - * the remainder. This works because 2000 is a leap year, and 1900/2100 - * are out of the range. - */ - - tmp = (tmp * 4) + 70; - isLeap = 0; - if (rem >= SECSPERYEAR) { /* 1971, etc. */ - tmp++; - rem -= SECSPERYEAR; - if (rem >= SECSPERYEAR) { /* 1972, etc. */ - tmp++; - rem -= SECSPERYEAR; - if (rem >= SECSPERYEAR + SECSPERDAY) { /* 1973, etc. */ - tmp++; - rem -= SECSPERYEAR + SECSPERDAY; - } else { - isLeap = 1; - } - } - } - tmPtr->tm_year = tmp; - - /* - * Compute the day of year and leave the seconds in the current day in the - * remainder. - */ - - tmPtr->tm_yday = rem / SECSPERDAY; - rem %= SECSPERDAY; - - /* - * Compute the time of day. - */ - - tmPtr->tm_hour = rem / 3600; - rem %= 3600; - tmPtr->tm_min = rem / 60; - tmPtr->tm_sec = rem % 60; - - /* - * Compute the month and day of month. - */ - - days = (isLeap) ? leapDays : normalDays; - for (tmp = 1; days[tmp] < tmPtr->tm_yday; tmp++) { - /* empty body */ - } - tmPtr->tm_mon = --tmp; - tmPtr->tm_mday = tmPtr->tm_yday - days[tmp]; - - /* - * Compute day of week. Epoch started on a Thursday. - */ - - tmPtr->tm_wday = (long)(*tp / SECSPERDAY) + 4; - if ((*tp % SECSPERDAY) < 0) { - tmPtr->tm_wday--; - } - tmPtr->tm_wday %= 7; - if (tmPtr->tm_wday < 0) { - tmPtr->tm_wday += 7; - } - - return tmPtr; -} - -/* - *---------------------------------------------------------------------- - * * CalibrationThread -- * * Thread that manages calibration of the hi-resolution time derived from -- cgit v0.12 From ecc90e3787b23274b9f03670ba869c8f7da8213a Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Mon, 24 Aug 2015 08:01:23 +0000 Subject: one more.... --- generic/tclStubInit.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/generic/tclStubInit.c b/generic/tclStubInit.c index edeb42a..8359fa6 100644 --- a/generic/tclStubInit.c +++ b/generic/tclStubInit.c @@ -294,10 +294,6 @@ static int formatInt(char *buffer, int n){ #define TclFormatInt (int(*)(char *, long))formatInt #endif - -#else /* UNIX and MAC */ -# define TclpLocaltime_unix TclpLocaltime -# define TclpGmtime_unix TclpGmtime #endif /* @@ -586,8 +582,8 @@ static const TclIntPlatStubs tclIntPlatStubs = { TclUnixWaitForFile, /* 8 */ TclpCreateTempFile, /* 9 */ TclpReaddir, /* 10 */ - TclpLocaltime_unix, /* 11 */ - TclpGmtime_unix, /* 12 */ + 0, /* 11 */ + 0, /* 12 */ TclpInetNtoa, /* 13 */ TclUnixCopyFile, /* 14 */ 0, /* 15 */ @@ -652,8 +648,8 @@ static const TclIntPlatStubs tclIntPlatStubs = { TclUnixWaitForFile, /* 8 */ TclpCreateTempFile, /* 9 */ TclpReaddir, /* 10 */ - TclpLocaltime_unix, /* 11 */ - TclpGmtime_unix, /* 12 */ + 0, /* 11 */ + 0, /* 12 */ TclpInetNtoa, /* 13 */ TclUnixCopyFile, /* 14 */ TclMacOSXGetFileAttribute, /* 15 */ -- cgit v0.12 From dbe627594edb4a5b12aa260f2c02d9c2b2b48c3f Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Mon, 31 Aug 2015 17:30:01 +0000 Subject: Dependancies from androwish upstream --- Android.mk | 2 ++ tcl-config.mk | 72 +++++++++++++++++++++++++++++---------------------------- win/Makefile.in | 5 ++-- 3 files changed, 42 insertions(+), 37 deletions(-) diff --git a/Android.mk b/Android.mk index 9d8ce27..13e55d9 100644 --- a/Android.mk +++ b/Android.mk @@ -12,6 +12,8 @@ tcl_path := $(LOCAL_PATH) include $(tcl_path)/tcl-config.mk +LOCAL_ADDITIONAL_DEPENDENCIES += $(tcl_path)/tcl-config.mk + LOCAL_MODULE := tcl LOCAL_ARM_MODE := arm diff --git a/tcl-config.mk b/tcl-config.mk index ae14b6b..e072516 100644 --- a/tcl-config.mk +++ b/tcl-config.mk @@ -1,60 +1,62 @@ tcl_includes := $(tcl_path)/generic $(tcl_path)/unix tcl_cflags := \ - -DHAVE_SYS_SELECT_H=1 \ - -DHAVE_LIMITS_H=1 \ - -DHAVE_UNISTD_H=1 \ - -DHAVE_SYS_PARAM_H=1 \ - -D_LARGEFILE64_SOURCE=1 \ - -DTCL_WIDE_INT_TYPE="long long" \ - -DTCL_SHLIB_EXT="\".so\"" \ - -DHAVE_CAST_TO_UNION=1 \ - -DHAVE_GETCWD=1 \ - -DHAVE_OPENDIR=1 \ + -DHAVE_SYS_SELECT_H=1 \ + -DHAVE_LIMITS_H=1 \ + -DHAVE_UNISTD_H=1 \ + -DHAVE_SYS_PARAM_H=1 \ + -D_LARGEFILE64_SOURCE=1 \ + -DTCL_WIDE_INT_TYPE="long long" \ + -DTCL_SHLIB_EXT="\".so\"" \ + -DHAVE_CAST_TO_UNION=1 \ + -DHAVE_GETCWD=1 \ + -DHAVE_OPENDIR=1 \ -DHAVE_MKSTEMP=1 \ -DHAVE_MKSTEMPS=1 \ - -DHAVE_STRSTR=1 \ - -DHAVE_STRTOL=1 \ - -DHAVE_STRTOLL=1 \ - -DHAVE_STRTOULL=1 \ - -DHAVE_TMPNAM=1 \ - -DHAVE_WAITPID=1 \ + -DHAVE_STRSTR=1 \ + -DHAVE_STRTOL=1 \ + -DHAVE_STRTOLL=1 \ + -DHAVE_STRTOULL=1 \ + -DHAVE_TMPNAM=1 \ + -DHAVE_WAITPID=1 \ -DHAVE_STRUCT_ADDRINFO=1 \ -DHAVE_STRUCT_IN6_ADDR=1 \ -DHAVE_STRUCT_SOCKADDR_IN6=1 \ -DHAVE_STRUCT_SOCKADDR_STORAGE=1 \ - -DUSE_TERMIOS=1 \ - -DHAVE_MKTIME=1 \ - -DUSE_INTERP_ERRORLINE=1 \ - -DHAVE_SYS_TIME_H=1 \ - -DTIME_WITH_SYS_TIME=1 \ - -DHAVE_TM_ZONE=1 \ - -DHAVE_GMTIME_R=1 \ - -DHAVE_LOCALTIME_R=1 \ - -DHAVE_TM_GMTOFF=1 \ - -DHAVE_TIMEZONE_VAR=1 \ - -DHAVE_ST_BLKSIZE=1 \ - -DSTDC_HEADERS=1 \ + -DHAVE_GETHOSTBYNAME_R=1 \ + -DUSE_TERMIOS=1 \ + -DHAVE_MKTIME=1 \ + -DUSE_INTERP_ERRORLINE=1 \ + -DHAVE_SYS_TIME_H=1 \ + -DTIME_WITH_SYS_TIME=1 \ + -DHAVE_TM_ZONE=1 \ + -DHAVE_GMTIME_R=1 \ + -DHAVE_LOCALTIME_R=1 \ + -DHAVE_TM_GMTOFF=1 \ + -DHAVE_TIMEZONE_VAR=1 \ + -DHAVE_ST_BLKSIZE=1 \ + -DSTDC_HEADERS=1 \ -DHAVE_INTPTR_T=1 \ -DHAVE_UINTPTR_T=1 \ -DHAVE_SIGNED_CHAR=1 \ - -DHAVE_SYS_IOCTL_H=1 \ - -DHAVE_MEMCPY=1 \ - -DHAVE_MEMMOVE=1 \ - -DVOID=void \ - -DNO_UNION_WAIT=1 \ - -DHAVE_ZLIB=1 \ + -DHAVE_SYS_IOCTL_H=1 \ + -DHAVE_MEMCPY=1 \ + -DHAVE_MEMMOVE=1 \ + -DVOID=void \ + -DNO_UNION_WAIT=1 \ + -DHAVE_ZLIB=1 \ -DMP_PREC=4 \ -DTCL_TOMMATH=1 \ -D_REENTRANT=1 \ -D_THREADSAFE=1 \ + -DTCL_UTF_MAX=6 \ -DTCL_THREADS=1 \ -DTCL_PTHREAD_ATFORK=1 \ -DUSE_THREAD_ALLOC=1 \ -DTCL_CFGVAL_ENCODING="\"utf-8\"" \ -DTCL_UNLOAD_DLLS=1 \ -DTCL_CFG_OPTIMIZED=1 \ - -DZIPFS_IN_TCL=1 \ + -DZIPFS_IN_TCL=1 \ -DTCL_PACKAGE_PATH="\"/assets\"" \ -DTCL_LIBRARY="\"/assets/tcl8.6\"" diff --git a/win/Makefile.in b/win/Makefile.in index b92a062..b8a130c 100644 --- a/win/Makefile.in +++ b/win/Makefile.in @@ -296,7 +296,8 @@ GENERIC_OBJS = \ tclUtf.$(OBJEXT) \ tclUtil.$(OBJEXT) \ tclVar.$(OBJEXT) \ - tclZlib.$(OBJEXT) + tclZlib.$(OBJEXT) \ + zipfs.$(OBJEXT) TOMMATH_OBJS = \ bncore.${OBJEXT} \ @@ -741,7 +742,7 @@ clean: cleanhelp clean-packages distclean: distclean-packages clean $(RM) Makefile config.status config.cache config.log tclConfig.sh \ - tcl.hpj config.status.lineno + tcl.hpj config.status.lineno tclsh.exe.manifest # # Bundled package targets -- cgit v0.12 From 842b15b839b378f34b23291dda5ba279cffe1607 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Thu, 17 Sep 2015 11:47:04 +0000 Subject: fixed bug in zipfs error handling (backported from androwish) --- generic/zipfs.c | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/generic/zipfs.c b/generic/zipfs.c index ec58d9f..c150da0 100644 --- a/generic/zipfs.c +++ b/generic/zipfs.c @@ -819,10 +819,13 @@ Zipfs_Mount(Tcl_Interp *interp, CONST char *zipname, CONST char *mntpt, if (!isNew) { zf = (ZipFile *) Tcl_GetHashValue(hPtr); if (interp != NULL) { - Tcl_AppendResult(interp, "already mounted at ", zf->mntpt, - (char *) NULL); + Tcl_AppendResult(interp, "already mounted on \"", zf->mntptlen ? + zf->mntpt : "/", "\"", (char *) NULL); } - goto error; + Unlock(); + Tcl_DStringFree(&ds); + ZipFSCloseArchive(interp, &zf0); + return TCL_ERROR; } if (strcmp(mntpt, "/") == 0) { mntpt = ""; @@ -915,6 +918,7 @@ Zipfs_Mount(Tcl_Interp *interp, CONST char *zipname, CONST char *mntpt, goto nextent; } if (!isdir && (mntpt[0] == '\0') && !CountSlashes(path)) { + /* regular files skipped when mounting on root */ goto nextent; } Tcl_DStringSetLength(&fpBuf, 0); @@ -947,7 +951,7 @@ Zipfs_Mount(Tcl_Interp *interp, CONST char *zipname, CONST char *mntpt, z->data = NULL; hPtr = Tcl_CreateHashEntry(&ZipFS.fileHash, fullpath, &isNew); if (!isNew) { - /* skip it */ + /* should not happen but skip it anyway */ Tcl_Free((char *) z); } else { Tcl_SetHashValue(hPtr, (ClientData) z); @@ -988,7 +992,7 @@ Zipfs_Mount(Tcl_Interp *interp, CONST char *zipname, CONST char *mntpt, zd->data = NULL; hPtr = Tcl_CreateHashEntry(&ZipFS.fileHash, dir, &isNew); if (!isNew) { - /* should never happen but skip it */ + /* should not happen but skip it anyway */ Tcl_Free((char *) zd); } else { Tcl_SetHashValue(hPtr, (ClientData) zd); @@ -1012,13 +1016,6 @@ nextent: Unlock(); Tcl_FSMountsChanged(NULL); return TCL_OK; - -error: - Tcl_DStringFree(&ds); - Unlock(); - ZipFSCloseArchive(interp, zf); - Tcl_Free((char *) zf); - return TCL_ERROR; } int @@ -1039,7 +1036,7 @@ Zipfs_Unmount(Tcl_Interp *interp, CONST char *zipname) } hPtr = Tcl_FindHashEntry(&ZipFS.zipHash, realname); if (hPtr == NULL) { - /* does not report error */ + /* don't report error */ goto done; } zf = (ZipFile *) Tcl_GetHashValue(hPtr); @@ -1707,7 +1704,8 @@ ZipFSListObjCmd(ClientData clientData, Tcl_Interp *interp, return TCL_ERROR; } } else { - Tcl_AppendResult(interp, "unknown option: ", what, (char *) NULL); + Tcl_AppendResult(interp, "unknown option \"", what, + "\"", (char *) NULL); return TCL_ERROR; } } else if (objc == 2) { -- cgit v0.12 From 9dd94f739633837da43ddf3f0af5f99a36c2e803 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Mon, 28 Sep 2015 10:58:30 +0000 Subject: Don't use mutex retry mechanism on Android. (problems ???) --- unix/tclUnixThrd.c | 51 +++++---------------------------------------------- win/tclWinThrd.c | 37 +++++-------------------------------- 2 files changed, 10 insertions(+), 78 deletions(-) diff --git a/unix/tclUnixThrd.c b/unix/tclUnixThrd.c index ae81c5f..0e8070d 100644 --- a/unix/tclUnixThrd.c +++ b/unix/tclUnixThrd.c @@ -22,19 +22,6 @@ typedef struct ThreadSpecificData { static Tcl_ThreadDataKey dataKey; /* - * This is the number of milliseconds to wait between internal retries in - * the Tcl_MutexLock function. This value must be greater than zero and - * should be a suitable value for the given platform. - * - * TODO: This may need to be dynamically determined, based on the relative - * performance of the running process. - */ - -#ifndef TCL_MUTEX_LOCK_SLEEP_TIME -# define TCL_MUTEX_LOCK_SLEEP_TIME (25) -#endif - -/* * masterLock is used to serialize creation of mutexes, condition variables, * and thread local storage. This is the only place that can count on the * ability to statically initialize the mutex. @@ -58,13 +45,6 @@ static pthread_mutex_t allocLock = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t *allocLockPtr = &allocLock; /* - * The mutexLock serializes Tcl_MutexLock. This is necessary to prevent - * races when finalizing a mutex that some other thread may want to lock. - */ - -static pthread_mutex_t mutexLock = PTHREAD_MUTEX_INITIALIZER; - -/* * These are for the critical sections inside this file. */ @@ -380,7 +360,6 @@ TclpMasterUnlock(void) pthread_mutex_unlock(&masterLock); #endif } - /* *---------------------------------------------------------------------- @@ -457,32 +436,12 @@ retry: } MASTER_UNLOCK; } - while (1) { - pthread_mutex_lock(&mutexLock); - pmutexPtr = *((pthread_mutex_t **)mutexPtr); - if (pmutexPtr == NULL) { - pthread_mutex_unlock(&mutexLock); - goto retry; - } - if (pthread_mutex_trylock(pmutexPtr) == 0) { - pthread_mutex_unlock(&mutexLock); - return; - } - pthread_mutex_unlock(&mutexLock); - /* - * BUGBUG: All core and Thread package tests pass when usleep() - * is used; however, the Thread package tests hang at - * various places when Tcl_Sleep() is used, typically - * while running test "thread-17.8", "thread-17.9", or - * "thread-17.11a". Really, what we want here is just - * to yield to other threads for a while. - */ -#ifdef HAVE_USLEEP - usleep(TCL_MUTEX_LOCK_SLEEP_TIME * 1000); -#else - Tcl_Sleep(TCL_MUTEX_LOCK_SLEEP_TIME); -#endif + + pmutexPtr = *((pthread_mutex_t **)mutexPtr); + if (pmutexPtr == NULL) { + goto retry; } + pthread_mutex_lock(pmutexPtr); } /* diff --git a/win/tclWinThrd.c b/win/tclWinThrd.c index ae7ce80..927e115 100644 --- a/win/tclWinThrd.c +++ b/win/tclWinThrd.c @@ -24,16 +24,6 @@ _CRTIMP unsigned int __cdecl _controlfp (unsigned int unNew, unsigned int unMask #endif /* - * This is the number of milliseconds to wait between internal retries in - * the Tcl_MutexLock function. This value must be greater than or equal - * to zero and should be a suitable value for the given platform. - */ - -#ifndef TCL_MUTEX_LOCK_SLEEP_TIME -# define TCL_MUTEX_LOCK_SLEEP_TIME (0) -#endif - -/* * This is the master lock used to serialize access to other serialization * data structures. */ @@ -67,13 +57,6 @@ static int allocOnce = 0; #endif /* TCL_THREADS */ /* - * The mutexLock serializes Tcl_MutexLock. This is necessary to prevent - * races when finalizing a mutex that some other thread may want to lock. - */ - -static CRITICAL_SECTION mutexLock; - -/* * The joinLock serializes Create- and ExitThread. This is necessary to * prevent a race where a new joinable thread exits before the creating thread * had the time to create the necessary data structures in the emulation @@ -386,7 +369,6 @@ TclpInitLock(void) */ init = 1; - InitializeCriticalSection(&mutexLock); InitializeCriticalSection(&joinLock); InitializeCriticalSection(&initLock); InitializeCriticalSection(&masterLock); @@ -534,7 +516,6 @@ void TclFinalizeLock(void) { MASTER_LOCK; - DeleteCriticalSection(&mutexLock); DeleteCriticalSection(&joinLock); /* @@ -605,20 +586,12 @@ retry: } MASTER_UNLOCK; } - while (1) { - EnterCriticalSection(&mutexLock); - csPtr = *((CRITICAL_SECTION **)mutexPtr); - if (csPtr == NULL) { - LeaveCriticalSection(&mutexLock); - goto retry; - } - if (TryEnterCriticalSection(csPtr)) { - LeaveCriticalSection(&mutexLock); - return; - } - LeaveCriticalSection(&mutexLock); - Tcl_Sleep(TCL_MUTEX_LOCK_SLEEP_TIME); + + csPtr = *((CRITICAL_SECTION **)mutexPtr); + if (csPtr == NULL) { + goto retry; } + EnterCriticalSection(csPtr); } /* -- cgit v0.12 From 38d734ddcfc00e2885ad397ee93ac12e062be4ef Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Tue, 3 Nov 2015 13:13:14 +0000 Subject: better handle out-of-memory conditions in ZIP filesystem hard-wire initial encoding on Android to UTF-8 --- generic/zipfs.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++------- unix/tclUnixInit.c | 4 +++ 2 files changed, 69 insertions(+), 9 deletions(-) diff --git a/generic/zipfs.c b/generic/zipfs.c index 1722688..e3bb7db 100644 --- a/generic/zipfs.c +++ b/generic/zipfs.c @@ -830,7 +830,14 @@ ZipFSOpenArchive(Tcl_Interp *interp, CONST char *zipname, int needZip, goto error; } Tcl_Seek(zf->chan, 0, SEEK_SET); - zf->tofree = zf->data = (unsigned char *) Tcl_Alloc(zf->length); + zf->tofree = zf->data = (unsigned char *) Tcl_AttemptAlloc(zf->length); + if (zf->tofree == NULL) { + if (interp) { + Tcl_SetObjResult(interp, + Tcl_NewStringObj("out of memory", -1)); + } + goto error; + } i = Tcl_Read(zf->chan, (char *) zf->data, zf->length); if (i != zf->length) { if (interp) { @@ -1092,7 +1099,16 @@ Zipfs_Mount(Tcl_Interp *interp, CONST char *zipname, CONST char *mntpt, if (strcmp(mntpt, "/") == 0) { mntpt = ""; } - zf = (ZipFile *) Tcl_Alloc(sizeof (*zf) + strlen(mntpt) + 1); + zf = (ZipFile *) Tcl_AttemptAlloc(sizeof (*zf) + strlen(mntpt) + 1); + if (zf == NULL) { + if (interp != NULL) { + Tcl_AppendResult(interp, "out of memory", (char *) NULL); + } + Unlock(); + Tcl_DStringFree(&ds); + ZipFSCloseArchive(interp, &zf0); + return TCL_ERROR; + } *zf = zf0; zf->name = Tcl_GetHashKey(&ZipFS.zipHash, hPtr); strcpy(zf->mntpt, mntpt); @@ -2263,8 +2279,8 @@ ZipChannelClose(ClientData instanceData, Tcl_Interp *interp) ZipEntry *z = info->zipentry; unsigned char *newdata; - newdata = - (unsigned char *) Tcl_Realloc((char *) info->ubuf, info->nread); + newdata = (unsigned char *) + Tcl_AttemptRealloc((char *) info->ubuf, info->nread); if (newdata != NULL) { if (z->data != NULL) { Tcl_Free((char *) z->data); @@ -2595,7 +2611,13 @@ ZipChannelOpen(Tcl_Interp *interp, char *filename, int mode, int permissions) } else { flags = TCL_WRITABLE; } - info = (ZipChannel *) Tcl_Alloc (sizeof (*info)); + info = (ZipChannel *) Tcl_AttemptAlloc(sizeof (*info)); + if (info == NULL) { + if (interp != NULL) { + Tcl_SetObjResult(interp, Tcl_NewStringObj("out of memory", -1)); + } + goto error; + } info->zipfile = z->zipfile; info->zipentry = z; info->nread = 0; @@ -2606,7 +2628,19 @@ ZipChannelOpen(Tcl_Interp *interp, char *filename, int mode, int permissions) info->nmax = ZipFS.wrmax; info->iscompr = 0; info->isenc = 0; - info->ubuf = (unsigned char *) Tcl_Alloc(info->nmax); + info->ubuf = (unsigned char *) Tcl_AttemptAlloc(info->nmax); + if (info->ubuf == NULL) { +merror0: + if (info->ubuf != NULL) { + Tcl_Free((char *) info->ubuf); + } + Tcl_Free((char *) info); + if (interp != NULL) { + Tcl_SetObjResult(interp, + Tcl_NewStringObj("out of memory", -1)); + } + goto error; + } memset(info->ubuf, 0, info->nmax); if (trunc) { info->nbyte = 0; @@ -2650,7 +2684,11 @@ ZipChannelOpen(Tcl_Interp *interp, char *filename, int mode, int permissions) stream.avail_in = z->nbytecompr; if (z->isenc) { stream.avail_in -= 12; - cbuf = (unsigned char *) Tcl_Alloc(stream.avail_in); + cbuf = (unsigned char *) + Tcl_AttemptAlloc(stream.avail_in); + if (cbuf == NULL) { + goto merror0; + } for (i = 0; i < stream.avail_in; i++) { ch = info->ubuf[i]; cbuf[i] = zdecode(info->keys, crc32tab, ch); @@ -2747,7 +2785,11 @@ cerror0: stream.avail_in = z->nbytecompr; if (info->isenc) { stream.avail_in -= 12; - ubuf = (unsigned char *) Tcl_Alloc(stream.avail_in); + ubuf = (unsigned char *) Tcl_AttemptAlloc(stream.avail_in); + if (ubuf == NULL) { + info->ubuf = NULL; + goto merror; + } for (i = 0; i < stream.avail_in; i++) { ch = info->ubuf[i]; ubuf[i] = zdecode(info->keys, crc32tab, ch); @@ -2757,7 +2799,21 @@ cerror0: stream.next_in = info->ubuf; } stream.next_out = info->ubuf = - (unsigned char *) Tcl_Alloc(info->nbyte); + (unsigned char *) Tcl_AttemptAlloc(info->nbyte); + if (info->ubuf == NULL) { +merror: + if (ubuf != NULL) { + info->isenc = 0; + memset(info->keys, 0, sizeof (info->keys)); + Tcl_Free((char *) ubuf); + } + Tcl_Free((char *) info); + if (interp != NULL) { + Tcl_SetObjResult(interp, + Tcl_NewStringObj("out of memory", -1)); + } + goto error; + } stream.avail_out = info->nbyte; if (inflateInit2(&stream, -15) != Z_OK) { goto cerror; diff --git a/unix/tclUnixInit.c b/unix/tclUnixInit.c index c0fa94d..cb1f70e 100644 --- a/unix/tclUnixInit.c +++ b/unix/tclUnixInit.c @@ -588,10 +588,14 @@ TclpInitLibraryPath( void TclpSetInitialEncodings(void) { +#ifdef ANDROID + Tcl_SetSystemEncoding(NULL, "utf-8"); +#else Tcl_DString encodingName; Tcl_SetSystemEncoding(NULL, Tcl_GetEncodingNameFromEnvironment(&encodingName)); Tcl_DStringFree(&encodingName); +#endif } void -- cgit v0.12 From 19627fed479882d04fb4d3e738e4f959ff60b34d Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 16 Dec 2015 13:26:54 +0000 Subject: Remove zipfs symbols from stub table. Those symbols should be exported as-is, without using the stub mechanism. --- generic/tclInt.decls | 12 ------------ generic/tclIntDecls.h | 18 ------------------ generic/tclStubInit.c | 3 --- generic/zipfs.h | 19 +++++-------------- 4 files changed, 5 insertions(+), 47 deletions(-) diff --git a/generic/tclInt.decls b/generic/tclInt.decls index 5aadbf2..53d5ad0 100644 --- a/generic/tclInt.decls +++ b/generic/tclInt.decls @@ -1014,18 +1014,6 @@ declare 251 { int TclRegisterLiteral(void *envPtr, char *bytes, int length, int flags) } - -declare 252 { - int Tclzipfs_Init(Tcl_Interp *interp) -} -declare 253 { - int Tclzipfs_Mount(Tcl_Interp *interp, const char *zipname, - const char *mntpt, const char *passwd) -} -declare 254 { - int Tclzipfs_Unmount(Tcl_Interp *interp, const char *zipname) -} - ############################################################################## diff --git a/generic/tclIntDecls.h b/generic/tclIntDecls.h index 5962b60..bbd1aae 100644 --- a/generic/tclIntDecls.h +++ b/generic/tclIntDecls.h @@ -614,15 +614,6 @@ EXTERN void TclSetSlaveCancelFlags(Tcl_Interp *interp, int flags, /* 251 */ EXTERN int TclRegisterLiteral(void *envPtr, char *bytes, int length, int flags); -/* 252 */ -EXTERN int Tclzipfs_Init(Tcl_Interp *interp); -/* 253 */ -EXTERN int Tclzipfs_Mount(Tcl_Interp *interp, - const char *zipname, const char *mntpt, - const char *passwd); -/* 254 */ -EXTERN int Tclzipfs_Unmount(Tcl_Interp *interp, - const char *zipname); typedef struct TclIntStubs { int magic; @@ -880,9 +871,6 @@ typedef struct TclIntStubs { char * (*tclDoubleDigits) (double dv, int ndigits, int flags, int *decpt, int *signum, char **endPtr); /* 249 */ void (*tclSetSlaveCancelFlags) (Tcl_Interp *interp, int flags, int force); /* 250 */ int (*tclRegisterLiteral) (void *envPtr, char *bytes, int length, int flags); /* 251 */ - int (*tclzipfs_Init) (Tcl_Interp *interp); /* 252 */ - int (*tclzipfs_Mount) (Tcl_Interp *interp, const char *zipname, const char *mntpt, const char *passwd); /* 253 */ - int (*tclzipfs_Unmount) (Tcl_Interp *interp, const char *zipname); /* 254 */ } TclIntStubs; extern const TclIntStubs *tclIntStubsPtr; @@ -1311,12 +1299,6 @@ extern const TclIntStubs *tclIntStubsPtr; (tclIntStubsPtr->tclSetSlaveCancelFlags) /* 250 */ #define TclRegisterLiteral \ (tclIntStubsPtr->tclRegisterLiteral) /* 251 */ -#define Tclzipfs_Init \ - (tclIntStubsPtr->tclzipfs_Init) /* 252 */ -#define Tclzipfs_Mount \ - (tclIntStubsPtr->tclzipfs_Mount) /* 253 */ -#define Tclzipfs_Unmount \ - (tclIntStubsPtr->tclzipfs_Unmount) /* 254 */ #endif /* defined(USE_TCL_STUBS) */ diff --git a/generic/tclStubInit.c b/generic/tclStubInit.c index 214b0c4..95e46ca 100644 --- a/generic/tclStubInit.c +++ b/generic/tclStubInit.c @@ -562,9 +562,6 @@ static const TclIntStubs tclIntStubs = { TclDoubleDigits, /* 249 */ TclSetSlaveCancelFlags, /* 250 */ TclRegisterLiteral, /* 251 */ - Tclzipfs_Init, /* 252 */ - Tclzipfs_Mount, /* 253 */ - Tclzipfs_Unmount, /* 254 */ }; static const TclIntPlatStubs tclIntPlatStubs = { diff --git a/generic/zipfs.h b/generic/zipfs.h index a6bd45c..acc709b 100644 --- a/generic/zipfs.h +++ b/generic/zipfs.h @@ -33,20 +33,11 @@ extern "C" { #define Zipfs_SafeInit Tclzipfs_SafeInit #endif -#ifndef EXTERN -#define EXTERN extern -#endif - -#ifdef BUILD_tcl -#undef EXTERN -#define EXTERN -#endif - -EXTERN int Zipfs_Mount(Tcl_Interp *interp, CONST char *zipname, - CONST char *mntpt, CONST char *passwd); -EXTERN int Zipfs_Unmount(Tcl_Interp *interp, CONST char *zipname); -EXTERN int Zipfs_Init(Tcl_Interp *interp); -EXTERN int Zipfs_SafeInit(Tcl_Interp *interp); +DLLEXPORT int Zipfs_Mount(Tcl_Interp *interp, const char *zipname, + const char *mntpt, const char *passwd); +DLLEXPORT int Zipfs_Unmount(Tcl_Interp *interp, const char *zipname); +DLLEXPORT int Zipfs_Init(Tcl_Interp *interp); +DLLEXPORT int Zipfs_SafeInit(Tcl_Interp *interp); #ifdef __cplusplus } -- cgit v0.12 From 8f6089f225a01b69fadeb69105db95887d3ba9a5 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 16 Dec 2015 13:37:20 +0000 Subject: No need for more than tcl.h in zipfs.h --- generic/zipfs.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/generic/zipfs.h b/generic/zipfs.h index acc709b..a19e214 100644 --- a/generic/zipfs.h +++ b/generic/zipfs.h @@ -13,12 +13,13 @@ #ifndef _ZIPFS_H #define _ZIPFS_H +#include "tcl.h" + #ifdef __cplusplus extern "C" { #endif #ifdef ZIPFS_IN_TK -#include "tkInt.h" #define Zipfs_Mount Tkzipfs_Mount #define Zipfs_Unmount Tkzipfs_Unmount #define Zipfs_Init Tkzipfs_Init @@ -26,16 +27,15 @@ extern "C" { #endif #ifdef ZIPFS_IN_TCL -#include "tclPort.h" #define Zipfs_Mount Tclzipfs_Mount #define Zipfs_Unmount Tclzipfs_Unmount #define Zipfs_Init Tclzipfs_Init #define Zipfs_SafeInit Tclzipfs_SafeInit #endif -DLLEXPORT int Zipfs_Mount(Tcl_Interp *interp, const char *zipname, - const char *mntpt, const char *passwd); -DLLEXPORT int Zipfs_Unmount(Tcl_Interp *interp, const char *zipname); +DLLEXPORT int Zipfs_Mount(Tcl_Interp *interp, CONST char *zipname, + CONST char *mntpt, CONST char *passwd); +DLLEXPORT int Zipfs_Unmount(Tcl_Interp *interp, CONST char *zipname); DLLEXPORT int Zipfs_Init(Tcl_Interp *interp); DLLEXPORT int Zipfs_SafeInit(Tcl_Interp *interp); -- cgit v0.12 From 58ace2b1dc62afca0a94b701a8c7857f2b620313 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 16 Dec 2015 15:18:59 +0000 Subject: remove unnecessary Tclzipfs defines in tclStubInit.c --- generic/tclStubInit.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/generic/tclStubInit.c b/generic/tclStubInit.c index 95e46ca..9131c45 100644 --- a/generic/tclStubInit.c +++ b/generic/tclStubInit.c @@ -48,12 +48,6 @@ #undef TclWinGetSockOpt #undef TclWinSetSockOpt -#ifndef ZIPFS_IN_TCL -# define Tclzipfs_Init 0 -# define Tclzipfs_Mount 0 -# define Tclzipfs_Unmount 0 -#endif - /* See bug 510001: TclSockMinimumBuffers needs plat imp */ #ifdef _WIN64 # define TclSockMinimumBuffersOld 0 -- cgit v0.12 From d6fdfa46244d1d14d8c2dce5378e3a23ab51aac2 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Thu, 17 Dec 2015 12:04:22 +0000 Subject: minor tweaks for MSVC --- generic/zipfs.h | 20 ++++++++++++++++---- unix/tclUnixInit.c | 3 +++ 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/generic/zipfs.h b/generic/zipfs.h index a19e214..15ca37c 100644 --- a/generic/zipfs.h +++ b/generic/zipfs.h @@ -19,11 +19,19 @@ extern "C" { #endif +#ifndef ZIPFSAPI +# define ZIPFSAPI extern +#endif + #ifdef ZIPFS_IN_TK #define Zipfs_Mount Tkzipfs_Mount #define Zipfs_Unmount Tkzipfs_Unmount #define Zipfs_Init Tkzipfs_Init #define Zipfs_SafeInit Tkzipfs_SafeInit +#ifdef BUILD_tk +# undef ZIPFSAPI +# define ZIPFSAPI DLLEXPORT +#endif #endif #ifdef ZIPFS_IN_TCL @@ -31,13 +39,17 @@ extern "C" { #define Zipfs_Unmount Tclzipfs_Unmount #define Zipfs_Init Tclzipfs_Init #define Zipfs_SafeInit Tclzipfs_SafeInit +#ifdef BUILD_tcl +# undef ZIPFSAPI +# define ZIPFSAPI DLLEXPORT +#endif #endif -DLLEXPORT int Zipfs_Mount(Tcl_Interp *interp, CONST char *zipname, +ZIPFSAPI int Zipfs_Mount(Tcl_Interp *interp, CONST char *zipname, CONST char *mntpt, CONST char *passwd); -DLLEXPORT int Zipfs_Unmount(Tcl_Interp *interp, CONST char *zipname); -DLLEXPORT int Zipfs_Init(Tcl_Interp *interp); -DLLEXPORT int Zipfs_SafeInit(Tcl_Interp *interp); +ZIPFSAPI int Zipfs_Unmount(Tcl_Interp *interp, CONST char *zipname); +ZIPFSAPI int Zipfs_Init(Tcl_Interp *interp); +ZIPFSAPI int Zipfs_SafeInit(Tcl_Interp *interp); #ifdef __cplusplus } diff --git a/unix/tclUnixInit.c b/unix/tclUnixInit.c index cb1f70e..e8ccc76 100644 --- a/unix/tclUnixInit.c +++ b/unix/tclUnixInit.c @@ -9,6 +9,9 @@ */ #include "tclInt.h" +#ifdef ZIPFS_IN_TCL +#include "zipfs.h" +#endif #include #include #ifdef HAVE_LANGINFO -- cgit v0.12 From ecd9567624afb68333af5c0439bf195145312858 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Thu, 17 Dec 2015 15:23:27 +0000 Subject: Minor tweaks on ZIPFS_IN_TCL --- generic/tclMain.c | 12 +++++++----- unix/configure | 18 ++++++++++++++++++ unix/configure.in | 8 ++++++++ 3 files changed, 33 insertions(+), 5 deletions(-) diff --git a/generic/tclMain.c b/generic/tclMain.c index a52d62d..6acd15d 100644 --- a/generic/tclMain.c +++ b/generic/tclMain.c @@ -321,14 +321,14 @@ Tcl_MainEx( { Tcl_Obj *path, *resultPtr, *argvPtr, *appName; const char *encodingName = NULL; - int code, length, exitCode = 0; + int code, exitCode = 0; Tcl_MainLoopProc *mainLoopProc; Tcl_Channel chan; InteractiveState is; +#ifdef ZIPFS_IN_TCL const char *zipFile = NULL; Tcl_Obj *zipval = NULL; int autoRun = 1; -#ifdef ZIPFS_IN_TCL int zipOk = TCL_ERROR; #ifndef ANDROID const char *exeName; @@ -337,7 +337,7 @@ Tcl_MainEx( TclpSetInitialEncodings(); TclpFindExecutable((const char *)argv[0]); -#ifndef ANDROID +#if defined(ZIPFS_IN_TCL) && !defined(ANDROID) exeName = Tcl_GetNameOfExecutable(); #endif @@ -369,8 +369,9 @@ Tcl_MainEx( Tcl_DecrRefCount(value); argc -= 3; argv += 3; +#ifdef ZIPFS_IN_TCL } else if (argc > 2) { - length = strlen((char *) argv[1]); + int length = strlen((char *) argv[1]); if ((length >= 2) && (0 == _tcsncmp(TEXT("-zip"), argv[1], length))) { argc--; @@ -387,6 +388,7 @@ Tcl_MainEx( argc--; argv++; } +#endif } else if ((argc > 1) && ('-' != argv[1][0])) { Tcl_SetStartupScript(NewNativeObj(argv[1], -1), NULL); argc--; @@ -475,11 +477,11 @@ Tcl_MainEx( Tcl_DStringFree(&dsLib); #endif } -#endif if (zipval != NULL) { Tcl_DecrRefCount(zipval); zipval = NULL; } +#endif /* * Invoke application-specific initialization. diff --git a/unix/configure b/unix/configure index c19a77a..3e72a0d 100755 --- a/unix/configure +++ b/unix/configure @@ -869,6 +869,7 @@ Optional Packages: --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-encoding encoding for configuration values (default: iso8859-1) + --with-zipfs include ZIP filesystem --with-tzdata install timezone data (default: autodetect) Some influential environment variables: @@ -6211,6 +6212,23 @@ cat >>confdefs.h <<\_ACEOF _ACEOF +# Check whether --with-zipfs or --without-zipfs was given. +if test "${with_zipfs+set}" = set; then + withval="$with_zipfs" + tcl_ok=$withval +else + tcl_ok=no +fi; +echo "$as_me:$LINENO: result: $tcl_ok" >&5 +echo "${ECHO_T}$tcl_ok" >&6 +if test $tcl_ok = yes; then + +cat >>confdefs.h <<\_ACEOF +#define ZIPFS_IN_TCL 1 +_ACEOF + +fi + #-------------------------------------------------------------------- # The statements below define a collection of compile flags. This # macro depends on the value of SHARED_BUILD, and should be called diff --git a/unix/configure.in b/unix/configure.in index c7b0edc..7eeff3b 100644 --- a/unix/configure.in +++ b/unix/configure.in @@ -171,6 +171,14 @@ AS_IF([test $zlib_ok = no], [ AC_SUBST(ZLIB_INCLUDE,[-I\${ZLIB_DIR}]) ]) AC_DEFINE(HAVE_ZLIB, 1, [Is there an installed zlib?]) +AC_ARG_WITH(zipfs, + AC_HELP_STRING([--with-zipfs], + [include ZIP filesystem]), + [tcl_ok=$withval], [tcl_ok=no]) +AC_MSG_RESULT([$tcl_ok]) +if test $tcl_ok = yes; then + AC_DEFINE(ZIPFS_IN_TCL, 1, [Include ZIP filesystem?]) +fi #-------------------------------------------------------------------- # The statements below define a collection of compile flags. This -- cgit v0.12 From c795f44ea527a23d9d9cba2f4c811053ac7af6ff Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Fri, 18 Dec 2015 12:39:24 +0000 Subject: upstream androwish change --- debian/rules | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/debian/rules b/debian/rules index 7a0214c..a4b3bd4 100755 --- a/debian/rules +++ b/debian/rules @@ -18,8 +18,6 @@ else CFLAGS=-g -O2 -fno-unit-at-a-time endif -CFLAGS+=-DZIPFS_IN_TCL=1 - unpatch: dh_testdir quilt pop -a || test $$? = 2 @@ -49,7 +47,8 @@ build-stamp: patch-stamp --enable-man-symlinks \ --enable-man-compression=gzip \ --enable-threads \ - --without-tzdata && \ + --without-tzdata \ + --with-zipfs && \ touch ../generic/tclStubInit.c && \ $(MAKE) # Build the static library. -- cgit v0.12 From 4d946107e7d14769b306d8bf05ff4f661b7883ff Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Mon, 21 Dec 2015 09:16:38 +0000 Subject: Put back the stub entries for TclpGetDate/TclpLocaltime/TclpGmtime. Although those functions are dead (they will be removed in Tcl 9, already done in the "novem" branch), removing those functions is a good idea, this cannot be done in any 8.x release. It hinders the acceptance of a "zipfs" TIP, therefore this change should not be part of the "androwish" change-set. --- generic/tclInt.decls | 35 +++--- generic/tclIntDecls.h | 24 ++-- generic/tclIntPlatDecls.h | 32 +++-- generic/tclStubInit.c | 18 +-- unix/tclUnixTime.c | 197 +++++++++++++++++++++++++++++ win/tclWinTime.c | 308 +++++++++++++++++++++++++++++++++++++++++++++- 6 files changed, 565 insertions(+), 49 deletions(-) diff --git a/generic/tclInt.decls b/generic/tclInt.decls index 53d5ad0..4e7e422 100644 --- a/generic/tclInt.decls +++ b/generic/tclInt.decls @@ -532,10 +532,9 @@ declare 131 { declare 132 { int TclpHasSockets(Tcl_Interp *interp) } -# Removed in androwish -# declare 133 { -# struct tm *TclpGetDate(const time_t *time, int useGMT) -#} +declare 133 { + struct tm *TclpGetDate(const time_t *time, int useGMT) +} # Removed in 8.5 #declare 134 { # size_t TclpStrftime(char *s, size_t maxsize, const char *format, @@ -751,14 +750,12 @@ declare 179 { # TclpGmtime and TclpLocaltime promoted to the generic interface from unix -# Removed in androwish -#declare 182 { -# struct tm *TclpLocaltime(const time_t *clock) -#} -# Removed in androwish -#declare 183 { -# struct tm *TclpGmtime(const time_t *clock) -#} +declare 182 { + struct tm *TclpLocaltime(const time_t *clock) +} +declare 183 { + struct tm *TclpGmtime(const time_t *clock) +} # For the new "Thread Storage" subsystem. @@ -1207,14 +1204,12 @@ declare 10 unix { } # Slots 11 and 12 are forwarders for functions that were promoted to # generic Stubs -# Removed in androwish -#declare 11 unix { -# struct tm *TclpLocaltime_unix(const time_t *clock) -#} -# Removed in androwish -#declare 12 unix { -# struct tm *TclpGmtime_unix(const time_t *clock) -#} +declare 11 unix { + struct tm *TclpLocaltime_unix(const time_t *clock) +} +declare 12 unix { + struct tm *TclpGmtime_unix(const time_t *clock) +} declare 13 unix { char *TclpInetNtoa(struct in_addr addr) } diff --git a/generic/tclIntDecls.h b/generic/tclIntDecls.h index bbd1aae..f95f999 100644 --- a/generic/tclIntDecls.h +++ b/generic/tclIntDecls.h @@ -349,7 +349,8 @@ EXTERN void Tcl_SetNamespaceResolvers( Tcl_ResolveCompiledVarProc *compiledVarProc); /* 132 */ EXTERN int TclpHasSockets(Tcl_Interp *interp); -/* Slot 133 is reserved */ +/* 133 */ +EXTERN struct tm * TclpGetDate(const time_t *time, int useGMT); /* Slot 134 is reserved */ /* Slot 135 is reserved */ /* Slot 136 is reserved */ @@ -462,8 +463,10 @@ EXTERN void Tcl_SetStartupScript(Tcl_Obj *pathPtr, EXTERN Tcl_Obj * Tcl_GetStartupScript(const char **encodingNamePtr); /* Slot 180 is reserved */ /* Slot 181 is reserved */ -/* Slot 182 is reserved */ -/* Slot 183 is reserved */ +/* 182 */ +EXTERN struct tm * TclpLocaltime(const time_t *clock); +/* 183 */ +EXTERN struct tm * TclpGmtime(const time_t *clock); /* Slot 184 is reserved */ /* Slot 185 is reserved */ /* Slot 186 is reserved */ @@ -752,7 +755,7 @@ typedef struct TclIntStubs { int (*tcl_RemoveInterpResolvers) (Tcl_Interp *interp, const char *name); /* 130 */ void (*tcl_SetNamespaceResolvers) (Tcl_Namespace *namespacePtr, Tcl_ResolveCmdProc *cmdProc, Tcl_ResolveVarProc *varProc, Tcl_ResolveCompiledVarProc *compiledVarProc); /* 131 */ int (*tclpHasSockets) (Tcl_Interp *interp); /* 132 */ - void (*reserved133)(void); + struct tm * (*tclpGetDate) (const time_t *time, int useGMT); /* 133 */ void (*reserved134)(void); void (*reserved135)(void); void (*reserved136)(void); @@ -801,8 +804,8 @@ typedef struct TclIntStubs { Tcl_Obj * (*tcl_GetStartupScript) (const char **encodingNamePtr); /* 179 */ void (*reserved180)(void); void (*reserved181)(void); - void (*reserved182)(void); - void (*reserved183)(void); + struct tm * (*tclpLocaltime) (const time_t *clock); /* 182 */ + struct tm * (*tclpGmtime) (const time_t *clock); /* 183 */ void (*reserved184)(void); void (*reserved185)(void); void (*reserved186)(void); @@ -1100,7 +1103,8 @@ extern const TclIntStubs *tclIntStubsPtr; (tclIntStubsPtr->tcl_SetNamespaceResolvers) /* 131 */ #define TclpHasSockets \ (tclIntStubsPtr->tclpHasSockets) /* 132 */ -/* Slot 133 is reserved */ +#define TclpGetDate \ + (tclIntStubsPtr->tclpGetDate) /* 133 */ /* Slot 134 is reserved */ /* Slot 135 is reserved */ /* Slot 136 is reserved */ @@ -1185,8 +1189,10 @@ extern const TclIntStubs *tclIntStubsPtr; (tclIntStubsPtr->tcl_GetStartupScript) /* 179 */ /* Slot 180 is reserved */ /* Slot 181 is reserved */ -/* Slot 182 is reserved */ -/* Slot 183 is reserved */ +#define TclpLocaltime \ + (tclIntStubsPtr->tclpLocaltime) /* 182 */ +#define TclpGmtime \ + (tclIntStubsPtr->tclpGmtime) /* 183 */ /* Slot 184 is reserved */ /* Slot 185 is reserved */ /* Slot 186 is reserved */ diff --git a/generic/tclIntPlatDecls.h b/generic/tclIntPlatDecls.h index b7a44d8..ac06787 100644 --- a/generic/tclIntPlatDecls.h +++ b/generic/tclIntPlatDecls.h @@ -73,8 +73,10 @@ EXTERN int TclUnixWaitForFile(int fd, int mask, int timeout); EXTERN TclFile TclpCreateTempFile(const char *contents); /* 10 */ EXTERN Tcl_DirEntry * TclpReaddir(DIR *dir); -/* Slot 11 is reserved */ -/* Slot 12 is reserved */ +/* 11 */ +EXTERN struct tm * TclpLocaltime_unix(const time_t *clock); +/* 12 */ +EXTERN struct tm * TclpGmtime_unix(const time_t *clock); /* 13 */ EXTERN char * TclpInetNtoa(struct in_addr addr); /* 14 */ @@ -205,8 +207,10 @@ EXTERN int TclUnixWaitForFile(int fd, int mask, int timeout); EXTERN TclFile TclpCreateTempFile(const char *contents); /* 10 */ EXTERN Tcl_DirEntry * TclpReaddir(DIR *dir); -/* Slot 11 is reserved */ -/* Slot 12 is reserved */ +/* 11 */ +EXTERN struct tm * TclpLocaltime_unix(const time_t *clock); +/* 12 */ +EXTERN struct tm * TclpGmtime_unix(const time_t *clock); /* 13 */ EXTERN char * TclpInetNtoa(struct in_addr addr); /* 14 */ @@ -266,8 +270,8 @@ typedef struct TclIntPlatStubs { int (*tclUnixWaitForFile) (int fd, int mask, int timeout); /* 8 */ TclFile (*tclpCreateTempFile) (const char *contents); /* 9 */ Tcl_DirEntry * (*tclpReaddir) (DIR *dir); /* 10 */ - void (*reserved11)(void); - void (*reserved12)(void); + struct tm * (*tclpLocaltime_unix) (const time_t *clock); /* 11 */ + struct tm * (*tclpGmtime_unix) (const time_t *clock); /* 12 */ char * (*tclpInetNtoa) (struct in_addr addr); /* 13 */ int (*tclUnixCopyFile) (const char *src, const char *dst, const Tcl_StatBuf *statBufPtr, int dontCopyAtts); /* 14 */ void (*reserved15)(void); @@ -332,8 +336,8 @@ typedef struct TclIntPlatStubs { int (*tclUnixWaitForFile) (int fd, int mask, int timeout); /* 8 */ TclFile (*tclpCreateTempFile) (const char *contents); /* 9 */ Tcl_DirEntry * (*tclpReaddir) (DIR *dir); /* 10 */ - void (*reserved11)(void); - void (*reserved12)(void); + struct tm * (*tclpLocaltime_unix) (const time_t *clock); /* 11 */ + struct tm * (*tclpGmtime_unix) (const time_t *clock); /* 12 */ char * (*tclpInetNtoa) (struct in_addr addr); /* 13 */ int (*tclUnixCopyFile) (const char *src, const char *dst, const Tcl_StatBuf *statBufPtr, int dontCopyAtts); /* 14 */ int (*tclMacOSXGetFileAttribute) (Tcl_Interp *interp, int objIndex, Tcl_Obj *fileName, Tcl_Obj **attributePtrPtr); /* 15 */ @@ -389,8 +393,10 @@ extern const TclIntPlatStubs *tclIntPlatStubsPtr; (tclIntPlatStubsPtr->tclpCreateTempFile) /* 9 */ #define TclpReaddir \ (tclIntPlatStubsPtr->tclpReaddir) /* 10 */ -/* Slot 11 is reserved */ -/* Slot 12 is reserved */ +#define TclpLocaltime_unix \ + (tclIntPlatStubsPtr->tclpLocaltime_unix) /* 11 */ +#define TclpGmtime_unix \ + (tclIntPlatStubsPtr->tclpGmtime_unix) /* 12 */ #define TclpInetNtoa \ (tclIntPlatStubsPtr->tclpInetNtoa) /* 13 */ #define TclUnixCopyFile \ @@ -498,8 +504,10 @@ extern const TclIntPlatStubs *tclIntPlatStubsPtr; (tclIntPlatStubsPtr->tclpCreateTempFile) /* 9 */ #define TclpReaddir \ (tclIntPlatStubsPtr->tclpReaddir) /* 10 */ -/* Slot 11 is reserved */ -/* Slot 12 is reserved */ +#define TclpLocaltime_unix \ + (tclIntPlatStubsPtr->tclpLocaltime_unix) /* 11 */ +#define TclpGmtime_unix \ + (tclIntPlatStubsPtr->tclpGmtime_unix) /* 12 */ #define TclpInetNtoa \ (tclIntPlatStubsPtr->tclpInetNtoa) /* 13 */ #define TclUnixCopyFile \ diff --git a/generic/tclStubInit.c b/generic/tclStubInit.c index 9131c45..5b7a1cd 100644 --- a/generic/tclStubInit.c +++ b/generic/tclStubInit.c @@ -288,6 +288,10 @@ static int formatInt(char *buffer, int n){ #define TclFormatInt (int(*)(char *, long))formatInt #endif + +#else /* UNIX and MAC */ +# define TclpLocaltime_unix TclpLocaltime +# define TclpGmtime_unix TclpGmtime #endif /* @@ -437,7 +441,7 @@ static const TclIntStubs tclIntStubs = { Tcl_RemoveInterpResolvers, /* 130 */ Tcl_SetNamespaceResolvers, /* 131 */ TclpHasSockets, /* 132 */ - 0, /* 133 */ + TclpGetDate, /* 133 */ 0, /* 134 */ 0, /* 135 */ 0, /* 136 */ @@ -486,8 +490,8 @@ static const TclIntStubs tclIntStubs = { Tcl_GetStartupScript, /* 179 */ 0, /* 180 */ 0, /* 181 */ - 0, /* 182 */ - 0, /* 183 */ + TclpLocaltime, /* 182 */ + TclpGmtime, /* 183 */ 0, /* 184 */ 0, /* 185 */ 0, /* 186 */ @@ -573,8 +577,8 @@ static const TclIntPlatStubs tclIntPlatStubs = { TclUnixWaitForFile, /* 8 */ TclpCreateTempFile, /* 9 */ TclpReaddir, /* 10 */ - 0, /* 11 */ - 0, /* 12 */ + TclpLocaltime_unix, /* 11 */ + TclpGmtime_unix, /* 12 */ TclpInetNtoa, /* 13 */ TclUnixCopyFile, /* 14 */ 0, /* 15 */ @@ -639,8 +643,8 @@ static const TclIntPlatStubs tclIntPlatStubs = { TclUnixWaitForFile, /* 8 */ TclpCreateTempFile, /* 9 */ TclpReaddir, /* 10 */ - 0, /* 11 */ - 0, /* 12 */ + TclpLocaltime_unix, /* 11 */ + TclpGmtime_unix, /* 12 */ TclpInetNtoa, /* 13 */ TclUnixCopyFile, /* 14 */ TclMacOSXGetFileAttribute, /* 15 */ diff --git a/unix/tclUnixTime.c b/unix/tclUnixTime.c index 470b122..315bcf9 100644 --- a/unix/tclUnixTime.c +++ b/unix/tclUnixTime.c @@ -17,9 +17,34 @@ #endif /* + * TclpGetDate is coded to return a pointer to a 'struct tm'. For thread + * safety, this structure must be in thread-specific data. The 'tmKey' + * variable is the key to this buffer. + */ + +static Tcl_ThreadDataKey tmKey; +typedef struct ThreadSpecificData { + struct tm gmtime_buf; + struct tm localtime_buf; +} ThreadSpecificData; + +/* + * If we fall back on the thread-unsafe versions of gmtime and localtime, use + * this mutex to try to protect them. + */ + +TCL_DECLARE_MUTEX(tmMutex) + +static char *lastTZ = NULL; /* Holds the last setting of the TZ + * environment variable, or an empty string if + * the variable was not set. */ + +/* * Static functions declared in this file. */ +static void SetTZIfNecessary(void); +static void CleanupMemory(ClientData clientData); static void NativeScaleTime(Tcl_Time *timebuf, ClientData clientData); static void NativeGetTime(Tcl_Time *timebuf, @@ -223,6 +248,114 @@ Tcl_GetTime( /* *---------------------------------------------------------------------- * + * TclpGetDate -- + * + * This function converts between seconds and struct tm. If useGMT is + * true, then the returned date will be in Greenwich Mean Time (GMT). + * Otherwise, it will be in the local time zone. + * + * Results: + * Returns a static tm structure. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +struct tm * +TclpGetDate( + const time_t *time, + int useGMT) +{ + if (useGMT) { + return TclpGmtime(time); + } else { + return TclpLocaltime(time); + } +} + +/* + *---------------------------------------------------------------------- + * + * TclpGmtime -- + * + * Wrapper around the 'gmtime' library function to make it thread safe. + * + * Results: + * Returns a pointer to a 'struct tm' in thread-specific data. + * + * Side effects: + * Invokes gmtime or gmtime_r as appropriate. + * + *---------------------------------------------------------------------- + */ + +struct tm * +TclpGmtime( + const time_t *timePtr) /* Pointer to the number of seconds since the + * local system's epoch */ +{ + /* + * Get a thread-local buffer to hold the returned time. + */ + + ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&tmKey); + +#ifdef HAVE_GMTIME_R + gmtime_r(timePtr, &tsdPtr->gmtime_buf); +#else + Tcl_MutexLock(&tmMutex); + memcpy(&tsdPtr->gmtime_buf, gmtime(timePtr), sizeof(struct tm)); + Tcl_MutexUnlock(&tmMutex); +#endif + + return &tsdPtr->gmtime_buf; +} + +/* + *---------------------------------------------------------------------- + * + * TclpLocaltime -- + * + * Wrapper around the 'localtime' library function to make it thread + * safe. + * + * Results: + * Returns a pointer to a 'struct tm' in thread-specific data. + * + * Side effects: + * Invokes localtime or localtime_r as appropriate. + * + *---------------------------------------------------------------------- + */ + +struct tm * +TclpLocaltime( + const time_t *timePtr) /* Pointer to the number of seconds since the + * local system's epoch */ +{ + /* + * Get a thread-local buffer to hold the returned time. + */ + + ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&tmKey); + + SetTZIfNecessary(); +#ifdef HAVE_LOCALTIME_R + localtime_r(timePtr, &tsdPtr->localtime_buf); +#else + Tcl_MutexLock(&tmMutex); + memcpy(&tsdPtr->localtime_buf, localtime(timePtr), sizeof(struct tm)); + Tcl_MutexUnlock(&tmMutex); +#endif + + return &tsdPtr->localtime_buf; +} + +/* + *---------------------------------------------------------------------- + * * Tcl_SetTimeProc -- * * TIP #233 (Virtualized Time): Registers two handlers for the @@ -334,6 +467,70 @@ NativeGetTime( timePtr->sec = tv.tv_sec; timePtr->usec = tv.tv_usec; } +/* + *---------------------------------------------------------------------- + * + * SetTZIfNecessary -- + * + * Determines whether a call to 'tzset' is needed prior to the next call + * to 'localtime' or examination of the 'timezone' variable. + * + * Results: + * None. + * + * Side effects: + * If 'tzset' has never been called in the current process, or if the + * value of the environment variable TZ has changed since the last call + * to 'tzset', then 'tzset' is called again. + * + *---------------------------------------------------------------------- + */ + +static void +SetTZIfNecessary(void) +{ + const char *newTZ = getenv("TZ"); + + Tcl_MutexLock(&tmMutex); + if (newTZ == NULL) { + newTZ = ""; + } + if (lastTZ == NULL || strcmp(lastTZ, newTZ)) { + tzset(); + if (lastTZ == NULL) { + Tcl_CreateExitHandler(CleanupMemory, NULL); + } else { + ckfree(lastTZ); + } + lastTZ = ckalloc(strlen(newTZ) + 1); + strcpy(lastTZ, newTZ); + } + Tcl_MutexUnlock(&tmMutex); +} + +/* + *---------------------------------------------------------------------- + * + * CleanupMemory -- + * + * Releases the private copy of the TZ environment variable upon exit + * from Tcl. + * + * Results: + * None. + * + * Side effects: + * Frees allocated memory. + * + *---------------------------------------------------------------------- + */ + +static void +CleanupMemory( + ClientData ignored) +{ + ckfree(lastTZ); +} /* * Local Variables: diff --git a/win/tclWinTime.c b/win/tclWinTime.c index 0762362..7045c72 100644 --- a/win/tclWinTime.c +++ b/win/tclWinTime.c @@ -12,6 +12,10 @@ #include "tclInt.h" +#define SECSPERDAY (60L * 60L * 24L) +#define SECSPERYEAR (SECSPERDAY * 365L) +#define SECSPER4YEAR (SECSPERYEAR * 4L + SECSPERDAY) + /* * Number of samples over which to estimate the performance counter. */ @@ -19,10 +23,29 @@ #define SAMPLES 64 /* + * The following arrays contain the day of year for the last day of each + * month, where index 1 is January. + */ + +static const int normalDays[] = { + -1, 30, 58, 89, 119, 150, 180, 211, 242, 272, 303, 333, 364 +}; + +static const int leapDays[] = { + -1, 30, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 +}; + +typedef struct ThreadSpecificData { + char tzName[64]; /* Time zone name */ + struct tm tm; /* time information */ +} ThreadSpecificData; +static Tcl_ThreadDataKey dataKey; + +/* * Data for managing high-resolution timers. */ -typedef struct { +typedef struct TimeInfo { CRITICAL_SECTION cs; /* Mutex guarding this structure. */ int initialized; /* Flag == 1 if this structure is * initialized. */ @@ -90,6 +113,7 @@ static TimeInfo timeInfo = { * Declarations for functions defined later in this file. */ +static struct tm * ComputeGMT(const time_t *tp); static void StopCalibration(ClientData clientData); static DWORD WINAPI CalibrationThread(LPVOID arg); static void UpdateTimeEachSecond(void); @@ -465,6 +489,227 @@ StopCalibration( /* *---------------------------------------------------------------------- * + * TclpGetDate -- + * + * This function converts between seconds and struct tm. If useGMT is + * true, then the returned date will be in Greenwich Mean Time (GMT). + * Otherwise, it will be in the local time zone. + * + * Results: + * Returns a static tm structure. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +struct tm * +TclpGetDate( + const time_t *t, + int useGMT) +{ + struct tm *tmPtr; + time_t time; + + if (!useGMT) { + tzset(); + + /* + * If we are in the valid range, let the C run-time library handle it. + * Otherwise we need to fake it. Note that this algorithm ignores + * daylight savings time before the epoch. + */ + + /* + * Hm, Borland's localtime manages to return NULL under certain + * circumstances (e.g. wintime.test, test 1.2). Nobody tests for this, + * since 'localtime' isn't supposed to do this, possibly leading to + * crashes. + * + * Patch: We only call this function if we are at least one day into + * the epoch, else we handle it ourselves (like we do for times < 0). + * H. Giese, June 2003 + */ + +#ifdef __BORLANDC__ +#define LOCALTIME_VALIDITY_BOUNDARY SECSPERDAY +#else +#define LOCALTIME_VALIDITY_BOUNDARY 0 +#endif + + if (*t >= LOCALTIME_VALIDITY_BOUNDARY) { + return TclpLocaltime(t); + } + + time = *t - timezone; + + /* + * If we aren't near to overflowing the long, just add the bias and + * use the normal calculation. Otherwise we will need to adjust the + * result at the end. + */ + + if (*t < (LONG_MAX - 2*SECSPERDAY) && *t > (LONG_MIN + 2*SECSPERDAY)) { + tmPtr = ComputeGMT(&time); + } else { + tmPtr = ComputeGMT(t); + + tzset(); + + /* + * Add the bias directly to the tm structure to avoid overflow. + * Propagate seconds overflow into minutes, hours and days. + */ + + time = tmPtr->tm_sec - timezone; + tmPtr->tm_sec = (int)(time % 60); + if (tmPtr->tm_sec < 0) { + tmPtr->tm_sec += 60; + time -= 60; + } + + time = tmPtr->tm_min + time/60; + tmPtr->tm_min = (int)(time % 60); + if (tmPtr->tm_min < 0) { + tmPtr->tm_min += 60; + time -= 60; + } + + time = tmPtr->tm_hour + time/60; + tmPtr->tm_hour = (int)(time % 24); + if (tmPtr->tm_hour < 0) { + tmPtr->tm_hour += 24; + time -= 24; + } + + time /= 24; + tmPtr->tm_mday += (int)time; + tmPtr->tm_yday += (int)time; + tmPtr->tm_wday = (tmPtr->tm_wday + (int)time) % 7; + } + } else { + tmPtr = ComputeGMT(t); + } + return tmPtr; +} + +/* + *---------------------------------------------------------------------- + * + * ComputeGMT -- + * + * This function computes GMT given the number of seconds since the epoch + * (midnight Jan 1 1970). + * + * Results: + * Returns a (per thread) statically allocated struct tm. + * + * Side effects: + * Updates the values of the static struct tm. + * + *---------------------------------------------------------------------- + */ + +static struct tm * +ComputeGMT( + const time_t *tp) +{ + struct tm *tmPtr; + long tmp, rem; + int isLeap; + const int *days; + ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); + + tmPtr = &tsdPtr->tm; + + /* + * Compute the 4 year span containing the specified time. + */ + + tmp = (long)(*tp / SECSPER4YEAR); + rem = (long)(*tp % SECSPER4YEAR); + + /* + * Correct for weird mod semantics so the remainder is always positive. + */ + + if (rem < 0) { + tmp--; + rem += SECSPER4YEAR; + } + + /* + * Compute the year after 1900 by taking the 4 year span and adjusting for + * the remainder. This works because 2000 is a leap year, and 1900/2100 + * are out of the range. + */ + + tmp = (tmp * 4) + 70; + isLeap = 0; + if (rem >= SECSPERYEAR) { /* 1971, etc. */ + tmp++; + rem -= SECSPERYEAR; + if (rem >= SECSPERYEAR) { /* 1972, etc. */ + tmp++; + rem -= SECSPERYEAR; + if (rem >= SECSPERYEAR + SECSPERDAY) { /* 1973, etc. */ + tmp++; + rem -= SECSPERYEAR + SECSPERDAY; + } else { + isLeap = 1; + } + } + } + tmPtr->tm_year = tmp; + + /* + * Compute the day of year and leave the seconds in the current day in the + * remainder. + */ + + tmPtr->tm_yday = rem / SECSPERDAY; + rem %= SECSPERDAY; + + /* + * Compute the time of day. + */ + + tmPtr->tm_hour = rem / 3600; + rem %= 3600; + tmPtr->tm_min = rem / 60; + tmPtr->tm_sec = rem % 60; + + /* + * Compute the month and day of month. + */ + + days = (isLeap) ? leapDays : normalDays; + for (tmp = 1; days[tmp] < tmPtr->tm_yday; tmp++) { + /* empty body */ + } + tmPtr->tm_mon = --tmp; + tmPtr->tm_mday = tmPtr->tm_yday - days[tmp]; + + /* + * Compute day of week. Epoch started on a Thursday. + */ + + tmPtr->tm_wday = (long)(*tp / SECSPERDAY) + 4; + if ((*tp % SECSPERDAY) < 0) { + tmPtr->tm_wday--; + } + tmPtr->tm_wday %= 7; + if (tmPtr->tm_wday < 0) { + tmPtr->tm_wday += 7; + } + + return tmPtr; +} + +/* + *---------------------------------------------------------------------- + * * CalibrationThread -- * * Thread that manages calibration of the hi-resolution time derived from @@ -792,6 +1037,67 @@ AccumulateSample( /* *---------------------------------------------------------------------- * + * TclpGmtime -- + * + * Wrapper around the 'gmtime' library function to make it thread safe. + * + * Results: + * Returns a pointer to a 'struct tm' in thread-specific data. + * + * Side effects: + * Invokes gmtime or gmtime_r as appropriate. + * + *---------------------------------------------------------------------- + */ + +struct tm * +TclpGmtime( + const time_t *timePtr) /* Pointer to the number of seconds since the + * local system's epoch */ +{ + /* + * The MS implementation of gmtime is thread safe because it returns the + * time in a block of thread-local storage, and Windows does not provide a + * Posix gmtime_r function. + */ + + return gmtime(timePtr); +} + +/* + *---------------------------------------------------------------------- + * + * TclpLocaltime -- + * + * Wrapper around the 'localtime' library function to make it thread + * safe. + * + * Results: + * Returns a pointer to a 'struct tm' in thread-specific data. + * + * Side effects: + * Invokes localtime or localtime_r as appropriate. + * + *---------------------------------------------------------------------- + */ + +struct tm * +TclpLocaltime( + const time_t *timePtr) /* Pointer to the number of seconds since the + * local system's epoch */ +{ + /* + * The MS implementation of localtime is thread safe because it returns + * the time in a block of thread-local storage, and Windows does not + * provide a Posix localtime_r function. + */ + + return localtime(timePtr); +} + +/* + *---------------------------------------------------------------------- + * * Tcl_SetTimeProc -- * * TIP #233 (Virtualized Time): Registers two handlers for the -- cgit v0.12 From cb73551e8dda297b93eecea5b526196ef7589c86 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Mon, 21 Dec 2015 09:31:36 +0000 Subject: Start of "zipfs" branch, meant for keeping track of the proposed changes for a new TIP. Remove some android-specific build/configure files. --- Android.mk | 204 --------------------------------------------- debian/changelog | 23 ----- debian/compat | 1 - debian/control | 37 -------- debian/copyright | 141 ------------------------------- debian/rules | 130 ----------------------------- debian/sdltcl8.6-dev.dirs | 2 - debian/sdltcl8.6-dev.files | 2 - debian/sdltcl8.6-doc.files | 2 - debian/sdltcl8.6.files | 18 ---- debian/shlibs.local | 1 - pkgs/Android.mk | 1 - tcl-config.mk | 62 -------------- 13 files changed, 624 deletions(-) delete mode 100644 Android.mk delete mode 100644 debian/changelog delete mode 100644 debian/compat delete mode 100644 debian/control delete mode 100644 debian/copyright delete mode 100755 debian/rules delete mode 100644 debian/sdltcl8.6-dev.dirs delete mode 100644 debian/sdltcl8.6-dev.files delete mode 100644 debian/sdltcl8.6-doc.files delete mode 100644 debian/sdltcl8.6.files delete mode 100644 debian/shlibs.local delete mode 100644 pkgs/Android.mk delete mode 100644 tcl-config.mk diff --git a/Android.mk b/Android.mk deleted file mode 100644 index 13e55d9..0000000 --- a/Android.mk +++ /dev/null @@ -1,204 +0,0 @@ -LOCAL_PATH := $(call my-dir) - -########################### -# -# Tcl shared library -# -########################### - -include $(CLEAR_VARS) - -tcl_path := $(LOCAL_PATH) - -include $(tcl_path)/tcl-config.mk - -LOCAL_ADDITIONAL_DEPENDENCIES += $(tcl_path)/tcl-config.mk - -LOCAL_MODULE := tcl - -LOCAL_ARM_MODE := arm - -LOCAL_C_INCLUDES := $(tcl_includes) $(LOCAL_PATH)/libtommath - -LOCAL_EXPORT_C_INCLUDES := $(LOCAL_C_INCLUDES) - -LOCAL_SRC_FILES := \ - libtommath/bncore.c \ - libtommath/bn_reverse.c \ - libtommath/bn_fast_s_mp_mul_digs.c \ - libtommath/bn_fast_s_mp_sqr.c \ - libtommath/bn_mp_add.c \ - libtommath/bn_mp_add_d.c \ - libtommath/bn_mp_and.c \ - libtommath/bn_mp_clamp.c \ - libtommath/bn_mp_clear.c \ - libtommath/bn_mp_clear_multi.c \ - libtommath/bn_mp_cmp.c \ - libtommath/bn_mp_cmp_d.c \ - libtommath/bn_mp_cmp_mag.c \ - libtommath/bn_mp_copy.c \ - libtommath/bn_mp_cnt_lsb.c \ - libtommath/bn_mp_count_bits.c \ - libtommath/bn_mp_div.c \ - libtommath/bn_mp_div_d.c \ - libtommath/bn_mp_div_2.c \ - libtommath/bn_mp_div_2d.c \ - libtommath/bn_mp_div_3.c \ - libtommath/bn_mp_exch.c \ - libtommath/bn_mp_expt_d.c \ - libtommath/bn_mp_grow.c \ - libtommath/bn_mp_init.c \ - libtommath/bn_mp_init_copy.c \ - libtommath/bn_mp_init_multi.c \ - libtommath/bn_mp_init_set.c \ - libtommath/bn_mp_init_set_int.c \ - libtommath/bn_mp_init_size.c \ - libtommath/bn_mp_karatsuba_mul.c \ - libtommath/bn_mp_karatsuba_sqr.c \ - libtommath/bn_mp_lshd.c \ - libtommath/bn_mp_mod.c \ - libtommath/bn_mp_mod_2d.c \ - libtommath/bn_mp_mul.c \ - libtommath/bn_mp_mul_2.c \ - libtommath/bn_mp_mul_2d.c \ - libtommath/bn_mp_mul_d.c \ - libtommath/bn_mp_neg.c \ - libtommath/bn_mp_or.c \ - libtommath/bn_mp_radix_size.c \ - libtommath/bn_mp_radix_smap.c \ - libtommath/bn_mp_read_radix.c \ - libtommath/bn_mp_rshd.c \ - libtommath/bn_mp_set.c \ - libtommath/bn_mp_set_int.c \ - libtommath/bn_mp_shrink.c \ - libtommath/bn_mp_sqr.c \ - libtommath/bn_mp_sqrt.c \ - libtommath/bn_mp_sub.c \ - libtommath/bn_mp_sub_d.c \ - libtommath/bn_mp_to_unsigned_bin.c \ - libtommath/bn_mp_to_unsigned_bin_n.c \ - libtommath/bn_mp_toom_mul.c \ - libtommath/bn_mp_toom_sqr.c \ - libtommath/bn_mp_toradix_n.c \ - libtommath/bn_mp_unsigned_bin_size.c \ - libtommath/bn_mp_xor.c \ - libtommath/bn_mp_zero.c \ - libtommath/bn_s_mp_add.c \ - libtommath/bn_s_mp_mul_digs.c \ - libtommath/bn_s_mp_sqr.c \ - libtommath/bn_s_mp_sub.c \ - generic/regcomp.c \ - generic/regexec.c \ - generic/regfree.c \ - generic/regerror.c \ - generic/tclAlloc.c \ - generic/tclAssembly.c \ - generic/tclAsync.c \ - generic/tclBasic.c \ - generic/tclBinary.c \ - generic/tclCkalloc.c \ - generic/tclClock.c \ - generic/tclCmdAH.c \ - generic/tclCmdIL.c \ - generic/tclCmdMZ.c \ - generic/tclCompCmds.c \ - generic/tclCompCmdsGR.c \ - generic/tclCompCmdsSZ.c \ - generic/tclCompExpr.c \ - generic/tclCompile.c \ - generic/tclConfig.c \ - generic/tclDate.c \ - generic/tclDictObj.c \ - generic/tclDisassemble.c \ - generic/tclEncoding.c \ - generic/tclEnsemble.c \ - generic/tclEnv.c \ - generic/tclEvent.c \ - generic/tclExecute.c \ - generic/tclFCmd.c \ - generic/tclFileName.c \ - generic/tclGet.c \ - generic/tclHash.c \ - generic/tclHistory.c \ - generic/tclIndexObj.c \ - generic/tclInterp.c \ - generic/tclIO.c \ - generic/tclIOCmd.c \ - generic/tclIOGT.c \ - generic/tclIOSock.c \ - generic/tclIOUtil.c \ - generic/tclIORChan.c \ - generic/tclIORTrans.c \ - generic/tclLink.c \ - generic/tclListObj.c \ - generic/tclLiteral.c \ - generic/tclLoad.c \ - generic/tclMain.c \ - generic/tclNamesp.c \ - generic/tclNotify.c \ - generic/tclObj.c \ - generic/tclOptimize.c \ - generic/tclPanic.c \ - generic/tclParse.c \ - generic/tclPathObj.c \ - generic/tclPipe.c \ - generic/tclPkg.c \ - generic/tclPkgConfig.c \ - generic/tclPosixStr.c \ - generic/tclPreserve.c \ - generic/tclProc.c \ - generic/tclRegexp.c \ - generic/tclResolve.c \ - generic/tclResult.c \ - generic/tclScan.c \ - generic/tclStubInit.c \ - generic/tclStringObj.c \ - generic/tclStrToD.c \ - generic/tclThread.c \ - generic/tclThreadAlloc.c \ - generic/tclThreadJoin.c \ - generic/tclThreadStorage.c \ - generic/tclTimer.c \ - generic/tclTomMathInterface.c \ - generic/tclTrace.c \ - generic/tclUtil.c \ - generic/tclUtf.c \ - generic/tclVar.c \ - generic/tclZlib.c \ - generic/tclOO.c \ - generic/tclOOBasic.c \ - generic/tclOOCall.c \ - generic/tclOODefineCmds.c \ - generic/tclOOInfo.c \ - generic/tclOOMethod.c \ - generic/tclOOStubInit.c \ - generic/tclStubLib.c \ - generic/tclTomMathStubLib.c \ - generic/tclOOStubLib.c \ - generic/zipfs.c \ - unix/tclAppInit.c \ - unix/tclLoadDl.c \ - unix/tclUnixChan.c \ - unix/tclUnixCompat.c \ - unix/tclUnixEvent.c \ - unix/tclUnixFCmd.c \ - unix/tclUnixFile.c \ - unix/tclUnixInit.c \ - unix/tclUnixNotfy.c \ - unix/tclUnixPipe.c \ - unix/tclUnixSock.c \ - unix/tclUnixTest.c \ - unix/tclUnixThrd.c \ - unix/tclUnixTime.c - -LOCAL_CFLAGS := $(tcl_cflags) \ - -DPACKAGE_NAME="\"tcl\"" \ - -DPACKAGE_VERSION="\"8.6\"" \ - -DBUILD_tcl=1 \ - -Dmain=tclsh \ - -O2 - -LOCAL_LDLIBS := -ldl -lz -llog - -include $(BUILD_SHARED_LIBRARY) - diff --git a/debian/changelog b/debian/changelog deleted file mode 100644 index caad3ba..0000000 --- a/debian/changelog +++ /dev/null @@ -1,23 +0,0 @@ -sdltcl8.6 (8.6.4-1) unstable; urgency=low - - * Update to 8.6.4 - - -- Christian Werner Thu, 12 Mar 2015 22:00:00 +0100 - -sdltcl8.6 (8.6.3-1) unstable; urgency=low - - * Update to 8.6.3 - - -- Christian Werner Wed, 12 Nov 2014 20:00:00 +0100 - -sdltcl8.6 (8.6.2-1) unstable; urgency=low - - * Update to 8.6.2 - - -- Christian Werner Thu, 28 Aug 2014 07:10:10 +0200 - -sdltcl8.6 (8.6.1-1) unstable; urgency=low - - * Initial packaging - - -- Christian Werner Sat, 05 Apr 2014 14:44:48 +0200 diff --git a/debian/compat b/debian/compat deleted file mode 100644 index 7ed6ff8..0000000 --- a/debian/compat +++ /dev/null @@ -1 +0,0 @@ -5 diff --git a/debian/control b/debian/control deleted file mode 100644 index 3434297..0000000 --- a/debian/control +++ /dev/null @@ -1,37 +0,0 @@ -Source: sdltcl8.6 -Section: libs -Priority: optional -Maintainer: -Build-Depends: debhelper (>= 5.0.0), quilt -Standards-Version: 3.8.3 -Homepage: http://www.tcl.tk/ - -Package: sdltcl8.6 -Section: interpreters -Priority: optional -Architecture: any -Depends: ${shlibs:Depends} -Description: Tcl (the Tool Command Language) v8.6 - run-time files - Tcl is a powerful, easy to use, embeddable, cross-platform interpreted - scripting language. This package contains everything you need to run - Tcl scripts and Tcl-enabled apps. This version includes thread support. - -Package: sdltcl8.6-doc -Section: doc -Priority: optional -Architecture: all -Suggests: sdltcl8.6 -Description: Tcl (the Tool Command Language) v8.6 - manual pages - Tcl is a powerful, easy-to-use, embeddable, cross-platform interpreted - scripting language. This package contains the man pages for Tcl commands. - -Package: sdltcl8.6-dev -Section: devel -Priority: optional -Architecture: any -Depends: sdltcl8.6 (= ${binary:Version}) -Suggests: sdltcl8.6-doc -Description: Tcl (the Tool Command Language) v8.6 - development files - Tcl is a powerful, easy-to-use, embeddable, cross-platform interpreted - scripting language. This package contains the headers and libraries - needed to embed or extend Tcl. diff --git a/debian/copyright b/debian/copyright deleted file mode 100644 index 075c312..0000000 --- a/debian/copyright +++ /dev/null @@ -1,141 +0,0 @@ -This package was originally debianized by David Engel -from sources obtained at http://prdownloads.sourceforge.net/tcl - -List of copyright holders mentioned in individual files: - -Copyright 1983, 1988-1994 The Regents of the University of California -Copyright 1991-1999 Karl Lehenbauer and Mark Diekhans -Copyright 1992-1996 Free Software Foundation, Inc. -Copyright 1993-1994 Lockheed Missle & Space Company, AI Center -Copyright 1993-1997 Bell Labs Innovations for Lucent Technologies -Copyright 1993-1997 Lucent Technologies -Copyright 1994-1998 Sun Microsystems, Inc. -Copyright 1995 General Electric Company -Copyright 1995 Dave Nebinger -Copyright 1995-1997 Roger E. Critchlow Jr -Copyright 1996 Lucent Technologies and Jim Ingham -Copyright 1997-2000 Ajuba Solutions -Copyright 1998-2000 Scriptics Corporation -Copyright 1998-1999 Henry Spencer -Copyright 1998 Paul Duffin -Copyright 1998 Mark Harrison -Copyright 1999 America Online, Inc. -Copyright 1999-2000 Andreas Kupries -Copyright 2000-2001 ActiveState Corporation, et al -Copyright 2001 ActiveState Tool Corp. -Copyright 2001-2002 Apple Computer, Inc. -Copyright 2001-2002 ActiveState Corporation -Copyright 2001-2002 Vincent Darley -Copyright 2001-2002 Donal K. Fellows -Copyright 2001-2003 Kevin B. Kenny -Copyright 2001-2002 David Gravereaux -Contributions from Don Porter, NIST, 2002-2003. (not subject to US copyright) -Copyright 2005 Tcl Core Team -Copyright 2005 Daniel A. Steffen - -Copyright: - -This software is copyrighted by the Regents of the University of -California, Sun Microsystems, Inc., Scriptics Corporation, -and other parties. The following terms apply to all files associated -with the software unless explicitly disclaimed in individual files. - -The authors hereby grant permission to use, copy, modify, distribute, -and license this software and its documentation for any purpose, provided -that existing copyright notices are retained in all copies and that this -notice is included verbatim in any distributions. No written agreement, -license, or royalty fee is required for any of the authorized uses. -Modifications to this software may be copyrighted by their authors -and need not follow the licensing terms described here, provided that -the new terms are clearly indicated on the first page of each file where -they apply. - -IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY -FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES -ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY -DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - -THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE -IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE -NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR -MODIFICATIONS. - -GOVERNMENT USE: If you are acquiring this software on behalf of the -U.S. government, the Government shall have only "Restricted Rights" -in the software and related documentation as defined in the Federal -Acquisition Regulations (FARs) in Clause 52.227.19 (c) (2). If you -are acquiring the software on behalf of the Department of Defense, the -software shall be classified as "Commercial Computer Software" and the -Government shall have only "Restricted Rights" as defined in Clause -252.227-7013 (c) (1) of DFARs. Notwithstanding the foregoing, the -authors grant the U.S. Government and others acting in its behalf -permission to use and distribute the software in accordance with the -terms specified in this license. - -Several files are distributed under other conditions: - -compat/strftime.c: -/* - * strftime.c -- - * - * This file contains a modified version of the BSD 4.4 strftime - * function. - * - * This file is a modified version of the strftime.c file from the BSD 4.4 - * source. See the copyright notice below for details on redistribution - * restrictions. The "license.terms" file does not apply to this file. - * - * Changes 2002 Copyright (c) 2002 ActiveState Corporation. - * - * RCS: @(#) $Id: strftime.c,v 1.10.2.3 2005/11/04 18:18:04 kennykb Exp $ - */ - -/* - * Copyright (c) 1989 The Regents of the University of California. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -compat/dlfcn.h and unix/tclLoadAix.c: - * This file is subject to the following copyright notice, which is - * different from the notice used elsewhere in Tcl but rougly - * equivalent in meaning. - * - * Copyright (c) 1992,1993,1995,1996, Jens-Uwe Mager, Helios Software GmbH - * Not derived from licensed software. - * - * Permission is granted to freely use, copy, modify, and redistribute - * this software, provided that the author is not construed to be liable - * for any results of using the software, alterations are clearly marked - * as such, and this notice is not modified. - diff --git a/debian/rules b/debian/rules deleted file mode 100755 index a4b3bd4..0000000 --- a/debian/rules +++ /dev/null @@ -1,130 +0,0 @@ -#!/usr/bin/make -f -# debian/rules that uses debhelper. - -# Uncomment this to turn on verbose mode. -#export DH_VERBOSE=1 - -DEB_HOST_GNU_TYPE := $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE) -DEB_BUILD_GNU_TYPE := $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE) - -export QUILT_PATCHES := debian/patches - -v = 8.6 - -ifneq (,$(findstring debug,$(DEB_BUILD_OPTIONS))) -CFLAGS=-g -O0 -else -# See bug #446335 -CFLAGS=-g -O2 -fno-unit-at-a-time -endif - -unpatch: - dh_testdir - quilt pop -a || test $$? = 2 - rm -rf patch-stamp .pc - -patch: patch-stamp -patch-stamp: - dh_testdir - quilt push -a || test $$? = 2 - touch patch-stamp - -build: build-stamp -build-stamp: patch-stamp - dh_testdir -# So so ugly but it works... - touch generic/tclStubInit.c - cd unix && \ - CFLAGS="$(CFLAGS)" \ - ac_cv_func_strtod=yes \ - tcl_cv_strtod_buggy=1 \ - ./configure --host=$(DEB_HOST_GNU_TYPE) \ - --build=$(DEB_BUILD_GNU_TYPE) \ - --prefix=/opt/sdltk86 \ - --includedir=/opt/sdltk86/include \ - --enable-shared \ - --mandir=/opt/sdltk86/man \ - --enable-man-symlinks \ - --enable-man-compression=gzip \ - --enable-threads \ - --without-tzdata \ - --with-zipfs && \ - touch ../generic/tclStubInit.c && \ - $(MAKE) -# Build the static library. - cd unix && \ - ar cr libtcl$(v).a *.o && \ - ar d libtcl$(v).a tclAppInit.o && \ - ranlib libtcl$(v).a - touch build-stamp - -clean: clean-patched unpatch - dh_testdir - dh_testroot - dh_clean - -clean-patched: - dh_testdir - dh_testroot - rm -f build-stamp install-stamp - cd unix && [ ! -f Makefile ] || $(MAKE) distclean -# Remove forgotten files - rm -f tests/pkg/pkga.so unix/config.log unix/Tcltest.so - -install: install-stamp -install-stamp: build-stamp - dh_testdir - dh_testroot - dh_clean -k - dh_installdirs - cd unix && \ - GZIP=-9 \ - $(MAKE) INSTALL_ROOT=`pwd`/../debian/tmp \ - MAN_INSTALL_DIR=`pwd`/../debian/tmp/opt/sdltk86/man \ - install install-private-headers install-packages -# Fix up the libraries. - cp unix/libtcl$(v).a debian/tmp/opt/sdltk86/lib - touch install-stamp - -# Build architecture-independent files here. -binary-indep: build install - dh_testdir -i - dh_testroot -i - dh_movefiles -i - dh_installdocs -i - dh_installchangelogs -i ChangeLog - dh_compress -i - dh_fixperms -i - dh_installdeb -i - dh_gencontrol -i - dh_md5sums -i - dh_builddeb -i - -# Build architecture-dependent files here. -binary-arch: build install - dh_testdir -a - dh_testroot -a - dh_movefiles -a -# now, fix up file locations for .sh - mv debian/sdltcl$(v)/opt/sdltk86/lib/tclConfig.sh \ - debian/sdltcl$(v)-dev/opt/sdltk86/lib - dh_installdocs -a - dh_installmenu -a - dh_installchangelogs -a ChangeLog - dh_fixperms -a - dh_strip -a - dh_compress -a - dh_makeshlibs -a -V 'sdltcl$(v) (>= 8.6.2)' -XTcltest - dh_installdeb -a - dh_shlibdeps -a -ldebian/sdltcl$(v)/opt/sdltk86/lib - dh_gencontrol -a - dh_md5sums -a - dh_builddeb -a - -source diff: - @echo >&2 'source and diff are obsolete - use dpkg-source -b'; false - -binary: binary-indep binary-arch - -.PHONY: patch unpatch clean-patched build clean binary-indep binary-arch binary install - diff --git a/debian/sdltcl8.6-dev.dirs b/debian/sdltcl8.6-dev.dirs deleted file mode 100644 index 4de4819..0000000 --- a/debian/sdltcl8.6-dev.dirs +++ /dev/null @@ -1,2 +0,0 @@ -opt/sdltk86/lib -opt/sdltk86/include diff --git a/debian/sdltcl8.6-dev.files b/debian/sdltcl8.6-dev.files deleted file mode 100644 index 5cd0878..0000000 --- a/debian/sdltcl8.6-dev.files +++ /dev/null @@ -1,2 +0,0 @@ -opt/sdltk86/include -opt/sdltk86/lib/*.a diff --git a/debian/sdltcl8.6-doc.files b/debian/sdltcl8.6-doc.files deleted file mode 100644 index 56ca7e7..0000000 --- a/debian/sdltcl8.6-doc.files +++ /dev/null @@ -1,2 +0,0 @@ -opt/sdltk86/man/man3 -opt/sdltk86/man/mann diff --git a/debian/sdltcl8.6.files b/debian/sdltcl8.6.files deleted file mode 100644 index 501d10a..0000000 --- a/debian/sdltcl8.6.files +++ /dev/null @@ -1,18 +0,0 @@ -opt/sdltk86/bin -opt/sdltk86/lib/tcl8 -opt/sdltk86/lib/tcl8/* -opt/sdltk86/lib/tcl8.6 -opt/sdltk86/lib/tcl8.6/* -opt/sdltk86/lib/*.so -opt/sdltk86/lib/*.sh -opt/sdltk86/lib/itcl* -opt/sdltk86/lib/itcl*/* -opt/sdltk86/lib/pkgconfig -opt/sdltk86/lib/pkgconfig/* -opt/sdltk86/lib/sqlite* -opt/sdltk86/lib/sqlite*/* -opt/sdltk86/lib/tdbc* -opt/sdltk86/lib/tdbc*/* -opt/sdltk86/lib/thread* -opt/sdltk86/lib/thread*/* -opt/sdltk86/man/man1 diff --git a/debian/shlibs.local b/debian/shlibs.local deleted file mode 100644 index 7da5dd4..0000000 --- a/debian/shlibs.local +++ /dev/null @@ -1 +0,0 @@ -libtcl8.6 1 diff --git a/pkgs/Android.mk b/pkgs/Android.mk deleted file mode 100644 index 5053e7d..0000000 --- a/pkgs/Android.mk +++ /dev/null @@ -1 +0,0 @@ -include $(call all-subdir-makefiles) diff --git a/tcl-config.mk b/tcl-config.mk deleted file mode 100644 index e072516..0000000 --- a/tcl-config.mk +++ /dev/null @@ -1,62 +0,0 @@ -tcl_includes := $(tcl_path)/generic $(tcl_path)/unix - -tcl_cflags := \ - -DHAVE_SYS_SELECT_H=1 \ - -DHAVE_LIMITS_H=1 \ - -DHAVE_UNISTD_H=1 \ - -DHAVE_SYS_PARAM_H=1 \ - -D_LARGEFILE64_SOURCE=1 \ - -DTCL_WIDE_INT_TYPE="long long" \ - -DTCL_SHLIB_EXT="\".so\"" \ - -DHAVE_CAST_TO_UNION=1 \ - -DHAVE_GETCWD=1 \ - -DHAVE_OPENDIR=1 \ - -DHAVE_MKSTEMP=1 \ - -DHAVE_MKSTEMPS=1 \ - -DHAVE_STRSTR=1 \ - -DHAVE_STRTOL=1 \ - -DHAVE_STRTOLL=1 \ - -DHAVE_STRTOULL=1 \ - -DHAVE_TMPNAM=1 \ - -DHAVE_WAITPID=1 \ - -DHAVE_STRUCT_ADDRINFO=1 \ - -DHAVE_STRUCT_IN6_ADDR=1 \ - -DHAVE_STRUCT_SOCKADDR_IN6=1 \ - -DHAVE_STRUCT_SOCKADDR_STORAGE=1 \ - -DHAVE_GETHOSTBYNAME_R=1 \ - -DUSE_TERMIOS=1 \ - -DHAVE_MKTIME=1 \ - -DUSE_INTERP_ERRORLINE=1 \ - -DHAVE_SYS_TIME_H=1 \ - -DTIME_WITH_SYS_TIME=1 \ - -DHAVE_TM_ZONE=1 \ - -DHAVE_GMTIME_R=1 \ - -DHAVE_LOCALTIME_R=1 \ - -DHAVE_TM_GMTOFF=1 \ - -DHAVE_TIMEZONE_VAR=1 \ - -DHAVE_ST_BLKSIZE=1 \ - -DSTDC_HEADERS=1 \ - -DHAVE_INTPTR_T=1 \ - -DHAVE_UINTPTR_T=1 \ - -DHAVE_SIGNED_CHAR=1 \ - -DHAVE_SYS_IOCTL_H=1 \ - -DHAVE_MEMCPY=1 \ - -DHAVE_MEMMOVE=1 \ - -DVOID=void \ - -DNO_UNION_WAIT=1 \ - -DHAVE_ZLIB=1 \ - -DMP_PREC=4 \ - -DTCL_TOMMATH=1 \ - -D_REENTRANT=1 \ - -D_THREADSAFE=1 \ - -DTCL_UTF_MAX=6 \ - -DTCL_THREADS=1 \ - -DTCL_PTHREAD_ATFORK=1 \ - -DUSE_THREAD_ALLOC=1 \ - -DTCL_CFGVAL_ENCODING="\"utf-8\"" \ - -DTCL_UNLOAD_DLLS=1 \ - -DTCL_CFG_OPTIMIZED=1 \ - -DZIPFS_IN_TCL=1 \ - -DTCL_PACKAGE_PATH="\"/assets\"" \ - -DTCL_LIBRARY="\"/assets/tcl8.6\"" - -- cgit v0.12 From b0a98f480d3a16432d023ddb8cb4ba8e22edd973 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Mon, 21 Dec 2015 10:03:06 +0000 Subject: Undo more Android-specific changes, which don't form part of Zipfs, as further preparation for Zipfs TIP. Rename zipfs.h to tclZipfs.h, so it can be installed together with tcl.h --- generic/tclIOUtil.c | 2 +- generic/tclMain.c | 197 ---------------------------------------------------- generic/tclZipfs.h | 65 +++++++++++++++++ generic/zipfs.c | 6 +- generic/zipfs.h | 66 ------------------ unix/Makefile.in | 4 +- unix/configure | 18 ----- unix/configure.in | 8 --- unix/tclUnixInit.c | 8 --- win/Makefile.in | 1 + win/configure | 19 ----- win/configure.in | 8 --- win/makefile.vc | 1 + 13 files changed, 75 insertions(+), 328 deletions(-) create mode 100644 generic/tclZipfs.h delete mode 100644 generic/zipfs.h diff --git a/generic/tclIOUtil.c b/generic/tclIOUtil.c index 9bc868b..0ef6d3b 100644 --- a/generic/tclIOUtil.c +++ b/generic/tclIOUtil.c @@ -192,7 +192,7 @@ const Tcl_Filesystem tclNativeFilesystem = { }; #ifdef ZIPFS_IN_TCL -extern Tcl_Filesystem zipfsFilesystem; +MODULE_SCOPE Tcl_Filesystem zipfsFilesystem; #endif /* diff --git a/generic/tclMain.c b/generic/tclMain.c index 6acd15d..927de7e 100644 --- a/generic/tclMain.c +++ b/generic/tclMain.c @@ -34,15 +34,6 @@ #include "tclInt.h" -#ifdef ZIPFS_IN_TCL -#include "zipfs.h" -#endif - -#ifdef ANDROID -#undef ZIPFS_BOOTDIR -#define ZIPFS_BOOTDIR "/assets" -#endif - /* * The default prompt used when the user has not overridden it. */ @@ -60,7 +51,6 @@ # define TCHAR char # define TEXT(arg) arg # define _tcscmp strcmp -# define _tcsncmp strncmp #endif /* @@ -325,21 +315,9 @@ Tcl_MainEx( Tcl_MainLoopProc *mainLoopProc; Tcl_Channel chan; InteractiveState is; -#ifdef ZIPFS_IN_TCL - const char *zipFile = NULL; - Tcl_Obj *zipval = NULL; - int autoRun = 1; - int zipOk = TCL_ERROR; -#ifndef ANDROID - const char *exeName; -#endif -#endif TclpSetInitialEncodings(); TclpFindExecutable((const char *)argv[0]); -#if defined(ZIPFS_IN_TCL) && !defined(ANDROID) - exeName = Tcl_GetNameOfExecutable(); -#endif Tcl_InitMemory(interp); @@ -369,26 +347,6 @@ Tcl_MainEx( Tcl_DecrRefCount(value); argc -= 3; argv += 3; -#ifdef ZIPFS_IN_TCL - } else if (argc > 2) { - int length = strlen((char *) argv[1]); - if ((length >= 2) && - (0 == _tcsncmp(TEXT("-zip"), argv[1], length))) { - argc--; - argv++; - if ((argc > 1) && (argv[1][0] != (TCHAR) '-')) { - zipval = NewNativeObj(argv[1], -1); - zipFile = Tcl_GetString(zipval); - autoRun = 0; - argc--; - argv++; - } - } else if ('-' != argv[1][0]) { - Tcl_SetStartupScript(NewNativeObj(argv[1], -1), NULL); - argc--; - argv++; - } -#endif } else if ((argc > 1) && ('-' != argv[1][0])) { Tcl_SetStartupScript(NewNativeObj(argv[1], -1), NULL); argc--; @@ -422,67 +380,6 @@ Tcl_MainEx( Tcl_SetVar2Ex(interp, "tcl_interactive", NULL, Tcl_NewIntObj(!path && is.tty), TCL_GLOBAL_ONLY); -#ifdef ZIPFS_IN_TCL - zipOk = Tclzipfs_Init(interp); - if (zipOk == TCL_OK) { - int relax = 0; - - if (zipFile == NULL) { - relax = 1; -#ifdef ANDROID - zipFile = getenv("PACKAGE_CODE_PATH"); - if (zipFile == NULL) { - zipFile = Tcl_GetNameOfExecutable(); - } -#else - zipFile = exeName; -#endif - } - if (zipFile != NULL) { -#ifdef ANDROID - zipOk = Tclzipfs_Mount(interp, zipFile, "", NULL); -#else - zipOk = Tclzipfs_Mount(interp, zipFile, exeName, NULL); -#endif - if (!relax && (zipOk != TCL_OK)) { - exitCode = 1; - goto done; - } - } else { - zipOk = TCL_ERROR; - } - Tcl_ResetResult(interp); - } - if (zipOk == TCL_OK) { -#ifdef ZIPFS_BOOTDIR - char *tcl_lib = ZIPFS_BOOTDIR "/tcl" TCL_VERSION; - char *tcl_pkg = ZIPFS_BOOTDIR; -#else - char *tcl_lib; - char *tcl_pkg = (char *) exeName; - Tcl_DString dsLib; - - Tcl_DStringInit(&dsLib); - Tcl_DStringAppend(&dsLib, exeName, -1); - Tcl_DStringAppend(&dsLib, "/tcl" TCL_VERSION, -1); - tcl_lib = Tcl_DStringValue(&dsLib); -#endif - Tcl_SetVar2(interp, "env", "TCL_LIBRARY", tcl_lib, TCL_GLOBAL_ONLY); - Tcl_SetVar(interp, "tcl_libPath", tcl_lib, TCL_GLOBAL_ONLY); - Tcl_SetVar(interp, "tcl_library", tcl_lib, TCL_GLOBAL_ONLY); - Tcl_SetVar(interp, "tcl_pkgPath", tcl_pkg, TCL_GLOBAL_ONLY); - Tcl_SetVar(interp, "auto_path", tcl_lib, - TCL_GLOBAL_ONLY | TCL_LIST_ELEMENT); -#ifndef ZIPFS_BOOTDIR - Tcl_DStringFree(&dsLib); -#endif - } - if (zipval != NULL) { - Tcl_DecrRefCount(zipval); - zipval = NULL; - } -#endif - /* * Invoke application-specific initialization. */ @@ -512,100 +409,6 @@ Tcl_MainEx( Tcl_CreateExitHandler(FreeMainInterp, interp); } -#ifdef ZIPFS_IN_TCL - /* - * Setup auto loading info to point to mounted ZIP file. - */ - - if (zipOk == TCL_OK) { -#ifdef ZIPFS_BOOTDIR - char *tcl_lib = ZIPFS_BOOTDIR "/tcl" TCL_VERSION; - char *tcl_pkg = ZIPFS_BOOTDIR; -#else - char *tcl_lib; - char *tcl_pkg = (char *) exeName; - Tcl_DString dsLib; - - Tcl_DStringInit(&dsLib); - Tcl_DStringAppend(&dsLib, exeName, -1); - Tcl_DStringAppend(&dsLib, "/tcl" TCL_VERSION, -1); - tcl_lib = Tcl_DStringValue(&dsLib); -#endif - Tcl_SetVar(interp, "tcl_libPath", tcl_lib, TCL_GLOBAL_ONLY); - Tcl_SetVar(interp, "tcl_library", tcl_lib, TCL_GLOBAL_ONLY); - Tcl_SetVar(interp, "tcl_pkgPath", tcl_pkg, TCL_GLOBAL_ONLY); -#ifndef ZIPFS_BOOTDIR - Tcl_DStringFree(&dsLib); -#endif - - /* - * We need to re-init encoding (after initializing Tcl), - * otherwise "encoding system" will return "identity" - */ - - TclpSetInitialEncodings(); - } - - /* - * Set embedded application startup file, if any. - */ - - if ((zipOk == TCL_OK) && autoRun) { - char *filename; - Tcl_Channel chan; -#ifdef ZIPFS_BOOTDIR - filename = ZIPFS_BOOTDIR "/app/main.tcl"; -#else - Tcl_DString dsFile; - - Tcl_DStringInit(&dsFile); - Tcl_DStringAppend(&dsFile, exeName, -1); - Tcl_DStringAppend(&dsFile, "/app/main.tcl", -1); - filename = Tcl_DStringValue(&dsFile); -#endif - chan = Tcl_OpenFileChannel(NULL, filename, "r", 0); - if (chan != (Tcl_Channel) NULL) { - Tcl_Obj *arg; - - Tcl_Close(NULL, chan); - - /* - * Push back script file to argv, if any. - */ - if ((arg = Tcl_GetStartupScript(NULL)) != NULL) { - Tcl_Obj *v, *no; - - no = Tcl_NewStringObj("argv", 4); - v = Tcl_ObjGetVar2(interp, no, NULL, TCL_GLOBAL_ONLY); - if (v != NULL) { - Tcl_Obj **objv, *nv; - int objc, i; - - objc = 0; - Tcl_ListObjGetElements(NULL, v, &objc, &objv); - nv = Tcl_NewListObj(1, &arg); - for (i = 0; i < objc; i++) { - Tcl_ListObjAppendElement(NULL, nv, objv[i]); - } - Tcl_IncrRefCount(nv); - if (Tcl_ObjSetVar2(interp, no, NULL, nv, TCL_GLOBAL_ONLY) - != NULL) { - Tcl_GlobalEval(interp, "incr argc"); - } - Tcl_DecrRefCount(nv); - } - Tcl_DecrRefCount(no); - } - Tcl_SetStartupScript(Tcl_NewStringObj(filename, -1), NULL); - Tcl_SetVar(interp, "argv0", filename, TCL_GLOBAL_ONLY); - Tcl_SetVar(interp, "tcl_interactive", "0", TCL_GLOBAL_ONLY); - } -#ifndef ANDROID - Tcl_DStringFree(&dsFile); -#endif - } -#endif - /* * Invoke the script specified on the command line, if any. Must fetch it * again, as the appInitProc might have reset it. diff --git a/generic/tclZipfs.h b/generic/tclZipfs.h new file mode 100644 index 0000000..bf3a3cb --- /dev/null +++ b/generic/tclZipfs.h @@ -0,0 +1,65 @@ +/* + * tclZipfs.h -- + * + * This header file describes the interface of the ZIPFS filesystem + * + * Copyright (c) 2013-2015 Christian Werner + * + * See the file "license.terms" for information on usage and redistribution of + * this file, and for a DISCLAIMER OF ALL WARRANTIES. + */ + +#ifndef _ZIPFS_H +#define _ZIPFS_H + +#include "tcl.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef ZIPFSAPI +# define ZIPFSAPI extern +#endif + +#ifdef ZIPFS_IN_TK +#define Zipfs_Mount Tkzipfs_Mount +#define Zipfs_Unmount Tkzipfs_Unmount +#define Zipfs_Init Tkzipfs_Init +#define Zipfs_SafeInit Tkzipfs_SafeInit +#ifdef BUILD_tk +# undef ZIPFSAPI +# define ZIPFSAPI DLLEXPORT +#endif +#endif + +#ifdef ZIPFS_IN_TCL +#define Zipfs_Mount Tclzipfs_Mount +#define Zipfs_Unmount Tclzipfs_Unmount +#define Zipfs_Init Tclzipfs_Init +#define Zipfs_SafeInit Tclzipfs_SafeInit +#ifdef BUILD_tcl +# undef ZIPFSAPI +# define ZIPFSAPI DLLEXPORT +#endif +#endif + +ZIPFSAPI int Zipfs_Mount(Tcl_Interp *interp, CONST char *zipname, + CONST char *mntpt, CONST char *passwd); +ZIPFSAPI int Zipfs_Unmount(Tcl_Interp *interp, CONST char *zipname); +ZIPFSAPI int Zipfs_Init(Tcl_Interp *interp); +ZIPFSAPI int Zipfs_SafeInit(Tcl_Interp *interp); + +#ifdef __cplusplus +} +#endif + +#endif /* _ZIPFS_H */ + +/* + * Local Variables: + * mode: c + * c-basic-offset: 4 + * fill-column: 78 + * End: + */ diff --git a/generic/zipfs.c b/generic/zipfs.c index 0683c32..6d49f4f 100644 --- a/generic/zipfs.c +++ b/generic/zipfs.c @@ -24,7 +24,7 @@ #endif #include "tclInt.h" #include "tclFileSystem.h" -#include "zipfs.h" +#include "tclZipfs.h" #ifdef HAVE_ZLIB @@ -3821,7 +3821,9 @@ Zip_FSLoadFile(Tcl_Interp *interp, Tcl_Obj *path, Tcl_LoadHandle *loadHandle, * Define the ZIP filesystem dispatch table. */ -Tcl_Filesystem zipfsFilesystem = { +MODULE_SCOPE const Tcl_Filesystem zipfsFilesystem; + +const Tcl_Filesystem zipfsFilesystem = { "zipfs", sizeof (Tcl_Filesystem), TCL_FILESYSTEM_VERSION_2, diff --git a/generic/zipfs.h b/generic/zipfs.h deleted file mode 100644 index 15ca37c..0000000 --- a/generic/zipfs.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * zipfs.h -- - * - * This header file describes the interface of the ZIPFS filesystem - * used in AndroWish. - * - * Copyright (c) 2013-2015 Christian Werner - * - * See the file "license.terms" for information on usage and redistribution of - * this file, and for a DISCLAIMER OF ALL WARRANTIES. - */ - -#ifndef _ZIPFS_H -#define _ZIPFS_H - -#include "tcl.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef ZIPFSAPI -# define ZIPFSAPI extern -#endif - -#ifdef ZIPFS_IN_TK -#define Zipfs_Mount Tkzipfs_Mount -#define Zipfs_Unmount Tkzipfs_Unmount -#define Zipfs_Init Tkzipfs_Init -#define Zipfs_SafeInit Tkzipfs_SafeInit -#ifdef BUILD_tk -# undef ZIPFSAPI -# define ZIPFSAPI DLLEXPORT -#endif -#endif - -#ifdef ZIPFS_IN_TCL -#define Zipfs_Mount Tclzipfs_Mount -#define Zipfs_Unmount Tclzipfs_Unmount -#define Zipfs_Init Tclzipfs_Init -#define Zipfs_SafeInit Tclzipfs_SafeInit -#ifdef BUILD_tcl -# undef ZIPFSAPI -# define ZIPFSAPI DLLEXPORT -#endif -#endif - -ZIPFSAPI int Zipfs_Mount(Tcl_Interp *interp, CONST char *zipname, - CONST char *mntpt, CONST char *passwd); -ZIPFSAPI int Zipfs_Unmount(Tcl_Interp *interp, CONST char *zipname); -ZIPFSAPI int Zipfs_Init(Tcl_Interp *interp); -ZIPFSAPI int Zipfs_SafeInit(Tcl_Interp *interp); - -#ifdef __cplusplus -} -#endif - -#endif /* _ZIPFS_H */ - -/* - * Local Variables: - * mode: c - * c-basic-offset: 4 - * fill-column: 78 - * End: - */ diff --git a/unix/Makefile.in b/unix/Makefile.in index ebbd61c..c09fb35 100644 --- a/unix/Makefile.in +++ b/unix/Makefile.in @@ -373,6 +373,7 @@ GENERIC_HDRS = \ $(GENERIC_DIR)/tclInt.h \ $(GENERIC_DIR)/tclIntDecls.h \ $(GENERIC_DIR)/tclIntPlatDecls.h \ + $(GENERIC_DIR)/tclZipfs.h \ $(GENERIC_DIR)/tclTomMath.h \ $(GENERIC_DIR)/tclTomMathDecls.h \ $(GENERIC_DIR)/tclOO.h \ @@ -383,7 +384,7 @@ GENERIC_HDRS = \ $(GENERIC_DIR)/tclPlatDecls.h \ $(GENERIC_DIR)/tclPort.h \ $(GENERIC_DIR)/tclRegexp.h \ - $(GENERIC_DIR)/zipfs.h + $(GENERIC_DIR)/tclZipfs.h GENERIC_SRCS = \ $(GENERIC_DIR)/regcomp.c \ @@ -954,6 +955,7 @@ install-headers: @for i in $(GENERIC_DIR)/tcl.h $(GENERIC_DIR)/tclDecls.h \ $(GENERIC_DIR)/tclOO.h $(GENERIC_DIR)/tclOODecls.h \ $(GENERIC_DIR)/tclPlatDecls.h \ + $(GENERIC_DIR)/tclZipfs.h \ $(GENERIC_DIR)/tclTomMath.h \ $(GENERIC_DIR)/tclTomMathDecls.h ; \ do \ diff --git a/unix/configure b/unix/configure index 3e72a0d..c19a77a 100755 --- a/unix/configure +++ b/unix/configure @@ -869,7 +869,6 @@ Optional Packages: --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-encoding encoding for configuration values (default: iso8859-1) - --with-zipfs include ZIP filesystem --with-tzdata install timezone data (default: autodetect) Some influential environment variables: @@ -6212,23 +6211,6 @@ cat >>confdefs.h <<\_ACEOF _ACEOF -# Check whether --with-zipfs or --without-zipfs was given. -if test "${with_zipfs+set}" = set; then - withval="$with_zipfs" - tcl_ok=$withval -else - tcl_ok=no -fi; -echo "$as_me:$LINENO: result: $tcl_ok" >&5 -echo "${ECHO_T}$tcl_ok" >&6 -if test $tcl_ok = yes; then - -cat >>confdefs.h <<\_ACEOF -#define ZIPFS_IN_TCL 1 -_ACEOF - -fi - #-------------------------------------------------------------------- # The statements below define a collection of compile flags. This # macro depends on the value of SHARED_BUILD, and should be called diff --git a/unix/configure.in b/unix/configure.in index 7eeff3b..c7b0edc 100644 --- a/unix/configure.in +++ b/unix/configure.in @@ -171,14 +171,6 @@ AS_IF([test $zlib_ok = no], [ AC_SUBST(ZLIB_INCLUDE,[-I\${ZLIB_DIR}]) ]) AC_DEFINE(HAVE_ZLIB, 1, [Is there an installed zlib?]) -AC_ARG_WITH(zipfs, - AC_HELP_STRING([--with-zipfs], - [include ZIP filesystem]), - [tcl_ok=$withval], [tcl_ok=no]) -AC_MSG_RESULT([$tcl_ok]) -if test $tcl_ok = yes; then - AC_DEFINE(ZIPFS_IN_TCL, 1, [Include ZIP filesystem?]) -fi #-------------------------------------------------------------------- # The statements below define a collection of compile flags. This diff --git a/unix/tclUnixInit.c b/unix/tclUnixInit.c index e8ccc76..5e4ef0a 100644 --- a/unix/tclUnixInit.c +++ b/unix/tclUnixInit.c @@ -9,9 +9,6 @@ */ #include "tclInt.h" -#ifdef ZIPFS_IN_TCL -#include "zipfs.h" -#endif #include #include #ifdef HAVE_LANGINFO @@ -544,11 +541,6 @@ TclpInitLibraryPath( */ str = defaultLibraryDir; -#ifdef ZIPFS_IN_TCL - if (Tclzipfs_Mount(NULL, NULL, NULL, NULL) == TCL_OK) { - str = ""; - } -#endif } if (str[0] != '\0') { objPtr = Tcl_NewStringObj(str, -1); diff --git a/win/Makefile.in b/win/Makefile.in index 00f5c99..f6d006b 100644 --- a/win/Makefile.in +++ b/win/Makefile.in @@ -636,6 +636,7 @@ install-libraries: libraries install-tzdata install-msgs @echo "Installing header files"; @for i in "$(GENERIC_DIR)/tcl.h" "$(GENERIC_DIR)/tclDecls.h" \ "$(GENERIC_DIR)/tclOO.h" "$(GENERIC_DIR)/tclOODecls.h" \ + "$(GENERIC_DIR)/tclZipfs.h" \ "$(GENERIC_DIR)/tclPlatDecls.h" \ "$(GENERIC_DIR)/tclTomMath.h" \ "$(GENERIC_DIR)/tclTomMathDecls.h"; \ diff --git a/win/configure b/win/configure index 27f2c10..3ebc697 100755 --- a/win/configure +++ b/win/configure @@ -853,7 +853,6 @@ Optional Packages: --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-encoding encoding for configuration values --with-celib=DIR use Windows/CE support library from DIR - --with-zipfs include ZIP filesystem Some influential environment variables: CC C compiler command @@ -4409,24 +4408,6 @@ cat >>confdefs.h <<\_ACEOF _ACEOF -# Check whether --with-zipfs or --without-zipfs was given. -if test "${with_zipfs+set}" = set; then - withval="$with_zipfs" - tcl_ok=$withval -else - tcl_ok=no -fi; -echo "$as_me:$LINENO: result: $tcl_ok" >&5 -echo "${ECHO_T}$tcl_ok" >&6 -if test $tcl_ok = yes; then - -cat >>confdefs.h <<\_ACEOF -#define ZIPFS_IN_TCL 1 -_ACEOF - -fi - - echo "$as_me:$LINENO: checking for intptr_t" >&5 echo $ECHO_N "checking for intptr_t... $ECHO_C" >&6 if test "${ac_cv_type_intptr_t+set}" = set; then diff --git a/win/configure.in b/win/configure.in index c8ab2e3..9e9df90 100644 --- a/win/configure.in +++ b/win/configure.in @@ -141,14 +141,6 @@ AS_IF([test "$tcl_ok" = "yes"], [ AC_SUBST(ZLIB_OBJS,[\${ZLIB_OBJS}]) ]) AC_DEFINE(HAVE_ZLIB, 1, [Is there an installed zlib?]) -AC_ARG_WITH(zipfs, - AC_HELP_STRING([--with-zipfs], - [include ZIP filesystem]), - [tcl_ok=$withval], [tcl_ok=no]) -AC_MSG_RESULT([$tcl_ok]) -if test $tcl_ok = yes; then - AC_DEFINE(ZIPFS_IN_TCL, 1, [Include ZIP filesystem?]) -fi AC_CHECK_TYPE([intptr_t], [ AC_DEFINE([HAVE_INTPTR_T], 1, [Do we have the intptr_t type?])], [ diff --git a/win/makefile.vc b/win/makefile.vc index ecfcecf..82dd655 100644 --- a/win/makefile.vc +++ b/win/makefile.vc @@ -1115,6 +1115,7 @@ install-libraries: tclConfig install-msgs install-tzdata @$(CPY) "$(GENERICDIR)\tclDecls.h" "$(INCLUDE_INSTALL_DIR)\" @$(CPY) "$(GENERICDIR)\tclOO.h" "$(INCLUDE_INSTALL_DIR)\" @$(CPY) "$(GENERICDIR)\tclOODecls.h" "$(INCLUDE_INSTALL_DIR)\" + @$(CPY) "$(GENERICDIR)\tclZipfs.h" "$(INCLUDE_INSTALL_DIR)\" @$(CPY) "$(GENERICDIR)\tclPlatDecls.h" "$(INCLUDE_INSTALL_DIR)\" @$(CPY) "$(GENERICDIR)\tclTomMath.h" "$(INCLUDE_INSTALL_DIR)\" @$(CPY) "$(GENERICDIR)\tclTomMathDecls.h" "$(INCLUDE_INSTALL_DIR)\" -- cgit v0.12 From 4d007159025e0fc8ea75aae346bc7e6588e391c2 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Mon, 21 Dec 2015 10:49:36 +0000 Subject: CONST -> const --- generic/tclZipfs.h | 6 ++--- generic/zipfs.c | 68 +++++++++++++++++++++++++++--------------------------- 2 files changed, 37 insertions(+), 37 deletions(-) diff --git a/generic/tclZipfs.h b/generic/tclZipfs.h index bf3a3cb..75dcb13 100644 --- a/generic/tclZipfs.h +++ b/generic/tclZipfs.h @@ -44,9 +44,9 @@ extern "C" { #endif #endif -ZIPFSAPI int Zipfs_Mount(Tcl_Interp *interp, CONST char *zipname, - CONST char *mntpt, CONST char *passwd); -ZIPFSAPI int Zipfs_Unmount(Tcl_Interp *interp, CONST char *zipname); +ZIPFSAPI int Zipfs_Mount(Tcl_Interp *interp, const char *zipname, + const char *mntpt, const char *passwd); +ZIPFSAPI int Zipfs_Unmount(Tcl_Interp *interp, const char *zipname); ZIPFSAPI int Zipfs_Init(Tcl_Interp *interp); ZIPFSAPI int Zipfs_SafeInit(Tcl_Interp *interp); diff --git a/generic/zipfs.c b/generic/zipfs.c index 6d49f4f..a9f0a39 100644 --- a/generic/zipfs.c +++ b/generic/zipfs.c @@ -109,7 +109,7 @@ #if defined(_WIN32) || defined(_WIN64) #define HAS_DRIVES 1 -static CONST char drvletters[] = +static const char drvletters[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; #else #define HAS_DRIVES 0 @@ -223,7 +223,7 @@ static struct { * For password rotation. */ -static CONST char pwrot[16] = { +static const char pwrot[16] = { 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0 }; @@ -232,7 +232,7 @@ static CONST char pwrot[16] = { * Table to compute CRC32. */ -static CONST unsigned int crc32tab[256] = { +static const unsigned int crc32tab[256] = { 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, @@ -458,10 +458,10 @@ ToDosDate(time_t when) */ static int -CountSlashes(CONST char *string) +CountSlashes(const char *string) { int count = 0; - CONST char *p = string; + const char *p = string; while (*p != '\0') { if (*p == '/') { @@ -491,7 +491,7 @@ CountSlashes(CONST char *string) */ static char * -CanonicalPath(CONST char *root, CONST char *tail, Tcl_DString *dsPtr) +CanonicalPath(const char *root, const char *tail, Tcl_DString *dsPtr) { char *path; int i, j, c, isunc = 0; @@ -598,7 +598,7 @@ CanonicalPath(CONST char *root, CONST char *tail, Tcl_DString *dsPtr) */ static char * -AbsolutePath(CONST char *path, +AbsolutePath(const char *path, #if HAS_DRIVES int *drvPtr, #endif @@ -832,7 +832,7 @@ ZipFSCloseArchive(Tcl_Interp *interp, ZipFile *zf) */ static int -ZipFSOpenArchive(Tcl_Interp *interp, CONST char *zipname, int needZip, +ZipFSOpenArchive(Tcl_Interp *interp, const char *zipname, int needZip, ZipFile *zf) { int i; @@ -1049,8 +1049,8 @@ error: */ int -Zipfs_Mount(Tcl_Interp *interp, CONST char *zipname, CONST char *mntpt, - CONST char *passwd) +Zipfs_Mount(Tcl_Interp *interp, const char *zipname, const char *mntpt, + const char *passwd) { char *realname, *p; int i, pwlen, isNew; @@ -1420,7 +1420,7 @@ nextent: */ int -Zipfs_Unmount(Tcl_Interp *interp, CONST char *zipname) +Zipfs_Unmount(Tcl_Interp *interp, const char *zipname) { char *realname; ZipFile *zf; @@ -1504,7 +1504,7 @@ done: static int ZipFSMountCmd(ClientData clientData, Tcl_Interp *interp, - int argc, CONST char **argv) + int argc, const char **argv) { if (argc > 4) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], @@ -1534,7 +1534,7 @@ ZipFSMountCmd(ClientData clientData, Tcl_Interp *interp, static int ZipFSUnmountCmd(ClientData clientData, Tcl_Interp *interp, - int argc, CONST char **argv) + int argc, const char **argv) { if (argc != 2) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], @@ -1563,7 +1563,7 @@ ZipFSUnmountCmd(ClientData clientData, Tcl_Interp *interp, static int ZipFSMkKeyCmd(ClientData clientData, Tcl_Interp *interp, - int argc, CONST char **argv) + int argc, const char **argv) { int len, i = 0; char pwbuf[264]; @@ -1621,15 +1621,15 @@ ZipFSMkKeyCmd(ClientData clientData, Tcl_Interp *interp, */ static int -ZipAddFile(Tcl_Interp *interp, CONST char *path, CONST char *name, - Tcl_Channel out, CONST char *passwd, +ZipAddFile(Tcl_Interp *interp, const char *path, const char *name, + Tcl_Channel out, const char *passwd, char *buf, int bufsize, Tcl_HashTable *fileHash) { Tcl_Channel in; Tcl_HashEntry *hPtr; ZipEntry *z; z_stream stream; - CONST char *zpath; + const char *zpath; int nbyte, nbytecompr, len, crc, flush, pos[3], zpathlen, olen; int mtime = 0, isNew, align = 0, cmeth; unsigned long keys[3], keys0[3]; @@ -1947,11 +1947,11 @@ seekErr: static int ZipFSMkZipOrImgCmd(ClientData clientData, Tcl_Interp *interp, - int isImg, int argc, CONST char **argv) + int isImg, int argc, const char **argv) { Tcl_Channel out; int len = 0, pwlen = 0, slen = 0, i, count, ret = TCL_ERROR, largc, pos[3]; - CONST char **largv; + const char **largv; Tcl_DString ds; ZipEntry *z; Tcl_HashEntry *hPtr; @@ -2056,7 +2056,7 @@ ZipFSMkZipOrImgCmd(ClientData clientData, Tcl_Interp *interp, slen = strlen(argv[3]); } for (i = 0; i < largc; i++) { - CONST char *name = largv[i]; + const char *name = largv[i]; if (slen > 0) { len = strlen(name); @@ -2080,7 +2080,7 @@ ZipFSMkZipOrImgCmd(ClientData clientData, Tcl_Interp *interp, pos[1] = Tcl_Tell(out); count = 0; for (i = 0; i < largc; i++) { - CONST char *name = largv[i]; + const char *name = largv[i]; if (slen > 0) { len = strlen(name); @@ -2175,7 +2175,7 @@ done: static int ZipFSMkZipCmd(ClientData clientData, Tcl_Interp *interp, - int argc, CONST char **argv) + int argc, const char **argv) { return ZipFSMkZipOrImgCmd(clientData, interp, 0, argc, argv); } @@ -2199,7 +2199,7 @@ ZipFSMkZipCmd(ClientData clientData, Tcl_Interp *interp, static int ZipFSMkImgCmd(ClientData clientData, Tcl_Interp *interp, - int argc, CONST char **argv) + int argc, const char **argv) { return ZipFSMkZipOrImgCmd(clientData, interp, 1, argc, argv); } @@ -2224,7 +2224,7 @@ ZipFSMkImgCmd(ClientData clientData, Tcl_Interp *interp, static int ZipFSExistsObjCmd(ClientData clientData, Tcl_Interp *interp, - int objc, Tcl_Obj *CONST objv[]) + int objc, Tcl_Obj *const objv[]) { char *filename; int exists; @@ -2262,7 +2262,7 @@ ZipFSExistsObjCmd(ClientData clientData, Tcl_Interp *interp, static int ZipFSInfoObjCmd(ClientData clientData, Tcl_Interp *interp, - int objc, Tcl_Obj *CONST objv[]) + int objc, Tcl_Obj *const objv[]) { char *filename; ZipEntry *z; @@ -2307,7 +2307,7 @@ ZipFSInfoObjCmd(ClientData clientData, Tcl_Interp *interp, static int ZipFSListObjCmd(ClientData clientData, Tcl_Interp *interp, - int objc, Tcl_Obj *CONST objv[]) + int objc, Tcl_Obj *const objv[]) { char *pattern = NULL; Tcl_RegExp regexp = NULL; @@ -2496,7 +2496,7 @@ ZipChannelRead(ClientData instanceData, char *buf, int toRead, int *errloc) */ static int -ZipChannelWrite(ClientData instanceData, CONST char *buf, +ZipChannelWrite(ClientData instanceData, const char *buf, int toWrite, int *errloc) { ZipChannel *info = (ZipChannel *) instanceData; @@ -3176,7 +3176,7 @@ Zip_FSFilesystemSeparatorProc(Tcl_Obj *pathPtr) static int Zip_FSMatchInDirectoryProc(Tcl_Interp* interp, Tcl_Obj *result, - Tcl_Obj *pathPtr, CONST char *pattern, + Tcl_Obj *pathPtr, const char *pattern, Tcl_GlobTypeData *types) { Tcl_HashEntry *hPtr; @@ -3606,10 +3606,10 @@ Zip_FSChdirProc(Tcl_Obj *pathPtr) *------------------------------------------------------------------------- */ -static CONST char *CONST86 * +static const char *const * Zip_FSFileAttrStringsProc(Tcl_Obj *pathPtr, Tcl_Obj** objPtrRef) { - static CONST char *attrs[] = { + static const char *const attrs[] = { "-uncompsize", "-compsize", "-offset", @@ -3885,7 +3885,7 @@ static int Zipfs_doInit(Tcl_Interp *interp, int safe) { #ifdef HAVE_ZLIB - static CONST char findproc[] = + static const char findproc[] = "proc ::zipfs::find dir {\n" " set result {}\n" " if {[catch {glob -directory $dir -tails -nocomplain * .*} list]} {\n" @@ -4009,14 +4009,14 @@ Zipfs_SafeInit(Tcl_Interp *interp) */ int -Zipfs_Mount(Tcl_Interp *interp, CONST char *zipname, CONST char *mntpt, - CONST char *passwd) +Zipfs_Mount(Tcl_Interp *interp, const char *zipname, const char *mntpt, + const char *passwd) { return Zipfs_doInit(interp, 1); } int -Zipfs_Unmount(Tcl_Interp *interp, CONST char *zipname) +Zipfs_Unmount(Tcl_Interp *interp, const char *zipname) { return Zipfs_doInit(interp, 1); } -- cgit v0.12 From 8ecd6aeb5b622ad2cc8c4690880e066c60abec54 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Mon, 21 Dec 2015 11:29:38 +0000 Subject: Make it compile warning-free with MSVC compiler (VS2013, at least). Other tweaks. --- generic/tclPkgConfig.c | 20 -------------------- generic/zipfs.c | 31 ++++++++++++++++--------------- unix/Makefile.in | 3 +-- unix/tclLoadDl.c | 40 +--------------------------------------- unix/tclUnixFCmd.c | 21 --------------------- unix/tclUnixInit.c | 4 ---- win/makefile.vc | 6 +++++- 7 files changed, 23 insertions(+), 102 deletions(-) diff --git a/generic/tclPkgConfig.c b/generic/tclPkgConfig.c index 3f8178e..466d535 100644 --- a/generic/tclPkgConfig.c +++ b/generic/tclPkgConfig.c @@ -100,35 +100,19 @@ static Tcl_Config const cfg[] = { /* Runtime paths to various stuff */ -#ifdef ANDROID - {"libdir,runtime", ""}, - {"bindir,runtime", ""}, - {"scriptdir,runtime", ""}, - {"includedir,runtime", ""}, - {"docdir,runtime", ""}, -#else {"libdir,runtime", CFG_RUNTIME_LIBDIR}, {"bindir,runtime", CFG_RUNTIME_BINDIR}, {"scriptdir,runtime", CFG_RUNTIME_SCRDIR}, {"includedir,runtime", CFG_RUNTIME_INCDIR}, {"docdir,runtime", CFG_RUNTIME_DOCDIR}, -#endif /* Installation paths to various stuff */ -#ifdef ANDROID - {"libdir,install", ""}, - {"bindir,install", ""}, - {"scriptdir,install", ""}, - {"includedir,install", ""}, - {"docdir,install", ""}, -#else {"libdir,install", CFG_INSTALL_LIBDIR}, {"bindir,install", CFG_INSTALL_BINDIR}, {"scriptdir,install", CFG_INSTALL_SCRDIR}, {"includedir,install", CFG_INSTALL_INCDIR}, {"docdir,install", CFG_INSTALL_DOCDIR}, -#endif /* Last entry, closes the array */ {NULL, NULL} @@ -139,10 +123,6 @@ TclInitEmbeddedConfigurationInformation( Tcl_Interp *interp) /* Interpreter the configuration command is * registered in. */ { -#if defined(ANDROID) && !defined(TCL_CFGVAL_ENCODING) -#define TCL_CFGVAL_ENCODING "utf-8" -#endif - Tcl_RegisterConfig(interp, "tcl", cfg, TCL_CFGVAL_ENCODING); } diff --git a/generic/zipfs.c b/generic/zipfs.c index a9f0a39..67390a6 100644 --- a/generic/zipfs.c +++ b/generic/zipfs.c @@ -2561,19 +2561,19 @@ ZipChannelSeek(ClientData instanceData, long offset, int mode, int *errloc) *errloc = EINVAL; return -1; } + if (offset < 0) { + *errloc = EINVAL; + return -1; + } if (info->iswr) { - if (offset > info->nmax) { + if ((unsigned long) offset > info->nmax) { *errloc = EINVAL; return -1; } - if (offset > info->nbyte) { + if ((unsigned long) offset > info->nbyte) { info->nbyte = offset; } - } else if (offset > info->nbyte) { - *errloc = EINVAL; - return -1; - } - if (offset < 0) { + } else if ((unsigned long) offset > info->nbyte) { *errloc = EINVAL; return -1; } @@ -2772,12 +2772,12 @@ merror0: info->nbyte = 0; } else { if (z->data != NULL) { - i = z->nbyte; - if (i > info->nmax) { - i = info->nmax; + unsigned int j = z->nbyte; + if (j > info->nmax) { + j = info->nmax; } - memcpy(info->ubuf, z->data, i); - info->nbyte = i; + memcpy(info->ubuf, z->data, j); + info->nbyte = j; } else { unsigned char *zbuf = z->zipfile->data + z->offset; @@ -2809,15 +2809,16 @@ merror0: stream.opaque = Z_NULL; stream.avail_in = z->nbytecompr; if (z->isenc) { + unsigned int j; stream.avail_in -= 12; cbuf = (unsigned char *) Tcl_AttemptAlloc(stream.avail_in); if (cbuf == NULL) { goto merror0; } - for (i = 0; i < stream.avail_in; i++) { - ch = info->ubuf[i]; - cbuf[i] = zdecode(info->keys, crc32tab, ch); + for (j = 0; j < stream.avail_in; j++) { + ch = info->ubuf[j]; + cbuf[j] = zdecode(info->keys, crc32tab, ch); } stream.next_in = cbuf; } else { diff --git a/unix/Makefile.in b/unix/Makefile.in index 3e4cfc7..d65dceb 100644 --- a/unix/Makefile.in +++ b/unix/Makefile.in @@ -383,8 +383,7 @@ GENERIC_HDRS = \ $(GENERIC_DIR)/tclPatch.h \ $(GENERIC_DIR)/tclPlatDecls.h \ $(GENERIC_DIR)/tclPort.h \ - $(GENERIC_DIR)/tclRegexp.h \ - $(GENERIC_DIR)/tclZipfs.h + $(GENERIC_DIR)/tclRegexp.h GENERIC_SRCS = \ $(GENERIC_DIR)/regcomp.c \ diff --git a/unix/tclLoadDl.c b/unix/tclLoadDl.c index bb2361c..aec071c 100644 --- a/unix/tclLoadDl.c +++ b/unix/tclLoadDl.c @@ -97,11 +97,7 @@ TclpDlopen( } else { dlopenflags |= RTLD_NOW; } - if (native == NULL) { - handle = NULL; - } else { - handle = dlopen(native, dlopenflags); - } + handle = dlopen(native, dlopenflags); if (handle == NULL) { /* * Let the OS loader examine the binary search path for whatever @@ -119,41 +115,7 @@ TclpDlopen( handle = dlopen(native, dlopenflags); Tcl_DStringFree(&ds); } -#ifdef ANDROID - /* - * If not an absolute or relative path, try to load - * from $INTERNAL_STORAGE/../lib (the place where the - * system has installed bundled .so files from the .APK) - */ - if (handle == NULL) { - native = Tcl_GetString(pathPtr); - if ((native != NULL) && (strchr(native, '/') == NULL)) { - char *storage = getenv("INTERNAL_STORAGE"); - Tcl_DString ds2; - if ((storage != NULL) && (storage[0] != '\0')) { - Tcl_DStringInit(&ds2); - Tcl_DStringAppend(&ds2, storage, -1); - Tcl_DStringAppend(&ds2, "/../lib/", -1); - Tcl_DStringAppend(&ds2, native, -1); - handle = dlopen(Tcl_DStringValue(&ds2), RTLD_NOW | RTLD_GLOBAL); - Tcl_DStringFree(&ds2); - } - if (handle == NULL) { - storage = getenv("TK_TCL_WISH_LD_LIBS"); - if ((storage != NULL) && (storage[0] != '\0')) { - Tcl_DStringInit(&ds2); - Tcl_DStringAppend(&ds2, storage, -1); - Tcl_DStringAppend(&ds2, "/", -1); - Tcl_DStringAppend(&ds2, native, -1); - handle = - dlopen(Tcl_DStringValue(&ds2), RTLD_NOW | RTLD_GLOBAL); - Tcl_DStringFree(&ds2); - } - } - } - } - #endif if (handle == NULL) { /* * Write the string to a variable first to work around a compiler bug diff --git a/unix/tclUnixFCmd.c b/unix/tclUnixFCmd.c index 0193dae..3b1b6ca 100644 --- a/unix/tclUnixFCmd.c +++ b/unix/tclUnixFCmd.c @@ -465,9 +465,6 @@ DoCopyFile( /* Used to determine filetype. */ { Tcl_StatBuf dstStatBuf; -#ifdef ANDROID - int ret; -#endif if (S_ISDIR(statBufPtr->st_mode)) { errno = EISDIR; @@ -523,15 +520,7 @@ DoCopyFile( if (mkfifo(dst, statBufPtr->st_mode) < 0) { /* INTL: Native. */ return TCL_ERROR; } -#ifdef ANDROID - ret = CopyFileAtts(src, dst, statBufPtr); - if (ret != TCL_OK && errno == EPERM) { - ret = TCL_OK; - } - return ret; -#else return CopyFileAtts(src, dst, statBufPtr); -#endif default: return TclUnixCopyFile(src, dst, statBufPtr, 0); } @@ -640,11 +629,6 @@ TclUnixCopyFile( return TCL_ERROR; } if (!dontCopyAtts && CopyFileAtts(src, dst, statBufPtr) == TCL_ERROR) { -#ifdef ANDROID - if (errno == EPERM) { - return TCL_OK; - } -#endif /* * The copy succeeded, but setting the permissions failed, so be in a * consistent state, we remove the file that was created by the copy. @@ -1219,11 +1203,6 @@ TraversalCopy( Tcl_DStringValue(dstPtr), statBufPtr) == TCL_OK) { return TCL_OK; } -#ifdef ANDROID - if (errno == EPERM) { - return TCL_OK; - } -#endif break; } diff --git a/unix/tclUnixInit.c b/unix/tclUnixInit.c index 5e4ef0a..5fc0035 100644 --- a/unix/tclUnixInit.c +++ b/unix/tclUnixInit.c @@ -583,14 +583,10 @@ TclpInitLibraryPath( void TclpSetInitialEncodings(void) { -#ifdef ANDROID - Tcl_SetSystemEncoding(NULL, "utf-8"); -#else Tcl_DString encodingName; Tcl_SetSystemEncoding(NULL, Tcl_GetEncodingNameFromEnvironment(&encodingName)); Tcl_DStringFree(&encodingName); -#endif } void diff --git a/win/makefile.vc b/win/makefile.vc index 82dd655..2e04f15 100644 --- a/win/makefile.vc +++ b/win/makefile.vc @@ -344,7 +344,8 @@ COREOBJS = \ $(TMP_DIR)\tclUtf.obj \ $(TMP_DIR)\tclUtil.obj \ $(TMP_DIR)\tclVar.obj \ - $(TMP_DIR)\tclZlib.obj + $(TMP_DIR)\tclZlib.obj \ + $(TMP_DIR)\zipfs.obj ZLIBOBJS = \ $(TMP_DIR)\adler32.obj \ @@ -942,6 +943,9 @@ $(TMP_DIR)\tclWinTest.obj: $(WINDIR)\tclWinTest.c $(TMP_DIR)\tclZlib.obj: $(GENERICDIR)\tclZlib.c $(cc32) $(TCL_CFLAGS) -I$(COMPATDIR)\zlib -DBUILD_tcl -Fo$@ $? +$(TMP_DIR)\zipfs.obj: $(GENERICDIR)\zipfs.c + $(cc32) $(TCL_CFLAGS) -I$(COMPATDIR)\zlib -DBUILD_tcl -Fo$@ $? + $(TMP_DIR)\tclPkgConfig.obj: $(GENERICDIR)\tclPkgConfig.c $(cc32) -DBUILD_tcl $(TCL_CFLAGS) \ -DCFG_INSTALL_LIBDIR="\"$(LIB_INSTALL_DIR:\=\\)\"" \ -- cgit v0.12 From 1c3288f038d8b2f9883e3b9f63f37f42e6811969 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Mon, 21 Dec 2015 11:59:08 +0000 Subject: Finally, make it compile warning-free using Visual Studio, if ZIPFS_IN_TCL is defined --- generic/zipfs.c | 17 ++++++++--------- win/makefile.vc | 2 +- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/generic/zipfs.c b/generic/zipfs.c index 67390a6..6179542 100644 --- a/generic/zipfs.c +++ b/generic/zipfs.c @@ -9,6 +9,9 @@ * this file, and for a DISCLAIMER OF ALL WARRANTIES. */ +#include "tclInt.h" +#include "tclFileSystem.h" +#include "tclZipfs.h" #if !defined(_WIN32) && !defined(_WIN64) #include #endif @@ -18,15 +21,10 @@ #include #include #include + #ifdef HAVE_ZLIB #include "zlib.h" #include "zcrypt.h" -#endif -#include "tclInt.h" -#include "tclFileSystem.h" -#include "tclZipfs.h" - -#ifdef HAVE_ZLIB /* * Various constants and offsets found in ZIP archive files. @@ -2904,6 +2902,7 @@ cerror0: z_stream stream; int err; unsigned char *ubuf = NULL; + unsigned int j; memset(&stream, 0, sizeof (stream)); stream.zalloc = Z_NULL; @@ -2917,9 +2916,9 @@ cerror0: info->ubuf = NULL; goto merror; } - for (i = 0; i < stream.avail_in; i++) { - ch = info->ubuf[i]; - ubuf[i] = zdecode(info->keys, crc32tab, ch); + for (j = 0; j < stream.avail_in; j++) { + ch = info->ubuf[j]; + ubuf[j] = zdecode(info->keys, crc32tab, ch); } stream.next_in = ubuf; } else { diff --git a/win/makefile.vc b/win/makefile.vc index 2e04f15..80682b9 100644 --- a/win/makefile.vc +++ b/win/makefile.vc @@ -504,7 +504,7 @@ crt = -MT !endif TCL_INCLUDES = -I"$(WINDIR)" -I"$(GENERICDIR)" -I"$(TOMMATHDIR)" -TCL_DEFINES = -DTCL_TOMMATH -DMP_PREC=4 -Dinline=__inline -DHAVE_ZLIB=1 +TCL_DEFINES = -DTCL_TOMMATH -DMP_PREC=4 -Dinline=__inline -DHAVE_ZLIB=1 -DZIPFS_IN_TCL BASE_CFLAGS = $(cflags) $(cdebug) $(crt) $(TCL_INCLUDES) $(TCL_DEFINES) CON_CFLAGS = $(cflags) $(cdebug) $(crt) -DCONSOLE TCL_CFLAGS = $(BASE_CFLAGS) $(OPTDEFINES) -- cgit v0.12 From 63b07461da87c89858482b065e62b2d31d765c40 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Mon, 21 Dec 2015 12:43:54 +0000 Subject: Fix android compilation (zipfsFilesystem.loadFileProc is a constant, so it cannot be written) --- generic/zipfs.c | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/generic/zipfs.c b/generic/zipfs.c index 6179542..b54d5a2 100644 --- a/generic/zipfs.c +++ b/generic/zipfs.c @@ -2807,7 +2807,7 @@ merror0: stream.opaque = Z_NULL; stream.avail_in = z->nbytecompr; if (z->isenc) { - unsigned int j; + unsigned int j; stream.avail_in -= 12; cbuf = (unsigned char *) Tcl_AttemptAlloc(stream.avail_in); @@ -3734,7 +3734,6 @@ Zip_FSFilesystemPathTypeProc(Tcl_Obj *pathPtr) return Tcl_NewStringObj("zip", -1); } -#ifndef ANDROID /* *------------------------------------------------------------------------- @@ -3762,6 +3761,14 @@ static int Zip_FSLoadFile(Tcl_Interp *interp, Tcl_Obj *path, Tcl_LoadHandle *loadHandle, Tcl_FSUnloadFileProc **unloadProcPtr, int flags) { +#ifdef ANDROID + /* + * Force loadFileProc to native implementation since the + * package manger already extracted the shared libraries + * from the APK at install time. + */ + return tclNativeFilesystem.loadFileProc(interp, path, loadHandle, unloadProcPtr, flags); +#else Tcl_FSLoadFileProc2 *loadFileProc; Tcl_Obj *altPath = NULL; int ret = -1; @@ -3813,8 +3820,8 @@ Zip_FSLoadFile(Tcl_Interp *interp, Tcl_Obj *path, Tcl_LoadHandle *loadHandle, Tcl_DecrRefCount(altPath); } return ret; -} #endif +} /* @@ -3852,11 +3859,7 @@ const Tcl_Filesystem zipfsFilesystem = { NULL, /* renameFileProc */ NULL, /* copyDirectoryProc */ NULL, /* lstatProc */ -#ifdef ANDROID - NULL, /* loadFileProc */ -#else (Tcl_FSLoadFileProc *) Zip_FSLoadFile, -#endif NULL, /* getCwdProc */ Zip_FSChdirProc, }; @@ -3922,14 +3925,6 @@ Zipfs_doInit(Tcl_Interp *interp, int safe) Tcl_ConditionWait(&ZipFSCond, &ZipFSMutex, &t); Tcl_MutexUnlock(&ZipFSMutex); #endif -#ifdef ANDROID - /* - * Force loadFileProc to native implementation since the - * package manger already extracted the shared libraries - * from the APK at install time. - */ - zipfsFilesystem.loadFileProc = tclNativeFilesystem.loadFileProc; -#endif Tcl_FSRegister(NULL, &zipfsFilesystem); Tcl_InitHashTable(&ZipFS.fileHash, TCL_STRING_KEYS); Tcl_InitHashTable(&ZipFS.zipHash, TCL_STRING_KEYS); -- cgit v0.12 From 56c5833c4ab4b228c29eb2ade13ba727e1e45da5 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Mon, 21 Dec 2015 14:01:57 +0000 Subject: Eliminate all use of ZIPFS_IN_TCL --- generic/tclIOUtil.c | 6 ------ generic/tclZipfs.h | 25 ++++--------------------- generic/zipfs.c | 42 +++++++++++++++++++----------------------- win/makefile.vc | 2 +- 4 files changed, 24 insertions(+), 51 deletions(-) diff --git a/generic/tclIOUtil.c b/generic/tclIOUtil.c index 0ef6d3b..79ec894 100644 --- a/generic/tclIOUtil.c +++ b/generic/tclIOUtil.c @@ -191,9 +191,7 @@ const Tcl_Filesystem tclNativeFilesystem = { TclpObjChdir }; -#ifdef ZIPFS_IN_TCL MODULE_SCOPE Tcl_Filesystem zipfsFilesystem; -#endif /* * Define the tail of the linked list. Note that for unconventional uses of @@ -1415,7 +1413,6 @@ TclFSNormalizeToUniquePath( Claim(); for (fsRecPtr=firstFsRecPtr; fsRecPtr!=NULL; fsRecPtr=fsRecPtr->nextPtr) { -#ifdef ZIPFS_IN_TCL if (fsRecPtr->fsPtr == &zipfsFilesystem) { ClientData clientData = NULL; /* @@ -1432,7 +1429,6 @@ TclFSNormalizeToUniquePath( } continue; } -#endif if (fsRecPtr->fsPtr != &tclNativeFilesystem) { continue; } @@ -1457,11 +1453,9 @@ TclFSNormalizeToUniquePath( if (fsRecPtr->fsPtr == &tclNativeFilesystem) { continue; } -#ifdef ZIPFS_IN_TCL if (fsRecPtr->fsPtr == &zipfsFilesystem) { continue; } -#endif if (fsRecPtr->fsPtr->normalizePathProc != NULL) { startAt = fsRecPtr->fsPtr->normalizePathProc(interp, pathPtr, diff --git a/generic/tclZipfs.h b/generic/tclZipfs.h index 75dcb13..bcf6cef 100644 --- a/generic/tclZipfs.h +++ b/generic/tclZipfs.h @@ -22,33 +22,16 @@ extern "C" { # define ZIPFSAPI extern #endif -#ifdef ZIPFS_IN_TK -#define Zipfs_Mount Tkzipfs_Mount -#define Zipfs_Unmount Tkzipfs_Unmount -#define Zipfs_Init Tkzipfs_Init -#define Zipfs_SafeInit Tkzipfs_SafeInit -#ifdef BUILD_tk -# undef ZIPFSAPI -# define ZIPFSAPI DLLEXPORT -#endif -#endif - -#ifdef ZIPFS_IN_TCL -#define Zipfs_Mount Tclzipfs_Mount -#define Zipfs_Unmount Tclzipfs_Unmount -#define Zipfs_Init Tclzipfs_Init -#define Zipfs_SafeInit Tclzipfs_SafeInit #ifdef BUILD_tcl # undef ZIPFSAPI # define ZIPFSAPI DLLEXPORT #endif -#endif -ZIPFSAPI int Zipfs_Mount(Tcl_Interp *interp, const char *zipname, +ZIPFSAPI int Tclzipfs_Mount(Tcl_Interp *interp, const char *zipname, const char *mntpt, const char *passwd); -ZIPFSAPI int Zipfs_Unmount(Tcl_Interp *interp, const char *zipname); -ZIPFSAPI int Zipfs_Init(Tcl_Interp *interp); -ZIPFSAPI int Zipfs_SafeInit(Tcl_Interp *interp); +ZIPFSAPI int Tclzipfs_Unmount(Tcl_Interp *interp, const char *zipname); +ZIPFSAPI int Tclzipfs_Init(Tcl_Interp *interp); +ZIPFSAPI int Tclzipfs_SafeInit(Tcl_Interp *interp); #ifdef __cplusplus } diff --git a/generic/zipfs.c b/generic/zipfs.c index b54d5a2..144be30 100644 --- a/generic/zipfs.c +++ b/generic/zipfs.c @@ -1031,7 +1031,7 @@ error: /* *------------------------------------------------------------------------- * - * Zipfs_Mount -- + * Tclzipfs_Mount -- * * This procedure is invoked to mount a given ZIP archive file on * a given mountpoint with optional ZIP password. @@ -1047,7 +1047,7 @@ error: */ int -Zipfs_Mount(Tcl_Interp *interp, const char *zipname, const char *mntpt, +Tclzipfs_Mount(Tcl_Interp *interp, const char *zipname, const char *mntpt, const char *passwd) { char *realname, *p; @@ -1404,7 +1404,7 @@ nextent: /* *------------------------------------------------------------------------- * - * Zipfs_Unmount -- + * Tclzipfs_Unmount -- * * This procedure is invoked to unmount a given ZIP archive. * @@ -1418,7 +1418,7 @@ nextent: */ int -Zipfs_Unmount(Tcl_Interp *interp, const char *zipname) +Tclzipfs_Unmount(Tcl_Interp *interp, const char *zipname) { char *realname; ZipFile *zf; @@ -1509,7 +1509,7 @@ ZipFSMountCmd(ClientData clientData, Tcl_Interp *interp, " ?zipfile ?mountpoint? ?password???\"", 0); return TCL_ERROR; } - return Zipfs_Mount(interp, (argc > 1) ? argv[1] : NULL, + return Tclzipfs_Mount(interp, (argc > 1) ? argv[1] : NULL, (argc > 2) ? argv[2] : NULL, (argc > 3) ? argv[3] : NULL); } @@ -1539,7 +1539,7 @@ ZipFSUnmountCmd(ClientData clientData, Tcl_Interp *interp, " zipfile\"", (char *) NULL); return TCL_ERROR; } - return Zipfs_Unmount(interp, argv[1]); + return Tclzipfs_Unmount(interp, argv[1]); } /* @@ -3870,7 +3870,7 @@ const Tcl_Filesystem zipfsFilesystem = { /* *------------------------------------------------------------------------- * - * Zipfs_doInit -- + * doInit -- * * Perform per interpreter initialization of this module. * @@ -3885,7 +3885,7 @@ const Tcl_Filesystem zipfsFilesystem = { */ static int -Zipfs_doInit(Tcl_Interp *interp, int safe) +doInit(Tcl_Interp *interp, int safe) { #ifdef HAVE_ZLIB static const char findproc[] = @@ -3929,14 +3929,10 @@ Zipfs_doInit(Tcl_Interp *interp, int safe) Tcl_InitHashTable(&ZipFS.fileHash, TCL_STRING_KEYS); Tcl_InitHashTable(&ZipFS.zipHash, TCL_STRING_KEYS); ZipFS.initialized = ZipFS.idCount = 1; -#if defined(ZIPFS_IN_TCL) || defined(ZIPFS_IN_TK) - Tcl_StaticPackage(interp, "zipfs", Zipfs_Init, Zipfs_SafeInit); -#endif + Tcl_StaticPackage(interp, "zipfs", Tclzipfs_Init, Tclzipfs_SafeInit); } Unlock(); -#if !defined(ZIPFS_IN_TCL) && !defined(ZIPFS_IN_TK) Tcl_PkgProvide(interp, "zipfs", "1.0"); -#endif if (!safe) { Tcl_CreateCommand(interp, "::zipfs::mount", ZipFSMountCmd, 0, 0); Tcl_CreateCommand(interp, "::zipfs::unmount", ZipFSUnmountCmd, 0, 0); @@ -3964,7 +3960,7 @@ Zipfs_doInit(Tcl_Interp *interp, int safe) /* *------------------------------------------------------------------------- * - * Zipfs_Init, Zipfs_SafeInit -- + * Tclzipfs_Init, Tclzipfs_SafeInit -- * * These functions are invoked to perform per interpreter initialization * of this module. @@ -3980,15 +3976,15 @@ Zipfs_doInit(Tcl_Interp *interp, int safe) */ int -Zipfs_Init(Tcl_Interp *interp) +Tclzipfs_Init(Tcl_Interp *interp) { - return Zipfs_doInit(interp, 0); + return doInit(interp, 0); } int -Zipfs_SafeInit(Tcl_Interp *interp) +Tclzipfs_SafeInit(Tcl_Interp *interp) { - return Zipfs_doInit(interp, 1); + return doInit(interp, 1); } #ifndef HAVE_ZLIB @@ -3996,7 +3992,7 @@ Zipfs_SafeInit(Tcl_Interp *interp) /* *------------------------------------------------------------------------- * - * Zipfs_Mount, Zipfs_Unmount -- + * Tclzipfs_Mount, Tclzipfs_Unmount -- * * Dummy version when no ZLIB support available. * @@ -4004,16 +4000,16 @@ Zipfs_SafeInit(Tcl_Interp *interp) */ int -Zipfs_Mount(Tcl_Interp *interp, const char *zipname, const char *mntpt, +Tclzipfs_Mount(Tcl_Interp *interp, const char *zipname, const char *mntpt, const char *passwd) { - return Zipfs_doInit(interp, 1); + return doInit(interp, 1); } int -Zipfs_Unmount(Tcl_Interp *interp, const char *zipname) +Tclzipfs_Unmount(Tcl_Interp *interp, const char *zipname) { - return Zipfs_doInit(interp, 1); + return doInit(interp, 1); } #endif diff --git a/win/makefile.vc b/win/makefile.vc index 80682b9..2e04f15 100644 --- a/win/makefile.vc +++ b/win/makefile.vc @@ -504,7 +504,7 @@ crt = -MT !endif TCL_INCLUDES = -I"$(WINDIR)" -I"$(GENERICDIR)" -I"$(TOMMATHDIR)" -TCL_DEFINES = -DTCL_TOMMATH -DMP_PREC=4 -Dinline=__inline -DHAVE_ZLIB=1 -DZIPFS_IN_TCL +TCL_DEFINES = -DTCL_TOMMATH -DMP_PREC=4 -Dinline=__inline -DHAVE_ZLIB=1 BASE_CFLAGS = $(cflags) $(cdebug) $(crt) $(TCL_INCLUDES) $(TCL_DEFINES) CON_CFLAGS = $(cflags) $(cdebug) $(crt) -DCONSOLE TCL_CFLAGS = $(BASE_CFLAGS) $(OPTDEFINES) -- cgit v0.12 From 3c03a492f903c82b544cd54fb5b8f2e2e374a150 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Mon, 21 Dec 2015 15:21:21 +0000 Subject: Start with a few simple basic test-cases --- generic/zipfs.c | 13 +++-------- tests/zipfs.test | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ unix/tclAppInit.c | 5 +++++ win/tclAppInit.c | 5 +++++ 4 files changed, 80 insertions(+), 10 deletions(-) create mode 100644 tests/zipfs.test diff --git a/generic/zipfs.c b/generic/zipfs.c index 144be30..3c330b2 100644 --- a/generic/zipfs.c +++ b/generic/zipfs.c @@ -3761,15 +3761,15 @@ static int Zip_FSLoadFile(Tcl_Interp *interp, Tcl_Obj *path, Tcl_LoadHandle *loadHandle, Tcl_FSUnloadFileProc **unloadProcPtr, int flags) { + Tcl_FSLoadFileProc2 *loadFileProc = (Tcl_FSLoadFileProc2 *) tclNativeFilesystem.loadFileProc; #ifdef ANDROID /* * Force loadFileProc to native implementation since the * package manger already extracted the shared libraries * from the APK at install time. */ - return tclNativeFilesystem.loadFileProc(interp, path, loadHandle, unloadProcPtr, flags); + return loadFileProc(interp, path, loadHandle, unloadProcPtr, flags); #else - Tcl_FSLoadFileProc2 *loadFileProc; Tcl_Obj *altPath = NULL; int ret = -1; @@ -3810,7 +3810,6 @@ Zip_FSLoadFile(Tcl_Interp *interp, Tcl_Obj *path, Tcl_LoadHandle *loadHandle, Tcl_DecrRefCount(objs[1]); } } - loadFileProc = (Tcl_FSLoadFileProc2 *) tclNativeFilesystem.loadFileProc; if (loadFileProc != NULL) { ret = loadFileProc(interp, path, loadHandle, unloadProcPtr, flags); } else { @@ -3885,8 +3884,7 @@ const Tcl_Filesystem zipfsFilesystem = { */ static int -doInit(Tcl_Interp *interp, int safe) -{ +doInit(Tcl_Interp *interp, int safe) { #ifdef HAVE_ZLIB static const char findproc[] = "proc ::zipfs::find dir {\n" @@ -3907,11 +3905,6 @@ doInit(Tcl_Interp *interp, int safe) " return [lsort $result]\n" "}\n"; -#ifdef USE_TCL_STUBS - if (Tcl_InitStubs(interp, "8.0", 0) == NULL) { - return TCL_ERROR; - } -#endif /* one-time initialization */ WriteLock(); if (!ZipFS.initialized) { diff --git a/tests/zipfs.test b/tests/zipfs.test new file mode 100644 index 0000000..e8112f5 --- /dev/null +++ b/tests/zipfs.test @@ -0,0 +1,67 @@ +# The file tests the tclZlib.c file. +# +# This file contains a collection of tests for one or more of the Tcl built-in +# commands. Sourcing this file into Tcl runs the tests and generates output +# for errors. No output means no errors were found. +# +# Copyright (c) 1996-1998 by Sun Microsystems, Inc. +# Copyright (c) 1998-1999 by Scriptics Corporation. +# +# See the file "license.terms" for information on usage and redistribution of +# this file, and for a DISCLAIMER OF ALL WARRANTIES. + +if {"::tcltest" ni [namespace children]} { + package require tcltest 2.1 + namespace import -force ::tcltest::* +} + +testConstraint zlib [llength [info commands zlib]] + +test zipfs-1.1 {zipfs basics} -constraints zlib -body { + load {} zipfs + package require zipfs +} -result {1.0} + +test zipfs-1.2 {zipfs basics} -constraints zlib -returnCodes error -body { + ::zipfs::mount a b c d e f +} -result {wrong # args: should be "::zipfs::mount ?zipfile ?mountpoint? ?password???"} + +test zipfs-1.3 {zipfs basics} -constraints zlib -returnCodes error -body { + ::zipfs::unmount a b c d e f +} -result {wrong # args: should be "::zipfs::unmount zipfile"} + +test zipfs-1.4 {zipfs basics} -constraints zlib -returnCodes error -body { + ::zipfs::mkkey a b c d e f +} -result {wrong # args: should be "::zipfs::mkkey password"} + +test zipfs-1.5 {zipfs basics} -constraints zlib -returnCodes error -body { + ::zipfs::mkimg a b c d e f +} -result {wrong # args: should be "::zipfs::mkimg outfile indir ?strip? ?password? ?infile?"} + +test zipfs-1.6 {zipfs basics} -constraints zlib -returnCodes error -body { + ::zipfs::mkzip a b c d e f +} -result {wrong # args: should be "::zipfs::mkzip outfile indir ?strip? ?password?"} + +test zipfs-1.7 {zipfs basics} -constraints zlib -returnCodes error -body { + ::zipfs::exists a b c d e f +} -result {wrong # args: should be "::zipfs::exists filename"} + +test zipfs-1.8 {zipfs basics} -constraints zlib -returnCodes error -body { + ::zipfs::info a b c d e f +} -result {wrong # args: should be "::zipfs::info filename"} + +test zipfs-1.9 {zipfs basics} -constraints zlib -returnCodes error -body { + ::zipfs::list a b c d e f +} -result {wrong # args: should be "::zipfs::list ?(-glob|-regexp)? ?pattern?"} + + + + + + +::tcltest::cleanupTests +return + +# Local Variables: +# mode: tcl +# End: diff --git a/unix/tclAppInit.c b/unix/tclAppInit.c index 9bbc88b..40b10f3 100644 --- a/unix/tclAppInit.c +++ b/unix/tclAppInit.c @@ -17,6 +17,7 @@ #include "tcl.h" #ifdef TCL_TEST +#include "tclZipfs.h" extern Tcl_PackageInitProc Tcltest_Init; extern Tcl_PackageInitProc Tcltest_SafeInit; #endif /* TCL_TEST */ @@ -123,6 +124,10 @@ Tcl_AppInit( return TCL_ERROR; } Tcl_StaticPackage(interp, "Tcltest", Tcltest_Init, Tcltest_SafeInit); + if (Tclzipfs_Init(interp) == TCL_ERROR) { + return TCL_ERROR; + } + Tcl_StaticPackage(interp, "zipfs", Tclzipfs_Init, Tclzipfs_SafeInit); #endif /* TCL_TEST */ /* diff --git a/win/tclAppInit.c b/win/tclAppInit.c index e06eaf5..b821ca7 100644 --- a/win/tclAppInit.c +++ b/win/tclAppInit.c @@ -25,6 +25,7 @@ #include #ifdef TCL_TEST +#include "tclZipfs.h" extern Tcl_PackageInitProc Tcltest_Init; extern Tcl_PackageInitProc Tcltest_SafeInit; #endif /* TCL_TEST */ @@ -174,6 +175,10 @@ Tcl_AppInit( return TCL_ERROR; } Tcl_StaticPackage(interp, "Tcltest", Tcltest_Init, Tcltest_SafeInit); + if (Tclzipfs_Init(interp) == TCL_ERROR) { + return TCL_ERROR; + } + Tcl_StaticPackage(interp, "zipfs", Tclzipfs_Init, Tclzipfs_SafeInit); #endif /* TCL_TEST */ /* -- cgit v0.12 From a03e74efc1bbec20a5c2488448a8de28d9fb28fb Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Mon, 21 Dec 2015 21:25:40 +0000 Subject: USE_TCL_STUBS is not defined anyway --- generic/zipfs.c | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/generic/zipfs.c b/generic/zipfs.c index 3c330b2..1f126ce 100644 --- a/generic/zipfs.c +++ b/generic/zipfs.c @@ -12,6 +12,7 @@ #include "tclInt.h" #include "tclFileSystem.h" #include "tclZipfs.h" + #if !defined(_WIN32) && !defined(_WIN64) #include #endif @@ -2771,6 +2772,7 @@ merror0: } else { if (z->data != NULL) { unsigned int j = z->nbyte; + if (j > info->nmax) { j = info->nmax; } @@ -2808,6 +2810,7 @@ merror0: stream.avail_in = z->nbytecompr; if (z->isenc) { unsigned int j; + stream.avail_in -= 12; cbuf = (unsigned char *) Tcl_AttemptAlloc(stream.avail_in); @@ -3761,14 +3764,20 @@ static int Zip_FSLoadFile(Tcl_Interp *interp, Tcl_Obj *path, Tcl_LoadHandle *loadHandle, Tcl_FSUnloadFileProc **unloadProcPtr, int flags) { - Tcl_FSLoadFileProc2 *loadFileProc = (Tcl_FSLoadFileProc2 *) tclNativeFilesystem.loadFileProc; + Tcl_FSLoadFileProc2 *loadFileProc; #ifdef ANDROID - /* - * Force loadFileProc to native implementation since the - * package manger already extracted the shared libraries - * from the APK at install time. - */ - return loadFileProc(interp, path, loadHandle, unloadProcPtr, flags); + /* + * Force loadFileProc to native implementation since the + * package manger already extracted the shared libraries + * from the APK at install time. + */ + + loadFileProc = (Tcl_FSLoadFileProc2 *) tclNativeFilesystem.loadFileProc; + if (loadFileProc != NULL) { + return loadFileProc(interp, path, loadHandle, unloadProcPtr, flags); + } + Tcl_SetErrno(ENOENT); + return -1; #else Tcl_Obj *altPath = NULL; int ret = -1; @@ -3810,6 +3819,7 @@ Zip_FSLoadFile(Tcl_Interp *interp, Tcl_Obj *path, Tcl_LoadHandle *loadHandle, Tcl_DecrRefCount(objs[1]); } } + loadFileProc = (Tcl_FSLoadFileProc2 *) tclNativeFilesystem.loadFileProc; if (loadFileProc != NULL) { ret = loadFileProc(interp, path, loadHandle, unloadProcPtr, flags); } else { @@ -3869,7 +3879,7 @@ const Tcl_Filesystem zipfsFilesystem = { /* *------------------------------------------------------------------------- * - * doInit -- + * Zipfs_doInit -- * * Perform per interpreter initialization of this module. * @@ -3884,7 +3894,8 @@ const Tcl_Filesystem zipfsFilesystem = { */ static int -doInit(Tcl_Interp *interp, int safe) { +Zipfs_doInit(Tcl_Interp *interp, int safe) +{ #ifdef HAVE_ZLIB static const char findproc[] = "proc ::zipfs::find dir {\n" @@ -3971,13 +3982,13 @@ doInit(Tcl_Interp *interp, int safe) { int Tclzipfs_Init(Tcl_Interp *interp) { - return doInit(interp, 0); + return Zipfs_doInit(interp, 0); } int Tclzipfs_SafeInit(Tcl_Interp *interp) { - return doInit(interp, 1); + return Zipfs_doInit(interp, 1); } #ifndef HAVE_ZLIB @@ -3996,13 +4007,13 @@ int Tclzipfs_Mount(Tcl_Interp *interp, const char *zipname, const char *mntpt, const char *passwd) { - return doInit(interp, 1); + return Zipfs_doInit(interp, 1); } int Tclzipfs_Unmount(Tcl_Interp *interp, const char *zipname) { - return doInit(interp, 1); + return Zipfs_doInit(interp, 1); } #endif -- cgit v0.12 From 299924e512e6809f22f5fa3e4410fcc706ceec82 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Tue, 22 Dec 2015 09:11:57 +0000 Subject: Remove TIP #414 fragment, not strictly needed for the zipfs TIP. Add more zipfs test-cases --- generic/tcl.h | 7 ----- generic/tclEncoding.c | 23 +++------------- tests/zipfs.test | 73 ++++++++++++++++++++++++++++++++++++++++++--------- 3 files changed, 64 insertions(+), 39 deletions(-) diff --git a/generic/tcl.h b/generic/tcl.h index fed6b78..a08edde 100644 --- a/generic/tcl.h +++ b/generic/tcl.h @@ -2424,13 +2424,6 @@ const char * TclTomMathInitializeStubs(Tcl_Interp *interp, * TODO - tommath stubs export goes here! */ -/* Tcl_InitSubsystems, see TIP #414 */ - -#ifndef USE_TCL_STUBS -EXTERN const char * Tcl_InitSubsystems(TCL_NORETURN1 - Tcl_PanicProc *panicProc); -#endif - /* * Public functions that are not accessible via the stubs table. * Tcl_GetMemoryInfo is needed for AOLserver. [Bug 1868171] diff --git a/generic/tclEncoding.c b/generic/tclEncoding.c index 4020445..4edebcf 100644 --- a/generic/tclEncoding.c +++ b/generic/tclEncoding.c @@ -1440,10 +1440,10 @@ Tcl_UtfToExternal( /* *--------------------------------------------------------------------------- * - * Tcl_InitSubsystems/Tcl_FindExecutable -- + * Tcl_FindExecutable -- * - * This function initializes everything needed for the Tcl library - * to be able to operate. + * This function computes the absolute path name of the current + * application, given its argv[0] value. * * Results: * None. @@ -1454,23 +1454,6 @@ Tcl_UtfToExternal( * *--------------------------------------------------------------------------- */ -MODULE_SCOPE const TclStubs tclStubs; - -static const struct { - const TclStubs *stubs; - const char version[16]; -} stubInfo = { - &tclStubs, TCL_PATCH_LEVEL -}; - -const char * -Tcl_InitSubsystems(TCL_NORETURN1 Tcl_PanicProc *panicProc) -{ - Tcl_SetPanicProc(panicProc); - TclInitSubsystems(); - return stubInfo.version; -} - #undef Tcl_FindExecutable void Tcl_FindExecutable( diff --git a/tests/zipfs.test b/tests/zipfs.test index e8112f5..3f53cf8 100644 --- a/tests/zipfs.test +++ b/tests/zipfs.test @@ -15,49 +15,98 @@ if {"::tcltest" ni [namespace children]} { namespace import -force ::tcltest::* } -testConstraint zlib [llength [info commands zlib]] +testConstraint zipfs [expr {[llength [info commands zlib]] && [regexp tcltest [info nameofexecutable]]}] -test zipfs-1.1 {zipfs basics} -constraints zlib -body { +test zipfs-1.1 {zipfs basics} -constraints zipfs -body { load {} zipfs +} -result {} + +test zipfs-1.2 {zipfs basics} -constraints zipfs -body { package require zipfs } -result {1.0} -test zipfs-1.2 {zipfs basics} -constraints zlib -returnCodes error -body { +test zipfs-1.3 {zipfs basics} -constraints zipfs -returnCodes error -body { ::zipfs::mount a b c d e f } -result {wrong # args: should be "::zipfs::mount ?zipfile ?mountpoint? ?password???"} -test zipfs-1.3 {zipfs basics} -constraints zlib -returnCodes error -body { +test zipfs-1.4 {zipfs basics} -constraints zipfs -returnCodes error -body { ::zipfs::unmount a b c d e f } -result {wrong # args: should be "::zipfs::unmount zipfile"} -test zipfs-1.4 {zipfs basics} -constraints zlib -returnCodes error -body { +test zipfs-1.5 {zipfs basics} -constraints zipfs -returnCodes error -body { ::zipfs::mkkey a b c d e f } -result {wrong # args: should be "::zipfs::mkkey password"} -test zipfs-1.5 {zipfs basics} -constraints zlib -returnCodes error -body { +test zipfs-1.6 {zipfs basics} -constraints zipfs -returnCodes error -body { ::zipfs::mkimg a b c d e f } -result {wrong # args: should be "::zipfs::mkimg outfile indir ?strip? ?password? ?infile?"} -test zipfs-1.6 {zipfs basics} -constraints zlib -returnCodes error -body { +test zipfs-1.7 {zipfs basics} -constraints zipfs -returnCodes error -body { ::zipfs::mkzip a b c d e f } -result {wrong # args: should be "::zipfs::mkzip outfile indir ?strip? ?password?"} -test zipfs-1.7 {zipfs basics} -constraints zlib -returnCodes error -body { +test zipfs-1.8 {zipfs basics} -constraints zipfs -returnCodes error -body { ::zipfs::exists a b c d e f } -result {wrong # args: should be "::zipfs::exists filename"} -test zipfs-1.8 {zipfs basics} -constraints zlib -returnCodes error -body { +test zipfs-1.9 {zipfs basics} -constraints zipfs -returnCodes error -body { ::zipfs::info a b c d e f } -result {wrong # args: should be "::zipfs::info filename"} -test zipfs-1.9 {zipfs basics} -constraints zlib -returnCodes error -body { +test zipfs-1.10 {zipfs basics} -constraints zipfs -returnCodes error -body { ::zipfs::list a b c d e f } -result {wrong # args: should be "::zipfs::list ?(-glob|-regexp)? ?pattern?"} +test zipfs-2.1 {zipfs mkzip empty archive} -constraints zipfs -returnCodes error -body { + ::zipfs::mkzip abc.zip $tcl_library/xxxx +} -result {empty archive} + +test zipfs-2.2 {zipfs mkzip} -constraints zipfs -body { + set pwd [pwd] + cd $tcl_library/encoding + ::zipfs::mkzip abc.zip . + ::zipfs::mount abc.zip /abc + ::zipfs::list -glob /abc/cp850.* +} -cleanup { + cd $pwd +} -result {/abc/cp850.enc} + +test zipfs-2.3 {zipfs unmount} -constraints zipfs -body { + ::zipfs::info /abc/cp850.enc +} -result [list $tcl_library/encoding/abc.zip 1090 527 39434] + +test zipfs-2.4 {zipfs unmount} -constraints zipfs -body { + set f [open /abc/cp850.enc] + read $f +} -result {# Encoding file: cp850, single-byte +S +003F 0 1 +00 +0000000100020003000400050006000700080009000A000B000C000D000E000F +0010001100120013001400150016001700180019001A001B001C001D001E001F +0020002100220023002400250026002700280029002A002B002C002D002E002F +0030003100320033003400350036003700380039003A003B003C003D003E003F +0040004100420043004400450046004700480049004A004B004C004D004E004F +0050005100520053005400550056005700580059005A005B005C005D005E005F +0060006100620063006400650066006700680069006A006B006C006D006E006F +0070007100720073007400750076007700780079007A007B007C007D007E007F +00C700FC00E900E200E400E000E500E700EA00EB00E800EF00EE00EC00C400C5 +00C900E600C600F400F600F200FB00F900FF00D600DC00F800A300D800D70192 +00E100ED00F300FA00F100D100AA00BA00BF00AE00AC00BD00BC00A100AB00BB +2591259225932502252400C100C200C000A9256325512557255D00A200A52510 +25142534252C251C2500253C00E300C3255A25542569256625602550256C00A4 +00F000D000CA00CB00C8013100CD00CE00CF2518250C2588258400A600CC2580 +00D300DF00D400D200F500D500B500FE00DE00DA00DB00D900FD00DD00AF00B4 +00AD00B1201700BE00B600A700F700B800B000A800B700B900B300B225A000A0 +} - - +test zipfs-2.5 {zipfs exists} -constraints zipfs -body { + ::zipfs::unmount abc.zip + ::zipfs::exists /abc/cp850.enc +} -cleanup { + file delete abc.zip +} -result 1 ::tcltest::cleanupTests return -- cgit v0.12 From e9795fb40711ccc9e08e1a60232a31797bf8356a Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Tue, 22 Dec 2015 11:39:28 +0000 Subject: first shot at documentation --- doc/zipfs.3 | 45 +++++++++++++++++++++++++++++++ doc/zipfs.n | 88 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 133 insertions(+) create mode 100644 doc/zipfs.3 create mode 100644 doc/zipfs.n diff --git a/doc/zipfs.3 b/doc/zipfs.3 new file mode 100644 index 0000000..9e031bc --- /dev/null +++ b/doc/zipfs.3 @@ -0,0 +1,45 @@ +'\" +'\" Copyright (c) 2015 Jan Nijtmans +'\" Copyright (c) 2015 Christian Werner +'\" +'\" See the file "license.terms" for information on usage and redistribution +'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. +'\" +.TH Tclzipfs 3 8.7 Tcl "Tcl Library Procedures" +.so man.macros +.BS +.SH NAME +Tclzipfs_Init, Tclzipfs_SafeInit, Tclzipfs_Mount, Tclzipfs_Unmount \- handle ZIP files as VFS +.SH SYNOPSIS +.nf +\fB#include \fR +.sp +int +\fBTclzipfs_Init\fR(\fIinterp\fR) +.sp +int +\fBTclzipfs_SafeInit\fR(\fIinterp\fR) +.sp +int +\fBTclzipfs_Mount\fR(\fIinterp, zipname, mntpt, passwd\fR) +.sp +int +\fBTclzipfs_Unmount\fR(\fIinterp, zipname\fR) +.SH ARGUMENTS +.AS Tcl_Interp **termPtr +.AP Tcl_Interp *interp in +Interpreter in which the zip file system is mounted. The interpreter's result is +modified to hold the result or error message from the script. +.AP "const char" *zipname in +Name of a zipfile. +.AP "const char" *mntpt in +Name of a mount point. +.AP "const char" *passwd in +An (optional) password. +.BE +.SH DESCRIPTION +.PP +TODO +.PP +.SH KEYWORDS +compress, filesystem, zip diff --git a/doc/zipfs.n b/doc/zipfs.n new file mode 100644 index 0000000..16b25e5 --- /dev/null +++ b/doc/zipfs.n @@ -0,0 +1,88 @@ +'\" +'\" Copyright (c) 2015 Jan Nijtmans +'\" Copyright (c) 2015 Christian Werner +'\" +'\" See the file "license.terms" for information on usage and redistribution +'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. +'\" +.TH zipfs n 1.0 Zipfs "zipfs Commands" +.so man.macros +.BS +'\" Note: do not modify the .SH NAME line immediately below! +.SH NAME +zipfs \- Mount and work with ZIP files within Tcl +.SH SYNOPSIS +.nf +\fBpackage require zipfs \fR?\fB1.0\fR? +.sp +\fB::zipfs::exists\fR \fIfilename\fR +\fB::zipfs::find\fR \fIdir\fR +\fB::zipfs::info\fR \fIfilename\fR +\fB::zipfs::list\fR \fB?(-glob|-regexp)?\fR \fI?pattern?\fR +\fB::zipfs::mkimg\fR \fIoutfile\fR \fIindir\fR \fI?strip?\fR \fI?password?\fR \fI?infile?\fR +\fB::zipfs::mkkey\fR \fIpassword\fR +\fB::zipfs::mkzip\fR \fIoutfile\fR \fIindir\fR \fI?strip?\fR \fI?password?\fR +\fB::zipfs::mount\fR \fI?zipfile\fR \fI?mountpoint?\fR \fI?password?\fR +\fB::zipfs::unmount\fR \fIzipfile\fR +.fi +.BE +.SH DESCRIPTION +.PP +The \fBzipfs\fR package provides tcl with the ability to mount +the contents of a zip file as a virtual file system. +.TP +\fB::zipfs::mount ?\fIzipfile\fR? ?\fImountpoint\fR? +. +The \fB::zipfs::mount\fR procedure mounts a zipfile as a VFS. +After this command executes, files contained in \fIzipfile\fR +will appear to Tcl to be regular files at the mount point. +.RS +.PP +With no \fImountpoint\fR, returns the mount point for \fIzipfile\fR. With no \fIzipfile\fR, +return all zipfile/mount pairs. If \fImountpoint\fR is specified as an empty +string, mount on file path. +.RE +.TP +\fB::zipfs::unmount \fIzipfile\fR +. +Unmounts a previously mounted zip, \fIzipfile\fR. +.TP +\fB::zipfs::exists\fR \fIfilename\fR +. +Return 1 if the given filename exists in the mounted zipfs and 0 if it does not. +.TP +\fB::zipfs::info\fR \fIfile\fR +. +Return information about the given file in the mounted zipfs. The information +consists of (1) the name of the ZIP zipfile that contains the file, (2) the +size of the file after decompressions, (3) the compressed size of the file, +and (4) the offset of the compressed data in the zipfile. +.RS +.PP +Note: querying the mount point gives the start of zip data offset in (4), +which can be used to truncate the zip info off an executable. +.RE +.TP +\fB::zipfs::list\fR \fB?(-glob|-regexp)?\fR \fI?pattern?\fR +. +Return a list of all files in the mounted zipfs. The order of the names +in the list is arbitrary. +.TP +\fB::zipfs::mkimg\fR \fIoutfile\fR \fIindir\fR \fI?strip?\fR \fI?password?\fR \fI?infile?\fR +. +TODO +.TP +\fB::zipfs::mkkey\fR \fIpassword\fR +. +TODO +.TP +\fB::zipfs::mkzip\fR \fIoutfile\fR \fIindir\fR \fI?strip?\fR \fI?password?\fR +. +TODO +.SH "SEE ALSO" +tclsh(1), file(n), zlib(n) +.SH "KEYWORDS" +compress, filesystem, zip +'\" Local Variables: +'\" mode: nroff +'\" End: -- cgit v0.12 From a1740d976679e2a4928898a1eddd1dad22f4fd16 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Fri, 1 Jan 2016 16:50:52 +0000 Subject: Make al zipfs command Tcl_Obj-based --- generic/tclZipfs.h | 2 +- generic/zipfs.c | 284 +++++++++++++++++++++++++++++++++-------------------- 2 files changed, 176 insertions(+), 110 deletions(-) diff --git a/generic/tclZipfs.h b/generic/tclZipfs.h index bcf6cef..01c9e96 100644 --- a/generic/tclZipfs.h +++ b/generic/tclZipfs.h @@ -28,7 +28,7 @@ extern "C" { #endif ZIPFSAPI int Tclzipfs_Mount(Tcl_Interp *interp, const char *zipname, - const char *mntpt, const char *passwd); + const char *mntpt, const char *passwd); ZIPFSAPI int Tclzipfs_Unmount(Tcl_Interp *interp, const char *zipname); ZIPFSAPI int Tclzipfs_Init(Tcl_Interp *interp); ZIPFSAPI int Tclzipfs_SafeInit(Tcl_Interp *interp); diff --git a/generic/zipfs.c b/generic/zipfs.c index 1f126ce..55c6d2c 100644 --- a/generic/zipfs.c +++ b/generic/zipfs.c @@ -91,15 +91,15 @@ * Macros to read and write 16 and 32 bit integers from/to ZIP archives. */ -#define zip_read_int(p) \ +#define zip_read_int(p) \ ((p)[0] | ((p)[1] << 8) | ((p)[2] << 16) | ((p)[3] << 24)) -#define zip_read_short(p) \ +#define zip_read_short(p) \ ((p)[0] | ((p)[1] << 8)) -#define zip_write_int(p, v) \ - (p)[0] = (v) & 0xff; (p)[1] = ((v) >> 8) & 0xff; \ +#define zip_write_int(p, v) \ + (p)[0] = (v) & 0xff; (p)[1] = ((v) >> 8) & 0xff; \ (p)[2] = ((v) >> 16) & 0xff; (p)[3] = ((v) >> 24) & 0xff; -#define zip_write_short(p, v) \ +#define zip_write_short(p, v) \ (p)[0] = (v) & 0xff; (p)[1] = ((v) >> 8) & 0xff; /* @@ -1488,7 +1488,7 @@ done: /* *------------------------------------------------------------------------- * - * ZipFSMountCmd -- + * ZipFSMountObjCmd -- * * This procedure is invoked to process the "zipfs::mount" command. * @@ -1502,23 +1502,23 @@ done: */ static int -ZipFSMountCmd(ClientData clientData, Tcl_Interp *interp, - int argc, const char **argv) +ZipFSMountObjCmd(ClientData clientData, Tcl_Interp *interp, + int objc, Tcl_Obj *const objv[]) { - if (argc > 4) { - Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], - " ?zipfile ?mountpoint? ?password???\"", 0); + if (objc > 4) { + Tcl_WrongNumArgs(interp, 1, objv, + "?zipfile mountpoint password?"); return TCL_ERROR; } - return Tclzipfs_Mount(interp, (argc > 1) ? argv[1] : NULL, - (argc > 2) ? argv[2] : NULL, - (argc > 3) ? argv[3] : NULL); + return Tclzipfs_Mount(interp, (objc > 1) ? Tcl_GetString(objv[1]) : NULL, + (objc > 2) ? Tcl_GetString(objv[2]) : NULL, + (objc > 3) ? Tcl_GetString(objv[3]) : NULL); } /* *------------------------------------------------------------------------- * - * ZipFSUnmountCmd -- + * ZipFSUnmountObjCmd -- * * This procedure is invoked to process the "zipfs::unmount" command. * @@ -1532,21 +1532,20 @@ ZipFSMountCmd(ClientData clientData, Tcl_Interp *interp, */ static int -ZipFSUnmountCmd(ClientData clientData, Tcl_Interp *interp, - int argc, const char **argv) +ZipFSUnmountObjCmd(ClientData clientData, Tcl_Interp *interp, + int objc, Tcl_Obj *const objv[]) { - if (argc != 2) { - Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], - " zipfile\"", (char *) NULL); + if (objc != 2) { + Tcl_WrongNumArgs(interp, 1, objv, "zipfile"); return TCL_ERROR; } - return Tclzipfs_Unmount(interp, argv[1]); + return Tclzipfs_Unmount(interp, Tcl_GetString(objv[1])); } /* *------------------------------------------------------------------------- * - * ZipFSMountCmd -- + * ZipFSMkKeyObjCmd -- * * This procedure is invoked to process the "zipfs::mkkey" command. * It produces a rotated password to be embedded into an image file. @@ -1561,28 +1560,28 @@ ZipFSUnmountCmd(ClientData clientData, Tcl_Interp *interp, */ static int -ZipFSMkKeyCmd(ClientData clientData, Tcl_Interp *interp, - int argc, const char **argv) +ZipFSMkKeyObjCmd(ClientData clientData, Tcl_Interp *interp, + int objc, Tcl_Obj *const objv[]) { int len, i = 0; - char pwbuf[264]; + char *pw, pwbuf[264]; - if (argc != 2) { - Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], - " password\"", (char *) NULL); + if (objc != 2) { + Tcl_WrongNumArgs(interp, 1, objv, "password"); return TCL_ERROR; } - len = strlen(argv[1]); + pw = Tcl_GetString(objv[1]); + len = strlen(pw); if (len == 0) { return TCL_OK; } - if ((len > 255) || (strchr(argv[1], 0xff) != NULL)) { + if ((len > 255) || (strchr(pw, 0xff) != NULL)) { Tcl_SetObjResult(interp, Tcl_NewStringObj("illegal password", -1)); return TCL_ERROR; } while (len > 0) { - int ch = argv[1][len - 1]; + int ch = pw[len - 1]; pwbuf[i] = (ch & 0x0f) | pwrot[(ch >> 4) & 0x0f]; i++; @@ -1928,7 +1927,7 @@ seekErr: /* *------------------------------------------------------------------------- * - * ZipFSMkZipOrImgCmd -- + * ZipFSMkZipOrImgObjCmd -- * * This procedure is creates a new ZIP archive file or image file * given output filename, input directory of files to be archived, @@ -1945,75 +1944,107 @@ seekErr: */ static int -ZipFSMkZipOrImgCmd(ClientData clientData, Tcl_Interp *interp, - int isImg, int argc, const char **argv) +ZipFSMkZipOrImgObjCmd(ClientData clientData, Tcl_Interp *interp, + int isImg, int isList, int objc, Tcl_Obj *const objv[]) { Tcl_Channel out; - int len = 0, pwlen = 0, slen = 0, i, count, ret = TCL_ERROR, largc, pos[3]; - const char **largv; - Tcl_DString ds; + int len = 0, pwlen = 0, slen = 0, i, count, ret = TCL_ERROR, lobjc, pos[3]; + Tcl_Obj **lobjv, *list = NULL; ZipEntry *z; Tcl_HashEntry *hPtr; Tcl_HashSearch search; Tcl_HashTable fileHash; - char pwbuf[264], buf[4096]; + char *strip = NULL, *pw = NULL, pwbuf[264], buf[4096]; - if ((argc < 3) || (argc > (isImg ? 6 : 5))) { - Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], - " outfile indir ?strip? ?password?", - isImg ? " ?infile?\"" : "\"", (char *) NULL); - return TCL_ERROR; + if (isList) { + if ((objc < 3) || (objc > (isImg ? 5 : 4))) { + Tcl_WrongNumArgs(interp, 1, objv, isImg ? + "outfile inlist ?password infile?" : + "outfile inlist ?password?"); + return TCL_ERROR; + } + } else { + if ((objc < 3) || (objc > (isImg ? 6 : 5))) { + Tcl_WrongNumArgs(interp, 1, objv, isImg ? + "outfile indir ?strip password infile?" : + "outfile indir ?strip password?"); + return TCL_ERROR; + } } pwbuf[0] = 0; - if (argc > 4) { - pwlen = strlen(argv[4]); - if ((pwlen > 255) || (strchr(argv[4], 0xff) != NULL)) { - Tcl_AppendResult(interp, "illegal password", (char *) NULL); + if (objc > (isList ? 3 : 4)) { + pw = Tcl_GetString(objv[isList ? 3 : 4]); + pwlen = strlen(pw); + if ((pwlen > 255) || (strchr(pw, 0xff) != NULL)) { + Tcl_SetObjResult(interp, + Tcl_NewStringObj("illegal password", -1)); return TCL_ERROR; } } - Tcl_DStringInit(&ds); - Tcl_DStringAppendElement(&ds, "::zipfs::find"); - Tcl_DStringAppendElement(&ds, argv[2]); - if (Tcl_Eval(interp, Tcl_DStringValue(&ds)) != TCL_OK) { - Tcl_DStringFree(&ds); + if (isList) { + list = objv[2]; + Tcl_IncrRefCount(list); + } else { + Tcl_Obj *cmd[3]; + + cmd[1] = Tcl_NewStringObj("::zipfs::find", -1); + cmd[2] = objv[2]; + cmd[0] = Tcl_NewListObj(2, cmd + 1); + Tcl_IncrRefCount(cmd[0]); + if (Tcl_EvalObjEx(interp, cmd[0], TCL_EVAL_DIRECT) != TCL_OK) { + Tcl_DecrRefCount(cmd[0]); + return TCL_ERROR; + } + Tcl_DecrRefCount(cmd[0]); + list = Tcl_GetObjResult(interp); + Tcl_IncrRefCount(list); + } + if (Tcl_ListObjGetElements(interp, list, &lobjc, &lobjv) != TCL_OK) { + Tcl_DecrRefCount(list); return TCL_ERROR; } - Tcl_DStringFree(&ds); - if (Tcl_SplitList(interp, Tcl_GetStringResult(interp), &largc, &largv) - != TCL_OK) { + if (isList && (lobjc % 2)) { + Tcl_DecrRefCount(list); + Tcl_SetObjResult(interp, + Tcl_NewStringObj("need even number of elements", -1)); return TCL_ERROR; } - Tcl_ResetResult(interp); - if (largc == 0) { - Tcl_Free((char *) largv); - Tcl_AppendResult(interp, "empty archive", (char *) NULL); + if (lobjc == 0) { + Tcl_DecrRefCount(list); + Tcl_SetObjResult(interp, Tcl_NewStringObj("empty archive", -1)); return TCL_ERROR; } - out = Tcl_OpenFileChannel(interp, argv[1], "w", 0755); + out = Tcl_OpenFileChannel(interp, Tcl_GetString(objv[1]), "w", 0755); if ((out == NULL) || (Tcl_SetChannelOption(interp, out, "-translation", "binary") != TCL_OK) || (Tcl_SetChannelOption(interp, out, "-encoding", "binary") != TCL_OK)) { + Tcl_DecrRefCount(list); Tcl_Close(interp, out); - Tcl_Free((char *) largv); return TCL_ERROR; } if (isImg) { ZipFile zf0; + const char *imgName; - if (ZipFSOpenArchive(interp, (argc > 5) ? argv[5] : - Tcl_GetNameOfExecutable(), 0, &zf0) != TCL_OK) { + if (isList) { + imgName = (objc > 4) ? Tcl_GetString(objv[4]) : + Tcl_GetNameOfExecutable(); + } else { + imgName = (objc > 5) ? Tcl_GetString(objv[5]) : + Tcl_GetNameOfExecutable(); + } + if (ZipFSOpenArchive(interp, imgName, 0, &zf0) != TCL_OK) { + Tcl_DecrRefCount(list); Tcl_Close(interp, out); - Tcl_Free((char *) largv); return TCL_ERROR; } - if (pwlen && (argc > 4)) { + if ((pw != NULL) && pwlen) { i = 0; len = pwlen; while (len > 0) { - int ch = argv[4][len - 1]; + int ch = pw[len - 1]; pwbuf[i] = (ch & 0x0f) | pwrot[(ch >> 4) & 0x0f]; i++; @@ -2029,9 +2060,9 @@ ZipFSMkZipOrImgCmd(ClientData clientData, Tcl_Interp *interp, } i = Tcl_Write(out, (char *) zf0.data, zf0.baseoffsp); if (i != zf0.baseoffsp) { - Tcl_AppendResult(interp, "write error", (char *) NULL); + Tcl_DecrRefCount(list); + Tcl_SetObjResult(interp, Tcl_NewStringObj("write error", -1)); Tcl_Close(interp, out); - Tcl_Free((char *) largv); ZipFSCloseArchive(interp, &zf0); return TCL_ERROR; } @@ -2040,9 +2071,9 @@ ZipFSMkZipOrImgCmd(ClientData clientData, Tcl_Interp *interp, if (len > 0) { i = Tcl_Write(out, pwbuf, len); if (i != len) { - Tcl_AppendResult(interp, "write error", (char *) NULL); + Tcl_DecrRefCount(list); + Tcl_SetObjResult(interp, Tcl_NewStringObj("write error", -1)); Tcl_Close(interp, out); - Tcl_Free((char *) largv); return TCL_ERROR; } } @@ -2051,18 +2082,25 @@ ZipFSMkZipOrImgCmd(ClientData clientData, Tcl_Interp *interp, } Tcl_InitHashTable(&fileHash, TCL_STRING_KEYS); pos[0] = Tcl_Tell(out); - if (argc > 3) { - slen = strlen(argv[3]); + if (!isList && (objc > 3)) { + strip = Tcl_GetString(objv[3]); + slen = strlen(strip); } - for (i = 0; i < largc; i++) { - const char *name = largv[i]; + for (i = 0; i < lobjc; i += (isList ? 2 : 1)) { + const char *path, *name; - if (slen > 0) { - len = strlen(name); - if ((len <= slen) || (strncmp(argv[3], name, slen) != 0)) { - continue; + path = Tcl_GetString(lobjv[i]); + if (isList) { + name = Tcl_GetString(lobjv[i + 1]); + } else { + name = path; + if (slen > 0) { + len = strlen(name); + if ((len <= slen) || (strncmp(strip, name, slen) != 0)) { + continue; + } + name += slen; } - name += slen; } while (name[0] == '/') { ++name; @@ -2070,23 +2108,28 @@ ZipFSMkZipOrImgCmd(ClientData clientData, Tcl_Interp *interp, if (name[0] == '\0') { continue; } - if (ZipAddFile(interp, largv[i], name, out, - (pwlen > 0) ? argv[4] : NULL, buf, sizeof (buf), &fileHash) - != TCL_OK) { + if (ZipAddFile(interp, path, name, out, pw, buf, sizeof (buf), + &fileHash) != TCL_OK) { goto done; } } pos[1] = Tcl_Tell(out); count = 0; - for (i = 0; i < largc; i++) { - const char *name = largv[i]; + for (i = 0; i < lobjc; i += (isList ? 2 : 1)) { + const char *path, *name; - if (slen > 0) { - len = strlen(name); - if ((len <= slen) || (strncmp(argv[3], name, slen) != 0)) { - continue; + path = Tcl_GetString(lobjv[i]); + if (isList) { + name = Tcl_GetString(lobjv[i + 1]); + } else { + name = path; + if (slen > 0) { + len = strlen(name); + if ((len <= slen) || (strncmp(strip, name, slen) != 0)) { + continue; + } + name += slen; } - name += slen; } while (name[0] == '/') { ++name; @@ -2117,10 +2160,10 @@ ZipFSMkZipOrImgCmd(ClientData clientData, Tcl_Interp *interp, zip_write_short(buf + ZIP_CENTRAL_IATTR_OFFS, 0); zip_write_int(buf + ZIP_CENTRAL_EATTR_OFFS, 0); zip_write_int(buf + ZIP_CENTRAL_LOCALHDR_OFFS, z->offset - pos[0]); - memcpy(buf + ZIP_CENTRAL_HEADER_LEN, z->name, len); - len += ZIP_CENTRAL_HEADER_LEN; - if (Tcl_Write(out, buf, len) != len) { - Tcl_AppendResult(interp, "write error", (char *) NULL); + if ((Tcl_Write(out, buf, ZIP_CENTRAL_HEADER_LEN) != + ZIP_CENTRAL_HEADER_LEN) || + (Tcl_Write(out, z->name, len) != len)) { + Tcl_SetObjResult(interp, Tcl_NewStringObj("write error", -1)); goto done; } count++; @@ -2136,14 +2179,18 @@ ZipFSMkZipOrImgCmd(ClientData clientData, Tcl_Interp *interp, zip_write_int(buf + ZIP_CENTRAL_DIRSTART_OFFS, pos[1] - pos[0]); zip_write_short(buf + ZIP_CENTRAL_COMMENTLEN_OFFS, 0); if (Tcl_Write(out, buf, ZIP_CENTRAL_END_LEN) != ZIP_CENTRAL_END_LEN) { - Tcl_AppendResult(interp, "write error", (char *) NULL); + Tcl_SetObjResult(interp, Tcl_NewStringObj("write error", -1)); goto done; } Tcl_Flush(out); ret = TCL_OK; done: - Tcl_Free((char *) largv); - Tcl_Close(interp, out); + if (ret == TCL_OK) { + ret = Tcl_Close(interp, out); + } else { + Tcl_Close(interp, out); + } + Tcl_DecrRefCount(list); hPtr = Tcl_FirstHashEntry(&fileHash, &search); while (hPtr != NULL) { z = (ZipEntry *) Tcl_GetHashValue(hPtr); @@ -2158,7 +2205,7 @@ done: /* *------------------------------------------------------------------------- * - * ZipFSMkZipCmd -- + * ZipFSMkZipObjCmd -- * * This procedure is invoked to process the "zipfs::mkzip" command. * See description of ZipFSMkZipOrImgCmd(). @@ -2173,16 +2220,23 @@ done: */ static int -ZipFSMkZipCmd(ClientData clientData, Tcl_Interp *interp, - int argc, const char **argv) +ZipFSMkZipObjCmd(ClientData clientData, Tcl_Interp *interp, + int objc, Tcl_Obj *const objv[]) +{ + return ZipFSMkZipOrImgObjCmd(clientData, interp, 0, 0, objc, objv); +} + +static int +ZipFSLMkZipObjCmd(ClientData clientData, Tcl_Interp *interp, + int objc, Tcl_Obj *const objv[]) { - return ZipFSMkZipOrImgCmd(clientData, interp, 0, argc, argv); + return ZipFSMkZipOrImgObjCmd(clientData, interp, 0, 1, objc, objv); } /* *------------------------------------------------------------------------- * - * ZipFSMkImgCmd -- + * ZipFSMkImgObjCmd -- * * This procedure is invoked to process the "zipfs::mkimg" command. * See description of ZipFSMkZipOrImgCmd(). @@ -2197,10 +2251,17 @@ ZipFSMkZipCmd(ClientData clientData, Tcl_Interp *interp, */ static int -ZipFSMkImgCmd(ClientData clientData, Tcl_Interp *interp, - int argc, const char **argv) +ZipFSMkImgObjCmd(ClientData clientData, Tcl_Interp *interp, + int objc, Tcl_Obj *const objv[]) +{ + return ZipFSMkZipOrImgObjCmd(clientData, interp, 1, 0, objc, objv); +} + +static int +ZipFSLMkImgObjCmd(ClientData clientData, Tcl_Interp *interp, + int objc, Tcl_Obj *const objv[]) { - return ZipFSMkZipOrImgCmd(clientData, interp, 1, argc, argv); + return ZipFSMkZipOrImgObjCmd(clientData, interp, 1, 1, objc, objv); } /* @@ -3938,11 +3999,16 @@ Zipfs_doInit(Tcl_Interp *interp, int safe) Unlock(); Tcl_PkgProvide(interp, "zipfs", "1.0"); if (!safe) { - Tcl_CreateCommand(interp, "::zipfs::mount", ZipFSMountCmd, 0, 0); - Tcl_CreateCommand(interp, "::zipfs::unmount", ZipFSUnmountCmd, 0, 0); - Tcl_CreateCommand(interp, "::zipfs::mkkey", ZipFSMkKeyCmd, 0, 0); - Tcl_CreateCommand(interp, "::zipfs::mkimg", ZipFSMkImgCmd, 0, 0); - Tcl_CreateCommand(interp, "::zipfs::mkzip", ZipFSMkZipCmd, 0, 0); + Tcl_CreateObjCommand(interp, "::zipfs::mount", ZipFSMountObjCmd, 0, 0); + Tcl_CreateObjCommand(interp, "::zipfs::unmount", + ZipFSUnmountObjCmd, 0, 0); + Tcl_CreateObjCommand(interp, "::zipfs::mkkey", ZipFSMkKeyObjCmd, 0, 0); + Tcl_CreateObjCommand(interp, "::zipfs::mkimg", ZipFSMkImgObjCmd, 0, 0); + Tcl_CreateObjCommand(interp, "::zipfs::mkzip", ZipFSMkZipObjCmd, 0, 0); + Tcl_CreateObjCommand(interp, "::zipfs::lmkimg", + ZipFSLMkImgObjCmd, 0, 0); + Tcl_CreateObjCommand(interp, "::zipfs::lmkzip", + ZipFSLMkZipObjCmd, 0, 0); Tcl_GlobalEval(interp, findproc); } Tcl_CreateObjCommand(interp, "::zipfs::exists", ZipFSExistsObjCmd, 0, 0); -- cgit v0.12 From f6bb864fc7610c6c893acee7b4a7604a287e6018 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Mon, 18 Jan 2016 09:28:55 +0000 Subject: Minor tweaks in documentation/testcases. Don't use deprecated Tcl methods any more --- doc/zipfs.n | 4 ++-- generic/zipfs.c | 10 +++++----- tests/zipfs.test | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/doc/zipfs.n b/doc/zipfs.n index b21ad57..d16c047 100644 --- a/doc/zipfs.n +++ b/doc/zipfs.n @@ -22,7 +22,7 @@ zipfs \- Mount and work with ZIP files within Tcl \fB::zipfs::mkimg\fR \fIoutfile\fR \fIindir\fR \fI?strip?\fR \fI?password?\fR \fI?infile?\fR \fB::zipfs::mkkey\fR \fIpassword\fR \fB::zipfs::mkzip\fR \fIoutfile\fR \fIindir\fR \fI?strip?\fR \fI?password?\fR -\fB::zipfs::mount\fR \fI?zipfile\fR \fI?mountpoint?\fR \fI?password?\fR +\fB::zipfs::mount\fR \fI?zipfile?\fR \fI?mountpoint?\fR \fI?password?\fR \fB::zipfs::unmount\fR \fIzipfile\fR .fi .BE @@ -94,7 +94,7 @@ Caution: the choice of the \fIindir\fR parameter archive's content. .RE .TP -\fB::zipfs::mount ?\fIzipfile\fR? ?\fImountpoint\fR? +\fB::zipfs::mount ?\fIzipfile\fR? ?\fImountpoint\fR? ?\fIpassword\fR? . The \fB::zipfs::mount\fR command mounts a ZIP archive file as a VFS. After this command executes, files contained in \fIzipfile\fR diff --git a/generic/zipfs.c b/generic/zipfs.c index 55c6d2c..e789e14 100644 --- a/generic/zipfs.c +++ b/generic/zipfs.c @@ -1507,7 +1507,7 @@ ZipFSMountObjCmd(ClientData clientData, Tcl_Interp *interp, { if (objc > 4) { Tcl_WrongNumArgs(interp, 1, objv, - "?zipfile mountpoint password?"); + "?zipfile? ?mountpoint? ?password?"); return TCL_ERROR; } return Tclzipfs_Mount(interp, (objc > 1) ? Tcl_GetString(objv[1]) : NULL, @@ -1729,7 +1729,7 @@ wrerr: init_keys(passwd, keys, crc32tab); for (i = 0; i < 12 - 2; i++) { - if (Tcl_Eval(interp, "expr int(rand() * 256) % 256") != TCL_OK) { + if (Tcl_EvalEx(interp, "expr int(rand() * 256) % 256", -1, 0) != TCL_OK) { Tcl_AppendResult(interp, "PRNG error", (char *) NULL); Tcl_Close(interp, in); return TCL_ERROR; @@ -1966,8 +1966,8 @@ ZipFSMkZipOrImgObjCmd(ClientData clientData, Tcl_Interp *interp, } else { if ((objc < 3) || (objc > (isImg ? 6 : 5))) { Tcl_WrongNumArgs(interp, 1, objv, isImg ? - "outfile indir ?strip password infile?" : - "outfile indir ?strip password?"); + "outfile indir ?strip? ?password? ?infile?" : + "outfile indir ?strip? ?password?"); return TCL_ERROR; } } @@ -4009,7 +4009,7 @@ Zipfs_doInit(Tcl_Interp *interp, int safe) ZipFSLMkImgObjCmd, 0, 0); Tcl_CreateObjCommand(interp, "::zipfs::lmkzip", ZipFSLMkZipObjCmd, 0, 0); - Tcl_GlobalEval(interp, findproc); + Tcl_EvalEx(interp, findproc, -1, TCL_EVAL_GLOBAL); } Tcl_CreateObjCommand(interp, "::zipfs::exists", ZipFSExistsObjCmd, 0, 0); Tcl_CreateObjCommand(interp, "::zipfs::info", ZipFSInfoObjCmd, 0, 0); diff --git a/tests/zipfs.test b/tests/zipfs.test index 3f53cf8..189461a 100644 --- a/tests/zipfs.test +++ b/tests/zipfs.test @@ -27,7 +27,7 @@ test zipfs-1.2 {zipfs basics} -constraints zipfs -body { test zipfs-1.3 {zipfs basics} -constraints zipfs -returnCodes error -body { ::zipfs::mount a b c d e f -} -result {wrong # args: should be "::zipfs::mount ?zipfile ?mountpoint? ?password???"} +} -result {wrong # args: should be "::zipfs::mount ?zipfile? ?mountpoint? ?password?"} test zipfs-1.4 {zipfs basics} -constraints zipfs -returnCodes error -body { ::zipfs::unmount a b c d e f -- cgit v0.12 From 22f5c55560bbc2db11df037944b62c294e250928 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Fri, 29 Jan 2016 09:17:55 +0000 Subject: Upstream zipfs change and unbreak zipfs test-case --- generic/zipfs.c | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/generic/zipfs.c b/generic/zipfs.c index c5cb65b..1c96f7b 100644 --- a/generic/zipfs.c +++ b/generic/zipfs.c @@ -3854,6 +3854,8 @@ Zip_FSLoadFile(Tcl_Interp *interp, Tcl_Obj *path, Tcl_LoadHandle *loadHandle, objs[1] = TclPathPart(interp, path, TCL_PATH_DIRNAME); if ((objs[1] != NULL) && (Zip_FSAccessProc(objs[1], R_OK) == 0)) { + const char *execName = Tcl_GetNameOfExecutable(); + /* * Shared object is not in ZIP but its path prefix is, * thus try to load from directory where the executable @@ -3861,8 +3863,23 @@ Zip_FSLoadFile(Tcl_Interp *interp, Tcl_Obj *path, Tcl_LoadHandle *loadHandle, */ TclDecrRefCount(objs[1]); objs[1] = TclPathPart(interp, path, TCL_PATH_TAIL); - objs[0] = TclPathPart(interp, TclGetObjNameOfExecutable(), - TCL_PATH_DIRNAME); + /* + * Get directory name of executable manually to deal + * with cases where [file dirname [info nameofexecutable]] + * is equal to [info nameofexecutable] due to VFS effects. + */ + if (execName != NULL) { + const char *p = strrchr(execName, '/'); + + if (p > execName + 1) { + --p; + objs[0] = Tcl_NewStringObj(execName, p - execName); + } + } + if (objs[0] == NULL) { + objs[0] = TclPathPart(interp, TclGetObjNameOfExecutable(), + TCL_PATH_DIRNAME); + } if (objs[0] != NULL) { altPath = TclJoinPath(2, objs); if (altPath != NULL) { @@ -3980,6 +3997,7 @@ Zipfs_doInit(Tcl_Interp *interp, int safe) }; static const char findproc[] = + "namespace eval zipfs {}\n" "proc ::zipfs::find dir {\n" " set result {}\n" " if {[catch {glob -directory $dir -tails -nocomplain * .*} list]} {\n" @@ -4018,13 +4036,15 @@ Zipfs_doInit(Tcl_Interp *interp, int safe) Tcl_StaticPackage(interp, "zipfs", Tclzipfs_Init, Tclzipfs_SafeInit); } Unlock(); - Tcl_PkgProvide(interp, "zipfs", "1.0"); if (!safe) { Tcl_EvalEx(interp, findproc, -1, TCL_EVAL_GLOBAL); Tcl_LinkVar(interp, "::zipfs::wrmax", (char *) &ZipFS.wrmax, TCL_LINK_INT); } TclMakeEnsemble(interp, "zipfs", safe ? initSafeMap : initMap); + + Tcl_PkgProvide(interp, "zipfs", "1.0"); + return TCL_OK; #else if (interp != NULL) { -- cgit v0.12 From 763f9dff55f828aff79b6899498782220d0678bf Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 2 Mar 2016 15:39:32 +0000 Subject: minor upstream changes --- generic/zipfs.c | 56 +++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 37 insertions(+), 19 deletions(-) diff --git a/generic/zipfs.c b/generic/zipfs.c index 1c96f7b..c2effac 100644 --- a/generic/zipfs.c +++ b/generic/zipfs.c @@ -294,6 +294,10 @@ static const unsigned int crc32tab[256] = { * POSIX like rwlock functions to support multiple readers * and single writer on internal structs. * + * Limitations: + * - a read lock cannot be promoted to a write lock + * - a write lock may not be nested + * *------------------------------------------------------------------------- */ @@ -1056,7 +1060,7 @@ Tclzipfs_Mount(Tcl_Interp *interp, const char *zipname, const char *mntpt, ZipFile *zf, zf0; ZipEntry *z; Tcl_HashEntry *hPtr; - Tcl_DString ds, fpBuf; + Tcl_DString ds, dsm, fpBuf; unsigned char *q; #if HAS_DRIVES int drive = 0; @@ -1108,11 +1112,21 @@ Tclzipfs_Mount(Tcl_Interp *interp, const char *zipname, const char *mntpt, if (hPtr != NULL) { if ((zf = Tcl_GetHashValue(hPtr)) != NULL) { #if HAS_DRIVES - if (drive == zf->mntdrv) -#endif - { - Tcl_SetObjResult(interp, Tcl_NewStringObj(zf->mntpt, -1)); + if (drive == zf->mntdrv) { + Tcl_Obj *string; + char drvbuf[3]; + + drvbuf[0] = zf->mntdrv; + drvbuf[1] = ':'; + drvbuf[2] = '\0'; + string = Tcl_NewStringObj(drvbuf, 2); + Tcl_AppendToObj(string, zf->mntpt, zf->mntptlen); + Tcl_SetObjResult(interp, string); } +#else + Tcl_SetObjResult(interp, + Tcl_NewStringObj(zf->mntpt, zf->mntptlen)); +#endif } } Unlock(); @@ -1140,6 +1154,17 @@ Tclzipfs_Mount(Tcl_Interp *interp, const char *zipname, const char *mntpt, #else realname = AbsolutePath(zipname, &ds); #endif + /* + * Mount point can come from Tcl_GetNameOfExecutable() + * which sometimes is a relative or otherwise denormalized path. + * But an absolute name is needed as mount point here. + */ + Tcl_DStringInit(&dsm); +#if HAS_DRIVES + mntpt = AbsolutePath(mntpt, &drive, &dsm); +#else + mntpt = AbsolutePath(mntpt, &dsm); +#endif WriteLock(); hPtr = Tcl_CreateHashEntry(&ZipFS.zipHash, realname, &isNew); Tcl_DStringSetLength(&ds, 0); @@ -1151,19 +1176,10 @@ Tclzipfs_Mount(Tcl_Interp *interp, const char *zipname, const char *mntpt, } Unlock(); Tcl_DStringFree(&ds); + Tcl_DStringFree(&dsm); ZipFSCloseArchive(interp, &zf0); return TCL_ERROR; } -#if HAS_DRIVES - if ((mntpt[0] != '\0') && (mntpt[1] == ':') && - (strchr(drvletters, mntpt[0]) != NULL)) { - drive = mntpt[0]; - if ((drive >= 'a') && (drive <= 'z')) { - drive -= 'a' - 'A'; - } - mntpt += 2; - } -#endif if (strcmp(mntpt, "/") == 0) { mntpt = ""; } @@ -1174,6 +1190,7 @@ Tclzipfs_Mount(Tcl_Interp *interp, const char *zipname, const char *mntpt, } Unlock(); Tcl_DStringFree(&ds); + Tcl_DStringFree(&dsm); ZipFSCloseArchive(interp, &zf0); return TCL_ERROR; } @@ -1395,9 +1412,10 @@ Tclzipfs_Mount(Tcl_Interp *interp, const char *zipname, const char *mntpt, nextent: q += pathlen + comlen + extra + ZIP_CENTRAL_HEADER_LEN; } + Unlock(); Tcl_DStringFree(&fpBuf); Tcl_DStringFree(&ds); - Unlock(); + Tcl_DStringFree(&dsm); Tcl_FSMountsChanged(NULL); return TCL_OK; } @@ -1818,9 +1836,9 @@ wrerr: pos[1] = Tcl_Tell(out); if (nbyte - nbytecompr <= 0) { /* - * Compressed file larger than input, - * write it again uncompressed. - */ + * Compressed file larger than input, + * write it again uncompressed. + */ if ((int) Tcl_Seek(in, 0, SEEK_SET) != 0) { goto seekErr; } -- cgit v0.12 From 395d0889b0a2eb0f0626b193ee4dccab8d9882ee Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 30 Mar 2016 07:52:15 +0000 Subject: merge core-8-6-branch --- generic/tclCompCmdsGR.c | 14 +++- library/tzdata/America/Santiago | 169 +++++++++++++++++++++++++++++++++++++- library/tzdata/Antarctica/Palmer | 169 +++++++++++++++++++++++++++++++++++++- library/tzdata/Asia/Baku | 168 ------------------------------------- library/tzdata/Asia/Barnaul | 6 +- library/tzdata/Europe/Kaliningrad | 10 +-- library/tzdata/Europe/Vilnius | 11 +-- library/tzdata/Europe/Volgograd | 6 +- library/tzdata/Pacific/Easter | 169 +++++++++++++++++++++++++++++++++++++- tests/lreplace.test | 11 +++ 10 files changed, 545 insertions(+), 188 deletions(-) diff --git a/generic/tclCompCmdsGR.c b/generic/tclCompCmdsGR.c index 87ed745..9f430ea 100644 --- a/generic/tclCompCmdsGR.c +++ b/generic/tclCompCmdsGR.c @@ -1488,8 +1488,18 @@ TclCompileLreplaceCmd( return TCL_ERROR; } - if(idx2 != INDEX_END && idx2 >= 0 && idx2 < idx1) { - idx2 = idx1-1; + /* + * Compilation fails when one index is end-based but the other isn't. + * Fixing this will require more bytecodes, but this is a workaround for + * now. [Bug 47ac84309b] + */ + + if ((idx1 <= INDEX_END) != (idx2 <= INDEX_END)) { + return TCL_ERROR; + } + + if (idx2 != INDEX_END && idx2 >= 0 && idx2 < idx1) { + idx2 = idx1 - 1; } /* diff --git a/library/tzdata/America/Santiago b/library/tzdata/America/Santiago index b6d9b38..3a5c0fd 100644 --- a/library/tzdata/America/Santiago +++ b/library/tzdata/America/Santiago @@ -118,5 +118,172 @@ set TZData(:America/Santiago) { {1378612800 -10800 1 CLST} {1398567600 -14400 0 CLT} {1410062400 -10800 1 CLST} - {1430017200 -10800 0 CLT} + {1463281200 -14400 0 CLT} + {1471147200 -10800 1 CLST} + {1494730800 -14400 0 CLT} + {1502596800 -10800 1 CLST} + {1526180400 -14400 0 CLT} + {1534046400 -10800 1 CLST} + {1557630000 -14400 0 CLT} + {1565496000 -10800 1 CLST} + {1589079600 -14400 0 CLT} + {1596945600 -10800 1 CLST} + {1620529200 -14400 0 CLT} + {1629000000 -10800 1 CLST} + {1652583600 -14400 0 CLT} + {1660449600 -10800 1 CLST} + {1684033200 -14400 0 CLT} + {1691899200 -10800 1 CLST} + {1715482800 -14400 0 CLT} + {1723348800 -10800 1 CLST} + {1746932400 -14400 0 CLT} + {1754798400 -10800 1 CLST} + {1778382000 -14400 0 CLT} + {1786248000 -10800 1 CLST} + {1809831600 -14400 0 CLT} + {1818302400 -10800 1 CLST} + {1841886000 -14400 0 CLT} + {1849752000 -10800 1 CLST} + {1873335600 -14400 0 CLT} + {1881201600 -10800 1 CLST} + {1904785200 -14400 0 CLT} + {1912651200 -10800 1 CLST} + {1936234800 -14400 0 CLT} + {1944100800 -10800 1 CLST} + {1967684400 -14400 0 CLT} + {1976155200 -10800 1 CLST} + {1999738800 -14400 0 CLT} + {2007604800 -10800 1 CLST} + {2031188400 -14400 0 CLT} + {2039054400 -10800 1 CLST} + {2062638000 -14400 0 CLT} + {2070504000 -10800 1 CLST} + {2094087600 -14400 0 CLT} + {2101953600 -10800 1 CLST} + {2125537200 -14400 0 CLT} + {2133403200 -10800 1 CLST} + {2156986800 -14400 0 CLT} + {2165457600 -10800 1 CLST} + {2189041200 -14400 0 CLT} + {2196907200 -10800 1 CLST} + {2220490800 -14400 0 CLT} + {2228356800 -10800 1 CLST} + {2251940400 -14400 0 CLT} + {2259806400 -10800 1 CLST} + {2283390000 -14400 0 CLT} + {2291256000 -10800 1 CLST} + {2314839600 -14400 0 CLT} + {2322705600 -10800 1 CLST} + {2346894000 -14400 0 CLT} + {2354760000 -10800 1 CLST} + {2378343600 -14400 0 CLT} + {2386209600 -10800 1 CLST} + {2409793200 -14400 0 CLT} + {2417659200 -10800 1 CLST} + {2441242800 -14400 0 CLT} + {2449108800 -10800 1 CLST} + {2472692400 -14400 0 CLT} + {2480558400 -10800 1 CLST} + {2504142000 -14400 0 CLT} + {2512612800 -10800 1 CLST} + {2536196400 -14400 0 CLT} + {2544062400 -10800 1 CLST} + {2567646000 -14400 0 CLT} + {2575512000 -10800 1 CLST} + {2599095600 -14400 0 CLT} + {2606961600 -10800 1 CLST} + {2630545200 -14400 0 CLT} + {2638411200 -10800 1 CLST} + {2661994800 -14400 0 CLT} + {2669860800 -10800 1 CLST} + {2693444400 -14400 0 CLT} + {2701915200 -10800 1 CLST} + {2725498800 -14400 0 CLT} + {2733364800 -10800 1 CLST} + {2756948400 -14400 0 CLT} + {2764814400 -10800 1 CLST} + {2788398000 -14400 0 CLT} + {2796264000 -10800 1 CLST} + {2819847600 -14400 0 CLT} + {2827713600 -10800 1 CLST} + {2851297200 -14400 0 CLT} + {2859768000 -10800 1 CLST} + {2883351600 -14400 0 CLT} + {2891217600 -10800 1 CLST} + {2914801200 -14400 0 CLT} + {2922667200 -10800 1 CLST} + {2946250800 -14400 0 CLT} + {2954116800 -10800 1 CLST} + {2977700400 -14400 0 CLT} + {2985566400 -10800 1 CLST} + {3009150000 -14400 0 CLT} + {3017016000 -10800 1 CLST} + {3040599600 -14400 0 CLT} + {3049070400 -10800 1 CLST} + {3072654000 -14400 0 CLT} + {3080520000 -10800 1 CLST} + {3104103600 -14400 0 CLT} + {3111969600 -10800 1 CLST} + {3135553200 -14400 0 CLT} + {3143419200 -10800 1 CLST} + {3167002800 -14400 0 CLT} + {3174868800 -10800 1 CLST} + {3198452400 -14400 0 CLT} + {3206318400 -10800 1 CLST} + {3230506800 -14400 0 CLT} + {3238372800 -10800 1 CLST} + {3261956400 -14400 0 CLT} + {3269822400 -10800 1 CLST} + {3293406000 -14400 0 CLT} + {3301272000 -10800 1 CLST} + {3324855600 -14400 0 CLT} + {3332721600 -10800 1 CLST} + {3356305200 -14400 0 CLT} + {3364171200 -10800 1 CLST} + {3387754800 -14400 0 CLT} + {3396225600 -10800 1 CLST} + {3419809200 -14400 0 CLT} + {3427675200 -10800 1 CLST} + {3451258800 -14400 0 CLT} + {3459124800 -10800 1 CLST} + {3482708400 -14400 0 CLT} + {3490574400 -10800 1 CLST} + {3514158000 -14400 0 CLT} + {3522024000 -10800 1 CLST} + {3545607600 -14400 0 CLT} + {3553473600 -10800 1 CLST} + {3577057200 -14400 0 CLT} + {3585528000 -10800 1 CLST} + {3609111600 -14400 0 CLT} + {3616977600 -10800 1 CLST} + {3640561200 -14400 0 CLT} + {3648427200 -10800 1 CLST} + {3672010800 -14400 0 CLT} + {3679876800 -10800 1 CLST} + {3703460400 -14400 0 CLT} + {3711326400 -10800 1 CLST} + {3734910000 -14400 0 CLT} + {3743380800 -10800 1 CLST} + {3766964400 -14400 0 CLT} + {3774830400 -10800 1 CLST} + {3798414000 -14400 0 CLT} + {3806280000 -10800 1 CLST} + {3829863600 -14400 0 CLT} + {3837729600 -10800 1 CLST} + {3861313200 -14400 0 CLT} + {3869179200 -10800 1 CLST} + {3892762800 -14400 0 CLT} + {3900628800 -10800 1 CLST} + {3924212400 -14400 0 CLT} + {3932683200 -10800 1 CLST} + {3956266800 -14400 0 CLT} + {3964132800 -10800 1 CLST} + {3987716400 -14400 0 CLT} + {3995582400 -10800 1 CLST} + {4019166000 -14400 0 CLT} + {4027032000 -10800 1 CLST} + {4050615600 -14400 0 CLT} + {4058481600 -10800 1 CLST} + {4082065200 -14400 0 CLT} + {4089931200 -10800 1 CLST} } diff --git a/library/tzdata/Antarctica/Palmer b/library/tzdata/Antarctica/Palmer index 2c43861..5767985 100644 --- a/library/tzdata/Antarctica/Palmer +++ b/library/tzdata/Antarctica/Palmer @@ -81,5 +81,172 @@ set TZData(:Antarctica/Palmer) { {1378612800 -10800 1 CLST} {1398567600 -14400 0 CLT} {1410062400 -10800 1 CLST} - {1430017200 -10800 0 CLT} + {1463281200 -14400 0 CLT} + {1471147200 -10800 1 CLST} + {1494730800 -14400 0 CLT} + {1502596800 -10800 1 CLST} + {1526180400 -14400 0 CLT} + {1534046400 -10800 1 CLST} + {1557630000 -14400 0 CLT} + {1565496000 -10800 1 CLST} + {1589079600 -14400 0 CLT} + {1596945600 -10800 1 CLST} + {1620529200 -14400 0 CLT} + {1629000000 -10800 1 CLST} + {1652583600 -14400 0 CLT} + {1660449600 -10800 1 CLST} + {1684033200 -14400 0 CLT} + {1691899200 -10800 1 CLST} + {1715482800 -14400 0 CLT} + {1723348800 -10800 1 CLST} + {1746932400 -14400 0 CLT} + {1754798400 -10800 1 CLST} + {1778382000 -14400 0 CLT} + {1786248000 -10800 1 CLST} + {1809831600 -14400 0 CLT} + {1818302400 -10800 1 CLST} + {1841886000 -14400 0 CLT} + {1849752000 -10800 1 CLST} + {1873335600 -14400 0 CLT} + {1881201600 -10800 1 CLST} + {1904785200 -14400 0 CLT} + {1912651200 -10800 1 CLST} + {1936234800 -14400 0 CLT} + {1944100800 -10800 1 CLST} + {1967684400 -14400 0 CLT} + {1976155200 -10800 1 CLST} + {1999738800 -14400 0 CLT} + {2007604800 -10800 1 CLST} + {2031188400 -14400 0 CLT} + {2039054400 -10800 1 CLST} + {2062638000 -14400 0 CLT} + {2070504000 -10800 1 CLST} + {2094087600 -14400 0 CLT} + {2101953600 -10800 1 CLST} + {2125537200 -14400 0 CLT} + {2133403200 -10800 1 CLST} + {2156986800 -14400 0 CLT} + {2165457600 -10800 1 CLST} + {2189041200 -14400 0 CLT} + {2196907200 -10800 1 CLST} + {2220490800 -14400 0 CLT} + {2228356800 -10800 1 CLST} + {2251940400 -14400 0 CLT} + {2259806400 -10800 1 CLST} + {2283390000 -14400 0 CLT} + {2291256000 -10800 1 CLST} + {2314839600 -14400 0 CLT} + {2322705600 -10800 1 CLST} + {2346894000 -14400 0 CLT} + {2354760000 -10800 1 CLST} + {2378343600 -14400 0 CLT} + {2386209600 -10800 1 CLST} + {2409793200 -14400 0 CLT} + {2417659200 -10800 1 CLST} + {2441242800 -14400 0 CLT} + {2449108800 -10800 1 CLST} + {2472692400 -14400 0 CLT} + {2480558400 -10800 1 CLST} + {2504142000 -14400 0 CLT} + {2512612800 -10800 1 CLST} + {2536196400 -14400 0 CLT} + {2544062400 -10800 1 CLST} + {2567646000 -14400 0 CLT} + {2575512000 -10800 1 CLST} + {2599095600 -14400 0 CLT} + {2606961600 -10800 1 CLST} + {2630545200 -14400 0 CLT} + {2638411200 -10800 1 CLST} + {2661994800 -14400 0 CLT} + {2669860800 -10800 1 CLST} + {2693444400 -14400 0 CLT} + {2701915200 -10800 1 CLST} + {2725498800 -14400 0 CLT} + {2733364800 -10800 1 CLST} + {2756948400 -14400 0 CLT} + {2764814400 -10800 1 CLST} + {2788398000 -14400 0 CLT} + {2796264000 -10800 1 CLST} + {2819847600 -14400 0 CLT} + {2827713600 -10800 1 CLST} + {2851297200 -14400 0 CLT} + {2859768000 -10800 1 CLST} + {2883351600 -14400 0 CLT} + {2891217600 -10800 1 CLST} + {2914801200 -14400 0 CLT} + {2922667200 -10800 1 CLST} + {2946250800 -14400 0 CLT} + {2954116800 -10800 1 CLST} + {2977700400 -14400 0 CLT} + {2985566400 -10800 1 CLST} + {3009150000 -14400 0 CLT} + {3017016000 -10800 1 CLST} + {3040599600 -14400 0 CLT} + {3049070400 -10800 1 CLST} + {3072654000 -14400 0 CLT} + {3080520000 -10800 1 CLST} + {3104103600 -14400 0 CLT} + {3111969600 -10800 1 CLST} + {3135553200 -14400 0 CLT} + {3143419200 -10800 1 CLST} + {3167002800 -14400 0 CLT} + {3174868800 -10800 1 CLST} + {3198452400 -14400 0 CLT} + {3206318400 -10800 1 CLST} + {3230506800 -14400 0 CLT} + {3238372800 -10800 1 CLST} + {3261956400 -14400 0 CLT} + {3269822400 -10800 1 CLST} + {3293406000 -14400 0 CLT} + {3301272000 -10800 1 CLST} + {3324855600 -14400 0 CLT} + {3332721600 -10800 1 CLST} + {3356305200 -14400 0 CLT} + {3364171200 -10800 1 CLST} + {3387754800 -14400 0 CLT} + {3396225600 -10800 1 CLST} + {3419809200 -14400 0 CLT} + {3427675200 -10800 1 CLST} + {3451258800 -14400 0 CLT} + {3459124800 -10800 1 CLST} + {3482708400 -14400 0 CLT} + {3490574400 -10800 1 CLST} + {3514158000 -14400 0 CLT} + {3522024000 -10800 1 CLST} + {3545607600 -14400 0 CLT} + {3553473600 -10800 1 CLST} + {3577057200 -14400 0 CLT} + {3585528000 -10800 1 CLST} + {3609111600 -14400 0 CLT} + {3616977600 -10800 1 CLST} + {3640561200 -14400 0 CLT} + {3648427200 -10800 1 CLST} + {3672010800 -14400 0 CLT} + {3679876800 -10800 1 CLST} + {3703460400 -14400 0 CLT} + {3711326400 -10800 1 CLST} + {3734910000 -14400 0 CLT} + {3743380800 -10800 1 CLST} + {3766964400 -14400 0 CLT} + {3774830400 -10800 1 CLST} + {3798414000 -14400 0 CLT} + {3806280000 -10800 1 CLST} + {3829863600 -14400 0 CLT} + {3837729600 -10800 1 CLST} + {3861313200 -14400 0 CLT} + {3869179200 -10800 1 CLST} + {3892762800 -14400 0 CLT} + {3900628800 -10800 1 CLST} + {3924212400 -14400 0 CLT} + {3932683200 -10800 1 CLST} + {3956266800 -14400 0 CLT} + {3964132800 -10800 1 CLST} + {3987716400 -14400 0 CLT} + {3995582400 -10800 1 CLST} + {4019166000 -14400 0 CLT} + {4027032000 -10800 1 CLST} + {4050615600 -14400 0 CLT} + {4058481600 -10800 1 CLST} + {4082065200 -14400 0 CLT} + {4089931200 -10800 1 CLST} } diff --git a/library/tzdata/Asia/Baku b/library/tzdata/Asia/Baku index e50071b..c26a2f5 100644 --- a/library/tzdata/Asia/Baku +++ b/library/tzdata/Asia/Baku @@ -71,172 +71,4 @@ set TZData(:Asia/Baku) { {1414281600 14400 0 AZT} {1427587200 18000 1 AZST} {1445731200 14400 0 AZT} - {1459036800 18000 1 AZST} - {1477785600 14400 0 AZT} - {1490486400 18000 1 AZST} - {1509235200 14400 0 AZT} - {1521936000 18000 1 AZST} - {1540684800 14400 0 AZT} - {1553990400 18000 1 AZST} - {1572134400 14400 0 AZT} - {1585440000 18000 1 AZST} - {1603584000 14400 0 AZT} - {1616889600 18000 1 AZST} - {1635638400 14400 0 AZT} - {1648339200 18000 1 AZST} - {1667088000 14400 0 AZT} - {1679788800 18000 1 AZST} - {1698537600 14400 0 AZT} - {1711843200 18000 1 AZST} - {1729987200 14400 0 AZT} - {1743292800 18000 1 AZST} - {1761436800 14400 0 AZT} - {1774742400 18000 1 AZST} - {1792886400 14400 0 AZT} - {1806192000 18000 1 AZST} - {1824940800 14400 0 AZT} - {1837641600 18000 1 AZST} - {1856390400 14400 0 AZT} - {1869091200 18000 1 AZST} - {1887840000 14400 0 AZT} - {1901145600 18000 1 AZST} - {1919289600 14400 0 AZT} - {1932595200 18000 1 AZST} - {1950739200 14400 0 AZT} - {1964044800 18000 1 AZST} - {1982793600 14400 0 AZT} - {1995494400 18000 1 AZST} - {2014243200 14400 0 AZT} - {2026944000 18000 1 AZST} - {2045692800 14400 0 AZT} - {2058393600 18000 1 AZST} - {2077142400 14400 0 AZT} - {2090448000 18000 1 AZST} - {2108592000 14400 0 AZT} - {2121897600 18000 1 AZST} - {2140041600 14400 0 AZT} - {2153347200 18000 1 AZST} - {2172096000 14400 0 AZT} - {2184796800 18000 1 AZST} - {2203545600 14400 0 AZT} - {2216246400 18000 1 AZST} - {2234995200 14400 0 AZT} - {2248300800 18000 1 AZST} - {2266444800 14400 0 AZT} - {2279750400 18000 1 AZST} - {2297894400 14400 0 AZT} - {2311200000 18000 1 AZST} - {2329344000 14400 0 AZT} - {2342649600 18000 1 AZST} - {2361398400 14400 0 AZT} - {2374099200 18000 1 AZST} - {2392848000 14400 0 AZT} - {2405548800 18000 1 AZST} - {2424297600 14400 0 AZT} - {2437603200 18000 1 AZST} - {2455747200 14400 0 AZT} - {2469052800 18000 1 AZST} - {2487196800 14400 0 AZT} - {2500502400 18000 1 AZST} - {2519251200 14400 0 AZT} - {2531952000 18000 1 AZST} - {2550700800 14400 0 AZT} - {2563401600 18000 1 AZST} - {2582150400 14400 0 AZT} - {2595456000 18000 1 AZST} - {2613600000 14400 0 AZT} - {2626905600 18000 1 AZST} - {2645049600 14400 0 AZT} - {2658355200 18000 1 AZST} - {2676499200 14400 0 AZT} - {2689804800 18000 1 AZST} - {2708553600 14400 0 AZT} - {2721254400 18000 1 AZST} - {2740003200 14400 0 AZT} - {2752704000 18000 1 AZST} - {2771452800 14400 0 AZT} - {2784758400 18000 1 AZST} - {2802902400 14400 0 AZT} - {2816208000 18000 1 AZST} - {2834352000 14400 0 AZT} - {2847657600 18000 1 AZST} - {2866406400 14400 0 AZT} - {2879107200 18000 1 AZST} - {2897856000 14400 0 AZT} - {2910556800 18000 1 AZST} - {2929305600 14400 0 AZT} - {2942006400 18000 1 AZST} - {2960755200 14400 0 AZT} - {2974060800 18000 1 AZST} - {2992204800 14400 0 AZT} - {3005510400 18000 1 AZST} - {3023654400 14400 0 AZT} - {3036960000 18000 1 AZST} - {3055708800 14400 0 AZT} - {3068409600 18000 1 AZST} - {3087158400 14400 0 AZT} - {3099859200 18000 1 AZST} - {3118608000 14400 0 AZT} - {3131913600 18000 1 AZST} - {3150057600 14400 0 AZT} - {3163363200 18000 1 AZST} - {3181507200 14400 0 AZT} - {3194812800 18000 1 AZST} - {3212956800 14400 0 AZT} - {3226262400 18000 1 AZST} - {3245011200 14400 0 AZT} - {3257712000 18000 1 AZST} - {3276460800 14400 0 AZT} - {3289161600 18000 1 AZST} - {3307910400 14400 0 AZT} - {3321216000 18000 1 AZST} - {3339360000 14400 0 AZT} - {3352665600 18000 1 AZST} - {3370809600 14400 0 AZT} - {3384115200 18000 1 AZST} - {3402864000 14400 0 AZT} - {3415564800 18000 1 AZST} - {3434313600 14400 0 AZT} - {3447014400 18000 1 AZST} - {3465763200 14400 0 AZT} - {3479068800 18000 1 AZST} - {3497212800 14400 0 AZT} - {3510518400 18000 1 AZST} - {3528662400 14400 0 AZT} - {3541968000 18000 1 AZST} - {3560112000 14400 0 AZT} - {3573417600 18000 1 AZST} - {3592166400 14400 0 AZT} - {3604867200 18000 1 AZST} - {3623616000 14400 0 AZT} - {3636316800 18000 1 AZST} - {3655065600 14400 0 AZT} - {3668371200 18000 1 AZST} - {3686515200 14400 0 AZT} - {3699820800 18000 1 AZST} - {3717964800 14400 0 AZT} - {3731270400 18000 1 AZST} - {3750019200 14400 0 AZT} - {3762720000 18000 1 AZST} - {3781468800 14400 0 AZT} - {3794169600 18000 1 AZST} - {3812918400 14400 0 AZT} - {3825619200 18000 1 AZST} - {3844368000 14400 0 AZT} - {3857673600 18000 1 AZST} - {3875817600 14400 0 AZT} - {3889123200 18000 1 AZST} - {3907267200 14400 0 AZT} - {3920572800 18000 1 AZST} - {3939321600 14400 0 AZT} - {3952022400 18000 1 AZST} - {3970771200 14400 0 AZT} - {3983472000 18000 1 AZST} - {4002220800 14400 0 AZT} - {4015526400 18000 1 AZST} - {4033670400 14400 0 AZT} - {4046976000 18000 1 AZST} - {4065120000 14400 0 AZT} - {4078425600 18000 1 AZST} - {4096569600 14400 0 AZT} } diff --git a/library/tzdata/Asia/Barnaul b/library/tzdata/Asia/Barnaul index 8072e34..f6a45da 100644 --- a/library/tzdata/Asia/Barnaul +++ b/library/tzdata/Asia/Barnaul @@ -24,8 +24,10 @@ set TZData(:Asia/Barnaul) { {622580400 25200 0 +07} {638305200 28800 1 +08} {654634800 25200 0 +07} - {670359600 28800 1 +08} - {686084400 25200 0 +07} + {670359600 21600 0 +07} + {670363200 25200 1 +07} + {686088000 21600 0 +06} + {695764800 25200 0 +08} {701798400 28800 1 +08} {717519600 25200 0 +07} {733258800 28800 1 +08} diff --git a/library/tzdata/Europe/Kaliningrad b/library/tzdata/Europe/Kaliningrad index d03f7d0..32d7aaa 100644 --- a/library/tzdata/Europe/Kaliningrad +++ b/library/tzdata/Europe/Kaliningrad @@ -35,11 +35,11 @@ set TZData(:Europe/Kaliningrad) { {559695600 10800 0 MSK} {575420400 14400 1 MSD} {591145200 10800 0 MSK} - {606870000 14400 1 MSD} - {622594800 10800 0 MSK} - {638319600 14400 1 MSD} - {654649200 10800 0 MSK} - {670374000 7200 0 EEMMTT} + {606870000 7200 0 EEMMTT} + {606873600 10800 1 EEST} + {622598400 7200 0 EET} + {638323200 10800 1 EEST} + {654652800 7200 0 EET} {670377600 10800 1 EEST} {686102400 7200 0 EET} {701816400 10800 1 EEST} diff --git a/library/tzdata/Europe/Vilnius b/library/tzdata/Europe/Vilnius index 62d5d87..5e73150 100644 --- a/library/tzdata/Europe/Vilnius +++ b/library/tzdata/Europe/Vilnius @@ -30,11 +30,12 @@ set TZData(:Europe/Vilnius) { {559695600 10800 0 MSK} {575420400 14400 1 MSD} {591145200 10800 0 MSK} - {606870000 14400 1 MSD} - {622594800 10800 0 MSK} - {638319600 14400 1 MSD} - {654649200 10800 0 MSK} - {670374000 10800 1 EEST} + {606870000 7200 0 EEMMTT} + {606873600 10800 1 EEST} + {622598400 7200 0 EET} + {638323200 10800 1 EEST} + {654652800 7200 0 EET} + {670377600 10800 1 EEST} {686102400 7200 0 EET} {701827200 10800 1 EEST} {717552000 7200 0 EET} diff --git a/library/tzdata/Europe/Volgograd b/library/tzdata/Europe/Volgograd index d71fb0b..ef33d4b 100644 --- a/library/tzdata/Europe/Volgograd +++ b/library/tzdata/Europe/Volgograd @@ -20,9 +20,9 @@ set TZData(:Europe/Volgograd) { {528242400 14400 0 VOLT} {543967200 18000 1 VOLST} {559692000 14400 0 VOLT} - {575416800 18000 1 VOLST} - {591141600 14400 0 VOLT} - {606866400 10800 0 VOLMMTT} + {575416800 10800 0 VOLMMTT} + {575420400 14400 1 VOLST} + {591145200 10800 0 VOLT} {606870000 14400 1 VOLST} {622594800 10800 0 VOLT} {638319600 14400 1 VOLST} diff --git a/library/tzdata/Pacific/Easter b/library/tzdata/Pacific/Easter index 4b45ba2..ef0f2d5 100644 --- a/library/tzdata/Pacific/Easter +++ b/library/tzdata/Pacific/Easter @@ -97,5 +97,172 @@ set TZData(:Pacific/Easter) { {1378612800 -18000 1 EASST} {1398567600 -21600 0 EAST} {1410062400 -18000 1 EASST} - {1430017200 -18000 0 EAST} + {1463281200 -21600 0 EAST} + {1471147200 -18000 1 EASST} + {1494730800 -21600 0 EAST} + {1502596800 -18000 1 EASST} + {1526180400 -21600 0 EAST} + {1534046400 -18000 1 EASST} + {1557630000 -21600 0 EAST} + {1565496000 -18000 1 EASST} + {1589079600 -21600 0 EAST} + {1596945600 -18000 1 EASST} + {1620529200 -21600 0 EAST} + {1629000000 -18000 1 EASST} + {1652583600 -21600 0 EAST} + {1660449600 -18000 1 EASST} + {1684033200 -21600 0 EAST} + {1691899200 -18000 1 EASST} + {1715482800 -21600 0 EAST} + {1723348800 -18000 1 EASST} + {1746932400 -21600 0 EAST} + {1754798400 -18000 1 EASST} + {1778382000 -21600 0 EAST} + {1786248000 -18000 1 EASST} + {1809831600 -21600 0 EAST} + {1818302400 -18000 1 EASST} + {1841886000 -21600 0 EAST} + {1849752000 -18000 1 EASST} + {1873335600 -21600 0 EAST} + {1881201600 -18000 1 EASST} + {1904785200 -21600 0 EAST} + {1912651200 -18000 1 EASST} + {1936234800 -21600 0 EAST} + {1944100800 -18000 1 EASST} + {1967684400 -21600 0 EAST} + {1976155200 -18000 1 EASST} + {1999738800 -21600 0 EAST} + {2007604800 -18000 1 EASST} + {2031188400 -21600 0 EAST} + {2039054400 -18000 1 EASST} + {2062638000 -21600 0 EAST} + {2070504000 -18000 1 EASST} + {2094087600 -21600 0 EAST} + {2101953600 -18000 1 EASST} + {2125537200 -21600 0 EAST} + {2133403200 -18000 1 EASST} + {2156986800 -21600 0 EAST} + {2165457600 -18000 1 EASST} + {2189041200 -21600 0 EAST} + {2196907200 -18000 1 EASST} + {2220490800 -21600 0 EAST} + {2228356800 -18000 1 EASST} + {2251940400 -21600 0 EAST} + {2259806400 -18000 1 EASST} + {2283390000 -21600 0 EAST} + {2291256000 -18000 1 EASST} + {2314839600 -21600 0 EAST} + {2322705600 -18000 1 EASST} + {2346894000 -21600 0 EAST} + {2354760000 -18000 1 EASST} + {2378343600 -21600 0 EAST} + {2386209600 -18000 1 EASST} + {2409793200 -21600 0 EAST} + {2417659200 -18000 1 EASST} + {2441242800 -21600 0 EAST} + {2449108800 -18000 1 EASST} + {2472692400 -21600 0 EAST} + {2480558400 -18000 1 EASST} + {2504142000 -21600 0 EAST} + {2512612800 -18000 1 EASST} + {2536196400 -21600 0 EAST} + {2544062400 -18000 1 EASST} + {2567646000 -21600 0 EAST} + {2575512000 -18000 1 EASST} + {2599095600 -21600 0 EAST} + {2606961600 -18000 1 EASST} + {2630545200 -21600 0 EAST} + {2638411200 -18000 1 EASST} + {2661994800 -21600 0 EAST} + {2669860800 -18000 1 EASST} + {2693444400 -21600 0 EAST} + {2701915200 -18000 1 EASST} + {2725498800 -21600 0 EAST} + {2733364800 -18000 1 EASST} + {2756948400 -21600 0 EAST} + {2764814400 -18000 1 EASST} + {2788398000 -21600 0 EAST} + {2796264000 -18000 1 EASST} + {2819847600 -21600 0 EAST} + {2827713600 -18000 1 EASST} + {2851297200 -21600 0 EAST} + {2859768000 -18000 1 EASST} + {2883351600 -21600 0 EAST} + {2891217600 -18000 1 EASST} + {2914801200 -21600 0 EAST} + {2922667200 -18000 1 EASST} + {2946250800 -21600 0 EAST} + {2954116800 -18000 1 EASST} + {2977700400 -21600 0 EAST} + {2985566400 -18000 1 EASST} + {3009150000 -21600 0 EAST} + {3017016000 -18000 1 EASST} + {3040599600 -21600 0 EAST} + {3049070400 -18000 1 EASST} + {3072654000 -21600 0 EAST} + {3080520000 -18000 1 EASST} + {3104103600 -21600 0 EAST} + {3111969600 -18000 1 EASST} + {3135553200 -21600 0 EAST} + {3143419200 -18000 1 EASST} + {3167002800 -21600 0 EAST} + {3174868800 -18000 1 EASST} + {3198452400 -21600 0 EAST} + {3206318400 -18000 1 EASST} + {3230506800 -21600 0 EAST} + {3238372800 -18000 1 EASST} + {3261956400 -21600 0 EAST} + {3269822400 -18000 1 EASST} + {3293406000 -21600 0 EAST} + {3301272000 -18000 1 EASST} + {3324855600 -21600 0 EAST} + {3332721600 -18000 1 EASST} + {3356305200 -21600 0 EAST} + {3364171200 -18000 1 EASST} + {3387754800 -21600 0 EAST} + {3396225600 -18000 1 EASST} + {3419809200 -21600 0 EAST} + {3427675200 -18000 1 EASST} + {3451258800 -21600 0 EAST} + {3459124800 -18000 1 EASST} + {3482708400 -21600 0 EAST} + {3490574400 -18000 1 EASST} + {3514158000 -21600 0 EAST} + {3522024000 -18000 1 EASST} + {3545607600 -21600 0 EAST} + {3553473600 -18000 1 EASST} + {3577057200 -21600 0 EAST} + {3585528000 -18000 1 EASST} + {3609111600 -21600 0 EAST} + {3616977600 -18000 1 EASST} + {3640561200 -21600 0 EAST} + {3648427200 -18000 1 EASST} + {3672010800 -21600 0 EAST} + {3679876800 -18000 1 EASST} + {3703460400 -21600 0 EAST} + {3711326400 -18000 1 EASST} + {3734910000 -21600 0 EAST} + {3743380800 -18000 1 EASST} + {3766964400 -21600 0 EAST} + {3774830400 -18000 1 EASST} + {3798414000 -21600 0 EAST} + {3806280000 -18000 1 EASST} + {3829863600 -21600 0 EAST} + {3837729600 -18000 1 EASST} + {3861313200 -21600 0 EAST} + {3869179200 -18000 1 EASST} + {3892762800 -21600 0 EAST} + {3900628800 -18000 1 EASST} + {3924212400 -21600 0 EAST} + {3932683200 -18000 1 EASST} + {3956266800 -21600 0 EAST} + {3964132800 -18000 1 EASST} + {3987716400 -21600 0 EAST} + {3995582400 -18000 1 EASST} + {4019166000 -21600 0 EAST} + {4027032000 -18000 1 EASST} + {4050615600 -21600 0 EAST} + {4058481600 -18000 1 EASST} + {4082065200 -21600 0 EAST} + {4089931200 -18000 1 EASST} } diff --git a/tests/lreplace.test b/tests/lreplace.test index e66a331..55a36a8 100644 --- a/tests/lreplace.test +++ b/tests/lreplace.test @@ -181,6 +181,17 @@ test lreplace-4.11 {lreplace end index first} { test lreplace-4.12 {lreplace end index first} { lreplace {0 1 2 3 4} end-2 2 a b c } {0 1 a b c 3 4} + +test lreplace-5.1 {compiled lreplace: Bug 47ac84309b} { + apply {x { + lreplace $x end 0 + }} {a b c} +} {a b c} +test lreplace-5.2 {compiled lreplace: Bug 47ac84309b} { + apply {x { + lreplace $x end 0 A + }} {a b c} +} {a b A c} # cleanup catch {unset foo} -- cgit v0.12 From 824b71f9590840c9ff84285235c46b111cee31a5 Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Wed, 14 Sep 2016 13:33:32 +0000 Subject: Beginning work in earnest on Tip#430 and Tip#453 Renamed zipfs.c to tclZipfs.c. Eliminated tclZipfs.h. Removed the bootstrap introduced by Odie/Androwish. With zipfs in the core one only needs to specify the TclPreInitScript The project at least builds on OSX. Working on Windows under MSYS/MinGW next Added a local snapshot of practcl. --- generic/tclBasic.c | 3 + generic/tclIOUtil.c | 34 - generic/tclInt.h | 4 + generic/tclZipfs.c | 3915 ++++++++++++++++++++++++++++++++++++++ generic/tclZipfs.h | 48 - generic/zipfs.c | 4229 ------------------------------------------ library/practcl/pkgIndex.tcl | 11 + library/practcl/practcl.tcl | 4000 +++++++++++++++++++++++++++++++++++++++ unix/Makefile.in | 8 +- unix/tclAppInit.c | 18 +- win/Makefile.in | 15 +- win/makefile.vc | 2 +- win/tclAppInit.c | 17 +- 13 files changed, 7954 insertions(+), 4350 deletions(-) create mode 100644 generic/tclZipfs.c delete mode 100644 generic/tclZipfs.h delete mode 100644 generic/zipfs.c create mode 100644 library/practcl/pkgIndex.tcl create mode 100644 library/practcl/practcl.tcl diff --git a/generic/tclBasic.c b/generic/tclBasic.c index 53023d8..3550d93 100644 --- a/generic/tclBasic.c +++ b/generic/tclBasic.c @@ -982,6 +982,9 @@ Tcl_CreateInterp(void) if (TclZlibInit(interp) != TCL_OK) { Tcl_Panic("%s", Tcl_GetString(Tcl_GetObjResult(interp))); } + if (TclZipfsInit(interp) != TCL_OK) { + Tcl_Panic("%s", Tcl_GetString(Tcl_GetObjResult(interp))); + } #endif TOP_CB(iPtr) = NULL; diff --git a/generic/tclIOUtil.c b/generic/tclIOUtil.c index e8fce01..397c3b1 100644 --- a/generic/tclIOUtil.c +++ b/generic/tclIOUtil.c @@ -190,8 +190,6 @@ const Tcl_Filesystem tclNativeFilesystem = { TclpObjChdir }; -MODULE_SCOPE Tcl_Filesystem zipfsFilesystem; - /* * Define the tail of the linked list. Note that for unconventional uses of * Tcl without a native filesystem, we may in the future wish to modify the @@ -1412,22 +1410,6 @@ TclFSNormalizeToUniquePath( Claim(); for (fsRecPtr=firstFsRecPtr; fsRecPtr!=NULL; fsRecPtr=fsRecPtr->nextPtr) { - if (fsRecPtr->fsPtr == &zipfsFilesystem) { - ClientData clientData = NULL; - /* - * Allow mounted zipfs filesystem to overtake entire normalisation. - * This is needed on unix for mounts on symlinks right below root. - */ - - if (fsRecPtr->fsPtr->pathInFilesystemProc != NULL) { - if (fsRecPtr->fsPtr->pathInFilesystemProc(pathPtr, - &clientData)!=-1) { - TclFSSetPathDetails(pathPtr, fsRecPtr->fsPtr, clientData); - break; - } - } - continue; - } if (fsRecPtr->fsPtr != &tclNativeFilesystem) { continue; } @@ -1452,9 +1434,6 @@ TclFSNormalizeToUniquePath( if (fsRecPtr->fsPtr == &tclNativeFilesystem) { continue; } - if (fsRecPtr->fsPtr == &zipfsFilesystem) { - continue; - } if (fsRecPtr->fsPtr->normalizePathProc != NULL) { startAt = fsRecPtr->fsPtr->normalizePathProc(interp, pathPtr, @@ -2935,19 +2914,6 @@ Tcl_FSChdir( } fsPtr = Tcl_FSGetFileSystemForPath(pathPtr); - - if ((fsPtr != NULL) && (fsPtr != &tclNativeFilesystem)) { - /* - * Watch out for tilde substitution. - * Only valid in native filesystem. - */ - char *name = Tcl_GetString(pathPtr); - - if ((name != NULL) && (*name == '~')) { - fsPtr = &tclNativeFilesystem; - } - } - if (fsPtr != NULL) { if (fsPtr->chdirProc != NULL) { /* diff --git a/generic/tclInt.h b/generic/tclInt.h index da1b5c5..aaffd34 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -3177,6 +3177,10 @@ MODULE_SCOPE Tcl_WideInt TclpGetWideClicks(void); MODULE_SCOPE double TclpWideClicksToNanoseconds(Tcl_WideInt clicks); #endif MODULE_SCOPE int TclZlibInit(Tcl_Interp *interp); +MODULE_SCOPE int TclZipfsInit(Tcl_Interp *interp); +MODULE_SCOPE int TclZipfsMount(Tcl_Interp *interp, const char *zipname, + const char *mntpt, const char *passwd); +MODULE_SCOPE int TclZipfsUnmount(Tcl_Interp *interp, const char *zipname); MODULE_SCOPE void * TclpThreadCreateKey(void); MODULE_SCOPE void TclpThreadDeleteKey(void *keyPtr); MODULE_SCOPE void TclpThreadSetMasterTSD(void *tsdKeyPtr, void *ptr); diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c new file mode 100644 index 0000000..01d46c6 --- /dev/null +++ b/generic/tclZipfs.c @@ -0,0 +1,3915 @@ +/* + * tclZipfs.c -- + * + * Implementation of the ZIP filesystem used in TIP 430 + * Adapted from the implentation for AndroWish. + * + * Coptright (c) 2016 Sean Woods + * Copyright (c) 2013-2015 Christian Werner + * + * See the file "license.terms" for information on usage and redistribution of + * this file, and for a DISCLAIMER OF ALL WARRANTIES. + */ + +#include "tclInt.h" +#include "tclFileSystem.h" + +#if !defined(_WIN32) && !defined(_WIN64) +#include +#endif +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_ZLIB +#include "zlib.h" +#include "zcrypt.h" + +#define ZIPFS_VOLUME "zipfs:/" +#define ZIPFS_VOLUME_LEN 7 + +/* + * Various constants and offsets found in ZIP archive files + */ + +#define ZIP_SIG_LEN 4 + +/* Local header of ZIP archive member (at very beginning of each member). */ +#define ZIP_LOCAL_HEADER_SIG 0x04034b50 +#define ZIP_LOCAL_HEADER_LEN 30 +#define ZIP_LOCAL_SIG_OFFS 0 +#define ZIP_LOCAL_VERSION_OFFS 4 +#define ZIP_LOCAL_FLAGS_OFFS 6 +#define ZIP_LOCAL_COMPMETH_OFFS 8 +#define ZIP_LOCAL_MTIME_OFFS 10 +#define ZIP_LOCAL_MDATE_OFFS 12 +#define ZIP_LOCAL_CRC32_OFFS 14 +#define ZIP_LOCAL_COMPLEN_OFFS 18 +#define ZIP_LOCAL_UNCOMPLEN_OFFS 22 +#define ZIP_LOCAL_PATHLEN_OFFS 26 +#define ZIP_LOCAL_EXTRALEN_OFFS 28 + +/* Central header of ZIP archive member at end of ZIP file. */ +#define ZIP_CENTRAL_HEADER_SIG 0x02014b50 +#define ZIP_CENTRAL_HEADER_LEN 46 +#define ZIP_CENTRAL_SIG_OFFS 0 +#define ZIP_CENTRAL_VERSIONMADE_OFFS 4 +#define ZIP_CENTRAL_VERSION_OFFS 6 +#define ZIP_CENTRAL_FLAGS_OFFS 8 +#define ZIP_CENTRAL_COMPMETH_OFFS 10 +#define ZIP_CENTRAL_MTIME_OFFS 12 +#define ZIP_CENTRAL_MDATE_OFFS 14 +#define ZIP_CENTRAL_CRC32_OFFS 16 +#define ZIP_CENTRAL_COMPLEN_OFFS 20 +#define ZIP_CENTRAL_UNCOMPLEN_OFFS 24 +#define ZIP_CENTRAL_PATHLEN_OFFS 28 +#define ZIP_CENTRAL_EXTRALEN_OFFS 30 +#define ZIP_CENTRAL_FCOMMENTLEN_OFFS 32 +#define ZIP_CENTRAL_DISKFILE_OFFS 34 +#define ZIP_CENTRAL_IATTR_OFFS 36 +#define ZIP_CENTRAL_EATTR_OFFS 38 +#define ZIP_CENTRAL_LOCALHDR_OFFS 42 + +/* Central end signature at very end of ZIP file. */ +#define ZIP_CENTRAL_END_SIG 0x06054b50 +#define ZIP_CENTRAL_END_LEN 22 +#define ZIP_CENTRAL_END_SIG_OFFS 0 +#define ZIP_CENTRAL_DISKNO_OFFS 4 +#define ZIP_CENTRAL_DISKDIR_OFFS 6 +#define ZIP_CENTRAL_ENTS_OFFS 8 +#define ZIP_CENTRAL_TOTALENTS_OFFS 10 +#define ZIP_CENTRAL_DIRSIZE_OFFS 12 +#define ZIP_CENTRAL_DIRSTART_OFFS 16 +#define ZIP_CENTRAL_COMMENTLEN_OFFS 20 + +#define ZIP_MIN_VERSION 20 +#define ZIP_COMPMETH_STORED 0 +#define ZIP_COMPMETH_DEFLATED 8 + +#define ZIP_PASSWORD_END_SIG 0x5a5a4b50 + +/* + * Macros to read and write 16 and 32 bit integers from/to ZIP archives. + */ + +#define zip_read_int(p) \ + ((p)[0] | ((p)[1] << 8) | ((p)[2] << 16) | ((p)[3] << 24)) +#define zip_read_short(p) \ + ((p)[0] | ((p)[1] << 8)) + +#define zip_write_int(p, v) \ + (p)[0] = (v) & 0xff; (p)[1] = ((v) >> 8) & 0xff; \ + (p)[2] = ((v) >> 16) & 0xff; (p)[3] = ((v) >> 24) & 0xff; +#define zip_write_short(p, v) \ + (p)[0] = (v) & 0xff; (p)[1] = ((v) >> 8) & 0xff; + +/* + * Windows drive letters. + */ + +#if defined(_WIN32) || defined(_WIN64) +#define HAS_DRIVES 1 +static const char drvletters[] = + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; +#else +#define HAS_DRIVES 0 +#endif + +/* + * Mutex to protect localtime(3) when no reentrant version available. + */ + +#if !defined(_WIN32) && !defined(_WIN64) +#ifndef HAVE_LOCALTIME_R +#ifdef TCL_THREADS +TCL_DECLARE_MUTEX(localtimeMutex) +#endif +#endif +#endif + +/* + * In-core description of mounted ZIP archive file. + */ + +typedef struct ZipFile { + char *name; /* Archive name */ + Tcl_Channel chan; /* Channel handle or NULL */ + unsigned char *data; /* Memory mapped or malloc'ed file */ + long length; /* Length of memory mapped file */ + unsigned char *tofree; /* Non-NULL if malloc'ed file */ + int nfiles; /* Number of files in archive */ + int baseoffs; /* Archive start */ + int baseoffsp; /* Password start */ + int centoffs; /* Archive directory start */ + char pwbuf[264]; /* Password buffer */ +#if defined(_WIN32) || defined(_WIN64) + HANDLE mh; +#endif + int nopen; /* Number of open files on archive */ + struct ZipEntry *entries; /* List of files in archive */ + struct ZipEntry *topents; /* List of top-level dirs in archive */ +#if HAS_DRIVES + int mntdrv; /* Drive letter of mount point */ +#endif + int mntptlen; /* Length of mount point */ + char mntpt[1]; /* Mount point */ +} ZipFile; + +/* + * In-core description of file contained in mounted ZIP archive. + */ + +typedef struct ZipEntry { + char *name; /* The full pathname of the virtual file */ + ZipFile *zipfile; /* The ZIP file holding this virtual file */ + long offset; /* Data offset into memory mapped ZIP file */ + int nbyte; /* Uncompressed size of the virtual file */ + int nbytecompr; /* Compressed size of the virtual file */ + int cmeth; /* Compress method */ + int isdir; /* Set to 1 if directory */ + int depth; /* Number of slashes in path. */ + int crc32; /* CRC-32 */ + int timestamp; /* Modification time */ + int isenc; /* True if data is encrypted */ + unsigned char *data; /* File data if written */ + struct ZipEntry *next; /* Next file in the same archive */ + struct ZipEntry *tnext; /* Next top-level dir in archive */ +} ZipEntry; + +/* + * File channel for file contained in mounted ZIP archive. + */ + +typedef struct ZipChannel { + ZipFile *zipfile; /* The ZIP file holding this channel */ + ZipEntry *zipentry; /* Pointer back to virtual file */ + unsigned long nmax; /* Max. size for write */ + unsigned long nbyte; /* Number of bytes of uncompressed data */ + unsigned long nread; /* Pos of next byte to be read from the channel */ + unsigned char *ubuf; /* Pointer to the uncompressed data */ + int iscompr; /* True if data is compressed */ + int isdir; /* Set to 1 if directory */ + int isenc; /* True if data is encrypted */ + int iswr; /* True if open for writing */ + unsigned long keys[3]; /* Key for decryption */ +} ZipChannel; + +/* + * Global variables. + * + * Most are kept in single ZipFS struct. When build with threading + * support this struct is protected by the ZipFSMutex (see below). + * + * The "fileHash" component is the process wide global table of all known + * ZIP archive members in all mounted ZIP archives. + * + * The "zipHash" components is the process wide global table of all mounted + * ZIP archive files. + */ + +static struct { + int initialized; /* True when initialized */ + int lock; /* RW lock, see below */ + int waiters; /* RW lock, see below */ + int wrmax; /* Maximum write size of a file */ + int idCount; /* Counter for channel names */ + Tcl_HashTable fileHash; /* File name to ZipEntry mapping */ + Tcl_HashTable zipHash; /* Mount to ZipFile mapping */ +} ZipFS = { + 0, 0, 0, 0, 0, +}; + +/* + * For password rotation. + */ + +static const char pwrot[16] = { + 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, + 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0 +}; + +/* + * Table to compute CRC32. + */ + +static const unsigned int crc32tab[256] = { + 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, + 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, + 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, + 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, + 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, + 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, + 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, + 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, + 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, + 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, + 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, + 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, + 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, + 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, + 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, + 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, + 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, + 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, + 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, + 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, + 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, + 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, + 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, + 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, + 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, + 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, + 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, + 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344, + 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, + 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, + 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, + 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, + 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, + 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, + 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, + 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, + 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, + 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, + 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, + 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, + 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, + 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, + 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, + 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, + 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, + 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, + 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, + 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, + 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, + 0x2d02ef8d, +}; + +/* + *------------------------------------------------------------------------- + * + * ReadLock, WriteLock, Unlock -- + * + * POSIX like rwlock functions to support multiple readers + * and single writer on internal structs. + * + * Limitations: + * - a read lock cannot be promoted to a write lock + * - a write lock may not be nested + * + *------------------------------------------------------------------------- + */ + +TCL_DECLARE_MUTEX(ZipFSMutex) + +#ifdef TCL_THREADS + +static Tcl_Condition ZipFSCond; + +static void +ReadLock(void) +{ + Tcl_MutexLock(&ZipFSMutex); + while (ZipFS.lock < 0) { + ZipFS.waiters++; + Tcl_ConditionWait(&ZipFSCond, &ZipFSMutex, NULL); + ZipFS.waiters--; + } + ZipFS.lock++; + Tcl_MutexUnlock(&ZipFSMutex); +} + +static void +WriteLock(void) +{ + Tcl_MutexLock(&ZipFSMutex); + while (ZipFS.lock != 0) { + ZipFS.waiters++; + Tcl_ConditionWait(&ZipFSCond, &ZipFSMutex, NULL); + ZipFS.waiters--; + } + ZipFS.lock = -1; + Tcl_MutexUnlock(&ZipFSMutex); +} + +static void +Unlock(void) +{ + Tcl_MutexLock(&ZipFSMutex); + if (ZipFS.lock > 0) { + --ZipFS.lock; + } else if (ZipFS.lock < 0) { + ZipFS.lock = 0; + } + if ((ZipFS.lock == 0) && (ZipFS.waiters > 0)) { + Tcl_ConditionNotify(&ZipFSCond); + } + Tcl_MutexUnlock(&ZipFSMutex); +} + +#else + +#define ReadLock() do {} while (0) +#define WriteLock() do {} while (0) +#define Unlock() do {} while (0) + +#endif + +/* + *------------------------------------------------------------------------- + * + * DosTimeDate, ToDosTime, ToDosDate -- + * + * Functions to perform conversions between DOS time stamps + * and POSIX time_t. + * + *------------------------------------------------------------------------- + */ + +static time_t +DosTimeDate(int dosDate, int dosTime) +{ + struct tm tm; + time_t ret; + + memset(&tm, 0, sizeof (tm)); + tm.tm_year = (((dosDate & 0xfe00) >> 9) + 80); + tm.tm_mon = ((dosDate & 0x1e0) >> 5) - 1; + tm.tm_mday = dosDate & 0x1f; + tm.tm_hour = (dosTime & 0xf800) >> 11; + tm.tm_min = (dosTime & 0x7e) >> 5; + tm.tm_sec = (dosTime & 0x1f) << 1; + ret = mktime(&tm); + if (ret == (time_t) -1) { + /* fallback to 1980-01-01T00:00:00+00:00 (DOS epoch) */ + ret = (time_t) 315532800; + } + return ret; +} + +static int +ToDosTime(time_t when) +{ + struct tm *tmp, tm; + +#ifdef TCL_THREADS +#if defined(_WIN32) || defined(_WIN64) + /* Win32 uses thread local storage */ + tmp = localtime(&when); + tm = *tmp; +#else +#ifdef HAVE_LOCALTIME_R + tmp = &tm; + localtime_r(&when, tmp); +#else + Tcl_MutexLock(&localtimeMutex); + tmp = localtime(&when); + tm = *tmp; + Tcl_MutexUnlock(&localtimeMutex); +#endif +#endif +#else + tmp = localtime(&when); + tm = *tmp; +#endif + return (tm.tm_hour << 11) | (tm.tm_min << 5) | (tm.tm_sec >> 1); +} + +static int +ToDosDate(time_t when) +{ + struct tm *tmp, tm; + +#ifdef TCL_THREADS +#if defined(_WIN32) || defined(_WIN64) + /* Win32 uses thread local storage */ + tmp = localtime(&when); + tm = *tmp; +#else +#ifdef HAVE_LOCALTIME_R + tmp = &tm; + localtime_r(&when, tmp); +#else + Tcl_MutexLock(&localtimeMutex); + tmp = localtime(&when); + tm = *tmp; + Tcl_MutexUnlock(&localtimeMutex); +#endif +#endif +#else + tmp = localtime(&when); + tm = *tmp; +#endif + return ((tm.tm_year - 80) << 9) | ((tm.tm_mon + 1) << 5) | tm.tm_mday; +} + +/* + *------------------------------------------------------------------------- + * + * CountSlashes -- + * + * This function counts the number of slashes in a pathname string. + * + * Results: + * Number of slashes found in string. + * + * Side effects: + * None. + * + *------------------------------------------------------------------------- + */ + +static int +CountSlashes(const char *string) +{ + int count = 0; + const char *p = string; + + while (*p != '\0') { + if (*p == '/') { + count++; + } + p++; + } + return count; +} + +/* + *------------------------------------------------------------------------- + * + * CanonicalPath -- + * + * This function computes the canonical path from a directory + * and file name components into the specified Tcl_DString. + * + * Results: + * Returns the pointer to the canonical path contained in the + * specified Tcl_DString. + * + * Side effects: + * Modifies the specified Tcl_DString. + * + *------------------------------------------------------------------------- + */ + +static char * +CanonicalPath(const char *root, const char *tail, Tcl_DString *dsPtr,int ZIPFSPATH) +{ + char *path; + char *result; + int i, j, c, isunc = 0, isvfs=0, n=0; +#if HAS_DRIVES + int zipfspath=1; + if ((tail[0] != '\0') && (strchr(drvletters, tail[0]) != NULL) && + (tail[1] == ':')) { + tail += 2; + zipfspath=0; + } + /* UNC style path */ + if (tail[0] == '\\') { + root = ""; + ++tail; + zipfspath=0; + } + if (tail[0] == '\\') { + root = "/"; + ++tail; + zipfspath=0; + } + if(zipfspath) { +#endif + /* UNC style path */ + if(root && strncmp(root,ZIPFS_VOLUME,ZIPFS_VOLUME_LEN)==0) { + isvfs=1; + } else if (tail && strncmp(tail,ZIPFS_VOLUME,ZIPFS_VOLUME_LEN) == 0) { + isvfs=2; + } + if(isvfs!=1) { + if ((root[0] == '/') && (root[1] == '/')) { + isunc = 1; + } + } +#if HAS_DRIVES + } +#endif + if(isvfs!=2) { + if (tail[0] == '/') { + if(isvfs!=1) { + root = ""; + } + ++tail; + isunc = 0; + } + if (tail[0] == '/') { + if(isvfs!=1) { + root = "/"; + } + ++tail; + isunc = 1; + } + } + i = strlen(root); + j = strlen(tail); + if(isvfs==1) { + if(i>ZIPFS_VOLUME_LEN) { + Tcl_DStringSetLength(dsPtr, i + j + 1); + path = Tcl_DStringValue(dsPtr); + memcpy(path, root, i); + path[i++] = '/'; + memcpy(path + i, tail, j); + } else { + Tcl_DStringSetLength(dsPtr, i + j); + path = Tcl_DStringValue(dsPtr); + memcpy(path, root, i); + memcpy(path + i, tail, j); + } + } else if(isvfs==2) { + Tcl_DStringSetLength(dsPtr, j); + path = Tcl_DStringValue(dsPtr); + memcpy(path, tail, j); + } else { + if (ZIPFSPATH) { + Tcl_DStringSetLength(dsPtr, i + j + ZIPFS_VOLUME_LEN); + path = Tcl_DStringValue(dsPtr); + memcpy(path, ZIPFS_VOLUME, ZIPFS_VOLUME_LEN); + memcpy(path + ZIPFS_VOLUME_LEN + i , tail, j); + } else { + Tcl_DStringSetLength(dsPtr, i + j + 1); + path = Tcl_DStringValue(dsPtr); + memcpy(path, root, i); + path[i++] = '/'; + memcpy(path + i, tail, j); + } + } +#if HAS_DRIVES + for (i = 0; path[i] != '\0'; i++) { + if (path[i] == '\\') { + path[i] = '/'; + } + } +#endif + if(ZIPFSPATH) { + n=ZIPFS_VOLUME_LEN; + } else { + n=0; + } + for (i = j = n; (c = path[i]) != '\0'; i++) { + if (c == '/') { + int c2 = path[i + 1]; + if (c2 == '/') { + continue; + } + if (c2 == '.') { + int c3 = path[i + 2]; + if ((c3 == '/') || (c3 == '\0')) { + i++; + continue; + } + if ((c3 == '.') && + ((path[i + 3] == '/') || (path [i + 3] == '\0'))) { + i += 2; + while ((j > 0) && (path[j - 1] != '/')) { + j--; + } + if (j > isunc) { + --j; + while ((j > 1 + isunc) && (path[j - 2] == '/')) { + j--; + } + } + continue; + } + } + } + path[j++] = c; + } + if (j == 0) { + path[j++] = '/'; + } + path[j] = 0; + Tcl_DStringSetLength(dsPtr, j); + result=Tcl_DStringValue(dsPtr); + return result; +} + + + +/* + *------------------------------------------------------------------------- + * + * AbsolutePath -- + * + * This function computes the absolute path from a given + * (relative) path name into the specified Tcl_DString. + * + * Results: + * Returns the pointer to the absolute path contained in the + * specified Tcl_DString. + * + * Side effects: + * Modifies the specified Tcl_DString. + * + *------------------------------------------------------------------------- + */ + +static char * +AbsolutePath(const char *path, + Tcl_DString *dsPtr, + int ZIPFSPATH) +{ + char *result; + if (*path == '~') { + Tcl_DStringAppend(dsPtr, path, -1); + return Tcl_DStringValue(dsPtr); + } + if (*path != '/') { + Tcl_DString pwd; + + /* relative path */ + Tcl_DStringInit(&pwd); + Tcl_GetCwd(NULL, &pwd); + result = Tcl_DStringValue(&pwd); + result = CanonicalPath(result, path, dsPtr,ZIPFSPATH); + Tcl_DStringFree(&pwd); + } else { + /* absolute path */ + result = CanonicalPath("", path, dsPtr,ZIPFSPATH); + } + return result; +} + +/* + *------------------------------------------------------------------------- + * + * ZipFSLookup -- + * + * This function returns the ZIP entry struct corresponding to + * the ZIP archive member of the given file name. + * + * Results: + * Returns the pointer to ZIP entry struct or NULL if the + * the given file name could not be found in the global list + * of ZIP archive members. + * + * Side effects: + * None. + * + *------------------------------------------------------------------------- + */ + +static ZipEntry * +ZipFSLookup(char *filename) +{ + char *realname; + + Tcl_HashEntry *hPtr; + ZipEntry *z; + Tcl_DString ds; + Tcl_DStringInit(&ds); + realname = AbsolutePath(filename, &ds, 1); + hPtr = Tcl_FindHashEntry(&ZipFS.fileHash, realname); + z = hPtr ? (ZipEntry *) Tcl_GetHashValue(hPtr) : NULL; + Tcl_DStringFree(&ds); + return z; +} + +#ifdef NEVER_USED + +/* + *------------------------------------------------------------------------- + * + * ZipFSLookupMount -- + * + * This function returns an indication if the given file name + * corresponds to a mounted ZIP archive file. + * + * Results: + * Returns true, if the given file name is a mounted ZIP archive file. + * + * Side effects: + * None. + * + *------------------------------------------------------------------------- + */ + +static int +ZipFSLookupMount(char *filename) +{ + char *realname; + Tcl_HashEntry *hPtr; + Tcl_HashSearch search; + ZipFile *zf; + Tcl_DString ds; + int match = 0; + Tcl_DStringInit(&ds); + realname = AbsolutePath(filename, &ds, 1); + hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); + while (hPtr != NULL) { + if ((zf = (ZipFile *) Tcl_GetHashValue(hPtr)) != NULL) { + if (strcmp(zf->mntpt, realname) == 0) { + match = 1; + break; + } + } + hPtr = Tcl_NextHashEntry(&search); + } + Tcl_DStringFree(&ds); + return match; +} +#endif + +/* + *------------------------------------------------------------------------- + * + * ZipFSCloseArchive -- + * + * This function closes a mounted ZIP archive file. + * + * Results: + * None. + * + * Side effects: + * A memory mapped ZIP archive is unmapped, allocated memory is + * released. + * + *------------------------------------------------------------------------- + */ + +static void +ZipFSCloseArchive(Tcl_Interp *interp, ZipFile *zf) +{ +#if defined(_WIN32) || defined(_WIN64) + if ((zf->data != NULL) && (zf->tofree == NULL)) { + UnmapViewOfFile(zf->data); + zf->data = NULL; + } + if (zf->mh != INVALID_HANDLE_VALUE) { + CloseHandle(zf->mh); + } +#else + if ((zf->data != MAP_FAILED) && (zf->tofree == NULL)) { + munmap(zf->data, zf->length); + zf->data = MAP_FAILED; + } +#endif + if (zf->tofree != NULL) { + Tcl_Free((char *) zf->tofree); + zf->tofree = NULL; + } + Tcl_Close(interp, zf->chan); + zf->chan = NULL; +} + +/* + *------------------------------------------------------------------------- + * + * ZipFSOpenArchive -- + * + * This function opens a ZIP archive file for reading. An attempt + * is made to memory map that file. Otherwise it is read into + * an allocated memory buffer. The ZIP archive header is verified + * and must be valid for the function to succeed. When "needZip" + * is zero an embedded ZIP archive in an executable file is accepted. + * + * Results: + * TCL_OK on success, TCL_ERROR otherwise with an error message + * placed into the given "interp" if it is not NULL. + * + * Side effects: + * ZIP archive is memory mapped or read into allocated memory, + * the given ZipFile struct is filled with information about + * the ZIP archive file. + * + *------------------------------------------------------------------------- + */ + +static int +ZipFSOpenArchive(Tcl_Interp *interp, const char *zipname, int needZip, + ZipFile *zf) +{ + int i; + ClientData handle; + unsigned char *p, *q; + +#if defined(_WIN32) || defined(_WIN64) + zf->data = NULL; + zf->mh = INVALID_HANDLE_VALUE; +#else + zf->data = MAP_FAILED; +#endif + zf->length = 0; + zf->nfiles = 0; + zf->baseoffs = zf->baseoffsp = 0; + zf->tofree = NULL; + zf->pwbuf[0] = 0; + zf->chan = Tcl_OpenFileChannel(interp, zipname, "r", 0); + if (zf->chan == NULL) { + return TCL_ERROR; + } + if (Tcl_GetChannelHandle(zf->chan, TCL_READABLE, &handle) != TCL_OK) { + if (Tcl_SetChannelOption(interp, zf->chan, "-translation", "binary") + != TCL_OK) { + goto error; + } + if (Tcl_SetChannelOption(interp, zf->chan, "-encoding", "binary") + != TCL_OK) { + goto error; + } + zf->length = Tcl_Seek(zf->chan, 0, SEEK_END); + if ((zf->length <= 0) || (zf->length > 64 * 1024 * 1024)) { + if (interp) { + Tcl_SetObjResult(interp, + Tcl_NewStringObj("illegal file size", -1)); + } + goto error; + } + Tcl_Seek(zf->chan, 0, SEEK_SET); + zf->tofree = zf->data = (unsigned char *) Tcl_AttemptAlloc(zf->length); + if (zf->tofree == NULL) { + if (interp) { + Tcl_SetObjResult(interp, + Tcl_NewStringObj("out of memory", -1)); + } + goto error; + } + i = Tcl_Read(zf->chan, (char *) zf->data, zf->length); + if (i != zf->length) { + if (interp) { + Tcl_SetObjResult(interp, + Tcl_NewStringObj("file read error", -1)); + } + goto error; + } + Tcl_Close(interp, zf->chan); + zf->chan = NULL; + } else { +#if defined(_WIN32) || defined(_WIN64) + zf->length = GetFileSize((HANDLE) handle, 0); + if ((zf->length == INVALID_FILE_SIZE) || + (zf->length < ZIP_CENTRAL_END_LEN)) { + if (interp != NULL) { + Tcl_SetObjResult(interp, + Tcl_NewStringObj("invalid file size", -1)); + } + goto error; + } + zf->mh = CreateFileMapping((HANDLE) handle, 0, PAGE_READONLY, 0, + zf->length, 0); + if (zf->mh == INVALID_HANDLE_VALUE) { + if (interp != NULL) { + Tcl_SetObjResult(interp, + Tcl_NewStringObj("file mapping failed", -1)); + } + goto error; + } + zf->data = MapViewOfFile(zf->mh, FILE_MAP_READ, 0, 0, zf->length); + if (zf->data == NULL) { + if (interp != NULL) { + Tcl_SetObjResult(interp, + Tcl_NewStringObj("file mapping failed", -1)); + } + goto error; + } +#else + zf->length = lseek((int) (long) handle, 0, SEEK_END); + if ((zf->length == -1) || (zf->length < ZIP_CENTRAL_END_LEN)) { + if (interp != NULL) { + Tcl_SetObjResult(interp, + Tcl_NewStringObj("invalid file size", -1)); + } + goto error; + } + lseek((int) (long) handle, 0, SEEK_SET); + zf->data = (unsigned char *) mmap(0, zf->length, PROT_READ, + MAP_FILE | MAP_PRIVATE, + (int) (long) handle, 0); + if (zf->data == MAP_FAILED) { + if (interp != NULL) { + Tcl_SetObjResult(interp, + Tcl_NewStringObj("file mapping failed", -1)); + } + goto error; + } +#endif + } + p = zf->data + zf->length - ZIP_CENTRAL_END_LEN; + while (p >= zf->data) { + if (*p == (ZIP_CENTRAL_END_SIG & 0xFF)) { + if (zip_read_int(p) == ZIP_CENTRAL_END_SIG) { + break; + } + p -= ZIP_SIG_LEN; + } else { + --p; + } + } + if (p < zf->data) { + if (!needZip) { + zf->baseoffs = zf->baseoffsp = zf->length; + return TCL_OK; + } + if (interp != NULL) { + Tcl_SetObjResult(interp, + Tcl_NewStringObj("wrong end signature", -1)); + } + goto error; + } + zf->nfiles = zip_read_short(p + ZIP_CENTRAL_ENTS_OFFS); + if (zf->nfiles == 0) { + if (!needZip) { + zf->baseoffs = zf->baseoffsp = zf->length; + return TCL_OK; + } + if (interp != NULL) { + Tcl_SetObjResult(interp, + Tcl_NewStringObj("empty archive", -1)); + } + goto error; + } + q = zf->data + zip_read_int(p + ZIP_CENTRAL_DIRSTART_OFFS); + p -= zip_read_int(p + ZIP_CENTRAL_DIRSIZE_OFFS); + if ((p < zf->data) || (p > (zf->data + zf->length)) || + (q < zf->data) || (q > (zf->data + zf->length))) { + if (!needZip) { + zf->baseoffs = zf->baseoffsp = zf->length; + return TCL_OK; + } + if (interp != NULL) { + Tcl_SetObjResult(interp, + Tcl_NewStringObj("archive directory not found", -1)); + } + goto error; + } + zf->baseoffs = zf->baseoffsp = p - q; + zf->centoffs = p - zf->data; + q = p; + for (i = 0; i < zf->nfiles; i++) { + int pathlen, comlen, extra; + + if ((q + ZIP_CENTRAL_HEADER_LEN) > (zf->data + zf->length)) { + if (interp != NULL) { + Tcl_SetObjResult(interp, + Tcl_NewStringObj("wrong header length", -1)); + } + goto error; + } + if (zip_read_int(q) != ZIP_CENTRAL_HEADER_SIG) { + if (interp != NULL) { + Tcl_SetObjResult(interp, + Tcl_NewStringObj("wrong header signature", -1)); + } + goto error; + } + pathlen = zip_read_short(q + ZIP_CENTRAL_PATHLEN_OFFS); + comlen = zip_read_short(q + ZIP_CENTRAL_FCOMMENTLEN_OFFS); + extra = zip_read_short(q + ZIP_CENTRAL_EXTRALEN_OFFS); + q += pathlen + comlen + extra + ZIP_CENTRAL_HEADER_LEN; + } + q = zf->data + zf->baseoffs; + if ((zf->baseoffs >= 6) && + (zip_read_int(q - 4) == ZIP_PASSWORD_END_SIG)) { + i = q[-5]; + if (q - 5 - i > zf->data) { + zf->pwbuf[0] = i; + memcpy(zf->pwbuf + 1, q - 5 - i, i); + zf->baseoffsp -= i ? (5 + i) : 0; + } + } + return TCL_OK; + +error: + ZipFSCloseArchive(interp, zf); + return TCL_ERROR; +} + +/* + *------------------------------------------------------------------------- + * + * TclZipfsMount -- + * + * This procedure is invoked to mount a given ZIP archive file on + * a given mountpoint with optional ZIP password. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * A ZIP archive file is read, analyzed and mounted, resources are + * allocated. + * + *------------------------------------------------------------------------- + */ + +int +TclZipfsMount(Tcl_Interp *interp, const char *zipname, const char *mntpt, + const char *passwd) +{ + char *realname, *p; + int i, pwlen, isNew; + ZipFile *zf, zf0; + ZipEntry *z; + Tcl_HashEntry *hPtr; + Tcl_DString ds, dsm, fpBuf; + unsigned char *q; + + ReadLock(); + if (!ZipFS.initialized) { + if (interp != NULL) { + Tcl_SetObjResult(interp, + Tcl_NewStringObj("not initialized", -1)); + } + Unlock(); + return TCL_ERROR; + } + if (zipname == NULL) { + Tcl_HashSearch search; + int ret = TCL_OK; + + i = 0; + hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); + while (hPtr != NULL) { + if ((zf = (ZipFile *) Tcl_GetHashValue(hPtr)) != NULL) { + if (interp != NULL) { + Tcl_AppendElement(interp, zf->mntpt); + Tcl_AppendElement(interp, zf->name); + } + ++i; + } + hPtr = Tcl_NextHashEntry(&search); + } + if (interp == NULL) { + ret = (i > 0) ? TCL_OK : TCL_BREAK; + } + Unlock(); + return ret; + } + if (mntpt == NULL) { + if (interp == NULL) { + Unlock(); + return TCL_OK; + } + Tcl_DStringInit(&ds); + p = AbsolutePath(zipname, &ds, 0); + hPtr = Tcl_FindHashEntry(&ZipFS.zipHash, p); + if (hPtr != NULL) { + if ((zf = Tcl_GetHashValue(hPtr)) != NULL) { + Tcl_SetObjResult(interp, + Tcl_NewStringObj(zf->mntpt, zf->mntptlen)); + } + } + Unlock(); + Tcl_DStringFree(&ds); + return TCL_OK; + } + Unlock(); + pwlen = 0; + if (passwd != NULL) { + pwlen = strlen(passwd); + if ((pwlen > 255) || (strchr(passwd, 0xff) != NULL)) { + if (interp) { + Tcl_SetObjResult(interp, + Tcl_NewStringObj("illegal password", -1)); + } + return TCL_ERROR; + } + } + if (ZipFSOpenArchive(interp, zipname, 1, &zf0) != TCL_OK) { + return TCL_ERROR; + } + Tcl_DStringInit(&ds); + realname = AbsolutePath(zipname, &ds, 0); + /* + * Mount point can come from Tcl_GetNameOfExecutable() + * which sometimes is a relative or otherwise denormalized path. + * But an absolute name is needed as mount point here. + */ + Tcl_DStringInit(&dsm); + mntpt = CanonicalPath("", mntpt, &dsm, 1); + WriteLock(); + hPtr = Tcl_CreateHashEntry(&ZipFS.zipHash, realname, &isNew); + Tcl_DStringSetLength(&ds, 0); + if (!isNew) { + zf = (ZipFile *) Tcl_GetHashValue(hPtr); + if (interp != NULL) { + Tcl_AppendResult(interp, "already mounted on \"", zf->mntptlen ? + zf->mntpt : "/", "\"", (char *) NULL); + } + Unlock(); + Tcl_DStringFree(&ds); + Tcl_DStringFree(&dsm); + ZipFSCloseArchive(interp, &zf0); + return TCL_ERROR; + } + if (strcmp(mntpt, "/") == 0) { + mntpt = ""; + } + zf = (ZipFile *) Tcl_AttemptAlloc(sizeof (*zf) + strlen(mntpt) + 1); + if (zf == NULL) { + if (interp != NULL) { + Tcl_AppendResult(interp, "out of memory", (char *) NULL); + } + Unlock(); + Tcl_DStringFree(&ds); + Tcl_DStringFree(&dsm); + ZipFSCloseArchive(interp, &zf0); + return TCL_ERROR; + } + *zf = zf0; + zf->name = Tcl_GetHashKey(&ZipFS.zipHash, hPtr); + strcpy(zf->mntpt, mntpt); + zf->mntptlen = strlen(zf->mntpt); + zf->entries = NULL; + zf->topents = NULL; + zf->nopen = 0; + Tcl_SetHashValue(hPtr, (ClientData) zf); + if ((zf->pwbuf[0] == 0) && pwlen) { + int k = 0; + i = pwlen; + zf->pwbuf[k++] = i; + while (i > 0) { + zf->pwbuf[k] = (passwd[i - 1] & 0x0f) | + pwrot[(passwd[i - 1] >> 4) & 0x0f]; + k++; + i--; + } + zf->pwbuf[k] = '\0'; + } + if (mntpt[0] != '\0') { + z = (ZipEntry *) Tcl_Alloc(sizeof (*z)); + z->name = NULL; + z->tnext = NULL; + z->depth = CountSlashes(mntpt); + z->zipfile = zf; + z->isdir = 1; + z->isenc = 0; + z->offset = zf->baseoffs; + z->crc32 = 0; + z->timestamp = 0; + z->nbyte = z->nbytecompr = 0; + z->cmeth = ZIP_COMPMETH_STORED; + z->data = NULL; + hPtr = Tcl_CreateHashEntry(&ZipFS.fileHash, mntpt, &isNew); + if (!isNew) { + /* skip it */ + Tcl_Free((char *) z); + } else { + Tcl_SetHashValue(hPtr, (ClientData) z); + z->name = Tcl_GetHashKey(&ZipFS.fileHash, hPtr); + z->next = zf->entries; + zf->entries = z; + } + } + q = zf->data + zf->centoffs; + Tcl_DStringInit(&fpBuf); + for (i = 0; i < zf->nfiles; i++) { + int pathlen, comlen, extra, isdir = 0, dosTime, dosDate, nbcompr, offs; + unsigned char *lq, *gq = NULL; + char *fullpath, *path; + + pathlen = zip_read_short(q + ZIP_CENTRAL_PATHLEN_OFFS); + comlen = zip_read_short(q + ZIP_CENTRAL_FCOMMENTLEN_OFFS); + extra = zip_read_short(q + ZIP_CENTRAL_EXTRALEN_OFFS); + Tcl_DStringSetLength(&ds, 0); + Tcl_DStringAppend(&ds, (char *) q + ZIP_CENTRAL_HEADER_LEN, pathlen); + path = Tcl_DStringValue(&ds); + if ((pathlen > 0) && (path[pathlen - 1] == '/')) { + Tcl_DStringSetLength(&ds, pathlen - 1); + path = Tcl_DStringValue(&ds); + isdir = 1; + } + if ((strcmp(path, ".") == 0) || (strcmp(path, "..") == 0)) { + goto nextent; + } + lq = zf->data + zf->baseoffs + + zip_read_int(q + ZIP_CENTRAL_LOCALHDR_OFFS); + if ((lq < zf->data) || (lq > (zf->data + zf->length))) { + goto nextent; + } + nbcompr = zip_read_int(lq + ZIP_LOCAL_COMPLEN_OFFS); + if (!isdir && (nbcompr == 0) && + (zip_read_int(lq + ZIP_LOCAL_UNCOMPLEN_OFFS) == 0) && + (zip_read_int(lq + ZIP_LOCAL_CRC32_OFFS) == 0)) { + gq = q; + nbcompr = zip_read_int(gq + ZIP_CENTRAL_COMPLEN_OFFS); + } + offs = (lq - zf->data) + + ZIP_LOCAL_HEADER_LEN + + zip_read_short(lq + ZIP_LOCAL_PATHLEN_OFFS) + + zip_read_short(lq + ZIP_LOCAL_EXTRALEN_OFFS); + if ((offs + nbcompr) > zf->length) { + goto nextent; + } + if (!isdir && (mntpt[0] == '\0') && !CountSlashes(path)) { +#ifdef ANDROID + /* + * When mounting the ZIP archive on the root directory try + * to remap top level regular files of the archive to + * /assets/.root/... since this directory should not be + * in a valid APK due to the leading dot in the file name + * component. This trick should make the files + * AndroidManifest.xml, resources.arsc, and classes.dex + * visible to Tcl. + */ + Tcl_DString ds2; + + Tcl_DStringInit(&ds2); + Tcl_DStringAppend(&ds2, "assets/.root/", -1); + Tcl_DStringAppend(&ds2, path, -1); + hPtr = Tcl_FindHashEntry(&ZipFS.fileHash, Tcl_DStringValue(&ds2)); + if (hPtr != NULL) { + /* should not happen but skip it anyway */ + Tcl_DStringFree(&ds2); + goto nextent; + } + Tcl_DStringSetLength(&ds, 0); + Tcl_DStringAppend(&ds, Tcl_DStringValue(&ds2), + Tcl_DStringLength(&ds2)); + path = Tcl_DStringValue(&ds); + Tcl_DStringFree(&ds2); +#else + /* + * Regular files skipped when mounting on root. + */ + goto nextent; +#endif + } + Tcl_DStringSetLength(&fpBuf, 0); + fullpath = CanonicalPath(mntpt, path, &fpBuf, 1); + z = (ZipEntry *) Tcl_Alloc(sizeof (*z)); + z->name = NULL; + z->tnext = NULL; + z->depth = CountSlashes(fullpath); + z->zipfile = zf; + z->isdir = isdir; + z->isenc = (zip_read_short(lq + ZIP_LOCAL_FLAGS_OFFS) & 1) + && (nbcompr > 12); + z->offset = offs; + if (gq != NULL) { + z->crc32 = zip_read_int(gq + ZIP_CENTRAL_CRC32_OFFS); + dosDate = zip_read_short(gq + ZIP_CENTRAL_MDATE_OFFS); + dosTime = zip_read_short(gq + ZIP_CENTRAL_MTIME_OFFS); + z->timestamp = DosTimeDate(dosDate, dosTime); + z->nbyte = zip_read_int(gq + ZIP_CENTRAL_UNCOMPLEN_OFFS); + z->cmeth = zip_read_short(gq + ZIP_CENTRAL_COMPMETH_OFFS); + } else { + z->crc32 = zip_read_int(lq + ZIP_LOCAL_CRC32_OFFS); + dosDate = zip_read_short(lq + ZIP_LOCAL_MDATE_OFFS); + dosTime = zip_read_short(lq + ZIP_LOCAL_MTIME_OFFS); + z->timestamp = DosTimeDate(dosDate, dosTime); + z->nbyte = zip_read_int(lq + ZIP_LOCAL_UNCOMPLEN_OFFS); + z->cmeth = zip_read_short(lq + ZIP_LOCAL_COMPMETH_OFFS); + } + z->nbytecompr = nbcompr; + z->data = NULL; + hPtr = Tcl_CreateHashEntry(&ZipFS.fileHash, fullpath, &isNew); + if (!isNew) { + /* should not happen but skip it anyway */ + Tcl_Free((char *) z); + } else { + Tcl_SetHashValue(hPtr, (ClientData) z); + z->name = Tcl_GetHashKey(&ZipFS.fileHash, hPtr); + z->next = zf->entries; + zf->entries = z; + if (isdir && (mntpt[0] == '\0') && (z->depth == 1)) { + z->tnext = zf->topents; + zf->topents = z; + } + if (!z->isdir && (z->depth > 1)) { + char *dir, *end; + ZipEntry *zd; + + Tcl_DStringSetLength(&ds, strlen(z->name) + 8); + Tcl_DStringSetLength(&ds, 0); + Tcl_DStringAppend(&ds, z->name, -1); + dir = Tcl_DStringValue(&ds); + end = strrchr(dir, '/'); + while ((end != NULL) && (end != dir)) { + Tcl_DStringSetLength(&ds, end - dir); + hPtr = Tcl_FindHashEntry(&ZipFS.fileHash, dir); + if (hPtr != NULL) { + break; + } + zd = (ZipEntry *) Tcl_Alloc(sizeof (*zd)); + zd->name = NULL; + zd->tnext = NULL; + zd->depth = CountSlashes(dir); + zd->zipfile = zf; + zd->isdir = 1; + zd->isenc = 0; + zd->offset = z->offset; + zd->crc32 = 0; + zd->timestamp = z->timestamp; + zd->nbyte = zd->nbytecompr = 0; + zd->cmeth = ZIP_COMPMETH_STORED; + zd->data = NULL; + hPtr = Tcl_CreateHashEntry(&ZipFS.fileHash, dir, &isNew); + if (!isNew) { + /* should not happen but skip it anyway */ + Tcl_Free((char *) zd); + } else { + Tcl_SetHashValue(hPtr, (ClientData) zd); + zd->name = Tcl_GetHashKey(&ZipFS.fileHash, hPtr); + zd->next = zf->entries; + zf->entries = zd; + if ((mntpt[0] == '\0') && (zd->depth == 1)) { + zd->tnext = zf->topents; + zf->topents = zd; + } + } + end = strrchr(dir, '/'); + } + } + } +nextent: + q += pathlen + comlen + extra + ZIP_CENTRAL_HEADER_LEN; + } + Unlock(); + Tcl_DStringFree(&fpBuf); + Tcl_DStringFree(&ds); + Tcl_DStringFree(&dsm); + Tcl_FSMountsChanged(NULL); + return TCL_OK; +} + +/* + *------------------------------------------------------------------------- + * + * TclZipfsUnmount -- + * + * This procedure is invoked to unmount a given ZIP archive. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * A mounted ZIP archive file is unmounted, resources are free'd. + * + *------------------------------------------------------------------------- + */ + +int +TclZipfsUnmount(Tcl_Interp *interp, const char *zipname) +{ + char *realname; + ZipFile *zf; + ZipEntry *z, *znext; + Tcl_HashEntry *hPtr; + Tcl_DString ds; + int ret = TCL_OK, unmounted = 0; + + Tcl_DStringInit(&ds); + realname = AbsolutePath(zipname, &ds, 0); + WriteLock(); + if (!ZipFS.initialized) { + goto done; + } + hPtr = Tcl_FindHashEntry(&ZipFS.zipHash, realname); + if (hPtr == NULL) { + /* don't report error */ + goto done; + } + zf = (ZipFile *) Tcl_GetHashValue(hPtr); + if (zf->nopen > 0) { + if (interp != NULL) { + Tcl_SetObjResult(interp, + Tcl_NewStringObj("filesystem is busy", -1)); + } + ret = TCL_ERROR; + goto done; + } + Tcl_DeleteHashEntry(hPtr); + for (z = zf->entries; z; z = znext) { + znext = z->next; + hPtr = Tcl_FindHashEntry(&ZipFS.fileHash, z->name); + if (hPtr) { + Tcl_DeleteHashEntry(hPtr); + } + if (z->data != NULL) { + Tcl_Free((char *) z->data); + } + Tcl_Free((char *) z); + } + ZipFSCloseArchive(interp, zf); + Tcl_Free((char *) zf); + unmounted = 1; +done: + Unlock(); + Tcl_DStringFree(&ds); + if (unmounted) { + Tcl_FSMountsChanged(NULL); + } + return ret; +} + +/* + *------------------------------------------------------------------------- + * + * ZipFSMountObjCmd -- + * + * This procedure is invoked to process the "zipfs::mount" command. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * A ZIP archive file is mounted, resources are allocated. + * + *------------------------------------------------------------------------- + */ + +static int +ZipFSMountObjCmd(ClientData clientData, Tcl_Interp *interp, + int objc, Tcl_Obj *const objv[]) +{ + if (objc > 4) { + Tcl_WrongNumArgs(interp, 1, objv, + "?zipfile? ?mountpoint? ?password?"); + return TCL_ERROR; + } + return TclZipfsMount(interp, (objc > 1) ? Tcl_GetString(objv[1]) : NULL, + (objc > 2) ? Tcl_GetString(objv[2]) : NULL, + (objc > 3) ? Tcl_GetString(objv[3]) : NULL); +} + +/* + *------------------------------------------------------------------------- + * + * ZipFSUnmountObjCmd -- + * + * This procedure is invoked to process the "zipfs::unmount" command. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * A mounted ZIP archive file is unmounted, resources are free'd. + * + *------------------------------------------------------------------------- + */ + +static int +ZipFSUnmountObjCmd(ClientData clientData, Tcl_Interp *interp, + int objc, Tcl_Obj *const objv[]) +{ + if (objc != 2) { + Tcl_WrongNumArgs(interp, 1, objv, "zipfile"); + return TCL_ERROR; + } + return TclZipfsUnmount(interp, Tcl_GetString(objv[1])); +} + +/* + *------------------------------------------------------------------------- + * + * ZipFSMkKeyObjCmd -- + * + * This procedure is invoked to process the "zipfs::mkkey" command. + * It produces a rotated password to be embedded into an image file. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * None. + * + *------------------------------------------------------------------------- + */ + +static int +ZipFSMkKeyObjCmd(ClientData clientData, Tcl_Interp *interp, + int objc, Tcl_Obj *const objv[]) +{ + int len, i = 0; + char *pw, pwbuf[264]; + + if (objc != 2) { + Tcl_WrongNumArgs(interp, 1, objv, "password"); + return TCL_ERROR; + } + pw = Tcl_GetString(objv[1]); + len = strlen(pw); + if (len == 0) { + return TCL_OK; + } + if ((len > 255) || (strchr(pw, 0xff) != NULL)) { + Tcl_SetObjResult(interp, + Tcl_NewStringObj("illegal password", -1)); + return TCL_ERROR; + } + while (len > 0) { + int ch = pw[len - 1]; + + pwbuf[i] = (ch & 0x0f) | pwrot[(ch >> 4) & 0x0f]; + i++; + len--; + } + pwbuf[i] = i; + ++i; + pwbuf[i++] = (char) ZIP_PASSWORD_END_SIG; + pwbuf[i++] = (char) (ZIP_PASSWORD_END_SIG >> 8); + pwbuf[i++] = (char) (ZIP_PASSWORD_END_SIG >> 16); + pwbuf[i++] = (char) (ZIP_PASSWORD_END_SIG >> 24); + pwbuf[i] = '\0'; + Tcl_AppendResult(interp, pwbuf, (char *) NULL); + return TCL_OK; +} + +/* + *------------------------------------------------------------------------- + * + * ZipAddFile -- + * + * This procedure is used by ZipFSMkZipOrImgCmd() to add a single + * file to the output ZIP archive file being written. A ZipEntry + * struct about the input file is added to the given fileHash table + * for later creation of the central ZIP directory. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * Input file is read and (compressed and) written to the output + * ZIP archive file. + * + *------------------------------------------------------------------------- + */ + +static int +ZipAddFile(Tcl_Interp *interp, const char *path, const char *name, + Tcl_Channel out, const char *passwd, + char *buf, int bufsize, Tcl_HashTable *fileHash) +{ + Tcl_Channel in; + Tcl_HashEntry *hPtr; + ZipEntry *z; + z_stream stream; + const char *zpath; + int nbyte, nbytecompr, len, crc, flush, pos[3], zpathlen, olen; + int mtime = 0, isNew, align = 0, cmeth; + unsigned long keys[3], keys0[3]; + char obuf[4096]; + + zpath = name; + while (zpath != NULL && zpath[0] == '/') { + zpath++; + } + if ((zpath == NULL) || (zpath[0] == '\0')) { + return TCL_OK; + } + zpathlen = strlen(zpath); + if (zpathlen + ZIP_CENTRAL_HEADER_LEN > bufsize) { + Tcl_AppendResult(interp, "path too long for \"", path, "\"", + (char *) NULL); + return TCL_ERROR; + } + in = Tcl_OpenFileChannel(interp, path, "r", 0); + if ((in == NULL) || + (Tcl_SetChannelOption(interp, in, "-translation", "binary") + != TCL_OK) || + (Tcl_SetChannelOption(interp, in, "-encoding", "binary") + != TCL_OK)) { +#if defined(_WIN32) || defined(_WIN64) + /* hopefully a directory */ + if (strcmp("permission denied", Tcl_PosixError(interp)) == 0) { + Tcl_Close(interp, in); + return TCL_OK; + } +#endif + Tcl_Close(interp, in); + return TCL_ERROR; + } else { + Tcl_Obj *pathObj = Tcl_NewStringObj(path, -1); + Tcl_StatBuf statBuf; + + Tcl_IncrRefCount(pathObj); + if (Tcl_FSStat(pathObj, &statBuf) != -1) { + mtime = statBuf.st_mtime; + } + Tcl_DecrRefCount(pathObj); + } + Tcl_ResetResult(interp); + crc = 0; + nbyte = nbytecompr = 0; + while ((len = Tcl_Read(in, buf, bufsize)) > 0) { + crc = crc32(crc, (unsigned char *) buf, len); + nbyte += len; + } + if (len == -1) { + if (nbyte == 0) { + if (strcmp("illegal operation on a directory", + Tcl_PosixError(interp)) == 0) { + Tcl_Close(interp, in); + return TCL_OK; + } + } + Tcl_AppendResult(interp, "read error on \"", path, "\"", + (char *) NULL); + Tcl_Close(interp, in); + return TCL_ERROR; + } + if (Tcl_Seek(in, 0, SEEK_SET) == -1) { + Tcl_AppendResult(interp, "seek error on \"", path, "\"", + (char *) NULL); + Tcl_Close(interp, in); + return TCL_ERROR; + } + pos[0] = Tcl_Tell(out); + memset(buf, '\0', ZIP_LOCAL_HEADER_LEN); + memcpy(buf + ZIP_LOCAL_HEADER_LEN, zpath, zpathlen); + len = zpathlen + ZIP_LOCAL_HEADER_LEN; + if (Tcl_Write(out, buf, len) != len) { +wrerr: + Tcl_AppendResult(interp, "write error", (char *) NULL); + Tcl_Close(interp, in); + return TCL_ERROR; + } + if ((len + pos[0]) & 3) { + char abuf[8]; + + /* + * Align payload to next 4-byte boundary using a dummy extra + * entry similar to the zipalign tool from Android's SDK. + */ + align = 4 + ((len + pos[0]) & 3); + zip_write_short(abuf, 0xffff); + zip_write_short(abuf + 2, align - 4); + zip_write_int(abuf + 4, 0x03020100); + if (Tcl_Write(out, abuf, align) != align) { + goto wrerr; + } + } + if (passwd != NULL) { + int i, ch, tmp; + unsigned char kvbuf[24]; + Tcl_Obj *ret; + + init_keys(passwd, keys, crc32tab); + for (i = 0; i < 12 - 2; i++) { + if (Tcl_EvalEx(interp, "expr int(rand() * 256) % 256", -1, 0) != TCL_OK) { + Tcl_AppendResult(interp, "PRNG error", (char *) NULL); + Tcl_Close(interp, in); + return TCL_ERROR; + } + ret = Tcl_GetObjResult(interp); + if (Tcl_GetIntFromObj(interp, ret, &ch) != TCL_OK) { + Tcl_Close(interp, in); + return TCL_ERROR; + } + kvbuf[i + 12] = (unsigned char) zencode(keys, crc32tab, ch, tmp); + } + Tcl_ResetResult(interp); + init_keys(passwd, keys, crc32tab); + for (i = 0; i < 12 - 2; i++) { + kvbuf[i] = (unsigned char) zencode(keys, crc32tab, + kvbuf[i + 12], tmp); + } + kvbuf[i++] = (unsigned char) zencode(keys, crc32tab, crc >> 16, tmp); + kvbuf[i++] = (unsigned char) zencode(keys, crc32tab, crc >> 24, tmp); + len = Tcl_Write(out, (char *) kvbuf, 12); + memset(kvbuf, 0, 24); + if (len != 12) { + Tcl_AppendResult(interp, "write error", (char *) NULL); + Tcl_Close(interp, in); + return TCL_ERROR; + } + memcpy(keys0, keys, sizeof (keys0)); + nbytecompr += 12; + } + Tcl_Flush(out); + pos[2] = Tcl_Tell(out); + cmeth = ZIP_COMPMETH_DEFLATED; + memset(&stream, 0, sizeof (stream)); + stream.zalloc = Z_NULL; + stream.zfree = Z_NULL; + stream.opaque = Z_NULL; + if (deflateInit2(&stream, 9, Z_DEFLATED, -15, 8, Z_DEFAULT_STRATEGY) + != Z_OK) { + Tcl_AppendResult(interp, "compression init error on \"", path, "\"", + (char *) NULL); + Tcl_Close(interp, in); + return TCL_ERROR; + } + do { + len = Tcl_Read(in, buf, bufsize); + if (len == -1) { + Tcl_AppendResult(interp, "read error on \"", path, "\"", + (char *) NULL); + deflateEnd(&stream); + Tcl_Close(interp, in); + return TCL_ERROR; + } + stream.avail_in = len; + stream.next_in = (unsigned char *) buf; + flush = Tcl_Eof(in) ? Z_FINISH : Z_NO_FLUSH; + do { + stream.avail_out = sizeof (obuf); + stream.next_out = (unsigned char *) obuf; + len = deflate(&stream, flush); + if (len == Z_STREAM_ERROR) { + Tcl_AppendResult(interp, "deflate error on \"", path, "\"", + (char *) NULL); + deflateEnd(&stream); + Tcl_Close(interp, in); + return TCL_ERROR; + } + olen = sizeof (obuf) - stream.avail_out; + if (passwd != NULL) { + int i, tmp; + + for (i = 0; i < olen; i++) { + obuf[i] = (char) zencode(keys, crc32tab, obuf[i], tmp); + } + } + if (olen && (Tcl_Write(out, obuf, olen) != olen)) { + Tcl_AppendResult(interp, "write error", (char *) NULL); + deflateEnd(&stream); + Tcl_Close(interp, in); + return TCL_ERROR; + } + nbytecompr += olen; + } while (stream.avail_out == 0); + } while (flush != Z_FINISH); + deflateEnd(&stream); + Tcl_Flush(out); + pos[1] = Tcl_Tell(out); + if (nbyte - nbytecompr <= 0) { + /* + * Compressed file larger than input, + * write it again uncompressed. + */ + if ((int) Tcl_Seek(in, 0, SEEK_SET) != 0) { + goto seekErr; + } + if ((int) Tcl_Seek(out, pos[2], SEEK_SET) != pos[2]) { +seekErr: + Tcl_Close(interp, in); + Tcl_AppendResult(interp, "seek error", (char *) NULL); + return TCL_ERROR; + } + nbytecompr = (passwd != NULL) ? 12 : 0; + while (1) { + len = Tcl_Read(in, buf, bufsize); + if (len == -1) { + Tcl_AppendResult(interp, "read error on \"", path, "\"", + (char *) NULL); + Tcl_Close(interp, in); + return TCL_ERROR; + } else if (len == 0) { + break; + } + if (passwd != NULL) { + int i, tmp; + + for (i = 0; i < len; i++) { + buf[i] = (char) zencode(keys0, crc32tab, buf[i], tmp); + } + } + if (Tcl_Write(out, buf, len) != len) { + Tcl_AppendResult(interp, "write error", (char *) NULL); + Tcl_Close(interp, in); + return TCL_ERROR; + } + nbytecompr += len; + } + cmeth = ZIP_COMPMETH_STORED; + Tcl_Flush(out); + pos[1] = Tcl_Tell(out); + Tcl_TruncateChannel(out, pos[1]); + } + Tcl_Close(interp, in); + + z = (ZipEntry *) Tcl_Alloc(sizeof (*z)); + z->name = NULL; + z->tnext = NULL; + z->depth = 0; + z->zipfile = NULL; + z->isdir = 0; + z->isenc = (passwd != NULL) ? 1 : 0; + z->offset = pos[0]; + z->crc32 = crc; + z->timestamp = mtime; + z->nbyte = nbyte; + z->nbytecompr = nbytecompr; + z->cmeth = cmeth; + z->data = NULL; + hPtr = Tcl_CreateHashEntry(fileHash, zpath, &isNew); + if (!isNew) { + Tcl_AppendResult(interp, "non-unique path name \"", path, "\"", + (char *) NULL); + Tcl_Free((char *) z); + return TCL_ERROR; + } else { + Tcl_SetHashValue(hPtr, (ClientData) z); + z->name = Tcl_GetHashKey(fileHash, hPtr); + z->next = NULL; + } + + /* + * Write final local header information. + */ + zip_write_int(buf + ZIP_LOCAL_SIG_OFFS, ZIP_LOCAL_HEADER_SIG); + zip_write_short(buf + ZIP_LOCAL_VERSION_OFFS, ZIP_MIN_VERSION); + zip_write_short(buf + ZIP_LOCAL_FLAGS_OFFS, z->isenc); + zip_write_short(buf + ZIP_LOCAL_COMPMETH_OFFS, z->cmeth); + zip_write_short(buf + ZIP_LOCAL_MTIME_OFFS, ToDosTime(z->timestamp)); + zip_write_short(buf + ZIP_LOCAL_MDATE_OFFS, ToDosDate(z->timestamp)); + zip_write_int(buf + ZIP_LOCAL_CRC32_OFFS, z->crc32); + zip_write_int(buf + ZIP_LOCAL_COMPLEN_OFFS, z->nbytecompr); + zip_write_int(buf + ZIP_LOCAL_UNCOMPLEN_OFFS, z->nbyte); + zip_write_short(buf + ZIP_LOCAL_PATHLEN_OFFS, zpathlen); + zip_write_short(buf + ZIP_LOCAL_EXTRALEN_OFFS, align); + if ((int) Tcl_Seek(out, pos[0], SEEK_SET) != pos[0]) { + Tcl_DeleteHashEntry(hPtr); + Tcl_Free((char *) z); + Tcl_AppendResult(interp, "seek error", (char *) NULL); + return TCL_ERROR; + } + if (Tcl_Write(out, buf, ZIP_LOCAL_HEADER_LEN) != ZIP_LOCAL_HEADER_LEN) { + Tcl_DeleteHashEntry(hPtr); + Tcl_Free((char *) z); + Tcl_AppendResult(interp, "write error", (char *) NULL); + return TCL_ERROR; + } + Tcl_Flush(out); + if ((int) Tcl_Seek(out, pos[1], SEEK_SET) != pos[1]) { + Tcl_DeleteHashEntry(hPtr); + Tcl_Free((char *) z); + Tcl_AppendResult(interp, "seek error", (char *) NULL); + return TCL_ERROR; + } + return TCL_OK; +} + +/* + *------------------------------------------------------------------------- + * + * ZipFSMkZipOrImgObjCmd -- + * + * This procedure is creates a new ZIP archive file or image file + * given output filename, input directory of files to be archived, + * optional password, and optional image to be prepended to the + * output ZIP archive file. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * A new ZIP archive file or image file is written. + * + *------------------------------------------------------------------------- + */ + +static int +ZipFSMkZipOrImgObjCmd(ClientData clientData, Tcl_Interp *interp, + int isImg, int isList, int objc, Tcl_Obj *const objv[]) +{ + Tcl_Channel out; + int len = 0, pwlen = 0, slen = 0, i, count, ret = TCL_ERROR, lobjc, pos[3]; + Tcl_Obj **lobjv, *list = NULL; + ZipEntry *z; + Tcl_HashEntry *hPtr; + Tcl_HashSearch search; + Tcl_HashTable fileHash; + char *strip = NULL, *pw = NULL, pwbuf[264], buf[4096]; + + if (isList) { + if ((objc < 3) || (objc > (isImg ? 5 : 4))) { + Tcl_WrongNumArgs(interp, 1, objv, isImg ? + "outfile inlist ?password infile?" : + "outfile inlist ?password?"); + return TCL_ERROR; + } + } else { + if ((objc < 3) || (objc > (isImg ? 6 : 5))) { + Tcl_WrongNumArgs(interp, 1, objv, isImg ? + "outfile indir ?strip? ?password? ?infile?" : + "outfile indir ?strip? ?password?"); + return TCL_ERROR; + } + } + pwbuf[0] = 0; + if (objc > (isList ? 3 : 4)) { + pw = Tcl_GetString(objv[isList ? 3 : 4]); + pwlen = strlen(pw); + if ((pwlen > 255) || (strchr(pw, 0xff) != NULL)) { + Tcl_SetObjResult(interp, + Tcl_NewStringObj("illegal password", -1)); + return TCL_ERROR; + } + } + if (isList) { + list = objv[2]; + Tcl_IncrRefCount(list); + } else { + Tcl_Obj *cmd[3]; + + cmd[1] = Tcl_NewStringObj("::zipfs::find", -1); + cmd[2] = objv[2]; + cmd[0] = Tcl_NewListObj(2, cmd + 1); + Tcl_IncrRefCount(cmd[0]); + if (Tcl_EvalObjEx(interp, cmd[0], TCL_EVAL_DIRECT) != TCL_OK) { + Tcl_DecrRefCount(cmd[0]); + return TCL_ERROR; + } + Tcl_DecrRefCount(cmd[0]); + list = Tcl_GetObjResult(interp); + Tcl_IncrRefCount(list); + } + if (Tcl_ListObjGetElements(interp, list, &lobjc, &lobjv) != TCL_OK) { + Tcl_DecrRefCount(list); + return TCL_ERROR; + } + if (isList && (lobjc % 2)) { + Tcl_DecrRefCount(list); + Tcl_SetObjResult(interp, + Tcl_NewStringObj("need even number of elements", -1)); + return TCL_ERROR; + } + if (lobjc == 0) { + Tcl_DecrRefCount(list); + Tcl_SetObjResult(interp, Tcl_NewStringObj("empty archive", -1)); + return TCL_ERROR; + } + out = Tcl_OpenFileChannel(interp, Tcl_GetString(objv[1]), "w", 0755); + if ((out == NULL) || + (Tcl_SetChannelOption(interp, out, "-translation", "binary") + != TCL_OK) || + (Tcl_SetChannelOption(interp, out, "-encoding", "binary") + != TCL_OK)) { + Tcl_DecrRefCount(list); + Tcl_Close(interp, out); + return TCL_ERROR; + } + if (isImg) { + ZipFile zf0; + const char *imgName; + + if (isList) { + imgName = (objc > 4) ? Tcl_GetString(objv[4]) : + Tcl_GetNameOfExecutable(); + } else { + imgName = (objc > 5) ? Tcl_GetString(objv[5]) : + Tcl_GetNameOfExecutable(); + } + if (ZipFSOpenArchive(interp, imgName, 0, &zf0) != TCL_OK) { + Tcl_DecrRefCount(list); + Tcl_Close(interp, out); + return TCL_ERROR; + } + if ((pw != NULL) && pwlen) { + i = 0; + len = pwlen; + while (len > 0) { + int ch = pw[len - 1]; + + pwbuf[i] = (ch & 0x0f) | pwrot[(ch >> 4) & 0x0f]; + i++; + len--; + } + pwbuf[i] = i; + ++i; + pwbuf[i++] = (char) ZIP_PASSWORD_END_SIG; + pwbuf[i++] = (char) (ZIP_PASSWORD_END_SIG >> 8); + pwbuf[i++] = (char) (ZIP_PASSWORD_END_SIG >> 16); + pwbuf[i++] = (char) (ZIP_PASSWORD_END_SIG >> 24); + pwbuf[i] = '\0'; + } + i = Tcl_Write(out, (char *) zf0.data, zf0.baseoffsp); + if (i != zf0.baseoffsp) { + Tcl_DecrRefCount(list); + Tcl_SetObjResult(interp, Tcl_NewStringObj("write error", -1)); + Tcl_Close(interp, out); + ZipFSCloseArchive(interp, &zf0); + return TCL_ERROR; + } + ZipFSCloseArchive(interp, &zf0); + len = strlen(pwbuf); + if (len > 0) { + i = Tcl_Write(out, pwbuf, len); + if (i != len) { + Tcl_DecrRefCount(list); + Tcl_SetObjResult(interp, Tcl_NewStringObj("write error", -1)); + Tcl_Close(interp, out); + return TCL_ERROR; + } + } + memset(pwbuf, 0, sizeof (pwbuf)); + Tcl_Flush(out); + } + Tcl_InitHashTable(&fileHash, TCL_STRING_KEYS); + pos[0] = Tcl_Tell(out); + if (!isList && (objc > 3)) { + strip = Tcl_GetString(objv[3]); + slen = strlen(strip); + } + for (i = 0; i < lobjc; i += (isList ? 2 : 1)) { + const char *path, *name; + + path = Tcl_GetString(lobjv[i]); + if (isList) { + name = Tcl_GetString(lobjv[i + 1]); + } else { + name = path; + if (slen > 0) { + len = strlen(name); + if ((len <= slen) || (strncmp(strip, name, slen) != 0)) { + continue; + } + name += slen; + } + } + while (name[0] == '/') { + ++name; + } + if (name[0] == '\0') { + continue; + } + if (ZipAddFile(interp, path, name, out, pw, buf, sizeof (buf), + &fileHash) != TCL_OK) { + goto done; + } + } + pos[1] = Tcl_Tell(out); + count = 0; + for (i = 0; i < lobjc; i += (isList ? 2 : 1)) { + const char *path, *name; + + path = Tcl_GetString(lobjv[i]); + if (isList) { + name = Tcl_GetString(lobjv[i + 1]); + } else { + name = path; + if (slen > 0) { + len = strlen(name); + if ((len <= slen) || (strncmp(strip, name, slen) != 0)) { + continue; + } + name += slen; + } + } + while (name[0] == '/') { + ++name; + } + if (name[0] == '\0') { + continue; + } + hPtr = Tcl_FindHashEntry(&fileHash, name); + if (hPtr == NULL) { + continue; + } + z = (ZipEntry *) Tcl_GetHashValue(hPtr); + len = strlen(z->name); + zip_write_int(buf + ZIP_CENTRAL_SIG_OFFS, ZIP_CENTRAL_HEADER_SIG); + zip_write_short(buf + ZIP_CENTRAL_VERSIONMADE_OFFS, ZIP_MIN_VERSION); + zip_write_short(buf + ZIP_CENTRAL_VERSION_OFFS, ZIP_MIN_VERSION); + zip_write_short(buf + ZIP_CENTRAL_FLAGS_OFFS, z->isenc ? 1 : 0); + zip_write_short(buf + ZIP_CENTRAL_COMPMETH_OFFS, z->cmeth); + zip_write_short(buf + ZIP_CENTRAL_MTIME_OFFS, ToDosTime(z->timestamp)); + zip_write_short(buf + ZIP_CENTRAL_MDATE_OFFS, ToDosDate(z->timestamp)); + zip_write_int(buf + ZIP_CENTRAL_CRC32_OFFS, z->crc32); + zip_write_int(buf + ZIP_CENTRAL_COMPLEN_OFFS, z->nbytecompr); + zip_write_int(buf + ZIP_CENTRAL_UNCOMPLEN_OFFS, z->nbyte); + zip_write_short(buf + ZIP_CENTRAL_PATHLEN_OFFS, len); + zip_write_short(buf + ZIP_CENTRAL_EXTRALEN_OFFS, 0); + zip_write_short(buf + ZIP_CENTRAL_FCOMMENTLEN_OFFS, 0); + zip_write_short(buf + ZIP_CENTRAL_DISKFILE_OFFS, 0); + zip_write_short(buf + ZIP_CENTRAL_IATTR_OFFS, 0); + zip_write_int(buf + ZIP_CENTRAL_EATTR_OFFS, 0); + zip_write_int(buf + ZIP_CENTRAL_LOCALHDR_OFFS, z->offset - pos[0]); + if ((Tcl_Write(out, buf, ZIP_CENTRAL_HEADER_LEN) != + ZIP_CENTRAL_HEADER_LEN) || + (Tcl_Write(out, z->name, len) != len)) { + Tcl_SetObjResult(interp, Tcl_NewStringObj("write error", -1)); + goto done; + } + count++; + } + Tcl_Flush(out); + pos[2] = Tcl_Tell(out); + zip_write_int(buf + ZIP_CENTRAL_END_SIG_OFFS, ZIP_CENTRAL_END_SIG); + zip_write_short(buf + ZIP_CENTRAL_DISKNO_OFFS, 0); + zip_write_short(buf + ZIP_CENTRAL_DISKDIR_OFFS, 0); + zip_write_short(buf + ZIP_CENTRAL_ENTS_OFFS, count); + zip_write_short(buf + ZIP_CENTRAL_TOTALENTS_OFFS, count); + zip_write_int(buf + ZIP_CENTRAL_DIRSIZE_OFFS, pos[2] - pos[1]); + zip_write_int(buf + ZIP_CENTRAL_DIRSTART_OFFS, pos[1] - pos[0]); + zip_write_short(buf + ZIP_CENTRAL_COMMENTLEN_OFFS, 0); + if (Tcl_Write(out, buf, ZIP_CENTRAL_END_LEN) != ZIP_CENTRAL_END_LEN) { + Tcl_SetObjResult(interp, Tcl_NewStringObj("write error", -1)); + goto done; + } + Tcl_Flush(out); + ret = TCL_OK; +done: + if (ret == TCL_OK) { + ret = Tcl_Close(interp, out); + } else { + Tcl_Close(interp, out); + } + Tcl_DecrRefCount(list); + hPtr = Tcl_FirstHashEntry(&fileHash, &search); + while (hPtr != NULL) { + z = (ZipEntry *) Tcl_GetHashValue(hPtr); + Tcl_Free((char *) z); + Tcl_DeleteHashEntry(hPtr); + hPtr = Tcl_FirstHashEntry(&fileHash, &search); + } + Tcl_DeleteHashTable(&fileHash); + return ret; +} + +/* + *------------------------------------------------------------------------- + * + * ZipFSMkZipObjCmd -- + * + * This procedure is invoked to process the "zipfs::mkzip" command. + * See description of ZipFSMkZipOrImgCmd(). + * + * Results: + * A standard Tcl result. + * + * Side effects: + * See description of ZipFSMkZipOrImgCmd(). + * + *------------------------------------------------------------------------- + */ + +static int +ZipFSMkZipObjCmd(ClientData clientData, Tcl_Interp *interp, + int objc, Tcl_Obj *const objv[]) +{ + return ZipFSMkZipOrImgObjCmd(clientData, interp, 0, 0, objc, objv); +} + +static int +ZipFSLMkZipObjCmd(ClientData clientData, Tcl_Interp *interp, + int objc, Tcl_Obj *const objv[]) +{ + return ZipFSMkZipOrImgObjCmd(clientData, interp, 0, 1, objc, objv); +} + +/* + *------------------------------------------------------------------------- + * + * ZipFSMkImgObjCmd -- + * + * This procedure is invoked to process the "zipfs::mkimg" command. + * See description of ZipFSMkZipOrImgCmd(). + * + * Results: + * A standard Tcl result. + * + * Side effects: + * See description of ZipFSMkZipOrImgCmd(). + * + *------------------------------------------------------------------------- + */ + +static int +ZipFSMkImgObjCmd(ClientData clientData, Tcl_Interp *interp, + int objc, Tcl_Obj *const objv[]) +{ + return ZipFSMkZipOrImgObjCmd(clientData, interp, 1, 0, objc, objv); +} + +static int +ZipFSLMkImgObjCmd(ClientData clientData, Tcl_Interp *interp, + int objc, Tcl_Obj *const objv[]) +{ + return ZipFSMkZipOrImgObjCmd(clientData, interp, 1, 1, objc, objv); +} + +/* + *------------------------------------------------------------------------- + * + * ZipFSExistsObjCmd -- + * + * This procedure is invoked to process the "zipfs::exists" command. + * It tests for the existence of a file in the ZIP filesystem and + * places a boolean into the interp's result. + * + * Results: + * Always TCL_OK. + * + * Side effects: + * None. + * + *------------------------------------------------------------------------- + */ + +static int +ZipFSCanonicalObjCmd(ClientData clientData, Tcl_Interp *interp, + int objc, Tcl_Obj *const objv[]) +{ + char *mntpoint=NULL; + char *filename=NULL; + char *result; + Tcl_DString dPath; + + if (objc != 2 && objc != 3 && objc!=4) { + Tcl_WrongNumArgs(interp, 1, objv, "?mntpnt? filename ?ZIPFS?"); + return TCL_ERROR; + } + Tcl_DStringInit(&dPath); + if(objc==2) { + filename = Tcl_GetString(objv[1]); + result=CanonicalPath("",filename,&dPath,1); + } else if (objc==3) { + mntpoint = Tcl_GetString(objv[1]); + filename = Tcl_GetString(objv[2]); + result=CanonicalPath(mntpoint,filename,&dPath,1); + } else { + int zipfs=0; + if(Tcl_GetBooleanFromObj(interp,objv[3],&zipfs)) { + return TCL_ERROR; + } + mntpoint = Tcl_GetString(objv[1]); + filename = Tcl_GetString(objv[2]); + result=CanonicalPath(mntpoint,filename,&dPath,zipfs); + } + Tcl_SetObjResult(interp,Tcl_NewStringObj(result,-1)); + return TCL_OK; +} + +/* + *------------------------------------------------------------------------- + * + * ZipFSExistsObjCmd -- + * + * This procedure is invoked to process the "zipfs::exists" command. + * It tests for the existence of a file in the ZIP filesystem and + * places a boolean into the interp's result. + * + * Results: + * Always TCL_OK. + * + * Side effects: + * None. + * + *------------------------------------------------------------------------- + */ + +static int +ZipFSExistsObjCmd(ClientData clientData, Tcl_Interp *interp, + int objc, Tcl_Obj *const objv[]) +{ + char *filename; + int exists; + + if (objc != 2) { + Tcl_WrongNumArgs(interp, 1, objv, "filename"); + return TCL_ERROR; + } + filename = Tcl_GetStringFromObj(objv[1], 0); + ReadLock(); + exists = ZipFSLookup(filename) != NULL; + Unlock(); + Tcl_SetObjResult(interp,Tcl_NewBooleanObj(exists)); + return TCL_OK; +} + +/* + *------------------------------------------------------------------------- + * + * ZipFSInfoObjCmd -- + * + * This procedure is invoked to process the "zipfs::info" command. + * On success, it returns a Tcl list made up of name of ZIP archive + * file, size uncompressed, size compressed, and archive offset of + * a file in the ZIP filesystem. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * None. + * + *------------------------------------------------------------------------- + */ + +static int +ZipFSInfoObjCmd(ClientData clientData, Tcl_Interp *interp, + int objc, Tcl_Obj *const objv[]) +{ + char *filename; + ZipEntry *z; + + if (objc != 2) { + Tcl_WrongNumArgs(interp, 1, objv, "filename"); + return TCL_ERROR; + } + filename = Tcl_GetStringFromObj(objv[1], 0); + ReadLock(); + z = ZipFSLookup(filename); + if (z != NULL) { + Tcl_Obj *result = Tcl_GetObjResult(interp); + + Tcl_ListObjAppendElement(interp, result, + Tcl_NewStringObj(z->zipfile->name, -1)); + Tcl_ListObjAppendElement(interp, result, Tcl_NewIntObj(z->nbyte)); + Tcl_ListObjAppendElement(interp, result, Tcl_NewIntObj(z->nbytecompr)); + Tcl_ListObjAppendElement(interp, result, Tcl_NewIntObj(z->offset)); + } + Unlock(); + return TCL_OK; +} + +/* + *------------------------------------------------------------------------- + * + * ZipFSListObjCmd -- + * + * This procedure is invoked to process the "zipfs::list" command. + * On success, it returns a Tcl list of files of the ZIP filesystem + * which match a search pattern (glob or regexp). + * + * Results: + * A standard Tcl result. + * + * Side effects: + * None. + * + *------------------------------------------------------------------------- + */ + +static int +ZipFSListObjCmd(ClientData clientData, Tcl_Interp *interp, + int objc, Tcl_Obj *const objv[]) +{ + char *pattern = NULL; + Tcl_RegExp regexp = NULL; + Tcl_HashEntry *hPtr; + Tcl_HashSearch search; + Tcl_Obj *result = Tcl_GetObjResult(interp); + + if (objc > 3) { + Tcl_WrongNumArgs(interp, 1, objv, "?(-glob|-regexp)? ?pattern?"); + return TCL_ERROR; + } + if (objc == 3) { + int n; + char *what = Tcl_GetStringFromObj(objv[1], &n); + + if ((n >= 2) && (strncmp(what, "-glob", n) == 0)) { + pattern = Tcl_GetString(objv[2]); + } else if ((n >= 2) && (strncmp(what, "-regexp", n) == 0)) { + regexp = Tcl_RegExpCompile(interp, Tcl_GetString(objv[2])); + if (regexp == NULL) { + return TCL_ERROR; + } + } else { + Tcl_AppendResult(interp, "unknown option \"", what, + "\"", (char *) NULL); + return TCL_ERROR; + } + } else if (objc == 2) { + pattern = Tcl_GetStringFromObj(objv[1], 0); + } + ReadLock(); + if (pattern != NULL) { + for (hPtr = Tcl_FirstHashEntry(&ZipFS.fileHash, &search); + hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) { + ZipEntry *z = (ZipEntry *) Tcl_GetHashValue(hPtr); + + if (Tcl_StringMatch(z->name, pattern)) { + Tcl_ListObjAppendElement(interp, result, + Tcl_NewStringObj(z->name, -1)); + } + } + } else if (regexp != NULL) { + for (hPtr = Tcl_FirstHashEntry(&ZipFS.fileHash, &search); + hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) { + ZipEntry *z = (ZipEntry *) Tcl_GetHashValue(hPtr); + + if (Tcl_RegExpExec(interp, regexp, z->name, z->name)) { + Tcl_ListObjAppendElement(interp, result, + Tcl_NewStringObj(z->name, -1)); + } + } + } else { + for (hPtr = Tcl_FirstHashEntry(&ZipFS.fileHash, &search); + hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) { + ZipEntry *z = (ZipEntry *) Tcl_GetHashValue(hPtr); + + Tcl_ListObjAppendElement(interp, result, + Tcl_NewStringObj(z->name, -1)); + } + } + Unlock(); + return TCL_OK; +} + +/* + *------------------------------------------------------------------------- + * + * ZipChannelClose -- + * + * This function is called to close a channel. + * + * Results: + * Always TCL_OK. + * + * Side effects: + * Resources are free'd. + * + *------------------------------------------------------------------------- + */ + +static int +ZipChannelClose(ClientData instanceData, Tcl_Interp *interp) +{ + ZipChannel *info = (ZipChannel *) instanceData; + + if (info->iscompr && (info->ubuf != NULL)) { + Tcl_Free((char *) info->ubuf); + info->ubuf = NULL; + } + if (info->isenc) { + info->isenc = 0; + memset(info->keys, 0, sizeof (info->keys)); + } + if (info->iswr) { + ZipEntry *z = info->zipentry; + unsigned char *newdata; + + newdata = (unsigned char *) + Tcl_AttemptRealloc((char *) info->ubuf, info->nread); + if (newdata != NULL) { + if (z->data != NULL) { + Tcl_Free((char *) z->data); + } + z->data = newdata; + z->nbyte = z->nbytecompr = info->nbyte; + z->cmeth = ZIP_COMPMETH_STORED; + z->timestamp = time(NULL); + z->isdir = 0; + z->isenc = 0; + z->offset = 0; + z->crc32 = 0; + } else { + Tcl_Free((char *) info->ubuf); + } + } + WriteLock(); + info->zipfile->nopen--; + Unlock(); + Tcl_Free((char *) info); + return TCL_OK; +} + +/* + *------------------------------------------------------------------------- + * + * ZipChannelRead -- + * + * This function is called to read data from channel. + * + * Results: + * Number of bytes read or -1 on error with error number set. + * + * Side effects: + * Data is read and file pointer is advanced. + * + *------------------------------------------------------------------------- + */ + +static int +ZipChannelRead(ClientData instanceData, char *buf, int toRead, int *errloc) +{ + ZipChannel *info = (ZipChannel *) instanceData; + unsigned long nextpos; + + if (info->isdir) { + *errloc = EISDIR; + return -1; + } + nextpos = info->nread + toRead; + if (nextpos > info->nbyte) { + toRead = info->nbyte - info->nread; + nextpos = info->nbyte; + } + if (toRead == 0) { + return 0; + } + if (info->isenc) { + int i, ch; + + for (i = 0; i < toRead; i++) { + ch = info->ubuf[i + info->nread]; + buf[i] = zdecode(info->keys, crc32tab, ch); + } + } else { + memcpy(buf, info->ubuf + info->nread, toRead); + } + info->nread = nextpos; + *errloc = 0; + return toRead; +} + +/* + *------------------------------------------------------------------------- + * + * ZipChannelWrite -- + * + * This function is called to write data into channel. + * + * Results: + * Number of bytes written or -1 on error with error number set. + * + * Side effects: + * Data is written and file pointer is advanced. + * + *------------------------------------------------------------------------- + */ + +static int +ZipChannelWrite(ClientData instanceData, const char *buf, + int toWrite, int *errloc) +{ + ZipChannel *info = (ZipChannel *) instanceData; + unsigned long nextpos; + + if (!info->iswr) { + *errloc = EINVAL; + return -1; + } + nextpos = info->nread + toWrite; + if (nextpos > info->nmax) { + toWrite = info->nmax - info->nread; + nextpos = info->nmax; + } + if (toWrite == 0) { + return 0; + } + memcpy(info->ubuf + info->nread, buf, toWrite); + info->nread = nextpos; + if (info->nread > info->nbyte) { + info->nbyte = info->nread; + } + *errloc = 0; + return toWrite; +} + +/* + *------------------------------------------------------------------------- + * + * ZipChannelSeek -- + * + * This function is called to position file pointer of channel. + * + * Results: + * New file position or -1 on error with error number set. + * + * Side effects: + * File pointer is repositioned according to offset and mode. + * + *------------------------------------------------------------------------- + */ + +static int +ZipChannelSeek(ClientData instanceData, long offset, int mode, int *errloc) +{ + ZipChannel *info = (ZipChannel *) instanceData; + + if (info->isdir) { + *errloc = EINVAL; + return -1; + } + switch (mode) { + case SEEK_CUR: + offset += info->nread; + break; + case SEEK_END: + offset += info->nbyte; + break; + case SEEK_SET: + break; + default: + *errloc = EINVAL; + return -1; + } + if (offset < 0) { + *errloc = EINVAL; + return -1; + } + if (info->iswr) { + if ((unsigned long) offset > info->nmax) { + *errloc = EINVAL; + return -1; + } + if ((unsigned long) offset > info->nbyte) { + info->nbyte = offset; + } + } else if ((unsigned long) offset > info->nbyte) { + *errloc = EINVAL; + return -1; + } + info->nread = (unsigned long) offset; + return info->nread; +} + +/* + *------------------------------------------------------------------------- + * + * ZipChannelWatchChannel -- + * + * This function is called for event notifications on channel. + * + * Results: + * None. + * + * Side effects: + * None. + * + *------------------------------------------------------------------------- + */ + +static void +ZipChannelWatchChannel(ClientData instanceData, int mask) +{ + return; +} + +/* + *------------------------------------------------------------------------- + * + * ZipChannelGetFile -- + * + * This function is called to retrieve OS handle for channel. + * + * Results: + * Always TCL_ERROR since there's never an OS handle for a + * file within a ZIP archive. + * + * Side effects: + * None. + * + *------------------------------------------------------------------------- + */ + +static int +ZipChannelGetFile(ClientData instanceData, int direction, + ClientData *handlePtr) +{ + return TCL_ERROR; +} + +/* + * The channel type/driver definition used for ZIP archive members. + */ + +static Tcl_ChannelType ZipChannelType = { + "zip", /* Type name. */ +#ifdef TCL_CHANNEL_VERSION_4 + TCL_CHANNEL_VERSION_4, + ZipChannelClose, /* Close channel, clean instance data */ + ZipChannelRead, /* Handle read request */ + ZipChannelWrite, /* Handle write request */ + ZipChannelSeek, /* Move location of access point, NULL'able */ + NULL, /* Set options, NULL'able */ + NULL, /* Get options, NULL'able */ + ZipChannelWatchChannel, /* Initialize notifier */ + ZipChannelGetFile, /* Get OS handle from the channel */ + NULL, /* 2nd version of close channel, NULL'able */ + NULL, /* Set blocking mode for raw channel, NULL'able */ + NULL, /* Function to flush channel, NULL'able */ + NULL, /* Function to handle event, NULL'able */ + NULL, /* Wide seek function, NULL'able */ + NULL, /* Thread action function, NULL'able */ +#else + NULL, /* Set blocking/nonblocking behaviour, NULL'able */ + ZipChannelClose, /* Close channel, clean instance data */ + ZipChannelRead, /* Handle read request */ + ZipChannelWrite, /* Handle write request */ + ZipChannelSeek, /* Move location of access point, NULL'able */ + NULL, /* Set options, NULL'able */ + NULL, /* Get options, NULL'able */ + ZipChannelWatchChannel, /* Initialize notifier */ + ZipChannelGetFile, /* Get OS handle from the channel */ +#endif +}; + +/* + *------------------------------------------------------------------------- + * + * ZipChannelOpen -- + * + * This function opens a Tcl_Channel on a file from a mounted ZIP + * archive according to given open mode. + * + * Results: + * Tcl_Channel on success, or NULL on error. + * + * Side effects: + * Memory is allocated, the file from the ZIP archive is uncompressed. + * + *------------------------------------------------------------------------- + */ + +static Tcl_Channel +ZipChannelOpen(Tcl_Interp *interp, char *filename, int mode, int permissions) +{ + ZipEntry *z; + ZipChannel *info; + int i, ch, trunc, wr, flags = 0; + char cname[128]; + + if ((mode & O_APPEND) || + ((ZipFS.wrmax <= 0) && (mode & (O_WRONLY | O_RDWR)))) { + if (interp != NULL) { + Tcl_SetObjResult(interp, Tcl_NewStringObj("unsupported open mode", -1)); + } + return NULL; + } + WriteLock(); + z = ZipFSLookup(filename); + if (z == NULL) { + if (interp != NULL) { + Tcl_SetObjResult(interp, Tcl_NewStringObj("file not found", -1)); + } + goto error; + } + trunc = (mode & O_TRUNC) != 0; + wr = (mode & (O_WRONLY | O_RDWR)) != 0; + if ((z->cmeth != ZIP_COMPMETH_STORED) && + (z->cmeth != ZIP_COMPMETH_DEFLATED)) { + if (interp != NULL) { + Tcl_SetObjResult(interp, + Tcl_NewStringObj("unsupported compression method", -1)); + } + goto error; + } + if (wr && z->isdir) { + if (interp != NULL) { + Tcl_SetObjResult(interp, + Tcl_NewStringObj("unsupported file type", -1)); + } + goto error; + } + if (!trunc) { + flags |= TCL_READABLE; + if (z->isenc && (z->zipfile->pwbuf[0] == 0)) { + if (interp != NULL) { + Tcl_SetObjResult(interp, + Tcl_NewStringObj("decryption failed", -1)); + } + goto error; + } else if (wr && (z->data == NULL) && (z->nbyte > ZipFS.wrmax)) { + if (interp != NULL) { + Tcl_SetObjResult(interp, + Tcl_NewStringObj("file too large", -1)); + } + goto error; + } + } else { + flags = TCL_WRITABLE; + } + info = (ZipChannel *) Tcl_AttemptAlloc(sizeof (*info)); + if (info == NULL) { + if (interp != NULL) { + Tcl_SetObjResult(interp, Tcl_NewStringObj("out of memory", -1)); + } + goto error; + } + info->zipfile = z->zipfile; + info->zipentry = z; + info->nread = 0; + if (wr) { + flags |= TCL_WRITABLE; + info->iswr = 1; + info->isdir = 0; + info->nmax = ZipFS.wrmax; + info->iscompr = 0; + info->isenc = 0; + info->ubuf = (unsigned char *) Tcl_AttemptAlloc(info->nmax); + if (info->ubuf == NULL) { +merror0: + if (info->ubuf != NULL) { + Tcl_Free((char *) info->ubuf); + } + Tcl_Free((char *) info); + if (interp != NULL) { + Tcl_SetObjResult(interp, + Tcl_NewStringObj("out of memory", -1)); + } + goto error; + } + memset(info->ubuf, 0, info->nmax); + if (trunc) { + info->nbyte = 0; + } else { + if (z->data != NULL) { + unsigned int j = z->nbyte; + + if (j > info->nmax) { + j = info->nmax; + } + memcpy(info->ubuf, z->data, j); + info->nbyte = j; + } else { + unsigned char *zbuf = z->zipfile->data + z->offset; + + if (z->isenc) { + int len = z->zipfile->pwbuf[0]; + char pwbuf[260]; + + for (i = 0; i < len; i++) { + ch = z->zipfile->pwbuf[len - i]; + pwbuf[i] = (ch & 0x0f) | pwrot[(ch >> 4) & 0x0f]; + } + pwbuf[i] = '\0'; + init_keys(pwbuf, info->keys, crc32tab); + memset(pwbuf, 0, sizeof (pwbuf)); + for (i = 0; i < 12; i++) { + ch = info->ubuf[i]; + zdecode(info->keys, crc32tab, ch); + } + zbuf += i; + } + if (z->cmeth == ZIP_COMPMETH_DEFLATED) { + z_stream stream; + int err; + unsigned char *cbuf = NULL; + + memset(&stream, 0, sizeof (stream)); + stream.zalloc = Z_NULL; + stream.zfree = Z_NULL; + stream.opaque = Z_NULL; + stream.avail_in = z->nbytecompr; + if (z->isenc) { + unsigned int j; + + stream.avail_in -= 12; + cbuf = (unsigned char *) + Tcl_AttemptAlloc(stream.avail_in); + if (cbuf == NULL) { + goto merror0; + } + for (j = 0; j < stream.avail_in; j++) { + ch = info->ubuf[j]; + cbuf[j] = zdecode(info->keys, crc32tab, ch); + } + stream.next_in = cbuf; + } else { + stream.next_in = zbuf; + } + stream.next_out = info->ubuf; + stream.avail_out = info->nmax; + if (inflateInit2(&stream, -15) != Z_OK) { + goto cerror0; + } + err = inflate(&stream, Z_SYNC_FLUSH); + inflateEnd(&stream); + if ((err == Z_STREAM_END) || + ((err == Z_OK) && (stream.avail_in == 0))) { + if (cbuf != NULL) { + memset(info->keys, 0, sizeof (info->keys)); + Tcl_Free((char *) cbuf); + } + goto wrapchan; + } +cerror0: + if (cbuf != NULL) { + memset(info->keys, 0, sizeof (info->keys)); + Tcl_Free((char *) cbuf); + } + if (info->ubuf != NULL) { + Tcl_Free((char *) info->ubuf); + } + Tcl_Free((char *) info); + if (interp != NULL) { + Tcl_SetObjResult(interp, + Tcl_NewStringObj("decompression error", -1)); + } + goto error; + } else if (z->isenc) { + for (i = 0; i < z->nbyte - 12; i++) { + ch = zbuf[i]; + info->ubuf[i] = zdecode(info->keys, crc32tab, ch); + } + } else { + memcpy(info->ubuf, zbuf, z->nbyte); + } + memset(info->keys, 0, sizeof (info->keys)); + goto wrapchan; + } + } + } else if (z->data != NULL) { + flags |= TCL_READABLE; + info->iswr = 0; + info->iscompr = 0; + info->isdir = 0; + info->isenc = 0; + info->nbyte = z->nbyte; + info->nmax = 0; + info->ubuf = z->data; + } else { + flags |= TCL_READABLE; + info->iswr = 0; + info->iscompr = z->cmeth == ZIP_COMPMETH_DEFLATED; + info->ubuf = z->zipfile->data + z->offset; + info->isdir = z->isdir; + info->isenc = z->isenc; + info->nbyte = z->nbyte; + info->nmax = 0; + if (info->isenc) { + int len = z->zipfile->pwbuf[0]; + char pwbuf[260]; + + for (i = 0; i < len; i++) { + ch = z->zipfile->pwbuf[len - i]; + pwbuf[i] = (ch & 0x0f) | pwrot[(ch >> 4) & 0x0f]; + } + pwbuf[i] = '\0'; + init_keys(pwbuf, info->keys, crc32tab); + memset(pwbuf, 0, sizeof (pwbuf)); + for (i = 0; i < 12; i++) { + ch = info->ubuf[i]; + zdecode(info->keys, crc32tab, ch); + } + info->ubuf += i; + } + if (info->iscompr) { + z_stream stream; + int err; + unsigned char *ubuf = NULL; + unsigned int j; + + memset(&stream, 0, sizeof (stream)); + stream.zalloc = Z_NULL; + stream.zfree = Z_NULL; + stream.opaque = Z_NULL; + stream.avail_in = z->nbytecompr; + if (info->isenc) { + stream.avail_in -= 12; + ubuf = (unsigned char *) Tcl_AttemptAlloc(stream.avail_in); + if (ubuf == NULL) { + info->ubuf = NULL; + goto merror; + } + for (j = 0; j < stream.avail_in; j++) { + ch = info->ubuf[j]; + ubuf[j] = zdecode(info->keys, crc32tab, ch); + } + stream.next_in = ubuf; + } else { + stream.next_in = info->ubuf; + } + stream.next_out = info->ubuf = + (unsigned char *) Tcl_AttemptAlloc(info->nbyte); + if (info->ubuf == NULL) { +merror: + if (ubuf != NULL) { + info->isenc = 0; + memset(info->keys, 0, sizeof (info->keys)); + Tcl_Free((char *) ubuf); + } + Tcl_Free((char *) info); + if (interp != NULL) { + Tcl_SetObjResult(interp, + Tcl_NewStringObj("out of memory", -1)); + } + goto error; + } + stream.avail_out = info->nbyte; + if (inflateInit2(&stream, -15) != Z_OK) { + goto cerror; + } + err = inflate(&stream, Z_SYNC_FLUSH); + inflateEnd(&stream); + if ((err == Z_STREAM_END) || + ((err == Z_OK) && (stream.avail_in == 0))) { + if (ubuf != NULL) { + info->isenc = 0; + memset(info->keys, 0, sizeof (info->keys)); + Tcl_Free((char *) ubuf); + } + goto wrapchan; + } +cerror: + if (ubuf != NULL) { + info->isenc = 0; + memset(info->keys, 0, sizeof (info->keys)); + Tcl_Free((char *) ubuf); + } + if (info->ubuf != NULL) { + Tcl_Free((char *) info->ubuf); + } + Tcl_Free((char *) info); + if (interp != NULL) { + Tcl_SetObjResult(interp, + Tcl_NewStringObj("decompression error", -1)); + } + goto error; + } + } +wrapchan: + sprintf(cname, "zipfs_%lx_%d", (unsigned long) z->offset, ZipFS.idCount++); + z->zipfile->nopen++; + Unlock(); + return Tcl_CreateChannel(&ZipChannelType, cname, (ClientData) info, flags); + +error: + Unlock(); + return NULL; +} + +/* + *------------------------------------------------------------------------- + * + * ZipEntryStat -- + * + * This function implements the ZIP filesystem specific version + * of the library version of stat. + * + * Results: + * See stat documentation. + * + * Side effects: + * See stat documentation. + * + *------------------------------------------------------------------------- + */ + +static int +ZipEntryStat(char *path, Tcl_StatBuf *buf) +{ + ZipEntry *z; + int ret = -1; + + ReadLock(); + z = ZipFSLookup(path); + if (z == NULL) { + goto done; + } + memset(buf, 0, sizeof (Tcl_StatBuf)); + if (z->isdir) { + buf->st_mode = S_IFDIR | 0555; + } else { + buf->st_mode = S_IFREG | 0555; + } + buf->st_size = z->nbyte; + buf->st_mtime = z->timestamp; + buf->st_ctime = z->timestamp; + buf->st_atime = z->timestamp; + ret = 0; +done: + Unlock(); + return ret; +} + +/* + *------------------------------------------------------------------------- + * + * ZipEntryAccess -- + * + * This function implements the ZIP filesystem specific version + * of the library version of access. + * + * Results: + * See access documentation. + * + * Side effects: + * See access documentation. + * + *------------------------------------------------------------------------- + */ + +static int +ZipEntryAccess(char *path, int mode) +{ + ZipEntry *z; + + if (mode & 3) { + return -1; + } + ReadLock(); + z = ZipFSLookup(path); + Unlock(); + return (z != NULL) ? 0 : -1; +} + +/* + *------------------------------------------------------------------------- + * + * Zip_FSOpenFileChannelProc -- + * + * Results: + * + * Side effects: + * + *------------------------------------------------------------------------- + */ + +static Tcl_Channel +Zip_FSOpenFileChannelProc(Tcl_Interp *interp, Tcl_Obj *pathPtr, + int mode, int permissions) +{ + int len; + + return ZipChannelOpen(interp, Tcl_GetStringFromObj(pathPtr, &len), + mode, permissions); +} + +/* + *------------------------------------------------------------------------- + * + * Zip_FSStatProc -- + * + * This function implements the ZIP filesystem specific version + * of the library version of stat. + * + * Results: + * See stat documentation. + * + * Side effects: + * See stat documentation. + * + *------------------------------------------------------------------------- + */ + +static int +Zip_FSStatProc(Tcl_Obj *pathPtr, Tcl_StatBuf *buf) +{ + int len; + + return ZipEntryStat(Tcl_GetStringFromObj(pathPtr, &len), buf); +} + +/* + *------------------------------------------------------------------------- + * + * Zip_FSAccessProc -- + * + * This function implements the ZIP filesystem specific version + * of the library version of access. + * + * Results: + * See access documentation. + * + * Side effects: + * See access documentation. + * + *------------------------------------------------------------------------- + */ + +static int +Zip_FSAccessProc(Tcl_Obj *pathPtr, int mode) +{ + int len; + + return ZipEntryAccess(Tcl_GetStringFromObj(pathPtr, &len), mode); +} + +/* + *------------------------------------------------------------------------- + * + * Zip_FSFilesystemSeparatorProc -- + * + * This function returns the separator to be used for a given path. The + * object returned should have a refCount of zero + * + * Results: + * A Tcl object, with a refCount of zero. If the caller needs to retain a + * reference to the object, it should call Tcl_IncrRefCount, and should + * otherwise free the object. + * + * Side effects: + * None. + * + *------------------------------------------------------------------------- + */ + +static Tcl_Obj * +Zip_FSFilesystemSeparatorProc(Tcl_Obj *pathPtr) +{ + return Tcl_NewStringObj("/", -1); +} + +/* + *------------------------------------------------------------------------- + * + * Zip_FSMatchInDirectoryProc -- + * + * This routine is used by the globbing code to search a directory for + * all files which match a given pattern. + * + * Results: + * The return value is a standard Tcl result indicating whether an + * error occurred in globbing. Errors are left in interp, good + * results are lappend'ed to resultPtr (which must be a valid object). + * + * Side effects: + * None. + * + *------------------------------------------------------------------------- + */ +static int +Zip_FSMatchInDirectoryProc(Tcl_Interp* interp, Tcl_Obj *result, + Tcl_Obj *pathPtr, const char *pattern, + Tcl_GlobTypeData *types) +{ + Tcl_HashEntry *hPtr; + Tcl_HashSearch search; + int scnt, len, l, dirOnly = -1, prefixLen, strip = 0; + char *pat, *prefix, *path; + Tcl_DString ds, dsPref; + if (types != NULL) { + dirOnly = (types->type & TCL_GLOB_TYPE_DIR) == TCL_GLOB_TYPE_DIR; + } + Tcl_DStringInit(&ds); + Tcl_DStringInit(&dsPref); + prefix = Tcl_GetStringFromObj(pathPtr, &prefixLen); + Tcl_DStringAppend(&dsPref, prefix, prefixLen); + prefix = Tcl_DStringValue(&dsPref); + path = AbsolutePath(prefix, &ds, 1); + len = Tcl_DStringLength(&ds); + if (strcmp(prefix, path) == 0) { + prefix = NULL; + } else { + strip = len + 1; + } + if (prefix != NULL) { + Tcl_DStringAppend(&dsPref, "/", 1); + prefixLen++; + prefix = Tcl_DStringValue(&dsPref); + } + ReadLock(); + if ((types != NULL) && (types->type == TCL_GLOB_TYPE_MOUNT)) { + l = CountSlashes(path); + if (path[len - 1] == '/') { + len--; + } else { + l++; + } + if ((pattern == NULL) || (pattern[0] == '\0')) { + pattern = "*"; + } + hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); + while (hPtr != NULL) { + ZipFile *zf = (ZipFile *) Tcl_GetHashValue(hPtr); + + if (zf->mntptlen == 0) { + ZipEntry *z = zf->topents; + while (z != NULL) { + int lenz = strlen(z->name); + if ((lenz > len + 1) && + (strncmp(z->name, path, len) == 0) && + (z->name[len] == '/') && + (CountSlashes(z->name) == l) && + Tcl_StringCaseMatch(z->name + len + 1, pattern, 0)) { + if (prefix != NULL) { + Tcl_DStringAppend(&dsPref, z->name, lenz); + Tcl_ListObjAppendElement(NULL, result, + Tcl_NewStringObj(Tcl_DStringValue(&dsPref), + Tcl_DStringLength(&dsPref))); + Tcl_DStringSetLength(&dsPref, prefixLen); + } else { + Tcl_ListObjAppendElement(NULL, result, + Tcl_NewStringObj(z->name, lenz)); + } + } + z = z->tnext; + } + } else if ((zf->mntptlen > len + 1) && + (strncmp(zf->mntpt, path, len) == 0) && + (zf->mntpt[len] == '/') && + (CountSlashes(zf->mntpt) == l) && + Tcl_StringCaseMatch(zf->mntpt + len + 1, pattern, 0)) { + if (prefix != NULL) { + Tcl_DStringAppend(&dsPref, zf->mntpt, zf->mntptlen); + Tcl_ListObjAppendElement(NULL, result, + Tcl_NewStringObj(Tcl_DStringValue(&dsPref), + Tcl_DStringLength(&dsPref))); + Tcl_DStringSetLength(&dsPref, prefixLen); + } else { + Tcl_ListObjAppendElement(NULL, result, + Tcl_NewStringObj(zf->mntpt, zf->mntptlen)); + } + } + hPtr = Tcl_NextHashEntry(&search); + } + goto end; + } + if ((pattern == NULL) || (pattern[0] == '\0')) { + hPtr = Tcl_FindHashEntry(&ZipFS.fileHash, path); + if (hPtr != NULL) { + ZipEntry *z = (ZipEntry *) Tcl_GetHashValue(hPtr); + + if ((dirOnly < 0) || + (!dirOnly && !z->isdir) || + (dirOnly && z->isdir)) { + if (prefix != NULL) { + Tcl_DStringAppend(&dsPref, z->name, -1); + Tcl_ListObjAppendElement(NULL, result, + Tcl_NewStringObj(Tcl_DStringValue(&dsPref), + Tcl_DStringLength(&dsPref))); + Tcl_DStringSetLength(&dsPref, prefixLen); + } else { + Tcl_ListObjAppendElement(NULL, result, + Tcl_NewStringObj(z->name, -1)); + } + } + } + goto end; + } + l = strlen(pattern); + pat = Tcl_Alloc(len + l + 2); + memcpy(pat, path, len); + while ((len > 1) && (pat[len - 1] == '/')) { + --len; + } + if ((len > 1) || (pat[0] != '/')) { + pat[len] = '/'; + ++len; + } + memcpy(pat + len, pattern, l + 1); + scnt = CountSlashes(pat); + for (hPtr = Tcl_FirstHashEntry(&ZipFS.fileHash, &search); + hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) { + ZipEntry *z = (ZipEntry *) Tcl_GetHashValue(hPtr); + if ((dirOnly >= 0) && + ((dirOnly && !z->isdir) || (!dirOnly && z->isdir))) { + continue; + } + if ((z->depth == scnt) && Tcl_StringCaseMatch(z->name, pat, 0)) { + if (prefix != NULL) { + Tcl_DStringAppend(&dsPref, z->name + strip, -1); + Tcl_ListObjAppendElement(NULL, result, + Tcl_NewStringObj(Tcl_DStringValue(&dsPref), + Tcl_DStringLength(&dsPref))); + Tcl_DStringSetLength(&dsPref, prefixLen); + } else { + Tcl_ListObjAppendElement(NULL, result, + Tcl_NewStringObj(z->name + strip, -1)); + } + } + } + Tcl_Free(pat); +end: + Unlock(); + Tcl_DStringFree(&dsPref); + Tcl_DStringFree(&ds); + return TCL_OK; +} + +/* + *------------------------------------------------------------------------- + * + * Zip_FSPathInFilesystemProc -- + * + * This function determines if the given path object is in the + * ZIP filesystem. + * + * Results: + * TCL_OK when the path object is in the ZIP filesystem, -1 otherwise. + * + * Side effects: + * None. + * + *------------------------------------------------------------------------- + */ + +static int +Zip_FSPathInFilesystemProc(Tcl_Obj *pathPtr, ClientData *clientDataPtr) +{ + Tcl_HashEntry *hPtr; + Tcl_HashSearch search; + ZipFile *zf; + int ret = -1, len; + char *path; + Tcl_DString ds; + + path = Tcl_GetStringFromObj(pathPtr, &len); + if(strncmp(path,ZIPFS_VOLUME,ZIPFS_VOLUME_LEN)!=0) { + return -1; + } + + Tcl_DStringInit(&ds); + path = CanonicalPath("",path, &ds, 1); + len = Tcl_DStringLength(&ds); + ReadLock(); + hPtr = Tcl_FindHashEntry(&ZipFS.fileHash, path); + if (hPtr != NULL) { + ret = TCL_OK; + goto endloop; + } + hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); + while (hPtr != NULL) { + zf = (ZipFile *) Tcl_GetHashValue(hPtr); + if (zf->mntptlen == 0) { + ZipEntry *z = zf->topents; + while (z != NULL) { + int lenz = strlen(z->name); + + if ((len >= lenz) && + (strncmp(path, z->name, lenz) == 0)) { + ret = TCL_OK; + goto endloop; + } + z = z->tnext; + } + } else if ((len >= zf->mntptlen) && + (strncmp(path, zf->mntpt, zf->mntptlen) == 0)) { + ret = TCL_OK; + goto endloop; + } + hPtr = Tcl_NextHashEntry(&search); + } +endloop: + Unlock(); + Tcl_DStringFree(&ds); + return ret; +} + +/* + *------------------------------------------------------------------------- + * + * Zip_FSListVolumesProc -- + * + * Lists the currently mounted ZIP filesystem volumes. + * + * Results: + * The list of volumes. + * + * Side effects: + * None + * + *------------------------------------------------------------------------- + */ +static Tcl_Obj * +Zip_FSListVolumesProc(void) { + return Tcl_NewStringObj(ZIPFS_VOLUME, -1); +} + +/* + *------------------------------------------------------------------------- + * + * Zip_FSFileAttrStringsProc -- + * + * This function implements the ZIP filesystem dependent 'file attributes' + * subcommand, for listing the set of possible attribute strings. + * + * Results: + * An array of strings + * + * Side effects: + * None. + * + *------------------------------------------------------------------------- + */ + +static const char *const * +Zip_FSFileAttrStringsProc(Tcl_Obj *pathPtr, Tcl_Obj** objPtrRef) +{ + static const char *const attrs[] = { + "-uncompsize", + "-compsize", + "-offset", + "-mount", + "-archive", + "-permissions", + NULL, + }; + + return attrs; +} + +/* + *------------------------------------------------------------------------- + * + * Zip_FSFileAttrsGetProc -- + * + * This function implements the ZIP filesystem specific + * 'file attributes' subcommand, for 'get' operations. + * + * Results: + * Standard Tcl return code. The object placed in objPtrRef (if TCL_OK + * was returned) is likely to have a refCount of zero. Either way we must + * either store it somewhere (e.g. the Tcl result), or Incr/Decr its + * refCount to ensure it is properly freed. + * + * Side effects: + * None. + * + *------------------------------------------------------------------------- + */ + +static int +Zip_FSFileAttrsGetProc(Tcl_Interp *interp, int index, Tcl_Obj *pathPtr, + Tcl_Obj **objPtrRef) +{ + int len, ret = TCL_OK; + char *path; + ZipEntry *z; + + path = Tcl_GetStringFromObj(pathPtr, &len); + ReadLock(); + z = ZipFSLookup(path); + if (z == NULL) { + if (interp != NULL) { + Tcl_SetObjResult(interp, Tcl_NewStringObj("file not found", -1)); + } + ret = TCL_ERROR; + goto done; + } + switch (index) { + case 0: + *objPtrRef = Tcl_NewIntObj(z->nbyte); + goto done; + case 1: + *objPtrRef= Tcl_NewIntObj(z->nbytecompr); + goto done; + case 2: + *objPtrRef= Tcl_NewLongObj(z->offset); + goto done; + case 3: + *objPtrRef= Tcl_NewStringObj(z->zipfile->mntpt, -1); + goto done; + case 4: + *objPtrRef= Tcl_NewStringObj(z->zipfile->name, -1); + goto done; + case 5: + *objPtrRef= Tcl_NewStringObj("0555", -1); + goto done; + } + if (interp != NULL) { + Tcl_SetObjResult(interp, Tcl_NewStringObj("unknown attribute", -1)); + } + ret = TCL_ERROR; +done: + Unlock(); + return ret; +} + +/* + *------------------------------------------------------------------------- + * + * Zip_FSFileAttrsSetProc -- + * + * This function implements the ZIP filesystem specific + * 'file attributes' subcommand, for 'set' operations. + * + * Results: + * Standard Tcl return code. + * + * Side effects: + * None. + * + *------------------------------------------------------------------------- + */ + +static int +Zip_FSFileAttrsSetProc(Tcl_Interp *interp, int index, Tcl_Obj *pathPtr, + Tcl_Obj *objPtr) +{ + if (interp != NULL) { + Tcl_SetObjResult(interp, Tcl_NewStringObj("unsupported operation", -1)); + } + return TCL_ERROR; +} + +/* + *------------------------------------------------------------------------- + * + * Zip_FSFilesystemPathTypeProc -- + * + * Results: + * + * Side effects: + * + *------------------------------------------------------------------------- + */ + +static Tcl_Obj * +Zip_FSFilesystemPathTypeProc(Tcl_Obj *pathPtr) +{ + return Tcl_NewStringObj("zip", -1); +} + + +/* + *------------------------------------------------------------------------- + * + * Zip_FSLoadFile -- + * + * This functions deals with loading native object code. If + * the given path object refers to a file within the ZIP + * filesystem, an approriate error code is returned to delegate + * loading to the caller (by copying the file to temp store + * and loading from there). As fallback when the file refers + * to the ZIP file system but is not present, it is looked up + * relative to the executable and loaded from there when available. + * + * Results: + * TCL_OK on success, -1 otherwise with error number set. + * + * Side effects: + * Loads native code into the process address space. + * + *------------------------------------------------------------------------- + */ + +static int +Zip_FSLoadFile(Tcl_Interp *interp, Tcl_Obj *path, Tcl_LoadHandle *loadHandle, + Tcl_FSUnloadFileProc **unloadProcPtr, int flags) +{ + Tcl_FSLoadFileProc2 *loadFileProc; +#ifdef ANDROID + /* + * Force loadFileProc to native implementation since the + * package manger already extracted the shared libraries + * from the APK at install time. + */ + + loadFileProc = (Tcl_FSLoadFileProc2 *) tclNativeFilesystem.loadFileProc; + if (loadFileProc != NULL) { + return loadFileProc(interp, path, loadHandle, unloadProcPtr, flags); + } + Tcl_SetErrno(ENOENT); + return -1; +#else + Tcl_Obj *altPath = NULL; + int ret = -1; + + if (Tcl_FSAccess(path, R_OK) == 0) { + /* + * EXDEV should trigger loading by copying to temp store. + */ + Tcl_SetErrno(EXDEV); + return ret; + } else { + Tcl_Obj *objs[2] = { NULL, NULL }; + + objs[1] = TclPathPart(interp, path, TCL_PATH_DIRNAME); + if ((objs[1] != NULL) && (Zip_FSAccessProc(objs[1], R_OK) == 0)) { + const char *execName = Tcl_GetNameOfExecutable(); + + /* + * Shared object is not in ZIP but its path prefix is, + * thus try to load from directory where the executable + * came from. + */ + TclDecrRefCount(objs[1]); + objs[1] = TclPathPart(interp, path, TCL_PATH_TAIL); + /* + * Get directory name of executable manually to deal + * with cases where [file dirname [info nameofexecutable]] + * is equal to [info nameofexecutable] due to VFS effects. + */ + if (execName != NULL) { + const char *p = strrchr(execName, '/'); + + if (p > execName + 1) { + --p; + objs[0] = Tcl_NewStringObj(execName, p - execName); + } + } + if (objs[0] == NULL) { + objs[0] = TclPathPart(interp, TclGetObjNameOfExecutable(), + TCL_PATH_DIRNAME); + } + if (objs[0] != NULL) { + altPath = TclJoinPath(2, objs); + if (altPath != NULL) { + Tcl_IncrRefCount(altPath); + if (Tcl_FSAccess(altPath, R_OK) == 0) { + path = altPath; + } + } + } + } + if (objs[0] != NULL) { + Tcl_DecrRefCount(objs[0]); + } + if (objs[1] != NULL) { + Tcl_DecrRefCount(objs[1]); + } + } + loadFileProc = (Tcl_FSLoadFileProc2 *) tclNativeFilesystem.loadFileProc; + if (loadFileProc != NULL) { + ret = loadFileProc(interp, path, loadHandle, unloadProcPtr, flags); + } else { + Tcl_SetErrno(ENOENT); + } + if (altPath != NULL) { + Tcl_DecrRefCount(altPath); + } + return ret; +#endif +} + + +/* + * Define the ZIP filesystem dispatch table. + */ + +MODULE_SCOPE const Tcl_Filesystem zipfsFilesystem; + +const Tcl_Filesystem zipfsFilesystem = { + "zipfs", + sizeof (Tcl_Filesystem), + TCL_FILESYSTEM_VERSION_2, + Zip_FSPathInFilesystemProc, + NULL, /* dupInternalRepProc */ + NULL, /* freeInternalRepProc */ + NULL, /* internalToNormalizedProc */ + NULL, /* createInternalRepProc */ + NULL, /* normalizePathProc */ + Zip_FSFilesystemPathTypeProc, + Zip_FSFilesystemSeparatorProc, + Zip_FSStatProc, + Zip_FSAccessProc, + Zip_FSOpenFileChannelProc, + Zip_FSMatchInDirectoryProc, + NULL, /* utimeProc */ + NULL, /* linkProc */ + Zip_FSListVolumesProc, + Zip_FSFileAttrStringsProc, + Zip_FSFileAttrsGetProc, + Zip_FSFileAttrsSetProc, + NULL, /* createDirectoryProc */ + NULL, /* removeDirectoryProc */ + NULL, /* deleteFileProc */ + NULL, /* copyFileProc */ + NULL, /* renameFileProc */ + NULL, /* copyDirectoryProc */ + NULL, /* lstatProc */ + (Tcl_FSLoadFileProc *) Zip_FSLoadFile, + NULL, /* getCwdProc */ + NULL, /* chdirProc*/ +}; + +#endif /* HAVE_ZLIB */ + + + +/* + *------------------------------------------------------------------------- + * + * TclZipfsInit -- + * + * Perform per interpreter initialization of this module. + * + * Results: + * The return value is a standard Tcl result. + * + * Side effects: + * Initializes this module if not already initialized, and adds + * module related commands to the given interpreter. + * + *------------------------------------------------------------------------- + */ + +int +TclZipfsInit(Tcl_Interp *interp) +{ +#ifdef HAVE_ZLIB + /* one-time initialization */ + WriteLock(); + if (!ZipFS.initialized) { +#ifdef TCL_THREADS + static const Tcl_Time t = { 0, 0 }; + /* + * Inflate condition variable. + */ + Tcl_MutexLock(&ZipFSMutex); + Tcl_ConditionWait(&ZipFSCond, &ZipFSMutex, &t); + Tcl_MutexUnlock(&ZipFSMutex); +#endif + Tcl_FSRegister(NULL, &zipfsFilesystem); + Tcl_InitHashTable(&ZipFS.fileHash, TCL_STRING_KEYS); + Tcl_InitHashTable(&ZipFS.zipHash, TCL_STRING_KEYS); + ZipFS.initialized = ZipFS.idCount = 1; + } + Unlock(); + if(interp != NULL) { + static const EnsembleImplMap initMap[] = { + {"mount", ZipFSMountObjCmd, NULL, NULL, NULL, 0}, + {"unmount", ZipFSUnmountObjCmd, NULL, NULL, NULL, 0}, + {"mkkey", ZipFSMkKeyObjCmd, NULL, NULL, NULL, 0}, + {"mkimg", ZipFSMkImgObjCmd, NULL, NULL, NULL, 0}, + {"mkzip", ZipFSMkZipObjCmd, NULL, NULL, NULL, 0}, + {"lmkimg", ZipFSLMkImgObjCmd, NULL, NULL, NULL, 0}, + {"lmkzip", ZipFSLMkZipObjCmd, NULL, NULL, NULL, 0}, + {"exists", ZipFSExistsObjCmd, NULL, NULL, NULL, 1}, + {"info", ZipFSInfoObjCmd, NULL, NULL, NULL, 1}, + {"list", ZipFSListObjCmd, NULL, NULL, NULL, 1}, + {"canonical", ZipFSCanonicalObjCmd, NULL, NULL, NULL, 1}, + {NULL, NULL, NULL, NULL, NULL, 0} + }; + static const char findproc[] = + "namespace eval zipfs {}\n" + "proc ::zipfs::find dir {\n" + " set result {}\n" + " if {[catch {glob -directory $dir -tails -nocomplain * .*} list]} {\n" + " return $result\n" + " }\n" + " foreach file $list {\n" + " if {$file eq \".\" || $file eq \"..\"} {\n" + " continue\n" + " }\n" + " set file [file join $dir $file]\n" + " lappend result $file\n" + " foreach file [::zipfs::find $file] {\n" + " lappend result $file\n" + " }\n" + " }\n" + " return [lsort $result]\n" + "}\n"; + Tcl_EvalEx(interp, findproc, -1, TCL_EVAL_GLOBAL); + Tcl_LinkVar(interp, "::zipfs::wrmax", (char *) &ZipFS.wrmax, + TCL_LINK_INT); + TclMakeEnsemble(interp, "zipfs", initMap); + Tcl_PkgProvide(interp, "zipfs", "1.0"); + } + return TCL_OK; +#else + if (interp != NULL) { + Tcl_SetObjResult(interp, Tcl_NewStringObj("no zlib available", -1)); + } + return TCL_ERROR; +#endif +} + + +#ifndef HAVE_ZLIB + +/* + *------------------------------------------------------------------------- + * + * TclZipfsMount, TclZipfsUnmount -- + * + * Dummy version when no ZLIB support available. + * + *------------------------------------------------------------------------- + */ + +int +TclZipfsMount(Tcl_Interp *interp, const char *zipname, const char *mntpt, + const char *passwd) +{ + return TclZipFsInit(interp, 1); +} + +int +TclZipfsUnmount(Tcl_Interp *interp, const char *zipname) +{ + return TclZipFsInit(interp, 1); +} + +#endif + +/* + * Local Variables: + * mode: c + * c-basic-offset: 4 + * fill-column: 78 + * End: + */ diff --git a/generic/tclZipfs.h b/generic/tclZipfs.h deleted file mode 100644 index 01c9e96..0000000 --- a/generic/tclZipfs.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * tclZipfs.h -- - * - * This header file describes the interface of the ZIPFS filesystem - * - * Copyright (c) 2013-2015 Christian Werner - * - * See the file "license.terms" for information on usage and redistribution of - * this file, and for a DISCLAIMER OF ALL WARRANTIES. - */ - -#ifndef _ZIPFS_H -#define _ZIPFS_H - -#include "tcl.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef ZIPFSAPI -# define ZIPFSAPI extern -#endif - -#ifdef BUILD_tcl -# undef ZIPFSAPI -# define ZIPFSAPI DLLEXPORT -#endif - -ZIPFSAPI int Tclzipfs_Mount(Tcl_Interp *interp, const char *zipname, - const char *mntpt, const char *passwd); -ZIPFSAPI int Tclzipfs_Unmount(Tcl_Interp *interp, const char *zipname); -ZIPFSAPI int Tclzipfs_Init(Tcl_Interp *interp); -ZIPFSAPI int Tclzipfs_SafeInit(Tcl_Interp *interp); - -#ifdef __cplusplus -} -#endif - -#endif /* _ZIPFS_H */ - -/* - * Local Variables: - * mode: c - * c-basic-offset: 4 - * fill-column: 78 - * End: - */ diff --git a/generic/zipfs.c b/generic/zipfs.c deleted file mode 100644 index 70a8d6e..0000000 --- a/generic/zipfs.c +++ /dev/null @@ -1,4229 +0,0 @@ -/* - * zipfs.c -- - * - * Implementation of the ZIP filesystem used in AndroWish. - * - * Copyright (c) 2013-2015 Christian Werner - * - * See the file "license.terms" for information on usage and redistribution of - * this file, and for a DISCLAIMER OF ALL WARRANTIES. - */ - -#include "tclInt.h" -#include "tclFileSystem.h" -#include "tclZipfs.h" - -#if !defined(_WIN32) && !defined(_WIN64) -#include -#endif -#include -#include -#include -#include -#include -#include - -#ifdef HAVE_ZLIB -#include "zlib.h" -#include "zcrypt.h" - -/* - * Various constants and offsets found in ZIP archive files. - */ - -#define ZIP_SIG_LEN 4 - -/* Local header of ZIP archive member (at very beginning of each member). */ -#define ZIP_LOCAL_HEADER_SIG 0x04034b50 -#define ZIP_LOCAL_HEADER_LEN 30 -#define ZIP_LOCAL_SIG_OFFS 0 -#define ZIP_LOCAL_VERSION_OFFS 4 -#define ZIP_LOCAL_FLAGS_OFFS 6 -#define ZIP_LOCAL_COMPMETH_OFFS 8 -#define ZIP_LOCAL_MTIME_OFFS 10 -#define ZIP_LOCAL_MDATE_OFFS 12 -#define ZIP_LOCAL_CRC32_OFFS 14 -#define ZIP_LOCAL_COMPLEN_OFFS 18 -#define ZIP_LOCAL_UNCOMPLEN_OFFS 22 -#define ZIP_LOCAL_PATHLEN_OFFS 26 -#define ZIP_LOCAL_EXTRALEN_OFFS 28 - -/* Central header of ZIP archive member at end of ZIP file. */ -#define ZIP_CENTRAL_HEADER_SIG 0x02014b50 -#define ZIP_CENTRAL_HEADER_LEN 46 -#define ZIP_CENTRAL_SIG_OFFS 0 -#define ZIP_CENTRAL_VERSIONMADE_OFFS 4 -#define ZIP_CENTRAL_VERSION_OFFS 6 -#define ZIP_CENTRAL_FLAGS_OFFS 8 -#define ZIP_CENTRAL_COMPMETH_OFFS 10 -#define ZIP_CENTRAL_MTIME_OFFS 12 -#define ZIP_CENTRAL_MDATE_OFFS 14 -#define ZIP_CENTRAL_CRC32_OFFS 16 -#define ZIP_CENTRAL_COMPLEN_OFFS 20 -#define ZIP_CENTRAL_UNCOMPLEN_OFFS 24 -#define ZIP_CENTRAL_PATHLEN_OFFS 28 -#define ZIP_CENTRAL_EXTRALEN_OFFS 30 -#define ZIP_CENTRAL_FCOMMENTLEN_OFFS 32 -#define ZIP_CENTRAL_DISKFILE_OFFS 34 -#define ZIP_CENTRAL_IATTR_OFFS 36 -#define ZIP_CENTRAL_EATTR_OFFS 38 -#define ZIP_CENTRAL_LOCALHDR_OFFS 42 - -/* Central end signature at very end of ZIP file. */ -#define ZIP_CENTRAL_END_SIG 0x06054b50 -#define ZIP_CENTRAL_END_LEN 22 -#define ZIP_CENTRAL_END_SIG_OFFS 0 -#define ZIP_CENTRAL_DISKNO_OFFS 4 -#define ZIP_CENTRAL_DISKDIR_OFFS 6 -#define ZIP_CENTRAL_ENTS_OFFS 8 -#define ZIP_CENTRAL_TOTALENTS_OFFS 10 -#define ZIP_CENTRAL_DIRSIZE_OFFS 12 -#define ZIP_CENTRAL_DIRSTART_OFFS 16 -#define ZIP_CENTRAL_COMMENTLEN_OFFS 20 - -#define ZIP_MIN_VERSION 20 -#define ZIP_COMPMETH_STORED 0 -#define ZIP_COMPMETH_DEFLATED 8 - -#define ZIP_PASSWORD_END_SIG 0x5a5a4b50 - -/* - * Macros to read and write 16 and 32 bit integers from/to ZIP archives. - */ - -#define zip_read_int(p) \ - ((p)[0] | ((p)[1] << 8) | ((p)[2] << 16) | ((p)[3] << 24)) -#define zip_read_short(p) \ - ((p)[0] | ((p)[1] << 8)) - -#define zip_write_int(p, v) \ - (p)[0] = (v) & 0xff; (p)[1] = ((v) >> 8) & 0xff; \ - (p)[2] = ((v) >> 16) & 0xff; (p)[3] = ((v) >> 24) & 0xff; -#define zip_write_short(p, v) \ - (p)[0] = (v) & 0xff; (p)[1] = ((v) >> 8) & 0xff; - -/* - * Windows drive letters. - */ - -#if defined(_WIN32) || defined(_WIN64) -#define HAS_DRIVES 1 -static const char drvletters[] = - "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; -#else -#define HAS_DRIVES 0 -#endif - -/* - * Mutex to protect localtime(3) when no reentrant version available. - */ - -#if !defined(_WIN32) && !defined(_WIN64) -#ifndef HAVE_LOCALTIME_R -#ifdef TCL_THREADS -TCL_DECLARE_MUTEX(localtimeMutex) -#endif -#endif -#endif - -/* - * In-core description of mounted ZIP archive file. - */ - -typedef struct ZipFile { - char *name; /* Archive name */ - Tcl_Channel chan; /* Channel handle or NULL */ - unsigned char *data; /* Memory mapped or malloc'ed file */ - long length; /* Length of memory mapped file */ - unsigned char *tofree; /* Non-NULL if malloc'ed file */ - int nfiles; /* Number of files in archive */ - int baseoffs; /* Archive start */ - int baseoffsp; /* Password start */ - int centoffs; /* Archive directory start */ - char pwbuf[264]; /* Password buffer */ -#if defined(_WIN32) || defined(_WIN64) - HANDLE mh; -#endif - int nopen; /* Number of open files on archive */ - struct ZipEntry *entries; /* List of files in archive */ - struct ZipEntry *topents; /* List of top-level dirs in archive */ -#if HAS_DRIVES - int mntdrv; /* Drive letter of mount point */ -#endif - int mntptlen; /* Length of mount point */ - char mntpt[1]; /* Mount point */ -} ZipFile; - -/* - * In-core description of file contained in mounted ZIP archive. - */ - -typedef struct ZipEntry { - char *name; /* The full pathname of the virtual file */ - ZipFile *zipfile; /* The ZIP file holding this virtual file */ - long offset; /* Data offset into memory mapped ZIP file */ - int nbyte; /* Uncompressed size of the virtual file */ - int nbytecompr; /* Compressed size of the virtual file */ - int cmeth; /* Compress method */ - int isdir; /* Set to 1 if directory */ - int depth; /* Number of slashes in path. */ - int crc32; /* CRC-32 */ - int timestamp; /* Modification time */ - int isenc; /* True if data is encrypted */ - unsigned char *data; /* File data if written */ - struct ZipEntry *next; /* Next file in the same archive */ - struct ZipEntry *tnext; /* Next top-level dir in archive */ -} ZipEntry; - -/* - * File channel for file contained in mounted ZIP archive. - */ - -typedef struct ZipChannel { - ZipFile *zipfile; /* The ZIP file holding this channel */ - ZipEntry *zipentry; /* Pointer back to virtual file */ - unsigned long nmax; /* Max. size for write */ - unsigned long nbyte; /* Number of bytes of uncompressed data */ - unsigned long nread; /* Pos of next byte to be read from the channel */ - unsigned char *ubuf; /* Pointer to the uncompressed data */ - int iscompr; /* True if data is compressed */ - int isdir; /* Set to 1 if directory */ - int isenc; /* True if data is encrypted */ - int iswr; /* True if open for writing */ - unsigned long keys[3]; /* Key for decryption */ -} ZipChannel; - -/* - * Global variables. - * - * Most are kept in single ZipFS struct. When build with threading - * support this struct is protected by the ZipFSMutex (see below). - * - * The "fileHash" component is the process wide global table of all known - * ZIP archive members in all mounted ZIP archives. - * - * The "zipHash" components is the process wide global table of all mounted - * ZIP archive files. - */ - -static struct { - int initialized; /* True when initialized */ - int lock; /* RW lock, see below */ - int waiters; /* RW lock, see below */ - int wrmax; /* Maximum write size of a file */ - int idCount; /* Counter for channel names */ - Tcl_HashTable fileHash; /* File name to ZipEntry mapping */ - Tcl_HashTable zipHash; /* Mount to ZipFile mapping */ -} ZipFS = { - 0, 0, 0, 0, 0, -}; - -/* - * For password rotation. - */ - -static const char pwrot[16] = { - 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, - 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0 -}; - -/* - * Table to compute CRC32. - */ - -static const unsigned int crc32tab[256] = { - 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, - 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, - 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, - 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, - 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, - 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, - 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, - 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, - 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, - 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, - 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, - 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, - 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, - 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, - 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, - 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, - 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, - 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, - 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, - 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, - 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, - 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, - 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, - 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, - 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, - 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, - 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, - 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, - 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344, - 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, - 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, - 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, - 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, - 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, - 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, - 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, - 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, - 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, - 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, - 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, - 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, - 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, - 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, - 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, - 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, - 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, - 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, - 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, - 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, - 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, - 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, - 0x2d02ef8d, -}; - -/* - *------------------------------------------------------------------------- - * - * ReadLock, WriteLock, Unlock -- - * - * POSIX like rwlock functions to support multiple readers - * and single writer on internal structs. - * - * Limitations: - * - a read lock cannot be promoted to a write lock - * - a write lock may not be nested - * - *------------------------------------------------------------------------- - */ - -TCL_DECLARE_MUTEX(ZipFSMutex) - -#ifdef TCL_THREADS - -static Tcl_Condition ZipFSCond; - -static void -ReadLock(void) -{ - Tcl_MutexLock(&ZipFSMutex); - while (ZipFS.lock < 0) { - ZipFS.waiters++; - Tcl_ConditionWait(&ZipFSCond, &ZipFSMutex, NULL); - ZipFS.waiters--; - } - ZipFS.lock++; - Tcl_MutexUnlock(&ZipFSMutex); -} - -static void -WriteLock(void) -{ - Tcl_MutexLock(&ZipFSMutex); - while (ZipFS.lock != 0) { - ZipFS.waiters++; - Tcl_ConditionWait(&ZipFSCond, &ZipFSMutex, NULL); - ZipFS.waiters--; - } - ZipFS.lock = -1; - Tcl_MutexUnlock(&ZipFSMutex); -} - -static void -Unlock(void) -{ - Tcl_MutexLock(&ZipFSMutex); - if (ZipFS.lock > 0) { - --ZipFS.lock; - } else if (ZipFS.lock < 0) { - ZipFS.lock = 0; - } - if ((ZipFS.lock == 0) && (ZipFS.waiters > 0)) { - Tcl_ConditionNotify(&ZipFSCond); - } - Tcl_MutexUnlock(&ZipFSMutex); -} - -#else - -#define ReadLock() do {} while (0) -#define WriteLock() do {} while (0) -#define Unlock() do {} while (0) - -#endif - -/* - *------------------------------------------------------------------------- - * - * DosTimeDate, ToDosTime, ToDosDate -- - * - * Functions to perform conversions between DOS time stamps - * and POSIX time_t. - * - *------------------------------------------------------------------------- - */ - -static time_t -DosTimeDate(int dosDate, int dosTime) -{ - struct tm tm; - time_t ret; - - memset(&tm, 0, sizeof (tm)); - tm.tm_year = (((dosDate & 0xfe00) >> 9) + 80); - tm.tm_mon = ((dosDate & 0x1e0) >> 5) - 1; - tm.tm_mday = dosDate & 0x1f; - tm.tm_hour = (dosTime & 0xf800) >> 11; - tm.tm_min = (dosTime & 0x7e) >> 5; - tm.tm_sec = (dosTime & 0x1f) << 1; - ret = mktime(&tm); - if (ret == (time_t) -1) { - /* fallback to 1980-01-01T00:00:00+00:00 (DOS epoch) */ - ret = (time_t) 315532800; - } - return ret; -} - -static int -ToDosTime(time_t when) -{ - struct tm *tmp, tm; - -#ifdef TCL_THREADS -#if defined(_WIN32) || defined(_WIN64) - /* Win32 uses thread local storage */ - tmp = localtime(&when); - tm = *tmp; -#else -#ifdef HAVE_LOCALTIME_R - tmp = &tm; - localtime_r(&when, tmp); -#else - Tcl_MutexLock(&localtimeMutex); - tmp = localtime(&when); - tm = *tmp; - Tcl_MutexUnlock(&localtimeMutex); -#endif -#endif -#else - tmp = localtime(&when); - tm = *tmp; -#endif - return (tm.tm_hour << 11) | (tm.tm_min << 5) | (tm.tm_sec >> 1); -} - -static int -ToDosDate(time_t when) -{ - struct tm *tmp, tm; - -#ifdef TCL_THREADS -#if defined(_WIN32) || defined(_WIN64) - /* Win32 uses thread local storage */ - tmp = localtime(&when); - tm = *tmp; -#else -#ifdef HAVE_LOCALTIME_R - tmp = &tm; - localtime_r(&when, tmp); -#else - Tcl_MutexLock(&localtimeMutex); - tmp = localtime(&when); - tm = *tmp; - Tcl_MutexUnlock(&localtimeMutex); -#endif -#endif -#else - tmp = localtime(&when); - tm = *tmp; -#endif - return ((tm.tm_year - 80) << 9) | ((tm.tm_mon + 1) << 5) | tm.tm_mday; -} - -/* - *------------------------------------------------------------------------- - * - * CountSlashes -- - * - * This function counts the number of slashes in a pathname string. - * - * Results: - * Number of slashes found in string. - * - * Side effects: - * None. - * - *------------------------------------------------------------------------- - */ - -static int -CountSlashes(const char *string) -{ - int count = 0; - const char *p = string; - - while (*p != '\0') { - if (*p == '/') { - count++; - } - p++; - } - return count; -} - -/* - *------------------------------------------------------------------------- - * - * CanonicalPath -- - * - * This function computes the canonical path from a directory - * and file name components into the specified Tcl_DString. - * - * Results: - * Returns the pointer to the canonical path contained in the - * specified Tcl_DString. - * - * Side effects: - * Modifies the specified Tcl_DString. - * - *------------------------------------------------------------------------- - */ - -static char * -CanonicalPath(const char *root, const char *tail, Tcl_DString *dsPtr) -{ - char *path; - int i, j, c, isunc = 0; - -#if HAS_DRIVES - if ((tail[0] != '\0') && (strchr(drvletters, tail[0]) != NULL) && - (tail[1] == ':')) { - tail += 2; - } - /* UNC style path */ - if (tail[0] == '\\') { - root = ""; - ++tail; - } - if (tail[0] == '\\') { - root = "/"; - ++tail; - } -#endif - /* UNC style path */ - if ((root[0] == '/') && (root[1] == '/')) { - isunc = 1; - } - if (tail[0] == '/') { - root = ""; - ++tail; - isunc = 0; - } - if (tail[0] == '/') { - root = "/"; - ++tail; - isunc = 1; - } - i = strlen(root); - j = strlen(tail); - Tcl_DStringSetLength(dsPtr, i + j + 1); - path = Tcl_DStringValue(dsPtr); - memcpy(path, root, i); - path[i++] = '/'; - memcpy(path + i, tail, j); -#if HAS_DRIVES - for (i = 0; path[i] != '\0'; i++) { - if (path[i] == '\\') { - path[i] = '/'; - } - } -#endif - for (i = j = 0; (c = path[i]) != '\0'; i++) { - if (c == '/') { - int c2 = path[i + 1]; - - if (c2 == '/') { - continue; - } - if (c2 == '.') { - int c3 = path[i + 2]; - - if ((c3 == '/') || (c3 == '\0')) { - i++; - continue; - } - if ((c3 == '.') && - ((path[i + 3] == '/') || (path [i + 3] == '\0'))) { - i += 2; - while ((j > 0) && (path[j - 1] != '/')) { - j--; - } - if (j > isunc) { - --j; - while ((j > 1 + isunc) && (path[j - 2] == '/')) { - j--; - } - } - continue; - } - } - } - path[j++] = c; - } - if (j == 0) { - path[j++] = '/'; - } - path[j] = 0; - Tcl_DStringSetLength(dsPtr, j); - return Tcl_DStringValue(dsPtr); -} - -/* - *------------------------------------------------------------------------- - * - * AbsolutePath -- - * - * This function computes the absolute path from a given - * (relative) path name into the specified Tcl_DString. - * - * Results: - * Returns the pointer to the absolute path contained in the - * specified Tcl_DString. - * - * Side effects: - * Modifies the specified Tcl_DString. - * - *------------------------------------------------------------------------- - */ - -static char * -AbsolutePath(const char *path, -#if HAS_DRIVES - int *drvPtr, -#endif - Tcl_DString *dsPtr) -{ - char *result; - -#if HAS_DRIVES - if (drvPtr != NULL) { - *drvPtr = 0; - } -#endif - if (*path == '~') { - Tcl_DStringAppend(dsPtr, path, -1); - return Tcl_DStringValue(dsPtr); - } - if ((*path != '/') -#if HAS_DRIVES - && (*path != '\\') && - (((*path != '\0') && (strchr(drvletters, *path) == NULL)) || - (path[1] != ':')) -#endif - ) { - Tcl_DString pwd; - - /* relative path */ - Tcl_DStringInit(&pwd); - Tcl_GetCwd(NULL, &pwd); - result = Tcl_DStringValue(&pwd); -#if HAS_DRIVES - if ((result[0] != '\0') && (strchr(drvletters, result[0]) != NULL) && - (result[1] == ':')) { - if (drvPtr != NULL) { - drvPtr[0] = result[0]; - if ((drvPtr[0] >= 'a') && (drvPtr[0] <= 'z')) { - drvPtr[0] -= 'a' - 'A'; - } - } - result += 2; - } -#endif - result = CanonicalPath(result, path, dsPtr); - Tcl_DStringFree(&pwd); - } else { - /* absolute path */ -#if HAS_DRIVES - if ((path[0] != '\0') && (strchr(drvletters, path[0]) != NULL) && - (path[1] == ':')) { - if (drvPtr != NULL) { - drvPtr[0] = path[0]; - if ((drvPtr[0] >= 'a') && (drvPtr[0] <= 'z')) { - drvPtr[0] -= 'a' - 'A'; - } - } - } -#endif - result = CanonicalPath("", path, dsPtr); - } - return result; -} - -/* - *------------------------------------------------------------------------- - * - * ZipFSLookup -- - * - * This function returns the ZIP entry struct corresponding to - * the ZIP archive member of the given file name. - * - * Results: - * Returns the pointer to ZIP entry struct or NULL if the - * the given file name could not be found in the global list - * of ZIP archive members. - * - * Side effects: - * None. - * - *------------------------------------------------------------------------- - */ - -static ZipEntry * -ZipFSLookup(char *filename) -{ - char *realname; - Tcl_HashEntry *hPtr; - ZipEntry *z; - Tcl_DString ds; -#if HAS_DRIVES - int drive = 0; -#endif - - Tcl_DStringInit(&ds); -#if HAS_DRIVES - realname = AbsolutePath(filename, &drive, &ds); -#else - realname = AbsolutePath(filename, &ds); -#endif - hPtr = Tcl_FindHashEntry(&ZipFS.fileHash, realname); - z = hPtr ? (ZipEntry *) Tcl_GetHashValue(hPtr) : NULL; - Tcl_DStringFree(&ds); -#if HAS_DRIVES - if ((z != NULL) && drive && (drive != z->zipfile->mntdrv)) { - z = NULL; - } -#endif - return z; -} - -#ifdef NEVER_USED - -/* - *------------------------------------------------------------------------- - * - * ZipFSLookupMount -- - * - * This function returns an indication if the given file name - * corresponds to a mounted ZIP archive file. - * - * Results: - * Returns true, if the given file name is a mounted ZIP archive file. - * - * Side effects: - * None. - * - *------------------------------------------------------------------------- - */ - -static int -ZipFSLookupMount(char *filename) -{ - char *realname; - Tcl_HashEntry *hPtr; - Tcl_HashSearch search; - ZipFile *zf; - Tcl_DString ds; - int match = 0; -#if HAS_DRIVES - int drive = 0; -#endif - - Tcl_DStringInit(&ds); -#if HAS_DRIVES - realname = AbsolutePath(filename, &drive, &ds); -#else - realname = AbsolutePath(filename, &ds); -#endif - hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); - while (hPtr != NULL) { - if ((zf = (ZipFile *) Tcl_GetHashValue(hPtr)) != NULL) { -#if HAS_DRIVES - if (drive && (drive != zf->mntdrv)) { - hPtr = Tcl_NextHashEntry(&search); - continue; - } -#endif - if (strcmp(zf->mntpt, realname) == 0) { - match = 1; - break; - } - } - hPtr = Tcl_NextHashEntry(&search); - } - Tcl_DStringFree(&ds); - return match; -} -#endif - -/* - *------------------------------------------------------------------------- - * - * ZipFSCloseArchive -- - * - * This function closes a mounted ZIP archive file. - * - * Results: - * None. - * - * Side effects: - * A memory mapped ZIP archive is unmapped, allocated memory is - * released. - * - *------------------------------------------------------------------------- - */ - -static void -ZipFSCloseArchive(Tcl_Interp *interp, ZipFile *zf) -{ -#if defined(_WIN32) || defined(_WIN64) - if ((zf->data != NULL) && (zf->tofree == NULL)) { - UnmapViewOfFile(zf->data); - zf->data = NULL; - } - if (zf->mh != INVALID_HANDLE_VALUE) { - CloseHandle(zf->mh); - } -#else - if ((zf->data != MAP_FAILED) && (zf->tofree == NULL)) { - munmap(zf->data, zf->length); - zf->data = MAP_FAILED; - } -#endif - if (zf->tofree != NULL) { - Tcl_Free((char *) zf->tofree); - zf->tofree = NULL; - } - Tcl_Close(interp, zf->chan); - zf->chan = NULL; -} - -/* - *------------------------------------------------------------------------- - * - * ZipFSOpenArchive -- - * - * This function opens a ZIP archive file for reading. An attempt - * is made to memory map that file. Otherwise it is read into - * an allocated memory buffer. The ZIP archive header is verified - * and must be valid for the function to succeed. When "needZip" - * is zero an embedded ZIP archive in an executable file is accepted. - * - * Results: - * TCL_OK on success, TCL_ERROR otherwise with an error message - * placed into the given "interp" if it is not NULL. - * - * Side effects: - * ZIP archive is memory mapped or read into allocated memory, - * the given ZipFile struct is filled with information about - * the ZIP archive file. - * - *------------------------------------------------------------------------- - */ - -static int -ZipFSOpenArchive(Tcl_Interp *interp, const char *zipname, int needZip, - ZipFile *zf) -{ - int i; - ClientData handle; - unsigned char *p, *q; - -#if defined(_WIN32) || defined(_WIN64) - zf->data = NULL; - zf->mh = INVALID_HANDLE_VALUE; -#else - zf->data = MAP_FAILED; -#endif - zf->length = 0; - zf->nfiles = 0; - zf->baseoffs = zf->baseoffsp = 0; - zf->tofree = NULL; - zf->pwbuf[0] = 0; - zf->chan = Tcl_OpenFileChannel(interp, zipname, "r", 0); - if (zf->chan == NULL) { - return TCL_ERROR; - } - if (Tcl_GetChannelHandle(zf->chan, TCL_READABLE, &handle) != TCL_OK) { - if (Tcl_SetChannelOption(interp, zf->chan, "-translation", "binary") - != TCL_OK) { - goto error; - } - if (Tcl_SetChannelOption(interp, zf->chan, "-encoding", "binary") - != TCL_OK) { - goto error; - } - zf->length = Tcl_Seek(zf->chan, 0, SEEK_END); - if ((zf->length <= 0) || (zf->length > 64 * 1024 * 1024)) { - if (interp) { - Tcl_SetObjResult(interp, - Tcl_NewStringObj("illegal file size", -1)); - } - goto error; - } - Tcl_Seek(zf->chan, 0, SEEK_SET); - zf->tofree = zf->data = (unsigned char *) Tcl_AttemptAlloc(zf->length); - if (zf->tofree == NULL) { - if (interp) { - Tcl_SetObjResult(interp, - Tcl_NewStringObj("out of memory", -1)); - } - goto error; - } - i = Tcl_Read(zf->chan, (char *) zf->data, zf->length); - if (i != zf->length) { - if (interp) { - Tcl_SetObjResult(interp, - Tcl_NewStringObj("file read error", -1)); - } - goto error; - } - Tcl_Close(interp, zf->chan); - zf->chan = NULL; - } else { -#if defined(_WIN32) || defined(_WIN64) - zf->length = GetFileSize((HANDLE) handle, 0); - if ((zf->length == INVALID_FILE_SIZE) || - (zf->length < ZIP_CENTRAL_END_LEN)) { - if (interp != NULL) { - Tcl_SetObjResult(interp, - Tcl_NewStringObj("invalid file size", -1)); - } - goto error; - } - zf->mh = CreateFileMapping((HANDLE) handle, 0, PAGE_READONLY, 0, - zf->length, 0); - if (zf->mh == INVALID_HANDLE_VALUE) { - if (interp != NULL) { - Tcl_SetObjResult(interp, - Tcl_NewStringObj("file mapping failed", -1)); - } - goto error; - } - zf->data = MapViewOfFile(zf->mh, FILE_MAP_READ, 0, 0, zf->length); - if (zf->data == NULL) { - if (interp != NULL) { - Tcl_SetObjResult(interp, - Tcl_NewStringObj("file mapping failed", -1)); - } - goto error; - } -#else - zf->length = lseek((int) (long) handle, 0, SEEK_END); - if ((zf->length == -1) || (zf->length < ZIP_CENTRAL_END_LEN)) { - if (interp != NULL) { - Tcl_SetObjResult(interp, - Tcl_NewStringObj("invalid file size", -1)); - } - goto error; - } - lseek((int) (long) handle, 0, SEEK_SET); - zf->data = (unsigned char *) mmap(0, zf->length, PROT_READ, - MAP_FILE | MAP_PRIVATE, - (int) (long) handle, 0); - if (zf->data == MAP_FAILED) { - if (interp != NULL) { - Tcl_SetObjResult(interp, - Tcl_NewStringObj("file mapping failed", -1)); - } - goto error; - } -#endif - } - p = zf->data + zf->length - ZIP_CENTRAL_END_LEN; - while (p >= zf->data) { - if (*p == (ZIP_CENTRAL_END_SIG & 0xFF)) { - if (zip_read_int(p) == ZIP_CENTRAL_END_SIG) { - break; - } - p -= ZIP_SIG_LEN; - } else { - --p; - } - } - if (p < zf->data) { - if (!needZip) { - zf->baseoffs = zf->baseoffsp = zf->length; - return TCL_OK; - } - if (interp != NULL) { - Tcl_SetObjResult(interp, - Tcl_NewStringObj("wrong end signature", -1)); - } - goto error; - } - zf->nfiles = zip_read_short(p + ZIP_CENTRAL_ENTS_OFFS); - if (zf->nfiles == 0) { - if (!needZip) { - zf->baseoffs = zf->baseoffsp = zf->length; - return TCL_OK; - } - if (interp != NULL) { - Tcl_SetObjResult(interp, - Tcl_NewStringObj("empty archive", -1)); - } - goto error; - } - q = zf->data + zip_read_int(p + ZIP_CENTRAL_DIRSTART_OFFS); - p -= zip_read_int(p + ZIP_CENTRAL_DIRSIZE_OFFS); - if ((p < zf->data) || (p > (zf->data + zf->length)) || - (q < zf->data) || (q > (zf->data + zf->length))) { - if (!needZip) { - zf->baseoffs = zf->baseoffsp = zf->length; - return TCL_OK; - } - if (interp != NULL) { - Tcl_SetObjResult(interp, - Tcl_NewStringObj("archive directory not found", -1)); - } - goto error; - } - zf->baseoffs = zf->baseoffsp = p - q; - zf->centoffs = p - zf->data; - q = p; - for (i = 0; i < zf->nfiles; i++) { - int pathlen, comlen, extra; - - if ((q + ZIP_CENTRAL_HEADER_LEN) > (zf->data + zf->length)) { - if (interp != NULL) { - Tcl_SetObjResult(interp, - Tcl_NewStringObj("wrong header length", -1)); - } - goto error; - } - if (zip_read_int(q) != ZIP_CENTRAL_HEADER_SIG) { - if (interp != NULL) { - Tcl_SetObjResult(interp, - Tcl_NewStringObj("wrong header signature", -1)); - } - goto error; - } - pathlen = zip_read_short(q + ZIP_CENTRAL_PATHLEN_OFFS); - comlen = zip_read_short(q + ZIP_CENTRAL_FCOMMENTLEN_OFFS); - extra = zip_read_short(q + ZIP_CENTRAL_EXTRALEN_OFFS); - q += pathlen + comlen + extra + ZIP_CENTRAL_HEADER_LEN; - } - q = zf->data + zf->baseoffs; - if ((zf->baseoffs >= 6) && - (zip_read_int(q - 4) == ZIP_PASSWORD_END_SIG)) { - i = q[-5]; - if (q - 5 - i > zf->data) { - zf->pwbuf[0] = i; - memcpy(zf->pwbuf + 1, q - 5 - i, i); - zf->baseoffsp -= i ? (5 + i) : 0; - } - } - return TCL_OK; - -error: - ZipFSCloseArchive(interp, zf); - return TCL_ERROR; -} - -/* - *------------------------------------------------------------------------- - * - * Tclzipfs_Mount -- - * - * This procedure is invoked to mount a given ZIP archive file on - * a given mountpoint with optional ZIP password. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * A ZIP archive file is read, analyzed and mounted, resources are - * allocated. - * - *------------------------------------------------------------------------- - */ - -int -Tclzipfs_Mount(Tcl_Interp *interp, const char *zipname, const char *mntpt, - const char *passwd) -{ - char *realname, *p; - int i, pwlen, isNew; - ZipFile *zf, zf0; - ZipEntry *z; - Tcl_HashEntry *hPtr; - Tcl_DString ds, dsm, fpBuf; - unsigned char *q; -#if HAS_DRIVES - int drive = 0; -#endif - - ReadLock(); - if (!ZipFS.initialized) { - if (interp != NULL) { - Tcl_SetObjResult(interp, - Tcl_NewStringObj("not initialized", -1)); - } - Unlock(); - return TCL_ERROR; - } - if (zipname == NULL) { - Tcl_HashSearch search; - int ret = TCL_OK; - - i = 0; - hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); - while (hPtr != NULL) { - if ((zf = (ZipFile *) Tcl_GetHashValue(hPtr)) != NULL) { - if (interp != NULL) { - Tcl_AppendElement(interp, zf->mntpt); - Tcl_AppendElement(interp, zf->name); - } - ++i; - } - hPtr = Tcl_NextHashEntry(&search); - } - if (interp == NULL) { - ret = (i > 0) ? TCL_OK : TCL_BREAK; - } - Unlock(); - return ret; - } - if (mntpt == NULL) { - if (interp == NULL) { - Unlock(); - return TCL_OK; - } - Tcl_DStringInit(&ds); -#if HAS_DRIVES - p = AbsolutePath(zipname, &drive, &ds); -#else - p = AbsolutePath(zipname, &ds); -#endif - hPtr = Tcl_FindHashEntry(&ZipFS.zipHash, p); - if (hPtr != NULL) { - if ((zf = Tcl_GetHashValue(hPtr)) != NULL) { -#if HAS_DRIVES - if (drive == zf->mntdrv) { - Tcl_Obj *string; - char drvbuf[3]; - - drvbuf[0] = zf->mntdrv; - drvbuf[1] = ':'; - drvbuf[2] = '\0'; - string = Tcl_NewStringObj(drvbuf, 2); - Tcl_AppendToObj(string, zf->mntpt, zf->mntptlen); - Tcl_SetObjResult(interp, string); - } -#else - Tcl_SetObjResult(interp, - Tcl_NewStringObj(zf->mntpt, zf->mntptlen)); -#endif - } - } - Unlock(); - Tcl_DStringFree(&ds); - return TCL_OK; - } - Unlock(); - pwlen = 0; - if (passwd != NULL) { - pwlen = strlen(passwd); - if ((pwlen > 255) || (strchr(passwd, 0xff) != NULL)) { - if (interp) { - Tcl_SetObjResult(interp, - Tcl_NewStringObj("illegal password", -1)); - } - return TCL_ERROR; - } - } - if (ZipFSOpenArchive(interp, zipname, 1, &zf0) != TCL_OK) { - return TCL_ERROR; - } - Tcl_DStringInit(&ds); -#if HAS_DRIVES - realname = AbsolutePath(zipname, NULL, &ds); -#else - realname = AbsolutePath(zipname, &ds); -#endif - /* - * Mount point can come from Tcl_GetNameOfExecutable() - * which sometimes is a relative or otherwise denormalized path. - * But an absolute name is needed as mount point here. - */ - Tcl_DStringInit(&dsm); -#if HAS_DRIVES - mntpt = AbsolutePath(mntpt, &drive, &dsm); -#else - mntpt = AbsolutePath(mntpt, &dsm); -#endif - WriteLock(); - hPtr = Tcl_CreateHashEntry(&ZipFS.zipHash, realname, &isNew); - Tcl_DStringSetLength(&ds, 0); - if (!isNew) { - zf = (ZipFile *) Tcl_GetHashValue(hPtr); - if (interp != NULL) { - Tcl_AppendResult(interp, "already mounted on \"", zf->mntptlen ? - zf->mntpt : "/", "\"", (char *) NULL); - } - Unlock(); - Tcl_DStringFree(&ds); - Tcl_DStringFree(&dsm); - ZipFSCloseArchive(interp, &zf0); - return TCL_ERROR; - } - if (strcmp(mntpt, "/") == 0) { - mntpt = ""; - } - zf = (ZipFile *) Tcl_AttemptAlloc(sizeof (*zf) + strlen(mntpt) + 1); - if (zf == NULL) { - if (interp != NULL) { - Tcl_AppendResult(interp, "out of memory", (char *) NULL); - } - Unlock(); - Tcl_DStringFree(&ds); - Tcl_DStringFree(&dsm); - ZipFSCloseArchive(interp, &zf0); - return TCL_ERROR; - } - *zf = zf0; - zf->name = Tcl_GetHashKey(&ZipFS.zipHash, hPtr); - strcpy(zf->mntpt, mntpt); - zf->mntptlen = strlen(zf->mntpt); -#if HAS_DRIVES - for (p = zf->mntpt; *p != '\0'; p++) { - if (*p == '\\') { - *p = '/'; - } - } - zf->mntdrv = drive; -#endif - zf->entries = NULL; - zf->topents = NULL; - zf->nopen = 0; - Tcl_SetHashValue(hPtr, (ClientData) zf); - if ((zf->pwbuf[0] == 0) && pwlen) { - int k = 0; - - i = pwlen; - zf->pwbuf[k++] = i; - while (i > 0) { - zf->pwbuf[k] = (passwd[i - 1] & 0x0f) | - pwrot[(passwd[i - 1] >> 4) & 0x0f]; - k++; - i--; - } - zf->pwbuf[k] = '\0'; - } - if (mntpt[0] != '\0') { - z = (ZipEntry *) Tcl_Alloc(sizeof (*z)); - z->name = NULL; - z->tnext = NULL; - z->depth = CountSlashes(mntpt); - z->zipfile = zf; - z->isdir = 1; - z->isenc = 0; - z->offset = zf->baseoffs; - z->crc32 = 0; - z->timestamp = 0; - z->nbyte = z->nbytecompr = 0; - z->cmeth = ZIP_COMPMETH_STORED; - z->data = NULL; - hPtr = Tcl_CreateHashEntry(&ZipFS.fileHash, mntpt, &isNew); - if (!isNew) { - /* skip it */ - Tcl_Free((char *) z); - } else { - Tcl_SetHashValue(hPtr, (ClientData) z); - z->name = Tcl_GetHashKey(&ZipFS.fileHash, hPtr); - z->next = zf->entries; - zf->entries = z; - } - } - q = zf->data + zf->centoffs; - Tcl_DStringInit(&fpBuf); - for (i = 0; i < zf->nfiles; i++) { - int pathlen, comlen, extra, isdir = 0, dosTime, dosDate, nbcompr, offs; - unsigned char *lq, *gq = NULL; - char *fullpath, *path; - - pathlen = zip_read_short(q + ZIP_CENTRAL_PATHLEN_OFFS); - comlen = zip_read_short(q + ZIP_CENTRAL_FCOMMENTLEN_OFFS); - extra = zip_read_short(q + ZIP_CENTRAL_EXTRALEN_OFFS); - Tcl_DStringSetLength(&ds, 0); - Tcl_DStringAppend(&ds, (char *) q + ZIP_CENTRAL_HEADER_LEN, pathlen); - path = Tcl_DStringValue(&ds); - if ((pathlen > 0) && (path[pathlen - 1] == '/')) { - Tcl_DStringSetLength(&ds, pathlen - 1); - path = Tcl_DStringValue(&ds); - isdir = 1; - } - if ((strcmp(path, ".") == 0) || (strcmp(path, "..") == 0)) { - goto nextent; - } - lq = zf->data + zf->baseoffs + - zip_read_int(q + ZIP_CENTRAL_LOCALHDR_OFFS); - if ((lq < zf->data) || (lq > (zf->data + zf->length))) { - goto nextent; - } - nbcompr = zip_read_int(lq + ZIP_LOCAL_COMPLEN_OFFS); - if (!isdir && (nbcompr == 0) && - (zip_read_int(lq + ZIP_LOCAL_UNCOMPLEN_OFFS) == 0) && - (zip_read_int(lq + ZIP_LOCAL_CRC32_OFFS) == 0)) { - gq = q; - nbcompr = zip_read_int(gq + ZIP_CENTRAL_COMPLEN_OFFS); - } - offs = (lq - zf->data) - + ZIP_LOCAL_HEADER_LEN - + zip_read_short(lq + ZIP_LOCAL_PATHLEN_OFFS) - + zip_read_short(lq + ZIP_LOCAL_EXTRALEN_OFFS); - if ((offs + nbcompr) > zf->length) { - goto nextent; - } - if (!isdir && (mntpt[0] == '\0') && !CountSlashes(path)) { -#ifdef ANDROID - /* - * When mounting the ZIP archive on the root directory try - * to remap top level regular files of the archive to - * /assets/.root/... since this directory should not be - * in a valid APK due to the leading dot in the file name - * component. This trick should make the files - * AndroidManifest.xml, resources.arsc, and classes.dex - * visible to Tcl. - */ - Tcl_DString ds2; - - Tcl_DStringInit(&ds2); - Tcl_DStringAppend(&ds2, "assets/.root/", -1); - Tcl_DStringAppend(&ds2, path, -1); - hPtr = Tcl_FindHashEntry(&ZipFS.fileHash, Tcl_DStringValue(&ds2)); - if (hPtr != NULL) { - /* should not happen but skip it anyway */ - Tcl_DStringFree(&ds2); - goto nextent; - } - Tcl_DStringSetLength(&ds, 0); - Tcl_DStringAppend(&ds, Tcl_DStringValue(&ds2), - Tcl_DStringLength(&ds2)); - path = Tcl_DStringValue(&ds); - Tcl_DStringFree(&ds2); -#else - /* - * Regular files skipped when mounting on root. - */ - goto nextent; -#endif - } - Tcl_DStringSetLength(&fpBuf, 0); - fullpath = CanonicalPath(mntpt, path, &fpBuf); - z = (ZipEntry *) Tcl_Alloc(sizeof (*z)); - z->name = NULL; - z->tnext = NULL; - z->depth = CountSlashes(fullpath); - z->zipfile = zf; - z->isdir = isdir; - z->isenc = (zip_read_short(lq + ZIP_LOCAL_FLAGS_OFFS) & 1) - && (nbcompr > 12); - z->offset = offs; - if (gq != NULL) { - z->crc32 = zip_read_int(gq + ZIP_CENTRAL_CRC32_OFFS); - dosDate = zip_read_short(gq + ZIP_CENTRAL_MDATE_OFFS); - dosTime = zip_read_short(gq + ZIP_CENTRAL_MTIME_OFFS); - z->timestamp = DosTimeDate(dosDate, dosTime); - z->nbyte = zip_read_int(gq + ZIP_CENTRAL_UNCOMPLEN_OFFS); - z->cmeth = zip_read_short(gq + ZIP_CENTRAL_COMPMETH_OFFS); - } else { - z->crc32 = zip_read_int(lq + ZIP_LOCAL_CRC32_OFFS); - dosDate = zip_read_short(lq + ZIP_LOCAL_MDATE_OFFS); - dosTime = zip_read_short(lq + ZIP_LOCAL_MTIME_OFFS); - z->timestamp = DosTimeDate(dosDate, dosTime); - z->nbyte = zip_read_int(lq + ZIP_LOCAL_UNCOMPLEN_OFFS); - z->cmeth = zip_read_short(lq + ZIP_LOCAL_COMPMETH_OFFS); - } - z->nbytecompr = nbcompr; - z->data = NULL; - hPtr = Tcl_CreateHashEntry(&ZipFS.fileHash, fullpath, &isNew); - if (!isNew) { - /* should not happen but skip it anyway */ - Tcl_Free((char *) z); - } else { - Tcl_SetHashValue(hPtr, (ClientData) z); - z->name = Tcl_GetHashKey(&ZipFS.fileHash, hPtr); - z->next = zf->entries; - zf->entries = z; - if (isdir && (mntpt[0] == '\0') && (z->depth == 1)) { - z->tnext = zf->topents; - zf->topents = z; - } - if (!z->isdir && (z->depth > 1)) { - char *dir, *end; - ZipEntry *zd; - - Tcl_DStringSetLength(&ds, strlen(z->name) + 8); - Tcl_DStringSetLength(&ds, 0); - Tcl_DStringAppend(&ds, z->name, -1); - dir = Tcl_DStringValue(&ds); - end = strrchr(dir, '/'); - while ((end != NULL) && (end != dir)) { - Tcl_DStringSetLength(&ds, end - dir); - hPtr = Tcl_FindHashEntry(&ZipFS.fileHash, dir); - if (hPtr != NULL) { - break; - } - zd = (ZipEntry *) Tcl_Alloc(sizeof (*zd)); - zd->name = NULL; - zd->tnext = NULL; - zd->depth = CountSlashes(dir); - zd->zipfile = zf; - zd->isdir = 1; - zd->isenc = 0; - zd->offset = z->offset; - zd->crc32 = 0; - zd->timestamp = z->timestamp; - zd->nbyte = zd->nbytecompr = 0; - zd->cmeth = ZIP_COMPMETH_STORED; - zd->data = NULL; - hPtr = Tcl_CreateHashEntry(&ZipFS.fileHash, dir, &isNew); - if (!isNew) { - /* should not happen but skip it anyway */ - Tcl_Free((char *) zd); - } else { - Tcl_SetHashValue(hPtr, (ClientData) zd); - zd->name = Tcl_GetHashKey(&ZipFS.fileHash, hPtr); - zd->next = zf->entries; - zf->entries = zd; - if ((mntpt[0] == '\0') && (zd->depth == 1)) { - zd->tnext = zf->topents; - zf->topents = zd; - } - } - end = strrchr(dir, '/'); - } - } - } -nextent: - q += pathlen + comlen + extra + ZIP_CENTRAL_HEADER_LEN; - } - Unlock(); - Tcl_DStringFree(&fpBuf); - Tcl_DStringFree(&ds); - Tcl_DStringFree(&dsm); - Tcl_FSMountsChanged(NULL); - return TCL_OK; -} - -/* - *------------------------------------------------------------------------- - * - * Tclzipfs_Unmount -- - * - * This procedure is invoked to unmount a given ZIP archive. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * A mounted ZIP archive file is unmounted, resources are free'd. - * - *------------------------------------------------------------------------- - */ - -int -Tclzipfs_Unmount(Tcl_Interp *interp, const char *zipname) -{ - char *realname; - ZipFile *zf; - ZipEntry *z, *znext; - Tcl_HashEntry *hPtr; - Tcl_DString ds; - int ret = TCL_OK, unmounted = 0; -#if HAS_DRIVES - int drive = 0; -#endif - - Tcl_DStringInit(&ds); -#if HAS_DRIVES - realname = AbsolutePath(zipname, &drive, &ds); -#else - realname = AbsolutePath(zipname, &ds); -#endif - WriteLock(); - if (!ZipFS.initialized) { - goto done; - } - hPtr = Tcl_FindHashEntry(&ZipFS.zipHash, realname); - if (hPtr == NULL) { - /* don't report error */ - goto done; - } - zf = (ZipFile *) Tcl_GetHashValue(hPtr); -#if HAS_DRIVES - if (drive != zf->mntdrv) { - /* don't report error */ - goto done; - } -#endif - if (zf->nopen > 0) { - if (interp != NULL) { - Tcl_SetObjResult(interp, - Tcl_NewStringObj("filesystem is busy", -1)); - } - ret = TCL_ERROR; - goto done; - } - Tcl_DeleteHashEntry(hPtr); - for (z = zf->entries; z; z = znext) { - znext = z->next; - hPtr = Tcl_FindHashEntry(&ZipFS.fileHash, z->name); - if (hPtr) { - Tcl_DeleteHashEntry(hPtr); - } - if (z->data != NULL) { - Tcl_Free((char *) z->data); - } - Tcl_Free((char *) z); - } - ZipFSCloseArchive(interp, zf); - Tcl_Free((char *) zf); - unmounted = 1; -done: - Unlock(); - Tcl_DStringFree(&ds); - if (unmounted) { - Tcl_FSMountsChanged(NULL); - } - return ret; -} - -/* - *------------------------------------------------------------------------- - * - * ZipFSMountObjCmd -- - * - * This procedure is invoked to process the "zipfs::mount" command. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * A ZIP archive file is mounted, resources are allocated. - * - *------------------------------------------------------------------------- - */ - -static int -ZipFSMountObjCmd(ClientData clientData, Tcl_Interp *interp, - int objc, Tcl_Obj *const objv[]) -{ - if (objc > 4) { - Tcl_WrongNumArgs(interp, 1, objv, - "?zipfile? ?mountpoint? ?password?"); - return TCL_ERROR; - } - return Tclzipfs_Mount(interp, (objc > 1) ? Tcl_GetString(objv[1]) : NULL, - (objc > 2) ? Tcl_GetString(objv[2]) : NULL, - (objc > 3) ? Tcl_GetString(objv[3]) : NULL); -} - -/* - *------------------------------------------------------------------------- - * - * ZipFSUnmountObjCmd -- - * - * This procedure is invoked to process the "zipfs::unmount" command. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * A mounted ZIP archive file is unmounted, resources are free'd. - * - *------------------------------------------------------------------------- - */ - -static int -ZipFSUnmountObjCmd(ClientData clientData, Tcl_Interp *interp, - int objc, Tcl_Obj *const objv[]) -{ - if (objc != 2) { - Tcl_WrongNumArgs(interp, 1, objv, "zipfile"); - return TCL_ERROR; - } - return Tclzipfs_Unmount(interp, Tcl_GetString(objv[1])); -} - -/* - *------------------------------------------------------------------------- - * - * ZipFSMkKeyObjCmd -- - * - * This procedure is invoked to process the "zipfs::mkkey" command. - * It produces a rotated password to be embedded into an image file. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * None. - * - *------------------------------------------------------------------------- - */ - -static int -ZipFSMkKeyObjCmd(ClientData clientData, Tcl_Interp *interp, - int objc, Tcl_Obj *const objv[]) -{ - int len, i = 0; - char *pw, pwbuf[264]; - - if (objc != 2) { - Tcl_WrongNumArgs(interp, 1, objv, "password"); - return TCL_ERROR; - } - pw = Tcl_GetString(objv[1]); - len = strlen(pw); - if (len == 0) { - return TCL_OK; - } - if ((len > 255) || (strchr(pw, 0xff) != NULL)) { - Tcl_SetObjResult(interp, - Tcl_NewStringObj("illegal password", -1)); - return TCL_ERROR; - } - while (len > 0) { - int ch = pw[len - 1]; - - pwbuf[i] = (ch & 0x0f) | pwrot[(ch >> 4) & 0x0f]; - i++; - len--; - } - pwbuf[i] = i; - ++i; - pwbuf[i++] = (char) ZIP_PASSWORD_END_SIG; - pwbuf[i++] = (char) (ZIP_PASSWORD_END_SIG >> 8); - pwbuf[i++] = (char) (ZIP_PASSWORD_END_SIG >> 16); - pwbuf[i++] = (char) (ZIP_PASSWORD_END_SIG >> 24); - pwbuf[i] = '\0'; - Tcl_AppendResult(interp, pwbuf, (char *) NULL); - return TCL_OK; -} - -/* - *------------------------------------------------------------------------- - * - * ZipAddFile -- - * - * This procedure is used by ZipFSMkZipOrImgCmd() to add a single - * file to the output ZIP archive file being written. A ZipEntry - * struct about the input file is added to the given fileHash table - * for later creation of the central ZIP directory. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * Input file is read and (compressed and) written to the output - * ZIP archive file. - * - *------------------------------------------------------------------------- - */ - -static int -ZipAddFile(Tcl_Interp *interp, const char *path, const char *name, - Tcl_Channel out, const char *passwd, - char *buf, int bufsize, Tcl_HashTable *fileHash) -{ - Tcl_Channel in; - Tcl_HashEntry *hPtr; - ZipEntry *z; - z_stream stream; - const char *zpath; - int nbyte, nbytecompr, len, crc, flush, pos[3], zpathlen, olen; - int mtime = 0, isNew, align = 0, cmeth; - unsigned long keys[3], keys0[3]; - char obuf[4096]; - - zpath = name; - while (zpath != NULL && zpath[0] == '/') { - zpath++; - } - if ((zpath == NULL) || (zpath[0] == '\0')) { - return TCL_OK; - } - zpathlen = strlen(zpath); - if (zpathlen + ZIP_CENTRAL_HEADER_LEN > bufsize) { - Tcl_AppendResult(interp, "path too long for \"", path, "\"", - (char *) NULL); - return TCL_ERROR; - } - in = Tcl_OpenFileChannel(interp, path, "r", 0); - if ((in == NULL) || - (Tcl_SetChannelOption(interp, in, "-translation", "binary") - != TCL_OK) || - (Tcl_SetChannelOption(interp, in, "-encoding", "binary") - != TCL_OK)) { -#if defined(_WIN32) || defined(_WIN64) - /* hopefully a directory */ - if (strcmp("permission denied", Tcl_PosixError(interp)) == 0) { - Tcl_Close(interp, in); - return TCL_OK; - } -#endif - Tcl_Close(interp, in); - return TCL_ERROR; - } else { - Tcl_Obj *pathObj = Tcl_NewStringObj(path, -1); - Tcl_StatBuf statBuf; - - Tcl_IncrRefCount(pathObj); - if (Tcl_FSStat(pathObj, &statBuf) != -1) { - mtime = statBuf.st_mtime; - } - Tcl_DecrRefCount(pathObj); - } - Tcl_ResetResult(interp); - crc = 0; - nbyte = nbytecompr = 0; - while ((len = Tcl_Read(in, buf, bufsize)) > 0) { - crc = crc32(crc, (unsigned char *) buf, len); - nbyte += len; - } - if (len == -1) { - if (nbyte == 0) { - if (strcmp("illegal operation on a directory", - Tcl_PosixError(interp)) == 0) { - Tcl_Close(interp, in); - return TCL_OK; - } - } - Tcl_AppendResult(interp, "read error on \"", path, "\"", - (char *) NULL); - Tcl_Close(interp, in); - return TCL_ERROR; - } - if (Tcl_Seek(in, 0, SEEK_SET) == -1) { - Tcl_AppendResult(interp, "seek error on \"", path, "\"", - (char *) NULL); - Tcl_Close(interp, in); - return TCL_ERROR; - } - pos[0] = Tcl_Tell(out); - memset(buf, '\0', ZIP_LOCAL_HEADER_LEN); - memcpy(buf + ZIP_LOCAL_HEADER_LEN, zpath, zpathlen); - len = zpathlen + ZIP_LOCAL_HEADER_LEN; - if (Tcl_Write(out, buf, len) != len) { -wrerr: - Tcl_AppendResult(interp, "write error", (char *) NULL); - Tcl_Close(interp, in); - return TCL_ERROR; - } - if ((len + pos[0]) & 3) { - char abuf[8]; - - /* - * Align payload to next 4-byte boundary using a dummy extra - * entry similar to the zipalign tool from Android's SDK. - */ - align = 4 + ((len + pos[0]) & 3); - zip_write_short(abuf, 0xffff); - zip_write_short(abuf + 2, align - 4); - zip_write_int(abuf + 4, 0x03020100); - if (Tcl_Write(out, abuf, align) != align) { - goto wrerr; - } - } - if (passwd != NULL) { - int i, ch, tmp; - unsigned char kvbuf[24]; - Tcl_Obj *ret; - - init_keys(passwd, keys, crc32tab); - for (i = 0; i < 12 - 2; i++) { - if (Tcl_EvalEx(interp, "expr int(rand() * 256) % 256", -1, 0) != TCL_OK) { - Tcl_AppendResult(interp, "PRNG error", (char *) NULL); - Tcl_Close(interp, in); - return TCL_ERROR; - } - ret = Tcl_GetObjResult(interp); - if (Tcl_GetIntFromObj(interp, ret, &ch) != TCL_OK) { - Tcl_Close(interp, in); - return TCL_ERROR; - } - kvbuf[i + 12] = (unsigned char) zencode(keys, crc32tab, ch, tmp); - } - Tcl_ResetResult(interp); - init_keys(passwd, keys, crc32tab); - for (i = 0; i < 12 - 2; i++) { - kvbuf[i] = (unsigned char) zencode(keys, crc32tab, - kvbuf[i + 12], tmp); - } - kvbuf[i++] = (unsigned char) zencode(keys, crc32tab, crc >> 16, tmp); - kvbuf[i++] = (unsigned char) zencode(keys, crc32tab, crc >> 24, tmp); - len = Tcl_Write(out, (char *) kvbuf, 12); - memset(kvbuf, 0, 24); - if (len != 12) { - Tcl_AppendResult(interp, "write error", (char *) NULL); - Tcl_Close(interp, in); - return TCL_ERROR; - } - memcpy(keys0, keys, sizeof (keys0)); - nbytecompr += 12; - } - Tcl_Flush(out); - pos[2] = Tcl_Tell(out); - cmeth = ZIP_COMPMETH_DEFLATED; - memset(&stream, 0, sizeof (stream)); - stream.zalloc = Z_NULL; - stream.zfree = Z_NULL; - stream.opaque = Z_NULL; - if (deflateInit2(&stream, 9, Z_DEFLATED, -15, 8, Z_DEFAULT_STRATEGY) - != Z_OK) { - Tcl_AppendResult(interp, "compression init error on \"", path, "\"", - (char *) NULL); - Tcl_Close(interp, in); - return TCL_ERROR; - } - do { - len = Tcl_Read(in, buf, bufsize); - if (len == -1) { - Tcl_AppendResult(interp, "read error on \"", path, "\"", - (char *) NULL); - deflateEnd(&stream); - Tcl_Close(interp, in); - return TCL_ERROR; - } - stream.avail_in = len; - stream.next_in = (unsigned char *) buf; - flush = Tcl_Eof(in) ? Z_FINISH : Z_NO_FLUSH; - do { - stream.avail_out = sizeof (obuf); - stream.next_out = (unsigned char *) obuf; - len = deflate(&stream, flush); - if (len == Z_STREAM_ERROR) { - Tcl_AppendResult(interp, "deflate error on \"", path, "\"", - (char *) NULL); - deflateEnd(&stream); - Tcl_Close(interp, in); - return TCL_ERROR; - } - olen = sizeof (obuf) - stream.avail_out; - if (passwd != NULL) { - int i, tmp; - - for (i = 0; i < olen; i++) { - obuf[i] = (char) zencode(keys, crc32tab, obuf[i], tmp); - } - } - if (olen && (Tcl_Write(out, obuf, olen) != olen)) { - Tcl_AppendResult(interp, "write error", (char *) NULL); - deflateEnd(&stream); - Tcl_Close(interp, in); - return TCL_ERROR; - } - nbytecompr += olen; - } while (stream.avail_out == 0); - } while (flush != Z_FINISH); - deflateEnd(&stream); - Tcl_Flush(out); - pos[1] = Tcl_Tell(out); - if (nbyte - nbytecompr <= 0) { - /* - * Compressed file larger than input, - * write it again uncompressed. - */ - if ((int) Tcl_Seek(in, 0, SEEK_SET) != 0) { - goto seekErr; - } - if ((int) Tcl_Seek(out, pos[2], SEEK_SET) != pos[2]) { -seekErr: - Tcl_Close(interp, in); - Tcl_AppendResult(interp, "seek error", (char *) NULL); - return TCL_ERROR; - } - nbytecompr = (passwd != NULL) ? 12 : 0; - while (1) { - len = Tcl_Read(in, buf, bufsize); - if (len == -1) { - Tcl_AppendResult(interp, "read error on \"", path, "\"", - (char *) NULL); - Tcl_Close(interp, in); - return TCL_ERROR; - } else if (len == 0) { - break; - } - if (passwd != NULL) { - int i, tmp; - - for (i = 0; i < len; i++) { - buf[i] = (char) zencode(keys0, crc32tab, buf[i], tmp); - } - } - if (Tcl_Write(out, buf, len) != len) { - Tcl_AppendResult(interp, "write error", (char *) NULL); - Tcl_Close(interp, in); - return TCL_ERROR; - } - nbytecompr += len; - } - cmeth = ZIP_COMPMETH_STORED; - Tcl_Flush(out); - pos[1] = Tcl_Tell(out); - Tcl_TruncateChannel(out, pos[1]); - } - Tcl_Close(interp, in); - - z = (ZipEntry *) Tcl_Alloc(sizeof (*z)); - z->name = NULL; - z->tnext = NULL; - z->depth = 0; - z->zipfile = NULL; - z->isdir = 0; - z->isenc = (passwd != NULL) ? 1 : 0; - z->offset = pos[0]; - z->crc32 = crc; - z->timestamp = mtime; - z->nbyte = nbyte; - z->nbytecompr = nbytecompr; - z->cmeth = cmeth; - z->data = NULL; - hPtr = Tcl_CreateHashEntry(fileHash, zpath, &isNew); - if (!isNew) { - Tcl_AppendResult(interp, "non-unique path name \"", path, "\"", - (char *) NULL); - Tcl_Free((char *) z); - return TCL_ERROR; - } else { - Tcl_SetHashValue(hPtr, (ClientData) z); - z->name = Tcl_GetHashKey(fileHash, hPtr); - z->next = NULL; - } - - /* - * Write final local header information. - */ - zip_write_int(buf + ZIP_LOCAL_SIG_OFFS, ZIP_LOCAL_HEADER_SIG); - zip_write_short(buf + ZIP_LOCAL_VERSION_OFFS, ZIP_MIN_VERSION); - zip_write_short(buf + ZIP_LOCAL_FLAGS_OFFS, z->isenc); - zip_write_short(buf + ZIP_LOCAL_COMPMETH_OFFS, z->cmeth); - zip_write_short(buf + ZIP_LOCAL_MTIME_OFFS, ToDosTime(z->timestamp)); - zip_write_short(buf + ZIP_LOCAL_MDATE_OFFS, ToDosDate(z->timestamp)); - zip_write_int(buf + ZIP_LOCAL_CRC32_OFFS, z->crc32); - zip_write_int(buf + ZIP_LOCAL_COMPLEN_OFFS, z->nbytecompr); - zip_write_int(buf + ZIP_LOCAL_UNCOMPLEN_OFFS, z->nbyte); - zip_write_short(buf + ZIP_LOCAL_PATHLEN_OFFS, zpathlen); - zip_write_short(buf + ZIP_LOCAL_EXTRALEN_OFFS, align); - if ((int) Tcl_Seek(out, pos[0], SEEK_SET) != pos[0]) { - Tcl_DeleteHashEntry(hPtr); - Tcl_Free((char *) z); - Tcl_AppendResult(interp, "seek error", (char *) NULL); - return TCL_ERROR; - } - if (Tcl_Write(out, buf, ZIP_LOCAL_HEADER_LEN) != ZIP_LOCAL_HEADER_LEN) { - Tcl_DeleteHashEntry(hPtr); - Tcl_Free((char *) z); - Tcl_AppendResult(interp, "write error", (char *) NULL); - return TCL_ERROR; - } - Tcl_Flush(out); - if ((int) Tcl_Seek(out, pos[1], SEEK_SET) != pos[1]) { - Tcl_DeleteHashEntry(hPtr); - Tcl_Free((char *) z); - Tcl_AppendResult(interp, "seek error", (char *) NULL); - return TCL_ERROR; - } - return TCL_OK; -} - -/* - *------------------------------------------------------------------------- - * - * ZipFSMkZipOrImgObjCmd -- - * - * This procedure is creates a new ZIP archive file or image file - * given output filename, input directory of files to be archived, - * optional password, and optional image to be prepended to the - * output ZIP archive file. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * A new ZIP archive file or image file is written. - * - *------------------------------------------------------------------------- - */ - -static int -ZipFSMkZipOrImgObjCmd(ClientData clientData, Tcl_Interp *interp, - int isImg, int isList, int objc, Tcl_Obj *const objv[]) -{ - Tcl_Channel out; - int len = 0, pwlen = 0, slen = 0, i, count, ret = TCL_ERROR, lobjc, pos[3]; - Tcl_Obj **lobjv, *list = NULL; - ZipEntry *z; - Tcl_HashEntry *hPtr; - Tcl_HashSearch search; - Tcl_HashTable fileHash; - char *strip = NULL, *pw = NULL, pwbuf[264], buf[4096]; - - if (isList) { - if ((objc < 3) || (objc > (isImg ? 5 : 4))) { - Tcl_WrongNumArgs(interp, 1, objv, isImg ? - "outfile inlist ?password infile?" : - "outfile inlist ?password?"); - return TCL_ERROR; - } - } else { - if ((objc < 3) || (objc > (isImg ? 6 : 5))) { - Tcl_WrongNumArgs(interp, 1, objv, isImg ? - "outfile indir ?strip? ?password? ?infile?" : - "outfile indir ?strip? ?password?"); - return TCL_ERROR; - } - } - pwbuf[0] = 0; - if (objc > (isList ? 3 : 4)) { - pw = Tcl_GetString(objv[isList ? 3 : 4]); - pwlen = strlen(pw); - if ((pwlen > 255) || (strchr(pw, 0xff) != NULL)) { - Tcl_SetObjResult(interp, - Tcl_NewStringObj("illegal password", -1)); - return TCL_ERROR; - } - } - if (isList) { - list = objv[2]; - Tcl_IncrRefCount(list); - } else { - Tcl_Obj *cmd[3]; - - cmd[1] = Tcl_NewStringObj("::zipfs::find", -1); - cmd[2] = objv[2]; - cmd[0] = Tcl_NewListObj(2, cmd + 1); - Tcl_IncrRefCount(cmd[0]); - if (Tcl_EvalObjEx(interp, cmd[0], TCL_EVAL_DIRECT) != TCL_OK) { - Tcl_DecrRefCount(cmd[0]); - return TCL_ERROR; - } - Tcl_DecrRefCount(cmd[0]); - list = Tcl_GetObjResult(interp); - Tcl_IncrRefCount(list); - } - if (Tcl_ListObjGetElements(interp, list, &lobjc, &lobjv) != TCL_OK) { - Tcl_DecrRefCount(list); - return TCL_ERROR; - } - if (isList && (lobjc % 2)) { - Tcl_DecrRefCount(list); - Tcl_SetObjResult(interp, - Tcl_NewStringObj("need even number of elements", -1)); - return TCL_ERROR; - } - if (lobjc == 0) { - Tcl_DecrRefCount(list); - Tcl_SetObjResult(interp, Tcl_NewStringObj("empty archive", -1)); - return TCL_ERROR; - } - out = Tcl_OpenFileChannel(interp, Tcl_GetString(objv[1]), "w", 0755); - if ((out == NULL) || - (Tcl_SetChannelOption(interp, out, "-translation", "binary") - != TCL_OK) || - (Tcl_SetChannelOption(interp, out, "-encoding", "binary") - != TCL_OK)) { - Tcl_DecrRefCount(list); - Tcl_Close(interp, out); - return TCL_ERROR; - } - if (isImg) { - ZipFile zf0; - const char *imgName; - - if (isList) { - imgName = (objc > 4) ? Tcl_GetString(objv[4]) : - Tcl_GetNameOfExecutable(); - } else { - imgName = (objc > 5) ? Tcl_GetString(objv[5]) : - Tcl_GetNameOfExecutable(); - } - if (ZipFSOpenArchive(interp, imgName, 0, &zf0) != TCL_OK) { - Tcl_DecrRefCount(list); - Tcl_Close(interp, out); - return TCL_ERROR; - } - if ((pw != NULL) && pwlen) { - i = 0; - len = pwlen; - while (len > 0) { - int ch = pw[len - 1]; - - pwbuf[i] = (ch & 0x0f) | pwrot[(ch >> 4) & 0x0f]; - i++; - len--; - } - pwbuf[i] = i; - ++i; - pwbuf[i++] = (char) ZIP_PASSWORD_END_SIG; - pwbuf[i++] = (char) (ZIP_PASSWORD_END_SIG >> 8); - pwbuf[i++] = (char) (ZIP_PASSWORD_END_SIG >> 16); - pwbuf[i++] = (char) (ZIP_PASSWORD_END_SIG >> 24); - pwbuf[i] = '\0'; - } - i = Tcl_Write(out, (char *) zf0.data, zf0.baseoffsp); - if (i != zf0.baseoffsp) { - Tcl_DecrRefCount(list); - Tcl_SetObjResult(interp, Tcl_NewStringObj("write error", -1)); - Tcl_Close(interp, out); - ZipFSCloseArchive(interp, &zf0); - return TCL_ERROR; - } - ZipFSCloseArchive(interp, &zf0); - len = strlen(pwbuf); - if (len > 0) { - i = Tcl_Write(out, pwbuf, len); - if (i != len) { - Tcl_DecrRefCount(list); - Tcl_SetObjResult(interp, Tcl_NewStringObj("write error", -1)); - Tcl_Close(interp, out); - return TCL_ERROR; - } - } - memset(pwbuf, 0, sizeof (pwbuf)); - Tcl_Flush(out); - } - Tcl_InitHashTable(&fileHash, TCL_STRING_KEYS); - pos[0] = Tcl_Tell(out); - if (!isList && (objc > 3)) { - strip = Tcl_GetString(objv[3]); - slen = strlen(strip); - } - for (i = 0; i < lobjc; i += (isList ? 2 : 1)) { - const char *path, *name; - - path = Tcl_GetString(lobjv[i]); - if (isList) { - name = Tcl_GetString(lobjv[i + 1]); - } else { - name = path; - if (slen > 0) { - len = strlen(name); - if ((len <= slen) || (strncmp(strip, name, slen) != 0)) { - continue; - } - name += slen; - } - } - while (name[0] == '/') { - ++name; - } - if (name[0] == '\0') { - continue; - } - if (ZipAddFile(interp, path, name, out, pw, buf, sizeof (buf), - &fileHash) != TCL_OK) { - goto done; - } - } - pos[1] = Tcl_Tell(out); - count = 0; - for (i = 0; i < lobjc; i += (isList ? 2 : 1)) { - const char *path, *name; - - path = Tcl_GetString(lobjv[i]); - if (isList) { - name = Tcl_GetString(lobjv[i + 1]); - } else { - name = path; - if (slen > 0) { - len = strlen(name); - if ((len <= slen) || (strncmp(strip, name, slen) != 0)) { - continue; - } - name += slen; - } - } - while (name[0] == '/') { - ++name; - } - if (name[0] == '\0') { - continue; - } - hPtr = Tcl_FindHashEntry(&fileHash, name); - if (hPtr == NULL) { - continue; - } - z = (ZipEntry *) Tcl_GetHashValue(hPtr); - len = strlen(z->name); - zip_write_int(buf + ZIP_CENTRAL_SIG_OFFS, ZIP_CENTRAL_HEADER_SIG); - zip_write_short(buf + ZIP_CENTRAL_VERSIONMADE_OFFS, ZIP_MIN_VERSION); - zip_write_short(buf + ZIP_CENTRAL_VERSION_OFFS, ZIP_MIN_VERSION); - zip_write_short(buf + ZIP_CENTRAL_FLAGS_OFFS, z->isenc ? 1 : 0); - zip_write_short(buf + ZIP_CENTRAL_COMPMETH_OFFS, z->cmeth); - zip_write_short(buf + ZIP_CENTRAL_MTIME_OFFS, ToDosTime(z->timestamp)); - zip_write_short(buf + ZIP_CENTRAL_MDATE_OFFS, ToDosDate(z->timestamp)); - zip_write_int(buf + ZIP_CENTRAL_CRC32_OFFS, z->crc32); - zip_write_int(buf + ZIP_CENTRAL_COMPLEN_OFFS, z->nbytecompr); - zip_write_int(buf + ZIP_CENTRAL_UNCOMPLEN_OFFS, z->nbyte); - zip_write_short(buf + ZIP_CENTRAL_PATHLEN_OFFS, len); - zip_write_short(buf + ZIP_CENTRAL_EXTRALEN_OFFS, 0); - zip_write_short(buf + ZIP_CENTRAL_FCOMMENTLEN_OFFS, 0); - zip_write_short(buf + ZIP_CENTRAL_DISKFILE_OFFS, 0); - zip_write_short(buf + ZIP_CENTRAL_IATTR_OFFS, 0); - zip_write_int(buf + ZIP_CENTRAL_EATTR_OFFS, 0); - zip_write_int(buf + ZIP_CENTRAL_LOCALHDR_OFFS, z->offset - pos[0]); - if ((Tcl_Write(out, buf, ZIP_CENTRAL_HEADER_LEN) != - ZIP_CENTRAL_HEADER_LEN) || - (Tcl_Write(out, z->name, len) != len)) { - Tcl_SetObjResult(interp, Tcl_NewStringObj("write error", -1)); - goto done; - } - count++; - } - Tcl_Flush(out); - pos[2] = Tcl_Tell(out); - zip_write_int(buf + ZIP_CENTRAL_END_SIG_OFFS, ZIP_CENTRAL_END_SIG); - zip_write_short(buf + ZIP_CENTRAL_DISKNO_OFFS, 0); - zip_write_short(buf + ZIP_CENTRAL_DISKDIR_OFFS, 0); - zip_write_short(buf + ZIP_CENTRAL_ENTS_OFFS, count); - zip_write_short(buf + ZIP_CENTRAL_TOTALENTS_OFFS, count); - zip_write_int(buf + ZIP_CENTRAL_DIRSIZE_OFFS, pos[2] - pos[1]); - zip_write_int(buf + ZIP_CENTRAL_DIRSTART_OFFS, pos[1] - pos[0]); - zip_write_short(buf + ZIP_CENTRAL_COMMENTLEN_OFFS, 0); - if (Tcl_Write(out, buf, ZIP_CENTRAL_END_LEN) != ZIP_CENTRAL_END_LEN) { - Tcl_SetObjResult(interp, Tcl_NewStringObj("write error", -1)); - goto done; - } - Tcl_Flush(out); - ret = TCL_OK; -done: - if (ret == TCL_OK) { - ret = Tcl_Close(interp, out); - } else { - Tcl_Close(interp, out); - } - Tcl_DecrRefCount(list); - hPtr = Tcl_FirstHashEntry(&fileHash, &search); - while (hPtr != NULL) { - z = (ZipEntry *) Tcl_GetHashValue(hPtr); - Tcl_Free((char *) z); - Tcl_DeleteHashEntry(hPtr); - hPtr = Tcl_FirstHashEntry(&fileHash, &search); - } - Tcl_DeleteHashTable(&fileHash); - return ret; -} - -/* - *------------------------------------------------------------------------- - * - * ZipFSMkZipObjCmd -- - * - * This procedure is invoked to process the "zipfs::mkzip" command. - * See description of ZipFSMkZipOrImgCmd(). - * - * Results: - * A standard Tcl result. - * - * Side effects: - * See description of ZipFSMkZipOrImgCmd(). - * - *------------------------------------------------------------------------- - */ - -static int -ZipFSMkZipObjCmd(ClientData clientData, Tcl_Interp *interp, - int objc, Tcl_Obj *const objv[]) -{ - return ZipFSMkZipOrImgObjCmd(clientData, interp, 0, 0, objc, objv); -} - -static int -ZipFSLMkZipObjCmd(ClientData clientData, Tcl_Interp *interp, - int objc, Tcl_Obj *const objv[]) -{ - return ZipFSMkZipOrImgObjCmd(clientData, interp, 0, 1, objc, objv); -} - -/* - *------------------------------------------------------------------------- - * - * ZipFSMkImgObjCmd -- - * - * This procedure is invoked to process the "zipfs::mkimg" command. - * See description of ZipFSMkZipOrImgCmd(). - * - * Results: - * A standard Tcl result. - * - * Side effects: - * See description of ZipFSMkZipOrImgCmd(). - * - *------------------------------------------------------------------------- - */ - -static int -ZipFSMkImgObjCmd(ClientData clientData, Tcl_Interp *interp, - int objc, Tcl_Obj *const objv[]) -{ - return ZipFSMkZipOrImgObjCmd(clientData, interp, 1, 0, objc, objv); -} - -static int -ZipFSLMkImgObjCmd(ClientData clientData, Tcl_Interp *interp, - int objc, Tcl_Obj *const objv[]) -{ - return ZipFSMkZipOrImgObjCmd(clientData, interp, 1, 1, objc, objv); -} - -/* - *------------------------------------------------------------------------- - * - * ZipFSExistsObjCmd -- - * - * This procedure is invoked to process the "zipfs::exists" command. - * It tests for the existence of a file in the ZIP filesystem and - * places a boolean into the interp's result. - * - * Results: - * Always TCL_OK. - * - * Side effects: - * None. - * - *------------------------------------------------------------------------- - */ - -static int -ZipFSExistsObjCmd(ClientData clientData, Tcl_Interp *interp, - int objc, Tcl_Obj *const objv[]) -{ - char *filename; - int exists; - - if (objc != 2) { - Tcl_WrongNumArgs(interp, 1, objv, "filename"); - return TCL_ERROR; - } - filename = Tcl_GetStringFromObj(objv[1], 0); - ReadLock(); - exists = ZipFSLookup(filename) != NULL; - Unlock(); - Tcl_SetBooleanObj(Tcl_GetObjResult(interp), exists); - return TCL_OK; -} - -/* - *------------------------------------------------------------------------- - * - * ZipFSInfoObjCmd -- - * - * This procedure is invoked to process the "zipfs::info" command. - * On success, it returns a Tcl list made up of name of ZIP archive - * file, size uncompressed, size compressed, and archive offset of - * a file in the ZIP filesystem. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * None. - * - *------------------------------------------------------------------------- - */ - -static int -ZipFSInfoObjCmd(ClientData clientData, Tcl_Interp *interp, - int objc, Tcl_Obj *const objv[]) -{ - char *filename; - ZipEntry *z; - - if (objc != 2) { - Tcl_WrongNumArgs(interp, 1, objv, "filename"); - return TCL_ERROR; - } - filename = Tcl_GetStringFromObj(objv[1], 0); - ReadLock(); - z = ZipFSLookup(filename); - if (z != NULL) { - Tcl_Obj *result = Tcl_GetObjResult(interp); - - Tcl_ListObjAppendElement(interp, result, - Tcl_NewStringObj(z->zipfile->name, -1)); - Tcl_ListObjAppendElement(interp, result, Tcl_NewIntObj(z->nbyte)); - Tcl_ListObjAppendElement(interp, result, Tcl_NewIntObj(z->nbytecompr)); - Tcl_ListObjAppendElement(interp, result, Tcl_NewIntObj(z->offset)); - } - Unlock(); - return TCL_OK; -} - -/* - *------------------------------------------------------------------------- - * - * ZipFSListObjCmd -- - * - * This procedure is invoked to process the "zipfs::list" command. - * On success, it returns a Tcl list of files of the ZIP filesystem - * which match a search pattern (glob or regexp). - * - * Results: - * A standard Tcl result. - * - * Side effects: - * None. - * - *------------------------------------------------------------------------- - */ - -static int -ZipFSListObjCmd(ClientData clientData, Tcl_Interp *interp, - int objc, Tcl_Obj *const objv[]) -{ - char *pattern = NULL; - Tcl_RegExp regexp = NULL; - Tcl_HashEntry *hPtr; - Tcl_HashSearch search; - Tcl_Obj *result = Tcl_GetObjResult(interp); - - if (objc > 3) { - Tcl_WrongNumArgs(interp, 1, objv, "?(-glob|-regexp)? ?pattern?"); - return TCL_ERROR; - } - if (objc == 3) { - int n; - char *what = Tcl_GetStringFromObj(objv[1], &n); - - if ((n >= 2) && (strncmp(what, "-glob", n) == 0)) { - pattern = Tcl_GetString(objv[2]); - } else if ((n >= 2) && (strncmp(what, "-regexp", n) == 0)) { - regexp = Tcl_RegExpCompile(interp, Tcl_GetString(objv[2])); - if (regexp == NULL) { - return TCL_ERROR; - } - } else { - Tcl_AppendResult(interp, "unknown option \"", what, - "\"", (char *) NULL); - return TCL_ERROR; - } - } else if (objc == 2) { - pattern = Tcl_GetStringFromObj(objv[1], 0); - } - ReadLock(); - if (pattern != NULL) { - for (hPtr = Tcl_FirstHashEntry(&ZipFS.fileHash, &search); - hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) { - ZipEntry *z = (ZipEntry *) Tcl_GetHashValue(hPtr); - - if (Tcl_StringMatch(z->name, pattern)) { - Tcl_ListObjAppendElement(interp, result, - Tcl_NewStringObj(z->name, -1)); - } - } - } else if (regexp != NULL) { - for (hPtr = Tcl_FirstHashEntry(&ZipFS.fileHash, &search); - hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) { - ZipEntry *z = (ZipEntry *) Tcl_GetHashValue(hPtr); - - if (Tcl_RegExpExec(interp, regexp, z->name, z->name)) { - Tcl_ListObjAppendElement(interp, result, - Tcl_NewStringObj(z->name, -1)); - } - } - } else { - for (hPtr = Tcl_FirstHashEntry(&ZipFS.fileHash, &search); - hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) { - ZipEntry *z = (ZipEntry *) Tcl_GetHashValue(hPtr); - - Tcl_ListObjAppendElement(interp, result, - Tcl_NewStringObj(z->name, -1)); - } - } - Unlock(); - return TCL_OK; -} - -/* - *------------------------------------------------------------------------- - * - * ZipChannelClose -- - * - * This function is called to close a channel. - * - * Results: - * Always TCL_OK. - * - * Side effects: - * Resources are free'd. - * - *------------------------------------------------------------------------- - */ - -static int -ZipChannelClose(ClientData instanceData, Tcl_Interp *interp) -{ - ZipChannel *info = (ZipChannel *) instanceData; - - if (info->iscompr && (info->ubuf != NULL)) { - Tcl_Free((char *) info->ubuf); - info->ubuf = NULL; - } - if (info->isenc) { - info->isenc = 0; - memset(info->keys, 0, sizeof (info->keys)); - } - if (info->iswr) { - ZipEntry *z = info->zipentry; - unsigned char *newdata; - - newdata = (unsigned char *) - Tcl_AttemptRealloc((char *) info->ubuf, info->nread); - if (newdata != NULL) { - if (z->data != NULL) { - Tcl_Free((char *) z->data); - } - z->data = newdata; - z->nbyte = z->nbytecompr = info->nbyte; - z->cmeth = ZIP_COMPMETH_STORED; - z->timestamp = time(NULL); - z->isdir = 0; - z->isenc = 0; - z->offset = 0; - z->crc32 = 0; - } else { - Tcl_Free((char *) info->ubuf); - } - } - WriteLock(); - info->zipfile->nopen--; - Unlock(); - Tcl_Free((char *) info); - return TCL_OK; -} - -/* - *------------------------------------------------------------------------- - * - * ZipChannelRead -- - * - * This function is called to read data from channel. - * - * Results: - * Number of bytes read or -1 on error with error number set. - * - * Side effects: - * Data is read and file pointer is advanced. - * - *------------------------------------------------------------------------- - */ - -static int -ZipChannelRead(ClientData instanceData, char *buf, int toRead, int *errloc) -{ - ZipChannel *info = (ZipChannel *) instanceData; - unsigned long nextpos; - - if (info->isdir) { - *errloc = EISDIR; - return -1; - } - nextpos = info->nread + toRead; - if (nextpos > info->nbyte) { - toRead = info->nbyte - info->nread; - nextpos = info->nbyte; - } - if (toRead == 0) { - return 0; - } - if (info->isenc) { - int i, ch; - - for (i = 0; i < toRead; i++) { - ch = info->ubuf[i + info->nread]; - buf[i] = zdecode(info->keys, crc32tab, ch); - } - } else { - memcpy(buf, info->ubuf + info->nread, toRead); - } - info->nread = nextpos; - *errloc = 0; - return toRead; -} - -/* - *------------------------------------------------------------------------- - * - * ZipChannelWrite -- - * - * This function is called to write data into channel. - * - * Results: - * Number of bytes written or -1 on error with error number set. - * - * Side effects: - * Data is written and file pointer is advanced. - * - *------------------------------------------------------------------------- - */ - -static int -ZipChannelWrite(ClientData instanceData, const char *buf, - int toWrite, int *errloc) -{ - ZipChannel *info = (ZipChannel *) instanceData; - unsigned long nextpos; - - if (!info->iswr) { - *errloc = EINVAL; - return -1; - } - nextpos = info->nread + toWrite; - if (nextpos > info->nmax) { - toWrite = info->nmax - info->nread; - nextpos = info->nmax; - } - if (toWrite == 0) { - return 0; - } - memcpy(info->ubuf + info->nread, buf, toWrite); - info->nread = nextpos; - if (info->nread > info->nbyte) { - info->nbyte = info->nread; - } - *errloc = 0; - return toWrite; -} - -/* - *------------------------------------------------------------------------- - * - * ZipChannelSeek -- - * - * This function is called to position file pointer of channel. - * - * Results: - * New file position or -1 on error with error number set. - * - * Side effects: - * File pointer is repositioned according to offset and mode. - * - *------------------------------------------------------------------------- - */ - -static int -ZipChannelSeek(ClientData instanceData, long offset, int mode, int *errloc) -{ - ZipChannel *info = (ZipChannel *) instanceData; - - if (info->isdir) { - *errloc = EINVAL; - return -1; - } - switch (mode) { - case SEEK_CUR: - offset += info->nread; - break; - case SEEK_END: - offset += info->nbyte; - break; - case SEEK_SET: - break; - default: - *errloc = EINVAL; - return -1; - } - if (offset < 0) { - *errloc = EINVAL; - return -1; - } - if (info->iswr) { - if ((unsigned long) offset > info->nmax) { - *errloc = EINVAL; - return -1; - } - if ((unsigned long) offset > info->nbyte) { - info->nbyte = offset; - } - } else if ((unsigned long) offset > info->nbyte) { - *errloc = EINVAL; - return -1; - } - info->nread = (unsigned long) offset; - return info->nread; -} - -/* - *------------------------------------------------------------------------- - * - * ZipChannelWatchChannel -- - * - * This function is called for event notifications on channel. - * - * Results: - * None. - * - * Side effects: - * None. - * - *------------------------------------------------------------------------- - */ - -static void -ZipChannelWatchChannel(ClientData instanceData, int mask) -{ - return; -} - -/* - *------------------------------------------------------------------------- - * - * ZipChannelGetFile -- - * - * This function is called to retrieve OS handle for channel. - * - * Results: - * Always TCL_ERROR since there's never an OS handle for a - * file within a ZIP archive. - * - * Side effects: - * None. - * - *------------------------------------------------------------------------- - */ - -static int -ZipChannelGetFile(ClientData instanceData, int direction, - ClientData *handlePtr) -{ - return TCL_ERROR; -} - -/* - * The channel type/driver definition used for ZIP archive members. - */ - -static Tcl_ChannelType ZipChannelType = { - "zip", /* Type name. */ -#ifdef TCL_CHANNEL_VERSION_4 - TCL_CHANNEL_VERSION_4, - ZipChannelClose, /* Close channel, clean instance data */ - ZipChannelRead, /* Handle read request */ - ZipChannelWrite, /* Handle write request */ - ZipChannelSeek, /* Move location of access point, NULL'able */ - NULL, /* Set options, NULL'able */ - NULL, /* Get options, NULL'able */ - ZipChannelWatchChannel, /* Initialize notifier */ - ZipChannelGetFile, /* Get OS handle from the channel */ - NULL, /* 2nd version of close channel, NULL'able */ - NULL, /* Set blocking mode for raw channel, NULL'able */ - NULL, /* Function to flush channel, NULL'able */ - NULL, /* Function to handle event, NULL'able */ - NULL, /* Wide seek function, NULL'able */ - NULL, /* Thread action function, NULL'able */ -#else - NULL, /* Set blocking/nonblocking behaviour, NULL'able */ - ZipChannelClose, /* Close channel, clean instance data */ - ZipChannelRead, /* Handle read request */ - ZipChannelWrite, /* Handle write request */ - ZipChannelSeek, /* Move location of access point, NULL'able */ - NULL, /* Set options, NULL'able */ - NULL, /* Get options, NULL'able */ - ZipChannelWatchChannel, /* Initialize notifier */ - ZipChannelGetFile, /* Get OS handle from the channel */ -#endif -}; - -/* - *------------------------------------------------------------------------- - * - * ZipChannelOpen -- - * - * This function opens a Tcl_Channel on a file from a mounted ZIP - * archive according to given open mode. - * - * Results: - * Tcl_Channel on success, or NULL on error. - * - * Side effects: - * Memory is allocated, the file from the ZIP archive is uncompressed. - * - *------------------------------------------------------------------------- - */ - -static Tcl_Channel -ZipChannelOpen(Tcl_Interp *interp, char *filename, int mode, int permissions) -{ - ZipEntry *z; - ZipChannel *info; - int i, ch, trunc, wr, flags = 0; - char cname[128]; - - if ((mode & O_APPEND) || - ((ZipFS.wrmax <= 0) && (mode & (O_WRONLY | O_RDWR)))) { - if (interp != NULL) { - Tcl_SetObjResult(interp, Tcl_NewStringObj("unsupported open mode", -1)); - } - return NULL; - } - WriteLock(); - z = ZipFSLookup(filename); - if (z == NULL) { - if (interp != NULL) { - Tcl_SetObjResult(interp, Tcl_NewStringObj("file not found", -1)); - } - goto error; - } - trunc = (mode & O_TRUNC) != 0; - wr = (mode & (O_WRONLY | O_RDWR)) != 0; - if ((z->cmeth != ZIP_COMPMETH_STORED) && - (z->cmeth != ZIP_COMPMETH_DEFLATED)) { - if (interp != NULL) { - Tcl_SetObjResult(interp, - Tcl_NewStringObj("unsupported compression method", -1)); - } - goto error; - } - if (wr && z->isdir) { - if (interp != NULL) { - Tcl_SetObjResult(interp, - Tcl_NewStringObj("unsupported file type", -1)); - } - goto error; - } - if (!trunc) { - flags |= TCL_READABLE; - if (z->isenc && (z->zipfile->pwbuf[0] == 0)) { - if (interp != NULL) { - Tcl_SetObjResult(interp, - Tcl_NewStringObj("decryption failed", -1)); - } - goto error; - } else if (wr && (z->data == NULL) && (z->nbyte > ZipFS.wrmax)) { - if (interp != NULL) { - Tcl_SetObjResult(interp, - Tcl_NewStringObj("file too large", -1)); - } - goto error; - } - } else { - flags = TCL_WRITABLE; - } - info = (ZipChannel *) Tcl_AttemptAlloc(sizeof (*info)); - if (info == NULL) { - if (interp != NULL) { - Tcl_SetObjResult(interp, Tcl_NewStringObj("out of memory", -1)); - } - goto error; - } - info->zipfile = z->zipfile; - info->zipentry = z; - info->nread = 0; - if (wr) { - flags |= TCL_WRITABLE; - info->iswr = 1; - info->isdir = 0; - info->nmax = ZipFS.wrmax; - info->iscompr = 0; - info->isenc = 0; - info->ubuf = (unsigned char *) Tcl_AttemptAlloc(info->nmax); - if (info->ubuf == NULL) { -merror0: - if (info->ubuf != NULL) { - Tcl_Free((char *) info->ubuf); - } - Tcl_Free((char *) info); - if (interp != NULL) { - Tcl_SetObjResult(interp, - Tcl_NewStringObj("out of memory", -1)); - } - goto error; - } - memset(info->ubuf, 0, info->nmax); - if (trunc) { - info->nbyte = 0; - } else { - if (z->data != NULL) { - unsigned int j = z->nbyte; - - if (j > info->nmax) { - j = info->nmax; - } - memcpy(info->ubuf, z->data, j); - info->nbyte = j; - } else { - unsigned char *zbuf = z->zipfile->data + z->offset; - - if (z->isenc) { - int len = z->zipfile->pwbuf[0]; - char pwbuf[260]; - - for (i = 0; i < len; i++) { - ch = z->zipfile->pwbuf[len - i]; - pwbuf[i] = (ch & 0x0f) | pwrot[(ch >> 4) & 0x0f]; - } - pwbuf[i] = '\0'; - init_keys(pwbuf, info->keys, crc32tab); - memset(pwbuf, 0, sizeof (pwbuf)); - for (i = 0; i < 12; i++) { - ch = info->ubuf[i]; - zdecode(info->keys, crc32tab, ch); - } - zbuf += i; - } - if (z->cmeth == ZIP_COMPMETH_DEFLATED) { - z_stream stream; - int err; - unsigned char *cbuf = NULL; - - memset(&stream, 0, sizeof (stream)); - stream.zalloc = Z_NULL; - stream.zfree = Z_NULL; - stream.opaque = Z_NULL; - stream.avail_in = z->nbytecompr; - if (z->isenc) { - unsigned int j; - - stream.avail_in -= 12; - cbuf = (unsigned char *) - Tcl_AttemptAlloc(stream.avail_in); - if (cbuf == NULL) { - goto merror0; - } - for (j = 0; j < stream.avail_in; j++) { - ch = info->ubuf[j]; - cbuf[j] = zdecode(info->keys, crc32tab, ch); - } - stream.next_in = cbuf; - } else { - stream.next_in = zbuf; - } - stream.next_out = info->ubuf; - stream.avail_out = info->nmax; - if (inflateInit2(&stream, -15) != Z_OK) { - goto cerror0; - } - err = inflate(&stream, Z_SYNC_FLUSH); - inflateEnd(&stream); - if ((err == Z_STREAM_END) || - ((err == Z_OK) && (stream.avail_in == 0))) { - if (cbuf != NULL) { - memset(info->keys, 0, sizeof (info->keys)); - Tcl_Free((char *) cbuf); - } - goto wrapchan; - } -cerror0: - if (cbuf != NULL) { - memset(info->keys, 0, sizeof (info->keys)); - Tcl_Free((char *) cbuf); - } - if (info->ubuf != NULL) { - Tcl_Free((char *) info->ubuf); - } - Tcl_Free((char *) info); - if (interp != NULL) { - Tcl_SetObjResult(interp, - Tcl_NewStringObj("decompression error", -1)); - } - goto error; - } else if (z->isenc) { - for (i = 0; i < z->nbyte - 12; i++) { - ch = zbuf[i]; - info->ubuf[i] = zdecode(info->keys, crc32tab, ch); - } - } else { - memcpy(info->ubuf, zbuf, z->nbyte); - } - memset(info->keys, 0, sizeof (info->keys)); - goto wrapchan; - } - } - } else if (z->data != NULL) { - flags |= TCL_READABLE; - info->iswr = 0; - info->iscompr = 0; - info->isdir = 0; - info->isenc = 0; - info->nbyte = z->nbyte; - info->nmax = 0; - info->ubuf = z->data; - } else { - flags |= TCL_READABLE; - info->iswr = 0; - info->iscompr = z->cmeth == ZIP_COMPMETH_DEFLATED; - info->ubuf = z->zipfile->data + z->offset; - info->isdir = z->isdir; - info->isenc = z->isenc; - info->nbyte = z->nbyte; - info->nmax = 0; - if (info->isenc) { - int len = z->zipfile->pwbuf[0]; - char pwbuf[260]; - - for (i = 0; i < len; i++) { - ch = z->zipfile->pwbuf[len - i]; - pwbuf[i] = (ch & 0x0f) | pwrot[(ch >> 4) & 0x0f]; - } - pwbuf[i] = '\0'; - init_keys(pwbuf, info->keys, crc32tab); - memset(pwbuf, 0, sizeof (pwbuf)); - for (i = 0; i < 12; i++) { - ch = info->ubuf[i]; - zdecode(info->keys, crc32tab, ch); - } - info->ubuf += i; - } - if (info->iscompr) { - z_stream stream; - int err; - unsigned char *ubuf = NULL; - unsigned int j; - - memset(&stream, 0, sizeof (stream)); - stream.zalloc = Z_NULL; - stream.zfree = Z_NULL; - stream.opaque = Z_NULL; - stream.avail_in = z->nbytecompr; - if (info->isenc) { - stream.avail_in -= 12; - ubuf = (unsigned char *) Tcl_AttemptAlloc(stream.avail_in); - if (ubuf == NULL) { - info->ubuf = NULL; - goto merror; - } - for (j = 0; j < stream.avail_in; j++) { - ch = info->ubuf[j]; - ubuf[j] = zdecode(info->keys, crc32tab, ch); - } - stream.next_in = ubuf; - } else { - stream.next_in = info->ubuf; - } - stream.next_out = info->ubuf = - (unsigned char *) Tcl_AttemptAlloc(info->nbyte); - if (info->ubuf == NULL) { -merror: - if (ubuf != NULL) { - info->isenc = 0; - memset(info->keys, 0, sizeof (info->keys)); - Tcl_Free((char *) ubuf); - } - Tcl_Free((char *) info); - if (interp != NULL) { - Tcl_SetObjResult(interp, - Tcl_NewStringObj("out of memory", -1)); - } - goto error; - } - stream.avail_out = info->nbyte; - if (inflateInit2(&stream, -15) != Z_OK) { - goto cerror; - } - err = inflate(&stream, Z_SYNC_FLUSH); - inflateEnd(&stream); - if ((err == Z_STREAM_END) || - ((err == Z_OK) && (stream.avail_in == 0))) { - if (ubuf != NULL) { - info->isenc = 0; - memset(info->keys, 0, sizeof (info->keys)); - Tcl_Free((char *) ubuf); - } - goto wrapchan; - } -cerror: - if (ubuf != NULL) { - info->isenc = 0; - memset(info->keys, 0, sizeof (info->keys)); - Tcl_Free((char *) ubuf); - } - if (info->ubuf != NULL) { - Tcl_Free((char *) info->ubuf); - } - Tcl_Free((char *) info); - if (interp != NULL) { - Tcl_SetObjResult(interp, - Tcl_NewStringObj("decompression error", -1)); - } - goto error; - } - } -wrapchan: - sprintf(cname, "zipfs_%lx_%d", (unsigned long) z->offset, ZipFS.idCount++); - z->zipfile->nopen++; - Unlock(); - return Tcl_CreateChannel(&ZipChannelType, cname, (ClientData) info, flags); - -error: - Unlock(); - return NULL; -} - -/* - *------------------------------------------------------------------------- - * - * ZipEntryStat -- - * - * This function implements the ZIP filesystem specific version - * of the library version of stat. - * - * Results: - * See stat documentation. - * - * Side effects: - * See stat documentation. - * - *------------------------------------------------------------------------- - */ - -static int -ZipEntryStat(char *path, Tcl_StatBuf *buf) -{ - ZipEntry *z; - int ret = -1; - - ReadLock(); - z = ZipFSLookup(path); - if (z == NULL) { - goto done; - } - memset(buf, 0, sizeof (Tcl_StatBuf)); - if (z->isdir) { - buf->st_mode = S_IFDIR | 0555; - } else { - buf->st_mode = S_IFREG | 0555; - } - buf->st_size = z->nbyte; - buf->st_mtime = z->timestamp; - buf->st_ctime = z->timestamp; - buf->st_atime = z->timestamp; - ret = 0; -done: - Unlock(); - return ret; -} - -/* - *------------------------------------------------------------------------- - * - * ZipEntryAccess -- - * - * This function implements the ZIP filesystem specific version - * of the library version of access. - * - * Results: - * See access documentation. - * - * Side effects: - * See access documentation. - * - *------------------------------------------------------------------------- - */ - -static int -ZipEntryAccess(char *path, int mode) -{ - ZipEntry *z; - - if (mode & 3) { - return -1; - } - ReadLock(); - z = ZipFSLookup(path); - Unlock(); - return (z != NULL) ? 0 : -1; -} - -/* - *------------------------------------------------------------------------- - * - * Zip_FSOpenFileChannelProc -- - * - * Results: - * - * Side effects: - * - *------------------------------------------------------------------------- - */ - -static Tcl_Channel -Zip_FSOpenFileChannelProc(Tcl_Interp *interp, Tcl_Obj *pathPtr, - int mode, int permissions) -{ - int len; - - return ZipChannelOpen(interp, Tcl_GetStringFromObj(pathPtr, &len), - mode, permissions); -} - -/* - *------------------------------------------------------------------------- - * - * Zip_FSStatProc -- - * - * This function implements the ZIP filesystem specific version - * of the library version of stat. - * - * Results: - * See stat documentation. - * - * Side effects: - * See stat documentation. - * - *------------------------------------------------------------------------- - */ - -static int -Zip_FSStatProc(Tcl_Obj *pathPtr, Tcl_StatBuf *buf) -{ - int len; - - return ZipEntryStat(Tcl_GetStringFromObj(pathPtr, &len), buf); -} - -/* - *------------------------------------------------------------------------- - * - * Zip_FSAccessProc -- - * - * This function implements the ZIP filesystem specific version - * of the library version of access. - * - * Results: - * See access documentation. - * - * Side effects: - * See access documentation. - * - *------------------------------------------------------------------------- - */ - -static int -Zip_FSAccessProc(Tcl_Obj *pathPtr, int mode) -{ - int len; - - return ZipEntryAccess(Tcl_GetStringFromObj(pathPtr, &len), mode); -} - -/* - *------------------------------------------------------------------------- - * - * Zip_FSFilesystemSeparatorProc -- - * - * This function returns the separator to be used for a given path. The - * object returned should have a refCount of zero - * - * Results: - * A Tcl object, with a refCount of zero. If the caller needs to retain a - * reference to the object, it should call Tcl_IncrRefCount, and should - * otherwise free the object. - * - * Side effects: - * None. - * - *------------------------------------------------------------------------- - */ - -static Tcl_Obj * -Zip_FSFilesystemSeparatorProc(Tcl_Obj *pathPtr) -{ - return Tcl_NewStringObj("/", -1); -} - -/* - *------------------------------------------------------------------------- - * - * Zip_FSMatchInDirectoryProc -- - * - * This routine is used by the globbing code to search a directory for - * all files which match a given pattern. - * - * Results: - * The return value is a standard Tcl result indicating whether an - * error occurred in globbing. Errors are left in interp, good - * results are lappend'ed to resultPtr (which must be a valid object). - * - * Side effects: - * None. - * - *------------------------------------------------------------------------- - */ - -static int -Zip_FSMatchInDirectoryProc(Tcl_Interp* interp, Tcl_Obj *result, - Tcl_Obj *pathPtr, const char *pattern, - Tcl_GlobTypeData *types) -{ - Tcl_HashEntry *hPtr; - Tcl_HashSearch search; - int scnt, len, l, dirOnly = -1, prefixLen, strip = 0; - char *pat, *prefix, *path; -#if HAS_DRIVES - char drivePrefix[3]; -#endif - Tcl_DString ds, dsPref; - -#if HAS_DRIVES - if ((pattern != NULL) && (pattern[0] != '\0') && - (strchr(drvletters, pattern[0]) != NULL) && (pattern[1] == ':')) { - pattern += 2; - } -#endif - if (types != NULL) { - dirOnly = (types->type & TCL_GLOB_TYPE_DIR) == TCL_GLOB_TYPE_DIR; - } - Tcl_DStringInit(&ds); - Tcl_DStringInit(&dsPref); - prefix = Tcl_GetStringFromObj(pathPtr, &prefixLen); - Tcl_DStringAppend(&dsPref, prefix, prefixLen); - prefix = Tcl_DStringValue(&dsPref); -#if HAS_DRIVES - path = AbsolutePath(prefix, NULL, &ds); -#else - path = AbsolutePath(prefix, &ds); -#endif - len = Tcl_DStringLength(&ds); - if (strcmp(prefix, path) == 0) { - prefix = NULL; - } else { -#if HAS_DRIVES - if ((strchr(drvletters, prefix[0]) != NULL) && (prefix[1] == ':')) { - if (strcmp(prefix + 2, path) == 0) { - strncpy(drivePrefix, prefix, 3); - drivePrefix[2] = '\0'; - prefix = drivePrefix; - } - } else { - strip = len + 1; - } -#else - strip = len + 1; -#endif - } - if (prefix != NULL) { -#if HAS_DRIVES - if (prefix == drivePrefix) { - Tcl_DStringSetLength(&dsPref, 0); - Tcl_DStringAppend(&dsPref, drivePrefix, -1); - prefixLen = Tcl_DStringLength(&dsPref); - } else { - Tcl_DStringAppend(&dsPref, "/", 1); - prefixLen++; - } - prefix = Tcl_DStringValue(&dsPref); -#else - Tcl_DStringAppend(&dsPref, "/", 1); - prefixLen++; - prefix = Tcl_DStringValue(&dsPref); -#endif - } - ReadLock(); - if ((types != NULL) && (types->type == TCL_GLOB_TYPE_MOUNT)) { - l = CountSlashes(path); - if (path[len - 1] == '/') { - len--; - } else { - l++; - } - if ((pattern == NULL) || (pattern[0] == '\0')) { - pattern = "*"; - } - hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); - while (hPtr != NULL) { - ZipFile *zf = (ZipFile *) Tcl_GetHashValue(hPtr); - - if (zf->mntptlen == 0) { - ZipEntry *z = zf->topents; - - while (z != NULL) { - int lenz = strlen(z->name); - - if ((lenz > len + 1) && - (strncmp(z->name, path, len) == 0) && - (z->name[len] == '/') && - (CountSlashes(z->name) == l) && - Tcl_StringCaseMatch(z->name + len + 1, pattern, 0)) { - if (prefix != NULL) { - Tcl_DStringAppend(&dsPref, z->name, lenz); - Tcl_ListObjAppendElement(NULL, result, - Tcl_NewStringObj(Tcl_DStringValue(&dsPref), - Tcl_DStringLength(&dsPref))); - Tcl_DStringSetLength(&dsPref, prefixLen); - } else { - Tcl_ListObjAppendElement(NULL, result, - Tcl_NewStringObj(z->name, lenz)); - } - } - z = z->tnext; - } - } else if ((zf->mntptlen > len + 1) && - (strncmp(zf->mntpt, path, len) == 0) && - (zf->mntpt[len] == '/') && - (CountSlashes(zf->mntpt) == l) && - Tcl_StringCaseMatch(zf->mntpt + len + 1, pattern, 0)) { - if (prefix != NULL) { - Tcl_DStringAppend(&dsPref, zf->mntpt, zf->mntptlen); - Tcl_ListObjAppendElement(NULL, result, - Tcl_NewStringObj(Tcl_DStringValue(&dsPref), - Tcl_DStringLength(&dsPref))); - Tcl_DStringSetLength(&dsPref, prefixLen); - } else { - Tcl_ListObjAppendElement(NULL, result, - Tcl_NewStringObj(zf->mntpt, zf->mntptlen)); - } - } - hPtr = Tcl_NextHashEntry(&search); - } - goto end; - } - if ((pattern == NULL) || (pattern[0] == '\0')) { - hPtr = Tcl_FindHashEntry(&ZipFS.fileHash, path); - if (hPtr != NULL) { - ZipEntry *z = (ZipEntry *) Tcl_GetHashValue(hPtr); - - if ((dirOnly < 0) || - (!dirOnly && !z->isdir) || - (dirOnly && z->isdir)) { - if (prefix != NULL) { - Tcl_DStringAppend(&dsPref, z->name, -1); - Tcl_ListObjAppendElement(NULL, result, - Tcl_NewStringObj(Tcl_DStringValue(&dsPref), - Tcl_DStringLength(&dsPref))); - Tcl_DStringSetLength(&dsPref, prefixLen); - } else { - Tcl_ListObjAppendElement(NULL, result, - Tcl_NewStringObj(z->name, -1)); - } - } - } - goto end; - } - l = strlen(pattern); - pat = Tcl_Alloc(len + l + 2); - memcpy(pat, path, len); - while ((len > 1) && (pat[len - 1] == '/')) { - --len; - } - if ((len > 1) || (pat[0] != '/')) { - pat[len] = '/'; - ++len; - } - memcpy(pat + len, pattern, l + 1); - scnt = CountSlashes(pat); - for (hPtr = Tcl_FirstHashEntry(&ZipFS.fileHash, &search); - hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) { - ZipEntry *z = (ZipEntry *) Tcl_GetHashValue(hPtr); - - if ((dirOnly >= 0) && - ((dirOnly && !z->isdir) || (!dirOnly && z->isdir))) { - continue; - } - if ((z->depth == scnt) && Tcl_StringCaseMatch(z->name, pat, 0)) { - if (prefix != NULL) { - Tcl_DStringAppend(&dsPref, z->name + strip, -1); - Tcl_ListObjAppendElement(NULL, result, - Tcl_NewStringObj(Tcl_DStringValue(&dsPref), - Tcl_DStringLength(&dsPref))); - Tcl_DStringSetLength(&dsPref, prefixLen); - } else { - Tcl_ListObjAppendElement(NULL, result, - Tcl_NewStringObj(z->name + strip, -1)); - } - } - } - Tcl_Free(pat); -end: - Unlock(); - Tcl_DStringFree(&dsPref); - Tcl_DStringFree(&ds); - return TCL_OK; -} - -/* - *------------------------------------------------------------------------- - * - * Zip_FSNormalizePathProc -- - * - * Function to normalize given path object. - * - * Results: - * Length of final absolute path name. - * - * Side effects: - * Path object gets converted to an absolute path. - * - *------------------------------------------------------------------------- - */ - -static int -Zip_FSNormalizePathProc(Tcl_Interp *interp, Tcl_Obj *pathPtr, - int nextCheckpoint) -{ - char *path; - Tcl_DString ds; - int len; - - path = Tcl_GetStringFromObj(pathPtr, &len); - Tcl_DStringInit(&ds); -#if HAS_DRIVES - path = AbsolutePath(path, NULL, &ds); -#else - path = AbsolutePath(path, &ds); -#endif - nextCheckpoint = Tcl_DStringLength(&ds); - Tcl_SetStringObj(pathPtr, Tcl_DStringValue(&ds), - Tcl_DStringLength(&ds)); - Tcl_DStringFree(&ds); - return nextCheckpoint; -} - -/* - *------------------------------------------------------------------------- - * - * Zip_FSPathInFilesystemProc -- - * - * This function determines if the given path object is in the - * ZIP filesystem. - * - * Results: - * TCL_OK when the path object is in the ZIP filesystem, -1 otherwise. - * - * Side effects: - * None. - * - *------------------------------------------------------------------------- - */ - -static int -Zip_FSPathInFilesystemProc(Tcl_Obj *pathPtr, ClientData *clientDataPtr) -{ - Tcl_HashEntry *hPtr; - Tcl_HashSearch search; - ZipFile *zf; - int ret = -1, len; - char *path; - Tcl_DString ds; -#if HAS_DRIVES - int drive = 0; -#endif - - path = Tcl_GetStringFromObj(pathPtr, &len); - Tcl_DStringInit(&ds); -#if HAS_DRIVES - path = AbsolutePath(path, &drive, &ds); -#else - path = AbsolutePath(path, &ds); -#endif - len = Tcl_DStringLength(&ds); -#if HAS_DRIVES - if (len && (strchr(drvletters, path[0]) != NULL) && (path[1] == ':')) { - path += 2; - len -= 2; - } -#endif - ReadLock(); - hPtr = Tcl_FindHashEntry(&ZipFS.fileHash, path); - if (hPtr != NULL) { -#if HAS_DRIVES - ZipEntry *z = (ZipEntry *) Tcl_GetHashValue(hPtr); - if (drive == z->zipfile->mntdrv) { - ret = TCL_OK; - goto endloop; - } -#else - ret = TCL_OK; - goto endloop; -#endif - } - hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); - while (hPtr != NULL) { - zf = (ZipFile *) Tcl_GetHashValue(hPtr); -#if HAS_DRIVES - if (drive != zf->mntdrv) { - hPtr = Tcl_NextHashEntry(&search); - continue; - } -#endif - if (zf->mntptlen == 0) { - ZipEntry *z = zf->topents; - - while (z != NULL) { - int lenz = strlen(z->name); - - if ((len >= lenz) && - (strncmp(path, z->name, lenz) == 0)) { - ret = TCL_OK; - goto endloop; - } - z = z->tnext; - } - } else if ((len >= zf->mntptlen) && - (strncmp(path, zf->mntpt, zf->mntptlen) == 0)) { - ret = TCL_OK; - goto endloop; - } - hPtr = Tcl_NextHashEntry(&search); - } -endloop: - Unlock(); - Tcl_DStringFree(&ds); - return ret; -} - -/* - *------------------------------------------------------------------------- - * - * Zip_FSListVolumesProc -- - * - * Lists the currently mounted ZIP filesystem volumes. - * - * Results: - * The list of volumes. - * - * Side effects: - * None - * - *------------------------------------------------------------------------- - */ - -static Tcl_Obj * -Zip_FSListVolumesProc(void) -{ - Tcl_HashEntry *hPtr; - Tcl_HashSearch search; - ZipFile *zf; - Tcl_Obj *vols = Tcl_NewObj(), *vol; - - ReadLock(); - hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); - while (hPtr != NULL) { - zf = (ZipFile *) Tcl_GetHashValue(hPtr); -#if HAS_DRIVES - vol = Tcl_ObjPrintf("%c:%s", zf->mntdrv, - zf->mntpt[0] ? zf->mntpt : "/"); -#else - if (zf->mntpt[0]) { - vol = Tcl_NewStringObj(zf->mntpt, zf->mntptlen); - } else { - vol = Tcl_NewStringObj("/", 1); - } -#endif - Tcl_ListObjAppendElement(NULL, vols, vol); - hPtr = Tcl_NextHashEntry(&search); - } - Unlock(); - Tcl_IncrRefCount(vols); - return vols; -} - -/* - *------------------------------------------------------------------------- - * - * Zip_FSChdirProc -- - * - * If the path object refers to a directory within the ZIP - * filesystem the current directory is set to this directory. - * - * Results: - * TCL_OK on success, -1 on error with error number set. - * - * Side effects: - * The global cwdPathPtr may change value. - * - *------------------------------------------------------------------------- - */ - -static int -Zip_FSChdirProc(Tcl_Obj *pathPtr) -{ - int len; - char *path; - Tcl_DString ds; - ZipEntry *z; - int ret = TCL_OK; -#if HAS_DRIVES - int drive = 0; -#endif - - path = Tcl_GetStringFromObj(pathPtr, &len); - Tcl_DStringInit(&ds); -#if HAS_DRIVES - path = AbsolutePath(path, &drive, &ds); -#else - path = AbsolutePath(path, &ds); -#endif - ReadLock(); - z = ZipFSLookup(path); - if ((z == NULL) || !z->isdir) { - Tcl_SetErrno(ENOENT); - ret = -1; - } -#if HAS_DRIVES - if ((z != NULL) && (drive != z->zipfile->mntdrv)) { - Tcl_SetErrno(ENOENT); - ret = -1; - } -#endif - Unlock(); - Tcl_DStringFree(&ds); - return ret; -} - -/* - *------------------------------------------------------------------------- - * - * Zip_FSFileAttrStringsProc -- - * - * This function implements the ZIP filesystem dependent 'file attributes' - * subcommand, for listing the set of possible attribute strings. - * - * Results: - * An array of strings - * - * Side effects: - * None. - * - *------------------------------------------------------------------------- - */ - -static const char *const * -Zip_FSFileAttrStringsProc(Tcl_Obj *pathPtr, Tcl_Obj** objPtrRef) -{ - static const char *const attrs[] = { - "-uncompsize", - "-compsize", - "-offset", - "-mount", - "-archive", - "-permissions", - NULL, - }; - - return attrs; -} - -/* - *------------------------------------------------------------------------- - * - * Zip_FSFileAttrsGetProc -- - * - * This function implements the ZIP filesystem specific - * 'file attributes' subcommand, for 'get' operations. - * - * Results: - * Standard Tcl return code. The object placed in objPtrRef (if TCL_OK - * was returned) is likely to have a refCount of zero. Either way we must - * either store it somewhere (e.g. the Tcl result), or Incr/Decr its - * refCount to ensure it is properly freed. - * - * Side effects: - * None. - * - *------------------------------------------------------------------------- - */ - -static int -Zip_FSFileAttrsGetProc(Tcl_Interp *interp, int index, Tcl_Obj *pathPtr, - Tcl_Obj **objPtrRef) -{ - int len, ret = TCL_OK; - char *path; - ZipEntry *z; - - path = Tcl_GetStringFromObj(pathPtr, &len); - ReadLock(); - z = ZipFSLookup(path); - if (z == NULL) { - if (interp != NULL) { - Tcl_SetObjResult(interp, Tcl_NewStringObj("file not found", -1)); - } - ret = TCL_ERROR; - goto done; - } - switch (index) { - case 0: - *objPtrRef = Tcl_NewIntObj(z->nbyte); - goto done; - case 1: - *objPtrRef= Tcl_NewIntObj(z->nbytecompr); - goto done; - case 2: - *objPtrRef= Tcl_NewLongObj(z->offset); - goto done; - case 3: - *objPtrRef= Tcl_NewStringObj(z->zipfile->mntpt, -1); - goto done; - case 4: - *objPtrRef= Tcl_NewStringObj(z->zipfile->name, -1); - goto done; - case 5: - *objPtrRef= Tcl_NewStringObj("0555", -1); - goto done; - } - if (interp != NULL) { - Tcl_SetObjResult(interp, Tcl_NewStringObj("unknown attribute", -1)); - } - ret = TCL_ERROR; -done: - Unlock(); - return ret; -} - -/* - *------------------------------------------------------------------------- - * - * Zip_FSFileAttrsSetProc -- - * - * This function implements the ZIP filesystem specific - * 'file attributes' subcommand, for 'set' operations. - * - * Results: - * Standard Tcl return code. - * - * Side effects: - * None. - * - *------------------------------------------------------------------------- - */ - -static int -Zip_FSFileAttrsSetProc(Tcl_Interp *interp, int index, Tcl_Obj *pathPtr, - Tcl_Obj *objPtr) -{ - if (interp != NULL) { - Tcl_SetObjResult(interp, Tcl_NewStringObj("unsupported operation", -1)); - } - return TCL_ERROR; -} - -/* - *------------------------------------------------------------------------- - * - * Zip_FSFilesystemPathTypeProc -- - * - * Results: - * - * Side effects: - * - *------------------------------------------------------------------------- - */ - -static Tcl_Obj * -Zip_FSFilesystemPathTypeProc(Tcl_Obj *pathPtr) -{ - return Tcl_NewStringObj("zip", -1); -} - - -/* - *------------------------------------------------------------------------- - * - * Zip_FSLoadFile -- - * - * This functions deals with loading native object code. If - * the given path object refers to a file within the ZIP - * filesystem, an approriate error code is returned to delegate - * loading to the caller (by copying the file to temp store - * and loading from there). As fallback when the file refers - * to the ZIP file system but is not present, it is looked up - * relative to the executable and loaded from there when available. - * - * Results: - * TCL_OK on success, -1 otherwise with error number set. - * - * Side effects: - * Loads native code into the process address space. - * - *------------------------------------------------------------------------- - */ - -static int -Zip_FSLoadFile(Tcl_Interp *interp, Tcl_Obj *path, Tcl_LoadHandle *loadHandle, - Tcl_FSUnloadFileProc **unloadProcPtr, int flags) -{ - Tcl_FSLoadFileProc2 *loadFileProc; -#ifdef ANDROID - /* - * Force loadFileProc to native implementation since the - * package manger already extracted the shared libraries - * from the APK at install time. - */ - - loadFileProc = (Tcl_FSLoadFileProc2 *) tclNativeFilesystem.loadFileProc; - if (loadFileProc != NULL) { - return loadFileProc(interp, path, loadHandle, unloadProcPtr, flags); - } - Tcl_SetErrno(ENOENT); - return -1; -#else - Tcl_Obj *altPath = NULL; - int ret = -1; - - if (Tcl_FSAccess(path, R_OK) == 0) { - /* - * EXDEV should trigger loading by copying to temp store. - */ - Tcl_SetErrno(EXDEV); - return ret; - } else { - Tcl_Obj *objs[2] = { NULL, NULL }; - - objs[1] = TclPathPart(interp, path, TCL_PATH_DIRNAME); - if ((objs[1] != NULL) && (Zip_FSAccessProc(objs[1], R_OK) == 0)) { - const char *execName = Tcl_GetNameOfExecutable(); - - /* - * Shared object is not in ZIP but its path prefix is, - * thus try to load from directory where the executable - * came from. - */ - TclDecrRefCount(objs[1]); - objs[1] = TclPathPart(interp, path, TCL_PATH_TAIL); - /* - * Get directory name of executable manually to deal - * with cases where [file dirname [info nameofexecutable]] - * is equal to [info nameofexecutable] due to VFS effects. - */ - if (execName != NULL) { - const char *p = strrchr(execName, '/'); - - if (p > execName + 1) { - --p; - objs[0] = Tcl_NewStringObj(execName, p - execName); - } - } - if (objs[0] == NULL) { - objs[0] = TclPathPart(interp, TclGetObjNameOfExecutable(), - TCL_PATH_DIRNAME); - } - if (objs[0] != NULL) { - altPath = TclJoinPath(2, objs); - if (altPath != NULL) { - Tcl_IncrRefCount(altPath); - if (Tcl_FSAccess(altPath, R_OK) == 0) { - path = altPath; - } - } - } - } - if (objs[0] != NULL) { - Tcl_DecrRefCount(objs[0]); - } - if (objs[1] != NULL) { - Tcl_DecrRefCount(objs[1]); - } - } - loadFileProc = (Tcl_FSLoadFileProc2 *) tclNativeFilesystem.loadFileProc; - if (loadFileProc != NULL) { - ret = loadFileProc(interp, path, loadHandle, unloadProcPtr, flags); - } else { - Tcl_SetErrno(ENOENT); - } - if (altPath != NULL) { - Tcl_DecrRefCount(altPath); - } - return ret; -#endif -} - - -/* - * Define the ZIP filesystem dispatch table. - */ - -MODULE_SCOPE const Tcl_Filesystem zipfsFilesystem; - -const Tcl_Filesystem zipfsFilesystem = { - "zipfs", - sizeof (Tcl_Filesystem), - TCL_FILESYSTEM_VERSION_2, - Zip_FSPathInFilesystemProc, - NULL, /* dupInternalRepProc */ - NULL, /* freeInternalRepProc */ - NULL, /* internalToNormalizedProc */ - NULL, /* createInternalRepProc */ - Zip_FSNormalizePathProc, - Zip_FSFilesystemPathTypeProc, - Zip_FSFilesystemSeparatorProc, - Zip_FSStatProc, - Zip_FSAccessProc, - Zip_FSOpenFileChannelProc, - Zip_FSMatchInDirectoryProc, - NULL, /* utimeProc */ - NULL, /* linkProc */ - Zip_FSListVolumesProc, - Zip_FSFileAttrStringsProc, - Zip_FSFileAttrsGetProc, - Zip_FSFileAttrsSetProc, - NULL, /* createDirectoryProc */ - NULL, /* removeDirectoryProc */ - NULL, /* deleteFileProc */ - NULL, /* copyFileProc */ - NULL, /* renameFileProc */ - NULL, /* copyDirectoryProc */ - NULL, /* lstatProc */ - (Tcl_FSLoadFileProc *) Zip_FSLoadFile, - NULL, /* getCwdProc */ - Zip_FSChdirProc, -}; - -#endif /* HAVE_ZLIB */ - - - -Zipfs_one_time_init(Tcl_Interp *interp) { - /* one-time initialization */ - WriteLock(); - if (!ZipFS.initialized) { -#ifdef TCL_THREADS - static const Tcl_Time t = { 0, 0 }; - - /* - * Inflate condition variable. - */ - Tcl_MutexLock(&ZipFSMutex); - Tcl_ConditionWait(&ZipFSCond, &ZipFSMutex, &t); - Tcl_MutexUnlock(&ZipFSMutex); -#endif - Tcl_FSRegister(NULL, &zipfsFilesystem); - Tcl_InitHashTable(&ZipFS.fileHash, TCL_STRING_KEYS); - Tcl_InitHashTable(&ZipFS.zipHash, TCL_STRING_KEYS); - ZipFS.initialized = ZipFS.idCount = 1; - if(interp) { - Tcl_StaticPackage(interp, "zipfs", Tclzipfs_Init, Tclzipfs_SafeInit); - } - } - Unlock(); -} -/* - *------------------------------------------------------------------------- - * - * Zipfs_doInit -- - * - * Perform per interpreter initialization of this module. - * - * Results: - * The return value is a standard Tcl result. - * - * Side effects: - * Initializes this module if not already initialized, and adds - * module related commands to the given interpreter. - * - *------------------------------------------------------------------------- - */ - -static int -Zipfs_doInit(Tcl_Interp *interp, int safe) -{ -#ifdef HAVE_ZLIB - static const EnsembleImplMap initMap[] = { - {"mount", ZipFSMountObjCmd, NULL, NULL, NULL, 0}, - {"unmount", ZipFSUnmountObjCmd, NULL, NULL, NULL, 0}, - {"mkkey", ZipFSMkKeyObjCmd, NULL, NULL, NULL, 0}, - {"mkimg", ZipFSMkImgObjCmd, NULL, NULL, NULL, 0}, - {"mkzip", ZipFSMkZipObjCmd, NULL, NULL, NULL, 0}, - {"lmkimg", ZipFSLMkImgObjCmd, NULL, NULL, NULL, 0}, - {"lmkzip", ZipFSLMkZipObjCmd, NULL, NULL, NULL, 0}, - {"exists", ZipFSExistsObjCmd, NULL, NULL, NULL, 0}, - {"info", ZipFSInfoObjCmd, NULL, NULL, NULL, 0}, - {"list", ZipFSListObjCmd, NULL, NULL, NULL, 0}, - {NULL, NULL, NULL, NULL, NULL, 0} - }; - - static const EnsembleImplMap initSafeMap[] = { - {"exists", ZipFSExistsObjCmd, NULL, NULL, NULL, 0}, - {"info", ZipFSInfoObjCmd, NULL, NULL, NULL, 0}, - {"list", ZipFSListObjCmd, NULL, NULL, NULL, 0}, - {NULL, NULL, NULL, NULL, NULL, 0} - }; - - static const char findproc[] = - "namespace eval zipfs {}\n" - "proc ::zipfs::find dir {\n" - " set result {}\n" - " if {[catch {glob -directory $dir -tails -nocomplain * .*} list]} {\n" - " return $result\n" - " }\n" - " foreach file $list {\n" - " if {$file eq \".\" || $file eq \"..\"} {\n" - " continue\n" - " }\n" - " set file [file join $dir $file]\n" - " lappend result $file\n" - " foreach file [::zipfs::find $file] {\n" - " lappend result $file\n" - " }\n" - " }\n" - " return [lsort $result]\n" - "}\n"; - Zipfs_one_time_init(interp); - if (!safe) { - Tcl_EvalEx(interp, findproc, -1, TCL_EVAL_GLOBAL); - Tcl_LinkVar(interp, "::zipfs::wrmax", (char *) &ZipFS.wrmax, - TCL_LINK_INT); - } - TclMakeEnsemble(interp, "zipfs", safe ? initSafeMap : initMap); - - Tcl_PkgProvide(interp, "zipfs", "1.0"); - - return TCL_OK; -#else - if (interp != NULL) { - Tcl_SetObjResult(interp, Tcl_NewStringObj("no zlib available", -1)); - } - return TCL_ERROR; -#endif -} - -/* - *------------------------------------------------------------------------- - * - * Tclzipfs_Init, Tclzipfs_SafeInit -- - * - * These functions are invoked to perform per interpreter initialization - * of this module. - * - * Results: - * The return value is a standard Tcl result. - * - * Side effects: - * Initializes this module if not already initialized, and adds - * module related commands to the given interpreter. - * - *------------------------------------------------------------------------- - */ - -int -Tclzipfs_Init(Tcl_Interp *interp) -{ - return Zipfs_doInit(interp, 0); -} - -int -Tclzipfs_SafeInit(Tcl_Interp *interp) -{ - return Zipfs_doInit(interp, 1); -} - -#ifndef HAVE_ZLIB - -/* - *------------------------------------------------------------------------- - * - * Tclzipfs_Mount, Tclzipfs_Unmount -- - * - * Dummy version when no ZLIB support available. - * - *------------------------------------------------------------------------- - */ - -int -Tclzipfs_Mount(Tcl_Interp *interp, const char *zipname, const char *mntpt, - const char *passwd) -{ - return Zipfs_doInit(interp, 1); -} - -int -Tclzipfs_Unmount(Tcl_Interp *interp, const char *zipname) -{ - return Zipfs_doInit(interp, 1); -} - -#endif - -/* -** Boot a shell, mount the executable's VFS, detect main.tcl -*/ -int Tcl_Zvfs_Boot(const char *archive,const char *vfsmountpoint,const char *initscript,const char *passwd) { - #ifdef HAVE_ZLIB - Zipfs_one_time_init(NULL); - if(!vfsmountpoint) { - vfsmountpoint="/zvfs"; - } - if(!initscript) { - initscript="main.tcl"; - } - /* We have to initialize the virtual filesystem before calling - ** Tcl_Init(). Otherwise, Tcl_Init() will not be able to find - ** its startup script files. - */ - if(!Tclzipfs_Mount(NULL, archive, vfsmountpoint,passwd)) { - Tcl_DString filepath; - Tcl_DString preinit; - - Tcl_Obj *vfsinitscript; - Tcl_Obj *vfstcllib; - Tcl_Obj *vfstklib; - Tcl_Obj *vfspreinit; - Tcl_DStringInit(&filepath); - Tcl_DStringInit(&preinit); - - Tcl_DStringInit(&filepath); - Tcl_DStringAppend(&filepath,vfsmountpoint,-1); - Tcl_DStringAppend(&filepath,"/",-1); - Tcl_DStringAppend(&filepath,initscript,-1); - vfsinitscript=Tcl_NewStringObj(Tcl_DStringValue(&filepath),-1); - Tcl_DStringFree(&filepath); - - Tcl_DStringInit(&filepath); - Tcl_DStringAppend(&filepath,vfsmountpoint,-1); - Tcl_DStringAppend(&filepath,"/boot/tcl",-1); - vfstcllib=Tcl_NewStringObj(Tcl_DStringValue(&filepath),-1); - Tcl_DStringFree(&filepath); - - Tcl_DStringInit(&filepath); - Tcl_DStringAppend(&filepath,vfsmountpoint,-1); - Tcl_DStringAppend(&filepath,"/boot/tk",-1); - vfstklib=Tcl_NewStringObj(Tcl_DStringValue(&filepath),-1); - Tcl_DStringFree(&filepath); - - Tcl_IncrRefCount(vfsinitscript); - Tcl_IncrRefCount(vfstcllib); - Tcl_IncrRefCount(vfstklib); - - if(Tcl_FSAccess(vfsinitscript,F_OK)==0) { - /* Startup script should be set before calling Tcl_AppInit */ - Tcl_SetStartupScript(vfsinitscript,NULL); - } - /* Record the mountpoint for scripts to refer back to */ - Tcl_DStringAppend(&preinit,"\nset ::tcl_boot_vfs ",-1); - Tcl_DStringAppendElement(&preinit,vfsmountpoint); - Tcl_DStringAppend(&preinit,"\nset ::SRCDIR ",-1); - Tcl_DStringAppendElement(&preinit,vfsmountpoint); - - if(Tcl_FSAccess(vfstcllib,F_OK)==0) { - Tcl_DStringAppend(&preinit,"\nset tcl_library ",-1); - Tcl_DStringAppendElement(&preinit,Tcl_GetString(vfstcllib)); - } - if(Tcl_FSAccess(vfstklib,F_OK)==0) { - Tcl_DStringAppend(&preinit,"\nset tk_library ",-1); - Tcl_DStringAppendElement(&preinit,Tcl_GetString(vfstklib)); - } - vfspreinit=Tcl_NewStringObj(Tcl_DStringValue(&preinit),-1); - /* NOTE: We never decr this refcount, lest the contents of the script be deallocated */ - Tcl_IncrRefCount(vfspreinit); - TclSetPreInitScript(Tcl_GetString(vfspreinit)); - - Tcl_DecrRefCount(vfsinitscript); - Tcl_DecrRefCount(vfstcllib); - Tcl_DecrRefCount(vfstklib); - } - #endif - return TCL_OK; -} - -/* - * Local Variables: - * mode: c - * c-basic-offset: 4 - * fill-column: 78 - * End: - */ diff --git a/library/practcl/pkgIndex.tcl b/library/practcl/pkgIndex.tcl new file mode 100644 index 0000000..1e378e8 --- /dev/null +++ b/library/practcl/pkgIndex.tcl @@ -0,0 +1,11 @@ +# Tcl package index file, version 1.1 +# This file is generated by the "pkg_mkIndex" command +# and sourced either when an application starts up or +# by a "package unknown" script. It invokes the +# "package ifneeded" command to set up package-related +# information so that packages will be loaded automatically +# in response to "package require" commands. When this +# script is sourced, the variable $dir must contain the +# full path name of this file's directory. + +package ifneeded practcl 0.5 [list source [file join $dir practcl.tcl]] diff --git a/library/practcl/practcl.tcl b/library/practcl/practcl.tcl new file mode 100644 index 0000000..3b4b04e --- /dev/null +++ b/library/practcl/practcl.tcl @@ -0,0 +1,4000 @@ +### +# Practcl +# An object oriented templating system for stamping out Tcl API calls to C +### +puts [list LOADED practcl.tcl from [info script]] +package require TclOO +proc ::debug args { + #puts $args + ::practcl::cputs ::DEBUG_INFO $args +} + +### +# Drop in a static copy of Tcl +### +proc ::doexec args { + puts [list {*}$args] + exec {*}$args >&@ stdout +} + +proc ::dotclexec args { + puts [list [info nameofexecutable] {*}$args] + exec [info nameofexecutable] {*}$args >&@ stdout +} + +proc ::domake {path args} { + set PWD [pwd] + cd $path + puts [list *** $path ***] + puts [list make {*}$args] + exec make {*}$args >&@ stdout + cd $PWD +} + +proc ::domake.tcl {path args} { + set PWD [pwd] + cd $path + puts [list *** $path ***] + puts [list make.tcl {*}$args] + exec [info nameofexecutable] make.tcl {*}$args >&@ stdout + cd $PWD +} + +proc ::fossil {path args} { + set PWD [pwd] + cd $path + puts [list {*}$args] + exec fossil {*}$args >&@ stdout + cd $PWD +} + + +proc ::fossil_status {dir} { + if {[info exists ::fosdat($dir)]} { + return $::fosdat($dir) + } + set result { +tags experimental +version {} + } + set pwd [pwd] + cd $dir + set info [exec fossil status] + cd $pwd + foreach line [split $info \n] { + if {[lindex $line 0] eq "checkout:"} { + set hash [lindex $line end-3] + set maxdate [lrange $line end-2 end-1] + dict set result hash $hash + dict set result maxdate $maxdate + regsub -all {[^0-9]} $maxdate {} isodate + dict set result isodate $isodate + } + if {[lindex $line 0] eq "tags:"} { + set tags [lrange $line 1 end] + dict set result tags $tags + break + } + } + set ::fosdat($dir) $result + return $result +} +### +# Seek out Tcllib if it's available +### +set tcllib_path {} +foreach path {.. ../.. ../../..} { + foreach path [glob -nocomplain [file join [file normalize $path] tcllib* modules]] { + set tclib_path $path + lappend ::auto_path $path + break + } + if {$tcllib_path ne {}} break +} + + +### +# Build utility functions +### +namespace eval ::practcl {} + +proc ::practcl::os {} { + if {[info exists ::project(TEACUP_OS)] && $::project(TEACUP_OS) ni {"@TEACUP_OS@" {}}} { + return $::project(TEACUP_OS) + } + set info [::practcl::config.tcl $::project(builddir)] + if {[dict exists $info TEACUP_OS]} { + return [dict get $info TEACUP_OS] + } + return unknown +} + +### +# Detect local platform +### +proc ::practcl::config.tcl {path} { + dict set result buildpath $path + set result {} + if {[file exists [file join $path config.tcl]]} { + set fin [open [file join $path config.tcl] r] + set bufline {} + set rawcount 0 + set linecount 0 + while {[gets $fin thisline]>=0} { + incr rawcount + append bufline \n $thisline + if {![info complete $bufline]} continue + set line [string trimleft $bufline] + set bufline {} + if {[string index [string trimleft $line] 0] eq "#"} continue + incr linecount + set key [lindex $line 0] + set value [lindex $line 1] + dict set result $key $value + } + dict set result sandbox [file dirname [dict get $result srcdir]] + dict set result download [file join [dict get $result sandbox] download] + dict set result teapot [file join [dict get $result sandbox] teapot] + set result [::practcl::de_shell $result] + } + # If data is available from autoconf, defer to that + if {[dict exists $result TEACUP_OS] && [dict get $result TEACUP_OS] ni {"@TEACUP_OS@" {}}} { + return $result + } + # If autoconf hasn't run yet, assume we are not cross compiling + # and defer to local checks + dict set result TEACUP_PROFILE unknown + dict set result TEACUP_OS unknown + dict set result EXEEXT {} + if {$::tcl_platform(platform) eq "windows"} { + set system "windows" + set arch ix86 + dict set result TEACUP_PROFILE win32-ix86 + dict set result TEACUP_OS windows + dict set result EXEEXT .exe + } else { + set system [exec uname -s]-[exec uname -r] + set arch unknown + dict set result TEACUP_OS generic + } + dict set result TEA_PLATFORM $system + dict set result TEA_SYSTEM $system + switch -glob $system { + Linux* { + dict set result TEACUP_OS linux + set arch [exec uname -m] + dict set result TEACUP_PROFILE "linux-glibc2.3-$arch" + } + GNU* { + set arch [exec uname -m] + dict set result TEACUP_OS "gnu" + } + NetBSD-Debian { + set arch [exec uname -m] + dict set result TEACUP_OS "netbsd-debian" + } + OpenBSD-* { + set arch [exec arch -s] + dict set result TEACUP_OS "openbsd" + } + Darwin* { + set arch [exec uname -m] + dict set result TEACUP_OS "macosx" + if {$arch eq "x86_64"} { + dict set result TEACUP_PROFILE "macosx10.5-i386-x86_84" + } else { + dict set result TEACUP_PROFILE "macosx-universal" + } + } + OpenBSD* { + set arch [exec arch -s] + dict set result TEACUP_OS "openbsd" + } + } + if {$arch eq "unknown"} { + catch {set arch [exec uname -m]} + } + switch -glob $arch { + i*86 { + set arch "ix86" + } + amd64 { + set arch "x86_64" + } + } + dict set result TEACUP_ARCH $arch + if {[dict get $result TEACUP_PROFILE] eq "unknown"} { + dict set result TEACUP_PROFILE [dict get $result TEACUP_OS]-$arch + } + return $result +} + + +### +# Convert an MSYS path to a windows native path +### +if {$::tcl_platform(platform) eq "windows"} { +proc ::practcl::msys_to_tclpath msyspath { + return [exec sh -c "cd $msyspath ; pwd -W"] +} +} else { +proc ::practcl::msys_to_tclpath msyspath { + return [file normalize $msyspath] +} +} + +### +# Bits stolen from fileutil +### +proc ::practcl::cat fname { + set fname [open $fname r] + set data [read $fname] + close $fname + return $data +} + +proc ::practcl::file_lexnormalize {sp} { + set spx [file split $sp] + + # Resolution of embedded relative modifiers (., and ..). + + if { + ([lsearch -exact $spx . ] < 0) && + ([lsearch -exact $spx ..] < 0) + } { + # Quick path out if there are no relative modifiers + return $sp + } + + set absolute [expr {![string equal [file pathtype $sp] relative]}] + # A volumerelative path counts as absolute for our purposes. + + set sp $spx + set np {} + set noskip 1 + + while {[llength $sp]} { + set ele [lindex $sp 0] + set sp [lrange $sp 1 end] + set islast [expr {[llength $sp] == 0}] + + if {[string equal $ele ".."]} { + if { + ($absolute && ([llength $np] > 1)) || + (!$absolute && ([llength $np] >= 1)) + } { + # .. : Remove the previous element added to the + # new path, if there actually is enough to remove. + set np [lrange $np 0 end-1] + } + } elseif {[string equal $ele "."]} { + # Ignore .'s, they stay at the current location + continue + } else { + # A regular element. + lappend np $ele + } + } + if {[llength $np] > 0} { + return [eval [linsert $np 0 file join]] + # 8.5: return [file join {*}$np] + } + return {} +} + +proc ::practcl::file_relative {base dst} { + # Ensure that the link to directory 'dst' is properly done relative to + # the directory 'base'. + + if {![string equal [file pathtype $base] [file pathtype $dst]]} { + return -code error "Unable to compute relation for paths of different pathtypes: [file pathtype $base] vs. [file pathtype $dst], ($base vs. $dst)" + } + + set base [file_lexnormalize [file join [pwd] $base]] + set dst [file_lexnormalize [file join [pwd] $dst]] + + set save $dst + set base [file split $base] + set dst [file split $dst] + + while {[string equal [lindex $dst 0] [lindex $base 0]]} { + set dst [lrange $dst 1 end] + set base [lrange $base 1 end] + if {![llength $dst]} {break} + } + + set dstlen [llength $dst] + set baselen [llength $base] + + if {($dstlen == 0) && ($baselen == 0)} { + # Cases: + # (a) base == dst + + set dst . + } else { + # Cases: + # (b) base is: base/sub = sub + # dst is: base = {} + + # (c) base is: base = {} + # dst is: base/sub = sub + + while {$baselen > 0} { + set dst [linsert $dst 0 ..] + incr baselen -1 + } + # 8.5: set dst [file join {*}$dst] + set dst [eval [linsert $dst 0 file join]] + } + + return $dst +} + +### +# Unpack the source of a fossil project into a designated location +### +proc ::practcl::fossil_sandbox {pkg args} { + if {[llength $args]==1} { + set info [lindex $args 0] + } else { + set info $args + } + set result $info + if {[dict exists $info srcroot]} { + set srcroot [dict get $info srcroot] + } elseif {[dict exists $info sandbox]} { + set srcroot [file join [dict get $info sandbox] $pkg] + } else { + set srcroot [file join $::CWD .. $pkg] + } + dict set result srcroot $srcroot + puts [list fossil_sandbox $pkg $srcroot] + if {[dict exists $info download]} { + ### + # Source is actually a zip archive + ### + set download [dict get $info download] + if {[file exists [file join $download $pkg.zip]]} { + if {![info exists $srcroot]} { + package require zipfile::decode + ::zipfile::decode::unzipfile [file join $download $pkg.zip] $srcroot + } + return + } + } + variable fossil_dbs + if {![::info exists fossil_dbs]} { + # Get a list of local fossil databases + set fossil_dbs [exec fossil all list] + } + set CWD [pwd] + if {![dict exists $info tag]} { + set tag trunk + } else { + set tag [dict get $info tag] + } + dict set result tag $tag + + try { + if {[file exists [file join $srcroot .fslckout]]} { + if {[dict exists $info update] && [dict get $info update]==1} { + catch { + puts "FOSSIL UPDATE" + cd $srcroot + doexec fossil update $tag + } + } + } elseif {[file exists [file join $srcroot _FOSSIL_]]} { + if {[dict exists $info update] && [dict get $info update]==1} { + catch { + puts "FOSSIL UPDATE" + cd $srcroot + doexec fossil update $tag + } + } + } else { + puts "OPEN AND UNPACK" + set fosdb {} + foreach line [split $fossil_dbs \n] { + set line [string trim $line] + if {[file rootname [file tail $line]] eq $pkg} { + set fosdb $line + break + } + } + if {$fosdb eq {}} { + file mkdir [file join $download fossil] + set fosdb [file join $download fossil $pkg.fos] + set cloned 0 + if {[dict exists $info localmirror]} { + set localmirror [dict get $info localmirror] + catch { + doexec fossil clone $localmirror/$pkg $fosdb + set cloned 1 + } + } + if {!$cloned && [dict exists $info fossil_url]} { + set localmirror [dict get $info fossil_url] + catch { + doexec fossil clone $localmirror/$pkg $fosdb + set cloned 1 + } + } + if {!$cloned} { + doexec fossil clone http://fossil.etoyoc.com/fossil/$pkg $fosdb + } + } + file mkdir $srcroot + cd $srcroot + puts "FOSSIL OPEN [pwd]" + doexec fossil open $fosdb $tag + } + } on error {result opts} { + puts [list ERR [dict get $opts -errorinfo]] + return {*}$opts + } finally { + cd $CWD + } + return $result +} + +### +# topic: e71f3f61c348d56292011eec83e95f0aacc1c618 +# description: Converts a XXX.sh file into a series of Tcl variables +### +proc ::practcl::read_sh_subst {line info} { + regsub -all {\x28} $line \x7B line + regsub -all {\x29} $line \x7D line + + #set line [string map $key [string trim $line]] + foreach {field value} $info { + catch {set $field $value} + } + if [catch {subst $line} result] { + return {} + } + set result [string trim $result] + return [string trim $result '] +} + +### +# topic: 03567140cca33c814664c7439570f669b9ab88e6 +### +proc ::practcl::read_sh_file {filename {localdat {}}} { + set fin [open $filename r] + set result {} + if {$localdat eq {}} { + set top 1 + set local [array get ::env] + dict set local EXE {} + } else { + set top 0 + set local $localdat + } + while {[gets $fin line] >= 0} { + set line [string trim $line] + if {[string index $line 0] eq "#"} continue + if {$line eq {}} continue + catch { + if {[string range $line 0 6] eq "export "} { + set eq [string first "=" $line] + set field [string trim [string range $line 6 [expr {$eq - 1}]]] + set value [read_sh_subst [string range $line [expr {$eq+1}] end] $local] + dict set result $field [read_sh_subst $value $local] + dict set local $field $value + } elseif {[string range $line 0 7] eq "include "} { + set subfile [read_sh_subst [string range $line 7 end] $local] + foreach {field value} [read_sh_file $subfile $local] { + dict set result $field $value + } + } else { + set eq [string first "=" $line] + if {$eq > 0} { + set field [read_sh_subst [string range $line 0 [expr {$eq - 1}]] $local] + set value [string trim [string range $line [expr {$eq+1}] end] '] + #set value [read_sh_subst [string range $line [expr {$eq+1}] end] $local] + dict set local $field $value + dict set result $field $value + } + } + } err opts + if {[dict get $opts -code] != 0} { + #puts $opts + puts "Error reading line:\n$line\nerr: $err\n***" + return $err {*}$opts + } + } + return $result +} + +### +# A simpler form of read_sh_file tailored +# to pulling data from (tcl|tk)Config.sh +### +proc ::practcl::read_Config.sh filename { + set fin [open $filename r] + set result {} + set linecount 0 + while {[gets $fin line] >= 0} { + set line [string trim $line] + if {[string index $line 0] eq "#"} continue + if {$line eq {}} continue + catch { + set eq [string first "=" $line] + if {$eq > 0} { + set field [string range $line 0 [expr {$eq - 1}]] + set value [string trim [string range $line [expr {$eq+1}] end] '] + #set value [read_sh_subst [string range $line [expr {$eq+1}] end] $local] + dict set result $field $value + incr $linecount + } + } err opts + if {[dict get $opts -code] != 0} { + #puts $opts + puts "Error reading line:\n$line\nerr: $err\n***" + return $err {*}$opts + } + } + return $result +} + +### +# A simpler form of read_sh_file tailored +# to pulling data from a Makefile +### +proc ::practcl::read_Makefile filename { + set fin [open $filename r] + set result {} + while {[gets $fin line] >= 0} { + set line [string trim $line] + if {[string index $line 0] eq "#"} continue + if {$line eq {}} continue + catch { + set eq [string first "=" $line] + if {$eq > 0} { + set field [string trim [string range $line 0 [expr {$eq - 1}]]] + set value [string trim [string trim [string range $line [expr {$eq+1}] end] ']] + switch $field { + PKG_LIB_FILE { + dict set result libfile $value + } + srcdir { + if {$value eq "."} { + dict set result srcdir [file dirname $filename] + } else { + dict set result srcdir $value + } + } + PACKAGE_NAME { + dict set result name $value + } + PACKAGE_VERSION { + dict set result version $value + } + LIBS { + dict set result PRACTCL_LIBS $value + } + PKG_LIB_FILE { + dict set result libfile $value + } + } + } + } err opts + if {[dict get $opts -code] != 0} { + #puts $opts + puts "Error reading line:\n$line\nerr: $err\n***" + return $err {*}$opts + } + # the Compile field is about where most TEA files start getting silly + if {$field eq "compile"} { + break + } + } + return $result +} + +## Append arguments to a buffer +# The command works like puts in that each call will also insert +# a line feed. Unlike puts, blank links in the interstitial are +# suppressed +proc ::practcl::cputs {varname args} { + upvar 1 $varname buffer + if {[llength $args]==1 && [string length [string trim [lindex $args 0]]] == 0} { + + } + if {[info exist buffer]} { + if {[string index $buffer end] ne "\n"} { + append buffer \n + } + } else { + set buffer \n + } + # Trim leading \n's + append buffer [string trimleft [lindex $args 0] \n] {*}[lrange $args 1 end] +} + + +proc ::practcl::tcl_to_c {body} { + set result {} + foreach rawline [split $body \n] { + set line [string map [list \" \\\" \\ \\\\] $rawline] + cputs result "\n \"$line\\n\" \\" + } + return [string trimright $result \\] +} + + +proc ::practcl::_tagblock {text {style tcl} {note {}}} { + if {[string length [string trim $text]]==0} { + return {} + } + set output {} + switch $style { + tcl { + ::practcl::cputs output "# BEGIN $note" + } + c { + ::practcl::cputs output "/* BEGIN $note */" + } + default { + ::practcl::cputs output "# BEGIN $note" + } + } + ::practcl::cputs output $text + switch $style { + tcl { + ::practcl::cputs output "# END $note" + } + c { + ::practcl::cputs output "/* END $note */" + } + default { + ::practcl::cputs output "# END $note" + } + } + return $output +} + +proc ::practcl::_isdirectory name { + return [file isdirectory $name] +} + +### +# Return true if the pkgindex file contains +# any statement other than "package ifneeded" +# and/or if any package ifneeded loads a DLL +### +proc ::practcl::_pkgindex_directory {path} { + set buffer {} + set pkgidxfile [file join $path pkgIndex.tcl] + if {![file exists $pkgidxfile]} { + # No pkgIndex file, read the source + foreach file [glob -nocomplain $path/*.tm] { + set file [file normalize $file] + set fname [file rootname [file tail $file]] + ### + # We used to be able to ... Assume the package is correct in the filename + # No hunt for a "package provides" + ### + set package [lindex [split $fname -] 0] + set version [lindex [split $fname -] 1] + ### + # Read the file, and override assumptions as needed + ### + set fin [open $file r] + set dat [read $fin] + close $fin + # Look for a teapot style Package statement + foreach line [split $dat \n] { + set line [string trim $line] + if { [string range $line 0 9] != "# Package " } continue + set package [lindex $line 2] + set version [lindex $line 3] + break + } + # Look for a package provide statement + foreach line [split $dat \n] { + set line [string trim $line] + if { [string range $line 0 14] != "package provide" } continue + set package [lindex $line 2] + set version [lindex $line 3] + break + } + append buffer "package ifneeded $package $version \[list source \[file join \$dir [file tail $file]\]\]" \n + } + foreach file [glob -nocomplain $path/*.tcl] { + if { [file tail $file] == "version_info.tcl" } continue + set fin [open $file r] + set dat [read $fin] + close $fin + if {![regexp "package provide" $dat]} continue + set fname [file rootname [file tail $file]] + # Look for a package provide statement + foreach line [split $dat \n] { + set line [string trim $line] + if { [string range $line 0 14] != "package provide" } continue + set package [lindex $line 2] + set version [lindex $line 3] + if {[string index $package 0] in "\$ \["} continue + if {[string index $version 0] in "\$ \["} continue + append buffer "package ifneeded $package $version \[list source \[file join \$dir [file tail $file]\]\]" \n + break + } + } + return $buffer + } + set fin [open $pkgidxfile r] + set dat [read $fin] + close $fin + set thisline {} + foreach line [split $dat \n] { + append thisline $line \n + if {![info complete $thisline]} continue + set line [string trim $line] + if {[string length $line]==0} { + set thisline {} ; continue + } + if {[string index $line 0] eq "#"} { + set thisline {} ; continue + } + try { + # Ignore contditionals + if {[regexp "if.*catch.*package.*Tcl.*return" $thisline]} continue + if {[regexp "if.*package.*vsatisfies.*package.*provide.*return" $thisline]} continue + if {![regexp "package.*ifneeded" $thisline]} { + # This package index contains arbitrary code + # source instead of trying to add it to the master + # package index + return {source [file join $dir pkgIndex.tcl]} + } + append buffer $thisline \n + } on error {err opts} { + puts *** + puts "GOOF: $pkgidxfile" + puts $line + puts $err + puts [dict get $opts -errorinfo] + puts *** + } finally { + set thisline {} + } + } + return $buffer +} + + +proc ::practcl::_pkgindex_path_subdir {path} { + set result {} + foreach subpath [glob -nocomplain [file join $path *]] { + if {[file isdirectory $subpath]} { + lappend result $subpath {*}[_pkgindex_path_subdir $subpath] + } + } + return $result +} +### +# Index all paths given as though they will end up in the same +# virtual file system +### +proc ::practcl::pkgindex_path args { + set stack {} + set buffer { +lappend ::PATHSTACK $dir + } + foreach base $args { + set base [file normalize $base] + set paths [::practcl::_pkgindex_path_subdir $base] + set i [string length $base] + # Build a list of all of the paths + foreach path $paths { + if {$path eq $base} continue + set path_indexed($path) 0 + } + set path_indexed($base) 1 + set path_indexed([file join $base boot tcl]) 1 + #set path_index([file join $base boot tk]) 1 + + foreach path $paths { + if {$path_indexed($path)} continue + set thisdir [file_relative $base $path] + #set thisdir [string range $path $i+1 end] + set idxbuf [::practcl::_pkgindex_directory $path] + if {[string length $idxbuf]} { + incr path_indexed($path) + append buffer "set dir \[set PKGDIR \[file join \[lindex \$::PATHSTACK end\] $thisdir\]\]" \n + append buffer [string map {$dir $PKGDIR} [string trimright $idxbuf]] \n + } + } + } + append buffer { +set dir [lindex $::PATHSTACK end] +set ::PATHSTACK [lrange $::PATHSTACK 0 end-1] +} + return $buffer +} + +### +# topic: 64319f4600fb63c82b2258d908f9d066 +# description: Script to build the VFS file system +### +proc ::practcl::installDir {d1 d2} { + + puts [format {%*sCreating %s} [expr {4 * [info level]}] {} [file tail $d2]] + file delete -force -- $d2 + file mkdir $d2 + + foreach ftail [glob -directory $d1 -nocomplain -tails *] { + set f [file join $d1 $ftail] + if {[file isdirectory $f] && [string compare CVS $ftail]} { + installDir $f [file join $d2 $ftail] + } elseif {[file isfile $f]} { + file copy -force $f [file join $d2 $ftail] + if {$::tcl_platform(platform) eq {unix}} { + file attributes [file join $d2 $ftail] -permissions 0644 + } else { + file attributes [file join $d2 $ftail] -readonly 1 + } + } + } + + if {$::tcl_platform(platform) eq {unix}} { + file attributes $d2 -permissions 0755 + } else { + file attributes $d2 -readonly 1 + } +} + +proc ::practcl::copyDir {d1 d2} { + #puts [list $d1 -> $d2] + #file delete -force -- $d2 + file mkdir $d2 + + foreach ftail [glob -directory $d1 -nocomplain -tails *] { + set f [file join $d1 $ftail] + if {[file isdirectory $f] && [string compare CVS $ftail]} { + copyDir $f [file join $d2 $ftail] + } elseif {[file isfile $f]} { + file copy -force $f [file join $d2 $ftail] + } + } +} + +::oo::class create ::practcl::metaclass { + superclass ::oo::object + + method script script { + eval $script + } + + method source filename { + source $filename + } + + method initialize {} {} + + method define {submethod args} { + my variable define + switch $submethod { + dump { + return [array get define] + } + add { + set field [lindex $args 0] + if {![info exists define($field)]} { + set define($field) {} + } + foreach arg [lrange $args 1 end] { + if {$arg ni $define($field)} { + lappend define($field) $arg + } + } + return $define($field) + } + remove { + set field [lindex $args 0] + if {![info exists define($field)]} { + return + } + set rlist [lrange $args 1 end] + set olist $define($field) + set nlist {} + foreach arg $olist { + if {$arg in $rlist} continue + lappend nlist $arg + } + set define($field) $nlist + return $nlist + } + exists { + set field [lindex $args 0] + return [info exists define($field)] + } + getnull - + get - + cget { + set field [lindex $args 0] + if {[info exists define($field)]} { + return $define($field) + } + return [lindex $args 1] + } + set { + if {[llength $args]==1} { + set arglist [lindex $args 0] + } else { + set arglist $args + } + array set define $arglist + if {[dict exists $arglist class]} { + my select + } + } + default { + array $submethod define {*}$args + } + } + } + + method graft args { + my variable organs + if {[llength $args] == 1} { + error "Need two arguments" + } + set object {} + foreach {stub object} $args { + dict set organs $stub $object + oo::objdefine [self] forward <${stub}> $object + oo::objdefine [self] export <${stub}> + } + return $object + } + + method organ {{stub all}} { + my variable organs + if {![info exists organs]} { + return {} + } + if { $stub eq "all" } { + return $organs + } + if {[dict exists $organs $stub]} { + return [dict get $organs $stub] + } + } + + method link {command args} { + my variable links + switch $command { + object { + foreach obj $args { + foreach linktype [$obj linktype] { + my link add $linktype $obj + } + } + } + add { + ### + # Add a link to an object that was externally created + ### + if {[llength $args] ne 2} { error "Usage: link add LINKTYPE OBJECT"} + lassign $args linktype object + if {[info exists links($linktype)] && $object in $links($linktype)} { + return + } + lappend links($linktype) $object + } + remove { + set object [lindex $args 0] + if {[llength $args]==1} { + set ltype * + } else { + set ltype [lindex $args 1] + } + foreach {linktype elements} [array get links $ltype] { + if {$object in $elements} { + set nlist {} + foreach e $elements { + if { $object ne $e } { lappend nlist $e } + } + set links($linktype) $nlist + } + } + } + list { + if {[llength $args]==0} { + return [array get links] + } + if {[llength $args] != 1} { error "Usage: link list LINKTYPE"} + set linktype [lindex $args 0] + if {![info exists links($linktype)]} { + return {} + } + return $links($linktype) + } + dump { + return [array get links] + } + } + } + + method select {} { + my variable define + set class {} + if {[info exists define(class)]} { + if {[info command $define(class)] ne {}} { + set class $define(class) + } elseif {[info command ::practcl::$define(class)] ne {}} { + set class ::practcl::$define(class) + } else { + switch $define(class) { + default { + set class ::practcl::object + } + } + } + } + if {$class ne {}} { + ::oo::objdefine [self] class $class + } + if {[::info exists define(oodefine)]} { + ::oo::objdefine [self] $define(oodefine) + unset define(oodefine) + } + } +} + +proc ::practcl::trigger {args} { + foreach name $args { + if {[dict exists $::make_objects $name]} { + [dict get $::make_objects $name] triggers + } + } +} + +proc ::practcl::depends {args} { + foreach name $args { + if {[dict exists $::make_objects $name]} { + [dict get $::make_objects $name] check + } + } +} + +proc ::practcl::target {name info} { + set obj [::practcl::target_obj new $name $info] + dict set ::make_objects $name $obj + if {[dict exists $info aliases]} { + foreach item [dict get $info aliases] { + if {![dict exists $::make_objects $item]} { + dict set ::make_objects $item $obj + } + } + } + set ::make($name) 0 + set ::trigger($name) 0 + set filename [$obj define get filename] + if {$filename ne {}} { + set ::target($name) $filename + } +} + +### Batch Tasks + +namespace eval ::practcl::build {} + +## method DEFS +# This method populates 4 variables: +# name - The name of the package +# version - The version of the package +# defs - C flags passed to the compiler +# includedir - A list of paths to feed to the compiler for finding headers +# +proc ::practcl::build::DEFS {PROJECT DEFS namevar versionvar defsvar} { + upvar 1 $namevar name $versionvar version NAME NAME $defsvar defs + set name [string tolower [${PROJECT} define get name [${PROJECT} define get pkg_name]]] + set NAME [string toupper $name] + set version [${PROJECT} define get version [${PROJECT} define get pkg_vers]] + if {$version eq {}} { + set version 0.1a + } + set defs {} + append defs " -DPACKAGE_NAME=\"${name}\" -DPACKAGE_VERSION=\"${version}\"" + append defs " -DPACKAGE_TARNAME=\"${name}\" -DPACKAGE_STRING=\"${name}\x5c\x20${version}\"" + set NAME [string toupper $name] + set idx 0 + set count 0 + while {$idx>=0} { + set ndx [string first " -D" $DEFS $idx+1] + set item [string range $DEFS $idx $ndx] + set item [string trim $item] + set item [string trimleft $item -D] + if {[string range $item 0 7] eq "PACKAGE_"} { + set idx $ndx + continue + } + set eqidx [string first = $item ] + if {$eqidx < 0} { + append defs { } $item + set idx $ndx + continue + } + + set field [string range $item 0 [expr {$eqidx-1}]] + set value [string range $item [expr {$eqidx+1}] end] + set emap {} + lappend emap \x5c \x5c\x5c \x20 \x5c\x20 \x22 \x5c\x22 \x28 \x5c\x28 \x29 \x5c\x29 + if {[string is integer -strict $value]} { + append defs " -D${field}=$value" + } else { + append defs " -D${field}=[string map $emap $value]" + } + set idx $ndx + } + return $defs +} + +proc ::practcl::build::tclkit_main {PROJECT PKG_OBJS} { + ### + # Build static package list + ### + set statpkglist {} + dict set statpkglist Tk {autoload 0} + puts [list TCLKIT MAIN $PROJECT] + + foreach {ofile info} [${PROJECT} compile-products] { + puts [list * PROD $ofile $info] + if {![dict exists $info object]} continue + set cobj [dict get $info object] + foreach {pkg info} [$cobj static-packages] { + dict set statpkglist $pkg $info + } + } + foreach cobj [list {*}${PKG_OBJS} $PROJECT] { + puts [list * PROG $cobj] + foreach {pkg info} [$cobj static-packages] { + puts [list * PKG $pkg $info] + dict set statpkglist $pkg $info + } + } + + set result {} + $PROJECT include {} + $PROJECT include {"tclInt.h"} + $PROJECT include {"tclFileSystem.h"} + $PROJECT include {} + $PROJECT include {} + $PROJECT include {} + $PROJECT include {} + $PROJECT include {} + + $PROJECT code header { +#ifndef MODULE_SCOPE +# define MODULE_SCOPE extern +#endif + +/* +** Provide a dummy Tcl_InitStubs if we are using this as a static +** library. +*/ +#ifndef USE_TCL_STUBS +# undef Tcl_InitStubs +# define Tcl_InitStubs(a,b,c) TCL_VERSION +#endif +#define STATIC_BUILD 1 +#undef USE_TCL_STUBS + +/* Make sure the stubbed variants of those are never used. */ +#undef Tcl_ObjSetVar2 +#undef Tcl_NewStringObj +#undef Tk_Init +#undef Tk_MainEx +#undef Tk_SafeInit +} + + # Build an area of the file for #define directives and + # function declarations + set define {} + set mainhook [$PROJECT define get TCL_LOCAL_MAIN_HOOK Tclkit_MainHook] + set mainfunc [$PROJECT define get TCL_LOCAL_APPINIT Tclkit_AppInit] + set mainscript [$PROJECT define get main.tcl main.tcl] + set vfsroot [$PROJECT define get vfsroot zipfs:/app] + set vfs_main "${vfsroot}/${mainscript}" + set vfs_tcl_library "${vfsroot}/boot/tcl" + set vfs_tk_library "${vfsroot}/boot/tk" + + set map {} + foreach var { + vfsroot mainhook mainfunc vfs_main vfs_tcl_library vfs_tk_library + } { + dict set map %${var}% [set $var] + } + set preinitscript { +set ::odie(boot_vfs) {%vfsroot%} +set ::SRCDIR {%vfsroot%} +if {[file exists {%vfs_tcl_library%}]} { + set ::tcl_library {%vfs_tcl_library%} + set ::auto_path {} +} +if {[file exists {%vfs_tk_library%}]} { + set ::tk_library {%vfs_tk_library%} +} +} ; # Preinitscript + + set zvfsboot { +/* + * %mainhook% -- + * Performs the argument munging for the shell + */ + } + ::practcl::cputs zvfsboot { + CONST char *archive; + Tcl_FindExecutable(*argv[0]); + archive=Tcl_GetNameOfExecutable(); + + Tclzipfs_Init(NULL); + } + # We have to initialize the virtual filesystem before calling + # Tcl_Init(). Otherwise, Tcl_Init() will not be able to find + # its startup script files. + $PROJECT include {"tclZipfs.h"} + + ::practcl::cputs zvfsboot " if(!TclZipfsMount(NULL, archive, \"%vfsroot%\", NULL)) \x7B " + ::practcl::cputs zvfsboot { + Tcl_Obj *vfsinitscript; + vfsinitscript=Tcl_NewStringObj("%vfs_main%",-1); + Tcl_IncrRefCount(vfsinitscript); + if(Tcl_FSAccess(vfsinitscript,F_OK)==0) { + /* Startup script should be set before calling Tcl_AppInit */ + Tcl_SetStartupScript(vfsinitscript,NULL); + } + } + ::practcl::cputs zvfsboot " TclSetPreInitScript([::practcl::tcl_to_c $preinitscript])\;" + ::practcl::cputs zvfsboot " \x7D else \x7B" + ::practcl::cputs zvfsboot " TclSetPreInitScript([::practcl::tcl_to_c { +foreach path { + ../tcl +} { + set p [file join $path library init.tcl] + if {[file exists [file join $path library init.tcl]]} { + set ::tcl_library [file normalize [file join $path library]] + break + } +} +foreach path { + ../tk +} { + if {[file exists [file join $path library tk.tcl]]} { + set ::tk_library [file normalize [file join $path library]] + break + } +} +}])\;" + + ::practcl::cputs zvfsboot " \x7D" + + ::practcl::cputs zvfsboot " return TCL_OK;" + + if {[$PROJECT define get os] eq "windows"} { + set header {int %mainhook%(int *argc, TCHAR ***argv)} + } else { + set header {int %mainhook%(int *argc, char ***argv)} + } + $PROJECT c_function [string map $map $header] [string map $map $zvfsboot] + + practcl::cputs appinit "int %mainfunc%(Tcl_Interp *interp) \x7B" + + # Build AppInit() + set appinit {} + practcl::cputs appinit { + if ((Tcl_Init)(interp) == TCL_ERROR) { + return TCL_ERROR; + } +} + set main_init_script {} + + foreach {statpkg info} $statpkglist { + set initfunc {} + if {[dict exists $info initfunc]} { + set initfunc [dict get $info initfunc] + } + if {$initfunc eq {}} { + set initfunc [string totitle ${statpkg}]_Init + } + # We employ a NULL to prevent the package system from thinking the + # package is actually loaded into the interpreter + $PROJECT code header "extern Tcl_PackageInitProc $initfunc\;\n" + set script [list package ifneeded $statpkg [dict get $info version] [list ::load {} $statpkg]] + append main_init_script \n [list set ::kitpkg(${statpkg}) $script] + if {[dict get $info autoload]} { + ::practcl::cputs appinit " if(${initfunc}(interp)) return TCL_ERROR\;" + ::practcl::cputs appinit " Tcl_StaticPackage(interp,\"$statpkg\",$initfunc,NULL)\;" + } else { + ::practcl::cputs appinit "\n Tcl_StaticPackage(NULL,\"$statpkg\",$initfunc,NULL)\;" + append main_init_script \n $script + } + } + append main_init_script \n { +if {[file exists [file join $::SRCDIR packages.tcl]]} { + #In a wrapped exe, we don't go out to the environment + set dir $::SRCDIR + source [file join $::SRCDIR packages.tcl] +} +# Specify a user-specific startup file to invoke if the application +# is run interactively. Typically the startup file is "~/.apprc" +# where "app" is the name of the application. If this line is deleted +# then no user-specific startup file will be run under any conditions. + } + append main_init_script \n [list set tcl_rcFileName [$PROJECT define get tcl_rcFileName ~/.tclshrc]] + practcl::cputs appinit " Tcl_Eval(interp,[::practcl::tcl_to_c $main_init_script]);" + practcl::cputs appinit { return TCL_OK;} + $PROJECT c_function [string map $map "int %mainfunc%(Tcl_Interp *interp)"] [string map $map $appinit] +} + +proc ::practcl::build::compile-sources {PROJECT COMPILE {CPPCOMPILE {}}} { + set EXTERN_OBJS {} + set OBJECTS {} + set result {} + set builddir [$PROJECT define get builddir] + file mkdir [file join $builddir objs] + set debug [$PROJECT define get debug 0] + if {$CPPCOMPILE eq {}} { + set CPPCOMPILE $COMPILE + } + set task [${PROJECT} compile-products] + ### + # Compile the C sources + ### + foreach {ofile info} $task { + dict set task $ofile done 0 + if {[dict exists $info external] && [dict get $info external]==1} { + dict set task $ofile external 1 + } else { + dict set task $ofile external 0 + } + if {[dict exists $info library]} { + dict set task $ofile done 1 + continue + } + # Products with no cfile aren't compiled + if {![dict exists $info cfile] || [set cfile [dict get $info cfile]] eq {}} { + dict set task $ofile done 1 + continue + } + set cfile [dict get $info cfile] + set ofilename [file join $builddir objs [file tail $ofile]] + if {$debug} { + set ofilename [file join $builddir objs [file rootname [file tail $ofile]].debug.o] + } + dict set task $ofile filename $ofilename + if {[file exists $ofilename] && [file mtime $ofilename]>[file mtime $cfile]} { + lappend result $ofilename + dict set task $ofile done 1 + continue + } + if {![dict exist $info command]} { + if {[file extension $cfile] in {.c++ .cpp}} { + set cmd $CPPCOMPILE + } else { + set cmd $COMPILE + } + if {[dict exists $info extra]} { + append cmd " [dict get $info extra]" + } + append cmd " -c $cfile" + append cmd " -o $ofilename" + dict set task $ofile command $cmd + } + } + set completed 0 + while {$completed==0} { + set completed 1 + foreach {ofile info} $task { + set waiting {} + if {[dict exists $info done] && [dict get $info done]} continue + if {[dict exists $info depend]} { + foreach file [dict get $info depend] { + if {[dict exists $task $file command] && [dict exists $task $file done] && [dict get $task $file done] != 1} { + set waiting $file + break + } + } + } + if {$waiting ne {}} { + set completed 0 + puts "$ofile waiting for $waiting" + continue + } + if {[dict exists $info command]} { + set cmd [dict get $info command] + puts "$cmd" + exec {*}$cmd >&@ stdout + } + lappend result [dict get $info filename] + dict set task $ofile done 1 + } + } + return $result +} + +proc ::practcl::de_shell {data} { + set values {} + foreach flag {DEFS TCL_DEFS TK_DEFS} { + if {[dict exists $data $flag]} { + set value {} + foreach item [dict get $data $flag] { + append value " " [string map {{ } {\ }} $item] + } + dict set values $flag $value + } + } + set map {} + lappend map {${PKG_OBJECTS}} %LIBRARY_OBJECTS% + lappend map {$(PKG_OBJECTS)} %LIBRARY_OBJECTS% + lappend map {${PKG_STUB_OBJECTS}} %LIBRARY_STUB_OBJECTS% + lappend map {$(PKG_STUB_OBJECTS)} %LIBRARY_STUB_OBJECTS% + + lappend map %LIBRARY_NAME% [dict get $data name] + lappend map %LIBRARY_VERSION% [dict get $data version] + lappend map %LIBRARY_VERSION_NODOTS% [string map {. {}} [dict get $data version]] + if {[dict exists $data libprefix]} { + lappend map %LIBRARY_PREFIX% [dict get $data libprefix] + } else { + lappend map %LIBRARY_PREFIX% [dict get $data prefix] + } + foreach flag [dict keys $data] { + if {$flag in {TCL_DEFS TK_DEFS DEFS}} continue + + dict set map "%${flag}%" [dict get $data $flag] + dict set map "\$\{${flag}\}" [dict get $data $flag] + dict set map "\$\(${flag}\)" [dict get $data $flag] + dict set values $flag [dict get $data $flag] + #dict set map "\$\{${flag}\}" $proj($flag) + } + set changed 1 + while {$changed} { + set changed 0 + foreach {field value} $values { + if {$field in {TCL_DEFS TK_DEFS DEFS}} continue + dict with values {} + set newval [string map $map $value] + if {$newval eq $value} continue + set changed 1 + dict set values $field $newval + } + } + return $values +} + +proc ::practcl::build::Makefile {path PROJECT} { + array set proj [$PROJECT define dump] + set path $proj(builddir) + cd $path + set includedir . + #lappend includedir [::practcl::file_relative $path $proj(TCL_INCLUDES)] + lappend includedir [::practcl::file_relative $path [file normalize [file join $proj(TCL_SRC_DIR) generic]]] + lappend includedir [::practcl::file_relative $path [file normalize [file join $proj(srcdir) generic]]] + foreach include [$PROJECT generate-include-directory] { + set cpath [::practcl::file_relative $path [file normalize $include]] + if {$cpath ni $includedir} { + lappend includedir $cpath + } + } + set INCLUDES "-I[join $includedir " -I"]" + set NAME [string toupper $proj(name)] + set result {} + set products {} + set libraries {} + set thisline {} + ::practcl::cputs result "${NAME}_DEFS = $proj(DEFS)\n" + ::practcl::cputs result "${NAME}_INCLUDES = -I\"[join $includedir "\" -I\""]\"\n" + ::practcl::cputs result "${NAME}_COMPILE = \$(CC) \$(CFLAGS) \$(PKG_CFLAGS) \$(${NAME}_DEFS) \$(${NAME}_INCLUDES) \$(INCLUDES) \$(AM_CPPFLAGS) \$(CPPFLAGS) \$(AM_CFLAGS)" + ::practcl::cputs result "${NAME}_CPPCOMPILE = \$(CXX) \$(CFLAGS) \$(PKG_CFLAGS) \$(${NAME}_DEFS) \$(${NAME}_INCLUDES) \$(INCLUDES) \$(AM_CPPFLAGS) \$(CPPFLAGS) \$(AM_CFLAGS)" + + foreach {ofile info} [$PROJECT compile-products] { + dict set products $ofile $info + if {[dict exists $info library]} { +lappend libraries $ofile +continue + } + if {[dict exists $info depend]} { + ::practcl::cputs result "\n${ofile}: [dict get $info depend]" + } else { + ::practcl::cputs result "\n${ofile}:" + } + set cfile [dict get $info cfile] + if {[file extension $cfile] in {.c++ .cpp}} { + set cmd "\t\$\(${NAME}_CPPCOMPILE\)" + } else { + set cmd "\t\$\(${NAME}_COMPILE\)" + } + if {[dict exists $info extra]} { + append cmd " [dict get $info extra]" + } + append cmd " -c [dict get $info cfile] -o \$@\n\t" + ::practcl::cputs result $cmd + } + + set map {} + lappend map %LIBRARY_NAME% $proj(name) + lappend map %LIBRARY_VERSION% $proj(version) + lappend map %LIBRARY_VERSION_NODOTS% [string map {. {}} $proj(version)] + lappend map %LIBRARY_PREFIX% [$PROJECT define getnull libprefix] + + if {[string is true [$PROJECT define get SHARED_BUILD]]} { + set outfile [$PROJECT define get libfile] + } else { + set outfile [$PROJECT shared_library] + } + $PROJECT define set shared_library $outfile + ::practcl::cputs result " +${NAME}_SHLIB = $outfile +${NAME}_OBJS = [dict keys $products] +" + + #lappend map %OUTFILE% {\[$]@} + lappend map %OUTFILE% $outfile + lappend map %LIBRARY_OBJECTS% "\$(${NAME}_OBJS)" + ::practcl::cputs result "$outfile: \$(${NAME}_OBJS)" + ::practcl::cputs result "\t[string map $map [$PROJECT define get PRACTCL_SHARED_LIB]]" + if {[$PROJECT define get PRACTCL_VC_MANIFEST_EMBED_DLL] ni {: {}}} { + ::practcl::cputs result "\t[string map $map [$PROJECT define get PRACTCL_VC_MANIFEST_EMBED_DLL]]" + } + ::practcl::cputs result {} + if {[string is true [$PROJECT define get SHARED_BUILD]]} { + #set outfile [$PROJECT static_library] + set outfile $proj(name).a + } else { + set outfile [$PROJECT define get libfile] + } + $PROJECT define set static_library $outfile + dict set map %OUTFILE% $outfile + ::practcl::cputs result "$outfile: \$(${NAME}_OBJS)" + ::practcl::cputs result "\t[string map $map [$PROJECT define get PRACTCL_STATIC_LIB]]" + ::practcl::cputs result {} + return $result +} + +### +# Produce a dynamic library +### +proc ::practcl::build::library {outfile PROJECT} { + array set proj [$PROJECT define dump] + set path $proj(builddir) + cd $path + set includedir . + #lappend includedir [::practcl::file_relative $path $proj(TCL_INCLUDES)] + lappend includedir [::practcl::file_relative $path [file normalize [file join $proj(TCL_SRC_DIR) generic]]] + lappend includedir [::practcl::file_relative $path [file normalize [file join $proj(srcdir) generic]]] + if {[$PROJECT define get tk 0]} { + lappend includedir [::practcl::file_relative $path [file normalize [file join $proj(TK_SRC_DIR) generic]]] + lappend includedir [::practcl::file_relative $path [file normalize [file join $proj(TK_SRC_DIR) ttk]]] + lappend includedir [::practcl::file_relative $path [file normalize [file join $proj(TK_SRC_DIR) xlib]]] + lappend includedir [::practcl::file_relative $path [file normalize $proj(TK_BIN_DIR)]] + } + foreach include [$PROJECT generate-include-directory] { + set cpath [::practcl::file_relative $path [file normalize $include]] + if {$cpath ni $includedir} { + lappend includedir $cpath + } + } + ::practcl::build::DEFS $PROJECT $proj(DEFS) name version defs + set NAME [string toupper $name] + set debug [$PROJECT define get debug 0] + set os [$PROJECT define get os] + + set INCLUDES "-I[join $includedir " -I"]" + if {$debug} { + set COMPILE "$proj(CC) $proj(CFLAGS_DEBUG) -ggdb \ +$proj(CFLAGS_WARNING) $INCLUDES $defs" + + if {[info exists proc(CXX)]} { + set COMPILECPP "$proj(CXX) $defs $INCLUDES $proj(CFLAGS_DEBUG) -ggdb \ + $proj(DEFS) $proj(CFLAGS_WARNING)" + } else { + set COMPILECPP $COMPILE + } + } else { + set COMPILE "$proj(CC) $proj(CFLAGS) $defs $INCLUDES " + + if {[info exists proc(CXX)]} { + set COMPILECPP "$proj(CXX) $defs $INCLUDES $proj(CFLAGS) $proj(DEFS)" + } else { + set COMPILECPP $COMPILE + } + } + + set products [compile-sources $PROJECT $COMPILE $COMPILECPP] + + set map {} + lappend map %LIBRARY_NAME% $proj(name) + lappend map %LIBRARY_VERSION% $proj(version) + lappend map %LIBRARY_VERSION_NODOTS% [string map {. {}} $proj(version)] + lappend map %OUTFILE% $outfile + lappend map %LIBRARY_OBJECTS% $products + lappend map {${CFLAGS}} "$proj(CFLAGS_DEFAULT) $proj(CFLAGS_WARNING)" + + if {[string is true [$PROJECT define get SHARED_BUILD 1]]} { + set cmd [$PROJECT define get PRACTCL_SHARED_LIB] + append cmd " [$PROJECT define get PRACTCL_LIBS]" + set cmd [string map $map $cmd] + puts $cmd + exec {*}$cmd >&@ stdout + if {[$PROJECT define get PRACTCL_VC_MANIFEST_EMBED_DLL] ni {: {}}} { + set cmd [string map $map [$PROJECT define get PRACTCL_VC_MANIFEST_EMBED_DLL]] + puts $cmd + exec {*}$cmd >&@ stdout + } + } else { + set cmd [string map $map [$PROJECT define get PRACTCL_STATIC_LIB]] + puts $cmd + exec {*}$cmd >&@ stdout + } +} + +### +# Produce a static executable +### +proc ::practcl::build::static-tclsh {outfile PROJECT} { + puts " BUILDING STATIC TCLSH " + set TCLOBJ [$PROJECT project TCLCORE] + set TKOBJ [$PROJECT project TKCORE] + set ODIEOBJ [$PROJECT project odie] + + set PKG_OBJS {} + foreach item [$PROJECT link list package] { + if {[string is true [$item define get static]]} { + lappend PKG_OBJS $item + } + } + array set TCL [$TCLOBJ config.sh] + array set TK [$TKOBJ config.sh] + set path [file dirname $outfile] + cd $path + ### + # For a static Tcl shell, we need to build all local sources + # with the same DEFS flags as the tcl core was compiled with. + # The DEFS produced by a TEA extension aren't intended to operate + # with the internals of a staticly linked Tcl + ### + ::practcl::build::DEFS $PROJECT $TCL(defs) name version defs + set debug [$PROJECT define get debug 0] + set NAME [string toupper $name] + set result {} + set libraries {} + set thisline {} + set OBJECTS {} + set EXTERN_OBJS {} + foreach obj $PKG_OBJS { + $obj compile + set config($obj) [$obj config.sh] + } + set os [$PROJECT define get os] + set TCLSRCDIR [$TCLOBJ define get srcroot] + set TKSRCDIR [$TKOBJ define get srcroot] + + set includedir . + foreach include [$TCLOBJ generate-include-directory] { + set cpath [::practcl::file_relative $path [file normalize $include]] + if {$cpath ni $includedir} { + lappend includedir $cpath + } + } + lappend includedir [::practcl::file_relative $path [file normalize ../tcl/compat/zlib]] + foreach include [$PROJECT generate-include-directory] { + set cpath [::practcl::file_relative $path [file normalize $include]] + if {$cpath ni $includedir} { + lappend includedir $cpath + } + } + + set INCLUDES "-I[join $includedir " -I"]" + if {$debug} { + set COMPILE "$TCL(cc) $TCL(shlib_cflags) $TCL(cflags_debug) -ggdb \ +$TCL(cflags_warning) $TCL(extra_cflags) $INCLUDES" + } else { + set COMPILE "$TCL(cc) $TCL(shlib_cflags) $TCL(cflags_optimize) \ +$TCL(cflags_warning) $TCL(extra_cflags) $INCLUDES" + } + append COMPILE " " $defs + lappend OBJECTS {*}[compile-sources $PROJECT $COMPILE $COMPILE] + + if {[${PROJECT} define get platform] eq "windows"} { + set RSOBJ [file join $path build tclkit.res.o] + set RCSRC [${PROJECT} define get kit_resource_file] + if {$RCSRC eq {} || ![file exists $RCSRC]} { + set RCSRC [file join $TKSRCDIR win rc wish.rc] + } + set cmd [list windres -o $RSOBJ -DSTATIC_BUILD] + set TCLSRC [file normalize $TCLSRCDIR] + set TKSRC [file normalize $TKSRCDIR] + + lappend cmd --include [::practcl::file_relative $path [file join $TCLSRC generic]] \ + --include [::practcl::file_relative $path [file join $TKSRC generic]] \ + --include [::practcl::file_relative $path [file join $TKSRC win]] \ + --include [::practcl::file_relative $path [file join $TKSRC win rc]] + foreach item [${PROJECT} define get resource_include] { + lappend cmd --include [::practcl::file_relative $path [file normalize $item]] + } + lappend cmd $RCSRC + doexec {*}$cmd + + lappend OBJECTS $RSOBJ + set LDFLAGS_CONSOLE {-mconsole -pipe -static-libgcc} + set LDFLAGS_WINDOW {-mwindows -pipe -static-libgcc} + } else { + set LDFLAGS_CONSOLE {} + set LDFLAGS_WINDOW {} + } + puts "***" + if {$debug} { + set cmd "$TCL(cc) $TCL(shlib_cflags) $TCL(cflags_debug) \ +$TCL(cflags_warning) $TCL(extra_cflags) $INCLUDES" + } else { + set cmd "$TCL(cc) $TCL(shlib_cflags) $TCL(cflags_optimize) \ +$TCL(cflags_warning) $TCL(extra_cflags) $INCLUDES" + } + append cmd " $OBJECTS" + append cmd " $EXTERN_OBJS " + # On OSX it is impossibly to generate a completely static + # executable + if {[$PROJECT define get TEACUP_OS] ne "macosx"} { + append cmd " -static " + } + parray TCL + if {$debug} { + if {$os eq "windows"} { + append cmd " -L${TCL(src_dir)}/win -ltcl86g" + append cmd " -L${TK(src_dir)}/win -ltk86g" + } else { + append cmd " -L${TCL(src_dir)}/unix -ltcl86g" + append cmd " -L${TK(src_dir)}/unix -ltk86g" + } + } else { + append cmd " $TCL(build_lib_spec) $TK(build_lib_spec)" + } + foreach obj $PKG_OBJS { + append cmd " [$obj linker-products $config($obj)]" + } + append cmd " $TCL(libs) $TK(libs)" + foreach obj $PKG_OBJS { + append cmd " [$obj linker-external $config($obj)]" + } + if {$debug} { + if {$os eq "windows"} { + append cmd " -L${TCL(src_dir)}/win ${TCL(stub_lib_flag)}" + append cmd " -L${TK(src_dir)}/win ${TK(stub_lib_flag)}" + } else { + append cmd " -L${TCL(src_dir)}/unix ${TCL(stub_lib_flag)}" + append cmd " -L${TK(src_dir)}/unix ${TK(stub_lib_flag)}" + } + } else { + append cmd " $TCL(build_stub_lib_spec)" + append cmd " $TK(build_stub_lib_spec)" + } + append cmd " -o $outfile $LDFLAGS_CONSOLE" + puts "LINK: $cmd" + exec {*}$cmd >&@ stdout +} + +::oo::class create ::practcl::target_obj { + superclass ::practcl::metaclass + + constructor {name info} { + my variable define triggered domake + set triggered 0 + set domake 0 + set define(name) $name + set data [uplevel 2 [list subst $info]] + array set define $data + my select + my initialize + } + + method do {} { + my variable domake + return $domake + } + + method check {} { + my variable needs_make domake + if {$domake} { + return 1 + } + if {[info exists needs_make]} { + return $needs_make + } + set needs_make 0 + foreach item [my define get depends] { + if {![dict exists $::make_objects $item]} continue + set depobj [dict get $::make_objects $item] + if {$depobj eq [self]} { + puts "WARNING [self] depends on itself" + continue + } + if {[$depobj check]} { + set needs_make 1 + } + } + if {!$needs_make} { + set filename [my define get filename] + if {$filename ne {} && ![file exists $filename]} { + set needs_make 1 + } + } + return $needs_make + } + + method triggers {} { + my variable triggered domake define + if {$triggered} { + return $domake + } + set triggered 1 + foreach item [my define get depends] { + puts [list $item [dict exists $::make_objects $item]] + if {![dict exists $::make_objects $item]} continue + set depobj [dict get $::make_objects $item] + if {$depobj eq [self]} { + puts "WARNING [self] triggers itself" + continue + } else { + set r [$depobj check] + puts [list $depobj check $r] + if {$r} { + puts [list $depobj TRIGGER] + $depobj triggers + } + } + } + if {[info exists ::make($define(name))] && $::make($define(name))} { + return + } + set ::make($define(name)) 1 + ::practcl::trigger {*}[my define get triggers] + } +} + + +### +# Define the metaclass +### +::oo::class create ::practcl::object { + superclass ::practcl::metaclass + + constructor {parent args} { + my variable links define + set organs [$parent child organs] + my graft {*}$organs + array set define $organs + array set define [$parent child define] + array set links {} + if {[llength $args]==1 && [file exists [lindex $args 0]]} { + my InitializeSourceFile [lindex $args 0] + } elseif {[llength $args] == 1} { + set data [uplevel 1 [list subst [lindex $args 0]]] + array set define $data + my select + my initialize + } else { + array set define [uplevel 1 [list subst $args]] + my select + my initialize + } + } + + + method include_dir args { + my define add include_dir {*}$args + } + + method include_directory args { + my define add include_dir {*}$args + } + + method Collate_Source CWD {} + + + method child {method} { + return {} + } + + method InitializeSourceFile filename { + my define set filename $filename + set class {} + switch [file extension $filename] { + .tcl { + set class ::practcl::dynamic + } + .h { + set class ::practcl::cheader + } + .c { + set class ::practcl::csource + } + .ini { + switch [file tail $filename] { + module.ini { + set class ::practcl::module + } + library.ini { + set class ::practcl::subproject + } + } + } + .so - + .dll - + .dylib - + .a { + set class ::practcl::clibrary + } + } + if {$class ne {}} { + oo::objdefine [self] class $class + my initialize + } + } + + method add args { + my variable links + set object [::practcl::object new [self] {*}$args] + foreach linktype [$object linktype] { + lappend links($linktype) $object + } + return $object + } + + method go {} { + debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] + my variable links + foreach {linktype objs} [array get links] { + foreach obj $objs { + $obj go + } + } + debug [list /[self] [self method] [self class]] + } + + method code {section body} { + my variable code + ::practcl::cputs code($section) $body + } + + method Ofile filename { + set lpath [my define get localpath] + if {$lpath eq {}} { + set lpath [my define get name] + } + return ${lpath}_[file rootname [file tail $filename]].o + } + + method compile-products {} { + set filename [my define get filename] + set result {} + if {$filename ne {}} { + if {[my define exists ofile]} { + set ofile [my define get ofile] + } else { + set ofile [my Ofile $filename] + my define set ofile $ofile + } + lappend result $ofile [list cfile $filename extra [my define get extra] external [string is true -strict [my define get external]] object [self]] + } + foreach item [my link list subordinate] { + lappend result {*}[$item compile-products] + } + return $result + } + + method generate-include-directory {} { + debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] + set result [my define get include_dir] + foreach obj [my link list product] { + foreach path [$obj generate-include-directory] { + lappend result $path + } + } + return $result + } + + method generate-debug {{spaces {}}} { + set result {} + ::practcl::cputs result "$spaces[list [self] [list class [info object class [self]] filename [my define get filename]] links [my link list]]" + foreach item [my link list subordinate] { + practcl::cputs result [$item generate-debug "$spaces "] + } + return $result + } + + # Empty template methods + method generate-cheader {} { + debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] + my variable code cfunct cstruct methods tcltype tclprocs + set result {} + if {[info exists code(header)]} { + ::practcl::cputs result $code(header) + } + foreach obj [my link list product] { + # Exclude products that will generate their own C files + if {[$obj define get output_c] ne {}} continue + ::practcl::cputs result "/* BEGIN [$obj define get filename] generate-cheader */" + ::practcl::cputs result [$obj generate-cheader] + ::practcl::cputs result "/* END [$obj define get filename] generate-cheader */" + } + debug [list cfunct [info exists cfunct]] + if {[info exists cfunct]} { + foreach {funcname info} $cfunct { + if {[dict get $info public]} continue + ::practcl::cputs result "[dict get $info header]\;" + } + } + debug [list tclprocs [info exists tclprocs]] + if {[info exists tclprocs]} { + foreach {name info} $tclprocs { + if {[dict exists $info header]} { + ::practcl::cputs result "[dict get $info header]\;" + } + } + } + debug [list methods [info exists methods] [my define get cclass]] + + if {[info exists methods]} { + set thisclass [my define get cclass] + foreach {name info} $methods { + if {[dict exists $info header]} { + ::practcl::cputs result "[dict get $info header]\;" + } + } + # Add the initializer wrapper for the class + ::practcl::cputs result "static int ${thisclass}_OO_Init(Tcl_Interp *interp)\;" + } + return $result + } + + method generate-public-define {} { + debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] + my variable code + set result {} + if {[info exists code(public-define)]} { + ::practcl::cputs result $code(public-define) + } + set result [::practcl::_tagblock $result c [my define get filename]] + foreach mod [my link list product] { + ::practcl::cputs result [$mod generate-public-define] + } + return $result + } + + method generate-public-macro {} { + debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] + my variable code + set result {} + if {[info exists code(public-macro)]} { + ::practcl::cputs result $code(public-macro) + } + set result [::practcl::_tagblock $result c [my define get filename]] + foreach mod [my link list product] { + ::practcl::cputs result [$mod generate-public-macro] + } + return $result + } + + method generate-public-typedef {} { + debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] + my variable code cstruct + set result {} + if {[info exists code(public-typedef)]} { + ::practcl::cputs result $code(public-typedef) + } + if {[info exists cstruct]} { + # Add defintion for native c data structures + foreach {name info} $cstruct { + ::practcl::cputs result "typedef struct $name ${name}\;" + if {[dict exists $info aliases]} { + foreach n [dict get $info aliases] { + ::practcl::cputs result "typedef struct $name ${n}\;" + } + } + } + } + set result [::practcl::_tagblock $result c [my define get filename]] + foreach mod [my link list product] { + ::practcl::cputs result [$mod generate-public-typedef] + } + return $result + } + + method generate-public-structure {} { + debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] + my variable code cstruct + set result {} + if {[info exists code(public-structure)]} { + ::practcl::cputs result $code(public-structure) + } + if {[info exists cstruct]} { + foreach {name info} $cstruct { + if {[dict exists $info comment]} { + ::practcl::cputs result [dict get $info comment] + } + ::practcl::cputs result "struct $name \{[dict get $info body]\}\;" + } + } + set result [::practcl::_tagblock $result c [my define get filename]] + foreach mod [my link list product] { + ::practcl::cputs result [$mod generate-public-structure] + } + return $result + } + method generate-public-headers {} { + debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] + my variable code tcltype + set result {} + if {[info exists code(public-header)]} { + ::practcl::cputs result $code(public-header) + } + if {[info exists tcltype]} { + foreach {type info} $tcltype { + if {![dict exists $info cname]} { + set cname [string tolower ${type}]_tclobjtype + dict set tcltype $type cname $cname + } else { + set cname [dict get $info cname] + } + ::practcl::cputs result "extern const Tcl_ObjType $cname\;" + } + } + if {[info exists code(public)]} { + ::practcl::cputs result $code(public) + } + set result [::practcl::_tagblock $result c [my define get filename]] + foreach mod [my link list product] { + ::practcl::cputs result [$mod generate-public-headers] + } + return $result + } + + method generate-stub-function {} { + debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] + my variable code cfunct tcltype + set result {} + foreach mod [my link list product] { + foreach {funct def} [$mod generate-stub-function] { + dict set result $funct $def + } + } + if {[info exists cfunct]} { + foreach {funcname info} $cfunct { + if {![dict get $info export]} continue + dict set result $funcname [dict get $info header] + } + } + return $result + } + + method generate-public-function {} { + debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] + my variable code cfunct tcltype + set result {} + + if {[my define get initfunc] ne {}} { + ::practcl::cputs result "int [my define get initfunc](Tcl_Interp *interp);" + } + if {[info exists cfunct]} { + foreach {funcname info} $cfunct { + if {![dict get $info public]} continue + ::practcl::cputs result "[dict get $info header]\;" + } + } + set result [::practcl::_tagblock $result c [my define get filename]] + foreach mod [my link list product] { + ::practcl::cputs result [$mod generate-public-function] + } + return $result + } + + method generate-public-includes {} { + debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] + set includes {} + foreach item [my define get public-include] { + if {$item ni $includes} { + lappend includes $item + } + } + foreach mod [my link list product] { + foreach item [$mod generate-public-includes] { + if {$item ni $includes} { + lappend includes $item + } + } + } + return $includes + } + method generate-public-verbatim {} { + debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] + set includes {} + foreach item [my define get public-verbatim] { + if {$item ni $includes} { + lappend includes $item + } + } + foreach mod [my link list subordinate] { + foreach item [$mod generate-public-verbatim] { + if {$item ni $includes} { + lappend includes $item + } + } + } + return $includes + } + ### + # This methods generates the contents of an amalgamated .h file + # which describes the public API of this module + ### + method generate-h {} { + debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] + set result {} + set includes [my generate-public-includes] + foreach inc $includes { + if {[string index $inc 0] ni {< \"}} { + ::practcl::cputs result "#include \"$inc\"" + } else { + ::practcl::cputs result "#include $inc" + } + } + foreach file [my generate-public-verbatim] { + ::practcl::cputs result "/* BEGIN $file */" + ::practcl::cputs result [::practcl::cat $file] + ::practcl::cputs result "/* END $file */" + } + foreach method { + generate-public-define + generate-public-macro + generate-public-typedef + generate-public-structure + generate-public-headers + generate-public-function + } { + ::practcl::cputs result "/* BEGIN SECTION $method */" + ::practcl::cputs result [my $method] + ::practcl::cputs result "/* END SECTION $method */" + } + return $result + } + + ### + # This methods generates the contents of an amalgamated .c file + # which implements the loader for a batch of tools + ### + method generate-c {} { + debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] + set result { +/* This file was generated by practcl */ + } + set includes {} + lappend headers + if {[my define get tk 0]} { + lappend headers + } + lappend headers {*}[my define get include] + if {[my define get output_h] ne {}} { + lappend headers "\"[my define get output_h]\"" + } + foreach mod [my link list product] { + # Signal modules to formulate final implementation + $mod go + } + foreach mod [my link list dynamic] { + foreach inc [$mod define get include] { + if {$inc ni $headers} { + lappend headers $inc + } + } + } + foreach inc $headers { + if {[string index $inc 0] ni {< \"}} { + ::practcl::cputs result "#include \"$inc\"" + } else { + ::practcl::cputs result "#include $inc" + } + } + foreach {method} { + generate-cheader + generate-cstruct + generate-constant + generate-cfunct + generate-cmethod + } { + ::practcl::cputs result "/* BEGIN $method [my define get filename] */" + ::practcl::cputs result [my $method] + ::practcl::cputs result "/* END $method [my define get filename] */" + } + debug [list /[self] [self method] [self class] -- [my define get filename] [info object class [self]]] + return $result + } + + + method generate-loader {} { + debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] + set result {} + if {[my define get initfunc] eq {}} return + ::practcl::cputs result " +extern int DLLEXPORT [my define get initfunc]( Tcl_Interp *interp ) \{" + ::practcl::cputs result { + /* Initialise the stubs tables. */ + #ifdef USE_TCL_STUBS + if (Tcl_InitStubs(interp, "8.6", 0)==NULL) return TCL_ERROR; + if (TclOOInitializeStubs(interp, "1.0") == NULL) return TCL_ERROR; +} + if {[my define get tk 0]} { + ::practcl::cputs result { if (Tk_InitStubs(interp, "8.6", 0)==NULL) return TCL_ERROR;} + } + ::practcl::cputs result { #endif} + set TCLINIT [my generate-tcl] + ::practcl::cputs result " if(Tcl_Eval(interp,[::practcl::tcl_to_c $TCLINIT])) return TCL_ERROR ;" + foreach item [my link list product] { + if {[$item define get output_c] ne {}} { + ::practcl::cputs result [$item generate-cinit-external] + } else { + ::practcl::cputs result [$item generate-cinit] + } + } + if {[my define exists pkg_name]} { + ::practcl::cputs result " if (Tcl_PkgProvide(interp, \"[my define get pkg_name [my define get name]]\" , \"[my define get pkg_vers [my define get version]]\" )) return TCL_ERROR\;" + } + ::practcl::cputs result " return TCL_OK\;\n\}\n" + return $result + } + + ### + # This methods generates any Tcl script file + # which is required to pre-initialize the C library + ### + method generate-tcl {} { + debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] + set result {} + my variable code + if {[info exists code(tcl)]} { + ::practcl::cputs result $code(tcl) + } + set result [::practcl::_tagblock $result tcl [my define get filename]] + foreach mod [my link list product] { + ::practcl::cputs result [$mod generate-tcl] + } + return $result + } + + method static-packages {} { + set result [my define get static_packages] + set statpkg [my define get static_pkg] + set initfunc [my define get initfunc] + if {$initfunc ne {}} { + set pkg_name [my define get pkg_name] + if {$pkg_name ne {}} { + dict set result $pkg_name initfunc $initfunc + dict set result $pkg_name version [my define get version [my define get pkg_vers]] + dict set result $pkg_name autoload [my define get autoload 0] + } + } + foreach item [my link list subordinate] { + foreach {pkg info} [$item static-packages] { + dict set result $pkg $info + } + } + return $result + } + + method target {method args} { + switch $method { + is_unix { return [expr {$::tcl_platform(platform) eq "unix"}] } + } + } + +} + +::oo::class create ::practcl::product { + superclass ::practcl::object + + method linktype {} { + return {subordinate product} + } + + method include header { + my define add include $header + } + + method cstructure {name definition {argdat {}}} { + my variable cstruct + dict set cstruct $name body $definition + foreach {f v} $argdat { + dict set cstruct $name $f $v + } + } + + method generate-cinit {} { + debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] + my variable code + set result {} + if {[info exists code(cinit)]} { + ::practcl::cputs result $code(cinit) + } + if {[my define get initfunc] ne {}} { + ::practcl::cputs result " if([my define get initfunc](interp)!=TCL_OK) return TCL_ERROR\;" + } + set result [::practcl::_tagblock $result c [my define get filename]] + foreach obj [my link list product] { + ::practcl::cputs result [$obj generate-cinit] + } + return $result + } +} + +### +# Dynamic blocks do not generate their own .c files, +# instead the contribute to the amalgamation +# of the main library file +### +::oo::class create ::practcl::dynamic { + superclass ::practcl::product + + # Retrieve any additional source files required + + method compile-products {} { + set filename [my define get output_c] + set result {} + if {$filename ne {}} { + if {[my define exists ofile]} { + set ofile [my define get ofile] + } else { + set ofile [my Ofile $filename] + my define set ofile $ofile + } + lappend result $ofile [list cfile $filename extra [my define get extra] external [string is true -strict [my define get external]]] + } else { + set filename [my define get cfile] + if {$filename ne {}} { + if {[my define exists ofile]} { + set ofile [my define get ofile] + } else { + set ofile [my Ofile $filename] + my define set ofile $ofile + } + lappend result $ofile [list cfile $filename extra [my define get extra] external [string is true -strict [my define get external]]] + } + } + foreach item [my link list subordinate] { + lappend result {*}[$item compile-products] + } + return $result + } + + method implement path { + my go + my Collate_Source $path + if {[my define get output_c] eq {}} return + set filename [file join $path [my define get output_c]] + my define set cfile $filename + set fout [open $filename w] + puts $fout [my generate-c] + puts $fout "extern int DLLEXPORT [my define get initfunc]( Tcl_Interp *interp ) \x7B" + puts $fout [my generate-cinit] + if {[my define get pkg_name] ne {}} { + puts $fout " Tcl_PkgProvide(interp, \"[my define get pkg_name]\", \"[my define get pkg_vers]\");" + } + puts $fout " return TCL_OK\;" + puts $fout "\x7D" + close $fout + } + + method initialize {} { + set filename [my define get filename] + if {$filename eq {}} { + return + } + if {[my define get name] eq {}} { + my define set name [file tail [file rootname $filename]] + } + if {[my define get localpath] eq {}} { + my define set localpath [my define get localpath]_[my define get name] + } + ::source $filename + } + + method linktype {} { + return {subordinate product dynamic} + } + + ### + # Populate const static data structures + ### + method generate-cstruct {} { + debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] + my variable code cstruct methods tcltype + set result {} + if {[info exists code(struct)]} { + ::practcl::cputs result $code(struct) + } + foreach obj [my link list dynamic] { + # Exclude products that will generate their own C files + if {[$obj define get output_c] ne {}} continue + ::practcl::cputs result [$obj generate-cstruct] + } + return $result + } + + method generate-constant {} { + debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] + set result {} + my variable code cstruct methods tcltype + if {[info exists code(constant)]} { + ::practcl::cputs result "/* [my define get filename] CONSTANT */" + ::practcl::cputs result $code(constant) + } + if {[info exists cstruct]} { + foreach {name info} $cstruct { + set map {} + lappend map @NAME@ $name + lappend map @MACRO@ GET[string toupper $name] + + if {[dict exists $info deleteproc]} { + lappend map @DELETEPROC@ [dict get $info deleteproc] + } else { + lappend map @DELETEPROC@ NULL + } + if {[dict exists $info cloneproc]} { + lappend map @CLONEPROC@ [dict get $info cloneproc] + } else { + lappend map @CLONEPROC@ NULL + } + ::practcl::cputs result [string map $map { +const static Tcl_ObjectMetadataType @NAME@DataType = { + TCL_OO_METADATA_VERSION_CURRENT, + "@NAME@", + @DELETEPROC@, + @CLONEPROC@ +}; +#define @MACRO@(OBJCONTEXT) (@NAME@ *) Tcl_ObjectGetMetadata(OBJCONTEXT,&@NAME@DataType) +}] + } + } + if {[info exists tcltype]} { + foreach {type info} $tcltype { + dict with info {} + ::practcl::cputs result "const Tcl_ObjType $cname = \{\n .freeIntRepProc = &${freeproc},\n .dupIntRepProc = &${dupproc},\n .updateStringProc = &${updatestringproc},\n .setFromAnyProc = &${setfromanyproc}\n\}\;" + } + } + + if {[info exists methods]} { + set mtypes {} + foreach {name info} $methods { + set callproc [dict get $info callproc] + set methodtype [dict get $info methodtype] + if {$methodtype in $mtypes} continue + lappend mtypes $methodtype + ### + # Build the data struct for this method + ### + ::practcl::cputs result "const static Tcl_MethodType $methodtype = \{" + ::practcl::cputs result " .version = TCL_OO_METADATA_VERSION_CURRENT,\n .name = \"$name\",\n .callProc = $callproc," + if {[dict exists $info deleteproc]} { + set deleteproc [dict get $info deleteproc] + } else { + set deleteproc NULL + } + if {$deleteproc ni { {} NULL }} { + ::practcl::cputs result " .deleteProc = $deleteproc," + } else { + ::practcl::cputs result " .deleteProc = NULL," + } + if {[dict exists $info cloneproc]} { + set cloneproc [dict get $info cloneproc] + } else { + set cloneproc NULL + } + if {$cloneproc ni { {} NULL }} { + ::practcl::cputs result " .cloneProc = $cloneproc\n\}\;" + } else { + ::practcl::cputs result " .cloneProc = NULL\n\}\;" + } + dict set methods $name methodtype $methodtype + } + } + foreach obj [my link list dynamic] { + # Exclude products that will generate their own C files + if {[$obj define get output_c] ne {}} continue + ::practcl::cputs result [$obj generate-constant] + } + return $result + } + + ### + # Generate code that provides subroutines called by + # Tcl API methods + ### + method generate-cfunct {} { + debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] + my variable code cfunct + set result {} + if {[info exists code(funct)]} { + ::practcl::cputs result $code(funct) + } + if {[info exists cfunct]} { + foreach {funcname info} $cfunct { + ::practcl::cputs result "[dict get $info header]\{[dict get $info body]\}\;" + } + } + foreach obj [my link list dynamic] { + # Exclude products that will generate their own C files + if {[$obj define get output_c] ne {}} { + continue + } + ::practcl::cputs result [$obj generate-cfunct] + } + return $result + } + + ### + # Generate code that provides implements Tcl API + # calls + ### + method generate-cmethod {} { + debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] + my variable code methods tclprocs + set result {} + if {[info exists code(method)]} { + ::practcl::cputs result $code(method) + } + + if {[info exists tclprocs]} { + foreach {name info} $tclprocs { + if {![dict exists $info body]} continue + set callproc [dict get $info callproc] + set header [dict get $info header] + set body [dict get $info body] + ::practcl::cputs result "${header} \{${body}\}" + } + } + + + if {[info exists methods]} { + set thisclass [my define get cclass] + foreach {name info} $methods { + if {![dict exists $info body]} continue + set callproc [dict get $info callproc] + set header [dict get $info header] + set body [dict get $info body] + ::practcl::cputs result "${header} \{${body}\}" + } + # Build the OO_Init function + ::practcl::cputs result "static int ${thisclass}_OO_Init(Tcl_Interp *interp) \{" + ::practcl::cputs result [string map [list @CCLASS@ $thisclass @TCLCLASS@ [my define get class]] { + /* + ** Build the "@TCLCLASS@" class + */ + Tcl_Obj* nameObj; /* Name of a class or method being looked up */ + Tcl_Object curClassObject; /* Tcl_Object representing the current class */ + Tcl_Class curClass; /* Tcl_Class representing the current class */ + + /* + * Find the "@TCLCLASS@" class, and attach an 'init' method to it. + */ + + nameObj = Tcl_NewStringObj("@TCLCLASS@", -1); + Tcl_IncrRefCount(nameObj); + if ((curClassObject = Tcl_GetObjectFromObj(interp, nameObj)) == NULL) { + Tcl_DecrRefCount(nameObj); + return TCL_ERROR; + } + Tcl_DecrRefCount(nameObj); + curClass = Tcl_GetObjectAsClass(curClassObject); +}] + if {[dict exists $methods constructor]} { + set mtype [dict get $methods constructor methodtype] + ::practcl::cputs result [string map [list @MTYPE@ $mtype] { + /* Attach the constructor to the class */ + Tcl_ClassSetConstructor(interp, curClass, Tcl_NewMethod(interp, curClass, NULL, 1, &@MTYPE@, NULL)); + }] + } + foreach {name info} $methods { + dict with info {} + if {$name in {constructor destructor}} continue + ::practcl::cputs result [string map [list @NAME@ $name @MTYPE@ $methodtype] { + nameObj=Tcl_NewStringObj("@NAME@",-1); + Tcl_NewMethod(interp, curClass, nameObj, 1, &@MTYPE@, (ClientData) NULL); + Tcl_DecrRefCount(nameObj); +}] + if {[dict exists $info aliases]} { + foreach alias [dict get $info aliases] { + if {[dict exists $methods $alias]} continue + ::practcl::cputs result [string map [list @NAME@ $alias @MTYPE@ $methodtype] { + nameObj=Tcl_NewStringObj("@NAME@",-1); + Tcl_NewMethod(interp, curClass, nameObj, 1, &@MTYPE@, (ClientData) NULL); + Tcl_DecrRefCount(nameObj); +}] + } + } + } + ::practcl::cputs result " return TCL_OK\;\n\}\n" + } + foreach obj [my link list dynamic] { + # Exclude products that will generate their own C files + if {[$obj define get output_c] ne {}} continue + ::practcl::cputs result [$obj generate-cmethod] + } + return $result + } + + method generate-cinit-external {} { + if {[my define get initfunc] eq {}} { + return "/* [my define get filename] declared not initfunc */" + } + return " if([my define get initfunc](interp)) return TCL_ERROR\;" + } + + ### + # Generate code that runs when the package/module is + # initialized into the interpreter + ### + method generate-cinit {} { + debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] + set result {} + my variable code methods tclprocs + if {[info exists code(nspace)]} { + ::practcl::cputs result " \{\n Tcl_Namespace *modPtr;" + foreach nspace $code(nspace) { + ::practcl::cputs result [string map [list @NSPACE@ $nspace] { + modPtr=Tcl_FindNamespace(interp,"@NSPACE@",NULL,TCL_NAMESPACE_ONLY); + if(!modPtr) { + modPtr = Tcl_CreateNamespace(interp, "@NSPACE@", NULL, NULL); + } +}] + } + ::practcl::cputs result " \}" + } + if {[info exists code(tclinit)]} { + ::practcl::cputs result $code(tclinit) + } + if {[info exists code(cinit)]} { + ::practcl::cputs result $code(cinit) + } + if {[info exists code(initfuncts)]} { + foreach func $code(initfuncts) { + ::practcl::cputs result " if (${func}(interp) != TCL_OK) return TCL_ERROR\;" + } + } + if {[info exists tclprocs]} { + foreach {name info} $tclprocs { + set map [list @NAME@ $name @CALLPROC@ [dict get $info callproc]] + ::practcl::cputs result [string map $map { Tcl_CreateObjCommand(interp,"@NAME@",(Tcl_ObjCmdProc *)@CALLPROC@,NULL,NULL);}] + if {[dict exists $info aliases]} { + foreach alias [dict get $info aliases] { + set map [list @NAME@ $alias @CALLPROC@ [dict get $info callproc]] + ::practcl::cputs result [string map $map { Tcl_CreateObjCommand(interp,"@NAME@",(Tcl_ObjCmdProc *)@CALLPROC@,NULL,NULL);}] + } + } + } + } + + if {[info exists code(nspace)]} { + ::practcl::cputs result " \{\n Tcl_Namespace *modPtr;" + foreach nspace $code(nspace) { + ::practcl::cputs result [string map [list @NSPACE@ $nspace] { + modPtr=Tcl_FindNamespace(interp,"@NSPACE@",NULL,TCL_NAMESPACE_ONLY); + Tcl_CreateEnsemble(interp, modPtr->fullName, modPtr, TCL_ENSEMBLE_PREFIX); + Tcl_Export(interp, modPtr, "[a-z]*", 1); +}] + } + ::practcl::cputs result " \}" + } + set result [::practcl::_tagblock $result c [my define get filename]] + foreach obj [my link list product] { + # Exclude products that will generate their own C files + if {[$obj define get output_c] ne {}} { + ::practcl::cputs result [$obj generate-cinit-external] + } else { + ::practcl::cputs result [$obj generate-cinit] + } + } + return $result + } + + method c_header body { + my variable code + ::practcl::cputs code(header) $body + } + + method c_code body { + my variable code + ::practcl::cputs code(funct) $body + } + method c_function {header body} { + my variable code cfunct + foreach regexp { + {(.*) ([a-zA-Z_][a-zA-Z0-9_]*) *\((.*)\)} + {(.*) (\x2a[a-zA-Z_][a-zA-Z0-9_]*) *\((.*)\)} + } { + if {[regexp $regexp $header all keywords funcname arglist]} { + dict set cfunct $funcname header $header + dict set cfunct $funcname body $body + dict set cfunct $funcname keywords $keywords + dict set cfunct $funcname arglist $arglist + dict set cfunct $funcname public [expr {"static" ni $keywords}] + dict set cfunct $funcname export [expr {"STUB_EXPORT" in $keywords}] + + return + } + } + ::practcl::cputs code(header) "$header\;" + # Could not parse that block as a function + # append it verbatim to our c_implementation + ::practcl::cputs code(funct) "$header [list $body]" + } + + + method cmethod {name body {arginfo {}}} { + my variable methods code + foreach {f v} $arginfo { + dict set methods $name $f $v + } + dict set methods $name body "Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */ +$body" + } + + method c_tclproc_nspace nspace { + my variable code + if {![info exists code(nspace)]} { + set code(nspace) {} + } + if {$nspace ni $code(nspace)} { + lappend code(nspace) $nspace + } + } + + method c_tclproc_raw {name body {arginfo {}}} { + my variable tclprocs code + + foreach {f v} $arginfo { + dict set tclprocs $name $f $v + } + dict set tclprocs $name body $body + } + + method go {} { + debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] + next + my variable methods code cstruct tclprocs + if {[info exists methods]} { + debug [self] methods [my define get cclass] + set thisclass [my define get cclass] + foreach {name info} $methods { + # Provide a callproc + if {![dict exists $info callproc]} { + set callproc [string map {____ _ ___ _ __ _} [string map {{ } _ : _} OOMethod_${thisclass}_${name}]] + dict set methods $name callproc $callproc + } else { + set callproc [dict get $info callproc] + } + if {[dict exists $info body] && ![dict exists $info header]} { + dict set methods $name header "static int ${callproc}(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv)" + } + if {![dict exists $info methodtype]} { + set methodtype [string map {{ } _ : _} MethodType_${thisclass}_${name}] + dict set methods $name methodtype $methodtype + } + } + if {![info exists code(initfuncts)] || "${thisclass}_OO_Init" ni $code(initfuncts)} { + lappend code(initfuncts) "${thisclass}_OO_Init" + } + } + set thisnspace [my define get nspace] + + if {[info exists tclprocs]} { + debug [self] tclprocs [dict keys $tclprocs] + foreach {name info} $tclprocs { + if {![dict exists $info callproc]} { + set callproc [string map {____ _ ___ _ __ _} [string map {{ } _ : _} Tclcmd_${thisnspace}_${name}]] + dict set tclprocs $name callproc $callproc + } else { + set callproc [dict get $info callproc] + } + if {[dict exists $info body] && ![dict exists $info header]} { + dict set tclprocs $name header "static int ${callproc}(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv\[\])" + } + } + } + debug [list /[self] [self method] [self class]] + } + + # Once an object marks itself as some + # flavor of dynamic, stop trying to morph + # it into something else + method select {} {} + + + method tcltype {name argdat} { + my variable tcltype + foreach {f v} $argdat { + dict set tcltype $name $f $v + } + if {![dict exists tcltype $name cname]} { + dict set tcltype $name cname [string tolower $name]_tclobjtype + } + lappend map @NAME@ $name + set info [dict get $tcltype $name] + foreach {f v} $info { + lappend map @[string toupper $f]@ $v + } + foreach {func fpat template} { + freeproc {@Name@Obj_freeIntRepProc} {void @FNAME@(Tcl_Obj *objPtr)} + dupproc {@Name@Obj_dupIntRepProc} {void @FNAME@(Tcl_Obj *srcPtr,Tcl_Obj *dupPtr)} + updatestringproc {@Name@Obj_updateStringRepProc} {void @FNAME@(Tcl_Obj *objPtr)} + setfromanyproc {@Name@Obj_setFromAnyProc} {int @FNAME@(Tcl_Interp *interp,Tcl_Obj *objPtr)} + } { + if {![dict exists $info $func]} { + error "$name does not define $func" + } + set body [dict get $info $func] + # We were given a function name to call + if {[llength $body] eq 1} continue + set fname [string map [list @Name@ [string totitle $name]] $fpat] + my c_function [string map [list @FNAME@ $fname] $template] [string map $map $body] + dict set tcltype $name $func $fname + } + } +} + +::oo::class create ::practcl::cheader { + superclass ::practcl::product + + method compile-products {} {} + method generate-cinit {} {} +} + +::oo::class create ::practcl::csource { + superclass ::practcl::product +} + +::oo::class create ::practcl::clibrary { + superclass ::practcl::product + + method linker-products {configdict} { + return [my define get filename] + } + +} + +### +# In the end, all C code must be loaded into a module +# This will either be a dynamically loaded library implementing +# a tcl extension, or a compiled in segment of a custom shell/app +### +::oo::class create ::practcl::module { + superclass ::practcl::dynamic + + method child which { + switch $which { + organs { + return [list project [my define get project] module [self]] + } + } + } + + method initialize {} { + set filename [my define get filename] + if {$filename eq {}} { + return + } + if {[my define get name] eq {}} { + my define set name [file tail [file dirname $filename]] + } + if {[my define get localpath] eq {}} { + my define set localpath [my define get name]_[my define get name] + } + debug [self] SOURCE $filename + my source $filename + } + + method implement path { + my go + my Collate_Source $path + foreach item [my link list dynamic] { + if {[catch {$item implement $path} err]} { + puts "Skipped $item: $err" + } + } + foreach item [my link list module] { + if {[catch {$item implement $path} err]} { + puts "Skipped $item: $err" + } + } + debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] + set filename [my define get output_c] + if {$filename eq {}} { + debug [list /[self] [self method] [self class]] + return + } + set cout [open [file join $path [file rootname $filename].c] w] + puts $cout [subst {/* +** This file is generated by the [info script] script +** any changes will be overwritten the next time it is run +*/}] + puts $cout [my generate-c] + puts $cout [my generate-loader] + close $cout + debug [list /[self] [self method] [self class]] + } + + method linktype {} { + return {subordinate product dynamic module} + } +} + +::oo::class create ::practcl::autoconf { + + ### + # find or fake a key/value list describing this project + ### + method config.sh {} { + my variable conf_result + if {[info exists conf_result]} { + return $conf_result + } + set result {} + set name [my define get name] + set PWD $::CWD + set builddir [my define get builddir] + my unpack + set srcroot [my define get srcroot] + if {![file exists $builddir]} { + my Configure + } + set filename [file join $builddir config.tcl] + # Project uses the practcl template. Use the leavings from autoconf + if {[file exists $filename]} { + set dat [::practcl::config.tcl $builddir] + foreach {item value} [lsort -stride 2 -dictionary $dat] { + dict set result $item $value + } + set conf_result $result + return $result + } + set filename [file join $builddir ${name}Config.sh] + if {[file exists $filename]} { + set l [expr {[string length $name]+1}] + foreach {field dat} [::practcl::read_Config.sh $filename] { + set field [string tolower $field] + if {[string match ${name}_* $field]} { + set field [string range $field $l end] + } + dict set result $field $dat + } + set conf_result $result + return $result + } + ### + # Oh man... we have to guess + ### + set filename [file join $builddir Makefile] + if {![file exists $filename]} { + error "Could not locate any configuration data in $srcroot" + } + foreach {field dat} [::practcl::read_Makefile $filename] { + dict set result $field $dat + } + set conf_result $result + cd $PWD + return $result + } +} + + +::oo::class create ::practcl::project { + superclass ::practcl::module ::practcl::autoconf + + constructor args { + my variable define + if {[llength $args] == 1} { + if {[catch {uplevel 1 [list subst [lindex $args 0]]} contents]} { + set contents [lindex $args 0] + } + } else { + if {[catch {uplevel 1 [list subst $args]} contents]} { + set contents $args + } + } + array set define $contents + my select + my initialize + } + + + method add_project {pkg info {oodefine {}}} { + set os [my define get os] + if {$os eq {}} { + set os [::practcl::os] + my define set os $os + } + set fossilinfo [list download [my define get download] tag trunk sandbox [my define get sandbox]] + if {[dict exists $info os] && ($os ni [dict get $info os])} return + # Select which tag to use here. + # For production builds: tag-release + if {[::info exists ::env(FOSSIL_MIRROR)]} { + dict set info localmirror $::env(FOSSIL_MIRROR) + } + set profile [my define get profile release]: + if {[dict exists $info profile $profile]} { + dict set info tag [dict get $info profile $profile] + } + set obj [namespace current]::PROJECT.$pkg + if {[info command $obj] eq {}} { + set obj [::practcl::subproject create $obj [self] [dict merge $fossilinfo [list name $pkg pkg_name $pkg static 0] $info]] + } + my link object $obj + oo::objdefine $obj $oodefine + $obj define set masterpath $::CWD + $obj go + return $obj + } + + method child which { + switch $which { + organs { + # A library can be a project, it can be a module. Any + # subordinate modules will indicate their existance + return [list project [self] module [self]] + } + } + } + + method linktype {} { + return project + } + + # Exercise the methods of a sub-object + method project {pkg args} { + set obj [namespace current]::PROJECT.$pkg + if {[llength $args]==0} { + return $obj + } + tailcall ${obj} {*}$args + } +} + +::oo::class create ::practcl::library { + superclass ::practcl::project + + method compile-products {} { + set result {} + foreach item [my link list subordinate] { + lappend result {*}[$item compile-products] + } + set filename [my define get output_c] + if {$filename ne {}} { + set ofile [file rootname [file tail $filename]]_main.o + lappend result $ofile [list cfile $filename extra [my define get extra] external [string is true -strict [my define get external]]] + } + return $result + } + + method generate-tcl-loader {} { + set result {} + set PKGINIT [my define get pkginit] + set PKG_NAME [my define get name [my define get pkg_name]] + set PKG_VERSION [my define get pkg_vers [my define get version]] + if {[string is true [my define get SHARED_BUILD 0]]} { + set LIBFILE [my define get libfile] + ::practcl::cputs result [string map \ + [list @LIBFILE@ $LIBFILE @PKGINIT@ $PKGINIT @PKG_NAME@ $PKG_NAME @PKG_VERSION@ $PKG_VERSION] { +# Shared Library Style +load [file join [file dirname [file join [pwd] [info script]]] @LIBFILE@] @PKGINIT@ +package provide @PKG_NAME@ @PKG_VERSION@ +}] + } else { + ::practcl::cputs result [string map \ + [list @PKGINIT@ $PKGINIT @PKG_NAME@ $PKG_NAME @PKG_VERSION@ $PKG_VERSION] { +# Tclkit Style +load {} @PKGINIT@ +package provide @PKG_NAME@ @PKG_VERSION@ +}] + } + return $result + } + + method go {} { + debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] + set name [my define getnull name] + if {$name eq {}} { + set name generic + my define name generic + } + if {[my define get tk] eq {@TEA_TK_EXTENSION@}} { + my define set tk 0 + } + set output_c [my define getnull output_c] + if {$output_c eq {}} { + set output_c [file rootname $name].c + my define set output_c $output_c + } + set output_h [my define getnull output_h] + if {$output_h eq {}} { + set output_h [file rootname $output_c].h + my define set output_h $output_h + } + set output_tcl [my define getnull output_tcl] + #if {$output_tcl eq {}} { + # set output_tcl [file rootname $output_c].tcl + # my define set output_tcl $output_tcl + #} + #set output_mk [my define getnull output_mk] + #if {$output_mk eq {}} { + # set output_mk [file rootname $output_c].mk + # my define set output_mk $output_mk + #} + set initfunc [my define getnull initfunc] + if {$initfunc eq {}} { + set initfunc [string totitle $name]_Init + my define set initfunc $initfunc + } + set output_decls [my define getnull output_decls] + if {$output_decls eq {}} { + set output_decls [file rootname $output_c].decls + my define set output_decls $output_decls + } + my variable links + foreach {linktype objs} [array get links] { + foreach obj $objs { + $obj go + } + } + debug [list /[self] [self method] [self class] -- [my define get filename] [info object class [self]]] + } + + method implement path { + my go + my Collate_Source $path + foreach item [my link list dynamic] { + if {[catch {$item implement $path} err]} { + puts "Skipped $item: $err" + } + } + foreach item [my link list module] { + if {[catch {$item implement $path} err]} { + puts "Skipped $item: $err" + } + } + set cout [open [file join $path [my define get output_c]] w] + puts $cout [subst {/* +** This file is generated by the [info script] script +** any changes will be overwritten the next time it is run +*/}] + puts $cout [my generate-c] + puts $cout [my generate-loader] + close $cout + + set macro HAVE_[string toupper [file rootname [my define get output_h]]]_H + set hout [open [file join $path [my define get output_h]] w] + puts $hout [subst {/* +** This file is generated by the [info script] script +** any changes will be overwritten the next time it is run +*/}] + puts $hout "#ifndef ${macro}" + puts $hout "#define ${macro}" + puts $hout [my generate-h] + puts $hout "#endif" + close $hout + + set output_tcl [my define get output_tcl] + if {$output_tcl ne {}} { + set tclout [open [file join $path [my define get output_tcl]] w] + puts $tclout "### +# This file is generated by the [info script] script +# any changes will be overwritten the next time it is run +###" + puts $tclout [my generate-tcl] + puts $tclout [my generate-tcl-loader] + close $tclout + } + } + + method generate-decls {pkgname path} { + debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] + set outfile [file join $path/$pkgname.decls] + + ### + # Build the decls file + ### + set fout [open $outfile w] + puts $fout [subst {### + # $outfile + # + # This file was generated by [info script] + ### + + library $pkgname + interface $pkgname + }] + + ### + # Generate list of functions + ### + set stubfuncts [my generate-stub-function] + set thisline {} + set functcount 0 + foreach {func header} $stubfuncts { + puts $fout [list declare [incr functcount] $header] + } + puts $fout [list export "int [my define get initfunc](Tcl_Inter *interp)"] + puts $fout [list export "char *[string totitle [my define get name]]_InitStubs(Tcl_Inter *interp, char *version, int exact)"] + + close $fout + + ### + # Build [package]Decls.h + ### + set hout [open [file join $path ${pkgname}Decls.h] w] + + close $hout + + set cout [open [file join $path ${pkgname}StubInit.c] w] +puts $cout [string map [list %pkgname% $pkgname %PkgName% [string totitle $pkgname]] { +#ifndef USE_TCL_STUBS +#define USE_TCL_STUBS +#endif +#undef USE_TCL_STUB_PROCS + +#include "tcl.h" +#include "%pkgname%.h" + + /* + ** Ensure that Tdom_InitStubs is built as an exported symbol. The other stub + ** functions should be built as non-exported symbols. + */ + +#undef TCL_STORAGE_CLASS +#define TCL_STORAGE_CLASS DLLEXPORT + +%PkgName%Stubs *%pkgname%StubsPtr; + + /* + **---------------------------------------------------------------------- + ** + ** %PkgName%_InitStubs -- + ** + ** Checks that the correct version of %PkgName% is loaded and that it + ** supports stubs. It then initialises the stub table pointers. + ** + ** Results: + ** The actual version of %PkgName% that satisfies the request, or + ** NULL to indicate that an error occurred. + ** + ** Side effects: + ** Sets the stub table pointers. + ** + **---------------------------------------------------------------------- + */ + +char * +%PkgName%_InitStubs (Tcl_Interp *interp, char *version, int exact) +{ + char *actualVersion; + actualVersion = Tcl_PkgRequireEx(interp, "%pkgname%", version, exact,(ClientData *) &%pkgname%StubsPtr); + if (!actualVersion) { + return NULL; + } + if (!%pkgname%StubsPtr) { + Tcl_SetResult(interp,"This implementation of %PkgName% does not support stubs",TCL_STATIC); + return NULL; + } + return actualVersion; +} +}] + close $cout + } + + # Backward compadible call + method generate-make path { + ::practcl::build::Makefile $path [self] + } + + method install-headers {} { + set result {} + return $result + } + + method linktype {} { + return library + } + + # Create a "package ifneeded" + # Args are a list of aliases for which this package will answer to + method package-ifneeded {args} { + set result {} + set name [my define get pkg_name [my define get name]] + set version [my define get pkg_vers [my define get version]] + if {$version eq {}} { + set version 0.1a + } + set output_tcl [my define get output_tcl] + if {$output_tcl ne {}} { + set script "\[list source \[file join \$dir $output_tcl\]\]" + } elseif {[string is true -strict [my define get SHARED_BUILD]]} { + set script "\[list load \[file join \$dir [my define get libfile]\] $name\]" + } else { + # Provide a null passthrough + set script [list package provide $name $version] + } + set result "package ifneeded [list $name] [list $version] $script" + foreach alias $args { + set script "package require $name $version \; package provide $alias $version" + append result \n\n [list package ifneeded $alias $version $script] + } + return $result + } + + + method shared_library {} { + set name [string tolower [my define get name [my define get pkg_name]]] + set NAME [string toupper $name] + set version [my define get version [my define get pkg_vers]] + set map {} + lappend map %LIBRARY_NAME% $name + lappend map %LIBRARY_VERSION% $version + lappend map %LIBRARY_VERSION_NODOTS% [string map {. {}} $version] + lappend map %LIBRARY_PREFIX% [my define getnull libprefix] + set outfile [string map $map [my define get PRACTCL_NAME_LIBRARY]][my define get SHLIB_SUFFIX] + return $outfile + } +} + +::oo::class create ::practcl::tclkit { + superclass ::practcl::library + + method Collate_Source CWD { + my define set SHARED_BUILD 0 + set name [my define get name] + + if {![my define exists TCL_LOCAL_APPINIT]} { + my define set TCL_LOCAL_APPINIT Tclkit_AppInit + } + if {![my define exists TCL_LOCAL_MAIN_HOOK]} { + my define set TCL_LOCAL_MAIN_HOOK Tclkit_MainHook + } + + set PROJECT [self] + set os [$PROJECT define get os] + set TCLOBJ [$PROJECT project TCLCORE] + set TKOBJ [$PROJECT project TKCORE] + set ODIEOBJ [$PROJECT project odie] + + set TCLSRCDIR [$TCLOBJ define get srcroot] + set TKSRCDIR [$TKOBJ define get srcroot] + set PKG_OBJS {} + foreach item [$PROJECT link list package] { + if {[string is true [$item define get static]]} { + lappend PKG_OBJS $item + } + } + # Arrange to build an main.c that utilizes TCL_LOCAL_APPINIT and TCL_LOCAL_MAIN_HOOK + if {$os eq "windows"} { + set PLATFORM_SRC_DIR win + my add class csource filename [file join $TCLSRCDIR win tclWinReg.c] initfunc Registry_Init pkg_name registry pkg_vers 1.3.1 autoload 1 + my add class csource filename [file join $TCLSRCDIR win tclWinDde.c] initfunc Dde_Init pkg_name dde pkg_vers 1.4.0 autoload 1 + my add class csource ofile [my define get name]_appinit.o filename [file join $TCLSRCDIR win tclAppInit.c] extra [list -DTCL_LOCAL_MAIN_HOOK=[my define get TCL_LOCAL_MAIN_HOOK Tclkit_MainHook] -DTCL_LOCAL_APPINIT=[my define get TCL_LOCAL_APPINIT Tclkit_AppInit]] + } else { + set PLATFORM_SRC_DIR unix + my add class csource ofile [my define get name]_appinit.o filename [file join $TCLSRCDIR unix tclAppInit.c] extra [list -DTCL_LOCAL_MAIN_HOOK=[my define get TCL_LOCAL_MAIN_HOOK Tclkit_MainHook] -DTCL_LOCAL_APPINIT=[my define get TCL_LOCAL_APPINIT Tclkit_AppInit]] + } + ### + # Add local static Zlib implementation + ### + set cdir [file join $TCLSRCDIR compat zlib] + foreach file { + adler32.c compress.c crc32.c + deflate.c infback.c inffast.c + inflate.c inftrees.c trees.c + uncompr.c zutil.c + } { + my add [file join $cdir $file] + } + + ### + # Pre 8.7, Tcl doesn't include a Zipfs implementation + # in the core. Grab the one from odielib + ### + set zipfs [file join $TCLSRCDIR generic zvfs.c] + if {![file exists $zipfs]} { + # The Odie project maintains a mirror of the version + # released with the Tcl core + my add_project odie { + tag trunk + class subproject + vfsinstall 0 + } + my project odie unpack + set ODIESRCROOT [my project odie define get srcroot] + set cdir [file join $ODIESRCROOT compat zipfs] + my define add include_dir $cdir + set zipfs [file join $cdir zvfs.c] + } + + my add class csource filename $zipfs initfunc Tclzipfs_Init pkg_name zipfs pkg_vers 1.0 autoload 1 + + my define add include_dir [file join $TKSRCDIR generic] + my define add include_dir [file join $TKSRCDIR $PLATFORM_SRC_DIR] + my define add include_dir [file join $TKSRCDIR bitmaps] + my define add include_dir [file join $TKSRCDIR xlib] + my define add include_dir [file join $TCLSRCDIR generic] + my define add include_dir [file join $TCLSRCDIR $PLATFORM_SRC_DIR] + my define add include_dir [file join $TCLSRCDIR compat zlib] + # This file will implement TCL_LOCAL_APPINIT and TCL_LOCAL_MAIN_HOOK + ::practcl::build::tclkit_main $PROJECT $PKG_OBJS + } + + ## Wrap an executable + # + method wrap {PWD exename vfspath args} { + cd $PWD + if {![file exists $vfspath]} { + file mkdir $vfspath + } + foreach item [my link list core.library] { + set name [$item define get name] + set libsrcroot [$item define get srcroot] + if {[file exists [file join $libsrcroot library]]} { + ::practcl::copyDir [file join $libsrcroot library] [file join $vfspath boot $name] + } + } + if {[my define get installdir] ne {}} { + ::practcl::copyDir [file join [my define get installdir] [string trimleft [my define get prefix] /] lib] [file join $vfspath lib] + } + foreach arg $args { + ::practcl::copyDir $arg $vfspath + } + + set fout [open [file join $vfspath packages.tcl] w] + puts $fout { + set ::PKGIDXFILE [info script] + set dir [file dirname $::PKGIDXFILE] + } + #set BASEVFS [my define get BASEVFS] + set EXEEXT [my define get EXEEXT] + + set tclkit_bare [my define get tclkit_bare] + + set buffer [::practcl::pkgindex_path $vfspath] + puts $fout $buffer + puts $fout { + # Advertise statically linked packages + foreach {pkg script} [array get ::kitpkg] { + eval $script + } + } + close $fout + package require zipfile::mkzip + ::zipfile::mkzip::mkzip ${exename}${EXEEXT} -runtime $tclkit_bare -directory $vfspath + if { [my define get platform] ne "windows" } { + file attributes ${exename}${EXEEXT} -permissions a+x + } + } +} + +### +# Meta repository +# The default is an inert source code block +### +oo::class create ::practcl::subproject { + superclass ::practcl::object + + method compile {} {} + + method go {} { + set platform [my define get platform] + my define get USEMSVC [my define get USEMSVC] + set name [my define get name] + if {![my define exists srcroot]} { + my define set srcroot [file join [my define get sandbox] $name] + } + set srcroot [my define get srcroot] + my define set localsrcdir $srcroot + my define add include_dir [file join $srcroot generic] + my sources + } + + # Install project into the local build system + method install-local {} { + my unpack + } + + # Install project into the virtual file system + method install-vfs {} {} + + method linktype {} { + return {subordinate package} + } + + method linker-products {configdict} {} + + method linker-external {configdict} { + if {[dict exists $configdict PRACTCL_LIBS]} { + return [dict get $configdict PRACTCL_LIBS] + } + } + + method sources {} {} + + method unpack {} { + set name [my define get name] + puts [list $name [self] UNPACK] + my define set [::practcl::fossil_sandbox $name [my define dump]] + } + + method update {} { + set name [my define get name] + my define set [::practcl::fossil_sandbox $name [dict merge [my define dump] {update 1}]] + } +} + +### +# A project which the kit compiles and integrates +# the source for itself +### +oo::class create ::practcl::subproject.source { + superclass ::practcl::subproject ::practcl::library + + method linktype {} { + return {subordinate package source} + } + +} + +# a copy from the teapot +oo::class create ::practcl::subproject.teapot { + superclass ::practcl::subproject + + method install-local {} { + my install-vfs + } + + method install-vfs {} { + set pkg [my define get pkg_name [my define get name]] + set download [my define get download] + my unpack + set DEST [my define get installdir] + set prefix [string trimleft [my define get prefix] /] + # Get tcllib from our destination + set dir [file join $DEST $prefix lib tcllib] + source [file join $DEST $prefix lib tcllib pkgIndex.tcl] + package require zipfile::decode + ::zipfile::decode::unzipfile [file join $download $pkg.zip] [file join $DEST $prefix lib $pkg] + } +} + +oo::class create ::practcl::subproject.sak { + superclass ::practcl::subproject + + method install-local {} { + my install-vfs + } + + method install-vfs {} { + ### + # Handle teapot installs + ### + set pkg [my define get pkg_name [my define get name]] + my unpack + set DEST [my define get installdir] + set prefix [string trimleft [my define get prefix] /] + set srcroot [my define get srcroot] + ::dotclexec [file join $srcroot installer.tcl] \ + -pkg-path [file join $DEST $prefix lib $pkg] \ + -no-examples -no-html -no-nroff \ + -no-wait -no-gui -no-apps + } +} + +### +# A binary package +### +oo::class create ::practcl::subproject.binary { + superclass ::practcl::subproject ::practcl::autoconf + + + method compile-products {} {} + + method ConfigureOpts {} { + set opts {} + set builddir [my define get builddir] + if {[my define get broken_destroot 0]} { + set PREFIX [my define get prefix_broken_destdir] + } else { + set PREFIX [my define get prefix] + } + if {[my define get HOST] != [my define get TARGET]} { + lappend opts --host=[my define get TARGET] + } + if {[my define exists tclsrcdir]} { + set TCLSRCDIR [::practcl::file_relative [file normalize $builddir] [file normalize [file join $::CWD [my define get tclsrcdir]]]] + set TCLGENERIC [::practcl::file_relative [file normalize $builddir] [file normalize [file join $::CWD [my define get tclsrcdir] .. generic]]] + lappend opts --with-tcl=$TCLSRCDIR --with-tclinclude=$TCLGENERIC + } + if {[my define exists tksrcdir]} { + set TKSRCDIR [::practcl::file_relative [file normalize $builddir] [file normalize [file join $::CWD [my define get tksrcdir]]]] + set TKGENERIC [::practcl::file_relative [file normalize $builddir] [file normalize [file join $::CWD [my define get tksrcdir] .. generic]]] + lappend opts --with-tk=$TKSRCDIR --with-tkinclude=$TKGENERIC + } + lappend opts {*}[my define get config_opts] + lappend opts --prefix=$PREFIX + #--exec_prefix=$PREFIX + #if {$::tcl_platform(platform) eq "windows"} { + # lappend opts --disable-64bit + #} + if {[my define get static 1]} { + lappend opts --disable-shared --disable-stubs + # + } else { + lappend opts --enable-shared + } + return $opts + } + + method go {} { + next + my define set builddir [my BuildDir [my define get masterpath]] + } + + method linker-products {configdict} { + if {![my define get static 0]} { + return {} + } + set srcdir [my define get builddir] + if {[dict exists $configdict libfile]} { + return " [file join $srcdir [dict get $configdict libfile]]" + } + } + + method static-packages {} { + if {![my define get static 0]} { + return {} + } + set result [my define get static_packages] + set statpkg [my define get static_pkg] + set initfunc [my define get initfunc] + if {$initfunc ne {}} { + set pkg_name [my define get pkg_name] + if {$pkg_name ne {}} { + dict set result $pkg_name initfunc $initfunc + set version [my define get version] + if {$version eq {}} { + set info [my config.sh] + set version [dict get $info version] + set pl {} + if {[dict exists $info patch_level]} { + set pl [dict get $info patch_level] + append version $pl + } + my define set version $version + } + dict set result $pkg_name version $version + dict set result $pkg_name autoload [my define get autoload 0] + } + } + foreach item [my link list subordinate] { + foreach {pkg info} [$item static-packages] { + dict set result $pkg $info + } + } + return $result + } + + method BuildDir {PWD} { + set name [my define get name] + return [my define get builddir [file join $PWD pkg.$name]] + } + + method compile {} { + set name [my define get name] + set PWD $::CWD + cd $PWD + my go + set srcroot [file normalize [my define get srcroot]] + my Collate_Source $PWD + + ### + # Build a starter VFS for both Tcl and wish + ### + set srcroot [my define get srcroot] + if {[my define get static 1]} { + puts "BUILDING Static $name $srcroot" + } else { + puts "BUILDING Dynamic $name $srcroot" + } + if {[my define get USEMSVC 0]} { + cd $srcroot + doexec nmake -f makefile.vc INSTALLDIR=[my define get installdir] release + } else { + cd $::CWD + set builddir [file normalize [my define get builddir]] + file mkdir $builddir + if {![file exists [file join $builddir Makefile]]} { + my Configure + } + if {[file exists [file join $builddir make.tcl]]} { + domake.tcl $builddir library + } else { + domake $builddir all + } + } + cd $PWD + } + + + method Configure {} { + cd $::CWD + my unpack + my TeaConfig + set builddir [file normalize [my define get builddir]] + file mkdir $builddir + set srcroot [file normalize [my define get srcroot]] + if {[my define get USEMSVC 0]} { + return + } + set opts [my ConfigureOpts] + puts [list [self] CONFIGURE] + puts [list PWD [pwd]] + puts [list LOCALSRC $srcroot] + puts [list BUILDDIR $builddir] + puts [list CONFIGURE {*}$opts] + cd $builddir + exec sh [file join $srcroot configure] {*}$opts >& [file join $builddir practcl.log] + cd $::CWD + } + + method install-vfs {} { + set PWD [pwd] + set PKGROOT [my define get installdir] + set PREFIX [my define get prefix] + + ### + # Handle teapot installs + ### + set pkg [my define get pkg_name [my define get name]] + if {[my define get teapot] ne {}} { + set TEAPOT [my define get teapot] + set found 0 + foreach ver [my define get pkg_vers [my define get version]] { + set teapath [file join $TEAPOT $pkg$ver] + if {[file exists $teapath]} { + set dest [file join $PKGROOT [string trimleft $PREFIX /] lib [file tail $teapath]] + ::practcl::copyDir $teapath $dest + return + } + } + } + my compile + if {[my define get USEMSVC 0]} { + set srcroot [my define get srcroot] + cd $srcroot + puts "[self] VFS INSTALL $PKGROOT" + doexec nmake -f makefile.vc INSTALLDIR=$PKGROOT install + } else { + set builddir [my define get builddir] + if {[file exists [file join $builddir make.tcl]]} { + # Practcl builds can inject right to where we need them + puts "[self] VFS INSTALL $PKGROOT (Practcl)" + domake.tcl $builddir install-package $PKGROOT + } elseif {[my define get broken_destroot 0] == 0} { + # Most modern TEA projects understand DESTROOT in the makefile + puts "[self] VFS INSTALL $PKGROOT (TEA)" + domake $builddir install DESTDIR=$PKGROOT + } else { + # But some require us to do an install into a fictitious filesystem + # and then extract the gooey parts within. + # (*cough*) TkImg + set PREFIX [my define get prefix] + set BROKENROOT [::practcl::msys_to_tclpath [my define get prefix_broken_destdir]] + file delete -force $BROKENROOT + file mkdir $BROKENROOT + domake $builddir $install + ::practcl::copyDir $BROKENROOT [file join $PKGROOT [string trimleft $PREFIX /]] + file delete -force $BROKENROOT + } + } + cd $PWD + } + + method TeaConfig {} { + set srcroot [file normalize [my define get srcroot]] + set copytea 0 + if {![file exists [file join $srcroot tclconfig]]} { + set copytea 1 + } else { + if {![file exists [file join $srcroot tclconfig practcl.tcl]] || ![file exists [file join $srcroot tclconfig config.tcl.in]]} { + set copytea 1 + } + } + # ensure we have tclconfig with all of the trimming + if {$copytea} { + set tclconfiginfo [::practcl::fossil_sandbox tclconfig [list sandbox [my define get sandbox]]] + ::practcl::copyDir [dict get $tclconfiginfo srcroot] [file join $srcroot tclconfig] + if {$::tcl_platform(platform) ne "windows"} { + set pwd [pwd] + cd $srcroot + # On windows there's no practical way to execute + # autoconf. We'll have to trust that configure + # us up to date + foreach template {configure.ac configure.in} { + set input [file join $srcroot $template] + if {[file exists $input]} { + puts "autoconf -f $input > [file join $srcroot configure]" + exec autoconf -f $input > [file join $srcroot configure] + } + } + cd $pwd + } + } + } +} + +oo::class create ::practcl::subproject.core { + superclass ::practcl::subproject.binary + + # On the windows platform MinGW must build + # from the platform directory in the source repo + method BuildDir {PWD} { + return [my define get localsrcdir] + } + + method Configure {} { + if {[my define get USEMSVC 0]} { + return + } + set opts [my ConfigureOpts] + puts [list PWD [pwd]] + puts [list [self] CONFIGURE] + set builddir [file normalize [my define get builddir]] + set localsrcdir [file normalize [my define get localsrcdir]] + puts [list LOCALSRC $localsrcdir] + puts [list BUILDDIR $builddir] + puts [list CONFIGURE {*}$opts] + cd $localsrcdir + exec sh [file join $localsrcdir configure] {*}$opts >& [file join $builddir practcl.log] + } + + method ConfigureOpts {} { + set opts {} + set builddir [file normalize [my define get builddir]] + set PREFIX [my define get prefix] + if {[my define get HOST] != [my define get TARGET]} { + lappend opts --host=[my define get TARGET] + } + lappend opts {*}[my define get config_opts] + lappend opts --prefix=$PREFIX + #--exec_prefix=$PREFIX + lappend opts --disable-shared + return $opts + } + + method go {} { + set name [my define get name] + set platform [my define get platform] + if {![my define exists srcroot]} { + my define set srcroot [file join [my define get sandbox] $name] + } + set srcroot [my define get srcroot] + my define add include_dir [file join $srcroot generic] + switch $platform { + windows { + my define set localsrcdir [file join $srcroot win] + my define add include_dir [file join $srcroot win] + } + default { + my define set localsrcdir [file join $srcroot unix] + my define add include_dir [file join $srcroot $name unix] + } + } + my define set builddir [my BuildDir [my define get masterpath]] + } + + method linktype {} { + return {subordinate core.library} + } +} + +package provide practcl 0.5 diff --git a/unix/Makefile.in b/unix/Makefile.in index 1afc883..ca15312 100644 --- a/unix/Makefile.in +++ b/unix/Makefile.in @@ -308,7 +308,7 @@ GENERIC_OBJS = regcomp.o regexec.o regfree.o regerror.o tclAlloc.o \ tclStrToD.o tclThread.o \ tclThreadAlloc.o tclThreadJoin.o tclThreadStorage.o tclStubInit.o \ tclTimer.o tclTrace.o tclUtf.o tclUtil.o tclVar.o tclZlib.o \ - tclTomMathInterface.o zipfs.o + tclTomMathInterface.o tclZipfs.o OO_OBJS = tclOO.o tclOOBasic.o tclOOCall.o tclOODefineCmds.o tclOOInfo.o \ tclOOMethod.o tclOOStubInit.o @@ -373,7 +373,6 @@ GENERIC_HDRS = \ $(GENERIC_DIR)/tclInt.h \ $(GENERIC_DIR)/tclIntDecls.h \ $(GENERIC_DIR)/tclIntPlatDecls.h \ - $(GENERIC_DIR)/tclZipfs.h \ $(GENERIC_DIR)/tclTomMath.h \ $(GENERIC_DIR)/tclTomMathDecls.h \ $(GENERIC_DIR)/tclOO.h \ @@ -954,7 +953,6 @@ install-headers: @for i in $(GENERIC_DIR)/tcl.h $(GENERIC_DIR)/tclDecls.h \ $(GENERIC_DIR)/tclOO.h $(GENERIC_DIR)/tclOODecls.h \ $(GENERIC_DIR)/tclPlatDecls.h \ - $(GENERIC_DIR)/tclZipfs.h \ $(GENERIC_DIR)/tclTomMath.h \ $(GENERIC_DIR)/tclTomMathDecls.h ; \ do \ @@ -1324,8 +1322,8 @@ tclVar.o: $(GENERIC_DIR)/tclVar.c tclZlib.o: $(GENERIC_DIR)/tclZlib.c $(CC) -c $(CC_SWITCHES) $(ZLIB_INCLUDE) $(GENERIC_DIR)/tclZlib.c -zipfs.o: $(GENERIC_DIR)/zipfs.c - $(CC) -c $(CC_SWITCHES) $(ZLIB_INCLUDE) $(GENERIC_DIR)/zipfs.c +tclZipfs.o: $(GENERIC_DIR)/tclZipfs.c + $(CC) -c $(CC_SWITCHES) $(ZLIB_INCLUDE) $(GENERIC_DIR)/tclZipfs.c tclTest.o: $(GENERIC_DIR)/tclTest.c $(IOHDR) $(TCLREHDRS) $(CC) -c $(APP_CC_SWITCHES) $(GENERIC_DIR)/tclTest.c diff --git a/unix/tclAppInit.c b/unix/tclAppInit.c index 2dcd192..9bbc88b 100644 --- a/unix/tclAppInit.c +++ b/unix/tclAppInit.c @@ -15,9 +15,7 @@ #undef BUILD_tcl #undef STATIC_BUILD #include "tcl.h" -#ifdef HAVE_ZLIB -#include "tclZipfs.h" -#endif + #ifdef TCL_TEST extern Tcl_PackageInitProc Tcltest_Init; extern Tcl_PackageInitProc Tcltest_SafeInit; @@ -42,7 +40,6 @@ extern Tcl_PackageInitProc Tclxttest_Init; #endif MODULE_SCOPE int TCL_LOCAL_APPINIT(Tcl_Interp *); MODULE_SCOPE int main(int, char **); -MODULE_SCOPE int Tcl_Zvfs_Boot(const char *,const char *,const char *,const char *); /* * The following #if block allows you to change how Tcl finds the startup @@ -83,12 +80,7 @@ main( #ifdef TCL_LOCAL_MAIN_HOOK TCL_LOCAL_MAIN_HOOK(&argc, &argv); #endif - #define TCLKIT_INIT "main.tcl" - #define TCLKIT_VFSMOUNT "/zvfs" - #define TCLKIT_PASSWD NULL - Tcl_FindExecutable(argv[0]); - CONST char *cp=Tcl_GetNameOfExecutable(); - Tcl_Zvfs_Boot(cp,TCLKIT_VFSMOUNT,TCLKIT_INIT,TCLKIT_PASSWD); + Tcl_Main(argc, argv, TCL_LOCAL_APPINIT); return 0; /* Needed only to prevent compiler warning. */ } @@ -119,11 +111,7 @@ Tcl_AppInit( if ((Tcl_Init)(interp) == TCL_ERROR) { return TCL_ERROR; } - /* Load the zipfs package */ - if (Tclzipfs_Init(interp) == TCL_ERROR) { - return TCL_ERROR; - } - Tcl_StaticPackage(interp, "zipfs", Tclzipfs_Init, Tclzipfs_SafeInit); + #ifdef TCL_XT_TEST if (Tclxttest_Init(interp) == TCL_ERROR) { return TCL_ERROR; diff --git a/win/Makefile.in b/win/Makefile.in index e4ca501..118ccb1 100644 --- a/win/Makefile.in +++ b/win/Makefile.in @@ -152,6 +152,7 @@ SHARED_LIBRARIES = $(TCL_DLL_FILE) @ZLIB_DLL_FILE@ STATIC_LIBRARIES = $(TCL_LIB_FILE) TCLSH = tclsh$(VER)${EXESUFFIX} +TCLKIT = tclkit$(VER)${EXESUFFIX} CAT32 = cat32$(EXEEXT) MAN2TCL = man2tcl$(EXEEXT) @@ -303,7 +304,7 @@ GENERIC_OBJS = \ tclUtil.$(OBJEXT) \ tclVar.$(OBJEXT) \ tclZlib.$(OBJEXT) \ - zipfs.$(OBJEXT) + tclZipfs.$(OBJEXT) TOMMATH_OBJS = \ bncore.${OBJEXT} \ @@ -399,6 +400,8 @@ STUB_OBJS = \ TCLSH_OBJS = tclAppInit.$(OBJEXT) +TCLKIT_OBJS = tclkitMain.${OBJEXT} tclkit.${OBJEXT} + ZLIB_OBJS = \ adler32.$(OBJEXT) \ compress.$(OBJEXT) \ @@ -420,7 +423,7 @@ all: binaries libraries doc packages tcltest: $(TCLSH) $(TEST_DLL_FILE) -binaries: $(TCL_STUB_LIB_FILE) @LIBRARIES@ winextensions $(TCLSH) +binaries: $(TCL_STUB_LIB_FILE) @LIBRARIES@ winextensions $(TCLSH) $(TCLKIT) winextensions: ${DDE_DLL_FILE} ${REG_DLL_FILE} @@ -433,6 +436,11 @@ $(TCLSH): $(TCLSH_OBJS) @LIBRARIES@ $(TCL_STUB_LIB_FILE) tclsh.$(RES) tclsh.$(RES) $(CC_EXENAME) $(LDFLAGS_CONSOLE) @VC_MANIFEST_EMBED_EXE@ +$(TCLKIT): $(TCLKIT_OBJ) @LIBRARIES@ $(TCL_STUB_LIB_FILE) tclsh.$(RES) + $(CC) $(CFLAGS) $(TCLKIT_OBJ) $(TCL_LIB_FILE) $(TCL_STUB_LIB_FILE) $(LIBS) \ + tclsh.$(RES) $(CC_EXENAME) $(LDFLAGS_CONSOLE) + @VC_MANIFEST_EMBED_EXE@ + cat32.$(OBJEXT): cat.c $(CC) -c $(CC_SWITCHES) @DEPARG@ $(CC_OBJNAME) @@ -496,6 +504,9 @@ testMain.${OBJEXT}: tclAppInit.c tclMain2.${OBJEXT}: tclMain.c $(CC) -c $(CC_SWITCHES) -DBUILD_tcl -DTCL_ASCII_MAIN @DEPARG@ $(CC_OBJNAME) +tclkitMain.${OBJEXT}: tclAppInit.c + $(CC) -c $(CC_SWITCHES) -DTCL_LOCAL_MAIN_HOOK="Tclkit_MainHook" -DTCL_LOCAL_APPINIT="Tclkit_AppInit" @DEPARG@ $(CC_OBJNAME) + # TIP #59, embedding of configuration information into the binary library. # # Part of Tcl's configuration information are the paths where it was installed diff --git a/win/makefile.vc b/win/makefile.vc index ec7afac..cf7d422 100644 --- a/win/makefile.vc +++ b/win/makefile.vc @@ -345,7 +345,7 @@ COREOBJS = \ $(TMP_DIR)\tclUtil.obj \ $(TMP_DIR)\tclVar.obj \ $(TMP_DIR)\tclZlib.obj \ - $(TMP_DIR)\zipfs.obj + $(TMP_DIR)\tclZipfs.obj ZLIBOBJS = \ $(TMP_DIR)\adler32.obj \ diff --git a/win/tclAppInit.c b/win/tclAppInit.c index 1c3ef9b..e06eaf5 100644 --- a/win/tclAppInit.c +++ b/win/tclAppInit.c @@ -25,13 +25,10 @@ #include #ifdef TCL_TEST -#include "tclZipfs.h" extern Tcl_PackageInitProc Tcltest_Init; extern Tcl_PackageInitProc Tcltest_SafeInit; #endif /* TCL_TEST */ -MODULE_SCOPE int Tcl_Zvfs_Boot(const char *,const char *,const char *); - #if defined(STATIC_BUILD) && TCL_USE_STATIC_PACKAGES extern Tcl_PackageInitProc Registry_Init; extern Tcl_PackageInitProc Dde_Init; @@ -128,13 +125,7 @@ _tmain( #ifdef TCL_LOCAL_MAIN_HOOK TCL_LOCAL_MAIN_HOOK(&argc, &argv); #endif -#ifdef TCL_ZIPVFS - #define TCLKIT_INIT "main.tcl" - #define TCLKIT_VFSMOUNT "/zvfs" - Tcl_FindExecutable(argv[0]); - CONST char *cp=Tcl_GetNameOfExecutable(); - Tcl_Zvfs_Boot(cp,TCLKIT_VFSMOUNT,TCLKIT_INIT); -#endif + Tcl_Main(argc, argv, TCL_LOCAL_APPINIT); return 0; /* Needed only to prevent compiler warning. */ } @@ -165,9 +156,6 @@ Tcl_AppInit( if ((Tcl_Init)(interp) == TCL_ERROR) { return TCL_ERROR; } - if(Tcl_StaticPackage(interp, "zipfs", Tclzipfs_Init, Tclzipfs_SafeInit) == TCL_ERROR ) { - return TCL_ERROR; - } #if defined(STATIC_BUILD) && TCL_USE_STATIC_PACKAGES if (Registry_Init(interp) == TCL_ERROR) { @@ -186,9 +174,6 @@ Tcl_AppInit( return TCL_ERROR; } Tcl_StaticPackage(interp, "Tcltest", Tcltest_Init, Tcltest_SafeInit); - if (Tclzipfs_Init(interp) == TCL_ERROR) { - return TCL_ERROR; - } #endif /* TCL_TEST */ /* -- cgit v0.12 From 58ab27bf86284012b5dba6df12a30f10ecee6491 Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Wed, 14 Sep 2016 13:36:27 +0000 Subject: Fixed the line endings on practcl.tcl --- library/practcl/practcl.tcl | 7998 +++++++++++++++++++++---------------------- 1 file changed, 3999 insertions(+), 3999 deletions(-) diff --git a/library/practcl/practcl.tcl b/library/practcl/practcl.tcl index 3b4b04e..f285116 100644 --- a/library/practcl/practcl.tcl +++ b/library/practcl/practcl.tcl @@ -1,4000 +1,4000 @@ -### -# Practcl -# An object oriented templating system for stamping out Tcl API calls to C -### -puts [list LOADED practcl.tcl from [info script]] -package require TclOO -proc ::debug args { - #puts $args - ::practcl::cputs ::DEBUG_INFO $args -} - -### -# Drop in a static copy of Tcl -### -proc ::doexec args { - puts [list {*}$args] - exec {*}$args >&@ stdout -} - -proc ::dotclexec args { - puts [list [info nameofexecutable] {*}$args] - exec [info nameofexecutable] {*}$args >&@ stdout -} - -proc ::domake {path args} { - set PWD [pwd] - cd $path - puts [list *** $path ***] - puts [list make {*}$args] - exec make {*}$args >&@ stdout - cd $PWD -} - -proc ::domake.tcl {path args} { - set PWD [pwd] - cd $path - puts [list *** $path ***] - puts [list make.tcl {*}$args] - exec [info nameofexecutable] make.tcl {*}$args >&@ stdout - cd $PWD -} - -proc ::fossil {path args} { - set PWD [pwd] - cd $path - puts [list {*}$args] - exec fossil {*}$args >&@ stdout - cd $PWD -} - - -proc ::fossil_status {dir} { - if {[info exists ::fosdat($dir)]} { - return $::fosdat($dir) - } - set result { -tags experimental -version {} - } - set pwd [pwd] - cd $dir - set info [exec fossil status] - cd $pwd - foreach line [split $info \n] { - if {[lindex $line 0] eq "checkout:"} { - set hash [lindex $line end-3] - set maxdate [lrange $line end-2 end-1] - dict set result hash $hash - dict set result maxdate $maxdate - regsub -all {[^0-9]} $maxdate {} isodate - dict set result isodate $isodate - } - if {[lindex $line 0] eq "tags:"} { - set tags [lrange $line 1 end] - dict set result tags $tags - break - } - } - set ::fosdat($dir) $result - return $result -} -### -# Seek out Tcllib if it's available -### -set tcllib_path {} -foreach path {.. ../.. ../../..} { - foreach path [glob -nocomplain [file join [file normalize $path] tcllib* modules]] { - set tclib_path $path - lappend ::auto_path $path - break - } - if {$tcllib_path ne {}} break -} - - -### -# Build utility functions -### -namespace eval ::practcl {} - -proc ::practcl::os {} { - if {[info exists ::project(TEACUP_OS)] && $::project(TEACUP_OS) ni {"@TEACUP_OS@" {}}} { - return $::project(TEACUP_OS) - } - set info [::practcl::config.tcl $::project(builddir)] - if {[dict exists $info TEACUP_OS]} { - return [dict get $info TEACUP_OS] - } - return unknown -} - -### -# Detect local platform -### -proc ::practcl::config.tcl {path} { - dict set result buildpath $path - set result {} - if {[file exists [file join $path config.tcl]]} { - set fin [open [file join $path config.tcl] r] - set bufline {} - set rawcount 0 - set linecount 0 - while {[gets $fin thisline]>=0} { - incr rawcount - append bufline \n $thisline - if {![info complete $bufline]} continue - set line [string trimleft $bufline] - set bufline {} - if {[string index [string trimleft $line] 0] eq "#"} continue - incr linecount - set key [lindex $line 0] - set value [lindex $line 1] - dict set result $key $value - } - dict set result sandbox [file dirname [dict get $result srcdir]] - dict set result download [file join [dict get $result sandbox] download] - dict set result teapot [file join [dict get $result sandbox] teapot] - set result [::practcl::de_shell $result] - } - # If data is available from autoconf, defer to that - if {[dict exists $result TEACUP_OS] && [dict get $result TEACUP_OS] ni {"@TEACUP_OS@" {}}} { - return $result - } - # If autoconf hasn't run yet, assume we are not cross compiling - # and defer to local checks - dict set result TEACUP_PROFILE unknown - dict set result TEACUP_OS unknown - dict set result EXEEXT {} - if {$::tcl_platform(platform) eq "windows"} { - set system "windows" - set arch ix86 - dict set result TEACUP_PROFILE win32-ix86 - dict set result TEACUP_OS windows - dict set result EXEEXT .exe - } else { - set system [exec uname -s]-[exec uname -r] - set arch unknown - dict set result TEACUP_OS generic - } - dict set result TEA_PLATFORM $system - dict set result TEA_SYSTEM $system - switch -glob $system { - Linux* { - dict set result TEACUP_OS linux - set arch [exec uname -m] - dict set result TEACUP_PROFILE "linux-glibc2.3-$arch" - } - GNU* { - set arch [exec uname -m] - dict set result TEACUP_OS "gnu" - } - NetBSD-Debian { - set arch [exec uname -m] - dict set result TEACUP_OS "netbsd-debian" - } - OpenBSD-* { - set arch [exec arch -s] - dict set result TEACUP_OS "openbsd" - } - Darwin* { - set arch [exec uname -m] - dict set result TEACUP_OS "macosx" - if {$arch eq "x86_64"} { - dict set result TEACUP_PROFILE "macosx10.5-i386-x86_84" - } else { - dict set result TEACUP_PROFILE "macosx-universal" - } - } - OpenBSD* { - set arch [exec arch -s] - dict set result TEACUP_OS "openbsd" - } - } - if {$arch eq "unknown"} { - catch {set arch [exec uname -m]} - } - switch -glob $arch { - i*86 { - set arch "ix86" - } - amd64 { - set arch "x86_64" - } - } - dict set result TEACUP_ARCH $arch - if {[dict get $result TEACUP_PROFILE] eq "unknown"} { - dict set result TEACUP_PROFILE [dict get $result TEACUP_OS]-$arch - } - return $result -} - - -### -# Convert an MSYS path to a windows native path -### -if {$::tcl_platform(platform) eq "windows"} { -proc ::practcl::msys_to_tclpath msyspath { - return [exec sh -c "cd $msyspath ; pwd -W"] -} -} else { -proc ::practcl::msys_to_tclpath msyspath { - return [file normalize $msyspath] -} -} - -### -# Bits stolen from fileutil -### -proc ::practcl::cat fname { - set fname [open $fname r] - set data [read $fname] - close $fname - return $data -} - -proc ::practcl::file_lexnormalize {sp} { - set spx [file split $sp] - - # Resolution of embedded relative modifiers (., and ..). - - if { - ([lsearch -exact $spx . ] < 0) && - ([lsearch -exact $spx ..] < 0) - } { - # Quick path out if there are no relative modifiers - return $sp - } - - set absolute [expr {![string equal [file pathtype $sp] relative]}] - # A volumerelative path counts as absolute for our purposes. - - set sp $spx - set np {} - set noskip 1 - - while {[llength $sp]} { - set ele [lindex $sp 0] - set sp [lrange $sp 1 end] - set islast [expr {[llength $sp] == 0}] - - if {[string equal $ele ".."]} { - if { - ($absolute && ([llength $np] > 1)) || - (!$absolute && ([llength $np] >= 1)) - } { - # .. : Remove the previous element added to the - # new path, if there actually is enough to remove. - set np [lrange $np 0 end-1] - } - } elseif {[string equal $ele "."]} { - # Ignore .'s, they stay at the current location - continue - } else { - # A regular element. - lappend np $ele - } - } - if {[llength $np] > 0} { - return [eval [linsert $np 0 file join]] - # 8.5: return [file join {*}$np] - } - return {} -} - -proc ::practcl::file_relative {base dst} { - # Ensure that the link to directory 'dst' is properly done relative to - # the directory 'base'. - - if {![string equal [file pathtype $base] [file pathtype $dst]]} { - return -code error "Unable to compute relation for paths of different pathtypes: [file pathtype $base] vs. [file pathtype $dst], ($base vs. $dst)" - } - - set base [file_lexnormalize [file join [pwd] $base]] - set dst [file_lexnormalize [file join [pwd] $dst]] - - set save $dst - set base [file split $base] - set dst [file split $dst] - - while {[string equal [lindex $dst 0] [lindex $base 0]]} { - set dst [lrange $dst 1 end] - set base [lrange $base 1 end] - if {![llength $dst]} {break} - } - - set dstlen [llength $dst] - set baselen [llength $base] - - if {($dstlen == 0) && ($baselen == 0)} { - # Cases: - # (a) base == dst - - set dst . - } else { - # Cases: - # (b) base is: base/sub = sub - # dst is: base = {} - - # (c) base is: base = {} - # dst is: base/sub = sub - - while {$baselen > 0} { - set dst [linsert $dst 0 ..] - incr baselen -1 - } - # 8.5: set dst [file join {*}$dst] - set dst [eval [linsert $dst 0 file join]] - } - - return $dst -} - -### -# Unpack the source of a fossil project into a designated location -### -proc ::practcl::fossil_sandbox {pkg args} { - if {[llength $args]==1} { - set info [lindex $args 0] - } else { - set info $args - } - set result $info - if {[dict exists $info srcroot]} { - set srcroot [dict get $info srcroot] - } elseif {[dict exists $info sandbox]} { - set srcroot [file join [dict get $info sandbox] $pkg] - } else { - set srcroot [file join $::CWD .. $pkg] - } - dict set result srcroot $srcroot - puts [list fossil_sandbox $pkg $srcroot] - if {[dict exists $info download]} { - ### - # Source is actually a zip archive - ### - set download [dict get $info download] - if {[file exists [file join $download $pkg.zip]]} { - if {![info exists $srcroot]} { - package require zipfile::decode - ::zipfile::decode::unzipfile [file join $download $pkg.zip] $srcroot - } - return - } - } - variable fossil_dbs - if {![::info exists fossil_dbs]} { - # Get a list of local fossil databases - set fossil_dbs [exec fossil all list] - } - set CWD [pwd] - if {![dict exists $info tag]} { - set tag trunk - } else { - set tag [dict get $info tag] - } - dict set result tag $tag - - try { - if {[file exists [file join $srcroot .fslckout]]} { - if {[dict exists $info update] && [dict get $info update]==1} { - catch { - puts "FOSSIL UPDATE" - cd $srcroot - doexec fossil update $tag - } - } - } elseif {[file exists [file join $srcroot _FOSSIL_]]} { - if {[dict exists $info update] && [dict get $info update]==1} { - catch { - puts "FOSSIL UPDATE" - cd $srcroot - doexec fossil update $tag - } - } - } else { - puts "OPEN AND UNPACK" - set fosdb {} - foreach line [split $fossil_dbs \n] { - set line [string trim $line] - if {[file rootname [file tail $line]] eq $pkg} { - set fosdb $line - break - } - } - if {$fosdb eq {}} { - file mkdir [file join $download fossil] - set fosdb [file join $download fossil $pkg.fos] - set cloned 0 - if {[dict exists $info localmirror]} { - set localmirror [dict get $info localmirror] - catch { - doexec fossil clone $localmirror/$pkg $fosdb - set cloned 1 - } - } - if {!$cloned && [dict exists $info fossil_url]} { - set localmirror [dict get $info fossil_url] - catch { - doexec fossil clone $localmirror/$pkg $fosdb - set cloned 1 - } - } - if {!$cloned} { - doexec fossil clone http://fossil.etoyoc.com/fossil/$pkg $fosdb - } - } - file mkdir $srcroot - cd $srcroot - puts "FOSSIL OPEN [pwd]" - doexec fossil open $fosdb $tag - } - } on error {result opts} { - puts [list ERR [dict get $opts -errorinfo]] - return {*}$opts - } finally { - cd $CWD - } - return $result -} - -### -# topic: e71f3f61c348d56292011eec83e95f0aacc1c618 -# description: Converts a XXX.sh file into a series of Tcl variables -### -proc ::practcl::read_sh_subst {line info} { - regsub -all {\x28} $line \x7B line - regsub -all {\x29} $line \x7D line - - #set line [string map $key [string trim $line]] - foreach {field value} $info { - catch {set $field $value} - } - if [catch {subst $line} result] { - return {} - } - set result [string trim $result] - return [string trim $result '] -} - -### -# topic: 03567140cca33c814664c7439570f669b9ab88e6 -### -proc ::practcl::read_sh_file {filename {localdat {}}} { - set fin [open $filename r] - set result {} - if {$localdat eq {}} { - set top 1 - set local [array get ::env] - dict set local EXE {} - } else { - set top 0 - set local $localdat - } - while {[gets $fin line] >= 0} { - set line [string trim $line] - if {[string index $line 0] eq "#"} continue - if {$line eq {}} continue - catch { - if {[string range $line 0 6] eq "export "} { - set eq [string first "=" $line] - set field [string trim [string range $line 6 [expr {$eq - 1}]]] - set value [read_sh_subst [string range $line [expr {$eq+1}] end] $local] - dict set result $field [read_sh_subst $value $local] - dict set local $field $value - } elseif {[string range $line 0 7] eq "include "} { - set subfile [read_sh_subst [string range $line 7 end] $local] - foreach {field value} [read_sh_file $subfile $local] { - dict set result $field $value - } - } else { - set eq [string first "=" $line] - if {$eq > 0} { - set field [read_sh_subst [string range $line 0 [expr {$eq - 1}]] $local] - set value [string trim [string range $line [expr {$eq+1}] end] '] - #set value [read_sh_subst [string range $line [expr {$eq+1}] end] $local] - dict set local $field $value - dict set result $field $value - } - } - } err opts - if {[dict get $opts -code] != 0} { - #puts $opts - puts "Error reading line:\n$line\nerr: $err\n***" - return $err {*}$opts - } - } - return $result -} - -### -# A simpler form of read_sh_file tailored -# to pulling data from (tcl|tk)Config.sh -### -proc ::practcl::read_Config.sh filename { - set fin [open $filename r] - set result {} - set linecount 0 - while {[gets $fin line] >= 0} { - set line [string trim $line] - if {[string index $line 0] eq "#"} continue - if {$line eq {}} continue - catch { - set eq [string first "=" $line] - if {$eq > 0} { - set field [string range $line 0 [expr {$eq - 1}]] - set value [string trim [string range $line [expr {$eq+1}] end] '] - #set value [read_sh_subst [string range $line [expr {$eq+1}] end] $local] - dict set result $field $value - incr $linecount - } - } err opts - if {[dict get $opts -code] != 0} { - #puts $opts - puts "Error reading line:\n$line\nerr: $err\n***" - return $err {*}$opts - } - } - return $result -} - -### -# A simpler form of read_sh_file tailored -# to pulling data from a Makefile -### -proc ::practcl::read_Makefile filename { - set fin [open $filename r] - set result {} - while {[gets $fin line] >= 0} { - set line [string trim $line] - if {[string index $line 0] eq "#"} continue - if {$line eq {}} continue - catch { - set eq [string first "=" $line] - if {$eq > 0} { - set field [string trim [string range $line 0 [expr {$eq - 1}]]] - set value [string trim [string trim [string range $line [expr {$eq+1}] end] ']] - switch $field { - PKG_LIB_FILE { - dict set result libfile $value - } - srcdir { - if {$value eq "."} { - dict set result srcdir [file dirname $filename] - } else { - dict set result srcdir $value - } - } - PACKAGE_NAME { - dict set result name $value - } - PACKAGE_VERSION { - dict set result version $value - } - LIBS { - dict set result PRACTCL_LIBS $value - } - PKG_LIB_FILE { - dict set result libfile $value - } - } - } - } err opts - if {[dict get $opts -code] != 0} { - #puts $opts - puts "Error reading line:\n$line\nerr: $err\n***" - return $err {*}$opts - } - # the Compile field is about where most TEA files start getting silly - if {$field eq "compile"} { - break - } - } - return $result -} - -## Append arguments to a buffer -# The command works like puts in that each call will also insert -# a line feed. Unlike puts, blank links in the interstitial are -# suppressed -proc ::practcl::cputs {varname args} { - upvar 1 $varname buffer - if {[llength $args]==1 && [string length [string trim [lindex $args 0]]] == 0} { - - } - if {[info exist buffer]} { - if {[string index $buffer end] ne "\n"} { - append buffer \n - } - } else { - set buffer \n - } - # Trim leading \n's - append buffer [string trimleft [lindex $args 0] \n] {*}[lrange $args 1 end] -} - - -proc ::practcl::tcl_to_c {body} { - set result {} - foreach rawline [split $body \n] { - set line [string map [list \" \\\" \\ \\\\] $rawline] - cputs result "\n \"$line\\n\" \\" - } - return [string trimright $result \\] -} - - -proc ::practcl::_tagblock {text {style tcl} {note {}}} { - if {[string length [string trim $text]]==0} { - return {} - } - set output {} - switch $style { - tcl { - ::practcl::cputs output "# BEGIN $note" - } - c { - ::practcl::cputs output "/* BEGIN $note */" - } - default { - ::practcl::cputs output "# BEGIN $note" - } - } - ::practcl::cputs output $text - switch $style { - tcl { - ::practcl::cputs output "# END $note" - } - c { - ::practcl::cputs output "/* END $note */" - } - default { - ::practcl::cputs output "# END $note" - } - } - return $output -} - -proc ::practcl::_isdirectory name { - return [file isdirectory $name] -} - -### -# Return true if the pkgindex file contains -# any statement other than "package ifneeded" -# and/or if any package ifneeded loads a DLL -### -proc ::practcl::_pkgindex_directory {path} { - set buffer {} - set pkgidxfile [file join $path pkgIndex.tcl] - if {![file exists $pkgidxfile]} { - # No pkgIndex file, read the source - foreach file [glob -nocomplain $path/*.tm] { - set file [file normalize $file] - set fname [file rootname [file tail $file]] - ### - # We used to be able to ... Assume the package is correct in the filename - # No hunt for a "package provides" - ### - set package [lindex [split $fname -] 0] - set version [lindex [split $fname -] 1] - ### - # Read the file, and override assumptions as needed - ### - set fin [open $file r] - set dat [read $fin] - close $fin - # Look for a teapot style Package statement - foreach line [split $dat \n] { - set line [string trim $line] - if { [string range $line 0 9] != "# Package " } continue - set package [lindex $line 2] - set version [lindex $line 3] - break - } - # Look for a package provide statement - foreach line [split $dat \n] { - set line [string trim $line] - if { [string range $line 0 14] != "package provide" } continue - set package [lindex $line 2] - set version [lindex $line 3] - break - } - append buffer "package ifneeded $package $version \[list source \[file join \$dir [file tail $file]\]\]" \n - } - foreach file [glob -nocomplain $path/*.tcl] { - if { [file tail $file] == "version_info.tcl" } continue - set fin [open $file r] - set dat [read $fin] - close $fin - if {![regexp "package provide" $dat]} continue - set fname [file rootname [file tail $file]] - # Look for a package provide statement - foreach line [split $dat \n] { - set line [string trim $line] - if { [string range $line 0 14] != "package provide" } continue - set package [lindex $line 2] - set version [lindex $line 3] - if {[string index $package 0] in "\$ \["} continue - if {[string index $version 0] in "\$ \["} continue - append buffer "package ifneeded $package $version \[list source \[file join \$dir [file tail $file]\]\]" \n - break - } - } - return $buffer - } - set fin [open $pkgidxfile r] - set dat [read $fin] - close $fin - set thisline {} - foreach line [split $dat \n] { - append thisline $line \n - if {![info complete $thisline]} continue - set line [string trim $line] - if {[string length $line]==0} { - set thisline {} ; continue - } - if {[string index $line 0] eq "#"} { - set thisline {} ; continue - } - try { - # Ignore contditionals - if {[regexp "if.*catch.*package.*Tcl.*return" $thisline]} continue - if {[regexp "if.*package.*vsatisfies.*package.*provide.*return" $thisline]} continue - if {![regexp "package.*ifneeded" $thisline]} { - # This package index contains arbitrary code - # source instead of trying to add it to the master - # package index - return {source [file join $dir pkgIndex.tcl]} - } - append buffer $thisline \n - } on error {err opts} { - puts *** - puts "GOOF: $pkgidxfile" - puts $line - puts $err - puts [dict get $opts -errorinfo] - puts *** - } finally { - set thisline {} - } - } - return $buffer -} - - -proc ::practcl::_pkgindex_path_subdir {path} { - set result {} - foreach subpath [glob -nocomplain [file join $path *]] { - if {[file isdirectory $subpath]} { - lappend result $subpath {*}[_pkgindex_path_subdir $subpath] - } - } - return $result -} -### -# Index all paths given as though they will end up in the same -# virtual file system -### -proc ::practcl::pkgindex_path args { - set stack {} - set buffer { -lappend ::PATHSTACK $dir - } - foreach base $args { - set base [file normalize $base] - set paths [::practcl::_pkgindex_path_subdir $base] - set i [string length $base] - # Build a list of all of the paths - foreach path $paths { - if {$path eq $base} continue - set path_indexed($path) 0 - } - set path_indexed($base) 1 - set path_indexed([file join $base boot tcl]) 1 - #set path_index([file join $base boot tk]) 1 - - foreach path $paths { - if {$path_indexed($path)} continue - set thisdir [file_relative $base $path] - #set thisdir [string range $path $i+1 end] - set idxbuf [::practcl::_pkgindex_directory $path] - if {[string length $idxbuf]} { - incr path_indexed($path) - append buffer "set dir \[set PKGDIR \[file join \[lindex \$::PATHSTACK end\] $thisdir\]\]" \n - append buffer [string map {$dir $PKGDIR} [string trimright $idxbuf]] \n - } - } - } - append buffer { -set dir [lindex $::PATHSTACK end] -set ::PATHSTACK [lrange $::PATHSTACK 0 end-1] -} - return $buffer -} - -### -# topic: 64319f4600fb63c82b2258d908f9d066 -# description: Script to build the VFS file system -### -proc ::practcl::installDir {d1 d2} { - - puts [format {%*sCreating %s} [expr {4 * [info level]}] {} [file tail $d2]] - file delete -force -- $d2 - file mkdir $d2 - - foreach ftail [glob -directory $d1 -nocomplain -tails *] { - set f [file join $d1 $ftail] - if {[file isdirectory $f] && [string compare CVS $ftail]} { - installDir $f [file join $d2 $ftail] - } elseif {[file isfile $f]} { - file copy -force $f [file join $d2 $ftail] - if {$::tcl_platform(platform) eq {unix}} { - file attributes [file join $d2 $ftail] -permissions 0644 - } else { - file attributes [file join $d2 $ftail] -readonly 1 - } - } - } - - if {$::tcl_platform(platform) eq {unix}} { - file attributes $d2 -permissions 0755 - } else { - file attributes $d2 -readonly 1 - } -} - -proc ::practcl::copyDir {d1 d2} { - #puts [list $d1 -> $d2] - #file delete -force -- $d2 - file mkdir $d2 - - foreach ftail [glob -directory $d1 -nocomplain -tails *] { - set f [file join $d1 $ftail] - if {[file isdirectory $f] && [string compare CVS $ftail]} { - copyDir $f [file join $d2 $ftail] - } elseif {[file isfile $f]} { - file copy -force $f [file join $d2 $ftail] - } - } -} - -::oo::class create ::practcl::metaclass { - superclass ::oo::object - - method script script { - eval $script - } - - method source filename { - source $filename - } - - method initialize {} {} - - method define {submethod args} { - my variable define - switch $submethod { - dump { - return [array get define] - } - add { - set field [lindex $args 0] - if {![info exists define($field)]} { - set define($field) {} - } - foreach arg [lrange $args 1 end] { - if {$arg ni $define($field)} { - lappend define($field) $arg - } - } - return $define($field) - } - remove { - set field [lindex $args 0] - if {![info exists define($field)]} { - return - } - set rlist [lrange $args 1 end] - set olist $define($field) - set nlist {} - foreach arg $olist { - if {$arg in $rlist} continue - lappend nlist $arg - } - set define($field) $nlist - return $nlist - } - exists { - set field [lindex $args 0] - return [info exists define($field)] - } - getnull - - get - - cget { - set field [lindex $args 0] - if {[info exists define($field)]} { - return $define($field) - } - return [lindex $args 1] - } - set { - if {[llength $args]==1} { - set arglist [lindex $args 0] - } else { - set arglist $args - } - array set define $arglist - if {[dict exists $arglist class]} { - my select - } - } - default { - array $submethod define {*}$args - } - } - } - - method graft args { - my variable organs - if {[llength $args] == 1} { - error "Need two arguments" - } - set object {} - foreach {stub object} $args { - dict set organs $stub $object - oo::objdefine [self] forward <${stub}> $object - oo::objdefine [self] export <${stub}> - } - return $object - } - - method organ {{stub all}} { - my variable organs - if {![info exists organs]} { - return {} - } - if { $stub eq "all" } { - return $organs - } - if {[dict exists $organs $stub]} { - return [dict get $organs $stub] - } - } - - method link {command args} { - my variable links - switch $command { - object { - foreach obj $args { - foreach linktype [$obj linktype] { - my link add $linktype $obj - } - } - } - add { - ### - # Add a link to an object that was externally created - ### - if {[llength $args] ne 2} { error "Usage: link add LINKTYPE OBJECT"} - lassign $args linktype object - if {[info exists links($linktype)] && $object in $links($linktype)} { - return - } - lappend links($linktype) $object - } - remove { - set object [lindex $args 0] - if {[llength $args]==1} { - set ltype * - } else { - set ltype [lindex $args 1] - } - foreach {linktype elements} [array get links $ltype] { - if {$object in $elements} { - set nlist {} - foreach e $elements { - if { $object ne $e } { lappend nlist $e } - } - set links($linktype) $nlist - } - } - } - list { - if {[llength $args]==0} { - return [array get links] - } - if {[llength $args] != 1} { error "Usage: link list LINKTYPE"} - set linktype [lindex $args 0] - if {![info exists links($linktype)]} { - return {} - } - return $links($linktype) - } - dump { - return [array get links] - } - } - } - - method select {} { - my variable define - set class {} - if {[info exists define(class)]} { - if {[info command $define(class)] ne {}} { - set class $define(class) - } elseif {[info command ::practcl::$define(class)] ne {}} { - set class ::practcl::$define(class) - } else { - switch $define(class) { - default { - set class ::practcl::object - } - } - } - } - if {$class ne {}} { - ::oo::objdefine [self] class $class - } - if {[::info exists define(oodefine)]} { - ::oo::objdefine [self] $define(oodefine) - unset define(oodefine) - } - } -} - -proc ::practcl::trigger {args} { - foreach name $args { - if {[dict exists $::make_objects $name]} { - [dict get $::make_objects $name] triggers - } - } -} - -proc ::practcl::depends {args} { - foreach name $args { - if {[dict exists $::make_objects $name]} { - [dict get $::make_objects $name] check - } - } -} - -proc ::practcl::target {name info} { - set obj [::practcl::target_obj new $name $info] - dict set ::make_objects $name $obj - if {[dict exists $info aliases]} { - foreach item [dict get $info aliases] { - if {![dict exists $::make_objects $item]} { - dict set ::make_objects $item $obj - } - } - } - set ::make($name) 0 - set ::trigger($name) 0 - set filename [$obj define get filename] - if {$filename ne {}} { - set ::target($name) $filename - } -} - -### Batch Tasks - -namespace eval ::practcl::build {} - -## method DEFS -# This method populates 4 variables: -# name - The name of the package -# version - The version of the package -# defs - C flags passed to the compiler -# includedir - A list of paths to feed to the compiler for finding headers -# -proc ::practcl::build::DEFS {PROJECT DEFS namevar versionvar defsvar} { - upvar 1 $namevar name $versionvar version NAME NAME $defsvar defs - set name [string tolower [${PROJECT} define get name [${PROJECT} define get pkg_name]]] - set NAME [string toupper $name] - set version [${PROJECT} define get version [${PROJECT} define get pkg_vers]] - if {$version eq {}} { - set version 0.1a - } - set defs {} - append defs " -DPACKAGE_NAME=\"${name}\" -DPACKAGE_VERSION=\"${version}\"" - append defs " -DPACKAGE_TARNAME=\"${name}\" -DPACKAGE_STRING=\"${name}\x5c\x20${version}\"" - set NAME [string toupper $name] - set idx 0 - set count 0 - while {$idx>=0} { - set ndx [string first " -D" $DEFS $idx+1] - set item [string range $DEFS $idx $ndx] - set item [string trim $item] - set item [string trimleft $item -D] - if {[string range $item 0 7] eq "PACKAGE_"} { - set idx $ndx - continue - } - set eqidx [string first = $item ] - if {$eqidx < 0} { - append defs { } $item - set idx $ndx - continue - } - - set field [string range $item 0 [expr {$eqidx-1}]] - set value [string range $item [expr {$eqidx+1}] end] - set emap {} - lappend emap \x5c \x5c\x5c \x20 \x5c\x20 \x22 \x5c\x22 \x28 \x5c\x28 \x29 \x5c\x29 - if {[string is integer -strict $value]} { - append defs " -D${field}=$value" - } else { - append defs " -D${field}=[string map $emap $value]" - } - set idx $ndx - } - return $defs -} - -proc ::practcl::build::tclkit_main {PROJECT PKG_OBJS} { - ### - # Build static package list - ### - set statpkglist {} - dict set statpkglist Tk {autoload 0} - puts [list TCLKIT MAIN $PROJECT] - - foreach {ofile info} [${PROJECT} compile-products] { - puts [list * PROD $ofile $info] - if {![dict exists $info object]} continue - set cobj [dict get $info object] - foreach {pkg info} [$cobj static-packages] { - dict set statpkglist $pkg $info - } - } - foreach cobj [list {*}${PKG_OBJS} $PROJECT] { - puts [list * PROG $cobj] - foreach {pkg info} [$cobj static-packages] { - puts [list * PKG $pkg $info] - dict set statpkglist $pkg $info - } - } - - set result {} - $PROJECT include {} - $PROJECT include {"tclInt.h"} - $PROJECT include {"tclFileSystem.h"} - $PROJECT include {} - $PROJECT include {} - $PROJECT include {} - $PROJECT include {} - $PROJECT include {} - - $PROJECT code header { -#ifndef MODULE_SCOPE -# define MODULE_SCOPE extern -#endif - -/* -** Provide a dummy Tcl_InitStubs if we are using this as a static -** library. -*/ -#ifndef USE_TCL_STUBS -# undef Tcl_InitStubs -# define Tcl_InitStubs(a,b,c) TCL_VERSION -#endif -#define STATIC_BUILD 1 -#undef USE_TCL_STUBS - -/* Make sure the stubbed variants of those are never used. */ -#undef Tcl_ObjSetVar2 -#undef Tcl_NewStringObj -#undef Tk_Init -#undef Tk_MainEx -#undef Tk_SafeInit -} - - # Build an area of the file for #define directives and - # function declarations - set define {} - set mainhook [$PROJECT define get TCL_LOCAL_MAIN_HOOK Tclkit_MainHook] - set mainfunc [$PROJECT define get TCL_LOCAL_APPINIT Tclkit_AppInit] - set mainscript [$PROJECT define get main.tcl main.tcl] - set vfsroot [$PROJECT define get vfsroot zipfs:/app] - set vfs_main "${vfsroot}/${mainscript}" - set vfs_tcl_library "${vfsroot}/boot/tcl" - set vfs_tk_library "${vfsroot}/boot/tk" - - set map {} - foreach var { - vfsroot mainhook mainfunc vfs_main vfs_tcl_library vfs_tk_library - } { - dict set map %${var}% [set $var] - } - set preinitscript { -set ::odie(boot_vfs) {%vfsroot%} -set ::SRCDIR {%vfsroot%} -if {[file exists {%vfs_tcl_library%}]} { - set ::tcl_library {%vfs_tcl_library%} - set ::auto_path {} -} -if {[file exists {%vfs_tk_library%}]} { - set ::tk_library {%vfs_tk_library%} -} -} ; # Preinitscript - - set zvfsboot { -/* - * %mainhook% -- - * Performs the argument munging for the shell - */ - } - ::practcl::cputs zvfsboot { - CONST char *archive; - Tcl_FindExecutable(*argv[0]); - archive=Tcl_GetNameOfExecutable(); - - Tclzipfs_Init(NULL); - } - # We have to initialize the virtual filesystem before calling - # Tcl_Init(). Otherwise, Tcl_Init() will not be able to find - # its startup script files. - $PROJECT include {"tclZipfs.h"} - - ::practcl::cputs zvfsboot " if(!TclZipfsMount(NULL, archive, \"%vfsroot%\", NULL)) \x7B " - ::practcl::cputs zvfsboot { - Tcl_Obj *vfsinitscript; - vfsinitscript=Tcl_NewStringObj("%vfs_main%",-1); - Tcl_IncrRefCount(vfsinitscript); - if(Tcl_FSAccess(vfsinitscript,F_OK)==0) { - /* Startup script should be set before calling Tcl_AppInit */ - Tcl_SetStartupScript(vfsinitscript,NULL); - } - } - ::practcl::cputs zvfsboot " TclSetPreInitScript([::practcl::tcl_to_c $preinitscript])\;" - ::practcl::cputs zvfsboot " \x7D else \x7B" - ::practcl::cputs zvfsboot " TclSetPreInitScript([::practcl::tcl_to_c { -foreach path { - ../tcl -} { - set p [file join $path library init.tcl] - if {[file exists [file join $path library init.tcl]]} { - set ::tcl_library [file normalize [file join $path library]] - break - } -} -foreach path { - ../tk -} { - if {[file exists [file join $path library tk.tcl]]} { - set ::tk_library [file normalize [file join $path library]] - break - } -} -}])\;" - - ::practcl::cputs zvfsboot " \x7D" - - ::practcl::cputs zvfsboot " return TCL_OK;" - - if {[$PROJECT define get os] eq "windows"} { - set header {int %mainhook%(int *argc, TCHAR ***argv)} - } else { - set header {int %mainhook%(int *argc, char ***argv)} - } - $PROJECT c_function [string map $map $header] [string map $map $zvfsboot] - - practcl::cputs appinit "int %mainfunc%(Tcl_Interp *interp) \x7B" - - # Build AppInit() - set appinit {} - practcl::cputs appinit { - if ((Tcl_Init)(interp) == TCL_ERROR) { - return TCL_ERROR; - } -} - set main_init_script {} - - foreach {statpkg info} $statpkglist { - set initfunc {} - if {[dict exists $info initfunc]} { - set initfunc [dict get $info initfunc] - } - if {$initfunc eq {}} { - set initfunc [string totitle ${statpkg}]_Init - } - # We employ a NULL to prevent the package system from thinking the - # package is actually loaded into the interpreter - $PROJECT code header "extern Tcl_PackageInitProc $initfunc\;\n" - set script [list package ifneeded $statpkg [dict get $info version] [list ::load {} $statpkg]] - append main_init_script \n [list set ::kitpkg(${statpkg}) $script] +### +# Practcl +# An object oriented templating system for stamping out Tcl API calls to C +### +puts [list LOADED practcl.tcl from [info script]] +package require TclOO +proc ::debug args { + #puts $args + ::practcl::cputs ::DEBUG_INFO $args +} + +### +# Drop in a static copy of Tcl +### +proc ::doexec args { + puts [list {*}$args] + exec {*}$args >&@ stdout +} + +proc ::dotclexec args { + puts [list [info nameofexecutable] {*}$args] + exec [info nameofexecutable] {*}$args >&@ stdout +} + +proc ::domake {path args} { + set PWD [pwd] + cd $path + puts [list *** $path ***] + puts [list make {*}$args] + exec make {*}$args >&@ stdout + cd $PWD +} + +proc ::domake.tcl {path args} { + set PWD [pwd] + cd $path + puts [list *** $path ***] + puts [list make.tcl {*}$args] + exec [info nameofexecutable] make.tcl {*}$args >&@ stdout + cd $PWD +} + +proc ::fossil {path args} { + set PWD [pwd] + cd $path + puts [list {*}$args] + exec fossil {*}$args >&@ stdout + cd $PWD +} + + +proc ::fossil_status {dir} { + if {[info exists ::fosdat($dir)]} { + return $::fosdat($dir) + } + set result { +tags experimental +version {} + } + set pwd [pwd] + cd $dir + set info [exec fossil status] + cd $pwd + foreach line [split $info \n] { + if {[lindex $line 0] eq "checkout:"} { + set hash [lindex $line end-3] + set maxdate [lrange $line end-2 end-1] + dict set result hash $hash + dict set result maxdate $maxdate + regsub -all {[^0-9]} $maxdate {} isodate + dict set result isodate $isodate + } + if {[lindex $line 0] eq "tags:"} { + set tags [lrange $line 1 end] + dict set result tags $tags + break + } + } + set ::fosdat($dir) $result + return $result +} +### +# Seek out Tcllib if it's available +### +set tcllib_path {} +foreach path {.. ../.. ../../..} { + foreach path [glob -nocomplain [file join [file normalize $path] tcllib* modules]] { + set tclib_path $path + lappend ::auto_path $path + break + } + if {$tcllib_path ne {}} break +} + + +### +# Build utility functions +### +namespace eval ::practcl {} + +proc ::practcl::os {} { + if {[info exists ::project(TEACUP_OS)] && $::project(TEACUP_OS) ni {"@TEACUP_OS@" {}}} { + return $::project(TEACUP_OS) + } + set info [::practcl::config.tcl $::project(builddir)] + if {[dict exists $info TEACUP_OS]} { + return [dict get $info TEACUP_OS] + } + return unknown +} + +### +# Detect local platform +### +proc ::practcl::config.tcl {path} { + dict set result buildpath $path + set result {} + if {[file exists [file join $path config.tcl]]} { + set fin [open [file join $path config.tcl] r] + set bufline {} + set rawcount 0 + set linecount 0 + while {[gets $fin thisline]>=0} { + incr rawcount + append bufline \n $thisline + if {![info complete $bufline]} continue + set line [string trimleft $bufline] + set bufline {} + if {[string index [string trimleft $line] 0] eq "#"} continue + incr linecount + set key [lindex $line 0] + set value [lindex $line 1] + dict set result $key $value + } + dict set result sandbox [file dirname [dict get $result srcdir]] + dict set result download [file join [dict get $result sandbox] download] + dict set result teapot [file join [dict get $result sandbox] teapot] + set result [::practcl::de_shell $result] + } + # If data is available from autoconf, defer to that + if {[dict exists $result TEACUP_OS] && [dict get $result TEACUP_OS] ni {"@TEACUP_OS@" {}}} { + return $result + } + # If autoconf hasn't run yet, assume we are not cross compiling + # and defer to local checks + dict set result TEACUP_PROFILE unknown + dict set result TEACUP_OS unknown + dict set result EXEEXT {} + if {$::tcl_platform(platform) eq "windows"} { + set system "windows" + set arch ix86 + dict set result TEACUP_PROFILE win32-ix86 + dict set result TEACUP_OS windows + dict set result EXEEXT .exe + } else { + set system [exec uname -s]-[exec uname -r] + set arch unknown + dict set result TEACUP_OS generic + } + dict set result TEA_PLATFORM $system + dict set result TEA_SYSTEM $system + switch -glob $system { + Linux* { + dict set result TEACUP_OS linux + set arch [exec uname -m] + dict set result TEACUP_PROFILE "linux-glibc2.3-$arch" + } + GNU* { + set arch [exec uname -m] + dict set result TEACUP_OS "gnu" + } + NetBSD-Debian { + set arch [exec uname -m] + dict set result TEACUP_OS "netbsd-debian" + } + OpenBSD-* { + set arch [exec arch -s] + dict set result TEACUP_OS "openbsd" + } + Darwin* { + set arch [exec uname -m] + dict set result TEACUP_OS "macosx" + if {$arch eq "x86_64"} { + dict set result TEACUP_PROFILE "macosx10.5-i386-x86_84" + } else { + dict set result TEACUP_PROFILE "macosx-universal" + } + } + OpenBSD* { + set arch [exec arch -s] + dict set result TEACUP_OS "openbsd" + } + } + if {$arch eq "unknown"} { + catch {set arch [exec uname -m]} + } + switch -glob $arch { + i*86 { + set arch "ix86" + } + amd64 { + set arch "x86_64" + } + } + dict set result TEACUP_ARCH $arch + if {[dict get $result TEACUP_PROFILE] eq "unknown"} { + dict set result TEACUP_PROFILE [dict get $result TEACUP_OS]-$arch + } + return $result +} + + +### +# Convert an MSYS path to a windows native path +### +if {$::tcl_platform(platform) eq "windows"} { +proc ::practcl::msys_to_tclpath msyspath { + return [exec sh -c "cd $msyspath ; pwd -W"] +} +} else { +proc ::practcl::msys_to_tclpath msyspath { + return [file normalize $msyspath] +} +} + +### +# Bits stolen from fileutil +### +proc ::practcl::cat fname { + set fname [open $fname r] + set data [read $fname] + close $fname + return $data +} + +proc ::practcl::file_lexnormalize {sp} { + set spx [file split $sp] + + # Resolution of embedded relative modifiers (., and ..). + + if { + ([lsearch -exact $spx . ] < 0) && + ([lsearch -exact $spx ..] < 0) + } { + # Quick path out if there are no relative modifiers + return $sp + } + + set absolute [expr {![string equal [file pathtype $sp] relative]}] + # A volumerelative path counts as absolute for our purposes. + + set sp $spx + set np {} + set noskip 1 + + while {[llength $sp]} { + set ele [lindex $sp 0] + set sp [lrange $sp 1 end] + set islast [expr {[llength $sp] == 0}] + + if {[string equal $ele ".."]} { + if { + ($absolute && ([llength $np] > 1)) || + (!$absolute && ([llength $np] >= 1)) + } { + # .. : Remove the previous element added to the + # new path, if there actually is enough to remove. + set np [lrange $np 0 end-1] + } + } elseif {[string equal $ele "."]} { + # Ignore .'s, they stay at the current location + continue + } else { + # A regular element. + lappend np $ele + } + } + if {[llength $np] > 0} { + return [eval [linsert $np 0 file join]] + # 8.5: return [file join {*}$np] + } + return {} +} + +proc ::practcl::file_relative {base dst} { + # Ensure that the link to directory 'dst' is properly done relative to + # the directory 'base'. + + if {![string equal [file pathtype $base] [file pathtype $dst]]} { + return -code error "Unable to compute relation for paths of different pathtypes: [file pathtype $base] vs. [file pathtype $dst], ($base vs. $dst)" + } + + set base [file_lexnormalize [file join [pwd] $base]] + set dst [file_lexnormalize [file join [pwd] $dst]] + + set save $dst + set base [file split $base] + set dst [file split $dst] + + while {[string equal [lindex $dst 0] [lindex $base 0]]} { + set dst [lrange $dst 1 end] + set base [lrange $base 1 end] + if {![llength $dst]} {break} + } + + set dstlen [llength $dst] + set baselen [llength $base] + + if {($dstlen == 0) && ($baselen == 0)} { + # Cases: + # (a) base == dst + + set dst . + } else { + # Cases: + # (b) base is: base/sub = sub + # dst is: base = {} + + # (c) base is: base = {} + # dst is: base/sub = sub + + while {$baselen > 0} { + set dst [linsert $dst 0 ..] + incr baselen -1 + } + # 8.5: set dst [file join {*}$dst] + set dst [eval [linsert $dst 0 file join]] + } + + return $dst +} + +### +# Unpack the source of a fossil project into a designated location +### +proc ::practcl::fossil_sandbox {pkg args} { + if {[llength $args]==1} { + set info [lindex $args 0] + } else { + set info $args + } + set result $info + if {[dict exists $info srcroot]} { + set srcroot [dict get $info srcroot] + } elseif {[dict exists $info sandbox]} { + set srcroot [file join [dict get $info sandbox] $pkg] + } else { + set srcroot [file join $::CWD .. $pkg] + } + dict set result srcroot $srcroot + puts [list fossil_sandbox $pkg $srcroot] + if {[dict exists $info download]} { + ### + # Source is actually a zip archive + ### + set download [dict get $info download] + if {[file exists [file join $download $pkg.zip]]} { + if {![info exists $srcroot]} { + package require zipfile::decode + ::zipfile::decode::unzipfile [file join $download $pkg.zip] $srcroot + } + return + } + } + variable fossil_dbs + if {![::info exists fossil_dbs]} { + # Get a list of local fossil databases + set fossil_dbs [exec fossil all list] + } + set CWD [pwd] + if {![dict exists $info tag]} { + set tag trunk + } else { + set tag [dict get $info tag] + } + dict set result tag $tag + + try { + if {[file exists [file join $srcroot .fslckout]]} { + if {[dict exists $info update] && [dict get $info update]==1} { + catch { + puts "FOSSIL UPDATE" + cd $srcroot + doexec fossil update $tag + } + } + } elseif {[file exists [file join $srcroot _FOSSIL_]]} { + if {[dict exists $info update] && [dict get $info update]==1} { + catch { + puts "FOSSIL UPDATE" + cd $srcroot + doexec fossil update $tag + } + } + } else { + puts "OPEN AND UNPACK" + set fosdb {} + foreach line [split $fossil_dbs \n] { + set line [string trim $line] + if {[file rootname [file tail $line]] eq $pkg} { + set fosdb $line + break + } + } + if {$fosdb eq {}} { + file mkdir [file join $download fossil] + set fosdb [file join $download fossil $pkg.fos] + set cloned 0 + if {[dict exists $info localmirror]} { + set localmirror [dict get $info localmirror] + catch { + doexec fossil clone $localmirror/$pkg $fosdb + set cloned 1 + } + } + if {!$cloned && [dict exists $info fossil_url]} { + set localmirror [dict get $info fossil_url] + catch { + doexec fossil clone $localmirror/$pkg $fosdb + set cloned 1 + } + } + if {!$cloned} { + doexec fossil clone http://fossil.etoyoc.com/fossil/$pkg $fosdb + } + } + file mkdir $srcroot + cd $srcroot + puts "FOSSIL OPEN [pwd]" + doexec fossil open $fosdb $tag + } + } on error {result opts} { + puts [list ERR [dict get $opts -errorinfo]] + return {*}$opts + } finally { + cd $CWD + } + return $result +} + +### +# topic: e71f3f61c348d56292011eec83e95f0aacc1c618 +# description: Converts a XXX.sh file into a series of Tcl variables +### +proc ::practcl::read_sh_subst {line info} { + regsub -all {\x28} $line \x7B line + regsub -all {\x29} $line \x7D line + + #set line [string map $key [string trim $line]] + foreach {field value} $info { + catch {set $field $value} + } + if [catch {subst $line} result] { + return {} + } + set result [string trim $result] + return [string trim $result '] +} + +### +# topic: 03567140cca33c814664c7439570f669b9ab88e6 +### +proc ::practcl::read_sh_file {filename {localdat {}}} { + set fin [open $filename r] + set result {} + if {$localdat eq {}} { + set top 1 + set local [array get ::env] + dict set local EXE {} + } else { + set top 0 + set local $localdat + } + while {[gets $fin line] >= 0} { + set line [string trim $line] + if {[string index $line 0] eq "#"} continue + if {$line eq {}} continue + catch { + if {[string range $line 0 6] eq "export "} { + set eq [string first "=" $line] + set field [string trim [string range $line 6 [expr {$eq - 1}]]] + set value [read_sh_subst [string range $line [expr {$eq+1}] end] $local] + dict set result $field [read_sh_subst $value $local] + dict set local $field $value + } elseif {[string range $line 0 7] eq "include "} { + set subfile [read_sh_subst [string range $line 7 end] $local] + foreach {field value} [read_sh_file $subfile $local] { + dict set result $field $value + } + } else { + set eq [string first "=" $line] + if {$eq > 0} { + set field [read_sh_subst [string range $line 0 [expr {$eq - 1}]] $local] + set value [string trim [string range $line [expr {$eq+1}] end] '] + #set value [read_sh_subst [string range $line [expr {$eq+1}] end] $local] + dict set local $field $value + dict set result $field $value + } + } + } err opts + if {[dict get $opts -code] != 0} { + #puts $opts + puts "Error reading line:\n$line\nerr: $err\n***" + return $err {*}$opts + } + } + return $result +} + +### +# A simpler form of read_sh_file tailored +# to pulling data from (tcl|tk)Config.sh +### +proc ::practcl::read_Config.sh filename { + set fin [open $filename r] + set result {} + set linecount 0 + while {[gets $fin line] >= 0} { + set line [string trim $line] + if {[string index $line 0] eq "#"} continue + if {$line eq {}} continue + catch { + set eq [string first "=" $line] + if {$eq > 0} { + set field [string range $line 0 [expr {$eq - 1}]] + set value [string trim [string range $line [expr {$eq+1}] end] '] + #set value [read_sh_subst [string range $line [expr {$eq+1}] end] $local] + dict set result $field $value + incr $linecount + } + } err opts + if {[dict get $opts -code] != 0} { + #puts $opts + puts "Error reading line:\n$line\nerr: $err\n***" + return $err {*}$opts + } + } + return $result +} + +### +# A simpler form of read_sh_file tailored +# to pulling data from a Makefile +### +proc ::practcl::read_Makefile filename { + set fin [open $filename r] + set result {} + while {[gets $fin line] >= 0} { + set line [string trim $line] + if {[string index $line 0] eq "#"} continue + if {$line eq {}} continue + catch { + set eq [string first "=" $line] + if {$eq > 0} { + set field [string trim [string range $line 0 [expr {$eq - 1}]]] + set value [string trim [string trim [string range $line [expr {$eq+1}] end] ']] + switch $field { + PKG_LIB_FILE { + dict set result libfile $value + } + srcdir { + if {$value eq "."} { + dict set result srcdir [file dirname $filename] + } else { + dict set result srcdir $value + } + } + PACKAGE_NAME { + dict set result name $value + } + PACKAGE_VERSION { + dict set result version $value + } + LIBS { + dict set result PRACTCL_LIBS $value + } + PKG_LIB_FILE { + dict set result libfile $value + } + } + } + } err opts + if {[dict get $opts -code] != 0} { + #puts $opts + puts "Error reading line:\n$line\nerr: $err\n***" + return $err {*}$opts + } + # the Compile field is about where most TEA files start getting silly + if {$field eq "compile"} { + break + } + } + return $result +} + +## Append arguments to a buffer +# The command works like puts in that each call will also insert +# a line feed. Unlike puts, blank links in the interstitial are +# suppressed +proc ::practcl::cputs {varname args} { + upvar 1 $varname buffer + if {[llength $args]==1 && [string length [string trim [lindex $args 0]]] == 0} { + + } + if {[info exist buffer]} { + if {[string index $buffer end] ne "\n"} { + append buffer \n + } + } else { + set buffer \n + } + # Trim leading \n's + append buffer [string trimleft [lindex $args 0] \n] {*}[lrange $args 1 end] +} + + +proc ::practcl::tcl_to_c {body} { + set result {} + foreach rawline [split $body \n] { + set line [string map [list \" \\\" \\ \\\\] $rawline] + cputs result "\n \"$line\\n\" \\" + } + return [string trimright $result \\] +} + + +proc ::practcl::_tagblock {text {style tcl} {note {}}} { + if {[string length [string trim $text]]==0} { + return {} + } + set output {} + switch $style { + tcl { + ::practcl::cputs output "# BEGIN $note" + } + c { + ::practcl::cputs output "/* BEGIN $note */" + } + default { + ::practcl::cputs output "# BEGIN $note" + } + } + ::practcl::cputs output $text + switch $style { + tcl { + ::practcl::cputs output "# END $note" + } + c { + ::practcl::cputs output "/* END $note */" + } + default { + ::practcl::cputs output "# END $note" + } + } + return $output +} + +proc ::practcl::_isdirectory name { + return [file isdirectory $name] +} + +### +# Return true if the pkgindex file contains +# any statement other than "package ifneeded" +# and/or if any package ifneeded loads a DLL +### +proc ::practcl::_pkgindex_directory {path} { + set buffer {} + set pkgidxfile [file join $path pkgIndex.tcl] + if {![file exists $pkgidxfile]} { + # No pkgIndex file, read the source + foreach file [glob -nocomplain $path/*.tm] { + set file [file normalize $file] + set fname [file rootname [file tail $file]] + ### + # We used to be able to ... Assume the package is correct in the filename + # No hunt for a "package provides" + ### + set package [lindex [split $fname -] 0] + set version [lindex [split $fname -] 1] + ### + # Read the file, and override assumptions as needed + ### + set fin [open $file r] + set dat [read $fin] + close $fin + # Look for a teapot style Package statement + foreach line [split $dat \n] { + set line [string trim $line] + if { [string range $line 0 9] != "# Package " } continue + set package [lindex $line 2] + set version [lindex $line 3] + break + } + # Look for a package provide statement + foreach line [split $dat \n] { + set line [string trim $line] + if { [string range $line 0 14] != "package provide" } continue + set package [lindex $line 2] + set version [lindex $line 3] + break + } + append buffer "package ifneeded $package $version \[list source \[file join \$dir [file tail $file]\]\]" \n + } + foreach file [glob -nocomplain $path/*.tcl] { + if { [file tail $file] == "version_info.tcl" } continue + set fin [open $file r] + set dat [read $fin] + close $fin + if {![regexp "package provide" $dat]} continue + set fname [file rootname [file tail $file]] + # Look for a package provide statement + foreach line [split $dat \n] { + set line [string trim $line] + if { [string range $line 0 14] != "package provide" } continue + set package [lindex $line 2] + set version [lindex $line 3] + if {[string index $package 0] in "\$ \["} continue + if {[string index $version 0] in "\$ \["} continue + append buffer "package ifneeded $package $version \[list source \[file join \$dir [file tail $file]\]\]" \n + break + } + } + return $buffer + } + set fin [open $pkgidxfile r] + set dat [read $fin] + close $fin + set thisline {} + foreach line [split $dat \n] { + append thisline $line \n + if {![info complete $thisline]} continue + set line [string trim $line] + if {[string length $line]==0} { + set thisline {} ; continue + } + if {[string index $line 0] eq "#"} { + set thisline {} ; continue + } + try { + # Ignore contditionals + if {[regexp "if.*catch.*package.*Tcl.*return" $thisline]} continue + if {[regexp "if.*package.*vsatisfies.*package.*provide.*return" $thisline]} continue + if {![regexp "package.*ifneeded" $thisline]} { + # This package index contains arbitrary code + # source instead of trying to add it to the master + # package index + return {source [file join $dir pkgIndex.tcl]} + } + append buffer $thisline \n + } on error {err opts} { + puts *** + puts "GOOF: $pkgidxfile" + puts $line + puts $err + puts [dict get $opts -errorinfo] + puts *** + } finally { + set thisline {} + } + } + return $buffer +} + + +proc ::practcl::_pkgindex_path_subdir {path} { + set result {} + foreach subpath [glob -nocomplain [file join $path *]] { + if {[file isdirectory $subpath]} { + lappend result $subpath {*}[_pkgindex_path_subdir $subpath] + } + } + return $result +} +### +# Index all paths given as though they will end up in the same +# virtual file system +### +proc ::practcl::pkgindex_path args { + set stack {} + set buffer { +lappend ::PATHSTACK $dir + } + foreach base $args { + set base [file normalize $base] + set paths [::practcl::_pkgindex_path_subdir $base] + set i [string length $base] + # Build a list of all of the paths + foreach path $paths { + if {$path eq $base} continue + set path_indexed($path) 0 + } + set path_indexed($base) 1 + set path_indexed([file join $base boot tcl]) 1 + #set path_index([file join $base boot tk]) 1 + + foreach path $paths { + if {$path_indexed($path)} continue + set thisdir [file_relative $base $path] + #set thisdir [string range $path $i+1 end] + set idxbuf [::practcl::_pkgindex_directory $path] + if {[string length $idxbuf]} { + incr path_indexed($path) + append buffer "set dir \[set PKGDIR \[file join \[lindex \$::PATHSTACK end\] $thisdir\]\]" \n + append buffer [string map {$dir $PKGDIR} [string trimright $idxbuf]] \n + } + } + } + append buffer { +set dir [lindex $::PATHSTACK end] +set ::PATHSTACK [lrange $::PATHSTACK 0 end-1] +} + return $buffer +} + +### +# topic: 64319f4600fb63c82b2258d908f9d066 +# description: Script to build the VFS file system +### +proc ::practcl::installDir {d1 d2} { + + puts [format {%*sCreating %s} [expr {4 * [info level]}] {} [file tail $d2]] + file delete -force -- $d2 + file mkdir $d2 + + foreach ftail [glob -directory $d1 -nocomplain -tails *] { + set f [file join $d1 $ftail] + if {[file isdirectory $f] && [string compare CVS $ftail]} { + installDir $f [file join $d2 $ftail] + } elseif {[file isfile $f]} { + file copy -force $f [file join $d2 $ftail] + if {$::tcl_platform(platform) eq {unix}} { + file attributes [file join $d2 $ftail] -permissions 0644 + } else { + file attributes [file join $d2 $ftail] -readonly 1 + } + } + } + + if {$::tcl_platform(platform) eq {unix}} { + file attributes $d2 -permissions 0755 + } else { + file attributes $d2 -readonly 1 + } +} + +proc ::practcl::copyDir {d1 d2} { + #puts [list $d1 -> $d2] + #file delete -force -- $d2 + file mkdir $d2 + + foreach ftail [glob -directory $d1 -nocomplain -tails *] { + set f [file join $d1 $ftail] + if {[file isdirectory $f] && [string compare CVS $ftail]} { + copyDir $f [file join $d2 $ftail] + } elseif {[file isfile $f]} { + file copy -force $f [file join $d2 $ftail] + } + } +} + +::oo::class create ::practcl::metaclass { + superclass ::oo::object + + method script script { + eval $script + } + + method source filename { + source $filename + } + + method initialize {} {} + + method define {submethod args} { + my variable define + switch $submethod { + dump { + return [array get define] + } + add { + set field [lindex $args 0] + if {![info exists define($field)]} { + set define($field) {} + } + foreach arg [lrange $args 1 end] { + if {$arg ni $define($field)} { + lappend define($field) $arg + } + } + return $define($field) + } + remove { + set field [lindex $args 0] + if {![info exists define($field)]} { + return + } + set rlist [lrange $args 1 end] + set olist $define($field) + set nlist {} + foreach arg $olist { + if {$arg in $rlist} continue + lappend nlist $arg + } + set define($field) $nlist + return $nlist + } + exists { + set field [lindex $args 0] + return [info exists define($field)] + } + getnull - + get - + cget { + set field [lindex $args 0] + if {[info exists define($field)]} { + return $define($field) + } + return [lindex $args 1] + } + set { + if {[llength $args]==1} { + set arglist [lindex $args 0] + } else { + set arglist $args + } + array set define $arglist + if {[dict exists $arglist class]} { + my select + } + } + default { + array $submethod define {*}$args + } + } + } + + method graft args { + my variable organs + if {[llength $args] == 1} { + error "Need two arguments" + } + set object {} + foreach {stub object} $args { + dict set organs $stub $object + oo::objdefine [self] forward <${stub}> $object + oo::objdefine [self] export <${stub}> + } + return $object + } + + method organ {{stub all}} { + my variable organs + if {![info exists organs]} { + return {} + } + if { $stub eq "all" } { + return $organs + } + if {[dict exists $organs $stub]} { + return [dict get $organs $stub] + } + } + + method link {command args} { + my variable links + switch $command { + object { + foreach obj $args { + foreach linktype [$obj linktype] { + my link add $linktype $obj + } + } + } + add { + ### + # Add a link to an object that was externally created + ### + if {[llength $args] ne 2} { error "Usage: link add LINKTYPE OBJECT"} + lassign $args linktype object + if {[info exists links($linktype)] && $object in $links($linktype)} { + return + } + lappend links($linktype) $object + } + remove { + set object [lindex $args 0] + if {[llength $args]==1} { + set ltype * + } else { + set ltype [lindex $args 1] + } + foreach {linktype elements} [array get links $ltype] { + if {$object in $elements} { + set nlist {} + foreach e $elements { + if { $object ne $e } { lappend nlist $e } + } + set links($linktype) $nlist + } + } + } + list { + if {[llength $args]==0} { + return [array get links] + } + if {[llength $args] != 1} { error "Usage: link list LINKTYPE"} + set linktype [lindex $args 0] + if {![info exists links($linktype)]} { + return {} + } + return $links($linktype) + } + dump { + return [array get links] + } + } + } + + method select {} { + my variable define + set class {} + if {[info exists define(class)]} { + if {[info command $define(class)] ne {}} { + set class $define(class) + } elseif {[info command ::practcl::$define(class)] ne {}} { + set class ::practcl::$define(class) + } else { + switch $define(class) { + default { + set class ::practcl::object + } + } + } + } + if {$class ne {}} { + ::oo::objdefine [self] class $class + } + if {[::info exists define(oodefine)]} { + ::oo::objdefine [self] $define(oodefine) + unset define(oodefine) + } + } +} + +proc ::practcl::trigger {args} { + foreach name $args { + if {[dict exists $::make_objects $name]} { + [dict get $::make_objects $name] triggers + } + } +} + +proc ::practcl::depends {args} { + foreach name $args { + if {[dict exists $::make_objects $name]} { + [dict get $::make_objects $name] check + } + } +} + +proc ::practcl::target {name info} { + set obj [::practcl::target_obj new $name $info] + dict set ::make_objects $name $obj + if {[dict exists $info aliases]} { + foreach item [dict get $info aliases] { + if {![dict exists $::make_objects $item]} { + dict set ::make_objects $item $obj + } + } + } + set ::make($name) 0 + set ::trigger($name) 0 + set filename [$obj define get filename] + if {$filename ne {}} { + set ::target($name) $filename + } +} + +### Batch Tasks + +namespace eval ::practcl::build {} + +## method DEFS +# This method populates 4 variables: +# name - The name of the package +# version - The version of the package +# defs - C flags passed to the compiler +# includedir - A list of paths to feed to the compiler for finding headers +# +proc ::practcl::build::DEFS {PROJECT DEFS namevar versionvar defsvar} { + upvar 1 $namevar name $versionvar version NAME NAME $defsvar defs + set name [string tolower [${PROJECT} define get name [${PROJECT} define get pkg_name]]] + set NAME [string toupper $name] + set version [${PROJECT} define get version [${PROJECT} define get pkg_vers]] + if {$version eq {}} { + set version 0.1a + } + set defs {} + append defs " -DPACKAGE_NAME=\"${name}\" -DPACKAGE_VERSION=\"${version}\"" + append defs " -DPACKAGE_TARNAME=\"${name}\" -DPACKAGE_STRING=\"${name}\x5c\x20${version}\"" + set NAME [string toupper $name] + set idx 0 + set count 0 + while {$idx>=0} { + set ndx [string first " -D" $DEFS $idx+1] + set item [string range $DEFS $idx $ndx] + set item [string trim $item] + set item [string trimleft $item -D] + if {[string range $item 0 7] eq "PACKAGE_"} { + set idx $ndx + continue + } + set eqidx [string first = $item ] + if {$eqidx < 0} { + append defs { } $item + set idx $ndx + continue + } + + set field [string range $item 0 [expr {$eqidx-1}]] + set value [string range $item [expr {$eqidx+1}] end] + set emap {} + lappend emap \x5c \x5c\x5c \x20 \x5c\x20 \x22 \x5c\x22 \x28 \x5c\x28 \x29 \x5c\x29 + if {[string is integer -strict $value]} { + append defs " -D${field}=$value" + } else { + append defs " -D${field}=[string map $emap $value]" + } + set idx $ndx + } + return $defs +} + +proc ::practcl::build::tclkit_main {PROJECT PKG_OBJS} { + ### + # Build static package list + ### + set statpkglist {} + dict set statpkglist Tk {autoload 0} + puts [list TCLKIT MAIN $PROJECT] + + foreach {ofile info} [${PROJECT} compile-products] { + puts [list * PROD $ofile $info] + if {![dict exists $info object]} continue + set cobj [dict get $info object] + foreach {pkg info} [$cobj static-packages] { + dict set statpkglist $pkg $info + } + } + foreach cobj [list {*}${PKG_OBJS} $PROJECT] { + puts [list * PROG $cobj] + foreach {pkg info} [$cobj static-packages] { + puts [list * PKG $pkg $info] + dict set statpkglist $pkg $info + } + } + + set result {} + $PROJECT include {} + $PROJECT include {"tclInt.h"} + $PROJECT include {"tclFileSystem.h"} + $PROJECT include {} + $PROJECT include {} + $PROJECT include {} + $PROJECT include {} + $PROJECT include {} + + $PROJECT code header { +#ifndef MODULE_SCOPE +# define MODULE_SCOPE extern +#endif + +/* +** Provide a dummy Tcl_InitStubs if we are using this as a static +** library. +*/ +#ifndef USE_TCL_STUBS +# undef Tcl_InitStubs +# define Tcl_InitStubs(a,b,c) TCL_VERSION +#endif +#define STATIC_BUILD 1 +#undef USE_TCL_STUBS + +/* Make sure the stubbed variants of those are never used. */ +#undef Tcl_ObjSetVar2 +#undef Tcl_NewStringObj +#undef Tk_Init +#undef Tk_MainEx +#undef Tk_SafeInit +} + + # Build an area of the file for #define directives and + # function declarations + set define {} + set mainhook [$PROJECT define get TCL_LOCAL_MAIN_HOOK Tclkit_MainHook] + set mainfunc [$PROJECT define get TCL_LOCAL_APPINIT Tclkit_AppInit] + set mainscript [$PROJECT define get main.tcl main.tcl] + set vfsroot [$PROJECT define get vfsroot zipfs:/app] + set vfs_main "${vfsroot}/${mainscript}" + set vfs_tcl_library "${vfsroot}/boot/tcl" + set vfs_tk_library "${vfsroot}/boot/tk" + + set map {} + foreach var { + vfsroot mainhook mainfunc vfs_main vfs_tcl_library vfs_tk_library + } { + dict set map %${var}% [set $var] + } + set preinitscript { +set ::odie(boot_vfs) {%vfsroot%} +set ::SRCDIR {%vfsroot%} +if {[file exists {%vfs_tcl_library%}]} { + set ::tcl_library {%vfs_tcl_library%} + set ::auto_path {} +} +if {[file exists {%vfs_tk_library%}]} { + set ::tk_library {%vfs_tk_library%} +} +} ; # Preinitscript + + set zvfsboot { +/* + * %mainhook% -- + * Performs the argument munging for the shell + */ + } + ::practcl::cputs zvfsboot { + CONST char *archive; + Tcl_FindExecutable(*argv[0]); + archive=Tcl_GetNameOfExecutable(); + + Tclzipfs_Init(NULL); + } + # We have to initialize the virtual filesystem before calling + # Tcl_Init(). Otherwise, Tcl_Init() will not be able to find + # its startup script files. + $PROJECT include {"tclZipfs.h"} + + ::practcl::cputs zvfsboot " if(!TclZipfsMount(NULL, archive, \"%vfsroot%\", NULL)) \x7B " + ::practcl::cputs zvfsboot { + Tcl_Obj *vfsinitscript; + vfsinitscript=Tcl_NewStringObj("%vfs_main%",-1); + Tcl_IncrRefCount(vfsinitscript); + if(Tcl_FSAccess(vfsinitscript,F_OK)==0) { + /* Startup script should be set before calling Tcl_AppInit */ + Tcl_SetStartupScript(vfsinitscript,NULL); + } + } + ::practcl::cputs zvfsboot " TclSetPreInitScript([::practcl::tcl_to_c $preinitscript])\;" + ::practcl::cputs zvfsboot " \x7D else \x7B" + ::practcl::cputs zvfsboot " TclSetPreInitScript([::practcl::tcl_to_c { +foreach path { + ../tcl +} { + set p [file join $path library init.tcl] + if {[file exists [file join $path library init.tcl]]} { + set ::tcl_library [file normalize [file join $path library]] + break + } +} +foreach path { + ../tk +} { + if {[file exists [file join $path library tk.tcl]]} { + set ::tk_library [file normalize [file join $path library]] + break + } +} +}])\;" + + ::practcl::cputs zvfsboot " \x7D" + + ::practcl::cputs zvfsboot " return TCL_OK;" + + if {[$PROJECT define get os] eq "windows"} { + set header {int %mainhook%(int *argc, TCHAR ***argv)} + } else { + set header {int %mainhook%(int *argc, char ***argv)} + } + $PROJECT c_function [string map $map $header] [string map $map $zvfsboot] + + practcl::cputs appinit "int %mainfunc%(Tcl_Interp *interp) \x7B" + + # Build AppInit() + set appinit {} + practcl::cputs appinit { + if ((Tcl_Init)(interp) == TCL_ERROR) { + return TCL_ERROR; + } +} + set main_init_script {} + + foreach {statpkg info} $statpkglist { + set initfunc {} + if {[dict exists $info initfunc]} { + set initfunc [dict get $info initfunc] + } + if {$initfunc eq {}} { + set initfunc [string totitle ${statpkg}]_Init + } + # We employ a NULL to prevent the package system from thinking the + # package is actually loaded into the interpreter + $PROJECT code header "extern Tcl_PackageInitProc $initfunc\;\n" + set script [list package ifneeded $statpkg [dict get $info version] [list ::load {} $statpkg]] + append main_init_script \n [list set ::kitpkg(${statpkg}) $script] if {[dict get $info autoload]} { - ::practcl::cputs appinit " if(${initfunc}(interp)) return TCL_ERROR\;" - ::practcl::cputs appinit " Tcl_StaticPackage(interp,\"$statpkg\",$initfunc,NULL)\;" - } else { - ::practcl::cputs appinit "\n Tcl_StaticPackage(NULL,\"$statpkg\",$initfunc,NULL)\;" - append main_init_script \n $script - } - } - append main_init_script \n { -if {[file exists [file join $::SRCDIR packages.tcl]]} { - #In a wrapped exe, we don't go out to the environment - set dir $::SRCDIR - source [file join $::SRCDIR packages.tcl] -} -# Specify a user-specific startup file to invoke if the application -# is run interactively. Typically the startup file is "~/.apprc" -# where "app" is the name of the application. If this line is deleted -# then no user-specific startup file will be run under any conditions. - } - append main_init_script \n [list set tcl_rcFileName [$PROJECT define get tcl_rcFileName ~/.tclshrc]] - practcl::cputs appinit " Tcl_Eval(interp,[::practcl::tcl_to_c $main_init_script]);" - practcl::cputs appinit { return TCL_OK;} - $PROJECT c_function [string map $map "int %mainfunc%(Tcl_Interp *interp)"] [string map $map $appinit] -} - -proc ::practcl::build::compile-sources {PROJECT COMPILE {CPPCOMPILE {}}} { - set EXTERN_OBJS {} - set OBJECTS {} - set result {} - set builddir [$PROJECT define get builddir] - file mkdir [file join $builddir objs] - set debug [$PROJECT define get debug 0] - if {$CPPCOMPILE eq {}} { - set CPPCOMPILE $COMPILE - } - set task [${PROJECT} compile-products] - ### - # Compile the C sources - ### - foreach {ofile info} $task { - dict set task $ofile done 0 - if {[dict exists $info external] && [dict get $info external]==1} { - dict set task $ofile external 1 - } else { - dict set task $ofile external 0 - } - if {[dict exists $info library]} { - dict set task $ofile done 1 - continue - } - # Products with no cfile aren't compiled - if {![dict exists $info cfile] || [set cfile [dict get $info cfile]] eq {}} { - dict set task $ofile done 1 - continue - } - set cfile [dict get $info cfile] - set ofilename [file join $builddir objs [file tail $ofile]] - if {$debug} { - set ofilename [file join $builddir objs [file rootname [file tail $ofile]].debug.o] - } - dict set task $ofile filename $ofilename - if {[file exists $ofilename] && [file mtime $ofilename]>[file mtime $cfile]} { - lappend result $ofilename - dict set task $ofile done 1 - continue - } - if {![dict exist $info command]} { - if {[file extension $cfile] in {.c++ .cpp}} { - set cmd $CPPCOMPILE - } else { - set cmd $COMPILE - } - if {[dict exists $info extra]} { - append cmd " [dict get $info extra]" - } - append cmd " -c $cfile" - append cmd " -o $ofilename" - dict set task $ofile command $cmd - } - } - set completed 0 - while {$completed==0} { - set completed 1 - foreach {ofile info} $task { - set waiting {} - if {[dict exists $info done] && [dict get $info done]} continue - if {[dict exists $info depend]} { - foreach file [dict get $info depend] { - if {[dict exists $task $file command] && [dict exists $task $file done] && [dict get $task $file done] != 1} { - set waiting $file - break - } - } - } - if {$waiting ne {}} { - set completed 0 - puts "$ofile waiting for $waiting" - continue - } - if {[dict exists $info command]} { - set cmd [dict get $info command] - puts "$cmd" - exec {*}$cmd >&@ stdout - } - lappend result [dict get $info filename] - dict set task $ofile done 1 - } - } - return $result -} - -proc ::practcl::de_shell {data} { - set values {} - foreach flag {DEFS TCL_DEFS TK_DEFS} { - if {[dict exists $data $flag]} { - set value {} - foreach item [dict get $data $flag] { - append value " " [string map {{ } {\ }} $item] - } - dict set values $flag $value - } - } - set map {} - lappend map {${PKG_OBJECTS}} %LIBRARY_OBJECTS% - lappend map {$(PKG_OBJECTS)} %LIBRARY_OBJECTS% - lappend map {${PKG_STUB_OBJECTS}} %LIBRARY_STUB_OBJECTS% - lappend map {$(PKG_STUB_OBJECTS)} %LIBRARY_STUB_OBJECTS% - - lappend map %LIBRARY_NAME% [dict get $data name] - lappend map %LIBRARY_VERSION% [dict get $data version] - lappend map %LIBRARY_VERSION_NODOTS% [string map {. {}} [dict get $data version]] - if {[dict exists $data libprefix]} { - lappend map %LIBRARY_PREFIX% [dict get $data libprefix] - } else { - lappend map %LIBRARY_PREFIX% [dict get $data prefix] - } - foreach flag [dict keys $data] { - if {$flag in {TCL_DEFS TK_DEFS DEFS}} continue - - dict set map "%${flag}%" [dict get $data $flag] - dict set map "\$\{${flag}\}" [dict get $data $flag] - dict set map "\$\(${flag}\)" [dict get $data $flag] - dict set values $flag [dict get $data $flag] - #dict set map "\$\{${flag}\}" $proj($flag) - } - set changed 1 - while {$changed} { - set changed 0 - foreach {field value} $values { - if {$field in {TCL_DEFS TK_DEFS DEFS}} continue - dict with values {} - set newval [string map $map $value] - if {$newval eq $value} continue - set changed 1 - dict set values $field $newval - } - } - return $values -} - -proc ::practcl::build::Makefile {path PROJECT} { - array set proj [$PROJECT define dump] - set path $proj(builddir) - cd $path - set includedir . - #lappend includedir [::practcl::file_relative $path $proj(TCL_INCLUDES)] - lappend includedir [::practcl::file_relative $path [file normalize [file join $proj(TCL_SRC_DIR) generic]]] - lappend includedir [::practcl::file_relative $path [file normalize [file join $proj(srcdir) generic]]] - foreach include [$PROJECT generate-include-directory] { - set cpath [::practcl::file_relative $path [file normalize $include]] - if {$cpath ni $includedir} { - lappend includedir $cpath - } - } - set INCLUDES "-I[join $includedir " -I"]" - set NAME [string toupper $proj(name)] - set result {} - set products {} - set libraries {} - set thisline {} - ::practcl::cputs result "${NAME}_DEFS = $proj(DEFS)\n" - ::practcl::cputs result "${NAME}_INCLUDES = -I\"[join $includedir "\" -I\""]\"\n" - ::practcl::cputs result "${NAME}_COMPILE = \$(CC) \$(CFLAGS) \$(PKG_CFLAGS) \$(${NAME}_DEFS) \$(${NAME}_INCLUDES) \$(INCLUDES) \$(AM_CPPFLAGS) \$(CPPFLAGS) \$(AM_CFLAGS)" - ::practcl::cputs result "${NAME}_CPPCOMPILE = \$(CXX) \$(CFLAGS) \$(PKG_CFLAGS) \$(${NAME}_DEFS) \$(${NAME}_INCLUDES) \$(INCLUDES) \$(AM_CPPFLAGS) \$(CPPFLAGS) \$(AM_CFLAGS)" - - foreach {ofile info} [$PROJECT compile-products] { - dict set products $ofile $info - if {[dict exists $info library]} { -lappend libraries $ofile -continue - } - if {[dict exists $info depend]} { - ::practcl::cputs result "\n${ofile}: [dict get $info depend]" - } else { - ::practcl::cputs result "\n${ofile}:" - } - set cfile [dict get $info cfile] - if {[file extension $cfile] in {.c++ .cpp}} { - set cmd "\t\$\(${NAME}_CPPCOMPILE\)" - } else { - set cmd "\t\$\(${NAME}_COMPILE\)" - } - if {[dict exists $info extra]} { - append cmd " [dict get $info extra]" - } - append cmd " -c [dict get $info cfile] -o \$@\n\t" - ::practcl::cputs result $cmd - } - - set map {} - lappend map %LIBRARY_NAME% $proj(name) - lappend map %LIBRARY_VERSION% $proj(version) - lappend map %LIBRARY_VERSION_NODOTS% [string map {. {}} $proj(version)] - lappend map %LIBRARY_PREFIX% [$PROJECT define getnull libprefix] - - if {[string is true [$PROJECT define get SHARED_BUILD]]} { - set outfile [$PROJECT define get libfile] - } else { - set outfile [$PROJECT shared_library] - } - $PROJECT define set shared_library $outfile - ::practcl::cputs result " -${NAME}_SHLIB = $outfile -${NAME}_OBJS = [dict keys $products] -" - - #lappend map %OUTFILE% {\[$]@} - lappend map %OUTFILE% $outfile - lappend map %LIBRARY_OBJECTS% "\$(${NAME}_OBJS)" - ::practcl::cputs result "$outfile: \$(${NAME}_OBJS)" - ::practcl::cputs result "\t[string map $map [$PROJECT define get PRACTCL_SHARED_LIB]]" - if {[$PROJECT define get PRACTCL_VC_MANIFEST_EMBED_DLL] ni {: {}}} { - ::practcl::cputs result "\t[string map $map [$PROJECT define get PRACTCL_VC_MANIFEST_EMBED_DLL]]" - } - ::practcl::cputs result {} - if {[string is true [$PROJECT define get SHARED_BUILD]]} { - #set outfile [$PROJECT static_library] - set outfile $proj(name).a - } else { - set outfile [$PROJECT define get libfile] - } - $PROJECT define set static_library $outfile - dict set map %OUTFILE% $outfile - ::practcl::cputs result "$outfile: \$(${NAME}_OBJS)" - ::practcl::cputs result "\t[string map $map [$PROJECT define get PRACTCL_STATIC_LIB]]" - ::practcl::cputs result {} - return $result -} - -### -# Produce a dynamic library -### -proc ::practcl::build::library {outfile PROJECT} { - array set proj [$PROJECT define dump] - set path $proj(builddir) - cd $path - set includedir . - #lappend includedir [::practcl::file_relative $path $proj(TCL_INCLUDES)] - lappend includedir [::practcl::file_relative $path [file normalize [file join $proj(TCL_SRC_DIR) generic]]] - lappend includedir [::practcl::file_relative $path [file normalize [file join $proj(srcdir) generic]]] - if {[$PROJECT define get tk 0]} { - lappend includedir [::practcl::file_relative $path [file normalize [file join $proj(TK_SRC_DIR) generic]]] - lappend includedir [::practcl::file_relative $path [file normalize [file join $proj(TK_SRC_DIR) ttk]]] - lappend includedir [::practcl::file_relative $path [file normalize [file join $proj(TK_SRC_DIR) xlib]]] - lappend includedir [::practcl::file_relative $path [file normalize $proj(TK_BIN_DIR)]] - } - foreach include [$PROJECT generate-include-directory] { - set cpath [::practcl::file_relative $path [file normalize $include]] - if {$cpath ni $includedir} { - lappend includedir $cpath - } - } - ::practcl::build::DEFS $PROJECT $proj(DEFS) name version defs - set NAME [string toupper $name] - set debug [$PROJECT define get debug 0] - set os [$PROJECT define get os] - - set INCLUDES "-I[join $includedir " -I"]" - if {$debug} { - set COMPILE "$proj(CC) $proj(CFLAGS_DEBUG) -ggdb \ -$proj(CFLAGS_WARNING) $INCLUDES $defs" - - if {[info exists proc(CXX)]} { - set COMPILECPP "$proj(CXX) $defs $INCLUDES $proj(CFLAGS_DEBUG) -ggdb \ - $proj(DEFS) $proj(CFLAGS_WARNING)" - } else { - set COMPILECPP $COMPILE - } - } else { - set COMPILE "$proj(CC) $proj(CFLAGS) $defs $INCLUDES " - - if {[info exists proc(CXX)]} { - set COMPILECPP "$proj(CXX) $defs $INCLUDES $proj(CFLAGS) $proj(DEFS)" - } else { - set COMPILECPP $COMPILE - } - } - - set products [compile-sources $PROJECT $COMPILE $COMPILECPP] - - set map {} - lappend map %LIBRARY_NAME% $proj(name) - lappend map %LIBRARY_VERSION% $proj(version) - lappend map %LIBRARY_VERSION_NODOTS% [string map {. {}} $proj(version)] - lappend map %OUTFILE% $outfile - lappend map %LIBRARY_OBJECTS% $products - lappend map {${CFLAGS}} "$proj(CFLAGS_DEFAULT) $proj(CFLAGS_WARNING)" - - if {[string is true [$PROJECT define get SHARED_BUILD 1]]} { - set cmd [$PROJECT define get PRACTCL_SHARED_LIB] - append cmd " [$PROJECT define get PRACTCL_LIBS]" - set cmd [string map $map $cmd] - puts $cmd - exec {*}$cmd >&@ stdout - if {[$PROJECT define get PRACTCL_VC_MANIFEST_EMBED_DLL] ni {: {}}} { - set cmd [string map $map [$PROJECT define get PRACTCL_VC_MANIFEST_EMBED_DLL]] - puts $cmd - exec {*}$cmd >&@ stdout - } - } else { - set cmd [string map $map [$PROJECT define get PRACTCL_STATIC_LIB]] - puts $cmd - exec {*}$cmd >&@ stdout - } -} - -### -# Produce a static executable -### -proc ::practcl::build::static-tclsh {outfile PROJECT} { - puts " BUILDING STATIC TCLSH " - set TCLOBJ [$PROJECT project TCLCORE] - set TKOBJ [$PROJECT project TKCORE] - set ODIEOBJ [$PROJECT project odie] - - set PKG_OBJS {} - foreach item [$PROJECT link list package] { - if {[string is true [$item define get static]]} { - lappend PKG_OBJS $item - } - } - array set TCL [$TCLOBJ config.sh] - array set TK [$TKOBJ config.sh] - set path [file dirname $outfile] - cd $path - ### - # For a static Tcl shell, we need to build all local sources - # with the same DEFS flags as the tcl core was compiled with. - # The DEFS produced by a TEA extension aren't intended to operate - # with the internals of a staticly linked Tcl - ### - ::practcl::build::DEFS $PROJECT $TCL(defs) name version defs - set debug [$PROJECT define get debug 0] - set NAME [string toupper $name] - set result {} - set libraries {} - set thisline {} - set OBJECTS {} - set EXTERN_OBJS {} - foreach obj $PKG_OBJS { - $obj compile - set config($obj) [$obj config.sh] - } - set os [$PROJECT define get os] - set TCLSRCDIR [$TCLOBJ define get srcroot] - set TKSRCDIR [$TKOBJ define get srcroot] - - set includedir . - foreach include [$TCLOBJ generate-include-directory] { - set cpath [::practcl::file_relative $path [file normalize $include]] - if {$cpath ni $includedir} { - lappend includedir $cpath - } - } - lappend includedir [::practcl::file_relative $path [file normalize ../tcl/compat/zlib]] - foreach include [$PROJECT generate-include-directory] { - set cpath [::practcl::file_relative $path [file normalize $include]] - if {$cpath ni $includedir} { - lappend includedir $cpath - } - } - - set INCLUDES "-I[join $includedir " -I"]" - if {$debug} { - set COMPILE "$TCL(cc) $TCL(shlib_cflags) $TCL(cflags_debug) -ggdb \ -$TCL(cflags_warning) $TCL(extra_cflags) $INCLUDES" - } else { - set COMPILE "$TCL(cc) $TCL(shlib_cflags) $TCL(cflags_optimize) \ -$TCL(cflags_warning) $TCL(extra_cflags) $INCLUDES" - } - append COMPILE " " $defs - lappend OBJECTS {*}[compile-sources $PROJECT $COMPILE $COMPILE] - - if {[${PROJECT} define get platform] eq "windows"} { - set RSOBJ [file join $path build tclkit.res.o] - set RCSRC [${PROJECT} define get kit_resource_file] - if {$RCSRC eq {} || ![file exists $RCSRC]} { - set RCSRC [file join $TKSRCDIR win rc wish.rc] - } - set cmd [list windres -o $RSOBJ -DSTATIC_BUILD] - set TCLSRC [file normalize $TCLSRCDIR] - set TKSRC [file normalize $TKSRCDIR] - - lappend cmd --include [::practcl::file_relative $path [file join $TCLSRC generic]] \ - --include [::practcl::file_relative $path [file join $TKSRC generic]] \ - --include [::practcl::file_relative $path [file join $TKSRC win]] \ - --include [::practcl::file_relative $path [file join $TKSRC win rc]] - foreach item [${PROJECT} define get resource_include] { - lappend cmd --include [::practcl::file_relative $path [file normalize $item]] - } - lappend cmd $RCSRC - doexec {*}$cmd - - lappend OBJECTS $RSOBJ - set LDFLAGS_CONSOLE {-mconsole -pipe -static-libgcc} - set LDFLAGS_WINDOW {-mwindows -pipe -static-libgcc} - } else { - set LDFLAGS_CONSOLE {} - set LDFLAGS_WINDOW {} - } - puts "***" - if {$debug} { - set cmd "$TCL(cc) $TCL(shlib_cflags) $TCL(cflags_debug) \ -$TCL(cflags_warning) $TCL(extra_cflags) $INCLUDES" - } else { - set cmd "$TCL(cc) $TCL(shlib_cflags) $TCL(cflags_optimize) \ -$TCL(cflags_warning) $TCL(extra_cflags) $INCLUDES" - } - append cmd " $OBJECTS" - append cmd " $EXTERN_OBJS " - # On OSX it is impossibly to generate a completely static - # executable - if {[$PROJECT define get TEACUP_OS] ne "macosx"} { - append cmd " -static " - } - parray TCL - if {$debug} { - if {$os eq "windows"} { - append cmd " -L${TCL(src_dir)}/win -ltcl86g" - append cmd " -L${TK(src_dir)}/win -ltk86g" - } else { - append cmd " -L${TCL(src_dir)}/unix -ltcl86g" - append cmd " -L${TK(src_dir)}/unix -ltk86g" - } - } else { - append cmd " $TCL(build_lib_spec) $TK(build_lib_spec)" - } - foreach obj $PKG_OBJS { - append cmd " [$obj linker-products $config($obj)]" - } - append cmd " $TCL(libs) $TK(libs)" - foreach obj $PKG_OBJS { - append cmd " [$obj linker-external $config($obj)]" - } - if {$debug} { - if {$os eq "windows"} { - append cmd " -L${TCL(src_dir)}/win ${TCL(stub_lib_flag)}" - append cmd " -L${TK(src_dir)}/win ${TK(stub_lib_flag)}" - } else { - append cmd " -L${TCL(src_dir)}/unix ${TCL(stub_lib_flag)}" - append cmd " -L${TK(src_dir)}/unix ${TK(stub_lib_flag)}" - } - } else { - append cmd " $TCL(build_stub_lib_spec)" - append cmd " $TK(build_stub_lib_spec)" - } - append cmd " -o $outfile $LDFLAGS_CONSOLE" - puts "LINK: $cmd" - exec {*}$cmd >&@ stdout -} - -::oo::class create ::practcl::target_obj { - superclass ::practcl::metaclass - - constructor {name info} { - my variable define triggered domake - set triggered 0 - set domake 0 - set define(name) $name - set data [uplevel 2 [list subst $info]] - array set define $data - my select - my initialize - } - - method do {} { - my variable domake - return $domake - } - - method check {} { - my variable needs_make domake - if {$domake} { - return 1 - } - if {[info exists needs_make]} { - return $needs_make - } - set needs_make 0 - foreach item [my define get depends] { - if {![dict exists $::make_objects $item]} continue - set depobj [dict get $::make_objects $item] - if {$depobj eq [self]} { - puts "WARNING [self] depends on itself" - continue - } - if {[$depobj check]} { - set needs_make 1 - } - } - if {!$needs_make} { - set filename [my define get filename] - if {$filename ne {} && ![file exists $filename]} { - set needs_make 1 - } - } - return $needs_make - } - - method triggers {} { - my variable triggered domake define - if {$triggered} { - return $domake - } - set triggered 1 - foreach item [my define get depends] { - puts [list $item [dict exists $::make_objects $item]] - if {![dict exists $::make_objects $item]} continue - set depobj [dict get $::make_objects $item] - if {$depobj eq [self]} { - puts "WARNING [self] triggers itself" - continue - } else { - set r [$depobj check] - puts [list $depobj check $r] - if {$r} { - puts [list $depobj TRIGGER] - $depobj triggers - } - } - } - if {[info exists ::make($define(name))] && $::make($define(name))} { - return - } - set ::make($define(name)) 1 - ::practcl::trigger {*}[my define get triggers] - } -} - - -### -# Define the metaclass -### -::oo::class create ::practcl::object { - superclass ::practcl::metaclass - - constructor {parent args} { - my variable links define - set organs [$parent child organs] - my graft {*}$organs - array set define $organs - array set define [$parent child define] - array set links {} - if {[llength $args]==1 && [file exists [lindex $args 0]]} { - my InitializeSourceFile [lindex $args 0] - } elseif {[llength $args] == 1} { - set data [uplevel 1 [list subst [lindex $args 0]]] - array set define $data - my select - my initialize - } else { - array set define [uplevel 1 [list subst $args]] - my select - my initialize - } - } - - - method include_dir args { - my define add include_dir {*}$args - } - - method include_directory args { - my define add include_dir {*}$args - } - - method Collate_Source CWD {} - - - method child {method} { - return {} - } - - method InitializeSourceFile filename { - my define set filename $filename - set class {} - switch [file extension $filename] { - .tcl { - set class ::practcl::dynamic - } - .h { - set class ::practcl::cheader - } - .c { - set class ::practcl::csource - } - .ini { - switch [file tail $filename] { - module.ini { - set class ::practcl::module - } - library.ini { - set class ::practcl::subproject - } - } - } - .so - - .dll - - .dylib - - .a { - set class ::practcl::clibrary - } - } - if {$class ne {}} { - oo::objdefine [self] class $class - my initialize - } - } - - method add args { - my variable links - set object [::practcl::object new [self] {*}$args] - foreach linktype [$object linktype] { - lappend links($linktype) $object - } - return $object - } - - method go {} { - debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] - my variable links - foreach {linktype objs} [array get links] { - foreach obj $objs { - $obj go - } - } - debug [list /[self] [self method] [self class]] - } - - method code {section body} { - my variable code - ::practcl::cputs code($section) $body - } - - method Ofile filename { - set lpath [my define get localpath] - if {$lpath eq {}} { - set lpath [my define get name] - } - return ${lpath}_[file rootname [file tail $filename]].o - } - - method compile-products {} { - set filename [my define get filename] - set result {} - if {$filename ne {}} { - if {[my define exists ofile]} { - set ofile [my define get ofile] - } else { - set ofile [my Ofile $filename] - my define set ofile $ofile - } - lappend result $ofile [list cfile $filename extra [my define get extra] external [string is true -strict [my define get external]] object [self]] - } - foreach item [my link list subordinate] { - lappend result {*}[$item compile-products] - } - return $result - } - - method generate-include-directory {} { - debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] - set result [my define get include_dir] - foreach obj [my link list product] { - foreach path [$obj generate-include-directory] { - lappend result $path - } - } - return $result - } - - method generate-debug {{spaces {}}} { - set result {} - ::practcl::cputs result "$spaces[list [self] [list class [info object class [self]] filename [my define get filename]] links [my link list]]" - foreach item [my link list subordinate] { - practcl::cputs result [$item generate-debug "$spaces "] - } - return $result - } - - # Empty template methods - method generate-cheader {} { - debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] - my variable code cfunct cstruct methods tcltype tclprocs - set result {} - if {[info exists code(header)]} { - ::practcl::cputs result $code(header) - } - foreach obj [my link list product] { - # Exclude products that will generate their own C files - if {[$obj define get output_c] ne {}} continue - ::practcl::cputs result "/* BEGIN [$obj define get filename] generate-cheader */" - ::practcl::cputs result [$obj generate-cheader] - ::practcl::cputs result "/* END [$obj define get filename] generate-cheader */" - } - debug [list cfunct [info exists cfunct]] - if {[info exists cfunct]} { - foreach {funcname info} $cfunct { - if {[dict get $info public]} continue - ::practcl::cputs result "[dict get $info header]\;" - } - } - debug [list tclprocs [info exists tclprocs]] - if {[info exists tclprocs]} { - foreach {name info} $tclprocs { - if {[dict exists $info header]} { - ::practcl::cputs result "[dict get $info header]\;" - } - } - } - debug [list methods [info exists methods] [my define get cclass]] - - if {[info exists methods]} { - set thisclass [my define get cclass] - foreach {name info} $methods { - if {[dict exists $info header]} { - ::practcl::cputs result "[dict get $info header]\;" - } - } - # Add the initializer wrapper for the class - ::practcl::cputs result "static int ${thisclass}_OO_Init(Tcl_Interp *interp)\;" - } - return $result - } - - method generate-public-define {} { - debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] - my variable code - set result {} - if {[info exists code(public-define)]} { - ::practcl::cputs result $code(public-define) - } - set result [::practcl::_tagblock $result c [my define get filename]] - foreach mod [my link list product] { - ::practcl::cputs result [$mod generate-public-define] - } - return $result - } - - method generate-public-macro {} { - debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] - my variable code - set result {} - if {[info exists code(public-macro)]} { - ::practcl::cputs result $code(public-macro) - } - set result [::practcl::_tagblock $result c [my define get filename]] - foreach mod [my link list product] { - ::practcl::cputs result [$mod generate-public-macro] - } - return $result - } - - method generate-public-typedef {} { - debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] - my variable code cstruct - set result {} - if {[info exists code(public-typedef)]} { - ::practcl::cputs result $code(public-typedef) - } - if {[info exists cstruct]} { - # Add defintion for native c data structures - foreach {name info} $cstruct { - ::practcl::cputs result "typedef struct $name ${name}\;" - if {[dict exists $info aliases]} { - foreach n [dict get $info aliases] { - ::practcl::cputs result "typedef struct $name ${n}\;" - } - } - } - } - set result [::practcl::_tagblock $result c [my define get filename]] - foreach mod [my link list product] { - ::practcl::cputs result [$mod generate-public-typedef] - } - return $result - } - - method generate-public-structure {} { - debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] - my variable code cstruct - set result {} - if {[info exists code(public-structure)]} { - ::practcl::cputs result $code(public-structure) - } - if {[info exists cstruct]} { - foreach {name info} $cstruct { - if {[dict exists $info comment]} { - ::practcl::cputs result [dict get $info comment] - } - ::practcl::cputs result "struct $name \{[dict get $info body]\}\;" - } - } - set result [::practcl::_tagblock $result c [my define get filename]] - foreach mod [my link list product] { - ::practcl::cputs result [$mod generate-public-structure] - } - return $result - } - method generate-public-headers {} { - debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] - my variable code tcltype - set result {} - if {[info exists code(public-header)]} { - ::practcl::cputs result $code(public-header) - } - if {[info exists tcltype]} { - foreach {type info} $tcltype { - if {![dict exists $info cname]} { - set cname [string tolower ${type}]_tclobjtype - dict set tcltype $type cname $cname - } else { - set cname [dict get $info cname] - } - ::practcl::cputs result "extern const Tcl_ObjType $cname\;" - } - } - if {[info exists code(public)]} { - ::practcl::cputs result $code(public) - } - set result [::practcl::_tagblock $result c [my define get filename]] - foreach mod [my link list product] { - ::practcl::cputs result [$mod generate-public-headers] - } - return $result - } - - method generate-stub-function {} { - debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] - my variable code cfunct tcltype - set result {} - foreach mod [my link list product] { - foreach {funct def} [$mod generate-stub-function] { - dict set result $funct $def - } - } - if {[info exists cfunct]} { - foreach {funcname info} $cfunct { - if {![dict get $info export]} continue - dict set result $funcname [dict get $info header] - } - } - return $result - } - - method generate-public-function {} { - debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] - my variable code cfunct tcltype - set result {} - - if {[my define get initfunc] ne {}} { - ::practcl::cputs result "int [my define get initfunc](Tcl_Interp *interp);" - } - if {[info exists cfunct]} { - foreach {funcname info} $cfunct { - if {![dict get $info public]} continue - ::practcl::cputs result "[dict get $info header]\;" - } - } - set result [::practcl::_tagblock $result c [my define get filename]] - foreach mod [my link list product] { - ::practcl::cputs result [$mod generate-public-function] - } - return $result - } - - method generate-public-includes {} { - debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] - set includes {} - foreach item [my define get public-include] { - if {$item ni $includes} { - lappend includes $item - } - } - foreach mod [my link list product] { - foreach item [$mod generate-public-includes] { - if {$item ni $includes} { - lappend includes $item - } - } - } - return $includes - } - method generate-public-verbatim {} { - debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] - set includes {} - foreach item [my define get public-verbatim] { - if {$item ni $includes} { - lappend includes $item - } - } - foreach mod [my link list subordinate] { - foreach item [$mod generate-public-verbatim] { - if {$item ni $includes} { - lappend includes $item - } - } - } - return $includes - } - ### - # This methods generates the contents of an amalgamated .h file - # which describes the public API of this module - ### - method generate-h {} { - debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] - set result {} - set includes [my generate-public-includes] - foreach inc $includes { - if {[string index $inc 0] ni {< \"}} { - ::practcl::cputs result "#include \"$inc\"" - } else { - ::practcl::cputs result "#include $inc" - } - } - foreach file [my generate-public-verbatim] { - ::practcl::cputs result "/* BEGIN $file */" - ::practcl::cputs result [::practcl::cat $file] - ::practcl::cputs result "/* END $file */" - } - foreach method { - generate-public-define - generate-public-macro - generate-public-typedef - generate-public-structure - generate-public-headers - generate-public-function - } { - ::practcl::cputs result "/* BEGIN SECTION $method */" - ::practcl::cputs result [my $method] - ::practcl::cputs result "/* END SECTION $method */" - } - return $result - } - - ### - # This methods generates the contents of an amalgamated .c file - # which implements the loader for a batch of tools - ### - method generate-c {} { - debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] - set result { -/* This file was generated by practcl */ - } - set includes {} - lappend headers - if {[my define get tk 0]} { - lappend headers - } - lappend headers {*}[my define get include] - if {[my define get output_h] ne {}} { - lappend headers "\"[my define get output_h]\"" - } - foreach mod [my link list product] { - # Signal modules to formulate final implementation - $mod go - } - foreach mod [my link list dynamic] { - foreach inc [$mod define get include] { - if {$inc ni $headers} { - lappend headers $inc - } - } - } - foreach inc $headers { - if {[string index $inc 0] ni {< \"}} { - ::practcl::cputs result "#include \"$inc\"" - } else { - ::practcl::cputs result "#include $inc" - } - } - foreach {method} { - generate-cheader - generate-cstruct - generate-constant - generate-cfunct - generate-cmethod - } { - ::practcl::cputs result "/* BEGIN $method [my define get filename] */" - ::practcl::cputs result [my $method] - ::practcl::cputs result "/* END $method [my define get filename] */" - } - debug [list /[self] [self method] [self class] -- [my define get filename] [info object class [self]]] - return $result - } - - - method generate-loader {} { - debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] - set result {} - if {[my define get initfunc] eq {}} return - ::practcl::cputs result " -extern int DLLEXPORT [my define get initfunc]( Tcl_Interp *interp ) \{" - ::practcl::cputs result { - /* Initialise the stubs tables. */ - #ifdef USE_TCL_STUBS - if (Tcl_InitStubs(interp, "8.6", 0)==NULL) return TCL_ERROR; - if (TclOOInitializeStubs(interp, "1.0") == NULL) return TCL_ERROR; -} - if {[my define get tk 0]} { - ::practcl::cputs result { if (Tk_InitStubs(interp, "8.6", 0)==NULL) return TCL_ERROR;} - } - ::practcl::cputs result { #endif} - set TCLINIT [my generate-tcl] - ::practcl::cputs result " if(Tcl_Eval(interp,[::practcl::tcl_to_c $TCLINIT])) return TCL_ERROR ;" - foreach item [my link list product] { - if {[$item define get output_c] ne {}} { - ::practcl::cputs result [$item generate-cinit-external] - } else { - ::practcl::cputs result [$item generate-cinit] - } - } - if {[my define exists pkg_name]} { - ::practcl::cputs result " if (Tcl_PkgProvide(interp, \"[my define get pkg_name [my define get name]]\" , \"[my define get pkg_vers [my define get version]]\" )) return TCL_ERROR\;" - } - ::practcl::cputs result " return TCL_OK\;\n\}\n" - return $result - } - - ### - # This methods generates any Tcl script file - # which is required to pre-initialize the C library - ### - method generate-tcl {} { - debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] - set result {} - my variable code - if {[info exists code(tcl)]} { - ::practcl::cputs result $code(tcl) - } - set result [::practcl::_tagblock $result tcl [my define get filename]] - foreach mod [my link list product] { - ::practcl::cputs result [$mod generate-tcl] - } - return $result - } - - method static-packages {} { - set result [my define get static_packages] - set statpkg [my define get static_pkg] - set initfunc [my define get initfunc] - if {$initfunc ne {}} { - set pkg_name [my define get pkg_name] - if {$pkg_name ne {}} { - dict set result $pkg_name initfunc $initfunc - dict set result $pkg_name version [my define get version [my define get pkg_vers]] - dict set result $pkg_name autoload [my define get autoload 0] - } - } - foreach item [my link list subordinate] { - foreach {pkg info} [$item static-packages] { - dict set result $pkg $info - } - } - return $result - } - - method target {method args} { - switch $method { - is_unix { return [expr {$::tcl_platform(platform) eq "unix"}] } - } - } - -} - -::oo::class create ::practcl::product { - superclass ::practcl::object - - method linktype {} { - return {subordinate product} - } - - method include header { - my define add include $header - } - - method cstructure {name definition {argdat {}}} { - my variable cstruct - dict set cstruct $name body $definition - foreach {f v} $argdat { - dict set cstruct $name $f $v - } - } - - method generate-cinit {} { - debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] - my variable code - set result {} - if {[info exists code(cinit)]} { - ::practcl::cputs result $code(cinit) - } - if {[my define get initfunc] ne {}} { - ::practcl::cputs result " if([my define get initfunc](interp)!=TCL_OK) return TCL_ERROR\;" - } - set result [::practcl::_tagblock $result c [my define get filename]] - foreach obj [my link list product] { - ::practcl::cputs result [$obj generate-cinit] - } - return $result - } -} - -### -# Dynamic blocks do not generate their own .c files, -# instead the contribute to the amalgamation -# of the main library file -### -::oo::class create ::practcl::dynamic { - superclass ::practcl::product - - # Retrieve any additional source files required - - method compile-products {} { - set filename [my define get output_c] - set result {} - if {$filename ne {}} { - if {[my define exists ofile]} { - set ofile [my define get ofile] - } else { - set ofile [my Ofile $filename] - my define set ofile $ofile - } - lappend result $ofile [list cfile $filename extra [my define get extra] external [string is true -strict [my define get external]]] - } else { - set filename [my define get cfile] - if {$filename ne {}} { - if {[my define exists ofile]} { - set ofile [my define get ofile] - } else { - set ofile [my Ofile $filename] - my define set ofile $ofile - } - lappend result $ofile [list cfile $filename extra [my define get extra] external [string is true -strict [my define get external]]] - } - } - foreach item [my link list subordinate] { - lappend result {*}[$item compile-products] - } - return $result - } - - method implement path { - my go - my Collate_Source $path - if {[my define get output_c] eq {}} return - set filename [file join $path [my define get output_c]] - my define set cfile $filename - set fout [open $filename w] - puts $fout [my generate-c] - puts $fout "extern int DLLEXPORT [my define get initfunc]( Tcl_Interp *interp ) \x7B" - puts $fout [my generate-cinit] - if {[my define get pkg_name] ne {}} { - puts $fout " Tcl_PkgProvide(interp, \"[my define get pkg_name]\", \"[my define get pkg_vers]\");" - } - puts $fout " return TCL_OK\;" - puts $fout "\x7D" - close $fout - } - - method initialize {} { - set filename [my define get filename] - if {$filename eq {}} { - return - } - if {[my define get name] eq {}} { - my define set name [file tail [file rootname $filename]] - } - if {[my define get localpath] eq {}} { - my define set localpath [my define get localpath]_[my define get name] - } - ::source $filename - } - - method linktype {} { - return {subordinate product dynamic} - } - - ### - # Populate const static data structures - ### - method generate-cstruct {} { - debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] - my variable code cstruct methods tcltype - set result {} - if {[info exists code(struct)]} { - ::practcl::cputs result $code(struct) - } - foreach obj [my link list dynamic] { - # Exclude products that will generate their own C files - if {[$obj define get output_c] ne {}} continue - ::practcl::cputs result [$obj generate-cstruct] - } - return $result - } - - method generate-constant {} { - debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] - set result {} - my variable code cstruct methods tcltype - if {[info exists code(constant)]} { - ::practcl::cputs result "/* [my define get filename] CONSTANT */" - ::practcl::cputs result $code(constant) - } - if {[info exists cstruct]} { - foreach {name info} $cstruct { - set map {} - lappend map @NAME@ $name - lappend map @MACRO@ GET[string toupper $name] - - if {[dict exists $info deleteproc]} { - lappend map @DELETEPROC@ [dict get $info deleteproc] - } else { - lappend map @DELETEPROC@ NULL - } - if {[dict exists $info cloneproc]} { - lappend map @CLONEPROC@ [dict get $info cloneproc] - } else { - lappend map @CLONEPROC@ NULL - } - ::practcl::cputs result [string map $map { -const static Tcl_ObjectMetadataType @NAME@DataType = { - TCL_OO_METADATA_VERSION_CURRENT, - "@NAME@", - @DELETEPROC@, - @CLONEPROC@ -}; -#define @MACRO@(OBJCONTEXT) (@NAME@ *) Tcl_ObjectGetMetadata(OBJCONTEXT,&@NAME@DataType) -}] - } - } - if {[info exists tcltype]} { - foreach {type info} $tcltype { - dict with info {} - ::practcl::cputs result "const Tcl_ObjType $cname = \{\n .freeIntRepProc = &${freeproc},\n .dupIntRepProc = &${dupproc},\n .updateStringProc = &${updatestringproc},\n .setFromAnyProc = &${setfromanyproc}\n\}\;" - } - } - - if {[info exists methods]} { - set mtypes {} - foreach {name info} $methods { - set callproc [dict get $info callproc] - set methodtype [dict get $info methodtype] - if {$methodtype in $mtypes} continue - lappend mtypes $methodtype - ### - # Build the data struct for this method - ### - ::practcl::cputs result "const static Tcl_MethodType $methodtype = \{" - ::practcl::cputs result " .version = TCL_OO_METADATA_VERSION_CURRENT,\n .name = \"$name\",\n .callProc = $callproc," - if {[dict exists $info deleteproc]} { - set deleteproc [dict get $info deleteproc] - } else { - set deleteproc NULL - } - if {$deleteproc ni { {} NULL }} { - ::practcl::cputs result " .deleteProc = $deleteproc," - } else { - ::practcl::cputs result " .deleteProc = NULL," - } - if {[dict exists $info cloneproc]} { - set cloneproc [dict get $info cloneproc] - } else { - set cloneproc NULL - } - if {$cloneproc ni { {} NULL }} { - ::practcl::cputs result " .cloneProc = $cloneproc\n\}\;" - } else { - ::practcl::cputs result " .cloneProc = NULL\n\}\;" - } - dict set methods $name methodtype $methodtype - } - } - foreach obj [my link list dynamic] { - # Exclude products that will generate their own C files - if {[$obj define get output_c] ne {}} continue - ::practcl::cputs result [$obj generate-constant] - } - return $result - } - - ### - # Generate code that provides subroutines called by - # Tcl API methods - ### - method generate-cfunct {} { - debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] - my variable code cfunct - set result {} - if {[info exists code(funct)]} { - ::practcl::cputs result $code(funct) - } - if {[info exists cfunct]} { - foreach {funcname info} $cfunct { - ::practcl::cputs result "[dict get $info header]\{[dict get $info body]\}\;" - } - } - foreach obj [my link list dynamic] { - # Exclude products that will generate their own C files - if {[$obj define get output_c] ne {}} { - continue - } - ::practcl::cputs result [$obj generate-cfunct] - } - return $result - } - - ### - # Generate code that provides implements Tcl API - # calls - ### - method generate-cmethod {} { - debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] - my variable code methods tclprocs - set result {} - if {[info exists code(method)]} { - ::practcl::cputs result $code(method) - } - - if {[info exists tclprocs]} { - foreach {name info} $tclprocs { - if {![dict exists $info body]} continue - set callproc [dict get $info callproc] - set header [dict get $info header] - set body [dict get $info body] - ::practcl::cputs result "${header} \{${body}\}" - } - } - - - if {[info exists methods]} { - set thisclass [my define get cclass] - foreach {name info} $methods { - if {![dict exists $info body]} continue - set callproc [dict get $info callproc] - set header [dict get $info header] - set body [dict get $info body] - ::practcl::cputs result "${header} \{${body}\}" - } - # Build the OO_Init function - ::practcl::cputs result "static int ${thisclass}_OO_Init(Tcl_Interp *interp) \{" - ::practcl::cputs result [string map [list @CCLASS@ $thisclass @TCLCLASS@ [my define get class]] { - /* - ** Build the "@TCLCLASS@" class - */ - Tcl_Obj* nameObj; /* Name of a class or method being looked up */ - Tcl_Object curClassObject; /* Tcl_Object representing the current class */ - Tcl_Class curClass; /* Tcl_Class representing the current class */ - - /* - * Find the "@TCLCLASS@" class, and attach an 'init' method to it. - */ - - nameObj = Tcl_NewStringObj("@TCLCLASS@", -1); - Tcl_IncrRefCount(nameObj); - if ((curClassObject = Tcl_GetObjectFromObj(interp, nameObj)) == NULL) { - Tcl_DecrRefCount(nameObj); - return TCL_ERROR; - } - Tcl_DecrRefCount(nameObj); - curClass = Tcl_GetObjectAsClass(curClassObject); -}] - if {[dict exists $methods constructor]} { - set mtype [dict get $methods constructor methodtype] - ::practcl::cputs result [string map [list @MTYPE@ $mtype] { - /* Attach the constructor to the class */ - Tcl_ClassSetConstructor(interp, curClass, Tcl_NewMethod(interp, curClass, NULL, 1, &@MTYPE@, NULL)); - }] - } - foreach {name info} $methods { - dict with info {} - if {$name in {constructor destructor}} continue - ::practcl::cputs result [string map [list @NAME@ $name @MTYPE@ $methodtype] { - nameObj=Tcl_NewStringObj("@NAME@",-1); - Tcl_NewMethod(interp, curClass, nameObj, 1, &@MTYPE@, (ClientData) NULL); - Tcl_DecrRefCount(nameObj); -}] - if {[dict exists $info aliases]} { - foreach alias [dict get $info aliases] { - if {[dict exists $methods $alias]} continue - ::practcl::cputs result [string map [list @NAME@ $alias @MTYPE@ $methodtype] { - nameObj=Tcl_NewStringObj("@NAME@",-1); - Tcl_NewMethod(interp, curClass, nameObj, 1, &@MTYPE@, (ClientData) NULL); - Tcl_DecrRefCount(nameObj); -}] - } - } - } - ::practcl::cputs result " return TCL_OK\;\n\}\n" - } - foreach obj [my link list dynamic] { - # Exclude products that will generate their own C files - if {[$obj define get output_c] ne {}} continue - ::practcl::cputs result [$obj generate-cmethod] - } - return $result - } - - method generate-cinit-external {} { - if {[my define get initfunc] eq {}} { - return "/* [my define get filename] declared not initfunc */" - } - return " if([my define get initfunc](interp)) return TCL_ERROR\;" - } - - ### - # Generate code that runs when the package/module is - # initialized into the interpreter - ### - method generate-cinit {} { - debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] - set result {} - my variable code methods tclprocs - if {[info exists code(nspace)]} { - ::practcl::cputs result " \{\n Tcl_Namespace *modPtr;" - foreach nspace $code(nspace) { - ::practcl::cputs result [string map [list @NSPACE@ $nspace] { - modPtr=Tcl_FindNamespace(interp,"@NSPACE@",NULL,TCL_NAMESPACE_ONLY); - if(!modPtr) { - modPtr = Tcl_CreateNamespace(interp, "@NSPACE@", NULL, NULL); - } -}] - } - ::practcl::cputs result " \}" - } - if {[info exists code(tclinit)]} { - ::practcl::cputs result $code(tclinit) - } - if {[info exists code(cinit)]} { - ::practcl::cputs result $code(cinit) - } - if {[info exists code(initfuncts)]} { - foreach func $code(initfuncts) { - ::practcl::cputs result " if (${func}(interp) != TCL_OK) return TCL_ERROR\;" - } - } - if {[info exists tclprocs]} { - foreach {name info} $tclprocs { - set map [list @NAME@ $name @CALLPROC@ [dict get $info callproc]] - ::practcl::cputs result [string map $map { Tcl_CreateObjCommand(interp,"@NAME@",(Tcl_ObjCmdProc *)@CALLPROC@,NULL,NULL);}] - if {[dict exists $info aliases]} { - foreach alias [dict get $info aliases] { - set map [list @NAME@ $alias @CALLPROC@ [dict get $info callproc]] - ::practcl::cputs result [string map $map { Tcl_CreateObjCommand(interp,"@NAME@",(Tcl_ObjCmdProc *)@CALLPROC@,NULL,NULL);}] - } - } - } - } - - if {[info exists code(nspace)]} { - ::practcl::cputs result " \{\n Tcl_Namespace *modPtr;" - foreach nspace $code(nspace) { - ::practcl::cputs result [string map [list @NSPACE@ $nspace] { - modPtr=Tcl_FindNamespace(interp,"@NSPACE@",NULL,TCL_NAMESPACE_ONLY); - Tcl_CreateEnsemble(interp, modPtr->fullName, modPtr, TCL_ENSEMBLE_PREFIX); - Tcl_Export(interp, modPtr, "[a-z]*", 1); -}] - } - ::practcl::cputs result " \}" - } - set result [::practcl::_tagblock $result c [my define get filename]] - foreach obj [my link list product] { - # Exclude products that will generate their own C files - if {[$obj define get output_c] ne {}} { - ::practcl::cputs result [$obj generate-cinit-external] - } else { - ::practcl::cputs result [$obj generate-cinit] - } - } - return $result - } - - method c_header body { - my variable code - ::practcl::cputs code(header) $body - } - - method c_code body { - my variable code - ::practcl::cputs code(funct) $body - } - method c_function {header body} { - my variable code cfunct - foreach regexp { - {(.*) ([a-zA-Z_][a-zA-Z0-9_]*) *\((.*)\)} - {(.*) (\x2a[a-zA-Z_][a-zA-Z0-9_]*) *\((.*)\)} - } { - if {[regexp $regexp $header all keywords funcname arglist]} { - dict set cfunct $funcname header $header - dict set cfunct $funcname body $body - dict set cfunct $funcname keywords $keywords - dict set cfunct $funcname arglist $arglist - dict set cfunct $funcname public [expr {"static" ni $keywords}] - dict set cfunct $funcname export [expr {"STUB_EXPORT" in $keywords}] - - return - } - } - ::practcl::cputs code(header) "$header\;" - # Could not parse that block as a function - # append it verbatim to our c_implementation - ::practcl::cputs code(funct) "$header [list $body]" - } - - - method cmethod {name body {arginfo {}}} { - my variable methods code - foreach {f v} $arginfo { - dict set methods $name $f $v - } - dict set methods $name body "Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */ -$body" - } - - method c_tclproc_nspace nspace { - my variable code - if {![info exists code(nspace)]} { - set code(nspace) {} - } - if {$nspace ni $code(nspace)} { - lappend code(nspace) $nspace - } - } - - method c_tclproc_raw {name body {arginfo {}}} { - my variable tclprocs code - - foreach {f v} $arginfo { - dict set tclprocs $name $f $v - } - dict set tclprocs $name body $body - } - - method go {} { - debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] - next - my variable methods code cstruct tclprocs - if {[info exists methods]} { - debug [self] methods [my define get cclass] - set thisclass [my define get cclass] - foreach {name info} $methods { - # Provide a callproc - if {![dict exists $info callproc]} { - set callproc [string map {____ _ ___ _ __ _} [string map {{ } _ : _} OOMethod_${thisclass}_${name}]] - dict set methods $name callproc $callproc - } else { - set callproc [dict get $info callproc] - } - if {[dict exists $info body] && ![dict exists $info header]} { - dict set methods $name header "static int ${callproc}(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv)" - } - if {![dict exists $info methodtype]} { - set methodtype [string map {{ } _ : _} MethodType_${thisclass}_${name}] - dict set methods $name methodtype $methodtype - } - } - if {![info exists code(initfuncts)] || "${thisclass}_OO_Init" ni $code(initfuncts)} { - lappend code(initfuncts) "${thisclass}_OO_Init" - } - } - set thisnspace [my define get nspace] - - if {[info exists tclprocs]} { - debug [self] tclprocs [dict keys $tclprocs] - foreach {name info} $tclprocs { - if {![dict exists $info callproc]} { - set callproc [string map {____ _ ___ _ __ _} [string map {{ } _ : _} Tclcmd_${thisnspace}_${name}]] - dict set tclprocs $name callproc $callproc - } else { - set callproc [dict get $info callproc] - } - if {[dict exists $info body] && ![dict exists $info header]} { - dict set tclprocs $name header "static int ${callproc}(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv\[\])" - } - } - } - debug [list /[self] [self method] [self class]] - } - - # Once an object marks itself as some - # flavor of dynamic, stop trying to morph - # it into something else - method select {} {} - - - method tcltype {name argdat} { - my variable tcltype - foreach {f v} $argdat { - dict set tcltype $name $f $v - } - if {![dict exists tcltype $name cname]} { - dict set tcltype $name cname [string tolower $name]_tclobjtype - } - lappend map @NAME@ $name - set info [dict get $tcltype $name] - foreach {f v} $info { - lappend map @[string toupper $f]@ $v - } - foreach {func fpat template} { - freeproc {@Name@Obj_freeIntRepProc} {void @FNAME@(Tcl_Obj *objPtr)} - dupproc {@Name@Obj_dupIntRepProc} {void @FNAME@(Tcl_Obj *srcPtr,Tcl_Obj *dupPtr)} - updatestringproc {@Name@Obj_updateStringRepProc} {void @FNAME@(Tcl_Obj *objPtr)} - setfromanyproc {@Name@Obj_setFromAnyProc} {int @FNAME@(Tcl_Interp *interp,Tcl_Obj *objPtr)} - } { - if {![dict exists $info $func]} { - error "$name does not define $func" - } - set body [dict get $info $func] - # We were given a function name to call - if {[llength $body] eq 1} continue - set fname [string map [list @Name@ [string totitle $name]] $fpat] - my c_function [string map [list @FNAME@ $fname] $template] [string map $map $body] - dict set tcltype $name $func $fname - } - } -} - -::oo::class create ::practcl::cheader { - superclass ::practcl::product - - method compile-products {} {} - method generate-cinit {} {} -} - -::oo::class create ::practcl::csource { - superclass ::practcl::product -} - -::oo::class create ::practcl::clibrary { - superclass ::practcl::product - - method linker-products {configdict} { - return [my define get filename] - } - -} - -### -# In the end, all C code must be loaded into a module -# This will either be a dynamically loaded library implementing -# a tcl extension, or a compiled in segment of a custom shell/app -### -::oo::class create ::practcl::module { - superclass ::practcl::dynamic - - method child which { - switch $which { - organs { - return [list project [my define get project] module [self]] - } - } - } - - method initialize {} { - set filename [my define get filename] - if {$filename eq {}} { - return - } - if {[my define get name] eq {}} { - my define set name [file tail [file dirname $filename]] - } - if {[my define get localpath] eq {}} { - my define set localpath [my define get name]_[my define get name] - } - debug [self] SOURCE $filename - my source $filename - } - - method implement path { - my go - my Collate_Source $path - foreach item [my link list dynamic] { - if {[catch {$item implement $path} err]} { - puts "Skipped $item: $err" - } - } - foreach item [my link list module] { - if {[catch {$item implement $path} err]} { - puts "Skipped $item: $err" - } - } - debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] - set filename [my define get output_c] - if {$filename eq {}} { - debug [list /[self] [self method] [self class]] - return - } - set cout [open [file join $path [file rootname $filename].c] w] - puts $cout [subst {/* -** This file is generated by the [info script] script -** any changes will be overwritten the next time it is run -*/}] - puts $cout [my generate-c] - puts $cout [my generate-loader] - close $cout - debug [list /[self] [self method] [self class]] - } - - method linktype {} { - return {subordinate product dynamic module} - } -} - -::oo::class create ::practcl::autoconf { - - ### - # find or fake a key/value list describing this project - ### - method config.sh {} { - my variable conf_result - if {[info exists conf_result]} { - return $conf_result - } - set result {} - set name [my define get name] - set PWD $::CWD - set builddir [my define get builddir] - my unpack - set srcroot [my define get srcroot] - if {![file exists $builddir]} { - my Configure - } - set filename [file join $builddir config.tcl] - # Project uses the practcl template. Use the leavings from autoconf - if {[file exists $filename]} { - set dat [::practcl::config.tcl $builddir] - foreach {item value} [lsort -stride 2 -dictionary $dat] { - dict set result $item $value - } - set conf_result $result - return $result - } - set filename [file join $builddir ${name}Config.sh] - if {[file exists $filename]} { - set l [expr {[string length $name]+1}] - foreach {field dat} [::practcl::read_Config.sh $filename] { - set field [string tolower $field] - if {[string match ${name}_* $field]} { - set field [string range $field $l end] - } - dict set result $field $dat - } - set conf_result $result - return $result - } - ### - # Oh man... we have to guess - ### - set filename [file join $builddir Makefile] - if {![file exists $filename]} { - error "Could not locate any configuration data in $srcroot" - } - foreach {field dat} [::practcl::read_Makefile $filename] { - dict set result $field $dat - } - set conf_result $result - cd $PWD - return $result - } -} - - -::oo::class create ::practcl::project { - superclass ::practcl::module ::practcl::autoconf - - constructor args { - my variable define - if {[llength $args] == 1} { - if {[catch {uplevel 1 [list subst [lindex $args 0]]} contents]} { - set contents [lindex $args 0] - } - } else { - if {[catch {uplevel 1 [list subst $args]} contents]} { - set contents $args - } - } - array set define $contents - my select - my initialize - } - - - method add_project {pkg info {oodefine {}}} { - set os [my define get os] - if {$os eq {}} { - set os [::practcl::os] - my define set os $os - } - set fossilinfo [list download [my define get download] tag trunk sandbox [my define get sandbox]] - if {[dict exists $info os] && ($os ni [dict get $info os])} return - # Select which tag to use here. - # For production builds: tag-release - if {[::info exists ::env(FOSSIL_MIRROR)]} { - dict set info localmirror $::env(FOSSIL_MIRROR) - } - set profile [my define get profile release]: - if {[dict exists $info profile $profile]} { - dict set info tag [dict get $info profile $profile] - } - set obj [namespace current]::PROJECT.$pkg - if {[info command $obj] eq {}} { - set obj [::practcl::subproject create $obj [self] [dict merge $fossilinfo [list name $pkg pkg_name $pkg static 0] $info]] - } - my link object $obj - oo::objdefine $obj $oodefine - $obj define set masterpath $::CWD - $obj go - return $obj - } - - method child which { - switch $which { - organs { - # A library can be a project, it can be a module. Any - # subordinate modules will indicate their existance - return [list project [self] module [self]] - } - } - } - - method linktype {} { - return project - } - - # Exercise the methods of a sub-object - method project {pkg args} { - set obj [namespace current]::PROJECT.$pkg - if {[llength $args]==0} { - return $obj - } - tailcall ${obj} {*}$args - } -} - -::oo::class create ::practcl::library { - superclass ::practcl::project - - method compile-products {} { - set result {} - foreach item [my link list subordinate] { - lappend result {*}[$item compile-products] - } - set filename [my define get output_c] - if {$filename ne {}} { - set ofile [file rootname [file tail $filename]]_main.o - lappend result $ofile [list cfile $filename extra [my define get extra] external [string is true -strict [my define get external]]] - } - return $result - } - - method generate-tcl-loader {} { - set result {} - set PKGINIT [my define get pkginit] - set PKG_NAME [my define get name [my define get pkg_name]] - set PKG_VERSION [my define get pkg_vers [my define get version]] - if {[string is true [my define get SHARED_BUILD 0]]} { - set LIBFILE [my define get libfile] - ::practcl::cputs result [string map \ - [list @LIBFILE@ $LIBFILE @PKGINIT@ $PKGINIT @PKG_NAME@ $PKG_NAME @PKG_VERSION@ $PKG_VERSION] { -# Shared Library Style -load [file join [file dirname [file join [pwd] [info script]]] @LIBFILE@] @PKGINIT@ -package provide @PKG_NAME@ @PKG_VERSION@ -}] - } else { - ::practcl::cputs result [string map \ - [list @PKGINIT@ $PKGINIT @PKG_NAME@ $PKG_NAME @PKG_VERSION@ $PKG_VERSION] { -# Tclkit Style -load {} @PKGINIT@ -package provide @PKG_NAME@ @PKG_VERSION@ -}] - } - return $result - } - - method go {} { - debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] - set name [my define getnull name] - if {$name eq {}} { - set name generic - my define name generic - } - if {[my define get tk] eq {@TEA_TK_EXTENSION@}} { - my define set tk 0 - } - set output_c [my define getnull output_c] - if {$output_c eq {}} { - set output_c [file rootname $name].c - my define set output_c $output_c - } - set output_h [my define getnull output_h] - if {$output_h eq {}} { - set output_h [file rootname $output_c].h - my define set output_h $output_h - } - set output_tcl [my define getnull output_tcl] - #if {$output_tcl eq {}} { - # set output_tcl [file rootname $output_c].tcl - # my define set output_tcl $output_tcl - #} - #set output_mk [my define getnull output_mk] - #if {$output_mk eq {}} { - # set output_mk [file rootname $output_c].mk - # my define set output_mk $output_mk - #} - set initfunc [my define getnull initfunc] - if {$initfunc eq {}} { - set initfunc [string totitle $name]_Init - my define set initfunc $initfunc - } - set output_decls [my define getnull output_decls] - if {$output_decls eq {}} { - set output_decls [file rootname $output_c].decls - my define set output_decls $output_decls - } - my variable links - foreach {linktype objs} [array get links] { - foreach obj $objs { - $obj go - } - } - debug [list /[self] [self method] [self class] -- [my define get filename] [info object class [self]]] - } - - method implement path { - my go - my Collate_Source $path - foreach item [my link list dynamic] { - if {[catch {$item implement $path} err]} { - puts "Skipped $item: $err" - } - } - foreach item [my link list module] { - if {[catch {$item implement $path} err]} { - puts "Skipped $item: $err" - } - } - set cout [open [file join $path [my define get output_c]] w] - puts $cout [subst {/* -** This file is generated by the [info script] script -** any changes will be overwritten the next time it is run -*/}] - puts $cout [my generate-c] - puts $cout [my generate-loader] - close $cout - - set macro HAVE_[string toupper [file rootname [my define get output_h]]]_H - set hout [open [file join $path [my define get output_h]] w] - puts $hout [subst {/* -** This file is generated by the [info script] script -** any changes will be overwritten the next time it is run -*/}] - puts $hout "#ifndef ${macro}" - puts $hout "#define ${macro}" - puts $hout [my generate-h] - puts $hout "#endif" - close $hout - - set output_tcl [my define get output_tcl] - if {$output_tcl ne {}} { - set tclout [open [file join $path [my define get output_tcl]] w] - puts $tclout "### -# This file is generated by the [info script] script -# any changes will be overwritten the next time it is run -###" - puts $tclout [my generate-tcl] - puts $tclout [my generate-tcl-loader] - close $tclout - } - } - - method generate-decls {pkgname path} { - debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] - set outfile [file join $path/$pkgname.decls] - - ### - # Build the decls file - ### - set fout [open $outfile w] - puts $fout [subst {### - # $outfile - # - # This file was generated by [info script] - ### - - library $pkgname - interface $pkgname - }] - - ### - # Generate list of functions - ### - set stubfuncts [my generate-stub-function] - set thisline {} - set functcount 0 - foreach {func header} $stubfuncts { - puts $fout [list declare [incr functcount] $header] - } - puts $fout [list export "int [my define get initfunc](Tcl_Inter *interp)"] - puts $fout [list export "char *[string totitle [my define get name]]_InitStubs(Tcl_Inter *interp, char *version, int exact)"] - - close $fout - - ### - # Build [package]Decls.h - ### - set hout [open [file join $path ${pkgname}Decls.h] w] - - close $hout - - set cout [open [file join $path ${pkgname}StubInit.c] w] -puts $cout [string map [list %pkgname% $pkgname %PkgName% [string totitle $pkgname]] { -#ifndef USE_TCL_STUBS -#define USE_TCL_STUBS -#endif -#undef USE_TCL_STUB_PROCS - -#include "tcl.h" -#include "%pkgname%.h" - - /* - ** Ensure that Tdom_InitStubs is built as an exported symbol. The other stub - ** functions should be built as non-exported symbols. - */ - -#undef TCL_STORAGE_CLASS -#define TCL_STORAGE_CLASS DLLEXPORT - -%PkgName%Stubs *%pkgname%StubsPtr; - - /* - **---------------------------------------------------------------------- - ** - ** %PkgName%_InitStubs -- - ** - ** Checks that the correct version of %PkgName% is loaded and that it - ** supports stubs. It then initialises the stub table pointers. - ** - ** Results: - ** The actual version of %PkgName% that satisfies the request, or - ** NULL to indicate that an error occurred. - ** - ** Side effects: - ** Sets the stub table pointers. - ** - **---------------------------------------------------------------------- - */ - -char * -%PkgName%_InitStubs (Tcl_Interp *interp, char *version, int exact) -{ - char *actualVersion; - actualVersion = Tcl_PkgRequireEx(interp, "%pkgname%", version, exact,(ClientData *) &%pkgname%StubsPtr); - if (!actualVersion) { - return NULL; - } - if (!%pkgname%StubsPtr) { - Tcl_SetResult(interp,"This implementation of %PkgName% does not support stubs",TCL_STATIC); - return NULL; - } - return actualVersion; -} -}] - close $cout - } - - # Backward compadible call - method generate-make path { - ::practcl::build::Makefile $path [self] - } - - method install-headers {} { - set result {} - return $result - } - - method linktype {} { - return library - } - - # Create a "package ifneeded" - # Args are a list of aliases for which this package will answer to - method package-ifneeded {args} { - set result {} - set name [my define get pkg_name [my define get name]] - set version [my define get pkg_vers [my define get version]] - if {$version eq {}} { - set version 0.1a - } - set output_tcl [my define get output_tcl] - if {$output_tcl ne {}} { - set script "\[list source \[file join \$dir $output_tcl\]\]" - } elseif {[string is true -strict [my define get SHARED_BUILD]]} { - set script "\[list load \[file join \$dir [my define get libfile]\] $name\]" - } else { - # Provide a null passthrough - set script [list package provide $name $version] - } - set result "package ifneeded [list $name] [list $version] $script" - foreach alias $args { - set script "package require $name $version \; package provide $alias $version" - append result \n\n [list package ifneeded $alias $version $script] - } - return $result - } - - - method shared_library {} { - set name [string tolower [my define get name [my define get pkg_name]]] - set NAME [string toupper $name] - set version [my define get version [my define get pkg_vers]] - set map {} - lappend map %LIBRARY_NAME% $name - lappend map %LIBRARY_VERSION% $version - lappend map %LIBRARY_VERSION_NODOTS% [string map {. {}} $version] - lappend map %LIBRARY_PREFIX% [my define getnull libprefix] - set outfile [string map $map [my define get PRACTCL_NAME_LIBRARY]][my define get SHLIB_SUFFIX] - return $outfile - } -} - -::oo::class create ::practcl::tclkit { - superclass ::practcl::library - - method Collate_Source CWD { - my define set SHARED_BUILD 0 - set name [my define get name] - - if {![my define exists TCL_LOCAL_APPINIT]} { - my define set TCL_LOCAL_APPINIT Tclkit_AppInit - } - if {![my define exists TCL_LOCAL_MAIN_HOOK]} { - my define set TCL_LOCAL_MAIN_HOOK Tclkit_MainHook - } - - set PROJECT [self] - set os [$PROJECT define get os] - set TCLOBJ [$PROJECT project TCLCORE] - set TKOBJ [$PROJECT project TKCORE] - set ODIEOBJ [$PROJECT project odie] - - set TCLSRCDIR [$TCLOBJ define get srcroot] - set TKSRCDIR [$TKOBJ define get srcroot] - set PKG_OBJS {} - foreach item [$PROJECT link list package] { - if {[string is true [$item define get static]]} { - lappend PKG_OBJS $item - } - } - # Arrange to build an main.c that utilizes TCL_LOCAL_APPINIT and TCL_LOCAL_MAIN_HOOK - if {$os eq "windows"} { - set PLATFORM_SRC_DIR win - my add class csource filename [file join $TCLSRCDIR win tclWinReg.c] initfunc Registry_Init pkg_name registry pkg_vers 1.3.1 autoload 1 - my add class csource filename [file join $TCLSRCDIR win tclWinDde.c] initfunc Dde_Init pkg_name dde pkg_vers 1.4.0 autoload 1 - my add class csource ofile [my define get name]_appinit.o filename [file join $TCLSRCDIR win tclAppInit.c] extra [list -DTCL_LOCAL_MAIN_HOOK=[my define get TCL_LOCAL_MAIN_HOOK Tclkit_MainHook] -DTCL_LOCAL_APPINIT=[my define get TCL_LOCAL_APPINIT Tclkit_AppInit]] - } else { - set PLATFORM_SRC_DIR unix - my add class csource ofile [my define get name]_appinit.o filename [file join $TCLSRCDIR unix tclAppInit.c] extra [list -DTCL_LOCAL_MAIN_HOOK=[my define get TCL_LOCAL_MAIN_HOOK Tclkit_MainHook] -DTCL_LOCAL_APPINIT=[my define get TCL_LOCAL_APPINIT Tclkit_AppInit]] - } - ### - # Add local static Zlib implementation - ### - set cdir [file join $TCLSRCDIR compat zlib] - foreach file { - adler32.c compress.c crc32.c - deflate.c infback.c inffast.c - inflate.c inftrees.c trees.c - uncompr.c zutil.c - } { - my add [file join $cdir $file] - } - - ### - # Pre 8.7, Tcl doesn't include a Zipfs implementation - # in the core. Grab the one from odielib - ### - set zipfs [file join $TCLSRCDIR generic zvfs.c] - if {![file exists $zipfs]} { - # The Odie project maintains a mirror of the version - # released with the Tcl core - my add_project odie { - tag trunk - class subproject - vfsinstall 0 - } - my project odie unpack - set ODIESRCROOT [my project odie define get srcroot] - set cdir [file join $ODIESRCROOT compat zipfs] - my define add include_dir $cdir - set zipfs [file join $cdir zvfs.c] - } - - my add class csource filename $zipfs initfunc Tclzipfs_Init pkg_name zipfs pkg_vers 1.0 autoload 1 - - my define add include_dir [file join $TKSRCDIR generic] - my define add include_dir [file join $TKSRCDIR $PLATFORM_SRC_DIR] - my define add include_dir [file join $TKSRCDIR bitmaps] - my define add include_dir [file join $TKSRCDIR xlib] - my define add include_dir [file join $TCLSRCDIR generic] - my define add include_dir [file join $TCLSRCDIR $PLATFORM_SRC_DIR] - my define add include_dir [file join $TCLSRCDIR compat zlib] - # This file will implement TCL_LOCAL_APPINIT and TCL_LOCAL_MAIN_HOOK - ::practcl::build::tclkit_main $PROJECT $PKG_OBJS - } - - ## Wrap an executable - # - method wrap {PWD exename vfspath args} { - cd $PWD - if {![file exists $vfspath]} { - file mkdir $vfspath - } - foreach item [my link list core.library] { - set name [$item define get name] - set libsrcroot [$item define get srcroot] - if {[file exists [file join $libsrcroot library]]} { - ::practcl::copyDir [file join $libsrcroot library] [file join $vfspath boot $name] - } - } - if {[my define get installdir] ne {}} { - ::practcl::copyDir [file join [my define get installdir] [string trimleft [my define get prefix] /] lib] [file join $vfspath lib] - } - foreach arg $args { - ::practcl::copyDir $arg $vfspath - } - - set fout [open [file join $vfspath packages.tcl] w] - puts $fout { - set ::PKGIDXFILE [info script] - set dir [file dirname $::PKGIDXFILE] - } - #set BASEVFS [my define get BASEVFS] - set EXEEXT [my define get EXEEXT] - - set tclkit_bare [my define get tclkit_bare] - - set buffer [::practcl::pkgindex_path $vfspath] - puts $fout $buffer - puts $fout { - # Advertise statically linked packages - foreach {pkg script} [array get ::kitpkg] { - eval $script - } - } - close $fout - package require zipfile::mkzip - ::zipfile::mkzip::mkzip ${exename}${EXEEXT} -runtime $tclkit_bare -directory $vfspath - if { [my define get platform] ne "windows" } { - file attributes ${exename}${EXEEXT} -permissions a+x - } - } -} - -### -# Meta repository -# The default is an inert source code block -### -oo::class create ::practcl::subproject { - superclass ::practcl::object - - method compile {} {} - - method go {} { - set platform [my define get platform] - my define get USEMSVC [my define get USEMSVC] - set name [my define get name] - if {![my define exists srcroot]} { - my define set srcroot [file join [my define get sandbox] $name] - } - set srcroot [my define get srcroot] - my define set localsrcdir $srcroot - my define add include_dir [file join $srcroot generic] - my sources - } - - # Install project into the local build system - method install-local {} { - my unpack - } - - # Install project into the virtual file system - method install-vfs {} {} - - method linktype {} { - return {subordinate package} - } - - method linker-products {configdict} {} - - method linker-external {configdict} { - if {[dict exists $configdict PRACTCL_LIBS]} { - return [dict get $configdict PRACTCL_LIBS] - } - } - - method sources {} {} - - method unpack {} { - set name [my define get name] - puts [list $name [self] UNPACK] - my define set [::practcl::fossil_sandbox $name [my define dump]] - } - - method update {} { - set name [my define get name] - my define set [::practcl::fossil_sandbox $name [dict merge [my define dump] {update 1}]] - } -} - -### -# A project which the kit compiles and integrates -# the source for itself -### -oo::class create ::practcl::subproject.source { - superclass ::practcl::subproject ::practcl::library - - method linktype {} { - return {subordinate package source} - } - -} - -# a copy from the teapot -oo::class create ::practcl::subproject.teapot { - superclass ::practcl::subproject - - method install-local {} { - my install-vfs - } - - method install-vfs {} { - set pkg [my define get pkg_name [my define get name]] - set download [my define get download] - my unpack - set DEST [my define get installdir] - set prefix [string trimleft [my define get prefix] /] - # Get tcllib from our destination - set dir [file join $DEST $prefix lib tcllib] - source [file join $DEST $prefix lib tcllib pkgIndex.tcl] - package require zipfile::decode - ::zipfile::decode::unzipfile [file join $download $pkg.zip] [file join $DEST $prefix lib $pkg] - } -} - -oo::class create ::practcl::subproject.sak { - superclass ::practcl::subproject - - method install-local {} { - my install-vfs - } - - method install-vfs {} { - ### - # Handle teapot installs - ### - set pkg [my define get pkg_name [my define get name]] - my unpack - set DEST [my define get installdir] - set prefix [string trimleft [my define get prefix] /] - set srcroot [my define get srcroot] - ::dotclexec [file join $srcroot installer.tcl] \ - -pkg-path [file join $DEST $prefix lib $pkg] \ - -no-examples -no-html -no-nroff \ - -no-wait -no-gui -no-apps - } -} - -### -# A binary package -### -oo::class create ::practcl::subproject.binary { - superclass ::practcl::subproject ::practcl::autoconf - - - method compile-products {} {} - - method ConfigureOpts {} { - set opts {} - set builddir [my define get builddir] - if {[my define get broken_destroot 0]} { - set PREFIX [my define get prefix_broken_destdir] - } else { - set PREFIX [my define get prefix] - } - if {[my define get HOST] != [my define get TARGET]} { - lappend opts --host=[my define get TARGET] - } - if {[my define exists tclsrcdir]} { - set TCLSRCDIR [::practcl::file_relative [file normalize $builddir] [file normalize [file join $::CWD [my define get tclsrcdir]]]] - set TCLGENERIC [::practcl::file_relative [file normalize $builddir] [file normalize [file join $::CWD [my define get tclsrcdir] .. generic]]] - lappend opts --with-tcl=$TCLSRCDIR --with-tclinclude=$TCLGENERIC - } - if {[my define exists tksrcdir]} { - set TKSRCDIR [::practcl::file_relative [file normalize $builddir] [file normalize [file join $::CWD [my define get tksrcdir]]]] - set TKGENERIC [::practcl::file_relative [file normalize $builddir] [file normalize [file join $::CWD [my define get tksrcdir] .. generic]]] - lappend opts --with-tk=$TKSRCDIR --with-tkinclude=$TKGENERIC - } - lappend opts {*}[my define get config_opts] - lappend opts --prefix=$PREFIX - #--exec_prefix=$PREFIX - #if {$::tcl_platform(platform) eq "windows"} { - # lappend opts --disable-64bit - #} - if {[my define get static 1]} { - lappend opts --disable-shared --disable-stubs - # - } else { - lappend opts --enable-shared - } - return $opts - } - - method go {} { - next - my define set builddir [my BuildDir [my define get masterpath]] - } - - method linker-products {configdict} { - if {![my define get static 0]} { - return {} - } - set srcdir [my define get builddir] - if {[dict exists $configdict libfile]} { - return " [file join $srcdir [dict get $configdict libfile]]" - } - } - - method static-packages {} { - if {![my define get static 0]} { - return {} - } - set result [my define get static_packages] - set statpkg [my define get static_pkg] - set initfunc [my define get initfunc] - if {$initfunc ne {}} { - set pkg_name [my define get pkg_name] - if {$pkg_name ne {}} { - dict set result $pkg_name initfunc $initfunc - set version [my define get version] - if {$version eq {}} { - set info [my config.sh] - set version [dict get $info version] - set pl {} - if {[dict exists $info patch_level]} { - set pl [dict get $info patch_level] - append version $pl - } - my define set version $version - } - dict set result $pkg_name version $version - dict set result $pkg_name autoload [my define get autoload 0] - } - } - foreach item [my link list subordinate] { - foreach {pkg info} [$item static-packages] { - dict set result $pkg $info - } - } - return $result - } - - method BuildDir {PWD} { - set name [my define get name] - return [my define get builddir [file join $PWD pkg.$name]] - } - - method compile {} { - set name [my define get name] - set PWD $::CWD - cd $PWD - my go - set srcroot [file normalize [my define get srcroot]] - my Collate_Source $PWD - - ### - # Build a starter VFS for both Tcl and wish - ### - set srcroot [my define get srcroot] - if {[my define get static 1]} { - puts "BUILDING Static $name $srcroot" - } else { - puts "BUILDING Dynamic $name $srcroot" - } - if {[my define get USEMSVC 0]} { - cd $srcroot - doexec nmake -f makefile.vc INSTALLDIR=[my define get installdir] release - } else { - cd $::CWD - set builddir [file normalize [my define get builddir]] - file mkdir $builddir - if {![file exists [file join $builddir Makefile]]} { - my Configure - } - if {[file exists [file join $builddir make.tcl]]} { - domake.tcl $builddir library - } else { - domake $builddir all - } - } - cd $PWD - } - - - method Configure {} { - cd $::CWD - my unpack - my TeaConfig - set builddir [file normalize [my define get builddir]] - file mkdir $builddir - set srcroot [file normalize [my define get srcroot]] - if {[my define get USEMSVC 0]} { - return - } - set opts [my ConfigureOpts] - puts [list [self] CONFIGURE] - puts [list PWD [pwd]] - puts [list LOCALSRC $srcroot] - puts [list BUILDDIR $builddir] - puts [list CONFIGURE {*}$opts] - cd $builddir - exec sh [file join $srcroot configure] {*}$opts >& [file join $builddir practcl.log] - cd $::CWD - } - - method install-vfs {} { - set PWD [pwd] - set PKGROOT [my define get installdir] - set PREFIX [my define get prefix] - - ### - # Handle teapot installs - ### - set pkg [my define get pkg_name [my define get name]] - if {[my define get teapot] ne {}} { - set TEAPOT [my define get teapot] - set found 0 - foreach ver [my define get pkg_vers [my define get version]] { - set teapath [file join $TEAPOT $pkg$ver] - if {[file exists $teapath]} { - set dest [file join $PKGROOT [string trimleft $PREFIX /] lib [file tail $teapath]] - ::practcl::copyDir $teapath $dest - return - } - } - } - my compile - if {[my define get USEMSVC 0]} { - set srcroot [my define get srcroot] - cd $srcroot - puts "[self] VFS INSTALL $PKGROOT" - doexec nmake -f makefile.vc INSTALLDIR=$PKGROOT install - } else { - set builddir [my define get builddir] - if {[file exists [file join $builddir make.tcl]]} { - # Practcl builds can inject right to where we need them - puts "[self] VFS INSTALL $PKGROOT (Practcl)" - domake.tcl $builddir install-package $PKGROOT - } elseif {[my define get broken_destroot 0] == 0} { - # Most modern TEA projects understand DESTROOT in the makefile - puts "[self] VFS INSTALL $PKGROOT (TEA)" - domake $builddir install DESTDIR=$PKGROOT - } else { - # But some require us to do an install into a fictitious filesystem - # and then extract the gooey parts within. - # (*cough*) TkImg - set PREFIX [my define get prefix] - set BROKENROOT [::practcl::msys_to_tclpath [my define get prefix_broken_destdir]] - file delete -force $BROKENROOT - file mkdir $BROKENROOT - domake $builddir $install - ::practcl::copyDir $BROKENROOT [file join $PKGROOT [string trimleft $PREFIX /]] - file delete -force $BROKENROOT - } - } - cd $PWD - } - - method TeaConfig {} { - set srcroot [file normalize [my define get srcroot]] - set copytea 0 - if {![file exists [file join $srcroot tclconfig]]} { - set copytea 1 - } else { - if {![file exists [file join $srcroot tclconfig practcl.tcl]] || ![file exists [file join $srcroot tclconfig config.tcl.in]]} { - set copytea 1 - } - } - # ensure we have tclconfig with all of the trimming - if {$copytea} { - set tclconfiginfo [::practcl::fossil_sandbox tclconfig [list sandbox [my define get sandbox]]] - ::practcl::copyDir [dict get $tclconfiginfo srcroot] [file join $srcroot tclconfig] - if {$::tcl_platform(platform) ne "windows"} { - set pwd [pwd] - cd $srcroot - # On windows there's no practical way to execute - # autoconf. We'll have to trust that configure - # us up to date - foreach template {configure.ac configure.in} { - set input [file join $srcroot $template] - if {[file exists $input]} { - puts "autoconf -f $input > [file join $srcroot configure]" - exec autoconf -f $input > [file join $srcroot configure] - } - } - cd $pwd - } - } - } -} - -oo::class create ::practcl::subproject.core { - superclass ::practcl::subproject.binary - - # On the windows platform MinGW must build - # from the platform directory in the source repo - method BuildDir {PWD} { - return [my define get localsrcdir] - } - - method Configure {} { - if {[my define get USEMSVC 0]} { - return - } - set opts [my ConfigureOpts] - puts [list PWD [pwd]] - puts [list [self] CONFIGURE] - set builddir [file normalize [my define get builddir]] - set localsrcdir [file normalize [my define get localsrcdir]] - puts [list LOCALSRC $localsrcdir] - puts [list BUILDDIR $builddir] - puts [list CONFIGURE {*}$opts] - cd $localsrcdir - exec sh [file join $localsrcdir configure] {*}$opts >& [file join $builddir practcl.log] - } - - method ConfigureOpts {} { - set opts {} - set builddir [file normalize [my define get builddir]] - set PREFIX [my define get prefix] - if {[my define get HOST] != [my define get TARGET]} { - lappend opts --host=[my define get TARGET] - } - lappend opts {*}[my define get config_opts] - lappend opts --prefix=$PREFIX - #--exec_prefix=$PREFIX - lappend opts --disable-shared - return $opts - } - - method go {} { - set name [my define get name] - set platform [my define get platform] - if {![my define exists srcroot]} { - my define set srcroot [file join [my define get sandbox] $name] - } - set srcroot [my define get srcroot] - my define add include_dir [file join $srcroot generic] - switch $platform { - windows { - my define set localsrcdir [file join $srcroot win] - my define add include_dir [file join $srcroot win] - } - default { - my define set localsrcdir [file join $srcroot unix] - my define add include_dir [file join $srcroot $name unix] - } - } - my define set builddir [my BuildDir [my define get masterpath]] - } - - method linktype {} { - return {subordinate core.library} - } -} - -package provide practcl 0.5 + ::practcl::cputs appinit " if(${initfunc}(interp)) return TCL_ERROR\;" + ::practcl::cputs appinit " Tcl_StaticPackage(interp,\"$statpkg\",$initfunc,NULL)\;" + } else { + ::practcl::cputs appinit "\n Tcl_StaticPackage(NULL,\"$statpkg\",$initfunc,NULL)\;" + append main_init_script \n $script + } + } + append main_init_script \n { +if {[file exists [file join $::SRCDIR packages.tcl]]} { + #In a wrapped exe, we don't go out to the environment + set dir $::SRCDIR + source [file join $::SRCDIR packages.tcl] +} +# Specify a user-specific startup file to invoke if the application +# is run interactively. Typically the startup file is "~/.apprc" +# where "app" is the name of the application. If this line is deleted +# then no user-specific startup file will be run under any conditions. + } + append main_init_script \n [list set tcl_rcFileName [$PROJECT define get tcl_rcFileName ~/.tclshrc]] + practcl::cputs appinit " Tcl_Eval(interp,[::practcl::tcl_to_c $main_init_script]);" + practcl::cputs appinit { return TCL_OK;} + $PROJECT c_function [string map $map "int %mainfunc%(Tcl_Interp *interp)"] [string map $map $appinit] +} + +proc ::practcl::build::compile-sources {PROJECT COMPILE {CPPCOMPILE {}}} { + set EXTERN_OBJS {} + set OBJECTS {} + set result {} + set builddir [$PROJECT define get builddir] + file mkdir [file join $builddir objs] + set debug [$PROJECT define get debug 0] + if {$CPPCOMPILE eq {}} { + set CPPCOMPILE $COMPILE + } + set task [${PROJECT} compile-products] + ### + # Compile the C sources + ### + foreach {ofile info} $task { + dict set task $ofile done 0 + if {[dict exists $info external] && [dict get $info external]==1} { + dict set task $ofile external 1 + } else { + dict set task $ofile external 0 + } + if {[dict exists $info library]} { + dict set task $ofile done 1 + continue + } + # Products with no cfile aren't compiled + if {![dict exists $info cfile] || [set cfile [dict get $info cfile]] eq {}} { + dict set task $ofile done 1 + continue + } + set cfile [dict get $info cfile] + set ofilename [file join $builddir objs [file tail $ofile]] + if {$debug} { + set ofilename [file join $builddir objs [file rootname [file tail $ofile]].debug.o] + } + dict set task $ofile filename $ofilename + if {[file exists $ofilename] && [file mtime $ofilename]>[file mtime $cfile]} { + lappend result $ofilename + dict set task $ofile done 1 + continue + } + if {![dict exist $info command]} { + if {[file extension $cfile] in {.c++ .cpp}} { + set cmd $CPPCOMPILE + } else { + set cmd $COMPILE + } + if {[dict exists $info extra]} { + append cmd " [dict get $info extra]" + } + append cmd " -c $cfile" + append cmd " -o $ofilename" + dict set task $ofile command $cmd + } + } + set completed 0 + while {$completed==0} { + set completed 1 + foreach {ofile info} $task { + set waiting {} + if {[dict exists $info done] && [dict get $info done]} continue + if {[dict exists $info depend]} { + foreach file [dict get $info depend] { + if {[dict exists $task $file command] && [dict exists $task $file done] && [dict get $task $file done] != 1} { + set waiting $file + break + } + } + } + if {$waiting ne {}} { + set completed 0 + puts "$ofile waiting for $waiting" + continue + } + if {[dict exists $info command]} { + set cmd [dict get $info command] + puts "$cmd" + exec {*}$cmd >&@ stdout + } + lappend result [dict get $info filename] + dict set task $ofile done 1 + } + } + return $result +} + +proc ::practcl::de_shell {data} { + set values {} + foreach flag {DEFS TCL_DEFS TK_DEFS} { + if {[dict exists $data $flag]} { + set value {} + foreach item [dict get $data $flag] { + append value " " [string map {{ } {\ }} $item] + } + dict set values $flag $value + } + } + set map {} + lappend map {${PKG_OBJECTS}} %LIBRARY_OBJECTS% + lappend map {$(PKG_OBJECTS)} %LIBRARY_OBJECTS% + lappend map {${PKG_STUB_OBJECTS}} %LIBRARY_STUB_OBJECTS% + lappend map {$(PKG_STUB_OBJECTS)} %LIBRARY_STUB_OBJECTS% + + lappend map %LIBRARY_NAME% [dict get $data name] + lappend map %LIBRARY_VERSION% [dict get $data version] + lappend map %LIBRARY_VERSION_NODOTS% [string map {. {}} [dict get $data version]] + if {[dict exists $data libprefix]} { + lappend map %LIBRARY_PREFIX% [dict get $data libprefix] + } else { + lappend map %LIBRARY_PREFIX% [dict get $data prefix] + } + foreach flag [dict keys $data] { + if {$flag in {TCL_DEFS TK_DEFS DEFS}} continue + + dict set map "%${flag}%" [dict get $data $flag] + dict set map "\$\{${flag}\}" [dict get $data $flag] + dict set map "\$\(${flag}\)" [dict get $data $flag] + dict set values $flag [dict get $data $flag] + #dict set map "\$\{${flag}\}" $proj($flag) + } + set changed 1 + while {$changed} { + set changed 0 + foreach {field value} $values { + if {$field in {TCL_DEFS TK_DEFS DEFS}} continue + dict with values {} + set newval [string map $map $value] + if {$newval eq $value} continue + set changed 1 + dict set values $field $newval + } + } + return $values +} + +proc ::practcl::build::Makefile {path PROJECT} { + array set proj [$PROJECT define dump] + set path $proj(builddir) + cd $path + set includedir . + #lappend includedir [::practcl::file_relative $path $proj(TCL_INCLUDES)] + lappend includedir [::practcl::file_relative $path [file normalize [file join $proj(TCL_SRC_DIR) generic]]] + lappend includedir [::practcl::file_relative $path [file normalize [file join $proj(srcdir) generic]]] + foreach include [$PROJECT generate-include-directory] { + set cpath [::practcl::file_relative $path [file normalize $include]] + if {$cpath ni $includedir} { + lappend includedir $cpath + } + } + set INCLUDES "-I[join $includedir " -I"]" + set NAME [string toupper $proj(name)] + set result {} + set products {} + set libraries {} + set thisline {} + ::practcl::cputs result "${NAME}_DEFS = $proj(DEFS)\n" + ::practcl::cputs result "${NAME}_INCLUDES = -I\"[join $includedir "\" -I\""]\"\n" + ::practcl::cputs result "${NAME}_COMPILE = \$(CC) \$(CFLAGS) \$(PKG_CFLAGS) \$(${NAME}_DEFS) \$(${NAME}_INCLUDES) \$(INCLUDES) \$(AM_CPPFLAGS) \$(CPPFLAGS) \$(AM_CFLAGS)" + ::practcl::cputs result "${NAME}_CPPCOMPILE = \$(CXX) \$(CFLAGS) \$(PKG_CFLAGS) \$(${NAME}_DEFS) \$(${NAME}_INCLUDES) \$(INCLUDES) \$(AM_CPPFLAGS) \$(CPPFLAGS) \$(AM_CFLAGS)" + + foreach {ofile info} [$PROJECT compile-products] { + dict set products $ofile $info + if {[dict exists $info library]} { +lappend libraries $ofile +continue + } + if {[dict exists $info depend]} { + ::practcl::cputs result "\n${ofile}: [dict get $info depend]" + } else { + ::practcl::cputs result "\n${ofile}:" + } + set cfile [dict get $info cfile] + if {[file extension $cfile] in {.c++ .cpp}} { + set cmd "\t\$\(${NAME}_CPPCOMPILE\)" + } else { + set cmd "\t\$\(${NAME}_COMPILE\)" + } + if {[dict exists $info extra]} { + append cmd " [dict get $info extra]" + } + append cmd " -c [dict get $info cfile] -o \$@\n\t" + ::practcl::cputs result $cmd + } + + set map {} + lappend map %LIBRARY_NAME% $proj(name) + lappend map %LIBRARY_VERSION% $proj(version) + lappend map %LIBRARY_VERSION_NODOTS% [string map {. {}} $proj(version)] + lappend map %LIBRARY_PREFIX% [$PROJECT define getnull libprefix] + + if {[string is true [$PROJECT define get SHARED_BUILD]]} { + set outfile [$PROJECT define get libfile] + } else { + set outfile [$PROJECT shared_library] + } + $PROJECT define set shared_library $outfile + ::practcl::cputs result " +${NAME}_SHLIB = $outfile +${NAME}_OBJS = [dict keys $products] +" + + #lappend map %OUTFILE% {\[$]@} + lappend map %OUTFILE% $outfile + lappend map %LIBRARY_OBJECTS% "\$(${NAME}_OBJS)" + ::practcl::cputs result "$outfile: \$(${NAME}_OBJS)" + ::practcl::cputs result "\t[string map $map [$PROJECT define get PRACTCL_SHARED_LIB]]" + if {[$PROJECT define get PRACTCL_VC_MANIFEST_EMBED_DLL] ni {: {}}} { + ::practcl::cputs result "\t[string map $map [$PROJECT define get PRACTCL_VC_MANIFEST_EMBED_DLL]]" + } + ::practcl::cputs result {} + if {[string is true [$PROJECT define get SHARED_BUILD]]} { + #set outfile [$PROJECT static_library] + set outfile $proj(name).a + } else { + set outfile [$PROJECT define get libfile] + } + $PROJECT define set static_library $outfile + dict set map %OUTFILE% $outfile + ::practcl::cputs result "$outfile: \$(${NAME}_OBJS)" + ::practcl::cputs result "\t[string map $map [$PROJECT define get PRACTCL_STATIC_LIB]]" + ::practcl::cputs result {} + return $result +} + +### +# Produce a dynamic library +### +proc ::practcl::build::library {outfile PROJECT} { + array set proj [$PROJECT define dump] + set path $proj(builddir) + cd $path + set includedir . + #lappend includedir [::practcl::file_relative $path $proj(TCL_INCLUDES)] + lappend includedir [::practcl::file_relative $path [file normalize [file join $proj(TCL_SRC_DIR) generic]]] + lappend includedir [::practcl::file_relative $path [file normalize [file join $proj(srcdir) generic]]] + if {[$PROJECT define get tk 0]} { + lappend includedir [::practcl::file_relative $path [file normalize [file join $proj(TK_SRC_DIR) generic]]] + lappend includedir [::practcl::file_relative $path [file normalize [file join $proj(TK_SRC_DIR) ttk]]] + lappend includedir [::practcl::file_relative $path [file normalize [file join $proj(TK_SRC_DIR) xlib]]] + lappend includedir [::practcl::file_relative $path [file normalize $proj(TK_BIN_DIR)]] + } + foreach include [$PROJECT generate-include-directory] { + set cpath [::practcl::file_relative $path [file normalize $include]] + if {$cpath ni $includedir} { + lappend includedir $cpath + } + } + ::practcl::build::DEFS $PROJECT $proj(DEFS) name version defs + set NAME [string toupper $name] + set debug [$PROJECT define get debug 0] + set os [$PROJECT define get os] + + set INCLUDES "-I[join $includedir " -I"]" + if {$debug} { + set COMPILE "$proj(CC) $proj(CFLAGS_DEBUG) -ggdb \ +$proj(CFLAGS_WARNING) $INCLUDES $defs" + + if {[info exists proc(CXX)]} { + set COMPILECPP "$proj(CXX) $defs $INCLUDES $proj(CFLAGS_DEBUG) -ggdb \ + $proj(DEFS) $proj(CFLAGS_WARNING)" + } else { + set COMPILECPP $COMPILE + } + } else { + set COMPILE "$proj(CC) $proj(CFLAGS) $defs $INCLUDES " + + if {[info exists proc(CXX)]} { + set COMPILECPP "$proj(CXX) $defs $INCLUDES $proj(CFLAGS) $proj(DEFS)" + } else { + set COMPILECPP $COMPILE + } + } + + set products [compile-sources $PROJECT $COMPILE $COMPILECPP] + + set map {} + lappend map %LIBRARY_NAME% $proj(name) + lappend map %LIBRARY_VERSION% $proj(version) + lappend map %LIBRARY_VERSION_NODOTS% [string map {. {}} $proj(version)] + lappend map %OUTFILE% $outfile + lappend map %LIBRARY_OBJECTS% $products + lappend map {${CFLAGS}} "$proj(CFLAGS_DEFAULT) $proj(CFLAGS_WARNING)" + + if {[string is true [$PROJECT define get SHARED_BUILD 1]]} { + set cmd [$PROJECT define get PRACTCL_SHARED_LIB] + append cmd " [$PROJECT define get PRACTCL_LIBS]" + set cmd [string map $map $cmd] + puts $cmd + exec {*}$cmd >&@ stdout + if {[$PROJECT define get PRACTCL_VC_MANIFEST_EMBED_DLL] ni {: {}}} { + set cmd [string map $map [$PROJECT define get PRACTCL_VC_MANIFEST_EMBED_DLL]] + puts $cmd + exec {*}$cmd >&@ stdout + } + } else { + set cmd [string map $map [$PROJECT define get PRACTCL_STATIC_LIB]] + puts $cmd + exec {*}$cmd >&@ stdout + } +} + +### +# Produce a static executable +### +proc ::practcl::build::static-tclsh {outfile PROJECT} { + puts " BUILDING STATIC TCLSH " + set TCLOBJ [$PROJECT project TCLCORE] + set TKOBJ [$PROJECT project TKCORE] + set ODIEOBJ [$PROJECT project odie] + + set PKG_OBJS {} + foreach item [$PROJECT link list package] { + if {[string is true [$item define get static]]} { + lappend PKG_OBJS $item + } + } + array set TCL [$TCLOBJ config.sh] + array set TK [$TKOBJ config.sh] + set path [file dirname $outfile] + cd $path + ### + # For a static Tcl shell, we need to build all local sources + # with the same DEFS flags as the tcl core was compiled with. + # The DEFS produced by a TEA extension aren't intended to operate + # with the internals of a staticly linked Tcl + ### + ::practcl::build::DEFS $PROJECT $TCL(defs) name version defs + set debug [$PROJECT define get debug 0] + set NAME [string toupper $name] + set result {} + set libraries {} + set thisline {} + set OBJECTS {} + set EXTERN_OBJS {} + foreach obj $PKG_OBJS { + $obj compile + set config($obj) [$obj config.sh] + } + set os [$PROJECT define get os] + set TCLSRCDIR [$TCLOBJ define get srcroot] + set TKSRCDIR [$TKOBJ define get srcroot] + + set includedir . + foreach include [$TCLOBJ generate-include-directory] { + set cpath [::practcl::file_relative $path [file normalize $include]] + if {$cpath ni $includedir} { + lappend includedir $cpath + } + } + lappend includedir [::practcl::file_relative $path [file normalize ../tcl/compat/zlib]] + foreach include [$PROJECT generate-include-directory] { + set cpath [::practcl::file_relative $path [file normalize $include]] + if {$cpath ni $includedir} { + lappend includedir $cpath + } + } + + set INCLUDES "-I[join $includedir " -I"]" + if {$debug} { + set COMPILE "$TCL(cc) $TCL(shlib_cflags) $TCL(cflags_debug) -ggdb \ +$TCL(cflags_warning) $TCL(extra_cflags) $INCLUDES" + } else { + set COMPILE "$TCL(cc) $TCL(shlib_cflags) $TCL(cflags_optimize) \ +$TCL(cflags_warning) $TCL(extra_cflags) $INCLUDES" + } + append COMPILE " " $defs + lappend OBJECTS {*}[compile-sources $PROJECT $COMPILE $COMPILE] + + if {[${PROJECT} define get platform] eq "windows"} { + set RSOBJ [file join $path build tclkit.res.o] + set RCSRC [${PROJECT} define get kit_resource_file] + if {$RCSRC eq {} || ![file exists $RCSRC]} { + set RCSRC [file join $TKSRCDIR win rc wish.rc] + } + set cmd [list windres -o $RSOBJ -DSTATIC_BUILD] + set TCLSRC [file normalize $TCLSRCDIR] + set TKSRC [file normalize $TKSRCDIR] + + lappend cmd --include [::practcl::file_relative $path [file join $TCLSRC generic]] \ + --include [::practcl::file_relative $path [file join $TKSRC generic]] \ + --include [::practcl::file_relative $path [file join $TKSRC win]] \ + --include [::practcl::file_relative $path [file join $TKSRC win rc]] + foreach item [${PROJECT} define get resource_include] { + lappend cmd --include [::practcl::file_relative $path [file normalize $item]] + } + lappend cmd $RCSRC + doexec {*}$cmd + + lappend OBJECTS $RSOBJ + set LDFLAGS_CONSOLE {-mconsole -pipe -static-libgcc} + set LDFLAGS_WINDOW {-mwindows -pipe -static-libgcc} + } else { + set LDFLAGS_CONSOLE {} + set LDFLAGS_WINDOW {} + } + puts "***" + if {$debug} { + set cmd "$TCL(cc) $TCL(shlib_cflags) $TCL(cflags_debug) \ +$TCL(cflags_warning) $TCL(extra_cflags) $INCLUDES" + } else { + set cmd "$TCL(cc) $TCL(shlib_cflags) $TCL(cflags_optimize) \ +$TCL(cflags_warning) $TCL(extra_cflags) $INCLUDES" + } + append cmd " $OBJECTS" + append cmd " $EXTERN_OBJS " + # On OSX it is impossibly to generate a completely static + # executable + if {[$PROJECT define get TEACUP_OS] ne "macosx"} { + append cmd " -static " + } + parray TCL + if {$debug} { + if {$os eq "windows"} { + append cmd " -L${TCL(src_dir)}/win -ltcl86g" + append cmd " -L${TK(src_dir)}/win -ltk86g" + } else { + append cmd " -L${TCL(src_dir)}/unix -ltcl86g" + append cmd " -L${TK(src_dir)}/unix -ltk86g" + } + } else { + append cmd " $TCL(build_lib_spec) $TK(build_lib_spec)" + } + foreach obj $PKG_OBJS { + append cmd " [$obj linker-products $config($obj)]" + } + append cmd " $TCL(libs) $TK(libs)" + foreach obj $PKG_OBJS { + append cmd " [$obj linker-external $config($obj)]" + } + if {$debug} { + if {$os eq "windows"} { + append cmd " -L${TCL(src_dir)}/win ${TCL(stub_lib_flag)}" + append cmd " -L${TK(src_dir)}/win ${TK(stub_lib_flag)}" + } else { + append cmd " -L${TCL(src_dir)}/unix ${TCL(stub_lib_flag)}" + append cmd " -L${TK(src_dir)}/unix ${TK(stub_lib_flag)}" + } + } else { + append cmd " $TCL(build_stub_lib_spec)" + append cmd " $TK(build_stub_lib_spec)" + } + append cmd " -o $outfile $LDFLAGS_CONSOLE" + puts "LINK: $cmd" + exec {*}$cmd >&@ stdout +} + +::oo::class create ::practcl::target_obj { + superclass ::practcl::metaclass + + constructor {name info} { + my variable define triggered domake + set triggered 0 + set domake 0 + set define(name) $name + set data [uplevel 2 [list subst $info]] + array set define $data + my select + my initialize + } + + method do {} { + my variable domake + return $domake + } + + method check {} { + my variable needs_make domake + if {$domake} { + return 1 + } + if {[info exists needs_make]} { + return $needs_make + } + set needs_make 0 + foreach item [my define get depends] { + if {![dict exists $::make_objects $item]} continue + set depobj [dict get $::make_objects $item] + if {$depobj eq [self]} { + puts "WARNING [self] depends on itself" + continue + } + if {[$depobj check]} { + set needs_make 1 + } + } + if {!$needs_make} { + set filename [my define get filename] + if {$filename ne {} && ![file exists $filename]} { + set needs_make 1 + } + } + return $needs_make + } + + method triggers {} { + my variable triggered domake define + if {$triggered} { + return $domake + } + set triggered 1 + foreach item [my define get depends] { + puts [list $item [dict exists $::make_objects $item]] + if {![dict exists $::make_objects $item]} continue + set depobj [dict get $::make_objects $item] + if {$depobj eq [self]} { + puts "WARNING [self] triggers itself" + continue + } else { + set r [$depobj check] + puts [list $depobj check $r] + if {$r} { + puts [list $depobj TRIGGER] + $depobj triggers + } + } + } + if {[info exists ::make($define(name))] && $::make($define(name))} { + return + } + set ::make($define(name)) 1 + ::practcl::trigger {*}[my define get triggers] + } +} + + +### +# Define the metaclass +### +::oo::class create ::practcl::object { + superclass ::practcl::metaclass + + constructor {parent args} { + my variable links define + set organs [$parent child organs] + my graft {*}$organs + array set define $organs + array set define [$parent child define] + array set links {} + if {[llength $args]==1 && [file exists [lindex $args 0]]} { + my InitializeSourceFile [lindex $args 0] + } elseif {[llength $args] == 1} { + set data [uplevel 1 [list subst [lindex $args 0]]] + array set define $data + my select + my initialize + } else { + array set define [uplevel 1 [list subst $args]] + my select + my initialize + } + } + + + method include_dir args { + my define add include_dir {*}$args + } + + method include_directory args { + my define add include_dir {*}$args + } + + method Collate_Source CWD {} + + + method child {method} { + return {} + } + + method InitializeSourceFile filename { + my define set filename $filename + set class {} + switch [file extension $filename] { + .tcl { + set class ::practcl::dynamic + } + .h { + set class ::practcl::cheader + } + .c { + set class ::practcl::csource + } + .ini { + switch [file tail $filename] { + module.ini { + set class ::practcl::module + } + library.ini { + set class ::practcl::subproject + } + } + } + .so - + .dll - + .dylib - + .a { + set class ::practcl::clibrary + } + } + if {$class ne {}} { + oo::objdefine [self] class $class + my initialize + } + } + + method add args { + my variable links + set object [::practcl::object new [self] {*}$args] + foreach linktype [$object linktype] { + lappend links($linktype) $object + } + return $object + } + + method go {} { + debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] + my variable links + foreach {linktype objs} [array get links] { + foreach obj $objs { + $obj go + } + } + debug [list /[self] [self method] [self class]] + } + + method code {section body} { + my variable code + ::practcl::cputs code($section) $body + } + + method Ofile filename { + set lpath [my define get localpath] + if {$lpath eq {}} { + set lpath [my define get name] + } + return ${lpath}_[file rootname [file tail $filename]].o + } + + method compile-products {} { + set filename [my define get filename] + set result {} + if {$filename ne {}} { + if {[my define exists ofile]} { + set ofile [my define get ofile] + } else { + set ofile [my Ofile $filename] + my define set ofile $ofile + } + lappend result $ofile [list cfile $filename extra [my define get extra] external [string is true -strict [my define get external]] object [self]] + } + foreach item [my link list subordinate] { + lappend result {*}[$item compile-products] + } + return $result + } + + method generate-include-directory {} { + debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] + set result [my define get include_dir] + foreach obj [my link list product] { + foreach path [$obj generate-include-directory] { + lappend result $path + } + } + return $result + } + + method generate-debug {{spaces {}}} { + set result {} + ::practcl::cputs result "$spaces[list [self] [list class [info object class [self]] filename [my define get filename]] links [my link list]]" + foreach item [my link list subordinate] { + practcl::cputs result [$item generate-debug "$spaces "] + } + return $result + } + + # Empty template methods + method generate-cheader {} { + debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] + my variable code cfunct cstruct methods tcltype tclprocs + set result {} + if {[info exists code(header)]} { + ::practcl::cputs result $code(header) + } + foreach obj [my link list product] { + # Exclude products that will generate their own C files + if {[$obj define get output_c] ne {}} continue + ::practcl::cputs result "/* BEGIN [$obj define get filename] generate-cheader */" + ::practcl::cputs result [$obj generate-cheader] + ::practcl::cputs result "/* END [$obj define get filename] generate-cheader */" + } + debug [list cfunct [info exists cfunct]] + if {[info exists cfunct]} { + foreach {funcname info} $cfunct { + if {[dict get $info public]} continue + ::practcl::cputs result "[dict get $info header]\;" + } + } + debug [list tclprocs [info exists tclprocs]] + if {[info exists tclprocs]} { + foreach {name info} $tclprocs { + if {[dict exists $info header]} { + ::practcl::cputs result "[dict get $info header]\;" + } + } + } + debug [list methods [info exists methods] [my define get cclass]] + + if {[info exists methods]} { + set thisclass [my define get cclass] + foreach {name info} $methods { + if {[dict exists $info header]} { + ::practcl::cputs result "[dict get $info header]\;" + } + } + # Add the initializer wrapper for the class + ::practcl::cputs result "static int ${thisclass}_OO_Init(Tcl_Interp *interp)\;" + } + return $result + } + + method generate-public-define {} { + debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] + my variable code + set result {} + if {[info exists code(public-define)]} { + ::practcl::cputs result $code(public-define) + } + set result [::practcl::_tagblock $result c [my define get filename]] + foreach mod [my link list product] { + ::practcl::cputs result [$mod generate-public-define] + } + return $result + } + + method generate-public-macro {} { + debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] + my variable code + set result {} + if {[info exists code(public-macro)]} { + ::practcl::cputs result $code(public-macro) + } + set result [::practcl::_tagblock $result c [my define get filename]] + foreach mod [my link list product] { + ::practcl::cputs result [$mod generate-public-macro] + } + return $result + } + + method generate-public-typedef {} { + debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] + my variable code cstruct + set result {} + if {[info exists code(public-typedef)]} { + ::practcl::cputs result $code(public-typedef) + } + if {[info exists cstruct]} { + # Add defintion for native c data structures + foreach {name info} $cstruct { + ::practcl::cputs result "typedef struct $name ${name}\;" + if {[dict exists $info aliases]} { + foreach n [dict get $info aliases] { + ::practcl::cputs result "typedef struct $name ${n}\;" + } + } + } + } + set result [::practcl::_tagblock $result c [my define get filename]] + foreach mod [my link list product] { + ::practcl::cputs result [$mod generate-public-typedef] + } + return $result + } + + method generate-public-structure {} { + debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] + my variable code cstruct + set result {} + if {[info exists code(public-structure)]} { + ::practcl::cputs result $code(public-structure) + } + if {[info exists cstruct]} { + foreach {name info} $cstruct { + if {[dict exists $info comment]} { + ::practcl::cputs result [dict get $info comment] + } + ::practcl::cputs result "struct $name \{[dict get $info body]\}\;" + } + } + set result [::practcl::_tagblock $result c [my define get filename]] + foreach mod [my link list product] { + ::practcl::cputs result [$mod generate-public-structure] + } + return $result + } + method generate-public-headers {} { + debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] + my variable code tcltype + set result {} + if {[info exists code(public-header)]} { + ::practcl::cputs result $code(public-header) + } + if {[info exists tcltype]} { + foreach {type info} $tcltype { + if {![dict exists $info cname]} { + set cname [string tolower ${type}]_tclobjtype + dict set tcltype $type cname $cname + } else { + set cname [dict get $info cname] + } + ::practcl::cputs result "extern const Tcl_ObjType $cname\;" + } + } + if {[info exists code(public)]} { + ::practcl::cputs result $code(public) + } + set result [::practcl::_tagblock $result c [my define get filename]] + foreach mod [my link list product] { + ::practcl::cputs result [$mod generate-public-headers] + } + return $result + } + + method generate-stub-function {} { + debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] + my variable code cfunct tcltype + set result {} + foreach mod [my link list product] { + foreach {funct def} [$mod generate-stub-function] { + dict set result $funct $def + } + } + if {[info exists cfunct]} { + foreach {funcname info} $cfunct { + if {![dict get $info export]} continue + dict set result $funcname [dict get $info header] + } + } + return $result + } + + method generate-public-function {} { + debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] + my variable code cfunct tcltype + set result {} + + if {[my define get initfunc] ne {}} { + ::practcl::cputs result "int [my define get initfunc](Tcl_Interp *interp);" + } + if {[info exists cfunct]} { + foreach {funcname info} $cfunct { + if {![dict get $info public]} continue + ::practcl::cputs result "[dict get $info header]\;" + } + } + set result [::practcl::_tagblock $result c [my define get filename]] + foreach mod [my link list product] { + ::practcl::cputs result [$mod generate-public-function] + } + return $result + } + + method generate-public-includes {} { + debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] + set includes {} + foreach item [my define get public-include] { + if {$item ni $includes} { + lappend includes $item + } + } + foreach mod [my link list product] { + foreach item [$mod generate-public-includes] { + if {$item ni $includes} { + lappend includes $item + } + } + } + return $includes + } + method generate-public-verbatim {} { + debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] + set includes {} + foreach item [my define get public-verbatim] { + if {$item ni $includes} { + lappend includes $item + } + } + foreach mod [my link list subordinate] { + foreach item [$mod generate-public-verbatim] { + if {$item ni $includes} { + lappend includes $item + } + } + } + return $includes + } + ### + # This methods generates the contents of an amalgamated .h file + # which describes the public API of this module + ### + method generate-h {} { + debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] + set result {} + set includes [my generate-public-includes] + foreach inc $includes { + if {[string index $inc 0] ni {< \"}} { + ::practcl::cputs result "#include \"$inc\"" + } else { + ::practcl::cputs result "#include $inc" + } + } + foreach file [my generate-public-verbatim] { + ::practcl::cputs result "/* BEGIN $file */" + ::practcl::cputs result [::practcl::cat $file] + ::practcl::cputs result "/* END $file */" + } + foreach method { + generate-public-define + generate-public-macro + generate-public-typedef + generate-public-structure + generate-public-headers + generate-public-function + } { + ::practcl::cputs result "/* BEGIN SECTION $method */" + ::practcl::cputs result [my $method] + ::practcl::cputs result "/* END SECTION $method */" + } + return $result + } + + ### + # This methods generates the contents of an amalgamated .c file + # which implements the loader for a batch of tools + ### + method generate-c {} { + debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] + set result { +/* This file was generated by practcl */ + } + set includes {} + lappend headers + if {[my define get tk 0]} { + lappend headers + } + lappend headers {*}[my define get include] + if {[my define get output_h] ne {}} { + lappend headers "\"[my define get output_h]\"" + } + foreach mod [my link list product] { + # Signal modules to formulate final implementation + $mod go + } + foreach mod [my link list dynamic] { + foreach inc [$mod define get include] { + if {$inc ni $headers} { + lappend headers $inc + } + } + } + foreach inc $headers { + if {[string index $inc 0] ni {< \"}} { + ::practcl::cputs result "#include \"$inc\"" + } else { + ::practcl::cputs result "#include $inc" + } + } + foreach {method} { + generate-cheader + generate-cstruct + generate-constant + generate-cfunct + generate-cmethod + } { + ::practcl::cputs result "/* BEGIN $method [my define get filename] */" + ::practcl::cputs result [my $method] + ::practcl::cputs result "/* END $method [my define get filename] */" + } + debug [list /[self] [self method] [self class] -- [my define get filename] [info object class [self]]] + return $result + } + + + method generate-loader {} { + debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] + set result {} + if {[my define get initfunc] eq {}} return + ::practcl::cputs result " +extern int DLLEXPORT [my define get initfunc]( Tcl_Interp *interp ) \{" + ::practcl::cputs result { + /* Initialise the stubs tables. */ + #ifdef USE_TCL_STUBS + if (Tcl_InitStubs(interp, "8.6", 0)==NULL) return TCL_ERROR; + if (TclOOInitializeStubs(interp, "1.0") == NULL) return TCL_ERROR; +} + if {[my define get tk 0]} { + ::practcl::cputs result { if (Tk_InitStubs(interp, "8.6", 0)==NULL) return TCL_ERROR;} + } + ::practcl::cputs result { #endif} + set TCLINIT [my generate-tcl] + ::practcl::cputs result " if(Tcl_Eval(interp,[::practcl::tcl_to_c $TCLINIT])) return TCL_ERROR ;" + foreach item [my link list product] { + if {[$item define get output_c] ne {}} { + ::practcl::cputs result [$item generate-cinit-external] + } else { + ::practcl::cputs result [$item generate-cinit] + } + } + if {[my define exists pkg_name]} { + ::practcl::cputs result " if (Tcl_PkgProvide(interp, \"[my define get pkg_name [my define get name]]\" , \"[my define get pkg_vers [my define get version]]\" )) return TCL_ERROR\;" + } + ::practcl::cputs result " return TCL_OK\;\n\}\n" + return $result + } + + ### + # This methods generates any Tcl script file + # which is required to pre-initialize the C library + ### + method generate-tcl {} { + debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] + set result {} + my variable code + if {[info exists code(tcl)]} { + ::practcl::cputs result $code(tcl) + } + set result [::practcl::_tagblock $result tcl [my define get filename]] + foreach mod [my link list product] { + ::practcl::cputs result [$mod generate-tcl] + } + return $result + } + + method static-packages {} { + set result [my define get static_packages] + set statpkg [my define get static_pkg] + set initfunc [my define get initfunc] + if {$initfunc ne {}} { + set pkg_name [my define get pkg_name] + if {$pkg_name ne {}} { + dict set result $pkg_name initfunc $initfunc + dict set result $pkg_name version [my define get version [my define get pkg_vers]] + dict set result $pkg_name autoload [my define get autoload 0] + } + } + foreach item [my link list subordinate] { + foreach {pkg info} [$item static-packages] { + dict set result $pkg $info + } + } + return $result + } + + method target {method args} { + switch $method { + is_unix { return [expr {$::tcl_platform(platform) eq "unix"}] } + } + } + +} + +::oo::class create ::practcl::product { + superclass ::practcl::object + + method linktype {} { + return {subordinate product} + } + + method include header { + my define add include $header + } + + method cstructure {name definition {argdat {}}} { + my variable cstruct + dict set cstruct $name body $definition + foreach {f v} $argdat { + dict set cstruct $name $f $v + } + } + + method generate-cinit {} { + debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] + my variable code + set result {} + if {[info exists code(cinit)]} { + ::practcl::cputs result $code(cinit) + } + if {[my define get initfunc] ne {}} { + ::practcl::cputs result " if([my define get initfunc](interp)!=TCL_OK) return TCL_ERROR\;" + } + set result [::practcl::_tagblock $result c [my define get filename]] + foreach obj [my link list product] { + ::practcl::cputs result [$obj generate-cinit] + } + return $result + } +} + +### +# Dynamic blocks do not generate their own .c files, +# instead the contribute to the amalgamation +# of the main library file +### +::oo::class create ::practcl::dynamic { + superclass ::practcl::product + + # Retrieve any additional source files required + + method compile-products {} { + set filename [my define get output_c] + set result {} + if {$filename ne {}} { + if {[my define exists ofile]} { + set ofile [my define get ofile] + } else { + set ofile [my Ofile $filename] + my define set ofile $ofile + } + lappend result $ofile [list cfile $filename extra [my define get extra] external [string is true -strict [my define get external]]] + } else { + set filename [my define get cfile] + if {$filename ne {}} { + if {[my define exists ofile]} { + set ofile [my define get ofile] + } else { + set ofile [my Ofile $filename] + my define set ofile $ofile + } + lappend result $ofile [list cfile $filename extra [my define get extra] external [string is true -strict [my define get external]]] + } + } + foreach item [my link list subordinate] { + lappend result {*}[$item compile-products] + } + return $result + } + + method implement path { + my go + my Collate_Source $path + if {[my define get output_c] eq {}} return + set filename [file join $path [my define get output_c]] + my define set cfile $filename + set fout [open $filename w] + puts $fout [my generate-c] + puts $fout "extern int DLLEXPORT [my define get initfunc]( Tcl_Interp *interp ) \x7B" + puts $fout [my generate-cinit] + if {[my define get pkg_name] ne {}} { + puts $fout " Tcl_PkgProvide(interp, \"[my define get pkg_name]\", \"[my define get pkg_vers]\");" + } + puts $fout " return TCL_OK\;" + puts $fout "\x7D" + close $fout + } + + method initialize {} { + set filename [my define get filename] + if {$filename eq {}} { + return + } + if {[my define get name] eq {}} { + my define set name [file tail [file rootname $filename]] + } + if {[my define get localpath] eq {}} { + my define set localpath [my define get localpath]_[my define get name] + } + ::source $filename + } + + method linktype {} { + return {subordinate product dynamic} + } + + ### + # Populate const static data structures + ### + method generate-cstruct {} { + debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] + my variable code cstruct methods tcltype + set result {} + if {[info exists code(struct)]} { + ::practcl::cputs result $code(struct) + } + foreach obj [my link list dynamic] { + # Exclude products that will generate their own C files + if {[$obj define get output_c] ne {}} continue + ::practcl::cputs result [$obj generate-cstruct] + } + return $result + } + + method generate-constant {} { + debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] + set result {} + my variable code cstruct methods tcltype + if {[info exists code(constant)]} { + ::practcl::cputs result "/* [my define get filename] CONSTANT */" + ::practcl::cputs result $code(constant) + } + if {[info exists cstruct]} { + foreach {name info} $cstruct { + set map {} + lappend map @NAME@ $name + lappend map @MACRO@ GET[string toupper $name] + + if {[dict exists $info deleteproc]} { + lappend map @DELETEPROC@ [dict get $info deleteproc] + } else { + lappend map @DELETEPROC@ NULL + } + if {[dict exists $info cloneproc]} { + lappend map @CLONEPROC@ [dict get $info cloneproc] + } else { + lappend map @CLONEPROC@ NULL + } + ::practcl::cputs result [string map $map { +const static Tcl_ObjectMetadataType @NAME@DataType = { + TCL_OO_METADATA_VERSION_CURRENT, + "@NAME@", + @DELETEPROC@, + @CLONEPROC@ +}; +#define @MACRO@(OBJCONTEXT) (@NAME@ *) Tcl_ObjectGetMetadata(OBJCONTEXT,&@NAME@DataType) +}] + } + } + if {[info exists tcltype]} { + foreach {type info} $tcltype { + dict with info {} + ::practcl::cputs result "const Tcl_ObjType $cname = \{\n .freeIntRepProc = &${freeproc},\n .dupIntRepProc = &${dupproc},\n .updateStringProc = &${updatestringproc},\n .setFromAnyProc = &${setfromanyproc}\n\}\;" + } + } + + if {[info exists methods]} { + set mtypes {} + foreach {name info} $methods { + set callproc [dict get $info callproc] + set methodtype [dict get $info methodtype] + if {$methodtype in $mtypes} continue + lappend mtypes $methodtype + ### + # Build the data struct for this method + ### + ::practcl::cputs result "const static Tcl_MethodType $methodtype = \{" + ::practcl::cputs result " .version = TCL_OO_METADATA_VERSION_CURRENT,\n .name = \"$name\",\n .callProc = $callproc," + if {[dict exists $info deleteproc]} { + set deleteproc [dict get $info deleteproc] + } else { + set deleteproc NULL + } + if {$deleteproc ni { {} NULL }} { + ::practcl::cputs result " .deleteProc = $deleteproc," + } else { + ::practcl::cputs result " .deleteProc = NULL," + } + if {[dict exists $info cloneproc]} { + set cloneproc [dict get $info cloneproc] + } else { + set cloneproc NULL + } + if {$cloneproc ni { {} NULL }} { + ::practcl::cputs result " .cloneProc = $cloneproc\n\}\;" + } else { + ::practcl::cputs result " .cloneProc = NULL\n\}\;" + } + dict set methods $name methodtype $methodtype + } + } + foreach obj [my link list dynamic] { + # Exclude products that will generate their own C files + if {[$obj define get output_c] ne {}} continue + ::practcl::cputs result [$obj generate-constant] + } + return $result + } + + ### + # Generate code that provides subroutines called by + # Tcl API methods + ### + method generate-cfunct {} { + debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] + my variable code cfunct + set result {} + if {[info exists code(funct)]} { + ::practcl::cputs result $code(funct) + } + if {[info exists cfunct]} { + foreach {funcname info} $cfunct { + ::practcl::cputs result "[dict get $info header]\{[dict get $info body]\}\;" + } + } + foreach obj [my link list dynamic] { + # Exclude products that will generate their own C files + if {[$obj define get output_c] ne {}} { + continue + } + ::practcl::cputs result [$obj generate-cfunct] + } + return $result + } + + ### + # Generate code that provides implements Tcl API + # calls + ### + method generate-cmethod {} { + debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] + my variable code methods tclprocs + set result {} + if {[info exists code(method)]} { + ::practcl::cputs result $code(method) + } + + if {[info exists tclprocs]} { + foreach {name info} $tclprocs { + if {![dict exists $info body]} continue + set callproc [dict get $info callproc] + set header [dict get $info header] + set body [dict get $info body] + ::practcl::cputs result "${header} \{${body}\}" + } + } + + + if {[info exists methods]} { + set thisclass [my define get cclass] + foreach {name info} $methods { + if {![dict exists $info body]} continue + set callproc [dict get $info callproc] + set header [dict get $info header] + set body [dict get $info body] + ::practcl::cputs result "${header} \{${body}\}" + } + # Build the OO_Init function + ::practcl::cputs result "static int ${thisclass}_OO_Init(Tcl_Interp *interp) \{" + ::practcl::cputs result [string map [list @CCLASS@ $thisclass @TCLCLASS@ [my define get class]] { + /* + ** Build the "@TCLCLASS@" class + */ + Tcl_Obj* nameObj; /* Name of a class or method being looked up */ + Tcl_Object curClassObject; /* Tcl_Object representing the current class */ + Tcl_Class curClass; /* Tcl_Class representing the current class */ + + /* + * Find the "@TCLCLASS@" class, and attach an 'init' method to it. + */ + + nameObj = Tcl_NewStringObj("@TCLCLASS@", -1); + Tcl_IncrRefCount(nameObj); + if ((curClassObject = Tcl_GetObjectFromObj(interp, nameObj)) == NULL) { + Tcl_DecrRefCount(nameObj); + return TCL_ERROR; + } + Tcl_DecrRefCount(nameObj); + curClass = Tcl_GetObjectAsClass(curClassObject); +}] + if {[dict exists $methods constructor]} { + set mtype [dict get $methods constructor methodtype] + ::practcl::cputs result [string map [list @MTYPE@ $mtype] { + /* Attach the constructor to the class */ + Tcl_ClassSetConstructor(interp, curClass, Tcl_NewMethod(interp, curClass, NULL, 1, &@MTYPE@, NULL)); + }] + } + foreach {name info} $methods { + dict with info {} + if {$name in {constructor destructor}} continue + ::practcl::cputs result [string map [list @NAME@ $name @MTYPE@ $methodtype] { + nameObj=Tcl_NewStringObj("@NAME@",-1); + Tcl_NewMethod(interp, curClass, nameObj, 1, &@MTYPE@, (ClientData) NULL); + Tcl_DecrRefCount(nameObj); +}] + if {[dict exists $info aliases]} { + foreach alias [dict get $info aliases] { + if {[dict exists $methods $alias]} continue + ::practcl::cputs result [string map [list @NAME@ $alias @MTYPE@ $methodtype] { + nameObj=Tcl_NewStringObj("@NAME@",-1); + Tcl_NewMethod(interp, curClass, nameObj, 1, &@MTYPE@, (ClientData) NULL); + Tcl_DecrRefCount(nameObj); +}] + } + } + } + ::practcl::cputs result " return TCL_OK\;\n\}\n" + } + foreach obj [my link list dynamic] { + # Exclude products that will generate their own C files + if {[$obj define get output_c] ne {}} continue + ::practcl::cputs result [$obj generate-cmethod] + } + return $result + } + + method generate-cinit-external {} { + if {[my define get initfunc] eq {}} { + return "/* [my define get filename] declared not initfunc */" + } + return " if([my define get initfunc](interp)) return TCL_ERROR\;" + } + + ### + # Generate code that runs when the package/module is + # initialized into the interpreter + ### + method generate-cinit {} { + debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] + set result {} + my variable code methods tclprocs + if {[info exists code(nspace)]} { + ::practcl::cputs result " \{\n Tcl_Namespace *modPtr;" + foreach nspace $code(nspace) { + ::practcl::cputs result [string map [list @NSPACE@ $nspace] { + modPtr=Tcl_FindNamespace(interp,"@NSPACE@",NULL,TCL_NAMESPACE_ONLY); + if(!modPtr) { + modPtr = Tcl_CreateNamespace(interp, "@NSPACE@", NULL, NULL); + } +}] + } + ::practcl::cputs result " \}" + } + if {[info exists code(tclinit)]} { + ::practcl::cputs result $code(tclinit) + } + if {[info exists code(cinit)]} { + ::practcl::cputs result $code(cinit) + } + if {[info exists code(initfuncts)]} { + foreach func $code(initfuncts) { + ::practcl::cputs result " if (${func}(interp) != TCL_OK) return TCL_ERROR\;" + } + } + if {[info exists tclprocs]} { + foreach {name info} $tclprocs { + set map [list @NAME@ $name @CALLPROC@ [dict get $info callproc]] + ::practcl::cputs result [string map $map { Tcl_CreateObjCommand(interp,"@NAME@",(Tcl_ObjCmdProc *)@CALLPROC@,NULL,NULL);}] + if {[dict exists $info aliases]} { + foreach alias [dict get $info aliases] { + set map [list @NAME@ $alias @CALLPROC@ [dict get $info callproc]] + ::practcl::cputs result [string map $map { Tcl_CreateObjCommand(interp,"@NAME@",(Tcl_ObjCmdProc *)@CALLPROC@,NULL,NULL);}] + } + } + } + } + + if {[info exists code(nspace)]} { + ::practcl::cputs result " \{\n Tcl_Namespace *modPtr;" + foreach nspace $code(nspace) { + ::practcl::cputs result [string map [list @NSPACE@ $nspace] { + modPtr=Tcl_FindNamespace(interp,"@NSPACE@",NULL,TCL_NAMESPACE_ONLY); + Tcl_CreateEnsemble(interp, modPtr->fullName, modPtr, TCL_ENSEMBLE_PREFIX); + Tcl_Export(interp, modPtr, "[a-z]*", 1); +}] + } + ::practcl::cputs result " \}" + } + set result [::practcl::_tagblock $result c [my define get filename]] + foreach obj [my link list product] { + # Exclude products that will generate their own C files + if {[$obj define get output_c] ne {}} { + ::practcl::cputs result [$obj generate-cinit-external] + } else { + ::practcl::cputs result [$obj generate-cinit] + } + } + return $result + } + + method c_header body { + my variable code + ::practcl::cputs code(header) $body + } + + method c_code body { + my variable code + ::practcl::cputs code(funct) $body + } + method c_function {header body} { + my variable code cfunct + foreach regexp { + {(.*) ([a-zA-Z_][a-zA-Z0-9_]*) *\((.*)\)} + {(.*) (\x2a[a-zA-Z_][a-zA-Z0-9_]*) *\((.*)\)} + } { + if {[regexp $regexp $header all keywords funcname arglist]} { + dict set cfunct $funcname header $header + dict set cfunct $funcname body $body + dict set cfunct $funcname keywords $keywords + dict set cfunct $funcname arglist $arglist + dict set cfunct $funcname public [expr {"static" ni $keywords}] + dict set cfunct $funcname export [expr {"STUB_EXPORT" in $keywords}] + + return + } + } + ::practcl::cputs code(header) "$header\;" + # Could not parse that block as a function + # append it verbatim to our c_implementation + ::practcl::cputs code(funct) "$header [list $body]" + } + + + method cmethod {name body {arginfo {}}} { + my variable methods code + foreach {f v} $arginfo { + dict set methods $name $f $v + } + dict set methods $name body "Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */ +$body" + } + + method c_tclproc_nspace nspace { + my variable code + if {![info exists code(nspace)]} { + set code(nspace) {} + } + if {$nspace ni $code(nspace)} { + lappend code(nspace) $nspace + } + } + + method c_tclproc_raw {name body {arginfo {}}} { + my variable tclprocs code + + foreach {f v} $arginfo { + dict set tclprocs $name $f $v + } + dict set tclprocs $name body $body + } + + method go {} { + debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] + next + my variable methods code cstruct tclprocs + if {[info exists methods]} { + debug [self] methods [my define get cclass] + set thisclass [my define get cclass] + foreach {name info} $methods { + # Provide a callproc + if {![dict exists $info callproc]} { + set callproc [string map {____ _ ___ _ __ _} [string map {{ } _ : _} OOMethod_${thisclass}_${name}]] + dict set methods $name callproc $callproc + } else { + set callproc [dict get $info callproc] + } + if {[dict exists $info body] && ![dict exists $info header]} { + dict set methods $name header "static int ${callproc}(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv)" + } + if {![dict exists $info methodtype]} { + set methodtype [string map {{ } _ : _} MethodType_${thisclass}_${name}] + dict set methods $name methodtype $methodtype + } + } + if {![info exists code(initfuncts)] || "${thisclass}_OO_Init" ni $code(initfuncts)} { + lappend code(initfuncts) "${thisclass}_OO_Init" + } + } + set thisnspace [my define get nspace] + + if {[info exists tclprocs]} { + debug [self] tclprocs [dict keys $tclprocs] + foreach {name info} $tclprocs { + if {![dict exists $info callproc]} { + set callproc [string map {____ _ ___ _ __ _} [string map {{ } _ : _} Tclcmd_${thisnspace}_${name}]] + dict set tclprocs $name callproc $callproc + } else { + set callproc [dict get $info callproc] + } + if {[dict exists $info body] && ![dict exists $info header]} { + dict set tclprocs $name header "static int ${callproc}(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv\[\])" + } + } + } + debug [list /[self] [self method] [self class]] + } + + # Once an object marks itself as some + # flavor of dynamic, stop trying to morph + # it into something else + method select {} {} + + + method tcltype {name argdat} { + my variable tcltype + foreach {f v} $argdat { + dict set tcltype $name $f $v + } + if {![dict exists tcltype $name cname]} { + dict set tcltype $name cname [string tolower $name]_tclobjtype + } + lappend map @NAME@ $name + set info [dict get $tcltype $name] + foreach {f v} $info { + lappend map @[string toupper $f]@ $v + } + foreach {func fpat template} { + freeproc {@Name@Obj_freeIntRepProc} {void @FNAME@(Tcl_Obj *objPtr)} + dupproc {@Name@Obj_dupIntRepProc} {void @FNAME@(Tcl_Obj *srcPtr,Tcl_Obj *dupPtr)} + updatestringproc {@Name@Obj_updateStringRepProc} {void @FNAME@(Tcl_Obj *objPtr)} + setfromanyproc {@Name@Obj_setFromAnyProc} {int @FNAME@(Tcl_Interp *interp,Tcl_Obj *objPtr)} + } { + if {![dict exists $info $func]} { + error "$name does not define $func" + } + set body [dict get $info $func] + # We were given a function name to call + if {[llength $body] eq 1} continue + set fname [string map [list @Name@ [string totitle $name]] $fpat] + my c_function [string map [list @FNAME@ $fname] $template] [string map $map $body] + dict set tcltype $name $func $fname + } + } +} + +::oo::class create ::practcl::cheader { + superclass ::practcl::product + + method compile-products {} {} + method generate-cinit {} {} +} + +::oo::class create ::practcl::csource { + superclass ::practcl::product +} + +::oo::class create ::practcl::clibrary { + superclass ::practcl::product + + method linker-products {configdict} { + return [my define get filename] + } + +} + +### +# In the end, all C code must be loaded into a module +# This will either be a dynamically loaded library implementing +# a tcl extension, or a compiled in segment of a custom shell/app +### +::oo::class create ::practcl::module { + superclass ::practcl::dynamic + + method child which { + switch $which { + organs { + return [list project [my define get project] module [self]] + } + } + } + + method initialize {} { + set filename [my define get filename] + if {$filename eq {}} { + return + } + if {[my define get name] eq {}} { + my define set name [file tail [file dirname $filename]] + } + if {[my define get localpath] eq {}} { + my define set localpath [my define get name]_[my define get name] + } + debug [self] SOURCE $filename + my source $filename + } + + method implement path { + my go + my Collate_Source $path + foreach item [my link list dynamic] { + if {[catch {$item implement $path} err]} { + puts "Skipped $item: $err" + } + } + foreach item [my link list module] { + if {[catch {$item implement $path} err]} { + puts "Skipped $item: $err" + } + } + debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] + set filename [my define get output_c] + if {$filename eq {}} { + debug [list /[self] [self method] [self class]] + return + } + set cout [open [file join $path [file rootname $filename].c] w] + puts $cout [subst {/* +** This file is generated by the [info script] script +** any changes will be overwritten the next time it is run +*/}] + puts $cout [my generate-c] + puts $cout [my generate-loader] + close $cout + debug [list /[self] [self method] [self class]] + } + + method linktype {} { + return {subordinate product dynamic module} + } +} + +::oo::class create ::practcl::autoconf { + + ### + # find or fake a key/value list describing this project + ### + method config.sh {} { + my variable conf_result + if {[info exists conf_result]} { + return $conf_result + } + set result {} + set name [my define get name] + set PWD $::CWD + set builddir [my define get builddir] + my unpack + set srcroot [my define get srcroot] + if {![file exists $builddir]} { + my Configure + } + set filename [file join $builddir config.tcl] + # Project uses the practcl template. Use the leavings from autoconf + if {[file exists $filename]} { + set dat [::practcl::config.tcl $builddir] + foreach {item value} [lsort -stride 2 -dictionary $dat] { + dict set result $item $value + } + set conf_result $result + return $result + } + set filename [file join $builddir ${name}Config.sh] + if {[file exists $filename]} { + set l [expr {[string length $name]+1}] + foreach {field dat} [::practcl::read_Config.sh $filename] { + set field [string tolower $field] + if {[string match ${name}_* $field]} { + set field [string range $field $l end] + } + dict set result $field $dat + } + set conf_result $result + return $result + } + ### + # Oh man... we have to guess + ### + set filename [file join $builddir Makefile] + if {![file exists $filename]} { + error "Could not locate any configuration data in $srcroot" + } + foreach {field dat} [::practcl::read_Makefile $filename] { + dict set result $field $dat + } + set conf_result $result + cd $PWD + return $result + } +} + + +::oo::class create ::practcl::project { + superclass ::practcl::module ::practcl::autoconf + + constructor args { + my variable define + if {[llength $args] == 1} { + if {[catch {uplevel 1 [list subst [lindex $args 0]]} contents]} { + set contents [lindex $args 0] + } + } else { + if {[catch {uplevel 1 [list subst $args]} contents]} { + set contents $args + } + } + array set define $contents + my select + my initialize + } + + + method add_project {pkg info {oodefine {}}} { + set os [my define get os] + if {$os eq {}} { + set os [::practcl::os] + my define set os $os + } + set fossilinfo [list download [my define get download] tag trunk sandbox [my define get sandbox]] + if {[dict exists $info os] && ($os ni [dict get $info os])} return + # Select which tag to use here. + # For production builds: tag-release + if {[::info exists ::env(FOSSIL_MIRROR)]} { + dict set info localmirror $::env(FOSSIL_MIRROR) + } + set profile [my define get profile release]: + if {[dict exists $info profile $profile]} { + dict set info tag [dict get $info profile $profile] + } + set obj [namespace current]::PROJECT.$pkg + if {[info command $obj] eq {}} { + set obj [::practcl::subproject create $obj [self] [dict merge $fossilinfo [list name $pkg pkg_name $pkg static 0] $info]] + } + my link object $obj + oo::objdefine $obj $oodefine + $obj define set masterpath $::CWD + $obj go + return $obj + } + + method child which { + switch $which { + organs { + # A library can be a project, it can be a module. Any + # subordinate modules will indicate their existance + return [list project [self] module [self]] + } + } + } + + method linktype {} { + return project + } + + # Exercise the methods of a sub-object + method project {pkg args} { + set obj [namespace current]::PROJECT.$pkg + if {[llength $args]==0} { + return $obj + } + tailcall ${obj} {*}$args + } +} + +::oo::class create ::practcl::library { + superclass ::practcl::project + + method compile-products {} { + set result {} + foreach item [my link list subordinate] { + lappend result {*}[$item compile-products] + } + set filename [my define get output_c] + if {$filename ne {}} { + set ofile [file rootname [file tail $filename]]_main.o + lappend result $ofile [list cfile $filename extra [my define get extra] external [string is true -strict [my define get external]]] + } + return $result + } + + method generate-tcl-loader {} { + set result {} + set PKGINIT [my define get pkginit] + set PKG_NAME [my define get name [my define get pkg_name]] + set PKG_VERSION [my define get pkg_vers [my define get version]] + if {[string is true [my define get SHARED_BUILD 0]]} { + set LIBFILE [my define get libfile] + ::practcl::cputs result [string map \ + [list @LIBFILE@ $LIBFILE @PKGINIT@ $PKGINIT @PKG_NAME@ $PKG_NAME @PKG_VERSION@ $PKG_VERSION] { +# Shared Library Style +load [file join [file dirname [file join [pwd] [info script]]] @LIBFILE@] @PKGINIT@ +package provide @PKG_NAME@ @PKG_VERSION@ +}] + } else { + ::practcl::cputs result [string map \ + [list @PKGINIT@ $PKGINIT @PKG_NAME@ $PKG_NAME @PKG_VERSION@ $PKG_VERSION] { +# Tclkit Style +load {} @PKGINIT@ +package provide @PKG_NAME@ @PKG_VERSION@ +}] + } + return $result + } + + method go {} { + debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] + set name [my define getnull name] + if {$name eq {}} { + set name generic + my define name generic + } + if {[my define get tk] eq {@TEA_TK_EXTENSION@}} { + my define set tk 0 + } + set output_c [my define getnull output_c] + if {$output_c eq {}} { + set output_c [file rootname $name].c + my define set output_c $output_c + } + set output_h [my define getnull output_h] + if {$output_h eq {}} { + set output_h [file rootname $output_c].h + my define set output_h $output_h + } + set output_tcl [my define getnull output_tcl] + #if {$output_tcl eq {}} { + # set output_tcl [file rootname $output_c].tcl + # my define set output_tcl $output_tcl + #} + #set output_mk [my define getnull output_mk] + #if {$output_mk eq {}} { + # set output_mk [file rootname $output_c].mk + # my define set output_mk $output_mk + #} + set initfunc [my define getnull initfunc] + if {$initfunc eq {}} { + set initfunc [string totitle $name]_Init + my define set initfunc $initfunc + } + set output_decls [my define getnull output_decls] + if {$output_decls eq {}} { + set output_decls [file rootname $output_c].decls + my define set output_decls $output_decls + } + my variable links + foreach {linktype objs} [array get links] { + foreach obj $objs { + $obj go + } + } + debug [list /[self] [self method] [self class] -- [my define get filename] [info object class [self]]] + } + + method implement path { + my go + my Collate_Source $path + foreach item [my link list dynamic] { + if {[catch {$item implement $path} err]} { + puts "Skipped $item: $err" + } + } + foreach item [my link list module] { + if {[catch {$item implement $path} err]} { + puts "Skipped $item: $err" + } + } + set cout [open [file join $path [my define get output_c]] w] + puts $cout [subst {/* +** This file is generated by the [info script] script +** any changes will be overwritten the next time it is run +*/}] + puts $cout [my generate-c] + puts $cout [my generate-loader] + close $cout + + set macro HAVE_[string toupper [file rootname [my define get output_h]]]_H + set hout [open [file join $path [my define get output_h]] w] + puts $hout [subst {/* +** This file is generated by the [info script] script +** any changes will be overwritten the next time it is run +*/}] + puts $hout "#ifndef ${macro}" + puts $hout "#define ${macro}" + puts $hout [my generate-h] + puts $hout "#endif" + close $hout + + set output_tcl [my define get output_tcl] + if {$output_tcl ne {}} { + set tclout [open [file join $path [my define get output_tcl]] w] + puts $tclout "### +# This file is generated by the [info script] script +# any changes will be overwritten the next time it is run +###" + puts $tclout [my generate-tcl] + puts $tclout [my generate-tcl-loader] + close $tclout + } + } + + method generate-decls {pkgname path} { + debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] + set outfile [file join $path/$pkgname.decls] + + ### + # Build the decls file + ### + set fout [open $outfile w] + puts $fout [subst {### + # $outfile + # + # This file was generated by [info script] + ### + + library $pkgname + interface $pkgname + }] + + ### + # Generate list of functions + ### + set stubfuncts [my generate-stub-function] + set thisline {} + set functcount 0 + foreach {func header} $stubfuncts { + puts $fout [list declare [incr functcount] $header] + } + puts $fout [list export "int [my define get initfunc](Tcl_Inter *interp)"] + puts $fout [list export "char *[string totitle [my define get name]]_InitStubs(Tcl_Inter *interp, char *version, int exact)"] + + close $fout + + ### + # Build [package]Decls.h + ### + set hout [open [file join $path ${pkgname}Decls.h] w] + + close $hout + + set cout [open [file join $path ${pkgname}StubInit.c] w] +puts $cout [string map [list %pkgname% $pkgname %PkgName% [string totitle $pkgname]] { +#ifndef USE_TCL_STUBS +#define USE_TCL_STUBS +#endif +#undef USE_TCL_STUB_PROCS + +#include "tcl.h" +#include "%pkgname%.h" + + /* + ** Ensure that Tdom_InitStubs is built as an exported symbol. The other stub + ** functions should be built as non-exported symbols. + */ + +#undef TCL_STORAGE_CLASS +#define TCL_STORAGE_CLASS DLLEXPORT + +%PkgName%Stubs *%pkgname%StubsPtr; + + /* + **---------------------------------------------------------------------- + ** + ** %PkgName%_InitStubs -- + ** + ** Checks that the correct version of %PkgName% is loaded and that it + ** supports stubs. It then initialises the stub table pointers. + ** + ** Results: + ** The actual version of %PkgName% that satisfies the request, or + ** NULL to indicate that an error occurred. + ** + ** Side effects: + ** Sets the stub table pointers. + ** + **---------------------------------------------------------------------- + */ + +char * +%PkgName%_InitStubs (Tcl_Interp *interp, char *version, int exact) +{ + char *actualVersion; + actualVersion = Tcl_PkgRequireEx(interp, "%pkgname%", version, exact,(ClientData *) &%pkgname%StubsPtr); + if (!actualVersion) { + return NULL; + } + if (!%pkgname%StubsPtr) { + Tcl_SetResult(interp,"This implementation of %PkgName% does not support stubs",TCL_STATIC); + return NULL; + } + return actualVersion; +} +}] + close $cout + } + + # Backward compadible call + method generate-make path { + ::practcl::build::Makefile $path [self] + } + + method install-headers {} { + set result {} + return $result + } + + method linktype {} { + return library + } + + # Create a "package ifneeded" + # Args are a list of aliases for which this package will answer to + method package-ifneeded {args} { + set result {} + set name [my define get pkg_name [my define get name]] + set version [my define get pkg_vers [my define get version]] + if {$version eq {}} { + set version 0.1a + } + set output_tcl [my define get output_tcl] + if {$output_tcl ne {}} { + set script "\[list source \[file join \$dir $output_tcl\]\]" + } elseif {[string is true -strict [my define get SHARED_BUILD]]} { + set script "\[list load \[file join \$dir [my define get libfile]\] $name\]" + } else { + # Provide a null passthrough + set script [list package provide $name $version] + } + set result "package ifneeded [list $name] [list $version] $script" + foreach alias $args { + set script "package require $name $version \; package provide $alias $version" + append result \n\n [list package ifneeded $alias $version $script] + } + return $result + } + + + method shared_library {} { + set name [string tolower [my define get name [my define get pkg_name]]] + set NAME [string toupper $name] + set version [my define get version [my define get pkg_vers]] + set map {} + lappend map %LIBRARY_NAME% $name + lappend map %LIBRARY_VERSION% $version + lappend map %LIBRARY_VERSION_NODOTS% [string map {. {}} $version] + lappend map %LIBRARY_PREFIX% [my define getnull libprefix] + set outfile [string map $map [my define get PRACTCL_NAME_LIBRARY]][my define get SHLIB_SUFFIX] + return $outfile + } +} + +::oo::class create ::practcl::tclkit { + superclass ::practcl::library + + method Collate_Source CWD { + my define set SHARED_BUILD 0 + set name [my define get name] + + if {![my define exists TCL_LOCAL_APPINIT]} { + my define set TCL_LOCAL_APPINIT Tclkit_AppInit + } + if {![my define exists TCL_LOCAL_MAIN_HOOK]} { + my define set TCL_LOCAL_MAIN_HOOK Tclkit_MainHook + } + + set PROJECT [self] + set os [$PROJECT define get os] + set TCLOBJ [$PROJECT project TCLCORE] + set TKOBJ [$PROJECT project TKCORE] + set ODIEOBJ [$PROJECT project odie] + + set TCLSRCDIR [$TCLOBJ define get srcroot] + set TKSRCDIR [$TKOBJ define get srcroot] + set PKG_OBJS {} + foreach item [$PROJECT link list package] { + if {[string is true [$item define get static]]} { + lappend PKG_OBJS $item + } + } + # Arrange to build an main.c that utilizes TCL_LOCAL_APPINIT and TCL_LOCAL_MAIN_HOOK + if {$os eq "windows"} { + set PLATFORM_SRC_DIR win + my add class csource filename [file join $TCLSRCDIR win tclWinReg.c] initfunc Registry_Init pkg_name registry pkg_vers 1.3.1 autoload 1 + my add class csource filename [file join $TCLSRCDIR win tclWinDde.c] initfunc Dde_Init pkg_name dde pkg_vers 1.4.0 autoload 1 + my add class csource ofile [my define get name]_appinit.o filename [file join $TCLSRCDIR win tclAppInit.c] extra [list -DTCL_LOCAL_MAIN_HOOK=[my define get TCL_LOCAL_MAIN_HOOK Tclkit_MainHook] -DTCL_LOCAL_APPINIT=[my define get TCL_LOCAL_APPINIT Tclkit_AppInit]] + } else { + set PLATFORM_SRC_DIR unix + my add class csource ofile [my define get name]_appinit.o filename [file join $TCLSRCDIR unix tclAppInit.c] extra [list -DTCL_LOCAL_MAIN_HOOK=[my define get TCL_LOCAL_MAIN_HOOK Tclkit_MainHook] -DTCL_LOCAL_APPINIT=[my define get TCL_LOCAL_APPINIT Tclkit_AppInit]] + } + ### + # Add local static Zlib implementation + ### + set cdir [file join $TCLSRCDIR compat zlib] + foreach file { + adler32.c compress.c crc32.c + deflate.c infback.c inffast.c + inflate.c inftrees.c trees.c + uncompr.c zutil.c + } { + my add [file join $cdir $file] + } + + ### + # Pre 8.7, Tcl doesn't include a Zipfs implementation + # in the core. Grab the one from odielib + ### + set zipfs [file join $TCLSRCDIR generic zvfs.c] + if {![file exists $zipfs]} { + # The Odie project maintains a mirror of the version + # released with the Tcl core + my add_project odie { + tag trunk + class subproject + vfsinstall 0 + } + my project odie unpack + set ODIESRCROOT [my project odie define get srcroot] + set cdir [file join $ODIESRCROOT compat zipfs] + my define add include_dir $cdir + set zipfs [file join $cdir zvfs.c] + } + + my add class csource filename $zipfs initfunc Tclzipfs_Init pkg_name zipfs pkg_vers 1.0 autoload 1 + + my define add include_dir [file join $TKSRCDIR generic] + my define add include_dir [file join $TKSRCDIR $PLATFORM_SRC_DIR] + my define add include_dir [file join $TKSRCDIR bitmaps] + my define add include_dir [file join $TKSRCDIR xlib] + my define add include_dir [file join $TCLSRCDIR generic] + my define add include_dir [file join $TCLSRCDIR $PLATFORM_SRC_DIR] + my define add include_dir [file join $TCLSRCDIR compat zlib] + # This file will implement TCL_LOCAL_APPINIT and TCL_LOCAL_MAIN_HOOK + ::practcl::build::tclkit_main $PROJECT $PKG_OBJS + } + + ## Wrap an executable + # + method wrap {PWD exename vfspath args} { + cd $PWD + if {![file exists $vfspath]} { + file mkdir $vfspath + } + foreach item [my link list core.library] { + set name [$item define get name] + set libsrcroot [$item define get srcroot] + if {[file exists [file join $libsrcroot library]]} { + ::practcl::copyDir [file join $libsrcroot library] [file join $vfspath boot $name] + } + } + if {[my define get installdir] ne {}} { + ::practcl::copyDir [file join [my define get installdir] [string trimleft [my define get prefix] /] lib] [file join $vfspath lib] + } + foreach arg $args { + ::practcl::copyDir $arg $vfspath + } + + set fout [open [file join $vfspath packages.tcl] w] + puts $fout { + set ::PKGIDXFILE [info script] + set dir [file dirname $::PKGIDXFILE] + } + #set BASEVFS [my define get BASEVFS] + set EXEEXT [my define get EXEEXT] + + set tclkit_bare [my define get tclkit_bare] + + set buffer [::practcl::pkgindex_path $vfspath] + puts $fout $buffer + puts $fout { + # Advertise statically linked packages + foreach {pkg script} [array get ::kitpkg] { + eval $script + } + } + close $fout + package require zipfile::mkzip + ::zipfile::mkzip::mkzip ${exename}${EXEEXT} -runtime $tclkit_bare -directory $vfspath + if { [my define get platform] ne "windows" } { + file attributes ${exename}${EXEEXT} -permissions a+x + } + } +} + +### +# Meta repository +# The default is an inert source code block +### +oo::class create ::practcl::subproject { + superclass ::practcl::object + + method compile {} {} + + method go {} { + set platform [my define get platform] + my define get USEMSVC [my define get USEMSVC] + set name [my define get name] + if {![my define exists srcroot]} { + my define set srcroot [file join [my define get sandbox] $name] + } + set srcroot [my define get srcroot] + my define set localsrcdir $srcroot + my define add include_dir [file join $srcroot generic] + my sources + } + + # Install project into the local build system + method install-local {} { + my unpack + } + + # Install project into the virtual file system + method install-vfs {} {} + + method linktype {} { + return {subordinate package} + } + + method linker-products {configdict} {} + + method linker-external {configdict} { + if {[dict exists $configdict PRACTCL_LIBS]} { + return [dict get $configdict PRACTCL_LIBS] + } + } + + method sources {} {} + + method unpack {} { + set name [my define get name] + puts [list $name [self] UNPACK] + my define set [::practcl::fossil_sandbox $name [my define dump]] + } + + method update {} { + set name [my define get name] + my define set [::practcl::fossil_sandbox $name [dict merge [my define dump] {update 1}]] + } +} + +### +# A project which the kit compiles and integrates +# the source for itself +### +oo::class create ::practcl::subproject.source { + superclass ::practcl::subproject ::practcl::library + + method linktype {} { + return {subordinate package source} + } + +} + +# a copy from the teapot +oo::class create ::practcl::subproject.teapot { + superclass ::practcl::subproject + + method install-local {} { + my install-vfs + } + + method install-vfs {} { + set pkg [my define get pkg_name [my define get name]] + set download [my define get download] + my unpack + set DEST [my define get installdir] + set prefix [string trimleft [my define get prefix] /] + # Get tcllib from our destination + set dir [file join $DEST $prefix lib tcllib] + source [file join $DEST $prefix lib tcllib pkgIndex.tcl] + package require zipfile::decode + ::zipfile::decode::unzipfile [file join $download $pkg.zip] [file join $DEST $prefix lib $pkg] + } +} + +oo::class create ::practcl::subproject.sak { + superclass ::practcl::subproject + + method install-local {} { + my install-vfs + } + + method install-vfs {} { + ### + # Handle teapot installs + ### + set pkg [my define get pkg_name [my define get name]] + my unpack + set DEST [my define get installdir] + set prefix [string trimleft [my define get prefix] /] + set srcroot [my define get srcroot] + ::dotclexec [file join $srcroot installer.tcl] \ + -pkg-path [file join $DEST $prefix lib $pkg] \ + -no-examples -no-html -no-nroff \ + -no-wait -no-gui -no-apps + } +} + +### +# A binary package +### +oo::class create ::practcl::subproject.binary { + superclass ::practcl::subproject ::practcl::autoconf + + + method compile-products {} {} + + method ConfigureOpts {} { + set opts {} + set builddir [my define get builddir] + if {[my define get broken_destroot 0]} { + set PREFIX [my define get prefix_broken_destdir] + } else { + set PREFIX [my define get prefix] + } + if {[my define get HOST] != [my define get TARGET]} { + lappend opts --host=[my define get TARGET] + } + if {[my define exists tclsrcdir]} { + set TCLSRCDIR [::practcl::file_relative [file normalize $builddir] [file normalize [file join $::CWD [my define get tclsrcdir]]]] + set TCLGENERIC [::practcl::file_relative [file normalize $builddir] [file normalize [file join $::CWD [my define get tclsrcdir] .. generic]]] + lappend opts --with-tcl=$TCLSRCDIR --with-tclinclude=$TCLGENERIC + } + if {[my define exists tksrcdir]} { + set TKSRCDIR [::practcl::file_relative [file normalize $builddir] [file normalize [file join $::CWD [my define get tksrcdir]]]] + set TKGENERIC [::practcl::file_relative [file normalize $builddir] [file normalize [file join $::CWD [my define get tksrcdir] .. generic]]] + lappend opts --with-tk=$TKSRCDIR --with-tkinclude=$TKGENERIC + } + lappend opts {*}[my define get config_opts] + lappend opts --prefix=$PREFIX + #--exec_prefix=$PREFIX + #if {$::tcl_platform(platform) eq "windows"} { + # lappend opts --disable-64bit + #} + if {[my define get static 1]} { + lappend opts --disable-shared --disable-stubs + # + } else { + lappend opts --enable-shared + } + return $opts + } + + method go {} { + next + my define set builddir [my BuildDir [my define get masterpath]] + } + + method linker-products {configdict} { + if {![my define get static 0]} { + return {} + } + set srcdir [my define get builddir] + if {[dict exists $configdict libfile]} { + return " [file join $srcdir [dict get $configdict libfile]]" + } + } + + method static-packages {} { + if {![my define get static 0]} { + return {} + } + set result [my define get static_packages] + set statpkg [my define get static_pkg] + set initfunc [my define get initfunc] + if {$initfunc ne {}} { + set pkg_name [my define get pkg_name] + if {$pkg_name ne {}} { + dict set result $pkg_name initfunc $initfunc + set version [my define get version] + if {$version eq {}} { + set info [my config.sh] + set version [dict get $info version] + set pl {} + if {[dict exists $info patch_level]} { + set pl [dict get $info patch_level] + append version $pl + } + my define set version $version + } + dict set result $pkg_name version $version + dict set result $pkg_name autoload [my define get autoload 0] + } + } + foreach item [my link list subordinate] { + foreach {pkg info} [$item static-packages] { + dict set result $pkg $info + } + } + return $result + } + + method BuildDir {PWD} { + set name [my define get name] + return [my define get builddir [file join $PWD pkg.$name]] + } + + method compile {} { + set name [my define get name] + set PWD $::CWD + cd $PWD + my go + set srcroot [file normalize [my define get srcroot]] + my Collate_Source $PWD + + ### + # Build a starter VFS for both Tcl and wish + ### + set srcroot [my define get srcroot] + if {[my define get static 1]} { + puts "BUILDING Static $name $srcroot" + } else { + puts "BUILDING Dynamic $name $srcroot" + } + if {[my define get USEMSVC 0]} { + cd $srcroot + doexec nmake -f makefile.vc INSTALLDIR=[my define get installdir] release + } else { + cd $::CWD + set builddir [file normalize [my define get builddir]] + file mkdir $builddir + if {![file exists [file join $builddir Makefile]]} { + my Configure + } + if {[file exists [file join $builddir make.tcl]]} { + domake.tcl $builddir library + } else { + domake $builddir all + } + } + cd $PWD + } + + + method Configure {} { + cd $::CWD + my unpack + my TeaConfig + set builddir [file normalize [my define get builddir]] + file mkdir $builddir + set srcroot [file normalize [my define get srcroot]] + if {[my define get USEMSVC 0]} { + return + } + set opts [my ConfigureOpts] + puts [list [self] CONFIGURE] + puts [list PWD [pwd]] + puts [list LOCALSRC $srcroot] + puts [list BUILDDIR $builddir] + puts [list CONFIGURE {*}$opts] + cd $builddir + exec sh [file join $srcroot configure] {*}$opts >& [file join $builddir practcl.log] + cd $::CWD + } + + method install-vfs {} { + set PWD [pwd] + set PKGROOT [my define get installdir] + set PREFIX [my define get prefix] + + ### + # Handle teapot installs + ### + set pkg [my define get pkg_name [my define get name]] + if {[my define get teapot] ne {}} { + set TEAPOT [my define get teapot] + set found 0 + foreach ver [my define get pkg_vers [my define get version]] { + set teapath [file join $TEAPOT $pkg$ver] + if {[file exists $teapath]} { + set dest [file join $PKGROOT [string trimleft $PREFIX /] lib [file tail $teapath]] + ::practcl::copyDir $teapath $dest + return + } + } + } + my compile + if {[my define get USEMSVC 0]} { + set srcroot [my define get srcroot] + cd $srcroot + puts "[self] VFS INSTALL $PKGROOT" + doexec nmake -f makefile.vc INSTALLDIR=$PKGROOT install + } else { + set builddir [my define get builddir] + if {[file exists [file join $builddir make.tcl]]} { + # Practcl builds can inject right to where we need them + puts "[self] VFS INSTALL $PKGROOT (Practcl)" + domake.tcl $builddir install-package $PKGROOT + } elseif {[my define get broken_destroot 0] == 0} { + # Most modern TEA projects understand DESTROOT in the makefile + puts "[self] VFS INSTALL $PKGROOT (TEA)" + domake $builddir install DESTDIR=$PKGROOT + } else { + # But some require us to do an install into a fictitious filesystem + # and then extract the gooey parts within. + # (*cough*) TkImg + set PREFIX [my define get prefix] + set BROKENROOT [::practcl::msys_to_tclpath [my define get prefix_broken_destdir]] + file delete -force $BROKENROOT + file mkdir $BROKENROOT + domake $builddir $install + ::practcl::copyDir $BROKENROOT [file join $PKGROOT [string trimleft $PREFIX /]] + file delete -force $BROKENROOT + } + } + cd $PWD + } + + method TeaConfig {} { + set srcroot [file normalize [my define get srcroot]] + set copytea 0 + if {![file exists [file join $srcroot tclconfig]]} { + set copytea 1 + } else { + if {![file exists [file join $srcroot tclconfig practcl.tcl]] || ![file exists [file join $srcroot tclconfig config.tcl.in]]} { + set copytea 1 + } + } + # ensure we have tclconfig with all of the trimming + if {$copytea} { + set tclconfiginfo [::practcl::fossil_sandbox tclconfig [list sandbox [my define get sandbox]]] + ::practcl::copyDir [dict get $tclconfiginfo srcroot] [file join $srcroot tclconfig] + if {$::tcl_platform(platform) ne "windows"} { + set pwd [pwd] + cd $srcroot + # On windows there's no practical way to execute + # autoconf. We'll have to trust that configure + # us up to date + foreach template {configure.ac configure.in} { + set input [file join $srcroot $template] + if {[file exists $input]} { + puts "autoconf -f $input > [file join $srcroot configure]" + exec autoconf -f $input > [file join $srcroot configure] + } + } + cd $pwd + } + } + } +} + +oo::class create ::practcl::subproject.core { + superclass ::practcl::subproject.binary + + # On the windows platform MinGW must build + # from the platform directory in the source repo + method BuildDir {PWD} { + return [my define get localsrcdir] + } + + method Configure {} { + if {[my define get USEMSVC 0]} { + return + } + set opts [my ConfigureOpts] + puts [list PWD [pwd]] + puts [list [self] CONFIGURE] + set builddir [file normalize [my define get builddir]] + set localsrcdir [file normalize [my define get localsrcdir]] + puts [list LOCALSRC $localsrcdir] + puts [list BUILDDIR $builddir] + puts [list CONFIGURE {*}$opts] + cd $localsrcdir + exec sh [file join $localsrcdir configure] {*}$opts >& [file join $builddir practcl.log] + } + + method ConfigureOpts {} { + set opts {} + set builddir [file normalize [my define get builddir]] + set PREFIX [my define get prefix] + if {[my define get HOST] != [my define get TARGET]} { + lappend opts --host=[my define get TARGET] + } + lappend opts {*}[my define get config_opts] + lappend opts --prefix=$PREFIX + #--exec_prefix=$PREFIX + lappend opts --disable-shared + return $opts + } + + method go {} { + set name [my define get name] + set platform [my define get platform] + if {![my define exists srcroot]} { + my define set srcroot [file join [my define get sandbox] $name] + } + set srcroot [my define get srcroot] + my define add include_dir [file join $srcroot generic] + switch $platform { + windows { + my define set localsrcdir [file join $srcroot win] + my define add include_dir [file join $srcroot win] + } + default { + my define set localsrcdir [file join $srcroot unix] + my define add include_dir [file join $srcroot $name unix] + } + } + my define set builddir [my BuildDir [my define get masterpath]] + } + + method linktype {} { + return {subordinate core.library} + } +} + +package provide practcl 0.5 -- cgit v0.12 From 5bf83d86b6b6d8581410139efdc0312b88b99831 Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Wed, 14 Sep 2016 15:04:41 +0000 Subject: Further adaptations and improvements to practcl. And get, tclsh make.tcl basekit even works now --- library/practcl/practcl.tcl | 62 +++++++++++++++++++++++++++------------------ 1 file changed, 38 insertions(+), 24 deletions(-) diff --git a/library/practcl/practcl.tcl b/library/practcl/practcl.tcl index f285116..77d1181 100644 --- a/library/practcl/practcl.tcl +++ b/library/practcl/practcl.tcl @@ -1121,11 +1121,16 @@ proc ::practcl::build::DEFS {PROJECT DEFS namevar versionvar defsvar} { set field [string range $item 0 [expr {$eqidx-1}]] set value [string range $item [expr {$eqidx+1}] end] set emap {} - lappend emap \x5c \x5c\x5c \x20 \x5c\x20 \x22 \x5c\x22 \x28 \x5c\x28 \x29 \x5c\x29 - if {[string is integer -strict $value]} { - append defs " -D${field}=$value" + # On Windows we need to do some munging of escape characters + if {[practcl::os]=="windows"} { + lappend emap \x5c \x5c\x5c \x20 \x5c\x20 \x22 \x5c\x22 \x28 \x5c\x28 \x29 \x5c\x29 + if {[string is integer -strict $value]} { + append defs " -D${field}=$value" + } else { + append defs " -D${field}=[string map $emap $value]" + } } else { - append defs " -D${field}=[string map $emap $value]" + append defs " -D${field}=$value" } set idx $ndx } @@ -1229,13 +1234,18 @@ if {[file exists {%vfs_tk_library%}]} { CONST char *archive; Tcl_FindExecutable(*argv[0]); archive=Tcl_GetNameOfExecutable(); - +} + if {![$PROJECT define get CORE_ZIPFS 0]} { + ::practcl::cputs zvfsboot { + /* + ** We have to initialize the virtual filesystem before calling + ** Tcl_Init(). Otherwise, Tcl_Init() will not be able to find + ** its startup script files. + */ Tclzipfs_Init(NULL); +} + $PROJECT include {"tclZipfs.h"} } - # We have to initialize the virtual filesystem before calling - # Tcl_Init(). Otherwise, Tcl_Init() will not be able to find - # its startup script files. - $PROJECT include {"tclZipfs.h"} ::practcl::cputs zvfsboot " if(!TclZipfsMount(NULL, archive, \"%vfsroot%\", NULL)) \x7B " ::practcl::cputs zvfsboot { @@ -1656,6 +1666,7 @@ proc ::practcl::build::static-tclsh {outfile PROJECT} { # with the internals of a staticly linked Tcl ### ::practcl::build::DEFS $PROJECT $TCL(defs) name version defs + set debug [$PROJECT define get debug 0] set NAME [string toupper $name] set result {} @@ -3481,27 +3492,30 @@ char * set PLATFORM_SRC_DIR unix my add class csource ofile [my define get name]_appinit.o filename [file join $TCLSRCDIR unix tclAppInit.c] extra [list -DTCL_LOCAL_MAIN_HOOK=[my define get TCL_LOCAL_MAIN_HOOK Tclkit_MainHook] -DTCL_LOCAL_APPINIT=[my define get TCL_LOCAL_APPINIT Tclkit_AppInit]] } - ### - # Add local static Zlib implementation - ### - set cdir [file join $TCLSRCDIR compat zlib] - foreach file { - adler32.c compress.c crc32.c - deflate.c infback.c inffast.c - inflate.c inftrees.c trees.c - uncompr.c zutil.c - } { - my add [file join $cdir $file] - } ### # Pre 8.7, Tcl doesn't include a Zipfs implementation # in the core. Grab the one from odielib ### - set zipfs [file join $TCLSRCDIR generic zvfs.c] - if {![file exists $zipfs]} { + set zipfs [file join $TCLSRCDIR generic tclZipfs.c] + if {[file exists $zipfs]} { + my define set CORE_ZIPFS 1 + } else { + ### + # Add local static Zlib implementation + ### + set cdir [file join $TCLSRCDIR compat zlib] + foreach file { + adler32.c compress.c crc32.c + deflate.c infback.c inffast.c + inflate.c inftrees.c trees.c + uncompr.c zutil.c + } { + my add [file join $cdir $file] + } # The Odie project maintains a mirror of the version # released with the Tcl core + my define set CORE_ZIPFS 0 my add_project odie { tag trunk class subproject @@ -3512,9 +3526,9 @@ char * set cdir [file join $ODIESRCROOT compat zipfs] my define add include_dir $cdir set zipfs [file join $cdir zvfs.c] + my add class csource filename $zipfs initfunc Tclzipfs_Init pkg_name zipfs pkg_vers 1.0 autoload 1 } - my add class csource filename $zipfs initfunc Tclzipfs_Init pkg_name zipfs pkg_vers 1.0 autoload 1 my define add include_dir [file join $TKSRCDIR generic] my define add include_dir [file join $TKSRCDIR $PLATFORM_SRC_DIR] -- cgit v0.12 From a4dbdda70039562e22ccf70611cf68cfe09f41c1 Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Wed, 14 Sep 2016 15:11:12 +0000 Subject: Adding build scripts to implement Tip#453 --- pkgs/make.tcl | 165 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ pkgs/packages.tcl | 92 ++++++++++++++++++++++++++++++ 2 files changed, 257 insertions(+) create mode 100644 pkgs/make.tcl create mode 100644 pkgs/packages.tcl diff --git a/pkgs/make.tcl b/pkgs/make.tcl new file mode 100644 index 0000000..94a4050 --- /dev/null +++ b/pkgs/make.tcl @@ -0,0 +1,165 @@ +### +# This file contains instructions for how to build the Odielib library +# It will produce the following files in whatever directory it was called from: +# +# * odielibc.mk - A Makefile snippet needed to compile the odielib sources +# * odielibc.c - A C file which acts as the loader for odielibc +# * logicset.c/h - A c +# * (several .c and .h files) - C sources that are generated on the fly by automation +### +# Ad a "just in case" version or practcl we ship locally + +set ::CWD [pwd] +set ::project(builddir) $::CWD +set ::project(srcdir) [file dirname [file dirname [file normalize [info script]]]] +set ::project(sandbox) [file dirname $::project(srcdir)] +set ::project(download) [file join $::project(sandbox) download] +set ::project(teapot) [file join $::project(sandbox) teapot] +source [file join $::CWD .. library practcl practcl.tcl] +array set ::project [::practcl::config.tcl $CWD] + +set SRCPATH $::project(srcdir) +set SANDBOX $::project(sandbox) +file mkdir $CWD/build + +::practcl::target implement { + triggers {} +} +::practcl::target tcltk { + depends deps + triggers {script-packages script-pkgindex} +} +::practcl::target basekit { + depends {deps tcltk} + triggers {} + filename [file join $CWD tclkit_bare$::project(EXEEXT)] +} +::practcl::target packages { + depends {deps tcltk} +} +::practcl::target distclean {} +::practcl::target example { + depends basekit +} + +switch [lindex $argv 0] { + autoconf - + pre - + deps { + ::practcl::trigger implement + } + os { + puts "OS: [practcl::os]" + parray ::project + exit 0 + } + wrap { + ::practcl::depends basekit + } + all { + # Auto detect missing bits + foreach {item obj} $::make_objects { + if {[$obj check]} { + $obj trigger + } + } + } + package { + ::practcl::trigger packages + } + default { + ::practcl::trigger {*}$argv + } +} + +parray make + +set ::CWD [pwd] +::practcl::tclkit create BASEKIT {} +BASEKIT define set name tclkit +BASEKIT define set pkg_name tclkit +BASEKIT define set pkg_version 8.7.0a +BASEKIT define set localpath tclkit +BASEKIT define set profile devel +BASEKIT source [file join $::CWD packages.tcl] + +if {$make(distclean)} { + # Clean all source code back to it's pristine state from fossil + foreach item [BASEKIT link list package] { + $item go + set projdir [$item define get localsrcdir] + if {$projdir ne {} && [file exists $projdir]} { + fossil $projdir clean -force + } + } +} + +file mkdir [file join $CWD build] + +if {$make(tcltk)} { + ### + # Download our required packages + ### + set tcl_config_opts {} + set tk_config_opts {} + switch [::practcl::os] { + windows { + #lappend tcl_config_opts --disable-stubs + } + linux { + lappend tk_config_opts --enable-xft=no --enable-xss=no + } + macosx { + lappend tcl_config_opts --enable-corefoundation=yes --enable-framework=no + lappend tk_config_opts --enable-aqua=yes + } + } + lappend tcl_config_opts --with-tzdata --prefix [BASEKIT define get prefix] + BASEKIT project TCLCORE define set config_opts $tcl_config_opts + BASEKIT project TCLCORE go + set _TclSrcDir [BASEKIT project TCLCORE define get localsrcdir] + BASEKIT define set tclsrcdir $_TclSrcDir + lappend tk_config_opts --with-tcl=$_TclSrcDir + BASEKIT project TKCORE define set config_opts $tk_config_opts + BASEKIT project TCLCORE compile + BASEKIT project TKCORE compile +} + +if {$make(basekit)} { + BASEKIT implement $CWD + ::practcl::build::static-tclsh $target(basekit) BASEKIT +} + +if {[lindex $argv 0] eq "package"} { + #set result {} + foreach item [lrange $argv 1 end] { + set obj [BASEKIT project $item] + puts [list build $item [$obj define get static] [info object class $obj]] + if {[string is true [$obj define get static]]} { + $obj compile + } + if {[string is true [$obj define get vfsinstall]]} { + $obj install-vfs + } + } + #puts "RESULT: $result" +} elseif {$make(packages)} { + foreach item [BASEKIT link list package] { + if {[string is true [$item define get static]]} { + $item compile + } + if {[string is true [$item define get vfsinstall]]} { + $item install-vfs + } + } +} + + +if {$make(example)} { + file mkdir [file join $CWD example.vfs] + BASEKIT wrap $CWD example example.vfs +} + +if {[lindex $argv 0] eq "wrap"} { + BASEKIT wrap $CWD {*}[lrange $argv 1 end] +} diff --git a/pkgs/packages.tcl b/pkgs/packages.tcl new file mode 100644 index 0000000..2a84971 --- /dev/null +++ b/pkgs/packages.tcl @@ -0,0 +1,92 @@ +### +# This script implements a basic TclTkit with statically linked +# Tk, sqlite, threads, udp, and mmtk (which includes canvas3d and tkhtml) +### + +set CWD [pwd] + +my define set [array get ::project] +set os [::practcl::os] +my define set os $os +puts [list BASEKIT SANDBOX $::project(sandbox)] +my define set platform $::project(TEA_PLATFORM) +my define set prefix /zvfs +my define set sandbox [file normalize $::project(sandbox)] +my define set installdir [file join $::project(sandbox) pkg] +my define set teapot [file join $::project(sandbox) teapot] +my define set USEMSVC [info exists env(VisualStudioVersion)] +my define set prefix_broken_destdir [file join $::project(sandbox) tmp] +my define set HOST $os +my define set TARGET $os +my define set tclkit_bare [file join $CWD tclkit_bare$::project(EXEEXT)] + +my define set name tclkit +my define set output_c tclkit.c +my define set libs {} + +my add_project TCLCORE { + class subproject.core + name tcl + tag release + static 1 +} +my project TCLCORE define set srcdir [file dirname $::project(sandbox)] + +my add_project TKCORE { + class subproject.core + name tk + tag release + static 1 + autoload 0 + pkg_name Tk + initfunc Tk_Init +} + +my add_project tclconfig { + profile { + release: 3dfb97da548fae506374ac0015352ac0921d0cc9 + devel: practcl + } + class subproject + preload 1 + vfsinstall 0 +} + +my add_project thread { + profile { + release: 2a36d0a6c31569bfb3562e3d58e9e8204f447a7e + devel: practcl + } + class subproject.binary + pkg_name Thread + autoload 1 + initfunc Thread_Init + static 1 +} + +my add_project sqlite { + profile { + release: 40ffdfb26af3e7443b2912e1039c06bf9ed75846 + devel: practcl + } + class subproject.binary + pkg_name sqlite3 + autoload 1 + initfunc Sqlite3_Init + static 1 + vfsinstall 0 +} + +my add_project udp { + profile { + release: 7c396e1a767db57b07b48daa8e0cfc0ea622bbe9 + devel: practcl + } + class subproject.binary + static 1 + autoload 1 + initfunc Udp_Init + pkg_name udp + vfsinstall 0 +} + -- cgit v0.12 From e58a9dabbe2ced71aab80cdcb05f5db244dccd94 Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Sun, 2 Oct 2016 18:30:43 +0000 Subject: Typo fix for Makefile.in --- unix/Makefile.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/unix/Makefile.in b/unix/Makefile.in index ca15312..0a138ed 100644 --- a/unix/Makefile.in +++ b/unix/Makefile.in @@ -464,7 +464,7 @@ GENERIC_SRCS = \ $(GENERIC_DIR)/tclVar.c \ $(GENERIC_DIR)/tclAssembly.c \ $(GENERIC_DIR)/tclZlib.c \ - $(GENERIC_DIR)/zipfs.c + $(GENERIC_DIR)/tclZipfs.c OO_SRCS = \ $(GENERIC_DIR)/tclOO.c \ -- cgit v0.12 From 9dfe53af4ac9a368f01fd80c5c67fbe842d387df Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Sun, 2 Oct 2016 18:42:56 +0000 Subject: Re-created the build mods for tip#340. Something I was doing was screwing with building a proper shell --- win/Makefile.in | 20 +++-------- win/makefile.vc | 8 ++--- win/tclkit.exe.manifest.in | 51 ---------------------------- win/tclkit.rc | 82 ---------------------------------------------- 4 files changed, 6 insertions(+), 155 deletions(-) delete mode 100644 win/tclkit.exe.manifest.in delete mode 100644 win/tclkit.rc diff --git a/win/Makefile.in b/win/Makefile.in index 7e371c8..b6533a4 100644 --- a/win/Makefile.in +++ b/win/Makefile.in @@ -152,7 +152,6 @@ SHARED_LIBRARIES = $(TCL_DLL_FILE) @ZLIB_DLL_FILE@ STATIC_LIBRARIES = $(TCL_LIB_FILE) TCLSH = tclsh$(VER)${EXESUFFIX} -TCLKIT = tclkit$(VER)${EXESUFFIX} CAT32 = cat32$(EXEEXT) MAN2TCL = man2tcl$(EXEEXT) @@ -303,8 +302,8 @@ GENERIC_OBJS = \ tclUtf.$(OBJEXT) \ tclUtil.$(OBJEXT) \ tclVar.$(OBJEXT) \ - tclZlib.$(OBJEXT) \ - tclZipfs.$(OBJEXT) + tclZipfs.$(OBJEXT) \ + tclZlib.$(OBJEXT) TOMMATH_OBJS = \ bncore.${OBJEXT} \ @@ -400,8 +399,6 @@ STUB_OBJS = \ TCLSH_OBJS = tclAppInit.$(OBJEXT) -TCLKIT_OBJS = tclkitMain.${OBJEXT} tclkit.${OBJEXT} - ZLIB_OBJS = \ adler32.$(OBJEXT) \ compress.$(OBJEXT) \ @@ -423,7 +420,7 @@ all: binaries libraries doc packages tcltest: $(TCLSH) $(TEST_DLL_FILE) -binaries: $(TCL_STUB_LIB_FILE) @LIBRARIES@ winextensions $(TCLSH) $(TCLKIT) +binaries: $(TCL_STUB_LIB_FILE) @LIBRARIES@ winextensions $(TCLSH) winextensions: ${DDE_DLL_FILE} ${REG_DLL_FILE} @@ -436,11 +433,6 @@ $(TCLSH): $(TCLSH_OBJS) @LIBRARIES@ $(TCL_STUB_LIB_FILE) tclsh.$(RES) tclsh.$(RES) $(CC_EXENAME) $(LDFLAGS_CONSOLE) @VC_MANIFEST_EMBED_EXE@ -$(TCLKIT): $(TCLKIT_OBJ) @LIBRARIES@ $(TCL_STUB_LIB_FILE) tclsh.$(RES) - $(CC) $(CFLAGS) $(TCLKIT_OBJ) $(TCL_LIB_FILE) $(TCL_STUB_LIB_FILE) $(LIBS) \ - tclsh.$(RES) $(CC_EXENAME) $(LDFLAGS_CONSOLE) - @VC_MANIFEST_EMBED_EXE@ - cat32.$(OBJEXT): cat.c $(CC) -c $(CC_SWITCHES) @DEPARG@ $(CC_OBJNAME) @@ -504,9 +496,6 @@ testMain.${OBJEXT}: tclAppInit.c tclMain2.${OBJEXT}: tclMain.c $(CC) -c $(CC_SWITCHES) -DBUILD_tcl -DTCL_ASCII_MAIN @DEPARG@ $(CC_OBJNAME) -tclkitMain.${OBJEXT}: tclAppInit.c - $(CC) -c $(CC_SWITCHES) -DTCL_LOCAL_MAIN_HOOK="Tclkit_MainHook" -DTCL_LOCAL_APPINIT="Tclkit_AppInit" @DEPARG@ $(CC_OBJNAME) - # TIP #59, embedding of configuration information into the binary library. # # Part of Tcl's configuration information are the paths where it was installed @@ -647,7 +636,6 @@ install-libraries: libraries install-tzdata install-msgs @echo "Installing header files"; @for i in "$(GENERIC_DIR)/tcl.h" "$(GENERIC_DIR)/tclDecls.h" \ "$(GENERIC_DIR)/tclOO.h" "$(GENERIC_DIR)/tclOODecls.h" \ - "$(GENERIC_DIR)/tclZipfs.h" \ "$(GENERIC_DIR)/tclPlatDecls.h" \ "$(GENERIC_DIR)/tclTomMath.h" \ "$(GENERIC_DIR)/tclTomMathDecls.h"; \ @@ -762,7 +750,7 @@ clean: cleanhelp clean-packages distclean: distclean-packages clean $(RM) Makefile config.status config.cache config.log tclConfig.sh \ - tcl.hpj config.status.lineno tclsh.exe.manifest + tcl.hpj config.status.lineno # # Bundled package targets diff --git a/win/makefile.vc b/win/makefile.vc index d360e67..dd7b061 100644 --- a/win/makefile.vc +++ b/win/makefile.vc @@ -344,8 +344,8 @@ COREOBJS = \ $(TMP_DIR)\tclUtf.obj \ $(TMP_DIR)\tclUtil.obj \ $(TMP_DIR)\tclVar.obj \ - $(TMP_DIR)\tclZlib.obj \ - $(TMP_DIR)\tclZipfs.obj + $(TMP_DIR)\tclZipfs.obj \ + $(TMP_DIR)\tclZlib.obj ZLIBOBJS = \ $(TMP_DIR)\adler32.obj \ @@ -945,9 +945,6 @@ $(TMP_DIR)\tclWinTest.obj: $(WINDIR)\tclWinTest.c $(TMP_DIR)\tclZlib.obj: $(GENERICDIR)\tclZlib.c $(cc32) $(TCL_CFLAGS) -I$(COMPATDIR)\zlib -DBUILD_tcl -Fo$@ $? -$(TMP_DIR)\zipfs.obj: $(GENERICDIR)\zipfs.c - $(cc32) $(TCL_CFLAGS) -I$(COMPATDIR)\zlib -DBUILD_tcl -Fo$@ $? - $(TMP_DIR)\tclPkgConfig.obj: $(GENERICDIR)\tclPkgConfig.c $(cc32) -DBUILD_tcl $(TCL_CFLAGS) \ -DCFG_INSTALL_LIBDIR="\"$(LIB_INSTALL_DIR:\=\\)\"" \ @@ -1121,7 +1118,6 @@ install-libraries: tclConfig install-msgs install-tzdata @$(CPY) "$(GENERICDIR)\tclDecls.h" "$(INCLUDE_INSTALL_DIR)\" @$(CPY) "$(GENERICDIR)\tclOO.h" "$(INCLUDE_INSTALL_DIR)\" @$(CPY) "$(GENERICDIR)\tclOODecls.h" "$(INCLUDE_INSTALL_DIR)\" - @$(CPY) "$(GENERICDIR)\tclZipfs.h" "$(INCLUDE_INSTALL_DIR)\" @$(CPY) "$(GENERICDIR)\tclPlatDecls.h" "$(INCLUDE_INSTALL_DIR)\" @$(CPY) "$(GENERICDIR)\tclTomMath.h" "$(INCLUDE_INSTALL_DIR)\" @$(CPY) "$(GENERICDIR)\tclTomMathDecls.h" "$(INCLUDE_INSTALL_DIR)\" diff --git a/win/tclkit.exe.manifest.in b/win/tclkit.exe.manifest.in deleted file mode 100644 index 13c1d24..0000000 --- a/win/tclkit.exe.manifest.in +++ /dev/null @@ -1,51 +0,0 @@ - - - - Tcl self-contained executable (tclkit) - - - - - - - - - - - - - - - - - - - - - - true - - - - - - - - diff --git a/win/tclkit.rc b/win/tclkit.rc deleted file mode 100644 index ebe37e1..0000000 --- a/win/tclkit.rc +++ /dev/null @@ -1,82 +0,0 @@ -// -// Version Resource Script -// - -#include -#include - -// -// build-up the name suffix that defines the type of build this is. -// -#if TCL_THREADS -#define SUFFIX_THREADS "t" -#else -#define SUFFIX_THREADS "" -#endif - -#if STATIC_BUILD -#define SUFFIX_STATIC "s" -#else -#define SUFFIX_STATIC "" -#endif - -#if DEBUG && !UNCHECKED -#define SUFFIX_DEBUG "g" -#else -#define SUFFIX_DEBUG "" -#endif - -#define SUFFIX SUFFIX_THREADS SUFFIX_STATIC SUFFIX_DEBUG - - -LANGUAGE 0x9, 0x1 /* LANG_ENGLISH, SUBLANG_DEFAULT */ - -VS_VERSION_INFO VERSIONINFO - FILEVERSION TCL_MAJOR_VERSION,TCL_MINOR_VERSION,TCL_RELEASE_LEVEL,TCL_RELEASE_SERIAL - PRODUCTVERSION TCL_MAJOR_VERSION,TCL_MINOR_VERSION,TCL_RELEASE_LEVEL,TCL_RELEASE_SERIAL - FILEFLAGSMASK 0x3fL -#ifdef DEBUG - FILEFLAGS VS_FF_DEBUG -#else - FILEFLAGS 0x0L -#endif - FILEOS VOS__WINDOWS32 - FILETYPE VFT_APP - FILESUBTYPE 0x0L -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "040904b0" - BEGIN - VALUE "FileDescription", "Tclkit Application\0" - VALUE "OriginalFilename", "tclkit" STRINGIFY(TCL_MAJOR_VERSION) STRINGIFY(TCL_MINOR_VERSION) SUFFIX ".exe\0" - VALUE "CompanyName", "ActiveState Corporation\0" - VALUE "FileVersion", TCL_PATCH_LEVEL - VALUE "LegalCopyright", "Copyright \251 2000 by ActiveState Corporation, et al\0" - VALUE "ProductName", "Tcl " TCL_VERSION " for Windows\0" - VALUE "ProductVersion", TCL_PATCH_LEVEL - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x409, 1200 - END -END - -// -// Icon -// - -tclsh ICON DISCARDABLE "tclsh.ico" - -// -// This is needed for Windows 8.1 onwards. -// - -#ifndef RT_MANIFEST -#define RT_MANIFEST 24 -#endif -#ifndef CREATEPROCESS_MANIFEST_RESOURCE_ID -#define CREATEPROCESS_MANIFEST_RESOURCE_ID 1 -#endif -CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "tclkit.exe.manifest" -- cgit v0.12 From 522456ba985545e9ba23b34d8093a2f770ebc10b Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Tue, 5 Sep 2017 16:33:37 +0000 Subject: Removed the package style loader from tclAppInit. Zipfs now loads as part of the interpreter. --- unix/tclAppInit.c | 5 ----- win/tclAppInit.c | 5 ----- 2 files changed, 10 deletions(-) diff --git a/unix/tclAppInit.c b/unix/tclAppInit.c index 40b10f3..9bbc88b 100644 --- a/unix/tclAppInit.c +++ b/unix/tclAppInit.c @@ -17,7 +17,6 @@ #include "tcl.h" #ifdef TCL_TEST -#include "tclZipfs.h" extern Tcl_PackageInitProc Tcltest_Init; extern Tcl_PackageInitProc Tcltest_SafeInit; #endif /* TCL_TEST */ @@ -124,10 +123,6 @@ Tcl_AppInit( return TCL_ERROR; } Tcl_StaticPackage(interp, "Tcltest", Tcltest_Init, Tcltest_SafeInit); - if (Tclzipfs_Init(interp) == TCL_ERROR) { - return TCL_ERROR; - } - Tcl_StaticPackage(interp, "zipfs", Tclzipfs_Init, Tclzipfs_SafeInit); #endif /* TCL_TEST */ /* diff --git a/win/tclAppInit.c b/win/tclAppInit.c index b821ca7..e06eaf5 100644 --- a/win/tclAppInit.c +++ b/win/tclAppInit.c @@ -25,7 +25,6 @@ #include #ifdef TCL_TEST -#include "tclZipfs.h" extern Tcl_PackageInitProc Tcltest_Init; extern Tcl_PackageInitProc Tcltest_SafeInit; #endif /* TCL_TEST */ @@ -175,10 +174,6 @@ Tcl_AppInit( return TCL_ERROR; } Tcl_StaticPackage(interp, "Tcltest", Tcltest_Init, Tcltest_SafeInit); - if (Tclzipfs_Init(interp) == TCL_ERROR) { - return TCL_ERROR; - } - Tcl_StaticPackage(interp, "zipfs", Tclzipfs_Init, Tclzipfs_SafeInit); #endif /* TCL_TEST */ /* -- cgit v0.12 From 54bc992b814ebb022b6cdb9798e2effdc14a2550 Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Mon, 25 Sep 2017 16:23:56 +0000 Subject: Improvements to Tip#430 based on community input. Added a forward declaration of TclZipfs_Init. Added TclZipfs_Mount() and TclZifs_Unmount to stubs table. --- generic/tcl.decls | 9 +++++++- generic/tclBasic.c | 2 +- generic/tclDecls.h | 13 +++++++++++ generic/tclInt.h | 4 ++++ generic/tclStubInit.c | 2 ++ generic/tclZipfs.c | 62 +++++++++++++++++++++++++-------------------------- generic/tclZipfs.h | 8 +++---- 7 files changed, 63 insertions(+), 37 deletions(-) diff --git a/generic/tcl.decls b/generic/tcl.decls index b2b91a9..c19bf68 100644 --- a/generic/tcl.decls +++ b/generic/tcl.decls @@ -2335,7 +2335,14 @@ declare 631 { # ----- BASELINE -- FOR -- 8.7.0 ----- # - +# TIP #430 +declare 632 { + int TclZipfs_Mount(Tcl_Interp *interp, const char *zipname, const char *mntpt, + const char *passwd) +} +declare 633 { + int TclZipfs_Unmount(Tcl_Interp *interp, const char *zipname) +} ############################################################################## diff --git a/generic/tclBasic.c b/generic/tclBasic.c index f798a3d..3e6ad56 100644 --- a/generic/tclBasic.c +++ b/generic/tclBasic.c @@ -990,7 +990,7 @@ Tcl_CreateInterp(void) if (TclZlibInit(interp) != TCL_OK) { Tcl_Panic("%s", TclGetString(Tcl_GetObjResult(interp))); } - if (TclZipfsInit(interp) != TCL_OK) { + if (TclZipfs_Init(interp) != TCL_OK) { Tcl_Panic("%s", Tcl_GetString(Tcl_GetObjResult(interp))); } #endif diff --git a/generic/tclDecls.h b/generic/tclDecls.h index 464fc0f..24a22c3 100644 --- a/generic/tclDecls.h +++ b/generic/tclDecls.h @@ -1831,6 +1831,13 @@ EXTERN Tcl_Channel Tcl_OpenTcpServerEx(Tcl_Interp *interp, unsigned int flags, Tcl_TcpAcceptProc *acceptProc, ClientData callbackData); +/* 632 */ +EXTERN int TclZipfs_Mount(Tcl_Interp *interp, + const char *zipname, const char *mntpt, + const char *passwd); +/* 633 */ +EXTERN int TclZipfs_Unmount(Tcl_Interp *interp, + const char *zipname); typedef struct { const struct TclPlatStubs *tclPlatStubs; @@ -2498,6 +2505,8 @@ typedef struct TclStubs { int (*tcl_FSUnloadFile) (Tcl_Interp *interp, Tcl_LoadHandle handlePtr); /* 629 */ void (*tcl_ZlibStreamSetCompressionDictionary) (Tcl_ZlibStream zhandle, Tcl_Obj *compressionDictionaryObj); /* 630 */ Tcl_Channel (*tcl_OpenTcpServerEx) (Tcl_Interp *interp, const char *service, const char *host, unsigned int flags, Tcl_TcpAcceptProc *acceptProc, ClientData callbackData); /* 631 */ + int (*tclZipfs_Mount) (Tcl_Interp *interp, const char *zipname, const char *mntpt, const char *passwd); /* 632 */ + int (*tclZipfs_Unmount) (Tcl_Interp *interp, const char *zipname); /* 633 */ } TclStubs; extern const TclStubs *tclStubsPtr; @@ -3792,6 +3801,10 @@ extern const TclStubs *tclStubsPtr; (tclStubsPtr->tcl_ZlibStreamSetCompressionDictionary) /* 630 */ #define Tcl_OpenTcpServerEx \ (tclStubsPtr->tcl_OpenTcpServerEx) /* 631 */ +#define TclZipfs_Mount \ + (tclStubsPtr->tclZipfs_Mount) /* 632 */ +#define TclZipfs_Unmount \ + (tclStubsPtr->tclZipfs_Unmount) /* 633 */ #endif /* defined(USE_TCL_STUBS) */ diff --git a/generic/tclInt.h b/generic/tclInt.h index be93f16..8339fb1 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -3215,6 +3215,10 @@ MODULE_SCOPE void TclpThreadSetMasterTSD(void *tsdKeyPtr, void *ptr); MODULE_SCOPE void * TclpThreadGetMasterTSD(void *tsdKeyPtr); MODULE_SCOPE void TclErrorStackResetIf(Tcl_Interp *interp, const char *msg, int length); +/* Tip 430 */ +MODULE_SCOPE int TclZipfs_Init(Tcl_Interp *interp); +MODULE_SCOPE int TclZipfs_SafeInit(Tcl_Interp *interp); + /* *---------------------------------------------------------------- diff --git a/generic/tclStubInit.c b/generic/tclStubInit.c index ebd2086..f251a57 100644 --- a/generic/tclStubInit.c +++ b/generic/tclStubInit.c @@ -1536,6 +1536,8 @@ const TclStubs tclStubs = { Tcl_FSUnloadFile, /* 629 */ Tcl_ZlibStreamSetCompressionDictionary, /* 630 */ Tcl_OpenTcpServerEx, /* 631 */ + TclZipfs_Mount, /* 632 */ + TclZipfs_Unmount, /* 633 */ }; /* !END!: Do not edit above this line. */ diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c index 01d46c6..9d74890 100644 --- a/generic/tclZipfs.c +++ b/generic/tclZipfs.c @@ -505,19 +505,19 @@ CanonicalPath(const char *root, const char *tail, Tcl_DString *dsPtr,int ZIPFSPA int i, j, c, isunc = 0, isvfs=0, n=0; #if HAS_DRIVES int zipfspath=1; - if ((tail[0] != '\0') && (strchr(drvletters, tail[0]) != NULL) && - (tail[1] == ':')) { + if ((tail[0] != '\0') && (strchr(drvletters, tail[0]) != NULL) && + (tail[1] == ':')) { tail += 2; zipfspath=0; - } - /* UNC style path */ - if (tail[0] == '\\') { - root = ""; + } + /* UNC style path */ + if (tail[0] == '\\') { + root = ""; ++tail; zipfspath=0; - } - if (tail[0] == '\\') { - root = "/"; + } + if (tail[0] == '\\') { + root = "/"; ++tail; zipfspath=0; } @@ -571,7 +571,7 @@ CanonicalPath(const char *root, const char *tail, Tcl_DString *dsPtr,int ZIPFSPA } else if(isvfs==2) { Tcl_DStringSetLength(dsPtr, j); path = Tcl_DStringValue(dsPtr); - memcpy(path, tail, j); + memcpy(path, tail, j); } else { if (ZIPFSPATH) { Tcl_DStringSetLength(dsPtr, i + j + ZIPFS_VOLUME_LEN); @@ -586,12 +586,12 @@ CanonicalPath(const char *root, const char *tail, Tcl_DString *dsPtr,int ZIPFSPA memcpy(path + i, tail, j); } } -#if HAS_DRIVES - for (i = 0; path[i] != '\0'; i++) { - if (path[i] == '\\') { - path[i] = '/'; +#if HAS_DRIVES + for (i = 0; path[i] != '\0'; i++) { + if (path[i] == '\\') { + path[i] = '/'; } - } + } #endif if(ZIPFSPATH) { n=ZIPFS_VOLUME_LEN; @@ -706,7 +706,7 @@ static ZipEntry * ZipFSLookup(char *filename) { char *realname; - + Tcl_HashEntry *hPtr; ZipEntry *z; Tcl_DString ds; @@ -1030,7 +1030,7 @@ error: /* *------------------------------------------------------------------------- * - * TclZipfsMount -- + * TclZipfs_Mount -- * * This procedure is invoked to mount a given ZIP archive file on * a given mountpoint with optional ZIP password. @@ -1046,7 +1046,7 @@ error: */ int -TclZipfsMount(Tcl_Interp *interp, const char *zipname, const char *mntpt, +TclZipfs_Mount(Tcl_Interp *interp, const char *zipname, const char *mntpt, const char *passwd) { char *realname, *p; @@ -1379,7 +1379,7 @@ nextent: /* *------------------------------------------------------------------------- * - * TclZipfsUnmount -- + * TclZipfs_Unmount -- * * This procedure is invoked to unmount a given ZIP archive. * @@ -1393,7 +1393,7 @@ nextent: */ int -TclZipfsUnmount(Tcl_Interp *interp, const char *zipname) +TclZipfs_Unmount(Tcl_Interp *interp, const char *zipname) { char *realname; ZipFile *zf; @@ -1471,7 +1471,7 @@ ZipFSMountObjCmd(ClientData clientData, Tcl_Interp *interp, "?zipfile? ?mountpoint? ?password?"); return TCL_ERROR; } - return TclZipfsMount(interp, (objc > 1) ? Tcl_GetString(objv[1]) : NULL, + return TclZipfs_Mount(interp, (objc > 1) ? Tcl_GetString(objv[1]) : NULL, (objc > 2) ? Tcl_GetString(objv[2]) : NULL, (objc > 3) ? Tcl_GetString(objv[3]) : NULL); } @@ -1500,7 +1500,7 @@ ZipFSUnmountObjCmd(ClientData clientData, Tcl_Interp *interp, Tcl_WrongNumArgs(interp, 1, objv, "zipfile"); return TCL_ERROR; } - return TclZipfsUnmount(interp, Tcl_GetString(objv[1])); + return TclZipfs_Unmount(interp, Tcl_GetString(objv[1])); } /* @@ -2271,7 +2271,7 @@ ZipFSCanonicalObjCmd(ClientData clientData, Tcl_Interp *interp, } mntpoint = Tcl_GetString(objv[1]); filename = Tcl_GetString(objv[2]); - result=CanonicalPath(mntpoint,filename,&dPath,zipfs); + result=CanonicalPath(mntpoint,filename,&dPath,zipfs); } Tcl_SetObjResult(interp,Tcl_NewStringObj(result,-1)); return TCL_OK; @@ -3430,7 +3430,7 @@ Zip_FSPathInFilesystemProc(Tcl_Obj *pathPtr, ClientData *clientDataPtr) if(strncmp(path,ZIPFS_VOLUME,ZIPFS_VOLUME_LEN)!=0) { return -1; } - + Tcl_DStringInit(&ds); path = CanonicalPath("",path, &ds, 1); len = Tcl_DStringLength(&ds); @@ -3793,7 +3793,7 @@ const Tcl_Filesystem zipfsFilesystem = { /* *------------------------------------------------------------------------- * - * TclZipfsInit -- + * TclZipfs_Init -- * * Perform per interpreter initialization of this module. * @@ -3808,7 +3808,7 @@ const Tcl_Filesystem zipfsFilesystem = { */ int -TclZipfsInit(Tcl_Interp *interp) +TclZipfs_Init(Tcl_Interp *interp) { #ifdef HAVE_ZLIB /* one-time initialization */ @@ -3884,7 +3884,7 @@ TclZipfsInit(Tcl_Interp *interp) /* *------------------------------------------------------------------------- * - * TclZipfsMount, TclZipfsUnmount -- + * TclZipfs_Mount, TclZipfs_Unmount -- * * Dummy version when no ZLIB support available. * @@ -3892,16 +3892,16 @@ TclZipfsInit(Tcl_Interp *interp) */ int -TclZipfsMount(Tcl_Interp *interp, const char *zipname, const char *mntpt, +TclZipfs_Mount(Tcl_Interp *interp, const char *zipname, const char *mntpt, const char *passwd) { - return TclZipFsInit(interp, 1); + return TclZipfs_Init(interp, 1); } int -TclZipfsUnmount(Tcl_Interp *interp, const char *zipname) +TclZipfs_Unmount(Tcl_Interp *interp, const char *zipname) { - return TclZipFsInit(interp, 1); + return TclZipfs_Init(interp, 1); } #endif diff --git a/generic/tclZipfs.h b/generic/tclZipfs.h index 01c9e96..f7da3bd 100644 --- a/generic/tclZipfs.h +++ b/generic/tclZipfs.h @@ -27,11 +27,11 @@ extern "C" { # define ZIPFSAPI DLLEXPORT #endif -ZIPFSAPI int Tclzipfs_Mount(Tcl_Interp *interp, const char *zipname, +ZIPFSAPI int TclZipfs_Mount(Tcl_Interp *interp, const char *zipname, const char *mntpt, const char *passwd); -ZIPFSAPI int Tclzipfs_Unmount(Tcl_Interp *interp, const char *zipname); -ZIPFSAPI int Tclzipfs_Init(Tcl_Interp *interp); -ZIPFSAPI int Tclzipfs_SafeInit(Tcl_Interp *interp); +ZIPFSAPI int TclZipfs_Unmount(Tcl_Interp *interp, const char *zipname); +ZIPFSAPI int TclZipfs_Init(Tcl_Interp *interp); +ZIPFSAPI int TclZipfs_SafeInit(Tcl_Interp *interp); #ifdef __cplusplus } -- cgit v0.12 From 67e505d2abdb7ddb2d38ee7e579785a410008188 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Fri, 27 Oct 2017 08:45:13 +0000 Subject: First implementation of [http://core.tcl.tk/tips/doc/trunk/tip/481.md|TIP #481]: Extend size range of various Tcl_Get*() functions --- generic/tcl.decls | 12 ++++++++++++ generic/tcl.h | 8 ++++++++ generic/tclDecls.h | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++ generic/tclObj.c | 48 ++++++++++++++++++++++++++++++++++++++++++++-- generic/tclStringObj.c | 26 ++++++++++++++++++++++++- generic/tclStubInit.c | 5 +++++ generic/tclTest.c | 26 +++++++++++++------------ generic/tclTestObj.c | 5 +++-- 8 files changed, 165 insertions(+), 17 deletions(-) diff --git a/generic/tcl.decls b/generic/tcl.decls index b2b91a9..85b7b81 100644 --- a/generic/tcl.decls +++ b/generic/tcl.decls @@ -2332,6 +2332,18 @@ declare 631 { const char *host, unsigned int flags, Tcl_TcpAcceptProc *acceptProc, ClientData callbackData) } +# TIP #481 +declare 634 { + int Tcl_GetValue(Tcl_Interp *interp, Tcl_Obj *objPtr, + void *intPtr, int flags) +} +declare 635 { + char *Tcl_GetStringFromObj2(Tcl_Obj *objPtr, size_t *lengthPtr) +} +declare 636 { + Tcl_UniChar *Tcl_GetUnicodeFromObj2(Tcl_Obj *objPtr, size_t *lengthPtr) +} + # ----- BASELINE -- FOR -- 8.7.0 ----- # diff --git a/generic/tcl.h b/generic/tcl.h index 07d841d..17406e1 100644 --- a/generic/tcl.h +++ b/generic/tcl.h @@ -1153,6 +1153,14 @@ typedef struct Tcl_DString { #define TCL_LINK_FLOAT 13 #define TCL_LINK_WIDE_UINT 14 #define TCL_LINK_READ_ONLY 0x80 + +/* + * Types for Tcl_GetValue(): + */ + +#define TCL_TYPE_I(type) (0x100 | (int)sizeof(type)) /* signed integer */ +#define TCL_TYPE_U(type) (0x200 | (int)sizeof(type)) /* unsigned integer */ +#define TCL_TYPE_D(type) (0x300 | (int)sizeof(type)) /* float/double/long double */ /* *---------------------------------------------------------------------------- diff --git a/generic/tclDecls.h b/generic/tclDecls.h index 464fc0f..b4b0320 100644 --- a/generic/tclDecls.h +++ b/generic/tclDecls.h @@ -1831,6 +1831,17 @@ EXTERN Tcl_Channel Tcl_OpenTcpServerEx(Tcl_Interp *interp, unsigned int flags, Tcl_TcpAcceptProc *acceptProc, ClientData callbackData); +/* Slot 632 is reserved */ +/* Slot 633 is reserved */ +/* 634 */ +EXTERN int Tcl_GetValue(Tcl_Interp *interp, Tcl_Obj *objPtr, + void *intPtr, int flags); +/* 635 */ +EXTERN char * Tcl_GetStringFromObj2(Tcl_Obj *objPtr, + size_t *lengthPtr); +/* 636 */ +EXTERN Tcl_UniChar * Tcl_GetUnicodeFromObj2(Tcl_Obj *objPtr, + size_t *lengthPtr); typedef struct { const struct TclPlatStubs *tclPlatStubs; @@ -2498,6 +2509,11 @@ typedef struct TclStubs { int (*tcl_FSUnloadFile) (Tcl_Interp *interp, Tcl_LoadHandle handlePtr); /* 629 */ void (*tcl_ZlibStreamSetCompressionDictionary) (Tcl_ZlibStream zhandle, Tcl_Obj *compressionDictionaryObj); /* 630 */ Tcl_Channel (*tcl_OpenTcpServerEx) (Tcl_Interp *interp, const char *service, const char *host, unsigned int flags, Tcl_TcpAcceptProc *acceptProc, ClientData callbackData); /* 631 */ + void (*reserved632)(void); + void (*reserved633)(void); + int (*tcl_GetValue) (Tcl_Interp *interp, Tcl_Obj *objPtr, void *intPtr, int flags); /* 634 */ + char * (*tcl_GetStringFromObj2) (Tcl_Obj *objPtr, size_t *lengthPtr); /* 635 */ + Tcl_UniChar * (*tcl_GetUnicodeFromObj2) (Tcl_Obj *objPtr, size_t *lengthPtr); /* 636 */ } TclStubs; extern const TclStubs *tclStubsPtr; @@ -3792,6 +3808,14 @@ extern const TclStubs *tclStubsPtr; (tclStubsPtr->tcl_ZlibStreamSetCompressionDictionary) /* 630 */ #define Tcl_OpenTcpServerEx \ (tclStubsPtr->tcl_OpenTcpServerEx) /* 631 */ +/* Slot 632 is reserved */ +/* Slot 633 is reserved */ +#define Tcl_GetValue \ + (tclStubsPtr->tcl_GetValue) /* 634 */ +#define Tcl_GetStringFromObj2 \ + (tclStubsPtr->tcl_GetStringFromObj2) /* 635 */ +#define Tcl_GetUnicodeFromObj2 \ + (tclStubsPtr->tcl_GetUnicodeFromObj2) /* 636 */ #endif /* defined(USE_TCL_STUBS) */ @@ -3966,6 +3990,34 @@ extern const TclStubs *tclStubsPtr; # endif #endif +#undef Tcl_GetDoubleFromObj +#undef Tcl_GetIntFromObj +#undef Tcl_GetStringFromObj +#undef Tcl_GetUnicodeFromObj +#if defined(USE_TCL_STUBS) +#define Tcl_GetDoubleFromObj(interp, objPtr, dblPtr) \ + (sizeof(*dblPtr) == sizeof(double) ? tclStubsPtr->tcl_GetDoubleFromObj(interp, objPtr, (double *)dblPtr) : tclStubsPtr->tcl_GetValue(interp, objPtr, dblPtr, TCL_TYPE_D(*dblPtr))) +#define Tcl_GetIntFromObj(interp, objPtr, intPtr) \ + (sizeof(*intPtr) == sizeof(int) ? tclStubsPtr->tcl_GetIntFromObj(interp, objPtr, (int *)intPtr) : tclStubsPtr->tcl_GetValue(interp, objPtr, intPtr, TCL_TYPE_I(*intPtr))) +#define Tcl_GetUIntFromObj(interp, objPtr, intPtr) \ + (sizeof(*intPtr) == sizeof(int) ? tclStubsPtr->tcl_GetIntFromObj(interp, objPtr, (int *)intPtr) : tclStubsPtr->tcl_GetValue(interp, objPtr, intPtr, TCL_TYPE_U(*intPtr))) +#define Tcl_GetStringFromObj(objPtr, sizePtr) \ + (sizeof(*sizePtr) <= sizeof(int) ? tclStubsPtr->tcl_GetStringFromObj(objPtr, (int *)sizePtr) : tclStubsPtr->tcl_GetStringFromObj2(objPtr, (size_t *)sizePtr)) +#define Tcl_GetUnicodeFromObj(objPtr, sizePtr) \ + (sizeof(*sizePtr) <= sizeof(int) ? tclStubsPtr->tcl_GetUnicodeFromObj(objPtr, (int *)sizePtr) : tclStubsPtr->tcl_GetUnicodeFromObj2(objPtr, (size_t *)sizePtr)) +#else +#define Tcl_GetDoubleFromObj(interp, objPtr, dblPtr) \ + (sizeof(*dblPtr) == sizeof(double) ? (Tcl_GetDoubleFromObj)(interp, objPtr, (double *)dblPtr) : Tcl_GetValue(interp, objPtr, dblPtr, TCL_TYPE_D(*dblPtr))) +#define Tcl_GetIntFromObj(interp, objPtr, intPtr) \ + (sizeof(*intPtr) == sizeof(int) ? Tcl_GetIntFromObj(interp, objPtr, (int *)intPtr) : Tcl_GetValue(interp, objPtr, intPtr, TCL_TYPE_I(*intPtr))) +#define Tcl_GetUIntFromObj(interp, objPtr, intPtr) \ + (sizeof(*intPtr) == sizeof(int) ? Tcl_GetIntFromObj(interp, objPtr, (int *)intPtr) : Tcl_GetValue(interp, objPtr, intPtr, TCL_TYPE_U(*intPtr))) +#define Tcl_GetStringFromObj(objPtr, sizePtr) \ + (sizeof(*sizePtr) <= sizeof(int) ? Tcl_GetStringFromObj(objPtr, (int *)sizePtr) : Tcl_GetStringFromObj2(objPtr, (size_t *)sizePtr)) +#define Tcl_GetUnicodeFromObj(objPtr, sizePtr) \ + (sizeof(*sizePtr) <= sizeof(int) ? Tcl_GetUnicodeFromObj(objPtr, (int *)sizePtr) : Tcl_GetUnicodeFromObj2(objPtr, (size_t *)sizePtr)) +#endif + /* * Deprecated Tcl procedures: */ diff --git a/generic/tclObj.c b/generic/tclObj.c index 1a00011..f61ccb7 100644 --- a/generic/tclObj.c +++ b/generic/tclObj.c @@ -1659,7 +1659,7 @@ Tcl_GetString( /* *---------------------------------------------------------------------- * - * Tcl_GetStringFromObj -- + * Tcl_GetStringFromObj/Tcl_GetStringFromObj2 -- * * Returns the string representation's byte array pointer and length for * an object. @@ -1679,6 +1679,7 @@ Tcl_GetString( *---------------------------------------------------------------------- */ +#undef Tcl_GetStringFromObj char * Tcl_GetStringFromObj( register Tcl_Obj *objPtr, /* Object whose string rep byte pointer should @@ -1694,6 +1695,21 @@ Tcl_GetStringFromObj( } return objPtr->bytes; } +char * +Tcl_GetStringFromObj2( + register Tcl_Obj *objPtr, /* Object whose string rep byte pointer should + * be returned. */ + register size_t *lengthPtr) /* If non-NULL, the location where the string + * rep's byte array length should * be stored. + * If NULL, no length is stored. */ +{ + (void) TclGetString(objPtr); + + if (lengthPtr != NULL) { + *lengthPtr = objPtr->length; + } + return objPtr->bytes; +} /* *---------------------------------------------------------------------- @@ -2273,6 +2289,7 @@ Tcl_SetDoubleObj( *---------------------------------------------------------------------- */ +#undef Tcl_GetDoubleFromObj int Tcl_GetDoubleFromObj( Tcl_Interp *interp, /* Used for error reporting if not NULL. */ @@ -2466,7 +2483,7 @@ Tcl_SetIntObj( /* *---------------------------------------------------------------------- * - * Tcl_GetIntFromObj -- + * Tcl_GetIntFromObj/Tcl_GetValue -- * * Attempt to return an int from the Tcl object "objPtr". If the object * is not already an int, an attempt will be made to convert it to one. @@ -2489,6 +2506,7 @@ Tcl_SetIntObj( *---------------------------------------------------------------------- */ +#undef Tcl_GetIntFromObj int Tcl_GetIntFromObj( Tcl_Interp *interp, /* Used for error reporting if not NULL. */ @@ -2516,6 +2534,32 @@ Tcl_GetIntFromObj( return TCL_OK; #endif } +int +Tcl_GetValue( + Tcl_Interp *interp, /* Used for error reporting if not NULL. */ + register Tcl_Obj *objPtr, /* The object from which to get a int. */ + register void *ptr, /* Place to store resulting int. */ + register int flags) +{ + double value; + int result; + if (flags == TCL_TYPE_I(int)) { + return Tcl_GetIntFromObj(interp, objPtr, ptr); + } + if (flags == TCL_TYPE_I(Tcl_WideInt)) { + return Tcl_GetWideIntFromObj(interp, objPtr, ptr); + } + if (flags == TCL_TYPE_D(double)) { + return Tcl_GetDoubleFromObj(interp, objPtr, ptr); + } + result = Tcl_GetDoubleFromObj(interp, objPtr, &value); + if (flags == TCL_TYPE_D(float)) { + *(float *)ptr = (float) value; + } else { + *(long double *)ptr = (long double) value; + } + return result; +} /* *---------------------------------------------------------------------- diff --git a/generic/tclStringObj.c b/generic/tclStringObj.c index 7c1d42b..0195656 100644 --- a/generic/tclStringObj.c +++ b/generic/tclStringObj.c @@ -540,7 +540,7 @@ Tcl_GetUnicode( /* *---------------------------------------------------------------------- * - * Tcl_GetUnicodeFromObj -- + * Tcl_GetUnicodeFromObj/Tcl_GetUnicodeFromObj2 -- * * Get the Unicode form of the String object with length. If the object * is not already a String object, it will be converted to one. If the @@ -556,6 +556,7 @@ Tcl_GetUnicode( *---------------------------------------------------------------------- */ +#undef Tcl_GetUnicodeFromObj Tcl_UniChar * Tcl_GetUnicodeFromObj( Tcl_Obj *objPtr, /* The object to find the unicode string @@ -579,6 +580,29 @@ Tcl_GetUnicodeFromObj( } return stringPtr->unicode; } +Tcl_UniChar * +Tcl_GetUnicodeFromObj2( + Tcl_Obj *objPtr, /* The object to find the unicode string + * for. */ + size_t *lengthPtr) /* If non-NULL, the location where the string + * rep's unichar length should be stored. If + * NULL, no length is stored. */ +{ + String *stringPtr; + + SetStringFromAny(NULL, objPtr); + stringPtr = GET_STRING(objPtr); + + if (stringPtr->hasUnicode == 0) { + FillUnicodeRep(objPtr); + stringPtr = GET_STRING(objPtr); + } + + if (lengthPtr != NULL) { + *lengthPtr = stringPtr->numChars; + } + return stringPtr->unicode; +} /* *---------------------------------------------------------------------- diff --git a/generic/tclStubInit.c b/generic/tclStubInit.c index ebd2086..b765206 100644 --- a/generic/tclStubInit.c +++ b/generic/tclStubInit.c @@ -1536,6 +1536,11 @@ const TclStubs tclStubs = { Tcl_FSUnloadFile, /* 629 */ Tcl_ZlibStreamSetCompressionDictionary, /* 630 */ Tcl_OpenTcpServerEx, /* 631 */ + 0, /* 632 */ + 0, /* 633 */ + Tcl_GetValue, /* 634 */ + Tcl_GetStringFromObj2, /* 635 */ + Tcl_GetUnicodeFromObj2, /* 636 */ }; /* !END!: Do not edit above this line. */ diff --git a/generic/tclTest.c b/generic/tclTest.c index ebd90ae..5bb99cc 100644 --- a/generic/tclTest.c +++ b/generic/tclTest.c @@ -1733,9 +1733,9 @@ TestdoubledigitsObjCmd(ClientData unused, }; const Tcl_ObjType* doubleType; - double d; + long double d; int status; - int ndigits; + size_t ndigits; int type; int decpt; int signum; @@ -1752,16 +1752,18 @@ TestdoubledigitsObjCmd(ClientData unused, if (status != TCL_OK) { doubleType = Tcl_GetObjType("double"); if (objv[1]->typePtr == doubleType - || TclIsNaN(objv[1]->internalRep.doubleValue)) { + && TclIsNaN(objv[1]->internalRep.doubleValue)) { + double d1; status = TCL_OK; - memcpy(&d, &(objv[1]->internalRep.doubleValue), sizeof(double)); + memcpy(&d1, &(objv[1]->internalRep.doubleValue), sizeof(double)); + d = d1; } } if (status != TCL_OK || Tcl_GetIntFromObj(interp, objv[2], &ndigits) != TCL_OK || Tcl_GetIndexFromObj(interp, objv[3], options, "conversion type", TCL_EXACT, &type) != TCL_OK) { - fprintf(stderr, "bad value? %g\n", d); + fprintf(stderr, "bad value? %Lg\n", d); return TCL_ERROR; } type = types[type]; @@ -3084,7 +3086,7 @@ TestlinkCmd( } if (argv[6][0] != 0) { tmp = Tcl_NewStringObj(argv[6], -1); - if (Tcl_GetWideIntFromObj(interp, tmp, &wideVar) != TCL_OK) { + if (Tcl_GetIntFromObj(interp, tmp, &wideVar) != TCL_OK) { Tcl_DecrRefCount(tmp); return TCL_ERROR; } @@ -3142,7 +3144,7 @@ TestlinkCmd( if (argv[15][0]) { Tcl_WideInt w; tmp = Tcl_NewStringObj(argv[15], -1); - if (Tcl_GetWideIntFromObj(interp, tmp, &w) != TCL_OK) { + if (Tcl_GetIntFromObj(interp, tmp, &w) != TCL_OK) { Tcl_DecrRefCount(tmp); return TCL_ERROR; } @@ -3192,7 +3194,7 @@ TestlinkCmd( } if (argv[6][0] != 0) { tmp = Tcl_NewStringObj(argv[6], -1); - if (Tcl_GetWideIntFromObj(interp, tmp, &wideVar) != TCL_OK) { + if (Tcl_GetIntFromObj(interp, tmp, &wideVar) != TCL_OK) { Tcl_DecrRefCount(tmp); return TCL_ERROR; } @@ -3259,7 +3261,7 @@ TestlinkCmd( if (argv[15][0]) { Tcl_WideInt w; tmp = Tcl_NewStringObj(argv[15], -1); - if (Tcl_GetWideIntFromObj(interp, tmp, &w) != TCL_OK) { + if (Tcl_GetIntFromObj(interp, tmp, &w) != TCL_OK) { Tcl_DecrRefCount(tmp); return TCL_ERROR; } @@ -3527,7 +3529,7 @@ TestparserObjCmd( Tcl_Obj *const objv[]) /* The argument objects. */ { const char *script; - int length, dummy; + size_t length, dummy; Tcl_Parse parse; if (objc != 3) { @@ -3583,7 +3585,7 @@ TestexprparserObjCmd( Tcl_Obj *const objv[]) /* The argument objects. */ { const char *script; - int length, dummy; + size_t length, dummy; Tcl_Parse parse; if (objc != 3) { @@ -3870,7 +3872,7 @@ TestprintObjCmd( } if (objc > 1) { - Tcl_GetWideIntFromObj(interp, objv[2], &argv1); + Tcl_GetIntFromObj(interp, objv[2], &argv1); } argv2 = (size_t)argv1; Tcl_SetObjResult(interp, Tcl_ObjPrintf(Tcl_GetString(objv[1]), argv1, argv2, argv2)); diff --git a/generic/tclTestObj.c b/generic/tclTestObj.c index 5627608..f08b893 100644 --- a/generic/tclTestObj.c +++ b/generic/tclTestObj.c @@ -1163,7 +1163,8 @@ TeststringobjCmd( Tcl_Obj *const objv[]) /* Argument objects. */ { Tcl_UniChar *unicode; - int varIndex, option, i, length; + int varIndex, option; + size_t length, i; #define MAX_STRINGS 11 const char *index, *string, *strings[MAX_STRINGS+1]; String *strPtr; @@ -1230,7 +1231,7 @@ TeststringobjCmd( if (Tcl_IsShared(varPtr[varIndex])) { SetVarToObj(varPtr, varIndex, Tcl_DuplicateObj(varPtr[varIndex])); } - for (i = 3; i < objc; i++) { + for (i = 3; i < (size_t)objc; i++) { strings[i-3] = Tcl_GetString(objv[i]); } for ( ; i < 12 + 3; i++) { -- cgit v0.12 From 338e92cb28bb8cc4d6dac152cf24593323d293bb Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Tue, 7 Nov 2017 18:45:24 +0000 Subject: Updated the zipfs portion of the testsuite to tip430 standards --- tests/zipfs.test | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/tests/zipfs.test b/tests/zipfs.test index adacbde..2aea3bf 100644 --- a/tests/zipfs.test +++ b/tests/zipfs.test @@ -17,9 +17,10 @@ if {"::tcltest" ni [namespace children]} { testConstraint zipfs [expr {[llength [info commands zlib]] && [regexp tcltest [info nameofexecutable]]}] -test zipfs-1.1 {zipfs basics} -constraints zipfs -body { - load {} zipfs -} -result {} +# Removed in tip430 - zipfs is no longer a static package +#test zipfs-1.1 {zipfs basics} -constraints zipfs -body { +# load {} zipfs +#} -result {} test zipfs-1.2 {zipfs basics} -constraints zipfs -body { package require zipfs @@ -66,18 +67,18 @@ test zipfs-2.2 {zipfs mkzip} -constraints zipfs -body { set pwd [pwd] cd $tcl_library/encoding zipfs mkzip abc.zip . - zipfs mount abc.zip /abc - zipfs list -glob /abc/cp850.* + zipfs mount abc.zip zipfs:/abc + zipfs list -glob zipfs:/abc/cp850.* } -cleanup { cd $pwd -} -result {/abc/cp850.enc} +} -result {zipfs:/abc/cp850.enc} test zipfs-2.3 {zipfs unmount} -constraints zipfs -body { - zipfs info /abc/cp850.enc + zipfs info zipfs:/abc/cp850.enc } -result [list $tcl_library/encoding/abc.zip 1090 527 39434] test zipfs-2.4 {zipfs unmount} -constraints zipfs -body { - set f [open /abc/cp850.enc] + set f [open zipfs:/abc/cp850.enc] read $f } -result {# Encoding file: cp850, single-byte S -- cgit v0.12 From 399ff79e21dd4d6374ddc5d825a8a35912a3eaa0 Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Tue, 7 Nov 2017 19:13:34 +0000 Subject: Adding a [file normalize] to zipfs tests that are looking for absolute filenames. On Linux symlinks can cause a discrepency in what the tests think they are looking for. --- tests/zipfs.test | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tests/zipfs.test b/tests/zipfs.test index 2aea3bf..89d35ad 100644 --- a/tests/zipfs.test +++ b/tests/zipfs.test @@ -58,14 +58,15 @@ test zipfs-1.10 {zipfs basics} -constraints zipfs -returnCodes error -body { zipfs list a b c d e f } -result {wrong # args: should be "zipfs list ?(-glob|-regexp)? ?pattern?"} +set ntcl_library [file normalize $tcl_library] test zipfs-2.1 {zipfs mkzip empty archive} -constraints zipfs -returnCodes error -body { - zipfs mkzip abc.zip $tcl_library/xxxx + zipfs mkzip abc.zip $ntcl_library/xxxx } -result {empty archive} test zipfs-2.2 {zipfs mkzip} -constraints zipfs -body { set pwd [pwd] - cd $tcl_library/encoding + cd $ntcl_library/encoding zipfs mkzip abc.zip . zipfs mount abc.zip zipfs:/abc zipfs list -glob zipfs:/abc/cp850.* @@ -75,7 +76,7 @@ test zipfs-2.2 {zipfs mkzip} -constraints zipfs -body { test zipfs-2.3 {zipfs unmount} -constraints zipfs -body { zipfs info zipfs:/abc/cp850.enc -} -result [list $tcl_library/encoding/abc.zip 1090 527 39434] +} -result [list $ntcl_library/encoding/abc.zip 1090 527 39434] test zipfs-2.4 {zipfs unmount} -constraints zipfs -body { set f [open zipfs:/abc/cp850.enc] -- cgit v0.12 From 23440fcbd7900cac63198c161e871dd19ae36d10 Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Tue, 7 Nov 2017 19:26:21 +0000 Subject: Removing patches for Androwish that are not needed for tip430 --- generic/tclIOUtil.c | 34 ---------------------------------- 1 file changed, 34 deletions(-) diff --git a/generic/tclIOUtil.c b/generic/tclIOUtil.c index bb6a7ca..2c389c6 100644 --- a/generic/tclIOUtil.c +++ b/generic/tclIOUtil.c @@ -190,8 +190,6 @@ const Tcl_Filesystem tclNativeFilesystem = { TclpObjChdir }; -MODULE_SCOPE Tcl_Filesystem zipfsFilesystem; - /* * Define the tail of the linked list. Note that for unconventional uses of * Tcl without a native filesystem, we may in the future wish to modify the @@ -1414,22 +1412,6 @@ TclFSNormalizeToUniquePath( Claim(); for (fsRecPtr=firstFsRecPtr; fsRecPtr!=NULL; fsRecPtr=fsRecPtr->nextPtr) { - if (fsRecPtr->fsPtr == &zipfsFilesystem) { - ClientData clientData = NULL; - /* - * Allow mounted zipfs filesystem to overtake entire normalisation. - * This is needed on unix for mounts on symlinks right below root. - */ - - if (fsRecPtr->fsPtr->pathInFilesystemProc != NULL) { - if (fsRecPtr->fsPtr->pathInFilesystemProc(pathPtr, - &clientData)!=-1) { - TclFSSetPathDetails(pathPtr, fsRecPtr->fsPtr, clientData); - break; - } - } - continue; - } if (fsRecPtr->fsPtr != &tclNativeFilesystem) { continue; } @@ -1454,9 +1436,6 @@ TclFSNormalizeToUniquePath( if (fsRecPtr->fsPtr == &tclNativeFilesystem) { continue; } - if (fsRecPtr->fsPtr == &zipfsFilesystem) { - continue; - } if (fsRecPtr->fsPtr->normalizePathProc != NULL) { startAt = fsRecPtr->fsPtr->normalizePathProc(interp, pathPtr, @@ -2939,19 +2918,6 @@ Tcl_FSChdir( } fsPtr = Tcl_FSGetFileSystemForPath(pathPtr); - - if ((fsPtr != NULL) && (fsPtr != &tclNativeFilesystem)) { - /* - * Watch out for tilde substitution. - * Only valid in native filesystem. - */ - char *name = Tcl_GetString(pathPtr); - - if ((name != NULL) && (*name == '~')) { - fsPtr = &tclNativeFilesystem; - } - } - if (fsPtr != NULL) { if (fsPtr->chdirProc != NULL) { /* -- cgit v0.12 From c2dfae075806fd3b5117755f85ba3e8a3a6c2170 Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Tue, 7 Nov 2017 19:51:53 +0000 Subject: Removing kit building facilities. They aren't part of the tip430 spec --- library/practcl/pkgIndex.tcl | 11 - library/practcl/practcl.tcl | 4014 --------------------------------------- library/zvfstools/pkgIndex.tcl | 1 - library/zvfstools/zvfstools.tcl | 325 ---- pkgs/make.tcl | 165 -- pkgs/packages.tcl | 92 - 6 files changed, 4608 deletions(-) delete mode 100644 library/practcl/pkgIndex.tcl delete mode 100644 library/practcl/practcl.tcl delete mode 100644 library/zvfstools/pkgIndex.tcl delete mode 100644 library/zvfstools/zvfstools.tcl delete mode 100644 pkgs/make.tcl delete mode 100644 pkgs/packages.tcl diff --git a/library/practcl/pkgIndex.tcl b/library/practcl/pkgIndex.tcl deleted file mode 100644 index 1e378e8..0000000 --- a/library/practcl/pkgIndex.tcl +++ /dev/null @@ -1,11 +0,0 @@ -# Tcl package index file, version 1.1 -# This file is generated by the "pkg_mkIndex" command -# and sourced either when an application starts up or -# by a "package unknown" script. It invokes the -# "package ifneeded" command to set up package-related -# information so that packages will be loaded automatically -# in response to "package require" commands. When this -# script is sourced, the variable $dir must contain the -# full path name of this file's directory. - -package ifneeded practcl 0.5 [list source [file join $dir practcl.tcl]] diff --git a/library/practcl/practcl.tcl b/library/practcl/practcl.tcl deleted file mode 100644 index 77d1181..0000000 --- a/library/practcl/practcl.tcl +++ /dev/null @@ -1,4014 +0,0 @@ -### -# Practcl -# An object oriented templating system for stamping out Tcl API calls to C -### -puts [list LOADED practcl.tcl from [info script]] -package require TclOO -proc ::debug args { - #puts $args - ::practcl::cputs ::DEBUG_INFO $args -} - -### -# Drop in a static copy of Tcl -### -proc ::doexec args { - puts [list {*}$args] - exec {*}$args >&@ stdout -} - -proc ::dotclexec args { - puts [list [info nameofexecutable] {*}$args] - exec [info nameofexecutable] {*}$args >&@ stdout -} - -proc ::domake {path args} { - set PWD [pwd] - cd $path - puts [list *** $path ***] - puts [list make {*}$args] - exec make {*}$args >&@ stdout - cd $PWD -} - -proc ::domake.tcl {path args} { - set PWD [pwd] - cd $path - puts [list *** $path ***] - puts [list make.tcl {*}$args] - exec [info nameofexecutable] make.tcl {*}$args >&@ stdout - cd $PWD -} - -proc ::fossil {path args} { - set PWD [pwd] - cd $path - puts [list {*}$args] - exec fossil {*}$args >&@ stdout - cd $PWD -} - - -proc ::fossil_status {dir} { - if {[info exists ::fosdat($dir)]} { - return $::fosdat($dir) - } - set result { -tags experimental -version {} - } - set pwd [pwd] - cd $dir - set info [exec fossil status] - cd $pwd - foreach line [split $info \n] { - if {[lindex $line 0] eq "checkout:"} { - set hash [lindex $line end-3] - set maxdate [lrange $line end-2 end-1] - dict set result hash $hash - dict set result maxdate $maxdate - regsub -all {[^0-9]} $maxdate {} isodate - dict set result isodate $isodate - } - if {[lindex $line 0] eq "tags:"} { - set tags [lrange $line 1 end] - dict set result tags $tags - break - } - } - set ::fosdat($dir) $result - return $result -} -### -# Seek out Tcllib if it's available -### -set tcllib_path {} -foreach path {.. ../.. ../../..} { - foreach path [glob -nocomplain [file join [file normalize $path] tcllib* modules]] { - set tclib_path $path - lappend ::auto_path $path - break - } - if {$tcllib_path ne {}} break -} - - -### -# Build utility functions -### -namespace eval ::practcl {} - -proc ::practcl::os {} { - if {[info exists ::project(TEACUP_OS)] && $::project(TEACUP_OS) ni {"@TEACUP_OS@" {}}} { - return $::project(TEACUP_OS) - } - set info [::practcl::config.tcl $::project(builddir)] - if {[dict exists $info TEACUP_OS]} { - return [dict get $info TEACUP_OS] - } - return unknown -} - -### -# Detect local platform -### -proc ::practcl::config.tcl {path} { - dict set result buildpath $path - set result {} - if {[file exists [file join $path config.tcl]]} { - set fin [open [file join $path config.tcl] r] - set bufline {} - set rawcount 0 - set linecount 0 - while {[gets $fin thisline]>=0} { - incr rawcount - append bufline \n $thisline - if {![info complete $bufline]} continue - set line [string trimleft $bufline] - set bufline {} - if {[string index [string trimleft $line] 0] eq "#"} continue - incr linecount - set key [lindex $line 0] - set value [lindex $line 1] - dict set result $key $value - } - dict set result sandbox [file dirname [dict get $result srcdir]] - dict set result download [file join [dict get $result sandbox] download] - dict set result teapot [file join [dict get $result sandbox] teapot] - set result [::practcl::de_shell $result] - } - # If data is available from autoconf, defer to that - if {[dict exists $result TEACUP_OS] && [dict get $result TEACUP_OS] ni {"@TEACUP_OS@" {}}} { - return $result - } - # If autoconf hasn't run yet, assume we are not cross compiling - # and defer to local checks - dict set result TEACUP_PROFILE unknown - dict set result TEACUP_OS unknown - dict set result EXEEXT {} - if {$::tcl_platform(platform) eq "windows"} { - set system "windows" - set arch ix86 - dict set result TEACUP_PROFILE win32-ix86 - dict set result TEACUP_OS windows - dict set result EXEEXT .exe - } else { - set system [exec uname -s]-[exec uname -r] - set arch unknown - dict set result TEACUP_OS generic - } - dict set result TEA_PLATFORM $system - dict set result TEA_SYSTEM $system - switch -glob $system { - Linux* { - dict set result TEACUP_OS linux - set arch [exec uname -m] - dict set result TEACUP_PROFILE "linux-glibc2.3-$arch" - } - GNU* { - set arch [exec uname -m] - dict set result TEACUP_OS "gnu" - } - NetBSD-Debian { - set arch [exec uname -m] - dict set result TEACUP_OS "netbsd-debian" - } - OpenBSD-* { - set arch [exec arch -s] - dict set result TEACUP_OS "openbsd" - } - Darwin* { - set arch [exec uname -m] - dict set result TEACUP_OS "macosx" - if {$arch eq "x86_64"} { - dict set result TEACUP_PROFILE "macosx10.5-i386-x86_84" - } else { - dict set result TEACUP_PROFILE "macosx-universal" - } - } - OpenBSD* { - set arch [exec arch -s] - dict set result TEACUP_OS "openbsd" - } - } - if {$arch eq "unknown"} { - catch {set arch [exec uname -m]} - } - switch -glob $arch { - i*86 { - set arch "ix86" - } - amd64 { - set arch "x86_64" - } - } - dict set result TEACUP_ARCH $arch - if {[dict get $result TEACUP_PROFILE] eq "unknown"} { - dict set result TEACUP_PROFILE [dict get $result TEACUP_OS]-$arch - } - return $result -} - - -### -# Convert an MSYS path to a windows native path -### -if {$::tcl_platform(platform) eq "windows"} { -proc ::practcl::msys_to_tclpath msyspath { - return [exec sh -c "cd $msyspath ; pwd -W"] -} -} else { -proc ::practcl::msys_to_tclpath msyspath { - return [file normalize $msyspath] -} -} - -### -# Bits stolen from fileutil -### -proc ::practcl::cat fname { - set fname [open $fname r] - set data [read $fname] - close $fname - return $data -} - -proc ::practcl::file_lexnormalize {sp} { - set spx [file split $sp] - - # Resolution of embedded relative modifiers (., and ..). - - if { - ([lsearch -exact $spx . ] < 0) && - ([lsearch -exact $spx ..] < 0) - } { - # Quick path out if there are no relative modifiers - return $sp - } - - set absolute [expr {![string equal [file pathtype $sp] relative]}] - # A volumerelative path counts as absolute for our purposes. - - set sp $spx - set np {} - set noskip 1 - - while {[llength $sp]} { - set ele [lindex $sp 0] - set sp [lrange $sp 1 end] - set islast [expr {[llength $sp] == 0}] - - if {[string equal $ele ".."]} { - if { - ($absolute && ([llength $np] > 1)) || - (!$absolute && ([llength $np] >= 1)) - } { - # .. : Remove the previous element added to the - # new path, if there actually is enough to remove. - set np [lrange $np 0 end-1] - } - } elseif {[string equal $ele "."]} { - # Ignore .'s, they stay at the current location - continue - } else { - # A regular element. - lappend np $ele - } - } - if {[llength $np] > 0} { - return [eval [linsert $np 0 file join]] - # 8.5: return [file join {*}$np] - } - return {} -} - -proc ::practcl::file_relative {base dst} { - # Ensure that the link to directory 'dst' is properly done relative to - # the directory 'base'. - - if {![string equal [file pathtype $base] [file pathtype $dst]]} { - return -code error "Unable to compute relation for paths of different pathtypes: [file pathtype $base] vs. [file pathtype $dst], ($base vs. $dst)" - } - - set base [file_lexnormalize [file join [pwd] $base]] - set dst [file_lexnormalize [file join [pwd] $dst]] - - set save $dst - set base [file split $base] - set dst [file split $dst] - - while {[string equal [lindex $dst 0] [lindex $base 0]]} { - set dst [lrange $dst 1 end] - set base [lrange $base 1 end] - if {![llength $dst]} {break} - } - - set dstlen [llength $dst] - set baselen [llength $base] - - if {($dstlen == 0) && ($baselen == 0)} { - # Cases: - # (a) base == dst - - set dst . - } else { - # Cases: - # (b) base is: base/sub = sub - # dst is: base = {} - - # (c) base is: base = {} - # dst is: base/sub = sub - - while {$baselen > 0} { - set dst [linsert $dst 0 ..] - incr baselen -1 - } - # 8.5: set dst [file join {*}$dst] - set dst [eval [linsert $dst 0 file join]] - } - - return $dst -} - -### -# Unpack the source of a fossil project into a designated location -### -proc ::practcl::fossil_sandbox {pkg args} { - if {[llength $args]==1} { - set info [lindex $args 0] - } else { - set info $args - } - set result $info - if {[dict exists $info srcroot]} { - set srcroot [dict get $info srcroot] - } elseif {[dict exists $info sandbox]} { - set srcroot [file join [dict get $info sandbox] $pkg] - } else { - set srcroot [file join $::CWD .. $pkg] - } - dict set result srcroot $srcroot - puts [list fossil_sandbox $pkg $srcroot] - if {[dict exists $info download]} { - ### - # Source is actually a zip archive - ### - set download [dict get $info download] - if {[file exists [file join $download $pkg.zip]]} { - if {![info exists $srcroot]} { - package require zipfile::decode - ::zipfile::decode::unzipfile [file join $download $pkg.zip] $srcroot - } - return - } - } - variable fossil_dbs - if {![::info exists fossil_dbs]} { - # Get a list of local fossil databases - set fossil_dbs [exec fossil all list] - } - set CWD [pwd] - if {![dict exists $info tag]} { - set tag trunk - } else { - set tag [dict get $info tag] - } - dict set result tag $tag - - try { - if {[file exists [file join $srcroot .fslckout]]} { - if {[dict exists $info update] && [dict get $info update]==1} { - catch { - puts "FOSSIL UPDATE" - cd $srcroot - doexec fossil update $tag - } - } - } elseif {[file exists [file join $srcroot _FOSSIL_]]} { - if {[dict exists $info update] && [dict get $info update]==1} { - catch { - puts "FOSSIL UPDATE" - cd $srcroot - doexec fossil update $tag - } - } - } else { - puts "OPEN AND UNPACK" - set fosdb {} - foreach line [split $fossil_dbs \n] { - set line [string trim $line] - if {[file rootname [file tail $line]] eq $pkg} { - set fosdb $line - break - } - } - if {$fosdb eq {}} { - file mkdir [file join $download fossil] - set fosdb [file join $download fossil $pkg.fos] - set cloned 0 - if {[dict exists $info localmirror]} { - set localmirror [dict get $info localmirror] - catch { - doexec fossil clone $localmirror/$pkg $fosdb - set cloned 1 - } - } - if {!$cloned && [dict exists $info fossil_url]} { - set localmirror [dict get $info fossil_url] - catch { - doexec fossil clone $localmirror/$pkg $fosdb - set cloned 1 - } - } - if {!$cloned} { - doexec fossil clone http://fossil.etoyoc.com/fossil/$pkg $fosdb - } - } - file mkdir $srcroot - cd $srcroot - puts "FOSSIL OPEN [pwd]" - doexec fossil open $fosdb $tag - } - } on error {result opts} { - puts [list ERR [dict get $opts -errorinfo]] - return {*}$opts - } finally { - cd $CWD - } - return $result -} - -### -# topic: e71f3f61c348d56292011eec83e95f0aacc1c618 -# description: Converts a XXX.sh file into a series of Tcl variables -### -proc ::practcl::read_sh_subst {line info} { - regsub -all {\x28} $line \x7B line - regsub -all {\x29} $line \x7D line - - #set line [string map $key [string trim $line]] - foreach {field value} $info { - catch {set $field $value} - } - if [catch {subst $line} result] { - return {} - } - set result [string trim $result] - return [string trim $result '] -} - -### -# topic: 03567140cca33c814664c7439570f669b9ab88e6 -### -proc ::practcl::read_sh_file {filename {localdat {}}} { - set fin [open $filename r] - set result {} - if {$localdat eq {}} { - set top 1 - set local [array get ::env] - dict set local EXE {} - } else { - set top 0 - set local $localdat - } - while {[gets $fin line] >= 0} { - set line [string trim $line] - if {[string index $line 0] eq "#"} continue - if {$line eq {}} continue - catch { - if {[string range $line 0 6] eq "export "} { - set eq [string first "=" $line] - set field [string trim [string range $line 6 [expr {$eq - 1}]]] - set value [read_sh_subst [string range $line [expr {$eq+1}] end] $local] - dict set result $field [read_sh_subst $value $local] - dict set local $field $value - } elseif {[string range $line 0 7] eq "include "} { - set subfile [read_sh_subst [string range $line 7 end] $local] - foreach {field value} [read_sh_file $subfile $local] { - dict set result $field $value - } - } else { - set eq [string first "=" $line] - if {$eq > 0} { - set field [read_sh_subst [string range $line 0 [expr {$eq - 1}]] $local] - set value [string trim [string range $line [expr {$eq+1}] end] '] - #set value [read_sh_subst [string range $line [expr {$eq+1}] end] $local] - dict set local $field $value - dict set result $field $value - } - } - } err opts - if {[dict get $opts -code] != 0} { - #puts $opts - puts "Error reading line:\n$line\nerr: $err\n***" - return $err {*}$opts - } - } - return $result -} - -### -# A simpler form of read_sh_file tailored -# to pulling data from (tcl|tk)Config.sh -### -proc ::practcl::read_Config.sh filename { - set fin [open $filename r] - set result {} - set linecount 0 - while {[gets $fin line] >= 0} { - set line [string trim $line] - if {[string index $line 0] eq "#"} continue - if {$line eq {}} continue - catch { - set eq [string first "=" $line] - if {$eq > 0} { - set field [string range $line 0 [expr {$eq - 1}]] - set value [string trim [string range $line [expr {$eq+1}] end] '] - #set value [read_sh_subst [string range $line [expr {$eq+1}] end] $local] - dict set result $field $value - incr $linecount - } - } err opts - if {[dict get $opts -code] != 0} { - #puts $opts - puts "Error reading line:\n$line\nerr: $err\n***" - return $err {*}$opts - } - } - return $result -} - -### -# A simpler form of read_sh_file tailored -# to pulling data from a Makefile -### -proc ::practcl::read_Makefile filename { - set fin [open $filename r] - set result {} - while {[gets $fin line] >= 0} { - set line [string trim $line] - if {[string index $line 0] eq "#"} continue - if {$line eq {}} continue - catch { - set eq [string first "=" $line] - if {$eq > 0} { - set field [string trim [string range $line 0 [expr {$eq - 1}]]] - set value [string trim [string trim [string range $line [expr {$eq+1}] end] ']] - switch $field { - PKG_LIB_FILE { - dict set result libfile $value - } - srcdir { - if {$value eq "."} { - dict set result srcdir [file dirname $filename] - } else { - dict set result srcdir $value - } - } - PACKAGE_NAME { - dict set result name $value - } - PACKAGE_VERSION { - dict set result version $value - } - LIBS { - dict set result PRACTCL_LIBS $value - } - PKG_LIB_FILE { - dict set result libfile $value - } - } - } - } err opts - if {[dict get $opts -code] != 0} { - #puts $opts - puts "Error reading line:\n$line\nerr: $err\n***" - return $err {*}$opts - } - # the Compile field is about where most TEA files start getting silly - if {$field eq "compile"} { - break - } - } - return $result -} - -## Append arguments to a buffer -# The command works like puts in that each call will also insert -# a line feed. Unlike puts, blank links in the interstitial are -# suppressed -proc ::practcl::cputs {varname args} { - upvar 1 $varname buffer - if {[llength $args]==1 && [string length [string trim [lindex $args 0]]] == 0} { - - } - if {[info exist buffer]} { - if {[string index $buffer end] ne "\n"} { - append buffer \n - } - } else { - set buffer \n - } - # Trim leading \n's - append buffer [string trimleft [lindex $args 0] \n] {*}[lrange $args 1 end] -} - - -proc ::practcl::tcl_to_c {body} { - set result {} - foreach rawline [split $body \n] { - set line [string map [list \" \\\" \\ \\\\] $rawline] - cputs result "\n \"$line\\n\" \\" - } - return [string trimright $result \\] -} - - -proc ::practcl::_tagblock {text {style tcl} {note {}}} { - if {[string length [string trim $text]]==0} { - return {} - } - set output {} - switch $style { - tcl { - ::practcl::cputs output "# BEGIN $note" - } - c { - ::practcl::cputs output "/* BEGIN $note */" - } - default { - ::practcl::cputs output "# BEGIN $note" - } - } - ::practcl::cputs output $text - switch $style { - tcl { - ::practcl::cputs output "# END $note" - } - c { - ::practcl::cputs output "/* END $note */" - } - default { - ::practcl::cputs output "# END $note" - } - } - return $output -} - -proc ::practcl::_isdirectory name { - return [file isdirectory $name] -} - -### -# Return true if the pkgindex file contains -# any statement other than "package ifneeded" -# and/or if any package ifneeded loads a DLL -### -proc ::practcl::_pkgindex_directory {path} { - set buffer {} - set pkgidxfile [file join $path pkgIndex.tcl] - if {![file exists $pkgidxfile]} { - # No pkgIndex file, read the source - foreach file [glob -nocomplain $path/*.tm] { - set file [file normalize $file] - set fname [file rootname [file tail $file]] - ### - # We used to be able to ... Assume the package is correct in the filename - # No hunt for a "package provides" - ### - set package [lindex [split $fname -] 0] - set version [lindex [split $fname -] 1] - ### - # Read the file, and override assumptions as needed - ### - set fin [open $file r] - set dat [read $fin] - close $fin - # Look for a teapot style Package statement - foreach line [split $dat \n] { - set line [string trim $line] - if { [string range $line 0 9] != "# Package " } continue - set package [lindex $line 2] - set version [lindex $line 3] - break - } - # Look for a package provide statement - foreach line [split $dat \n] { - set line [string trim $line] - if { [string range $line 0 14] != "package provide" } continue - set package [lindex $line 2] - set version [lindex $line 3] - break - } - append buffer "package ifneeded $package $version \[list source \[file join \$dir [file tail $file]\]\]" \n - } - foreach file [glob -nocomplain $path/*.tcl] { - if { [file tail $file] == "version_info.tcl" } continue - set fin [open $file r] - set dat [read $fin] - close $fin - if {![regexp "package provide" $dat]} continue - set fname [file rootname [file tail $file]] - # Look for a package provide statement - foreach line [split $dat \n] { - set line [string trim $line] - if { [string range $line 0 14] != "package provide" } continue - set package [lindex $line 2] - set version [lindex $line 3] - if {[string index $package 0] in "\$ \["} continue - if {[string index $version 0] in "\$ \["} continue - append buffer "package ifneeded $package $version \[list source \[file join \$dir [file tail $file]\]\]" \n - break - } - } - return $buffer - } - set fin [open $pkgidxfile r] - set dat [read $fin] - close $fin - set thisline {} - foreach line [split $dat \n] { - append thisline $line \n - if {![info complete $thisline]} continue - set line [string trim $line] - if {[string length $line]==0} { - set thisline {} ; continue - } - if {[string index $line 0] eq "#"} { - set thisline {} ; continue - } - try { - # Ignore contditionals - if {[regexp "if.*catch.*package.*Tcl.*return" $thisline]} continue - if {[regexp "if.*package.*vsatisfies.*package.*provide.*return" $thisline]} continue - if {![regexp "package.*ifneeded" $thisline]} { - # This package index contains arbitrary code - # source instead of trying to add it to the master - # package index - return {source [file join $dir pkgIndex.tcl]} - } - append buffer $thisline \n - } on error {err opts} { - puts *** - puts "GOOF: $pkgidxfile" - puts $line - puts $err - puts [dict get $opts -errorinfo] - puts *** - } finally { - set thisline {} - } - } - return $buffer -} - - -proc ::practcl::_pkgindex_path_subdir {path} { - set result {} - foreach subpath [glob -nocomplain [file join $path *]] { - if {[file isdirectory $subpath]} { - lappend result $subpath {*}[_pkgindex_path_subdir $subpath] - } - } - return $result -} -### -# Index all paths given as though they will end up in the same -# virtual file system -### -proc ::practcl::pkgindex_path args { - set stack {} - set buffer { -lappend ::PATHSTACK $dir - } - foreach base $args { - set base [file normalize $base] - set paths [::practcl::_pkgindex_path_subdir $base] - set i [string length $base] - # Build a list of all of the paths - foreach path $paths { - if {$path eq $base} continue - set path_indexed($path) 0 - } - set path_indexed($base) 1 - set path_indexed([file join $base boot tcl]) 1 - #set path_index([file join $base boot tk]) 1 - - foreach path $paths { - if {$path_indexed($path)} continue - set thisdir [file_relative $base $path] - #set thisdir [string range $path $i+1 end] - set idxbuf [::practcl::_pkgindex_directory $path] - if {[string length $idxbuf]} { - incr path_indexed($path) - append buffer "set dir \[set PKGDIR \[file join \[lindex \$::PATHSTACK end\] $thisdir\]\]" \n - append buffer [string map {$dir $PKGDIR} [string trimright $idxbuf]] \n - } - } - } - append buffer { -set dir [lindex $::PATHSTACK end] -set ::PATHSTACK [lrange $::PATHSTACK 0 end-1] -} - return $buffer -} - -### -# topic: 64319f4600fb63c82b2258d908f9d066 -# description: Script to build the VFS file system -### -proc ::practcl::installDir {d1 d2} { - - puts [format {%*sCreating %s} [expr {4 * [info level]}] {} [file tail $d2]] - file delete -force -- $d2 - file mkdir $d2 - - foreach ftail [glob -directory $d1 -nocomplain -tails *] { - set f [file join $d1 $ftail] - if {[file isdirectory $f] && [string compare CVS $ftail]} { - installDir $f [file join $d2 $ftail] - } elseif {[file isfile $f]} { - file copy -force $f [file join $d2 $ftail] - if {$::tcl_platform(platform) eq {unix}} { - file attributes [file join $d2 $ftail] -permissions 0644 - } else { - file attributes [file join $d2 $ftail] -readonly 1 - } - } - } - - if {$::tcl_platform(platform) eq {unix}} { - file attributes $d2 -permissions 0755 - } else { - file attributes $d2 -readonly 1 - } -} - -proc ::practcl::copyDir {d1 d2} { - #puts [list $d1 -> $d2] - #file delete -force -- $d2 - file mkdir $d2 - - foreach ftail [glob -directory $d1 -nocomplain -tails *] { - set f [file join $d1 $ftail] - if {[file isdirectory $f] && [string compare CVS $ftail]} { - copyDir $f [file join $d2 $ftail] - } elseif {[file isfile $f]} { - file copy -force $f [file join $d2 $ftail] - } - } -} - -::oo::class create ::practcl::metaclass { - superclass ::oo::object - - method script script { - eval $script - } - - method source filename { - source $filename - } - - method initialize {} {} - - method define {submethod args} { - my variable define - switch $submethod { - dump { - return [array get define] - } - add { - set field [lindex $args 0] - if {![info exists define($field)]} { - set define($field) {} - } - foreach arg [lrange $args 1 end] { - if {$arg ni $define($field)} { - lappend define($field) $arg - } - } - return $define($field) - } - remove { - set field [lindex $args 0] - if {![info exists define($field)]} { - return - } - set rlist [lrange $args 1 end] - set olist $define($field) - set nlist {} - foreach arg $olist { - if {$arg in $rlist} continue - lappend nlist $arg - } - set define($field) $nlist - return $nlist - } - exists { - set field [lindex $args 0] - return [info exists define($field)] - } - getnull - - get - - cget { - set field [lindex $args 0] - if {[info exists define($field)]} { - return $define($field) - } - return [lindex $args 1] - } - set { - if {[llength $args]==1} { - set arglist [lindex $args 0] - } else { - set arglist $args - } - array set define $arglist - if {[dict exists $arglist class]} { - my select - } - } - default { - array $submethod define {*}$args - } - } - } - - method graft args { - my variable organs - if {[llength $args] == 1} { - error "Need two arguments" - } - set object {} - foreach {stub object} $args { - dict set organs $stub $object - oo::objdefine [self] forward <${stub}> $object - oo::objdefine [self] export <${stub}> - } - return $object - } - - method organ {{stub all}} { - my variable organs - if {![info exists organs]} { - return {} - } - if { $stub eq "all" } { - return $organs - } - if {[dict exists $organs $stub]} { - return [dict get $organs $stub] - } - } - - method link {command args} { - my variable links - switch $command { - object { - foreach obj $args { - foreach linktype [$obj linktype] { - my link add $linktype $obj - } - } - } - add { - ### - # Add a link to an object that was externally created - ### - if {[llength $args] ne 2} { error "Usage: link add LINKTYPE OBJECT"} - lassign $args linktype object - if {[info exists links($linktype)] && $object in $links($linktype)} { - return - } - lappend links($linktype) $object - } - remove { - set object [lindex $args 0] - if {[llength $args]==1} { - set ltype * - } else { - set ltype [lindex $args 1] - } - foreach {linktype elements} [array get links $ltype] { - if {$object in $elements} { - set nlist {} - foreach e $elements { - if { $object ne $e } { lappend nlist $e } - } - set links($linktype) $nlist - } - } - } - list { - if {[llength $args]==0} { - return [array get links] - } - if {[llength $args] != 1} { error "Usage: link list LINKTYPE"} - set linktype [lindex $args 0] - if {![info exists links($linktype)]} { - return {} - } - return $links($linktype) - } - dump { - return [array get links] - } - } - } - - method select {} { - my variable define - set class {} - if {[info exists define(class)]} { - if {[info command $define(class)] ne {}} { - set class $define(class) - } elseif {[info command ::practcl::$define(class)] ne {}} { - set class ::practcl::$define(class) - } else { - switch $define(class) { - default { - set class ::practcl::object - } - } - } - } - if {$class ne {}} { - ::oo::objdefine [self] class $class - } - if {[::info exists define(oodefine)]} { - ::oo::objdefine [self] $define(oodefine) - unset define(oodefine) - } - } -} - -proc ::practcl::trigger {args} { - foreach name $args { - if {[dict exists $::make_objects $name]} { - [dict get $::make_objects $name] triggers - } - } -} - -proc ::practcl::depends {args} { - foreach name $args { - if {[dict exists $::make_objects $name]} { - [dict get $::make_objects $name] check - } - } -} - -proc ::practcl::target {name info} { - set obj [::practcl::target_obj new $name $info] - dict set ::make_objects $name $obj - if {[dict exists $info aliases]} { - foreach item [dict get $info aliases] { - if {![dict exists $::make_objects $item]} { - dict set ::make_objects $item $obj - } - } - } - set ::make($name) 0 - set ::trigger($name) 0 - set filename [$obj define get filename] - if {$filename ne {}} { - set ::target($name) $filename - } -} - -### Batch Tasks - -namespace eval ::practcl::build {} - -## method DEFS -# This method populates 4 variables: -# name - The name of the package -# version - The version of the package -# defs - C flags passed to the compiler -# includedir - A list of paths to feed to the compiler for finding headers -# -proc ::practcl::build::DEFS {PROJECT DEFS namevar versionvar defsvar} { - upvar 1 $namevar name $versionvar version NAME NAME $defsvar defs - set name [string tolower [${PROJECT} define get name [${PROJECT} define get pkg_name]]] - set NAME [string toupper $name] - set version [${PROJECT} define get version [${PROJECT} define get pkg_vers]] - if {$version eq {}} { - set version 0.1a - } - set defs {} - append defs " -DPACKAGE_NAME=\"${name}\" -DPACKAGE_VERSION=\"${version}\"" - append defs " -DPACKAGE_TARNAME=\"${name}\" -DPACKAGE_STRING=\"${name}\x5c\x20${version}\"" - set NAME [string toupper $name] - set idx 0 - set count 0 - while {$idx>=0} { - set ndx [string first " -D" $DEFS $idx+1] - set item [string range $DEFS $idx $ndx] - set item [string trim $item] - set item [string trimleft $item -D] - if {[string range $item 0 7] eq "PACKAGE_"} { - set idx $ndx - continue - } - set eqidx [string first = $item ] - if {$eqidx < 0} { - append defs { } $item - set idx $ndx - continue - } - - set field [string range $item 0 [expr {$eqidx-1}]] - set value [string range $item [expr {$eqidx+1}] end] - set emap {} - # On Windows we need to do some munging of escape characters - if {[practcl::os]=="windows"} { - lappend emap \x5c \x5c\x5c \x20 \x5c\x20 \x22 \x5c\x22 \x28 \x5c\x28 \x29 \x5c\x29 - if {[string is integer -strict $value]} { - append defs " -D${field}=$value" - } else { - append defs " -D${field}=[string map $emap $value]" - } - } else { - append defs " -D${field}=$value" - } - set idx $ndx - } - return $defs -} - -proc ::practcl::build::tclkit_main {PROJECT PKG_OBJS} { - ### - # Build static package list - ### - set statpkglist {} - dict set statpkglist Tk {autoload 0} - puts [list TCLKIT MAIN $PROJECT] - - foreach {ofile info} [${PROJECT} compile-products] { - puts [list * PROD $ofile $info] - if {![dict exists $info object]} continue - set cobj [dict get $info object] - foreach {pkg info} [$cobj static-packages] { - dict set statpkglist $pkg $info - } - } - foreach cobj [list {*}${PKG_OBJS} $PROJECT] { - puts [list * PROG $cobj] - foreach {pkg info} [$cobj static-packages] { - puts [list * PKG $pkg $info] - dict set statpkglist $pkg $info - } - } - - set result {} - $PROJECT include {} - $PROJECT include {"tclInt.h"} - $PROJECT include {"tclFileSystem.h"} - $PROJECT include {} - $PROJECT include {} - $PROJECT include {} - $PROJECT include {} - $PROJECT include {} - - $PROJECT code header { -#ifndef MODULE_SCOPE -# define MODULE_SCOPE extern -#endif - -/* -** Provide a dummy Tcl_InitStubs if we are using this as a static -** library. -*/ -#ifndef USE_TCL_STUBS -# undef Tcl_InitStubs -# define Tcl_InitStubs(a,b,c) TCL_VERSION -#endif -#define STATIC_BUILD 1 -#undef USE_TCL_STUBS - -/* Make sure the stubbed variants of those are never used. */ -#undef Tcl_ObjSetVar2 -#undef Tcl_NewStringObj -#undef Tk_Init -#undef Tk_MainEx -#undef Tk_SafeInit -} - - # Build an area of the file for #define directives and - # function declarations - set define {} - set mainhook [$PROJECT define get TCL_LOCAL_MAIN_HOOK Tclkit_MainHook] - set mainfunc [$PROJECT define get TCL_LOCAL_APPINIT Tclkit_AppInit] - set mainscript [$PROJECT define get main.tcl main.tcl] - set vfsroot [$PROJECT define get vfsroot zipfs:/app] - set vfs_main "${vfsroot}/${mainscript}" - set vfs_tcl_library "${vfsroot}/boot/tcl" - set vfs_tk_library "${vfsroot}/boot/tk" - - set map {} - foreach var { - vfsroot mainhook mainfunc vfs_main vfs_tcl_library vfs_tk_library - } { - dict set map %${var}% [set $var] - } - set preinitscript { -set ::odie(boot_vfs) {%vfsroot%} -set ::SRCDIR {%vfsroot%} -if {[file exists {%vfs_tcl_library%}]} { - set ::tcl_library {%vfs_tcl_library%} - set ::auto_path {} -} -if {[file exists {%vfs_tk_library%}]} { - set ::tk_library {%vfs_tk_library%} -} -} ; # Preinitscript - - set zvfsboot { -/* - * %mainhook% -- - * Performs the argument munging for the shell - */ - } - ::practcl::cputs zvfsboot { - CONST char *archive; - Tcl_FindExecutable(*argv[0]); - archive=Tcl_GetNameOfExecutable(); -} - if {![$PROJECT define get CORE_ZIPFS 0]} { - ::practcl::cputs zvfsboot { - /* - ** We have to initialize the virtual filesystem before calling - ** Tcl_Init(). Otherwise, Tcl_Init() will not be able to find - ** its startup script files. - */ - Tclzipfs_Init(NULL); -} - $PROJECT include {"tclZipfs.h"} - } - - ::practcl::cputs zvfsboot " if(!TclZipfsMount(NULL, archive, \"%vfsroot%\", NULL)) \x7B " - ::practcl::cputs zvfsboot { - Tcl_Obj *vfsinitscript; - vfsinitscript=Tcl_NewStringObj("%vfs_main%",-1); - Tcl_IncrRefCount(vfsinitscript); - if(Tcl_FSAccess(vfsinitscript,F_OK)==0) { - /* Startup script should be set before calling Tcl_AppInit */ - Tcl_SetStartupScript(vfsinitscript,NULL); - } - } - ::practcl::cputs zvfsboot " TclSetPreInitScript([::practcl::tcl_to_c $preinitscript])\;" - ::practcl::cputs zvfsboot " \x7D else \x7B" - ::practcl::cputs zvfsboot " TclSetPreInitScript([::practcl::tcl_to_c { -foreach path { - ../tcl -} { - set p [file join $path library init.tcl] - if {[file exists [file join $path library init.tcl]]} { - set ::tcl_library [file normalize [file join $path library]] - break - } -} -foreach path { - ../tk -} { - if {[file exists [file join $path library tk.tcl]]} { - set ::tk_library [file normalize [file join $path library]] - break - } -} -}])\;" - - ::practcl::cputs zvfsboot " \x7D" - - ::practcl::cputs zvfsboot " return TCL_OK;" - - if {[$PROJECT define get os] eq "windows"} { - set header {int %mainhook%(int *argc, TCHAR ***argv)} - } else { - set header {int %mainhook%(int *argc, char ***argv)} - } - $PROJECT c_function [string map $map $header] [string map $map $zvfsboot] - - practcl::cputs appinit "int %mainfunc%(Tcl_Interp *interp) \x7B" - - # Build AppInit() - set appinit {} - practcl::cputs appinit { - if ((Tcl_Init)(interp) == TCL_ERROR) { - return TCL_ERROR; - } -} - set main_init_script {} - - foreach {statpkg info} $statpkglist { - set initfunc {} - if {[dict exists $info initfunc]} { - set initfunc [dict get $info initfunc] - } - if {$initfunc eq {}} { - set initfunc [string totitle ${statpkg}]_Init - } - # We employ a NULL to prevent the package system from thinking the - # package is actually loaded into the interpreter - $PROJECT code header "extern Tcl_PackageInitProc $initfunc\;\n" - set script [list package ifneeded $statpkg [dict get $info version] [list ::load {} $statpkg]] - append main_init_script \n [list set ::kitpkg(${statpkg}) $script] - if {[dict get $info autoload]} { - ::practcl::cputs appinit " if(${initfunc}(interp)) return TCL_ERROR\;" - ::practcl::cputs appinit " Tcl_StaticPackage(interp,\"$statpkg\",$initfunc,NULL)\;" - } else { - ::practcl::cputs appinit "\n Tcl_StaticPackage(NULL,\"$statpkg\",$initfunc,NULL)\;" - append main_init_script \n $script - } - } - append main_init_script \n { -if {[file exists [file join $::SRCDIR packages.tcl]]} { - #In a wrapped exe, we don't go out to the environment - set dir $::SRCDIR - source [file join $::SRCDIR packages.tcl] -} -# Specify a user-specific startup file to invoke if the application -# is run interactively. Typically the startup file is "~/.apprc" -# where "app" is the name of the application. If this line is deleted -# then no user-specific startup file will be run under any conditions. - } - append main_init_script \n [list set tcl_rcFileName [$PROJECT define get tcl_rcFileName ~/.tclshrc]] - practcl::cputs appinit " Tcl_Eval(interp,[::practcl::tcl_to_c $main_init_script]);" - practcl::cputs appinit { return TCL_OK;} - $PROJECT c_function [string map $map "int %mainfunc%(Tcl_Interp *interp)"] [string map $map $appinit] -} - -proc ::practcl::build::compile-sources {PROJECT COMPILE {CPPCOMPILE {}}} { - set EXTERN_OBJS {} - set OBJECTS {} - set result {} - set builddir [$PROJECT define get builddir] - file mkdir [file join $builddir objs] - set debug [$PROJECT define get debug 0] - if {$CPPCOMPILE eq {}} { - set CPPCOMPILE $COMPILE - } - set task [${PROJECT} compile-products] - ### - # Compile the C sources - ### - foreach {ofile info} $task { - dict set task $ofile done 0 - if {[dict exists $info external] && [dict get $info external]==1} { - dict set task $ofile external 1 - } else { - dict set task $ofile external 0 - } - if {[dict exists $info library]} { - dict set task $ofile done 1 - continue - } - # Products with no cfile aren't compiled - if {![dict exists $info cfile] || [set cfile [dict get $info cfile]] eq {}} { - dict set task $ofile done 1 - continue - } - set cfile [dict get $info cfile] - set ofilename [file join $builddir objs [file tail $ofile]] - if {$debug} { - set ofilename [file join $builddir objs [file rootname [file tail $ofile]].debug.o] - } - dict set task $ofile filename $ofilename - if {[file exists $ofilename] && [file mtime $ofilename]>[file mtime $cfile]} { - lappend result $ofilename - dict set task $ofile done 1 - continue - } - if {![dict exist $info command]} { - if {[file extension $cfile] in {.c++ .cpp}} { - set cmd $CPPCOMPILE - } else { - set cmd $COMPILE - } - if {[dict exists $info extra]} { - append cmd " [dict get $info extra]" - } - append cmd " -c $cfile" - append cmd " -o $ofilename" - dict set task $ofile command $cmd - } - } - set completed 0 - while {$completed==0} { - set completed 1 - foreach {ofile info} $task { - set waiting {} - if {[dict exists $info done] && [dict get $info done]} continue - if {[dict exists $info depend]} { - foreach file [dict get $info depend] { - if {[dict exists $task $file command] && [dict exists $task $file done] && [dict get $task $file done] != 1} { - set waiting $file - break - } - } - } - if {$waiting ne {}} { - set completed 0 - puts "$ofile waiting for $waiting" - continue - } - if {[dict exists $info command]} { - set cmd [dict get $info command] - puts "$cmd" - exec {*}$cmd >&@ stdout - } - lappend result [dict get $info filename] - dict set task $ofile done 1 - } - } - return $result -} - -proc ::practcl::de_shell {data} { - set values {} - foreach flag {DEFS TCL_DEFS TK_DEFS} { - if {[dict exists $data $flag]} { - set value {} - foreach item [dict get $data $flag] { - append value " " [string map {{ } {\ }} $item] - } - dict set values $flag $value - } - } - set map {} - lappend map {${PKG_OBJECTS}} %LIBRARY_OBJECTS% - lappend map {$(PKG_OBJECTS)} %LIBRARY_OBJECTS% - lappend map {${PKG_STUB_OBJECTS}} %LIBRARY_STUB_OBJECTS% - lappend map {$(PKG_STUB_OBJECTS)} %LIBRARY_STUB_OBJECTS% - - lappend map %LIBRARY_NAME% [dict get $data name] - lappend map %LIBRARY_VERSION% [dict get $data version] - lappend map %LIBRARY_VERSION_NODOTS% [string map {. {}} [dict get $data version]] - if {[dict exists $data libprefix]} { - lappend map %LIBRARY_PREFIX% [dict get $data libprefix] - } else { - lappend map %LIBRARY_PREFIX% [dict get $data prefix] - } - foreach flag [dict keys $data] { - if {$flag in {TCL_DEFS TK_DEFS DEFS}} continue - - dict set map "%${flag}%" [dict get $data $flag] - dict set map "\$\{${flag}\}" [dict get $data $flag] - dict set map "\$\(${flag}\)" [dict get $data $flag] - dict set values $flag [dict get $data $flag] - #dict set map "\$\{${flag}\}" $proj($flag) - } - set changed 1 - while {$changed} { - set changed 0 - foreach {field value} $values { - if {$field in {TCL_DEFS TK_DEFS DEFS}} continue - dict with values {} - set newval [string map $map $value] - if {$newval eq $value} continue - set changed 1 - dict set values $field $newval - } - } - return $values -} - -proc ::practcl::build::Makefile {path PROJECT} { - array set proj [$PROJECT define dump] - set path $proj(builddir) - cd $path - set includedir . - #lappend includedir [::practcl::file_relative $path $proj(TCL_INCLUDES)] - lappend includedir [::practcl::file_relative $path [file normalize [file join $proj(TCL_SRC_DIR) generic]]] - lappend includedir [::practcl::file_relative $path [file normalize [file join $proj(srcdir) generic]]] - foreach include [$PROJECT generate-include-directory] { - set cpath [::practcl::file_relative $path [file normalize $include]] - if {$cpath ni $includedir} { - lappend includedir $cpath - } - } - set INCLUDES "-I[join $includedir " -I"]" - set NAME [string toupper $proj(name)] - set result {} - set products {} - set libraries {} - set thisline {} - ::practcl::cputs result "${NAME}_DEFS = $proj(DEFS)\n" - ::practcl::cputs result "${NAME}_INCLUDES = -I\"[join $includedir "\" -I\""]\"\n" - ::practcl::cputs result "${NAME}_COMPILE = \$(CC) \$(CFLAGS) \$(PKG_CFLAGS) \$(${NAME}_DEFS) \$(${NAME}_INCLUDES) \$(INCLUDES) \$(AM_CPPFLAGS) \$(CPPFLAGS) \$(AM_CFLAGS)" - ::practcl::cputs result "${NAME}_CPPCOMPILE = \$(CXX) \$(CFLAGS) \$(PKG_CFLAGS) \$(${NAME}_DEFS) \$(${NAME}_INCLUDES) \$(INCLUDES) \$(AM_CPPFLAGS) \$(CPPFLAGS) \$(AM_CFLAGS)" - - foreach {ofile info} [$PROJECT compile-products] { - dict set products $ofile $info - if {[dict exists $info library]} { -lappend libraries $ofile -continue - } - if {[dict exists $info depend]} { - ::practcl::cputs result "\n${ofile}: [dict get $info depend]" - } else { - ::practcl::cputs result "\n${ofile}:" - } - set cfile [dict get $info cfile] - if {[file extension $cfile] in {.c++ .cpp}} { - set cmd "\t\$\(${NAME}_CPPCOMPILE\)" - } else { - set cmd "\t\$\(${NAME}_COMPILE\)" - } - if {[dict exists $info extra]} { - append cmd " [dict get $info extra]" - } - append cmd " -c [dict get $info cfile] -o \$@\n\t" - ::practcl::cputs result $cmd - } - - set map {} - lappend map %LIBRARY_NAME% $proj(name) - lappend map %LIBRARY_VERSION% $proj(version) - lappend map %LIBRARY_VERSION_NODOTS% [string map {. {}} $proj(version)] - lappend map %LIBRARY_PREFIX% [$PROJECT define getnull libprefix] - - if {[string is true [$PROJECT define get SHARED_BUILD]]} { - set outfile [$PROJECT define get libfile] - } else { - set outfile [$PROJECT shared_library] - } - $PROJECT define set shared_library $outfile - ::practcl::cputs result " -${NAME}_SHLIB = $outfile -${NAME}_OBJS = [dict keys $products] -" - - #lappend map %OUTFILE% {\[$]@} - lappend map %OUTFILE% $outfile - lappend map %LIBRARY_OBJECTS% "\$(${NAME}_OBJS)" - ::practcl::cputs result "$outfile: \$(${NAME}_OBJS)" - ::practcl::cputs result "\t[string map $map [$PROJECT define get PRACTCL_SHARED_LIB]]" - if {[$PROJECT define get PRACTCL_VC_MANIFEST_EMBED_DLL] ni {: {}}} { - ::practcl::cputs result "\t[string map $map [$PROJECT define get PRACTCL_VC_MANIFEST_EMBED_DLL]]" - } - ::practcl::cputs result {} - if {[string is true [$PROJECT define get SHARED_BUILD]]} { - #set outfile [$PROJECT static_library] - set outfile $proj(name).a - } else { - set outfile [$PROJECT define get libfile] - } - $PROJECT define set static_library $outfile - dict set map %OUTFILE% $outfile - ::practcl::cputs result "$outfile: \$(${NAME}_OBJS)" - ::practcl::cputs result "\t[string map $map [$PROJECT define get PRACTCL_STATIC_LIB]]" - ::practcl::cputs result {} - return $result -} - -### -# Produce a dynamic library -### -proc ::practcl::build::library {outfile PROJECT} { - array set proj [$PROJECT define dump] - set path $proj(builddir) - cd $path - set includedir . - #lappend includedir [::practcl::file_relative $path $proj(TCL_INCLUDES)] - lappend includedir [::practcl::file_relative $path [file normalize [file join $proj(TCL_SRC_DIR) generic]]] - lappend includedir [::practcl::file_relative $path [file normalize [file join $proj(srcdir) generic]]] - if {[$PROJECT define get tk 0]} { - lappend includedir [::practcl::file_relative $path [file normalize [file join $proj(TK_SRC_DIR) generic]]] - lappend includedir [::practcl::file_relative $path [file normalize [file join $proj(TK_SRC_DIR) ttk]]] - lappend includedir [::practcl::file_relative $path [file normalize [file join $proj(TK_SRC_DIR) xlib]]] - lappend includedir [::practcl::file_relative $path [file normalize $proj(TK_BIN_DIR)]] - } - foreach include [$PROJECT generate-include-directory] { - set cpath [::practcl::file_relative $path [file normalize $include]] - if {$cpath ni $includedir} { - lappend includedir $cpath - } - } - ::practcl::build::DEFS $PROJECT $proj(DEFS) name version defs - set NAME [string toupper $name] - set debug [$PROJECT define get debug 0] - set os [$PROJECT define get os] - - set INCLUDES "-I[join $includedir " -I"]" - if {$debug} { - set COMPILE "$proj(CC) $proj(CFLAGS_DEBUG) -ggdb \ -$proj(CFLAGS_WARNING) $INCLUDES $defs" - - if {[info exists proc(CXX)]} { - set COMPILECPP "$proj(CXX) $defs $INCLUDES $proj(CFLAGS_DEBUG) -ggdb \ - $proj(DEFS) $proj(CFLAGS_WARNING)" - } else { - set COMPILECPP $COMPILE - } - } else { - set COMPILE "$proj(CC) $proj(CFLAGS) $defs $INCLUDES " - - if {[info exists proc(CXX)]} { - set COMPILECPP "$proj(CXX) $defs $INCLUDES $proj(CFLAGS) $proj(DEFS)" - } else { - set COMPILECPP $COMPILE - } - } - - set products [compile-sources $PROJECT $COMPILE $COMPILECPP] - - set map {} - lappend map %LIBRARY_NAME% $proj(name) - lappend map %LIBRARY_VERSION% $proj(version) - lappend map %LIBRARY_VERSION_NODOTS% [string map {. {}} $proj(version)] - lappend map %OUTFILE% $outfile - lappend map %LIBRARY_OBJECTS% $products - lappend map {${CFLAGS}} "$proj(CFLAGS_DEFAULT) $proj(CFLAGS_WARNING)" - - if {[string is true [$PROJECT define get SHARED_BUILD 1]]} { - set cmd [$PROJECT define get PRACTCL_SHARED_LIB] - append cmd " [$PROJECT define get PRACTCL_LIBS]" - set cmd [string map $map $cmd] - puts $cmd - exec {*}$cmd >&@ stdout - if {[$PROJECT define get PRACTCL_VC_MANIFEST_EMBED_DLL] ni {: {}}} { - set cmd [string map $map [$PROJECT define get PRACTCL_VC_MANIFEST_EMBED_DLL]] - puts $cmd - exec {*}$cmd >&@ stdout - } - } else { - set cmd [string map $map [$PROJECT define get PRACTCL_STATIC_LIB]] - puts $cmd - exec {*}$cmd >&@ stdout - } -} - -### -# Produce a static executable -### -proc ::practcl::build::static-tclsh {outfile PROJECT} { - puts " BUILDING STATIC TCLSH " - set TCLOBJ [$PROJECT project TCLCORE] - set TKOBJ [$PROJECT project TKCORE] - set ODIEOBJ [$PROJECT project odie] - - set PKG_OBJS {} - foreach item [$PROJECT link list package] { - if {[string is true [$item define get static]]} { - lappend PKG_OBJS $item - } - } - array set TCL [$TCLOBJ config.sh] - array set TK [$TKOBJ config.sh] - set path [file dirname $outfile] - cd $path - ### - # For a static Tcl shell, we need to build all local sources - # with the same DEFS flags as the tcl core was compiled with. - # The DEFS produced by a TEA extension aren't intended to operate - # with the internals of a staticly linked Tcl - ### - ::practcl::build::DEFS $PROJECT $TCL(defs) name version defs - - set debug [$PROJECT define get debug 0] - set NAME [string toupper $name] - set result {} - set libraries {} - set thisline {} - set OBJECTS {} - set EXTERN_OBJS {} - foreach obj $PKG_OBJS { - $obj compile - set config($obj) [$obj config.sh] - } - set os [$PROJECT define get os] - set TCLSRCDIR [$TCLOBJ define get srcroot] - set TKSRCDIR [$TKOBJ define get srcroot] - - set includedir . - foreach include [$TCLOBJ generate-include-directory] { - set cpath [::practcl::file_relative $path [file normalize $include]] - if {$cpath ni $includedir} { - lappend includedir $cpath - } - } - lappend includedir [::practcl::file_relative $path [file normalize ../tcl/compat/zlib]] - foreach include [$PROJECT generate-include-directory] { - set cpath [::practcl::file_relative $path [file normalize $include]] - if {$cpath ni $includedir} { - lappend includedir $cpath - } - } - - set INCLUDES "-I[join $includedir " -I"]" - if {$debug} { - set COMPILE "$TCL(cc) $TCL(shlib_cflags) $TCL(cflags_debug) -ggdb \ -$TCL(cflags_warning) $TCL(extra_cflags) $INCLUDES" - } else { - set COMPILE "$TCL(cc) $TCL(shlib_cflags) $TCL(cflags_optimize) \ -$TCL(cflags_warning) $TCL(extra_cflags) $INCLUDES" - } - append COMPILE " " $defs - lappend OBJECTS {*}[compile-sources $PROJECT $COMPILE $COMPILE] - - if {[${PROJECT} define get platform] eq "windows"} { - set RSOBJ [file join $path build tclkit.res.o] - set RCSRC [${PROJECT} define get kit_resource_file] - if {$RCSRC eq {} || ![file exists $RCSRC]} { - set RCSRC [file join $TKSRCDIR win rc wish.rc] - } - set cmd [list windres -o $RSOBJ -DSTATIC_BUILD] - set TCLSRC [file normalize $TCLSRCDIR] - set TKSRC [file normalize $TKSRCDIR] - - lappend cmd --include [::practcl::file_relative $path [file join $TCLSRC generic]] \ - --include [::practcl::file_relative $path [file join $TKSRC generic]] \ - --include [::practcl::file_relative $path [file join $TKSRC win]] \ - --include [::practcl::file_relative $path [file join $TKSRC win rc]] - foreach item [${PROJECT} define get resource_include] { - lappend cmd --include [::practcl::file_relative $path [file normalize $item]] - } - lappend cmd $RCSRC - doexec {*}$cmd - - lappend OBJECTS $RSOBJ - set LDFLAGS_CONSOLE {-mconsole -pipe -static-libgcc} - set LDFLAGS_WINDOW {-mwindows -pipe -static-libgcc} - } else { - set LDFLAGS_CONSOLE {} - set LDFLAGS_WINDOW {} - } - puts "***" - if {$debug} { - set cmd "$TCL(cc) $TCL(shlib_cflags) $TCL(cflags_debug) \ -$TCL(cflags_warning) $TCL(extra_cflags) $INCLUDES" - } else { - set cmd "$TCL(cc) $TCL(shlib_cflags) $TCL(cflags_optimize) \ -$TCL(cflags_warning) $TCL(extra_cflags) $INCLUDES" - } - append cmd " $OBJECTS" - append cmd " $EXTERN_OBJS " - # On OSX it is impossibly to generate a completely static - # executable - if {[$PROJECT define get TEACUP_OS] ne "macosx"} { - append cmd " -static " - } - parray TCL - if {$debug} { - if {$os eq "windows"} { - append cmd " -L${TCL(src_dir)}/win -ltcl86g" - append cmd " -L${TK(src_dir)}/win -ltk86g" - } else { - append cmd " -L${TCL(src_dir)}/unix -ltcl86g" - append cmd " -L${TK(src_dir)}/unix -ltk86g" - } - } else { - append cmd " $TCL(build_lib_spec) $TK(build_lib_spec)" - } - foreach obj $PKG_OBJS { - append cmd " [$obj linker-products $config($obj)]" - } - append cmd " $TCL(libs) $TK(libs)" - foreach obj $PKG_OBJS { - append cmd " [$obj linker-external $config($obj)]" - } - if {$debug} { - if {$os eq "windows"} { - append cmd " -L${TCL(src_dir)}/win ${TCL(stub_lib_flag)}" - append cmd " -L${TK(src_dir)}/win ${TK(stub_lib_flag)}" - } else { - append cmd " -L${TCL(src_dir)}/unix ${TCL(stub_lib_flag)}" - append cmd " -L${TK(src_dir)}/unix ${TK(stub_lib_flag)}" - } - } else { - append cmd " $TCL(build_stub_lib_spec)" - append cmd " $TK(build_stub_lib_spec)" - } - append cmd " -o $outfile $LDFLAGS_CONSOLE" - puts "LINK: $cmd" - exec {*}$cmd >&@ stdout -} - -::oo::class create ::practcl::target_obj { - superclass ::practcl::metaclass - - constructor {name info} { - my variable define triggered domake - set triggered 0 - set domake 0 - set define(name) $name - set data [uplevel 2 [list subst $info]] - array set define $data - my select - my initialize - } - - method do {} { - my variable domake - return $domake - } - - method check {} { - my variable needs_make domake - if {$domake} { - return 1 - } - if {[info exists needs_make]} { - return $needs_make - } - set needs_make 0 - foreach item [my define get depends] { - if {![dict exists $::make_objects $item]} continue - set depobj [dict get $::make_objects $item] - if {$depobj eq [self]} { - puts "WARNING [self] depends on itself" - continue - } - if {[$depobj check]} { - set needs_make 1 - } - } - if {!$needs_make} { - set filename [my define get filename] - if {$filename ne {} && ![file exists $filename]} { - set needs_make 1 - } - } - return $needs_make - } - - method triggers {} { - my variable triggered domake define - if {$triggered} { - return $domake - } - set triggered 1 - foreach item [my define get depends] { - puts [list $item [dict exists $::make_objects $item]] - if {![dict exists $::make_objects $item]} continue - set depobj [dict get $::make_objects $item] - if {$depobj eq [self]} { - puts "WARNING [self] triggers itself" - continue - } else { - set r [$depobj check] - puts [list $depobj check $r] - if {$r} { - puts [list $depobj TRIGGER] - $depobj triggers - } - } - } - if {[info exists ::make($define(name))] && $::make($define(name))} { - return - } - set ::make($define(name)) 1 - ::practcl::trigger {*}[my define get triggers] - } -} - - -### -# Define the metaclass -### -::oo::class create ::practcl::object { - superclass ::practcl::metaclass - - constructor {parent args} { - my variable links define - set organs [$parent child organs] - my graft {*}$organs - array set define $organs - array set define [$parent child define] - array set links {} - if {[llength $args]==1 && [file exists [lindex $args 0]]} { - my InitializeSourceFile [lindex $args 0] - } elseif {[llength $args] == 1} { - set data [uplevel 1 [list subst [lindex $args 0]]] - array set define $data - my select - my initialize - } else { - array set define [uplevel 1 [list subst $args]] - my select - my initialize - } - } - - - method include_dir args { - my define add include_dir {*}$args - } - - method include_directory args { - my define add include_dir {*}$args - } - - method Collate_Source CWD {} - - - method child {method} { - return {} - } - - method InitializeSourceFile filename { - my define set filename $filename - set class {} - switch [file extension $filename] { - .tcl { - set class ::practcl::dynamic - } - .h { - set class ::practcl::cheader - } - .c { - set class ::practcl::csource - } - .ini { - switch [file tail $filename] { - module.ini { - set class ::practcl::module - } - library.ini { - set class ::practcl::subproject - } - } - } - .so - - .dll - - .dylib - - .a { - set class ::practcl::clibrary - } - } - if {$class ne {}} { - oo::objdefine [self] class $class - my initialize - } - } - - method add args { - my variable links - set object [::practcl::object new [self] {*}$args] - foreach linktype [$object linktype] { - lappend links($linktype) $object - } - return $object - } - - method go {} { - debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] - my variable links - foreach {linktype objs} [array get links] { - foreach obj $objs { - $obj go - } - } - debug [list /[self] [self method] [self class]] - } - - method code {section body} { - my variable code - ::practcl::cputs code($section) $body - } - - method Ofile filename { - set lpath [my define get localpath] - if {$lpath eq {}} { - set lpath [my define get name] - } - return ${lpath}_[file rootname [file tail $filename]].o - } - - method compile-products {} { - set filename [my define get filename] - set result {} - if {$filename ne {}} { - if {[my define exists ofile]} { - set ofile [my define get ofile] - } else { - set ofile [my Ofile $filename] - my define set ofile $ofile - } - lappend result $ofile [list cfile $filename extra [my define get extra] external [string is true -strict [my define get external]] object [self]] - } - foreach item [my link list subordinate] { - lappend result {*}[$item compile-products] - } - return $result - } - - method generate-include-directory {} { - debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] - set result [my define get include_dir] - foreach obj [my link list product] { - foreach path [$obj generate-include-directory] { - lappend result $path - } - } - return $result - } - - method generate-debug {{spaces {}}} { - set result {} - ::practcl::cputs result "$spaces[list [self] [list class [info object class [self]] filename [my define get filename]] links [my link list]]" - foreach item [my link list subordinate] { - practcl::cputs result [$item generate-debug "$spaces "] - } - return $result - } - - # Empty template methods - method generate-cheader {} { - debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] - my variable code cfunct cstruct methods tcltype tclprocs - set result {} - if {[info exists code(header)]} { - ::practcl::cputs result $code(header) - } - foreach obj [my link list product] { - # Exclude products that will generate their own C files - if {[$obj define get output_c] ne {}} continue - ::practcl::cputs result "/* BEGIN [$obj define get filename] generate-cheader */" - ::practcl::cputs result [$obj generate-cheader] - ::practcl::cputs result "/* END [$obj define get filename] generate-cheader */" - } - debug [list cfunct [info exists cfunct]] - if {[info exists cfunct]} { - foreach {funcname info} $cfunct { - if {[dict get $info public]} continue - ::practcl::cputs result "[dict get $info header]\;" - } - } - debug [list tclprocs [info exists tclprocs]] - if {[info exists tclprocs]} { - foreach {name info} $tclprocs { - if {[dict exists $info header]} { - ::practcl::cputs result "[dict get $info header]\;" - } - } - } - debug [list methods [info exists methods] [my define get cclass]] - - if {[info exists methods]} { - set thisclass [my define get cclass] - foreach {name info} $methods { - if {[dict exists $info header]} { - ::practcl::cputs result "[dict get $info header]\;" - } - } - # Add the initializer wrapper for the class - ::practcl::cputs result "static int ${thisclass}_OO_Init(Tcl_Interp *interp)\;" - } - return $result - } - - method generate-public-define {} { - debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] - my variable code - set result {} - if {[info exists code(public-define)]} { - ::practcl::cputs result $code(public-define) - } - set result [::practcl::_tagblock $result c [my define get filename]] - foreach mod [my link list product] { - ::practcl::cputs result [$mod generate-public-define] - } - return $result - } - - method generate-public-macro {} { - debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] - my variable code - set result {} - if {[info exists code(public-macro)]} { - ::practcl::cputs result $code(public-macro) - } - set result [::practcl::_tagblock $result c [my define get filename]] - foreach mod [my link list product] { - ::practcl::cputs result [$mod generate-public-macro] - } - return $result - } - - method generate-public-typedef {} { - debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] - my variable code cstruct - set result {} - if {[info exists code(public-typedef)]} { - ::practcl::cputs result $code(public-typedef) - } - if {[info exists cstruct]} { - # Add defintion for native c data structures - foreach {name info} $cstruct { - ::practcl::cputs result "typedef struct $name ${name}\;" - if {[dict exists $info aliases]} { - foreach n [dict get $info aliases] { - ::practcl::cputs result "typedef struct $name ${n}\;" - } - } - } - } - set result [::practcl::_tagblock $result c [my define get filename]] - foreach mod [my link list product] { - ::practcl::cputs result [$mod generate-public-typedef] - } - return $result - } - - method generate-public-structure {} { - debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] - my variable code cstruct - set result {} - if {[info exists code(public-structure)]} { - ::practcl::cputs result $code(public-structure) - } - if {[info exists cstruct]} { - foreach {name info} $cstruct { - if {[dict exists $info comment]} { - ::practcl::cputs result [dict get $info comment] - } - ::practcl::cputs result "struct $name \{[dict get $info body]\}\;" - } - } - set result [::practcl::_tagblock $result c [my define get filename]] - foreach mod [my link list product] { - ::practcl::cputs result [$mod generate-public-structure] - } - return $result - } - method generate-public-headers {} { - debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] - my variable code tcltype - set result {} - if {[info exists code(public-header)]} { - ::practcl::cputs result $code(public-header) - } - if {[info exists tcltype]} { - foreach {type info} $tcltype { - if {![dict exists $info cname]} { - set cname [string tolower ${type}]_tclobjtype - dict set tcltype $type cname $cname - } else { - set cname [dict get $info cname] - } - ::practcl::cputs result "extern const Tcl_ObjType $cname\;" - } - } - if {[info exists code(public)]} { - ::practcl::cputs result $code(public) - } - set result [::practcl::_tagblock $result c [my define get filename]] - foreach mod [my link list product] { - ::practcl::cputs result [$mod generate-public-headers] - } - return $result - } - - method generate-stub-function {} { - debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] - my variable code cfunct tcltype - set result {} - foreach mod [my link list product] { - foreach {funct def} [$mod generate-stub-function] { - dict set result $funct $def - } - } - if {[info exists cfunct]} { - foreach {funcname info} $cfunct { - if {![dict get $info export]} continue - dict set result $funcname [dict get $info header] - } - } - return $result - } - - method generate-public-function {} { - debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] - my variable code cfunct tcltype - set result {} - - if {[my define get initfunc] ne {}} { - ::practcl::cputs result "int [my define get initfunc](Tcl_Interp *interp);" - } - if {[info exists cfunct]} { - foreach {funcname info} $cfunct { - if {![dict get $info public]} continue - ::practcl::cputs result "[dict get $info header]\;" - } - } - set result [::practcl::_tagblock $result c [my define get filename]] - foreach mod [my link list product] { - ::practcl::cputs result [$mod generate-public-function] - } - return $result - } - - method generate-public-includes {} { - debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] - set includes {} - foreach item [my define get public-include] { - if {$item ni $includes} { - lappend includes $item - } - } - foreach mod [my link list product] { - foreach item [$mod generate-public-includes] { - if {$item ni $includes} { - lappend includes $item - } - } - } - return $includes - } - method generate-public-verbatim {} { - debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] - set includes {} - foreach item [my define get public-verbatim] { - if {$item ni $includes} { - lappend includes $item - } - } - foreach mod [my link list subordinate] { - foreach item [$mod generate-public-verbatim] { - if {$item ni $includes} { - lappend includes $item - } - } - } - return $includes - } - ### - # This methods generates the contents of an amalgamated .h file - # which describes the public API of this module - ### - method generate-h {} { - debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] - set result {} - set includes [my generate-public-includes] - foreach inc $includes { - if {[string index $inc 0] ni {< \"}} { - ::practcl::cputs result "#include \"$inc\"" - } else { - ::practcl::cputs result "#include $inc" - } - } - foreach file [my generate-public-verbatim] { - ::practcl::cputs result "/* BEGIN $file */" - ::practcl::cputs result [::practcl::cat $file] - ::practcl::cputs result "/* END $file */" - } - foreach method { - generate-public-define - generate-public-macro - generate-public-typedef - generate-public-structure - generate-public-headers - generate-public-function - } { - ::practcl::cputs result "/* BEGIN SECTION $method */" - ::practcl::cputs result [my $method] - ::practcl::cputs result "/* END SECTION $method */" - } - return $result - } - - ### - # This methods generates the contents of an amalgamated .c file - # which implements the loader for a batch of tools - ### - method generate-c {} { - debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] - set result { -/* This file was generated by practcl */ - } - set includes {} - lappend headers - if {[my define get tk 0]} { - lappend headers - } - lappend headers {*}[my define get include] - if {[my define get output_h] ne {}} { - lappend headers "\"[my define get output_h]\"" - } - foreach mod [my link list product] { - # Signal modules to formulate final implementation - $mod go - } - foreach mod [my link list dynamic] { - foreach inc [$mod define get include] { - if {$inc ni $headers} { - lappend headers $inc - } - } - } - foreach inc $headers { - if {[string index $inc 0] ni {< \"}} { - ::practcl::cputs result "#include \"$inc\"" - } else { - ::practcl::cputs result "#include $inc" - } - } - foreach {method} { - generate-cheader - generate-cstruct - generate-constant - generate-cfunct - generate-cmethod - } { - ::practcl::cputs result "/* BEGIN $method [my define get filename] */" - ::practcl::cputs result [my $method] - ::practcl::cputs result "/* END $method [my define get filename] */" - } - debug [list /[self] [self method] [self class] -- [my define get filename] [info object class [self]]] - return $result - } - - - method generate-loader {} { - debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] - set result {} - if {[my define get initfunc] eq {}} return - ::practcl::cputs result " -extern int DLLEXPORT [my define get initfunc]( Tcl_Interp *interp ) \{" - ::practcl::cputs result { - /* Initialise the stubs tables. */ - #ifdef USE_TCL_STUBS - if (Tcl_InitStubs(interp, "8.6", 0)==NULL) return TCL_ERROR; - if (TclOOInitializeStubs(interp, "1.0") == NULL) return TCL_ERROR; -} - if {[my define get tk 0]} { - ::practcl::cputs result { if (Tk_InitStubs(interp, "8.6", 0)==NULL) return TCL_ERROR;} - } - ::practcl::cputs result { #endif} - set TCLINIT [my generate-tcl] - ::practcl::cputs result " if(Tcl_Eval(interp,[::practcl::tcl_to_c $TCLINIT])) return TCL_ERROR ;" - foreach item [my link list product] { - if {[$item define get output_c] ne {}} { - ::practcl::cputs result [$item generate-cinit-external] - } else { - ::practcl::cputs result [$item generate-cinit] - } - } - if {[my define exists pkg_name]} { - ::practcl::cputs result " if (Tcl_PkgProvide(interp, \"[my define get pkg_name [my define get name]]\" , \"[my define get pkg_vers [my define get version]]\" )) return TCL_ERROR\;" - } - ::practcl::cputs result " return TCL_OK\;\n\}\n" - return $result - } - - ### - # This methods generates any Tcl script file - # which is required to pre-initialize the C library - ### - method generate-tcl {} { - debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] - set result {} - my variable code - if {[info exists code(tcl)]} { - ::practcl::cputs result $code(tcl) - } - set result [::practcl::_tagblock $result tcl [my define get filename]] - foreach mod [my link list product] { - ::practcl::cputs result [$mod generate-tcl] - } - return $result - } - - method static-packages {} { - set result [my define get static_packages] - set statpkg [my define get static_pkg] - set initfunc [my define get initfunc] - if {$initfunc ne {}} { - set pkg_name [my define get pkg_name] - if {$pkg_name ne {}} { - dict set result $pkg_name initfunc $initfunc - dict set result $pkg_name version [my define get version [my define get pkg_vers]] - dict set result $pkg_name autoload [my define get autoload 0] - } - } - foreach item [my link list subordinate] { - foreach {pkg info} [$item static-packages] { - dict set result $pkg $info - } - } - return $result - } - - method target {method args} { - switch $method { - is_unix { return [expr {$::tcl_platform(platform) eq "unix"}] } - } - } - -} - -::oo::class create ::practcl::product { - superclass ::practcl::object - - method linktype {} { - return {subordinate product} - } - - method include header { - my define add include $header - } - - method cstructure {name definition {argdat {}}} { - my variable cstruct - dict set cstruct $name body $definition - foreach {f v} $argdat { - dict set cstruct $name $f $v - } - } - - method generate-cinit {} { - debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] - my variable code - set result {} - if {[info exists code(cinit)]} { - ::practcl::cputs result $code(cinit) - } - if {[my define get initfunc] ne {}} { - ::practcl::cputs result " if([my define get initfunc](interp)!=TCL_OK) return TCL_ERROR\;" - } - set result [::practcl::_tagblock $result c [my define get filename]] - foreach obj [my link list product] { - ::practcl::cputs result [$obj generate-cinit] - } - return $result - } -} - -### -# Dynamic blocks do not generate their own .c files, -# instead the contribute to the amalgamation -# of the main library file -### -::oo::class create ::practcl::dynamic { - superclass ::practcl::product - - # Retrieve any additional source files required - - method compile-products {} { - set filename [my define get output_c] - set result {} - if {$filename ne {}} { - if {[my define exists ofile]} { - set ofile [my define get ofile] - } else { - set ofile [my Ofile $filename] - my define set ofile $ofile - } - lappend result $ofile [list cfile $filename extra [my define get extra] external [string is true -strict [my define get external]]] - } else { - set filename [my define get cfile] - if {$filename ne {}} { - if {[my define exists ofile]} { - set ofile [my define get ofile] - } else { - set ofile [my Ofile $filename] - my define set ofile $ofile - } - lappend result $ofile [list cfile $filename extra [my define get extra] external [string is true -strict [my define get external]]] - } - } - foreach item [my link list subordinate] { - lappend result {*}[$item compile-products] - } - return $result - } - - method implement path { - my go - my Collate_Source $path - if {[my define get output_c] eq {}} return - set filename [file join $path [my define get output_c]] - my define set cfile $filename - set fout [open $filename w] - puts $fout [my generate-c] - puts $fout "extern int DLLEXPORT [my define get initfunc]( Tcl_Interp *interp ) \x7B" - puts $fout [my generate-cinit] - if {[my define get pkg_name] ne {}} { - puts $fout " Tcl_PkgProvide(interp, \"[my define get pkg_name]\", \"[my define get pkg_vers]\");" - } - puts $fout " return TCL_OK\;" - puts $fout "\x7D" - close $fout - } - - method initialize {} { - set filename [my define get filename] - if {$filename eq {}} { - return - } - if {[my define get name] eq {}} { - my define set name [file tail [file rootname $filename]] - } - if {[my define get localpath] eq {}} { - my define set localpath [my define get localpath]_[my define get name] - } - ::source $filename - } - - method linktype {} { - return {subordinate product dynamic} - } - - ### - # Populate const static data structures - ### - method generate-cstruct {} { - debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] - my variable code cstruct methods tcltype - set result {} - if {[info exists code(struct)]} { - ::practcl::cputs result $code(struct) - } - foreach obj [my link list dynamic] { - # Exclude products that will generate their own C files - if {[$obj define get output_c] ne {}} continue - ::practcl::cputs result [$obj generate-cstruct] - } - return $result - } - - method generate-constant {} { - debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] - set result {} - my variable code cstruct methods tcltype - if {[info exists code(constant)]} { - ::practcl::cputs result "/* [my define get filename] CONSTANT */" - ::practcl::cputs result $code(constant) - } - if {[info exists cstruct]} { - foreach {name info} $cstruct { - set map {} - lappend map @NAME@ $name - lappend map @MACRO@ GET[string toupper $name] - - if {[dict exists $info deleteproc]} { - lappend map @DELETEPROC@ [dict get $info deleteproc] - } else { - lappend map @DELETEPROC@ NULL - } - if {[dict exists $info cloneproc]} { - lappend map @CLONEPROC@ [dict get $info cloneproc] - } else { - lappend map @CLONEPROC@ NULL - } - ::practcl::cputs result [string map $map { -const static Tcl_ObjectMetadataType @NAME@DataType = { - TCL_OO_METADATA_VERSION_CURRENT, - "@NAME@", - @DELETEPROC@, - @CLONEPROC@ -}; -#define @MACRO@(OBJCONTEXT) (@NAME@ *) Tcl_ObjectGetMetadata(OBJCONTEXT,&@NAME@DataType) -}] - } - } - if {[info exists tcltype]} { - foreach {type info} $tcltype { - dict with info {} - ::practcl::cputs result "const Tcl_ObjType $cname = \{\n .freeIntRepProc = &${freeproc},\n .dupIntRepProc = &${dupproc},\n .updateStringProc = &${updatestringproc},\n .setFromAnyProc = &${setfromanyproc}\n\}\;" - } - } - - if {[info exists methods]} { - set mtypes {} - foreach {name info} $methods { - set callproc [dict get $info callproc] - set methodtype [dict get $info methodtype] - if {$methodtype in $mtypes} continue - lappend mtypes $methodtype - ### - # Build the data struct for this method - ### - ::practcl::cputs result "const static Tcl_MethodType $methodtype = \{" - ::practcl::cputs result " .version = TCL_OO_METADATA_VERSION_CURRENT,\n .name = \"$name\",\n .callProc = $callproc," - if {[dict exists $info deleteproc]} { - set deleteproc [dict get $info deleteproc] - } else { - set deleteproc NULL - } - if {$deleteproc ni { {} NULL }} { - ::practcl::cputs result " .deleteProc = $deleteproc," - } else { - ::practcl::cputs result " .deleteProc = NULL," - } - if {[dict exists $info cloneproc]} { - set cloneproc [dict get $info cloneproc] - } else { - set cloneproc NULL - } - if {$cloneproc ni { {} NULL }} { - ::practcl::cputs result " .cloneProc = $cloneproc\n\}\;" - } else { - ::practcl::cputs result " .cloneProc = NULL\n\}\;" - } - dict set methods $name methodtype $methodtype - } - } - foreach obj [my link list dynamic] { - # Exclude products that will generate their own C files - if {[$obj define get output_c] ne {}} continue - ::practcl::cputs result [$obj generate-constant] - } - return $result - } - - ### - # Generate code that provides subroutines called by - # Tcl API methods - ### - method generate-cfunct {} { - debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] - my variable code cfunct - set result {} - if {[info exists code(funct)]} { - ::practcl::cputs result $code(funct) - } - if {[info exists cfunct]} { - foreach {funcname info} $cfunct { - ::practcl::cputs result "[dict get $info header]\{[dict get $info body]\}\;" - } - } - foreach obj [my link list dynamic] { - # Exclude products that will generate their own C files - if {[$obj define get output_c] ne {}} { - continue - } - ::practcl::cputs result [$obj generate-cfunct] - } - return $result - } - - ### - # Generate code that provides implements Tcl API - # calls - ### - method generate-cmethod {} { - debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] - my variable code methods tclprocs - set result {} - if {[info exists code(method)]} { - ::practcl::cputs result $code(method) - } - - if {[info exists tclprocs]} { - foreach {name info} $tclprocs { - if {![dict exists $info body]} continue - set callproc [dict get $info callproc] - set header [dict get $info header] - set body [dict get $info body] - ::practcl::cputs result "${header} \{${body}\}" - } - } - - - if {[info exists methods]} { - set thisclass [my define get cclass] - foreach {name info} $methods { - if {![dict exists $info body]} continue - set callproc [dict get $info callproc] - set header [dict get $info header] - set body [dict get $info body] - ::practcl::cputs result "${header} \{${body}\}" - } - # Build the OO_Init function - ::practcl::cputs result "static int ${thisclass}_OO_Init(Tcl_Interp *interp) \{" - ::practcl::cputs result [string map [list @CCLASS@ $thisclass @TCLCLASS@ [my define get class]] { - /* - ** Build the "@TCLCLASS@" class - */ - Tcl_Obj* nameObj; /* Name of a class or method being looked up */ - Tcl_Object curClassObject; /* Tcl_Object representing the current class */ - Tcl_Class curClass; /* Tcl_Class representing the current class */ - - /* - * Find the "@TCLCLASS@" class, and attach an 'init' method to it. - */ - - nameObj = Tcl_NewStringObj("@TCLCLASS@", -1); - Tcl_IncrRefCount(nameObj); - if ((curClassObject = Tcl_GetObjectFromObj(interp, nameObj)) == NULL) { - Tcl_DecrRefCount(nameObj); - return TCL_ERROR; - } - Tcl_DecrRefCount(nameObj); - curClass = Tcl_GetObjectAsClass(curClassObject); -}] - if {[dict exists $methods constructor]} { - set mtype [dict get $methods constructor methodtype] - ::practcl::cputs result [string map [list @MTYPE@ $mtype] { - /* Attach the constructor to the class */ - Tcl_ClassSetConstructor(interp, curClass, Tcl_NewMethod(interp, curClass, NULL, 1, &@MTYPE@, NULL)); - }] - } - foreach {name info} $methods { - dict with info {} - if {$name in {constructor destructor}} continue - ::practcl::cputs result [string map [list @NAME@ $name @MTYPE@ $methodtype] { - nameObj=Tcl_NewStringObj("@NAME@",-1); - Tcl_NewMethod(interp, curClass, nameObj, 1, &@MTYPE@, (ClientData) NULL); - Tcl_DecrRefCount(nameObj); -}] - if {[dict exists $info aliases]} { - foreach alias [dict get $info aliases] { - if {[dict exists $methods $alias]} continue - ::practcl::cputs result [string map [list @NAME@ $alias @MTYPE@ $methodtype] { - nameObj=Tcl_NewStringObj("@NAME@",-1); - Tcl_NewMethod(interp, curClass, nameObj, 1, &@MTYPE@, (ClientData) NULL); - Tcl_DecrRefCount(nameObj); -}] - } - } - } - ::practcl::cputs result " return TCL_OK\;\n\}\n" - } - foreach obj [my link list dynamic] { - # Exclude products that will generate their own C files - if {[$obj define get output_c] ne {}} continue - ::practcl::cputs result [$obj generate-cmethod] - } - return $result - } - - method generate-cinit-external {} { - if {[my define get initfunc] eq {}} { - return "/* [my define get filename] declared not initfunc */" - } - return " if([my define get initfunc](interp)) return TCL_ERROR\;" - } - - ### - # Generate code that runs when the package/module is - # initialized into the interpreter - ### - method generate-cinit {} { - debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] - set result {} - my variable code methods tclprocs - if {[info exists code(nspace)]} { - ::practcl::cputs result " \{\n Tcl_Namespace *modPtr;" - foreach nspace $code(nspace) { - ::practcl::cputs result [string map [list @NSPACE@ $nspace] { - modPtr=Tcl_FindNamespace(interp,"@NSPACE@",NULL,TCL_NAMESPACE_ONLY); - if(!modPtr) { - modPtr = Tcl_CreateNamespace(interp, "@NSPACE@", NULL, NULL); - } -}] - } - ::practcl::cputs result " \}" - } - if {[info exists code(tclinit)]} { - ::practcl::cputs result $code(tclinit) - } - if {[info exists code(cinit)]} { - ::practcl::cputs result $code(cinit) - } - if {[info exists code(initfuncts)]} { - foreach func $code(initfuncts) { - ::practcl::cputs result " if (${func}(interp) != TCL_OK) return TCL_ERROR\;" - } - } - if {[info exists tclprocs]} { - foreach {name info} $tclprocs { - set map [list @NAME@ $name @CALLPROC@ [dict get $info callproc]] - ::practcl::cputs result [string map $map { Tcl_CreateObjCommand(interp,"@NAME@",(Tcl_ObjCmdProc *)@CALLPROC@,NULL,NULL);}] - if {[dict exists $info aliases]} { - foreach alias [dict get $info aliases] { - set map [list @NAME@ $alias @CALLPROC@ [dict get $info callproc]] - ::practcl::cputs result [string map $map { Tcl_CreateObjCommand(interp,"@NAME@",(Tcl_ObjCmdProc *)@CALLPROC@,NULL,NULL);}] - } - } - } - } - - if {[info exists code(nspace)]} { - ::practcl::cputs result " \{\n Tcl_Namespace *modPtr;" - foreach nspace $code(nspace) { - ::practcl::cputs result [string map [list @NSPACE@ $nspace] { - modPtr=Tcl_FindNamespace(interp,"@NSPACE@",NULL,TCL_NAMESPACE_ONLY); - Tcl_CreateEnsemble(interp, modPtr->fullName, modPtr, TCL_ENSEMBLE_PREFIX); - Tcl_Export(interp, modPtr, "[a-z]*", 1); -}] - } - ::practcl::cputs result " \}" - } - set result [::practcl::_tagblock $result c [my define get filename]] - foreach obj [my link list product] { - # Exclude products that will generate their own C files - if {[$obj define get output_c] ne {}} { - ::practcl::cputs result [$obj generate-cinit-external] - } else { - ::practcl::cputs result [$obj generate-cinit] - } - } - return $result - } - - method c_header body { - my variable code - ::practcl::cputs code(header) $body - } - - method c_code body { - my variable code - ::practcl::cputs code(funct) $body - } - method c_function {header body} { - my variable code cfunct - foreach regexp { - {(.*) ([a-zA-Z_][a-zA-Z0-9_]*) *\((.*)\)} - {(.*) (\x2a[a-zA-Z_][a-zA-Z0-9_]*) *\((.*)\)} - } { - if {[regexp $regexp $header all keywords funcname arglist]} { - dict set cfunct $funcname header $header - dict set cfunct $funcname body $body - dict set cfunct $funcname keywords $keywords - dict set cfunct $funcname arglist $arglist - dict set cfunct $funcname public [expr {"static" ni $keywords}] - dict set cfunct $funcname export [expr {"STUB_EXPORT" in $keywords}] - - return - } - } - ::practcl::cputs code(header) "$header\;" - # Could not parse that block as a function - # append it verbatim to our c_implementation - ::practcl::cputs code(funct) "$header [list $body]" - } - - - method cmethod {name body {arginfo {}}} { - my variable methods code - foreach {f v} $arginfo { - dict set methods $name $f $v - } - dict set methods $name body "Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext); /* The current connection object */ -$body" - } - - method c_tclproc_nspace nspace { - my variable code - if {![info exists code(nspace)]} { - set code(nspace) {} - } - if {$nspace ni $code(nspace)} { - lappend code(nspace) $nspace - } - } - - method c_tclproc_raw {name body {arginfo {}}} { - my variable tclprocs code - - foreach {f v} $arginfo { - dict set tclprocs $name $f $v - } - dict set tclprocs $name body $body - } - - method go {} { - debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] - next - my variable methods code cstruct tclprocs - if {[info exists methods]} { - debug [self] methods [my define get cclass] - set thisclass [my define get cclass] - foreach {name info} $methods { - # Provide a callproc - if {![dict exists $info callproc]} { - set callproc [string map {____ _ ___ _ __ _} [string map {{ } _ : _} OOMethod_${thisclass}_${name}]] - dict set methods $name callproc $callproc - } else { - set callproc [dict get $info callproc] - } - if {[dict exists $info body] && ![dict exists $info header]} { - dict set methods $name header "static int ${callproc}(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext objectContext ,int objc ,Tcl_Obj *const *objv)" - } - if {![dict exists $info methodtype]} { - set methodtype [string map {{ } _ : _} MethodType_${thisclass}_${name}] - dict set methods $name methodtype $methodtype - } - } - if {![info exists code(initfuncts)] || "${thisclass}_OO_Init" ni $code(initfuncts)} { - lappend code(initfuncts) "${thisclass}_OO_Init" - } - } - set thisnspace [my define get nspace] - - if {[info exists tclprocs]} { - debug [self] tclprocs [dict keys $tclprocs] - foreach {name info} $tclprocs { - if {![dict exists $info callproc]} { - set callproc [string map {____ _ ___ _ __ _} [string map {{ } _ : _} Tclcmd_${thisnspace}_${name}]] - dict set tclprocs $name callproc $callproc - } else { - set callproc [dict get $info callproc] - } - if {[dict exists $info body] && ![dict exists $info header]} { - dict set tclprocs $name header "static int ${callproc}(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv\[\])" - } - } - } - debug [list /[self] [self method] [self class]] - } - - # Once an object marks itself as some - # flavor of dynamic, stop trying to morph - # it into something else - method select {} {} - - - method tcltype {name argdat} { - my variable tcltype - foreach {f v} $argdat { - dict set tcltype $name $f $v - } - if {![dict exists tcltype $name cname]} { - dict set tcltype $name cname [string tolower $name]_tclobjtype - } - lappend map @NAME@ $name - set info [dict get $tcltype $name] - foreach {f v} $info { - lappend map @[string toupper $f]@ $v - } - foreach {func fpat template} { - freeproc {@Name@Obj_freeIntRepProc} {void @FNAME@(Tcl_Obj *objPtr)} - dupproc {@Name@Obj_dupIntRepProc} {void @FNAME@(Tcl_Obj *srcPtr,Tcl_Obj *dupPtr)} - updatestringproc {@Name@Obj_updateStringRepProc} {void @FNAME@(Tcl_Obj *objPtr)} - setfromanyproc {@Name@Obj_setFromAnyProc} {int @FNAME@(Tcl_Interp *interp,Tcl_Obj *objPtr)} - } { - if {![dict exists $info $func]} { - error "$name does not define $func" - } - set body [dict get $info $func] - # We were given a function name to call - if {[llength $body] eq 1} continue - set fname [string map [list @Name@ [string totitle $name]] $fpat] - my c_function [string map [list @FNAME@ $fname] $template] [string map $map $body] - dict set tcltype $name $func $fname - } - } -} - -::oo::class create ::practcl::cheader { - superclass ::practcl::product - - method compile-products {} {} - method generate-cinit {} {} -} - -::oo::class create ::practcl::csource { - superclass ::practcl::product -} - -::oo::class create ::practcl::clibrary { - superclass ::practcl::product - - method linker-products {configdict} { - return [my define get filename] - } - -} - -### -# In the end, all C code must be loaded into a module -# This will either be a dynamically loaded library implementing -# a tcl extension, or a compiled in segment of a custom shell/app -### -::oo::class create ::practcl::module { - superclass ::practcl::dynamic - - method child which { - switch $which { - organs { - return [list project [my define get project] module [self]] - } - } - } - - method initialize {} { - set filename [my define get filename] - if {$filename eq {}} { - return - } - if {[my define get name] eq {}} { - my define set name [file tail [file dirname $filename]] - } - if {[my define get localpath] eq {}} { - my define set localpath [my define get name]_[my define get name] - } - debug [self] SOURCE $filename - my source $filename - } - - method implement path { - my go - my Collate_Source $path - foreach item [my link list dynamic] { - if {[catch {$item implement $path} err]} { - puts "Skipped $item: $err" - } - } - foreach item [my link list module] { - if {[catch {$item implement $path} err]} { - puts "Skipped $item: $err" - } - } - debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] - set filename [my define get output_c] - if {$filename eq {}} { - debug [list /[self] [self method] [self class]] - return - } - set cout [open [file join $path [file rootname $filename].c] w] - puts $cout [subst {/* -** This file is generated by the [info script] script -** any changes will be overwritten the next time it is run -*/}] - puts $cout [my generate-c] - puts $cout [my generate-loader] - close $cout - debug [list /[self] [self method] [self class]] - } - - method linktype {} { - return {subordinate product dynamic module} - } -} - -::oo::class create ::practcl::autoconf { - - ### - # find or fake a key/value list describing this project - ### - method config.sh {} { - my variable conf_result - if {[info exists conf_result]} { - return $conf_result - } - set result {} - set name [my define get name] - set PWD $::CWD - set builddir [my define get builddir] - my unpack - set srcroot [my define get srcroot] - if {![file exists $builddir]} { - my Configure - } - set filename [file join $builddir config.tcl] - # Project uses the practcl template. Use the leavings from autoconf - if {[file exists $filename]} { - set dat [::practcl::config.tcl $builddir] - foreach {item value} [lsort -stride 2 -dictionary $dat] { - dict set result $item $value - } - set conf_result $result - return $result - } - set filename [file join $builddir ${name}Config.sh] - if {[file exists $filename]} { - set l [expr {[string length $name]+1}] - foreach {field dat} [::practcl::read_Config.sh $filename] { - set field [string tolower $field] - if {[string match ${name}_* $field]} { - set field [string range $field $l end] - } - dict set result $field $dat - } - set conf_result $result - return $result - } - ### - # Oh man... we have to guess - ### - set filename [file join $builddir Makefile] - if {![file exists $filename]} { - error "Could not locate any configuration data in $srcroot" - } - foreach {field dat} [::practcl::read_Makefile $filename] { - dict set result $field $dat - } - set conf_result $result - cd $PWD - return $result - } -} - - -::oo::class create ::practcl::project { - superclass ::practcl::module ::practcl::autoconf - - constructor args { - my variable define - if {[llength $args] == 1} { - if {[catch {uplevel 1 [list subst [lindex $args 0]]} contents]} { - set contents [lindex $args 0] - } - } else { - if {[catch {uplevel 1 [list subst $args]} contents]} { - set contents $args - } - } - array set define $contents - my select - my initialize - } - - - method add_project {pkg info {oodefine {}}} { - set os [my define get os] - if {$os eq {}} { - set os [::practcl::os] - my define set os $os - } - set fossilinfo [list download [my define get download] tag trunk sandbox [my define get sandbox]] - if {[dict exists $info os] && ($os ni [dict get $info os])} return - # Select which tag to use here. - # For production builds: tag-release - if {[::info exists ::env(FOSSIL_MIRROR)]} { - dict set info localmirror $::env(FOSSIL_MIRROR) - } - set profile [my define get profile release]: - if {[dict exists $info profile $profile]} { - dict set info tag [dict get $info profile $profile] - } - set obj [namespace current]::PROJECT.$pkg - if {[info command $obj] eq {}} { - set obj [::practcl::subproject create $obj [self] [dict merge $fossilinfo [list name $pkg pkg_name $pkg static 0] $info]] - } - my link object $obj - oo::objdefine $obj $oodefine - $obj define set masterpath $::CWD - $obj go - return $obj - } - - method child which { - switch $which { - organs { - # A library can be a project, it can be a module. Any - # subordinate modules will indicate their existance - return [list project [self] module [self]] - } - } - } - - method linktype {} { - return project - } - - # Exercise the methods of a sub-object - method project {pkg args} { - set obj [namespace current]::PROJECT.$pkg - if {[llength $args]==0} { - return $obj - } - tailcall ${obj} {*}$args - } -} - -::oo::class create ::practcl::library { - superclass ::practcl::project - - method compile-products {} { - set result {} - foreach item [my link list subordinate] { - lappend result {*}[$item compile-products] - } - set filename [my define get output_c] - if {$filename ne {}} { - set ofile [file rootname [file tail $filename]]_main.o - lappend result $ofile [list cfile $filename extra [my define get extra] external [string is true -strict [my define get external]]] - } - return $result - } - - method generate-tcl-loader {} { - set result {} - set PKGINIT [my define get pkginit] - set PKG_NAME [my define get name [my define get pkg_name]] - set PKG_VERSION [my define get pkg_vers [my define get version]] - if {[string is true [my define get SHARED_BUILD 0]]} { - set LIBFILE [my define get libfile] - ::practcl::cputs result [string map \ - [list @LIBFILE@ $LIBFILE @PKGINIT@ $PKGINIT @PKG_NAME@ $PKG_NAME @PKG_VERSION@ $PKG_VERSION] { -# Shared Library Style -load [file join [file dirname [file join [pwd] [info script]]] @LIBFILE@] @PKGINIT@ -package provide @PKG_NAME@ @PKG_VERSION@ -}] - } else { - ::practcl::cputs result [string map \ - [list @PKGINIT@ $PKGINIT @PKG_NAME@ $PKG_NAME @PKG_VERSION@ $PKG_VERSION] { -# Tclkit Style -load {} @PKGINIT@ -package provide @PKG_NAME@ @PKG_VERSION@ -}] - } - return $result - } - - method go {} { - debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] - set name [my define getnull name] - if {$name eq {}} { - set name generic - my define name generic - } - if {[my define get tk] eq {@TEA_TK_EXTENSION@}} { - my define set tk 0 - } - set output_c [my define getnull output_c] - if {$output_c eq {}} { - set output_c [file rootname $name].c - my define set output_c $output_c - } - set output_h [my define getnull output_h] - if {$output_h eq {}} { - set output_h [file rootname $output_c].h - my define set output_h $output_h - } - set output_tcl [my define getnull output_tcl] - #if {$output_tcl eq {}} { - # set output_tcl [file rootname $output_c].tcl - # my define set output_tcl $output_tcl - #} - #set output_mk [my define getnull output_mk] - #if {$output_mk eq {}} { - # set output_mk [file rootname $output_c].mk - # my define set output_mk $output_mk - #} - set initfunc [my define getnull initfunc] - if {$initfunc eq {}} { - set initfunc [string totitle $name]_Init - my define set initfunc $initfunc - } - set output_decls [my define getnull output_decls] - if {$output_decls eq {}} { - set output_decls [file rootname $output_c].decls - my define set output_decls $output_decls - } - my variable links - foreach {linktype objs} [array get links] { - foreach obj $objs { - $obj go - } - } - debug [list /[self] [self method] [self class] -- [my define get filename] [info object class [self]]] - } - - method implement path { - my go - my Collate_Source $path - foreach item [my link list dynamic] { - if {[catch {$item implement $path} err]} { - puts "Skipped $item: $err" - } - } - foreach item [my link list module] { - if {[catch {$item implement $path} err]} { - puts "Skipped $item: $err" - } - } - set cout [open [file join $path [my define get output_c]] w] - puts $cout [subst {/* -** This file is generated by the [info script] script -** any changes will be overwritten the next time it is run -*/}] - puts $cout [my generate-c] - puts $cout [my generate-loader] - close $cout - - set macro HAVE_[string toupper [file rootname [my define get output_h]]]_H - set hout [open [file join $path [my define get output_h]] w] - puts $hout [subst {/* -** This file is generated by the [info script] script -** any changes will be overwritten the next time it is run -*/}] - puts $hout "#ifndef ${macro}" - puts $hout "#define ${macro}" - puts $hout [my generate-h] - puts $hout "#endif" - close $hout - - set output_tcl [my define get output_tcl] - if {$output_tcl ne {}} { - set tclout [open [file join $path [my define get output_tcl]] w] - puts $tclout "### -# This file is generated by the [info script] script -# any changes will be overwritten the next time it is run -###" - puts $tclout [my generate-tcl] - puts $tclout [my generate-tcl-loader] - close $tclout - } - } - - method generate-decls {pkgname path} { - debug [list [self] [self method] [self class] -- [my define get filename] [info object class [self]]] - set outfile [file join $path/$pkgname.decls] - - ### - # Build the decls file - ### - set fout [open $outfile w] - puts $fout [subst {### - # $outfile - # - # This file was generated by [info script] - ### - - library $pkgname - interface $pkgname - }] - - ### - # Generate list of functions - ### - set stubfuncts [my generate-stub-function] - set thisline {} - set functcount 0 - foreach {func header} $stubfuncts { - puts $fout [list declare [incr functcount] $header] - } - puts $fout [list export "int [my define get initfunc](Tcl_Inter *interp)"] - puts $fout [list export "char *[string totitle [my define get name]]_InitStubs(Tcl_Inter *interp, char *version, int exact)"] - - close $fout - - ### - # Build [package]Decls.h - ### - set hout [open [file join $path ${pkgname}Decls.h] w] - - close $hout - - set cout [open [file join $path ${pkgname}StubInit.c] w] -puts $cout [string map [list %pkgname% $pkgname %PkgName% [string totitle $pkgname]] { -#ifndef USE_TCL_STUBS -#define USE_TCL_STUBS -#endif -#undef USE_TCL_STUB_PROCS - -#include "tcl.h" -#include "%pkgname%.h" - - /* - ** Ensure that Tdom_InitStubs is built as an exported symbol. The other stub - ** functions should be built as non-exported symbols. - */ - -#undef TCL_STORAGE_CLASS -#define TCL_STORAGE_CLASS DLLEXPORT - -%PkgName%Stubs *%pkgname%StubsPtr; - - /* - **---------------------------------------------------------------------- - ** - ** %PkgName%_InitStubs -- - ** - ** Checks that the correct version of %PkgName% is loaded and that it - ** supports stubs. It then initialises the stub table pointers. - ** - ** Results: - ** The actual version of %PkgName% that satisfies the request, or - ** NULL to indicate that an error occurred. - ** - ** Side effects: - ** Sets the stub table pointers. - ** - **---------------------------------------------------------------------- - */ - -char * -%PkgName%_InitStubs (Tcl_Interp *interp, char *version, int exact) -{ - char *actualVersion; - actualVersion = Tcl_PkgRequireEx(interp, "%pkgname%", version, exact,(ClientData *) &%pkgname%StubsPtr); - if (!actualVersion) { - return NULL; - } - if (!%pkgname%StubsPtr) { - Tcl_SetResult(interp,"This implementation of %PkgName% does not support stubs",TCL_STATIC); - return NULL; - } - return actualVersion; -} -}] - close $cout - } - - # Backward compadible call - method generate-make path { - ::practcl::build::Makefile $path [self] - } - - method install-headers {} { - set result {} - return $result - } - - method linktype {} { - return library - } - - # Create a "package ifneeded" - # Args are a list of aliases for which this package will answer to - method package-ifneeded {args} { - set result {} - set name [my define get pkg_name [my define get name]] - set version [my define get pkg_vers [my define get version]] - if {$version eq {}} { - set version 0.1a - } - set output_tcl [my define get output_tcl] - if {$output_tcl ne {}} { - set script "\[list source \[file join \$dir $output_tcl\]\]" - } elseif {[string is true -strict [my define get SHARED_BUILD]]} { - set script "\[list load \[file join \$dir [my define get libfile]\] $name\]" - } else { - # Provide a null passthrough - set script [list package provide $name $version] - } - set result "package ifneeded [list $name] [list $version] $script" - foreach alias $args { - set script "package require $name $version \; package provide $alias $version" - append result \n\n [list package ifneeded $alias $version $script] - } - return $result - } - - - method shared_library {} { - set name [string tolower [my define get name [my define get pkg_name]]] - set NAME [string toupper $name] - set version [my define get version [my define get pkg_vers]] - set map {} - lappend map %LIBRARY_NAME% $name - lappend map %LIBRARY_VERSION% $version - lappend map %LIBRARY_VERSION_NODOTS% [string map {. {}} $version] - lappend map %LIBRARY_PREFIX% [my define getnull libprefix] - set outfile [string map $map [my define get PRACTCL_NAME_LIBRARY]][my define get SHLIB_SUFFIX] - return $outfile - } -} - -::oo::class create ::practcl::tclkit { - superclass ::practcl::library - - method Collate_Source CWD { - my define set SHARED_BUILD 0 - set name [my define get name] - - if {![my define exists TCL_LOCAL_APPINIT]} { - my define set TCL_LOCAL_APPINIT Tclkit_AppInit - } - if {![my define exists TCL_LOCAL_MAIN_HOOK]} { - my define set TCL_LOCAL_MAIN_HOOK Tclkit_MainHook - } - - set PROJECT [self] - set os [$PROJECT define get os] - set TCLOBJ [$PROJECT project TCLCORE] - set TKOBJ [$PROJECT project TKCORE] - set ODIEOBJ [$PROJECT project odie] - - set TCLSRCDIR [$TCLOBJ define get srcroot] - set TKSRCDIR [$TKOBJ define get srcroot] - set PKG_OBJS {} - foreach item [$PROJECT link list package] { - if {[string is true [$item define get static]]} { - lappend PKG_OBJS $item - } - } - # Arrange to build an main.c that utilizes TCL_LOCAL_APPINIT and TCL_LOCAL_MAIN_HOOK - if {$os eq "windows"} { - set PLATFORM_SRC_DIR win - my add class csource filename [file join $TCLSRCDIR win tclWinReg.c] initfunc Registry_Init pkg_name registry pkg_vers 1.3.1 autoload 1 - my add class csource filename [file join $TCLSRCDIR win tclWinDde.c] initfunc Dde_Init pkg_name dde pkg_vers 1.4.0 autoload 1 - my add class csource ofile [my define get name]_appinit.o filename [file join $TCLSRCDIR win tclAppInit.c] extra [list -DTCL_LOCAL_MAIN_HOOK=[my define get TCL_LOCAL_MAIN_HOOK Tclkit_MainHook] -DTCL_LOCAL_APPINIT=[my define get TCL_LOCAL_APPINIT Tclkit_AppInit]] - } else { - set PLATFORM_SRC_DIR unix - my add class csource ofile [my define get name]_appinit.o filename [file join $TCLSRCDIR unix tclAppInit.c] extra [list -DTCL_LOCAL_MAIN_HOOK=[my define get TCL_LOCAL_MAIN_HOOK Tclkit_MainHook] -DTCL_LOCAL_APPINIT=[my define get TCL_LOCAL_APPINIT Tclkit_AppInit]] - } - - ### - # Pre 8.7, Tcl doesn't include a Zipfs implementation - # in the core. Grab the one from odielib - ### - set zipfs [file join $TCLSRCDIR generic tclZipfs.c] - if {[file exists $zipfs]} { - my define set CORE_ZIPFS 1 - } else { - ### - # Add local static Zlib implementation - ### - set cdir [file join $TCLSRCDIR compat zlib] - foreach file { - adler32.c compress.c crc32.c - deflate.c infback.c inffast.c - inflate.c inftrees.c trees.c - uncompr.c zutil.c - } { - my add [file join $cdir $file] - } - # The Odie project maintains a mirror of the version - # released with the Tcl core - my define set CORE_ZIPFS 0 - my add_project odie { - tag trunk - class subproject - vfsinstall 0 - } - my project odie unpack - set ODIESRCROOT [my project odie define get srcroot] - set cdir [file join $ODIESRCROOT compat zipfs] - my define add include_dir $cdir - set zipfs [file join $cdir zvfs.c] - my add class csource filename $zipfs initfunc Tclzipfs_Init pkg_name zipfs pkg_vers 1.0 autoload 1 - } - - - my define add include_dir [file join $TKSRCDIR generic] - my define add include_dir [file join $TKSRCDIR $PLATFORM_SRC_DIR] - my define add include_dir [file join $TKSRCDIR bitmaps] - my define add include_dir [file join $TKSRCDIR xlib] - my define add include_dir [file join $TCLSRCDIR generic] - my define add include_dir [file join $TCLSRCDIR $PLATFORM_SRC_DIR] - my define add include_dir [file join $TCLSRCDIR compat zlib] - # This file will implement TCL_LOCAL_APPINIT and TCL_LOCAL_MAIN_HOOK - ::practcl::build::tclkit_main $PROJECT $PKG_OBJS - } - - ## Wrap an executable - # - method wrap {PWD exename vfspath args} { - cd $PWD - if {![file exists $vfspath]} { - file mkdir $vfspath - } - foreach item [my link list core.library] { - set name [$item define get name] - set libsrcroot [$item define get srcroot] - if {[file exists [file join $libsrcroot library]]} { - ::practcl::copyDir [file join $libsrcroot library] [file join $vfspath boot $name] - } - } - if {[my define get installdir] ne {}} { - ::practcl::copyDir [file join [my define get installdir] [string trimleft [my define get prefix] /] lib] [file join $vfspath lib] - } - foreach arg $args { - ::practcl::copyDir $arg $vfspath - } - - set fout [open [file join $vfspath packages.tcl] w] - puts $fout { - set ::PKGIDXFILE [info script] - set dir [file dirname $::PKGIDXFILE] - } - #set BASEVFS [my define get BASEVFS] - set EXEEXT [my define get EXEEXT] - - set tclkit_bare [my define get tclkit_bare] - - set buffer [::practcl::pkgindex_path $vfspath] - puts $fout $buffer - puts $fout { - # Advertise statically linked packages - foreach {pkg script} [array get ::kitpkg] { - eval $script - } - } - close $fout - package require zipfile::mkzip - ::zipfile::mkzip::mkzip ${exename}${EXEEXT} -runtime $tclkit_bare -directory $vfspath - if { [my define get platform] ne "windows" } { - file attributes ${exename}${EXEEXT} -permissions a+x - } - } -} - -### -# Meta repository -# The default is an inert source code block -### -oo::class create ::practcl::subproject { - superclass ::practcl::object - - method compile {} {} - - method go {} { - set platform [my define get platform] - my define get USEMSVC [my define get USEMSVC] - set name [my define get name] - if {![my define exists srcroot]} { - my define set srcroot [file join [my define get sandbox] $name] - } - set srcroot [my define get srcroot] - my define set localsrcdir $srcroot - my define add include_dir [file join $srcroot generic] - my sources - } - - # Install project into the local build system - method install-local {} { - my unpack - } - - # Install project into the virtual file system - method install-vfs {} {} - - method linktype {} { - return {subordinate package} - } - - method linker-products {configdict} {} - - method linker-external {configdict} { - if {[dict exists $configdict PRACTCL_LIBS]} { - return [dict get $configdict PRACTCL_LIBS] - } - } - - method sources {} {} - - method unpack {} { - set name [my define get name] - puts [list $name [self] UNPACK] - my define set [::practcl::fossil_sandbox $name [my define dump]] - } - - method update {} { - set name [my define get name] - my define set [::practcl::fossil_sandbox $name [dict merge [my define dump] {update 1}]] - } -} - -### -# A project which the kit compiles and integrates -# the source for itself -### -oo::class create ::practcl::subproject.source { - superclass ::practcl::subproject ::practcl::library - - method linktype {} { - return {subordinate package source} - } - -} - -# a copy from the teapot -oo::class create ::practcl::subproject.teapot { - superclass ::practcl::subproject - - method install-local {} { - my install-vfs - } - - method install-vfs {} { - set pkg [my define get pkg_name [my define get name]] - set download [my define get download] - my unpack - set DEST [my define get installdir] - set prefix [string trimleft [my define get prefix] /] - # Get tcllib from our destination - set dir [file join $DEST $prefix lib tcllib] - source [file join $DEST $prefix lib tcllib pkgIndex.tcl] - package require zipfile::decode - ::zipfile::decode::unzipfile [file join $download $pkg.zip] [file join $DEST $prefix lib $pkg] - } -} - -oo::class create ::practcl::subproject.sak { - superclass ::practcl::subproject - - method install-local {} { - my install-vfs - } - - method install-vfs {} { - ### - # Handle teapot installs - ### - set pkg [my define get pkg_name [my define get name]] - my unpack - set DEST [my define get installdir] - set prefix [string trimleft [my define get prefix] /] - set srcroot [my define get srcroot] - ::dotclexec [file join $srcroot installer.tcl] \ - -pkg-path [file join $DEST $prefix lib $pkg] \ - -no-examples -no-html -no-nroff \ - -no-wait -no-gui -no-apps - } -} - -### -# A binary package -### -oo::class create ::practcl::subproject.binary { - superclass ::practcl::subproject ::practcl::autoconf - - - method compile-products {} {} - - method ConfigureOpts {} { - set opts {} - set builddir [my define get builddir] - if {[my define get broken_destroot 0]} { - set PREFIX [my define get prefix_broken_destdir] - } else { - set PREFIX [my define get prefix] - } - if {[my define get HOST] != [my define get TARGET]} { - lappend opts --host=[my define get TARGET] - } - if {[my define exists tclsrcdir]} { - set TCLSRCDIR [::practcl::file_relative [file normalize $builddir] [file normalize [file join $::CWD [my define get tclsrcdir]]]] - set TCLGENERIC [::practcl::file_relative [file normalize $builddir] [file normalize [file join $::CWD [my define get tclsrcdir] .. generic]]] - lappend opts --with-tcl=$TCLSRCDIR --with-tclinclude=$TCLGENERIC - } - if {[my define exists tksrcdir]} { - set TKSRCDIR [::practcl::file_relative [file normalize $builddir] [file normalize [file join $::CWD [my define get tksrcdir]]]] - set TKGENERIC [::practcl::file_relative [file normalize $builddir] [file normalize [file join $::CWD [my define get tksrcdir] .. generic]]] - lappend opts --with-tk=$TKSRCDIR --with-tkinclude=$TKGENERIC - } - lappend opts {*}[my define get config_opts] - lappend opts --prefix=$PREFIX - #--exec_prefix=$PREFIX - #if {$::tcl_platform(platform) eq "windows"} { - # lappend opts --disable-64bit - #} - if {[my define get static 1]} { - lappend opts --disable-shared --disable-stubs - # - } else { - lappend opts --enable-shared - } - return $opts - } - - method go {} { - next - my define set builddir [my BuildDir [my define get masterpath]] - } - - method linker-products {configdict} { - if {![my define get static 0]} { - return {} - } - set srcdir [my define get builddir] - if {[dict exists $configdict libfile]} { - return " [file join $srcdir [dict get $configdict libfile]]" - } - } - - method static-packages {} { - if {![my define get static 0]} { - return {} - } - set result [my define get static_packages] - set statpkg [my define get static_pkg] - set initfunc [my define get initfunc] - if {$initfunc ne {}} { - set pkg_name [my define get pkg_name] - if {$pkg_name ne {}} { - dict set result $pkg_name initfunc $initfunc - set version [my define get version] - if {$version eq {}} { - set info [my config.sh] - set version [dict get $info version] - set pl {} - if {[dict exists $info patch_level]} { - set pl [dict get $info patch_level] - append version $pl - } - my define set version $version - } - dict set result $pkg_name version $version - dict set result $pkg_name autoload [my define get autoload 0] - } - } - foreach item [my link list subordinate] { - foreach {pkg info} [$item static-packages] { - dict set result $pkg $info - } - } - return $result - } - - method BuildDir {PWD} { - set name [my define get name] - return [my define get builddir [file join $PWD pkg.$name]] - } - - method compile {} { - set name [my define get name] - set PWD $::CWD - cd $PWD - my go - set srcroot [file normalize [my define get srcroot]] - my Collate_Source $PWD - - ### - # Build a starter VFS for both Tcl and wish - ### - set srcroot [my define get srcroot] - if {[my define get static 1]} { - puts "BUILDING Static $name $srcroot" - } else { - puts "BUILDING Dynamic $name $srcroot" - } - if {[my define get USEMSVC 0]} { - cd $srcroot - doexec nmake -f makefile.vc INSTALLDIR=[my define get installdir] release - } else { - cd $::CWD - set builddir [file normalize [my define get builddir]] - file mkdir $builddir - if {![file exists [file join $builddir Makefile]]} { - my Configure - } - if {[file exists [file join $builddir make.tcl]]} { - domake.tcl $builddir library - } else { - domake $builddir all - } - } - cd $PWD - } - - - method Configure {} { - cd $::CWD - my unpack - my TeaConfig - set builddir [file normalize [my define get builddir]] - file mkdir $builddir - set srcroot [file normalize [my define get srcroot]] - if {[my define get USEMSVC 0]} { - return - } - set opts [my ConfigureOpts] - puts [list [self] CONFIGURE] - puts [list PWD [pwd]] - puts [list LOCALSRC $srcroot] - puts [list BUILDDIR $builddir] - puts [list CONFIGURE {*}$opts] - cd $builddir - exec sh [file join $srcroot configure] {*}$opts >& [file join $builddir practcl.log] - cd $::CWD - } - - method install-vfs {} { - set PWD [pwd] - set PKGROOT [my define get installdir] - set PREFIX [my define get prefix] - - ### - # Handle teapot installs - ### - set pkg [my define get pkg_name [my define get name]] - if {[my define get teapot] ne {}} { - set TEAPOT [my define get teapot] - set found 0 - foreach ver [my define get pkg_vers [my define get version]] { - set teapath [file join $TEAPOT $pkg$ver] - if {[file exists $teapath]} { - set dest [file join $PKGROOT [string trimleft $PREFIX /] lib [file tail $teapath]] - ::practcl::copyDir $teapath $dest - return - } - } - } - my compile - if {[my define get USEMSVC 0]} { - set srcroot [my define get srcroot] - cd $srcroot - puts "[self] VFS INSTALL $PKGROOT" - doexec nmake -f makefile.vc INSTALLDIR=$PKGROOT install - } else { - set builddir [my define get builddir] - if {[file exists [file join $builddir make.tcl]]} { - # Practcl builds can inject right to where we need them - puts "[self] VFS INSTALL $PKGROOT (Practcl)" - domake.tcl $builddir install-package $PKGROOT - } elseif {[my define get broken_destroot 0] == 0} { - # Most modern TEA projects understand DESTROOT in the makefile - puts "[self] VFS INSTALL $PKGROOT (TEA)" - domake $builddir install DESTDIR=$PKGROOT - } else { - # But some require us to do an install into a fictitious filesystem - # and then extract the gooey parts within. - # (*cough*) TkImg - set PREFIX [my define get prefix] - set BROKENROOT [::practcl::msys_to_tclpath [my define get prefix_broken_destdir]] - file delete -force $BROKENROOT - file mkdir $BROKENROOT - domake $builddir $install - ::practcl::copyDir $BROKENROOT [file join $PKGROOT [string trimleft $PREFIX /]] - file delete -force $BROKENROOT - } - } - cd $PWD - } - - method TeaConfig {} { - set srcroot [file normalize [my define get srcroot]] - set copytea 0 - if {![file exists [file join $srcroot tclconfig]]} { - set copytea 1 - } else { - if {![file exists [file join $srcroot tclconfig practcl.tcl]] || ![file exists [file join $srcroot tclconfig config.tcl.in]]} { - set copytea 1 - } - } - # ensure we have tclconfig with all of the trimming - if {$copytea} { - set tclconfiginfo [::practcl::fossil_sandbox tclconfig [list sandbox [my define get sandbox]]] - ::practcl::copyDir [dict get $tclconfiginfo srcroot] [file join $srcroot tclconfig] - if {$::tcl_platform(platform) ne "windows"} { - set pwd [pwd] - cd $srcroot - # On windows there's no practical way to execute - # autoconf. We'll have to trust that configure - # us up to date - foreach template {configure.ac configure.in} { - set input [file join $srcroot $template] - if {[file exists $input]} { - puts "autoconf -f $input > [file join $srcroot configure]" - exec autoconf -f $input > [file join $srcroot configure] - } - } - cd $pwd - } - } - } -} - -oo::class create ::practcl::subproject.core { - superclass ::practcl::subproject.binary - - # On the windows platform MinGW must build - # from the platform directory in the source repo - method BuildDir {PWD} { - return [my define get localsrcdir] - } - - method Configure {} { - if {[my define get USEMSVC 0]} { - return - } - set opts [my ConfigureOpts] - puts [list PWD [pwd]] - puts [list [self] CONFIGURE] - set builddir [file normalize [my define get builddir]] - set localsrcdir [file normalize [my define get localsrcdir]] - puts [list LOCALSRC $localsrcdir] - puts [list BUILDDIR $builddir] - puts [list CONFIGURE {*}$opts] - cd $localsrcdir - exec sh [file join $localsrcdir configure] {*}$opts >& [file join $builddir practcl.log] - } - - method ConfigureOpts {} { - set opts {} - set builddir [file normalize [my define get builddir]] - set PREFIX [my define get prefix] - if {[my define get HOST] != [my define get TARGET]} { - lappend opts --host=[my define get TARGET] - } - lappend opts {*}[my define get config_opts] - lappend opts --prefix=$PREFIX - #--exec_prefix=$PREFIX - lappend opts --disable-shared - return $opts - } - - method go {} { - set name [my define get name] - set platform [my define get platform] - if {![my define exists srcroot]} { - my define set srcroot [file join [my define get sandbox] $name] - } - set srcroot [my define get srcroot] - my define add include_dir [file join $srcroot generic] - switch $platform { - windows { - my define set localsrcdir [file join $srcroot win] - my define add include_dir [file join $srcroot win] - } - default { - my define set localsrcdir [file join $srcroot unix] - my define add include_dir [file join $srcroot $name unix] - } - } - my define set builddir [my BuildDir [my define get masterpath]] - } - - method linktype {} { - return {subordinate core.library} - } -} - -package provide practcl 0.5 diff --git a/library/zvfstools/pkgIndex.tcl b/library/zvfstools/pkgIndex.tcl deleted file mode 100644 index 824d5b3..0000000 --- a/library/zvfstools/pkgIndex.tcl +++ /dev/null @@ -1 +0,0 @@ -package ifneeded zvfstools 0.1 [list source [file join $dir zvfstools.tcl]] diff --git a/library/zvfstools/zvfstools.tcl b/library/zvfstools/zvfstools.tcl deleted file mode 100644 index 274d5a1..0000000 --- a/library/zvfstools/zvfstools.tcl +++ /dev/null @@ -1,325 +0,0 @@ -# -*- tcl -*- -# ### ### ### ######### ######### ######### -## Copyright (c) 2008-2009 ActiveState Software Inc. -## Andreas Kupries -## Copyright (C) 2009 Pat Thoyts -## Copyright (C) 2014 Sean Woods -## -## BSD License -## -# Package providing commands for: -# * the generation of a zip archive, -# * building a zip archive from a file system -# * building a file system from a zip archive - -package require Tcl 8.6 -# Cop -# -# Create ZIP archives in Tcl. -# -# Create a zipkit using mkzip filename.zkit -zipkit -directory xyz.vfs -# or a zipfile using mkzip filename.zip -directory dirname -exclude "*~" -# - -namespace eval ::zvfs {} - -proc ::zvfs::setbinary chan { - fconfigure $chan \ - -encoding binary \ - -translation binary \ - -eofchar {} - -} - -# zip::timet_to_dos -# -# Convert a unix timestamp into a DOS timestamp for ZIP times. -# -# DOS timestamps are 32 bits split into bit regions as follows: -# 24 16 8 0 -# +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ -# |Y|Y|Y|Y|Y|Y|Y|m| |m|m|m|d|d|d|d|d| |h|h|h|h|h|m|m|m| |m|m|m|s|s|s|s|s| -# +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ -# -proc ::zvfs::timet_to_dos {time_t} { - set s [clock format $time_t -format {%Y %m %e %k %M %S}] - scan $s {%d %d %d %d %d %d} year month day hour min sec - expr {(($year-1980) << 25) | ($month << 21) | ($day << 16) - | ($hour << 11) | ($min << 5) | ($sec >> 1)} -} - -# zip::pop -- -# -# Pop an element from a list -# -proc ::zvfs::pop {varname {nth 0}} { - upvar $varname args - set r [lindex $args $nth] - set args [lreplace $args $nth $nth] - return $r -} - -# zip::walk -- -# -# Walk a directory tree rooted at 'path'. The excludes list can be -# a set of glob expressions to match against files and to avoid. -# The match arg is internal. -# eg: walk library {CVS/* *~ .#*} to exclude CVS and emacs cruft. -# -proc ::zvfs::walk {base {excludes ""} {match *} {path {}}} { - set result {} - set imatch [file join $path $match] - set files [glob -nocomplain -tails -types f -directory $base $imatch] - foreach file $files { - set excluded 0 - foreach glob $excludes { - if {[string match $glob $file]} { - set excluded 1 - break - } - } - if {!$excluded} {lappend result $file} - } - foreach dir [glob -nocomplain -tails -types d -directory $base $imatch] { - lappend result $dir - set subdir [walk $base $excludes $match $dir] - if {[llength $subdir]>0} { - set result [concat $result [list $dir] $subdir] - } - } - return $result -} - -# zvfs::add_file_to_archive -- -# -# Add a single file to a zip archive. The zipchan channel should -# already be open and binary. You may provide a comment for the -# file The return value is the central directory record that -# will need to be used when finalizing the zip archive. -# -# FIX ME: should handle the current offset for non-seekable channels -# -proc ::zvfs::add_file_to_archive {zipchan base path {comment ""}} { - set fullpath [file join $base $path] - set mtime [timet_to_dos [file mtime $fullpath]] - if {[file isdirectory $fullpath]} { - append path / - } - set utfpath [encoding convertto utf-8 $path] - set utfcomment [encoding convertto utf-8 $comment] - set flags [expr {(1<<11)}] ;# utf-8 comment and path - set method 0 ;# store 0, deflate 8 - set attr 0 ;# text or binary (default binary) - set version 20 ;# minumum version req'd to extract - set extra "" - set crc 0 - set size 0 - set csize 0 - set data "" - set seekable [expr {[tell $zipchan] != -1}] - if {[file isdirectory $fullpath]} { - set attrex 0x41ff0010 ;# 0o040777 (drwxrwxrwx) - } elseif {[file executable $fullpath]} { - set attrex 0x81ff0080 ;# 0o100777 (-rwxrwxrwx) - } else { - set attrex 0x81b60020 ;# 0o100666 (-rw-rw-rw-) - if {[file extension $fullpath] in {".tcl" ".txt" ".c"}} { - set attr 1 ;# text - } - } - - if {[file isfile $fullpath]} { - set size [file size $fullpath] - if {!$seekable} {set flags [expr {$flags | (1 << 3)}]} - } - - set offset [tell $zipchan] - set local [binary format a4sssiiiiss PK\03\04 \ - $version $flags $method $mtime $crc $csize $size \ - [string length $utfpath] [string length $extra]] - append local $utfpath $extra - puts -nonewline $zipchan $local - - if {[file isfile $fullpath]} { - # If the file is under 2MB then zip in one chunk, otherwize we use - # streaming to avoid requiring excess memory. This helps to prevent - # storing re-compressed data that may be larger than the source when - # handling PNG or JPEG or nested ZIP files. - if {$size < 0x00200000} { - set fin [::open $fullpath rb] - setbinary $fin - set data [::read $fin] - set crc [::zlib crc32 $data] - set cdata [::zlib deflate $data] - if {[string length $cdata] < $size} { - set method 8 - set data $cdata - } - close $fin - set csize [string length $data] - puts -nonewline $zipchan $data - } else { - set method 8 - set fin [::open $fullpath rb] - setbinary $fin - set zlib [::zlib stream deflate] - while {![eof $fin]} { - set data [read $fin 4096] - set crc [zlib crc32 $data $crc] - $zlib put $data - if {[string length [set zdata [$zlib get]]]} { - incr csize [string length $zdata] - puts -nonewline $zipchan $zdata - } - } - close $fin - $zlib finalize - set zdata [$zlib get] - incr csize [string length $zdata] - puts -nonewline $zipchan $zdata - $zlib close - } - - if {$seekable} { - # update the header if the output is seekable - set local [binary format a4sssiiii PK\03\04 \ - $version $flags $method $mtime $crc $csize $size] - set current [tell $zipchan] - seek $zipchan $offset - puts -nonewline $zipchan $local - seek $zipchan $current - } else { - # Write a data descriptor record - set ddesc [binary format a4iii PK\7\8 $crc $csize $size] - puts -nonewline $zipchan $ddesc - } - } - - set hdr [binary format a4ssssiiiisssssii PK\01\02 0x0317 \ - $version $flags $method $mtime $crc $csize $size \ - [string length $utfpath] [string length $extra]\ - [string length $utfcomment] 0 $attr $attrex $offset] - append hdr $utfpath $extra $utfcomment - return $hdr -} - -# zvfs::mkzip -- -# -# Create a zip archive in 'filename'. If a file already exists it will be -# overwritten by a new file. If '-directory' is used, the new zip archive -# will be rooted in the provided directory. -# -runtime can be used to specify a prefix file. For instance, -# zip myzip -runtime unzipsfx.exe -directory subdir -# will create a self-extracting zip archive from the subdir/ folder. -# The -comment parameter specifies an optional comment for the archive. -# -# eg: zip my.zip -directory Subdir -runtime unzipsfx.exe *.txt -# -proc ::zvfs::mkzip {filename args} { - array set opts { - -zipkit 0 -runtime "" -comment "" -directory "" - -exclude {CVS/* */CVS/* *~ ".#*" "*/.#*"} - } - - while {[string match -* [set option [lindex $args 0]]]} { - switch -exact -- $option { - -zipkit { set opts(-zipkit) 1 } - -comment { set opts(-comment) [encoding convertto utf-8 [pop args 1]] } - -runtime { set opts(-runtime) [pop args 1] } - -directory {set opts(-directory) [file normalize [pop args 1]] } - -exclude {set opts(-exclude) [pop args 1] } - -- { pop args ; break } - default { - break - } - } - pop args - } - - set zf [::open $filename wb] - setbinary $zf - if {$opts(-runtime) ne ""} { - set rt [::open $opts(-runtime) rb] - setbinary $rt - fcopy $rt $zf - close $rt - } elseif {$opts(-zipkit)} { - set zkd {#!/usr/bin/env tclsh -# This is a zip-based Tcl Module -if {![package vsatisfies [package provide zvfs] 1.0]} { - package require vfs::zip - vfs::zip::Mount [info script] [info script] -} else { - zvfs::mount [info script] [info script] -} -# Load any CLIP file present -if {[file exists [file join [info script] pkgIndex.tcl]] } { - set dir [info script] - source [file join [info script] pkgIndex.tcl] -} -# Run any main.tcl present -if {[file exists [file join [info script] main.tcl]] } { - source [file join [info script] main.tcl] -} - } - append zkd \x1A - puts -nonewline $zf $zkd - } - - set count 0 - set cd "" - - if {$opts(-directory) ne ""} { - set paths [walk $opts(-directory) $opts(-exclude)] - } else { - set paths [glob -nocomplain {*}$args] - } - foreach path $paths { - append cd [add_file_to_archive $zf $opts(-directory) $path] - incr count - } - set cdoffset [tell $zf] - set endrec [binary format a4ssssiis PK\05\06 0 0 \ - $count $count [string length $cd] $cdoffset\ - [string length $opts(-comment)]] - append endrec $opts(-comment) - puts -nonewline $zf $cd - puts -nonewline $zf $endrec - close $zf - - return -} - -### -# Decode routines -### -proc ::zvfs::copy_file {zipbase destbase file} { - set l [string length $zipbase] - set relname [string trimleft [string range $file $l end] /] - if {[file isdirectory $file]} { - foreach sfile [glob -nocomplain $file/*] { - file mkdir [file join $destbase $relname] - copy_file $zipbase $destbase $sfile - } - return - } - file copy -force $file [file join $destbase $relname] -} - -# ### ### ### ######### ######### ######### -## Convenience command, decode and copy to dir -## This routine relies on zvfs::mount, so we only load -## it when the zvfs package is present -## -proc ::zvfs::unzip {in out} { - package require zvfs 1.0 - set root /ziptmp#[incr ::zvfs::count] - zvfs::mount $in $root - set out [file normalize $out] - foreach file [glob $root/*] { - copy_file $root $out $file - } - zvfs::unmount $in - return -} -package provide zvfstools 0.1 diff --git a/pkgs/make.tcl b/pkgs/make.tcl deleted file mode 100644 index 94a4050..0000000 --- a/pkgs/make.tcl +++ /dev/null @@ -1,165 +0,0 @@ -### -# This file contains instructions for how to build the Odielib library -# It will produce the following files in whatever directory it was called from: -# -# * odielibc.mk - A Makefile snippet needed to compile the odielib sources -# * odielibc.c - A C file which acts as the loader for odielibc -# * logicset.c/h - A c -# * (several .c and .h files) - C sources that are generated on the fly by automation -### -# Ad a "just in case" version or practcl we ship locally - -set ::CWD [pwd] -set ::project(builddir) $::CWD -set ::project(srcdir) [file dirname [file dirname [file normalize [info script]]]] -set ::project(sandbox) [file dirname $::project(srcdir)] -set ::project(download) [file join $::project(sandbox) download] -set ::project(teapot) [file join $::project(sandbox) teapot] -source [file join $::CWD .. library practcl practcl.tcl] -array set ::project [::practcl::config.tcl $CWD] - -set SRCPATH $::project(srcdir) -set SANDBOX $::project(sandbox) -file mkdir $CWD/build - -::practcl::target implement { - triggers {} -} -::practcl::target tcltk { - depends deps - triggers {script-packages script-pkgindex} -} -::practcl::target basekit { - depends {deps tcltk} - triggers {} - filename [file join $CWD tclkit_bare$::project(EXEEXT)] -} -::practcl::target packages { - depends {deps tcltk} -} -::practcl::target distclean {} -::practcl::target example { - depends basekit -} - -switch [lindex $argv 0] { - autoconf - - pre - - deps { - ::practcl::trigger implement - } - os { - puts "OS: [practcl::os]" - parray ::project - exit 0 - } - wrap { - ::practcl::depends basekit - } - all { - # Auto detect missing bits - foreach {item obj} $::make_objects { - if {[$obj check]} { - $obj trigger - } - } - } - package { - ::practcl::trigger packages - } - default { - ::practcl::trigger {*}$argv - } -} - -parray make - -set ::CWD [pwd] -::practcl::tclkit create BASEKIT {} -BASEKIT define set name tclkit -BASEKIT define set pkg_name tclkit -BASEKIT define set pkg_version 8.7.0a -BASEKIT define set localpath tclkit -BASEKIT define set profile devel -BASEKIT source [file join $::CWD packages.tcl] - -if {$make(distclean)} { - # Clean all source code back to it's pristine state from fossil - foreach item [BASEKIT link list package] { - $item go - set projdir [$item define get localsrcdir] - if {$projdir ne {} && [file exists $projdir]} { - fossil $projdir clean -force - } - } -} - -file mkdir [file join $CWD build] - -if {$make(tcltk)} { - ### - # Download our required packages - ### - set tcl_config_opts {} - set tk_config_opts {} - switch [::practcl::os] { - windows { - #lappend tcl_config_opts --disable-stubs - } - linux { - lappend tk_config_opts --enable-xft=no --enable-xss=no - } - macosx { - lappend tcl_config_opts --enable-corefoundation=yes --enable-framework=no - lappend tk_config_opts --enable-aqua=yes - } - } - lappend tcl_config_opts --with-tzdata --prefix [BASEKIT define get prefix] - BASEKIT project TCLCORE define set config_opts $tcl_config_opts - BASEKIT project TCLCORE go - set _TclSrcDir [BASEKIT project TCLCORE define get localsrcdir] - BASEKIT define set tclsrcdir $_TclSrcDir - lappend tk_config_opts --with-tcl=$_TclSrcDir - BASEKIT project TKCORE define set config_opts $tk_config_opts - BASEKIT project TCLCORE compile - BASEKIT project TKCORE compile -} - -if {$make(basekit)} { - BASEKIT implement $CWD - ::practcl::build::static-tclsh $target(basekit) BASEKIT -} - -if {[lindex $argv 0] eq "package"} { - #set result {} - foreach item [lrange $argv 1 end] { - set obj [BASEKIT project $item] - puts [list build $item [$obj define get static] [info object class $obj]] - if {[string is true [$obj define get static]]} { - $obj compile - } - if {[string is true [$obj define get vfsinstall]]} { - $obj install-vfs - } - } - #puts "RESULT: $result" -} elseif {$make(packages)} { - foreach item [BASEKIT link list package] { - if {[string is true [$item define get static]]} { - $item compile - } - if {[string is true [$item define get vfsinstall]]} { - $item install-vfs - } - } -} - - -if {$make(example)} { - file mkdir [file join $CWD example.vfs] - BASEKIT wrap $CWD example example.vfs -} - -if {[lindex $argv 0] eq "wrap"} { - BASEKIT wrap $CWD {*}[lrange $argv 1 end] -} diff --git a/pkgs/packages.tcl b/pkgs/packages.tcl deleted file mode 100644 index 2a84971..0000000 --- a/pkgs/packages.tcl +++ /dev/null @@ -1,92 +0,0 @@ -### -# This script implements a basic TclTkit with statically linked -# Tk, sqlite, threads, udp, and mmtk (which includes canvas3d and tkhtml) -### - -set CWD [pwd] - -my define set [array get ::project] -set os [::practcl::os] -my define set os $os -puts [list BASEKIT SANDBOX $::project(sandbox)] -my define set platform $::project(TEA_PLATFORM) -my define set prefix /zvfs -my define set sandbox [file normalize $::project(sandbox)] -my define set installdir [file join $::project(sandbox) pkg] -my define set teapot [file join $::project(sandbox) teapot] -my define set USEMSVC [info exists env(VisualStudioVersion)] -my define set prefix_broken_destdir [file join $::project(sandbox) tmp] -my define set HOST $os -my define set TARGET $os -my define set tclkit_bare [file join $CWD tclkit_bare$::project(EXEEXT)] - -my define set name tclkit -my define set output_c tclkit.c -my define set libs {} - -my add_project TCLCORE { - class subproject.core - name tcl - tag release - static 1 -} -my project TCLCORE define set srcdir [file dirname $::project(sandbox)] - -my add_project TKCORE { - class subproject.core - name tk - tag release - static 1 - autoload 0 - pkg_name Tk - initfunc Tk_Init -} - -my add_project tclconfig { - profile { - release: 3dfb97da548fae506374ac0015352ac0921d0cc9 - devel: practcl - } - class subproject - preload 1 - vfsinstall 0 -} - -my add_project thread { - profile { - release: 2a36d0a6c31569bfb3562e3d58e9e8204f447a7e - devel: practcl - } - class subproject.binary - pkg_name Thread - autoload 1 - initfunc Thread_Init - static 1 -} - -my add_project sqlite { - profile { - release: 40ffdfb26af3e7443b2912e1039c06bf9ed75846 - devel: practcl - } - class subproject.binary - pkg_name sqlite3 - autoload 1 - initfunc Sqlite3_Init - static 1 - vfsinstall 0 -} - -my add_project udp { - profile { - release: 7c396e1a767db57b07b48daa8e0cfc0ea622bbe9 - devel: practcl - } - class subproject.binary - static 1 - autoload 1 - initfunc Udp_Init - pkg_name udp - vfsinstall 0 -} - -- cgit v0.12 From b2722c42b1a43b10ba1047b6be28d5b4663732b8 Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Wed, 8 Nov 2017 09:41:00 +0000 Subject: Pairing down the tip#430 branch to only include files and utilities called out by the tip. Eliminated the header files tclZipfs.h and zcrypt.h. The only public calls for tclZipfs.h are now in the stubs table and the contents of zcrypt.h are already part of the minizip implementation that Tcl keeps around in the compat/zlib/contrib/minizip directory. tclBootVFS.h hasn't been used by the implementation in a while. Alos eliminated the mkzip.tcl facility from tools/. The C based mkzip is much faster and more reliable --- doc/zipfs.3 | 21 +----- generic/tclBootVfs.h | 24 ------- generic/tclZipfs.c | 6 +- generic/tclZipfs.h | 48 ------------- generic/zcrypt.h | 131 ---------------------------------- tools/mkVfs.tcl | 198 +++++++++++++++++++++++++-------------------------- tools/mkzip.tcl | 5 -- unix/Makefile.in | 4 +- win/Makefile.in | 6 +- win/makefile.vc | 4 +- 10 files changed, 113 insertions(+), 334 deletions(-) delete mode 100644 generic/tclBootVfs.h delete mode 100644 generic/tclZipfs.h delete mode 100644 generic/zcrypt.h delete mode 100644 tools/mkzip.tcl diff --git a/doc/zipfs.3 b/doc/zipfs.3 index 6846f58..a3b3da8 100644 --- a/doc/zipfs.3 +++ b/doc/zipfs.3 @@ -1,24 +1,18 @@ '\" '\" Copyright (c) 2015 Jan Nijtmans '\" Copyright (c) 2015 Christian Werner +'\" Copyright (c) 2017 Sean Woods '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH Tclzipfs 3 8.7 Tcl "Tcl Library Procedures" .so man.macros .BS .SH NAME -Tclzipfs_Init, Tclzipfs_SafeInit, Tclzipfs_Mount, Tclzipfs_Unmount \- handle ZIP files as VFS +Tclzipfs_Mount, Tclzipfs_Unmount \- handle ZIP files as VFS .SH SYNOPSIS .nf -\fB#include \fR -.sp -int -\fBTclzipfs_Init\fR(\fIinterp\fR) -.sp -int -\fBTclzipfs_SafeInit\fR(\fIinterp\fR) .sp int \fBTclzipfs_Mount\fR(\fIinterp, zipname, mntpt, passwd\fR) @@ -38,15 +32,6 @@ Name of a mount point. An (optional) password. .BE .SH DESCRIPTION -\fBTclzipfs_Init()\fR performs one-time initialization of the file system -and registers it process wide. Additionally, a package named \fIzipfs\fR -is provided and supplemental Tcl commands are created in the given -interpreter \fIinterp\fR. -.PP -\fBTclzipfs_SafeInit()\fR is the version of \fBTclzipfs_Init()\fR for -safe interpreters. It exposes only uncritical supplemental Tcl commands -in the given interpreter \fIinterp\fR. -.PP \fBTclzipfs_Mount()\fR mount the ZIP archive \fIzipname\fR on the mount point given in \fImntpt\fR using the optional ZIP password \fIpasswd\fR. Errors during that process are reported in the interpreter \fIinterp\fR. diff --git a/generic/tclBootVfs.h b/generic/tclBootVfs.h deleted file mode 100644 index 1cb7c23..0000000 --- a/generic/tclBootVfs.h +++ /dev/null @@ -1,24 +0,0 @@ -#include -#include "tclInt.h" -#include "tclFileSystem.h" - -#ifndef MODULE_SCOPE -# define MODULE_SCOPE extern -#endif - -#define TCLVFSBOOT_INIT "main.tcl" -#define TCLVFSBOOT_MOUNT "/zvfs" - -/* Make sure the stubbed variants of those are never used. */ -#undef Tcl_ObjSetVar2 -#undef Tcl_NewStringObj -#undef Tk_Init -#undef Tk_MainEx -#undef Tk_SafeInit - -MODULE_SCOPE int Tcl_Zvfs_Boot(const char *,const char *,const char *); -MODULE_SCOPE int Zvfs_Init(Tcl_Interp *); -MODULE_SCOPE int Zvfs_SafeInit(Tcl_Interp *); -MODULE_SCOPE int Tclkit_Packages_Init(Tcl_Interp *); - - diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c index 9d74890..fe4553e 100644 --- a/generic/tclZipfs.c +++ b/generic/tclZipfs.c @@ -4,7 +4,7 @@ * Implementation of the ZIP filesystem used in TIP 430 * Adapted from the implentation for AndroWish. * - * Coptright (c) 2016 Sean Woods + * Coptright (c) 2016-2017 Sean Woods * Copyright (c) 2013-2015 Christian Werner * * See the file "license.terms" for information on usage and redistribution of @@ -26,7 +26,7 @@ #ifdef HAVE_ZLIB #include "zlib.h" -#include "zcrypt.h" +#include "crypt.h" #define ZIPFS_VOLUME "zipfs:/" #define ZIPFS_VOLUME_LEN 7 @@ -235,7 +235,7 @@ static const char pwrot[16] = { * Table to compute CRC32. */ -static const unsigned int crc32tab[256] = { +static const unsigned long crc32tab[256] = { 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, diff --git a/generic/tclZipfs.h b/generic/tclZipfs.h deleted file mode 100644 index f7da3bd..0000000 --- a/generic/tclZipfs.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * tclZipfs.h -- - * - * This header file describes the interface of the ZIPFS filesystem - * - * Copyright (c) 2013-2015 Christian Werner - * - * See the file "license.terms" for information on usage and redistribution of - * this file, and for a DISCLAIMER OF ALL WARRANTIES. - */ - -#ifndef _ZIPFS_H -#define _ZIPFS_H - -#include "tcl.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef ZIPFSAPI -# define ZIPFSAPI extern -#endif - -#ifdef BUILD_tcl -# undef ZIPFSAPI -# define ZIPFSAPI DLLEXPORT -#endif - -ZIPFSAPI int TclZipfs_Mount(Tcl_Interp *interp, const char *zipname, - const char *mntpt, const char *passwd); -ZIPFSAPI int TclZipfs_Unmount(Tcl_Interp *interp, const char *zipname); -ZIPFSAPI int TclZipfs_Init(Tcl_Interp *interp); -ZIPFSAPI int TclZipfs_SafeInit(Tcl_Interp *interp); - -#ifdef __cplusplus -} -#endif - -#endif /* _ZIPFS_H */ - -/* - * Local Variables: - * mode: c - * c-basic-offset: 4 - * fill-column: 78 - * End: - */ diff --git a/generic/zcrypt.h b/generic/zcrypt.h deleted file mode 100644 index eb9865b..0000000 --- a/generic/zcrypt.h +++ /dev/null @@ -1,131 +0,0 @@ -/* crypt.h -- base code for crypt/uncrypt ZIPfile - - - Version 1.01e, February 12th, 2005 - - Copyright (C) 1998-2005 Gilles Vollant - - This code is a modified version of crypting code in Infozip distribution - - The encryption/decryption parts of this source code (as opposed to the - non-echoing password parts) were originally written in Europe. The - whole source package can be freely distributed, including from the USA. - (Prior to January 2000, re-export from the US was a violation of US law.) - - This encryption code is a direct transcription of the algorithm from - Roger Schlafly, described by Phil Katz in the file appnote.txt. This - file (appnote.txt) is distributed with the PKZIP program (even in the - version without encryption capabilities). - - If you don't need crypting in your application, just define symbols - NOCRYPT and NOUNCRYPT. - - This code support the "Traditional PKWARE Encryption". - - The new AES encryption added on Zip format by Winzip (see the page - http://www.winzip.com/aes_info.htm ) and PKWare PKZip 5.x Strong - Encryption is not supported. -*/ - -#define CRC32(c, b) ((*(pcrc_32_tab+(((int)(c) ^ (b)) & 0xff))) ^ ((c) >> 8)) - -/*********************************************************************** - * Return the next byte in the pseudo-random sequence - */ -static int decrypt_byte(unsigned long* pkeys, const unsigned int* pcrc_32_tab) -{ - unsigned temp; /* POTENTIAL BUG: temp*(temp^1) may overflow in an - * unpredictable manner on 16-bit systems; not a problem - * with any known compiler so far, though */ - - temp = ((unsigned)(*(pkeys+2)) & 0xffff) | 2; - return (int)(((temp * (temp ^ 1)) >> 8) & 0xff); -} - -/*********************************************************************** - * Update the encryption keys with the next byte of plain text - */ -static int update_keys(unsigned long* pkeys,const unsigned int* pcrc_32_tab,int c) -{ - (*(pkeys+0)) = CRC32((*(pkeys+0)), c); - (*(pkeys+1)) += (*(pkeys+0)) & 0xff; - (*(pkeys+1)) = (*(pkeys+1)) * 134775813L + 1; - { - register int keyshift = (int)((*(pkeys+1)) >> 24); - (*(pkeys+2)) = CRC32((*(pkeys+2)), keyshift); - } - return c; -} - - -/*********************************************************************** - * Initialize the encryption keys and the random header according to - * the given password. - */ -static void init_keys(const char* passwd,unsigned long* pkeys,const unsigned int* pcrc_32_tab) -{ - *(pkeys+0) = 305419896L; - *(pkeys+1) = 591751049L; - *(pkeys+2) = 878082192L; - while (*passwd != '\0') { - update_keys(pkeys,pcrc_32_tab,(int)*passwd); - passwd++; - } -} - -#define zdecode(pkeys,pcrc_32_tab,c) \ - (update_keys(pkeys,pcrc_32_tab,c ^= decrypt_byte(pkeys,pcrc_32_tab))) - -#define zencode(pkeys,pcrc_32_tab,c,t) \ - (t=decrypt_byte(pkeys,pcrc_32_tab), update_keys(pkeys,pcrc_32_tab,c), t^(c)) - -#ifdef INCLUDECRYPTINGCODE_IFCRYPTALLOWED - -#define RAND_HEAD_LEN 12 - /* "last resort" source for second part of crypt seed pattern */ -# ifndef ZCR_SEED2 -# define ZCR_SEED2 3141592654UL /* use PI as default pattern */ -# endif - -static int crypthead(const char* passwd, /* password string */ - unsigned char* buf, /* where to write header */ - int bufSize, - unsigned long* pkeys, - const unsigned int* pcrc_32_tab, - unsigned long crcForCrypting) -{ - int n; /* index in random header */ - int t; /* temporary */ - int c; /* random byte */ - unsigned char header[RAND_HEAD_LEN-2]; /* random header */ - static unsigned calls = 0; /* ensure different random header each time */ - - if (bufSize> 7) & 0xff; - header[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, c, t); - } - /* Encrypt random header (last two bytes is high word of crc) */ - init_keys(passwd, pkeys, pcrc_32_tab); - for (n = 0; n < RAND_HEAD_LEN-2; n++) - { - buf[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, header[n], t); - } - buf[n++] = (unsigned char)zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 16) & 0xff, t); - buf[n++] = (unsigned char)zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 24) & 0xff, t); - return n; -} - -#endif diff --git a/tools/mkVfs.tcl b/tools/mkVfs.tcl index e670775..cbfb81e 100644 --- a/tools/mkVfs.tcl +++ b/tools/mkVfs.tcl @@ -1,99 +1,99 @@ -proc cat fname { - set fname [open $fname r] - set data [read $fname] - close $fname - return $data -} - -proc pkgIndexDir {root fout d1} { - - puts [format {%*sIndexing %s} [expr {4 * [info level]}] {} \ - [file tail $d1]] - set idx [string length $root] - foreach ftail [glob -directory $d1 -nocomplain -tails *] { - set f [file join $d1 $ftail] - if {[file isdirectory $f] && [string compare CVS $ftail]} { - pkgIndexDir $root $fout $f - } elseif {[file tail $f] eq "pkgIndex.tcl"} { - puts $fout "set dir \${VFSROOT}[string range $d1 $idx end]" - puts $fout [cat $f] - } - } -} - -### -# Script to build the VFS file system -### -proc copyDir {d1 d2} { - - puts [format {%*sCreating %s} [expr {4 * [info level]}] {} \ - [file tail $d2]] - - file delete -force -- $d2 - file mkdir $d2 - - foreach ftail [glob -directory $d1 -nocomplain -tails *] { - set f [file join $d1 $ftail] - if {[file isdirectory $f] && [string compare CVS $ftail]} { - copyDir $f [file join $d2 $ftail] - } elseif {[file isfile $f]} { - file copy -force $f [file join $d2 $ftail] - if {$::tcl_platform(platform) eq {unix}} { - file attributes [file join $d2 $ftail] -permissions 0644 - } else { - file attributes [file join $d2 $ftail] -readonly 1 - } - } - } - - if {$::tcl_platform(platform) eq {unix}} { - file attributes $d2 -permissions 0755 - } else { - file attributes $d2 -readonly 1 - } -} - -if {[llength $argv] < 3} { - puts "Usage: VFS_ROOT TCLSRC_ROOT PLATFORM" - exit 1 -} -set TCL_SCRIPT_DIR [lindex $argv 0] -set TCLSRC_ROOT [lindex $argv 1] -set PLATFORM [lindex $argv 2] -set TKDLL [lindex $argv 3] -set TKVER [lindex $argv 4] - -puts "Building [file tail $TCL_SCRIPT_DIR] for $PLATFORM" -copyDir ${TCLSRC_ROOT}/library ${TCL_SCRIPT_DIR} - -if {$PLATFORM == "windows"} { - set ddedll [glob -nocomplain ${TCLSRC_ROOT}/win/tcldde*.dll] - puts "DDE DLL $ddedll" - if {$ddedll != {}} { - file copy $ddedll ${TCL_SCRIPT_DIR}/dde - } - set regdll [glob -nocomplain ${TCLSRC_ROOT}/win/tclreg*.dll] - puts "REG DLL $ddedll" - if {$regdll != {}} { - file copy $regdll ${TCL_SCRIPT_DIR}/reg - } -} else { - # Remove the dde and reg package paths - file delete -force ${TCL_SCRIPT_DIR}/dde - file delete -force ${TCL_SCRIPT_DIR}/reg -} - -# For the following packages, cat their pkgIndex files to tclIndex -file attributes ${TCL_SCRIPT_DIR}/tclIndex -readonly 0 -set fout [open ${TCL_SCRIPT_DIR}/tclIndex a] -puts $fout {# -# MANIFEST OF INCLUDED PACKAGES -# -set VFSROOT $dir -} -if {$TKDLL ne {} && [file exists $TKDLL]} { - file copy $TKDLL ${TCL_SCRIPT_DIR} - puts $fout [list package ifneeded Tk $TKVER "load \$dir $TKDLL"] -} -pkgIndexDir ${TCL_SCRIPT_DIR} $fout ${TCL_SCRIPT_DIR} -close $fout +proc cat fname { + set fname [open $fname r] + set data [read $fname] + close $fname + return $data +} + +proc pkgIndexDir {root fout d1} { + + puts [format {%*sIndexing %s} [expr {4 * [info level]}] {} \ + [file tail $d1]] + set idx [string length $root] + foreach ftail [glob -directory $d1 -nocomplain -tails *] { + set f [file join $d1 $ftail] + if {[file isdirectory $f] && [string compare CVS $ftail]} { + pkgIndexDir $root $fout $f + } elseif {[file tail $f] eq "pkgIndex.tcl"} { + puts $fout "set dir \${VFSROOT}[string range $d1 $idx end]" + puts $fout [cat $f] + } + } +} + +### +# Script to build the VFS file system +### +proc copyDir {d1 d2} { + + puts [format {%*sCreating %s} [expr {4 * [info level]}] {} \ + [file tail $d2]] + + file delete -force -- $d2 + file mkdir $d2 + + foreach ftail [glob -directory $d1 -nocomplain -tails *] { + set f [file join $d1 $ftail] + if {[file isdirectory $f] && [string compare CVS $ftail]} { + copyDir $f [file join $d2 $ftail] + } elseif {[file isfile $f]} { + file copy -force $f [file join $d2 $ftail] + if {$::tcl_platform(platform) eq {unix}} { + file attributes [file join $d2 $ftail] -permissions 0644 + } else { + file attributes [file join $d2 $ftail] -readonly 1 + } + } + } + + if {$::tcl_platform(platform) eq {unix}} { + file attributes $d2 -permissions 0755 + } else { + file attributes $d2 -readonly 1 + } +} + +if {[llength $argv] < 3} { + puts "Usage: VFS_ROOT TCLSRC_ROOT PLATFORM" + exit 1 +} +set TCL_SCRIPT_DIR [lindex $argv 0] +set TCLSRC_ROOT [lindex $argv 1] +set PLATFORM [lindex $argv 2] +set TKDLL [lindex $argv 3] +set TKVER [lindex $argv 4] + +puts "Building [file tail $TCL_SCRIPT_DIR] for $PLATFORM" +copyDir ${TCLSRC_ROOT}/library ${TCL_SCRIPT_DIR} + +if {$PLATFORM == "windows"} { + set ddedll [glob -nocomplain ${TCLSRC_ROOT}/win/tcldde*.dll] + puts "DDE DLL $ddedll" + if {$ddedll != {}} { + file copy $ddedll ${TCL_SCRIPT_DIR}/dde + } + set regdll [glob -nocomplain ${TCLSRC_ROOT}/win/tclreg*.dll] + puts "REG DLL $ddedll" + if {$regdll != {}} { + file copy $regdll ${TCL_SCRIPT_DIR}/reg + } +} else { + # Remove the dde and reg package paths + file delete -force ${TCL_SCRIPT_DIR}/dde + file delete -force ${TCL_SCRIPT_DIR}/reg +} + +# For the following packages, cat their pkgIndex files to tclIndex +file attributes ${TCL_SCRIPT_DIR}/tclIndex -readonly 0 +set fout [open ${TCL_SCRIPT_DIR}/tclIndex a] +puts $fout {# +# MANIFEST OF INCLUDED PACKAGES +# +set VFSROOT $dir +} +if {$TKDLL ne {} && [file exists $TKDLL]} { + file copy $TKDLL ${TCL_SCRIPT_DIR} + puts $fout [list package ifneeded Tk $TKVER "load \$dir $TKDLL"] +} +pkgIndexDir ${TCL_SCRIPT_DIR} $fout ${TCL_SCRIPT_DIR} +close $fout diff --git a/tools/mkzip.tcl b/tools/mkzip.tcl deleted file mode 100644 index ba10908..0000000 --- a/tools/mkzip.tcl +++ /dev/null @@ -1,5 +0,0 @@ -### -# Wrapper to allow access to Tcl's zvfs::mkzip command from Makefiles -### -source [file join [file dirname [file normalize [info script]]] .. library zvfstools zvfstools.tcl] -zvfs::mkzip {*}$argv diff --git a/unix/Makefile.in b/unix/Makefile.in index ee3ed75..5f4e125 100644 --- a/unix/Makefile.in +++ b/unix/Makefile.in @@ -373,7 +373,6 @@ GENERIC_HDRS = \ $(GENERIC_DIR)/tclInt.h \ $(GENERIC_DIR)/tclIntDecls.h \ $(GENERIC_DIR)/tclIntPlatDecls.h \ - $(GENERIC_DIR)/tclZipfs.h \ $(GENERIC_DIR)/tclTomMath.h \ $(GENERIC_DIR)/tclTomMathDecls.h \ $(GENERIC_DIR)/tclOO.h \ @@ -962,7 +961,6 @@ install-headers: @for i in $(GENERIC_DIR)/tcl.h $(GENERIC_DIR)/tclDecls.h \ $(GENERIC_DIR)/tclOO.h $(GENERIC_DIR)/tclOODecls.h \ $(GENERIC_DIR)/tclPlatDecls.h \ - $(GENERIC_DIR)/tclZipfs.h \ $(GENERIC_DIR)/tclTomMath.h \ $(GENERIC_DIR)/tclTomMathDecls.h ; \ do \ @@ -1333,7 +1331,7 @@ tclZlib.o: $(GENERIC_DIR)/tclZlib.c $(CC) -c $(CC_SWITCHES) $(ZLIB_INCLUDE) $(GENERIC_DIR)/tclZlib.c tclZipfs.o: $(GENERIC_DIR)/tclZipfs.c - $(CC) -c $(CC_SWITCHES) $(ZLIB_INCLUDE) $(GENERIC_DIR)/tclZipfs.c + $(CC) -c $(CC_SWITCHES) $(ZLIB_INCLUDE) -I$(ZLIB_DIR)/contrib/minizip $(GENERIC_DIR)/tclZipfs.c tclTest.o: $(GENERIC_DIR)/tclTest.c $(IOHDR) $(TCLREHDRS) $(CC) -c $(APP_CC_SWITCHES) $(GENERIC_DIR)/tclTest.c diff --git a/win/Makefile.in b/win/Makefile.in index 8d5aa5a..1a88cc8 100644 --- a/win/Makefile.in +++ b/win/Makefile.in @@ -502,6 +502,11 @@ testMain.${OBJEXT}: tclAppInit.c tclMain2.${OBJEXT}: tclMain.c $(CC) -c $(CC_SWITCHES) -DBUILD_tcl -DTCL_ASCII_MAIN @DEPARG@ $(CC_OBJNAME) +# TIP #430, ZipFS Support +tclZipfs.${OBJEXT}: $(GENERIC_DIR)/tclZipfs.c + $(CC) -c $(CC_SWITCHES) $(ZLIB_INCLUDE) -I$(ZLIB_DIR)/contrib/minizip $(GENERIC_DIR)/tclZipfs.c + + # TIP #59, embedding of configuration information into the binary library. # # Part of Tcl's configuration information are the paths where it was installed @@ -642,7 +647,6 @@ install-libraries: libraries install-tzdata install-msgs @echo "Installing header files"; @for i in "$(GENERIC_DIR)/tcl.h" "$(GENERIC_DIR)/tclDecls.h" \ "$(GENERIC_DIR)/tclOO.h" "$(GENERIC_DIR)/tclOODecls.h" \ - "$(GENERIC_DIR)/tclZipfs.h" \ "$(GENERIC_DIR)/tclPlatDecls.h" \ "$(GENERIC_DIR)/tclTomMath.h" \ "$(GENERIC_DIR)/tclTomMathDecls.h"; \ diff --git a/win/makefile.vc b/win/makefile.vc index 19e1e2d..c8713fe 100644 --- a/win/makefile.vc +++ b/win/makefile.vc @@ -959,8 +959,9 @@ $(TMP_DIR)\tclWinTest.obj: $(WINDIR)\tclWinTest.c $(TMP_DIR)\tclZlib.obj: $(GENERICDIR)\tclZlib.c $(cc32) $(TCL_CFLAGS) -I$(COMPATDIR)\zlib -DBUILD_tcl -Fo$@ $? +### TIP #430 ZipFS Support $(TMP_DIR)\zipfs.obj: $(GENERICDIR)\zipfs.c - $(cc32) $(TCL_CFLAGS) -I$(COMPATDIR)\zlib -DBUILD_tcl -Fo$@ $? + $(cc32) $(TCL_CFLAGS) -I$(COMPATDIR)\zlib -I$(COMPATDIR)\zlib\contrib\minizip -DBUILD_tcl -Fo$@ $? $(TMP_DIR)\tclPkgConfig.obj: $(GENERICDIR)\tclPkgConfig.c $(cc32) -DBUILD_tcl $(TCL_CFLAGS) \ @@ -1135,7 +1136,6 @@ install-libraries: tclConfig install-msgs install-tzdata @$(CPY) "$(GENERICDIR)\tclDecls.h" "$(INCLUDE_INSTALL_DIR)\" @$(CPY) "$(GENERICDIR)\tclOO.h" "$(INCLUDE_INSTALL_DIR)\" @$(CPY) "$(GENERICDIR)\tclOODecls.h" "$(INCLUDE_INSTALL_DIR)\" - @$(CPY) "$(GENERICDIR)\tclZipfs.h" "$(INCLUDE_INSTALL_DIR)\" @$(CPY) "$(GENERICDIR)\tclPlatDecls.h" "$(INCLUDE_INSTALL_DIR)\" @$(CPY) "$(GENERICDIR)\tclTomMath.h" "$(INCLUDE_INSTALL_DIR)\" @$(CPY) "$(GENERICDIR)\tclTomMathDecls.h" "$(INCLUDE_INSTALL_DIR)\" -- cgit v0.12 From 932afb01058a92816df27ea786c0a5c0cbd09290 Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Sat, 11 Nov 2017 09:18:09 +0000 Subject: Improvements to tip430 to embed the /library file system within a shared library or as a zip archive with a canonical name matching the current patch level This new version also builds a native executable version of minizip to allow archive to be built within make, even when cross compiling Added a new function TclZipfs_AppHook which implements tip430 core behavior startups to stock tclsh Embedding the file system as a zip archive can be defeated with --enable-zipfs=no --- generic/tcl.decls | 4 +- generic/tclDecls.h | 5 ++ generic/tclInterp.c | 2 + generic/tclPkgConfig.c | 2 + generic/tclStubInit.c | 1 + generic/tclZipfs.c | 73 +++++++++++++++++++- unix/Makefile.in | 152 +++++++++++++++++++++++++++++++++++++++-- unix/configure | 178 ++++++++++++++++++++++++++++++++++++++++++++++++- unix/configure.ac | 61 +++++++++++++++++ unix/tcl.m4 | 107 +++++++++++++++++++++++++++++ unix/tclAppInit.c | 2 + unix/tclConfig.sh.in | 3 + 12 files changed, 582 insertions(+), 8 deletions(-) diff --git a/generic/tcl.decls b/generic/tcl.decls index c19bf68..fcc6235 100644 --- a/generic/tcl.decls +++ b/generic/tcl.decls @@ -2343,7 +2343,9 @@ declare 632 { declare 633 { int TclZipfs_Unmount(Tcl_Interp *interp, const char *zipname) } - +declare 634 { + int TclZipfs_AppHook(int *argc, char ***argv) +} ############################################################################## # Define the platform specific public Tcl interface. These functions are only diff --git a/generic/tclDecls.h b/generic/tclDecls.h index 24a22c3..c7cac7c 100644 --- a/generic/tclDecls.h +++ b/generic/tclDecls.h @@ -1838,6 +1838,8 @@ EXTERN int TclZipfs_Mount(Tcl_Interp *interp, /* 633 */ EXTERN int TclZipfs_Unmount(Tcl_Interp *interp, const char *zipname); +/* 634 */ +EXTERN int TclZipfs_AppHook(int *argc, char ***argv); typedef struct { const struct TclPlatStubs *tclPlatStubs; @@ -2507,6 +2509,7 @@ typedef struct TclStubs { Tcl_Channel (*tcl_OpenTcpServerEx) (Tcl_Interp *interp, const char *service, const char *host, unsigned int flags, Tcl_TcpAcceptProc *acceptProc, ClientData callbackData); /* 631 */ int (*tclZipfs_Mount) (Tcl_Interp *interp, const char *zipname, const char *mntpt, const char *passwd); /* 632 */ int (*tclZipfs_Unmount) (Tcl_Interp *interp, const char *zipname); /* 633 */ + int (*tclZipfs_AppHook) (int *argc, char ***argv); /* 634 */ } TclStubs; extern const TclStubs *tclStubsPtr; @@ -3805,6 +3808,8 @@ extern const TclStubs *tclStubsPtr; (tclStubsPtr->tclZipfs_Mount) /* 632 */ #define TclZipfs_Unmount \ (tclStubsPtr->tclZipfs_Unmount) /* 633 */ +#define TclZipfs_AppHook \ + (tclStubsPtr->tclZipfs_AppHook) /* 634 */ #endif /* defined(USE_TCL_STUBS) */ diff --git a/generic/tclInterp.c b/generic/tclInterp.c index d9dfd37..2b0582a 100644 --- a/generic/tclInterp.c +++ b/generic/tclInterp.c @@ -402,6 +402,8 @@ Tcl_Init( " set scripts {{set tcl_library}}\n" " } else {\n" " set scripts {}\n" +" lappend scripts {set temp zipfs:/lib/tcl/tcl_library}\n" +" lappend scripts {set temp zipfs:/app/tcl_library}\n" " if {[info exists env(TCL_LIBRARY)] && ($env(TCL_LIBRARY) ne {})} {\n" " lappend scripts {set env(TCL_LIBRARY)}\n" " lappend scripts {\n" diff --git a/generic/tclPkgConfig.c b/generic/tclPkgConfig.c index 466d535..53b7dbb 100644 --- a/generic/tclPkgConfig.c +++ b/generic/tclPkgConfig.c @@ -105,6 +105,8 @@ static Tcl_Config const cfg[] = { {"scriptdir,runtime", CFG_RUNTIME_SCRDIR}, {"includedir,runtime", CFG_RUNTIME_INCDIR}, {"docdir,runtime", CFG_RUNTIME_DOCDIR}, + {"dllfile,runtime", CFG_RUNTIME_DLLFILE}, + {"zipfile,runtime", CFG_RUNTIME_ZIPFILE}, /* Installation paths to various stuff */ diff --git a/generic/tclStubInit.c b/generic/tclStubInit.c index f251a57..16d5837 100644 --- a/generic/tclStubInit.c +++ b/generic/tclStubInit.c @@ -1538,6 +1538,7 @@ const TclStubs tclStubs = { Tcl_OpenTcpServerEx, /* 631 */ TclZipfs_Mount, /* 632 */ TclZipfs_Unmount, /* 633 */ + TclZipfs_AppHook, /* 634 */ }; /* !END!: Do not edit above this line. */ diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c index fe4553e..9dfca7a 100644 --- a/generic/tclZipfs.c +++ b/generic/tclZipfs.c @@ -28,7 +28,10 @@ #include "zlib.h" #include "crypt.h" -#define ZIPFS_VOLUME "zipfs:/" +#define ZIPFS_VOLUME "zipfs:/" +#define ZIPFS_APP_MOUNT "zipfs:/app" +#define ZIPFS_ZIP_MOUNT "zipfs:/lib/tcl" + #define ZIPFS_VOLUME_LEN 7 /* @@ -3807,7 +3810,7 @@ const Tcl_Filesystem zipfsFilesystem = { *------------------------------------------------------------------------- */ -int +MODULE_SCOPE int TclZipfs_Init(Tcl_Interp *interp) { #ifdef HAVE_ZLIB @@ -3877,6 +3880,72 @@ TclZipfs_Init(Tcl_Interp *interp) return TCL_ERROR; #endif } + +static int TclZipfs_AppHook_FindTclInit(const char *archive){ + Tcl_Obj *vfsinitscript; + int found; + if(TclZipfs_Mount(NULL, archive, ZIPFS_ZIP_MOUNT, NULL)) { + /* Either the file doesn't exist or it is not a zip archive */ + return TCL_ERROR; + } + vfsinitscript=Tcl_NewStringObj(ZIPFS_ZIP_MOUNT "/init.tcl",-1); + Tcl_IncrRefCount(vfsinitscript); + found=Tcl_FSAccess(vfsinitscript,F_OK); + if(found==0) { + return TCL_OK; + } + Tcl_DecrRefCount(vfsinitscript); + vfsinitscript=Tcl_NewStringObj(ZIPFS_ZIP_MOUNT "/tcl_library/init.tcl",-1); + Tcl_IncrRefCount(vfsinitscript); + found=Tcl_FSAccess(vfsinitscript,F_OK); + if(found==0) { + return TCL_OK; + } + return TCL_ERROR; +} + +int TclZipfs_AppHook(int *argc, char ***argv){ + /* + * Tclkit_MainHook -- + * Performs the argument munging for the shell + */ + + CONST char *archive; + Tcl_FindExecutable(*argv[0]); + archive=Tcl_GetNameOfExecutable(); + TclZipfs_Init(NULL); + if(!TclZipfs_Mount(NULL, archive, ZIPFS_APP_MOUNT, NULL)) { + int found; + Tcl_Obj *vfsinitscript; + vfsinitscript=Tcl_NewStringObj(ZIPFS_APP_MOUNT "/main.tcl",-1); + Tcl_IncrRefCount(vfsinitscript); + if(Tcl_FSAccess(vfsinitscript,F_OK)==0) { + /* Startup script should be set before calling Tcl_AppInit */ + Tcl_SetStartupScript(vfsinitscript,NULL); + } else { + Tcl_DecrRefCount(vfsinitscript); + } + /* Set Tcl Encodings */ + vfsinitscript=Tcl_NewStringObj(ZIPFS_APP_MOUNT "/tcl_library/init.tcl",-1); + Tcl_IncrRefCount(vfsinitscript); + found=Tcl_FSAccess(vfsinitscript,F_OK); + Tcl_DecrRefCount(vfsinitscript); + if(found==TCL_OK) { + return TCL_OK; + } + } + /* Mount zip file and dll before releasing to search */ + if(TclZipfs_AppHook_FindTclInit(CFG_RUNTIME_ZIPFILE)==TCL_OK) { + return TCL_OK; + } + if(TclZipfs_AppHook_FindTclInit(CFG_RUNTIME_PATH "/" CFG_RUNTIME_ZIPFILE)==TCL_OK) { + return TCL_OK; + } + if(TclZipfs_AppHook_FindTclInit(CFG_RUNTIME_PATH "/" CFG_RUNTIME_DLLFILE)==TCL_OK) { + return TCL_OK; + } + return TCL_OK; +} #ifndef HAVE_ZLIB diff --git a/unix/Makefile.in b/unix/Makefile.in index 5f4e125..d7cc3c7 100644 --- a/unix/Makefile.in +++ b/unix/Makefile.in @@ -199,6 +199,10 @@ LD_SEARCH_FLAGS = @LD_SEARCH_FLAGS@ BUILD_DLTEST = @BUILD_DLTEST@ #BUILD_DLTEST = +TCL_ZIP_FILE = @TCL_ZIP_FILE@ +TCL_VFS_PATH = libtcl.vfs/tcl_library +TCL_VFS_ROOT = libtcl.vfs + TCL_LIB_FILE = @TCL_LIB_FILE@ #TCL_LIB_FILE = libtcl.a @@ -242,6 +246,14 @@ ZLIB_DIR = ${COMPAT_DIR}/zlib ZLIB_INCLUDE = @ZLIB_INCLUDE@ CC = @CC@ +OBJEXT = @OBJEXT@ +HOST_CC = @CC_FOR_BUILD@ +HOST_EXEEXT = @EXEEXT_FOR_BUILD@ +HOST_OBJEXT = @OBJEXT_FOR_BUILD@ +ZIPFS_BUILD = @ZIPFS_BUILD@ +NATIVE_ZIP = @ZIP_PROG@ +SHARED_BUILD = @SHARED_BUILD@ + #CC = purify -best-effort @CC@ -DPURIFY # Flags to be passed to installManPage to control how the manpages should be @@ -251,6 +263,10 @@ MAN_FLAGS = @MAN_FLAGS@ # If non-empty, install the timezone files that are included with Tcl, # otherwise use the ones that ship with the OS. INSTALL_TZDATA = @INSTALL_TZDATA@ +INSTALL_LIBRARIES = @INSTALL_LIBRARIES@ +INSTALL_MSGS = @INSTALL_MSGS@ + + #-------------------------------------------------------------------------- # The information below is usually usable as is. The configure script won't @@ -617,6 +633,26 @@ ZLIB_SRCS = \ SRCS = $(GENERIC_SRCS) $(TOMMATH_SRCS) $(UNIX_SRCS) $(NOTIFY_SRCS) \ $(OO_SRCS) $(STUB_SRCS) @PLAT_SRCS@ @ZLIB_SRCS@ +# Minizip +MINIZIP_OBJS = \ + adler32.$(HOST_OBJEXT) \ + compress.$(HOST_OBJEXT) \ + crc32.$(HOST_OBJEXT) \ + deflate.$(HOST_OBJEXT) \ + infback.$(HOST_OBJEXT) \ + inffast.$(HOST_OBJEXT) \ + inflate.$(HOST_OBJEXT) \ + inftrees.$(HOST_OBJEXT) \ + ioapi.$(HOST_OBJEXT) \ + trees.$(HOST_OBJEXT) \ + uncompr.$(HOST_OBJEXT) \ + zip.$(HOST_OBJEXT) \ + zutil.$(HOST_OBJEXT) \ + minizip.$(HOST_OBJEXT) + +ZIP_INSTALL_OBJS = minizip${EXEEXT_FOR_BUILD} + + #-------------------------------------------------------------------------- # Start of rules #-------------------------------------------------------------------------- @@ -629,11 +665,23 @@ libraries: doc: +tclzipfile: ${TCL_ZIP_FILE} + + +${TCL_ZIP_FILE}: ${ZIP_INSTALL_OBJS} + rm -rf ${TCL_VFS_ROOT} + mkdir -p ${TCL_VFS_PATH} + cp -a ../library/* ${TCL_VFS_PATH} + cd ${TCL_VFS_ROOT} ; ../minizip${EXEEXT_FOR_BUILD} -o ../${TCL_ZIP_FILE} `find . -type f` + # The following target is configured by autoconf to generate either a shared # library or non-shared library for Tcl. -${LIB_FILE}: ${STUB_LIB_FILE} ${OBJS} +${LIB_FILE}: ${STUB_LIB_FILE} ${OBJS} ${TCL_ZIP_FILE} rm -f $@ @MAKE_LIB@ +ifeq (${ZIPFS_BUILD},1) + cat ${TCL_ZIP_FILE} >> ${LIB_FILE} +endif ${STUB_LIB_FILE}: ${STUB_LIB_OBJS} @if test "x${LIB_FILE}" = "xlibtcl${MAJOR_VERSION}.${MINOR_VERSION}.dll"; then \ @@ -667,7 +715,8 @@ Makefile: $(UNIX_DIR)/Makefile.in $(DLTEST_DIR)/Makefile.in clean: clean-packages rm -rf *.a *.o libtcl* core errs *~ \#* TAGS *.E a.out \ - errors ${TCL_EXE} ${TCLTEST_EXE} lib.exp Tcl @DTRACE_HDR@ + errors ${TCL_EXE} ${TCLTEST_EXE} lib.exp Tcl @DTRACE_HDR@ \ + minizip${EXEEXT_FOR_BUILD} *.${HOST_OBJEXT} cd dltest ; $(MAKE) clean distclean: distclean-packages clean @@ -777,7 +826,7 @@ trace-test: ${TCLTEST_EXE} # Installation rules #-------------------------------------------------------------------------- -INSTALL_BASE_TARGETS = install-binaries install-libraries install-msgs $(INSTALL_TZDATA) +INSTALL_BASE_TARGETS = install-binaries $(INSTALL_LIBRARIES) $(INSTALL_MSGS) $(INSTALL_TZDATA) INSTALL_DOC_TARGETS = install-doc INSTALL_PACKAGE_TARGETS = install-packages INSTALL_DEV_TARGETS = install-headers @@ -821,6 +870,25 @@ install-binaries: binaries @$(INSTALL_DATA_DIR) $(LIB_INSTALL_DIR)/pkgconfig @$(INSTALL_DATA) tcl.pc $(LIB_INSTALL_DIR)/pkgconfig/tcl.pc +install-libraries-zipfs-shared: libraries + @for i in "$(SCRIPT_INSTALL_DIR)"; \ + do \ + if [ ! -d "$$i" ] ; then \ + echo "Making directory $$i"; \ + $(INSTALL_DATA_DIR) "$$i"; \ + else true; \ + fi; \ + done; + @echo "Installing library files to $(SCRIPT_INSTALL_DIR)/"; + @for i in \ + $(UNIX_DIR)/tclAppInit.c @LDAIX_SRC@ @DTRACE_SRC@; \ + do \ + $(INSTALL_DATA) $$i "$(SCRIPT_INSTALL_DIR)"; \ + done; + +install-libraries-zipfs-static: install-libraries-zipfs-shared + $(INSTALL_DATA) ${TCL_ZIP_FILE} "$(LIB_INSTALL_DIR)" ;\ + install-libraries: libraries @for i in "$(SCRIPT_INSTALL_DIR)"; \ do \ @@ -875,6 +943,7 @@ install-libraries: libraries echo "if {![interp issafe]} { ::tcl::tm::roots {$(TCL_MODULE_PATH)} }" >> \ "$(SCRIPT_INSTALL_DIR)"/tm.tcl; \ fi + end install-tzdata: @for i in tzdata; \ @@ -1282,6 +1351,8 @@ tclPkgConfig.o: $(GENERIC_DIR)/tclPkgConfig.c -DCFG_RUNTIME_SCRDIR="\"$(TCL_LIBRARY)\"" \ -DCFG_RUNTIME_INCDIR="\"$(includedir)\"" \ -DCFG_RUNTIME_DOCDIR="\"$(mandir)\"" \ + -DCFG_RUNTIME_DLLFILE="\"$(TCL_LIB_FILE)\"" \ + -DCFG_RUNTIME_ZIPFILE="\"$(TCL_ZIP_FILE)\"" \ \ $(GENERIC_DIR)/tclPkgConfig.c @@ -1331,7 +1402,11 @@ tclZlib.o: $(GENERIC_DIR)/tclZlib.c $(CC) -c $(CC_SWITCHES) $(ZLIB_INCLUDE) $(GENERIC_DIR)/tclZlib.c tclZipfs.o: $(GENERIC_DIR)/tclZipfs.c - $(CC) -c $(CC_SWITCHES) $(ZLIB_INCLUDE) -I$(ZLIB_DIR)/contrib/minizip $(GENERIC_DIR)/tclZipfs.c + $(CC) -c $(CC_SWITCHES) \ + -DCFG_RUNTIME_DLLFILE="\"$(TCL_LIB_FILE)\"" \ + -DCFG_RUNTIME_ZIPFILE="\"$(TCL_ZIP_FILE)\"" \ + -DCFG_RUNTIME_PATH="\"$(DLL_INSTALL_DIR)\"" \ + $(ZLIB_INCLUDE) -I$(ZLIB_DIR)/contrib/minizip $(GENERIC_DIR)/tclZipfs.c tclTest.o: $(GENERIC_DIR)/tclTest.c $(IOHDR) $(TCLREHDRS) $(CC) -c $(APP_CC_SWITCHES) $(GENERIC_DIR)/tclTest.c @@ -1741,6 +1816,74 @@ tclOOStubLib.o: $(GENERIC_DIR)/tclOOStubLib.c $(CC) -c $(CC_SWITCHES) $< #-------------------------------------------------------------------------- +# Minizip implementation +#-------------------------------------------------------------------------- +adler32.$(HOST_OBJEXT): + $(HOST_CC) -o $@ -I$(ZLIB_DIR) -c $(ZLIB_DIR)/adler32.c + +compress.$(HOST_OBJEXT): + $(HOST_CC) -o $@ -I$(ZLIB_DIR) -c $(ZLIB_DIR)/compress.c + +crc32.$(HOST_OBJEXT): + $(HOST_CC) -o $@ -I$(ZLIB_DIR) -c $(ZLIB_DIR)/crc32.c + +deflate.$(HOST_OBJEXT): + $(HOST_CC) -o $@ -I$(ZLIB_DIR) -c $(ZLIB_DIR)/deflate.c + +ioapi.$(HOST_OBJEXT): + $(HOST_CC) -o $@ -I$(ZLIB_DIR) -I$(ZLIB_DIR)/contrib/minizip -c $(ZLIB_DIR)/contrib/minizip/ioapi.c + +infback.$(HOST_OBJEXT): + $(HOST_CC) -o $@ -I$(ZLIB_DIR) -c $(ZLIB_DIR)/infback.c + +inffast.$(HOST_OBJEXT): + $(HOST_CC) -o $@ -I$(ZLIB_DIR) -c $(ZLIB_DIR)/inffast.c + +inflate.$(HOST_OBJEXT): + $(HOST_CC) -o $@ -I$(ZLIB_DIR) -c $(ZLIB_DIR)/inflate.c + +inftrees.$(HOST_OBJEXT): + $(HOST_CC) -o $@ -I$(ZLIB_DIR) -c $(ZLIB_DIR)/inftrees.c + +trees.$(HOST_OBJEXT): + $(HOST_CC) -o $@ -I$(ZLIB_DIR) -c $(ZLIB_DIR)/trees.c + +uncompr.$(HOST_OBJEXT): + $(HOST_CC) -o $@ -I$(ZLIB_DIR) -c $(ZLIB_DIR)/uncompr.c + +zip.$(HOST_OBJEXT): + $(HOST_CC) -o $@ -I$(ZLIB_DIR) -I$(ZLIB_DIR)/contrib/minizip -c $(ZLIB_DIR)/contrib/minizip/zip.c + +zutil.$(HOST_OBJEXT): + $(HOST_CC) -o $@ -I$(ZLIB_DIR) -c $(ZLIB_DIR)/zutil.c + +minizip.$(HOST_OBJEXT): + $(HOST_CC) -o $@ -I$(ZLIB_DIR) -I$(ZLIB_DIR)/contrib/minizip -c $(ZLIB_DIR)/contrib/minizip/minizip.c + +minizip${EXEEXT_FOR_BUILD}: $(MINIZIP_OBJS) + $(HOST_CC) -o $@ $(MINIZIP_OBJS) + +tclvfs.zip: minizip${EXEEXT_FOR_BUILD} + rm -rf $(TCL_VFS_ROOT) + mkdir -p $(TCL_VFS_PATH) + @for i in "$(TCL_VFS_PATH)"; \ + do \ + if [ ! -d "$$i" ] ; then \ + echo "Making directory $$i"; \ + $(INSTALL_DATA_DIR) "$$i"; \ + else true; \ + fi; \ + done; + cp -a ../library/* $(TCL_VFS_PATH) + (cd $TCL_VFS ROOT ; ./minizip${EXEEXT_FOR_BUILD} -o ../tclvfs.zip `find . -type f`) + +zipsetupstub.$(HOST_OBJEXT): $(COMPAT_DIR)/zipsetupstub.c + $(HOST_CC) -o $@ -I$(ZLIB_DIR) -c $(COMPAT_DIR)/zipsetupstub.c + +zipsetupstub${EXEEXT_FOR_BUILD}: zipsetupstub.$(HOST_OBJEXT) + $(HOST_CC) -o $@ zipsetupstub.$(HOST_OBJEXT) + +#-------------------------------------------------------------------------- # Bundled Package targets #-------------------------------------------------------------------------- @@ -2148,6 +2291,7 @@ BUILD_HTML = \ .PHONY: install-tzdata install-msgs .PHONY: packages configure-packages test-packages clean-packages .PHONY: dist-packages distclean-packages install-packages +.PHONY: iinstall-libraries-zipfs-shared install-libraries-zipfs-static tclzipfile #-------------------------------------------------------------------------- # DO NOT DELETE THIS LINE -- make depend depends on it. diff --git a/unix/configure b/unix/configure index 129c283..8e2ec0f 100755 --- a/unix/configure +++ b/unix/configure @@ -658,12 +658,16 @@ TCL_STUB_LIB_FILE TCL_LIB_SPEC TCL_LIB_FLAG TCL_LIB_FILE +TCL_ZIP_FILE PKG_CFG_ARGS TCL_YEAR TCL_PATCH_LEVEL TCL_MINOR_VERSION TCL_MAJOR_VERSION TCL_VERSION +INSTALL_MSGS +INSTALL_LIBRARIES +ZIPFS_BUILD DTRACE LDFLAGS_DEFAULT CFLAGS_DEFAULT @@ -698,7 +702,11 @@ RANLIB ZLIB_INCLUDE ZLIB_SRCS ZLIB_OBJS +EXEEXT_FOR_BUILD +CC_FOR_BUILD +ZIP_PROG TCLSH_PROG +SHARED_BUILD TCL_THREADS EGREP GREP @@ -748,7 +756,8 @@ PACKAGE_VERSION PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR -SHELL' +SHELL +OBJEXT_FOR_BUILD' ac_subst_files='' ac_user_opts=' enable_option_checking @@ -768,6 +777,7 @@ enable_langinfo enable_dll_unloading with_tzdata enable_dtrace +enable_zipfs enable_framework ' ac_precious_vars='build_alias @@ -1408,6 +1418,7 @@ Optional Features: startup, otherwise use old heuristic (default: on) --enable-dll-unloading enable the 'unload' command (default: on) --enable-dtrace build with DTrace support (default: off) + --enable-zipfs build with Zipfs support (default: on) --enable-framework package shared libraries in MacOSX frameworks (default: off) @@ -2330,6 +2341,7 @@ VERSION=${TCL_VERSION} EXTRA_INSTALL_BINARIES=${EXTRA_INSTALL_BINARIES:-"@:"} EXTRA_BUILD_HTML=${EXTRA_BUILD_HTML:-"@:"} +TCL_ZIP_FILE=libtcl_${TCL_MAJOR_VERSION}_${TCL_MINOR_VERSION}_${TCL_PATCH_LEVEL}.zip #------------------------------------------------------------------------ # Setup configure arguments for bundled packages @@ -3273,6 +3285,7 @@ _ACEOF esac + #-------------------------------------------------------------------- # Supply substitutes for missing POSIX header files. Special notes: # - stdlib.h doesn't define strtol, strtoul, or @@ -4545,6 +4558,7 @@ $as_echo "#define STATIC_BUILD 1" >>confdefs.h fi + #-------------------------------------------------------------------- # Look for a native installed tclsh binary (if available) # If one cannot be found then use the binary we build (fails for @@ -4590,6 +4604,120 @@ if test "$TCLSH_PROG" = ""; then TCLSH_PROG='./${TCL_EXE}' fi +# +# Check for --enable-zipfs flag +# +SC_ENABLE_ZIPFS + +# +# Find a native zip implementation +# + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for zip" >&5 +$as_echo_n "checking for zip... " >&6; } + if ${ac_cv_path_zip+:} false; then : + $as_echo_n "(cached) " >&6 +else + + search_path=`echo ${PATH} | sed -e 's/:/ /g'` + for dir in $search_path ; do + for j in `ls -r $dir/zip 2> /dev/null` \ + `ls -r $dir/zip 2> /dev/null` ; do + if test x"$ac_cv_path_zip" = x ; then + if test -f "$j" ; then + ac_cv_path_zip=$j + break + fi + fi + done + done + +fi + + + if test -f "$ac_cv_path_zip" ; then + ZIP_PROG="$ac_cv_path_zip" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ZIP_PROG" >&5 +$as_echo "$ZIP_PROG" >&6; } + else + # It is not an error if an installed version of Zip can't be located. + ZIP_PROG="" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: No zip found on PATH" >&5 +$as_echo "No zip found on PATH" >&6; } + fi + + + +# +# Find a native compiler +# +# Put a plausible default for CC_FOR_BUILD in Makefile. +if test -z "$CC_FOR_BUILD"; then + if test "x$cross_compiling" = "xno"; then + CC_FOR_BUILD='$(CC)' + else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gcc" >&5 +$as_echo_n "checking for gcc... " >&6; } + if ${ac_cv_path_cc+:} false; then : + $as_echo_n "(cached) " >&6 +else + + search_path=`echo ${PATH} | sed -e 's/:/ /g'` + for dir in $search_path ; do + for j in `ls -r $dir/gcc 2> /dev/null` \ + `ls -r $dir/gcc 2> /dev/null` ; do + if test x"$ac_cv_path_cc" = x ; then + if test -f "$j" ; then + ac_cv_path_cc=$j + break + fi + fi + done + done + +fi + + fi +fi + +# Also set EXEEXT_FOR_BUILD. +if test "x$cross_compiling" = "xno"; then + EXEEXT_FOR_BUILD='$(EXEEXT)' + OBJEXT_FOR_BUILD='$(OBJEXT)' +else + OBJEXT_FOR_BUILD='.no' + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for build system executable suffix" >&5 +$as_echo_n "checking for build system executable suffix... " >&6; } +if ${bfd_cv_build_exeext+:} false; then : + $as_echo_n "(cached) " >&6 +else + rm -f conftest* + echo 'int main () { return 0; }' > conftest.c + bfd_cv_build_exeext= + ${CC_FOR_BUILD} -o conftest conftest.c 1>&5 2>&5 + for file in conftest.*; do + case $file in + *.c | *.o | *.obj | *.ilk | *.pdb) ;; + *) bfd_cv_build_exeext=`echo $file | sed -e s/conftest//` ;; + esac + done + rm -f conftest* + test x"${bfd_cv_build_exeext}" = x && bfd_cv_build_exeext=no +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $bfd_cv_build_exeext" >&5 +$as_echo "$bfd_cv_build_exeext" >&6; } + EXEEXT_FOR_BUILD="" + test x"${bfd_cv_build_exeext}" != xno && EXEEXT_FOR_BUILD=${bfd_cv_build_exeext} +fi + + +if test "$ZIP_PROG" = ""; then + ZIP_PROG='./minizip${EXEEXT_FOR_BUILD}' +fi + + + + #------------------------------------------------------------------------ # Add stuff for zlib #------------------------------------------------------------------------ @@ -10151,6 +10279,53 @@ fi $as_echo "$tcl_ok" >&6; } #-------------------------------------------------------------------- +# Zipfs support +#-------------------------------------------------------------------- + +# Check whether --enable-zipfs was given. +if test "${enable_zipfs+set}" = set; then : + enableval=$enable_zipfs; tcl_ok=$enableval +else + tcl_ok=yes +fi + + if test "$tcl_ok" = "yes" -o "${TCL_THREADS}" = 1; then + ZIPFS_BUILD=1 + else + ZIPFS_BUILD=0 + fi + # Do checking message here to not mess up interleaved configure output + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for building with zipfs" >&5 +$as_echo_n "checking for building with zipfs... " >&6; } + if test "${ZIPFS_BUILD}" = 1; then + if test "${SHARED_BUILD}" = 0; then + ZIPFS_BUILD=2; + +$as_echo "#define ZIPFS_BUILD 2" >>confdefs.h + + INSTALL_LIBRARIES=install-libraries-zipfs-static + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + else + +$as_echo "#define ZIPFS_BUILD 1" >>confdefs.h +\ + INSTALL_LIBRARIES=install-libraries-zipfs-shared + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + fi + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + INSTALL_LIBRARIES=install-libraries + INSTALL_MSGS=install-msgs + fi + + + + + +#-------------------------------------------------------------------- # The check below checks whether the cpuid instruction is usable. #-------------------------------------------------------------------- @@ -10436,6 +10611,7 @@ TCL_SHARED_BUILD=${SHARED_BUILD} + ac_config_files="$ac_config_files Makefile:../unix/Makefile.in dltest/Makefile:../unix/dltest/Makefile.in tclConfig.sh:../unix/tclConfig.sh.in tcl.pc:../unix/tcl.pc.in" cat >confcache <<\_ACEOF diff --git a/unix/configure.ac b/unix/configure.ac index e14d85e..b2700cf 100644 --- a/unix/configure.ac +++ b/unix/configure.ac @@ -30,6 +30,7 @@ VERSION=${TCL_VERSION} EXTRA_INSTALL_BINARIES=${EXTRA_INSTALL_BINARIES:-"@:"} EXTRA_BUILD_HTML=${EXTRA_BUILD_HTML:-"@:"} +TCL_ZIP_FILE=libtcl_${TCL_MAJOR_VERSION}_${TCL_MINOR_VERSION}_${TCL_PATCH_LEVEL}.zip #------------------------------------------------------------------------ # Setup configure arguments for bundled packages @@ -86,6 +87,7 @@ fi AC_PROG_CC AC_C_INLINE + #-------------------------------------------------------------------- # Supply substitutes for missing POSIX header files. Special notes: # - stdlib.h doesn't define strtol, strtoul, or @@ -153,6 +155,28 @@ if test "$TCLSH_PROG" = ""; then TCLSH_PROG='./${TCL_EXE}' fi +# +# Check for --enable-zipfs flag +# +SC_ENABLE_ZIPFS + +# +# Find a native zip implementation +# +SC_PROG_ZIP + +# +# Find a native compiler +# +AX_CC_FOR_BUILD + +if test "$ZIP_PROG" = ""; then + ZIP_PROG='./minizip${EXEEXT_FOR_BUILD}' +fi + + + + #------------------------------------------------------------------------ # Add stuff for zlib #------------------------------------------------------------------------ @@ -791,6 +815,42 @@ fi AC_MSG_RESULT([$tcl_ok]) #-------------------------------------------------------------------- +# Zipfs support +#-------------------------------------------------------------------- + +AC_ARG_ENABLE(zipfs, + AC_HELP_STRING([--enable-zipfs], + [build with Zipfs support (default: on)]), + [tcl_ok=$enableval], [tcl_ok=yes]) + if test "$tcl_ok" = "yes" -o "${TCL_THREADS}" = 1; then + ZIPFS_BUILD=1 + else + ZIPFS_BUILD=0 + fi + # Do checking message here to not mess up interleaved configure output + AC_MSG_CHECKING([for building with zipfs]) + if test "${ZIPFS_BUILD}" = 1; then + if test "${SHARED_BUILD}" = 0; then + ZIPFS_BUILD=2; + AC_DEFINE(ZIPFS_BUILD, 2, [Are we building with zipfs enabled?]) + INSTALL_LIBRARIES=install-libraries-zipfs-static + AC_MSG_RESULT([yes]) + else + AC_DEFINE(ZIPFS_BUILD, 1, [Are we building with zipfs enabled?])\ + INSTALL_LIBRARIES=install-libraries-zipfs-shared + AC_MSG_RESULT([yes]) + fi + else + AC_MSG_RESULT([no]) + INSTALL_LIBRARIES=install-libraries + INSTALL_MSGS=install-msgs + fi + AC_SUBST(ZIPFS_BUILD) + AC_SUBST(INSTALL_LIBRARIES) + AC_SUBST(INSTALL_MSGS) + + +#-------------------------------------------------------------------- # The check below checks whether the cpuid instruction is usable. #-------------------------------------------------------------------- @@ -960,6 +1020,7 @@ AC_SUBST(TCL_PATCH_LEVEL) AC_SUBST(TCL_YEAR) AC_SUBST(PKG_CFG_ARGS) +AC_SUBST(TCL_ZIP_FILE) AC_SUBST(TCL_LIB_FILE) AC_SUBST(TCL_LIB_FLAG) AC_SUBST(TCL_LIB_SPEC) diff --git a/unix/tcl.m4 b/unix/tcl.m4 index 45922e0..132e602 100644 --- a/unix/tcl.m4 +++ b/unix/tcl.m4 @@ -276,6 +276,7 @@ AC_DEFUN([SC_PATH_TKCONFIG], [ # TCL_BIN_DIR # TCL_SRC_DIR # TCL_LIB_FILE +# TCL_ZIP_FILE #------------------------------------------------------------------------ AC_DEFUN([SC_LOAD_TCLCONFIG], [ @@ -289,6 +290,7 @@ AC_DEFUN([SC_LOAD_TCLCONFIG], [ fi # eval is required to do the TCL_DBGX substitution + eval "TCL_ZIP_FILE=\"${TCL_ZIP_FILE}\"" eval "TCL_LIB_FILE=\"${TCL_LIB_FILE}\"" eval "TCL_STUB_LIB_FILE=\"${TCL_STUB_LIB_FILE}\"" @@ -336,6 +338,7 @@ AC_DEFUN([SC_LOAD_TCLCONFIG], [ AC_SUBST(TCL_BIN_DIR) AC_SUBST(TCL_SRC_DIR) + AC_SUBST(TCL_ZIP_FILE) AC_SUBST(TCL_LIB_FILE) AC_SUBST(TCL_LIB_FLAG) AC_SUBST(TCL_LIB_SPEC) @@ -542,6 +545,7 @@ AC_DEFUN([SC_ENABLE_SHARED], [ SHARED_BUILD=0 AC_DEFINE(STATIC_BUILD, 1, [Is this a static build?]) fi + AC_SUBST(SHARED_BUILD) ]) #------------------------------------------------------------------------ @@ -3014,6 +3018,109 @@ if test "x$NEED_FAKE_RFC2553" = "x1"; then AC_CHECK_FUNC(strlcpy) fi ]) + +#------------------------------------------------------------------------ +# SC_PROG_ZIP +# Locate a zip encoder installed on the system path, or none. +# +# Arguments: +# none +# +# Results: +# Substitutes the following vars: +# ZIP_PROG +#------------------------------------------------------------------------ + +AC_DEFUN([SC_PROG_ZIP], [ + AC_MSG_CHECKING([for zip]) + AC_CACHE_VAL(ac_cv_path_zip, [ + search_path=`echo ${PATH} | sed -e 's/:/ /g'` + for dir in $search_path ; do + for j in `ls -r $dir/zip 2> /dev/null` \ + `ls -r $dir/zip 2> /dev/null` ; do + if test x"$ac_cv_path_zip" = x ; then + if test -f "$j" ; then + ac_cv_path_zip=$j + break + fi + fi + done + done + ]) + + if test -f "$ac_cv_path_zip" ; then + ZIP_PROG="$ac_cv_path_zip" + AC_MSG_RESULT([$ZIP_PROG]) + else + # It is not an error if an installed version of Zip can't be located. + ZIP_PROG="" + AC_MSG_RESULT([No zip found on PATH]) + fi + AC_SUBST(ZIP_PROG) +]) + +#------------------------------------------------------------------------ +# SC_CC_FOR_BUILD +# For cross compiles, locate a C compiler that can generate native binaries. +# +# Arguments: +# none +# +# Results: +# Substitutes the following vars: +# CC_FOR_BUILD +# EXEEXT_FOR_BUILD +#------------------------------------------------------------------------ + +dnl Get a default for CC_FOR_BUILD to put into Makefile. +AC_DEFUN([AX_CC_FOR_BUILD], +[# Put a plausible default for CC_FOR_BUILD in Makefile. +if test -z "$CC_FOR_BUILD"; then + if test "x$cross_compiling" = "xno"; then + CC_FOR_BUILD='$(CC)' + else + AC_MSG_CHECKING([for gcc]) + AC_CACHE_VAL(ac_cv_path_cc, [ + search_path=`echo ${PATH} | sed -e 's/:/ /g'` + for dir in $search_path ; do + for j in `ls -r $dir/gcc 2> /dev/null` \ + `ls -r $dir/gcc 2> /dev/null` ; do + if test x"$ac_cv_path_cc" = x ; then + if test -f "$j" ; then + ac_cv_path_cc=$j + break + fi + fi + done + done + ]) + fi +fi +AC_SUBST(CC_FOR_BUILD) +# Also set EXEEXT_FOR_BUILD. +if test "x$cross_compiling" = "xno"; then + EXEEXT_FOR_BUILD='$(EXEEXT)' + OBJEXT_FOR_BUILD='$(OBJEXT)' +else + OBJEXT_FOR_BUILD='.no' + AC_CACHE_CHECK([for build system executable suffix], bfd_cv_build_exeext, + [rm -f conftest* + echo 'int main () { return 0; }' > conftest.c + bfd_cv_build_exeext= + ${CC_FOR_BUILD} -o conftest conftest.c 1>&5 2>&5 + for file in conftest.*; do + case $file in + *.c | *.o | *.obj | *.ilk | *.pdb) ;; + *) bfd_cv_build_exeext=`echo $file | sed -e s/conftest//` ;; + esac + done + rm -f conftest* + test x"${bfd_cv_build_exeext}" = x && bfd_cv_build_exeext=no]) + EXEEXT_FOR_BUILD="" + test x"${bfd_cv_build_exeext}" != xno && EXEEXT_FOR_BUILD=${bfd_cv_build_exeext} +fi +AC_SUBST(EXEEXT_FOR_BUILD)])dnl +AC_SUBST(OBJEXT_FOR_BUILD)])dnl # Local Variables: # mode: autoconf # End: diff --git a/unix/tclAppInit.c b/unix/tclAppInit.c index 9bbc88b..3587f35 100644 --- a/unix/tclAppInit.c +++ b/unix/tclAppInit.c @@ -79,6 +79,8 @@ main( #ifdef TCL_LOCAL_MAIN_HOOK TCL_LOCAL_MAIN_HOOK(&argc, &argv); +#else + TclZipfs_AppHook(&argc, &argv); #endif Tcl_Main(argc, argv, TCL_LOCAL_APPINIT); diff --git a/unix/tclConfig.sh.in b/unix/tclConfig.sh.in index fdc56b7..3da4afd 100644 --- a/unix/tclConfig.sh.in +++ b/unix/tclConfig.sh.in @@ -39,6 +39,9 @@ TCL_SHARED_BUILD=@TCL_SHARED_BUILD@ # The name of the Tcl library (may be either a .a file or a shared library): TCL_LIB_FILE='@TCL_LIB_FILE@' +# The name of a zip containing the /library and /encodings (may be either a .zip file or a shared library): +TCL_ZIP_FILE='@TCL_ZIP_FILE@' + # Additional libraries to use when linking Tcl. TCL_LIBS='@TCL_LIBS@' -- cgit v0.12 From be47788793ebb60ab44b11d994b5f053e8f6050a Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Fri, 17 Nov 2017 03:09:26 +0000 Subject: Moved Zipfs initialization and path hinting out of tclInterp.c and into a preinit script populated by TclZipfs_AppHook --- generic/tclInterp.c | 2 -- generic/tclZipfs.c | 22 +++++++++++++++++++++- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/generic/tclInterp.c b/generic/tclInterp.c index 2b0582a..d9dfd37 100644 --- a/generic/tclInterp.c +++ b/generic/tclInterp.c @@ -402,8 +402,6 @@ Tcl_Init( " set scripts {{set tcl_library}}\n" " } else {\n" " set scripts {}\n" -" lappend scripts {set temp zipfs:/lib/tcl/tcl_library}\n" -" lappend scripts {set temp zipfs:/app/tcl_library}\n" " if {[info exists env(TCL_LIBRARY)] && ($env(TCL_LIBRARY) ne {})} {\n" " lappend scripts {set env(TCL_LIBRARY)}\n" " lappend scripts {\n" diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c index 9dfca7a..bc7d65a 100644 --- a/generic/tclZipfs.c +++ b/generic/tclZipfs.c @@ -3816,6 +3816,7 @@ TclZipfs_Init(Tcl_Interp *interp) #ifdef HAVE_ZLIB /* one-time initialization */ WriteLock(); + Tcl_StaticPackage(interp, "zipfs", TclZipfs_Init, TclZipfs_Init); if (!ZipFS.initialized) { #ifdef TCL_THREADS static const Tcl_Time t = { 0, 0 }; @@ -3870,7 +3871,7 @@ TclZipfs_Init(Tcl_Interp *interp) Tcl_LinkVar(interp, "::zipfs::wrmax", (char *) &ZipFS.wrmax, TCL_LINK_INT); TclMakeEnsemble(interp, "zipfs", initMap); - Tcl_PkgProvide(interp, "zipfs", "1.0"); + Tcl_PkgProvide(interp, "zipfs", "2.0"); } return TCL_OK; #else @@ -3914,6 +3915,25 @@ int TclZipfs_AppHook(int *argc, char ***argv){ Tcl_FindExecutable(*argv[0]); archive=Tcl_GetNameOfExecutable(); TclZipfs_Init(NULL); + TclSetPreInitScript( +"foreach {path} {\n" +" {" ZIPFS_APP_MOUNT "/tcl_library}\n" +" {" ZIPFS_ZIP_MOUNT "/tcl_library}\n" +"} {\n" +" if {![file exists [file join $path init.tcl]]} continue\n" +" set ::tcl_library $path\n" +" break\n" +"}\n" +"foreach {path} {\n" +" {" ZIPFS_APP_MOUNT "/tk_library}\n" +" {" ZIPFS_ZIP_MOUNT "/tk_library}\n" +" {" ZIPFS_VOLUME "lib/tk/tk_library}\n" +"} {\n" +" if {[file exists [file join $path init.tcl]]} continue\n" +" set ::tk_library $path\n" +" break\n" +"}\n" + ); if(!TclZipfs_Mount(NULL, archive, ZIPFS_APP_MOUNT, NULL)) { int found; Tcl_Obj *vfsinitscript; -- cgit v0.12 From e84763748b39ba9655d93c056c0bfe614b7cb791 Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Fri, 17 Nov 2017 04:13:48 +0000 Subject: First pass on the Msys style windows build. Moving Zipfs features closer together in the autoconf --- unix/Makefile.in | 32 ++++---- unix/configure | 231 ++++++++++++++++++++++++++-------------------------- unix/configure.ac | 41 +++++----- win/Makefile.in | 149 ++++++++++++++++++++++++++++++++- win/configure | 176 ++++++++++++++++++++++++++++++++++++++- win/configure.ac | 59 ++++++++++++++ win/tcl.m4 | 108 ++++++++++++++++++++++++ win/tclAppInit.c | 2 + win/tclConfig.sh.in | 3 + 9 files changed, 644 insertions(+), 157 deletions(-) diff --git a/unix/Makefile.in b/unix/Makefile.in index d7cc3c7..4540710 100644 --- a/unix/Makefile.in +++ b/unix/Makefile.in @@ -199,10 +199,6 @@ LD_SEARCH_FLAGS = @LD_SEARCH_FLAGS@ BUILD_DLTEST = @BUILD_DLTEST@ #BUILD_DLTEST = -TCL_ZIP_FILE = @TCL_ZIP_FILE@ -TCL_VFS_PATH = libtcl.vfs/tcl_library -TCL_VFS_ROOT = libtcl.vfs - TCL_LIB_FILE = @TCL_LIB_FILE@ #TCL_LIB_FILE = libtcl.a @@ -247,12 +243,6 @@ ZLIB_INCLUDE = @ZLIB_INCLUDE@ CC = @CC@ OBJEXT = @OBJEXT@ -HOST_CC = @CC_FOR_BUILD@ -HOST_EXEEXT = @EXEEXT_FOR_BUILD@ -HOST_OBJEXT = @OBJEXT_FOR_BUILD@ -ZIPFS_BUILD = @ZIPFS_BUILD@ -NATIVE_ZIP = @ZIP_PROG@ -SHARED_BUILD = @SHARED_BUILD@ #CC = purify -best-effort @CC@ -DPURIFY @@ -263,10 +253,6 @@ MAN_FLAGS = @MAN_FLAGS@ # If non-empty, install the timezone files that are included with Tcl, # otherwise use the ones that ship with the OS. INSTALL_TZDATA = @INSTALL_TZDATA@ -INSTALL_LIBRARIES = @INSTALL_LIBRARIES@ -INSTALL_MSGS = @INSTALL_MSGS@ - - #-------------------------------------------------------------------------- # The information below is usually usable as is. The configure script won't @@ -633,6 +619,23 @@ ZLIB_SRCS = \ SRCS = $(GENERIC_SRCS) $(TOMMATH_SRCS) $(UNIX_SRCS) $(NOTIFY_SRCS) \ $(OO_SRCS) $(STUB_SRCS) @PLAT_SRCS@ @ZLIB_SRCS@ +### +# Tip 430 - ZipFS Modifications +### + +TCL_ZIP_FILE = @TCL_ZIP_FILE@ +TCL_VFS_PATH = libtcl.vfs/tcl_library +TCL_VFS_ROOT = libtcl.vfs + +HOST_CC = @CC_FOR_BUILD@ +HOST_EXEEXT = @EXEEXT_FOR_BUILD@ +HOST_OBJEXT = @OBJEXT_FOR_BUILD@ +ZIPFS_BUILD = @ZIPFS_BUILD@ +NATIVE_ZIP = @ZIP_PROG@ +SHARED_BUILD = @SHARED_BUILD@ +INSTALL_LIBRARIES = @INSTALL_LIBRARIES@ +INSTALL_MSGS = @INSTALL_MSGS@ + # Minizip MINIZIP_OBJS = \ adler32.$(HOST_OBJEXT) \ @@ -652,7 +655,6 @@ MINIZIP_OBJS = \ ZIP_INSTALL_OBJS = minizip${EXEEXT_FOR_BUILD} - #-------------------------------------------------------------------------- # Start of rules #-------------------------------------------------------------------------- diff --git a/unix/configure b/unix/configure index cff57cb..44bd2a6 100755 --- a/unix/configure +++ b/unix/configure @@ -668,6 +668,9 @@ TCL_VERSION INSTALL_MSGS INSTALL_LIBRARIES ZIPFS_BUILD +EXEEXT_FOR_BUILD +CC_FOR_BUILD +ZIP_PROG DTRACE LDFLAGS_DEFAULT CFLAGS_DEFAULT @@ -702,9 +705,6 @@ RANLIB ZLIB_INCLUDE ZLIB_SRCS ZLIB_OBJS -EXEEXT_FOR_BUILD -CC_FOR_BUILD -ZIP_PROG TCLSH_PROG SHARED_BUILD TCL_THREADS @@ -4594,120 +4594,6 @@ if test "$TCLSH_PROG" = ""; then TCLSH_PROG='./${TCL_EXE}' fi -# -# Check for --enable-zipfs flag -# -SC_ENABLE_ZIPFS - -# -# Find a native zip implementation -# - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for zip" >&5 -$as_echo_n "checking for zip... " >&6; } - if ${ac_cv_path_zip+:} false; then : - $as_echo_n "(cached) " >&6 -else - - search_path=`echo ${PATH} | sed -e 's/:/ /g'` - for dir in $search_path ; do - for j in `ls -r $dir/zip 2> /dev/null` \ - `ls -r $dir/zip 2> /dev/null` ; do - if test x"$ac_cv_path_zip" = x ; then - if test -f "$j" ; then - ac_cv_path_zip=$j - break - fi - fi - done - done - -fi - - - if test -f "$ac_cv_path_zip" ; then - ZIP_PROG="$ac_cv_path_zip" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ZIP_PROG" >&5 -$as_echo "$ZIP_PROG" >&6; } - else - # It is not an error if an installed version of Zip can't be located. - ZIP_PROG="" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: No zip found on PATH" >&5 -$as_echo "No zip found on PATH" >&6; } - fi - - - -# -# Find a native compiler -# -# Put a plausible default for CC_FOR_BUILD in Makefile. -if test -z "$CC_FOR_BUILD"; then - if test "x$cross_compiling" = "xno"; then - CC_FOR_BUILD='$(CC)' - else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gcc" >&5 -$as_echo_n "checking for gcc... " >&6; } - if ${ac_cv_path_cc+:} false; then : - $as_echo_n "(cached) " >&6 -else - - search_path=`echo ${PATH} | sed -e 's/:/ /g'` - for dir in $search_path ; do - for j in `ls -r $dir/gcc 2> /dev/null` \ - `ls -r $dir/gcc 2> /dev/null` ; do - if test x"$ac_cv_path_cc" = x ; then - if test -f "$j" ; then - ac_cv_path_cc=$j - break - fi - fi - done - done - -fi - - fi -fi - -# Also set EXEEXT_FOR_BUILD. -if test "x$cross_compiling" = "xno"; then - EXEEXT_FOR_BUILD='$(EXEEXT)' - OBJEXT_FOR_BUILD='$(OBJEXT)' -else - OBJEXT_FOR_BUILD='.no' - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for build system executable suffix" >&5 -$as_echo_n "checking for build system executable suffix... " >&6; } -if ${bfd_cv_build_exeext+:} false; then : - $as_echo_n "(cached) " >&6 -else - rm -f conftest* - echo 'int main () { return 0; }' > conftest.c - bfd_cv_build_exeext= - ${CC_FOR_BUILD} -o conftest conftest.c 1>&5 2>&5 - for file in conftest.*; do - case $file in - *.c | *.o | *.obj | *.ilk | *.pdb) ;; - *) bfd_cv_build_exeext=`echo $file | sed -e s/conftest//` ;; - esac - done - rm -f conftest* - test x"${bfd_cv_build_exeext}" = x && bfd_cv_build_exeext=no -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $bfd_cv_build_exeext" >&5 -$as_echo "$bfd_cv_build_exeext" >&6; } - EXEEXT_FOR_BUILD="" - test x"${bfd_cv_build_exeext}" != xno && EXEEXT_FOR_BUILD=${bfd_cv_build_exeext} -fi - - -if test "$ZIP_PROG" = ""; then - ZIP_PROG='./minizip${EXEEXT_FOR_BUILD}' -fi - - - - #------------------------------------------------------------------------ # Add stuff for zlib #------------------------------------------------------------------------ @@ -10272,6 +10158,117 @@ $as_echo "$tcl_ok" >&6; } # Zipfs support #-------------------------------------------------------------------- +# +# Check for --enable-zipfs flag +# +SC_ENABLE_ZIPFS + +# +# Find a native zip implementation +# + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for zip" >&5 +$as_echo_n "checking for zip... " >&6; } + if ${ac_cv_path_zip+:} false; then : + $as_echo_n "(cached) " >&6 +else + + search_path=`echo ${PATH} | sed -e 's/:/ /g'` + for dir in $search_path ; do + for j in `ls -r $dir/zip 2> /dev/null` \ + `ls -r $dir/zip 2> /dev/null` ; do + if test x"$ac_cv_path_zip" = x ; then + if test -f "$j" ; then + ac_cv_path_zip=$j + break + fi + fi + done + done + +fi + + + if test -f "$ac_cv_path_zip" ; then + ZIP_PROG="$ac_cv_path_zip" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ZIP_PROG" >&5 +$as_echo "$ZIP_PROG" >&6; } + else + # It is not an error if an installed version of Zip can't be located. + ZIP_PROG="" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: No zip found on PATH" >&5 +$as_echo "No zip found on PATH" >&6; } + fi + + + +# +# Find a native compiler +# +# Put a plausible default for CC_FOR_BUILD in Makefile. +if test -z "$CC_FOR_BUILD"; then + if test "x$cross_compiling" = "xno"; then + CC_FOR_BUILD='$(CC)' + else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gcc" >&5 +$as_echo_n "checking for gcc... " >&6; } + if ${ac_cv_path_cc+:} false; then : + $as_echo_n "(cached) " >&6 +else + + search_path=`echo ${PATH} | sed -e 's/:/ /g'` + for dir in $search_path ; do + for j in `ls -r $dir/gcc 2> /dev/null` \ + `ls -r $dir/gcc 2> /dev/null` ; do + if test x"$ac_cv_path_cc" = x ; then + if test -f "$j" ; then + ac_cv_path_cc=$j + break + fi + fi + done + done + +fi + + fi +fi + +# Also set EXEEXT_FOR_BUILD. +if test "x$cross_compiling" = "xno"; then + EXEEXT_FOR_BUILD='$(EXEEXT)' + OBJEXT_FOR_BUILD='$(OBJEXT)' +else + OBJEXT_FOR_BUILD='.no' + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for build system executable suffix" >&5 +$as_echo_n "checking for build system executable suffix... " >&6; } +if ${bfd_cv_build_exeext+:} false; then : + $as_echo_n "(cached) " >&6 +else + rm -f conftest* + echo 'int main () { return 0; }' > conftest.c + bfd_cv_build_exeext= + ${CC_FOR_BUILD} -o conftest conftest.c 1>&5 2>&5 + for file in conftest.*; do + case $file in + *.c | *.o | *.obj | *.ilk | *.pdb) ;; + *) bfd_cv_build_exeext=`echo $file | sed -e s/conftest//` ;; + esac + done + rm -f conftest* + test x"${bfd_cv_build_exeext}" = x && bfd_cv_build_exeext=no +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $bfd_cv_build_exeext" >&5 +$as_echo "$bfd_cv_build_exeext" >&6; } + EXEEXT_FOR_BUILD="" + test x"${bfd_cv_build_exeext}" != xno && EXEEXT_FOR_BUILD=${bfd_cv_build_exeext} +fi + + +if test "$ZIP_PROG" = ""; then + ZIP_PROG='./minizip${EXEEXT_FOR_BUILD}' +fi + # Check whether --enable-zipfs was given. if test "${enable_zipfs+set}" = set; then : enableval=$enable_zipfs; tcl_ok=$enableval diff --git a/unix/configure.ac b/unix/configure.ac index b2700cf..35429b5 100644 --- a/unix/configure.ac +++ b/unix/configure.ac @@ -155,28 +155,6 @@ if test "$TCLSH_PROG" = ""; then TCLSH_PROG='./${TCL_EXE}' fi -# -# Check for --enable-zipfs flag -# -SC_ENABLE_ZIPFS - -# -# Find a native zip implementation -# -SC_PROG_ZIP - -# -# Find a native compiler -# -AX_CC_FOR_BUILD - -if test "$ZIP_PROG" = ""; then - ZIP_PROG='./minizip${EXEEXT_FOR_BUILD}' -fi - - - - #------------------------------------------------------------------------ # Add stuff for zlib #------------------------------------------------------------------------ @@ -818,6 +796,25 @@ AC_MSG_RESULT([$tcl_ok]) # Zipfs support #-------------------------------------------------------------------- +# +# Check for --enable-zipfs flag +# +SC_ENABLE_ZIPFS + +# +# Find a native zip implementation +# +SC_PROG_ZIP + +# +# Find a native compiler +# +AX_CC_FOR_BUILD + +if test "$ZIP_PROG" = ""; then + ZIP_PROG='./minizip${EXEEXT_FOR_BUILD}' +fi + AC_ARG_ENABLE(zipfs, AC_HELP_STRING([--enable-zipfs], [build with Zipfs support (default: on)]), diff --git a/win/Makefile.in b/win/Makefile.in index 1a88cc8..14868cf 100644 --- a/win/Makefile.in +++ b/win/Makefile.in @@ -137,6 +137,11 @@ DDEDOTVER = @TCL_DDE_MAJOR_VERSION@.@TCL_DDE_MINOR_VERSION@ REGVER = @TCL_REG_MAJOR_VERSION@@TCL_REG_MINOR_VERSION@ REGDOTVER = @TCL_REG_MAJOR_VERSION@.@TCL_REG_MINOR_VERSION@ +TCL_ZIP_FILE = @TCL_ZIP_FILE@ +TCL_VFS_PATH = libtcl.vfs/tcl_library +TCL_VFS_ROOT = libtcl.vfs + + TCL_STUB_LIB_FILE = @TCL_STUB_LIB_FILE@ TCL_DLL_FILE = @TCL_DLL_FILE@ TCL_LIB_FILE = @TCL_LIB_FILE@ @@ -196,6 +201,42 @@ SHELL = @SHELL@ RM = rm -f COPY = cp +### +# Tip 430 - ZipFS Modifications +### + +TCL_ZIP_FILE = @TCL_ZIP_FILE@ +TCL_VFS_PATH = libtcl.vfs/tcl_library +TCL_VFS_ROOT = libtcl.vfs + +HOST_CC = @CC_FOR_BUILD@ +HOST_EXEEXT = @EXEEXT_FOR_BUILD@ +HOST_OBJEXT = @OBJEXT_FOR_BUILD@ +ZIPFS_BUILD = @ZIPFS_BUILD@ +NATIVE_ZIP = @ZIP_PROG@ +SHARED_BUILD = @SHARED_BUILD@ +INSTALL_MSGS = @INSTALL_MSGS@ +INSTALL_LIBRARIES = @INSTALL_LIBRARIES@ + +# Minizip +MINIZIP_OBJS = \ + adler32.$(HOST_OBJEXT) \ + compress.$(HOST_OBJEXT) \ + crc32.$(HOST_OBJEXT) \ + deflate.$(HOST_OBJEXT) \ + infback.$(HOST_OBJEXT) \ + inffast.$(HOST_OBJEXT) \ + inflate.$(HOST_OBJEXT) \ + inftrees.$(HOST_OBJEXT) \ + ioapi.$(HOST_OBJEXT) \ + trees.$(HOST_OBJEXT) \ + uncompr.$(HOST_OBJEXT) \ + zip.$(HOST_OBJEXT) \ + zutil.$(HOST_OBJEXT) \ + minizip.$(HOST_OBJEXT) + +ZIP_INSTALL_OBJS = minizip${EXEEXT_FOR_BUILD} + CC_SWITCHES = ${CFLAGS} ${CFLAGS_WARNING} ${TCL_SHLIB_CFLAGS} \ -I"${ZLIB_DIR_NATIVE}" -I"${GENERIC_DIR_NATIVE}" \ -DMP_PREC=4 -I"${TOMMATH_DIR_NATIVE}" -I"${WIN_DIR_NATIVE}" \ @@ -434,9 +475,17 @@ libraries: doc: +tclzipfile: ${TCL_ZIP_FILE} + +${TCL_ZIP_FILE}: ${ZIP_INSTALL_OBJS} + rm -rf ${TCL_VFS_ROOT} + mkdir -p ${TCL_VFS_PATH} + cp -a ../library/* ${TCL_VFS_PATH} + cd ${TCL_VFS_ROOT} ; ../minizip${EXEEXT_FOR_BUILD} -o ../${TCL_ZIP_FILE} `find . -type f` + $(TCLSH): $(TCLSH_OBJS) @LIBRARIES@ $(TCL_STUB_LIB_FILE) tclsh.$(RES) $(CC) $(CFLAGS) $(TCLSH_OBJS) $(TCL_LIB_FILE) $(TCL_STUB_LIB_FILE) $(LIBS) \ - tclsh.$(RES) $(CC_EXENAME) $(LDFLAGS_CONSOLE) + tclsh.$(RES) $(CC_EXENAME) $(LDFLAGS_CONSOLE) @VC_MANIFEST_EMBED_EXE@ cat32.$(OBJEXT): cat.c @@ -453,10 +502,13 @@ ${TCL_STUB_LIB_FILE}: ${STUB_OBJS} @MAKE_STUB_LIB@ ${STUB_OBJS} @POST_MAKE_LIB@ -${TCL_DLL_FILE}: ${TCL_OBJS} tcl.$(RES) @ZLIB_DLL_FILE@ +${TCL_DLL_FILE}: ${TCL_OBJS} tcl.$(RES) @ZLIB_DLL_FILE@ ${TCL_ZIP_FILE} @$(RM) ${TCL_DLL_FILE} $(TCL_LIB_FILE) @MAKE_DLL@ ${TCL_OBJS} tcl.$(RES) $(SHLIB_LD_LIBS) @VC_MANIFEST_EMBED_DLL@ +ifeq (${ZIPFS_BUILD},1) + cat ${TCL_ZIP_FILE} >> ${TCL_DLL_FILE} +endif ${TCL_LIB_FILE}: ${TCL_OBJS} ${DDE_OBJS} ${REG_OBJS} @$(RM) ${TCL_LIB_FILE} @@ -528,6 +580,8 @@ tclPkgConfig.${OBJEXT}: tclPkgConfig.c -DCFG_RUNTIME_SCRDIR=\"$(TCL_LIBRARY_NATIVE)\" \ -DCFG_RUNTIME_INCDIR=\"$(includedir_native)\" \ -DCFG_RUNTIME_DOCDIR=\"$(mandir_native)\" \ + -DCFG_RUNTIME_DLLFILE="\"$(TCL_LIB_FILE)\"" \ + -DCFG_RUNTIME_ZIPFILE="\"$(TCL_ZIP_FILE)\"" \ -DBUILD_tcl \ @DEPARG@ $(CC_OBJNAME) @@ -551,6 +605,76 @@ tclOOStubLib.${OBJEXT}: tclOOStubLib.c .rc.$(RES): $(RC) @RC_OUT@ $@ @RC_TYPE@ @RC_DEFINES@ @RC_INCLUDE@ "$(GENERIC_DIR_NATIVE)" @RC_INCLUDE@ "$(WIN_DIR_NATIVE)" @DEPARG@ + + +#-------------------------------------------------------------------------- +# Minizip implementation +#-------------------------------------------------------------------------- +adler32.$(HOST_OBJEXT): + $(HOST_CC) -o $@ -I$(ZLIB_DIR) -c $(ZLIB_DIR)/adler32.c + +compress.$(HOST_OBJEXT): + $(HOST_CC) -o $@ -I$(ZLIB_DIR) -c $(ZLIB_DIR)/compress.c + +crc32.$(HOST_OBJEXT): + $(HOST_CC) -o $@ -I$(ZLIB_DIR) -c $(ZLIB_DIR)/crc32.c + +deflate.$(HOST_OBJEXT): + $(HOST_CC) -o $@ -I$(ZLIB_DIR) -c $(ZLIB_DIR)/deflate.c + +ioapi.$(HOST_OBJEXT): + $(HOST_CC) -o $@ -I$(ZLIB_DIR) -I$(ZLIB_DIR)/contrib/minizip -c $(ZLIB_DIR)/contrib/minizip/ioapi.c + +infback.$(HOST_OBJEXT): + $(HOST_CC) -o $@ -I$(ZLIB_DIR) -c $(ZLIB_DIR)/infback.c + +inffast.$(HOST_OBJEXT): + $(HOST_CC) -o $@ -I$(ZLIB_DIR) -c $(ZLIB_DIR)/inffast.c + +inflate.$(HOST_OBJEXT): + $(HOST_CC) -o $@ -I$(ZLIB_DIR) -c $(ZLIB_DIR)/inflate.c + +inftrees.$(HOST_OBJEXT): + $(HOST_CC) -o $@ -I$(ZLIB_DIR) -c $(ZLIB_DIR)/inftrees.c + +trees.$(HOST_OBJEXT): + $(HOST_CC) -o $@ -I$(ZLIB_DIR) -c $(ZLIB_DIR)/trees.c + +uncompr.$(HOST_OBJEXT): + $(HOST_CC) -o $@ -I$(ZLIB_DIR) -c $(ZLIB_DIR)/uncompr.c + +zip.$(HOST_OBJEXT): + $(HOST_CC) -o $@ -I$(ZLIB_DIR) -I$(ZLIB_DIR)/contrib/minizip -c $(ZLIB_DIR)/contrib/minizip/zip.c + +zutil.$(HOST_OBJEXT): + $(HOST_CC) -o $@ -I$(ZLIB_DIR) -c $(ZLIB_DIR)/zutil.c + +minizip.$(HOST_OBJEXT): + $(HOST_CC) -o $@ -I$(ZLIB_DIR) -I$(ZLIB_DIR)/contrib/minizip -c $(ZLIB_DIR)/contrib/minizip/minizip.c + +minizip${EXEEXT_FOR_BUILD}: $(MINIZIP_OBJS) + $(HOST_CC) -o $@ $(MINIZIP_OBJS) + +tclvfs.zip: minizip${EXEEXT_FOR_BUILD} + rm -rf $(TCL_VFS_ROOT) + mkdir -p $(TCL_VFS_PATH) + @for i in "$(TCL_VFS_PATH)"; \ + do \ + if [ ! -d "$$i" ] ; then \ + echo "Making directory $$i"; \ + $(INSTALL_DATA_DIR) "$$i"; \ + else true; \ + fi; \ + done; + cp -a ../library/* $(TCL_VFS_PATH) + (cd $TCL_VFS ROOT ; ./minizip${EXEEXT_FOR_BUILD} -o ../tclvfs.zip `find . -type f`) + +zipsetupstub.$(HOST_OBJEXT): $(COMPAT_DIR)/zipsetupstub.c + $(HOST_CC) -o $@ -I$(ZLIB_DIR) -c $(COMPAT_DIR)/zipsetupstub.c + +zipsetupstub${EXEEXT_FOR_BUILD}: zipsetupstub.$(HOST_OBJEXT) + $(HOST_CC) -o $@ zipsetupstub.$(HOST_OBJEXT) + # The following target generates the file generic/tclDate.c from the yacc # grammar found in generic/tclGetDate.y. This is only run by hand as yacc is # not available in all environments. The name of the .c file is different than @@ -626,6 +750,25 @@ install-binaries: binaries $(COPY) $(REG_LIB_FILE) $(LIB_INSTALL_DIR)/reg${REGDOTVER}; \ fi +install-libraries-zipfs-shared: libraries + @for i in "$(SCRIPT_INSTALL_DIR)"; \ + do \ + if [ ! -d "$$i" ] ; then \ + echo "Making directory $$i"; \ + $(INSTALL_DATA_DIR) "$$i"; \ + else true; \ + fi; \ + done; + @echo "Installing library files to $(SCRIPT_INSTALL_DIR)/"; + @for i in \ + $(UNIX_DIR)/tclAppInit.c @LDAIX_SRC@ @DTRACE_SRC@; \ + do \ + $(INSTALL_DATA) $$i "$(SCRIPT_INSTALL_DIR)"; \ + done; + +install-libraries-zipfs-static: install-libraries-zipfs-shared + $(INSTALL_DATA) ${TCL_ZIP_FILE} "$(LIB_INSTALL_DIR)" ;\ + install-libraries: libraries install-tzdata install-msgs @for i in "$$($(CYGPATH) $(prefix)/lib)" "$(INCLUDE_INSTALL_DIR)" \ $(SCRIPT_INSTALL_DIR); \ @@ -758,6 +901,7 @@ clean: cleanhelp clean-packages $(RM) *.lib *.a *.exp *.dll *.$(RES) *.${OBJEXT} *~ \#* TAGS a.out $(RM) $(TCLSH) $(CAT32) $(RM) *.pch *.ilk *.pdb + minizip${EXEEXT_FOR_BUILD} *.${HOST_OBJEXT} distclean: distclean-packages clean $(RM) Makefile config.status config.cache config.log tclConfig.sh \ @@ -890,5 +1034,6 @@ html-tk: $(TCLSH) .PHONY: gdb depend cleanhelp clean distclean packages install-packages .PHONY: test-packages clean-packages distclean-packages genstubs html .PHONY: html-tcl html-tk +.PHONY: iinstall-libraries-zipfs-shared install-libraries-zipfs-static tclzipfile # DO NOT DELETE THIS LINE -- make depend depends on it. diff --git a/win/configure b/win/configure index fdd3adb..ddba42a 100755 --- a/win/configure +++ b/win/configure @@ -687,6 +687,7 @@ TCL_STATIC_LIB_FLAG TCL_STATIC_LIB_FILE TCL_LIB_FLAG TCL_LIB_FILE +TCL_ZIP_FILE TCL_EXE PKG_CFG_ARGS TCL_PATCH_LEVEL @@ -699,6 +700,12 @@ VC_MANIFEST_EMBED_EXE VC_MANIFEST_EMBED_DLL LDFLAGS_DEFAULT CFLAGS_DEFAULT +INSTALL_MSGS +INSTALL_LIBRARIES +ZIPFS_BUILD +EXEEXT_FOR_BUILD +CC_FOR_BUILD +ZIP_PROG ZLIB_OBJS ZLIB_LIBS ZLIB_DLL_FILE @@ -708,6 +715,7 @@ CFLAGS_DEBUG DL_LIBS CELIB_DIR CYGPATH +SHARED_BUILD TCL_THREADS SET_MAKE RC @@ -760,7 +768,8 @@ PACKAGE_VERSION PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR -SHELL' +SHELL +OBJEXT_FOR_BUILD' ac_subst_files='' ac_user_opts=' enable_option_checking @@ -770,6 +779,7 @@ enable_shared enable_64bit enable_wince with_celib +enable_zipfs enable_symbols enable_embedded_manifest ' @@ -1393,6 +1403,7 @@ Optional Features: --enable-shared build and link with shared libraries (default: on) --enable-64bit enable 64bit support (where applicable) --enable-wince enable Win/CE support (where applicable) + --enable-zipfs build with Zipfs support (default: on) --enable-symbols build with debugging symbols (default: off) --enable-embedded-manifest embed manifest if possible (default: yes) @@ -2117,6 +2128,8 @@ REGVER=$TCL_REG_MAJOR_VERSION$TCL_REG_MINOR_VERSION PKG_CFG_ARGS=$@ +TCL_ZIP_FILE=libtcl_${TCL_MAJOR_VERSION}_${TCL_MINOR_VERSION}_${TCL_PATCH_LEVEL}.zip + #------------------------------------------------------------------------ # Empty slate for bundled packages, to avoid stale configuration #------------------------------------------------------------------------ @@ -3772,6 +3785,7 @@ $as_echo "#define STATIC_BUILD 1" >>confdefs.h fi + #-------------------------------------------------------------------- # The statements below define a collection of compile flags. This # macro depends on the value of SHARED_BUILD, and should be called @@ -4828,6 +4842,165 @@ _ACEOF fi + +#-------------------------------------------------------------------- +# Zipfs support +#-------------------------------------------------------------------- + +# +# Check for --enable-zipfs flag +# +SC_ENABLE_ZIPFS + +# +# Find a native zip implementation +# + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for zip" >&5 +$as_echo_n "checking for zip... " >&6; } + if ${ac_cv_path_zip+:} false; then : + $as_echo_n "(cached) " >&6 +else + + search_path=`echo ${PATH} | sed -e 's/:/ /g'` + for dir in $search_path ; do + for j in `ls -r $dir/zip 2> /dev/null` \ + `ls -r $dir/zip 2> /dev/null` ; do + if test x"$ac_cv_path_zip" = x ; then + if test -f "$j" ; then + ac_cv_path_zip=$j + break + fi + fi + done + done + +fi + + + if test -f "$ac_cv_path_zip" ; then + ZIP_PROG="$ac_cv_path_zip" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ZIP_PROG" >&5 +$as_echo "$ZIP_PROG" >&6; } + else + # It is not an error if an installed version of Zip can't be located. + ZIP_PROG="" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: No zip found on PATH" >&5 +$as_echo "No zip found on PATH" >&6; } + fi + + + +# +# Find a native compiler +# +# Put a plausible default for CC_FOR_BUILD in Makefile. +if test -z "$CC_FOR_BUILD"; then + if test "x$cross_compiling" = "xno"; then + CC_FOR_BUILD='$(CC)' + else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gcc" >&5 +$as_echo_n "checking for gcc... " >&6; } + if ${ac_cv_path_cc+:} false; then : + $as_echo_n "(cached) " >&6 +else + + search_path=`echo ${PATH} | sed -e 's/:/ /g'` + for dir in $search_path ; do + for j in `ls -r $dir/gcc 2> /dev/null` \ + `ls -r $dir/gcc 2> /dev/null` ; do + if test x"$ac_cv_path_cc" = x ; then + if test -f "$j" ; then + ac_cv_path_cc=$j + break + fi + fi + done + done + +fi + + fi +fi + +# Also set EXEEXT_FOR_BUILD. +if test "x$cross_compiling" = "xno"; then + EXEEXT_FOR_BUILD='$(EXEEXT)' + OBJEXT_FOR_BUILD='$(OBJEXT)' +else + OBJEXT_FOR_BUILD='.no' + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for build system executable suffix" >&5 +$as_echo_n "checking for build system executable suffix... " >&6; } +if ${bfd_cv_build_exeext+:} false; then : + $as_echo_n "(cached) " >&6 +else + rm -f conftest* + echo 'int main () { return 0; }' > conftest.c + bfd_cv_build_exeext= + ${CC_FOR_BUILD} -o conftest conftest.c 1>&5 2>&5 + for file in conftest.*; do + case $file in + *.c | *.o | *.obj | *.ilk | *.pdb) ;; + *) bfd_cv_build_exeext=`echo $file | sed -e s/conftest//` ;; + esac + done + rm -f conftest* + test x"${bfd_cv_build_exeext}" = x && bfd_cv_build_exeext=no +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $bfd_cv_build_exeext" >&5 +$as_echo "$bfd_cv_build_exeext" >&6; } + EXEEXT_FOR_BUILD="" + test x"${bfd_cv_build_exeext}" != xno && EXEEXT_FOR_BUILD=${bfd_cv_build_exeext} +fi + + +if test "$ZIP_PROG" = ""; then + ZIP_PROG='./minizip${EXEEXT_FOR_BUILD}' +fi + +# Check whether --enable-zipfs was given. +if test "${enable_zipfs+set}" = set; then : + enableval=$enable_zipfs; tcl_ok=$enableval +else + tcl_ok=yes +fi + + if test "$tcl_ok" = "yes" -o "${TCL_THREADS}" = 1; then + ZIPFS_BUILD=1 + else + ZIPFS_BUILD=0 + fi + # Do checking message here to not mess up interleaved configure output + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for building with zipfs" >&5 +$as_echo_n "checking for building with zipfs... " >&6; } + if test "${ZIPFS_BUILD}" = 1; then + if test "${SHARED_BUILD}" = 0; then + ZIPFS_BUILD=2; + +$as_echo "#define ZIPFS_BUILD 2" >>confdefs.h + + INSTALL_LIBRARIES=install-libraries-zipfs-static + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + else + +$as_echo "#define ZIPFS_BUILD 1" >>confdefs.h +\ + INSTALL_LIBRARIES=install-libraries-zipfs-shared + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + fi + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + INSTALL_LIBRARIES=install-libraries + INSTALL_MSGS=install-msgs + fi + + + + + #-------------------------------------------------------------------- # Perform additinal compiler tests. #-------------------------------------------------------------------- @@ -5220,6 +5393,7 @@ TCL_WIN_VERSION="$TCL_VERSION.$TCL_RELEASE_LEVEL.`echo $TCL_PATCH_LEVEL | tr -d + # empty on win diff --git a/win/configure.ac b/win/configure.ac index d03695c..0bb0d7d 100644 --- a/win/configure.ac +++ b/win/configure.ac @@ -29,6 +29,8 @@ REGVER=$TCL_REG_MAJOR_VERSION$TCL_REG_MINOR_VERSION PKG_CFG_ARGS=$@ +TCL_ZIP_FILE=libtcl_${TCL_MAJOR_VERSION}_${TCL_MINOR_VERSION}_${TCL_PATCH_LEVEL}.zip + #------------------------------------------------------------------------ # Empty slate for bundled packages, to avoid stale configuration #------------------------------------------------------------------------ @@ -174,6 +176,62 @@ AC_CHECK_TYPE([uintptr_t], [ fi ]) + +#-------------------------------------------------------------------- +# Zipfs support +#-------------------------------------------------------------------- + +# +# Check for --enable-zipfs flag +# +SC_ENABLE_ZIPFS + +# +# Find a native zip implementation +# +SC_PROG_ZIP + +# +# Find a native compiler +# +AX_CC_FOR_BUILD + +if test "$ZIP_PROG" = ""; then + ZIP_PROG='./minizip${EXEEXT_FOR_BUILD}' +fi + +AC_ARG_ENABLE(zipfs, + AC_HELP_STRING([--enable-zipfs], + [build with Zipfs support (default: on)]), + [tcl_ok=$enableval], [tcl_ok=yes]) + if test "$tcl_ok" = "yes" -o "${TCL_THREADS}" = 1; then + ZIPFS_BUILD=1 + else + ZIPFS_BUILD=0 + fi + # Do checking message here to not mess up interleaved configure output + AC_MSG_CHECKING([for building with zipfs]) + if test "${ZIPFS_BUILD}" = 1; then + if test "${SHARED_BUILD}" = 0; then + ZIPFS_BUILD=2; + AC_DEFINE(ZIPFS_BUILD, 2, [Are we building with zipfs enabled?]) + INSTALL_LIBRARIES=install-libraries-zipfs-static + AC_MSG_RESULT([yes]) + else + AC_DEFINE(ZIPFS_BUILD, 1, [Are we building with zipfs enabled?])\ + INSTALL_LIBRARIES=install-libraries-zipfs-shared + AC_MSG_RESULT([yes]) + fi + else + AC_MSG_RESULT([no]) + INSTALL_LIBRARIES=install-libraries + INSTALL_MSGS=install-msgs + fi + AC_SUBST(ZIPFS_BUILD) + AC_SUBST(INSTALL_LIBRARIES) + AC_SUBST(INSTALL_MSGS) + + #-------------------------------------------------------------------- # Perform additinal compiler tests. #-------------------------------------------------------------------- @@ -370,6 +428,7 @@ AC_SUBST(TCL_PATCH_LEVEL) AC_SUBST(PKG_CFG_ARGS) AC_SUBST(TCL_EXE) +AC_SUBST(TCL_ZIP_FILE) AC_SUBST(TCL_LIB_FILE) AC_SUBST(TCL_LIB_FLAG) AC_SUBST(TCL_STATIC_LIB_FILE) diff --git a/win/tcl.m4 b/win/tcl.m4 index b4fbcce..07be5a4 100644 --- a/win/tcl.m4 +++ b/win/tcl.m4 @@ -251,6 +251,7 @@ AC_DEFUN([SC_PATH_TKCONFIG], [ # TCL_BIN_DIR # TCL_SRC_DIR # TCL_LIB_FILE +# TCL_ZIP_FILE # #------------------------------------------------------------------------ @@ -283,6 +284,7 @@ AC_DEFUN([SC_LOAD_TCLCONFIG], [ # eval is required to do the TCL_DBGX substitution # + eval "TCL_ZIP_FILE=\"${TCL_ZIP_FILE}\"" eval "TCL_LIB_FILE=\"${TCL_LIB_FILE}\"" eval "TCL_LIB_FLAG=\"${TCL_LIB_FLAG}\"" eval "TCL_LIB_SPEC=\"${TCL_LIB_SPEC}\"" @@ -295,6 +297,7 @@ AC_DEFUN([SC_LOAD_TCLCONFIG], [ AC_SUBST(TCL_BIN_DIR) AC_SUBST(TCL_SRC_DIR) + AC_SUBST(TCL_ZIP_FILE) AC_SUBST(TCL_LIB_FILE) AC_SUBST(TCL_LIB_FLAG) AC_SUBST(TCL_LIB_SPEC) @@ -380,6 +383,7 @@ AC_DEFUN([SC_ENABLE_SHARED], [ SHARED_BUILD=0 AC_DEFINE(STATIC_BUILD, 1, [Is this a static build?]) fi + AC_SUBST(SHARED_BUILD) ]) #------------------------------------------------------------------------ @@ -1297,3 +1301,107 @@ print("manifest needed") AC_SUBST(VC_MANIFEST_EMBED_DLL) AC_SUBST(VC_MANIFEST_EMBED_EXE) ]) + + +#------------------------------------------------------------------------ +# SC_PROG_ZIP +# Locate a zip encoder installed on the system path, or none. +# +# Arguments: +# none +# +# Results: +# Substitutes the following vars: +# ZIP_PROG +#------------------------------------------------------------------------ + +AC_DEFUN([SC_PROG_ZIP], [ + AC_MSG_CHECKING([for zip]) + AC_CACHE_VAL(ac_cv_path_zip, [ + search_path=`echo ${PATH} | sed -e 's/:/ /g'` + for dir in $search_path ; do + for j in `ls -r $dir/zip 2> /dev/null` \ + `ls -r $dir/zip 2> /dev/null` ; do + if test x"$ac_cv_path_zip" = x ; then + if test -f "$j" ; then + ac_cv_path_zip=$j + break + fi + fi + done + done + ]) + + if test -f "$ac_cv_path_zip" ; then + ZIP_PROG="$ac_cv_path_zip" + AC_MSG_RESULT([$ZIP_PROG]) + else + # It is not an error if an installed version of Zip can't be located. + ZIP_PROG="" + AC_MSG_RESULT([No zip found on PATH]) + fi + AC_SUBST(ZIP_PROG) +]) + +#------------------------------------------------------------------------ +# SC_CC_FOR_BUILD +# For cross compiles, locate a C compiler that can generate native binaries. +# +# Arguments: +# none +# +# Results: +# Substitutes the following vars: +# CC_FOR_BUILD +# EXEEXT_FOR_BUILD +#------------------------------------------------------------------------ + +dnl Get a default for CC_FOR_BUILD to put into Makefile. +AC_DEFUN([AX_CC_FOR_BUILD], +[# Put a plausible default for CC_FOR_BUILD in Makefile. +if test -z "$CC_FOR_BUILD"; then + if test "x$cross_compiling" = "xno"; then + CC_FOR_BUILD='$(CC)' + else + AC_MSG_CHECKING([for gcc]) + AC_CACHE_VAL(ac_cv_path_cc, [ + search_path=`echo ${PATH} | sed -e 's/:/ /g'` + for dir in $search_path ; do + for j in `ls -r $dir/gcc 2> /dev/null` \ + `ls -r $dir/gcc 2> /dev/null` ; do + if test x"$ac_cv_path_cc" = x ; then + if test -f "$j" ; then + ac_cv_path_cc=$j + break + fi + fi + done + done + ]) + fi +fi +AC_SUBST(CC_FOR_BUILD) +# Also set EXEEXT_FOR_BUILD. +if test "x$cross_compiling" = "xno"; then + EXEEXT_FOR_BUILD='$(EXEEXT)' + OBJEXT_FOR_BUILD='$(OBJEXT)' +else + OBJEXT_FOR_BUILD='.no' + AC_CACHE_CHECK([for build system executable suffix], bfd_cv_build_exeext, + [rm -f conftest* + echo 'int main () { return 0; }' > conftest.c + bfd_cv_build_exeext= + ${CC_FOR_BUILD} -o conftest conftest.c 1>&5 2>&5 + for file in conftest.*; do + case $file in + *.c | *.o | *.obj | *.ilk | *.pdb) ;; + *) bfd_cv_build_exeext=`echo $file | sed -e s/conftest//` ;; + esac + done + rm -f conftest* + test x"${bfd_cv_build_exeext}" = x && bfd_cv_build_exeext=no]) + EXEEXT_FOR_BUILD="" + test x"${bfd_cv_build_exeext}" != xno && EXEEXT_FOR_BUILD=${bfd_cv_build_exeext} +fi +AC_SUBST(EXEEXT_FOR_BUILD)])dnl +AC_SUBST(OBJEXT_FOR_BUILD)])dnl diff --git a/win/tclAppInit.c b/win/tclAppInit.c index ef9f98b..bbe727f 100644 --- a/win/tclAppInit.c +++ b/win/tclAppInit.c @@ -124,6 +124,8 @@ _tmain( #ifdef TCL_LOCAL_MAIN_HOOK TCL_LOCAL_MAIN_HOOK(&argc, &argv); +#else + TclZipfs_AppHook(&argc, &argv); #endif Tcl_Main(argc, argv, TCL_LOCAL_APPINIT); diff --git a/win/tclConfig.sh.in b/win/tclConfig.sh.in index 97670aa..25fc3de 100644 --- a/win/tclConfig.sh.in +++ b/win/tclConfig.sh.in @@ -41,6 +41,9 @@ TCL_SHARED_BUILD=@TCL_SHARED_BUILD@ # The name of the Tcl library (may be either a .a file or a shared library): TCL_LIB_FILE='@TCL_LIB_FILE@' +# The name of a zip containing the /library and /encodings (may be either a .zip file or a shared library): +TCL_ZIP_FILE='@TCL_ZIP_FILE@' + # Flag to indicate whether shared libraries need export files. TCL_NEEDS_EXP_FILE=@TCL_NEEDS_EXP_FILE@ -- cgit v0.12 From ded3368d3c2650fc1d5a7c888218f8ca7a4fd459 Mon Sep 17 00:00:00 2001 From: tne Date: Fri, 17 Nov 2017 04:45:07 +0000 Subject: Final tweaks to get Msys Zipfs build working --- unix/configure.ac | 5 ----- win/Makefile.in | 10 +++++++++- win/configure.ac | 5 ----- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/unix/configure.ac b/unix/configure.ac index 35429b5..ed85184 100644 --- a/unix/configure.ac +++ b/unix/configure.ac @@ -797,11 +797,6 @@ AC_MSG_RESULT([$tcl_ok]) #-------------------------------------------------------------------- # -# Check for --enable-zipfs flag -# -SC_ENABLE_ZIPFS - -# # Find a native zip implementation # SC_PROG_ZIP diff --git a/win/Makefile.in b/win/Makefile.in index 14868cf..214cf7b 100644 --- a/win/Makefile.in +++ b/win/Makefile.in @@ -229,6 +229,7 @@ MINIZIP_OBJS = \ inflate.$(HOST_OBJEXT) \ inftrees.$(HOST_OBJEXT) \ ioapi.$(HOST_OBJEXT) \ + iowin32.$(HOST_OBJEXT) \ trees.$(HOST_OBJEXT) \ uncompr.$(HOST_OBJEXT) \ zip.$(HOST_OBJEXT) \ @@ -556,7 +557,11 @@ tclMain2.${OBJEXT}: tclMain.c # TIP #430, ZipFS Support tclZipfs.${OBJEXT}: $(GENERIC_DIR)/tclZipfs.c - $(CC) -c $(CC_SWITCHES) $(ZLIB_INCLUDE) -I$(ZLIB_DIR)/contrib/minizip $(GENERIC_DIR)/tclZipfs.c + $(CC) -c $(CC_SWITCHES) -DBUILD_tcl \ + -DCFG_RUNTIME_DLLFILE="\"$(TCL_LIB_FILE)\"" \ + -DCFG_RUNTIME_ZIPFILE="\"$(TCL_ZIP_FILE)\"" \ + -DCFG_RUNTIME_PATH="\"$(DLL_INSTALL_DIR)\"" \ + $(ZLIB_INCLUDE) -I$(ZLIB_DIR)/contrib/minizip @DEPARG@ $(CC_OBJNAME) # TIP #59, embedding of configuration information into the binary library. @@ -625,6 +630,9 @@ deflate.$(HOST_OBJEXT): ioapi.$(HOST_OBJEXT): $(HOST_CC) -o $@ -I$(ZLIB_DIR) -I$(ZLIB_DIR)/contrib/minizip -c $(ZLIB_DIR)/contrib/minizip/ioapi.c +iowin32.$(HOST_OBJEXT): + $(HOST_CC) -o $@ -I$(ZLIB_DIR) -I$(ZLIB_DIR)/contrib/minizip -c $(ZLIB_DIR)/contrib/minizip/iowin32.c + infback.$(HOST_OBJEXT): $(HOST_CC) -o $@ -I$(ZLIB_DIR) -c $(ZLIB_DIR)/infback.c diff --git a/win/configure.ac b/win/configure.ac index 0bb0d7d..cf66fc2 100644 --- a/win/configure.ac +++ b/win/configure.ac @@ -182,11 +182,6 @@ AC_CHECK_TYPE([uintptr_t], [ #-------------------------------------------------------------------- # -# Check for --enable-zipfs flag -# -SC_ENABLE_ZIPFS - -# # Find a native zip implementation # SC_PROG_ZIP -- cgit v0.12 From 3c532f6336d06908079d7247329984747d31e152 Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Fri, 17 Nov 2017 04:47:16 +0000 Subject: Rebuilt the configure files without the call to the missing SC_ENABLE_ZIPFS macro --- unix/configure | 5 ----- win/configure | 5 ----- 2 files changed, 10 deletions(-) diff --git a/unix/configure b/unix/configure index 44bd2a6..dd6bf6b 100755 --- a/unix/configure +++ b/unix/configure @@ -10159,11 +10159,6 @@ $as_echo "$tcl_ok" >&6; } #-------------------------------------------------------------------- # -# Check for --enable-zipfs flag -# -SC_ENABLE_ZIPFS - -# # Find a native zip implementation # diff --git a/win/configure b/win/configure index ddba42a..f65b78a 100755 --- a/win/configure +++ b/win/configure @@ -4848,11 +4848,6 @@ fi #-------------------------------------------------------------------- # -# Check for --enable-zipfs flag -# -SC_ENABLE_ZIPFS - -# # Find a native zip implementation # -- cgit v0.12 From da76cd286ccf8763ea9970ee813e3ef3da20e252 Mon Sep 17 00:00:00 2001 From: aspect Date: Fri, 17 Nov 2017 08:39:31 +0000 Subject: Zipfs: Use //zipfs:/ as mount point. Use Tcl_FSNormalizePath() on the way in to most VFS operations. Add some tests. --- generic/tclInterp.c | 4 +- generic/tclZipfs.c | 19 ++++++++-- tests/zipfs.test | 104 ++++++++++++++++++++++++++++++++++++++-------------- 3 files changed, 93 insertions(+), 34 deletions(-) diff --git a/generic/tclInterp.c b/generic/tclInterp.c index 2b0582a..8d45d87 100644 --- a/generic/tclInterp.c +++ b/generic/tclInterp.c @@ -402,8 +402,8 @@ Tcl_Init( " set scripts {{set tcl_library}}\n" " } else {\n" " set scripts {}\n" -" lappend scripts {set temp zipfs:/lib/tcl/tcl_library}\n" -" lappend scripts {set temp zipfs:/app/tcl_library}\n" +" lappend scripts {set temp //zipfs:/lib/tcl/tcl_library}\n" +" lappend scripts {set temp //zipfs:/app/tcl_library}\n" " if {[info exists env(TCL_LIBRARY)] && ($env(TCL_LIBRARY) ne {})} {\n" " lappend scripts {set env(TCL_LIBRARY)}\n" " lappend scripts {\n" diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c index 9dfca7a..6b707fc 100644 --- a/generic/tclZipfs.c +++ b/generic/tclZipfs.c @@ -28,11 +28,11 @@ #include "zlib.h" #include "crypt.h" -#define ZIPFS_VOLUME "zipfs:/" -#define ZIPFS_APP_MOUNT "zipfs:/app" -#define ZIPFS_ZIP_MOUNT "zipfs:/lib/tcl" +#define ZIPFS_VOLUME "//zipfs:/" +#define ZIPFS_APP_MOUNT "//zipfs:/app" +#define ZIPFS_ZIP_MOUNT "//zipfs:/lib/tcl" -#define ZIPFS_VOLUME_LEN 7 +#define ZIPFS_VOLUME_LEN 9 /* * Various constants and offsets found in ZIP archive files @@ -2775,6 +2775,7 @@ ZipChannelOpen(Tcl_Interp *interp, char *filename, int mode, int permissions) if (z == NULL) { if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj("file not found", -1)); + Tcl_AppendResult(interp, " \"", filename, "\"", NULL); } goto error; } @@ -3156,6 +3157,8 @@ Zip_FSOpenFileChannelProc(Tcl_Interp *interp, Tcl_Obj *pathPtr, { int len; + if (!(pathPtr = Tcl_FSGetNormalizedPath(NULL, pathPtr))) return -1; + return ZipChannelOpen(interp, Tcl_GetStringFromObj(pathPtr, &len), mode, permissions); } @@ -3182,6 +3185,8 @@ Zip_FSStatProc(Tcl_Obj *pathPtr, Tcl_StatBuf *buf) { int len; + if (!(pathPtr = Tcl_FSGetNormalizedPath(NULL, pathPtr))) return -1; + return ZipEntryStat(Tcl_GetStringFromObj(pathPtr, &len), buf); } @@ -3207,6 +3212,8 @@ Zip_FSAccessProc(Tcl_Obj *pathPtr, int mode) { int len; + if (!(pathPtr = Tcl_FSGetNormalizedPath(NULL, pathPtr))) return -1; + return ZipEntryAccess(Tcl_GetStringFromObj(pathPtr, &len), mode); } @@ -3429,6 +3436,8 @@ Zip_FSPathInFilesystemProc(Tcl_Obj *pathPtr, ClientData *clientDataPtr) char *path; Tcl_DString ds; + if (!(pathPtr = Tcl_FSGetNormalizedPath(NULL, pathPtr))) return -1; + path = Tcl_GetStringFromObj(pathPtr, &len); if(strncmp(path,ZIPFS_VOLUME,ZIPFS_VOLUME_LEN)!=0) { return -1; @@ -3552,6 +3561,8 @@ Zip_FSFileAttrsGetProc(Tcl_Interp *interp, int index, Tcl_Obj *pathPtr, char *path; ZipEntry *z; + if (!(pathPtr = Tcl_FSGetNormalizedPath(NULL, pathPtr))) return -1; + path = Tcl_GetStringFromObj(pathPtr, &len); ReadLock(); z = ZipFSLookup(path); diff --git a/tests/zipfs.test b/tests/zipfs.test index 89d35ad..b14aa7d 100644 --- a/tests/zipfs.test +++ b/tests/zipfs.test @@ -18,69 +18,108 @@ if {"::tcltest" ni [namespace children]} { testConstraint zipfs [expr {[llength [info commands zlib]] && [regexp tcltest [info nameofexecutable]]}] # Removed in tip430 - zipfs is no longer a static package -#test zipfs-1.1 {zipfs basics} -constraints zipfs -body { +#test zipfs-0.0 {zipfs basics} -constraints zipfs -body { # load {} zipfs #} -result {} -test zipfs-1.2 {zipfs basics} -constraints zipfs -body { +test zipfs-0.1 {zipfs basics} -constraints zipfs -body { package require zipfs } -result {1.0} -test zipfs-1.3 {zipfs basics} -constraints zipfs -returnCodes error -body { +test zipfs-0.1 {zipfs basics} -constraints zipfs -body { + expr {"//zipfs:/" in [file volumes]} +} -result 1 + +test zipfs-0.2 {zipfs basics} -constraints zipfs -body { + string match //zipfs:/* $tcl_library +} -result 1 + +test zipfs-0.3 {zipfs basics: glob} -constraints zipfs -body { + set pwd [pwd] + cd $tcl_library + lsort [glob -dir . http*] +} -cleanup { + cd $pwd +} -result {./http ./http1.0} + +test zipfs-0.4 {zipfs basics: glob} -constraints zipfs -body { + set pwd [pwd] + cd $tcl_library + lsort [glob -dir [pwd] http*] +} -cleanup { + cd $pwd +} -result [list $tcl_library/http $tcl_library/http1.0] + +test zipfs-0.5 {zipfs basics: glob} -constraints zipfs -body { + lsort [glob -dir $tcl_library http*] +} -result [list $tcl_library/http $tcl_library/http1.0] + +test zipfs-0.6 {zipfs basics: glob} -constraints zipfs -body { + lsort [glob -tails -dir $tcl_library http*] +} -result {http http1.0} + +test zipfs-0.7 {zipfs basics: glob} -constraints zipfs -body { + lsort [glob -nocomplain -tails -types d -dir $tcl_library http*] +} -result {http http1.0} + +test zipfs-0.8 {zipfs basics: glob} -constraints zipfs -body { + lsort [glob -nocomplain -tails -types f -dir $tcl_library http*] +} -result {} + + +test zipfs-1.3 {zipfs errors} -constraints zipfs -returnCodes error -body { zipfs mount a b c d e f } -result {wrong # args: should be "zipfs mount ?zipfile? ?mountpoint? ?password?"} -test zipfs-1.4 {zipfs basics} -constraints zipfs -returnCodes error -body { +test zipfs-1.4 {zipfs errors} -constraints zipfs -returnCodes error -body { zipfs unmount a b c d e f } -result {wrong # args: should be "zipfs unmount zipfile"} -test zipfs-1.5 {zipfs basics} -constraints zipfs -returnCodes error -body { +test zipfs-1.5 {zipfs errors} -constraints zipfs -returnCodes error -body { zipfs mkkey a b c d e f } -result {wrong # args: should be "zipfs mkkey password"} -test zipfs-1.6 {zipfs basics} -constraints zipfs -returnCodes error -body { +test zipfs-1.6 {zipfs errors} -constraints zipfs -returnCodes error -body { zipfs mkimg a b c d e f } -result {wrong # args: should be "zipfs mkimg outfile indir ?strip? ?password? ?infile?"} -test zipfs-1.7 {zipfs basics} -constraints zipfs -returnCodes error -body { +test zipfs-1.7 {zipfs errors} -constraints zipfs -returnCodes error -body { zipfs mkzip a b c d e f } -result {wrong # args: should be "zipfs mkzip outfile indir ?strip? ?password?"} -test zipfs-1.8 {zipfs basics} -constraints zipfs -returnCodes error -body { +test zipfs-1.8 {zipfs errors} -constraints zipfs -returnCodes error -body { zipfs exists a b c d e f } -result {wrong # args: should be "zipfs exists filename"} -test zipfs-1.9 {zipfs basics} -constraints zipfs -returnCodes error -body { +test zipfs-1.9 {zipfs errors} -constraints zipfs -returnCodes error -body { zipfs info a b c d e f } -result {wrong # args: should be "zipfs info filename"} -test zipfs-1.10 {zipfs basics} -constraints zipfs -returnCodes error -body { +test zipfs-1.10 {zipfs errors} -constraints zipfs -returnCodes error -body { zipfs list a b c d e f } -result {wrong # args: should be "zipfs list ?(-glob|-regexp)? ?pattern?"} -set ntcl_library [file normalize $tcl_library] - test zipfs-2.1 {zipfs mkzip empty archive} -constraints zipfs -returnCodes error -body { - zipfs mkzip abc.zip $ntcl_library/xxxx + zipfs mkzip /tmp/abc.zip $tcl_library/xxxx ;# FIXME: test independence } -result {empty archive} test zipfs-2.2 {zipfs mkzip} -constraints zipfs -body { set pwd [pwd] - cd $ntcl_library/encoding - zipfs mkzip abc.zip . - zipfs mount abc.zip zipfs:/abc - zipfs list -glob zipfs:/abc/cp850.* + cd $tcl_library/encoding + zipfs mkzip /tmp/abc.zip . + zipfs mount /tmp/abc.zip //zipfs:/abc ;# FIXME: test independence + zipfs list -glob //zipfs:/abc/cp850.* } -cleanup { cd $pwd -} -result {zipfs:/abc/cp850.enc} +} -result {//zipfs:/abc/cp850.enc} -test zipfs-2.3 {zipfs unmount} -constraints zipfs -body { - zipfs info zipfs:/abc/cp850.enc -} -result [list $ntcl_library/encoding/abc.zip 1090 527 39434] +test zipfs-2.3 {zipfs info} -constraints zipfs -body { + zipfs info //zipfs:/abc/cp850.enc +} -result [list /tmp/abc.zip 1090 527 39318] ;# FIXME: result depends on content of encodings dir -test zipfs-2.4 {zipfs unmount} -constraints zipfs -body { - set f [open zipfs:/abc/cp850.enc] - read $f +test zipfs-2.4 {zipfs data} -constraints zipfs -body { + set zipfd [open //zipfs:/abc/cp850.enc] ;# FIXME: leave open - see later test + read $zipfd } -result {# Encoding file: cp850, single-byte S 003F 0 1 @@ -101,14 +140,23 @@ S 00F000D000CA00CB00C8013100CD00CE00CF2518250C2588258400A600CC2580 00D300DF00D400D200F500D500B500FE00DE00DA00DB00D900FD00DD00AF00B4 00AD00B1201700BE00B600A700F700B800B000A800B700B900B300B225A000A0 -} +} ;# FIXME: result depends on content of encodings dir test zipfs-2.5 {zipfs exists} -constraints zipfs -body { - zipfs unmount abc.zip zipfs exists /abc/cp850.enc -} -cleanup { - file delete abc.zip } -result 1 + +test zipfs-2.6 {zipfs unmount while busy} -constraints zipfs -body { + zipfs unmount /tmp/abc.zip +} -returnCodes error -result {filesystem is busy} + +test zipfs-2.7 {zipfs unmount} -constraints zipfs -body { + close $zipfd + zipfs unmount /tmp/abc.zip + zipfs exists /abc/cp850.enc +} -cleanup { + file delete /tmp/abc.zip ;# FIXME: test independence +} -result 0 ::tcltest::cleanupTests return -- cgit v0.12 From 87d37d3101b7ac510f9eb38766e63de5308a4d4b Mon Sep 17 00:00:00 2001 From: aspect Date: Fri, 17 Nov 2017 10:17:47 +0000 Subject: Zipfs: Nix AbsolutePath() and most uses of CanonicalPath(). Tcl_FSNormalizePath is to be trusted. --- generic/tclZipfs.c | 116 +++++++++++++++-------------------------------------- 1 file changed, 32 insertions(+), 84 deletions(-) diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c index 6b707fc..a03f4cf 100644 --- a/generic/tclZipfs.c +++ b/generic/tclZipfs.c @@ -645,50 +645,6 @@ CanonicalPath(const char *root, const char *tail, Tcl_DString *dsPtr,int ZIPFSPA /* *------------------------------------------------------------------------- * - * AbsolutePath -- - * - * This function computes the absolute path from a given - * (relative) path name into the specified Tcl_DString. - * - * Results: - * Returns the pointer to the absolute path contained in the - * specified Tcl_DString. - * - * Side effects: - * Modifies the specified Tcl_DString. - * - *------------------------------------------------------------------------- - */ - -static char * -AbsolutePath(const char *path, - Tcl_DString *dsPtr, - int ZIPFSPATH) -{ - char *result; - if (*path == '~') { - Tcl_DStringAppend(dsPtr, path, -1); - return Tcl_DStringValue(dsPtr); - } - if (*path != '/') { - Tcl_DString pwd; - - /* relative path */ - Tcl_DStringInit(&pwd); - Tcl_GetCwd(NULL, &pwd); - result = Tcl_DStringValue(&pwd); - result = CanonicalPath(result, path, dsPtr,ZIPFSPATH); - Tcl_DStringFree(&pwd); - } else { - /* absolute path */ - result = CanonicalPath("", path, dsPtr,ZIPFSPATH); - } - return result; -} - -/* - *------------------------------------------------------------------------- - * * ZipFSLookup -- * * This function returns the ZIP entry struct corresponding to @@ -708,14 +664,11 @@ AbsolutePath(const char *path, static ZipEntry * ZipFSLookup(char *filename) { - char *realname; - Tcl_HashEntry *hPtr; ZipEntry *z; Tcl_DString ds; Tcl_DStringInit(&ds); - realname = AbsolutePath(filename, &ds, 1); - hPtr = Tcl_FindHashEntry(&ZipFS.fileHash, realname); + hPtr = Tcl_FindHashEntry(&ZipFS.fileHash, filename); z = hPtr ? (ZipEntry *) Tcl_GetHashValue(hPtr) : NULL; Tcl_DStringFree(&ds); return z; @@ -743,18 +696,16 @@ ZipFSLookup(char *filename) static int ZipFSLookupMount(char *filename) { - char *realname; Tcl_HashEntry *hPtr; Tcl_HashSearch search; ZipFile *zf; Tcl_DString ds; int match = 0; Tcl_DStringInit(&ds); - realname = AbsolutePath(filename, &ds, 1); hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); while (hPtr != NULL) { if ((zf = (ZipFile *) Tcl_GetHashValue(hPtr)) != NULL) { - if (strcmp(zf->mntpt, realname) == 0) { + if (strcmp(zf->mntpt, filename) == 0) { match = 1; break; } @@ -1052,12 +1003,11 @@ int TclZipfs_Mount(Tcl_Interp *interp, const char *zipname, const char *mntpt, const char *passwd) { - char *realname, *p; int i, pwlen, isNew; ZipFile *zf, zf0; ZipEntry *z; Tcl_HashEntry *hPtr; - Tcl_DString ds, dsm, fpBuf; + Tcl_DString ds, fpBuf; unsigned char *q; ReadLock(); @@ -1096,9 +1046,7 @@ TclZipfs_Mount(Tcl_Interp *interp, const char *zipname, const char *mntpt, Unlock(); return TCL_OK; } - Tcl_DStringInit(&ds); - p = AbsolutePath(zipname, &ds, 0); - hPtr = Tcl_FindHashEntry(&ZipFS.zipHash, p); + hPtr = Tcl_FindHashEntry(&ZipFS.zipHash, zipname); if (hPtr != NULL) { if ((zf = Tcl_GetHashValue(hPtr)) != NULL) { Tcl_SetObjResult(interp, @@ -1106,7 +1054,6 @@ TclZipfs_Mount(Tcl_Interp *interp, const char *zipname, const char *mntpt, } } Unlock(); - Tcl_DStringFree(&ds); return TCL_OK; } Unlock(); @@ -1124,18 +1071,13 @@ TclZipfs_Mount(Tcl_Interp *interp, const char *zipname, const char *mntpt, if (ZipFSOpenArchive(interp, zipname, 1, &zf0) != TCL_OK) { return TCL_ERROR; } - Tcl_DStringInit(&ds); - realname = AbsolutePath(zipname, &ds, 0); /* * Mount point can come from Tcl_GetNameOfExecutable() * which sometimes is a relative or otherwise denormalized path. * But an absolute name is needed as mount point here. */ - Tcl_DStringInit(&dsm); - mntpt = CanonicalPath("", mntpt, &dsm, 1); WriteLock(); - hPtr = Tcl_CreateHashEntry(&ZipFS.zipHash, realname, &isNew); - Tcl_DStringSetLength(&ds, 0); + hPtr = Tcl_CreateHashEntry(&ZipFS.zipHash, zipname, &isNew); if (!isNew) { zf = (ZipFile *) Tcl_GetHashValue(hPtr); if (interp != NULL) { @@ -1143,8 +1085,6 @@ TclZipfs_Mount(Tcl_Interp *interp, const char *zipname, const char *mntpt, zf->mntpt : "/", "\"", (char *) NULL); } Unlock(); - Tcl_DStringFree(&ds); - Tcl_DStringFree(&dsm); ZipFSCloseArchive(interp, &zf0); return TCL_ERROR; } @@ -1157,8 +1097,6 @@ TclZipfs_Mount(Tcl_Interp *interp, const char *zipname, const char *mntpt, Tcl_AppendResult(interp, "out of memory", (char *) NULL); } Unlock(); - Tcl_DStringFree(&ds); - Tcl_DStringFree(&dsm); ZipFSCloseArchive(interp, &zf0); return TCL_ERROR; } @@ -1209,6 +1147,7 @@ TclZipfs_Mount(Tcl_Interp *interp, const char *zipname, const char *mntpt, } q = zf->data + zf->centoffs; Tcl_DStringInit(&fpBuf); + Tcl_DStringInit(&ds); for (i = 0; i < zf->nfiles; i++) { int pathlen, comlen, extra, isdir = 0, dosTime, dosDate, nbcompr, offs; unsigned char *lq, *gq = NULL; @@ -1374,7 +1313,6 @@ nextent: Unlock(); Tcl_DStringFree(&fpBuf); Tcl_DStringFree(&ds); - Tcl_DStringFree(&dsm); Tcl_FSMountsChanged(NULL); return TCL_OK; } @@ -1398,7 +1336,6 @@ nextent: int TclZipfs_Unmount(Tcl_Interp *interp, const char *zipname) { - char *realname; ZipFile *zf; ZipEntry *z, *znext; Tcl_HashEntry *hPtr; @@ -1406,12 +1343,11 @@ TclZipfs_Unmount(Tcl_Interp *interp, const char *zipname) int ret = TCL_OK, unmounted = 0; Tcl_DStringInit(&ds); - realname = AbsolutePath(zipname, &ds, 0); WriteLock(); if (!ZipFS.initialized) { goto done; } - hPtr = Tcl_FindHashEntry(&ZipFS.zipHash, realname); + hPtr = Tcl_FindHashEntry(&ZipFS.zipHash, zipname); if (hPtr == NULL) { /* don't report error */ goto done; @@ -2304,15 +2240,24 @@ ZipFSExistsObjCmd(ClientData clientData, Tcl_Interp *interp, { char *filename; int exists; + Tcl_DString ds; if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "filename"); return TCL_ERROR; } + + /* prepend ZIPFS_VOLUME to filename, eliding the final / */ filename = Tcl_GetStringFromObj(objv[1], 0); + Tcl_DStringInit(&ds); + Tcl_DStringAppend(&ds, ZIPFS_VOLUME, ZIPFS_VOLUME_LEN-1); + Tcl_DStringAppend(&ds, filename, -1); + filename = Tcl_DStringValue(&ds); + ReadLock(); exists = ZipFSLookup(filename) != NULL; Unlock(); + Tcl_SetObjResult(interp,Tcl_NewBooleanObj(exists)); return TCL_OK; } @@ -3157,7 +3102,7 @@ Zip_FSOpenFileChannelProc(Tcl_Interp *interp, Tcl_Obj *pathPtr, { int len; - if (!(pathPtr = Tcl_FSGetNormalizedPath(NULL, pathPtr))) return -1; + if (!(pathPtr = Tcl_FSGetNormalizedPath(NULL, pathPtr))) return NULL; return ZipChannelOpen(interp, Tcl_GetStringFromObj(pathPtr, &len), mode, permissions); @@ -3267,19 +3212,26 @@ Zip_FSMatchInDirectoryProc(Tcl_Interp* interp, Tcl_Obj *result, { Tcl_HashEntry *hPtr; Tcl_HashSearch search; + Tcl_Obj *normPathPtr; int scnt, len, l, dirOnly = -1, prefixLen, strip = 0; char *pat, *prefix, *path; - Tcl_DString ds, dsPref; + Tcl_DString dsPref; + + if (!(normPathPtr = Tcl_FSGetNormalizedPath(NULL, pathPtr))) return -1; + if (types != NULL) { dirOnly = (types->type & TCL_GLOB_TYPE_DIR) == TCL_GLOB_TYPE_DIR; } - Tcl_DStringInit(&ds); - Tcl_DStringInit(&dsPref); + + /* the prefix that gets prepended to results */ prefix = Tcl_GetStringFromObj(pathPtr, &prefixLen); + + /* the (normalized) path we're searching */ + path = Tcl_GetStringFromObj(normPathPtr, &len); + + Tcl_DStringInit(&dsPref); Tcl_DStringAppend(&dsPref, prefix, prefixLen); - prefix = Tcl_DStringValue(&dsPref); - path = AbsolutePath(prefix, &ds, 1); - len = Tcl_DStringLength(&ds); + if (strcmp(prefix, path) == 0) { prefix = NULL; } else { @@ -3405,7 +3357,6 @@ Zip_FSMatchInDirectoryProc(Tcl_Interp* interp, Tcl_Obj *result, end: Unlock(); Tcl_DStringFree(&dsPref); - Tcl_DStringFree(&ds); return TCL_OK; } @@ -3434,7 +3385,6 @@ Zip_FSPathInFilesystemProc(Tcl_Obj *pathPtr, ClientData *clientDataPtr) ZipFile *zf; int ret = -1, len; char *path; - Tcl_DString ds; if (!(pathPtr = Tcl_FSGetNormalizedPath(NULL, pathPtr))) return -1; @@ -3443,9 +3393,8 @@ Zip_FSPathInFilesystemProc(Tcl_Obj *pathPtr, ClientData *clientDataPtr) return -1; } - Tcl_DStringInit(&ds); - path = CanonicalPath("",path, &ds, 1); - len = Tcl_DStringLength(&ds); + len = strlen(path); + ReadLock(); hPtr = Tcl_FindHashEntry(&ZipFS.fileHash, path); if (hPtr != NULL) { @@ -3476,7 +3425,6 @@ Zip_FSPathInFilesystemProc(Tcl_Obj *pathPtr, ClientData *clientDataPtr) } endloop: Unlock(); - Tcl_DStringFree(&ds); return ret; } -- cgit v0.12 From 451510384623e7c0f4ca04f3ec6d5845fe69de33 Mon Sep 17 00:00:00 2001 From: aspect Date: Fri, 17 Nov 2017 10:21:41 +0000 Subject: whitespace consistency --- generic/tclZipfs.c | 1152 ++++++++++++++++++++++++++-------------------------- 1 file changed, 576 insertions(+), 576 deletions(-) diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c index a03f4cf..5aa001f 100644 --- a/generic/tclZipfs.c +++ b/generic/tclZipfs.c @@ -503,141 +503,141 @@ CountSlashes(const char *string) static char * CanonicalPath(const char *root, const char *tail, Tcl_DString *dsPtr,int ZIPFSPATH) { - char *path; - char *result; - int i, j, c, isunc = 0, isvfs=0, n=0; + char *path; + char *result; + int i, j, c, isunc = 0, isvfs=0, n=0; #if HAS_DRIVES - int zipfspath=1; - if ((tail[0] != '\0') && (strchr(drvletters, tail[0]) != NULL) && - (tail[1] == ':')) { - tail += 2; - zipfspath=0; - } - /* UNC style path */ - if (tail[0] == '\\') { - root = ""; - ++tail; - zipfspath=0; - } - if (tail[0] == '\\') { - root = "/"; - ++tail; - zipfspath=0; - } - if(zipfspath) { -#endif + int zipfspath=1; + if ((tail[0] != '\0') && (strchr(drvletters, tail[0]) != NULL) && + (tail[1] == ':')) { + tail += 2; + zipfspath=0; + } /* UNC style path */ - if(root && strncmp(root,ZIPFS_VOLUME,ZIPFS_VOLUME_LEN)==0) { - isvfs=1; - } else if (tail && strncmp(tail,ZIPFS_VOLUME,ZIPFS_VOLUME_LEN) == 0) { - isvfs=2; - } - if(isvfs!=1) { - if ((root[0] == '/') && (root[1] == '/')) { - isunc = 1; - } + if (tail[0] == '\\') { + root = ""; + ++tail; + zipfspath=0; } -#if HAS_DRIVES - } -#endif - if(isvfs!=2) { - if (tail[0] == '/') { - if(isvfs!=1) { - root = ""; - } - ++tail; - isunc = 0; + if (tail[0] == '\\') { + root = "/"; + ++tail; + zipfspath=0; } - if (tail[0] == '/') { - if(isvfs!=1) { - root = "/"; - } - ++tail; - isunc = 1; - } - } - i = strlen(root); - j = strlen(tail); - if(isvfs==1) { - if(i>ZIPFS_VOLUME_LEN) { - Tcl_DStringSetLength(dsPtr, i + j + 1); - path = Tcl_DStringValue(dsPtr); - memcpy(path, root, i); - path[i++] = '/'; - memcpy(path + i, tail, j); - } else { - Tcl_DStringSetLength(dsPtr, i + j); - path = Tcl_DStringValue(dsPtr); - memcpy(path, root, i); - memcpy(path + i, tail, j); + if(zipfspath) { +#endif + /* UNC style path */ + if(root && strncmp(root,ZIPFS_VOLUME,ZIPFS_VOLUME_LEN)==0) { + isvfs=1; + } else if (tail && strncmp(tail,ZIPFS_VOLUME,ZIPFS_VOLUME_LEN) == 0) { + isvfs=2; + } + if(isvfs!=1) { + if ((root[0] == '/') && (root[1] == '/')) { + isunc = 1; + } + } +#if HAS_DRIVES } - } else if(isvfs==2) { - Tcl_DStringSetLength(dsPtr, j); - path = Tcl_DStringValue(dsPtr); - memcpy(path, tail, j); - } else { - if (ZIPFSPATH) { - Tcl_DStringSetLength(dsPtr, i + j + ZIPFS_VOLUME_LEN); - path = Tcl_DStringValue(dsPtr); - memcpy(path, ZIPFS_VOLUME, ZIPFS_VOLUME_LEN); - memcpy(path + ZIPFS_VOLUME_LEN + i , tail, j); +#endif + if(isvfs!=2) { + if (tail[0] == '/') { + if(isvfs!=1) { + root = ""; + } + ++tail; + isunc = 0; + } + if (tail[0] == '/') { + if(isvfs!=1) { + root = "/"; + } + ++tail; + isunc = 1; + } + } + i = strlen(root); + j = strlen(tail); + if(isvfs==1) { + if(i>ZIPFS_VOLUME_LEN) { + Tcl_DStringSetLength(dsPtr, i + j + 1); + path = Tcl_DStringValue(dsPtr); + memcpy(path, root, i); + path[i++] = '/'; + memcpy(path + i, tail, j); + } else { + Tcl_DStringSetLength(dsPtr, i + j); + path = Tcl_DStringValue(dsPtr); + memcpy(path, root, i); + memcpy(path + i, tail, j); + } + } else if(isvfs==2) { + Tcl_DStringSetLength(dsPtr, j); + path = Tcl_DStringValue(dsPtr); + memcpy(path, tail, j); } else { - Tcl_DStringSetLength(dsPtr, i + j + 1); - path = Tcl_DStringValue(dsPtr); - memcpy(path, root, i); - path[i++] = '/'; - memcpy(path + i, tail, j); + if (ZIPFSPATH) { + Tcl_DStringSetLength(dsPtr, i + j + ZIPFS_VOLUME_LEN); + path = Tcl_DStringValue(dsPtr); + memcpy(path, ZIPFS_VOLUME, ZIPFS_VOLUME_LEN); + memcpy(path + ZIPFS_VOLUME_LEN + i , tail, j); + } else { + Tcl_DStringSetLength(dsPtr, i + j + 1); + path = Tcl_DStringValue(dsPtr); + memcpy(path, root, i); + path[i++] = '/'; + memcpy(path + i, tail, j); + } } - } #if HAS_DRIVES - for (i = 0; path[i] != '\0'; i++) { - if (path[i] == '\\') { - path[i] = '/'; + for (i = 0; path[i] != '\0'; i++) { + if (path[i] == '\\') { + path[i] = '/'; + } } - } #endif - if(ZIPFSPATH) { - n=ZIPFS_VOLUME_LEN; - } else { - n=0; - } - for (i = j = n; (c = path[i]) != '\0'; i++) { - if (c == '/') { + if(ZIPFSPATH) { + n=ZIPFS_VOLUME_LEN; + } else { + n=0; + } + for (i = j = n; (c = path[i]) != '\0'; i++) { + if (c == '/') { int c2 = path[i + 1]; if (c2 == '/') { - continue; + continue; } if (c2 == '.') { - int c3 = path[i + 2]; - if ((c3 == '/') || (c3 == '\0')) { - i++; - continue; - } - if ((c3 == '.') && - ((path[i + 3] == '/') || (path [i + 3] == '\0'))) { - i += 2; - while ((j > 0) && (path[j - 1] != '/')) { - j--; - } - if (j > isunc) { - --j; - while ((j > 1 + isunc) && (path[j - 2] == '/')) { - j--; - } - } - continue; - } + int c3 = path[i + 2]; + if ((c3 == '/') || (c3 == '\0')) { + i++; + continue; + } + if ((c3 == '.') && + ((path[i + 3] == '/') || (path [i + 3] == '\0'))) { + i += 2; + while ((j > 0) && (path[j - 1] != '/')) { + j--; + } + if (j > isunc) { + --j; + while ((j > 1 + isunc) && (path[j - 2] == '/')) { + j--; + } + } + continue; + } } + } + path[j++] = c; + } + if (j == 0) { + path[j++] = '/'; } - path[j++] = c; - } - if (j == 0) { - path[j++] = '/'; - } - path[j] = 0; - Tcl_DStringSetLength(dsPtr, j); - result=Tcl_DStringValue(dsPtr); - return result; + path[j] = 0; + Tcl_DStringSetLength(dsPtr, j); + result=Tcl_DStringValue(dsPtr); + return result; } @@ -664,14 +664,14 @@ CanonicalPath(const char *root, const char *tail, Tcl_DString *dsPtr,int ZIPFSPA static ZipEntry * ZipFSLookup(char *filename) { - Tcl_HashEntry *hPtr; - ZipEntry *z; - Tcl_DString ds; - Tcl_DStringInit(&ds); - hPtr = Tcl_FindHashEntry(&ZipFS.fileHash, filename); - z = hPtr ? (ZipEntry *) Tcl_GetHashValue(hPtr) : NULL; - Tcl_DStringFree(&ds); - return z; + Tcl_HashEntry *hPtr; + ZipEntry *z; + Tcl_DString ds; + Tcl_DStringInit(&ds); + hPtr = Tcl_FindHashEntry(&ZipFS.fileHash, filename); + z = hPtr ? (ZipEntry *) Tcl_GetHashValue(hPtr) : NULL; + Tcl_DStringFree(&ds); + return z; } #ifdef NEVER_USED @@ -696,24 +696,24 @@ ZipFSLookup(char *filename) static int ZipFSLookupMount(char *filename) { - Tcl_HashEntry *hPtr; - Tcl_HashSearch search; - ZipFile *zf; - Tcl_DString ds; - int match = 0; - Tcl_DStringInit(&ds); - hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); - while (hPtr != NULL) { - if ((zf = (ZipFile *) Tcl_GetHashValue(hPtr)) != NULL) { - if (strcmp(zf->mntpt, filename) == 0) { - match = 1; - break; - } + Tcl_HashEntry *hPtr; + Tcl_HashSearch search; + ZipFile *zf; + Tcl_DString ds; + int match = 0; + Tcl_DStringInit(&ds); + hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); + while (hPtr != NULL) { + if ((zf = (ZipFile *) Tcl_GetHashValue(hPtr)) != NULL) { + if (strcmp(zf->mntpt, filename) == 0) { + match = 1; + break; + } + } + hPtr = Tcl_NextHashEntry(&search); } - hPtr = Tcl_NextHashEntry(&search); - } - Tcl_DStringFree(&ds); - return match; + Tcl_DStringFree(&ds); + return match; } #endif @@ -1003,190 +1003,190 @@ int TclZipfs_Mount(Tcl_Interp *interp, const char *zipname, const char *mntpt, const char *passwd) { - int i, pwlen, isNew; - ZipFile *zf, zf0; - ZipEntry *z; - Tcl_HashEntry *hPtr; - Tcl_DString ds, fpBuf; - unsigned char *q; - - ReadLock(); - if (!ZipFS.initialized) { - if (interp != NULL) { - Tcl_SetObjResult(interp, - Tcl_NewStringObj("not initialized", -1)); - } - Unlock(); - return TCL_ERROR; - } - if (zipname == NULL) { - Tcl_HashSearch search; - int ret = TCL_OK; + int i, pwlen, isNew; + ZipFile *zf, zf0; + ZipEntry *z; + Tcl_HashEntry *hPtr; + Tcl_DString ds, fpBuf; + unsigned char *q; - i = 0; - hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); - while (hPtr != NULL) { - if ((zf = (ZipFile *) Tcl_GetHashValue(hPtr)) != NULL) { - if (interp != NULL) { - Tcl_AppendElement(interp, zf->mntpt); - Tcl_AppendElement(interp, zf->name); - } - ++i; - } - hPtr = Tcl_NextHashEntry(&search); + ReadLock(); + if (!ZipFS.initialized) { + if (interp != NULL) { + Tcl_SetObjResult(interp, + Tcl_NewStringObj("not initialized", -1)); + } + Unlock(); + return TCL_ERROR; } - if (interp == NULL) { - ret = (i > 0) ? TCL_OK : TCL_BREAK; + if (zipname == NULL) { + Tcl_HashSearch search; + int ret = TCL_OK; + + i = 0; + hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); + while (hPtr != NULL) { + if ((zf = (ZipFile *) Tcl_GetHashValue(hPtr)) != NULL) { + if (interp != NULL) { + Tcl_AppendElement(interp, zf->mntpt); + Tcl_AppendElement(interp, zf->name); + } + ++i; + } + hPtr = Tcl_NextHashEntry(&search); + } + if (interp == NULL) { + ret = (i > 0) ? TCL_OK : TCL_BREAK; + } + Unlock(); + return ret; } - Unlock(); - return ret; - } - if (mntpt == NULL) { - if (interp == NULL) { + if (mntpt == NULL) { + if (interp == NULL) { Unlock(); return TCL_OK; - } - hPtr = Tcl_FindHashEntry(&ZipFS.zipHash, zipname); - if (hPtr != NULL) { - if ((zf = Tcl_GetHashValue(hPtr)) != NULL) { - Tcl_SetObjResult(interp, - Tcl_NewStringObj(zf->mntpt, zf->mntptlen)); - } + } + hPtr = Tcl_FindHashEntry(&ZipFS.zipHash, zipname); + if (hPtr != NULL) { + if ((zf = Tcl_GetHashValue(hPtr)) != NULL) { + Tcl_SetObjResult(interp, + Tcl_NewStringObj(zf->mntpt, zf->mntptlen)); + } + } + Unlock(); + return TCL_OK; } Unlock(); - return TCL_OK; - } - Unlock(); - pwlen = 0; - if (passwd != NULL) { - pwlen = strlen(passwd); - if ((pwlen > 255) || (strchr(passwd, 0xff) != NULL)) { + pwlen = 0; + if (passwd != NULL) { + pwlen = strlen(passwd); + if ((pwlen > 255) || (strchr(passwd, 0xff) != NULL)) { if (interp) { - Tcl_SetObjResult(interp, - Tcl_NewStringObj("illegal password", -1)); + Tcl_SetObjResult(interp, + Tcl_NewStringObj("illegal password", -1)); } return TCL_ERROR; + } } - } - if (ZipFSOpenArchive(interp, zipname, 1, &zf0) != TCL_OK) { - return TCL_ERROR; - } - /* - * Mount point can come from Tcl_GetNameOfExecutable() - * which sometimes is a relative or otherwise denormalized path. - * But an absolute name is needed as mount point here. - */ - WriteLock(); - hPtr = Tcl_CreateHashEntry(&ZipFS.zipHash, zipname, &isNew); - if (!isNew) { - zf = (ZipFile *) Tcl_GetHashValue(hPtr); - if (interp != NULL) { - Tcl_AppendResult(interp, "already mounted on \"", zf->mntptlen ? - zf->mntpt : "/", "\"", (char *) NULL); - } - Unlock(); - ZipFSCloseArchive(interp, &zf0); - return TCL_ERROR; - } - if (strcmp(mntpt, "/") == 0) { - mntpt = ""; - } - zf = (ZipFile *) Tcl_AttemptAlloc(sizeof (*zf) + strlen(mntpt) + 1); - if (zf == NULL) { - if (interp != NULL) { - Tcl_AppendResult(interp, "out of memory", (char *) NULL); + if (ZipFSOpenArchive(interp, zipname, 1, &zf0) != TCL_OK) { + return TCL_ERROR; } - Unlock(); - ZipFSCloseArchive(interp, &zf0); - return TCL_ERROR; - } - *zf = zf0; - zf->name = Tcl_GetHashKey(&ZipFS.zipHash, hPtr); - strcpy(zf->mntpt, mntpt); - zf->mntptlen = strlen(zf->mntpt); - zf->entries = NULL; - zf->topents = NULL; - zf->nopen = 0; - Tcl_SetHashValue(hPtr, (ClientData) zf); - if ((zf->pwbuf[0] == 0) && pwlen) { - int k = 0; - i = pwlen; - zf->pwbuf[k++] = i; - while (i > 0) { - zf->pwbuf[k] = (passwd[i - 1] & 0x0f) | - pwrot[(passwd[i - 1] >> 4) & 0x0f]; - k++; - i--; - } - zf->pwbuf[k] = '\0'; - } - if (mntpt[0] != '\0') { - z = (ZipEntry *) Tcl_Alloc(sizeof (*z)); - z->name = NULL; - z->tnext = NULL; - z->depth = CountSlashes(mntpt); - z->zipfile = zf; - z->isdir = 1; - z->isenc = 0; - z->offset = zf->baseoffs; - z->crc32 = 0; - z->timestamp = 0; - z->nbyte = z->nbytecompr = 0; - z->cmeth = ZIP_COMPMETH_STORED; - z->data = NULL; - hPtr = Tcl_CreateHashEntry(&ZipFS.fileHash, mntpt, &isNew); + /* + * Mount point can come from Tcl_GetNameOfExecutable() + * which sometimes is a relative or otherwise denormalized path. + * But an absolute name is needed as mount point here. + */ + WriteLock(); + hPtr = Tcl_CreateHashEntry(&ZipFS.zipHash, zipname, &isNew); if (!isNew) { + zf = (ZipFile *) Tcl_GetHashValue(hPtr); + if (interp != NULL) { + Tcl_AppendResult(interp, "already mounted on \"", zf->mntptlen ? + zf->mntpt : "/", "\"", (char *) NULL); + } + Unlock(); + ZipFSCloseArchive(interp, &zf0); + return TCL_ERROR; + } + if (strcmp(mntpt, "/") == 0) { + mntpt = ""; + } + zf = (ZipFile *) Tcl_AttemptAlloc(sizeof (*zf) + strlen(mntpt) + 1); + if (zf == NULL) { + if (interp != NULL) { + Tcl_AppendResult(interp, "out of memory", (char *) NULL); + } + Unlock(); + ZipFSCloseArchive(interp, &zf0); + return TCL_ERROR; + } + *zf = zf0; + zf->name = Tcl_GetHashKey(&ZipFS.zipHash, hPtr); + strcpy(zf->mntpt, mntpt); + zf->mntptlen = strlen(zf->mntpt); + zf->entries = NULL; + zf->topents = NULL; + zf->nopen = 0; + Tcl_SetHashValue(hPtr, (ClientData) zf); + if ((zf->pwbuf[0] == 0) && pwlen) { + int k = 0; + i = pwlen; + zf->pwbuf[k++] = i; + while (i > 0) { + zf->pwbuf[k] = (passwd[i - 1] & 0x0f) | + pwrot[(passwd[i - 1] >> 4) & 0x0f]; + k++; + i--; + } + zf->pwbuf[k] = '\0'; + } + if (mntpt[0] != '\0') { + z = (ZipEntry *) Tcl_Alloc(sizeof (*z)); + z->name = NULL; + z->tnext = NULL; + z->depth = CountSlashes(mntpt); + z->zipfile = zf; + z->isdir = 1; + z->isenc = 0; + z->offset = zf->baseoffs; + z->crc32 = 0; + z->timestamp = 0; + z->nbyte = z->nbytecompr = 0; + z->cmeth = ZIP_COMPMETH_STORED; + z->data = NULL; + hPtr = Tcl_CreateHashEntry(&ZipFS.fileHash, mntpt, &isNew); + if (!isNew) { /* skip it */ Tcl_Free((char *) z); - } else { + } else { Tcl_SetHashValue(hPtr, (ClientData) z); z->name = Tcl_GetHashKey(&ZipFS.fileHash, hPtr); z->next = zf->entries; zf->entries = z; + } } - } - q = zf->data + zf->centoffs; - Tcl_DStringInit(&fpBuf); - Tcl_DStringInit(&ds); - for (i = 0; i < zf->nfiles; i++) { - int pathlen, comlen, extra, isdir = 0, dosTime, dosDate, nbcompr, offs; - unsigned char *lq, *gq = NULL; - char *fullpath, *path; - - pathlen = zip_read_short(q + ZIP_CENTRAL_PATHLEN_OFFS); - comlen = zip_read_short(q + ZIP_CENTRAL_FCOMMENTLEN_OFFS); - extra = zip_read_short(q + ZIP_CENTRAL_EXTRALEN_OFFS); - Tcl_DStringSetLength(&ds, 0); - Tcl_DStringAppend(&ds, (char *) q + ZIP_CENTRAL_HEADER_LEN, pathlen); - path = Tcl_DStringValue(&ds); - if ((pathlen > 0) && (path[pathlen - 1] == '/')) { + q = zf->data + zf->centoffs; + Tcl_DStringInit(&fpBuf); + Tcl_DStringInit(&ds); + for (i = 0; i < zf->nfiles; i++) { + int pathlen, comlen, extra, isdir = 0, dosTime, dosDate, nbcompr, offs; + unsigned char *lq, *gq = NULL; + char *fullpath, *path; + + pathlen = zip_read_short(q + ZIP_CENTRAL_PATHLEN_OFFS); + comlen = zip_read_short(q + ZIP_CENTRAL_FCOMMENTLEN_OFFS); + extra = zip_read_short(q + ZIP_CENTRAL_EXTRALEN_OFFS); + Tcl_DStringSetLength(&ds, 0); + Tcl_DStringAppend(&ds, (char *) q + ZIP_CENTRAL_HEADER_LEN, pathlen); + path = Tcl_DStringValue(&ds); + if ((pathlen > 0) && (path[pathlen - 1] == '/')) { Tcl_DStringSetLength(&ds, pathlen - 1); path = Tcl_DStringValue(&ds); isdir = 1; - } - if ((strcmp(path, ".") == 0) || (strcmp(path, "..") == 0)) { + } + if ((strcmp(path, ".") == 0) || (strcmp(path, "..") == 0)) { goto nextent; - } - lq = zf->data + zf->baseoffs + - zip_read_int(q + ZIP_CENTRAL_LOCALHDR_OFFS); - if ((lq < zf->data) || (lq > (zf->data + zf->length))) { + } + lq = zf->data + zf->baseoffs + + zip_read_int(q + ZIP_CENTRAL_LOCALHDR_OFFS); + if ((lq < zf->data) || (lq > (zf->data + zf->length))) { goto nextent; - } - nbcompr = zip_read_int(lq + ZIP_LOCAL_COMPLEN_OFFS); - if (!isdir && (nbcompr == 0) && - (zip_read_int(lq + ZIP_LOCAL_UNCOMPLEN_OFFS) == 0) && - (zip_read_int(lq + ZIP_LOCAL_CRC32_OFFS) == 0)) { + } + nbcompr = zip_read_int(lq + ZIP_LOCAL_COMPLEN_OFFS); + if (!isdir && (nbcompr == 0) && + (zip_read_int(lq + ZIP_LOCAL_UNCOMPLEN_OFFS) == 0) && + (zip_read_int(lq + ZIP_LOCAL_CRC32_OFFS) == 0)) { gq = q; nbcompr = zip_read_int(gq + ZIP_CENTRAL_COMPLEN_OFFS); - } - offs = (lq - zf->data) - + ZIP_LOCAL_HEADER_LEN - + zip_read_short(lq + ZIP_LOCAL_PATHLEN_OFFS) - + zip_read_short(lq + ZIP_LOCAL_EXTRALEN_OFFS); - if ((offs + nbcompr) > zf->length) { + } + offs = (lq - zf->data) + + ZIP_LOCAL_HEADER_LEN + + zip_read_short(lq + ZIP_LOCAL_PATHLEN_OFFS) + + zip_read_short(lq + ZIP_LOCAL_EXTRALEN_OFFS); + if ((offs + nbcompr) > zf->length) { goto nextent; - } - if (!isdir && (mntpt[0] == '\0') && !CountSlashes(path)) { + } + if (!isdir && (mntpt[0] == '\0') && !CountSlashes(path)) { #ifdef ANDROID /* * When mounting the ZIP archive on the root directory try @@ -1204,117 +1204,117 @@ TclZipfs_Mount(Tcl_Interp *interp, const char *zipname, const char *mntpt, Tcl_DStringAppend(&ds2, path, -1); hPtr = Tcl_FindHashEntry(&ZipFS.fileHash, Tcl_DStringValue(&ds2)); if (hPtr != NULL) { - /* should not happen but skip it anyway */ - Tcl_DStringFree(&ds2); - goto nextent; + /* should not happen but skip it anyway */ + Tcl_DStringFree(&ds2); + goto nextent; } Tcl_DStringSetLength(&ds, 0); Tcl_DStringAppend(&ds, Tcl_DStringValue(&ds2), - Tcl_DStringLength(&ds2)); + Tcl_DStringLength(&ds2)); path = Tcl_DStringValue(&ds); Tcl_DStringFree(&ds2); #else - /* - * Regular files skipped when mounting on root. - */ - goto nextent; + /* + * Regular files skipped when mounting on root. + */ + goto nextent; #endif - } - Tcl_DStringSetLength(&fpBuf, 0); - fullpath = CanonicalPath(mntpt, path, &fpBuf, 1); - z = (ZipEntry *) Tcl_Alloc(sizeof (*z)); - z->name = NULL; - z->tnext = NULL; - z->depth = CountSlashes(fullpath); - z->zipfile = zf; - z->isdir = isdir; - z->isenc = (zip_read_short(lq + ZIP_LOCAL_FLAGS_OFFS) & 1) + } + Tcl_DStringSetLength(&fpBuf, 0); + fullpath = CanonicalPath(mntpt, path, &fpBuf, 1); + z = (ZipEntry *) Tcl_Alloc(sizeof (*z)); + z->name = NULL; + z->tnext = NULL; + z->depth = CountSlashes(fullpath); + z->zipfile = zf; + z->isdir = isdir; + z->isenc = (zip_read_short(lq + ZIP_LOCAL_FLAGS_OFFS) & 1) && (nbcompr > 12); - z->offset = offs; - if (gq != NULL) { + z->offset = offs; + if (gq != NULL) { z->crc32 = zip_read_int(gq + ZIP_CENTRAL_CRC32_OFFS); dosDate = zip_read_short(gq + ZIP_CENTRAL_MDATE_OFFS); dosTime = zip_read_short(gq + ZIP_CENTRAL_MTIME_OFFS); z->timestamp = DosTimeDate(dosDate, dosTime); z->nbyte = zip_read_int(gq + ZIP_CENTRAL_UNCOMPLEN_OFFS); z->cmeth = zip_read_short(gq + ZIP_CENTRAL_COMPMETH_OFFS); - } else { + } else { z->crc32 = zip_read_int(lq + ZIP_LOCAL_CRC32_OFFS); dosDate = zip_read_short(lq + ZIP_LOCAL_MDATE_OFFS); dosTime = zip_read_short(lq + ZIP_LOCAL_MTIME_OFFS); z->timestamp = DosTimeDate(dosDate, dosTime); z->nbyte = zip_read_int(lq + ZIP_LOCAL_UNCOMPLEN_OFFS); z->cmeth = zip_read_short(lq + ZIP_LOCAL_COMPMETH_OFFS); - } - z->nbytecompr = nbcompr; - z->data = NULL; - hPtr = Tcl_CreateHashEntry(&ZipFS.fileHash, fullpath, &isNew); - if (!isNew) { + } + z->nbytecompr = nbcompr; + z->data = NULL; + hPtr = Tcl_CreateHashEntry(&ZipFS.fileHash, fullpath, &isNew); + if (!isNew) { /* should not happen but skip it anyway */ Tcl_Free((char *) z); - } else { + } else { Tcl_SetHashValue(hPtr, (ClientData) z); z->name = Tcl_GetHashKey(&ZipFS.fileHash, hPtr); z->next = zf->entries; zf->entries = z; if (isdir && (mntpt[0] == '\0') && (z->depth == 1)) { - z->tnext = zf->topents; - zf->topents = z; + z->tnext = zf->topents; + zf->topents = z; } if (!z->isdir && (z->depth > 1)) { - char *dir, *end; - ZipEntry *zd; - - Tcl_DStringSetLength(&ds, strlen(z->name) + 8); - Tcl_DStringSetLength(&ds, 0); - Tcl_DStringAppend(&ds, z->name, -1); - dir = Tcl_DStringValue(&ds); - end = strrchr(dir, '/'); - while ((end != NULL) && (end != dir)) { - Tcl_DStringSetLength(&ds, end - dir); - hPtr = Tcl_FindHashEntry(&ZipFS.fileHash, dir); - if (hPtr != NULL) { - break; - } - zd = (ZipEntry *) Tcl_Alloc(sizeof (*zd)); - zd->name = NULL; - zd->tnext = NULL; - zd->depth = CountSlashes(dir); - zd->zipfile = zf; - zd->isdir = 1; - zd->isenc = 0; - zd->offset = z->offset; - zd->crc32 = 0; - zd->timestamp = z->timestamp; - zd->nbyte = zd->nbytecompr = 0; - zd->cmeth = ZIP_COMPMETH_STORED; - zd->data = NULL; - hPtr = Tcl_CreateHashEntry(&ZipFS.fileHash, dir, &isNew); - if (!isNew) { - /* should not happen but skip it anyway */ - Tcl_Free((char *) zd); - } else { - Tcl_SetHashValue(hPtr, (ClientData) zd); - zd->name = Tcl_GetHashKey(&ZipFS.fileHash, hPtr); - zd->next = zf->entries; - zf->entries = zd; - if ((mntpt[0] == '\0') && (zd->depth == 1)) { - zd->tnext = zf->topents; - zf->topents = zd; - } - } - end = strrchr(dir, '/'); - } + char *dir, *end; + ZipEntry *zd; + + Tcl_DStringSetLength(&ds, strlen(z->name) + 8); + Tcl_DStringSetLength(&ds, 0); + Tcl_DStringAppend(&ds, z->name, -1); + dir = Tcl_DStringValue(&ds); + end = strrchr(dir, '/'); + while ((end != NULL) && (end != dir)) { + Tcl_DStringSetLength(&ds, end - dir); + hPtr = Tcl_FindHashEntry(&ZipFS.fileHash, dir); + if (hPtr != NULL) { + break; + } + zd = (ZipEntry *) Tcl_Alloc(sizeof (*zd)); + zd->name = NULL; + zd->tnext = NULL; + zd->depth = CountSlashes(dir); + zd->zipfile = zf; + zd->isdir = 1; + zd->isenc = 0; + zd->offset = z->offset; + zd->crc32 = 0; + zd->timestamp = z->timestamp; + zd->nbyte = zd->nbytecompr = 0; + zd->cmeth = ZIP_COMPMETH_STORED; + zd->data = NULL; + hPtr = Tcl_CreateHashEntry(&ZipFS.fileHash, dir, &isNew); + if (!isNew) { + /* should not happen but skip it anyway */ + Tcl_Free((char *) zd); + } else { + Tcl_SetHashValue(hPtr, (ClientData) zd); + zd->name = Tcl_GetHashKey(&ZipFS.fileHash, hPtr); + zd->next = zf->entries; + zf->entries = zd; + if ((mntpt[0] == '\0') && (zd->depth == 1)) { + zd->tnext = zf->topents; + zf->topents = zd; + } + } + end = strrchr(dir, '/'); + } } - } + } nextent: - q += pathlen + comlen + extra + ZIP_CENTRAL_HEADER_LEN; - } - Unlock(); - Tcl_DStringFree(&fpBuf); - Tcl_DStringFree(&ds); - Tcl_FSMountsChanged(NULL); - return TCL_OK; + q += pathlen + comlen + extra + ZIP_CENTRAL_HEADER_LEN; + } + Unlock(); + Tcl_DStringFree(&fpBuf); + Tcl_DStringFree(&ds); + Tcl_FSMountsChanged(NULL); + return TCL_OK; } /* @@ -1336,53 +1336,53 @@ nextent: int TclZipfs_Unmount(Tcl_Interp *interp, const char *zipname) { - ZipFile *zf; - ZipEntry *z, *znext; - Tcl_HashEntry *hPtr; - Tcl_DString ds; - int ret = TCL_OK, unmounted = 0; - - Tcl_DStringInit(&ds); - WriteLock(); - if (!ZipFS.initialized) { - goto done; - } - hPtr = Tcl_FindHashEntry(&ZipFS.zipHash, zipname); - if (hPtr == NULL) { - /* don't report error */ - goto done; - } - zf = (ZipFile *) Tcl_GetHashValue(hPtr); - if (zf->nopen > 0) { - if (interp != NULL) { + ZipFile *zf; + ZipEntry *z, *znext; + Tcl_HashEntry *hPtr; + Tcl_DString ds; + int ret = TCL_OK, unmounted = 0; + + Tcl_DStringInit(&ds); + WriteLock(); + if (!ZipFS.initialized) { + goto done; + } + hPtr = Tcl_FindHashEntry(&ZipFS.zipHash, zipname); + if (hPtr == NULL) { + /* don't report error */ + goto done; + } + zf = (ZipFile *) Tcl_GetHashValue(hPtr); + if (zf->nopen > 0) { + if (interp != NULL) { Tcl_SetObjResult(interp, - Tcl_NewStringObj("filesystem is busy", -1)); + Tcl_NewStringObj("filesystem is busy", -1)); + } + ret = TCL_ERROR; + goto done; } - ret = TCL_ERROR; - goto done; - } - Tcl_DeleteHashEntry(hPtr); - for (z = zf->entries; z; z = znext) { - znext = z->next; - hPtr = Tcl_FindHashEntry(&ZipFS.fileHash, z->name); - if (hPtr) { + Tcl_DeleteHashEntry(hPtr); + for (z = zf->entries; z; z = znext) { + znext = z->next; + hPtr = Tcl_FindHashEntry(&ZipFS.fileHash, z->name); + if (hPtr) { Tcl_DeleteHashEntry(hPtr); - } - if (z->data != NULL) { + } + if (z->data != NULL) { Tcl_Free((char *) z->data); + } + Tcl_Free((char *) z); } - Tcl_Free((char *) z); - } - ZipFSCloseArchive(interp, zf); - Tcl_Free((char *) zf); - unmounted = 1; + ZipFSCloseArchive(interp, zf); + Tcl_Free((char *) zf); + unmounted = 1; done: - Unlock(); - Tcl_DStringFree(&ds); - if (unmounted) { - Tcl_FSMountsChanged(NULL); - } - return ret; + Unlock(); + Tcl_DStringFree(&ds); + if (unmounted) { + Tcl_FSMountsChanged(NULL); + } + return ret; } /* @@ -2186,34 +2186,34 @@ static int ZipFSCanonicalObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { - char *mntpoint=NULL; - char *filename=NULL; - char *result; - Tcl_DString dPath; + char *mntpoint=NULL; + char *filename=NULL; + char *result; + Tcl_DString dPath; - if (objc != 2 && objc != 3 && objc!=4) { - Tcl_WrongNumArgs(interp, 1, objv, "?mntpnt? filename ?ZIPFS?"); - return TCL_ERROR; - } - Tcl_DStringInit(&dPath); - if(objc==2) { - filename = Tcl_GetString(objv[1]); - result=CanonicalPath("",filename,&dPath,1); - } else if (objc==3) { - mntpoint = Tcl_GetString(objv[1]); - filename = Tcl_GetString(objv[2]); - result=CanonicalPath(mntpoint,filename,&dPath,1); - } else { - int zipfs=0; - if(Tcl_GetBooleanFromObj(interp,objv[3],&zipfs)) { - return TCL_ERROR; + if (objc != 2 && objc != 3 && objc!=4) { + Tcl_WrongNumArgs(interp, 1, objv, "?mntpnt? filename ?ZIPFS?"); + return TCL_ERROR; + } + Tcl_DStringInit(&dPath); + if(objc==2) { + filename = Tcl_GetString(objv[1]); + result=CanonicalPath("",filename,&dPath,1); + } else if (objc==3) { + mntpoint = Tcl_GetString(objv[1]); + filename = Tcl_GetString(objv[2]); + result=CanonicalPath(mntpoint,filename,&dPath,1); + } else { + int zipfs=0; + if(Tcl_GetBooleanFromObj(interp,objv[3],&zipfs)) { + return TCL_ERROR; + } + mntpoint = Tcl_GetString(objv[1]); + filename = Tcl_GetString(objv[2]); + result=CanonicalPath(mntpoint,filename,&dPath,zipfs); } - mntpoint = Tcl_GetString(objv[1]); - filename = Tcl_GetString(objv[2]); - result=CanonicalPath(mntpoint,filename,&dPath,zipfs); - } - Tcl_SetObjResult(interp,Tcl_NewStringObj(result,-1)); - return TCL_OK; + Tcl_SetObjResult(interp,Tcl_NewStringObj(result,-1)); + return TCL_OK; } /* @@ -3210,154 +3210,154 @@ Zip_FSMatchInDirectoryProc(Tcl_Interp* interp, Tcl_Obj *result, Tcl_Obj *pathPtr, const char *pattern, Tcl_GlobTypeData *types) { - Tcl_HashEntry *hPtr; - Tcl_HashSearch search; - Tcl_Obj *normPathPtr; - int scnt, len, l, dirOnly = -1, prefixLen, strip = 0; - char *pat, *prefix, *path; - Tcl_DString dsPref; - - if (!(normPathPtr = Tcl_FSGetNormalizedPath(NULL, pathPtr))) return -1; - - if (types != NULL) { - dirOnly = (types->type & TCL_GLOB_TYPE_DIR) == TCL_GLOB_TYPE_DIR; - } - - /* the prefix that gets prepended to results */ - prefix = Tcl_GetStringFromObj(pathPtr, &prefixLen); - - /* the (normalized) path we're searching */ - path = Tcl_GetStringFromObj(normPathPtr, &len); - - Tcl_DStringInit(&dsPref); - Tcl_DStringAppend(&dsPref, prefix, prefixLen); - - if (strcmp(prefix, path) == 0) { - prefix = NULL; - } else { - strip = len + 1; - } - if (prefix != NULL) { - Tcl_DStringAppend(&dsPref, "/", 1); - prefixLen++; - prefix = Tcl_DStringValue(&dsPref); - } - ReadLock(); - if ((types != NULL) && (types->type == TCL_GLOB_TYPE_MOUNT)) { - l = CountSlashes(path); - if (path[len - 1] == '/') { - len--; + Tcl_HashEntry *hPtr; + Tcl_HashSearch search; + Tcl_Obj *normPathPtr; + int scnt, len, l, dirOnly = -1, prefixLen, strip = 0; + char *pat, *prefix, *path; + Tcl_DString dsPref; + + if (!(normPathPtr = Tcl_FSGetNormalizedPath(NULL, pathPtr))) return -1; + + if (types != NULL) { + dirOnly = (types->type & TCL_GLOB_TYPE_DIR) == TCL_GLOB_TYPE_DIR; + } + + /* the prefix that gets prepended to results */ + prefix = Tcl_GetStringFromObj(pathPtr, &prefixLen); + + /* the (normalized) path we're searching */ + path = Tcl_GetStringFromObj(normPathPtr, &len); + + Tcl_DStringInit(&dsPref); + Tcl_DStringAppend(&dsPref, prefix, prefixLen); + + if (strcmp(prefix, path) == 0) { + prefix = NULL; } else { - l++; + strip = len + 1; } - if ((pattern == NULL) || (pattern[0] == '\0')) { - pattern = "*"; + if (prefix != NULL) { + Tcl_DStringAppend(&dsPref, "/", 1); + prefixLen++; + prefix = Tcl_DStringValue(&dsPref); } - hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); - while (hPtr != NULL) { + ReadLock(); + if ((types != NULL) && (types->type == TCL_GLOB_TYPE_MOUNT)) { + l = CountSlashes(path); + if (path[len - 1] == '/') { + len--; + } else { + l++; + } + if ((pattern == NULL) || (pattern[0] == '\0')) { + pattern = "*"; + } + hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); + while (hPtr != NULL) { ZipFile *zf = (ZipFile *) Tcl_GetHashValue(hPtr); if (zf->mntptlen == 0) { - ZipEntry *z = zf->topents; - while (z != NULL) { - int lenz = strlen(z->name); - if ((lenz > len + 1) && - (strncmp(z->name, path, len) == 0) && - (z->name[len] == '/') && - (CountSlashes(z->name) == l) && - Tcl_StringCaseMatch(z->name + len + 1, pattern, 0)) { - if (prefix != NULL) { - Tcl_DStringAppend(&dsPref, z->name, lenz); - Tcl_ListObjAppendElement(NULL, result, - Tcl_NewStringObj(Tcl_DStringValue(&dsPref), - Tcl_DStringLength(&dsPref))); - Tcl_DStringSetLength(&dsPref, prefixLen); - } else { - Tcl_ListObjAppendElement(NULL, result, - Tcl_NewStringObj(z->name, lenz)); - } - } - z = z->tnext; - } + ZipEntry *z = zf->topents; + while (z != NULL) { + int lenz = strlen(z->name); + if ((lenz > len + 1) && + (strncmp(z->name, path, len) == 0) && + (z->name[len] == '/') && + (CountSlashes(z->name) == l) && + Tcl_StringCaseMatch(z->name + len + 1, pattern, 0)) { + if (prefix != NULL) { + Tcl_DStringAppend(&dsPref, z->name, lenz); + Tcl_ListObjAppendElement(NULL, result, + Tcl_NewStringObj(Tcl_DStringValue(&dsPref), + Tcl_DStringLength(&dsPref))); + Tcl_DStringSetLength(&dsPref, prefixLen); + } else { + Tcl_ListObjAppendElement(NULL, result, + Tcl_NewStringObj(z->name, lenz)); + } + } + z = z->tnext; + } } else if ((zf->mntptlen > len + 1) && - (strncmp(zf->mntpt, path, len) == 0) && - (zf->mntpt[len] == '/') && - (CountSlashes(zf->mntpt) == l) && - Tcl_StringCaseMatch(zf->mntpt + len + 1, pattern, 0)) { - if (prefix != NULL) { - Tcl_DStringAppend(&dsPref, zf->mntpt, zf->mntptlen); - Tcl_ListObjAppendElement(NULL, result, - Tcl_NewStringObj(Tcl_DStringValue(&dsPref), - Tcl_DStringLength(&dsPref))); - Tcl_DStringSetLength(&dsPref, prefixLen); - } else { - Tcl_ListObjAppendElement(NULL, result, - Tcl_NewStringObj(zf->mntpt, zf->mntptlen)); - } + (strncmp(zf->mntpt, path, len) == 0) && + (zf->mntpt[len] == '/') && + (CountSlashes(zf->mntpt) == l) && + Tcl_StringCaseMatch(zf->mntpt + len + 1, pattern, 0)) { + if (prefix != NULL) { + Tcl_DStringAppend(&dsPref, zf->mntpt, zf->mntptlen); + Tcl_ListObjAppendElement(NULL, result, + Tcl_NewStringObj(Tcl_DStringValue(&dsPref), + Tcl_DStringLength(&dsPref))); + Tcl_DStringSetLength(&dsPref, prefixLen); + } else { + Tcl_ListObjAppendElement(NULL, result, + Tcl_NewStringObj(zf->mntpt, zf->mntptlen)); + } } hPtr = Tcl_NextHashEntry(&search); + } + goto end; } - goto end; - } - if ((pattern == NULL) || (pattern[0] == '\0')) { - hPtr = Tcl_FindHashEntry(&ZipFS.fileHash, path); - if (hPtr != NULL) { + if ((pattern == NULL) || (pattern[0] == '\0')) { + hPtr = Tcl_FindHashEntry(&ZipFS.fileHash, path); + if (hPtr != NULL) { ZipEntry *z = (ZipEntry *) Tcl_GetHashValue(hPtr); if ((dirOnly < 0) || - (!dirOnly && !z->isdir) || - (dirOnly && z->isdir)) { - if (prefix != NULL) { - Tcl_DStringAppend(&dsPref, z->name, -1); - Tcl_ListObjAppendElement(NULL, result, - Tcl_NewStringObj(Tcl_DStringValue(&dsPref), - Tcl_DStringLength(&dsPref))); - Tcl_DStringSetLength(&dsPref, prefixLen); - } else { - Tcl_ListObjAppendElement(NULL, result, - Tcl_NewStringObj(z->name, -1)); - } + (!dirOnly && !z->isdir) || + (dirOnly && z->isdir)) { + if (prefix != NULL) { + Tcl_DStringAppend(&dsPref, z->name, -1); + Tcl_ListObjAppendElement(NULL, result, + Tcl_NewStringObj(Tcl_DStringValue(&dsPref), + Tcl_DStringLength(&dsPref))); + Tcl_DStringSetLength(&dsPref, prefixLen); + } else { + Tcl_ListObjAppendElement(NULL, result, + Tcl_NewStringObj(z->name, -1)); + } } - } - goto end; - } - l = strlen(pattern); - pat = Tcl_Alloc(len + l + 2); - memcpy(pat, path, len); - while ((len > 1) && (pat[len - 1] == '/')) { - --len; - } - if ((len > 1) || (pat[0] != '/')) { - pat[len] = '/'; - ++len; - } - memcpy(pat + len, pattern, l + 1); - scnt = CountSlashes(pat); - for (hPtr = Tcl_FirstHashEntry(&ZipFS.fileHash, &search); - hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) { - ZipEntry *z = (ZipEntry *) Tcl_GetHashValue(hPtr); - if ((dirOnly >= 0) && - ((dirOnly && !z->isdir) || (!dirOnly && z->isdir))) { + } + goto end; + } + l = strlen(pattern); + pat = Tcl_Alloc(len + l + 2); + memcpy(pat, path, len); + while ((len > 1) && (pat[len - 1] == '/')) { + --len; + } + if ((len > 1) || (pat[0] != '/')) { + pat[len] = '/'; + ++len; + } + memcpy(pat + len, pattern, l + 1); + scnt = CountSlashes(pat); + for (hPtr = Tcl_FirstHashEntry(&ZipFS.fileHash, &search); + hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) { + ZipEntry *z = (ZipEntry *) Tcl_GetHashValue(hPtr); + if ((dirOnly >= 0) && + ((dirOnly && !z->isdir) || (!dirOnly && z->isdir))) { continue; - } - if ((z->depth == scnt) && Tcl_StringCaseMatch(z->name, pat, 0)) { + } + if ((z->depth == scnt) && Tcl_StringCaseMatch(z->name, pat, 0)) { if (prefix != NULL) { - Tcl_DStringAppend(&dsPref, z->name + strip, -1); - Tcl_ListObjAppendElement(NULL, result, - Tcl_NewStringObj(Tcl_DStringValue(&dsPref), - Tcl_DStringLength(&dsPref))); - Tcl_DStringSetLength(&dsPref, prefixLen); + Tcl_DStringAppend(&dsPref, z->name + strip, -1); + Tcl_ListObjAppendElement(NULL, result, + Tcl_NewStringObj(Tcl_DStringValue(&dsPref), + Tcl_DStringLength(&dsPref))); + Tcl_DStringSetLength(&dsPref, prefixLen); } else { - Tcl_ListObjAppendElement(NULL, result, - Tcl_NewStringObj(z->name + strip, -1)); + Tcl_ListObjAppendElement(NULL, result, + Tcl_NewStringObj(z->name + strip, -1)); } + } } - } - Tcl_Free(pat); + Tcl_Free(pat); end: - Unlock(); - Tcl_DStringFree(&dsPref); - return TCL_OK; + Unlock(); + Tcl_DStringFree(&dsPref); + return TCL_OK; } /* @@ -3445,7 +3445,7 @@ endloop: */ static Tcl_Obj * Zip_FSListVolumesProc(void) { - return Tcl_NewStringObj(ZIPFS_VOLUME, -1); + return Tcl_NewStringObj(ZIPFS_VOLUME, -1); } /* -- cgit v0.12 From 7c1f63bb60215a26625aa1f5a7ad3074d83d4898 Mon Sep 17 00:00:00 2001 From: aspect Date: Fri, 17 Nov 2017 10:24:45 +0000 Subject: clean up stray unused dstrings --- generic/tclZipfs.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c index 5aa001f..38abf0e 100644 --- a/generic/tclZipfs.c +++ b/generic/tclZipfs.c @@ -699,9 +699,7 @@ ZipFSLookupMount(char *filename) Tcl_HashEntry *hPtr; Tcl_HashSearch search; ZipFile *zf; - Tcl_DString ds; int match = 0; - Tcl_DStringInit(&ds); hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); while (hPtr != NULL) { if ((zf = (ZipFile *) Tcl_GetHashValue(hPtr)) != NULL) { @@ -712,7 +710,6 @@ ZipFSLookupMount(char *filename) } hPtr = Tcl_NextHashEntry(&search); } - Tcl_DStringFree(&ds); return match; } #endif @@ -1339,10 +1336,8 @@ TclZipfs_Unmount(Tcl_Interp *interp, const char *zipname) ZipFile *zf; ZipEntry *z, *znext; Tcl_HashEntry *hPtr; - Tcl_DString ds; int ret = TCL_OK, unmounted = 0; - Tcl_DStringInit(&ds); WriteLock(); if (!ZipFS.initialized) { goto done; @@ -1378,7 +1373,6 @@ TclZipfs_Unmount(Tcl_Interp *interp, const char *zipname) unmounted = 1; done: Unlock(); - Tcl_DStringFree(&ds); if (unmounted) { Tcl_FSMountsChanged(NULL); } -- cgit v0.12 From f81c2ae72421a94e27139ec158ac8822ad6beb5c Mon Sep 17 00:00:00 2001 From: aspect Date: Fri, 17 Nov 2017 11:53:19 +0000 Subject: fix [glob] handling of leading // --- generic/tclFileName.c | 2 +- tests/zipfs.test | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/generic/tclFileName.c b/generic/tclFileName.c index 15fcde7..015cfc3 100644 --- a/generic/tclFileName.c +++ b/generic/tclFileName.c @@ -1881,7 +1881,7 @@ TclGlob( separators = "/\\"; } else if (tclPlatform == TCL_PLATFORM_UNIX) { - if (pathPrefix == NULL && tail[0] == '/') { + if (pathPrefix == NULL && tail[0] == '/' && tail[1] != '/') { pathPrefix = Tcl_NewStringObj(tail, 1); tail++; Tcl_IncrRefCount(pathPrefix); diff --git a/tests/zipfs.test b/tests/zipfs.test index b14aa7d..97dc463 100644 --- a/tests/zipfs.test +++ b/tests/zipfs.test @@ -55,14 +55,18 @@ test zipfs-0.5 {zipfs basics: glob} -constraints zipfs -body { } -result [list $tcl_library/http $tcl_library/http1.0] test zipfs-0.6 {zipfs basics: glob} -constraints zipfs -body { + lsort [glob $tcl_library/http*] +} -result [list $tcl_library/http $tcl_library/http1.0] + +test zipfs-0.7 {zipfs basics: glob} -constraints zipfs -body { lsort [glob -tails -dir $tcl_library http*] } -result {http http1.0} -test zipfs-0.7 {zipfs basics: glob} -constraints zipfs -body { +test zipfs-0.8 {zipfs basics: glob} -constraints zipfs -body { lsort [glob -nocomplain -tails -types d -dir $tcl_library http*] } -result {http http1.0} -test zipfs-0.8 {zipfs basics: glob} -constraints zipfs -body { +test zipfs-0.9 {zipfs basics: glob} -constraints zipfs -body { lsort [glob -nocomplain -tails -types f -dir $tcl_library http*] } -result {} -- cgit v0.12 From c6d82079ea51d3ce14e290d139edd76ddc971794 Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Fri, 17 Nov 2017 17:23:01 +0000 Subject: Added a package manifest to init to allow core distributed packages to auto-populate [package ifneeded] on startup --- library/init.tcl | 4 ++++ library/pkgIndex.tcl | 16 ++++++++++++++++ 2 files changed, 20 insertions(+) create mode 100644 library/pkgIndex.tcl diff --git a/library/init.tcl b/library/init.tcl index 87d9f14..38d8726 100644 --- a/library/init.tcl +++ b/library/init.tcl @@ -836,3 +836,7 @@ proc tcl::CopyDirectory {action src dest} { } return } +if {[file exists [file join $::tcl_library pkgIndex.tcl]]} { + set dir $::tcl_library + source [file join $::tcl_library pkgIndex.tcl] +} diff --git a/library/pkgIndex.tcl b/library/pkgIndex.tcl new file mode 100644 index 0000000..ff8d0f1 --- /dev/null +++ b/library/pkgIndex.tcl @@ -0,0 +1,16 @@ +### +# Package manifest for all Tcl packages included in the /library file system +### +foreach {package version file} { + http 2.8.12 {http http.tcl} + http 1.0 {http1.0 http.tcl} + msgcat 1.6.1 {msgcat msgcat.tcl} + opt 0.4.7 {opt optparse.tcl} + platform 1.0.14 {platform platform.tcl} + platform::shell 1.1.4 {platform shell.tcl} + tcltest 2.4.1 {tcltest tcltest.tcl} +} { + package ifneeded $package $version [list source [file join $dir {*}$file]] +} +# Opt is the odd man out +package ifneeded opt 0.4.7 [list source [file join $dir opt optparse.tcl]] -- cgit v0.12 From b59255450b97c1cc7fe5223937c86c805aa89eb8 Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Sat, 18 Nov 2017 11:48:08 +0000 Subject: Added a pool of literal strings to zipfs to manage constants that are being belched out by the file system. Created a separate mount point for Unix and Windows, with a new "zipfs root" command to tell the user which location to use for their platform --- generic/tclZipfs.c | 92 ++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 76 insertions(+), 16 deletions(-) diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c index 8eae35a..4a72392 100644 --- a/generic/tclZipfs.c +++ b/generic/tclZipfs.c @@ -28,12 +28,21 @@ #include "zlib.h" #include "crypt.h" +/* +** On windows we need VFS to look like a volume +** On Unix we need it to look like a UNC path +*/ +#if defined(_WIN32) || defined(_WIN64) +#define ZIPFS_VOLUME "zipfs:/" +#define ZIPFS_VOLUME_LEN 7 +#define ZIPFS_APP_MOUNT "zipfs:/app" +#define ZIPFS_ZIP_MOUNT "zipfs:/lib/tcl" +#else #define ZIPFS_VOLUME "//zipfs:/" +#define ZIPFS_VOLUME_LEN 9 #define ZIPFS_APP_MOUNT "//zipfs:/app" #define ZIPFS_ZIP_MOUNT "//zipfs:/lib/tcl" - -#define ZIPFS_VOLUME_LEN 9 - +#endif /* * Various constants and offsets found in ZIP archive files */ @@ -292,6 +301,11 @@ static const unsigned long crc32tab[256] = { 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d, }; + +static Tcl_Obj *zipfs_literal_fstype=NULL; +static Tcl_Obj *zipfs_literal_fsroot=NULL; +static Tcl_Obj *zipfs_literal_fsseparator=NULL; + /* *------------------------------------------------------------------------- @@ -1412,6 +1426,35 @@ ZipFSMountObjCmd(ClientData clientData, Tcl_Interp *interp, /* *------------------------------------------------------------------------- * + * ZipFSRootObjCmd -- + * + * This procedure is invoked to process the "zipfs::root" command. It + * returns the root that all zipfs file systems are mounted under. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * + *------------------------------------------------------------------------- + */ + +static int +ZipFSRootObjCmd(ClientData clientData, Tcl_Interp *interp, + int objc, Tcl_Obj *const objv[]) +{ + if(!zipfs_literal_fsroot) { + zipfs_literal_fsroot=Tcl_NewStringObj(ZIPFS_VOLUME, -1); + Tcl_IncrRefCount(zipfs_literal_fsroot); + } + Tcl_IncrRefCount(zipfs_literal_fsroot); + Tcl_SetObjResult(interp,zipfs_literal_fsroot); + return TCL_OK; +} + +/* + *------------------------------------------------------------------------- + * * ZipFSUnmountObjCmd -- * * This procedure is invoked to process the "zipfs::unmount" command. @@ -3178,7 +3221,12 @@ Zip_FSAccessProc(Tcl_Obj *pathPtr, int mode) static Tcl_Obj * Zip_FSFilesystemSeparatorProc(Tcl_Obj *pathPtr) { - return Tcl_NewStringObj("/", -1); + if(!zipfs_literal_fsseparator) { + zipfs_literal_fsseparator=Tcl_NewStringObj("/", -1); + Tcl_IncrRefCount(zipfs_literal_fsseparator); + } + Tcl_IncrRefCount(zipfs_literal_fsseparator); + return zipfs_literal_fsseparator; } /* @@ -3439,7 +3487,12 @@ endloop: */ static Tcl_Obj * Zip_FSListVolumesProc(void) { - return Tcl_NewStringObj(ZIPFS_VOLUME, -1); + if(!zipfs_literal_fsroot) { + zipfs_literal_fsroot=Tcl_NewStringObj(ZIPFS_VOLUME, -1); + Tcl_IncrRefCount(zipfs_literal_fsroot); + } + Tcl_IncrRefCount(zipfs_literal_fsroot); + return zipfs_literal_fsroot; } /* @@ -3586,7 +3639,12 @@ Zip_FSFileAttrsSetProc(Tcl_Interp *interp, int index, Tcl_Obj *pathPtr, static Tcl_Obj * Zip_FSFilesystemPathTypeProc(Tcl_Obj *pathPtr) { - return Tcl_NewStringObj("zip", -1); + if(!zipfs_literal_fstype) { + zipfs_literal_fstype=Tcl_NewStringObj("zip", -1); + Tcl_IncrRefCount(zipfs_literal_fstype); + } + Tcl_IncrRefCount(zipfs_literal_fstype); + return zipfs_literal_fstype; } @@ -3788,17 +3846,19 @@ TclZipfs_Init(Tcl_Interp *interp) Unlock(); if(interp != NULL) { static const EnsembleImplMap initMap[] = { - {"mount", ZipFSMountObjCmd, NULL, NULL, NULL, 0}, - {"unmount", ZipFSUnmountObjCmd, NULL, NULL, NULL, 0}, - {"mkkey", ZipFSMkKeyObjCmd, NULL, NULL, NULL, 0}, - {"mkimg", ZipFSMkImgObjCmd, NULL, NULL, NULL, 0}, - {"mkzip", ZipFSMkZipObjCmd, NULL, NULL, NULL, 0}, - {"lmkimg", ZipFSLMkImgObjCmd, NULL, NULL, NULL, 0}, - {"lmkzip", ZipFSLMkZipObjCmd, NULL, NULL, NULL, 0}, - {"exists", ZipFSExistsObjCmd, NULL, NULL, NULL, 1}, - {"info", ZipFSInfoObjCmd, NULL, NULL, NULL, 1}, - {"list", ZipFSListObjCmd, NULL, NULL, NULL, 1}, + {"mount", ZipFSMountObjCmd, NULL, NULL, NULL, 0}, + {"unmount", ZipFSUnmountObjCmd, NULL, NULL, NULL, 0}, + {"mkkey", ZipFSMkKeyObjCmd, NULL, NULL, NULL, 0}, + {"mkimg", ZipFSMkImgObjCmd, NULL, NULL, NULL, 0}, + {"mkzip", ZipFSMkZipObjCmd, NULL, NULL, NULL, 0}, + {"lmkimg", ZipFSLMkImgObjCmd, NULL, NULL, NULL, 0}, + {"lmkzip", ZipFSLMkZipObjCmd, NULL, NULL, NULL, 0}, + {"exists", ZipFSExistsObjCmd, NULL, NULL, NULL, 1}, + {"info", ZipFSInfoObjCmd, NULL, NULL, NULL, 1}, + {"list", ZipFSListObjCmd, NULL, NULL, NULL, 1}, {"canonical", ZipFSCanonicalObjCmd, NULL, NULL, NULL, 1}, + {"root", ZipFSRootObjCmd, NULL, NULL, NULL, 1}, + {NULL, NULL, NULL, NULL, NULL, 0} }; static const char findproc[] = -- cgit v0.12 From 02a019458f248912f3eaffedd11359545eb79abb Mon Sep 17 00:00:00 2001 From: tne Date: Sat, 18 Nov 2017 11:59:20 +0000 Subject: Updated zipfs tests to recognize the mount points are different on different platforms --- tests/zipfs.test | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/tests/zipfs.test b/tests/zipfs.test index 97dc463..9284404 100644 --- a/tests/zipfs.test +++ b/tests/zipfs.test @@ -22,16 +22,18 @@ testConstraint zipfs [expr {[llength [info commands zlib]] && [regexp tcltest [i # load {} zipfs #} -result {} +set ziproot [zipfs root] + test zipfs-0.1 {zipfs basics} -constraints zipfs -body { package require zipfs -} -result {1.0} +} -result {2.0} test zipfs-0.1 {zipfs basics} -constraints zipfs -body { - expr {"//zipfs:/" in [file volumes]} + expr {${ziproot} in [file volumes]} } -result 1 test zipfs-0.2 {zipfs basics} -constraints zipfs -body { - string match //zipfs:/* $tcl_library + string match ${ziproot}* $tcl_library } -result 1 test zipfs-0.3 {zipfs basics: glob} -constraints zipfs -body { @@ -111,18 +113,18 @@ test zipfs-2.2 {zipfs mkzip} -constraints zipfs -body { set pwd [pwd] cd $tcl_library/encoding zipfs mkzip /tmp/abc.zip . - zipfs mount /tmp/abc.zip //zipfs:/abc ;# FIXME: test independence - zipfs list -glob //zipfs:/abc/cp850.* + zipfs mount /tmp/abc.zip /abc ;# FIXME: test independence + zipfs list -glob ${ziproot}/abc/cp850.* } -cleanup { cd $pwd -} -result {//zipfs:/abc/cp850.enc} +} -result {[zipfs root]/abc/cp850.enc} test zipfs-2.3 {zipfs info} -constraints zipfs -body { - zipfs info //zipfs:/abc/cp850.enc + zipfs info ${ziproot}/abc/cp850.enc } -result [list /tmp/abc.zip 1090 527 39318] ;# FIXME: result depends on content of encodings dir test zipfs-2.4 {zipfs data} -constraints zipfs -body { - set zipfd [open //zipfs:/abc/cp850.enc] ;# FIXME: leave open - see later test + set zipfd [open ${ziproot}/abc/cp850.enc] ;# FIXME: leave open - see later test read $zipfd } -result {# Encoding file: cp850, single-byte S -- cgit v0.12 From b171f5cc41b72d1f0b313a6b720394c25bd8d310 Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Sat, 18 Nov 2017 12:21:35 +0000 Subject: Added documentation for the zipfs root command and working of TclZipfs_AppHook --- doc/zipfs.3 | 22 +++++++++++++++++++++- doc/zipfs.n | 10 ++++++++-- 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/doc/zipfs.3 b/doc/zipfs.3 index a3b3da8..b23afae 100644 --- a/doc/zipfs.3 +++ b/doc/zipfs.3 @@ -10,16 +10,24 @@ .so man.macros .BS .SH NAME -Tclzipfs_Mount, Tclzipfs_Unmount \- handle ZIP files as VFS +TclZipfs_AppHook, Tclzipfs_Mount, Tclzipfs_Unmount, \- handle ZIP files as VFS .SH SYNOPSIS .nf .sp int +\fBTclZipfs_AppHook(\fIint *argc, char ***argv\fR) +.sp +int \fBTclzipfs_Mount\fR(\fIinterp, zipname, mntpt, passwd\fR) .sp int \fBTclzipfs_Unmount\fR(\fIinterp, zipname\fR) .SH ARGUMENTS +.AP "int" *argc in +Number of command line arguments from main() +.AP "char" ***argv in +Pointer to an array of strings containing the command +line arguments to main() .AS Tcl_Interp **termPtr .AP Tcl_Interp *interp in Interpreter in which the zip file system is mounted. The interpreter's result is @@ -32,6 +40,18 @@ Name of a mount point. An (optional) password. .BE .SH DESCRIPTION +\fBTclZipfs_AppHook()\fR is a utility function to perform standard +application initialization procedures. If the current application has +a mountable zip file system, that file system is mounted under \fIZIPROOT\fR\fB/app\fR. +If a file named \fBmain.tcl\fR is located in that file system, it is treated +as the startup script for the process. If the file \fIZIPROOT\fR\fB/app/tcl_library/init.tcl\fR +is present, \fBtcl_library\fR is set to \fIZIPROOT\fR\fB/app/tcl_library. +.PP +If the \fBtcl_library\fR was not found in the application, the system will then search for it +as either a VFS attached to the application dynamic library, or as a zip archive named +libtcl_\fIMAJOR\fR_\fIMINOR\fR_\fIpatchLevel\fR.zip either in the present working directory +or in the standard tcl install location. +.PP \fBTclzipfs_Mount()\fR mount the ZIP archive \fIzipname\fR on the mount point given in \fImntpt\fR using the optional ZIP password \fIpasswd\fR. Errors during that process are reported in the interpreter \fIinterp\fR. diff --git a/doc/zipfs.n b/doc/zipfs.n index f82100f..a026b6d 100644 --- a/doc/zipfs.n +++ b/doc/zipfs.n @@ -24,6 +24,7 @@ zipfs \- Mount and work with ZIP files within Tcl \fBzipfs mkkey\fR \fIpassword\fR \fBzipfs mkzip\fR \fIoutfile\fR \fIindir\fR \fI?strip?\fR \fI?password?\fR \fBzipfs mount\fR \fI?zipfile?\fR \fI?mountpoint?\fR \fI?password?\fR +\fBzipfs root\fR \fBzipfs unmount\fR \fIzipfile\fR .fi .BE @@ -41,7 +42,7 @@ Return 1 if the given filename exists in the mounted zipfs and 0 if it does not. Recursively lists files including and below the directory \fIdir\fR. The result list consists of relative path names starting from the given directory. This command is also used by the \fBzipfs mkzip\fR -and \fBzipfs mkimg\fR commands. +and \fBzipfs mkimg\fR commands. .TP \fBzipfs info\fR \fIfile\fR . @@ -92,7 +93,7 @@ of the respective file name. .PP Caution: the choice of the \fIindir\fR parameter (less the optional stripped prefix) determines the later root name of the -archive's content. +archive's content. .RE .TP \fBzipfs mount ?\fIzipfile\fR? ?\fImountpoint\fR? ?\fIpassword\fR? @@ -107,6 +108,11 @@ With no \fIzipfile\fR, return all zipfile/mount pairs. If \fImountpoint\fR is specified as an empty string, mount on file path. .RE .TP +\fBzipfs root\fR +Returns a constant string which indicates the mount point for zipfs volumes +for the current platform. On Windows, this value is zipfs:/. On Unux, //zipfs:/ +.RE +.TP \fBzipfs unmount \fIzipfile\fR . Unmounts a previously mounted ZIP archive file \fIzipfile\fR. -- cgit v0.12 From 3730061388d459b86b5b62d877d786e1ddfee7ff Mon Sep 17 00:00:00 2001 From: aspect Date: Sat, 18 Nov 2017 17:02:08 +0000 Subject: fix zipfs tests --- tests/zipfs.test | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/zipfs.test b/tests/zipfs.test index 9284404..ce287da 100644 --- a/tests/zipfs.test +++ b/tests/zipfs.test @@ -113,14 +113,14 @@ test zipfs-2.2 {zipfs mkzip} -constraints zipfs -body { set pwd [pwd] cd $tcl_library/encoding zipfs mkzip /tmp/abc.zip . - zipfs mount /tmp/abc.zip /abc ;# FIXME: test independence - zipfs list -glob ${ziproot}/abc/cp850.* + zipfs mount /tmp/abc.zip ${ziproot}abc ;# FIXME: test independence + zipfs list -glob ${ziproot}abc/cp850.* } -cleanup { cd $pwd -} -result {[zipfs root]/abc/cp850.enc} +} -result "[zipfs root]abc/cp850.enc" test zipfs-2.3 {zipfs info} -constraints zipfs -body { - zipfs info ${ziproot}/abc/cp850.enc + zipfs info ${ziproot}abc/cp850.enc } -result [list /tmp/abc.zip 1090 527 39318] ;# FIXME: result depends on content of encodings dir test zipfs-2.4 {zipfs data} -constraints zipfs -body { -- cgit v0.12 From d8a0c08bbc357c4f126c8852692c0fd6d9d2688a Mon Sep 17 00:00:00 2001 From: aspect Date: Sat, 18 Nov 2017 17:04:03 +0000 Subject: add some tests for join and normalize --- tests/zipfs.test | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tests/zipfs.test b/tests/zipfs.test index ce287da..abf888b 100644 --- a/tests/zipfs.test +++ b/tests/zipfs.test @@ -72,6 +72,17 @@ test zipfs-0.9 {zipfs basics: glob} -constraints zipfs -body { lsort [glob -nocomplain -tails -types f -dir $tcl_library http*] } -result {} +test zipfs-0.10 {zipfs basics: join} -constraints zipfs -body { + file join [zipfs root] bar baz +} -result "[zipfs root]bar/baz" + +test zipfs-0.11 {zipfs basics: join} -constraints zipfs -body { + file normalize [zipfs root] +} -result "[zipfs root]" + +test zipfs-0.12 {zipfs basics: join} -constraints zipfs -body { + file normalize [zipfs root]//bar/baz//qux/../ +} -result "[zipfs root]bar/baz" test zipfs-1.3 {zipfs errors} -constraints zipfs -returnCodes error -body { zipfs mount a b c d e f -- cgit v0.12 From 157e55c7bc831fdf3cb6d68917ac6c7222442166 Mon Sep 17 00:00:00 2001 From: aspect Date: Sat, 18 Nov 2017 17:07:48 +0000 Subject: Reserve paths matching //[^/]*: for VFS mount points, and prevent calling native filesystem ops during normalization for them. This is permitted by UNC standards (which do not allow : at the end), and should prevent observed slow [glob] operations (and others) on Windows when using such paths. --- generic/tclIOUtil.c | 59 ++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 45 insertions(+), 14 deletions(-) diff --git a/generic/tclIOUtil.c b/generic/tclIOUtil.c index 4f2288e..bca74fa 100644 --- a/generic/tclIOUtil.c +++ b/generic/tclIOUtil.c @@ -1400,31 +1400,62 @@ TclFSNormalizeToUniquePath( { FilesystemRecord *fsRecPtr, *firstFsRecPtr; + int i; + int isVfsPath = 0; + char *path; + /* - * Call each of the "normalise path" functions in succession. This is a - * special case, in which if we have a native filesystem handler, we call - * it first. This is because the root of Tcl's filesystem is always a - * native filesystem (i.e., '/' on unix is native). + * Paths starting with a UNC prefix whose final character is a colon + * are reserved for VFS use. These names can not conflict with real + * UNC paths per https://msdn.microsoft.com/en-us/library/gg465305.aspx + * and rfc3986's definition of reg-name. + * + * We check these first to avoid useless calls to the native filesystem's + * normalizePathProc. */ + path = Tcl_GetStringFromObj(pathPtr, &i); + + if ( (i >= 3) && ( (path[0] == '/' && path[1] == '/') + || (path[0] == '\\' && path[1] == '\\') ) ) { + for ( i = 2; ; i++) { + if (path[i] == '\0') break; + if (path[i] == path[0]) break; + } + --i; + if (path[i] == ':') isVfsPath = 1; + } + /* + * Call each of the "normalise path" functions in succession. + */ firstFsRecPtr = FsGetFirstFilesystem(); Claim(); - for (fsRecPtr=firstFsRecPtr; fsRecPtr!=NULL; fsRecPtr=fsRecPtr->nextPtr) { - if (fsRecPtr->fsPtr != &tclNativeFilesystem) { - continue; - } + + if (!isVfsPath) { /* - * TODO: Assume that we always find the native file system; it should - * always be there... + * If we have a native filesystem handler, we call it first. This is + * because the root of Tcl's filesystem is always a native filesystem + * (i.e., '/' on unix is native). */ - if (fsRecPtr->fsPtr->normalizePathProc != NULL) { - startAt = fsRecPtr->fsPtr->normalizePathProc(interp, pathPtr, - startAt); + for (fsRecPtr=firstFsRecPtr; fsRecPtr!=NULL; fsRecPtr=fsRecPtr->nextPtr) { + if (fsRecPtr->fsPtr != &tclNativeFilesystem) { + continue; + } + + /* + * TODO: Assume that we always find the native file system; it should + * always be there... + */ + + if (fsRecPtr->fsPtr->normalizePathProc != NULL) { + startAt = fsRecPtr->fsPtr->normalizePathProc(interp, pathPtr, + startAt); + } + break; } - break; } for (fsRecPtr=firstFsRecPtr; fsRecPtr!=NULL; fsRecPtr=fsRecPtr->nextPtr) { -- cgit v0.12 From 30938251a229de790732bbffff59a1de806d083d Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Sat, 18 Nov 2017 20:21:13 +0000 Subject: Adjust the rule to look for libtcl_XXX.zip ONLY in the directory that contains the executable or the install location for tcl. The directory adjacent copy is only looked for and mounted in an install location version cannot be located. --- generic/tclZipfs.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c index 4a72392..80d153b 100644 --- a/generic/tclZipfs.c +++ b/generic/tclZipfs.c @@ -3928,6 +3928,11 @@ int TclZipfs_AppHook(int *argc, char ***argv){ Tcl_FindExecutable(*argv[0]); archive=Tcl_GetNameOfExecutable(); TclZipfs_Init(NULL); + /* + ** Look for init.tcl in one of the locations mounted later in this function + ** and failing that, look for a file name CFG_RUNTIME_ZIPFILE adjacent to the + ** executable + */ TclSetPreInitScript( "foreach {path} {\n" " {" ZIPFS_APP_MOUNT "/tcl_library}\n" @@ -3937,6 +3942,17 @@ int TclZipfs_AppHook(int *argc, char ***argv){ " set ::tcl_library $path\n" " break\n" "}\n" +"if {![info exists ::tcl_library] || $::tcl_library eq {}} {\n" +" set zipfile [file join [file dirname [info nameofexecutable]] " CFG_RUNTIME_ZIPFILE "]\n" +" if {[file exists $zipfile]} {\n" +" zipfs mount $zipfile {" ZIPFS_ZIP_MOUNT "}\n" +" if {[file exists [file join {" ZIPFS_ZIP_MOUNT "} init.tcl]]} \{\n" +" set ::tcl_library {" ZIPFS_ZIP_MOUNT "}\n" +" } else {\n" +" zipfs unmount {" ZIPFS_ZIP_MOUNT "}\n" +" }\n" +" }\n" +"}\n" "foreach {path} {\n" " {" ZIPFS_APP_MOUNT "/tk_library}\n" " {" ZIPFS_ZIP_MOUNT "/tk_library}\n" @@ -3968,15 +3984,12 @@ int TclZipfs_AppHook(int *argc, char ***argv){ } } /* Mount zip file and dll before releasing to search */ - if(TclZipfs_AppHook_FindTclInit(CFG_RUNTIME_ZIPFILE)==TCL_OK) { + if(TclZipfs_AppHook_FindTclInit(CFG_RUNTIME_PATH "/" CFG_RUNTIME_DLLFILE)==TCL_OK) { return TCL_OK; } if(TclZipfs_AppHook_FindTclInit(CFG_RUNTIME_PATH "/" CFG_RUNTIME_ZIPFILE)==TCL_OK) { return TCL_OK; } - if(TclZipfs_AppHook_FindTclInit(CFG_RUNTIME_PATH "/" CFG_RUNTIME_DLLFILE)==TCL_OK) { - return TCL_OK; - } return TCL_OK; } -- cgit v0.12 From 1d444f56103f94c966ce2541224daf28a519421a Mon Sep 17 00:00:00 2001 From: tne Date: Sat, 18 Nov 2017 20:25:25 +0000 Subject: Now that UNC paths work correctly on Windows, removing the platform specific zipfs mount point for windows --- generic/tclZipfs.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c index 80d153b..af19224 100644 --- a/generic/tclZipfs.c +++ b/generic/tclZipfs.c @@ -32,17 +32,10 @@ ** On windows we need VFS to look like a volume ** On Unix we need it to look like a UNC path */ -#if defined(_WIN32) || defined(_WIN64) -#define ZIPFS_VOLUME "zipfs:/" -#define ZIPFS_VOLUME_LEN 7 -#define ZIPFS_APP_MOUNT "zipfs:/app" -#define ZIPFS_ZIP_MOUNT "zipfs:/lib/tcl" -#else #define ZIPFS_VOLUME "//zipfs:/" #define ZIPFS_VOLUME_LEN 9 #define ZIPFS_APP_MOUNT "//zipfs:/app" #define ZIPFS_ZIP_MOUNT "//zipfs:/lib/tcl" -#endif /* * Various constants and offsets found in ZIP archive files */ -- cgit v0.12 From 280b6aa62e68db8d71bc519af2d89d05c745cfcc Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Sun, 19 Nov 2017 18:16:43 +0000 Subject: Added handling to allow Tclsh to intercept a zip file fed as the first command line argument, and open it as a kit --- generic/tclZipfs.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c index af19224..689a648 100644 --- a/generic/tclZipfs.c +++ b/generic/tclZipfs.c @@ -3975,6 +3975,29 @@ int TclZipfs_AppHook(int *argc, char ***argv){ if(found==TCL_OK) { return TCL_OK; } + } else if (*argc>1) { + archive=(*argv)[1]; + fflush(stdout); + if(!TclZipfs_Mount(NULL, archive, ZIPFS_APP_MOUNT, NULL)) { + int found; + Tcl_Obj *vfsinitscript; + vfsinitscript=Tcl_NewStringObj(ZIPFS_APP_MOUNT "/main.tcl",-1); + Tcl_IncrRefCount(vfsinitscript); + if(Tcl_FSAccess(vfsinitscript,F_OK)==0) { + /* Startup script should be set before calling Tcl_AppInit */ + Tcl_SetStartupScript(vfsinitscript,NULL); + } else { + Tcl_DecrRefCount(vfsinitscript); + } + /* Set Tcl Encodings */ + vfsinitscript=Tcl_NewStringObj(ZIPFS_APP_MOUNT "/tcl_library/init.tcl",-1); + Tcl_IncrRefCount(vfsinitscript); + found=Tcl_FSAccess(vfsinitscript,F_OK); + Tcl_DecrRefCount(vfsinitscript); + if(found==TCL_OK) { + return TCL_OK; + } + } } /* Mount zip file and dll before releasing to search */ if(TclZipfs_AppHook_FindTclInit(CFG_RUNTIME_PATH "/" CFG_RUNTIME_DLLFILE)==TCL_OK) { -- cgit v0.12 From 4e97c16367e23bcde62e1b0910c32a7d06614518 Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Mon, 20 Nov 2017 17:09:44 +0000 Subject: Modifications to allow the Tcl build system to exploit either a native zip executable in the path or a tclsh that understands the new "install" keyword from the command line Added a new file to /library which is run when the user executes "tclsh install ..." Embedded in installer.tcl is a facility for building zip archives --- generic/tclZipfs.c | 39 ++++++----- library/install.tcl | 13 ++++ unix/Makefile.in | 6 +- unix/configure | 194 +++++++++++++++++++++------------------------------- unix/configure.ac | 75 ++++++++++---------- unix/tcl.m4 | 192 +++++++++++++++++++++++++++++---------------------- win/Makefile.in | 6 +- win/configure | 114 ++++++++++-------------------- win/configure.ac | 77 ++++++++++----------- win/tcl.m4 | 112 +++++++++++++++++++----------- 10 files changed, 408 insertions(+), 420 deletions(-) create mode 100644 library/install.tcl diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c index 689a648..8c852b2 100644 --- a/generic/tclZipfs.c +++ b/generic/tclZipfs.c @@ -3977,25 +3977,32 @@ int TclZipfs_AppHook(int *argc, char ***argv){ } } else if (*argc>1) { archive=(*argv)[1]; - fflush(stdout); - if(!TclZipfs_Mount(NULL, archive, ZIPFS_APP_MOUNT, NULL)) { - int found; + if(strcmp(archive,"install")==0) { + /* If the first argument is mkzip, run the mkzip program */ Tcl_Obj *vfsinitscript; - vfsinitscript=Tcl_NewStringObj(ZIPFS_APP_MOUNT "/main.tcl",-1); + vfsinitscript=Tcl_NewStringObj(ZIPFS_ZIP_MOUNT "/tcl_library/install.tcl",-1); Tcl_IncrRefCount(vfsinitscript); - if(Tcl_FSAccess(vfsinitscript,F_OK)==0) { - /* Startup script should be set before calling Tcl_AppInit */ - Tcl_SetStartupScript(vfsinitscript,NULL); - } else { + Tcl_SetStartupScript(vfsinitscript,NULL); + } else { + if(!TclZipfs_Mount(NULL, archive, ZIPFS_APP_MOUNT, NULL)) { + int found; + Tcl_Obj *vfsinitscript; + vfsinitscript=Tcl_NewStringObj(ZIPFS_APP_MOUNT "/main.tcl",-1); + Tcl_IncrRefCount(vfsinitscript); + if(Tcl_FSAccess(vfsinitscript,F_OK)==0) { + /* Startup script should be set before calling Tcl_AppInit */ + Tcl_SetStartupScript(vfsinitscript,NULL); + } else { + Tcl_DecrRefCount(vfsinitscript); + } + /* Set Tcl Encodings */ + vfsinitscript=Tcl_NewStringObj(ZIPFS_APP_MOUNT "/tcl_library/init.tcl",-1); + Tcl_IncrRefCount(vfsinitscript); + found=Tcl_FSAccess(vfsinitscript,F_OK); Tcl_DecrRefCount(vfsinitscript); - } - /* Set Tcl Encodings */ - vfsinitscript=Tcl_NewStringObj(ZIPFS_APP_MOUNT "/tcl_library/init.tcl",-1); - Tcl_IncrRefCount(vfsinitscript); - found=Tcl_FSAccess(vfsinitscript,F_OK); - Tcl_DecrRefCount(vfsinitscript); - if(found==TCL_OK) { - return TCL_OK; + if(found==TCL_OK) { + return TCL_OK; + } } } } diff --git a/library/install.tcl b/library/install.tcl new file mode 100644 index 0000000..f126b37 --- /dev/null +++ b/library/install.tcl @@ -0,0 +1,13 @@ +### +# Installer actions built into tclsh and invoked +# if the first command line argument is "install" +### +if {[llength $argv] < 2} { + exit 0 +} +switch [lindex $argv 1] { + mkzip { + zipfs mkzip {*}[lrange $argv 2 end] + } +} +exit 0 diff --git a/unix/Makefile.in b/unix/Makefile.in index 4540710..98c5865 100644 --- a/unix/Makefile.in +++ b/unix/Makefile.in @@ -632,6 +632,8 @@ HOST_EXEEXT = @EXEEXT_FOR_BUILD@ HOST_OBJEXT = @OBJEXT_FOR_BUILD@ ZIPFS_BUILD = @ZIPFS_BUILD@ NATIVE_ZIP = @ZIP_PROG@ +ZIP_PROG_OPTIONS = @ZIP_PROG_OPTIONS@ +ZIP_PROG_VFSSEARCH = @ZIP_PROG_VFSSEARCH@ SHARED_BUILD = @SHARED_BUILD@ INSTALL_LIBRARIES = @INSTALL_LIBRARIES@ INSTALL_MSGS = @INSTALL_MSGS@ @@ -653,7 +655,7 @@ MINIZIP_OBJS = \ zutil.$(HOST_OBJEXT) \ minizip.$(HOST_OBJEXT) -ZIP_INSTALL_OBJS = minizip${EXEEXT_FOR_BUILD} +ZIP_INSTALL_OBJS = @ZIP_INSTALL_OBJS@ #-------------------------------------------------------------------------- # Start of rules @@ -674,7 +676,7 @@ ${TCL_ZIP_FILE}: ${ZIP_INSTALL_OBJS} rm -rf ${TCL_VFS_ROOT} mkdir -p ${TCL_VFS_PATH} cp -a ../library/* ${TCL_VFS_PATH} - cd ${TCL_VFS_ROOT} ; ../minizip${EXEEXT_FOR_BUILD} -o ../${TCL_ZIP_FILE} `find . -type f` + cd ${TCL_VFS_ROOT} ; ${NATIVE_ZIP} ${ZIP_PROG_OPTIONS} ../${TCL_ZIP_FILE} ${ZIP_PROG_VFSSEARCH} # The following target is configured by autoconf to generate either a shared # library or non-shared library for Tcl. diff --git a/unix/configure b/unix/configure index dd6bf6b..1c3a206 100755 --- a/unix/configure +++ b/unix/configure @@ -658,7 +658,6 @@ TCL_STUB_LIB_FILE TCL_LIB_SPEC TCL_LIB_FLAG TCL_LIB_FILE -TCL_ZIP_FILE PKG_CFG_ARGS TCL_YEAR TCL_PATCH_LEVEL @@ -667,10 +666,10 @@ TCL_MAJOR_VERSION TCL_VERSION INSTALL_MSGS INSTALL_LIBRARIES +TCL_ZIP_FILE ZIPFS_BUILD EXEEXT_FOR_BUILD CC_FOR_BUILD -ZIP_PROG DTRACE LDFLAGS_DEFAULT CFLAGS_DEFAULT @@ -2341,7 +2340,6 @@ VERSION=${TCL_VERSION} EXTRA_INSTALL_BINARIES=${EXTRA_INSTALL_BINARIES:-"@:"} EXTRA_BUILD_HTML=${EXTRA_BUILD_HTML:-"@:"} -TCL_ZIP_FILE=libtcl_${TCL_MAJOR_VERSION}_${TCL_MINOR_VERSION}_${TCL_PATCH_LEVEL}.zip #------------------------------------------------------------------------ # Setup configure arguments for bundled packages @@ -10155,153 +10153,115 @@ fi $as_echo "$tcl_ok" >&6; } #-------------------------------------------------------------------- -# Zipfs support +# Zipfs support - Tip 430 #-------------------------------------------------------------------- - -# -# Find a native zip implementation -# - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for zip" >&5 -$as_echo_n "checking for zip... " >&6; } - if ${ac_cv_path_zip+:} false; then : - $as_echo_n "(cached) " >&6 +# Check whether --enable-zipfs was given. +if test "${enable_zipfs+set}" = set; then : + enableval=$enable_zipfs; tcl_ok=$enableval else - - search_path=`echo ${PATH} | sed -e 's/:/ /g'` - for dir in $search_path ; do - for j in `ls -r $dir/zip 2> /dev/null` \ - `ls -r $dir/zip 2> /dev/null` ; do - if test x"$ac_cv_path_zip" = x ; then - if test -f "$j" ; then - ac_cv_path_zip=$j - break - fi - fi - done - done - + tcl_ok=yes fi - - if test -f "$ac_cv_path_zip" ; then - ZIP_PROG="$ac_cv_path_zip" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ZIP_PROG" >&5 -$as_echo "$ZIP_PROG" >&6; } - else - # It is not an error if an installed version of Zip can't be located. - ZIP_PROG="" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: No zip found on PATH" >&5 -$as_echo "No zip found on PATH" >&6; } - fi - - - -# -# Find a native compiler -# -# Put a plausible default for CC_FOR_BUILD in Makefile. -if test -z "$CC_FOR_BUILD"; then - if test "x$cross_compiling" = "xno"; then - CC_FOR_BUILD='$(CC)' - else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gcc" >&5 +if test "$tcl_ok" = "yes" ; then + # + # Find a native compiler + # + # Put a plausible default for CC_FOR_BUILD in Makefile. + if test -z "$CC_FOR_BUILD"; then + if test "x$cross_compiling" = "xno"; then + CC_FOR_BUILD='$(CC)' + else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gcc" >&5 $as_echo_n "checking for gcc... " >&6; } - if ${ac_cv_path_cc+:} false; then : + if ${ac_cv_path_cc+:} false; then : $as_echo_n "(cached) " >&6 else - search_path=`echo ${PATH} | sed -e 's/:/ /g'` - for dir in $search_path ; do - for j in `ls -r $dir/gcc 2> /dev/null` \ - `ls -r $dir/gcc 2> /dev/null` ; do - if test x"$ac_cv_path_cc" = x ; then - if test -f "$j" ; then - ac_cv_path_cc=$j - break - fi - fi - done - done + search_path=`echo ${PATH} | sed -e 's/:/ /g'` + for dir in $search_path ; do + for j in `ls -r $dir/gcc 2> /dev/null` \ + `ls -r $dir/gcc 2> /dev/null` ; do + if test x"$ac_cv_path_cc" = x ; then + if test -f "$j" ; then + ac_cv_path_cc=$j + break + fi + fi + done + done fi - fi -fi + fi + fi -# Also set EXEEXT_FOR_BUILD. -if test "x$cross_compiling" = "xno"; then - EXEEXT_FOR_BUILD='$(EXEEXT)' - OBJEXT_FOR_BUILD='$(OBJEXT)' -else - OBJEXT_FOR_BUILD='.no' - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for build system executable suffix" >&5 + # Also set EXEEXT_FOR_BUILD. + if test "x$cross_compiling" = "xno"; then + EXEEXT_FOR_BUILD='$(EXEEXT)' + OBJEXT_FOR_BUILD='$(OBJEXT)' + else + OBJEXT_FOR_BUILD='.no' + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for build system executable suffix" >&5 $as_echo_n "checking for build system executable suffix... " >&6; } if ${bfd_cv_build_exeext+:} false; then : $as_echo_n "(cached) " >&6 else rm -f conftest* - echo 'int main () { return 0; }' > conftest.c - bfd_cv_build_exeext= - ${CC_FOR_BUILD} -o conftest conftest.c 1>&5 2>&5 - for file in conftest.*; do - case $file in - *.c | *.o | *.obj | *.ilk | *.pdb) ;; - *) bfd_cv_build_exeext=`echo $file | sed -e s/conftest//` ;; - esac - done - rm -f conftest* - test x"${bfd_cv_build_exeext}" = x && bfd_cv_build_exeext=no + echo 'int main () { return 0; }' > conftest.c + bfd_cv_build_exeext= + ${CC_FOR_BUILD} -o conftest conftest.c 1>&5 2>&5 + for file in conftest.*; do + case $file in + *.c | *.o | *.obj | *.ilk | *.pdb) ;; + *) bfd_cv_build_exeext=`echo $file | sed -e s/conftest//` ;; + esac + done + rm -f conftest* + test x"${bfd_cv_build_exeext}" = x && bfd_cv_build_exeext=no fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $bfd_cv_build_exeext" >&5 $as_echo "$bfd_cv_build_exeext" >&6; } - EXEEXT_FOR_BUILD="" - test x"${bfd_cv_build_exeext}" != xno && EXEEXT_FOR_BUILD=${bfd_cv_build_exeext} -fi - - -if test "$ZIP_PROG" = ""; then - ZIP_PROG='./minizip${EXEEXT_FOR_BUILD}' -fi - -# Check whether --enable-zipfs was given. -if test "${enable_zipfs+set}" = set; then : - enableval=$enable_zipfs; tcl_ok=$enableval -else - tcl_ok=yes -fi + EXEEXT_FOR_BUILD="" + test x"${bfd_cv_build_exeext}" != xno && EXEEXT_FOR_BUILD=${bfd_cv_build_exeext} + fi - if test "$tcl_ok" = "yes" -o "${TCL_THREADS}" = 1; then + # + # Find a native zip implementation + # + SC_PROG_ZIP ZIPFS_BUILD=1 - else + TCL_ZIP_FILE=libtcl_${TCL_MAJOR_VERSION}_${TCL_MINOR_VERSION}_${TCL_PATCH_LEVEL}.zip +else ZIPFS_BUILD=0 - fi - # Do checking message here to not mess up interleaved configure output - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for building with zipfs" >&5 + TCL_ZIP_FILE= +fi +# Do checking message here to not mess up interleaved configure output +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for building with zipfs" >&5 $as_echo_n "checking for building with zipfs... " >&6; } - if test "${ZIPFS_BUILD}" = 1; then - if test "${SHARED_BUILD}" = 0; then - ZIPFS_BUILD=2; +if test "${ZIPFS_BUILD}" = 1; then + if test "${SHARED_BUILD}" = 0; then + ZIPFS_BUILD=2; $as_echo "#define ZIPFS_BUILD 2" >>confdefs.h - INSTALL_LIBRARIES=install-libraries-zipfs-static - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + INSTALL_LIBRARIES=install-libraries-zipfs-static + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } - else + else $as_echo "#define ZIPFS_BUILD 1" >>confdefs.h \ - INSTALL_LIBRARIES=install-libraries-zipfs-shared - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + INSTALL_LIBRARIES=install-libraries-zipfs-shared + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } - fi - else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - INSTALL_LIBRARIES=install-libraries - INSTALL_MSGS=install-msgs fi +else +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +INSTALL_LIBRARIES=install-libraries +INSTALL_MSGS=install-msgs +fi + diff --git a/unix/configure.ac b/unix/configure.ac index ed85184..0928fc8 100644 --- a/unix/configure.ac +++ b/unix/configure.ac @@ -30,7 +30,6 @@ VERSION=${TCL_VERSION} EXTRA_INSTALL_BINARIES=${EXTRA_INSTALL_BINARIES:-"@:"} EXTRA_BUILD_HTML=${EXTRA_BUILD_HTML:-"@:"} -TCL_ZIP_FILE=libtcl_${TCL_MAJOR_VERSION}_${TCL_MINOR_VERSION}_${TCL_PATCH_LEVEL}.zip #------------------------------------------------------------------------ # Setup configure arguments for bundled packages @@ -793,53 +792,49 @@ fi AC_MSG_RESULT([$tcl_ok]) #-------------------------------------------------------------------- -# Zipfs support +# Zipfs support - Tip 430 #-------------------------------------------------------------------- - -# -# Find a native zip implementation -# -SC_PROG_ZIP - -# -# Find a native compiler -# -AX_CC_FOR_BUILD - -if test "$ZIP_PROG" = ""; then - ZIP_PROG='./minizip${EXEEXT_FOR_BUILD}' -fi - AC_ARG_ENABLE(zipfs, AC_HELP_STRING([--enable-zipfs], [build with Zipfs support (default: on)]), [tcl_ok=$enableval], [tcl_ok=yes]) - if test "$tcl_ok" = "yes" -o "${TCL_THREADS}" = 1; then +if test "$tcl_ok" = "yes" ; then + # + # Find a native compiler + # + AX_CC_FOR_BUILD + # + # Find a native zip implementation + # + SC_PROG_ZIP ZIPFS_BUILD=1 - else + TCL_ZIP_FILE=libtcl_${TCL_MAJOR_VERSION}_${TCL_MINOR_VERSION}_${TCL_PATCH_LEVEL}.zip +else ZIPFS_BUILD=0 + TCL_ZIP_FILE= +fi +# Do checking message here to not mess up interleaved configure output +AC_MSG_CHECKING([for building with zipfs]) +if test "${ZIPFS_BUILD}" = 1; then + if test "${SHARED_BUILD}" = 0; then + ZIPFS_BUILD=2; + AC_DEFINE(ZIPFS_BUILD, 2, [Are we building with zipfs enabled?]) + INSTALL_LIBRARIES=install-libraries-zipfs-static + AC_MSG_RESULT([yes]) + else + AC_DEFINE(ZIPFS_BUILD, 1, [Are we building with zipfs enabled?])\ + INSTALL_LIBRARIES=install-libraries-zipfs-shared + AC_MSG_RESULT([yes]) fi - # Do checking message here to not mess up interleaved configure output - AC_MSG_CHECKING([for building with zipfs]) - if test "${ZIPFS_BUILD}" = 1; then - if test "${SHARED_BUILD}" = 0; then - ZIPFS_BUILD=2; - AC_DEFINE(ZIPFS_BUILD, 2, [Are we building with zipfs enabled?]) - INSTALL_LIBRARIES=install-libraries-zipfs-static - AC_MSG_RESULT([yes]) - else - AC_DEFINE(ZIPFS_BUILD, 1, [Are we building with zipfs enabled?])\ - INSTALL_LIBRARIES=install-libraries-zipfs-shared - AC_MSG_RESULT([yes]) - fi - else - AC_MSG_RESULT([no]) - INSTALL_LIBRARIES=install-libraries - INSTALL_MSGS=install-msgs - fi - AC_SUBST(ZIPFS_BUILD) - AC_SUBST(INSTALL_LIBRARIES) - AC_SUBST(INSTALL_MSGS) +else +AC_MSG_RESULT([no]) +INSTALL_LIBRARIES=install-libraries +INSTALL_MSGS=install-msgs +fi +AC_SUBST(ZIPFS_BUILD) +AC_SUBST(TCL_ZIP_FILE) +AC_SUBST(INSTALL_LIBRARIES) +AC_SUBST(INSTALL_MSGS) #-------------------------------------------------------------------- diff --git a/unix/tcl.m4 b/unix/tcl.m4 index 1806207..9cfb746 100644 --- a/unix/tcl.m4 +++ b/unix/tcl.m4 @@ -276,7 +276,6 @@ AC_DEFUN([SC_PATH_TKCONFIG], [ # TCL_BIN_DIR # TCL_SRC_DIR # TCL_LIB_FILE -# TCL_ZIP_FILE #------------------------------------------------------------------------ AC_DEFUN([SC_LOAD_TCLCONFIG], [ @@ -290,7 +289,6 @@ AC_DEFUN([SC_LOAD_TCLCONFIG], [ fi # eval is required to do the TCL_DBGX substitution - eval "TCL_ZIP_FILE=\"${TCL_ZIP_FILE}\"" eval "TCL_LIB_FILE=\"${TCL_LIB_FILE}\"" eval "TCL_STUB_LIB_FILE=\"${TCL_STUB_LIB_FILE}\"" @@ -338,7 +336,6 @@ AC_DEFUN([SC_LOAD_TCLCONFIG], [ AC_SUBST(TCL_BIN_DIR) AC_SUBST(TCL_SRC_DIR) - AC_SUBST(TCL_ZIP_FILE) AC_SUBST(TCL_LIB_FILE) AC_SUBST(TCL_LIB_FLAG) AC_SUBST(TCL_LIB_SPEC) @@ -3019,107 +3016,138 @@ fi ]) #------------------------------------------------------------------------ -# SC_PROG_ZIP -# Locate a zip encoder installed on the system path, or none. +# SC_CC_FOR_BUILD +# For cross compiles, locate a C compiler that can generate native binaries. # # Arguments: # none # # Results: # Substitutes the following vars: -# ZIP_PROG +# CC_FOR_BUILD +# EXEEXT_FOR_BUILD #------------------------------------------------------------------------ -AC_DEFUN([SC_PROG_ZIP], [ - AC_MSG_CHECKING([for zip]) - AC_CACHE_VAL(ac_cv_path_zip, [ - search_path=`echo ${PATH} | sed -e 's/:/ /g'` - for dir in $search_path ; do - for j in `ls -r $dir/zip 2> /dev/null` \ - `ls -r $dir/zip 2> /dev/null` ; do - if test x"$ac_cv_path_zip" = x ; then - if test -f "$j" ; then - ac_cv_path_zip=$j - break - fi - fi - done - done - ]) - - if test -f "$ac_cv_path_zip" ; then - ZIP_PROG="$ac_cv_path_zip" - AC_MSG_RESULT([$ZIP_PROG]) +dnl Get a default for CC_FOR_BUILD to put into Makefile. +AC_DEFUN([AX_CC_FOR_BUILD],[# Put a plausible default for CC_FOR_BUILD in Makefile. + if test -z "$CC_FOR_BUILD"; then + if test "x$cross_compiling" = "xno"; then + CC_FOR_BUILD='$(CC)' + else + AC_MSG_CHECKING([for gcc]) + AC_CACHE_VAL(ac_cv_path_cc, [ + search_path=`echo ${PATH} | sed -e 's/:/ /g'` + for dir in $search_path ; do + for j in `ls -r $dir/gcc 2> /dev/null` \ + `ls -r $dir/gcc 2> /dev/null` ; do + if test x"$ac_cv_path_cc" = x ; then + if test -f "$j" ; then + ac_cv_path_cc=$j + break + fi + fi + done + done + ]) + fi + fi + AC_SUBST(CC_FOR_BUILD) + # Also set EXEEXT_FOR_BUILD. + if test "x$cross_compiling" = "xno"; then + EXEEXT_FOR_BUILD='$(EXEEXT)' + OBJEXT_FOR_BUILD='$(OBJEXT)' else - # It is not an error if an installed version of Zip can't be located. - ZIP_PROG="" - AC_MSG_RESULT([No zip found on PATH]) + OBJEXT_FOR_BUILD='.no' + AC_CACHE_CHECK([for build system executable suffix], bfd_cv_build_exeext, + [rm -f conftest* + echo 'int main () { return 0; }' > conftest.c + bfd_cv_build_exeext= + ${CC_FOR_BUILD} -o conftest conftest.c 1>&5 2>&5 + for file in conftest.*; do + case $file in + *.c | *.o | *.obj | *.ilk | *.pdb) ;; + *) bfd_cv_build_exeext=`echo $file | sed -e s/conftest//` ;; + esac + done + rm -f conftest* + test x"${bfd_cv_build_exeext}" = x && bfd_cv_build_exeext=no]) + EXEEXT_FOR_BUILD="" + test x"${bfd_cv_build_exeext}" != xno && EXEEXT_FOR_BUILD=${bfd_cv_build_exeext} fi - AC_SUBST(ZIP_PROG) + AC_SUBST(EXEEXT_FOR_BUILD)])dnl + AC_SUBST(OBJEXT_FOR_BUILD)])dnl ]) + #------------------------------------------------------------------------ -# SC_CC_FOR_BUILD -# For cross compiles, locate a C compiler that can generate native binaries. +# SC_ZIPFS_SUPPORT +# Locate a zip encoder installed on the system path, or none. # # Arguments: # none # # Results: # Substitutes the following vars: -# CC_FOR_BUILD -# EXEEXT_FOR_BUILD +# ZIP_PROG +# ZIP_PROG_OPTIONS +# ZIP_PROG_VFSSEARCH +# ZIP_INSTALL_OBJS #------------------------------------------------------------------------ -dnl Get a default for CC_FOR_BUILD to put into Makefile. -AC_DEFUN([AX_CC_FOR_BUILD], -[# Put a plausible default for CC_FOR_BUILD in Makefile. -if test -z "$CC_FOR_BUILD"; then - if test "x$cross_compiling" = "xno"; then - CC_FOR_BUILD='$(CC)' - else - AC_MSG_CHECKING([for gcc]) - AC_CACHE_VAL(ac_cv_path_cc, [ - search_path=`echo ${PATH} | sed -e 's/:/ /g'` - for dir in $search_path ; do - for j in `ls -r $dir/gcc 2> /dev/null` \ - `ls -r $dir/gcc 2> /dev/null` ; do - if test x"$ac_cv_path_cc" = x ; then - if test -f "$j" ; then - ac_cv_path_cc=$j - break - fi - fi - done - done +AC_DEFUN([SC_ZIPFS_SUPPORT], [ + ZIP_PROG="" + ZIP_PROG_OPTIONS="" + ZIP_PROG_VFSSEARCH="" + ZIP_INSTALL_OBJS="" + AC_MSG_CHECKING([for zip]) + # If our native tclsh processes the "install" command line option + # we can use it to mint zip files + AS_IF([$TCLSH_PROG install],[ + ZIP_PROG=${TCLSH_PROG} + ZIP_PROG_OPTIONS="install mkzip" + ZIP_PROG_VFSSEARCH="." + AC_MSG_RESULT([Can use Native Tclsh for Zip encoding]) ]) - fi -fi -AC_SUBST(CC_FOR_BUILD) -# Also set EXEEXT_FOR_BUILD. -if test "x$cross_compiling" = "xno"; then - EXEEXT_FOR_BUILD='$(EXEEXT)' - OBJEXT_FOR_BUILD='$(OBJEXT)' -else - OBJEXT_FOR_BUILD='.no' - AC_CACHE_CHECK([for build system executable suffix], bfd_cv_build_exeext, - [rm -f conftest* - echo 'int main () { return 0; }' > conftest.c - bfd_cv_build_exeext= - ${CC_FOR_BUILD} -o conftest conftest.c 1>&5 2>&5 - for file in conftest.*; do - case $file in - *.c | *.o | *.obj | *.ilk | *.pdb) ;; - *) bfd_cv_build_exeext=`echo $file | sed -e s/conftest//` ;; - esac - done - rm -f conftest* - test x"${bfd_cv_build_exeext}" = x && bfd_cv_build_exeext=no]) - EXEEXT_FOR_BUILD="" - test x"${bfd_cv_build_exeext}" != xno && EXEEXT_FOR_BUILD=${bfd_cv_build_exeext} -fi -AC_SUBST(EXEEXT_FOR_BUILD)])dnl -AC_SUBST(OBJEXT_FOR_BUILD)])dnl + + if test "x$ZIP_PROG" = "x" ; then + AC_MSG_CHECKING([for zip]) + AC_CACHE_VAL(ac_cv_path_zip, [ + search_path=`echo ${PATH} | sed -e 's/:/ /g'` + for dir in $search_path ; do + for j in `ls -r $dir/zip 2> /dev/null` \ + `ls -r $dir/zip 2> /dev/null` ; do + if test x"$ac_cv_path_zip" = x ; then + if test -f "$j" ; then + ac_cv_path_zip=$j + break + fi + fi + done + done + ]) + if test -f "$ac_cv_path_zip" ; then + ZIP_PROG="$ac_cv_path_zip " + AC_MSG_RESULT([$ZIP_PROG]) + ZIP_PROG_OPTIONS="-rq" + ZIP_PROG_VFSSEARCH="." + AC_MSG_RESULT([Found INFO Zip in environment]) + # Use standard arguments for zip + else + # It is not an error if an installed version of Zip can't be located. + # We can use the locally distributed minizip instead + ZIP_PROG="../minizip${EXEEXT_FOR_BUILD}" + ZIP_PROG_OPTIONS="\"-o\"" + ZIP_PROG_VFSSEARCH="\`find . -type f\'" + ZIP_INSTALL_OBJS="minizip${EXEEXT_FOR_BUILD}" + AC_MSG_RESULT([No zip found on PATH building minizip]) + fi + fi + AC_SUBST(ZIP_PROG) + AC_SUBST(ZIP_PROG_OPTIONS) + AC_SUBST(ZIP_PROG_VFSSEARCH) + AC_SUBST(ZIP_INSTALL_OBJS) +]) + # Local Variables: # mode: autoconf # End: diff --git a/win/Makefile.in b/win/Makefile.in index 214cf7b..7f4fc70 100644 --- a/win/Makefile.in +++ b/win/Makefile.in @@ -214,6 +214,8 @@ HOST_EXEEXT = @EXEEXT_FOR_BUILD@ HOST_OBJEXT = @OBJEXT_FOR_BUILD@ ZIPFS_BUILD = @ZIPFS_BUILD@ NATIVE_ZIP = @ZIP_PROG@ +ZIP_PROG_OPTIONS = @ZIP_PROG_OPTIONS@ +ZIP_PROG_VFSSEARCH = @ZIP_PROG_VFSSEARCH@ SHARED_BUILD = @SHARED_BUILD@ INSTALL_MSGS = @INSTALL_MSGS@ INSTALL_LIBRARIES = @INSTALL_LIBRARIES@ @@ -236,7 +238,7 @@ MINIZIP_OBJS = \ zutil.$(HOST_OBJEXT) \ minizip.$(HOST_OBJEXT) -ZIP_INSTALL_OBJS = minizip${EXEEXT_FOR_BUILD} +ZIP_INSTALL_OBJS = @ZIP_INSTALL_OBJS@ CC_SWITCHES = ${CFLAGS} ${CFLAGS_WARNING} ${TCL_SHLIB_CFLAGS} \ -I"${ZLIB_DIR_NATIVE}" -I"${GENERIC_DIR_NATIVE}" \ @@ -482,7 +484,7 @@ ${TCL_ZIP_FILE}: ${ZIP_INSTALL_OBJS} rm -rf ${TCL_VFS_ROOT} mkdir -p ${TCL_VFS_PATH} cp -a ../library/* ${TCL_VFS_PATH} - cd ${TCL_VFS_ROOT} ; ../minizip${EXEEXT_FOR_BUILD} -o ../${TCL_ZIP_FILE} `find . -type f` + cd ${TCL_VFS_ROOT} ; ${NATIVE_ZIP} ${ZIP_PROG_OPTIONS} ../${TCL_ZIP_FILE} ${ZIP_PROG_VFSSEARCH} $(TCLSH): $(TCLSH_OBJS) @LIBRARIES@ $(TCL_STUB_LIB_FILE) tclsh.$(RES) $(CC) $(CFLAGS) $(TCLSH_OBJS) $(TCL_LIB_FILE) $(TCL_STUB_LIB_FILE) $(LIBS) \ diff --git a/win/configure b/win/configure index f65b78a..c99d499 100755 --- a/win/configure +++ b/win/configure @@ -687,7 +687,6 @@ TCL_STATIC_LIB_FLAG TCL_STATIC_LIB_FILE TCL_LIB_FLAG TCL_LIB_FILE -TCL_ZIP_FILE TCL_EXE PKG_CFG_ARGS TCL_PATCH_LEVEL @@ -702,10 +701,10 @@ LDFLAGS_DEFAULT CFLAGS_DEFAULT INSTALL_MSGS INSTALL_LIBRARIES +TCL_ZIP_FILE ZIPFS_BUILD EXEEXT_FOR_BUILD CC_FOR_BUILD -ZIP_PROG ZLIB_OBJS ZLIB_LIBS ZLIB_DLL_FILE @@ -2128,8 +2127,6 @@ REGVER=$TCL_REG_MAJOR_VERSION$TCL_REG_MINOR_VERSION PKG_CFG_ARGS=$@ -TCL_ZIP_FILE=libtcl_${TCL_MAJOR_VERSION}_${TCL_MINOR_VERSION}_${TCL_PATCH_LEVEL}.zip - #------------------------------------------------------------------------ # Empty slate for bundled packages, to avoid stale configuration #------------------------------------------------------------------------ @@ -4844,52 +4841,20 @@ fi #-------------------------------------------------------------------- -# Zipfs support +# Zipfs support - Tip 430 #-------------------------------------------------------------------- - -# -# Find a native zip implementation -# - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for zip" >&5 -$as_echo_n "checking for zip... " >&6; } - if ${ac_cv_path_zip+:} false; then : - $as_echo_n "(cached) " >&6 +# Check whether --enable-zipfs was given. +if test "${enable_zipfs+set}" = set; then : + enableval=$enable_zipfs; tcl_ok=$enableval else - - search_path=`echo ${PATH} | sed -e 's/:/ /g'` - for dir in $search_path ; do - for j in `ls -r $dir/zip 2> /dev/null` \ - `ls -r $dir/zip 2> /dev/null` ; do - if test x"$ac_cv_path_zip" = x ; then - if test -f "$j" ; then - ac_cv_path_zip=$j - break - fi - fi - done - done - + tcl_ok=yes fi - - if test -f "$ac_cv_path_zip" ; then - ZIP_PROG="$ac_cv_path_zip" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ZIP_PROG" >&5 -$as_echo "$ZIP_PROG" >&6; } - else - # It is not an error if an installed version of Zip can't be located. - ZIP_PROG="" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: No zip found on PATH" >&5 -$as_echo "No zip found on PATH" >&6; } - fi - - - -# -# Find a native compiler -# -# Put a plausible default for CC_FOR_BUILD in Makefile. +if test "$tcl_ok" = "yes" ; then + # + # Find a native compiler + # + # Put a plausible default for CC_FOR_BUILD in Makefile. if test -z "$CC_FOR_BUILD"; then if test "x$cross_compiling" = "xno"; then CC_FOR_BUILD='$(CC)' @@ -4948,49 +4913,43 @@ $as_echo "$bfd_cv_build_exeext" >&6; } test x"${bfd_cv_build_exeext}" != xno && EXEEXT_FOR_BUILD=${bfd_cv_build_exeext} fi - -if test "$ZIP_PROG" = ""; then - ZIP_PROG='./minizip${EXEEXT_FOR_BUILD}' -fi - -# Check whether --enable-zipfs was given. -if test "${enable_zipfs+set}" = set; then : - enableval=$enable_zipfs; tcl_ok=$enableval -else - tcl_ok=yes -fi - - if test "$tcl_ok" = "yes" -o "${TCL_THREADS}" = 1; then + # + # Find a native zip implementation + # + SC_PROG_ZIP ZIPFS_BUILD=1 - else + TCL_ZIP_FILE=libtcl_${TCL_MAJOR_VERSION}_${TCL_MINOR_VERSION}_${TCL_PATCH_LEVEL}.zip +else ZIPFS_BUILD=0 - fi - # Do checking message here to not mess up interleaved configure output - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for building with zipfs" >&5 + TCL_ZIP_FILE= +fi +# Do checking message here to not mess up interleaved configure output +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for building with zipfs" >&5 $as_echo_n "checking for building with zipfs... " >&6; } - if test "${ZIPFS_BUILD}" = 1; then - if test "${SHARED_BUILD}" = 0; then - ZIPFS_BUILD=2; +if test "${ZIPFS_BUILD}" = 1; then + if test "${SHARED_BUILD}" = 0; then + ZIPFS_BUILD=2; $as_echo "#define ZIPFS_BUILD 2" >>confdefs.h - INSTALL_LIBRARIES=install-libraries-zipfs-static - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + INSTALL_LIBRARIES=install-libraries-zipfs-static + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } - else + else $as_echo "#define ZIPFS_BUILD 1" >>confdefs.h \ - INSTALL_LIBRARIES=install-libraries-zipfs-shared - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + INSTALL_LIBRARIES=install-libraries-zipfs-shared + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } - fi - else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - INSTALL_LIBRARIES=install-libraries - INSTALL_MSGS=install-msgs fi +else +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +INSTALL_LIBRARIES=install-libraries +INSTALL_MSGS=install-msgs +fi + @@ -5388,7 +5347,6 @@ TCL_WIN_VERSION="$TCL_VERSION.$TCL_RELEASE_LEVEL.`echo $TCL_PATCH_LEVEL | tr -d - # empty on win diff --git a/win/configure.ac b/win/configure.ac index cf66fc2..b1f3a52 100644 --- a/win/configure.ac +++ b/win/configure.ac @@ -29,8 +29,6 @@ REGVER=$TCL_REG_MAJOR_VERSION$TCL_REG_MINOR_VERSION PKG_CFG_ARGS=$@ -TCL_ZIP_FILE=libtcl_${TCL_MAJOR_VERSION}_${TCL_MINOR_VERSION}_${TCL_PATCH_LEVEL}.zip - #------------------------------------------------------------------------ # Empty slate for bundled packages, to avoid stale configuration #------------------------------------------------------------------------ @@ -178,53 +176,49 @@ AC_CHECK_TYPE([uintptr_t], [ #-------------------------------------------------------------------- -# Zipfs support +# Zipfs support - Tip 430 #-------------------------------------------------------------------- - -# -# Find a native zip implementation -# -SC_PROG_ZIP - -# -# Find a native compiler -# -AX_CC_FOR_BUILD - -if test "$ZIP_PROG" = ""; then - ZIP_PROG='./minizip${EXEEXT_FOR_BUILD}' -fi - AC_ARG_ENABLE(zipfs, AC_HELP_STRING([--enable-zipfs], [build with Zipfs support (default: on)]), [tcl_ok=$enableval], [tcl_ok=yes]) - if test "$tcl_ok" = "yes" -o "${TCL_THREADS}" = 1; then +if test "$tcl_ok" = "yes" ; then + # + # Find a native compiler + # + AX_CC_FOR_BUILD + # + # Find a native zip implementation + # + SC_PROG_ZIP ZIPFS_BUILD=1 - else + TCL_ZIP_FILE=libtcl_${TCL_MAJOR_VERSION}_${TCL_MINOR_VERSION}_${TCL_PATCH_LEVEL}.zip +else ZIPFS_BUILD=0 + TCL_ZIP_FILE= +fi +# Do checking message here to not mess up interleaved configure output +AC_MSG_CHECKING([for building with zipfs]) +if test "${ZIPFS_BUILD}" = 1; then + if test "${SHARED_BUILD}" = 0; then + ZIPFS_BUILD=2; + AC_DEFINE(ZIPFS_BUILD, 2, [Are we building with zipfs enabled?]) + INSTALL_LIBRARIES=install-libraries-zipfs-static + AC_MSG_RESULT([yes]) + else + AC_DEFINE(ZIPFS_BUILD, 1, [Are we building with zipfs enabled?])\ + INSTALL_LIBRARIES=install-libraries-zipfs-shared + AC_MSG_RESULT([yes]) fi - # Do checking message here to not mess up interleaved configure output - AC_MSG_CHECKING([for building with zipfs]) - if test "${ZIPFS_BUILD}" = 1; then - if test "${SHARED_BUILD}" = 0; then - ZIPFS_BUILD=2; - AC_DEFINE(ZIPFS_BUILD, 2, [Are we building with zipfs enabled?]) - INSTALL_LIBRARIES=install-libraries-zipfs-static - AC_MSG_RESULT([yes]) - else - AC_DEFINE(ZIPFS_BUILD, 1, [Are we building with zipfs enabled?])\ - INSTALL_LIBRARIES=install-libraries-zipfs-shared - AC_MSG_RESULT([yes]) - fi - else - AC_MSG_RESULT([no]) - INSTALL_LIBRARIES=install-libraries - INSTALL_MSGS=install-msgs - fi - AC_SUBST(ZIPFS_BUILD) - AC_SUBST(INSTALL_LIBRARIES) - AC_SUBST(INSTALL_MSGS) +else +AC_MSG_RESULT([no]) +INSTALL_LIBRARIES=install-libraries +INSTALL_MSGS=install-msgs +fi +AC_SUBST(ZIPFS_BUILD) +AC_SUBST(TCL_ZIP_FILE) +AC_SUBST(INSTALL_LIBRARIES) +AC_SUBST(INSTALL_MSGS) #-------------------------------------------------------------------- @@ -423,7 +417,6 @@ AC_SUBST(TCL_PATCH_LEVEL) AC_SUBST(PKG_CFG_ARGS) AC_SUBST(TCL_EXE) -AC_SUBST(TCL_ZIP_FILE) AC_SUBST(TCL_LIB_FILE) AC_SUBST(TCL_LIB_FLAG) AC_SUBST(TCL_STATIC_LIB_FILE) diff --git a/win/tcl.m4 b/win/tcl.m4 index 07be5a4..4d34c7d 100644 --- a/win/tcl.m4 +++ b/win/tcl.m4 @@ -1302,47 +1302,6 @@ print("manifest needed") AC_SUBST(VC_MANIFEST_EMBED_EXE) ]) - -#------------------------------------------------------------------------ -# SC_PROG_ZIP -# Locate a zip encoder installed on the system path, or none. -# -# Arguments: -# none -# -# Results: -# Substitutes the following vars: -# ZIP_PROG -#------------------------------------------------------------------------ - -AC_DEFUN([SC_PROG_ZIP], [ - AC_MSG_CHECKING([for zip]) - AC_CACHE_VAL(ac_cv_path_zip, [ - search_path=`echo ${PATH} | sed -e 's/:/ /g'` - for dir in $search_path ; do - for j in `ls -r $dir/zip 2> /dev/null` \ - `ls -r $dir/zip 2> /dev/null` ; do - if test x"$ac_cv_path_zip" = x ; then - if test -f "$j" ; then - ac_cv_path_zip=$j - break - fi - fi - done - done - ]) - - if test -f "$ac_cv_path_zip" ; then - ZIP_PROG="$ac_cv_path_zip" - AC_MSG_RESULT([$ZIP_PROG]) - else - # It is not an error if an installed version of Zip can't be located. - ZIP_PROG="" - AC_MSG_RESULT([No zip found on PATH]) - fi - AC_SUBST(ZIP_PROG) -]) - #------------------------------------------------------------------------ # SC_CC_FOR_BUILD # For cross compiles, locate a C compiler that can generate native binaries. @@ -1405,3 +1364,74 @@ else fi AC_SUBST(EXEEXT_FOR_BUILD)])dnl AC_SUBST(OBJEXT_FOR_BUILD)])dnl + + + +#------------------------------------------------------------------------ +# SC_ZIPFS_SUPPORT +# Locate a zip encoder installed on the system path, or none. +# +# Arguments: +# none +# +# Results: +# Substitutes the following vars: +# ZIP_PROG +# ZIP_PROG_OPTIONS +# ZIP_PROG_VFSSEARCH +# ZIP_INSTALL_OBJS +#------------------------------------------------------------------------ + +AC_DEFUN([SC_ZIPFS_SUPPORT], [ + ZIP_PROG="" + ZIP_PROG_OPTIONS="" + ZIP_PROG_VFSSEARCH="" + ZIP_INSTALL_OBJS="" + AC_MSG_CHECKING([for zip]) + # If our native tclsh processes the "install" command line option + # we can use it to mint zip files + AS_IF([$TCLSH_PROG install],[ + ZIP_PROG=${TCLSH_PROG} + ZIP_PROG_OPTIONS="install mkzip" + ZIP_PROG_VFSSEARCH="." + AC_MSG_RESULT([Can use Native Tclsh for Zip encoding]) + ]) + + if test "x$ZIP_PROG" = "x" ; then + AC_MSG_CHECKING([for zip]) + AC_CACHE_VAL(ac_cv_path_zip, [ + search_path=`echo ${PATH} | sed -e 's/:/ /g'` + for dir in $search_path ; do + for j in `ls -r $dir/zip 2> /dev/null` \ + `ls -r $dir/zip 2> /dev/null` ; do + if test x"$ac_cv_path_zip" = x ; then + if test -f "$j" ; then + ac_cv_path_zip=$j + break + fi + fi + done + done + ]) + if test -f "$ac_cv_path_zip" ; then + ZIP_PROG="$ac_cv_path_zip " + AC_MSG_RESULT([$ZIP_PROG]) + ZIP_PROG_OPTIONS="-rq" + ZIP_PROG_VFSSEARCH="." + AC_MSG_RESULT([Found INFO Zip in environment]) + # Use standard arguments for zip + else + # It is not an error if an installed version of Zip can't be located. + # We can use the locally distributed minizip instead + ZIP_PROG="../minizip${EXEEXT_FOR_BUILD}" + ZIP_PROG_OPTIONS="\"-o\"" + ZIP_PROG_VFSSEARCH="\`find . -type f\'" + ZIP_INSTALL_OBJS="minizip${EXEEXT_FOR_BUILD}" + AC_MSG_RESULT([No zip found on PATH building minizip]) + fi + fi + AC_SUBST(ZIP_PROG) + AC_SUBST(ZIP_PROG_OPTIONS) + AC_SUBST(ZIP_PROG_VFSSEARCH) + AC_SUBST(ZIP_INSTALL_OBJS) +]) -- cgit v0.12 From 3640513caf65072e9caf1d7f24856864767c9cca Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Mon, 20 Nov 2017 18:08:12 +0000 Subject: Autoconf fixes --- unix/configure | 71 ++++++++++++++++++++++++++++++++++- unix/configure.ac | 2 +- win/configure | 108 +++++++++++++++++++++++++++++++++++++++++++++++++++++- win/configure.ac | 3 +- 4 files changed, 180 insertions(+), 4 deletions(-) diff --git a/unix/configure b/unix/configure index 1c3a206..cbcdd85 100755 --- a/unix/configure +++ b/unix/configure @@ -668,6 +668,10 @@ INSTALL_MSGS INSTALL_LIBRARIES TCL_ZIP_FILE ZIPFS_BUILD +ZIP_INSTALL_OBJS +ZIP_PROG_VFSSEARCH +ZIP_PROG_OPTIONS +ZIP_PROG EXEEXT_FOR_BUILD CC_FOR_BUILD DTRACE @@ -10228,7 +10232,72 @@ $as_echo "$bfd_cv_build_exeext" >&6; } # # Find a native zip implementation # - SC_PROG_ZIP + + ZIP_PROG="" + ZIP_PROG_OPTIONS="" + ZIP_PROG_VFSSEARCH="" + ZIP_INSTALL_OBJS="" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for zip" >&5 +$as_echo_n "checking for zip... " >&6; } + # If our native tclsh processes the "install" command line option + # we can use it to mint zip files + if $TCLSH_PROG install; then : + + ZIP_PROG=${TCLSH_PROG} + ZIP_PROG_OPTIONS="install mkzip" + ZIP_PROG_VFSSEARCH="." + { $as_echo "$as_me:${as_lineno-$LINENO}: result: Can use Native Tclsh for Zip encoding" >&5 +$as_echo "Can use Native Tclsh for Zip encoding" >&6; } + +fi + + if test "x$ZIP_PROG" = "x" ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for zip" >&5 +$as_echo_n "checking for zip... " >&6; } + if ${ac_cv_path_zip+:} false; then : + $as_echo_n "(cached) " >&6 +else + + search_path=`echo ${PATH} | sed -e 's/:/ /g'` + for dir in $search_path ; do + for j in `ls -r $dir/zip 2> /dev/null` \ + `ls -r $dir/zip 2> /dev/null` ; do + if test x"$ac_cv_path_zip" = x ; then + if test -f "$j" ; then + ac_cv_path_zip=$j + break + fi + fi + done + done + +fi + + if test -f "$ac_cv_path_zip" ; then + ZIP_PROG="$ac_cv_path_zip " + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ZIP_PROG" >&5 +$as_echo "$ZIP_PROG" >&6; } + ZIP_PROG_OPTIONS="-rq" + ZIP_PROG_VFSSEARCH="." + { $as_echo "$as_me:${as_lineno-$LINENO}: result: Found INFO Zip in environment" >&5 +$as_echo "Found INFO Zip in environment" >&6; } + # Use standard arguments for zip + else + # It is not an error if an installed version of Zip can't be located. + # We can use the locally distributed minizip instead + ZIP_PROG="../minizip${EXEEXT_FOR_BUILD}" + ZIP_PROG_OPTIONS="\"-o\"" + ZIP_PROG_VFSSEARCH="\`find . -type f\'" + ZIP_INSTALL_OBJS="minizip${EXEEXT_FOR_BUILD}" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: No zip found on PATH building minizip" >&5 +$as_echo "No zip found on PATH building minizip" >&6; } + fi + fi + + + + + ZIPFS_BUILD=1 TCL_ZIP_FILE=libtcl_${TCL_MAJOR_VERSION}_${TCL_MINOR_VERSION}_${TCL_PATCH_LEVEL}.zip else diff --git a/unix/configure.ac b/unix/configure.ac index 0928fc8..d633cce 100644 --- a/unix/configure.ac +++ b/unix/configure.ac @@ -806,7 +806,7 @@ if test "$tcl_ok" = "yes" ; then # # Find a native zip implementation # - SC_PROG_ZIP + SC_ZIPFS_SUPPORT ZIPFS_BUILD=1 TCL_ZIP_FILE=libtcl_${TCL_MAJOR_VERSION}_${TCL_MINOR_VERSION}_${TCL_PATCH_LEVEL}.zip else diff --git a/win/configure b/win/configure index c99d499..9bc07f0 100755 --- a/win/configure +++ b/win/configure @@ -703,6 +703,11 @@ INSTALL_MSGS INSTALL_LIBRARIES TCL_ZIP_FILE ZIPFS_BUILD +ZIP_INSTALL_OBJS +ZIP_PROG_VFSSEARCH +ZIP_PROG_OPTIONS +ZIP_PROG +TCLSH_PROG EXEEXT_FOR_BUILD CC_FOR_BUILD ZLIB_OBJS @@ -4916,7 +4921,108 @@ fi # # Find a native zip implementation # - SC_PROG_ZIP + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for tclsh" >&5 +$as_echo_n "checking for tclsh... " >&6; } + + if ${ac_cv_path_tclsh+:} false; then : + $as_echo_n "(cached) " >&6 +else + + search_path=`echo ${PATH} | sed -e 's/:/ /g'` + for dir in $search_path ; do + for j in `ls -r $dir/tclsh[8-9]*.exe 2> /dev/null` \ + `ls -r $dir/tclsh* 2> /dev/null` ; do + if test x"$ac_cv_path_tclsh" = x ; then + if test -f "$j" ; then + ac_cv_path_tclsh=$j + break + fi + fi + done + done + +fi + + + if test -f "$ac_cv_path_tclsh" ; then + TCLSH_PROG="$ac_cv_path_tclsh" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $TCLSH_PROG" >&5 +$as_echo "$TCLSH_PROG" >&6; } + else + # It is not an error if an installed version of Tcl can't be located. + TCLSH_PROG="" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: No tclsh found on PATH" >&5 +$as_echo "No tclsh found on PATH" >&6; } + fi + + + + ZIP_PROG="" + ZIP_PROG_OPTIONS="" + ZIP_PROG_VFSSEARCH="" + ZIP_INSTALL_OBJS="" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for zip" >&5 +$as_echo_n "checking for zip... " >&6; } + # If our native tclsh processes the "install" command line option + # we can use it to mint zip files + if $TCLSH_PROG install; then : + + ZIP_PROG=${TCLSH_PROG} + ZIP_PROG_OPTIONS="install mkzip" + ZIP_PROG_VFSSEARCH="." + { $as_echo "$as_me:${as_lineno-$LINENO}: result: Can use Native Tclsh for Zip encoding" >&5 +$as_echo "Can use Native Tclsh for Zip encoding" >&6; } + +fi + + if test "x$ZIP_PROG" = "x" ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for zip" >&5 +$as_echo_n "checking for zip... " >&6; } + if ${ac_cv_path_zip+:} false; then : + $as_echo_n "(cached) " >&6 +else + + search_path=`echo ${PATH} | sed -e 's/:/ /g'` + for dir in $search_path ; do + for j in `ls -r $dir/zip 2> /dev/null` \ + `ls -r $dir/zip 2> /dev/null` ; do + if test x"$ac_cv_path_zip" = x ; then + if test -f "$j" ; then + ac_cv_path_zip=$j + break + fi + fi + done + done + +fi + + if test -f "$ac_cv_path_zip" ; then + ZIP_PROG="$ac_cv_path_zip " + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ZIP_PROG" >&5 +$as_echo "$ZIP_PROG" >&6; } + ZIP_PROG_OPTIONS="-rq" + ZIP_PROG_VFSSEARCH="." + { $as_echo "$as_me:${as_lineno-$LINENO}: result: Found INFO Zip in environment" >&5 +$as_echo "Found INFO Zip in environment" >&6; } + # Use standard arguments for zip + else + # It is not an error if an installed version of Zip can't be located. + # We can use the locally distributed minizip instead + ZIP_PROG="../minizip${EXEEXT_FOR_BUILD}" + ZIP_PROG_OPTIONS="\"-o\"" + ZIP_PROG_VFSSEARCH="\`find . -type f\'" + ZIP_INSTALL_OBJS="minizip${EXEEXT_FOR_BUILD}" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: No zip found on PATH building minizip" >&5 +$as_echo "No zip found on PATH building minizip" >&6; } + fi + fi + + + + + ZIPFS_BUILD=1 TCL_ZIP_FILE=libtcl_${TCL_MAJOR_VERSION}_${TCL_MINOR_VERSION}_${TCL_PATCH_LEVEL}.zip else diff --git a/win/configure.ac b/win/configure.ac index b1f3a52..41bd55c 100644 --- a/win/configure.ac +++ b/win/configure.ac @@ -190,7 +190,8 @@ if test "$tcl_ok" = "yes" ; then # # Find a native zip implementation # - SC_PROG_ZIP + SC_PROG_TCLSH + SC_ZIPFS_SUPPORT ZIPFS_BUILD=1 TCL_ZIP_FILE=libtcl_${TCL_MAJOR_VERSION}_${TCL_MINOR_VERSION}_${TCL_PATCH_LEVEL}.zip else -- cgit v0.12 From 4a8bb308e8dad6abe65db94dfe0c0ddccdbcbb6c Mon Sep 17 00:00:00 2001 From: tne Date: Mon, 20 Nov 2017 19:21:12 +0000 Subject: Fixes to determing the dll location on Windows using GetModuleFileName() --- generic/tclZipfs.c | 41 +++++++++++++++++++++++++++++++++++++++ win/Makefile.in | 57 +++++++++++++++++++++++++++++------------------------- 2 files changed, 72 insertions(+), 26 deletions(-) diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c index 8c852b2..f02cc06 100644 --- a/generic/tclZipfs.c +++ b/generic/tclZipfs.c @@ -16,6 +16,8 @@ #if !defined(_WIN32) && !defined(_WIN64) #include +#else +#include #endif #include #include @@ -3888,6 +3890,26 @@ TclZipfs_Init(Tcl_Interp *interp) #endif } +#if defined(_WIN32) || defined(_WIN64) +#define LIBRARY_SIZE 64 +static int +ToUtf( + const WCHAR *wSrc, + char *dst) +{ + char *start; + + start = dst; + while (*wSrc != '\0') { + dst += Tcl_UniCharToUtf(*wSrc, dst); + wSrc++; + } + *dst = '\0'; + return (int) (dst - start); +} + +#endif + static int TclZipfs_AppHook_FindTclInit(const char *archive){ Tcl_Obj *vfsinitscript; int found; @@ -3918,6 +3940,12 @@ int TclZipfs_AppHook(int *argc, char ***argv){ */ CONST char *archive; +#if defined(_WIN32) || defined(_WIN64) + HMODULE hModule = TclWinGetTclInstance(); + WCHAR wName[MAX_PATH + LIBRARY_SIZE]; + char dllname[(MAX_PATH + LIBRARY_SIZE) * TCL_UTF_MAX]; +#endif + Tcl_FindExecutable(*argv[0]); archive=Tcl_GetNameOfExecutable(); TclZipfs_Init(NULL); @@ -4006,10 +4034,23 @@ int TclZipfs_AppHook(int *argc, char ***argv){ } } } +#if defined(_WIN32) || defined(_WIN64) + if (GetModuleFileNameW(hModule, wName, MAX_PATH) == 0) { + GetModuleFileNameA(hModule, dllname, MAX_PATH); + } else { + ToUtf(wName, dllname); + } + printf("DLL FILE: %s\n",dllname); fflush(stdout); + /* Mount zip file and dll before releasing to search */ + if(TclZipfs_AppHook_FindTclInit(dllname)==TCL_OK) { + return TCL_OK; + } +#else /* Mount zip file and dll before releasing to search */ if(TclZipfs_AppHook_FindTclInit(CFG_RUNTIME_PATH "/" CFG_RUNTIME_DLLFILE)==TCL_OK) { return TCL_OK; } +#endif if(TclZipfs_AppHook_FindTclInit(CFG_RUNTIME_PATH "/" CFG_RUNTIME_ZIPFILE)==TCL_OK) { return TCL_OK; } diff --git a/win/Makefile.in b/win/Makefile.in index 7f4fc70..6734985 100644 --- a/win/Makefile.in +++ b/win/Makefile.in @@ -560,9 +560,10 @@ tclMain2.${OBJEXT}: tclMain.c # TIP #430, ZipFS Support tclZipfs.${OBJEXT}: $(GENERIC_DIR)/tclZipfs.c $(CC) -c $(CC_SWITCHES) -DBUILD_tcl \ + -DCFG_RUNTIME_PATH=\"$(bindir_native)\" \ -DCFG_RUNTIME_DLLFILE="\"$(TCL_LIB_FILE)\"" \ -DCFG_RUNTIME_ZIPFILE="\"$(TCL_ZIP_FILE)\"" \ - -DCFG_RUNTIME_PATH="\"$(DLL_INSTALL_DIR)\"" \ + -DCFG_RUNTIME_PATH="\"$(BIN_INSTALL_DIR)\"" \ $(ZLIB_INCLUDE) -I$(ZLIB_DIR)/contrib/minizip @DEPARG@ $(CC_OBJNAME) @@ -705,7 +706,15 @@ gentommath_h: "$(TOMMATH_DIR_NATIVE)/tommath.h" \ > "$(GENERIC_DIR_NATIVE)/tclTomMath.h" -install: all install-binaries install-libraries install-doc install-packages +INSTALL_BASE_TARGETS = install-binaries $(INSTALL_LIBRARIES) $(INSTALL_MSGS) $(INSTALL_TZDATA) +INSTALL_DOC_TARGETS = install-doc +INSTALL_PACKAGE_TARGETS = install-packages +INSTALL_DEV_TARGETS = install-headers +INSTALL_EXTRA_TARGETS = +INSTALL_TARGETS = $(INSTALL_BASE_TARGETS) $(INSTALL_DOC_TARGETS) $(INSTALL_DEV_TARGETS) \ + $(INSTALL_PACKAGE_TARGETS) $(INSTALL_EXTRA_TARGETS) + +install: $(INSTALL_TARGETS) install-binaries: binaries @for i in "$(LIB_INSTALL_DIR)" "$(BIN_INSTALL_DIR)" ; \ @@ -761,23 +770,9 @@ install-binaries: binaries fi install-libraries-zipfs-shared: libraries - @for i in "$(SCRIPT_INSTALL_DIR)"; \ - do \ - if [ ! -d "$$i" ] ; then \ - echo "Making directory $$i"; \ - $(INSTALL_DATA_DIR) "$$i"; \ - else true; \ - fi; \ - done; - @echo "Installing library files to $(SCRIPT_INSTALL_DIR)/"; - @for i in \ - $(UNIX_DIR)/tclAppInit.c @LDAIX_SRC@ @DTRACE_SRC@; \ - do \ - $(INSTALL_DATA) $$i "$(SCRIPT_INSTALL_DIR)"; \ - done; install-libraries-zipfs-static: install-libraries-zipfs-shared - $(INSTALL_DATA) ${TCL_ZIP_FILE} "$(LIB_INSTALL_DIR)" ;\ + $(INSTALL_DATA) ${TCL_ZIP_FILE} "$(LIB_INSTALL_DIR)" install-libraries: libraries install-tzdata install-msgs @for i in "$$($(CYGPATH) $(prefix)/lib)" "$(INCLUDE_INSTALL_DIR)" \ @@ -797,15 +792,6 @@ install-libraries: libraries install-tzdata install-msgs else true; \ fi; \ done; - @echo "Installing header files"; - @for i in "$(GENERIC_DIR)/tcl.h" "$(GENERIC_DIR)/tclDecls.h" \ - "$(GENERIC_DIR)/tclOO.h" "$(GENERIC_DIR)/tclOODecls.h" \ - "$(GENERIC_DIR)/tclPlatDecls.h" \ - "$(GENERIC_DIR)/tclTomMath.h" \ - "$(GENERIC_DIR)/tclTomMathDecls.h"; \ - do \ - $(COPY) "$$i" "$(INCLUDE_INSTALL_DIR)"; \ - done; @echo "Installing library files to $(SCRIPT_INSTALL_DIR)"; @for i in $(ROOT_DIR)/library/*.tcl $(ROOT_DIR)/library/tclIndex; \ do \ @@ -848,6 +834,25 @@ install-msgs: install-doc: doc +install-headers: + @for i in "$(INCLUDE_INSTALL_DIR)"; \ + do \ + if [ ! -d "$$i" ] ; then \ + echo "Making directory $$i"; \ + $(INSTALL_DATA_DIR) "$$i"; \ + else true; \ + fi; \ + done; + @echo "Installing header files to $(INCLUDE_INSTALL_DIR)/"; + @for i in $(GENERIC_DIR)/tcl.h $(GENERIC_DIR)/tclDecls.h \ + $(GENERIC_DIR)/tclOO.h $(GENERIC_DIR)/tclOODecls.h \ + $(GENERIC_DIR)/tclPlatDecls.h \ + $(GENERIC_DIR)/tclTomMath.h \ + $(GENERIC_DIR)/tclTomMathDecls.h ; \ + do \ + $(COPY) $$i "$(INCLUDE_INSTALL_DIR)"; \ + done; + # Optional target to install private headers install-private-headers: libraries @for i in $(PRIVATE_INCLUDE_INSTALL_DIR); \ -- cgit v0.12 From 1f34b918b9bf1c3cc57c59952f006aec619c435c Mon Sep 17 00:00:00 2001 From: tne Date: Mon, 20 Nov 2017 19:35:40 +0000 Subject: Removing debugging printf() statement --- generic/tclZipfs.c | 1 - 1 file changed, 1 deletion(-) diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c index f02cc06..b3e863b 100644 --- a/generic/tclZipfs.c +++ b/generic/tclZipfs.c @@ -4040,7 +4040,6 @@ int TclZipfs_AppHook(int *argc, char ***argv){ } else { ToUtf(wName, dllname); } - printf("DLL FILE: %s\n",dllname); fflush(stdout); /* Mount zip file and dll before releasing to search */ if(TclZipfs_AppHook_FindTclInit(dllname)==TCL_OK) { return TCL_OK; -- cgit v0.12 From 12a14f4954455c5d991ab3e71094f7995b15e8c7 Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Mon, 20 Nov 2017 21:29:57 +0000 Subject: Updating tcl.m4 in windows to fix a typo --- win/configure | 2 +- win/tcl.m4 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/win/configure b/win/configure index 9bc07f0..846d824 100755 --- a/win/configure +++ b/win/configure @@ -5012,7 +5012,7 @@ $as_echo "Found INFO Zip in environment" >&6; } # We can use the locally distributed minizip instead ZIP_PROG="../minizip${EXEEXT_FOR_BUILD}" ZIP_PROG_OPTIONS="\"-o\"" - ZIP_PROG_VFSSEARCH="\`find . -type f\'" + ZIP_PROG_VFSSEARCH="'find . -type f'" ZIP_INSTALL_OBJS="minizip${EXEEXT_FOR_BUILD}" { $as_echo "$as_me:${as_lineno-$LINENO}: result: No zip found on PATH building minizip" >&5 $as_echo "No zip found on PATH building minizip" >&6; } diff --git a/win/tcl.m4 b/win/tcl.m4 index 4d34c7d..3a9ae07 100644 --- a/win/tcl.m4 +++ b/win/tcl.m4 @@ -1425,7 +1425,7 @@ AC_DEFUN([SC_ZIPFS_SUPPORT], [ # We can use the locally distributed minizip instead ZIP_PROG="../minizip${EXEEXT_FOR_BUILD}" ZIP_PROG_OPTIONS="\"-o\"" - ZIP_PROG_VFSSEARCH="\`find . -type f\'" + ZIP_PROG_VFSSEARCH="'find . -type f'" ZIP_INSTALL_OBJS="minizip${EXEEXT_FOR_BUILD}" AC_MSG_RESULT([No zip found on PATH building minizip]) fi -- cgit v0.12 From d2fc7a6ed510eccea8dd9052d243ed160eb883ba Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Mon, 20 Nov 2017 22:45:35 +0000 Subject: Fixing the quoting for arguments to minizip --- unix/configure | 4 ++-- unix/tcl.m4 | 4 ++-- win/configure | 2 +- win/tcl.m4 | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/unix/configure b/unix/configure index cbcdd85..53e0a07 100755 --- a/unix/configure +++ b/unix/configure @@ -10286,8 +10286,8 @@ $as_echo "Found INFO Zip in environment" >&6; } # It is not an error if an installed version of Zip can't be located. # We can use the locally distributed minizip instead ZIP_PROG="../minizip${EXEEXT_FOR_BUILD}" - ZIP_PROG_OPTIONS="\"-o\"" - ZIP_PROG_VFSSEARCH="\`find . -type f\'" + ZIP_PROG_OPTIONS="-o" + ZIP_PROG_VFSSEARCH="\"`find . -type f`\"" ZIP_INSTALL_OBJS="minizip${EXEEXT_FOR_BUILD}" { $as_echo "$as_me:${as_lineno-$LINENO}: result: No zip found on PATH building minizip" >&5 $as_echo "No zip found on PATH building minizip" >&6; } diff --git a/unix/tcl.m4 b/unix/tcl.m4 index 9cfb746..dbc92da 100644 --- a/unix/tcl.m4 +++ b/unix/tcl.m4 @@ -3136,8 +3136,8 @@ AC_DEFUN([SC_ZIPFS_SUPPORT], [ # It is not an error if an installed version of Zip can't be located. # We can use the locally distributed minizip instead ZIP_PROG="../minizip${EXEEXT_FOR_BUILD}" - ZIP_PROG_OPTIONS="\"-o\"" - ZIP_PROG_VFSSEARCH="\`find . -type f\'" + ZIP_PROG_OPTIONS="-o" + ZIP_PROG_VFSSEARCH="\"`find . -type f`\"" ZIP_INSTALL_OBJS="minizip${EXEEXT_FOR_BUILD}" AC_MSG_RESULT([No zip found on PATH building minizip]) fi diff --git a/win/configure b/win/configure index 846d824..f4d0448 100755 --- a/win/configure +++ b/win/configure @@ -5012,7 +5012,7 @@ $as_echo "Found INFO Zip in environment" >&6; } # We can use the locally distributed minizip instead ZIP_PROG="../minizip${EXEEXT_FOR_BUILD}" ZIP_PROG_OPTIONS="\"-o\"" - ZIP_PROG_VFSSEARCH="'find . -type f'" + ZIP_PROG_VFSSEARCH="\"`find . -type f`\"" ZIP_INSTALL_OBJS="minizip${EXEEXT_FOR_BUILD}" { $as_echo "$as_me:${as_lineno-$LINENO}: result: No zip found on PATH building minizip" >&5 $as_echo "No zip found on PATH building minizip" >&6; } diff --git a/win/tcl.m4 b/win/tcl.m4 index 3a9ae07..ecfcd52 100644 --- a/win/tcl.m4 +++ b/win/tcl.m4 @@ -1425,7 +1425,7 @@ AC_DEFUN([SC_ZIPFS_SUPPORT], [ # We can use the locally distributed minizip instead ZIP_PROG="../minizip${EXEEXT_FOR_BUILD}" ZIP_PROG_OPTIONS="\"-o\"" - ZIP_PROG_VFSSEARCH="'find . -type f'" + ZIP_PROG_VFSSEARCH="\"`find . -type f`\"" ZIP_INSTALL_OBJS="minizip${EXEEXT_FOR_BUILD}" AC_MSG_RESULT([No zip found on PATH building minizip]) fi -- cgit v0.12 From 3cd8b86e50caa31bf230d5f1b224708f5dda41af Mon Sep 17 00:00:00 2001 From: tne Date: Mon, 20 Nov 2017 23:34:21 +0000 Subject: Change to TclZipfs_AppHook to accomidate Windows --- generic/tcl.decls | 11 +++++++---- generic/tclDecls.h | 5 ----- generic/tclPlatDecls.h | 26 ++++++++++++++++++++------ generic/tclStubInit.c | 7 +++++-- generic/tclZipfs.c | 31 ++++++++++++++++++++++++++++--- 5 files changed, 60 insertions(+), 20 deletions(-) diff --git a/generic/tcl.decls b/generic/tcl.decls index e929eaf..03104ba 100644 --- a/generic/tcl.decls +++ b/generic/tcl.decls @@ -2340,9 +2340,7 @@ declare 632 { declare 633 { int TclZipfs_Unmount(Tcl_Interp *interp, const char *zipname) } -declare 634 { - int TclZipfs_AppHook(int *argc, char ***argv) -} + ############################################################################## # Define the platform specific public Tcl interface. These functions are only @@ -2353,6 +2351,9 @@ interface tclPlat ################################ # Unix specific functions # (none) +declare 0 unix { + int TclZipfs_AppHook(int *argc, char ***argv) +} ################################ # Windows specific functions @@ -2365,7 +2366,9 @@ declare 0 win { declare 1 win { char *Tcl_WinTCharToUtf(const TCHAR *str, int len, Tcl_DString *dsPtr) } - +declare 2 win { + int TclZipfs_AppHook(int *argc, TCHAR ***argv) +} ################################ # Mac OS X specific functions diff --git a/generic/tclDecls.h b/generic/tclDecls.h index c41a20b..c5b42d3 100644 --- a/generic/tclDecls.h +++ b/generic/tclDecls.h @@ -1845,8 +1845,6 @@ EXTERN int TclZipfs_Mount(Tcl_Interp *interp, /* 633 */ EXTERN int TclZipfs_Unmount(Tcl_Interp *interp, const char *zipname); -/* 634 */ -EXTERN int TclZipfs_AppHook(int *argc, char ***argv); typedef struct { const struct TclPlatStubs *tclPlatStubs; @@ -2516,7 +2514,6 @@ typedef struct TclStubs { Tcl_Channel (*tcl_OpenTcpServerEx) (Tcl_Interp *interp, const char *service, const char *host, unsigned int flags, Tcl_TcpAcceptProc *acceptProc, ClientData callbackData); /* 631 */ int (*tclZipfs_Mount) (Tcl_Interp *interp, const char *zipname, const char *mntpt, const char *passwd); /* 632 */ int (*tclZipfs_Unmount) (Tcl_Interp *interp, const char *zipname); /* 633 */ - int (*tclZipfs_AppHook) (int *argc, char ***argv); /* 634 */ } TclStubs; extern const TclStubs *tclStubsPtr; @@ -3815,8 +3812,6 @@ extern const TclStubs *tclStubsPtr; (tclStubsPtr->tclZipfs_Mount) /* 632 */ #define TclZipfs_Unmount \ (tclStubsPtr->tclZipfs_Unmount) /* 633 */ -#define TclZipfs_AppHook \ - (tclStubsPtr->tclZipfs_AppHook) /* 634 */ #endif /* defined(USE_TCL_STUBS) */ diff --git a/generic/tclPlatDecls.h b/generic/tclPlatDecls.h index abc8ee8..e746a6d 100644 --- a/generic/tclPlatDecls.h +++ b/generic/tclPlatDecls.h @@ -50,6 +50,10 @@ extern "C" { * Exported function declarations: */ +#if !defined(_WIN32) && !defined(__CYGWIN__) && !defined(MAC_OSX_TCL) /* UNIX */ +/* 0 */ +EXTERN int TclZipfs_AppHook(int *argc, char ***argv); +#endif /* UNIX */ #if defined(_WIN32) || defined(__CYGWIN__) /* WIN */ /* 0 */ EXTERN TCHAR * Tcl_WinUtfToTChar(const char *str, int len, @@ -57,12 +61,12 @@ EXTERN TCHAR * Tcl_WinUtfToTChar(const char *str, int len, /* 1 */ EXTERN char * Tcl_WinTCharToUtf(const TCHAR *str, int len, Tcl_DString *dsPtr); +/* 2 */ +EXTERN int TclZipfs_AppHook(int *argc, TCHAR ***argv); #endif /* WIN */ #ifdef MAC_OSX_TCL /* MACOSX */ /* 0 */ -EXTERN int Tcl_MacOSXOpenBundleResources(Tcl_Interp *interp, - const char *bundleName, int hasResourceFile, - int maxPathLen, char *libraryPath); +EXTERN int TclZipfs_AppHook(int *argc, char ***argv); /* 1 */ EXTERN int Tcl_MacOSXOpenVersionedBundleResources( Tcl_Interp *interp, const char *bundleName, @@ -75,12 +79,16 @@ typedef struct TclPlatStubs { int magic; void *hooks; +#if !defined(_WIN32) && !defined(__CYGWIN__) && !defined(MAC_OSX_TCL) /* UNIX */ + int (*tclZipfs_AppHook) (int *argc, char ***argv); /* 0 */ +#endif /* UNIX */ #if defined(_WIN32) || defined(__CYGWIN__) /* WIN */ TCHAR * (*tcl_WinUtfToTChar) (const char *str, int len, Tcl_DString *dsPtr); /* 0 */ char * (*tcl_WinTCharToUtf) (const TCHAR *str, int len, Tcl_DString *dsPtr); /* 1 */ + int (*tclZipfs_AppHook) (int *argc, TCHAR ***argv); /* 2 */ #endif /* WIN */ #ifdef MAC_OSX_TCL /* MACOSX */ - int (*tcl_MacOSXOpenBundleResources) (Tcl_Interp *interp, const char *bundleName, int hasResourceFile, int maxPathLen, char *libraryPath); /* 0 */ + int (*tclZipfs_AppHook) (int *argc, char ***argv); /* 0 */ int (*tcl_MacOSXOpenVersionedBundleResources) (Tcl_Interp *interp, const char *bundleName, const char *bundleVersion, int hasResourceFile, int maxPathLen, char *libraryPath); /* 1 */ #endif /* MACOSX */ } TclPlatStubs; @@ -97,15 +105,21 @@ extern const TclPlatStubs *tclPlatStubsPtr; * Inline function declarations: */ +#if !defined(_WIN32) && !defined(__CYGWIN__) && !defined(MAC_OSX_TCL) /* UNIX */ +#define TclZipfs_AppHook \ + (tclPlatStubsPtr->tclZipfs_AppHook) /* 0 */ +#endif /* UNIX */ #if defined(_WIN32) || defined(__CYGWIN__) /* WIN */ #define Tcl_WinUtfToTChar \ (tclPlatStubsPtr->tcl_WinUtfToTChar) /* 0 */ #define Tcl_WinTCharToUtf \ (tclPlatStubsPtr->tcl_WinTCharToUtf) /* 1 */ +#define TclZipfs_AppHook \ + (tclPlatStubsPtr->tclZipfs_AppHook) /* 2 */ #endif /* WIN */ #ifdef MAC_OSX_TCL /* MACOSX */ -#define Tcl_MacOSXOpenBundleResources \ - (tclPlatStubsPtr->tcl_MacOSXOpenBundleResources) /* 0 */ +#define TclZipfs_AppHook \ + (tclPlatStubsPtr->tclZipfs_AppHook) /* 0 */ #define Tcl_MacOSXOpenVersionedBundleResources \ (tclPlatStubsPtr->tcl_MacOSXOpenVersionedBundleResources) /* 1 */ #endif /* MACOSX */ diff --git a/generic/tclStubInit.c b/generic/tclStubInit.c index 0702f69..ffa42bf 100644 --- a/generic/tclStubInit.c +++ b/generic/tclStubInit.c @@ -789,12 +789,16 @@ static const TclIntPlatStubs tclIntPlatStubs = { static const TclPlatStubs tclPlatStubs = { TCL_STUB_MAGIC, 0, +#if !defined(_WIN32) && !defined(__CYGWIN__) && !defined(MAC_OSX_TCL) /* UNIX */ + TclZipfs_AppHook, /* 0 */ +#endif /* UNIX */ #if defined(_WIN32) || defined(__CYGWIN__) /* WIN */ Tcl_WinUtfToTChar, /* 0 */ Tcl_WinTCharToUtf, /* 1 */ + TclZipfs_AppHook, /* 2 */ #endif /* WIN */ #ifdef MAC_OSX_TCL /* MACOSX */ - Tcl_MacOSXOpenBundleResources, /* 0 */ + TclZipfs_AppHook, /* 0 */ Tcl_MacOSXOpenVersionedBundleResources, /* 1 */ #endif /* MACOSX */ }; @@ -1543,7 +1547,6 @@ const TclStubs tclStubs = { Tcl_OpenTcpServerEx, /* 631 */ TclZipfs_Mount, /* 632 */ TclZipfs_Unmount, /* 633 */ - TclZipfs_AppHook, /* 634 */ }; /* !END!: Do not edit above this line. */ diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c index b3e863b..e6acc8d 100644 --- a/generic/tclZipfs.c +++ b/generic/tclZipfs.c @@ -3933,13 +3933,18 @@ static int TclZipfs_AppHook_FindTclInit(const char *archive){ return TCL_ERROR; } -int TclZipfs_AppHook(int *argc, char ***argv){ +#if defined(_WIN32) || defined(_WIN64) +int TclZipfs_AppHook(int *argc, TCHAR ***argv) +#else +int TclZipfs_AppHook(int *argc, char ***argv) +#endif +{ /* * Tclkit_MainHook -- * Performs the argument munging for the shell */ - CONST char *archive; + char *archive; #if defined(_WIN32) || defined(_WIN64) HMODULE hModule = TclWinGetTclInstance(); WCHAR wName[MAX_PATH + LIBRARY_SIZE]; @@ -4004,13 +4009,33 @@ int TclZipfs_AppHook(int *argc, char ***argv){ return TCL_OK; } } else if (*argc>1) { + Tcl_DString ds; +#if defined(_WIN32) || defined(_WIN64) + strcpy(archive, Tcl_WinTCharToUtf((*argv)[1], -1, &ds)); + Tcl_DStringFree(&ds); +#else archive=(*argv)[1]; +#endif + printf(" arg1 %s\n",archive); fflush(stdout); if(strcmp(archive,"install")==0) { /* If the first argument is mkzip, run the mkzip program */ Tcl_Obj *vfsinitscript; + vfsinitscript=Tcl_NewStringObj(ZIPFS_ZIP_MOUNT "/tcl_library/install.tcl",-1); Tcl_IncrRefCount(vfsinitscript); - Tcl_SetStartupScript(vfsinitscript,NULL); + printf(" startup script %s\n",Tcl_GetString(vfsinitscript)); fflush(stdout); +#if defined(_WIN32) || defined(_WIN64) + if (GetModuleFileNameW(hModule, wName, MAX_PATH) == 0) { + GetModuleFileNameA(hModule, dllname, MAX_PATH); + } else { + ToUtf(wName, dllname); + } + /* Mount zip file and dll before releasing to search */ + if(TclZipfs_AppHook_FindTclInit(dllname)==TCL_OK) { + Tcl_SetStartupScript(vfsinitscript,NULL); + return TCL_OK; + } +#endif } else { if(!TclZipfs_Mount(NULL, archive, ZIPFS_APP_MOUNT, NULL)) { int found; -- cgit v0.12 From 6b40a5dc5afee7752743e154ebff5935e614214f Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Tue, 21 Nov 2017 00:36:55 +0000 Subject: Added a new function to the Zipfs: TclZipfs_TclLibrary, which returns a previously discovered /library file system from a zip archive, performs the search to see if the current dll has one (and return that), or NULL if zipfs cannot locate /library. Injected a call to [zipfs tcl_library] (which invokes TclZipfs_TclLibrary) inside if interp.c as the first command to try to locate Tcl_Library (if a preinit script hasn't already pointed one out to us.) --- generic/tcl.decls | 4 +- generic/tclDecls.h | 5 ++ generic/tclInterp.c | 1 + generic/tclStubInit.c | 1 + generic/tclZipfs.c | 136 ++++++++++++++++++++++++++++++++++---------------- 5 files changed, 102 insertions(+), 45 deletions(-) diff --git a/generic/tcl.decls b/generic/tcl.decls index 03104ba..87beab3 100644 --- a/generic/tcl.decls +++ b/generic/tcl.decls @@ -2340,7 +2340,9 @@ declare 632 { declare 633 { int TclZipfs_Unmount(Tcl_Interp *interp, const char *zipname) } - +declare 634 { + Tcl_Obj *TclZipfs_TclLibrary(void) +} ############################################################################## # Define the platform specific public Tcl interface. These functions are only diff --git a/generic/tclDecls.h b/generic/tclDecls.h index c5b42d3..8ba9e5c 100644 --- a/generic/tclDecls.h +++ b/generic/tclDecls.h @@ -1845,6 +1845,8 @@ EXTERN int TclZipfs_Mount(Tcl_Interp *interp, /* 633 */ EXTERN int TclZipfs_Unmount(Tcl_Interp *interp, const char *zipname); +/* 634 */ +EXTERN Tcl_Obj * TclZipfs_TclLibrary(void); typedef struct { const struct TclPlatStubs *tclPlatStubs; @@ -2514,6 +2516,7 @@ typedef struct TclStubs { Tcl_Channel (*tcl_OpenTcpServerEx) (Tcl_Interp *interp, const char *service, const char *host, unsigned int flags, Tcl_TcpAcceptProc *acceptProc, ClientData callbackData); /* 631 */ int (*tclZipfs_Mount) (Tcl_Interp *interp, const char *zipname, const char *mntpt, const char *passwd); /* 632 */ int (*tclZipfs_Unmount) (Tcl_Interp *interp, const char *zipname); /* 633 */ + Tcl_Obj * (*tclZipfs_TclLibrary) (void); /* 634 */ } TclStubs; extern const TclStubs *tclStubsPtr; @@ -3812,6 +3815,8 @@ extern const TclStubs *tclStubsPtr; (tclStubsPtr->tclZipfs_Mount) /* 632 */ #define TclZipfs_Unmount \ (tclStubsPtr->tclZipfs_Unmount) /* 633 */ +#define TclZipfs_TclLibrary \ + (tclStubsPtr->tclZipfs_TclLibrary) /* 634 */ #endif /* defined(USE_TCL_STUBS) */ diff --git a/generic/tclInterp.c b/generic/tclInterp.c index d9dfd37..b58aee0 100644 --- a/generic/tclInterp.c +++ b/generic/tclInterp.c @@ -402,6 +402,7 @@ Tcl_Init( " set scripts {{set tcl_library}}\n" " } else {\n" " set scripts {}\n" +" lappend scripts {zipfs tcl_library}\n" " if {[info exists env(TCL_LIBRARY)] && ($env(TCL_LIBRARY) ne {})} {\n" " lappend scripts {set env(TCL_LIBRARY)}\n" " lappend scripts {\n" diff --git a/generic/tclStubInit.c b/generic/tclStubInit.c index ffa42bf..abd030a 100644 --- a/generic/tclStubInit.c +++ b/generic/tclStubInit.c @@ -1547,6 +1547,7 @@ const TclStubs tclStubs = { Tcl_OpenTcpServerEx, /* 631 */ TclZipfs_Mount, /* 632 */ TclZipfs_Unmount, /* 633 */ + TclZipfs_TclLibrary, /* 634 */ }; /* !END!: Do not edit above this line. */ diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c index e6acc8d..2e24afe 100644 --- a/generic/tclZipfs.c +++ b/generic/tclZipfs.c @@ -300,6 +300,8 @@ static const unsigned long crc32tab[256] = { static Tcl_Obj *zipfs_literal_fstype=NULL; static Tcl_Obj *zipfs_literal_fsroot=NULL; static Tcl_Obj *zipfs_literal_fsseparator=NULL; +static Tcl_Obj *zipfs_literal_null=NULL; +static Tcl_Obj *zipfs_literal_tcl_library=NULL; /* @@ -2424,6 +2426,40 @@ ZipFSListObjCmd(ClientData clientData, Tcl_Interp *interp, Unlock(); return TCL_OK; } + +/* + *------------------------------------------------------------------------- + * + * ZipFSTclLibraryObjCmd -- + * + * This procedure is invoked to process the "zipfs::root" command. It + * returns the root that all zipfs file systems are mounted under. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * + *------------------------------------------------------------------------- + */ + +static int +ZipFSTclLibraryObjCmd(ClientData clientData, Tcl_Interp *interp, + int objc, Tcl_Obj *const objv[]) +{ + Tcl_Obj *pResult; + pResult=TclZipfs_TclLibrary(); + if(!pResult) { + if(!zipfs_literal_null) { + zipfs_literal_null=Tcl_NewObj(); + Tcl_IncrRefCount(zipfs_literal_null); + } + pResult=zipfs_literal_null; + Tcl_IncrRefCount(zipfs_literal_null); + } + Tcl_SetObjResult(interp,pResult); + return TCL_OK; +} /* *------------------------------------------------------------------------- @@ -3853,6 +3889,7 @@ TclZipfs_Init(Tcl_Interp *interp) {"list", ZipFSListObjCmd, NULL, NULL, NULL, 1}, {"canonical", ZipFSCanonicalObjCmd, NULL, NULL, NULL, 1}, {"root", ZipFSRootObjCmd, NULL, NULL, NULL, 1}, + {"tcl_library", ZipFSTclLibraryObjCmd, NULL, NULL, NULL, 0}, {NULL, NULL, NULL, NULL, NULL, 0} }; @@ -3920,14 +3957,19 @@ static int TclZipfs_AppHook_FindTclInit(const char *archive){ vfsinitscript=Tcl_NewStringObj(ZIPFS_ZIP_MOUNT "/init.tcl",-1); Tcl_IncrRefCount(vfsinitscript); found=Tcl_FSAccess(vfsinitscript,F_OK); + Tcl_DecrRefCount(vfsinitscript); if(found==0) { + zipfs_literal_tcl_library=Tcl_NewStringObj(ZIPFS_ZIP_MOUNT,-1); + Tcl_IncrRefCount(zipfs_literal_tcl_library); return TCL_OK; } - Tcl_DecrRefCount(vfsinitscript); vfsinitscript=Tcl_NewStringObj(ZIPFS_ZIP_MOUNT "/tcl_library/init.tcl",-1); Tcl_IncrRefCount(vfsinitscript); found=Tcl_FSAccess(vfsinitscript,F_OK); + Tcl_DecrRefCount(vfsinitscript); if(found==0) { + zipfs_literal_tcl_library=Tcl_NewStringObj(ZIPFS_ZIP_MOUNT "/tcl_library",-1); + Tcl_IncrRefCount(zipfs_literal_tcl_library); return TCL_OK; } return TCL_ERROR; @@ -3943,14 +3985,8 @@ int TclZipfs_AppHook(int *argc, char ***argv) * Tclkit_MainHook -- * Performs the argument munging for the shell */ - char *archive; -#if defined(_WIN32) || defined(_WIN64) - HMODULE hModule = TclWinGetTclInstance(); - WCHAR wName[MAX_PATH + LIBRARY_SIZE]; - char dllname[(MAX_PATH + LIBRARY_SIZE) * TCL_UTF_MAX]; -#endif - + Tcl_FindExecutable(*argv[0]); archive=Tcl_GetNameOfExecutable(); TclZipfs_Init(NULL); @@ -4001,41 +4037,34 @@ int TclZipfs_AppHook(int *argc, char ***argv) Tcl_DecrRefCount(vfsinitscript); } /* Set Tcl Encodings */ - vfsinitscript=Tcl_NewStringObj(ZIPFS_APP_MOUNT "/tcl_library/init.tcl",-1); - Tcl_IncrRefCount(vfsinitscript); - found=Tcl_FSAccess(vfsinitscript,F_OK); - Tcl_DecrRefCount(vfsinitscript); - if(found==TCL_OK) { - return TCL_OK; + if(!zipfs_literal_tcl_library) { + vfsinitscript=Tcl_NewStringObj(ZIPFS_APP_MOUNT "/tcl_library/init.tcl",-1); + Tcl_IncrRefCount(vfsinitscript); + found=Tcl_FSAccess(vfsinitscript,F_OK); + Tcl_DecrRefCount(vfsinitscript); + if(found==TCL_OK) { + zipfs_literal_tcl_library=Tcl_NewStringObj(ZIPFS_APP_MOUNT "/tcl_library",-1); + Tcl_IncrRefCount(zipfs_literal_tcl_library); + return TCL_OK; + } } } else if (*argc>1) { - Tcl_DString ds; #if defined(_WIN32) || defined(_WIN64) + Tcl_DString ds; strcpy(archive, Tcl_WinTCharToUtf((*argv)[1], -1, &ds)); Tcl_DStringFree(&ds); #else archive=(*argv)[1]; #endif - printf(" arg1 %s\n",archive); fflush(stdout); if(strcmp(archive,"install")==0) { /* If the first argument is mkzip, run the mkzip program */ Tcl_Obj *vfsinitscript; vfsinitscript=Tcl_NewStringObj(ZIPFS_ZIP_MOUNT "/tcl_library/install.tcl",-1); Tcl_IncrRefCount(vfsinitscript); - printf(" startup script %s\n",Tcl_GetString(vfsinitscript)); fflush(stdout); -#if defined(_WIN32) || defined(_WIN64) - if (GetModuleFileNameW(hModule, wName, MAX_PATH) == 0) { - GetModuleFileNameA(hModule, dllname, MAX_PATH); - } else { - ToUtf(wName, dllname); - } - /* Mount zip file and dll before releasing to search */ - if(TclZipfs_AppHook_FindTclInit(dllname)==TCL_OK) { - Tcl_SetStartupScript(vfsinitscript,NULL); - return TCL_OK; - } -#endif + /* Run this now to ensure the file is present by the time Tcl_Main wants it */ + TclZipfs_TclLibrary(); + return TCL_OK; } else { if(!TclZipfs_Mount(NULL, archive, ZIPFS_APP_MOUNT, NULL)) { int found; @@ -4054,31 +4083,50 @@ int TclZipfs_AppHook(int *argc, char ***argv) found=Tcl_FSAccess(vfsinitscript,F_OK); Tcl_DecrRefCount(vfsinitscript); if(found==TCL_OK) { + zipfs_literal_tcl_library=Tcl_NewStringObj(ZIPFS_APP_MOUNT "/tcl_library",-1); + Tcl_IncrRefCount(zipfs_literal_tcl_library); + zipfs_literal_tcl_library=vfsinitscript; return TCL_OK; } } } } -#if defined(_WIN32) || defined(_WIN64) - if (GetModuleFileNameW(hModule, wName, MAX_PATH) == 0) { - GetModuleFileNameA(hModule, dllname, MAX_PATH); + return TCL_OK; +} + +Tcl_Obj *TclZipfs_TclLibrary(void) { + if(zipfs_literal_tcl_library) { + Tcl_IncrRefCount(zipfs_literal_tcl_library); + return zipfs_literal_tcl_library; } else { - ToUtf(wName, dllname); - } - /* Mount zip file and dll before releasing to search */ - if(TclZipfs_AppHook_FindTclInit(dllname)==TCL_OK) { - return TCL_OK; - } +#if defined(_WIN32) || defined(_WIN64) + HMODULE hModule = TclWinGetTclInstance(); + WCHAR wName[MAX_PATH + LIBRARY_SIZE]; + char dllname[(MAX_PATH + LIBRARY_SIZE) * TCL_UTF_MAX]; + + if (GetModuleFileNameW(hModule, wName, MAX_PATH) == 0) { + GetModuleFileNameA(hModule, dllname, MAX_PATH); + } else { + ToUtf(wName, dllname); + } + /* Mount zip file and dll before releasing to search */ + if(TclZipfs_AppHook_FindTclInit(dllname)==TCL_OK) { + Tcl_IncrRefCount(zipfs_literal_tcl_library); + return zipfs_literal_tcl_library; + } #else - /* Mount zip file and dll before releasing to search */ - if(TclZipfs_AppHook_FindTclInit(CFG_RUNTIME_PATH "/" CFG_RUNTIME_DLLFILE)==TCL_OK) { - return TCL_OK; - } + /* Mount zip file and dll before releasing to search */ + if(TclZipfs_AppHook_FindTclInit(CFG_RUNTIME_PATH "/" CFG_RUNTIME_DLLFILE)==TCL_OK) { + Tcl_IncrRefCount(zipfs_literal_tcl_library); + return zipfs_literal_tcl_library; + } #endif + } if(TclZipfs_AppHook_FindTclInit(CFG_RUNTIME_PATH "/" CFG_RUNTIME_ZIPFILE)==TCL_OK) { - return TCL_OK; + Tcl_IncrRefCount(zipfs_literal_tcl_library); + return zipfs_literal_tcl_library; } - return TCL_OK; + return NULL; } -- cgit v0.12 From 9ef614086a2b3267669f4fb644ad1a92debb5fb0 Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Tue, 21 Nov 2017 00:41:04 +0000 Subject: Typo fixes for minizip --- win/configure | 4 ++-- win/tcl.m4 | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/win/configure b/win/configure index f4d0448..f0159d1 100755 --- a/win/configure +++ b/win/configure @@ -5011,8 +5011,8 @@ $as_echo "Found INFO Zip in environment" >&6; } # It is not an error if an installed version of Zip can't be located. # We can use the locally distributed minizip instead ZIP_PROG="../minizip${EXEEXT_FOR_BUILD}" - ZIP_PROG_OPTIONS="\"-o\"" - ZIP_PROG_VFSSEARCH="\"`find . -type f`\"" + ZIP_PROG_OPTIONS="-o" + ZIP_PROG_VFSSEARCH="\"\`find . -type f\`\"" ZIP_INSTALL_OBJS="minizip${EXEEXT_FOR_BUILD}" { $as_echo "$as_me:${as_lineno-$LINENO}: result: No zip found on PATH building minizip" >&5 $as_echo "No zip found on PATH building minizip" >&6; } diff --git a/win/tcl.m4 b/win/tcl.m4 index ecfcd52..c56cd09 100644 --- a/win/tcl.m4 +++ b/win/tcl.m4 @@ -1424,8 +1424,8 @@ AC_DEFUN([SC_ZIPFS_SUPPORT], [ # It is not an error if an installed version of Zip can't be located. # We can use the locally distributed minizip instead ZIP_PROG="../minizip${EXEEXT_FOR_BUILD}" - ZIP_PROG_OPTIONS="\"-o\"" - ZIP_PROG_VFSSEARCH="\"`find . -type f`\"" + ZIP_PROG_OPTIONS="-o" + ZIP_PROG_VFSSEARCH="\"\`find . -type f\`\"" ZIP_INSTALL_OBJS="minizip${EXEEXT_FOR_BUILD}" AC_MSG_RESULT([No zip found on PATH building minizip]) fi -- cgit v0.12 From d7b40297d2ec40549321631ce061f496a14b4f46 Mon Sep 17 00:00:00 2001 From: tne Date: Tue, 21 Nov 2017 01:14:05 +0000 Subject: Final tweaks to make "./tclsh install" work properly on Windows NOTE: We still seem to be screwing up minizip on MinGW. the `find . -type f` substitution is not working --- generic/tclZipfs.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c index 2e24afe..a954dd6 100644 --- a/generic/tclZipfs.c +++ b/generic/tclZipfs.c @@ -4059,11 +4059,13 @@ int TclZipfs_AppHook(int *argc, char ***argv) if(strcmp(archive,"install")==0) { /* If the first argument is mkzip, run the mkzip program */ Tcl_Obj *vfsinitscript; - - vfsinitscript=Tcl_NewStringObj(ZIPFS_ZIP_MOUNT "/tcl_library/install.tcl",-1); - Tcl_IncrRefCount(vfsinitscript); /* Run this now to ensure the file is present by the time Tcl_Main wants it */ TclZipfs_TclLibrary(); + vfsinitscript=Tcl_NewStringObj(ZIPFS_ZIP_MOUNT "/tcl_library/install.tcl",-1); + Tcl_IncrRefCount(vfsinitscript); + if(Tcl_FSAccess(vfsinitscript,F_OK)==0) { + Tcl_SetStartupScript(vfsinitscript,NULL); + } return TCL_OK; } else { if(!TclZipfs_Mount(NULL, archive, ZIPFS_APP_MOUNT, NULL)) { -- cgit v0.12 From d8a921174ea67582c89d57f5e1b8d072acfd462c Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Tue, 21 Nov 2017 04:07:45 +0000 Subject: Added an implementation of tinydir.h, and spliced it into minizip to allow minizip to recurse directory structures (and get us out of having to feed `find` via autoconf) --- compat/zlib/contrib/minizip/minizip.c | 264 ++++++----- compat/zlib/contrib/minizip/tinydir.h | 816 ++++++++++++++++++++++++++++++++++ unix/configure | 4 +- unix/tcl.m4 | 4 +- win/configure | 4 +- win/tcl.m4 | 4 +- 6 files changed, 975 insertions(+), 121 deletions(-) create mode 100755 compat/zlib/contrib/minizip/tinydir.h diff --git a/compat/zlib/contrib/minizip/minizip.c b/compat/zlib/contrib/minizip/minizip.c index 4288962..b5c67cc 100644 --- a/compat/zlib/contrib/minizip/minizip.c +++ b/compat/zlib/contrib/minizip/minizip.c @@ -12,7 +12,6 @@ Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) */ - #if (!defined(_WIN32)) && (!defined(WIN32)) && (!defined(__APPLE__)) #ifndef __USE_FILE_OFFSET64 #define __USE_FILE_OFFSET64 @@ -39,8 +38,7 @@ #define FSEEKO_FUNC(stream, offset, origin) fseeko64(stream, offset, origin) #endif - - +#include "tinydir.h" #include #include #include @@ -172,6 +170,7 @@ void do_banner() void do_help() { printf("Usage : minizip [-o] [-a] [-0 to -9] [-p password] [-j] file.zip [files_to_add]\n\n" \ + " -r Scan directories recursively\n" \ " -o Overwrite existing file.zip\n" \ " -a Append to existing file.zip\n" \ " -0 Store only\n" \ @@ -243,12 +242,153 @@ int isLargeFile(const char* filename) return largeFile; } +void addFileToZip(zipFile zf, const char *filenameinzip, const char *password, int opt_exclude_path,int opt_compress_level) { + FILE * fin; + int size_read; + const char *savefilenameinzip; + zip_fileinfo zi; + unsigned long crcFile=0; + int zip64 = 0; + int err=0; + int size_buf=WRITEBUFFERSIZE; + unsigned char buf[WRITEBUFFERSIZE]; + zi.tmz_date.tm_sec = zi.tmz_date.tm_min = zi.tmz_date.tm_hour = + zi.tmz_date.tm_mday = zi.tmz_date.tm_mon = zi.tmz_date.tm_year = 0; + zi.dosDate = 0; + zi.internal_fa = 0; + zi.external_fa = 0; + filetime(filenameinzip,&zi.tmz_date,&zi.dosDate); + +/* + err = zipOpenNewFileInZip(zf,filenameinzip,&zi, + NULL,0,NULL,0,NULL / * comment * /, + (opt_compress_level != 0) ? Z_DEFLATED : 0, + opt_compress_level); +*/ + if ((password != NULL) && (err==ZIP_OK)) + err = getFileCrc(filenameinzip,buf,size_buf,&crcFile); + + zip64 = isLargeFile(filenameinzip); + + /* The path name saved, should not include a leading slash. */ + /*if it did, windows/xp and dynazip couldn't read the zip file. */ + savefilenameinzip = filenameinzip; + while( savefilenameinzip[0] == '\\' || savefilenameinzip[0] == '/' ) + { + savefilenameinzip++; + } + + /*should the zip file contain any path at all?*/ + if( opt_exclude_path ) + { + const char *tmpptr; + const char *lastslash = 0; + for( tmpptr = savefilenameinzip; *tmpptr; tmpptr++) + { + if( *tmpptr == '\\' || *tmpptr == '/') + { + lastslash = tmpptr; + } + } + if( lastslash != NULL ) + { + savefilenameinzip = lastslash+1; // base filename follows last slash. + } + } + + /**/ + err = zipOpenNewFileInZip3_64(zf,savefilenameinzip,&zi, + NULL,0,NULL,0,NULL /* comment*/, + (opt_compress_level != 0) ? Z_DEFLATED : 0, + opt_compress_level,0, + /* -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, */ + -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, + password,crcFile, zip64); + + if (err != ZIP_OK) + printf("error in opening %s in zipfile\n",filenameinzip); + else + { + fin = FOPEN_FUNC(filenameinzip,"rb"); + if (fin==NULL) + { + err=ZIP_ERRNO; + printf("error in opening %s for reading\n",filenameinzip); + } + } + + if (err == ZIP_OK) + do + { + err = ZIP_OK; + size_read = (int)fread(buf,1,size_buf,fin); + if (size_read < size_buf) + if (feof(fin)==0) + { + printf("error in reading %s\n",filenameinzip); + err = ZIP_ERRNO; + } + + if (size_read>0) + { + err = zipWriteInFileInZip (zf,buf,size_read); + if (err<0) + { + printf("error in writing %s in the zipfile\n", + filenameinzip); + } + + } + } while ((err == ZIP_OK) && (size_read>0)); + + if (fin) + fclose(fin); + + if (err<0) + err=ZIP_ERRNO; + else + { + err = zipCloseFileInZip(zf); + if (err!=ZIP_OK) + printf("error in closing %s in the zipfile\n", + filenameinzip); + } +} + + +void addPathToZip(zipFile zf, const char *filenameinzip, const char *password, int opt_exclude_path,int opt_compress_level) { + tinydir_dir dir; + int i; + char *newname[512]; + + tinydir_open_sorted(&dir, filenameinzip); + + for (i = 0; i < dir.n_files; i++) + { + tinydir_file file; + tinydir_readfile_n(&dir, &file, i); + if(strcmp(file.name,".")==0) continue; + if(strcmp(file.name,"..")==0) continue; + sprintf(newname,"%s/%s",dir.path,file.name); + if (file.is_dir) + { + addPathToZip(zf,newname,password,opt_exclude_path,opt_compress_level); + } else { + addFileToZip(zf,newname,password,opt_exclude_path,opt_compress_level); + } + } + + tinydir_close(&dir); +} + + int main(argc,argv) int argc; char *argv[]; { int i; - int opt_overwrite=0; + int opt_recursive=0; + int opt_overwrite=1; int opt_compress_level=Z_DEFAULT_COMPRESSION; int opt_exclude_path=0; int zipfilenamearg = 0; @@ -285,7 +425,8 @@ int main(argc,argv) opt_compress_level = c-'0'; if ((c=='j') || (c=='J')) opt_exclude_path = 1; - + if ((c=='r') || (c=='R')) + opt_recursive = 1; if (((c=='p') || (c=='P')) && (i+1='0') || (argv[i][1]<='9'))) && (strlen(argv[i]) == 2))) { - FILE * fin; - int size_read; - const char* filenameinzip = argv[i]; - const char *savefilenameinzip; - zip_fileinfo zi; - unsigned long crcFile=0; - int zip64 = 0; - - zi.tmz_date.tm_sec = zi.tmz_date.tm_min = zi.tmz_date.tm_hour = - zi.tmz_date.tm_mday = zi.tmz_date.tm_mon = zi.tmz_date.tm_year = 0; - zi.dosDate = 0; - zi.internal_fa = 0; - zi.external_fa = 0; - filetime(filenameinzip,&zi.tmz_date,&zi.dosDate); - -/* - err = zipOpenNewFileInZip(zf,filenameinzip,&zi, - NULL,0,NULL,0,NULL / * comment * /, - (opt_compress_level != 0) ? Z_DEFLATED : 0, - opt_compress_level); -*/ - if ((password != NULL) && (err==ZIP_OK)) - err = getFileCrc(filenameinzip,buf,size_buf,&crcFile); - - zip64 = isLargeFile(filenameinzip); - - /* The path name saved, should not include a leading slash. */ - /*if it did, windows/xp and dynazip couldn't read the zip file. */ - savefilenameinzip = filenameinzip; - while( savefilenameinzip[0] == '\\' || savefilenameinzip[0] == '/' ) - { - savefilenameinzip++; - } - - /*should the zip file contain any path at all?*/ - if( opt_exclude_path ) - { - const char *tmpptr; - const char *lastslash = 0; - for( tmpptr = savefilenameinzip; *tmpptr; tmpptr++) - { - if( *tmpptr == '\\' || *tmpptr == '/') - { - lastslash = tmpptr; - } - } - if( lastslash != NULL ) - { - savefilenameinzip = lastslash+1; // base filename follows last slash. - } - } - - /**/ - err = zipOpenNewFileInZip3_64(zf,savefilenameinzip,&zi, - NULL,0,NULL,0,NULL /* comment*/, - (opt_compress_level != 0) ? Z_DEFLATED : 0, - opt_compress_level,0, - /* -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, */ - -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, - password,crcFile, zip64); - - if (err != ZIP_OK) - printf("error in opening %s in zipfile\n",filenameinzip); - else - { - fin = FOPEN_FUNC(filenameinzip,"rb"); - if (fin==NULL) - { - err=ZIP_ERRNO; - printf("error in opening %s for reading\n",filenameinzip); - } - } - - if (err == ZIP_OK) - do - { - err = ZIP_OK; - size_read = (int)fread(buf,1,size_buf,fin); - if (size_read < size_buf) - if (feof(fin)==0) - { - printf("error in reading %s\n",filenameinzip); - err = ZIP_ERRNO; - } - - if (size_read>0) - { - err = zipWriteInFileInZip (zf,buf,size_read); - if (err<0) - { - printf("error in writing %s in the zipfile\n", - filenameinzip); - } - - } - } while ((err == ZIP_OK) && (size_read>0)); - - if (fin) - fclose(fin); - - if (err<0) - err=ZIP_ERRNO; - else - { - err = zipCloseFileInZip(zf); - if (err!=ZIP_OK) - printf("error in closing %s in the zipfile\n", - filenameinzip); + if(opt_recursive) { + addPathToZip(zf,argv[i],password,opt_exclude_path,opt_compress_level); + } else { + addFileToZip(zf,argv[i],password,opt_exclude_path,opt_compress_level); } } } diff --git a/compat/zlib/contrib/minizip/tinydir.h b/compat/zlib/contrib/minizip/tinydir.h new file mode 100755 index 0000000..eb34399 --- /dev/null +++ b/compat/zlib/contrib/minizip/tinydir.h @@ -0,0 +1,816 @@ +/* +Copyright (c) 2013-2017, tinydir authors: +- Cong Xu +- Lautis Sun +- Baudouin Feildel +- Andargor +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +#ifndef TINYDIR_H +#define TINYDIR_H + +#ifdef __cplusplus +extern "C" { +#endif + +#if ((defined _UNICODE) && !(defined UNICODE)) +#define UNICODE +#endif + +#if ((defined UNICODE) && !(defined _UNICODE)) +#define _UNICODE +#endif + +#include +#include +#include +#ifdef _MSC_VER +# define WIN32_LEAN_AND_MEAN +# include +# include +# pragma warning(push) +# pragma warning (disable : 4996) +#else +# include +# include +# include +# include +#endif +#ifdef __MINGW32__ +# include +#endif + + +/* types */ + +/* Windows UNICODE wide character support */ +#if defined _MSC_VER || defined __MINGW32__ +# define _tinydir_char_t TCHAR +# define TINYDIR_STRING(s) _TEXT(s) +# define _tinydir_strlen _tcslen +# define _tinydir_strcpy _tcscpy +# define _tinydir_strcat _tcscat +# define _tinydir_strcmp _tcscmp +# define _tinydir_strrchr _tcsrchr +# define _tinydir_strncmp _tcsncmp +#else +# define _tinydir_char_t char +# define TINYDIR_STRING(s) s +# define _tinydir_strlen strlen +# define _tinydir_strcpy strcpy +# define _tinydir_strcat strcat +# define _tinydir_strcmp strcmp +# define _tinydir_strrchr strrchr +# define _tinydir_strncmp strncmp +#endif + +#if (defined _MSC_VER || defined __MINGW32__) +# include +# define _TINYDIR_PATH_MAX MAX_PATH +#elif defined __linux__ +# include +# define _TINYDIR_PATH_MAX PATH_MAX +#elif defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) +# include +# if defined(BSD) +# include +# define _TINYDIR_PATH_MAX PATH_MAX +# endif +#endif + +#ifndef _TINYDIR_PATH_MAX +#define _TINYDIR_PATH_MAX 4096 +#endif + +#ifdef _MSC_VER +/* extra chars for the "\\*" mask */ +# define _TINYDIR_PATH_EXTRA 2 +#else +# define _TINYDIR_PATH_EXTRA 0 +#endif + +#define _TINYDIR_FILENAME_MAX 256 + +#if (defined _MSC_VER || defined __MINGW32__) +#define _TINYDIR_DRIVE_MAX 3 +#endif + +#ifdef _MSC_VER +# define _TINYDIR_FUNC static __inline +#elif !defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L +# define _TINYDIR_FUNC static __inline__ +#else +# define _TINYDIR_FUNC static inline +#endif + +/* readdir_r usage; define TINYDIR_USE_READDIR_R to use it (if supported) */ +#ifdef TINYDIR_USE_READDIR_R + +/* readdir_r is a POSIX-only function, and may not be available under various + * environments/settings, e.g. MinGW. Use readdir fallback */ +#if _POSIX_C_SOURCE >= 1 || _XOPEN_SOURCE || _BSD_SOURCE || _SVID_SOURCE ||\ + _POSIX_SOURCE +# define _TINYDIR_HAS_READDIR_R +#endif +#if _POSIX_C_SOURCE >= 200112L +# define _TINYDIR_HAS_FPATHCONF +# include +#endif +#if _BSD_SOURCE || _SVID_SOURCE || \ + (_POSIX_C_SOURCE >= 200809L || _XOPEN_SOURCE >= 700) +# define _TINYDIR_HAS_DIRFD +# include +#endif +#if defined _TINYDIR_HAS_FPATHCONF && defined _TINYDIR_HAS_DIRFD &&\ + defined _PC_NAME_MAX +# define _TINYDIR_USE_FPATHCONF +#endif +#if defined __MINGW32__ || !defined _TINYDIR_HAS_READDIR_R ||\ + !(defined _TINYDIR_USE_FPATHCONF || defined NAME_MAX) +# define _TINYDIR_USE_READDIR +#endif + +/* Use readdir by default */ +#else +# define _TINYDIR_USE_READDIR +#endif + +/* MINGW32 has two versions of dirent, ASCII and UNICODE*/ +#ifndef _MSC_VER +#if (defined __MINGW32__) && (defined _UNICODE) +#define _TINYDIR_DIR _WDIR +#define _tinydir_dirent _wdirent +#define _tinydir_opendir _wopendir +#define _tinydir_readdir _wreaddir +#define _tinydir_closedir _wclosedir +#else +#define _TINYDIR_DIR DIR +#define _tinydir_dirent dirent +#define _tinydir_opendir opendir +#define _tinydir_readdir readdir +#define _tinydir_closedir closedir +#endif +#endif + +/* Allow user to use a custom allocator by defining _TINYDIR_MALLOC and _TINYDIR_FREE. */ +#if defined(_TINYDIR_MALLOC) && defined(_TINYDIR_FREE) +#elif !defined(_TINYDIR_MALLOC) && !defined(_TINYDIR_FREE) +#else +#error "Either define both alloc and free or none of them!" +#endif + +#if !defined(_TINYDIR_MALLOC) + #define _TINYDIR_MALLOC(_size) malloc(_size) + #define _TINYDIR_FREE(_ptr) free(_ptr) +#endif /* !defined(_TINYDIR_MALLOC) */ + +typedef struct tinydir_file +{ + _tinydir_char_t path[_TINYDIR_PATH_MAX]; + _tinydir_char_t name[_TINYDIR_FILENAME_MAX]; + _tinydir_char_t *extension; + int is_dir; + int is_reg; + +#ifndef _MSC_VER +#ifdef __MINGW32__ + struct _stat _s; +#else + struct stat _s; +#endif +#endif +} tinydir_file; + +typedef struct tinydir_dir +{ + _tinydir_char_t path[_TINYDIR_PATH_MAX]; + int has_next; + size_t n_files; + + tinydir_file *_files; +#ifdef _MSC_VER + HANDLE _h; + WIN32_FIND_DATA _f; +#else + _TINYDIR_DIR *_d; + struct _tinydir_dirent *_e; +#ifndef _TINYDIR_USE_READDIR + struct _tinydir_dirent *_ep; +#endif +#endif +} tinydir_dir; + + +/* declarations */ + +_TINYDIR_FUNC +int tinydir_open(tinydir_dir *dir, const _tinydir_char_t *path); +_TINYDIR_FUNC +int tinydir_open_sorted(tinydir_dir *dir, const _tinydir_char_t *path); +_TINYDIR_FUNC +void tinydir_close(tinydir_dir *dir); + +_TINYDIR_FUNC +int tinydir_next(tinydir_dir *dir); +_TINYDIR_FUNC +int tinydir_readfile(const tinydir_dir *dir, tinydir_file *file); +_TINYDIR_FUNC +int tinydir_readfile_n(const tinydir_dir *dir, tinydir_file *file, size_t i); +_TINYDIR_FUNC +int tinydir_open_subdir_n(tinydir_dir *dir, size_t i); + +_TINYDIR_FUNC +int tinydir_file_open(tinydir_file *file, const _tinydir_char_t *path); +_TINYDIR_FUNC +void _tinydir_get_ext(tinydir_file *file); +_TINYDIR_FUNC +int _tinydir_file_cmp(const void *a, const void *b); +#ifndef _MSC_VER +#ifndef _TINYDIR_USE_READDIR +_TINYDIR_FUNC +size_t _tinydir_dirent_buf_size(_TINYDIR_DIR *dirp); +#endif +#endif + + +/* definitions*/ + +_TINYDIR_FUNC +int tinydir_open(tinydir_dir *dir, const _tinydir_char_t *path) +{ +#ifndef _MSC_VER +#ifndef _TINYDIR_USE_READDIR + int error; + int size; /* using int size */ +#endif +#else + _tinydir_char_t path_buf[_TINYDIR_PATH_MAX]; +#endif + _tinydir_char_t *pathp; + + if (dir == NULL || path == NULL || _tinydir_strlen(path) == 0) + { + errno = EINVAL; + return -1; + } + if (_tinydir_strlen(path) + _TINYDIR_PATH_EXTRA >= _TINYDIR_PATH_MAX) + { + errno = ENAMETOOLONG; + return -1; + } + + /* initialise dir */ + dir->_files = NULL; +#ifdef _MSC_VER + dir->_h = INVALID_HANDLE_VALUE; +#else + dir->_d = NULL; +#ifndef _TINYDIR_USE_READDIR + dir->_ep = NULL; +#endif +#endif + tinydir_close(dir); + + _tinydir_strcpy(dir->path, path); + /* Remove trailing slashes */ + pathp = &dir->path[_tinydir_strlen(dir->path) - 1]; + while (pathp != dir->path && (*pathp == TINYDIR_STRING('\\') || *pathp == TINYDIR_STRING('/'))) + { + *pathp = TINYDIR_STRING('\0'); + pathp++; + } +#ifdef _MSC_VER + _tinydir_strcpy(path_buf, dir->path); + _tinydir_strcat(path_buf, TINYDIR_STRING("\\*")); +#if (defined WINAPI_FAMILY) && (WINAPI_FAMILY != WINAPI_FAMILY_DESKTOP_APP) + dir->_h = FindFirstFileEx(path_buf, FindExInfoStandard, &dir->_f, FindExSearchNameMatch, NULL, 0); +#else + dir->_h = FindFirstFile(path_buf, &dir->_f); +#endif + if (dir->_h == INVALID_HANDLE_VALUE) + { + errno = ENOENT; +#else + dir->_d = _tinydir_opendir(path); + if (dir->_d == NULL) + { +#endif + goto bail; + } + + /* read first file */ + dir->has_next = 1; +#ifndef _MSC_VER +#ifdef _TINYDIR_USE_READDIR + dir->_e = _tinydir_readdir(dir->_d); +#else + /* allocate dirent buffer for readdir_r */ + size = _tinydir_dirent_buf_size(dir->_d); /* conversion to int */ + if (size == -1) return -1; + dir->_ep = (struct _tinydir_dirent*)_TINYDIR_MALLOC(size); + if (dir->_ep == NULL) return -1; + + error = readdir_r(dir->_d, dir->_ep, &dir->_e); + if (error != 0) return -1; +#endif + if (dir->_e == NULL) + { + dir->has_next = 0; + } +#endif + + return 0; + +bail: + tinydir_close(dir); + return -1; +} + +_TINYDIR_FUNC +int tinydir_open_sorted(tinydir_dir *dir, const _tinydir_char_t *path) +{ + /* Count the number of files first, to pre-allocate the files array */ + size_t n_files = 0; + if (tinydir_open(dir, path) == -1) + { + return -1; + } + while (dir->has_next) + { + n_files++; + if (tinydir_next(dir) == -1) + { + goto bail; + } + } + tinydir_close(dir); + + if (tinydir_open(dir, path) == -1) + { + return -1; + } + + dir->n_files = 0; + dir->_files = (tinydir_file *)_TINYDIR_MALLOC(sizeof *dir->_files * n_files); + if (dir->_files == NULL) + { + goto bail; + } + while (dir->has_next) + { + tinydir_file *p_file; + dir->n_files++; + + p_file = &dir->_files[dir->n_files - 1]; + if (tinydir_readfile(dir, p_file) == -1) + { + goto bail; + } + + if (tinydir_next(dir) == -1) + { + goto bail; + } + + /* Just in case the number of files has changed between the first and + second reads, terminate without writing into unallocated memory */ + if (dir->n_files == n_files) + { + break; + } + } + + qsort(dir->_files, dir->n_files, sizeof(tinydir_file), _tinydir_file_cmp); + + return 0; + +bail: + tinydir_close(dir); + return -1; +} + +_TINYDIR_FUNC +void tinydir_close(tinydir_dir *dir) +{ + if (dir == NULL) + { + return; + } + + memset(dir->path, 0, sizeof(dir->path)); + dir->has_next = 0; + dir->n_files = 0; + _TINYDIR_FREE(dir->_files); + dir->_files = NULL; +#ifdef _MSC_VER + if (dir->_h != INVALID_HANDLE_VALUE) + { + FindClose(dir->_h); + } + dir->_h = INVALID_HANDLE_VALUE; +#else + if (dir->_d) + { + _tinydir_closedir(dir->_d); + } + dir->_d = NULL; + dir->_e = NULL; +#ifndef _TINYDIR_USE_READDIR + _TINYDIR_FREE(dir->_ep); + dir->_ep = NULL; +#endif +#endif +} + +_TINYDIR_FUNC +int tinydir_next(tinydir_dir *dir) +{ + if (dir == NULL) + { + errno = EINVAL; + return -1; + } + if (!dir->has_next) + { + errno = ENOENT; + return -1; + } + +#ifdef _MSC_VER + if (FindNextFile(dir->_h, &dir->_f) == 0) +#else +#ifdef _TINYDIR_USE_READDIR + dir->_e = _tinydir_readdir(dir->_d); +#else + if (dir->_ep == NULL) + { + return -1; + } + if (readdir_r(dir->_d, dir->_ep, &dir->_e) != 0) + { + return -1; + } +#endif + if (dir->_e == NULL) +#endif + { + dir->has_next = 0; +#ifdef _MSC_VER + if (GetLastError() != ERROR_SUCCESS && + GetLastError() != ERROR_NO_MORE_FILES) + { + tinydir_close(dir); + errno = EIO; + return -1; + } +#endif + } + + return 0; +} + +_TINYDIR_FUNC +int tinydir_readfile(const tinydir_dir *dir, tinydir_file *file) +{ + if (dir == NULL || file == NULL) + { + errno = EINVAL; + return -1; + } +#ifdef _MSC_VER + if (dir->_h == INVALID_HANDLE_VALUE) +#else + if (dir->_e == NULL) +#endif + { + errno = ENOENT; + return -1; + } + if (_tinydir_strlen(dir->path) + + _tinydir_strlen( +#ifdef _MSC_VER + dir->_f.cFileName +#else + dir->_e->d_name +#endif + ) + 1 + _TINYDIR_PATH_EXTRA >= + _TINYDIR_PATH_MAX) + { + /* the path for the file will be too long */ + errno = ENAMETOOLONG; + return -1; + } + if (_tinydir_strlen( +#ifdef _MSC_VER + dir->_f.cFileName +#else + dir->_e->d_name +#endif + ) >= _TINYDIR_FILENAME_MAX) + { + errno = ENAMETOOLONG; + return -1; + } + + _tinydir_strcpy(file->path, dir->path); + _tinydir_strcat(file->path, TINYDIR_STRING("/")); + _tinydir_strcpy(file->name, +#ifdef _MSC_VER + dir->_f.cFileName +#else + dir->_e->d_name +#endif + ); + _tinydir_strcat(file->path, file->name); +#ifndef _MSC_VER +#ifdef __MINGW32__ + if (_tstat( +#else + if (stat( +#endif + file->path, &file->_s) == -1) + { + return -1; + } +#endif + _tinydir_get_ext(file); + + file->is_dir = +#ifdef _MSC_VER + !!(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY); +#else + S_ISDIR(file->_s.st_mode); +#endif + file->is_reg = +#ifdef _MSC_VER + !!(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_NORMAL) || + ( + !(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_DEVICE) && + !(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && + !(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_ENCRYPTED) && +#ifdef FILE_ATTRIBUTE_INTEGRITY_STREAM + !(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_INTEGRITY_STREAM) && +#endif +#ifdef FILE_ATTRIBUTE_NO_SCRUB_DATA + !(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_NO_SCRUB_DATA) && +#endif + !(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_OFFLINE) && + !(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_TEMPORARY)); +#else + S_ISREG(file->_s.st_mode); +#endif + + return 0; +} + +_TINYDIR_FUNC +int tinydir_readfile_n(const tinydir_dir *dir, tinydir_file *file, size_t i) +{ + if (dir == NULL || file == NULL) + { + errno = EINVAL; + return -1; + } + if (i >= dir->n_files) + { + errno = ENOENT; + return -1; + } + + memcpy(file, &dir->_files[i], sizeof(tinydir_file)); + _tinydir_get_ext(file); + + return 0; +} + +_TINYDIR_FUNC +int tinydir_open_subdir_n(tinydir_dir *dir, size_t i) +{ + _tinydir_char_t path[_TINYDIR_PATH_MAX]; + if (dir == NULL) + { + errno = EINVAL; + return -1; + } + if (i >= dir->n_files || !dir->_files[i].is_dir) + { + errno = ENOENT; + return -1; + } + + _tinydir_strcpy(path, dir->_files[i].path); + tinydir_close(dir); + if (tinydir_open_sorted(dir, path) == -1) + { + return -1; + } + + return 0; +} + +/* Open a single file given its path */ +_TINYDIR_FUNC +int tinydir_file_open(tinydir_file *file, const _tinydir_char_t *path) +{ + tinydir_dir dir; + int result = 0; + int found = 0; + _tinydir_char_t dir_name_buf[_TINYDIR_PATH_MAX]; + _tinydir_char_t file_name_buf[_TINYDIR_FILENAME_MAX]; + _tinydir_char_t *dir_name; + _tinydir_char_t *base_name; +#if (defined _MSC_VER || defined __MINGW32__) + _tinydir_char_t drive_buf[_TINYDIR_PATH_MAX]; + _tinydir_char_t ext_buf[_TINYDIR_FILENAME_MAX]; +#endif + + if (file == NULL || path == NULL || _tinydir_strlen(path) == 0) + { + errno = EINVAL; + return -1; + } + if (_tinydir_strlen(path) + _TINYDIR_PATH_EXTRA >= _TINYDIR_PATH_MAX) + { + errno = ENAMETOOLONG; + return -1; + } + + /* Get the parent path */ +#if (defined _MSC_VER || defined __MINGW32__) +#if ((defined _MSC_VER) && (_MSC_VER >= 1400)) + _tsplitpath_s( + path, + drive_buf, _TINYDIR_DRIVE_MAX, + dir_name_buf, _TINYDIR_FILENAME_MAX, + file_name_buf, _TINYDIR_FILENAME_MAX, + ext_buf, _TINYDIR_FILENAME_MAX); +#else + _tsplitpath( + path, + drive_buf, + dir_name_buf, + file_name_buf, + ext_buf); +#endif + +/* _splitpath_s not work fine with only filename and widechar support */ +#ifdef _UNICODE + if (drive_buf[0] == L'\xFEFE') + drive_buf[0] = '\0'; + if (dir_name_buf[0] == L'\xFEFE') + dir_name_buf[0] = '\0'; +#endif + + if (errno) + { + errno = EINVAL; + return -1; + } + /* Emulate the behavior of dirname by returning "." for dir name if it's + empty */ + if (drive_buf[0] == '\0' && dir_name_buf[0] == '\0') + { + _tinydir_strcpy(dir_name_buf, TINYDIR_STRING(".")); + } + /* Concatenate the drive letter and dir name to form full dir name */ + _tinydir_strcat(drive_buf, dir_name_buf); + dir_name = drive_buf; + /* Concatenate the file name and extension to form base name */ + _tinydir_strcat(file_name_buf, ext_buf); + base_name = file_name_buf; +#else + _tinydir_strcpy(dir_name_buf, path); + dir_name = dirname(dir_name_buf); + _tinydir_strcpy(file_name_buf, path); + base_name =basename(file_name_buf); +#endif + + /* Open the parent directory */ + if (tinydir_open(&dir, dir_name) == -1) + { + return -1; + } + + /* Read through the parent directory and look for the file */ + while (dir.has_next) + { + if (tinydir_readfile(&dir, file) == -1) + { + result = -1; + goto bail; + } + if (_tinydir_strcmp(file->name, base_name) == 0) + { + /* File found */ + found = 1; + break; + } + tinydir_next(&dir); + } + if (!found) + { + result = -1; + errno = ENOENT; + } + +bail: + tinydir_close(&dir); + return result; +} + +_TINYDIR_FUNC +void _tinydir_get_ext(tinydir_file *file) +{ + _tinydir_char_t *period = _tinydir_strrchr(file->name, TINYDIR_STRING('.')); + if (period == NULL) + { + file->extension = &(file->name[_tinydir_strlen(file->name)]); + } + else + { + file->extension = period + 1; + } +} + +_TINYDIR_FUNC +int _tinydir_file_cmp(const void *a, const void *b) +{ + const tinydir_file *fa = (const tinydir_file *)a; + const tinydir_file *fb = (const tinydir_file *)b; + if (fa->is_dir != fb->is_dir) + { + return -(fa->is_dir - fb->is_dir); + } + return _tinydir_strncmp(fa->name, fb->name, _TINYDIR_FILENAME_MAX); +} + +#ifndef _MSC_VER +#ifndef _TINYDIR_USE_READDIR +/* +The following authored by Ben Hutchings +from https://womble.decadent.org.uk/readdir_r-advisory.html +*/ +/* Calculate the required buffer size (in bytes) for directory * +* entries read from the given directory handle. Return -1 if this * +* this cannot be done. * +* * +* This code does not trust values of NAME_MAX that are less than * +* 255, since some systems (including at least HP-UX) incorrectly * +* define it to be a smaller value. */ +_TINYDIR_FUNC +size_t _tinydir_dirent_buf_size(_TINYDIR_DIR *dirp) +{ + long name_max; + size_t name_end; + /* parameter may be unused */ + (void)dirp; + +#if defined _TINYDIR_USE_FPATHCONF + name_max = fpathconf(dirfd(dirp), _PC_NAME_MAX); + if (name_max == -1) +#if defined(NAME_MAX) + name_max = (NAME_MAX > 255) ? NAME_MAX : 255; +#else + return (size_t)(-1); +#endif +#elif defined(NAME_MAX) + name_max = (NAME_MAX > 255) ? NAME_MAX : 255; +#else +#error "buffer size for readdir_r cannot be determined" +#endif + name_end = (size_t)offsetof(struct _tinydir_dirent, d_name) + name_max + 1; + return (name_end > sizeof(struct _tinydir_dirent) ? + name_end : sizeof(struct _tinydir_dirent)); +} +#endif +#endif + +#ifdef __cplusplus +} +#endif + +# if defined (_MSC_VER) +# pragma warning(pop) +# endif + +#endif diff --git a/unix/configure b/unix/configure index 53e0a07..08c97e9 100755 --- a/unix/configure +++ b/unix/configure @@ -10286,8 +10286,8 @@ $as_echo "Found INFO Zip in environment" >&6; } # It is not an error if an installed version of Zip can't be located. # We can use the locally distributed minizip instead ZIP_PROG="../minizip${EXEEXT_FOR_BUILD}" - ZIP_PROG_OPTIONS="-o" - ZIP_PROG_VFSSEARCH="\"`find . -type f`\"" + ZIP_PROG_OPTIONS="-o -r" + ZIP_PROG_VFSSEARCH="." ZIP_INSTALL_OBJS="minizip${EXEEXT_FOR_BUILD}" { $as_echo "$as_me:${as_lineno-$LINENO}: result: No zip found on PATH building minizip" >&5 $as_echo "No zip found on PATH building minizip" >&6; } diff --git a/unix/tcl.m4 b/unix/tcl.m4 index dbc92da..81c0601 100644 --- a/unix/tcl.m4 +++ b/unix/tcl.m4 @@ -3136,8 +3136,8 @@ AC_DEFUN([SC_ZIPFS_SUPPORT], [ # It is not an error if an installed version of Zip can't be located. # We can use the locally distributed minizip instead ZIP_PROG="../minizip${EXEEXT_FOR_BUILD}" - ZIP_PROG_OPTIONS="-o" - ZIP_PROG_VFSSEARCH="\"`find . -type f`\"" + ZIP_PROG_OPTIONS="-o -r" + ZIP_PROG_VFSSEARCH="." ZIP_INSTALL_OBJS="minizip${EXEEXT_FOR_BUILD}" AC_MSG_RESULT([No zip found on PATH building minizip]) fi diff --git a/win/configure b/win/configure index f0159d1..bc851bc 100755 --- a/win/configure +++ b/win/configure @@ -5011,8 +5011,8 @@ $as_echo "Found INFO Zip in environment" >&6; } # It is not an error if an installed version of Zip can't be located. # We can use the locally distributed minizip instead ZIP_PROG="../minizip${EXEEXT_FOR_BUILD}" - ZIP_PROG_OPTIONS="-o" - ZIP_PROG_VFSSEARCH="\"\`find . -type f\`\"" + ZIP_PROG_OPTIONS="-o -r" + ZIP_PROG_VFSSEARCH="." ZIP_INSTALL_OBJS="minizip${EXEEXT_FOR_BUILD}" { $as_echo "$as_me:${as_lineno-$LINENO}: result: No zip found on PATH building minizip" >&5 $as_echo "No zip found on PATH building minizip" >&6; } diff --git a/win/tcl.m4 b/win/tcl.m4 index c56cd09..4f5b562 100644 --- a/win/tcl.m4 +++ b/win/tcl.m4 @@ -1424,8 +1424,8 @@ AC_DEFUN([SC_ZIPFS_SUPPORT], [ # It is not an error if an installed version of Zip can't be located. # We can use the locally distributed minizip instead ZIP_PROG="../minizip${EXEEXT_FOR_BUILD}" - ZIP_PROG_OPTIONS="-o" - ZIP_PROG_VFSSEARCH="\"\`find . -type f\`\"" + ZIP_PROG_OPTIONS="-o -r" + ZIP_PROG_VFSSEARCH="." ZIP_INSTALL_OBJS="minizip${EXEEXT_FOR_BUILD}" AC_MSG_RESULT([No zip found on PATH building minizip]) fi -- cgit v0.12 From 334149646f5c9c764a5fd5c7c0c9eaee1d90c04e Mon Sep 17 00:00:00 2001 From: tne Date: Tue, 21 Nov 2017 04:26:37 +0000 Subject: Fixes to "make clean" to do a better job of cleaning up zip files and vfs directories Fixed a type that was keeping minizip from building --- unix/Makefile.in | 24 ++---------------------- win/Makefile.in | 26 ++++---------------------- 2 files changed, 6 insertions(+), 44 deletions(-) diff --git a/unix/Makefile.in b/unix/Makefile.in index 98c5865..d6152a6 100644 --- a/unix/Makefile.in +++ b/unix/Makefile.in @@ -720,7 +720,7 @@ Makefile: $(UNIX_DIR)/Makefile.in $(DLTEST_DIR)/Makefile.in clean: clean-packages rm -rf *.a *.o libtcl* core errs *~ \#* TAGS *.E a.out \ errors ${TCL_EXE} ${TCLTEST_EXE} lib.exp Tcl @DTRACE_HDR@ \ - minizip${EXEEXT_FOR_BUILD} *.${HOST_OBJEXT} + minizip${HOST_EXEEXT} *.${HOST_OBJEXT} *.zip *.vfs cd dltest ; $(MAKE) clean distclean: distclean-packages clean @@ -1864,29 +1864,9 @@ zutil.$(HOST_OBJEXT): minizip.$(HOST_OBJEXT): $(HOST_CC) -o $@ -I$(ZLIB_DIR) -I$(ZLIB_DIR)/contrib/minizip -c $(ZLIB_DIR)/contrib/minizip/minizip.c -minizip${EXEEXT_FOR_BUILD}: $(MINIZIP_OBJS) +minizip${HOST_EXEEXT}: $(MINIZIP_OBJS) $(HOST_CC) -o $@ $(MINIZIP_OBJS) -tclvfs.zip: minizip${EXEEXT_FOR_BUILD} - rm -rf $(TCL_VFS_ROOT) - mkdir -p $(TCL_VFS_PATH) - @for i in "$(TCL_VFS_PATH)"; \ - do \ - if [ ! -d "$$i" ] ; then \ - echo "Making directory $$i"; \ - $(INSTALL_DATA_DIR) "$$i"; \ - else true; \ - fi; \ - done; - cp -a ../library/* $(TCL_VFS_PATH) - (cd $TCL_VFS ROOT ; ./minizip${EXEEXT_FOR_BUILD} -o ../tclvfs.zip `find . -type f`) - -zipsetupstub.$(HOST_OBJEXT): $(COMPAT_DIR)/zipsetupstub.c - $(HOST_CC) -o $@ -I$(ZLIB_DIR) -c $(COMPAT_DIR)/zipsetupstub.c - -zipsetupstub${EXEEXT_FOR_BUILD}: zipsetupstub.$(HOST_OBJEXT) - $(HOST_CC) -o $@ zipsetupstub.$(HOST_OBJEXT) - #-------------------------------------------------------------------------- # Bundled Package targets #-------------------------------------------------------------------------- diff --git a/win/Makefile.in b/win/Makefile.in index 6734985..49f0bfb 100644 --- a/win/Makefile.in +++ b/win/Makefile.in @@ -663,29 +663,9 @@ zutil.$(HOST_OBJEXT): minizip.$(HOST_OBJEXT): $(HOST_CC) -o $@ -I$(ZLIB_DIR) -I$(ZLIB_DIR)/contrib/minizip -c $(ZLIB_DIR)/contrib/minizip/minizip.c -minizip${EXEEXT_FOR_BUILD}: $(MINIZIP_OBJS) +minizip${HOST_EXEEXT}: $(MINIZIP_OBJS) $(HOST_CC) -o $@ $(MINIZIP_OBJS) -tclvfs.zip: minizip${EXEEXT_FOR_BUILD} - rm -rf $(TCL_VFS_ROOT) - mkdir -p $(TCL_VFS_PATH) - @for i in "$(TCL_VFS_PATH)"; \ - do \ - if [ ! -d "$$i" ] ; then \ - echo "Making directory $$i"; \ - $(INSTALL_DATA_DIR) "$$i"; \ - else true; \ - fi; \ - done; - cp -a ../library/* $(TCL_VFS_PATH) - (cd $TCL_VFS ROOT ; ./minizip${EXEEXT_FOR_BUILD} -o ../tclvfs.zip `find . -type f`) - -zipsetupstub.$(HOST_OBJEXT): $(COMPAT_DIR)/zipsetupstub.c - $(HOST_CC) -o $@ -I$(ZLIB_DIR) -c $(COMPAT_DIR)/zipsetupstub.c - -zipsetupstub${EXEEXT_FOR_BUILD}: zipsetupstub.$(HOST_OBJEXT) - $(HOST_CC) -o $@ zipsetupstub.$(HOST_OBJEXT) - # The following target generates the file generic/tclDate.c from the yacc # grammar found in generic/tclGetDate.y. This is only run by hand as yacc is # not available in all environments. The name of the .c file is different than @@ -916,7 +896,9 @@ clean: cleanhelp clean-packages $(RM) *.lib *.a *.exp *.dll *.$(RES) *.${OBJEXT} *~ \#* TAGS a.out $(RM) $(TCLSH) $(CAT32) $(RM) *.pch *.ilk *.pdb - minizip${EXEEXT_FOR_BUILD} *.${HOST_OBJEXT} + $(RM) minizip${HOST_EXEEXT} *.${HOST_OBJEXT} + $(RM) *.zip + $(RMDIR) *.vfs distclean: distclean-packages clean $(RM) Makefile config.status config.cache config.log tclConfig.sh \ -- cgit v0.12 From 35adf8c728b9c0592670777b6beada9fdd6efa70 Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Tue, 21 Nov 2017 14:21:48 +0000 Subject: Removing the pool of literal values within the internals of tclZipfs.c. Replaced with a single pointer to a const string once discovery has sorted out where tcl_library is to be loaded from. Fixed a goof in the build system if tcl is compiled outside of the source directory --- generic/tclZipfs.c | 76 ++++++++++++++---------------------------------------- unix/Makefile.in | 2 +- unix/tcl.pc.in | 2 ++ win/Makefile.in | 2 +- 4 files changed, 23 insertions(+), 59 deletions(-) diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c index a954dd6..03170a1 100644 --- a/generic/tclZipfs.c +++ b/generic/tclZipfs.c @@ -297,11 +297,7 @@ static const unsigned long crc32tab[256] = { 0x2d02ef8d, }; -static Tcl_Obj *zipfs_literal_fstype=NULL; -static Tcl_Obj *zipfs_literal_fsroot=NULL; -static Tcl_Obj *zipfs_literal_fsseparator=NULL; -static Tcl_Obj *zipfs_literal_null=NULL; -static Tcl_Obj *zipfs_literal_tcl_library=NULL; +const char *zipfs_literal_tcl_library=NULL; /* @@ -1440,13 +1436,7 @@ static int ZipFSRootObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { - if(!zipfs_literal_fsroot) { - zipfs_literal_fsroot=Tcl_NewStringObj(ZIPFS_VOLUME, -1); - Tcl_IncrRefCount(zipfs_literal_fsroot); - } - Tcl_IncrRefCount(zipfs_literal_fsroot); - Tcl_SetObjResult(interp,zipfs_literal_fsroot); - return TCL_OK; + return Tcl_NewStringObj(ZIPFS_VOLUME, -1); } /* @@ -2450,12 +2440,7 @@ ZipFSTclLibraryObjCmd(ClientData clientData, Tcl_Interp *interp, Tcl_Obj *pResult; pResult=TclZipfs_TclLibrary(); if(!pResult) { - if(!zipfs_literal_null) { - zipfs_literal_null=Tcl_NewObj(); - Tcl_IncrRefCount(zipfs_literal_null); - } - pResult=zipfs_literal_null; - Tcl_IncrRefCount(zipfs_literal_null); + pResult=Tcl_NewObj(); } Tcl_SetObjResult(interp,pResult); return TCL_OK; @@ -3252,12 +3237,7 @@ Zip_FSAccessProc(Tcl_Obj *pathPtr, int mode) static Tcl_Obj * Zip_FSFilesystemSeparatorProc(Tcl_Obj *pathPtr) { - if(!zipfs_literal_fsseparator) { - zipfs_literal_fsseparator=Tcl_NewStringObj("/", -1); - Tcl_IncrRefCount(zipfs_literal_fsseparator); - } - Tcl_IncrRefCount(zipfs_literal_fsseparator); - return zipfs_literal_fsseparator; + return Tcl_NewStringObj("/", -1); } /* @@ -3518,12 +3498,7 @@ endloop: */ static Tcl_Obj * Zip_FSListVolumesProc(void) { - if(!zipfs_literal_fsroot) { - zipfs_literal_fsroot=Tcl_NewStringObj(ZIPFS_VOLUME, -1); - Tcl_IncrRefCount(zipfs_literal_fsroot); - } - Tcl_IncrRefCount(zipfs_literal_fsroot); - return zipfs_literal_fsroot; + return Tcl_NewStringObj(ZIPFS_VOLUME, -1); } /* @@ -3670,12 +3645,7 @@ Zip_FSFileAttrsSetProc(Tcl_Interp *interp, int index, Tcl_Obj *pathPtr, static Tcl_Obj * Zip_FSFilesystemPathTypeProc(Tcl_Obj *pathPtr) { - if(!zipfs_literal_fstype) { - zipfs_literal_fstype=Tcl_NewStringObj("zip", -1); - Tcl_IncrRefCount(zipfs_literal_fstype); - } - Tcl_IncrRefCount(zipfs_literal_fstype); - return zipfs_literal_fstype; + return Tcl_NewStringObj("zip", -1); } @@ -3959,8 +3929,7 @@ static int TclZipfs_AppHook_FindTclInit(const char *archive){ found=Tcl_FSAccess(vfsinitscript,F_OK); Tcl_DecrRefCount(vfsinitscript); if(found==0) { - zipfs_literal_tcl_library=Tcl_NewStringObj(ZIPFS_ZIP_MOUNT,-1); - Tcl_IncrRefCount(zipfs_literal_tcl_library); + zipfs_literal_tcl_library=ZIPFS_ZIP_MOUNT; return TCL_OK; } vfsinitscript=Tcl_NewStringObj(ZIPFS_ZIP_MOUNT "/tcl_library/init.tcl",-1); @@ -3968,8 +3937,7 @@ static int TclZipfs_AppHook_FindTclInit(const char *archive){ found=Tcl_FSAccess(vfsinitscript,F_OK); Tcl_DecrRefCount(vfsinitscript); if(found==0) { - zipfs_literal_tcl_library=Tcl_NewStringObj(ZIPFS_ZIP_MOUNT "/tcl_library",-1); - Tcl_IncrRefCount(zipfs_literal_tcl_library); + zipfs_literal_tcl_library=ZIPFS_ZIP_MOUNT "/tcl_library"; return TCL_OK; } return TCL_ERROR; @@ -4020,7 +3988,7 @@ int TclZipfs_AppHook(int *argc, char ***argv) " {" ZIPFS_ZIP_MOUNT "/tk_library}\n" " {" ZIPFS_VOLUME "lib/tk/tk_library}\n" "} {\n" -" if {[file exists [file join $path init.tcl]]} continue\n" +" if {![file exists [file join $path init.tcl]]} continue\n" " set ::tk_library $path\n" " break\n" "}\n" @@ -4043,8 +4011,7 @@ int TclZipfs_AppHook(int *argc, char ***argv) found=Tcl_FSAccess(vfsinitscript,F_OK); Tcl_DecrRefCount(vfsinitscript); if(found==TCL_OK) { - zipfs_literal_tcl_library=Tcl_NewStringObj(ZIPFS_APP_MOUNT "/tcl_library",-1); - Tcl_IncrRefCount(zipfs_literal_tcl_library); + zipfs_literal_tcl_library=ZIPFS_APP_MOUNT "/tcl_library"; return TCL_OK; } } @@ -4085,9 +4052,7 @@ int TclZipfs_AppHook(int *argc, char ***argv) found=Tcl_FSAccess(vfsinitscript,F_OK); Tcl_DecrRefCount(vfsinitscript); if(found==TCL_OK) { - zipfs_literal_tcl_library=Tcl_NewStringObj(ZIPFS_APP_MOUNT "/tcl_library",-1); - Tcl_IncrRefCount(zipfs_literal_tcl_library); - zipfs_literal_tcl_library=vfsinitscript; + zipfs_literal_tcl_library=ZIPFS_APP_MOUNT "/tcl_library"; return TCL_OK; } } @@ -4097,10 +4062,7 @@ int TclZipfs_AppHook(int *argc, char ***argv) } Tcl_Obj *TclZipfs_TclLibrary(void) { - if(zipfs_literal_tcl_library) { - Tcl_IncrRefCount(zipfs_literal_tcl_library); - return zipfs_literal_tcl_library; - } else { + if(!zipfs_literal_tcl_library) { #if defined(_WIN32) || defined(_WIN64) HMODULE hModule = TclWinGetTclInstance(); WCHAR wName[MAX_PATH + LIBRARY_SIZE]; @@ -4113,20 +4075,20 @@ Tcl_Obj *TclZipfs_TclLibrary(void) { } /* Mount zip file and dll before releasing to search */ if(TclZipfs_AppHook_FindTclInit(dllname)==TCL_OK) { - Tcl_IncrRefCount(zipfs_literal_tcl_library); - return zipfs_literal_tcl_library; + return Tcl_NewStringObj(zipfs_literal_tcl_library,-1); } #else /* Mount zip file and dll before releasing to search */ if(TclZipfs_AppHook_FindTclInit(CFG_RUNTIME_PATH "/" CFG_RUNTIME_DLLFILE)==TCL_OK) { - Tcl_IncrRefCount(zipfs_literal_tcl_library); - return zipfs_literal_tcl_library; + return Tcl_NewStringObj(zipfs_literal_tcl_library,-1); } #endif + if(TclZipfs_AppHook_FindTclInit(CFG_RUNTIME_PATH "/" CFG_RUNTIME_ZIPFILE)==TCL_OK) { + return Tcl_NewStringObj(zipfs_literal_tcl_library,-1); + } } - if(TclZipfs_AppHook_FindTclInit(CFG_RUNTIME_PATH "/" CFG_RUNTIME_ZIPFILE)==TCL_OK) { - Tcl_IncrRefCount(zipfs_literal_tcl_library); - return zipfs_literal_tcl_library; + if(zipfs_literal_tcl_library) { + return Tcl_NewStringObj(zipfs_literal_tcl_library,-1); } return NULL; } diff --git a/unix/Makefile.in b/unix/Makefile.in index d6152a6..db98646 100644 --- a/unix/Makefile.in +++ b/unix/Makefile.in @@ -675,7 +675,7 @@ tclzipfile: ${TCL_ZIP_FILE} ${TCL_ZIP_FILE}: ${ZIP_INSTALL_OBJS} rm -rf ${TCL_VFS_ROOT} mkdir -p ${TCL_VFS_PATH} - cp -a ../library/* ${TCL_VFS_PATH} + cp -a $(TOP_DIR)/library/* ${TCL_VFS_PATH} cd ${TCL_VFS_ROOT} ; ${NATIVE_ZIP} ${ZIP_PROG_OPTIONS} ../${TCL_ZIP_FILE} ${ZIP_PROG_VFSSEARCH} # The following target is configured by autoconf to generate either a shared diff --git a/unix/tcl.pc.in b/unix/tcl.pc.in index 846cb11..ca932d2 100644 --- a/unix/tcl.pc.in +++ b/unix/tcl.pc.in @@ -4,6 +4,8 @@ prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ +libfile=@TCL_LIB_FILE@ +zipfile=@TCL_ZIP_FILE@ Name: Tool Command Language Description: Tcl is a powerful, easy-to-learn dynamic programming language, suitable for a wide range of uses. diff --git a/win/Makefile.in b/win/Makefile.in index 49f0bfb..768178d 100644 --- a/win/Makefile.in +++ b/win/Makefile.in @@ -483,7 +483,7 @@ tclzipfile: ${TCL_ZIP_FILE} ${TCL_ZIP_FILE}: ${ZIP_INSTALL_OBJS} rm -rf ${TCL_VFS_ROOT} mkdir -p ${TCL_VFS_PATH} - cp -a ../library/* ${TCL_VFS_PATH} + $(COPY) -a $(TOP_DIR)/library/* ${TCL_VFS_PATH} cd ${TCL_VFS_ROOT} ; ${NATIVE_ZIP} ${ZIP_PROG_OPTIONS} ../${TCL_ZIP_FILE} ${ZIP_PROG_VFSSEARCH} $(TCLSH): $(TCLSH_OBJS) @LIBRARIES@ $(TCL_STUB_LIB_FILE) tclsh.$(RES) -- cgit v0.12 From 8225859a93e2e55934b39855a9f4f736555bc474 Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Tue, 21 Nov 2017 16:49:24 +0000 Subject: Eliminated the need for a preinit script in Tip 430's AppHook. tcl_findLibrary now knows to scan the dll offered up by [info loaded] to see if an attached zipfile could possibly contain the files the extension is looking for. --- generic/tclZipfs.c | 41 ++++++++--------------------------------- library/auto.tcl | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 33 deletions(-) diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c index 03170a1..fa5b1a3 100644 --- a/generic/tclZipfs.c +++ b/generic/tclZipfs.c @@ -1013,7 +1013,6 @@ TclZipfs_Mount(Tcl_Interp *interp, const char *zipname, const char *mntpt, Tcl_HashEntry *hPtr; Tcl_DString ds, fpBuf; unsigned char *q; - ReadLock(); if (!ZipFS.initialized) { if (interp != NULL) { @@ -1436,7 +1435,8 @@ static int ZipFSRootObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { - return Tcl_NewStringObj(ZIPFS_VOLUME, -1); + Tcl_SetObjResult(interp,Tcl_NewStringObj(ZIPFS_VOLUME, -1)); + return TCL_OK; } /* @@ -3920,6 +3920,9 @@ ToUtf( static int TclZipfs_AppHook_FindTclInit(const char *archive){ Tcl_Obj *vfsinitscript; int found; + if(zipfs_literal_tcl_library) { + return TCL_ERROR; + } if(TclZipfs_Mount(NULL, archive, ZIPFS_ZIP_MOUNT, NULL)) { /* Either the file doesn't exist or it is not a zip archive */ return TCL_ERROR; @@ -3963,36 +3966,6 @@ int TclZipfs_AppHook(int *argc, char ***argv) ** and failing that, look for a file name CFG_RUNTIME_ZIPFILE adjacent to the ** executable */ - TclSetPreInitScript( -"foreach {path} {\n" -" {" ZIPFS_APP_MOUNT "/tcl_library}\n" -" {" ZIPFS_ZIP_MOUNT "/tcl_library}\n" -"} {\n" -" if {![file exists [file join $path init.tcl]]} continue\n" -" set ::tcl_library $path\n" -" break\n" -"}\n" -"if {![info exists ::tcl_library] || $::tcl_library eq {}} {\n" -" set zipfile [file join [file dirname [info nameofexecutable]] " CFG_RUNTIME_ZIPFILE "]\n" -" if {[file exists $zipfile]} {\n" -" zipfs mount $zipfile {" ZIPFS_ZIP_MOUNT "}\n" -" if {[file exists [file join {" ZIPFS_ZIP_MOUNT "} init.tcl]]} \{\n" -" set ::tcl_library {" ZIPFS_ZIP_MOUNT "}\n" -" } else {\n" -" zipfs unmount {" ZIPFS_ZIP_MOUNT "}\n" -" }\n" -" }\n" -"}\n" -"foreach {path} {\n" -" {" ZIPFS_APP_MOUNT "/tk_library}\n" -" {" ZIPFS_ZIP_MOUNT "/tk_library}\n" -" {" ZIPFS_VOLUME "lib/tk/tk_library}\n" -"} {\n" -" if {![file exists [file join $path init.tcl]]} continue\n" -" set ::tk_library $path\n" -" break\n" -"}\n" - ); if(!TclZipfs_Mount(NULL, archive, ZIPFS_APP_MOUNT, NULL)) { int found; Tcl_Obj *vfsinitscript; @@ -4062,7 +4035,9 @@ int TclZipfs_AppHook(int *argc, char ***argv) } Tcl_Obj *TclZipfs_TclLibrary(void) { - if(!zipfs_literal_tcl_library) { + if(zipfs_literal_tcl_library) { + return Tcl_NewStringObj(zipfs_literal_tcl_library,-1); + } else { #if defined(_WIN32) || defined(_WIN64) HMODULE hModule = TclWinGetTclInstance(); WCHAR wName[MAX_PATH + LIBRARY_SIZE]; diff --git a/library/auto.tcl b/library/auto.tcl index a7a8979..d8f9d88 100644 --- a/library/auto.tcl +++ b/library/auto.tcl @@ -74,6 +74,54 @@ proc tcl_findLibrary {basename version patch initScript enVarName varName} { lappend dirs $env($enVarName) } + catch { + set found 0 + set root [zipfs root] + set mountpoint [file join $root lib [string tolower $basename]] + lappend dirs [file join $root app ${basename}_library] + lappend dirs [file join $root lib $mountpoint ${basename}_library] + lappend dirs [file join $root lib $mountpoint] + if {![zipfs exists [file join $root app ${basename}_library]] && ![zipfs exists $mountpoint]} { + set found 0 + foreach pkgdat [info loaded] { + lassign $pkgdat dllfile dllpkg + if {[string tolower $dllpkg] ne [string tolower $basename]} continue + if {$dllfile eq {}} { + # Loaded statically + break + } + set found 1 + zipfs mount $dllfile $mountpoint + break + } + if {!$found} { + set paths {} + lappend paths [file join $root app] + lappend paths [::${basename}::pkgconfig get libdir,runtime] + lappend paths [::${basename}::pkgconfig get bindir,runtime] + if {[catch {::${basename}::pkgconfig get zipfile,runtime} zipfile]} { + set zipfile [string tolower "lib${basename}_[join [list {*}[split $version .] {*}$patch] _].zip"] + } + foreach path $paths { + set archive [file join $path $zipfile] + if {![file exists $archive]} continue + zipfs mount $archive $mountpoint + if {[zipfs exists [file join $mountpoint ${basename}_library $initScript]]} { + lappend dirs [file join $mountpoint ${basename}_library] + set found 1 + break + } elseif {[zipfs exists [file join $mountpoint $initScript]]} { + lappend dirs [file join $mountpoint $initScript] + set found 1 + break + } else { + catch {zipfs unmount $archive} + } + } + } + } + } + # 2. In the package script directory registered within the # configuration of the package itself. -- cgit v0.12 From d997aa477de14bc3128e4e5ac08713f7c40d647c Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Tue, 21 Nov 2017 18:57:31 +0000 Subject: Added additional functions to the "install" command in tclsh --- library/install.tcl | 231 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 231 insertions(+) diff --git a/library/install.tcl b/library/install.tcl index f126b37..e62226e 100644 --- a/library/install.tcl +++ b/library/install.tcl @@ -5,9 +5,240 @@ if {[llength $argv] < 2} { exit 0 } +namespace eval ::practcl {} +### +# Installer tools +### +proc ::practcl::_isdirectory name { + return [file isdirectory $name] +} +### +# Return true if the pkgindex file contains +# any statement other than "package ifneeded" +# and/or if any package ifneeded loads a DLL +### +proc ::practcl::_pkgindex_directory {path} { + set buffer {} + set pkgidxfile [file join $path pkgIndex.tcl] + if {![file exists $pkgidxfile]} { + # No pkgIndex file, read the source + foreach file [glob -nocomplain $path/*.tm] { + set file [file normalize $file] + set fname [file rootname [file tail $file]] + ### + # We used to be able to ... Assume the package is correct in the filename + # No hunt for a "package provides" + ### + set package [lindex [split $fname -] 0] + set version [lindex [split $fname -] 1] + ### + # Read the file, and override assumptions as needed + ### + set fin [open $file r] + set dat [read $fin] + close $fin + # Look for a teapot style Package statement + foreach line [split $dat \n] { + set line [string trim $line] + if { [string range $line 0 9] != "# Package " } continue + set package [lindex $line 2] + set version [lindex $line 3] + break + } + # Look for a package provide statement + foreach line [split $dat \n] { + set line [string trim $line] + if { [string range $line 0 14] != "package provide" } continue + set package [lindex $line 2] + set version [lindex $line 3] + break + } + append buffer "package ifneeded $package $version \[list source \[file join \$dir [file tail $file]\]\]" \n + } + foreach file [glob -nocomplain $path/*.tcl] { + if { [file tail $file] == "version_info.tcl" } continue + set fin [open $file r] + set dat [read $fin] + close $fin + if {![regexp "package provide" $dat]} continue + set fname [file rootname [file tail $file]] + # Look for a package provide statement + foreach line [split $dat \n] { + set line [string trim $line] + if { [string range $line 0 14] != "package provide" } continue + set package [lindex $line 2] + set version [lindex $line 3] + if {[string index $package 0] in "\$ \[ @"} continue + if {[string index $version 0] in "\$ \[ @"} continue + append buffer "package ifneeded $package $version \[list source \[file join \$dir [file tail $file]\]\]" \n + break + } + } + return $buffer + } + set fin [open $pkgidxfile r] + set dat [read $fin] + close $fin + set trace 0 + #if {[file tail $path] eq "tool"} { + # set trace 1 + #} + set thisline {} + foreach line [split $dat \n] { + append thisline $line \n + if {![info complete $thisline]} continue + set line [string trim $line] + if {[string length $line]==0} { + set thisline {} ; continue + } + if {[string index $line 0] eq "#"} { + set thisline {} ; continue + } + if {[regexp "if.*catch.*package.*Tcl.*return" $thisline]} { + if {$trace} {puts "[file dirname $pkgidxfile] Ignoring $thisline"} + set thisline {} ; continue + } + if {[regexp "if.*package.*vsatisfies.*package.*provide.*return" $thisline]} { + if {$trace} { puts "[file dirname $pkgidxfile] Ignoring $thisline" } + set thisline {} ; continue + } + if {![regexp "package.*ifneeded" $thisline]} { + # This package index contains arbitrary code + # source instead of trying to add it to the master + # package index + if {$trace} { puts "[file dirname $pkgidxfile] Arbitrary code $thisline" } + return {source [file join $dir pkgIndex.tcl]} + } + append buffer $thisline \n + set thisline {} + } + if {$trace} {puts [list [file dirname $pkgidxfile] $buffer]} + return $buffer +} + + +proc ::practcl::_pkgindex_path_subdir {path} { + set result {} + foreach subpath [glob -nocomplain [file join $path *]] { + if {[file isdirectory $subpath]} { + lappend result $subpath {*}[_pkgindex_path_subdir $subpath] + } + } + return $result +} +### +# Index all paths given as though they will end up in the same +# virtual file system +### +proc ::practcl::pkgindex_path args { + set stack {} + set buffer { +lappend ::PATHSTACK $dir + } + foreach base $args { + set base [file normalize $base] + set paths {} + foreach dir [glob -nocomplain [file join $base *]] { + if {[file tail $dir] eq "teapot"} continue + lappend paths $dir {*}[::practcl::_pkgindex_path_subdir $dir] + } + set i [string length $base] + # Build a list of all of the paths + if {[llength $paths]} { + foreach path $paths { + if {$path eq $base} continue + set path_indexed($path) 0 + } + } else { + puts [list WARNING: NO PATHS FOUND IN $base] + } + set path_indexed($base) 1 + set path_indexed([file join $base boot tcl]) 1 + foreach teapath [glob -nocomplain [file join $base teapot *]] { + set pkg [file tail $teapath] + append buffer [list set pkg $pkg] + append buffer { +set pkginstall [file join $::g(HOME) teapot $pkg] +if {![file exists $pkginstall]} { + installDir [file join $dir teapot $pkg] $pkginstall +} +} + } + foreach path $paths { + if {$path_indexed($path)} continue + set thisdir [file_relative $base $path] + set idxbuf [::practcl::_pkgindex_directory $path] + if {[string length $idxbuf]} { + incr path_indexed($path) + append buffer "set dir \[set PKGDIR \[file join \[lindex \$::PATHSTACK end\] $thisdir\]\]" \n + append buffer [string map {$dir $PKGDIR} [string trimright $idxbuf]] \n + } + } + } + append buffer { +set dir [lindex $::PATHSTACK end] +set ::PATHSTACK [lrange $::PATHSTACK 0 end-1] +} + return $buffer +} + +### +# topic: 64319f4600fb63c82b2258d908f9d066 +# description: Script to build the VFS file system +### +proc ::practcl::installDir {d1 d2} { + + puts [format {%*sCreating %s} [expr {4 * [info level]}] {} [file tail $d2]] + file delete -force -- $d2 + file mkdir $d2 + + foreach ftail [glob -directory $d1 -nocomplain -tails *] { + set f [file join $d1 $ftail] + if {[file isdirectory $f] && [string compare CVS $ftail]} { + installDir $f [file join $d2 $ftail] + } elseif {[file isfile $f]} { + file copy -force $f [file join $d2 $ftail] + if {$::tcl_platform(platform) eq {unix}} { + file attributes [file join $d2 $ftail] -permissions 0644 + } else { + file attributes [file join $d2 $ftail] -readonly 1 + } + } + } + + if {$::tcl_platform(platform) eq {unix}} { + file attributes $d2 -permissions 0755 + } else { + file attributes $d2 -readonly 1 + } +} + +proc ::practcl::copyDir {d1 d2 {toplevel 1}} { + #if {$toplevel} { + # puts [list ::practcl::copyDir $d1 -> $d2] + #} + #file delete -force -- $d2 + file mkdir $d2 + + foreach ftail [glob -directory $d1 -nocomplain -tails *] { + set f [file join $d1 $ftail] + if {[file isdirectory $f] && [string compare CVS $ftail]} { + copyDir $f [file join $d2 $ftail] 0 + } elseif {[file isfile $f]} { + file copy -force $f [file join $d2 $ftail] + } + } +} + switch [lindex $argv 1] { mkzip { zipfs mkzip {*}[lrange $argv 2 end] } + mkzip { + zipfs mkimg {*}[lrange $argv 2 end] + } + default { + ::practcl::[lindex $argv 1] {*}[lrange $argv 2 end] + } } exit 0 -- cgit v0.12 From 2d811a0adff9b3a837a8bd2111d6f88742c9f5d5 Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Thu, 23 Nov 2017 11:55:03 +0000 Subject: Fixing a goof, Zipfs was looking for the Dll where the installer put the file, which is not necessarily where the file will be found at runtime. --- generic/tclZipfs.c | 7 +++++-- unix/Makefile.in | 3 ++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c index fa5b1a3..2d475f0 100644 --- a/generic/tclZipfs.c +++ b/generic/tclZipfs.c @@ -4054,11 +4054,14 @@ Tcl_Obj *TclZipfs_TclLibrary(void) { } #else /* Mount zip file and dll before releasing to search */ - if(TclZipfs_AppHook_FindTclInit(CFG_RUNTIME_PATH "/" CFG_RUNTIME_DLLFILE)==TCL_OK) { + if(TclZipfs_AppHook_FindTclInit(CFG_RUNTIME_LIBDIR "/" CFG_RUNTIME_DLLFILE)==TCL_OK) { return Tcl_NewStringObj(zipfs_literal_tcl_library,-1); } #endif - if(TclZipfs_AppHook_FindTclInit(CFG_RUNTIME_PATH "/" CFG_RUNTIME_ZIPFILE)==TCL_OK) { + if(TclZipfs_AppHook_FindTclInit(CFG_RUNTIME_LIBDIR "/" CFG_RUNTIME_ZIPFILE)==TCL_OK) { + return Tcl_NewStringObj(zipfs_literal_tcl_library,-1); + } + if(TclZipfs_AppHook_FindTclInit(CFG_RUNTIME_SRCDIR "/" CFG_RUNTIME_ZIPFILE)==TCL_OK) { return Tcl_NewStringObj(zipfs_literal_tcl_library,-1); } } diff --git a/unix/Makefile.in b/unix/Makefile.in index db98646..3229934 100644 --- a/unix/Makefile.in +++ b/unix/Makefile.in @@ -1409,7 +1409,8 @@ tclZipfs.o: $(GENERIC_DIR)/tclZipfs.c $(CC) -c $(CC_SWITCHES) \ -DCFG_RUNTIME_DLLFILE="\"$(TCL_LIB_FILE)\"" \ -DCFG_RUNTIME_ZIPFILE="\"$(TCL_ZIP_FILE)\"" \ - -DCFG_RUNTIME_PATH="\"$(DLL_INSTALL_DIR)\"" \ + -DCFG_RUNTIME_LIBDIR="\"$(libdir)\"" \ + -DCFG_RUNTIME_SCRDIR="\"$(TCL_LIBRARY)\"" \ $(ZLIB_INCLUDE) -I$(ZLIB_DIR)/contrib/minizip $(GENERIC_DIR)/tclZipfs.c tclTest.o: $(GENERIC_DIR)/tclTest.c $(IOHDR) $(TCLREHDRS) -- cgit v0.12 From 2fcfa34fcf2d769d0421000f57d8601a3a712322 Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Fri, 24 Nov 2017 10:32:10 +0000 Subject: Restoring whitespace to tclZipfs.c to improve legibility. --- generic/tclZipfs.c | 2927 +++++++++++++++++++++++++--------------------------- 1 file changed, 1426 insertions(+), 1501 deletions(-) diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c index 2d475f0..b9d09f1 100644 --- a/generic/tclZipfs.c +++ b/generic/tclZipfs.c @@ -98,6 +98,10 @@ #define ZIP_PASSWORD_END_SIG 0x5a5a4b50 +/* Macro to report errors only if an interp is present */ +#define ZIPFS_ERROR(interp,errstr) \ + if(interp != NULL) Tcl_SetObjResult(interp, Tcl_NewStringObj(errstr, -1)); + /* * Macros to read and write 16 and 32 bit integers from/to ZIP archives. */ @@ -328,7 +332,7 @@ ReadLock(void) while (ZipFS.lock < 0) { ZipFS.waiters++; Tcl_ConditionWait(&ZipFSCond, &ZipFSMutex, NULL); - ZipFS.waiters--; + ZipFS.waiters--; } ZipFS.lock++; Tcl_MutexUnlock(&ZipFSMutex); @@ -341,7 +345,7 @@ WriteLock(void) while (ZipFS.lock != 0) { ZipFS.waiters++; Tcl_ConditionWait(&ZipFSCond, &ZipFSMutex, NULL); - ZipFS.waiters--; + ZipFS.waiters--; } ZipFS.lock = -1; Tcl_MutexUnlock(&ZipFSMutex); @@ -352,12 +356,12 @@ Unlock(void) { Tcl_MutexLock(&ZipFSMutex); if (ZipFS.lock > 0) { - --ZipFS.lock; + --ZipFS.lock; } else if (ZipFS.lock < 0) { - ZipFS.lock = 0; + ZipFS.lock = 0; } if ((ZipFS.lock == 0) && (ZipFS.waiters > 0)) { - Tcl_ConditionNotify(&ZipFSCond); + Tcl_ConditionNotify(&ZipFSCond); } Tcl_MutexUnlock(&ZipFSMutex); } @@ -396,8 +400,8 @@ DosTimeDate(int dosDate, int dosTime) tm.tm_sec = (dosTime & 0x1f) << 1; ret = mktime(&tm); if (ret == (time_t) -1) { - /* fallback to 1980-01-01T00:00:00+00:00 (DOS epoch) */ - ret = (time_t) 315532800; + /* fallback to 1980-01-01T00:00:00+00:00 (DOS epoch) */ + ret = (time_t) 315532800; } return ret; } @@ -481,10 +485,10 @@ CountSlashes(const char *string) const char *p = string; while (*p != '\0') { - if (*p == '/') { - count++; - } - p++; + if (*p == '/') { + count++; + } + p++; } return count; } @@ -515,131 +519,136 @@ CanonicalPath(const char *root, const char *tail, Tcl_DString *dsPtr,int ZIPFSPA int i, j, c, isunc = 0, isvfs=0, n=0; #if HAS_DRIVES int zipfspath=1; - if ((tail[0] != '\0') && (strchr(drvletters, tail[0]) != NULL) && - (tail[1] == ':')) { - tail += 2; - zipfspath=0; + if ( + (tail[0] != '\0') + && (strchr(drvletters, tail[0]) != NULL) + && (tail[1] == ':') + ) { + tail += 2; + zipfspath=0; } /* UNC style path */ if (tail[0] == '\\') { - root = ""; - ++tail; - zipfspath=0; + root = ""; + ++tail; + zipfspath=0; } if (tail[0] == '\\') { - root = "/"; - ++tail; - zipfspath=0; + root = "/"; + ++tail; + zipfspath=0; } if(zipfspath) { #endif - /* UNC style path */ - if(root && strncmp(root,ZIPFS_VOLUME,ZIPFS_VOLUME_LEN)==0) { - isvfs=1; - } else if (tail && strncmp(tail,ZIPFS_VOLUME,ZIPFS_VOLUME_LEN) == 0) { - isvfs=2; - } - if(isvfs!=1) { - if ((root[0] == '/') && (root[1] == '/')) { - isunc = 1; - } - } + /* UNC style path */ + if(root && strncmp(root,ZIPFS_VOLUME,ZIPFS_VOLUME_LEN)==0) { + isvfs=1; + } else if (tail && strncmp(tail,ZIPFS_VOLUME,ZIPFS_VOLUME_LEN) == 0) { + isvfs=2; + } + if(isvfs!=1) { + if ((root[0] == '/') && (root[1] == '/')) { + isunc = 1; + } + } #if HAS_DRIVES } #endif if(isvfs!=2) { - if (tail[0] == '/') { - if(isvfs!=1) { - root = ""; - } - ++tail; - isunc = 0; - } - if (tail[0] == '/') { - if(isvfs!=1) { - root = "/"; - } - ++tail; - isunc = 1; - } + if (tail[0] == '/') { + if(isvfs!=1) { + root = ""; + } + ++tail; + isunc = 0; + } + if (tail[0] == '/') { + if(isvfs!=1) { + root = "/"; + } + ++tail; + isunc = 1; + } } i = strlen(root); j = strlen(tail); if(isvfs==1) { - if(i>ZIPFS_VOLUME_LEN) { - Tcl_DStringSetLength(dsPtr, i + j + 1); - path = Tcl_DStringValue(dsPtr); - memcpy(path, root, i); - path[i++] = '/'; - memcpy(path + i, tail, j); - } else { - Tcl_DStringSetLength(dsPtr, i + j); - path = Tcl_DStringValue(dsPtr); - memcpy(path, root, i); - memcpy(path + i, tail, j); - } + if(i>ZIPFS_VOLUME_LEN) { + Tcl_DStringSetLength(dsPtr, i + j + 1); + path = Tcl_DStringValue(dsPtr); + memcpy(path, root, i); + path[i++] = '/'; + memcpy(path + i, tail, j); + } else { + Tcl_DStringSetLength(dsPtr, i + j); + path = Tcl_DStringValue(dsPtr); + memcpy(path, root, i); + memcpy(path + i, tail, j); + } } else if(isvfs==2) { - Tcl_DStringSetLength(dsPtr, j); - path = Tcl_DStringValue(dsPtr); - memcpy(path, tail, j); + Tcl_DStringSetLength(dsPtr, j); + path = Tcl_DStringValue(dsPtr); + memcpy(path, tail, j); } else { - if (ZIPFSPATH) { - Tcl_DStringSetLength(dsPtr, i + j + ZIPFS_VOLUME_LEN); - path = Tcl_DStringValue(dsPtr); - memcpy(path, ZIPFS_VOLUME, ZIPFS_VOLUME_LEN); - memcpy(path + ZIPFS_VOLUME_LEN + i , tail, j); - } else { - Tcl_DStringSetLength(dsPtr, i + j + 1); - path = Tcl_DStringValue(dsPtr); - memcpy(path, root, i); - path[i++] = '/'; - memcpy(path + i, tail, j); - } + if (ZIPFSPATH) { + Tcl_DStringSetLength(dsPtr, i + j + ZIPFS_VOLUME_LEN); + path = Tcl_DStringValue(dsPtr); + memcpy(path, ZIPFS_VOLUME, ZIPFS_VOLUME_LEN); + memcpy(path + ZIPFS_VOLUME_LEN + i , tail, j); + } else { + Tcl_DStringSetLength(dsPtr, i + j + 1); + path = Tcl_DStringValue(dsPtr); + memcpy(path, root, i); + path[i++] = '/'; + memcpy(path + i, tail, j); + } } #if HAS_DRIVES for (i = 0; path[i] != '\0'; i++) { - if (path[i] == '\\') { - path[i] = '/'; - } + if (path[i] == '\\') { + path[i] = '/'; + } } #endif if(ZIPFSPATH) { - n=ZIPFS_VOLUME_LEN; + n=ZIPFS_VOLUME_LEN; } else { - n=0; + n=0; } for (i = j = n; (c = path[i]) != '\0'; i++) { - if (c == '/') { - int c2 = path[i + 1]; - if (c2 == '/') { - continue; - } - if (c2 == '.') { - int c3 = path[i + 2]; - if ((c3 == '/') || (c3 == '\0')) { - i++; - continue; - } - if ((c3 == '.') && - ((path[i + 3] == '/') || (path [i + 3] == '\0'))) { - i += 2; - while ((j > 0) && (path[j - 1] != '/')) { - j--; - } - if (j > isunc) { - --j; - while ((j > 1 + isunc) && (path[j - 2] == '/')) { - j--; - } - } - continue; - } - } - } - path[j++] = c; + if (c == '/') { + int c2 = path[i + 1]; + if (c2 == '/') { + continue; + } + if (c2 == '.') { + int c3 = path[i + 2]; + if ((c3 == '/') || (c3 == '\0')) { + i++; + continue; + } + if ( + (c3 == '.') + && ((path[i + 3] == '/') || (path [i + 3] == '\0')) + ) { + i += 2; + while ((j > 0) && (path[j - 1] != '/')) { + j--; + } + if (j > isunc) { + --j; + while ((j > 1 + isunc) && (path[j - 2] == '/')) { + j--; + } + } + continue; + } + } + } + path[j++] = c; } if (j == 0) { - path[j++] = '/'; + path[j++] = '/'; } path[j] = 0; Tcl_DStringSetLength(dsPtr, j); @@ -709,13 +718,12 @@ ZipFSLookupMount(char *filename) int match = 0; hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); while (hPtr != NULL) { - if ((zf = (ZipFile *) Tcl_GetHashValue(hPtr)) != NULL) { - if (strcmp(zf->mntpt, filename) == 0) { - match = 1; - break; - } - } - hPtr = Tcl_NextHashEntry(&search); + if ((zf = (ZipFile *) Tcl_GetHashValue(hPtr)) == NULL) continue; + if (strcmp(zf->mntpt, filename) == 0) { + match = 1; + break; + } + hPtr = Tcl_NextHashEntry(&search); } return match; } @@ -743,21 +751,21 @@ ZipFSCloseArchive(Tcl_Interp *interp, ZipFile *zf) { #if defined(_WIN32) || defined(_WIN64) if ((zf->data != NULL) && (zf->tofree == NULL)) { - UnmapViewOfFile(zf->data); - zf->data = NULL; + UnmapViewOfFile(zf->data); + zf->data = NULL; } if (zf->mh != INVALID_HANDLE_VALUE) { - CloseHandle(zf->mh); + CloseHandle(zf->mh); } #else if ((zf->data != MAP_FAILED) && (zf->tofree == NULL)) { - munmap(zf->data, zf->length); - zf->data = MAP_FAILED; + munmap(zf->data, zf->length); + zf->data = MAP_FAILED; } #endif if (zf->tofree != NULL) { - Tcl_Free((char *) zf->tofree); - zf->tofree = NULL; + Tcl_Free((char *) zf->tofree); + zf->tofree = NULL; } Tcl_Close(interp, zf->chan); zf->chan = NULL; @@ -807,176 +815,138 @@ ZipFSOpenArchive(Tcl_Interp *interp, const char *zipname, int needZip, zf->pwbuf[0] = 0; zf->chan = Tcl_OpenFileChannel(interp, zipname, "r", 0); if (zf->chan == NULL) { - return TCL_ERROR; + return TCL_ERROR; } if (Tcl_GetChannelHandle(zf->chan, TCL_READABLE, &handle) != TCL_OK) { - if (Tcl_SetChannelOption(interp, zf->chan, "-translation", "binary") - != TCL_OK) { - goto error; - } - if (Tcl_SetChannelOption(interp, zf->chan, "-encoding", "binary") - != TCL_OK) { - goto error; - } - zf->length = Tcl_Seek(zf->chan, 0, SEEK_END); - if ((zf->length <= 0) || (zf->length > 64 * 1024 * 1024)) { - if (interp) { - Tcl_SetObjResult(interp, - Tcl_NewStringObj("illegal file size", -1)); - } - goto error; - } - Tcl_Seek(zf->chan, 0, SEEK_SET); - zf->tofree = zf->data = (unsigned char *) Tcl_AttemptAlloc(zf->length); - if (zf->tofree == NULL) { - if (interp) { - Tcl_SetObjResult(interp, - Tcl_NewStringObj("out of memory", -1)); - } - goto error; - } - i = Tcl_Read(zf->chan, (char *) zf->data, zf->length); - if (i != zf->length) { - if (interp) { - Tcl_SetObjResult(interp, - Tcl_NewStringObj("file read error", -1)); - } - goto error; - } - Tcl_Close(interp, zf->chan); - zf->chan = NULL; + if (Tcl_SetChannelOption(interp, zf->chan, "-translation", "binary") != TCL_OK) { + goto error; + } + if (Tcl_SetChannelOption(interp, zf->chan, "-encoding", "binary") != TCL_OK) { + goto error; + } + zf->length = Tcl_Seek(zf->chan, 0, SEEK_END); + if ((zf->length <= 0) || (zf->length > 64 * 1024 * 1024)) { + ZIPFS_ERROR(interp,"illegal file size"); + goto error; + } + Tcl_Seek(zf->chan, 0, SEEK_SET); + zf->tofree = zf->data = (unsigned char *) Tcl_AttemptAlloc(zf->length); + if (zf->tofree == NULL) { + ZIPFS_ERROR(interp,"out of memory") + goto error; + } + i = Tcl_Read(zf->chan, (char *) zf->data, zf->length); + if (i != zf->length) { + ZIPFS_ERROR(interp,"file read error"); + goto error; + } + Tcl_Close(interp, zf->chan); + zf->chan = NULL; } else { #if defined(_WIN32) || defined(_WIN64) - zf->length = GetFileSize((HANDLE) handle, 0); - if ((zf->length == INVALID_FILE_SIZE) || - (zf->length < ZIP_CENTRAL_END_LEN)) { - if (interp != NULL) { - Tcl_SetObjResult(interp, - Tcl_NewStringObj("invalid file size", -1)); - } - goto error; - } - zf->mh = CreateFileMapping((HANDLE) handle, 0, PAGE_READONLY, 0, - zf->length, 0); - if (zf->mh == INVALID_HANDLE_VALUE) { - if (interp != NULL) { - Tcl_SetObjResult(interp, - Tcl_NewStringObj("file mapping failed", -1)); - } - goto error; - } - zf->data = MapViewOfFile(zf->mh, FILE_MAP_READ, 0, 0, zf->length); - if (zf->data == NULL) { - if (interp != NULL) { - Tcl_SetObjResult(interp, - Tcl_NewStringObj("file mapping failed", -1)); - } - goto error; - } + zf->length = GetFileSize((HANDLE) handle, 0); + if ( + (zf->length == INVALID_FILE_SIZE) || + (zf->length < ZIP_CENTRAL_END_LEN) + ) { + ZIPFS_ERROR(interp,"invalid file size"); + goto error; + } + zf->mh = CreateFileMapping((HANDLE) handle, 0, PAGE_READONLY, 0, + zf->length, 0); + if (zf->mh == INVALID_HANDLE_VALUE) { + ZIPFS_ERROR(interp,"file mapping failed"); + goto error; + } + zf->data = MapViewOfFile(zf->mh, FILE_MAP_READ, 0, 0, zf->length); + if (zf->data == NULL) { + ZIPFS_ERROR(interp,"file mapping failed"); + goto error; + } #else - zf->length = lseek((int) (long) handle, 0, SEEK_END); - if ((zf->length == -1) || (zf->length < ZIP_CENTRAL_END_LEN)) { - if (interp != NULL) { - Tcl_SetObjResult(interp, - Tcl_NewStringObj("invalid file size", -1)); - } - goto error; - } - lseek((int) (long) handle, 0, SEEK_SET); - zf->data = (unsigned char *) mmap(0, zf->length, PROT_READ, - MAP_FILE | MAP_PRIVATE, - (int) (long) handle, 0); - if (zf->data == MAP_FAILED) { - if (interp != NULL) { - Tcl_SetObjResult(interp, - Tcl_NewStringObj("file mapping failed", -1)); - } - goto error; - } + zf->length = lseek((int) (long) handle, 0, SEEK_END); + if ((zf->length == -1) || (zf->length < ZIP_CENTRAL_END_LEN)) { + ZIPFS_ERROR(interp,"invalid file size"); + goto error; + } + lseek((int) (long) handle, 0, SEEK_SET); + zf->data = (unsigned char *) mmap(0, zf->length, PROT_READ, + MAP_FILE | MAP_PRIVATE, + (int) (long) handle, 0); + if (zf->data == MAP_FAILED) { + ZIPFS_ERROR(interp,"file mapping failed"); + goto error; + } #endif } p = zf->data + zf->length - ZIP_CENTRAL_END_LEN; while (p >= zf->data) { - if (*p == (ZIP_CENTRAL_END_SIG & 0xFF)) { - if (zip_read_int(p) == ZIP_CENTRAL_END_SIG) { - break; - } - p -= ZIP_SIG_LEN; - } else { - --p; - } + if (*p == (ZIP_CENTRAL_END_SIG & 0xFF)) { + if (zip_read_int(p) == ZIP_CENTRAL_END_SIG) { + break; + } + p -= ZIP_SIG_LEN; + } else { + --p; + } } if (p < zf->data) { - if (!needZip) { - zf->baseoffs = zf->baseoffsp = zf->length; - return TCL_OK; - } - if (interp != NULL) { - Tcl_SetObjResult(interp, - Tcl_NewStringObj("wrong end signature", -1)); - } - goto error; + if (!needZip) { + zf->baseoffs = zf->baseoffsp = zf->length; + return TCL_OK; + } + ZIPFS_ERROR(interp,"wrong end signature"); + goto error; } zf->nfiles = zip_read_short(p + ZIP_CENTRAL_ENTS_OFFS); if (zf->nfiles == 0) { - if (!needZip) { - zf->baseoffs = zf->baseoffsp = zf->length; - return TCL_OK; - } - if (interp != NULL) { - Tcl_SetObjResult(interp, - Tcl_NewStringObj("empty archive", -1)); - } - goto error; + if (!needZip) { + zf->baseoffs = zf->baseoffsp = zf->length; + return TCL_OK; + } + ZIPFS_ERROR(interp,"empty archive"); + goto error; } q = zf->data + zip_read_int(p + ZIP_CENTRAL_DIRSTART_OFFS); p -= zip_read_int(p + ZIP_CENTRAL_DIRSIZE_OFFS); - if ((p < zf->data) || (p > (zf->data + zf->length)) || - (q < zf->data) || (q > (zf->data + zf->length))) { - if (!needZip) { - zf->baseoffs = zf->baseoffsp = zf->length; - return TCL_OK; - } - if (interp != NULL) { - Tcl_SetObjResult(interp, - Tcl_NewStringObj("archive directory not found", -1)); - } - goto error; + if ( + (p < zf->data) || (p > (zf->data + zf->length)) || + (q < zf->data) || (q > (zf->data + zf->length)) + ) { + if (!needZip) { + zf->baseoffs = zf->baseoffsp = zf->length; + return TCL_OK; + } + ZIPFS_ERROR(interp,"archive directory not found"); + goto error; } zf->baseoffs = zf->baseoffsp = p - q; zf->centoffs = p - zf->data; q = p; for (i = 0; i < zf->nfiles; i++) { - int pathlen, comlen, extra; + int pathlen, comlen, extra; - if ((q + ZIP_CENTRAL_HEADER_LEN) > (zf->data + zf->length)) { - if (interp != NULL) { - Tcl_SetObjResult(interp, - Tcl_NewStringObj("wrong header length", -1)); - } - goto error; - } - if (zip_read_int(q) != ZIP_CENTRAL_HEADER_SIG) { - if (interp != NULL) { - Tcl_SetObjResult(interp, - Tcl_NewStringObj("wrong header signature", -1)); - } - goto error; - } - pathlen = zip_read_short(q + ZIP_CENTRAL_PATHLEN_OFFS); - comlen = zip_read_short(q + ZIP_CENTRAL_FCOMMENTLEN_OFFS); - extra = zip_read_short(q + ZIP_CENTRAL_EXTRALEN_OFFS); - q += pathlen + comlen + extra + ZIP_CENTRAL_HEADER_LEN; + if ((q + ZIP_CENTRAL_HEADER_LEN) > (zf->data + zf->length)) { + ZIPFS_ERROR(interp,"wrong header length"); + goto error; + } + if (zip_read_int(q) != ZIP_CENTRAL_HEADER_SIG) { + ZIPFS_ERROR(interp,"wrong header signature"); + goto error; + } + pathlen = zip_read_short(q + ZIP_CENTRAL_PATHLEN_OFFS); + comlen = zip_read_short(q + ZIP_CENTRAL_FCOMMENTLEN_OFFS); + extra = zip_read_short(q + ZIP_CENTRAL_EXTRALEN_OFFS); + q += pathlen + comlen + extra + ZIP_CENTRAL_HEADER_LEN; } q = zf->data + zf->baseoffs; - if ((zf->baseoffs >= 6) && - (zip_read_int(q - 4) == ZIP_PASSWORD_END_SIG)) { - i = q[-5]; - if (q - 5 - i > zf->data) { - zf->pwbuf[0] = i; - memcpy(zf->pwbuf + 1, q - 5 - i, i); - zf->baseoffsp -= i ? (5 + i) : 0; - } + if ((zf->baseoffs >= 6) && (zip_read_int(q - 4) == ZIP_PASSWORD_END_SIG)) { + i = q[-5]; + if (q - 5 - i > zf->data) { + zf->pwbuf[0] = i; + memcpy(zf->pwbuf + 1, q - 5 - i, i); + zf->baseoffsp -= i ? (5 + i) : 0; + } } return TCL_OK; @@ -1004,9 +974,11 @@ error: */ int -TclZipfs_Mount(Tcl_Interp *interp, const char *zipname, const char *mntpt, - const char *passwd) -{ +TclZipfs_Mount( + Tcl_Interp *interp, const char *zipname, + const char *mntpt, + const char *passwd +) { int i, pwlen, isNew; ZipFile *zf, zf0; ZipEntry *z; @@ -1015,49 +987,45 @@ TclZipfs_Mount(Tcl_Interp *interp, const char *zipname, const char *mntpt, unsigned char *q; ReadLock(); if (!ZipFS.initialized) { - if (interp != NULL) { - Tcl_SetObjResult(interp, - Tcl_NewStringObj("not initialized", -1)); - } - Unlock(); - return TCL_ERROR; + ZIPFS_ERROR(interp,"not initialized"); + Unlock(); + return TCL_ERROR; } if (zipname == NULL) { - Tcl_HashSearch search; - int ret = TCL_OK; - - i = 0; - hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); - while (hPtr != NULL) { - if ((zf = (ZipFile *) Tcl_GetHashValue(hPtr)) != NULL) { - if (interp != NULL) { - Tcl_AppendElement(interp, zf->mntpt); - Tcl_AppendElement(interp, zf->name); - } - ++i; - } - hPtr = Tcl_NextHashEntry(&search); - } - if (interp == NULL) { - ret = (i > 0) ? TCL_OK : TCL_BREAK; - } - Unlock(); - return ret; + Tcl_HashSearch search; + int ret = TCL_OK; + + i = 0; + hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); + while (hPtr != NULL) { + if ((zf = (ZipFile *) Tcl_GetHashValue(hPtr)) != NULL) { + if (interp != NULL) { + Tcl_AppendElement(interp, zf->mntpt); + Tcl_AppendElement(interp, zf->name); + } + ++i; + } + hPtr = Tcl_NextHashEntry(&search); + } + if (interp == NULL) { + ret = (i > 0) ? TCL_OK : TCL_BREAK; + } + Unlock(); + return ret; } if (mntpt == NULL) { - if (interp == NULL) { - Unlock(); - return TCL_OK; - } - hPtr = Tcl_FindHashEntry(&ZipFS.zipHash, zipname); - if (hPtr != NULL) { - if ((zf = Tcl_GetHashValue(hPtr)) != NULL) { - Tcl_SetObjResult(interp, - Tcl_NewStringObj(zf->mntpt, zf->mntptlen)); - } - } - Unlock(); - return TCL_OK; + if (interp == NULL) { + Unlock(); + return TCL_OK; + } + hPtr = Tcl_FindHashEntry(&ZipFS.zipHash, zipname); + if (hPtr != NULL) { + if ((zf = Tcl_GetHashValue(hPtr)) != NULL) { + Tcl_SetObjResult(interp,Tcl_NewStringObj(zf->mntpt, zf->mntptlen)); + } + } + Unlock(); + return TCL_OK; } Unlock(); pwlen = 0; @@ -1072,7 +1040,7 @@ TclZipfs_Mount(Tcl_Interp *interp, const char *zipname, const char *mntpt, } } if (ZipFSOpenArchive(interp, zipname, 1, &zf0) != TCL_OK) { - return TCL_ERROR; + return TCL_ERROR; } /* * Mount point can come from Tcl_GetNameOfExecutable() @@ -1082,236 +1050,235 @@ TclZipfs_Mount(Tcl_Interp *interp, const char *zipname, const char *mntpt, WriteLock(); hPtr = Tcl_CreateHashEntry(&ZipFS.zipHash, zipname, &isNew); if (!isNew) { - zf = (ZipFile *) Tcl_GetHashValue(hPtr); - if (interp != NULL) { - Tcl_AppendResult(interp, "already mounted on \"", zf->mntptlen ? - zf->mntpt : "/", "\"", (char *) NULL); - } - Unlock(); - ZipFSCloseArchive(interp, &zf0); - return TCL_ERROR; + zf = (ZipFile *) Tcl_GetHashValue(hPtr); + if (interp != NULL) { + Tcl_AppendResult(interp, "already mounted on \"", zf->mntptlen ? + zf->mntpt : "/", "\"", (char *) NULL); + } + Unlock(); + ZipFSCloseArchive(interp, &zf0); + return TCL_ERROR; } if (strcmp(mntpt, "/") == 0) { - mntpt = ""; + mntpt = ""; } zf = (ZipFile *) Tcl_AttemptAlloc(sizeof (*zf) + strlen(mntpt) + 1); if (zf == NULL) { - if (interp != NULL) { - Tcl_AppendResult(interp, "out of memory", (char *) NULL); - } - Unlock(); - ZipFSCloseArchive(interp, &zf0); - return TCL_ERROR; - } - *zf = zf0; - zf->name = Tcl_GetHashKey(&ZipFS.zipHash, hPtr); - strcpy(zf->mntpt, mntpt); - zf->mntptlen = strlen(zf->mntpt); - zf->entries = NULL; - zf->topents = NULL; - zf->nopen = 0; - Tcl_SetHashValue(hPtr, (ClientData) zf); - if ((zf->pwbuf[0] == 0) && pwlen) { - int k = 0; - i = pwlen; - zf->pwbuf[k++] = i; - while (i > 0) { - zf->pwbuf[k] = (passwd[i - 1] & 0x0f) | - pwrot[(passwd[i - 1] >> 4) & 0x0f]; - k++; - i--; - } - zf->pwbuf[k] = '\0'; + if (interp != NULL) { + Tcl_AppendResult(interp, "out of memory", (char *) NULL); + } + Unlock(); + ZipFSCloseArchive(interp, &zf0); + return TCL_ERROR; + } + *zf = zf0; + zf->name = Tcl_GetHashKey(&ZipFS.zipHash, hPtr); + strcpy(zf->mntpt, mntpt); + zf->mntptlen = strlen(zf->mntpt); + zf->entries = NULL; + zf->topents = NULL; + zf->nopen = 0; + Tcl_SetHashValue(hPtr, (ClientData) zf); + if ((zf->pwbuf[0] == 0) && pwlen) { + int k = 0; + i = pwlen; + zf->pwbuf[k++] = i; + while (i > 0) { + zf->pwbuf[k] = (passwd[i - 1] & 0x0f) | + pwrot[(passwd[i - 1] >> 4) & 0x0f]; + k++; + i--; + } + zf->pwbuf[k] = '\0'; } if (mntpt[0] != '\0') { - z = (ZipEntry *) Tcl_Alloc(sizeof (*z)); - z->name = NULL; - z->tnext = NULL; - z->depth = CountSlashes(mntpt); - z->zipfile = zf; - z->isdir = 1; - z->isenc = 0; - z->offset = zf->baseoffs; - z->crc32 = 0; - z->timestamp = 0; - z->nbyte = z->nbytecompr = 0; - z->cmeth = ZIP_COMPMETH_STORED; - z->data = NULL; - hPtr = Tcl_CreateHashEntry(&ZipFS.fileHash, mntpt, &isNew); - if (!isNew) { - /* skip it */ - Tcl_Free((char *) z); - } else { - Tcl_SetHashValue(hPtr, (ClientData) z); - z->name = Tcl_GetHashKey(&ZipFS.fileHash, hPtr); - z->next = zf->entries; - zf->entries = z; - } + z = (ZipEntry *) Tcl_Alloc(sizeof (*z)); + z->name = NULL; + z->tnext = NULL; + z->depth = CountSlashes(mntpt); + z->zipfile = zf; + z->isdir = 1; + z->isenc = 0; + z->offset = zf->baseoffs; + z->crc32 = 0; + z->timestamp = 0; + z->nbyte = z->nbytecompr = 0; + z->cmeth = ZIP_COMPMETH_STORED; + z->data = NULL; + hPtr = Tcl_CreateHashEntry(&ZipFS.fileHash, mntpt, &isNew); + if (!isNew) { + /* skip it */ + Tcl_Free((char *) z); + } else { + Tcl_SetHashValue(hPtr, (ClientData) z); + z->name = Tcl_GetHashKey(&ZipFS.fileHash, hPtr); + z->next = zf->entries; + zf->entries = z; + } } q = zf->data + zf->centoffs; Tcl_DStringInit(&fpBuf); Tcl_DStringInit(&ds); for (i = 0; i < zf->nfiles; i++) { - int pathlen, comlen, extra, isdir = 0, dosTime, dosDate, nbcompr, offs; - unsigned char *lq, *gq = NULL; - char *fullpath, *path; - - pathlen = zip_read_short(q + ZIP_CENTRAL_PATHLEN_OFFS); - comlen = zip_read_short(q + ZIP_CENTRAL_FCOMMENTLEN_OFFS); - extra = zip_read_short(q + ZIP_CENTRAL_EXTRALEN_OFFS); - Tcl_DStringSetLength(&ds, 0); - Tcl_DStringAppend(&ds, (char *) q + ZIP_CENTRAL_HEADER_LEN, pathlen); - path = Tcl_DStringValue(&ds); - if ((pathlen > 0) && (path[pathlen - 1] == '/')) { - Tcl_DStringSetLength(&ds, pathlen - 1); - path = Tcl_DStringValue(&ds); - isdir = 1; - } - if ((strcmp(path, ".") == 0) || (strcmp(path, "..") == 0)) { - goto nextent; - } - lq = zf->data + zf->baseoffs + - zip_read_int(q + ZIP_CENTRAL_LOCALHDR_OFFS); - if ((lq < zf->data) || (lq > (zf->data + zf->length))) { - goto nextent; - } - nbcompr = zip_read_int(lq + ZIP_LOCAL_COMPLEN_OFFS); - if (!isdir && (nbcompr == 0) && - (zip_read_int(lq + ZIP_LOCAL_UNCOMPLEN_OFFS) == 0) && - (zip_read_int(lq + ZIP_LOCAL_CRC32_OFFS) == 0)) { - gq = q; - nbcompr = zip_read_int(gq + ZIP_CENTRAL_COMPLEN_OFFS); - } - offs = (lq - zf->data) - + ZIP_LOCAL_HEADER_LEN - + zip_read_short(lq + ZIP_LOCAL_PATHLEN_OFFS) - + zip_read_short(lq + ZIP_LOCAL_EXTRALEN_OFFS); - if ((offs + nbcompr) > zf->length) { - goto nextent; - } - if (!isdir && (mntpt[0] == '\0') && !CountSlashes(path)) { + int pathlen, comlen, extra, isdir = 0, dosTime, dosDate, nbcompr, offs; + unsigned char *lq, *gq = NULL; + char *fullpath, *path; + + pathlen = zip_read_short(q + ZIP_CENTRAL_PATHLEN_OFFS); + comlen = zip_read_short(q + ZIP_CENTRAL_FCOMMENTLEN_OFFS); + extra = zip_read_short(q + ZIP_CENTRAL_EXTRALEN_OFFS); + Tcl_DStringSetLength(&ds, 0); + Tcl_DStringAppend(&ds, (char *) q + ZIP_CENTRAL_HEADER_LEN, pathlen); + path = Tcl_DStringValue(&ds); + if ((pathlen > 0) && (path[pathlen - 1] == '/')) { + Tcl_DStringSetLength(&ds, pathlen - 1); + path = Tcl_DStringValue(&ds); + isdir = 1; + } + if ((strcmp(path, ".") == 0) || (strcmp(path, "..") == 0)) { + goto nextent; + } + lq = zf->data + zf->baseoffs + zip_read_int(q + ZIP_CENTRAL_LOCALHDR_OFFS); + if ((lq < zf->data) || (lq > (zf->data + zf->length))) { + goto nextent; + } + nbcompr = zip_read_int(lq + ZIP_LOCAL_COMPLEN_OFFS); + if ( + !isdir && (nbcompr == 0) + && (zip_read_int(lq + ZIP_LOCAL_UNCOMPLEN_OFFS) == 0) + && (zip_read_int(lq + ZIP_LOCAL_CRC32_OFFS) == 0) + ) { + gq = q; + nbcompr = zip_read_int(gq + ZIP_CENTRAL_COMPLEN_OFFS); + } + offs = (lq - zf->data) + + ZIP_LOCAL_HEADER_LEN + + zip_read_short(lq + ZIP_LOCAL_PATHLEN_OFFS) + + zip_read_short(lq + ZIP_LOCAL_EXTRALEN_OFFS); + if ((offs + nbcompr) > zf->length) { + goto nextent; + } + if (!isdir && (mntpt[0] == '\0') && !CountSlashes(path)) { #ifdef ANDROID - /* - * When mounting the ZIP archive on the root directory try - * to remap top level regular files of the archive to - * /assets/.root/... since this directory should not be - * in a valid APK due to the leading dot in the file name - * component. This trick should make the files - * AndroidManifest.xml, resources.arsc, and classes.dex - * visible to Tcl. - */ - Tcl_DString ds2; - - Tcl_DStringInit(&ds2); - Tcl_DStringAppend(&ds2, "assets/.root/", -1); - Tcl_DStringAppend(&ds2, path, -1); - hPtr = Tcl_FindHashEntry(&ZipFS.fileHash, Tcl_DStringValue(&ds2)); - if (hPtr != NULL) { - /* should not happen but skip it anyway */ - Tcl_DStringFree(&ds2); - goto nextent; - } - Tcl_DStringSetLength(&ds, 0); - Tcl_DStringAppend(&ds, Tcl_DStringValue(&ds2), - Tcl_DStringLength(&ds2)); - path = Tcl_DStringValue(&ds); - Tcl_DStringFree(&ds2); + /* + * When mounting the ZIP archive on the root directory try + * to remap top level regular files of the archive to + * /assets/.root/... since this directory should not be + * in a valid APK due to the leading dot in the file name + * component. This trick should make the files + * AndroidManifest.xml, resources.arsc, and classes.dex + * visible to Tcl. + */ + Tcl_DString ds2; + + Tcl_DStringInit(&ds2); + Tcl_DStringAppend(&ds2, "assets/.root/", -1); + Tcl_DStringAppend(&ds2, path, -1); + hPtr = Tcl_FindHashEntry(&ZipFS.fileHash, Tcl_DStringValue(&ds2)); + if (hPtr != NULL) { + /* should not happen but skip it anyway */ + Tcl_DStringFree(&ds2); + goto nextent; + } + Tcl_DStringSetLength(&ds, 0); + Tcl_DStringAppend(&ds, Tcl_DStringValue(&ds2), Tcl_DStringLength(&ds2)); + path = Tcl_DStringValue(&ds); + Tcl_DStringFree(&ds2); #else - /* - * Regular files skipped when mounting on root. - */ - goto nextent; + /* + * Regular files skipped when mounting on root. + */ + goto nextent; #endif - } - Tcl_DStringSetLength(&fpBuf, 0); - fullpath = CanonicalPath(mntpt, path, &fpBuf, 1); - z = (ZipEntry *) Tcl_Alloc(sizeof (*z)); - z->name = NULL; - z->tnext = NULL; - z->depth = CountSlashes(fullpath); - z->zipfile = zf; - z->isdir = isdir; - z->isenc = (zip_read_short(lq + ZIP_LOCAL_FLAGS_OFFS) & 1) - && (nbcompr > 12); - z->offset = offs; - if (gq != NULL) { - z->crc32 = zip_read_int(gq + ZIP_CENTRAL_CRC32_OFFS); - dosDate = zip_read_short(gq + ZIP_CENTRAL_MDATE_OFFS); - dosTime = zip_read_short(gq + ZIP_CENTRAL_MTIME_OFFS); - z->timestamp = DosTimeDate(dosDate, dosTime); - z->nbyte = zip_read_int(gq + ZIP_CENTRAL_UNCOMPLEN_OFFS); - z->cmeth = zip_read_short(gq + ZIP_CENTRAL_COMPMETH_OFFS); - } else { - z->crc32 = zip_read_int(lq + ZIP_LOCAL_CRC32_OFFS); - dosDate = zip_read_short(lq + ZIP_LOCAL_MDATE_OFFS); - dosTime = zip_read_short(lq + ZIP_LOCAL_MTIME_OFFS); - z->timestamp = DosTimeDate(dosDate, dosTime); - z->nbyte = zip_read_int(lq + ZIP_LOCAL_UNCOMPLEN_OFFS); - z->cmeth = zip_read_short(lq + ZIP_LOCAL_COMPMETH_OFFS); - } - z->nbytecompr = nbcompr; - z->data = NULL; - hPtr = Tcl_CreateHashEntry(&ZipFS.fileHash, fullpath, &isNew); - if (!isNew) { - /* should not happen but skip it anyway */ - Tcl_Free((char *) z); - } else { - Tcl_SetHashValue(hPtr, (ClientData) z); - z->name = Tcl_GetHashKey(&ZipFS.fileHash, hPtr); - z->next = zf->entries; - zf->entries = z; - if (isdir && (mntpt[0] == '\0') && (z->depth == 1)) { - z->tnext = zf->topents; - zf->topents = z; - } - if (!z->isdir && (z->depth > 1)) { - char *dir, *end; - ZipEntry *zd; - - Tcl_DStringSetLength(&ds, strlen(z->name) + 8); - Tcl_DStringSetLength(&ds, 0); - Tcl_DStringAppend(&ds, z->name, -1); - dir = Tcl_DStringValue(&ds); - end = strrchr(dir, '/'); - while ((end != NULL) && (end != dir)) { - Tcl_DStringSetLength(&ds, end - dir); - hPtr = Tcl_FindHashEntry(&ZipFS.fileHash, dir); - if (hPtr != NULL) { - break; - } - zd = (ZipEntry *) Tcl_Alloc(sizeof (*zd)); - zd->name = NULL; - zd->tnext = NULL; - zd->depth = CountSlashes(dir); - zd->zipfile = zf; - zd->isdir = 1; - zd->isenc = 0; - zd->offset = z->offset; - zd->crc32 = 0; - zd->timestamp = z->timestamp; - zd->nbyte = zd->nbytecompr = 0; - zd->cmeth = ZIP_COMPMETH_STORED; - zd->data = NULL; - hPtr = Tcl_CreateHashEntry(&ZipFS.fileHash, dir, &isNew); - if (!isNew) { - /* should not happen but skip it anyway */ - Tcl_Free((char *) zd); - } else { - Tcl_SetHashValue(hPtr, (ClientData) zd); - zd->name = Tcl_GetHashKey(&ZipFS.fileHash, hPtr); - zd->next = zf->entries; - zf->entries = zd; - if ((mntpt[0] == '\0') && (zd->depth == 1)) { - zd->tnext = zf->topents; - zf->topents = zd; - } - } - end = strrchr(dir, '/'); - } - } - } + } + Tcl_DStringSetLength(&fpBuf, 0); + fullpath = CanonicalPath(mntpt, path, &fpBuf, 1); + z = (ZipEntry *) Tcl_Alloc(sizeof (*z)); + z->name = NULL; + z->tnext = NULL; + z->depth = CountSlashes(fullpath); + z->zipfile = zf; + z->isdir = isdir; + z->isenc = (zip_read_short(lq + ZIP_LOCAL_FLAGS_OFFS) & 1) && (nbcompr > 12); + z->offset = offs; + if (gq != NULL) { + z->crc32 = zip_read_int(gq + ZIP_CENTRAL_CRC32_OFFS); + dosDate = zip_read_short(gq + ZIP_CENTRAL_MDATE_OFFS); + dosTime = zip_read_short(gq + ZIP_CENTRAL_MTIME_OFFS); + z->timestamp = DosTimeDate(dosDate, dosTime); + z->nbyte = zip_read_int(gq + ZIP_CENTRAL_UNCOMPLEN_OFFS); + z->cmeth = zip_read_short(gq + ZIP_CENTRAL_COMPMETH_OFFS); + } else { + z->crc32 = zip_read_int(lq + ZIP_LOCAL_CRC32_OFFS); + dosDate = zip_read_short(lq + ZIP_LOCAL_MDATE_OFFS); + dosTime = zip_read_short(lq + ZIP_LOCAL_MTIME_OFFS); + z->timestamp = DosTimeDate(dosDate, dosTime); + z->nbyte = zip_read_int(lq + ZIP_LOCAL_UNCOMPLEN_OFFS); + z->cmeth = zip_read_short(lq + ZIP_LOCAL_COMPMETH_OFFS); + } + z->nbytecompr = nbcompr; + z->data = NULL; + hPtr = Tcl_CreateHashEntry(&ZipFS.fileHash, fullpath, &isNew); + if (!isNew) { + /* should not happen but skip it anyway */ + Tcl_Free((char *) z); + } else { + Tcl_SetHashValue(hPtr, (ClientData) z); + z->name = Tcl_GetHashKey(&ZipFS.fileHash, hPtr); + z->next = zf->entries; + zf->entries = z; + if (isdir && (mntpt[0] == '\0') && (z->depth == 1)) { + z->tnext = zf->topents; + zf->topents = z; + } + if (!z->isdir && (z->depth > 1)) { + char *dir, *end; + ZipEntry *zd; + + Tcl_DStringSetLength(&ds, strlen(z->name) + 8); + Tcl_DStringSetLength(&ds, 0); + Tcl_DStringAppend(&ds, z->name, -1); + dir = Tcl_DStringValue(&ds); + end = strrchr(dir, '/'); + while ((end != NULL) && (end != dir)) { + Tcl_DStringSetLength(&ds, end - dir); + hPtr = Tcl_FindHashEntry(&ZipFS.fileHash, dir); + if (hPtr != NULL) { + break; + } + zd = (ZipEntry *) Tcl_Alloc(sizeof (*zd)); + zd->name = NULL; + zd->tnext = NULL; + zd->depth = CountSlashes(dir); + zd->zipfile = zf; + zd->isdir = 1; + zd->isenc = 0; + zd->offset = z->offset; + zd->crc32 = 0; + zd->timestamp = z->timestamp; + zd->nbyte = zd->nbytecompr = 0; + zd->cmeth = ZIP_COMPMETH_STORED; + zd->data = NULL; + hPtr = Tcl_CreateHashEntry(&ZipFS.fileHash, dir, &isNew); + if (!isNew) { + /* should not happen but skip it anyway */ + Tcl_Free((char *) zd); + } else { + Tcl_SetHashValue(hPtr, (ClientData) zd); + zd->name = Tcl_GetHashKey(&ZipFS.fileHash, hPtr); + zd->next = zf->entries; + zf->entries = zd; + if ((mntpt[0] == '\0') && (zd->depth == 1)) { + zd->tnext = zf->topents; + zf->topents = zd; + } + } + end = strrchr(dir, '/'); + } + } + } nextent: - q += pathlen + comlen + extra + ZIP_CENTRAL_HEADER_LEN; + q += pathlen + comlen + extra + ZIP_CENTRAL_HEADER_LEN; } Unlock(); Tcl_DStringFree(&fpBuf); @@ -1345,34 +1312,30 @@ TclZipfs_Unmount(Tcl_Interp *interp, const char *zipname) int ret = TCL_OK, unmounted = 0; WriteLock(); - if (!ZipFS.initialized) { - goto done; - } + if (!ZipFS.initialized) goto done; + hPtr = Tcl_FindHashEntry(&ZipFS.zipHash, zipname); - if (hPtr == NULL) { + /* don't report error */ - goto done; - } + if (hPtr == NULL) goto done; + zf = (ZipFile *) Tcl_GetHashValue(hPtr); if (zf->nopen > 0) { - if (interp != NULL) { - Tcl_SetObjResult(interp, - Tcl_NewStringObj("filesystem is busy", -1)); - } - ret = TCL_ERROR; - goto done; + ZIPFS_ERROR(interp,"filesystem is busy"); + ret = TCL_ERROR; + goto done; } Tcl_DeleteHashEntry(hPtr); for (z = zf->entries; z; z = znext) { - znext = z->next; - hPtr = Tcl_FindHashEntry(&ZipFS.fileHash, z->name); - if (hPtr) { - Tcl_DeleteHashEntry(hPtr); - } - if (z->data != NULL) { - Tcl_Free((char *) z->data); - } - Tcl_Free((char *) z); + znext = z->next; + hPtr = Tcl_FindHashEntry(&ZipFS.fileHash, z->name); + if (hPtr) { + Tcl_DeleteHashEntry(hPtr); + } + if (z->data != NULL) { + Tcl_Free((char *) z->data); + } + Tcl_Free((char *) z); } ZipFSCloseArchive(interp, zf); Tcl_Free((char *) zf); @@ -1380,7 +1343,7 @@ TclZipfs_Unmount(Tcl_Interp *interp, const char *zipname) done: Unlock(); if (unmounted) { - Tcl_FSMountsChanged(NULL); + Tcl_FSMountsChanged(NULL); } return ret; } @@ -1402,13 +1365,13 @@ done: */ static int -ZipFSMountObjCmd(ClientData clientData, Tcl_Interp *interp, - int objc, Tcl_Obj *const objv[]) -{ +ZipFSMountObjCmd( + ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[] +) { if (objc > 4) { - Tcl_WrongNumArgs(interp, 1, objv, - "?zipfile? ?mountpoint? ?password?"); - return TCL_ERROR; + Tcl_WrongNumArgs(interp, 1, objv, + "?zipfile? ?mountpoint? ?password?"); + return TCL_ERROR; } return TclZipfs_Mount(interp, (objc > 1) ? Tcl_GetString(objv[1]) : NULL, (objc > 2) ? Tcl_GetString(objv[2]) : NULL, @@ -1432,9 +1395,9 @@ ZipFSMountObjCmd(ClientData clientData, Tcl_Interp *interp, */ static int -ZipFSRootObjCmd(ClientData clientData, Tcl_Interp *interp, - int objc, Tcl_Obj *const objv[]) -{ +ZipFSRootObjCmd( + ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[] +) { Tcl_SetObjResult(interp,Tcl_NewStringObj(ZIPFS_VOLUME, -1)); return TCL_OK; } @@ -1456,12 +1419,12 @@ ZipFSRootObjCmd(ClientData clientData, Tcl_Interp *interp, */ static int -ZipFSUnmountObjCmd(ClientData clientData, Tcl_Interp *interp, - int objc, Tcl_Obj *const objv[]) -{ +ZipFSUnmountObjCmd( + ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[] +) { if (objc != 2) { - Tcl_WrongNumArgs(interp, 1, objv, "zipfile"); - return TCL_ERROR; + Tcl_WrongNumArgs(interp, 1, objv, "zipfile"); + return TCL_ERROR; } return TclZipfs_Unmount(interp, Tcl_GetString(objv[1])); } @@ -1484,32 +1447,31 @@ ZipFSUnmountObjCmd(ClientData clientData, Tcl_Interp *interp, */ static int -ZipFSMkKeyObjCmd(ClientData clientData, Tcl_Interp *interp, - int objc, Tcl_Obj *const objv[]) -{ +ZipFSMkKeyObjCmd( + ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[] +) { int len, i = 0; char *pw, pwbuf[264]; if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "password"); - return TCL_ERROR; + return TCL_ERROR; } pw = Tcl_GetString(objv[1]); len = strlen(pw); if (len == 0) { - return TCL_OK; + return TCL_OK; } if ((len > 255) || (strchr(pw, 0xff) != NULL)) { - Tcl_SetObjResult(interp, - Tcl_NewStringObj("illegal password", -1)); - return TCL_ERROR; + Tcl_SetObjResult(interp, Tcl_NewStringObj("illegal password", -1)); + return TCL_ERROR; } while (len > 0) { - int ch = pw[len - 1]; + int ch = pw[len - 1]; - pwbuf[i] = (ch & 0x0f) | pwrot[(ch >> 4) & 0x0f]; - i++; - len--; + pwbuf[i] = (ch & 0x0f) | pwrot[(ch >> 4) & 0x0f]; + i++; + len--; } pwbuf[i] = i; ++i; @@ -1543,10 +1505,11 @@ ZipFSMkKeyObjCmd(ClientData clientData, Tcl_Interp *interp, */ static int -ZipAddFile(Tcl_Interp *interp, const char *path, const char *name, - Tcl_Channel out, const char *passwd, - char *buf, int bufsize, Tcl_HashTable *fileHash) -{ +ZipAddFile( + Tcl_Interp *interp, const char *path, const char *name, + Tcl_Channel out, const char *passwd, + char *buf, int bufsize, Tcl_HashTable *fileHash +) { Tcl_Channel in; Tcl_HashEntry *hPtr; ZipEntry *z; @@ -1559,67 +1522,66 @@ ZipAddFile(Tcl_Interp *interp, const char *path, const char *name, zpath = name; while (zpath != NULL && zpath[0] == '/') { - zpath++; + zpath++; } if ((zpath == NULL) || (zpath[0] == '\0')) { - return TCL_OK; + return TCL_OK; } zpathlen = strlen(zpath); if (zpathlen + ZIP_CENTRAL_HEADER_LEN > bufsize) { - Tcl_AppendResult(interp, "path too long for \"", path, "\"", - (char *) NULL); - return TCL_ERROR; + Tcl_AppendResult(interp, "path too long for \"", path, "\"", (char *) NULL); + return TCL_ERROR; } in = Tcl_OpenFileChannel(interp, path, "r", 0); - if ((in == NULL) || - (Tcl_SetChannelOption(interp, in, "-translation", "binary") - != TCL_OK) || - (Tcl_SetChannelOption(interp, in, "-encoding", "binary") - != TCL_OK)) { + if ( + (in == NULL) + || (Tcl_SetChannelOption(interp, in, "-translation", "binary") != TCL_OK) + || (Tcl_SetChannelOption(interp, in, "-encoding", "binary") != TCL_OK) + ) { #if defined(_WIN32) || defined(_WIN64) - /* hopefully a directory */ - if (strcmp("permission denied", Tcl_PosixError(interp)) == 0) { - Tcl_Close(interp, in); - return TCL_OK; - } + /* hopefully a directory */ + if (strcmp("permission denied", Tcl_PosixError(interp)) == 0) { + Tcl_Close(interp, in); + return TCL_OK; + } #endif - Tcl_Close(interp, in); - return TCL_ERROR; + Tcl_Close(interp, in); + return TCL_ERROR; } else { - Tcl_Obj *pathObj = Tcl_NewStringObj(path, -1); - Tcl_StatBuf statBuf; + Tcl_Obj *pathObj = Tcl_NewStringObj(path, -1); + Tcl_StatBuf statBuf; - Tcl_IncrRefCount(pathObj); - if (Tcl_FSStat(pathObj, &statBuf) != -1) { - mtime = statBuf.st_mtime; - } - Tcl_DecrRefCount(pathObj); + Tcl_IncrRefCount(pathObj); + if (Tcl_FSStat(pathObj, &statBuf) != -1) { + mtime = statBuf.st_mtime; + } + Tcl_DecrRefCount(pathObj); } Tcl_ResetResult(interp); crc = 0; nbyte = nbytecompr = 0; while ((len = Tcl_Read(in, buf, bufsize)) > 0) { - crc = crc32(crc, (unsigned char *) buf, len); - nbyte += len; + crc = crc32(crc, (unsigned char *) buf, len); + nbyte += len; } if (len == -1) { - if (nbyte == 0) { - if (strcmp("illegal operation on a directory", - Tcl_PosixError(interp)) == 0) { - Tcl_Close(interp, in); - return TCL_OK; - } - } - Tcl_AppendResult(interp, "read error on \"", path, "\"", - (char *) NULL); - Tcl_Close(interp, in); - return TCL_ERROR; + if (nbyte == 0) { + if (strcmp("illegal operation on a directory", + Tcl_PosixError(interp)) == 0) { + Tcl_Close(interp, in); + return TCL_OK; + } + } + Tcl_AppendResult(interp, "read error on \"", path, "\"", + (char *) NULL); + Tcl_Close(interp, in); + return TCL_ERROR; } if (Tcl_Seek(in, 0, SEEK_SET) == -1) { - Tcl_AppendResult(interp, "seek error on \"", path, "\"", - (char *) NULL); - Tcl_Close(interp, in); - return TCL_ERROR; + Tcl_AppendResult(interp, "seek error on \"", path, "\"", + (char *) NULL); + Tcl_Close(interp, in); + return TCL_ERROR; } pos[0] = Tcl_Tell(out); memset(buf, '\0', ZIP_LOCAL_HEADER_LEN); @@ -1632,56 +1594,55 @@ wrerr: return TCL_ERROR; } if ((len + pos[0]) & 3) { - char abuf[8]; - - /* - * Align payload to next 4-byte boundary using a dummy extra - * entry similar to the zipalign tool from Android's SDK. - */ - align = 4 + ((len + pos[0]) & 3); - zip_write_short(abuf, 0xffff); - zip_write_short(abuf + 2, align - 4); - zip_write_int(abuf + 4, 0x03020100); - if (Tcl_Write(out, abuf, align) != align) { - goto wrerr; - } + char abuf[8]; + + /* + * Align payload to next 4-byte boundary using a dummy extra + * entry similar to the zipalign tool from Android's SDK. + */ + align = 4 + ((len + pos[0]) & 3); + zip_write_short(abuf, 0xffff); + zip_write_short(abuf + 2, align - 4); + zip_write_int(abuf + 4, 0x03020100); + if (Tcl_Write(out, abuf, align) != align) { + goto wrerr; + } } if (passwd != NULL) { - int i, ch, tmp; - unsigned char kvbuf[24]; - Tcl_Obj *ret; - - init_keys(passwd, keys, crc32tab); - for (i = 0; i < 12 - 2; i++) { - if (Tcl_EvalEx(interp, "expr int(rand() * 256) % 256", -1, 0) != TCL_OK) { - Tcl_AppendResult(interp, "PRNG error", (char *) NULL); - Tcl_Close(interp, in); - return TCL_ERROR; - } - ret = Tcl_GetObjResult(interp); - if (Tcl_GetIntFromObj(interp, ret, &ch) != TCL_OK) { - Tcl_Close(interp, in); - return TCL_ERROR; - } - kvbuf[i + 12] = (unsigned char) zencode(keys, crc32tab, ch, tmp); - } - Tcl_ResetResult(interp); - init_keys(passwd, keys, crc32tab); - for (i = 0; i < 12 - 2; i++) { - kvbuf[i] = (unsigned char) zencode(keys, crc32tab, - kvbuf[i + 12], tmp); - } - kvbuf[i++] = (unsigned char) zencode(keys, crc32tab, crc >> 16, tmp); - kvbuf[i++] = (unsigned char) zencode(keys, crc32tab, crc >> 24, tmp); - len = Tcl_Write(out, (char *) kvbuf, 12); - memset(kvbuf, 0, 24); - if (len != 12) { - Tcl_AppendResult(interp, "write error", (char *) NULL); - Tcl_Close(interp, in); - return TCL_ERROR; - } - memcpy(keys0, keys, sizeof (keys0)); - nbytecompr += 12; + int i, ch, tmp; + unsigned char kvbuf[24]; + Tcl_Obj *ret; + + init_keys(passwd, keys, crc32tab); + for (i = 0; i < 12 - 2; i++) { + if (Tcl_EvalEx(interp, "expr int(rand() * 256) % 256", -1, 0) != TCL_OK) { + Tcl_AppendResult(interp, "PRNG error", (char *) NULL); + Tcl_Close(interp, in); + return TCL_ERROR; + } + ret = Tcl_GetObjResult(interp); + if (Tcl_GetIntFromObj(interp, ret, &ch) != TCL_OK) { + Tcl_Close(interp, in); + return TCL_ERROR; + } + kvbuf[i + 12] = (unsigned char) zencode(keys, crc32tab, ch, tmp); + } + Tcl_ResetResult(interp); + init_keys(passwd, keys, crc32tab); + for (i = 0; i < 12 - 2; i++) { + kvbuf[i] = (unsigned char) zencode(keys, crc32tab, kvbuf[i + 12], tmp); + } + kvbuf[i++] = (unsigned char) zencode(keys, crc32tab, crc >> 16, tmp); + kvbuf[i++] = (unsigned char) zencode(keys, crc32tab, crc >> 24, tmp); + len = Tcl_Write(out, (char *) kvbuf, 12); + memset(kvbuf, 0, 24); + if (len != 12) { + Tcl_AppendResult(interp, "write error", (char *) NULL); + Tcl_Close(interp, in); + return TCL_ERROR; + } + memcpy(keys0, keys, sizeof (keys0)); + nbytecompr += 12; } Tcl_Flush(out); pos[2] = Tcl_Tell(out); @@ -1690,12 +1651,11 @@ wrerr: stream.zalloc = Z_NULL; stream.zfree = Z_NULL; stream.opaque = Z_NULL; - if (deflateInit2(&stream, 9, Z_DEFLATED, -15, 8, Z_DEFAULT_STRATEGY) - != Z_OK) { - Tcl_AppendResult(interp, "compression init error on \"", path, "\"", - (char *) NULL); - Tcl_Close(interp, in); - return TCL_ERROR; + if (deflateInit2(&stream, 9, Z_DEFLATED, -15, 8, Z_DEFAULT_STRATEGY) != Z_OK) { + Tcl_AppendResult(interp, "compression init error on \"", path, "\"", + (char *) NULL); + Tcl_Close(interp, in); + return TCL_ERROR; } do { len = Tcl_Read(in, buf, bufsize); @@ -1714,25 +1674,25 @@ wrerr: stream.next_out = (unsigned char *) obuf; len = deflate(&stream, flush); if (len == Z_STREAM_ERROR) { - Tcl_AppendResult(interp, "deflate error on \"", path, "\"", - (char *) NULL); - deflateEnd(&stream); - Tcl_Close(interp, in); - return TCL_ERROR; + Tcl_AppendResult(interp, "deflate error on \"", path, "\"", + (char *) NULL); + deflateEnd(&stream); + Tcl_Close(interp, in); + return TCL_ERROR; } olen = sizeof (obuf) - stream.avail_out; if (passwd != NULL) { - int i, tmp; + int i, tmp; - for (i = 0; i < olen; i++) { - obuf[i] = (char) zencode(keys, crc32tab, obuf[i], tmp); - } + for (i = 0; i < olen; i++) { + obuf[i] = (char) zencode(keys, crc32tab, obuf[i], tmp); + } } if (olen && (Tcl_Write(out, obuf, olen) != olen)) { - Tcl_AppendResult(interp, "write error", (char *) NULL); - deflateEnd(&stream); - Tcl_Close(interp, in); - return TCL_ERROR; + Tcl_AppendResult(interp, "write error", (char *) NULL); + deflateEnd(&stream); + Tcl_Close(interp, in); + return TCL_ERROR; } nbytecompr += olen; } while (stream.avail_out == 0); @@ -1741,48 +1701,48 @@ wrerr: Tcl_Flush(out); pos[1] = Tcl_Tell(out); if (nbyte - nbytecompr <= 0) { - /* - * Compressed file larger than input, - * write it again uncompressed. - */ - if ((int) Tcl_Seek(in, 0, SEEK_SET) != 0) { - goto seekErr; - } - if ((int) Tcl_Seek(out, pos[2], SEEK_SET) != pos[2]) { + /* + * Compressed file larger than input, + * write it again uncompressed. + */ + if ((int) Tcl_Seek(in, 0, SEEK_SET) != 0) { + goto seekErr; + } + if ((int) Tcl_Seek(out, pos[2], SEEK_SET) != pos[2]) { seekErr: - Tcl_Close(interp, in); - Tcl_AppendResult(interp, "seek error", (char *) NULL); - return TCL_ERROR; - } - nbytecompr = (passwd != NULL) ? 12 : 0; - while (1) { - len = Tcl_Read(in, buf, bufsize); - if (len == -1) { - Tcl_AppendResult(interp, "read error on \"", path, "\"", - (char *) NULL); - Tcl_Close(interp, in); - return TCL_ERROR; - } else if (len == 0) { - break; - } - if (passwd != NULL) { - int i, tmp; + Tcl_Close(interp, in); + Tcl_AppendResult(interp, "seek error", (char *) NULL); + return TCL_ERROR; + } + nbytecompr = (passwd != NULL) ? 12 : 0; + while (1) { + len = Tcl_Read(in, buf, bufsize); + if (len == -1) { + Tcl_AppendResult(interp, "read error on \"", path, "\"", + (char *) NULL); + Tcl_Close(interp, in); + return TCL_ERROR; + } else if (len == 0) { + break; + } + if (passwd != NULL) { + int i, tmp; - for (i = 0; i < len; i++) { - buf[i] = (char) zencode(keys0, crc32tab, buf[i], tmp); - } - } - if (Tcl_Write(out, buf, len) != len) { - Tcl_AppendResult(interp, "write error", (char *) NULL); - Tcl_Close(interp, in); - return TCL_ERROR; - } - nbytecompr += len; - } - cmeth = ZIP_COMPMETH_STORED; - Tcl_Flush(out); - pos[1] = Tcl_Tell(out); - Tcl_TruncateChannel(out, pos[1]); + for (i = 0; i < len; i++) { + buf[i] = (char) zencode(keys0, crc32tab, buf[i], tmp); + } + } + if (Tcl_Write(out, buf, len) != len) { + Tcl_AppendResult(interp, "write error", (char *) NULL); + Tcl_Close(interp, in); + return TCL_ERROR; + } + nbytecompr += len; + } + cmeth = ZIP_COMPMETH_STORED; + Tcl_Flush(out); + pos[1] = Tcl_Tell(out); + Tcl_TruncateChannel(out, pos[1]); } Tcl_Close(interp, in); @@ -1802,14 +1762,14 @@ seekErr: z->data = NULL; hPtr = Tcl_CreateHashEntry(fileHash, zpath, &isNew); if (!isNew) { - Tcl_AppendResult(interp, "non-unique path name \"", path, "\"", - (char *) NULL); - Tcl_Free((char *) z); - return TCL_ERROR; + Tcl_AppendResult(interp, "non-unique path name \"", path, "\"", + (char *) NULL); + Tcl_Free((char *) z); + return TCL_ERROR; } else { - Tcl_SetHashValue(hPtr, (ClientData) z); - z->name = Tcl_GetHashKey(fileHash, hPtr); - z->next = NULL; + Tcl_SetHashValue(hPtr, (ClientData) z); + z->name = Tcl_GetHashKey(fileHash, hPtr); + z->next = NULL; } /* @@ -1827,23 +1787,23 @@ seekErr: zip_write_short(buf + ZIP_LOCAL_PATHLEN_OFFS, zpathlen); zip_write_short(buf + ZIP_LOCAL_EXTRALEN_OFFS, align); if ((int) Tcl_Seek(out, pos[0], SEEK_SET) != pos[0]) { - Tcl_DeleteHashEntry(hPtr); - Tcl_Free((char *) z); - Tcl_AppendResult(interp, "seek error", (char *) NULL); - return TCL_ERROR; + Tcl_DeleteHashEntry(hPtr); + Tcl_Free((char *) z); + Tcl_AppendResult(interp, "seek error", (char *) NULL); + return TCL_ERROR; } if (Tcl_Write(out, buf, ZIP_LOCAL_HEADER_LEN) != ZIP_LOCAL_HEADER_LEN) { - Tcl_DeleteHashEntry(hPtr); - Tcl_Free((char *) z); - Tcl_AppendResult(interp, "write error", (char *) NULL); - return TCL_ERROR; + Tcl_DeleteHashEntry(hPtr); + Tcl_Free((char *) z); + Tcl_AppendResult(interp, "write error", (char *) NULL); + return TCL_ERROR; } Tcl_Flush(out); if ((int) Tcl_Seek(out, pos[1], SEEK_SET) != pos[1]) { - Tcl_DeleteHashEntry(hPtr); - Tcl_Free((char *) z); - Tcl_AppendResult(interp, "seek error", (char *) NULL); - return TCL_ERROR; + Tcl_DeleteHashEntry(hPtr); + Tcl_Free((char *) z); + Tcl_AppendResult(interp, "seek error", (char *) NULL); + return TCL_ERROR; } return TCL_OK; } @@ -1868,9 +1828,9 @@ seekErr: */ static int -ZipFSMkZipOrImgObjCmd(ClientData clientData, Tcl_Interp *interp, - int isImg, int isList, int objc, Tcl_Obj *const objv[]) -{ +ZipFSMkZipOrImgObjCmd( + ClientData clientData, Tcl_Interp *interp,int isImg, int isList, int objc, Tcl_Obj *const objv[] +) { Tcl_Channel out; int len = 0, pwlen = 0, slen = 0, i, count, ret = TCL_ERROR, lobjc, pos[3]; Tcl_Obj **lobjv, *list = NULL; @@ -1881,161 +1841,160 @@ ZipFSMkZipOrImgObjCmd(ClientData clientData, Tcl_Interp *interp, char *strip = NULL, *pw = NULL, pwbuf[264], buf[4096]; if (isList) { - if ((objc < 3) || (objc > (isImg ? 5 : 4))) { - Tcl_WrongNumArgs(interp, 1, objv, isImg ? - "outfile inlist ?password infile?" : - "outfile inlist ?password?"); - return TCL_ERROR; - } + if ((objc < 3) || (objc > (isImg ? 5 : 4))) { + Tcl_WrongNumArgs(interp, 1, objv, isImg ? + "outfile inlist ?password infile?" : + "outfile inlist ?password?"); + return TCL_ERROR; + } } else { - if ((objc < 3) || (objc > (isImg ? 6 : 5))) { - Tcl_WrongNumArgs(interp, 1, objv, isImg ? - "outfile indir ?strip? ?password? ?infile?" : - "outfile indir ?strip? ?password?"); - return TCL_ERROR; - } + if ((objc < 3) || (objc > (isImg ? 6 : 5))) { + Tcl_WrongNumArgs(interp, 1, objv, isImg ? + "outfile indir ?strip? ?password? ?infile?" : + "outfile indir ?strip? ?password?"); + return TCL_ERROR; + } } pwbuf[0] = 0; if (objc > (isList ? 3 : 4)) { - pw = Tcl_GetString(objv[isList ? 3 : 4]); - pwlen = strlen(pw); - if ((pwlen > 255) || (strchr(pw, 0xff) != NULL)) { - Tcl_SetObjResult(interp, - Tcl_NewStringObj("illegal password", -1)); - return TCL_ERROR; - } + pw = Tcl_GetString(objv[isList ? 3 : 4]); + pwlen = strlen(pw); + if ((pwlen > 255) || (strchr(pw, 0xff) != NULL)) { + Tcl_SetObjResult(interp, + Tcl_NewStringObj("illegal password", -1)); + return TCL_ERROR; + } } if (isList) { - list = objv[2]; - Tcl_IncrRefCount(list); + list = objv[2]; + Tcl_IncrRefCount(list); } else { - Tcl_Obj *cmd[3]; - - cmd[1] = Tcl_NewStringObj("::zipfs::find", -1); - cmd[2] = objv[2]; - cmd[0] = Tcl_NewListObj(2, cmd + 1); - Tcl_IncrRefCount(cmd[0]); - if (Tcl_EvalObjEx(interp, cmd[0], TCL_EVAL_DIRECT) != TCL_OK) { - Tcl_DecrRefCount(cmd[0]); - return TCL_ERROR; - } - Tcl_DecrRefCount(cmd[0]); - list = Tcl_GetObjResult(interp); - Tcl_IncrRefCount(list); + Tcl_Obj *cmd[3]; + + cmd[1] = Tcl_NewStringObj("::tcl::zipfs::find", -1); + cmd[2] = objv[2]; + cmd[0] = Tcl_NewListObj(2, cmd + 1); + Tcl_IncrRefCount(cmd[0]); + if (Tcl_EvalObjEx(interp, cmd[0], TCL_EVAL_DIRECT) != TCL_OK) { + Tcl_DecrRefCount(cmd[0]); + return TCL_ERROR; + } + Tcl_DecrRefCount(cmd[0]); + list = Tcl_GetObjResult(interp); + Tcl_IncrRefCount(list); } if (Tcl_ListObjGetElements(interp, list, &lobjc, &lobjv) != TCL_OK) { - Tcl_DecrRefCount(list); - return TCL_ERROR; + Tcl_DecrRefCount(list); + return TCL_ERROR; } if (isList && (lobjc % 2)) { - Tcl_DecrRefCount(list); - Tcl_SetObjResult(interp, - Tcl_NewStringObj("need even number of elements", -1)); - return TCL_ERROR; + Tcl_DecrRefCount(list); + Tcl_SetObjResult(interp, + Tcl_NewStringObj("need even number of elements", -1)); + return TCL_ERROR; } if (lobjc == 0) { - Tcl_DecrRefCount(list); - Tcl_SetObjResult(interp, Tcl_NewStringObj("empty archive", -1)); - return TCL_ERROR; + Tcl_DecrRefCount(list); + Tcl_SetObjResult(interp, Tcl_NewStringObj("empty archive", -1)); + return TCL_ERROR; } out = Tcl_OpenFileChannel(interp, Tcl_GetString(objv[1]), "w", 0755); - if ((out == NULL) || - (Tcl_SetChannelOption(interp, out, "-translation", "binary") - != TCL_OK) || - (Tcl_SetChannelOption(interp, out, "-encoding", "binary") - != TCL_OK)) { - Tcl_DecrRefCount(list); - Tcl_Close(interp, out); - return TCL_ERROR; - } - if (isImg) { - ZipFile zf0; - const char *imgName; - - if (isList) { - imgName = (objc > 4) ? Tcl_GetString(objv[4]) : - Tcl_GetNameOfExecutable(); - } else { - imgName = (objc > 5) ? Tcl_GetString(objv[5]) : - Tcl_GetNameOfExecutable(); - } - if (ZipFSOpenArchive(interp, imgName, 0, &zf0) != TCL_OK) { - Tcl_DecrRefCount(list); - Tcl_Close(interp, out); - return TCL_ERROR; - } - if ((pw != NULL) && pwlen) { - i = 0; - len = pwlen; - while (len > 0) { - int ch = pw[len - 1]; - - pwbuf[i] = (ch & 0x0f) | pwrot[(ch >> 4) & 0x0f]; - i++; - len--; - } - pwbuf[i] = i; - ++i; - pwbuf[i++] = (char) ZIP_PASSWORD_END_SIG; - pwbuf[i++] = (char) (ZIP_PASSWORD_END_SIG >> 8); - pwbuf[i++] = (char) (ZIP_PASSWORD_END_SIG >> 16); - pwbuf[i++] = (char) (ZIP_PASSWORD_END_SIG >> 24); - pwbuf[i] = '\0'; - } - i = Tcl_Write(out, (char *) zf0.data, zf0.baseoffsp); - if (i != zf0.baseoffsp) { + if ( + (out == NULL) + || (Tcl_SetChannelOption(interp, out, "-translation", "binary") != TCL_OK) + || (Tcl_SetChannelOption(interp, out, "-encoding", "binary") != TCL_OK) + ) { Tcl_DecrRefCount(list); - Tcl_SetObjResult(interp, Tcl_NewStringObj("write error", -1)); Tcl_Close(interp, out); - ZipFSCloseArchive(interp, &zf0); return TCL_ERROR; - } - ZipFSCloseArchive(interp, &zf0); - len = strlen(pwbuf); - if (len > 0) { - i = Tcl_Write(out, pwbuf, len); - if (i != len) { - Tcl_DecrRefCount(list); - Tcl_SetObjResult(interp, Tcl_NewStringObj("write error", -1)); - Tcl_Close(interp, out); - return TCL_ERROR; - } - } - memset(pwbuf, 0, sizeof (pwbuf)); - Tcl_Flush(out); + } + if (isImg) { + ZipFile zf0; + const char *imgName; + + if (isList) { + imgName = (objc > 4) ? Tcl_GetString(objv[4]) : + Tcl_GetNameOfExecutable(); + } else { + imgName = (objc > 5) ? Tcl_GetString(objv[5]) : + Tcl_GetNameOfExecutable(); + } + if (ZipFSOpenArchive(interp, imgName, 0, &zf0) != TCL_OK) { + Tcl_DecrRefCount(list); + Tcl_Close(interp, out); + return TCL_ERROR; + } + if ((pw != NULL) && pwlen) { + i = 0; + len = pwlen; + while (len > 0) { + int ch = pw[len - 1]; + + pwbuf[i] = (ch & 0x0f) | pwrot[(ch >> 4) & 0x0f]; + i++; + len--; + } + pwbuf[i] = i; + ++i; + pwbuf[i++] = (char) ZIP_PASSWORD_END_SIG; + pwbuf[i++] = (char) (ZIP_PASSWORD_END_SIG >> 8); + pwbuf[i++] = (char) (ZIP_PASSWORD_END_SIG >> 16); + pwbuf[i++] = (char) (ZIP_PASSWORD_END_SIG >> 24); + pwbuf[i] = '\0'; + } + i = Tcl_Write(out, (char *) zf0.data, zf0.baseoffsp); + if (i != zf0.baseoffsp) { + Tcl_DecrRefCount(list); + Tcl_SetObjResult(interp, Tcl_NewStringObj("write error", -1)); + Tcl_Close(interp, out); + ZipFSCloseArchive(interp, &zf0); + return TCL_ERROR; + } + ZipFSCloseArchive(interp, &zf0); + len = strlen(pwbuf); + if (len > 0) { + i = Tcl_Write(out, pwbuf, len); + if (i != len) { + Tcl_DecrRefCount(list); + Tcl_SetObjResult(interp, Tcl_NewStringObj("write error", -1)); + Tcl_Close(interp, out); + return TCL_ERROR; + } + } + memset(pwbuf, 0, sizeof (pwbuf)); + Tcl_Flush(out); } Tcl_InitHashTable(&fileHash, TCL_STRING_KEYS); pos[0] = Tcl_Tell(out); if (!isList && (objc > 3)) { - strip = Tcl_GetString(objv[3]); - slen = strlen(strip); + strip = Tcl_GetString(objv[3]); + slen = strlen(strip); } for (i = 0; i < lobjc; i += (isList ? 2 : 1)) { - const char *path, *name; + const char *path, *name; - path = Tcl_GetString(lobjv[i]); - if (isList) { - name = Tcl_GetString(lobjv[i + 1]); - } else { - name = path; - if (slen > 0) { - len = strlen(name); - if ((len <= slen) || (strncmp(strip, name, slen) != 0)) { - continue; - } - name += slen; - } - } - while (name[0] == '/') { - ++name; - } - if (name[0] == '\0') { - continue; - } - if (ZipAddFile(interp, path, name, out, pw, buf, sizeof (buf), - &fileHash) != TCL_OK) { - goto done; - } + path = Tcl_GetString(lobjv[i]); + if (isList) { + name = Tcl_GetString(lobjv[i + 1]); + } else { + name = path; + if (slen > 0) { + len = strlen(name); + if ((len <= slen) || (strncmp(strip, name, slen) != 0)) { + continue; + } + name += slen; + } + } + while (name[0] == '/') { + ++name; + } + if (name[0] == '\0') { + continue; + } + if (ZipAddFile(interp, path, name, out, pw, buf, sizeof (buf), &fileHash) != TCL_OK) { + goto done; + } } pos[1] = Tcl_Tell(out); count = 0; @@ -2048,11 +2007,11 @@ ZipFSMkZipOrImgObjCmd(ClientData clientData, Tcl_Interp *interp, } else { name = path; if (slen > 0) { - len = strlen(name); - if ((len <= slen) || (strncmp(strip, name, slen) != 0)) { - continue; - } - name += slen; + len = strlen(name); + if ((len <= slen) || (strncmp(strip, name, slen) != 0)) { + continue; + } + name += slen; } } while (name[0] == '/') { @@ -2084,9 +2043,10 @@ ZipFSMkZipOrImgObjCmd(ClientData clientData, Tcl_Interp *interp, zip_write_short(buf + ZIP_CENTRAL_IATTR_OFFS, 0); zip_write_int(buf + ZIP_CENTRAL_EATTR_OFFS, 0); zip_write_int(buf + ZIP_CENTRAL_LOCALHDR_OFFS, z->offset - pos[0]); - if ((Tcl_Write(out, buf, ZIP_CENTRAL_HEADER_LEN) != - ZIP_CENTRAL_HEADER_LEN) || - (Tcl_Write(out, z->name, len) != len)) { + if ( + (Tcl_Write(out, buf, ZIP_CENTRAL_HEADER_LEN) != ZIP_CENTRAL_HEADER_LEN) + || (Tcl_Write(out, z->name, len) != len) + ) { Tcl_SetObjResult(interp, Tcl_NewStringObj("write error", -1)); goto done; } @@ -2103,24 +2063,24 @@ ZipFSMkZipOrImgObjCmd(ClientData clientData, Tcl_Interp *interp, zip_write_int(buf + ZIP_CENTRAL_DIRSTART_OFFS, pos[1] - pos[0]); zip_write_short(buf + ZIP_CENTRAL_COMMENTLEN_OFFS, 0); if (Tcl_Write(out, buf, ZIP_CENTRAL_END_LEN) != ZIP_CENTRAL_END_LEN) { - Tcl_SetObjResult(interp, Tcl_NewStringObj("write error", -1)); - goto done; + Tcl_SetObjResult(interp, Tcl_NewStringObj("write error", -1)); + goto done; } Tcl_Flush(out); ret = TCL_OK; done: if (ret == TCL_OK) { - ret = Tcl_Close(interp, out); + ret = Tcl_Close(interp, out); } else { - Tcl_Close(interp, out); + Tcl_Close(interp, out); } Tcl_DecrRefCount(list); hPtr = Tcl_FirstHashEntry(&fileHash, &search); while (hPtr != NULL) { - z = (ZipEntry *) Tcl_GetHashValue(hPtr); - Tcl_Free((char *) z); - Tcl_DeleteHashEntry(hPtr); - hPtr = Tcl_FirstHashEntry(&fileHash, &search); + z = (ZipEntry *) Tcl_GetHashValue(hPtr); + Tcl_Free((char *) z); + Tcl_DeleteHashEntry(hPtr); + hPtr = Tcl_FirstHashEntry(&fileHash, &search); } Tcl_DeleteHashTable(&fileHash); return ret; @@ -2144,16 +2104,16 @@ done: */ static int -ZipFSMkZipObjCmd(ClientData clientData, Tcl_Interp *interp, - int objc, Tcl_Obj *const objv[]) -{ +ZipFSMkZipObjCmd( + ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[] +) { return ZipFSMkZipOrImgObjCmd(clientData, interp, 0, 0, objc, objv); } static int -ZipFSLMkZipObjCmd(ClientData clientData, Tcl_Interp *interp, - int objc, Tcl_Obj *const objv[]) -{ +ZipFSLMkZipObjCmd( + ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[] +) { return ZipFSMkZipOrImgObjCmd(clientData, interp, 0, 1, objc, objv); } @@ -2207,34 +2167,34 @@ ZipFSLMkImgObjCmd(ClientData clientData, Tcl_Interp *interp, */ static int -ZipFSCanonicalObjCmd(ClientData clientData, Tcl_Interp *interp, - int objc, Tcl_Obj *const objv[]) -{ +ZipFSCanonicalObjCmd( + ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[] +) { char *mntpoint=NULL; char *filename=NULL; char *result; Tcl_DString dPath; if (objc != 2 && objc != 3 && objc!=4) { - Tcl_WrongNumArgs(interp, 1, objv, "?mntpnt? filename ?ZIPFS?"); - return TCL_ERROR; + Tcl_WrongNumArgs(interp, 1, objv, "?mntpnt? filename ?ZIPFS?"); + return TCL_ERROR; } Tcl_DStringInit(&dPath); if(objc==2) { - filename = Tcl_GetString(objv[1]); - result=CanonicalPath("",filename,&dPath,1); + filename = Tcl_GetString(objv[1]); + result=CanonicalPath("",filename,&dPath,1); } else if (objc==3) { - mntpoint = Tcl_GetString(objv[1]); - filename = Tcl_GetString(objv[2]); - result=CanonicalPath(mntpoint,filename,&dPath,1); + mntpoint = Tcl_GetString(objv[1]); + filename = Tcl_GetString(objv[2]); + result=CanonicalPath(mntpoint,filename,&dPath,1); } else { - int zipfs=0; - if(Tcl_GetBooleanFromObj(interp,objv[3],&zipfs)) { - return TCL_ERROR; - } - mntpoint = Tcl_GetString(objv[1]); - filename = Tcl_GetString(objv[2]); - result=CanonicalPath(mntpoint,filename,&dPath,zipfs); + int zipfs=0; + if(Tcl_GetBooleanFromObj(interp,objv[3],&zipfs)) { + return TCL_ERROR; + } + mntpoint = Tcl_GetString(objv[1]); + filename = Tcl_GetString(objv[2]); + result=CanonicalPath(mntpoint,filename,&dPath,zipfs); } Tcl_SetObjResult(interp,Tcl_NewStringObj(result,-1)); return TCL_OK; @@ -2259,9 +2219,9 @@ ZipFSCanonicalObjCmd(ClientData clientData, Tcl_Interp *interp, */ static int -ZipFSExistsObjCmd(ClientData clientData, Tcl_Interp *interp, - int objc, Tcl_Obj *const objv[]) -{ +ZipFSExistsObjCmd( + ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[] +) { char *filename; int exists; Tcl_DString ds; @@ -2306,27 +2266,27 @@ ZipFSExistsObjCmd(ClientData clientData, Tcl_Interp *interp, */ static int -ZipFSInfoObjCmd(ClientData clientData, Tcl_Interp *interp, - int objc, Tcl_Obj *const objv[]) -{ +ZipFSInfoObjCmd( + ClientData clientData, Tcl_Interp *interp,int objc, Tcl_Obj *const objv[] +) { char *filename; ZipEntry *z; if (objc != 2) { - Tcl_WrongNumArgs(interp, 1, objv, "filename"); - return TCL_ERROR; + Tcl_WrongNumArgs(interp, 1, objv, "filename"); + return TCL_ERROR; } filename = Tcl_GetStringFromObj(objv[1], 0); ReadLock(); z = ZipFSLookup(filename); if (z != NULL) { - Tcl_Obj *result = Tcl_GetObjResult(interp); + Tcl_Obj *result = Tcl_GetObjResult(interp); - Tcl_ListObjAppendElement(interp, result, - Tcl_NewStringObj(z->zipfile->name, -1)); - Tcl_ListObjAppendElement(interp, result, Tcl_NewIntObj(z->nbyte)); - Tcl_ListObjAppendElement(interp, result, Tcl_NewIntObj(z->nbytecompr)); - Tcl_ListObjAppendElement(interp, result, Tcl_NewIntObj(z->offset)); + Tcl_ListObjAppendElement(interp, result, + Tcl_NewStringObj(z->zipfile->name, -1)); + Tcl_ListObjAppendElement(interp, result, Tcl_NewIntObj(z->nbyte)); + Tcl_ListObjAppendElement(interp, result, Tcl_NewIntObj(z->nbytecompr)); + Tcl_ListObjAppendElement(interp, result, Tcl_NewIntObj(z->offset)); } Unlock(); return TCL_OK; @@ -2351,9 +2311,9 @@ ZipFSInfoObjCmd(ClientData clientData, Tcl_Interp *interp, */ static int -ZipFSListObjCmd(ClientData clientData, Tcl_Interp *interp, - int objc, Tcl_Obj *const objv[]) -{ +ZipFSListObjCmd( + ClientData clientData, Tcl_Interp *interp,int objc, Tcl_Obj *const objv[] +) { char *pattern = NULL; Tcl_RegExp regexp = NULL; Tcl_HashEntry *hPtr; @@ -2361,57 +2321,61 @@ ZipFSListObjCmd(ClientData clientData, Tcl_Interp *interp, Tcl_Obj *result = Tcl_GetObjResult(interp); if (objc > 3) { - Tcl_WrongNumArgs(interp, 1, objv, "?(-glob|-regexp)? ?pattern?"); - return TCL_ERROR; + Tcl_WrongNumArgs(interp, 1, objv, "?(-glob|-regexp)? ?pattern?"); + return TCL_ERROR; } if (objc == 3) { - int n; - char *what = Tcl_GetStringFromObj(objv[1], &n); - - if ((n >= 2) && (strncmp(what, "-glob", n) == 0)) { - pattern = Tcl_GetString(objv[2]); - } else if ((n >= 2) && (strncmp(what, "-regexp", n) == 0)) { - regexp = Tcl_RegExpCompile(interp, Tcl_GetString(objv[2])); - if (regexp == NULL) { - return TCL_ERROR; - } - } else { - Tcl_AppendResult(interp, "unknown option \"", what, - "\"", (char *) NULL); - return TCL_ERROR; - } + int n; + char *what = Tcl_GetStringFromObj(objv[1], &n); + + if ((n >= 2) && (strncmp(what, "-glob", n) == 0)) { + pattern = Tcl_GetString(objv[2]); + } else if ((n >= 2) && (strncmp(what, "-regexp", n) == 0)) { + regexp = Tcl_RegExpCompile(interp, Tcl_GetString(objv[2])); + if (regexp == NULL) { + return TCL_ERROR; + } + } else { + Tcl_AppendResult(interp, "unknown option \"", what,"\"", (char *) NULL); + return TCL_ERROR; + } } else if (objc == 2) { - pattern = Tcl_GetStringFromObj(objv[1], 0); + pattern = Tcl_GetStringFromObj(objv[1], 0); } ReadLock(); if (pattern != NULL) { - for (hPtr = Tcl_FirstHashEntry(&ZipFS.fileHash, &search); - hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) { - ZipEntry *z = (ZipEntry *) Tcl_GetHashValue(hPtr); - - if (Tcl_StringMatch(z->name, pattern)) { - Tcl_ListObjAppendElement(interp, result, - Tcl_NewStringObj(z->name, -1)); - } - } + for ( + hPtr = Tcl_FirstHashEntry(&ZipFS.fileHash, &search); + hPtr != NULL; + hPtr = Tcl_NextHashEntry(&search) + ) { + ZipEntry *z = (ZipEntry *) Tcl_GetHashValue(hPtr); + + if (Tcl_StringMatch(z->name, pattern)) { + Tcl_ListObjAppendElement(interp, result,Tcl_NewStringObj(z->name, -1)); + } + } } else if (regexp != NULL) { - for (hPtr = Tcl_FirstHashEntry(&ZipFS.fileHash, &search); - hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) { - ZipEntry *z = (ZipEntry *) Tcl_GetHashValue(hPtr); - - if (Tcl_RegExpExec(interp, regexp, z->name, z->name)) { - Tcl_ListObjAppendElement(interp, result, - Tcl_NewStringObj(z->name, -1)); - } - } + for ( + hPtr = Tcl_FirstHashEntry(&ZipFS.fileHash, &search); + hPtr != NULL; + hPtr = Tcl_NextHashEntry(&search) + ) { + ZipEntry *z = (ZipEntry *) Tcl_GetHashValue(hPtr); + if (Tcl_RegExpExec(interp, regexp, z->name, z->name)) { + Tcl_ListObjAppendElement(interp, result,Tcl_NewStringObj(z->name, -1)); + } + } } else { - for (hPtr = Tcl_FirstHashEntry(&ZipFS.fileHash, &search); - hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) { - ZipEntry *z = (ZipEntry *) Tcl_GetHashValue(hPtr); - - Tcl_ListObjAppendElement(interp, result, - Tcl_NewStringObj(z->name, -1)); - } + for ( + hPtr = Tcl_FirstHashEntry(&ZipFS.fileHash, &search); + hPtr != NULL; + hPtr = Tcl_NextHashEntry(&search) + ) { + ZipEntry *z = (ZipEntry *) Tcl_GetHashValue(hPtr); + + Tcl_ListObjAppendElement(interp, result, Tcl_NewStringObj(z->name, -1)); + } } Unlock(); return TCL_OK; @@ -2438,6 +2402,7 @@ ZipFSTclLibraryObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { Tcl_Obj *pResult; + pResult=TclZipfs_TclLibrary(); if(!pResult) { pResult=Tcl_NewObj(); @@ -2468,34 +2433,33 @@ ZipChannelClose(ClientData instanceData, Tcl_Interp *interp) ZipChannel *info = (ZipChannel *) instanceData; if (info->iscompr && (info->ubuf != NULL)) { - Tcl_Free((char *) info->ubuf); - info->ubuf = NULL; + Tcl_Free((char *) info->ubuf); + info->ubuf = NULL; } if (info->isenc) { - info->isenc = 0; - memset(info->keys, 0, sizeof (info->keys)); + info->isenc = 0; + memset(info->keys, 0, sizeof (info->keys)); } if (info->iswr) { - ZipEntry *z = info->zipentry; - unsigned char *newdata; - - newdata = (unsigned char *) - Tcl_AttemptRealloc((char *) info->ubuf, info->nread); - if (newdata != NULL) { - if (z->data != NULL) { - Tcl_Free((char *) z->data); - } - z->data = newdata; - z->nbyte = z->nbytecompr = info->nbyte; - z->cmeth = ZIP_COMPMETH_STORED; - z->timestamp = time(NULL); - z->isdir = 0; - z->isenc = 0; - z->offset = 0; - z->crc32 = 0; - } else { - Tcl_Free((char *) info->ubuf); - } + ZipEntry *z = info->zipentry; + unsigned char *newdata; + + newdata = (unsigned char *) Tcl_AttemptRealloc((char *) info->ubuf, info->nread); + if (newdata != NULL) { + if (z->data != NULL) { + Tcl_Free((char *) z->data); + } + z->data = newdata; + z->nbyte = z->nbytecompr = info->nbyte; + z->cmeth = ZIP_COMPMETH_STORED; + z->timestamp = time(NULL); + z->isdir = 0; + z->isenc = 0; + z->offset = 0; + z->crc32 = 0; + } else { + Tcl_Free((char *) info->ubuf); + } } WriteLock(); info->zipfile->nopen--; @@ -2527,26 +2491,26 @@ ZipChannelRead(ClientData instanceData, char *buf, int toRead, int *errloc) unsigned long nextpos; if (info->isdir) { - *errloc = EISDIR; - return -1; + *errloc = EISDIR; + return -1; } nextpos = info->nread + toRead; if (nextpos > info->nbyte) { - toRead = info->nbyte - info->nread; - nextpos = info->nbyte; + toRead = info->nbyte - info->nread; + nextpos = info->nbyte; } if (toRead == 0) { - return 0; + return 0; } if (info->isenc) { - int i, ch; + int i, ch; - for (i = 0; i < toRead; i++) { - ch = info->ubuf[i + info->nread]; - buf[i] = zdecode(info->keys, crc32tab, ch); - } + for (i = 0; i < toRead; i++) { + ch = info->ubuf[i + info->nread]; + buf[i] = zdecode(info->keys, crc32tab, ch); + } } else { - memcpy(buf, info->ubuf + info->nread, toRead); + memcpy(buf, info->ubuf + info->nread, toRead); } info->nread = nextpos; *errloc = 0; @@ -2577,21 +2541,21 @@ ZipChannelWrite(ClientData instanceData, const char *buf, unsigned long nextpos; if (!info->iswr) { - *errloc = EINVAL; - return -1; + *errloc = EINVAL; + return -1; } nextpos = info->nread + toWrite; if (nextpos > info->nmax) { - toWrite = info->nmax - info->nread; - nextpos = info->nmax; + toWrite = info->nmax - info->nread; + nextpos = info->nmax; } if (toWrite == 0) { - return 0; + return 0; } memcpy(info->ubuf + info->nread, buf, toWrite); info->nread = nextpos; if (info->nread > info->nbyte) { - info->nbyte = info->nread; + info->nbyte = info->nread; } *errloc = 0; return toWrite; @@ -2619,37 +2583,37 @@ ZipChannelSeek(ClientData instanceData, long offset, int mode, int *errloc) ZipChannel *info = (ZipChannel *) instanceData; if (info->isdir) { - *errloc = EINVAL; - return -1; + *errloc = EINVAL; + return -1; } switch (mode) { - case SEEK_CUR: - offset += info->nread; - break; - case SEEK_END: - offset += info->nbyte; - break; - case SEEK_SET: - break; - default: - *errloc = EINVAL; - return -1; + case SEEK_CUR: + offset += info->nread; + break; + case SEEK_END: + offset += info->nbyte; + break; + case SEEK_SET: + break; + default: + *errloc = EINVAL; + return -1; } if (offset < 0) { - *errloc = EINVAL; - return -1; - } - if (info->iswr) { - if ((unsigned long) offset > info->nmax) { *errloc = EINVAL; return -1; - } - if ((unsigned long) offset > info->nbyte) { - info->nbyte = offset; - } + } + if (info->iswr) { + if ((unsigned long) offset > info->nmax) { + *errloc = EINVAL; + return -1; + } + if ((unsigned long) offset > info->nbyte) { + info->nbyte = offset; + } } else if ((unsigned long) offset > info->nbyte) { - *errloc = EINVAL; - return -1; + *errloc = EINVAL; + return -1; } info->nread = (unsigned long) offset; return info->nread; @@ -2695,9 +2659,9 @@ ZipChannelWatchChannel(ClientData instanceData, int mask) */ static int -ZipChannelGetFile(ClientData instanceData, int direction, - ClientData *handlePtr) -{ +ZipChannelGetFile( + ClientData instanceData, int direction,ClientData *handlePtr +) { return TCL_ERROR; } @@ -2761,295 +2725,268 @@ ZipChannelOpen(Tcl_Interp *interp, char *filename, int mode, int permissions) int i, ch, trunc, wr, flags = 0; char cname[128]; - if ((mode & O_APPEND) || - ((ZipFS.wrmax <= 0) && (mode & (O_WRONLY | O_RDWR)))) { - if (interp != NULL) { - Tcl_SetObjResult(interp, Tcl_NewStringObj("unsupported open mode", -1)); - } - return NULL; + if ( + (mode & O_APPEND) + || ((ZipFS.wrmax <= 0) && (mode & (O_WRONLY | O_RDWR))) + ) { + if (interp != NULL) { + Tcl_SetObjResult(interp, Tcl_NewStringObj("unsupported open mode", -1)); + } + return NULL; } WriteLock(); z = ZipFSLookup(filename); if (z == NULL) { - if (interp != NULL) { - Tcl_SetObjResult(interp, Tcl_NewStringObj("file not found", -1)); - Tcl_AppendResult(interp, " \"", filename, "\"", NULL); - } - goto error; + if (interp != NULL) { + Tcl_SetObjResult(interp, Tcl_NewStringObj("file not found", -1)); + Tcl_AppendResult(interp, " \"", filename, "\"", NULL); + } + goto error; } trunc = (mode & O_TRUNC) != 0; wr = (mode & (O_WRONLY | O_RDWR)) != 0; - if ((z->cmeth != ZIP_COMPMETH_STORED) && - (z->cmeth != ZIP_COMPMETH_DEFLATED)) { - if (interp != NULL) { - Tcl_SetObjResult(interp, - Tcl_NewStringObj("unsupported compression method", -1)); - } - goto error; + if ((z->cmeth != ZIP_COMPMETH_STORED) && (z->cmeth != ZIP_COMPMETH_DEFLATED)) { + ZIPFS_ERROR(interp,"unsupported compression method"); + goto error; } if (wr && z->isdir) { - if (interp != NULL) { - Tcl_SetObjResult(interp, - Tcl_NewStringObj("unsupported file type", -1)); - } - goto error; + ZIPFS_ERROR(interp,"unsupported file type"); + goto error; } if (!trunc) { - flags |= TCL_READABLE; - if (z->isenc && (z->zipfile->pwbuf[0] == 0)) { - if (interp != NULL) { - Tcl_SetObjResult(interp, - Tcl_NewStringObj("decryption failed", -1)); - } - goto error; - } else if (wr && (z->data == NULL) && (z->nbyte > ZipFS.wrmax)) { - if (interp != NULL) { - Tcl_SetObjResult(interp, - Tcl_NewStringObj("file too large", -1)); - } - goto error; - } + flags |= TCL_READABLE; + if (z->isenc && (z->zipfile->pwbuf[0] == 0)) { + ZIPFS_ERROR(interp,"decryption failed"); + goto error; + } else if (wr && (z->data == NULL) && (z->nbyte > ZipFS.wrmax)) { + ZIPFS_ERROR(interp,"file too large"); + goto error; + } } else { - flags = TCL_WRITABLE; + flags = TCL_WRITABLE; } info = (ZipChannel *) Tcl_AttemptAlloc(sizeof (*info)); if (info == NULL) { - if (interp != NULL) { - Tcl_SetObjResult(interp, Tcl_NewStringObj("out of memory", -1)); - } - goto error; + ZIPFS_ERROR(interp,"out of memory"); + goto error; } info->zipfile = z->zipfile; info->zipentry = z; info->nread = 0; if (wr) { - flags |= TCL_WRITABLE; - info->iswr = 1; - info->isdir = 0; - info->nmax = ZipFS.wrmax; - info->iscompr = 0; - info->isenc = 0; - info->ubuf = (unsigned char *) Tcl_AttemptAlloc(info->nmax); - if (info->ubuf == NULL) { + flags |= TCL_WRITABLE; + info->iswr = 1; + info->isdir = 0; + info->nmax = ZipFS.wrmax; + info->iscompr = 0; + info->isenc = 0; + info->ubuf = (unsigned char *) Tcl_AttemptAlloc(info->nmax); + if (info->ubuf == NULL) { merror0: - if (info->ubuf != NULL) { - Tcl_Free((char *) info->ubuf); - } - Tcl_Free((char *) info); - if (interp != NULL) { - Tcl_SetObjResult(interp, - Tcl_NewStringObj("out of memory", -1)); - } - goto error; - } - memset(info->ubuf, 0, info->nmax); - if (trunc) { - info->nbyte = 0; - } else { - if (z->data != NULL) { - unsigned int j = z->nbyte; + if (info->ubuf != NULL) { + Tcl_Free((char *) info->ubuf); + } + Tcl_Free((char *) info); + ZIPFS_ERROR(interp,"out of memory"); + goto error; + } + memset(info->ubuf, 0, info->nmax); + if (trunc) { + info->nbyte = 0; + } else { + if (z->data != NULL) { + unsigned int j = z->nbyte; - if (j > info->nmax) { - j = info->nmax; - } - memcpy(info->ubuf, z->data, j); - info->nbyte = j; - } else { - unsigned char *zbuf = z->zipfile->data + z->offset; - - if (z->isenc) { - int len = z->zipfile->pwbuf[0]; - char pwbuf[260]; - - for (i = 0; i < len; i++) { - ch = z->zipfile->pwbuf[len - i]; - pwbuf[i] = (ch & 0x0f) | pwrot[(ch >> 4) & 0x0f]; - } - pwbuf[i] = '\0'; - init_keys(pwbuf, info->keys, crc32tab); - memset(pwbuf, 0, sizeof (pwbuf)); - for (i = 0; i < 12; i++) { - ch = info->ubuf[i]; - zdecode(info->keys, crc32tab, ch); - } - zbuf += i; - } - if (z->cmeth == ZIP_COMPMETH_DEFLATED) { - z_stream stream; - int err; - unsigned char *cbuf = NULL; - - memset(&stream, 0, sizeof (stream)); - stream.zalloc = Z_NULL; - stream.zfree = Z_NULL; - stream.opaque = Z_NULL; - stream.avail_in = z->nbytecompr; - if (z->isenc) { - unsigned int j; - - stream.avail_in -= 12; - cbuf = (unsigned char *) - Tcl_AttemptAlloc(stream.avail_in); - if (cbuf == NULL) { - goto merror0; - } - for (j = 0; j < stream.avail_in; j++) { - ch = info->ubuf[j]; - cbuf[j] = zdecode(info->keys, crc32tab, ch); - } - stream.next_in = cbuf; - } else { - stream.next_in = zbuf; - } - stream.next_out = info->ubuf; - stream.avail_out = info->nmax; - if (inflateInit2(&stream, -15) != Z_OK) { - goto cerror0; - } - err = inflate(&stream, Z_SYNC_FLUSH); - inflateEnd(&stream); - if ((err == Z_STREAM_END) || - ((err == Z_OK) && (stream.avail_in == 0))) { - if (cbuf != NULL) { - memset(info->keys, 0, sizeof (info->keys)); - Tcl_Free((char *) cbuf); - } - goto wrapchan; - } + if (j > info->nmax) { + j = info->nmax; + } + memcpy(info->ubuf, z->data, j); + info->nbyte = j; + } else { + unsigned char *zbuf = z->zipfile->data + z->offset; + + if (z->isenc) { + int len = z->zipfile->pwbuf[0]; + char pwbuf[260]; + + for (i = 0; i < len; i++) { + ch = z->zipfile->pwbuf[len - i]; + pwbuf[i] = (ch & 0x0f) | pwrot[(ch >> 4) & 0x0f]; + } + pwbuf[i] = '\0'; + init_keys(pwbuf, info->keys, crc32tab); + memset(pwbuf, 0, sizeof (pwbuf)); + for (i = 0; i < 12; i++) { + ch = info->ubuf[i]; + zdecode(info->keys, crc32tab, ch); + } + zbuf += i; + } + if (z->cmeth == ZIP_COMPMETH_DEFLATED) { + z_stream stream; + int err; + unsigned char *cbuf = NULL; + + memset(&stream, 0, sizeof (stream)); + stream.zalloc = Z_NULL; + stream.zfree = Z_NULL; + stream.opaque = Z_NULL; + stream.avail_in = z->nbytecompr; + if (z->isenc) { + unsigned int j; + + stream.avail_in -= 12; + cbuf = (unsigned char *) + Tcl_AttemptAlloc(stream.avail_in); + if (cbuf == NULL) { + goto merror0; + } + for (j = 0; j < stream.avail_in; j++) { + ch = info->ubuf[j]; + cbuf[j] = zdecode(info->keys, crc32tab, ch); + } + stream.next_in = cbuf; + } else { + stream.next_in = zbuf; + } + stream.next_out = info->ubuf; + stream.avail_out = info->nmax; + if (inflateInit2(&stream, -15) != Z_OK) goto cerror0; + err = inflate(&stream, Z_SYNC_FLUSH); + inflateEnd(&stream); + if ((err == Z_STREAM_END) || ((err == Z_OK) && (stream.avail_in == 0))) { + if (cbuf != NULL) { + memset(info->keys, 0, sizeof (info->keys)); + Tcl_Free((char *) cbuf); + } + goto wrapchan; + } cerror0: - if (cbuf != NULL) { - memset(info->keys, 0, sizeof (info->keys)); - Tcl_Free((char *) cbuf); - } - if (info->ubuf != NULL) { - Tcl_Free((char *) info->ubuf); - } - Tcl_Free((char *) info); - if (interp != NULL) { - Tcl_SetObjResult(interp, - Tcl_NewStringObj("decompression error", -1)); - } - goto error; - } else if (z->isenc) { - for (i = 0; i < z->nbyte - 12; i++) { - ch = zbuf[i]; - info->ubuf[i] = zdecode(info->keys, crc32tab, ch); - } - } else { - memcpy(info->ubuf, zbuf, z->nbyte); - } - memset(info->keys, 0, sizeof (info->keys)); - goto wrapchan; - } - } + if (cbuf != NULL) { + memset(info->keys, 0, sizeof (info->keys)); + Tcl_Free((char *) cbuf); + } + if (info->ubuf != NULL) { + Tcl_Free((char *) info->ubuf); + } + Tcl_Free((char *) info); + ZIPFS_ERROR(interp,"decompression error"); + goto error; + } else if (z->isenc) { + for (i = 0; i < z->nbyte - 12; i++) { + ch = zbuf[i]; + info->ubuf[i] = zdecode(info->keys, crc32tab, ch); + } + } else { + memcpy(info->ubuf, zbuf, z->nbyte); + } + memset(info->keys, 0, sizeof (info->keys)); + goto wrapchan; + } + } } else if (z->data != NULL) { - flags |= TCL_READABLE; - info->iswr = 0; - info->iscompr = 0; - info->isdir = 0; - info->isenc = 0; - info->nbyte = z->nbyte; - info->nmax = 0; - info->ubuf = z->data; + flags |= TCL_READABLE; + info->iswr = 0; + info->iscompr = 0; + info->isdir = 0; + info->isenc = 0; + info->nbyte = z->nbyte; + info->nmax = 0; + info->ubuf = z->data; } else { - flags |= TCL_READABLE; - info->iswr = 0; - info->iscompr = z->cmeth == ZIP_COMPMETH_DEFLATED; - info->ubuf = z->zipfile->data + z->offset; - info->isdir = z->isdir; - info->isenc = z->isenc; - info->nbyte = z->nbyte; - info->nmax = 0; - if (info->isenc) { - int len = z->zipfile->pwbuf[0]; - char pwbuf[260]; - - for (i = 0; i < len; i++) { - ch = z->zipfile->pwbuf[len - i]; - pwbuf[i] = (ch & 0x0f) | pwrot[(ch >> 4) & 0x0f]; - } - pwbuf[i] = '\0'; - init_keys(pwbuf, info->keys, crc32tab); - memset(pwbuf, 0, sizeof (pwbuf)); - for (i = 0; i < 12; i++) { - ch = info->ubuf[i]; - zdecode(info->keys, crc32tab, ch); - } - info->ubuf += i; - } - if (info->iscompr) { - z_stream stream; - int err; - unsigned char *ubuf = NULL; - unsigned int j; - - memset(&stream, 0, sizeof (stream)); - stream.zalloc = Z_NULL; - stream.zfree = Z_NULL; - stream.opaque = Z_NULL; - stream.avail_in = z->nbytecompr; - if (info->isenc) { - stream.avail_in -= 12; - ubuf = (unsigned char *) Tcl_AttemptAlloc(stream.avail_in); - if (ubuf == NULL) { - info->ubuf = NULL; - goto merror; - } - for (j = 0; j < stream.avail_in; j++) { - ch = info->ubuf[j]; - ubuf[j] = zdecode(info->keys, crc32tab, ch); - } - stream.next_in = ubuf; - } else { - stream.next_in = info->ubuf; - } - stream.next_out = info->ubuf = - (unsigned char *) Tcl_AttemptAlloc(info->nbyte); - if (info->ubuf == NULL) { + flags |= TCL_READABLE; + info->iswr = 0; + info->iscompr = z->cmeth == ZIP_COMPMETH_DEFLATED; + info->ubuf = z->zipfile->data + z->offset; + info->isdir = z->isdir; + info->isenc = z->isenc; + info->nbyte = z->nbyte; + info->nmax = 0; + if (info->isenc) { + int len = z->zipfile->pwbuf[0]; + char pwbuf[260]; + + for (i = 0; i < len; i++) { + ch = z->zipfile->pwbuf[len - i]; + pwbuf[i] = (ch & 0x0f) | pwrot[(ch >> 4) & 0x0f]; + } + pwbuf[i] = '\0'; + init_keys(pwbuf, info->keys, crc32tab); + memset(pwbuf, 0, sizeof (pwbuf)); + for (i = 0; i < 12; i++) { + ch = info->ubuf[i]; + zdecode(info->keys, crc32tab, ch); + } + info->ubuf += i; + } + if (info->iscompr) { + z_stream stream; + int err; + unsigned char *ubuf = NULL; + unsigned int j; + + memset(&stream, 0, sizeof (stream)); + stream.zalloc = Z_NULL; + stream.zfree = Z_NULL; + stream.opaque = Z_NULL; + stream.avail_in = z->nbytecompr; + if (info->isenc) { + stream.avail_in -= 12; + ubuf = (unsigned char *) Tcl_AttemptAlloc(stream.avail_in); + if (ubuf == NULL) { + info->ubuf = NULL; + goto merror; + } + for (j = 0; j < stream.avail_in; j++) { + ch = info->ubuf[j]; + ubuf[j] = zdecode(info->keys, crc32tab, ch); + } + stream.next_in = ubuf; + } else { + stream.next_in = info->ubuf; + } + stream.next_out = info->ubuf = (unsigned char *) Tcl_AttemptAlloc(info->nbyte); + if (info->ubuf == NULL) { merror: - if (ubuf != NULL) { - info->isenc = 0; - memset(info->keys, 0, sizeof (info->keys)); - Tcl_Free((char *) ubuf); - } - Tcl_Free((char *) info); - if (interp != NULL) { - Tcl_SetObjResult(interp, - Tcl_NewStringObj("out of memory", -1)); - } - goto error; - } - stream.avail_out = info->nbyte; - if (inflateInit2(&stream, -15) != Z_OK) { - goto cerror; - } - err = inflate(&stream, Z_SYNC_FLUSH); - inflateEnd(&stream); - if ((err == Z_STREAM_END) || - ((err == Z_OK) && (stream.avail_in == 0))) { - if (ubuf != NULL) { - info->isenc = 0; - memset(info->keys, 0, sizeof (info->keys)); - Tcl_Free((char *) ubuf); - } - goto wrapchan; - } + if (ubuf != NULL) { + info->isenc = 0; + memset(info->keys, 0, sizeof (info->keys)); + Tcl_Free((char *) ubuf); + } + Tcl_Free((char *) info); + if (interp != NULL) { + Tcl_SetObjResult(interp, + Tcl_NewStringObj("out of memory", -1)); + } + goto error; + } + stream.avail_out = info->nbyte; + if (inflateInit2(&stream, -15) != Z_OK) { + goto cerror; + } + err = inflate(&stream, Z_SYNC_FLUSH); + inflateEnd(&stream); + if ((err == Z_STREAM_END) || ((err == Z_OK) && (stream.avail_in == 0))) { + if (ubuf != NULL) { + info->isenc = 0; + memset(info->keys, 0, sizeof (info->keys)); + Tcl_Free((char *) ubuf); + } + goto wrapchan; + } cerror: - if (ubuf != NULL) { - info->isenc = 0; - memset(info->keys, 0, sizeof (info->keys)); - Tcl_Free((char *) ubuf); - } - if (info->ubuf != NULL) { - Tcl_Free((char *) info->ubuf); - } - Tcl_Free((char *) info); - if (interp != NULL) { - Tcl_SetObjResult(interp, - Tcl_NewStringObj("decompression error", -1)); - } - goto error; - } + if (ubuf != NULL) { + info->isenc = 0; + memset(info->keys, 0, sizeof (info->keys)); + Tcl_Free((char *) ubuf); + } + if (info->ubuf != NULL) { + Tcl_Free((char *) info->ubuf); + } + Tcl_Free((char *) info); + ZIPFS_ERROR(interp,"decompression error"); + goto error; + } } wrapchan: sprintf(cname, "zipfs_%lx_%d", (unsigned long) z->offset, ZipFS.idCount++); @@ -3087,14 +3024,13 @@ ZipEntryStat(char *path, Tcl_StatBuf *buf) ReadLock(); z = ZipFSLookup(path); - if (z == NULL) { - goto done; - } + if (z == NULL) goto done; + memset(buf, 0, sizeof (Tcl_StatBuf)); if (z->isdir) { - buf->st_mode = S_IFDIR | 0555; + buf->st_mode = S_IFDIR | 0555; } else { - buf->st_mode = S_IFREG | 0555; + buf->st_mode = S_IFREG | 0555; } buf->st_size = z->nbyte; buf->st_mtime = z->timestamp; @@ -3128,9 +3064,7 @@ ZipEntryAccess(char *path, int mode) { ZipEntry *z; - if (mode & 3) { - return -1; - } + if (mode & 3) return -1; ReadLock(); z = ZipFSLookup(path); Unlock(); @@ -3154,11 +3088,8 @@ Zip_FSOpenFileChannelProc(Tcl_Interp *interp, Tcl_Obj *pathPtr, int mode, int permissions) { int len; - if (!(pathPtr = Tcl_FSGetNormalizedPath(NULL, pathPtr))) return NULL; - - return ZipChannelOpen(interp, Tcl_GetStringFromObj(pathPtr, &len), - mode, permissions); + return ZipChannelOpen(interp, Tcl_GetStringFromObj(pathPtr, &len), mode, permissions); } /* @@ -3182,9 +3113,7 @@ static int Zip_FSStatProc(Tcl_Obj *pathPtr, Tcl_StatBuf *buf) { int len; - if (!(pathPtr = Tcl_FSGetNormalizedPath(NULL, pathPtr))) return -1; - return ZipEntryStat(Tcl_GetStringFromObj(pathPtr, &len), buf); } @@ -3209,9 +3138,7 @@ static int Zip_FSAccessProc(Tcl_Obj *pathPtr, int mode) { int len; - if (!(pathPtr = Tcl_FSGetNormalizedPath(NULL, pathPtr))) return -1; - return ZipEntryAccess(Tcl_GetStringFromObj(pathPtr, &len), mode); } @@ -3273,7 +3200,7 @@ Zip_FSMatchInDirectoryProc(Tcl_Interp* interp, Tcl_Obj *result, if (!(normPathPtr = Tcl_FSGetNormalizedPath(NULL, pathPtr))) return -1; if (types != NULL) { - dirOnly = (types->type & TCL_GLOB_TYPE_DIR) == TCL_GLOB_TYPE_DIR; + dirOnly = (types->type & TCL_GLOB_TYPE_DIR) == TCL_GLOB_TYPE_DIR; } /* the prefix that gets prepended to results */ @@ -3286,14 +3213,14 @@ Zip_FSMatchInDirectoryProc(Tcl_Interp* interp, Tcl_Obj *result, Tcl_DStringAppend(&dsPref, prefix, prefixLen); if (strcmp(prefix, path) == 0) { - prefix = NULL; + prefix = NULL; } else { - strip = len + 1; + strip = len + 1; } if (prefix != NULL) { - Tcl_DStringAppend(&dsPref, "/", 1); - prefixLen++; - prefix = Tcl_DStringValue(&dsPref); + Tcl_DStringAppend(&dsPref, "/", 1); + prefixLen++; + prefix = Tcl_DStringValue(&dsPref); } ReadLock(); if ((types != NULL) && (types->type == TCL_GLOB_TYPE_MOUNT)) { @@ -3311,42 +3238,47 @@ Zip_FSMatchInDirectoryProc(Tcl_Interp* interp, Tcl_Obj *result, ZipFile *zf = (ZipFile *) Tcl_GetHashValue(hPtr); if (zf->mntptlen == 0) { - ZipEntry *z = zf->topents; - while (z != NULL) { - int lenz = strlen(z->name); - if ((lenz > len + 1) && - (strncmp(z->name, path, len) == 0) && - (z->name[len] == '/') && - (CountSlashes(z->name) == l) && - Tcl_StringCaseMatch(z->name + len + 1, pattern, 0)) { - if (prefix != NULL) { - Tcl_DStringAppend(&dsPref, z->name, lenz); - Tcl_ListObjAppendElement(NULL, result, - Tcl_NewStringObj(Tcl_DStringValue(&dsPref), - Tcl_DStringLength(&dsPref))); - Tcl_DStringSetLength(&dsPref, prefixLen); - } else { - Tcl_ListObjAppendElement(NULL, result, - Tcl_NewStringObj(z->name, lenz)); - } - } - z = z->tnext; - } - } else if ((zf->mntptlen > len + 1) && - (strncmp(zf->mntpt, path, len) == 0) && - (zf->mntpt[len] == '/') && - (CountSlashes(zf->mntpt) == l) && - Tcl_StringCaseMatch(zf->mntpt + len + 1, pattern, 0)) { - if (prefix != NULL) { - Tcl_DStringAppend(&dsPref, zf->mntpt, zf->mntptlen); - Tcl_ListObjAppendElement(NULL, result, - Tcl_NewStringObj(Tcl_DStringValue(&dsPref), - Tcl_DStringLength(&dsPref))); - Tcl_DStringSetLength(&dsPref, prefixLen); - } else { - Tcl_ListObjAppendElement(NULL, result, - Tcl_NewStringObj(zf->mntpt, zf->mntptlen)); - } + ZipEntry *z = zf->topents; + while (z != NULL) { + int lenz = strlen(z->name); + if ( + (lenz > len + 1) + && (strncmp(z->name, path, len) == 0) + && (z->name[len] == '/') + && (CountSlashes(z->name) == l) + && Tcl_StringCaseMatch(z->name + len + 1, pattern, 0) + ) { + if (prefix != NULL) { + Tcl_DStringAppend(&dsPref, z->name, lenz); + Tcl_ListObjAppendElement( + NULL, result, + Tcl_NewStringObj(Tcl_DStringValue(&dsPref), + Tcl_DStringLength(&dsPref)) + ); + Tcl_DStringSetLength(&dsPref, prefixLen); + } else { + Tcl_ListObjAppendElement(NULL, result, Tcl_NewStringObj(z->name, lenz)); + } + } + z = z->tnext; + } + } else if ( + (zf->mntptlen > len + 1) + && (strncmp(zf->mntpt, path, len) == 0) + && (zf->mntpt[len] == '/') + && (CountSlashes(zf->mntpt) == l) + && Tcl_StringCaseMatch(zf->mntpt + len + 1, pattern, 0) + ) { + if (prefix != NULL) { + Tcl_DStringAppend(&dsPref, zf->mntpt, zf->mntptlen); + Tcl_ListObjAppendElement(NULL, result, + Tcl_NewStringObj(Tcl_DStringValue(&dsPref), + Tcl_DStringLength(&dsPref))); + Tcl_DStringSetLength(&dsPref, prefixLen); + } else { + Tcl_ListObjAppendElement(NULL, result, + Tcl_NewStringObj(zf->mntpt, zf->mntptlen)); + } } hPtr = Tcl_NextHashEntry(&search); } @@ -3378,33 +3310,38 @@ Zip_FSMatchInDirectoryProc(Tcl_Interp* interp, Tcl_Obj *result, pat = Tcl_Alloc(len + l + 2); memcpy(pat, path, len); while ((len > 1) && (pat[len - 1] == '/')) { - --len; + --len; } if ((len > 1) || (pat[0] != '/')) { - pat[len] = '/'; - ++len; + pat[len] = '/'; + ++len; } memcpy(pat + len, pattern, l + 1); scnt = CountSlashes(pat); - for (hPtr = Tcl_FirstHashEntry(&ZipFS.fileHash, &search); - hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) { - ZipEntry *z = (ZipEntry *) Tcl_GetHashValue(hPtr); - if ((dirOnly >= 0) && - ((dirOnly && !z->isdir) || (!dirOnly && z->isdir))) { - continue; - } - if ((z->depth == scnt) && Tcl_StringCaseMatch(z->name, pat, 0)) { - if (prefix != NULL) { - Tcl_DStringAppend(&dsPref, z->name + strip, -1); - Tcl_ListObjAppendElement(NULL, result, - Tcl_NewStringObj(Tcl_DStringValue(&dsPref), - Tcl_DStringLength(&dsPref))); - Tcl_DStringSetLength(&dsPref, prefixLen); - } else { - Tcl_ListObjAppendElement(NULL, result, - Tcl_NewStringObj(z->name + strip, -1)); - } - } + for ( + hPtr = Tcl_FirstHashEntry(&ZipFS.fileHash, &search); + hPtr != NULL; + hPtr = Tcl_NextHashEntry(&search) + ) { + ZipEntry *z = (ZipEntry *) Tcl_GetHashValue(hPtr); + if ( + (dirOnly >= 0) && ((dirOnly && !z->isdir) || (!dirOnly && z->isdir)) + ) { + continue; + } + if ((z->depth == scnt) && Tcl_StringCaseMatch(z->name, pat, 0)) { + if (prefix != NULL) { + Tcl_DStringAppend(&dsPref, z->name + strip, -1); + Tcl_ListObjAppendElement( + NULL, result, + Tcl_NewStringObj(Tcl_DStringValue(&dsPref), + Tcl_DStringLength(&dsPref)) + ); + Tcl_DStringSetLength(&dsPref, prefixLen); + } else { + Tcl_ListObjAppendElement(NULL, result, Tcl_NewStringObj(z->name + strip, -1)); + } + } } Tcl_Free(pat); end: @@ -3443,7 +3380,7 @@ Zip_FSPathInFilesystemProc(Tcl_Obj *pathPtr, ClientData *clientDataPtr) path = Tcl_GetStringFromObj(pathPtr, &len); if(strncmp(path,ZIPFS_VOLUME,ZIPFS_VOLUME_LEN)!=0) { - return -1; + return -1; } len = strlen(path); @@ -3451,30 +3388,31 @@ Zip_FSPathInFilesystemProc(Tcl_Obj *pathPtr, ClientData *clientDataPtr) ReadLock(); hPtr = Tcl_FindHashEntry(&ZipFS.fileHash, path); if (hPtr != NULL) { - ret = TCL_OK; - goto endloop; + ret = TCL_OK; + goto endloop; } hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); while (hPtr != NULL) { - zf = (ZipFile *) Tcl_GetHashValue(hPtr); - if (zf->mntptlen == 0) { - ZipEntry *z = zf->topents; - while (z != NULL) { - int lenz = strlen(z->name); - - if ((len >= lenz) && - (strncmp(path, z->name, lenz) == 0)) { + zf = (ZipFile *) Tcl_GetHashValue(hPtr); + if (zf->mntptlen == 0) { + ZipEntry *z = zf->topents; + while (z != NULL) { + int lenz = strlen(z->name); + if ( + (len >= lenz) && (strncmp(path, z->name, lenz) == 0) + ) { + ret = TCL_OK; + goto endloop; + } + z = z->tnext; + } + } else if ( + (len >= zf->mntptlen) && (strncmp(path, zf->mntpt, zf->mntptlen) == 0) + ) { ret = TCL_OK; goto endloop; - } - z = z->tnext; } - } else if ((len >= zf->mntptlen) && - (strncmp(path, zf->mntpt, zf->mntptlen) == 0)) { - ret = TCL_OK; - goto endloop; - } - hPtr = Tcl_NextHashEntry(&search); + hPtr = Tcl_NextHashEntry(&search); } endloop: Unlock(); @@ -3530,7 +3468,6 @@ Zip_FSFileAttrStringsProc(Tcl_Obj *pathPtr, Tcl_Obj** objPtrRef) "-permissions", NULL, }; - return attrs; } @@ -3563,40 +3500,35 @@ Zip_FSFileAttrsGetProc(Tcl_Interp *interp, int index, Tcl_Obj *pathPtr, ZipEntry *z; if (!(pathPtr = Tcl_FSGetNormalizedPath(NULL, pathPtr))) return -1; - path = Tcl_GetStringFromObj(pathPtr, &len); ReadLock(); z = ZipFSLookup(path); if (z == NULL) { - if (interp != NULL) { - Tcl_SetObjResult(interp, Tcl_NewStringObj("file not found", -1)); - } - ret = TCL_ERROR; - goto done; + ZIPFS_ERROR(interp,"file not found"); + ret = TCL_ERROR; + goto done; } switch (index) { - case 0: - *objPtrRef = Tcl_NewIntObj(z->nbyte); - goto done; - case 1: - *objPtrRef= Tcl_NewIntObj(z->nbytecompr); - goto done; - case 2: - *objPtrRef= Tcl_NewLongObj(z->offset); - goto done; - case 3: - *objPtrRef= Tcl_NewStringObj(z->zipfile->mntpt, -1); - goto done; - case 4: - *objPtrRef= Tcl_NewStringObj(z->zipfile->name, -1); - goto done; - case 5: - *objPtrRef= Tcl_NewStringObj("0555", -1); - goto done; - } - if (interp != NULL) { - Tcl_SetObjResult(interp, Tcl_NewStringObj("unknown attribute", -1)); - } + case 0: + *objPtrRef = Tcl_NewIntObj(z->nbyte); + goto done; + case 1: + *objPtrRef= Tcl_NewIntObj(z->nbytecompr); + goto done; + case 2: + *objPtrRef= Tcl_NewLongObj(z->offset); + goto done; + case 3: + *objPtrRef= Tcl_NewStringObj(z->zipfile->mntpt, -1); + goto done; + case 4: + *objPtrRef= Tcl_NewStringObj(z->zipfile->name, -1); + goto done; + case 5: + *objPtrRef= Tcl_NewStringObj("0555", -1); + goto done; + } + ZIPFS_ERROR(interp,"unknown attribute"); ret = TCL_ERROR; done: Unlock(); @@ -3621,11 +3553,10 @@ done: */ static int -Zip_FSFileAttrsSetProc(Tcl_Interp *interp, int index, Tcl_Obj *pathPtr, - Tcl_Obj *objPtr) +Zip_FSFileAttrsSetProc(Tcl_Interp *interp, int index, Tcl_Obj *pathPtr,Tcl_Obj *objPtr) { if (interp != NULL) { - Tcl_SetObjResult(interp, Tcl_NewStringObj("unsupported operation", -1)); + Tcl_SetObjResult(interp, Tcl_NewStringObj("unsupported operation", -1)); } return TCL_ERROR; } @@ -3685,7 +3616,7 @@ Zip_FSLoadFile(Tcl_Interp *interp, Tcl_Obj *path, Tcl_LoadHandle *loadHandle, loadFileProc = (Tcl_FSLoadFileProc2 *) tclNativeFilesystem.loadFileProc; if (loadFileProc != NULL) { - return loadFileProc(interp, path, loadHandle, unloadProcPtr, flags); + return loadFileProc(interp, path, loadHandle, unloadProcPtr, flags); } Tcl_SetErrno(ENOENT); return -1; @@ -3694,67 +3625,66 @@ Zip_FSLoadFile(Tcl_Interp *interp, Tcl_Obj *path, Tcl_LoadHandle *loadHandle, int ret = -1; if (Tcl_FSAccess(path, R_OK) == 0) { - /* - * EXDEV should trigger loading by copying to temp store. - */ - Tcl_SetErrno(EXDEV); - return ret; + /* + * EXDEV should trigger loading by copying to temp store. + */ + Tcl_SetErrno(EXDEV); + return ret; } else { - Tcl_Obj *objs[2] = { NULL, NULL }; - - objs[1] = TclPathPart(interp, path, TCL_PATH_DIRNAME); - if ((objs[1] != NULL) && (Zip_FSAccessProc(objs[1], R_OK) == 0)) { - const char *execName = Tcl_GetNameOfExecutable(); - - /* - * Shared object is not in ZIP but its path prefix is, - * thus try to load from directory where the executable - * came from. - */ - TclDecrRefCount(objs[1]); - objs[1] = TclPathPart(interp, path, TCL_PATH_TAIL); - /* - * Get directory name of executable manually to deal - * with cases where [file dirname [info nameofexecutable]] - * is equal to [info nameofexecutable] due to VFS effects. - */ - if (execName != NULL) { - const char *p = strrchr(execName, '/'); - - if (p > execName + 1) { - --p; - objs[0] = Tcl_NewStringObj(execName, p - execName); - } - } - if (objs[0] == NULL) { - objs[0] = TclPathPart(interp, TclGetObjNameOfExecutable(), - TCL_PATH_DIRNAME); - } - if (objs[0] != NULL) { - altPath = TclJoinPath(2, objs); - if (altPath != NULL) { - Tcl_IncrRefCount(altPath); - if (Tcl_FSAccess(altPath, R_OK) == 0) { - path = altPath; - } - } - } - } - if (objs[0] != NULL) { - Tcl_DecrRefCount(objs[0]); - } - if (objs[1] != NULL) { - Tcl_DecrRefCount(objs[1]); - } + Tcl_Obj *objs[2] = { NULL, NULL }; + + objs[1] = TclPathPart(interp, path, TCL_PATH_DIRNAME); + if ((objs[1] != NULL) && (Zip_FSAccessProc(objs[1], R_OK) == 0)) { + const char *execName = Tcl_GetNameOfExecutable(); + + /* + * Shared object is not in ZIP but its path prefix is, + * thus try to load from directory where the executable + * came from. + */ + TclDecrRefCount(objs[1]); + objs[1] = TclPathPart(interp, path, TCL_PATH_TAIL); + /* + * Get directory name of executable manually to deal + * with cases where [file dirname [info nameofexecutable]] + * is equal to [info nameofexecutable] due to VFS effects. + */ + if (execName != NULL) { + const char *p = strrchr(execName, '/'); + + if (p > execName + 1) { + --p; + objs[0] = Tcl_NewStringObj(execName, p - execName); + } + } + if (objs[0] == NULL) { + objs[0] = TclPathPart(interp, TclGetObjNameOfExecutable(),TCL_PATH_DIRNAME); + } + if (objs[0] != NULL) { + altPath = TclJoinPath(2, objs); + if (altPath != NULL) { + Tcl_IncrRefCount(altPath); + if (Tcl_FSAccess(altPath, R_OK) == 0) { + path = altPath; + } + } + } + } + if (objs[0] != NULL) { + Tcl_DecrRefCount(objs[0]); + } + if (objs[1] != NULL) { + Tcl_DecrRefCount(objs[1]); + } } loadFileProc = (Tcl_FSLoadFileProc2 *) tclNativeFilesystem.loadFileProc; if (loadFileProc != NULL) { - ret = loadFileProc(interp, path, loadHandle, unloadProcPtr, flags); + ret = loadFileProc(interp, path, loadHandle, unloadProcPtr, flags); } else { - Tcl_SetErrno(ENOENT); + Tcl_SetErrno(ENOENT); } if (altPath != NULL) { - Tcl_DecrRefCount(altPath); + Tcl_DecrRefCount(altPath); } return ret; #endif @@ -3864,8 +3794,8 @@ TclZipfs_Init(Tcl_Interp *interp) {NULL, NULL, NULL, NULL, NULL, 0} }; static const char findproc[] = - "namespace eval zipfs {}\n" - "proc ::zipfs::find dir {\n" + "namespace eval ::tcl::zipfs::zipfs {}\n" + "proc ::tcl::zipfs::find dir {\n" " set result {}\n" " if {[catch {glob -directory $dir -tails -nocomplain * .*} list]} {\n" " return $result\n" @@ -3876,23 +3806,20 @@ TclZipfs_Init(Tcl_Interp *interp) " }\n" " set file [file join $dir $file]\n" " lappend result $file\n" - " foreach file [::zipfs::find $file] {\n" + " foreach file [::tcl::zipfs::find $file] {\n" " lappend result $file\n" " }\n" " }\n" " return [lsort $result]\n" "}\n"; Tcl_EvalEx(interp, findproc, -1, TCL_EVAL_GLOBAL); - Tcl_LinkVar(interp, "::zipfs::wrmax", (char *) &ZipFS.wrmax, - TCL_LINK_INT); + Tcl_LinkVar(interp, "::tcl::zipfs::wrmax", (char *) &ZipFS.wrmax,TCL_LINK_INT); TclMakeEnsemble(interp, "zipfs", initMap); Tcl_PkgProvide(interp, "zipfs", "2.0"); } return TCL_OK; #else - if (interp != NULL) { - Tcl_SetObjResult(interp, Tcl_NewStringObj("no zlib available", -1)); - } + ZIPFS_ERROR(interp,"no zlib available"); return TCL_ERROR; #endif } @@ -3963,8 +3890,6 @@ int TclZipfs_AppHook(int *argc, char ***argv) TclZipfs_Init(NULL); /* ** Look for init.tcl in one of the locations mounted later in this function - ** and failing that, look for a file name CFG_RUNTIME_ZIPFILE adjacent to the - ** executable */ if(!TclZipfs_Mount(NULL, archive, ZIPFS_APP_MOUNT, NULL)) { int found; @@ -4061,7 +3986,7 @@ Tcl_Obj *TclZipfs_TclLibrary(void) { if(TclZipfs_AppHook_FindTclInit(CFG_RUNTIME_LIBDIR "/" CFG_RUNTIME_ZIPFILE)==TCL_OK) { return Tcl_NewStringObj(zipfs_literal_tcl_library,-1); } - if(TclZipfs_AppHook_FindTclInit(CFG_RUNTIME_SRCDIR "/" CFG_RUNTIME_ZIPFILE)==TCL_OK) { + if(TclZipfs_AppHook_FindTclInit(CFG_RUNTIME_SCRDIR "/" CFG_RUNTIME_ZIPFILE)==TCL_OK) { return Tcl_NewStringObj(zipfs_literal_tcl_library,-1); } } -- cgit v0.12 From b3ff8cc20cdc84f12b4b9a571092a340c591f216 Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Fri, 24 Nov 2017 11:21:55 +0000 Subject: Pulling changes from Androwish --- generic/tclZipfs.c | 1098 +++++++++++++++++++++++++++++----------------------- 1 file changed, 610 insertions(+), 488 deletions(-) diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c index b9d09f1..668eee0 100644 --- a/generic/tclZipfs.c +++ b/generic/tclZipfs.c @@ -1,8 +1,8 @@ /* * tclZipfs.c -- * - * Implementation of the ZIP filesystem used in TIP 430 - * Adapted from the implentation for AndroWish. + * Implementation of the ZIP filesystem used in TIP 430 + * Adapted from the implentation for AndroWish. * * Coptright (c) 2016-2017 Sean Woods * Copyright (c) 2013-2015 Christian Werner @@ -26,6 +26,10 @@ #include #include +#ifndef MAP_FILE +#define MAP_FILE 0 +#endif + #ifdef HAVE_ZLIB #include "zlib.h" #include "crypt.h" @@ -106,15 +110,15 @@ * Macros to read and write 16 and 32 bit integers from/to ZIP archives. */ -#define zip_read_int(p) \ +#define zip_read_int(p) \ ((p)[0] | ((p)[1] << 8) | ((p)[2] << 16) | ((p)[3] << 24)) -#define zip_read_short(p) \ +#define zip_read_short(p) \ ((p)[0] | ((p)[1] << 8)) -#define zip_write_int(p, v) \ - (p)[0] = (v) & 0xff; (p)[1] = ((v) >> 8) & 0xff; \ +#define zip_write_int(p, v) \ + (p)[0] = (v) & 0xff; (p)[1] = ((v) >> 8) & 0xff; \ (p)[2] = ((v) >> 16) & 0xff; (p)[3] = ((v) >> 24) & 0xff; -#define zip_write_short(p, v) \ +#define zip_write_short(p, v) \ (p)[0] = (v) & 0xff; (p)[1] = ((v) >> 8) & 0xff; /* @@ -163,7 +167,7 @@ typedef struct ZipFile { struct ZipEntry *entries; /* List of files in archive */ struct ZipEntry *topents; /* List of top-level dirs in archive */ #if HAS_DRIVES - int mntdrv; /* Drive letter of mount point */ + int mntdrv; /* Drive letter of mount point */ #endif int mntptlen; /* Length of mount point */ char mntpt[1]; /* Mount point */ @@ -180,8 +184,8 @@ typedef struct ZipEntry { int nbyte; /* Uncompressed size of the virtual file */ int nbytecompr; /* Compressed size of the virtual file */ int cmeth; /* Compress method */ - int isdir; /* Set to 1 if directory */ - int depth; /* Number of slashes in path. */ + int isdir; /* Set to 1 if directory, or -1 if root */ + int depth; /* Number of slashes in path. */ int crc32; /* CRC-32 */ int timestamp; /* Modification time */ int isenc; /* True if data is encrypted */ @@ -202,7 +206,7 @@ typedef struct ZipChannel { unsigned long nread; /* Pos of next byte to be read from the channel */ unsigned char *ubuf; /* Pointer to the uncompressed data */ int iscompr; /* True if data is compressed */ - int isdir; /* Set to 1 if directory */ + int isdir; /* Set to 1 if directory, or -1 if root */ int isenc; /* True if data is encrypted */ int iswr; /* True if open for writing */ unsigned long keys[3]; /* Key for decryption */ @@ -222,13 +226,13 @@ typedef struct ZipChannel { */ static struct { - int initialized; /* True when initialized */ - int lock; /* RW lock, see below */ - int waiters; /* RW lock, see below */ - int wrmax; /* Maximum write size of a file */ - int idCount; /* Counter for channel names */ - Tcl_HashTable fileHash; /* File name to ZipEntry mapping */ - Tcl_HashTable zipHash; /* Mount to ZipFile mapping */ + int initialized; /* True when initialized */ + int lock; /* RW lock, see below */ + int waiters; /* RW lock, see below */ + int wrmax; /* Maximum write size of a file */ + int idCount; /* Counter for channel names */ + Tcl_HashTable fileHash; /* File name to ZipEntry mapping */ + Tcl_HashTable zipHash; /* Mount to ZipFile mapping */ } ZipFS = { 0, 0, 0, 0, 0, }; @@ -309,12 +313,12 @@ const char *zipfs_literal_tcl_library=NULL; * * ReadLock, WriteLock, Unlock -- * - * POSIX like rwlock functions to support multiple readers - * and single writer on internal structs. + * POSIX like rwlock functions to support multiple readers + * and single writer on internal structs. * - * Limitations: - * - a read lock cannot be promoted to a write lock - * - a write lock may not be nested + * Limitations: + * - a read lock cannot be promoted to a write lock + * - a write lock may not be nested * *------------------------------------------------------------------------- */ @@ -330,9 +334,9 @@ ReadLock(void) { Tcl_MutexLock(&ZipFSMutex); while (ZipFS.lock < 0) { - ZipFS.waiters++; - Tcl_ConditionWait(&ZipFSCond, &ZipFSMutex, NULL); - ZipFS.waiters--; + ZipFS.waiters++; + Tcl_ConditionWait(&ZipFSCond, &ZipFSMutex, NULL); + ZipFS.waiters--; } ZipFS.lock++; Tcl_MutexUnlock(&ZipFSMutex); @@ -343,9 +347,9 @@ WriteLock(void) { Tcl_MutexLock(&ZipFSMutex); while (ZipFS.lock != 0) { - ZipFS.waiters++; - Tcl_ConditionWait(&ZipFSCond, &ZipFSMutex, NULL); - ZipFS.waiters--; + ZipFS.waiters++; + Tcl_ConditionWait(&ZipFSCond, &ZipFSMutex, NULL); + ZipFS.waiters--; } ZipFS.lock = -1; Tcl_MutexUnlock(&ZipFSMutex); @@ -356,21 +360,21 @@ Unlock(void) { Tcl_MutexLock(&ZipFSMutex); if (ZipFS.lock > 0) { - --ZipFS.lock; + --ZipFS.lock; } else if (ZipFS.lock < 0) { - ZipFS.lock = 0; + ZipFS.lock = 0; } if ((ZipFS.lock == 0) && (ZipFS.waiters > 0)) { - Tcl_ConditionNotify(&ZipFSCond); + Tcl_ConditionNotify(&ZipFSCond); } Tcl_MutexUnlock(&ZipFSMutex); } #else -#define ReadLock() do {} while (0) -#define WriteLock() do {} while (0) -#define Unlock() do {} while (0) +#define ReadLock() do {} while (0) +#define WriteLock() do {} while (0) +#define Unlock() do {} while (0) #endif @@ -379,8 +383,8 @@ Unlock(void) * * DosTimeDate, ToDosTime, ToDosDate -- * - * Functions to perform conversions between DOS time stamps - * and POSIX time_t. + * Functions to perform conversions between DOS time stamps + * and POSIX time_t. * *------------------------------------------------------------------------- */ @@ -467,13 +471,13 @@ ToDosDate(time_t when) * * CountSlashes -- * - * This function counts the number of slashes in a pathname string. + * This function counts the number of slashes in a pathname string. * * Results: - * Number of slashes found in string. + * Number of slashes found in string. * * Side effects: - * None. + * None. * *------------------------------------------------------------------------- */ @@ -498,15 +502,15 @@ CountSlashes(const char *string) * * CanonicalPath -- * - * This function computes the canonical path from a directory - * and file name components into the specified Tcl_DString. + * This function computes the canonical path from a directory + * and file name components into the specified Tcl_DString. * * Results: - * Returns the pointer to the canonical path contained in the - * specified Tcl_DString. + * Returns the pointer to the canonical path contained in the + * specified Tcl_DString. * * Side effects: - * Modifies the specified Tcl_DString. + * Modifies the specified Tcl_DString. * *------------------------------------------------------------------------- */ @@ -611,9 +615,9 @@ CanonicalPath(const char *root, const char *tail, Tcl_DString *dsPtr,int ZIPFSPA } #endif if(ZIPFSPATH) { - n=ZIPFS_VOLUME_LEN; + n=ZIPFS_VOLUME_LEN; } else { - n=0; + n=0; } for (i = j = n; (c = path[i]) != '\0'; i++) { if (c == '/') { @@ -648,7 +652,7 @@ CanonicalPath(const char *root, const char *tail, Tcl_DString *dsPtr,int ZIPFSPA path[j++] = c; } if (j == 0) { - path[j++] = '/'; + path[j++] = '/'; } path[j] = 0; Tcl_DStringSetLength(dsPtr, j); @@ -663,16 +667,16 @@ CanonicalPath(const char *root, const char *tail, Tcl_DString *dsPtr,int ZIPFSPA * * ZipFSLookup -- * - * This function returns the ZIP entry struct corresponding to - * the ZIP archive member of the given file name. + * This function returns the ZIP entry struct corresponding to + * the ZIP archive member of the given file name. * * Results: - * Returns the pointer to ZIP entry struct or NULL if the - * the given file name could not be found in the global list - * of ZIP archive members. + * Returns the pointer to ZIP entry struct or NULL if the + * the given file name could not be found in the global list + * of ZIP archive members. * * Side effects: - * None. + * None. * *------------------------------------------------------------------------- */ @@ -697,14 +701,14 @@ ZipFSLookup(char *filename) * * ZipFSLookupMount -- * - * This function returns an indication if the given file name - * corresponds to a mounted ZIP archive file. + * This function returns an indication if the given file name + * corresponds to a mounted ZIP archive file. * * Results: - * Returns true, if the given file name is a mounted ZIP archive file. + * Returns true, if the given file name is a mounted ZIP archive file. * * Side effects: - * None. + * None. * *------------------------------------------------------------------------- */ @@ -734,14 +738,14 @@ ZipFSLookupMount(char *filename) * * ZipFSCloseArchive -- * - * This function closes a mounted ZIP archive file. + * This function closes a mounted ZIP archive file. * * Results: - * None. + * None. * * Side effects: - * A memory mapped ZIP archive is unmapped, allocated memory is - * released. + * A memory mapped ZIP archive is unmapped, allocated memory is + * released. * *------------------------------------------------------------------------- */ @@ -755,20 +759,22 @@ ZipFSCloseArchive(Tcl_Interp *interp, ZipFile *zf) zf->data = NULL; } if (zf->mh != INVALID_HANDLE_VALUE) { - CloseHandle(zf->mh); + CloseHandle(zf->mh); } #else if ((zf->data != MAP_FAILED) && (zf->tofree == NULL)) { - munmap(zf->data, zf->length); - zf->data = MAP_FAILED; + munmap(zf->data, zf->length); + zf->data = MAP_FAILED; } #endif if (zf->tofree != NULL) { - Tcl_Free((char *) zf->tofree); - zf->tofree = NULL; + Tcl_Free((char *) zf->tofree); + zf->tofree = NULL; + } + if(zf->chan != NULL) { + Tcl_Close(interp, zf->chan); + zf->chan = NULL; } - Tcl_Close(interp, zf->chan); - zf->chan = NULL; } /* @@ -776,27 +782,27 @@ ZipFSCloseArchive(Tcl_Interp *interp, ZipFile *zf) * * ZipFSOpenArchive -- * - * This function opens a ZIP archive file for reading. An attempt - * is made to memory map that file. Otherwise it is read into - * an allocated memory buffer. The ZIP archive header is verified - * and must be valid for the function to succeed. When "needZip" - * is zero an embedded ZIP archive in an executable file is accepted. + * This function opens a ZIP archive file for reading. An attempt + * is made to memory map that file. Otherwise it is read into + * an allocated memory buffer. The ZIP archive header is verified + * and must be valid for the function to succeed. When "needZip" + * is zero an embedded ZIP archive in an executable file is accepted. * * Results: - * TCL_OK on success, TCL_ERROR otherwise with an error message - * placed into the given "interp" if it is not NULL. + * TCL_OK on success, TCL_ERROR otherwise with an error message + * placed into the given "interp" if it is not NULL. * * Side effects: - * ZIP archive is memory mapped or read into allocated memory, - * the given ZipFile struct is filled with information about - * the ZIP archive file. + * ZIP archive is memory mapped or read into allocated memory, + * the given ZipFile struct is filled with information about + * the ZIP archive file. * *------------------------------------------------------------------------- */ static int ZipFSOpenArchive(Tcl_Interp *interp, const char *zipname, int needZip, - ZipFile *zf) + ZipFile *zf) { int i; ClientData handle; @@ -815,7 +821,7 @@ ZipFSOpenArchive(Tcl_Interp *interp, const char *zipname, int needZip, zf->pwbuf[0] = 0; zf->chan = Tcl_OpenFileChannel(interp, zipname, "r", 0); if (zf->chan == NULL) { - return TCL_ERROR; + return TCL_ERROR; } if (Tcl_GetChannelHandle(zf->chan, TCL_READABLE, &handle) != TCL_OK) { if (Tcl_SetChannelOption(interp, zf->chan, "-translation", "binary") != TCL_OK) { @@ -905,20 +911,20 @@ ZipFSOpenArchive(Tcl_Interp *interp, const char *zipname, int needZip, return TCL_OK; } ZIPFS_ERROR(interp,"empty archive"); - goto error; + goto error; } q = zf->data + zip_read_int(p + ZIP_CENTRAL_DIRSTART_OFFS); p -= zip_read_int(p + ZIP_CENTRAL_DIRSIZE_OFFS); if ( (p < zf->data) || (p > (zf->data + zf->length)) || - (q < zf->data) || (q > (zf->data + zf->length)) - ) { + (q < zf->data) || (q > (zf->data + zf->length)) + ) { if (!needZip) { zf->baseoffs = zf->baseoffsp = zf->length; return TCL_OK; } - ZIPFS_ERROR(interp,"archive directory not found"); - goto error; + ZIPFS_ERROR(interp,"archive directory not found"); + goto error; } zf->baseoffs = zf->baseoffsp = p - q; zf->centoffs = p - zf->data; @@ -961,14 +967,14 @@ error: * TclZipfs_Mount -- * * This procedure is invoked to mount a given ZIP archive file on - * a given mountpoint with optional ZIP password. + * a given mountpoint with optional ZIP password. * * Results: * A standard Tcl result. * * Side effects: * A ZIP archive file is read, analyzed and mounted, resources are - * allocated. + * allocated. * *------------------------------------------------------------------------- */ @@ -977,7 +983,7 @@ int TclZipfs_Mount( Tcl_Interp *interp, const char *zipname, const char *mntpt, - const char *passwd + const char *passwd ) { int i, pwlen, isNew; ZipFile *zf, zf0; @@ -1030,17 +1036,17 @@ TclZipfs_Mount( Unlock(); pwlen = 0; if (passwd != NULL) { - pwlen = strlen(passwd); - if ((pwlen > 255) || (strchr(passwd, 0xff) != NULL)) { - if (interp) { - Tcl_SetObjResult(interp, - Tcl_NewStringObj("illegal password", -1)); - } - return TCL_ERROR; - } + pwlen = strlen(passwd); + if ((pwlen > 255) || (strchr(passwd, 0xff) != NULL)) { + if (interp) { + Tcl_SetObjResult(interp, + Tcl_NewStringObj("illegal password", -1)); + } + return TCL_ERROR; + } } if (ZipFSOpenArchive(interp, zipname, 1, &zf0) != TCL_OK) { - return TCL_ERROR; + return TCL_ERROR; } /* * Mount point can come from Tcl_GetNameOfExecutable() @@ -1097,7 +1103,7 @@ TclZipfs_Mount( z->tnext = NULL; z->depth = CountSlashes(mntpt); z->zipfile = zf; - z->isdir = 1; + z->isdir = (zf->baseoffs == 0) ? 1 : -1; /* root marker */ z->isenc = 0; z->offset = zf->baseoffs; z->crc32 = 0; @@ -1316,7 +1322,7 @@ TclZipfs_Unmount(Tcl_Interp *interp, const char *zipname) hPtr = Tcl_FindHashEntry(&ZipFS.zipHash, zipname); - /* don't report error */ + /* don't report error */ if (hPtr == NULL) goto done; zf = (ZipFile *) Tcl_GetHashValue(hPtr); @@ -1343,7 +1349,7 @@ TclZipfs_Unmount(Tcl_Interp *interp, const char *zipname) done: Unlock(); if (unmounted) { - Tcl_FSMountsChanged(NULL); + Tcl_FSMountsChanged(NULL); } return ret; } @@ -1374,8 +1380,8 @@ ZipFSMountObjCmd( return TCL_ERROR; } return TclZipfs_Mount(interp, (objc > 1) ? Tcl_GetString(objv[1]) : NULL, - (objc > 2) ? Tcl_GetString(objv[2]) : NULL, - (objc > 3) ? Tcl_GetString(objv[3]) : NULL); + (objc > 2) ? Tcl_GetString(objv[2]) : NULL, + (objc > 3) ? Tcl_GetString(objv[3]) : NULL); } /* @@ -1435,7 +1441,7 @@ ZipFSUnmountObjCmd( * ZipFSMkKeyObjCmd -- * * This procedure is invoked to process the "zipfs::mkkey" command. - * It produces a rotated password to be embedded into an image file. + * It produces a rotated password to be embedded into an image file. * * Results: * A standard Tcl result. @@ -1454,13 +1460,13 @@ ZipFSMkKeyObjCmd( char *pw, pwbuf[264]; if (objc != 2) { - Tcl_WrongNumArgs(interp, 1, objv, "password"); - return TCL_ERROR; + Tcl_WrongNumArgs(interp, 1, objv, "password"); + return TCL_ERROR; } pw = Tcl_GetString(objv[1]); len = strlen(pw); if (len == 0) { - return TCL_OK; + return TCL_OK; } if ((len > 255) || (strchr(pw, 0xff) != NULL)) { Tcl_SetObjResult(interp, Tcl_NewStringObj("illegal password", -1)); @@ -1490,16 +1496,16 @@ ZipFSMkKeyObjCmd( * ZipAddFile -- * * This procedure is used by ZipFSMkZipOrImgCmd() to add a single - * file to the output ZIP archive file being written. A ZipEntry - * struct about the input file is added to the given fileHash table - * for later creation of the central ZIP directory. + * file to the output ZIP archive file being written. A ZipEntry + * struct about the input file is added to the given fileHash table + * for later creation of the central ZIP directory. * * Results: * A standard Tcl result. * * Side effects: - * Input file is read and (compressed and) written to the output - * ZIP archive file. + * Input file is read and (compressed and) written to the output + * ZIP archive file. * *------------------------------------------------------------------------- */ @@ -1507,8 +1513,8 @@ ZipFSMkKeyObjCmd( static int ZipAddFile( Tcl_Interp *interp, const char *path, const char *name, - Tcl_Channel out, const char *passwd, - char *buf, int bufsize, Tcl_HashTable *fileHash + Tcl_Channel out, const char *passwd, + char *buf, int bufsize, Tcl_HashTable *fileHash ) { Tcl_Channel in; Tcl_HashEntry *hPtr; @@ -1522,10 +1528,10 @@ ZipAddFile( zpath = name; while (zpath != NULL && zpath[0] == '/') { - zpath++; + zpath++; } if ((zpath == NULL) || (zpath[0] == '\0')) { - return TCL_OK; + return TCL_OK; } zpathlen = strlen(zpath); if (zpathlen + ZIP_CENTRAL_HEADER_LEN > bufsize) { @@ -1545,8 +1551,8 @@ ZipAddFile( return TCL_OK; } #endif - Tcl_Close(interp, in); - return TCL_ERROR; + Tcl_Close(interp, in); + return TCL_ERROR; } else { Tcl_Obj *pathObj = Tcl_NewStringObj(path, -1); Tcl_StatBuf statBuf; @@ -1589,9 +1595,9 @@ ZipAddFile( len = zpathlen + ZIP_LOCAL_HEADER_LEN; if (Tcl_Write(out, buf, len) != len) { wrerr: - Tcl_AppendResult(interp, "write error", (char *) NULL); - Tcl_Close(interp, in); - return TCL_ERROR; + Tcl_AppendResult(interp, "write error", (char *) NULL); + Tcl_Close(interp, in); + return TCL_ERROR; } if ((len + pos[0]) & 3) { char abuf[8]; @@ -1658,44 +1664,44 @@ wrerr: return TCL_ERROR; } do { - len = Tcl_Read(in, buf, bufsize); - if (len == -1) { - Tcl_AppendResult(interp, "read error on \"", path, "\"", - (char *) NULL); - deflateEnd(&stream); - Tcl_Close(interp, in); - return TCL_ERROR; - } - stream.avail_in = len; - stream.next_in = (unsigned char *) buf; - flush = Tcl_Eof(in) ? Z_FINISH : Z_NO_FLUSH; - do { - stream.avail_out = sizeof (obuf); - stream.next_out = (unsigned char *) obuf; - len = deflate(&stream, flush); - if (len == Z_STREAM_ERROR) { + len = Tcl_Read(in, buf, bufsize); + if (len == -1) { + Tcl_AppendResult(interp, "read error on \"", path, "\"", + (char *) NULL); + deflateEnd(&stream); + Tcl_Close(interp, in); + return TCL_ERROR; + } + stream.avail_in = len; + stream.next_in = (unsigned char *) buf; + flush = Tcl_Eof(in) ? Z_FINISH : Z_NO_FLUSH; + do { + stream.avail_out = sizeof (obuf); + stream.next_out = (unsigned char *) obuf; + len = deflate(&stream, flush); + if (len == Z_STREAM_ERROR) { Tcl_AppendResult(interp, "deflate error on \"", path, "\"", (char *) NULL); deflateEnd(&stream); Tcl_Close(interp, in); return TCL_ERROR; - } - olen = sizeof (obuf) - stream.avail_out; - if (passwd != NULL) { + } + olen = sizeof (obuf) - stream.avail_out; + if (passwd != NULL) { int i, tmp; for (i = 0; i < olen; i++) { obuf[i] = (char) zencode(keys, crc32tab, obuf[i], tmp); } - } - if (olen && (Tcl_Write(out, obuf, olen) != olen)) { + } + if (olen && (Tcl_Write(out, obuf, olen) != olen)) { Tcl_AppendResult(interp, "write error", (char *) NULL); deflateEnd(&stream); Tcl_Close(interp, in); return TCL_ERROR; - } - nbytecompr += olen; - } while (stream.avail_out == 0); + } + nbytecompr += olen; + } while (stream.avail_out == 0); } while (flush != Z_FINISH); deflateEnd(&stream); Tcl_Flush(out); @@ -1814,23 +1820,23 @@ seekErr: * ZipFSMkZipOrImgObjCmd -- * * This procedure is creates a new ZIP archive file or image file - * given output filename, input directory of files to be archived, - * optional password, and optional image to be prepended to the - * output ZIP archive file. + * given output filename, input directory of files to be archived, + * optional password, and optional image to be prepended to the + * output ZIP archive file. * * Results: * A standard Tcl result. * * Side effects: - * A new ZIP archive file or image file is written. + * A new ZIP archive file or image file is written. * *------------------------------------------------------------------------- */ static int -ZipFSMkZipOrImgObjCmd( - ClientData clientData, Tcl_Interp *interp,int isImg, int isList, int objc, Tcl_Obj *const objv[] -) { +ZipFSMkZipOrImgObjCmd(ClientData clientData, Tcl_Interp *interp, + int isImg, int isList, int objc, Tcl_Obj *const objv[]) +{ Tcl_Channel out; int len = 0, pwlen = 0, slen = 0, i, count, ret = TCL_ERROR, lobjc, pos[3]; Tcl_Obj **lobjv, *list = NULL; @@ -1843,15 +1849,15 @@ ZipFSMkZipOrImgObjCmd( if (isList) { if ((objc < 3) || (objc > (isImg ? 5 : 4))) { Tcl_WrongNumArgs(interp, 1, objv, isImg ? - "outfile inlist ?password infile?" : - "outfile inlist ?password?"); + "outfile inlist ?password infile?" : + "outfile inlist ?password?"); return TCL_ERROR; } } else { if ((objc < 3) || (objc > (isImg ? 6 : 5))) { Tcl_WrongNumArgs(interp, 1, objv, isImg ? - "outfile indir ?strip? ?password? ?infile?" : - "outfile indir ?strip? ?password?"); + "outfile indir ?strip? ?password? ?infile?" : + "outfile indir ?strip? ?password?"); return TCL_ERROR; } } @@ -1861,7 +1867,7 @@ ZipFSMkZipOrImgObjCmd( pwlen = strlen(pw); if ((pwlen > 255) || (strchr(pw, 0xff) != NULL)) { Tcl_SetObjResult(interp, - Tcl_NewStringObj("illegal password", -1)); + Tcl_NewStringObj("illegal password", -1)); return TCL_ERROR; } } @@ -1890,7 +1896,7 @@ ZipFSMkZipOrImgObjCmd( if (isList && (lobjc % 2)) { Tcl_DecrRefCount(list); Tcl_SetObjResult(interp, - Tcl_NewStringObj("need even number of elements", -1)); + Tcl_NewStringObj("need even number of elements", -1)); return TCL_ERROR; } if (lobjc == 0) { @@ -1904,35 +1910,33 @@ ZipFSMkZipOrImgObjCmd( || (Tcl_SetChannelOption(interp, out, "-translation", "binary") != TCL_OK) || (Tcl_SetChannelOption(interp, out, "-encoding", "binary") != TCL_OK) ) { - Tcl_DecrRefCount(list); - Tcl_Close(interp, out); - return TCL_ERROR; + Tcl_DecrRefCount(list); + Tcl_Close(interp, out); + return TCL_ERROR; + } + if (pwlen <= 0) { + pw = NULL; + pwlen = 0; } if (isImg) { - ZipFile zf0; + ZipFile *zf, zf0; + int isMounted = 0; const char *imgName; if (isList) { - imgName = (objc > 4) ? Tcl_GetString(objv[4]) : - Tcl_GetNameOfExecutable(); + imgName = (objc > 4) ? Tcl_GetString(objv[4]) : Tcl_GetNameOfExecutable(); } else { - imgName = (objc > 5) ? Tcl_GetString(objv[5]) : - Tcl_GetNameOfExecutable(); - } - if (ZipFSOpenArchive(interp, imgName, 0, &zf0) != TCL_OK) { - Tcl_DecrRefCount(list); - Tcl_Close(interp, out); - return TCL_ERROR; + imgName = (objc > 5) ? Tcl_GetString(objv[5]) : Tcl_GetNameOfExecutable(); } - if ((pw != NULL) && pwlen) { + if (pwlen) { i = 0; len = pwlen; while (len > 0) { - int ch = pw[len - 1]; + int ch = pw[len - 1]; - pwbuf[i] = (ch & 0x0f) | pwrot[(ch >> 4) & 0x0f]; - i++; - len--; + pwbuf[i] = (ch & 0x0f) | pwrot[(ch >> 4) & 0x0f]; + i++; + len--; } pwbuf[i] = i; ++i; @@ -1942,23 +1946,108 @@ ZipFSMkZipOrImgObjCmd( pwbuf[i++] = (char) (ZIP_PASSWORD_END_SIG >> 24); pwbuf[i] = '\0'; } - i = Tcl_Write(out, (char *) zf0.data, zf0.baseoffsp); - if (i != zf0.baseoffsp) { - Tcl_DecrRefCount(list); - Tcl_SetObjResult(interp, Tcl_NewStringObj("write error", -1)); - Tcl_Close(interp, out); - ZipFSCloseArchive(interp, &zf0); - return TCL_ERROR; + /* Check for mounted image */ + WriteLock(); + hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); + while (hPtr != NULL) { + if ((zf = (ZipFile *) Tcl_GetHashValue(hPtr)) != NULL) { + if (strcmp(zf->name, imgName) == 0) { + isMounted = 1; + zf->nopen++; + break; + } + } + hPtr = Tcl_NextHashEntry(&search); + } + Unlock(); + if (!isMounted) { + zf = &zf0; + } + if (isMounted || + (ZipFSOpenArchive(interp, imgName, 0, zf) == TCL_OK)) { + i = Tcl_Write(out, (char *) zf->data, zf->baseoffsp); + if (i != zf->baseoffsp) { + memset(pwbuf, 0, sizeof (pwbuf)); + Tcl_DecrRefCount(list); + Tcl_SetObjResult(interp, Tcl_NewStringObj("write error", -1)); + Tcl_Close(interp, out); + if (zf == &zf0) { + ZipFSCloseArchive(interp, zf); + } else { + WriteLock(); + zf->nopen--; + Unlock(); + } + return TCL_ERROR; + } + if (zf == &zf0) { + ZipFSCloseArchive(interp, zf); + } else { + WriteLock(); + zf->nopen--; + Unlock(); + } + } else { + int k, n, m; + Tcl_Channel in; + const char *errMsg = "seek error"; + + /* + * Fall back to read it as plain file which + * hopefully is a static tclsh or wish binary + * with proper zipfs infrastructure built in. + */ + Tcl_ResetResult(interp); + in = Tcl_OpenFileChannel(interp, imgName, "r", 0644); + if (in == NULL) { + memset(pwbuf, 0, sizeof (pwbuf)); + Tcl_DecrRefCount(list); + Tcl_Close(interp, out); + return TCL_ERROR; + } + Tcl_SetChannelOption(interp, in, "-translation", "binary"); + Tcl_SetChannelOption(interp, in, "-encoding", "binary"); + i = Tcl_Seek(in, 0, SEEK_END); + if (i == -1) { +cperr: + memset(pwbuf, 0, sizeof (pwbuf)); + Tcl_DecrRefCount(list); + Tcl_SetObjResult(interp, Tcl_NewStringObj(errMsg, -1)); + Tcl_Close(interp, out); + Tcl_Close(interp, in); + return TCL_ERROR; + } + Tcl_Seek(in, 0, SEEK_SET); + k = 0; + while (k < i) { + m = i - k; + if (m > sizeof (buf)) { + m = sizeof (buf); + } + n = Tcl_Read(in, buf, m); + if (n == -1) { + errMsg = "read error"; + goto cperr; + } else if (n == 0) { + break; + } + m = Tcl_Write(out, buf, n); + if (m != n) { + errMsg = "write error"; + goto cperr; + } + k += m; + } + Tcl_Close(interp, in); } - ZipFSCloseArchive(interp, &zf0); len = strlen(pwbuf); if (len > 0) { i = Tcl_Write(out, pwbuf, len); if (i != len) { - Tcl_DecrRefCount(list); - Tcl_SetObjResult(interp, Tcl_NewStringObj("write error", -1)); - Tcl_Close(interp, out); - return TCL_ERROR; + Tcl_DecrRefCount(list); + Tcl_SetObjResult(interp, Tcl_NewStringObj("write error", -1)); + Tcl_Close(interp, out); + return TCL_ERROR; } } memset(pwbuf, 0, sizeof (pwbuf)); @@ -1992,65 +2081,66 @@ ZipFSMkZipOrImgObjCmd( if (name[0] == '\0') { continue; } - if (ZipAddFile(interp, path, name, out, pw, buf, sizeof (buf), &fileHash) != TCL_OK) { + if (ZipAddFile(interp, path, name, out, pw, buf, sizeof (buf), + &fileHash) != TCL_OK) { goto done; } } pos[1] = Tcl_Tell(out); count = 0; for (i = 0; i < lobjc; i += (isList ? 2 : 1)) { - const char *path, *name; - - path = Tcl_GetString(lobjv[i]); - if (isList) { - name = Tcl_GetString(lobjv[i + 1]); - } else { - name = path; - if (slen > 0) { - len = strlen(name); - if ((len <= slen) || (strncmp(strip, name, slen) != 0)) { - continue; + const char *path, *name; + + path = Tcl_GetString(lobjv[i]); + if (isList) { + name = Tcl_GetString(lobjv[i + 1]); + } else { + name = path; + if (slen > 0) { + len = strlen(name); + if ((len <= slen) || (strncmp(strip, name, slen) != 0)) { + continue; + } + name += slen; } - name += slen; - } - } - while (name[0] == '/') { - ++name; - } - if (name[0] == '\0') { - continue; - } - hPtr = Tcl_FindHashEntry(&fileHash, name); - if (hPtr == NULL) { - continue; - } - z = (ZipEntry *) Tcl_GetHashValue(hPtr); - len = strlen(z->name); - zip_write_int(buf + ZIP_CENTRAL_SIG_OFFS, ZIP_CENTRAL_HEADER_SIG); - zip_write_short(buf + ZIP_CENTRAL_VERSIONMADE_OFFS, ZIP_MIN_VERSION); - zip_write_short(buf + ZIP_CENTRAL_VERSION_OFFS, ZIP_MIN_VERSION); - zip_write_short(buf + ZIP_CENTRAL_FLAGS_OFFS, z->isenc ? 1 : 0); - zip_write_short(buf + ZIP_CENTRAL_COMPMETH_OFFS, z->cmeth); - zip_write_short(buf + ZIP_CENTRAL_MTIME_OFFS, ToDosTime(z->timestamp)); - zip_write_short(buf + ZIP_CENTRAL_MDATE_OFFS, ToDosDate(z->timestamp)); - zip_write_int(buf + ZIP_CENTRAL_CRC32_OFFS, z->crc32); - zip_write_int(buf + ZIP_CENTRAL_COMPLEN_OFFS, z->nbytecompr); - zip_write_int(buf + ZIP_CENTRAL_UNCOMPLEN_OFFS, z->nbyte); - zip_write_short(buf + ZIP_CENTRAL_PATHLEN_OFFS, len); - zip_write_short(buf + ZIP_CENTRAL_EXTRALEN_OFFS, 0); - zip_write_short(buf + ZIP_CENTRAL_FCOMMENTLEN_OFFS, 0); - zip_write_short(buf + ZIP_CENTRAL_DISKFILE_OFFS, 0); - zip_write_short(buf + ZIP_CENTRAL_IATTR_OFFS, 0); - zip_write_int(buf + ZIP_CENTRAL_EATTR_OFFS, 0); - zip_write_int(buf + ZIP_CENTRAL_LOCALHDR_OFFS, z->offset - pos[0]); - if ( - (Tcl_Write(out, buf, ZIP_CENTRAL_HEADER_LEN) != ZIP_CENTRAL_HEADER_LEN) - || (Tcl_Write(out, z->name, len) != len) - ) { - Tcl_SetObjResult(interp, Tcl_NewStringObj("write error", -1)); - goto done; - } - count++; + } + while (name[0] == '/') { + ++name; + } + if (name[0] == '\0') { + continue; + } + hPtr = Tcl_FindHashEntry(&fileHash, name); + if (hPtr == NULL) { + continue; + } + z = (ZipEntry *) Tcl_GetHashValue(hPtr); + len = strlen(z->name); + zip_write_int(buf + ZIP_CENTRAL_SIG_OFFS, ZIP_CENTRAL_HEADER_SIG); + zip_write_short(buf + ZIP_CENTRAL_VERSIONMADE_OFFS, ZIP_MIN_VERSION); + zip_write_short(buf + ZIP_CENTRAL_VERSION_OFFS, ZIP_MIN_VERSION); + zip_write_short(buf + ZIP_CENTRAL_FLAGS_OFFS, z->isenc ? 1 : 0); + zip_write_short(buf + ZIP_CENTRAL_COMPMETH_OFFS, z->cmeth); + zip_write_short(buf + ZIP_CENTRAL_MTIME_OFFS, ToDosTime(z->timestamp)); + zip_write_short(buf + ZIP_CENTRAL_MDATE_OFFS, ToDosDate(z->timestamp)); + zip_write_int(buf + ZIP_CENTRAL_CRC32_OFFS, z->crc32); + zip_write_int(buf + ZIP_CENTRAL_COMPLEN_OFFS, z->nbytecompr); + zip_write_int(buf + ZIP_CENTRAL_UNCOMPLEN_OFFS, z->nbyte); + zip_write_short(buf + ZIP_CENTRAL_PATHLEN_OFFS, len); + zip_write_short(buf + ZIP_CENTRAL_EXTRALEN_OFFS, 0); + zip_write_short(buf + ZIP_CENTRAL_FCOMMENTLEN_OFFS, 0); + zip_write_short(buf + ZIP_CENTRAL_DISKFILE_OFFS, 0); + zip_write_short(buf + ZIP_CENTRAL_IATTR_OFFS, 0); + zip_write_int(buf + ZIP_CENTRAL_EATTR_OFFS, 0); + zip_write_int(buf + ZIP_CENTRAL_LOCALHDR_OFFS, z->offset - pos[0]); + if ( + (Tcl_Write(out, buf, ZIP_CENTRAL_HEADER_LEN) != ZIP_CENTRAL_HEADER_LEN) + || (Tcl_Write(out, z->name, len) != len) + ) { + Tcl_SetObjResult(interp, Tcl_NewStringObj("write error", -1)); + goto done; + } + count++; } Tcl_Flush(out); pos[2] = Tcl_Tell(out); @@ -2070,9 +2160,9 @@ ZipFSMkZipOrImgObjCmd( ret = TCL_OK; done: if (ret == TCL_OK) { - ret = Tcl_Close(interp, out); + ret = Tcl_Close(interp, out); } else { - Tcl_Close(interp, out); + Tcl_Close(interp, out); } Tcl_DecrRefCount(list); hPtr = Tcl_FirstHashEntry(&fileHash, &search); @@ -2080,7 +2170,7 @@ done: z = (ZipEntry *) Tcl_GetHashValue(hPtr); Tcl_Free((char *) z); Tcl_DeleteHashEntry(hPtr); - hPtr = Tcl_FirstHashEntry(&fileHash, &search); + hPtr = Tcl_NextHashEntry(&search); } Tcl_DeleteHashTable(&fileHash); return ret; @@ -2092,13 +2182,13 @@ done: * ZipFSMkZipObjCmd -- * * This procedure is invoked to process the "zipfs::mkzip" command. - * See description of ZipFSMkZipOrImgCmd(). + * See description of ZipFSMkZipOrImgCmd(). * * Results: * A standard Tcl result. * * Side effects: - * See description of ZipFSMkZipOrImgCmd(). + * See description of ZipFSMkZipOrImgCmd(). * *------------------------------------------------------------------------- */ @@ -2120,30 +2210,30 @@ ZipFSLMkZipObjCmd( /* *------------------------------------------------------------------------- * - * ZipFSMkImgObjCmd -- + * ZipFSZipFSOpenArchiveObjCmd -- * * This procedure is invoked to process the "zipfs::mkimg" command. - * See description of ZipFSMkZipOrImgCmd(). + * See description of ZipFSMkZipOrImgCmd(). * * Results: * A standard Tcl result. * * Side effects: - * See description of ZipFSMkZipOrImgCmd(). + * See description of ZipFSMkZipOrImgCmd(). * *------------------------------------------------------------------------- */ static int ZipFSMkImgObjCmd(ClientData clientData, Tcl_Interp *interp, - int objc, Tcl_Obj *const objv[]) + int objc, Tcl_Obj *const objv[]) { return ZipFSMkZipOrImgObjCmd(clientData, interp, 1, 0, objc, objv); } static int ZipFSLMkImgObjCmd(ClientData clientData, Tcl_Interp *interp, - int objc, Tcl_Obj *const objv[]) + int objc, Tcl_Obj *const objv[]) { return ZipFSMkZipOrImgObjCmd(clientData, interp, 1, 1, objc, objv); } @@ -2154,8 +2244,8 @@ ZipFSLMkImgObjCmd(ClientData clientData, Tcl_Interp *interp, * ZipFSExistsObjCmd -- * * This procedure is invoked to process the "zipfs::exists" command. - * It tests for the existence of a file in the ZIP filesystem and - * places a boolean into the interp's result. + * It tests for the existence of a file in the ZIP filesystem and + * places a boolean into the interp's result. * * Results: * Always TCL_OK. @@ -2206,8 +2296,8 @@ ZipFSCanonicalObjCmd( * ZipFSExistsObjCmd -- * * This procedure is invoked to process the "zipfs::exists" command. - * It tests for the existence of a file in the ZIP filesystem and - * places a boolean into the interp's result. + * It tests for the existence of a file in the ZIP filesystem and + * places a boolean into the interp's result. * * Results: * Always TCL_OK. @@ -2252,9 +2342,9 @@ ZipFSExistsObjCmd( * ZipFSInfoObjCmd -- * * This procedure is invoked to process the "zipfs::info" command. - * On success, it returns a Tcl list made up of name of ZIP archive - * file, size uncompressed, size compressed, and archive offset of - * a file in the ZIP filesystem. + * On success, it returns a Tcl list made up of name of ZIP archive + * file, size uncompressed, size compressed, and archive offset of + * a file in the ZIP filesystem. * * Results: * A standard Tcl result. @@ -2273,8 +2363,8 @@ ZipFSInfoObjCmd( ZipEntry *z; if (objc != 2) { - Tcl_WrongNumArgs(interp, 1, objv, "filename"); - return TCL_ERROR; + Tcl_WrongNumArgs(interp, 1, objv, "filename"); + return TCL_ERROR; } filename = Tcl_GetStringFromObj(objv[1], 0); ReadLock(); @@ -2298,8 +2388,8 @@ ZipFSInfoObjCmd( * ZipFSListObjCmd -- * * This procedure is invoked to process the "zipfs::list" command. - * On success, it returns a Tcl list of files of the ZIP filesystem - * which match a search pattern (glob or regexp). + * On success, it returns a Tcl list of files of the ZIP filesystem + * which match a search pattern (glob or regexp). * * Results: * A standard Tcl result. @@ -2321,8 +2411,8 @@ ZipFSListObjCmd( Tcl_Obj *result = Tcl_GetObjResult(interp); if (objc > 3) { - Tcl_WrongNumArgs(interp, 1, objv, "?(-glob|-regexp)? ?pattern?"); - return TCL_ERROR; + Tcl_WrongNumArgs(interp, 1, objv, "?(-glob|-regexp)? ?pattern?"); + return TCL_ERROR; } if (objc == 3) { int n; @@ -2340,7 +2430,7 @@ ZipFSListObjCmd( return TCL_ERROR; } } else if (objc == 2) { - pattern = Tcl_GetStringFromObj(objv[1], 0); + pattern = Tcl_GetStringFromObj(objv[1], 0); } ReadLock(); if (pattern != NULL) { @@ -2399,7 +2489,7 @@ ZipFSListObjCmd( static int ZipFSTclLibraryObjCmd(ClientData clientData, Tcl_Interp *interp, - int objc, Tcl_Obj *const objv[]) + int objc, Tcl_Obj *const objv[]) { Tcl_Obj *pResult; @@ -2416,13 +2506,13 @@ ZipFSTclLibraryObjCmd(ClientData clientData, Tcl_Interp *interp, * * ZipChannelClose -- * - * This function is called to close a channel. + * This function is called to close a channel. * * Results: - * Always TCL_OK. + * Always TCL_OK. * * Side effects: - * Resources are free'd. + * Resources are free'd. * *------------------------------------------------------------------------- */ @@ -2433,12 +2523,12 @@ ZipChannelClose(ClientData instanceData, Tcl_Interp *interp) ZipChannel *info = (ZipChannel *) instanceData; if (info->iscompr && (info->ubuf != NULL)) { - Tcl_Free((char *) info->ubuf); - info->ubuf = NULL; + Tcl_Free((char *) info->ubuf); + info->ubuf = NULL; } if (info->isenc) { - info->isenc = 0; - memset(info->keys, 0, sizeof (info->keys)); + info->isenc = 0; + memset(info->keys, 0, sizeof (info->keys)); } if (info->iswr) { ZipEntry *z = info->zipentry; @@ -2473,13 +2563,13 @@ ZipChannelClose(ClientData instanceData, Tcl_Interp *interp) * * ZipChannelRead -- * - * This function is called to read data from channel. + * This function is called to read data from channel. * * Results: - * Number of bytes read or -1 on error with error number set. + * Number of bytes read or -1 on error with error number set. * * Side effects: - * Data is read and file pointer is advanced. + * Data is read and file pointer is advanced. * *------------------------------------------------------------------------- */ @@ -2490,17 +2580,35 @@ ZipChannelRead(ClientData instanceData, char *buf, int toRead, int *errloc) ZipChannel *info = (ZipChannel *) instanceData; unsigned long nextpos; + if (info->isdir < 0) { + /* + * Special case: when executable combined with ZIP archive file + * read data in front of ZIP, i.e. the executable itself. + */ + nextpos = info->nread + toRead; + if (nextpos > info->zipfile->baseoffs) { + toRead = info->zipfile->baseoffs - info->nread; + nextpos = info->zipfile->baseoffs; + } + if (toRead == 0) { + return 0; + } + memcpy(buf, info->zipfile->data, toRead); + info->nread = nextpos; + *errloc = 0; + return toRead; + } if (info->isdir) { - *errloc = EISDIR; - return -1; + *errloc = EISDIR; + return -1; } nextpos = info->nread + toRead; if (nextpos > info->nbyte) { - toRead = info->nbyte - info->nread; - nextpos = info->nbyte; + toRead = info->nbyte - info->nread; + nextpos = info->nbyte; } if (toRead == 0) { - return 0; + return 0; } if (info->isenc) { int i, ch; @@ -2510,7 +2618,7 @@ ZipChannelRead(ClientData instanceData, char *buf, int toRead, int *errloc) buf[i] = zdecode(info->keys, crc32tab, ch); } } else { - memcpy(buf, info->ubuf + info->nread, toRead); + memcpy(buf, info->ubuf + info->nread, toRead); } info->nread = nextpos; *errloc = 0; @@ -2522,40 +2630,40 @@ ZipChannelRead(ClientData instanceData, char *buf, int toRead, int *errloc) * * ZipChannelWrite -- * - * This function is called to write data into channel. + * This function is called to write data into channel. * * Results: - * Number of bytes written or -1 on error with error number set. + * Number of bytes written or -1 on error with error number set. * * Side effects: - * Data is written and file pointer is advanced. + * Data is written and file pointer is advanced. * *------------------------------------------------------------------------- */ static int ZipChannelWrite(ClientData instanceData, const char *buf, - int toWrite, int *errloc) + int toWrite, int *errloc) { ZipChannel *info = (ZipChannel *) instanceData; unsigned long nextpos; if (!info->iswr) { - *errloc = EINVAL; - return -1; + *errloc = EINVAL; + return -1; } nextpos = info->nread + toWrite; if (nextpos > info->nmax) { - toWrite = info->nmax - info->nread; - nextpos = info->nmax; + toWrite = info->nmax - info->nread; + nextpos = info->nmax; } if (toWrite == 0) { - return 0; + return 0; } memcpy(info->ubuf + info->nread, buf, toWrite); info->nread = nextpos; if (info->nread > info->nbyte) { - info->nbyte = info->nread; + info->nbyte = info->nread; } *errloc = 0; return toWrite; @@ -2566,13 +2674,13 @@ ZipChannelWrite(ClientData instanceData, const char *buf, * * ZipChannelSeek -- * - * This function is called to position file pointer of channel. + * This function is called to position file pointer of channel. * * Results: - * New file position or -1 on error with error number set. + * New file position or -1 on error with error number set. * * Side effects: - * File pointer is repositioned according to offset and mode. + * File pointer is repositioned according to offset and mode. * *------------------------------------------------------------------------- */ @@ -2581,27 +2689,36 @@ static int ZipChannelSeek(ClientData instanceData, long offset, int mode, int *errloc) { ZipChannel *info = (ZipChannel *) instanceData; + unsigned long end; - if (info->isdir) { + if (!info->iswr && (info->isdir < 0)) { + /* + * Special case: when executable combined with ZIP archive file, + * seek within front of ZIP, i.e. the executable itself. + */ + end = info->zipfile->baseoffs; + } else if (info->isdir) { *errloc = EINVAL; return -1; + } else { + end = info->nbyte; } switch (mode) { - case SEEK_CUR: + case SEEK_CUR: offset += info->nread; break; - case SEEK_END: - offset += info->nbyte; + case SEEK_END: + offset += end; break; - case SEEK_SET: + case SEEK_SET: break; - default: + default: *errloc = EINVAL; return -1; } if (offset < 0) { - *errloc = EINVAL; - return -1; + *errloc = EINVAL; + return -1; } if (info->iswr) { if ((unsigned long) offset > info->nmax) { @@ -2611,7 +2728,7 @@ ZipChannelSeek(ClientData instanceData, long offset, int mode, int *errloc) if ((unsigned long) offset > info->nbyte) { info->nbyte = offset; } - } else if ((unsigned long) offset > info->nbyte) { + } else if ((unsigned long) offset > end) { *errloc = EINVAL; return -1; } @@ -2624,13 +2741,13 @@ ZipChannelSeek(ClientData instanceData, long offset, int mode, int *errloc) * * ZipChannelWatchChannel -- * - * This function is called for event notifications on channel. + * This function is called for event notifications on channel. * * Results: - * None. + * None. * * Side effects: - * None. + * None. * *------------------------------------------------------------------------- */ @@ -2646,14 +2763,14 @@ ZipChannelWatchChannel(ClientData instanceData, int mask) * * ZipChannelGetFile -- * - * This function is called to retrieve OS handle for channel. + * This function is called to retrieve OS handle for channel. * * Results: - * Always TCL_ERROR since there's never an OS handle for a - * file within a ZIP archive. + * Always TCL_ERROR since there's never an OS handle for a + * file within a ZIP archive. * * Side effects: - * None. + * None. * *------------------------------------------------------------------------- */ @@ -2705,14 +2822,14 @@ static Tcl_ChannelType ZipChannelType = { * * ZipChannelOpen -- * - * This function opens a Tcl_Channel on a file from a mounted ZIP - * archive according to given open mode. + * This function opens a Tcl_Channel on a file from a mounted ZIP + * archive according to given open mode. * * Results: - * Tcl_Channel on success, or NULL on error. + * Tcl_Channel on success, or NULL on error. * * Side effects: - * Memory is allocated, the file from the ZIP archive is uncompressed. + * Memory is allocated, the file from the ZIP archive is uncompressed. * *------------------------------------------------------------------------- */ @@ -2732,7 +2849,7 @@ ZipChannelOpen(Tcl_Interp *interp, char *filename, int mode, int permissions) if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj("unsupported open mode", -1)); } - return NULL; + return NULL; } WriteLock(); z = ZipFSLookup(filename); @@ -2746,12 +2863,12 @@ ZipChannelOpen(Tcl_Interp *interp, char *filename, int mode, int permissions) trunc = (mode & O_TRUNC) != 0; wr = (mode & (O_WRONLY | O_RDWR)) != 0; if ((z->cmeth != ZIP_COMPMETH_STORED) && (z->cmeth != ZIP_COMPMETH_DEFLATED)) { - ZIPFS_ERROR(interp,"unsupported compression method"); - goto error; + ZIPFS_ERROR(interp,"unsupported compression method"); + goto error; } if (wr && z->isdir) { ZIPFS_ERROR(interp,"unsupported file type"); - goto error; + goto error; } if (!trunc) { flags |= TCL_READABLE; @@ -2763,12 +2880,12 @@ ZipChannelOpen(Tcl_Interp *interp, char *filename, int mode, int permissions) goto error; } } else { - flags = TCL_WRITABLE; + flags = TCL_WRITABLE; } info = (ZipChannel *) Tcl_AttemptAlloc(sizeof (*info)); if (info == NULL) { ZIPFS_ERROR(interp,"out of memory"); - goto error; + goto error; } info->zipfile = z->zipfile; info->zipentry = z; @@ -3004,14 +3121,14 @@ error: * * ZipEntryStat -- * - * This function implements the ZIP filesystem specific version - * of the library version of stat. + * This function implements the ZIP filesystem specific version + * of the library version of stat. * * Results: - * See stat documentation. + * See stat documentation. * * Side effects: - * See stat documentation. + * See stat documentation. * *------------------------------------------------------------------------- */ @@ -3028,9 +3145,9 @@ ZipEntryStat(char *path, Tcl_StatBuf *buf) memset(buf, 0, sizeof (Tcl_StatBuf)); if (z->isdir) { - buf->st_mode = S_IFDIR | 0555; + buf->st_mode = S_IFDIR | 0555; } else { - buf->st_mode = S_IFREG | 0555; + buf->st_mode = S_IFREG | 0555; } buf->st_size = z->nbyte; buf->st_mtime = z->timestamp; @@ -3047,14 +3164,14 @@ done: * * ZipEntryAccess -- * - * This function implements the ZIP filesystem specific version - * of the library version of access. + * This function implements the ZIP filesystem specific version + * of the library version of access. * * Results: - * See access documentation. + * See access documentation. * * Side effects: - * See access documentation. + * See access documentation. * *------------------------------------------------------------------------- */ @@ -3085,7 +3202,7 @@ ZipEntryAccess(char *path, int mode) static Tcl_Channel Zip_FSOpenFileChannelProc(Tcl_Interp *interp, Tcl_Obj *pathPtr, - int mode, int permissions) + int mode, int permissions) { int len; if (!(pathPtr = Tcl_FSGetNormalizedPath(NULL, pathPtr))) return NULL; @@ -3097,14 +3214,14 @@ Zip_FSOpenFileChannelProc(Tcl_Interp *interp, Tcl_Obj *pathPtr, * * Zip_FSStatProc -- * - * This function implements the ZIP filesystem specific version - * of the library version of stat. + * This function implements the ZIP filesystem specific version + * of the library version of stat. * * Results: - * See stat documentation. + * See stat documentation. * * Side effects: - * See stat documentation. + * See stat documentation. * *------------------------------------------------------------------------- */ @@ -3122,14 +3239,14 @@ Zip_FSStatProc(Tcl_Obj *pathPtr, Tcl_StatBuf *buf) * * Zip_FSAccessProc -- * - * This function implements the ZIP filesystem specific version - * of the library version of access. + * This function implements the ZIP filesystem specific version + * of the library version of access. * * Results: - * See access documentation. + * See access documentation. * * Side effects: - * See access documentation. + * See access documentation. * *------------------------------------------------------------------------- */ @@ -3147,16 +3264,16 @@ Zip_FSAccessProc(Tcl_Obj *pathPtr, int mode) * * Zip_FSFilesystemSeparatorProc -- * - * This function returns the separator to be used for a given path. The - * object returned should have a refCount of zero + * This function returns the separator to be used for a given path. The + * object returned should have a refCount of zero * * Results: - * A Tcl object, with a refCount of zero. If the caller needs to retain a - * reference to the object, it should call Tcl_IncrRefCount, and should - * otherwise free the object. + * A Tcl object, with a refCount of zero. If the caller needs to retain a + * reference to the object, it should call Tcl_IncrRefCount, and should + * otherwise free the object. * * Side effects: - * None. + * None. * *------------------------------------------------------------------------- */ @@ -3172,23 +3289,23 @@ Zip_FSFilesystemSeparatorProc(Tcl_Obj *pathPtr) * * Zip_FSMatchInDirectoryProc -- * - * This routine is used by the globbing code to search a directory for - * all files which match a given pattern. + * This routine is used by the globbing code to search a directory for + * all files which match a given pattern. * * Results: - * The return value is a standard Tcl result indicating whether an - * error occurred in globbing. Errors are left in interp, good - * results are lappend'ed to resultPtr (which must be a valid object). + * The return value is a standard Tcl result indicating whether an + * error occurred in globbing. Errors are left in interp, good + * results are lappend'ed to resultPtr (which must be a valid object). * * Side effects: - * None. + * None. * *------------------------------------------------------------------------- */ static int Zip_FSMatchInDirectoryProc(Tcl_Interp* interp, Tcl_Obj *result, - Tcl_Obj *pathPtr, const char *pattern, - Tcl_GlobTypeData *types) + Tcl_Obj *pathPtr, const char *pattern, + Tcl_GlobTypeData *types) { Tcl_HashEntry *hPtr; Tcl_HashSearch search; @@ -3200,7 +3317,7 @@ Zip_FSMatchInDirectoryProc(Tcl_Interp* interp, Tcl_Obj *result, if (!(normPathPtr = Tcl_FSGetNormalizedPath(NULL, pathPtr))) return -1; if (types != NULL) { - dirOnly = (types->type & TCL_GLOB_TYPE_DIR) == TCL_GLOB_TYPE_DIR; + dirOnly = (types->type & TCL_GLOB_TYPE_DIR) == TCL_GLOB_TYPE_DIR; } /* the prefix that gets prepended to results */ @@ -3213,9 +3330,9 @@ Zip_FSMatchInDirectoryProc(Tcl_Interp* interp, Tcl_Obj *result, Tcl_DStringAppend(&dsPref, prefix, prefixLen); if (strcmp(prefix, path) == 0) { - prefix = NULL; + prefix = NULL; } else { - strip = len + 1; + strip = len + 1; } if (prefix != NULL) { Tcl_DStringAppend(&dsPref, "/", 1); @@ -3224,20 +3341,20 @@ Zip_FSMatchInDirectoryProc(Tcl_Interp* interp, Tcl_Obj *result, } ReadLock(); if ((types != NULL) && (types->type == TCL_GLOB_TYPE_MOUNT)) { - l = CountSlashes(path); - if (path[len - 1] == '/') { - len--; - } else { - l++; - } - if ((pattern == NULL) || (pattern[0] == '\0')) { - pattern = "*"; - } - hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); - while (hPtr != NULL) { - ZipFile *zf = (ZipFile *) Tcl_GetHashValue(hPtr); - - if (zf->mntptlen == 0) { + l = CountSlashes(path); + if (path[len - 1] == '/') { + len--; + } else { + l++; + } + if ((pattern == NULL) || (pattern[0] == '\0')) { + pattern = "*"; + } + hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); + while (hPtr != NULL) { + ZipFile *zf = (ZipFile *) Tcl_GetHashValue(hPtr); + + if (zf->mntptlen == 0) { ZipEntry *z = zf->topents; while (z != NULL) { int lenz = strlen(z->name); @@ -3262,13 +3379,13 @@ Zip_FSMatchInDirectoryProc(Tcl_Interp* interp, Tcl_Obj *result, } z = z->tnext; } - } else if ( - (zf->mntptlen > len + 1) - && (strncmp(zf->mntpt, path, len) == 0) - && (zf->mntpt[len] == '/') - && (CountSlashes(zf->mntpt) == l) - && Tcl_StringCaseMatch(zf->mntpt + len + 1, pattern, 0) - ) { + } else if ( + (zf->mntptlen > len + 1) + && (strncmp(zf->mntpt, path, len) == 0) + && (zf->mntpt[len] == '/') + && (CountSlashes(zf->mntpt) == l) + && Tcl_StringCaseMatch(zf->mntpt + len + 1, pattern, 0) + ) { if (prefix != NULL) { Tcl_DStringAppend(&dsPref, zf->mntpt, zf->mntptlen); Tcl_ListObjAppendElement(NULL, result, @@ -3279,38 +3396,38 @@ Zip_FSMatchInDirectoryProc(Tcl_Interp* interp, Tcl_Obj *result, Tcl_ListObjAppendElement(NULL, result, Tcl_NewStringObj(zf->mntpt, zf->mntptlen)); } - } - hPtr = Tcl_NextHashEntry(&search); - } - goto end; + } + hPtr = Tcl_NextHashEntry(&search); + } + goto end; } if ((pattern == NULL) || (pattern[0] == '\0')) { - hPtr = Tcl_FindHashEntry(&ZipFS.fileHash, path); - if (hPtr != NULL) { - ZipEntry *z = (ZipEntry *) Tcl_GetHashValue(hPtr); - - if ((dirOnly < 0) || - (!dirOnly && !z->isdir) || - (dirOnly && z->isdir)) { - if (prefix != NULL) { - Tcl_DStringAppend(&dsPref, z->name, -1); - Tcl_ListObjAppendElement(NULL, result, - Tcl_NewStringObj(Tcl_DStringValue(&dsPref), - Tcl_DStringLength(&dsPref))); - Tcl_DStringSetLength(&dsPref, prefixLen); - } else { - Tcl_ListObjAppendElement(NULL, result, - Tcl_NewStringObj(z->name, -1)); - } - } - } - goto end; + hPtr = Tcl_FindHashEntry(&ZipFS.fileHash, path); + if (hPtr != NULL) { + ZipEntry *z = (ZipEntry *) Tcl_GetHashValue(hPtr); + + if ((dirOnly < 0) || + (!dirOnly && !z->isdir) || + (dirOnly && z->isdir)) { + if (prefix != NULL) { + Tcl_DStringAppend(&dsPref, z->name, -1); + Tcl_ListObjAppendElement(NULL, result, + Tcl_NewStringObj(Tcl_DStringValue(&dsPref), + Tcl_DStringLength(&dsPref))); + Tcl_DStringSetLength(&dsPref, prefixLen); + } else { + Tcl_ListObjAppendElement(NULL, result, + Tcl_NewStringObj(z->name, -1)); + } + } + } + goto end; } l = strlen(pattern); pat = Tcl_Alloc(len + l + 2); memcpy(pat, path, len); while ((len > 1) && (pat[len - 1] == '/')) { - --len; + --len; } if ((len > 1) || (pat[0] != '/')) { pat[len] = '/'; @@ -3320,9 +3437,9 @@ Zip_FSMatchInDirectoryProc(Tcl_Interp* interp, Tcl_Obj *result, scnt = CountSlashes(pat); for ( hPtr = Tcl_FirstHashEntry(&ZipFS.fileHash, &search); - hPtr != NULL; - hPtr = Tcl_NextHashEntry(&search) - ) { + hPtr != NULL; + hPtr = Tcl_NextHashEntry(&search) + ) { ZipEntry *z = (ZipEntry *) Tcl_GetHashValue(hPtr); if ( (dirOnly >= 0) && ((dirOnly && !z->isdir) || (!dirOnly && z->isdir)) @@ -3355,14 +3472,14 @@ end: * * Zip_FSPathInFilesystemProc -- * - * This function determines if the given path object is in the - * ZIP filesystem. + * This function determines if the given path object is in the + * ZIP filesystem. * * Results: - * TCL_OK when the path object is in the ZIP filesystem, -1 otherwise. + * TCL_OK when the path object is in the ZIP filesystem, -1 otherwise. * * Side effects: - * None. + * None. * *------------------------------------------------------------------------- */ @@ -3424,13 +3541,13 @@ endloop: * * Zip_FSListVolumesProc -- * - * Lists the currently mounted ZIP filesystem volumes. + * Lists the currently mounted ZIP filesystem volumes. * * Results: - * The list of volumes. + * The list of volumes. * * Side effects: - * None + * None * *------------------------------------------------------------------------- */ @@ -3444,14 +3561,14 @@ Zip_FSListVolumesProc(void) { * * Zip_FSFileAttrStringsProc -- * - * This function implements the ZIP filesystem dependent 'file attributes' - * subcommand, for listing the set of possible attribute strings. + * This function implements the ZIP filesystem dependent 'file attributes' + * subcommand, for listing the set of possible attribute strings. * * Results: - * An array of strings + * An array of strings * * Side effects: - * None. + * None. * *------------------------------------------------------------------------- */ @@ -3460,13 +3577,13 @@ static const char *const * Zip_FSFileAttrStringsProc(Tcl_Obj *pathPtr, Tcl_Obj** objPtrRef) { static const char *const attrs[] = { - "-uncompsize", - "-compsize", - "-offset", - "-mount", - "-archive", - "-permissions", - NULL, + "-uncompsize", + "-compsize", + "-offset", + "-mount", + "-archive", + "-permissions", + NULL, }; return attrs; } @@ -3476,24 +3593,24 @@ Zip_FSFileAttrStringsProc(Tcl_Obj *pathPtr, Tcl_Obj** objPtrRef) * * Zip_FSFileAttrsGetProc -- * - * This function implements the ZIP filesystem specific - * 'file attributes' subcommand, for 'get' operations. + * This function implements the ZIP filesystem specific + * 'file attributes' subcommand, for 'get' operations. * * Results: - * Standard Tcl return code. The object placed in objPtrRef (if TCL_OK - * was returned) is likely to have a refCount of zero. Either way we must - * either store it somewhere (e.g. the Tcl result), or Incr/Decr its - * refCount to ensure it is properly freed. + * Standard Tcl return code. The object placed in objPtrRef (if TCL_OK + * was returned) is likely to have a refCount of zero. Either way we must + * either store it somewhere (e.g. the Tcl result), or Incr/Decr its + * refCount to ensure it is properly freed. * * Side effects: - * None. + * None. * *------------------------------------------------------------------------- */ static int Zip_FSFileAttrsGetProc(Tcl_Interp *interp, int index, Tcl_Obj *pathPtr, - Tcl_Obj **objPtrRef) + Tcl_Obj **objPtrRef) { int len, ret = TCL_OK; char *path; @@ -3540,14 +3657,14 @@ done: * * Zip_FSFileAttrsSetProc -- * - * This function implements the ZIP filesystem specific - * 'file attributes' subcommand, for 'set' operations. + * This function implements the ZIP filesystem specific + * 'file attributes' subcommand, for 'set' operations. * * Results: - * Standard Tcl return code. + * Standard Tcl return code. * * Side effects: - * None. + * None. * *------------------------------------------------------------------------- */ @@ -3556,7 +3673,7 @@ static int Zip_FSFileAttrsSetProc(Tcl_Interp *interp, int index, Tcl_Obj *pathPtr,Tcl_Obj *objPtr) { if (interp != NULL) { - Tcl_SetObjResult(interp, Tcl_NewStringObj("unsupported operation", -1)); + Tcl_SetObjResult(interp, Tcl_NewStringObj("unsupported operation", -1)); } return TCL_ERROR; } @@ -3585,50 +3702,53 @@ Zip_FSFilesystemPathTypeProc(Tcl_Obj *pathPtr) * * Zip_FSLoadFile -- * - * This functions deals with loading native object code. If - * the given path object refers to a file within the ZIP - * filesystem, an approriate error code is returned to delegate - * loading to the caller (by copying the file to temp store - * and loading from there). As fallback when the file refers - * to the ZIP file system but is not present, it is looked up - * relative to the executable and loaded from there when available. + * This functions deals with loading native object code. If + * the given path object refers to a file within the ZIP + * filesystem, an approriate error code is returned to delegate + * loading to the caller (by copying the file to temp store + * and loading from there). As fallback when the file refers + * to the ZIP file system but is not present, it is looked up + * relative to the executable and loaded from there when available. * * Results: - * TCL_OK on success, -1 otherwise with error number set. + * TCL_OK on success, TCL_ERROR otherwise with error message left. * * Side effects: - * Loads native code into the process address space. + * Loads native code into the process address space. * *------------------------------------------------------------------------- */ static int Zip_FSLoadFile(Tcl_Interp *interp, Tcl_Obj *path, Tcl_LoadHandle *loadHandle, - Tcl_FSUnloadFileProc **unloadProcPtr, int flags) + Tcl_FSUnloadFileProc **unloadProcPtr, int flags) { Tcl_FSLoadFileProc2 *loadFileProc; #ifdef ANDROID /* * Force loadFileProc to native implementation since the - * package manger already extracted the shared libraries + * package manager already extracted the shared libraries * from the APK at install time. */ loadFileProc = (Tcl_FSLoadFileProc2 *) tclNativeFilesystem.loadFileProc; if (loadFileProc != NULL) { - return loadFileProc(interp, path, loadHandle, unloadProcPtr, flags); + return loadFileProc(interp, path, loadHandle, unloadProcPtr, flags); } Tcl_SetErrno(ENOENT); - return -1; + ZIPFS_ERROR(interp,Tcl_PosixError(interp)); + return TCL_ERROR; #else Tcl_Obj *altPath = NULL; - int ret = -1; + int ret = TCL_ERROR; if (Tcl_FSAccess(path, R_OK) == 0) { /* * EXDEV should trigger loading by copying to temp store. */ + Tcl_SetErrno(EXDEV); + ZIPFS_ERROR(interp,Tcl_PosixError(interp)); return ret; } else { Tcl_Obj *objs[2] = { NULL, NULL }; @@ -3658,14 +3778,15 @@ Zip_FSLoadFile(Tcl_Interp *interp, Tcl_Obj *path, Tcl_LoadHandle *loadHandle, } } if (objs[0] == NULL) { - objs[0] = TclPathPart(interp, TclGetObjNameOfExecutable(),TCL_PATH_DIRNAME); + objs[0] = TclPathPart(interp, TclGetObjNameOfExecutable(), + TCL_PATH_DIRNAME); } if (objs[0] != NULL) { - altPath = TclJoinPath(2, objs); + altPath = TclJoinPath(2, objs); if (altPath != NULL) { Tcl_IncrRefCount(altPath); if (Tcl_FSAccess(altPath, R_OK) == 0) { - path = altPath; + path = altPath; } } } @@ -3679,12 +3800,13 @@ Zip_FSLoadFile(Tcl_Interp *interp, Tcl_Obj *path, Tcl_LoadHandle *loadHandle, } loadFileProc = (Tcl_FSLoadFileProc2 *) tclNativeFilesystem.loadFileProc; if (loadFileProc != NULL) { - ret = loadFileProc(interp, path, loadHandle, unloadProcPtr, flags); + ret = loadFileProc(interp, path, loadHandle, unloadProcPtr, flags); } else { - Tcl_SetErrno(ENOENT); + Tcl_SetErrno(ENOENT); + ZIPFS_ERROR(interp,Tcl_PosixError(interp)); } if (altPath != NULL) { - Tcl_DecrRefCount(altPath); + Tcl_DecrRefCount(altPath); } return ret; #endif @@ -3740,14 +3862,14 @@ const Tcl_Filesystem zipfsFilesystem = { * * TclZipfs_Init -- * - * Perform per interpreter initialization of this module. + * Perform per interpreter initialization of this module. * * Results: - * The return value is a standard Tcl result. + * The return value is a standard Tcl result. * * Side effects: - * Initializes this module if not already initialized, and adds - * module related commands to the given interpreter. + * Initializes this module if not already initialized, and adds + * module related commands to the given interpreter. * *------------------------------------------------------------------------- */ @@ -3761,35 +3883,35 @@ TclZipfs_Init(Tcl_Interp *interp) Tcl_StaticPackage(interp, "zipfs", TclZipfs_Init, TclZipfs_Init); if (!ZipFS.initialized) { #ifdef TCL_THREADS - static const Tcl_Time t = { 0, 0 }; - /* - * Inflate condition variable. - */ - Tcl_MutexLock(&ZipFSMutex); - Tcl_ConditionWait(&ZipFSCond, &ZipFSMutex, &t); - Tcl_MutexUnlock(&ZipFSMutex); + static const Tcl_Time t = { 0, 0 }; + /* + * Inflate condition variable. + */ + Tcl_MutexLock(&ZipFSMutex); + Tcl_ConditionWait(&ZipFSCond, &ZipFSMutex, &t); + Tcl_MutexUnlock(&ZipFSMutex); #endif - Tcl_FSRegister(NULL, &zipfsFilesystem); - Tcl_InitHashTable(&ZipFS.fileHash, TCL_STRING_KEYS); - Tcl_InitHashTable(&ZipFS.zipHash, TCL_STRING_KEYS); - ZipFS.initialized = ZipFS.idCount = 1; + Tcl_FSRegister(NULL, &zipfsFilesystem); + Tcl_InitHashTable(&ZipFS.fileHash, TCL_STRING_KEYS); + Tcl_InitHashTable(&ZipFS.zipHash, TCL_STRING_KEYS); + ZipFS.initialized = ZipFS.idCount = 1; } Unlock(); if(interp != NULL) { static const EnsembleImplMap initMap[] = { - {"mount", ZipFSMountObjCmd, NULL, NULL, NULL, 0}, - {"unmount", ZipFSUnmountObjCmd, NULL, NULL, NULL, 0}, - {"mkkey", ZipFSMkKeyObjCmd, NULL, NULL, NULL, 0}, - {"mkimg", ZipFSMkImgObjCmd, NULL, NULL, NULL, 0}, - {"mkzip", ZipFSMkZipObjCmd, NULL, NULL, NULL, 0}, - {"lmkimg", ZipFSLMkImgObjCmd, NULL, NULL, NULL, 0}, - {"lmkzip", ZipFSLMkZipObjCmd, NULL, NULL, NULL, 0}, - {"exists", ZipFSExistsObjCmd, NULL, NULL, NULL, 1}, - {"info", ZipFSInfoObjCmd, NULL, NULL, NULL, 1}, - {"list", ZipFSListObjCmd, NULL, NULL, NULL, 1}, + {"mount", ZipFSMountObjCmd, NULL, NULL, NULL, 0}, + {"unmount", ZipFSUnmountObjCmd, NULL, NULL, NULL, 0}, + {"mkkey", ZipFSMkKeyObjCmd, NULL, NULL, NULL, 0}, + {"mkimg", ZipFSMkImgObjCmd, NULL, NULL, NULL, 0}, + {"mkzip", ZipFSMkZipObjCmd, NULL, NULL, NULL, 0}, + {"lmkimg", ZipFSLMkImgObjCmd, NULL, NULL, NULL, 0}, + {"lmkzip", ZipFSLMkZipObjCmd, NULL, NULL, NULL, 0}, + {"exists", ZipFSExistsObjCmd, NULL, NULL, NULL, 1}, + {"info", ZipFSInfoObjCmd, NULL, NULL, NULL, 1}, + {"list", ZipFSListObjCmd, NULL, NULL, NULL, 1}, {"canonical", ZipFSCanonicalObjCmd, NULL, NULL, NULL, 1}, {"root", ZipFSRootObjCmd, NULL, NULL, NULL, 1}, - {"tcl_library", ZipFSTclLibraryObjCmd, NULL, NULL, NULL, 0}, + {"tcl_library", ZipFSTclLibraryObjCmd, NULL, NULL, NULL, 0}, {NULL, NULL, NULL, NULL, NULL, 0} }; @@ -3825,7 +3947,7 @@ TclZipfs_Init(Tcl_Interp *interp) } #if defined(_WIN32) || defined(_WIN64) -#define LIBRARY_SIZE 64 +#define LIBRARY_SIZE 64 static int ToUtf( const WCHAR *wSrc, @@ -3835,8 +3957,8 @@ ToUtf( start = dst; while (*wSrc != '\0') { - dst += Tcl_UniCharToUtf(*wSrc, dst); - wSrc++; + dst += Tcl_UniCharToUtf(*wSrc, dst); + wSrc++; } *dst = '\0'; return (int) (dst - start); @@ -3916,7 +4038,7 @@ int TclZipfs_AppHook(int *argc, char ***argv) } else if (*argc>1) { #if defined(_WIN32) || defined(_WIN64) Tcl_DString ds; - strcpy(archive, Tcl_WinTCharToUtf((*argv)[1], -1, &ds)); + strcpy(archive, Tcl_WinTCharToUtf((*argv)[1], -1, &ds)); Tcl_DStringFree(&ds); #else archive=(*argv)[1]; @@ -4004,14 +4126,14 @@ Tcl_Obj *TclZipfs_TclLibrary(void) { * * TclZipfs_Mount, TclZipfs_Unmount -- * - * Dummy version when no ZLIB support available. + * Dummy version when no ZLIB support available. * *------------------------------------------------------------------------- */ int TclZipfs_Mount(Tcl_Interp *interp, const char *zipname, const char *mntpt, - const char *passwd) + const char *passwd) { return TclZipfs_Init(interp, 1); } -- cgit v0.12 From 7154cc9c4777ae2394afa07b79adfb6680261293 Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Fri, 24 Nov 2017 11:46:34 +0000 Subject: Tweak to ensure mount points for zipfs are corralled into the //zipfs:/ prefix space --- generic/tclZipfs.c | 140 +++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 126 insertions(+), 14 deletions(-) diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c index 668eee0..2370980 100644 --- a/generic/tclZipfs.c +++ b/generic/tclZipfs.c @@ -35,11 +35,10 @@ #include "crypt.h" /* -** On windows we need VFS to look like a volume -** On Unix we need it to look like a UNC path +** TIP430 style zipfs prefix */ #define ZIPFS_VOLUME "//zipfs:/" -#define ZIPFS_VOLUME_LEN 9 +#define ZIPFS_VOLUME_LEN 9 #define ZIPFS_APP_MOUNT "//zipfs:/app" #define ZIPFS_ZIP_MOUNT "//zipfs:/lib/tcl" /* @@ -659,8 +658,88 @@ CanonicalPath(const char *root, const char *tail, Tcl_DString *dsPtr,int ZIPFSPA result=Tcl_DStringValue(dsPtr); return result; } + +/* + *------------------------------------------------------------------------- + * + * AbsolutePath -- + * + * This function computes the absolute path from a given + * (relative) path name into the specified Tcl_DString. + * + * Results: + * Returns the pointer to the absolute path contained in the + * specified Tcl_DString. + * + * Side effects: + * Modifies the specified Tcl_DString. + * + *------------------------------------------------------------------------- + */ +static char * +AbsolutePath(const char *path, +#if HAS_DRIVES + int *drvPtr, +#endif + Tcl_DString *dsPtr) +{ + char *result; + +#if HAS_DRIVES + if (drvPtr != NULL) { + *drvPtr = 0; + } +#endif + if (*path == '~') { + Tcl_DStringAppend(dsPtr, path, -1); + return Tcl_DStringValue(dsPtr); + } + if ((*path != '/') +#if HAS_DRIVES + && (*path != '\\') && + (((*path != '\0') && (strchr(drvletters, *path) == NULL)) || + (path[1] != ':')) +#endif + ) { + Tcl_DString pwd; + + /* relative path */ + Tcl_DStringInit(&pwd); + Tcl_GetCwd(NULL, &pwd); + result = Tcl_DStringValue(&pwd); +#if HAS_DRIVES + if ((result[0] != '\0') && (strchr(drvletters, result[0]) != NULL) && + (result[1] == ':')) { + if (drvPtr != NULL) { + drvPtr[0] = result[0]; + if ((drvPtr[0] >= 'a') && (drvPtr[0] <= 'z')) { + drvPtr[0] -= 'a' - 'A'; + } + } + result += 2; + } +#endif + result = CanonicalPath(result, path, dsPtr, 0); + Tcl_DStringFree(&pwd); + } else { + /* absolute path */ +#if HAS_DRIVES + if ((path[0] != '\0') && (strchr(drvletters, path[0]) != NULL) && + (path[1] == ':')) { + if (drvPtr != NULL) { + drvPtr[0] = path[0]; + if ((drvPtr[0] >= 'a') && (drvPtr[0] <= 'z')) { + drvPtr[0] -= 'a' - 'A'; + } + } + } +#endif + result = CanonicalPath("", path, dsPtr, 0); + } + return result; +} /* *------------------------------------------------------------------------- @@ -985,12 +1064,17 @@ TclZipfs_Mount( const char *mntpt, const char *passwd ) { + char *realname, *p; int i, pwlen, isNew; ZipFile *zf, zf0; ZipEntry *z; Tcl_HashEntry *hPtr; - Tcl_DString ds, fpBuf; + Tcl_DString ds, dsm, fpBuf; unsigned char *q; +#if HAS_DRIVES + int drive = 0; +#endif + ReadLock(); if (!ZipFS.initialized) { ZIPFS_ERROR(interp,"not initialized"); @@ -1024,11 +1108,31 @@ TclZipfs_Mount( Unlock(); return TCL_OK; } - hPtr = Tcl_FindHashEntry(&ZipFS.zipHash, zipname); + Tcl_DStringInit(&ds); +#if HAS_DRIVES + p = AbsolutePath(zipname, &drive, &ds); +#else + p = AbsolutePath(zipname, &ds); +#endif + hPtr = Tcl_FindHashEntry(&ZipFS.zipHash, p); if (hPtr != NULL) { +#if HAS_DRIVES + if (drive == zf->mntdrv) { + Tcl_Obj *string; + char drvbuf[3]; + + drvbuf[0] = zf->mntdrv; + drvbuf[1] = ':'; + drvbuf[2] = '\0'; + string = Tcl_NewStringObj(drvbuf, 2); + Tcl_AppendToObj(string, zf->mntpt, zf->mntptlen); + Tcl_SetObjResult(interp, string); + } +#else if ((zf = Tcl_GetHashValue(hPtr)) != NULL) { Tcl_SetObjResult(interp,Tcl_NewStringObj(zf->mntpt, zf->mntptlen)); } +#endif } Unlock(); return TCL_OK; @@ -1036,23 +1140,31 @@ TclZipfs_Mount( Unlock(); pwlen = 0; if (passwd != NULL) { - pwlen = strlen(passwd); - if ((pwlen > 255) || (strchr(passwd, 0xff) != NULL)) { - if (interp) { - Tcl_SetObjResult(interp, - Tcl_NewStringObj("illegal password", -1)); + pwlen = strlen(passwd); + if ((pwlen > 255) || (strchr(passwd, 0xff) != NULL)) { + if (interp) { + Tcl_SetObjResult(interp, + Tcl_NewStringObj("illegal password", -1)); + } + return TCL_ERROR; } - return TCL_ERROR; - } } if (ZipFSOpenArchive(interp, zipname, 1, &zf0) != TCL_OK) { return TCL_ERROR; } + Tcl_DStringInit(&ds); +#if HAS_DRIVES + realname = AbsolutePath(zipname, NULL, &ds); +#else + realname = AbsolutePath(zipname, &ds); +#endif /* - * Mount point can come from Tcl_GetNameOfExecutable() - * which sometimes is a relative or otherwise denormalized path. + * Mount point sometimes is a relative or otherwise denormalized path. * But an absolute name is needed as mount point here. */ + Tcl_DStringInit(&dsm); + mntpt = CanonicalPath("",mntpt, &dsm, 1); + WriteLock(); hPtr = Tcl_CreateHashEntry(&ZipFS.zipHash, zipname, &isNew); if (!isNew) { -- cgit v0.12 From 99dc87a51d1e450b24f642aacbda0df262402a94 Mon Sep 17 00:00:00 2001 From: tne Date: Sat, 25 Nov 2017 10:54:15 +0000 Subject: Restoring the Makefile.in for the win/ directory after an unfortunate copy/paste error --- win/Makefile.in | 1444 ++++++++++++++++++++++++++++++++----------------------- 1 file changed, 835 insertions(+), 609 deletions(-) diff --git a/win/Makefile.in b/win/Makefile.in index 5f81b74..99c8b77 100644 --- a/win/Makefile.in +++ b/win/Makefile.in @@ -1,26 +1,21 @@ -# This file is a Makefile for Tk. If it has the name "Makefile.in" -# then it is a template for a Makefile; to generate the actual Makefile, -# run "./configure", which is a configuration script generated by the -# "autoconf" program (constructs like "@foo@" will get replaced in the -# actual Makefile. - -TCLVERSION = @TCL_VERSION@ -TCLPATCHL = @TCL_PATCH_LEVEL@ -VERSION = @TK_VERSION@ -PATCH_LEVEL = @TK_PATCH_LEVEL@ - -#---------------------------------------------------------------- -# Things you can change to personalize the Makefile for your own -# site (you can make these changes in either Makefile.in or -# Makefile, but changes to Makefile will get lost if you re-run -# the configuration script). -#---------------------------------------------------------------- - -# Default top-level directories in which to install architecture- -# specific files (exec_prefix) and machine-independent files such -# as scripts (prefix). The values specified here may be overridden -# at configure-time with the --exec-prefix and --prefix options -# to the "configure" script. +# +# This file is a Makefile for Tcl. If it has the name "Makefile.in" then it +# is a template for a Makefile; to generate the actual Makefile, run +# "./configure", which is a configuration script generated by the "autoconf" +# program (constructs like "@foo@" will get replaced in the actual Makefile. + +VERSION = @TCL_VERSION@ + +#-------------------------------------------------------------------------- +# Things you can change to personalize the Makefile for your own site (you can +# make these changes in either Makefile.in or Makefile, but changes to +# Makefile will get lost if you re-run the configuration script). +#-------------------------------------------------------------------------- + +# Default top-level directories in which to install architecture-specific +# files (exec_prefix) and machine-independent files such as scripts (prefix). +# The values specified here may be overridden at configure-time with the +# --exec-prefix and --prefix options to the "configure" script. prefix = @prefix@ exec_prefix = @exec_prefix@ @@ -30,159 +25,164 @@ includedir = @includedir@ datarootdir = @datarootdir@ mandir = @mandir@ -# The following definition can be set to non-null for special systems -# like AFS with replication. It allows the pathnames used for installation -# to be different than those used for actually reference files at -# run-time. INSTALL_ROOT is prepended to $prefix and $exec_prefix -# when installing files. -INSTALL_ROOT = $(DESTDIR) +# The following definition can be set to non-null for special systems like AFS +# with replication. It allows the pathnames used for installation to be +# different than those used for actually reference files at run-time. +# INSTALL_ROOT is prepended to $prefix and $exec_prefix when installing files. +INSTALL_ROOT = -# Directory from which applications will reference the library of Tk -# scripts (note: you can set the TK_LIBRARY environment variable at -# run-time to override this value): -TK_LIBRARY = $(prefix)/lib/tk$(VERSION) +# Directory from which applications will reference the library of Tcl scripts +# (note: you can set the TCL_LIBRARY environment variable at run-time to +# override this value): +TCL_LIBRARY = $(prefix)/lib/tcl$(VERSION) # Path to use at runtime to refer to LIB_INSTALL_DIR: LIB_RUNTIME_DIR = $(libdir) -# Directory in which to install the program wish: +# Directory in which to install the program tclsh: BIN_INSTALL_DIR = $(INSTALL_ROOT)$(bindir) -# Directory in which to install the .a or .so binary for the Tk library: +# Directory in which to install the .a or .so binary for the Tcl library: LIB_INSTALL_DIR = $(INSTALL_ROOT)$(libdir) -# Path name to use when installing library scripts: -SCRIPT_INSTALL_DIR = $(INSTALL_ROOT)$(TK_LIBRARY) +# Path name to use when installing library scripts. +SCRIPT_INSTALL_DIR = $(INSTALL_ROOT)$(TCL_LIBRARY) -# Directory in which to install the include file tk.h: +# Directory in which to install the include file tcl.h: INCLUDE_INSTALL_DIR = $(INSTALL_ROOT)$(includedir) -# Directory in which to (optionally) install the private tk headers: +# Directory in which to (optionally) install the private tcl headers: PRIVATE_INCLUDE_INSTALL_DIR = $(INSTALL_ROOT)$(includedir) -# Top-level directory for manual entries: +# Top-level directory in which to install manual entries: MAN_INSTALL_DIR = $(INSTALL_ROOT)$(mandir) -# Directory in which to install manual entry for wish: -MAN1_INSTALL_DIR = $(MAN_INSTALL_DIR)/man1 +# Directory in which to install manual entry for tclsh: +MAN1_INSTALL_DIR = $(MAN_INSTALL_DIR)/man1 -# Directory in which to install manual entries for Tk's C library -# procedures: -MAN3_INSTALL_DIR = $(MAN_INSTALL_DIR)/man3 +# Directory in which to install manual entries for Tcl's C library procedures: +MAN3_INSTALL_DIR = $(MAN_INSTALL_DIR)/man3 -# Directory in which to install manual entries for the built-in -# Tk commands: -MANN_INSTALL_DIR = $(MAN_INSTALL_DIR)/mann +# Directory in which to install manual entries for the built-in Tcl commands: +MANN_INSTALL_DIR = $(MAN_INSTALL_DIR)/mann # Libraries built with optimization switches have this additional extension -TK_DBGX = @TK_DBGX@ - -# Directory in which to install the pkgIndex.tcl file for loadable Tk -PKG_INSTALL_DIR = $(LIB_INSTALL_DIR)/tk$(VERSION)$(TK_DBGX) - -# Package index file for loadable Tk -PKG_INDEX = $(PKG_INSTALL_DIR)/pkgIndex.tcl - -# The directory containing the Tcl source and header files. -TCL_SRC_DIR = @TCL_SRC_DIR@ +TCL_DBGX = @TCL_DBGX@ -# The directory containing the Tcl library archive file appropriate -# for this version of Tk: -TCL_BIN_DIR = @TCL_BIN_DIR@ +# warning flags +CFLAGS_WARNING = @CFLAGS_WARNING@ -# The directory containing the Tcl sources and headers appropriate -# for this version of Tk ("srcdir" will be replaced or has already -# been replaced by the configure script): -TCL_GENERIC_DIR = @TCL_SRC_DIR@/generic +# The default switches for optimization or debugging +CFLAGS_DEBUG = @CFLAGS_DEBUG@ +CFLAGS_OPTIMIZE = @CFLAGS_OPTIMIZE@ -# The directory containing the platform specific Tcl sources and headers -# appropriate for this version of Tk: -TCL_PLATFORM_DIR = @TCL_SRC_DIR@/win +# To change the compiler switches, for example to change from optimization to +# debugging symbols, change the following line: +#CFLAGS = $(CFLAGS_DEBUG) +#CFLAGS = $(CFLAGS_OPTIMIZE) +#CFLAGS = $(CFLAGS_DEBUG) $(CFLAGS_OPTIMIZE) +CFLAGS = @CFLAGS@ @CFLAGS_DEFAULT@ -DUNICODE -D_UNICODE -D_ATL_XP_TARGETING + +# To compile without backward compatibility and deprecated code uncomment the +# following +NO_DEPRECATED_FLAGS = +#NO_DEPRECATED_FLAGS = -DTCL_NO_DEPRECATED + +# To enable compilation debugging reverse the comment characters on one of the +# following lines. +COMPILE_DEBUG_FLAGS = +#COMPILE_DEBUG_FLAGS = -DTCL_COMPILE_DEBUG +#COMPILE_DEBUG_FLAGS = -DTCL_COMPILE_DEBUG -DTCL_COMPILE_STATS -TCL_TOOL_DIR = @TCL_SRC_DIR@/tools +SRC_DIR = @srcdir@ +ROOT_DIR = @srcdir@/.. +TOP_DIR = $(shell cd @srcdir@/..; pwd -P) +GENERIC_DIR = $(TOP_DIR)/generic +TOMMATH_DIR = $(TOP_DIR)/libtommath +WIN_DIR = $(TOP_DIR)/win +COMPAT_DIR = $(TOP_DIR)/compat +PKGS_DIR = $(TOP_DIR)/pkgs +ZLIB_DIR = $(COMPAT_DIR)/zlib # Converts a POSIX path to a Windows native path. CYGPATH = @CYGPATH@ -# The name of the Tcl library. -TCL_LIB_FILE = "$(shell $(CYGPATH) '@TCL_BIN_DIR@/@TCL_LIB_FILE@')" -TCL_STUB_LIB_FILE = "$(shell $(CYGPATH) '@TCL_BIN_DIR@/@TCL_STUB_LIB_FILE@')" - -SRC_DIR = @srcdir@ -ROOT_DIR = $(SRC_DIR)/.. -WIN_DIR = $(SRC_DIR) -UNIX_DIR = $(SRC_DIR)/../unix -GENERIC_DIR = $(SRC_DIR)/../generic -TTK_DIR = $(GENERIC_DIR)/ttk -BITMAP_DIR = $(ROOT_DIR)/bitmaps -XLIB_DIR = $(ROOT_DIR)/xlib -RC_DIR = $(WIN_DIR)/rc - -ROOT_DIR_NATIVE = $(shell $(CYGPATH) '$(ROOT_DIR)' | sed 's!\\!/!g') -WIN_DIR_NATIVE = $(shell $(CYGPATH) '$(WIN_DIR)' | sed 's!\\!/!g') -GENERIC_DIR_NATIVE = $(shell $(CYGPATH) '$(GENERIC_DIR)' | sed 's!\\!/!g') -BITMAP_DIR_NATIVE = $(ROOT_DIR_NATIVE)/bitmaps -XLIB_DIR_NATIVE = $(ROOT_DIR_NATIVE)/xlib -RC_DIR_NATIVE = $(WIN_DIR_NATIVE)/rc -TCL_GENERIC_NATIVE = $(shell $(CYGPATH) '$(TCL_GENERIC_DIR)' | sed 's!\\!/!g') -TCL_PLATFORM_NATIVE = $(shell $(CYGPATH) '$(TCL_PLATFORM_DIR)' | sed 's!\\!/!g') -TCL_SRC_DIR_NATIVE = $(shell $(CYGPATH) '$(TCL_SRC_DIR)' | sed 's!\\!/!g') - +libdir_native = $(shell $(CYGPATH) '$(libdir)') +bindir_native = $(shell $(CYGPATH) '$(bindir)') +includedir_native = $(shell $(CYGPATH) '$(includedir)') +mandir_native = $(shell $(CYGPATH) '$(mandir)') +TCL_LIBRARY_NATIVE = $(shell $(CYGPATH) '$(TCL_LIBRARY)') +GENERIC_DIR_NATIVE = $(shell $(CYGPATH) '$(GENERIC_DIR)') +TOMMATH_DIR_NATIVE = $(shell $(CYGPATH) '$(TOMMATH_DIR)') +WIN_DIR_NATIVE = $(shell $(CYGPATH) '$(WIN_DIR)') +ROOT_DIR_NATIVE = $(shell $(CYGPATH) '$(ROOT_DIR)') +ZLIB_DIR_NATIVE = $(shell $(CYGPATH) '$(ZLIB_DIR)') +#GENERIC_DIR_NATIVE = $(GENERIC_DIR) +#TOMMATH_DIR_NATIVE = $(TOMMATH_DIR) +#WIN_DIR_NATIVE = $(WIN_DIR) +#ROOT_DIR_NATIVE = $(ROOT_DIR) + +# Fully qualify library path so that `make test` +# does not depend on the current directory. +LIBRARY_DIR1 = $(shell cd '$(ROOT_DIR_NATIVE)/library' ; pwd -P) +LIBRARY_DIR = $(shell $(CYGPATH) '$(LIBRARY_DIR1)') DLLSUFFIX = @DLLSUFFIX@ LIBSUFFIX = @LIBSUFFIX@ EXESUFFIX = @EXESUFFIX@ -TK_STUB_LIB_FILE = @TK_STUB_LIB_FILE@ -TK_LIB_FILE = @TK_LIB_FILE@ -TK_DLL_FILE = @TK_DLL_FILE@ -TEST_DLL_FILE = tktest$(VER)${DLLSUFFIX} -TEST_LIB_FILE = @LIBPREFIX@tktest$(VER)${LIBSUFFIX} - -SHARED_LIBRARIES = $(TK_DLL_FILE) $(TK_STUB_LIB_FILE) -STATIC_LIBRARIES = $(TK_LIB_FILE) - -WISH = wish$(VER)${EXESUFFIX} -TKTEST = tktest${EXEEXT} +VER = @TCL_MAJOR_VERSION@@TCL_MINOR_VERSION@ +DOTVER = @TCL_MAJOR_VERSION@.@TCL_MINOR_VERSION@ +DDEVER = @TCL_DDE_MAJOR_VERSION@@TCL_DDE_MINOR_VERSION@ +DDEDOTVER = @TCL_DDE_MAJOR_VERSION@.@TCL_DDE_MINOR_VERSION@ +REGVER = @TCL_REG_MAJOR_VERSION@@TCL_REG_MINOR_VERSION@ +REGDOTVER = @TCL_REG_MAJOR_VERSION@.@TCL_REG_MINOR_VERSION@ + +TCL_ZIP_FILE = @TCL_ZIP_FILE@ +TCL_VFS_PATH = libtcl.vfs/tcl_library +TCL_VFS_ROOT = libtcl.vfs + + +TCL_STUB_LIB_FILE = @TCL_STUB_LIB_FILE@ +TCL_DLL_FILE = @TCL_DLL_FILE@ +TCL_LIB_FILE = @TCL_LIB_FILE@ +DDE_DLL_FILE = tcldde$(DDEVER)${DLLSUFFIX} +DDE_LIB_FILE = @LIBPREFIX@tcldde$(DDEVER)${LIBSUFFIX} +REG_DLL_FILE = tclreg$(REGVER)${DLLSUFFIX} +REG_LIB_FILE = @LIBPREFIX@tclreg$(REGVER)${LIBSUFFIX} +TEST_DLL_FILE = tcltest$(VER)${DLLSUFFIX} +TEST_LIB_FILE = @LIBPREFIX@tcltest$(VER)${LIBSUFFIX} +ZLIB_DLL_FILE = zlib1.dll + +SHARED_LIBRARIES = $(TCL_DLL_FILE) @ZLIB_DLL_FILE@ +STATIC_LIBRARIES = $(TCL_LIB_FILE) + +TCLSH = tclsh$(VER)${EXESUFFIX} CAT32 = cat32$(EXEEXT) MAN2TCL = man2tcl$(EXEEXT) -@SET_MAKE@ +# For cross-compiled builds, TCL_EXE is the name of a tclsh executable that is +# available *BEFORE* running make for the first time. Certain build targets +# (make genstubs, make install) need it to be available on the PATH. This +# executable should *NOT* be required just to do a normal build although +# it can be required to run make dist. +TCL_EXE = @TCL_EXE@ -# Setting the VPATH variable to a list of paths will cause the -# makefile to look into these paths when resolving .c to .obj -# dependencies. - -VPATH = $(GENERIC_DIR):$(TTK_DIR):$(WIN_DIR):$(UNIX_DIR):$(XLIB_DIR):$(RC_DIR) - -# warning flags -CFLAGS_WARNING = @CFLAGS_WARNING@ - -# The default switches for optimization or debugging -CFLAGS_DEBUG = @CFLAGS_DEBUG@ -CFLAGS_OPTIMIZE = @CFLAGS_OPTIMIZE@ - -# The default switches for optimization or debugging -LDFLAGS_DEBUG = @LDFLAGS_DEBUG@ -LDFLAGS_OPTIMIZE = @LDFLAGS_OPTIMIZE@ +@SET_MAKE@ -# To change the compiler switches, for example to change from optimization to -# debugging symbols, change the following line: -#CFLAGS = $(CFLAGS_DEBUG) -#CFLAGS = $(CFLAGS_OPTIMIZE) -#CFLAGS = $(CFLAGS_DEBUG) $(CFLAGS_OPTIMIZE) -CFLAGS = @CFLAGS@ @CFLAGS_DEFAULT@ -DUNICODE -D_UNICODE -D_ATL_XP_TARGETING +# Setting the VPATH variable to a list of paths will cause the Makefile to +# look into these paths when resolving .c to .obj dependencies. -# Special compiler flags to use when building man2tcl on Windows. -MAN2TCLFLAGS = @MAN2TCLFLAGS@ +VPATH = $(GENERIC_DIR):$(TOMMATH_DIR):$(WIN_DIR):$(COMPAT_DIR):$(ZLIB_DIR) AR = @AR@ RANLIB = @RANLIB@ CC = @CC@ RC = @RC@ RES = @RES@ -TK_RES = @TK_RES@ -AC_FLAGS = @EXTRA_CFLAGS@ @DEFS@ @TCL_DEFS@ +AC_FLAGS = @EXTRA_CFLAGS@ @DEFS@ CPPFLAGS = @CPPFLAGS@ +LDFLAGS_DEBUG = @LDFLAGS_DEBUG@ +LDFLAGS_OPTIMIZE = @LDFLAGS_OPTIMIZE@ LDFLAGS = @LDFLAGS@ @LDFLAGS_DEFAULT@ LDFLAGS_CONSOLE = @LDFLAGS_CONSOLE@ LDFLAGS_WINDOW = @LDFLAGS_WINDOW@ @@ -193,323 +193,512 @@ SHLIB_LD = @SHLIB_LD@ SHLIB_LD_LIBS = @SHLIB_LD_LIBS@ SHLIB_CFLAGS = @SHLIB_CFLAGS@ SHLIB_SUFFIX = @SHLIB_SUFFIX@ -VER = @TK_MAJOR_VERSION@@TK_MINOR_VERSION@ -DOTVER = @TK_MAJOR_VERSION@.@TK_MINOR_VERSION@ -LIBS = $(TCL_STUB_LIB_FILE) @LIBS@ @LIBS_GUI@ +LIBS = @LIBS@ $(shell $(CYGPATH) '@ZLIB_LIBS@') + RMDIR = rm -rf MKDIR = mkdir -p SHELL = @SHELL@ RM = rm -f COPY = cp -BUILD_TCLSH = @BUILD_TCLSH@ - -# Tk does not used deprecated Tcl constructs so it should -# compile fine with -DTCL_NO_DEPRECATED. To remove its own -# set of deprecated code uncomment the second line. -NO_DEPRECATED_FLAGS = -DTCL_NO_DEPRECATED -#NO_DEPRECATED_FLAGS = -DTCL_NO_DEPRECATED -DTK_NO_DEPRECATED +### +# Tip 430 - ZipFS Modifications +### -# TCL_EXE is the name of a tclsh executable that is available *BEFORE* -# running make for the first time. Certain build targets (make genstubs) -# need it to be available on the PATH. This executable should *NOT* be -# required just to do a normal build although it can be required to run -# make dist. -TCL_EXE = @TCLSH_PROG@ +TCL_ZIP_FILE = @TCL_ZIP_FILE@ +TCL_VFS_PATH = libtcl.vfs/tcl_library +TCL_VFS_ROOT = libtcl.vfs -CC_SWITCHES = ${CFLAGS} ${CFLAGS_WARNING} ${SHLIB_CFLAGS} \ --I"${GENERIC_DIR_NATIVE}" -I"${WIN_DIR_NATIVE}" \ --I"${XLIB_DIR_NATIVE}" -I"${BITMAP_DIR_NATIVE}" \ --I"${TCL_GENERIC_NATIVE}" -I"${TCL_PLATFORM_NATIVE}" \ -${AC_FLAGS} $(NO_DEPRECATED_FLAGS) -DUSE_TCL_STUBS +HOST_CC = @CC_FOR_BUILD@ +HOST_EXEEXT = @EXEEXT_FOR_BUILD@ +HOST_OBJEXT = @OBJEXT_FOR_BUILD@ +ZIPFS_BUILD = @ZIPFS_BUILD@ +NATIVE_ZIP = @ZIP_PROG@ +ZIP_PROG_OPTIONS = @ZIP_PROG_OPTIONS@ +ZIP_PROG_VFSSEARCH = @ZIP_PROG_VFSSEARCH@ +SHARED_BUILD = @SHARED_BUILD@ +INSTALL_MSGS = @INSTALL_MSGS@ +INSTALL_LIBRARIES = @INSTALL_LIBRARIES@ + +# Minizip +MINIZIP_OBJS = \ + adler32.$(HOST_OBJEXT) \ + compress.$(HOST_OBJEXT) \ + crc32.$(HOST_OBJEXT) \ + deflate.$(HOST_OBJEXT) \ + infback.$(HOST_OBJEXT) \ + inffast.$(HOST_OBJEXT) \ + inflate.$(HOST_OBJEXT) \ + inftrees.$(HOST_OBJEXT) \ + ioapi.$(HOST_OBJEXT) \ + iowin32.$(HOST_OBJEXT) \ + trees.$(HOST_OBJEXT) \ + uncompr.$(HOST_OBJEXT) \ + zip.$(HOST_OBJEXT) \ + zutil.$(HOST_OBJEXT) \ + minizip.$(HOST_OBJEXT) + +ZIP_INSTALL_OBJS = @ZIP_INSTALL_OBJS@ + +CC_SWITCHES = ${CFLAGS} ${CFLAGS_WARNING} ${TCL_SHLIB_CFLAGS} \ +-I"${ZLIB_DIR_NATIVE}" -I"${GENERIC_DIR_NATIVE}" \ +-DMP_PREC=4 -I"${TOMMATH_DIR_NATIVE}" -I"${WIN_DIR_NATIVE}" \ +${AC_FLAGS} ${COMPILE_DEBUG_FLAGS} ${NO_DEPRECATED_FLAGS} CC_OBJNAME = @CC_OBJNAME@ CC_EXENAME = @CC_EXENAME@ -# Tk used to let the configure script choose which program to use -# for installing, but there are just too many different versions of -# "install" around; better to use the install-sh script that comes -# with the distribution, which is slower but guaranteed to work. - -INSTALL = cp -INSTALL_PROGRAM = ${INSTALL} -INSTALL_DATA = ${INSTALL} - -WISH_OBJS = \ - winMain.$(OBJEXT) - -TKTEST_OBJS = \ - tkSquare.$(OBJEXT) \ - tkTest.$(OBJEXT) \ - tkOldTest.$(OBJEXT) \ - tkWinTest.$(OBJEXT) - -XLIB_OBJS = \ - xcolors.$(OBJEXT) \ - xdraw.$(OBJEXT) \ - xgc.$(OBJEXT) \ - ximage.$(OBJEXT) \ - xutil.$(OBJEXT) - -TK_OBJS = \ - tkConsole.$(OBJEXT) \ - tkUnixMenubu.$(OBJEXT) \ - tkUnixScale.$(OBJEXT) \ - $(XLIB_OBJS) \ - tkWin3d.$(OBJEXT) \ - tkWin32Dll.$(OBJEXT) \ - tkWinButton.$(OBJEXT) \ - tkWinClipboard.$(OBJEXT) \ - tkWinColor.$(OBJEXT) \ - tkWinConfig.$(OBJEXT) \ - tkWinCursor.$(OBJEXT) \ - tkWinDialog.$(OBJEXT) \ - tkWinDraw.$(OBJEXT) \ - tkWinEmbed.$(OBJEXT) \ - tkWinFont.$(OBJEXT) \ - tkWinImage.$(OBJEXT) \ - tkWinInit.$(OBJEXT) \ - tkWinKey.$(OBJEXT) \ - tkWinMenu.$(OBJEXT) \ - tkWinPixmap.$(OBJEXT) \ - tkWinPointer.$(OBJEXT) \ - tkWinRegion.$(OBJEXT) \ - tkWinScrlbr.$(OBJEXT) \ - tkWinSend.$(OBJEXT) \ - tkWinSendCom.$(OBJEXT) \ - tkWinWindow.$(OBJEXT) \ - tkWinWm.$(OBJEXT) \ - tkWinX.$(OBJEXT) \ - stubs.$(OBJEXT) \ - tk3d.$(OBJEXT) \ - tkArgv.$(OBJEXT) \ - tkAtom.$(OBJEXT) \ - tkBind.$(OBJEXT) \ - tkBitmap.$(OBJEXT) \ - tkBusy.$(OBJEXT) \ - tkButton.$(OBJEXT) \ - tkCanvArc.$(OBJEXT) \ - tkCanvBmap.$(OBJEXT) \ - tkCanvImg.$(OBJEXT) \ - tkCanvLine.$(OBJEXT) \ - tkCanvPoly.$(OBJEXT) \ - tkCanvPs.$(OBJEXT) \ - tkCanvText.$(OBJEXT) \ - tkCanvUtil.$(OBJEXT) \ - tkCanvWind.$(OBJEXT) \ - tkCanvas.$(OBJEXT) \ - tkClipboard.$(OBJEXT) \ - tkCmds.$(OBJEXT) \ - tkColor.$(OBJEXT) \ - tkConfig.$(OBJEXT) \ - tkCursor.$(OBJEXT) \ - tkEntry.$(OBJEXT) \ - tkError.$(OBJEXT) \ - tkEvent.$(OBJEXT) \ - tkFileFilter.$(OBJEXT) \ - tkFocus.$(OBJEXT) \ - tkFont.$(OBJEXT) \ - tkFrame.$(OBJEXT) \ - tkGC.$(OBJEXT) \ - tkGeometry.$(OBJEXT) \ - tkGet.$(OBJEXT) \ - tkGrab.$(OBJEXT) \ - tkGrid.$(OBJEXT) \ - tkImage.$(OBJEXT) \ - tkImgBmap.$(OBJEXT) \ - tkImgGIF.$(OBJEXT) \ - tkImgPNG.$(OBJEXT) \ - tkImgPPM.$(OBJEXT) \ - tkImgPhoto.$(OBJEXT) \ - tkImgPhInstance.$(OBJEXT) \ - tkImgUtil.$(OBJEXT) \ - tkListbox.$(OBJEXT) \ - tkMacWinMenu.$(OBJEXT) \ - tkMain.$(OBJEXT) \ - tkMain2.$(OBJEXT) \ - tkMenu.$(OBJEXT) \ - tkMenubutton.$(OBJEXT) \ - tkMenuDraw.$(OBJEXT) \ - tkMessage.$(OBJEXT) \ - tkPanedWindow.$(OBJEXT) \ - tkObj.$(OBJEXT) \ - tkOldConfig.$(OBJEXT) \ - tkOption.$(OBJEXT) \ - tkPack.$(OBJEXT) \ - tkPlace.$(OBJEXT) \ - tkPointer.$(OBJEXT) \ - tkRectOval.$(OBJEXT) \ - tkScale.$(OBJEXT) \ - tkScrollbar.$(OBJEXT) \ - tkSelect.$(OBJEXT) \ - tkStyle.$(OBJEXT) \ - tkText.$(OBJEXT) \ - tkTextBTree.$(OBJEXT) \ - tkTextDisp.$(OBJEXT) \ - tkTextImage.$(OBJEXT) \ - tkTextIndex.$(OBJEXT) \ - tkTextMark.$(OBJEXT) \ - tkTextTag.$(OBJEXT) \ - tkTextWind.$(OBJEXT) \ - tkTrig.$(OBJEXT) \ - tkUndo.$(OBJEXT) \ - tkUtil.$(OBJEXT) \ - tkVisual.$(OBJEXT) \ - tkStubInit.$(OBJEXT) \ - tkWindow.$(OBJEXT) \ - $(TTK_OBJS) - -TTK_OBJS = \ - ttkWinMonitor.$(OBJEXT) \ - ttkWinTheme.$(OBJEXT) \ - ttkWinXPTheme.$(OBJEXT) \ - ttkBlink.$(OBJEXT) \ - ttkButton.$(OBJEXT) \ - ttkCache.$(OBJEXT) \ - ttkClamTheme.$(OBJEXT) \ - ttkClassicTheme.$(OBJEXT) \ - ttkDefaultTheme.$(OBJEXT) \ - ttkElements.$(OBJEXT) \ - ttkEntry.$(OBJEXT) \ - ttkFrame.$(OBJEXT) \ - ttkImage.$(OBJEXT) \ - ttkInit.$(OBJEXT) \ - ttkLabel.$(OBJEXT) \ - ttkLayout.$(OBJEXT) \ - ttkManager.$(OBJEXT) \ - ttkNotebook.$(OBJEXT) \ - ttkPanedwindow.$(OBJEXT) \ - ttkProgress.$(OBJEXT) \ - ttkScale.$(OBJEXT) \ - ttkScrollbar.$(OBJEXT) \ - ttkScroll.$(OBJEXT) \ - ttkSeparator.$(OBJEXT) \ - ttkSquare.$(OBJEXT) \ - ttkState.$(OBJEXT) \ - ttkTagSet.$(OBJEXT) \ - ttkTheme.$(OBJEXT) \ - ttkTrace.$(OBJEXT) \ - ttkTrack.$(OBJEXT) \ - ttkTreeview.$(OBJEXT) \ - ttkWidget.$(OBJEXT) \ - ttkStubInit.$(OBJEXT) +STUB_CC_SWITCHES = ${CFLAGS} ${CFLAGS_WARNING} ${SHLIB_CFLAGS} \ +-I"${GENERIC_DIR_NATIVE}" -DMP_PREC=4 -I"${TOMMATH_DIR_NATIVE}" \ +-I"${WIN_DIR_NATIVE}" ${AC_FLAGS} \ +${COMPILE_DEBUG_FLAGS} + +TCLTEST_OBJS = \ + tclTest.$(OBJEXT) \ + tclTestObj.$(OBJEXT) \ + tclTestProcBodyObj.$(OBJEXT) \ + tclThreadTest.$(OBJEXT) \ + tclWinTest.$(OBJEXT) + +GENERIC_OBJS = \ + regcomp.$(OBJEXT) \ + regexec.$(OBJEXT) \ + regfree.$(OBJEXT) \ + regerror.$(OBJEXT) \ + tclAlloc.$(OBJEXT) \ + tclAssembly.$(OBJEXT) \ + tclAsync.$(OBJEXT) \ + tclBasic.$(OBJEXT) \ + tclBinary.$(OBJEXT) \ + tclCkalloc.$(OBJEXT) \ + tclClock.$(OBJEXT) \ + tclCmdAH.$(OBJEXT) \ + tclCmdIL.$(OBJEXT) \ + tclCmdMZ.$(OBJEXT) \ + tclCompCmds.$(OBJEXT) \ + tclCompCmdsGR.$(OBJEXT) \ + tclCompCmdsSZ.$(OBJEXT) \ + tclCompExpr.$(OBJEXT) \ + tclCompile.$(OBJEXT) \ + tclConfig.$(OBJEXT) \ + tclDate.$(OBJEXT) \ + tclDictObj.$(OBJEXT) \ + tclDisassemble.$(OBJEXT) \ + tclEncoding.$(OBJEXT) \ + tclEnsemble.$(OBJEXT) \ + tclEnv.$(OBJEXT) \ + tclEvent.$(OBJEXT) \ + tclExecute.$(OBJEXT) \ + tclFCmd.$(OBJEXT) \ + tclFileName.$(OBJEXT) \ + tclGet.$(OBJEXT) \ + tclHash.$(OBJEXT) \ + tclHistory.$(OBJEXT) \ + tclIndexObj.$(OBJEXT) \ + tclInterp.$(OBJEXT) \ + tclIO.$(OBJEXT) \ + tclIOCmd.$(OBJEXT) \ + tclIOGT.$(OBJEXT) \ + tclIORChan.$(OBJEXT) \ + tclIORTrans.$(OBJEXT) \ + tclIOSock.$(OBJEXT) \ + tclIOUtil.$(OBJEXT) \ + tclLink.$(OBJEXT) \ + tclLiteral.$(OBJEXT) \ + tclListObj.$(OBJEXT) \ + tclLoad.$(OBJEXT) \ + tclMain.$(OBJEXT) \ + tclMain2.$(OBJEXT) \ + tclNamesp.$(OBJEXT) \ + tclNotify.$(OBJEXT) \ + tclOO.$(OBJEXT) \ + tclOOBasic.$(OBJEXT) \ + tclOOCall.$(OBJEXT) \ + tclOODefineCmds.$(OBJEXT) \ + tclOOInfo.$(OBJEXT) \ + tclOOMethod.$(OBJEXT) \ + tclOOStubInit.$(OBJEXT) \ + tclObj.$(OBJEXT) \ + tclOptimize.$(OBJEXT) \ + tclPanic.$(OBJEXT) \ + tclParse.$(OBJEXT) \ + tclPathObj.$(OBJEXT) \ + tclPipe.$(OBJEXT) \ + tclPkg.$(OBJEXT) \ + tclPkgConfig.$(OBJEXT) \ + tclPosixStr.$(OBJEXT) \ + tclPreserve.$(OBJEXT) \ + tclProc.$(OBJEXT) \ + tclRegexp.$(OBJEXT) \ + tclResolve.$(OBJEXT) \ + tclResult.$(OBJEXT) \ + tclScan.$(OBJEXT) \ + tclStringObj.$(OBJEXT) \ + tclStrToD.$(OBJEXT) \ + tclStubInit.$(OBJEXT) \ + tclThread.$(OBJEXT) \ + tclThreadAlloc.$(OBJEXT) \ + tclThreadJoin.$(OBJEXT) \ + tclThreadStorage.$(OBJEXT) \ + tclTimer.$(OBJEXT) \ + tclTomMathInterface.$(OBJEXT) \ + tclTrace.$(OBJEXT) \ + tclUtf.$(OBJEXT) \ + tclUtil.$(OBJEXT) \ + tclVar.$(OBJEXT) \ + tclZipfs.$(OBJEXT) \ + tclZlib.$(OBJEXT) + +TOMMATH_OBJS = \ + bncore.${OBJEXT} \ + bn_reverse.${OBJEXT} \ + bn_fast_s_mp_mul_digs.${OBJEXT} \ + bn_fast_s_mp_sqr.${OBJEXT} \ + bn_mp_add.${OBJEXT} \ + bn_mp_add_d.${OBJEXT} \ + bn_mp_and.${OBJEXT} \ + bn_mp_clamp.${OBJEXT} \ + bn_mp_clear.${OBJEXT} \ + bn_mp_clear_multi.${OBJEXT} \ + bn_mp_cmp.${OBJEXT} \ + bn_mp_cmp_d.${OBJEXT} \ + bn_mp_cmp_mag.${OBJEXT} \ + bn_mp_cnt_lsb.${OBJEXT} \ + bn_mp_copy.${OBJEXT} \ + bn_mp_count_bits.${OBJEXT} \ + bn_mp_div.${OBJEXT} \ + bn_mp_div_d.${OBJEXT} \ + bn_mp_div_2.${OBJEXT} \ + bn_mp_div_2d.${OBJEXT} \ + bn_mp_div_3.${OBJEXT} \ + bn_mp_exch.${OBJEXT} \ + bn_mp_expt_d.${OBJEXT} \ + bn_mp_expt_d_ex.${OBJEXT} \ + bn_mp_get_int.${OBJEXT} \ + bn_mp_get_long.${OBJEXT} \ + bn_mp_get_long_long.${OBJEXT} \ + bn_mp_grow.${OBJEXT} \ + bn_mp_init.${OBJEXT} \ + bn_mp_init_copy.${OBJEXT} \ + bn_mp_init_multi.${OBJEXT} \ + bn_mp_init_set.${OBJEXT} \ + bn_mp_init_set_int.${OBJEXT} \ + bn_mp_init_size.${OBJEXT} \ + bn_mp_karatsuba_mul.${OBJEXT} \ + bn_mp_karatsuba_sqr.$(OBJEXT) \ + bn_mp_lshd.${OBJEXT} \ + bn_mp_mod.${OBJEXT} \ + bn_mp_mod_2d.${OBJEXT} \ + bn_mp_mul.${OBJEXT} \ + bn_mp_mul_2.${OBJEXT} \ + bn_mp_mul_2d.${OBJEXT} \ + bn_mp_mul_d.${OBJEXT} \ + bn_mp_neg.${OBJEXT} \ + bn_mp_or.${OBJEXT} \ + bn_mp_radix_size.${OBJEXT} \ + bn_mp_radix_smap.${OBJEXT} \ + bn_mp_read_radix.${OBJEXT} \ + bn_mp_rshd.${OBJEXT} \ + bn_mp_set.${OBJEXT} \ + bn_mp_set_int.${OBJEXT} \ + bn_mp_set_long.${OBJEXT} \ + bn_mp_set_long_long.${OBJEXT} \ + bn_mp_shrink.${OBJEXT} \ + bn_mp_sqr.${OBJEXT} \ + bn_mp_sqrt.${OBJEXT} \ + bn_mp_sub.${OBJEXT} \ + bn_mp_sub_d.${OBJEXT} \ + bn_mp_to_unsigned_bin.${OBJEXT} \ + bn_mp_to_unsigned_bin_n.${OBJEXT} \ + bn_mp_toom_mul.${OBJEXT} \ + bn_mp_toom_sqr.${OBJEXT} \ + bn_mp_toradix_n.${OBJEXT} \ + bn_mp_unsigned_bin_size.${OBJEXT} \ + bn_mp_xor.${OBJEXT} \ + bn_mp_zero.${OBJEXT} \ + bn_s_mp_add.${OBJEXT} \ + bn_s_mp_mul_digs.${OBJEXT} \ + bn_s_mp_sqr.${OBJEXT} \ + bn_s_mp_sub.${OBJEXT} + + +WIN_OBJS = \ + tclWin32Dll.$(OBJEXT) \ + tclWinChan.$(OBJEXT) \ + tclWinConsole.$(OBJEXT) \ + tclWinSerial.$(OBJEXT) \ + tclWinError.$(OBJEXT) \ + tclWinFCmd.$(OBJEXT) \ + tclWinFile.$(OBJEXT) \ + tclWinInit.$(OBJEXT) \ + tclWinLoad.$(OBJEXT) \ + tclWinNotify.$(OBJEXT) \ + tclWinPipe.$(OBJEXT) \ + tclWinSock.$(OBJEXT) \ + tclWinThrd.$(OBJEXT) \ + tclWinTime.$(OBJEXT) + +DDE_OBJS = tclWinDde.$(OBJEXT) + +REG_OBJS = tclWinReg.$(OBJEXT) STUB_OBJS = \ - tkStubLib.$(OBJEXT) \ - ttkStubLib.$(OBJEXT) + tclStubLib.$(OBJEXT) \ + tclTomMathStubLib.$(OBJEXT) \ + tclOOStubLib.$(OBJEXT) -TCL_DOCS = "$(TCL_SRC_DIR_NATIVE)/doc/*.[13n]" -TK_DOCS = "$(ROOT_DIR_NATIVE)/doc/*.[13n]" -CORE_DOCS = $(TCL_DOCS) $(TK_DOCS) +TCLSH_OBJS = tclAppInit.$(OBJEXT) -DEMOPROGS = browse hello ixset rmt rolodex square tcolor timer widget +ZLIB_OBJS = \ + adler32.$(OBJEXT) \ + compress.$(OBJEXT) \ + crc32.$(OBJEXT) \ + deflate.$(OBJEXT) \ + infback.$(OBJEXT) \ + inffast.$(OBJEXT) \ + inflate.$(OBJEXT) \ + inftrees.$(OBJEXT) \ + trees.$(OBJEXT) \ + uncompr.$(OBJEXT) \ + zutil.$(OBJEXT) -SHELL_ENV = \ - @TCL_LIBRARY="$(TCL_SRC_DIR_NATIVE)/library"; export TCL_LIBRARY; \ - TK_LIBRARY="$(ROOT_DIR_NATIVE)/library"; export TK_LIBRARY; \ - PATH="$(TCL_BIN_DIR):$(PATH)"; export PATH; +TCL_OBJS = ${GENERIC_OBJS} $(TOMMATH_OBJS) ${WIN_OBJS} @ZLIB_OBJS@ -### -# Tip 430 - ZipFS Modifications -### -TK_ZIP_FILE = libtk_${MAJOR_VERSION}_${MINOR_VERSION}_${PATCH_LEVEL}.zip -TK_VFS_PATH = libtk.vfs/tk_library -TK_VFS_ROOT = libtk.vfs -TCL_ZIPFS_SUPPORT = @TCL_ZIPFS_SUPPORT@ -TCL_ZIPFS_FLAG = @TCL_ZIPFS_FLAG@ -TCL_ZIPFS_OBJS = -ZIP_PROG = @ZIP_PROG@ -ZIP_PROG_OPTIONS = @ZIP_PROG_OPTIONS@ -ZIP_PROG_VFSSEARCH = @ZIP_PROG_VFSSEARCH@ -SHARED_BUILD = @SHARED_BUILD@ +TCL_DOCS = "$(ROOT_DIR_NATIVE)"/doc/*.[13n] -ifeq (${TCL_ZIPFS_SUPPORT},1) - TCL_ZIPFS_OBJS=${TK_ZIP_FILE} -endif -ifeq (${TCL_ZIPFS_SUPPORT},2) - TCL_ZIPFS_OBJS=${TK_ZIP_FILE} -endif +all: binaries libraries doc packages -# Main targets. The default target -- all -- builds the binaries, -# performs any post processing on libraries or documents. +tcltest: $(TCLSH) $(TEST_DLL_FILE) -all: binaries libraries doc +binaries: $(TCL_STUB_LIB_FILE) @LIBRARIES@ winextensions $(TCLSH) -binaries: @LIBRARIES@ $(WISH) +winextensions: ${DDE_DLL_FILE} ${REG_DLL_FILE} libraries: -$(ROOT_DIR)/doc/man.macros: - $(INSTALL_DATA) "$(TCL_SRC_DIR)/doc/man.macros" "$(ROOT_DIR)/doc/man.macros" +doc: + +tclzipfile: ${TCL_ZIP_FILE} -doc: $(ROOT_DIR)/doc/man.macros +${TCL_ZIP_FILE}: ${ZIP_INSTALL_OBJS} + rm -rf ${TCL_VFS_ROOT} + mkdir -p ${TCL_VFS_PATH} + $(COPY) -a $(TOP_DIR)/library/* ${TCL_VFS_PATH} + cd ${TCL_VFS_ROOT} ; ${NATIVE_ZIP} ${ZIP_PROG_OPTIONS} ../${TCL_ZIP_FILE} ${ZIP_PROG_VFSSEARCH} -${TK_ZIP_FILE}: - $(RMDIR) ${TK_VFS_ROOT} - $(MKDIR) ${TK_VFS_PATH} - $(COPY) -a $(TOP_DIR)/library/* ${TK_VFS_PATH} - cd ${TK_VFS_ROOT} ; ${ZIP_PROG} ${ZIP_PROG_OPTIONS} ../${TK_ZIP_FILE} ${ZIP_PROG_VFSSEARCH} +$(TCLSH): $(TCLSH_OBJS) @LIBRARIES@ $(TCL_STUB_LIB_FILE) tclsh.$(RES) + $(CC) $(CFLAGS) $(TCLSH_OBJS) $(TCL_LIB_FILE) $(TCL_STUB_LIB_FILE) $(LIBS) \ + tclsh.$(RES) $(CC_EXENAME) $(LDFLAGS_CONSOLE) + @VC_MANIFEST_EMBED_EXE@ +cat32.$(OBJEXT): cat.c + $(CC) -c $(CC_SWITCHES) @DEPARG@ $(CC_OBJNAME) -winhelp: $(TCL_SRC_DIR)/tools/man2help.tcl $(MAN2TCL) - $(TCL_EXE) "$(TCL_SRC_DIR_NATIVE)/tools/man2help.tcl" tcl "$(VER)" $(CORE_DOCS) - $(COPY) "$(TCL_BIN_DIR)/tcl.hpj" ./ - hcw /c /e tcl.hpj - $(COPY) ./tcl$(VER).cnt ./TCL$(VER).HLP "$(TCL_SRC_DIR_NATIVE)/tools/" +$(CAT32): cat32.$(OBJEXT) + $(CC) $(CFLAGS) cat32.$(OBJEXT) $(CC_EXENAME) $(LIBS) $(LDFLAGS_CONSOLE) -$(MAN2TCL): $(TCL_SRC_DIR)/tools/man2tcl.c - $(CC) $(CFLAGS_OPTIMIZE) $(MAN2TCLFLAGS) -o $(MAN2TCL) "$(TCL_SRC_DIR_NATIVE)/tools/man2tcl.c" +# The following targets are configured by autoconf to generate either a shared +# library or static library -# Specifying TESTFLAGS on the command line is the standard way to pass -# args to tcltest, ie: -# % make test TESTFLAGS="-verbose bps -file fileName.test" +${TCL_STUB_LIB_FILE}: ${STUB_OBJS} + @$(RM) ${TCL_STUB_LIB_FILE} + @MAKE_STUB_LIB@ ${STUB_OBJS} + @POST_MAKE_LIB@ -test: test-classic test-ttk +${TCL_DLL_FILE}: ${TCL_OBJS} tcl.$(RES) @ZLIB_DLL_FILE@ ${TCL_ZIP_FILE} + @$(RM) ${TCL_DLL_FILE} $(TCL_LIB_FILE) + @MAKE_DLL@ ${TCL_OBJS} tcl.$(RES) $(SHLIB_LD_LIBS) + @VC_MANIFEST_EMBED_DLL@ +ifeq (${ZIPFS_BUILD},1) + cat ${TCL_ZIP_FILE} >> ${TCL_DLL_FILE} +endif -test-classic: binaries $(TKTEST) $(TEST_DLL_FILE) $(CAT32) - $(SHELL_ENV) ./$(TKTEST) "$(ROOT_DIR_NATIVE)/tests/all.tcl" \ - $(TESTFLAGS) | ./$(CAT32) +${TCL_LIB_FILE}: ${TCL_OBJS} ${DDE_OBJS} ${REG_OBJS} + @$(RM) ${TCL_LIB_FILE} + @MAKE_LIB@ ${TCL_OBJS} ${DDE_OBJS} ${REG_OBJS} + @POST_MAKE_LIB@ -test-ttk: binaries $(TKTEST) $(TEST_DLL_FILE) $(CAT32) - $(SHELL_ENV) ./$(TKTEST) "$(ROOT_DIR_NATIVE)/tests/ttk/all.tcl" \ - $(TESTFLAGS) | ./$(CAT32) +${DDE_DLL_FILE}: ${TCL_STUB_LIB_FILE} ${DDE_OBJS} + @MAKE_DLL@ ${DDE_OBJS} $(TCL_STUB_LIB_FILE) $(SHLIB_LD_LIBS) -runtest: binaries $(TKTEST) $(TEST_DLL_FILE) - $(SHELL_ENV) ./$(TKTEST) $(TESTFLAGS) $(SCRIPT) +${REG_DLL_FILE}: ${TCL_STUB_LIB_FILE} ${REG_OBJS} + @MAKE_DLL@ ${REG_OBJS} $(TCL_STUB_LIB_FILE) $(SHLIB_LD_LIBS) -# This target can be used to run wish from the build directory -# via `make shell` or `make shell SCRIPT=foo.tcl` -shell: binaries - $(SHELL_ENV) ./$(WISH) $(SCRIPT) +${TEST_DLL_FILE}: ${TCL_STUB_LIB_FILE} ${TCLTEST_OBJS} + @$(RM) ${TEST_DLL_FILE} ${TEST_LIB_FILE} + @MAKE_DLL@ ${TCLTEST_OBJS} $(TCL_STUB_LIB_FILE) $(SHLIB_LD_LIBS) -demo: $(WISH) - $(SHELL_ENV) ./$(WISH) $(ROOT_DIR)/library/demos/widget +# use pre-built zlib1.dll +${ZLIB_DLL_FILE}: ${TCL_STUB_LIB_FILE} + @if test "@ZLIB_LIBS@set" != "${ZLIB_DIR_NATIVE}/win32/zdll.libset" ; then \ + $(COPY) $(ZLIB_DIR)/win64/${ZLIB_DLL_FILE} ${ZLIB_DLL_FILE}; \ + else \ + $(COPY) $(ZLIB_DIR)/win32/${ZLIB_DLL_FILE} ${ZLIB_DLL_FILE}; \ + fi; -# This target can be used to run wish inside either gdb or insight -gdb: binaries - @echo "set env TCL_LIBRARY=$(TCL_SRC_DIR_NATIVE)/library" > gdb.run - @echo "set env TK_LIBRARY=$(ROOT_DIR_NATIVE)/library" >> gdb.run - PATH="$(TCL_BIN_DIR):$(PATH)"; export PATH; \ - gdb ./$(WISH) --command=gdb.run - @$(RM) gdb.run - - -# Tip 430 - When we bump Tk, offer up only zipfile bundled Tk -# For now, 8.6 needs to be able to load Tk, and it doesn't -# have zipfs facilities -#INSTALL_LIBRARIES = @INSTALL_LIBRARIES@ -INSTALL_LIBRARIES = install-libraries -INSTALL_BASE_TARGETS = install-binaries $(INSTALL_LIBRARIES) +# Add the object extension to the implicit rules. By default .obj is not +# automatically added. + +.SUFFIXES: .${OBJEXT} +.SUFFIXES: .$(RES) +.SUFFIXES: .rc + +# Special case object targets + +tclWinInit.${OBJEXT}: tclWinInit.c + $(CC) -c $(CC_SWITCHES) -DBUILD_tcl $(EXTFLAGS) @DEPARG@ $(CC_OBJNAME) + +tclWinPipe.${OBJEXT}: tclWinPipe.c + $(CC) -c $(CC_SWITCHES) -DBUILD_tcl $(EXTFLAGS) @DEPARG@ $(CC_OBJNAME) + +testMain.${OBJEXT}: tclAppInit.c + $(CC) -c $(CC_SWITCHES) -DTCL_TEST @DEPARG@ $(CC_OBJNAME) + +tclMain2.${OBJEXT}: tclMain.c + $(CC) -c $(CC_SWITCHES) -DBUILD_tcl -DTCL_ASCII_MAIN @DEPARG@ $(CC_OBJNAME) + +# TIP #430, ZipFS Support +tclZipfs.${OBJEXT}: $(GENERIC_DIR)/tclZipfs.c + $(CC) -c $(CC_SWITCHES) -DBUILD_tcl \ + -DCFG_RUNTIME_PATH=\"$(bindir_native)\" \ + -DCFG_RUNTIME_DLLFILE="\"$(TCL_DLL_FILE)\"" \ + -DCFG_RUNTIME_ZIPFILE="\"$(TCL_ZIP_FILE)\"" \ + -DCFG_RUNTIME_LIBDIR="\"$(bindir_native)\"" \ + -DCFG_RUNTIME_SCRDIR="\"$(TCL_LIBRARY_NATIVE)\"" \ + $(ZLIB_INCLUDE) -I$(ZLIB_DIR)/contrib/minizip @DEPARG@ $(CC_OBJNAME) + + +# TIP #59, embedding of configuration information into the binary library. +# +# Part of Tcl's configuration information are the paths where it was installed +# and where it will look for its libraries (which can be different). We derive +# this information from the variables which can be overridden by the user. As +# every path can be configured separately we do not remember one general +# prefix/exec_prefix but all the different paths individually. + +tclPkgConfig.${OBJEXT}: tclPkgConfig.c + $(CC) -c $(CC_SWITCHES) \ + -DCFG_INSTALL_LIBDIR=\"$(LIB_INSTALL_DIR_NATIVE)\" \ + -DCFG_INSTALL_BINDIR=\"$(BIN_INSTALL_DIR_NATIVE)\" \ + -DCFG_INSTALL_SCRDIR=\"$(SCRIPT_INSTALL_DIR_NATIVE)\" \ + -DCFG_INSTALL_INCDIR=\"$(INCLUDE_INSTALL_DIR_NATIVE)\" \ + -DCFG_INSTALL_DOCDIR=\"$(MAN_INSTALL_DIR)\" \ + \ + -DCFG_RUNTIME_LIBDIR=\"$(libdir_native)\" \ + -DCFG_RUNTIME_BINDIR=\"$(bindir_native)\" \ + -DCFG_RUNTIME_SCRDIR=\"$(TCL_LIBRARY_NATIVE)\" \ + -DCFG_RUNTIME_INCDIR=\"$(includedir_native)\" \ + -DCFG_RUNTIME_DOCDIR=\"$(mandir_native)\" \ + -DCFG_RUNTIME_DLLFILE="\"$(TCL_DLL_FILE)\"" \ + -DCFG_RUNTIME_ZIPFILE="\"$(TCL_ZIP_FILE)\"" \ + -DBUILD_tcl \ + @DEPARG@ $(CC_OBJNAME) + +# The following objects are part of the stub library and should not be built +# as DLL objects but none of the symbols should be exported + +tclStubLib.${OBJEXT}: tclStubLib.c + $(CC) -c $(CC_SWITCHES) -DSTATIC_BUILD @DEPARG@ $(CC_OBJNAME) + +tclTomMathStubLib.${OBJEXT}: tclTomMathStubLib.c + $(CC) -c $(CC_SWITCHES) -DSTATIC_BUILD @DEPARG@ $(CC_OBJNAME) + +tclOOStubLib.${OBJEXT}: tclOOStubLib.c + $(CC) -c $(CC_SWITCHES) -DSTATIC_BUILD @DEPARG@ $(CC_OBJNAME) + +# Implicit rule for all object files that will end up in the Tcl library + +%.${OBJEXT}: %.c + $(CC) -c $(CC_SWITCHES) -DBUILD_tcl @DEPARG@ $(CC_OBJNAME) + +.rc.$(RES): + $(RC) @RC_OUT@ $@ @RC_TYPE@ @RC_DEFINES@ @RC_INCLUDE@ "$(GENERIC_DIR_NATIVE)" @RC_INCLUDE@ "$(WIN_DIR_NATIVE)" @DEPARG@ + + + +#-------------------------------------------------------------------------- +# Minizip implementation +#-------------------------------------------------------------------------- +adler32.$(HOST_OBJEXT): + $(HOST_CC) -o $@ -I$(ZLIB_DIR) -c $(ZLIB_DIR)/adler32.c + +compress.$(HOST_OBJEXT): + $(HOST_CC) -o $@ -I$(ZLIB_DIR) -c $(ZLIB_DIR)/compress.c + +crc32.$(HOST_OBJEXT): + $(HOST_CC) -o $@ -I$(ZLIB_DIR) -c $(ZLIB_DIR)/crc32.c + +deflate.$(HOST_OBJEXT): + $(HOST_CC) -o $@ -I$(ZLIB_DIR) -c $(ZLIB_DIR)/deflate.c + +ioapi.$(HOST_OBJEXT): + $(HOST_CC) -o $@ -I$(ZLIB_DIR) -I$(ZLIB_DIR)/contrib/minizip -c $(ZLIB_DIR)/contrib/minizip/ioapi.c + +iowin32.$(HOST_OBJEXT): + $(HOST_CC) -o $@ -I$(ZLIB_DIR) -I$(ZLIB_DIR)/contrib/minizip -c $(ZLIB_DIR)/contrib/minizip/iowin32.c + +infback.$(HOST_OBJEXT): + $(HOST_CC) -o $@ -I$(ZLIB_DIR) -c $(ZLIB_DIR)/infback.c + +inffast.$(HOST_OBJEXT): + $(HOST_CC) -o $@ -I$(ZLIB_DIR) -c $(ZLIB_DIR)/inffast.c + +inflate.$(HOST_OBJEXT): + $(HOST_CC) -o $@ -I$(ZLIB_DIR) -c $(ZLIB_DIR)/inflate.c + +inftrees.$(HOST_OBJEXT): + $(HOST_CC) -o $@ -I$(ZLIB_DIR) -c $(ZLIB_DIR)/inftrees.c + +trees.$(HOST_OBJEXT): + $(HOST_CC) -o $@ -I$(ZLIB_DIR) -c $(ZLIB_DIR)/trees.c + +uncompr.$(HOST_OBJEXT): + $(HOST_CC) -o $@ -I$(ZLIB_DIR) -c $(ZLIB_DIR)/uncompr.c + +zip.$(HOST_OBJEXT): + $(HOST_CC) -o $@ -I$(ZLIB_DIR) -I$(ZLIB_DIR)/contrib/minizip -c $(ZLIB_DIR)/contrib/minizip/zip.c + +zutil.$(HOST_OBJEXT): + $(HOST_CC) -o $@ -I$(ZLIB_DIR) -c $(ZLIB_DIR)/zutil.c + +minizip.$(HOST_OBJEXT): + $(HOST_CC) -o $@ -I$(ZLIB_DIR) -I$(ZLIB_DIR)/contrib/minizip -c $(ZLIB_DIR)/contrib/minizip/minizip.c + +minizip${HOST_EXEEXT}: $(MINIZIP_OBJS) + $(HOST_CC) -o $@ $(MINIZIP_OBJS) + +# The following target generates the file generic/tclDate.c from the yacc +# grammar found in generic/tclGetDate.y. This is only run by hand as yacc is +# not available in all environments. The name of the .c file is different than +# the name of the .y file so that make doesn't try to automatically regenerate +# the .c file. + +gendate: + bison --output-file=$(GENERIC_DIR)/tclDate.c \ + --name-prefix=TclDate \ + --no-lines \ + $(GENERIC_DIR)/tclGetDate.y + +# The following target generates the file generic/tclTomMath.h. It needs to be +# run (and the results checked) after updating to a new release of libtommath. + +gentommath_h: + $(TCL_EXE) "$(ROOT_DIR_NATIVE)/tools/fix_tommath_h.tcl" \ + "$(TOMMATH_DIR_NATIVE)/tommath.h" \ + > "$(GENERIC_DIR_NATIVE)/tclTomMath.h" + +INSTALL_BASE_TARGETS = install-binaries $(INSTALL_LIBRARIES) $(INSTALL_MSGS) $(INSTALL_TZDATA) INSTALL_DOC_TARGETS = install-doc +INSTALL_PACKAGE_TARGETS = install-packages INSTALL_DEV_TARGETS = install-headers -INSTALL_DEMO_TARGETS = install-demos -INSTALL_TARGETS = $(INSTALL_BASE_TARGETS) $(INSTALL_DOC_TARGETS) \ - $(INSTALL_DEMO_TARGETS) +INSTALL_EXTRA_TARGETS = +INSTALL_TARGETS = $(INSTALL_BASE_TARGETS) $(INSTALL_DOC_TARGETS) $(INSTALL_DEV_TARGETS) \ + $(INSTALL_PACKAGE_TARGETS) $(INSTALL_EXTRA_TARGETS) install: $(INSTALL_TARGETS) install-binaries: binaries - @for i in $(LIB_INSTALL_DIR) $(BIN_INSTALL_DIR) $(PKG_INSTALL_DIR); \ + @for i in "$(LIB_INSTALL_DIR)" "$(BIN_INSTALL_DIR)" ; \ do \ if [ ! -d $$i ] ; then \ echo "Making directory $$i"; \ @@ -518,140 +707,133 @@ install-binaries: binaries else true; \ fi; \ done; - @for i in $(TK_DLL_FILE) $(WISH); \ + @for i in dde${DDEDOTVER} reg${REGDOTVER}; \ + do \ + if [ ! -d $(LIB_INSTALL_DIR)/$$i ] ; then \ + echo "Making directory $(LIB_INSTALL_DIR)/$$i"; \ + $(MKDIR) $(LIB_INSTALL_DIR)/$$i; \ + else true; \ + fi; \ + done; + @for i in $(TCL_DLL_FILE) $(ZLIB_DLL_FILE) $(TCLSH); \ do \ if [ -f $$i ]; then \ echo "Installing $$i to $(BIN_INSTALL_DIR)/"; \ $(COPY) $$i "$(BIN_INSTALL_DIR)"; \ fi; \ done - @echo "Creating package index $(PKG_INDEX)"; - @$(RM) $(PKG_INDEX); - @(\ - echo "if {[catch {package present Tcl 8.6.0}]} return";\ - echo "if {(\$$::tcl_platform(platform) eq \"unix\") && ([info exists ::env(DISPLAY)]";\ - echo " || ([info exists ::argv] && (\"-display\" in \$$::argv)))} {";\ - echo " package ifneeded Tk $(VERSION)$(PATCH_LEVEL) [list load [file normalize [file join \$$dir .. .. bin libtk$(VERSION).dll]] Tk]";\ - echo "} else {";\ - echo " package ifneeded Tk $(VERSION)$(PATCH_LEVEL) [list load [file normalize [file join \$$dir .. .. bin $(TK_DLL_FILE)]] Tk]";\ - echo "}";\ - ) > $(PKG_INDEX); - @for i in tkConfig.sh $(TK_LIB_FILE) $(TK_STUB_LIB_FILE); \ + @for i in tclConfig.sh tclooConfig.sh $(TCL_LIB_FILE) $(TCL_STUB_LIB_FILE); \ do \ if [ -f $$i ]; then \ echo "Installing $$i to $(LIB_INSTALL_DIR)/"; \ $(COPY) $$i "$(LIB_INSTALL_DIR)"; \ fi; \ done + @if [ -f $(DDE_DLL_FILE) ]; then \ + echo Installing $(DDE_DLL_FILE); \ + $(COPY) $(DDE_DLL_FILE) $(LIB_INSTALL_DIR)/dde${DDEDOTVER}; \ + $(COPY) $(ROOT_DIR)/library/dde/pkgIndex.tcl \ + $(LIB_INSTALL_DIR)/dde${DDEDOTVER}; \ + fi + @if [ -f $(DDE_LIB_FILE) ]; then \ + echo Installing $(DDE_LIB_FILE); \ + $(COPY) $(DDE_LIB_FILE) $(LIB_INSTALL_DIR)/dde${DDEDOTVER}; \ + fi + @if [ -f $(REG_DLL_FILE) ]; then \ + echo Installing $(REG_DLL_FILE); \ + $(COPY) $(REG_DLL_FILE) $(LIB_INSTALL_DIR)/reg${REGDOTVER}; \ + $(COPY) $(ROOT_DIR)/library/reg/pkgIndex.tcl \ + $(LIB_INSTALL_DIR)/reg${REGDOTVER}; \ + fi + @if [ -f $(REG_LIB_FILE) ]; then \ + echo Installing $(REG_LIB_FILE); \ + $(COPY) $(REG_LIB_FILE) $(LIB_INSTALL_DIR)/reg${REGDOTVER}; \ + fi install-libraries-zipfs-shared: libraries - @for i in "$(SCRIPT_INSTALL_DIR)"; \ - do \ - if [ ! -d "$$i" ] ; then \ - echo "Making directory $$i"; \ - $(INSTALL_DATA_DIR) "$$i"; \ - else true; \ - fi; \ - done; - @echo "Installing library files to $(SCRIPT_INSTALL_DIR)/"; - @for i in \ - $(WIN_DIR)/tkAppInit.c; \ - do \ - $(INSTALL_DATA) $$i "$(SCRIPT_INSTALL_DIR)"; \ - done; install-libraries-zipfs-static: install-libraries-zipfs-shared - $(INSTALL_DATA) ${TCL_ZIP_FILE} "$(LIB_INSTALL_DIR)" ;\ + $(INSTALL_DATA) ${TCL_ZIP_FILE} "$(LIB_INSTALL_DIR)" -install-libraries: libraries - @for i in $(INSTALL_ROOT)$(prefix)/lib \ - $(INCLUDE_INSTALL_DIR) $(INCLUDE_INSTALL_DIR)/X11 \ - $(SCRIPT_INSTALL_DIR) $(SCRIPT_INSTALL_DIR)/images \ - $(SCRIPT_INSTALL_DIR)/msgs $(SCRIPT_INSTALL_DIR)/ttk; \ +install-libraries: libraries install-tzdata install-msgs + @for i in "$$($(CYGPATH) $(prefix)/lib)" "$(INCLUDE_INSTALL_DIR)" \ + $(SCRIPT_INSTALL_DIR); \ do \ if [ ! -d $$i ] ; then \ echo "Making directory $$i"; \ $(MKDIR) $$i; \ - chmod 755 $$i; \ else true; \ fi; \ done; - @echo "Installing header files to $(INCLUDE_INSTALL_DIR)/"; - @for i in $(GENERIC_DIR)/tk.h $(GENERIC_DIR)/tkPlatDecls.h \ - $(GENERIC_DIR)/tkIntXlibDecls.h $(GENERIC_DIR)/tkDecls.h ; \ - do \ - $(INSTALL_DATA) $$i $(INCLUDE_INSTALL_DIR); \ - done; - @for i in $(XLIB_DIR)/X11/*.h; \ + @for i in http1.0 opt0.4 encoding ../tcl8 ../tcl8/8.4 ../tcl8/8.4/platform ../tcl8/8.5 ../tcl8/8.6; \ do \ - $(INSTALL_DATA) $$i $(INCLUDE_INSTALL_DIR)/X11; \ + if [ ! -d $(SCRIPT_INSTALL_DIR)/$$i ] ; then \ + echo "Making directory $(SCRIPT_INSTALL_DIR)/$$i"; \ + $(MKDIR) $(SCRIPT_INSTALL_DIR)/$$i; \ + else true; \ + fi; \ done; @echo "Installing library files to $(SCRIPT_INSTALL_DIR)"; - @for i in $(ROOT_DIR)/library/*.tcl $(ROOT_DIR)/library/tclIndex \ - $(UNIX_DIR)/tkAppInit.c; \ + @for i in $(ROOT_DIR)/library/*.tcl $(ROOT_DIR)/library/tclIndex; \ do \ - $(INSTALL_DATA) $$i $(SCRIPT_INSTALL_DIR); \ + $(COPY) "$$i" "$(SCRIPT_INSTALL_DIR)"; \ done; - @echo "Installing library ttk directory"; - @for i in $(ROOT_DIR)/library/ttk/*.tcl; \ + @echo "Installing library http1.0 directory"; + @for j in $(ROOT_DIR)/library/http1.0/*.tcl; \ do \ - if [ -f $$i ] ; then \ - $(INSTALL_DATA) $$i $(SCRIPT_INSTALL_DIR)/ttk; \ - fi; \ + $(COPY) "$$j" "$(SCRIPT_INSTALL_DIR)/http1.0"; \ done; - @echo "Installing library images directory"; - @for i in $(ROOT_DIR)/library/images/*; \ + @echo "Installing package http 2.8.12 as a Tcl Module"; + @$(COPY) $(ROOT_DIR)/library/http/http.tcl $(SCRIPT_INSTALL_DIR)/../tcl8/8.6/http-2.8.12.tm; + @echo "Installing library opt0.4 directory"; + @for j in $(ROOT_DIR)/library/opt/*.tcl; \ do \ - if [ -f $$i ] ; then \ - $(INSTALL_DATA) $$i $(SCRIPT_INSTALL_DIR)/images; \ - fi; \ - done; - @echo "Installing translation directory"; - @for i in $(ROOT_DIR)/library/msgs/*.msg; \ - do \ - if [ -f $$i ] ; then \ - $(INSTALL_DATA) $$i $(SCRIPT_INSTALL_DIR)/msgs; \ - fi; \ + $(COPY) "$$j" "$(SCRIPT_INSTALL_DIR)/opt0.4"; \ done; + @echo "Installing package msgcat 1.6.1 as a Tcl Module"; + @$(COPY) $(ROOT_DIR)/library/msgcat/msgcat.tcl $(SCRIPT_INSTALL_DIR)/../tcl8/8.5/msgcat-1.6.1.tm; + @echo "Installing package tcltest 2.4.0 as a Tcl Module"; + @$(COPY) $(ROOT_DIR)/library/tcltest/tcltest.tcl $(SCRIPT_INSTALL_DIR)/../tcl8/8.5/tcltest-2.4.0.tm; + @echo "Installing package platform 1.0.14 as a Tcl Module"; + @$(COPY) $(ROOT_DIR)/library/platform/platform.tcl $(SCRIPT_INSTALL_DIR)/../tcl8/8.4/platform-1.0.14.tm; + @echo "Installing package platform::shell 1.1.4 as a Tcl Module"; + @$(COPY) $(ROOT_DIR)/library/platform/shell.tcl $(SCRIPT_INSTALL_DIR)/../tcl8/8.4/platform/shell-1.1.4.tm; + @echo "Installing encodings"; + @for i in $(ROOT_DIR)/library/encoding/*.enc ; do \ + $(COPY) "$$i" "$(SCRIPT_INSTALL_DIR)/encoding"; \ + done; + +install-tzdata: + @echo "Installing time zone data" + @$(TCL_EXE) "$(ROOT_DIR)/tools/installData.tcl" \ + "$(ROOT_DIR)/library/tzdata" "$(SCRIPT_INSTALL_DIR)/tzdata" + +install-msgs: + @echo "Installing message catalogs" + @$(TCL_EXE) "$(ROOT_DIR)/tools/installData.tcl" \ + "$(ROOT_DIR)/library/msgs" "$(SCRIPT_INSTALL_DIR)/msgs" -install-demos: - @for i in $(INSTALL_ROOT)$(prefix)/lib $(SCRIPT_INSTALL_DIR) \ - $(SCRIPT_INSTALL_DIR)/demos \ - $(SCRIPT_INSTALL_DIR)/demos/images ; \ +install-doc: doc + +install-headers: + @for i in "$(INCLUDE_INSTALL_DIR)"; \ do \ - if [ ! -d $$i ] ; then \ + if [ ! -d "$$i" ] ; then \ echo "Making directory $$i"; \ - $(MKDIR) $$i; \ - chmod 755 $$i; \ + $(INSTALL_DATA_DIR) "$$i"; \ else true; \ fi; \ done; - @echo "Installing demos to $(SCRIPT_INSTALL_DIR)/demos/"; - @for i in $(ROOT_DIR)/library/demos/*; \ - do \ - if [ -f $$i ] ; then \ - sed -e '3 s|exec wish|exec wish$(VER)|' \ - $$i > $(SCRIPT_INSTALL_DIR)/demos/`basename $$i`; \ - fi; \ - done; - @for i in $(DEMOPROGS); \ - do \ - if test $$i = "square"; then \ - rm -f $(SCRIPT_INSTALL_DIR)/demos/$$i; \ - else \ - chmod 755 $(SCRIPT_INSTALL_DIR)/demos/$$i; \ - fi; \ - done; - @echo "Installing demo images"; - @for i in $(ROOT_DIR)/library/demos/images/*; \ + @echo "Installing header files to $(INCLUDE_INSTALL_DIR)/"; + @for i in $(GENERIC_DIR)/tcl.h $(GENERIC_DIR)/tclDecls.h \ + $(GENERIC_DIR)/tclOO.h $(GENERIC_DIR)/tclOODecls.h \ + $(GENERIC_DIR)/tclPlatDecls.h \ + $(GENERIC_DIR)/tclTomMath.h \ + $(GENERIC_DIR)/tclTomMathDecls.h ; \ do \ - if [ -f $$i ] ; then \ - $(INSTALL_DATA) $$i $(SCRIPT_INSTALL_DIR)/demos/images; \ - fi; \ + $(COPY) $$i "$(INCLUDE_INSTALL_DIR)"; \ done; -install-doc: doc - # Optional target to install private headers install-private-headers: libraries @for i in $(PRIVATE_INCLUDE_INSTALL_DIR); \ @@ -659,153 +841,197 @@ install-private-headers: libraries if [ ! -d $$i ] ; then \ echo "Making directory $$i"; \ $(MKDIR) $$i; \ - chmod 755 $$i; \ else true; \ fi; \ done; - @echo "Installing private header files to $(PRIVATE_INCLUDE_INSTALL_DIR)/"; - @for i in $(GENERIC_DIR)/tkInt.h $(GENERIC_DIR)/tkIntDecls.h \ - $(GENERIC_DIR)/tkIntPlatDecls.h $(GENERIC_DIR)/tkPort.h \ - $(WIN_DIR)/tkWinPort.h $(WIN_DIR)/tkWinInt.h $(WIN_DIR)/tkWin.h; \ + @echo "Installing private header files"; + @for i in "$(GENERIC_DIR)/tclInt.h" "$(GENERIC_DIR)/tclIntDecls.h" \ + "$(GENERIC_DIR)/tclIntPlatDecls.h" "$(GENERIC_DIR)/tclPort.h" \ + "$(GENERIC_DIR)/tclOOInt.h" "$(GENERIC_DIR)/tclOOIntDecls.h" \ + "$(WIN_DIR)/tclWinPort.h" ; \ do \ - $(INSTALL_DATA) $$i $(PRIVATE_INCLUDE_INSTALL_DIR); \ + $(COPY) "$$i" "$(PRIVATE_INCLUDE_INSTALL_DIR)"; \ done; -$(WISH): $(WISH_OBJS) @LIBRARIES@ $(TK_STUB_LIB_FILE) wish.$(RES) - $(CC) $(CFLAGS) $(WISH_OBJS) $(TK_LIB_FILE) \ - $(TK_STUB_LIB_FILE) $(TCL_LIB_FILE) $(LIBS) \ - wish.$(RES) $(CC_EXENAME) $(LDFLAGS_WINDOW) - @VC_MANIFEST_EMBED_EXE@ - -tktest: $(TKTEST) - -$(TKTEST): testMain.$(OBJEXT) $(TEST_DLL_FILE) @LIBRARIES@ $(TK_STUB_LIB_FILE) wish.$(RES) - $(CC) $(CFLAGS) testMain.$(OBJEXT) $(TEST_LIB_FILE) $(TK_LIB_FILE) \ - $(TK_STUB_LIB_FILE) $(TCL_LIB_FILE) $(LIBS) \ - wish.$(RES) $(CC_EXENAME) $(LDFLAGS_WINDOW) - @VC_MANIFEST_EMBED_EXE@ - -${TEST_DLL_FILE}: ${TKTEST_OBJS} ${TK_STUB_LIB_FILE} - @MAKE_DLL@ ${TKTEST_OBJS} $(TK_STUB_LIB_FILE) $(SHLIB_LD_LIBS) - -# Msys make requires this next rule for some reason. -$(TCL_SRC_DIR)/win/cat.c: - -cat32.${OBJEXT}: $(TCL_SRC_DIR)/win/cat.c - $(CC) -c $(CC_SWITCHES) "$(TCL_SRC_DIR)/win/cat.c" $(CC_OBJNAME) - -$(CAT32): cat32.${OBJEXT} - $(CC) $(CFLAGS) cat32.$(OBJEXT) $(CC_EXENAME) $(LIBS) $(LDFLAGS_CONSOLE) - -# The following targets are configured by autoconf to generate either -# a shared library or static library - -${TK_STUB_LIB_FILE}: ${STUB_OBJS} - @$(RM) ${TK_STUB_LIB_FILE} - @MAKE_STUB_LIB@ ${STUB_OBJS} - @POST_MAKE_LIB@ - -${TK_DLL_FILE}: ${TK_OBJS} $(TK_RES) ${TCL_ZIPFS_OBJS} - @$(RM) ${TK_DLL_FILE} - @MAKE_DLL@ ${TK_OBJS} $(TK_RES) $(SHLIB_LD_LIBS) - @VC_MANIFEST_EMBED_DLL@ -ifeq (${TCL_ZIPFS_SUPPORT},1) - cat ${TK_ZIP_FILE} >> ${LIB_FILE} -endif - -${TK_LIB_FILE}: ${TK_OBJS} - @$(RM) ${TK_LIB_FILE} - @MAKE_LIB@ ${TK_OBJS} - @POST_MAKE_LIB@ - -# Special case object file targets - -winMain.$(OBJEXT): winMain.c - $(CC) -c $(CC_SWITCHES) @DEPARG@ $(CC_OBJNAME) - -testMain.$(OBJEXT): winMain.c - $(CC) -c $(CC_SWITCHES) @DEPARG@ -DTK_TEST $(CC_OBJNAME) - -tkTest.$(OBJEXT): tkTest.c - $(CC) -c $(CC_SWITCHES) @DEPARG@ $(CC_OBJNAME) - -tkOldTest.$(OBJEXT): tkOldTest.c - $(CC) -c $(CC_SWITCHES) @DEPARG@ $(CC_OBJNAME) - -tkWinTest.$(OBJEXT): tkWinTest.c - $(CC) -c $(CC_SWITCHES) @DEPARG@ $(CC_OBJNAME) - -tkSquare.$(OBJEXT): tkSquare.c - $(CC) -c $(CC_SWITCHES) @DEPARG@ $(CC_OBJNAME) - -tkMain2.$(OBJEXT): tkMain.c - $(CC) -c $(CC_SWITCHES) -DBUILD_tk -DTK_ASCII_MAIN @DEPARG@ $(CC_OBJNAME) - -# Extra dependency info -tkConsole.$(OBJEXT): configure Makefile -tkMain.$(OBJEXT): configure Makefile -tkWindow.$(OBJEXT): configure Makefile +# Specifying TESTFLAGS on the command line is the standard way to pass args to +# tcltest, i.e.: +# % make test TESTFLAGS="-verbose bps -file fileName.test" -# Add the object extension to the implicit rules. By default .obj is not -# automatically added. +test: test-tcl test-packages -.SUFFIXES: .${OBJEXT} -.SUFFIXES: .$(RES) -.SUFFIXES: .rc +test-tcl: binaries $(TCLSH) $(CAT32) $(TEST_DLL_FILE) + TCL_LIBRARY="$(LIBRARY_DIR)"; export TCL_LIBRARY; \ + ./$(TCLSH) "$(ROOT_DIR_NATIVE)/tests/all.tcl" $(TESTFLAGS) \ + -load "package ifneeded Tcltest ${VERSION}@TCL_PATCH_LEVEL@ [list load [file normalize ${TEST_DLL_FILE}] Tcltest]; \ + package ifneeded dde 1.4.0 [list load [file normalize ${DDE_DLL_FILE}] dde]; \ + package ifneeded registry 1.3.2 [list load [file normalize ${REG_DLL_FILE}] registry]" | ./$(CAT32) -# Implicit rule for all object files that will end up in the Tk library +# Useful target to launch a built tclsh with the proper path,... +runtest: binaries $(TCLSH) $(TEST_DLL_FILE) + @TCL_LIBRARY="$(LIBRARY_DIR)"; export TCL_LIBRARY; \ + ./$(TCLSH) $(TESTFLAGS) -load "package ifneeded Tcltest ${VERSION}@TCL_PATCH_LEVEL@ [list load [file normalize ${TEST_DLL_FILE}] Tcltest]; \ + package ifneeded dde 1.4.0 [list load [file normalize ${DDE_DLL_FILE}] dde]; \ + package ifneeded registry 1.3.2 [list load [file normalize ${REG_DLL_FILE}] registry]" $(SCRIPT) -%.$(OBJEXT): %.c - $(CC) -c $(CC_SWITCHES) -DBUILD_tk -DBUILD_ttk @DEPARG@ $(CC_OBJNAME) +# This target can be used to run tclsh from the build directory via +# `make shell SCRIPT=foo.tcl` +shell: binaries + @TCL_LIBRARY="$(LIBRARY_DIR)"; export TCL_LIBRARY; \ + ./$(TCLSH) $(SCRIPT) -.rc.$(RES): - $(RC) @RC_OUT@ $@ @RC_TYPE@ @RC_DEFINES@ @RC_INCLUDE@ "$(GENERIC_DIR_NATIVE)" @RC_INCLUDE@ "$(TCL_GENERIC_NATIVE)" @RC_INCLUDE@ "$(RC_DIR_NATIVE)" @DEPARG@ +# This target can be used to run tclsh inside either gdb or insight +gdb: binaries + @echo "set env TCL_LIBRARY=$(LIBRARY_DIR)" > gdb.run + gdb ./$(TCLSH) --command=gdb.run + rm gdb.run depend: +Makefile: $(SRC_DIR)/Makefile.in + ./config.status + cleanhelp: - $(RM) *.hlp *.cnt *.hpj *.GID *.rtf man2tcl${EXEEXT} + $(RM) *.hlp *.cnt *.GID *.rtf man2tcl.exe -clean: cleanhelp - $(RM) *.lib *.a *.exp *.dll *.res *.${OBJEXT} *~ \#* TAGS a.out - $(RM) $(WISH) $(TKTEST) $(CAT32) +clean: cleanhelp clean-packages + $(RM) *.lib *.a *.exp *.dll *.$(RES) *.${OBJEXT} *~ \#* TAGS a.out + $(RM) $(TCLSH) $(CAT32) $(RM) *.pch *.ilk *.pdb + $(RM) minizip${HOST_EXEEXT} *.${HOST_OBJEXT} + $(RM) *.zip + $(RMDIR) *.vfs -distclean: clean - $(RM) Makefile config.status config.cache config.log tkConfig.sh \ - wish.exe.manifest +distclean: distclean-packages clean + $(RM) Makefile config.status config.cache config.log tclConfig.sh \ + tcl.hpj config.status.lineno tclsh.exe.manifest -Makefile: $(SRC_DIR)/Makefile.in - ./config.status +# +# Bundled package targets +# + +PKG_CFG_ARGS = @PKG_CFG_ARGS@ +PKG_DIR = ./pkgs + +packages: + @builddir=`$(CYGPATH) $$(pwd -P)`; \ + for i in $(PKGS_DIR)/*; do \ + if [ -d $$i ] ; then \ + if [ -x $$i/configure ] ; then \ + pkg=`basename $$i`; \ + mkdir -p $(PKG_DIR)/$$pkg; \ + if [ ! -f $(PKG_DIR)/$$pkg/Makefile ]; then \ + ( cd $(PKG_DIR)/$$pkg; \ + echo "Configuring package '$$i' wd = `$(CYGPATH) $$(pwd -P)`"; \ + $$i/configure --with-tcl=$$builddir --with-tclinclude=$(GENERIC_DIR_NATIVE) $(PKG_CFG_ARGS) --enable-shared --enable-threads; ) \ + fi ; \ + echo "Building package '$$pkg'"; \ + ( cd $(PKG_DIR)/$$pkg; $(MAKE); ) \ + fi; \ + fi; \ + done; \ + cd $$builddir + +install-packages: packages + @builddir=`pwd -P`; \ + for i in $(PKGS_DIR)/*; do \ + if [ -d $$i ]; then \ + pkg=`basename $$i`; \ + if [ -f $(PKG_DIR)/$$pkg/Makefile ]; then \ + echo "Installing package '$$pkg'"; \ + ( cd $(PKG_DIR)/$$pkg; $(MAKE) install "DESTDIR=$(INSTALL_ROOT)"; ) \ + fi; \ + fi; \ + done; \ + cd $$builddir + +test-packages: tcltest packages + @builddir=`pwd -P`; \ + for i in $(PKGS_DIR)/*; do \ + if [ -d $$i ]; then \ + pkg=`basename $$i`; \ + if [ -f $(PKG_DIR)/$$pkg/Makefile ]; then \ + echo "Testing package '$$pkg'"; \ + ( cd $(PKG_DIR)/$$pkg; $(MAKE) "LD_LIBRARY_PATH=$$builddir:${LD_LIBRARY_PATH}" "TCL_LIBRARY=${TCL_BUILDTIME_LIBRARY}" "TCLLIBPATH=$$builddir/pkgs" test "TCLSH_PROG=$$builddir/${TCLSH}"; ) \ + fi; \ + fi; \ + done; \ + cd $$builddir + +clean-packages: + @builddir=`pwd -P`; \ + for i in $(PKGS_DIR)/*; do \ + if [ -d $$i ]; then \ + pkg=`basename $$i`; \ + if [ -f $(PKG_DIR)/$$pkg/Makefile ]; then \ + ( cd $(PKG_DIR)/$$pkg; $(MAKE) clean; ) \ + fi; \ + fi; \ + done; \ + cd $$builddir + +distclean-packages: + @builddir=`pwd -P`; \ + for i in $(PKGS_DIR)/*; do \ + if [ -d $$i ]; then \ + pkg=`basename $$i`; \ + if [ -f $(PKG_DIR)/$$pkg/Makefile ]; then \ + ( cd $(PKG_DIR)/$$pkg; $(MAKE) distclean; ) \ + fi; \ + cd $$builddir; \ + rm -rf $(PKG_DIR)/$$pkg; \ + fi; \ + done; \ + rm -rf $(PKG_DIR) # # Regenerate the stubs files. # -$(GENERIC_DIR)/tkStubInit.c: $(GENERIC_DIR)/tk.decls \ - $(GENERIC_DIR)/tkInt.decls - @echo "Warning: tkStubInit.c may be out of date." +$(GENERIC_DIR)/tclStubInit.c: $(GENERIC_DIR)/tcl.decls \ + $(GENERIC_DIR)/tclInt.decls + @echo "Warning: tclStubInit.c may be out of date." @echo "Developers may want to run \"make genstubs\" to regenerate." @echo "This warning can be safely ignored, do not report as a bug!" genstubs: - $(TCL_EXE) "$(TCL_TOOL_DIR)/genStubs.tcl" \ + $(TCL_EXE) "$(ROOT_DIR_NATIVE)/tools/genStubs.tcl" \ + "$(GENERIC_DIR_NATIVE)" \ + "$(GENERIC_DIR_NATIVE)/tcl.decls" \ + "$(GENERIC_DIR_NATIVE)/tclInt.decls" \ + "$(GENERIC_DIR_NATIVE)/tclTomMath.decls" + $(TCL_EXE) "$(ROOT_DIR_NATIVE)/tools/genStubs.tcl" \ "$(GENERIC_DIR_NATIVE)" \ - "$(GENERIC_DIR_NATIVE)/tk.decls" \ - "$(GENERIC_DIR_NATIVE)/tkInt.decls" - $(TCL_EXE) "$(TTK_DIR)/ttkGenStubs.tcl" \ - "$(TTK_DIR)" \ - "$(TTK_DIR)/ttk.decls" + "$(GENERIC_DIR_NATIVE)/tclOO.decls" + +# +# This target creates the HTML folder for Tcl & Tk and places it in +# DISTDIR/html. It uses the tcltk-man2html.tcl tool from the Tcl group's tool +# workspace. It depends on the Tcl & Tk being in directories called tcl8.* & +# tk8.* up two directories from the TOOL_DIR. +# + +TOOL_DIR=$(ROOT_DIR)/tools +HTML_INSTALL_DIR=$(ROOT_DIR)/html +html: + $(MAKE) shell SCRIPT="$(TOOL_DIR)/tcltk-man2html.tcl --htmldir=$(HTML_INSTALL_DIR) --srcdir=$(ROOT_DIR)/.. $(BUILD_HTML_FLAGS)" + +html-tcl: $(TCLSH) + $(MAKE) shell SCRIPT="$(TOOL_DIR)/tcltk-man2html.tcl --htmldir=$(HTML_INSTALL_DIR) --srcdir=$(ROOT_DIR)/.. $(BUILD_HTML_FLAGS) --tcl" + +html-tk: $(TCLSH) + $(MAKE) shell SCRIPT="$(TOOL_DIR)/tcltk-man2html.tcl --htmldir=$(HTML_INSTALL_DIR) --srcdir=$(ROOT_DIR)/.. $(BUILD_HTML_FLAGS) --tk" # # The list of all the targets that do not correspond to real files. This stops # 'make' from getting confused when someone makes an error in a rule. # -.PHONY: all binaries libraries doc tkLibObjs objs tktest-real test test-classic -.PHONY: test-ttk testlang runtest shell demo gdb install install-strip -.PHONY: install-binaries install-libraries install-demos install-doc -.PHONY: install-private-headers clean distclean depend genstubs checkstubs -.PHONY: checkuchar checkexports rpm dist alldist allpatch html html-tcl html-tk +.PHONY: all tcltest binaries libraries doc gendate gentommath_h install +.PHONY: install-binaries install-libraries install-tzdata install-msgs +.PHONY: install-doc install-private-headers test test-tcl runtest shell +.PHONY: gdb depend cleanhelp clean distclean packages install-packages +.PHONY: test-packages clean-packages distclean-packages genstubs html +.PHONY: html-tcl html-tk +.PHONY: iinstall-libraries-zipfs-shared install-libraries-zipfs-static tclzipfile # DO NOT DELETE THIS LINE -- make depend depends on it. -- cgit v0.12 From 71cf0dba4023ab771a4923f6e741c5b6ac19217a Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Sat, 16 Dec 2017 03:22:04 +0000 Subject: Re-arranging code and providing forward prototypes to allow the C infrastructure of Zipfs to be activated from withing the first call to TclZipfs_Mount(). This keeps up from having to expose TclZipfs_Init in the stubs table. --- generic/tclZipfs.c | 145 ++++++++++++++++++++++++++++++++--------------------- 1 file changed, 88 insertions(+), 57 deletions(-) diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c index 2370980..ca10b4f 100644 --- a/generic/tclZipfs.c +++ b/generic/tclZipfs.c @@ -306,6 +306,73 @@ static const unsigned long crc32tab[256] = { const char *zipfs_literal_tcl_library=NULL; +/* Function prototypes */ +static int Zip_FSPathInFilesystemProc(Tcl_Obj *pathPtr, ClientData *clientDataPtr); +static Tcl_Obj *Zip_FSFilesystemPathTypeProc(Tcl_Obj *pathPtr); +static Tcl_Obj *Zip_FSFilesystemSeparatorProc(Tcl_Obj *pathPtr); +static int Zip_FSStatProc(Tcl_Obj *pathPtr, Tcl_StatBuf *buf); +static int Zip_FSAccessProc(Tcl_Obj *pathPtr, int mode); +static Tcl_Channel Zip_FSOpenFileChannelProc( + Tcl_Interp *interp, Tcl_Obj *pathPtr, + int mode, int permissions +); +static int Zip_FSMatchInDirectoryProc( + Tcl_Interp* interp, Tcl_Obj *result, + Tcl_Obj *pathPtr, const char *pattern, + Tcl_GlobTypeData *types +); +static Tcl_Obj *Zip_FSListVolumesProc(void); +static const char *const *Zip_FSFileAttrStringsProc(Tcl_Obj *pathPtr, Tcl_Obj** objPtrRef); +static int Zip_FSFileAttrsGetProc( + Tcl_Interp *interp, int index, Tcl_Obj *pathPtr, + Tcl_Obj **objPtrRef +); +static int Zip_FSFileAttrsSetProc(Tcl_Interp *interp, int index, Tcl_Obj *pathPtr,Tcl_Obj *objPtr); +static int Zip_FSLoadFile(Tcl_Interp *interp, Tcl_Obj *path, Tcl_LoadHandle *loadHandle, + Tcl_FSUnloadFileProc **unloadProcPtr, int flags); +static void TclZipfs_C_Init(void); + +/* + * Define the ZIP filesystem dispatch table. + */ + +MODULE_SCOPE const Tcl_Filesystem zipfsFilesystem; + +const Tcl_Filesystem zipfsFilesystem = { + "zipfs", + sizeof (Tcl_Filesystem), + TCL_FILESYSTEM_VERSION_2, + Zip_FSPathInFilesystemProc, + NULL, /* dupInternalRepProc */ + NULL, /* freeInternalRepProc */ + NULL, /* internalToNormalizedProc */ + NULL, /* createInternalRepProc */ + NULL, /* normalizePathProc */ + Zip_FSFilesystemPathTypeProc, + Zip_FSFilesystemSeparatorProc, + Zip_FSStatProc, + Zip_FSAccessProc, + Zip_FSOpenFileChannelProc, + Zip_FSMatchInDirectoryProc, + NULL, /* utimeProc */ + NULL, /* linkProc */ + Zip_FSListVolumesProc, + Zip_FSFileAttrStringsProc, + Zip_FSFileAttrsGetProc, + Zip_FSFileAttrsSetProc, + NULL, /* createDirectoryProc */ + NULL, /* removeDirectoryProc */ + NULL, /* deleteFileProc */ + NULL, /* copyFileProc */ + NULL, /* renameFileProc */ + NULL, /* copyDirectoryProc */ + NULL, /* lstatProc */ + (Tcl_FSLoadFileProc *) Zip_FSLoadFile, + NULL, /* getCwdProc */ + NULL, /* chdirProc*/ +}; + + /* *------------------------------------------------------------------------- @@ -1039,6 +1106,25 @@ error: ZipFSCloseArchive(interp, zf); return TCL_ERROR; } + +static void TclZipfs_C_Init(void) { + static const Tcl_Time t = { 0, 0 }; + if (!ZipFS.initialized) { +#ifdef TCL_THREADS + /* + * Inflate condition variable. + */ + Tcl_MutexLock(&ZipFSMutex); + Tcl_ConditionWait(&ZipFSCond, &ZipFSMutex, &t); + Tcl_MutexUnlock(&ZipFSMutex); +#endif + Tcl_FSRegister(NULL, &zipfsFilesystem); + Tcl_InitHashTable(&ZipFS.fileHash, TCL_STRING_KEYS); + Tcl_InitHashTable(&ZipFS.zipHash, TCL_STRING_KEYS); + ZipFS.initialized = ZipFS.idCount = 1; + } +} + /* *------------------------------------------------------------------------- @@ -1077,9 +1163,7 @@ TclZipfs_Mount( ReadLock(); if (!ZipFS.initialized) { - ZIPFS_ERROR(interp,"not initialized"); - Unlock(); - return TCL_ERROR; + TclZipfs_C_Init(); } if (zipname == NULL) { Tcl_HashSearch search; @@ -3924,47 +4008,6 @@ Zip_FSLoadFile(Tcl_Interp *interp, Tcl_Obj *path, Tcl_LoadHandle *loadHandle, #endif } - -/* - * Define the ZIP filesystem dispatch table. - */ - -MODULE_SCOPE const Tcl_Filesystem zipfsFilesystem; - -const Tcl_Filesystem zipfsFilesystem = { - "zipfs", - sizeof (Tcl_Filesystem), - TCL_FILESYSTEM_VERSION_2, - Zip_FSPathInFilesystemProc, - NULL, /* dupInternalRepProc */ - NULL, /* freeInternalRepProc */ - NULL, /* internalToNormalizedProc */ - NULL, /* createInternalRepProc */ - NULL, /* normalizePathProc */ - Zip_FSFilesystemPathTypeProc, - Zip_FSFilesystemSeparatorProc, - Zip_FSStatProc, - Zip_FSAccessProc, - Zip_FSOpenFileChannelProc, - Zip_FSMatchInDirectoryProc, - NULL, /* utimeProc */ - NULL, /* linkProc */ - Zip_FSListVolumesProc, - Zip_FSFileAttrStringsProc, - Zip_FSFileAttrsGetProc, - Zip_FSFileAttrsSetProc, - NULL, /* createDirectoryProc */ - NULL, /* removeDirectoryProc */ - NULL, /* deleteFileProc */ - NULL, /* copyFileProc */ - NULL, /* renameFileProc */ - NULL, /* copyDirectoryProc */ - NULL, /* lstatProc */ - (Tcl_FSLoadFileProc *) Zip_FSLoadFile, - NULL, /* getCwdProc */ - NULL, /* chdirProc*/ -}; - #endif /* HAVE_ZLIB */ @@ -3994,19 +4037,7 @@ TclZipfs_Init(Tcl_Interp *interp) WriteLock(); Tcl_StaticPackage(interp, "zipfs", TclZipfs_Init, TclZipfs_Init); if (!ZipFS.initialized) { -#ifdef TCL_THREADS - static const Tcl_Time t = { 0, 0 }; - /* - * Inflate condition variable. - */ - Tcl_MutexLock(&ZipFSMutex); - Tcl_ConditionWait(&ZipFSCond, &ZipFSMutex, &t); - Tcl_MutexUnlock(&ZipFSMutex); -#endif - Tcl_FSRegister(NULL, &zipfsFilesystem); - Tcl_InitHashTable(&ZipFS.fileHash, TCL_STRING_KEYS); - Tcl_InitHashTable(&ZipFS.zipHash, TCL_STRING_KEYS); - ZipFS.initialized = ZipFS.idCount = 1; + TclZipfs_C_Init(); } Unlock(); if(interp != NULL) { -- cgit v0.12 From 45a3c74a04c973ba863d5914abedb96b85d17e1b Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Sat, 16 Dec 2017 03:24:21 +0000 Subject: Removing static package declaration of zipfs. --- generic/tclZipfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c index ca10b4f..45ba8e2 100644 --- a/generic/tclZipfs.c +++ b/generic/tclZipfs.c @@ -4035,7 +4035,7 @@ TclZipfs_Init(Tcl_Interp *interp) #ifdef HAVE_ZLIB /* one-time initialization */ WriteLock(); - Tcl_StaticPackage(interp, "zipfs", TclZipfs_Init, TclZipfs_Init); + /* Tcl_StaticPackage(interp, "zipfs", TclZipfs_Init, TclZipfs_Init); */ if (!ZipFS.initialized) { TclZipfs_C_Init(); } -- cgit v0.12 From 7f1c241ea2bb3908c647d517e512816b219771dd Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Sat, 16 Dec 2017 03:30:58 +0000 Subject: Update the config.test with new keys needed for zipfs --- tests/config.test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/config.test b/tests/config.test index d14837e..468a1df 100644 --- a/tests/config.test +++ b/tests/config.test @@ -19,7 +19,7 @@ if {[lsearch [namespace children] ::tcltest] == -1} { test pkgconfig-1.1 {query keys} { lsort [::tcl::pkgconfig list] -} {64bit bindir,install bindir,runtime compile_debug compile_stats debug docdir,install docdir,runtime includedir,install includedir,runtime libdir,install libdir,runtime mem_debug optimized profiled scriptdir,install scriptdir,runtime threaded} +} {64bit bindir,install bindir,runtime compile_debug compile_stats debug dllfile,runtime docdir,install docdir,runtime includedir,install includedir,runtime libdir,install libdir,runtime mem_debug optimized profiled scriptdir,install scriptdir,runtime threaded zipfile,runtime} test pkgconfig-1.2 {query keys multiple times} { string compare [::tcl::pkgconfig list] [::tcl::pkgconfig list] } 0 -- cgit v0.12 From 983b089edb6d9c4f233f21a1792393758dea4f65 Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Fri, 29 Dec 2017 20:40:29 +0000 Subject: Removing the standalone pkgIndex.tcl. There is enough stuff that needs to be manually edited in the init.tcl script for new releases as it is, there is no sense in having yet another file to edit. Marking which distributed packages are safe to load in a safe interpreter --- library/init.tcl | 25 +++++++++++++++++++++---- library/pkgIndex.tcl | 16 ---------------- 2 files changed, 21 insertions(+), 20 deletions(-) delete mode 100644 library/pkgIndex.tcl diff --git a/library/init.tcl b/library/init.tcl index d4a66e2..e58dcfc 100644 --- a/library/init.tcl +++ b/library/init.tcl @@ -6,7 +6,10 @@ # Copyright (c) 1991-1993 The Regents of the University of California. # Copyright (c) 1994-1996 Sun Microsystems, Inc. # Copyright (c) 1998-1999 Scriptics Corporation. -# Copyright (c) 2004 by Kevin B. Kenny. All rights reserved. +# Copyright (c) 2004 by Kevin B. Kenny. +# Copyright (c) 2018 by Sean Woods +# +# All rights reserved. # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. @@ -795,7 +798,21 @@ proc tcl::CopyDirectory {action src dest} { } return } -if {[file exists [file join $::tcl_library pkgIndex.tcl]]} { - set dir $::tcl_library - source [file join $::tcl_library pkgIndex.tcl] +set isafe [interp issafe] +### +# Package manifest for all Tcl packages included in the /library file system +### +set isafe [interp issafe] +set dir [file dirname [info script]] +foreach {safe package version file} { + 0 http 2.8.12 {http http.tcl} + 0 http 1.0 {http1.0 http.tcl} + 1 msgcat 1.6.1 {msgcat msgcat.tcl} + 1 opt 0.4.7 {opt optparse.tcl} + 0 platform 1.0.14 {platform platform.tcl} + 0 platform::shell 1.1.4 {platform shell.tcl} + 1 tcltest 2.4.1 {tcltest tcltest.tcl} +} { + if {$isafe && !$safe} continue + package ifneeded $package $version [list source [file join $dir {*}$file]] } diff --git a/library/pkgIndex.tcl b/library/pkgIndex.tcl deleted file mode 100644 index ff8d0f1..0000000 --- a/library/pkgIndex.tcl +++ /dev/null @@ -1,16 +0,0 @@ -### -# Package manifest for all Tcl packages included in the /library file system -### -foreach {package version file} { - http 2.8.12 {http http.tcl} - http 1.0 {http1.0 http.tcl} - msgcat 1.6.1 {msgcat msgcat.tcl} - opt 0.4.7 {opt optparse.tcl} - platform 1.0.14 {platform platform.tcl} - platform::shell 1.1.4 {platform shell.tcl} - tcltest 2.4.1 {tcltest tcltest.tcl} -} { - package ifneeded $package $version [list source [file join $dir {*}$file]] -} -# Opt is the odd man out -package ifneeded opt 0.4.7 [list source [file join $dir opt optparse.tcl]] -- cgit v0.12 From b533731c50bd2d75793771054f53afd96afbfd80 Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Fri, 29 Dec 2017 21:41:00 +0000 Subject: Modifications to clean up warnings on compile --- generic/tclZipfs.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c index 45ba8e2..49f3b04 100644 --- a/generic/tclZipfs.c +++ b/generic/tclZipfs.c @@ -155,14 +155,14 @@ typedef struct ZipFile { long length; /* Length of memory mapped file */ unsigned char *tofree; /* Non-NULL if malloc'ed file */ int nfiles; /* Number of files in archive */ - int baseoffs; /* Archive start */ - int baseoffsp; /* Password start */ - int centoffs; /* Archive directory start */ - char pwbuf[264]; /* Password buffer */ + unsigned long baseoffs; /* Archive start */ + long baseoffsp; /* Password start */ + unsigned long centoffs; /* Archive directory start */ + unsigned char pwbuf[264]; /* Password buffer */ #if defined(_WIN32) || defined(_WIN64) HANDLE mh; #endif - int nopen; /* Number of open files on archive */ + unsigned long nopen; /* Number of open files on archive */ struct ZipEntry *entries; /* List of files in archive */ struct ZipEntry *topents; /* List of top-level dirs in archive */ #if HAS_DRIVES @@ -1796,7 +1796,7 @@ wrerr: return TCL_ERROR; } if ((len + pos[0]) & 3) { - char abuf[8]; + unsigned char abuf[8]; /* * Align payload to next 4-byte boundary using a dummy extra @@ -1806,7 +1806,7 @@ wrerr: zip_write_short(abuf, 0xffff); zip_write_short(abuf + 2, align - 4); zip_write_int(abuf + 4, 0x03020100); - if (Tcl_Write(out, abuf, align) != align) { + if (Tcl_Write(out, (const char *)abuf, align) != align) { goto wrerr; } } @@ -4151,7 +4151,7 @@ int TclZipfs_AppHook(int *argc, char ***argv) char *archive; Tcl_FindExecutable(*argv[0]); - archive=Tcl_GetNameOfExecutable(); + archive=(char *)Tcl_GetNameOfExecutable(); TclZipfs_Init(NULL); /* ** Look for init.tcl in one of the locations mounted later in this function -- cgit v0.12 From 7aa147800f9c40128417d41e350815b482d4a927 Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 4 Jan 2018 02:23:37 +0000 Subject: Minimal fixes to stop the [package files] machinery writing to freed mem. This contribution needs a careful review from someone who actually knows how Tcl_Preserve, etc. work. --- generic/tclPkg.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/generic/tclPkg.c b/generic/tclPkg.c index cdf9a8b..288d5dc 100644 --- a/generic/tclPkg.c +++ b/generic/tclPkg.c @@ -948,6 +948,7 @@ Tcl_PackageObjCmd( Tcl_EventuallyFree(availPtr->script, TCL_DYNAMIC); if (availPtr->pkgIndex) { Tcl_EventuallyFree(availPtr->pkgIndex, TCL_DYNAMIC); + availPtr->pkgIndex = NULL; } ckfree(availPtr); } @@ -1001,6 +1002,7 @@ Tcl_PackageObjCmd( Tcl_EventuallyFree(availPtr->script, TCL_DYNAMIC); if (availPtr->pkgIndex) { Tcl_EventuallyFree(availPtr->pkgIndex, TCL_DYNAMIC); + availPtr->pkgIndex = NULL; } break; } @@ -1012,7 +1014,7 @@ Tcl_PackageObjCmd( } if (availPtr == NULL) { availPtr = ckalloc(sizeof(PkgAvail)); - availPtr->pkgIndex = 0; + availPtr->pkgIndex = NULL; DupBlock(availPtr->version, argv3, (unsigned) length + 1); if (prevPtr == NULL) { @@ -1384,6 +1386,7 @@ TclFreePackageInfo( Tcl_EventuallyFree(availPtr->script, TCL_DYNAMIC); if (availPtr->pkgIndex) { Tcl_EventuallyFree(availPtr->pkgIndex, TCL_DYNAMIC); + availPtr->pkgIndex = NULL; } ckfree(availPtr); } -- cgit v0.12 From 37b48e808c43273e27f69fff6280a7a29f3b7c4d Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Tue, 9 Jan 2018 18:10:06 +0000 Subject: Fix tests dependent on other tests in zipfs.test Add a workaround for the fact that dynamic libraries called out from a non-install location can't be located and mounted in time to be a candidate for tcl_library when running under the constraints of "make test" --- tests/zipfs.test | 65 +++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 48 insertions(+), 17 deletions(-) diff --git a/tests/zipfs.test b/tests/zipfs.test index abf888b..43aa48b 100644 --- a/tests/zipfs.test +++ b/tests/zipfs.test @@ -23,6 +23,10 @@ testConstraint zipfs [expr {[llength [info commands zlib]] && [regexp tcltest [i #} -result {} set ziproot [zipfs root] +set CWD [pwd] +set tmpdir [file join $CWD tmp] +file mkdir $tmpdir + test zipfs-0.1 {zipfs basics} -constraints zipfs -body { package require zipfs @@ -32,6 +36,22 @@ test zipfs-0.1 {zipfs basics} -constraints zipfs -body { expr {${ziproot} in [file volumes]} } -result 1 +if {![string match ${ziproot}* $tcl_library]} { + ### + # "make test" does not map tcl_library from the dynamic library on Unix + # + # Hack the environment to pretend we did pull tcl_library from a zip + # archive + ### + set tclzip [file join $CWD [::tcl::pkgconfig get zipfile,runtime]] + if {[file exists $tclzip]} { + zipfs mount $tclzip /lib/tcl + set ::tcl_library ${ziproot}lib/tcl/tcl_library + } else { + tcltest::skip zipfs-0.* + } +} + test zipfs-0.2 {zipfs basics} -constraints zipfs -body { string match ${ziproot}* $tcl_library } -result 1 @@ -116,25 +136,36 @@ test zipfs-1.10 {zipfs errors} -constraints zipfs -returnCodes error -body { zipfs list a b c d e f } -result {wrong # args: should be "zipfs list ?(-glob|-regexp)? ?pattern?"} +file mkdir tmp + test zipfs-2.1 {zipfs mkzip empty archive} -constraints zipfs -returnCodes error -body { - zipfs mkzip /tmp/abc.zip $tcl_library/xxxx ;# FIXME: test independence + zipfs mkzip [file join $tmpdir empty.zip] $tcl_library/xxxx } -result {empty archive} -test zipfs-2.2 {zipfs mkzip} -constraints zipfs -body { - set pwd [pwd] +### +# The 2.2 series of tests operate within +# a zipfile created a temporary directory +### +set zipfile [file join $tmpdir abc.zip] +if {[file exists $zipfile]} { + file delete $zipfile +} + +test zipfs-2.2.0 {zipfs mkzip} -constraints zipfs -body { cd $tcl_library/encoding - zipfs mkzip /tmp/abc.zip . - zipfs mount /tmp/abc.zip ${ziproot}abc ;# FIXME: test independence + zipfs mkzip $zipfile . + zipfs mount $zipfile ${ziproot}abc zipfs list -glob ${ziproot}abc/cp850.* } -cleanup { - cd $pwd + cd $CWD } -result "[zipfs root]abc/cp850.enc" -test zipfs-2.3 {zipfs info} -constraints zipfs -body { - zipfs info ${ziproot}abc/cp850.enc -} -result [list /tmp/abc.zip 1090 527 39318] ;# FIXME: result depends on content of encodings dir +test zipfs-2.2.1 {zipfs info} -constraints zipfs -body { + set r [zipfs info ${ziproot}abc/cp850.enc] + lrange $r 0 2 +} -result [list $zipfile 1090 527] ;# NOTE: Only the first 3 results are stable -test zipfs-2.4 {zipfs data} -constraints zipfs -body { +test zipfs-2.2.3 {zipfs data} -constraints zipfs -body { set zipfd [open ${ziproot}/abc/cp850.enc] ;# FIXME: leave open - see later test read $zipfd } -result {# Encoding file: cp850, single-byte @@ -159,21 +190,21 @@ S 00AD00B1201700BE00B600A700F700B800B000A800B700B900B300B225A000A0 } ;# FIXME: result depends on content of encodings dir -test zipfs-2.5 {zipfs exists} -constraints zipfs -body { +test zipfs-2.2.4 {zipfs exists} -constraints zipfs -body { zipfs exists /abc/cp850.enc } -result 1 -test zipfs-2.6 {zipfs unmount while busy} -constraints zipfs -body { - zipfs unmount /tmp/abc.zip +test zipfs-2.2.5 {zipfs unmount while busy} -constraints zipfs -body { + zipfs unmount $zipfile } -returnCodes error -result {filesystem is busy} -test zipfs-2.7 {zipfs unmount} -constraints zipfs -body { +test zipfs-2.2.6 {zipfs unmount} -constraints zipfs -body { close $zipfd - zipfs unmount /tmp/abc.zip + zipfs unmount $zipfile zipfs exists /abc/cp850.enc -} -cleanup { - file delete /tmp/abc.zip ;# FIXME: test independence } -result 0 + +file delete -force $tmpdir ::tcltest::cleanupTests return -- cgit v0.12 From 9947048fbda326ad65c7f4a163a00d1d51efd791 Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Thu, 11 Jan 2018 16:45:52 +0000 Subject: Tweaks to zipfs.test --- tests/zipfs.test | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/tests/zipfs.test b/tests/zipfs.test index 43aa48b..c9dd0ac 100644 --- a/tests/zipfs.test +++ b/tests/zipfs.test @@ -160,6 +160,13 @@ test zipfs-2.2.0 {zipfs mkzip} -constraints zipfs -body { cd $CWD } -result "[zipfs root]abc/cp850.enc" +skip [concat [skip] zipfs-2.2.*] + + +if {![zipfs exists /abc/cp850.enc]} { + tcltest::skip zipfs-2.2.* +} + test zipfs-2.2.1 {zipfs info} -constraints zipfs -body { set r [zipfs info ${ziproot}abc/cp850.enc] lrange $r 0 2 @@ -204,7 +211,7 @@ test zipfs-2.2.6 {zipfs unmount} -constraints zipfs -body { zipfs exists /abc/cp850.enc } -result 0 -file delete -force $tmpdir +catch {file delete -force $tmpdir} ::tcltest::cleanupTests return -- cgit v0.12 From 3502aebe1064bb99245ba6117c80459cace5ac0c Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Tue, 16 Jan 2018 23:25:50 +0000 Subject: Tweaks to the tclZipfs.c file to allow the same C source to be used both in the core and as a static package for external shells (Via TEA) --- generic/tclZipfs.c | 112 +++++++++++++++++++++++++++++++++++------------------ 1 file changed, 75 insertions(+), 37 deletions(-) diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c index 49f3b04..305fb7f 100644 --- a/generic/tclZipfs.c +++ b/generic/tclZipfs.c @@ -9,6 +9,10 @@ * * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. + * + * This file is distributed in two ways: + * generic/tclZipfs.c file in the TIP430 enabled tcl cores + * compat/tclZipfs.c file in the tclconfig (TEA) file system, for pre-tip430 projects */ #include "tclInt.h" @@ -34,13 +38,27 @@ #include "zlib.h" #include "crypt.h" +#ifdef CFG_RUNTIME_DLLFILE /* +** We are compiling as part of the core. ** TIP430 style zipfs prefix */ #define ZIPFS_VOLUME "//zipfs:/" #define ZIPFS_VOLUME_LEN 9 #define ZIPFS_APP_MOUNT "//zipfs:/app" #define ZIPFS_ZIP_MOUNT "//zipfs:/lib/tcl" +#else +/* +** We are compiling from the /compat folder of tclconfig +** Pre TIP430 style zipfs prefix +** //zipfs:/ doesn't work straight out of the box on either windows or Unix +** without other changes made to tip 430 +*/ +#define ZIPFS_VOLUME "zipfs:/" +#define ZIPFS_VOLUME_LEN 7 +#define ZIPFS_APP_MOUNT "zipfs:/app" +#define ZIPFS_ZIP_MOUNT "zipfs:/lib/tcl" +#endif /* * Various constants and offsets found in ZIP archive files */ @@ -249,7 +267,7 @@ static const char pwrot[16] = { * Table to compute CRC32. */ -static const unsigned long crc32tab[256] = { +static const z_crc_t crc32tab[256] = { 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, @@ -307,6 +325,8 @@ static const unsigned long crc32tab[256] = { const char *zipfs_literal_tcl_library=NULL; /* Function prototypes */ +int TclZipfs_Mount(Tcl_Interp *interp, const char *zipname, const char *mntpt,const char *passwd); +static int TclZipfs_AppHook_FindTclInit(const char *archive); static int Zip_FSPathInFilesystemProc(Tcl_Obj *pathPtr, ClientData *clientDataPtr); static Tcl_Obj *Zip_FSFilesystemPathTypeProc(Tcl_Obj *pathPtr); static Tcl_Obj *Zip_FSFilesystemSeparatorProc(Tcl_Obj *pathPtr); @@ -2667,6 +2687,60 @@ ZipFSListObjCmd( return TCL_OK; } + +Tcl_Obj *TclZipfs_TclLibrary(void) { + if(zipfs_literal_tcl_library) { + return Tcl_NewStringObj(zipfs_literal_tcl_library,-1); + } else { + Tcl_Obj *vfsinitscript; + int found=0; + + /* Look for the library file system within the executable */ + vfsinitscript=Tcl_NewStringObj(ZIPFS_APP_MOUNT "/tcl_library/init.tcl",-1); + Tcl_IncrRefCount(vfsinitscript); + found=Tcl_FSAccess(vfsinitscript,F_OK); + Tcl_DecrRefCount(vfsinitscript); + if(found==TCL_OK) { + zipfs_literal_tcl_library=ZIPFS_APP_MOUNT "/tcl_library"; + return Tcl_NewStringObj(zipfs_literal_tcl_library,-1); + } +#if defined(_WIN32) || defined(_WIN64) + HMODULE hModule = TclWinGetTclInstance(); + WCHAR wName[MAX_PATH + LIBRARY_SIZE]; + char dllname[(MAX_PATH + LIBRARY_SIZE) * TCL_UTF_MAX]; + + if (GetModuleFileNameW(hModule, wName, MAX_PATH) == 0) { + GetModuleFileNameA(hModule, dllname, MAX_PATH); + } else { + ToUtf(wName, dllname); + } + /* Mount zip file and dll before releasing to search */ + if(TclZipfs_AppHook_FindTclInit(dllname)==TCL_OK) { + return Tcl_NewStringObj(zipfs_literal_tcl_library,-1); + } +#else +#ifdef CFG_RUNTIME_DLLFILE + /* Mount zip file and dll before releasing to search */ + if(TclZipfs_AppHook_FindTclInit(CFG_RUNTIME_LIBDIR "/" CFG_RUNTIME_DLLFILE)==TCL_OK) { + return Tcl_NewStringObj(zipfs_literal_tcl_library,-1); + } +#endif +#endif +#ifdef CFG_RUNTIME_ZIPFILE + if(TclZipfs_AppHook_FindTclInit(CFG_RUNTIME_LIBDIR "/" CFG_RUNTIME_ZIPFILE)==TCL_OK) { + return Tcl_NewStringObj(zipfs_literal_tcl_library,-1); + } + if(TclZipfs_AppHook_FindTclInit(CFG_RUNTIME_SCRDIR "/" CFG_RUNTIME_ZIPFILE)==TCL_OK) { + return Tcl_NewStringObj(zipfs_literal_tcl_library,-1); + } +#endif + } + if(zipfs_literal_tcl_library) { + return Tcl_NewStringObj(zipfs_literal_tcl_library,-1); + } + return NULL; +} + /* *------------------------------------------------------------------------- * @@ -4224,42 +4298,6 @@ int TclZipfs_AppHook(int *argc, char ***argv) return TCL_OK; } -Tcl_Obj *TclZipfs_TclLibrary(void) { - if(zipfs_literal_tcl_library) { - return Tcl_NewStringObj(zipfs_literal_tcl_library,-1); - } else { -#if defined(_WIN32) || defined(_WIN64) - HMODULE hModule = TclWinGetTclInstance(); - WCHAR wName[MAX_PATH + LIBRARY_SIZE]; - char dllname[(MAX_PATH + LIBRARY_SIZE) * TCL_UTF_MAX]; - - if (GetModuleFileNameW(hModule, wName, MAX_PATH) == 0) { - GetModuleFileNameA(hModule, dllname, MAX_PATH); - } else { - ToUtf(wName, dllname); - } - /* Mount zip file and dll before releasing to search */ - if(TclZipfs_AppHook_FindTclInit(dllname)==TCL_OK) { - return Tcl_NewStringObj(zipfs_literal_tcl_library,-1); - } -#else - /* Mount zip file and dll before releasing to search */ - if(TclZipfs_AppHook_FindTclInit(CFG_RUNTIME_LIBDIR "/" CFG_RUNTIME_DLLFILE)==TCL_OK) { - return Tcl_NewStringObj(zipfs_literal_tcl_library,-1); - } -#endif - if(TclZipfs_AppHook_FindTclInit(CFG_RUNTIME_LIBDIR "/" CFG_RUNTIME_ZIPFILE)==TCL_OK) { - return Tcl_NewStringObj(zipfs_literal_tcl_library,-1); - } - if(TclZipfs_AppHook_FindTclInit(CFG_RUNTIME_SCRDIR "/" CFG_RUNTIME_ZIPFILE)==TCL_OK) { - return Tcl_NewStringObj(zipfs_literal_tcl_library,-1); - } - } - if(zipfs_literal_tcl_library) { - return Tcl_NewStringObj(zipfs_literal_tcl_library,-1); - } - return NULL; -} #ifndef HAVE_ZLIB -- cgit v0.12 From a866c42f19f6a9824006d8113367245c7df75b01 Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Wed, 17 Jan 2018 01:09:07 +0000 Subject: Modifications to index zip file systems by mountpoint, and separate the process of mounting a zip archive from the process of indexing its contents. This work is progress towards being able to pass a data block to the zipfs system as a new file system to be mounted. --- doc/zipfs.3 | 6 +- doc/zipfs.n | 14 +-- generic/tclZipfs.c | 262 ++++++++++++++++++++++++++++------------------------- tests/zipfs.test | 9 +- 4 files changed, 155 insertions(+), 136 deletions(-) diff --git a/doc/zipfs.3 b/doc/zipfs.3 index b23afae..7514525 100644 --- a/doc/zipfs.3 +++ b/doc/zipfs.3 @@ -18,7 +18,7 @@ int \fBTclZipfs_AppHook(\fIint *argc, char ***argv\fR) .sp int -\fBTclzipfs_Mount\fR(\fIinterp, zipname, mntpt, passwd\fR) +\fBTclzipfs_Mount\fR(\fIinterp, mntpt, zipname, passwd\fR) .sp int \fBTclzipfs_Unmount\fR(\fIinterp, zipname\fR) @@ -55,12 +55,12 @@ or in the standard tcl install location. \fBTclzipfs_Mount()\fR mount the ZIP archive \fIzipname\fR on the mount point given in \fImntpt\fR using the optional ZIP password \fIpasswd\fR. Errors during that process are reported in the interpreter \fIinterp\fR. -If \fIzipname\fR is a NULL pointer, information on all currently mounted +If \fImountpoint\fR is a NULL pointer, information on all currently mounted ZIP file systems is written into \fIinterp\fR's result as a sequence of mount points and ZIP file names. .PP \fBTclzipfs_Unmount()\fR undoes the effect of \fBTclzipfs_Mount()\fR, -i.e. it unmounts the mounted ZIP archive file \fIzipname\fR. Errors are +i.e. it unmounts the mounted ZIP file system at \fImountpoint\fR. Errors are reported in the interpreter \fIinterp\fR. .SH KEYWORDS compress, filesystem, zip diff --git a/doc/zipfs.n b/doc/zipfs.n index a026b6d..31a0707 100644 --- a/doc/zipfs.n +++ b/doc/zipfs.n @@ -23,9 +23,9 @@ zipfs \- Mount and work with ZIP files within Tcl \fBzipfs mkimg\fR \fIoutfile\fR \fIindir\fR \fI?strip?\fR \fI?password?\fR \fI?infile?\fR \fBzipfs mkkey\fR \fIpassword\fR \fBzipfs mkzip\fR \fIoutfile\fR \fIindir\fR \fI?strip?\fR \fI?password?\fR -\fBzipfs mount\fR \fI?zipfile?\fR \fI?mountpoint?\fR \fI?password?\fR +\fBzipfs mount\fR \fI?mountpoint?\fR \fI?zipfile?\fR \fI?password?\fR \fBzipfs root\fR -\fBzipfs unmount\fR \fIzipfile\fR +\fBzipfs unmount\fR \fImountpoint\fR .fi .BE .SH DESCRIPTION @@ -96,15 +96,15 @@ Caution: the choice of the \fIindir\fR parameter archive's content. .RE .TP -\fBzipfs mount ?\fIzipfile\fR? ?\fImountpoint\fR? ?\fIpassword\fR? +\fBzipfs mount ?\fImountpoint\fR? ?\fIzipfile\fR? ?\fIpassword\fR? . The \fBzipfs mount\fR command mounts a ZIP archive file as a VFS. After this command executes, files contained in \fIzipfile\fR will appear to Tcl to be regular files at the mount point. .RS .PP -With no \fImountpoint\fR, returns the mount point for \fIzipfile\fR. -With no \fIzipfile\fR, return all zipfile/mount pairs. +With no \fIzipfile\fR, returns the zipfile mounted at \fImountpoint\fR. +With no \fImountpoint\fR, return all zipfile/mount pairs. If \fImountpoint\fR is specified as an empty string, mount on file path. .RE .TP @@ -113,9 +113,9 @@ Returns a constant string which indicates the mount point for zipfs volumes for the current platform. On Windows, this value is zipfs:/. On Unux, //zipfs:/ .RE .TP -\fBzipfs unmount \fIzipfile\fR +\fBzipfs unmount \fImountpoint\fR . -Unmounts a previously mounted ZIP archive file \fIzipfile\fR. +Unmounts a previously mounted ZIP archive mounted to \fImountpoint\fR. .SH "SEE ALSO" tclsh(1), file(n), zlib(n) .SH "KEYWORDS" diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c index 305fb7f..5be25c3 100644 --- a/generic/tclZipfs.c +++ b/generic/tclZipfs.c @@ -186,8 +186,8 @@ typedef struct ZipFile { #if HAS_DRIVES int mntdrv; /* Drive letter of mount point */ #endif - int mntptlen; /* Length of mount point */ - char mntpt[1]; /* Mount point */ + char *mntpt; /* Mount point */ + size_t mntptlen; } ZipFile; /* @@ -325,7 +325,7 @@ static const z_crc_t crc32tab[256] = { const char *zipfs_literal_tcl_library=NULL; /* Function prototypes */ -int TclZipfs_Mount(Tcl_Interp *interp, const char *zipname, const char *mntpt,const char *passwd); +int TclZipfs_Mount(Tcl_Interp *interp, const char *mntpt, const char *zipname, const char *passwd); static int TclZipfs_AppHook_FindTclInit(const char *archive); static int Zip_FSPathInFilesystemProc(Tcl_Obj *pathPtr, ClientData *clientDataPtr); static Tcl_Obj *Zip_FSFilesystemPathTypeProc(Tcl_Obj *pathPtr); @@ -942,7 +942,105 @@ ZipFSCloseArchive(Tcl_Interp *interp, ZipFile *zf) zf->chan = NULL; } } - + +/* + *------------------------------------------------------------------------- + * + * ZipFSIndexArchive -- + * + * This function takes a memory mapped zip file and indexes the contents. + * When "needZip" is zero an embedded ZIP archive in an executable file is accepted. + * + * Results: + * TCL_OK on success, TCL_ERROR otherwise with an error message + * placed into the given "interp" if it is not NULL. + * + * Side effects: + * The given ZipFile struct is filled with information about the ZIP archive file. + * + *------------------------------------------------------------------------- + */ +static int +ZipFSIndexArchive(Tcl_Interp *interp, int needZip, ZipFile *zf) +{ + int i; + unsigned char *p, *q; + p = zf->data + zf->length - ZIP_CENTRAL_END_LEN; + while (p >= zf->data) { + if (*p == (ZIP_CENTRAL_END_SIG & 0xFF)) { + if (zip_read_int(p) == ZIP_CENTRAL_END_SIG) { + break; + } + p -= ZIP_SIG_LEN; + } else { + --p; + } + } + if (p < zf->data) { + if (!needZip) { + zf->baseoffs = zf->baseoffsp = zf->length; + return TCL_OK; + } + ZIPFS_ERROR(interp,"wrong end signature"); + goto error; + } + zf->nfiles = zip_read_short(p + ZIP_CENTRAL_ENTS_OFFS); + if (zf->nfiles == 0) { + if (!needZip) { + zf->baseoffs = zf->baseoffsp = zf->length; + return TCL_OK; + } + ZIPFS_ERROR(interp,"empty archive"); + goto error; + } + q = zf->data + zip_read_int(p + ZIP_CENTRAL_DIRSTART_OFFS); + p -= zip_read_int(p + ZIP_CENTRAL_DIRSIZE_OFFS); + if ( + (p < zf->data) || (p > (zf->data + zf->length)) || + (q < zf->data) || (q > (zf->data + zf->length)) + ) { + if (!needZip) { + zf->baseoffs = zf->baseoffsp = zf->length; + return TCL_OK; + } + ZIPFS_ERROR(interp,"archive directory not found"); + goto error; + } + zf->baseoffs = zf->baseoffsp = p - q; + zf->centoffs = p - zf->data; + q = p; + for (i = 0; i < zf->nfiles; i++) { + int pathlen, comlen, extra; + + if ((q + ZIP_CENTRAL_HEADER_LEN) > (zf->data + zf->length)) { + ZIPFS_ERROR(interp,"wrong header length"); + goto error; + } + if (zip_read_int(q) != ZIP_CENTRAL_HEADER_SIG) { + ZIPFS_ERROR(interp,"wrong header signature"); + goto error; + } + pathlen = zip_read_short(q + ZIP_CENTRAL_PATHLEN_OFFS); + comlen = zip_read_short(q + ZIP_CENTRAL_FCOMMENTLEN_OFFS); + extra = zip_read_short(q + ZIP_CENTRAL_EXTRALEN_OFFS); + q += pathlen + comlen + extra + ZIP_CENTRAL_HEADER_LEN; + } + q = zf->data + zf->baseoffs; + if ((zf->baseoffs >= 6) && (zip_read_int(q - 4) == ZIP_PASSWORD_END_SIG)) { + i = q[-5]; + if (q - 5 - i > zf->data) { + zf->pwbuf[0] = i; + memcpy(zf->pwbuf + 1, q - 5 - i, i); + zf->baseoffsp -= i ? (5 + i) : 0; + } + } + return TCL_OK; + +error: + ZipFSCloseArchive(interp, zf); + return TCL_ERROR; +} + /* *------------------------------------------------------------------------- * @@ -967,12 +1065,10 @@ ZipFSCloseArchive(Tcl_Interp *interp, ZipFile *zf) */ static int -ZipFSOpenArchive(Tcl_Interp *interp, const char *zipname, int needZip, - ZipFile *zf) +ZipFSOpenArchive(Tcl_Interp *interp, const char *zipname, int needZip, ZipFile *zf) { int i; ClientData handle; - unsigned char *p, *q; #if defined(_WIN32) || defined(_WIN64) zf->data = NULL; @@ -1051,82 +1147,14 @@ ZipFSOpenArchive(Tcl_Interp *interp, const char *zipname, int needZip, } #endif } - p = zf->data + zf->length - ZIP_CENTRAL_END_LEN; - while (p >= zf->data) { - if (*p == (ZIP_CENTRAL_END_SIG & 0xFF)) { - if (zip_read_int(p) == ZIP_CENTRAL_END_SIG) { - break; - } - p -= ZIP_SIG_LEN; - } else { - --p; - } - } - if (p < zf->data) { - if (!needZip) { - zf->baseoffs = zf->baseoffsp = zf->length; - return TCL_OK; - } - ZIPFS_ERROR(interp,"wrong end signature"); - goto error; - } - zf->nfiles = zip_read_short(p + ZIP_CENTRAL_ENTS_OFFS); - if (zf->nfiles == 0) { - if (!needZip) { - zf->baseoffs = zf->baseoffsp = zf->length; - return TCL_OK; - } - ZIPFS_ERROR(interp,"empty archive"); - goto error; - } - q = zf->data + zip_read_int(p + ZIP_CENTRAL_DIRSTART_OFFS); - p -= zip_read_int(p + ZIP_CENTRAL_DIRSIZE_OFFS); - if ( - (p < zf->data) || (p > (zf->data + zf->length)) || - (q < zf->data) || (q > (zf->data + zf->length)) - ) { - if (!needZip) { - zf->baseoffs = zf->baseoffsp = zf->length; - return TCL_OK; - } - ZIPFS_ERROR(interp,"archive directory not found"); - goto error; - } - zf->baseoffs = zf->baseoffsp = p - q; - zf->centoffs = p - zf->data; - q = p; - for (i = 0; i < zf->nfiles; i++) { - int pathlen, comlen, extra; - - if ((q + ZIP_CENTRAL_HEADER_LEN) > (zf->data + zf->length)) { - ZIPFS_ERROR(interp,"wrong header length"); - goto error; - } - if (zip_read_int(q) != ZIP_CENTRAL_HEADER_SIG) { - ZIPFS_ERROR(interp,"wrong header signature"); - goto error; - } - pathlen = zip_read_short(q + ZIP_CENTRAL_PATHLEN_OFFS); - comlen = zip_read_short(q + ZIP_CENTRAL_FCOMMENTLEN_OFFS); - extra = zip_read_short(q + ZIP_CENTRAL_EXTRALEN_OFFS); - q += pathlen + comlen + extra + ZIP_CENTRAL_HEADER_LEN; - } - q = zf->data + zf->baseoffs; - if ((zf->baseoffs >= 6) && (zip_read_int(q - 4) == ZIP_PASSWORD_END_SIG)) { - i = q[-5]; - if (q - 5 - i > zf->data) { - zf->pwbuf[0] = i; - memcpy(zf->pwbuf + 1, q - 5 - i, i); - zf->baseoffsp -= i ? (5 + i) : 0; - } - } - return TCL_OK; + return ZipFSIndexArchive(interp,needZip,zf); error: ZipFSCloseArchive(interp, zf); return TCL_ERROR; } + static void TclZipfs_C_Init(void) { static const Tcl_Time t = { 0, 0 }; if (!ZipFS.initialized) { @@ -1166,8 +1194,9 @@ static void TclZipfs_C_Init(void) { int TclZipfs_Mount( - Tcl_Interp *interp, const char *zipname, + Tcl_Interp *interp, const char *mntpt, + const char *zipname, const char *passwd ) { char *realname, *p; @@ -1185,7 +1214,7 @@ TclZipfs_Mount( if (!ZipFS.initialized) { TclZipfs_C_Init(); } - if (zipname == NULL) { + if (mntpt == NULL) { Tcl_HashSearch search; int ret = TCL_OK; @@ -1207,36 +1236,26 @@ TclZipfs_Mount( Unlock(); return ret; } - if (mntpt == NULL) { + /* + * Mount point sometimes is a relative or otherwise denormalized path. + * But an absolute name is needed as mount point here. + */ + Tcl_DStringInit(&dsm); + mntpt = CanonicalPath("",mntpt, &dsm, 1); + + if (zipname == NULL) { if (interp == NULL) { Unlock(); return TCL_OK; } + Tcl_DStringInit(&ds); -#if HAS_DRIVES - p = AbsolutePath(zipname, &drive, &ds); -#else - p = AbsolutePath(zipname, &ds); -#endif - hPtr = Tcl_FindHashEntry(&ZipFS.zipHash, p); + + hPtr = Tcl_FindHashEntry(&ZipFS.zipHash, mntpt); if (hPtr != NULL) { -#if HAS_DRIVES - if (drive == zf->mntdrv) { - Tcl_Obj *string; - char drvbuf[3]; - - drvbuf[0] = zf->mntdrv; - drvbuf[1] = ':'; - drvbuf[2] = '\0'; - string = Tcl_NewStringObj(drvbuf, 2); - Tcl_AppendToObj(string, zf->mntpt, zf->mntptlen); - Tcl_SetObjResult(interp, string); - } -#else if ((zf = Tcl_GetHashValue(hPtr)) != NULL) { - Tcl_SetObjResult(interp,Tcl_NewStringObj(zf->mntpt, zf->mntptlen)); + Tcl_SetObjResult(interp,Tcl_NewStringObj(zf->name, -1)); } -#endif } Unlock(); return TCL_OK; @@ -1262,20 +1281,13 @@ TclZipfs_Mount( #else realname = AbsolutePath(zipname, &ds); #endif - /* - * Mount point sometimes is a relative or otherwise denormalized path. - * But an absolute name is needed as mount point here. - */ - Tcl_DStringInit(&dsm); - mntpt = CanonicalPath("",mntpt, &dsm, 1); WriteLock(); - hPtr = Tcl_CreateHashEntry(&ZipFS.zipHash, zipname, &isNew); + hPtr = Tcl_CreateHashEntry(&ZipFS.zipHash, mntpt, &isNew); if (!isNew) { zf = (ZipFile *) Tcl_GetHashValue(hPtr); if (interp != NULL) { - Tcl_AppendResult(interp, "already mounted on \"", zf->mntptlen ? - zf->mntpt : "/", "\"", (char *) NULL); + Tcl_AppendResult(interp, zf->name, " is already mounted on ", mntpt, (char *) NULL); } Unlock(); ZipFSCloseArchive(interp, &zf0); @@ -1294,9 +1306,9 @@ TclZipfs_Mount( return TCL_ERROR; } *zf = zf0; - zf->name = Tcl_GetHashKey(&ZipFS.zipHash, hPtr); - strcpy(zf->mntpt, mntpt); - zf->mntptlen = strlen(zf->mntpt); + zf->mntpt = Tcl_GetHashKey(&ZipFS.zipHash, hPtr); + zf->mntptlen=strlen(zf->mntpt); + zf->name = strdup(zipname); zf->entries = NULL; zf->topents = NULL; zf->nopen = 0; @@ -1526,17 +1538,24 @@ nextent: */ int -TclZipfs_Unmount(Tcl_Interp *interp, const char *zipname) +TclZipfs_Unmount(Tcl_Interp *interp, const char *mntpt) { ZipFile *zf; ZipEntry *z, *znext; Tcl_HashEntry *hPtr; + Tcl_DString dsm; int ret = TCL_OK, unmounted = 0; WriteLock(); if (!ZipFS.initialized) goto done; - - hPtr = Tcl_FindHashEntry(&ZipFS.zipHash, zipname); + /* + * Mount point sometimes is a relative or otherwise denormalized path. + * But an absolute name is needed as mount point here. + */ + Tcl_DStringInit(&dsm); + mntpt = CanonicalPath("", mntpt, &dsm, 1); + + hPtr = Tcl_FindHashEntry(&ZipFS.zipHash, mntpt); /* don't report error */ if (hPtr == NULL) goto done; @@ -1560,6 +1579,7 @@ TclZipfs_Unmount(Tcl_Interp *interp, const char *zipname) Tcl_Free((char *) z); } ZipFSCloseArchive(interp, zf); + free(zf->name); //Allocated by strdup Tcl_Free((char *) zf); unmounted = 1; done: @@ -3906,7 +3926,7 @@ Zip_FSFileAttrsGetProc(Tcl_Interp *interp, int index, Tcl_Obj *pathPtr, *objPtrRef= Tcl_NewLongObj(z->offset); goto done; case 3: - *objPtrRef= Tcl_NewStringObj(z->zipfile->mntpt, -1); + *objPtrRef= Tcl_NewStringObj(z->zipfile->mntpt, z->zipfile->mntptlen); goto done; case 4: *objPtrRef= Tcl_NewStringObj(z->zipfile->name, -1); @@ -4189,7 +4209,7 @@ static int TclZipfs_AppHook_FindTclInit(const char *archive){ if(zipfs_literal_tcl_library) { return TCL_ERROR; } - if(TclZipfs_Mount(NULL, archive, ZIPFS_ZIP_MOUNT, NULL)) { + if(TclZipfs_Mount(NULL, ZIPFS_ZIP_MOUNT, archive, NULL)) { /* Either the file doesn't exist or it is not a zip archive */ return TCL_ERROR; } @@ -4230,7 +4250,7 @@ int TclZipfs_AppHook(int *argc, char ***argv) /* ** Look for init.tcl in one of the locations mounted later in this function */ - if(!TclZipfs_Mount(NULL, archive, ZIPFS_APP_MOUNT, NULL)) { + if(!TclZipfs_Mount(NULL, ZIPFS_APP_MOUNT, archive, NULL)) { int found; Tcl_Obj *vfsinitscript; vfsinitscript=Tcl_NewStringObj(ZIPFS_APP_MOUNT "/main.tcl",-1); @@ -4272,7 +4292,7 @@ int TclZipfs_AppHook(int *argc, char ***argv) } return TCL_OK; } else { - if(!TclZipfs_Mount(NULL, archive, ZIPFS_APP_MOUNT, NULL)) { + if(!TclZipfs_Mount(NULL, ZIPFS_APP_MOUNT, archive, NULL)) { int found; Tcl_Obj *vfsinitscript; vfsinitscript=Tcl_NewStringObj(ZIPFS_APP_MOUNT "/main.tcl",-1); @@ -4313,7 +4333,7 @@ int TclZipfs_AppHook(int *argc, char ***argv) */ int -TclZipfs_Mount(Tcl_Interp *interp, const char *zipname, const char *mntpt, +TclZipfs_Mount(Tcl_Interp *interp, const char *mntpt, const char *zipname, const char *passwd) { return TclZipfs_Init(interp, 1); diff --git a/tests/zipfs.test b/tests/zipfs.test index c9dd0ac..060e4a6 100644 --- a/tests/zipfs.test +++ b/tests/zipfs.test @@ -27,7 +27,6 @@ set CWD [pwd] set tmpdir [file join $CWD tmp] file mkdir $tmpdir - test zipfs-0.1 {zipfs basics} -constraints zipfs -body { package require zipfs } -result {2.0} @@ -45,7 +44,7 @@ if {![string match ${ziproot}* $tcl_library]} { ### set tclzip [file join $CWD [::tcl::pkgconfig get zipfile,runtime]] if {[file exists $tclzip]} { - zipfs mount $tclzip /lib/tcl + zipfs mount /lib/tcl $tclzip set ::tcl_library ${ziproot}lib/tcl/tcl_library } else { tcltest::skip zipfs-0.* @@ -154,7 +153,7 @@ if {[file exists $zipfile]} { test zipfs-2.2.0 {zipfs mkzip} -constraints zipfs -body { cd $tcl_library/encoding zipfs mkzip $zipfile . - zipfs mount $zipfile ${ziproot}abc + zipfs mount ${ziproot}abc $zipfile zipfs list -glob ${ziproot}abc/cp850.* } -cleanup { cd $CWD @@ -202,12 +201,12 @@ test zipfs-2.2.4 {zipfs exists} -constraints zipfs -body { } -result 1 test zipfs-2.2.5 {zipfs unmount while busy} -constraints zipfs -body { - zipfs unmount $zipfile + zipfs unmount /abc } -returnCodes error -result {filesystem is busy} test zipfs-2.2.6 {zipfs unmount} -constraints zipfs -body { close $zipfd - zipfs unmount $zipfile + zipfs unmount /abc zipfs exists /abc/cp850.enc } -result 0 -- cgit v0.12 From 608373fcb170fe76512b46c7ce07cc0691720ae5 Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Wed, 17 Jan 2018 15:56:32 +0000 Subject: Modifications to allow the mounting of zip file systems from data blocks Added a new stubs entry to mount a data block as a zip file system --- generic/tcl.decls | 15 +- generic/tclDecls.h | 14 +- generic/tclStubInit.c | 1 + generic/tclZipfs.c | 493 +++++++++++++++++++++++++++++++++++++------------- tests/zipfs.test | 73 +++++++- 5 files changed, 458 insertions(+), 138 deletions(-) diff --git a/generic/tcl.decls b/generic/tcl.decls index 87beab3..8d03db1 100644 --- a/generic/tcl.decls +++ b/generic/tcl.decls @@ -2334,8 +2334,11 @@ declare 631 { # TIP #430 declare 632 { - int TclZipfs_Mount(Tcl_Interp *interp, const char *zipname, const char *mntpt, - const char *passwd) + int TclZipfs_Mount( + Tcl_Interp *interp, + const char *mntpt, + const char *zipname, + const char *passwd) } declare 633 { int TclZipfs_Unmount(Tcl_Interp *interp, const char *zipname) @@ -2343,6 +2346,14 @@ declare 633 { declare 634 { Tcl_Obj *TclZipfs_TclLibrary(void) } +declare 635 { + int TclZipfs_Mount_Buffer( + Tcl_Interp *interp, + const char *mntpt, + unsigned char *data, + size_t datalen, + int copy) +} ############################################################################## # Define the platform specific public Tcl interface. These functions are only diff --git a/generic/tclDecls.h b/generic/tclDecls.h index 8ba9e5c..40fa7e2 100644 --- a/generic/tclDecls.h +++ b/generic/tclDecls.h @@ -1839,14 +1839,17 @@ EXTERN Tcl_Channel Tcl_OpenTcpServerEx(Tcl_Interp *interp, Tcl_TcpAcceptProc *acceptProc, ClientData callbackData); /* 632 */ -EXTERN int TclZipfs_Mount(Tcl_Interp *interp, - const char *zipname, const char *mntpt, - const char *passwd); +EXTERN int TclZipfs_Mount(Tcl_Interp *interp, const char *mntpt, + const char *zipname, const char *passwd); /* 633 */ EXTERN int TclZipfs_Unmount(Tcl_Interp *interp, const char *zipname); /* 634 */ EXTERN Tcl_Obj * TclZipfs_TclLibrary(void); +/* 635 */ +EXTERN int TclZipfs_Mount_Buffer(Tcl_Interp *interp, + const char *mntpt, unsigned char *data, + size_t datalen, int copy); typedef struct { const struct TclPlatStubs *tclPlatStubs; @@ -2514,9 +2517,10 @@ typedef struct TclStubs { int (*tcl_FSUnloadFile) (Tcl_Interp *interp, Tcl_LoadHandle handlePtr); /* 629 */ void (*tcl_ZlibStreamSetCompressionDictionary) (Tcl_ZlibStream zhandle, Tcl_Obj *compressionDictionaryObj); /* 630 */ Tcl_Channel (*tcl_OpenTcpServerEx) (Tcl_Interp *interp, const char *service, const char *host, unsigned int flags, Tcl_TcpAcceptProc *acceptProc, ClientData callbackData); /* 631 */ - int (*tclZipfs_Mount) (Tcl_Interp *interp, const char *zipname, const char *mntpt, const char *passwd); /* 632 */ + int (*tclZipfs_Mount) (Tcl_Interp *interp, const char *mntpt, const char *zipname, const char *passwd); /* 632 */ int (*tclZipfs_Unmount) (Tcl_Interp *interp, const char *zipname); /* 633 */ Tcl_Obj * (*tclZipfs_TclLibrary) (void); /* 634 */ + int (*tclZipfs_Mount_Buffer) (Tcl_Interp *interp, const char *mntpt, unsigned char *data, size_t datalen, int copy); /* 635 */ } TclStubs; extern const TclStubs *tclStubsPtr; @@ -3817,6 +3821,8 @@ extern const TclStubs *tclStubsPtr; (tclStubsPtr->tclZipfs_Unmount) /* 633 */ #define TclZipfs_TclLibrary \ (tclStubsPtr->tclZipfs_TclLibrary) /* 634 */ +#define TclZipfs_Mount_Buffer \ + (tclStubsPtr->tclZipfs_Mount_Buffer) /* 635 */ #endif /* defined(USE_TCL_STUBS) */ diff --git a/generic/tclStubInit.c b/generic/tclStubInit.c index fdc8aec..28d26a6 100644 --- a/generic/tclStubInit.c +++ b/generic/tclStubInit.c @@ -1616,6 +1616,7 @@ const TclStubs tclStubs = { TclZipfs_Mount, /* 632 */ TclZipfs_Unmount, /* 633 */ TclZipfs_TclLibrary, /* 634 */ + TclZipfs_Mount_Buffer, /* 635 */ }; /* !END!: Do not edit above this line. */ diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c index 5be25c3..b81c58f 100644 --- a/generic/tclZipfs.c +++ b/generic/tclZipfs.c @@ -168,6 +168,8 @@ TCL_DECLARE_MUTEX(localtimeMutex) typedef struct ZipFile { char *name; /* Archive name */ + size_t namelen; + char is_membuf; /* When true, not a file but a memory buffer */ Tcl_Channel chan; /* Channel handle or NULL */ unsigned char *data; /* Memory mapped or malloc'ed file */ long length; /* Length of memory mapped file */ @@ -186,8 +188,8 @@ typedef struct ZipFile { #if HAS_DRIVES int mntdrv; /* Drive letter of mount point */ #endif - char *mntpt; /* Mount point */ - size_t mntptlen; + int mntptlen; + char *mntpt; /* Mount point */ } ZipFile; /* @@ -325,7 +327,19 @@ static const z_crc_t crc32tab[256] = { const char *zipfs_literal_tcl_library=NULL; /* Function prototypes */ -int TclZipfs_Mount(Tcl_Interp *interp, const char *mntpt, const char *zipname, const char *passwd); +int TclZipfs_Mount( + Tcl_Interp *interp, + const char *mntpt, + const char *zipname, + const char *passwd +); +int TclZipfs_Mount_Buffer( + Tcl_Interp *interp, + const char *mntpt, + unsigned char *data, + size_t datalen, + int copy +); static int TclZipfs_AppHook_FindTclInit(const char *archive); static int Zip_FSPathInFilesystemProc(Tcl_Obj *pathPtr, ClientData *clientDataPtr); static Tcl_Obj *Zip_FSFilesystemPathTypeProc(Tcl_Obj *pathPtr); @@ -919,6 +933,18 @@ ZipFSLookupMount(char *filename) static void ZipFSCloseArchive(Tcl_Interp *interp, ZipFile *zf) { + if(zf->namelen) { + free(zf->name); //Allocated by strdup + } + if(zf->is_membuf==1) { + /* Pointer to memory */ + if (zf->tofree != NULL) { + Tcl_Free((char *) zf->tofree); + zf->tofree = NULL; + } + zf->data = NULL; + return; + } #if defined(_WIN32) || defined(_WIN64) if ((zf->data != NULL) && (zf->tofree == NULL)) { UnmapViewOfFile(zf->data); @@ -946,7 +972,7 @@ ZipFSCloseArchive(Tcl_Interp *interp, ZipFile *zf) /* *------------------------------------------------------------------------- * - * ZipFSIndexArchive -- + * ZipFS_Find_TOC -- * * This function takes a memory mapped zip file and indexes the contents. * When "needZip" is zero an embedded ZIP archive in an executable file is accepted. @@ -961,7 +987,7 @@ ZipFSCloseArchive(Tcl_Interp *interp, ZipFile *zf) *------------------------------------------------------------------------- */ static int -ZipFSIndexArchive(Tcl_Interp *interp, int needZip, ZipFile *zf) +ZipFS_Find_TOC(Tcl_Interp *interp, int needZip, ZipFile *zf) { int i; unsigned char *p, *q; @@ -1034,6 +1060,7 @@ ZipFSIndexArchive(Tcl_Interp *interp, int needZip, ZipFile *zf) zf->baseoffsp -= i ? (5 + i) : 0; } } + return TCL_OK; error: @@ -1069,7 +1096,8 @@ ZipFSOpenArchive(Tcl_Interp *interp, const char *zipname, int needZip, ZipFile * { int i; ClientData handle; - + + zf->is_membuf=0; #if defined(_WIN32) || defined(_WIN64) zf->data = NULL; zf->mh = INVALID_HANDLE_VALUE; @@ -1147,61 +1175,33 @@ ZipFSOpenArchive(Tcl_Interp *interp, const char *zipname, int needZip, ZipFile * } #endif } - return ZipFSIndexArchive(interp,needZip,zf); + return ZipFS_Find_TOC(interp,needZip,zf); error: ZipFSCloseArchive(interp, zf); return TCL_ERROR; } - -static void TclZipfs_C_Init(void) { - static const Tcl_Time t = { 0, 0 }; - if (!ZipFS.initialized) { -#ifdef TCL_THREADS - /* - * Inflate condition variable. - */ - Tcl_MutexLock(&ZipFSMutex); - Tcl_ConditionWait(&ZipFSCond, &ZipFSMutex, &t); - Tcl_MutexUnlock(&ZipFSMutex); -#endif - Tcl_FSRegister(NULL, &zipfsFilesystem); - Tcl_InitHashTable(&ZipFS.fileHash, TCL_STRING_KEYS); - Tcl_InitHashTable(&ZipFS.zipHash, TCL_STRING_KEYS); - ZipFS.initialized = ZipFS.idCount = 1; - } -} - - /* *------------------------------------------------------------------------- * - * TclZipfs_Mount -- + * ZipFSRootNode -- * - * This procedure is invoked to mount a given ZIP archive file on - * a given mountpoint with optional ZIP password. + * This function generates the root node for a ZIPFS filesystem * * Results: - * A standard Tcl result. + * TCL_OK on success, TCL_ERROR otherwise with an error message + * placed into the given "interp" if it is not NULL. * * Side effects: - * A ZIP archive file is read, analyzed and mounted, resources are - * allocated. - * *------------------------------------------------------------------------- */ -int -TclZipfs_Mount( - Tcl_Interp *interp, - const char *mntpt, - const char *zipname, - const char *passwd -) { - char *realname, *p; +static int +ZipFS_Catalogue_Filesystem(Tcl_Interp *interp, ZipFile *zf0, const char *mntpt, const char *passwd, const char *zipname) +{ int i, pwlen, isNew; - ZipFile *zf, zf0; + ZipFile *zf; ZipEntry *z; Tcl_HashEntry *hPtr; Tcl_DString ds, dsm, fpBuf; @@ -1209,58 +1209,8 @@ TclZipfs_Mount( #if HAS_DRIVES int drive = 0; #endif - - ReadLock(); - if (!ZipFS.initialized) { - TclZipfs_C_Init(); - } - if (mntpt == NULL) { - Tcl_HashSearch search; - int ret = TCL_OK; - - i = 0; - hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); - while (hPtr != NULL) { - if ((zf = (ZipFile *) Tcl_GetHashValue(hPtr)) != NULL) { - if (interp != NULL) { - Tcl_AppendElement(interp, zf->mntpt); - Tcl_AppendElement(interp, zf->name); - } - ++i; - } - hPtr = Tcl_NextHashEntry(&search); - } - if (interp == NULL) { - ret = (i > 0) ? TCL_OK : TCL_BREAK; - } - Unlock(); - return ret; - } - /* - * Mount point sometimes is a relative or otherwise denormalized path. - * But an absolute name is needed as mount point here. - */ - Tcl_DStringInit(&dsm); - mntpt = CanonicalPath("",mntpt, &dsm, 1); + WriteLock(); - if (zipname == NULL) { - if (interp == NULL) { - Unlock(); - return TCL_OK; - } - - Tcl_DStringInit(&ds); - - hPtr = Tcl_FindHashEntry(&ZipFS.zipHash, mntpt); - if (hPtr != NULL) { - if ((zf = Tcl_GetHashValue(hPtr)) != NULL) { - Tcl_SetObjResult(interp,Tcl_NewStringObj(zf->name, -1)); - } - } - Unlock(); - return TCL_OK; - } - Unlock(); pwlen = 0; if (passwd != NULL) { pwlen = strlen(passwd); @@ -1272,17 +1222,17 @@ TclZipfs_Mount( return TCL_ERROR; } } - if (ZipFSOpenArchive(interp, zipname, 1, &zf0) != TCL_OK) { - return TCL_ERROR; - } + /* + * Mount point sometimes is a relative or otherwise denormalized path. + * But an absolute name is needed as mount point here. + */ Tcl_DStringInit(&ds); -#if HAS_DRIVES - realname = AbsolutePath(zipname, NULL, &ds); -#else - realname = AbsolutePath(zipname, &ds); -#endif - - WriteLock(); + Tcl_DStringInit(&dsm); + if (strcmp(mntpt, "/") == 0) { + mntpt = ""; + } else { + mntpt = CanonicalPath("",mntpt, &dsm, 1); + } hPtr = Tcl_CreateHashEntry(&ZipFS.zipHash, mntpt, &isNew); if (!isNew) { zf = (ZipFile *) Tcl_GetHashValue(hPtr); @@ -1290,30 +1240,29 @@ TclZipfs_Mount( Tcl_AppendResult(interp, zf->name, " is already mounted on ", mntpt, (char *) NULL); } Unlock(); - ZipFSCloseArchive(interp, &zf0); + ZipFSCloseArchive(interp, zf0); return TCL_ERROR; } - if (strcmp(mntpt, "/") == 0) { - mntpt = ""; - } zf = (ZipFile *) Tcl_AttemptAlloc(sizeof (*zf) + strlen(mntpt) + 1); if (zf == NULL) { if (interp != NULL) { Tcl_AppendResult(interp, "out of memory", (char *) NULL); } Unlock(); - ZipFSCloseArchive(interp, &zf0); + ZipFSCloseArchive(interp, zf0); return TCL_ERROR; - } - *zf = zf0; - zf->mntpt = Tcl_GetHashKey(&ZipFS.zipHash, hPtr); - zf->mntptlen=strlen(zf->mntpt); - zf->name = strdup(zipname); - zf->entries = NULL; - zf->topents = NULL; - zf->nopen = 0; - Tcl_SetHashValue(hPtr, (ClientData) zf); - if ((zf->pwbuf[0] == 0) && pwlen) { + } + Unlock(); + *zf = *zf0; + zf->mntpt = Tcl_GetHashKey(&ZipFS.zipHash, hPtr); + zf->mntptlen=strlen(zf->mntpt); + zf->name = strdup(zipname); + zf->namelen= strlen(zipname); + zf->entries = NULL; + zf->topents = NULL; + zf->nopen = 0; + Tcl_SetHashValue(hPtr, (ClientData) zf); + if ((zf->pwbuf[0] == 0) && pwlen) { int k = 0; i = pwlen; zf->pwbuf[k++] = i; @@ -1352,7 +1301,6 @@ TclZipfs_Mount( } q = zf->data + zf->centoffs; Tcl_DStringInit(&fpBuf); - Tcl_DStringInit(&ds); for (i = 0; i < zf->nfiles; i++) { int pathlen, comlen, extra, isdir = 0, dosTime, dosDate, nbcompr, offs; unsigned char *lq, *gq = NULL; @@ -1514,12 +1462,229 @@ TclZipfs_Mount( nextent: q += pathlen + comlen + extra + ZIP_CENTRAL_HEADER_LEN; } - Unlock(); Tcl_DStringFree(&fpBuf); Tcl_DStringFree(&ds); Tcl_FSMountsChanged(NULL); + Unlock(); return TCL_OK; } + +static void TclZipfs_C_Init(void) { + static const Tcl_Time t = { 0, 0 }; + if (!ZipFS.initialized) { +#ifdef TCL_THREADS + /* + * Inflate condition variable. + */ + Tcl_MutexLock(&ZipFSMutex); + Tcl_ConditionWait(&ZipFSCond, &ZipFSMutex, &t); + Tcl_MutexUnlock(&ZipFSMutex); +#endif + Tcl_FSRegister(NULL, &zipfsFilesystem); + Tcl_InitHashTable(&ZipFS.fileHash, TCL_STRING_KEYS); + Tcl_InitHashTable(&ZipFS.zipHash, TCL_STRING_KEYS); + ZipFS.initialized = ZipFS.idCount = 1; + } +} + + +/* + *------------------------------------------------------------------------- + * + * TclZipfs_Mount -- + * + * This procedure is invoked to mount a given ZIP archive file on + * a given mountpoint with optional ZIP password. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * A ZIP archive file is read, analyzed and mounted, resources are + * allocated. + * + *------------------------------------------------------------------------- + */ + +int +TclZipfs_Mount( + Tcl_Interp *interp, + const char *mntpt, + const char *zipname, + const char *passwd +) { + int i, pwlen; + ZipFile *zf; + + ReadLock(); + if (!ZipFS.initialized) { + TclZipfs_C_Init(); + } + if (mntpt == NULL) { + Tcl_HashEntry *hPtr; + Tcl_HashSearch search; + int ret = TCL_OK; + i = 0; + hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); + while (hPtr != NULL) { + if ((zf = (ZipFile *) Tcl_GetHashValue(hPtr)) != NULL) { + if (interp != NULL) { + Tcl_AppendElement(interp, zf->mntpt); + Tcl_AppendElement(interp, zf->name); + } + ++i; + } + hPtr = Tcl_NextHashEntry(&search); + } + if (interp == NULL) { + ret = (i > 0) ? TCL_OK : TCL_BREAK; + } + Unlock(); + return ret; + } + + if (zipname == NULL) { + Tcl_HashEntry *hPtr; + if (interp == NULL) { + Unlock(); + return TCL_OK; + } + hPtr = Tcl_FindHashEntry(&ZipFS.zipHash, mntpt); + if (hPtr != NULL) { + if ((zf = Tcl_GetHashValue(hPtr)) != NULL) { + Tcl_SetObjResult(interp,Tcl_NewStringObj(zf->name, -1)); + } + } + Unlock(); + return TCL_OK; + } + Unlock(); + pwlen = 0; + if (passwd != NULL) { + pwlen = strlen(passwd); + if ((pwlen > 255) || (strchr(passwd, 0xff) != NULL)) { + if (interp) { + Tcl_SetObjResult(interp, + Tcl_NewStringObj("illegal password", -1)); + } + return TCL_ERROR; + } + } + zf = (ZipFile *) Tcl_AttemptAlloc(sizeof (*zf) + strlen(mntpt) + 1); + if (zf == NULL) { + if (interp != NULL) { + Tcl_AppendResult(interp, "out of memory", (char *) NULL); + } + return TCL_ERROR; + } + if (ZipFSOpenArchive(interp, zipname, 1, zf) != TCL_OK) { + return TCL_ERROR; + } + return ZipFS_Catalogue_Filesystem(interp,zf,mntpt,passwd,zipname); +} + +/* + *------------------------------------------------------------------------- + * + * TclZipfs_Mount_Buffer -- + * + * This procedure is invoked to mount a given ZIP archive file on + * a given mountpoint with optional ZIP password. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * A ZIP archive file is read, analyzed and mounted, resources are + * allocated. + * + *------------------------------------------------------------------------- + */ + +int +TclZipfs_Mount_Buffer( + Tcl_Interp *interp, + const char *mntpt, + unsigned char *data, + size_t datalen, + int copy +) { + int i; + ZipFile *zf; + + ReadLock(); + if (!ZipFS.initialized) { + TclZipfs_C_Init(); + } + if (mntpt == NULL) { + Tcl_HashEntry *hPtr; + Tcl_HashSearch search; + int ret = TCL_OK; + + i = 0; + hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); + while (hPtr != NULL) { + if ((zf = (ZipFile *) Tcl_GetHashValue(hPtr)) != NULL) { + if (interp != NULL) { + Tcl_AppendElement(interp, zf->mntpt); + Tcl_AppendElement(interp, zf->name); + } + ++i; + } + hPtr = Tcl_NextHashEntry(&search); + } + if (interp == NULL) { + ret = (i > 0) ? TCL_OK : TCL_BREAK; + } + Unlock(); + return ret; + } + + if (data == NULL) { + Tcl_HashEntry *hPtr; + + if (interp == NULL) { + Unlock(); + return TCL_OK; + } + hPtr = Tcl_FindHashEntry(&ZipFS.zipHash, mntpt); + if (hPtr != NULL) { + if ((zf = Tcl_GetHashValue(hPtr)) != NULL) { + Tcl_SetObjResult(interp,Tcl_NewStringObj(zf->name, -1)); + } + } + Unlock(); + return TCL_OK; + } + Unlock(); + zf = (ZipFile *) Tcl_AttemptAlloc(sizeof (*zf) + strlen(mntpt) + 1); + if (zf == NULL) { + if (interp != NULL) { + Tcl_AppendResult(interp, "out of memory", (char *) NULL); + } + return TCL_ERROR; + } + zf->is_membuf=1; + zf->length=datalen; + if(copy) { + zf->data=(unsigned char *)Tcl_AttemptAlloc(datalen); + if (zf->data == NULL) { + if (interp != NULL) { + Tcl_AppendResult(interp, "out of memory", (char *) NULL); + } + return TCL_ERROR; + } + memcpy(zf->data,data,datalen); + zf->tofree=zf->data; + } else { + zf->data=data; + zf->tofree=NULL; + } + if(ZipFS_Find_TOC(interp,0,zf)!=TCL_OK) { + return TCL_ERROR; + } + return ZipFS_Catalogue_Filesystem(interp,zf,mntpt,NULL,"Memory Buffer"); +} /* *------------------------------------------------------------------------- @@ -1579,7 +1744,6 @@ TclZipfs_Unmount(Tcl_Interp *interp, const char *mntpt) Tcl_Free((char *) z); } ZipFSCloseArchive(interp, zf); - free(zf->name); //Allocated by strdup Tcl_Free((char *) zf); unmounted = 1; done: @@ -1612,13 +1776,88 @@ ZipFSMountObjCmd( ) { if (objc > 4) { Tcl_WrongNumArgs(interp, 1, objv, - "?zipfile? ?mountpoint? ?password?"); + "?mountpoint? ?zipfile? ?password?"); return TCL_ERROR; } return TclZipfs_Mount(interp, (objc > 1) ? Tcl_GetString(objv[1]) : NULL, (objc > 2) ? Tcl_GetString(objv[2]) : NULL, (objc > 3) ? Tcl_GetString(objv[3]) : NULL); } + +/* + *------------------------------------------------------------------------- + * + * ZipFSMountObjCmd -- + * + * This procedure is invoked to process the "zipfs::mount" command. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * A ZIP archive file is mounted, resources are allocated. + * + *------------------------------------------------------------------------- + */ + +static int +ZipFSMountBufferObjCmd( + ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[] +) { + const char *mntpt; + unsigned char *data; + int length; + if (objc > 4) { + Tcl_WrongNumArgs(interp, 1, objv, "?mountpoint? ?data?"); + return TCL_ERROR; + } + if(objc<2) { + int i; + Tcl_HashEntry *hPtr; + Tcl_HashSearch search; + int ret = TCL_OK; + ZipFile *zf; + + ReadLock(); + i = 0; + hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); + while (hPtr != NULL) { + if ((zf = (ZipFile *) Tcl_GetHashValue(hPtr)) != NULL) { + if (interp != NULL) { + Tcl_AppendElement(interp, zf->mntpt); + Tcl_AppendElement(interp, zf->name); + } + ++i; + } + hPtr = Tcl_NextHashEntry(&search); + } + if (interp == NULL) { + ret = (i > 0) ? TCL_OK : TCL_BREAK; + } + Unlock(); + return ret; + } + mntpt=Tcl_GetString(objv[1]); + if(objc<3) { + Tcl_HashEntry *hPtr; + ZipFile *zf; + + if (interp == NULL) { + Unlock(); + return TCL_OK; + } + hPtr = Tcl_FindHashEntry(&ZipFS.zipHash, mntpt); + if (hPtr != NULL) { + if ((zf = Tcl_GetHashValue(hPtr)) != NULL) { + Tcl_SetObjResult(interp,Tcl_NewStringObj(zf->name, -1)); + } + } + Unlock(); + return TCL_OK; + } + data=Tcl_GetByteArrayFromObj(objv[2],&length); + return TclZipfs_Mount_Buffer(interp, mntpt,data,length,1); +} /* *------------------------------------------------------------------------- @@ -2477,11 +2716,10 @@ ZipFSLMkImgObjCmd(ClientData clientData, Tcl_Interp *interp, /* *------------------------------------------------------------------------- * - * ZipFSExistsObjCmd -- + * ZipFSCanonicalObjCmd -- * - * This procedure is invoked to process the "zipfs::exists" command. - * It tests for the existence of a file in the ZIP filesystem and - * places a boolean into the interp's result. + * This procedure is invoked to process the "zipfs::canonical" command. + * It returns the canonical name for a file within zipfs * * Results: * Always TCL_OK. @@ -4137,6 +4375,7 @@ TclZipfs_Init(Tcl_Interp *interp) if(interp != NULL) { static const EnsembleImplMap initMap[] = { {"mount", ZipFSMountObjCmd, NULL, NULL, NULL, 0}, + {"mount_data", ZipFSMountBufferObjCmd, NULL, NULL, NULL, 0}, {"unmount", ZipFSUnmountObjCmd, NULL, NULL, NULL, 0}, {"mkkey", ZipFSMkKeyObjCmd, NULL, NULL, NULL, 0}, {"mkimg", ZipFSMkImgObjCmd, NULL, NULL, NULL, 0}, diff --git a/tests/zipfs.test b/tests/zipfs.test index 060e4a6..5f5b93c 100644 --- a/tests/zipfs.test +++ b/tests/zipfs.test @@ -105,7 +105,7 @@ test zipfs-0.12 {zipfs basics: join} -constraints zipfs -body { test zipfs-1.3 {zipfs errors} -constraints zipfs -returnCodes error -body { zipfs mount a b c d e f -} -result {wrong # args: should be "zipfs mount ?zipfile? ?mountpoint? ?password?"} +} -result {wrong # args: should be "zipfs mount ?mountpoint? ?zipfile? ?password?"} test zipfs-1.4 {zipfs errors} -constraints zipfs -returnCodes error -body { zipfs unmount a b c d e f @@ -159,11 +159,8 @@ test zipfs-2.2.0 {zipfs mkzip} -constraints zipfs -body { cd $CWD } -result "[zipfs root]abc/cp850.enc" -skip [concat [skip] zipfs-2.2.*] - - if {![zipfs exists /abc/cp850.enc]} { - tcltest::skip zipfs-2.2.* + skip [concat [skip] zipfs-2.2.*] } test zipfs-2.2.1 {zipfs info} -constraints zipfs -body { @@ -210,7 +207,73 @@ test zipfs-2.2.6 {zipfs unmount} -constraints zipfs -body { zipfs exists /abc/cp850.enc } -result 0 + +### +# Repeat the tests for a buffer mounted archive +### +test zipfs-2.3.0 {zipfs mkzip} -constraints zipfs -body { + cd $tcl_library/encoding + zipfs mkzip $zipfile . + set fin [open $zipfile r] + fconfigure $fin -translation binary + set dat [read $fin] + close $fin + zipfs mount_data def $dat + zipfs list -glob ${ziproot}def/cp850.* +} -cleanup { + cd $CWD +} -result "[zipfs root]def/cp850.enc" + +if {![zipfs exists /def/cp850.enc]} { + skip [concat [skip] zipfs-2.3.*] +} + +test zipfs-2.3.1 {zipfs info} -constraints zipfs -body { + set r [zipfs info ${ziproot}def/cp850.enc] + lrange $r 0 2 +} -result [list {Memory Buffer} 1090 527] ;# NOTE: Only the first 3 results are stable + +test zipfs-2.3.3 {zipfs data} -constraints zipfs -body { + set zipfd [open ${ziproot}/def/cp850.enc] ;# FIXME: leave open - see later test + read $zipfd +} -result {# Encoding file: cp850, single-byte +S +003F 0 1 +00 +0000000100020003000400050006000700080009000A000B000C000D000E000F +0010001100120013001400150016001700180019001A001B001C001D001E001F +0020002100220023002400250026002700280029002A002B002C002D002E002F +0030003100320033003400350036003700380039003A003B003C003D003E003F +0040004100420043004400450046004700480049004A004B004C004D004E004F +0050005100520053005400550056005700580059005A005B005C005D005E005F +0060006100620063006400650066006700680069006A006B006C006D006E006F +0070007100720073007400750076007700780079007A007B007C007D007E007F +00C700FC00E900E200E400E000E500E700EA00EB00E800EF00EE00EC00C400C5 +00C900E600C600F400F600F200FB00F900FF00D600DC00F800A300D800D70192 +00E100ED00F300FA00F100D100AA00BA00BF00AE00AC00BD00BC00A100AB00BB +2591259225932502252400C100C200C000A9256325512557255D00A200A52510 +25142534252C251C2500253C00E300C3255A25542569256625602550256C00A4 +00F000D000CA00CB00C8013100CD00CE00CF2518250C2588258400A600CC2580 +00D300DF00D400D200F500D500B500FE00DE00DA00DB00D900FD00DD00AF00B4 +00AD00B1201700BE00B600A700F700B800B000A800B700B900B300B225A000A0 +} ;# FIXME: result depends on content of encodings dir + +test zipfs-2.3.4 {zipfs exists} -constraints zipfs -body { + zipfs exists /def/cp850.enc +} -result 1 + +test zipfs-2.3.5 {zipfs unmount while busy} -constraints zipfs -body { + zipfs unmount /def +} -returnCodes error -result {filesystem is busy} + +test zipfs-2.3.6 {zipfs unmount} -constraints zipfs -body { + close $zipfd + zipfs unmount /def + zipfs exists /def/cp850.enc +} -result 0 + catch {file delete -force $tmpdir} + ::tcltest::cleanupTests return -- cgit v0.12 From e16df96d28704115312eee43ffc5019a766d2cfd Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Fri, 19 Jan 2018 20:27:15 +0000 Subject: Fixed a problem where a Windows hack was occuring after it was called in the tclZipfs.c file, preventing it from compiling properly. --- generic/tclZipfs.c | 38 ++++++++++++++++++-------------------- 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c index b81c58f..bb9d45f 100644 --- a/generic/tclZipfs.c +++ b/generic/tclZipfs.c @@ -2945,6 +2945,24 @@ ZipFSListObjCmd( return TCL_OK; } +#if defined(_WIN32) || defined(_WIN64) +#define LIBRARY_SIZE 64 +static int +ToUtf( + const WCHAR *wSrc, + char *dst) +{ + char *start; + + start = dst; + while (*wSrc != '\0') { + dst += Tcl_UniCharToUtf(*wSrc, dst); + wSrc++; + } + *dst = '\0'; + return (int) (dst - start); +} +#endif Tcl_Obj *TclZipfs_TclLibrary(void) { if(zipfs_literal_tcl_library) { @@ -4422,26 +4440,6 @@ TclZipfs_Init(Tcl_Interp *interp) #endif } -#if defined(_WIN32) || defined(_WIN64) -#define LIBRARY_SIZE 64 -static int -ToUtf( - const WCHAR *wSrc, - char *dst) -{ - char *start; - - start = dst; - while (*wSrc != '\0') { - dst += Tcl_UniCharToUtf(*wSrc, dst); - wSrc++; - } - *dst = '\0'; - return (int) (dst - start); -} - -#endif - static int TclZipfs_AppHook_FindTclInit(const char *archive){ Tcl_Obj *vfsinitscript; int found; -- cgit v0.12 From 3b3a5ff07f3a3dd2bff6de66c86bb2d3883d9aa6 Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 15 Feb 2018 17:24:40 +0000 Subject: Better range checking in "string index". Add test-case to prove point. This opens a large discussion on what the right valid range for index values should be and what overflow behavior should be. New branch opened to answer those questions completely. --- generic/tclUtil.c | 11 ++++++++++- tests/util.test | 6 ++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/generic/tclUtil.c b/generic/tclUtil.c index 9557aac..e90477f 100644 --- a/generic/tclUtil.c +++ b/generic/tclUtil.c @@ -3585,7 +3585,16 @@ TclGetIntForIndex( * be converted to one, use it. */ - *indexPtr = endValue + (int)objPtr->internalRep.wideValue; + Tcl_WideInt value = endValue + objPtr->internalRep.wideValue; + if (endValue > 0 && value < objPtr->internalRep.wideValue) { + *indexPtr = INT_MAX; /* numerical overflow */ + } else if (value < INT_MIN || (endValue < 0 && value > objPtr->internalRep.wideValue)) { + *indexPtr = INT_MIN; /* numerical underflow or value < INT_MIN */ + } else if (value > INT_MAX) { + *indexPtr = INT_MAX;/* value > INT_MAX */ + } else { + *indexPtr = (int) value; + } return TCL_OK; } diff --git a/tests/util.test b/tests/util.test index 35fc642..d186523 100644 --- a/tests/util.test +++ b/tests/util.test @@ -729,6 +729,12 @@ test util-9.43 {TclGetIntForIndex} -body { test util-9.44 {TclGetIntForIndex} -body { string index a 0+1000000000000 } -returnCodes error -match glob -result * +test util-9.45 {TclGetIntForIndex} { + string index abcd end+2305843009213693950 +} {} +test util-9.46 {TclGetIntForIndex} { + string index abcd end+4294967294 +} {} test util-10.1 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} { convertDouble 0x0000000000000000 -- cgit v0.12 From 544d338e0e4d28400ced022ca13ccf6355a2b423 Mon Sep 17 00:00:00 2001 From: dgp Date: Tue, 27 Feb 2018 13:13:11 +0000 Subject: Work In Progress on index value reform -- not working. --- generic/tclUtil.c | 78 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/generic/tclUtil.c b/generic/tclUtil.c index e90477f..f31df0c 100644 --- a/generic/tclUtil.c +++ b/generic/tclUtil.c @@ -15,6 +15,7 @@ #include "tclInt.h" #include "tclParse.h" #include "tclStringTrim.h" +#include "tommath.h" #include /* @@ -3560,6 +3561,67 @@ TclFormatInt( */ int +GetWideForIndex( + Tcl_Interp *interp, /* Interpreter to use for error reporting. If + * NULL, then no error message is left after + * errors. */ + Tcl_Obj *objPtr, /* Points to an object containing either "end" + * or an integer. */ + int endValue, /* The value to be stored at "indexPtr" if + * "objPtr" holds "end". */ + Tcl_WideInt *widePtr) /* Location filled in with a wide integer + * representing an index. */ +{ + int numType; + ClientData cd = NULL; + int code = TclGetNumberFromObj(NULL, objPtr, &cd, &numType); + + if (code == TCL_OK) { + if (numType == TCL_NUMBER_WIDE) { + /* objPtr holds an integer in the signed wide range */ + *widePtr = (Tcl_WideInt)(*(Tcl_WideInt *)cd); + return TCL_OK; + } + if (numType == TCL_NUMBER_BIG) { + /* objPtr holds an integer outside the signed wide range */ + mp_int big; + const Tcl_WideInt wideMax = ((~(Tcl_WideUInt)0) >> 1); + + Tcl_TakeBignumFromObj(NULL, objPtr, &big); + if (mp_cmp_d(&big, 0) == MP_LT) { + *widePtr = ~wideMax; + } else { + *widePtr = wideMax; + } + return TCL_OK; + } + + /* Must be a double -> not a valid index */ + goto parseError; + } + + /* objPtr does not hold a number, parse for other index formats */ + + + + /* Report a parse error. */ + parseError: + if (interp != NULL) { + char * bytes = TclGetString(objPtr); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "bad index \"%s\": must be integer?[+-]integer? or" + " end?[+-]integer?", bytes)); + if (!strncmp(bytes, "end-", 4)) { + bytes += 4; + } + TclCheckBadOctal(interp, bytes); + Tcl_SetErrorCode(interp, "TCL", "VALUE", "INDEX", NULL); + } + + return TCL_ERROR; +} + +int TclGetIntForIndex( Tcl_Interp *interp, /* Interpreter to use for error reporting. If * NULL, then no error message is left after @@ -3571,6 +3633,21 @@ TclGetIntForIndex( int *indexPtr) /* Location filled in with an integer * representing an index. */ { +#if 1 + Tcl_WideInt wide; + + if (GetWideForIndex(interp, objPtr, endValue, &wide) == TCL_ERROR) { + return TCL_ERROR; + } + if (wide < INT_MIN) { + wide = INT_MIN; + } else if (wide > INT_MAX) { + wide = INT_MAX; + } + *indexPtr = (int) wide; + return TCL_OK; + +#else size_t length; char *opPtr; const char *bytes; @@ -3656,6 +3733,7 @@ TclGetIntForIndex( } return TCL_ERROR; +#endif } /* -- cgit v0.12 From e1efe253d236c463d01bc83d79b3f897e774cbee Mon Sep 17 00:00:00 2001 From: dgp Date: Tue, 27 Feb 2018 18:20:44 +0000 Subject: Much more progress expanding the vocabulary of index values, and getting results that make more intuitive sense. Still a few TODOs and tests to update. --- generic/tclUtil.c | 226 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 119 insertions(+), 107 deletions(-) diff --git a/generic/tclUtil.c b/generic/tclUtil.c index f31df0c..8ef5dfc 100644 --- a/generic/tclUtil.c +++ b/generic/tclUtil.c @@ -18,6 +18,8 @@ #include "tommath.h" #include +const Tcl_WideInt wideMax = ((~(Tcl_WideUInt)0) >> 1); + /* * The absolute pathname of the executable in which this Tcl library is * running. @@ -3567,14 +3569,16 @@ GetWideForIndex( * errors. */ Tcl_Obj *objPtr, /* Points to an object containing either "end" * or an integer. */ - int endValue, /* The value to be stored at "indexPtr" if + Tcl_WideInt endValue, /* The value to be stored at "indexPtr" if * "objPtr" holds "end". */ Tcl_WideInt *widePtr) /* Location filled in with a wide integer * representing an index. */ { - int numType; + const char *opPtr; + int length; ClientData cd = NULL; - int code = TclGetNumberFromObj(NULL, objPtr, &cd, &numType); + int numType, code = TclGetNumberFromObj(NULL, objPtr, &cd, &numType); + if (code == TCL_OK) { if (numType == TCL_NUMBER_WIDE) { @@ -3584,11 +3588,9 @@ GetWideForIndex( } if (numType == TCL_NUMBER_BIG) { /* objPtr holds an integer outside the signed wide range */ - mp_int big; - const Tcl_WideInt wideMax = ((~(Tcl_WideUInt)0) >> 1); + mp_int *bigPtr = (mp_int *)cd; - Tcl_TakeBignumFromObj(NULL, objPtr, &big); - if (mp_cmp_d(&big, 0) == MP_LT) { + if (mp_cmp_d(bigPtr, 0) == MP_LT) { *widePtr = ~wideMax; } else { *widePtr = wideMax; @@ -3600,12 +3602,88 @@ GetWideForIndex( goto parseError; } - /* objPtr does not hold a number, parse for other index formats */ + /* objPtr does not hold a number, check the end+/- format... */ + + if (SetEndOffsetFromAny(NULL, objPtr) == TCL_OK) { + Tcl_WideInt offset = objPtr->internalRep.wideValue; + + if ((endValue ^ offset) < 0) { + /* Different signs, sum cannot overflow */ + *widePtr = endValue + offset; + } else if (endValue >= 0) { + if (endValue < wideMax - offset) { + *widePtr = endValue + offset; + } else { + *widePtr = wideMax; + } + } else { + if (endValue > ~wideMax - offset) { + *widePtr = endValue + offset; + } else { + *widePtr = ~wideMax; + } + } + return TCL_OK; + } + + if (TCL_OK == Tcl_ListObjLength(NULL, objPtr, &length) && (length > 1)) { + goto parseError; + } + /* check the index arithmetic format... */ + if (TCL_OK == TclParseNumber(NULL, objPtr, NULL, NULL, -1, &opPtr, + TCL_PARSE_INTEGER_ONLY)) { + if ((*opPtr != '-') && (*opPtr != '+')) { + goto parseError; + } + TclGetNumberFromObj(NULL, objPtr, &cd, &numType); + if (numType == TCL_NUMBER_WIDE) { + Tcl_WideInt w1 = (*(Tcl_WideInt *)cd); + + if (TCL_OK == TclParseNumber(NULL, objPtr, NULL, opPtr+1, -1, + NULL, TCL_PARSE_INTEGER_ONLY)) { + TclGetNumberFromObj(NULL, objPtr, &cd, &numType); + if (numType == TCL_NUMBER_WIDE) { + Tcl_WideInt w2 = (*(Tcl_WideInt *)cd); + + TclFreeIntRep(objPtr); + if (*opPtr == '-') { + if (w2 == ~wideMax) { + /* TODO: need bignum */ + goto parseError; + } + w2 = -w2; + } + if ((w1 ^ w2) < 0) { + *widePtr = w1 + w2; + } else if (w1 >= 0) { + if (w1 < wideMax - w2) { + *widePtr = w1 + w2; + } else { + *widePtr = wideMax; + } + } else { + if (w1 > ~wideMax - w2) { + *widePtr = w1 + w2; + } else { + *widePtr = ~wideMax; + } + } + return TCL_OK; + } + /* TODO: 2d half is bignum */ + goto parseError; + } + goto parseError; + } + /* TODO: 1st half is bignum */ + goto parseError; + } /* Report a parse error. */ parseError: + TclFreeIntRep(objPtr); if (interp != NULL) { char * bytes = TclGetString(objPtr); Tcl_SetObjResult(interp, Tcl_ObjPrintf( @@ -3633,7 +3711,6 @@ TclGetIntForIndex( int *indexPtr) /* Location filled in with an integer * representing an index. */ { -#if 1 Tcl_WideInt wide; if (GetWideForIndex(interp, objPtr, endValue, &wide) == TCL_ERROR) { @@ -3646,94 +3723,6 @@ TclGetIntForIndex( } *indexPtr = (int) wide; return TCL_OK; - -#else - size_t length; - char *opPtr; - const char *bytes; - - if (TclGetIntFromObj(NULL, objPtr, indexPtr) == TCL_OK) { - return TCL_OK; - } - - if (SetEndOffsetFromAny(NULL, objPtr) == TCL_OK) { - /* - * If the object is already an offset from the end of the list, or can - * be converted to one, use it. - */ - - Tcl_WideInt value = endValue + objPtr->internalRep.wideValue; - if (endValue > 0 && value < objPtr->internalRep.wideValue) { - *indexPtr = INT_MAX; /* numerical overflow */ - } else if (value < INT_MIN || (endValue < 0 && value > objPtr->internalRep.wideValue)) { - *indexPtr = INT_MIN; /* numerical underflow or value < INT_MIN */ - } else if (value > INT_MAX) { - *indexPtr = INT_MAX;/* value > INT_MAX */ - } else { - *indexPtr = (int) value; - } - return TCL_OK; - } - - bytes = TclGetString(objPtr); - length = objPtr->length; - - /* - * Leading whitespace is acceptable in an index. - */ - - while (length && TclIsSpaceProc(*bytes)) { - bytes++; - length--; - } - - if (TclParseNumber(NULL, NULL, NULL, bytes, length, (const char **)&opPtr, - TCL_PARSE_INTEGER_ONLY | TCL_PARSE_NO_WHITESPACE) == TCL_OK) { - int code, first, second; - char savedOp = *opPtr; - - if ((savedOp != '+') && (savedOp != '-')) { - goto parseError; - } - if (TclIsSpaceProc(opPtr[1])) { - goto parseError; - } - *opPtr = '\0'; - code = Tcl_GetInt(interp, bytes, &first); - *opPtr = savedOp; - if (code == TCL_ERROR) { - goto parseError; - } - if (TCL_ERROR == Tcl_GetInt(interp, opPtr+1, &second)) { - goto parseError; - } - if (savedOp == '+') { - *indexPtr = first + second; - } else { - *indexPtr = first - second; - } - return TCL_OK; - } - - /* - * Report a parse error. - */ - - parseError: - if (interp != NULL) { - bytes = TclGetString(objPtr); - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "bad index \"%s\": must be integer?[+-]integer? or" - " end?[+-]integer?", bytes)); - if (!strncmp(bytes, "end-", 4)) { - bytes += 4; - } - TclCheckBadOctal(interp, bytes); - Tcl_SetErrorCode(interp, "TCL", "VALUE", "INDEX", NULL); - } - - return TCL_ERROR; -#endif } /* @@ -3809,18 +3798,22 @@ SetEndOffsetFromAny( } /* + * Multi-element lists cannot be permitted. Would confuse a single + * index of end[+-]$integer format with list of indices + */ + + if (TCL_OK == Tcl_ListObjLength(NULL, objPtr, &length) && (length > 1)) { + goto badIndexFormat; + } + + /* * Check for a string rep of the right form. */ bytes = TclGetStringFromObj(objPtr, &length); if ((*bytes != 'e') || (strncmp(bytes, "end", (size_t)((length > 3) ? 3 : length)) != 0)) { - if (interp != NULL) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "bad index \"%s\": must be end?[+-]integer?", bytes)); - Tcl_SetErrorCode(interp, "TCL", "VALUE", "INDEX", NULL); - } - return TCL_ERROR; + goto badIndexFormat; } /* @@ -3834,6 +3827,8 @@ SetEndOffsetFromAny( * This is our limited string expression evaluator. Pass everything * after "end-" to TclParseNumber. */ + int numType; + ClientData cd; if (TclIsSpaceProc(bytes[4])) { goto badIndexFormat; @@ -3842,12 +3837,28 @@ SetEndOffsetFromAny( TCL_PARSE_INTEGER_ONLY) != TCL_OK) { return TCL_ERROR; } - if (objPtr->typePtr != &tclIntType) { - goto badIndexFormat; + TclGetNumberFromObj(NULL, objPtr, &cd, &numType); + if (numType == TCL_NUMBER_BIG) { + /* objPtr holds an integer outside the signed wide range */ + mp_int *bigPtr = (mp_int *)cd; + + if (mp_cmp_d(bigPtr, 0) == MP_LT) { + offset = ~wideMax; + } else { + offset = wideMax; + } + } else if (numType == TCL_NUMBER_WIDE) { + offset = (*(Tcl_WideInt *)cd); + } else { + /* Can't happen? */ + goto badIndexFormat; } - offset = objPtr->internalRep.wideValue; if (bytes[3] == '-') { - offset = -offset; + if (offset == ~wideMax) { + offset = wideMax; + } else { + offset = -offset; + } } } else { /* @@ -3856,6 +3867,7 @@ SetEndOffsetFromAny( badIndexFormat: if (interp != NULL) { + bytes = TclGetStringFromObj(objPtr, &length); Tcl_SetObjResult(interp, Tcl_ObjPrintf( "bad index \"%s\": must be end?[+-]integer?", bytes)); Tcl_SetErrorCode(interp, "TCL", "VALUE", "INDEX", NULL); -- cgit v0.12 From 3607c177d947f19065109ff79d751cd5e303bfe5 Mon Sep 17 00:00:00 2001 From: dgp Date: Tue, 27 Feb 2018 22:35:24 +0000 Subject: Don't save indices with values outside the int range in bytecode. --- generic/tclCompCmdsGR.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/generic/tclCompCmdsGR.c b/generic/tclCompCmdsGR.c index ff5495c..a4c5a96 100644 --- a/generic/tclCompCmdsGR.c +++ b/generic/tclCompCmdsGR.c @@ -55,13 +55,21 @@ GetIndexFromToken( { Tcl_Obj *tmpObj = Tcl_NewObj(); int result, idx; + Tcl_WideInt wide; if (!TclWordKnownAtCompileTime(tokenPtr, tmpObj)) { Tcl_DecrRefCount(tmpObj); return TCL_ERROR; } - result = TclGetIntFromObj(NULL, tmpObj, &idx); + result = TclGetWideIntFromObj(NULL, tmpObj, &wide); + if (wide < INT_MIN) { + idx = INT_MIN; + } else if (wide > INT_MAX) { + idx = INT_MAX; + } else { + idx = (int) wide; + } if (result == TCL_OK) { if (idx < 0) { result = TCL_ERROR; -- cgit v0.12 From 221f1bc18e15cdf5247d4d7c7f97def268404000 Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 28 Feb 2018 13:40:36 +0000 Subject: Use mp_isneg() as appropriate. --- generic/tclUtil.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/generic/tclUtil.c b/generic/tclUtil.c index a721497..3fe2c32 100644 --- a/generic/tclUtil.c +++ b/generic/tclUtil.c @@ -3593,7 +3593,7 @@ GetWideForIndex( /* objPtr holds an integer outside the signed wide range */ mp_int *bigPtr = (mp_int *)cd; - if (mp_cmp_d(bigPtr, 0) == MP_LT) { + if (mp_isneg(bigPtr)) { *widePtr = ~wideMax; } else { *widePtr = wideMax; @@ -3808,7 +3808,7 @@ SetEndOffsetFromAny( /* objPtr holds an integer outside the signed wide range */ mp_int *bigPtr = (mp_int *)cd; - if (mp_cmp_d(bigPtr, 0) == MP_LT) { + if (mp_isneg(bigPtr)) { offset = ~wideMax; } else { offset = wideMax; -- cgit v0.12 From 0cb6effe147ce8a5933976d0f99edfc1ca6acdbf Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 1 Mar 2018 04:19:37 +0000 Subject: Continue consistent use of LLONG_MIN and LLONG_MAX. --- generic/tclUtil.c | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/generic/tclUtil.c b/generic/tclUtil.c index 3fe2c32..8afba01 100644 --- a/generic/tclUtil.c +++ b/generic/tclUtil.c @@ -18,8 +18,6 @@ #include "tommath.h" #include -const Tcl_WideInt wideMax = ((~(Tcl_WideUInt)0) >> 1); - /* * The absolute pathname of the executable in which this Tcl library is * running. @@ -3594,9 +3592,9 @@ GetWideForIndex( mp_int *bigPtr = (mp_int *)cd; if (mp_isneg(bigPtr)) { - *widePtr = ~wideMax; + *widePtr = LLONG_MIN; } else { - *widePtr = wideMax; + *widePtr = LLONG_MAX; } return TCL_OK; } @@ -3614,16 +3612,16 @@ GetWideForIndex( /* Different signs, sum cannot overflow */ *widePtr = endValue + offset; } else if (endValue >= 0) { - if (endValue < wideMax - offset) { + if (endValue < LLONG_MAX - offset) { *widePtr = endValue + offset; } else { - *widePtr = wideMax; + *widePtr = LLONG_MAX; } } else { - if (endValue > ~wideMax - offset) { + if (endValue > LLONG_MIN - offset) { *widePtr = endValue + offset; } else { - *widePtr = ~wideMax; + *widePtr = LLONG_MIN; } } return TCL_OK; @@ -3651,7 +3649,7 @@ GetWideForIndex( TclFreeIntRep(objPtr); if (*opPtr == '-') { - if (w2 == ~wideMax) { + if (w2 == LLONG_MIN) { /* TODO: need bignum */ goto parseError; } @@ -3661,16 +3659,16 @@ GetWideForIndex( if ((w1 ^ w2) < 0) { *widePtr = w1 + w2; } else if (w1 >= 0) { - if (w1 < wideMax - w2) { + if (w1 < LLONG_MAX - w2) { *widePtr = w1 + w2; } else { - *widePtr = wideMax; + *widePtr = LLONG_MAX; } } else { - if (w1 > ~wideMax - w2) { + if (w1 > LLONG_MIN - w2) { *widePtr = w1 + w2; } else { - *widePtr = ~wideMax; + *widePtr = LLONG_MIN; } } return TCL_OK; @@ -3809,9 +3807,9 @@ SetEndOffsetFromAny( mp_int *bigPtr = (mp_int *)cd; if (mp_isneg(bigPtr)) { - offset = ~wideMax; + offset = LLONG_MIN; } else { - offset = wideMax; + offset = LLONG_MAX; } } else if (numType == TCL_NUMBER_WIDE) { offset = (*(Tcl_WideInt *)cd); @@ -3820,8 +3818,8 @@ SetEndOffsetFromAny( goto badIndexFormat; } if (bytes[3] == '-') { - if (offset == ~wideMax) { - offset = wideMax; + if (offset == LLONG_MIN) { + offset = LLONG_MAX; } else { offset = -offset; } -- cgit v0.12 From 40dfdbd9290c1863d245b2cb1fb6e0c9f4ed1d33 Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 1 Mar 2018 19:30:15 +0000 Subject: Avoid full list conversion when we can cheaply discover a multi-element list is not possible. --- generic/tclUtil.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/generic/tclUtil.c b/generic/tclUtil.c index 8afba01..b7faa33 100644 --- a/generic/tclUtil.c +++ b/generic/tclUtil.c @@ -3627,7 +3627,9 @@ GetWideForIndex( return TCL_OK; } - if (TCL_OK == Tcl_ListObjLength(NULL, objPtr, &length) && (length > 1)) { + if ((TclMaxListLength(TclGetString(objPtr), -1, NULL) > 1) + && (TCL_OK == Tcl_ListObjLength(NULL, objPtr, &length)) + && (length > 1)) { goto parseError; } -- cgit v0.12 From 1a73baff0989dad465da8fd91f32d537bf704367 Mon Sep 17 00:00:00 2001 From: dgp Date: Mon, 26 Mar 2018 16:27:40 +0000 Subject: Work in progress implementing TIP 505. --- generic/tclCmdIL.c | 17 +++-------------- generic/tclCompCmdsGR.c | 1 + tests/lreplace.test | 8 ++++---- 3 files changed, 8 insertions(+), 18 deletions(-) diff --git a/generic/tclCmdIL.c b/generic/tclCmdIL.c index 3b2cb19..10fbd3f 100644 --- a/generic/tclCmdIL.c +++ b/generic/tclCmdIL.c @@ -2747,21 +2747,10 @@ Tcl_LreplaceObjCmd( if (first < 0) { first = 0; } - - /* - * Complain if the user asked for a start element that is greater than the - * list length. This won't ever trigger for the "end-*" case as that will - * be properly constrained by TclGetIntForIndex because we use listLen-1 - * (to allow for replacing the last elem). - */ - - if ((first >= listLen) && (listLen > 0)) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "list doesn't contain element %s", TclGetString(objv[2]))); - Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LREPLACE", "BADIDX", - NULL); - return TCL_ERROR; + if (first > listLen) { + first = listLen; } + if (last >= listLen) { last = listLen - 1; } diff --git a/generic/tclCompCmdsGR.c b/generic/tclCompCmdsGR.c index 396947c..ce324c8 100644 --- a/generic/tclCompCmdsGR.c +++ b/generic/tclCompCmdsGR.c @@ -1478,6 +1478,7 @@ TclCompileLreplaceCmd( if (parsePtr->numWords < 4) { return TCL_ERROR; } +return TCL_ERROR; listTokenPtr = TokenAfter(parsePtr->tokenPtr); tokenPtr = TokenAfter(listTokenPtr); diff --git a/tests/lreplace.test b/tests/lreplace.test index 4a6b853..fd2f7f8 100644 --- a/tests/lreplace.test +++ b/tests/lreplace.test @@ -100,10 +100,10 @@ test lreplace-1.26 {lreplace command} { } {a {} {}} test lreplace-1.27 {lreplace command} -body { lreplace x 1 1 -} -returnCodes 1 -result {list doesn't contain element 1} +} -result x test lreplace-1.28 {lreplace command} -body { lreplace x 1 1 y -} -returnCodes 1 -result {list doesn't contain element 1} +} -result {x y} test lreplace-1.29 {lreplace command} -body { lreplace x 1 1 [error foo] } -returnCodes 1 -result {foo} @@ -128,10 +128,10 @@ test lreplace-2.5 {lreplace errors} { } {1 {bad index "1x": must be integer?[+-]integer? or end?[+-]integer?}} test lreplace-2.6 {lreplace errors} { list [catch {lreplace x 3 2} msg] $msg -} {1 {list doesn't contain element 3}} +} {0 x} test lreplace-2.7 {lreplace errors} { list [catch {lreplace x 2 2} msg] $msg -} {1 {list doesn't contain element 2}} +} {0 x} test lreplace-3.1 {lreplace won't modify shared argument objects} { proc p {} { -- cgit v0.12 From 843d29b4486fa92657c326b43383a8e7e860fdf3 Mon Sep 17 00:00:00 2001 From: dgp Date: Mon, 26 Mar 2018 18:59:00 +0000 Subject: Rest of TIP 505 implementation -- mostly undoing dumb things. --- generic/tclCompCmdsGR.c | 60 ++++--------------------------------------------- 1 file changed, 4 insertions(+), 56 deletions(-) diff --git a/generic/tclCompCmdsGR.c b/generic/tclCompCmdsGR.c index ce324c8..1094352 100644 --- a/generic/tclCompCmdsGR.c +++ b/generic/tclCompCmdsGR.c @@ -1472,13 +1472,12 @@ TclCompileLreplaceCmd( { Tcl_Token *tokenPtr, *listTokenPtr; DefineLineInformation; /* TIP #280 */ - int idx1, idx2, i, offset, offset2; + int idx1, idx2, i; int emptyPrefix=1, suffixStart = 0; if (parsePtr->numWords < 4) { return TCL_ERROR; } -return TCL_ERROR; listTokenPtr = TokenAfter(parsePtr->tokenPtr); tokenPtr = TokenAfter(listTokenPtr); @@ -1494,23 +1493,6 @@ return TCL_ERROR; } /* - * idx1, idx2 are the conventional encoded forms of the tokens parsed - * as all forms of index values. Values of idx1 that come before the - * list are treated the same as if they were the start of the list. - * Values of idx2 that come after the list are treated the same as if - * they were the end of the list. - */ - - if (idx1 == TCL_INDEX_AFTER) { - /* - * [lreplace] treats idx1 value end+1 differently from end+2, etc. - * The operand encoding cannot distinguish them, so we must bail - * out to direct evaluation. - */ - return TCL_ERROR; - } - - /* * General structure of the [lreplace] result is * prefix replacement suffix * In a few cases we can predict various parts will be empty and @@ -1521,7 +1503,9 @@ return TCL_ERROR; * we must defer to direct evaluation. */ - if (idx2 == TCL_INDEX_BEFORE) { + if (idx1 == TCL_INDEX_AFTER) { + suffixStart = idx1; + } else if (idx2 == TCL_INDEX_BEFORE) { suffixStart = idx1; } else if (idx2 == TCL_INDEX_END) { suffixStart = TCL_INDEX_AFTER; @@ -1553,42 +1537,6 @@ return TCL_ERROR; emptyPrefix = 0; } - /* - * [lreplace] raises an error when idx1 points after the list, but - * only when the list is not empty. This is maximum stupidity. - * - * TODO: TIP this nonsense away! - */ - if (idx1 >= TCL_INDEX_START) { - if (emptyPrefix) { - TclEmitOpcode( INST_DUP, envPtr); - } else { - TclEmitInstInt4( INST_OVER, 1, envPtr); - } - TclEmitOpcode( INST_LIST_LENGTH, envPtr); - TclEmitOpcode( INST_DUP, envPtr); - offset = CurrentOffset(envPtr); - TclEmitInstInt1( INST_JUMP_FALSE1, 0, envPtr); - - /* List is not empty */ - TclEmitPush(TclAddLiteralObj(envPtr, Tcl_NewIntObj(idx1), - NULL), envPtr); - TclEmitOpcode( INST_GT, envPtr); - offset2 = CurrentOffset(envPtr); - TclEmitInstInt1( INST_JUMP_TRUE1, 0, envPtr); - - /* Idx1 >= list length ===> raise an error */ - TclEmitPush(TclAddLiteralObj(envPtr, Tcl_ObjPrintf( - "list doesn't contain element %d", idx1), NULL), envPtr); - CompileReturnInternal(envPtr, INST_RETURN_IMM, TCL_ERROR, 0, - Tcl_ObjPrintf("-errorcode {TCL OPERATION LREPLACE BADIDX}")); - TclStoreInt1AtPtr(CurrentOffset(envPtr) - offset, - envPtr->codeStart + offset + 1); - TclEmitOpcode( INST_POP, envPtr); - TclStoreInt1AtPtr(CurrentOffset(envPtr) - offset2, - envPtr->codeStart + offset2 + 1); - } - if ((idx1 == suffixStart) && (parsePtr->numWords == 4)) { /* * This is a "no-op". Example: [lreplace {a b c} 2 0] -- cgit v0.12 -- cgit v0.12 From 45f91441a5885c285f3ce537e1f11b0bdbe8ac2a Mon Sep 17 00:00:00 2001 From: kjnash Date: Tue, 27 Mar 2018 08:03:58 +0000 Subject: Adjust whitespace to Tcl 8+4 tab convention. --- library/http/http.tcl | 100 +++++++++++++++++++++++++------------------------- 1 file changed, 50 insertions(+), 50 deletions(-) diff --git a/library/http/http.tcl b/library/http/http.tcl index 9f5310b..d897fce 100644 --- a/library/http/http.tcl +++ b/library/http/http.tcl @@ -32,14 +32,14 @@ namespace eval http { # ::tcl_platform(osVersion). if {[interp issafe]} { set http(-useragent) "Mozilla/5.0\ - (Windows; U;\ - Windows NT 10.0)\ - http/[package provide http] Tcl/[package provide Tcl]" + (Windows; U;\ + Windows NT 10.0)\ + http/[package provide http] Tcl/[package provide Tcl]" } else { set http(-useragent) "Mozilla/5.0\ - ([string totitle $::tcl_platform(platform)]; U;\ - $::tcl_platform(os) $::tcl_platform(osVersion))\ - http/[package provide http] Tcl/[package provide Tcl]" + ([string totitle $::tcl_platform(platform)]; U;\ + $::tcl_platform(os) $::tcl_platform(osVersion))\ + http/[package provide http] Tcl/[package provide Tcl]" } } @@ -211,7 +211,7 @@ proc http::Finish {token {errormsg ""} {skipCB 0}} { || ([info exists state(-keepalive)] && !$state(-keepalive)) || ([info exists state(connection)] && ($state(connection) eq "close")) } { - CloseSocket $state(sock) $token + CloseSocket $state(sock) $token } if {[info exists state(after)]} { after cancel $state(after) @@ -238,22 +238,22 @@ proc ::http::CloseSocket {s {token {}}} { catch {fileevent $s readable {}} set conn_id {} if {$token ne ""} { - variable $token - upvar 0 $token state - if {[info exists state(socketinfo)]} { + variable $token + upvar 0 $token state + if {[info exists state(socketinfo)]} { set conn_id $state(socketinfo) - } + } } else { - set map [array get socketmap] - set ndx [lsearch -exact $map $s] - if {$ndx != -1} { + set map [array get socketmap] + set ndx [lsearch -exact $map $s] + if {$ndx != -1} { incr ndx -1 set conn_id [lindex $map $ndx] - } + } } if {$conn_id eq {} || ![info exists socketmap($conn_id)]} { - Log "Closing socket $s (no connection info)" - if {[catch {close $s} err]} { + Log "Closing socket $s (no connection info)" + if {[catch {close $s} err]} { Log "Error: $err" } } else { @@ -602,7 +602,7 @@ proc http::geturl {url args} { if {[info exists state(-myaddr)]} { lappend sockopts -myaddr $state(-myaddr) } - if {[catch {eval $defcmd $sockopts $targetAddr} sock]} { + if {[catch {eval $defcmd $sockopts $targetAddr} sock]} { # something went wrong while trying to establish the connection. # Clean up after events and such, but DON'T call the command # callback (if available) because we're going to throw an @@ -612,13 +612,13 @@ proc http::geturl {url args} { Finish $token "" 1 cleanup $token return -code error $sock - } + } } set state(sock) $sock Log "Using $sock for $state(socketinfo)" \ - [expr {$state(-keepalive)?"keepalive":""}] + [expr {$state(-keepalive)?"keepalive":""}] if {$state(-keepalive)} { - set socketmap($state(socketinfo)) $sock + set socketmap($state(socketinfo)) $sock } if {![info exists phost]} { @@ -731,16 +731,16 @@ proc http::Connected {token proto phost srvurl} { puts $sock "Host: $host:$port" } puts $sock "User-Agent: $http(-useragent)" - if {$state(-protocol) == 1.0 && $state(-keepalive)} { + if {$state(-protocol) == 1.0 && $state(-keepalive)} { puts $sock "Connection: keep-alive" - } - if {$state(-protocol) > 1.0 && !$state(-keepalive)} { + } + if {$state(-protocol) > 1.0 && !$state(-keepalive)} { puts $sock "Connection: close" ;# RFC2616 sec 8.1.2.1 - } - if {[info exists phost] && ($phost ne "") && $state(-keepalive)} { + } + if {[info exists phost] && ($phost ne "") && $state(-keepalive)} { puts $sock "Proxy-Connection: Keep-Alive" - } - set accept_encoding_seen 0 + } + set accept_encoding_seen 0 set content_type_seen 0 dict for {key value} $state(-headers) { set value [string map [list \n "" \r ""] $value] @@ -770,9 +770,9 @@ proc http::Connected {token proto phost srvurl} { if {!$accept_types_seen} { puts $sock "Accept: $state(accept-types)" } - if {!$accept_encoding_seen && ![info exists state(-handler)]} { + if {!$accept_encoding_seen && ![info exists state(-handler)]} { puts $sock "Accept-Encoding: gzip,deflate,compress" - } + } if {$isQueryChannel && $state(querylength) == 0} { # Try to determine size of data in channel. If we cannot seek, the # surrounding catch will trap us @@ -1548,31 +1548,31 @@ proc http::ContentEncoding {token} { proc http::make-transformation-chunked {chan command} { set lambda {{chan command} { - set data "" - set size -1 - yield - while {1} { - chan configure $chan -translation {crlf binary} - while {[gets $chan line] < 1} { yield } - chan configure $chan -translation {binary binary} - if {[scan $line %x size] != 1} { return -code error "invalid size: \"$line\"" } - set chunk "" - while {$size && ![chan eof $chan]} { - set part [chan read $chan $size] - incr size -[string length $part] - append chunk $part - } - if {[catch { + set data "" + set size -1 + yield + while {1} { + chan configure $chan -translation {crlf binary} + while {[gets $chan line] < 1} { yield } + chan configure $chan -translation {binary binary} + if {[scan $line %x size] != 1} { return -code error "invalid size: \"$line\"" } + set chunk "" + while {$size && ![chan eof $chan]} { + set part [chan read $chan $size] + incr size -[string length $part] + append chunk $part + } + if {[catch { uplevel #0 [linsert $command end $chunk] }]} { http::Log "Error in callback: $::errorInfo" } - if {[string length $chunk] == 0} { + if {[string length $chunk] == 0} { # channel might have been closed in the callback - catch {chan event $chan readable {}} - return - } - } + catch {chan event $chan readable {}} + return + } + } }} coroutine dechunk$chan ::apply $lambda $chan $command chan event $chan readable [namespace origin dechunk$chan] -- cgit v0.12 From 0a9706f48fcc2f0a675701d6d5097e08501d334e Mon Sep 17 00:00:00 2001 From: kjnash Date: Tue, 27 Mar 2018 08:05:42 +0000 Subject: Adjust to 80 columns except one 82-column line which would be less intelligible. --- library/http/http.tcl | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/library/http/http.tcl b/library/http/http.tcl index d897fce..6abd223 100644 --- a/library/http/http.tcl +++ b/library/http/http.tcl @@ -25,9 +25,9 @@ namespace eval http { -proxyfilter http::ProxyRequired -urlencoding utf-8 } - # We need a useragent string of this style or various servers will refuse to - # send us compressed content even when we ask for it. This follows the - # de-facto layout of user-agent strings in current browsers. + # We need a useragent string of this style or various servers will + # refuse to send us compressed content even when we ask for it. This + # follows the de-facto layout of user-agent strings in current browsers. # Safe interpreters do not have ::tcl_platform(os) or # ::tcl_platform(osVersion). if {[interp issafe]} { @@ -1026,7 +1026,9 @@ proc http::Event {sock token} { } elseif {$n == 0} { # We have now read all headers # We ignore HTTP/1.1 100 Continue returns. RFC2616 sec 8.2.3 - if {$state(http) == "" || ([regexp {^\S+\s(\d+)} $state(http) {} x] && $x == 100)} { + if { ($state(http) == "") + || ([regexp {^\S+\s(\d+)} $state(http) {} x] && $x == 100) + } { set state(state) "connecting" return } @@ -1369,8 +1371,8 @@ proc http::Eof {token {force 0}} { if {!$state(binary)} { # If we are getting text, set the incoming channel's encoding - # correctly. iso8859-1 is the RFC default, but this could be any IANA - # charset. However, we only know how to convert what we have + # correctly. iso8859-1 is the RFC default, but this could be any + # IANA charset. However, we only know how to convert what we have # encodings for. set enc [CharsetToEncoding $state(charset)] @@ -1538,7 +1540,8 @@ proc http::ContentEncoding {token} { compress - x-compress { lappend r decompress } identity {} default { - return -code error "unsupported content-encoding \"$coding\"" + set msg "unsupported content-encoding \"$coding\"" + return -code error $msg } } } @@ -1555,7 +1558,9 @@ proc http::make-transformation-chunked {chan command} { chan configure $chan -translation {crlf binary} while {[gets $chan line] < 1} { yield } chan configure $chan -translation {binary binary} - if {[scan $line %x size] != 1} { return -code error "invalid size: \"$line\"" } + if {[scan $line %x size] != 1} { + return -code error "invalid size: \"$line\"" + } set chunk "" while {$size && ![chan eof $chan]} { set part [chan read $chan $size] -- cgit v0.12 From d88d33f74d687fe01610c0d278a4ce228898c7f5 Mon Sep 17 00:00:00 2001 From: kjnash Date: Tue, 27 Mar 2018 08:07:05 +0000 Subject: Give all procs an explicit return, except where commented as "Implicit Return". --- library/http/http.tcl | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/library/http/http.tcl b/library/http/http.tcl index 6abd223..db3c044 100644 --- a/library/http/http.tcl +++ b/library/http/http.tcl @@ -68,6 +68,7 @@ namespace eval http { } } array set socketmap {} + return } init @@ -123,6 +124,7 @@ if {[info command http::Log] eq {}} {proc http::Log {args} {}} proc http::register {proto port command} { variable urlTypes set urlTypes([string tolower $proto]) [list $port $command] + # N.B. Implicit Return. } # http::unregister -- @@ -180,6 +182,7 @@ proc http::config {args} { } set http($flag) $value } + return } } @@ -224,6 +227,7 @@ proc http::Finish {token {errormsg ""} {skipCB 0}} { set state(status) error } } + return } # http::CloseSocket - @@ -267,6 +271,7 @@ proc ::http::CloseSocket {s {token {}}} { Log "Cannot close connection $conn_id - no socket in socket map" } } + return } # http::reset -- @@ -292,6 +297,7 @@ proc http::reset {token {why reset}} { unset state eval ::error $errorlist } + return } # http::geturl -- @@ -827,6 +833,7 @@ proc http::Connected {token proto phost srvurl} { Finish $token $err } } + return } # Data access functions: @@ -897,6 +904,7 @@ proc http::cleanup {token} { if {[info exists state]} { unset state } + return } # http::Connect @@ -987,6 +995,7 @@ proc http::Write {token} { eval $state(-queryprogress) \ [list $token $state(querylength) $state(queryoffset)] } + return } # http::Event @@ -1192,8 +1201,8 @@ proc http::Event {sock token} { # open connection closed on a token that has been cleaned up. CloseSocket $sock } - return } + return } # http::IsBinaryContentType -- @@ -1278,6 +1287,7 @@ proc http::CopyStart {sock token {initial 1}} { Finish $token $err } } + return } proc http::CopyChunk {token chunk} { @@ -1307,6 +1317,7 @@ proc http::CopyChunk {token chunk} { } Eof $token ;# FIX ME: pipelining. } + return } # http::CopyDone @@ -1337,6 +1348,7 @@ proc http::CopyDone {token count {error {}}} { } else { CopyStart $sock $token 0 } + return } # http::Eof @@ -1385,6 +1397,7 @@ proc http::Eof {token {force 0}} { } } Finish $token + return } # http::wait -- @@ -1487,6 +1500,7 @@ proc http::ProxyRequired {host} { } return [list $http(-proxyhost) $http(-proxyport)] } + return } # http::CharsetToEncoding -- -- cgit v0.12 From 97721e9675b4ddd37cd3d9a8ad151961e778fee3 Mon Sep 17 00:00:00 2001 From: kjnash Date: Tue, 27 Mar 2018 08:08:19 +0000 Subject: Add parentheses to some "if" tests; transform one test without changing its outcome. --- library/http/http.tcl | 43 +++++++++++++++++++++++++++---------------- 1 file changed, 27 insertions(+), 16 deletions(-) diff --git a/library/http/http.tcl b/library/http/http.tcl index db3c044..16e0c19 100644 --- a/library/http/http.tcl +++ b/library/http/http.tcl @@ -209,7 +209,7 @@ proc http::Finish {token {errormsg ""} {skipCB 0}} { set state(error) [list $errormsg $errorInfo $errorCode] set state(status) "error" } - if { ($state(status) eq "timeout") + if { ($state(status) eq "timeout") || ($state(status) eq "error") || ([info exists state(-keepalive)] && !$state(-keepalive)) || ([info exists state(connection)] && ($state(connection) eq "close")) @@ -219,8 +219,8 @@ proc http::Finish {token {errormsg ""} {skipCB 0}} { if {[info exists state(after)]} { after cancel $state(after) } - if {[info exists state(-command)] && !$skipCB - && ![info exists state(done-command-cb)]} { + if {[info exists state(-command)] && (!$skipCB) + && (![info exists state(done-command-cb)])} { set state(done-command-cb) yes if {[catch {eval $state(-command) {$token}} err] && $errormsg eq ""} { set state(error) [list $err $errorInfo $errorCode] @@ -715,7 +715,7 @@ proc http::Connected {token proto phost srvurl} { fconfigure $state(-querychannel) -blocking 1 -translation binary set contDone 0 } - if {[info exists state(-method)] && $state(-method) ne ""} { + if {[info exists state(-method)] && ($state(-method) ne "")} { set how $state(-method) } # We cannot handle chunked encodings with -handler, so force HTTP/1.0 @@ -737,10 +737,10 @@ proc http::Connected {token proto phost srvurl} { puts $sock "Host: $host:$port" } puts $sock "User-Agent: $http(-useragent)" - if {$state(-protocol) == 1.0 && $state(-keepalive)} { + if {($state(-protocol) == 1.0) && $state(-keepalive)} { puts $sock "Connection: keep-alive" } - if {$state(-protocol) > 1.0 && !$state(-keepalive)} { + if {($state(-protocol) > 1.0) && !$state(-keepalive)} { puts $sock "Connection: close" ;# RFC2616 sec 8.1.2.1 } if {[info exists phost] && ($phost ne "") && $state(-keepalive)} { @@ -779,7 +779,7 @@ proc http::Connected {token proto phost srvurl} { if {!$accept_encoding_seen && ![info exists state(-handler)]} { puts $sock "Accept-Encoding: gzip,deflate,compress" } - if {$isQueryChannel && $state(querylength) == 0} { + if {$isQueryChannel && ($state(querylength) == 0)} { # Try to determine size of data in channel. If we cannot seek, the # surrounding catch will trap us @@ -1050,15 +1050,26 @@ proc http::Event {sock token} { return } - # For non-chunked transfer we may have no body - in this case we - # may get no further file event if the connection doesn't close - # and no more data is sent. We can tell and must finish up now - - # not later. - if { - !(([info exists state(connection)] - && ($state(connection) eq "close")) - || [info exists state(transfer)]) - && ($state(totalsize) == 0) + # - For non-chunked transfer we may have no body - in this case we + # may get no further file event if the connection doesn't close + # and no more data is sent. We can tell and must finish up now - + # not later - the alternative would be to wait until the server + # times out. + # - In this case, the server has NOT told the client it will close + # the connection, AND it has NOT indicated the resource length + # EITHER by setting the Content-Length (totalsize) OR by using + # chunked Transer-Encoding. + # - Do not worry here about the case (Connection: close) because + # the server should close the connection. + # - IF (NOT Connection: close) AND (NOT chunked encoding) AND + # (totalsize == 0). + + if { (!( [info exists state(connection)] + && ($state(connection) eq "close") + ) + ) + && (![info exists state(transfer)]) + && ($state(totalsize) == 0) } { Log "body size is 0 and no events likely - complete." Eof $token -- cgit v0.12 From 58eff8f224ea6ee52db925d9ff2a214f271a7e50 Mon Sep 17 00:00:00 2001 From: kjnash Date: Tue, 27 Mar 2018 08:10:50 +0000 Subject: Rename some variables and commands. Details in ticket 46b6edad51. --- library/http/http.tcl | 100 ++++++++++++++++++++++++++++---------------------- 1 file changed, 57 insertions(+), 43 deletions(-) diff --git a/library/http/http.tcl b/library/http/http.tcl index 16e0c19..f22dc17 100644 --- a/library/http/http.tcl +++ b/library/http/http.tcl @@ -60,14 +60,14 @@ namespace eval http { variable formMap [array get map] # Create a map for HTTP/1.1 open sockets - variable socketmap - if {[info exists socketmap]} { + variable socketMapping + if {[info exists socketMapping]} { # Close but don't remove open sockets on re-init - foreach {url sock} [array get socketmap] { + foreach {url sock} [array get socketMapping] { catch {close $sock} } } - array set socketmap {} + array set socketMapping {} return } init @@ -238,37 +238,37 @@ proc http::Finish {token {errormsg ""} {skipCB 0}} { # the second section. proc ::http::CloseSocket {s {token {}}} { - variable socketmap + variable socketMapping catch {fileevent $s readable {}} - set conn_id {} + set connId {} if {$token ne ""} { variable $token upvar 0 $token state if {[info exists state(socketinfo)]} { - set conn_id $state(socketinfo) + set connId $state(socketinfo) } } else { - set map [array get socketmap] + set map [array get socketMapping] set ndx [lsearch -exact $map $s] if {$ndx != -1} { incr ndx -1 - set conn_id [lindex $map $ndx] + set connId [lindex $map $ndx] } } - if {$conn_id eq {} || ![info exists socketmap($conn_id)]} { + if {$connId eq {} || ![info exists socketMapping($connId)]} { Log "Closing socket $s (no connection info)" if {[catch {close $s} err]} { Log "Error: $err" } } else { - if {[info exists socketmap($conn_id)]} { - Log "Closing connection $conn_id (sock $socketmap($conn_id))" - if {[catch {close $socketmap($conn_id)} err]} { + if {[info exists socketMapping($connId)]} { + Log "Closing connection $connId (sock $socketMapping($connId))" + if {[catch {close $socketMapping($connId)} err]} { Log "Error: $err" } - unset socketmap($conn_id) + unset socketMapping($connId) } else { - Log "Cannot close connection $conn_id - no socket in socket map" + Log "Cannot close connection $connId - no socket in socket map" } } return @@ -588,13 +588,13 @@ proc http::geturl {url args} { # See if we are supposed to use a previously opened channel. if {$state(-keepalive)} { - variable socketmap - if {[info exists socketmap($state(socketinfo))]} { - if {[catch {fconfigure $socketmap($state(socketinfo))}]} { + variable socketMapping + if {[info exists socketMapping($state(socketinfo))]} { + if {[catch {fconfigure $socketMapping($state(socketinfo))}]} { Log "WARNING: socket for $state(socketinfo) was closed" - unset socketmap($state(socketinfo)) + unset socketMapping($state(socketinfo)) } else { - set sock $socketmap($state(socketinfo)) + set sock $socketMapping($state(socketinfo)) Log "reusing socket $sock for $state(socketinfo)" catch {fileevent $sock writable {}} catch {fileevent $sock readable {}} @@ -624,7 +624,7 @@ proc http::geturl {url args} { Log "Using $sock for $state(socketinfo)" \ [expr {$state(-keepalive)?"keepalive":""}] if {$state(-keepalive)} { - set socketmap($state(socketinfo)) $sock + set socketMapping($state(socketinfo)) $sock } if {![info exists phost]} { @@ -1024,15 +1024,18 @@ proc http::Event {sock token} { return } if {$state(state) eq "connecting"} { - if {[catch {gets $sock state(http)} n]} { - return [Finish $token $n] - } elseif {$n >= 0} { + if {[catch {gets $sock state(http)} nsl]} { + return [Finish $token $nsl] + } elseif {$nsl >= 0} { set state(state) "header" + } else { + # nsl is -1 so either fblocked (OK) or eof. + # Continue. Any eof is processed at the end of this proc. } } elseif {$state(state) eq "header"} { - if {[catch {gets $sock line} n]} { - return [Finish $token $n] - } elseif {$n == 0} { + if {[catch {gets $sock line} nhl]} { + return [Finish $token $nhl] + } elseif {$nhl == 0} { # We have now read all headers # We ignore HTTP/1.1 100 Continue returns. RFC2616 sec 8.2.3 if { ($state(http) == "") @@ -1046,7 +1049,7 @@ proc http::Event {sock token} { # If doing a HEAD, then we won't get any body if {$state(-validate)} { - Eof $token + Eot $token return } @@ -1072,7 +1075,7 @@ proc http::Event {sock token} { && ($state(totalsize) == 0) } { Log "body size is 0 and no events likely - complete." - Eof $token + Eot $token return } @@ -1096,7 +1099,7 @@ proc http::Event {sock token} { return } } - } elseif {$n > 0} { + } elseif {$nhl > 0} { # Process header lines if {[regexp -nocase {^([^:]+):(.+)$} $line x key value]} { switch -- [string tolower $key] { @@ -1144,17 +1147,17 @@ proc http::Event {sock token} { append state(transfer_final) $line } else { Log "final chunk part" - Eof $token + Eot $token } } elseif { [info exists state(transfer)] && $state(transfer) eq "chunked" } { set size 0 - set chunk [getTextLine $sock] - set n [string length $chunk] - if {[string trim $chunk] ne ""} { - scan $chunk %x size + set hexLenChunk [getTextLine $sock] + set ntl [string length $hexLenChunk] + if {[string trim $hexLenChunk] ne ""} { + scan $hexLenChunk %x size if {$size != 0} { set bl [fconfigure $sock -blocking] fconfigure $sock -blocking 1 @@ -1170,6 +1173,7 @@ proc http::Event {sock token} { } getTextLine $sock } else { + set n 0 set state(transfer_final) {} } } @@ -1190,7 +1194,7 @@ proc http::Event {sock token} { ($state(totalsize) > 0) && ($state(currentsize) >= $state(totalsize)) } { - Eof $token + Eot $token } } } err]} { @@ -1203,11 +1207,11 @@ proc http::Event {sock token} { } } - # catch as an Eof above may have closed the socket already + # catch as an Eot above may have closed the socket already if {![catch {eof $sock} eof] && $eof} { if {[info exists $token]} { set state(connection) close - Eof $token + Eot $token } else { # open connection closed on a token that has been cleaned up. CloseSocket $sock @@ -1326,7 +1330,7 @@ proc http::CopyChunk {token chunk} { foreach stream $state(zlib) { $stream close } unset state(zlib) } - Eof $token ;# FIX ME: pipelining. + Eot $token ;# FIX ME: pipelining. } return } @@ -1355,24 +1359,34 @@ proc http::CopyDone {token count {error {}}} { if {[string length $error]} { Finish $token $error } elseif {[catch {eof $sock} iseof] || $iseof} { - Eof $token + Eot $token } else { CopyStart $sock $token 0 } return } -# http::Eof +# http::Eot +# +# Called when either: +# a. An eof condition is detected on the socket. +# b. The client decides that the response is complete. +# c. The client detects an inconsistency and aborts the transaction. # -# Handle eof on the socket +# Does: +# 1. Set state(status) +# 2. Reverse any Content-Encoding +# 3. Convert charset encoding and line ends if necessary +# 4. Call http::Finish # # Arguments # token The token returned from http::geturl +# force optional, has no effect # # Side Effects # Clean up the socket -proc http::Eof {token {force 0}} { +proc http::Eot {token {force 0}} { variable $token upvar 0 $token state if {$state(state) eq "header"} { -- cgit v0.12 From 3b48db4a90ae3ec99e9c2e85d5a3610262d77707 Mon Sep 17 00:00:00 2001 From: kjnash Date: Tue, 27 Mar 2018 08:12:47 +0000 Subject: Update some comments and a Log. --- library/http/http.tcl | 43 ++++++++++++++++++++++++++----------------- 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/library/http/http.tcl b/library/http/http.tcl index f22dc17..a6977f7 100644 --- a/library/http/http.tcl +++ b/library/http/http.tcl @@ -97,7 +97,11 @@ namespace eval http { } namespace export geturl config reset wait formatQuery register unregister - # Useful, but not exported: data size status code + # Useful, but not exported: data size status code cleanup error meta ncode + # Also mapReply. + # + # Not exported, probably should be upper-case initial letter as part + # of the internals: init getTextLine make-transformation-chunked } # http::Log -- @@ -199,7 +203,7 @@ proc http::config {args} { # reported to two places. # # Side Effects: -# Closes the socket +# May close the socket. proc http::Finish {token {errormsg ""} {skipCB 0}} { variable $token @@ -235,7 +239,7 @@ proc http::Finish {token {errormsg ""} {skipCB 0}} { # Close a socket and remove it from the persistent sockets table. If # possible an http token is included here but when we are called from a # fileevent on remote closure we need to find the correct entry - hence -# the second section. +# the "else" block of the first "if" command. proc ::http::CloseSocket {s {token {}}} { variable socketMapping @@ -600,7 +604,7 @@ proc http::geturl {url args} { catch {fileevent $sock readable {}} } } - # don't automatically close this connection socket + # Do not automatically close this connection socket. set state(connection) {} } if {![info exists sock]} { @@ -609,7 +613,7 @@ proc http::geturl {url args} { lappend sockopts -myaddr $state(-myaddr) } if {[catch {eval $defcmd $sockopts $targetAddr} sock]} { - # something went wrong while trying to establish the connection. + # Something went wrong while trying to establish the connection. # Clean up after events and such, but DON'T call the command # callback (if available) because we're going to throw an # exception from here instead. @@ -677,7 +681,7 @@ proc http::Connected {token proto phost srvurl} { variable $token upvar 0 $token state - # Set back the variables needed here + # Set back the variables needed here. set sock $state(sock) set isQueryChannel [info exists state(-querychannel)] set isQuery [info exists state(-query)] @@ -687,7 +691,7 @@ proc http::Connected {token proto phost srvurl} { set lower [string tolower $proto] set defport [lindex $urlTypes($lower) 0] - # Send data in cr-lf format, but accept any line terminators + # Send data in cr-lf format, but accept any line terminators. fconfigure $sock -translation {auto crlf} -buffersize $state(-blocksize) @@ -827,8 +831,8 @@ proc http::Connected {token proto phost srvurl} { # The socket probably was never connected, or the connection dropped # later. - # if state(status) is error, it means someone's already called Finish - # to do the above-described clean up. + # if state(status) is error, it means someone's already called + # Finish to do the above-described clean up. if {$state(status) ne "error"} { Finish $token $err } @@ -838,7 +842,7 @@ proc http::Connected {token proto phost srvurl} { # Data access functions: # Data - the URL data -# Status - the transaction status: ok, reset, eof, timeout +# Status - the transaction status: ok, reset, eof, timeout, error # Code - the HTTP transaction code, e.g., 200 # Size - the size of the URL data @@ -1085,7 +1089,7 @@ proc http::Event {sock token} { if { $state(-binary) || [IsBinaryContentType $state(type)] } { - # Turn off conversions for non-text data + # Turn off conversions for non-text data. set state(binary) 1 } if {[info exists state(-channel)]} { @@ -1093,19 +1097,19 @@ proc http::Event {sock token} { fconfigure $state(-channel) -translation binary } if {![info exists state(-handler)]} { - # Initiate a sequence of background fcopies + # Initiate a sequence of background fcopies. fileevent $sock readable {} CopyStart $sock $token return } } } elseif {$nhl > 0} { - # Process header lines + # Process header lines. if {[regexp -nocase {^([^:]+):(.+)$} $line x key value]} { switch -- [string tolower $key] { content-type { set state(type) [string trim [string tolower $value]] - # grab the optional charset information + # Grab the optional charset information. if {[regexp -nocase \ {charset\s*=\s*\"((?:[^""]|\\\")*)\"} \ $state(type) -> cs]} { @@ -1143,7 +1147,11 @@ proc http::Event {sock token} { set line [getTextLine $sock] set n [string length $line] if {$n > 0} { - Log "found $n bytes following final chunk" + # - HTTP trailers (late response headers) are permitted by + # Chunked Transfer-Encoding, and can be safely ignored. + # - Do not count these bytes in the total received for the + # response body. + Log "trailer of $n bytes after final chunk - token $token" append state(transfer_final) $line } else { Log "final chunk part" @@ -1255,6 +1263,7 @@ proc http::IsBinaryContentType {type} { # http::getTextLine -- # # Get one line with the stream in blocking crlf mode +# Used if Transfer-Encoding is chunked # # Arguments # sock The socket receiving input. @@ -1355,7 +1364,7 @@ proc http::CopyDone {token count {error {}}} { eval $state(-progress) \ [list $token $state(totalsize) $state(currentsize)] } - # At this point the token may have been reset + # At this point the token may have been reset. if {[string length $error]} { Finish $token $error } elseif {[catch {eof $sock} iseof] || $iseof} { @@ -1390,7 +1399,7 @@ proc http::Eot {token {force 0}} { variable $token upvar 0 $token state if {$state(state) eq "header"} { - # Premature eof + # Premature eof. set state(status) eof } else { set state(status) ok -- cgit v0.12 From 25aad1ab18e6ac7d57e72db5af7ed702e0ea1dc0 Mon Sep 17 00:00:00 2001 From: kjnash Date: Tue, 27 Mar 2018 08:15:26 +0000 Subject: Update some Log calls, mainly to specify token. --- library/http/http.tcl | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/library/http/http.tcl b/library/http/http.tcl index a6977f7..bfb2569 100644 --- a/library/http/http.tcl +++ b/library/http/http.tcl @@ -262,13 +262,13 @@ proc ::http::CloseSocket {s {token {}}} { if {$connId eq {} || ![info exists socketMapping($connId)]} { Log "Closing socket $s (no connection info)" if {[catch {close $s} err]} { - Log "Error: $err" + Log "Error closing socket: $err" } } else { if {[info exists socketMapping($connId)]} { Log "Closing connection $connId (sock $socketMapping($connId))" if {[catch {close $socketMapping($connId)} err]} { - Log "Error: $err" + Log "Error closing connection: $err" } unset socketMapping($connId) } else { @@ -595,11 +595,12 @@ proc http::geturl {url args} { variable socketMapping if {[info exists socketMapping($state(socketinfo))]} { if {[catch {fconfigure $socketMapping($state(socketinfo))}]} { - Log "WARNING: socket for $state(socketinfo) was closed" + Log "WARNING: socket for $state(socketinfo) was closed\ + - token $token" unset socketMapping($state(socketinfo)) } else { set sock $socketMapping($state(socketinfo)) - Log "reusing socket $sock for $state(socketinfo)" + Log "reusing socket $sock for $state(socketinfo) - token $token" catch {fileevent $sock writable {}} catch {fileevent $sock readable {}} } @@ -625,7 +626,7 @@ proc http::geturl {url args} { } } set state(sock) $sock - Log "Using $sock for $state(socketinfo)" \ + Log "Using $sock for $state(socketinfo) - token $token" \ [expr {$state(-keepalive)?"keepalive":""}] if {$state(-keepalive)} { set socketMapping($state(socketinfo)) $sock @@ -1021,7 +1022,8 @@ proc http::Event {sock token} { Log "Event $sock with invalid token '$token' - remote close?" if {![eof $sock]} { if {[set d [read $sock]] ne ""} { - Log "WARNING: additional data left on closed socket" + Log "WARNING: additional data left on closed socket\ + - token $token" } } CloseSocket $sock @@ -1078,7 +1080,8 @@ proc http::Event {sock token} { && (![info exists state(transfer)]) && ($state(totalsize) == 0) } { - Log "body size is 0 and no events likely - complete." + set msg {body size is 0 and no events likely - complete} + Log "$msg - token $token" Eot $token return } @@ -1154,7 +1157,7 @@ proc http::Event {sock token} { Log "trailer of $n bytes after final chunk - token $token" append state(transfer_final) $line } else { - Log "final chunk part" + Log "final chunk part - token $token" Eot $token } } elseif { @@ -1177,7 +1180,8 @@ proc http::Event {sock token} { } if {$size != [string length $chunk]} { Log "WARNING: mis-sized chunk:\ - was [string length $chunk], should be $size" + was [string length $chunk], should be $size -\ + token $token" } getTextLine $sock } else { @@ -1186,7 +1190,9 @@ proc http::Event {sock token} { } } } else { - #Log "read non-chunk $state(currentsize) of $state(totalsize)" + set c $state(currentsize) + set t $state(totalsize) + ##Log non-chunk currentsize $c of totalsize $t - token $token set block [read $sock $state(-blocksize)] set n [string length $block] if {$n >= 0} { @@ -1329,7 +1335,7 @@ proc http::CopyChunk {token chunk} { $token $state(totalsize) $state(currentsize)] } } else { - Log "CopyChunk Finish $token" + Log "CopyChunk Finish - token $token" if {[info exists state(zlib)]} { set excess "" foreach stream $state(zlib) { @@ -1411,7 +1417,7 @@ proc http::Eot {token {force 0}} { set state(body) [zlib $coding $state(body)] } } err]} { - Log "error doing decompression: $err" + Log "error doing decompression for token $token: $err" return [Finish $token $err] } -- cgit v0.12 From 4f8b1772509919a3fae2017482774f3714a4d5b7 Mon Sep 17 00:00:00 2001 From: kjnash Date: Tue, 27 Mar 2018 08:17:38 +0000 Subject: Tidying - add empty else clauses, omit :: at start of command name http::CloseSocket in proc definition, use two lines instead of "return [Finish ...]" because there is no return value! --- library/http/http.tcl | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/library/http/http.tcl b/library/http/http.tcl index bfb2569..c429138 100644 --- a/library/http/http.tcl +++ b/library/http/http.tcl @@ -241,7 +241,7 @@ proc http::Finish {token {errormsg ""} {skipCB 0}} { # fileevent on remote closure we need to find the correct entry - hence # the "else" block of the first "if" command. -proc ::http::CloseSocket {s {token {}}} { +proc http::CloseSocket {s {token {}}} { variable socketMapping catch {fileevent $s readable {}} set connId {} @@ -250,6 +250,7 @@ proc ::http::CloseSocket {s {token {}}} { upvar 0 $token state if {[info exists state(socketinfo)]} { set connId $state(socketinfo) + } else { } } else { set map [array get socketMapping] @@ -257,18 +258,21 @@ proc ::http::CloseSocket {s {token {}}} { if {$ndx != -1} { incr ndx -1 set connId [lindex $map $ndx] + } else { } } if {$connId eq {} || ![info exists socketMapping($connId)]} { Log "Closing socket $s (no connection info)" if {[catch {close $s} err]} { Log "Error closing socket: $err" + } else { } } else { if {[info exists socketMapping($connId)]} { Log "Closing connection $connId (sock $socketMapping($connId))" if {[catch {close $socketMapping($connId)} err]} { Log "Error closing connection: $err" + } else { } unset socketMapping($connId) } else { @@ -1031,7 +1035,8 @@ proc http::Event {sock token} { } if {$state(state) eq "connecting"} { if {[catch {gets $sock state(http)} nsl]} { - return [Finish $token $nsl] + Finish $token $nsl + return } elseif {$nsl >= 0} { set state(state) "header" } else { @@ -1040,7 +1045,8 @@ proc http::Event {sock token} { } } elseif {$state(state) eq "header"} { if {[catch {gets $sock line} nhl]} { - return [Finish $token $nhl] + Finish $token $nhl + return } elseif {$nhl == 0} { # We have now read all headers # We ignore HTTP/1.1 100 Continue returns. RFC2616 sec 8.2.3 @@ -1212,7 +1218,8 @@ proc http::Event {sock token} { } } } err]} { - return [Finish $token $err] + Finish $token $err + return } else { if {[info exists state(-progress)]} { eval $state(-progress) \ @@ -1418,7 +1425,8 @@ proc http::Eot {token {force 0}} { } } err]} { Log "error doing decompression for token $token: $err" - return [Finish $token $err] + Finish $token $err + return } if {!$state(binary)} { -- cgit v0.12 From a8408767a49483d5bbca7cb51addc85b0d1ee9fd Mon Sep 17 00:00:00 2001 From: kjnash Date: Tue, 27 Mar 2018 08:20:14 +0000 Subject: Add "array unset socketMapping" in http::init. The sockets are closed and therefore do not belong in socketMapping, which should be unset. --- library/http/http.tcl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/library/http/http.tcl b/library/http/http.tcl index c429138..77eae1b 100644 --- a/library/http/http.tcl +++ b/library/http/http.tcl @@ -62,11 +62,12 @@ namespace eval http { # Create a map for HTTP/1.1 open sockets variable socketMapping if {[info exists socketMapping]} { - # Close but don't remove open sockets on re-init + # Close open sockets on re-init foreach {url sock} [array get socketMapping] { catch {close $sock} } } + array unset socketMapping array set socketMapping {} return } -- cgit v0.12 From b00317d1742830de2509ee2020d19c46ff0dd665 Mon Sep 17 00:00:00 2001 From: kjnash Date: Tue, 27 Mar 2018 08:25:14 +0000 Subject: Changes to response handling in Finish, Eot and Event. Carefully distinguish expected and premature eof. Stricter handling of errors, minor bugfixes. Details in ticket 46b6edad51. --- library/http/http.tcl | 113 ++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 104 insertions(+), 9 deletions(-) diff --git a/library/http/http.tcl b/library/http/http.tcl index 77eae1b..5b9d03a 100644 --- a/library/http/http.tcl +++ b/library/http/http.tcl @@ -216,6 +216,7 @@ proc http::Finish {token {errormsg ""} {skipCB 0}} { } if { ($state(status) eq "timeout") || ($state(status) eq "error") + || ($state(status) eq "eof") || ([info exists state(-keepalive)] && !$state(-keepalive)) || ([info exists state(connection)] && ($state(connection) eq "close")) } { @@ -1023,6 +1024,8 @@ proc http::Event {sock token} { variable $token upvar 0 $token state + ##Log Event call - token $token + if {![info exists state]} { Log "Event $sock with invalid token '$token' - remote close?" if {![eof $sock]} { @@ -1035,20 +1038,25 @@ proc http::Event {sock token} { return } if {$state(state) eq "connecting"} { + ##Log - connecting - token $token if {[catch {gets $sock state(http)} nsl]} { Finish $token $nsl return } elseif {$nsl >= 0} { + ##Log - connecting 1 - token $token set state(state) "header" } else { + ##Log - connecting 2 - token $token # nsl is -1 so either fblocked (OK) or eof. # Continue. Any eof is processed at the end of this proc. } } elseif {$state(state) eq "header"} { if {[catch {gets $sock line} nhl]} { + ##Log header failed - token $token Finish $token $nhl return } elseif {$nhl == 0} { + ##Log header done - token $token # We have now read all headers # We ignore HTTP/1.1 100 Continue returns. RFC2616 sec 8.2.3 if { ($state(http) == "") @@ -1062,6 +1070,7 @@ proc http::Event {sock token} { # If doing a HEAD, then we won't get any body if {$state(-validate)} { + set state(state) complete Eot $token return } @@ -1089,6 +1098,7 @@ proc http::Event {sock token} { } { set msg {body size is 0 and no events likely - complete} Log "$msg - token $token" + set state(state) complete Eot $token return } @@ -1115,6 +1125,7 @@ proc http::Event {sock token} { } } elseif {$nhl > 0} { # Process header lines. + ##Log header - token $token - $line if {[regexp -nocase {^([^:]+):(.+)$} $line x key value]} { switch -- [string tolower $key] { content-type { @@ -1150,12 +1161,46 @@ proc http::Event {sock token} { } } else { # Now reading body + ##Log body - token $token if {[catch { if {[info exists state(-handler)]} { set n [eval $state(-handler) [list $sock $token]] + ##Log handler $n - token $token + # N.B. the protocol has been set to 1.0 because the -handler + # logic is not expected to handle chunked encoding. + # FIXME allow -handler with 1.1 on dechunked stacked channel. + if {$state(totalsize) == 0} { + # We know the transfer is complete only when the server + # closes the connection - i.e. eof is not an error. + set state(state) complete + } + if {![string is integer -strict $n]} { + if 1 { + # Do not tolerate bad -handler - fail with error status. + set msg {the -handler command for http::geturl must\ + return an integer (the number of bytes read)} + Eot $token $msg + } else { + # Tolerate the bad -handler, and continue. The penalty: + # (a) Because the handler returns nonsense, we know the + # transfer is complete only when the server closes + # the connection - i.e. eof is not an error. + # (b) http::size will not be accurate. + # (c) The transaction is already downgraded to 1.0 to + # avoid chunked transfer encoding. It MUST also be + # forced to "Connection: close" or the HTTP/1.0 + # equivalent; or it MUST fail (as above) if the + # server sends "Connection: keep-alive" or the + # HTTP/1.0 equivalent. + set n 0 + set state(state) complete + } + } else { + } } elseif {[info exists state(transfer_final)]} { set line [getTextLine $sock] set n [string length $line] + set state(state) complete if {$n > 0} { # - HTTP trailers (late response headers) are permitted by # Chunked Transfer-Encoding, and can be safely ignored. @@ -1163,20 +1208,22 @@ proc http::Event {sock token} { # response body. Log "trailer of $n bytes after final chunk - token $token" append state(transfer_final) $line + set n 0 } else { Log "final chunk part - token $token" Eot $token } - } elseif { - [info exists state(transfer)] - && $state(transfer) eq "chunked" + } elseif { [info exists state(transfer)] + && ($state(transfer) eq "chunked") } { + ##Log chunked - token $token set size 0 set hexLenChunk [getTextLine $sock] - set ntl [string length $hexLenChunk] + #set ntl [string length $hexLenChunk] if {[string trim $hexLenChunk] ne ""} { scan $hexLenChunk %x size if {$size != 0} { + ##Log chunk-measure $size - token $token set bl [fconfigure $sock -blocking] fconfigure $sock -blocking 1 set chunk [read $sock $size] @@ -1184,19 +1231,39 @@ proc http::Event {sock token} { set n [string length $chunk] if {$n >= 0} { append state(body) $chunk + incr state(log_size) [string length $chunk] + ##Log chunk $n cumul $state(log_size) - token $token } if {$size != [string length $chunk]} { Log "WARNING: mis-sized chunk:\ was [string length $chunk], should be $size -\ token $token" + set n 0 + set state(connection) close + set msg {error in chunked encoding - fetch\ + terminated} + Eot $token $msg } + # CRLF that follows chunk: getTextLine $sock } else { set n 0 set state(transfer_final) {} } + } else { + # Line expected to hold chunk length is empty. + ##Log bad-chunk-measure - token $token + set n 0 + set state(connection) close + Eot $token {error in chunked encoding - fetch terminated} } } else { + ##Log unchunked - token $token + if {$state(totalsize) == 0} { + # We know the transfer is complete only when the server + # closes the connection. + set state(state) complete + } set c $state(currentsize) set t $state(totalsize) ##Log non-chunk currentsize $c of totalsize $t - token $token @@ -1204,17 +1271,24 @@ proc http::Event {sock token} { set n [string length $block] if {$n >= 0} { append state(body) $block + ##Log non-chunk [string length $state(body)] - token $token } } + # This calculation uses n from the -handler, chunked, or unchunked + # case as appropriate. if {[info exists state]} { if {$n >= 0} { incr state(currentsize) $n + set c $state(currentsize) + set t $state(totalsize) + ##Log chunk $n currentsize $c totalsize $t - token $token } # If Content-Length - check for end of data. if { ($state(totalsize) > 0) && ($state(currentsize) >= $state(totalsize)) } { + set state(state) complete Eot $token } } @@ -1230,10 +1304,21 @@ proc http::Event {sock token} { } # catch as an Eot above may have closed the socket already + # $state(state) may be connecting, header, body, or complete if {![catch {eof $sock} eof] && $eof} { + ##Log eof - token $token if {[info exists $token]} { set state(connection) close - Eot $token + if {$state(state) eq "complete"} { + # This includes all cases in which the transaction + # can be completed by eof. + # The value "complete" is set only in http::Event, and it is + # used only in the test above. + Eot $token + } else { + # Premature eof. + Eot $token eof + } } else { # open connection closed on a token that has been cleaned up. CloseSocket $sock @@ -1404,18 +1489,28 @@ proc http::CopyDone {token count {error {}}} { # # Arguments # token The token returned from http::geturl -# force optional, has no effect +# force (previously) optional, has no effect +# reason - "eof" means premature EOF (not EOF as the natural end of +# the response) +# - "" means completion of response, with or without EOF +# - anything else describes an error confition other than +# premature EOF. # # Side Effects # Clean up the socket -proc http::Eot {token {force 0}} { +proc http::Eot {token {reason {}}} { variable $token upvar 0 $token state - if {$state(state) eq "header"} { + if {$reason eq "eof"} { # Premature eof. set state(status) eof + set reason {} + } elseif {$reason ne ""} { + # Abort the transaction. + set state(status) $reason } else { + # The response is complete. set state(status) ok } @@ -1445,7 +1540,7 @@ proc http::Eot {token {force 0}} { set state(body) [string map {\r\n \n \r \n} $state(body)] } } - Finish $token + Finish $token $reason return } -- cgit v0.12 From 767cf6314a06f14d275746f66df21ef6ee324715 Mon Sep 17 00:00:00 2001 From: kjnash Date: Tue, 27 Mar 2018 08:29:43 +0000 Subject: Workaround for bug with https and unchunked response. A [read] does not deliver until the server closes the socket. The workaround is to specify the buffer size as the precise length required. --- library/http/http.tcl | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/library/http/http.tcl b/library/http/http.tcl index 5b9d03a..d67e217 100644 --- a/library/http/http.tcl +++ b/library/http/http.tcl @@ -1263,11 +1263,23 @@ proc http::Event {sock token} { # We know the transfer is complete only when the server # closes the connection. set state(state) complete + set reqSize $state(-blocksize) + } else { + # Ask for the whole of the unserved response-body. + # This works around a problem with a tls::socket - for https + # in keep-alive mode, and a request for $state(-blocksize) + # bytes, the last part of the resource does not get read + # until the server times out. + set reqSize [expr {$state(totalsize) - $state(currentsize)}] + + # The workaround fails if reqSize is + # capped at $state(-blocksize). + # set reqSize [expr {min($reqSize, $state(-blocksize))}] } set c $state(currentsize) set t $state(totalsize) ##Log non-chunk currentsize $c of totalsize $t - token $token - set block [read $sock $state(-blocksize)] + set block [read $sock $reqSize] set n [string length $block] if {$n >= 0} { append state(body) $block @@ -1404,6 +1416,10 @@ proc http::CopyStart {sock token {initial 1}} { } } if {[catch { + # FIXME Keep-Alive on https tls::socket with unchunked transfer + # hangs until the server times out. A workaround is possible, as for + # the case without -channel, but it does not use the neat "fcopy" + # solution. fcopy $sock $state(-channel) -size $state(-blocksize) -command \ [list http::CopyDone $token] } err]} { -- cgit v0.12 From 731f40c6d954e4bb641cb336383eb4ea5d204b92 Mon Sep 17 00:00:00 2001 From: kjnash Date: Tue, 27 Mar 2018 08:32:37 +0000 Subject: New http::config option -zip to control whether to send an "Accept-Encoding" request-header for a zipped response. Default true for backward compatibility. --- library/http/http.tcl | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/library/http/http.tcl b/library/http/http.tcl index d67e217..9069291 100644 --- a/library/http/http.tcl +++ b/library/http/http.tcl @@ -24,6 +24,7 @@ namespace eval http { -proxyport {} -proxyfilter http::ProxyRequired -urlencoding utf-8 + -zip 1 } # We need a useragent string of this style or various servers will # refuse to send us compressed content even when we ask for it. This @@ -787,7 +788,10 @@ proc http::Connected {token proto phost srvurl} { if {!$accept_types_seen} { puts $sock "Accept: $state(accept-types)" } - if {!$accept_encoding_seen && ![info exists state(-handler)]} { + if { (!$accept_encoding_seen) + && (![info exists state(-handler)]) + && $http(-zip) + } { puts $sock "Accept-Encoding: gzip,deflate,compress" } if {$isQueryChannel && ($state(querylength) == 0)} { -- cgit v0.12 From e80e2146736e8176a0364b03fd8ad0fefe92e8d6 Mon Sep 17 00:00:00 2001 From: kjnash Date: Tue, 27 Mar 2018 08:37:06 +0000 Subject: BUGFIX. Send "Connection: keep-alive" even if HTTP/1.1. Some servers (including Apache 2.2 on RHEL6) use the discretion granted by RFCs and will close the connection unless this header is sent. --- library/http/http.tcl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/library/http/http.tcl b/library/http/http.tcl index 9069291..485498a 100644 --- a/library/http/http.tcl +++ b/library/http/http.tcl @@ -749,7 +749,9 @@ proc http::Connected {token proto phost srvurl} { puts $sock "Host: $host:$port" } puts $sock "User-Agent: $http(-useragent)" - if {($state(-protocol) == 1.0) && $state(-keepalive)} { + if {($state(-protocol) >= 1.0) && $state(-keepalive)} { + # Send this header, because a 1.1 server is not compelled to treat + # this as the default. puts $sock "Connection: keep-alive" } if {($state(-protocol) > 1.0) && !$state(-keepalive)} { -- cgit v0.12 From f35c0dc2edcc96ff38d150cd621cea7b771c9a4c Mon Sep 17 00:00:00 2001 From: kjnash Date: Tue, 27 Mar 2018 08:49:13 +0000 Subject: Revise tests/http11.test for use with commits from 78b23edb6b onwards. Adjust proc "handler" to conform to http(n) --- tests/http11.test | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/tests/http11.test b/tests/http11.test index c9ded0b..8483aa3 100644 --- a/tests/http11.test +++ b/tests/http11.test @@ -515,10 +515,7 @@ proc handler {var sock token} { set chunk [read $sock] append data $chunk #::http::Log "handler read [string length $chunk] ([chan configure $sock -buffersize])" - if {[eof $sock]} { - #::http::Log "handler eof $sock" - chan event $sock readable {} - } + return [string length $chunk] } test http11-3.0 "-handler,close,identity" -setup { -- cgit v0.12 From e9bb0992b0f392798d2d978f2bdcbc62aa6ea602 Mon Sep 17 00:00:00 2001 From: kjnash Date: Tue, 27 Mar 2018 08:52:40 +0000 Subject: First step for implementing concurrent requests using the same connection. Define namespace variables socket* and http where they will (eventually) be used. Leave them unused except in http::init where they are initialised. --- library/http/http.tcl | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/library/http/http.tcl b/library/http/http.tcl index 485498a..8b4d714 100644 --- a/library/http/http.tcl +++ b/library/http/http.tcl @@ -62,14 +62,35 @@ namespace eval http { # Create a map for HTTP/1.1 open sockets variable socketMapping + variable socketRdState + variable socketWrState + variable socketRdQueue + variable socketWrQueue + variable socketClosing + variable socketPlayCmd if {[info exists socketMapping]} { # Close open sockets on re-init foreach {url sock} [array get socketMapping] { catch {close $sock} } } + + # Traces on "unset socketRdState(*)" will cancel any queued responses. + # Traces on "unset socketWrState(*)" will cancel any queued requests. array unset socketMapping + array unset socketRdState + array unset socketWrState + array unset socketRdQueue + array unset socketWrQueue + array unset socketClosing + array unset socketPlayCmd array set socketMapping {} + array set socketRdState {} + array set socketWrState {} + array set socketRdQueue {} + array set socketWrQueue {} + array set socketClosing {} + array set socketPlayCmd {} return } init @@ -208,6 +229,14 @@ proc http::config {args} { # May close the socket. proc http::Finish {token {errormsg ""} {skipCB 0}} { + variable socketMapping + variable socketRdState + variable socketWrState + variable socketRdQueue + variable socketWrQueue + variable socketClosing + variable socketPlayCmd + variable $token upvar 0 $token state global errorInfo errorCode @@ -246,6 +275,13 @@ proc http::Finish {token {errormsg ""} {skipCB 0}} { proc http::CloseSocket {s {token {}}} { variable socketMapping + variable socketRdState + variable socketWrState + variable socketRdQueue + variable socketWrQueue + variable socketClosing + variable socketPlayCmd + catch {fileevent $s readable {}} set connId {} if {$token ne ""} { @@ -600,6 +636,13 @@ proc http::geturl {url args} { # See if we are supposed to use a previously opened channel. if {$state(-keepalive)} { variable socketMapping + variable socketRdState + variable socketWrState + variable socketRdQueue + variable socketWrQueue + variable socketClosing + variable socketPlayCmd + if {[info exists socketMapping($state(socketinfo))]} { if {[catch {fconfigure $socketMapping($state(socketinfo))}]} { Log "WARNING: socket for $state(socketinfo) was closed\ @@ -685,6 +728,13 @@ proc http::geturl {url args} { proc http::Connected {token proto phost srvurl} { variable http variable urlTypes + variable socketMapping + variable socketRdState + variable socketWrState + variable socketRdQueue + variable socketWrQueue + variable socketClosing + variable socketPlayCmd variable $token upvar 0 $token state @@ -962,6 +1012,15 @@ proc http::Connect {token proto phost srvurl} { # Write the socket and handle callbacks. proc http::Write {token} { + variable http + variable socketMapping + variable socketRdState + variable socketWrState + variable socketRdQueue + variable socketWrQueue + variable socketClosing + variable socketPlayCmd + variable $token upvar 0 $token state set sock $state(sock) @@ -1027,6 +1086,15 @@ proc http::Write {token} { # Read the socket and handle callbacks. proc http::Event {sock token} { + variable http + variable socketMapping + variable socketRdState + variable socketWrState + variable socketRdQueue + variable socketWrQueue + variable socketClosing + variable socketPlayCmd + variable $token upvar 0 $token state -- cgit v0.12 From 0d887fa4657702c34d0b109df9e2634a563e5178 Mon Sep 17 00:00:00 2001 From: kjnash Date: Tue, 27 Mar 2018 08:55:21 +0000 Subject: Define variable tk used in Log calls for testing. --- library/http/http.tcl | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/library/http/http.tcl b/library/http/http.tcl index 8b4d714..2a5bc24 100644 --- a/library/http/http.tcl +++ b/library/http/http.tcl @@ -282,6 +282,8 @@ proc http::CloseSocket {s {token {}}} { variable socketClosing variable socketPlayCmd + set tk [namespace tail $token] + catch {fileevent $s readable {}} set connId {} if {$token ne ""} { @@ -375,6 +377,7 @@ proc http::geturl {url args} { set token [namespace current]::[incr http(uid)] variable $token upvar 0 $token state + set tk [namespace tail $token] reset $token # Process command options. @@ -738,6 +741,7 @@ proc http::Connected {token proto phost srvurl} { variable $token upvar 0 $token state + set tk [namespace tail $token] # Set back the variables needed here. set sock $state(sock) @@ -988,6 +992,7 @@ proc http::cleanup {token} { proc http::Connect {token proto phost srvurl} { variable $token upvar 0 $token state + set tk [namespace tail $token] set err "due to unexpected EOF" if { [eof $state(sock)] || @@ -1023,6 +1028,7 @@ proc http::Write {token} { variable $token upvar 0 $token state + set tk [namespace tail $token] set sock $state(sock) # Output a block. Tcl will buffer this if the socket blocks @@ -1097,6 +1103,7 @@ proc http::Event {sock token} { variable $token upvar 0 $token state + set tk [namespace tail $token] ##Log Event call - token $token -- cgit v0.12 From d38ae8f97463f0a3fc07324aeae3de9508dbe9cc Mon Sep 17 00:00:00 2001 From: kjnash Date: Tue, 27 Mar 2018 08:56:16 +0000 Subject: Adapt fconfigure -translation for two-way pipelined operation. --- library/http/http.tcl | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/library/http/http.tcl b/library/http/http.tcl index 2a5bc24..06f452d 100644 --- a/library/http/http.tcl +++ b/library/http/http.tcl @@ -676,8 +676,13 @@ proc http::geturl {url args} { Finish $token "" 1 cleanup $token return -code error $sock + } else { + # Initialisation of a new socket. + fconfigure $sock -translation {auto crlf} \ + -buffersize $state(-blocksize) } } + set state(sock) $sock Log "Using $sock for $state(socketinfo) - token $token" \ [expr {$state(-keepalive)?"keepalive":""}] @@ -754,8 +759,11 @@ proc http::Connected {token proto phost srvurl} { set defport [lindex $urlTypes($lower) 0] # Send data in cr-lf format, but accept any line terminators. - - fconfigure $sock -translation {auto crlf} -buffersize $state(-blocksize) + # Initialisation to {auto *} now done in geturl. + # We are concerned here with the request (write) not the response (read). + lassign [fconfigure $sock -translation] trRead trWrite + fconfigure $sock -translation [list $trRead crlf] \ + -buffersize $state(-blocksize) # The following is disallowed in safe interpreters, but the socket is # already in non-blocking mode in that case. @@ -778,7 +786,9 @@ proc http::Connected {token proto phost srvurl} { set how POST # The query channel must be blocking for the async Write to # work properly. - fconfigure $state(-querychannel) -blocking 1 -translation binary + lassign [fconfigure $sock -translation] trRead trWrite + fconfigure $state(-querychannel) -blocking 1 \ + -translation [list $trRead binary] set contDone 0 } if {[info exists state(-method)] && ($state(-method) ne "")} { @@ -886,7 +896,8 @@ proc http::Connected {token proto phost srvurl} { puts $sock "Content-Length: $state(querylength)" } puts $sock "" - fconfigure $sock -translation {auto binary} + lassign [fconfigure $sock -translation] trRead trWrite + fconfigure $sock -translation [list $trRead binary] fileevent $sock writable [list http::Write $token] } else { puts $sock "" @@ -1185,7 +1196,8 @@ proc http::Event {sock token} { } # We have to use binary translation to count bytes properly. - fconfigure $sock -translation binary + lassign [fconfigure $sock -translation] trRead trWrite + fconfigure $sock -translation [list binary $trWrite] if { $state(-binary) || [IsBinaryContentType $state(type)] @@ -1465,8 +1477,9 @@ proc http::IsBinaryContentType {type} { proc http::getTextLine {sock} { set tr [fconfigure $sock -translation] + lassign $tr trRead trWrite set bl [fconfigure $sock -blocking] - fconfigure $sock -translation crlf -blocking 1 + fconfigure $sock -translation [list crlf $trWrite] -blocking 1 set r [gets $sock] fconfigure $sock -translation $tr -blocking $bl return $r -- cgit v0.12 From 70af5c2b8260845974300e98c2e4c464b787d94e Mon Sep 17 00:00:00 2001 From: kjnash Date: Tue, 27 Mar 2018 14:20:23 +0000 Subject: Implement queuing and pipelining for HTTP requests over a persistent connection. --- doc/http.n | 159 ++++- library/http/http.tcl | 1448 ++++++++++++++++++++++++++++++++++++++++++++-- tests/httpPipeline.test | 859 +++++++++++++++++++++++++++ tests/httpTest.tcl | 431 ++++++++++++++ tests/httpTestScript.tcl | 509 ++++++++++++++++ 5 files changed, 3356 insertions(+), 50 deletions(-) create mode 100644 tests/httpPipeline.test create mode 100644 tests/httpTest.tcl create mode 100644 tests/httpTestScript.tcl diff --git a/doc/http.n b/doc/http.n index 40ced23..2dae77e 100644 --- a/doc/http.n +++ b/doc/http.n @@ -6,14 +6,14 @@ '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. '\" -.TH "http" n 2.7 http "Tcl Bundled Packages" +.TH "http" n 2.8 http "Tcl Bundled Packages" .so man.macros .BS '\" Note: do not modify the .SH NAME line immediately below! .SH NAME http \- Client-side implementation of the HTTP/1.1 protocol .SH SYNOPSIS -\fBpackage require http ?2.7?\fR +\fBpackage require http ?2.8?\fR .\" See Also -useragent option documentation in body! .sp \fB::http::config ?\fI\-option value\fR ...? @@ -49,7 +49,7 @@ http \- Client-side implementation of the HTTP/1.1 protocol .SH DESCRIPTION .PP The \fBhttp\fR package provides the client side of the HTTP/1.1 -protocol, as defined in RFC 2616. +protocol, as defined in RFC 7230 to RFC 7235, which supersede RFC 2616. The package implements the GET, POST, and HEAD operations of HTTP/1.1. It allows configuration of a proxy host to get through firewalls. The package is compatible with the \fBSafesock\fR security @@ -95,6 +95,19 @@ comma-separated list of mime type patterns that you are willing to receive. For example, .QW "image/gif, image/jpeg, text/*" . .TP +\fB\-pipeline\fR \fIboolean\fR +. +Specifies whether HTTP/1.1 transactions on a persistent socket will be +pipelined. See the \fBPERSISTENT SOCKETS\fR section for details. The default +is 1. +.TP +\fB\-postfresh\fR \fIboolean\fR +. +Specifies whether requests that use the \fBPOST\fR method will always use a +fresh socket, overriding the \fB-keepalive\fR option of +command \fBhttp::geturl\fR. See the \fBPERSISTENT SOCKETS\fR section for details. +The default is 0. +.TP \fB\-proxyhost\fR \fIhostname\fR . The name of the proxy host, if any. If this value is the @@ -116,6 +129,18 @@ an empty list. The default filter returns the values of the \fB\-proxyhost\fR and \fB\-proxyport\fR settings if they are non-empty. .TP +\fB\-repost\fR \fIboolean\fR +. +Specifies what to do if a POST request over a persistent connection fails +because the server has half-closed the connection. If boolean \fBtrue\fR, the +request +will be automatically retried; if boolean \fBfalse\fR it will not, and the +application +that uses \fBhttp::geturl\fR is expected to seek user confirmation before +retrying the POST. The value \fBtrue\fR should be used only under certain +conditions. See the \fBPERSISTENT SOCKETS\fR section for details. The +default is 0. +.TP \fB\-urlencoding\fR \fIencoding\fR . The \fIencoding\fR used for creating the x-url-encoded URLs with @@ -128,8 +153,22 @@ characters. .TP \fB\-useragent\fR \fIstring\fR . -The value of the User-Agent header in the HTTP request. The default is -.QW "\fBTcl http client package 2.7\fR" . +The value of the User-Agent header in the HTTP request. In an unsafe +interpreter, the default value depends upon the operating system, and +the version numbers of \fBhttp\fR and \fBTcl\fR, and is (for example) +.QW "\fBMozilla/5.0 (Windows; U; Windows NT 10.0) http/2.8.12 Tcl/8.6.8\fR" . +A safe interpreter cannot determine its operating system, and so the default +in a safe interpreter is to use a Windows 10 value with the current version +numbers of \fBhttp\fR and \fBTcl\fR. +.TP +\fB\-zip\fR \fIboolean\fR +. +If the value is boolean \fBtrue\fR, then by default requests will send a header +.QW "\fBAccept-Encoding: gzip,deflate,compress\fR" . +If the value is boolean \fBfalse\fR, then by default this header will not be sent. +In either case the default can be overridden for an individual request by +supplying a custom \fBAccept-Encoding\fR header in the \fB-headers\fR option +of \fBhttp::geturl\fR. The default is 1. .RE .TP \fB::http::geturl\fR \fIurl\fR ?\fIoptions\fR? @@ -227,7 +266,7 @@ Pragma: no-cache .TP \fB\-keepalive\fR \fIboolean\fR . -If true, attempt to keep the connection open for servicing +If boolean \fBtrue\fR, attempt to keep the connection open for servicing multiple requests. Default is 0. .TP \fB\-method\fR \fItype\fR @@ -504,6 +543,14 @@ The following elements of the array are supported: .RS .TP +\fBbinary\fR +. +This is boolean \fBtrue\fR if (after decoding any compression specified +by the +.QW "Content-Encoding" +response header) the HTTP response is binary. It is boolean \fBfalse\fR +if the HTTP response is text. +.TP \fBbody\fR . The contents of the URL. This will be empty if the \fB\-channel\fR @@ -602,6 +649,106 @@ A copy of the \fBContent-Type\fR meta-data value. . The requested URL. .RE +.SH "PERSISTENT CONNECTIONS" +.PP +.SS "BASICS" +.PP +See RFC 7230 Sec 6, which supersedes RFC 2616 Sec 8.1. +.PP +A persistent connection allows multiple HTTP/1.1 transactions to be +carried over the same TCP connection. Pipelining allows a +client to make multiple requests over a persistent connection without +waiting for each response. The server sends responses in the same order +that the requests were received. +.PP +If a POST request fails to complete, typically user confirmation is +needed before sending the request again. The user may wish to verify +whether the server was modified by the failed POST request, before +sending the same request again. +.PP +A HTTP request will use a persistent socket if the call to +\fBhttp::geturl\fR has the option \fB-keepalive true\fR. It will use +pipelining where permitted if the \fBhttp::config\fR option +\fB-pipeline\fR is boolean \fBtrue\fR (its default value). +.PP +The http package maintains no more than one persistent connection to each +server (i.e. each value of +.QW "domain:port" ). +If \fBhttp::geturl\fR is called to make a request over a persistent +connection while the connection is busy with another request, the new +request will be held in a queue until the connection is free. +.PP +The http package does not support HTTP/1.0 persistent connections +controlled by the \fBKeep-Alive\fR header. +.SS "SPECIAL CASES" +.PP +This subsection discusses issues related to closure of the +persistent connection by the server, automatic retry of failed requests, +the special treatment necessary for POST requests, and the options for +dealing with these cases. +.PP +In accordance with RFC 7230, \fBhttp::geturl\fR does not pipeline +requests that use the POST method. If a POST uses a persistent +connection and is not the first request on that connection, +\fBhttp::geturl\fR waits until it has received the response for the previous +request; or (if \fBhttp::config\fR option \fB-postfresh\fR is boolean \fBtrue\fR) it +uses a new connection for each POST. +.PP +If the server is processing a number of pipelined requests, and sends a +response header +.QW "\fBConnection: close\fR" +with one of the responses (other than the last), then subsequent responses +are unfulfilled. \fBhttp::geturl\fR will send the unfulfilled requests again +over a new connection. +.PP +A difficulty arises when a HTTP client sends a request over a persistent +connection that has been idle for a while. The HTTP server may +half-close an apparently idle connection while the client is sending a +request, but before the request arrives at the server: in this case (an +.QW "asynchronous close event" ) +the request will fail. The difficulty arises because the client cannot +be certain whether the POST modified the state of the server. For HEAD or +GET requests, \fBhttp::geturl\fR opens another connection and retransmits +the failed request. However, if the request was a POST, RFC 7230 forbids +automatic retry by default, suggesting either user confirmation, or +confirmation by user-agent software that has semantic understanding of +the application. The \fBhttp::config\fR option \fB-repost\fR allows for +either possibility. +.PP +Asynchronous close events can occur only in a short interval of time. The +\fBhttp\fR package monitors each persistent connection for closure by the +server. Upon detection, the connection is also closed at the client end, +and subsequent requests will use a fresh connection. +.PP +If the \fBhttp::geturl\fR command is called with option \fB-keepalive true\fR, +then it will both try to use an existing persistent connection +(if one is available), and it will send the server a +.QW "\fBConnection: keep-alive\fR" +request header asking to keep the connection open for future requests. +.PP +The \fBhttp::config\fR options \fB-pipeline\fR, \fB-postfresh\fR, and +\fB-repost\fR relate to persistent connections. +.PP +Option \fB-pipeline\fR, if boolean \fBtrue\fR, will pipeline GET and HEAD requests +made +over a persistent connection. POST requests will not be pipelined - if the +POST is not the first transaction on the connection, its request will not +be sent until the previous response has finished. GET and HEAD requests +made after a POST will not be sent until the POST response has been +delivered, and will not be sent if the POST fails. +.PP +Option \fB-postfresh\fR, if boolean \fBtrue\fR, will override the \fBhttp::geturl\fR option +\fB-keepalive\fR, and always open a fresh connection for a POST request. +.PP +Option \fB-repost\fR, if \fBtrue\fR, permits automatic retry of a POST request +that fails because it uses a persistent connection that the server has +half-closed (an +.QW "asynchronous close event" ). +Subsequent GET and HEAD requests in a failed pipeline will also be retried. +\fIThe -repost option should be used only if the application understands +that the retry is appropriate\fR - specifically, the application must know +that if the failed POST successfully modified the state of the server, a repeat POST +would have no adverse effect. .SH EXAMPLE .PP This example creates a procedure to copy a URL to a file while printing a diff --git a/library/http/http.tcl b/library/http/http.tcl index 06f452d..f4f83c6 100644 --- a/library/http/http.tcl +++ b/library/http/http.tcl @@ -20,9 +20,12 @@ namespace eval http { if {![info exists http]} { array set http { -accept */* + -pipeline 1 + -postfresh 0 -proxyhost {} -proxyport {} -proxyfilter http::ProxyRequired + -repost 0 -urlencoding utf-8 -zip 1 } @@ -220,7 +223,7 @@ proc http::config {args} { # Arguments: # token Connection token. # errormsg (optional) If set, forces status to error. -# skipCB (optional) If set, don't call the -command callback. This +# skipCB (optional) If set, don't call the -command callback. This # is useful when geturl wants to throw an exception instead # of calling the callback. That way, the same error isn't # reported to two places. @@ -240,6 +243,7 @@ proc http::Finish {token {errormsg ""} {skipCB 0}} { variable $token upvar 0 $token state global errorInfo errorCode + set closeQueue 0 if {$errormsg ne ""} { set state(error) [list $errormsg $errorInfo $errorCode] set state(status) "error" @@ -251,6 +255,12 @@ proc http::Finish {token {errormsg ""} {skipCB 0}} { || ([info exists state(connection)] && ($state(connection) eq "close")) } { CloseSocket $state(sock) $token + set closeQueue 1 + } elseif { + ([info exists state(-keepalive)] && $state(-keepalive)) + && ([info exists state(connection)] && ($state(connection) ne "close")) + } { + KeepSocket $token } if {[info exists state(after)]} { after cancel $state(after) @@ -263,6 +273,233 @@ proc http::Finish {token {errormsg ""} {skipCB 0}} { set state(status) error } } + + if { $closeQueue + && [info exists state(socketinfo)] + && [info exists socketMapping($state(socketinfo))] + && ($socketMapping($state(socketinfo)) eq $state(sock)) + } { + http::CloseQueuedQueries $state(socketinfo) $token + } + + return +} + +# http::KeepSocket - +# +# Keep a socket in the persistent sockets table and connect it to its next +# queued task if possible. Otherwise leave it idle and ready for its next +# use. +# +# Arguments: +# token Connection token. + +proc http::KeepSocket {token} { + variable http + variable socketMapping + variable socketRdState + variable socketWrState + variable socketRdQueue + variable socketWrQueue + variable socketClosing + variable socketPlayCmd + + variable $token + upvar 0 $token state + set tk [namespace tail $token] + + # Keep this socket open for another request ("Keep-Alive"). + # React if the server half-closes the socket. + # Discussion is in http::geturl. + catch {fileevent $state(sock) readable [list http::CheckEof $state(sock)]} + + # The line below should not be changed in production code. + # It is edited by the test suite. + set TEST_EOF 0 + if {$TEST_EOF} { + # ONLY for testing reaction to server eof. + # No server timeouts will be caught. + catch {fileevent $state(sock) readable {}} + } else { + # Normal operation. + # Test constraint normalEof. + } + + if { [info exists state(socketinfo)] + && [info exists socketMapping($state(socketinfo))] + } { + set connId $state(socketinfo) + # The value "Rready" is set only here. + set socketRdState($connId) Rready + + if { $state(-pipeline) + && [info exists socketRdQueue($connId)] + && [llength $socketRdQueue($connId)] + } { + # The usual case for pipelined responses - if another response is + # queued, arrange to read it. + set token3 [lindex $socketRdQueue($connId) 0] + set socketRdQueue($connId) [lrange $socketRdQueue($connId) 1 end] + variable $token3 + upvar 0 $token3 state3 + set tk2 [namespace tail $token3] + + #Log pipelined, GRANT read access to $token3 in KeepSocket + set socketRdState($connId) $token3 + lassign [fconfigure $state3(sock) -translation] trRead trWrite + fconfigure $state3(sock) -translation [list auto $trWrite] \ + -buffersize $state3(-blocksize) + Log ^D$tk2 begin receiving response - token $token3 + fileevent $state3(sock) readable \ + [list http::Event $state3(sock) $token3] + #Log ---- $state3(sock) >> conn to $token3 for HTTP response (a) + + # Other pipelined cases. + # - The test above ensures that, for the pipelined cases in the two + # tests below, the read queue is empty. + # - In those two tests, check whether the next write will be + # nonpipeline. + } elseif { + $state(-pipeline) + && [info exists socketWrState($connId)] + && ($socketWrState($connId) eq "peNding") + + && [info exists socketWrQueue($connId)] + && [llength $socketWrQueue($connId)] + && (![set token3 [lindex $socketWrQueue($connId) 0] + set ${token3}(-pipeline) + ] + ) + } { + # This case: + # - Now it the time to run the "pending" request. + # - The next token in the write queue is nonpipeline, and + # socketWrState has been marked "pending" (in + # http::NextPipelinedWrite or http::geturl) so a new pipelined + # request cannot jump the queue. + # + # Tests: + # - In this case the read queue (tested above) is empty and this + # "pending" write token is in front of the rest of the write + # queue. + # - The write state is not Wready and therefore appears to be busy, + # but because it is "pending" we know that it is reserved for the + # first item in the write queue, a non-pipelined request that is + # waiting for the read queue to empty. That has now happened: so + # give that request read and write access. + variable $token3 + set conn [set ${token3}(tmpConnArgs)] + #Log nonpipeline, GRANT r/w access to $token3 in KeepSocket + set socketRdState($connId) $token3 + set socketWrState($connId) $token3 + set socketWrQueue($connId) [lrange $socketWrQueue($connId) 1 end] + # Connect does its own fconfigure. + fileevent $state(sock) writable [list http::Connect $token3 {*}$conn] + #Log ---- $state(sock) << conn to $token3 for HTTP request (c) + + } elseif { + $state(-pipeline) + && [info exists socketWrState($connId)] + && ($socketWrState($connId) eq "peNding") + + } { + # Should not come here. The second block in the previous "elseif" + # test should be tautologous (but was needed in an earlier + # implementation) and will be removed after testing. + # If we get here, the value "pending" was assigned in error. + # This error would block the queue for ever. + Log ^X$tk <<<<< Error in queueing of requests >>>>> - token $token + + } elseif { + $state(-pipeline) + && [info exists socketWrState($connId)] + && ($socketWrState($connId) eq "Wready") + + && [info exists socketWrQueue($connId)] + && [llength $socketWrQueue($connId)] + && (![set token3 [lindex $socketWrQueue($connId) 0] + set ${token3}(-pipeline) + ] + ) + } { + # This case: + # - The next token in the write queue is nonpipeline, and + # socketWrState is Wready. Get the next event from socketWrQueue. + # Tests: + # - In this case the read state (tested above) is Rready and the + # write state (tested here) is Wready - there is no "pending" + # request. + # Code: + # - The code is the same as the code below for the nonpipelined + # case with a queued request. + variable $token3 + set conn [set ${token3}(tmpConnArgs)] + #Log nonpipeline, GRANT r/w access to $token3 in KeepSocket + set socketRdState($connId) $token3 + set socketWrState($connId) $token3 + set socketWrQueue($connId) [lrange $socketWrQueue($connId) 1 end] + # Connect does its own fconfigure. + fileevent $state(sock) writable [list http::Connect $token3 {*}$conn] + #Log ---- $state(sock) << conn to $token3 for HTTP request (c) + + } elseif { + (!$state(-pipeline)) + && [info exists socketWrQueue($connId)] + && [llength $socketWrQueue($connId)] + && ($state(connection) ne "close") + } { + # If not pipelined, (socketRdState eq Rready) tells us that we are + # ready for the next write - there is no need to check + # socketWrState. Write the next request, if one is waiting. + # If the next request is pipelined, it receives premature read + # access to the socket. This is not a problem. + set token3 [lindex $socketWrQueue($connId) 0] + variable $token3 + set conn [set ${token3}(tmpConnArgs)] + #Log nonpipeline, GRANT r/w access to $token3 in KeepSocket + set socketRdState($connId) $token3 + set socketWrState($connId) $token3 + set socketWrQueue($connId) [lrange $socketWrQueue($connId) 1 end] + # Connect does its own fconfigure. + fileevent $state(sock) writable [list http::Connect $token3 {*}$conn] + #Log ---- $state(sock) << conn to $token3 for HTTP request (d) + + } elseif {(!$state(-pipeline))} { + set socketWrState($connId) Wready + # Rready and Wready and idle: nothing to do. + } else { + # Rready and idle: nothing to do. + } + + } else { + CloseSocket $state(sock) $token + } + return +} + +# http::CheckEof - +# +# Read from a socket and close it if eof. +# The command is bound to "fileevent readable" on an idle socket, and +# "eof" is the only event that should trigger the binding, occurring when +# the server times out and half-closes the socket. +# +# A read is necessary so that [eof] gives a meaningful result. +# Any bytes sent are junk (or a bug). + +proc http::CheckEof {sock} { + set junk [read $sock] + set n [string length $junk] + if {$n} { + Log "WARNING: $n bytes received but no HTTP request sent" + } + + if {[catch {eof $sock} res] || $res} { + # The server has half-closed the socket. + # If a new write has started, its transaction will fail and + # will then be error-handled. + CloseSocket $sock + } return } @@ -302,23 +539,85 @@ proc http::CloseSocket {s {token {}}} { } else { } } - if {$connId eq {} || ![info exists socketMapping($connId)]} { + if { ($connId ne {}) + && [info exists socketMapping($connId)] + && ($socketMapping($connId) eq $s) + } { + Log "Closing connection $connId (sock $socketMapping($connId))" + if {[catch {close $socketMapping($connId)} err]} { + Log "Error closing connection: $err" + } else { + } + if {$token eq {}} { + # Cases with a non-empty token are handled by Finish, so the tokens + # are finished in connection order. + http::CloseQueuedQueries $connId $token + } else { + } + } else { Log "Closing socket $s (no connection info)" if {[catch {close $s} err]} { Log "Error closing socket: $err" } else { } + } + return +} + +# http::CloseQueuedQueries +# +# connId - identifier "domain:port" for the connection +# token - (optional) used only for logging +# +# Called from http::CloseSocket and http::Finish, after a connection is closed, +# to clear the read and write queues if this has not already been done. + +proc http::CloseQueuedQueries {connId {token {}}} { + variable socketMapping + variable socketRdState + variable socketWrState + variable socketRdQueue + variable socketWrQueue + variable socketClosing + variable socketPlayCmd + + if {![info exists socketMapping($connId)]} { + # Command has already been called. + # Don't come here again - especially recursively. + return + } + + # Used only for logging. + if {$token eq {}} { + set tk {} } else { - if {[info exists socketMapping($connId)]} { - Log "Closing connection $connId (sock $socketMapping($connId))" - if {[catch {close $socketMapping($connId)} err]} { - Log "Error closing connection: $err" - } else { - } - unset socketMapping($connId) - } else { - Log "Cannot close connection $connId - no socket in socket map" - } + set tk [namespace tail $token] + } + + if { [info exists socketPlayCmd($connId)] + && ($socketPlayCmd($connId) ne {ReplayIfClose Wready {} {}}) + } { + set unfinished $socketPlayCmd($connId) + } else { + set unfinished {} + } + + # The trace on "unset socketRdState(*)" cancels any pipelined + # responses. + # The trace on "unset socketWrState(*)" cancels any pipelined + # requests. + unset socketMapping($connId) + unset socketRdState($connId) + unset socketWrState($connId) + unset -nocomplain socketRdQueue($connId) + unset -nocomplain socketWrQueue($connId) + unset -nocomplain socketClosing($connId) + unset -nocomplain socketPlayCmd($connId) + + if {$unfinished ne {}} { + Log ^R$tk Any unfinished transactions (excluding $token) failed \ + - token $token + {*}$unfinished } return } @@ -332,7 +631,7 @@ proc http::CloseSocket {s {token {}}} { # why Status info. # # Side Effects: -# See Finish +# See Finish proc http::reset {token {why reset}} { variable $token @@ -354,8 +653,8 @@ proc http::reset {token {why reset}} { # Establishes a connection to a remote url via http. # # Arguments: -# url The http URL to goget. -# args Option value pairs. Valid options include: +# url The http URL to goget. +# args Option value pairs. Valid options include: # -blocksize, -validate, -headers, -timeout # Results: # Returns a token for this connection. This token is the name of an @@ -375,10 +674,12 @@ proc http::geturl {url args} { set http(uid) 0 } set token [namespace current]::[incr http(uid)] + ##Log Starting http::geturl - token $token variable $token upvar 0 $token state set tk [namespace tail $token] reset $token + Log ^A$tk URL $url - token $token # Process command options. @@ -393,8 +694,9 @@ proc http::geturl {url args} { -queryprogress {} -protocol 1.1 binary 0 - state connecting + state created meta {} + method {} coding {} currentsize 0 totalsize 0 @@ -611,14 +913,7 @@ proc http::geturl {url args} { # Don't append the fragment! set state(url) $url - # If a timeout is specified we set up the after event and arrange for an - # asynchronous socket connection. - set sockopts [list -async] - if {$state(-timeout) > 0} { - set state(after) [after $state(-timeout) \ - [list http::reset $token timeout]] - } # If we are using the proxy, we must pass in the full URL that includes # the server name. @@ -636,7 +931,36 @@ proc http::geturl {url args} { # c11a51c482] set state(accept-types) $http(-accept) + if {$isQuery || $isQueryChannel} { + # It's a POST. + # A client wishing to send a non-idempotent request SHOULD wait to send + # that request until it has received the response status for the + # previous request. + if {$http(-postfresh)} { + # Override -keepalive for a POST. Use a new connection, and thus + # avoid the small risk of a race against server timeout. + set state(-keepalive) 0 + } else { + # Allow -keepalive but do not -pipeline - wait for the previous + # transaction to finish. + # There is a small risk of a race against server timeout. + set state(-pipeline) 0 + } + } else { + # It's a GET or HEAD. + set state(-pipeline) $http(-pipeline) + } + # See if we are supposed to use a previously opened channel. + # - In principle, ANY call to http::geturl could use a previously opened + # channel if it is available - the "Connection: keep-alive" header is a + # request to leave the channel open AFTER completion of this call. + # - In fact, we try to use an existing channel only if -keepalive 1 -- this + # means that at most one channel is left open for each value of + # $state(socketinfo). This property simplifies the mapping of open + # channels. + set reusing 0 + set alreadyQueued 0 if {$state(-keepalive)} { variable socketMapping variable socketRdState @@ -647,20 +971,97 @@ proc http::geturl {url args} { variable socketPlayCmd if {[info exists socketMapping($state(socketinfo))]} { + # - If the connection is idle, it has a "fileevent readable" binding + # to http::CheckEof, in case the server times out and half-closes + # the socket (http::CheckEof closes the other half). + # - We leave this binding in place until just before the last + # puts+flush in http::Connected (GET/HEAD) or http::Write (POST), + # after which the HTTP response might be generated. + # - Therefore we must be prepared for full closure of the socket, + # and catch errors on any socket operation. + if {[catch {fconfigure $socketMapping($state(socketinfo))}]} { Log "WARNING: socket for $state(socketinfo) was closed\ - - token $token" + - token $token" + + # The trace on "unset socketRdState(*)" cancels any pipelined + # responses. + # The trace on "`(*)" cancels any pipelined + # requests. unset socketMapping($state(socketinfo)) + unset socketRdState($state(socketinfo)) + unset socketWrState($state(socketinfo)) + unset -nocomplain socketRdQueue($state(socketinfo)) + unset -nocomplain socketWrQueue($state(socketinfo)) + unset -nocomplain socketClosing($state(socketinfo)) + unset -nocomplain socketPlayCmd($state(socketinfo)) + + # Do not automatically close the eventual connection socket. + set state(connection) {} + } elseif { [info exists socketClosing($state(socketinfo))] + && $socketClosing($state(socketinfo)) + } { + # The server has sent a "Connection: close" header. + # Do not use the persistent socket again. + # Since we have only one persistent socket per server, and the + # old socket is not yet dead, add the request to the write queue + # of the dying socket, which will be replayed by ReplayIfClose. + set reusing 1 + set sock $socketMapping($state(socketinfo)) + Log "reusing socket $sock for $state(socketinfo) - token $token" + + # Do not automatically close this connection socket. + set state(connection) {} + set alreadyQueued 1 + lassign $socketPlayCmd($state(socketinfo)) com0 com1 com2 com3 + lappend com3 $token + set socketPlayCmd($state(socketinfo)) [list $com0 $com1 $com2 $com3] } else { + # Use the persistent socket. + # The socket may not be ready to write: an earlier request might + # still be still writing (in the pipelined case) or + # writing/reading (in the nonpipeline case). This possibility + # is handled by socketWrQueue later in this command. + set reusing 1 set sock $socketMapping($state(socketinfo)) Log "reusing socket $sock for $state(socketinfo) - token $token" - catch {fileevent $sock writable {}} - catch {fileevent $sock readable {}} + + # Do not automatically close this connection socket. + set state(connection) {} } } - # Do not automatically close this connection socket. - set state(connection) {} } + + if {$reusing} { + # Define state(tmpState) and state(tmpOpenCmd) for use + # by http::ReplayIfDead if the persistent connection has died. + set state(tmpState) [array get state] + + # Pass -myaddr directly to the socket command + if {[info exists state(-myaddr)]} { + lappend sockopts -myaddr $state(-myaddr) + } + + set state(tmpOpenCmd) [list {*}$defcmd {*}$sockopts {*}$targetAddr] + } + + set state(reusing) $reusing + # Excluding ReplayIfDead and the decision whether to call it, there are four + # places outside http::geturl where state(reusing) is used: + # - Connected - if reusing and not pipelined, start the state(-timeout) + # timeout (when writing). + # - DoneRequest - if reusing and pipelined, send the next pipelined write + # - Event - if reusing and pipelined, start the state(-timeout) + # timeout (when reading). + # - Event - if not reusing and pipelined, send the next pipelined + # write + + # See comments above re the start of this timeout in other cases. + if {(!$state(reusing)) && ($state(-timeout) > 0)} { + set state(after) [after $state(-timeout) \ + [list http::reset $token timeout]] + } + if {![info exists sock]} { # Pass -myaddr directly to the socket command if {[info exists state(-myaddr)]} { @@ -686,14 +1087,126 @@ proc http::geturl {url args} { set state(sock) $sock Log "Using $sock for $state(socketinfo) - token $token" \ [expr {$state(-keepalive)?"keepalive":""}] - if {$state(-keepalive)} { + + if { $state(-keepalive) + && (![info exists socketMapping($state(socketinfo))]) + } { + # Freshly-opened socket that we would like to become persistent. set socketMapping($state(socketinfo)) $sock + if {$state(-pipeline)} { + #Log new, init for pipelined, GRANT write access to $token in geturl + # Also grant premature read access to the socket. This is OK. + set socketRdState($state(socketinfo)) $token + set socketWrState($state(socketinfo)) $token + } else { + # socketWrState is not used by this non-pipelined transaction. + # We cannot leave it as "Wready" because the next call to + # http::geturl with a pipelined transaction would conclude that the + # socket is available for writing. + #Log new, init for nonpipeline, GRANT r/w access to $token in geturl + set socketRdState($state(socketinfo)) $token + set socketWrState($state(socketinfo)) $token + } + + if {![info exists socketRdQueue($state(socketinfo))]} { + set socketRdQueue($state(socketinfo)) {} + set varName ::http::socketRdState($state(socketinfo)) + trace add variable $varName unset ::http::CancelReadPipeline + } + if {![info exists socketWrQueue($state(socketinfo))]} { + set socketWrQueue($state(socketinfo)) {} + set varName ::http::socketWrState($state(socketinfo)) + trace add variable $varName unset ::http::CancelWritePipeline + } } if {![info exists phost]} { set phost "" } - fileevent $sock writable [list http::Connect $token $proto $phost $srvurl] + if {$reusing} { + # For use by http::ReplayIfDead if the persistent connection has died. + # Also used by NextPipelinedWrite. + set state(tmpConnArgs) [list $proto $phost $srvurl] + } + + # The element socketWrState($connId) has a value which is either the name of + # the token that is permitted to write to the socket, or "Wready" if no + # token is permitted to write. + # + # The code that sets the value to Wready immediately calls + # http::NextPipelinedWrite, which examines socketWrQueue($connId) and + # processes the next request in the queue, if there is one. The value + # Wready is not found when the interpreter is in the event loop unless the + # socket is idle. + # + # The element socketRdState($connId) has a value which is either the name of + # the token that is permitted to read from the socket, or "Rready" if no + # token is permitted to read. + # + # The code that sets the value to Rready then examines + # socketRdQueue($connId) and processes the next request in the queue, if + # there is one. The value Rready is not found when the interpreter is in + # the event loop unless the socket is idle. + + if {$alreadyQueued} { + # A write may or may not be in progress. There is no need to set + # socketWrState to prevent another call stealing write access - all + # subsequent calls on this socket will come here because the socket + # will close after the current read, and its + # socketClosing($connId) is 1. + ##Log "HTTP request for token $token is queued" + + } elseif { $reusing + && $state(-pipeline) + && ($socketWrState($state(socketinfo)) ne "Wready") + } { + ##Log "HTTP request for token $token is queued for pipelined use" + lappend socketWrQueue($state(socketinfo)) $token + + } elseif { $reusing + && (!$state(-pipeline)) + && ($socketWrState($state(socketinfo)) ne "Wready") + } { + # A write is queued or in progress. Lappend to the write queue. + ##Log "HTTP request for token $token is queued for nonpipeline use" + lappend socketWrQueue($state(socketinfo)) $token + + } elseif { $reusing + && (!$state(-pipeline)) + && ($socketWrState($state(socketinfo)) eq "Wready") + && ($socketRdState($state(socketinfo)) ne "Rready") + } { + # A read is queued or in progress, but not a write. Cannot start the + # nonpipeline transaction, but must set socketWrState to prevent a + # pipelined request jumping the queue. + ##Log "HTTP request for token $token is queued for nonpipeline use" + #Log re-use nonpipeline, GRANT delayed write access to $token in geturl + + set socketWrState($state(socketinfo)) peNding + lappend socketWrQueue($state(socketinfo)) $token + + } else { + if {$reusing && $state(-pipeline)} { + #Log re-use pipelined, GRANT write access to $token in geturl + set socketWrState($state(socketinfo)) $token + + } elseif {$reusing} { + # Cf tests above - both are ready. + #Log re-use nonpipeline, GRANT r/w access to $token in geturl + set socketRdState($state(socketinfo)) $token + set socketWrState($state(socketinfo)) $token + + } else { + # (!$reusing) + } + + # All (!$reusing) cases come here, and also some $reusing cases if the + # connection is ready. + #Log ---- $state(socketinfo) << conn to $token for HTTP request (a) + # Connect does its own fconfigure. + fileevent $sock writable \ + [list http::Connect $token $proto $phost $srvurl] + } # Wait for the connection to complete. if {![info exists state(-command)]} { @@ -716,7 +1229,7 @@ proc http::geturl {url args} { return -code error $err } } - + ##Log Leaving http::geturl - token $token return $token } @@ -726,8 +1239,8 @@ proc http::geturl {url args} { # established. # # Arguments: -# token State token. -# proto What protocol (http, https, etc.) was used to connect. +# token State token. +# proto What protocol (http, https, etc.) was used to connect. # phost Are we using keep-alive? Non-empty if yes. # srvurl Service-local URL that we're requesting # Results: @@ -748,6 +1261,11 @@ proc http::Connected {token proto phost srvurl} { upvar 0 $token state set tk [namespace tail $token] + if {$state(reusing) && (!$state(-pipeline)) && ($state(-timeout) > 0)} { + set state(after) [after $state(-timeout) \ + [list http::reset $token timeout]] + } + # Set back the variables needed here. set sock $state(sock) set isQueryChannel [info exists state(-querychannel)] @@ -759,7 +1277,7 @@ proc http::Connected {token proto phost srvurl} { set defport [lindex $urlTypes($lower) 0] # Send data in cr-lf format, but accept any line terminators. - # Initialisation to {auto *} now done in geturl. + # Initialisation to {auto *} now done in geturl, KeepSocket and DoneRequest. # We are concerned here with the request (write) not the response (read). lassign [fconfigure $sock -translation] trRead trWrite fconfigure $sock -translation [list $trRead crlf] \ @@ -800,7 +1318,11 @@ proc http::Connected {token proto phost srvurl} { set state(-protocol) 1.0 } set accept_types_seen 0 + + Log ^B$tk begin sending request - token $token + if {[catch { + set state(method) $how puts $sock "$how $srvurl HTTP/$state(-protocol)" if {[dict exists $state(-headers) Host]} { # Allow Host spoofing. [Bug 928154] @@ -889,6 +1411,7 @@ proc http::Connected {token proto phost srvurl} { # response. if {$isQuery || $isQueryChannel} { + # POST method. if {!$content_type_seen} { puts $sock "Content-Type: $state(-type)" } @@ -899,25 +1422,624 @@ proc http::Connected {token proto phost srvurl} { lassign [fconfigure $sock -translation] trRead trWrite fconfigure $sock -translation [list $trRead binary] fileevent $sock writable [list http::Write $token] + # The http::Write command decides when to make the socket readable, + # using the same test as the GET/HEAD case below. } else { + # GET or HEAD method. + if { (![catch {fileevent $sock readable} binding]) + && ($binding eq [list http::CheckEof $sock]) + } { + # Remove the "fileevent readable" binding of an idle persistent + # socket to http::CheckEof. We can no longer treat bytes + # received as junk. The server might still time out and + # half-close the socket if it has not yet received the first + # "puts". + fileevent $sock readable {} + } puts $sock "" flush $sock - fileevent $sock readable [list http::Event $sock $token] + Log ^C$tk end sending request - token $token + # End of writing (GET/HEAD methods). The request has been sent. + + DoneRequest $token } } err]} { # The socket probably was never connected, or the connection dropped # later. + if {[info exists state(reusing)] && $state(reusing)} { + # The socket was closed at the server end, and closed at + # this end by http::CheckEof. + if {[TestForReplay $token write $err a]} { + return + } else { + Finish $token {failed to re-use socket} + } - # if state(status) is error, it means someone's already called - # Finish to do the above-described clean up. - if {$state(status) ne "error"} { + # else: + # This is NOT a persistent socket that has been closed since its + # last use. + # If any other requests are in flight or pipelined/queued, they will + # be discarded. + } elseif {$state(status) eq ""} { + Finish $token {failed to re-use socket} + } elseif {$state(status) ne "error"} { Finish $token $err + } else { + # if state(status) is error, it means someone's already called + # Finish to do the above-described clean up. } } return } +# http::DoneRequest -- +# +# Command called when a request has been sent. It will arrange the +# next request and/or response as appropriate. + +proc http::DoneRequest {token} { + variable http + variable socketMapping + variable socketRdState + variable socketWrState + variable socketRdQueue + variable socketWrQueue + variable socketClosing + variable socketPlayCmd + + variable $token + upvar 0 $token state + set tk [namespace tail $token] + set sock $state(sock) + + # If pipelined, connect the next HTTP request to the socket. + if {$state(reusing) && $state(-pipeline)} { + # Enable next token (if any) to write. + # The value "Wready" is set only here, and + # in http::Event after reading the response-headers of a + # non-reusing transaction. + # Previous value is $token. It cannot be pending. + set socketWrState($state(socketinfo)) Wready + + # Now ready to write the next pipelined request (if any). + http::NextPipelinedWrite $token + } else { + # If pipelined, this is the first transaction on this socket. We wait + # for the response headers to discover whether the connection is + # persistent. (If this is not done and the connection is not + # persistent, we SHOULD retry and then MUST NOT pipeline before knowing + # that we have a persistent connection + # (rfc2616 8.1.2.2)). + } + + # Connect to receive the response, unless the socket is pipelined + # and another response is being sent. + # This code block is separate from the code below because there are + # cases where socketRdState already has the value $token. + if { $state(-keepalive) + && $state(-pipeline) + && [info exists socketRdState($state(socketinfo))] + && ($socketRdState($state(socketinfo)) eq "Rready") + } { + #Log pipelined, GRANT read access to $token in Connected + set socketRdState($state(socketinfo)) $token + } + + if { $state(-keepalive) + && $state(-pipeline) + && [info exists socketRdState($state(socketinfo))] + && ($socketRdState($state(socketinfo)) ne $token) + } { + # Do not read from the socket until it is ready. + ##Log "HTTP response for token $token is queued for pipelined use" + lappend socketRdQueue($state(socketinfo)) $token + } else { + # In the pipelined case, connection for reading depends on the + # value of socketRdState. + # In the nonpipeline case, connection for reading always occurs. + #Log ---- $state(socketinfo) >> conn to $token for HTTP response (b) + lassign [fconfigure $sock -translation] trRead trWrite + fconfigure $sock -translation [list auto $trWrite] \ + -buffersize $state(-blocksize) + Log ^D$tk begin receiving response - token $token + fileevent $sock readable [list http::Event $sock $token] + } + return +} + +# http::NextPipelinedWrite +# +# - Connecting a socket to a token for writing is done by this command and by +# command KeepSocket. +# - If another request has a pipelined write scheduled for $token's socket, +# and if the socket is ready to accept it, connect the write and update +# the queue accordingly. +# - This command is called from http::DoneRequest and http::Event, +# IF $state(-pipeline) AND (the current transfer has reached the point at +# which the socket is ready for the next request to be written). +# - This command is called when a token has write access and is pipelined and +# keep-alive, and sets socketWrState to Wready. +# - The command need not consider the case where socketWrState is set to a token +# that does not yet have write access. Such a token is waiting for Rready, +# and the assignment of the connection to the token will be done elsewhere (in +# http::KeepSocket). +# - This command cannot be called after socketWrState has been set to a +# "pending" token value (that is then overwritten by the caller), because that +# value is set by this command when it is called by an earlier token when it +# relinquishes its write access, and the pending token is always the next in +# line to write. + +proc http::NextPipelinedWrite {token} { + variable http + variable socketRdState + variable socketWrState + variable socketWrQueue + + variable $token + upvar 0 $token state + set connId $state(socketinfo) + + if { $state(-pipeline) + && [info exists socketWrState($connId)] + && ($socketWrState($connId) eq "Wready") + + && [info exists socketWrQueue($connId)] + && [llength $socketWrQueue($connId)] + && ([set token2 [lindex $socketWrQueue($connId) 0] + set ${token2}(-pipeline) + ] + ) + } { + # - The usual case for a pipelined connection, ready for a new request. + #Log pipelined, GRANT write access to $token2 in NextPipelinedWrite + set conn [set ${token2}(tmpConnArgs)] + set socketWrState($connId) $token2 + set socketWrQueue($connId) [lrange $socketWrQueue($connId) 1 end] + # Connect does its own fconfigure. + fileevent $state(sock) writable [list http::Connect $token2 {*}$conn] + #Log ---- $connId << conn to $token2 for HTTP request (b) + + # In the tests below, the next request will be nonpipeline. + } elseif { $state(-pipeline) + && [info exists socketWrState($connId)] + && ($socketWrState($connId) eq "Wready") + + && [info exists socketWrQueue($connId)] + && [llength $socketWrQueue($connId)] + && (![ set token3 [lindex $socketWrQueue($connId) 0] + set ${token3}(-pipeline) + ] + ) + + && [info exists socketRdState($connId)] + && ($socketRdState($connId) eq "Rready") + } { + # The case in which the next request will be non-pipelined, and the read + # and write queues is ready: which is the condition for a non-pipelined + # write. + variable $token3 + upvar 0 $token3 state3 + set conn [set ${token3}(tmpConnArgs)] + #Log nonpipeline, GRANT r/w access to $token3 in NextPipelinedWrite + set socketRdState($connId) $token3 + set socketWrState($connId) $token3 + set socketWrQueue($connId) [lrange $socketWrQueue($connId) 1 end] + # Connect does its own fconfigure. + fileevent $state(sock) writable [list http::Connect $token3 {*}$conn] + #Log ---- $state(sock) << conn to $token3 for HTTP request (c) + + } elseif { $state(-pipeline) + && [info exists socketWrState($connId)] + && ($socketWrState($connId) eq "Wready") + + && [info exists socketWrQueue($connId)] + && [llength $socketWrQueue($connId)] + && (![set token2 [lindex $socketWrQueue($connId) 0] + set ${token2}(-pipeline) + ] + ) + } { + # - The case in which the next request will be non-pipelined, but the + # read queue is NOT ready. + # - A read is queued or in progress, but not a write. Cannot start the + # nonpipeline transaction, but must set socketWrState to prevent a new + # pipelined request (in http::geturl) jumping the queue. + # - Because socketWrState($connId) is not set to Wready, the assignment + # of the connection to $token2 will be done elsewhere - by command + # http::KeepSocket when $socketRdState($connId) is set to "Rready". + + #Log re-use nonpipeline, GRANT delayed write access to $token in NextP.. + set socketWrState($connId) peNding + + } else { + # No requests in socketWrQueue. Nothing to do. + } + + return +} + +# http::CancelReadPipeline +# +# Cancel pipelined responses on a closing "Keep-Alive" socket. +# +# - Called by a trace when the variable ::http::socketRdState($connId) is +# unset (the trace itself is automatically removed). +# - The variable relates to a Keep-Alive socket, which has been closed. +# - Cancels all pipelined responses. The requests have been sent, +# the responses have not yet been received. +# - N.B. Always delete ::http::socketRdState($connId) before deleting +# ::http::socketRdQueue($connId), or this command will do nothing. +# +# Arguments +# As for a trace command on a variable. + +proc http::CancelReadPipeline {name1 connId op} { + variable socketRdQueue + + ##Log CancelReadPipeline $name1 $connId $op + if {[info exists socketRdQueue($connId)]} { + set msg {the connection was Closed} + foreach token $socketRdQueue($connId) { + set tk [namespace tail $token] + Log ^X$tk end of response "($msg)" - token $token + set ${token}(status) eof + Finish $token ;#$msg + } + set socketRdQueue($connId) {} + } + return +} + +# http::CancelWritePipeline +# +# Cancel queued events on a closing "Keep-Alive" socket. +# +# - Called by a trace when the variable ::http::socketWrState($connId) is +# unset (the trace itself is automatically removed). +# - The variable relates to a Keep-Alive socket, which has been closed. +# - In pipelined or nonpipeline case: cancels all queued requests. The +# requests have not yet been sent, the responses are not due and have +# no data to cancel. +# - N.B. Always delete ::http::socketWrState($connId) before deleting +# ::http::socketWrQueue($connId), or this command will do nothing. +# +# Arguments +# As for a trace command on a variable. + +proc http::CancelWritePipeline {name1 connId op} { + variable socketWrQueue + + ##Log CancelWritePipeline $name1 $connId $op + if {[info exists socketWrQueue($connId)]} { + set msg {the connection was Closed} + foreach token $socketWrQueue($connId) { + set tk [namespace tail $token] + Log ^X$tk end of response "($msg)" - token $token + set ${token}(status) eof + Finish $token ;#$msg + } + set socketWrQueue($connId) {} + } + return +} + +# http::ReplayIfDead -- +# +# - A query on a re-used persistent socket failed at the earliest opportunity, +# because the socket had been closed by the server. Keep the token, tidy up, +# and try to connect on a fresh socket. +# - The connection is monitored for eof by the command http::CheckEof. Thus +# http::ReplayIfDead is needed only when a server event (half-closing an +# apparently idle connection), and a client event (sending a request) occur at +# almost the same time, and neither client nor server detects the other's +# action before performing its own (an "asynchronous close event"). +# - To simplify testing of http::ReplayIfDead, set TEST_EOF 1 in +# http::KeepSocket, and then http::ReplayIfDead will be called if http::geturl +# is called at any time after the server timeout. +# +# Arguments: +# token Connection token. +# +# Side Effects: +# Use the same token, but try to open a new socket. + +proc http::ReplayIfDead {tokenArg doing} { + variable socketMapping + variable socketRdState + variable socketWrState + variable socketRdQueue + variable socketWrQueue + variable socketClosing + variable socketPlayCmd + + variable $tokenArg + upvar 0 $tokenArg stateArg + + Log running http::ReplayIfDead for $tokenArg $doing + + # 1. Merge the tokens for transactions in flight, the read (response) queue, + # and the write (request) queue. + + set InFlightR {} + set InFlightW {} + + # Obtain the tokens for transactions in flight. + if {$stateArg(-pipeline)} { + # Two transactions may be in flight. The "read" transaction was first. + # It is unlikely that the server would close the socket if a response + # was pending; however, an earlier request (as well as the present + # request) may have been sent and ignored if the socket was half-closed + # by the server. + + if { [info exists socketRdState($stateArg(socketinfo))] + && ($socketRdState($stateArg(socketinfo)) ne "Rready") + } { + lappend InFlightR $socketRdState($stateArg(socketinfo)) + } elseif {($doing eq "read")} { + lappend InFlightR $tokenArg + } else { + } + + if { [info exists socketWrState($stateArg(socketinfo))] + && $socketWrState($stateArg(socketinfo)) ni {Wready peNding} + } { + lappend InFlightW $socketWrState($stateArg(socketinfo)) + } elseif {($doing eq "write")} { + lappend InFlightW $tokenArg + } else { + } + + # Report any inconsistency of $tokenArg with socket*state. + if { ($doing eq "read") + && [info exists socketRdState($stateArg(socketinfo))] + && ($tokenArg ne $socketRdState($stateArg(socketinfo))) + } { + Log WARNING - ReplayIfDead pipelined tokenArg $tokenArg $doing \ + ne socketRdState($stateArg(socketinfo)) \ + $socketRdState($stateArg(socketinfo)) + + } elseif { + ($doing eq "write") + && [info exists socketWrState($stateArg(socketinfo))] + && ($tokenArg ne $socketWrState($stateArg(socketinfo))) + } { + Log WARNING - ReplayIfDead pipelined tokenArg $tokenArg $doing \ + ne socketWrState($stateArg(socketinfo)) \ + $socketWrState($stateArg(socketinfo)) + } else { + } + } else { + # One transaction should be in flight. + # socketRdState, socketWrQueue are used. + # socketRdQueue should be empty. + + # Report any inconsistency of $tokenArg with socket*state. + if {$tokenArg ne $socketRdState($stateArg(socketinfo))} { + Log WARNING - ReplayIfDead nonpipeline tokenArg $tokenArg $doing \ + ne socketRdState($stateArg(socketinfo)) \ + $socketRdState($stateArg(socketinfo)) + } else { + } + + # Report the inconsistency that socketRdQueue is non-empty. + if { [info exists socketRdQueue($stateArg(socketinfo))] + && ($socketRdQueue($stateArg(socketinfo)) ne {}) + } { + Log WARNING - ReplayIfDead nonpipeline tokenArg $tokenArg $doing \ + has read queue socketRdQueue($stateArg(socketinfo)) \ + $socketRdQueue($stateArg(socketinfo)) ne {} + } else { + } + + lappend InFlightW $socketRdState($stateArg(socketinfo)) + set socketRdQueue($stateArg(socketinfo)) {} + } + + set newQueue {} + lappend newQueue {*}$InFlightR + lappend newQueue {*}$socketRdQueue($stateArg(socketinfo)) + lappend newQueue {*}$InFlightW + lappend newQueue {*}$socketWrQueue($stateArg(socketinfo)) + + + # 2. Tidy up tokenArg. This is a cut-down form of Finish/CloseSocket. + # CloseSocket cancels file events, closes the socket, and unsets the + # socketMapping. + # Finish calls CloseSocket, if called as below. + # Don't want Eot. + # Do not change state(status). + # Want to not unset socketWrState(*). + + if {[info exists stateArg(after)]} { + after cancel $stateArg(after) + } + catch {close $stateArg(sock)} + + # The relevant element of socketMapping, socketRdState, socketWrState, + # socketRdQueue, socketWrQueue, socketClosing, socketPlayCmd will be set to + # new values in ReplayCore. + # The trace on "unset socketRdState(*)" cancels any pipelined responses. + # It also clears socketRdQueue(*). + # Transactions, if any, that are awaiting responses cannot be completed. + # They are listed for re-sending in newQueue. + # There is no need to unset socketWrState - the write queue transactions + # have not yet been sent, nor the state(-timeout) events. + # All tokens are preserved for re-use by ReplayCore. + + unset socketRdState($stateArg(socketinfo)) + + ReplayCore $newQueue + return +} + +# http::ReplayIfClose -- +# +# A request on a socket that was previously "Connection: keep-alive" has +# received a "Connection: close" response header. The server supplies +# that response correctly, but any later requests already queued on this +# connection will be lost when the socket closes. +# +# This command takes arguments that represent the socketWrState, +# socketRdQueue and socketWrQueue for this connection. The socketRdState +# is not needed because the server responds in full to the request that +# received the "Connection: close" response header. +# +# Existing request tokens $token (::http::$n) are preserved. The caller +# will be unaware that the request was processed this way. + +proc http::ReplayIfClose {Wstate Rqueue Wqueue} { + Log running http::ReplayIfClose for $Wstate $Rqueue $Wqueue + + if {$Wstate in $Rqueue || $Wstate in $Wqueue} { + Log WARNING duplicate token in http::ReplayIfClose - token $Wstate + set Wstate Wready + } + + # 1. Create newQueue + set InFlightW {} + if {$Wstate ni {Wready peNding}} { + lappend InFlightW $Wstate + } + + set newQueue {} + lappend newQueue {*}$Rqueue + lappend newQueue {*}$InFlightW + lappend newQueue {*}$Wqueue + + # 2. Cleanup - none needed, done by the caller. + + ReplayCore $newQueue + return +} + +# http::ReplayCore -- +# +# Command to replay a list of requests, using existing connection tokens. +# +# Abstracted from http::geturl which stores extra state in state(tmp*) so +# we don't need to do the argument processing again. +# +# Arguments: +# newQueue List of connection tokens. +# +# Side Effects: +# Use existing tokens, but try to open a new socket. + +proc http::ReplayCore {newQueue} { + variable socketMapping + variable socketRdState + variable socketWrState + variable socketRdQueue + variable socketWrQueue + variable socketClosing + variable socketPlayCmd + + if {[llength $newQueue] == 0} { + # Nothing to do. + return + } + + ##Log running ReplayCore for {*}$newQueue + set newToken [lindex $newQueue 0] + set newQueue [lrange $newQueue 1 end] + + # 3. Use newToken, and restore its values of state(*). Do not restore + # elements tmp* - we try again only once. + + set token $newToken + variable $token + upvar 0 $token state + + if {!( + [info exists state(tmpState)] + && [info exists state(tmpOpenCmd)] + && [info exists state(tmpConnArgs)] + ) + } { + Log FAILED in http::ReplayCore - NO tmp vars + Finish $token error 1 + return + } + + # Don't alter state(status) - this would trigger http::wait if it is in use. + set tmpState $state(tmpState) + set tmpOpenCmd $state(tmpOpenCmd) + set tmpConnArgs $state(tmpConnArgs) + foreach name [array names state] { + if {$name ne "status"} { + unset state($name) + } + } + + # Don't alter state(status). + dict unset tmpState status + array set state $tmpState + set state(reusing) 0 + + if {$state(-timeout) > 0} { + set resetCmd [list http::reset $token timeout] + set state(after) [after $state(-timeout) $resetCmd] + } + + # 4. Open a socket. + if {[catch {eval $tmpOpenCmd} sock]} { + # Something went wrong while trying to establish the connection. + Log FAILED - $tmpOpenCmd + set state(sock) $sock + Finish $token error 1 + return + } + + # 5. Configure the persistent socket data. + if {$state(-keepalive)} { + set socketMapping($state(socketinfo)) $sock + if {$state(-pipeline)} { + #Log new, init for pipelined, GRANT write acc to $token ReplayCore + set socketRdState($state(socketinfo)) $token + set socketWrState($state(socketinfo)) $token + } else { + #Log new, init for nonpipeline, GRANT r/w acc to $token ReplayCore + set socketRdState($state(socketinfo)) $token + set socketWrState($state(socketinfo)) $token + } + + if {![info exists socketRdQueue($state(socketinfo))]} { + set socketRdQueue($state(socketinfo)) {} + set varName ::http::socketRdState($state(socketinfo)) + trace add variable $varName unset ::http::CancelReadPipeline + } + set socketRdQueue($state(socketinfo)) {} + + if {![info exists socketWrQueue($state(socketinfo))]} { + set socketWrQueue($state(socketinfo)) {} + set varName ::http::socketWrState($state(socketinfo)) + trace add variable $varName unset ::http::CancelWritePipeline + } + set socketWrQueue($state(socketinfo)) $newQueue + set socketClosing($state(socketinfo)) 0 + set socketPlayCmd($state(socketinfo)) {} + } + + # 6. Configure sockets in the queue. + foreach tok $newQueue { + set ${tok}(sock) $sock + } + + # 7. Configure the socket for newToken to send a request. + set state(sock) $sock + Log "Using $sock for $state(socketinfo) - token $token" \ + [expr {$state(-keepalive)?"keepalive":""}] + + # Initialisation of a new socket. + fconfigure $sock -translation {auto crlf} -buffersize $state(-blocksize) + + # Connect does its own fconfigure. + fileevent $sock writable [list http::Connect $token {*}$tmpConnArgs] + #Log ---- $sock << conn to $token for HTTP request (e) + return +} + # Data access functions: # Data - the URL data # Status - the transaction status: ok, reset, eof, timeout, error @@ -1009,8 +2131,22 @@ proc http::Connect {token proto phost srvurl} { [eof $state(sock)] || [set err [fconfigure $state(sock) -error]] ne "" } { + if {[info exists state(reusing)] && $state(reusing)} { + # The socket was closed at the server end, and closed at + # this end by http::CheckEof. + if {[TestForReplay $token write $err b]} { + return + } + + # else: + # This is NOT a persistent socket that has been closed since its + # last use. + # If any other requests are in flight or pipelined/queued, they will + # be discarded. + } Finish $token "connect failed $err" } else { + set state(state) connecting fileevent $state(sock) writable {} ::http::Connected $token $proto $phost $srvurl } @@ -1050,7 +2186,21 @@ proc http::Write {token} { if {[info exists state(-query)]} { # Chop up large query strings so queryprogress callback can give # smooth feedback. - + if { $state(queryoffset) + $state(-queryblocksize) + >= $state(querylength) + } { + # This will be the last puts for the request-body. + if { (![catch {fileevent $sock readable} binding]) + && ($binding eq [list http::CheckEof $sock]) + } { + # Remove the "fileevent readable" binding of an idle + # persistent socket to http::CheckEof. We can no longer + # treat bytes received as junk. The server might still time + # out and half-close the socket if it has not yet received + # the first "puts". + fileevent $sock readable {} + } + } puts -nonewline $sock \ [string range $state(-query) $state(queryoffset) \ [expr {$state(queryoffset) + $state(-queryblocksize) - 1}]] @@ -1063,6 +2213,19 @@ proc http::Write {token} { # Copy blocks from the query channel set outStr [read $state(-querychannel) $state(-queryblocksize)] + if {[eof $state(-querychannel)]} { + # This will be the last puts for the request-body. + if { (![catch {fileevent $sock readable} binding]) + && ($binding eq [list http::CheckEof $sock]) + } { + # Remove the "fileevent readable" binding of an idle + # persistent socket to http::CheckEof. We can no longer + # treat bytes received as junk. The server might still time + # out and half-close the socket if it has not yet received + # the first "puts". + fileevent $sock readable {} + } + } puts -nonewline $sock $outStr incr state(queryoffset) [string length $outStr] if {[eof $state(-querychannel)]} { @@ -1076,10 +2239,14 @@ proc http::Write {token} { set state(posterror) $err set done 1 } + if {$done} { catch {flush $sock} fileevent $sock writable {} - fileevent $sock readable [list http::Event $sock $token] + Log ^C$tk end sending request - token $token + # End of writing (POST method). The request has been sent. + + DoneRequest $token } # Callback to the client after we've completely handled everything. @@ -1126,29 +2293,74 @@ proc http::Event {sock token} { - token $token" } } + Log ^X$tk end of response (token error) - token $token CloseSocket $sock return } if {$state(state) eq "connecting"} { ##Log - connecting - token $token + if { $state(reusing) + && $state(-pipeline) + && ($state(-timeout) > 0) + && (![info exists state(after)]) + } { + set state(after) [after $state(-timeout) \ + [list http::reset $token timeout]] + } + if {[catch {gets $sock state(http)} nsl]} { - Finish $token $nsl - return + if {[info exists state(reusing)] && $state(reusing)} { + # The socket was closed at the server end, and closed at + # this end by http::CheckEof. + + if {[TestForReplay $token read $nsl c]} { + return + } + + # else: + # This is NOT a persistent socket that has been closed since its + # last use. + # If any other requests are in flight or pipelined/queued, they + # will be discarded. + } else { + Log ^X$tk end of response (error) - token $token + Finish $token $nsl + return + } } elseif {$nsl >= 0} { ##Log - connecting 1 - token $token set state(state) "header" + } elseif { [eof $sock] + && [info exists state(reusing)] + && $state(reusing) + } { + # The socket was closed at the server end, and we didn't notice. + # This is the first read - where the closure is usually first + # detected. + + if {[TestForReplay $token read {} d]} { + return + } + + # else: + # This is NOT a persistent socket that has been closed since its + # last use. + # If any other requests are in flight or pipelined/queued, they will + # be discarded. } else { ##Log - connecting 2 - token $token - # nsl is -1 so either fblocked (OK) or eof. + # nsl is -1 so either fblocked (OK) or (eof and not reusing). # Continue. Any eof is processed at the end of this proc. } } elseif {$state(state) eq "header"} { if {[catch {gets $sock line} nhl]} { ##Log header failed - token $token + Log ^X$tk end of response (error) - token $token Finish $token $nhl return } elseif {$nhl == 0} { ##Log header done - token $token + Log ^E$tk end of response headers - token $token # We have now read all headers # We ignore HTTP/1.1 100 Continue returns. RFC2616 sec 8.2.3 if { ($state(http) == "") @@ -1158,10 +2370,89 @@ proc http::Event {sock token} { return } + if { ([info exists state(connection)]) + && ([info exists socketMapping($state(socketinfo))]) + && ($state(connection) eq "keep-alive") + && ($state(-keepalive)) + && (!$state(reusing)) + && ($state(-pipeline)) + } { + # Response headers received for first request on a persistent + # socket. Now ready for pipelined writes (if any). + # Previous value is $token. It cannot be pending. + set socketWrState($state(socketinfo)) Wready + http::NextPipelinedWrite $token + } + + # Once a "close" has been signaled, the client MUST NOT send any + # more requests on that connection. + # + # If either the client or the server sends the "close" token in the + # Connection header, that request becomes the last one for the + # connection. + + if { ([info exists state(connection)]) + && ([info exists socketMapping($state(socketinfo))]) + && ($state(connection) eq "close") + && ($state(-keepalive)) + } { + # The server warns that it will close the socket after this + # response. + ##Log WARNING - socket will close after response for $token + # Prepare data for a call to ReplayIfClose. + if { ($socketRdQueue($state(socketinfo)) ne {}) + || ($socketWrQueue($state(socketinfo)) ne {}) + || ($socketWrState($state(socketinfo)) ni + [list Wready peNding $token]) + } { + set InFlightW $socketWrState($state(socketinfo)) + if {$InFlightW in [list Wready peNding $token]} { + set InFlightW Wready + } else { + set msg "token ${InFlightW} is InFlightW" + ##Log $msg - token $token + } + + set socketPlayCmd($state(socketinfo)) \ + [list ReplayIfClose $InFlightW \ + $socketRdQueue($state(socketinfo)) \ + $socketWrQueue($state(socketinfo))] + + # See discussion below. + foreach tokenElement $socketRdQueue($state(socketinfo)) { + if {[info exists ${tokenElement}(after)]} { + after cancel [set ${tokenElement}(after)] + } + } + + # - Clear the queues. By doing this here, the code for + # connecting the next token to the socket needs no + # modification. + # - Do not unset socketRdState and socketWrState and trigger + # their traces, because this will close the socket, which + # is still needed for the current read. + # - The only other thing that the traces would have done is + # cancel the state(after) timeout events. This is now + # done above. + # - All tokens are preserved for re-use by ReplayCore. + + set socketRdQueue($state(socketinfo)) {} + set socketWrQueue($state(socketinfo)) {} + + } else { + set socketPlayCmd($state(socketinfo)) \ + {ReplayIfClose Wready {} {}} + } + + # Do not allow further connections on this socket. + set socketClosing($state(socketinfo)) 1 + } + set state(state) body # If doing a HEAD, then we won't get any body if {$state(-validate)} { + Log ^F$tk end of response for HEAD request - token $token set state(state) complete Eot $token return @@ -1190,6 +2481,8 @@ proc http::Event {sock token} { } { set msg {body size is 0 and no events likely - complete} Log "$msg - token $token" + set msg {(length unknown, set to 0)} + Log ^F$tk end of response body {*}$msg - token $token set state(state) complete Eot $token return @@ -1272,6 +2565,7 @@ proc http::Event {sock token} { # Do not tolerate bad -handler - fail with error status. set msg {the -handler command for http::geturl must\ return an integer (the number of bytes read)} + Log ^X$tk end of response (handler error) - token $token Eot $token $msg } else { # Tolerate the bad -handler, and continue. The penalty: @@ -1303,6 +2597,7 @@ proc http::Event {sock token} { append state(transfer_final) $line set n 0 } else { + Log ^F$tk end of response body (chunked) - token $token Log "final chunk part - token $token" Eot $token } @@ -1333,6 +2628,8 @@ proc http::Event {sock token} { token $token" set n 0 set state(connection) close + Log ^X$tk end of response (chunk error) \ + - token $token set msg {error in chunked encoding - fetch\ terminated} Eot $token $msg @@ -1348,6 +2645,7 @@ proc http::Event {sock token} { ##Log bad-chunk-measure - token $token set n 0 set state(connection) close + Log ^X$tk end of response (chunk error) - token $token Eot $token {error in chunked encoding - fetch terminated} } } else { @@ -1393,11 +2691,13 @@ proc http::Event {sock token} { ($state(totalsize) > 0) && ($state(currentsize) >= $state(totalsize)) } { + Log ^F$tk end of response body (unchunked) - token $token set state(state) complete Eot $token } } } err]} { + Log ^X$tk end of response (error ${err}) - token $token Finish $token $err return } else { @@ -1419,19 +2719,77 @@ proc http::Event {sock token} { # can be completed by eof. # The value "complete" is set only in http::Event, and it is # used only in the test above. + Log ^F$tk end of response body (unchunked, eof) - token $token Eot $token } else { # Premature eof. + Log ^X$tk end of response (unexpected eof) - token $token Eot $token eof } } else { # open connection closed on a token that has been cleaned up. + Log ^X$tk end of response (token error) - token $token CloseSocket $sock } } return } +# http::TestForReplay +# +# Command called if eof is discovered when a socket is first used for a +# new transaction. Typically this occurs if a persistent socket is used +# after a period of idleness and the server has half-closed the socket. +# +# token - the connection token returned by http::geturl +# doing - "read" or "write" +# err - error message, if any +# caller - code to identify the caller - used only in logging +# +# Return Value: boolean, true iff the command calls http::ReplayIfDead. + +proc http::TestForReplay {token doing err caller} { + variable http + variable $token + upvar 0 $token state + set tk [namespace tail $token] + if {$doing eq "read"} { + set code Q + set action response + set ing reading + } else { + set code P + set action request + set ing writing + } + + if {$err eq {}} { + set err "detect eof when $ing (server timed out?)" + } + + if {$state(method) eq "POST" && !$http(-repost)} { + # No Replay. + # The present transaction will end when Finish is called. + # That call to Finish will abort any other transactions + # currently in the write queue. + # For calls from http::Event this occurs when execution + # reaches the code block at the end of that proc. + set msg {no retry for POST with http::config -repost 0} + Log reusing socket failed "($caller)" - $msg - token $token + Log error - $err - token $token + Log ^X$tk end of $action (error) - token $token + return 0 + } else { + # Replay. + set msg {try a new socket} + Log reusing socket failed "($caller)" - $msg - token $token + Log error - $err - token $token + Log ^$code$tk Any unfinished (incl this one) failed - token $token + ReplayIfDead $token $doing + return 1 + } +} + # http::IsBinaryContentType -- # # Determine if the content-type means that we should definitely transfer @@ -1475,6 +2833,8 @@ proc http::IsBinaryContentType {type} { # Results: # The line of text, without trailing newline +# FIXME get rid of blocking + proc http::getTextLine {sock} { set tr [fconfigure $sock -translation] lassign $tr trRead trWrite @@ -1662,7 +3022,7 @@ proc http::Eot {token {reason {}}} { # token Connection token. # # Results: -# The status after the wait. +# The status after the wait. proc http::wait {token} { variable $token diff --git a/tests/httpPipeline.test b/tests/httpPipeline.test new file mode 100644 index 0000000..017661d --- /dev/null +++ b/tests/httpPipeline.test @@ -0,0 +1,859 @@ +# httpPipeline.test +# +# Test HTTP/1.1 concurrent requests including +# queueing, pipelining and retries. +# +# Copyright (C) 2018 Keith Nash +# +# See the file "license.terms" for information on usage and redistribution +# of this file, and for a DISCLAIMER OF ALL WARRANTIES. + +package require tcltest 2 +namespace import -force ::tcltest::* + +package require http 2.8 + +set sourcedir [file normalize [file dirname [info script]]] +source [file join $sourcedir httpTest.tcl] +source [file join $sourcedir httpTestScript.tcl] + +# ------------------------------------------------------------------------------ +# (1) Define the test scripts that will be used to generate logs for analysis - +# and also define the "correct" results. +# ------------------------------------------------------------------------------ + +proc ReturnTestScriptAndResult {ca cb delay te} { + + switch -- $ca { + 1 {set start { + START + KEEPALIVE 0 + PIPELINE 0 + }} + + 2 {set start { + START + KEEPALIVE 0 + PIPELINE 1 + }} + + 3 {set start { + START + KEEPALIVE 1 + PIPELINE 0 + }} + + 4 {set start { + START + KEEPALIVE 1 + PIPELINE 1 + }} + + default { + return -code error {no matching script} + } + } + + set middle " + [list DELAY $delay] + " + + switch -- $cb { + 1 {set end { + GET a + GET b + GET c + GET a + STOP + } + set resShort {1 ? ? ?} + set resLong {1 2 3 4} + } + + 2 {set end { + GET a + HEAD b + GET c + HEAD a + HEAD c + STOP + } + set resShort {1 ? ? ? ?} + set resLong {1 2 3 4 5} + } + + 3 {set end { + HEAD a + GET b + HEAD c + HEAD b + GET a + GET b + STOP + } + set resShort {1 ? ? ? ? ?} + set resLong {1 2 3 4 5 6} + } + + 4 {set end { + GET a + GET b + GET c + GET a + POST b address=home code=brief paid=yes + GET c + GET a + GET b + GET c + STOP + } + set resShort {1 ? ? ? 5 ? ? ? ?} + set resLong {1 2 3 4 5 6 7 8 9} + } + + 5 {set end { + POST a address=home code=brief paid=yes + POST b address=home code=brief paid=yes + POST c address=home code=brief paid=yes + POST a address=home code=brief paid=yes + POST b address=home code=brief paid=yes + POST c address=home code=brief paid=yes + POST a address=home code=brief paid=yes + POST b address=home code=brief paid=yes + POST c address=home code=brief paid=yes + STOP + } + set resShort {1 2 3 4 5 6 7 8 9} + set resLong {1 2 3 4 5 6 7 8 9} + } + + 6 {set end { + POST a address=home code=brief paid=yes + GET b address=home code=brief paid=yes + POST c address=home code=brief paid=yes + GET a address=home code=brief paid=yes + GET b address=home code=brief paid=yes + POST c address=home code=brief paid=yes + POST a address=home code=brief paid=yes + HEAD b address=home code=brief paid=yes + GET c address=home code=brief paid=yes + STOP + } + set resShort {1 ? 3 ? ? 6 7 ? ?} + set resLong {1 2 3 4 5 6 7 8 9} + } + + 7 {set end { + GET b address=home code=brief paid=yes + POST a address=home code=brief paid=yes + GET a address=home code=brief paid=yes + POST c address=home code=brief paid=yes + GET b address=home code=brief paid=yes + HEAD b address=home code=brief paid=yes + POST c address=home code=brief paid=yes + POST a address=home code=brief paid=yes + GET c address=home code=brief paid=yes + STOP + } + set resShort {1 2 ? 4 ? ? 7 8 ?} + set resLong {1 2 3 4 5 6 7 8 9} + } + + 8 {set end { + # Telling the server to close the connection. + GET a + GET b close=y + GET c + GET a + GET b + GET c + GET a + GET b + GET c + STOP + } + set resShort {1 ? 3 ? ? ? ? ? ?} + set resLong {1 2 3 4 5 6 7 8 9} + } + + 9 {set end { + # Telling the server to close the connection. + GET a + POST b close=y address=home code=brief paid=yes + GET c + GET a + GET b + GET c + GET a + GET b + GET c + STOP + } + set resShort {1 2 3 ? ? ? ? ? ?} + set resLong {1 2 3 4 5 6 7 8 9} + } + + 10 {set end { + # Telling the server to close the connection. + GET a + GET b close=y + POST c address=home code=brief paid=yes + GET a + GET b + GET c + GET a + GET b + GET c + STOP + } + set resShort {1 ? 3 ? ? ? ? ? ?} + set resLong {1 2 3 4 5 6 7 8 9} + } + + 11 {set end { + # Telling the server to close the connection twice. + GET a + GET b close=y + GET c + GET a + GET b close=y + GET c + GET a + GET b + GET c + STOP + } + set resShort {1 ? 3 ? ? 6 ? ? ?} + set resLong {1 2 3 4 5 6 7 8 9} + } + + 12 {set end { + # Telling the server to delay before sending the response. + GET a + GET b delay=1 + GET c + GET a + GET b + STOP + } + set resShort {1 ? ? ? ?} + set resLong {1 2 3 4 5} + } + + 13 {set end { + # Making the server close the connection (time out). + GET a + WAIT 2000 + GET b + GET c + GET a + GET b + STOP + } + set resShort {1 2 ? ? ?} + set resLong {1 2 3 4 5} + } + + 14 {set end { + # Making the server close the connection (time out) twice. + GET a + WAIT 2000 + GET b + GET c + GET a + WAIT 2000 + GET b + GET c + GET a + GET b + GET c + STOP + } + set resShort {1 2 ? ? 5 ? ? ? ?} + set resLong {1 2 3 4 5 6 7 8 9} + } + + 15 {set end { + POST a address=home code=brief paid=yes + POST b address=home code=brief paid=yes close=y delay=1 + POST c address=home code=brief paid=yes delay=1 + POST a address=home code=brief paid=yes close=y + WAIT 2000 + POST b address=home code=brief paid=yes delay=1 + POST c address=home code=brief paid=yes close=y + POST a address=home code=brief paid=yes + POST b address=home code=brief paid=yes close=y + POST c address=home code=brief paid=yes + STOP + } + set resShort {1 2 3 4 5 6 7 8 9} + set resLong {1 2 3 4 5 6 7 8 9} + } + + 16 {set end { + POST a address=home code=brief paid=yes + GET b address=home code=brief paid=yes + POST c address=home code=brief paid=yes close=y + GET a address=home code=brief paid=yes + GET b address=home code=brief paid=yes close=y + POST c address=home code=brief paid=yes + WAIT 2000 + POST a address=home code=brief paid=yes + HEAD b address=home code=brief paid=yes close=y + GET c address=home code=brief paid=yes + STOP + } + set resShort {1 ? 3 4 ? 6 7 ? 9} + set resLong {1 2 3 4 5 6 7 8 9} + } + + 17 {set end { + GET b address=home code=brief paid=yes + POST a address=home code=brief paid=yes + GET a address=home code=brief paid=yes + POST c address=home code=brief paid=yes close=y + GET b address=home code=brief paid=yes + HEAD b address=home code=brief paid=yes close=y + POST c address=home code=brief paid=yes + WAIT 2000 + POST a address=home code=brief paid=yes + WAIT 2000 + GET c address=home code=brief paid=yes + STOP + } + set resShort {1 2 3 4 5 ? 7 8 9} + set resLong {1 2 3 4 5 6 7 8 9} + } + + + 18 {set end { + REPOST 0 + GET a + WAIT 2000 + POST b address=home code=brief paid=yes + GET c + GET a + STOP + } + set resShort {1 2 ? ?} + set resLong {1 2 3 4} + # resShort is overwritten below for the case ($te == 1). + } + + + 19 {set end { + REPOST 0 + GET a + WAIT 2000 + GET b address=home code=brief paid=yes + GET c + GET a + STOP + } + set resShort {1 2 ? ?} + set resLong {1 2 3 4} + } + + + 20 {set end { + POSTFRESH 1 + GET a + WAIT 2000 + POST b address=home code=brief paid=yes + GET c + GET a + STOP + } + set resShort {1 3 ?} + set resLong {1 3 4} + } + + + 21 {set end { + POSTFRESH 1 + GET a + WAIT 2000 + GET b address=home code=brief paid=yes + GET c + GET a + STOP + } + set resShort {1 2 ? ?} + set resLong {1 2 3 4} + } + + 22 {set end { + GET a + WAIT 2000 + KEEPALIVE 0 + POST b address=home code=brief paid=yes + KEEPALIVE 1 + GET c + GET a + STOP + } + set resShort {1 3 ?} + set resLong {1 3 4} + } + + + 23 {set end { + GET a + WAIT 2000 + KEEPALIVE 0 + GET b address=home code=brief paid=yes + KEEPALIVE 1 + GET c + GET a + STOP + } + set resShort {1 3 ?} + set resLong {1 3 4} + } + + 24 {set end { + GET a + KEEPALIVE 0 + POST b address=home code=brief paid=yes + KEEPALIVE 1 + GET c + GET a + STOP + } + set resShort {1 ? ?} + set resLong {1 3 4} + } + + + 25 {set end { + GET a + KEEPALIVE 0 + GET b address=home code=brief paid=yes + KEEPALIVE 1 + GET c + GET a + STOP + } + set resShort {1 ? ?} + set resLong {1 3 4} + } + + default { + return -code error {no matching script} + } + } + + + if {$ca < 3} { + # Not Keep-Alive. + set result "Passed all sanity checks." + + } elseif {$ca == 3} { + # Keep-Alive, not pipelined. + set result {} + append result "Passed all sanity checks.\n" + append result "Have overlaps including response body:\n" + + } else { + # Keep-Alive, pipelined: ($ca == 4) + set result {} + append result "Passed all sanity checks.\n" + append result "Overlap-free without response body:\n" + append result "$resShort" + } + + # - The special case of test *.18*-testEof needs test results to be + # individually written. + # - These test -repost 0 when there is a POST to apply it to, and the server + # timeout has not been detected. + if {($cb == 18) && ($te == 1)} { + if {$ca < 3} { + # Not Keep-Alive. + set result "Passed all sanity checks." + + } elseif {$ca == 3 && $delay == 0} { + # Keep-Alive, not pipelined. + set result [MakeMessage { + |Problems with sanity checks: + |Wrong sequence for token ::http::2 - {A B C D X X X} + |- and error(s) X + |Wrong sequence for token ::http::3 - {A X X} + |- and error(s) X + |Wrong sequence for token ::http::4 - {A X X X} + |- and error(s) X + | + |Have overlaps including response body: + | + }] + + } elseif {$ca == 3} { + # Keep-Alive, not pipelined. + set result [MakeMessage { + |Problems with sanity checks: + |Wrong sequence for token ::http::2 - {A B C D X X X} + |- and error(s) X + | + |Have overlaps including response body: + | + }] + + } elseif {$delay == 0} { + # Keep-Alive, pipelined: ($ca == 4) + set result [MakeMessage { + |Problems with sanity checks: + |Wrong sequence for token ::http::2 - {A B C D X X X} + |- and error(s) X + |Wrong sequence for token ::http::3 - {A X X} + |- and error(s) X + |Wrong sequence for token ::http::4 - {A X X X} + |- and error(s) X + | + |Overlap-free without response body: + | + }] + + } else { + set result [MakeMessage { + |Problems with sanity checks: + |Wrong sequence for token ::http::2 - {A B C D X X X} + |- and error(s) X + | + |Overlap-free without response body: + | + }] + + } + } + + return [list "$start$middle$end" $result] +} + +# ------------------------------------------------------------------------------ +# Proc MakeMessage +# ------------------------------------------------------------------------------ +# WHD's one-line command to generate multi-line strings from readable code. +# +# Example: +# set blurb [MakeMessage { +# |This command allows multi-line strings to be created with readable +# |code, and without breaking the rules for indentation. +# | +# |The command shifts the entire block of text to the left, omitting +# |the pipe character and the spaces to its left. +# }] +# ------------------------------------------------------------------------------ + +proc MakeMessage {in} { + regsub -all -line {^\s*\|} [string trim $in] {} + # N.B. Implicit Return. +} + + +proc ReturnTestScript {ca cb delay te} { + lassign [ReturnTestScriptAndResult $ca $cb $delay $te] script result + return $script +} + +proc ReturnTestResult {ca cb delay te} { + lassign [ReturnTestScriptAndResult $ca $cb $delay $te] script result + return $result +} + + +# ------------------------------------------------------------------------------ +# (2) Command to run a test script and use httpTest to analyse the logs. +# ------------------------------------------------------------------------------ + +namespace import httpTestScript::runHttpTestScript +namespace import httpTestScript::cleanupHttpTestScript + +proc RunTest {header footer delay te} { + set num [runHttpTestScript [ReturnTestScript $header $footer $delay $te]] + set skipOverlaps 0 + set notIncluded {} + + # -------------------------------------------------------------------------- + # Custom code for specific tests + # -------------------------------------------------------------------------- + if {$header < 3} { + set skipOverlaps 1 + for {set i 1} {$i <= $num} {incr i} { + lappend notIncluded $i + } + } elseif {$header > 2 && $footer == 18 && $te == 1} { + set skipOverlaps 1 + if {$delay == 0} { + # Transaction 1 is conventional. + # Check that transactions 2,3,4 are cancelled. + set notIncluded {1} + } else { + # Transaction 1 is conventional. + # Check that transaction 2 is cancelled. + # The timing of transactions 3 and 4 is uncertain. + set notIncluded {1 3 4} + } + } elseif {$footer in {20 22 23 24 25}} { + # Transaction 2 uses its own socket. + set notIncluded 2 + } else { + } + # -------------------------------------------------------------------------- + # End of custom code for specific tests + # -------------------------------------------------------------------------- + + + set Results [httpTest::LogAnalyse $num $skipOverlaps $notIncluded $notIncluded] + lassign $Results msg cleanE cleanF dirtyE dirtyF + if {$msg eq {}} { + set msg "Passed all sanity checks." + } else { + set msg "Problems with sanity checks:\n$msg" + } + + if 0 { + puts $msg + puts "Overlap-free including response body:\n$cleanF" + puts "Have overlaps including response body:\n$dirtyF" + puts "Overlap-free without response body:\n$cleanE" + puts "Have overlaps without response body:\n$dirtyE" + } + + if {$header < 3} { + # No ordering, just check that transactions all finish + set result $msg + } elseif {$header == 3} { + # Not pipelined - check overlaps with response body. + set result "$msg\nHave overlaps including response body:\n$dirtyF" + } else { + # Pipelined - check overlaps without response body. Check that the + # first request, the first requests after replay, and POSTs are clean. + set result "$msg\nOverlap-free without response body:\n$cleanE" + } + set ::nTokens $num + return $result +} + + +# ------------------------------------------------------------------------------ +# (3) VERBOSITY CONTROL +# ------------------------------------------------------------------------------ +# If tests fail, run an individual test with -verbose 1 or 2 for diagnosis. +# If still obscure, uncomment #Log and ##Log lines in the http package. +# ------------------------------------------------------------------------------ + +set ::httpTest::testOptions(-verbose) 0 + + +# ------------------------------------------------------------------------------ +# (4) Define the base URLs used for testing. Each must have a query string. +# ------------------------------------------------------------------------------ +# - A HTTP/1.1 server is required. It should be configured to provide +# persistent connections when requested to do so, and to close these +# connections if they are idle for one second. +# - The resource must be served with status 200 in response to a valid GET or +# POST. +# - The value of "page" is always specified in the query-string. Different +# resources for the three values of "page" allow testing of both chunked and +# unchunked transfer encoding. +# - The variables "close" and "delay" may be specified in the query-string (for +# a GET) or the request body (for a POST). +# - "delay" is a numerical value in seconds, and causes the server to delay +# the response, including headers. +# - "close", if it has the value "y", instructs the server to close the +# connection ater the current request. +# - Any other variables should be ignored. +# ------------------------------------------------------------------------------ + +namespace eval ::httpTestScript { + variable URL + array set URL { + a http://test-tcl-http.kerlin.org/index.html?page=privacy + b http://test-tcl-http.kerlin.org/index.html?page=conditions + c http://test-tcl-http.kerlin.org/index.html?page=welcome + } +} + + +# ------------------------------------------------------------------------------ +# (5) Define the tests +# ------------------------------------------------------------------------------ +# Constraints: +# - serverNeeded - the URLs defined at (4) must be available, and must have the +# properties specified there. +# - duplicate - the value of -pipeline does not matter if -keepalive 0 +# - timeout1s - tests that work correctly only if the server closes +# persistent connections after one second. +# +# Server timeout of persistent connections should be 1s. Delays of 2s are +# intended to cause timeout. +# Servers are usually configured to use a longer timeout: this will cause the +# tests to fail. The "2000" could be replaced with a larger number, but the +# tests will then be inconveniently slow. +# ------------------------------------------------------------------------------ + +#testConstraint serverNeeded 1 +#testConstraint timeout1s 1 +#testConstraint duplicate 1 + +# ------------------------------------------------------------------------------ +# Proc SetTestEof - to edit the command ::http::KeepSocket +# ------------------------------------------------------------------------------ +# The usual line in command ::http::KeepSocket is " set TEST_EOF 0". +# Whether the value set in the file is 0 or 1, change it here to the value +# specified by the argument. +# +# It is worth doing all tests for both values of the argument. +# +# test 0 - ::http::KeepSocket is unchanged, detects server eof where possible +# and closes the connection. +# test 1 - ::http::KeepSocket is edited, does not detect server eof, so the +# reaction to finding server eof can be tested without the difficulty +# of testing in the few milliseconds of an asynchronous close event. +# ------------------------------------------------------------------------------ + +proc SetTestEof {test} { + set body [info body ::http::KeepSocket] + set subs " set TEST_EOF $test" + set count [regsub -line -all -- {^\s*set TEST_EOF .*$} $body $subs newBody] + if {$count != 1} { + return -code error {proc ::http::KeepSocket has unexpected form} + } + proc ::http::KeepSocket {token} $newBody + return +} + +for {set header 1} {$header <= 4} {incr header} { + if {$header == 4} { + set ::httpTest::testOptions(-dotted) 1 + set match glob + } else { + set ::httpTest::testOptions(-dotted) 0 + set match exact + } + + if {$header == 2} { + set cons0 {serverNeeded duplicate} + } else { + set cons0 serverNeeded + } + + for {set footer 1} {$footer <= 25} {incr footer} { + foreach {delay label} { + 0 a + 1 b + 2 c + 3 d + 5 e + 8 f + 12 g + 100 h + 500 i + 2000 j + } { + foreach te {0 1} { + if {$te} { + set tag testEof + } else { + set tag normal + } + set suffix {} + set cons $cons0 + + # ------------------------------------------------------------------ + # Custom code for individual tests + # ------------------------------------------------------------------ + if {$footer in {18}} { + # Custom code: + if {($label eq "j") && ($te == 1)} { + continue + } + if {$te == 1} { + # The test (of REPOST 0) is useful if tag is "testEof" + # (server timeout without client reaction). The same test + # has a different result if tag is "normal". + + set suffix " - extra test for -repost 0 - ::http::2 must be" + append suffix " cancelled" + if {($delay == 0)} { + append suffix ", along with ::http::3 ::http::4 if" + append suffix " the test creates these before ::http::2" + append suffix " is cancelled" + } + } else { + } + } elseif {$footer in {19}} { + set suffix " - extra test for -repost 0" + } elseif {$footer in {20 21}} { + set suffix " - extra test for -postfresh 1" + if {($footer == 20)} { + append suffix " - ::http::2 uses a separate socket" + append suffix ", other requests use a persistent connection" + } + } elseif {$footer in {22 23 24 25}} { + append suffix " - ::http::2 uses a separate socket" + append suffix ", other requests use a persistent connection" + } else { + } + + if {($footer >= 13 && $footer <= 23)} { + # Test use WAIT and depend on server timeout before this time. + lappend cons timeout1s + } + # ------------------------------------------------------------------ + # End of custom code. + # ------------------------------------------------------------------ + + set name "pipeline test header $header footer $footer delay $delay $tag$suffix" + + + # Here's the test: + test http11-${header}.${footer}${label}-${tag} $name -constraints $cons \ + -setup [string map [list TE $te] { + http::init + set http::http(uid) 0 + # Restore default values for tests: + http::config -pipeline 1 -postfresh 0 -repost 1 + SetTestEof {TE} + }] -body [list RunTest $header $footer $delay $te] -cleanup { + # Restore default values for tests: + http::config -pipeline 1 -postfresh 0 -repost 1 + cleanupHttpTestScript + SetTestEof 0 + set ::httpTest::testResults {} + after 2000 + # Wait for persistent sockets on the server to time out. + } -result [ReturnTestResult $header $footer $delay $te] -match $match + + + } + + } + } +} + +# ------------------------------------------------------------------------------ +# (*) Notes on tests *.18*-testEof, *.19*-testEof - these test -repost 0 +# ------------------------------------------------------------------------------ +# These tests are a bit awkward because the main test kit analyses whether all +# requests are satisfied, with retries if necessary, and it has result analysis +# for processing retry logs. +# - *.18*-testEof tests that certain requests are NOT satisfied, so the analysis +# is a one-off. +# - Tests *.18a-testEof depend on client/server timing - the test needs to call +# http::geturl for all requests before the POST (request 2) is cancelled. +# We test that requests 2, 3, 4 are all cancelled. +# - Other tests *.18*-testEof may not request 3 and 4 in time for the to be +# added to the write queue before request 2 is completed. We simply check that +# request 2 is cancelled. +# - The behaviour is different if all connections are allowed to time out +# (label "j"). This case is not needed to test -repost 0, and is omitted. +# - Tests *.18*-normal and *.19* are conventional (-repost 0 should have no +# effect). +# ------------------------------------------------------------------------------ + + +unset header footer delay label suffix match cons name te +namespace delete ::httpTest +namespace delete ::httpTestScript + +::tcltest::cleanupTests diff --git a/tests/httpTest.tcl b/tests/httpTest.tcl new file mode 100644 index 0000000..ad08048 --- /dev/null +++ b/tests/httpTest.tcl @@ -0,0 +1,431 @@ +# httpTest.tcl +# +# Test HTTP/1.1 concurrent requests including +# queueing, pipelining and retries. +# +# Copyright (C) 2018 Keith Nash +# +# See the file "license.terms" for information on usage and redistribution +# of this file, and for a DISCLAIMER OF ALL WARRANTIES. + +# ------------------------------------------------------------------------------ +# "Package" httpTest for analysis of Log output of http requests. +# ------------------------------------------------------------------------------ +# This is a specialised test kit for examining the presence, ordering, and +# overlap of multiple HTTP transactions over a persistent ("Keep-Alive") +# connection; and also for testing reconnection in accordance with RFC 7230 when +# the connection is lost. +# +# This kit is probably not useful for other purposes. It depends on the +# presence of specific Log commands in the http library, and it interprets the +# logs that these commands create. +# ------------------------------------------------------------------------------ + +package require http + +namespace eval ::http { + variable TestStartTimeInMs [clock milliseconds] +} + +namespace eval ::httpTest { + variable testResults {} + variable testOptions + array set testOptions { + -verbose 0 + -dotted 1 + } + # -verbose - 0 quiet 1 write to stderr 2 write more + # -dotted - (boolean) use dots for absences in lists of transactions +} + +proc httpTest::Puts {txt} { + variable testOptions + if {$testOptions(-verbose) > 0} { + puts stderr $txt + flush stderr + } + return +} + +# http::Log +# +# A special-purpose logger used for running tests. +# - Processes Log calls that have "^" in their arguments, and records them in +# variable ::httpTest::testResults. +# - Also writes them to stderr (using Puts) if ($testOptions(-verbose) > 0). +# - Also writes Log calls that do not have "^", if ($testOptions(-verbose) > 1). + +proc http::Log {args} { + variable TestStartTimeInMs + set time [expr {[clock milliseconds] - $TestStartTimeInMs}] + set txt [list $time {*}$args] + if {[string first ^ $txt] != -1} { + ::httpTest::LogRecord $txt + ::httpTest::Puts $txt + } elseif {$::httpTest::testOptions(-verbose) > 1} { + ::httpTest::Puts $txt + } + return +} + + +# Called by http::Log (the "testing" version) to record logs for later analysis. + +proc httpTest::LogRecord {txt} { + variable testResults + + set pos [string first ^ $txt] + set len [string length $txt] + if {$pos > $len - 3} { + puts stderr "Logging Error: $txt" + puts stderr "Fix this call to Log in http-*.tm so it has ^ then\ + a letter then a numeral." + flush stderr + } elseif {$pos == -1} { + # Called by mistake. + } else { + set letter [string index $txt [incr pos]] + set number [string index $txt [incr pos]] + # Max 9 requests! + lappend testResults [list $letter $number] + } + + return +} + + +# ------------------------------------------------------------------------------ +# Commands for analysing the logs recorded when calling http::geturl. +# ------------------------------------------------------------------------------ + +# httpTest::TestOverlaps -- +# +# The main test for correct behaviour of pipelined and sequential +# (non-pipelined) transactions. Other tests should be run first to detect +# any inconsistencies in the data (e.g. absence of the elements that are +# examined here). +# +# Examine the sequence $someResults for each transaction from 1 to $n, +# ignoring any that are listed in $badTrans. +# Determine whether the elements "B" to $term for one transaction overlap +# elements "B" to $term for the previous and following transactions. +# +# Transactions in the list $badTrans are not included in "clean" or +# "dirty", but their possible overlap with other transactions is noted. +# Transactions in the list $notPiped are a subset of $badTrans, and +# their possible overlap with other transactions is NOT noted. +# +# Arguments: +# someResults - list of results, each of the form {letter numeral} +# n - number of HTTP transactions +# term - letter that indicated end of search range. "E" for testing +# overlaps from start of request to end of response headers. +# "F" to extend to the end of the response body. +# msg - the cumulative message from sanity checks. Append to it only +# to report a test failure. +# badTrans - list of transaction numbers not to be assessed as "clean" or +# "dirty" +# notPiped - subset of badTrans. List of transaction numbers that cannot +# taint another transaction by overlapping with it, because it +# used a different socket. +# +# Return value: [list $msg $clean $dirty] +# msg - warning messages: nothing will be appended to argument $msg if there +# is an error with the test. +# clean - list of transactions that have no overlap with other transactions +# dirty - list of transactions that have YES overlap with other transactions + +proc httpTest::TestOverlaps {someResults n term msg badTrans notPiped} { + variable testOptions + + # Check whether transactions overlap: + set clean {} + set dirty {} + for {set i 1} {$i <= $n} {incr i} { + if {$i in $badTrans} { + continue + } + set myStart [lsearch -exact $someResults [list B $i]] + set myEnd [lsearch -exact $someResults [list $term $i]] + + if {($myStart == -1 || $myEnd == -1)} { + set res "Cannot find positions of transaction $i" + append msg $res \n + Puts $res + } + + set overlaps {} + for {set j $myStart} {$j <= $myEnd} {incr j} { + lassign [lindex $someResults $j] letter number + if {$number != $i && $letter ne "A" && $number ni $notPiped} { + lappend overlaps $number + } + } + + if {[llength $overlaps] == 0} { + set res "Transaction $i has no overlaps" + Puts $res + lappend clean $i + if {$testOptions(-dotted)} { + # N.B. results from different segments are concatenated. + lappend dirty . + } else { + } + } else { + set res "Transaction $i overlaps with [join $overlaps { }]" + Puts $res + lappend dirty $i + if {$testOptions(-dotted)} { + # N.B. results from different segments are concatenated. + lappend clean . + } else { + } + } + } + return [list $msg $clean $dirty] +} + +# httpTest::PipelineNext -- +# +# Test whether prevPair, pair are valid as consecutive elements of a pipelined +# sequence (Start 1), (End 1), (Start 2), (End 2) ... +# Numbers are integers increasing (by 1 if argument "any" is false), and need +# not begin with 1. +# The first element of the sequence has prevPair {} and is always passed as +# valid. +# +# Arguments; +# Start - string that labels the start of a segment +# End - string that labels the end of a segment +# prevPair - previous "pair" (list of string and number) element of a +# sequence, or {} if argument "pair" is the first in the +# sequence. +# pair - current "pair" (list of string and number) element of a +# sequence +# any - (boolean) iff true, accept any increasing sequence of integers. +# If false, integers must increase by 1. +# +# Return value - boolean, true iff the two pairs are valid consecutive elements. + +proc httpTest::PipelineNext {Start End prevPair pair any} { + if {$prevPair eq {}} { + return 1 + } + + lassign $prevPair letter number + lassign $pair newLetter newNumber + if {$letter eq $Start} { + return [expr {($newLetter eq $End) && ($newNumber == $number)}] + } elseif {$any} { + set nxt [list $Start [expr {$number + 1}]] + return [expr {($newLetter eq $Start) && ($newNumber > $number)}] + } else { + set nxt [list $Start [expr {$number + 1}]] + return [expr {($newLetter eq $Start) && ($newNumber == $number + 1)}] + } +} + +# httpTest::TestPipeline -- +# +# Given a sequence of "pair" elements, check that the elements whose string is +# $Start or $End form a valid pipeline. Ignore other elements. +# +# Return value: {} if valid pipeline, otherwise a non-empty error message. + +proc httpTest::TestPipeline {someResults n Start End msg desc badTrans} { + set sequence {} + set prevPair {} + set ok 1 + set any [llength $badTrans] + foreach pair $someResults { + lassign $pair letter number + if {($letter in [list $Start $End]) && ($number ni $badTrans)} { + lappend sequence $pair + if {![PipelineNext $Start $End $prevPair $pair $any]} { + set ok 0 + break + } + set prevPair $pair + } + } + + if {!$ok} { + set res "$desc are not pipelined: {$sequence}" + append msg $res \n + Puts $res + } + return $msg +} + +# httpTest::TestSequence -- +# +# Examine each transaction from 1 to $n, ignoring any that are listed +# in $badTrans. +# Check that each transaction has elements A to F, in alphabetical order. + +proc httpTest::TestSequence {someResults n msg badTrans} { + variable testOptions + + for {set i 1} {$i <= $n} {incr i} { + if {$i in $badTrans} { + continue + } + set sequence {} + foreach pair $someResults { + lassign $pair letter number + if {$number == $i} { + lappend sequence $letter + } + } + if {$sequence eq {A B C D E F}} { + } else { + set res "Wrong sequence for token ::http::$i - {$sequence}" + append msg $res \n + Puts $res + if {"X" in $sequence} { + set res "- and error(s) X" + append msg $res \n + Puts $res + } + if {"Y" in $sequence} { + set res "- and warnings(s) Y" + append msg $res \n + Puts $res + } + } + } + return $msg +} + +proc httpTest::MostAnalysis {someResults n msg skipOverlaps badTrans notPiped} { + variable testOptions + + # Check that stages for "good" transactions are all present and correct: + set msg [TestSequence $someResults $n $msg $badTrans] + + # Check that requests are pipelined: + set msg [TestPipeline $someResults $n B C $msg Requests $notPiped] + + # Check that responses are pipelined: + set msg [TestPipeline $someResults $n D F $msg Responses $notPiped] + + if {$skipOverlaps} { + set cleanE {} + set dirtyE {} + set cleanF {} + set dirtyF {} + } else { + Puts "Overlaps including response body (test for non-pipelined case)" + lassign [TestOverlaps $someResults $n F $msg $badTrans $notPiped] msg cleanF dirtyF + + Puts "Overlaps without response body (test for pipelined case)" + lassign [TestOverlaps $someResults $n E $msg $badTrans $notPiped] msg cleanE dirtyE + } + + return [list $msg $cleanE $cleanF $dirtyE $dirtyF] +} + +# httpTest::ProcessRetries -- +# +# Command to examine results for socket-changing records [PQR], +# divide the results into segments for each connection, and analyse each segment +# individually. +# (Could add $sock to the logging to simplify this, but never mind.) +# +# In each segment, identify any transactions that are not included, and +# any that are aborted, to assist subsequent testing. +# +# Prepend A records (socket-independent) to each segment for transactions that +# were scheduled (by A) but not completed (by F). Pass each segment to +# MostAnalysis for processing. + +proc httpTest::ProcessRetries {someResults n msg skipOverlaps notIncluded notPiped} { + variable testOptions + + set nextRetry [lsearch -glob -index 0 $someResults {[PQR]}] + if {$nextRetry == -1} { + return [MostAnalysis $someResults $n $msg $skipOverlaps $notIncluded $notPiped] + } + set badTrans $notIncluded + set tryCount 0 + set try $nextRetry + incr tryCount + lassign [lindex $someResults $try] letter number + Puts "Processing retry [lindex $someResults $try]" + set beforeTry [lrange $someResults 0 $try-1] + Puts [join $beforeTry \n] + set afterTry [lrange $someResults $try+1 end] + + set dummyTry {} + for {set i 1} {$i <= $n} {incr i} { + set first [lsearch -exact $beforeTry [list A $i]] + set last [lsearch -exact $beforeTry [list F $i]] + if {$first == -1} { + set res "Transaction $i was not started in connection number $tryCount" + # append msg $res \n + Puts $res + if {$i ni $badTrans} { + lappend badTrans $i + } else { + } + } elseif {$last == -1} { + set res "Transaction $i was started but unfinished in connection number $tryCount" + # append msg $res \n + Puts $res + lappend badTrans $i + lappend dummyTry [list A $i] + } else { + set res "Transaction $i was started and finished in connection number $tryCount" + # append msg $res \n + Puts $res + lappend notIncluded $i + } + } + + # Analyse the part of the results before the first replay: + set HeadResults [MostAnalysis $beforeTry $n $msg $skipOverlaps $badTrans $notPiped] + lassign $HeadResults msg cleanE1 cleanF1 dirtyE1 dirtyF1 + + # Pass the rest of the results to be processed recursively. + set afterTry [concat $dummyTry $afterTry] + set TailResults [ProcessRetries $afterTry $n $msg $skipOverlaps $notIncluded $notPiped] + lassign $TailResults msg cleanE2 cleanF2 dirtyE2 dirtyF2 + + set cleanE [concat $cleanE1 $cleanE2] + set cleanF [concat $cleanF1 $cleanF2] + set dirtyE [concat $dirtyE1 $dirtyE2] + set dirtyF [concat $dirtyF1 $dirtyF2] + return [list $msg $cleanE $cleanF $dirtyE $dirtyF] +} + +proc httpTest::LogAnalyse {n skipOverlaps notIncluded notPiped} { + variable testResults + variable testOptions + + # Check that each data item has the correct form {letter numeral}. + set ii 0 + set ok 1 + foreach pair $testResults { + lassign $pair letter number + if { [string match {[A-Z]} $letter] + && [string match {[0-9]} $number] + } { + # OK + } else { + set ok 0 + set res "Error: testResults has bad element {$pair} at position $ii" + append msg $res \n + Puts $res + } + incr ii + } + + if {!$ok} { + return $msg + } + set msg {} + + Puts [join $testResults \n] + ProcessRetries $testResults $n $msg $skipOverlaps $notIncluded $notPiped + # N.B. Implicit Return. +} diff --git a/tests/httpTestScript.tcl b/tests/httpTestScript.tcl new file mode 100644 index 0000000..a826c81 --- /dev/null +++ b/tests/httpTestScript.tcl @@ -0,0 +1,509 @@ +# httpTestScript.tcl +# +# Test HTTP/1.1 concurrent requests including +# queueing, pipelining and retries. +# +# Copyright (C) 2018 Keith Nash +# +# See the file "license.terms" for information on usage and redistribution +# of this file, and for a DISCLAIMER OF ALL WARRANTIES. + +# ------------------------------------------------------------------------------ +# "Package" httpTestScript for executing test scripts written in a convenient +# shorthand. +# ------------------------------------------------------------------------------ + +# ------------------------------------------------------------------------------ +# Documentation for "package" httpTestScript. +# ------------------------------------------------------------------------------ +# To use the package: +# (a) define URLs as the values of elements in the array ::httpTestScript +# (b) define a script in terms of the commands +# START STOP DELAY KEEPALIVE WAIT PIPELINE GET HEAD POST +# referring to URLs by the name of the corresponding array element. The +# script can include any other Tcl commands, and evaluates in the +# httpTestScript namespace. +# (c) Use the command httpTestScript::runHttpTestScript to evaluate the script. +# (d) For tcltest tests, wrap the runHttpTestScript call in a suitable "test" +# command. +# ------------------------------------------------------------------------------ +# START +# Must be the first command of the script. +# +# STOP +# Must be present in the script to avoid waiting for client timeout. +# Usually the last command, but can be elsewhere to end a script prematurely. +# Subsequent httpTestScript commands will have no effect. +# +# DELAY ms +# If there are no WAIT commands, this sets the delay in ms between subsequent +# calls to http::geturl. Default 500ms. +# +# KEEPALIVE +# Set the value passed to http::geturl for the -keepalive option. The command +# applies to subsequent requests in the script. Default 1. +# +# WAIT ms +# Pause for a time in ms before sending subsequent requests. +# +# PIPELINE boolean +# Set the value of -pipeline using http::config. The last PIPELINE command +# in the script applies to every request. Default 1. +# +# POSTFRESH boolean +# Set the value of -postfresh using http::config. The last POSTFRESH command +# in the script applies to every request. Default 0. +# +# REPOST boolean +# Set the value of -repost using http::config. The last REPOST command +# in the script applies to every request. Default 1 for httpTestScript. +# (Default value in http is 0). +# +# GET uriCode ?arg ...? +# Send a HTTP request using the GET method. +# Arguments: +# uriCode - the code for the base URI - the value must be stored in +# ::httpTestScript::URL($uriCode). +# args - strings that will be joined by "&" and appended to the query +# string with a preceding "&". +# +# HEAD uriCode ?arg ...? +# Send a HTTP request using the HEAD method. +# Arguments: as for GET +# +# POST uriCode ?arg ...? +# Send a HTTP request using the POST method. +# Arguments: +# uriCode - the code for the base URI - the value must be stored in +# ::httpTestScript::URL($uriCode). +# args - strings that will be joined by "&" and used as the request body. +# ------------------------------------------------------------------------------ + +namespace eval ::httpTestScript { + namespace export runHttpTestScript cleanupHttpTestScript +} + +# httpTestScript::START -- +# Initialise, and create a long-stop timeout. + +proc httpTestScript::START {} { + variable CountRequestedSoFar + variable RequestsWhenStopped + variable KeepAlive + variable Delay + variable TimeOutCode + variable TimeOutDone + variable StartDone + variable StopDone + variable CountFinishedSoFar + variable RequestList + variable RequestsMade + variable ExtraTime + variable ActualKeepAlive + + if {[info exists StartDone] && ($StartDone == 1)} { + set msg {START has been called twice without an intervening STOP} + return -code error $msg + } + + set StartDone 1 + set StopDone 0 + set TimeOutDone 0 + set CountFinishedSoFar 0 + set CountRequestedSoFar 0 + set RequestList {} + set RequestsMade {} + set ExtraTime 0 + set ActualKeepAlive 1 + + # Undefined until a STOP command: + unset -nocomplain RequestsWhenStopped + + # Default values: + set KeepAlive 1 + set Delay 500 + + # Default values for tests: + KEEPALIVE 1 + PIPELINE 1 + POSTFRESH 0 + REPOST 1 + + set TimeOutCode [after 30000 httpTestScript::TimeOutNow] +# set TimeOutCode [after 4000 httpTestScript::TimeOutNow] + return +} + +# httpTestScript::STOP -- +# Do not process any more commands. The commands will be executed but will +# silently do nothing. + +proc httpTestScript::STOP {} { + variable CountRequestedSoFar + variable CountFinishedSoFar + variable RequestsWhenStopped + variable TimeOutCode + variable StartDone + variable StopDone + variable RequestsMade + + if {$StopDone} { + # Don't do anything on a second call. + return + } + + if {![info exists StartDone]} { + return -code error {initialise the script by calling command START} + } + + set StopDone 1 + set StartDone 0 + set RequestsWhenStopped $CountRequestedSoFar + unset -nocomplain StartDone + + if {$CountFinishedSoFar == $RequestsWhenStopped} { + if {[info exists TimeOutCode]} { + after cancel $TimeOutCode + } + set ::httpTestScript::FOREVER 0 + } + return +} + +# httpTestScript::DELAY -- +# If there are no WAIT commands, this sets the delay in ms between subsequent +# calls to http::geturl. Default 500ms. + +proc httpTestScript::DELAY {t} { + variable StartDone + variable StopDone + + if {$StopDone} { + return + } + + if {![info exists StartDone]} { + return -code error {initialise the script by calling command START} + } + + variable Delay + + set Delay $t + return +} + +# httpTestScript::KEEPALIVE -- +# Set the value passed to http::geturl for the -keepalive option. Default 1. + +proc httpTestScript::KEEPALIVE {b} { + variable StartDone + variable StopDone + + if {$StopDone} { + return + } + + if {![info exists StartDone]} { + return -code error {initialise the script by calling command START} + } + + variable KeepAlive + set KeepAlive $b + return +} + +# httpTestScript::WAIT -- +# Pause for a time in ms before processing any more commands. + +proc httpTestScript::WAIT {t} { + variable StartDone + variable StopDone + variable ExtraTime + + if {$StopDone} { + return + } + + if {![info exists StartDone]} { + return -code error {initialise the script by calling command START} + } + + if {(![string is integer -strict $t]) || $t < 0} { + return -code error {argument to WAIT must be a non-negative integer} + } + + incr ExtraTime $t + + return +} + +# httpTestScript::PIPELINE -- +# Pass a value to http::config -pipeline. + +proc httpTestScript::PIPELINE {b} { + variable StartDone + variable StopDone + + if {$StopDone} { + return + } + + if {![info exists StartDone]} { + return -code error {initialise the script by calling command START} + } + + ::http::config -pipeline $b + ::http::Log http(-pipeline) is now [::http::config -pipeline] + return +} + +# httpTestScript::POSTFRESH -- +# Pass a value to http::config -postfresh. + +proc httpTestScript::POSTFRESH {b} { + variable StartDone + variable StopDone + + if {$StopDone} { + return + } + + if {![info exists StartDone]} { + return -code error {initialise the script by calling command START} + } + + ::http::config -postfresh $b + ::http::Log http(-postfresh) is now [::http::config -postfresh] + return +} + +# httpTestScript::REPOST -- +# Pass a value to http::config -repost. + +proc httpTestScript::REPOST {b} { + variable StartDone + variable StopDone + + if {$StopDone} { + return + } + + if {![info exists StartDone]} { + return -code error {initialise the script by calling command START} + } + + ::http::config -repost $b + ::http::Log http(-repost) is now [::http::config -repost] + return +} + +# httpTestScript::GET -- +# Send a HTTP request using the GET method. +# Arguments: +# uriCode - the code for the base URI - the value must be stored in +# ::httpTestScript::URL($uriCode). +# args - strings that will each be preceded by "&" and appended to the query +# string. + +proc httpTestScript::GET {uriCode args} { + variable RequestList + lappend RequestList GET + RequestAfter $uriCode 0 {} {*}$args + return +} + +# httpTestScript::HEAD -- +# Send a HTTP request using the HEAD method. +# Arguments: as for GET + +proc httpTestScript::HEAD {uriCode args} { + variable RequestList + lappend RequestList HEAD + RequestAfter $uriCode 1 {} {*}$args + return +} + +# httpTestScript::POST -- +# Send a HTTP request using the POST method. +# Arguments: +# uriCode - the code for the base URI - the value must be stored in +# ::httpTestScript::URL($uriCode). +# args - strings that will be joined by "&" and used as the request body. + +proc httpTestScript::POST {uriCode args} { + variable RequestList + lappend RequestList POST + RequestAfter $uriCode 0 {use} {*}$args + return +} + + +proc httpTestScript::RequestAfter {uriCode validate query args} { + variable CountRequestedSoFar + variable Delay + variable ExtraTime + variable StartDone + variable StopDone + variable KeepAlive + + if {$StopDone} { + return + } + + if {![info exists StartDone]} { + return -code error {initialise the script by calling command START} + } + + incr CountRequestedSoFar + set idelay [expr {($CountRequestedSoFar - 1) * $Delay + 10 + $ExtraTime}] + + # Could pass values of -pipeline, -postfresh, -repost if it were + # useful to change these mid-script. + after $idelay [list httpTestScript::Requester $uriCode $KeepAlive $validate $query {*}$args] + return +} + +proc httpTestScript::Requester {uriCode keepAlive validate query args} { + variable URL + + ::http::config -accept {*/*} + + set absUrl $URL($uriCode) + if {$query eq {}} { + if {$args ne {}} { + append absUrl & [join $args &] + } + set queryArgs {} + } elseif {$validate} { + return -code error {cannot have both -validate (HEAD) and -query (POST)} + } else { + set queryArgs [list -query [join $args &]] + } + + if {[catch { + ::http::geturl $absUrl \ + -validate $validate \ + -timeout 5000 \ + {*}$queryArgs \ + -keepalive $keepAlive \ + -command ::httpTestScript::WhenFinished + } token]} { + set msg $token + catch {puts stderr "Error: $msg"} + return + } else { + # Request will begin. + } + + return + +} + +proc httpTestScript::TimeOutNow {} { + variable TimeOutDone + + set TimeOutDone 1 + set ::httpTestScript::FOREVER 0 + return +} + +proc httpTestScript::WhenFinished {hToken} { + variable CountFinishedSoFar + variable RequestsWhenStopped + variable TimeOutCode + variable StopDone + variable RequestList + variable RequestsMade + variable ActualKeepAlive + + upvar #0 $hToken state + + if {[catch { + if { [info exists state(transfer)] + && ($state(transfer) eq "chunked") + } { + set Trans chunked + } else { + set Trans unchunked + } + + if { [info exists ::httpTest::testOptions(-verbose)] + && ($::httpTest::testOptions(-verbose) > 0) + } { + puts "Token $hToken +Response $state(http) +Status $state(status) +Method $state(method) +Transfer $Trans +Size $state(currentsize) +URL $state(url) +" + } + + if {!$state(-keepalive)} { + set ActualKeepAlive 0 + } + + if {[info exists state(method)]} { + lappend RequestsMade $state(method) + } else { + lappend RequestsMade UNKNOWN + } + set tk [namespace tail $hToken] + + if { ($state(http) != {HTTP/1.1 200 OK}) + || ($state(status) != {ok}) + || (($state(currentsize) == 0) && ($state(method) ne "HEAD")) + } { + ::http::Log ^X$tk unexpected result Response $state(http) Status $state(status) Size $state(currentsize) - token $hToken + } + } err]} { + ::http::Log ^X$tk httpTestScript::WhenFinished failed with error status: $err - token $hToken + } + + incr CountFinishedSoFar + if {$StopDone && ($CountFinishedSoFar == $RequestsWhenStopped)} { + if {[info exists TimeOutCode]} { + after cancel $TimeOutCode + } + if {$RequestsMade ne $RequestList && $ActualKeepAlive} { + ::http::Log ^X$tk unexpected result - Script asked for "{$RequestList}" but got "{$RequestsMade}" - token $hToken + } + set ::httpTestScript::FOREVER 0 + } + + return +} + + +proc httpTestScript::runHttpTestScript {scr} { + variable TimeOutDone + variable RequestsWhenStopped + + after idle [list namespace eval ::httpTestScript $scr] + vwait ::httpTestScript::FOREVER + # N.B. does not automatically execute in this namespace, unlike some other events. + # Release when all requests have been served or have timed out. + + if {$TimeOutDone} { + return -code error {test script timed out} + } + + return $RequestsWhenStopped +} + + +proc httpTestScript::cleanupHttpTestScript {} { + variable TimeOutDone + variable RequestsWhenStopped + + if {![info exists RequestsWhenStopped]} { + return -code error {Cleanup Failed: RequestsWhenStopped is undefined} + } + + for {set i 1} {$i <= $RequestsWhenStopped} {incr i} { + http::cleanup ::http::$i + } + + return +} -- cgit v0.12 From a0e1b18138fb42f0dee9353735aa7938a1c19951 Mon Sep 17 00:00:00 2001 From: kjnash Date: Thu, 29 Mar 2018 18:20:56 +0000 Subject: Adapt tests/httpPipeline.test for test without installation. Comment out some Log calls from tests/httpTestScript.tcl --- tests/httpPipeline.test | 4 ++-- tests/httpTestScript.tcl | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/httpPipeline.test b/tests/httpPipeline.test index 017661d..33462c05 100644 --- a/tests/httpPipeline.test +++ b/tests/httpPipeline.test @@ -809,10 +809,10 @@ for {set header 1} {$header <= 4} {incr header} { # Here's the test: test http11-${header}.${footer}${label}-${tag} $name -constraints $cons \ -setup [string map [list TE $te] { - http::init - set http::http(uid) 0 # Restore default values for tests: http::config -pipeline 1 -postfresh 0 -repost 1 + http::init + set http::http(uid) 0 SetTestEof {TE} }] -body [list RunTest $header $footer $delay $te] -cleanup { # Restore default values for tests: diff --git a/tests/httpTestScript.tcl b/tests/httpTestScript.tcl index a826c81..048cb4f 100644 --- a/tests/httpTestScript.tcl +++ b/tests/httpTestScript.tcl @@ -253,7 +253,7 @@ proc httpTestScript::PIPELINE {b} { } ::http::config -pipeline $b - ::http::Log http(-pipeline) is now [::http::config -pipeline] + ##::http::Log http(-pipeline) is now [::http::config -pipeline] return } @@ -273,7 +273,7 @@ proc httpTestScript::POSTFRESH {b} { } ::http::config -postfresh $b - ::http::Log http(-postfresh) is now [::http::config -postfresh] + ##::http::Log http(-postfresh) is now [::http::config -postfresh] return } @@ -293,7 +293,7 @@ proc httpTestScript::REPOST {b} { } ::http::config -repost $b - ::http::Log http(-repost) is now [::http::config -repost] + ##::http::Log http(-repost) is now [::http::config -repost] return } -- cgit v0.12 From 3117af219fe5b0c4374266fd7f781223f3036eb9 Mon Sep 17 00:00:00 2001 From: kjnash Date: Fri, 30 Mar 2018 10:02:44 +0000 Subject: Bugfixes. Details in ticket 46b6edad51. --- library/http/http.tcl | 372 +++++++++++++++++++++++++++++++----------------- tests/httpPipeline.test | 3 +- 2 files changed, 241 insertions(+), 134 deletions(-) diff --git a/library/http/http.tcl b/library/http/http.tcl index f4f83c6..a268e87 100644 --- a/library/http/http.tcl +++ b/library/http/http.tcl @@ -72,14 +72,20 @@ namespace eval http { variable socketClosing variable socketPlayCmd if {[info exists socketMapping]} { - # Close open sockets on re-init + # Close open sockets on re-init. Do not permit retries. foreach {url sock} [array get socketMapping] { - catch {close $sock} + unset -nocomplain socketClosing($url) + unset -nocomplain socketPlayCmd($url) + CloseSocket $sock } } - # Traces on "unset socketRdState(*)" will cancel any queued responses. - # Traces on "unset socketWrState(*)" will cancel any queued requests. + # CloseSocket should have unset the socket* arrays, one element at + # a time. Now unset anything that was overlooked. + # Traces on "unset socketRdState(*)" will call CancelReadPipeline and + # cancel any queued responses. + # Traces on "unset socketWrState(*)" will call CancelWritePipeline and + # cancel any queued requests. array unset socketMapping array unset socketRdState array unset socketWrState @@ -123,11 +129,12 @@ namespace eval http { } namespace export geturl config reset wait formatQuery register unregister - # Useful, but not exported: data size status code cleanup error meta ncode - # Also mapReply. + # Useful, but not exported: data size status code cleanup error meta ncode, + # mapReply, init. Comments suggest that "init" can be used for + # re-initialisation, although it is undocumented. # # Not exported, probably should be upper-case initial letter as part - # of the internals: init getTextLine make-transformation-chunked + # of the internals: getTextLine make-transformation-chunked } # http::Log -- @@ -264,6 +271,7 @@ proc http::Finish {token {errormsg ""} {skipCB 0}} { } if {[info exists state(after)]} { after cancel $state(after) + unset state(after) } if {[info exists state(-command)] && (!$skipCB) && (![info exists state(done-command-cb)])} { @@ -291,6 +299,9 @@ proc http::Finish {token {errormsg ""} {skipCB 0}} { # queued task if possible. Otherwise leave it idle and ready for its next # use. # +# If $socketClosing(*), then ($state(connection) eq "close") and therefore +# this command will not be called by Finish. +# # Arguments: # token Connection token. @@ -473,6 +484,8 @@ proc http::KeepSocket {token} { } else { CloseSocket $state(sock) $token + # There is no socketMapping($state(socketinfo)), so it does not matter + # that CloseQueuedQueries is not called. } return } @@ -551,7 +564,7 @@ proc http::CloseSocket {s {token {}}} { if {$token eq {}} { # Cases with a non-empty token are handled by Finish, so the tokens # are finished in connection order. - http::CloseQueuedQueries $connId $token + http::CloseQueuedQueries $connId } else { } } else { @@ -597,15 +610,46 @@ proc http::CloseQueuedQueries {connId {token {}}} { if { [info exists socketPlayCmd($connId)] && ($socketPlayCmd($connId) ne {ReplayIfClose Wready {} {}}) } { + # Before unsetting, there is some unfinished business. + # - If the server sent "Connection: close", we have stored the command + # for retrying any queued requests in socketPlayCmd, so copy that + # value for execution below. socketClosing(*) was also set. + # - Also clear the queues to prevent calls to Finish that would set the + # state for the requests that will be retried to "finished with error + # status". set unfinished $socketPlayCmd($connId) + set socketRdQueue($connId) {} + set socketWrQueue($connId) {} } else { set unfinished {} } - # The trace on "unset socketRdState(*)" cancels any pipelined - # responses. - # The trace on "unset socketWrState(*)" cancels any pipelined - # requests. + Unset $connId + + if {$unfinished ne {}} { + Log ^R$tk Any unfinished transactions (excluding $token) failed \ + - token $token + {*}$unfinished + } + return +} + +# http::Unset +# +# The trace on "unset socketRdState(*)" will call CancelReadPipeline +# and cancel any queued responses. +# The trace on "unset socketWrState(*)" will call CancelWritePipeline +# and cancel any queued requests. + +proc http::Unset {connId} { + variable socketMapping + variable socketRdState + variable socketWrState + variable socketRdQueue + variable socketWrQueue + variable socketClosing + variable socketPlayCmd + unset socketMapping($connId) unset socketRdState($connId) unset socketWrState($connId) @@ -614,11 +658,6 @@ proc http::CloseQueuedQueries {connId {token {}}} { unset -nocomplain socketClosing($connId) unset -nocomplain socketPlayCmd($connId) - if {$unfinished ne {}} { - Log ^R$tk Any unfinished transactions (excluding $token) failed \ - - token $token - {*}$unfinished - } return } @@ -977,45 +1016,39 @@ proc http::geturl {url args} { # - We leave this binding in place until just before the last # puts+flush in http::Connected (GET/HEAD) or http::Write (POST), # after which the HTTP response might be generated. - # - Therefore we must be prepared for full closure of the socket, - # and catch errors on any socket operation. - - if {[catch {fconfigure $socketMapping($state(socketinfo))}]} { - Log "WARNING: socket for $state(socketinfo) was closed\ - - token $token" - # The trace on "unset socketRdState(*)" cancels any pipelined - # responses. - # The trace on "`(*)" cancels any pipelined - # requests. - unset socketMapping($state(socketinfo)) - unset socketRdState($state(socketinfo)) - unset socketWrState($state(socketinfo)) - unset -nocomplain socketRdQueue($state(socketinfo)) - unset -nocomplain socketWrQueue($state(socketinfo)) - unset -nocomplain socketClosing($state(socketinfo)) - unset -nocomplain socketPlayCmd($state(socketinfo)) - - # Do not automatically close the eventual connection socket. - set state(connection) {} - } elseif { [info exists socketClosing($state(socketinfo))] + if { [info exists socketClosing($state(socketinfo))] && $socketClosing($state(socketinfo)) } { - # The server has sent a "Connection: close" header. + # socketClosing(*) is set because the server has sent a + # "Connection: close" header. # Do not use the persistent socket again. # Since we have only one persistent socket per server, and the # old socket is not yet dead, add the request to the write queue # of the dying socket, which will be replayed by ReplayIfClose. + # Also add it to socketWrQueue(*) which is used only if an error + # causes a call to Finish. set reusing 1 set sock $socketMapping($state(socketinfo)) Log "reusing socket $sock for $state(socketinfo) - token $token" - # Do not automatically close this connection socket. - set state(connection) {} set alreadyQueued 1 lassign $socketPlayCmd($state(socketinfo)) com0 com1 com2 com3 lappend com3 $token set socketPlayCmd($state(socketinfo)) [list $com0 $com1 $com2 $com3] + lappend socketWrQueue($state(socketinfo)) $token + } elseif {[catch {fconfigure $socketMapping($state(socketinfo))}]} { + # FIXME Is it still possible for this code to be executed? If + # so, this could be another place to call TestForReplay, + # rather than discarding the queued transactions. + Log "WARNING: socket for $state(socketinfo) was closed\ + - token $token" + Log "WARNING - if testing, pay special attention to this\ + case (GH) which is seldom executed - token $token" + + # This will call CancelReadPipeline, CancelWritePipeline, and + # cancel any queued requests, responses. + Unset $state(socketinfo) } else { # Use the persistent socket. # The socket may not be ready to write: an earlier request might @@ -1026,9 +1059,9 @@ proc http::geturl {url args} { set sock $socketMapping($state(socketinfo)) Log "reusing socket $sock for $state(socketinfo) - token $token" - # Do not automatically close this connection socket. - set state(connection) {} } + # Do not automatically close the connection socket. + set state(connection) {} } } @@ -1073,8 +1106,8 @@ proc http::geturl {url args} { # callback (if available) because we're going to throw an # exception from here instead. - set state(sock) $sock - Finish $token "" 1 + set state(sock) NONE + Finish $token $sock 1 cleanup $token return -code error $sock } else { @@ -1093,6 +1126,18 @@ proc http::geturl {url args} { } { # Freshly-opened socket that we would like to become persistent. set socketMapping($state(socketinfo)) $sock + + if {![info exists socketRdState($state(socketinfo))]} { + set socketRdState($state(socketinfo)) {} + set varName ::http::socketRdState($state(socketinfo)) + trace add variable $varName unset ::http::CancelReadPipeline + } + if {![info exists socketWrState($state(socketinfo))]} { + set socketWrState($state(socketinfo)) {} + set varName ::http::socketWrState($state(socketinfo)) + trace add variable $varName unset ::http::CancelWritePipeline + } + if {$state(-pipeline)} { #Log new, init for pipelined, GRANT write access to $token in geturl # Also grant premature read access to the socket. This is OK. @@ -1108,16 +1153,10 @@ proc http::geturl {url args} { set socketWrState($state(socketinfo)) $token } - if {![info exists socketRdQueue($state(socketinfo))]} { - set socketRdQueue($state(socketinfo)) {} - set varName ::http::socketRdState($state(socketinfo)) - trace add variable $varName unset ::http::CancelReadPipeline - } - if {![info exists socketWrQueue($state(socketinfo))]} { - set socketWrQueue($state(socketinfo)) {} - set varName ::http::socketWrState($state(socketinfo)) - trace add variable $varName unset ::http::CancelWritePipeline - } + set socketRdQueue($state(socketinfo)) {} + set socketWrQueue($state(socketinfo)) {} + set socketClosing($state(socketinfo)) 0 + set socketPlayCmd($state(socketinfo)) {ReplayIfClose Wready {} {}} } if {![info exists phost]} { @@ -1447,6 +1486,8 @@ proc http::Connected {token proto phost srvurl} { } err]} { # The socket probably was never connected, or the connection dropped # later. + Log "WARNING - if testing, pay special attention to this\ + case (GI) which is seldom executed - token $token" if {[info exists state(reusing)] && $state(reusing)} { # The socket was closed at the server end, and closed at # this end by http::CheckEof. @@ -1477,6 +1518,9 @@ proc http::Connected {token proto phost srvurl} { # # Command called when a request has been sent. It will arrange the # next request and/or response as appropriate. +# +# If this command is called when $socketClosing(*), the request $token +# that calls it must be pipelined and destined to fail. proc http::DoneRequest {token} { variable http @@ -1533,6 +1577,11 @@ proc http::DoneRequest {token} { } { # Do not read from the socket until it is ready. ##Log "HTTP response for token $token is queued for pipelined use" + # If $socketClosing(*), then the caller will be a pipelined write and + # execution will come here. + # This token has already been recorded as "in flight" for writing. + # When the socket is closed, the read queue will be cleared in + # CloseQueuedQueries and so the "lappend" here has no effect. lappend socketRdQueue($state(socketinfo)) $token } else { # In the pipelined case, connection for reading depends on the @@ -1575,12 +1624,18 @@ proc http::NextPipelinedWrite {token} { variable socketRdState variable socketWrState variable socketWrQueue - + variable socketClosing variable $token upvar 0 $token state set connId $state(socketinfo) - if { $state(-pipeline) + if { [info exists socketClosing($connId)] + && $socketClosing($connId) + } { + # socketClosing(*) is set because the server has sent a + # "Connection: close" header. + # Behave as if the queues are empty - so do nothing. + } elseif { $state(-pipeline) && [info exists socketWrState($connId)] && ($socketWrState($connId) eq "Wready") @@ -1663,11 +1718,13 @@ proc http::NextPipelinedWrite {token} { # # Cancel pipelined responses on a closing "Keep-Alive" socket. # -# - Called by a trace when the variable ::http::socketRdState($connId) is -# unset (the trace itself is automatically removed). +# - Called by a variable trace on "unset socketRdState($connId)". # - The variable relates to a Keep-Alive socket, which has been closed. # - Cancels all pipelined responses. The requests have been sent, # the responses have not yet been received. +# - This is a hard cancel that ends each transaction with error status, +# and closes the connection. Do not use it if you want to replay failed +# transactions. # - N.B. Always delete ::http::socketRdState($connId) before deleting # ::http::socketRdQueue($connId), or this command will do nothing. # @@ -1676,10 +1733,9 @@ proc http::NextPipelinedWrite {token} { proc http::CancelReadPipeline {name1 connId op} { variable socketRdQueue - ##Log CancelReadPipeline $name1 $connId $op if {[info exists socketRdQueue($connId)]} { - set msg {the connection was Closed} + set msg {the connection was closed by CancelReadPipeline} foreach token $socketRdQueue($connId) { set tk [namespace tail $token] Log ^X$tk end of response "($msg)" - token $token @@ -1695,12 +1751,13 @@ proc http::CancelReadPipeline {name1 connId op} { # # Cancel queued events on a closing "Keep-Alive" socket. # -# - Called by a trace when the variable ::http::socketWrState($connId) is -# unset (the trace itself is automatically removed). +# - Called by a variable trace on "unset socketWrState($connId)". # - The variable relates to a Keep-Alive socket, which has been closed. # - In pipelined or nonpipeline case: cancels all queued requests. The -# requests have not yet been sent, the responses are not due and have -# no data to cancel. +# requests have not yet been sent, the responses are not due. +# - This is a hard cancel that ends each transaction with error status, +# and closes the connection. Do not use it if you want to replay failed +# transactions. # - N.B. Always delete ::http::socketWrState($connId) before deleting # ::http::socketWrQueue($connId), or this command will do nothing. # @@ -1712,7 +1769,7 @@ proc http::CancelWritePipeline {name1 connId op} { ##Log CancelWritePipeline $name1 $connId $op if {[info exists socketWrQueue($connId)]} { - set msg {the connection was Closed} + set msg {the connection was closed by CancelWritePipeline} foreach token $socketWrQueue($connId) { set tk [namespace tail $token] Log ^X$tk end of response "($msg)" - token $token @@ -1844,30 +1901,20 @@ proc http::ReplayIfDead {tokenArg doing} { # 2. Tidy up tokenArg. This is a cut-down form of Finish/CloseSocket. - # CloseSocket cancels file events, closes the socket, and unsets the - # socketMapping. - # Finish calls CloseSocket, if called as below. - # Don't want Eot. # Do not change state(status). - # Want to not unset socketWrState(*). + # No need to after cancel stateArg(after) - either this is done in + # ReplayCore/ReInit, or Finish is called. - if {[info exists stateArg(after)]} { - after cancel $stateArg(after) - } catch {close $stateArg(sock)} - # The relevant element of socketMapping, socketRdState, socketWrState, - # socketRdQueue, socketWrQueue, socketClosing, socketPlayCmd will be set to - # new values in ReplayCore. - # The trace on "unset socketRdState(*)" cancels any pipelined responses. - # It also clears socketRdQueue(*). - # Transactions, if any, that are awaiting responses cannot be completed. - # They are listed for re-sending in newQueue. - # There is no need to unset socketWrState - the write queue transactions - # have not yet been sent, nor the state(-timeout) events. - # All tokens are preserved for re-use by ReplayCore. - - unset socketRdState($stateArg(socketinfo)) + # 2a. Tidy the tokens in the queues - this is done in ReplayCore/ReInit. + # - Transactions, if any, that are awaiting responses cannot be completed. + # They are listed for re-sending in newQueue. + # - All tokens are preserved for re-use by ReplayCore, and their variables + # will be re-initialised by calls to ReInit. + # - The relevant element of socketMapping, socketRdState, socketWrState, + # socketRdQueue, socketWrQueue, socketClosing, socketPlayCmd will be set + # to new values in ReplayCore. ReplayCore $newQueue return @@ -1913,6 +1960,72 @@ proc http::ReplayIfClose {Wstate Rqueue Wqueue} { return } +# http::ReInit -- +# +# Command to restore a token's state to a condition that +# makes it ready to replay a request. +# +# Command http::geturl stores extra state in state(tmp*) so +# we don't need to do the argument processing again. +# +# The caller must: +# - Set state(reusing) and state(sock) to their new values after calling +# this command. +# - Unset state(tmpState), state(tmpOpenCmd) if future calls to ReplayCore +# or ReInit are inappropriate for this token. Typically only one retry +# is allowed. +# The caller may also unset state(tmpConnArgs) if this value (and the +# token) will be used immediately. The value is needed by tokens that +# will be stored in a queue. +# +# Arguments: +# token Connection token. +# +# Return Value: (boolean) true iff the re-initialisation was successful. + +proc http::ReInit {token} { + variable $token + upvar 0 $token state + + if {!( + [info exists state(tmpState)] + && [info exists state(tmpOpenCmd)] + && [info exists state(tmpConnArgs)] + ) + } { + Log FAILED in http::ReInit via ReplayCore - NO tmp vars for $token + return 0 + } + + if {[info exists state(after)]} { + after cancel $state(after) + unset state(after) + } + + # Don't alter state(status) - this would trigger http::wait if it is in use. + set tmpState $state(tmpState) + set tmpOpenCmd $state(tmpOpenCmd) + set tmpConnArgs $state(tmpConnArgs) + foreach name [array names state] { + if {$name ne "status"} { + unset state($name) + } + } + + # Don't alter state(status). + # Restore state(tmp*) - the caller may decide to unset them. + # Restore state(tmpConnArgs) which is needed for connection. + # state(tmpState), state(tmpOpenCmd) are needed only for retries. + + dict unset tmpState status + array set state $tmpState + set state(tmpState) $tmpState + set state(tmpOpenCmd) $tmpOpenCmd + set state(tmpConnArgs) $tmpConnArgs + + return 1 +} + # http::ReplayCore -- # # Command to replay a list of requests, using existing connection tokens. @@ -1951,30 +2064,19 @@ proc http::ReplayCore {newQueue} { variable $token upvar 0 $token state - if {!( - [info exists state(tmpState)] - && [info exists state(tmpOpenCmd)] - && [info exists state(tmpConnArgs)] - ) - } { + if {![ReInit $token]} { Log FAILED in http::ReplayCore - NO tmp vars - Finish $token error 1 + Finish $token {cannot send this request again} return } - # Don't alter state(status) - this would trigger http::wait if it is in use. set tmpState $state(tmpState) set tmpOpenCmd $state(tmpOpenCmd) set tmpConnArgs $state(tmpConnArgs) - foreach name [array names state] { - if {$name ne "status"} { - unset state($name) - } - } + unset state(tmpState) + unset state(tmpOpenCmd) + unset state(tmpConnArgs) - # Don't alter state(status). - dict unset tmpState status - array set state $tmpState set state(reusing) 0 if {$state(-timeout) > 0} { @@ -1985,15 +2087,28 @@ proc http::ReplayCore {newQueue} { # 4. Open a socket. if {[catch {eval $tmpOpenCmd} sock]} { # Something went wrong while trying to establish the connection. - Log FAILED - $tmpOpenCmd - set state(sock) $sock - Finish $token error 1 + Log FAILED - $sock + set state(sock) NONE + Finish $token $sock return } # 5. Configure the persistent socket data. if {$state(-keepalive)} { set socketMapping($state(socketinfo)) $sock + + if {![info exists socketRdState($state(socketinfo))]} { + set socketRdState($state(socketinfo)) {} + set varName ::http::socketRdState($state(socketinfo)) + trace add variable $varName unset ::http::CancelReadPipeline + } + + if {![info exists socketWrState($state(socketinfo))]} { + set socketWrState($state(socketinfo)) {} + set varName ::http::socketWrState($state(socketinfo)) + trace add variable $varName unset ::http::CancelWritePipeline + } + if {$state(-pipeline)} { #Log new, init for pipelined, GRANT write acc to $token ReplayCore set socketRdState($state(socketinfo)) $token @@ -2004,26 +2119,22 @@ proc http::ReplayCore {newQueue} { set socketWrState($state(socketinfo)) $token } - if {![info exists socketRdQueue($state(socketinfo))]} { - set socketRdQueue($state(socketinfo)) {} - set varName ::http::socketRdState($state(socketinfo)) - trace add variable $varName unset ::http::CancelReadPipeline - } set socketRdQueue($state(socketinfo)) {} - - if {![info exists socketWrQueue($state(socketinfo))]} { - set socketWrQueue($state(socketinfo)) {} - set varName ::http::socketWrState($state(socketinfo)) - trace add variable $varName unset ::http::CancelWritePipeline - } set socketWrQueue($state(socketinfo)) $newQueue set socketClosing($state(socketinfo)) 0 - set socketPlayCmd($state(socketinfo)) {} + set socketPlayCmd($state(socketinfo)) {ReplayIfClose Wready {} {}} } # 6. Configure sockets in the queue. foreach tok $newQueue { - set ${tok}(sock) $sock + if {[ReInit $tok]} { + set ${tok}(reusing) 1 + set ${tok}(sock) $sock + } else { + set ${tok}(reusing) 1 + set ${tok}(sock) NONE + Finish $token {cannot send this request again} + } } # 7. Configure the socket for newToken to send a request. @@ -2131,6 +2242,8 @@ proc http::Connect {token proto phost srvurl} { [eof $state(sock)] || [set err [fconfigure $state(sock) -error]] ne "" } { + Log "WARNING - if testing, pay special attention to this\ + case (GJ) which is seldom executed - token $token" if {[info exists state(reusing)] && $state(reusing)} { # The socket was closed at the server end, and closed at # this end by http::CheckEof. @@ -2309,6 +2422,8 @@ proc http::Event {sock token} { } if {[catch {gets $sock state(http)} nsl]} { + Log "WARNING - if testing, pay special attention to this\ + case (GK) which is seldom executed - token $token" if {[info exists state(reusing)] && $state(reusing)} { # The socket was closed at the server end, and closed at # this end by http::CheckEof. @@ -2418,27 +2533,18 @@ proc http::Event {sock token} { $socketRdQueue($state(socketinfo)) \ $socketWrQueue($state(socketinfo))] - # See discussion below. + # - All tokens are preserved for re-use by ReplayCore. + # - Queues are preserved in case of Finish with error, but + # are not used for anything else because socketClosing(*) + # is set below. + # - Cancel the state(after) timeout events. foreach tokenElement $socketRdQueue($state(socketinfo)) { if {[info exists ${tokenElement}(after)]} { after cancel [set ${tokenElement}(after)] + unset ${tokenElement}(after) } } - # - Clear the queues. By doing this here, the code for - # connecting the next token to the socket needs no - # modification. - # - Do not unset socketRdState and socketWrState and trigger - # their traces, because this will close the socket, which - # is still needed for the current read. - # - The only other thing that the traces would have done is - # cancel the state(after) timeout events. This is now - # done above. - # - All tokens are preserved for re-use by ReplayCore. - - set socketRdQueue($state(socketinfo)) {} - set socketWrQueue($state(socketinfo)) {} - } else { set socketPlayCmd($state(socketinfo)) \ {ReplayIfClose Wready {} {}} diff --git a/tests/httpPipeline.test b/tests/httpPipeline.test index 33462c05..cab36b2 100644 --- a/tests/httpPipeline.test +++ b/tests/httpPipeline.test @@ -807,7 +807,8 @@ for {set header 1} {$header <= 4} {incr header} { # Here's the test: - test http11-${header}.${footer}${label}-${tag} $name -constraints $cons \ + test httpPipeline-${header}.${footer}${label}-${tag} $name \ + -constraints $cons \ -setup [string map [list TE $te] { # Restore default values for tests: http::config -pipeline 1 -postfresh 0 -repost 1 -- cgit v0.12 From 441e4f6796e1e3cecba7872500d68d0ebbf3a943 Mon Sep 17 00:00:00 2001 From: kjnash Date: Fri, 30 Mar 2018 10:13:57 +0000 Subject: For thorough testing, set test file to verbose, and uncomment Log calls in http.tcl. --- library/http/http.tcl | 108 ++++++++++++++++++++++++------------------------ tests/httpPipeline.test | 2 +- 2 files changed, 55 insertions(+), 55 deletions(-) diff --git a/library/http/http.tcl b/library/http/http.tcl index a268e87..ac51370 100644 --- a/library/http/http.tcl +++ b/library/http/http.tcl @@ -355,7 +355,7 @@ proc http::KeepSocket {token} { upvar 0 $token3 state3 set tk2 [namespace tail $token3] - #Log pipelined, GRANT read access to $token3 in KeepSocket + Log #Log pipelined, GRANT read access to $token3 in KeepSocket set socketRdState($connId) $token3 lassign [fconfigure $state3(sock) -translation] trRead trWrite fconfigure $state3(sock) -translation [list auto $trWrite] \ @@ -363,7 +363,7 @@ proc http::KeepSocket {token} { Log ^D$tk2 begin receiving response - token $token3 fileevent $state3(sock) readable \ [list http::Event $state3(sock) $token3] - #Log ---- $state3(sock) >> conn to $token3 for HTTP response (a) + Log #Log ---- $state3(sock) >> conn to $token3 for HTTP response (a) # Other pipelined cases. # - The test above ensures that, for the pipelined cases in the two @@ -400,13 +400,13 @@ proc http::KeepSocket {token} { # give that request read and write access. variable $token3 set conn [set ${token3}(tmpConnArgs)] - #Log nonpipeline, GRANT r/w access to $token3 in KeepSocket + Log #Log nonpipeline, GRANT r/w access to $token3 in KeepSocket set socketRdState($connId) $token3 set socketWrState($connId) $token3 set socketWrQueue($connId) [lrange $socketWrQueue($connId) 1 end] # Connect does its own fconfigure. fileevent $state(sock) writable [list http::Connect $token3 {*}$conn] - #Log ---- $state(sock) << conn to $token3 for HTTP request (c) + Log #Log ---- $state(sock) << conn to $token3 for HTTP request (c) } elseif { $state(-pipeline) @@ -445,13 +445,13 @@ proc http::KeepSocket {token} { # case with a queued request. variable $token3 set conn [set ${token3}(tmpConnArgs)] - #Log nonpipeline, GRANT r/w access to $token3 in KeepSocket + Log #Log nonpipeline, GRANT r/w access to $token3 in KeepSocket set socketRdState($connId) $token3 set socketWrState($connId) $token3 set socketWrQueue($connId) [lrange $socketWrQueue($connId) 1 end] # Connect does its own fconfigure. fileevent $state(sock) writable [list http::Connect $token3 {*}$conn] - #Log ---- $state(sock) << conn to $token3 for HTTP request (c) + Log #Log ---- $state(sock) << conn to $token3 for HTTP request (c) } elseif { (!$state(-pipeline)) @@ -467,13 +467,13 @@ proc http::KeepSocket {token} { set token3 [lindex $socketWrQueue($connId) 0] variable $token3 set conn [set ${token3}(tmpConnArgs)] - #Log nonpipeline, GRANT r/w access to $token3 in KeepSocket + Log #Log nonpipeline, GRANT r/w access to $token3 in KeepSocket set socketRdState($connId) $token3 set socketWrState($connId) $token3 set socketWrQueue($connId) [lrange $socketWrQueue($connId) 1 end] # Connect does its own fconfigure. fileevent $state(sock) writable [list http::Connect $token3 {*}$conn] - #Log ---- $state(sock) << conn to $token3 for HTTP request (d) + Log #Log ---- $state(sock) << conn to $token3 for HTTP request (d) } elseif {(!$state(-pipeline))} { set socketWrState($connId) Wready @@ -713,7 +713,7 @@ proc http::geturl {url args} { set http(uid) 0 } set token [namespace current]::[incr http(uid)] - ##Log Starting http::geturl - token $token + Log ##Log Starting http::geturl - token $token variable $token upvar 0 $token state set tk [namespace tail $token] @@ -1139,7 +1139,7 @@ proc http::geturl {url args} { } if {$state(-pipeline)} { - #Log new, init for pipelined, GRANT write access to $token in geturl + Log #Log new, init for pipelined, GRANT write access to $token in geturl # Also grant premature read access to the socket. This is OK. set socketRdState($state(socketinfo)) $token set socketWrState($state(socketinfo)) $token @@ -1148,7 +1148,7 @@ proc http::geturl {url args} { # We cannot leave it as "Wready" because the next call to # http::geturl with a pipelined transaction would conclude that the # socket is available for writing. - #Log new, init for nonpipeline, GRANT r/w access to $token in geturl + Log #Log new, init for nonpipeline, GRANT r/w access to $token in geturl set socketRdState($state(socketinfo)) $token set socketWrState($state(socketinfo)) $token } @@ -1193,13 +1193,13 @@ proc http::geturl {url args} { # subsequent calls on this socket will come here because the socket # will close after the current read, and its # socketClosing($connId) is 1. - ##Log "HTTP request for token $token is queued" + Log ##Log "HTTP request for token $token is queued" } elseif { $reusing && $state(-pipeline) && ($socketWrState($state(socketinfo)) ne "Wready") } { - ##Log "HTTP request for token $token is queued for pipelined use" + Log ##Log "HTTP request for token $token is queued for pipelined use" lappend socketWrQueue($state(socketinfo)) $token } elseif { $reusing @@ -1207,7 +1207,7 @@ proc http::geturl {url args} { && ($socketWrState($state(socketinfo)) ne "Wready") } { # A write is queued or in progress. Lappend to the write queue. - ##Log "HTTP request for token $token is queued for nonpipeline use" + Log ##Log "HTTP request for token $token is queued for nonpipeline use" lappend socketWrQueue($state(socketinfo)) $token } elseif { $reusing @@ -1218,20 +1218,20 @@ proc http::geturl {url args} { # A read is queued or in progress, but not a write. Cannot start the # nonpipeline transaction, but must set socketWrState to prevent a # pipelined request jumping the queue. - ##Log "HTTP request for token $token is queued for nonpipeline use" - #Log re-use nonpipeline, GRANT delayed write access to $token in geturl + Log ##Log "HTTP request for token $token is queued for nonpipeline use" + Log #Log re-use nonpipeline, GRANT delayed write access to $token in geturl set socketWrState($state(socketinfo)) peNding lappend socketWrQueue($state(socketinfo)) $token } else { if {$reusing && $state(-pipeline)} { - #Log re-use pipelined, GRANT write access to $token in geturl + Log #Log re-use pipelined, GRANT write access to $token in geturl set socketWrState($state(socketinfo)) $token } elseif {$reusing} { # Cf tests above - both are ready. - #Log re-use nonpipeline, GRANT r/w access to $token in geturl + Log #Log re-use nonpipeline, GRANT r/w access to $token in geturl set socketRdState($state(socketinfo)) $token set socketWrState($state(socketinfo)) $token @@ -1241,7 +1241,7 @@ proc http::geturl {url args} { # All (!$reusing) cases come here, and also some $reusing cases if the # connection is ready. - #Log ---- $state(socketinfo) << conn to $token for HTTP request (a) + Log #Log ---- $state(socketinfo) << conn to $token for HTTP request (a) # Connect does its own fconfigure. fileevent $sock writable \ [list http::Connect $token $proto $phost $srvurl] @@ -1268,7 +1268,7 @@ proc http::geturl {url args} { return -code error $err } } - ##Log Leaving http::geturl - token $token + Log ##Log Leaving http::geturl - token $token return $token } @@ -1566,7 +1566,7 @@ proc http::DoneRequest {token} { && [info exists socketRdState($state(socketinfo))] && ($socketRdState($state(socketinfo)) eq "Rready") } { - #Log pipelined, GRANT read access to $token in Connected + Log #Log pipelined, GRANT read access to $token in Connected set socketRdState($state(socketinfo)) $token } @@ -1576,7 +1576,7 @@ proc http::DoneRequest {token} { && ($socketRdState($state(socketinfo)) ne $token) } { # Do not read from the socket until it is ready. - ##Log "HTTP response for token $token is queued for pipelined use" + Log ##Log "HTTP response for token $token is queued for pipelined use" # If $socketClosing(*), then the caller will be a pipelined write and # execution will come here. # This token has already been recorded as "in flight" for writing. @@ -1587,7 +1587,7 @@ proc http::DoneRequest {token} { # In the pipelined case, connection for reading depends on the # value of socketRdState. # In the nonpipeline case, connection for reading always occurs. - #Log ---- $state(socketinfo) >> conn to $token for HTTP response (b) + Log #Log ---- $state(socketinfo) >> conn to $token for HTTP response (b) lassign [fconfigure $sock -translation] trRead trWrite fconfigure $sock -translation [list auto $trWrite] \ -buffersize $state(-blocksize) @@ -1647,13 +1647,13 @@ proc http::NextPipelinedWrite {token} { ) } { # - The usual case for a pipelined connection, ready for a new request. - #Log pipelined, GRANT write access to $token2 in NextPipelinedWrite + Log #Log pipelined, GRANT write access to $token2 in NextPipelinedWrite set conn [set ${token2}(tmpConnArgs)] set socketWrState($connId) $token2 set socketWrQueue($connId) [lrange $socketWrQueue($connId) 1 end] # Connect does its own fconfigure. fileevent $state(sock) writable [list http::Connect $token2 {*}$conn] - #Log ---- $connId << conn to $token2 for HTTP request (b) + Log #Log ---- $connId << conn to $token2 for HTTP request (b) # In the tests below, the next request will be nonpipeline. } elseif { $state(-pipeline) @@ -1676,13 +1676,13 @@ proc http::NextPipelinedWrite {token} { variable $token3 upvar 0 $token3 state3 set conn [set ${token3}(tmpConnArgs)] - #Log nonpipeline, GRANT r/w access to $token3 in NextPipelinedWrite + Log #Log nonpipeline, GRANT r/w access to $token3 in NextPipelinedWrite set socketRdState($connId) $token3 set socketWrState($connId) $token3 set socketWrQueue($connId) [lrange $socketWrQueue($connId) 1 end] # Connect does its own fconfigure. fileevent $state(sock) writable [list http::Connect $token3 {*}$conn] - #Log ---- $state(sock) << conn to $token3 for HTTP request (c) + Log #Log ---- $state(sock) << conn to $token3 for HTTP request (c) } elseif { $state(-pipeline) && [info exists socketWrState($connId)] @@ -1704,7 +1704,7 @@ proc http::NextPipelinedWrite {token} { # of the connection to $token2 will be done elsewhere - by command # http::KeepSocket when $socketRdState($connId) is set to "Rready". - #Log re-use nonpipeline, GRANT delayed write access to $token in NextP.. + Log #Log re-use nonpipeline, GRANT delayed write access to $token in NextP.. set socketWrState($connId) peNding } else { @@ -1733,7 +1733,7 @@ proc http::NextPipelinedWrite {token} { proc http::CancelReadPipeline {name1 connId op} { variable socketRdQueue - ##Log CancelReadPipeline $name1 $connId $op + Log ##Log CancelReadPipeline $name1 $connId $op if {[info exists socketRdQueue($connId)]} { set msg {the connection was closed by CancelReadPipeline} foreach token $socketRdQueue($connId) { @@ -1767,7 +1767,7 @@ proc http::CancelReadPipeline {name1 connId op} { proc http::CancelWritePipeline {name1 connId op} { variable socketWrQueue - ##Log CancelWritePipeline $name1 $connId $op + Log ##Log CancelWritePipeline $name1 $connId $op if {[info exists socketWrQueue($connId)]} { set msg {the connection was closed by CancelWritePipeline} foreach token $socketWrQueue($connId) { @@ -2053,7 +2053,7 @@ proc http::ReplayCore {newQueue} { return } - ##Log running ReplayCore for {*}$newQueue + Log ##Log running ReplayCore for {*}$newQueue set newToken [lindex $newQueue 0] set newQueue [lrange $newQueue 1 end] @@ -2110,11 +2110,11 @@ proc http::ReplayCore {newQueue} { } if {$state(-pipeline)} { - #Log new, init for pipelined, GRANT write acc to $token ReplayCore + Log #Log new, init for pipelined, GRANT write acc to $token ReplayCore set socketRdState($state(socketinfo)) $token set socketWrState($state(socketinfo)) $token } else { - #Log new, init for nonpipeline, GRANT r/w acc to $token ReplayCore + Log #Log new, init for nonpipeline, GRANT r/w acc to $token ReplayCore set socketRdState($state(socketinfo)) $token set socketWrState($state(socketinfo)) $token } @@ -2147,7 +2147,7 @@ proc http::ReplayCore {newQueue} { # Connect does its own fconfigure. fileevent $sock writable [list http::Connect $token {*}$tmpConnArgs] - #Log ---- $sock << conn to $token for HTTP request (e) + Log #Log ---- $sock << conn to $token for HTTP request (e) return } @@ -2396,7 +2396,7 @@ proc http::Event {sock token} { upvar 0 $token state set tk [namespace tail $token] - ##Log Event call - token $token + Log ##Log Event call - token $token if {![info exists state]} { Log "Event $sock with invalid token '$token' - remote close?" @@ -2411,7 +2411,7 @@ proc http::Event {sock token} { return } if {$state(state) eq "connecting"} { - ##Log - connecting - token $token + Log ##Log - connecting - token $token if { $state(reusing) && $state(-pipeline) && ($state(-timeout) > 0) @@ -2443,7 +2443,7 @@ proc http::Event {sock token} { return } } elseif {$nsl >= 0} { - ##Log - connecting 1 - token $token + Log ##Log - connecting 1 - token $token set state(state) "header" } elseif { [eof $sock] && [info exists state(reusing)] @@ -2463,18 +2463,18 @@ proc http::Event {sock token} { # If any other requests are in flight or pipelined/queued, they will # be discarded. } else { - ##Log - connecting 2 - token $token + Log ##Log - connecting 2 - token $token # nsl is -1 so either fblocked (OK) or (eof and not reusing). # Continue. Any eof is processed at the end of this proc. } } elseif {$state(state) eq "header"} { if {[catch {gets $sock line} nhl]} { - ##Log header failed - token $token + Log ##Log header failed - token $token Log ^X$tk end of response (error) - token $token Finish $token $nhl return } elseif {$nhl == 0} { - ##Log header done - token $token + Log ##Log header done - token $token Log ^E$tk end of response headers - token $token # We have now read all headers # We ignore HTTP/1.1 100 Continue returns. RFC2616 sec 8.2.3 @@ -2513,7 +2513,7 @@ proc http::Event {sock token} { } { # The server warns that it will close the socket after this # response. - ##Log WARNING - socket will close after response for $token + Log ##Log WARNING - socket will close after response for $token # Prepare data for a call to ReplayIfClose. if { ($socketRdQueue($state(socketinfo)) ne {}) || ($socketWrQueue($state(socketinfo)) ne {}) @@ -2525,7 +2525,7 @@ proc http::Event {sock token} { set InFlightW Wready } else { set msg "token ${InFlightW} is InFlightW" - ##Log $msg - token $token + Log ##Log $msg - token $token } set socketPlayCmd($state(socketinfo)) \ @@ -2617,7 +2617,7 @@ proc http::Event {sock token} { } } elseif {$nhl > 0} { # Process header lines. - ##Log header - token $token - $line + Log ##Log header - token $token - $line if {[regexp -nocase {^([^:]+):(.+)$} $line x key value]} { switch -- [string tolower $key] { content-type { @@ -2653,11 +2653,11 @@ proc http::Event {sock token} { } } else { # Now reading body - ##Log body - token $token + Log ##Log body - token $token if {[catch { if {[info exists state(-handler)]} { set n [eval $state(-handler) [list $sock $token]] - ##Log handler $n - token $token + Log ##Log handler $n - token $token # N.B. the protocol has been set to 1.0 because the -handler # logic is not expected to handle chunked encoding. # FIXME allow -handler with 1.1 on dechunked stacked channel. @@ -2710,14 +2710,14 @@ proc http::Event {sock token} { } elseif { [info exists state(transfer)] && ($state(transfer) eq "chunked") } { - ##Log chunked - token $token + Log ##Log chunked - token $token set size 0 set hexLenChunk [getTextLine $sock] #set ntl [string length $hexLenChunk] if {[string trim $hexLenChunk] ne ""} { scan $hexLenChunk %x size if {$size != 0} { - ##Log chunk-measure $size - token $token + Log ##Log chunk-measure $size - token $token set bl [fconfigure $sock -blocking] fconfigure $sock -blocking 1 set chunk [read $sock $size] @@ -2726,7 +2726,7 @@ proc http::Event {sock token} { if {$n >= 0} { append state(body) $chunk incr state(log_size) [string length $chunk] - ##Log chunk $n cumul $state(log_size) - token $token + Log ##Log chunk $n cumul $state(log_size) - token $token } if {$size != [string length $chunk]} { Log "WARNING: mis-sized chunk:\ @@ -2748,14 +2748,14 @@ proc http::Event {sock token} { } } else { # Line expected to hold chunk length is empty. - ##Log bad-chunk-measure - token $token + Log ##Log bad-chunk-measure - token $token set n 0 set state(connection) close Log ^X$tk end of response (chunk error) - token $token Eot $token {error in chunked encoding - fetch terminated} } } else { - ##Log unchunked - token $token + Log ##Log unchunked - token $token if {$state(totalsize) == 0} { # We know the transfer is complete only when the server # closes the connection. @@ -2775,12 +2775,12 @@ proc http::Event {sock token} { } set c $state(currentsize) set t $state(totalsize) - ##Log non-chunk currentsize $c of totalsize $t - token $token + Log ##Log non-chunk currentsize $c of totalsize $t - token $token set block [read $sock $reqSize] set n [string length $block] if {$n >= 0} { append state(body) $block - ##Log non-chunk [string length $state(body)] - token $token + Log ##Log non-chunk [string length $state(body)] - token $token } } # This calculation uses n from the -handler, chunked, or unchunked @@ -2790,7 +2790,7 @@ proc http::Event {sock token} { incr state(currentsize) $n set c $state(currentsize) set t $state(totalsize) - ##Log chunk $n currentsize $c totalsize $t - token $token + Log ##Log chunk $n currentsize $c totalsize $t - token $token } # If Content-Length - check for end of data. if { @@ -2817,7 +2817,7 @@ proc http::Event {sock token} { # catch as an Eot above may have closed the socket already # $state(state) may be connecting, header, body, or complete if {![catch {eof $sock} eof] && $eof} { - ##Log eof - token $token + Log ##Log eof - token $token if {[info exists $token]} { set state(connection) close if {$state(state) eq "complete"} { diff --git a/tests/httpPipeline.test b/tests/httpPipeline.test index cab36b2..08eb076 100644 --- a/tests/httpPipeline.test +++ b/tests/httpPipeline.test @@ -641,7 +641,7 @@ proc RunTest {header footer delay te} { # If still obscure, uncomment #Log and ##Log lines in the http package. # ------------------------------------------------------------------------------ -set ::httpTest::testOptions(-verbose) 0 +set ::httpTest::testOptions(-verbose) 2 # ------------------------------------------------------------------------------ -- cgit v0.12 From 466fd1d9304f60660938226a59e6ed8156a0d02e Mon Sep 17 00:00:00 2001 From: kjnash Date: Sat, 31 Mar 2018 15:27:52 +0000 Subject: Chasing timeout bug: reduce client timeout to 4s in tests; more sanity checking in non-keep-alive tests; tidying; more logging in http.tcl. --- library/http/http.tcl | 29 ++++++++++++++++-- tests/httpPipeline.test | 26 ++++++++++------- tests/httpTest.tcl | 76 +++++++++++++++++++++++++++++++++++++++++++++++- tests/httpTestScript.tcl | 2 +- 4 files changed, 119 insertions(+), 14 deletions(-) diff --git a/library/http/http.tcl b/library/http/http.tcl index ac51370..49898db 100644 --- a/library/http/http.tcl +++ b/library/http/http.tcl @@ -1086,7 +1086,7 @@ proc http::geturl {url args} { # - DoneRequest - if reusing and pipelined, send the next pipelined write # - Event - if reusing and pipelined, start the state(-timeout) # timeout (when reading). - # - Event - if not reusing and pipelined, send the next pipelined + # - Event - if (not reusing) and pipelined, send the next pipelined # write # See comments above re the start of this timeout in other cases. @@ -1100,6 +1100,9 @@ proc http::geturl {url args} { if {[info exists state(-myaddr)]} { lappend sockopts -myaddr $state(-myaddr) } + set pre [clock milliseconds] + Log ##Log pre socket opened, - token $token + Log ##Log [concat $defcmd $sockopts $targetAddr] - token $token if {[catch {eval $defcmd $sockopts $targetAddr} sock]} { # Something went wrong while trying to establish the connection. # Clean up after events and such, but DON'T call the command @@ -1112,10 +1115,19 @@ proc http::geturl {url args} { return -code error $sock } else { # Initialisation of a new socket. + Log ##Log post socket opened, - token $token + Log ##Log socket opened, now fconfigure - token $token + set delay [expr {[clock milliseconds] - $pre}] + if {$delay > 3000} { + Log ##Log socket delay $delay - token $token + } fconfigure $sock -translation {auto crlf} \ -buffersize $state(-blocksize) + Log ##Log socket opened, DONE fconfigure - token $token } } + # Command [socket] is called with -async, but occasionally takes seconds to return. + # It returns after 5s, and the request times out when this command returns. set state(sock) $sock Log "Using $sock for $state(socketinfo) - token $token" \ @@ -2084,6 +2096,9 @@ proc http::ReplayCore {newQueue} { set state(after) [after $state(-timeout) $resetCmd] } + set pre [clock milliseconds] + Log ##Log pre socket opened, - token $token + Log ##Log $tmpOpenCmd - token $token # 4. Open a socket. if {[catch {eval $tmpOpenCmd} sock]} { # Something went wrong while trying to establish the connection. @@ -2092,6 +2107,13 @@ proc http::ReplayCore {newQueue} { Finish $token $sock return } + Log ##Log post socket opened, - token $token + set delay [expr {[clock milliseconds] - $pre}] + if {$delay > 3000} { + Log ##Log socket delay $delay - token $token + } + # Command [socket] is called with -async, but occasionally takes seconds to return. + # It returns after 5s, and the request times out when this command returns. # 5. Configure the persistent socket data. if {$state(-keepalive)} { @@ -2125,6 +2147,7 @@ proc http::ReplayCore {newQueue} { set socketPlayCmd($state(socketinfo)) {ReplayIfClose Wready {} {}} } + Log ##Log pre newQueue ReInit, - token $token # 6. Configure sockets in the queue. foreach tok $newQueue { if {[ReInit $tok]} { @@ -2143,7 +2166,9 @@ proc http::ReplayCore {newQueue} { [expr {$state(-keepalive)?"keepalive":""}] # Initialisation of a new socket. + Log ##Log socket opened, now fconfigure - token $token fconfigure $sock -translation {auto crlf} -buffersize $state(-blocksize) + Log ##Log socket opened, DONE fconfigure - token $token # Connect does its own fconfigure. fileevent $sock writable [list http::Connect $token {*}$tmpConnArgs] @@ -2790,7 +2815,7 @@ proc http::Event {sock token} { incr state(currentsize) $n set c $state(currentsize) set t $state(totalsize) - Log ##Log chunk $n currentsize $c totalsize $t - token $token + Log ##Log another $n currentsize $c totalsize $t - token $token } # If Content-Length - check for end of data. if { diff --git a/tests/httpPipeline.test b/tests/httpPipeline.test index 08eb076..4823d19 100644 --- a/tests/httpPipeline.test +++ b/tests/httpPipeline.test @@ -566,10 +566,14 @@ proc ReturnTestResult {ca cb delay te} { namespace import httpTestScript::runHttpTestScript namespace import httpTestScript::cleanupHttpTestScript +namespace import httpTest::cleanupHttpTest +namespace import httpTest::logAnalyse +namespace import httpTest::setHttpTestOptions proc RunTest {header footer delay te} { set num [runHttpTestScript [ReturnTestScript $header $footer $delay $te]] set skipOverlaps 0 + set notPiped {} set notIncluded {} # -------------------------------------------------------------------------- @@ -578,23 +582,26 @@ proc RunTest {header footer delay te} { if {$header < 3} { set skipOverlaps 1 for {set i 1} {$i <= $num} {incr i} { - lappend notIncluded $i + lappend notPiped $i } } elseif {$header > 2 && $footer == 18 && $te == 1} { set skipOverlaps 1 if {$delay == 0} { # Transaction 1 is conventional. # Check that transactions 2,3,4 are cancelled. - set notIncluded {1} + set notPiped {1} + set notIncluded $notPiped } else { # Transaction 1 is conventional. # Check that transaction 2 is cancelled. # The timing of transactions 3 and 4 is uncertain. - set notIncluded {1 3 4} + set notPiped {1 3 4} + set notIncluded $notPiped } } elseif {$footer in {20 22 23 24 25}} { # Transaction 2 uses its own socket. - set notIncluded 2 + set notPiped 2 + set notIncluded $notPiped } else { } # -------------------------------------------------------------------------- @@ -602,7 +609,7 @@ proc RunTest {header footer delay te} { # -------------------------------------------------------------------------- - set Results [httpTest::LogAnalyse $num $skipOverlaps $notIncluded $notIncluded] + set Results [logAnalyse $num $skipOverlaps $notIncluded $notPiped] lassign $Results msg cleanE cleanF dirtyE dirtyF if {$msg eq {}} { set msg "Passed all sanity checks." @@ -641,8 +648,7 @@ proc RunTest {header footer delay te} { # If still obscure, uncomment #Log and ##Log lines in the http package. # ------------------------------------------------------------------------------ -set ::httpTest::testOptions(-verbose) 2 - +setHttpTestOptions -verbose 2 # ------------------------------------------------------------------------------ # (4) Define the base URLs used for testing. Each must have a query string. @@ -724,10 +730,10 @@ proc SetTestEof {test} { for {set header 1} {$header <= 4} {incr header} { if {$header == 4} { - set ::httpTest::testOptions(-dotted) 1 + setHttpTestOptions -dotted 1 set match glob } else { - set ::httpTest::testOptions(-dotted) 0 + setHttpTestOptions -dotted 0 set match exact } @@ -820,7 +826,7 @@ for {set header 1} {$header <= 4} {incr header} { http::config -pipeline 1 -postfresh 0 -repost 1 cleanupHttpTestScript SetTestEof 0 - set ::httpTest::testResults {} + cleanupHttpTest after 2000 # Wait for persistent sockets on the server to time out. } -result [ReturnTestResult $header $footer $delay $te] -match $match diff --git a/tests/httpTest.tcl b/tests/httpTest.tcl index ad08048..38ba43f 100644 --- a/tests/httpTest.tcl +++ b/tests/httpTest.tcl @@ -25,6 +25,7 @@ package require http namespace eval ::http { variable TestStartTimeInMs [clock milliseconds] + catch {puts stderr "Start time (zero ms) is $TestStartTimeInMs"} } namespace eval ::httpTest { @@ -297,6 +298,32 @@ proc httpTest::TestSequence {someResults n msg badTrans} { return $msg } +# +# Arguments: +# someResults - list of elements, each a list of a letter and a number +# n - (positive integer) the number of HTTP requests +# msg - accumulated warning messages +# skipOverlaps - (boolean) whether to skip testing of transaction overlaps +# badTrans - list of transaction numbers not to be assessed as "clean" or +# "dirty" by their overlaps +# for 1/2 includes all transactions +# for 3/4 includes an increasing (with recursion) set that will not be included in the list because they are already handled. +# notPiped - subset of badTrans. List of transaction numbers that cannot +# taint another transaction by overlapping with it, because it +# used a different socket. +# +# Return value: [list $msg $cleanE $cleanF $dirtyE $dirtyF] +# msg - warning messages: nothing will be appended to argument $msg if there +# is no error with the test. +# cleanE - list of transactions that have no overlap with other transactions +# (not considering response body) +# dirtyE - list of transactions that have YES overlap with other transactions +# (not considering response body) +# cleanF - list of transactions that have no overlap with other transactions +# (including response body) +# dirtyF - list of transactions that have YES overlap with other transactions +# (including response body) + proc httpTest::MostAnalysis {someResults n msg skipOverlaps badTrans notPiped} { variable testOptions @@ -362,6 +389,7 @@ proc httpTest::ProcessRetries {someResults n msg skipOverlaps notIncluded notPip set last [lsearch -exact $beforeTry [list F $i]] if {$first == -1} { set res "Transaction $i was not started in connection number $tryCount" + # So lappend it to badTrans and don't include it in the call below of MostAnalysis. # append msg $res \n Puts $res if {$i ni $badTrans} { @@ -370,12 +398,16 @@ proc httpTest::ProcessRetries {someResults n msg skipOverlaps notIncluded notPip } } elseif {$last == -1} { set res "Transaction $i was started but unfinished in connection number $tryCount" + # So lappend it to badTrans and don't include it in the call below of MostAnalysis. # append msg $res \n Puts $res lappend badTrans $i lappend dummyTry [list A $i] } else { set res "Transaction $i was started and finished in connection number $tryCount" + # So include it in the call below of MostAnalysis. + # So lappend it to notIncluded and don't include it in the recursive call of + # ProcessRetries which handles the later connections. # append msg $res \n Puts $res lappend notIncluded $i @@ -398,7 +430,31 @@ proc httpTest::ProcessRetries {someResults n msg skipOverlaps notIncluded notPip return [list $msg $cleanE $cleanF $dirtyE $dirtyF] } -proc httpTest::LogAnalyse {n skipOverlaps notIncluded notPiped} { +# httpTest::logAnalyse -- +# +# The main command called to analyse logs for a single test. +# +# Arguments: +# n - (positive integer) the number of HTTP requests +# skipOverlaps - (boolean) whether to skip testing of transaction overlaps +# notIncluded - list of transaction numbers not to be assessed as "clean" or +# "dirty" by their overlaps +# notPiped - subset of notIncluded. List of transaction numbers that cannot +# taint another transaction by overlapping with it, because it +# used a different socket. +# +# Return value: [list $msg $cleanE $cleanF $dirtyE $dirtyF] +# msg - warning messages: {} if there is no error with the test. +# cleanE - list of transactions that have no overlap with other transactions +# (not considering response body) +# dirtyE - list of transactions that have YES overlap with other transactions +# (not considering response body) +# cleanF - list of transactions that have no overlap with other transactions +# (including response body) +# dirtyF - list of transactions that have YES overlap with other transactions +# (including response body) + +proc httpTest::logAnalyse {n skipOverlaps notIncluded notPiped} { variable testResults variable testOptions @@ -429,3 +485,21 @@ proc httpTest::LogAnalyse {n skipOverlaps notIncluded notPiped} { ProcessRetries $testResults $n $msg $skipOverlaps $notIncluded $notPiped # N.B. Implicit Return. } + +proc httpTest::cleanupHttpTest {} { + variable testResults + set testResults {} + return +} + +proc httpTest::setHttpTestOptions {key args} { + variable testOptions + if {$key ni {-dotted -verbose}} { + return -code error {valid options are -dotted, -verbose} + } + set testOptions($key) {*}$args +} + +namespace eval httpTest { + namespace export cleanupHttpTest logAnalyse setHttpTestOptions +} diff --git a/tests/httpTestScript.tcl b/tests/httpTestScript.tcl index 048cb4f..68b3474 100644 --- a/tests/httpTestScript.tcl +++ b/tests/httpTestScript.tcl @@ -383,7 +383,7 @@ proc httpTestScript::Requester {uriCode keepAlive validate query args} { if {[catch { ::http::geturl $absUrl \ -validate $validate \ - -timeout 5000 \ + -timeout 4000 \ {*}$queryArgs \ -keepalive $keepAlive \ -command ::httpTestScript::WhenFinished -- cgit v0.12 From 13571723674678c9c380ee2e6f2f5bc44777f58f Mon Sep 17 00:00:00 2001 From: kjnash Date: Sun, 1 Apr 2018 01:09:57 +0000 Subject: Increase test timeout to 10s. Remove commenting from Log calls that report long delay for [socket]. --- library/http/http.tcl | 18 ++++++++++++------ tests/httpTestScript.tcl | 2 +- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/library/http/http.tcl b/library/http/http.tcl index 49898db..83a4665 100644 --- a/library/http/http.tcl +++ b/library/http/http.tcl @@ -1119,15 +1119,18 @@ proc http::geturl {url args} { Log ##Log socket opened, now fconfigure - token $token set delay [expr {[clock milliseconds] - $pre}] if {$delay > 3000} { - Log ##Log socket delay $delay - token $token + Log socket delay $delay - token $token } fconfigure $sock -translation {auto crlf} \ -buffersize $state(-blocksize) Log ##Log socket opened, DONE fconfigure - token $token } } - # Command [socket] is called with -async, but occasionally takes seconds to return. - # It returns after 5s, and the request times out when this command returns. + # Command [socket] is called with -async, but takes 5s to 5.1s to return, + # with probability of order 1 in 10,000. This may be a bizarre scheduling + # issue with my (KJN's) system (Fedora Linux). + # This does not cause a problem (unless the request times out when this + # command returns). set state(sock) $sock Log "Using $sock for $state(socketinfo) - token $token" \ @@ -2110,10 +2113,13 @@ proc http::ReplayCore {newQueue} { Log ##Log post socket opened, - token $token set delay [expr {[clock milliseconds] - $pre}] if {$delay > 3000} { - Log ##Log socket delay $delay - token $token + Log socket delay $delay - token $token } - # Command [socket] is called with -async, but occasionally takes seconds to return. - # It returns after 5s, and the request times out when this command returns. + # Command [socket] is called with -async, but takes 5s to 5.1s to return, + # with probability of order 1 in 10,000. This may be a bizarre scheduling + # issue with my (KJN's) system (Fedora Linux). + # This does not cause a problem (unless the request times out when this + # command returns). # 5. Configure the persistent socket data. if {$state(-keepalive)} { diff --git a/tests/httpTestScript.tcl b/tests/httpTestScript.tcl index 68b3474..4046c7a 100644 --- a/tests/httpTestScript.tcl +++ b/tests/httpTestScript.tcl @@ -383,7 +383,7 @@ proc httpTestScript::Requester {uriCode keepAlive validate query args} { if {[catch { ::http::geturl $absUrl \ -validate $validate \ - -timeout 4000 \ + -timeout 10000 \ {*}$queryArgs \ -keepalive $keepAlive \ -command ::httpTestScript::WhenFinished -- cgit v0.12 From 6a58a0cab24668a9c1feda011147c87f3ba34801 Mon Sep 17 00:00:00 2001 From: kjnash Date: Wed, 4 Apr 2018 12:00:03 +0000 Subject: Use coroutines to remove blocking on HTTP connections --- library/http/http.tcl | 874 +++++++++++++++++++++++++++----------------------- 1 file changed, 466 insertions(+), 408 deletions(-) diff --git a/library/http/http.tcl b/library/http/http.tcl index 83a4665..77a2a43 100644 --- a/library/http/http.tcl +++ b/library/http/http.tcl @@ -255,6 +255,9 @@ proc http::Finish {token {errormsg ""} {skipCB 0}} { set state(error) [list $errormsg $errorInfo $errorCode] set state(status) "error" } + if {[info commands ${token}EventCoroutine] ne {}} { + rename ${token}EventCoroutine {} + } if { ($state(status) eq "timeout") || ($state(status) eq "error") || ($state(status) eq "eof") @@ -357,13 +360,7 @@ proc http::KeepSocket {token} { Log #Log pipelined, GRANT read access to $token3 in KeepSocket set socketRdState($connId) $token3 - lassign [fconfigure $state3(sock) -translation] trRead trWrite - fconfigure $state3(sock) -translation [list auto $trWrite] \ - -buffersize $state3(-blocksize) - Log ^D$tk2 begin receiving response - token $token3 - fileevent $state3(sock) readable \ - [list http::Event $state3(sock) $token3] - Log #Log ---- $state3(sock) >> conn to $token3 for HTTP response (a) + ReceiveResponse $token3 # Other pipelined cases. # - The test above ensures that, for the pipelined cases in the two @@ -1602,16 +1599,32 @@ proc http::DoneRequest {token} { # In the pipelined case, connection for reading depends on the # value of socketRdState. # In the nonpipeline case, connection for reading always occurs. - Log #Log ---- $state(socketinfo) >> conn to $token for HTTP response (b) - lassign [fconfigure $sock -translation] trRead trWrite - fconfigure $sock -translation [list auto $trWrite] \ - -buffersize $state(-blocksize) - Log ^D$tk begin receiving response - token $token - fileevent $sock readable [list http::Event $sock $token] + ReceiveResponse $token } return } +# http::ReceiveResponse +# +# Connects token to its socket for reading. + +proc http::ReceiveResponse {token} { + variable $token + upvar 0 $token state + set tk [namespace tail $token] + set sock $state(sock) + + Log #Log ---- $state(socketinfo) >> conn to $token for HTTP response + lassign [fconfigure $sock -translation] trRead trWrite + fconfigure $sock -translation [list auto $trWrite] \ + -buffersize $state(-blocksize) + Log ^D$tk begin receiving response - token $token + + coroutine ${token}EventCoroutine http::Event $sock $token + fileevent $sock readable ${token}EventCoroutine + return +} + # http::NextPipelinedWrite # # - Connecting a socket to a token for writing is done by this command and by @@ -2247,6 +2260,9 @@ proc http::error {token} { proc http::cleanup {token} { variable $token upvar 0 $token state + if {[info commands ${token}EventCoroutine] ne {}} { + rename ${token}EventCoroutine {} + } if {[info exists state]} { unset state } @@ -2426,447 +2442,452 @@ proc http::Event {sock token} { variable $token upvar 0 $token state set tk [namespace tail $token] + while 1 { + yield + Log ##Log Event call - token $token - Log ##Log Event call - token $token - - if {![info exists state]} { - Log "Event $sock with invalid token '$token' - remote close?" - if {![eof $sock]} { - if {[set d [read $sock]] ne ""} { - Log "WARNING: additional data left on closed socket\ - - token $token" + if {![info exists state]} { + Log "Event $sock with invalid token '$token' - remote close?" + if {![eof $sock]} { + if {[set d [read $sock]] ne ""} { + Log "WARNING: additional data left on closed socket\ + - token $token" + } } + Log ^X$tk end of response (token error) - token $token + CloseSocket $sock + return } - Log ^X$tk end of response (token error) - token $token - CloseSocket $sock - return - } - if {$state(state) eq "connecting"} { - Log ##Log - connecting - token $token - if { $state(reusing) - && $state(-pipeline) - && ($state(-timeout) > 0) - && (![info exists state(after)]) - } { - set state(after) [after $state(-timeout) \ - [list http::reset $token timeout]] - } + if {$state(state) eq "connecting"} { + Log ##Log - connecting - token $token + if { $state(reusing) + && $state(-pipeline) + && ($state(-timeout) > 0) + && (![info exists state(after)]) + } { + set state(after) [after $state(-timeout) \ + [list http::reset $token timeout]] + } + + if {[catch {gets $sock state(http)} nsl]} { + Log "WARNING - if testing, pay special attention to this\ + case (GK) which is seldom executed - token $token" + if {[info exists state(reusing)] && $state(reusing)} { + # The socket was closed at the server end, and closed at + # this end by http::CheckEof. - if {[catch {gets $sock state(http)} nsl]} { - Log "WARNING - if testing, pay special attention to this\ - case (GK) which is seldom executed - token $token" - if {[info exists state(reusing)] && $state(reusing)} { - # The socket was closed at the server end, and closed at - # this end by http::CheckEof. + if {[TestForReplay $token read $nsl c]} { + return + } - if {[TestForReplay $token read $nsl c]} { + # else: + # This is NOT a persistent socket that has been closed since its + # last use. + # If any other requests are in flight or pipelined/queued, they + # will be discarded. + } else { + Log ^X$tk end of response (error) - token $token + Finish $token $nsl + return + } + } elseif {$nsl >= 0} { + Log ##Log - connecting 1 - token $token + set state(state) "header" + } elseif { [eof $sock] + && [info exists state(reusing)] + && $state(reusing) + } { + # The socket was closed at the server end, and we didn't notice. + # This is the first read - where the closure is usually first + # detected. + + if {[TestForReplay $token read {} d]} { return } # else: # This is NOT a persistent socket that has been closed since its # last use. - # If any other requests are in flight or pipelined/queued, they - # will be discarded. + # If any other requests are in flight or pipelined/queued, they will + # be discarded. } else { - Log ^X$tk end of response (error) - token $token - Finish $token $nsl - return + Log ##Log - connecting 2 - token $token + # nsl is -1 so either fblocked (OK) or (eof and not reusing). + # Continue. Any eof is processed at the end of this proc. } - } elseif {$nsl >= 0} { - Log ##Log - connecting 1 - token $token - set state(state) "header" - } elseif { [eof $sock] - && [info exists state(reusing)] - && $state(reusing) - } { - # The socket was closed at the server end, and we didn't notice. - # This is the first read - where the closure is usually first - # detected. - - if {[TestForReplay $token read {} d]} { - return - } - - # else: - # This is NOT a persistent socket that has been closed since its - # last use. - # If any other requests are in flight or pipelined/queued, they will - # be discarded. - } else { - Log ##Log - connecting 2 - token $token - # nsl is -1 so either fblocked (OK) or (eof and not reusing). - # Continue. Any eof is processed at the end of this proc. - } - } elseif {$state(state) eq "header"} { - if {[catch {gets $sock line} nhl]} { - Log ##Log header failed - token $token - Log ^X$tk end of response (error) - token $token - Finish $token $nhl - return - } elseif {$nhl == 0} { - Log ##Log header done - token $token - Log ^E$tk end of response headers - token $token - # We have now read all headers - # We ignore HTTP/1.1 100 Continue returns. RFC2616 sec 8.2.3 - if { ($state(http) == "") - || ([regexp {^\S+\s(\d+)} $state(http) {} x] && $x == 100) - } { - set state(state) "connecting" + } elseif {$state(state) eq "header"} { + if {[catch {gets $sock line} nhl]} { + Log ##Log header failed - token $token + Log ^X$tk end of response (error) - token $token + Finish $token $nhl return - } + } elseif {$nhl == 0} { + Log ##Log header done - token $token + Log ^E$tk end of response headers - token $token + # We have now read all headers + # We ignore HTTP/1.1 100 Continue returns. RFC2616 sec 8.2.3 + if { ($state(http) == "") + || ([regexp {^\S+\s(\d+)} $state(http) {} x] && $x == 100) + } { + set state(state) "connecting" + continue + # This was a "return" in the pre-coroutine code. + } - if { ([info exists state(connection)]) - && ([info exists socketMapping($state(socketinfo))]) - && ($state(connection) eq "keep-alive") - && ($state(-keepalive)) - && (!$state(reusing)) - && ($state(-pipeline)) - } { - # Response headers received for first request on a persistent - # socket. Now ready for pipelined writes (if any). - # Previous value is $token. It cannot be pending. - set socketWrState($state(socketinfo)) Wready - http::NextPipelinedWrite $token - } + if { ([info exists state(connection)]) + && ([info exists socketMapping($state(socketinfo))]) + && ($state(connection) eq "keep-alive") + && ($state(-keepalive)) + && (!$state(reusing)) + && ($state(-pipeline)) + } { + # Response headers received for first request on a persistent + # socket. Now ready for pipelined writes (if any). + # Previous value is $token. It cannot be pending. + set socketWrState($state(socketinfo)) Wready + http::NextPipelinedWrite $token + } - # Once a "close" has been signaled, the client MUST NOT send any - # more requests on that connection. - # - # If either the client or the server sends the "close" token in the - # Connection header, that request becomes the last one for the - # connection. - - if { ([info exists state(connection)]) - && ([info exists socketMapping($state(socketinfo))]) - && ($state(connection) eq "close") - && ($state(-keepalive)) - } { - # The server warns that it will close the socket after this - # response. - Log ##Log WARNING - socket will close after response for $token - # Prepare data for a call to ReplayIfClose. - if { ($socketRdQueue($state(socketinfo)) ne {}) - || ($socketWrQueue($state(socketinfo)) ne {}) - || ($socketWrState($state(socketinfo)) ni - [list Wready peNding $token]) + # Once a "close" has been signaled, the client MUST NOT send any + # more requests on that connection. + # + # If either the client or the server sends the "close" token in the + # Connection header, that request becomes the last one for the + # connection. + + if { ([info exists state(connection)]) + && ([info exists socketMapping($state(socketinfo))]) + && ($state(connection) eq "close") + && ($state(-keepalive)) } { - set InFlightW $socketWrState($state(socketinfo)) - if {$InFlightW in [list Wready peNding $token]} { - set InFlightW Wready - } else { - set msg "token ${InFlightW} is InFlightW" - Log ##Log $msg - token $token - } + # The server warns that it will close the socket after this + # response. + Log ##Log WARNING - socket will close after response for $token + # Prepare data for a call to ReplayIfClose. + if { ($socketRdQueue($state(socketinfo)) ne {}) + || ($socketWrQueue($state(socketinfo)) ne {}) + || ($socketWrState($state(socketinfo)) ni + [list Wready peNding $token]) + } { + set InFlightW $socketWrState($state(socketinfo)) + if {$InFlightW in [list Wready peNding $token]} { + set InFlightW Wready + } else { + set msg "token ${InFlightW} is InFlightW" + Log ##Log $msg - token $token + } - set socketPlayCmd($state(socketinfo)) \ - [list ReplayIfClose $InFlightW \ - $socketRdQueue($state(socketinfo)) \ - $socketWrQueue($state(socketinfo))] - - # - All tokens are preserved for re-use by ReplayCore. - # - Queues are preserved in case of Finish with error, but - # are not used for anything else because socketClosing(*) - # is set below. - # - Cancel the state(after) timeout events. - foreach tokenElement $socketRdQueue($state(socketinfo)) { - if {[info exists ${tokenElement}(after)]} { - after cancel [set ${tokenElement}(after)] - unset ${tokenElement}(after) + set socketPlayCmd($state(socketinfo)) \ + [list ReplayIfClose $InFlightW \ + $socketRdQueue($state(socketinfo)) \ + $socketWrQueue($state(socketinfo))] + + # - All tokens are preserved for re-use by ReplayCore. + # - Queues are preserved in case of Finish with error, but + # are not used for anything else because socketClosing(*) + # is set below. + # - Cancel the state(after) timeout events. + foreach tokenElement $socketRdQueue($state(socketinfo)) { + if {[info exists ${tokenElement}(after)]} { + after cancel [set ${tokenElement}(after)] + unset ${tokenElement}(after) + } } + + } else { + set socketPlayCmd($state(socketinfo)) \ + {ReplayIfClose Wready {} {}} } - } else { - set socketPlayCmd($state(socketinfo)) \ - {ReplayIfClose Wready {} {}} + # Do not allow further connections on this socket. + set socketClosing($state(socketinfo)) 1 } - # Do not allow further connections on this socket. - set socketClosing($state(socketinfo)) 1 - } - - set state(state) body + set state(state) body - # If doing a HEAD, then we won't get any body - if {$state(-validate)} { - Log ^F$tk end of response for HEAD request - token $token - set state(state) complete - Eot $token - return - } + # If doing a HEAD, then we won't get any body + if {$state(-validate)} { + Log ^F$tk end of response for HEAD request - token $token + set state(state) complete + Eot $token + return + } - # - For non-chunked transfer we may have no body - in this case we - # may get no further file event if the connection doesn't close - # and no more data is sent. We can tell and must finish up now - - # not later - the alternative would be to wait until the server - # times out. - # - In this case, the server has NOT told the client it will close - # the connection, AND it has NOT indicated the resource length - # EITHER by setting the Content-Length (totalsize) OR by using - # chunked Transer-Encoding. - # - Do not worry here about the case (Connection: close) because - # the server should close the connection. - # - IF (NOT Connection: close) AND (NOT chunked encoding) AND - # (totalsize == 0). - - if { (!( [info exists state(connection)] - && ($state(connection) eq "close") - ) - ) - && (![info exists state(transfer)]) - && ($state(totalsize) == 0) - } { - set msg {body size is 0 and no events likely - complete} - Log "$msg - token $token" - set msg {(length unknown, set to 0)} - Log ^F$tk end of response body {*}$msg - token $token - set state(state) complete - Eot $token - return - } + # - For non-chunked transfer we may have no body - in this case we + # may get no further file event if the connection doesn't close + # and no more data is sent. We can tell and must finish up now - + # not later - the alternative would be to wait until the server + # times out. + # - In this case, the server has NOT told the client it will close + # the connection, AND it has NOT indicated the resource length + # EITHER by setting the Content-Length (totalsize) OR by using + # chunked Transer-Encoding. + # - Do not worry here about the case (Connection: close) because + # the server should close the connection. + # - IF (NOT Connection: close) AND (NOT chunked encoding) AND + # (totalsize == 0). + + if { (!( [info exists state(connection)] + && ($state(connection) eq "close") + ) + ) + && (![info exists state(transfer)]) + && ($state(totalsize) == 0) + } { + set msg {body size is 0 and no events likely - complete} + Log "$msg - token $token" + set msg {(length unknown, set to 0)} + Log ^F$tk end of response body {*}$msg - token $token + set state(state) complete + Eot $token + return + } - # We have to use binary translation to count bytes properly. - lassign [fconfigure $sock -translation] trRead trWrite - fconfigure $sock -translation [list binary $trWrite] + # We have to use binary translation to count bytes properly. + lassign [fconfigure $sock -translation] trRead trWrite + fconfigure $sock -translation [list binary $trWrite] - if { - $state(-binary) || [IsBinaryContentType $state(type)] - } { - # Turn off conversions for non-text data. - set state(binary) 1 - } - if {[info exists state(-channel)]} { - if {$state(binary) || [llength [ContentEncoding $token]]} { - fconfigure $state(-channel) -translation binary - } - if {![info exists state(-handler)]} { - # Initiate a sequence of background fcopies. - fileevent $sock readable {} - CopyStart $sock $token - return + if { + $state(-binary) || [IsBinaryContentType $state(type)] + } { + # Turn off conversions for non-text data. + set state(binary) 1 } - } - } elseif {$nhl > 0} { - # Process header lines. - Log ##Log header - token $token - $line - if {[regexp -nocase {^([^:]+):(.+)$} $line x key value]} { - switch -- [string tolower $key] { - content-type { - set state(type) [string trim [string tolower $value]] - # Grab the optional charset information. - if {[regexp -nocase \ - {charset\s*=\s*\"((?:[^""]|\\\")*)\"} \ - $state(type) -> cs]} { - set state(charset) [string map {{\"} \"} $cs] - } else { - regexp -nocase {charset\s*=\s*(\S+?);?} \ - $state(type) -> state(charset) - } + if {[info exists state(-channel)]} { + if {$state(binary) || [llength [ContentEncoding $token]]} { + fconfigure $state(-channel) -translation binary } - content-length { - set state(totalsize) [string trim $value] + if {![info exists state(-handler)]} { + # Initiate a sequence of background fcopies. + fileevent $sock readable {} + rename ${token}EventCoroutine {} + CopyStart $sock $token + return } - content-encoding { - set state(coding) [string trim $value] - } - transfer-encoding { - set state(transfer) \ - [string trim [string tolower $value]] - } - proxy-connection - - connection { - set state(connection) \ - [string trim [string tolower $value]] + } + } elseif {$nhl > 0} { + # Process header lines. + Log ##Log header - token $token - $line + if {[regexp -nocase {^([^:]+):(.+)$} $line x key value]} { + switch -- [string tolower $key] { + content-type { + set state(type) [string trim [string tolower $value]] + # Grab the optional charset information. + if {[regexp -nocase \ + {charset\s*=\s*\"((?:[^""]|\\\")*)\"} \ + $state(type) -> cs]} { + set state(charset) [string map {{\"} \"} $cs] + } else { + regexp -nocase {charset\s*=\s*(\S+?);?} \ + $state(type) -> state(charset) + } + } + content-length { + set state(totalsize) [string trim $value] + } + content-encoding { + set state(coding) [string trim $value] + } + transfer-encoding { + set state(transfer) \ + [string trim [string tolower $value]] + } + proxy-connection - + connection { + set state(connection) \ + [string trim [string tolower $value]] + } } + lappend state(meta) $key [string trim $value] } - lappend state(meta) $key [string trim $value] } - } - } else { - # Now reading body - Log ##Log body - token $token - if {[catch { - if {[info exists state(-handler)]} { - set n [eval $state(-handler) [list $sock $token]] - Log ##Log handler $n - token $token - # N.B. the protocol has been set to 1.0 because the -handler - # logic is not expected to handle chunked encoding. - # FIXME allow -handler with 1.1 on dechunked stacked channel. - if {$state(totalsize) == 0} { - # We know the transfer is complete only when the server - # closes the connection - i.e. eof is not an error. - set state(state) complete - } - if {![string is integer -strict $n]} { - if 1 { - # Do not tolerate bad -handler - fail with error status. - set msg {the -handler command for http::geturl must\ - return an integer (the number of bytes read)} - Log ^X$tk end of response (handler error) - token $token - Eot $token $msg - } else { - # Tolerate the bad -handler, and continue. The penalty: - # (a) Because the handler returns nonsense, we know the - # transfer is complete only when the server closes - # the connection - i.e. eof is not an error. - # (b) http::size will not be accurate. - # (c) The transaction is already downgraded to 1.0 to - # avoid chunked transfer encoding. It MUST also be - # forced to "Connection: close" or the HTTP/1.0 - # equivalent; or it MUST fail (as above) if the - # server sends "Connection: keep-alive" or the - # HTTP/1.0 equivalent. - set n 0 + } else { + # Now reading body + Log ##Log body - token $token + if {[catch { + if {[info exists state(-handler)]} { + set n [eval $state(-handler) [list $sock $token]] + Log ##Log handler $n - token $token + # N.B. the protocol has been set to 1.0 because the -handler + # logic is not expected to handle chunked encoding. + # FIXME allow -handler with 1.1 on dechunked stacked channel. + if {$state(totalsize) == 0} { + # We know the transfer is complete only when the server + # closes the connection - i.e. eof is not an error. set state(state) complete } - } else { - } - } elseif {[info exists state(transfer_final)]} { - set line [getTextLine $sock] - set n [string length $line] - set state(state) complete - if {$n > 0} { - # - HTTP trailers (late response headers) are permitted by - # Chunked Transfer-Encoding, and can be safely ignored. - # - Do not count these bytes in the total received for the - # response body. - Log "trailer of $n bytes after final chunk - token $token" - append state(transfer_final) $line - set n 0 - } else { - Log ^F$tk end of response body (chunked) - token $token - Log "final chunk part - token $token" - Eot $token - } - } elseif { [info exists state(transfer)] - && ($state(transfer) eq "chunked") - } { - Log ##Log chunked - token $token - set size 0 - set hexLenChunk [getTextLine $sock] - #set ntl [string length $hexLenChunk] - if {[string trim $hexLenChunk] ne ""} { - scan $hexLenChunk %x size - if {$size != 0} { - Log ##Log chunk-measure $size - token $token - set bl [fconfigure $sock -blocking] - fconfigure $sock -blocking 1 - set chunk [read $sock $size] - fconfigure $sock -blocking $bl - set n [string length $chunk] - if {$n >= 0} { - append state(body) $chunk - incr state(log_size) [string length $chunk] - Log ##Log chunk $n cumul $state(log_size) - token $token + if {![string is integer -strict $n]} { + if 1 { + # Do not tolerate bad -handler - fail with error status. + set msg {the -handler command for http::geturl must\ + return an integer (the number of bytes read)} + Log ^X$tk end of response (handler error) - token $token + Eot $token $msg + } else { + # Tolerate the bad -handler, and continue. The penalty: + # (a) Because the handler returns nonsense, we know the + # transfer is complete only when the server closes + # the connection - i.e. eof is not an error. + # (b) http::size will not be accurate. + # (c) The transaction is already downgraded to 1.0 to + # avoid chunked transfer encoding. It MUST also be + # forced to "Connection: close" or the HTTP/1.0 + # equivalent; or it MUST fail (as above) if the + # server sends "Connection: keep-alive" or the + # HTTP/1.0 equivalent. + set n 0 + set state(state) complete } - if {$size != [string length $chunk]} { - Log "WARNING: mis-sized chunk:\ - was [string length $chunk], should be $size -\ - token $token" + } else { + } + } elseif {[info exists state(transfer_final)]} { + set line [getTextLine $sock] + set n [string length $line] + set state(state) complete + if {$n > 0} { + # - HTTP trailers (late response headers) are permitted by + # Chunked Transfer-Encoding, and can be safely ignored. + # - Do not count these bytes in the total received for the + # response body. + Log "trailer of $n bytes after final chunk - token $token" + append state(transfer_final) $line + set n 0 + } else { + Log ^F$tk end of response body (chunked) - token $token + Log "final chunk part - token $token" + Eot $token + } + } elseif { [info exists state(transfer)] + && ($state(transfer) eq "chunked") + } { + Log ##Log chunked - token $token + set size 0 + set hexLenChunk [getTextLine $sock] + #set ntl [string length $hexLenChunk] + if {[string trim $hexLenChunk] ne ""} { + scan $hexLenChunk %x size + if {$size != 0} { + Log ##Log chunk-measure $size - token $token + set chunk [BlockingRead $sock $size] + set n [string length $chunk] + if {$n >= 0} { + append state(body) $chunk + incr state(log_size) [string length $chunk] + Log ##Log chunk $n cumul $state(log_size) - token $token + } + if {$size != [string length $chunk]} { + Log "WARNING: mis-sized chunk:\ + was [string length $chunk], should be $size -\ + token $token" + set n 0 + set state(connection) close + Log ^X$tk end of response (chunk error) \ + - token $token + set msg {error in chunked encoding - fetch\ + terminated} + Eot $token $msg + } + # CRLF that follows chunk: + getTextLine $sock + } else { set n 0 - set state(connection) close - Log ^X$tk end of response (chunk error) \ - - token $token - set msg {error in chunked encoding - fetch\ - terminated} - Eot $token $msg + set state(transfer_final) {} } - # CRLF that follows chunk: - getTextLine $sock } else { + # Line expected to hold chunk length is empty. + Log ##Log bad-chunk-measure - token $token set n 0 - set state(transfer_final) {} + set state(connection) close + Log ^X$tk end of response (chunk error) - token $token + Eot $token {error in chunked encoding - fetch terminated} } } else { - # Line expected to hold chunk length is empty. - Log ##Log bad-chunk-measure - token $token - set n 0 - set state(connection) close - Log ^X$tk end of response (chunk error) - token $token - Eot $token {error in chunked encoding - fetch terminated} - } - } else { - Log ##Log unchunked - token $token - if {$state(totalsize) == 0} { - # We know the transfer is complete only when the server - # closes the connection. - set state(state) complete - set reqSize $state(-blocksize) - } else { - # Ask for the whole of the unserved response-body. - # This works around a problem with a tls::socket - for https - # in keep-alive mode, and a request for $state(-blocksize) - # bytes, the last part of the resource does not get read - # until the server times out. - set reqSize [expr {$state(totalsize) - $state(currentsize)}] - - # The workaround fails if reqSize is - # capped at $state(-blocksize). - # set reqSize [expr {min($reqSize, $state(-blocksize))}] - } - set c $state(currentsize) - set t $state(totalsize) - Log ##Log non-chunk currentsize $c of totalsize $t - token $token - set block [read $sock $reqSize] - set n [string length $block] - if {$n >= 0} { - append state(body) $block - Log ##Log non-chunk [string length $state(body)] - token $token - } - } - # This calculation uses n from the -handler, chunked, or unchunked - # case as appropriate. - if {[info exists state]} { - if {$n >= 0} { - incr state(currentsize) $n + Log ##Log unchunked - token $token + if {$state(totalsize) == 0} { + # We know the transfer is complete only when the server + # closes the connection. + set state(state) complete + set reqSize $state(-blocksize) + } else { + # Ask for the whole of the unserved response-body. + # This works around a problem with a tls::socket - for https + # in keep-alive mode, and a request for $state(-blocksize) + # bytes, the last part of the resource does not get read + # until the server times out. + set reqSize [expr {$state(totalsize) - $state(currentsize)}] + + # The workaround fails if reqSize is + # capped at $state(-blocksize). + # set reqSize [expr {min($reqSize, $state(-blocksize))}] + } set c $state(currentsize) set t $state(totalsize) - Log ##Log another $n currentsize $c totalsize $t - token $token + Log ##Log non-chunk currentsize $c of totalsize $t - token $token + set block [read $sock $reqSize] + set n [string length $block] + if {$n >= 0} { + append state(body) $block + Log ##Log non-chunk [string length $state(body)] - token $token + } } - # If Content-Length - check for end of data. - if { - ($state(totalsize) > 0) - && ($state(currentsize) >= $state(totalsize)) - } { - Log ^F$tk end of response body (unchunked) - token $token - set state(state) complete - Eot $token + # This calculation uses n from the -handler, chunked, or unchunked + # case as appropriate. + if {[info exists state]} { + if {$n >= 0} { + incr state(currentsize) $n + set c $state(currentsize) + set t $state(totalsize) + Log ##Log another $n currentsize $c totalsize $t - token $token + } + # If Content-Length - check for end of data. + if { + ($state(totalsize) > 0) + && ($state(currentsize) >= $state(totalsize)) + } { + Log ^F$tk end of response body (unchunked) - token $token + set state(state) complete + Eot $token + } + } + } err]} { + Log ^X$tk end of response (error ${err}) - token $token + Finish $token $err + return + } else { + if {[info exists state(-progress)]} { + eval $state(-progress) \ + [list $token $state(totalsize) $state(currentsize)] } - } - } err]} { - Log ^X$tk end of response (error ${err}) - token $token - Finish $token $err - return - } else { - if {[info exists state(-progress)]} { - eval $state(-progress) \ - [list $token $state(totalsize) $state(currentsize)] } } - } - # catch as an Eot above may have closed the socket already - # $state(state) may be connecting, header, body, or complete - if {![catch {eof $sock} eof] && $eof} { - Log ##Log eof - token $token - if {[info exists $token]} { - set state(connection) close - if {$state(state) eq "complete"} { - # This includes all cases in which the transaction - # can be completed by eof. - # The value "complete" is set only in http::Event, and it is - # used only in the test above. - Log ^F$tk end of response body (unchunked, eof) - token $token - Eot $token + # catch as an Eot above may have closed the socket already + # $state(state) may be connecting, header, body, or complete + if {![set cc [catch {eof $sock} eof]] && $eof} { + Log ##Log eof - token $token + if {[info exists $token]} { + set state(connection) close + if {$state(state) eq "complete"} { + # This includes all cases in which the transaction + # can be completed by eof. + # The value "complete" is set only in http::Event, and it is + # used only in the test above. + Log ^F$tk end of response body (unchunked, eof) - token $token + Eot $token + } else { + # Premature eof. + Log ^X$tk end of response (unexpected eof) - token $token + Eot $token eof + } } else { - # Premature eof. - Log ^X$tk end of response (unexpected eof) - token $token - Eot $token eof + # open connection closed on a token that has been cleaned up. + Log ^X$tk end of response (token error) - token $token + CloseSocket $sock } + } elseif {$cc} { + return } else { - # open connection closed on a token that has been cleaned up. - Log ^X$tk end of response (token error) - token $token - CloseSocket $sock + # Not eof, continue and yield. } } return @@ -2970,18 +2991,55 @@ proc http::IsBinaryContentType {type} { # Results: # The line of text, without trailing newline -# FIXME get rid of blocking - proc http::getTextLine {sock} { set tr [fconfigure $sock -translation] lassign $tr trRead trWrite - set bl [fconfigure $sock -blocking] - fconfigure $sock -translation [list crlf $trWrite] -blocking 1 - set r [gets $sock] - fconfigure $sock -translation $tr -blocking $bl + fconfigure $sock -translation [list crlf $trWrite] + set r [BlockingGets $sock] + fconfigure $sock -translation $tr return $r } +# http::BlockingRead +# +# Replacement for a blocking read. +# The caller must be a coroutine. + +proc http::BlockingRead {sock size} { + if {$size < 1} { + return + } + set result {} + while 1 { + set need [expr {$size - [string length $result]}] + set block [read $sock $need] + set eof [eof $sock] + append result $block + if {[string length $result] >= $size || $eof} { + return $result + } else { + yield + } + } +} + +# http::BlockingGets +# +# Replacement for a blocking gets. +# The caller must be a coroutine. + +proc http::BlockingGets {sock} { + while 1 { + set count [gets $sock line] + set eof [eof $sock] + if {$count > -1 || $eof} { + return $line + } else { + yield + } + } +} + # http::CopyStart # # Error handling wrapper around fcopy -- cgit v0.12 From 6bc8c27b7f2b94c8b35b1a7533fb19cb2f788fbd Mon Sep 17 00:00:00 2001 From: kjnash Date: Wed, 4 Apr 2018 13:37:37 +0000 Subject: Restore most lines to 80 columns --- library/http/http.tcl | 147 ++++++++++++++++++++++++++++---------------------- 1 file changed, 83 insertions(+), 64 deletions(-) diff --git a/library/http/http.tcl b/library/http/http.tcl index 77a2a43..28bb13d 100644 --- a/library/http/http.tcl +++ b/library/http/http.tcl @@ -2420,7 +2420,9 @@ proc http::Write {token} { # http::Event # -# Handle input on the socket +# Handle input on the socket. This command is the core of +# the coroutine commands ${token}EventCoroutine that are +# bound to "fileevent $sock readable" and process input. # # Arguments # sock The socket receiving input. @@ -2481,10 +2483,10 @@ proc http::Event {sock token} { } # else: - # This is NOT a persistent socket that has been closed since its - # last use. - # If any other requests are in flight or pipelined/queued, they - # will be discarded. + # This is NOT a persistent socket that has been closed since + # its last use. + # If any other requests are in flight or pipelined/queued, + # they will be discarded. } else { Log ^X$tk end of response (error) - token $token Finish $token $nsl @@ -2508,8 +2510,8 @@ proc http::Event {sock token} { # else: # This is NOT a persistent socket that has been closed since its # last use. - # If any other requests are in flight or pipelined/queued, they will - # be discarded. + # If any other requests are in flight or pipelined/queued, they + # will be discarded. } else { Log ##Log - connecting 2 - token $token # nsl is -1 so either fblocked (OK) or (eof and not reusing). @@ -2541,9 +2543,10 @@ proc http::Event {sock token} { && (!$state(reusing)) && ($state(-pipeline)) } { - # Response headers received for first request on a persistent - # socket. Now ready for pipelined writes (if any). - # Previous value is $token. It cannot be pending. + # Response headers received for first request on a + # persistent socket. Now ready for pipelined writes (if + # any). + # Previous value is $token. It cannot be "pending". set socketWrState($state(socketinfo)) Wready http::NextPipelinedWrite $token } @@ -2551,9 +2554,9 @@ proc http::Event {sock token} { # Once a "close" has been signaled, the client MUST NOT send any # more requests on that connection. # - # If either the client or the server sends the "close" token in the - # Connection header, that request becomes the last one for the - # connection. + # If either the client or the server sends the "close" token in + # the Connection header, that request becomes the last one for + # the connection. if { ([info exists state(connection)]) && ([info exists socketMapping($state(socketinfo))]) @@ -2583,14 +2586,14 @@ proc http::Event {sock token} { $socketWrQueue($state(socketinfo))] # - All tokens are preserved for re-use by ReplayCore. - # - Queues are preserved in case of Finish with error, but - # are not used for anything else because socketClosing(*) - # is set below. + # - Queues are preserved in case of Finish with error, + # but are not used for anything else because + # socketClosing(*) is set below. # - Cancel the state(after) timeout events. - foreach tokenElement $socketRdQueue($state(socketinfo)) { - if {[info exists ${tokenElement}(after)]} { - after cancel [set ${tokenElement}(after)] - unset ${tokenElement}(after) + foreach tokenVal $socketRdQueue($state(socketinfo)) { + if {[info exists ${tokenVal}(after)]} { + after cancel [set ${tokenVal}(after)] + unset ${tokenVal}(after) } } @@ -2613,15 +2616,15 @@ proc http::Event {sock token} { return } - # - For non-chunked transfer we may have no body - in this case we - # may get no further file event if the connection doesn't close - # and no more data is sent. We can tell and must finish up now - - # not later - the alternative would be to wait until the server - # times out. - # - In this case, the server has NOT told the client it will close - # the connection, AND it has NOT indicated the resource length - # EITHER by setting the Content-Length (totalsize) OR by using - # chunked Transer-Encoding. + # - For non-chunked transfer we may have no body - in this case + # we may get no further file event if the connection doesn't + # close and no more data is sent. We can tell and must finish + # up now - not later - the alternative would be to wait until + # the server times out. + # - In this case, the server has NOT told the client it will + # close the connection, AND it has NOT indicated the resource + # length EITHER by setting the Content-Length (totalsize) OR + # by using chunked Transfer-Encoding. # - Do not worry here about the case (Connection: close) because # the server should close the connection. # - IF (NOT Connection: close) AND (NOT chunked encoding) AND @@ -2710,7 +2713,7 @@ proc http::Event {sock token} { Log ##Log handler $n - token $token # N.B. the protocol has been set to 1.0 because the -handler # logic is not expected to handle chunked encoding. - # FIXME allow -handler with 1.1 on dechunked stacked channel. + # FIXME Allow -handler with 1.1 on dechunked stacked chan. if {$state(totalsize) == 0} { # We know the transfer is complete only when the server # closes the connection - i.e. eof is not an error. @@ -2718,23 +2721,29 @@ proc http::Event {sock token} { } if {![string is integer -strict $n]} { if 1 { - # Do not tolerate bad -handler - fail with error status. + # Do not tolerate bad -handler - fail with error + # status. set msg {the -handler command for http::geturl must\ - return an integer (the number of bytes read)} - Log ^X$tk end of response (handler error) - token $token + return an integer (the number of bytes\ + read)} + Log ^X$tk end of response (handler error) -\ + token $token Eot $token $msg } else { - # Tolerate the bad -handler, and continue. The penalty: - # (a) Because the handler returns nonsense, we know the - # transfer is complete only when the server closes - # the connection - i.e. eof is not an error. + # Tolerate the bad -handler, and continue. The + # penalty: + # (a) Because the handler returns nonsense, we know + # the transfer is complete only when the server + # closes the connection - i.e. eof is not an + # error. # (b) http::size will not be accurate. - # (c) The transaction is already downgraded to 1.0 to - # avoid chunked transfer encoding. It MUST also be - # forced to "Connection: close" or the HTTP/1.0 - # equivalent; or it MUST fail (as above) if the - # server sends "Connection: keep-alive" or the - # HTTP/1.0 equivalent. + # (c) The transaction is already downgraded to 1.0 + # to avoid chunked transfer encoding. It MUST + # also be forced to "Connection: close" or the + # HTTP/1.0 equivalent; or it MUST fail (as + # above) if the server sends + # "Connection: keep-alive" or the HTTP/1.0 + # equivalent. set n 0 set state(state) complete } @@ -2745,11 +2754,13 @@ proc http::Event {sock token} { set n [string length $line] set state(state) complete if {$n > 0} { - # - HTTP trailers (late response headers) are permitted by - # Chunked Transfer-Encoding, and can be safely ignored. - # - Do not count these bytes in the total received for the - # response body. - Log "trailer of $n bytes after final chunk - token $token" + # - HTTP trailers (late response headers) are permitted + # by Chunked Transfer-Encoding, and can be safely + # ignored. + # - Do not count these bytes in the total received for + # the response body. + Log "trailer of $n bytes after final chunk -\ + token $token" append state(transfer_final) $line set n 0 } else { @@ -2773,12 +2784,13 @@ proc http::Event {sock token} { if {$n >= 0} { append state(body) $chunk incr state(log_size) [string length $chunk] - Log ##Log chunk $n cumul $state(log_size) - token $token + Log ##Log chunk $n cumul $state(log_size) -\ + token $token } if {$size != [string length $chunk]} { Log "WARNING: mis-sized chunk:\ - was [string length $chunk], should be $size -\ - token $token" + was [string length $chunk], should be\ + $size - token $token" set n 0 set state(connection) close Log ^X$tk end of response (chunk error) \ @@ -2799,7 +2811,8 @@ proc http::Event {sock token} { set n 0 set state(connection) close Log ^X$tk end of response (chunk error) - token $token - Eot $token {error in chunked encoding - fetch terminated} + Eot $token {error in chunked encoding -\ + fetch terminated} } } else { Log ##Log unchunked - token $token @@ -2810,11 +2823,12 @@ proc http::Event {sock token} { set reqSize $state(-blocksize) } else { # Ask for the whole of the unserved response-body. - # This works around a problem with a tls::socket - for https - # in keep-alive mode, and a request for $state(-blocksize) - # bytes, the last part of the resource does not get read - # until the server times out. - set reqSize [expr {$state(totalsize) - $state(currentsize)}] + # This works around a problem with a tls::socket - for + # https in keep-alive mode, and a request for + # $state(-blocksize) bytes, the last part of the + # resource does not get read until the server times out. + set reqSize [expr { $state(totalsize) + - $state(currentsize)}] # The workaround fails if reqSize is # capped at $state(-blocksize). @@ -2822,29 +2836,33 @@ proc http::Event {sock token} { } set c $state(currentsize) set t $state(totalsize) - Log ##Log non-chunk currentsize $c of totalsize $t - token $token + Log ##Log non-chunk currentsize $c of totalsize $t -\ + token $token set block [read $sock $reqSize] set n [string length $block] if {$n >= 0} { append state(body) $block - Log ##Log non-chunk [string length $state(body)] - token $token + Log ##Log non-chunk [string length $state(body)] -\ + token $token } } - # This calculation uses n from the -handler, chunked, or unchunked - # case as appropriate. + # This calculation uses n from the -handler, chunked, or + # unchunked case as appropriate. if {[info exists state]} { if {$n >= 0} { incr state(currentsize) $n set c $state(currentsize) set t $state(totalsize) - Log ##Log another $n currentsize $c totalsize $t - token $token + Log ##Log another $n currentsize $c totalsize $t -\ + token $token } # If Content-Length - check for end of data. if { ($state(totalsize) > 0) && ($state(currentsize) >= $state(totalsize)) } { - Log ^F$tk end of response body (unchunked) - token $token + Log ^F$tk end of response body (unchunked) -\ + token $token set state(state) complete Eot $token } @@ -2872,7 +2890,8 @@ proc http::Event {sock token} { # can be completed by eof. # The value "complete" is set only in http::Event, and it is # used only in the test above. - Log ^F$tk end of response body (unchunked, eof) - token $token + Log ^F$tk end of response body (unchunked, eof) -\ + token $token Eot $token } else { # Premature eof. -- cgit v0.12 From d690b847384c4c4ea77254292ac7e36a71b4867d Mon Sep 17 00:00:00 2001 From: kjnash Date: Fri, 13 Apr 2018 15:41:00 +0000 Subject: Improve detection and reporting of TLS errors. New command http::registerError to assist the latter. Ensure that http::cleanup cancels any timeout event if not already done. Add comments on non-blocking read/gets. --- library/http/http.tcl | 80 ++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 66 insertions(+), 14 deletions(-) diff --git a/library/http/http.tcl b/library/http/http.tcl index 28bb13d..e0382e7 100644 --- a/library/http/http.tcl +++ b/library/http/http.tcl @@ -128,13 +128,13 @@ namespace eval http { set defaultKeepalive 0 } - namespace export geturl config reset wait formatQuery register unregister - # Useful, but not exported: data size status code cleanup error meta ncode, - # mapReply, init. Comments suggest that "init" can be used for - # re-initialisation, although it is undocumented. - # - # Not exported, probably should be upper-case initial letter as part - # of the internals: getTextLine make-transformation-chunked + namespace export geturl config reset wait formatQuery + namespace export register unregister registerError + # - Useful, but not exported: data, size, status, code, cleanup, error, + # meta, ncode, mapReply, init. Comments suggest that "init" can be used + # for re-initialisation, although the command is undocumented. + # - Not exported, probably should be upper-case initial letter as part + # of the internals: getTextLine, make-transformation-chunked. } # http::Log -- @@ -1470,6 +1470,11 @@ proc http::Connected {token proto phost srvurl} { puts $sock "Content-Length: $state(querylength)" } puts $sock "" + flush $sock + # Flush flushes the error in the https case with a bad handshake: + # else the socket never becomes writable again, and hangs until + # timeout (if any). + lassign [fconfigure $sock -translation] trRead trWrite fconfigure $sock -translation [list $trRead binary] fileevent $sock writable [list http::Write $token] @@ -1496,8 +1501,9 @@ proc http::Connected {token proto phost srvurl} { } } err]} { - # The socket probably was never connected, or the connection dropped - # later. + # The socket probably was never connected, OR the connection dropped + # later, OR https handshake error, which may be discovered as late as + # the "flush" command above... Log "WARNING - if testing, pay special attention to this\ case (GI) which is seldom executed - token $token" if {[info exists state(reusing)] && $state(reusing)} { @@ -1515,7 +1521,14 @@ proc http::Connected {token proto phost srvurl} { # If any other requests are in flight or pipelined/queued, they will # be discarded. } elseif {$state(status) eq ""} { - Finish $token {failed to re-use socket} + # ...https handshake errors come here. + set msg [registerError $sock] + registerError $sock {} + if {$msg eq {}} { + set msg {failed to use socket} + } else { + } + Finish $token $msg } elseif {$state(status) ne "error"} { Finish $token $err } else { @@ -1526,6 +1539,35 @@ proc http::Connected {token proto phost srvurl} { return } +# http::registerError +# +# Called (for example when processing TclTLS activity) to register +# an error for a connection on a specific socket. This helps +# http::Connected to deliver meaningful error messages, e.g. when a TLS +# certificate fails verification. +# +# Usage: http::registerError socket ?newValue? +# +# "set" semantics, except that a "get" (a call without a new value) for a +# non-existent socket returns {}, not an error. + +proc http::registerError {sock args} { + variable registeredErrors + + if { ([llength $args] == 0) + && (![info exists registeredErrors($sock)]) + } { + return + } elseif { ([llength $args] == 1) + && ([lindex $args 0] eq {}) + } { + unset -nocomplain registeredErrors($sock) + return + } + set registeredErrors($sock) {*}$args + # N.B. Implicit Return +} + # http::DoneRequest -- # # Command called when a request has been sent. It will arrange the @@ -2263,6 +2305,10 @@ proc http::cleanup {token} { if {[info commands ${token}EventCoroutine] ne {}} { rename ${token}EventCoroutine {} } + if {[info exists state(after)]} { + after cancel $state(after) + unset state(after) + } if {[info exists state]} { unset state } @@ -2750,6 +2796,7 @@ proc http::Event {sock token} { } else { } } elseif {[info exists state(transfer_final)]} { + # This code forgives EOF in place of the final CRLF. set line [getTextLine $sock] set n [string length $line] set state(state) complete @@ -2799,14 +2846,15 @@ proc http::Event {sock token} { terminated} Eot $token $msg } - # CRLF that follows chunk: + # CRLF that follows chunk. + # If eof, this is handled at the end of this proc. getTextLine $sock } else { set n 0 set state(transfer_final) {} } } else { - # Line expected to hold chunk length is empty. + # Line expected to hold chunk length is empty, or eof. Log ##Log bad-chunk-measure - token $token set n 0 set state(connection) close @@ -3001,8 +3049,10 @@ proc http::IsBinaryContentType {type} { # http::getTextLine -- # -# Get one line with the stream in blocking crlf mode -# Used if Transfer-Encoding is chunked +# Get one line with the stream in crlf mode. +# Used if Transfer-Encoding is chunked. +# Empty line is not distinguished from eof. The caller must +# be able to handle this. # # Arguments # sock The socket receiving input. @@ -3046,6 +3096,8 @@ proc http::BlockingRead {sock size} { # # Replacement for a blocking gets. # The caller must be a coroutine. +# Empty line is not distinguished from eof. The caller must +# be able to handle this. proc http::BlockingGets {sock} { while 1 { -- cgit v0.12 From 4588d7300e53e7403a693eedb0d10d54efccb972 Mon Sep 17 00:00:00 2001 From: kjnash Date: Fri, 13 Apr 2018 15:48:13 +0000 Subject: Restore Tcl 8+4 tab convention --- library/http/http.tcl | 56 +++++++++++++++++++++++++-------------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/library/http/http.tcl b/library/http/http.tcl index e0382e7..30b69e6 100644 --- a/library/http/http.tcl +++ b/library/http/http.tcl @@ -256,7 +256,7 @@ proc http::Finish {token {errormsg ""} {skipCB 0}} { set state(status) "error" } if {[info commands ${token}EventCoroutine] ne {}} { - rename ${token}EventCoroutine {} + rename ${token}EventCoroutine {} } if { ($state(status) eq "timeout") || ($state(status) eq "error") @@ -333,10 +333,10 @@ proc http::KeepSocket {token} { if {$TEST_EOF} { # ONLY for testing reaction to server eof. # No server timeouts will be caught. - catch {fileevent $state(sock) readable {}} + catch {fileevent $state(sock) readable {}} } else { - # Normal operation. - # Test constraint normalEof. + # Normal operation. + # Test constraint normalEof. } if { [info exists state(socketinfo)] @@ -1555,14 +1555,14 @@ proc http::registerError {sock args} { variable registeredErrors if { ([llength $args] == 0) - && (![info exists registeredErrors($sock)]) + && (![info exists registeredErrors($sock)]) } { - return + return } elseif { ([llength $args] == 1) - && ([lindex $args 0] eq {}) + && ([lindex $args 0] eq {}) } { - unset -nocomplain registeredErrors($sock) - return + unset -nocomplain registeredErrors($sock) + return } set registeredErrors($sock) {*}$args # N.B. Implicit Return @@ -2303,7 +2303,7 @@ proc http::cleanup {token} { variable $token upvar 0 $token state if {[info commands ${token}EventCoroutine] ne {}} { - rename ${token}EventCoroutine {} + rename ${token}EventCoroutine {} } if {[info exists state(after)]} { after cancel $state(after) @@ -2876,7 +2876,7 @@ proc http::Event {sock token} { # $state(-blocksize) bytes, the last part of the # resource does not get read until the server times out. set reqSize [expr { $state(totalsize) - - $state(currentsize)}] + - $state(currentsize)}] # The workaround fails if reqSize is # capped at $state(-blocksize). @@ -3076,19 +3076,19 @@ proc http::getTextLine {sock} { proc http::BlockingRead {sock size} { if {$size < 1} { - return + return } set result {} while 1 { - set need [expr {$size - [string length $result]}] - set block [read $sock $need] - set eof [eof $sock] - append result $block - if {[string length $result] >= $size || $eof} { - return $result - } else { - yield - } + set need [expr {$size - [string length $result]}] + set block [read $sock $need] + set eof [eof $sock] + append result $block + if {[string length $result] >= $size || $eof} { + return $result + } else { + yield + } } } @@ -3101,13 +3101,13 @@ proc http::BlockingRead {sock size} { proc http::BlockingGets {sock} { while 1 { - set count [gets $sock line] - set eof [eof $sock] - if {$count > -1 || $eof} { - return $line - } else { - yield - } + set count [gets $sock line] + set eof [eof $sock] + if {$count > -1 || $eof} { + return $line + } else { + yield + } } } -- cgit v0.12 From 3771e638b05a4c75d1222ee7653e01cd2289643e Mon Sep 17 00:00:00 2001 From: kjnash Date: Fri, 20 Apr 2018 20:06:30 +0000 Subject: Document the new proc http::registerError in http.n --- doc/http.n | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/doc/http.n b/doc/http.n index 2dae77e..e788022 100644 --- a/doc/http.n +++ b/doc/http.n @@ -44,6 +44,8 @@ http \- Client-side implementation of the HTTP/1.1 protocol .sp \fB::http::register \fIproto port command\fR .sp +\fB::http::registerError \fIport\fR ?\fImessage\fR? +.sp \fB::http::unregister \fIproto\fR .BE .SH DESCRIPTION @@ -454,6 +456,17 @@ set token [::http::geturl https://my.secure.site/] .CE .RE .TP +\fB::http::registerError\fR \fIport\fR ?\fImessage\fR? +. +This procedure allows a registered protocol handler to deliver an error +message for use by \fBhttp\fR. Calling this command does not raise an +error. The command is useful when a registered protocol detects an problem +(for example, an invalid TLS certificate) that will cause an error to +propagate to \fBhttp\fR. The command allows \fBhttp\fR to provide a +precise error message rather than a general one. The command returns the +value provided by the last call with argument \fImessage\fR, or the empty +string if no such call has been made. +.TP \fB::http::unregister\fR \fIproto\fR . This procedure unregisters a protocol handler that was previously -- cgit v0.12 From b169c964e611847319cc92875f653466939bcb43 Mon Sep 17 00:00:00 2001 From: kjnash Date: Sat, 21 Apr 2018 13:31:16 +0000 Subject: Amend httpPipeline.test tests to use stdout not stderr, and thus avoid the report {Test files exiting with errors} even when all tests pass. --- tests/httpTest.tcl | 16 ++++++++-------- tests/httpTestScript.tcl | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/tests/httpTest.tcl b/tests/httpTest.tcl index 38ba43f..9cd7a5d 100644 --- a/tests/httpTest.tcl +++ b/tests/httpTest.tcl @@ -25,7 +25,7 @@ package require http namespace eval ::http { variable TestStartTimeInMs [clock milliseconds] - catch {puts stderr "Start time (zero ms) is $TestStartTimeInMs"} + catch {puts stdout "Start time (zero ms) is $TestStartTimeInMs"} } namespace eval ::httpTest { @@ -35,15 +35,15 @@ namespace eval ::httpTest { -verbose 0 -dotted 1 } - # -verbose - 0 quiet 1 write to stderr 2 write more + # -verbose - 0 quiet 1 write to stdout 2 write more # -dotted - (boolean) use dots for absences in lists of transactions } proc httpTest::Puts {txt} { variable testOptions if {$testOptions(-verbose) > 0} { - puts stderr $txt - flush stderr + puts stdout $txt + flush stdout } return } @@ -53,7 +53,7 @@ proc httpTest::Puts {txt} { # A special-purpose logger used for running tests. # - Processes Log calls that have "^" in their arguments, and records them in # variable ::httpTest::testResults. -# - Also writes them to stderr (using Puts) if ($testOptions(-verbose) > 0). +# - Also writes them to stdout (using Puts) if ($testOptions(-verbose) > 0). # - Also writes Log calls that do not have "^", if ($testOptions(-verbose) > 1). proc http::Log {args} { @@ -78,10 +78,10 @@ proc httpTest::LogRecord {txt} { set pos [string first ^ $txt] set len [string length $txt] if {$pos > $len - 3} { - puts stderr "Logging Error: $txt" - puts stderr "Fix this call to Log in http-*.tm so it has ^ then\ + puts stdout "Logging Error: $txt" + puts stdout "Fix this call to Log in http-*.tm so it has ^ then\ a letter then a numeral." - flush stderr + flush stdout } elseif {$pos == -1} { # Called by mistake. } else { diff --git a/tests/httpTestScript.tcl b/tests/httpTestScript.tcl index 4046c7a..a8ef9c8 100644 --- a/tests/httpTestScript.tcl +++ b/tests/httpTestScript.tcl @@ -389,7 +389,7 @@ proc httpTestScript::Requester {uriCode keepAlive validate query args} { -command ::httpTestScript::WhenFinished } token]} { set msg $token - catch {puts stderr "Error: $msg"} + catch {puts stdout "Error: $msg"} return } else { # Request will begin. -- cgit v0.12 From 227db01958097c4aac9a9b57569db68002ab1187 Mon Sep 17 00:00:00 2001 From: kjnash Date: Sat, 21 Apr 2018 14:22:35 +0000 Subject: Restore production test settings: set tests/httpPipeline.test to non-verbose, and comment out most Log calls in library/http/http.tcl --- library/http/http.tcl | 128 ++++++++++++++++++++++++------------------------ tests/httpPipeline.test | 2 +- 2 files changed, 65 insertions(+), 65 deletions(-) diff --git a/library/http/http.tcl b/library/http/http.tcl index 4bde573..d16a8d9 100644 --- a/library/http/http.tcl +++ b/library/http/http.tcl @@ -358,7 +358,7 @@ proc http::KeepSocket {token} { upvar 0 $token3 state3 set tk2 [namespace tail $token3] - Log #Log pipelined, GRANT read access to $token3 in KeepSocket + #Log pipelined, GRANT read access to $token3 in KeepSocket set socketRdState($connId) $token3 ReceiveResponse $token3 @@ -397,13 +397,13 @@ proc http::KeepSocket {token} { # give that request read and write access. variable $token3 set conn [set ${token3}(tmpConnArgs)] - Log #Log nonpipeline, GRANT r/w access to $token3 in KeepSocket + #Log nonpipeline, GRANT r/w access to $token3 in KeepSocket set socketRdState($connId) $token3 set socketWrState($connId) $token3 set socketWrQueue($connId) [lrange $socketWrQueue($connId) 1 end] # Connect does its own fconfigure. fileevent $state(sock) writable [list http::Connect $token3 {*}$conn] - Log #Log ---- $state(sock) << conn to $token3 for HTTP request (c) + #Log ---- $state(sock) << conn to $token3 for HTTP request (c) } elseif { $state(-pipeline) @@ -442,13 +442,13 @@ proc http::KeepSocket {token} { # case with a queued request. variable $token3 set conn [set ${token3}(tmpConnArgs)] - Log #Log nonpipeline, GRANT r/w access to $token3 in KeepSocket + #Log nonpipeline, GRANT r/w access to $token3 in KeepSocket set socketRdState($connId) $token3 set socketWrState($connId) $token3 set socketWrQueue($connId) [lrange $socketWrQueue($connId) 1 end] # Connect does its own fconfigure. fileevent $state(sock) writable [list http::Connect $token3 {*}$conn] - Log #Log ---- $state(sock) << conn to $token3 for HTTP request (c) + #Log ---- $state(sock) << conn to $token3 for HTTP request (c) } elseif { (!$state(-pipeline)) @@ -464,13 +464,13 @@ proc http::KeepSocket {token} { set token3 [lindex $socketWrQueue($connId) 0] variable $token3 set conn [set ${token3}(tmpConnArgs)] - Log #Log nonpipeline, GRANT r/w access to $token3 in KeepSocket + #Log nonpipeline, GRANT r/w access to $token3 in KeepSocket set socketRdState($connId) $token3 set socketWrState($connId) $token3 set socketWrQueue($connId) [lrange $socketWrQueue($connId) 1 end] # Connect does its own fconfigure. fileevent $state(sock) writable [list http::Connect $token3 {*}$conn] - Log #Log ---- $state(sock) << conn to $token3 for HTTP request (d) + #Log ---- $state(sock) << conn to $token3 for HTTP request (d) } elseif {(!$state(-pipeline))} { set socketWrState($connId) Wready @@ -710,7 +710,7 @@ proc http::geturl {url args} { set http(uid) 0 } set token [namespace current]::[incr http(uid)] - Log ##Log Starting http::geturl - token $token + ##Log Starting http::geturl - token $token variable $token upvar 0 $token state set tk [namespace tail $token] @@ -1098,8 +1098,8 @@ proc http::geturl {url args} { lappend sockopts -myaddr $state(-myaddr) } set pre [clock milliseconds] - Log ##Log pre socket opened, - token $token - Log ##Log [concat $defcmd $sockopts $targetAddr] - token $token + ##Log pre socket opened, - token $token + ##Log [concat $defcmd $sockopts $targetAddr] - token $token if {[catch {eval $defcmd $sockopts $targetAddr} sock errdict]} { # Something went wrong while trying to establish the connection. # Clean up after events and such, but DON'T call the command @@ -1113,15 +1113,15 @@ proc http::geturl {url args} { return -options $errdict $sock } else { # Initialisation of a new socket. - Log ##Log post socket opened, - token $token - Log ##Log socket opened, now fconfigure - token $token + ##Log post socket opened, - token $token + ##Log socket opened, now fconfigure - token $token set delay [expr {[clock milliseconds] - $pre}] if {$delay > 3000} { Log socket delay $delay - token $token } fconfigure $sock -translation {auto crlf} \ -buffersize $state(-blocksize) - Log ##Log socket opened, DONE fconfigure - token $token + ##Log socket opened, DONE fconfigure - token $token } } # Command [socket] is called with -async, but takes 5s to 5.1s to return, @@ -1152,7 +1152,7 @@ proc http::geturl {url args} { } if {$state(-pipeline)} { - Log #Log new, init for pipelined, GRANT write access to $token in geturl + #Log new, init for pipelined, GRANT write access to $token in geturl # Also grant premature read access to the socket. This is OK. set socketRdState($state(socketinfo)) $token set socketWrState($state(socketinfo)) $token @@ -1161,7 +1161,7 @@ proc http::geturl {url args} { # We cannot leave it as "Wready" because the next call to # http::geturl with a pipelined transaction would conclude that the # socket is available for writing. - Log #Log new, init for nonpipeline, GRANT r/w access to $token in geturl + #Log new, init for nonpipeline, GRANT r/w access to $token in geturl set socketRdState($state(socketinfo)) $token set socketWrState($state(socketinfo)) $token } @@ -1206,13 +1206,13 @@ proc http::geturl {url args} { # subsequent calls on this socket will come here because the socket # will close after the current read, and its # socketClosing($connId) is 1. - Log ##Log "HTTP request for token $token is queued" + ##Log "HTTP request for token $token is queued" } elseif { $reusing && $state(-pipeline) && ($socketWrState($state(socketinfo)) ne "Wready") } { - Log ##Log "HTTP request for token $token is queued for pipelined use" + ##Log "HTTP request for token $token is queued for pipelined use" lappend socketWrQueue($state(socketinfo)) $token } elseif { $reusing @@ -1220,7 +1220,7 @@ proc http::geturl {url args} { && ($socketWrState($state(socketinfo)) ne "Wready") } { # A write is queued or in progress. Lappend to the write queue. - Log ##Log "HTTP request for token $token is queued for nonpipeline use" + ##Log "HTTP request for token $token is queued for nonpipeline use" lappend socketWrQueue($state(socketinfo)) $token } elseif { $reusing @@ -1231,20 +1231,20 @@ proc http::geturl {url args} { # A read is queued or in progress, but not a write. Cannot start the # nonpipeline transaction, but must set socketWrState to prevent a # pipelined request jumping the queue. - Log ##Log "HTTP request for token $token is queued for nonpipeline use" - Log #Log re-use nonpipeline, GRANT delayed write access to $token in geturl + ##Log "HTTP request for token $token is queued for nonpipeline use" + #Log re-use nonpipeline, GRANT delayed write access to $token in geturl set socketWrState($state(socketinfo)) peNding lappend socketWrQueue($state(socketinfo)) $token } else { if {$reusing && $state(-pipeline)} { - Log #Log re-use pipelined, GRANT write access to $token in geturl + #Log re-use pipelined, GRANT write access to $token in geturl set socketWrState($state(socketinfo)) $token } elseif {$reusing} { # Cf tests above - both are ready. - Log #Log re-use nonpipeline, GRANT r/w access to $token in geturl + #Log re-use nonpipeline, GRANT r/w access to $token in geturl set socketRdState($state(socketinfo)) $token set socketWrState($state(socketinfo)) $token @@ -1254,7 +1254,7 @@ proc http::geturl {url args} { # All (!$reusing) cases come here, and also some $reusing cases if the # connection is ready. - Log #Log ---- $state(socketinfo) << conn to $token for HTTP request (a) + #Log ---- $state(socketinfo) << conn to $token for HTTP request (a) # Connect does its own fconfigure. fileevent $sock writable \ [list http::Connect $token $proto $phost $srvurl] @@ -1281,7 +1281,7 @@ proc http::geturl {url args} { return -code error $err } } - Log ##Log Leaving http::geturl - token $token + ##Log Leaving http::geturl - token $token return $token } @@ -1621,7 +1621,7 @@ proc http::DoneRequest {token} { && [info exists socketRdState($state(socketinfo))] && ($socketRdState($state(socketinfo)) eq "Rready") } { - Log #Log pipelined, GRANT read access to $token in Connected + #Log pipelined, GRANT read access to $token in Connected set socketRdState($state(socketinfo)) $token } @@ -1631,7 +1631,7 @@ proc http::DoneRequest {token} { && ($socketRdState($state(socketinfo)) ne $token) } { # Do not read from the socket until it is ready. - Log ##Log "HTTP response for token $token is queued for pipelined use" + ##Log "HTTP response for token $token is queued for pipelined use" # If $socketClosing(*), then the caller will be a pipelined write and # execution will come here. # This token has already been recorded as "in flight" for writing. @@ -1657,7 +1657,7 @@ proc http::ReceiveResponse {token} { set tk [namespace tail $token] set sock $state(sock) - Log #Log ---- $state(socketinfo) >> conn to $token for HTTP response + #Log ---- $state(socketinfo) >> conn to $token for HTTP response lassign [fconfigure $sock -translation] trRead trWrite fconfigure $sock -translation [list auto $trWrite] \ -buffersize $state(-blocksize) @@ -1718,13 +1718,13 @@ proc http::NextPipelinedWrite {token} { ) } { # - The usual case for a pipelined connection, ready for a new request. - Log #Log pipelined, GRANT write access to $token2 in NextPipelinedWrite + #Log pipelined, GRANT write access to $token2 in NextPipelinedWrite set conn [set ${token2}(tmpConnArgs)] set socketWrState($connId) $token2 set socketWrQueue($connId) [lrange $socketWrQueue($connId) 1 end] # Connect does its own fconfigure. fileevent $state(sock) writable [list http::Connect $token2 {*}$conn] - Log #Log ---- $connId << conn to $token2 for HTTP request (b) + #Log ---- $connId << conn to $token2 for HTTP request (b) # In the tests below, the next request will be nonpipeline. } elseif { $state(-pipeline) @@ -1747,13 +1747,13 @@ proc http::NextPipelinedWrite {token} { variable $token3 upvar 0 $token3 state3 set conn [set ${token3}(tmpConnArgs)] - Log #Log nonpipeline, GRANT r/w access to $token3 in NextPipelinedWrite + #Log nonpipeline, GRANT r/w access to $token3 in NextPipelinedWrite set socketRdState($connId) $token3 set socketWrState($connId) $token3 set socketWrQueue($connId) [lrange $socketWrQueue($connId) 1 end] # Connect does its own fconfigure. fileevent $state(sock) writable [list http::Connect $token3 {*}$conn] - Log #Log ---- $state(sock) << conn to $token3 for HTTP request (c) + #Log ---- $state(sock) << conn to $token3 for HTTP request (c) } elseif { $state(-pipeline) && [info exists socketWrState($connId)] @@ -1775,7 +1775,7 @@ proc http::NextPipelinedWrite {token} { # of the connection to $token2 will be done elsewhere - by command # http::KeepSocket when $socketRdState($connId) is set to "Rready". - Log #Log re-use nonpipeline, GRANT delayed write access to $token in NextP.. + #Log re-use nonpipeline, GRANT delayed write access to $token in NextP.. set socketWrState($connId) peNding } else { @@ -1804,7 +1804,7 @@ proc http::NextPipelinedWrite {token} { proc http::CancelReadPipeline {name1 connId op} { variable socketRdQueue - Log ##Log CancelReadPipeline $name1 $connId $op + ##Log CancelReadPipeline $name1 $connId $op if {[info exists socketRdQueue($connId)]} { set msg {the connection was closed by CancelReadPipeline} foreach token $socketRdQueue($connId) { @@ -1838,7 +1838,7 @@ proc http::CancelReadPipeline {name1 connId op} { proc http::CancelWritePipeline {name1 connId op} { variable socketWrQueue - Log ##Log CancelWritePipeline $name1 $connId $op + ##Log CancelWritePipeline $name1 $connId $op if {[info exists socketWrQueue($connId)]} { set msg {the connection was closed by CancelWritePipeline} foreach token $socketWrQueue($connId) { @@ -2124,7 +2124,7 @@ proc http::ReplayCore {newQueue} { return } - Log ##Log running ReplayCore for {*}$newQueue + ##Log running ReplayCore for {*}$newQueue set newToken [lindex $newQueue 0] set newQueue [lrange $newQueue 1 end] @@ -2156,8 +2156,8 @@ proc http::ReplayCore {newQueue} { } set pre [clock milliseconds] - Log ##Log pre socket opened, - token $token - Log ##Log $tmpOpenCmd - token $token + ##Log pre socket opened, - token $token + ##Log $tmpOpenCmd - token $token # 4. Open a socket. if {[catch {eval $tmpOpenCmd} sock]} { # Something went wrong while trying to establish the connection. @@ -2166,7 +2166,7 @@ proc http::ReplayCore {newQueue} { Finish $token $sock return } - Log ##Log post socket opened, - token $token + ##Log post socket opened, - token $token set delay [expr {[clock milliseconds] - $pre}] if {$delay > 3000} { Log socket delay $delay - token $token @@ -2194,11 +2194,11 @@ proc http::ReplayCore {newQueue} { } if {$state(-pipeline)} { - Log #Log new, init for pipelined, GRANT write acc to $token ReplayCore + #Log new, init for pipelined, GRANT write acc to $token ReplayCore set socketRdState($state(socketinfo)) $token set socketWrState($state(socketinfo)) $token } else { - Log #Log new, init for nonpipeline, GRANT r/w acc to $token ReplayCore + #Log new, init for nonpipeline, GRANT r/w acc to $token ReplayCore set socketRdState($state(socketinfo)) $token set socketWrState($state(socketinfo)) $token } @@ -2209,7 +2209,7 @@ proc http::ReplayCore {newQueue} { set socketPlayCmd($state(socketinfo)) {ReplayIfClose Wready {} {}} } - Log ##Log pre newQueue ReInit, - token $token + ##Log pre newQueue ReInit, - token $token # 6. Configure sockets in the queue. foreach tok $newQueue { if {[ReInit $tok]} { @@ -2228,13 +2228,13 @@ proc http::ReplayCore {newQueue} { [expr {$state(-keepalive)?"keepalive":""}] # Initialisation of a new socket. - Log ##Log socket opened, now fconfigure - token $token + ##Log socket opened, now fconfigure - token $token fconfigure $sock -translation {auto crlf} -buffersize $state(-blocksize) - Log ##Log socket opened, DONE fconfigure - token $token + ##Log socket opened, DONE fconfigure - token $token # Connect does its own fconfigure. fileevent $sock writable [list http::Connect $token {*}$tmpConnArgs] - Log #Log ---- $sock << conn to $token for HTTP request (e) + #Log ---- $sock << conn to $token for HTTP request (e) return } @@ -2493,7 +2493,7 @@ proc http::Event {sock token} { set tk [namespace tail $token] while 1 { yield - Log ##Log Event call - token $token + ##Log Event call - token $token if {![info exists state]} { Log "Event $sock with invalid token '$token' - remote close?" @@ -2508,7 +2508,7 @@ proc http::Event {sock token} { return } if {$state(state) eq "connecting"} { - Log ##Log - connecting - token $token + ##Log - connecting - token $token if { $state(reusing) && $state(-pipeline) && ($state(-timeout) > 0) @@ -2540,7 +2540,7 @@ proc http::Event {sock token} { return } } elseif {$nsl >= 0} { - Log ##Log - connecting 1 - token $token + ##Log - connecting 1 - token $token set state(state) "header" } elseif { [eof $sock] && [info exists state(reusing)] @@ -2560,18 +2560,18 @@ proc http::Event {sock token} { # If any other requests are in flight or pipelined/queued, they # will be discarded. } else { - Log ##Log - connecting 2 - token $token + ##Log - connecting 2 - token $token # nsl is -1 so either fblocked (OK) or (eof and not reusing). # Continue. Any eof is processed at the end of this proc. } } elseif {$state(state) eq "header"} { if {[catch {gets $sock line} nhl]} { - Log ##Log header failed - token $token + ##Log header failed - token $token Log ^X$tk end of response (error) - token $token Finish $token $nhl return } elseif {$nhl == 0} { - Log ##Log header done - token $token + ##Log header done - token $token Log ^E$tk end of response headers - token $token # We have now read all headers # We ignore HTTP/1.1 100 Continue returns. RFC2616 sec 8.2.3 @@ -2612,7 +2612,7 @@ proc http::Event {sock token} { } { # The server warns that it will close the socket after this # response. - Log ##Log WARNING - socket will close after response for $token + ##Log WARNING - socket will close after response for $token # Prepare data for a call to ReplayIfClose. if { ($socketRdQueue($state(socketinfo)) ne {}) || ($socketWrQueue($state(socketinfo)) ne {}) @@ -2624,7 +2624,7 @@ proc http::Event {sock token} { set InFlightW Wready } else { set msg "token ${InFlightW} is InFlightW" - Log ##Log $msg - token $token + ##Log $msg - token $token } set socketPlayCmd($state(socketinfo)) \ @@ -2717,7 +2717,7 @@ proc http::Event {sock token} { } } elseif {$nhl > 0} { # Process header lines. - Log ##Log header - token $token - $line + ##Log header - token $token - $line if {[regexp -nocase {^([^:]+):(.+)$} $line x key value]} { switch -- [string tolower $key] { content-type { @@ -2753,11 +2753,11 @@ proc http::Event {sock token} { } } else { # Now reading body - Log ##Log body - token $token + ##Log body - token $token if {[catch { if {[info exists state(-handler)]} { set n [eval $state(-handler) [list $sock $token]] - Log ##Log handler $n - token $token + ##Log handler $n - token $token # N.B. the protocol has been set to 1.0 because the -handler # logic is not expected to handle chunked encoding. # FIXME Allow -handler with 1.1 on dechunked stacked chan. @@ -2819,20 +2819,20 @@ proc http::Event {sock token} { } elseif { [info exists state(transfer)] && ($state(transfer) eq "chunked") } { - Log ##Log chunked - token $token + ##Log chunked - token $token set size 0 set hexLenChunk [getTextLine $sock] #set ntl [string length $hexLenChunk] if {[string trim $hexLenChunk] ne ""} { scan $hexLenChunk %x size if {$size != 0} { - Log ##Log chunk-measure $size - token $token + ##Log chunk-measure $size - token $token set chunk [BlockingRead $sock $size] set n [string length $chunk] if {$n >= 0} { append state(body) $chunk incr state(log_size) [string length $chunk] - Log ##Log chunk $n cumul $state(log_size) -\ + ##Log chunk $n cumul $state(log_size) -\ token $token } if {$size != [string length $chunk]} { @@ -2856,7 +2856,7 @@ proc http::Event {sock token} { } } else { # Line expected to hold chunk length is empty, or eof. - Log ##Log bad-chunk-measure - token $token + ##Log bad-chunk-measure - token $token set n 0 set state(connection) close Log ^X$tk end of response (chunk error) - token $token @@ -2864,7 +2864,7 @@ proc http::Event {sock token} { fetch terminated} } } else { - Log ##Log unchunked - token $token + ##Log unchunked - token $token if {$state(totalsize) == 0} { # We know the transfer is complete only when the server # closes the connection. @@ -2885,13 +2885,13 @@ proc http::Event {sock token} { } set c $state(currentsize) set t $state(totalsize) - Log ##Log non-chunk currentsize $c of totalsize $t -\ + ##Log non-chunk currentsize $c of totalsize $t -\ token $token set block [read $sock $reqSize] set n [string length $block] if {$n >= 0} { append state(body) $block - Log ##Log non-chunk [string length $state(body)] -\ + ##Log non-chunk [string length $state(body)] -\ token $token } } @@ -2902,7 +2902,7 @@ proc http::Event {sock token} { incr state(currentsize) $n set c $state(currentsize) set t $state(totalsize) - Log ##Log another $n currentsize $c totalsize $t -\ + ##Log another $n currentsize $c totalsize $t -\ token $token } # If Content-Length - check for end of data. @@ -2931,7 +2931,7 @@ proc http::Event {sock token} { # catch as an Eot above may have closed the socket already # $state(state) may be connecting, header, body, or complete if {![set cc [catch {eof $sock} eof]] && $eof} { - Log ##Log eof - token $token + ##Log eof - token $token if {[info exists $token]} { set state(connection) close if {$state(state) eq "complete"} { diff --git a/tests/httpPipeline.test b/tests/httpPipeline.test index 4823d19..5eb02d3 100644 --- a/tests/httpPipeline.test +++ b/tests/httpPipeline.test @@ -648,7 +648,7 @@ proc RunTest {header footer delay te} { # If still obscure, uncomment #Log and ##Log lines in the http package. # ------------------------------------------------------------------------------ -setHttpTestOptions -verbose 2 +setHttpTestOptions -verbose 0 # ------------------------------------------------------------------------------ # (4) Define the base URLs used for testing. Each must have a query string. -- cgit v0.12 From 351c77bca3c16380aa5ce476fb96848e0fa63665 Mon Sep 17 00:00:00 2001 From: dgp Date: Tue, 24 Apr 2018 14:02:49 +0000 Subject: silence compiler warning --- generic/tclUtil.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/generic/tclUtil.c b/generic/tclUtil.c index 1890acd..b637a52 100644 --- a/generic/tclUtil.c +++ b/generic/tclUtil.c @@ -3691,7 +3691,6 @@ GetWideForIndex( * representing an index. */ { ClientData cd; - Tcl_WideInt w1, w2; const char *opPtr; int numType, length, t1 = 0, t2 = 0; int code = TclGetNumberFromObj(NULL, objPtr, &cd, &numType); @@ -3745,6 +3744,8 @@ GetWideForIndex( /* Passed the list screen, so parse for index arithmetic expression */ if (TCL_OK == TclParseNumber(NULL, objPtr, NULL, NULL, -1, &opPtr, TCL_PARSE_INTEGER_ONLY)) { + Tcl_WideInt w1=0, w2=0; + /* value starts with valid integer... */ if ((*opPtr == '-') || (*opPtr == '+')) { -- cgit v0.12 From ab49bdfd12dd83f49e1151bcc11015d1d389b21d Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Fri, 27 Apr 2018 03:06:36 +0000 Subject: Added an initialization of 0 for the namelen field for new ZipFile data structures. In memory debugging mode, that value will be something random, not zero on alloc. --- generic/tclZipfs.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c index bb9d45f..e934490 100644 --- a/generic/tclZipfs.c +++ b/generic/tclZipfs.c @@ -943,8 +943,8 @@ ZipFSCloseArchive(Tcl_Interp *interp, ZipFile *zf) zf->tofree = NULL; } zf->data = NULL; - return; - } + return; + } #if defined(_WIN32) || defined(_WIN64) if ((zf->data != NULL) && (zf->tofree == NULL)) { UnmapViewOfFile(zf->data); @@ -1060,7 +1060,7 @@ ZipFS_Find_TOC(Tcl_Interp *interp, int needZip, ZipFile *zf) zf->baseoffsp -= i ? (5 + i) : 0; } } - + return TCL_OK; error: @@ -1096,7 +1096,7 @@ ZipFSOpenArchive(Tcl_Interp *interp, const char *zipname, int needZip, ZipFile * { int i; ClientData handle; - + zf->namelen=0; zf->is_membuf=0; #if defined(_WIN32) || defined(_WIN64) zf->data = NULL; @@ -1210,7 +1210,7 @@ ZipFS_Catalogue_Filesystem(Tcl_Interp *interp, ZipFile *zf0, const char *mntpt, int drive = 0; #endif WriteLock(); - + pwlen = 0; if (passwd != NULL) { pwlen = strlen(passwd); @@ -1542,7 +1542,7 @@ TclZipfs_Mount( Unlock(); return ret; } - + if (zipname == NULL) { Tcl_HashEntry *hPtr; if (interp == NULL) { @@ -1639,7 +1639,7 @@ TclZipfs_Mount_Buffer( Unlock(); return ret; } - + if (data == NULL) { Tcl_HashEntry *hPtr; @@ -1719,7 +1719,7 @@ TclZipfs_Unmount(Tcl_Interp *interp, const char *mntpt) */ Tcl_DStringInit(&dsm); mntpt = CanonicalPath("", mntpt, &dsm, 1); - + hPtr = Tcl_FindHashEntry(&ZipFS.zipHash, mntpt); /* don't report error */ @@ -1817,7 +1817,7 @@ ZipFSMountBufferObjCmd( Tcl_HashSearch search; int ret = TCL_OK; ZipFile *zf; - + ReadLock(); i = 0; hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); @@ -2970,7 +2970,7 @@ Tcl_Obj *TclZipfs_TclLibrary(void) { } else { Tcl_Obj *vfsinitscript; int found=0; - + /* Look for the library file system within the executable */ vfsinitscript=Tcl_NewStringObj(ZIPFS_APP_MOUNT "/tcl_library/init.tcl",-1); Tcl_IncrRefCount(vfsinitscript); @@ -4570,7 +4570,7 @@ int TclZipfs_AppHook(int *argc, char ***argv) */ int -TclZipfs_Mount(Tcl_Interp *interp, const char *mntpt, const char *zipname, +TclZipfs_Mount(Tcl_Interp *interp, const char *mntpt, const char *zipname, const char *passwd) { return TclZipfs_Init(interp, 1); -- cgit v0.12 -- cgit v0.12 From c2fceada6c1e45c299dacdbe6111f97c41b68c98 Mon Sep 17 00:00:00 2001 From: fbonnet Date: Sun, 13 May 2018 22:15:36 +0000 Subject: Initial implementation of TIP #508: [array default] --- generic/tclExecute.c | 5 +- generic/tclInt.h | 6 ++ generic/tclVar.c | 288 ++++++++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 278 insertions(+), 21 deletions(-) diff --git a/generic/tclExecute.c b/generic/tclExecute.c index fda50b2..7d7384f 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -4070,10 +4070,7 @@ TEBCresume( TRACE_ERROR(interp); goto gotError; } - TclSetVarArray(varPtr); - varPtr->value.tablePtr = ckalloc(sizeof(TclVarHashTable)); - TclInitVarHashTable(varPtr->value.tablePtr, - TclGetVarNsPtr(varPtr)); + TclInitArrayVar(varPtr); #ifdef TCL_COMPILE_DEBUG TRACE_APPEND(("done\n")); } else { diff --git a/generic/tclInt.h b/generic/tclInt.h index 8f5d8ba..c0630ef 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -4100,6 +4100,12 @@ MODULE_SCOPE TclProcessWaitStatus TclProcessWait(Tcl_Pid pid, int options, Tcl_Obj **errorObjPtr); /* + * TIP #508: [array default] + */ + +MODULE_SCOPE void TclInitArrayVar(Var *arrayPtr); + +/* * Utility routines for encoding index values as integers. Used by both * some of the command compilers and by [lsort] and [lsearch]. */ diff --git a/generic/tclVar.c b/generic/tclVar.c index d5e0fa1..78188d2 100644 --- a/generic/tclVar.c +++ b/generic/tclVar.c @@ -198,6 +198,17 @@ static void UnsetVarStruct(Var *varPtr, Var *arrayPtr, Tcl_Obj *part2Ptr, int flags, int index); /* + * TIP #508: [array default] + */ + +static int ArrayDefaultCmd(ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *const objv[]); +static void DeleteArrayVar(Var *arrayPtr); +static Tcl_Obj * GetArrayDefault(Var *arrayPtr); +static void SetArrayDefault(Var *arrayPtr, Tcl_Obj *defaultObj); + +/* * Functions defined in this file that may be exported in the future for use * by the bytecode compiler and engine or to the public interface. */ @@ -1015,8 +1026,6 @@ TclLookupArrayElement( { int isNew; Var *varPtr; - TclVarHashTable *tablePtr; - Namespace *nsPtr; /* * We're dealing with an array element. Make sure the variable is an array @@ -1049,16 +1058,7 @@ TclLookupArrayElement( return NULL; } - TclSetVarArray(arrayPtr); - tablePtr = ckalloc(sizeof(TclVarHashTable)); - arrayPtr->value.tablePtr = tablePtr; - - if (TclIsVarInHash(arrayPtr) && TclGetVarNsPtr(arrayPtr)) { - nsPtr = TclGetVarNsPtr(arrayPtr); - } else { - nsPtr = NULL; - } - TclInitVarHashTable(arrayPtr->value.tablePtr, nsPtr); + TclInitArrayVar(arrayPtr); } else if (!TclIsVarArray(arrayPtr)) { if (flags & TCL_LEAVE_ERR_MSG) { TclObjVarErrMsg(interp, arrayNamePtr, elNamePtr, msg, needArray, @@ -1408,6 +1408,13 @@ TclPtrGetVarIdx( return varPtr->value.objPtr; } + /* + * Return the array default value if any. + */ + if (arrayPtr && TclIsVarArray(arrayPtr) && GetArrayDefault(arrayPtr)) { + return GetArrayDefault(arrayPtr); + } + if (flags & TCL_LEAVE_ERR_MSG) { if (TclIsVarUndefined(varPtr) && arrayPtr && !TclIsVarUndefined(arrayPtr)) { @@ -4074,9 +4081,7 @@ ArraySetCmd( return TCL_ERROR; } } - TclSetVarArray(varPtr); - varPtr->value.tablePtr = ckalloc(sizeof(TclVarHashTable)); - TclInitVarHashTable(varPtr->value.tablePtr, TclGetVarNsPtr(varPtr)); + TclInitArrayVar(varPtr); return TCL_OK; } @@ -4356,6 +4361,7 @@ TclInitArrayCmd( { static const EnsembleImplMap arrayImplMap[] = { {"anymore", ArrayAnyMoreCmd, TclCompileBasic2ArgCmd, NULL, NULL, 0}, + {"default", ArrayDefaultCmd, TclCompileBasic2Or3ArgCmd, NULL, NULL, 0}, {"donesearch", ArrayDoneSearchCmd, TclCompileBasic2ArgCmd, NULL, NULL, 0}, {"exists", ArrayExistsCmd, TclCompileArrayExistsCmd, NULL, NULL, 0}, {"for", ArrayForObjCmd, TclCompileBasic3ArgCmd, ArrayForNRCmd, NULL, 0}, @@ -5546,8 +5552,7 @@ DeleteArray( TclClearVarNamespaceVar(elPtr); } - VarHashDeleteTable(varPtr->value.tablePtr); - ckfree(varPtr->value.tablePtr); + DeleteArrayVar(varPtr); } /* @@ -6436,6 +6441,255 @@ CompareVarKeys( } /* + * TIP #508: [array default] + */ + +/* + * The following structure extends the regular TclVarHashTable used by array + * variables to store their optional default value. + */ + +typedef struct ArrayVarHashTable { + TclVarHashTable table; + Tcl_Obj *defaultObj; +} ArrayVarHashTable; + +/*---------------------------------------------------------------------- + * + * ArrayDefaultCmd -- + * + * This function implements the 'array default' Tcl command. + * Refer to the user documentation for details on what it does. + * + * Results: + * Returns a standard Tcl result. + * + * Side effects: + * See the user documentation. + * + *---------------------------------------------------------------------- + */ + + /* ARGSUSED */ +static int +ArrayDefaultCmd( + ClientData clientData, /* Not used. */ + Tcl_Interp *interp, /* Current interpreter. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument objects. */ +{ + static const char *const options[] = { + "get", "set", "exists", "unset", NULL + }; + enum options { OPT_GET, OPT_SET, OPT_EXISTS, OPT_UNSET }; + Tcl_Obj *arrayNameObj, *defaultValueObj; + Var *varPtr, *arrayPtr; + int isArray, option; + + /* + * Parse arguments. + */ + + if (objc != 3 && objc != 4) { + Tcl_WrongNumArgs(interp, 1, objv, "option arrayName ?value?"); + return TCL_ERROR; + } + if (Tcl_GetIndexFromObj(interp, objv[1], options, "option", + 0, &option) != TCL_OK) { + return TCL_ERROR; + } + + arrayNameObj = objv[2]; + + if (TCL_ERROR == LocateArray(interp, arrayNameObj, &varPtr, &isArray)) { + return TCL_ERROR; + } + + switch (option) { + case OPT_GET: + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "arrayName"); + return TCL_ERROR; + } + if (!varPtr || !isArray) { + return NotArrayError(interp, arrayNameObj); + } + + defaultValueObj = GetArrayDefault(varPtr); + if (!defaultValueObj) { + /* Array default must exist. */ + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "array has no default value", -1)); + Tcl_SetErrorCode(interp, "TCL", "READ", "ARRAY", "DEFAULT", NULL); + return TCL_ERROR; + } + Tcl_SetObjResult(interp, defaultValueObj); + return TCL_OK; + + case OPT_SET: + if (objc != 4) { + Tcl_WrongNumArgs(interp, 2, objv, "arrayName value"); + return TCL_ERROR; + } + + /* + * Attempt to create array if needed. + */ + varPtr = TclObjLookupVarEx(interp, arrayNameObj, NULL, + /*flags*/ TCL_LEAVE_ERR_MSG, /*msg*/ "array default set", + /*createPart1*/ 1, /*createPart2*/ 1, &arrayPtr); + if (varPtr == NULL) { + return TCL_ERROR; + } + if (arrayPtr) { + /* + * Not a valid array name. + */ + + CleanupVar(varPtr, arrayPtr); + TclObjVarErrMsg(interp, arrayNameObj, NULL, "array default set", needArray, -1); + Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "VARNAME", + TclGetString(arrayNameObj), NULL); + return TCL_ERROR; + } + if (!TclIsVarArray(varPtr) && !TclIsVarUndefined(varPtr)) { + /* + * Not an array. + */ + + TclObjVarErrMsg(interp, arrayNameObj, NULL, "array default set", + needArray, -1); + Tcl_SetErrorCode(interp, "TCL", "WRITE", "ARRAY", NULL); + return TCL_ERROR; + } + + if (!TclIsVarArray(varPtr)) { + TclInitArrayVar(varPtr); + } + defaultValueObj = objv[3]; + SetArrayDefault(varPtr, defaultValueObj); + return TCL_OK; + + case OPT_EXISTS: + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "arrayName"); + return TCL_ERROR; + } + if (varPtr && !isArray) { + return NotArrayError(interp, arrayNameObj); + } + + if (!varPtr) { + Tcl_SetObjResult(interp, Tcl_NewBooleanObj(0)); + } else { + defaultValueObj = GetArrayDefault(varPtr); + Tcl_SetObjResult(interp, Tcl_NewBooleanObj(!!defaultValueObj)); + } + return TCL_OK; + + case OPT_UNSET: + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "arrayName"); + return TCL_ERROR; + } + if (varPtr && !isArray) { + return NotArrayError(interp, arrayNameObj); + } + + if (varPtr) { + SetArrayDefault(varPtr, NULL); + } + return TCL_OK; + } + + /* Unreached */ + return TCL_ERROR; +} + +/* + * Initialize array variable. + */ + +void +TclInitArrayVar( + Var *arrayPtr) +{ + ArrayVarHashTable *tablePtr; + + TclSetVarArray(arrayPtr); + + tablePtr = ckalloc(sizeof(ArrayVarHashTable)); + + // Regular TclVarHashTable initialization. + arrayPtr->value.tablePtr = (TclVarHashTable *) tablePtr; + TclInitVarHashTable(arrayPtr->value.tablePtr, TclGetVarNsPtr(arrayPtr)); + + // Default value initialization. + tablePtr->defaultObj = NULL; +} + +/* + * Cleanup array variable. + */ + +static void +DeleteArrayVar( + Var *arrayPtr) +{ + ArrayVarHashTable *tablePtr = (ArrayVarHashTable *) arrayPtr->value.tablePtr; + + // Default value cleanup. + SetArrayDefault(arrayPtr, NULL); + + // Regular TclVarHashTable cleanup. + VarHashDeleteTable(arrayPtr->value.tablePtr); + + ckfree(tablePtr); +} + +/* + * Get array default value if any. + */ + +static Tcl_Obj * +GetArrayDefault( + Var *arrayPtr) +{ + ArrayVarHashTable *tablePtr = (ArrayVarHashTable *) arrayPtr->value.tablePtr; + return tablePtr->defaultObj; +} + +/* + * Set/replace/unset array default value. + */ + +static void +SetArrayDefault( + Var *arrayPtr, + Tcl_Obj *defaultObj) +{ + ArrayVarHashTable *tablePtr = (ArrayVarHashTable *) arrayPtr->value.tablePtr; + + /* + * Increment/decrement refcount twice to ensure that the object is shared, + * so that it doesn't get modified accidentally by the folling code: + * + * array default set v 1 + * lappend v(a) 2; # returns a new object {1 2} + * set v(b); # returns the original default object "1" + */ + if (tablePtr->defaultObj) { + Tcl_DecrRefCount(tablePtr->defaultObj); + Tcl_DecrRefCount(tablePtr->defaultObj); + } + tablePtr->defaultObj = defaultObj; + if (tablePtr->defaultObj) { + Tcl_IncrRefCount(tablePtr->defaultObj); + Tcl_IncrRefCount(tablePtr->defaultObj); + } +} + +/* * Local Variables: * mode: c * c-basic-offset: 4 -- cgit v0.12 -- cgit v0.12 From b91a2765aef7499e3bf0ca35d47c6dc068c35ed6 Mon Sep 17 00:00:00 2001 From: fbonnet Date: Fri, 25 May 2018 19:43:23 +0000 Subject: TIP #509: Implement reentrant mutexes on all platforms --- unix/configure | 78 ++++++++++++++++++++++++++- unix/tcl.m4 | 3 ++ unix/tclUnixThrd.c | 156 +++++++++++++++++++++++++++++++++++++++++++++-------- 3 files changed, 213 insertions(+), 24 deletions(-) diff --git a/unix/configure b/unix/configure index 36bc4b9..11c04c3 100755 --- a/unix/configure +++ b/unix/configure @@ -730,6 +730,7 @@ infodir docdir oldincludedir includedir +runstatedir localstatedir sharedstatedir sysconfdir @@ -817,6 +818,7 @@ datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' +runstatedir='${localstatedir}/run' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' @@ -1069,6 +1071,15 @@ do | -silent | --silent | --silen | --sile | --sil) silent=yes ;; + -runstatedir | --runstatedir | --runstatedi | --runstated \ + | --runstate | --runstat | --runsta | --runst | --runs \ + | --run | --ru | --r) + ac_prev=runstatedir ;; + -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ + | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ + | --run=* | --ru=* | --r=*) + runstatedir=$ac_optarg ;; + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ @@ -1206,7 +1217,7 @@ fi for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ - libdir localedir mandir + libdir localedir mandir runstatedir do eval ac_val=\$$ac_var # Remove trailing slashes. @@ -1359,6 +1370,7 @@ Fine tuning of the installation directories: --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] @@ -1856,6 +1868,52 @@ $as_echo "$ac_res" >&6; } } # ac_fn_c_check_func +# ac_fn_c_check_decl LINENO SYMBOL VAR INCLUDES +# --------------------------------------------- +# Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR +# accordingly. +ac_fn_c_check_decl () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + as_decl_name=`echo $2|sed 's/ *(.*//'` + as_decl_use=`echo $2|sed -e 's/(/((/' -e 's/)/) 0&/' -e 's/,/) 0& (/g'` + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $as_decl_name is declared" >&5 +$as_echo_n "checking whether $as_decl_name is declared... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +#ifndef $as_decl_name +#ifdef __cplusplus + (void) $as_decl_use; +#else + (void) $as_decl_name; +#endif +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_decl + # ac_fn_c_check_type LINENO TYPE VAR INCLUDES # ------------------------------------------- # Tests whether TYPE exists after having included INCLUDES, setting cache @@ -4224,6 +4282,24 @@ $as_echo "yes" >&6; } $as_echo "no" >&6; } fi + ac_fn_c_check_decl "$LINENO" "PTHREAD_MUTEX_RECURSIVE" "ac_cv_have_decl_PTHREAD_MUTEX_RECURSIVE" "#include +" +if test "x$ac_cv_have_decl_PTHREAD_MUTEX_RECURSIVE" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_PTHREAD_MUTEX_RECURSIVE $ac_have_decl +_ACEOF +if test $ac_have_decl = 1; then : + tcl_ok=yes +else + tcl_ok=no +fi + + diff --git a/unix/tcl.m4 b/unix/tcl.m4 index 4acbed0..6d650ea 100644 --- a/unix/tcl.m4 +++ b/unix/tcl.m4 @@ -696,6 +696,9 @@ AC_DEFUN([SC_ENABLE_THREADS], [ AC_MSG_RESULT([no]) fi + # TIP #509. + AC_CHECK_DECLS([PTHREAD_MUTEX_RECURSIVE],tcl_ok=yes,tcl_ok=no, [[#include ]]) + AC_SUBST(TCL_THREADS) ]) diff --git a/unix/tclUnixThrd.c b/unix/tclUnixThrd.c index 120d5d5..3d3f81d 100644 --- a/unix/tclUnixThrd.c +++ b/unix/tclUnixThrd.c @@ -15,6 +15,109 @@ #ifdef TCL_THREADS +/* + * TIP #509. + */ + +#if defined(HAVE_DECL_PTHREAD_MUTEX_RECURSIVE) \ + && HAVE_DECL_PTHREAD_MUTEX_RECURSIVE +/* + * Pthread has native reentrant (AKA recursive) mutexes. Use them for Tcl_Mutex. + */ + +typedef pthread_mutex_t PMutex; + +static void +PMutexInit( + PMutex *pmutexPtr +) +{ + pthread_mutexattr_t attr; + pthread_mutexattr_init(&attr); + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); + pthread_mutex_init(pmutexPtr, &attr); +} + +#define PMutexDestroy pthread_mutex_destroy +#define PMutexLock pthread_mutex_lock +#define PMutexUnlock pthread_mutex_unlock +#define PCondWait pthread_cond_wait +#define PCondTimedWait pthread_cond_timedwait + +#else /* HAVE_PTHREAD_MUTEX_RECURSIVE */ + +/* + * No native support for reentrant mutexes. Emulate them with regular mutexes + * and thread-local counters. + */ + +typedef struct PMutex { + pthread_mutex_t mutex; + pthread_key_t counter; +} PMutex; + +static void +PMutexInit( + PMutex *pmutexPtr +) +{ + pthread_mutex_init(&pmutexPtr->mutex, NULL); + pthread_key_create(&pmutexPtr->counter, NULL); +} + +static void +PMutexDestroy( + PMutex *pmutexPtr +) +{ + pthread_mutex_destroy(&pmutexPtr->mutex); + pthread_key_delete(pmutexPtr->counter); +} + +static void +PMutexLock( + PMutex *pmutexPtr +) +{ + intptr_t count = (intptr_t)pthread_getspecific(pmutexPtr->counter); + pthread_setspecific(pmutexPtr->counter, (const void *)(count+1)); + if (count == 0) { + pthread_mutex_lock(&pmutexPtr->mutex); + } +} + +static void +PMutexUnlock( + PMutex *pmutexPtr +) +{ + intptr_t count = (intptr_t)pthread_getspecific(pmutexPtr->counter); + pthread_setspecific(pmutexPtr->counter, (const void *)(count-1)); + if (count == 1) { + pthread_mutex_unlock(&pmutexPtr->mutex); + } +} + +static void +PCondWait( + pthread_cond_t *pcondPtr, + PMutex *pmutexPtr +) +{ + pthread_cond_wait(pcondPtr, &pmutexPtr->mutex); +} + +static void +PCondTimedWait( + pthread_cond_t *pcondPtr, + PMutex *pmutexPtr, + struct timespec *ptime +) +{ + pthread_cond_timedwait(pcondPtr, &pmutexPtr->mutex, ptime); +} +#endif /* HAVE_PTHREAD_MUTEX_RECURSIVE */ + #ifndef TCL_NO_DEPRECATED typedef struct { char nabuf[16]; @@ -43,8 +146,14 @@ static pthread_mutex_t initLock = PTHREAD_MUTEX_INITIALIZER; * obvious reasons, cannot use any dyamically allocated storage. */ -static pthread_mutex_t allocLock = PTHREAD_MUTEX_INITIALIZER; -static pthread_mutex_t *allocLockPtr = &allocLock; +static PMutex allocLock; +static pthread_once_t allocLockInitOnce = PTHREAD_ONCE_INIT; +static void +allocLockInit() +{ + PMutexInit(&allocLock); +} +static PMutex *allocLockPtr = &allocLock; #endif /* TCL_THREADS */ @@ -379,7 +488,8 @@ Tcl_Mutex * Tcl_GetAllocMutex(void) { #ifdef TCL_THREADS - pthread_mutex_t **allocLockPtrPtr = &allocLockPtr; + PMutex **allocLockPtrPtr = &allocLockPtr; + pthread_once(&allocLockInitOnce, allocLockInit); return (Tcl_Mutex *) allocLockPtrPtr; #else return NULL; @@ -411,9 +521,9 @@ Tcl_GetAllocMutex(void) void Tcl_MutexLock( - Tcl_Mutex *mutexPtr) /* Really (pthread_mutex_t **) */ + Tcl_Mutex *mutexPtr) /* Really (PMutex **) */ { - pthread_mutex_t *pmutexPtr; + PMutex *pmutexPtr; if (*mutexPtr == NULL) { pthread_mutex_lock(&masterLock); @@ -422,15 +532,15 @@ Tcl_MutexLock( * Double inside master lock check to avoid a race condition. */ - pmutexPtr = ckalloc(sizeof(pthread_mutex_t)); - pthread_mutex_init(pmutexPtr, NULL); + pmutexPtr = ckalloc(sizeof(PMutex)); + PMutexInit(pmutexPtr); *mutexPtr = (Tcl_Mutex)pmutexPtr; TclRememberMutex(mutexPtr); } pthread_mutex_unlock(&masterLock); } - pmutexPtr = *((pthread_mutex_t **)mutexPtr); - pthread_mutex_lock(pmutexPtr); + pmutexPtr = *((PMutex **)mutexPtr); + PMutexLock(pmutexPtr); } /* @@ -452,11 +562,11 @@ Tcl_MutexLock( void Tcl_MutexUnlock( - Tcl_Mutex *mutexPtr) /* Really (pthread_mutex_t **) */ + Tcl_Mutex *mutexPtr) /* Really (PMutex **) */ { - pthread_mutex_t *pmutexPtr = *(pthread_mutex_t **) mutexPtr; + PMutex *pmutexPtr = *(PMutex **) mutexPtr; - pthread_mutex_unlock(pmutexPtr); + PMutexUnlock(pmutexPtr); } /* @@ -482,10 +592,10 @@ void TclpFinalizeMutex( Tcl_Mutex *mutexPtr) { - pthread_mutex_t *pmutexPtr = *(pthread_mutex_t **) mutexPtr; + PMutex *pmutexPtr = *(PMutex **) mutexPtr; if (pmutexPtr != NULL) { - pthread_mutex_destroy(pmutexPtr); + PMutexDestroy(pmutexPtr); ckfree(pmutexPtr); *mutexPtr = NULL; } @@ -516,11 +626,11 @@ TclpFinalizeMutex( void Tcl_ConditionWait( Tcl_Condition *condPtr, /* Really (pthread_cond_t **) */ - Tcl_Mutex *mutexPtr, /* Really (pthread_mutex_t **) */ + Tcl_Mutex *mutexPtr, /* Really (PMutex **) */ const Tcl_Time *timePtr) /* Timeout on waiting period */ { pthread_cond_t *pcondPtr; - pthread_mutex_t *pmutexPtr; + PMutex *pmutexPtr; struct timespec ptime; if (*condPtr == NULL) { @@ -539,10 +649,10 @@ Tcl_ConditionWait( } pthread_mutex_unlock(&masterLock); } - pmutexPtr = *((pthread_mutex_t **)mutexPtr); + pmutexPtr = *((PMutex **)mutexPtr); pcondPtr = *((pthread_cond_t **)condPtr); if (timePtr == NULL) { - pthread_cond_wait(pcondPtr, pmutexPtr); + PCondWait(pcondPtr, pmutexPtr); } else { Tcl_Time now; @@ -555,7 +665,7 @@ Tcl_ConditionWait( ptime.tv_sec = timePtr->sec + now.sec + (timePtr->usec + now.usec) / 1000000; ptime.tv_nsec = 1000 * ((timePtr->usec + now.usec) % 1000000); - pthread_cond_timedwait(pcondPtr, pmutexPtr, &ptime); + PCondTimedWait(pcondPtr, pmutexPtr, &ptime); } } @@ -681,14 +791,14 @@ static pthread_key_t key; typedef struct { Tcl_Mutex tlock; - pthread_mutex_t plock; + PMutex plock; } allocMutex; Tcl_Mutex * TclpNewAllocMutex(void) { allocMutex *lockPtr; - register pthread_mutex_t *plockPtr; + register PMutex *plockPtr; lockPtr = malloc(sizeof(allocMutex)); if (lockPtr == NULL) { @@ -696,7 +806,7 @@ TclpNewAllocMutex(void) } plockPtr = &lockPtr->plock; lockPtr->tlock = (Tcl_Mutex) plockPtr; - pthread_mutex_init(&lockPtr->plock, NULL); + PMutexInit(&lockPtr->plock); return &lockPtr->tlock; } @@ -708,7 +818,7 @@ TclpFreeAllocMutex( if (!lockPtr) { return; } - pthread_mutex_destroy(&lockPtr->plock); + PMutexDestroy(&lockPtr->plock); free(lockPtr); } -- cgit v0.12 From 754bb107b4100f394d445d589dddc94e59dd2d04 Mon Sep 17 00:00:00 2001 From: kjnash Date: Fri, 1 Jun 2018 18:34:07 +0000 Subject: Bugfix - always cleanup persistent socket. --- library/http/http.tcl | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/library/http/http.tcl b/library/http/http.tcl index d16a8d9..c177374 100644 --- a/library/http/http.tcl +++ b/library/http/http.tcl @@ -264,8 +264,10 @@ proc http::Finish {token {errormsg ""} {skipCB 0}} { || ([info exists state(-keepalive)] && !$state(-keepalive)) || ([info exists state(connection)] && ($state(connection) eq "close")) } { - CloseSocket $state(sock) $token set closeQueue 1 + set connId $state(socketinfo) + set sock $state(sock) + CloseSocket $state(sock) $token } elseif { ([info exists state(-keepalive)] && $state(-keepalive)) && ([info exists state(connection)] && ($state(connection) ne "close")) @@ -286,11 +288,10 @@ proc http::Finish {token {errormsg ""} {skipCB 0}} { } if { $closeQueue - && [info exists state(socketinfo)] - && [info exists socketMapping($state(socketinfo))] - && ($socketMapping($state(socketinfo)) eq $state(sock)) + && [info exists socketMapping($connId)] + && ($socketMapping($connId) eq $sock) } { - http::CloseQueuedQueries $state(socketinfo) $token + http::CloseQueuedQueries $connId $token } return -- cgit v0.12 From 240e6b50d2dfd9d501eeb3e180be594f51f6f03c Mon Sep 17 00:00:00 2001 From: sebres Date: Mon, 4 Jun 2018 13:49:38 +0000 Subject: fixes [92564326a9] if compiled on some x86 systems (with dirent64 but without DIR64, partially cherry-picked from https://www.androwish.org/index.html/info/6119b8ac2aee8411). --- unix/configure | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++++ unix/tcl.m4 | 11 ++++++++- unix/tclConfig.h.in | 3 +++ unix/tclUnixPort.h | 13 ++++++----- 4 files changed, 85 insertions(+), 6 deletions(-) diff --git a/unix/configure b/unix/configure index 7ff9f72..61d922a 100755 --- a/unix/configure +++ b/unix/configure @@ -9643,6 +9643,70 @@ _ACEOF fi + echo "$as_me:$LINENO: checking for DIR64" >&5 +echo $ECHO_N "checking for DIR64... $ECHO_C" >&6 +if test "${tcl_cv_DIR64+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +int +main () +{ +struct dirent64 *p; DIR64 d = opendir64("."); + p = readdir64(d); rewinddir64(d); closedir64(d); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + tcl_cv_DIR64=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +tcl_cv_DIR64=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $tcl_cv_DIR64" >&5 +echo "${ECHO_T}$tcl_cv_DIR64" >&6 + if test "x${tcl_cv_DIR64}" = "xyes" ; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_DIR64 1 +_ACEOF + + fi + echo "$as_me:$LINENO: checking for struct stat64" >&5 echo $ECHO_N "checking for struct stat64... $ECHO_C" >&6 if test "${tcl_cv_struct_stat64+set}" = set; then diff --git a/unix/tcl.m4 b/unix/tcl.m4 index 6b6d373..294ecf0 100644 --- a/unix/tcl.m4 +++ b/unix/tcl.m4 @@ -2749,7 +2749,7 @@ AC_DEFUN([SC_TCL_EARLY_FLAGS],[ # Might define the following vars: # TCL_WIDE_INT_IS_LONG # TCL_WIDE_INT_TYPE -# HAVE_STRUCT_DIRENT64 +# HAVE_STRUCT_DIRENT64, HAVE_DIR64 # HAVE_STRUCT_STAT64 # HAVE_TYPE_OFF64_T # @@ -2785,6 +2785,15 @@ AC_DEFUN([SC_TCL_64BIT_FLAGS], [ AC_DEFINE(HAVE_STRUCT_DIRENT64, 1, [Is 'struct dirent64' in ?]) fi + AC_CACHE_CHECK([for DIR64], tcl_cv_DIR64,[ + AC_TRY_COMPILE([#include +#include ],[struct dirent64 *p; DIR64 d = opendir64("."); + p = readdir64(d); rewinddir64(d); closedir64(d);], + tcl_cv_DIR64=yes,tcl_cv_DIR64=no)]) + if test "x${tcl_cv_DIR64}" = "xyes" ; then + AC_DEFINE(HAVE_DIR64, 1, [Is 'DIR64' in ?]) + fi + AC_CACHE_CHECK([for struct stat64], tcl_cv_struct_stat64,[ AC_TRY_COMPILE([#include ],[struct stat64 p; ], diff --git a/unix/tclConfig.h.in b/unix/tclConfig.h.in index 9774ce9..0879c7a 100644 --- a/unix/tclConfig.h.in +++ b/unix/tclConfig.h.in @@ -193,6 +193,9 @@ /* Is 'struct dirent64' in ? */ #undef HAVE_STRUCT_DIRENT64 +/* Is 'DIR64' in ? */ +#undef HAVE_DIR64 + /* Is 'struct stat64' in ? */ #undef HAVE_STRUCT_STAT64 diff --git a/unix/tclUnixPort.h b/unix/tclUnixPort.h index a248213..9a923ef 100644 --- a/unix/tclUnixPort.h +++ b/unix/tclUnixPort.h @@ -58,16 +58,19 @@ */ #ifdef HAVE_STRUCT_DIRENT64 -typedef DIR64 TclDIR; -typedef struct dirent64 Tcl_DirEntry; +typedef struct dirent64 Tcl_DirEntry; # define TclOSreaddir readdir64 +#else +typedef struct dirent Tcl_DirEntry; +# define TclOSreaddir readdir +#endif +#ifdef HAVE_DIR64 +typedef DIR64 TclDIR; # define TclOSopendir opendir64 # define TclOSrewinddir rewinddir64 # define TclOSclosedir closedir64 #else -typedef DIR TclDIR; -typedef struct dirent Tcl_DirEntry; -# define TclOSreaddir readdir +typedef DIR TclDIR; # define TclOSopendir opendir # define TclOSrewinddir rewinddir # define TclOSclosedir closedir -- cgit v0.12 From 3b14a4b0ed16f753791f2c6046b761c4fcd5be05 Mon Sep 17 00:00:00 2001 From: sebres Date: Tue, 5 Jun 2018 09:10:56 +0000 Subject: re-autoconfigure with v.2.69 --- unix/configure | 66 +++++++++++++++++++++------------------------------------- 1 file changed, 24 insertions(+), 42 deletions(-) diff --git a/unix/configure b/unix/configure index 2f5f72d..101c7f4 100755 --- a/unix/configure +++ b/unix/configure @@ -729,6 +729,7 @@ infodir docdir oldincludedir includedir +runstatedir localstatedir sharedstatedir sysconfdir @@ -815,6 +816,7 @@ datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' +runstatedir='${localstatedir}/run' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' @@ -1067,6 +1069,15 @@ do | -silent | --silent | --silen | --sile | --sil) silent=yes ;; + -runstatedir | --runstatedir | --runstatedi | --runstated \ + | --runstate | --runstat | --runsta | --runst | --runs \ + | --run | --ru | --r) + ac_prev=runstatedir ;; + -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ + | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ + | --run=* | --ru=* | --r=*) + runstatedir=$ac_optarg ;; + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ @@ -1204,7 +1215,7 @@ fi for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ - libdir localedir mandir + libdir localedir mandir runstatedir do eval ac_val=\$$ac_var # Remove trailing slashes. @@ -1357,6 +1368,7 @@ Fine tuning of the installation directories: --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] @@ -6868,17 +6880,13 @@ $as_echo "#define HAVE_STRUCT_DIRENT64 1" >>confdefs.h fi - echo "$as_me:$LINENO: checking for DIR64" >&5 -echo $ECHO_N "checking for DIR64... $ECHO_C" >&6 -if test "${tcl_cv_DIR64+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for DIR64" >&5 +$as_echo_n "checking for DIR64... " >&6; } +if ${tcl_cv_DIR64+:} false; then : + $as_echo_n "(cached) " >&6 else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include @@ -6891,44 +6899,18 @@ struct dirent64 *p; DIR64 d = opendir64("."); return 0; } _ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -z "$ac_c_werror_flag" - || test ! -s conftest.err' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then +if ac_fn_c_try_compile "$LINENO"; then : tcl_cv_DIR64=yes else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -tcl_cv_DIR64=no + tcl_cv_DIR64=no fi -rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi -echo "$as_me:$LINENO: result: $tcl_cv_DIR64" >&5 -echo "${ECHO_T}$tcl_cv_DIR64" >&6 +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_DIR64" >&5 +$as_echo "$tcl_cv_DIR64" >&6; } if test "x${tcl_cv_DIR64}" = "xyes" ; then -cat >>confdefs.h <<\_ACEOF -#define HAVE_DIR64 1 -_ACEOF +$as_echo "#define HAVE_DIR64 1" >>confdefs.h fi -- cgit v0.12 From c2e16d9b1f9dea745ffe57948997ba3ded2e58a5 Mon Sep 17 00:00:00 2001 From: sebres Date: Tue, 5 Jun 2018 21:59:09 +0000 Subject: amend to [eeefdb44cf]: fixes missing install path (closes [593aa7c421]) for mingw/*nix --- unix/Makefile.in | 2 +- win/Makefile.in | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/unix/Makefile.in b/unix/Makefile.in index e1d7d65..f044e41 100644 --- a/unix/Makefile.in +++ b/unix/Makefile.in @@ -830,7 +830,7 @@ install-libraries: libraries else true; \ fi; \ done; - @for i in opt0.4 encoding ../tcl8 ../tcl8/8.4 ../tcl8/8.4/platform ../tcl8/8.5 ../tcl8/8.6; \ + @for i in opt0.4 encoding ../tcl8 ../tcl8/8.4 ../tcl8/8.4/platform ../tcl8/8.5 ../tcl8/8.6 ../tcl8/8.7; \ do \ if [ ! -d "$(SCRIPT_INSTALL_DIR)"/$$i ] ; then \ echo "Making directory $(SCRIPT_INSTALL_DIR)/$$i"; \ diff --git a/win/Makefile.in b/win/Makefile.in index bf9ab8c..4e75b06 100644 --- a/win/Makefile.in +++ b/win/Makefile.in @@ -635,7 +635,7 @@ install-libraries: libraries install-tzdata install-msgs else true; \ fi; \ done; - @for i in opt0.4 encoding ../tcl8 ../tcl8/8.4 ../tcl8/8.4/platform ../tcl8/8.5 ../tcl8/8.6; \ + @for i in opt0.4 encoding ../tcl8 ../tcl8/8.4 ../tcl8/8.4/platform ../tcl8/8.5 ../tcl8/8.6 ../tcl8/8.7; \ do \ if [ ! -d $(SCRIPT_INSTALL_DIR)/$$i ] ; then \ echo "Making directory $(SCRIPT_INSTALL_DIR)/$$i"; \ -- cgit v0.12 From 4755be8f419815dd933db195d13761b2c69ab480 Mon Sep 17 00:00:00 2001 From: pooryorick Date: Thu, 7 Jun 2018 20:59:27 +0000 Subject: Give tests more time to finish since valgrind slows things down considerably. --- tests/async.test | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/tests/async.test b/tests/async.test index 6de814b..fa3aae1 100644 --- a/tests/async.test +++ b/tests/async.test @@ -159,10 +159,12 @@ test async-4.1 {async interrupting bytecode sequence} -constraints { global aresult set aresult {Async event not delivered} testasync marklater $handle - for {set i 0} { - $i < 2500000 && $aresult eq "Async event not delivered" - } {incr i} { - nothing + # allow plenty of time to pass in case valgrind is running + set start [clock seconds] + while { + [clock seconds] - $start < 180 && $aresult eq "Async event not delivered" + } { + nothing } return $aresult }} $hm @@ -178,9 +180,12 @@ test async-4.2 {async interrupting straight bytecode sequence} -constraints { global aresult set aresult {Async event not delivered} testasync marklater $handle - for {set i 0} { - $i < 2500000 && $aresult eq "Async event not delivered" - } {incr i} {} + # allow plenty of time to pass in case valgrind is running + set start [clock seconds] + while { + [clock seconds] - $start < 180 && $aresult eq "Async event not delivered" + } { + } return $aresult }} $hm } -result {test pattern} -cleanup { -- cgit v0.12 From f8b9cb869de274ad68beeac3cd77ad8c857f30ca Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Fri, 8 Jun 2018 06:56:33 +0000 Subject: re-generate configure script (where does --runstatedir come from? --- unix/configure | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/unix/configure b/unix/configure index 101c7f4..9eba7f9 100755 --- a/unix/configure +++ b/unix/configure @@ -729,7 +729,6 @@ infodir docdir oldincludedir includedir -runstatedir localstatedir sharedstatedir sysconfdir @@ -816,7 +815,6 @@ datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' -runstatedir='${localstatedir}/run' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' @@ -1069,15 +1067,6 @@ do | -silent | --silent | --silen | --sile | --sil) silent=yes ;; - -runstatedir | --runstatedir | --runstatedi | --runstated \ - | --runstate | --runstat | --runsta | --runst | --runs \ - | --run | --ru | --r) - ac_prev=runstatedir ;; - -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ - | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ - | --run=* | --ru=* | --r=*) - runstatedir=$ac_optarg ;; - -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ @@ -1215,7 +1204,7 @@ fi for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ - libdir localedir mandir runstatedir + libdir localedir mandir do eval ac_val=\$$ac_var # Remove trailing slashes. @@ -1368,7 +1357,6 @@ Fine tuning of the installation directories: --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] - --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] -- cgit v0.12 From 04d1270786231c4481e3000d2f98d272c63e90db Mon Sep 17 00:00:00 2001 From: sebres Date: Fri, 8 Jun 2018 12:50:43 +0000 Subject: resolves some warnings by compiling with new gcc-versions (>= 7.x): - '*' in boolean context, suggest '&&' instead [-Wint-in-bool-context] - passing argument 1 of 'Tcl_CreateExitHandler' from incompatible pointer type [-Wincompatible-pointer-types] --- generic/tclStringObj.c | 2 +- win/tclWinFile.c | 10 ++++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/generic/tclStringObj.c b/generic/tclStringObj.c index 67e86c5..996be77 100644 --- a/generic/tclStringObj.c +++ b/generic/tclStringObj.c @@ -113,7 +113,7 @@ typedef struct String { #define STRING_UALLOC(numChars) \ ((numChars) * sizeof(Tcl_UniChar)) #define STRING_SIZE(ualloc) \ - ((unsigned) ((ualloc) \ + ((unsigned) ((ualloc != 0) \ ? (sizeof(String) - sizeof(Tcl_UniChar) + (ualloc)) \ : sizeof(String))) #define stringCheckLimits(numChars) \ diff --git a/win/tclWinFile.c b/win/tclWinFile.c index 3655321..1536bc0 100755 --- a/win/tclWinFile.c +++ b/win/tclWinFile.c @@ -1394,6 +1394,12 @@ NativeMatchType( return 1; } +static void +FreeLoadLibHandle( + ClientData clientData) +{ + FreeLibrary((HMODULE)clientData); +} /* *---------------------------------------------------------------------- * @@ -1445,13 +1451,13 @@ TclpGetUserHome( GetProcAddress(handle, "NetGetDCName"); netUserGetInfoProc = (NETUSERGETINFOPROC *) GetProcAddress(handle, "NetUserGetInfo"); - Tcl_CreateExitHandler(TclpUnloadFile, handle); + Tcl_CreateExitHandler(FreeLoadLibHandle, handle); } handle = LoadLibraryA("userenv.dll"); if (handle) { getProfilesDirectoryProc = (GETPROFILESDIRECTORYPROC *) GetProcAddress(handle, "GetProfilesDirectoryW"); - Tcl_CreateExitHandler(TclpUnloadFile, handle); + Tcl_CreateExitHandler(FreeLoadLibHandle, handle); } apistubs = -1; -- cgit v0.12 From 400feb302b25831ba4be2781fbd08d22b2df35f7 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Sat, 9 Jun 2018 07:41:47 +0000 Subject: Update to latest tzdata (backported from 8.6) --- library/tzdata/Africa/Accra | 94 ++--- library/tzdata/Africa/Bissau | 2 +- library/tzdata/Africa/Sao_Tome | 9 +- library/tzdata/Africa/Windhoek | 95 +++-- library/tzdata/America/Araguaina | 50 +-- library/tzdata/America/Argentina/Buenos_Aires | 58 +-- library/tzdata/America/Argentina/Catamarca | 56 +-- library/tzdata/America/Argentina/Cordoba | 58 +-- library/tzdata/America/Argentina/Jujuy | 52 +-- library/tzdata/America/Argentina/La_Rioja | 56 +-- library/tzdata/America/Argentina/Mendoza | 52 +-- library/tzdata/America/Argentina/Rio_Gallegos | 56 +-- library/tzdata/America/Argentina/Salta | 56 +-- library/tzdata/America/Argentina/San_Juan | 56 +-- library/tzdata/America/Argentina/San_Luis | 50 +-- library/tzdata/America/Argentina/Tucuman | 58 +-- library/tzdata/America/Argentina/Ushuaia | 56 +-- library/tzdata/America/Asuncion | 250 ++++++------- library/tzdata/America/Bahia | 60 +-- library/tzdata/America/Belem | 28 +- library/tzdata/America/Boa_Vista | 32 +- library/tzdata/America/Bogota | 2 +- library/tzdata/America/Campo_Grande | 252 ++++++------- library/tzdata/America/Cuiaba | 250 ++++++------- library/tzdata/America/Eirunepe | 30 +- library/tzdata/America/Fortaleza | 38 +- library/tzdata/America/Grand_Turk | 4 +- library/tzdata/America/Guayaquil | 2 +- library/tzdata/America/Jamaica | 6 +- library/tzdata/America/La_Paz | 2 +- library/tzdata/America/Lima | 6 +- library/tzdata/America/Maceio | 40 +- library/tzdata/America/Manaus | 30 +- library/tzdata/America/Montevideo | 126 +++---- library/tzdata/America/Noronha | 38 +- library/tzdata/America/Porto_Velho | 28 +- library/tzdata/America/Punta_Arenas | 106 +++--- library/tzdata/America/Recife | 38 +- library/tzdata/America/Rio_Branco | 28 +- library/tzdata/America/Santarem | 28 +- library/tzdata/America/Santiago | 272 +++++++------- library/tzdata/America/Sao_Paulo | 250 ++++++------- library/tzdata/Antarctica/Casey | 1 + library/tzdata/Antarctica/Palmer | 78 ++-- library/tzdata/Asia/Almaty | 48 +-- library/tzdata/Asia/Aqtau | 48 +-- library/tzdata/Asia/Aqtobe | 46 +-- library/tzdata/Asia/Ashgabat | 22 +- library/tzdata/Asia/Atyrau | 46 +-- library/tzdata/Asia/Baghdad | 104 +++--- library/tzdata/Asia/Baku | 62 ++-- library/tzdata/Asia/Bishkek | 50 +-- library/tzdata/Asia/Choibalsan | 48 +-- library/tzdata/Asia/Dhaka | 2 +- library/tzdata/Asia/Dushanbe | 20 +- library/tzdata/Asia/Gaza | 72 ++-- library/tzdata/Asia/Hebron | 72 ++-- library/tzdata/Asia/Hovd | 48 +-- library/tzdata/Asia/Kuching | 14 +- library/tzdata/Asia/Macau | 2 +- library/tzdata/Asia/Manila | 6 +- library/tzdata/Asia/Oral | 46 +-- library/tzdata/Asia/Pyongyang | 1 + library/tzdata/Asia/Qyzylorda | 46 +-- library/tzdata/Asia/Samarkand | 20 +- library/tzdata/Asia/Tashkent | 22 +- library/tzdata/Asia/Tbilisi | 50 +-- library/tzdata/Asia/Tehran | 444 +++++++++++----------- library/tzdata/Asia/Tokyo | 16 +- library/tzdata/Asia/Ulaanbaatar | 48 +-- library/tzdata/Asia/Yerevan | 60 +-- library/tzdata/Atlantic/Azores | 2 +- library/tzdata/Atlantic/Cape_Verde | 2 +- library/tzdata/Atlantic/Madeira | 2 +- library/tzdata/Atlantic/Reykjavik | 66 ++-- library/tzdata/Atlantic/Stanley | 66 ++-- library/tzdata/Australia/Lord_Howe | 478 ++++++++++++------------ library/tzdata/Europe/Dublin | 515 +++++++++++++------------- library/tzdata/Europe/Lisbon | 2 +- library/tzdata/Europe/Prague | 9 +- library/tzdata/Indian/Mauritius | 4 +- library/tzdata/Pacific/Apia | 362 +++++++++--------- library/tzdata/Pacific/Chatham | 504 ++++++++++++------------- library/tzdata/Pacific/Easter | 262 ++++++------- library/tzdata/Pacific/Efate | 20 +- library/tzdata/Pacific/Enderbury | 2 +- library/tzdata/Pacific/Fiji | 186 +++++----- library/tzdata/Pacific/Galapagos | 2 +- library/tzdata/Pacific/Kiritimati | 2 +- library/tzdata/Pacific/Noumea | 6 +- library/tzdata/Pacific/Rarotonga | 26 +- library/tzdata/Pacific/Tongatapu | 8 +- 92 files changed, 3467 insertions(+), 3461 deletions(-) diff --git a/library/tzdata/Africa/Accra b/library/tzdata/Africa/Accra index 18f4522..f43f751 100644 --- a/library/tzdata/Africa/Accra +++ b/library/tzdata/Africa/Accra @@ -2,51 +2,51 @@ set TZData(:Africa/Accra) { {-9223372036854775808 -52 0 LMT} - {-1640995148 0 0 +0020} - {-1556841600 1200 1 +0020} - {-1546388400 0 0 +0020} - {-1525305600 1200 1 +0020} - {-1514852400 0 0 +0020} - {-1493769600 1200 1 +0020} - {-1483316400 0 0 +0020} - {-1462233600 1200 1 +0020} - {-1451780400 0 0 +0020} - {-1430611200 1200 1 +0020} - {-1420158000 0 0 +0020} - {-1399075200 1200 1 +0020} - {-1388622000 0 0 +0020} - {-1367539200 1200 1 +0020} - {-1357086000 0 0 +0020} - {-1336003200 1200 1 +0020} - {-1325550000 0 0 +0020} - {-1304380800 1200 1 +0020} - {-1293927600 0 0 +0020} - {-1272844800 1200 1 +0020} - {-1262391600 0 0 +0020} - {-1241308800 1200 1 +0020} - {-1230855600 0 0 +0020} - {-1209772800 1200 1 +0020} - {-1199319600 0 0 +0020} - {-1178150400 1200 1 +0020} - {-1167697200 0 0 +0020} - {-1146614400 1200 1 +0020} - {-1136161200 0 0 +0020} - {-1115078400 1200 1 +0020} - {-1104625200 0 0 +0020} - {-1083542400 1200 1 +0020} - {-1073089200 0 0 +0020} - {-1051920000 1200 1 +0020} - {-1041466800 0 0 +0020} - {-1020384000 1200 1 +0020} - {-1009930800 0 0 +0020} - {-988848000 1200 1 +0020} - {-978394800 0 0 +0020} - {-957312000 1200 1 +0020} - {-946858800 0 0 +0020} - {-925689600 1200 1 +0020} - {-915236400 0 0 +0020} - {-894153600 1200 1 +0020} - {-883700400 0 0 +0020} - {-862617600 1200 1 +0020} - {-852164400 0 0 +0020} + {-1640995148 0 0 GMT} + {-1556841600 1200 1 GMT} + {-1546388400 0 0 GMT} + {-1525305600 1200 1 GMT} + {-1514852400 0 0 GMT} + {-1493769600 1200 1 GMT} + {-1483316400 0 0 GMT} + {-1462233600 1200 1 GMT} + {-1451780400 0 0 GMT} + {-1430611200 1200 1 GMT} + {-1420158000 0 0 GMT} + {-1399075200 1200 1 GMT} + {-1388622000 0 0 GMT} + {-1367539200 1200 1 GMT} + {-1357086000 0 0 GMT} + {-1336003200 1200 1 GMT} + {-1325550000 0 0 GMT} + {-1304380800 1200 1 GMT} + {-1293927600 0 0 GMT} + {-1272844800 1200 1 GMT} + {-1262391600 0 0 GMT} + {-1241308800 1200 1 GMT} + {-1230855600 0 0 GMT} + {-1209772800 1200 1 GMT} + {-1199319600 0 0 GMT} + {-1178150400 1200 1 GMT} + {-1167697200 0 0 GMT} + {-1146614400 1200 1 GMT} + {-1136161200 0 0 GMT} + {-1115078400 1200 1 GMT} + {-1104625200 0 0 GMT} + {-1083542400 1200 1 GMT} + {-1073089200 0 0 GMT} + {-1051920000 1200 1 GMT} + {-1041466800 0 0 GMT} + {-1020384000 1200 1 GMT} + {-1009930800 0 0 GMT} + {-988848000 1200 1 GMT} + {-978394800 0 0 GMT} + {-957312000 1200 1 GMT} + {-946858800 0 0 GMT} + {-925689600 1200 1 GMT} + {-915236400 0 0 GMT} + {-894153600 1200 1 GMT} + {-883700400 0 0 GMT} + {-862617600 1200 1 GMT} + {-852164400 0 0 GMT} } diff --git a/library/tzdata/Africa/Bissau b/library/tzdata/Africa/Bissau index 88d9d03..e0568fb 100644 --- a/library/tzdata/Africa/Bissau +++ b/library/tzdata/Africa/Bissau @@ -2,6 +2,6 @@ set TZData(:Africa/Bissau) { {-9223372036854775808 -3740 0 LMT} - {-1830380260 -3600 0 -01} + {-1830380400 -3600 0 -01} {157770000 0 0 GMT} } diff --git a/library/tzdata/Africa/Sao_Tome b/library/tzdata/Africa/Sao_Tome index 078591d..6a60f5c 100644 --- a/library/tzdata/Africa/Sao_Tome +++ b/library/tzdata/Africa/Sao_Tome @@ -1,5 +1,8 @@ # created by tools/tclZIC.tcl - do not edit -if {![info exists TZData(Africa/Abidjan)]} { - LoadTimeZoneFile Africa/Abidjan + +set TZData(:Africa/Sao_Tome) { + {-9223372036854775808 1616 0 LMT} + {-2713912016 -2205 0 LMT} + {-1830384000 0 0 GMT} + {1514768400 3600 0 WAT} } -set TZData(:Africa/Sao_Tome) $TZData(:Africa/Abidjan) diff --git a/library/tzdata/Africa/Windhoek b/library/tzdata/Africa/Windhoek index 974ebda..d03c8b8 100644 --- a/library/tzdata/Africa/Windhoek +++ b/library/tzdata/Africa/Windhoek @@ -7,53 +7,52 @@ set TZData(:Africa/Windhoek) { {-860976000 10800 1 SAST} {-845254800 7200 0 SAST} {637970400 7200 0 CAT} - {764200800 3600 0 WAT} - {764204400 3600 0 WAT} - {778640400 7200 1 WAST} - {796780800 3600 0 WAT} - {810090000 7200 1 WAST} - {828835200 3600 0 WAT} - {841539600 7200 1 WAST} - {860284800 3600 0 WAT} - {873594000 7200 1 WAST} - {891734400 3600 0 WAT} - {905043600 7200 1 WAST} - {923184000 3600 0 WAT} - {936493200 7200 1 WAST} - {954633600 3600 0 WAT} - {967942800 7200 1 WAST} - {986083200 3600 0 WAT} - {999392400 7200 1 WAST} - {1018137600 3600 0 WAT} - {1030842000 7200 1 WAST} - {1049587200 3600 0 WAT} - {1062896400 7200 1 WAST} - {1081036800 3600 0 WAT} - {1094346000 7200 1 WAST} - {1112486400 3600 0 WAT} - {1125795600 7200 1 WAST} - {1143936000 3600 0 WAT} - {1157245200 7200 1 WAST} - {1175385600 3600 0 WAT} - {1188694800 7200 1 WAST} - {1207440000 3600 0 WAT} - {1220749200 7200 1 WAST} - {1238889600 3600 0 WAT} - {1252198800 7200 1 WAST} - {1270339200 3600 0 WAT} - {1283648400 7200 1 WAST} - {1301788800 3600 0 WAT} - {1315098000 7200 1 WAST} - {1333238400 3600 0 WAT} - {1346547600 7200 1 WAST} - {1365292800 3600 0 WAT} - {1377997200 7200 1 WAST} - {1396742400 3600 0 WAT} - {1410051600 7200 1 WAST} - {1428192000 3600 0 WAT} - {1441501200 7200 1 WAST} - {1459641600 3600 0 WAT} - {1472950800 7200 1 WAST} - {1491091200 3600 0 WAT} + {764200800 3600 1 WAT} + {778640400 7200 0 CAT} + {796780800 3600 1 WAT} + {810090000 7200 0 CAT} + {828835200 3600 1 WAT} + {841539600 7200 0 CAT} + {860284800 3600 1 WAT} + {873594000 7200 0 CAT} + {891734400 3600 1 WAT} + {905043600 7200 0 CAT} + {923184000 3600 1 WAT} + {936493200 7200 0 CAT} + {954633600 3600 1 WAT} + {967942800 7200 0 CAT} + {986083200 3600 1 WAT} + {999392400 7200 0 CAT} + {1018137600 3600 1 WAT} + {1030842000 7200 0 CAT} + {1049587200 3600 1 WAT} + {1062896400 7200 0 CAT} + {1081036800 3600 1 WAT} + {1094346000 7200 0 CAT} + {1112486400 3600 1 WAT} + {1125795600 7200 0 CAT} + {1143936000 3600 1 WAT} + {1157245200 7200 0 CAT} + {1175385600 3600 1 WAT} + {1188694800 7200 0 CAT} + {1207440000 3600 1 WAT} + {1220749200 7200 0 CAT} + {1238889600 3600 1 WAT} + {1252198800 7200 0 CAT} + {1270339200 3600 1 WAT} + {1283648400 7200 0 CAT} + {1301788800 3600 1 WAT} + {1315098000 7200 0 CAT} + {1333238400 3600 1 WAT} + {1346547600 7200 0 CAT} + {1365292800 3600 1 WAT} + {1377997200 7200 0 CAT} + {1396742400 3600 1 WAT} + {1410051600 7200 0 CAT} + {1428192000 3600 1 WAT} + {1441501200 7200 0 CAT} + {1459641600 3600 1 WAT} + {1472950800 7200 0 CAT} + {1491091200 3600 1 WAT} {1504400400 7200 0 CAT} } diff --git a/library/tzdata/America/Araguaina b/library/tzdata/America/Araguaina index b9e2aec..ca64292 100644 --- a/library/tzdata/America/Araguaina +++ b/library/tzdata/America/Araguaina @@ -3,58 +3,58 @@ set TZData(:America/Araguaina) { {-9223372036854775808 -11568 0 LMT} {-1767214032 -10800 0 -03} - {-1206957600 -7200 1 -02} + {-1206957600 -7200 1 -03} {-1191362400 -10800 0 -03} - {-1175374800 -7200 1 -02} + {-1175374800 -7200 1 -03} {-1159826400 -10800 0 -03} - {-633819600 -7200 1 -02} + {-633819600 -7200 1 -03} {-622069200 -10800 0 -03} - {-602283600 -7200 1 -02} + {-602283600 -7200 1 -03} {-591832800 -10800 0 -03} - {-570747600 -7200 1 -02} + {-570747600 -7200 1 -03} {-560210400 -10800 0 -03} - {-539125200 -7200 1 -02} + {-539125200 -7200 1 -03} {-531352800 -10800 0 -03} - {-191365200 -7200 1 -02} + {-191365200 -7200 1 -03} {-184197600 -10800 0 -03} - {-155163600 -7200 1 -02} + {-155163600 -7200 1 -03} {-150069600 -10800 0 -03} - {-128898000 -7200 1 -02} + {-128898000 -7200 1 -03} {-121125600 -10800 0 -03} - {-99954000 -7200 1 -02} + {-99954000 -7200 1 -03} {-89589600 -10800 0 -03} - {-68418000 -7200 1 -02} + {-68418000 -7200 1 -03} {-57967200 -10800 0 -03} - {499748400 -7200 1 -02} + {499748400 -7200 1 -03} {511236000 -10800 0 -03} - {530593200 -7200 1 -02} + {530593200 -7200 1 -03} {540266400 -10800 0 -03} - {562129200 -7200 1 -02} + {562129200 -7200 1 -03} {571197600 -10800 0 -03} - {592974000 -7200 1 -02} + {592974000 -7200 1 -03} {602042400 -10800 0 -03} - {624423600 -7200 1 -02} + {624423600 -7200 1 -03} {634701600 -10800 0 -03} {653536800 -10800 0 -03} {811047600 -10800 0 -03} - {813726000 -7200 1 -02} + {813726000 -7200 1 -03} {824004000 -10800 0 -03} - {844570800 -7200 1 -02} + {844570800 -7200 1 -03} {856058400 -10800 0 -03} - {876106800 -7200 1 -02} + {876106800 -7200 1 -03} {888717600 -10800 0 -03} - {908074800 -7200 1 -02} + {908074800 -7200 1 -03} {919562400 -10800 0 -03} - {938919600 -7200 1 -02} + {938919600 -7200 1 -03} {951616800 -10800 0 -03} - {970974000 -7200 1 -02} + {970974000 -7200 1 -03} {982461600 -10800 0 -03} - {1003028400 -7200 1 -02} + {1003028400 -7200 1 -03} {1013911200 -10800 0 -03} - {1036292400 -7200 1 -02} + {1036292400 -7200 1 -03} {1045360800 -10800 0 -03} {1064368800 -10800 0 -03} - {1350788400 -7200 0 -02} + {1350788400 -7200 0 -03} {1361066400 -10800 0 -03} {1378000800 -10800 0 -03} } diff --git a/library/tzdata/America/Argentina/Buenos_Aires b/library/tzdata/America/Argentina/Buenos_Aires index 8be2c45..40f1912 100644 --- a/library/tzdata/America/Argentina/Buenos_Aires +++ b/library/tzdata/America/Argentina/Buenos_Aires @@ -4,64 +4,64 @@ set TZData(:America/Argentina/Buenos_Aires) { {-9223372036854775808 -14028 0 LMT} {-2372097972 -15408 0 CMT} {-1567453392 -14400 0 -04} - {-1233432000 -10800 0 -03} + {-1233432000 -10800 0 -04} {-1222981200 -14400 0 -04} - {-1205956800 -10800 1 -03} + {-1205956800 -10800 1 -04} {-1194037200 -14400 0 -04} - {-1172865600 -10800 1 -03} + {-1172865600 -10800 1 -04} {-1162501200 -14400 0 -04} - {-1141329600 -10800 1 -03} + {-1141329600 -10800 1 -04} {-1130965200 -14400 0 -04} - {-1109793600 -10800 1 -03} + {-1109793600 -10800 1 -04} {-1099429200 -14400 0 -04} - {-1078257600 -10800 1 -03} + {-1078257600 -10800 1 -04} {-1067806800 -14400 0 -04} - {-1046635200 -10800 1 -03} + {-1046635200 -10800 1 -04} {-1036270800 -14400 0 -04} - {-1015099200 -10800 1 -03} + {-1015099200 -10800 1 -04} {-1004734800 -14400 0 -04} - {-983563200 -10800 1 -03} + {-983563200 -10800 1 -04} {-973198800 -14400 0 -04} - {-952027200 -10800 1 -03} + {-952027200 -10800 1 -04} {-941576400 -14400 0 -04} - {-931032000 -10800 1 -03} + {-931032000 -10800 1 -04} {-900882000 -14400 0 -04} - {-890337600 -10800 1 -03} + {-890337600 -10800 1 -04} {-833749200 -14400 0 -04} - {-827265600 -10800 1 -03} + {-827265600 -10800 1 -04} {-752274000 -14400 0 -04} - {-733780800 -10800 1 -03} + {-733780800 -10800 1 -04} {-197326800 -14400 0 -04} - {-190843200 -10800 1 -03} + {-190843200 -10800 1 -04} {-184194000 -14400 0 -04} - {-164491200 -10800 1 -03} + {-164491200 -10800 1 -04} {-152658000 -14400 0 -04} - {-132955200 -10800 1 -03} + {-132955200 -10800 1 -04} {-121122000 -14400 0 -04} - {-101419200 -10800 1 -03} + {-101419200 -10800 1 -04} {-86821200 -14400 0 -04} - {-71092800 -10800 1 -03} + {-71092800 -10800 1 -04} {-54766800 -14400 0 -04} - {-39038400 -10800 1 -03} + {-39038400 -10800 1 -04} {-23317200 -14400 0 -04} {-7588800 -10800 0 -03} - {128142000 -7200 1 -02} + {128142000 -7200 1 -03} {136605600 -10800 0 -03} - {596948400 -7200 1 -02} + {596948400 -7200 1 -03} {605066400 -10800 0 -03} - {624423600 -7200 1 -02} + {624423600 -7200 1 -03} {636516000 -10800 0 -03} - {656478000 -7200 1 -02} + {656478000 -7200 1 -03} {667965600 -10800 0 -03} - {687927600 -7200 1 -02} + {687927600 -7200 1 -03} {699415200 -10800 0 -03} - {719377200 -7200 1 -02} + {719377200 -7200 1 -03} {731469600 -10800 0 -03} {938916000 -10800 0 -04} - {938919600 -10800 1 -03} + {938919600 -10800 1 -04} {952056000 -10800 0 -03} - {1198983600 -7200 1 -02} + {1198983600 -7200 1 -03} {1205632800 -10800 0 -03} - {1224385200 -7200 1 -02} + {1224385200 -7200 1 -03} {1237082400 -10800 0 -03} } diff --git a/library/tzdata/America/Argentina/Catamarca b/library/tzdata/America/Argentina/Catamarca index a546bfc..da5b42a 100644 --- a/library/tzdata/America/Argentina/Catamarca +++ b/library/tzdata/America/Argentina/Catamarca @@ -4,65 +4,65 @@ set TZData(:America/Argentina/Catamarca) { {-9223372036854775808 -15788 0 LMT} {-2372096212 -15408 0 CMT} {-1567453392 -14400 0 -04} - {-1233432000 -10800 0 -03} + {-1233432000 -10800 0 -04} {-1222981200 -14400 0 -04} - {-1205956800 -10800 1 -03} + {-1205956800 -10800 1 -04} {-1194037200 -14400 0 -04} - {-1172865600 -10800 1 -03} + {-1172865600 -10800 1 -04} {-1162501200 -14400 0 -04} - {-1141329600 -10800 1 -03} + {-1141329600 -10800 1 -04} {-1130965200 -14400 0 -04} - {-1109793600 -10800 1 -03} + {-1109793600 -10800 1 -04} {-1099429200 -14400 0 -04} - {-1078257600 -10800 1 -03} + {-1078257600 -10800 1 -04} {-1067806800 -14400 0 -04} - {-1046635200 -10800 1 -03} + {-1046635200 -10800 1 -04} {-1036270800 -14400 0 -04} - {-1015099200 -10800 1 -03} + {-1015099200 -10800 1 -04} {-1004734800 -14400 0 -04} - {-983563200 -10800 1 -03} + {-983563200 -10800 1 -04} {-973198800 -14400 0 -04} - {-952027200 -10800 1 -03} + {-952027200 -10800 1 -04} {-941576400 -14400 0 -04} - {-931032000 -10800 1 -03} + {-931032000 -10800 1 -04} {-900882000 -14400 0 -04} - {-890337600 -10800 1 -03} + {-890337600 -10800 1 -04} {-833749200 -14400 0 -04} - {-827265600 -10800 1 -03} + {-827265600 -10800 1 -04} {-752274000 -14400 0 -04} - {-733780800 -10800 1 -03} + {-733780800 -10800 1 -04} {-197326800 -14400 0 -04} - {-190843200 -10800 1 -03} + {-190843200 -10800 1 -04} {-184194000 -14400 0 -04} - {-164491200 -10800 1 -03} + {-164491200 -10800 1 -04} {-152658000 -14400 0 -04} - {-132955200 -10800 1 -03} + {-132955200 -10800 1 -04} {-121122000 -14400 0 -04} - {-101419200 -10800 1 -03} + {-101419200 -10800 1 -04} {-86821200 -14400 0 -04} - {-71092800 -10800 1 -03} + {-71092800 -10800 1 -04} {-54766800 -14400 0 -04} - {-39038400 -10800 1 -03} + {-39038400 -10800 1 -04} {-23317200 -14400 0 -04} {-7588800 -10800 0 -03} - {128142000 -7200 1 -02} + {128142000 -7200 1 -03} {136605600 -10800 0 -03} - {596948400 -7200 1 -02} + {596948400 -7200 1 -03} {605066400 -10800 0 -03} - {624423600 -7200 1 -02} + {624423600 -7200 1 -03} {636516000 -10800 0 -03} - {656478000 -7200 1 -02} + {656478000 -7200 1 -03} {667965600 -14400 0 -04} - {687931200 -7200 0 -02} + {687931200 -7200 0 -03} {699415200 -10800 0 -03} - {719377200 -7200 1 -02} + {719377200 -7200 1 -03} {731469600 -10800 0 -03} {938916000 -10800 0 -04} - {938919600 -10800 1 -03} + {938919600 -10800 1 -04} {952056000 -10800 0 -03} {1086058800 -14400 0 -04} {1087704000 -10800 0 -03} - {1198983600 -7200 1 -02} + {1198983600 -7200 1 -03} {1205632800 -10800 0 -03} {1224295200 -10800 0 -03} } diff --git a/library/tzdata/America/Argentina/Cordoba b/library/tzdata/America/Argentina/Cordoba index ec6978e..6a1426e 100644 --- a/library/tzdata/America/Argentina/Cordoba +++ b/library/tzdata/America/Argentina/Cordoba @@ -4,64 +4,64 @@ set TZData(:America/Argentina/Cordoba) { {-9223372036854775808 -15408 0 LMT} {-2372096592 -15408 0 CMT} {-1567453392 -14400 0 -04} - {-1233432000 -10800 0 -03} + {-1233432000 -10800 0 -04} {-1222981200 -14400 0 -04} - {-1205956800 -10800 1 -03} + {-1205956800 -10800 1 -04} {-1194037200 -14400 0 -04} - {-1172865600 -10800 1 -03} + {-1172865600 -10800 1 -04} {-1162501200 -14400 0 -04} - {-1141329600 -10800 1 -03} + {-1141329600 -10800 1 -04} {-1130965200 -14400 0 -04} - {-1109793600 -10800 1 -03} + {-1109793600 -10800 1 -04} {-1099429200 -14400 0 -04} - {-1078257600 -10800 1 -03} + {-1078257600 -10800 1 -04} {-1067806800 -14400 0 -04} - {-1046635200 -10800 1 -03} + {-1046635200 -10800 1 -04} {-1036270800 -14400 0 -04} - {-1015099200 -10800 1 -03} + {-1015099200 -10800 1 -04} {-1004734800 -14400 0 -04} - {-983563200 -10800 1 -03} + {-983563200 -10800 1 -04} {-973198800 -14400 0 -04} - {-952027200 -10800 1 -03} + {-952027200 -10800 1 -04} {-941576400 -14400 0 -04} - {-931032000 -10800 1 -03} + {-931032000 -10800 1 -04} {-900882000 -14400 0 -04} - {-890337600 -10800 1 -03} + {-890337600 -10800 1 -04} {-833749200 -14400 0 -04} - {-827265600 -10800 1 -03} + {-827265600 -10800 1 -04} {-752274000 -14400 0 -04} - {-733780800 -10800 1 -03} + {-733780800 -10800 1 -04} {-197326800 -14400 0 -04} - {-190843200 -10800 1 -03} + {-190843200 -10800 1 -04} {-184194000 -14400 0 -04} - {-164491200 -10800 1 -03} + {-164491200 -10800 1 -04} {-152658000 -14400 0 -04} - {-132955200 -10800 1 -03} + {-132955200 -10800 1 -04} {-121122000 -14400 0 -04} - {-101419200 -10800 1 -03} + {-101419200 -10800 1 -04} {-86821200 -14400 0 -04} - {-71092800 -10800 1 -03} + {-71092800 -10800 1 -04} {-54766800 -14400 0 -04} - {-39038400 -10800 1 -03} + {-39038400 -10800 1 -04} {-23317200 -14400 0 -04} {-7588800 -10800 0 -03} - {128142000 -7200 1 -02} + {128142000 -7200 1 -03} {136605600 -10800 0 -03} - {596948400 -7200 1 -02} + {596948400 -7200 1 -03} {605066400 -10800 0 -03} - {624423600 -7200 1 -02} + {624423600 -7200 1 -03} {636516000 -10800 0 -03} - {656478000 -7200 1 -02} + {656478000 -7200 1 -03} {667965600 -14400 0 -04} - {687931200 -7200 0 -02} + {687931200 -7200 0 -03} {699415200 -10800 0 -03} - {719377200 -7200 1 -02} + {719377200 -7200 1 -03} {731469600 -10800 0 -03} {938916000 -10800 0 -04} - {938919600 -10800 1 -03} + {938919600 -10800 1 -04} {952056000 -10800 0 -03} - {1198983600 -7200 1 -02} + {1198983600 -7200 1 -03} {1205632800 -10800 0 -03} - {1224385200 -7200 1 -02} + {1224385200 -7200 1 -03} {1237082400 -10800 0 -03} } diff --git a/library/tzdata/America/Argentina/Jujuy b/library/tzdata/America/Argentina/Jujuy index 0e11ba2..72080f5 100644 --- a/library/tzdata/America/Argentina/Jujuy +++ b/library/tzdata/America/Argentina/Jujuy @@ -4,64 +4,64 @@ set TZData(:America/Argentina/Jujuy) { {-9223372036854775808 -15672 0 LMT} {-2372096328 -15408 0 CMT} {-1567453392 -14400 0 -04} - {-1233432000 -10800 0 -03} + {-1233432000 -10800 0 -04} {-1222981200 -14400 0 -04} - {-1205956800 -10800 1 -03} + {-1205956800 -10800 1 -04} {-1194037200 -14400 0 -04} - {-1172865600 -10800 1 -03} + {-1172865600 -10800 1 -04} {-1162501200 -14400 0 -04} - {-1141329600 -10800 1 -03} + {-1141329600 -10800 1 -04} {-1130965200 -14400 0 -04} - {-1109793600 -10800 1 -03} + {-1109793600 -10800 1 -04} {-1099429200 -14400 0 -04} - {-1078257600 -10800 1 -03} + {-1078257600 -10800 1 -04} {-1067806800 -14400 0 -04} - {-1046635200 -10800 1 -03} + {-1046635200 -10800 1 -04} {-1036270800 -14400 0 -04} - {-1015099200 -10800 1 -03} + {-1015099200 -10800 1 -04} {-1004734800 -14400 0 -04} - {-983563200 -10800 1 -03} + {-983563200 -10800 1 -04} {-973198800 -14400 0 -04} - {-952027200 -10800 1 -03} + {-952027200 -10800 1 -04} {-941576400 -14400 0 -04} - {-931032000 -10800 1 -03} + {-931032000 -10800 1 -04} {-900882000 -14400 0 -04} - {-890337600 -10800 1 -03} + {-890337600 -10800 1 -04} {-833749200 -14400 0 -04} - {-827265600 -10800 1 -03} + {-827265600 -10800 1 -04} {-752274000 -14400 0 -04} - {-733780800 -10800 1 -03} + {-733780800 -10800 1 -04} {-197326800 -14400 0 -04} - {-190843200 -10800 1 -03} + {-190843200 -10800 1 -04} {-184194000 -14400 0 -04} - {-164491200 -10800 1 -03} + {-164491200 -10800 1 -04} {-152658000 -14400 0 -04} - {-132955200 -10800 1 -03} + {-132955200 -10800 1 -04} {-121122000 -14400 0 -04} - {-101419200 -10800 1 -03} + {-101419200 -10800 1 -04} {-86821200 -14400 0 -04} - {-71092800 -10800 1 -03} + {-71092800 -10800 1 -04} {-54766800 -14400 0 -04} - {-39038400 -10800 1 -03} + {-39038400 -10800 1 -04} {-23317200 -14400 0 -04} {-7588800 -10800 0 -03} - {128142000 -7200 1 -02} + {128142000 -7200 1 -03} {136605600 -10800 0 -03} - {596948400 -7200 1 -02} + {596948400 -7200 1 -03} {605066400 -10800 0 -03} - {624423600 -7200 1 -02} + {624423600 -7200 1 -03} {636516000 -14400 0 -04} {657086400 -10800 1 -03} {669178800 -14400 0 -04} {686721600 -7200 1 -02} {694231200 -7200 0 -03} {699415200 -10800 0 -03} - {719377200 -7200 1 -02} + {719377200 -7200 1 -03} {731469600 -10800 0 -03} {938916000 -10800 0 -04} - {938919600 -10800 1 -03} + {938919600 -10800 1 -04} {952056000 -10800 0 -03} - {1198983600 -7200 1 -02} + {1198983600 -7200 1 -03} {1205632800 -10800 0 -03} {1224295200 -10800 0 -03} } diff --git a/library/tzdata/America/Argentina/La_Rioja b/library/tzdata/America/Argentina/La_Rioja index 90e0030..fb7b237 100644 --- a/library/tzdata/America/Argentina/La_Rioja +++ b/library/tzdata/America/Argentina/La_Rioja @@ -4,66 +4,66 @@ set TZData(:America/Argentina/La_Rioja) { {-9223372036854775808 -16044 0 LMT} {-2372095956 -15408 0 CMT} {-1567453392 -14400 0 -04} - {-1233432000 -10800 0 -03} + {-1233432000 -10800 0 -04} {-1222981200 -14400 0 -04} - {-1205956800 -10800 1 -03} + {-1205956800 -10800 1 -04} {-1194037200 -14400 0 -04} - {-1172865600 -10800 1 -03} + {-1172865600 -10800 1 -04} {-1162501200 -14400 0 -04} - {-1141329600 -10800 1 -03} + {-1141329600 -10800 1 -04} {-1130965200 -14400 0 -04} - {-1109793600 -10800 1 -03} + {-1109793600 -10800 1 -04} {-1099429200 -14400 0 -04} - {-1078257600 -10800 1 -03} + {-1078257600 -10800 1 -04} {-1067806800 -14400 0 -04} - {-1046635200 -10800 1 -03} + {-1046635200 -10800 1 -04} {-1036270800 -14400 0 -04} - {-1015099200 -10800 1 -03} + {-1015099200 -10800 1 -04} {-1004734800 -14400 0 -04} - {-983563200 -10800 1 -03} + {-983563200 -10800 1 -04} {-973198800 -14400 0 -04} - {-952027200 -10800 1 -03} + {-952027200 -10800 1 -04} {-941576400 -14400 0 -04} - {-931032000 -10800 1 -03} + {-931032000 -10800 1 -04} {-900882000 -14400 0 -04} - {-890337600 -10800 1 -03} + {-890337600 -10800 1 -04} {-833749200 -14400 0 -04} - {-827265600 -10800 1 -03} + {-827265600 -10800 1 -04} {-752274000 -14400 0 -04} - {-733780800 -10800 1 -03} + {-733780800 -10800 1 -04} {-197326800 -14400 0 -04} - {-190843200 -10800 1 -03} + {-190843200 -10800 1 -04} {-184194000 -14400 0 -04} - {-164491200 -10800 1 -03} + {-164491200 -10800 1 -04} {-152658000 -14400 0 -04} - {-132955200 -10800 1 -03} + {-132955200 -10800 1 -04} {-121122000 -14400 0 -04} - {-101419200 -10800 1 -03} + {-101419200 -10800 1 -04} {-86821200 -14400 0 -04} - {-71092800 -10800 1 -03} + {-71092800 -10800 1 -04} {-54766800 -14400 0 -04} - {-39038400 -10800 1 -03} + {-39038400 -10800 1 -04} {-23317200 -14400 0 -04} {-7588800 -10800 0 -03} - {128142000 -7200 1 -02} + {128142000 -7200 1 -03} {136605600 -10800 0 -03} - {596948400 -7200 1 -02} + {596948400 -7200 1 -03} {605066400 -10800 0 -03} - {624423600 -7200 1 -02} + {624423600 -7200 1 -03} {636516000 -10800 0 -03} - {656478000 -7200 1 -02} + {656478000 -7200 1 -03} {667792800 -14400 0 -04} {673588800 -10800 0 -03} - {687927600 -7200 1 -02} + {687927600 -7200 1 -03} {699415200 -10800 0 -03} - {719377200 -7200 1 -02} + {719377200 -7200 1 -03} {731469600 -10800 0 -03} {938916000 -10800 0 -04} - {938919600 -10800 1 -03} + {938919600 -10800 1 -04} {952056000 -10800 0 -03} {1086058800 -14400 0 -04} {1087704000 -10800 0 -03} - {1198983600 -7200 1 -02} + {1198983600 -7200 1 -03} {1205632800 -10800 0 -03} {1224295200 -10800 0 -03} } diff --git a/library/tzdata/America/Argentina/Mendoza b/library/tzdata/America/Argentina/Mendoza index 8dfcd2b..af7342e 100644 --- a/library/tzdata/America/Argentina/Mendoza +++ b/library/tzdata/America/Argentina/Mendoza @@ -4,65 +4,65 @@ set TZData(:America/Argentina/Mendoza) { {-9223372036854775808 -16516 0 LMT} {-2372095484 -15408 0 CMT} {-1567453392 -14400 0 -04} - {-1233432000 -10800 0 -03} + {-1233432000 -10800 0 -04} {-1222981200 -14400 0 -04} - {-1205956800 -10800 1 -03} + {-1205956800 -10800 1 -04} {-1194037200 -14400 0 -04} - {-1172865600 -10800 1 -03} + {-1172865600 -10800 1 -04} {-1162501200 -14400 0 -04} - {-1141329600 -10800 1 -03} + {-1141329600 -10800 1 -04} {-1130965200 -14400 0 -04} - {-1109793600 -10800 1 -03} + {-1109793600 -10800 1 -04} {-1099429200 -14400 0 -04} - {-1078257600 -10800 1 -03} + {-1078257600 -10800 1 -04} {-1067806800 -14400 0 -04} - {-1046635200 -10800 1 -03} + {-1046635200 -10800 1 -04} {-1036270800 -14400 0 -04} - {-1015099200 -10800 1 -03} + {-1015099200 -10800 1 -04} {-1004734800 -14400 0 -04} - {-983563200 -10800 1 -03} + {-983563200 -10800 1 -04} {-973198800 -14400 0 -04} - {-952027200 -10800 1 -03} + {-952027200 -10800 1 -04} {-941576400 -14400 0 -04} - {-931032000 -10800 1 -03} + {-931032000 -10800 1 -04} {-900882000 -14400 0 -04} - {-890337600 -10800 1 -03} + {-890337600 -10800 1 -04} {-833749200 -14400 0 -04} - {-827265600 -10800 1 -03} + {-827265600 -10800 1 -04} {-752274000 -14400 0 -04} - {-733780800 -10800 1 -03} + {-733780800 -10800 1 -04} {-197326800 -14400 0 -04} - {-190843200 -10800 1 -03} + {-190843200 -10800 1 -04} {-184194000 -14400 0 -04} - {-164491200 -10800 1 -03} + {-164491200 -10800 1 -04} {-152658000 -14400 0 -04} - {-132955200 -10800 1 -03} + {-132955200 -10800 1 -04} {-121122000 -14400 0 -04} - {-101419200 -10800 1 -03} + {-101419200 -10800 1 -04} {-86821200 -14400 0 -04} - {-71092800 -10800 1 -03} + {-71092800 -10800 1 -04} {-54766800 -14400 0 -04} - {-39038400 -10800 1 -03} + {-39038400 -10800 1 -04} {-23317200 -14400 0 -04} {-7588800 -10800 0 -03} - {128142000 -7200 1 -02} + {128142000 -7200 1 -03} {136605600 -10800 0 -03} - {596948400 -7200 1 -02} + {596948400 -7200 1 -03} {605066400 -10800 0 -03} - {624423600 -7200 1 -02} + {624423600 -7200 1 -03} {636516000 -14400 0 -04} {655963200 -10800 1 -03} {667796400 -14400 0 -04} {687499200 -10800 1 -03} {699418800 -14400 0 -04} - {719380800 -7200 0 -02} + {719380800 -7200 0 -03} {731469600 -10800 0 -03} {938916000 -10800 0 -04} - {938919600 -10800 1 -03} + {938919600 -10800 1 -04} {952056000 -10800 0 -03} {1085281200 -14400 0 -04} {1096171200 -10800 0 -03} - {1198983600 -7200 1 -02} + {1198983600 -7200 1 -03} {1205632800 -10800 0 -03} {1224295200 -10800 0 -03} } diff --git a/library/tzdata/America/Argentina/Rio_Gallegos b/library/tzdata/America/Argentina/Rio_Gallegos index 4b2a348..2a197a4 100644 --- a/library/tzdata/America/Argentina/Rio_Gallegos +++ b/library/tzdata/America/Argentina/Rio_Gallegos @@ -4,65 +4,65 @@ set TZData(:America/Argentina/Rio_Gallegos) { {-9223372036854775808 -16612 0 LMT} {-2372095388 -15408 0 CMT} {-1567453392 -14400 0 -04} - {-1233432000 -10800 0 -03} + {-1233432000 -10800 0 -04} {-1222981200 -14400 0 -04} - {-1205956800 -10800 1 -03} + {-1205956800 -10800 1 -04} {-1194037200 -14400 0 -04} - {-1172865600 -10800 1 -03} + {-1172865600 -10800 1 -04} {-1162501200 -14400 0 -04} - {-1141329600 -10800 1 -03} + {-1141329600 -10800 1 -04} {-1130965200 -14400 0 -04} - {-1109793600 -10800 1 -03} + {-1109793600 -10800 1 -04} {-1099429200 -14400 0 -04} - {-1078257600 -10800 1 -03} + {-1078257600 -10800 1 -04} {-1067806800 -14400 0 -04} - {-1046635200 -10800 1 -03} + {-1046635200 -10800 1 -04} {-1036270800 -14400 0 -04} - {-1015099200 -10800 1 -03} + {-1015099200 -10800 1 -04} {-1004734800 -14400 0 -04} - {-983563200 -10800 1 -03} + {-983563200 -10800 1 -04} {-973198800 -14400 0 -04} - {-952027200 -10800 1 -03} + {-952027200 -10800 1 -04} {-941576400 -14400 0 -04} - {-931032000 -10800 1 -03} + {-931032000 -10800 1 -04} {-900882000 -14400 0 -04} - {-890337600 -10800 1 -03} + {-890337600 -10800 1 -04} {-833749200 -14400 0 -04} - {-827265600 -10800 1 -03} + {-827265600 -10800 1 -04} {-752274000 -14400 0 -04} - {-733780800 -10800 1 -03} + {-733780800 -10800 1 -04} {-197326800 -14400 0 -04} - {-190843200 -10800 1 -03} + {-190843200 -10800 1 -04} {-184194000 -14400 0 -04} - {-164491200 -10800 1 -03} + {-164491200 -10800 1 -04} {-152658000 -14400 0 -04} - {-132955200 -10800 1 -03} + {-132955200 -10800 1 -04} {-121122000 -14400 0 -04} - {-101419200 -10800 1 -03} + {-101419200 -10800 1 -04} {-86821200 -14400 0 -04} - {-71092800 -10800 1 -03} + {-71092800 -10800 1 -04} {-54766800 -14400 0 -04} - {-39038400 -10800 1 -03} + {-39038400 -10800 1 -04} {-23317200 -14400 0 -04} {-7588800 -10800 0 -03} - {128142000 -7200 1 -02} + {128142000 -7200 1 -03} {136605600 -10800 0 -03} - {596948400 -7200 1 -02} + {596948400 -7200 1 -03} {605066400 -10800 0 -03} - {624423600 -7200 1 -02} + {624423600 -7200 1 -03} {636516000 -10800 0 -03} - {656478000 -7200 1 -02} + {656478000 -7200 1 -03} {667965600 -10800 0 -03} - {687927600 -7200 1 -02} + {687927600 -7200 1 -03} {699415200 -10800 0 -03} - {719377200 -7200 1 -02} + {719377200 -7200 1 -03} {731469600 -10800 0 -03} {938916000 -10800 0 -04} - {938919600 -10800 1 -03} + {938919600 -10800 1 -04} {952056000 -10800 0 -03} {1086058800 -14400 0 -04} {1087704000 -10800 0 -03} - {1198983600 -7200 1 -02} + {1198983600 -7200 1 -03} {1205632800 -10800 0 -03} {1224295200 -10800 0 -03} } diff --git a/library/tzdata/America/Argentina/Salta b/library/tzdata/America/Argentina/Salta index 4f9ccf9..d49e82f 100644 --- a/library/tzdata/America/Argentina/Salta +++ b/library/tzdata/America/Argentina/Salta @@ -4,63 +4,63 @@ set TZData(:America/Argentina/Salta) { {-9223372036854775808 -15700 0 LMT} {-2372096300 -15408 0 CMT} {-1567453392 -14400 0 -04} - {-1233432000 -10800 0 -03} + {-1233432000 -10800 0 -04} {-1222981200 -14400 0 -04} - {-1205956800 -10800 1 -03} + {-1205956800 -10800 1 -04} {-1194037200 -14400 0 -04} - {-1172865600 -10800 1 -03} + {-1172865600 -10800 1 -04} {-1162501200 -14400 0 -04} - {-1141329600 -10800 1 -03} + {-1141329600 -10800 1 -04} {-1130965200 -14400 0 -04} - {-1109793600 -10800 1 -03} + {-1109793600 -10800 1 -04} {-1099429200 -14400 0 -04} - {-1078257600 -10800 1 -03} + {-1078257600 -10800 1 -04} {-1067806800 -14400 0 -04} - {-1046635200 -10800 1 -03} + {-1046635200 -10800 1 -04} {-1036270800 -14400 0 -04} - {-1015099200 -10800 1 -03} + {-1015099200 -10800 1 -04} {-1004734800 -14400 0 -04} - {-983563200 -10800 1 -03} + {-983563200 -10800 1 -04} {-973198800 -14400 0 -04} - {-952027200 -10800 1 -03} + {-952027200 -10800 1 -04} {-941576400 -14400 0 -04} - {-931032000 -10800 1 -03} + {-931032000 -10800 1 -04} {-900882000 -14400 0 -04} - {-890337600 -10800 1 -03} + {-890337600 -10800 1 -04} {-833749200 -14400 0 -04} - {-827265600 -10800 1 -03} + {-827265600 -10800 1 -04} {-752274000 -14400 0 -04} - {-733780800 -10800 1 -03} + {-733780800 -10800 1 -04} {-197326800 -14400 0 -04} - {-190843200 -10800 1 -03} + {-190843200 -10800 1 -04} {-184194000 -14400 0 -04} - {-164491200 -10800 1 -03} + {-164491200 -10800 1 -04} {-152658000 -14400 0 -04} - {-132955200 -10800 1 -03} + {-132955200 -10800 1 -04} {-121122000 -14400 0 -04} - {-101419200 -10800 1 -03} + {-101419200 -10800 1 -04} {-86821200 -14400 0 -04} - {-71092800 -10800 1 -03} + {-71092800 -10800 1 -04} {-54766800 -14400 0 -04} - {-39038400 -10800 1 -03} + {-39038400 -10800 1 -04} {-23317200 -14400 0 -04} {-7588800 -10800 0 -03} - {128142000 -7200 1 -02} + {128142000 -7200 1 -03} {136605600 -10800 0 -03} - {596948400 -7200 1 -02} + {596948400 -7200 1 -03} {605066400 -10800 0 -03} - {624423600 -7200 1 -02} + {624423600 -7200 1 -03} {636516000 -10800 0 -03} - {656478000 -7200 1 -02} + {656478000 -7200 1 -03} {667965600 -14400 0 -04} - {687931200 -7200 0 -02} + {687931200 -7200 0 -03} {699415200 -10800 0 -03} - {719377200 -7200 1 -02} + {719377200 -7200 1 -03} {731469600 -10800 0 -03} {938916000 -10800 0 -04} - {938919600 -10800 1 -03} + {938919600 -10800 1 -04} {952056000 -10800 0 -03} - {1198983600 -7200 1 -02} + {1198983600 -7200 1 -03} {1205632800 -10800 0 -03} {1224295200 -10800 0 -03} } diff --git a/library/tzdata/America/Argentina/San_Juan b/library/tzdata/America/Argentina/San_Juan index 1f0530a..d67f688 100644 --- a/library/tzdata/America/Argentina/San_Juan +++ b/library/tzdata/America/Argentina/San_Juan @@ -4,66 +4,66 @@ set TZData(:America/Argentina/San_Juan) { {-9223372036854775808 -16444 0 LMT} {-2372095556 -15408 0 CMT} {-1567453392 -14400 0 -04} - {-1233432000 -10800 0 -03} + {-1233432000 -10800 0 -04} {-1222981200 -14400 0 -04} - {-1205956800 -10800 1 -03} + {-1205956800 -10800 1 -04} {-1194037200 -14400 0 -04} - {-1172865600 -10800 1 -03} + {-1172865600 -10800 1 -04} {-1162501200 -14400 0 -04} - {-1141329600 -10800 1 -03} + {-1141329600 -10800 1 -04} {-1130965200 -14400 0 -04} - {-1109793600 -10800 1 -03} + {-1109793600 -10800 1 -04} {-1099429200 -14400 0 -04} - {-1078257600 -10800 1 -03} + {-1078257600 -10800 1 -04} {-1067806800 -14400 0 -04} - {-1046635200 -10800 1 -03} + {-1046635200 -10800 1 -04} {-1036270800 -14400 0 -04} - {-1015099200 -10800 1 -03} + {-1015099200 -10800 1 -04} {-1004734800 -14400 0 -04} - {-983563200 -10800 1 -03} + {-983563200 -10800 1 -04} {-973198800 -14400 0 -04} - {-952027200 -10800 1 -03} + {-952027200 -10800 1 -04} {-941576400 -14400 0 -04} - {-931032000 -10800 1 -03} + {-931032000 -10800 1 -04} {-900882000 -14400 0 -04} - {-890337600 -10800 1 -03} + {-890337600 -10800 1 -04} {-833749200 -14400 0 -04} - {-827265600 -10800 1 -03} + {-827265600 -10800 1 -04} {-752274000 -14400 0 -04} - {-733780800 -10800 1 -03} + {-733780800 -10800 1 -04} {-197326800 -14400 0 -04} - {-190843200 -10800 1 -03} + {-190843200 -10800 1 -04} {-184194000 -14400 0 -04} - {-164491200 -10800 1 -03} + {-164491200 -10800 1 -04} {-152658000 -14400 0 -04} - {-132955200 -10800 1 -03} + {-132955200 -10800 1 -04} {-121122000 -14400 0 -04} - {-101419200 -10800 1 -03} + {-101419200 -10800 1 -04} {-86821200 -14400 0 -04} - {-71092800 -10800 1 -03} + {-71092800 -10800 1 -04} {-54766800 -14400 0 -04} - {-39038400 -10800 1 -03} + {-39038400 -10800 1 -04} {-23317200 -14400 0 -04} {-7588800 -10800 0 -03} - {128142000 -7200 1 -02} + {128142000 -7200 1 -03} {136605600 -10800 0 -03} - {596948400 -7200 1 -02} + {596948400 -7200 1 -03} {605066400 -10800 0 -03} - {624423600 -7200 1 -02} + {624423600 -7200 1 -03} {636516000 -10800 0 -03} - {656478000 -7200 1 -02} + {656478000 -7200 1 -03} {667792800 -14400 0 -04} {673588800 -10800 0 -03} - {687927600 -7200 1 -02} + {687927600 -7200 1 -03} {699415200 -10800 0 -03} - {719377200 -7200 1 -02} + {719377200 -7200 1 -03} {731469600 -10800 0 -03} {938916000 -10800 0 -04} - {938919600 -10800 1 -03} + {938919600 -10800 1 -04} {952056000 -10800 0 -03} {1085972400 -14400 0 -04} {1090728000 -10800 0 -03} - {1198983600 -7200 1 -02} + {1198983600 -7200 1 -03} {1205632800 -10800 0 -03} {1224295200 -10800 0 -03} } diff --git a/library/tzdata/America/Argentina/San_Luis b/library/tzdata/America/Argentina/San_Luis index 3583a39..4d27c32 100644 --- a/library/tzdata/America/Argentina/San_Luis +++ b/library/tzdata/America/Argentina/San_Luis @@ -4,52 +4,52 @@ set TZData(:America/Argentina/San_Luis) { {-9223372036854775808 -15924 0 LMT} {-2372096076 -15408 0 CMT} {-1567453392 -14400 0 -04} - {-1233432000 -10800 0 -03} + {-1233432000 -10800 0 -04} {-1222981200 -14400 0 -04} - {-1205956800 -10800 1 -03} + {-1205956800 -10800 1 -04} {-1194037200 -14400 0 -04} - {-1172865600 -10800 1 -03} + {-1172865600 -10800 1 -04} {-1162501200 -14400 0 -04} - {-1141329600 -10800 1 -03} + {-1141329600 -10800 1 -04} {-1130965200 -14400 0 -04} - {-1109793600 -10800 1 -03} + {-1109793600 -10800 1 -04} {-1099429200 -14400 0 -04} - {-1078257600 -10800 1 -03} + {-1078257600 -10800 1 -04} {-1067806800 -14400 0 -04} - {-1046635200 -10800 1 -03} + {-1046635200 -10800 1 -04} {-1036270800 -14400 0 -04} - {-1015099200 -10800 1 -03} + {-1015099200 -10800 1 -04} {-1004734800 -14400 0 -04} - {-983563200 -10800 1 -03} + {-983563200 -10800 1 -04} {-973198800 -14400 0 -04} - {-952027200 -10800 1 -03} + {-952027200 -10800 1 -04} {-941576400 -14400 0 -04} - {-931032000 -10800 1 -03} + {-931032000 -10800 1 -04} {-900882000 -14400 0 -04} - {-890337600 -10800 1 -03} + {-890337600 -10800 1 -04} {-833749200 -14400 0 -04} - {-827265600 -10800 1 -03} + {-827265600 -10800 1 -04} {-752274000 -14400 0 -04} - {-733780800 -10800 1 -03} + {-733780800 -10800 1 -04} {-197326800 -14400 0 -04} - {-190843200 -10800 1 -03} + {-190843200 -10800 1 -04} {-184194000 -14400 0 -04} - {-164491200 -10800 1 -03} + {-164491200 -10800 1 -04} {-152658000 -14400 0 -04} - {-132955200 -10800 1 -03} + {-132955200 -10800 1 -04} {-121122000 -14400 0 -04} - {-101419200 -10800 1 -03} + {-101419200 -10800 1 -04} {-86821200 -14400 0 -04} - {-71092800 -10800 1 -03} + {-71092800 -10800 1 -04} {-54766800 -14400 0 -04} - {-39038400 -10800 1 -03} + {-39038400 -10800 1 -04} {-23317200 -14400 0 -04} {-7588800 -10800 0 -03} - {128142000 -7200 1 -02} + {128142000 -7200 1 -03} {136605600 -10800 0 -03} - {596948400 -7200 1 -02} + {596948400 -7200 1 -03} {605066400 -10800 0 -03} - {624423600 -7200 1 -02} + {624423600 -7200 1 -03} {631159200 -7200 1 -02} {637380000 -14400 0 -04} {655963200 -10800 1 -03} @@ -59,10 +59,10 @@ set TZData(:America/Argentina/San_Luis) { {952052400 -10800 0 -03} {1085972400 -14400 0 -04} {1090728000 -10800 0 -03} - {1198983600 -7200 1 -02} + {1198983600 -7200 1 -03} {1200880800 -10800 0 -04} {1205031600 -14400 0 -04} - {1223784000 -10800 1 -03} + {1223784000 -10800 1 -04} {1236481200 -14400 0 -04} {1255233600 -10800 0 -03} } diff --git a/library/tzdata/America/Argentina/Tucuman b/library/tzdata/America/Argentina/Tucuman index 15c5c63..6809800 100644 --- a/library/tzdata/America/Argentina/Tucuman +++ b/library/tzdata/America/Argentina/Tucuman @@ -4,66 +4,66 @@ set TZData(:America/Argentina/Tucuman) { {-9223372036854775808 -15652 0 LMT} {-2372096348 -15408 0 CMT} {-1567453392 -14400 0 -04} - {-1233432000 -10800 0 -03} + {-1233432000 -10800 0 -04} {-1222981200 -14400 0 -04} - {-1205956800 -10800 1 -03} + {-1205956800 -10800 1 -04} {-1194037200 -14400 0 -04} - {-1172865600 -10800 1 -03} + {-1172865600 -10800 1 -04} {-1162501200 -14400 0 -04} - {-1141329600 -10800 1 -03} + {-1141329600 -10800 1 -04} {-1130965200 -14400 0 -04} - {-1109793600 -10800 1 -03} + {-1109793600 -10800 1 -04} {-1099429200 -14400 0 -04} - {-1078257600 -10800 1 -03} + {-1078257600 -10800 1 -04} {-1067806800 -14400 0 -04} - {-1046635200 -10800 1 -03} + {-1046635200 -10800 1 -04} {-1036270800 -14400 0 -04} - {-1015099200 -10800 1 -03} + {-1015099200 -10800 1 -04} {-1004734800 -14400 0 -04} - {-983563200 -10800 1 -03} + {-983563200 -10800 1 -04} {-973198800 -14400 0 -04} - {-952027200 -10800 1 -03} + {-952027200 -10800 1 -04} {-941576400 -14400 0 -04} - {-931032000 -10800 1 -03} + {-931032000 -10800 1 -04} {-900882000 -14400 0 -04} - {-890337600 -10800 1 -03} + {-890337600 -10800 1 -04} {-833749200 -14400 0 -04} - {-827265600 -10800 1 -03} + {-827265600 -10800 1 -04} {-752274000 -14400 0 -04} - {-733780800 -10800 1 -03} + {-733780800 -10800 1 -04} {-197326800 -14400 0 -04} - {-190843200 -10800 1 -03} + {-190843200 -10800 1 -04} {-184194000 -14400 0 -04} - {-164491200 -10800 1 -03} + {-164491200 -10800 1 -04} {-152658000 -14400 0 -04} - {-132955200 -10800 1 -03} + {-132955200 -10800 1 -04} {-121122000 -14400 0 -04} - {-101419200 -10800 1 -03} + {-101419200 -10800 1 -04} {-86821200 -14400 0 -04} - {-71092800 -10800 1 -03} + {-71092800 -10800 1 -04} {-54766800 -14400 0 -04} - {-39038400 -10800 1 -03} + {-39038400 -10800 1 -04} {-23317200 -14400 0 -04} {-7588800 -10800 0 -03} - {128142000 -7200 1 -02} + {128142000 -7200 1 -03} {136605600 -10800 0 -03} - {596948400 -7200 1 -02} + {596948400 -7200 1 -03} {605066400 -10800 0 -03} - {624423600 -7200 1 -02} + {624423600 -7200 1 -03} {636516000 -10800 0 -03} - {656478000 -7200 1 -02} + {656478000 -7200 1 -03} {667965600 -14400 0 -04} - {687931200 -7200 0 -02} + {687931200 -7200 0 -03} {699415200 -10800 0 -03} - {719377200 -7200 1 -02} + {719377200 -7200 1 -03} {731469600 -10800 0 -03} {938916000 -10800 0 -04} - {938919600 -10800 1 -03} + {938919600 -10800 1 -04} {952056000 -10800 0 -03} {1086058800 -14400 0 -04} {1087099200 -10800 0 -03} - {1198983600 -7200 1 -02} + {1198983600 -7200 1 -03} {1205632800 -10800 0 -03} - {1224385200 -7200 1 -02} + {1224385200 -7200 1 -03} {1237082400 -10800 0 -03} } diff --git a/library/tzdata/America/Argentina/Ushuaia b/library/tzdata/America/Argentina/Ushuaia index 4214c1d..c62ca0d 100644 --- a/library/tzdata/America/Argentina/Ushuaia +++ b/library/tzdata/America/Argentina/Ushuaia @@ -4,65 +4,65 @@ set TZData(:America/Argentina/Ushuaia) { {-9223372036854775808 -16392 0 LMT} {-2372095608 -15408 0 CMT} {-1567453392 -14400 0 -04} - {-1233432000 -10800 0 -03} + {-1233432000 -10800 0 -04} {-1222981200 -14400 0 -04} - {-1205956800 -10800 1 -03} + {-1205956800 -10800 1 -04} {-1194037200 -14400 0 -04} - {-1172865600 -10800 1 -03} + {-1172865600 -10800 1 -04} {-1162501200 -14400 0 -04} - {-1141329600 -10800 1 -03} + {-1141329600 -10800 1 -04} {-1130965200 -14400 0 -04} - {-1109793600 -10800 1 -03} + {-1109793600 -10800 1 -04} {-1099429200 -14400 0 -04} - {-1078257600 -10800 1 -03} + {-1078257600 -10800 1 -04} {-1067806800 -14400 0 -04} - {-1046635200 -10800 1 -03} + {-1046635200 -10800 1 -04} {-1036270800 -14400 0 -04} - {-1015099200 -10800 1 -03} + {-1015099200 -10800 1 -04} {-1004734800 -14400 0 -04} - {-983563200 -10800 1 -03} + {-983563200 -10800 1 -04} {-973198800 -14400 0 -04} - {-952027200 -10800 1 -03} + {-952027200 -10800 1 -04} {-941576400 -14400 0 -04} - {-931032000 -10800 1 -03} + {-931032000 -10800 1 -04} {-900882000 -14400 0 -04} - {-890337600 -10800 1 -03} + {-890337600 -10800 1 -04} {-833749200 -14400 0 -04} - {-827265600 -10800 1 -03} + {-827265600 -10800 1 -04} {-752274000 -14400 0 -04} - {-733780800 -10800 1 -03} + {-733780800 -10800 1 -04} {-197326800 -14400 0 -04} - {-190843200 -10800 1 -03} + {-190843200 -10800 1 -04} {-184194000 -14400 0 -04} - {-164491200 -10800 1 -03} + {-164491200 -10800 1 -04} {-152658000 -14400 0 -04} - {-132955200 -10800 1 -03} + {-132955200 -10800 1 -04} {-121122000 -14400 0 -04} - {-101419200 -10800 1 -03} + {-101419200 -10800 1 -04} {-86821200 -14400 0 -04} - {-71092800 -10800 1 -03} + {-71092800 -10800 1 -04} {-54766800 -14400 0 -04} - {-39038400 -10800 1 -03} + {-39038400 -10800 1 -04} {-23317200 -14400 0 -04} {-7588800 -10800 0 -03} - {128142000 -7200 1 -02} + {128142000 -7200 1 -03} {136605600 -10800 0 -03} - {596948400 -7200 1 -02} + {596948400 -7200 1 -03} {605066400 -10800 0 -03} - {624423600 -7200 1 -02} + {624423600 -7200 1 -03} {636516000 -10800 0 -03} - {656478000 -7200 1 -02} + {656478000 -7200 1 -03} {667965600 -10800 0 -03} - {687927600 -7200 1 -02} + {687927600 -7200 1 -03} {699415200 -10800 0 -03} - {719377200 -7200 1 -02} + {719377200 -7200 1 -03} {731469600 -10800 0 -03} {938916000 -10800 0 -04} - {938919600 -10800 1 -03} + {938919600 -10800 1 -04} {952056000 -10800 0 -03} {1085886000 -14400 0 -04} {1087704000 -10800 0 -03} - {1198983600 -7200 1 -02} + {1198983600 -7200 1 -03} {1205632800 -10800 0 -03} {1224295200 -10800 0 -03} } diff --git a/library/tzdata/America/Asuncion b/library/tzdata/America/Asuncion index 606db57..8e6c1b0 100644 --- a/library/tzdata/America/Asuncion +++ b/library/tzdata/America/Asuncion @@ -7,253 +7,253 @@ set TZData(:America/Asuncion) { {86760000 -10800 0 -03} {134017200 -14400 0 -04} {162878400 -14400 0 -04} - {181368000 -10800 1 -03} + {181368000 -10800 1 -04} {194497200 -14400 0 -04} - {212990400 -10800 1 -03} + {212990400 -10800 1 -04} {226033200 -14400 0 -04} - {244526400 -10800 1 -03} + {244526400 -10800 1 -04} {257569200 -14400 0 -04} - {276062400 -10800 1 -03} + {276062400 -10800 1 -04} {291783600 -14400 0 -04} - {307598400 -10800 1 -03} + {307598400 -10800 1 -04} {323406000 -14400 0 -04} - {339220800 -10800 1 -03} + {339220800 -10800 1 -04} {354942000 -14400 0 -04} - {370756800 -10800 1 -03} + {370756800 -10800 1 -04} {386478000 -14400 0 -04} - {402292800 -10800 1 -03} + {402292800 -10800 1 -04} {418014000 -14400 0 -04} - {433828800 -10800 1 -03} + {433828800 -10800 1 -04} {449636400 -14400 0 -04} - {465451200 -10800 1 -03} + {465451200 -10800 1 -04} {481172400 -14400 0 -04} - {496987200 -10800 1 -03} + {496987200 -10800 1 -04} {512708400 -14400 0 -04} - {528523200 -10800 1 -03} + {528523200 -10800 1 -04} {544244400 -14400 0 -04} - {560059200 -10800 1 -03} + {560059200 -10800 1 -04} {575866800 -14400 0 -04} - {591681600 -10800 1 -03} + {591681600 -10800 1 -04} {607402800 -14400 0 -04} - {625032000 -10800 1 -03} + {625032000 -10800 1 -04} {638938800 -14400 0 -04} - {654753600 -10800 1 -03} + {654753600 -10800 1 -04} {670474800 -14400 0 -04} - {686721600 -10800 1 -03} + {686721600 -10800 1 -04} {699418800 -14400 0 -04} - {718257600 -10800 1 -03} + {718257600 -10800 1 -04} {733546800 -14400 0 -04} - {749448000 -10800 1 -03} + {749448000 -10800 1 -04} {762318000 -14400 0 -04} - {780984000 -10800 1 -03} + {780984000 -10800 1 -04} {793767600 -14400 0 -04} - {812520000 -10800 1 -03} + {812520000 -10800 1 -04} {825649200 -14400 0 -04} - {844574400 -10800 1 -03} + {844574400 -10800 1 -04} {856666800 -14400 0 -04} - {876024000 -10800 1 -03} + {876024000 -10800 1 -04} {888721200 -14400 0 -04} - {907473600 -10800 1 -03} + {907473600 -10800 1 -04} {920775600 -14400 0 -04} - {938923200 -10800 1 -03} + {938923200 -10800 1 -04} {952225200 -14400 0 -04} - {970372800 -10800 1 -03} + {970372800 -10800 1 -04} {983674800 -14400 0 -04} - {1002427200 -10800 1 -03} + {1002427200 -10800 1 -04} {1018148400 -14400 0 -04} - {1030852800 -10800 1 -03} + {1030852800 -10800 1 -04} {1049598000 -14400 0 -04} - {1062907200 -10800 1 -03} + {1062907200 -10800 1 -04} {1081047600 -14400 0 -04} - {1097985600 -10800 1 -03} + {1097985600 -10800 1 -04} {1110682800 -14400 0 -04} - {1129435200 -10800 1 -03} + {1129435200 -10800 1 -04} {1142132400 -14400 0 -04} - {1160884800 -10800 1 -03} + {1160884800 -10800 1 -04} {1173582000 -14400 0 -04} - {1192939200 -10800 1 -03} + {1192939200 -10800 1 -04} {1205031600 -14400 0 -04} - {1224388800 -10800 1 -03} + {1224388800 -10800 1 -04} {1236481200 -14400 0 -04} - {1255838400 -10800 1 -03} + {1255838400 -10800 1 -04} {1270954800 -14400 0 -04} - {1286078400 -10800 1 -03} + {1286078400 -10800 1 -04} {1302404400 -14400 0 -04} - {1317528000 -10800 1 -03} + {1317528000 -10800 1 -04} {1333854000 -14400 0 -04} - {1349582400 -10800 1 -03} + {1349582400 -10800 1 -04} {1364094000 -14400 0 -04} - {1381032000 -10800 1 -03} + {1381032000 -10800 1 -04} {1395543600 -14400 0 -04} - {1412481600 -10800 1 -03} + {1412481600 -10800 1 -04} {1426993200 -14400 0 -04} - {1443931200 -10800 1 -03} + {1443931200 -10800 1 -04} {1459047600 -14400 0 -04} - {1475380800 -10800 1 -03} + {1475380800 -10800 1 -04} {1490497200 -14400 0 -04} - {1506830400 -10800 1 -03} + {1506830400 -10800 1 -04} {1521946800 -14400 0 -04} - {1538884800 -10800 1 -03} + {1538884800 -10800 1 -04} {1553396400 -14400 0 -04} - {1570334400 -10800 1 -03} + {1570334400 -10800 1 -04} {1584846000 -14400 0 -04} - {1601784000 -10800 1 -03} + {1601784000 -10800 1 -04} {1616900400 -14400 0 -04} - {1633233600 -10800 1 -03} + {1633233600 -10800 1 -04} {1648350000 -14400 0 -04} - {1664683200 -10800 1 -03} + {1664683200 -10800 1 -04} {1679799600 -14400 0 -04} - {1696132800 -10800 1 -03} + {1696132800 -10800 1 -04} {1711249200 -14400 0 -04} - {1728187200 -10800 1 -03} + {1728187200 -10800 1 -04} {1742698800 -14400 0 -04} - {1759636800 -10800 1 -03} + {1759636800 -10800 1 -04} {1774148400 -14400 0 -04} - {1791086400 -10800 1 -03} + {1791086400 -10800 1 -04} {1806202800 -14400 0 -04} - {1822536000 -10800 1 -03} + {1822536000 -10800 1 -04} {1837652400 -14400 0 -04} - {1853985600 -10800 1 -03} + {1853985600 -10800 1 -04} {1869102000 -14400 0 -04} - {1886040000 -10800 1 -03} + {1886040000 -10800 1 -04} {1900551600 -14400 0 -04} - {1917489600 -10800 1 -03} + {1917489600 -10800 1 -04} {1932001200 -14400 0 -04} - {1948939200 -10800 1 -03} + {1948939200 -10800 1 -04} {1964055600 -14400 0 -04} - {1980388800 -10800 1 -03} + {1980388800 -10800 1 -04} {1995505200 -14400 0 -04} - {2011838400 -10800 1 -03} + {2011838400 -10800 1 -04} {2026954800 -14400 0 -04} - {2043288000 -10800 1 -03} + {2043288000 -10800 1 -04} {2058404400 -14400 0 -04} - {2075342400 -10800 1 -03} + {2075342400 -10800 1 -04} {2089854000 -14400 0 -04} - {2106792000 -10800 1 -03} + {2106792000 -10800 1 -04} {2121303600 -14400 0 -04} - {2138241600 -10800 1 -03} + {2138241600 -10800 1 -04} {2153358000 -14400 0 -04} - {2169691200 -10800 1 -03} + {2169691200 -10800 1 -04} {2184807600 -14400 0 -04} - {2201140800 -10800 1 -03} + {2201140800 -10800 1 -04} {2216257200 -14400 0 -04} - {2233195200 -10800 1 -03} + {2233195200 -10800 1 -04} {2247706800 -14400 0 -04} - {2264644800 -10800 1 -03} + {2264644800 -10800 1 -04} {2279156400 -14400 0 -04} - {2296094400 -10800 1 -03} + {2296094400 -10800 1 -04} {2310606000 -14400 0 -04} - {2327544000 -10800 1 -03} + {2327544000 -10800 1 -04} {2342660400 -14400 0 -04} - {2358993600 -10800 1 -03} + {2358993600 -10800 1 -04} {2374110000 -14400 0 -04} - {2390443200 -10800 1 -03} + {2390443200 -10800 1 -04} {2405559600 -14400 0 -04} - {2422497600 -10800 1 -03} + {2422497600 -10800 1 -04} {2437009200 -14400 0 -04} - {2453947200 -10800 1 -03} + {2453947200 -10800 1 -04} {2468458800 -14400 0 -04} - {2485396800 -10800 1 -03} + {2485396800 -10800 1 -04} {2500513200 -14400 0 -04} - {2516846400 -10800 1 -03} + {2516846400 -10800 1 -04} {2531962800 -14400 0 -04} - {2548296000 -10800 1 -03} + {2548296000 -10800 1 -04} {2563412400 -14400 0 -04} - {2579745600 -10800 1 -03} + {2579745600 -10800 1 -04} {2594862000 -14400 0 -04} - {2611800000 -10800 1 -03} + {2611800000 -10800 1 -04} {2626311600 -14400 0 -04} - {2643249600 -10800 1 -03} + {2643249600 -10800 1 -04} {2657761200 -14400 0 -04} - {2674699200 -10800 1 -03} + {2674699200 -10800 1 -04} {2689815600 -14400 0 -04} - {2706148800 -10800 1 -03} + {2706148800 -10800 1 -04} {2721265200 -14400 0 -04} - {2737598400 -10800 1 -03} + {2737598400 -10800 1 -04} {2752714800 -14400 0 -04} - {2769652800 -10800 1 -03} + {2769652800 -10800 1 -04} {2784164400 -14400 0 -04} - {2801102400 -10800 1 -03} + {2801102400 -10800 1 -04} {2815614000 -14400 0 -04} - {2832552000 -10800 1 -03} + {2832552000 -10800 1 -04} {2847668400 -14400 0 -04} - {2864001600 -10800 1 -03} + {2864001600 -10800 1 -04} {2879118000 -14400 0 -04} - {2895451200 -10800 1 -03} + {2895451200 -10800 1 -04} {2910567600 -14400 0 -04} - {2926900800 -10800 1 -03} + {2926900800 -10800 1 -04} {2942017200 -14400 0 -04} - {2958955200 -10800 1 -03} + {2958955200 -10800 1 -04} {2973466800 -14400 0 -04} - {2990404800 -10800 1 -03} + {2990404800 -10800 1 -04} {3004916400 -14400 0 -04} - {3021854400 -10800 1 -03} + {3021854400 -10800 1 -04} {3036970800 -14400 0 -04} - {3053304000 -10800 1 -03} + {3053304000 -10800 1 -04} {3068420400 -14400 0 -04} - {3084753600 -10800 1 -03} + {3084753600 -10800 1 -04} {3099870000 -14400 0 -04} - {3116808000 -10800 1 -03} + {3116808000 -10800 1 -04} {3131319600 -14400 0 -04} - {3148257600 -10800 1 -03} + {3148257600 -10800 1 -04} {3162769200 -14400 0 -04} - {3179707200 -10800 1 -03} + {3179707200 -10800 1 -04} {3194218800 -14400 0 -04} - {3211156800 -10800 1 -03} + {3211156800 -10800 1 -04} {3226273200 -14400 0 -04} - {3242606400 -10800 1 -03} + {3242606400 -10800 1 -04} {3257722800 -14400 0 -04} - {3274056000 -10800 1 -03} + {3274056000 -10800 1 -04} {3289172400 -14400 0 -04} - {3306110400 -10800 1 -03} + {3306110400 -10800 1 -04} {3320622000 -14400 0 -04} - {3337560000 -10800 1 -03} + {3337560000 -10800 1 -04} {3352071600 -14400 0 -04} - {3369009600 -10800 1 -03} + {3369009600 -10800 1 -04} {3384126000 -14400 0 -04} - {3400459200 -10800 1 -03} + {3400459200 -10800 1 -04} {3415575600 -14400 0 -04} - {3431908800 -10800 1 -03} + {3431908800 -10800 1 -04} {3447025200 -14400 0 -04} - {3463358400 -10800 1 -03} + {3463358400 -10800 1 -04} {3478474800 -14400 0 -04} - {3495412800 -10800 1 -03} + {3495412800 -10800 1 -04} {3509924400 -14400 0 -04} - {3526862400 -10800 1 -03} + {3526862400 -10800 1 -04} {3541374000 -14400 0 -04} - {3558312000 -10800 1 -03} + {3558312000 -10800 1 -04} {3573428400 -14400 0 -04} - {3589761600 -10800 1 -03} + {3589761600 -10800 1 -04} {3604878000 -14400 0 -04} - {3621211200 -10800 1 -03} + {3621211200 -10800 1 -04} {3636327600 -14400 0 -04} - {3653265600 -10800 1 -03} + {3653265600 -10800 1 -04} {3667777200 -14400 0 -04} - {3684715200 -10800 1 -03} + {3684715200 -10800 1 -04} {3699226800 -14400 0 -04} - {3716164800 -10800 1 -03} + {3716164800 -10800 1 -04} {3731281200 -14400 0 -04} - {3747614400 -10800 1 -03} + {3747614400 -10800 1 -04} {3762730800 -14400 0 -04} - {3779064000 -10800 1 -03} + {3779064000 -10800 1 -04} {3794180400 -14400 0 -04} - {3810513600 -10800 1 -03} + {3810513600 -10800 1 -04} {3825630000 -14400 0 -04} - {3842568000 -10800 1 -03} + {3842568000 -10800 1 -04} {3857079600 -14400 0 -04} - {3874017600 -10800 1 -03} + {3874017600 -10800 1 -04} {3888529200 -14400 0 -04} - {3905467200 -10800 1 -03} + {3905467200 -10800 1 -04} {3920583600 -14400 0 -04} - {3936916800 -10800 1 -03} + {3936916800 -10800 1 -04} {3952033200 -14400 0 -04} - {3968366400 -10800 1 -03} + {3968366400 -10800 1 -04} {3983482800 -14400 0 -04} - {4000420800 -10800 1 -03} + {4000420800 -10800 1 -04} {4014932400 -14400 0 -04} - {4031870400 -10800 1 -03} + {4031870400 -10800 1 -04} {4046382000 -14400 0 -04} - {4063320000 -10800 1 -03} + {4063320000 -10800 1 -04} {4077831600 -14400 0 -04} - {4094769600 -10800 1 -03} + {4094769600 -10800 1 -04} } diff --git a/library/tzdata/America/Bahia b/library/tzdata/America/Bahia index 7dbcb90..7aaf834 100644 --- a/library/tzdata/America/Bahia +++ b/library/tzdata/America/Bahia @@ -3,66 +3,66 @@ set TZData(:America/Bahia) { {-9223372036854775808 -9244 0 LMT} {-1767216356 -10800 0 -03} - {-1206957600 -7200 1 -02} + {-1206957600 -7200 1 -03} {-1191362400 -10800 0 -03} - {-1175374800 -7200 1 -02} + {-1175374800 -7200 1 -03} {-1159826400 -10800 0 -03} - {-633819600 -7200 1 -02} + {-633819600 -7200 1 -03} {-622069200 -10800 0 -03} - {-602283600 -7200 1 -02} + {-602283600 -7200 1 -03} {-591832800 -10800 0 -03} - {-570747600 -7200 1 -02} + {-570747600 -7200 1 -03} {-560210400 -10800 0 -03} - {-539125200 -7200 1 -02} + {-539125200 -7200 1 -03} {-531352800 -10800 0 -03} - {-191365200 -7200 1 -02} + {-191365200 -7200 1 -03} {-184197600 -10800 0 -03} - {-155163600 -7200 1 -02} + {-155163600 -7200 1 -03} {-150069600 -10800 0 -03} - {-128898000 -7200 1 -02} + {-128898000 -7200 1 -03} {-121125600 -10800 0 -03} - {-99954000 -7200 1 -02} + {-99954000 -7200 1 -03} {-89589600 -10800 0 -03} - {-68418000 -7200 1 -02} + {-68418000 -7200 1 -03} {-57967200 -10800 0 -03} - {499748400 -7200 1 -02} + {499748400 -7200 1 -03} {511236000 -10800 0 -03} - {530593200 -7200 1 -02} + {530593200 -7200 1 -03} {540266400 -10800 0 -03} - {562129200 -7200 1 -02} + {562129200 -7200 1 -03} {571197600 -10800 0 -03} - {592974000 -7200 1 -02} + {592974000 -7200 1 -03} {602042400 -10800 0 -03} - {624423600 -7200 1 -02} + {624423600 -7200 1 -03} {634701600 -10800 0 -03} - {656478000 -7200 1 -02} + {656478000 -7200 1 -03} {666756000 -10800 0 -03} - {687927600 -7200 1 -02} + {687927600 -7200 1 -03} {697600800 -10800 0 -03} - {719982000 -7200 1 -02} + {719982000 -7200 1 -03} {728445600 -10800 0 -03} - {750826800 -7200 1 -02} + {750826800 -7200 1 -03} {761709600 -10800 0 -03} - {782276400 -7200 1 -02} + {782276400 -7200 1 -03} {793159200 -10800 0 -03} - {813726000 -7200 1 -02} + {813726000 -7200 1 -03} {824004000 -10800 0 -03} - {844570800 -7200 1 -02} + {844570800 -7200 1 -03} {856058400 -10800 0 -03} - {876106800 -7200 1 -02} + {876106800 -7200 1 -03} {888717600 -10800 0 -03} - {908074800 -7200 1 -02} + {908074800 -7200 1 -03} {919562400 -10800 0 -03} - {938919600 -7200 1 -02} + {938919600 -7200 1 -03} {951616800 -10800 0 -03} - {970974000 -7200 1 -02} + {970974000 -7200 1 -03} {982461600 -10800 0 -03} - {1003028400 -7200 1 -02} + {1003028400 -7200 1 -03} {1013911200 -10800 0 -03} - {1036292400 -7200 1 -02} + {1036292400 -7200 1 -03} {1045360800 -10800 0 -03} {1064368800 -10800 0 -03} - {1318734000 -7200 0 -02} + {1318734000 -7200 0 -03} {1330221600 -10800 0 -03} {1350784800 -10800 0 -03} } diff --git a/library/tzdata/America/Belem b/library/tzdata/America/Belem index b2bf3a6..42a3ec5 100644 --- a/library/tzdata/America/Belem +++ b/library/tzdata/America/Belem @@ -3,33 +3,33 @@ set TZData(:America/Belem) { {-9223372036854775808 -11636 0 LMT} {-1767213964 -10800 0 -03} - {-1206957600 -7200 1 -02} + {-1206957600 -7200 1 -03} {-1191362400 -10800 0 -03} - {-1175374800 -7200 1 -02} + {-1175374800 -7200 1 -03} {-1159826400 -10800 0 -03} - {-633819600 -7200 1 -02} + {-633819600 -7200 1 -03} {-622069200 -10800 0 -03} - {-602283600 -7200 1 -02} + {-602283600 -7200 1 -03} {-591832800 -10800 0 -03} - {-570747600 -7200 1 -02} + {-570747600 -7200 1 -03} {-560210400 -10800 0 -03} - {-539125200 -7200 1 -02} + {-539125200 -7200 1 -03} {-531352800 -10800 0 -03} - {-191365200 -7200 1 -02} + {-191365200 -7200 1 -03} {-184197600 -10800 0 -03} - {-155163600 -7200 1 -02} + {-155163600 -7200 1 -03} {-150069600 -10800 0 -03} - {-128898000 -7200 1 -02} + {-128898000 -7200 1 -03} {-121125600 -10800 0 -03} - {-99954000 -7200 1 -02} + {-99954000 -7200 1 -03} {-89589600 -10800 0 -03} - {-68418000 -7200 1 -02} + {-68418000 -7200 1 -03} {-57967200 -10800 0 -03} - {499748400 -7200 1 -02} + {499748400 -7200 1 -03} {511236000 -10800 0 -03} - {530593200 -7200 1 -02} + {530593200 -7200 1 -03} {540266400 -10800 0 -03} - {562129200 -7200 1 -02} + {562129200 -7200 1 -03} {571197600 -10800 0 -03} {590032800 -10800 0 -03} } diff --git a/library/tzdata/America/Boa_Vista b/library/tzdata/America/Boa_Vista index 982249b..0af989e 100644 --- a/library/tzdata/America/Boa_Vista +++ b/library/tzdata/America/Boa_Vista @@ -3,38 +3,38 @@ set TZData(:America/Boa_Vista) { {-9223372036854775808 -14560 0 LMT} {-1767211040 -14400 0 -04} - {-1206954000 -10800 1 -03} + {-1206954000 -10800 1 -04} {-1191358800 -14400 0 -04} - {-1175371200 -10800 1 -03} + {-1175371200 -10800 1 -04} {-1159822800 -14400 0 -04} - {-633816000 -10800 1 -03} + {-633816000 -10800 1 -04} {-622065600 -14400 0 -04} - {-602280000 -10800 1 -03} + {-602280000 -10800 1 -04} {-591829200 -14400 0 -04} - {-570744000 -10800 1 -03} + {-570744000 -10800 1 -04} {-560206800 -14400 0 -04} - {-539121600 -10800 1 -03} + {-539121600 -10800 1 -04} {-531349200 -14400 0 -04} - {-191361600 -10800 1 -03} + {-191361600 -10800 1 -04} {-184194000 -14400 0 -04} - {-155160000 -10800 1 -03} + {-155160000 -10800 1 -04} {-150066000 -14400 0 -04} - {-128894400 -10800 1 -03} + {-128894400 -10800 1 -04} {-121122000 -14400 0 -04} - {-99950400 -10800 1 -03} + {-99950400 -10800 1 -04} {-89586000 -14400 0 -04} - {-68414400 -10800 1 -03} + {-68414400 -10800 1 -04} {-57963600 -14400 0 -04} - {499752000 -10800 1 -03} + {499752000 -10800 1 -04} {511239600 -14400 0 -04} - {530596800 -10800 1 -03} + {530596800 -10800 1 -04} {540270000 -14400 0 -04} - {562132800 -10800 1 -03} + {562132800 -10800 1 -04} {571201200 -14400 0 -04} {590036400 -14400 0 -04} {938664000 -14400 0 -04} - {938923200 -10800 1 -03} + {938923200 -10800 1 -04} {951620400 -14400 0 -04} - {970977600 -10800 1 -03} + {970977600 -10800 1 -04} {971578800 -14400 0 -04} } diff --git a/library/tzdata/America/Bogota b/library/tzdata/America/Bogota index 69e4557..8ca39ba 100644 --- a/library/tzdata/America/Bogota +++ b/library/tzdata/America/Bogota @@ -4,6 +4,6 @@ set TZData(:America/Bogota) { {-9223372036854775808 -17776 0 LMT} {-2707671824 -17776 0 BMT} {-1739041424 -18000 0 -05} - {704869200 -14400 1 -04} + {704869200 -14400 1 -05} {733896000 -18000 0 -05} } diff --git a/library/tzdata/America/Campo_Grande b/library/tzdata/America/Campo_Grande index 77cb4d1..5ec7112 100644 --- a/library/tzdata/America/Campo_Grande +++ b/library/tzdata/America/Campo_Grande @@ -3,255 +3,255 @@ set TZData(:America/Campo_Grande) { {-9223372036854775808 -13108 0 LMT} {-1767212492 -14400 0 -04} - {-1206954000 -10800 1 -03} + {-1206954000 -10800 1 -04} {-1191358800 -14400 0 -04} - {-1175371200 -10800 1 -03} + {-1175371200 -10800 1 -04} {-1159822800 -14400 0 -04} - {-633816000 -10800 1 -03} + {-633816000 -10800 1 -04} {-622065600 -14400 0 -04} - {-602280000 -10800 1 -03} + {-602280000 -10800 1 -04} {-591829200 -14400 0 -04} - {-570744000 -10800 1 -03} + {-570744000 -10800 1 -04} {-560206800 -14400 0 -04} - {-539121600 -10800 1 -03} + {-539121600 -10800 1 -04} {-531349200 -14400 0 -04} - {-191361600 -10800 1 -03} + {-191361600 -10800 1 -04} {-184194000 -14400 0 -04} - {-155160000 -10800 1 -03} + {-155160000 -10800 1 -04} {-150066000 -14400 0 -04} - {-128894400 -10800 1 -03} + {-128894400 -10800 1 -04} {-121122000 -14400 0 -04} - {-99950400 -10800 1 -03} + {-99950400 -10800 1 -04} {-89586000 -14400 0 -04} - {-68414400 -10800 1 -03} + {-68414400 -10800 1 -04} {-57963600 -14400 0 -04} - {499752000 -10800 1 -03} + {499752000 -10800 1 -04} {511239600 -14400 0 -04} - {530596800 -10800 1 -03} + {530596800 -10800 1 -04} {540270000 -14400 0 -04} - {562132800 -10800 1 -03} + {562132800 -10800 1 -04} {571201200 -14400 0 -04} - {592977600 -10800 1 -03} + {592977600 -10800 1 -04} {602046000 -14400 0 -04} - {624427200 -10800 1 -03} + {624427200 -10800 1 -04} {634705200 -14400 0 -04} - {656481600 -10800 1 -03} + {656481600 -10800 1 -04} {666759600 -14400 0 -04} - {687931200 -10800 1 -03} + {687931200 -10800 1 -04} {697604400 -14400 0 -04} - {719985600 -10800 1 -03} + {719985600 -10800 1 -04} {728449200 -14400 0 -04} - {750830400 -10800 1 -03} + {750830400 -10800 1 -04} {761713200 -14400 0 -04} - {782280000 -10800 1 -03} + {782280000 -10800 1 -04} {793162800 -14400 0 -04} - {813729600 -10800 1 -03} + {813729600 -10800 1 -04} {824007600 -14400 0 -04} - {844574400 -10800 1 -03} + {844574400 -10800 1 -04} {856062000 -14400 0 -04} - {876110400 -10800 1 -03} + {876110400 -10800 1 -04} {888721200 -14400 0 -04} - {908078400 -10800 1 -03} + {908078400 -10800 1 -04} {919566000 -14400 0 -04} - {938923200 -10800 1 -03} + {938923200 -10800 1 -04} {951620400 -14400 0 -04} - {970977600 -10800 1 -03} + {970977600 -10800 1 -04} {982465200 -14400 0 -04} - {1003032000 -10800 1 -03} + {1003032000 -10800 1 -04} {1013914800 -14400 0 -04} - {1036296000 -10800 1 -03} + {1036296000 -10800 1 -04} {1045364400 -14400 0 -04} - {1066536000 -10800 1 -03} + {1066536000 -10800 1 -04} {1076814000 -14400 0 -04} - {1099368000 -10800 1 -03} + {1099368000 -10800 1 -04} {1108868400 -14400 0 -04} - {1129435200 -10800 1 -03} + {1129435200 -10800 1 -04} {1140318000 -14400 0 -04} - {1162699200 -10800 1 -03} + {1162699200 -10800 1 -04} {1172372400 -14400 0 -04} - {1192334400 -10800 1 -03} + {1192334400 -10800 1 -04} {1203217200 -14400 0 -04} - {1224388800 -10800 1 -03} + {1224388800 -10800 1 -04} {1234666800 -14400 0 -04} - {1255838400 -10800 1 -03} + {1255838400 -10800 1 -04} {1266721200 -14400 0 -04} - {1287288000 -10800 1 -03} + {1287288000 -10800 1 -04} {1298170800 -14400 0 -04} - {1318737600 -10800 1 -03} + {1318737600 -10800 1 -04} {1330225200 -14400 0 -04} - {1350792000 -10800 1 -03} + {1350792000 -10800 1 -04} {1361070000 -14400 0 -04} - {1382241600 -10800 1 -03} + {1382241600 -10800 1 -04} {1392519600 -14400 0 -04} - {1413691200 -10800 1 -03} + {1413691200 -10800 1 -04} {1424574000 -14400 0 -04} - {1445140800 -10800 1 -03} + {1445140800 -10800 1 -04} {1456023600 -14400 0 -04} - {1476590400 -10800 1 -03} + {1476590400 -10800 1 -04} {1487473200 -14400 0 -04} - {1508040000 -10800 1 -03} + {1508040000 -10800 1 -04} {1518922800 -14400 0 -04} - {1540094400 -10800 1 -03} + {1541304000 -10800 1 -04} {1550372400 -14400 0 -04} - {1571544000 -10800 1 -03} + {1572753600 -10800 1 -04} {1581822000 -14400 0 -04} - {1602993600 -10800 1 -03} + {1604203200 -10800 1 -04} {1613876400 -14400 0 -04} - {1634443200 -10800 1 -03} + {1636257600 -10800 1 -04} {1645326000 -14400 0 -04} - {1665892800 -10800 1 -03} + {1667707200 -10800 1 -04} {1677380400 -14400 0 -04} - {1697342400 -10800 1 -03} + {1699156800 -10800 1 -04} {1708225200 -14400 0 -04} - {1729396800 -10800 1 -03} + {1730606400 -10800 1 -04} {1739674800 -14400 0 -04} - {1760846400 -10800 1 -03} + {1762056000 -10800 1 -04} {1771729200 -14400 0 -04} - {1792296000 -10800 1 -03} + {1793505600 -10800 1 -04} {1803178800 -14400 0 -04} - {1823745600 -10800 1 -03} + {1825560000 -10800 1 -04} {1834628400 -14400 0 -04} - {1855195200 -10800 1 -03} + {1857009600 -10800 1 -04} {1866078000 -14400 0 -04} - {1887249600 -10800 1 -03} + {1888459200 -10800 1 -04} {1897527600 -14400 0 -04} - {1918699200 -10800 1 -03} + {1919908800 -10800 1 -04} {1928977200 -14400 0 -04} - {1950148800 -10800 1 -03} + {1951358400 -10800 1 -04} {1960426800 -14400 0 -04} - {1981598400 -10800 1 -03} + {1983412800 -10800 1 -04} {1992481200 -14400 0 -04} - {2013048000 -10800 1 -03} + {2014862400 -10800 1 -04} {2024535600 -14400 0 -04} - {2044497600 -10800 1 -03} + {2046312000 -10800 1 -04} {2055380400 -14400 0 -04} - {2076552000 -10800 1 -03} + {2077761600 -10800 1 -04} {2086830000 -14400 0 -04} - {2108001600 -10800 1 -03} + {2109211200 -10800 1 -04} {2118884400 -14400 0 -04} - {2139451200 -10800 1 -03} + {2140660800 -10800 1 -04} {2150334000 -14400 0 -04} - {2170900800 -10800 1 -03} + {2172715200 -10800 1 -04} {2181783600 -14400 0 -04} - {2202350400 -10800 1 -03} + {2204164800 -10800 1 -04} {2213233200 -14400 0 -04} - {2234404800 -10800 1 -03} + {2235614400 -10800 1 -04} {2244682800 -14400 0 -04} - {2265854400 -10800 1 -03} + {2267064000 -10800 1 -04} {2276132400 -14400 0 -04} - {2297304000 -10800 1 -03} + {2298513600 -10800 1 -04} {2307582000 -14400 0 -04} - {2328753600 -10800 1 -03} + {2329963200 -10800 1 -04} {2339636400 -14400 0 -04} - {2360203200 -10800 1 -03} + {2362017600 -10800 1 -04} {2371086000 -14400 0 -04} - {2391652800 -10800 1 -03} + {2393467200 -10800 1 -04} {2402535600 -14400 0 -04} - {2423707200 -10800 1 -03} + {2424916800 -10800 1 -04} {2433985200 -14400 0 -04} - {2455156800 -10800 1 -03} + {2456366400 -10800 1 -04} {2465434800 -14400 0 -04} - {2486606400 -10800 1 -03} + {2487816000 -10800 1 -04} {2497489200 -14400 0 -04} - {2518056000 -10800 1 -03} + {2519870400 -10800 1 -04} {2528938800 -14400 0 -04} - {2549505600 -10800 1 -03} + {2551320000 -10800 1 -04} {2560388400 -14400 0 -04} - {2580955200 -10800 1 -03} + {2582769600 -10800 1 -04} {2591838000 -14400 0 -04} - {2613009600 -10800 1 -03} + {2614219200 -10800 1 -04} {2623287600 -14400 0 -04} - {2644459200 -10800 1 -03} + {2645668800 -10800 1 -04} {2654737200 -14400 0 -04} - {2675908800 -10800 1 -03} + {2677118400 -10800 1 -04} {2686791600 -14400 0 -04} - {2707358400 -10800 1 -03} + {2709172800 -10800 1 -04} {2718241200 -14400 0 -04} - {2738808000 -10800 1 -03} + {2740622400 -10800 1 -04} {2749690800 -14400 0 -04} - {2770862400 -10800 1 -03} + {2772072000 -10800 1 -04} {2781140400 -14400 0 -04} - {2802312000 -10800 1 -03} + {2803521600 -10800 1 -04} {2812590000 -14400 0 -04} - {2833761600 -10800 1 -03} + {2834971200 -10800 1 -04} {2844039600 -14400 0 -04} - {2865211200 -10800 1 -03} + {2867025600 -10800 1 -04} {2876094000 -14400 0 -04} - {2896660800 -10800 1 -03} + {2898475200 -10800 1 -04} {2907543600 -14400 0 -04} - {2928110400 -10800 1 -03} + {2929924800 -10800 1 -04} {2938993200 -14400 0 -04} - {2960164800 -10800 1 -03} + {2961374400 -10800 1 -04} {2970442800 -14400 0 -04} - {2991614400 -10800 1 -03} + {2992824000 -10800 1 -04} {3001892400 -14400 0 -04} - {3023064000 -10800 1 -03} + {3024273600 -10800 1 -04} {3033946800 -14400 0 -04} - {3054513600 -10800 1 -03} + {3056328000 -10800 1 -04} {3065396400 -14400 0 -04} - {3085963200 -10800 1 -03} + {3087777600 -10800 1 -04} {3096846000 -14400 0 -04} - {3118017600 -10800 1 -03} + {3119227200 -10800 1 -04} {3128295600 -14400 0 -04} - {3149467200 -10800 1 -03} + {3150676800 -10800 1 -04} {3159745200 -14400 0 -04} - {3180916800 -10800 1 -03} + {3182126400 -10800 1 -04} {3191194800 -14400 0 -04} - {3212366400 -10800 1 -03} + {3213576000 -10800 1 -04} {3223249200 -14400 0 -04} - {3243816000 -10800 1 -03} + {3245630400 -10800 1 -04} {3254698800 -14400 0 -04} - {3275265600 -10800 1 -03} + {3277080000 -10800 1 -04} {3286148400 -14400 0 -04} - {3307320000 -10800 1 -03} + {3308529600 -10800 1 -04} {3317598000 -14400 0 -04} - {3338769600 -10800 1 -03} + {3339979200 -10800 1 -04} {3349047600 -14400 0 -04} - {3370219200 -10800 1 -03} + {3371428800 -10800 1 -04} {3381102000 -14400 0 -04} - {3401668800 -10800 1 -03} + {3403483200 -10800 1 -04} {3412551600 -14400 0 -04} - {3433118400 -10800 1 -03} + {3434932800 -10800 1 -04} {3444001200 -14400 0 -04} - {3464568000 -10800 1 -03} + {3466382400 -10800 1 -04} {3475450800 -14400 0 -04} - {3496622400 -10800 1 -03} + {3497832000 -10800 1 -04} {3506900400 -14400 0 -04} - {3528072000 -10800 1 -03} + {3529281600 -10800 1 -04} {3538350000 -14400 0 -04} - {3559521600 -10800 1 -03} + {3560731200 -10800 1 -04} {3570404400 -14400 0 -04} - {3590971200 -10800 1 -03} + {3592785600 -10800 1 -04} {3601854000 -14400 0 -04} - {3622420800 -10800 1 -03} + {3624235200 -10800 1 -04} {3633303600 -14400 0 -04} - {3654475200 -10800 1 -03} + {3655684800 -10800 1 -04} {3664753200 -14400 0 -04} - {3685924800 -10800 1 -03} + {3687134400 -10800 1 -04} {3696202800 -14400 0 -04} - {3717374400 -10800 1 -03} + {3718584000 -10800 1 -04} {3727652400 -14400 0 -04} - {3748824000 -10800 1 -03} + {3750638400 -10800 1 -04} {3759706800 -14400 0 -04} - {3780273600 -10800 1 -03} + {3782088000 -10800 1 -04} {3791156400 -14400 0 -04} - {3811723200 -10800 1 -03} + {3813537600 -10800 1 -04} {3822606000 -14400 0 -04} - {3843777600 -10800 1 -03} + {3844987200 -10800 1 -04} {3854055600 -14400 0 -04} - {3875227200 -10800 1 -03} + {3876436800 -10800 1 -04} {3885505200 -14400 0 -04} - {3906676800 -10800 1 -03} + {3907886400 -10800 1 -04} {3917559600 -14400 0 -04} - {3938126400 -10800 1 -03} + {3939940800 -10800 1 -04} {3949009200 -14400 0 -04} - {3969576000 -10800 1 -03} + {3971390400 -10800 1 -04} {3980458800 -14400 0 -04} - {4001630400 -10800 1 -03} + {4002840000 -10800 1 -04} {4011908400 -14400 0 -04} - {4033080000 -10800 1 -03} + {4034289600 -10800 1 -04} {4043358000 -14400 0 -04} - {4064529600 -10800 1 -03} + {4065739200 -10800 1 -04} {4074807600 -14400 0 -04} - {4095979200 -10800 1 -03} + {4097188800 -10800 1 -04} } diff --git a/library/tzdata/America/Cuiaba b/library/tzdata/America/Cuiaba index 57cd38c..09f5b1f 100644 --- a/library/tzdata/America/Cuiaba +++ b/library/tzdata/America/Cuiaba @@ -3,255 +3,255 @@ set TZData(:America/Cuiaba) { {-9223372036854775808 -13460 0 LMT} {-1767212140 -14400 0 -04} - {-1206954000 -10800 1 -03} + {-1206954000 -10800 1 -04} {-1191358800 -14400 0 -04} - {-1175371200 -10800 1 -03} + {-1175371200 -10800 1 -04} {-1159822800 -14400 0 -04} - {-633816000 -10800 1 -03} + {-633816000 -10800 1 -04} {-622065600 -14400 0 -04} - {-602280000 -10800 1 -03} + {-602280000 -10800 1 -04} {-591829200 -14400 0 -04} - {-570744000 -10800 1 -03} + {-570744000 -10800 1 -04} {-560206800 -14400 0 -04} - {-539121600 -10800 1 -03} + {-539121600 -10800 1 -04} {-531349200 -14400 0 -04} - {-191361600 -10800 1 -03} + {-191361600 -10800 1 -04} {-184194000 -14400 0 -04} - {-155160000 -10800 1 -03} + {-155160000 -10800 1 -04} {-150066000 -14400 0 -04} - {-128894400 -10800 1 -03} + {-128894400 -10800 1 -04} {-121122000 -14400 0 -04} - {-99950400 -10800 1 -03} + {-99950400 -10800 1 -04} {-89586000 -14400 0 -04} - {-68414400 -10800 1 -03} + {-68414400 -10800 1 -04} {-57963600 -14400 0 -04} - {499752000 -10800 1 -03} + {499752000 -10800 1 -04} {511239600 -14400 0 -04} - {530596800 -10800 1 -03} + {530596800 -10800 1 -04} {540270000 -14400 0 -04} - {562132800 -10800 1 -03} + {562132800 -10800 1 -04} {571201200 -14400 0 -04} - {592977600 -10800 1 -03} + {592977600 -10800 1 -04} {602046000 -14400 0 -04} - {624427200 -10800 1 -03} + {624427200 -10800 1 -04} {634705200 -14400 0 -04} - {656481600 -10800 1 -03} + {656481600 -10800 1 -04} {666759600 -14400 0 -04} - {687931200 -10800 1 -03} + {687931200 -10800 1 -04} {697604400 -14400 0 -04} - {719985600 -10800 1 -03} + {719985600 -10800 1 -04} {728449200 -14400 0 -04} - {750830400 -10800 1 -03} + {750830400 -10800 1 -04} {761713200 -14400 0 -04} - {782280000 -10800 1 -03} + {782280000 -10800 1 -04} {793162800 -14400 0 -04} - {813729600 -10800 1 -03} + {813729600 -10800 1 -04} {824007600 -14400 0 -04} - {844574400 -10800 1 -03} + {844574400 -10800 1 -04} {856062000 -14400 0 -04} - {876110400 -10800 1 -03} + {876110400 -10800 1 -04} {888721200 -14400 0 -04} - {908078400 -10800 1 -03} + {908078400 -10800 1 -04} {919566000 -14400 0 -04} - {938923200 -10800 1 -03} + {938923200 -10800 1 -04} {951620400 -14400 0 -04} - {970977600 -10800 1 -03} + {970977600 -10800 1 -04} {982465200 -14400 0 -04} - {1003032000 -10800 1 -03} + {1003032000 -10800 1 -04} {1013914800 -14400 0 -04} - {1036296000 -10800 1 -03} + {1036296000 -10800 1 -04} {1045364400 -14400 0 -04} {1064372400 -14400 0 -04} {1096603200 -14400 0 -04} - {1099368000 -10800 1 -03} + {1099368000 -10800 1 -04} {1108868400 -14400 0 -04} - {1129435200 -10800 1 -03} + {1129435200 -10800 1 -04} {1140318000 -14400 0 -04} - {1162699200 -10800 1 -03} + {1162699200 -10800 1 -04} {1172372400 -14400 0 -04} - {1192334400 -10800 1 -03} + {1192334400 -10800 1 -04} {1203217200 -14400 0 -04} - {1224388800 -10800 1 -03} + {1224388800 -10800 1 -04} {1234666800 -14400 0 -04} - {1255838400 -10800 1 -03} + {1255838400 -10800 1 -04} {1266721200 -14400 0 -04} - {1287288000 -10800 1 -03} + {1287288000 -10800 1 -04} {1298170800 -14400 0 -04} - {1318737600 -10800 1 -03} + {1318737600 -10800 1 -04} {1330225200 -14400 0 -04} - {1350792000 -10800 1 -03} + {1350792000 -10800 1 -04} {1361070000 -14400 0 -04} - {1382241600 -10800 1 -03} + {1382241600 -10800 1 -04} {1392519600 -14400 0 -04} - {1413691200 -10800 1 -03} + {1413691200 -10800 1 -04} {1424574000 -14400 0 -04} - {1445140800 -10800 1 -03} + {1445140800 -10800 1 -04} {1456023600 -14400 0 -04} - {1476590400 -10800 1 -03} + {1476590400 -10800 1 -04} {1487473200 -14400 0 -04} - {1508040000 -10800 1 -03} + {1508040000 -10800 1 -04} {1518922800 -14400 0 -04} - {1540094400 -10800 1 -03} + {1541304000 -10800 1 -04} {1550372400 -14400 0 -04} - {1571544000 -10800 1 -03} + {1572753600 -10800 1 -04} {1581822000 -14400 0 -04} - {1602993600 -10800 1 -03} + {1604203200 -10800 1 -04} {1613876400 -14400 0 -04} - {1634443200 -10800 1 -03} + {1636257600 -10800 1 -04} {1645326000 -14400 0 -04} - {1665892800 -10800 1 -03} + {1667707200 -10800 1 -04} {1677380400 -14400 0 -04} - {1697342400 -10800 1 -03} + {1699156800 -10800 1 -04} {1708225200 -14400 0 -04} - {1729396800 -10800 1 -03} + {1730606400 -10800 1 -04} {1739674800 -14400 0 -04} - {1760846400 -10800 1 -03} + {1762056000 -10800 1 -04} {1771729200 -14400 0 -04} - {1792296000 -10800 1 -03} + {1793505600 -10800 1 -04} {1803178800 -14400 0 -04} - {1823745600 -10800 1 -03} + {1825560000 -10800 1 -04} {1834628400 -14400 0 -04} - {1855195200 -10800 1 -03} + {1857009600 -10800 1 -04} {1866078000 -14400 0 -04} - {1887249600 -10800 1 -03} + {1888459200 -10800 1 -04} {1897527600 -14400 0 -04} - {1918699200 -10800 1 -03} + {1919908800 -10800 1 -04} {1928977200 -14400 0 -04} - {1950148800 -10800 1 -03} + {1951358400 -10800 1 -04} {1960426800 -14400 0 -04} - {1981598400 -10800 1 -03} + {1983412800 -10800 1 -04} {1992481200 -14400 0 -04} - {2013048000 -10800 1 -03} + {2014862400 -10800 1 -04} {2024535600 -14400 0 -04} - {2044497600 -10800 1 -03} + {2046312000 -10800 1 -04} {2055380400 -14400 0 -04} - {2076552000 -10800 1 -03} + {2077761600 -10800 1 -04} {2086830000 -14400 0 -04} - {2108001600 -10800 1 -03} + {2109211200 -10800 1 -04} {2118884400 -14400 0 -04} - {2139451200 -10800 1 -03} + {2140660800 -10800 1 -04} {2150334000 -14400 0 -04} - {2170900800 -10800 1 -03} + {2172715200 -10800 1 -04} {2181783600 -14400 0 -04} - {2202350400 -10800 1 -03} + {2204164800 -10800 1 -04} {2213233200 -14400 0 -04} - {2234404800 -10800 1 -03} + {2235614400 -10800 1 -04} {2244682800 -14400 0 -04} - {2265854400 -10800 1 -03} + {2267064000 -10800 1 -04} {2276132400 -14400 0 -04} - {2297304000 -10800 1 -03} + {2298513600 -10800 1 -04} {2307582000 -14400 0 -04} - {2328753600 -10800 1 -03} + {2329963200 -10800 1 -04} {2339636400 -14400 0 -04} - {2360203200 -10800 1 -03} + {2362017600 -10800 1 -04} {2371086000 -14400 0 -04} - {2391652800 -10800 1 -03} + {2393467200 -10800 1 -04} {2402535600 -14400 0 -04} - {2423707200 -10800 1 -03} + {2424916800 -10800 1 -04} {2433985200 -14400 0 -04} - {2455156800 -10800 1 -03} + {2456366400 -10800 1 -04} {2465434800 -14400 0 -04} - {2486606400 -10800 1 -03} + {2487816000 -10800 1 -04} {2497489200 -14400 0 -04} - {2518056000 -10800 1 -03} + {2519870400 -10800 1 -04} {2528938800 -14400 0 -04} - {2549505600 -10800 1 -03} + {2551320000 -10800 1 -04} {2560388400 -14400 0 -04} - {2580955200 -10800 1 -03} + {2582769600 -10800 1 -04} {2591838000 -14400 0 -04} - {2613009600 -10800 1 -03} + {2614219200 -10800 1 -04} {2623287600 -14400 0 -04} - {2644459200 -10800 1 -03} + {2645668800 -10800 1 -04} {2654737200 -14400 0 -04} - {2675908800 -10800 1 -03} + {2677118400 -10800 1 -04} {2686791600 -14400 0 -04} - {2707358400 -10800 1 -03} + {2709172800 -10800 1 -04} {2718241200 -14400 0 -04} - {2738808000 -10800 1 -03} + {2740622400 -10800 1 -04} {2749690800 -14400 0 -04} - {2770862400 -10800 1 -03} + {2772072000 -10800 1 -04} {2781140400 -14400 0 -04} - {2802312000 -10800 1 -03} + {2803521600 -10800 1 -04} {2812590000 -14400 0 -04} - {2833761600 -10800 1 -03} + {2834971200 -10800 1 -04} {2844039600 -14400 0 -04} - {2865211200 -10800 1 -03} + {2867025600 -10800 1 -04} {2876094000 -14400 0 -04} - {2896660800 -10800 1 -03} + {2898475200 -10800 1 -04} {2907543600 -14400 0 -04} - {2928110400 -10800 1 -03} + {2929924800 -10800 1 -04} {2938993200 -14400 0 -04} - {2960164800 -10800 1 -03} + {2961374400 -10800 1 -04} {2970442800 -14400 0 -04} - {2991614400 -10800 1 -03} + {2992824000 -10800 1 -04} {3001892400 -14400 0 -04} - {3023064000 -10800 1 -03} + {3024273600 -10800 1 -04} {3033946800 -14400 0 -04} - {3054513600 -10800 1 -03} + {3056328000 -10800 1 -04} {3065396400 -14400 0 -04} - {3085963200 -10800 1 -03} + {3087777600 -10800 1 -04} {3096846000 -14400 0 -04} - {3118017600 -10800 1 -03} + {3119227200 -10800 1 -04} {3128295600 -14400 0 -04} - {3149467200 -10800 1 -03} + {3150676800 -10800 1 -04} {3159745200 -14400 0 -04} - {3180916800 -10800 1 -03} + {3182126400 -10800 1 -04} {3191194800 -14400 0 -04} - {3212366400 -10800 1 -03} + {3213576000 -10800 1 -04} {3223249200 -14400 0 -04} - {3243816000 -10800 1 -03} + {3245630400 -10800 1 -04} {3254698800 -14400 0 -04} - {3275265600 -10800 1 -03} + {3277080000 -10800 1 -04} {3286148400 -14400 0 -04} - {3307320000 -10800 1 -03} + {3308529600 -10800 1 -04} {3317598000 -14400 0 -04} - {3338769600 -10800 1 -03} + {3339979200 -10800 1 -04} {3349047600 -14400 0 -04} - {3370219200 -10800 1 -03} + {3371428800 -10800 1 -04} {3381102000 -14400 0 -04} - {3401668800 -10800 1 -03} + {3403483200 -10800 1 -04} {3412551600 -14400 0 -04} - {3433118400 -10800 1 -03} + {3434932800 -10800 1 -04} {3444001200 -14400 0 -04} - {3464568000 -10800 1 -03} + {3466382400 -10800 1 -04} {3475450800 -14400 0 -04} - {3496622400 -10800 1 -03} + {3497832000 -10800 1 -04} {3506900400 -14400 0 -04} - {3528072000 -10800 1 -03} + {3529281600 -10800 1 -04} {3538350000 -14400 0 -04} - {3559521600 -10800 1 -03} + {3560731200 -10800 1 -04} {3570404400 -14400 0 -04} - {3590971200 -10800 1 -03} + {3592785600 -10800 1 -04} {3601854000 -14400 0 -04} - {3622420800 -10800 1 -03} + {3624235200 -10800 1 -04} {3633303600 -14400 0 -04} - {3654475200 -10800 1 -03} + {3655684800 -10800 1 -04} {3664753200 -14400 0 -04} - {3685924800 -10800 1 -03} + {3687134400 -10800 1 -04} {3696202800 -14400 0 -04} - {3717374400 -10800 1 -03} + {3718584000 -10800 1 -04} {3727652400 -14400 0 -04} - {3748824000 -10800 1 -03} + {3750638400 -10800 1 -04} {3759706800 -14400 0 -04} - {3780273600 -10800 1 -03} + {3782088000 -10800 1 -04} {3791156400 -14400 0 -04} - {3811723200 -10800 1 -03} + {3813537600 -10800 1 -04} {3822606000 -14400 0 -04} - {3843777600 -10800 1 -03} + {3844987200 -10800 1 -04} {3854055600 -14400 0 -04} - {3875227200 -10800 1 -03} + {3876436800 -10800 1 -04} {3885505200 -14400 0 -04} - {3906676800 -10800 1 -03} + {3907886400 -10800 1 -04} {3917559600 -14400 0 -04} - {3938126400 -10800 1 -03} + {3939940800 -10800 1 -04} {3949009200 -14400 0 -04} - {3969576000 -10800 1 -03} + {3971390400 -10800 1 -04} {3980458800 -14400 0 -04} - {4001630400 -10800 1 -03} + {4002840000 -10800 1 -04} {4011908400 -14400 0 -04} - {4033080000 -10800 1 -03} + {4034289600 -10800 1 -04} {4043358000 -14400 0 -04} - {4064529600 -10800 1 -03} + {4065739200 -10800 1 -04} {4074807600 -14400 0 -04} - {4095979200 -10800 1 -03} + {4097188800 -10800 1 -04} } diff --git a/library/tzdata/America/Eirunepe b/library/tzdata/America/Eirunepe index 41b4cc9..a81b09e 100644 --- a/library/tzdata/America/Eirunepe +++ b/library/tzdata/America/Eirunepe @@ -3,37 +3,37 @@ set TZData(:America/Eirunepe) { {-9223372036854775808 -16768 0 LMT} {-1767208832 -18000 0 -05} - {-1206950400 -14400 1 -04} + {-1206950400 -14400 1 -05} {-1191355200 -18000 0 -05} - {-1175367600 -14400 1 -04} + {-1175367600 -14400 1 -05} {-1159819200 -18000 0 -05} - {-633812400 -14400 1 -04} + {-633812400 -14400 1 -05} {-622062000 -18000 0 -05} - {-602276400 -14400 1 -04} + {-602276400 -14400 1 -05} {-591825600 -18000 0 -05} - {-570740400 -14400 1 -04} + {-570740400 -14400 1 -05} {-560203200 -18000 0 -05} - {-539118000 -14400 1 -04} + {-539118000 -14400 1 -05} {-531345600 -18000 0 -05} - {-191358000 -14400 1 -04} + {-191358000 -14400 1 -05} {-184190400 -18000 0 -05} - {-155156400 -14400 1 -04} + {-155156400 -14400 1 -05} {-150062400 -18000 0 -05} - {-128890800 -14400 1 -04} + {-128890800 -14400 1 -05} {-121118400 -18000 0 -05} - {-99946800 -14400 1 -04} + {-99946800 -14400 1 -05} {-89582400 -18000 0 -05} - {-68410800 -14400 1 -04} + {-68410800 -14400 1 -05} {-57960000 -18000 0 -05} - {499755600 -14400 1 -04} + {499755600 -14400 1 -05} {511243200 -18000 0 -05} - {530600400 -14400 1 -04} + {530600400 -14400 1 -05} {540273600 -18000 0 -05} - {562136400 -14400 1 -04} + {562136400 -14400 1 -05} {571204800 -18000 0 -05} {590040000 -18000 0 -05} {749192400 -18000 0 -05} - {750834000 -14400 1 -04} + {750834000 -14400 1 -05} {761716800 -18000 0 -05} {780206400 -18000 0 -05} {1214283600 -14400 0 -04} diff --git a/library/tzdata/America/Fortaleza b/library/tzdata/America/Fortaleza index 06c7b84..bd806f1 100644 --- a/library/tzdata/America/Fortaleza +++ b/library/tzdata/America/Fortaleza @@ -3,46 +3,46 @@ set TZData(:America/Fortaleza) { {-9223372036854775808 -9240 0 LMT} {-1767216360 -10800 0 -03} - {-1206957600 -7200 1 -02} + {-1206957600 -7200 1 -03} {-1191362400 -10800 0 -03} - {-1175374800 -7200 1 -02} + {-1175374800 -7200 1 -03} {-1159826400 -10800 0 -03} - {-633819600 -7200 1 -02} + {-633819600 -7200 1 -03} {-622069200 -10800 0 -03} - {-602283600 -7200 1 -02} + {-602283600 -7200 1 -03} {-591832800 -10800 0 -03} - {-570747600 -7200 1 -02} + {-570747600 -7200 1 -03} {-560210400 -10800 0 -03} - {-539125200 -7200 1 -02} + {-539125200 -7200 1 -03} {-531352800 -10800 0 -03} - {-191365200 -7200 1 -02} + {-191365200 -7200 1 -03} {-184197600 -10800 0 -03} - {-155163600 -7200 1 -02} + {-155163600 -7200 1 -03} {-150069600 -10800 0 -03} - {-128898000 -7200 1 -02} + {-128898000 -7200 1 -03} {-121125600 -10800 0 -03} - {-99954000 -7200 1 -02} + {-99954000 -7200 1 -03} {-89589600 -10800 0 -03} - {-68418000 -7200 1 -02} + {-68418000 -7200 1 -03} {-57967200 -10800 0 -03} - {499748400 -7200 1 -02} + {499748400 -7200 1 -03} {511236000 -10800 0 -03} - {530593200 -7200 1 -02} + {530593200 -7200 1 -03} {540266400 -10800 0 -03} - {562129200 -7200 1 -02} + {562129200 -7200 1 -03} {571197600 -10800 0 -03} - {592974000 -7200 1 -02} + {592974000 -7200 1 -03} {602042400 -10800 0 -03} - {624423600 -7200 1 -02} + {624423600 -7200 1 -03} {634701600 -10800 0 -03} {653536800 -10800 0 -03} {938660400 -10800 0 -03} - {938919600 -7200 1 -02} + {938919600 -7200 1 -03} {951616800 -10800 0 -03} - {970974000 -7200 1 -02} + {970974000 -7200 1 -03} {972180000 -10800 0 -03} {1000350000 -10800 0 -03} - {1003028400 -7200 1 -02} + {1003028400 -7200 1 -03} {1013911200 -10800 0 -03} {1033437600 -10800 0 -03} } diff --git a/library/tzdata/America/Grand_Turk b/library/tzdata/America/Grand_Turk index c963adc..da5f09b 100644 --- a/library/tzdata/America/Grand_Turk +++ b/library/tzdata/America/Grand_Turk @@ -2,8 +2,8 @@ set TZData(:America/Grand_Turk) { {-9223372036854775808 -17072 0 LMT} - {-2524504528 -18431 0 KMT} - {-1827687169 -18000 0 EST} + {-2524504528 -18430 0 KMT} + {-1827687170 -18000 0 EST} {284014800 -18000 0 EST} {294217200 -14400 1 EDT} {309938400 -18000 0 EST} diff --git a/library/tzdata/America/Guayaquil b/library/tzdata/America/Guayaquil index 353eb69..6ba7b93 100644 --- a/library/tzdata/America/Guayaquil +++ b/library/tzdata/America/Guayaquil @@ -4,6 +4,6 @@ set TZData(:America/Guayaquil) { {-9223372036854775808 -19160 0 LMT} {-2524502440 -18840 0 QMT} {-1230749160 -18000 0 -05} - {722926800 -14400 1 -04} + {722926800 -14400 1 -05} {728884800 -18000 0 -05} } diff --git a/library/tzdata/America/Jamaica b/library/tzdata/America/Jamaica index f752842..0f758bd 100644 --- a/library/tzdata/America/Jamaica +++ b/library/tzdata/America/Jamaica @@ -1,9 +1,9 @@ # created by tools/tclZIC.tcl - do not edit set TZData(:America/Jamaica) { - {-9223372036854775808 -18431 0 LMT} - {-2524503169 -18431 0 KMT} - {-1827687169 -18000 0 EST} + {-9223372036854775808 -18430 0 LMT} + {-2524503170 -18430 0 KMT} + {-1827687170 -18000 0 EST} {126248400 -18000 0 EST} {126687600 -14400 1 EDT} {152085600 -18000 0 EST} diff --git a/library/tzdata/America/La_Paz b/library/tzdata/America/La_Paz index a245afd..ea2f711 100644 --- a/library/tzdata/America/La_Paz +++ b/library/tzdata/America/La_Paz @@ -3,6 +3,6 @@ set TZData(:America/La_Paz) { {-9223372036854775808 -16356 0 LMT} {-2524505244 -16356 0 CMT} - {-1205954844 -12756 1 BOST} + {-1205954844 -12756 1 BST} {-1192307244 -14400 0 -04} } diff --git a/library/tzdata/America/Lima b/library/tzdata/America/Lima index b224a64..e8b69d6 100644 --- a/library/tzdata/America/Lima +++ b/library/tzdata/America/Lima @@ -3,11 +3,11 @@ set TZData(:America/Lima) { {-9223372036854775808 -18492 0 LMT} {-2524503108 -18516 0 LMT} - {-1938538284 -14400 0 -04} + {-1938538284 -14400 0 -05} {-1002052800 -18000 0 -05} - {-986756400 -14400 1 -04} + {-986756400 -14400 1 -05} {-971035200 -18000 0 -05} - {-955306800 -14400 1 -04} + {-955306800 -14400 1 -05} {-939585600 -18000 0 -05} {512712000 -18000 0 -05} {544248000 -18000 0 -05} diff --git a/library/tzdata/America/Maceio b/library/tzdata/America/Maceio index e6ed548..eab534e 100644 --- a/library/tzdata/America/Maceio +++ b/library/tzdata/America/Maceio @@ -3,50 +3,50 @@ set TZData(:America/Maceio) { {-9223372036854775808 -8572 0 LMT} {-1767217028 -10800 0 -03} - {-1206957600 -7200 1 -02} + {-1206957600 -7200 1 -03} {-1191362400 -10800 0 -03} - {-1175374800 -7200 1 -02} + {-1175374800 -7200 1 -03} {-1159826400 -10800 0 -03} - {-633819600 -7200 1 -02} + {-633819600 -7200 1 -03} {-622069200 -10800 0 -03} - {-602283600 -7200 1 -02} + {-602283600 -7200 1 -03} {-591832800 -10800 0 -03} - {-570747600 -7200 1 -02} + {-570747600 -7200 1 -03} {-560210400 -10800 0 -03} - {-539125200 -7200 1 -02} + {-539125200 -7200 1 -03} {-531352800 -10800 0 -03} - {-191365200 -7200 1 -02} + {-191365200 -7200 1 -03} {-184197600 -10800 0 -03} - {-155163600 -7200 1 -02} + {-155163600 -7200 1 -03} {-150069600 -10800 0 -03} - {-128898000 -7200 1 -02} + {-128898000 -7200 1 -03} {-121125600 -10800 0 -03} - {-99954000 -7200 1 -02} + {-99954000 -7200 1 -03} {-89589600 -10800 0 -03} - {-68418000 -7200 1 -02} + {-68418000 -7200 1 -03} {-57967200 -10800 0 -03} - {499748400 -7200 1 -02} + {499748400 -7200 1 -03} {511236000 -10800 0 -03} - {530593200 -7200 1 -02} + {530593200 -7200 1 -03} {540266400 -10800 0 -03} - {562129200 -7200 1 -02} + {562129200 -7200 1 -03} {571197600 -10800 0 -03} - {592974000 -7200 1 -02} + {592974000 -7200 1 -03} {602042400 -10800 0 -03} - {624423600 -7200 1 -02} + {624423600 -7200 1 -03} {634701600 -10800 0 -03} {653536800 -10800 0 -03} {813553200 -10800 0 -03} - {813726000 -7200 1 -02} + {813726000 -7200 1 -03} {824004000 -10800 0 -03} {841802400 -10800 0 -03} {938660400 -10800 0 -03} - {938919600 -7200 1 -02} + {938919600 -7200 1 -03} {951616800 -10800 0 -03} - {970974000 -7200 1 -02} + {970974000 -7200 1 -03} {972180000 -10800 0 -03} {1000350000 -10800 0 -03} - {1003028400 -7200 1 -02} + {1003028400 -7200 1 -03} {1013911200 -10800 0 -03} {1033437600 -10800 0 -03} } diff --git a/library/tzdata/America/Manaus b/library/tzdata/America/Manaus index f17023c..a855062 100644 --- a/library/tzdata/America/Manaus +++ b/library/tzdata/America/Manaus @@ -3,37 +3,37 @@ set TZData(:America/Manaus) { {-9223372036854775808 -14404 0 LMT} {-1767211196 -14400 0 -04} - {-1206954000 -10800 1 -03} + {-1206954000 -10800 1 -04} {-1191358800 -14400 0 -04} - {-1175371200 -10800 1 -03} + {-1175371200 -10800 1 -04} {-1159822800 -14400 0 -04} - {-633816000 -10800 1 -03} + {-633816000 -10800 1 -04} {-622065600 -14400 0 -04} - {-602280000 -10800 1 -03} + {-602280000 -10800 1 -04} {-591829200 -14400 0 -04} - {-570744000 -10800 1 -03} + {-570744000 -10800 1 -04} {-560206800 -14400 0 -04} - {-539121600 -10800 1 -03} + {-539121600 -10800 1 -04} {-531349200 -14400 0 -04} - {-191361600 -10800 1 -03} + {-191361600 -10800 1 -04} {-184194000 -14400 0 -04} - {-155160000 -10800 1 -03} + {-155160000 -10800 1 -04} {-150066000 -14400 0 -04} - {-128894400 -10800 1 -03} + {-128894400 -10800 1 -04} {-121122000 -14400 0 -04} - {-99950400 -10800 1 -03} + {-99950400 -10800 1 -04} {-89586000 -14400 0 -04} - {-68414400 -10800 1 -03} + {-68414400 -10800 1 -04} {-57963600 -14400 0 -04} - {499752000 -10800 1 -03} + {499752000 -10800 1 -04} {511239600 -14400 0 -04} - {530596800 -10800 1 -03} + {530596800 -10800 1 -04} {540270000 -14400 0 -04} - {562132800 -10800 1 -03} + {562132800 -10800 1 -04} {571201200 -14400 0 -04} {590036400 -14400 0 -04} {749188800 -14400 0 -04} - {750830400 -10800 1 -03} + {750830400 -10800 1 -04} {761713200 -14400 0 -04} {780202800 -14400 0 -04} } diff --git a/library/tzdata/America/Montevideo b/library/tzdata/America/Montevideo index ff85fb3..27fb76e 100644 --- a/library/tzdata/America/Montevideo +++ b/library/tzdata/America/Montevideo @@ -1,96 +1,96 @@ # created by tools/tclZIC.tcl - do not edit set TZData(:America/Montevideo) { - {-9223372036854775808 -13484 0 LMT} - {-2256668116 -13484 0 MMT} - {-1567455316 -12600 0 -0330} - {-1459542600 -10800 1 -03} + {-9223372036854775808 -13491 0 LMT} + {-1942690509 -13491 0 MMT} + {-1567455309 -14400 0 -04} + {-1459627200 -10800 0 -0330} {-1443819600 -12600 0 -0330} - {-1428006600 -10800 1 -03} + {-1428006600 -10800 1 -0330} {-1412283600 -12600 0 -0330} - {-1396470600 -10800 1 -03} + {-1396470600 -10800 1 -0330} {-1380747600 -12600 0 -0330} - {-1141590600 -10800 1 -03} + {-1141590600 -10800 1 -0330} {-1128286800 -12600 0 -0330} - {-1110141000 -10800 1 -03} + {-1110141000 -10800 1 -0330} {-1096837200 -12600 0 -0330} - {-1078691400 -10800 1 -03} + {-1078691400 -10800 1 -0330} {-1065387600 -12600 0 -0330} - {-1046637000 -10800 1 -03} + {-1047241800 -10800 1 -0330} {-1033938000 -12600 0 -0330} - {-1015187400 -10800 1 -03} + {-1015187400 -10800 1 -0330} {-1002488400 -12600 0 -0330} - {-983737800 -10800 1 -03} + {-983737800 -10800 1 -0330} {-971038800 -12600 0 -0330} - {-952288200 -10800 1 -03} + {-954707400 -10800 1 -0330} {-938984400 -12600 0 -0330} - {-920838600 -10800 1 -03} + {-920838600 -10800 1 -0330} {-907534800 -12600 0 -0330} - {-896819400 -10800 1 -03} - {-853623000 -10800 0 -03} - {-853621200 -7200 1 -02} - {-845848800 -10800 0 -03} - {-334789200 -7200 1 -02} - {-319672800 -10800 0 -03} - {-314226000 -7200 1 -02} + {-896819400 -10800 1 -0330} + {-853621200 -9000 0 -03} + {-845847000 -10800 0 -03} + {-334789200 -9000 1 -03} + {-319671000 -10800 0 -03} + {-315608400 -10800 0 -03} + {-314226000 -7200 1 -03} {-309996000 -10800 0 -03} - {-149720400 -7200 1 -02} + {-149720400 -7200 1 -03} {-134604000 -10800 0 -03} - {-118270800 -7200 1 -02} - {-100044000 -10800 0 -03} - {-86821200 -7200 1 -02} - {-68508000 -10800 0 -03} {-63147600 -10800 0 -03} - {-50446800 -9000 1 -0230} - {-34119000 -10800 0 -03} - {-18910800 -9000 1 -0230} - {-2583000 -10800 0 -03} - {12625200 -9000 1 -0230} - {28953000 -10800 0 -03} - {31546800 -10800 0 -03} - {72932400 -7200 1 -02} - {82692000 -10800 0 -03} + {-50446800 -9000 1 -03} + {-34205400 -10800 0 -03} + {10800 -10800 0 -03} + {9860400 -7200 1 -03} + {14176800 -10800 0 -03} + {72846000 -7200 1 -03} + {80100000 -10800 0 -03} {126241200 -10800 0 -03} - {132116400 -9000 1 -0230} - {156909600 -9000 0 -02} - {156911400 -7200 1 -02} - {212983200 -10800 0 -03} - {250052400 -7200 1 -02} - {260244000 -10800 0 -03} - {307594800 -7200 1 -02} - {325994400 -10800 0 -03} - {566449200 -7200 1 -02} - {574308000 -10800 0 -03} - {597812400 -7200 1 -02} - {605671200 -10800 0 -03} - {625633200 -7200 1 -02} - {636516000 -10800 0 -03} - {656478000 -7200 1 -02} + {127278000 -5400 1 -03} + {132112800 -9000 0 -03} + {147234600 -10800 0 -03} + {156909600 -10800 0 -03} + {156913200 -7200 1 -03} + {165376800 -10800 0 -03} + {219812400 -7200 1 -03} + {226461600 -10800 0 -03} + {250052400 -7200 1 -03} + {257911200 -10800 0 -03} + {282711600 -7200 1 -03} + {289360800 -10800 0 -03} + {294202800 -7200 1 -03} + {322020000 -10800 0 -03} + {566449200 -7200 1 -03} + {573012000 -10800 0 -03} + {597812400 -7200 1 -03} + {605066400 -10800 0 -03} + {625633200 -7200 1 -03} + {635911200 -10800 0 -03} + {656478000 -7200 1 -03} {667965600 -10800 0 -03} - {688532400 -7200 1 -02} + {688532400 -7200 1 -03} {699415200 -10800 0 -03} - {719377200 -7200 1 -02} + {719377200 -7200 1 -03} {730864800 -10800 0 -03} - {1095562800 -7200 1 -02} + {1095562800 -7200 1 -03} {1111896000 -10800 0 -03} - {1128834000 -7200 1 -02} + {1128834000 -7200 1 -03} {1142136000 -10800 0 -03} - {1159678800 -7200 1 -02} + {1159678800 -7200 1 -03} {1173585600 -10800 0 -03} - {1191733200 -7200 1 -02} + {1191733200 -7200 1 -03} {1205035200 -10800 0 -03} - {1223182800 -7200 1 -02} + {1223182800 -7200 1 -03} {1236484800 -10800 0 -03} - {1254632400 -7200 1 -02} + {1254632400 -7200 1 -03} {1268539200 -10800 0 -03} - {1286082000 -7200 1 -02} + {1286082000 -7200 1 -03} {1299988800 -10800 0 -03} - {1317531600 -7200 1 -02} + {1317531600 -7200 1 -03} {1331438400 -10800 0 -03} - {1349586000 -7200 1 -02} + {1349586000 -7200 1 -03} {1362888000 -10800 0 -03} - {1381035600 -7200 1 -02} + {1381035600 -7200 1 -03} {1394337600 -10800 0 -03} - {1412485200 -7200 1 -02} + {1412485200 -7200 1 -03} {1425787200 -10800 0 -03} } diff --git a/library/tzdata/America/Noronha b/library/tzdata/America/Noronha index f24b412..01fb745 100644 --- a/library/tzdata/America/Noronha +++ b/library/tzdata/America/Noronha @@ -3,46 +3,46 @@ set TZData(:America/Noronha) { {-9223372036854775808 -7780 0 LMT} {-1767217820 -7200 0 -02} - {-1206961200 -3600 1 -01} + {-1206961200 -3600 1 -02} {-1191366000 -7200 0 -02} - {-1175378400 -3600 1 -01} + {-1175378400 -3600 1 -02} {-1159830000 -7200 0 -02} - {-633823200 -3600 1 -01} + {-633823200 -3600 1 -02} {-622072800 -7200 0 -02} - {-602287200 -3600 1 -01} + {-602287200 -3600 1 -02} {-591836400 -7200 0 -02} - {-570751200 -3600 1 -01} + {-570751200 -3600 1 -02} {-560214000 -7200 0 -02} - {-539128800 -3600 1 -01} + {-539128800 -3600 1 -02} {-531356400 -7200 0 -02} - {-191368800 -3600 1 -01} + {-191368800 -3600 1 -02} {-184201200 -7200 0 -02} - {-155167200 -3600 1 -01} + {-155167200 -3600 1 -02} {-150073200 -7200 0 -02} - {-128901600 -3600 1 -01} + {-128901600 -3600 1 -02} {-121129200 -7200 0 -02} - {-99957600 -3600 1 -01} + {-99957600 -3600 1 -02} {-89593200 -7200 0 -02} - {-68421600 -3600 1 -01} + {-68421600 -3600 1 -02} {-57970800 -7200 0 -02} - {499744800 -3600 1 -01} + {499744800 -3600 1 -02} {511232400 -7200 0 -02} - {530589600 -3600 1 -01} + {530589600 -3600 1 -02} {540262800 -7200 0 -02} - {562125600 -3600 1 -01} + {562125600 -3600 1 -02} {571194000 -7200 0 -02} - {592970400 -3600 1 -01} + {592970400 -3600 1 -02} {602038800 -7200 0 -02} - {624420000 -3600 1 -01} + {624420000 -3600 1 -02} {634698000 -7200 0 -02} {653533200 -7200 0 -02} {938656800 -7200 0 -02} - {938916000 -3600 1 -01} + {938916000 -3600 1 -02} {951613200 -7200 0 -02} - {970970400 -3600 1 -01} + {970970400 -3600 1 -02} {971571600 -7200 0 -02} {1000346400 -7200 0 -02} - {1003024800 -3600 1 -01} + {1003024800 -3600 1 -02} {1013907600 -7200 0 -02} {1033434000 -7200 0 -02} } diff --git a/library/tzdata/America/Porto_Velho b/library/tzdata/America/Porto_Velho index 42566ad..8d7c8fd 100644 --- a/library/tzdata/America/Porto_Velho +++ b/library/tzdata/America/Porto_Velho @@ -3,33 +3,33 @@ set TZData(:America/Porto_Velho) { {-9223372036854775808 -15336 0 LMT} {-1767210264 -14400 0 -04} - {-1206954000 -10800 1 -03} + {-1206954000 -10800 1 -04} {-1191358800 -14400 0 -04} - {-1175371200 -10800 1 -03} + {-1175371200 -10800 1 -04} {-1159822800 -14400 0 -04} - {-633816000 -10800 1 -03} + {-633816000 -10800 1 -04} {-622065600 -14400 0 -04} - {-602280000 -10800 1 -03} + {-602280000 -10800 1 -04} {-591829200 -14400 0 -04} - {-570744000 -10800 1 -03} + {-570744000 -10800 1 -04} {-560206800 -14400 0 -04} - {-539121600 -10800 1 -03} + {-539121600 -10800 1 -04} {-531349200 -14400 0 -04} - {-191361600 -10800 1 -03} + {-191361600 -10800 1 -04} {-184194000 -14400 0 -04} - {-155160000 -10800 1 -03} + {-155160000 -10800 1 -04} {-150066000 -14400 0 -04} - {-128894400 -10800 1 -03} + {-128894400 -10800 1 -04} {-121122000 -14400 0 -04} - {-99950400 -10800 1 -03} + {-99950400 -10800 1 -04} {-89586000 -14400 0 -04} - {-68414400 -10800 1 -03} + {-68414400 -10800 1 -04} {-57963600 -14400 0 -04} - {499752000 -10800 1 -03} + {499752000 -10800 1 -04} {511239600 -14400 0 -04} - {530596800 -10800 1 -03} + {530596800 -10800 1 -04} {540270000 -14400 0 -04} - {562132800 -10800 1 -03} + {562132800 -10800 1 -04} {571201200 -14400 0 -04} {590036400 -14400 0 -04} } diff --git a/library/tzdata/America/Punta_Arenas b/library/tzdata/America/Punta_Arenas index 75487e7..5e8202a 100644 --- a/library/tzdata/America/Punta_Arenas +++ b/library/tzdata/America/Punta_Arenas @@ -8,115 +8,115 @@ set TZData(:America/Punta_Arenas) { {-1619205434 -14400 0 -04} {-1593806400 -16966 0 SMT} {-1335986234 -18000 0 -05} - {-1335985200 -14400 1 -04} + {-1335985200 -14400 1 -05} {-1317585600 -18000 0 -05} - {-1304362800 -14400 1 -04} + {-1304362800 -14400 1 -05} {-1286049600 -18000 0 -05} - {-1272826800 -14400 1 -04} + {-1272826800 -14400 1 -05} {-1254513600 -18000 0 -05} - {-1241290800 -14400 1 -04} + {-1241290800 -14400 1 -05} {-1222977600 -18000 0 -05} - {-1209754800 -14400 1 -04} + {-1209754800 -14400 1 -05} {-1191355200 -18000 0 -05} {-1178132400 -14400 0 -04} {-870552000 -18000 0 -05} {-865278000 -14400 0 -04} {-718056000 -18000 0 -05} {-713649600 -14400 0 -04} - {-36619200 -10800 1 -03} + {-36619200 -10800 1 -04} {-23922000 -14400 0 -04} - {-3355200 -10800 1 -03} + {-3355200 -10800 1 -04} {7527600 -14400 0 -04} - {24465600 -10800 1 -03} + {24465600 -10800 1 -04} {37767600 -14400 0 -04} - {55915200 -10800 1 -03} + {55915200 -10800 1 -04} {69217200 -14400 0 -04} - {87969600 -10800 1 -03} + {87969600 -10800 1 -04} {100666800 -14400 0 -04} - {118209600 -10800 1 -03} + {118209600 -10800 1 -04} {132116400 -14400 0 -04} - {150868800 -10800 1 -03} + {150868800 -10800 1 -04} {163566000 -14400 0 -04} - {182318400 -10800 1 -03} + {182318400 -10800 1 -04} {195620400 -14400 0 -04} - {213768000 -10800 1 -03} + {213768000 -10800 1 -04} {227070000 -14400 0 -04} - {245217600 -10800 1 -03} + {245217600 -10800 1 -04} {258519600 -14400 0 -04} - {277272000 -10800 1 -03} + {277272000 -10800 1 -04} {289969200 -14400 0 -04} - {308721600 -10800 1 -03} + {308721600 -10800 1 -04} {321418800 -14400 0 -04} - {340171200 -10800 1 -03} + {340171200 -10800 1 -04} {353473200 -14400 0 -04} - {371620800 -10800 1 -03} + {371620800 -10800 1 -04} {384922800 -14400 0 -04} - {403070400 -10800 1 -03} + {403070400 -10800 1 -04} {416372400 -14400 0 -04} - {434520000 -10800 1 -03} + {434520000 -10800 1 -04} {447822000 -14400 0 -04} - {466574400 -10800 1 -03} + {466574400 -10800 1 -04} {479271600 -14400 0 -04} - {498024000 -10800 1 -03} + {498024000 -10800 1 -04} {510721200 -14400 0 -04} - {529473600 -10800 1 -03} + {529473600 -10800 1 -04} {545194800 -14400 0 -04} - {560923200 -10800 1 -03} + {560923200 -10800 1 -04} {574225200 -14400 0 -04} - {592372800 -10800 1 -03} + {592372800 -10800 1 -04} {605674800 -14400 0 -04} - {624427200 -10800 1 -03} + {624427200 -10800 1 -04} {637124400 -14400 0 -04} - {653457600 -10800 1 -03} + {653457600 -10800 1 -04} {668574000 -14400 0 -04} - {687326400 -10800 1 -03} + {687326400 -10800 1 -04} {700628400 -14400 0 -04} - {718776000 -10800 1 -03} + {718776000 -10800 1 -04} {732078000 -14400 0 -04} - {750225600 -10800 1 -03} + {750225600 -10800 1 -04} {763527600 -14400 0 -04} - {781675200 -10800 1 -03} + {781675200 -10800 1 -04} {794977200 -14400 0 -04} - {813729600 -10800 1 -03} + {813729600 -10800 1 -04} {826426800 -14400 0 -04} - {845179200 -10800 1 -03} + {845179200 -10800 1 -04} {859690800 -14400 0 -04} - {876628800 -10800 1 -03} + {876628800 -10800 1 -04} {889930800 -14400 0 -04} - {906868800 -10800 1 -03} + {906868800 -10800 1 -04} {923194800 -14400 0 -04} - {939528000 -10800 1 -03} + {939528000 -10800 1 -04} {952830000 -14400 0 -04} - {971582400 -10800 1 -03} + {971582400 -10800 1 -04} {984279600 -14400 0 -04} - {1003032000 -10800 1 -03} + {1003032000 -10800 1 -04} {1015729200 -14400 0 -04} - {1034481600 -10800 1 -03} + {1034481600 -10800 1 -04} {1047178800 -14400 0 -04} - {1065931200 -10800 1 -03} + {1065931200 -10800 1 -04} {1079233200 -14400 0 -04} - {1097380800 -10800 1 -03} + {1097380800 -10800 1 -04} {1110682800 -14400 0 -04} - {1128830400 -10800 1 -03} + {1128830400 -10800 1 -04} {1142132400 -14400 0 -04} - {1160884800 -10800 1 -03} + {1160884800 -10800 1 -04} {1173582000 -14400 0 -04} - {1192334400 -10800 1 -03} + {1192334400 -10800 1 -04} {1206846000 -14400 0 -04} - {1223784000 -10800 1 -03} + {1223784000 -10800 1 -04} {1237086000 -14400 0 -04} - {1255233600 -10800 1 -03} + {1255233600 -10800 1 -04} {1270350000 -14400 0 -04} - {1286683200 -10800 1 -03} + {1286683200 -10800 1 -04} {1304823600 -14400 0 -04} - {1313899200 -10800 1 -03} + {1313899200 -10800 1 -04} {1335668400 -14400 0 -04} - {1346558400 -10800 1 -03} + {1346558400 -10800 1 -04} {1367118000 -14400 0 -04} - {1378612800 -10800 1 -03} + {1378612800 -10800 1 -04} {1398567600 -14400 0 -04} - {1410062400 -10800 1 -03} + {1410062400 -10800 1 -04} {1463281200 -14400 0 -04} - {1471147200 -10800 1 -03} + {1471147200 -10800 1 -04} {1480820400 -10800 0 -03} } diff --git a/library/tzdata/America/Recife b/library/tzdata/America/Recife index 8eae571..db0a445 100644 --- a/library/tzdata/America/Recife +++ b/library/tzdata/America/Recife @@ -3,46 +3,46 @@ set TZData(:America/Recife) { {-9223372036854775808 -8376 0 LMT} {-1767217224 -10800 0 -03} - {-1206957600 -7200 1 -02} + {-1206957600 -7200 1 -03} {-1191362400 -10800 0 -03} - {-1175374800 -7200 1 -02} + {-1175374800 -7200 1 -03} {-1159826400 -10800 0 -03} - {-633819600 -7200 1 -02} + {-633819600 -7200 1 -03} {-622069200 -10800 0 -03} - {-602283600 -7200 1 -02} + {-602283600 -7200 1 -03} {-591832800 -10800 0 -03} - {-570747600 -7200 1 -02} + {-570747600 -7200 1 -03} {-560210400 -10800 0 -03} - {-539125200 -7200 1 -02} + {-539125200 -7200 1 -03} {-531352800 -10800 0 -03} - {-191365200 -7200 1 -02} + {-191365200 -7200 1 -03} {-184197600 -10800 0 -03} - {-155163600 -7200 1 -02} + {-155163600 -7200 1 -03} {-150069600 -10800 0 -03} - {-128898000 -7200 1 -02} + {-128898000 -7200 1 -03} {-121125600 -10800 0 -03} - {-99954000 -7200 1 -02} + {-99954000 -7200 1 -03} {-89589600 -10800 0 -03} - {-68418000 -7200 1 -02} + {-68418000 -7200 1 -03} {-57967200 -10800 0 -03} - {499748400 -7200 1 -02} + {499748400 -7200 1 -03} {511236000 -10800 0 -03} - {530593200 -7200 1 -02} + {530593200 -7200 1 -03} {540266400 -10800 0 -03} - {562129200 -7200 1 -02} + {562129200 -7200 1 -03} {571197600 -10800 0 -03} - {592974000 -7200 1 -02} + {592974000 -7200 1 -03} {602042400 -10800 0 -03} - {624423600 -7200 1 -02} + {624423600 -7200 1 -03} {634701600 -10800 0 -03} {653536800 -10800 0 -03} {938660400 -10800 0 -03} - {938919600 -7200 1 -02} + {938919600 -7200 1 -03} {951616800 -10800 0 -03} - {970974000 -7200 1 -02} + {970974000 -7200 1 -03} {971575200 -10800 0 -03} {1000350000 -10800 0 -03} - {1003028400 -7200 1 -02} + {1003028400 -7200 1 -03} {1013911200 -10800 0 -03} {1033437600 -10800 0 -03} } diff --git a/library/tzdata/America/Rio_Branco b/library/tzdata/America/Rio_Branco index e3c2f31..088800b 100644 --- a/library/tzdata/America/Rio_Branco +++ b/library/tzdata/America/Rio_Branco @@ -3,33 +3,33 @@ set TZData(:America/Rio_Branco) { {-9223372036854775808 -16272 0 LMT} {-1767209328 -18000 0 -05} - {-1206950400 -14400 1 -04} + {-1206950400 -14400 1 -05} {-1191355200 -18000 0 -05} - {-1175367600 -14400 1 -04} + {-1175367600 -14400 1 -05} {-1159819200 -18000 0 -05} - {-633812400 -14400 1 -04} + {-633812400 -14400 1 -05} {-622062000 -18000 0 -05} - {-602276400 -14400 1 -04} + {-602276400 -14400 1 -05} {-591825600 -18000 0 -05} - {-570740400 -14400 1 -04} + {-570740400 -14400 1 -05} {-560203200 -18000 0 -05} - {-539118000 -14400 1 -04} + {-539118000 -14400 1 -05} {-531345600 -18000 0 -05} - {-191358000 -14400 1 -04} + {-191358000 -14400 1 -05} {-184190400 -18000 0 -05} - {-155156400 -14400 1 -04} + {-155156400 -14400 1 -05} {-150062400 -18000 0 -05} - {-128890800 -14400 1 -04} + {-128890800 -14400 1 -05} {-121118400 -18000 0 -05} - {-99946800 -14400 1 -04} + {-99946800 -14400 1 -05} {-89582400 -18000 0 -05} - {-68410800 -14400 1 -04} + {-68410800 -14400 1 -05} {-57960000 -18000 0 -05} - {499755600 -14400 1 -04} + {499755600 -14400 1 -05} {511243200 -18000 0 -05} - {530600400 -14400 1 -04} + {530600400 -14400 1 -05} {540273600 -18000 0 -05} - {562136400 -14400 1 -04} + {562136400 -14400 1 -05} {571204800 -18000 0 -05} {590040000 -18000 0 -05} {1214283600 -14400 0 -04} diff --git a/library/tzdata/America/Santarem b/library/tzdata/America/Santarem index f81e9b6..5fa3551 100644 --- a/library/tzdata/America/Santarem +++ b/library/tzdata/America/Santarem @@ -3,33 +3,33 @@ set TZData(:America/Santarem) { {-9223372036854775808 -13128 0 LMT} {-1767212472 -14400 0 -04} - {-1206954000 -10800 1 -03} + {-1206954000 -10800 1 -04} {-1191358800 -14400 0 -04} - {-1175371200 -10800 1 -03} + {-1175371200 -10800 1 -04} {-1159822800 -14400 0 -04} - {-633816000 -10800 1 -03} + {-633816000 -10800 1 -04} {-622065600 -14400 0 -04} - {-602280000 -10800 1 -03} + {-602280000 -10800 1 -04} {-591829200 -14400 0 -04} - {-570744000 -10800 1 -03} + {-570744000 -10800 1 -04} {-560206800 -14400 0 -04} - {-539121600 -10800 1 -03} + {-539121600 -10800 1 -04} {-531349200 -14400 0 -04} - {-191361600 -10800 1 -03} + {-191361600 -10800 1 -04} {-184194000 -14400 0 -04} - {-155160000 -10800 1 -03} + {-155160000 -10800 1 -04} {-150066000 -14400 0 -04} - {-128894400 -10800 1 -03} + {-128894400 -10800 1 -04} {-121122000 -14400 0 -04} - {-99950400 -10800 1 -03} + {-99950400 -10800 1 -04} {-89586000 -14400 0 -04} - {-68414400 -10800 1 -03} + {-68414400 -10800 1 -04} {-57963600 -14400 0 -04} - {499752000 -10800 1 -03} + {499752000 -10800 1 -04} {511239600 -14400 0 -04} - {530596800 -10800 1 -03} + {530596800 -10800 1 -04} {540270000 -14400 0 -04} - {562132800 -10800 1 -03} + {562132800 -10800 1 -04} {571201200 -14400 0 -04} {590036400 -14400 0 -04} {1214280000 -10800 0 -03} diff --git a/library/tzdata/America/Santiago b/library/tzdata/America/Santiago index 95e920d..67d5b5c 100644 --- a/library/tzdata/America/Santiago +++ b/library/tzdata/America/Santiago @@ -8,15 +8,15 @@ set TZData(:America/Santiago) { {-1619205434 -14400 0 -04} {-1593806400 -16966 0 SMT} {-1335986234 -18000 0 -05} - {-1335985200 -14400 1 -04} + {-1335985200 -14400 1 -05} {-1317585600 -18000 0 -05} - {-1304362800 -14400 1 -04} + {-1304362800 -14400 1 -05} {-1286049600 -18000 0 -05} - {-1272826800 -14400 1 -04} + {-1272826800 -14400 1 -05} {-1254513600 -18000 0 -05} - {-1241290800 -14400 1 -04} + {-1241290800 -14400 1 -05} {-1222977600 -18000 0 -05} - {-1209754800 -14400 1 -04} + {-1209754800 -14400 1 -05} {-1191355200 -18000 0 -05} {-1178132400 -14400 0 -04} {-870552000 -18000 0 -05} @@ -25,265 +25,265 @@ set TZData(:America/Santiago) { {-736376400 -14400 0 -04} {-718056000 -18000 0 -05} {-713649600 -14400 0 -04} - {-36619200 -10800 1 -03} + {-36619200 -10800 1 -04} {-23922000 -14400 0 -04} - {-3355200 -10800 1 -03} + {-3355200 -10800 1 -04} {7527600 -14400 0 -04} - {24465600 -10800 1 -03} + {24465600 -10800 1 -04} {37767600 -14400 0 -04} - {55915200 -10800 1 -03} + {55915200 -10800 1 -04} {69217200 -14400 0 -04} - {87969600 -10800 1 -03} + {87969600 -10800 1 -04} {100666800 -14400 0 -04} - {118209600 -10800 1 -03} + {118209600 -10800 1 -04} {132116400 -14400 0 -04} - {150868800 -10800 1 -03} + {150868800 -10800 1 -04} {163566000 -14400 0 -04} - {182318400 -10800 1 -03} + {182318400 -10800 1 -04} {195620400 -14400 0 -04} - {213768000 -10800 1 -03} + {213768000 -10800 1 -04} {227070000 -14400 0 -04} - {245217600 -10800 1 -03} + {245217600 -10800 1 -04} {258519600 -14400 0 -04} - {277272000 -10800 1 -03} + {277272000 -10800 1 -04} {289969200 -14400 0 -04} - {308721600 -10800 1 -03} + {308721600 -10800 1 -04} {321418800 -14400 0 -04} - {340171200 -10800 1 -03} + {340171200 -10800 1 -04} {353473200 -14400 0 -04} - {371620800 -10800 1 -03} + {371620800 -10800 1 -04} {384922800 -14400 0 -04} - {403070400 -10800 1 -03} + {403070400 -10800 1 -04} {416372400 -14400 0 -04} - {434520000 -10800 1 -03} + {434520000 -10800 1 -04} {447822000 -14400 0 -04} - {466574400 -10800 1 -03} + {466574400 -10800 1 -04} {479271600 -14400 0 -04} - {498024000 -10800 1 -03} + {498024000 -10800 1 -04} {510721200 -14400 0 -04} - {529473600 -10800 1 -03} + {529473600 -10800 1 -04} {545194800 -14400 0 -04} - {560923200 -10800 1 -03} + {560923200 -10800 1 -04} {574225200 -14400 0 -04} - {592372800 -10800 1 -03} + {592372800 -10800 1 -04} {605674800 -14400 0 -04} - {624427200 -10800 1 -03} + {624427200 -10800 1 -04} {637124400 -14400 0 -04} - {653457600 -10800 1 -03} + {653457600 -10800 1 -04} {668574000 -14400 0 -04} - {687326400 -10800 1 -03} + {687326400 -10800 1 -04} {700628400 -14400 0 -04} - {718776000 -10800 1 -03} + {718776000 -10800 1 -04} {732078000 -14400 0 -04} - {750225600 -10800 1 -03} + {750225600 -10800 1 -04} {763527600 -14400 0 -04} - {781675200 -10800 1 -03} + {781675200 -10800 1 -04} {794977200 -14400 0 -04} - {813729600 -10800 1 -03} + {813729600 -10800 1 -04} {826426800 -14400 0 -04} - {845179200 -10800 1 -03} + {845179200 -10800 1 -04} {859690800 -14400 0 -04} - {876628800 -10800 1 -03} + {876628800 -10800 1 -04} {889930800 -14400 0 -04} - {906868800 -10800 1 -03} + {906868800 -10800 1 -04} {923194800 -14400 0 -04} - {939528000 -10800 1 -03} + {939528000 -10800 1 -04} {952830000 -14400 0 -04} - {971582400 -10800 1 -03} + {971582400 -10800 1 -04} {984279600 -14400 0 -04} - {1003032000 -10800 1 -03} + {1003032000 -10800 1 -04} {1015729200 -14400 0 -04} - {1034481600 -10800 1 -03} + {1034481600 -10800 1 -04} {1047178800 -14400 0 -04} - {1065931200 -10800 1 -03} + {1065931200 -10800 1 -04} {1079233200 -14400 0 -04} - {1097380800 -10800 1 -03} + {1097380800 -10800 1 -04} {1110682800 -14400 0 -04} - {1128830400 -10800 1 -03} + {1128830400 -10800 1 -04} {1142132400 -14400 0 -04} - {1160884800 -10800 1 -03} + {1160884800 -10800 1 -04} {1173582000 -14400 0 -04} - {1192334400 -10800 1 -03} + {1192334400 -10800 1 -04} {1206846000 -14400 0 -04} - {1223784000 -10800 1 -03} + {1223784000 -10800 1 -04} {1237086000 -14400 0 -04} - {1255233600 -10800 1 -03} + {1255233600 -10800 1 -04} {1270350000 -14400 0 -04} - {1286683200 -10800 1 -03} + {1286683200 -10800 1 -04} {1304823600 -14400 0 -04} - {1313899200 -10800 1 -03} + {1313899200 -10800 1 -04} {1335668400 -14400 0 -04} - {1346558400 -10800 1 -03} + {1346558400 -10800 1 -04} {1367118000 -14400 0 -04} - {1378612800 -10800 1 -03} + {1378612800 -10800 1 -04} {1398567600 -14400 0 -04} - {1410062400 -10800 1 -03} + {1410062400 -10800 1 -04} {1463281200 -14400 0 -04} - {1471147200 -10800 1 -03} + {1471147200 -10800 1 -04} {1494730800 -14400 0 -04} - {1502596800 -10800 1 -03} + {1502596800 -10800 1 -04} {1526180400 -14400 0 -04} - {1534046400 -10800 1 -03} + {1534046400 -10800 1 -04} {1557630000 -14400 0 -04} - {1565496000 -10800 1 -03} + {1565496000 -10800 1 -04} {1589079600 -14400 0 -04} - {1596945600 -10800 1 -03} + {1596945600 -10800 1 -04} {1620529200 -14400 0 -04} - {1629000000 -10800 1 -03} + {1629000000 -10800 1 -04} {1652583600 -14400 0 -04} - {1660449600 -10800 1 -03} + {1660449600 -10800 1 -04} {1684033200 -14400 0 -04} - {1691899200 -10800 1 -03} + {1691899200 -10800 1 -04} {1715482800 -14400 0 -04} - {1723348800 -10800 1 -03} + {1723348800 -10800 1 -04} {1746932400 -14400 0 -04} - {1754798400 -10800 1 -03} + {1754798400 -10800 1 -04} {1778382000 -14400 0 -04} - {1786248000 -10800 1 -03} + {1786248000 -10800 1 -04} {1809831600 -14400 0 -04} - {1818302400 -10800 1 -03} + {1818302400 -10800 1 -04} {1841886000 -14400 0 -04} - {1849752000 -10800 1 -03} + {1849752000 -10800 1 -04} {1873335600 -14400 0 -04} - {1881201600 -10800 1 -03} + {1881201600 -10800 1 -04} {1904785200 -14400 0 -04} - {1912651200 -10800 1 -03} + {1912651200 -10800 1 -04} {1936234800 -14400 0 -04} - {1944100800 -10800 1 -03} + {1944100800 -10800 1 -04} {1967684400 -14400 0 -04} - {1976155200 -10800 1 -03} + {1976155200 -10800 1 -04} {1999738800 -14400 0 -04} - {2007604800 -10800 1 -03} + {2007604800 -10800 1 -04} {2031188400 -14400 0 -04} - {2039054400 -10800 1 -03} + {2039054400 -10800 1 -04} {2062638000 -14400 0 -04} - {2070504000 -10800 1 -03} + {2070504000 -10800 1 -04} {2094087600 -14400 0 -04} - {2101953600 -10800 1 -03} + {2101953600 -10800 1 -04} {2125537200 -14400 0 -04} - {2133403200 -10800 1 -03} + {2133403200 -10800 1 -04} {2156986800 -14400 0 -04} - {2165457600 -10800 1 -03} + {2165457600 -10800 1 -04} {2189041200 -14400 0 -04} - {2196907200 -10800 1 -03} + {2196907200 -10800 1 -04} {2220490800 -14400 0 -04} - {2228356800 -10800 1 -03} + {2228356800 -10800 1 -04} {2251940400 -14400 0 -04} - {2259806400 -10800 1 -03} + {2259806400 -10800 1 -04} {2283390000 -14400 0 -04} - {2291256000 -10800 1 -03} + {2291256000 -10800 1 -04} {2314839600 -14400 0 -04} - {2322705600 -10800 1 -03} + {2322705600 -10800 1 -04} {2346894000 -14400 0 -04} - {2354760000 -10800 1 -03} + {2354760000 -10800 1 -04} {2378343600 -14400 0 -04} - {2386209600 -10800 1 -03} + {2386209600 -10800 1 -04} {2409793200 -14400 0 -04} - {2417659200 -10800 1 -03} + {2417659200 -10800 1 -04} {2441242800 -14400 0 -04} - {2449108800 -10800 1 -03} + {2449108800 -10800 1 -04} {2472692400 -14400 0 -04} - {2480558400 -10800 1 -03} + {2480558400 -10800 1 -04} {2504142000 -14400 0 -04} - {2512612800 -10800 1 -03} + {2512612800 -10800 1 -04} {2536196400 -14400 0 -04} - {2544062400 -10800 1 -03} + {2544062400 -10800 1 -04} {2567646000 -14400 0 -04} - {2575512000 -10800 1 -03} + {2575512000 -10800 1 -04} {2599095600 -14400 0 -04} - {2606961600 -10800 1 -03} + {2606961600 -10800 1 -04} {2630545200 -14400 0 -04} - {2638411200 -10800 1 -03} + {2638411200 -10800 1 -04} {2661994800 -14400 0 -04} - {2669860800 -10800 1 -03} + {2669860800 -10800 1 -04} {2693444400 -14400 0 -04} - {2701915200 -10800 1 -03} + {2701915200 -10800 1 -04} {2725498800 -14400 0 -04} - {2733364800 -10800 1 -03} + {2733364800 -10800 1 -04} {2756948400 -14400 0 -04} - {2764814400 -10800 1 -03} + {2764814400 -10800 1 -04} {2788398000 -14400 0 -04} - {2796264000 -10800 1 -03} + {2796264000 -10800 1 -04} {2819847600 -14400 0 -04} - {2827713600 -10800 1 -03} + {2827713600 -10800 1 -04} {2851297200 -14400 0 -04} - {2859768000 -10800 1 -03} + {2859768000 -10800 1 -04} {2883351600 -14400 0 -04} - {2891217600 -10800 1 -03} + {2891217600 -10800 1 -04} {2914801200 -14400 0 -04} - {2922667200 -10800 1 -03} + {2922667200 -10800 1 -04} {2946250800 -14400 0 -04} - {2954116800 -10800 1 -03} + {2954116800 -10800 1 -04} {2977700400 -14400 0 -04} - {2985566400 -10800 1 -03} + {2985566400 -10800 1 -04} {3009150000 -14400 0 -04} - {3017016000 -10800 1 -03} + {3017016000 -10800 1 -04} {3040599600 -14400 0 -04} - {3049070400 -10800 1 -03} + {3049070400 -10800 1 -04} {3072654000 -14400 0 -04} - {3080520000 -10800 1 -03} + {3080520000 -10800 1 -04} {3104103600 -14400 0 -04} - {3111969600 -10800 1 -03} + {3111969600 -10800 1 -04} {3135553200 -14400 0 -04} - {3143419200 -10800 1 -03} + {3143419200 -10800 1 -04} {3167002800 -14400 0 -04} - {3174868800 -10800 1 -03} + {3174868800 -10800 1 -04} {3198452400 -14400 0 -04} - {3206318400 -10800 1 -03} + {3206318400 -10800 1 -04} {3230506800 -14400 0 -04} - {3238372800 -10800 1 -03} + {3238372800 -10800 1 -04} {3261956400 -14400 0 -04} - {3269822400 -10800 1 -03} + {3269822400 -10800 1 -04} {3293406000 -14400 0 -04} - {3301272000 -10800 1 -03} + {3301272000 -10800 1 -04} {3324855600 -14400 0 -04} - {3332721600 -10800 1 -03} + {3332721600 -10800 1 -04} {3356305200 -14400 0 -04} - {3364171200 -10800 1 -03} + {3364171200 -10800 1 -04} {3387754800 -14400 0 -04} - {3396225600 -10800 1 -03} + {3396225600 -10800 1 -04} {3419809200 -14400 0 -04} - {3427675200 -10800 1 -03} + {3427675200 -10800 1 -04} {3451258800 -14400 0 -04} - {3459124800 -10800 1 -03} + {3459124800 -10800 1 -04} {3482708400 -14400 0 -04} - {3490574400 -10800 1 -03} + {3490574400 -10800 1 -04} {3514158000 -14400 0 -04} - {3522024000 -10800 1 -03} + {3522024000 -10800 1 -04} {3545607600 -14400 0 -04} - {3553473600 -10800 1 -03} + {3553473600 -10800 1 -04} {3577057200 -14400 0 -04} - {3585528000 -10800 1 -03} + {3585528000 -10800 1 -04} {3609111600 -14400 0 -04} - {3616977600 -10800 1 -03} + {3616977600 -10800 1 -04} {3640561200 -14400 0 -04} - {3648427200 -10800 1 -03} + {3648427200 -10800 1 -04} {3672010800 -14400 0 -04} - {3679876800 -10800 1 -03} + {3679876800 -10800 1 -04} {3703460400 -14400 0 -04} - {3711326400 -10800 1 -03} + {3711326400 -10800 1 -04} {3734910000 -14400 0 -04} - {3743380800 -10800 1 -03} + {3743380800 -10800 1 -04} {3766964400 -14400 0 -04} - {3774830400 -10800 1 -03} + {3774830400 -10800 1 -04} {3798414000 -14400 0 -04} - {3806280000 -10800 1 -03} + {3806280000 -10800 1 -04} {3829863600 -14400 0 -04} - {3837729600 -10800 1 -03} + {3837729600 -10800 1 -04} {3861313200 -14400 0 -04} - {3869179200 -10800 1 -03} + {3869179200 -10800 1 -04} {3892762800 -14400 0 -04} - {3900628800 -10800 1 -03} + {3900628800 -10800 1 -04} {3924212400 -14400 0 -04} - {3932683200 -10800 1 -03} + {3932683200 -10800 1 -04} {3956266800 -14400 0 -04} - {3964132800 -10800 1 -03} + {3964132800 -10800 1 -04} {3987716400 -14400 0 -04} - {3995582400 -10800 1 -03} + {3995582400 -10800 1 -04} {4019166000 -14400 0 -04} - {4027032000 -10800 1 -03} + {4027032000 -10800 1 -04} {4050615600 -14400 0 -04} - {4058481600 -10800 1 -03} + {4058481600 -10800 1 -04} {4082065200 -14400 0 -04} - {4089931200 -10800 1 -03} + {4089931200 -10800 1 -04} } diff --git a/library/tzdata/America/Sao_Paulo b/library/tzdata/America/Sao_Paulo index a61c638..235f57a 100644 --- a/library/tzdata/America/Sao_Paulo +++ b/library/tzdata/America/Sao_Paulo @@ -3,256 +3,256 @@ set TZData(:America/Sao_Paulo) { {-9223372036854775808 -11188 0 LMT} {-1767214412 -10800 0 -03} - {-1206957600 -7200 1 -02} + {-1206957600 -7200 1 -03} {-1191362400 -10800 0 -03} - {-1175374800 -7200 1 -02} + {-1175374800 -7200 1 -03} {-1159826400 -10800 0 -03} - {-633819600 -7200 1 -02} + {-633819600 -7200 1 -03} {-622069200 -10800 0 -03} - {-602283600 -7200 1 -02} + {-602283600 -7200 1 -03} {-591832800 -10800 0 -03} - {-570747600 -7200 1 -02} + {-570747600 -7200 1 -03} {-560210400 -10800 0 -03} - {-539125200 -7200 1 -02} + {-539125200 -7200 1 -03} {-531352800 -10800 0 -03} {-195429600 -7200 1 -02} {-189381600 -7200 0 -03} {-184197600 -10800 0 -03} - {-155163600 -7200 1 -02} + {-155163600 -7200 1 -03} {-150069600 -10800 0 -03} - {-128898000 -7200 1 -02} + {-128898000 -7200 1 -03} {-121125600 -10800 0 -03} - {-99954000 -7200 1 -02} + {-99954000 -7200 1 -03} {-89589600 -10800 0 -03} - {-68418000 -7200 1 -02} + {-68418000 -7200 1 -03} {-57967200 -10800 0 -03} - {499748400 -7200 1 -02} + {499748400 -7200 1 -03} {511236000 -10800 0 -03} - {530593200 -7200 1 -02} + {530593200 -7200 1 -03} {540266400 -10800 0 -03} - {562129200 -7200 1 -02} + {562129200 -7200 1 -03} {571197600 -10800 0 -03} - {592974000 -7200 1 -02} + {592974000 -7200 1 -03} {602042400 -10800 0 -03} - {624423600 -7200 1 -02} + {624423600 -7200 1 -03} {634701600 -10800 0 -03} - {656478000 -7200 1 -02} + {656478000 -7200 1 -03} {666756000 -10800 0 -03} - {687927600 -7200 1 -02} + {687927600 -7200 1 -03} {697600800 -10800 0 -03} - {719982000 -7200 1 -02} + {719982000 -7200 1 -03} {728445600 -10800 0 -03} - {750826800 -7200 1 -02} + {750826800 -7200 1 -03} {761709600 -10800 0 -03} - {782276400 -7200 1 -02} + {782276400 -7200 1 -03} {793159200 -10800 0 -03} - {813726000 -7200 1 -02} + {813726000 -7200 1 -03} {824004000 -10800 0 -03} - {844570800 -7200 1 -02} + {844570800 -7200 1 -03} {856058400 -10800 0 -03} - {876106800 -7200 1 -02} + {876106800 -7200 1 -03} {888717600 -10800 0 -03} - {908074800 -7200 1 -02} + {908074800 -7200 1 -03} {919562400 -10800 0 -03} - {938919600 -7200 1 -02} + {938919600 -7200 1 -03} {951616800 -10800 0 -03} - {970974000 -7200 1 -02} + {970974000 -7200 1 -03} {982461600 -10800 0 -03} - {1003028400 -7200 1 -02} + {1003028400 -7200 1 -03} {1013911200 -10800 0 -03} - {1036292400 -7200 1 -02} + {1036292400 -7200 1 -03} {1045360800 -10800 0 -03} - {1066532400 -7200 1 -02} + {1066532400 -7200 1 -03} {1076810400 -10800 0 -03} - {1099364400 -7200 1 -02} + {1099364400 -7200 1 -03} {1108864800 -10800 0 -03} - {1129431600 -7200 1 -02} + {1129431600 -7200 1 -03} {1140314400 -10800 0 -03} - {1162695600 -7200 1 -02} + {1162695600 -7200 1 -03} {1172368800 -10800 0 -03} - {1192330800 -7200 1 -02} + {1192330800 -7200 1 -03} {1203213600 -10800 0 -03} - {1224385200 -7200 1 -02} + {1224385200 -7200 1 -03} {1234663200 -10800 0 -03} - {1255834800 -7200 1 -02} + {1255834800 -7200 1 -03} {1266717600 -10800 0 -03} - {1287284400 -7200 1 -02} + {1287284400 -7200 1 -03} {1298167200 -10800 0 -03} - {1318734000 -7200 1 -02} + {1318734000 -7200 1 -03} {1330221600 -10800 0 -03} - {1350788400 -7200 1 -02} + {1350788400 -7200 1 -03} {1361066400 -10800 0 -03} - {1382238000 -7200 1 -02} + {1382238000 -7200 1 -03} {1392516000 -10800 0 -03} - {1413687600 -7200 1 -02} + {1413687600 -7200 1 -03} {1424570400 -10800 0 -03} - {1445137200 -7200 1 -02} + {1445137200 -7200 1 -03} {1456020000 -10800 0 -03} - {1476586800 -7200 1 -02} + {1476586800 -7200 1 -03} {1487469600 -10800 0 -03} - {1508036400 -7200 1 -02} + {1508036400 -7200 1 -03} {1518919200 -10800 0 -03} - {1540090800 -7200 1 -02} + {1541300400 -7200 1 -03} {1550368800 -10800 0 -03} - {1571540400 -7200 1 -02} + {1572750000 -7200 1 -03} {1581818400 -10800 0 -03} - {1602990000 -7200 1 -02} + {1604199600 -7200 1 -03} {1613872800 -10800 0 -03} - {1634439600 -7200 1 -02} + {1636254000 -7200 1 -03} {1645322400 -10800 0 -03} - {1665889200 -7200 1 -02} + {1667703600 -7200 1 -03} {1677376800 -10800 0 -03} - {1697338800 -7200 1 -02} + {1699153200 -7200 1 -03} {1708221600 -10800 0 -03} - {1729393200 -7200 1 -02} + {1730602800 -7200 1 -03} {1739671200 -10800 0 -03} - {1760842800 -7200 1 -02} + {1762052400 -7200 1 -03} {1771725600 -10800 0 -03} - {1792292400 -7200 1 -02} + {1793502000 -7200 1 -03} {1803175200 -10800 0 -03} - {1823742000 -7200 1 -02} + {1825556400 -7200 1 -03} {1834624800 -10800 0 -03} - {1855191600 -7200 1 -02} + {1857006000 -7200 1 -03} {1866074400 -10800 0 -03} - {1887246000 -7200 1 -02} + {1888455600 -7200 1 -03} {1897524000 -10800 0 -03} - {1918695600 -7200 1 -02} + {1919905200 -7200 1 -03} {1928973600 -10800 0 -03} - {1950145200 -7200 1 -02} + {1951354800 -7200 1 -03} {1960423200 -10800 0 -03} - {1981594800 -7200 1 -02} + {1983409200 -7200 1 -03} {1992477600 -10800 0 -03} - {2013044400 -7200 1 -02} + {2014858800 -7200 1 -03} {2024532000 -10800 0 -03} - {2044494000 -7200 1 -02} + {2046308400 -7200 1 -03} {2055376800 -10800 0 -03} - {2076548400 -7200 1 -02} + {2077758000 -7200 1 -03} {2086826400 -10800 0 -03} - {2107998000 -7200 1 -02} + {2109207600 -7200 1 -03} {2118880800 -10800 0 -03} - {2139447600 -7200 1 -02} + {2140657200 -7200 1 -03} {2150330400 -10800 0 -03} - {2170897200 -7200 1 -02} + {2172711600 -7200 1 -03} {2181780000 -10800 0 -03} - {2202346800 -7200 1 -02} + {2204161200 -7200 1 -03} {2213229600 -10800 0 -03} - {2234401200 -7200 1 -02} + {2235610800 -7200 1 -03} {2244679200 -10800 0 -03} - {2265850800 -7200 1 -02} + {2267060400 -7200 1 -03} {2276128800 -10800 0 -03} - {2297300400 -7200 1 -02} + {2298510000 -7200 1 -03} {2307578400 -10800 0 -03} - {2328750000 -7200 1 -02} + {2329959600 -7200 1 -03} {2339632800 -10800 0 -03} - {2360199600 -7200 1 -02} + {2362014000 -7200 1 -03} {2371082400 -10800 0 -03} - {2391649200 -7200 1 -02} + {2393463600 -7200 1 -03} {2402532000 -10800 0 -03} - {2423703600 -7200 1 -02} + {2424913200 -7200 1 -03} {2433981600 -10800 0 -03} - {2455153200 -7200 1 -02} + {2456362800 -7200 1 -03} {2465431200 -10800 0 -03} - {2486602800 -7200 1 -02} + {2487812400 -7200 1 -03} {2497485600 -10800 0 -03} - {2518052400 -7200 1 -02} + {2519866800 -7200 1 -03} {2528935200 -10800 0 -03} - {2549502000 -7200 1 -02} + {2551316400 -7200 1 -03} {2560384800 -10800 0 -03} - {2580951600 -7200 1 -02} + {2582766000 -7200 1 -03} {2591834400 -10800 0 -03} - {2613006000 -7200 1 -02} + {2614215600 -7200 1 -03} {2623284000 -10800 0 -03} - {2644455600 -7200 1 -02} + {2645665200 -7200 1 -03} {2654733600 -10800 0 -03} - {2675905200 -7200 1 -02} + {2677114800 -7200 1 -03} {2686788000 -10800 0 -03} - {2707354800 -7200 1 -02} + {2709169200 -7200 1 -03} {2718237600 -10800 0 -03} - {2738804400 -7200 1 -02} + {2740618800 -7200 1 -03} {2749687200 -10800 0 -03} - {2770858800 -7200 1 -02} + {2772068400 -7200 1 -03} {2781136800 -10800 0 -03} - {2802308400 -7200 1 -02} + {2803518000 -7200 1 -03} {2812586400 -10800 0 -03} - {2833758000 -7200 1 -02} + {2834967600 -7200 1 -03} {2844036000 -10800 0 -03} - {2865207600 -7200 1 -02} + {2867022000 -7200 1 -03} {2876090400 -10800 0 -03} - {2896657200 -7200 1 -02} + {2898471600 -7200 1 -03} {2907540000 -10800 0 -03} - {2928106800 -7200 1 -02} + {2929921200 -7200 1 -03} {2938989600 -10800 0 -03} - {2960161200 -7200 1 -02} + {2961370800 -7200 1 -03} {2970439200 -10800 0 -03} - {2991610800 -7200 1 -02} + {2992820400 -7200 1 -03} {3001888800 -10800 0 -03} - {3023060400 -7200 1 -02} + {3024270000 -7200 1 -03} {3033943200 -10800 0 -03} - {3054510000 -7200 1 -02} + {3056324400 -7200 1 -03} {3065392800 -10800 0 -03} - {3085959600 -7200 1 -02} + {3087774000 -7200 1 -03} {3096842400 -10800 0 -03} - {3118014000 -7200 1 -02} + {3119223600 -7200 1 -03} {3128292000 -10800 0 -03} - {3149463600 -7200 1 -02} + {3150673200 -7200 1 -03} {3159741600 -10800 0 -03} - {3180913200 -7200 1 -02} + {3182122800 -7200 1 -03} {3191191200 -10800 0 -03} - {3212362800 -7200 1 -02} + {3213572400 -7200 1 -03} {3223245600 -10800 0 -03} - {3243812400 -7200 1 -02} + {3245626800 -7200 1 -03} {3254695200 -10800 0 -03} - {3275262000 -7200 1 -02} + {3277076400 -7200 1 -03} {3286144800 -10800 0 -03} - {3307316400 -7200 1 -02} + {3308526000 -7200 1 -03} {3317594400 -10800 0 -03} - {3338766000 -7200 1 -02} + {3339975600 -7200 1 -03} {3349044000 -10800 0 -03} - {3370215600 -7200 1 -02} + {3371425200 -7200 1 -03} {3381098400 -10800 0 -03} - {3401665200 -7200 1 -02} + {3403479600 -7200 1 -03} {3412548000 -10800 0 -03} - {3433114800 -7200 1 -02} + {3434929200 -7200 1 -03} {3443997600 -10800 0 -03} - {3464564400 -7200 1 -02} + {3466378800 -7200 1 -03} {3475447200 -10800 0 -03} - {3496618800 -7200 1 -02} + {3497828400 -7200 1 -03} {3506896800 -10800 0 -03} - {3528068400 -7200 1 -02} + {3529278000 -7200 1 -03} {3538346400 -10800 0 -03} - {3559518000 -7200 1 -02} + {3560727600 -7200 1 -03} {3570400800 -10800 0 -03} - {3590967600 -7200 1 -02} + {3592782000 -7200 1 -03} {3601850400 -10800 0 -03} - {3622417200 -7200 1 -02} + {3624231600 -7200 1 -03} {3633300000 -10800 0 -03} - {3654471600 -7200 1 -02} + {3655681200 -7200 1 -03} {3664749600 -10800 0 -03} - {3685921200 -7200 1 -02} + {3687130800 -7200 1 -03} {3696199200 -10800 0 -03} - {3717370800 -7200 1 -02} + {3718580400 -7200 1 -03} {3727648800 -10800 0 -03} - {3748820400 -7200 1 -02} + {3750634800 -7200 1 -03} {3759703200 -10800 0 -03} - {3780270000 -7200 1 -02} + {3782084400 -7200 1 -03} {3791152800 -10800 0 -03} - {3811719600 -7200 1 -02} + {3813534000 -7200 1 -03} {3822602400 -10800 0 -03} - {3843774000 -7200 1 -02} + {3844983600 -7200 1 -03} {3854052000 -10800 0 -03} - {3875223600 -7200 1 -02} + {3876433200 -7200 1 -03} {3885501600 -10800 0 -03} - {3906673200 -7200 1 -02} + {3907882800 -7200 1 -03} {3917556000 -10800 0 -03} - {3938122800 -7200 1 -02} + {3939937200 -7200 1 -03} {3949005600 -10800 0 -03} - {3969572400 -7200 1 -02} + {3971386800 -7200 1 -03} {3980455200 -10800 0 -03} - {4001626800 -7200 1 -02} + {4002836400 -7200 1 -03} {4011904800 -10800 0 -03} - {4033076400 -7200 1 -02} + {4034286000 -7200 1 -03} {4043354400 -10800 0 -03} - {4064526000 -7200 1 -02} + {4065735600 -7200 1 -03} {4074804000 -10800 0 -03} - {4095975600 -7200 1 -02} + {4097185200 -7200 1 -03} } diff --git a/library/tzdata/Antarctica/Casey b/library/tzdata/Antarctica/Casey index beb0f9e..aa37480 100644 --- a/library/tzdata/Antarctica/Casey +++ b/library/tzdata/Antarctica/Casey @@ -8,4 +8,5 @@ set TZData(:Antarctica/Casey) { {1319738400 39600 0 +11} {1329843600 28800 0 +08} {1477065600 39600 0 +11} + {1520701200 28800 0 +08} } diff --git a/library/tzdata/Antarctica/Palmer b/library/tzdata/Antarctica/Palmer index bb2be4d..f450e3b 100644 --- a/library/tzdata/Antarctica/Palmer +++ b/library/tzdata/Antarctica/Palmer @@ -4,84 +4,84 @@ set TZData(:Antarctica/Palmer) { {-9223372036854775808 0 0 -00} {-157766400 -14400 0 -04} {-152654400 -14400 0 -04} - {-132955200 -10800 1 -03} + {-132955200 -10800 1 -04} {-121122000 -14400 0 -04} - {-101419200 -10800 1 -03} + {-101419200 -10800 1 -04} {-86821200 -14400 0 -04} - {-71092800 -10800 1 -03} + {-71092800 -10800 1 -04} {-54766800 -14400 0 -04} - {-39038400 -10800 1 -03} + {-39038400 -10800 1 -04} {-23317200 -14400 0 -04} {-7588800 -10800 0 -03} - {128142000 -7200 1 -02} + {128142000 -7200 1 -03} {136605600 -10800 0 -03} {389070000 -14400 0 -04} - {403070400 -10800 1 -03} + {403070400 -10800 1 -04} {416372400 -14400 0 -04} - {434520000 -10800 1 -03} + {434520000 -10800 1 -04} {447822000 -14400 0 -04} - {466574400 -10800 1 -03} + {466574400 -10800 1 -04} {479271600 -14400 0 -04} - {498024000 -10800 1 -03} + {498024000 -10800 1 -04} {510721200 -14400 0 -04} - {529473600 -10800 1 -03} + {529473600 -10800 1 -04} {545194800 -14400 0 -04} - {560923200 -10800 1 -03} + {560923200 -10800 1 -04} {574225200 -14400 0 -04} - {592372800 -10800 1 -03} + {592372800 -10800 1 -04} {605674800 -14400 0 -04} - {624427200 -10800 1 -03} + {624427200 -10800 1 -04} {637124400 -14400 0 -04} - {653457600 -10800 1 -03} + {653457600 -10800 1 -04} {668574000 -14400 0 -04} - {687326400 -10800 1 -03} + {687326400 -10800 1 -04} {700628400 -14400 0 -04} - {718776000 -10800 1 -03} + {718776000 -10800 1 -04} {732078000 -14400 0 -04} - {750225600 -10800 1 -03} + {750225600 -10800 1 -04} {763527600 -14400 0 -04} - {781675200 -10800 1 -03} + {781675200 -10800 1 -04} {794977200 -14400 0 -04} - {813729600 -10800 1 -03} + {813729600 -10800 1 -04} {826426800 -14400 0 -04} - {845179200 -10800 1 -03} + {845179200 -10800 1 -04} {859690800 -14400 0 -04} - {876628800 -10800 1 -03} + {876628800 -10800 1 -04} {889930800 -14400 0 -04} - {906868800 -10800 1 -03} + {906868800 -10800 1 -04} {923194800 -14400 0 -04} - {939528000 -10800 1 -03} + {939528000 -10800 1 -04} {952830000 -14400 0 -04} - {971582400 -10800 1 -03} + {971582400 -10800 1 -04} {984279600 -14400 0 -04} - {1003032000 -10800 1 -03} + {1003032000 -10800 1 -04} {1015729200 -14400 0 -04} - {1034481600 -10800 1 -03} + {1034481600 -10800 1 -04} {1047178800 -14400 0 -04} - {1065931200 -10800 1 -03} + {1065931200 -10800 1 -04} {1079233200 -14400 0 -04} - {1097380800 -10800 1 -03} + {1097380800 -10800 1 -04} {1110682800 -14400 0 -04} - {1128830400 -10800 1 -03} + {1128830400 -10800 1 -04} {1142132400 -14400 0 -04} - {1160884800 -10800 1 -03} + {1160884800 -10800 1 -04} {1173582000 -14400 0 -04} - {1192334400 -10800 1 -03} + {1192334400 -10800 1 -04} {1206846000 -14400 0 -04} - {1223784000 -10800 1 -03} + {1223784000 -10800 1 -04} {1237086000 -14400 0 -04} - {1255233600 -10800 1 -03} + {1255233600 -10800 1 -04} {1270350000 -14400 0 -04} - {1286683200 -10800 1 -03} + {1286683200 -10800 1 -04} {1304823600 -14400 0 -04} - {1313899200 -10800 1 -03} + {1313899200 -10800 1 -04} {1335668400 -14400 0 -04} - {1346558400 -10800 1 -03} + {1346558400 -10800 1 -04} {1367118000 -14400 0 -04} - {1378612800 -10800 1 -03} + {1378612800 -10800 1 -04} {1398567600 -14400 0 -04} - {1410062400 -10800 1 -03} + {1410062400 -10800 1 -04} {1463281200 -14400 0 -04} - {1471147200 -10800 1 -03} + {1471147200 -10800 1 -04} {1480820400 -10800 0 -03} } diff --git a/library/tzdata/Asia/Almaty b/library/tzdata/Asia/Almaty index 2b83197..f42935d 100644 --- a/library/tzdata/Asia/Almaty +++ b/library/tzdata/Asia/Almaty @@ -4,54 +4,54 @@ set TZData(:Asia/Almaty) { {-9223372036854775808 18468 0 LMT} {-1441170468 18000 0 +05} {-1247547600 21600 0 +06} - {354909600 25200 1 +07} + {354909600 25200 1 +06} {370717200 21600 0 +06} - {386445600 25200 1 +07} + {386445600 25200 1 +06} {402253200 21600 0 +06} - {417981600 25200 1 +07} + {417981600 25200 1 +06} {433789200 21600 0 +06} - {449604000 25200 1 +07} + {449604000 25200 1 +06} {465336000 21600 0 +06} - {481060800 25200 1 +07} + {481060800 25200 1 +06} {496785600 21600 0 +06} - {512510400 25200 1 +07} + {512510400 25200 1 +06} {528235200 21600 0 +06} - {543960000 25200 1 +07} + {543960000 25200 1 +06} {559684800 21600 0 +06} - {575409600 25200 1 +07} + {575409600 25200 1 +06} {591134400 21600 0 +06} - {606859200 25200 1 +07} + {606859200 25200 1 +06} {622584000 21600 0 +06} - {638308800 25200 1 +07} + {638308800 25200 1 +06} {654638400 21600 0 +06} {670363200 18000 0 +05} - {670366800 21600 1 +06} + {670366800 21600 1 +05} {686091600 18000 0 +05} {695768400 21600 0 +06} - {701812800 25200 1 +07} + {701812800 25200 1 +06} {717537600 21600 0 +06} - {733262400 25200 1 +07} + {733262400 25200 1 +06} {748987200 21600 0 +06} - {764712000 25200 1 +07} + {764712000 25200 1 +06} {780436800 21600 0 +06} - {796161600 25200 1 +07} + {796161600 25200 1 +06} {811886400 21600 0 +06} - {828216000 25200 1 +07} + {828216000 25200 1 +06} {846360000 21600 0 +06} - {859665600 25200 1 +07} + {859665600 25200 1 +06} {877809600 21600 0 +06} - {891115200 25200 1 +07} + {891115200 25200 1 +06} {909259200 21600 0 +06} - {922564800 25200 1 +07} + {922564800 25200 1 +06} {941313600 21600 0 +06} - {954014400 25200 1 +07} + {954014400 25200 1 +06} {972763200 21600 0 +06} - {985464000 25200 1 +07} + {985464000 25200 1 +06} {1004212800 21600 0 +06} - {1017518400 25200 1 +07} + {1017518400 25200 1 +06} {1035662400 21600 0 +06} - {1048968000 25200 1 +07} + {1048968000 25200 1 +06} {1067112000 21600 0 +06} - {1080417600 25200 1 +07} + {1080417600 25200 1 +06} {1099166400 21600 0 +06} } diff --git a/library/tzdata/Asia/Aqtau b/library/tzdata/Asia/Aqtau index c128b27..41da2ca 100644 --- a/library/tzdata/Asia/Aqtau +++ b/library/tzdata/Asia/Aqtau @@ -6,53 +6,53 @@ set TZData(:Asia/Aqtau) { {-1247544000 18000 0 +05} {370724400 21600 0 +06} {386445600 18000 0 +05} - {386449200 21600 1 +06} + {386449200 21600 1 +05} {402256800 18000 0 +05} - {417985200 21600 1 +06} + {417985200 21600 1 +05} {433792800 18000 0 +05} - {449607600 21600 1 +06} + {449607600 21600 1 +05} {465339600 18000 0 +05} - {481064400 21600 1 +06} + {481064400 21600 1 +05} {496789200 18000 0 +05} - {512514000 21600 1 +06} + {512514000 21600 1 +05} {528238800 18000 0 +05} - {543963600 21600 1 +06} + {543963600 21600 1 +05} {559688400 18000 0 +05} - {575413200 21600 1 +06} + {575413200 21600 1 +05} {591138000 18000 0 +05} - {606862800 21600 1 +06} + {606862800 21600 1 +05} {622587600 18000 0 +05} - {638312400 21600 1 +06} + {638312400 21600 1 +05} {654642000 18000 0 +05} {670366800 14400 0 +04} - {670370400 18000 1 +05} + {670370400 18000 1 +04} {686095200 14400 0 +04} {695772000 18000 0 +05} - {701816400 21600 1 +06} + {701816400 21600 1 +05} {717541200 18000 0 +05} - {733266000 21600 1 +06} + {733266000 21600 1 +05} {748990800 18000 0 +05} - {764715600 21600 1 +06} - {780440400 18000 0 +05} + {764715600 21600 1 +05} + {780440400 18000 0 +04} {780444000 14400 0 +04} - {796168800 18000 1 +05} + {796168800 18000 1 +04} {811893600 14400 0 +04} - {828223200 18000 1 +05} + {828223200 18000 1 +04} {846367200 14400 0 +04} - {859672800 18000 1 +05} + {859672800 18000 1 +04} {877816800 14400 0 +04} - {891122400 18000 1 +05} + {891122400 18000 1 +04} {909266400 14400 0 +04} - {922572000 18000 1 +05} + {922572000 18000 1 +04} {941320800 14400 0 +04} - {954021600 18000 1 +05} + {954021600 18000 1 +04} {972770400 14400 0 +04} - {985471200 18000 1 +05} + {985471200 18000 1 +04} {1004220000 14400 0 +04} - {1017525600 18000 1 +05} + {1017525600 18000 1 +04} {1035669600 14400 0 +04} - {1048975200 18000 1 +05} + {1048975200 18000 1 +04} {1067119200 14400 0 +04} - {1080424800 18000 1 +05} + {1080424800 18000 1 +04} {1099173600 18000 0 +05} } diff --git a/library/tzdata/Asia/Aqtobe b/library/tzdata/Asia/Aqtobe index 55ef556..2316e68 100644 --- a/library/tzdata/Asia/Aqtobe +++ b/library/tzdata/Asia/Aqtobe @@ -7,52 +7,52 @@ set TZData(:Asia/Aqtobe) { {354913200 21600 1 +06} {370720800 21600 0 +06} {386445600 18000 0 +05} - {386449200 21600 1 +06} + {386449200 21600 1 +05} {402256800 18000 0 +05} - {417985200 21600 1 +06} + {417985200 21600 1 +05} {433792800 18000 0 +05} - {449607600 21600 1 +06} + {449607600 21600 1 +05} {465339600 18000 0 +05} - {481064400 21600 1 +06} + {481064400 21600 1 +05} {496789200 18000 0 +05} - {512514000 21600 1 +06} + {512514000 21600 1 +05} {528238800 18000 0 +05} - {543963600 21600 1 +06} + {543963600 21600 1 +05} {559688400 18000 0 +05} - {575413200 21600 1 +06} + {575413200 21600 1 +05} {591138000 18000 0 +05} - {606862800 21600 1 +06} + {606862800 21600 1 +05} {622587600 18000 0 +05} - {638312400 21600 1 +06} + {638312400 21600 1 +05} {654642000 18000 0 +05} {670366800 14400 0 +04} - {670370400 18000 1 +05} + {670370400 18000 1 +04} {686095200 14400 0 +04} {695772000 18000 0 +05} - {701816400 21600 1 +06} + {701816400 21600 1 +05} {717541200 18000 0 +05} - {733266000 21600 1 +06} + {733266000 21600 1 +05} {748990800 18000 0 +05} - {764715600 21600 1 +06} + {764715600 21600 1 +05} {780440400 18000 0 +05} - {796165200 21600 1 +06} + {796165200 21600 1 +05} {811890000 18000 0 +05} - {828219600 21600 1 +06} + {828219600 21600 1 +05} {846363600 18000 0 +05} - {859669200 21600 1 +06} + {859669200 21600 1 +05} {877813200 18000 0 +05} - {891118800 21600 1 +06} + {891118800 21600 1 +05} {909262800 18000 0 +05} - {922568400 21600 1 +06} + {922568400 21600 1 +05} {941317200 18000 0 +05} - {954018000 21600 1 +06} + {954018000 21600 1 +05} {972766800 18000 0 +05} - {985467600 21600 1 +06} + {985467600 21600 1 +05} {1004216400 18000 0 +05} - {1017522000 21600 1 +06} + {1017522000 21600 1 +05} {1035666000 18000 0 +05} - {1048971600 21600 1 +06} + {1048971600 21600 1 +05} {1067115600 18000 0 +05} - {1080421200 21600 1 +06} + {1080421200 21600 1 +05} {1099170000 18000 0 +05} } diff --git a/library/tzdata/Asia/Ashgabat b/library/tzdata/Asia/Ashgabat index fa6a619..feb7725 100644 --- a/library/tzdata/Asia/Ashgabat +++ b/library/tzdata/Asia/Ashgabat @@ -4,28 +4,28 @@ set TZData(:Asia/Ashgabat) { {-9223372036854775808 14012 0 LMT} {-1441166012 14400 0 +04} {-1247544000 18000 0 +05} - {354913200 21600 1 +06} + {354913200 21600 1 +05} {370720800 18000 0 +05} - {386449200 21600 1 +06} + {386449200 21600 1 +05} {402256800 18000 0 +05} - {417985200 21600 1 +06} + {417985200 21600 1 +05} {433792800 18000 0 +05} - {449607600 21600 1 +06} + {449607600 21600 1 +05} {465339600 18000 0 +05} - {481064400 21600 1 +06} + {481064400 21600 1 +05} {496789200 18000 0 +05} - {512514000 21600 1 +06} + {512514000 21600 1 +05} {528238800 18000 0 +05} - {543963600 21600 1 +06} + {543963600 21600 1 +05} {559688400 18000 0 +05} - {575413200 21600 1 +06} + {575413200 21600 1 +05} {591138000 18000 0 +05} - {606862800 21600 1 +06} + {606862800 21600 1 +05} {622587600 18000 0 +05} - {638312400 21600 1 +06} + {638312400 21600 1 +05} {654642000 18000 0 +05} {670366800 14400 0 +04} - {670370400 18000 1 +05} + {670370400 18000 1 +04} {686095200 14400 0 +04} {695772000 18000 0 +05} } diff --git a/library/tzdata/Asia/Atyrau b/library/tzdata/Asia/Atyrau index c31ff11..b6d8253 100644 --- a/library/tzdata/Asia/Atyrau +++ b/library/tzdata/Asia/Atyrau @@ -6,53 +6,53 @@ set TZData(:Asia/Atyrau) { {-1247540400 18000 0 +05} {370724400 21600 0 +06} {386445600 18000 0 +05} - {386449200 21600 1 +06} + {386449200 21600 1 +05} {402256800 18000 0 +05} - {417985200 21600 1 +06} + {417985200 21600 1 +05} {433792800 18000 0 +05} - {449607600 21600 1 +06} + {449607600 21600 1 +05} {465339600 18000 0 +05} - {481064400 21600 1 +06} + {481064400 21600 1 +05} {496789200 18000 0 +05} - {512514000 21600 1 +06} + {512514000 21600 1 +05} {528238800 18000 0 +05} - {543963600 21600 1 +06} + {543963600 21600 1 +05} {559688400 18000 0 +05} - {575413200 21600 1 +06} + {575413200 21600 1 +05} {591138000 18000 0 +05} - {606862800 21600 1 +06} + {606862800 21600 1 +05} {622587600 18000 0 +05} - {638312400 21600 1 +06} + {638312400 21600 1 +05} {654642000 18000 0 +05} {670366800 14400 0 +04} - {670370400 18000 1 +05} + {670370400 18000 1 +04} {686095200 14400 0 +04} {695772000 18000 0 +05} - {701816400 21600 1 +06} + {701816400 21600 1 +05} {717541200 18000 0 +05} - {733266000 21600 1 +06} + {733266000 21600 1 +05} {748990800 18000 0 +05} - {764715600 21600 1 +06} + {764715600 21600 1 +05} {780440400 18000 0 +05} - {796165200 21600 1 +06} + {796165200 21600 1 +05} {811890000 18000 0 +05} - {828219600 21600 1 +06} + {828219600 21600 1 +05} {846363600 18000 0 +05} - {859669200 21600 1 +06} + {859669200 21600 1 +05} {877813200 18000 0 +05} - {891118800 21600 1 +06} + {891118800 21600 1 +05} {909262800 18000 0 +05} {922568400 14400 0 +04} - {922572000 18000 1 +05} + {922572000 18000 1 +04} {941320800 14400 0 +04} - {954021600 18000 1 +05} + {954021600 18000 1 +04} {972770400 14400 0 +04} - {985471200 18000 1 +05} + {985471200 18000 1 +04} {1004220000 14400 0 +04} - {1017525600 18000 1 +05} + {1017525600 18000 1 +04} {1035669600 14400 0 +04} - {1048975200 18000 1 +05} + {1048975200 18000 1 +04} {1067119200 14400 0 +04} - {1080424800 18000 1 +05} + {1080424800 18000 1 +04} {1099173600 18000 0 +05} } diff --git a/library/tzdata/Asia/Baghdad b/library/tzdata/Asia/Baghdad index 623e310..c76a6a1 100644 --- a/library/tzdata/Asia/Baghdad +++ b/library/tzdata/Asia/Baghdad @@ -4,56 +4,56 @@ set TZData(:Asia/Baghdad) { {-9223372036854775808 10660 0 LMT} {-2524532260 10656 0 BMT} {-1641005856 10800 0 +03} - {389048400 14400 0 +04} - {402264000 10800 0 +04} - {417906000 14400 1 +04} - {433800000 10800 0 +04} - {449614800 14400 1 +04} - {465422400 10800 0 +04} - {481150800 14400 1 +04} - {496792800 10800 0 +04} - {512517600 14400 1 +04} - {528242400 10800 0 +04} - {543967200 14400 1 +04} - {559692000 10800 0 +04} - {575416800 14400 1 +04} - {591141600 10800 0 +04} - {606866400 14400 1 +04} - {622591200 10800 0 +04} - {638316000 14400 1 +04} - {654645600 10800 0 +04} - {670464000 14400 1 +04} - {686275200 10800 0 +04} - {702086400 14400 1 +04} - {717897600 10800 0 +04} - {733622400 14400 1 +04} - {749433600 10800 0 +04} - {765158400 14400 1 +04} - {780969600 10800 0 +04} - {796694400 14400 1 +04} - {812505600 10800 0 +04} - {828316800 14400 1 +04} - {844128000 10800 0 +04} - {859852800 14400 1 +04} - {875664000 10800 0 +04} - {891388800 14400 1 +04} - {907200000 10800 0 +04} - {922924800 14400 1 +04} - {938736000 10800 0 +04} - {954547200 14400 1 +04} - {970358400 10800 0 +04} - {986083200 14400 1 +04} - {1001894400 10800 0 +04} - {1017619200 14400 1 +04} - {1033430400 10800 0 +04} - {1049155200 14400 1 +04} - {1064966400 10800 0 +04} - {1080777600 14400 1 +04} - {1096588800 10800 0 +04} - {1112313600 14400 1 +04} - {1128124800 10800 0 +04} - {1143849600 14400 1 +04} - {1159660800 10800 0 +04} - {1175385600 14400 1 +04} - {1191196800 10800 0 +04} + {389048400 14400 0 +03} + {402264000 10800 0 +03} + {417906000 14400 1 +03} + {433800000 10800 0 +03} + {449614800 14400 1 +03} + {465422400 10800 0 +03} + {481150800 14400 1 +03} + {496792800 10800 0 +03} + {512517600 14400 1 +03} + {528242400 10800 0 +03} + {543967200 14400 1 +03} + {559692000 10800 0 +03} + {575416800 14400 1 +03} + {591141600 10800 0 +03} + {606866400 14400 1 +03} + {622591200 10800 0 +03} + {638316000 14400 1 +03} + {654645600 10800 0 +03} + {670464000 14400 1 +03} + {686275200 10800 0 +03} + {702086400 14400 1 +03} + {717897600 10800 0 +03} + {733622400 14400 1 +03} + {749433600 10800 0 +03} + {765158400 14400 1 +03} + {780969600 10800 0 +03} + {796694400 14400 1 +03} + {812505600 10800 0 +03} + {828316800 14400 1 +03} + {844128000 10800 0 +03} + {859852800 14400 1 +03} + {875664000 10800 0 +03} + {891388800 14400 1 +03} + {907200000 10800 0 +03} + {922924800 14400 1 +03} + {938736000 10800 0 +03} + {954547200 14400 1 +03} + {970358400 10800 0 +03} + {986083200 14400 1 +03} + {1001894400 10800 0 +03} + {1017619200 14400 1 +03} + {1033430400 10800 0 +03} + {1049155200 14400 1 +03} + {1064966400 10800 0 +03} + {1080777600 14400 1 +03} + {1096588800 10800 0 +03} + {1112313600 14400 1 +03} + {1128124800 10800 0 +03} + {1143849600 14400 1 +03} + {1159660800 10800 0 +03} + {1175385600 14400 1 +03} + {1191196800 10800 0 +03} } diff --git a/library/tzdata/Asia/Baku b/library/tzdata/Asia/Baku index f945b89..03dee19 100644 --- a/library/tzdata/Asia/Baku +++ b/library/tzdata/Asia/Baku @@ -4,71 +4,71 @@ set TZData(:Asia/Baku) { {-9223372036854775808 11964 0 LMT} {-1441163964 10800 0 +03} {-405140400 14400 0 +04} - {354916800 18000 1 +05} + {354916800 18000 1 +04} {370724400 14400 0 +04} - {386452800 18000 1 +05} + {386452800 18000 1 +04} {402260400 14400 0 +04} - {417988800 18000 1 +05} + {417988800 18000 1 +04} {433796400 14400 0 +04} - {449611200 18000 1 +05} + {449611200 18000 1 +04} {465343200 14400 0 +04} - {481068000 18000 1 +05} + {481068000 18000 1 +04} {496792800 14400 0 +04} - {512517600 18000 1 +05} + {512517600 18000 1 +04} {528242400 14400 0 +04} - {543967200 18000 1 +05} + {543967200 18000 1 +04} {559692000 14400 0 +04} - {575416800 18000 1 +05} + {575416800 18000 1 +04} {591141600 14400 0 +04} - {606866400 18000 1 +05} + {606866400 18000 1 +04} {622591200 14400 0 +04} - {638316000 18000 1 +05} + {638316000 18000 1 +04} {654645600 14400 0 +04} {670370400 10800 0 +03} - {670374000 14400 1 +04} + {670374000 14400 1 +03} {686098800 10800 0 +03} - {701823600 14400 1 +04} + {701823600 14400 1 +03} {717548400 14400 0 +04} {820440000 14400 0 +04} {828234000 18000 1 +05} {846378000 14400 0 +04} {852062400 14400 0 +04} - {859680000 18000 1 +05} + {859680000 18000 1 +04} {877824000 14400 0 +04} - {891129600 18000 1 +05} + {891129600 18000 1 +04} {909273600 14400 0 +04} - {922579200 18000 1 +05} + {922579200 18000 1 +04} {941328000 14400 0 +04} - {954028800 18000 1 +05} + {954028800 18000 1 +04} {972777600 14400 0 +04} - {985478400 18000 1 +05} + {985478400 18000 1 +04} {1004227200 14400 0 +04} - {1017532800 18000 1 +05} + {1017532800 18000 1 +04} {1035676800 14400 0 +04} - {1048982400 18000 1 +05} + {1048982400 18000 1 +04} {1067126400 14400 0 +04} - {1080432000 18000 1 +05} + {1080432000 18000 1 +04} {1099180800 14400 0 +04} - {1111881600 18000 1 +05} + {1111881600 18000 1 +04} {1130630400 14400 0 +04} - {1143331200 18000 1 +05} + {1143331200 18000 1 +04} {1162080000 14400 0 +04} - {1174780800 18000 1 +05} + {1174780800 18000 1 +04} {1193529600 14400 0 +04} - {1206835200 18000 1 +05} + {1206835200 18000 1 +04} {1224979200 14400 0 +04} - {1238284800 18000 1 +05} + {1238284800 18000 1 +04} {1256428800 14400 0 +04} - {1269734400 18000 1 +05} + {1269734400 18000 1 +04} {1288483200 14400 0 +04} - {1301184000 18000 1 +05} + {1301184000 18000 1 +04} {1319932800 14400 0 +04} - {1332633600 18000 1 +05} + {1332633600 18000 1 +04} {1351382400 14400 0 +04} - {1364688000 18000 1 +05} + {1364688000 18000 1 +04} {1382832000 14400 0 +04} - {1396137600 18000 1 +05} + {1396137600 18000 1 +04} {1414281600 14400 0 +04} - {1427587200 18000 1 +05} + {1427587200 18000 1 +04} {1445731200 14400 0 +04} } diff --git a/library/tzdata/Asia/Bishkek b/library/tzdata/Asia/Bishkek index a02d789..bc4cbdd 100644 --- a/library/tzdata/Asia/Bishkek +++ b/library/tzdata/Asia/Bishkek @@ -4,55 +4,55 @@ set TZData(:Asia/Bishkek) { {-9223372036854775808 17904 0 LMT} {-1441169904 18000 0 +05} {-1247547600 21600 0 +06} - {354909600 25200 1 +07} + {354909600 25200 1 +06} {370717200 21600 0 +06} - {386445600 25200 1 +07} + {386445600 25200 1 +06} {402253200 21600 0 +06} - {417981600 25200 1 +07} + {417981600 25200 1 +06} {433789200 21600 0 +06} - {449604000 25200 1 +07} + {449604000 25200 1 +06} {465336000 21600 0 +06} - {481060800 25200 1 +07} + {481060800 25200 1 +06} {496785600 21600 0 +06} - {512510400 25200 1 +07} + {512510400 25200 1 +06} {528235200 21600 0 +06} - {543960000 25200 1 +07} + {543960000 25200 1 +06} {559684800 21600 0 +06} - {575409600 25200 1 +07} + {575409600 25200 1 +06} {591134400 21600 0 +06} - {606859200 25200 1 +07} + {606859200 25200 1 +06} {622584000 21600 0 +06} - {638308800 25200 1 +07} + {638308800 25200 1 +06} {654638400 21600 0 +06} {670363200 18000 0 +05} - {670366800 21600 1 +06} + {670366800 21600 1 +05} {683586000 18000 0 +05} - {703018800 21600 1 +06} + {703018800 21600 1 +05} {717530400 18000 0 +05} - {734468400 21600 1 +06} + {734468400 21600 1 +05} {748980000 18000 0 +05} - {765918000 21600 1 +06} + {765918000 21600 1 +05} {780429600 18000 0 +05} - {797367600 21600 1 +06} + {797367600 21600 1 +05} {811879200 18000 0 +05} - {828817200 21600 1 +06} + {828817200 21600 1 +05} {843933600 18000 0 +05} - {859671000 21600 1 +06} + {859671000 21600 1 +05} {877811400 18000 0 +05} - {891120600 21600 1 +06} + {891120600 21600 1 +05} {909261000 18000 0 +05} - {922570200 21600 1 +06} + {922570200 21600 1 +05} {941315400 18000 0 +05} - {954019800 21600 1 +06} + {954019800 21600 1 +05} {972765000 18000 0 +05} - {985469400 21600 1 +06} + {985469400 21600 1 +05} {1004214600 18000 0 +05} - {1017523800 21600 1 +06} + {1017523800 21600 1 +05} {1035664200 18000 0 +05} - {1048973400 21600 1 +06} + {1048973400 21600 1 +05} {1067113800 18000 0 +05} - {1080423000 21600 1 +06} + {1080423000 21600 1 +05} {1099168200 18000 0 +05} - {1111872600 21600 1 +06} + {1111872600 21600 1 +05} {1123783200 21600 0 +06} } diff --git a/library/tzdata/Asia/Choibalsan b/library/tzdata/Asia/Choibalsan index 3db65de..b072c76 100644 --- a/library/tzdata/Asia/Choibalsan +++ b/library/tzdata/Asia/Choibalsan @@ -4,53 +4,53 @@ set TZData(:Asia/Choibalsan) { {-9223372036854775808 27480 0 LMT} {-2032933080 25200 0 +07} {252435600 28800 0 +08} - {417974400 36000 0 +10} + {417974400 36000 0 +09} {433778400 32400 0 +09} - {449593200 36000 1 +10} + {449593200 36000 1 +09} {465314400 32400 0 +09} - {481042800 36000 1 +10} + {481042800 36000 1 +09} {496764000 32400 0 +09} - {512492400 36000 1 +10} + {512492400 36000 1 +09} {528213600 32400 0 +09} - {543942000 36000 1 +10} + {543942000 36000 1 +09} {559663200 32400 0 +09} - {575391600 36000 1 +10} + {575391600 36000 1 +09} {591112800 32400 0 +09} - {606841200 36000 1 +10} + {606841200 36000 1 +09} {622562400 32400 0 +09} - {638290800 36000 1 +10} + {638290800 36000 1 +09} {654616800 32400 0 +09} - {670345200 36000 1 +10} + {670345200 36000 1 +09} {686066400 32400 0 +09} - {701794800 36000 1 +10} + {701794800 36000 1 +09} {717516000 32400 0 +09} - {733244400 36000 1 +10} + {733244400 36000 1 +09} {748965600 32400 0 +09} - {764694000 36000 1 +10} + {764694000 36000 1 +09} {780415200 32400 0 +09} - {796143600 36000 1 +10} + {796143600 36000 1 +09} {811864800 32400 0 +09} - {828198000 36000 1 +10} + {828198000 36000 1 +09} {843919200 32400 0 +09} - {859647600 36000 1 +10} + {859647600 36000 1 +09} {875368800 32400 0 +09} - {891097200 36000 1 +10} + {891097200 36000 1 +09} {906818400 32400 0 +09} - {988390800 36000 1 +10} + {988390800 36000 1 +09} {1001692800 32400 0 +09} - {1017421200 36000 1 +10} + {1017421200 36000 1 +09} {1033142400 32400 0 +09} - {1048870800 36000 1 +10} + {1048870800 36000 1 +09} {1064592000 32400 0 +09} - {1080320400 36000 1 +10} + {1080320400 36000 1 +09} {1096041600 32400 0 +09} - {1111770000 36000 1 +10} + {1111770000 36000 1 +09} {1127491200 32400 0 +09} - {1143219600 36000 1 +10} + {1143219600 36000 1 +09} {1159545600 32400 0 +09} {1206889200 28800 0 +08} - {1427479200 32400 1 +09} + {1427479200 32400 1 +08} {1443193200 28800 0 +08} - {1458928800 32400 1 +09} + {1458928800 32400 1 +08} {1474642800 28800 0 +08} } diff --git a/library/tzdata/Asia/Dhaka b/library/tzdata/Asia/Dhaka index 0dc3987..c044095 100644 --- a/library/tzdata/Asia/Dhaka +++ b/library/tzdata/Asia/Dhaka @@ -8,6 +8,6 @@ set TZData(:Asia/Dhaka) { {-862637400 23400 0 +0630} {-576138600 21600 0 +06} {1230746400 21600 0 +06} - {1245430800 25200 1 +07} + {1245430800 25200 1 +06} {1262278800 21600 0 +06} } diff --git a/library/tzdata/Asia/Dushanbe b/library/tzdata/Asia/Dushanbe index e9ed132..fe82ce7 100644 --- a/library/tzdata/Asia/Dushanbe +++ b/library/tzdata/Asia/Dushanbe @@ -4,25 +4,25 @@ set TZData(:Asia/Dushanbe) { {-9223372036854775808 16512 0 LMT} {-1441168512 18000 0 +05} {-1247547600 21600 0 +06} - {354909600 25200 1 +07} + {354909600 25200 1 +06} {370717200 21600 0 +06} - {386445600 25200 1 +07} + {386445600 25200 1 +06} {402253200 21600 0 +06} - {417981600 25200 1 +07} + {417981600 25200 1 +06} {433789200 21600 0 +06} - {449604000 25200 1 +07} + {449604000 25200 1 +06} {465336000 21600 0 +06} - {481060800 25200 1 +07} + {481060800 25200 1 +06} {496785600 21600 0 +06} - {512510400 25200 1 +07} + {512510400 25200 1 +06} {528235200 21600 0 +06} - {543960000 25200 1 +07} + {543960000 25200 1 +06} {559684800 21600 0 +06} - {575409600 25200 1 +07} + {575409600 25200 1 +06} {591134400 21600 0 +06} - {606859200 25200 1 +07} + {606859200 25200 1 +06} {622584000 21600 0 +06} - {638308800 25200 1 +07} + {638308800 25200 1 +06} {654638400 21600 0 +06} {670363200 21600 1 +06} {684363600 18000 0 +05} diff --git a/library/tzdata/Asia/Gaza b/library/tzdata/Asia/Gaza index 1149d51..85b9f67 100644 --- a/library/tzdata/Asia/Gaza +++ b/library/tzdata/Asia/Gaza @@ -111,9 +111,9 @@ set TZData(:Asia/Gaza) { {1477692000 7200 0 EET} {1490396400 10800 1 EEST} {1509141600 7200 0 EET} - {1522450800 10800 1 EEST} + {1521846000 10800 1 EEST} {1540591200 7200 0 EET} - {1553900400 10800 1 EEST} + {1553295600 10800 1 EEST} {1572040800 7200 0 EET} {1585350000 10800 1 EEST} {1604095200 7200 0 EET} @@ -123,9 +123,9 @@ set TZData(:Asia/Gaza) { {1666994400 7200 0 EET} {1679698800 10800 1 EEST} {1698444000 7200 0 EET} - {1711753200 10800 1 EEST} + {1711148400 10800 1 EEST} {1729893600 7200 0 EET} - {1743202800 10800 1 EEST} + {1742598000 10800 1 EEST} {1761343200 7200 0 EET} {1774652400 10800 1 EEST} {1793397600 7200 0 EET} @@ -133,11 +133,11 @@ set TZData(:Asia/Gaza) { {1824847200 7200 0 EET} {1837551600 10800 1 EEST} {1856296800 7200 0 EET} - {1869606000 10800 1 EEST} + {1869001200 10800 1 EEST} {1887746400 7200 0 EET} - {1901055600 10800 1 EEST} + {1900450800 10800 1 EEST} {1919196000 7200 0 EET} - {1932505200 10800 1 EEST} + {1931900400 10800 1 EEST} {1950645600 7200 0 EET} {1963954800 10800 1 EEST} {1982700000 7200 0 EET} @@ -145,9 +145,9 @@ set TZData(:Asia/Gaza) { {2014149600 7200 0 EET} {2026854000 10800 1 EEST} {2045599200 7200 0 EET} - {2058908400 10800 1 EEST} + {2058303600 10800 1 EEST} {2077048800 7200 0 EET} - {2090358000 10800 1 EEST} + {2089753200 10800 1 EEST} {2108498400 7200 0 EET} {2121807600 10800 1 EEST} {2140552800 7200 0 EET} @@ -155,11 +155,11 @@ set TZData(:Asia/Gaza) { {2172002400 7200 0 EET} {2184706800 10800 1 EEST} {2203452000 7200 0 EET} - {2216761200 10800 1 EEST} + {2216156400 10800 1 EEST} {2234901600 7200 0 EET} - {2248210800 10800 1 EEST} + {2247606000 10800 1 EEST} {2266351200 7200 0 EET} - {2279660400 10800 1 EEST} + {2279055600 10800 1 EEST} {2297800800 7200 0 EET} {2311110000 10800 1 EEST} {2329855200 7200 0 EET} @@ -167,9 +167,9 @@ set TZData(:Asia/Gaza) { {2361304800 7200 0 EET} {2374009200 10800 1 EEST} {2392754400 7200 0 EET} - {2406063600 10800 1 EEST} + {2405458800 10800 1 EEST} {2424204000 7200 0 EET} - {2437513200 10800 1 EEST} + {2436908400 10800 1 EEST} {2455653600 7200 0 EET} {2468962800 10800 1 EEST} {2487708000 7200 0 EET} @@ -179,9 +179,9 @@ set TZData(:Asia/Gaza) { {2550607200 7200 0 EET} {2563311600 10800 1 EEST} {2582056800 7200 0 EET} - {2595366000 10800 1 EEST} + {2594761200 10800 1 EEST} {2613506400 7200 0 EET} - {2626815600 10800 1 EEST} + {2626210800 10800 1 EEST} {2644956000 7200 0 EET} {2658265200 10800 1 EEST} {2677010400 7200 0 EET} @@ -189,11 +189,11 @@ set TZData(:Asia/Gaza) { {2708460000 7200 0 EET} {2721164400 10800 1 EEST} {2739909600 7200 0 EET} - {2753218800 10800 1 EEST} + {2752614000 10800 1 EEST} {2771359200 7200 0 EET} - {2784668400 10800 1 EEST} + {2784063600 10800 1 EEST} {2802808800 7200 0 EET} - {2816118000 10800 1 EEST} + {2815513200 10800 1 EEST} {2834258400 7200 0 EET} {2847567600 10800 1 EEST} {2866312800 7200 0 EET} @@ -201,9 +201,9 @@ set TZData(:Asia/Gaza) { {2897762400 7200 0 EET} {2910466800 10800 1 EEST} {2929212000 7200 0 EET} - {2942521200 10800 1 EEST} + {2941916400 10800 1 EEST} {2960661600 7200 0 EET} - {2973970800 10800 1 EEST} + {2973366000 10800 1 EEST} {2992111200 7200 0 EET} {3005420400 10800 1 EEST} {3024165600 7200 0 EET} @@ -211,11 +211,11 @@ set TZData(:Asia/Gaza) { {3055615200 7200 0 EET} {3068319600 10800 1 EEST} {3087064800 7200 0 EET} - {3100374000 10800 1 EEST} + {3099769200 10800 1 EEST} {3118514400 7200 0 EET} - {3131823600 10800 1 EEST} + {3131218800 10800 1 EEST} {3149964000 7200 0 EET} - {3163273200 10800 1 EEST} + {3162668400 10800 1 EEST} {3181413600 7200 0 EET} {3194722800 10800 1 EEST} {3213468000 7200 0 EET} @@ -223,9 +223,9 @@ set TZData(:Asia/Gaza) { {3244917600 7200 0 EET} {3257622000 10800 1 EEST} {3276367200 7200 0 EET} - {3289676400 10800 1 EEST} + {3289071600 10800 1 EEST} {3307816800 7200 0 EET} - {3321126000 10800 1 EEST} + {3320521200 10800 1 EEST} {3339266400 7200 0 EET} {3352575600 10800 1 EEST} {3371320800 7200 0 EET} @@ -235,9 +235,9 @@ set TZData(:Asia/Gaza) { {3434220000 7200 0 EET} {3446924400 10800 1 EEST} {3465669600 7200 0 EET} - {3478978800 10800 1 EEST} + {3478374000 10800 1 EEST} {3497119200 7200 0 EET} - {3510428400 10800 1 EEST} + {3509823600 10800 1 EEST} {3528568800 7200 0 EET} {3541878000 10800 1 EEST} {3560623200 7200 0 EET} @@ -245,11 +245,11 @@ set TZData(:Asia/Gaza) { {3592072800 7200 0 EET} {3604777200 10800 1 EEST} {3623522400 7200 0 EET} - {3636831600 10800 1 EEST} + {3636226800 10800 1 EEST} {3654972000 7200 0 EET} - {3668281200 10800 1 EEST} + {3667676400 10800 1 EEST} {3686421600 7200 0 EET} - {3699730800 10800 1 EEST} + {3699126000 10800 1 EEST} {3717871200 7200 0 EET} {3731180400 10800 1 EEST} {3749925600 7200 0 EET} @@ -257,9 +257,9 @@ set TZData(:Asia/Gaza) { {3781375200 7200 0 EET} {3794079600 10800 1 EEST} {3812824800 7200 0 EET} - {3826134000 10800 1 EEST} + {3825529200 10800 1 EEST} {3844274400 7200 0 EET} - {3857583600 10800 1 EEST} + {3856978800 10800 1 EEST} {3875724000 7200 0 EET} {3889033200 10800 1 EEST} {3907778400 7200 0 EET} @@ -267,11 +267,11 @@ set TZData(:Asia/Gaza) { {3939228000 7200 0 EET} {3951932400 10800 1 EEST} {3970677600 7200 0 EET} - {3983986800 10800 1 EEST} + {3983382000 10800 1 EEST} {4002127200 7200 0 EET} - {4015436400 10800 1 EEST} + {4014831600 10800 1 EEST} {4033576800 7200 0 EET} - {4046886000 10800 1 EEST} + {4046281200 10800 1 EEST} {4065026400 7200 0 EET} {4078335600 10800 1 EEST} {4097080800 7200 0 EET} diff --git a/library/tzdata/Asia/Hebron b/library/tzdata/Asia/Hebron index 5d312b8..c0f5447 100644 --- a/library/tzdata/Asia/Hebron +++ b/library/tzdata/Asia/Hebron @@ -110,9 +110,9 @@ set TZData(:Asia/Hebron) { {1477692000 7200 0 EET} {1490396400 10800 1 EEST} {1509141600 7200 0 EET} - {1522450800 10800 1 EEST} + {1521846000 10800 1 EEST} {1540591200 7200 0 EET} - {1553900400 10800 1 EEST} + {1553295600 10800 1 EEST} {1572040800 7200 0 EET} {1585350000 10800 1 EEST} {1604095200 7200 0 EET} @@ -122,9 +122,9 @@ set TZData(:Asia/Hebron) { {1666994400 7200 0 EET} {1679698800 10800 1 EEST} {1698444000 7200 0 EET} - {1711753200 10800 1 EEST} + {1711148400 10800 1 EEST} {1729893600 7200 0 EET} - {1743202800 10800 1 EEST} + {1742598000 10800 1 EEST} {1761343200 7200 0 EET} {1774652400 10800 1 EEST} {1793397600 7200 0 EET} @@ -132,11 +132,11 @@ set TZData(:Asia/Hebron) { {1824847200 7200 0 EET} {1837551600 10800 1 EEST} {1856296800 7200 0 EET} - {1869606000 10800 1 EEST} + {1869001200 10800 1 EEST} {1887746400 7200 0 EET} - {1901055600 10800 1 EEST} + {1900450800 10800 1 EEST} {1919196000 7200 0 EET} - {1932505200 10800 1 EEST} + {1931900400 10800 1 EEST} {1950645600 7200 0 EET} {1963954800 10800 1 EEST} {1982700000 7200 0 EET} @@ -144,9 +144,9 @@ set TZData(:Asia/Hebron) { {2014149600 7200 0 EET} {2026854000 10800 1 EEST} {2045599200 7200 0 EET} - {2058908400 10800 1 EEST} + {2058303600 10800 1 EEST} {2077048800 7200 0 EET} - {2090358000 10800 1 EEST} + {2089753200 10800 1 EEST} {2108498400 7200 0 EET} {2121807600 10800 1 EEST} {2140552800 7200 0 EET} @@ -154,11 +154,11 @@ set TZData(:Asia/Hebron) { {2172002400 7200 0 EET} {2184706800 10800 1 EEST} {2203452000 7200 0 EET} - {2216761200 10800 1 EEST} + {2216156400 10800 1 EEST} {2234901600 7200 0 EET} - {2248210800 10800 1 EEST} + {2247606000 10800 1 EEST} {2266351200 7200 0 EET} - {2279660400 10800 1 EEST} + {2279055600 10800 1 EEST} {2297800800 7200 0 EET} {2311110000 10800 1 EEST} {2329855200 7200 0 EET} @@ -166,9 +166,9 @@ set TZData(:Asia/Hebron) { {2361304800 7200 0 EET} {2374009200 10800 1 EEST} {2392754400 7200 0 EET} - {2406063600 10800 1 EEST} + {2405458800 10800 1 EEST} {2424204000 7200 0 EET} - {2437513200 10800 1 EEST} + {2436908400 10800 1 EEST} {2455653600 7200 0 EET} {2468962800 10800 1 EEST} {2487708000 7200 0 EET} @@ -178,9 +178,9 @@ set TZData(:Asia/Hebron) { {2550607200 7200 0 EET} {2563311600 10800 1 EEST} {2582056800 7200 0 EET} - {2595366000 10800 1 EEST} + {2594761200 10800 1 EEST} {2613506400 7200 0 EET} - {2626815600 10800 1 EEST} + {2626210800 10800 1 EEST} {2644956000 7200 0 EET} {2658265200 10800 1 EEST} {2677010400 7200 0 EET} @@ -188,11 +188,11 @@ set TZData(:Asia/Hebron) { {2708460000 7200 0 EET} {2721164400 10800 1 EEST} {2739909600 7200 0 EET} - {2753218800 10800 1 EEST} + {2752614000 10800 1 EEST} {2771359200 7200 0 EET} - {2784668400 10800 1 EEST} + {2784063600 10800 1 EEST} {2802808800 7200 0 EET} - {2816118000 10800 1 EEST} + {2815513200 10800 1 EEST} {2834258400 7200 0 EET} {2847567600 10800 1 EEST} {2866312800 7200 0 EET} @@ -200,9 +200,9 @@ set TZData(:Asia/Hebron) { {2897762400 7200 0 EET} {2910466800 10800 1 EEST} {2929212000 7200 0 EET} - {2942521200 10800 1 EEST} + {2941916400 10800 1 EEST} {2960661600 7200 0 EET} - {2973970800 10800 1 EEST} + {2973366000 10800 1 EEST} {2992111200 7200 0 EET} {3005420400 10800 1 EEST} {3024165600 7200 0 EET} @@ -210,11 +210,11 @@ set TZData(:Asia/Hebron) { {3055615200 7200 0 EET} {3068319600 10800 1 EEST} {3087064800 7200 0 EET} - {3100374000 10800 1 EEST} + {3099769200 10800 1 EEST} {3118514400 7200 0 EET} - {3131823600 10800 1 EEST} + {3131218800 10800 1 EEST} {3149964000 7200 0 EET} - {3163273200 10800 1 EEST} + {3162668400 10800 1 EEST} {3181413600 7200 0 EET} {3194722800 10800 1 EEST} {3213468000 7200 0 EET} @@ -222,9 +222,9 @@ set TZData(:Asia/Hebron) { {3244917600 7200 0 EET} {3257622000 10800 1 EEST} {3276367200 7200 0 EET} - {3289676400 10800 1 EEST} + {3289071600 10800 1 EEST} {3307816800 7200 0 EET} - {3321126000 10800 1 EEST} + {3320521200 10800 1 EEST} {3339266400 7200 0 EET} {3352575600 10800 1 EEST} {3371320800 7200 0 EET} @@ -234,9 +234,9 @@ set TZData(:Asia/Hebron) { {3434220000 7200 0 EET} {3446924400 10800 1 EEST} {3465669600 7200 0 EET} - {3478978800 10800 1 EEST} + {3478374000 10800 1 EEST} {3497119200 7200 0 EET} - {3510428400 10800 1 EEST} + {3509823600 10800 1 EEST} {3528568800 7200 0 EET} {3541878000 10800 1 EEST} {3560623200 7200 0 EET} @@ -244,11 +244,11 @@ set TZData(:Asia/Hebron) { {3592072800 7200 0 EET} {3604777200 10800 1 EEST} {3623522400 7200 0 EET} - {3636831600 10800 1 EEST} + {3636226800 10800 1 EEST} {3654972000 7200 0 EET} - {3668281200 10800 1 EEST} + {3667676400 10800 1 EEST} {3686421600 7200 0 EET} - {3699730800 10800 1 EEST} + {3699126000 10800 1 EEST} {3717871200 7200 0 EET} {3731180400 10800 1 EEST} {3749925600 7200 0 EET} @@ -256,9 +256,9 @@ set TZData(:Asia/Hebron) { {3781375200 7200 0 EET} {3794079600 10800 1 EEST} {3812824800 7200 0 EET} - {3826134000 10800 1 EEST} + {3825529200 10800 1 EEST} {3844274400 7200 0 EET} - {3857583600 10800 1 EEST} + {3856978800 10800 1 EEST} {3875724000 7200 0 EET} {3889033200 10800 1 EEST} {3907778400 7200 0 EET} @@ -266,11 +266,11 @@ set TZData(:Asia/Hebron) { {3939228000 7200 0 EET} {3951932400 10800 1 EEST} {3970677600 7200 0 EET} - {3983986800 10800 1 EEST} + {3983382000 10800 1 EEST} {4002127200 7200 0 EET} - {4015436400 10800 1 EEST} + {4014831600 10800 1 EEST} {4033576800 7200 0 EET} - {4046886000 10800 1 EEST} + {4046281200 10800 1 EEST} {4065026400 7200 0 EET} {4078335600 10800 1 EEST} {4097080800 7200 0 EET} diff --git a/library/tzdata/Asia/Hovd b/library/tzdata/Asia/Hovd index a9c995b..9b14d5b 100644 --- a/library/tzdata/Asia/Hovd +++ b/library/tzdata/Asia/Hovd @@ -4,52 +4,52 @@ set TZData(:Asia/Hovd) { {-9223372036854775808 21996 0 LMT} {-2032927596 21600 0 +06} {252439200 25200 0 +07} - {417978000 28800 1 +08} + {417978000 28800 1 +07} {433785600 25200 0 +07} - {449600400 28800 1 +08} + {449600400 28800 1 +07} {465321600 25200 0 +07} - {481050000 28800 1 +08} + {481050000 28800 1 +07} {496771200 25200 0 +07} - {512499600 28800 1 +08} + {512499600 28800 1 +07} {528220800 25200 0 +07} - {543949200 28800 1 +08} + {543949200 28800 1 +07} {559670400 25200 0 +07} - {575398800 28800 1 +08} + {575398800 28800 1 +07} {591120000 25200 0 +07} - {606848400 28800 1 +08} + {606848400 28800 1 +07} {622569600 25200 0 +07} - {638298000 28800 1 +08} + {638298000 28800 1 +07} {654624000 25200 0 +07} - {670352400 28800 1 +08} + {670352400 28800 1 +07} {686073600 25200 0 +07} - {701802000 28800 1 +08} + {701802000 28800 1 +07} {717523200 25200 0 +07} - {733251600 28800 1 +08} + {733251600 28800 1 +07} {748972800 25200 0 +07} - {764701200 28800 1 +08} + {764701200 28800 1 +07} {780422400 25200 0 +07} - {796150800 28800 1 +08} + {796150800 28800 1 +07} {811872000 25200 0 +07} - {828205200 28800 1 +08} + {828205200 28800 1 +07} {843926400 25200 0 +07} - {859654800 28800 1 +08} + {859654800 28800 1 +07} {875376000 25200 0 +07} - {891104400 28800 1 +08} + {891104400 28800 1 +07} {906825600 25200 0 +07} - {988398000 28800 1 +08} + {988398000 28800 1 +07} {1001700000 25200 0 +07} - {1017428400 28800 1 +08} + {1017428400 28800 1 +07} {1033149600 25200 0 +07} - {1048878000 28800 1 +08} + {1048878000 28800 1 +07} {1064599200 25200 0 +07} - {1080327600 28800 1 +08} + {1080327600 28800 1 +07} {1096048800 25200 0 +07} - {1111777200 28800 1 +08} + {1111777200 28800 1 +07} {1127498400 25200 0 +07} - {1143226800 28800 1 +08} + {1143226800 28800 1 +07} {1159552800 25200 0 +07} - {1427482800 28800 1 +08} + {1427482800 28800 1 +07} {1443196800 25200 0 +07} - {1458932400 28800 1 +08} + {1458932400 28800 1 +07} {1474646400 25200 0 +07} } diff --git a/library/tzdata/Asia/Kuching b/library/tzdata/Asia/Kuching index d6f5ad4..e5dc1b7 100644 --- a/library/tzdata/Asia/Kuching +++ b/library/tzdata/Asia/Kuching @@ -4,19 +4,19 @@ set TZData(:Asia/Kuching) { {-9223372036854775808 26480 0 LMT} {-1383463280 27000 0 +0730} {-1167636600 28800 0 +08} - {-1082448000 30000 1 +0820} + {-1082448000 30000 1 +08} {-1074586800 28800 0 +08} - {-1050825600 30000 1 +0820} + {-1050825600 30000 1 +08} {-1042964400 28800 0 +08} - {-1019289600 30000 1 +0820} + {-1019289600 30000 1 +08} {-1011428400 28800 0 +08} - {-987753600 30000 1 +0820} + {-987753600 30000 1 +08} {-979892400 28800 0 +08} - {-956217600 30000 1 +0820} + {-956217600 30000 1 +08} {-948356400 28800 0 +08} - {-924595200 30000 1 +0820} + {-924595200 30000 1 +08} {-916734000 28800 0 +08} - {-893059200 30000 1 +0820} + {-893059200 30000 1 +08} {-885198000 28800 0 +08} {-879667200 32400 0 +09} {-767005200 28800 0 +08} diff --git a/library/tzdata/Asia/Macau b/library/tzdata/Asia/Macau index 8458a8a..76a00aa 100644 --- a/library/tzdata/Asia/Macau +++ b/library/tzdata/Asia/Macau @@ -2,7 +2,7 @@ set TZData(:Asia/Macau) { {-9223372036854775808 27260 0 LMT} - {-1830411260 28800 0 CST} + {-1830412800 28800 0 CST} {-277360200 32400 1 CDT} {-257405400 28800 0 CST} {-245910600 32400 1 CDT} diff --git a/library/tzdata/Asia/Manila b/library/tzdata/Asia/Manila index 987919a..b7ffa7a 100644 --- a/library/tzdata/Asia/Manila +++ b/library/tzdata/Asia/Manila @@ -4,12 +4,12 @@ set TZData(:Asia/Manila) { {-9223372036854775808 -57360 0 LMT} {-3944621040 29040 0 LMT} {-2229321840 28800 0 +08} - {-1046678400 32400 1 +09} + {-1046678400 32400 1 +08} {-1038733200 28800 0 +08} {-873273600 32400 0 +09} {-794221200 28800 0 +08} - {-496224000 32400 1 +09} + {-496224000 32400 1 +08} {-489315600 28800 0 +08} - {259344000 32400 1 +09} + {259344000 32400 1 +08} {275151600 28800 0 +08} } diff --git a/library/tzdata/Asia/Oral b/library/tzdata/Asia/Oral index 624a59d..e781b60 100644 --- a/library/tzdata/Asia/Oral +++ b/library/tzdata/Asia/Oral @@ -7,52 +7,52 @@ set TZData(:Asia/Oral) { {354913200 21600 1 +06} {370720800 21600 0 +06} {386445600 18000 0 +05} - {386449200 21600 1 +06} + {386449200 21600 1 +05} {402256800 18000 0 +05} - {417985200 21600 1 +06} + {417985200 21600 1 +05} {433792800 18000 0 +05} - {449607600 21600 1 +06} + {449607600 21600 1 +05} {465339600 18000 0 +05} - {481064400 21600 1 +06} + {481064400 21600 1 +05} {496789200 18000 0 +05} - {512514000 21600 1 +06} + {512514000 21600 1 +05} {528238800 18000 0 +05} - {543963600 21600 1 +06} + {543963600 21600 1 +05} {559688400 18000 0 +05} - {575413200 21600 1 +06} + {575413200 21600 1 +05} {591138000 18000 0 +05} {606862800 14400 0 +04} - {606866400 18000 1 +05} + {606866400 18000 1 +04} {622591200 14400 0 +04} - {638316000 18000 1 +05} + {638316000 18000 1 +04} {654645600 14400 0 +04} - {670370400 18000 1 +05} + {670370400 18000 1 +04} {686095200 14400 0 +04} {701816400 14400 0 +04} - {701820000 18000 1 +05} + {701820000 18000 1 +04} {717544800 14400 0 +04} - {733269600 18000 1 +05} + {733269600 18000 1 +04} {748994400 14400 0 +04} - {764719200 18000 1 +05} + {764719200 18000 1 +04} {780444000 14400 0 +04} - {796168800 18000 1 +05} + {796168800 18000 1 +04} {811893600 14400 0 +04} - {828223200 18000 1 +05} + {828223200 18000 1 +04} {846367200 14400 0 +04} - {859672800 18000 1 +05} + {859672800 18000 1 +04} {877816800 14400 0 +04} - {891122400 18000 1 +05} + {891122400 18000 1 +04} {909266400 14400 0 +04} - {922572000 18000 1 +05} + {922572000 18000 1 +04} {941320800 14400 0 +04} - {954021600 18000 1 +05} + {954021600 18000 1 +04} {972770400 14400 0 +04} - {985471200 18000 1 +05} + {985471200 18000 1 +04} {1004220000 14400 0 +04} - {1017525600 18000 1 +05} + {1017525600 18000 1 +04} {1035669600 14400 0 +04} - {1048975200 18000 1 +05} + {1048975200 18000 1 +04} {1067119200 14400 0 +04} - {1080424800 18000 1 +05} + {1080424800 18000 1 +04} {1099173600 18000 0 +05} } diff --git a/library/tzdata/Asia/Pyongyang b/library/tzdata/Asia/Pyongyang index 72e7f23..5746472 100644 --- a/library/tzdata/Asia/Pyongyang +++ b/library/tzdata/Asia/Pyongyang @@ -6,4 +6,5 @@ set TZData(:Asia/Pyongyang) { {-1830414600 32400 0 JST} {-768646800 32400 0 KST} {1439564400 30600 0 KST} + {1525447800 32400 0 KST} } diff --git a/library/tzdata/Asia/Qyzylorda b/library/tzdata/Asia/Qyzylorda index b2e9472..7c6df32 100644 --- a/library/tzdata/Asia/Qyzylorda +++ b/library/tzdata/Asia/Qyzylorda @@ -7,51 +7,51 @@ set TZData(:Asia/Qyzylorda) { {354913200 21600 1 +06} {370720800 21600 0 +06} {386445600 18000 0 +05} - {386449200 21600 1 +06} + {386449200 21600 1 +05} {402256800 18000 0 +05} - {417985200 21600 1 +06} + {417985200 21600 1 +05} {433792800 18000 0 +05} - {449607600 21600 1 +06} + {449607600 21600 1 +05} {465339600 18000 0 +05} - {481064400 21600 1 +06} + {481064400 21600 1 +05} {496789200 18000 0 +05} - {512514000 21600 1 +06} + {512514000 21600 1 +05} {528238800 18000 0 +05} - {543963600 21600 1 +06} + {543963600 21600 1 +05} {559688400 18000 0 +05} - {575413200 21600 1 +06} + {575413200 21600 1 +05} {591138000 18000 0 +05} - {606862800 21600 1 +06} + {606862800 21600 1 +05} {622587600 18000 0 +05} - {638312400 21600 1 +06} + {638312400 21600 1 +05} {654642000 18000 0 +05} {670366800 14400 0 +04} - {670370400 18000 1 +05} + {670370400 18000 1 +04} {701812800 18000 0 +05} - {701816400 21600 1 +06} + {701816400 21600 1 +05} {717541200 18000 0 +05} - {733266000 21600 1 +06} + {733266000 21600 1 +05} {748990800 18000 0 +05} - {764715600 21600 1 +06} + {764715600 21600 1 +05} {780440400 18000 0 +05} - {796165200 21600 1 +06} + {796165200 21600 1 +05} {811890000 18000 0 +05} - {828219600 21600 1 +06} + {828219600 21600 1 +05} {846363600 18000 0 +05} - {859669200 21600 1 +06} + {859669200 21600 1 +05} {877813200 18000 0 +05} - {891118800 21600 1 +06} + {891118800 21600 1 +05} {909262800 18000 0 +05} - {922568400 21600 1 +06} + {922568400 21600 1 +05} {941317200 18000 0 +05} - {954018000 21600 1 +06} + {954018000 21600 1 +05} {972766800 18000 0 +05} - {985467600 21600 1 +06} + {985467600 21600 1 +05} {1004216400 18000 0 +05} - {1017522000 21600 1 +06} + {1017522000 21600 1 +05} {1035666000 18000 0 +05} - {1048971600 21600 1 +06} + {1048971600 21600 1 +05} {1067115600 18000 0 +05} - {1080421200 21600 1 +06} + {1080421200 21600 1 +05} {1099170000 21600 0 +06} } diff --git a/library/tzdata/Asia/Samarkand b/library/tzdata/Asia/Samarkand index 43ad774..805bab7 100644 --- a/library/tzdata/Asia/Samarkand +++ b/library/tzdata/Asia/Samarkand @@ -7,25 +7,25 @@ set TZData(:Asia/Samarkand) { {354913200 21600 1 +06} {370720800 21600 0 +06} {386445600 18000 0 +05} - {386449200 21600 1 +06} + {386449200 21600 1 +05} {402256800 18000 0 +05} - {417985200 21600 1 +06} + {417985200 21600 1 +05} {433792800 18000 0 +05} - {449607600 21600 1 +06} + {449607600 21600 1 +05} {465339600 18000 0 +05} - {481064400 21600 1 +06} + {481064400 21600 1 +05} {496789200 18000 0 +05} - {512514000 21600 1 +06} + {512514000 21600 1 +05} {528238800 18000 0 +05} - {543963600 21600 1 +06} + {543963600 21600 1 +05} {559688400 18000 0 +05} - {575413200 21600 1 +06} + {575413200 21600 1 +05} {591138000 18000 0 +05} - {606862800 21600 1 +06} + {606862800 21600 1 +05} {622587600 18000 0 +05} - {638312400 21600 1 +06} + {638312400 21600 1 +05} {654642000 18000 0 +05} - {670366800 21600 1 +06} + {670366800 21600 1 +05} {686091600 18000 0 +05} {694206000 18000 0 +05} } diff --git a/library/tzdata/Asia/Tashkent b/library/tzdata/Asia/Tashkent index 7b6abe4..bd16c91 100644 --- a/library/tzdata/Asia/Tashkent +++ b/library/tzdata/Asia/Tashkent @@ -4,28 +4,28 @@ set TZData(:Asia/Tashkent) { {-9223372036854775808 16631 0 LMT} {-1441168631 18000 0 +05} {-1247547600 21600 0 +06} - {354909600 25200 1 +07} + {354909600 25200 1 +06} {370717200 21600 0 +06} - {386445600 25200 1 +07} + {386445600 25200 1 +06} {402253200 21600 0 +06} - {417981600 25200 1 +07} + {417981600 25200 1 +06} {433789200 21600 0 +06} - {449604000 25200 1 +07} + {449604000 25200 1 +06} {465336000 21600 0 +06} - {481060800 25200 1 +07} + {481060800 25200 1 +06} {496785600 21600 0 +06} - {512510400 25200 1 +07} + {512510400 25200 1 +06} {528235200 21600 0 +06} - {543960000 25200 1 +07} + {543960000 25200 1 +06} {559684800 21600 0 +06} - {575409600 25200 1 +07} + {575409600 25200 1 +06} {591134400 21600 0 +06} - {606859200 25200 1 +07} + {606859200 25200 1 +06} {622584000 21600 0 +06} - {638308800 25200 1 +07} + {638308800 25200 1 +06} {654638400 21600 0 +06} {670363200 18000 0 +05} - {670366800 21600 1 +06} + {670366800 21600 1 +05} {686091600 18000 0 +05} {694206000 18000 0 +05} } diff --git a/library/tzdata/Asia/Tbilisi b/library/tzdata/Asia/Tbilisi index 60d253c..71e7695 100644 --- a/library/tzdata/Asia/Tbilisi +++ b/library/tzdata/Asia/Tbilisi @@ -5,56 +5,56 @@ set TZData(:Asia/Tbilisi) { {-2840151551 10751 0 TBMT} {-1441162751 10800 0 +03} {-405140400 14400 0 +04} - {354916800 18000 1 +05} + {354916800 18000 1 +04} {370724400 14400 0 +04} - {386452800 18000 1 +05} + {386452800 18000 1 +04} {402260400 14400 0 +04} - {417988800 18000 1 +05} + {417988800 18000 1 +04} {433796400 14400 0 +04} - {449611200 18000 1 +05} + {449611200 18000 1 +04} {465343200 14400 0 +04} - {481068000 18000 1 +05} + {481068000 18000 1 +04} {496792800 14400 0 +04} - {512517600 18000 1 +05} + {512517600 18000 1 +04} {528242400 14400 0 +04} - {543967200 18000 1 +05} + {543967200 18000 1 +04} {559692000 14400 0 +04} - {575416800 18000 1 +05} + {575416800 18000 1 +04} {591141600 14400 0 +04} - {606866400 18000 1 +05} + {606866400 18000 1 +04} {622591200 14400 0 +04} - {638316000 18000 1 +05} + {638316000 18000 1 +04} {654645600 14400 0 +04} {670370400 10800 0 +03} - {670374000 14400 1 +04} + {670374000 14400 1 +03} {686098800 10800 0 +03} {694213200 10800 0 +03} - {701816400 14400 1 +04} + {701816400 14400 1 +03} {717537600 10800 0 +03} - {733266000 14400 1 +04} + {733266000 14400 1 +03} {748987200 10800 0 +03} - {764715600 14400 1 +04} + {764715600 14400 1 +03} {780440400 14400 0 +04} - {796161600 18000 1 +05} + {796161600 18000 1 +04} {811882800 14400 0 +04} - {828216000 18000 1 +05} + {828216000 18000 1 +04} {846360000 18000 1 +05} - {859662000 18000 0 +05} + {859662000 18000 0 +04} {877806000 14400 0 +04} - {891115200 18000 1 +05} + {891115200 18000 1 +04} {909255600 14400 0 +04} - {922564800 18000 1 +05} + {922564800 18000 1 +04} {941310000 14400 0 +04} - {954014400 18000 1 +05} + {954014400 18000 1 +04} {972759600 14400 0 +04} - {985464000 18000 1 +05} + {985464000 18000 1 +04} {1004209200 14400 0 +04} - {1017518400 18000 1 +05} + {1017518400 18000 1 +04} {1035658800 14400 0 +04} - {1048968000 18000 1 +05} + {1048968000 18000 1 +04} {1067108400 14400 0 +04} - {1080417600 18000 1 +05} - {1088280000 14400 0 +04} + {1080417600 18000 1 +04} + {1088280000 14400 0 +03} {1099177200 10800 0 +03} {1111878000 14400 0 +04} } diff --git a/library/tzdata/Asia/Tehran b/library/tzdata/Asia/Tehran index a8912ce..3d44e42 100644 --- a/library/tzdata/Asia/Tehran +++ b/library/tzdata/Asia/Tehran @@ -4,226 +4,226 @@ set TZData(:Asia/Tehran) { {-9223372036854775808 12344 0 LMT} {-1704165944 12344 0 TMT} {-757394744 12600 0 +0330} - {247177800 14400 0 +05} - {259272000 18000 1 +05} - {277758000 14400 0 +05} - {283982400 12600 0 +0430} - {290809800 16200 1 +0430} - {306531000 12600 0 +0430} - {322432200 16200 1 +0430} - {338499000 12600 0 +0430} - {673216200 16200 1 +0430} - {685481400 12600 0 +0430} - {701209800 16200 1 +0430} - {717103800 12600 0 +0430} - {732745800 16200 1 +0430} - {748639800 12600 0 +0430} - {764281800 16200 1 +0430} - {780175800 12600 0 +0430} - {795817800 16200 1 +0430} - {811711800 12600 0 +0430} - {827353800 16200 1 +0430} - {843247800 12600 0 +0430} - {858976200 16200 1 +0430} - {874870200 12600 0 +0430} - {890512200 16200 1 +0430} - {906406200 12600 0 +0430} - {922048200 16200 1 +0430} - {937942200 12600 0 +0430} - {953584200 16200 1 +0430} - {969478200 12600 0 +0430} - {985206600 16200 1 +0430} - {1001100600 12600 0 +0430} - {1016742600 16200 1 +0430} - {1032636600 12600 0 +0430} - {1048278600 16200 1 +0430} - {1064172600 12600 0 +0430} - {1079814600 16200 1 +0430} - {1095708600 12600 0 +0430} - {1111437000 16200 1 +0430} - {1127331000 12600 0 +0430} - {1206045000 16200 1 +0430} - {1221939000 12600 0 +0430} - {1237667400 16200 1 +0430} - {1253561400 12600 0 +0430} - {1269203400 16200 1 +0430} - {1285097400 12600 0 +0430} - {1300739400 16200 1 +0430} - {1316633400 12600 0 +0430} - {1332275400 16200 1 +0430} - {1348169400 12600 0 +0430} - {1363897800 16200 1 +0430} - {1379791800 12600 0 +0430} - {1395433800 16200 1 +0430} - {1411327800 12600 0 +0430} - {1426969800 16200 1 +0430} - {1442863800 12600 0 +0430} - {1458505800 16200 1 +0430} - {1474399800 12600 0 +0430} - {1490128200 16200 1 +0430} - {1506022200 12600 0 +0430} - {1521664200 16200 1 +0430} - {1537558200 12600 0 +0430} - {1553200200 16200 1 +0430} - {1569094200 12600 0 +0430} - {1584736200 16200 1 +0430} - {1600630200 12600 0 +0430} - {1616358600 16200 1 +0430} - {1632252600 12600 0 +0430} - {1647894600 16200 1 +0430} - {1663788600 12600 0 +0430} - {1679430600 16200 1 +0430} - {1695324600 12600 0 +0430} - {1710966600 16200 1 +0430} - {1726860600 12600 0 +0430} - {1742589000 16200 1 +0430} - {1758483000 12600 0 +0430} - {1774125000 16200 1 +0430} - {1790019000 12600 0 +0430} - {1805661000 16200 1 +0430} - {1821555000 12600 0 +0430} - {1837197000 16200 1 +0430} - {1853091000 12600 0 +0430} - {1868733000 16200 1 +0430} - {1884627000 12600 0 +0430} - {1900355400 16200 1 +0430} - {1916249400 12600 0 +0430} - {1931891400 16200 1 +0430} - {1947785400 12600 0 +0430} - {1963427400 16200 1 +0430} - {1979321400 12600 0 +0430} - {1994963400 16200 1 +0430} - {2010857400 12600 0 +0430} - {2026585800 16200 1 +0430} - {2042479800 12600 0 +0430} - {2058121800 16200 1 +0430} - {2074015800 12600 0 +0430} - {2089657800 16200 1 +0430} - {2105551800 12600 0 +0430} - {2121193800 16200 1 +0430} - {2137087800 12600 0 +0430} - {2152729800 16200 1 +0430} - {2168623800 12600 0 +0430} - {2184265800 16200 1 +0430} - {2200159800 12600 0 +0430} - {2215888200 16200 1 +0430} - {2231782200 12600 0 +0430} - {2247424200 16200 1 +0430} - {2263318200 12600 0 +0430} - {2278960200 16200 1 +0430} - {2294854200 12600 0 +0430} - {2310496200 16200 1 +0430} - {2326390200 12600 0 +0430} - {2342118600 16200 1 +0430} - {2358012600 12600 0 +0430} - {2373654600 16200 1 +0430} - {2389548600 12600 0 +0430} - {2405190600 16200 1 +0430} - {2421084600 12600 0 +0430} - {2436726600 16200 1 +0430} - {2452620600 12600 0 +0430} - {2468349000 16200 1 +0430} - {2484243000 12600 0 +0430} - {2499885000 16200 1 +0430} - {2515779000 12600 0 +0430} - {2531421000 16200 1 +0430} - {2547315000 12600 0 +0430} - {2562957000 16200 1 +0430} - {2578851000 12600 0 +0430} - {2594579400 16200 1 +0430} - {2610473400 12600 0 +0430} - {2626115400 16200 1 +0430} - {2642009400 12600 0 +0430} - {2657651400 16200 1 +0430} - {2673545400 12600 0 +0430} - {2689187400 16200 1 +0430} - {2705081400 12600 0 +0430} - {2720809800 16200 1 +0430} - {2736703800 12600 0 +0430} - {2752345800 16200 1 +0430} - {2768239800 12600 0 +0430} - {2783881800 16200 1 +0430} - {2799775800 12600 0 +0430} - {2815417800 16200 1 +0430} - {2831311800 12600 0 +0430} - {2847040200 16200 1 +0430} - {2862934200 12600 0 +0430} - {2878576200 16200 1 +0430} - {2894470200 12600 0 +0430} - {2910112200 16200 1 +0430} - {2926006200 12600 0 +0430} - {2941648200 16200 1 +0430} - {2957542200 12600 0 +0430} - {2973270600 16200 1 +0430} - {2989164600 12600 0 +0430} - {3004806600 16200 1 +0430} - {3020700600 12600 0 +0430} - {3036342600 16200 1 +0430} - {3052236600 12600 0 +0430} - {3067878600 16200 1 +0430} - {3083772600 12600 0 +0430} - {3099501000 16200 1 +0430} - {3115395000 12600 0 +0430} - {3131037000 16200 1 +0430} - {3146931000 12600 0 +0430} - {3162573000 16200 1 +0430} - {3178467000 12600 0 +0430} - {3194109000 16200 1 +0430} - {3210003000 12600 0 +0430} - {3225731400 16200 1 +0430} - {3241625400 12600 0 +0430} - {3257267400 16200 1 +0430} - {3273161400 12600 0 +0430} - {3288803400 16200 1 +0430} - {3304697400 12600 0 +0430} - {3320339400 16200 1 +0430} - {3336233400 12600 0 +0430} - {3351961800 16200 1 +0430} - {3367855800 12600 0 +0430} - {3383497800 16200 1 +0430} - {3399391800 12600 0 +0430} - {3415033800 16200 1 +0430} - {3430927800 12600 0 +0430} - {3446569800 16200 1 +0430} - {3462463800 12600 0 +0430} - {3478192200 16200 1 +0430} - {3494086200 12600 0 +0430} - {3509728200 16200 1 +0430} - {3525622200 12600 0 +0430} - {3541264200 16200 1 +0430} - {3557158200 12600 0 +0430} - {3572800200 16200 1 +0430} - {3588694200 12600 0 +0430} - {3604422600 16200 1 +0430} - {3620316600 12600 0 +0430} - {3635958600 16200 1 +0430} - {3651852600 12600 0 +0430} - {3667494600 16200 1 +0430} - {3683388600 12600 0 +0430} - {3699030600 16200 1 +0430} - {3714924600 12600 0 +0430} - {3730653000 16200 1 +0430} - {3746547000 12600 0 +0430} - {3762189000 16200 1 +0430} - {3778083000 12600 0 +0430} - {3793725000 16200 1 +0430} - {3809619000 12600 0 +0430} - {3825261000 16200 1 +0430} - {3841155000 12600 0 +0430} - {3856883400 16200 1 +0430} - {3872777400 12600 0 +0430} - {3888419400 16200 1 +0430} - {3904313400 12600 0 +0430} - {3919955400 16200 1 +0430} - {3935849400 12600 0 +0430} - {3951491400 16200 1 +0430} - {3967385400 12600 0 +0430} - {3983113800 16200 1 +0430} - {3999007800 12600 0 +0430} - {4014649800 16200 1 +0430} - {4030543800 12600 0 +0430} - {4046185800 16200 1 +0430} - {4062079800 12600 0 +0430} - {4077721800 16200 1 +0430} - {4093615800 12600 0 +0430} + {247177800 14400 0 +04} + {259272000 18000 1 +04} + {277758000 14400 0 +04} + {283982400 12600 0 +0330} + {290809800 16200 1 +0330} + {306531000 12600 0 +0330} + {322432200 16200 1 +0330} + {338499000 12600 0 +0330} + {673216200 16200 1 +0330} + {685481400 12600 0 +0330} + {701209800 16200 1 +0330} + {717103800 12600 0 +0330} + {732745800 16200 1 +0330} + {748639800 12600 0 +0330} + {764281800 16200 1 +0330} + {780175800 12600 0 +0330} + {795817800 16200 1 +0330} + {811711800 12600 0 +0330} + {827353800 16200 1 +0330} + {843247800 12600 0 +0330} + {858976200 16200 1 +0330} + {874870200 12600 0 +0330} + {890512200 16200 1 +0330} + {906406200 12600 0 +0330} + {922048200 16200 1 +0330} + {937942200 12600 0 +0330} + {953584200 16200 1 +0330} + {969478200 12600 0 +0330} + {985206600 16200 1 +0330} + {1001100600 12600 0 +0330} + {1016742600 16200 1 +0330} + {1032636600 12600 0 +0330} + {1048278600 16200 1 +0330} + {1064172600 12600 0 +0330} + {1079814600 16200 1 +0330} + {1095708600 12600 0 +0330} + {1111437000 16200 1 +0330} + {1127331000 12600 0 +0330} + {1206045000 16200 1 +0330} + {1221939000 12600 0 +0330} + {1237667400 16200 1 +0330} + {1253561400 12600 0 +0330} + {1269203400 16200 1 +0330} + {1285097400 12600 0 +0330} + {1300739400 16200 1 +0330} + {1316633400 12600 0 +0330} + {1332275400 16200 1 +0330} + {1348169400 12600 0 +0330} + {1363897800 16200 1 +0330} + {1379791800 12600 0 +0330} + {1395433800 16200 1 +0330} + {1411327800 12600 0 +0330} + {1426969800 16200 1 +0330} + {1442863800 12600 0 +0330} + {1458505800 16200 1 +0330} + {1474399800 12600 0 +0330} + {1490128200 16200 1 +0330} + {1506022200 12600 0 +0330} + {1521664200 16200 1 +0330} + {1537558200 12600 0 +0330} + {1553200200 16200 1 +0330} + {1569094200 12600 0 +0330} + {1584736200 16200 1 +0330} + {1600630200 12600 0 +0330} + {1616358600 16200 1 +0330} + {1632252600 12600 0 +0330} + {1647894600 16200 1 +0330} + {1663788600 12600 0 +0330} + {1679430600 16200 1 +0330} + {1695324600 12600 0 +0330} + {1710966600 16200 1 +0330} + {1726860600 12600 0 +0330} + {1742589000 16200 1 +0330} + {1758483000 12600 0 +0330} + {1774125000 16200 1 +0330} + {1790019000 12600 0 +0330} + {1805661000 16200 1 +0330} + {1821555000 12600 0 +0330} + {1837197000 16200 1 +0330} + {1853091000 12600 0 +0330} + {1868733000 16200 1 +0330} + {1884627000 12600 0 +0330} + {1900355400 16200 1 +0330} + {1916249400 12600 0 +0330} + {1931891400 16200 1 +0330} + {1947785400 12600 0 +0330} + {1963427400 16200 1 +0330} + {1979321400 12600 0 +0330} + {1994963400 16200 1 +0330} + {2010857400 12600 0 +0330} + {2026585800 16200 1 +0330} + {2042479800 12600 0 +0330} + {2058121800 16200 1 +0330} + {2074015800 12600 0 +0330} + {2089657800 16200 1 +0330} + {2105551800 12600 0 +0330} + {2121193800 16200 1 +0330} + {2137087800 12600 0 +0330} + {2152729800 16200 1 +0330} + {2168623800 12600 0 +0330} + {2184265800 16200 1 +0330} + {2200159800 12600 0 +0330} + {2215888200 16200 1 +0330} + {2231782200 12600 0 +0330} + {2247424200 16200 1 +0330} + {2263318200 12600 0 +0330} + {2278960200 16200 1 +0330} + {2294854200 12600 0 +0330} + {2310496200 16200 1 +0330} + {2326390200 12600 0 +0330} + {2342118600 16200 1 +0330} + {2358012600 12600 0 +0330} + {2373654600 16200 1 +0330} + {2389548600 12600 0 +0330} + {2405190600 16200 1 +0330} + {2421084600 12600 0 +0330} + {2436726600 16200 1 +0330} + {2452620600 12600 0 +0330} + {2468349000 16200 1 +0330} + {2484243000 12600 0 +0330} + {2499885000 16200 1 +0330} + {2515779000 12600 0 +0330} + {2531421000 16200 1 +0330} + {2547315000 12600 0 +0330} + {2562957000 16200 1 +0330} + {2578851000 12600 0 +0330} + {2594579400 16200 1 +0330} + {2610473400 12600 0 +0330} + {2626115400 16200 1 +0330} + {2642009400 12600 0 +0330} + {2657651400 16200 1 +0330} + {2673545400 12600 0 +0330} + {2689187400 16200 1 +0330} + {2705081400 12600 0 +0330} + {2720809800 16200 1 +0330} + {2736703800 12600 0 +0330} + {2752345800 16200 1 +0330} + {2768239800 12600 0 +0330} + {2783881800 16200 1 +0330} + {2799775800 12600 0 +0330} + {2815417800 16200 1 +0330} + {2831311800 12600 0 +0330} + {2847040200 16200 1 +0330} + {2862934200 12600 0 +0330} + {2878576200 16200 1 +0330} + {2894470200 12600 0 +0330} + {2910112200 16200 1 +0330} + {2926006200 12600 0 +0330} + {2941648200 16200 1 +0330} + {2957542200 12600 0 +0330} + {2973270600 16200 1 +0330} + {2989164600 12600 0 +0330} + {3004806600 16200 1 +0330} + {3020700600 12600 0 +0330} + {3036342600 16200 1 +0330} + {3052236600 12600 0 +0330} + {3067878600 16200 1 +0330} + {3083772600 12600 0 +0330} + {3099501000 16200 1 +0330} + {3115395000 12600 0 +0330} + {3131037000 16200 1 +0330} + {3146931000 12600 0 +0330} + {3162573000 16200 1 +0330} + {3178467000 12600 0 +0330} + {3194109000 16200 1 +0330} + {3210003000 12600 0 +0330} + {3225731400 16200 1 +0330} + {3241625400 12600 0 +0330} + {3257267400 16200 1 +0330} + {3273161400 12600 0 +0330} + {3288803400 16200 1 +0330} + {3304697400 12600 0 +0330} + {3320339400 16200 1 +0330} + {3336233400 12600 0 +0330} + {3351961800 16200 1 +0330} + {3367855800 12600 0 +0330} + {3383497800 16200 1 +0330} + {3399391800 12600 0 +0330} + {3415033800 16200 1 +0330} + {3430927800 12600 0 +0330} + {3446569800 16200 1 +0330} + {3462463800 12600 0 +0330} + {3478192200 16200 1 +0330} + {3494086200 12600 0 +0330} + {3509728200 16200 1 +0330} + {3525622200 12600 0 +0330} + {3541264200 16200 1 +0330} + {3557158200 12600 0 +0330} + {3572800200 16200 1 +0330} + {3588694200 12600 0 +0330} + {3604422600 16200 1 +0330} + {3620316600 12600 0 +0330} + {3635958600 16200 1 +0330} + {3651852600 12600 0 +0330} + {3667494600 16200 1 +0330} + {3683388600 12600 0 +0330} + {3699030600 16200 1 +0330} + {3714924600 12600 0 +0330} + {3730653000 16200 1 +0330} + {3746547000 12600 0 +0330} + {3762189000 16200 1 +0330} + {3778083000 12600 0 +0330} + {3793725000 16200 1 +0330} + {3809619000 12600 0 +0330} + {3825261000 16200 1 +0330} + {3841155000 12600 0 +0330} + {3856883400 16200 1 +0330} + {3872777400 12600 0 +0330} + {3888419400 16200 1 +0330} + {3904313400 12600 0 +0330} + {3919955400 16200 1 +0330} + {3935849400 12600 0 +0330} + {3951491400 16200 1 +0330} + {3967385400 12600 0 +0330} + {3983113800 16200 1 +0330} + {3999007800 12600 0 +0330} + {4014649800 16200 1 +0330} + {4030543800 12600 0 +0330} + {4046185800 16200 1 +0330} + {4062079800 12600 0 +0330} + {4077721800 16200 1 +0330} + {4093615800 12600 0 +0330} } diff --git a/library/tzdata/Asia/Tokyo b/library/tzdata/Asia/Tokyo index 10add1c..790df0a 100644 --- a/library/tzdata/Asia/Tokyo +++ b/library/tzdata/Asia/Tokyo @@ -3,12 +3,12 @@ set TZData(:Asia/Tokyo) { {-9223372036854775808 33539 0 LMT} {-2587712400 32400 0 JST} - {-683794800 36000 1 JDT} - {-672393600 32400 0 JST} - {-654764400 36000 1 JDT} - {-640944000 32400 0 JST} - {-620290800 36000 1 JDT} - {-609494400 32400 0 JST} - {-588841200 36000 1 JDT} - {-578044800 32400 0 JST} + {-683802000 36000 1 JDT} + {-672314400 32400 0 JST} + {-654771600 36000 1 JDT} + {-640864800 32400 0 JST} + {-620298000 36000 1 JDT} + {-609415200 32400 0 JST} + {-588848400 36000 1 JDT} + {-577965600 32400 0 JST} } diff --git a/library/tzdata/Asia/Ulaanbaatar b/library/tzdata/Asia/Ulaanbaatar index e0ba7ab..3a33ef9 100644 --- a/library/tzdata/Asia/Ulaanbaatar +++ b/library/tzdata/Asia/Ulaanbaatar @@ -4,52 +4,52 @@ set TZData(:Asia/Ulaanbaatar) { {-9223372036854775808 25652 0 LMT} {-2032931252 25200 0 +07} {252435600 28800 0 +08} - {417974400 32400 1 +09} + {417974400 32400 1 +08} {433782000 28800 0 +08} - {449596800 32400 1 +09} + {449596800 32400 1 +08} {465318000 28800 0 +08} - {481046400 32400 1 +09} + {481046400 32400 1 +08} {496767600 28800 0 +08} - {512496000 32400 1 +09} + {512496000 32400 1 +08} {528217200 28800 0 +08} - {543945600 32400 1 +09} + {543945600 32400 1 +08} {559666800 28800 0 +08} - {575395200 32400 1 +09} + {575395200 32400 1 +08} {591116400 28800 0 +08} - {606844800 32400 1 +09} + {606844800 32400 1 +08} {622566000 28800 0 +08} - {638294400 32400 1 +09} + {638294400 32400 1 +08} {654620400 28800 0 +08} - {670348800 32400 1 +09} + {670348800 32400 1 +08} {686070000 28800 0 +08} - {701798400 32400 1 +09} + {701798400 32400 1 +08} {717519600 28800 0 +08} - {733248000 32400 1 +09} + {733248000 32400 1 +08} {748969200 28800 0 +08} - {764697600 32400 1 +09} + {764697600 32400 1 +08} {780418800 28800 0 +08} - {796147200 32400 1 +09} + {796147200 32400 1 +08} {811868400 28800 0 +08} - {828201600 32400 1 +09} + {828201600 32400 1 +08} {843922800 28800 0 +08} - {859651200 32400 1 +09} + {859651200 32400 1 +08} {875372400 28800 0 +08} - {891100800 32400 1 +09} + {891100800 32400 1 +08} {906822000 28800 0 +08} - {988394400 32400 1 +09} + {988394400 32400 1 +08} {1001696400 28800 0 +08} - {1017424800 32400 1 +09} + {1017424800 32400 1 +08} {1033146000 28800 0 +08} - {1048874400 32400 1 +09} + {1048874400 32400 1 +08} {1064595600 28800 0 +08} - {1080324000 32400 1 +09} + {1080324000 32400 1 +08} {1096045200 28800 0 +08} - {1111773600 32400 1 +09} + {1111773600 32400 1 +08} {1127494800 28800 0 +08} - {1143223200 32400 1 +09} + {1143223200 32400 1 +08} {1159549200 28800 0 +08} - {1427479200 32400 1 +09} + {1427479200 32400 1 +08} {1443193200 28800 0 +08} - {1458928800 32400 1 +09} + {1458928800 32400 1 +08} {1474642800 28800 0 +08} } diff --git a/library/tzdata/Asia/Yerevan b/library/tzdata/Asia/Yerevan index 25a349a..463bed0 100644 --- a/library/tzdata/Asia/Yerevan +++ b/library/tzdata/Asia/Yerevan @@ -4,67 +4,67 @@ set TZData(:Asia/Yerevan) { {-9223372036854775808 10680 0 LMT} {-1441162680 10800 0 +03} {-405140400 14400 0 +04} - {354916800 18000 1 +05} + {354916800 18000 1 +04} {370724400 14400 0 +04} - {386452800 18000 1 +05} + {386452800 18000 1 +04} {402260400 14400 0 +04} - {417988800 18000 1 +05} + {417988800 18000 1 +04} {433796400 14400 0 +04} - {449611200 18000 1 +05} + {449611200 18000 1 +04} {465343200 14400 0 +04} - {481068000 18000 1 +05} + {481068000 18000 1 +04} {496792800 14400 0 +04} - {512517600 18000 1 +05} + {512517600 18000 1 +04} {528242400 14400 0 +04} - {543967200 18000 1 +05} + {543967200 18000 1 +04} {559692000 14400 0 +04} - {575416800 18000 1 +05} + {575416800 18000 1 +04} {591141600 14400 0 +04} - {606866400 18000 1 +05} + {606866400 18000 1 +04} {622591200 14400 0 +04} - {638316000 18000 1 +05} + {638316000 18000 1 +04} {654645600 14400 0 +04} {670370400 10800 0 +03} - {670374000 14400 1 +04} + {670374000 14400 1 +03} {686098800 10800 0 +03} - {701823600 14400 1 +04} + {701823600 14400 1 +03} {717548400 10800 0 +03} - {733273200 14400 1 +04} + {733273200 14400 1 +03} {748998000 10800 0 +03} - {764722800 14400 1 +04} + {764722800 14400 1 +03} {780447600 10800 0 +03} - {796172400 14400 1 +04} + {796172400 14400 1 +03} {811897200 14400 0 +04} {852062400 14400 0 +04} - {859672800 18000 1 +05} + {859672800 18000 1 +04} {877816800 14400 0 +04} - {891122400 18000 1 +05} + {891122400 18000 1 +04} {909266400 14400 0 +04} - {922572000 18000 1 +05} + {922572000 18000 1 +04} {941320800 14400 0 +04} - {954021600 18000 1 +05} + {954021600 18000 1 +04} {972770400 14400 0 +04} - {985471200 18000 1 +05} + {985471200 18000 1 +04} {1004220000 14400 0 +04} - {1017525600 18000 1 +05} + {1017525600 18000 1 +04} {1035669600 14400 0 +04} - {1048975200 18000 1 +05} + {1048975200 18000 1 +04} {1067119200 14400 0 +04} - {1080424800 18000 1 +05} + {1080424800 18000 1 +04} {1099173600 14400 0 +04} - {1111874400 18000 1 +05} + {1111874400 18000 1 +04} {1130623200 14400 0 +04} - {1143324000 18000 1 +05} + {1143324000 18000 1 +04} {1162072800 14400 0 +04} - {1174773600 18000 1 +05} + {1174773600 18000 1 +04} {1193522400 14400 0 +04} - {1206828000 18000 1 +05} + {1206828000 18000 1 +04} {1224972000 14400 0 +04} - {1238277600 18000 1 +05} + {1238277600 18000 1 +04} {1256421600 14400 0 +04} - {1269727200 18000 1 +05} + {1269727200 18000 1 +04} {1288476000 14400 0 +04} {1293825600 14400 0 +04} - {1301176800 18000 1 +05} + {1301176800 18000 1 +04} {1319925600 14400 0 +04} } diff --git a/library/tzdata/Atlantic/Azores b/library/tzdata/Atlantic/Azores index a9bec94..088dd9a 100644 --- a/library/tzdata/Atlantic/Azores +++ b/library/tzdata/Atlantic/Azores @@ -3,7 +3,7 @@ set TZData(:Atlantic/Azores) { {-9223372036854775808 -6160 0 LMT} {-2713904240 -6872 0 HMT} - {-1830377128 -7200 0 -02} + {-1830376800 -7200 0 -02} {-1689548400 -3600 1 -01} {-1677794400 -7200 0 -02} {-1667430000 -3600 1 -01} diff --git a/library/tzdata/Atlantic/Cape_Verde b/library/tzdata/Atlantic/Cape_Verde index 6fc94eb..595db0b 100644 --- a/library/tzdata/Atlantic/Cape_Verde +++ b/library/tzdata/Atlantic/Cape_Verde @@ -2,7 +2,7 @@ set TZData(:Atlantic/Cape_Verde) { {-9223372036854775808 -5644 0 LMT} - {-1988144756 -7200 0 -02} + {-1830376800 -7200 0 -02} {-862610400 -3600 1 -01} {-764118000 -7200 0 -02} {186120000 -3600 0 -01} diff --git a/library/tzdata/Atlantic/Madeira b/library/tzdata/Atlantic/Madeira index cc5e5f8..fed9c19 100644 --- a/library/tzdata/Atlantic/Madeira +++ b/library/tzdata/Atlantic/Madeira @@ -3,7 +3,7 @@ set TZData(:Atlantic/Madeira) { {-9223372036854775808 -4056 0 LMT} {-2713906344 -4056 0 FMT} - {-1830379944 -3600 0 -01} + {-1830380400 -3600 0 -01} {-1689552000 0 1 +00} {-1677798000 -3600 0 -01} {-1667433600 0 1 +00} diff --git a/library/tzdata/Atlantic/Reykjavik b/library/tzdata/Atlantic/Reykjavik index 5555460..6270572 100644 --- a/library/tzdata/Atlantic/Reykjavik +++ b/library/tzdata/Atlantic/Reykjavik @@ -3,71 +3,71 @@ set TZData(:Atlantic/Reykjavik) { {-9223372036854775808 -5280 0 LMT} {-1956609120 -3600 0 -01} - {-1668211200 0 1 +00} + {-1668211200 0 1 -01} {-1647212400 -3600 0 -01} - {-1636675200 0 1 +00} + {-1636675200 0 1 -01} {-1613430000 -3600 0 -01} - {-1605139200 0 1 +00} + {-1605139200 0 1 -01} {-1581894000 -3600 0 -01} - {-1539561600 0 1 +00} + {-1539561600 0 1 -01} {-1531350000 -3600 0 -01} - {-968025600 0 1 +00} + {-968025600 0 1 -01} {-952293600 -3600 0 -01} - {-942008400 0 1 +00} + {-942008400 0 1 -01} {-920239200 -3600 0 -01} - {-909957600 0 1 +00} + {-909957600 0 1 -01} {-888789600 -3600 0 -01} - {-877903200 0 1 +00} + {-877903200 0 1 -01} {-857944800 -3600 0 -01} - {-846453600 0 1 +00} + {-846453600 0 1 -01} {-826495200 -3600 0 -01} - {-815004000 0 1 +00} + {-815004000 0 1 -01} {-795045600 -3600 0 -01} - {-783554400 0 1 +00} + {-783554400 0 1 -01} {-762991200 -3600 0 -01} - {-752104800 0 1 +00} + {-752104800 0 1 -01} {-731541600 -3600 0 -01} - {-717631200 0 1 +00} + {-717631200 0 1 -01} {-700092000 -3600 0 -01} - {-686181600 0 1 +00} + {-686181600 0 1 -01} {-668642400 -3600 0 -01} - {-654732000 0 1 +00} + {-654732000 0 1 -01} {-636588000 -3600 0 -01} - {-623282400 0 1 +00} + {-623282400 0 1 -01} {-605743200 -3600 0 -01} - {-591832800 0 1 +00} + {-591832800 0 1 -01} {-573688800 -3600 0 -01} - {-559778400 0 1 +00} + {-559778400 0 1 -01} {-542239200 -3600 0 -01} - {-528328800 0 1 +00} + {-528328800 0 1 -01} {-510789600 -3600 0 -01} - {-496879200 0 1 +00} + {-496879200 0 1 -01} {-479340000 -3600 0 -01} - {-465429600 0 1 +00} + {-465429600 0 1 -01} {-447890400 -3600 0 -01} - {-433980000 0 1 +00} + {-433980000 0 1 -01} {-415836000 -3600 0 -01} - {-401925600 0 1 +00} + {-401925600 0 1 -01} {-384386400 -3600 0 -01} - {-370476000 0 1 +00} + {-370476000 0 1 -01} {-352936800 -3600 0 -01} - {-339026400 0 1 +00} + {-339026400 0 1 -01} {-321487200 -3600 0 -01} - {-307576800 0 1 +00} + {-307576800 0 1 -01} {-290037600 -3600 0 -01} - {-276127200 0 1 +00} + {-276127200 0 1 -01} {-258588000 -3600 0 -01} - {-244677600 0 1 +00} + {-244677600 0 1 -01} {-226533600 -3600 0 -01} - {-212623200 0 1 +00} + {-212623200 0 1 -01} {-195084000 -3600 0 -01} - {-181173600 0 1 +00} + {-181173600 0 1 -01} {-163634400 -3600 0 -01} - {-149724000 0 1 +00} + {-149724000 0 1 -01} {-132184800 -3600 0 -01} - {-118274400 0 1 +00} + {-118274400 0 1 -01} {-100735200 -3600 0 -01} - {-86824800 0 1 +00} + {-86824800 0 1 -01} {-68680800 -3600 0 -01} {-54770400 0 0 GMT} } diff --git a/library/tzdata/Atlantic/Stanley b/library/tzdata/Atlantic/Stanley index 5210832..48473ca 100644 --- a/library/tzdata/Atlantic/Stanley +++ b/library/tzdata/Atlantic/Stanley @@ -4,72 +4,72 @@ set TZData(:Atlantic/Stanley) { {-9223372036854775808 -13884 0 LMT} {-2524507716 -13884 0 SMT} {-1824235716 -14400 0 -04} - {-1018209600 -10800 1 -03} + {-1018209600 -10800 1 -04} {-1003093200 -14400 0 -04} - {-986760000 -10800 1 -03} + {-986760000 -10800 1 -04} {-971643600 -14400 0 -04} - {-954705600 -10800 1 -03} + {-954705600 -10800 1 -04} {-939589200 -14400 0 -04} - {-923256000 -10800 1 -03} + {-923256000 -10800 1 -04} {-908139600 -14400 0 -04} - {-891806400 -10800 1 -03} + {-891806400 -10800 1 -04} {-876690000 -14400 0 -04} - {-860356800 -10800 1 -03} + {-860356800 -10800 1 -04} {420606000 -7200 0 -03} - {433303200 -7200 1 -02} + {433303200 -7200 1 -03} {452052000 -10800 0 -03} - {464151600 -7200 1 -02} + {464151600 -7200 1 -03} {483501600 -10800 0 -03} {495597600 -14400 0 -04} - {495604800 -10800 1 -03} + {495604800 -10800 1 -04} {514350000 -14400 0 -04} - {527054400 -10800 1 -03} + {527054400 -10800 1 -04} {545799600 -14400 0 -04} - {558504000 -10800 1 -03} + {558504000 -10800 1 -04} {577249200 -14400 0 -04} - {589953600 -10800 1 -03} + {589953600 -10800 1 -04} {608698800 -14400 0 -04} - {621403200 -10800 1 -03} + {621403200 -10800 1 -04} {640753200 -14400 0 -04} - {652852800 -10800 1 -03} + {652852800 -10800 1 -04} {672202800 -14400 0 -04} - {684907200 -10800 1 -03} + {684907200 -10800 1 -04} {703652400 -14400 0 -04} - {716356800 -10800 1 -03} + {716356800 -10800 1 -04} {735102000 -14400 0 -04} - {747806400 -10800 1 -03} + {747806400 -10800 1 -04} {766551600 -14400 0 -04} - {779256000 -10800 1 -03} + {779256000 -10800 1 -04} {798001200 -14400 0 -04} - {810705600 -10800 1 -03} + {810705600 -10800 1 -04} {830055600 -14400 0 -04} - {842760000 -10800 1 -03} + {842760000 -10800 1 -04} {861505200 -14400 0 -04} - {874209600 -10800 1 -03} + {874209600 -10800 1 -04} {892954800 -14400 0 -04} - {905659200 -10800 1 -03} + {905659200 -10800 1 -04} {924404400 -14400 0 -04} - {937108800 -10800 1 -03} + {937108800 -10800 1 -04} {955854000 -14400 0 -04} - {968558400 -10800 1 -03} + {968558400 -10800 1 -04} {987310800 -14400 0 -04} - {999410400 -10800 1 -03} + {999410400 -10800 1 -04} {1019365200 -14400 0 -04} - {1030860000 -10800 1 -03} + {1030860000 -10800 1 -04} {1050814800 -14400 0 -04} - {1062914400 -10800 1 -03} + {1062914400 -10800 1 -04} {1082264400 -14400 0 -04} - {1094364000 -10800 1 -03} + {1094364000 -10800 1 -04} {1113714000 -14400 0 -04} - {1125813600 -10800 1 -03} + {1125813600 -10800 1 -04} {1145163600 -14400 0 -04} - {1157263200 -10800 1 -03} + {1157263200 -10800 1 -04} {1176613200 -14400 0 -04} - {1188712800 -10800 1 -03} + {1188712800 -10800 1 -04} {1208667600 -14400 0 -04} - {1220767200 -10800 1 -03} + {1220767200 -10800 1 -04} {1240117200 -14400 0 -04} - {1252216800 -10800 1 -03} + {1252216800 -10800 1 -04} {1271566800 -14400 0 -04} {1283662800 -10800 0 -03} } diff --git a/library/tzdata/Australia/Lord_Howe b/library/tzdata/Australia/Lord_Howe index 0e2405e..c595967 100644 --- a/library/tzdata/Australia/Lord_Howe +++ b/library/tzdata/Australia/Lord_Howe @@ -3,243 +3,243 @@ set TZData(:Australia/Lord_Howe) { {-9223372036854775808 38180 0 LMT} {-2364114980 36000 0 AEST} - {352216800 37800 0 +1130} - {372785400 41400 1 +1130} - {384273000 37800 0 +1130} - {404839800 41400 1 +1130} - {415722600 37800 0 +1130} - {436289400 41400 1 +1130} - {447172200 37800 0 +1130} - {467739000 41400 1 +1130} - {478621800 37800 0 +1130} - {488984400 37800 0 +11} - {499188600 39600 1 +11} - {511282800 37800 0 +11} - {530033400 39600 1 +11} - {542732400 37800 0 +11} - {562087800 39600 1 +11} - {574786800 37800 0 +11} - {594142200 39600 1 +11} - {606236400 37800 0 +11} - {625591800 39600 1 +11} - {636476400 37800 0 +11} - {657041400 39600 1 +11} - {667926000 37800 0 +11} - {688491000 39600 1 +11} - {699375600 37800 0 +11} - {719940600 39600 1 +11} - {731430000 37800 0 +11} - {751995000 39600 1 +11} - {762879600 37800 0 +11} - {783444600 39600 1 +11} - {794329200 37800 0 +11} - {814894200 39600 1 +11} - {828198000 37800 0 +11} - {846343800 39600 1 +11} - {859647600 37800 0 +11} - {877793400 39600 1 +11} - {891097200 37800 0 +11} - {909243000 39600 1 +11} - {922546800 37800 0 +11} - {941297400 39600 1 +11} - {953996400 37800 0 +11} - {967303800 39600 1 +11} - {985446000 37800 0 +11} - {1004196600 39600 1 +11} - {1017500400 37800 0 +11} - {1035646200 39600 1 +11} - {1048950000 37800 0 +11} - {1067095800 39600 1 +11} - {1080399600 37800 0 +11} - {1099150200 39600 1 +11} - {1111849200 37800 0 +11} - {1130599800 39600 1 +11} - {1143903600 37800 0 +11} - {1162049400 39600 1 +11} - {1174748400 37800 0 +11} - {1193499000 39600 1 +11} - {1207407600 37800 0 +11} - {1223134200 39600 1 +11} - {1238857200 37800 0 +11} - {1254583800 39600 1 +11} - {1270306800 37800 0 +11} - {1286033400 39600 1 +11} - {1301756400 37800 0 +11} - {1317483000 39600 1 +11} - {1333206000 37800 0 +11} - {1349537400 39600 1 +11} - {1365260400 37800 0 +11} - {1380987000 39600 1 +11} - {1396710000 37800 0 +11} - {1412436600 39600 1 +11} - {1428159600 37800 0 +11} - {1443886200 39600 1 +11} - {1459609200 37800 0 +11} - {1475335800 39600 1 +11} - {1491058800 37800 0 +11} - {1506785400 39600 1 +11} - {1522508400 37800 0 +11} - {1538839800 39600 1 +11} - {1554562800 37800 0 +11} - {1570289400 39600 1 +11} - {1586012400 37800 0 +11} - {1601739000 39600 1 +11} - {1617462000 37800 0 +11} - {1633188600 39600 1 +11} - {1648911600 37800 0 +11} - {1664638200 39600 1 +11} - {1680361200 37800 0 +11} - {1696087800 39600 1 +11} - {1712415600 37800 0 +11} - {1728142200 39600 1 +11} - {1743865200 37800 0 +11} - {1759591800 39600 1 +11} - {1775314800 37800 0 +11} - {1791041400 39600 1 +11} - {1806764400 37800 0 +11} - {1822491000 39600 1 +11} - {1838214000 37800 0 +11} - {1853940600 39600 1 +11} - {1869663600 37800 0 +11} - {1885995000 39600 1 +11} - {1901718000 37800 0 +11} - {1917444600 39600 1 +11} - {1933167600 37800 0 +11} - {1948894200 39600 1 +11} - {1964617200 37800 0 +11} - {1980343800 39600 1 +11} - {1996066800 37800 0 +11} - {2011793400 39600 1 +11} - {2027516400 37800 0 +11} - {2043243000 39600 1 +11} - {2058966000 37800 0 +11} - {2075297400 39600 1 +11} - {2091020400 37800 0 +11} - {2106747000 39600 1 +11} - {2122470000 37800 0 +11} - {2138196600 39600 1 +11} - {2153919600 37800 0 +11} - {2169646200 39600 1 +11} - {2185369200 37800 0 +11} - {2201095800 39600 1 +11} - {2216818800 37800 0 +11} - {2233150200 39600 1 +11} - {2248873200 37800 0 +11} - {2264599800 39600 1 +11} - {2280322800 37800 0 +11} - {2296049400 39600 1 +11} - {2311772400 37800 0 +11} - {2327499000 39600 1 +11} - {2343222000 37800 0 +11} - {2358948600 39600 1 +11} - {2374671600 37800 0 +11} - {2390398200 39600 1 +11} - {2406121200 37800 0 +11} - {2422452600 39600 1 +11} - {2438175600 37800 0 +11} - {2453902200 39600 1 +11} - {2469625200 37800 0 +11} - {2485351800 39600 1 +11} - {2501074800 37800 0 +11} - {2516801400 39600 1 +11} - {2532524400 37800 0 +11} - {2548251000 39600 1 +11} - {2563974000 37800 0 +11} - {2579700600 39600 1 +11} - {2596028400 37800 0 +11} - {2611755000 39600 1 +11} - {2627478000 37800 0 +11} - {2643204600 39600 1 +11} - {2658927600 37800 0 +11} - {2674654200 39600 1 +11} - {2690377200 37800 0 +11} - {2706103800 39600 1 +11} - {2721826800 37800 0 +11} - {2737553400 39600 1 +11} - {2753276400 37800 0 +11} - {2769607800 39600 1 +11} - {2785330800 37800 0 +11} - {2801057400 39600 1 +11} - {2816780400 37800 0 +11} - {2832507000 39600 1 +11} - {2848230000 37800 0 +11} - {2863956600 39600 1 +11} - {2879679600 37800 0 +11} - {2895406200 39600 1 +11} - {2911129200 37800 0 +11} - {2926855800 39600 1 +11} - {2942578800 37800 0 +11} - {2958910200 39600 1 +11} - {2974633200 37800 0 +11} - {2990359800 39600 1 +11} - {3006082800 37800 0 +11} - {3021809400 39600 1 +11} - {3037532400 37800 0 +11} - {3053259000 39600 1 +11} - {3068982000 37800 0 +11} - {3084708600 39600 1 +11} - {3100431600 37800 0 +11} - {3116763000 39600 1 +11} - {3132486000 37800 0 +11} - {3148212600 39600 1 +11} - {3163935600 37800 0 +11} - {3179662200 39600 1 +11} - {3195385200 37800 0 +11} - {3211111800 39600 1 +11} - {3226834800 37800 0 +11} - {3242561400 39600 1 +11} - {3258284400 37800 0 +11} - {3274011000 39600 1 +11} - {3289734000 37800 0 +11} - {3306065400 39600 1 +11} - {3321788400 37800 0 +11} - {3337515000 39600 1 +11} - {3353238000 37800 0 +11} - {3368964600 39600 1 +11} - {3384687600 37800 0 +11} - {3400414200 39600 1 +11} - {3416137200 37800 0 +11} - {3431863800 39600 1 +11} - {3447586800 37800 0 +11} - {3463313400 39600 1 +11} - {3479641200 37800 0 +11} - {3495367800 39600 1 +11} - {3511090800 37800 0 +11} - {3526817400 39600 1 +11} - {3542540400 37800 0 +11} - {3558267000 39600 1 +11} - {3573990000 37800 0 +11} - {3589716600 39600 1 +11} - {3605439600 37800 0 +11} - {3621166200 39600 1 +11} - {3636889200 37800 0 +11} - {3653220600 39600 1 +11} - {3668943600 37800 0 +11} - {3684670200 39600 1 +11} - {3700393200 37800 0 +11} - {3716119800 39600 1 +11} - {3731842800 37800 0 +11} - {3747569400 39600 1 +11} - {3763292400 37800 0 +11} - {3779019000 39600 1 +11} - {3794742000 37800 0 +11} - {3810468600 39600 1 +11} - {3826191600 37800 0 +11} - {3842523000 39600 1 +11} - {3858246000 37800 0 +11} - {3873972600 39600 1 +11} - {3889695600 37800 0 +11} - {3905422200 39600 1 +11} - {3921145200 37800 0 +11} - {3936871800 39600 1 +11} - {3952594800 37800 0 +11} - {3968321400 39600 1 +11} - {3984044400 37800 0 +11} - {4000375800 39600 1 +11} - {4016098800 37800 0 +11} - {4031825400 39600 1 +11} - {4047548400 37800 0 +11} - {4063275000 39600 1 +11} - {4078998000 37800 0 +11} - {4094724600 39600 1 +11} + {352216800 37800 0 +1030} + {372785400 41400 1 +1030} + {384273000 37800 0 +1030} + {404839800 41400 1 +1030} + {415722600 37800 0 +1030} + {436289400 41400 1 +1030} + {447172200 37800 0 +1030} + {467739000 41400 1 +1030} + {478621800 37800 0 +1030} + {488984400 37800 0 +1030} + {499188600 39600 1 +1030} + {511282800 37800 0 +1030} + {530033400 39600 1 +1030} + {542732400 37800 0 +1030} + {562087800 39600 1 +1030} + {574786800 37800 0 +1030} + {594142200 39600 1 +1030} + {606236400 37800 0 +1030} + {625591800 39600 1 +1030} + {636476400 37800 0 +1030} + {657041400 39600 1 +1030} + {667926000 37800 0 +1030} + {688491000 39600 1 +1030} + {699375600 37800 0 +1030} + {719940600 39600 1 +1030} + {731430000 37800 0 +1030} + {751995000 39600 1 +1030} + {762879600 37800 0 +1030} + {783444600 39600 1 +1030} + {794329200 37800 0 +1030} + {814894200 39600 1 +1030} + {828198000 37800 0 +1030} + {846343800 39600 1 +1030} + {859647600 37800 0 +1030} + {877793400 39600 1 +1030} + {891097200 37800 0 +1030} + {909243000 39600 1 +1030} + {922546800 37800 0 +1030} + {941297400 39600 1 +1030} + {953996400 37800 0 +1030} + {967303800 39600 1 +1030} + {985446000 37800 0 +1030} + {1004196600 39600 1 +1030} + {1017500400 37800 0 +1030} + {1035646200 39600 1 +1030} + {1048950000 37800 0 +1030} + {1067095800 39600 1 +1030} + {1080399600 37800 0 +1030} + {1099150200 39600 1 +1030} + {1111849200 37800 0 +1030} + {1130599800 39600 1 +1030} + {1143903600 37800 0 +1030} + {1162049400 39600 1 +1030} + {1174748400 37800 0 +1030} + {1193499000 39600 1 +1030} + {1207407600 37800 0 +1030} + {1223134200 39600 1 +1030} + {1238857200 37800 0 +1030} + {1254583800 39600 1 +1030} + {1270306800 37800 0 +1030} + {1286033400 39600 1 +1030} + {1301756400 37800 0 +1030} + {1317483000 39600 1 +1030} + {1333206000 37800 0 +1030} + {1349537400 39600 1 +1030} + {1365260400 37800 0 +1030} + {1380987000 39600 1 +1030} + {1396710000 37800 0 +1030} + {1412436600 39600 1 +1030} + {1428159600 37800 0 +1030} + {1443886200 39600 1 +1030} + {1459609200 37800 0 +1030} + {1475335800 39600 1 +1030} + {1491058800 37800 0 +1030} + {1506785400 39600 1 +1030} + {1522508400 37800 0 +1030} + {1538839800 39600 1 +1030} + {1554562800 37800 0 +1030} + {1570289400 39600 1 +1030} + {1586012400 37800 0 +1030} + {1601739000 39600 1 +1030} + {1617462000 37800 0 +1030} + {1633188600 39600 1 +1030} + {1648911600 37800 0 +1030} + {1664638200 39600 1 +1030} + {1680361200 37800 0 +1030} + {1696087800 39600 1 +1030} + {1712415600 37800 0 +1030} + {1728142200 39600 1 +1030} + {1743865200 37800 0 +1030} + {1759591800 39600 1 +1030} + {1775314800 37800 0 +1030} + {1791041400 39600 1 +1030} + {1806764400 37800 0 +1030} + {1822491000 39600 1 +1030} + {1838214000 37800 0 +1030} + {1853940600 39600 1 +1030} + {1869663600 37800 0 +1030} + {1885995000 39600 1 +1030} + {1901718000 37800 0 +1030} + {1917444600 39600 1 +1030} + {1933167600 37800 0 +1030} + {1948894200 39600 1 +1030} + {1964617200 37800 0 +1030} + {1980343800 39600 1 +1030} + {1996066800 37800 0 +1030} + {2011793400 39600 1 +1030} + {2027516400 37800 0 +1030} + {2043243000 39600 1 +1030} + {2058966000 37800 0 +1030} + {2075297400 39600 1 +1030} + {2091020400 37800 0 +1030} + {2106747000 39600 1 +1030} + {2122470000 37800 0 +1030} + {2138196600 39600 1 +1030} + {2153919600 37800 0 +1030} + {2169646200 39600 1 +1030} + {2185369200 37800 0 +1030} + {2201095800 39600 1 +1030} + {2216818800 37800 0 +1030} + {2233150200 39600 1 +1030} + {2248873200 37800 0 +1030} + {2264599800 39600 1 +1030} + {2280322800 37800 0 +1030} + {2296049400 39600 1 +1030} + {2311772400 37800 0 +1030} + {2327499000 39600 1 +1030} + {2343222000 37800 0 +1030} + {2358948600 39600 1 +1030} + {2374671600 37800 0 +1030} + {2390398200 39600 1 +1030} + {2406121200 37800 0 +1030} + {2422452600 39600 1 +1030} + {2438175600 37800 0 +1030} + {2453902200 39600 1 +1030} + {2469625200 37800 0 +1030} + {2485351800 39600 1 +1030} + {2501074800 37800 0 +1030} + {2516801400 39600 1 +1030} + {2532524400 37800 0 +1030} + {2548251000 39600 1 +1030} + {2563974000 37800 0 +1030} + {2579700600 39600 1 +1030} + {2596028400 37800 0 +1030} + {2611755000 39600 1 +1030} + {2627478000 37800 0 +1030} + {2643204600 39600 1 +1030} + {2658927600 37800 0 +1030} + {2674654200 39600 1 +1030} + {2690377200 37800 0 +1030} + {2706103800 39600 1 +1030} + {2721826800 37800 0 +1030} + {2737553400 39600 1 +1030} + {2753276400 37800 0 +1030} + {2769607800 39600 1 +1030} + {2785330800 37800 0 +1030} + {2801057400 39600 1 +1030} + {2816780400 37800 0 +1030} + {2832507000 39600 1 +1030} + {2848230000 37800 0 +1030} + {2863956600 39600 1 +1030} + {2879679600 37800 0 +1030} + {2895406200 39600 1 +1030} + {2911129200 37800 0 +1030} + {2926855800 39600 1 +1030} + {2942578800 37800 0 +1030} + {2958910200 39600 1 +1030} + {2974633200 37800 0 +1030} + {2990359800 39600 1 +1030} + {3006082800 37800 0 +1030} + {3021809400 39600 1 +1030} + {3037532400 37800 0 +1030} + {3053259000 39600 1 +1030} + {3068982000 37800 0 +1030} + {3084708600 39600 1 +1030} + {3100431600 37800 0 +1030} + {3116763000 39600 1 +1030} + {3132486000 37800 0 +1030} + {3148212600 39600 1 +1030} + {3163935600 37800 0 +1030} + {3179662200 39600 1 +1030} + {3195385200 37800 0 +1030} + {3211111800 39600 1 +1030} + {3226834800 37800 0 +1030} + {3242561400 39600 1 +1030} + {3258284400 37800 0 +1030} + {3274011000 39600 1 +1030} + {3289734000 37800 0 +1030} + {3306065400 39600 1 +1030} + {3321788400 37800 0 +1030} + {3337515000 39600 1 +1030} + {3353238000 37800 0 +1030} + {3368964600 39600 1 +1030} + {3384687600 37800 0 +1030} + {3400414200 39600 1 +1030} + {3416137200 37800 0 +1030} + {3431863800 39600 1 +1030} + {3447586800 37800 0 +1030} + {3463313400 39600 1 +1030} + {3479641200 37800 0 +1030} + {3495367800 39600 1 +1030} + {3511090800 37800 0 +1030} + {3526817400 39600 1 +1030} + {3542540400 37800 0 +1030} + {3558267000 39600 1 +1030} + {3573990000 37800 0 +1030} + {3589716600 39600 1 +1030} + {3605439600 37800 0 +1030} + {3621166200 39600 1 +1030} + {3636889200 37800 0 +1030} + {3653220600 39600 1 +1030} + {3668943600 37800 0 +1030} + {3684670200 39600 1 +1030} + {3700393200 37800 0 +1030} + {3716119800 39600 1 +1030} + {3731842800 37800 0 +1030} + {3747569400 39600 1 +1030} + {3763292400 37800 0 +1030} + {3779019000 39600 1 +1030} + {3794742000 37800 0 +1030} + {3810468600 39600 1 +1030} + {3826191600 37800 0 +1030} + {3842523000 39600 1 +1030} + {3858246000 37800 0 +1030} + {3873972600 39600 1 +1030} + {3889695600 37800 0 +1030} + {3905422200 39600 1 +1030} + {3921145200 37800 0 +1030} + {3936871800 39600 1 +1030} + {3952594800 37800 0 +1030} + {3968321400 39600 1 +1030} + {3984044400 37800 0 +1030} + {4000375800 39600 1 +1030} + {4016098800 37800 0 +1030} + {4031825400 39600 1 +1030} + {4047548400 37800 0 +1030} + {4063275000 39600 1 +1030} + {4078998000 37800 0 +1030} + {4094724600 39600 1 +1030} } diff --git a/library/tzdata/Europe/Dublin b/library/tzdata/Europe/Dublin index c3a5c0e..56afc93 100644 --- a/library/tzdata/Europe/Dublin +++ b/library/tzdata/Europe/Dublin @@ -98,262 +98,261 @@ set TZData(:Europe/Dublin) { {-68680800 0 0 IST} {-59004000 3600 1 IST} {-37238400 3600 0 IST} - {57722400 0 0 IST} - {69818400 3600 1 IST} - {89172000 0 0 IST} - {101268000 3600 1 IST} - {120621600 0 0 IST} - {132717600 3600 1 IST} - {152071200 0 0 IST} - {164167200 3600 1 IST} - {183520800 0 0 IST} - {196221600 3600 1 IST} - {214970400 0 0 IST} - {227671200 3600 1 IST} - {246420000 0 0 IST} - {259120800 3600 1 IST} - {278474400 0 0 IST} - {290570400 3600 1 IST} - {309924000 0 0 IST} - {322020000 3600 1 IST} - {341373600 0 0 IST} - {354675600 3600 1 IST} - {372819600 0 0 IST} - {386125200 3600 1 IST} - {404269200 0 0 IST} - {417574800 3600 1 IST} - {435718800 0 0 IST} - {449024400 3600 1 IST} - {467773200 0 0 IST} - {481078800 3600 1 IST} - {499222800 0 0 IST} - {512528400 3600 1 IST} - {530672400 0 0 IST} - {543978000 3600 1 IST} - {562122000 0 0 IST} - {575427600 3600 1 IST} - {593571600 0 0 IST} - {606877200 3600 1 IST} - {625626000 0 0 IST} - {638326800 3600 1 IST} - {657075600 0 0 IST} - {670381200 3600 1 IST} - {688525200 0 0 IST} - {701830800 3600 1 IST} - {719974800 0 0 IST} - {733280400 3600 1 IST} - {751424400 0 0 IST} - {764730000 3600 1 IST} - {782874000 0 0 IST} - {796179600 3600 1 IST} - {814323600 0 0 IST} - {820454400 0 0 GMT} - {828234000 3600 1 IST} - {846378000 0 0 GMT} - {859683600 3600 1 IST} - {877827600 0 0 GMT} - {891133200 3600 1 IST} - {909277200 0 0 GMT} - {922582800 3600 1 IST} - {941331600 0 0 GMT} - {954032400 3600 1 IST} - {972781200 0 0 GMT} - {985482000 3600 1 IST} - {1004230800 0 0 GMT} - {1017536400 3600 1 IST} - {1035680400 0 0 GMT} - {1048986000 3600 1 IST} - {1067130000 0 0 GMT} - {1080435600 3600 1 IST} - {1099184400 0 0 GMT} - {1111885200 3600 1 IST} - {1130634000 0 0 GMT} - {1143334800 3600 1 IST} - {1162083600 0 0 GMT} - {1174784400 3600 1 IST} - {1193533200 0 0 GMT} - {1206838800 3600 1 IST} - {1224982800 0 0 GMT} - {1238288400 3600 1 IST} - {1256432400 0 0 GMT} - {1269738000 3600 1 IST} - {1288486800 0 0 GMT} - {1301187600 3600 1 IST} - {1319936400 0 0 GMT} - {1332637200 3600 1 IST} - {1351386000 0 0 GMT} - {1364691600 3600 1 IST} - {1382835600 0 0 GMT} - {1396141200 3600 1 IST} - {1414285200 0 0 GMT} - {1427590800 3600 1 IST} - {1445734800 0 0 GMT} - {1459040400 3600 1 IST} - {1477789200 0 0 GMT} - {1490490000 3600 1 IST} - {1509238800 0 0 GMT} - {1521939600 3600 1 IST} - {1540688400 0 0 GMT} - {1553994000 3600 1 IST} - {1572138000 0 0 GMT} - {1585443600 3600 1 IST} - {1603587600 0 0 GMT} - {1616893200 3600 1 IST} - {1635642000 0 0 GMT} - {1648342800 3600 1 IST} - {1667091600 0 0 GMT} - {1679792400 3600 1 IST} - {1698541200 0 0 GMT} - {1711846800 3600 1 IST} - {1729990800 0 0 GMT} - {1743296400 3600 1 IST} - {1761440400 0 0 GMT} - {1774746000 3600 1 IST} - {1792890000 0 0 GMT} - {1806195600 3600 1 IST} - {1824944400 0 0 GMT} - {1837645200 3600 1 IST} - {1856394000 0 0 GMT} - {1869094800 3600 1 IST} - {1887843600 0 0 GMT} - {1901149200 3600 1 IST} - {1919293200 0 0 GMT} - {1932598800 3600 1 IST} - {1950742800 0 0 GMT} - {1964048400 3600 1 IST} - {1982797200 0 0 GMT} - {1995498000 3600 1 IST} - {2014246800 0 0 GMT} - {2026947600 3600 1 IST} - {2045696400 0 0 GMT} - {2058397200 3600 1 IST} - {2077146000 0 0 GMT} - {2090451600 3600 1 IST} - {2108595600 0 0 GMT} - {2121901200 3600 1 IST} - {2140045200 0 0 GMT} - {2153350800 3600 1 IST} - {2172099600 0 0 GMT} - {2184800400 3600 1 IST} - {2203549200 0 0 GMT} - {2216250000 3600 1 IST} - {2234998800 0 0 GMT} - {2248304400 3600 1 IST} - {2266448400 0 0 GMT} - {2279754000 3600 1 IST} - {2297898000 0 0 GMT} - {2311203600 3600 1 IST} - {2329347600 0 0 GMT} - {2342653200 3600 1 IST} - {2361402000 0 0 GMT} - {2374102800 3600 1 IST} - {2392851600 0 0 GMT} - {2405552400 3600 1 IST} - {2424301200 0 0 GMT} - {2437606800 3600 1 IST} - {2455750800 0 0 GMT} - {2469056400 3600 1 IST} - {2487200400 0 0 GMT} - {2500506000 3600 1 IST} - {2519254800 0 0 GMT} - {2531955600 3600 1 IST} - {2550704400 0 0 GMT} - {2563405200 3600 1 IST} - {2582154000 0 0 GMT} - {2595459600 3600 1 IST} - {2613603600 0 0 GMT} - {2626909200 3600 1 IST} - {2645053200 0 0 GMT} - {2658358800 3600 1 IST} - {2676502800 0 0 GMT} - {2689808400 3600 1 IST} - {2708557200 0 0 GMT} - {2721258000 3600 1 IST} - {2740006800 0 0 GMT} - {2752707600 3600 1 IST} - {2771456400 0 0 GMT} - {2784762000 3600 1 IST} - {2802906000 0 0 GMT} - {2816211600 3600 1 IST} - {2834355600 0 0 GMT} - {2847661200 3600 1 IST} - {2866410000 0 0 GMT} - {2879110800 3600 1 IST} - {2897859600 0 0 GMT} - {2910560400 3600 1 IST} - {2929309200 0 0 GMT} - {2942010000 3600 1 IST} - {2960758800 0 0 GMT} - {2974064400 3600 1 IST} - {2992208400 0 0 GMT} - {3005514000 3600 1 IST} - {3023658000 0 0 GMT} - {3036963600 3600 1 IST} - {3055712400 0 0 GMT} - {3068413200 3600 1 IST} - {3087162000 0 0 GMT} - {3099862800 3600 1 IST} - {3118611600 0 0 GMT} - {3131917200 3600 1 IST} - {3150061200 0 0 GMT} - {3163366800 3600 1 IST} - {3181510800 0 0 GMT} - {3194816400 3600 1 IST} - {3212960400 0 0 GMT} - {3226266000 3600 1 IST} - {3245014800 0 0 GMT} - {3257715600 3600 1 IST} - {3276464400 0 0 GMT} - {3289165200 3600 1 IST} - {3307914000 0 0 GMT} - {3321219600 3600 1 IST} - {3339363600 0 0 GMT} - {3352669200 3600 1 IST} - {3370813200 0 0 GMT} - {3384118800 3600 1 IST} - {3402867600 0 0 GMT} - {3415568400 3600 1 IST} - {3434317200 0 0 GMT} - {3447018000 3600 1 IST} - {3465766800 0 0 GMT} - {3479072400 3600 1 IST} - {3497216400 0 0 GMT} - {3510522000 3600 1 IST} - {3528666000 0 0 GMT} - {3541971600 3600 1 IST} - {3560115600 0 0 GMT} - {3573421200 3600 1 IST} - {3592170000 0 0 GMT} - {3604870800 3600 1 IST} - {3623619600 0 0 GMT} - {3636320400 3600 1 IST} - {3655069200 0 0 GMT} - {3668374800 3600 1 IST} - {3686518800 0 0 GMT} - {3699824400 3600 1 IST} - {3717968400 0 0 GMT} - {3731274000 3600 1 IST} - {3750022800 0 0 GMT} - {3762723600 3600 1 IST} - {3781472400 0 0 GMT} - {3794173200 3600 1 IST} - {3812922000 0 0 GMT} - {3825622800 3600 1 IST} - {3844371600 0 0 GMT} - {3857677200 3600 1 IST} - {3875821200 0 0 GMT} - {3889126800 3600 1 IST} - {3907270800 0 0 GMT} - {3920576400 3600 1 IST} - {3939325200 0 0 GMT} - {3952026000 3600 1 IST} - {3970774800 0 0 GMT} - {3983475600 3600 1 IST} - {4002224400 0 0 GMT} - {4015530000 3600 1 IST} - {4033674000 0 0 GMT} - {4046979600 3600 1 IST} - {4065123600 0 0 GMT} - {4078429200 3600 1 IST} - {4096573200 0 0 GMT} + {57722400 0 1 IST} + {69818400 3600 0 IST} + {89172000 0 1 IST} + {101268000 3600 0 IST} + {120621600 0 1 IST} + {132717600 3600 0 IST} + {152071200 0 1 IST} + {164167200 3600 0 IST} + {183520800 0 1 IST} + {196221600 3600 0 IST} + {214970400 0 1 IST} + {227671200 3600 0 IST} + {246420000 0 1 IST} + {259120800 3600 0 IST} + {278474400 0 1 IST} + {290570400 3600 0 IST} + {309924000 0 1 IST} + {322020000 3600 0 IST} + {341373600 0 1 IST} + {354675600 3600 0 IST} + {372819600 0 1 IST} + {386125200 3600 0 IST} + {404269200 0 1 IST} + {417574800 3600 0 IST} + {435718800 0 1 IST} + {449024400 3600 0 IST} + {467773200 0 1 IST} + {481078800 3600 0 IST} + {499222800 0 1 IST} + {512528400 3600 0 IST} + {530672400 0 1 IST} + {543978000 3600 0 IST} + {562122000 0 1 IST} + {575427600 3600 0 IST} + {593571600 0 1 IST} + {606877200 3600 0 IST} + {625626000 0 1 IST} + {638326800 3600 0 IST} + {657075600 0 1 IST} + {670381200 3600 0 IST} + {688525200 0 1 IST} + {701830800 3600 0 IST} + {719974800 0 1 IST} + {733280400 3600 0 IST} + {751424400 0 1 IST} + {764730000 3600 0 IST} + {782874000 0 1 IST} + {796179600 3600 0 IST} + {814323600 0 1 IST} + {828234000 3600 0 IST} + {846378000 0 1 IST} + {859683600 3600 0 IST} + {877827600 0 1 IST} + {891133200 3600 0 IST} + {909277200 0 1 IST} + {922582800 3600 0 IST} + {941331600 0 1 IST} + {954032400 3600 0 IST} + {972781200 0 1 IST} + {985482000 3600 0 IST} + {1004230800 0 1 IST} + {1017536400 3600 0 IST} + {1035680400 0 1 IST} + {1048986000 3600 0 IST} + {1067130000 0 1 IST} + {1080435600 3600 0 IST} + {1099184400 0 1 IST} + {1111885200 3600 0 IST} + {1130634000 0 1 IST} + {1143334800 3600 0 IST} + {1162083600 0 1 IST} + {1174784400 3600 0 IST} + {1193533200 0 1 IST} + {1206838800 3600 0 IST} + {1224982800 0 1 IST} + {1238288400 3600 0 IST} + {1256432400 0 1 IST} + {1269738000 3600 0 IST} + {1288486800 0 1 IST} + {1301187600 3600 0 IST} + {1319936400 0 1 IST} + {1332637200 3600 0 IST} + {1351386000 0 1 IST} + {1364691600 3600 0 IST} + {1382835600 0 1 IST} + {1396141200 3600 0 IST} + {1414285200 0 1 IST} + {1427590800 3600 0 IST} + {1445734800 0 1 IST} + {1459040400 3600 0 IST} + {1477789200 0 1 IST} + {1490490000 3600 0 IST} + {1509238800 0 1 IST} + {1521939600 3600 0 IST} + {1540688400 0 1 IST} + {1553994000 3600 0 IST} + {1572138000 0 1 IST} + {1585443600 3600 0 IST} + {1603587600 0 1 IST} + {1616893200 3600 0 IST} + {1635642000 0 1 IST} + {1648342800 3600 0 IST} + {1667091600 0 1 IST} + {1679792400 3600 0 IST} + {1698541200 0 1 IST} + {1711846800 3600 0 IST} + {1729990800 0 1 IST} + {1743296400 3600 0 IST} + {1761440400 0 1 IST} + {1774746000 3600 0 IST} + {1792890000 0 1 IST} + {1806195600 3600 0 IST} + {1824944400 0 1 IST} + {1837645200 3600 0 IST} + {1856394000 0 1 IST} + {1869094800 3600 0 IST} + {1887843600 0 1 IST} + {1901149200 3600 0 IST} + {1919293200 0 1 IST} + {1932598800 3600 0 IST} + {1950742800 0 1 IST} + {1964048400 3600 0 IST} + {1982797200 0 1 IST} + {1995498000 3600 0 IST} + {2014246800 0 1 IST} + {2026947600 3600 0 IST} + {2045696400 0 1 IST} + {2058397200 3600 0 IST} + {2077146000 0 1 IST} + {2090451600 3600 0 IST} + {2108595600 0 1 IST} + {2121901200 3600 0 IST} + {2140045200 0 1 IST} + {2153350800 3600 0 IST} + {2172099600 0 1 IST} + {2184800400 3600 0 IST} + {2203549200 0 1 IST} + {2216250000 3600 0 IST} + {2234998800 0 1 IST} + {2248304400 3600 0 IST} + {2266448400 0 1 IST} + {2279754000 3600 0 IST} + {2297898000 0 1 IST} + {2311203600 3600 0 IST} + {2329347600 0 1 IST} + {2342653200 3600 0 IST} + {2361402000 0 1 IST} + {2374102800 3600 0 IST} + {2392851600 0 1 IST} + {2405552400 3600 0 IST} + {2424301200 0 1 IST} + {2437606800 3600 0 IST} + {2455750800 0 1 IST} + {2469056400 3600 0 IST} + {2487200400 0 1 IST} + {2500506000 3600 0 IST} + {2519254800 0 1 IST} + {2531955600 3600 0 IST} + {2550704400 0 1 IST} + {2563405200 3600 0 IST} + {2582154000 0 1 IST} + {2595459600 3600 0 IST} + {2613603600 0 1 IST} + {2626909200 3600 0 IST} + {2645053200 0 1 IST} + {2658358800 3600 0 IST} + {2676502800 0 1 IST} + {2689808400 3600 0 IST} + {2708557200 0 1 IST} + {2721258000 3600 0 IST} + {2740006800 0 1 IST} + {2752707600 3600 0 IST} + {2771456400 0 1 IST} + {2784762000 3600 0 IST} + {2802906000 0 1 IST} + {2816211600 3600 0 IST} + {2834355600 0 1 IST} + {2847661200 3600 0 IST} + {2866410000 0 1 IST} + {2879110800 3600 0 IST} + {2897859600 0 1 IST} + {2910560400 3600 0 IST} + {2929309200 0 1 IST} + {2942010000 3600 0 IST} + {2960758800 0 1 IST} + {2974064400 3600 0 IST} + {2992208400 0 1 IST} + {3005514000 3600 0 IST} + {3023658000 0 1 IST} + {3036963600 3600 0 IST} + {3055712400 0 1 IST} + {3068413200 3600 0 IST} + {3087162000 0 1 IST} + {3099862800 3600 0 IST} + {3118611600 0 1 IST} + {3131917200 3600 0 IST} + {3150061200 0 1 IST} + {3163366800 3600 0 IST} + {3181510800 0 1 IST} + {3194816400 3600 0 IST} + {3212960400 0 1 IST} + {3226266000 3600 0 IST} + {3245014800 0 1 IST} + {3257715600 3600 0 IST} + {3276464400 0 1 IST} + {3289165200 3600 0 IST} + {3307914000 0 1 IST} + {3321219600 3600 0 IST} + {3339363600 0 1 IST} + {3352669200 3600 0 IST} + {3370813200 0 1 IST} + {3384118800 3600 0 IST} + {3402867600 0 1 IST} + {3415568400 3600 0 IST} + {3434317200 0 1 IST} + {3447018000 3600 0 IST} + {3465766800 0 1 IST} + {3479072400 3600 0 IST} + {3497216400 0 1 IST} + {3510522000 3600 0 IST} + {3528666000 0 1 IST} + {3541971600 3600 0 IST} + {3560115600 0 1 IST} + {3573421200 3600 0 IST} + {3592170000 0 1 IST} + {3604870800 3600 0 IST} + {3623619600 0 1 IST} + {3636320400 3600 0 IST} + {3655069200 0 1 IST} + {3668374800 3600 0 IST} + {3686518800 0 1 IST} + {3699824400 3600 0 IST} + {3717968400 0 1 IST} + {3731274000 3600 0 IST} + {3750022800 0 1 IST} + {3762723600 3600 0 IST} + {3781472400 0 1 IST} + {3794173200 3600 0 IST} + {3812922000 0 1 IST} + {3825622800 3600 0 IST} + {3844371600 0 1 IST} + {3857677200 3600 0 IST} + {3875821200 0 1 IST} + {3889126800 3600 0 IST} + {3907270800 0 1 IST} + {3920576400 3600 0 IST} + {3939325200 0 1 IST} + {3952026000 3600 0 IST} + {3970774800 0 1 IST} + {3983475600 3600 0 IST} + {4002224400 0 1 IST} + {4015530000 3600 0 IST} + {4033674000 0 1 IST} + {4046979600 3600 0 IST} + {4065123600 0 1 IST} + {4078429200 3600 0 IST} + {4096573200 0 1 IST} } diff --git a/library/tzdata/Europe/Lisbon b/library/tzdata/Europe/Lisbon index 7168f96..b566b51 100644 --- a/library/tzdata/Europe/Lisbon +++ b/library/tzdata/Europe/Lisbon @@ -3,7 +3,7 @@ set TZData(:Europe/Lisbon) { {-9223372036854775808 -2205 0 LMT} {-2713908195 -2205 0 LMT} - {-1830381795 0 0 WET} + {-1830384000 0 0 WET} {-1689555600 3600 1 WEST} {-1677801600 0 0 WET} {-1667437200 3600 1 WEST} diff --git a/library/tzdata/Europe/Prague b/library/tzdata/Europe/Prague index 222b1ae..34df8ed 100644 --- a/library/tzdata/Europe/Prague +++ b/library/tzdata/Europe/Prague @@ -15,11 +15,14 @@ set TZData(:Europe/Prague) { {-844556400 7200 1 CEST} {-828226800 3600 0 CET} {-812502000 7200 1 CEST} - {-798073200 3600 0 CET} - {-780534000 7200 1 CEST} - {-761180400 3600 0 CET} + {-796777200 3600 0 CET} + {-781052400 7200 1 CEST} + {-777862800 7200 0 CEST} + {-765327600 3600 0 CET} {-746578800 7200 1 CEST} {-733359600 3600 0 CET} + {-728517600 0 1 GMT} + {-721260000 0 0 CET} {-716425200 7200 1 CEST} {-701910000 3600 0 CET} {-684975600 7200 1 CEST} diff --git a/library/tzdata/Indian/Mauritius b/library/tzdata/Indian/Mauritius index 2a7a0b1..4c9a051 100644 --- a/library/tzdata/Indian/Mauritius +++ b/library/tzdata/Indian/Mauritius @@ -3,8 +3,8 @@ set TZData(:Indian/Mauritius) { {-9223372036854775808 13800 0 LMT} {-1988164200 14400 0 +04} - {403041600 18000 1 +05} + {403041600 18000 1 +04} {417034800 14400 0 +04} - {1224972000 18000 1 +05} + {1224972000 18000 1 +04} {1238274000 14400 0 +04} } diff --git a/library/tzdata/Pacific/Apia b/library/tzdata/Pacific/Apia index 4c0d84a..4fc91f4 100644 --- a/library/tzdata/Pacific/Apia +++ b/library/tzdata/Pacific/Apia @@ -4,185 +4,185 @@ set TZData(:Pacific/Apia) { {-9223372036854775808 45184 0 LMT} {-2445424384 -41216 0 LMT} {-1861878784 -41400 0 -1130} - {-631110600 -39600 0 -10} - {1285498800 -36000 1 -10} - {1301752800 -39600 0 -10} - {1316872800 -36000 1 -10} - {1325239200 50400 0 +14} - {1333202400 46800 0 +14} - {1348927200 50400 1 +14} - {1365256800 46800 0 +14} - {1380376800 50400 1 +14} - {1396706400 46800 0 +14} - {1411826400 50400 1 +14} - {1428156000 46800 0 +14} - {1443276000 50400 1 +14} - {1459605600 46800 0 +14} - {1474725600 50400 1 +14} - {1491055200 46800 0 +14} - {1506175200 50400 1 +14} - {1522504800 46800 0 +14} - {1538229600 50400 1 +14} - {1554559200 46800 0 +14} - {1569679200 50400 1 +14} - {1586008800 46800 0 +14} - {1601128800 50400 1 +14} - {1617458400 46800 0 +14} - {1632578400 50400 1 +14} - {1648908000 46800 0 +14} - {1664028000 50400 1 +14} - {1680357600 46800 0 +14} - {1695477600 50400 1 +14} - {1712412000 46800 0 +14} - {1727532000 50400 1 +14} - {1743861600 46800 0 +14} - {1758981600 50400 1 +14} - {1775311200 46800 0 +14} - {1790431200 50400 1 +14} - {1806760800 46800 0 +14} - {1821880800 50400 1 +14} - {1838210400 46800 0 +14} - {1853330400 50400 1 +14} - {1869660000 46800 0 +14} - {1885384800 50400 1 +14} - {1901714400 46800 0 +14} - {1916834400 50400 1 +14} - {1933164000 46800 0 +14} - {1948284000 50400 1 +14} - {1964613600 46800 0 +14} - {1979733600 50400 1 +14} - {1996063200 46800 0 +14} - {2011183200 50400 1 +14} - {2027512800 46800 0 +14} - {2042632800 50400 1 +14} - {2058962400 46800 0 +14} - {2074687200 50400 1 +14} - {2091016800 46800 0 +14} - {2106136800 50400 1 +14} - {2122466400 46800 0 +14} - {2137586400 50400 1 +14} - {2153916000 46800 0 +14} - {2169036000 50400 1 +14} - {2185365600 46800 0 +14} - {2200485600 50400 1 +14} - {2216815200 46800 0 +14} - {2232540000 50400 1 +14} - {2248869600 46800 0 +14} - {2263989600 50400 1 +14} - {2280319200 46800 0 +14} - {2295439200 50400 1 +14} - {2311768800 46800 0 +14} - {2326888800 50400 1 +14} - {2343218400 46800 0 +14} - {2358338400 50400 1 +14} - {2374668000 46800 0 +14} - {2389788000 50400 1 +14} - {2406117600 46800 0 +14} - {2421842400 50400 1 +14} - {2438172000 46800 0 +14} - {2453292000 50400 1 +14} - {2469621600 46800 0 +14} - {2484741600 50400 1 +14} - {2501071200 46800 0 +14} - {2516191200 50400 1 +14} - {2532520800 46800 0 +14} - {2547640800 50400 1 +14} - {2563970400 46800 0 +14} - {2579090400 50400 1 +14} - {2596024800 46800 0 +14} - {2611144800 50400 1 +14} - {2627474400 46800 0 +14} - {2642594400 50400 1 +14} - {2658924000 46800 0 +14} - {2674044000 50400 1 +14} - {2690373600 46800 0 +14} - {2705493600 50400 1 +14} - {2721823200 46800 0 +14} - {2736943200 50400 1 +14} - {2753272800 46800 0 +14} - {2768997600 50400 1 +14} - {2785327200 46800 0 +14} - {2800447200 50400 1 +14} - {2816776800 46800 0 +14} - {2831896800 50400 1 +14} - {2848226400 46800 0 +14} - {2863346400 50400 1 +14} - {2879676000 46800 0 +14} - {2894796000 50400 1 +14} - {2911125600 46800 0 +14} - {2926245600 50400 1 +14} - {2942575200 46800 0 +14} - {2958300000 50400 1 +14} - {2974629600 46800 0 +14} - {2989749600 50400 1 +14} - {3006079200 46800 0 +14} - {3021199200 50400 1 +14} - {3037528800 46800 0 +14} - {3052648800 50400 1 +14} - {3068978400 46800 0 +14} - {3084098400 50400 1 +14} - {3100428000 46800 0 +14} - {3116152800 50400 1 +14} - {3132482400 46800 0 +14} - {3147602400 50400 1 +14} - {3163932000 46800 0 +14} - {3179052000 50400 1 +14} - {3195381600 46800 0 +14} - {3210501600 50400 1 +14} - {3226831200 46800 0 +14} - {3241951200 50400 1 +14} - {3258280800 46800 0 +14} - {3273400800 50400 1 +14} - {3289730400 46800 0 +14} - {3305455200 50400 1 +14} - {3321784800 46800 0 +14} - {3336904800 50400 1 +14} - {3353234400 46800 0 +14} - {3368354400 50400 1 +14} - {3384684000 46800 0 +14} - {3399804000 50400 1 +14} - {3416133600 46800 0 +14} - {3431253600 50400 1 +14} - {3447583200 46800 0 +14} - {3462703200 50400 1 +14} - {3479637600 46800 0 +14} - {3494757600 50400 1 +14} - {3511087200 46800 0 +14} - {3526207200 50400 1 +14} - {3542536800 46800 0 +14} - {3557656800 50400 1 +14} - {3573986400 46800 0 +14} - {3589106400 50400 1 +14} - {3605436000 46800 0 +14} - {3620556000 50400 1 +14} - {3636885600 46800 0 +14} - {3652610400 50400 1 +14} - {3668940000 46800 0 +14} - {3684060000 50400 1 +14} - {3700389600 46800 0 +14} - {3715509600 50400 1 +14} - {3731839200 46800 0 +14} - {3746959200 50400 1 +14} - {3763288800 46800 0 +14} - {3778408800 50400 1 +14} - {3794738400 46800 0 +14} - {3809858400 50400 1 +14} - {3826188000 46800 0 +14} - {3841912800 50400 1 +14} - {3858242400 46800 0 +14} - {3873362400 50400 1 +14} - {3889692000 46800 0 +14} - {3904812000 50400 1 +14} - {3921141600 46800 0 +14} - {3936261600 50400 1 +14} - {3952591200 46800 0 +14} - {3967711200 50400 1 +14} - {3984040800 46800 0 +14} - {3999765600 50400 1 +14} - {4016095200 46800 0 +14} - {4031215200 50400 1 +14} - {4047544800 46800 0 +14} - {4062664800 50400 1 +14} - {4078994400 46800 0 +14} - {4094114400 50400 1 +14} + {-631110600 -39600 0 -11} + {1285498800 -36000 1 -11} + {1301752800 -39600 0 -11} + {1316872800 -36000 1 -11} + {1325239200 50400 0 +13} + {1333202400 46800 0 +13} + {1348927200 50400 1 +13} + {1365256800 46800 0 +13} + {1380376800 50400 1 +13} + {1396706400 46800 0 +13} + {1411826400 50400 1 +13} + {1428156000 46800 0 +13} + {1443276000 50400 1 +13} + {1459605600 46800 0 +13} + {1474725600 50400 1 +13} + {1491055200 46800 0 +13} + {1506175200 50400 1 +13} + {1522504800 46800 0 +13} + {1538229600 50400 1 +13} + {1554559200 46800 0 +13} + {1569679200 50400 1 +13} + {1586008800 46800 0 +13} + {1601128800 50400 1 +13} + {1617458400 46800 0 +13} + {1632578400 50400 1 +13} + {1648908000 46800 0 +13} + {1664028000 50400 1 +13} + {1680357600 46800 0 +13} + {1695477600 50400 1 +13} + {1712412000 46800 0 +13} + {1727532000 50400 1 +13} + {1743861600 46800 0 +13} + {1758981600 50400 1 +13} + {1775311200 46800 0 +13} + {1790431200 50400 1 +13} + {1806760800 46800 0 +13} + {1821880800 50400 1 +13} + {1838210400 46800 0 +13} + {1853330400 50400 1 +13} + {1869660000 46800 0 +13} + {1885384800 50400 1 +13} + {1901714400 46800 0 +13} + {1916834400 50400 1 +13} + {1933164000 46800 0 +13} + {1948284000 50400 1 +13} + {1964613600 46800 0 +13} + {1979733600 50400 1 +13} + {1996063200 46800 0 +13} + {2011183200 50400 1 +13} + {2027512800 46800 0 +13} + {2042632800 50400 1 +13} + {2058962400 46800 0 +13} + {2074687200 50400 1 +13} + {2091016800 46800 0 +13} + {2106136800 50400 1 +13} + {2122466400 46800 0 +13} + {2137586400 50400 1 +13} + {2153916000 46800 0 +13} + {2169036000 50400 1 +13} + {2185365600 46800 0 +13} + {2200485600 50400 1 +13} + {2216815200 46800 0 +13} + {2232540000 50400 1 +13} + {2248869600 46800 0 +13} + {2263989600 50400 1 +13} + {2280319200 46800 0 +13} + {2295439200 50400 1 +13} + {2311768800 46800 0 +13} + {2326888800 50400 1 +13} + {2343218400 46800 0 +13} + {2358338400 50400 1 +13} + {2374668000 46800 0 +13} + {2389788000 50400 1 +13} + {2406117600 46800 0 +13} + {2421842400 50400 1 +13} + {2438172000 46800 0 +13} + {2453292000 50400 1 +13} + {2469621600 46800 0 +13} + {2484741600 50400 1 +13} + {2501071200 46800 0 +13} + {2516191200 50400 1 +13} + {2532520800 46800 0 +13} + {2547640800 50400 1 +13} + {2563970400 46800 0 +13} + {2579090400 50400 1 +13} + {2596024800 46800 0 +13} + {2611144800 50400 1 +13} + {2627474400 46800 0 +13} + {2642594400 50400 1 +13} + {2658924000 46800 0 +13} + {2674044000 50400 1 +13} + {2690373600 46800 0 +13} + {2705493600 50400 1 +13} + {2721823200 46800 0 +13} + {2736943200 50400 1 +13} + {2753272800 46800 0 +13} + {2768997600 50400 1 +13} + {2785327200 46800 0 +13} + {2800447200 50400 1 +13} + {2816776800 46800 0 +13} + {2831896800 50400 1 +13} + {2848226400 46800 0 +13} + {2863346400 50400 1 +13} + {2879676000 46800 0 +13} + {2894796000 50400 1 +13} + {2911125600 46800 0 +13} + {2926245600 50400 1 +13} + {2942575200 46800 0 +13} + {2958300000 50400 1 +13} + {2974629600 46800 0 +13} + {2989749600 50400 1 +13} + {3006079200 46800 0 +13} + {3021199200 50400 1 +13} + {3037528800 46800 0 +13} + {3052648800 50400 1 +13} + {3068978400 46800 0 +13} + {3084098400 50400 1 +13} + {3100428000 46800 0 +13} + {3116152800 50400 1 +13} + {3132482400 46800 0 +13} + {3147602400 50400 1 +13} + {3163932000 46800 0 +13} + {3179052000 50400 1 +13} + {3195381600 46800 0 +13} + {3210501600 50400 1 +13} + {3226831200 46800 0 +13} + {3241951200 50400 1 +13} + {3258280800 46800 0 +13} + {3273400800 50400 1 +13} + {3289730400 46800 0 +13} + {3305455200 50400 1 +13} + {3321784800 46800 0 +13} + {3336904800 50400 1 +13} + {3353234400 46800 0 +13} + {3368354400 50400 1 +13} + {3384684000 46800 0 +13} + {3399804000 50400 1 +13} + {3416133600 46800 0 +13} + {3431253600 50400 1 +13} + {3447583200 46800 0 +13} + {3462703200 50400 1 +13} + {3479637600 46800 0 +13} + {3494757600 50400 1 +13} + {3511087200 46800 0 +13} + {3526207200 50400 1 +13} + {3542536800 46800 0 +13} + {3557656800 50400 1 +13} + {3573986400 46800 0 +13} + {3589106400 50400 1 +13} + {3605436000 46800 0 +13} + {3620556000 50400 1 +13} + {3636885600 46800 0 +13} + {3652610400 50400 1 +13} + {3668940000 46800 0 +13} + {3684060000 50400 1 +13} + {3700389600 46800 0 +13} + {3715509600 50400 1 +13} + {3731839200 46800 0 +13} + {3746959200 50400 1 +13} + {3763288800 46800 0 +13} + {3778408800 50400 1 +13} + {3794738400 46800 0 +13} + {3809858400 50400 1 +13} + {3826188000 46800 0 +13} + {3841912800 50400 1 +13} + {3858242400 46800 0 +13} + {3873362400 50400 1 +13} + {3889692000 46800 0 +13} + {3904812000 50400 1 +13} + {3921141600 46800 0 +13} + {3936261600 50400 1 +13} + {3952591200 46800 0 +13} + {3967711200 50400 1 +13} + {3984040800 46800 0 +13} + {3999765600 50400 1 +13} + {4016095200 46800 0 +13} + {4031215200 50400 1 +13} + {4047544800 46800 0 +13} + {4062664800 50400 1 +13} + {4078994400 46800 0 +13} + {4094114400 50400 1 +13} } diff --git a/library/tzdata/Pacific/Chatham b/library/tzdata/Pacific/Chatham index 5d39879..6c1ab19 100644 --- a/library/tzdata/Pacific/Chatham +++ b/library/tzdata/Pacific/Chatham @@ -3,256 +3,256 @@ set TZData(:Pacific/Chatham) { {-9223372036854775808 44028 0 LMT} {-3192437628 44100 0 +1215} - {-757426500 45900 0 +1345} - {152632800 49500 1 +1345} - {162309600 45900 0 +1345} - {183477600 49500 1 +1345} - {194968800 45900 0 +1345} - {215532000 49500 1 +1345} - {226418400 45900 0 +1345} - {246981600 49500 1 +1345} - {257868000 45900 0 +1345} - {278431200 49500 1 +1345} - {289317600 45900 0 +1345} - {309880800 49500 1 +1345} - {320767200 45900 0 +1345} - {341330400 49500 1 +1345} - {352216800 45900 0 +1345} - {372780000 49500 1 +1345} - {384271200 45900 0 +1345} - {404834400 49500 1 +1345} - {415720800 45900 0 +1345} - {436284000 49500 1 +1345} - {447170400 45900 0 +1345} - {467733600 49500 1 +1345} - {478620000 45900 0 +1345} - {499183200 49500 1 +1345} - {510069600 45900 0 +1345} - {530632800 49500 1 +1345} - {541519200 45900 0 +1345} - {562082400 49500 1 +1345} - {573573600 45900 0 +1345} - {594136800 49500 1 +1345} - {605023200 45900 0 +1345} - {623772000 49500 1 +1345} - {637682400 45900 0 +1345} - {655221600 49500 1 +1345} - {669132000 45900 0 +1345} - {686671200 49500 1 +1345} - {700581600 45900 0 +1345} - {718120800 49500 1 +1345} - {732636000 45900 0 +1345} - {749570400 49500 1 +1345} - {764085600 45900 0 +1345} - {781020000 49500 1 +1345} - {795535200 45900 0 +1345} - {812469600 49500 1 +1345} - {826984800 45900 0 +1345} - {844524000 49500 1 +1345} - {858434400 45900 0 +1345} - {875973600 49500 1 +1345} - {889884000 45900 0 +1345} - {907423200 49500 1 +1345} - {921938400 45900 0 +1345} - {938872800 49500 1 +1345} - {953388000 45900 0 +1345} - {970322400 49500 1 +1345} - {984837600 45900 0 +1345} - {1002376800 49500 1 +1345} - {1016287200 45900 0 +1345} - {1033826400 49500 1 +1345} - {1047736800 45900 0 +1345} - {1065276000 49500 1 +1345} - {1079791200 45900 0 +1345} - {1096725600 49500 1 +1345} - {1111240800 45900 0 +1345} - {1128175200 49500 1 +1345} - {1142690400 45900 0 +1345} - {1159624800 49500 1 +1345} - {1174140000 45900 0 +1345} - {1191074400 49500 1 +1345} - {1207404000 45900 0 +1345} - {1222524000 49500 1 +1345} - {1238853600 45900 0 +1345} - {1253973600 49500 1 +1345} - {1270303200 45900 0 +1345} - {1285423200 49500 1 +1345} - {1301752800 45900 0 +1345} - {1316872800 49500 1 +1345} - {1333202400 45900 0 +1345} - {1348927200 49500 1 +1345} - {1365256800 45900 0 +1345} - {1380376800 49500 1 +1345} - {1396706400 45900 0 +1345} - {1411826400 49500 1 +1345} - {1428156000 45900 0 +1345} - {1443276000 49500 1 +1345} - {1459605600 45900 0 +1345} - {1474725600 49500 1 +1345} - {1491055200 45900 0 +1345} - {1506175200 49500 1 +1345} - {1522504800 45900 0 +1345} - {1538229600 49500 1 +1345} - {1554559200 45900 0 +1345} - {1569679200 49500 1 +1345} - {1586008800 45900 0 +1345} - {1601128800 49500 1 +1345} - {1617458400 45900 0 +1345} - {1632578400 49500 1 +1345} - {1648908000 45900 0 +1345} - {1664028000 49500 1 +1345} - {1680357600 45900 0 +1345} - {1695477600 49500 1 +1345} - {1712412000 45900 0 +1345} - {1727532000 49500 1 +1345} - {1743861600 45900 0 +1345} - {1758981600 49500 1 +1345} - {1775311200 45900 0 +1345} - {1790431200 49500 1 +1345} - {1806760800 45900 0 +1345} - {1821880800 49500 1 +1345} - {1838210400 45900 0 +1345} - {1853330400 49500 1 +1345} - {1869660000 45900 0 +1345} - {1885384800 49500 1 +1345} - {1901714400 45900 0 +1345} - {1916834400 49500 1 +1345} - {1933164000 45900 0 +1345} - {1948284000 49500 1 +1345} - {1964613600 45900 0 +1345} - {1979733600 49500 1 +1345} - {1996063200 45900 0 +1345} - {2011183200 49500 1 +1345} - {2027512800 45900 0 +1345} - {2042632800 49500 1 +1345} - {2058962400 45900 0 +1345} - {2074687200 49500 1 +1345} - {2091016800 45900 0 +1345} - {2106136800 49500 1 +1345} - {2122466400 45900 0 +1345} - {2137586400 49500 1 +1345} - {2153916000 45900 0 +1345} - {2169036000 49500 1 +1345} - {2185365600 45900 0 +1345} - {2200485600 49500 1 +1345} - {2216815200 45900 0 +1345} - {2232540000 49500 1 +1345} - {2248869600 45900 0 +1345} - {2263989600 49500 1 +1345} - {2280319200 45900 0 +1345} - {2295439200 49500 1 +1345} - {2311768800 45900 0 +1345} - {2326888800 49500 1 +1345} - {2343218400 45900 0 +1345} - {2358338400 49500 1 +1345} - {2374668000 45900 0 +1345} - {2389788000 49500 1 +1345} - {2406117600 45900 0 +1345} - {2421842400 49500 1 +1345} - {2438172000 45900 0 +1345} - {2453292000 49500 1 +1345} - {2469621600 45900 0 +1345} - {2484741600 49500 1 +1345} - {2501071200 45900 0 +1345} - {2516191200 49500 1 +1345} - {2532520800 45900 0 +1345} - {2547640800 49500 1 +1345} - {2563970400 45900 0 +1345} - {2579090400 49500 1 +1345} - {2596024800 45900 0 +1345} - {2611144800 49500 1 +1345} - {2627474400 45900 0 +1345} - {2642594400 49500 1 +1345} - {2658924000 45900 0 +1345} - {2674044000 49500 1 +1345} - {2690373600 45900 0 +1345} - {2705493600 49500 1 +1345} - {2721823200 45900 0 +1345} - {2736943200 49500 1 +1345} - {2753272800 45900 0 +1345} - {2768997600 49500 1 +1345} - {2785327200 45900 0 +1345} - {2800447200 49500 1 +1345} - {2816776800 45900 0 +1345} - {2831896800 49500 1 +1345} - {2848226400 45900 0 +1345} - {2863346400 49500 1 +1345} - {2879676000 45900 0 +1345} - {2894796000 49500 1 +1345} - {2911125600 45900 0 +1345} - {2926245600 49500 1 +1345} - {2942575200 45900 0 +1345} - {2958300000 49500 1 +1345} - {2974629600 45900 0 +1345} - {2989749600 49500 1 +1345} - {3006079200 45900 0 +1345} - {3021199200 49500 1 +1345} - {3037528800 45900 0 +1345} - {3052648800 49500 1 +1345} - {3068978400 45900 0 +1345} - {3084098400 49500 1 +1345} - {3100428000 45900 0 +1345} - {3116152800 49500 1 +1345} - {3132482400 45900 0 +1345} - {3147602400 49500 1 +1345} - {3163932000 45900 0 +1345} - {3179052000 49500 1 +1345} - {3195381600 45900 0 +1345} - {3210501600 49500 1 +1345} - {3226831200 45900 0 +1345} - {3241951200 49500 1 +1345} - {3258280800 45900 0 +1345} - {3273400800 49500 1 +1345} - {3289730400 45900 0 +1345} - {3305455200 49500 1 +1345} - {3321784800 45900 0 +1345} - {3336904800 49500 1 +1345} - {3353234400 45900 0 +1345} - {3368354400 49500 1 +1345} - {3384684000 45900 0 +1345} - {3399804000 49500 1 +1345} - {3416133600 45900 0 +1345} - {3431253600 49500 1 +1345} - {3447583200 45900 0 +1345} - {3462703200 49500 1 +1345} - {3479637600 45900 0 +1345} - {3494757600 49500 1 +1345} - {3511087200 45900 0 +1345} - {3526207200 49500 1 +1345} - {3542536800 45900 0 +1345} - {3557656800 49500 1 +1345} - {3573986400 45900 0 +1345} - {3589106400 49500 1 +1345} - {3605436000 45900 0 +1345} - {3620556000 49500 1 +1345} - {3636885600 45900 0 +1345} - {3652610400 49500 1 +1345} - {3668940000 45900 0 +1345} - {3684060000 49500 1 +1345} - {3700389600 45900 0 +1345} - {3715509600 49500 1 +1345} - {3731839200 45900 0 +1345} - {3746959200 49500 1 +1345} - {3763288800 45900 0 +1345} - {3778408800 49500 1 +1345} - {3794738400 45900 0 +1345} - {3809858400 49500 1 +1345} - {3826188000 45900 0 +1345} - {3841912800 49500 1 +1345} - {3858242400 45900 0 +1345} - {3873362400 49500 1 +1345} - {3889692000 45900 0 +1345} - {3904812000 49500 1 +1345} - {3921141600 45900 0 +1345} - {3936261600 49500 1 +1345} - {3952591200 45900 0 +1345} - {3967711200 49500 1 +1345} - {3984040800 45900 0 +1345} - {3999765600 49500 1 +1345} - {4016095200 45900 0 +1345} - {4031215200 49500 1 +1345} - {4047544800 45900 0 +1345} - {4062664800 49500 1 +1345} - {4078994400 45900 0 +1345} - {4094114400 49500 1 +1345} + {-757426500 45900 0 +1245} + {152632800 49500 1 +1245} + {162309600 45900 0 +1245} + {183477600 49500 1 +1245} + {194968800 45900 0 +1245} + {215532000 49500 1 +1245} + {226418400 45900 0 +1245} + {246981600 49500 1 +1245} + {257868000 45900 0 +1245} + {278431200 49500 1 +1245} + {289317600 45900 0 +1245} + {309880800 49500 1 +1245} + {320767200 45900 0 +1245} + {341330400 49500 1 +1245} + {352216800 45900 0 +1245} + {372780000 49500 1 +1245} + {384271200 45900 0 +1245} + {404834400 49500 1 +1245} + {415720800 45900 0 +1245} + {436284000 49500 1 +1245} + {447170400 45900 0 +1245} + {467733600 49500 1 +1245} + {478620000 45900 0 +1245} + {499183200 49500 1 +1245} + {510069600 45900 0 +1245} + {530632800 49500 1 +1245} + {541519200 45900 0 +1245} + {562082400 49500 1 +1245} + {573573600 45900 0 +1245} + {594136800 49500 1 +1245} + {605023200 45900 0 +1245} + {623772000 49500 1 +1245} + {637682400 45900 0 +1245} + {655221600 49500 1 +1245} + {669132000 45900 0 +1245} + {686671200 49500 1 +1245} + {700581600 45900 0 +1245} + {718120800 49500 1 +1245} + {732636000 45900 0 +1245} + {749570400 49500 1 +1245} + {764085600 45900 0 +1245} + {781020000 49500 1 +1245} + {795535200 45900 0 +1245} + {812469600 49500 1 +1245} + {826984800 45900 0 +1245} + {844524000 49500 1 +1245} + {858434400 45900 0 +1245} + {875973600 49500 1 +1245} + {889884000 45900 0 +1245} + {907423200 49500 1 +1245} + {921938400 45900 0 +1245} + {938872800 49500 1 +1245} + {953388000 45900 0 +1245} + {970322400 49500 1 +1245} + {984837600 45900 0 +1245} + {1002376800 49500 1 +1245} + {1016287200 45900 0 +1245} + {1033826400 49500 1 +1245} + {1047736800 45900 0 +1245} + {1065276000 49500 1 +1245} + {1079791200 45900 0 +1245} + {1096725600 49500 1 +1245} + {1111240800 45900 0 +1245} + {1128175200 49500 1 +1245} + {1142690400 45900 0 +1245} + {1159624800 49500 1 +1245} + {1174140000 45900 0 +1245} + {1191074400 49500 1 +1245} + {1207404000 45900 0 +1245} + {1222524000 49500 1 +1245} + {1238853600 45900 0 +1245} + {1253973600 49500 1 +1245} + {1270303200 45900 0 +1245} + {1285423200 49500 1 +1245} + {1301752800 45900 0 +1245} + {1316872800 49500 1 +1245} + {1333202400 45900 0 +1245} + {1348927200 49500 1 +1245} + {1365256800 45900 0 +1245} + {1380376800 49500 1 +1245} + {1396706400 45900 0 +1245} + {1411826400 49500 1 +1245} + {1428156000 45900 0 +1245} + {1443276000 49500 1 +1245} + {1459605600 45900 0 +1245} + {1474725600 49500 1 +1245} + {1491055200 45900 0 +1245} + {1506175200 49500 1 +1245} + {1522504800 45900 0 +1245} + {1538229600 49500 1 +1245} + {1554559200 45900 0 +1245} + {1569679200 49500 1 +1245} + {1586008800 45900 0 +1245} + {1601128800 49500 1 +1245} + {1617458400 45900 0 +1245} + {1632578400 49500 1 +1245} + {1648908000 45900 0 +1245} + {1664028000 49500 1 +1245} + {1680357600 45900 0 +1245} + {1695477600 49500 1 +1245} + {1712412000 45900 0 +1245} + {1727532000 49500 1 +1245} + {1743861600 45900 0 +1245} + {1758981600 49500 1 +1245} + {1775311200 45900 0 +1245} + {1790431200 49500 1 +1245} + {1806760800 45900 0 +1245} + {1821880800 49500 1 +1245} + {1838210400 45900 0 +1245} + {1853330400 49500 1 +1245} + {1869660000 45900 0 +1245} + {1885384800 49500 1 +1245} + {1901714400 45900 0 +1245} + {1916834400 49500 1 +1245} + {1933164000 45900 0 +1245} + {1948284000 49500 1 +1245} + {1964613600 45900 0 +1245} + {1979733600 49500 1 +1245} + {1996063200 45900 0 +1245} + {2011183200 49500 1 +1245} + {2027512800 45900 0 +1245} + {2042632800 49500 1 +1245} + {2058962400 45900 0 +1245} + {2074687200 49500 1 +1245} + {2091016800 45900 0 +1245} + {2106136800 49500 1 +1245} + {2122466400 45900 0 +1245} + {2137586400 49500 1 +1245} + {2153916000 45900 0 +1245} + {2169036000 49500 1 +1245} + {2185365600 45900 0 +1245} + {2200485600 49500 1 +1245} + {2216815200 45900 0 +1245} + {2232540000 49500 1 +1245} + {2248869600 45900 0 +1245} + {2263989600 49500 1 +1245} + {2280319200 45900 0 +1245} + {2295439200 49500 1 +1245} + {2311768800 45900 0 +1245} + {2326888800 49500 1 +1245} + {2343218400 45900 0 +1245} + {2358338400 49500 1 +1245} + {2374668000 45900 0 +1245} + {2389788000 49500 1 +1245} + {2406117600 45900 0 +1245} + {2421842400 49500 1 +1245} + {2438172000 45900 0 +1245} + {2453292000 49500 1 +1245} + {2469621600 45900 0 +1245} + {2484741600 49500 1 +1245} + {2501071200 45900 0 +1245} + {2516191200 49500 1 +1245} + {2532520800 45900 0 +1245} + {2547640800 49500 1 +1245} + {2563970400 45900 0 +1245} + {2579090400 49500 1 +1245} + {2596024800 45900 0 +1245} + {2611144800 49500 1 +1245} + {2627474400 45900 0 +1245} + {2642594400 49500 1 +1245} + {2658924000 45900 0 +1245} + {2674044000 49500 1 +1245} + {2690373600 45900 0 +1245} + {2705493600 49500 1 +1245} + {2721823200 45900 0 +1245} + {2736943200 49500 1 +1245} + {2753272800 45900 0 +1245} + {2768997600 49500 1 +1245} + {2785327200 45900 0 +1245} + {2800447200 49500 1 +1245} + {2816776800 45900 0 +1245} + {2831896800 49500 1 +1245} + {2848226400 45900 0 +1245} + {2863346400 49500 1 +1245} + {2879676000 45900 0 +1245} + {2894796000 49500 1 +1245} + {2911125600 45900 0 +1245} + {2926245600 49500 1 +1245} + {2942575200 45900 0 +1245} + {2958300000 49500 1 +1245} + {2974629600 45900 0 +1245} + {2989749600 49500 1 +1245} + {3006079200 45900 0 +1245} + {3021199200 49500 1 +1245} + {3037528800 45900 0 +1245} + {3052648800 49500 1 +1245} + {3068978400 45900 0 +1245} + {3084098400 49500 1 +1245} + {3100428000 45900 0 +1245} + {3116152800 49500 1 +1245} + {3132482400 45900 0 +1245} + {3147602400 49500 1 +1245} + {3163932000 45900 0 +1245} + {3179052000 49500 1 +1245} + {3195381600 45900 0 +1245} + {3210501600 49500 1 +1245} + {3226831200 45900 0 +1245} + {3241951200 49500 1 +1245} + {3258280800 45900 0 +1245} + {3273400800 49500 1 +1245} + {3289730400 45900 0 +1245} + {3305455200 49500 1 +1245} + {3321784800 45900 0 +1245} + {3336904800 49500 1 +1245} + {3353234400 45900 0 +1245} + {3368354400 49500 1 +1245} + {3384684000 45900 0 +1245} + {3399804000 49500 1 +1245} + {3416133600 45900 0 +1245} + {3431253600 49500 1 +1245} + {3447583200 45900 0 +1245} + {3462703200 49500 1 +1245} + {3479637600 45900 0 +1245} + {3494757600 49500 1 +1245} + {3511087200 45900 0 +1245} + {3526207200 49500 1 +1245} + {3542536800 45900 0 +1245} + {3557656800 49500 1 +1245} + {3573986400 45900 0 +1245} + {3589106400 49500 1 +1245} + {3605436000 45900 0 +1245} + {3620556000 49500 1 +1245} + {3636885600 45900 0 +1245} + {3652610400 49500 1 +1245} + {3668940000 45900 0 +1245} + {3684060000 49500 1 +1245} + {3700389600 45900 0 +1245} + {3715509600 49500 1 +1245} + {3731839200 45900 0 +1245} + {3746959200 49500 1 +1245} + {3763288800 45900 0 +1245} + {3778408800 49500 1 +1245} + {3794738400 45900 0 +1245} + {3809858400 49500 1 +1245} + {3826188000 45900 0 +1245} + {3841912800 49500 1 +1245} + {3858242400 45900 0 +1245} + {3873362400 49500 1 +1245} + {3889692000 45900 0 +1245} + {3904812000 49500 1 +1245} + {3921141600 45900 0 +1245} + {3936261600 49500 1 +1245} + {3952591200 45900 0 +1245} + {3967711200 49500 1 +1245} + {3984040800 45900 0 +1245} + {3999765600 49500 1 +1245} + {4016095200 45900 0 +1245} + {4031215200 49500 1 +1245} + {4047544800 45900 0 +1245} + {4062664800 49500 1 +1245} + {4078994400 45900 0 +1245} + {4094114400 49500 1 +1245} } diff --git a/library/tzdata/Pacific/Easter b/library/tzdata/Pacific/Easter index 474a32b..a087cd0 100644 --- a/library/tzdata/Pacific/Easter +++ b/library/tzdata/Pacific/Easter @@ -4,265 +4,265 @@ set TZData(:Pacific/Easter) { {-9223372036854775808 -26248 0 LMT} {-2524495352 -26248 0 EMT} {-1178124152 -25200 0 -07} - {-36619200 -21600 1 -06} + {-36619200 -21600 1 -07} {-23922000 -25200 0 -07} - {-3355200 -21600 1 -06} + {-3355200 -21600 1 -07} {7527600 -25200 0 -07} - {24465600 -21600 1 -06} + {24465600 -21600 1 -07} {37767600 -25200 0 -07} - {55915200 -21600 1 -06} + {55915200 -21600 1 -07} {69217200 -25200 0 -07} - {87969600 -21600 1 -06} + {87969600 -21600 1 -07} {100666800 -25200 0 -07} - {118209600 -21600 1 -06} + {118209600 -21600 1 -07} {132116400 -25200 0 -07} - {150868800 -21600 1 -06} + {150868800 -21600 1 -07} {163566000 -25200 0 -07} - {182318400 -21600 1 -06} + {182318400 -21600 1 -07} {195620400 -25200 0 -07} - {213768000 -21600 1 -06} + {213768000 -21600 1 -07} {227070000 -25200 0 -07} - {245217600 -21600 1 -06} + {245217600 -21600 1 -07} {258519600 -25200 0 -07} - {277272000 -21600 1 -06} + {277272000 -21600 1 -07} {289969200 -25200 0 -07} - {308721600 -21600 1 -06} + {308721600 -21600 1 -07} {321418800 -25200 0 -07} - {340171200 -21600 1 -06} + {340171200 -21600 1 -07} {353473200 -25200 0 -07} - {371620800 -21600 1 -06} + {371620800 -21600 1 -07} {384922800 -21600 0 -06} - {403070400 -18000 1 -05} + {403070400 -18000 1 -06} {416372400 -21600 0 -06} - {434520000 -18000 1 -05} + {434520000 -18000 1 -06} {447822000 -21600 0 -06} - {466574400 -18000 1 -05} + {466574400 -18000 1 -06} {479271600 -21600 0 -06} - {498024000 -18000 1 -05} + {498024000 -18000 1 -06} {510721200 -21600 0 -06} - {529473600 -18000 1 -05} + {529473600 -18000 1 -06} {545194800 -21600 0 -06} - {560923200 -18000 1 -05} + {560923200 -18000 1 -06} {574225200 -21600 0 -06} - {592372800 -18000 1 -05} + {592372800 -18000 1 -06} {605674800 -21600 0 -06} - {624427200 -18000 1 -05} + {624427200 -18000 1 -06} {637124400 -21600 0 -06} - {653457600 -18000 1 -05} + {653457600 -18000 1 -06} {668574000 -21600 0 -06} - {687326400 -18000 1 -05} + {687326400 -18000 1 -06} {700628400 -21600 0 -06} - {718776000 -18000 1 -05} + {718776000 -18000 1 -06} {732078000 -21600 0 -06} - {750225600 -18000 1 -05} + {750225600 -18000 1 -06} {763527600 -21600 0 -06} - {781675200 -18000 1 -05} + {781675200 -18000 1 -06} {794977200 -21600 0 -06} - {813729600 -18000 1 -05} + {813729600 -18000 1 -06} {826426800 -21600 0 -06} - {845179200 -18000 1 -05} + {845179200 -18000 1 -06} {859690800 -21600 0 -06} - {876628800 -18000 1 -05} + {876628800 -18000 1 -06} {889930800 -21600 0 -06} - {906868800 -18000 1 -05} + {906868800 -18000 1 -06} {923194800 -21600 0 -06} - {939528000 -18000 1 -05} + {939528000 -18000 1 -06} {952830000 -21600 0 -06} - {971582400 -18000 1 -05} + {971582400 -18000 1 -06} {984279600 -21600 0 -06} - {1003032000 -18000 1 -05} + {1003032000 -18000 1 -06} {1015729200 -21600 0 -06} - {1034481600 -18000 1 -05} + {1034481600 -18000 1 -06} {1047178800 -21600 0 -06} - {1065931200 -18000 1 -05} + {1065931200 -18000 1 -06} {1079233200 -21600 0 -06} - {1097380800 -18000 1 -05} + {1097380800 -18000 1 -06} {1110682800 -21600 0 -06} - {1128830400 -18000 1 -05} + {1128830400 -18000 1 -06} {1142132400 -21600 0 -06} - {1160884800 -18000 1 -05} + {1160884800 -18000 1 -06} {1173582000 -21600 0 -06} - {1192334400 -18000 1 -05} + {1192334400 -18000 1 -06} {1206846000 -21600 0 -06} - {1223784000 -18000 1 -05} + {1223784000 -18000 1 -06} {1237086000 -21600 0 -06} - {1255233600 -18000 1 -05} + {1255233600 -18000 1 -06} {1270350000 -21600 0 -06} - {1286683200 -18000 1 -05} + {1286683200 -18000 1 -06} {1304823600 -21600 0 -06} - {1313899200 -18000 1 -05} + {1313899200 -18000 1 -06} {1335668400 -21600 0 -06} - {1346558400 -18000 1 -05} + {1346558400 -18000 1 -06} {1367118000 -21600 0 -06} - {1378612800 -18000 1 -05} + {1378612800 -18000 1 -06} {1398567600 -21600 0 -06} - {1410062400 -18000 1 -05} + {1410062400 -18000 1 -06} {1463281200 -21600 0 -06} - {1471147200 -18000 1 -05} + {1471147200 -18000 1 -06} {1494730800 -21600 0 -06} - {1502596800 -18000 1 -05} + {1502596800 -18000 1 -06} {1526180400 -21600 0 -06} - {1534046400 -18000 1 -05} + {1534046400 -18000 1 -06} {1557630000 -21600 0 -06} - {1565496000 -18000 1 -05} + {1565496000 -18000 1 -06} {1589079600 -21600 0 -06} - {1596945600 -18000 1 -05} + {1596945600 -18000 1 -06} {1620529200 -21600 0 -06} - {1629000000 -18000 1 -05} + {1629000000 -18000 1 -06} {1652583600 -21600 0 -06} - {1660449600 -18000 1 -05} + {1660449600 -18000 1 -06} {1684033200 -21600 0 -06} - {1691899200 -18000 1 -05} + {1691899200 -18000 1 -06} {1715482800 -21600 0 -06} - {1723348800 -18000 1 -05} + {1723348800 -18000 1 -06} {1746932400 -21600 0 -06} - {1754798400 -18000 1 -05} + {1754798400 -18000 1 -06} {1778382000 -21600 0 -06} - {1786248000 -18000 1 -05} + {1786248000 -18000 1 -06} {1809831600 -21600 0 -06} - {1818302400 -18000 1 -05} + {1818302400 -18000 1 -06} {1841886000 -21600 0 -06} - {1849752000 -18000 1 -05} + {1849752000 -18000 1 -06} {1873335600 -21600 0 -06} - {1881201600 -18000 1 -05} + {1881201600 -18000 1 -06} {1904785200 -21600 0 -06} - {1912651200 -18000 1 -05} + {1912651200 -18000 1 -06} {1936234800 -21600 0 -06} - {1944100800 -18000 1 -05} + {1944100800 -18000 1 -06} {1967684400 -21600 0 -06} - {1976155200 -18000 1 -05} + {1976155200 -18000 1 -06} {1999738800 -21600 0 -06} - {2007604800 -18000 1 -05} + {2007604800 -18000 1 -06} {2031188400 -21600 0 -06} - {2039054400 -18000 1 -05} + {2039054400 -18000 1 -06} {2062638000 -21600 0 -06} - {2070504000 -18000 1 -05} + {2070504000 -18000 1 -06} {2094087600 -21600 0 -06} - {2101953600 -18000 1 -05} + {2101953600 -18000 1 -06} {2125537200 -21600 0 -06} - {2133403200 -18000 1 -05} + {2133403200 -18000 1 -06} {2156986800 -21600 0 -06} - {2165457600 -18000 1 -05} + {2165457600 -18000 1 -06} {2189041200 -21600 0 -06} - {2196907200 -18000 1 -05} + {2196907200 -18000 1 -06} {2220490800 -21600 0 -06} - {2228356800 -18000 1 -05} + {2228356800 -18000 1 -06} {2251940400 -21600 0 -06} - {2259806400 -18000 1 -05} + {2259806400 -18000 1 -06} {2283390000 -21600 0 -06} - {2291256000 -18000 1 -05} + {2291256000 -18000 1 -06} {2314839600 -21600 0 -06} - {2322705600 -18000 1 -05} + {2322705600 -18000 1 -06} {2346894000 -21600 0 -06} - {2354760000 -18000 1 -05} + {2354760000 -18000 1 -06} {2378343600 -21600 0 -06} - {2386209600 -18000 1 -05} + {2386209600 -18000 1 -06} {2409793200 -21600 0 -06} - {2417659200 -18000 1 -05} + {2417659200 -18000 1 -06} {2441242800 -21600 0 -06} - {2449108800 -18000 1 -05} + {2449108800 -18000 1 -06} {2472692400 -21600 0 -06} - {2480558400 -18000 1 -05} + {2480558400 -18000 1 -06} {2504142000 -21600 0 -06} - {2512612800 -18000 1 -05} + {2512612800 -18000 1 -06} {2536196400 -21600 0 -06} - {2544062400 -18000 1 -05} + {2544062400 -18000 1 -06} {2567646000 -21600 0 -06} - {2575512000 -18000 1 -05} + {2575512000 -18000 1 -06} {2599095600 -21600 0 -06} - {2606961600 -18000 1 -05} + {2606961600 -18000 1 -06} {2630545200 -21600 0 -06} - {2638411200 -18000 1 -05} + {2638411200 -18000 1 -06} {2661994800 -21600 0 -06} - {2669860800 -18000 1 -05} + {2669860800 -18000 1 -06} {2693444400 -21600 0 -06} - {2701915200 -18000 1 -05} + {2701915200 -18000 1 -06} {2725498800 -21600 0 -06} - {2733364800 -18000 1 -05} + {2733364800 -18000 1 -06} {2756948400 -21600 0 -06} - {2764814400 -18000 1 -05} + {2764814400 -18000 1 -06} {2788398000 -21600 0 -06} - {2796264000 -18000 1 -05} + {2796264000 -18000 1 -06} {2819847600 -21600 0 -06} - {2827713600 -18000 1 -05} + {2827713600 -18000 1 -06} {2851297200 -21600 0 -06} - {2859768000 -18000 1 -05} + {2859768000 -18000 1 -06} {2883351600 -21600 0 -06} - {2891217600 -18000 1 -05} + {2891217600 -18000 1 -06} {2914801200 -21600 0 -06} - {2922667200 -18000 1 -05} + {2922667200 -18000 1 -06} {2946250800 -21600 0 -06} - {2954116800 -18000 1 -05} + {2954116800 -18000 1 -06} {2977700400 -21600 0 -06} - {2985566400 -18000 1 -05} + {2985566400 -18000 1 -06} {3009150000 -21600 0 -06} - {3017016000 -18000 1 -05} + {3017016000 -18000 1 -06} {3040599600 -21600 0 -06} - {3049070400 -18000 1 -05} + {3049070400 -18000 1 -06} {3072654000 -21600 0 -06} - {3080520000 -18000 1 -05} + {3080520000 -18000 1 -06} {3104103600 -21600 0 -06} - {3111969600 -18000 1 -05} + {3111969600 -18000 1 -06} {3135553200 -21600 0 -06} - {3143419200 -18000 1 -05} + {3143419200 -18000 1 -06} {3167002800 -21600 0 -06} - {3174868800 -18000 1 -05} + {3174868800 -18000 1 -06} {3198452400 -21600 0 -06} - {3206318400 -18000 1 -05} + {3206318400 -18000 1 -06} {3230506800 -21600 0 -06} - {3238372800 -18000 1 -05} + {3238372800 -18000 1 -06} {3261956400 -21600 0 -06} - {3269822400 -18000 1 -05} + {3269822400 -18000 1 -06} {3293406000 -21600 0 -06} - {3301272000 -18000 1 -05} + {3301272000 -18000 1 -06} {3324855600 -21600 0 -06} - {3332721600 -18000 1 -05} + {3332721600 -18000 1 -06} {3356305200 -21600 0 -06} - {3364171200 -18000 1 -05} + {3364171200 -18000 1 -06} {3387754800 -21600 0 -06} - {3396225600 -18000 1 -05} + {3396225600 -18000 1 -06} {3419809200 -21600 0 -06} - {3427675200 -18000 1 -05} + {3427675200 -18000 1 -06} {3451258800 -21600 0 -06} - {3459124800 -18000 1 -05} + {3459124800 -18000 1 -06} {3482708400 -21600 0 -06} - {3490574400 -18000 1 -05} + {3490574400 -18000 1 -06} {3514158000 -21600 0 -06} - {3522024000 -18000 1 -05} + {3522024000 -18000 1 -06} {3545607600 -21600 0 -06} - {3553473600 -18000 1 -05} + {3553473600 -18000 1 -06} {3577057200 -21600 0 -06} - {3585528000 -18000 1 -05} + {3585528000 -18000 1 -06} {3609111600 -21600 0 -06} - {3616977600 -18000 1 -05} + {3616977600 -18000 1 -06} {3640561200 -21600 0 -06} - {3648427200 -18000 1 -05} + {3648427200 -18000 1 -06} {3672010800 -21600 0 -06} - {3679876800 -18000 1 -05} + {3679876800 -18000 1 -06} {3703460400 -21600 0 -06} - {3711326400 -18000 1 -05} + {3711326400 -18000 1 -06} {3734910000 -21600 0 -06} - {3743380800 -18000 1 -05} + {3743380800 -18000 1 -06} {3766964400 -21600 0 -06} - {3774830400 -18000 1 -05} + {3774830400 -18000 1 -06} {3798414000 -21600 0 -06} - {3806280000 -18000 1 -05} + {3806280000 -18000 1 -06} {3829863600 -21600 0 -06} - {3837729600 -18000 1 -05} + {3837729600 -18000 1 -06} {3861313200 -21600 0 -06} - {3869179200 -18000 1 -05} + {3869179200 -18000 1 -06} {3892762800 -21600 0 -06} - {3900628800 -18000 1 -05} + {3900628800 -18000 1 -06} {3924212400 -21600 0 -06} - {3932683200 -18000 1 -05} + {3932683200 -18000 1 -06} {3956266800 -21600 0 -06} - {3964132800 -18000 1 -05} + {3964132800 -18000 1 -06} {3987716400 -21600 0 -06} - {3995582400 -18000 1 -05} + {3995582400 -18000 1 -06} {4019166000 -21600 0 -06} - {4027032000 -18000 1 -05} + {4027032000 -18000 1 -06} {4050615600 -21600 0 -06} - {4058481600 -18000 1 -05} + {4058481600 -18000 1 -06} {4082065200 -21600 0 -06} - {4089931200 -18000 1 -05} + {4089931200 -18000 1 -06} } diff --git a/library/tzdata/Pacific/Efate b/library/tzdata/Pacific/Efate index a43852e..a026ee1 100644 --- a/library/tzdata/Pacific/Efate +++ b/library/tzdata/Pacific/Efate @@ -3,24 +3,24 @@ set TZData(:Pacific/Efate) { {-9223372036854775808 40396 0 LMT} {-1829387596 39600 0 +11} - {433256400 43200 1 +12} + {433256400 43200 1 +11} {448977600 39600 0 +11} - {467298000 43200 1 +12} + {467298000 43200 1 +11} {480427200 39600 0 +11} - {496760400 43200 1 +12} + {496760400 43200 1 +11} {511876800 39600 0 +11} - {528210000 43200 1 +12} + {528210000 43200 1 +11} {543931200 39600 0 +11} - {559659600 43200 1 +12} + {559659600 43200 1 +11} {575380800 39600 0 +11} - {591109200 43200 1 +12} + {591109200 43200 1 +11} {606830400 39600 0 +11} - {622558800 43200 1 +12} + {622558800 43200 1 +11} {638280000 39600 0 +11} - {654008400 43200 1 +12} + {654008400 43200 1 +11} {669729600 39600 0 +11} - {686062800 43200 1 +12} + {686062800 43200 1 +11} {696340800 39600 0 +11} - {719931600 43200 1 +12} + {719931600 43200 1 +11} {727790400 39600 0 +11} } diff --git a/library/tzdata/Pacific/Enderbury b/library/tzdata/Pacific/Enderbury index 6abd57e..48eaafe 100644 --- a/library/tzdata/Pacific/Enderbury +++ b/library/tzdata/Pacific/Enderbury @@ -4,5 +4,5 @@ set TZData(:Pacific/Enderbury) { {-9223372036854775808 -41060 0 LMT} {-2177411740 -43200 0 -12} {307627200 -39600 0 -11} - {788958000 46800 0 +13} + {788871600 46800 0 +13} } diff --git a/library/tzdata/Pacific/Fiji b/library/tzdata/Pacific/Fiji index f9d393c..610c191 100644 --- a/library/tzdata/Pacific/Fiji +++ b/library/tzdata/Pacific/Fiji @@ -3,189 +3,189 @@ set TZData(:Pacific/Fiji) { {-9223372036854775808 42944 0 LMT} {-1709985344 43200 0 +12} - {909842400 46800 1 +13} + {909842400 46800 1 +12} {920124000 43200 0 +12} - {941896800 46800 1 +13} + {941896800 46800 1 +12} {951573600 43200 0 +12} - {1259416800 46800 1 +13} + {1259416800 46800 1 +12} {1269698400 43200 0 +12} - {1287842400 46800 1 +13} + {1287842400 46800 1 +12} {1299333600 43200 0 +12} - {1319292000 46800 1 +13} + {1319292000 46800 1 +12} {1327154400 43200 0 +12} - {1350741600 46800 1 +13} + {1350741600 46800 1 +12} {1358604000 43200 0 +12} - {1382796000 46800 1 +13} + {1382796000 46800 1 +12} {1390050000 43200 0 +12} - {1414850400 46800 1 +13} + {1414850400 46800 1 +12} {1421503200 43200 0 +12} - {1446300000 46800 1 +13} + {1446300000 46800 1 +12} {1452952800 43200 0 +12} - {1478354400 46800 1 +13} + {1478354400 46800 1 +12} {1484402400 43200 0 +12} - {1509804000 46800 1 +13} + {1509804000 46800 1 +12} {1515852000 43200 0 +12} - {1541253600 46800 1 +13} + {1541253600 46800 1 +12} {1547906400 43200 0 +12} - {1572703200 46800 1 +13} + {1572703200 46800 1 +12} {1579356000 43200 0 +12} - {1604152800 46800 1 +13} + {1604152800 46800 1 +12} {1610805600 43200 0 +12} - {1636207200 46800 1 +13} + {1636207200 46800 1 +12} {1642255200 43200 0 +12} - {1667656800 46800 1 +13} + {1667656800 46800 1 +12} {1673704800 43200 0 +12} - {1699106400 46800 1 +13} + {1699106400 46800 1 +12} {1705154400 43200 0 +12} - {1730556000 46800 1 +13} + {1730556000 46800 1 +12} {1737208800 43200 0 +12} - {1762005600 46800 1 +13} + {1762005600 46800 1 +12} {1768658400 43200 0 +12} - {1793455200 46800 1 +13} + {1793455200 46800 1 +12} {1800108000 43200 0 +12} - {1825509600 46800 1 +13} + {1825509600 46800 1 +12} {1831557600 43200 0 +12} - {1856959200 46800 1 +13} + {1856959200 46800 1 +12} {1863007200 43200 0 +12} - {1888408800 46800 1 +13} + {1888408800 46800 1 +12} {1895061600 43200 0 +12} - {1919858400 46800 1 +13} + {1919858400 46800 1 +12} {1926511200 43200 0 +12} - {1951308000 46800 1 +13} + {1951308000 46800 1 +12} {1957960800 43200 0 +12} - {1983362400 46800 1 +13} + {1983362400 46800 1 +12} {1989410400 43200 0 +12} - {2014812000 46800 1 +13} + {2014812000 46800 1 +12} {2020860000 43200 0 +12} - {2046261600 46800 1 +13} + {2046261600 46800 1 +12} {2052309600 43200 0 +12} - {2077711200 46800 1 +13} + {2077711200 46800 1 +12} {2084364000 43200 0 +12} - {2109160800 46800 1 +13} + {2109160800 46800 1 +12} {2115813600 43200 0 +12} - {2140610400 46800 1 +13} + {2140610400 46800 1 +12} {2147263200 43200 0 +12} - {2172664800 46800 1 +13} + {2172664800 46800 1 +12} {2178712800 43200 0 +12} - {2204114400 46800 1 +13} + {2204114400 46800 1 +12} {2210162400 43200 0 +12} - {2235564000 46800 1 +13} + {2235564000 46800 1 +12} {2242216800 43200 0 +12} - {2267013600 46800 1 +13} + {2267013600 46800 1 +12} {2273666400 43200 0 +12} - {2298463200 46800 1 +13} + {2298463200 46800 1 +12} {2305116000 43200 0 +12} - {2329912800 46800 1 +13} + {2329912800 46800 1 +12} {2336565600 43200 0 +12} - {2361967200 46800 1 +13} + {2361967200 46800 1 +12} {2368015200 43200 0 +12} - {2393416800 46800 1 +13} + {2393416800 46800 1 +12} {2399464800 43200 0 +12} - {2424866400 46800 1 +13} + {2424866400 46800 1 +12} {2431519200 43200 0 +12} - {2456316000 46800 1 +13} + {2456316000 46800 1 +12} {2462968800 43200 0 +12} - {2487765600 46800 1 +13} + {2487765600 46800 1 +12} {2494418400 43200 0 +12} - {2519820000 46800 1 +13} + {2519820000 46800 1 +12} {2525868000 43200 0 +12} - {2551269600 46800 1 +13} + {2551269600 46800 1 +12} {2557317600 43200 0 +12} - {2582719200 46800 1 +13} + {2582719200 46800 1 +12} {2588767200 43200 0 +12} - {2614168800 46800 1 +13} + {2614168800 46800 1 +12} {2620821600 43200 0 +12} - {2645618400 46800 1 +13} + {2645618400 46800 1 +12} {2652271200 43200 0 +12} - {2677068000 46800 1 +13} + {2677068000 46800 1 +12} {2683720800 43200 0 +12} - {2709122400 46800 1 +13} + {2709122400 46800 1 +12} {2715170400 43200 0 +12} - {2740572000 46800 1 +13} + {2740572000 46800 1 +12} {2746620000 43200 0 +12} - {2772021600 46800 1 +13} + {2772021600 46800 1 +12} {2778674400 43200 0 +12} - {2803471200 46800 1 +13} + {2803471200 46800 1 +12} {2810124000 43200 0 +12} - {2834920800 46800 1 +13} + {2834920800 46800 1 +12} {2841573600 43200 0 +12} - {2866975200 46800 1 +13} + {2866975200 46800 1 +12} {2873023200 43200 0 +12} - {2898424800 46800 1 +13} + {2898424800 46800 1 +12} {2904472800 43200 0 +12} - {2929874400 46800 1 +13} + {2929874400 46800 1 +12} {2935922400 43200 0 +12} - {2961324000 46800 1 +13} + {2961324000 46800 1 +12} {2967976800 43200 0 +12} - {2992773600 46800 1 +13} + {2992773600 46800 1 +12} {2999426400 43200 0 +12} - {3024223200 46800 1 +13} + {3024223200 46800 1 +12} {3030876000 43200 0 +12} - {3056277600 46800 1 +13} + {3056277600 46800 1 +12} {3062325600 43200 0 +12} - {3087727200 46800 1 +13} + {3087727200 46800 1 +12} {3093775200 43200 0 +12} - {3119176800 46800 1 +13} + {3119176800 46800 1 +12} {3125829600 43200 0 +12} - {3150626400 46800 1 +13} + {3150626400 46800 1 +12} {3157279200 43200 0 +12} - {3182076000 46800 1 +13} + {3182076000 46800 1 +12} {3188728800 43200 0 +12} - {3213525600 46800 1 +13} + {3213525600 46800 1 +12} {3220178400 43200 0 +12} - {3245580000 46800 1 +13} + {3245580000 46800 1 +12} {3251628000 43200 0 +12} - {3277029600 46800 1 +13} + {3277029600 46800 1 +12} {3283077600 43200 0 +12} - {3308479200 46800 1 +13} + {3308479200 46800 1 +12} {3315132000 43200 0 +12} - {3339928800 46800 1 +13} + {3339928800 46800 1 +12} {3346581600 43200 0 +12} - {3371378400 46800 1 +13} + {3371378400 46800 1 +12} {3378031200 43200 0 +12} - {3403432800 46800 1 +13} + {3403432800 46800 1 +12} {3409480800 43200 0 +12} - {3434882400 46800 1 +13} + {3434882400 46800 1 +12} {3440930400 43200 0 +12} - {3466332000 46800 1 +13} + {3466332000 46800 1 +12} {3472380000 43200 0 +12} - {3497781600 46800 1 +13} + {3497781600 46800 1 +12} {3504434400 43200 0 +12} - {3529231200 46800 1 +13} + {3529231200 46800 1 +12} {3535884000 43200 0 +12} - {3560680800 46800 1 +13} + {3560680800 46800 1 +12} {3567333600 43200 0 +12} - {3592735200 46800 1 +13} + {3592735200 46800 1 +12} {3598783200 43200 0 +12} - {3624184800 46800 1 +13} + {3624184800 46800 1 +12} {3630232800 43200 0 +12} - {3655634400 46800 1 +13} + {3655634400 46800 1 +12} {3662287200 43200 0 +12} - {3687084000 46800 1 +13} + {3687084000 46800 1 +12} {3693736800 43200 0 +12} - {3718533600 46800 1 +13} + {3718533600 46800 1 +12} {3725186400 43200 0 +12} - {3750588000 46800 1 +13} + {3750588000 46800 1 +12} {3756636000 43200 0 +12} - {3782037600 46800 1 +13} + {3782037600 46800 1 +12} {3788085600 43200 0 +12} - {3813487200 46800 1 +13} + {3813487200 46800 1 +12} {3819535200 43200 0 +12} - {3844936800 46800 1 +13} + {3844936800 46800 1 +12} {3851589600 43200 0 +12} - {3876386400 46800 1 +13} + {3876386400 46800 1 +12} {3883039200 43200 0 +12} - {3907836000 46800 1 +13} + {3907836000 46800 1 +12} {3914488800 43200 0 +12} - {3939890400 46800 1 +13} + {3939890400 46800 1 +12} {3945938400 43200 0 +12} - {3971340000 46800 1 +13} + {3971340000 46800 1 +12} {3977388000 43200 0 +12} - {4002789600 46800 1 +13} + {4002789600 46800 1 +12} {4009442400 43200 0 +12} - {4034239200 46800 1 +13} + {4034239200 46800 1 +12} {4040892000 43200 0 +12} - {4065688800 46800 1 +13} + {4065688800 46800 1 +12} {4072341600 43200 0 +12} - {4097138400 46800 1 +13} + {4097138400 46800 1 +12} } diff --git a/library/tzdata/Pacific/Galapagos b/library/tzdata/Pacific/Galapagos index f276f73..180ce6a 100644 --- a/library/tzdata/Pacific/Galapagos +++ b/library/tzdata/Pacific/Galapagos @@ -4,6 +4,6 @@ set TZData(:Pacific/Galapagos) { {-9223372036854775808 -21504 0 LMT} {-1230746496 -18000 0 -05} {504939600 -21600 0 -06} - {722930400 -18000 1 -05} + {722930400 -18000 1 -06} {728888400 -21600 0 -06} } diff --git a/library/tzdata/Pacific/Kiritimati b/library/tzdata/Pacific/Kiritimati index b703f19..7d600f3 100644 --- a/library/tzdata/Pacific/Kiritimati +++ b/library/tzdata/Pacific/Kiritimati @@ -4,5 +4,5 @@ set TZData(:Pacific/Kiritimati) { {-9223372036854775808 -37760 0 LMT} {-2177415040 -38400 0 -1040} {307622400 -36000 0 -10} - {788954400 50400 0 +14} + {788868000 50400 0 +14} } diff --git a/library/tzdata/Pacific/Noumea b/library/tzdata/Pacific/Noumea index 36b570d..c9da825 100644 --- a/library/tzdata/Pacific/Noumea +++ b/library/tzdata/Pacific/Noumea @@ -3,10 +3,10 @@ set TZData(:Pacific/Noumea) { {-9223372036854775808 39948 0 LMT} {-1829387148 39600 0 +11} - {250002000 43200 1 +12} + {250002000 43200 1 +11} {257342400 39600 0 +11} - {281451600 43200 1 +12} + {281451600 43200 1 +11} {288878400 39600 0 +11} - {849366000 43200 1 +12} + {849366000 43200 1 +11} {857228400 39600 0 +11} } diff --git a/library/tzdata/Pacific/Rarotonga b/library/tzdata/Pacific/Rarotonga index 9a70318..2913d68 100644 --- a/library/tzdata/Pacific/Rarotonga +++ b/library/tzdata/Pacific/Rarotonga @@ -3,30 +3,30 @@ set TZData(:Pacific/Rarotonga) { {-9223372036854775808 -38344 0 LMT} {-2177414456 -37800 0 -1030} - {279714600 -34200 0 -0930} + {279714600 -34200 0 -10} {289387800 -36000 0 -10} - {309952800 -34200 1 -0930} + {309952800 -34200 1 -10} {320837400 -36000 0 -10} - {341402400 -34200 1 -0930} + {341402400 -34200 1 -10} {352287000 -36000 0 -10} - {372852000 -34200 1 -0930} + {372852000 -34200 1 -10} {384341400 -36000 0 -10} - {404906400 -34200 1 -0930} + {404906400 -34200 1 -10} {415791000 -36000 0 -10} - {436356000 -34200 1 -0930} + {436356000 -34200 1 -10} {447240600 -36000 0 -10} - {467805600 -34200 1 -0930} + {467805600 -34200 1 -10} {478690200 -36000 0 -10} - {499255200 -34200 1 -0930} + {499255200 -34200 1 -10} {510139800 -36000 0 -10} - {530704800 -34200 1 -0930} + {530704800 -34200 1 -10} {541589400 -36000 0 -10} - {562154400 -34200 1 -0930} + {562154400 -34200 1 -10} {573643800 -36000 0 -10} - {594208800 -34200 1 -0930} + {594208800 -34200 1 -10} {605093400 -36000 0 -10} - {625658400 -34200 1 -0930} + {625658400 -34200 1 -10} {636543000 -36000 0 -10} - {657108000 -34200 1 -0930} + {657108000 -34200 1 -10} {667992600 -36000 0 -10} } diff --git a/library/tzdata/Pacific/Tongatapu b/library/tzdata/Pacific/Tongatapu index 3cfaaaa..104888a 100644 --- a/library/tzdata/Pacific/Tongatapu +++ b/library/tzdata/Pacific/Tongatapu @@ -5,12 +5,12 @@ set TZData(:Pacific/Tongatapu) { {-2177497160 44400 0 +1220} {-915193200 46800 0 +13} {915102000 46800 0 +13} - {939214800 50400 1 +14} + {939214800 50400 1 +13} {953384400 46800 0 +13} - {973342800 50400 1 +14} + {973342800 50400 1 +13} {980596800 46800 0 +13} - {1004792400 50400 1 +14} + {1004792400 50400 1 +13} {1012046400 46800 0 +13} - {1478350800 50400 1 +14} + {1478350800 50400 1 +13} {1484398800 46800 0 +13} } -- cgit v0.12 From ac47e6953d5c9a8916296ab9f382bf914a56324b Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Sat, 9 Jun 2018 07:42:42 +0000 Subject: Update all Unicode tables to Unicode version 11.0 --- generic/regc_locale.c | 491 +++++++++-------- generic/tclUniData.c | 1447 +++++++++++++++++++++++++------------------------ 2 files changed, 984 insertions(+), 954 deletions(-) diff --git a/generic/regc_locale.c b/generic/regc_locale.c index 4435557..81aeb82 100644 --- a/generic/regc_locale.c +++ b/generic/regc_locale.c @@ -137,8 +137,8 @@ static const crange alphaRangeTable[] = { {0x41, 0x5a}, {0x61, 0x7a}, {0xc0, 0xd6}, {0xd8, 0xf6}, {0xf8, 0x2c1}, {0x2c6, 0x2d1}, {0x2e0, 0x2e4}, {0x370, 0x374}, {0x37a, 0x37d}, {0x388, 0x38a}, {0x38e, 0x3a1}, {0x3a3, 0x3f5}, - {0x3f7, 0x481}, {0x48a, 0x52f}, {0x531, 0x556}, {0x561, 0x587}, - {0x5d0, 0x5ea}, {0x5f0, 0x5f2}, {0x620, 0x64a}, {0x671, 0x6d3}, + {0x3f7, 0x481}, {0x48a, 0x52f}, {0x531, 0x556}, {0x560, 0x588}, + {0x5d0, 0x5ea}, {0x5ef, 0x5f2}, {0x620, 0x64a}, {0x671, 0x6d3}, {0x6fa, 0x6fc}, {0x712, 0x72f}, {0x74d, 0x7a5}, {0x7ca, 0x7ea}, {0x800, 0x815}, {0x840, 0x858}, {0x860, 0x86a}, {0x8a0, 0x8b4}, {0x8b6, 0x8bd}, {0x904, 0x939}, {0x958, 0x961}, {0x971, 0x980}, @@ -165,40 +165,41 @@ static const crange alphaRangeTable[] = { {0x1401, 0x166c}, {0x166f, 0x167f}, {0x1681, 0x169a}, {0x16a0, 0x16ea}, {0x16f1, 0x16f8}, {0x1700, 0x170c}, {0x170e, 0x1711}, {0x1720, 0x1731}, {0x1740, 0x1751}, {0x1760, 0x176c}, {0x176e, 0x1770}, {0x1780, 0x17b3}, - {0x1820, 0x1877}, {0x1880, 0x1884}, {0x1887, 0x18a8}, {0x18b0, 0x18f5}, + {0x1820, 0x1878}, {0x1880, 0x1884}, {0x1887, 0x18a8}, {0x18b0, 0x18f5}, {0x1900, 0x191e}, {0x1950, 0x196d}, {0x1970, 0x1974}, {0x1980, 0x19ab}, {0x19b0, 0x19c9}, {0x1a00, 0x1a16}, {0x1a20, 0x1a54}, {0x1b05, 0x1b33}, {0x1b45, 0x1b4b}, {0x1b83, 0x1ba0}, {0x1bba, 0x1be5}, {0x1c00, 0x1c23}, - {0x1c4d, 0x1c4f}, {0x1c5a, 0x1c7d}, {0x1c80, 0x1c88}, {0x1ce9, 0x1cec}, - {0x1cee, 0x1cf1}, {0x1d00, 0x1dbf}, {0x1e00, 0x1f15}, {0x1f18, 0x1f1d}, - {0x1f20, 0x1f45}, {0x1f48, 0x1f4d}, {0x1f50, 0x1f57}, {0x1f5f, 0x1f7d}, - {0x1f80, 0x1fb4}, {0x1fb6, 0x1fbc}, {0x1fc2, 0x1fc4}, {0x1fc6, 0x1fcc}, - {0x1fd0, 0x1fd3}, {0x1fd6, 0x1fdb}, {0x1fe0, 0x1fec}, {0x1ff2, 0x1ff4}, - {0x1ff6, 0x1ffc}, {0x2090, 0x209c}, {0x210a, 0x2113}, {0x2119, 0x211d}, - {0x212a, 0x212d}, {0x212f, 0x2139}, {0x213c, 0x213f}, {0x2145, 0x2149}, - {0x2c00, 0x2c2e}, {0x2c30, 0x2c5e}, {0x2c60, 0x2ce4}, {0x2ceb, 0x2cee}, - {0x2d00, 0x2d25}, {0x2d30, 0x2d67}, {0x2d80, 0x2d96}, {0x2da0, 0x2da6}, - {0x2da8, 0x2dae}, {0x2db0, 0x2db6}, {0x2db8, 0x2dbe}, {0x2dc0, 0x2dc6}, - {0x2dc8, 0x2dce}, {0x2dd0, 0x2dd6}, {0x2dd8, 0x2dde}, {0x3031, 0x3035}, - {0x3041, 0x3096}, {0x309d, 0x309f}, {0x30a1, 0x30fa}, {0x30fc, 0x30ff}, - {0x3105, 0x312e}, {0x3131, 0x318e}, {0x31a0, 0x31ba}, {0x31f0, 0x31ff}, - {0x3400, 0x4db5}, {0x4e00, 0x9fea}, {0xa000, 0xa48c}, {0xa4d0, 0xa4fd}, - {0xa500, 0xa60c}, {0xa610, 0xa61f}, {0xa640, 0xa66e}, {0xa67f, 0xa69d}, - {0xa6a0, 0xa6e5}, {0xa717, 0xa71f}, {0xa722, 0xa788}, {0xa78b, 0xa7ae}, - {0xa7b0, 0xa7b7}, {0xa7f7, 0xa801}, {0xa803, 0xa805}, {0xa807, 0xa80a}, - {0xa80c, 0xa822}, {0xa840, 0xa873}, {0xa882, 0xa8b3}, {0xa8f2, 0xa8f7}, - {0xa90a, 0xa925}, {0xa930, 0xa946}, {0xa960, 0xa97c}, {0xa984, 0xa9b2}, - {0xa9e0, 0xa9e4}, {0xa9e6, 0xa9ef}, {0xa9fa, 0xa9fe}, {0xaa00, 0xaa28}, - {0xaa40, 0xaa42}, {0xaa44, 0xaa4b}, {0xaa60, 0xaa76}, {0xaa7e, 0xaaaf}, - {0xaab9, 0xaabd}, {0xaadb, 0xaadd}, {0xaae0, 0xaaea}, {0xaaf2, 0xaaf4}, - {0xab01, 0xab06}, {0xab09, 0xab0e}, {0xab11, 0xab16}, {0xab20, 0xab26}, - {0xab28, 0xab2e}, {0xab30, 0xab5a}, {0xab5c, 0xab65}, {0xab70, 0xabe2}, - {0xac00, 0xd7a3}, {0xd7b0, 0xd7c6}, {0xd7cb, 0xd7fb}, {0xf900, 0xfa6d}, - {0xfa70, 0xfad9}, {0xfb00, 0xfb06}, {0xfb13, 0xfb17}, {0xfb1f, 0xfb28}, - {0xfb2a, 0xfb36}, {0xfb38, 0xfb3c}, {0xfb46, 0xfbb1}, {0xfbd3, 0xfd3d}, - {0xfd50, 0xfd8f}, {0xfd92, 0xfdc7}, {0xfdf0, 0xfdfb}, {0xfe70, 0xfe74}, - {0xfe76, 0xfefc}, {0xff21, 0xff3a}, {0xff41, 0xff5a}, {0xff66, 0xffbe}, - {0xffc2, 0xffc7}, {0xffca, 0xffcf}, {0xffd2, 0xffd7}, {0xffda, 0xffdc} + {0x1c4d, 0x1c4f}, {0x1c5a, 0x1c7d}, {0x1c80, 0x1c88}, {0x1c90, 0x1cba}, + {0x1cbd, 0x1cbf}, {0x1ce9, 0x1cec}, {0x1cee, 0x1cf1}, {0x1d00, 0x1dbf}, + {0x1e00, 0x1f15}, {0x1f18, 0x1f1d}, {0x1f20, 0x1f45}, {0x1f48, 0x1f4d}, + {0x1f50, 0x1f57}, {0x1f5f, 0x1f7d}, {0x1f80, 0x1fb4}, {0x1fb6, 0x1fbc}, + {0x1fc2, 0x1fc4}, {0x1fc6, 0x1fcc}, {0x1fd0, 0x1fd3}, {0x1fd6, 0x1fdb}, + {0x1fe0, 0x1fec}, {0x1ff2, 0x1ff4}, {0x1ff6, 0x1ffc}, {0x2090, 0x209c}, + {0x210a, 0x2113}, {0x2119, 0x211d}, {0x212a, 0x212d}, {0x212f, 0x2139}, + {0x213c, 0x213f}, {0x2145, 0x2149}, {0x2c00, 0x2c2e}, {0x2c30, 0x2c5e}, + {0x2c60, 0x2ce4}, {0x2ceb, 0x2cee}, {0x2d00, 0x2d25}, {0x2d30, 0x2d67}, + {0x2d80, 0x2d96}, {0x2da0, 0x2da6}, {0x2da8, 0x2dae}, {0x2db0, 0x2db6}, + {0x2db8, 0x2dbe}, {0x2dc0, 0x2dc6}, {0x2dc8, 0x2dce}, {0x2dd0, 0x2dd6}, + {0x2dd8, 0x2dde}, {0x3031, 0x3035}, {0x3041, 0x3096}, {0x309d, 0x309f}, + {0x30a1, 0x30fa}, {0x30fc, 0x30ff}, {0x3105, 0x312f}, {0x3131, 0x318e}, + {0x31a0, 0x31ba}, {0x31f0, 0x31ff}, {0x3400, 0x4db5}, {0x4e00, 0x9fef}, + {0xa000, 0xa48c}, {0xa4d0, 0xa4fd}, {0xa500, 0xa60c}, {0xa610, 0xa61f}, + {0xa640, 0xa66e}, {0xa67f, 0xa69d}, {0xa6a0, 0xa6e5}, {0xa717, 0xa71f}, + {0xa722, 0xa788}, {0xa78b, 0xa7b9}, {0xa7f7, 0xa801}, {0xa803, 0xa805}, + {0xa807, 0xa80a}, {0xa80c, 0xa822}, {0xa840, 0xa873}, {0xa882, 0xa8b3}, + {0xa8f2, 0xa8f7}, {0xa90a, 0xa925}, {0xa930, 0xa946}, {0xa960, 0xa97c}, + {0xa984, 0xa9b2}, {0xa9e0, 0xa9e4}, {0xa9e6, 0xa9ef}, {0xa9fa, 0xa9fe}, + {0xaa00, 0xaa28}, {0xaa40, 0xaa42}, {0xaa44, 0xaa4b}, {0xaa60, 0xaa76}, + {0xaa7e, 0xaaaf}, {0xaab9, 0xaabd}, {0xaadb, 0xaadd}, {0xaae0, 0xaaea}, + {0xaaf2, 0xaaf4}, {0xab01, 0xab06}, {0xab09, 0xab0e}, {0xab11, 0xab16}, + {0xab20, 0xab26}, {0xab28, 0xab2e}, {0xab30, 0xab5a}, {0xab5c, 0xab65}, + {0xab70, 0xabe2}, {0xac00, 0xd7a3}, {0xd7b0, 0xd7c6}, {0xd7cb, 0xd7fb}, + {0xf900, 0xfa6d}, {0xfa70, 0xfad9}, {0xfb00, 0xfb06}, {0xfb13, 0xfb17}, + {0xfb1f, 0xfb28}, {0xfb2a, 0xfb36}, {0xfb38, 0xfb3c}, {0xfb46, 0xfbb1}, + {0xfbd3, 0xfd3d}, {0xfd50, 0xfd8f}, {0xfd92, 0xfdc7}, {0xfdf0, 0xfdfb}, + {0xfe70, 0xfe74}, {0xfe76, 0xfefc}, {0xff21, 0xff3a}, {0xff41, 0xff5a}, + {0xff66, 0xffbe}, {0xffc2, 0xffc7}, {0xffca, 0xffcf}, {0xffd2, 0xffd7}, + {0xffda, 0xffdc} #if CHRBITS > 16 ,{0x10000, 0x1000b}, {0x1000d, 0x10026}, {0x10028, 0x1003a}, {0x1003f, 0x1004d}, {0x10050, 0x1005d}, {0x10080, 0x100fa}, {0x10280, 0x1029c}, {0x102a0, 0x102d0}, @@ -208,23 +209,25 @@ static const crange alphaRangeTable[] = { {0x10600, 0x10736}, {0x10740, 0x10755}, {0x10760, 0x10767}, {0x10800, 0x10805}, {0x1080a, 0x10835}, {0x1083f, 0x10855}, {0x10860, 0x10876}, {0x10880, 0x1089e}, {0x108e0, 0x108f2}, {0x10900, 0x10915}, {0x10920, 0x10939}, {0x10980, 0x109b7}, - {0x10a10, 0x10a13}, {0x10a15, 0x10a17}, {0x10a19, 0x10a33}, {0x10a60, 0x10a7c}, + {0x10a10, 0x10a13}, {0x10a15, 0x10a17}, {0x10a19, 0x10a35}, {0x10a60, 0x10a7c}, {0x10a80, 0x10a9c}, {0x10ac0, 0x10ac7}, {0x10ac9, 0x10ae4}, {0x10b00, 0x10b35}, {0x10b40, 0x10b55}, {0x10b60, 0x10b72}, {0x10b80, 0x10b91}, {0x10c00, 0x10c48}, - {0x10c80, 0x10cb2}, {0x10cc0, 0x10cf2}, {0x11003, 0x11037}, {0x11083, 0x110af}, - {0x110d0, 0x110e8}, {0x11103, 0x11126}, {0x11150, 0x11172}, {0x11183, 0x111b2}, - {0x111c1, 0x111c4}, {0x11200, 0x11211}, {0x11213, 0x1122b}, {0x11280, 0x11286}, - {0x1128a, 0x1128d}, {0x1128f, 0x1129d}, {0x1129f, 0x112a8}, {0x112b0, 0x112de}, - {0x11305, 0x1130c}, {0x11313, 0x11328}, {0x1132a, 0x11330}, {0x11335, 0x11339}, - {0x1135d, 0x11361}, {0x11400, 0x11434}, {0x11447, 0x1144a}, {0x11480, 0x114af}, - {0x11580, 0x115ae}, {0x115d8, 0x115db}, {0x11600, 0x1162f}, {0x11680, 0x116aa}, - {0x11700, 0x11719}, {0x118a0, 0x118df}, {0x11a0b, 0x11a32}, {0x11a5c, 0x11a83}, + {0x10c80, 0x10cb2}, {0x10cc0, 0x10cf2}, {0x10d00, 0x10d23}, {0x10f00, 0x10f1c}, + {0x10f30, 0x10f45}, {0x11003, 0x11037}, {0x11083, 0x110af}, {0x110d0, 0x110e8}, + {0x11103, 0x11126}, {0x11150, 0x11172}, {0x11183, 0x111b2}, {0x111c1, 0x111c4}, + {0x11200, 0x11211}, {0x11213, 0x1122b}, {0x11280, 0x11286}, {0x1128a, 0x1128d}, + {0x1128f, 0x1129d}, {0x1129f, 0x112a8}, {0x112b0, 0x112de}, {0x11305, 0x1130c}, + {0x11313, 0x11328}, {0x1132a, 0x11330}, {0x11335, 0x11339}, {0x1135d, 0x11361}, + {0x11400, 0x11434}, {0x11447, 0x1144a}, {0x11480, 0x114af}, {0x11580, 0x115ae}, + {0x115d8, 0x115db}, {0x11600, 0x1162f}, {0x11680, 0x116aa}, {0x11700, 0x1171a}, + {0x11800, 0x1182b}, {0x118a0, 0x118df}, {0x11a0b, 0x11a32}, {0x11a5c, 0x11a83}, {0x11a86, 0x11a89}, {0x11ac0, 0x11af8}, {0x11c00, 0x11c08}, {0x11c0a, 0x11c2e}, - {0x11c72, 0x11c8f}, {0x11d00, 0x11d06}, {0x11d0b, 0x11d30}, {0x12000, 0x12399}, - {0x12480, 0x12543}, {0x13000, 0x1342e}, {0x14400, 0x14646}, {0x16800, 0x16a38}, - {0x16a40, 0x16a5e}, {0x16ad0, 0x16aed}, {0x16b00, 0x16b2f}, {0x16b40, 0x16b43}, - {0x16b63, 0x16b77}, {0x16b7d, 0x16b8f}, {0x16f00, 0x16f44}, {0x16f93, 0x16f9f}, - {0x17000, 0x187ec}, {0x18800, 0x18af2}, {0x1b000, 0x1b11e}, {0x1b170, 0x1b2fb}, + {0x11c72, 0x11c8f}, {0x11d00, 0x11d06}, {0x11d0b, 0x11d30}, {0x11d60, 0x11d65}, + {0x11d6a, 0x11d89}, {0x11ee0, 0x11ef2}, {0x12000, 0x12399}, {0x12480, 0x12543}, + {0x13000, 0x1342e}, {0x14400, 0x14646}, {0x16800, 0x16a38}, {0x16a40, 0x16a5e}, + {0x16ad0, 0x16aed}, {0x16b00, 0x16b2f}, {0x16b40, 0x16b43}, {0x16b63, 0x16b77}, + {0x16b7d, 0x16b8f}, {0x16e40, 0x16e7f}, {0x16f00, 0x16f44}, {0x16f93, 0x16f9f}, + {0x17000, 0x187f1}, {0x18800, 0x18af2}, {0x1b000, 0x1b11e}, {0x1b170, 0x1b2fb}, {0x1bc00, 0x1bc6a}, {0x1bc70, 0x1bc7c}, {0x1bc80, 0x1bc88}, {0x1bc90, 0x1bc99}, {0x1d400, 0x1d454}, {0x1d456, 0x1d49c}, {0x1d4a9, 0x1d4ac}, {0x1d4ae, 0x1d4b9}, {0x1d4bd, 0x1d4c3}, {0x1d4c5, 0x1d505}, {0x1d507, 0x1d50a}, {0x1d50d, 0x1d514}, @@ -260,17 +263,18 @@ static const chr alphaCharTable[] = { 0x1baf, 0x1cf5, 0x1cf6, 0x1f59, 0x1f5b, 0x1f5d, 0x1fbe, 0x2071, 0x207f, 0x2102, 0x2107, 0x2115, 0x2124, 0x2126, 0x2128, 0x214e, 0x2183, 0x2184, 0x2cf2, 0x2cf3, 0x2d27, 0x2d2d, 0x2d6f, 0x2e2f, 0x3005, 0x3006, 0x303b, - 0x303c, 0xa62a, 0xa62b, 0xa8fb, 0xa8fd, 0xa9cf, 0xaa7a, 0xaab1, 0xaab5, - 0xaab6, 0xaac0, 0xaac2, 0xfb1d, 0xfb3e, 0xfb40, 0xfb41, 0xfb43, 0xfb44 + 0x303c, 0xa62a, 0xa62b, 0xa8fb, 0xa8fd, 0xa8fe, 0xa9cf, 0xaa7a, 0xaab1, + 0xaab5, 0xaab6, 0xaac0, 0xaac2, 0xfb1d, 0xfb3e, 0xfb40, 0xfb41, 0xfb43, + 0xfb44 #if CHRBITS > 16 ,0x1003c, 0x1003d, 0x10808, 0x10837, 0x10838, 0x1083c, 0x108f4, 0x108f5, 0x109be, - 0x109bf, 0x10a00, 0x11176, 0x111da, 0x111dc, 0x11288, 0x1130f, 0x11310, 0x11332, - 0x11333, 0x1133d, 0x11350, 0x114c4, 0x114c5, 0x114c7, 0x11644, 0x118ff, 0x11a00, - 0x11a3a, 0x11a50, 0x11c40, 0x11d08, 0x11d09, 0x11d46, 0x16f50, 0x16fe0, 0x16fe1, - 0x1d49e, 0x1d49f, 0x1d4a2, 0x1d4a5, 0x1d4a6, 0x1d4bb, 0x1d546, 0x1ee21, 0x1ee22, - 0x1ee24, 0x1ee27, 0x1ee39, 0x1ee3b, 0x1ee42, 0x1ee47, 0x1ee49, 0x1ee4b, 0x1ee51, - 0x1ee52, 0x1ee54, 0x1ee57, 0x1ee59, 0x1ee5b, 0x1ee5d, 0x1ee5f, 0x1ee61, 0x1ee62, - 0x1ee64, 0x1ee7e + 0x109bf, 0x10a00, 0x10f27, 0x11144, 0x11176, 0x111da, 0x111dc, 0x11288, 0x1130f, + 0x11310, 0x11332, 0x11333, 0x1133d, 0x11350, 0x114c4, 0x114c5, 0x114c7, 0x11644, + 0x118ff, 0x11a00, 0x11a3a, 0x11a50, 0x11a9d, 0x11c40, 0x11d08, 0x11d09, 0x11d46, + 0x11d67, 0x11d68, 0x11d98, 0x16f50, 0x16fe0, 0x16fe1, 0x1d49e, 0x1d49f, 0x1d4a2, + 0x1d4a5, 0x1d4a6, 0x1d4bb, 0x1d546, 0x1ee21, 0x1ee22, 0x1ee24, 0x1ee27, 0x1ee39, + 0x1ee3b, 0x1ee42, 0x1ee47, 0x1ee49, 0x1ee4b, 0x1ee51, 0x1ee52, 0x1ee54, 0x1ee57, + 0x1ee59, 0x1ee5b, 0x1ee5d, 0x1ee5f, 0x1ee61, 0x1ee62, 0x1ee64, 0x1ee7e #endif }; @@ -295,7 +299,7 @@ static const crange controlRangeTable[] = { static const chr controlCharTable[] = { 0xad, 0x61c, 0x6dd, 0x70f, 0x8e2, 0x180e, 0xfeff #if CHRBITS > 16 - ,0x110bd, 0xe0001 + ,0x110bd, 0x110cd, 0xe0001 #endif }; @@ -317,11 +321,11 @@ static const crange digitRangeTable[] = { {0xa9d0, 0xa9d9}, {0xa9f0, 0xa9f9}, {0xaa50, 0xaa59}, {0xabf0, 0xabf9}, {0xff10, 0xff19} #if CHRBITS > 16 - ,{0x104a0, 0x104a9}, {0x11066, 0x1106f}, {0x110f0, 0x110f9}, {0x11136, 0x1113f}, - {0x111d0, 0x111d9}, {0x112f0, 0x112f9}, {0x11450, 0x11459}, {0x114d0, 0x114d9}, - {0x11650, 0x11659}, {0x116c0, 0x116c9}, {0x11730, 0x11739}, {0x118e0, 0x118e9}, - {0x11c50, 0x11c59}, {0x11d50, 0x11d59}, {0x16a60, 0x16a69}, {0x16b50, 0x16b59}, - {0x1d7ce, 0x1d7ff}, {0x1e950, 0x1e959} + ,{0x104a0, 0x104a9}, {0x10d30, 0x10d39}, {0x11066, 0x1106f}, {0x110f0, 0x110f9}, + {0x11136, 0x1113f}, {0x111d0, 0x111d9}, {0x112f0, 0x112f9}, {0x11450, 0x11459}, + {0x114d0, 0x114d9}, {0x11650, 0x11659}, {0x116c0, 0x116c9}, {0x11730, 0x11739}, + {0x118e0, 0x118e9}, {0x11c50, 0x11c59}, {0x11d50, 0x11d59}, {0x11da0, 0x11da9}, + {0x16a60, 0x16a69}, {0x16b50, 0x16b59}, {0x1d7ce, 0x1d7ff}, {0x1e950, 0x1e959} #endif }; @@ -344,7 +348,7 @@ static const crange punctRangeTable[] = { {0x1b5a, 0x1b60}, {0x1bfc, 0x1bff}, {0x1c3b, 0x1c3f}, {0x1cc0, 0x1cc7}, {0x2010, 0x2027}, {0x2030, 0x2043}, {0x2045, 0x2051}, {0x2053, 0x205e}, {0x2308, 0x230b}, {0x2768, 0x2775}, {0x27e6, 0x27ef}, {0x2983, 0x2998}, - {0x29d8, 0x29db}, {0x2cf9, 0x2cfc}, {0x2e00, 0x2e2e}, {0x2e30, 0x2e49}, + {0x29d8, 0x29db}, {0x2cf9, 0x2cfc}, {0x2e00, 0x2e2e}, {0x2e30, 0x2e4e}, {0x3001, 0x3003}, {0x3008, 0x3011}, {0x3014, 0x301f}, {0xa60d, 0xa60f}, {0xa6f2, 0xa6f7}, {0xa874, 0xa877}, {0xa8f8, 0xa8fa}, {0xa9c1, 0xa9cd}, {0xaa5c, 0xaa5f}, {0xfe10, 0xfe19}, {0xfe30, 0xfe52}, {0xfe54, 0xfe61}, @@ -352,11 +356,12 @@ static const crange punctRangeTable[] = { {0xff5f, 0xff65} #if CHRBITS > 16 ,{0x10100, 0x10102}, {0x10a50, 0x10a58}, {0x10af0, 0x10af6}, {0x10b39, 0x10b3f}, - {0x10b99, 0x10b9c}, {0x11047, 0x1104d}, {0x110be, 0x110c1}, {0x11140, 0x11143}, - {0x111c5, 0x111c9}, {0x111dd, 0x111df}, {0x11238, 0x1123d}, {0x1144b, 0x1144f}, - {0x115c1, 0x115d7}, {0x11641, 0x11643}, {0x11660, 0x1166c}, {0x1173c, 0x1173e}, - {0x11a3f, 0x11a46}, {0x11a9a, 0x11a9c}, {0x11a9e, 0x11aa2}, {0x11c41, 0x11c45}, - {0x12470, 0x12474}, {0x16b37, 0x16b3b}, {0x1da87, 0x1da8b} + {0x10b99, 0x10b9c}, {0x10f55, 0x10f59}, {0x11047, 0x1104d}, {0x110be, 0x110c1}, + {0x11140, 0x11143}, {0x111c5, 0x111c8}, {0x111dd, 0x111df}, {0x11238, 0x1123d}, + {0x1144b, 0x1144f}, {0x115c1, 0x115d7}, {0x11641, 0x11643}, {0x11660, 0x1166c}, + {0x1173c, 0x1173e}, {0x11a3f, 0x11a46}, {0x11a9a, 0x11a9c}, {0x11a9e, 0x11aa2}, + {0x11c41, 0x11c45}, {0x12470, 0x12474}, {0x16b37, 0x16b3b}, {0x16e97, 0x16e9a}, + {0x1da87, 0x1da8b} #endif }; @@ -367,18 +372,20 @@ static const chr punctCharTable[] = { 0xab, 0xb6, 0xb7, 0xbb, 0xbf, 0x37e, 0x387, 0x589, 0x58a, 0x5be, 0x5c0, 0x5c3, 0x5c6, 0x5f3, 0x5f4, 0x609, 0x60a, 0x60c, 0x60d, 0x61b, 0x61e, 0x61f, 0x6d4, 0x85e, 0x964, 0x965, 0x970, - 0x9fd, 0xaf0, 0xdf4, 0xe4f, 0xe5a, 0xe5b, 0xf14, 0xf85, 0xfd9, - 0xfda, 0x10fb, 0x1400, 0x166d, 0x166e, 0x169b, 0x169c, 0x1735, 0x1736, - 0x1944, 0x1945, 0x1a1e, 0x1a1f, 0x1c7e, 0x1c7f, 0x1cd3, 0x207d, 0x207e, - 0x208d, 0x208e, 0x2329, 0x232a, 0x27c5, 0x27c6, 0x29fc, 0x29fd, 0x2cfe, - 0x2cff, 0x2d70, 0x3030, 0x303d, 0x30a0, 0x30fb, 0xa4fe, 0xa4ff, 0xa673, - 0xa67e, 0xa8ce, 0xa8cf, 0xa8fc, 0xa92e, 0xa92f, 0xa95f, 0xa9de, 0xa9df, - 0xaade, 0xaadf, 0xaaf0, 0xaaf1, 0xabeb, 0xfd3e, 0xfd3f, 0xfe63, 0xfe68, - 0xfe6a, 0xfe6b, 0xff1a, 0xff1b, 0xff1f, 0xff20, 0xff3f, 0xff5b, 0xff5d + 0x9fd, 0xa76, 0xaf0, 0xc84, 0xdf4, 0xe4f, 0xe5a, 0xe5b, 0xf14, + 0xf85, 0xfd9, 0xfda, 0x10fb, 0x1400, 0x166d, 0x166e, 0x169b, 0x169c, + 0x1735, 0x1736, 0x1944, 0x1945, 0x1a1e, 0x1a1f, 0x1c7e, 0x1c7f, 0x1cd3, + 0x207d, 0x207e, 0x208d, 0x208e, 0x2329, 0x232a, 0x27c5, 0x27c6, 0x29fc, + 0x29fd, 0x2cfe, 0x2cff, 0x2d70, 0x3030, 0x303d, 0x30a0, 0x30fb, 0xa4fe, + 0xa4ff, 0xa673, 0xa67e, 0xa8ce, 0xa8cf, 0xa8fc, 0xa92e, 0xa92f, 0xa95f, + 0xa9de, 0xa9df, 0xaade, 0xaadf, 0xaaf0, 0xaaf1, 0xabeb, 0xfd3e, 0xfd3f, + 0xfe63, 0xfe68, 0xfe6a, 0xfe6b, 0xff1a, 0xff1b, 0xff1f, 0xff20, 0xff3f, + 0xff5b, 0xff5d #if CHRBITS > 16 ,0x1039f, 0x103d0, 0x1056f, 0x10857, 0x1091f, 0x1093f, 0x10a7f, 0x110bb, 0x110bc, - 0x11174, 0x11175, 0x111cd, 0x111db, 0x112a9, 0x1145b, 0x1145d, 0x114c6, 0x11c70, - 0x11c71, 0x16a6e, 0x16a6f, 0x16af5, 0x16b44, 0x1bc9f, 0x1e95e, 0x1e95f + 0x11174, 0x11175, 0x111cd, 0x111db, 0x112a9, 0x1145b, 0x1145d, 0x114c6, 0x1183b, + 0x11c70, 0x11c71, 0x11ef7, 0x11ef8, 0x16a6e, 0x16a6f, 0x16af5, 0x16b44, 0x1bc9f, + 0x1e95e, 0x1e95f #endif }; @@ -409,25 +416,25 @@ static const crange lowerRangeTable[] = { {0x61, 0x7a}, {0xdf, 0xf6}, {0xf8, 0xff}, {0x17e, 0x180}, {0x199, 0x19b}, {0x1bd, 0x1bf}, {0x233, 0x239}, {0x24f, 0x293}, {0x295, 0x2af}, {0x37b, 0x37d}, {0x3ac, 0x3ce}, {0x3d5, 0x3d7}, - {0x3ef, 0x3f3}, {0x430, 0x45f}, {0x561, 0x587}, {0x13f8, 0x13fd}, - {0x1c80, 0x1c88}, {0x1d00, 0x1d2b}, {0x1d6b, 0x1d77}, {0x1d79, 0x1d9a}, - {0x1e95, 0x1e9d}, {0x1eff, 0x1f07}, {0x1f10, 0x1f15}, {0x1f20, 0x1f27}, - {0x1f30, 0x1f37}, {0x1f40, 0x1f45}, {0x1f50, 0x1f57}, {0x1f60, 0x1f67}, - {0x1f70, 0x1f7d}, {0x1f80, 0x1f87}, {0x1f90, 0x1f97}, {0x1fa0, 0x1fa7}, - {0x1fb0, 0x1fb4}, {0x1fc2, 0x1fc4}, {0x1fd0, 0x1fd3}, {0x1fe0, 0x1fe7}, - {0x1ff2, 0x1ff4}, {0x2146, 0x2149}, {0x2c30, 0x2c5e}, {0x2c76, 0x2c7b}, - {0x2d00, 0x2d25}, {0xa72f, 0xa731}, {0xa771, 0xa778}, {0xa793, 0xa795}, - {0xab30, 0xab5a}, {0xab60, 0xab65}, {0xab70, 0xabbf}, {0xfb00, 0xfb06}, - {0xfb13, 0xfb17}, {0xff41, 0xff5a} + {0x3ef, 0x3f3}, {0x430, 0x45f}, {0x560, 0x588}, {0x10d0, 0x10fa}, + {0x10fd, 0x10ff}, {0x13f8, 0x13fd}, {0x1c80, 0x1c88}, {0x1d00, 0x1d2b}, + {0x1d6b, 0x1d77}, {0x1d79, 0x1d9a}, {0x1e95, 0x1e9d}, {0x1eff, 0x1f07}, + {0x1f10, 0x1f15}, {0x1f20, 0x1f27}, {0x1f30, 0x1f37}, {0x1f40, 0x1f45}, + {0x1f50, 0x1f57}, {0x1f60, 0x1f67}, {0x1f70, 0x1f7d}, {0x1f80, 0x1f87}, + {0x1f90, 0x1f97}, {0x1fa0, 0x1fa7}, {0x1fb0, 0x1fb4}, {0x1fc2, 0x1fc4}, + {0x1fd0, 0x1fd3}, {0x1fe0, 0x1fe7}, {0x1ff2, 0x1ff4}, {0x2146, 0x2149}, + {0x2c30, 0x2c5e}, {0x2c76, 0x2c7b}, {0x2d00, 0x2d25}, {0xa72f, 0xa731}, + {0xa771, 0xa778}, {0xa793, 0xa795}, {0xab30, 0xab5a}, {0xab60, 0xab65}, + {0xab70, 0xabbf}, {0xfb00, 0xfb06}, {0xfb13, 0xfb17}, {0xff41, 0xff5a} #if CHRBITS > 16 ,{0x10428, 0x1044f}, {0x104d8, 0x104fb}, {0x10cc0, 0x10cf2}, {0x118c0, 0x118df}, - {0x1d41a, 0x1d433}, {0x1d44e, 0x1d454}, {0x1d456, 0x1d467}, {0x1d482, 0x1d49b}, - {0x1d4b6, 0x1d4b9}, {0x1d4bd, 0x1d4c3}, {0x1d4c5, 0x1d4cf}, {0x1d4ea, 0x1d503}, - {0x1d51e, 0x1d537}, {0x1d552, 0x1d56b}, {0x1d586, 0x1d59f}, {0x1d5ba, 0x1d5d3}, - {0x1d5ee, 0x1d607}, {0x1d622, 0x1d63b}, {0x1d656, 0x1d66f}, {0x1d68a, 0x1d6a5}, - {0x1d6c2, 0x1d6da}, {0x1d6dc, 0x1d6e1}, {0x1d6fc, 0x1d714}, {0x1d716, 0x1d71b}, - {0x1d736, 0x1d74e}, {0x1d750, 0x1d755}, {0x1d770, 0x1d788}, {0x1d78a, 0x1d78f}, - {0x1d7aa, 0x1d7c2}, {0x1d7c4, 0x1d7c9}, {0x1e922, 0x1e943} + {0x16e60, 0x16e7f}, {0x1d41a, 0x1d433}, {0x1d44e, 0x1d454}, {0x1d456, 0x1d467}, + {0x1d482, 0x1d49b}, {0x1d4b6, 0x1d4b9}, {0x1d4bd, 0x1d4c3}, {0x1d4c5, 0x1d4cf}, + {0x1d4ea, 0x1d503}, {0x1d51e, 0x1d537}, {0x1d552, 0x1d56b}, {0x1d586, 0x1d59f}, + {0x1d5ba, 0x1d5d3}, {0x1d5ee, 0x1d607}, {0x1d622, 0x1d63b}, {0x1d656, 0x1d66f}, + {0x1d68a, 0x1d6a5}, {0x1d6c2, 0x1d6da}, {0x1d6dc, 0x1d6e1}, {0x1d6fc, 0x1d714}, + {0x1d716, 0x1d71b}, {0x1d736, 0x1d74e}, {0x1d750, 0x1d755}, {0x1d770, 0x1d788}, + {0x1d78a, 0x1d78f}, {0x1d7aa, 0x1d7c2}, {0x1d7c4, 0x1d7c9}, {0x1e922, 0x1e943} #endif }; @@ -497,7 +504,7 @@ static const chr lowerCharTable[] = { 0xa763, 0xa765, 0xa767, 0xa769, 0xa76b, 0xa76d, 0xa76f, 0xa77a, 0xa77c, 0xa77f, 0xa781, 0xa783, 0xa785, 0xa787, 0xa78c, 0xa78e, 0xa791, 0xa797, 0xa799, 0xa79b, 0xa79d, 0xa79f, 0xa7a1, 0xa7a3, 0xa7a5, 0xa7a7, 0xa7a9, - 0xa7b5, 0xa7b7, 0xa7fa + 0xa7af, 0xa7b5, 0xa7b7, 0xa7b9, 0xa7fa #if CHRBITS > 16 ,0x1d4bb, 0x1d7cb #endif @@ -514,20 +521,22 @@ static const crange upperRangeTable[] = { {0x18e, 0x191}, {0x196, 0x198}, {0x1b1, 0x1b3}, {0x1f6, 0x1f8}, {0x243, 0x246}, {0x388, 0x38a}, {0x391, 0x3a1}, {0x3a3, 0x3ab}, {0x3d2, 0x3d4}, {0x3fd, 0x42f}, {0x531, 0x556}, {0x10a0, 0x10c5}, - {0x13a0, 0x13f5}, {0x1f08, 0x1f0f}, {0x1f18, 0x1f1d}, {0x1f28, 0x1f2f}, - {0x1f38, 0x1f3f}, {0x1f48, 0x1f4d}, {0x1f68, 0x1f6f}, {0x1fb8, 0x1fbb}, - {0x1fc8, 0x1fcb}, {0x1fd8, 0x1fdb}, {0x1fe8, 0x1fec}, {0x1ff8, 0x1ffb}, - {0x210b, 0x210d}, {0x2110, 0x2112}, {0x2119, 0x211d}, {0x212a, 0x212d}, - {0x2130, 0x2133}, {0x2c00, 0x2c2e}, {0x2c62, 0x2c64}, {0x2c6d, 0x2c70}, - {0x2c7e, 0x2c80}, {0xa7aa, 0xa7ae}, {0xa7b0, 0xa7b4}, {0xff21, 0xff3a} + {0x13a0, 0x13f5}, {0x1c90, 0x1cba}, {0x1cbd, 0x1cbf}, {0x1f08, 0x1f0f}, + {0x1f18, 0x1f1d}, {0x1f28, 0x1f2f}, {0x1f38, 0x1f3f}, {0x1f48, 0x1f4d}, + {0x1f68, 0x1f6f}, {0x1fb8, 0x1fbb}, {0x1fc8, 0x1fcb}, {0x1fd8, 0x1fdb}, + {0x1fe8, 0x1fec}, {0x1ff8, 0x1ffb}, {0x210b, 0x210d}, {0x2110, 0x2112}, + {0x2119, 0x211d}, {0x212a, 0x212d}, {0x2130, 0x2133}, {0x2c00, 0x2c2e}, + {0x2c62, 0x2c64}, {0x2c6d, 0x2c70}, {0x2c7e, 0x2c80}, {0xa7aa, 0xa7ae}, + {0xa7b0, 0xa7b4}, {0xff21, 0xff3a} #if CHRBITS > 16 ,{0x10400, 0x10427}, {0x104b0, 0x104d3}, {0x10c80, 0x10cb2}, {0x118a0, 0x118bf}, - {0x1d400, 0x1d419}, {0x1d434, 0x1d44d}, {0x1d468, 0x1d481}, {0x1d4a9, 0x1d4ac}, - {0x1d4ae, 0x1d4b5}, {0x1d4d0, 0x1d4e9}, {0x1d507, 0x1d50a}, {0x1d50d, 0x1d514}, - {0x1d516, 0x1d51c}, {0x1d53b, 0x1d53e}, {0x1d540, 0x1d544}, {0x1d54a, 0x1d550}, - {0x1d56c, 0x1d585}, {0x1d5a0, 0x1d5b9}, {0x1d5d4, 0x1d5ed}, {0x1d608, 0x1d621}, - {0x1d63c, 0x1d655}, {0x1d670, 0x1d689}, {0x1d6a8, 0x1d6c0}, {0x1d6e2, 0x1d6fa}, - {0x1d71c, 0x1d734}, {0x1d756, 0x1d76e}, {0x1d790, 0x1d7a8}, {0x1e900, 0x1e921} + {0x16e40, 0x16e5f}, {0x1d400, 0x1d419}, {0x1d434, 0x1d44d}, {0x1d468, 0x1d481}, + {0x1d4a9, 0x1d4ac}, {0x1d4ae, 0x1d4b5}, {0x1d4d0, 0x1d4e9}, {0x1d507, 0x1d50a}, + {0x1d50d, 0x1d514}, {0x1d516, 0x1d51c}, {0x1d53b, 0x1d53e}, {0x1d540, 0x1d544}, + {0x1d54a, 0x1d550}, {0x1d56c, 0x1d585}, {0x1d5a0, 0x1d5b9}, {0x1d5d4, 0x1d5ed}, + {0x1d608, 0x1d621}, {0x1d63c, 0x1d655}, {0x1d670, 0x1d689}, {0x1d6a8, 0x1d6c0}, + {0x1d6e2, 0x1d6fa}, {0x1d71c, 0x1d734}, {0x1d756, 0x1d76e}, {0x1d790, 0x1d7a8}, + {0x1e900, 0x1e921} #endif }; @@ -596,7 +605,8 @@ static const chr upperCharTable[] = { 0xa756, 0xa758, 0xa75a, 0xa75c, 0xa75e, 0xa760, 0xa762, 0xa764, 0xa766, 0xa768, 0xa76a, 0xa76c, 0xa76e, 0xa779, 0xa77b, 0xa77d, 0xa77e, 0xa780, 0xa782, 0xa784, 0xa786, 0xa78b, 0xa78d, 0xa790, 0xa792, 0xa796, 0xa798, - 0xa79a, 0xa79c, 0xa79e, 0xa7a0, 0xa7a2, 0xa7a4, 0xa7a6, 0xa7a8, 0xa7b6 + 0xa79a, 0xa79c, 0xa79e, 0xa7a0, 0xa7a2, 0xa7a4, 0xa7a6, 0xa7a8, 0xa7b6, + 0xa7b8 #if CHRBITS > 16 ,0x1d49c, 0x1d49e, 0x1d49f, 0x1d4a2, 0x1d4a5, 0x1d4a6, 0x1d504, 0x1d505, 0x1d538, 0x1d539, 0x1d546, 0x1d7ca @@ -612,80 +622,79 @@ static const chr upperCharTable[] = { static const crange graphRangeTable[] = { {0x21, 0x7e}, {0xa1, 0xac}, {0xae, 0x377}, {0x37a, 0x37f}, {0x384, 0x38a}, {0x38e, 0x3a1}, {0x3a3, 0x52f}, {0x531, 0x556}, - {0x559, 0x55f}, {0x561, 0x587}, {0x58d, 0x58f}, {0x591, 0x5c7}, - {0x5d0, 0x5ea}, {0x5f0, 0x5f4}, {0x606, 0x61b}, {0x61e, 0x6dc}, - {0x6de, 0x70d}, {0x710, 0x74a}, {0x74d, 0x7b1}, {0x7c0, 0x7fa}, - {0x800, 0x82d}, {0x830, 0x83e}, {0x840, 0x85b}, {0x860, 0x86a}, - {0x8a0, 0x8b4}, {0x8b6, 0x8bd}, {0x8d4, 0x8e1}, {0x8e3, 0x983}, - {0x985, 0x98c}, {0x993, 0x9a8}, {0x9aa, 0x9b0}, {0x9b6, 0x9b9}, - {0x9bc, 0x9c4}, {0x9cb, 0x9ce}, {0x9df, 0x9e3}, {0x9e6, 0x9fd}, - {0xa01, 0xa03}, {0xa05, 0xa0a}, {0xa13, 0xa28}, {0xa2a, 0xa30}, - {0xa3e, 0xa42}, {0xa4b, 0xa4d}, {0xa59, 0xa5c}, {0xa66, 0xa75}, - {0xa81, 0xa83}, {0xa85, 0xa8d}, {0xa8f, 0xa91}, {0xa93, 0xaa8}, - {0xaaa, 0xab0}, {0xab5, 0xab9}, {0xabc, 0xac5}, {0xac7, 0xac9}, - {0xacb, 0xacd}, {0xae0, 0xae3}, {0xae6, 0xaf1}, {0xaf9, 0xaff}, - {0xb01, 0xb03}, {0xb05, 0xb0c}, {0xb13, 0xb28}, {0xb2a, 0xb30}, - {0xb35, 0xb39}, {0xb3c, 0xb44}, {0xb4b, 0xb4d}, {0xb5f, 0xb63}, - {0xb66, 0xb77}, {0xb85, 0xb8a}, {0xb8e, 0xb90}, {0xb92, 0xb95}, - {0xba8, 0xbaa}, {0xbae, 0xbb9}, {0xbbe, 0xbc2}, {0xbc6, 0xbc8}, - {0xbca, 0xbcd}, {0xbe6, 0xbfa}, {0xc00, 0xc03}, {0xc05, 0xc0c}, - {0xc0e, 0xc10}, {0xc12, 0xc28}, {0xc2a, 0xc39}, {0xc3d, 0xc44}, - {0xc46, 0xc48}, {0xc4a, 0xc4d}, {0xc58, 0xc5a}, {0xc60, 0xc63}, - {0xc66, 0xc6f}, {0xc78, 0xc83}, {0xc85, 0xc8c}, {0xc8e, 0xc90}, - {0xc92, 0xca8}, {0xcaa, 0xcb3}, {0xcb5, 0xcb9}, {0xcbc, 0xcc4}, - {0xcc6, 0xcc8}, {0xcca, 0xccd}, {0xce0, 0xce3}, {0xce6, 0xcef}, - {0xd00, 0xd03}, {0xd05, 0xd0c}, {0xd0e, 0xd10}, {0xd12, 0xd44}, - {0xd46, 0xd48}, {0xd4a, 0xd4f}, {0xd54, 0xd63}, {0xd66, 0xd7f}, - {0xd85, 0xd96}, {0xd9a, 0xdb1}, {0xdb3, 0xdbb}, {0xdc0, 0xdc6}, - {0xdcf, 0xdd4}, {0xdd8, 0xddf}, {0xde6, 0xdef}, {0xdf2, 0xdf4}, - {0xe01, 0xe3a}, {0xe3f, 0xe5b}, {0xe94, 0xe97}, {0xe99, 0xe9f}, - {0xea1, 0xea3}, {0xead, 0xeb9}, {0xebb, 0xebd}, {0xec0, 0xec4}, - {0xec8, 0xecd}, {0xed0, 0xed9}, {0xedc, 0xedf}, {0xf00, 0xf47}, - {0xf49, 0xf6c}, {0xf71, 0xf97}, {0xf99, 0xfbc}, {0xfbe, 0xfcc}, - {0xfce, 0xfda}, {0x1000, 0x10c5}, {0x10d0, 0x1248}, {0x124a, 0x124d}, - {0x1250, 0x1256}, {0x125a, 0x125d}, {0x1260, 0x1288}, {0x128a, 0x128d}, - {0x1290, 0x12b0}, {0x12b2, 0x12b5}, {0x12b8, 0x12be}, {0x12c2, 0x12c5}, - {0x12c8, 0x12d6}, {0x12d8, 0x1310}, {0x1312, 0x1315}, {0x1318, 0x135a}, - {0x135d, 0x137c}, {0x1380, 0x1399}, {0x13a0, 0x13f5}, {0x13f8, 0x13fd}, - {0x1400, 0x167f}, {0x1681, 0x169c}, {0x16a0, 0x16f8}, {0x1700, 0x170c}, - {0x170e, 0x1714}, {0x1720, 0x1736}, {0x1740, 0x1753}, {0x1760, 0x176c}, - {0x176e, 0x1770}, {0x1780, 0x17dd}, {0x17e0, 0x17e9}, {0x17f0, 0x17f9}, - {0x1800, 0x180d}, {0x1810, 0x1819}, {0x1820, 0x1877}, {0x1880, 0x18aa}, - {0x18b0, 0x18f5}, {0x1900, 0x191e}, {0x1920, 0x192b}, {0x1930, 0x193b}, - {0x1944, 0x196d}, {0x1970, 0x1974}, {0x1980, 0x19ab}, {0x19b0, 0x19c9}, - {0x19d0, 0x19da}, {0x19de, 0x1a1b}, {0x1a1e, 0x1a5e}, {0x1a60, 0x1a7c}, - {0x1a7f, 0x1a89}, {0x1a90, 0x1a99}, {0x1aa0, 0x1aad}, {0x1ab0, 0x1abe}, - {0x1b00, 0x1b4b}, {0x1b50, 0x1b7c}, {0x1b80, 0x1bf3}, {0x1bfc, 0x1c37}, - {0x1c3b, 0x1c49}, {0x1c4d, 0x1c88}, {0x1cc0, 0x1cc7}, {0x1cd0, 0x1cf9}, - {0x1d00, 0x1df9}, {0x1dfb, 0x1f15}, {0x1f18, 0x1f1d}, {0x1f20, 0x1f45}, - {0x1f48, 0x1f4d}, {0x1f50, 0x1f57}, {0x1f5f, 0x1f7d}, {0x1f80, 0x1fb4}, - {0x1fb6, 0x1fc4}, {0x1fc6, 0x1fd3}, {0x1fd6, 0x1fdb}, {0x1fdd, 0x1fef}, - {0x1ff2, 0x1ff4}, {0x1ff6, 0x1ffe}, {0x2010, 0x2027}, {0x2030, 0x205e}, - {0x2074, 0x208e}, {0x2090, 0x209c}, {0x20a0, 0x20bf}, {0x20d0, 0x20f0}, - {0x2100, 0x218b}, {0x2190, 0x2426}, {0x2440, 0x244a}, {0x2460, 0x2b73}, - {0x2b76, 0x2b95}, {0x2b98, 0x2bb9}, {0x2bbd, 0x2bc8}, {0x2bca, 0x2bd2}, - {0x2bec, 0x2bef}, {0x2c00, 0x2c2e}, {0x2c30, 0x2c5e}, {0x2c60, 0x2cf3}, + {0x559, 0x58a}, {0x58d, 0x58f}, {0x591, 0x5c7}, {0x5d0, 0x5ea}, + {0x5ef, 0x5f4}, {0x606, 0x61b}, {0x61e, 0x6dc}, {0x6de, 0x70d}, + {0x710, 0x74a}, {0x74d, 0x7b1}, {0x7c0, 0x7fa}, {0x7fd, 0x82d}, + {0x830, 0x83e}, {0x840, 0x85b}, {0x860, 0x86a}, {0x8a0, 0x8b4}, + {0x8b6, 0x8bd}, {0x8d3, 0x8e1}, {0x8e3, 0x983}, {0x985, 0x98c}, + {0x993, 0x9a8}, {0x9aa, 0x9b0}, {0x9b6, 0x9b9}, {0x9bc, 0x9c4}, + {0x9cb, 0x9ce}, {0x9df, 0x9e3}, {0x9e6, 0x9fe}, {0xa01, 0xa03}, + {0xa05, 0xa0a}, {0xa13, 0xa28}, {0xa2a, 0xa30}, {0xa3e, 0xa42}, + {0xa4b, 0xa4d}, {0xa59, 0xa5c}, {0xa66, 0xa76}, {0xa81, 0xa83}, + {0xa85, 0xa8d}, {0xa8f, 0xa91}, {0xa93, 0xaa8}, {0xaaa, 0xab0}, + {0xab5, 0xab9}, {0xabc, 0xac5}, {0xac7, 0xac9}, {0xacb, 0xacd}, + {0xae0, 0xae3}, {0xae6, 0xaf1}, {0xaf9, 0xaff}, {0xb01, 0xb03}, + {0xb05, 0xb0c}, {0xb13, 0xb28}, {0xb2a, 0xb30}, {0xb35, 0xb39}, + {0xb3c, 0xb44}, {0xb4b, 0xb4d}, {0xb5f, 0xb63}, {0xb66, 0xb77}, + {0xb85, 0xb8a}, {0xb8e, 0xb90}, {0xb92, 0xb95}, {0xba8, 0xbaa}, + {0xbae, 0xbb9}, {0xbbe, 0xbc2}, {0xbc6, 0xbc8}, {0xbca, 0xbcd}, + {0xbe6, 0xbfa}, {0xc00, 0xc0c}, {0xc0e, 0xc10}, {0xc12, 0xc28}, + {0xc2a, 0xc39}, {0xc3d, 0xc44}, {0xc46, 0xc48}, {0xc4a, 0xc4d}, + {0xc58, 0xc5a}, {0xc60, 0xc63}, {0xc66, 0xc6f}, {0xc78, 0xc8c}, + {0xc8e, 0xc90}, {0xc92, 0xca8}, {0xcaa, 0xcb3}, {0xcb5, 0xcb9}, + {0xcbc, 0xcc4}, {0xcc6, 0xcc8}, {0xcca, 0xccd}, {0xce0, 0xce3}, + {0xce6, 0xcef}, {0xd00, 0xd03}, {0xd05, 0xd0c}, {0xd0e, 0xd10}, + {0xd12, 0xd44}, {0xd46, 0xd48}, {0xd4a, 0xd4f}, {0xd54, 0xd63}, + {0xd66, 0xd7f}, {0xd85, 0xd96}, {0xd9a, 0xdb1}, {0xdb3, 0xdbb}, + {0xdc0, 0xdc6}, {0xdcf, 0xdd4}, {0xdd8, 0xddf}, {0xde6, 0xdef}, + {0xdf2, 0xdf4}, {0xe01, 0xe3a}, {0xe3f, 0xe5b}, {0xe94, 0xe97}, + {0xe99, 0xe9f}, {0xea1, 0xea3}, {0xead, 0xeb9}, {0xebb, 0xebd}, + {0xec0, 0xec4}, {0xec8, 0xecd}, {0xed0, 0xed9}, {0xedc, 0xedf}, + {0xf00, 0xf47}, {0xf49, 0xf6c}, {0xf71, 0xf97}, {0xf99, 0xfbc}, + {0xfbe, 0xfcc}, {0xfce, 0xfda}, {0x1000, 0x10c5}, {0x10d0, 0x1248}, + {0x124a, 0x124d}, {0x1250, 0x1256}, {0x125a, 0x125d}, {0x1260, 0x1288}, + {0x128a, 0x128d}, {0x1290, 0x12b0}, {0x12b2, 0x12b5}, {0x12b8, 0x12be}, + {0x12c2, 0x12c5}, {0x12c8, 0x12d6}, {0x12d8, 0x1310}, {0x1312, 0x1315}, + {0x1318, 0x135a}, {0x135d, 0x137c}, {0x1380, 0x1399}, {0x13a0, 0x13f5}, + {0x13f8, 0x13fd}, {0x1400, 0x167f}, {0x1681, 0x169c}, {0x16a0, 0x16f8}, + {0x1700, 0x170c}, {0x170e, 0x1714}, {0x1720, 0x1736}, {0x1740, 0x1753}, + {0x1760, 0x176c}, {0x176e, 0x1770}, {0x1780, 0x17dd}, {0x17e0, 0x17e9}, + {0x17f0, 0x17f9}, {0x1800, 0x180d}, {0x1810, 0x1819}, {0x1820, 0x1878}, + {0x1880, 0x18aa}, {0x18b0, 0x18f5}, {0x1900, 0x191e}, {0x1920, 0x192b}, + {0x1930, 0x193b}, {0x1944, 0x196d}, {0x1970, 0x1974}, {0x1980, 0x19ab}, + {0x19b0, 0x19c9}, {0x19d0, 0x19da}, {0x19de, 0x1a1b}, {0x1a1e, 0x1a5e}, + {0x1a60, 0x1a7c}, {0x1a7f, 0x1a89}, {0x1a90, 0x1a99}, {0x1aa0, 0x1aad}, + {0x1ab0, 0x1abe}, {0x1b00, 0x1b4b}, {0x1b50, 0x1b7c}, {0x1b80, 0x1bf3}, + {0x1bfc, 0x1c37}, {0x1c3b, 0x1c49}, {0x1c4d, 0x1c88}, {0x1c90, 0x1cba}, + {0x1cbd, 0x1cc7}, {0x1cd0, 0x1cf9}, {0x1d00, 0x1df9}, {0x1dfb, 0x1f15}, + {0x1f18, 0x1f1d}, {0x1f20, 0x1f45}, {0x1f48, 0x1f4d}, {0x1f50, 0x1f57}, + {0x1f5f, 0x1f7d}, {0x1f80, 0x1fb4}, {0x1fb6, 0x1fc4}, {0x1fc6, 0x1fd3}, + {0x1fd6, 0x1fdb}, {0x1fdd, 0x1fef}, {0x1ff2, 0x1ff4}, {0x1ff6, 0x1ffe}, + {0x2010, 0x2027}, {0x2030, 0x205e}, {0x2074, 0x208e}, {0x2090, 0x209c}, + {0x20a0, 0x20bf}, {0x20d0, 0x20f0}, {0x2100, 0x218b}, {0x2190, 0x2426}, + {0x2440, 0x244a}, {0x2460, 0x2b73}, {0x2b76, 0x2b95}, {0x2b98, 0x2bc8}, + {0x2bca, 0x2bfe}, {0x2c00, 0x2c2e}, {0x2c30, 0x2c5e}, {0x2c60, 0x2cf3}, {0x2cf9, 0x2d25}, {0x2d30, 0x2d67}, {0x2d7f, 0x2d96}, {0x2da0, 0x2da6}, {0x2da8, 0x2dae}, {0x2db0, 0x2db6}, {0x2db8, 0x2dbe}, {0x2dc0, 0x2dc6}, - {0x2dc8, 0x2dce}, {0x2dd0, 0x2dd6}, {0x2dd8, 0x2dde}, {0x2de0, 0x2e49}, + {0x2dc8, 0x2dce}, {0x2dd0, 0x2dd6}, {0x2dd8, 0x2dde}, {0x2de0, 0x2e4e}, {0x2e80, 0x2e99}, {0x2e9b, 0x2ef3}, {0x2f00, 0x2fd5}, {0x2ff0, 0x2ffb}, - {0x3001, 0x303f}, {0x3041, 0x3096}, {0x3099, 0x30ff}, {0x3105, 0x312e}, + {0x3001, 0x303f}, {0x3041, 0x3096}, {0x3099, 0x30ff}, {0x3105, 0x312f}, {0x3131, 0x318e}, {0x3190, 0x31ba}, {0x31c0, 0x31e3}, {0x31f0, 0x321e}, - {0x3220, 0x32fe}, {0x3300, 0x4db5}, {0x4dc0, 0x9fea}, {0xa000, 0xa48c}, - {0xa490, 0xa4c6}, {0xa4d0, 0xa62b}, {0xa640, 0xa6f7}, {0xa700, 0xa7ae}, - {0xa7b0, 0xa7b7}, {0xa7f7, 0xa82b}, {0xa830, 0xa839}, {0xa840, 0xa877}, - {0xa880, 0xa8c5}, {0xa8ce, 0xa8d9}, {0xa8e0, 0xa8fd}, {0xa900, 0xa953}, - {0xa95f, 0xa97c}, {0xa980, 0xa9cd}, {0xa9cf, 0xa9d9}, {0xa9de, 0xa9fe}, - {0xaa00, 0xaa36}, {0xaa40, 0xaa4d}, {0xaa50, 0xaa59}, {0xaa5c, 0xaac2}, - {0xaadb, 0xaaf6}, {0xab01, 0xab06}, {0xab09, 0xab0e}, {0xab11, 0xab16}, - {0xab20, 0xab26}, {0xab28, 0xab2e}, {0xab30, 0xab65}, {0xab70, 0xabed}, - {0xabf0, 0xabf9}, {0xac00, 0xd7a3}, {0xd7b0, 0xd7c6}, {0xd7cb, 0xd7fb}, - {0xf900, 0xfa6d}, {0xfa70, 0xfad9}, {0xfb00, 0xfb06}, {0xfb13, 0xfb17}, - {0xfb1d, 0xfb36}, {0xfb38, 0xfb3c}, {0xfb46, 0xfbc1}, {0xfbd3, 0xfd3f}, - {0xfd50, 0xfd8f}, {0xfd92, 0xfdc7}, {0xfdf0, 0xfdfd}, {0xfe00, 0xfe19}, - {0xfe20, 0xfe52}, {0xfe54, 0xfe66}, {0xfe68, 0xfe6b}, {0xfe70, 0xfe74}, - {0xfe76, 0xfefc}, {0xff01, 0xffbe}, {0xffc2, 0xffc7}, {0xffca, 0xffcf}, - {0xffd2, 0xffd7}, {0xffda, 0xffdc}, {0xffe0, 0xffe6}, {0xffe8, 0xffee} + {0x3220, 0x32fe}, {0x3300, 0x4db5}, {0x4dc0, 0x9fef}, {0xa000, 0xa48c}, + {0xa490, 0xa4c6}, {0xa4d0, 0xa62b}, {0xa640, 0xa6f7}, {0xa700, 0xa7b9}, + {0xa7f7, 0xa82b}, {0xa830, 0xa839}, {0xa840, 0xa877}, {0xa880, 0xa8c5}, + {0xa8ce, 0xa8d9}, {0xa8e0, 0xa953}, {0xa95f, 0xa97c}, {0xa980, 0xa9cd}, + {0xa9cf, 0xa9d9}, {0xa9de, 0xa9fe}, {0xaa00, 0xaa36}, {0xaa40, 0xaa4d}, + {0xaa50, 0xaa59}, {0xaa5c, 0xaac2}, {0xaadb, 0xaaf6}, {0xab01, 0xab06}, + {0xab09, 0xab0e}, {0xab11, 0xab16}, {0xab20, 0xab26}, {0xab28, 0xab2e}, + {0xab30, 0xab65}, {0xab70, 0xabed}, {0xabf0, 0xabf9}, {0xac00, 0xd7a3}, + {0xd7b0, 0xd7c6}, {0xd7cb, 0xd7fb}, {0xf900, 0xfa6d}, {0xfa70, 0xfad9}, + {0xfb00, 0xfb06}, {0xfb13, 0xfb17}, {0xfb1d, 0xfb36}, {0xfb38, 0xfb3c}, + {0xfb46, 0xfbc1}, {0xfbd3, 0xfd3f}, {0xfd50, 0xfd8f}, {0xfd92, 0xfdc7}, + {0xfdf0, 0xfdfd}, {0xfe00, 0xfe19}, {0xfe20, 0xfe52}, {0xfe54, 0xfe66}, + {0xfe68, 0xfe6b}, {0xfe70, 0xfe74}, {0xfe76, 0xfefc}, {0xff01, 0xffbe}, + {0xffc2, 0xffc7}, {0xffca, 0xffcf}, {0xffd2, 0xffd7}, {0xffda, 0xffdc}, + {0xffe0, 0xffe6}, {0xffe8, 0xffee} #if CHRBITS > 16 ,{0x10000, 0x1000b}, {0x1000d, 0x10026}, {0x10028, 0x1003a}, {0x1003f, 0x1004d}, {0x10050, 0x1005d}, {0x10080, 0x100fa}, {0x10100, 0x10102}, {0x10107, 0x10133}, @@ -697,81 +706,85 @@ static const crange graphRangeTable[] = { {0x10760, 0x10767}, {0x10800, 0x10805}, {0x1080a, 0x10835}, {0x1083f, 0x10855}, {0x10857, 0x1089e}, {0x108a7, 0x108af}, {0x108e0, 0x108f2}, {0x108fb, 0x1091b}, {0x1091f, 0x10939}, {0x10980, 0x109b7}, {0x109bc, 0x109cf}, {0x109d2, 0x10a03}, - {0x10a0c, 0x10a13}, {0x10a15, 0x10a17}, {0x10a19, 0x10a33}, {0x10a38, 0x10a3a}, - {0x10a3f, 0x10a47}, {0x10a50, 0x10a58}, {0x10a60, 0x10a9f}, {0x10ac0, 0x10ae6}, + {0x10a0c, 0x10a13}, {0x10a15, 0x10a17}, {0x10a19, 0x10a35}, {0x10a38, 0x10a3a}, + {0x10a3f, 0x10a48}, {0x10a50, 0x10a58}, {0x10a60, 0x10a9f}, {0x10ac0, 0x10ae6}, {0x10aeb, 0x10af6}, {0x10b00, 0x10b35}, {0x10b39, 0x10b55}, {0x10b58, 0x10b72}, {0x10b78, 0x10b91}, {0x10b99, 0x10b9c}, {0x10ba9, 0x10baf}, {0x10c00, 0x10c48}, - {0x10c80, 0x10cb2}, {0x10cc0, 0x10cf2}, {0x10cfa, 0x10cff}, {0x10e60, 0x10e7e}, - {0x11000, 0x1104d}, {0x11052, 0x1106f}, {0x1107f, 0x110bc}, {0x110be, 0x110c1}, - {0x110d0, 0x110e8}, {0x110f0, 0x110f9}, {0x11100, 0x11134}, {0x11136, 0x11143}, - {0x11150, 0x11176}, {0x11180, 0x111cd}, {0x111d0, 0x111df}, {0x111e1, 0x111f4}, - {0x11200, 0x11211}, {0x11213, 0x1123e}, {0x11280, 0x11286}, {0x1128a, 0x1128d}, - {0x1128f, 0x1129d}, {0x1129f, 0x112a9}, {0x112b0, 0x112ea}, {0x112f0, 0x112f9}, - {0x11300, 0x11303}, {0x11305, 0x1130c}, {0x11313, 0x11328}, {0x1132a, 0x11330}, - {0x11335, 0x11339}, {0x1133c, 0x11344}, {0x1134b, 0x1134d}, {0x1135d, 0x11363}, - {0x11366, 0x1136c}, {0x11370, 0x11374}, {0x11400, 0x11459}, {0x11480, 0x114c7}, - {0x114d0, 0x114d9}, {0x11580, 0x115b5}, {0x115b8, 0x115dd}, {0x11600, 0x11644}, - {0x11650, 0x11659}, {0x11660, 0x1166c}, {0x11680, 0x116b7}, {0x116c0, 0x116c9}, - {0x11700, 0x11719}, {0x1171d, 0x1172b}, {0x11730, 0x1173f}, {0x118a0, 0x118f2}, - {0x11a00, 0x11a47}, {0x11a50, 0x11a83}, {0x11a86, 0x11a9c}, {0x11a9e, 0x11aa2}, - {0x11ac0, 0x11af8}, {0x11c00, 0x11c08}, {0x11c0a, 0x11c36}, {0x11c38, 0x11c45}, - {0x11c50, 0x11c6c}, {0x11c70, 0x11c8f}, {0x11c92, 0x11ca7}, {0x11ca9, 0x11cb6}, - {0x11d00, 0x11d06}, {0x11d0b, 0x11d36}, {0x11d3f, 0x11d47}, {0x11d50, 0x11d59}, + {0x10c80, 0x10cb2}, {0x10cc0, 0x10cf2}, {0x10cfa, 0x10d27}, {0x10d30, 0x10d39}, + {0x10e60, 0x10e7e}, {0x10f00, 0x10f27}, {0x10f30, 0x10f59}, {0x11000, 0x1104d}, + {0x11052, 0x1106f}, {0x1107f, 0x110bc}, {0x110be, 0x110c1}, {0x110d0, 0x110e8}, + {0x110f0, 0x110f9}, {0x11100, 0x11134}, {0x11136, 0x11146}, {0x11150, 0x11176}, + {0x11180, 0x111cd}, {0x111d0, 0x111df}, {0x111e1, 0x111f4}, {0x11200, 0x11211}, + {0x11213, 0x1123e}, {0x11280, 0x11286}, {0x1128a, 0x1128d}, {0x1128f, 0x1129d}, + {0x1129f, 0x112a9}, {0x112b0, 0x112ea}, {0x112f0, 0x112f9}, {0x11300, 0x11303}, + {0x11305, 0x1130c}, {0x11313, 0x11328}, {0x1132a, 0x11330}, {0x11335, 0x11339}, + {0x1133b, 0x11344}, {0x1134b, 0x1134d}, {0x1135d, 0x11363}, {0x11366, 0x1136c}, + {0x11370, 0x11374}, {0x11400, 0x11459}, {0x11480, 0x114c7}, {0x114d0, 0x114d9}, + {0x11580, 0x115b5}, {0x115b8, 0x115dd}, {0x11600, 0x11644}, {0x11650, 0x11659}, + {0x11660, 0x1166c}, {0x11680, 0x116b7}, {0x116c0, 0x116c9}, {0x11700, 0x1171a}, + {0x1171d, 0x1172b}, {0x11730, 0x1173f}, {0x11800, 0x1183b}, {0x118a0, 0x118f2}, + {0x11a00, 0x11a47}, {0x11a50, 0x11a83}, {0x11a86, 0x11aa2}, {0x11ac0, 0x11af8}, + {0x11c00, 0x11c08}, {0x11c0a, 0x11c36}, {0x11c38, 0x11c45}, {0x11c50, 0x11c6c}, + {0x11c70, 0x11c8f}, {0x11c92, 0x11ca7}, {0x11ca9, 0x11cb6}, {0x11d00, 0x11d06}, + {0x11d0b, 0x11d36}, {0x11d3f, 0x11d47}, {0x11d50, 0x11d59}, {0x11d60, 0x11d65}, + {0x11d6a, 0x11d8e}, {0x11d93, 0x11d98}, {0x11da0, 0x11da9}, {0x11ee0, 0x11ef8}, {0x12000, 0x12399}, {0x12400, 0x1246e}, {0x12470, 0x12474}, {0x12480, 0x12543}, {0x13000, 0x1342e}, {0x14400, 0x14646}, {0x16800, 0x16a38}, {0x16a40, 0x16a5e}, {0x16a60, 0x16a69}, {0x16ad0, 0x16aed}, {0x16af0, 0x16af5}, {0x16b00, 0x16b45}, {0x16b50, 0x16b59}, {0x16b5b, 0x16b61}, {0x16b63, 0x16b77}, {0x16b7d, 0x16b8f}, - {0x16f00, 0x16f44}, {0x16f50, 0x16f7e}, {0x16f8f, 0x16f9f}, {0x17000, 0x187ec}, - {0x18800, 0x18af2}, {0x1b000, 0x1b11e}, {0x1b170, 0x1b2fb}, {0x1bc00, 0x1bc6a}, - {0x1bc70, 0x1bc7c}, {0x1bc80, 0x1bc88}, {0x1bc90, 0x1bc99}, {0x1bc9c, 0x1bc9f}, - {0x1d000, 0x1d0f5}, {0x1d100, 0x1d126}, {0x1d129, 0x1d172}, {0x1d17b, 0x1d1e8}, - {0x1d200, 0x1d245}, {0x1d300, 0x1d356}, {0x1d360, 0x1d371}, {0x1d400, 0x1d454}, - {0x1d456, 0x1d49c}, {0x1d4a9, 0x1d4ac}, {0x1d4ae, 0x1d4b9}, {0x1d4bd, 0x1d4c3}, - {0x1d4c5, 0x1d505}, {0x1d507, 0x1d50a}, {0x1d50d, 0x1d514}, {0x1d516, 0x1d51c}, - {0x1d51e, 0x1d539}, {0x1d53b, 0x1d53e}, {0x1d540, 0x1d544}, {0x1d54a, 0x1d550}, - {0x1d552, 0x1d6a5}, {0x1d6a8, 0x1d7cb}, {0x1d7ce, 0x1da8b}, {0x1da9b, 0x1da9f}, - {0x1daa1, 0x1daaf}, {0x1e000, 0x1e006}, {0x1e008, 0x1e018}, {0x1e01b, 0x1e021}, - {0x1e026, 0x1e02a}, {0x1e800, 0x1e8c4}, {0x1e8c7, 0x1e8d6}, {0x1e900, 0x1e94a}, - {0x1e950, 0x1e959}, {0x1ee00, 0x1ee03}, {0x1ee05, 0x1ee1f}, {0x1ee29, 0x1ee32}, - {0x1ee34, 0x1ee37}, {0x1ee4d, 0x1ee4f}, {0x1ee67, 0x1ee6a}, {0x1ee6c, 0x1ee72}, - {0x1ee74, 0x1ee77}, {0x1ee79, 0x1ee7c}, {0x1ee80, 0x1ee89}, {0x1ee8b, 0x1ee9b}, - {0x1eea1, 0x1eea3}, {0x1eea5, 0x1eea9}, {0x1eeab, 0x1eebb}, {0x1f000, 0x1f02b}, - {0x1f030, 0x1f093}, {0x1f0a0, 0x1f0ae}, {0x1f0b1, 0x1f0bf}, {0x1f0c1, 0x1f0cf}, - {0x1f0d1, 0x1f0f5}, {0x1f100, 0x1f10c}, {0x1f110, 0x1f12e}, {0x1f130, 0x1f16b}, - {0x1f170, 0x1f1ac}, {0x1f1e6, 0x1f202}, {0x1f210, 0x1f23b}, {0x1f240, 0x1f248}, - {0x1f260, 0x1f265}, {0x1f300, 0x1f6d4}, {0x1f6e0, 0x1f6ec}, {0x1f6f0, 0x1f6f9}, - {0x1f700, 0x1f773}, {0x1f780, 0x1f7d4}, {0x1f800, 0x1f80b}, {0x1f810, 0x1f847}, - {0x1f850, 0x1f859}, {0x1f860, 0x1f887}, {0x1f890, 0x1f8ad}, {0x1f900, 0x1f90b}, - {0x1f910, 0x1f93e}, {0x1f940, 0x1f970}, {0x1f973, 0x1f976}, {0x1f97c, 0x1f9a2}, - {0x1f9b0, 0x1f9b9}, {0x1f9c0, 0x1f9c2}, {0x1f9d0, 0x1f9ff}, {0x1fa60, 0x1fa6d}, - {0x20000, 0x2a6d6}, {0x2a700, 0x2b734}, {0x2b740, 0x2b81d}, {0x2b820, 0x2cea1}, - {0x2ceb0, 0x2ebe0}, {0x2f800, 0x2fa1d}, {0xe0100, 0xe01ef} + {0x16e40, 0x16e9a}, {0x16f00, 0x16f44}, {0x16f50, 0x16f7e}, {0x16f8f, 0x16f9f}, + {0x17000, 0x187f1}, {0x18800, 0x18af2}, {0x1b000, 0x1b11e}, {0x1b170, 0x1b2fb}, + {0x1bc00, 0x1bc6a}, {0x1bc70, 0x1bc7c}, {0x1bc80, 0x1bc88}, {0x1bc90, 0x1bc99}, + {0x1bc9c, 0x1bc9f}, {0x1d000, 0x1d0f5}, {0x1d100, 0x1d126}, {0x1d129, 0x1d172}, + {0x1d17b, 0x1d1e8}, {0x1d200, 0x1d245}, {0x1d2e0, 0x1d2f3}, {0x1d300, 0x1d356}, + {0x1d360, 0x1d378}, {0x1d400, 0x1d454}, {0x1d456, 0x1d49c}, {0x1d4a9, 0x1d4ac}, + {0x1d4ae, 0x1d4b9}, {0x1d4bd, 0x1d4c3}, {0x1d4c5, 0x1d505}, {0x1d507, 0x1d50a}, + {0x1d50d, 0x1d514}, {0x1d516, 0x1d51c}, {0x1d51e, 0x1d539}, {0x1d53b, 0x1d53e}, + {0x1d540, 0x1d544}, {0x1d54a, 0x1d550}, {0x1d552, 0x1d6a5}, {0x1d6a8, 0x1d7cb}, + {0x1d7ce, 0x1da8b}, {0x1da9b, 0x1da9f}, {0x1daa1, 0x1daaf}, {0x1e000, 0x1e006}, + {0x1e008, 0x1e018}, {0x1e01b, 0x1e021}, {0x1e026, 0x1e02a}, {0x1e800, 0x1e8c4}, + {0x1e8c7, 0x1e8d6}, {0x1e900, 0x1e94a}, {0x1e950, 0x1e959}, {0x1ec71, 0x1ecb4}, + {0x1ee00, 0x1ee03}, {0x1ee05, 0x1ee1f}, {0x1ee29, 0x1ee32}, {0x1ee34, 0x1ee37}, + {0x1ee4d, 0x1ee4f}, {0x1ee67, 0x1ee6a}, {0x1ee6c, 0x1ee72}, {0x1ee74, 0x1ee77}, + {0x1ee79, 0x1ee7c}, {0x1ee80, 0x1ee89}, {0x1ee8b, 0x1ee9b}, {0x1eea1, 0x1eea3}, + {0x1eea5, 0x1eea9}, {0x1eeab, 0x1eebb}, {0x1f000, 0x1f02b}, {0x1f030, 0x1f093}, + {0x1f0a0, 0x1f0ae}, {0x1f0b1, 0x1f0bf}, {0x1f0c1, 0x1f0cf}, {0x1f0d1, 0x1f0f5}, + {0x1f100, 0x1f10c}, {0x1f110, 0x1f16b}, {0x1f170, 0x1f1ac}, {0x1f1e6, 0x1f202}, + {0x1f210, 0x1f23b}, {0x1f240, 0x1f248}, {0x1f260, 0x1f265}, {0x1f300, 0x1f6d4}, + {0x1f6e0, 0x1f6ec}, {0x1f6f0, 0x1f6f9}, {0x1f700, 0x1f773}, {0x1f780, 0x1f7d8}, + {0x1f800, 0x1f80b}, {0x1f810, 0x1f847}, {0x1f850, 0x1f859}, {0x1f860, 0x1f887}, + {0x1f890, 0x1f8ad}, {0x1f900, 0x1f90b}, {0x1f910, 0x1f93e}, {0x1f940, 0x1f970}, + {0x1f973, 0x1f976}, {0x1f97c, 0x1f9a2}, {0x1f9b0, 0x1f9b9}, {0x1f9c0, 0x1f9c2}, + {0x1f9d0, 0x1f9ff}, {0x1fa60, 0x1fa6d}, {0x20000, 0x2a6d6}, {0x2a700, 0x2b734}, + {0x2b740, 0x2b81d}, {0x2b820, 0x2cea1}, {0x2ceb0, 0x2ebe0}, {0x2f800, 0x2fa1d}, + {0xe0100, 0xe01ef} #endif }; #define NUM_GRAPH_RANGE (sizeof(graphRangeTable)/sizeof(crange)) static const chr graphCharTable[] = { - 0x38c, 0x589, 0x58a, 0x85e, 0x98f, 0x990, 0x9b2, 0x9c7, 0x9c8, - 0x9d7, 0x9dc, 0x9dd, 0xa0f, 0xa10, 0xa32, 0xa33, 0xa35, 0xa36, - 0xa38, 0xa39, 0xa3c, 0xa47, 0xa48, 0xa51, 0xa5e, 0xab2, 0xab3, - 0xad0, 0xb0f, 0xb10, 0xb32, 0xb33, 0xb47, 0xb48, 0xb56, 0xb57, - 0xb5c, 0xb5d, 0xb82, 0xb83, 0xb99, 0xb9a, 0xb9c, 0xb9e, 0xb9f, - 0xba3, 0xba4, 0xbd0, 0xbd7, 0xc55, 0xc56, 0xcd5, 0xcd6, 0xcde, - 0xcf1, 0xcf2, 0xd82, 0xd83, 0xdbd, 0xdca, 0xdd6, 0xe81, 0xe82, - 0xe84, 0xe87, 0xe88, 0xe8a, 0xe8d, 0xea5, 0xea7, 0xeaa, 0xeab, - 0xec6, 0x10c7, 0x10cd, 0x1258, 0x12c0, 0x1772, 0x1773, 0x1940, 0x1f59, - 0x1f5b, 0x1f5d, 0x2070, 0x2071, 0x2d27, 0x2d2d, 0x2d6f, 0x2d70, 0xfb3e, - 0xfb40, 0xfb41, 0xfb43, 0xfb44, 0xfffc, 0xfffd + 0x38c, 0x85e, 0x98f, 0x990, 0x9b2, 0x9c7, 0x9c8, 0x9d7, 0x9dc, + 0x9dd, 0xa0f, 0xa10, 0xa32, 0xa33, 0xa35, 0xa36, 0xa38, 0xa39, + 0xa3c, 0xa47, 0xa48, 0xa51, 0xa5e, 0xab2, 0xab3, 0xad0, 0xb0f, + 0xb10, 0xb32, 0xb33, 0xb47, 0xb48, 0xb56, 0xb57, 0xb5c, 0xb5d, + 0xb82, 0xb83, 0xb99, 0xb9a, 0xb9c, 0xb9e, 0xb9f, 0xba3, 0xba4, + 0xbd0, 0xbd7, 0xc55, 0xc56, 0xcd5, 0xcd6, 0xcde, 0xcf1, 0xcf2, + 0xd82, 0xd83, 0xdbd, 0xdca, 0xdd6, 0xe81, 0xe82, 0xe84, 0xe87, + 0xe88, 0xe8a, 0xe8d, 0xea5, 0xea7, 0xeaa, 0xeab, 0xec6, 0x10c7, + 0x10cd, 0x1258, 0x12c0, 0x1772, 0x1773, 0x1940, 0x1f59, 0x1f5b, 0x1f5d, + 0x2070, 0x2071, 0x2d27, 0x2d2d, 0x2d6f, 0x2d70, 0xfb3e, 0xfb40, 0xfb41, + 0xfb43, 0xfb44, 0xfffc, 0xfffd #if CHRBITS > 16 ,0x1003c, 0x1003d, 0x101a0, 0x1056f, 0x10808, 0x10837, 0x10838, 0x1083c, 0x108f4, 0x108f5, 0x1093f, 0x10a05, 0x10a06, 0x11288, 0x1130f, 0x11310, 0x11332, 0x11333, - 0x11347, 0x11348, 0x11350, 0x11357, 0x1145b, 0x1145d, 0x118ff, 0x11d08, 0x11d09, - 0x11d3a, 0x11d3c, 0x11d3d, 0x16a6e, 0x16a6f, 0x16fe0, 0x16fe1, 0x1d49e, 0x1d49f, - 0x1d4a2, 0x1d4a5, 0x1d4a6, 0x1d4bb, 0x1d546, 0x1e023, 0x1e024, 0x1e95e, 0x1e95f, - 0x1ee21, 0x1ee22, 0x1ee24, 0x1ee27, 0x1ee39, 0x1ee3b, 0x1ee42, 0x1ee47, 0x1ee49, - 0x1ee4b, 0x1ee51, 0x1ee52, 0x1ee54, 0x1ee57, 0x1ee59, 0x1ee5b, 0x1ee5d, 0x1ee5f, - 0x1ee61, 0x1ee62, 0x1ee64, 0x1ee7e, 0x1eef0, 0x1eef1, 0x1f250, 0x1f251, 0x1f97a + 0x11347, 0x11348, 0x11350, 0x11357, 0x1145b, 0x1145d, 0x1145e, 0x118ff, 0x11d08, + 0x11d09, 0x11d3a, 0x11d3c, 0x11d3d, 0x11d67, 0x11d68, 0x11d90, 0x11d91, 0x16a6e, + 0x16a6f, 0x16fe0, 0x16fe1, 0x1d49e, 0x1d49f, 0x1d4a2, 0x1d4a5, 0x1d4a6, 0x1d4bb, + 0x1d546, 0x1e023, 0x1e024, 0x1e95e, 0x1e95f, 0x1ee21, 0x1ee22, 0x1ee24, 0x1ee27, + 0x1ee39, 0x1ee3b, 0x1ee42, 0x1ee47, 0x1ee49, 0x1ee4b, 0x1ee51, 0x1ee52, 0x1ee54, + 0x1ee57, 0x1ee59, 0x1ee5b, 0x1ee5d, 0x1ee5f, 0x1ee61, 0x1ee62, 0x1ee64, 0x1ee7e, + 0x1eef0, 0x1eef1, 0x1f250, 0x1f251, 0x1f97a #endif }; diff --git a/generic/tclUniData.c b/generic/tclUniData.c index 834fcc4..faca93d 100644 --- a/generic/tclUniData.c +++ b/generic/tclUniData.c @@ -42,22 +42,22 @@ static const unsigned short pageMap[] = { 4384, 4416, 1344, 4448, 4480, 4512, 4544, 1344, 4576, 4608, 4640, 4672, 1344, 4704, 4736, 4768, 4800, 4832, 1344, 4864, 4896, 4928, 4960, 1344, 4992, 5024, 5056, 5088, 1824, 1824, 5120, 5152, 5184, 5216, 5248, 5280, - 1344, 5312, 1344, 5344, 5376, 5408, 5440, 1824, 5472, 5504, 5536, 5568, - 5600, 5632, 5664, 5600, 704, 5696, 224, 224, 224, 224, 5728, 224, 224, - 224, 5760, 5792, 5824, 5856, 5888, 5920, 5952, 5984, 6016, 6048, 6080, - 6112, 6144, 6176, 6208, 6240, 6272, 6304, 6336, 6368, 6400, 6432, 6464, - 6496, 6528, 6528, 6528, 6528, 6528, 6528, 6528, 6528, 6560, 6592, 4928, - 6624, 6656, 6688, 6720, 6752, 4928, 6784, 6816, 6848, 6880, 6912, 6944, - 6976, 4928, 4928, 4928, 4928, 4928, 7008, 7040, 7072, 4928, 4928, 4928, - 7104, 4928, 4928, 4928, 4928, 4928, 4928, 4928, 7136, 7168, 4928, 7200, - 7232, 4928, 4928, 4928, 4928, 4928, 4928, 4928, 4928, 6528, 6528, 6528, - 6528, 7264, 6528, 7296, 7328, 6528, 6528, 6528, 6528, 6528, 6528, 6528, - 6528, 4928, 7360, 7392, 7424, 7456, 7488, 7520, 7552, 7584, 7616, 7648, + 1344, 5312, 1344, 5344, 5376, 5408, 5440, 5472, 5504, 5536, 5568, 5600, + 5632, 5664, 5696, 5632, 704, 5728, 224, 224, 224, 224, 5760, 224, 224, + 224, 5792, 5824, 5856, 5888, 5920, 5952, 5984, 6016, 6048, 6080, 6112, + 6144, 6176, 6208, 6240, 6272, 6304, 6336, 6368, 6400, 6432, 6464, 6496, + 6528, 6560, 6560, 6560, 6560, 6560, 6560, 6560, 6560, 6592, 6624, 4928, + 6656, 6688, 6720, 6752, 6784, 4928, 6816, 6848, 6880, 6912, 6944, 6976, + 7008, 4928, 4928, 4928, 4928, 4928, 7040, 7072, 7104, 4928, 4928, 4928, + 7136, 4928, 4928, 4928, 4928, 4928, 4928, 4928, 7168, 7200, 4928, 7232, + 7264, 4928, 4928, 4928, 4928, 4928, 4928, 4928, 4928, 6560, 6560, 6560, + 6560, 7296, 6560, 7328, 7360, 6560, 6560, 6560, 6560, 6560, 6560, 6560, + 6560, 4928, 7392, 7424, 7456, 7488, 4928, 7520, 7552, 7584, 7616, 7648, 7680, 224, 224, 224, 7712, 7744, 7776, 1344, 7808, 7840, 7872, 7872, 704, 7904, 7936, 7968, 1824, 8000, 4928, 4928, 8032, 4928, 4928, 4928, 4928, 4928, 4928, 8064, 8096, 8128, 8160, 3232, 1344, 8192, 4192, 1344, - 8224, 8256, 8288, 1344, 1344, 8320, 8352, 4928, 8384, 8416, 8448, 8480, - 4928, 8448, 8512, 4928, 8416, 4928, 4928, 4928, 4928, 4928, 4928, 4928, + 8224, 8256, 8288, 1344, 1344, 8320, 8352, 4928, 8384, 7552, 8416, 8448, + 4928, 8416, 8480, 4928, 7552, 4928, 4928, 4928, 4928, 4928, 4928, 4928, 4928, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, @@ -130,7 +130,7 @@ static const unsigned short pageMap[] = { 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, - 1792, 8544, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 8512, 8544, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 8576, 4928, 8608, 5408, 1344, 1344, 1344, 1344, 1344, 1344, 1344, @@ -203,37 +203,37 @@ static const unsigned short pageMap[] = { 1344, 11520, 1824, 1824, 1824, 1824, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 7840, 4704, 10272, 1824, 1824, 1824, 1824, 11552, 11584, 11616, 11648, 4736, 11680, 1824, 11712, 11744, 11776, - 1824, 1824, 1344, 11808, 11840, 6848, 11872, 11904, 11936, 11968, 12000, + 1824, 1824, 1344, 11808, 11840, 6880, 11872, 11904, 11936, 11968, 12000, 1824, 12032, 12064, 1344, 12096, 12128, 12160, 12192, 12224, 1824, - 1824, 1344, 1344, 12256, 1824, 12288, 12320, 12352, 12384, 1824, 1824, - 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 12416, 1824, - 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 12448, - 12480, 12512, 12544, 5248, 12576, 12608, 12640, 12672, 12704, 12736, - 12768, 5248, 12800, 12832, 12864, 12896, 12928, 1824, 1824, 12960, - 12992, 13024, 13056, 13088, 2368, 13120, 13152, 1824, 1824, 1824, 1824, - 1344, 13184, 13216, 1824, 1344, 13248, 13280, 1824, 1824, 1824, 1824, - 1824, 1344, 13312, 13344, 1824, 1344, 13376, 13408, 13440, 1344, 13472, - 13504, 1824, 13536, 13568, 1824, 1824, 1824, 1824, 1824, 1824, 1824, - 1824, 1824, 1824, 1824, 13600, 13632, 13664, 1824, 1824, 1824, 1824, - 1824, 1824, 1824, 1824, 13696, 13728, 13760, 1344, 13792, 13824, 1344, - 13856, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 13888, 13920, - 13952, 13984, 14016, 14048, 1824, 1824, 14080, 14112, 14144, 1824, - 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, - 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1344, 1344, 1344, 1344, + 1824, 1344, 1344, 12256, 1824, 12288, 12320, 12352, 12384, 1344, 12416, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 12448, 1824, + 1824, 1824, 1824, 12000, 12480, 12512, 1824, 1824, 1824, 1824, 1824, + 12544, 12576, 12608, 12640, 5248, 12672, 12704, 12736, 12768, 12800, + 12832, 12864, 5248, 12896, 12928, 12960, 12992, 13024, 1824, 1824, + 13056, 13088, 13120, 13152, 13184, 13216, 13248, 13280, 1824, 1824, + 1824, 1824, 1344, 13312, 13344, 1824, 1344, 13376, 13408, 1824, 1824, + 1824, 1824, 1824, 1344, 13440, 13472, 1824, 1344, 13504, 13536, 13568, + 1344, 13600, 13632, 1824, 4032, 13664, 1824, 1824, 1824, 1824, 1824, + 1824, 1344, 13696, 1824, 1824, 1824, 13728, 13760, 13792, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 13824, 13856, 13888, 1344, 13920, + 13952, 1344, 4608, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 13984, 14016, 14048, 14080, 14112, 14144, 1824, 1824, 14176, 14208, + 14240, 14272, 14304, 13632, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 14336, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, - 9984, 1824, 1824, 1824, 10848, 10848, 10848, 14176, 1344, 1344, 1344, - 1344, 1344, 1344, 14208, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1344, 1344, 1344, 1344, 9984, 1824, 1824, 1824, 10848, 10848, 10848, + 14368, 1344, 1344, 1344, 1344, 1344, 1344, 14400, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, - 1824, 1824, 1824, 1824, 1824, 1824, 1344, 1344, 1344, 1344, 1344, 1344, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, - 1344, 1344, 1344, 14240, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1344, 1344, 1344, 1344, 1344, 1344, 1344, 14432, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, @@ -243,10 +243,9 @@ static const unsigned short pageMap[] = { 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, - 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1344, - 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, - 1344, 1344, 1344, 1344, 1344, 14272, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 14464, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, @@ -268,12 +267,13 @@ static const unsigned short pageMap[] = { 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, - 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, - 1344, 1344, 1344, 1344, 1344, 13856, 4736, 14304, 1824, 1824, 10208, - 14336, 1344, 14368, 14400, 14432, 14464, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, - 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1344, 1344, - 14496, 14528, 14560, 1824, 1824, 14592, 1344, 1344, 1344, 1344, 1344, + 1824, 1824, 1824, 1824, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 4608, 4736, 14496, + 1824, 1824, 10208, 14528, 1344, 14560, 14592, 14624, 8512, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 13728, 13760, 14656, 1824, + 1824, 1824, 1344, 1344, 14688, 14720, 14752, 1824, 1824, 14784, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, @@ -289,9 +289,9 @@ static const unsigned short pageMap[] = { 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, - 1344, 1344, 1344, 1344, 1344, 1344, 14624, 1344, 1344, 1344, 1344, + 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 14816, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, - 1344, 1344, 1344, 1344, 1344, 1344, 1344, 14656, 1824, 1824, 1824, + 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 14848, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, @@ -316,17 +316,16 @@ static const unsigned short pageMap[] = { 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, - 1824, 1824, 1824, 1824, 1824, 1344, 1344, 1344, 1344, 1344, 1344, 1344, - 1344, 4736, 1824, 1824, 10208, 1344, 1344, 1344, 1344, 1344, 1344, - 1344, 1344, 1344, 1344, 1344, 9856, 1824, 1824, 1824, 1824, 1824, 1824, - 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1344, 1344, 1344, 1344, + 1344, 1344, 1344, 1344, 4736, 1824, 1824, 10208, 1344, 1344, 1344, + 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 9856, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, - 1824, 1824, 1824, 1824, 1824, 1824, 1344, 1344, 1344, 14688, 14720, - 14752, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1344, 1344, 1344, + 14880, 14912, 14944, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, @@ -338,40 +337,42 @@ static const unsigned short pageMap[] = { 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, - 4928, 4928, 4928, 4928, 4928, 4928, 4928, 8064, 4928, 14784, 4928, - 14816, 14848, 14880, 4928, 14912, 4928, 4928, 14944, 1824, 1824, 1824, - 1824, 1824, 4928, 4928, 14976, 15008, 1824, 1824, 1824, 1824, 15040, - 15072, 15104, 15136, 15168, 15200, 15232, 15264, 15296, 15328, 15360, - 15392, 15424, 15040, 15072, 15456, 15136, 15488, 15520, 15552, 15264, - 15584, 15616, 15648, 15680, 15712, 15744, 15776, 15808, 15840, 15872, - 15904, 4928, 4928, 4928, 4928, 4928, 4928, 4928, 4928, 4928, 4928, - 4928, 4928, 4928, 4928, 4928, 4928, 704, 15936, 704, 15968, 16000, - 16032, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 4928, 4928, 4928, 4928, 4928, 4928, 4928, 8064, 4928, 14976, + 4928, 15008, 15040, 15072, 4928, 15104, 4928, 4928, 15136, 1824, 1824, + 1824, 1824, 15168, 4928, 4928, 15200, 15232, 1824, 1824, 1824, 1824, + 15264, 15296, 15328, 15360, 15392, 15424, 15456, 15488, 15520, 15552, + 15584, 15616, 15648, 15264, 15296, 15680, 15360, 15712, 15744, 15776, + 15488, 15808, 15840, 15872, 15904, 15936, 15968, 16000, 16032, 16064, + 16096, 16128, 4928, 4928, 4928, 4928, 4928, 4928, 4928, 4928, 4928, + 4928, 4928, 4928, 4928, 4928, 4928, 4928, 704, 16160, 704, 16192, 16224, + 16256, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, - 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 16064, 16096, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 16288, 16320, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, - 1824, 1344, 1344, 1344, 1344, 1344, 1344, 16128, 1824, 16160, 16192, - 16224, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1344, 1344, 1344, 1344, 1344, 1344, 16352, 1824, 16384, 16416, + 16448, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, - 1824, 1824, 1824, 16256, 16288, 16320, 16352, 16384, 16416, 1824, 16448, - 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 4928, 16480, 4928, - 4928, 8032, 16512, 16544, 8064, 16576, 16608, 4928, 16480, 4928, 16640, - 1824, 16672, 16704, 16736, 16768, 16800, 1824, 1824, 1824, 1824, 4928, - 4928, 4928, 4928, 4928, 4928, 4928, 16832, 4928, 4928, 4928, 4928, + 1824, 1824, 16480, 6880, 16512, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1824, 1824, 1824, 16544, 16576, 16608, 16640, 16672, 16704, 1824, + 16736, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 4928, 16768, + 4928, 4928, 8032, 16800, 16832, 8064, 16864, 4928, 4928, 16768, 4928, + 16896, 1824, 16928, 16960, 16992, 17024, 17056, 1824, 1824, 1824, 1824, + 4928, 4928, 4928, 4928, 4928, 4928, 4928, 17088, 4928, 4928, 4928, 4928, 4928, 4928, 4928, 4928, 4928, 4928, 4928, 4928, 4928, 4928, 4928, - 4928, 4928, 4928, 4928, 4928, 4928, 16864, 16896, 4928, 4928, 4928, - 8032, 4928, 4928, 16864, 1824, 16480, 4928, 16928, 4928, 16960, 16992, - 1824, 1824, 16480, 8416, 4928, 17024, 4928, 17056, 16704, 4928, 1824, - 1824, 1824, 16992, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 4928, 4928, 4928, 4928, 4928, 4928, 4928, 17120, 17152, 4928, 4928, + 4928, 8032, 4928, 4928, 17184, 1824, 16768, 4928, 17216, 4928, 17248, + 17280, 1824, 1824, 16768, 7552, 4928, 17312, 4928, 17344, 16960, 4928, + 1824, 1824, 1824, 17280, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, + 1824, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, @@ -482,8 +483,7 @@ static const unsigned short pageMap[] = { 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, - 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, - 1344, 1344, 7840, 1824, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 1344, 1344, 1344, 7840, 1824, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, @@ -494,7 +494,7 @@ static const unsigned short pageMap[] = { 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, - 1344, 17088, 1344, 1344, 1344, 1344, 1344, 1344, 11360, 1344, 1344, + 1344, 1344, 17376, 1344, 1344, 1344, 1344, 1344, 1344, 11360, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, @@ -509,7 +509,7 @@ static const unsigned short pageMap[] = { 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, - 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 17120, + 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 17408, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, @@ -529,7 +529,7 @@ static const unsigned short pageMap[] = { 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, - 1344, 1344, 1344, 1344, 1344, 17152, 1824, 1824, 1824, 1824, 1824, + 1344, 1344, 1344, 1344, 1344, 17440, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, @@ -539,7 +539,6 @@ static const unsigned short pageMap[] = { 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1824, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 11360 - #endif /* TCL_UTF_MAX > 3 */ }; @@ -617,100 +616,100 @@ static const unsigned char groupMap[] = { 23, 24, 23, 24, 0, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, - 0, 0, 91, 3, 3, 3, 3, 3, 3, 0, 123, 123, 123, 123, 123, 123, 123, 123, + 0, 0, 91, 3, 3, 3, 3, 3, 3, 21, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, - 123, 123, 21, 0, 3, 8, 0, 0, 14, 14, 4, 0, 92, 92, 92, 92, 92, 92, + 123, 123, 123, 21, 21, 3, 8, 0, 0, 14, 14, 4, 0, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, - 92, 92, 92, 92, 92, 8, 92, 3, 92, 92, 3, 92, 92, 3, 92, 0, 0, 0, 0, - 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, - 15, 15, 15, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 17, - 17, 17, 7, 7, 7, 3, 3, 4, 3, 3, 14, 14, 92, 92, 92, 92, 92, 92, 92, - 92, 92, 92, 92, 3, 17, 0, 3, 3, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 91, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, - 92, 92, 92, 92, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 3, 3, 3, 3, 15, 15, 92, + 92, 92, 92, 92, 92, 92, 8, 92, 3, 92, 92, 3, 92, 92, 3, 92, 0, 0, 0, + 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, + 15, 15, 15, 15, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, + 17, 17, 17, 7, 7, 7, 3, 3, 4, 3, 3, 14, 14, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 3, 17, 0, 3, 3, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 91, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 3, 3, 3, 3, 15, 15, + 92, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 3, 15, 92, 92, 92, 92, 92, 92, 92, 17, 14, 92, 92, 92, 92, 92, - 92, 91, 91, 92, 92, 14, 92, 92, 92, 92, 15, 15, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 15, 15, 15, 14, 14, 15, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 0, 17, 15, 92, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 3, 15, 92, 92, 92, 92, 92, 92, 92, 17, 14, 92, 92, 92, 92, + 92, 92, 91, 91, 92, 92, 14, 92, 92, 92, 92, 15, 15, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 15, 15, 15, 14, 14, 15, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 0, 17, 15, 92, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, - 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 0, 0, 15, 15, 15, 15, 15, + 15, 15, 15, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 15, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 15, + 15, 15, 15, 15, 15, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 15, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 92, 92, - 92, 92, 92, 92, 92, 92, 92, 91, 91, 14, 3, 3, 3, 91, 0, 0, 0, 0, 0, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 91, 91, 14, 3, 3, 3, 91, 0, 0, + 92, 4, 4, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 92, 92, 92, 92, 91, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 91, 92, 92, 92, 91, 92, 92, 92, 92, 92, 0, 0, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 92, 92, 92, 92, 91, 92, 92, 92, 92, 92, 92, 92, - 92, 92, 91, 92, 92, 92, 91, 92, 92, 92, 92, 92, 0, 0, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 92, - 92, 92, 0, 0, 3, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, + 15, 92, 92, 92, 0, 0, 3, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 92, - 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 17, 92, 92, 92, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, + 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 17, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, - 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 124, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 92, - 124, 92, 15, 124, 124, 124, 92, 92, 92, 92, 92, 92, 92, 92, 124, 124, - 124, 124, 92, 124, 124, 15, 92, 92, 92, 92, 92, 92, 92, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 92, 92, 3, 3, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 3, 91, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 92, 124, 124, 0, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 15, 15, 0, 0, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 0, 15, 0, 0, 0, - 15, 15, 15, 15, 0, 0, 92, 15, 124, 124, 124, 92, 92, 92, 92, 0, 0, - 124, 124, 0, 0, 124, 124, 92, 15, 0, 0, 0, 0, 0, 0, 0, 0, 124, 0, 0, - 0, 0, 15, 15, 0, 15, 15, 15, 92, 92, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 15, 15, 4, 4, 18, 18, 18, 18, 18, 18, 14, 4, 15, 3, 0, 0, 0, - 92, 92, 124, 0, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 15, 15, 0, 0, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 0, 15, 15, - 0, 15, 15, 0, 0, 92, 0, 124, 124, 124, 92, 92, 0, 0, 0, 0, 92, 92, - 0, 0, 92, 92, 92, 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, - 0, 15, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 92, 92, 15, - 15, 15, 92, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 92, 92, 124, 0, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 124, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 92, 124, 92, 15, 124, 124, 124, 92, 92, 92, 92, 92, 92, 92, + 92, 124, 124, 124, 124, 92, 124, 124, 15, 92, 92, 92, 92, 92, 92, 92, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 92, 92, 3, 3, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 3, 91, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 92, 124, 124, 0, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, + 15, 15, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 0, 15, + 0, 0, 0, 15, 15, 15, 15, 0, 0, 92, 15, 124, 124, 124, 92, 92, 92, 92, + 0, 0, 124, 124, 0, 0, 124, 124, 92, 15, 0, 0, 0, 0, 0, 0, 0, 0, 124, + 0, 0, 0, 0, 15, 15, 0, 15, 15, 15, 92, 92, 0, 0, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 15, 15, 4, 4, 18, 18, 18, 18, 18, 18, 14, 4, 15, 3, 92, + 0, 0, 92, 92, 124, 0, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 15, 15, 0, + 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 0, + 15, 15, 0, 15, 15, 0, 0, 92, 0, 124, 124, 124, 92, 92, 0, 0, 0, 0, + 92, 92, 0, 0, 92, 92, 92, 0, 0, 0, 92, 0, 0, 0, 0, 0, 0, 0, 15, 15, + 15, 15, 0, 15, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 92, + 92, 15, 15, 15, 92, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 92, 92, 124, 0, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 0, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 0, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 0, 15, 15, 15, 15, 15, + 0, 0, 92, 15, 124, 124, 124, 92, 92, 92, 92, 92, 0, 92, 92, 124, 0, + 124, 124, 92, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 15, 15, 92, 92, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 3, 4, 0, 0, 0, + 0, 0, 0, 0, 15, 92, 92, 92, 92, 92, 92, 0, 92, 124, 124, 0, 15, 15, + 15, 15, 15, 15, 15, 15, 0, 0, 15, 15, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 0, 15, 15, 15, 15, 15, 0, 0, - 92, 15, 124, 124, 124, 92, 92, 92, 92, 92, 0, 92, 92, 124, 0, 124, - 124, 92, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, - 15, 92, 92, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 3, 4, 0, 0, 0, 0, 0, - 0, 0, 15, 92, 92, 92, 92, 92, 92, 0, 92, 124, 124, 0, 15, 15, 15, 15, - 15, 15, 15, 15, 0, 0, 15, 15, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, - 15, 15, 15, 15, 15, 0, 15, 15, 0, 15, 15, 15, 15, 15, 0, 0, 92, 15, - 124, 92, 124, 92, 92, 92, 92, 0, 0, 124, 124, 0, 0, 124, 124, 92, 0, - 0, 0, 0, 0, 0, 0, 0, 92, 124, 0, 0, 0, 0, 15, 15, 0, 15, 15, 15, 92, - 92, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 14, 15, 18, 18, 18, 18, 18, - 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 92, 15, 0, 15, 15, 15, 15, 15, 15, - 0, 0, 0, 15, 15, 15, 0, 15, 15, 15, 15, 0, 0, 0, 15, 15, 0, 15, 0, - 15, 15, 0, 0, 0, 15, 15, 0, 0, 0, 15, 15, 15, 0, 0, 0, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 124, 124, 92, 124, + 92, 15, 124, 92, 124, 92, 92, 92, 92, 0, 0, 124, 124, 0, 0, 124, 124, + 92, 0, 0, 0, 0, 0, 0, 0, 0, 92, 124, 0, 0, 0, 0, 15, 15, 0, 15, 15, + 15, 92, 92, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 14, 15, 18, 18, 18, + 18, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 92, 15, 0, 15, 15, 15, 15, + 15, 15, 0, 0, 0, 15, 15, 15, 0, 15, 15, 15, 15, 0, 0, 0, 15, 15, 0, + 15, 0, 15, 15, 0, 0, 0, 15, 15, 0, 0, 0, 15, 15, 15, 0, 0, 0, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 124, 124, 92, 124, 124, 0, 0, 0, 124, 124, 124, 0, 124, 124, 124, 92, 0, 0, 15, 0, 0, 0, 0, 0, 0, 124, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 18, 18, 18, 14, 14, 14, 14, 14, 14, 4, 14, 0, - 0, 0, 0, 0, 92, 124, 124, 124, 0, 15, 15, 15, 15, 15, 15, 15, 15, 0, - 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 0, 0, 0, 0, 92, 124, 124, 124, 92, 15, 15, 15, 15, 15, 15, 15, 15, + 0, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 15, 92, 92, 92, 124, 124, 124, 124, 0, 92, 92, 92, 0, 92, 92, 92, 92, 0, 0, 0, 0, 0, 0, 0, 92, 92, 0, 15, 15, 15, 0, 0, 0, 0, 0, 15, 15, 92, 92, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 18, 18, 18, 18, 18, - 18, 18, 14, 15, 92, 124, 124, 0, 15, 15, 15, 15, 15, 15, 15, 15, 0, + 18, 18, 14, 15, 92, 124, 124, 3, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 0, 0, 92, 15, 124, 92, 124, @@ -765,353 +764,355 @@ static const unsigned char groupMap[] = { 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 0, 125, 0, 0, 0, 0, 0, 125, 0, 0, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 3, 91, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 0, 0, 15, 15, 15, 15, 15, - 15, 15, 0, 15, 0, 15, 15, 15, 15, 0, 0, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 0, 15, 15, 15, 15, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 0, 0, 15, 15, 15, 15, - 15, 15, 15, 0, 15, 0, 15, 15, 15, 15, 0, 0, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 0, 15, 15, 15, 15, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 92, 92, 92, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, - 0, 0, 0, 0, 0, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, - 126, 126, 126, 126, 126, 126, 126, 126, 126, 104, 104, 104, 104, 104, - 104, 0, 0, 110, 110, 110, 110, 110, 110, 0, 0, 8, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 3, 3, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 2, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 5, - 6, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 3, 3, 3, 127, - 127, 127, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, - 92, 92, 92, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 92, 92, 92, 3, 3, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 92, 92, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, - 0, 92, 92, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 92, 92, - 124, 92, 92, 92, 92, 92, 92, 92, 124, 124, 124, 124, 124, 124, 124, - 124, 92, 124, 124, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 3, 3, - 3, 91, 3, 3, 3, 4, 15, 92, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, - 0, 0, 0, 0, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 0, 0, 0, 0, 0, - 0, 3, 3, 3, 3, 3, 3, 8, 3, 3, 3, 3, 92, 92, 92, 17, 0, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 15, 15, 15, 91, 15, 15, 15, 15, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 3, 91, 126, 126, 126, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, + 15, 15, 15, 0, 0, 15, 15, 15, 15, 15, 15, 15, 0, 15, 0, 15, 15, 15, + 15, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 0, + 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 0, 15, 15, 15, 15, 0, 0, 15, 15, 15, 15, 15, 15, 15, 0, 15, 0, 15, + 15, 15, 15, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, - 0, 0, 0, 0, 15, 15, 15, 15, 15, 92, 92, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 92, 15, 0, 0, 0, 0, 0, 15, + 15, 0, 0, 92, 92, 92, 3, 3, 3, 3, 3, 3, 3, 3, 3, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 0, 0, 0, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 127, 127, 127, + 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, + 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, + 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, + 127, 127, 127, 104, 104, 104, 104, 104, 104, 0, 0, 110, 110, 110, 110, + 110, 110, 0, 0, 8, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 3, 3, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 2, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 5, 6, 0, 0, 0, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 3, 3, 3, 128, 128, 128, 15, 15, 15, 15, + 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 92, 92, 92, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 92, 92, 92, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 0, 92, 92, 92, 124, 124, 124, 124, 92, - 92, 124, 124, 124, 0, 0, 0, 0, 124, 124, 92, 124, 124, 124, 124, 124, - 124, 92, 92, 92, 0, 0, 0, 0, 14, 0, 0, 0, 3, 3, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 15, - 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, + 92, 92, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 0, 92, 92, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 92, 92, 124, 92, 92, 92, 92, 92, 92, + 92, 124, 124, 124, 124, 124, 124, 124, 124, 92, 124, 124, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 3, 3, 3, 91, 3, 3, 3, 4, 15, 92, 0, + 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 8, 3, 3, + 3, 3, 92, 92, 92, 17, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, + 0, 0, 15, 15, 15, 91, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 18, 0, 0, 0, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 92, 92, 124, 124, 92, 0, 0, 3, 3, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, + 92, 92, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 124, 92, 124, 92, 92, 92, 92, 92, 92, 92, 0, 92, 124, 92, 124, - 124, 92, 92, 92, 92, 92, 92, 92, 92, 124, 124, 124, 124, 124, 124, - 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 0, 0, 92, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, - 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 91, 3, 3, 3, 3, 3, 3, 0, 0, 92, 92, 92, - 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 119, 0, 92, 92, 92, 92, - 124, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 92, 15, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 92, 124, 92, - 92, 92, 92, 92, 124, 92, 124, 124, 124, 124, 124, 92, 124, 124, 15, - 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 3, - 3, 3, 3, 3, 3, 3, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 92, 92, 92, - 92, 92, 92, 92, 92, 92, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, - 92, 92, 124, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 124, - 92, 92, 92, 92, 124, 124, 92, 92, 124, 92, 92, 92, 15, 15, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 92, 124, 92, 92, 124, 124, 124, 92, 124, 92, 92, 92, 124, 124, 0, 0, - 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 15, 15, 15, 15, 124, 124, 124, 124, 124, - 124, 124, 124, 92, 92, 92, 92, 92, 92, 92, 92, 124, 124, 92, 92, 0, - 0, 0, 3, 3, 3, 3, 3, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 15, 15, - 15, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 91, 91, 91, 91, 91, 91, 3, 3, 128, 129, 130, 131, 131, - 132, 133, 134, 135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, - 92, 92, 92, 3, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, - 124, 92, 92, 92, 92, 92, 92, 92, 15, 15, 15, 15, 92, 15, 15, 15, 15, - 124, 124, 92, 15, 15, 124, 92, 92, 0, 0, 0, 0, 0, 0, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, + 92, 92, 92, 124, 124, 124, 124, 92, 92, 124, 124, 124, 0, 0, 0, 0, + 124, 124, 92, 124, 124, 124, 124, 124, 124, 92, 92, 92, 0, 0, 0, 0, + 14, 0, 0, 0, 3, 3, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 15, 15, 15, 15, 15, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, + 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 18, 0, 0, 0, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 92, 92, 124, 124, 92, 0, 0, 3, 3, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 124, 92, 124, 92, 92, + 92, 92, 92, 92, 92, 0, 92, 124, 92, 124, 124, 92, 92, 92, 92, 92, 92, + 92, 92, 124, 124, 124, 124, 124, 124, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 0, 0, 92, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 91, + 3, 3, 3, 3, 3, 3, 0, 0, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 119, 0, 92, 92, 92, 92, 124, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 92, 124, 92, 92, 92, 92, 92, 124, 92, 124, + 124, 124, 124, 124, 92, 124, 124, 15, 15, 15, 15, 15, 15, 15, 0, 0, + 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 3, 3, 3, 3, 3, 3, 3, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 92, 92, 92, 92, 92, 92, 92, 92, 92, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 92, 92, 124, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 124, 92, 92, 92, 92, 124, 124, + 92, 92, 124, 92, 92, 92, 15, 15, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 92, 124, 92, 92, 124, 124, + 124, 92, 124, 92, 92, 92, 124, 124, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, + 3, 15, 15, 15, 15, 124, 124, 124, 124, 124, 124, 124, 124, 92, 92, + 92, 92, 92, 92, 92, 92, 124, 124, 92, 92, 0, 0, 0, 3, 3, 3, 3, 3, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 15, 15, 15, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 91, 91, + 91, 91, 91, 91, 3, 3, 129, 130, 131, 132, 132, 133, 134, 135, 136, + 0, 0, 0, 0, 0, 0, 0, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, + 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, + 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, 137, + 137, 137, 137, 137, 137, 0, 0, 137, 137, 137, 3, 3, 3, 3, 3, 3, 3, + 3, 0, 0, 0, 0, 0, 0, 0, 0, 92, 92, 92, 3, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 124, 92, 92, 92, 92, 92, 92, 92, 15, 15, 15, + 15, 92, 15, 15, 15, 15, 124, 124, 92, 15, 15, 124, 92, 92, 0, 0, 0, + 0, 0, 0, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, - 91, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 91, 136, 21, - 21, 21, 137, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 91, 91, - 91, 91, 91, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, - 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 0, 92, 92, 92, 92, - 92, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, - 23, 24, 23, 24, 23, 24, 21, 21, 21, 21, 21, 138, 21, 21, 139, 21, 140, - 140, 140, 140, 140, 140, 140, 140, 141, 141, 141, 141, 141, 141, 141, - 141, 140, 140, 140, 140, 140, 140, 0, 0, 141, 141, 141, 141, 141, 141, - 0, 0, 140, 140, 140, 140, 140, 140, 140, 140, 141, 141, 141, 141, 141, - 141, 141, 141, 140, 140, 140, 140, 140, 140, 140, 140, 141, 141, 141, - 141, 141, 141, 141, 141, 140, 140, 140, 140, 140, 140, 0, 0, 141, 141, - 141, 141, 141, 141, 0, 0, 21, 140, 21, 140, 21, 140, 21, 140, 0, 141, - 0, 141, 0, 141, 0, 141, 140, 140, 140, 140, 140, 140, 140, 140, 141, - 141, 141, 141, 141, 141, 141, 141, 142, 142, 143, 143, 143, 143, 144, - 144, 145, 145, 146, 146, 147, 147, 0, 0, 140, 140, 140, 140, 140, 140, - 140, 140, 148, 148, 148, 148, 148, 148, 148, 148, 140, 140, 140, 140, - 140, 140, 140, 140, 148, 148, 148, 148, 148, 148, 148, 148, 140, 140, - 140, 140, 140, 140, 140, 140, 148, 148, 148, 148, 148, 148, 148, 148, - 140, 140, 21, 149, 21, 0, 21, 21, 141, 141, 150, 150, 151, 11, 152, - 11, 11, 11, 21, 149, 21, 0, 21, 21, 153, 153, 153, 153, 151, 11, 11, - 11, 140, 140, 21, 21, 0, 0, 21, 21, 141, 141, 154, 154, 0, 11, 11, - 11, 140, 140, 21, 21, 21, 113, 21, 21, 141, 141, 155, 155, 117, 11, - 11, 11, 0, 0, 21, 149, 21, 0, 21, 21, 156, 156, 157, 157, 151, 11, - 11, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 17, 17, 17, 17, 17, 8, 8, 8, - 8, 8, 8, 3, 3, 16, 20, 5, 16, 16, 20, 5, 16, 3, 3, 3, 3, 3, 3, 3, 3, - 158, 159, 17, 17, 17, 17, 17, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 16, 20, - 3, 3, 3, 3, 12, 12, 3, 3, 3, 7, 5, 6, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 7, 3, 12, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 17, 17, 17, 17, 17, 0, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 18, 91, 0, 0, 18, 18, 18, 18, - 18, 18, 7, 7, 7, 5, 6, 91, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 7, 7, 7, 5, 6, 0, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, - 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, - 119, 119, 119, 119, 92, 119, 119, 119, 92, 92, 92, 92, 92, 92, 92, - 92, 92, 92, 92, 92, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, - 14, 107, 14, 14, 14, 14, 107, 14, 14, 21, 107, 107, 107, 21, 21, 107, - 107, 107, 21, 14, 107, 14, 14, 7, 107, 107, 107, 107, 107, 14, 14, - 14, 14, 14, 14, 107, 14, 160, 14, 107, 14, 161, 162, 107, 107, 14, - 21, 107, 107, 163, 107, 21, 15, 15, 15, 15, 21, 14, 14, 21, 21, 107, - 107, 7, 7, 7, 7, 7, 107, 21, 21, 21, 21, 14, 7, 14, 14, 164, 14, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 165, 165, - 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, - 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, - 166, 166, 127, 127, 127, 23, 24, 127, 127, 127, 127, 18, 14, 14, 0, - 0, 0, 0, 7, 7, 7, 7, 7, 14, 14, 14, 14, 14, 7, 7, 14, 14, 14, 14, 7, - 14, 14, 7, 14, 14, 7, 14, 14, 14, 14, 14, 14, 14, 7, 14, 14, 14, 14, + 91, 91, 91, 91, 91, 91, 91, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 91, 138, 21, 21, 21, 139, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 91, 91, 91, 91, 91, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 0, 92, 92, 92, 92, 92, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, + 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 21, 21, 21, 21, 21, + 140, 21, 21, 141, 21, 142, 142, 142, 142, 142, 142, 142, 142, 143, + 143, 143, 143, 143, 143, 143, 143, 142, 142, 142, 142, 142, 142, 0, + 0, 143, 143, 143, 143, 143, 143, 0, 0, 142, 142, 142, 142, 142, 142, + 142, 142, 143, 143, 143, 143, 143, 143, 143, 143, 142, 142, 142, 142, + 142, 142, 142, 142, 143, 143, 143, 143, 143, 143, 143, 143, 142, 142, + 142, 142, 142, 142, 0, 0, 143, 143, 143, 143, 143, 143, 0, 0, 21, 142, + 21, 142, 21, 142, 21, 142, 0, 143, 0, 143, 0, 143, 0, 143, 142, 142, + 142, 142, 142, 142, 142, 142, 143, 143, 143, 143, 143, 143, 143, 143, + 144, 144, 145, 145, 145, 145, 146, 146, 147, 147, 148, 148, 149, 149, + 0, 0, 142, 142, 142, 142, 142, 142, 142, 142, 150, 150, 150, 150, 150, + 150, 150, 150, 142, 142, 142, 142, 142, 142, 142, 142, 150, 150, 150, + 150, 150, 150, 150, 150, 142, 142, 142, 142, 142, 142, 142, 142, 150, + 150, 150, 150, 150, 150, 150, 150, 142, 142, 21, 151, 21, 0, 21, 21, + 143, 143, 152, 152, 153, 11, 154, 11, 11, 11, 21, 151, 21, 0, 21, 21, + 155, 155, 155, 155, 153, 11, 11, 11, 142, 142, 21, 21, 0, 0, 21, 21, + 143, 143, 156, 156, 0, 11, 11, 11, 142, 142, 21, 21, 21, 113, 21, 21, + 143, 143, 157, 157, 117, 11, 11, 11, 0, 0, 21, 151, 21, 0, 21, 21, + 158, 158, 159, 159, 153, 11, 11, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 17, 17, 17, 17, 17, 8, 8, 8, 8, 8, 8, 3, 3, 16, 20, 5, 16, 16, 20, + 5, 16, 3, 3, 3, 3, 3, 3, 3, 3, 160, 161, 17, 17, 17, 17, 17, 2, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 16, 20, 3, 3, 3, 3, 12, 12, 3, 3, 3, 7, 5, + 6, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 7, 3, 12, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 2, 17, 17, 17, 17, 17, 0, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 18, 91, 0, 0, 18, 18, 18, 18, 18, 18, 7, 7, 7, 5, 6, 91, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 7, 7, 7, 5, 6, 0, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 119, 119, 119, 119, 92, 119, 119, + 119, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 107, 14, 14, 14, 14, 107, 14, + 14, 21, 107, 107, 107, 21, 21, 107, 107, 107, 21, 14, 107, 14, 14, + 7, 107, 107, 107, 107, 107, 14, 14, 14, 14, 14, 14, 107, 14, 162, 14, + 107, 14, 163, 164, 107, 107, 14, 21, 107, 107, 165, 107, 21, 15, 15, + 15, 15, 21, 14, 14, 21, 21, 107, 107, 7, 7, 7, 7, 7, 107, 21, 21, 21, + 21, 14, 7, 14, 14, 166, 14, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 167, 167, 167, 167, 167, 167, 167, 167, 167, + 167, 167, 167, 167, 167, 167, 167, 168, 168, 168, 168, 168, 168, 168, + 168, 168, 168, 168, 168, 168, 168, 168, 168, 128, 128, 128, 23, 24, + 128, 128, 128, 128, 18, 14, 14, 0, 0, 0, 0, 7, 7, 7, 7, 7, 14, 14, + 14, 14, 14, 7, 7, 14, 14, 14, 14, 7, 14, 14, 7, 14, 14, 7, 14, 14, + 14, 14, 14, 14, 14, 7, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 7, 7, 14, 14, 7, 14, 7, 14, + 14, 14, 14, 7, 7, 14, 14, 7, 14, 7, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 7, 7, 7, 7, 7, + 14, 14, 14, 14, 14, 14, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 14, 14, 14, 14, 14, - 14, 14, 14, 5, 6, 5, 6, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 7, 7, 14, 14, 14, 14, 14, 14, 14, - 5, 6, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 7, 7, 7, 7, 7, 7, 14, 14, 14, 14, 14, 14, 14, 14, 5, 6, 5, 6, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 7, + 14, 7, 7, 14, 14, 14, 14, 14, 14, 14, 5, 6, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 7, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 7, 7, 7, 7, 7, 7, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 7, 7, 7, 7, 7, + 7, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 14, 14, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 167, 167, 167, 167, 167, 167, 167, 167, - 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, - 167, 167, 167, 167, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, - 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, - 168, 168, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 7, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 7, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 170, 170, + 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, + 170, 170, 170, 170, 170, 170, 170, 170, 170, 170, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 7, 14, 14, 14, 14, 14, 14, 14, 14, 14, 7, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 7, 7, 7, 7, 7, 7, 7, 7, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 7, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 18, 18, + 14, 14, 7, 7, 7, 7, 7, 7, 7, 7, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 7, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 5, 6, 5, 6, + 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 7, 7, 7, 7, 7, 5, 6, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, - 6, 5, 6, 5, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 5, 6, 5, 6, 7, 7, 7, 7, 7, 7, + 18, 18, 18, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 7, 7, 7, + 7, 7, 5, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 5, 6, 5, 6, 5, + 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 5, 6, 7, 7, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 14, 14, 7, 7, 7, 7, 7, 7, 14, 14, 14, 14, 14, 14, 14, 14, + 7, 7, 5, 6, 5, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 5, 6, 7, 7, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 14, 14, 7, 7, 7, 7, + 7, 7, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 14, 14, + 14, 14, 14, 14, 14, 14, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 14, 14, 14, + 14, 14, 14, 14, 14, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, - 122, 122, 122, 122, 122, 122, 122, 122, 122, 0, 123, 123, 123, 123, + 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 0, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, - 123, 0, 23, 24, 169, 170, 171, 172, 173, 23, 24, 23, 24, 23, 24, 174, - 175, 176, 177, 21, 23, 24, 21, 23, 24, 21, 21, 21, 21, 21, 91, 91, - 178, 178, 23, 24, 23, 24, 21, 14, 14, 14, 14, 14, 14, 23, 24, 23, 24, - 92, 92, 92, 23, 24, 0, 0, 0, 0, 0, 3, 3, 3, 3, 18, 3, 3, 179, 179, - 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, - 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, - 179, 179, 179, 179, 179, 179, 179, 179, 0, 179, 0, 0, 0, 0, 0, 179, - 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 91, 3, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 92, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, - 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, - 0, 3, 3, 16, 20, 16, 20, 3, 3, 3, 16, 20, 3, 16, 20, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 8, 3, 3, 8, 3, 16, 20, 3, 3, 16, 20, 5, 6, 5, 6, 5, 6, - 5, 6, 3, 3, 3, 3, 3, 91, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 8, 8, 3, 3, - 3, 3, 8, 3, 5, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 123, 123, 123, 123, 123, 0, 23, 24, 171, 172, 173, 174, 175, 23, 24, + 23, 24, 23, 24, 176, 177, 178, 179, 21, 23, 24, 21, 23, 24, 21, 21, + 21, 21, 21, 91, 91, 180, 180, 23, 24, 23, 24, 21, 14, 14, 14, 14, 14, + 14, 23, 24, 23, 24, 92, 92, 92, 23, 24, 0, 0, 0, 0, 0, 3, 3, 3, 3, + 18, 3, 3, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, + 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, + 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, 0, 181, + 0, 0, 0, 0, 0, 181, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, + 0, 0, 91, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 92, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, + 15, 0, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 0, + 15, 15, 15, 15, 15, 15, 15, 0, 3, 3, 16, 20, 16, 20, 3, 3, 3, 16, 20, + 3, 16, 20, 3, 3, 3, 3, 3, 3, 3, 3, 3, 8, 3, 3, 8, 3, 16, 20, 3, 3, + 16, 20, 5, 6, 5, 6, 5, 6, 5, 6, 3, 3, 3, 3, 3, 91, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 8, 8, 3, 3, 3, 3, 8, 3, 5, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 0, 0, 0, 0, 2, 3, 3, 3, 14, 91, 15, 127, 5, 6, 5, 6, 5, - 6, 5, 6, 5, 6, 14, 14, 5, 6, 5, 6, 5, 6, 5, 6, 8, 5, 6, 6, 14, 127, - 127, 127, 127, 127, 127, 127, 127, 127, 92, 92, 92, 92, 124, 124, 8, - 91, 91, 91, 91, 91, 14, 14, 127, 127, 127, 91, 15, 3, 14, 14, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 0, 0, 92, 92, 11, 11, 91, 91, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 3, 91, 91, 91, 15, 0, 0, 0, 0, 0, 15, 15, 15, 15, + 14, 14, 14, 14, 14, 14, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 2, 3, 3, 3, 14, 91, + 15, 128, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 14, 14, 5, 6, 5, 6, 5, 6, 5, + 6, 8, 5, 6, 6, 14, 128, 128, 128, 128, 128, 128, 128, 128, 128, 92, + 92, 92, 92, 124, 124, 8, 91, 91, 91, 91, 91, 14, 14, 128, 128, 128, + 91, 15, 3, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 92, 92, 11, 11, 91, + 91, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 3, 91, 91, 91, 15, + 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 14, 14, 18, 18, 18, 18, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 0, 14, 14, 18, 18, 18, 18, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 14, 14, - 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 0, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 18, 18, 18, - 18, 18, 18, 18, 18, 14, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 91, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 14, 14, + 15, 15, 15, 0, 0, 0, 0, 0, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, + 14, 14, 14, 14, 14, 14, 14, 14, 18, 18, 18, 18, 18, 18, 18, 18, 14, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 91, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 91, 3, 3, 3, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 15, 15, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 24, 23, - 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 15, 92, 119, 119, 119, - 3, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 3, 91, 23, 24, 23, 24, 23, - 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, - 23, 24, 23, 24, 23, 24, 91, 91, 92, 92, 15, 15, 15, 15, 15, 15, 127, - 127, 127, 127, 127, 127, 127, 127, 127, 127, 92, 92, 3, 3, 3, 3, 3, - 3, 0, 0, 0, 0, 0, 0, 0, 0, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 91, 91, 91, 91, - 91, 91, 91, 91, 91, 11, 11, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, - 23, 24, 23, 24, 21, 21, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, - 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, - 23, 24, 91, 21, 21, 21, 21, 21, 21, 21, 21, 23, 24, 23, 24, 180, 23, - 24, 23, 24, 23, 24, 23, 24, 23, 24, 91, 11, 11, 23, 24, 181, 21, 15, - 23, 24, 23, 24, 21, 21, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, - 24, 23, 24, 23, 24, 23, 24, 23, 24, 182, 183, 184, 185, 182, 0, 186, - 187, 188, 189, 23, 24, 23, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 91, 91, - 21, 15, 15, 15, 15, 15, 15, 15, 92, 15, 15, 15, 92, 15, 15, 15, 15, - 92, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 124, 124, 92, 92, 124, 14, 14, 14, 14, - 0, 0, 0, 0, 18, 18, 18, 18, 18, 18, 14, 14, 4, 14, 0, 0, 0, 0, 0, 0, + 15, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 124, 124, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 91, 3, 3, 3, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 15, + 92, 119, 119, 119, 3, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 3, 91, + 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, + 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 91, 91, 92, 92, 15, 15, + 15, 15, 15, 15, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 92, + 92, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 11, 11, 23, 24, 23, 24, 23, 24, + 23, 24, 23, 24, 23, 24, 23, 24, 21, 21, 23, 24, 23, 24, 23, 24, 23, + 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, + 23, 24, 23, 24, 23, 24, 91, 21, 21, 21, 21, 21, 21, 21, 21, 23, 24, + 23, 24, 182, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 91, 11, 11, 23, + 24, 183, 21, 15, 23, 24, 23, 24, 21, 21, 23, 24, 23, 24, 23, 24, 23, + 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 184, 185, 186, + 187, 184, 21, 188, 189, 190, 191, 23, 24, 23, 24, 23, 24, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 15, 91, 91, 21, 15, 15, 15, 15, 15, 15, 15, 92, 15, 15, 15, + 92, 15, 15, 15, 15, 92, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 124, 124, 92, 92, 124, + 14, 14, 14, 14, 0, 0, 0, 0, 18, 18, 18, 18, 18, 18, 14, 14, 4, 14, + 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 124, + 124, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 124, 124, 124, - 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 92, - 92, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, - 0, 0, 0, 0, 0, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, - 92, 92, 92, 92, 92, 15, 15, 15, 15, 15, 15, 3, 3, 3, 15, 3, 15, 0, - 0, 15, 15, 15, 15, 15, 15, 92, 92, 92, 92, 92, 92, 92, 92, 3, 3, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 124, - 124, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 92, 124, 124, 92, 92, 92, 92, 124, - 124, 92, 124, 124, 124, 124, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 0, 91, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 3, 3, 15, 15, 15, - 15, 15, 92, 91, 15, 15, 15, 15, 15, 15, 15, 15, 15, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 92, 92, 92, 92, 92, 92, 124, 124, 92, 92, 124, 124, 92, 92, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 92, 15, 15, 15, 15, 15, 15, 15, - 15, 92, 124, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 3, 3, 3, 3, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 91, - 15, 15, 15, 15, 15, 15, 14, 14, 14, 15, 124, 92, 124, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 92, 15, 92, - 92, 92, 15, 15, 92, 92, 15, 15, 15, 15, 15, 92, 92, 15, 92, 15, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 15, 15, 91, 3, 3, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 124, - 92, 92, 124, 124, 3, 3, 15, 91, 91, 124, 92, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 15, 15, 15, 15, 15, 15, 0, 0, 15, 15, 15, 15, 15, 15, 0, 0, 15, - 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, - 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 0, 21, 21, 21, 21, 21, 21, 21, + 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, + 124, 124, 92, 92, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 0, 0, 0, 0, 0, 0, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 15, 15, 15, 15, 15, 15, 3, 3, 3, 15, + 3, 15, 15, 92, 15, 15, 15, 15, 15, 15, 92, 92, 92, 92, 92, 92, 92, + 92, 3, 3, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 124, 124, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 92, 124, 124, 92, 92, + 92, 92, 124, 124, 92, 124, 124, 124, 124, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 0, 91, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 3, 3, + 15, 15, 15, 15, 15, 92, 91, 15, 15, 15, 15, 15, 15, 15, 15, 15, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 92, 92, 92, 92, 92, 92, 124, 124, 92, 92, 124, 124, + 92, 92, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 92, 15, 15, 15, 15, + 15, 15, 15, 15, 92, 124, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, + 3, 3, 3, 3, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 91, 15, 15, 15, 15, 15, 15, 14, 14, 14, 15, 124, 92, 124, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 92, 15, 92, 92, 92, 15, 15, 92, 92, 15, 15, 15, 15, 15, 92, 92, 15, + 92, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 15, 15, 91, 3, 3, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 124, 92, 92, 124, 124, 3, 3, 15, 91, 91, 124, 92, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 0, 0, 15, 15, 15, 15, 15, 15, + 0, 0, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, + 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 0, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 190, 21, 21, 21, 21, 21, - 21, 21, 11, 91, 91, 91, 91, 21, 21, 21, 21, 21, 21, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, - 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, - 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, - 191, 191, 191, 191, 191, 191, 191, 191, 191, 15, 15, 15, 124, 124, - 92, 124, 124, 92, 124, 124, 3, 124, 92, 0, 0, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 15, 15, 15, 15, 15, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 192, 21, 21, 21, + 21, 21, 21, 21, 11, 91, 91, 91, 91, 21, 21, 21, 21, 21, 21, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, + 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, + 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, + 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 15, 15, 15, 124, + 124, 92, 124, 124, 92, 124, 124, 3, 124, 92, 0, 0, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 192, 192, 192, - 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, - 192, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, - 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, - 193, 193, 193, 193, 193, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 194, 194, 194, + 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, + 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, + 194, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, + 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, + 195, 195, 195, 195, 195, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 21, @@ -1161,10 +1162,10 @@ static const unsigned char groupMap[] = { 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 18, + 14, 14, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 18, 18, 18, 18, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 18, 18, 14, 14, 14, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -1177,29 +1178,29 @@ static const unsigned char groupMap[] = { 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 0, 0, 0, 0, 18, 18, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 127, 15, 15, 15, 15, 15, 15, - 15, 15, 127, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 128, 15, 15, 15, 15, 15, 15, + 15, 15, 128, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 92, 92, 92, 92, 92, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, - 3, 15, 15, 15, 15, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 3, 127, - 127, 127, 127, 127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 194, 194, 194, 194, - 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, - 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, - 194, 194, 194, 194, 194, 194, 194, 194, 195, 195, 195, 195, 195, 195, - 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, - 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, - 195, 195, 195, 195, 195, 195, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 3, 15, 15, 15, 15, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 3, 128, + 128, 128, 128, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 196, 196, 196, 196, + 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, + 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, + 196, 196, 196, 196, 196, 196, 196, 196, 197, 197, 197, 197, 197, 197, + 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, + 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, + 197, 197, 197, 197, 197, 197, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 194, - 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, - 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, - 194, 194, 194, 194, 194, 194, 194, 0, 0, 0, 0, 195, 195, 195, 195, - 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, - 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, - 195, 195, 195, 195, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 0, + 15, 15, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 196, + 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, + 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, + 196, 196, 196, 196, 196, 196, 196, 0, 0, 0, 0, 197, 197, 197, 197, + 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, + 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, + 197, 197, 197, 197, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, @@ -1223,300 +1224,316 @@ static const unsigned char groupMap[] = { 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 15, 92, 92, 92, 0, 92, 92, 0, 0, 0, 0, 0, 92, 92, 92, 92, 15, 15, 15, 15, 0, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 92, 92, 92, 0, 0, 0, - 0, 92, 18, 18, 18, 18, 18, 18, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 92, 92, 92, 0, 0, + 0, 0, 92, 18, 18, 18, 18, 18, 18, 18, 18, 18, 0, 0, 0, 0, 0, 0, 0, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 18, 18, 3, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 18, 18, 3, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 18, 18, 18, 15, 15, 15, 15, 15, 15, 15, 15, 14, 15, 15, + 15, 15, 15, 15, 15, 18, 18, 18, 15, 15, 15, 15, 15, 15, 15, 15, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 92, 92, 0, 0, 0, 0, 18, 18, 18, - 18, 18, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 92, 92, 0, 0, 0, 0, 18, + 18, 18, 18, 18, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 18, 18, + 15, 15, 15, 15, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, + 0, 18, 18, 18, 18, 18, 18, 18, 18, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 18, 18, 18, 18, 18, 18, 18, 18, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 18, 18, 18, 18, 18, - 18, 18, 18, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 18, 18, 18, 18, 18, 18, 18, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 97, + 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 18, 18, 18, 18, 18, 18, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, - 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 102, 102, 102, 102, 102, 102, 102, + 97, 97, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, - 102, 102, 0, 0, 0, 0, 0, 0, 0, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 102, 102, 102, 102, 102, 0, 0, 0, 0, 0, 0, 0, 18, 18, 18, 18, 18, 18, + 15, 15, 15, 15, 92, 92, 92, 92, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 0, 124, 92, 124, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 18, 18, 18, 18, 18, 18, 0, 18, 18, 18, 18, 18, 18, 18, 15, 0, 0, 0, + 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 18, 18, 18, 18, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 124, 92, + 124, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 3, 3, 3, - 3, 3, 3, 3, 0, 0, 0, 0, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 92, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 124, 124, 124, 92, 92, 92, - 92, 124, 124, 92, 92, 3, 3, 17, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 92, 92, 92, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 92, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 124, 124, 124, + 92, 92, 92, 92, 124, 124, 92, 92, 3, 3, 17, 3, 3, 3, 3, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, + 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 92, + 92, 92, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 92, 92, 92, 92, 92, 124, 92, 92, 92, 92, 92, 92, 92, 92, 0, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 15, 15, 15, 15, 92, 92, 92, 92, 92, 124, 92, 92, 92, 92, 92, 92, 92, + 92, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 3, 3, 3, 3, 15, 124, 124, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 92, 3, 3, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 92, 3, 3, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, + 15, 124, 124, 124, 92, 92, 92, 92, 92, 92, 92, 92, 92, 124, 124, 15, + 15, 15, 15, 3, 3, 3, 3, 92, 92, 92, 92, 3, 0, 0, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 15, 3, 15, 3, 3, 3, 0, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 124, 124, 124, - 92, 92, 92, 92, 92, 92, 92, 92, 92, 124, 124, 15, 15, 15, 15, 3, 3, - 3, 3, 3, 92, 92, 92, 3, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 15, 3, - 15, 3, 3, 3, 0, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, + 92, 92, 92, 124, 124, 92, 124, 92, 92, 3, 3, 3, 3, 3, 3, 92, 0, 15, + 15, 15, 15, 15, 15, 15, 0, 15, 0, 15, 15, 15, 15, 0, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 3, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 124, 124, 124, 92, 92, 92, 124, 124, - 92, 124, 92, 92, 3, 3, 3, 3, 3, 3, 92, 0, 15, 15, 15, 15, 15, 15, 15, - 0, 15, 0, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 3, 0, - 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 92, 124, 124, 124, 92, 92, 92, 92, 92, 92, 92, 92, 0, 0, 0, 0, 0, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 92, 92, 124, 124, 0, 15, - 15, 15, 15, 15, 15, 15, 15, 0, 0, 15, 15, 0, 0, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 92, 124, 124, 124, 124, 0, 0, 124, - 124, 0, 0, 124, 124, 124, 0, 0, 15, 0, 0, 0, 0, 0, 0, 124, 0, 0, 0, - 0, 0, 15, 15, 15, 15, 15, 124, 124, 0, 0, 92, 92, 92, 92, 92, 92, 92, - 0, 0, 0, 92, 92, 92, 92, 92, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 124, 124, 124, 92, 92, 92, 92, 92, 92, 92, 92, 124, 124, 92, - 92, 92, 124, 92, 15, 15, 15, 15, 3, 3, 3, 3, 3, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 0, 3, 0, 3, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 124, 124, 124, 92, 92, 92, 92, 92, 92, 124, - 92, 124, 124, 124, 124, 92, 92, 124, 92, 92, 15, 15, 3, 15, 0, 0, 0, - 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 124, 124, 124, - 92, 92, 92, 92, 0, 0, 124, 124, 124, 124, 92, 92, 124, 92, 92, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 15, - 15, 15, 15, 92, 92, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 92, 124, 124, 124, 92, 92, 92, 92, 92, 92, + 92, 92, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, + 0, 92, 92, 124, 124, 0, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 15, 15, + 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 0, + 15, 15, 15, 15, 15, 0, 92, 92, 15, 124, 124, 92, 124, 124, 124, 124, + 0, 0, 124, 124, 0, 0, 124, 124, 124, 0, 0, 15, 0, 0, 0, 0, 0, 0, 124, + 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 124, 124, 0, 0, 92, 92, 92, 92, + 92, 92, 92, 0, 0, 0, 92, 92, 92, 92, 92, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 124, 124, 124, 92, 92, 92, 92, 92, 92, 92, 92, - 124, 124, 92, 124, 92, 92, 3, 3, 3, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 92, 124, 92, - 124, 124, 92, 92, 92, 92, 92, 92, 124, 92, 0, 0, 0, 0, 0, 0, 0, 0, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, - 0, 0, 92, 92, 92, 124, 124, 92, 92, 92, 92, 124, 92, 92, 92, 92, 92, - 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 18, 18, 3, 3, 3, 14, 10, + 124, 124, 92, 92, 92, 124, 92, 15, 15, 15, 15, 3, 3, 3, 3, 3, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 0, 3, 0, 3, 92, 0, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 124, 124, 124, 92, 92, 92, + 92, 92, 92, 124, 92, 124, 124, 124, 124, 92, 92, 124, 92, 92, 15, 15, + 3, 15, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, + 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 124, 124, 124, 92, 92, 92, 92, 0, 0, 124, 124, 124, 124, 92, 92, + 124, 92, 92, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 15, 15, 15, 15, 92, 92, 0, 0, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 124, 124, 124, 92, 92, 92, + 92, 92, 92, 92, 92, 124, 124, 92, 124, 92, 92, 3, 3, 3, 15, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, + 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 92, 124, 92, 124, 124, 92, 92, 92, 92, 92, 92, 124, 92, 0, 0, 0, + 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 124, 124, 92, 92, 92, 92, + 124, 92, 92, 92, 92, 92, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 18, 18, 3, 3, 3, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 124, 124, 124, 92, 92, 92, 92, 92, 92, 92, 92, 92, 124, 92, 92, 3, + 0, 0, 0, 0, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 18, 18, 18, 18, 18, 18, 18, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 15, 15, 92, 92, 92, 92, 92, 92, 124, 124, 92, 92, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 92, 92, 92, 92, 92, 92, 124, 15, 92, 92, 92, 92, 3, - 3, 3, 3, 3, 3, 3, 3, 92, 0, 0, 0, 0, 0, 0, 0, 0, 15, 92, 92, 92, 92, - 92, 92, 124, 124, 92, 92, 92, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, - 15, 15, 15, 15, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, - 124, 92, 92, 3, 3, 3, 0, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 124, 92, 92, 92, 92, 92, 92, 92, 0, 92, - 92, 92, 92, 92, 92, 124, 92, 15, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 0, 0, 0, 3, 3, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 92, 92, 92, 92, - 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, - 92, 0, 124, 92, 92, 92, 92, 92, 92, 92, 124, 92, 92, 124, 92, 92, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 0, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 10, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 18, 18, 18, 18, 18, 18, 18, 18, 18, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 92, 92, 92, 92, 92, 92, 124, 15, 92, + 92, 92, 92, 3, 3, 3, 3, 3, 3, 3, 3, 92, 0, 0, 0, 0, 0, 0, 0, 0, 15, + 92, 92, 92, 92, 92, 92, 124, 124, 92, 92, 92, 15, 15, 15, 15, 15, 15, + 15, 15, 0, 0, 15, 15, 15, 15, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 124, 92, 92, 3, 3, 3, 15, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 92, 92, 92, 92, 92, 92, 0, 0, 0, 92, 0, 92, 92, 0, 92, - 92, 92, 92, 92, 92, 92, 15, 92, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 127, 127, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 127, 127, 127, 0, 3, 3, 3, 3, 3, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 0, 0, 92, 92, 92, 92, 92, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 92, 92, 92, 92, 92, 92, 92, 3, 3, 3, 3, 3, 14, 14, 14, 14, 91, 91, - 91, 91, 3, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 0, 18, 18, 18, 18, 18, 18, 18, 0, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, - 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, - 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 124, 124, 124, 124, - 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 124, 92, 92, 92, + 92, 92, 92, 92, 0, 92, 92, 92, 92, 92, 92, 124, 92, 15, 3, 3, 3, 3, + 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 0, 0, 0, 3, 3, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 0, 0, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 0, 124, 92, 92, 92, 92, 92, 92, 92, 124, + 92, 92, 124, 92, 92, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, + 15, 15, 0, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 92, 92, 92, 92, 92, 92, 0, 0, 0, + 92, 0, 92, 92, 0, 92, 92, 92, 92, 92, 92, 92, 15, 92, 0, 0, 0, 0, 0, + 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 15, 15, 15, + 15, 15, 15, 0, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 124, 124, 124, 124, 124, 0, 92, 92, 0, 124, 124, 92, + 124, 92, 15, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 92, 92, 124, 124, 3, 3, 0, + 0, 0, 0, 0, 0, 0, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 0, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 0, 0, 0, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, + 0, 92, 92, 92, 92, 92, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 92, 92, 92, 92, + 92, 92, 92, 3, 3, 3, 3, 3, 14, 14, 14, 14, 91, 91, 91, 91, 3, 14, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 18, 18, + 18, 18, 18, 18, 18, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 15, 15, 15, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 3, 3, 3, 3, 0, 0, 0, 0, 0, 15, 15, 15, 15, + 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 92, 92, 92, 92, 91, - 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 0, 0, 0, 0, + 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 92, 92, 92, 92, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, - 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 14, 92, 92, 3, 17, - 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 0, 0, 14, 14, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 14, 92, 92, 3, 17, 17, 17, + 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 124, 124, 92, 92, 92, 14, 14, 14, - 124, 124, 124, 124, 124, 124, 17, 17, 17, 17, 17, 17, 17, 17, 92, 92, - 92, 92, 92, 92, 92, 92, 14, 14, 92, 92, 92, 92, 92, 92, 92, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 124, 124, 92, 92, 92, 14, 14, 14, 124, + 124, 124, 124, 124, 124, 17, 17, 17, 17, 17, 17, 17, 17, 92, 92, 92, + 92, 92, 92, 92, 92, 14, 14, 92, 92, 92, 92, 92, 92, 92, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 92, 92, 92, 92, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 92, 92, 92, 92, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 92, 92, 92, 14, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, + 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 92, 92, 92, 14, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 107, 107, 107, 107, 107, 107, 107, 107, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 0, 0, 0, + 0, 0, 0, 0, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 107, 107, 107, + 107, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 21, 21, 21, 21, 21, 21, - 21, 0, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 21, 21, 21, 21, 21, 21, 21, 0, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 107, 0, 107, 107, 0, 0, 107, - 0, 0, 107, 107, 0, 0, 107, 107, 107, 107, 0, 107, 107, 107, 107, 107, - 107, 107, 107, 21, 21, 21, 21, 0, 21, 0, 21, 21, 21, 21, 21, 21, 21, - 0, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 107, 0, 107, 107, 0, 0, 107, 0, 0, 107, 107, + 0, 0, 107, 107, 107, 107, 0, 107, 107, 107, 107, 107, 107, 107, 107, + 21, 21, 21, 21, 0, 21, 0, 21, 21, 21, 21, 21, 21, 21, 0, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 21, 21, 21, 21, 21, 21, 21, + 107, 107, 107, 107, 107, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 107, 107, + 0, 107, 107, 107, 107, 0, 0, 107, 107, 107, 107, 107, 107, 107, 107, + 0, 107, 107, 107, 107, 107, 107, 107, 0, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 107, 107, 0, 107, 107, 107, 107, 0, 0, 107, 107, 107, 107, - 107, 107, 107, 107, 0, 107, 107, 107, 107, 107, 107, 107, 0, 21, 21, + 21, 21, 107, 107, 0, 107, 107, 107, 107, 0, 107, 107, 107, 107, 107, + 0, 107, 0, 0, 0, 107, 107, 107, 107, 107, 107, 107, 0, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 107, 107, 0, 107, 107, 107, 107, 0, 107, - 107, 107, 107, 107, 0, 107, 0, 0, 0, 107, 107, 107, 107, 107, 107, - 107, 0, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 107, 107, 107, 107, 107, + 21, 21, 21, 21, 21, 21, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 107, 107, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 107, 107, 107, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 21, 21, 21, 21, 21, 21, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 107, 107, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 21, 21, 21, 21, 21, 21, 0, 0, 107, 107, 107, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 7, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 7, 21, 21, 21, 21, 21, 21, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 7, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 7, 21, 21, - 21, 21, 21, 21, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 21, 21, 21, 21, 21, 21, 0, 0, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 7, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 7, 21, 21, 21, 21, 21, 21, 107, + 107, 107, 107, 7, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 7, 21, 21, 21, 21, + 21, 21, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 7, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 7, 21, 21, 21, 21, 21, 21, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 7, 21, 21, 21, 21, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 7, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 7, 21, 21, 21, 21, 21, 21, 107, 107, 107, 107, 107, + 21, 21, 21, 7, 21, 21, 21, 21, 21, 21, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 7, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 7, - 21, 21, 21, 21, 21, 21, 107, 21, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 107, 107, 107, 107, 107, 7, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 7, 21, + 21, 21, 21, 21, 21, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 7, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 7, 21, 21, 21, 21, 21, 21, + 107, 21, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 92, 92, 92, 92, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 14, 14, 14, 14, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, - 92, 92, 14, 14, 14, 14, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, - 92, 92, 92, 92, 92, 92, 92, 14, 14, 14, 14, 14, 14, 14, 14, 92, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 92, 14, 14, 3, - 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 92, 92, 92, - 92, 92, 0, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, - 92, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 92, 92, 92, 92, - 92, 92, 92, 0, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, - 92, 92, 92, 92, 0, 0, 92, 92, 92, 92, 92, 92, 92, 0, 92, 92, 0, 92, - 92, 92, 92, 92, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 15, 15, 15, 15, 15, 0, 0, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 92, 92, 92, 92, 92, 92, 92, 0, 0, 0, 0, 0, 0, 0, 0, 0, 196, 196, - 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, - 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, - 196, 196, 196, 196, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, - 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, - 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 92, 92, 92, 92, 92, - 92, 92, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 3, - 3, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, - 15, 0, 15, 0, 0, 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, - 15, 15, 15, 15, 0, 15, 0, 15, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 15, - 0, 15, 0, 15, 0, 15, 15, 15, 0, 15, 15, 0, 15, 0, 0, 15, 0, 15, 0, - 15, 0, 15, 0, 15, 0, 15, 15, 0, 15, 0, 0, 15, 15, 15, 15, 0, 15, 15, - 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 0, 15, 15, 15, 15, 0, 15, 0, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 15, 15, - 15, 0, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 14, 14, + 92, 14, 14, 14, 14, 14, 14, 14, 14, 92, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 92, 14, 14, 3, 3, 3, 3, 3, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 92, 92, 92, 92, 92, 0, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 92, 92, 92, 92, 92, 92, 92, 0, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 0, 0, 92, 92, + 92, 92, 92, 92, 92, 0, 92, 92, 0, 92, 92, 92, 92, 92, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, + 0, 0, 18, 18, 18, 18, 18, 18, 18, 18, 18, 92, 92, 92, 92, 92, 92, 92, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 198, 198, 198, 198, 198, 198, 198, 198, + 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, + 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 199, 199, + 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, + 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, 199, + 199, 199, 199, 199, 92, 92, 92, 92, 92, 92, 92, 0, 0, 0, 0, 0, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 14, + 18, 18, 18, 4, 18, 18, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, + 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, + 0, 15, 0, 0, 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, + 15, 15, 15, 0, 15, 0, 15, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 15, 0, + 15, 0, 15, 0, 15, 15, 15, 0, 15, 15, 0, 15, 0, 0, 15, 0, 15, 0, 15, + 0, 15, 0, 15, 0, 15, 15, 0, 15, 0, 0, 15, 15, 15, 15, 0, 15, 15, 15, + 15, 15, 15, 15, 0, 15, 15, 15, 15, 0, 15, 15, 15, 15, 0, 15, 0, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 15, 15, 15, + 0, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, - 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 0, 14, - 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 11, 11, 11, 11, 11, + 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 0, + 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, + 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 11, 11, 11, + 11, 11, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, - 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, - 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 14, + 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 0, + 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, + 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 14, 14, 14, 14, 0, 0, 0, 14, - 0, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 15, 15, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 0, 0, 14, 14, 14, 14, 0, 0, 0, 14, 0, 14, + 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 #endif /* TCL_UTF_MAX > 3 */ }; @@ -1552,16 +1569,16 @@ static const int groups[] = { 29761, 9793, 9537, 16449, 16193, 9858, 9602, 8066, 16514, 16258, 2113, 16002, 14722, 1, 12162, 13954, 2178, 22146, 20610, -1662, 29826, -15295, 24706, -1727, 20545, 7, 3905, 3970, 12353, 12418, - 8, 1859649, 9949249, 10, 1601154, 1600898, 1598594, 1598082, 1598338, - 1596546, 1582466, -9027966, -9044862, -976254, 15234, -1949375, - -1918, -1983, -18814, -21886, -25470, -32638, -28542, -32126, - -1981, -2174, -18879, -2237, 1844610, -21951, -25535, -28607, - -32703, -32191, 13, 14, -1924287, -2145983, -2115007, 7233, 7298, - 4170, 4234, 6749, 6813, -2750143, -976319, -2746047, 2763650, - 2762882, -2759615, -2751679, -2760383, -2760127, -2768575, 1859714, - -9044927, -10823615, -10830783, -10833599, -10832575, -10830015, - -10817983, -10824127, -10818751, 237633, 237698, 9949314, 18, - 17, 10305, 10370, 8769, 8834 + 8, 1859649, -769822, 9949249, 10, 1601154, 1600898, 1598594, 1598082, + 1598338, 1596546, 1582466, -9027966, -769983, -9044862, -976254, + 15234, -1949375, -1918, -1983, -18814, -21886, -25470, -32638, + -28542, -32126, -1981, -2174, -18879, -2237, 1844610, -21951, + -25535, -28607, -32703, -32191, 13, 14, -1924287, -2145983, -2115007, + 7233, 7298, 4170, 4234, 6749, 6813, -2750143, -976319, -2746047, + 2763650, 2762882, -2759615, -2751679, -2760383, -2760127, -2768575, + 1859714, -9044927, -10823615, -10830783, -10833599, -10832575, + -10830015, -10817983, -10824127, -10818751, 237633, 237698, 9949314, + 18, 17, 10305, 10370, 8769, 8834 }; #if TCL_UTF_MAX > 3 -- cgit v0.12 From 7fe9e1b90c4464f3f288cecc3fa1d65bb6904cd1 Mon Sep 17 00:00:00 2001 From: fbonnet Date: Sat, 9 Jun 2018 17:20:15 +0000 Subject: Removed thread-specific mutex lock counter and replaced by shared counter + thread ID for systems without PTHREAD_MUTEX_RECURSIVE --- unix/tclUnixThrd.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/unix/tclUnixThrd.c b/unix/tclUnixThrd.c index 3d3f81d..226552f 100644 --- a/unix/tclUnixThrd.c +++ b/unix/tclUnixThrd.c @@ -53,7 +53,8 @@ PMutexInit( typedef struct PMutex { pthread_mutex_t mutex; - pthread_key_t counter; + pthread_t thread; + int counter; } PMutex; static void @@ -62,7 +63,8 @@ PMutexInit( ) { pthread_mutex_init(&pmutexPtr->mutex, NULL); - pthread_key_create(&pmutexPtr->counter, NULL); + pmutexPtr->thread = 0; + pmutexPtr->counter = 0; } static void @@ -71,7 +73,6 @@ PMutexDestroy( ) { pthread_mutex_destroy(&pmutexPtr->mutex); - pthread_key_delete(pmutexPtr->counter); } static void @@ -79,11 +80,12 @@ PMutexLock( PMutex *pmutexPtr ) { - intptr_t count = (intptr_t)pthread_getspecific(pmutexPtr->counter); - pthread_setspecific(pmutexPtr->counter, (const void *)(count+1)); - if (count == 0) { - pthread_mutex_lock(&pmutexPtr->mutex); + if (pmutexPtr->thread != pthread_self() || pmutexPtr->counter == 0) { + pthread_mutex_lock(&pmutexPtr->mutex); + pmutexPtr->thread = pthread_self(); + pmutexPtr->counter = 0; } + pmutexPtr->counter++; } static void @@ -91,10 +93,10 @@ PMutexUnlock( PMutex *pmutexPtr ) { - intptr_t count = (intptr_t)pthread_getspecific(pmutexPtr->counter); - pthread_setspecific(pmutexPtr->counter, (const void *)(count-1)); - if (count == 1) { - pthread_mutex_unlock(&pmutexPtr->mutex); + pmutexPtr->counter--; + if (pmutexPtr->counter == 0) { + pmutexPtr->thread = 0; + pthread_mutex_unlock(&pmutexPtr->mutex); } } -- cgit v0.12 From 9c8f784329bdeba62d3712e5cb258bb291cec67f Mon Sep 17 00:00:00 2001 From: dgp Date: Tue, 12 Jun 2018 17:10:03 +0000 Subject: [860a9f1945] Remove test safe-8.8; Mac OS 9 tests are no longer useful. --- tests/safe.test | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/tests/safe.test b/tests/safe.test index 5bed5ff..00a9472 100644 --- a/tests/safe.test +++ b/tests/safe.test @@ -290,14 +290,10 @@ test safe-8.7 {safe source control on file} { [safe::setLogCmd $prevlog; unset log] \ [safe::interpDelete $i] ; } [list 1 {no such file or directory} [list "ERROR for slave a : [file join [info library] xxxxxxxxxxx.tcl]:no such file or directory"] {} {}] -test safe-8.8 {safe source forbids -rsrc} { - set i "a"; - catch {safe::interpDelete $i} - safe::interpCreate $i; - list [catch {$i eval {source -rsrc Init}} msg] \ - $msg \ - [safe::interpDelete $i] ; -} {1 {wrong # args: should be "source ?-encoding E? fileName"} {}} +test safe-8.8 {safe source forbids -rsrc} emptyTest { + # Disabled this test. It was only useful for long unsupported + # Mac OS 9 systems. [Bug 860a9f1945] +} {} test safe-8.9 {safe source and return} -setup { set returnScript [makeFile {return "ok"} return.tcl] catch {safe::interpDelete $i} -- cgit v0.12 From 1b3a0a73ae314d9cade49bd422025fb4d16c0cc9 Mon Sep 17 00:00:00 2001 From: dgp Date: Tue, 12 Jun 2018 19:16:38 +0000 Subject: Remove AbsolutePath(), no longer used. --- generic/tclZipfs.c | 82 ------------------------------------------------------ 1 file changed, 82 deletions(-) diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c index e934490..1df6694 100644 --- a/generic/tclZipfs.c +++ b/generic/tclZipfs.c @@ -760,88 +760,6 @@ CanonicalPath(const char *root, const char *tail, Tcl_DString *dsPtr,int ZIPFSPA return result; } - -/* - *------------------------------------------------------------------------- - * - * AbsolutePath -- - * - * This function computes the absolute path from a given - * (relative) path name into the specified Tcl_DString. - * - * Results: - * Returns the pointer to the absolute path contained in the - * specified Tcl_DString. - * - * Side effects: - * Modifies the specified Tcl_DString. - * - *------------------------------------------------------------------------- - */ - -static char * -AbsolutePath(const char *path, -#if HAS_DRIVES - int *drvPtr, -#endif - Tcl_DString *dsPtr) -{ - char *result; - -#if HAS_DRIVES - if (drvPtr != NULL) { - *drvPtr = 0; - } -#endif - if (*path == '~') { - Tcl_DStringAppend(dsPtr, path, -1); - return Tcl_DStringValue(dsPtr); - } - if ((*path != '/') -#if HAS_DRIVES - && (*path != '\\') && - (((*path != '\0') && (strchr(drvletters, *path) == NULL)) || - (path[1] != ':')) -#endif - ) { - Tcl_DString pwd; - - /* relative path */ - Tcl_DStringInit(&pwd); - Tcl_GetCwd(NULL, &pwd); - result = Tcl_DStringValue(&pwd); -#if HAS_DRIVES - if ((result[0] != '\0') && (strchr(drvletters, result[0]) != NULL) && - (result[1] == ':')) { - if (drvPtr != NULL) { - drvPtr[0] = result[0]; - if ((drvPtr[0] >= 'a') && (drvPtr[0] <= 'z')) { - drvPtr[0] -= 'a' - 'A'; - } - } - result += 2; - } -#endif - result = CanonicalPath(result, path, dsPtr, 0); - Tcl_DStringFree(&pwd); - } else { - /* absolute path */ -#if HAS_DRIVES - if ((path[0] != '\0') && (strchr(drvletters, path[0]) != NULL) && - (path[1] == ':')) { - if (drvPtr != NULL) { - drvPtr[0] = path[0]; - if ((drvPtr[0] >= 'a') && (drvPtr[0] <= 'z')) { - drvPtr[0] -= 'a' - 'A'; - } - } - } -#endif - result = CanonicalPath("", path, dsPtr, 0); - } - return result; -} - /* *------------------------------------------------------------------------- * -- cgit v0.12 From d62033b7e21f33603528c9712d11732f1fc756f7 Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Tue, 12 Jun 2018 19:32:03 +0000 Subject: Adding typecasts in tclZipfs.c to eliminate a compiler warning --- generic/tclZipfs.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c index 1df6694..b6c8a00 100644 --- a/generic/tclZipfs.c +++ b/generic/tclZipfs.c @@ -2381,7 +2381,7 @@ ZipFSMkZipOrImgObjCmd(ClientData clientData, Tcl_Interp *interp, Unlock(); } } else { - int k, n, m; + int k, m, n; Tcl_Channel in; const char *errMsg = "seek error"; @@ -2414,8 +2414,8 @@ cperr: k = 0; while (k < i) { m = i - k; - if (m > sizeof (buf)) { - m = sizeof (buf); + if (m > (int)sizeof (buf)) { + m = (int)sizeof (buf); } n = Tcl_Read(in, buf, m); if (n == -1) { -- cgit v0.12 From 33b84014364cffbf3c994dc7298164257512d2c4 Mon Sep 17 00:00:00 2001 From: pooryorick Date: Wed, 13 Jun 2018 10:49:25 +0000 Subject: Avoid valgrind "still reachable" reports stemming from early termination of threads. --- tests/async.test | 33 +++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/tests/async.test b/tests/async.test index fa3aae1..34c2fdc 100644 --- a/tests/async.test +++ b/tests/async.test @@ -156,19 +156,24 @@ test async-4.1 {async interrupting bytecode sequence} -constraints { } } -body { apply {{handle} { - global aresult - set aresult {Async event not delivered} - testasync marklater $handle - # allow plenty of time to pass in case valgrind is running - set start [clock seconds] - while { - [clock seconds] - $start < 180 && $aresult eq "Async event not delivered" - } { - nothing - } + global aresult + set aresult {Async event not delivered} + testasync marklater $handle + # allow plenty of time to pass in case valgrind is running + set start [clock seconds] + while { + [clock seconds] - $start < 180 && $aresult eq "Async event not delivered" + } { + # be less busy + after 100 + nothing + } return $aresult }} $hm } -result {test pattern} -cleanup { + # give other threads some time to go way so that valgrind doesn't pick up + # "still reachable" cases from early thread termination + after 100 testasync delete $hm } test async-4.2 {async interrupting straight bytecode sequence} -constraints { @@ -185,10 +190,15 @@ test async-4.2 {async interrupting straight bytecode sequence} -constraints { while { [clock seconds] - $start < 180 && $aresult eq "Async event not delivered" } { + # be less busy + after 100 } return $aresult }} $hm } -result {test pattern} -cleanup { + # give other threads some time to go way so that valgrind doesn't pick up + # "still reachable" cases from early thread termination + after 100 testasync delete $hm } test async-4.3 {async interrupting loop-less bytecode sequence} -constraints { @@ -205,6 +215,9 @@ test async-4.3 {async interrupting loop-less bytecode sequence} -constraints { return $aresult }]] $hm } -result {test pattern} -cleanup { + # give other threads some time to go way so that valgrind doesn't pick up + # "still reachable" cases from early thread termination + after 100 testasync delete $hm } -- cgit v0.12 From 83d92bd747f9da3b8e3413897e5e36cc63eb938e Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 13 Jun 2018 15:59:15 +0000 Subject: Stop creating a stray child process. --- tests/main.test | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/main.test b/tests/main.test index 324b594..302f95e 100644 --- a/tests/main.test +++ b/tests/main.test @@ -1218,8 +1218,6 @@ namespace eval ::tcl::test::main { Bug 1775878 } -constraints { exec Tcltest - } -setup { - catch {set f [open "|[list [interpreter]]" w+]} } -body { exec [interpreter] << "testsetmainloop\nputs \\\npwd\ntestexitmainloop" >& result set f [open result] -- cgit v0.12 From 15f804e04ee653eb4556a7e2265ab0c76200f483 Mon Sep 17 00:00:00 2001 From: pooryorick Date: Fri, 15 Jun 2018 13:17:17 +0000 Subject: new package tcltests exclude some exec.test tests when running under valgrind --- tests/all.tcl | 9 +++++++++ tests/exec.test | 25 +++++++++++++++---------- tests/ioCmd.test | 1 - tests/pkgIndex.tcl | 6 ++++++ 4 files changed, 30 insertions(+), 11 deletions(-) create mode 100644 tests/pkgIndex.tcl diff --git a/tests/all.tcl b/tests/all.tcl index 69a16ba..ad372db 100644 --- a/tests/all.tcl +++ b/tests/all.tcl @@ -18,5 +18,14 @@ configure {*}$argv -testdir [file dir [info script]] if {[singleProcess]} { interp debug {} -frame 1 } + +set testsdir [file dirname [file dirname [file normalize [info script]/...]]] +lappend auto_path $testsdir {*}[apply {{testsdir args} { + lmap x $args { + if {$x eq $testsdir} continue + lindex $x + } +}} $testsdir {*}$auto_path] + runAllTests proc exit args {} diff --git a/tests/exec.test b/tests/exec.test index 3d1cd56..dfc44c4 100644 --- a/tests/exec.test +++ b/tests/exec.test @@ -11,9 +11,14 @@ # See the file "license.terms" for information on usage and redistribution of # this file, and for a DISCLAIMER OF ALL WARRANTIES. +# There is no point in running Valgrind on cases where [exec] forks but then +# fails and the child process doesn't go through full cleanup. + package require tcltest 2 namespace import -force ::tcltest::* +package require tcltests + # All tests require the "exec" command. # Skip them if exec is not defined. testConstraint exec [llength [info commands exec]] @@ -325,11 +330,11 @@ test exec-8.2 {long input and output} {exec} { # Commands that return errors. -test exec-9.1 {commands returning errors} {exec} { +test exec-9.1 {commands returning errors} {exec notValgrind} { set x [catch {exec gorp456} msg] list $x [string tolower $msg] [string tolower $errorCode] } {1 {couldn't execute "gorp456": no such file or directory} {posix enoent {no such file or directory}}} -test exec-9.2 {commands returning errors} {exec} { +test exec-9.2 {commands returning errors} {exec notValgrind} { string tolower [list [catch {exec [interpreter] echo foo | foo123} msg] $msg $errorCode] } {1 {couldn't execute "foo123": no such file or directory} {posix enoent {no such file or directory}}} test exec-9.3 {commands returning errors} -constraints {exec stdio} -body { @@ -339,7 +344,7 @@ test exec-9.4 {commands returning errors} -constraints {exec stdio} -body { exec [interpreter] $path(exit) 43 | [interpreter] $path(echo) "foo bar" } -returnCodes error -result {foo bar child process exited abnormally} -test exec-9.5 {commands returning errors} -constraints {exec stdio} -body { +test exec-9.5 {commands returning errors} -constraints {exec stdio notValgrind} -body { exec gorp456 | [interpreter] echo a b c } -returnCodes error -result {couldn't execute "gorp456": no such file or directory} test exec-9.6 {commands returning errors} -constraints {exec} -body { @@ -428,13 +433,13 @@ test exec-10.19 {errors in exec invocation} -constraints {exec} -body { exec cat >@ $f } -returnCodes error -result "channel \"$f\" wasn't opened for writing" close $f -test exec-10.20 {errors in exec invocation} -constraints {exec} -body { +test exec-10.20 {errors in exec invocation} -constraints {exec notValgrind} -body { exec ~non_existent_user/foo/bar } -returnCodes error -result {user "non_existent_user" doesn't exist} -test exec-10.21 {errors in exec invocation} -constraints {exec} -body { +test exec-10.21 {errors in exec invocation} -constraints {exec notValgrind} -body { exec [interpreter] true | ~xyzzy_bad_user/x | false } -returnCodes error -result {user "xyzzy_bad_user" doesn't exist} -test exec-10.22 {errors in exec invocation} -constraints exec -body { +test exec-10.22 {errors in exec invocation} -constraints {exec notValgrind} -body { exec echo test > ~non_existent_user/foo/bar } -returnCodes error -result {user "non_existent_user" doesn't exist} # Commands in background. @@ -510,7 +515,7 @@ test exec-13.1 {setting errorCode variable} {exec} { test exec-13.2 {setting errorCode variable} {exec} { list [catch {exec [interpreter] $path(cat) > a/b/c} msg] [string tolower $errorCode] } {1 {posix enoent {no such file or directory}}} -test exec-13.3 {setting errorCode variable} {exec} { +test exec-13.3 {setting errorCode variable} {exec notValgrind} { set x [catch {exec _weird_cmd_} msg] list $x [string tolower $msg] [lindex $errorCode 0] \ [string tolower [lrange $errorCode 2 end]] @@ -548,7 +553,7 @@ test exec-14.2 {-keepnewline switch} -constraints {exec} -body { test exec-14.3 {unknown switch} -constraints {exec} -body { exec -gorp } -returnCodes error -result {bad option "-gorp": must be -ignorestderr, -keepnewline, or --} -test exec-14.4 {-- switch} -constraints {exec} -body { +test exec-14.4 {-- switch} -constraints {exec notValgrind} -body { exec -- -gorp } -returnCodes error -result {couldn't execute "-gorp": no such file or directory} test exec-14.5 {-ignorestderr switch} {exec} { @@ -662,7 +667,7 @@ test exec-18.2 {exec cat deals with weird file names} -body { # Note that this test cannot be adapted to work on Windows; that platform has # no kernel support for an analog of O_APPEND. OTOH, that means we can assume # that there is a POSIX shell... -test exec-19.1 {exec >> uses O_APPEND} -constraints {exec unix} -setup { +test exec-19.1 {exec >> uses O_APPEND} -constraints {exec unix notValgrind} -setup { set tmpfile [makeFile {0} tmpfile.exec-19.1] } -body { # Note that we have to allow for the current contents of the temporary @@ -675,7 +680,7 @@ test exec-19.1 {exec >> uses O_APPEND} -constraints {exec unix} -setup { {for a in a b c; do sleep 1; echo $a; done} >>$tmpfile & exec /bin/sh -c \ {for a in d e f; do sleep 1; echo $a >&2; done} 2>>$tmpfile & - # The above four shell invokations take about 3 seconds to finish, so allow + # The above four shell invocations take about 3 seconds to finish, so allow # 5s (in case the machine is busy) after 5000 # Check that no bytes have got lost through mixups with overlapping diff --git a/tests/ioCmd.test b/tests/ioCmd.test index cab4e97..ae58025 100644 --- a/tests/ioCmd.test +++ b/tests/ioCmd.test @@ -3781,7 +3781,6 @@ test iocmd.tf-32.0 {origin thread of moved channel gone} -match glob -body { # Use constraints to skip this test while valgrinding so this expected leak # doesn't prevent a finding of "leak-free". # -testConstraint notValgrind [expr {![testConstraint valgrind]}] test iocmd.tf-32.1 {origin thread of moved channel destroyed during access} -match glob -body { #puts <<$tcltest::mainThread>>main diff --git a/tests/pkgIndex.tcl b/tests/pkgIndex.tcl new file mode 100644 index 0000000..48ab71b --- /dev/null +++ b/tests/pkgIndex.tcl @@ -0,0 +1,6 @@ +#! /usr/bin/env tclsh + +package ifneeded tcltests 0.1 { + source [file dirname [file dirname [file normalize [info script]/...]]]/tcltests.tcl + package provide tcltests 0.1 +} -- cgit v0.12 From 06fc5fb636829f99e0f6e8c20bc1cd07338a5515 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Fri, 15 Jun 2018 18:31:24 +0000 Subject: Align common install locations in SC_PATH_TCLCONFIG and SC_PATH_TKCONFIG. Add FreeBSD (closes [d6d60efd35]) and OpenBSD 8.5 paths --- unix/tcl.m4 | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/unix/tcl.m4 b/unix/tcl.m4 index 294ecf0..99e0cbd 100644 --- a/unix/tcl.m4 +++ b/unix/tcl.m4 @@ -93,8 +93,11 @@ AC_DEFUN([SC_PATH_TCLCONFIG], [ `ls -d ${prefix}/lib 2>/dev/null` \ `ls -d /usr/local/lib 2>/dev/null` \ `ls -d /usr/contrib/lib 2>/dev/null` \ + `ls -d /usr/pkg/lib 2>/dev/null` \ `ls -d /usr/lib 2>/dev/null` \ `ls -d /usr/lib64 2>/dev/null` \ + `ls -d /usr/local/lib/tcl8.5 2>/dev/null` \ + `ls -d /usr/local/lib/tcl/tcl8.5 2>/dev/null` \ ; do if test -f "$i/tclConfig.sh" ; then ac_cv_c_tclconfig="`(cd $i; pwd)`" @@ -223,8 +226,11 @@ AC_DEFUN([SC_PATH_TKCONFIG], [ `ls -d ${prefix}/lib 2>/dev/null` \ `ls -d /usr/local/lib 2>/dev/null` \ `ls -d /usr/contrib/lib 2>/dev/null` \ + `ls -d /usr/pkg/lib 2>/dev/null` \ `ls -d /usr/lib 2>/dev/null` \ `ls -d /usr/lib64 2>/dev/null` \ + `ls -d /usr/local/lib/tk8.5 2>/dev/null` \ + `ls -d /usr/local/lib/tcl/tk8.5 2>/dev/null` \ ; do if test -f "$i/tkConfig.sh" ; then ac_cv_c_tkconfig="`(cd $i; pwd)`" -- cgit v0.12 From 41a61597547eca28506fbb85f2737413dc8f2162 Mon Sep 17 00:00:00 2001 From: pooryorick Date: Sat, 16 Jun 2018 17:55:31 +0000 Subject: new package tcltests exclude some exec.test tests when running under valgrind --- tests/all.tcl | 9 +++++++++ tests/exec.test | 25 +++++++++++++++---------- tests/ioCmd.test | 1 - tests/pkgIndex.tcl | 6 ++++++ 4 files changed, 30 insertions(+), 11 deletions(-) create mode 100644 tests/pkgIndex.tcl diff --git a/tests/all.tcl b/tests/all.tcl index 69a16ba..ad372db 100644 --- a/tests/all.tcl +++ b/tests/all.tcl @@ -18,5 +18,14 @@ configure {*}$argv -testdir [file dir [info script]] if {[singleProcess]} { interp debug {} -frame 1 } + +set testsdir [file dirname [file dirname [file normalize [info script]/...]]] +lappend auto_path $testsdir {*}[apply {{testsdir args} { + lmap x $args { + if {$x eq $testsdir} continue + lindex $x + } +}} $testsdir {*}$auto_path] + runAllTests proc exit args {} diff --git a/tests/exec.test b/tests/exec.test index 5542f3d..6570e57 100644 --- a/tests/exec.test +++ b/tests/exec.test @@ -11,9 +11,14 @@ # See the file "license.terms" for information on usage and redistribution of # this file, and for a DISCLAIMER OF ALL WARRANTIES. +# There is no point in running Valgrind on cases where [exec] forks but then +# fails and the child process doesn't go through full cleanup. + package require tcltest 2 namespace import -force ::tcltest::* +package require tcltests + # All tests require the "exec" command. # Skip them if exec is not defined. testConstraint exec [llength [info commands exec]] @@ -325,11 +330,11 @@ test exec-8.2 {long input and output} {exec} { # Commands that return errors. -test exec-9.1 {commands returning errors} {exec} { +test exec-9.1 {commands returning errors} {exec notValgrind} { set x [catch {exec gorp456} msg] list $x [string tolower $msg] [string tolower $errorCode] } {1 {couldn't execute "gorp456": no such file or directory} {posix enoent {no such file or directory}}} -test exec-9.2 {commands returning errors} {exec} { +test exec-9.2 {commands returning errors} {exec notValgrind} { string tolower [list [catch {exec [interpreter] echo foo | foo123} msg] $msg $errorCode] } {1 {couldn't execute "foo123": no such file or directory} {posix enoent {no such file or directory}}} test exec-9.3 {commands returning errors} -constraints {exec stdio} -body { @@ -339,7 +344,7 @@ test exec-9.4 {commands returning errors} -constraints {exec stdio} -body { exec [interpreter] $path(exit) 43 | [interpreter] $path(echo) "foo bar" } -returnCodes error -result {foo bar child process exited abnormally} -test exec-9.5 {commands returning errors} -constraints {exec stdio} -body { +test exec-9.5 {commands returning errors} -constraints {exec stdio notValgrind} -body { exec gorp456 | [interpreter] echo a b c } -returnCodes error -result {couldn't execute "gorp456": no such file or directory} test exec-9.6 {commands returning errors} -constraints {exec} -body { @@ -428,13 +433,13 @@ test exec-10.19 {errors in exec invocation} -constraints {exec} -body { exec cat >@ $f } -returnCodes error -result "channel \"$f\" wasn't opened for writing" close $f -test exec-10.20 {errors in exec invocation} -constraints {exec} -body { +test exec-10.20 {errors in exec invocation} -constraints {exec notValgrind} -body { exec ~non_existent_user/foo/bar } -returnCodes error -result {user "non_existent_user" doesn't exist} -test exec-10.21 {errors in exec invocation} -constraints {exec} -body { +test exec-10.21 {errors in exec invocation} -constraints {exec notValgrind} -body { exec [interpreter] true | ~xyzzy_bad_user/x | false } -returnCodes error -result {user "xyzzy_bad_user" doesn't exist} -test exec-10.22 {errors in exec invocation} -constraints exec -body { +test exec-10.22 {errors in exec invocation} -constraints {exec notValgrind} -body { exec echo test > ~non_existent_user/foo/bar } -returnCodes error -result {user "non_existent_user" doesn't exist} # Commands in background. @@ -510,7 +515,7 @@ test exec-13.1 {setting errorCode variable} {exec} { test exec-13.2 {setting errorCode variable} {exec} { list [catch {exec [interpreter] $path(cat) > a/b/c} msg] [string tolower $errorCode] } {1 {posix enoent {no such file or directory}}} -test exec-13.3 {setting errorCode variable} {exec} { +test exec-13.3 {setting errorCode variable} {exec notValgrind} { set x [catch {exec _weird_cmd_} msg] list $x [string tolower $msg] [lindex $errorCode 0] \ [string tolower [lrange $errorCode 2 end]] @@ -548,7 +553,7 @@ test exec-14.2 {-keepnewline switch} -constraints {exec} -body { test exec-14.3 {unknown switch} -constraints {exec} -body { exec -gorp } -returnCodes error -result {bad option "-gorp": must be -ignorestderr, -keepnewline, or --} -test exec-14.4 {-- switch} -constraints {exec} -body { +test exec-14.4 {-- switch} -constraints {exec notValgrind} -body { exec -- -gorp } -returnCodes error -result {couldn't execute "-gorp": no such file or directory} test exec-14.5 {-ignorestderr switch} {exec} { @@ -662,7 +667,7 @@ test exec-18.2 {exec cat deals with weird file names} -body { # Note that this test cannot be adapted to work on Windows; that platform has # no kernel support for an analog of O_APPEND. OTOH, that means we can assume # that there is a POSIX shell... -test exec-19.1 {exec >> uses O_APPEND} -constraints {exec unix} -setup { +test exec-19.1 {exec >> uses O_APPEND} -constraints {exec unix notValgrind} -setup { set tmpfile [makeFile {0} tmpfile.exec-19.1] } -body { # Note that we have to allow for the current contents of the temporary @@ -675,7 +680,7 @@ test exec-19.1 {exec >> uses O_APPEND} -constraints {exec unix} -setup { {for a in a b c; do sleep 1; echo $a; done} >>$tmpfile & exec /bin/sh -c \ {for a in d e f; do sleep 1; echo $a >&2; done} 2>>$tmpfile & - # The above four shell invokations take about 3 seconds to finish, so allow + # The above four shell invocations take about 3 seconds to finish, so allow # 5s (in case the machine is busy) after 5000 # Check that no bytes have got lost through mixups with overlapping diff --git a/tests/ioCmd.test b/tests/ioCmd.test index cab4e97..ae58025 100644 --- a/tests/ioCmd.test +++ b/tests/ioCmd.test @@ -3781,7 +3781,6 @@ test iocmd.tf-32.0 {origin thread of moved channel gone} -match glob -body { # Use constraints to skip this test while valgrinding so this expected leak # doesn't prevent a finding of "leak-free". # -testConstraint notValgrind [expr {![testConstraint valgrind]}] test iocmd.tf-32.1 {origin thread of moved channel destroyed during access} -match glob -body { #puts <<$tcltest::mainThread>>main diff --git a/tests/pkgIndex.tcl b/tests/pkgIndex.tcl new file mode 100644 index 0000000..48ab71b --- /dev/null +++ b/tests/pkgIndex.tcl @@ -0,0 +1,6 @@ +#! /usr/bin/env tclsh + +package ifneeded tcltests 0.1 { + source [file dirname [file dirname [file normalize [info script]/...]]]/tcltests.tcl + package provide tcltests 0.1 +} -- cgit v0.12 From 7bf68c2335062edb662417df9048b2c56244479f Mon Sep 17 00:00:00 2001 From: dkf Date: Sat, 16 Jun 2018 18:07:30 +0000 Subject: Add in basic github meta-files to reduce problems with issues being filed where we don't see them. --- .github/ISSUE_TEMPLATE.md | 3 +++ .github/PULL_REQUEST_TEMPLATE.md | 3 +++ 2 files changed, 6 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE.md create mode 100644 .github/PULL_REQUEST_TEMPLATE.md diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md new file mode 100644 index 0000000..22d3860 --- /dev/null +++ b/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,3 @@ +Important Note +========== +Please do not file issues with Tcl on Github. They are unlikely to be noticed in a timely fashion. Tcl issues are hosted in the [tcl fossil repository on core.tcl.tk](https://core.tcl.tk/tcl/tktnew); please post them there. diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..da07cd2 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,3 @@ +Important Note +========== +Please do not file pull requests with Tcl on Github. They are unlikely to be noticed in a timely fashion. Tcl issues (including patches) are hosted in the [tcl fossil repository on core.tcl.tk](https://core.tcl.tk/tcl/tktnew); please post them there. -- cgit v0.12 From 983854ad7b59ba90d6686bdd6f6f0fd3014a6912 Mon Sep 17 00:00:00 2001 From: pooryorick Date: Sat, 16 Jun 2018 22:56:07 +0000 Subject: Add tests/tcltests.tcl as a place to store common code for tests. --- tests/tcltests.tcl | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 tests/tcltests.tcl diff --git a/tests/tcltests.tcl b/tests/tcltests.tcl new file mode 100644 index 0000000..f7597b5 --- /dev/null +++ b/tests/tcltests.tcl @@ -0,0 +1,3 @@ +#! /usr/bin/env tclsh + +testConstraint notValgrind [expr {![testConstraint valgrind]}] -- cgit v0.12 From dd713ee96ec9cda48ba5f801193a70b6eb49d4a1 Mon Sep 17 00:00:00 2001 From: pooryorick Date: Sat, 16 Jun 2018 22:57:36 +0000 Subject: Add tests/tcltests.tcl as a place to store common code for tests. --- tests/tcltests.tcl | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 tests/tcltests.tcl diff --git a/tests/tcltests.tcl b/tests/tcltests.tcl new file mode 100644 index 0000000..f7597b5 --- /dev/null +++ b/tests/tcltests.tcl @@ -0,0 +1,3 @@ +#! /usr/bin/env tclsh + +testConstraint notValgrind [expr {![testConstraint valgrind]}] -- cgit v0.12 From 2b739c838a2b0f6dc7e64fad24eeb661d1a437ba Mon Sep 17 00:00:00 2001 From: pooryorick Date: Sun, 17 Jun 2018 08:47:29 +0000 Subject: Remove dependencies between tests in env.test. --- tests/env.test | 399 +++++++++++++++++++++++++++++++---------------------- tests/tcltests.tcl | 4 + 2 files changed, 236 insertions(+), 167 deletions(-) diff --git a/tests/env.test b/tests/env.test index 0dd4f98..2c077b1 100644 --- a/tests/env.test +++ b/tests/env.test @@ -16,49 +16,96 @@ if {[lsearch [namespace children] ::tcltest] == -1} { namespace import -force ::tcltest::* } -# Some tests require the "exec" command. -# Skip them if exec is not defined. -testConstraint exec [llength [info commands exec]] +package require tcltests + +# [exec] is required here to see the actual environment received by child +# processes. +proc getenv {} { + global printenvScript + catch {exec [interpreter] $printenvScript} out + if {$out eq "child process exited abnormally"} { + set out {} + } + return $out +} + + +proc envrestore {} { + # Restore the environment variables at the end of the test. + global env + variable env2 + + foreach name [array names env] { + unset env($name) + } + array set env $env2 + return +} + + +proc envprep {} { + # Save the current environment variables at the start of the test. + global env + variable keep + variable env2 + + set env2 [array get env] + foreach name [array names env] { + # Keep some environment variables that support operation of the tcltest + # package. + if {[string toupper $name] ni $keep} { + unset env($name) + } + } + return +} + + +proc encodingrestore {} { + variable sysenc + encoding system $sysenc + return +} + + +proc encodingswitch encoding { + variable sysenc + # Need to run [getenv] in known encoding, so save the current one here... + set sysenc [encoding system] + encoding system $encoding + return +} + + +proc setup1 {} { + global env + envprep + encodingswitch iso8859-1 +} + +proc setup2 {} { + global env + setup1 + set env(NAME1) {test string} + set env(NAME2) {new value} + set env(XYZZY) {garbage} +} + + +proc cleanup1 {} { + encodingrestore + envrestore +} -# -# These tests will run on any platform (and indeed crashed on the Mac). So put -# them before you test for the existance of exec. -# -test env-1.1 {propagation of env values to child interpreters} -setup { - catch {interp delete child} - catch {unset env(test)} -} -body { - interp create child - set env(test) garbage - child eval {set env(test)} -} -cleanup { - interp delete child - unset env(test) -} -result {garbage} -# -# This one crashed on Solaris under Tcl8.0, so we only want to make sure it -# runs. -# -test env-1.2 {lappend to env value} -setup { - catch {unset env(test)} -} -body { - set env(test) aaaaaaaaaaaaaaaa - append env(test) bbbbbbbbbbbbbb - unset env(test) +variable keep { + TCL_LIBRARY PATH LD_LIBRARY_PATH LIBPATH DISPLAY SHLIB_PATH + SYSTEMDRIVE SYSTEMROOT DYLD_LIBRARY_PATH DYLD_FRAMEWORK_PATH + DYLD_NEW_LOCAL_SHARED_REGIONS DYLD_NO_FIX_PREBINDING + SECURITYSESSIONID LANG WINDIR TERM + CONNOMPROGRAMFILES PROGRAMFILES COMMONPROGRAMW6432 PROGRAMW6432 } -test env-1.3 {reflection of env by "array names"} -setup { - catch {interp delete child} - catch {unset env(test)} -} -body { - interp create child - child eval {set env(test) garbage} - expr {"test" in [array names env]} -} -cleanup { - interp delete child - catch {unset env(test)} -} -result {1} -set printenvScript [makeFile { +variable printenvScript [makeFile [string map [list @keep@ [list $keep]] { encoding system iso8859-1 proc lrem {listname name} { upvar $listname list @@ -70,7 +117,7 @@ set printenvScript [makeFile { } proc mangle s { regsub -all {\[|\\|\]} $s {\\&} s - regsub -all "\[\u0000-\u001f\u007f-\uffff\]" $s {[manglechar &]} s + regsub -all "\[\u0000-\u001f\u007f-\uffff\]" $s {[manglechar {&}]} s return [subst -novariables $s] } proc manglechar c { @@ -84,161 +131,154 @@ set printenvScript [makeFile { lrem names ComSpec lrem names "" } - foreach name { - TCL_LIBRARY PATH LD_LIBRARY_PATH LIBPATH PURE_PROG_NAME DISPLAY - SHLIB_PATH SYSTEMDRIVE SYSTEMROOT DYLD_LIBRARY_PATH DYLD_FRAMEWORK_PATH - DYLD_NEW_LOCAL_SHARED_REGIONS DYLD_NO_FIX_PREBINDING - __CF_USER_TEXT_ENCODING SECURITYSESSIONID LANG WINDIR TERM - CommonProgramFiles ProgramFiles CommonProgramW6432 ProgramW6432 - } { + foreach name @keep@ { lrem names $name } foreach p $names { - puts "[mangle $p]=[mangle $env($p)]" + puts [mangle $p]=[mangle $env($p)] } exit -} printenv] +}] printenv] -# [exec] is required here to see the actual environment received by child -# processes. -proc getenv {} { - global printenvScript tcltest - catch {exec [interpreter] $printenvScript} out - if {$out eq "child process exited abnormally"} { - set out {} - } - return $out -} -# Save the current environment variables at the start of the test. - -set env2 [array get env] -foreach name [array names env] { - # Keep some environment variables that support operation of the tcltest - # package. - if {[string toupper $name] ni { - TCL_LIBRARY PATH LD_LIBRARY_PATH LIBPATH DISPLAY SHLIB_PATH - SYSTEMDRIVE SYSTEMROOT DYLD_LIBRARY_PATH DYLD_FRAMEWORK_PATH - DYLD_NEW_LOCAL_SHARED_REGIONS DYLD_NO_FIX_PREBINDING - SECURITYSESSIONID LANG WINDIR TERM - CONNOMPROGRAMFILES PROGRAMFILES COMMONPROGRAMW6432 PROGRAMW6432 - }} { - unset env($name) - } +test env-1.1 {propagation of env values to child interpreters} -setup { + catch {interp delete child} + catch {unset env(test)} +} -body { + interp create child + set env(test) garbage + child eval {set env(test)} +} -cleanup { + interp delete child + unset env(test) +} -result {garbage} + + +# This one crashed on Solaris under Tcl8.0, so we only want to make sure it +# runs. +test env-1.2 {lappend to env value} -setup { + catch {unset env(test)} +} -body { + set env(test) aaaaaaaaaaaaaaaa + append env(test) bbbbbbbbbbbbbb + unset env(test) } -# Need to run 'getenv' in known encoding, so save the current one here... -set sysenc [encoding system] -test env-2.1 {adding environment variables} -setup { - encoding system iso8859-1 -} -constraints {exec} -body { - getenv +test env-1.3 {reflection of env by "array names"} -setup { + catch {interp delete child} + catch {unset env(test)} +} -body { + interp create child + child eval {set env(test) garbage} + expr {"test" in [array names env]} } -cleanup { - encoding system $sysenc -} -result {} -test env-2.2 {adding environment variables} -setup { - encoding system iso8859-1 -} -constraints {exec} -body { + interp delete child + catch {unset env(test)} +} -result 1 + + +test env-2.1 { + adding environment variables +} -constraints exec -setup setup1 -body { + getenv +} -cleanup cleanup1 -result {} + + +test env-2.2 { + adding environment variables +} -constraints exec -setup setup1 -body { set env(NAME1) "test string" getenv -} -cleanup { - encoding system $sysenc -} -result {NAME1=test string} -test env-2.3 {adding environment variables} -setup { - encoding system iso8859-1 +} -cleanup cleanup1 -result {NAME1=test string} + + +test env-2.3 {adding environment variables} -constraints exec -setup { + setup1 set env(NAME1) "test string" -} -constraints {exec} -body { +} -body { set env(NAME2) "more" getenv -} -cleanup { - encoding system $sysenc -} -result {NAME1=test string +} -cleanup cleanup1 -result {NAME1=test string NAME2=more} -test env-2.4 {adding environment variables} -setup { - encoding system iso8859-1 + + +test env-2.4 { + adding environment variables +} -constraints exec -setup { + setup1 set env(NAME1) "test string" set env(NAME2) "more" -} -constraints {exec} -body { +} -body { set env(XYZZY) "garbage" getenv -} -cleanup { - encoding system $sysenc +} -cleanup { cleanup1 } -result {NAME1=test string NAME2=more XYZZY=garbage} -set env(NAME1) "test string" -set env(NAME2) "new value" -set env(XYZZY) "garbage" -test env-3.1 {changing environment variables} -setup { - encoding system iso8859-1 -} -constraints {exec} -body { + +test env-3.1 { + changing environment variables +} -constraints exec -setup setup2 -body { set result [getenv] unset env(NAME2) set result } -cleanup { - encoding system $sysenc + cleanup1 } -result {NAME1=test string NAME2=new value XYZZY=garbage} -unset -nocomplain env(NAME2) -test env-4.1 {unsetting environment variables: default} -setup { - encoding system iso8859-1 -} -constraints {exec} -body { + +test env-4.1 { + unsetting environment variables +} -constraints exec -setup setup2 -body { + unset -nocomplain env(NAME2) getenv -} -cleanup { - encoding system $sysenc -} -result {NAME1=test string +} -cleanup cleanup1 -result {NAME1=test string XYZZY=garbage} -test env-4.2 {unsetting environment variables} -setup { - encoding system iso8859-1 -} -constraints {exec} -body { - unset env(NAME1) - getenv -} -cleanup { - unset env(XYZZY) - encoding system $sysenc -} -result {XYZZY=garbage} -unset -nocomplain env(NAME1) env(XYZZY) -test env-4.3 {setting international environment variables} -setup { - encoding system iso8859-1 -} -constraints {exec} -body { + +# env-4.2 is deleted + +test env-4.3 { + setting international environment variables +} -constraints exec -setup setup1 -body { set env(\ua7) \ub6 getenv -} -cleanup { - encoding system $sysenc -} -result {\u00a7=\u00b6} -test env-4.4 {changing international environment variables} -setup { - encoding system iso8859-1 -} -constraints {exec} -body { +} -cleanup cleanup1 -result {\u00a7=\u00b6} + + +test env-4.4 { + changing international environment variables +} -constraints exec -setup setup1 -body { set env(\ua7) \ua7 getenv -} -cleanup { - encoding system $sysenc -} -result {\u00a7=\u00a7} -test env-4.5 {unsetting international environment variables} -setup { - encoding system iso8859-1 +} -cleanup cleanup1 -result {\u00a7=\u00a7} + + +test env-4.5 { + unsetting international environment variables +} -constraints exec -setup { + setup1 set env(\ua7) \ua7 } -body { set env(\ub6) \ua7 unset env(\ua7) getenv -} -constraints {exec} -cleanup { - unset env(\ub6) - encoding system $sysenc -} -result {\u00b6=\u00a7} +} -cleanup cleanup1 -result {\u00b6=\u00a7} -test env-5.0 {corner cases - set a value, it should exist} -body { +test env-5.0 { + corner cases - set a value, it should exist +} -setup setup1 -body { set env(temp) a set env(temp) -} -cleanup { - unset env(temp) -} -result {a} -test env-5.1 {corner cases - remove one elem at a time} -setup { - set x [array get env] -} -body { +} -cleanup cleanup1 -result a + + +test env-5.1 { + corner cases - remove one elem at a time +} -setup setup1 -body { # When no environment variables exist, the env var will contain no # entries. The "array names" call synchs up the C-level environ array with # the Tcl level env array. Make sure an empty Tcl array is created. @@ -246,9 +286,9 @@ test env-5.1 {corner cases - remove one elem at a time} -setup { unset env($e) } array size env -} -cleanup { - array set env $x -} -result {0} +} -cleanup cleanup1 -result 0 + + test env-5.2 {corner cases - unset the env array} -setup { interp create i } -body { @@ -262,42 +302,54 @@ test env-5.2 {corner cases - unset the env array} -setup { } -cleanup { interp delete i } -result {0} + + test env-5.3 {corner cases: unset the env in master should unset child} -setup { + setup1 interp create i } -body { # Variables deleted in a master interp should be deleted in child interp # too. - i eval { set env(THIS_SHOULD_EXIST) a} + i eval {set env(THIS_SHOULD_EXIST) a} set result [set env(THIS_SHOULD_EXIST)] unset env(THIS_SHOULD_EXIST) lappend result [i eval {catch {set env(THIS_SHOULD_EXIST)}}] } -cleanup { + cleanup1 interp delete i } -result {a 1} + + test env-5.4 {corner cases - unset the env array} -setup { + setup1 interp create i } -body { # The info exists command should be in synch with the env array. # Know Bug: 1737 - i eval { set env(THIS_SHOULD_EXIST) a} + i eval {set env(THIS_SHOULD_EXIST) a} set result [info exists env(THIS_SHOULD_EXIST)] lappend result [set env(THIS_SHOULD_EXIST)] lappend result [info exists env(THIS_SHOULD_EXIST)] } -cleanup { + cleanup1 interp delete i } -result {1 a 1} -test env-5.5 {corner cases - cannot have null entries on Windows} -constraints win -body { + + +test env-5.5 { + corner cases - cannot have null entries on Windows +} -constraints win -body { set env() a catch {set env()} -} -result 1 +} -cleanup cleanup1 -result 1 -test env-6.1 {corner cases - add lots of env variables} -body { +test env-6.1 {corner cases - add lots of env variables} -setup setup1 -body { set size [array size env] for {set i 0} {$i < 100} {incr i} { set env(BOGUS$i) $i } expr {[array size env] - $size} -} -result 100 +} -cleanup cleanup1 -result 100 test env-7.1 {[219226]: whole env array should not be unset by read} -body { set n [array size env] @@ -310,16 +362,20 @@ test env-7.1 {[219226]: whole env array should not be unset by read} -body { return $n } -result 0 -test env-7.2 {[219226]: links to env elements should not be removed by read} -body { +test env-7.2 { + [219226]: links to env elements should not be removed by read +} -setup setup1 -body { apply {{} { set ::env(test7_2) ok upvar env(test7_2) elem set ::env(PATH) return $elem }} -} -result ok +} -cleanup cleanup1 -result ok -test env-7.3 {[9b4702]: testing existence of env(some_thing) should not destroy trace} -body { +test env-7.3 { + [9b4702]: testing existence of env(some_thing) should not destroy trace +} -setup setup1 -body { apply {{} { catch {unset ::env(test7_3)} proc foo args { @@ -330,16 +386,25 @@ test env-7.3 {[9b4702]: testing existence of env(some_thing) should not destroy set ::env(not_yet_existent) "Now I'm here"; return [info exists ::env(test7_3)] }} -} -result 1 +} -cleanup cleanup1 -result 1 -# Restore the environment variables at the end of the test. +test env-8.0 { + memory usage - valgrind does not report reachable memory +} -body { + set res [set env(__DUMMY__) {i'm with dummy}] + unset env(__DUMMY__) + return $res +} -result {i'm with dummy} + -foreach name [array names env] { - unset env($name) -} -array set env $env2 # cleanup +rename getenv {} +rename envrestore {} +rename envprep {} +rename encodingrestore {} +rename encodingswitch {} + removeFile $printenvScript ::tcltest::cleanupTests return diff --git a/tests/tcltests.tcl b/tests/tcltests.tcl index f7597b5..8d42b70 100644 --- a/tests/tcltests.tcl +++ b/tests/tcltests.tcl @@ -1,3 +1,7 @@ #! /usr/bin/env tclsh +# Some tests require the "exec" command. +# Skip them if exec is not defined. +testConstraint exec [llength [info commands exec]] + testConstraint notValgrind [expr {![testConstraint valgrind]}] -- cgit v0.12 From 1f91c778bb2a0d9b3e67c7e6e55d46fa91311b4e Mon Sep 17 00:00:00 2001 From: dkf Date: Sun, 17 Jun 2018 15:42:58 +0000 Subject: Split scripted parts of TclOO into their own file. --- generic/tclOO.c | 66 +++++---------------------------------- generic/tclOOScript.h | 85 +++++++++++++++++++++++++++++++++++++++++++++++++++ unix/Makefile.in | 2 +- 3 files changed, 94 insertions(+), 59 deletions(-) create mode 100644 generic/tclOOScript.h diff --git a/generic/tclOO.c b/generic/tclOO.c index 6aa03fa..7f609b2 100644 --- a/generic/tclOO.c +++ b/generic/tclOO.c @@ -152,65 +152,10 @@ static const char *initScript = /* " tcloo.tcl OO_LIBRARY oo::library;"; */ /* - * The scripted part of the definitions of slots. + * The scripted part of the definitions of TclOO. */ -static const char *slotScript = -"::oo::define ::oo::Slot {\n" -" method Get {} {error unimplemented}\n" -" method Set list {error unimplemented}\n" -" method -set args {\n" -" uplevel 1 [list [namespace which my] Set $args]\n" -" }\n" -" method -append args {\n" -" uplevel 1 [list [namespace which my] Set [list" -" {*}[uplevel 1 [list [namespace which my] Get]] {*}$args]]\n" -" }\n" -" method -clear {} {uplevel 1 [list [namespace which my] Set {}]}\n" -" forward --default-operation my -append\n" -" method unknown {args} {\n" -" set def --default-operation\n" -" if {[llength $args] == 0} {\n" -" return [uplevel 1 [list [namespace which my] $def]]\n" -" } elseif {![string match -* [lindex $args 0]]} {\n" -" return [uplevel 1 [list [namespace which my] $def {*}$args]]\n" -" }\n" -" next {*}$args\n" -" }\n" -" export -set -append -clear\n" -" unexport unknown destroy\n" -"}\n" -"::oo::objdefine ::oo::define::superclass forward --default-operation my -set\n" -"::oo::objdefine ::oo::define::mixin forward --default-operation my -set\n" -"::oo::objdefine ::oo::objdefine::mixin forward --default-operation my -set\n"; - -/* - * The body of the method of oo::object. - */ - -static const char *clonedBody = -"foreach p [info procs [info object namespace $originObject]::*] {" -" set args [info args $p];" -" set idx -1;" -" foreach a $args {" -" lset args [incr idx] " -" [if {[info default $p $a d]} {list $a $d} {list $a}]" -" };" -" set b [info body $p];" -" set p [namespace tail $p];" -" proc $p $args $b;" -"};" -"foreach v [info vars [info object namespace $originObject]::*] {" -" upvar 0 $v vOrigin;" -" namespace upvar [namespace current] [namespace tail $v] vNew;" -" if {[info exists vOrigin]} {" -" if {[array exists vOrigin]} {" -" array set vNew [array get vOrigin];" -" } else {" -" set vNew $vOrigin;" -" }" -" }" -"}"; +#include "tclOOScript.h" /* * The actual definition of the variable holding the TclOO stub table. @@ -491,7 +436,12 @@ InitFoundation( if (TclOODefineSlots(fPtr) != TCL_OK) { return TCL_ERROR; } - return Tcl_EvalEx(interp, slotScript, -1, 0); + + /* + * Evaluate the remaining definitions, which are a compiled-in Tcl script. + */ + + return Tcl_EvalEx(interp, tclOOSetupScript, -1, 0); } /* diff --git a/generic/tclOOScript.h b/generic/tclOOScript.h new file mode 100644 index 0000000..51a8a56 --- /dev/null +++ b/generic/tclOOScript.h @@ -0,0 +1,85 @@ +/* + * tclOOScript.h -- + * + * This file contains support scripts for TclOO. They are defined here so + * that the code can be definitely run even in safe interpreters; TclOO's + * core setup is safe. + * + * Copyright (c) 2012-2018 by Donal K. Fellows + * + * See the file "license.terms" for information on usage and redistribution of + * this file, and for a DISCLAIMER OF ALL WARRANTIES. + */ + +#ifndef TCL_OO_SCRIPT_H +#define TCL_OO_SCRIPT_H + +/* + * The scripted part of the definitions of TclOO. + */ + +static const char *tclOOSetupScript = +"::oo::define ::oo::Slot {\n" +" method Get {} {return -code error unimplemented}\n" +" method Set list {return -code error unimplemented}\n" +" method -set args {tailcall my Set $args}\n" +" method -append args {\n" +" set current [uplevel 1 [list [namespace which my] Get]]\n" +" tailcall my Set [list {*}$current {*}$args]\n" +" }\n" +" method -clear {} {tailcall my Set {}}\n" +" forward --default-operation my -append\n" +" method unknown {args} {\n" +" set def --default-operation\n" +" if {[llength $args] == 0} {\n" +" tailcall my $def\n" +" } elseif {![string match -* [lindex $args 0]]} {\n" +" tailcall my $def {*}$args\n" +" }\n" +" next {*}$args\n" +" }\n" +" export -set -append -clear\n" +" unexport unknown destroy\n" +"}\n" +"\n" +"::oo::objdefine ::oo::define::superclass forward --default-operation my -set\n" +"::oo::objdefine ::oo::define::mixin forward --default-operation my -set\n" +"::oo::objdefine ::oo::objdefine::mixin forward --default-operation my -set\n"; + +/* + * The body of the method of oo::object. + */ + +static const char *clonedBody = +"foreach p [info procs [info object namespace $originObject]::*] {\n" +" set args [info args $p]\n" +" set idx -1\n" +" foreach a $args {\n" +" lset args [incr idx]" +" [if {[info default $p $a d]} {list $a $d} {list $a}]\n" +" }\n" +" set b [info body $p]\n" +" set p [namespace tail $p]\n" +" proc $p $args $b\n" +"}\n" +"foreach v [info vars [info object namespace $originObject]::*] {\n" +" upvar 0 $v vOrigin\n" +" namespace upvar [namespace current] [namespace tail $v] vNew\n" +" if {[info exists vOrigin]} {\n" +" if {[array exists vOrigin]} {\n" +" array set vNew [array get vOrigin]\n" +" } else {\n" +" set vNew $vOrigin\n" +" }\n" +" }\n" +"}\n"; + +#endif /* TCL_OO_SCRIPT_H */ + +/* + * Local Variables: + * mode: c + * c-basic-offset: 4 + * fill-column: 78 + * End: + */ diff --git a/unix/Makefile.in b/unix/Makefile.in index f044e41..9aa67fb 100644 --- a/unix/Makefile.in +++ b/unix/Makefile.in @@ -1220,7 +1220,7 @@ tclNamesp.o: $(GENERIC_DIR)/tclNamesp.c $(COMPILEHDR) tclNotify.o: $(GENERIC_DIR)/tclNotify.c $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclNotify.c -tclOO.o: $(GENERIC_DIR)/tclOO.c +tclOO.o: $(GENERIC_DIR)/tclOO.c $(GENERIC_DIR)/tclOOScript.h $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclOO.c tclOOBasic.o: $(GENERIC_DIR)/tclOOBasic.c -- cgit v0.12 From 8047a470ef35faeafe18de166f773a78097b3fc2 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Sun, 17 Jun 2018 16:07:09 +0000 Subject: Fix [53cad613d8a4de166e680f09a6c6399ebddbc17c|53cad613d8]: TIP 389 implementation makes Tk tests font-4.12 and font-4.15 fail. (Fix it in 8.6 too, for benefit of androwish) --- generic/tclParse.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/generic/tclParse.c b/generic/tclParse.c index f2cf322..fc7f77b 100644 --- a/generic/tclParse.c +++ b/generic/tclParse.c @@ -991,6 +991,14 @@ TclParseBackslash( if (readPtr != NULL) { *readPtr = count; } +#if TCL_UTF_MAX >= 4 + if ((result & 0xFC00) == 0xD800) { + dst[2] = (char) ((result | 0x80) & 0xBF); + dst[1] = (char) (((result >> 6) | 0x80) & 0xBF); + dst[0] = (char) ((result >> 12) | 0xE0); + return 3; + } +#endif return Tcl_UniCharToUtf(result, dst); } -- cgit v0.12 From 9e511d78742e4c5b32ad7d4286f2c0bd56e0083a Mon Sep 17 00:00:00 2001 From: dkf Date: Sun, 17 Jun 2018 16:47:45 +0000 Subject: Most of the implementation ported over. [classmethod] is trickier... --- generic/tclOOScript.h | 107 +++++++++++++++++++++++++++++++++++++++++++++++++- tests/oo.test | 2 +- 2 files changed, 107 insertions(+), 2 deletions(-) diff --git a/generic/tclOOScript.h b/generic/tclOOScript.h index 51a8a56..5772e2c 100644 --- a/generic/tclOOScript.h +++ b/generic/tclOOScript.h @@ -19,9 +19,90 @@ */ static const char *tclOOSetupScript = +"::proc ::oo::Helpers::callback {method args} {\n" +" list [uplevel 1 {namespace which my}] $method {*}$args\n" +"}\n" + +"::proc ::oo::Helpers::mymethod {method args} {\n" +" list [uplevel 1 {namespace which my}] $method {*}$args\n" +"}\n" + +"::proc ::oo::Helpers::classvariable {name args} {\n" +" # Get a reference to the class's namespace\n" +" set ns [info object namespace [uplevel 1 {self class}]]\n" +" # Double up the list of variable names\n" +" set vs [list $name $name]\n" +" foreach v $args {lappend vs $v $v}\n" +" # Lastly, link the caller's local variables to the class's variables\n" +" tailcall namespace upvar $ns {*}$vs\n" +"}\n" + +"::proc ::oo::Helpers::link {args} {\n" +" set ns [uplevel 1 {namespace current}]\n" +" foreach link $args {\n" +" if {[llength $link] == 2} {\n" +" lassign $link src dst\n" +" } else {\n" +" lassign $link src\n" +" set dst $src\n" +" }\n" +" interp alias {} ${ns}::$src {} ${ns}::my $dst\n" +" }\n" +" return\n" +"}\n" + +/* +"proc ::oo::define::classmethod {name {args {}} {body {}}} {\n" +" # Create the method on the class if the caller gave arguments and body\n" +" set argc [llength [info level 0]]\n" +" if {$argc == 3} {\n" +" return -code error [string cat {wrong # args: should be \"}" +" [lindex [info level 0] 0] { name ?args body?\"}]\n" +" }\n" +" # Get the name of the current class or class delegate\n" +" set cls [uplevel 1 self]\n" +" set d $cls.Delegate\n" +" if {[info object isa object $d] && [info object isa class $d]} {\n" +" set cls $d\n" +" }\n" +" if {$argc == 4} {\n" +" ::oo::define $cls method $name $args $body\n" +" }\n" +" # Make the connection by forwarding\n" +" tailcall forward $name [info object namespace $cls]::my $name\n" +"}\n" + +"# Build this *almost* like a class method, but with extra care to avoid\n" +"# nuking the existing method.\n" +"::oo::class create ::oo::class.Delegate {\n" +" method create {name args} {\n" +" if {![string match ::* $name]} {\n" +" set ns [uplevel 1 {namespace current}]\n" +" if {$ns eq {::}} {set ns {}}\n" +" set name ${ns}::${name}\n" +" }\n" +" if {[string match *.Delegate $name]} {\n" +" return [next $name {*}$args]\n" +" }\n" +" set delegate [oo::class create $name.Delegate]\n" +" set cls [next $name {*}$args]\n" +" set superdelegates [list $delegate]\n" +" foreach c [info class superclass $cls] {\n" +" set d $c.Delegate\n" +" if {[info object isa object $d] && [info object isa class $d]} {\n" +" lappend superdelegates $d\n" +" }\n" +" }\n" +" oo::objdefine $cls mixin {*}$superdelegates\n" +" return $cls\n" +" }\n" +"}\n" +*/ + "::oo::define ::oo::Slot {\n" " method Get {} {return -code error unimplemented}\n" " method Set list {return -code error unimplemented}\n" + " method -set args {tailcall my Set $args}\n" " method -append args {\n" " set current [uplevel 1 [list [namespace which my] Get]]\n" @@ -29,6 +110,7 @@ static const char *tclOOSetupScript = " }\n" " method -clear {} {tailcall my Set {}}\n" " forward --default-operation my -append\n" + " method unknown {args} {\n" " set def --default-operation\n" " if {[llength $args] == 0} {\n" @@ -38,13 +120,36 @@ static const char *tclOOSetupScript = " }\n" " next {*}$args\n" " }\n" + " export -set -append -clear\n" " unexport unknown destroy\n" "}\n" "\n" "::oo::objdefine ::oo::define::superclass forward --default-operation my -set\n" "::oo::objdefine ::oo::define::mixin forward --default-operation my -set\n" -"::oo::objdefine ::oo::objdefine::mixin forward --default-operation my -set\n"; +"::oo::objdefine ::oo::objdefine::mixin forward --default-operation my -set\n" + +/* +"::oo::define ::oo::class self mixin ::oo::class.Delegate\n" +*/ + +"::oo::class create ::oo::singleton {\n" +" superclass ::oo::class\n" +" variable object\n" +" unexport create createWithNamespace\n" +" method new args {\n" +" if {![info exists object]} {\n" +" set object [next {*}$args]\n" +" }\n" +" return $object\n" +" }\n" +"}\n" + +"::oo::class create ::oo::abstract {\n" +" superclass ::oo::class\n" +" unexport create createWithNamespace new\n" +"}\n" +; /* * The body of the method of oo::object. diff --git a/tests/oo.test b/tests/oo.test index 9a22438..25ef5e2 100644 --- a/tests/oo.test +++ b/tests/oo.test @@ -343,7 +343,7 @@ test oo-1.21 {basic test of OO functionality: default relations} -setup { }] {lsort $x} } -cleanup { interp delete $fresh -} -result {{} {::oo::Slot ::oo::class ::oo::object} {::oo::define::filter ::oo::define::mixin ::oo::define::superclass ::oo::define::variable ::oo::objdefine::filter ::oo::objdefine::mixin ::oo::objdefine::variable} {::oo::Slot ::oo::class} {} {} {} {} {} {} ::oo::object ::oo::object ::oo::class ::oo::class ::oo::class} +} -result {{} {::oo::Slot ::oo::abstract ::oo::class ::oo::object ::oo::singleton} {::oo::define::filter ::oo::define::mixin ::oo::define::superclass ::oo::define::variable ::oo::objdefine::filter ::oo::objdefine::mixin ::oo::objdefine::variable} {::oo::Slot ::oo::class} {::oo::abstract ::oo::singleton} {} {} {} {} {} ::oo::object ::oo::object ::oo::class ::oo::class ::oo::class} test oo-2.1 {basic test of OO functionality: constructor} -setup { # This is a bit complex because it needs to run in a sub-interp as -- cgit v0.12 From 8e696a5e5d19327336892388286b8d5d4fdc64a8 Mon Sep 17 00:00:00 2001 From: dkf Date: Sun, 17 Jun 2018 17:27:41 +0000 Subject: Leaving out the weird delegates stops the test failures. --- generic/tclOOScript.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/generic/tclOOScript.h b/generic/tclOOScript.h index 5772e2c..4ca286c 100644 --- a/generic/tclOOScript.h +++ b/generic/tclOOScript.h @@ -51,7 +51,6 @@ static const char *tclOOSetupScript = " return\n" "}\n" -/* "proc ::oo::define::classmethod {name {args {}} {body {}}} {\n" " # Create the method on the class if the caller gave arguments and body\n" " set argc [llength [info level 0]]\n" @@ -59,12 +58,13 @@ static const char *tclOOSetupScript = " return -code error [string cat {wrong # args: should be \"}" " [lindex [info level 0] 0] { name ?args body?\"}]\n" " }\n" -" # Get the name of the current class or class delegate\n" " set cls [uplevel 1 self]\n" +/* " set d $cls.Delegate\n" " if {[info object isa object $d] && [info object isa class $d]} {\n" " set cls $d\n" " }\n" +*/ " if {$argc == 4} {\n" " ::oo::define $cls method $name $args $body\n" " }\n" @@ -72,6 +72,7 @@ static const char *tclOOSetupScript = " tailcall forward $name [info object namespace $cls]::my $name\n" "}\n" +/* "# Build this *almost* like a class method, but with extra care to avoid\n" "# nuking the existing method.\n" "::oo::class create ::oo::class.Delegate {\n" -- cgit v0.12 From e9c0ec1219e3c42df67c414bfda0bb5aab9a5bbb Mon Sep 17 00:00:00 2001 From: pooryorick Date: Mon, 18 Jun 2018 05:59:22 +0000 Subject: Plug leak in TclSetEnv. --- generic/tclEnv.c | 4 ++++ tests/pkgIndex.tcl | 8 ++++---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/generic/tclEnv.c b/generic/tclEnv.c index 8cc4b74..c559c69 100644 --- a/generic/tclEnv.c +++ b/generic/tclEnv.c @@ -730,6 +730,10 @@ TclFinalizeEnvironment(void) ckfree(env.cache); env.cache = NULL; env.cacheSize = 0; + if ((env.ourEnviron != NULL)) { + ckfree(env.ourEnviron); + env.ourEnviron = NULL; + } #ifndef USE_PUTENV env.ourEnvironSize = 0; #endif diff --git a/tests/pkgIndex.tcl b/tests/pkgIndex.tcl index 48ab71b..0feb0eb 100644 --- a/tests/pkgIndex.tcl +++ b/tests/pkgIndex.tcl @@ -1,6 +1,6 @@ #! /usr/bin/env tclsh -package ifneeded tcltests 0.1 { - source [file dirname [file dirname [file normalize [info script]/...]]]/tcltests.tcl - package provide tcltests 0.1 -} +package ifneeded tcltests 0.1 " + source [list $dir]/tcltests.tcl + package provide tcltests 0.1 +" -- cgit v0.12 From 625aca976acac85e85a36f68a3727d2eec785922 Mon Sep 17 00:00:00 2001 From: pooryorick Date: Mon, 18 Jun 2018 07:06:04 +0000 Subject: Full cleanup of env cache when in a PURIFY build. --- generic/tclEnv.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/generic/tclEnv.c b/generic/tclEnv.c index c559c69..4a48f65 100644 --- a/generic/tclEnv.c +++ b/generic/tclEnv.c @@ -723,10 +723,18 @@ TclFinalizeEnvironment(void) * strings. This may leak more memory that strictly necessary, since some * of the strings may no longer be in the environment. However, * determining which ones are ok to delete is n-squared, and is pretty - * unlikely, so we don't bother. + * unlikely, so we don't bother. However, in the case of DPURIFY, just + * free all strings in the cache. */ + size_t i; + if (env.cache) { +#ifdef PURIFY + for (i = 0; i < env.cacheSize; i++) { + ckfree(env.cache[i]); + } +#endif ckfree(env.cache); env.cache = NULL; env.cacheSize = 0; -- cgit v0.12 From 155e8a1ad56291fb61f3578f3c7cda632556d1da Mon Sep 17 00:00:00 2001 From: pooryorick Date: Mon, 18 Jun 2018 08:09:32 +0000 Subject: Avoid valgrind "still reachable" reports stemming from early termination of threads. --- tests/async.test | 40 +++++++++++++++++++++++++++++----------- 1 file changed, 29 insertions(+), 11 deletions(-) diff --git a/tests/async.test b/tests/async.test index cb67cc2..e7fc45a 100644 --- a/tests/async.test +++ b/tests/async.test @@ -157,17 +157,24 @@ test async-4.1 {async interrupting bytecode sequence} -constraints { } } -body { apply {{handle} { - global aresult - set aresult {Async event not delivered} - testasync marklater $handle - for {set i 0} { - $i < 2500000 && $aresult eq "Async event not delivered" - } {incr i} { - nothing - } + global aresult + set aresult {Async event not delivered} + testasync marklater $handle + # allow plenty of time to pass in case valgrind is running + set start [clock seconds] + while { + [clock seconds] - $start < 180 && $aresult eq "Async event not delivered" + } { + # be less busy + after 100 + nothing + } return $aresult }} $hm } -result {test pattern} -cleanup { + # give other threads some time to go way so that valgrind doesn't pick up + # "still reachable" cases from early thread termination + after 100 testasync delete $hm } test async-4.2 {async interrupting straight bytecode sequence} -constraints { @@ -179,12 +186,20 @@ test async-4.2 {async interrupting straight bytecode sequence} -constraints { global aresult set aresult {Async event not delivered} testasync marklater $handle - for {set i 0} { - $i < 2500000 && $aresult eq "Async event not delivered" - } {incr i} {} + # allow plenty of time to pass in case valgrind is running + set start [clock seconds] + while { + [clock seconds] - $start < 180 && $aresult eq "Async event not delivered" + } { + # be less busy + after 100 + } return $aresult }} $hm } -result {test pattern} -cleanup { + # give other threads some time to go way so that valgrind doesn't pick up + # "still reachable" cases from early thread termination + after 100 testasync delete $hm } test async-4.3 {async interrupting loop-less bytecode sequence} -constraints { @@ -201,6 +216,9 @@ test async-4.3 {async interrupting loop-less bytecode sequence} -constraints { return $aresult }]] $hm } -result {test pattern} -cleanup { + # give other threads some time to go way so that valgrind doesn't pick up + # "still reachable" cases from early thread termination + after 100 testasync delete $hm } -- cgit v0.12 From 04004f3abcabe486568af1e7b026d03670b48ca8 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Mon, 18 Jun 2018 15:51:43 +0000 Subject: Unbreak build on Windows (and - most likely - some other platforms too) --- generic/tclEnv.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/generic/tclEnv.c b/generic/tclEnv.c index 4a48f65..40ced17 100644 --- a/generic/tclEnv.c +++ b/generic/tclEnv.c @@ -727,10 +727,9 @@ TclFinalizeEnvironment(void) * free all strings in the cache. */ - size_t i; - if (env.cache) { #ifdef PURIFY + int i; for (i = 0; i < env.cacheSize; i++) { ckfree(env.cache[i]); } @@ -738,11 +737,11 @@ TclFinalizeEnvironment(void) ckfree(env.cache); env.cache = NULL; env.cacheSize = 0; +#ifndef USE_PUTENV if ((env.ourEnviron != NULL)) { ckfree(env.ourEnviron); env.ourEnviron = NULL; } -#ifndef USE_PUTENV env.ourEnvironSize = 0; #endif } -- cgit v0.12 From 3c57d80efed172427e5aafa447365cb61439613c Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Mon, 18 Jun 2018 15:54:38 +0000 Subject: Fix [53cad613d8]: TIP 389 implementation makes Tk tests font-4.12 and font-4.15 fail. One more situation in which high surrogate causes problem --- generic/tclParse.c | 12 +++++------- generic/tclStringObj.c | 6 ++++++ generic/tclUtf.c | 7 +++++++ 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/generic/tclParse.c b/generic/tclParse.c index fc7f77b..f26f933 100644 --- a/generic/tclParse.c +++ b/generic/tclParse.c @@ -991,15 +991,13 @@ TclParseBackslash( if (readPtr != NULL) { *readPtr = count; } -#if TCL_UTF_MAX >= 4 - if ((result & 0xFC00) == 0xD800) { - dst[2] = (char) ((result | 0x80) & 0xBF); - dst[1] = (char) (((result >> 6) | 0x80) & 0xBF); - dst[0] = (char) ((result >> 12) | 0xE0); - return 3; + count = Tcl_UniCharToUtf(result, dst); +#if TCL_UTF_MAX > 3 + if (!count) { + count = Tcl_UniCharToUtf(-1, dst); } #endif - return Tcl_UniCharToUtf(result, dst); + return count; } /* diff --git a/generic/tclStringObj.c b/generic/tclStringObj.c index a503392..1795d0c 100644 --- a/generic/tclStringObj.c +++ b/generic/tclStringObj.c @@ -1996,6 +1996,12 @@ Tcl_AppendFormatToObj( goto error; } length = Tcl_UniCharToUtf(code, buf); +#if TCL_UTF_MAX > 3 + if (!length) { + /* Special case for handling upper surrogates. */ + length = Tcl_UniCharToUtf(-1, buf); + } +#endif segment = Tcl_NewStringObj(buf, length); Tcl_IncrRefCount(segment); allocSegment = 1; diff --git a/generic/tclUtf.c b/generic/tclUtf.c index 46ce4ef..c2963bf 100644 --- a/generic/tclUtf.c +++ b/generic/tclUtf.c @@ -189,6 +189,13 @@ Tcl_UniCharToUtf( buf[0] = (char) ((ch >> 18) | 0xF0); return 4; } + } else if (ch == -1) { + if (((buf[0] & 0xF8) == 0xF0) && ((buf[1] & 0xC0) == 0x80) + && ((buf[2] & 0xCF) == 0)) { + ch = 0xD7C0 + ((buf[0] & 0x07) << 8) + ((buf[1] & 0x3F) << 2) + + ((buf[2] & 0x30) >> 4); + goto three; + } #endif } -- cgit v0.12 From 03a3c09b1fc4fc80caec28b88b0fe09d612835b8 Mon Sep 17 00:00:00 2001 From: pooryorick Date: Tue, 19 Jun 2018 11:47:08 +0000 Subject: new file: tools/valgrind_suppress. num-callers bumped from 8 to 24. Valgrind now issues no "still reachable" reports for cmdAH.test. --- tests/all.tcl | 23 ++++++++++++++--------- tests/pkgIndex.tcl | 2 +- tools/valgrind_suppress | 33 +++++++++++++++++++++++++++++++++ unix/Makefile.in | 4 +++- 4 files changed, 51 insertions(+), 11 deletions(-) create mode 100644 tools/valgrind_suppress diff --git a/tests/all.tcl b/tests/all.tcl index ad372db..d6434fb 100644 --- a/tests/all.tcl +++ b/tests/all.tcl @@ -14,18 +14,23 @@ package prefer latest package require Tcl 8.5- package require tcltest 2.2 namespace import tcltest::* -configure {*}$argv -testdir [file dir [info script]] -if {[singleProcess]} { - interp debug {} -frame 1 -} -set testsdir [file dirname [file dirname [file normalize [info script]/...]]] -lappend auto_path $testsdir {*}[apply {{testsdir args} { - lmap x $args { +apply {args { + global auto_path + set testsdir [file dirname [file dirname [file normalize [ + info script]/...]]] + + configure {*}$args -testdir $testsdir + + if {[singleProcess]} { + interp debug {} -frame 1 + } + + set auto_path [lmap x $auto_path[set auto_path {}] { if {$x eq $testsdir} continue lindex $x - } -}} $testsdir {*}$auto_path] + }] +}} {*}$argv runAllTests proc exit args {} diff --git a/tests/pkgIndex.tcl b/tests/pkgIndex.tcl index 0feb0eb..854b943 100644 --- a/tests/pkgIndex.tcl +++ b/tests/pkgIndex.tcl @@ -1,6 +1,6 @@ #! /usr/bin/env tclsh package ifneeded tcltests 0.1 " - source [list $dir]/tcltests.tcl + source [list $dir/tcltests.tcl] package provide tcltests 0.1 " diff --git a/tools/valgrind_suppress b/tools/valgrind_suppress new file mode 100644 index 0000000..e8f0204 --- /dev/null +++ b/tools/valgrind_suppress @@ -0,0 +1,33 @@ +{ + TclpGetPwNam/getpwname_r/__nss_next2/calloc + Memcheck:Leak + match-leak-kinds: reachable + fun:calloc + ... + fun:__nss_next2 + ... + fun:TclpGetPwNam +} + +{ + TclpGetPwNam/getpwname_r/__nss_next2/malloc + Memcheck:Leak + match-leak-kinds: reachable + fun:malloc + ... + fun:__nss_next2 + ... + fun:TclpGetPwNam +} + +{ + TclpGetPwNam/getpwname_r/_nss_systemd_getpwnam_r/malloc + Memcheck:Leak + match-leak-kinds: reachable + fun:malloc + ... + fun:_nss_systemd_getpwnam_r + ... + fun:TclpGetPwNam +} + diff --git a/unix/Makefile.in b/unix/Makefile.in index 4277fad..060148f 100644 --- a/unix/Makefile.in +++ b/unix/Makefile.in @@ -262,7 +262,9 @@ GDB = gdb TRACE = strace TRACE_OPTS = VALGRIND = valgrind -VALGRINDARGS = --tool=memcheck --num-callers=8 --leak-resolution=high --leak-check=yes --show-reachable=yes -v +VALGRINDARGS = --tool=memcheck --num-callers=24 \ + --leak-resolution=high --leak-check=yes --show-reachable=yes -v \ + --suppressions=$(TOOL_DIR)/valgrind_suppress #-------------------------------------------------------------------------- # The information below should be usable as is. The configure script won't -- cgit v0.12 From 645241afc13d0aa6272925a04c3afa93ca93ef19 Mon Sep 17 00:00:00 2001 From: pooryorick Date: Wed, 20 Jun 2018 08:03:22 +0000 Subject: Remove recent auto_path modification in tests/all.tcl and suppress more valgrind reports. --- tests/all.tcl | 20 +++++--------------- tools/valgrind_suppress | 20 ++++++++++++++++++++ 2 files changed, 25 insertions(+), 15 deletions(-) diff --git a/tests/all.tcl b/tests/all.tcl index d6434fb..250163b 100644 --- a/tests/all.tcl +++ b/tests/all.tcl @@ -15,22 +15,12 @@ package require Tcl 8.5- package require tcltest 2.2 namespace import tcltest::* -apply {args { - global auto_path - set testsdir [file dirname [file dirname [file normalize [ - info script]/...]]] +configure {*}$argv -testdir [file dirname [file dirname [file normalize [ + info script]/...]]] - configure {*}$args -testdir $testsdir - - if {[singleProcess]} { - interp debug {} -frame 1 - } - - set auto_path [lmap x $auto_path[set auto_path {}] { - if {$x eq $testsdir} continue - lindex $x - }] -}} {*}$argv +if {[singleProcess]} { + interp debug {} -frame 1 +} runAllTests proc exit args {} diff --git a/tools/valgrind_suppress b/tools/valgrind_suppress index e8f0204..84ed4cd 100644 --- a/tools/valgrind_suppress +++ b/tools/valgrind_suppress @@ -31,3 +31,23 @@ fun:TclpGetPwNam } +{ + TclCreatesocketAddress/getaddrinfo/calloc + Memcheck:Leak + match-leak-kinds: reachable + fun:calloc + ... + fun:getaddrinfo + fun:TclCreateSocketAddress +} + +{ + TclCreatesocketAddress/getaddrinfo/malloc + Memcheck:Leak + match-leak-kinds: reachable + fun:malloc + ... + fun:getaddrinfo + fun:TclCreateSocketAddress +} + -- cgit v0.12 From c911dc937fb03f387cc7ecd74b04a2e60ddb53b5 Mon Sep 17 00:00:00 2001 From: pooryorick Date: Wed, 20 Jun 2018 19:06:40 +0000 Subject: Add valgrind suppression for dlopen and ensure that processes are reaped in http11.test. --- tests/http11.test | 7 +++++++ tools/valgrind_suppress | 10 ++++++++++ 2 files changed, 17 insertions(+) diff --git a/tests/http11.test b/tests/http11.test index c9ded0b..2e50837 100644 --- a/tests/http11.test +++ b/tests/http11.test @@ -666,6 +666,13 @@ test http11-4.3 "normal post request, check channel query length" -setup { # ------------------------------------------------------------------------- +# Eliminate valgrind "still reachable" reports on outstanding "Detached" +# structures in the detached list which stem from PipeClose2Proc not waiting +# around for background processes to complete, meaning that previous calls to +# Tcl_ReapDetachedProcs might not have had a chance to reap all processes. +after 10 +exec [info nameofexecutable] << {} + foreach p {create_httpd httpd_read halt_httpd meta check_crc} { if {[llength [info proc $p]]} {rename $p {}} } diff --git a/tools/valgrind_suppress b/tools/valgrind_suppress index 84ed4cd..3c733c2 100644 --- a/tools/valgrind_suppress +++ b/tools/valgrind_suppress @@ -51,3 +51,13 @@ fun:TclCreateSocketAddress } +{ + TclpDlopen/load + Memcheck:Leak + match-leak-kinds: reachable + fun:calloc + ... + fun:dlopen + fun:TclpDlopen +} + -- cgit v0.12 From 107fb1eb331d7f346dfbdf5e7655a28f4643899c Mon Sep 17 00:00:00 2001 From: pooryorick Date: Thu, 21 Jun 2018 22:16:29 +0000 Subject: Suppress more valgrind "still reachable" reports and ensure that threads are fully finalized in thread tests. --- tests/thread.test | 56 +++++++++++++++++++------------ tools/valgrind_suppress | 87 +++++++++++++++++++++++++++++++++++++++---------- 2 files changed, 106 insertions(+), 37 deletions(-) diff --git a/tests/thread.test b/tests/thread.test index cc4c871..a23670a 100644 --- a/tests/thread.test +++ b/tests/thread.test @@ -11,17 +11,22 @@ # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. + +# when thread::release is used, -wait is passed in order allow the thread to +# be fully finalized, which avoids valgrind "still reachable" reports. if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest 2.2 namespace import -force ::tcltest::* } +package require tcltests + ::tcltest::loadTestedCommands catch [list package require -exact Tcltest [info patchlevel]] # Some tests require the testthread command -testConstraint testthread [expr {[info commands testthread] != {}}] +testConstraint testthread [expr {[info commands testthread] ne {}}] # Some tests require the Thread package @@ -72,6 +77,17 @@ proc ThreadError {id info} { set threadSawError($id) true; # signal main thread to exit [vwait]. } +proc threadSuperKill id { + variable threadSuperKillScript + try { + thread::send $id $::threadSuperKillScript + } on error {tres topts} { + if {$tres ne {target thread died}} { + return -options $topts $tres + } + } +} + if {[testConstraint thread]} { thread::errorproc ThreadError } @@ -96,22 +112,22 @@ test thread-1.3 {Tcl_ThreadObjCmd: initial thread list} {thread} { test thread-1.4 {Tcl_ThreadObjCmd: thread create } {thread} { set serverthread [thread::create -preserved] set numthreads [llength [thread::names]] - thread::release $serverthread + thread::release -wait $serverthread set numthreads -} {2} +} 2 test thread-1.5 {Tcl_ThreadObjCmd: thread create one shot} {thread} { thread::create {set x 5} foreach try {0 1 2 4 5 6} { - # Try various ways to yield - update - after 10 - set l [llength [thread::names]] - if {$l == 1} { - break - } + # Try various ways to yield + update + after 10 + set l [llength [thread::names]] + if {$l == 1} { + break + } } set l -} {1} +} 1 test thread-1.6 {Tcl_ThreadObjCmd: thread exit} {thread} { thread::create {{*}{}} update @@ -121,13 +137,13 @@ test thread-1.6 {Tcl_ThreadObjCmd: thread exit} {thread} { test thread-1.13 {Tcl_ThreadObjCmd: send args} {thread} { set serverthread [thread::create -preserved] set five [thread::send $serverthread {set x 5}] - thread::release $serverthread + thread::release -wait $serverthread set five } 5 test thread-1.15 {Tcl_ThreadObjCmd: wait} {thread} { set serverthread [thread::create -preserved {set z 5 ; thread::wait}] set five [thread::send $serverthread {set z}] - thread::release $serverthread + thread::release -wait $serverthread set five } 5 @@ -159,7 +175,7 @@ test thread-3.1 {TclThreadList} {thread} { set l2 [thread::names] set c [string compare [lsort [concat [thread::id] $l1]] [lsort $l2]] foreach t $l1 { - thread::release $t + thread::release -wait $t } list $len $c } {1 0} @@ -887,7 +903,7 @@ test thread-7.24 {cancel: nested catch inside pure bytecode loop} {thread drainE # wait for other thread to signal "ready to cancel" vwait ::threadIdStarted; after 1000 set res [thread::cancel $serverthread] - thread::send $serverthread $::threadSuperKillScript + threadSuperKill $serverthread vwait ::threadSawError($serverthread) thread::join $serverthread; drainEventQueue list $res [expr {[info exists ::threadIdStarted] ? \ @@ -929,7 +945,7 @@ test thread-7.25 {cancel: nested catch inside pure inside-command loop} {thread # wait for other thread to signal "ready to cancel" vwait ::threadIdStarted; after 1000 set res [thread::cancel $serverthread] - thread::send $serverthread $::threadSuperKillScript + threadSuperKill $serverthread vwait ::threadSawError($serverthread) thread::join $serverthread; drainEventQueue list $res [expr {[info exists ::threadIdStarted] ? \ @@ -1029,7 +1045,7 @@ test thread-7.28 {cancel: send async cancel nested catch inside pure bytecode lo # wait for other thread to signal "ready to cancel" vwait ::threadIdStarted; after 1000 set res [thread::send -async $serverthread {interp cancel}] - thread::send $serverthread $::threadSuperKillScript + threadSuperKill $serverthread vwait ::threadSawError($serverthread) thread::join $serverthread; drainEventQueue list $res [expr {[info exists ::threadIdStarted] ? \ @@ -1071,7 +1087,7 @@ test thread-7.29 {cancel: send async cancel nested catch pure inside-command loo # wait for other thread to signal "ready to cancel" vwait ::threadIdStarted; after 1000 set res [thread::send -async $serverthread {interp cancel}] - thread::send $serverthread $::threadSuperKillScript + threadSuperKill $serverthread vwait ::threadSawError($serverthread) thread::join $serverthread; drainEventQueue list $res [expr {[info exists ::threadIdStarted] ? \ @@ -1111,7 +1127,7 @@ test thread-7.30 {cancel: send async thread cancel nested catch inside pure byte # wait for other thread to signal "ready to cancel" vwait ::threadIdStarted; after 1000 set res [thread::send -async $serverthread {thread::cancel [thread::id]}] - thread::send $serverthread $::threadSuperKillScript + threadSuperKill $serverthread vwait ::threadSawError($serverthread) thread::join $serverthread; drainEventQueue list $res [expr {[info exists ::threadIdStarted] ? \ @@ -1153,7 +1169,7 @@ test thread-7.31 {cancel: send async thread cancel nested catch pure inside-comm # wait for other thread to signal "ready to cancel" vwait ::threadIdStarted; after 1000 set res [thread::send -async $serverthread {thread::cancel [thread::id]}] - thread::send $serverthread $::threadSuperKillScript + threadSuperKill $serverthread vwait ::threadSawError($serverthread) thread::join $serverthread; drainEventQueue list $res [expr {[info exists ::threadIdStarted] ? \ diff --git a/tools/valgrind_suppress b/tools/valgrind_suppress index 3c733c2..ede584a 100644 --- a/tools/valgrind_suppress +++ b/tools/valgrind_suppress @@ -1,63 +1,116 @@ { - TclpGetPwNam/getpwname_r/__nss_next2/calloc + TclCreatesocketAddress/getaddrinfo/calloc + Memcheck:Leak + match-leak-kinds: reachable + fun:calloc + ... + fun:getaddrinfo + fun:TclCreateSocketAddress +} + +{ + TclCreatesocketAddress/getaddrinfo/malloc + Memcheck:Leak + match-leak-kinds: reachable + fun:malloc + ... + fun:getaddrinfo + fun:TclCreateSocketAddress +} + +{ + TclpDlopen/load + Memcheck:Leak + match-leak-kinds: reachable + fun:calloc + ... + fun:dlopen + fun:TclpDlopen +} + +{ + TclpGetGrNam/__nss_next2/calloc Memcheck:Leak match-leak-kinds: reachable fun:calloc ... fun:__nss_next2 ... - fun:TclpGetPwNam + fun:TclpGetGrNam } { - TclpGetPwNam/getpwname_r/__nss_next2/malloc + TclpGetGrNam/__nss_next2/malloc Memcheck:Leak match-leak-kinds: reachable fun:malloc ... fun:__nss_next2 ... - fun:TclpGetPwNam + fun:TclpGetGrNam } { - TclpGetPwNam/getpwname_r/_nss_systemd_getpwnam_r/malloc + TclpGetGrNam/__nss_systemd_getfrname_r/malloc Memcheck:Leak match-leak-kinds: reachable fun:malloc ... - fun:_nss_systemd_getpwnam_r + fun:_nss_systemd_getgrnam_r ... - fun:TclpGetPwNam + fun:TclpGetGrNam } { - TclCreatesocketAddress/getaddrinfo/calloc + TclpGetPwNam/getpwname_r/__nss_next2/calloc Memcheck:Leak match-leak-kinds: reachable fun:calloc ... - fun:getaddrinfo - fun:TclCreateSocketAddress + fun:__nss_next2 + ... + fun:TclpGetPwNam } { - TclCreatesocketAddress/getaddrinfo/malloc + TclpGetPwNam/getpwname_r/__nss_next2/malloc Memcheck:Leak match-leak-kinds: reachable fun:malloc ... - fun:getaddrinfo - fun:TclCreateSocketAddress + fun:__nss_next2 + ... + fun:TclpGetPwNam } { - TclpDlopen/load + TclpGetPwNam/getpwname_r/_nss_systemd_getpwnam_r/malloc Memcheck:Leak match-leak-kinds: reachable - fun:calloc + fun:malloc ... - fun:dlopen - fun:TclpDlopen + fun:_nss_systemd_getpwnam_r + ... + fun:TclpGetPwNam +} + +{ + TclpThreadExit/pthread_exit/calloc + Memcheck:Leak + match-leak-kinds: reachable + fun:calloc + ... + fun:pthread_exit + fun:TclpThreadExit +} + +{ + TclpThreadExit/pthread_exit/malloc + Memcheck:Leak + match-leak-kinds: reachable + fun:malloc + ... + fun:pthread_exit + fun:TclpThreadExit } -- cgit v0.12 From 56ca35e8a95b8cfaac73104d3699c2b901298a2d Mon Sep 17 00:00:00 2001 From: pooryorick Date: Thu, 21 Jun 2018 22:21:31 +0000 Subject: Add custom exit procedure for tcltests executable. --- generic/tclInt.h | 1 + generic/tclTest.c | 16 ++++++++++++++++ generic/tclThreadTest.c | 7 +++++++ 3 files changed, 24 insertions(+) diff --git a/generic/tclInt.h b/generic/tclInt.h index 0a3285f..6fc2e85 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -4532,6 +4532,7 @@ MODULE_SCOPE Tcl_PackageInitProc TclObjTest_Init; MODULE_SCOPE Tcl_PackageInitProc TclThread_Init; MODULE_SCOPE Tcl_PackageInitProc Procbodytest_Init; MODULE_SCOPE Tcl_PackageInitProc Procbodytest_SafeInit; +MODULE_SCOPE void *TclThreadTestFinalize(); /* *---------------------------------------------------------------- diff --git a/generic/tclTest.c b/generic/tclTest.c index 45cca5a..952f384 100644 --- a/generic/tclTest.c +++ b/generic/tclTest.c @@ -52,6 +52,7 @@ #define TCL_STORAGE_CLASS DLLEXPORT EXTERN int Tcltest_Init(Tcl_Interp *interp); EXTERN int Tcltest_SafeInit(Tcl_Interp *interp); +EXTERN TCL_NORETURN void Tcltest_Exit(ClientData clientData); /* * Dynamic string shared by TestdcallCmd and DelCallbackProc; used to collect @@ -563,6 +564,10 @@ Tcltest_Init( return TCL_ERROR; } + + /* Finalizer */ + Tcl_SetExitProc(Tcltest_Exit); + /* * Create additional commands and math functions for testing Tcl. */ @@ -790,6 +795,17 @@ Tcltest_SafeInit( return Procbodytest_SafeInit(interp); } +TCL_NORETURN void Tcltest_Exit( + ClientData clientData +) { + int status = PTR2INT(clientData); + Tcl_Finalize(); + TclThreadTestFinalize(); + TclpExit(status); + Tcl_Panic("OS exit failed!"); +} + + /* *---------------------------------------------------------------------- * diff --git a/generic/tclThreadTest.c b/generic/tclThreadTest.c index 6fc0e52..3d63964 100644 --- a/generic/tclThreadTest.c +++ b/generic/tclThreadTest.c @@ -176,6 +176,13 @@ TclThread_Init( } +void * TclThreadTestFinalize() { + if (errorProcString != NULL) { + ckfree(errorProcString); + errorProcString= NULL; + } +} + /* *---------------------------------------------------------------------- * -- cgit v0.12 From 563bd6e4ddc1fab518dc16ebd1d39d05feffa6b0 Mon Sep 17 00:00:00 2001 From: pooryorick Date: Thu, 21 Jun 2018 22:43:18 +0000 Subject: Fix function signature of TclThreadTestFinalize. --- generic/tclInt.h | 2 +- generic/tclThreadTest.c | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/generic/tclInt.h b/generic/tclInt.h index 6fc2e85..64004d8 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -4532,7 +4532,7 @@ MODULE_SCOPE Tcl_PackageInitProc TclObjTest_Init; MODULE_SCOPE Tcl_PackageInitProc TclThread_Init; MODULE_SCOPE Tcl_PackageInitProc Procbodytest_Init; MODULE_SCOPE Tcl_PackageInitProc Procbodytest_SafeInit; -MODULE_SCOPE void *TclThreadTestFinalize(); +MODULE_SCOPE void TclThreadTestFinalize(); /* *---------------------------------------------------------------- diff --git a/generic/tclThreadTest.c b/generic/tclThreadTest.c index 3d63964..92cfa13 100644 --- a/generic/tclThreadTest.c +++ b/generic/tclThreadTest.c @@ -176,11 +176,12 @@ TclThread_Init( } -void * TclThreadTestFinalize() { +void TclThreadTestFinalize() { if (errorProcString != NULL) { ckfree(errorProcString); errorProcString= NULL; } + return; } /* -- cgit v0.12 From 94ec3d943104b645666e3f71feb61ac260a43fcf Mon Sep 17 00:00:00 2001 From: pooryorick Date: Fri, 22 Jun 2018 15:10:04 +0000 Subject: Add another suppress rule for valgrind, factor test code into tests/tcltests.tcl, and constrained a some tests in the valgrind case. --- tests/all.tcl | 2 +- tests/chanio.test | 4 ---- tests/io.test | 4 ---- tests/ioCmd.test | 16 +++++++++++++--- tests/platform.test | 6 +++++- tests/tcltest.test | 7 +++++++ tests/tcltests.tcl | 12 ++++++++---- tests/thread.test | 11 ----------- tools/valgrind_suppress | 10 ++++++++++ 9 files changed, 44 insertions(+), 28 deletions(-) diff --git a/tests/all.tcl b/tests/all.tcl index 250163b..4fce323 100644 --- a/tests/all.tcl +++ b/tests/all.tcl @@ -13,7 +13,7 @@ package prefer latest package require Tcl 8.5- package require tcltest 2.2 -namespace import tcltest::* +namespace import -force ::tcltest::* configure {*}$argv -testdir [file dirname [file dirname [file normalize [ info script]/...]]] diff --git a/tests/chanio.test b/tests/chanio.test index 86c1485..492c11e 100644 --- a/tests/chanio.test +++ b/tests/chanio.test @@ -39,14 +39,10 @@ namespace eval ::tcl::test::io { catch [list package require -exact Tcltest [info patchlevel]] testConstraint testchannel [llength [info commands testchannel]] - testConstraint exec [llength [info commands exec]] testConstraint openpipe 1 - testConstraint fileevent [llength [info commands fileevent]] - testConstraint fcopy [llength [info commands fcopy]] testConstraint testfevent [llength [info commands testfevent]] testConstraint testchannelevent [llength [info commands testchannelevent]] testConstraint testmainthread [llength [info commands testmainthread]] - testConstraint thread [expr {0 == [catch {package require Thread 2.7-}]}] # You need a *very* special environment to do some tests. In particular, # many file systems do not support large-files... diff --git a/tests/io.test b/tests/io.test index cdecb7b..cc1d986 100644 --- a/tests/io.test +++ b/tests/io.test @@ -36,14 +36,10 @@ namespace eval ::tcl::test::io { variable expected testConstraint testchannel [llength [info commands testchannel]] -testConstraint exec [llength [info commands exec]] testConstraint openpipe 1 -testConstraint fileevent [llength [info commands fileevent]] -testConstraint fcopy [llength [info commands fcopy]] testConstraint testfevent [llength [info commands testfevent]] testConstraint testchannelevent [llength [info commands testchannelevent]] testConstraint testmainthread [llength [info commands testmainthread]] -testConstraint thread [expr {0 == [catch {package require Thread 2.7-}]}] testConstraint testobj [llength [info commands testobj]] # You need a *very* special environment to do some tests. In diff --git a/tests/ioCmd.test b/tests/ioCmd.test index ae58025..948671e 100644 --- a/tests/ioCmd.test +++ b/tests/ioCmd.test @@ -21,10 +21,10 @@ if {[lsearch [namespace children] ::tcltest] == -1} { ::tcltest::loadTestedCommands catch [list package require -exact Tcltest [info patchlevel]] +package require tcltests + # Custom constraints used in this file -testConstraint fcopy [llength [info commands fcopy]] testConstraint testchannel [llength [info commands testchannel]] -testConstraint thread [expr {0 == [catch {package require Thread 2.7-}]}] #---------------------------------------------------------------------- @@ -395,7 +395,7 @@ test iocmd-11.2 {I/O to command pipelines} {unixOrPc unixExecs} { test iocmd-11.3 {I/O to command pipelines} {unixOrPc unixExecs} { list [catch {open "| echo > \"$path(test5)\"" r+} msg] $msg $::errorCode } {1 {can't read output from command: standard output was redirected} {TCL OPERATION EXEC BADREDIRECT}} -test iocmd-11.4 {I/O to command pipelines} unixOrPc { +test iocmd-11.4 {I/O to command pipelines} {notValgrind unixOrPc} { list [catch {open "| no_such_command_exists" rb} msg] $msg $::errorCode } {1 {couldn't execute "no_such_command_exists": no such file or directory} {POSIX ENOENT {no such file or directory}}} @@ -3833,6 +3833,16 @@ test iocmd.tf-32.1 {origin thread of moved channel destroyed during access} -mat rename track {} # cleanup + + +# Eliminate valgrind "still reachable" reports on outstanding "Detached" +# structures in the detached list which stem from PipeClose2Proc not waiting +# around for background processes to complete, meaning that previous calls to +# Tcl_ReapDetachedProcs might not have had a chance to reap all processes. +after 10 +exec [info nameofexecutable] << {} + + foreach file [list test1 test2 test3 test4] { removeFile $file } diff --git a/tests/platform.test b/tests/platform.test index 8ee0ec7..e5a4c90 100644 --- a/tests/platform.test +++ b/tests/platform.test @@ -10,6 +10,7 @@ # of this file, and for a DISCLAIMER OF ALL WARRANTIES. package require tcltest 2 +package require tcltests namespace eval ::tcl::test::platform { namespace import ::tcltest::testConstraint @@ -67,7 +68,10 @@ test platform-3.1 {CPU ID on Windows/UNIX} \ # format of string it produces consists of two non-empty words separated by a # hyphen. package require platform -test platform-4.1 {format of platform::identify result} -match regexp -body { +test platform-4.1 {format of platform::identify result} -constraints notValgrind -match regexp -body { + # [identify] may attempt to [exec] dpkg-architecture, which may not exist, + # in which case fork will not be followed by exec, and valgrind will issue + # "still reachable" reports. platform::identify } -result {^([^-]+-)+[^-]+$} test platform-4.2 {format of platform::generic result} -match regexp -body { diff --git a/tests/tcltest.test b/tests/tcltest.test index 17fa926..0bcf342 100644 --- a/tests/tcltest.test +++ b/tests/tcltest.test @@ -908,7 +908,9 @@ removeFile load.tcl # [interpreter] test tcltest-13.1 {interpreter} { + -constraints notValgrind -setup { + #to do: Why is $::tcltest::tcltest being saved and restored here? set old $::tcltest::tcltest set ::tcltest::tcltest tcltest } @@ -920,6 +922,11 @@ test tcltest-13.1 {interpreter} { } -result {tcltest tclsh tclsh} -cleanup { + # writing ::tcltest::tcltest triggers a trace that sets up the stdio + # constraint, which involves a call to [exec] that might fail after + # "fork" and before "exec", in which case the forked process will not + # have a chance to clean itself up before exiting, which causes + # valgrind to issue numerous "still reachable" reports. set ::tcltest::tcltest $old } } diff --git a/tests/tcltests.tcl b/tests/tcltests.tcl index 8d42b70..2105279 100644 --- a/tests/tcltests.tcl +++ b/tests/tcltests.tcl @@ -1,7 +1,11 @@ #! /usr/bin/env tclsh -# Some tests require the "exec" command. -# Skip them if exec is not defined. -testConstraint exec [llength [info commands exec]] +package require tcltest 2.2 +namespace import -force ::tcltest::* -testConstraint notValgrind [expr {![testConstraint valgrind]}] +testConstraint exec [llength [info commands exec]] +testConstraint fcopy [llength [info commands fcopy]] +testConstraint fileevent [llength [info commands fileevent]] +testConstraint thread [ + expr {0 == [catch {package require Thread 2.7-}]}] +testConstraint notValgrind [expr {![testConstraint valgrind]}] diff --git a/tests/thread.test b/tests/thread.test index a23670a..eaaaa41 100644 --- a/tests/thread.test +++ b/tests/thread.test @@ -14,10 +14,6 @@ # when thread::release is used, -wait is passed in order allow the thread to # be fully finalized, which avoids valgrind "still reachable" reports. -if {[lsearch [namespace children] ::tcltest] == -1} { - package require tcltest 2.2 - namespace import -force ::tcltest::* -} package require tcltests @@ -28,13 +24,6 @@ catch [list package require -exact Tcltest [info patchlevel]] testConstraint testthread [expr {[info commands testthread] ne {}}] -# Some tests require the Thread package - -testConstraint thread [expr {0 == [catch {package require Thread 2.7-}]}] - -# Some tests may not work under valgrind - -testConstraint notValgrind [expr {![testConstraint valgrind]}] set threadSuperKillScript { rename catch "" diff --git a/tools/valgrind_suppress b/tools/valgrind_suppress index ede584a..fb7f173 100644 --- a/tools/valgrind_suppress +++ b/tools/valgrind_suppress @@ -29,6 +29,16 @@ } { + TclpDlopen/load + Memcheck:Leak + match-leak-kinds: reachable + fun:malloc + ... + fun:dlopen + fun:TclpDlopen +} + +{ TclpGetGrNam/__nss_next2/calloc Memcheck:Leak match-leak-kinds: reachable -- cgit v0.12 From 6cbfdcc4a338d5b7348ee7e65a7710d13f9bc27e Mon Sep 17 00:00:00 2001 From: pooryorick Date: Sat, 23 Jun 2018 14:18:06 +0000 Subject: Add a test for no generation of a string representation when comparing with the empty string. --- tests/expr.test | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/expr.test b/tests/expr.test index fd11870..a265ac6 100644 --- a/tests/expr.test +++ b/tests/expr.test @@ -7196,6 +7196,15 @@ test expr-51.1 {test round-to-even on input} { expr 6.9294956446009195e15 } 6929495644600920.0 +test expr-52.1 { + comparison with empty string does not generate string representation +} { + set a [list one two three] + list [expr {$a eq {}}] [expr {$a < {}}] [expr {$a > {}}] [ + string match {*no string representation*} [ + ::tcl::unsupported::representation $a]] +} {0 0 1 1} + # cleanup -- cgit v0.12 From 05209c57d377b14758bda3882b0a70b979898066 Mon Sep 17 00:00:00 2001 From: dkf Date: Sat, 23 Jun 2018 15:03:26 +0000 Subject: Make the delegates work by moving their creation into C. --- generic/tclOOBasic.c | 22 +++++++++++++++++--- generic/tclOOScript.h | 56 +++++++++++++++++---------------------------------- tests/oo.test | 45 ++++++++++++++++++++++++++++++++++++++++- 3 files changed, 81 insertions(+), 42 deletions(-) diff --git a/generic/tclOOBasic.c b/generic/tclOOBasic.c index 763f0ad..54115e0 100644 --- a/generic/tclOOBasic.c +++ b/generic/tclOOBasic.c @@ -83,7 +83,7 @@ TclOO_Class_Constructor( Tcl_Obj *const *objv) { Object *oPtr = (Object *) Tcl_ObjectContextObject(context); - Tcl_Obj **invoke; + Tcl_Obj **invoke, *nameObj; if (objc-1 > Tcl_ObjectContextSkippedArgs(context)) { Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv, @@ -94,6 +94,17 @@ TclOO_Class_Constructor( } /* + * Make the class definition delegate. This is special; it doesn't reenter + * here (and the class definition delegate doesn't run any constructors). + */ + + nameObj = Tcl_NewStringObj(oPtr->namespacePtr->fullName, -1); + Tcl_AppendToObj(nameObj, ":: oo ::delegate", -1); + Tcl_NewObjectInstance(interp, (Tcl_Class) oPtr->fPtr->classCls, + TclGetString(nameObj), NULL, -1, NULL, -1); + Tcl_DecrRefCount(nameObj); + + /* * Delegate to [oo::define] to do the work. */ @@ -128,12 +139,17 @@ DecrRefsPostClassConstructor( int result) { Tcl_Obj **invoke = data[0]; + Tcl_InterpState saved; TclDecrRefCount(invoke[0]); - TclDecrRefCount(invoke[1]); TclDecrRefCount(invoke[2]); + invoke[0] = Tcl_NewStringObj("::oo::MixinClassDelegates", -1); + Tcl_IncrRefCount(invoke[0]); + saved = Tcl_SaveInterpState(interp, result); + Tcl_EvalObjv(interp, 2, invoke, 0); + TclDecrRefCount(invoke[1]); ckfree(invoke); - return result; + return Tcl_RestoreInterpState(interp, saved); } /* diff --git a/generic/tclOOScript.h b/generic/tclOOScript.h index 4ca286c..102f2a2 100644 --- a/generic/tclOOScript.h +++ b/generic/tclOOScript.h @@ -5,7 +5,9 @@ * that the code can be definitely run even in safe interpreters; TclOO's * core setup is safe. * - * Copyright (c) 2012-2018 by Donal K. Fellows + * Copyright (c) 2012-2018 Donal K. Fellows + * Copyright (c) 2013 Andreas Kupries + * Copyright (c) 2017 Gerald Lester * * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. @@ -51,6 +53,10 @@ static const char *tclOOSetupScript = " return\n" "}\n" +"proc ::oo::DelegateName {class} {\n" +" string cat [info object namespace $class] {:: oo ::delegate}\n" +"}\n" + "proc ::oo::define::classmethod {name {args {}} {body {}}} {\n" " # Create the method on the class if the caller gave arguments and body\n" " set argc [llength [info level 0]]\n" @@ -59,46 +65,24 @@ static const char *tclOOSetupScript = " [lindex [info level 0] 0] { name ?args body?\"}]\n" " }\n" " set cls [uplevel 1 self]\n" -/* -" set d $cls.Delegate\n" -" if {[info object isa object $d] && [info object isa class $d]} {\n" -" set cls $d\n" -" }\n" -*/ " if {$argc == 4} {\n" -" ::oo::define $cls method $name $args $body\n" +" ::oo::define [::oo::DelegateName $cls] method $name $args $body\n" " }\n" " # Make the connection by forwarding\n" " tailcall forward $name [info object namespace $cls]::my $name\n" "}\n" -/* -"# Build this *almost* like a class method, but with extra care to avoid\n" -"# nuking the existing method.\n" -"::oo::class create ::oo::class.Delegate {\n" -" method create {name args} {\n" -" if {![string match ::* $name]} {\n" -" set ns [uplevel 1 {namespace current}]\n" -" if {$ns eq {::}} {set ns {}}\n" -" set name ${ns}::${name}\n" -" }\n" -" if {[string match *.Delegate $name]} {\n" -" return [next $name {*}$args]\n" -" }\n" -" set delegate [oo::class create $name.Delegate]\n" -" set cls [next $name {*}$args]\n" -" set superdelegates [list $delegate]\n" -" foreach c [info class superclass $cls] {\n" -" set d $c.Delegate\n" -" if {[info object isa object $d] && [info object isa class $d]} {\n" -" lappend superdelegates $d\n" -" }\n" -" }\n" -" oo::objdefine $cls mixin {*}$superdelegates\n" -" return $cls\n" -" }\n" +"proc ::oo::MixinClassDelegates {class} {\n" +" ::oo::objdefine $class mixin -append {*}[lmap c [info class superclass $class] {\n" +" set d [::oo::DelegateName $c]\n" +" if {![info object isa class $d]} continue; set d\n" +" }]\n" +"}\n" + +"::proc ::oo::define::initialise {body} {\n" +" set clsns [info object namespace [uplevel 1 self]]\n" +" tailcall apply [list {} $body $clsns]\n" "}\n" -*/ "::oo::define ::oo::Slot {\n" " method Get {} {return -code error unimplemented}\n" @@ -130,10 +114,6 @@ static const char *tclOOSetupScript = "::oo::objdefine ::oo::define::mixin forward --default-operation my -set\n" "::oo::objdefine ::oo::objdefine::mixin forward --default-operation my -set\n" -/* -"::oo::define ::oo::class self mixin ::oo::class.Delegate\n" -*/ - "::oo::class create ::oo::singleton {\n" " superclass ::oo::class\n" " variable object\n" diff --git a/tests/oo.test b/tests/oo.test index 25ef5e2..87f0567 100644 --- a/tests/oo.test +++ b/tests/oo.test @@ -340,7 +340,7 @@ test oo-1.21 {basic test of OO functionality: default relations} -setup { lappend x [info object class ::oo::$initial] } return $x - }] {lsort $x} + }] {lsort [lmap y $x {if {[string match *::delegate $y]} continue; set y}]} } -cleanup { interp delete $fresh } -result {{} {::oo::Slot ::oo::abstract ::oo::class ::oo::object ::oo::singleton} {::oo::define::filter ::oo::define::mixin ::oo::define::superclass ::oo::define::variable ::oo::objdefine::filter ::oo::objdefine::mixin ::oo::objdefine::variable} {::oo::Slot ::oo::class} {::oo::abstract ::oo::singleton} {} {} {} {} {} ::oo::object ::oo::object ::oo::class ::oo::class ::oo::class} @@ -4845,6 +4845,49 @@ test oo-40.3 {TIP 500: private and unexport} -setup { } -cleanup { cls destroy } -result {{} {} foo {} foo {}} + +test oo-41.1 {TIP 478: classmethod} -setup { + oo::class create parent +} -body { + oo::class create ActiveRecord { + superclass parent + classmethod find args { puts "[self] called with arguments: $args" } + } + oo::class create Table { + superclass ActiveRecord + } + Table find foo bar +} -cleanup { + parent destroy +} -output "::Table called with arguments: foo bar\n" +test oo-41.2 {TIP 478: classmethod in namespace} -setup { + namespace eval ::testns {} +} -body { + namespace eval ::testns { + oo::class create ActiveRecord { + classmethod find args { puts "[self] called with arguments: $args" } + } + oo::class create Table { + superclass ActiveRecord + } + } + testns::Table find foo bar +} -cleanup { + namespace delete ::testns +} -output "::testns::Table called with arguments: foo bar\n" +test oo-41.3 {TIP 478: classmethod must not interfere with constructor signatures} -setup { + oo::class create parent +} -body { + oo::class create TestClass { + superclass oo::class parent + self method create {name ignore body} { + next $name $body + } + } + TestClass create okay {} {} +} -cleanup { + parent destroy +} -result {::okay} cleanupTests return -- cgit v0.12 From e2a79c2604e79b36ec065a7bb44ec57eaca5ed8a Mon Sep 17 00:00:00 2001 From: pooryorick Date: Sun, 24 Jun 2018 07:17:46 +0000 Subject: Fix for [3592747]: Let TclNRTailcallEval handle namespace problems. --- generic/tclBasic.c | 8 +------- tests/tailcall.test | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/generic/tclBasic.c b/generic/tclBasic.c index 3ac3ffd..07f7e5c 100644 --- a/generic/tclBasic.c +++ b/generic/tclBasic.c @@ -8402,18 +8402,12 @@ TclNRTailcallObjCmd( if (objc > 1) { Tcl_Obj *listPtr, *nsObjPtr; Tcl_Namespace *nsPtr = (Tcl_Namespace *) iPtr->varFramePtr->nsPtr; - Tcl_Namespace *ns1Ptr; /* The tailcall data is in a Tcl list: the first element is the * namespace, the rest the command to be tailcalled. */ - listPtr = Tcl_NewListObj(objc, objv); - nsObjPtr = Tcl_NewStringObj(nsPtr->fullName, -1); - if ((TCL_OK != TclGetNamespaceFromObj(interp, nsObjPtr, &ns1Ptr)) - || (nsPtr != ns1Ptr)) { - Tcl_Panic("Tailcall failed to find the proper namespace"); - } + listPtr = Tcl_NewListObj(objc, objv); TclListObjSetElement(interp, listPtr, 0, nsObjPtr); iPtr->varFramePtr->tailcallPtr = listPtr; diff --git a/tests/tailcall.test b/tests/tailcall.test index 26f3cbf..3751c35 100644 --- a/tests/tailcall.test +++ b/tests/tailcall.test @@ -688,6 +688,26 @@ if {[testConstraint testnrelevels]} { namespace delete testnre } +test tailcall-14.1 {in a deleted namespace} -body { + namespace eval ns { + proc p args { + tailcall [namespace current] $args + } + namespace delete [namespace current] + p + } +} -returnCodes 1 -result {namespace "::ns" not found} + +test tailcall-14.1-bc {{in a deleted namespace} {byte compiled}} -body { + namespace eval ns { + proc p args { + tailcall [namespace current] {*}$args + } + namespace delete [namespace current] + p + } +} -returnCodes 1 -result {namespace "::ns" not found} + # cleanup ::tcltest::cleanupTests -- cgit v0.12 From 94f9cf81ed3e156bd372a3cac249974d1acb4e1d Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Sun, 24 Jun 2018 20:26:27 +0000 Subject: Fix "string tolower" and friends for handling unpaired surrogates correctly. Also add test-cases for those situations. Various typo's in comments. --- doc/Utf.3 | 5 ++++- generic/tclCmdMZ.c | 3 +++ generic/tclDisassemble.c | 2 +- generic/tclExecute.c | 14 ++++++++++---- generic/tclParse.c | 1 + generic/tclUtf.c | 21 +++++++++++++++------ tests/utf.test | 15 +++++++++++++++ 7 files changed, 49 insertions(+), 12 deletions(-) diff --git a/doc/Utf.3 b/doc/Utf.3 index 160575b..922fd81 100644 --- a/doc/Utf.3 +++ b/doc/Utf.3 @@ -132,7 +132,10 @@ represent one Unicode character in the UTF-8 representation. .PP \fBTcl_UniCharToUtf\fR stores the character \fIch\fR as a UTF-8 string in starting at \fIbuf\fR. The return value is the number of bytes stored -in \fIbuf\fR. +in \fIbuf\fR. If ch is an upper surrogate (range U+D800 - U+DBFF), then +the return value will be 0 and nothing will be stored. If you still +want to produce UTF-8 output for it (even though knowing it's an illegal +code-point on its own), just call \fBTcl_UniCharToUtf\fR again using ch = -1. .PP \fBTcl_UtfToUniChar\fR reads one UTF-8 character starting at \fIsrc\fR and stores it as a Tcl_UniChar in \fI*chPtr\fR. The return value is the diff --git a/generic/tclCmdMZ.c b/generic/tclCmdMZ.c index d64299e..0bd6cb4 100644 --- a/generic/tclCmdMZ.c +++ b/generic/tclCmdMZ.c @@ -1447,6 +1447,9 @@ StringIndexCmd( char buf[4]; length = Tcl_UniCharToUtf(ch, buf); + if (!length) { + length = Tcl_UniCharToUtf(-1, buf); + } Tcl_SetObjResult(interp, Tcl_NewStringObj(buf, length)); } } diff --git a/generic/tclDisassemble.c b/generic/tclDisassemble.c index e9aaec4..a0d1258 100644 --- a/generic/tclDisassemble.c +++ b/generic/tclDisassemble.c @@ -894,7 +894,7 @@ PrintSourceToObj( Tcl_AppendPrintfToObj(appendObj, "\\U%08x", ch); i += 10; } else -#elif TCL_UTF_MAX > 3 +#else /* If len == 0, this means we have a char > 0xffff, resulting in * TclUtfToUniChar producing a surrogate pair. We want to output * this pair as a single Unicode character. diff --git a/generic/tclExecute.c b/generic/tclExecute.c index fda50b2..82de752 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -4964,7 +4964,7 @@ TEBCresume( /* Decode index value operands. */ - /* + /* assert ( toIdx != TCL_INDEX_AFTER); * * Extra safety for legacy bytecodes: @@ -5223,9 +5223,15 @@ TEBCresume( * but creating the object as a string seems to be faster in * practical use. */ - - length = (ch != -1) ? Tcl_UniCharToUtf(ch, buf) : 0; - objResultPtr = Tcl_NewStringObj(buf, length); + if (ch == -1) { + objResultPtr = Tcl_NewObj(); + } else { + length = Tcl_UniCharToUtf(ch, buf); + if (!length) { + length = Tcl_UniCharToUtf(-1, buf); + } + objResultPtr = Tcl_NewStringObj(buf, length); + } } TRACE_APPEND(("\"%s\"\n", O2S(objResultPtr))); diff --git a/generic/tclParse.c b/generic/tclParse.c index 581270c..00b83a1 100644 --- a/generic/tclParse.c +++ b/generic/tclParse.c @@ -981,6 +981,7 @@ TclParseBackslash( } count = Tcl_UniCharToUtf(result, dst); if (!count) { + /* Special case for handling upper surrogates. */ count = Tcl_UniCharToUtf(-1, dst); } return count; diff --git a/generic/tclUtf.c b/generic/tclUtf.c index ed10ab2..c8292a2 100644 --- a/generic/tclUtf.c +++ b/generic/tclUtf.c @@ -218,7 +218,7 @@ Tcl_UniCharToUtfDString( { const Tcl_UniChar *w, *wEnd; char *p, *string; - int oldLength; + int oldLength, len = 1; /* * UTF-8 string length in bytes will be <= Unicode string length * 4. @@ -231,9 +231,18 @@ Tcl_UniCharToUtfDString( p = string; wEnd = uniStr + uniLength; for (w = uniStr; w < wEnd; ) { - p += Tcl_UniCharToUtf(*w, p); + if (!len && ((*w & 0xFC00) != 0xDC00)) { + /* Special case for handling upper surrogates. */ + p += Tcl_UniCharToUtf(-1, p); + } + len = Tcl_UniCharToUtf(*w, p); + p += len; w++; } + if (!len) { + /* Special case for handling upper surrogates. */ + p += Tcl_UniCharToUtf(-1, p); + } Tcl_DStringSetLength(dsPtr, oldLength + (p - string)); return string; @@ -899,7 +908,7 @@ Tcl_UtfToUpper( * char to dst if its size is <= the original char. */ - if (bytes < TclUtfCount(upChar)) { + if ((bytes < TclUtfCount(upChar)) || ((upChar & 0xF800) == 0xD800)) { memcpy(dst, src, (size_t) bytes); dst += bytes; } else { @@ -962,7 +971,7 @@ Tcl_UtfToLower( * char to dst if its size is <= the original char. */ - if (bytes < TclUtfCount(lowChar)) { + if ((bytes < TclUtfCount(lowChar)) || ((lowChar & 0xF800) == 0xD800)) { memcpy(dst, src, (size_t) bytes); dst += bytes; } else { @@ -1022,7 +1031,7 @@ Tcl_UtfToTitle( #endif titleChar = Tcl_UniCharToTitle(titleChar); - if (bytes < TclUtfCount(titleChar)) { + if ((bytes < TclUtfCount(titleChar)) || ((titleChar & 0xF800) == 0xD800)) { memcpy(dst, src, (size_t) bytes); dst += bytes; } else { @@ -1046,7 +1055,7 @@ Tcl_UtfToTitle( lowChar = Tcl_UniCharToLower(lowChar); } - if (bytes < TclUtfCount(lowChar)) { + if ((bytes < TclUtfCount(lowChar)) || ((lowChar & 0xF800) == 0xD800)) { memcpy(dst, src, (size_t) bytes); dst += bytes; } else { diff --git a/tests/utf.test b/tests/utf.test index 67a6778..e820359 100644 --- a/tests/utf.test +++ b/tests/utf.test @@ -158,6 +158,12 @@ test utf-8.3 {Tcl_UniCharAtIndex: index > 0} { test utf-8.4 {Tcl_UniCharAtIndex: index > 0} { string index \u4e4e\u25a\xff\u543 2 } "\uff" +test utf-8.5 {Tcl_UniCharAtIndex: upper surrogate} { + string index \ud842 0 +} "\ud842" +test utf-8.5 {Tcl_UniCharAtIndex: lower surrogate} { + string index \udc42 0 +} "\udc42" test utf-9.1 {Tcl_UtfAtIndex: index = 0} { string range abcd 0 2 @@ -263,6 +269,9 @@ test utf-11.4 {Tcl_UtfToUpper} { test utf-11.5 {Tcl_UtfToUpper Georgian (new in Unicode 11)} { string toupper \u10d0\u1c90 } \u1c90\u1c90 +test utf-11.6 {Tcl_UtfToUpper low/high surrogate)} { + string toupper \udc24\ud824 +} \udc24\ud824 test utf-12.1 {Tcl_UtfToLower} { string tolower {} @@ -279,6 +288,9 @@ test utf-12.4 {Tcl_UtfToLower} { test utf-12.5 {Tcl_UtfToLower Georgian (new in Unicode 11)} { string tolower \u10d0\u1c90 } \u10d0\u10d0 +test utf-12.6 {Tcl_UtfToUpper low/high surrogate)} { + string tolower \udc24\ud824 +} \udc24\ud824 test utf-13.1 {Tcl_UtfToTitle} { string totitle {} @@ -298,6 +310,9 @@ test utf-13.5 {Tcl_UtfToTitle Georgian (new in Unicode 11)} { test utf-13.6 {Tcl_UtfToTitle Georgian (new in Unicode 11)} { string totitle \u1c90\u10d0 } \u1c90\u10d0 +test utf-13.7 {Tcl_UtfToTitle low/high surrogate)} { + string totitle \udc24\ud824 +} \udc24\ud824 test utf-14.1 {Tcl_UtfNcasecmp} { string compare -nocase a b -- cgit v0.12 From 0839047d8bed631eeb82c7c3e26b0f13461717e6 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Mon, 25 Jun 2018 07:22:19 +0000 Subject: Simplify ToUtf(), expecially for TCL_UTF_MAX>3 (with correct surrogate handling). Fix various typo's --- tests/iogt.test | 2 +- unix/tclUnixSock.c | 6 +++--- unix/tclUnixThrd.c | 6 +++--- win/tclWinInit.c | 19 +++++++++++-------- win/tclWinSock.c | 16 ++++++++-------- win/tclWinThrd.c | 8 ++++---- 6 files changed, 30 insertions(+), 27 deletions(-) diff --git a/tests/iogt.test b/tests/iogt.test index 1ed89f7..269a0ba 100644 --- a/tests/iogt.test +++ b/tests/iogt.test @@ -608,7 +608,7 @@ test iogt-3.0 {Tcl_Channel valid after stack/unstack, fevent handling} -setup { variable copy 1 } } -constraints {testchannel knownBug} -body { - # This test to check the validity of aquired Tcl_Channel references is not + # This test to check the validity of acquired Tcl_Channel references is not # possible because even a backgrounded fcopy will immediately start to # copy data, without waiting for the event loop. This is done only in case # of an underflow on the read size!. So stacking transforms after the diff --git a/unix/tclUnixSock.c b/unix/tclUnixSock.c index e418ff0..90c72c0 100644 --- a/unix/tclUnixSock.c +++ b/unix/tclUnixSock.c @@ -1099,7 +1099,7 @@ TcpGetHandleProc( * TcpAsyncCallback -- * * Called by the event handler that TcpConnect sets up internally for - * [socket -async] to get notified when the asyncronous connection + * [socket -async] to get notified when the asynchronous connection * attempt has succeeded or failed. * * ---------------------------------------------------------------------- @@ -1132,7 +1132,7 @@ TcpAsyncCallback( * * Remarks: * A single host name may resolve to more than one IP address, e.g. for - * an IPv4/IPv6 dual stack host. For handling asyncronously connecting + * an IPv4/IPv6 dual stack host. For handling asynchronously connecting * sockets in the background for such hosts, this function can act as a * coroutine. On the first call, it sets up the control variables for the * two nested loops over the local and remote addresses. Once the first @@ -1140,7 +1140,7 @@ TcpAsyncCallback( * event handler for that socket, and returns. When the callback occurs, * control is transferred to the "reenter" label, right after the initial * return and the loops resume as if they had never been interrupted. - * For syncronously connecting sockets, the loops work the usual way. + * For synchronously connecting sockets, the loops work the usual way. * * ---------------------------------------------------------------------- */ diff --git a/unix/tclUnixThrd.c b/unix/tclUnixThrd.c index 0476d85..0609230 100644 --- a/unix/tclUnixThrd.c +++ b/unix/tclUnixThrd.c @@ -316,7 +316,7 @@ TclpInitUnlock(void) * in finalization; it is hidden during creation of the objects. * * This lock must be different than the initLock because the initLock is - * held during creation of syncronization objects. + * held during creation of synchronization objects. * * Results: * None. @@ -407,7 +407,7 @@ Tcl_GetAllocMutex(void) * None. * * Side effects: - * May block the current thread. The mutex is aquired when this returns. + * May block the current thread. The mutex is acquired when this returns. * Will allocate memory for a pthread_mutex_t and initialize this the * first time this Tcl_Mutex is used. * @@ -511,7 +511,7 @@ TclpFinalizeMutex( * None. * * Side effects: - * May block the current thread. The mutex is aquired when this returns. + * May block the current thread. The mutex is acquired when this returns. * Will allocate memory for a pthread_mutex_t and initialize this the * first time this Tcl_Mutex is used. * diff --git a/win/tclWinInit.c b/win/tclWinInit.c index 8e567e3..ff5327d 100644 --- a/win/tclWinInit.c +++ b/win/tclWinInit.c @@ -112,7 +112,12 @@ static ProcessGlobalValue sourceLibraryDir = {0, 0, NULL, NULL, InitializeSourceLibraryDir, NULL, NULL}; static void AppendEnvironment(Tcl_Obj *listPtr, const char *lib); -static int ToUtf(const WCHAR *wSrc, char *dst); + +#if TCL_UTF_MAX < 4 +static void ToUtf(const WCHAR *wSrc, char *dst); +#else +#define ToUtf(wSrc, dst) WideCharToMultiByte(CP_UTF8, 0, wSrc, -1, dst, MAX_PATH * TCL_UTF_MAX, NULL, NULL) +#endif /* *--------------------------------------------------------------------------- @@ -435,7 +440,7 @@ InitializeSourceLibraryDir( * * ToUtf -- * - * Convert a char string to a UTF string. + * Convert a wchar string to a UTF string. * * Results: * None. @@ -446,21 +451,19 @@ InitializeSourceLibraryDir( *--------------------------------------------------------------------------- */ -static int +#if TCL_UTF_MAX < 4 +static void ToUtf( const WCHAR *wSrc, char *dst) { - char *start; - - start = dst; while (*wSrc != '\0') { dst += Tcl_UniCharToUtf(*wSrc, dst); wSrc++; } *dst = '\0'; - return (int) (dst - start); } +#endif /* *--------------------------------------------------------------------------- @@ -660,7 +663,7 @@ TclpSetVariables( * TclpFindVariable -- * * Locate the entry in environ for a given name. On Unix this routine is - * case sensitive, on Windows this matches mioxed case. + * case sensitive, on Windows this matches mixed case. * * Results: * The return value is the index in environ of an entry with the name diff --git a/win/tclWinSock.c b/win/tclWinSock.c index da2e60a..e2479e81 100644 --- a/win/tclWinSock.c +++ b/win/tclWinSock.c @@ -686,7 +686,7 @@ WaitForConnect( } /* - * A non blocking socket waiting for an asyncronous connect + * A non blocking socket waiting for an asynchronous connect * returns directly the error EWOULDBLOCK */ @@ -1606,9 +1606,9 @@ TcpGetHandleProc( * * This might be called in 3 circumstances: * - By a regular socket command - * - By the event handler to continue an asynchroneous connect + * - By the event handler to continue an asynchronously connect * - By a blocking socket function (gets/puts) to terminate the - * connect synchroneously + * connect synchronously * * Results: * TCL_OK, if the socket was successfully connected or an asynchronous @@ -1620,7 +1620,7 @@ TcpGetHandleProc( * * Remarks: * A single host name may resolve to more than one IP address, e.g. for - * an IPv4/IPv6 dual stack host. For handling asyncronously connecting + * an IPv4/IPv6 dual stack host. For handling asynchronously connecting * sockets in the background for such hosts, this function can act as a * coroutine. On the first call, it sets up the control variables for the * two nested loops over the local and remote addresses. Once the first @@ -1628,7 +1628,7 @@ TcpGetHandleProc( * event handler for that socket, and returns. When the callback occurs, * control is transferred to the "reenter" label, right after the initial * return and the loops resume as if they had never been interrupted. - * For syncronously connecting sockets, the loops work the usual way. + * For synchronously connecting sockets, the loops work the usual way. * *---------------------------------------------------------------------- */ @@ -1718,7 +1718,7 @@ TcpConnect( continue; } /* - * For asyncroneous connect set the socket in nonblocking mode + * For asynchroneous connect set the socket in nonblocking mode * and activate connect notification */ if (async_connect) { @@ -1806,7 +1806,7 @@ TcpConnect( /* * Clear the tsd socket list pointer if we did not wait for - * the FD_CONNECT asyncroneously + * the FD_CONNECT asynchroneously */ tsdPtr->pendingTcpState = NULL; @@ -1868,7 +1868,7 @@ out: SetEvent(tsdPtr->socketListLock); } /* - * Error message on syncroneous connect + * Error message on synchroneous connect */ if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( diff --git a/win/tclWinThrd.c b/win/tclWinThrd.c index 8f3ddb9..0f83526 100644 --- a/win/tclWinThrd.c +++ b/win/tclWinThrd.c @@ -247,7 +247,7 @@ TclpThreadCreate( /* * The only purpose of this is to decrement the reference count so the - * OS resources will be reaquired when the thread closes. + * OS resources will be reacquired when the thread closes. */ CloseHandle(tHandle); @@ -405,7 +405,7 @@ TclpInitUnlock(void) * mutexes, condition variables, and thread local storage keys. * * This lock must be different than the initLock because the initLock is - * held during creation of syncronization objects. + * held during creation of synchronization objects. * * Results: * None. @@ -555,7 +555,7 @@ static void FinalizeConditionEvent(ClientData data); * None. * * Side effects: - * May block the current thread. The mutex is aquired when this returns. + * May block the current thread. The mutex is acquired when this returns. * *---------------------------------------------------------------------- */ @@ -655,7 +655,7 @@ TclpFinalizeMutex( * None. * * Side effects: - * May block the current thread. The mutex is aquired when this returns. + * May block the current thread. The mutex is acquired when this returns. * Will allocate memory for a HANDLE and initialize this the first time * this Tcl_Condition is used. * -- cgit v0.12 From ed5ed756bc5993edb110e13b90028646b413e92d Mon Sep 17 00:00:00 2001 From: dgp Date: Tue, 26 Jun 2018 14:22:08 +0000 Subject: Restore lost tests. --- tests/all.tcl | 2 +- tests/chanio.test | 11 ++++------- tests/io.test | 11 +++++------ tests/tcltests.tcl | 2 +- 4 files changed, 11 insertions(+), 15 deletions(-) diff --git a/tests/all.tcl b/tests/all.tcl index 4fce323..e14bd9c 100644 --- a/tests/all.tcl +++ b/tests/all.tcl @@ -13,7 +13,7 @@ package prefer latest package require Tcl 8.5- package require tcltest 2.2 -namespace import -force ::tcltest::* +namespace import ::tcltest::* configure {*}$argv -testdir [file dirname [file dirname [file normalize [ info script]/...]]] diff --git a/tests/chanio.test b/tests/chanio.test index 492c11e..6408f50 100644 --- a/tests/chanio.test +++ b/tests/chanio.test @@ -13,16 +13,11 @@ # See the file "license.terms" for information on usage and redistribution of # this file, and for a DISCLAIMER OF ALL WARRANTIES. +# TODO: This test is likely worthless. Confirm and remove if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest 2 - namespace import -force ::tcltest::* } -::tcltest::loadTestedCommands -catch [list package require -exact Tcltest [info patchlevel]] - -testConstraint testbytestring [llength [info commands testbytestring]] - namespace eval ::tcl::test::io { namespace import ::tcltest::* @@ -35,9 +30,11 @@ namespace eval ::tcl::test::io { variable msg variable expected - ::tcltest::loadTestedCommands + loadTestedCommands catch [list package require -exact Tcltest [info patchlevel]] + package require tcltests + testConstraint testbytestring [llength [info commands testbytestring]] testConstraint testchannel [llength [info commands testchannel]] testConstraint openpipe 1 testConstraint testfevent [llength [info commands testfevent]] diff --git a/tests/io.test b/tests/io.test index cc1d986..996e125 100644 --- a/tests/io.test +++ b/tests/io.test @@ -15,14 +15,8 @@ if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest 2 - namespace import -force ::tcltest::* } -::tcltest::loadTestedCommands -catch [list package require -exact Tcltest [info patchlevel]] - -testConstraint testbytestring [llength [info commands testbytestring]] - namespace eval ::tcl::test::io { namespace import ::tcltest::* @@ -35,6 +29,11 @@ namespace eval ::tcl::test::io { variable msg variable expected + loadTestedCommands + catch [list package require -exact Tcltest [info patchlevel]] + package require tcltests + +testConstraint testbytestring [llength [info commands testbytestring]] testConstraint testchannel [llength [info commands testchannel]] testConstraint openpipe 1 testConstraint testfevent [llength [info commands testfevent]] diff --git a/tests/tcltests.tcl b/tests/tcltests.tcl index 2105279..74d1b40 100644 --- a/tests/tcltests.tcl +++ b/tests/tcltests.tcl @@ -1,7 +1,7 @@ #! /usr/bin/env tclsh package require tcltest 2.2 -namespace import -force ::tcltest::* +namespace import ::tcltest::* testConstraint exec [llength [info commands exec]] testConstraint fcopy [llength [info commands fcopy]] -- cgit v0.12 From 9da2aebeaebd1ccbfa806b0c3550774abc7ad778 Mon Sep 17 00:00:00 2001 From: dgp Date: Tue, 26 Jun 2018 17:00:29 +0000 Subject: Use a thread exit handler, and not a custom exit proc for package cleanup. --- generic/tclInt.h | 1 - generic/tclTest.c | 16 ---------------- generic/tclThreadTest.c | 17 ++++++++--------- 3 files changed, 8 insertions(+), 26 deletions(-) diff --git a/generic/tclInt.h b/generic/tclInt.h index 64004d8..0a3285f 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -4532,7 +4532,6 @@ MODULE_SCOPE Tcl_PackageInitProc TclObjTest_Init; MODULE_SCOPE Tcl_PackageInitProc TclThread_Init; MODULE_SCOPE Tcl_PackageInitProc Procbodytest_Init; MODULE_SCOPE Tcl_PackageInitProc Procbodytest_SafeInit; -MODULE_SCOPE void TclThreadTestFinalize(); /* *---------------------------------------------------------------- diff --git a/generic/tclTest.c b/generic/tclTest.c index 952f384..45cca5a 100644 --- a/generic/tclTest.c +++ b/generic/tclTest.c @@ -52,7 +52,6 @@ #define TCL_STORAGE_CLASS DLLEXPORT EXTERN int Tcltest_Init(Tcl_Interp *interp); EXTERN int Tcltest_SafeInit(Tcl_Interp *interp); -EXTERN TCL_NORETURN void Tcltest_Exit(ClientData clientData); /* * Dynamic string shared by TestdcallCmd and DelCallbackProc; used to collect @@ -564,10 +563,6 @@ Tcltest_Init( return TCL_ERROR; } - - /* Finalizer */ - Tcl_SetExitProc(Tcltest_Exit); - /* * Create additional commands and math functions for testing Tcl. */ @@ -795,17 +790,6 @@ Tcltest_SafeInit( return Procbodytest_SafeInit(interp); } -TCL_NORETURN void Tcltest_Exit( - ClientData clientData -) { - int status = PTR2INT(clientData); - Tcl_Finalize(); - TclThreadTestFinalize(); - TclpExit(status); - Tcl_Panic("OS exit failed!"); -} - - /* *---------------------------------------------------------------------- * diff --git a/generic/tclThreadTest.c b/generic/tclThreadTest.c index 92cfa13..35b3fc3 100644 --- a/generic/tclThreadTest.c +++ b/generic/tclThreadTest.c @@ -174,15 +174,6 @@ TclThread_Init( Tcl_CreateObjCommand(interp, "testthread", ThreadObjCmd, NULL, NULL); return TCL_OK; } - - -void TclThreadTestFinalize() { - if (errorProcString != NULL) { - ckfree(errorProcString); - errorProcString= NULL; - } - return; -} /* *---------------------------------------------------------------------- @@ -1166,6 +1157,14 @@ ThreadExitProc( Tcl_MutexLock(&threadMutex); + if (self == errorThreadId) { + if (errorProcString) { /* Extra safety */ + ckfree(errorProcString); + errorProcString = NULL; + } + errorThreadId = 0; + } + if (threadEvalScript) { ckfree(threadEvalScript); threadEvalScript = NULL; -- cgit v0.12 From 7a9d97826e2df30fcf48191281dede724a99ff43 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Tue, 26 Jun 2018 19:45:22 +0000 Subject: Since Tcl is always compiled with -DUNICODE -D_UNICODE (on Windows) and we know TCL_UTF_MAX>=4, we can simplify things. No change in functionality. --- generic/tclIOSock.c | 2 +- win/tclWinConsole.c | 4 ---- win/tclWinDde.c | 31 -------------------------- win/tclWinError.c | 2 +- win/tclWinFile.c | 18 ++------------- win/tclWinInit.c | 64 ++++++++--------------------------------------------- win/tclWinPanic.c | 2 +- win/tclWinPipe.c | 2 +- win/tclWinReg.c | 7 ------ 9 files changed, 15 insertions(+), 117 deletions(-) diff --git a/generic/tclIOSock.c b/generic/tclIOSock.c index 6abfa60..12e2900 100644 --- a/generic/tclIOSock.c +++ b/generic/tclIOSock.c @@ -11,7 +11,7 @@ #include "tclInt.h" -#if defined(_WIN32) && defined(UNICODE) +#if defined(_WIN32) /* * On Windows, we need to do proper Unicode->UTF-8 conversion. */ diff --git a/win/tclWinConsole.c b/win/tclWinConsole.c index 92643cf..f8b67a3 100644 --- a/win/tclWinConsole.c +++ b/win/tclWinConsole.c @@ -1360,11 +1360,7 @@ TclWinOpenConsoleChannel( Tcl_SetChannelOption(NULL, infoPtr->channel, "-translation", "auto"); Tcl_SetChannelOption(NULL, infoPtr->channel, "-eofchar", "\032 {}"); -#ifdef UNICODE Tcl_SetChannelOption(NULL, infoPtr->channel, "-encoding", "unicode"); -#else - Tcl_SetChannelOption(NULL, infoPtr->channel, "-encoding", encoding); -#endif return infoPtr->channel; } diff --git a/win/tclWinDde.c b/win/tclWinDde.c index 381db65..52bcd42 100644 --- a/win/tclWinDde.c +++ b/win/tclWinDde.c @@ -18,15 +18,6 @@ #include #include -#ifndef UNICODE -# undef CP_WINUNICODE -# define CP_WINUNICODE CP_WINANSI -# undef Tcl_WinTCharToUtf -# define Tcl_WinTCharToUtf(a,b,c) Tcl_ExternalToUtfDString(NULL,a,b,c) -# undef Tcl_WinUtfToTChar -# define Tcl_WinUtfToTChar(a,b,c) Tcl_UtfToExternalDString(NULL,a,b,c) -#endif - #if !defined(NDEBUG) /* test POKE server Implemented for debug mode only */ # undef CBF_FAIL_POKES @@ -1432,11 +1423,7 @@ DdeObjCmd( Initialize(); if (firstArg != 1) { -#ifdef UNICODE serviceName = Tcl_GetUnicodeFromObj(objv[firstArg], &length); -#else - serviceName = Tcl_GetStringFromObj(objv[firstArg], &length); -#endif } else { length = 0; } @@ -1449,11 +1436,7 @@ DdeObjCmd( } if ((index != DDE_SERVERNAME) && (index != DDE_EVAL)) { -#ifdef UNICODE topicName = (TCHAR *) Tcl_GetUnicodeFromObj(objv[firstArg + 1], &length); -#else - topicName = Tcl_GetStringFromObj(objv[firstArg + 1], &length); -#endif if (length == 0) { topicName = NULL; } else { @@ -1467,11 +1450,7 @@ DdeObjCmd( serviceName = DdeSetServerName(interp, serviceName, flags, handlerPtr); if (serviceName != NULL) { -#ifdef UNICODE Tcl_SetObjResult(interp, Tcl_NewUnicodeObj((Tcl_UniChar *) serviceName, -1)); -#else - Tcl_SetObjResult(interp, Tcl_NewStringObj(serviceName, -1)); -#endif } else { Tcl_ResetResult(interp); } @@ -1530,13 +1509,8 @@ DdeObjCmd( break; } case DDE_REQUEST: { -#ifdef UNICODE const TCHAR *itemString = (TCHAR *) Tcl_GetUnicodeFromObj(objv[firstArg + 2], &length); -#else - const TCHAR *itemString = Tcl_GetStringFromObj(objv[firstArg + 2], - &length); -#endif if (length == 0) { Tcl_SetObjResult(interp, @@ -1590,13 +1564,8 @@ DdeObjCmd( break; } case DDE_POKE: { -#ifdef UNICODE const TCHAR *itemString = (TCHAR *) Tcl_GetUnicodeFromObj(objv[firstArg + 2], &length); -#else - const TCHAR *itemString = Tcl_GetStringFromObj(objv[firstArg + 2], - &length); -#endif BYTE *dataString; if (length == 0) { diff --git a/win/tclWinError.c b/win/tclWinError.c index 5d4423b..bce81fa 100644 --- a/win/tclWinError.c +++ b/win/tclWinError.c @@ -391,7 +391,7 @@ tclWinDebugPanic( if (IsDebuggerPresent()) { WCHAR msgString[TCL_MAX_WARN_LEN]; - char buf[TCL_MAX_WARN_LEN * TCL_UTF_MAX]; + char buf[TCL_MAX_WARN_LEN * 3]; vsnprintf(buf, sizeof(buf), format, argList); msgString[TCL_MAX_WARN_LEN-1] = L'\0'; diff --git a/win/tclWinFile.c b/win/tclWinFile.c index 0595e6c..f1e4cc9 100644 --- a/win/tclWinFile.c +++ b/win/tclWinFile.c @@ -567,7 +567,6 @@ WinReadLinkDirectory( */ offset = 0; -#ifdef UNICODE if (reparseBuffer->MountPointReparseBuffer.PathBuffer[0] == L'\\') { /* * Check whether this is a mounted volume. @@ -629,7 +628,6 @@ WinReadLinkDirectory( offset = 4; } } -#endif /* UNICODE */ Tcl_WinTCharToUtf((const TCHAR *) reparseBuffer->MountPointReparseBuffer.PathBuffer, @@ -800,7 +798,7 @@ tclWinDebugPanic( { #define TCL_MAX_WARN_LEN 1024 va_list argList; - char buf[TCL_MAX_WARN_LEN * TCL_UTF_MAX]; + char buf[TCL_MAX_WARN_LEN * 3]; WCHAR msgString[TCL_MAX_WARN_LEN]; va_start(argList, format); @@ -859,7 +857,7 @@ TclpFindExecutable( * ignore. */ { WCHAR wName[MAX_PATH]; - char name[MAX_PATH * TCL_UTF_MAX]; + char name[MAX_PATH * 3]; /* * Under Windows we ignore argv0, and return the path for the file used to @@ -871,17 +869,7 @@ TclpFindExecutable( Tcl_SetPanicProc(tclWinDebugPanic); } -#ifdef UNICODE GetModuleFileNameW(NULL, wName, MAX_PATH); -#else - GetModuleFileNameA(NULL, name, sizeof(name)); - - /* - * Convert to WCHAR to get out of ANSI codepage - */ - - MultiByteToWideChar(CP_ACP, 0, name, -1, wName, MAX_PATH); -#endif WideCharToMultiByte(CP_UTF8, 0, wName, -1, name, sizeof(name), NULL, NULL); TclWinNoBackslash(name); TclSetObjNameOfExecutable(Tcl_NewStringObj(name, -1), NULL); @@ -1646,7 +1634,6 @@ NativeAccess( * what permissions the OS has set for a file. */ -#ifdef UNICODE { SECURITY_DESCRIPTOR *sdPtr = NULL; unsigned long size; @@ -1809,7 +1796,6 @@ NativeAccess( } } -#endif /* !UNICODE */ return 0; } diff --git a/win/tclWinInit.c b/win/tclWinInit.c index f04069b..2ce19ce 100644 --- a/win/tclWinInit.c +++ b/win/tclWinInit.c @@ -107,12 +107,6 @@ static ProcessGlobalValue sourceLibraryDir = {0, 0, NULL, NULL, InitializeSourceLibraryDir, NULL, NULL}; static void AppendEnvironment(Tcl_Obj *listPtr, const char *lib); - -#if TCL_UTF_MAX < 4 -static void ToUtf(const WCHAR *wSrc, char *dst); -#else -#define ToUtf(wSrc, dst) WideCharToMultiByte(CP_UTF8, 0, wSrc, -1, dst, MAX_PATH * TCL_UTF_MAX, NULL, NULL) -#endif /* *--------------------------------------------------------------------------- @@ -262,7 +256,7 @@ AppendEnvironment( { int pathc; WCHAR wBuf[MAX_PATH]; - char buf[MAX_PATH * TCL_UTF_MAX]; + char buf[MAX_PATH * 3]; Tcl_Obj *objPtr; Tcl_DString ds; const char **pathv; @@ -291,12 +285,8 @@ AppendEnvironment( * this is a unicode string. */ - if (GetEnvironmentVariableW(L"TCL_LIBRARY", wBuf, MAX_PATH) == 0) { - buf[0] = '\0'; - GetEnvironmentVariableA("TCL_LIBRARY", buf, MAX_PATH); - } else { - ToUtf(wBuf, buf); - } + GetEnvironmentVariableW(L"TCL_LIBRARY", wBuf, MAX_PATH); + WideCharToMultiByte(CP_UTF8, 0, wBuf, -1, buf, MAX_PATH * 3, NULL, NULL); if (buf[0] != '\0') { objPtr = Tcl_NewStringObj(buf, -1); @@ -355,14 +345,11 @@ InitializeDefaultLibraryDir( { HMODULE hModule = TclWinGetTclInstance(); WCHAR wName[MAX_PATH + LIBRARY_SIZE]; - char name[(MAX_PATH + LIBRARY_SIZE) * TCL_UTF_MAX]; + char name[(MAX_PATH + LIBRARY_SIZE) * 3]; char *end, *p; - if (GetModuleFileNameW(hModule, wName, MAX_PATH) == 0) { - GetModuleFileNameA(hModule, name, MAX_PATH); - } else { - ToUtf(wName, name); - } + GetModuleFileNameW(hModule, wName, MAX_PATH); + WideCharToMultiByte(CP_UTF8, 0, wName, -1, name, MAX_PATH * 3, NULL, NULL); end = strrchr(name, '\\'); *end = '\0'; @@ -406,14 +393,11 @@ InitializeSourceLibraryDir( { HMODULE hModule = TclWinGetTclInstance(); WCHAR wName[MAX_PATH + LIBRARY_SIZE]; - char name[(MAX_PATH + LIBRARY_SIZE) * TCL_UTF_MAX]; + char name[(MAX_PATH + LIBRARY_SIZE) * 3]; char *end, *p; - if (GetModuleFileNameW(hModule, wName, MAX_PATH) == 0) { - GetModuleFileNameA(hModule, name, MAX_PATH); - } else { - ToUtf(wName, name); - } + GetModuleFileNameW(hModule, wName, MAX_PATH); + WideCharToMultiByte(CP_UTF8, 0, wName, -1, name, MAX_PATH * 3, NULL, NULL); end = strrchr(name, '\\'); *end = '\0'; @@ -434,36 +418,6 @@ InitializeSourceLibraryDir( /* *--------------------------------------------------------------------------- * - * ToUtf -- - * - * Convert a wchar string to a UTF string. - * - * Results: - * None. - * - * Side effects: - * None. - * - *--------------------------------------------------------------------------- - */ - -#if TCL_UTF_MAX < 4 -static void -ToUtf( - const WCHAR *wSrc, - char *dst) -{ - while (*wSrc != '\0') { - dst += Tcl_UniCharToUtf(*wSrc, dst); - wSrc++; - } - *dst = '\0'; -} -#endif - -/* - *--------------------------------------------------------------------------- - * * TclpSetInitialEncodings -- * * Based on the locale, determine the encoding of the operating system diff --git a/win/tclWinPanic.c b/win/tclWinPanic.c index d23ffcd..a71f506 100644 --- a/win/tclWinPanic.c +++ b/win/tclWinPanic.c @@ -35,7 +35,7 @@ Tcl_ConsolePanic( #define TCL_MAX_WARN_LEN 26000 va_list argList; WCHAR msgString[TCL_MAX_WARN_LEN]; - char buf[TCL_MAX_WARN_LEN * TCL_UTF_MAX]; + char buf[TCL_MAX_WARN_LEN * 3]; HANDLE handle = GetStdHandle(STD_ERROR_HANDLE); DWORD dummy; diff --git a/win/tclWinPipe.c b/win/tclWinPipe.c index a357412..2155a8d 100644 --- a/win/tclWinPipe.c +++ b/win/tclWinPipe.c @@ -941,7 +941,7 @@ TclpCreateProcess( PROCESS_INFORMATION procInfo; SECURITY_ATTRIBUTES secAtts; HANDLE hProcess, h, inputHandle, outputHandle, errorHandle; - char execPath[MAX_PATH * TCL_UTF_MAX]; + char execPath[MAX_PATH * 3]; WinFile *filePtr; PipeInit(); diff --git a/win/tclWinReg.c b/win/tclWinReg.c index de48b9b..95ab499 100644 --- a/win/tclWinReg.c +++ b/win/tclWinReg.c @@ -22,13 +22,6 @@ #endif #include -#ifndef UNICODE -# undef Tcl_WinTCharToUtf -# define Tcl_WinTCharToUtf(a,b,c) Tcl_ExternalToUtfDString(NULL,a,b,c) -# undef Tcl_WinUtfToTChar -# define Tcl_WinUtfToTChar(a,b,c) Tcl_UtfToExternalDString(NULL,a,b,c) -#endif /* !UNICODE */ - /* * Ensure that we can say which registry is being accessed. */ -- cgit v0.12 From 082e8c6d7aa61e4250a321d2d44ca57c8d09049d Mon Sep 17 00:00:00 2001 From: dkf Date: Wed, 27 Jun 2018 07:39:49 +0000 Subject: Add better error handling and make the delegation work with cloning. --- generic/tclOOBasic.c | 14 ++++- generic/tclOOScript.h | 35 +++++++++++-- tests/oo.test | 139 ++++++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 178 insertions(+), 10 deletions(-) diff --git a/generic/tclOOBasic.c b/generic/tclOOBasic.c index 54115e0..13c98f4 100644 --- a/generic/tclOOBasic.c +++ b/generic/tclOOBasic.c @@ -122,7 +122,7 @@ TclOO_Class_Constructor( Tcl_IncrRefCount(invoke[1]); Tcl_IncrRefCount(invoke[2]); TclNRAddCallback(interp, DecrRefsPostClassConstructor, - invoke, NULL, NULL, NULL); + invoke, oPtr, NULL, NULL); /* * Tricky point: do not want the extra reported level in the Tcl stack @@ -139,16 +139,26 @@ DecrRefsPostClassConstructor( int result) { Tcl_Obj **invoke = data[0]; + Object *oPtr = data[1]; Tcl_InterpState saved; + int code; TclDecrRefCount(invoke[0]); + TclDecrRefCount(invoke[1]); TclDecrRefCount(invoke[2]); invoke[0] = Tcl_NewStringObj("::oo::MixinClassDelegates", -1); + invoke[1] = TclOOObjectName(interp, oPtr); Tcl_IncrRefCount(invoke[0]); + Tcl_IncrRefCount(invoke[1]); saved = Tcl_SaveInterpState(interp, result); - Tcl_EvalObjv(interp, 2, invoke, 0); + code = Tcl_EvalObjv(interp, 2, invoke, 0); + TclDecrRefCount(invoke[0]); TclDecrRefCount(invoke[1]); ckfree(invoke); + if (code != TCL_OK) { + Tcl_DiscardInterpState(saved); + return code; + } return Tcl_RestoreInterpState(interp, saved); } diff --git a/generic/tclOOScript.h b/generic/tclOOScript.h index 102f2a2..73c3383 100644 --- a/generic/tclOOScript.h +++ b/generic/tclOOScript.h @@ -73,10 +73,21 @@ static const char *tclOOSetupScript = "}\n" "proc ::oo::MixinClassDelegates {class} {\n" -" ::oo::objdefine $class mixin -append {*}[lmap c [info class superclass $class] {\n" +" if {![info object isa class $class]} {\n" +" return\n" +" }\n" +" set delegate [::oo::DelegateName $class]\n" +" if {![info object isa class $delegate]} {\n" +" return\n" +" }\n" +" foreach c [info class superclass $class] {" " set d [::oo::DelegateName $c]\n" -" if {![info object isa class $d]} continue; set d\n" -" }]\n" +" if {![info object isa class $d]} {\n" +" continue\n" +" }\n" +" ::oo::define $delegate superclass -append $d\n" +" }\n" +" ::oo::objdefine $class mixin -append $delegate\n" "}\n" "::proc ::oo::define::initialise {body} {\n" @@ -114,6 +125,19 @@ static const char *tclOOSetupScript = "::oo::objdefine ::oo::define::mixin forward --default-operation my -set\n" "::oo::objdefine ::oo::objdefine::mixin forward --default-operation my -set\n" +"::oo::define ::oo::class method {originObject} {\n" +" next $originObject\n" +" # Rebuild the class inheritance delegation class\n" +" set originDelegate [::oo::DelegateName $originObject]\n" +" set targetDelegate [::oo::DelegateName [self]]\n" +" if {[info object isa class $originDelegate] && ![info object isa class $targetDelegate]} {\n" +" ::oo::copy $originDelegate $targetDelegate\n" +" ::oo::objdefine [self] mixin -set {*}[lmap c [info object mixin [self]] {\n" +" if {$c eq $originDelegate} {set targetDelegate} {set c}\n" +" }]\n" +" }\n" +"}\n" + "::oo::class create ::oo::singleton {\n" " superclass ::oo::class\n" " variable object\n" @@ -137,6 +161,7 @@ static const char *tclOOSetupScript = */ static const char *clonedBody = +"# Copy over the procedures from the original namespace\n" "foreach p [info procs [info object namespace $originObject]::*] {\n" " set args [info args $p]\n" " set idx -1\n" @@ -148,6 +173,7 @@ static const char *clonedBody = " set p [namespace tail $p]\n" " proc $p $args $b\n" "}\n" +"# Copy over the variables from the original namespace\n" "foreach v [info vars [info object namespace $originObject]::*] {\n" " upvar 0 $v vOrigin\n" " namespace upvar [namespace current] [namespace tail $v] vNew\n" @@ -158,7 +184,8 @@ static const char *clonedBody = " set vNew $vOrigin\n" " }\n" " }\n" -"}\n"; +"}\n" +; #endif /* TCL_OO_SCRIPT_H */ diff --git a/tests/oo.test b/tests/oo.test index 87f0567..9aafe2e 100644 --- a/tests/oo.test +++ b/tests/oo.test @@ -4851,7 +4851,9 @@ test oo-41.1 {TIP 478: classmethod} -setup { } -body { oo::class create ActiveRecord { superclass parent - classmethod find args { puts "[self] called with arguments: $args" } + classmethod find args { + return "[self] called with arguments: $args" + } } oo::class create Table { superclass ActiveRecord @@ -4859,13 +4861,15 @@ test oo-41.1 {TIP 478: classmethod} -setup { Table find foo bar } -cleanup { parent destroy -} -output "::Table called with arguments: foo bar\n" +} -result {::Table called with arguments: foo bar} test oo-41.2 {TIP 478: classmethod in namespace} -setup { namespace eval ::testns {} } -body { namespace eval ::testns { oo::class create ActiveRecord { - classmethod find args { puts "[self] called with arguments: $args" } + classmethod find args { + return "[self] called with arguments: $args" + } } oo::class create Table { superclass ActiveRecord @@ -4874,7 +4878,7 @@ test oo-41.2 {TIP 478: classmethod in namespace} -setup { testns::Table find foo bar } -cleanup { namespace delete ::testns -} -output "::testns::Table called with arguments: foo bar\n" +} -result {::testns::Table called with arguments: foo bar} test oo-41.3 {TIP 478: classmethod must not interfere with constructor signatures} -setup { oo::class create parent } -body { @@ -4888,6 +4892,133 @@ test oo-41.3 {TIP 478: classmethod must not interfere with constructor signature } -cleanup { parent destroy } -result {::okay} +test oo-41.4 {TIP 478: classmethod with three levels} -setup { + oo::class create parent +} -body { + oo::class create ActiveRecord { + superclass parent + classmethod find args { + return "[self] called with arguments: $args" + } + } + oo::class create Table { + superclass ActiveRecord + } + oo::class create SubTable { + superclass Table + } + SubTable find foo bar +} -cleanup { + parent destroy +} -result {::SubTable called with arguments: foo bar} + +test oo-42.1 {TIP 478: callback generation} -setup { + oo::class create parent +} -body { + oo::class create c { + superclass parent + method CallMe {} { return ok,[self] } + method makeCall {} { + return [callback CallMe] + } + } + c create ::context + set cb [context makeCall] + {*}$cb +} -cleanup { + parent destroy +} -result {ok,::context} +test oo-42.2 {TIP 478: callback generation} -setup { + oo::class create parent +} -body { + oo::class create c { + superclass parent + method CallMe {a b c} { return ok,[self],$a,$b,$c } + method makeCall {b} { + return [callback CallMe 123 $b] + } + } + c create ::context + set cb [context makeCall "a b c"] + {*}$cb PQR +} -cleanup { + parent destroy +} -result {ok,::context,123,a b c,PQR} +test oo-42.3 {TIP 478: callback generation, alternate name} -setup { + oo::class create parent +} -body { + oo::class create c { + superclass parent + method CallMe {} { return ok,[self] } + method makeCall {} { + return [mymethod CallMe] + } + } + c create ::context + set cb [context makeCall] + {*}$cb +} -cleanup { + parent destroy +} -result {ok,::context} +test oo-42.4 {TIP 478: callback generation, alternate name} -setup { + oo::class create parent +} -body { + oo::class create c { + superclass parent + method CallMe {a b c} { return ok,[self],$a,$b,$c } + method makeCall {b} { + return [mymethod CallMe 123 $b] + } + } + c create ::context + set cb [context makeCall "a b c"] + {*}$cb PQR +} -cleanup { + parent destroy +} -result {ok,::context,123,a b c,PQR} +test oo-42.5 {TIP 478: callbacks and method lifetime} -setup { + oo::class create parent +} -body { + oo::class create c { + superclass parent + method makeCall {b} { + return [callback CallMe 123 $b] + } + } + c create ::context + set cb [context makeCall "a b c"] + set result [list [catch {{*}$cb PQR} msg] $msg] + oo::objdefine context { + method CallMe {a b c} { return ok,[self],$a,$b,$c } + } + lappend result [{*}$cb PQR] +} -cleanup { + parent destroy +} -result {1 {unknown method "CallMe": must be , destroy, eval, makeCall, unknown, variable or varname} {ok,::context,123,a b c,PQR}} +test oo-42.6 {TIP 478: callback use case} -setup { + oo::class create parent + unset -nocomplain x +} -body { + oo::class create c { + superclass parent + variable count + constructor {var} { + set count 0 + upvar 1 $var v + trace add variable v write [callback TraceCallback] + } + method count {} {return $count} + method TraceCallback {name1 name2 op} { + incr count + } + } + set o [c new x] + for {set x 0} {$x < 5} {incr x} {} + $o count +} -cleanup { + unset -nocomplain x + parent destroy +} -result 6 cleanupTests return -- cgit v0.12 From 8219fb26323aa59d5e46299099e965049a0cb654 Mon Sep 17 00:00:00 2001 From: dkf Date: Thu, 28 Jun 2018 08:12:07 +0000 Subject: Tests for abstract and singleton --- generic/tclOOScript.h | 3 +- tests/oo.test | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 93 insertions(+), 2 deletions(-) diff --git a/generic/tclOOScript.h b/generic/tclOOScript.h index 73c3383..22f5e56 100644 --- a/generic/tclOOScript.h +++ b/generic/tclOOScript.h @@ -143,8 +143,9 @@ static const char *tclOOSetupScript = " variable object\n" " unexport create createWithNamespace\n" " method new args {\n" -" if {![info exists object]} {\n" +" if {![info exists object] || ![info object isa object $object]} {\n" " set object [next {*}$args]\n" +" ::oo::objdefine $object unexport destroy\n" " }\n" " return $object\n" " }\n" diff --git a/tests/oo.test b/tests/oo.test index 9aafe2e..1e694c1 100644 --- a/tests/oo.test +++ b/tests/oo.test @@ -4892,7 +4892,7 @@ test oo-41.3 {TIP 478: classmethod must not interfere with constructor signature } -cleanup { parent destroy } -result {::okay} -test oo-41.4 {TIP 478: classmethod with three levels} -setup { +test oo-41.4 {TIP 478: classmethod with several inheritance levels} -setup { oo::class create parent } -body { oo::class create ActiveRecord { @@ -4911,6 +4911,41 @@ test oo-41.4 {TIP 478: classmethod with three levels} -setup { } -cleanup { parent destroy } -result {::SubTable called with arguments: foo bar} +test oo-41.5 {TIP 478: classmethod and instances} -setup { + oo::class create parent +} -body { + oo::class create ActiveRecord { + superclass parent + classmethod find args { + return "[self] called with arguments: $args" + } + } + oo::class create Table { + superclass ActiveRecord + } + set t [Table new] + $t find 1 2 3 +} -cleanup { + parent destroy +} -result {::ActiveRecord called with arguments: 1 2 3} +test oo-41.6 {TIP 478: classmethod and instances} -setup { + oo::class create parent +} -body { + oo::class create ActiveRecord { + superclass parent + classmethod find args { + return "[self] called with arguments: $args" + } + } + oo::class create Table { + superclass ActiveRecord + unexport find + } + set t [Table new] + $t find 1 2 3 +} -returnCodes error -cleanup { + parent destroy +} -match glob -result {unknown method "find": must be *} test oo-42.1 {TIP 478: callback generation} -setup { oo::class create parent @@ -5019,6 +5054,61 @@ test oo-42.6 {TIP 478: callback use case} -setup { unset -nocomplain x parent destroy } -result 6 + +test oo-43.1 {TIP 478: class initialisation} -setup { + oo::class create parent +} -body { + oo::class create ::cls { + superclass parent + initialise { + proc foobar {} {return ok} + } + method calls {} { + list [catch foobar msg] $msg \ + [namespace eval [info object namespace [self class]] foobar] + } + } + [cls new] calls +} -cleanup { + parent destroy +} -result {1 {invalid command name "foobar"} ok} + +test oo-44.1 {TIP 478: singleton} -setup { + oo::class create parent +} -body { + oo::singleton create xyz { + superclass parent + } + set x [xyz new] + set y [xyz new] + set z [xyz new] + set code [catch {$x destroy} msg] + set p [xyz new] + lappend code $msg [catch {rename $x ""}] + set q [xyz new] + string map [list $x ONE $q TWO] [list {*}$code $x $y $z $p $q [xyz new]] +} -cleanup { + parent destroy +} -result {1 {object "ONE" has no visible methods} 0 ONE ONE ONE ONE TWO TWO} + +test oo-45.1 {TIP 478: abstract} -setup { + oo::class create parent +} -body { + oo::abstract create xyz { + superclass parent + method foo {} {return 123} + } + oo::class create pqr { + superclass xyz + method bar {} {return 456} + } + set codes [list [catch {xyz new}] [catch {xyz create x}] [catch {xyz createWithNamespace x y}]] + set x [pqr new] + set y [pqr create ::y] + lappend codes [$x foo] [$x bar] $y +} -cleanup { + parent destroy +} -result {1 1 1 123 456 ::y} cleanupTests return -- cgit v0.12 From 4c24e60418bdb662ac652345798230eeff89ce0b Mon Sep 17 00:00:00 2001 From: dkf Date: Thu, 28 Jun 2018 10:40:37 +0000 Subject: Split out TIP 478 tests into their own file. --- tests/oo.test | 264 ------------------------------------------ tests/ooUtil.test | 337 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 337 insertions(+), 264 deletions(-) create mode 100644 tests/ooUtil.test diff --git a/tests/oo.test b/tests/oo.test index 1e694c1..7e0f12e 100644 --- a/tests/oo.test +++ b/tests/oo.test @@ -4845,270 +4845,6 @@ test oo-40.3 {TIP 500: private and unexport} -setup { } -cleanup { cls destroy } -result {{} {} foo {} foo {}} - -test oo-41.1 {TIP 478: classmethod} -setup { - oo::class create parent -} -body { - oo::class create ActiveRecord { - superclass parent - classmethod find args { - return "[self] called with arguments: $args" - } - } - oo::class create Table { - superclass ActiveRecord - } - Table find foo bar -} -cleanup { - parent destroy -} -result {::Table called with arguments: foo bar} -test oo-41.2 {TIP 478: classmethod in namespace} -setup { - namespace eval ::testns {} -} -body { - namespace eval ::testns { - oo::class create ActiveRecord { - classmethod find args { - return "[self] called with arguments: $args" - } - } - oo::class create Table { - superclass ActiveRecord - } - } - testns::Table find foo bar -} -cleanup { - namespace delete ::testns -} -result {::testns::Table called with arguments: foo bar} -test oo-41.3 {TIP 478: classmethod must not interfere with constructor signatures} -setup { - oo::class create parent -} -body { - oo::class create TestClass { - superclass oo::class parent - self method create {name ignore body} { - next $name $body - } - } - TestClass create okay {} {} -} -cleanup { - parent destroy -} -result {::okay} -test oo-41.4 {TIP 478: classmethod with several inheritance levels} -setup { - oo::class create parent -} -body { - oo::class create ActiveRecord { - superclass parent - classmethod find args { - return "[self] called with arguments: $args" - } - } - oo::class create Table { - superclass ActiveRecord - } - oo::class create SubTable { - superclass Table - } - SubTable find foo bar -} -cleanup { - parent destroy -} -result {::SubTable called with arguments: foo bar} -test oo-41.5 {TIP 478: classmethod and instances} -setup { - oo::class create parent -} -body { - oo::class create ActiveRecord { - superclass parent - classmethod find args { - return "[self] called with arguments: $args" - } - } - oo::class create Table { - superclass ActiveRecord - } - set t [Table new] - $t find 1 2 3 -} -cleanup { - parent destroy -} -result {::ActiveRecord called with arguments: 1 2 3} -test oo-41.6 {TIP 478: classmethod and instances} -setup { - oo::class create parent -} -body { - oo::class create ActiveRecord { - superclass parent - classmethod find args { - return "[self] called with arguments: $args" - } - } - oo::class create Table { - superclass ActiveRecord - unexport find - } - set t [Table new] - $t find 1 2 3 -} -returnCodes error -cleanup { - parent destroy -} -match glob -result {unknown method "find": must be *} - -test oo-42.1 {TIP 478: callback generation} -setup { - oo::class create parent -} -body { - oo::class create c { - superclass parent - method CallMe {} { return ok,[self] } - method makeCall {} { - return [callback CallMe] - } - } - c create ::context - set cb [context makeCall] - {*}$cb -} -cleanup { - parent destroy -} -result {ok,::context} -test oo-42.2 {TIP 478: callback generation} -setup { - oo::class create parent -} -body { - oo::class create c { - superclass parent - method CallMe {a b c} { return ok,[self],$a,$b,$c } - method makeCall {b} { - return [callback CallMe 123 $b] - } - } - c create ::context - set cb [context makeCall "a b c"] - {*}$cb PQR -} -cleanup { - parent destroy -} -result {ok,::context,123,a b c,PQR} -test oo-42.3 {TIP 478: callback generation, alternate name} -setup { - oo::class create parent -} -body { - oo::class create c { - superclass parent - method CallMe {} { return ok,[self] } - method makeCall {} { - return [mymethod CallMe] - } - } - c create ::context - set cb [context makeCall] - {*}$cb -} -cleanup { - parent destroy -} -result {ok,::context} -test oo-42.4 {TIP 478: callback generation, alternate name} -setup { - oo::class create parent -} -body { - oo::class create c { - superclass parent - method CallMe {a b c} { return ok,[self],$a,$b,$c } - method makeCall {b} { - return [mymethod CallMe 123 $b] - } - } - c create ::context - set cb [context makeCall "a b c"] - {*}$cb PQR -} -cleanup { - parent destroy -} -result {ok,::context,123,a b c,PQR} -test oo-42.5 {TIP 478: callbacks and method lifetime} -setup { - oo::class create parent -} -body { - oo::class create c { - superclass parent - method makeCall {b} { - return [callback CallMe 123 $b] - } - } - c create ::context - set cb [context makeCall "a b c"] - set result [list [catch {{*}$cb PQR} msg] $msg] - oo::objdefine context { - method CallMe {a b c} { return ok,[self],$a,$b,$c } - } - lappend result [{*}$cb PQR] -} -cleanup { - parent destroy -} -result {1 {unknown method "CallMe": must be , destroy, eval, makeCall, unknown, variable or varname} {ok,::context,123,a b c,PQR}} -test oo-42.6 {TIP 478: callback use case} -setup { - oo::class create parent - unset -nocomplain x -} -body { - oo::class create c { - superclass parent - variable count - constructor {var} { - set count 0 - upvar 1 $var v - trace add variable v write [callback TraceCallback] - } - method count {} {return $count} - method TraceCallback {name1 name2 op} { - incr count - } - } - set o [c new x] - for {set x 0} {$x < 5} {incr x} {} - $o count -} -cleanup { - unset -nocomplain x - parent destroy -} -result 6 - -test oo-43.1 {TIP 478: class initialisation} -setup { - oo::class create parent -} -body { - oo::class create ::cls { - superclass parent - initialise { - proc foobar {} {return ok} - } - method calls {} { - list [catch foobar msg] $msg \ - [namespace eval [info object namespace [self class]] foobar] - } - } - [cls new] calls -} -cleanup { - parent destroy -} -result {1 {invalid command name "foobar"} ok} - -test oo-44.1 {TIP 478: singleton} -setup { - oo::class create parent -} -body { - oo::singleton create xyz { - superclass parent - } - set x [xyz new] - set y [xyz new] - set z [xyz new] - set code [catch {$x destroy} msg] - set p [xyz new] - lappend code $msg [catch {rename $x ""}] - set q [xyz new] - string map [list $x ONE $q TWO] [list {*}$code $x $y $z $p $q [xyz new]] -} -cleanup { - parent destroy -} -result {1 {object "ONE" has no visible methods} 0 ONE ONE ONE ONE TWO TWO} - -test oo-45.1 {TIP 478: abstract} -setup { - oo::class create parent -} -body { - oo::abstract create xyz { - superclass parent - method foo {} {return 123} - } - oo::class create pqr { - superclass xyz - method bar {} {return 456} - } - set codes [list [catch {xyz new}] [catch {xyz create x}] [catch {xyz createWithNamespace x y}]] - set x [pqr new] - set y [pqr create ::y] - lappend codes [$x foo] [$x bar] $y -} -cleanup { - parent destroy -} -result {1 1 1 123 456 ::y} cleanupTests return diff --git a/tests/ooUtil.test b/tests/ooUtil.test new file mode 100644 index 0000000..4e4dba1 --- /dev/null +++ b/tests/ooUtil.test @@ -0,0 +1,337 @@ +# This file contains a collection of tests for functionality originally +# sourced from the ooutil package in Tcllib. Sourcing this file into Tcl runs +# the tests and generates output for errors. No output means no errors were +# found. +# +# Copyright (c) 2014-2016 Andreas Kupries +# Copyright (c) 2018 Donal K. Fellows +# +# See the file "license.terms" for information on usage and redistribution of +# this file, and for a DISCLAIMER OF ALL WARRANTIES. + +package require TclOO 1.0.3 +package require tcltest 2 +if {"::tcltest" in [namespace children]} { + namespace import -force ::tcltest::* +} + +test ooUtil-1.1 {TIP 478: classmethod} -setup { + oo::class create parent +} -body { + oo::class create ActiveRecord { + superclass parent + classmethod find args { + return "[self] called with arguments: $args" + } + } + oo::class create Table { + superclass ActiveRecord + } + Table find foo bar +} -cleanup { + parent destroy +} -result {::Table called with arguments: foo bar} +test ooUtil-1.2 {TIP 478: classmethod in namespace} -setup { + namespace eval ::testns {} +} -body { + namespace eval ::testns { + oo::class create ActiveRecord { + classmethod find args { + return "[self] called with arguments: $args" + } + } + oo::class create Table { + superclass ActiveRecord + } + } + testns::Table find foo bar +} -cleanup { + namespace delete ::testns +} -result {::testns::Table called with arguments: foo bar} +test ooUtil-1.3 {TIP 478: classmethod must not interfere with constructor signatures} -setup { + oo::class create parent +} -body { + oo::class create TestClass { + superclass oo::class parent + self method create {name ignore body} { + next $name $body + } + } + TestClass create okay {} {} +} -cleanup { + parent destroy +} -result {::okay} +test ooUtil-1.4 {TIP 478: classmethod with several inheritance levels} -setup { + oo::class create parent +} -body { + oo::class create ActiveRecord { + superclass parent + classmethod find args { + return "[self] called with arguments: $args" + } + } + oo::class create Table { + superclass ActiveRecord + } + oo::class create SubTable { + superclass Table + } + SubTable find foo bar +} -cleanup { + parent destroy +} -result {::SubTable called with arguments: foo bar} +test ooUtil-1.5 {TIP 478: classmethod and instances} -setup { + oo::class create parent +} -body { + oo::class create ActiveRecord { + superclass parent + classmethod find args { + return "[self] called with arguments: $args" + } + } + oo::class create Table { + superclass ActiveRecord + } + set t [Table new] + $t find 1 2 3 +} -cleanup { + parent destroy +} -result {::ActiveRecord called with arguments: 1 2 3} +test ooUtil-1.6 {TIP 478: classmethod and instances} -setup { + oo::class create parent +} -body { + oo::class create ActiveRecord { + superclass parent + classmethod find args { + return "[self] called with arguments: $args" + } + } + oo::class create Table { + superclass ActiveRecord + unexport find + } + set t [Table new] + $t find 1 2 3 +} -returnCodes error -cleanup { + parent destroy +} -match glob -result {unknown method "find": must be *} + +test ooUtil-2.1 {TIP 478: callback generation} -setup { + oo::class create parent +} -body { + oo::class create c { + superclass parent + method CallMe {} { return ok,[self] } + method makeCall {} { + return [callback CallMe] + } + } + c create ::context + set cb [context makeCall] + {*}$cb +} -cleanup { + parent destroy +} -result {ok,::context} +test ooUtil-2.2 {TIP 478: callback generation} -setup { + oo::class create parent +} -body { + oo::class create c { + superclass parent + method CallMe {a b c} { return ok,[self],$a,$b,$c } + method makeCall {b} { + return [callback CallMe 123 $b] + } + } + c create ::context + set cb [context makeCall "a b c"] + {*}$cb PQR +} -cleanup { + parent destroy +} -result {ok,::context,123,a b c,PQR} +test ooUtil-2.3 {TIP 478: callback generation, alternate name} -setup { + oo::class create parent +} -body { + oo::class create c { + superclass parent + method CallMe {} { return ok,[self] } + method makeCall {} { + return [mymethod CallMe] + } + } + c create ::context + set cb [context makeCall] + {*}$cb +} -cleanup { + parent destroy +} -result {ok,::context} +test ooUtil-2.4 {TIP 478: callback generation, alternate name} -setup { + oo::class create parent +} -body { + oo::class create c { + superclass parent + method CallMe {a b c} { return ok,[self],$a,$b,$c } + method makeCall {b} { + return [mymethod CallMe 123 $b] + } + } + c create ::context + set cb [context makeCall "a b c"] + {*}$cb PQR +} -cleanup { + parent destroy +} -result {ok,::context,123,a b c,PQR} +test ooUtil-2.5 {TIP 478: callbacks and method lifetime} -setup { + oo::class create parent +} -body { + oo::class create c { + superclass parent + method makeCall {b} { + return [callback CallMe 123 $b] + } + } + c create ::context + set cb [context makeCall "a b c"] + set result [list [catch {{*}$cb PQR} msg] $msg] + oo::objdefine context { + method CallMe {a b c} { return ok,[self],$a,$b,$c } + } + lappend result [{*}$cb PQR] +} -cleanup { + parent destroy +} -result {1 {unknown method "CallMe": must be , destroy, eval, makeCall, unknown, variable or varname} {ok,::context,123,a b c,PQR}} +test ooUtil-2.6 {TIP 478: callback use case} -setup { + oo::class create parent + unset -nocomplain x +} -body { + oo::class create c { + superclass parent + variable count + constructor {var} { + set count 0 + upvar 1 $var v + trace add variable v write [callback TraceCallback] + } + method count {} {return $count} + method TraceCallback {name1 name2 op} { + incr count + } + } + set o [c new x] + for {set x 0} {$x < 5} {incr x} {} + $o count +} -cleanup { + unset -nocomplain x + parent destroy +} -result 6 + +test ooUtil-3.1 {TIP 478: class initialisation} -setup { + oo::class create parent + catch {rename ::foobar-3.1 {}} +} -body { + oo::class create ::cls { + superclass parent + initialise { + proc foobar-3.1 {} {return ok} + } + method calls {} { + list [catch foobar-3.1 msg] $msg \ + [namespace eval [info object namespace [self class]] foobar-3.1] + } + } + [cls new] calls +} -cleanup { + parent destroy +} -result {1 {invalid command name "foobar-3.1"} ok} +test ooUtil-3.2 {TIP 478: class variables} -setup { + oo::class create parent + catch {rename ::foobar-3.1 {}} +} -body { + oo::class create ::cls { + superclass parent + initialise { + variable x 123 + } + method call {} { + classvariable x + incr x + } + } + cls create a + cls create b + cls create c + list [a call] [b call] [c call] [a call] [b call] [c call] +} -cleanup { + parent destroy +} -result {124 125 126 127 128 129} + +test ooUtil-4.1 {TIP 478: singleton} -setup { + oo::class create parent +} -body { + oo::singleton create xyz { + superclass parent + } + set x [xyz new] + set y [xyz new] + set z [xyz new] + set code [catch {$x destroy} msg] + set p [xyz new] + lappend code $msg [catch {rename $x ""}] + set q [xyz new] + string map [list $x ONE $q TWO] [list {*}$code $x $y $z $p $q [xyz new]] +} -cleanup { + parent destroy +} -result {1 {object "ONE" has no visible methods} 0 ONE ONE ONE ONE TWO TWO} + +test ooUtil-5.1 {TIP 478: abstract} -setup { + oo::class create parent +} -body { + oo::abstract create xyz { + superclass parent + method foo {} {return 123} + } + oo::class create pqr { + superclass xyz + method bar {} {return 456} + } + set codes [list [catch {xyz new}] [catch {xyz create x}] [catch {xyz createWithNamespace x y}]] + set x [pqr new] + set y [pqr create ::y] + lappend codes [$x foo] [$x bar] $y +} -cleanup { + parent destroy +} -result {1 1 1 123 456 ::y} + +# Tests that verify issues detected with the tcllib version of the code +test ooUtil-tcllib-ticket-b3577ed586 {test scoping of delegation in oo::class.Delegate } -setup { + oo::class create animal {} + namespace eval ::ooutiltest { + oo::class create pet { superclass animal } + } +} -body { + namespace eval ::ooutiltest { + oo::class create dog { superclass pet } + } +} -cleanup { + namespace delete ooutiltest + rename animal {} +} -result {::ooutiltest::dog} +test ooUtil-tcllib-ticket-fe7a0e0a3a {classmethod must not interfere with constructor signatures} -setup { + oo::class create TestClass { + superclass oo::class + self method create {name ignore body} { + next $name $body + } + } +} -body { + TestClass create okay {} {} +} -cleanup { + rename TestClass {} +} -result {::okay} + +cleanupTests +return + +# Local Variables: +# fill-column: 78 +# mode: tcl +# End: -- cgit v0.12 From 3f8c7d5d407e778604b2238e06ced08bf1402eca Mon Sep 17 00:00:00 2001 From: dkf Date: Fri, 29 Jun 2018 07:15:06 +0000 Subject: More test cases. More fixes. --- generic/tclOOScript.h | 24 ++++++++++--- tests/ooUtil.test | 98 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 118 insertions(+), 4 deletions(-) diff --git a/generic/tclOOScript.h b/generic/tclOOScript.h index 22f5e56..6dd105e 100644 --- a/generic/tclOOScript.h +++ b/generic/tclOOScript.h @@ -33,8 +33,15 @@ static const char *tclOOSetupScript = " # Get a reference to the class's namespace\n" " set ns [info object namespace [uplevel 1 {self class}]]\n" " # Double up the list of variable names\n" -" set vs [list $name $name]\n" -" foreach v $args {lappend vs $v $v}\n" +" foreach v [list $name {*}$args] {\n" +" if {[string match *(*) $v]} {\n" +" return -code error [string cat {bad variable name \"} $v {\": can\'t create a scalar variable that looks like an array element}]\n" +" }\n" +" if {[string match *::* $v]} {\n" +" return -code error [string cat {bad variable name \"} $v {\": can\'t create a local variable with a namespace separator in it}]\n" +" }\n" +" lappend vs $v $v\n" +" }\n" " # Lastly, link the caller's local variables to the class's variables\n" " tailcall namespace upvar $ns {*}$vs\n" "}\n" @@ -48,12 +55,21 @@ static const char *tclOOSetupScript = " lassign $link src\n" " set dst $src\n" " }\n" -" interp alias {} ${ns}::$src {} ${ns}::my $dst\n" +" if {![string match ::* $src]} {\n" +" set src [string cat $ns :: $src]\n" +" }\n" +" interp alias {} $src {} ${ns}::my $dst\n" +" trace add command ${ns}::my delete [list ::oo::Helpers::Unlink $src]\n" " }\n" " return\n" "}\n" +"::proc ::oo::Helpers::Unlink {cmd args} {\n" +" if {[namespace which $cmd] ne {}} {\n" +" rename $cmd {}\n" +" }\n" +"}\n" -"proc ::oo::DelegateName {class} {\n" +"::proc ::oo::DelegateName {class} {\n" " string cat [info object namespace $class] {:: oo ::delegate}\n" "}\n" diff --git a/tests/ooUtil.test b/tests/ooUtil.test index 4e4dba1..77fa175 100644 --- a/tests/ooUtil.test +++ b/tests/ooUtil.test @@ -301,6 +301,104 @@ test ooUtil-5.1 {TIP 478: abstract} -setup { parent destroy } -result {1 1 1 123 456 ::y} +test ooUtil-6.1 {TIP 478: classvarable} -setup { + oo::class create parent +} -body { + oo::class create xyz { + superclass parent + initialise { + variable x 1 y 2 + } + method a {} { + classvariable x + incr x + } + method b {} { + classvariable y + incr y + } + method c {} { + classvariable x y + list $x $y + } + } + set p [xyz new] + set q [xyz new] + set result [list [$p c] [$q c]] + $p a + $q b + lappend result [[xyz new] c] +} -cleanup { + parent destroy +} -result {{1 2} {1 2} {2 3}} +test ooUtil-6.2 {TIP 478: classvarable error case} -setup { + oo::class create parent +} -body { + oo::class create xyz { + superclass parent + method a {} { + classvariable x(1) + incr x(1) + } + } + set p [xyz new] + set q [xyz new] + list [$p a] [$q a] +} -returnCodes error -cleanup { + parent destroy +} -result {bad variable name "x(1)": can't create a scalar variable that looks like an array element} +test ooUtil-6.3 {TIP 478: classvarable error case} -setup { + oo::class create parent +} -body { + oo::class create xyz { + superclass parent + method a {} { + classvariable ::x + incr x + } + } + set p [xyz new] + set q [xyz new] + list [$p a] [$q a] +} -returnCodes error -cleanup { + parent destroy +} -result {bad variable name "::x": can't create a local variable with a namespace separator in it} + +test ooUtil-7.1 {TIP 478: link calling pattern} -setup { + oo::class create parent +} -body { + oo::class create cls { + superclass parent + method foo {} {return "in foo of [self]"} + method Bar {} {return "in bar of [self]"} + method Grill {} {return "in grill of [self]"} + export eval + constructor {} { + link foo + link {bar Bar} {grill Grill} + } + } + cls create o + o eval {list [foo] [bar] [grill]} +} -cleanup { + parent destroy +} -result {{in foo of ::o} {in bar of ::o} {in grill of ::o}} +test ooUtil-7.2 {TIP 478: link removed when [my] disappears} -setup { + oo::class create parent +} -body { + oo::class create cls { + superclass parent + method foo {} {return "in foo of [self]"} + constructor {cmd} { + link [list ::$cmd foo] + } + } + cls create o pqr + list [o foo] [pqr] [rename [info object namespace o]::my {}] [catch pqr msg] $msg +} -cleanup { + parent destroy +} -result {{in foo of ::o} {in foo of ::o} {} 1 {invalid command name "pqr"}} + # Tests that verify issues detected with the tcllib version of the code test ooUtil-tcllib-ticket-b3577ed586 {test scoping of delegation in oo::class.Delegate } -setup { oo::class create animal {} -- cgit v0.12 From 0978bd50ce03a7d56c569156c606be4533699a31 Mon Sep 17 00:00:00 2001 From: dkf Date: Sat, 30 Jun 2018 05:13:39 +0000 Subject: Started to write documentation --- doc/callback.n | 86 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 doc/callback.n diff --git a/doc/callback.n b/doc/callback.n new file mode 100644 index 0000000..8244f07 --- /dev/null +++ b/doc/callback.n @@ -0,0 +1,86 @@ +'\" +'\" Copyright (c) 2018 Donal K. Fellows +'\" +'\" See the file "license.terms" for information on usage and redistribution +'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. +'\" +.TH callback n 0.1 TclOO "TclOO Commands" +.so man.macros +.BS +'\" Note: do not modify the .SH NAME line immediately below! +.SH NAME +callback, mymethod \- generate callbacks to methods +.SH SYNOPSIS +.nf +package require TclOO + +\fBcallback\fR \fImethodName\fR ?\fIarg ...\fR? +\fBmymethod\fR \fImethodName\fR ?\fIarg ...\fR? +.fi +.BE +.SH DESCRIPTION +The \fBcallback\fR command, also called \fBmymethod\fR for compatibility with +the ooutil package of Tcllib, and which should only be used from within the +context of a call to a method (i.e. inside a method, constructor or destructor +body) is used to generate a script fragment that will invoke the method, +\fImethodName\fR, on the current object (as reported by \fBself\fR) when +executed. Any additional arguments provided will be provided as leading +arguments to the callback. The resulting script fragment shall be a proper +list. +.PP +Note that it is up to the caller to ensure that the current object is able to +handle the call of \fImethodName\fR; this command does not check that. +\fImethodName\fR may refer to any exported or unexported method, but may not +refer to a private method as those can only be invoked directly from within +methods. If there is no such method present at the point when the callback is +invoked, the standard \fBunknown\fR method handler will be called. +.SH EXAMPLE +This is a simple echo server class. The \fBcallback\fR command is used in two +places, to arrange for the incoming socket connections to be handled by the +\fIAccept\fR method, and to arrange for the incoming bytes on those +connections to be handled by the \fIReceive\fR method. +.PP +.CS +oo::class create EchoServer { + variable server clients + constructor {port} { + set server [socket -server [\fBcallback\fR Accept] $port] + set clients {} + } + destructor { + chan close $server + foreach client [dict keys $clients] { + chan close $client + } + } + + method Accept {channel clientAddress clientPort} { + dict set clients $channel [dict create \e + address $clientAddress port $clientPort] + chan event $channel readable [\fBcallback\fR Receive $channel] + } + method Receive {channel} { + if {[chan gets $channel line] >= 0} { + my echo $channel $line + } else { + chan close $channel + dict unset clients $channel + } + } + + method echo {channel line} { + dict with clients $channel { + chan puts $channel \e + [format {[%s:%d] %s} $address $port $line] + } + } +} +.CE +.SH "SEE ALSO" +chan(n), fileevent(n), my(n), self(n), socket(n), trace(n) +.SH KEYWORDS +callback, object +.\" Local Variables: +.\" mode: nroff +.\" fill-column: 78 +.\" End: -- cgit v0.12 From bffb982059c34bbd6c4bcb6074af928f28ceeed4 Mon Sep 17 00:00:00 2001 From: dkf Date: Sat, 30 Jun 2018 13:44:25 +0000 Subject: More docs --- doc/callback.n | 18 +++++++------ doc/classvariable.n | 78 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+), 8 deletions(-) create mode 100644 doc/classvariable.n diff --git a/doc/callback.n b/doc/callback.n index 8244f07..a05eb9c 100644 --- a/doc/callback.n +++ b/doc/callback.n @@ -19,14 +19,16 @@ package require TclOO .fi .BE .SH DESCRIPTION -The \fBcallback\fR command, also called \fBmymethod\fR for compatibility with -the ooutil package of Tcllib, and which should only be used from within the -context of a call to a method (i.e. inside a method, constructor or destructor -body) is used to generate a script fragment that will invoke the method, -\fImethodName\fR, on the current object (as reported by \fBself\fR) when -executed. Any additional arguments provided will be provided as leading -arguments to the callback. The resulting script fragment shall be a proper -list. +The \fBcallback\fR command, +'\" Based on notes in the tcllib docs, we know the provenance of mymethod +also called \fBmymethod\fR for compatibility with the ooutil and snit packages +of Tcllib, +and which should only be used from within the context of a call to a method +(i.e. inside a method, constructor or destructor body) is used to generate a +script fragment that will invoke the method, \fImethodName\fR, on the current +object (as reported by \fBself\fR) when executed. Any additional arguments +provided will be provided as leading arguments to the callback. The resulting +script fragment shall be a proper list. .PP Note that it is up to the caller to ensure that the current object is able to handle the call of \fImethodName\fR; this command does not check that. diff --git a/doc/classvariable.n b/doc/classvariable.n new file mode 100644 index 0000000..1edca3e --- /dev/null +++ b/doc/classvariable.n @@ -0,0 +1,78 @@ +'\" +'\" Copyright (c) 2011-2015 Andreas Kupries +'\" Copyright (c) 2018 Donal K. Fellows +'\" +'\" See the file "license.terms" for information on usage and redistribution +'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. +'\" +.TH classvariable n 0.1 TclOO "TclOO Commands" +.so man.macros +.BS +'\" Note: do not modify the .SH NAME line immediately below! +.SH NAME +classvariable \- create link from local variable to variable in class +.SH SYNOPSIS +.nf +package require TclOO + +\fBclassvariable\fR \fIvariableName\fR ?\fI...\fR? +.fi +.BE +.SH DESCRIPTION +The \fBclassvariable\fR command is available within methods. It takes a series +of one or more variable names and makes them available in the method's scope; +those variable names must not be qualified and must not refer to array +elements. The originating scope for the variables is the namespace of the +class that the method was defined by. In other words, the referenced variables +are shared between all instances of that class. +.PP +Note: This command is equivalent to the command \fBtypevariable\fR provided by +the snit package in tcllib for approximately the same purpose. If used in a +method defined directly on a class instance (e.g., through the +\fBoo::objdefine\fR \fBmethod\fR definition) this is very much like just +using: +.PP +.CS +namespace upvar [namespace current] $var $var +.CE +.PP +for each variable listed to \fBclassvariable\fR. +.SH EXAMPLE +This class counts how many instances of it have been made. +.PP +.CS +oo::class create Counted { + initialise { + variable count 0 + } + + variable number + constructor {} { + \fBclassvariable\fR count + set number [incr count] + } + + method report {} { + \fBclassvariable\fR count + puts "This is instance $number of $count" + } +} + +set a [Counted new] +set b [Counted new] +$a report + \fI\(-> This is instance 1 of 2\fR +set c [Counted new] +$b report + \fI\(-> This is instance 2 of 3\fR +$c report + \fI\(-> This is instance 3 of 3\fR +.CE +.SH "SEE ALSO" +global(n), namespace(n), oo::class(n), oo::define(n), upvar(n), variable(n) +.SH KEYWORDS +class, class variable, variable +.\" Local Variables: +.\" mode: nroff +.\" fill-column: 78 +.\" End: -- cgit v0.12 From 1d1e95e7793597eb517bdeffc450474e6616ef92 Mon Sep 17 00:00:00 2001 From: dkf Date: Sat, 30 Jun 2018 18:30:53 +0000 Subject: More docs --- doc/link.n | 124 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 doc/link.n diff --git a/doc/link.n b/doc/link.n new file mode 100644 index 0000000..e7c28d7 --- /dev/null +++ b/doc/link.n @@ -0,0 +1,124 @@ +'\" +'\" Copyright (c) 2011-2015 Andreas Kupries +'\" Copyright (c) 2018 Donal K. Fellows +'\" +'\" See the file "license.terms" for information on usage and redistribution +'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. +'\" +.TH link n 0.1 TclOO "TclOO Commands" +.so man.macros +.BS +'\" Note: do not modify the .SH NAME line immediately below! +.SH NAME +link \- create link from command to method of object +.SH SYNOPSIS +.nf +package require TclOO + +\fBlink\fR \fImethodName\fR ?\fI...\fR? +\fBlink\fR \fB{\fIcommandName methodName\fB}\fR ?\fI...\fR? +.fi +.BE +.SH DESCRIPTION +The \fBlink\fR command is available within methods. It takes a series of one +or more method names (\fImethodName ...\fR) and/or pairs of command- and +method-name (\fB{\fIcommandName methodName\fB}\fR) and makes the named methods +available as commands without requiring the explicit use of the name of the +object or the \fBmy\fR command. The method does not need to exist at the time +that the link is made; if the link command is invoked when the method does not +exist, the standard \fBunknown\fR method handling system is used. +.PP +The command name under which the method becomes available defaults to the +method name, except where explicitly specified through an alias/method pair. +Formally, every argument must be a list; if the list has two elements, the +first element is the name of the command to create and the second element is +the name of the method of the current object to which the command links; +otherwise, the name of the command and the name of the method are the same +string (the first element of the list). +.PP +If the name of the command is not a fully-qualified command name, it will be +resolved with respect to the current namespace (i.e., the object namespace). +.SH EXAMPLES +This demonstrates linking a single method in various ways. First it makes a +simple link, then a renamed link, then an external link. Note that the method +itself is unexported, but that it can still be called directly from outside +the class. +.PP +.CS +oo::class create ABC { + method Foo {} { + puts "This is Foo in [self]" + } + + constructor {} { + \fBlink\fR Foo + # The method foo is now directly accessible as foo here + \fBlink\fR {bar Foo} + # The method foo is now directly accessible as bar + \fBlink\fR {::ExternalCall Foo} + # The method foo is now directly accessible in the global + # namespace as ExternalCall + } + + method grill {} { + puts "Step 1:" + Foo + puts "Step 2:" + bar + } +} + +ABC create abc +abc grill + \fI\(-> Step 1:\fR + \fI\(-> This is foo in ::abc\fR + \fI\(-> Step 2:\fR + \fI\(-> This is foo in ::abc\fR +# Direct access via the linked command +puts "Step 3:"; ExternalCall + \fI\(-> Step 3:\fR + \fI\(-> This is foo in ::abc\fR +.CE +.PP +This example shows that multiple linked commands can be made in a call to +\fBlink\fR, and that they can handle arguments. +.PP +.CS +oo::class create Ex { + constructor {} { + \fBlink\fR a b c + # The methods a, b, and c (defined below) are all now + # directly acessible within methods under their own names. + } + + method a {} { + puts "This is a" + } + method b {x} { + puts "This is b($x)" + } + method c {y z} { + puts "This is c($y,$z)" + } + + method call {p q r} { + a + b $p + c $q $r + } +} + +set o [Ex new] +$o 3 5 7 + \fI\(-> This is a\fR + \fI\(-> This is b(3)\fR + \fI\(-> This is c(5,7)\fR +.CE +.SH "SEE ALSO" +interp(n), my(n), oo::class(n), oo::define(n) +.SH KEYWORDS +command, method, object +.\" Local Variables: +.\" mode: nroff +.\" fill-column: 78 +.\" End: -- cgit v0.12 From 5c7ba37901819efd8c30dee373dada97eafdce04 Mon Sep 17 00:00:00 2001 From: dkf Date: Sat, 30 Jun 2018 21:36:01 +0000 Subject: More docs --- doc/abstract.n | 75 ++++++++++++++++++++++++++++++++++++++++++ doc/callback.n | 2 +- doc/classvariable.n | 2 +- doc/define.n | 7 ++++ doc/link.n | 2 +- doc/singleton.n | 93 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 178 insertions(+), 3 deletions(-) create mode 100644 doc/abstract.n create mode 100644 doc/singleton.n diff --git a/doc/abstract.n b/doc/abstract.n new file mode 100644 index 0000000..c11202b --- /dev/null +++ b/doc/abstract.n @@ -0,0 +1,75 @@ +'\" +'\" Copyright (c) 2018 Donal K. Fellows +'\" +'\" See the file "license.terms" for information on usage and redistribution +'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. +'\" +.TH abstract n 0.3 TclOO "TclOO Commands" +.so man.macros +.BS +'\" Note: do not modify the .SH NAME line immediately below! +.SH NAME +oo::abstract \- a class that does not allow direct instances of itself +.SH SYNOPSIS +.nf +package require TclOO + +\fBoo::abstract\fI method \fR?\fIarg ...\fR? +.fi +.SH "CLASS HIERARCHY" +.nf +\fBoo::object\fR + \(-> \fBoo::class\fR + \(-> \fBoo::abstract\fR +.fi +.BE +.SH DESCRIPTION +Abstract classes are classes that can contain definitions, but which cannot be +directly manufactured; they are intended to only ever be inherited from and +instantiated indirectly. The characteristic methods of \fBoo::class\fR +(\fBcreate\fR and \fBnew\fR) are not exported by an instance of +\fBoo::abstract\fR. +.PP +Note that \fBoo::abstract\fR is not itself an instance of \fBoo::abstract\fR. +.SS CONSTRUCTOR +The \fBoo::abstract\fR class does not define an explicit constructor; this +means that it is effectively the same as the constructor of the +\fBoo::class\fR class. +.SS DESTRUCTOR +The \fBoo::abstract\fR class does not define an explicit destructor. +.SS "EXPORTED METHODS" +The \fBoo::abstract\fR class defines no new exported methods. +.SS "NON-EXPORTED METHODS" +The \fBoo::abstract\fR class explicitly states that \fBcreate\fR, +\fBcreateWithNamespace\fR, and \fBnew\fR are unexported. +.SH EXAMPLES +.PP +This example defines a simple class hierarchy and creates a new instance of +it. It then invokes a method of the object before destroying the hierarchy and +showing that the destruction is transitive. +.PP +.CS +\fBoo::abstract\fR create fruit { + method eat {} { + puts "yummy!" + } +} +oo::class create banana { + superclass fruit + method peel {} { + puts "skin now off" + } +} +set b [banana \fBnew\fR] +$b peel \fI\(-> prints 'skin now off'\fR +$b eat \fI\(-> prints 'yummy!'\fR +set f [fruit new] \fI\(-> error 'unknown method "new"...'\fR +.CE +.SH "SEE ALSO" +oo::define(n), oo::object(n) +.SH KEYWORDS +abstract class, class, metaclass, object +.\" Local variables: +.\" mode: nroff +.\" fill-column: 78 +.\" End: diff --git a/doc/callback.n b/doc/callback.n index a05eb9c..95838a9 100644 --- a/doc/callback.n +++ b/doc/callback.n @@ -4,7 +4,7 @@ '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. '\" -.TH callback n 0.1 TclOO "TclOO Commands" +.TH callback n 0.3 TclOO "TclOO Commands" .so man.macros .BS '\" Note: do not modify the .SH NAME line immediately below! diff --git a/doc/classvariable.n b/doc/classvariable.n index 1edca3e..0798bb2 100644 --- a/doc/classvariable.n +++ b/doc/classvariable.n @@ -5,7 +5,7 @@ '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. '\" -.TH classvariable n 0.1 TclOO "TclOO Commands" +.TH classvariable n 0.3 TclOO "TclOO Commands" .so man.macros .BS '\" Note: do not modify the .SH NAME line immediately below! diff --git a/doc/define.n b/doc/define.n index b489e5f..c0c90d1 100644 --- a/doc/define.n +++ b/doc/define.n @@ -110,6 +110,13 @@ below), this command creates private forwarded methods. .VE TIP500 .RE .TP +\fBinitialise\fI script\fR +.VS TIP478 +This evaluates \fIscript\fR in a context which supports local variables and +where the current namespace is the instance namespace of the class object +itself. This is useful for setting up, e.g., class-scoped variables. +.VE TIP478 +.TP \fBmethod\fI name argList bodyScript\fR . This creates or updates a method that is implemented as a procedure-like diff --git a/doc/link.n b/doc/link.n index e7c28d7..7219342 100644 --- a/doc/link.n +++ b/doc/link.n @@ -5,7 +5,7 @@ '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. '\" -.TH link n 0.1 TclOO "TclOO Commands" +.TH link n 0.3 TclOO "TclOO Commands" .so man.macros .BS '\" Note: do not modify the .SH NAME line immediately below! diff --git a/doc/singleton.n b/doc/singleton.n new file mode 100644 index 0000000..6319abe --- /dev/null +++ b/doc/singleton.n @@ -0,0 +1,93 @@ +'\" +'\" Copyright (c) 2018 Donal K. Fellows +'\" +'\" See the file "license.terms" for information on usage and redistribution +'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. +'\" +.TH singleton n 0.3 TclOO "TclOO Commands" +.so man.macros +.BS +'\" Note: do not modify the .SH NAME line immediately below! +.SH NAME +oo::singleton \- a class that does only allows one instance of itself +.SH SYNOPSIS +.nf +package require TclOO + +\fBoo::singleton\fI method \fR?\fIarg ...\fR? +.fi +.SH "CLASS HIERARCHY" +.nf +\fBoo::object\fR + \(-> \fBoo::class\fR + \(-> \fBoo::singleton\fR +.fi +.BE +.SH DESCRIPTION +Singleton classes are classes that only permit at most one instance of +themselves to exist. They unexport the \fBcreate\fR and +\fBcreateWithNamespace\fR methods entirely, and override the \fBnew\fR method +so that it only makes a new instance if there is no existing instance. It is +not recommended to inherit from a singleton class; singleton-ness is \fInot\fR +inherited. It is not recommended that a singleton class's constructor take any +arguments. +.PP +Instances have their\fB destroy\fR method (from \fBoo::object\fR) unexported +in order to discourage destruction of the object, but destruction remains +possible if strictly necessary (e.g., by destroying the class or using +\fBrename\fR to delete it). +.SS CONSTRUCTOR +The \fBoo::singleton\fR class does not define an explicit constructor; this +means that it is effectively the same as the constructor of the +\fBoo::class\fR class. +.SS DESTRUCTOR +The \fBoo::singleton\fR class does not define an explicit destructor. +.SS "EXPORTED METHODS" +.TP +\fIcls \fBnew \fR?\fIarg ...\fR? +. +This returns the current instance of the singleton class, if one exists, and +creates a new instance only if there is no existing instance. The additional +arguments, \fIarg ...\fR, are only used if a new instance is actually +manufactured; that construction is via the \fBoo::class\fR class's \fBnew\fR +method. +.RS +.PP +This is an override of the behaviour of a superclass's method. +.RE +.SS "NON-EXPORTED METHODS" +The \fBoo::singleton\fR class explicitly states that \fBcreate\fR and +\fBcreateWithNamespace\fR are unexported. +.SH EXAMPLE +.PP +This example demonstrates that there is only one instance even though the +\fBnew\fR method is called three times. +.PP +.CS +\fBoo::singleton\fR create Highlander { + method say {} { + puts "there can be only one" + } +} + +set h1 [Highlander new] +set h2 [Highlander new] +if {$h1 eq $h2} { + puts "equal objects" \fI\(-> prints "equal objects"\fR +} +set h3 [Highlander new] +if {$h1 eq $h3} { + puts "equal objects" \fI\(-> prints "equal objects"\fR +} +.CE +.PP +Note that the name of the instance of the singleton is not guaranteed to be +anything in particular. +.SH "SEE ALSO" +oo::class(n) +.SH KEYWORDS +class, metaclass, object, single instance +.\" Local variables: +.\" mode: nroff +.\" fill-column: 78 +.\" End: -- cgit v0.12 From d11660acfec5e51e088b6e9661d3b6b8e0b1988a Mon Sep 17 00:00:00 2001 From: dkf Date: Sun, 1 Jul 2018 16:39:11 +0000 Subject: Create a special command, [ :my:class], (in each instance namespace) that allows objects to delegate methods to their class. --- generic/tclOO.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++ generic/tclOOInt.h | 2 ++ generic/tclOOScript.h | 2 +- tests/ooUtil.test | 25 +++++++++++++++++++++- unix/Makefile.in | 7 +++++++ 5 files changed, 92 insertions(+), 2 deletions(-) diff --git a/generic/tclOO.c b/generic/tclOO.c index 7f609b2..8229dc1 100644 --- a/generic/tclOO.c +++ b/generic/tclOO.c @@ -102,6 +102,13 @@ static int PrivateObjectCmd(ClientData clientData, static int PrivateNRObjectCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv); +static int MyClassObjCmd(ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *const *objv); +static int MyClassNRObjCmd(ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *const *objv); +static void MyClassDeletedCmd(ClientData clientData); /* * Methods in the oo::object and oo::class classes. First, we define a helper @@ -747,6 +754,9 @@ AllocObject( oPtr->myCommand = TclNRCreateCommandInNs(interp, "my", oPtr->namespacePtr, PrivateObjectCmd, PrivateNRObjectCmd, oPtr, MyDeleted); + oPtr->myclassCommand = TclNRCreateCommandInNs(interp, " :my:class", + oPtr->namespacePtr, MyClassObjCmd, MyClassNRObjCmd, oPtr, + MyClassDeletedCmd); return oPtr; } @@ -1165,6 +1175,9 @@ ObjectNamespaceDeleted( Tcl_DeleteCommandFromToken(oPtr->fPtr->interp, oPtr->command); } + if (oPtr->myclassCommand) { + Tcl_DeleteCommandFromToken(oPtr->fPtr->interp, oPtr->myclassCommand); + } if (oPtr->myCommand) { Tcl_DeleteCommandFromToken(oPtr->fPtr->interp, oPtr->myCommand); } @@ -2488,6 +2501,51 @@ TclOOInvokeObject( /* * ---------------------------------------------------------------------- * + * MyClassObjCmd, MyClassNRObjCmd, MyClassDeletedCmd -- + * + * Special trap door to allow an object to delegate simply to its class. + * + * ---------------------------------------------------------------------- + */ + +static int +MyClassObjCmd( + ClientData clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *const *objv) +{ + return Tcl_NRCallObjProc(interp, MyClassNRObjCmd, clientData, objc, objv); +} + +static int +MyClassNRObjCmd( + ClientData clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *const *objv) +{ + Object *oPtr = clientData; + + if (objc < 2) { + Tcl_WrongNumArgs(interp, 1, objv, "methodName ?arg ...?"); + return TCL_ERROR; + } + return TclOOObjectCmdCore(oPtr->selfCls->thisPtr, interp, objc, objv, 0, + NULL); +} + +static void +MyClassDeletedCmd( + ClientData clientData) +{ + Object *oPtr = clientData; + oPtr->myclassCommand = NULL; +} + +/* + * ---------------------------------------------------------------------- + * * TclOOObjectCmdCore, FinalizeObjectCall -- * * Main function for object invocations. Does call chain creation, diff --git a/generic/tclOOInt.h b/generic/tclOOInt.h index a43ab76..ce4ea0d 100644 --- a/generic/tclOOInt.h +++ b/generic/tclOOInt.h @@ -209,6 +209,8 @@ typedef struct Object { PrivateVariableList privateVariables; /* Configurations for the variable resolver * used inside methods. */ + Tcl_Command myclassCommand; /* Reference to this object's class dispatcher + * command. */ } Object; #define OBJECT_DELETED 1 /* Flag to say that an object has been diff --git a/generic/tclOOScript.h b/generic/tclOOScript.h index 6dd105e..237bff5 100644 --- a/generic/tclOOScript.h +++ b/generic/tclOOScript.h @@ -85,7 +85,7 @@ static const char *tclOOSetupScript = " ::oo::define [::oo::DelegateName $cls] method $name $args $body\n" " }\n" " # Make the connection by forwarding\n" -" tailcall forward $name [info object namespace $cls]::my $name\n" +" tailcall forward $name { :my:class} $name\n" "}\n" "proc ::oo::MixinClassDelegates {class} {\n" diff --git a/tests/ooUtil.test b/tests/ooUtil.test index 77fa175..28ab9c7 100644 --- a/tests/ooUtil.test +++ b/tests/ooUtil.test @@ -96,7 +96,7 @@ test ooUtil-1.5 {TIP 478: classmethod and instances} -setup { $t find 1 2 3 } -cleanup { parent destroy -} -result {::ActiveRecord called with arguments: 1 2 3} +} -result {::Table called with arguments: 1 2 3} test ooUtil-1.6 {TIP 478: classmethod and instances} -setup { oo::class create parent } -body { @@ -115,6 +115,29 @@ test ooUtil-1.6 {TIP 478: classmethod and instances} -setup { } -returnCodes error -cleanup { parent destroy } -match glob -result {unknown method "find": must be *} +test ooUtil-1.7 {} -setup { + oo::class create parent +} -body { + oo::class create Foo { + superclass parent + classmethod bar {} { + puts "This is in the class; self is [self]" + my meee + } + classmethod meee {} { + puts "This is meee" + } + } + oo::class create Grill { + superclass Foo + classmethod meee {} { + puts "This is meee 2" + } + } + list [Foo bar] [Grill bar] [[Foo new] bar] [[Grill new] bar] +} -cleanup { + parent destroy +} -result {{} {} {} {}} -output "This is in the class; self is ::Foo\nThis is meee\nThis is in the class; self is ::Grill\nThis is meee 2\nThis is in the class; self is ::Foo\nThis is meee\nThis is in the class; self is ::Grill\nThis is meee 2\n" test ooUtil-2.1 {TIP 478: callback generation} -setup { oo::class create parent diff --git a/unix/Makefile.in b/unix/Makefile.in index 9aa67fb..e4d77e6 100644 --- a/unix/Makefile.in +++ b/unix/Makefile.in @@ -259,6 +259,7 @@ INSTALL_TZDATA = @INSTALL_TZDATA@ #-------------------------------------------------------------------------- GDB = gdb +LLDB = lldb TRACE = strace TRACE_OPTS = VALGRIND = valgrind @@ -730,6 +731,12 @@ gdb-test: ${TCLTEST_EXE} $(GDB) ./${TCLTEST_EXE} --command=gdb.run rm gdb.run +lldb-test: ${TCLTEST_EXE} + @echo "settings set target.env-vars @LD_LIBRARY_PATH_VAR@=`pwd`:$${@LD_LIBRARY_PATH_VAR@}" > lldb.run + @echo "settings set target.env-vars TCL_LIBRARY=${TCL_BUILDTIME_LIBRARY}" >> lldb.run + $(LLDB) --source lldb.run ./${TCLTEST_EXE} -- $(TOP_DIR)/tests/all.tcl $(TESTFLAGS) -singleproc 1 + rm lldb.run + # Useful target to launch a built tcltest with the proper path,... runtest: ${TCLTEST_EXE} $(SHELL_ENV) ./${TCLTEST_EXE} -- cgit v0.12 From 414bcee273fa2ac3fbc1e329f65d1ae7396a22a4 Mon Sep 17 00:00:00 2001 From: dkf Date: Mon, 2 Jul 2018 07:44:09 +0000 Subject: Documentation for [classmethod] --- doc/define.n | 99 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) diff --git a/doc/define.n b/doc/define.n index c0c90d1..099e59f 100644 --- a/doc/define.n +++ b/doc/define.n @@ -39,6 +39,27 @@ used as the \fIdefScript\fR argument. The following commands are supported in the \fIdefScript\fR for \fBoo::define\fR, each of which may also be used in the \fIsubcommand\fR form: .TP +\fBclassmethod\fI name\fR ?\fIargList bodyScrip\fR? +.VS TIP478 +This creates a class method, or (if \fIargList\fR and \fIbodyScript\fR are +omitted) promotes an existing method on the class object to be a class +method. The \fIname\fR, \fIargList\fR and \fIbodyScript\fR arguments are as in +the \fBmethod\fR definition, below. +.RS +.PP +Class methods can be called on either the class itself or on the instances of +that class. When they are called, the current object (see the \fBself\R and +\fBmy\fR commands) is the class on which they are called or the class of the +instance on which they are called, depending on whether they are called on the +class or an instance of the class, respectively. If called on a subclass or +instance of the subclass, the current object is the subclass. +.PP +In a private definition context, the methods as invoked on classes are +\fInot\fR private, but the methods as invoked on instances of classes are +private. +.RE +.VE TIP478 +.TP \fBconstructor\fI argList bodyScript\fR . This creates or updates the constructor for a class. The formal arguments to @@ -503,6 +524,84 @@ oo::class create B { inst m1 \fI\(-> prints "red brick"\fR inst m2 \fI\(-> prints "blue brick"\fR .CE +.PP +.VS TIP478 +This example shows how to create and use class variables. It is a class that +counts how many instances of itself have been made. +.PP +.CS +oo::class create Counted +\fBoo::define\fR Counted { + \fBinitialise\fR { + variable count 0 + } + + \fBvariable\fR number + \fBconstructor\fR {} { + classvariable count + set number [incr count] + } + + \fBmethod\fR report {} { + classvariable count + puts "This is instance $number of $count" + } +} + +set a [Counted new] +set b [Counted new] +$a report + \fI\(-> This is instance 1 of 2\fR +set c [Counted new] +$b report + \fI\(-> This is instance 2 of 3\fR +$c report + \fI\(-> This is instance 3 of 3\fR +.CE +.PP +This example demonstrates how to use class methods. (Note that the constructor +for \fBoo::class\fR calls \fBoo::define\fR on the class.) +.PP +.CS +oo::class create DBTable { + \fBclassmethod\fR find {description} { + puts "DB: locate row from [self] matching $description" + return [my new] + } + \fBclassmethod\fR insert {description} { + puts "DB: create row in [self] matching $description" + return [my new] + } + \fBmethod\fR update {description} { + puts "DB: update row [self] with $description" + } + \fBmethod\fR delete {} { + puts "DB: delete row [self]" + my destroy; # Just delete the object, not the DB row + } +} + +oo::class create Users { + \fBsuperclass\fR DBTable +} +oo::class create Groups { + \fBsuperclass\fR DBTable +} + +set u1 [Users insert "username=abc"] + \fI\(-> DB: create row from ::Users matching username=abc\fR +set u2 [Users insert "username=def"] + \fI\(-> DB: create row from ::Users matching username=def\fR +$u2 update "group=NULL" + \fI\(-> DB: update row ::oo::Obj124 with group=NULL\fR +$u1 delete + \fI\(-> DB: delete row ::oo::Obj123\fR +set g [Group find "groupname=webadmins"] + \fI\(-> DB: locate row ::Group with groupname=webadmins\fR +$g update "emailaddress=admins" + \fI\(-> DB: update row ::oo::Obj125 with emailaddress=admins\fR +.CE +.VE TIP478 .SH "SEE ALSO" next(n), oo::class(n), oo::object(n) .SH KEYWORDS -- cgit v0.12 From da7eafc83b4c8797c24505fd5f2c629821c20c00 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 4 Jul 2018 20:18:39 +0000 Subject: Micro-optimization in Tcl_GetString() and Tcl_GetStringFromObj() --- generic/tclObj.c | 69 ++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 45 insertions(+), 24 deletions(-) diff --git a/generic/tclObj.c b/generic/tclObj.c index f93f583..16ef7c3 100644 --- a/generic/tclObj.c +++ b/generic/tclObj.c @@ -1632,32 +1632,30 @@ Tcl_GetString( register Tcl_Obj *objPtr) /* Object whose string rep byte pointer should * be returned. */ { - if (objPtr->bytes != NULL) { - return objPtr->bytes; - } - - /* - * Note we do not check for objPtr->typePtr == NULL. An invariant of - * a properly maintained Tcl_Obj is that at least one of objPtr->bytes - * and objPtr->typePtr must not be NULL. If broken extensions fail to - * maintain that invariant, we can crash here. - */ - - if (objPtr->typePtr->updateStringProc == NULL) { + if (objPtr->bytes == NULL) { /* - * Those Tcl_ObjTypes which choose not to define an updateStringProc - * must be written in such a way that (objPtr->bytes) never becomes - * NULL. This panic was added in Tcl 8.1. + * Note we do not check for objPtr->typePtr == NULL. An invariant + * of a properly maintained Tcl_Obj is that at least one of + * objPtr->bytes and objPtr->typePtr must not be NULL. If broken + * extensions fail to maintain that invariant, we can crash here. */ - Tcl_Panic("UpdateStringProc should not be invoked for type %s", - objPtr->typePtr->name); - } - objPtr->typePtr->updateStringProc(objPtr); - if (objPtr->bytes == NULL || objPtr->length < 0 - || objPtr->bytes[objPtr->length] != '\0') { - Tcl_Panic("UpdateStringProc for type '%s' " - "failed to create a valid string rep", objPtr->typePtr->name); + if (objPtr->typePtr->updateStringProc == NULL) { + /* + * Those Tcl_ObjTypes which choose not to define an + * updateStringProc must be written in such a way that + * (objPtr->bytes) never becomes NULL. + */ + Tcl_Panic("UpdateStringProc should not be invoked for type %s", + objPtr->typePtr->name); + } + objPtr->typePtr->updateStringProc(objPtr); + if (objPtr->bytes == NULL || objPtr->length < 0 + || objPtr->bytes[objPtr->length] != '\0') { + Tcl_Panic("UpdateStringProc for type '%s' " + "failed to create a valid string rep", + objPtr->typePtr->name); + } } return objPtr->bytes; } @@ -1693,8 +1691,31 @@ Tcl_GetStringFromObj( * rep's byte array length should * be stored. * If NULL, no length is stored. */ { - (void) TclGetString(objPtr); + if (objPtr->bytes == NULL) { + /* + * Note we do not check for objPtr->typePtr == NULL. An invariant + * of a properly maintained Tcl_Obj is that at least one of + * objPtr->bytes and objPtr->typePtr must not be NULL. If broken + * extensions fail to maintain that invariant, we can crash here. + */ + if (objPtr->typePtr->updateStringProc == NULL) { + /* + * Those Tcl_ObjTypes which choose not to define an + * updateStringProc must be written in such a way that + * (objPtr->bytes) never becomes NULL. + */ + Tcl_Panic("UpdateStringProc should not be invoked for type %s", + objPtr->typePtr->name); + } + objPtr->typePtr->updateStringProc(objPtr); + if (objPtr->bytes == NULL || objPtr->length < 0 + || objPtr->bytes[objPtr->length] != '\0') { + Tcl_Panic("UpdateStringProc for type '%s' " + "failed to create a valid string rep", + objPtr->typePtr->name); + } + } if (lengthPtr != NULL) { *lengthPtr = objPtr->length; } -- cgit v0.12 From 6982ae0ca7a42a53c0fbdf2fddf9296537b7bfa0 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 4 Jul 2018 20:20:28 +0000 Subject: Make Tcl_GetUnicode() a macro. Mark many other stub-entries which are no longer are in use (because they were converted to macros) as deprecated, since they will be removed in Tcl 9.0 --- generic/tcl.decls | 48 +++++++++---------- generic/tclDecls.h | 126 +++++++++++++++++++++++++++++-------------------- generic/tclStringObj.c | 3 ++ generic/tclStubInit.c | 2 + 4 files changed, 105 insertions(+), 74 deletions(-) diff --git a/generic/tcl.decls b/generic/tcl.decls index da551bb..60effc4 100644 --- a/generic/tcl.decls +++ b/generic/tcl.decls @@ -104,7 +104,7 @@ declare 20 { declare 21 { int Tcl_DbIsShared(Tcl_Obj *objPtr, const char *file, int line) } -declare 22 { +declare 22 {deprecated {No longer in use, changed to macro}} { Tcl_Obj *Tcl_DbNewBooleanObj(int boolValue, const char *file, int line) } declare 23 { @@ -119,7 +119,7 @@ declare 25 { Tcl_Obj *Tcl_DbNewListObj(int objc, Tcl_Obj *const *objv, const char *file, int line) } -declare 26 { +declare 26 {deprecated {No longer in use, changed to macro}} { Tcl_Obj *Tcl_DbNewLongObj(long longValue, const char *file, int line) } declare 27 { @@ -152,7 +152,7 @@ declare 35 { int Tcl_GetDoubleFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, double *doublePtr) } -declare 36 { +declare 36 {deprecated {No longer in use, changed to macro}} { int Tcl_GetIndexFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, const char *const *tablePtr, const char *msg, int flags, int *indexPtr) } @@ -198,7 +198,7 @@ declare 48 { int Tcl_ListObjReplace(Tcl_Interp *interp, Tcl_Obj *listPtr, int first, int count, int objc, Tcl_Obj *const objv[]) } -declare 49 { +declare 49 {deprecated {No longer in use, changed to macro}} { Tcl_Obj *Tcl_NewBooleanObj(int boolValue) } declare 50 { @@ -207,13 +207,13 @@ declare 50 { declare 51 { Tcl_Obj *Tcl_NewDoubleObj(double doubleValue) } -declare 52 { +declare 52 {deprecated {No longer in use, changed to macro}} { Tcl_Obj *Tcl_NewIntObj(int intValue) } declare 53 { Tcl_Obj *Tcl_NewListObj(int objc, Tcl_Obj *const objv[]) } -declare 54 { +declare 54 {deprecated {No longer in use, changed to macro}} { Tcl_Obj *Tcl_NewLongObj(long longValue) } declare 55 { @@ -222,7 +222,7 @@ declare 55 { declare 56 { Tcl_Obj *Tcl_NewStringObj(const char *bytes, int length) } -declare 57 { +declare 57 {deprecated {No longer in use, changed to macro}} { void Tcl_SetBooleanObj(Tcl_Obj *objPtr, int boolValue) } declare 58 { @@ -235,13 +235,13 @@ declare 59 { declare 60 { void Tcl_SetDoubleObj(Tcl_Obj *objPtr, double doubleValue) } -declare 61 { +declare 61 {deprecated {No longer in use, changed to macro}} { void Tcl_SetIntObj(Tcl_Obj *objPtr, int intValue) } declare 62 { void Tcl_SetListObj(Tcl_Obj *objPtr, int objc, Tcl_Obj *const objv[]) } -declare 63 { +declare 63 {deprecated {No longer in use, changed to macro}} { void Tcl_SetLongObj(Tcl_Obj *objPtr, long longValue) } declare 64 { @@ -250,10 +250,10 @@ declare 64 { declare 65 { void Tcl_SetStringObj(Tcl_Obj *objPtr, const char *bytes, int length) } -declare 66 { +declare 66 {deprecated {No longer in use, changed to macro}} { void Tcl_AddErrorInfo(Tcl_Interp *interp, const char *message) } -declare 67 { +declare 67 {deprecated {No longer in use, changed to macro}} { void Tcl_AddObjErrorInfo(Tcl_Interp *interp, const char *message, int length) } @@ -472,7 +472,7 @@ declare 129 { declare 130 { int Tcl_EvalFile(Tcl_Interp *interp, const char *fileName) } -declare 131 { +declare 131 {deprecated {No longer in use, changed to macro}} { int Tcl_EvalObj(Tcl_Interp *interp, Tcl_Obj *objPtr) } declare 132 { @@ -624,7 +624,7 @@ declare 173 { declare 174 { const char *Tcl_GetStringResult(Tcl_Interp *interp) } -declare 175 { +declare 175 {deprecated {No longer in use, changed to macro}} { const char *Tcl_GetVar(Tcl_Interp *interp, const char *varName, int flags) } @@ -635,7 +635,7 @@ declare 176 { declare 177 { int Tcl_GlobalEval(Tcl_Interp *interp, const char *command) } -declare 178 { +declare 178 {deprecated {No longer in use, changed to macro}} { int Tcl_GlobalEvalObj(Tcl_Interp *interp, Tcl_Obj *objPtr) } declare 179 { @@ -834,7 +834,7 @@ declare 235 { declare 236 { void Tcl_SetStdChannel(Tcl_Channel channel, int type) } -declare 237 { +declare 237 {deprecated {No longer in use, changed to macro}} { const char *Tcl_SetVar(Tcl_Interp *interp, const char *varName, const char *newValue, int flags) } @@ -869,7 +869,7 @@ declare 245 { declare 246 {deprecated {}} { int Tcl_TellOld(Tcl_Channel chan) } -declare 247 { +declare 247 {deprecated {No longer in use, changed to macro}} { int Tcl_TraceVar(Tcl_Interp *interp, const char *varName, int flags, Tcl_VarTraceProc *proc, ClientData clientData) } @@ -890,14 +890,14 @@ declare 251 { declare 252 { int Tcl_UnregisterChannel(Tcl_Interp *interp, Tcl_Channel chan) } -declare 253 { +declare 253 {deprecated {No longer in use, changed to macro}} { int Tcl_UnsetVar(Tcl_Interp *interp, const char *varName, int flags) } declare 254 { int Tcl_UnsetVar2(Tcl_Interp *interp, const char *part1, const char *part2, int flags) } -declare 255 { +declare 255 {deprecated {No longer in use, changed to macro}} { void Tcl_UntraceVar(Tcl_Interp *interp, const char *varName, int flags, Tcl_VarTraceProc *proc, ClientData clientData) } @@ -909,7 +909,7 @@ declare 256 { declare 257 { void Tcl_UpdateLinkedVar(Tcl_Interp *interp, const char *varName) } -declare 258 { +declare 258 {deprecated {No longer in use, changed to macro}} { int Tcl_UpVar(Tcl_Interp *interp, const char *frameName, const char *varName, const char *localName, int flags) } @@ -920,7 +920,7 @@ declare 259 { declare 260 { int Tcl_VarEval(Tcl_Interp *interp, ...) } -declare 261 { +declare 261 {deprecated {No longer in use, changed to macro}} { ClientData Tcl_VarTraceInfo(Tcl_Interp *interp, const char *varName, int flags, Tcl_VarTraceProc *procPtr, ClientData prevClientData) } @@ -955,7 +955,7 @@ declare 270 { const char *Tcl_ParseVar(Tcl_Interp *interp, const char *start, const char **termPtr) } -declare 271 { +declare 271 {deprecated {No longer in use, changed to macro}} { const char *Tcl_PkgPresent(Tcl_Interp *interp, const char *name, const char *version, int exact) } @@ -964,12 +964,12 @@ declare 272 { const char *name, const char *version, int exact, void *clientDataPtr) } -declare 273 { +declare 273 {deprecated {No longer in use, changed to macro}} { int Tcl_PkgProvide(Tcl_Interp *interp, const char *name, const char *version) } # TIP #268: The internally used new Require function is in slot 573. -declare 274 { +declare 274 {deprecated {No longer in use, changed to macro}} { const char *Tcl_PkgRequire(Tcl_Interp *interp, const char *name, const char *version, int exact) } @@ -1350,7 +1350,7 @@ declare 380 { declare 381 { int Tcl_GetUniChar(Tcl_Obj *objPtr, int index) } -declare 382 { +declare 382 {deprecated {No longer in use, changed to macro}} { Tcl_UniChar *Tcl_GetUnicode(Tcl_Obj *objPtr) } declare 383 { diff --git a/generic/tclDecls.h b/generic/tclDecls.h index 592d945..3f7f343 100644 --- a/generic/tclDecls.h +++ b/generic/tclDecls.h @@ -119,7 +119,8 @@ EXTERN void Tcl_DbIncrRefCount(Tcl_Obj *objPtr, const char *file, EXTERN int Tcl_DbIsShared(Tcl_Obj *objPtr, const char *file, int line); /* 22 */ -EXTERN Tcl_Obj * Tcl_DbNewBooleanObj(int boolValue, const char *file, +TCL_DEPRECATED("No longer in use, changed to macro") +Tcl_Obj * Tcl_DbNewBooleanObj(int boolValue, const char *file, int line); /* 23 */ EXTERN Tcl_Obj * Tcl_DbNewByteArrayObj(const unsigned char *bytes, @@ -131,7 +132,8 @@ EXTERN Tcl_Obj * Tcl_DbNewDoubleObj(double doubleValue, EXTERN Tcl_Obj * Tcl_DbNewListObj(int objc, Tcl_Obj *const *objv, const char *file, int line); /* 26 */ -EXTERN Tcl_Obj * Tcl_DbNewLongObj(long longValue, const char *file, +TCL_DEPRECATED("No longer in use, changed to macro") +Tcl_Obj * Tcl_DbNewLongObj(long longValue, const char *file, int line); /* 27 */ EXTERN Tcl_Obj * Tcl_DbNewObj(const char *file, int line); @@ -158,7 +160,8 @@ EXTERN int Tcl_GetDouble(Tcl_Interp *interp, const char *src, EXTERN int Tcl_GetDoubleFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, double *doublePtr); /* 36 */ -EXTERN int Tcl_GetIndexFromObj(Tcl_Interp *interp, +TCL_DEPRECATED("No longer in use, changed to macro") +int Tcl_GetIndexFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, const char *const *tablePtr, const char *msg, int flags, int *indexPtr); /* 37 */ @@ -198,24 +201,28 @@ EXTERN int Tcl_ListObjReplace(Tcl_Interp *interp, Tcl_Obj *listPtr, int first, int count, int objc, Tcl_Obj *const objv[]); /* 49 */ -EXTERN Tcl_Obj * Tcl_NewBooleanObj(int boolValue); +TCL_DEPRECATED("No longer in use, changed to macro") +Tcl_Obj * Tcl_NewBooleanObj(int boolValue); /* 50 */ EXTERN Tcl_Obj * Tcl_NewByteArrayObj(const unsigned char *bytes, int length); /* 51 */ EXTERN Tcl_Obj * Tcl_NewDoubleObj(double doubleValue); /* 52 */ -EXTERN Tcl_Obj * Tcl_NewIntObj(int intValue); +TCL_DEPRECATED("No longer in use, changed to macro") +Tcl_Obj * Tcl_NewIntObj(int intValue); /* 53 */ EXTERN Tcl_Obj * Tcl_NewListObj(int objc, Tcl_Obj *const objv[]); /* 54 */ -EXTERN Tcl_Obj * Tcl_NewLongObj(long longValue); +TCL_DEPRECATED("No longer in use, changed to macro") +Tcl_Obj * Tcl_NewLongObj(long longValue); /* 55 */ EXTERN Tcl_Obj * Tcl_NewObj(void); /* 56 */ EXTERN Tcl_Obj * Tcl_NewStringObj(const char *bytes, int length); /* 57 */ -EXTERN void Tcl_SetBooleanObj(Tcl_Obj *objPtr, int boolValue); +TCL_DEPRECATED("No longer in use, changed to macro") +void Tcl_SetBooleanObj(Tcl_Obj *objPtr, int boolValue); /* 58 */ EXTERN unsigned char * Tcl_SetByteArrayLength(Tcl_Obj *objPtr, int length); /* 59 */ @@ -224,22 +231,26 @@ EXTERN void Tcl_SetByteArrayObj(Tcl_Obj *objPtr, /* 60 */ EXTERN void Tcl_SetDoubleObj(Tcl_Obj *objPtr, double doubleValue); /* 61 */ -EXTERN void Tcl_SetIntObj(Tcl_Obj *objPtr, int intValue); +TCL_DEPRECATED("No longer in use, changed to macro") +void Tcl_SetIntObj(Tcl_Obj *objPtr, int intValue); /* 62 */ EXTERN void Tcl_SetListObj(Tcl_Obj *objPtr, int objc, Tcl_Obj *const objv[]); /* 63 */ -EXTERN void Tcl_SetLongObj(Tcl_Obj *objPtr, long longValue); +TCL_DEPRECATED("No longer in use, changed to macro") +void Tcl_SetLongObj(Tcl_Obj *objPtr, long longValue); /* 64 */ EXTERN void Tcl_SetObjLength(Tcl_Obj *objPtr, int length); /* 65 */ EXTERN void Tcl_SetStringObj(Tcl_Obj *objPtr, const char *bytes, int length); /* 66 */ -EXTERN void Tcl_AddErrorInfo(Tcl_Interp *interp, +TCL_DEPRECATED("No longer in use, changed to macro") +void Tcl_AddErrorInfo(Tcl_Interp *interp, const char *message); /* 67 */ -EXTERN void Tcl_AddObjErrorInfo(Tcl_Interp *interp, +TCL_DEPRECATED("No longer in use, changed to macro") +void Tcl_AddObjErrorInfo(Tcl_Interp *interp, const char *message, int length); /* 68 */ EXTERN void Tcl_AllowExceptions(Tcl_Interp *interp); @@ -422,7 +433,8 @@ EXTERN int Tcl_Eval(Tcl_Interp *interp, const char *script); EXTERN int Tcl_EvalFile(Tcl_Interp *interp, const char *fileName); /* 131 */ -EXTERN int Tcl_EvalObj(Tcl_Interp *interp, Tcl_Obj *objPtr); +TCL_DEPRECATED("No longer in use, changed to macro") +int Tcl_EvalObj(Tcl_Interp *interp, Tcl_Obj *objPtr); /* 132 */ EXTERN void Tcl_EventuallyFree(ClientData clientData, Tcl_FreeProc *freeProc); @@ -549,7 +561,8 @@ EXTERN Tcl_Channel Tcl_GetStdChannel(int type); /* 174 */ EXTERN const char * Tcl_GetStringResult(Tcl_Interp *interp); /* 175 */ -EXTERN const char * Tcl_GetVar(Tcl_Interp *interp, const char *varName, +TCL_DEPRECATED("No longer in use, changed to macro") +const char * Tcl_GetVar(Tcl_Interp *interp, const char *varName, int flags); /* 176 */ EXTERN const char * Tcl_GetVar2(Tcl_Interp *interp, const char *part1, @@ -558,7 +571,8 @@ EXTERN const char * Tcl_GetVar2(Tcl_Interp *interp, const char *part1, EXTERN int Tcl_GlobalEval(Tcl_Interp *interp, const char *command); /* 178 */ -EXTERN int Tcl_GlobalEvalObj(Tcl_Interp *interp, +TCL_DEPRECATED("No longer in use, changed to macro") +int Tcl_GlobalEvalObj(Tcl_Interp *interp, Tcl_Obj *objPtr); /* 179 */ EXTERN int Tcl_HideCommand(Tcl_Interp *interp, @@ -713,7 +727,8 @@ EXTERN void Tcl_SetObjResult(Tcl_Interp *interp, /* 236 */ EXTERN void Tcl_SetStdChannel(Tcl_Channel channel, int type); /* 237 */ -EXTERN const char * Tcl_SetVar(Tcl_Interp *interp, const char *varName, +TCL_DEPRECATED("No longer in use, changed to macro") +const char * Tcl_SetVar(Tcl_Interp *interp, const char *varName, const char *newValue, int flags); /* 238 */ EXTERN const char * Tcl_SetVar2(Tcl_Interp *interp, const char *part1, @@ -743,7 +758,8 @@ EXTERN int Tcl_StringMatch(const char *str, const char *pattern); TCL_DEPRECATED("") int Tcl_TellOld(Tcl_Channel chan); /* 247 */ -EXTERN int Tcl_TraceVar(Tcl_Interp *interp, const char *varName, +TCL_DEPRECATED("No longer in use, changed to macro") +int Tcl_TraceVar(Tcl_Interp *interp, const char *varName, int flags, Tcl_VarTraceProc *proc, ClientData clientData); /* 248 */ @@ -764,13 +780,15 @@ EXTERN void Tcl_UnlinkVar(Tcl_Interp *interp, EXTERN int Tcl_UnregisterChannel(Tcl_Interp *interp, Tcl_Channel chan); /* 253 */ -EXTERN int Tcl_UnsetVar(Tcl_Interp *interp, const char *varName, +TCL_DEPRECATED("No longer in use, changed to macro") +int Tcl_UnsetVar(Tcl_Interp *interp, const char *varName, int flags); /* 254 */ EXTERN int Tcl_UnsetVar2(Tcl_Interp *interp, const char *part1, const char *part2, int flags); /* 255 */ -EXTERN void Tcl_UntraceVar(Tcl_Interp *interp, +TCL_DEPRECATED("No longer in use, changed to macro") +void Tcl_UntraceVar(Tcl_Interp *interp, const char *varName, int flags, Tcl_VarTraceProc *proc, ClientData clientData); @@ -783,7 +801,8 @@ EXTERN void Tcl_UntraceVar2(Tcl_Interp *interp, EXTERN void Tcl_UpdateLinkedVar(Tcl_Interp *interp, const char *varName); /* 258 */ -EXTERN int Tcl_UpVar(Tcl_Interp *interp, const char *frameName, +TCL_DEPRECATED("No longer in use, changed to macro") +int Tcl_UpVar(Tcl_Interp *interp, const char *frameName, const char *varName, const char *localName, int flags); /* 259 */ @@ -793,7 +812,8 @@ EXTERN int Tcl_UpVar2(Tcl_Interp *interp, const char *frameName, /* 260 */ EXTERN int Tcl_VarEval(Tcl_Interp *interp, ...); /* 261 */ -EXTERN ClientData Tcl_VarTraceInfo(Tcl_Interp *interp, +TCL_DEPRECATED("No longer in use, changed to macro") +ClientData Tcl_VarTraceInfo(Tcl_Interp *interp, const char *varName, int flags, Tcl_VarTraceProc *procPtr, ClientData prevClientData); @@ -825,17 +845,20 @@ EXTERN char * Tcl_HashStats(Tcl_HashTable *tablePtr); EXTERN const char * Tcl_ParseVar(Tcl_Interp *interp, const char *start, const char **termPtr); /* 271 */ -EXTERN const char * Tcl_PkgPresent(Tcl_Interp *interp, const char *name, +TCL_DEPRECATED("No longer in use, changed to macro") +const char * Tcl_PkgPresent(Tcl_Interp *interp, const char *name, const char *version, int exact); /* 272 */ EXTERN const char * Tcl_PkgPresentEx(Tcl_Interp *interp, const char *name, const char *version, int exact, void *clientDataPtr); /* 273 */ -EXTERN int Tcl_PkgProvide(Tcl_Interp *interp, const char *name, +TCL_DEPRECATED("No longer in use, changed to macro") +int Tcl_PkgProvide(Tcl_Interp *interp, const char *name, const char *version); /* 274 */ -EXTERN const char * Tcl_PkgRequire(Tcl_Interp *interp, const char *name, +TCL_DEPRECATED("No longer in use, changed to macro") +const char * Tcl_PkgRequire(Tcl_Interp *interp, const char *name, const char *version, int exact); /* 275 */ TCL_DEPRECATED("see TIP #422") @@ -1125,7 +1148,8 @@ EXTERN int Tcl_GetCharLength(Tcl_Obj *objPtr); /* 381 */ EXTERN int Tcl_GetUniChar(Tcl_Obj *objPtr, int index); /* 382 */ -EXTERN Tcl_UniChar * Tcl_GetUnicode(Tcl_Obj *objPtr); +TCL_DEPRECATED("No longer in use, changed to macro") +Tcl_UniChar * Tcl_GetUnicode(Tcl_Obj *objPtr); /* 383 */ EXTERN Tcl_Obj * Tcl_GetRange(Tcl_Obj *objPtr, int first, int last); /* 384 */ @@ -1887,11 +1911,11 @@ typedef struct TclStubs { void (*tcl_DbDecrRefCount) (Tcl_Obj *objPtr, const char *file, int line); /* 19 */ void (*tcl_DbIncrRefCount) (Tcl_Obj *objPtr, const char *file, int line); /* 20 */ int (*tcl_DbIsShared) (Tcl_Obj *objPtr, const char *file, int line); /* 21 */ - Tcl_Obj * (*tcl_DbNewBooleanObj) (int boolValue, const char *file, int line); /* 22 */ + TCL_DEPRECATED_API("No longer in use, changed to macro") Tcl_Obj * (*tcl_DbNewBooleanObj) (int boolValue, const char *file, int line); /* 22 */ Tcl_Obj * (*tcl_DbNewByteArrayObj) (const unsigned char *bytes, int length, const char *file, int line); /* 23 */ Tcl_Obj * (*tcl_DbNewDoubleObj) (double doubleValue, const char *file, int line); /* 24 */ Tcl_Obj * (*tcl_DbNewListObj) (int objc, Tcl_Obj *const *objv, const char *file, int line); /* 25 */ - Tcl_Obj * (*tcl_DbNewLongObj) (long longValue, const char *file, int line); /* 26 */ + TCL_DEPRECATED_API("No longer in use, changed to macro") Tcl_Obj * (*tcl_DbNewLongObj) (long longValue, const char *file, int line); /* 26 */ Tcl_Obj * (*tcl_DbNewObj) (const char *file, int line); /* 27 */ Tcl_Obj * (*tcl_DbNewStringObj) (const char *bytes, int length, const char *file, int line); /* 28 */ Tcl_Obj * (*tcl_DuplicateObj) (Tcl_Obj *objPtr); /* 29 */ @@ -1901,7 +1925,7 @@ typedef struct TclStubs { unsigned char * (*tcl_GetByteArrayFromObj) (Tcl_Obj *objPtr, int *lengthPtr); /* 33 */ int (*tcl_GetDouble) (Tcl_Interp *interp, const char *src, double *doublePtr); /* 34 */ int (*tcl_GetDoubleFromObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, double *doublePtr); /* 35 */ - int (*tcl_GetIndexFromObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, const char *const *tablePtr, const char *msg, int flags, int *indexPtr); /* 36 */ + TCL_DEPRECATED_API("No longer in use, changed to macro") int (*tcl_GetIndexFromObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, const char *const *tablePtr, const char *msg, int flags, int *indexPtr); /* 36 */ int (*tcl_GetInt) (Tcl_Interp *interp, const char *src, int *intPtr); /* 37 */ int (*tcl_GetIntFromObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, int *intPtr); /* 38 */ int (*tcl_GetLongFromObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, long *longPtr); /* 39 */ @@ -1914,25 +1938,25 @@ typedef struct TclStubs { int (*tcl_ListObjIndex) (Tcl_Interp *interp, Tcl_Obj *listPtr, int index, Tcl_Obj **objPtrPtr); /* 46 */ int (*tcl_ListObjLength) (Tcl_Interp *interp, Tcl_Obj *listPtr, int *lengthPtr); /* 47 */ int (*tcl_ListObjReplace) (Tcl_Interp *interp, Tcl_Obj *listPtr, int first, int count, int objc, Tcl_Obj *const objv[]); /* 48 */ - Tcl_Obj * (*tcl_NewBooleanObj) (int boolValue); /* 49 */ + TCL_DEPRECATED_API("No longer in use, changed to macro") Tcl_Obj * (*tcl_NewBooleanObj) (int boolValue); /* 49 */ Tcl_Obj * (*tcl_NewByteArrayObj) (const unsigned char *bytes, int length); /* 50 */ Tcl_Obj * (*tcl_NewDoubleObj) (double doubleValue); /* 51 */ - Tcl_Obj * (*tcl_NewIntObj) (int intValue); /* 52 */ + TCL_DEPRECATED_API("No longer in use, changed to macro") Tcl_Obj * (*tcl_NewIntObj) (int intValue); /* 52 */ Tcl_Obj * (*tcl_NewListObj) (int objc, Tcl_Obj *const objv[]); /* 53 */ - Tcl_Obj * (*tcl_NewLongObj) (long longValue); /* 54 */ + TCL_DEPRECATED_API("No longer in use, changed to macro") Tcl_Obj * (*tcl_NewLongObj) (long longValue); /* 54 */ Tcl_Obj * (*tcl_NewObj) (void); /* 55 */ Tcl_Obj * (*tcl_NewStringObj) (const char *bytes, int length); /* 56 */ - void (*tcl_SetBooleanObj) (Tcl_Obj *objPtr, int boolValue); /* 57 */ + TCL_DEPRECATED_API("No longer in use, changed to macro") void (*tcl_SetBooleanObj) (Tcl_Obj *objPtr, int boolValue); /* 57 */ unsigned char * (*tcl_SetByteArrayLength) (Tcl_Obj *objPtr, int length); /* 58 */ void (*tcl_SetByteArrayObj) (Tcl_Obj *objPtr, const unsigned char *bytes, int length); /* 59 */ void (*tcl_SetDoubleObj) (Tcl_Obj *objPtr, double doubleValue); /* 60 */ - void (*tcl_SetIntObj) (Tcl_Obj *objPtr, int intValue); /* 61 */ + TCL_DEPRECATED_API("No longer in use, changed to macro") void (*tcl_SetIntObj) (Tcl_Obj *objPtr, int intValue); /* 61 */ void (*tcl_SetListObj) (Tcl_Obj *objPtr, int objc, Tcl_Obj *const objv[]); /* 62 */ - void (*tcl_SetLongObj) (Tcl_Obj *objPtr, long longValue); /* 63 */ + TCL_DEPRECATED_API("No longer in use, changed to macro") void (*tcl_SetLongObj) (Tcl_Obj *objPtr, long longValue); /* 63 */ void (*tcl_SetObjLength) (Tcl_Obj *objPtr, int length); /* 64 */ void (*tcl_SetStringObj) (Tcl_Obj *objPtr, const char *bytes, int length); /* 65 */ - void (*tcl_AddErrorInfo) (Tcl_Interp *interp, const char *message); /* 66 */ - void (*tcl_AddObjErrorInfo) (Tcl_Interp *interp, const char *message, int length); /* 67 */ + TCL_DEPRECATED_API("No longer in use, changed to macro") void (*tcl_AddErrorInfo) (Tcl_Interp *interp, const char *message); /* 66 */ + TCL_DEPRECATED_API("No longer in use, changed to macro") void (*tcl_AddObjErrorInfo) (Tcl_Interp *interp, const char *message, int length); /* 67 */ void (*tcl_AllowExceptions) (Tcl_Interp *interp); /* 68 */ void (*tcl_AppendElement) (Tcl_Interp *interp, const char *element); /* 69 */ void (*tcl_AppendResult) (Tcl_Interp *interp, ...); /* 70 */ @@ -1996,7 +2020,7 @@ typedef struct TclStubs { const char * (*tcl_ErrnoMsg) (int err); /* 128 */ int (*tcl_Eval) (Tcl_Interp *interp, const char *script); /* 129 */ int (*tcl_EvalFile) (Tcl_Interp *interp, const char *fileName); /* 130 */ - int (*tcl_EvalObj) (Tcl_Interp *interp, Tcl_Obj *objPtr); /* 131 */ + TCL_DEPRECATED_API("No longer in use, changed to macro") int (*tcl_EvalObj) (Tcl_Interp *interp, Tcl_Obj *objPtr); /* 131 */ void (*tcl_EventuallyFree) (ClientData clientData, Tcl_FreeProc *freeProc); /* 132 */ TCL_NORETURN1 void (*tcl_Exit) (int status); /* 133 */ int (*tcl_ExposeCommand) (Tcl_Interp *interp, const char *hiddenCmdToken, const char *cmdName); /* 134 */ @@ -2048,10 +2072,10 @@ typedef struct TclStubs { Tcl_Interp * (*tcl_GetSlave) (Tcl_Interp *interp, const char *slaveName); /* 172 */ Tcl_Channel (*tcl_GetStdChannel) (int type); /* 173 */ const char * (*tcl_GetStringResult) (Tcl_Interp *interp); /* 174 */ - const char * (*tcl_GetVar) (Tcl_Interp *interp, const char *varName, int flags); /* 175 */ + TCL_DEPRECATED_API("No longer in use, changed to macro") const char * (*tcl_GetVar) (Tcl_Interp *interp, const char *varName, int flags); /* 175 */ const char * (*tcl_GetVar2) (Tcl_Interp *interp, const char *part1, const char *part2, int flags); /* 176 */ int (*tcl_GlobalEval) (Tcl_Interp *interp, const char *command); /* 177 */ - int (*tcl_GlobalEvalObj) (Tcl_Interp *interp, Tcl_Obj *objPtr); /* 178 */ + TCL_DEPRECATED_API("No longer in use, changed to macro") int (*tcl_GlobalEvalObj) (Tcl_Interp *interp, Tcl_Obj *objPtr); /* 178 */ int (*tcl_HideCommand) (Tcl_Interp *interp, const char *cmdName, const char *hiddenCmdToken); /* 179 */ int (*tcl_Init) (Tcl_Interp *interp); /* 180 */ void (*tcl_InitHashTable) (Tcl_HashTable *tablePtr, int keyType); /* 181 */ @@ -2110,7 +2134,7 @@ typedef struct TclStubs { void (*tcl_SetObjErrorCode) (Tcl_Interp *interp, Tcl_Obj *errorObjPtr); /* 234 */ void (*tcl_SetObjResult) (Tcl_Interp *interp, Tcl_Obj *resultObjPtr); /* 235 */ void (*tcl_SetStdChannel) (Tcl_Channel channel, int type); /* 236 */ - const char * (*tcl_SetVar) (Tcl_Interp *interp, const char *varName, const char *newValue, int flags); /* 237 */ + TCL_DEPRECATED_API("No longer in use, changed to macro") const char * (*tcl_SetVar) (Tcl_Interp *interp, const char *varName, const char *newValue, int flags); /* 237 */ const char * (*tcl_SetVar2) (Tcl_Interp *interp, const char *part1, const char *part2, const char *newValue, int flags); /* 238 */ const char * (*tcl_SignalId) (int sig); /* 239 */ const char * (*tcl_SignalMsg) (int sig); /* 240 */ @@ -2120,21 +2144,21 @@ typedef struct TclStubs { void (*tcl_StaticPackage) (Tcl_Interp *interp, const char *pkgName, Tcl_PackageInitProc *initProc, Tcl_PackageInitProc *safeInitProc); /* 244 */ int (*tcl_StringMatch) (const char *str, const char *pattern); /* 245 */ TCL_DEPRECATED_API("") int (*tcl_TellOld) (Tcl_Channel chan); /* 246 */ - int (*tcl_TraceVar) (Tcl_Interp *interp, const char *varName, int flags, Tcl_VarTraceProc *proc, ClientData clientData); /* 247 */ + TCL_DEPRECATED_API("No longer in use, changed to macro") int (*tcl_TraceVar) (Tcl_Interp *interp, const char *varName, int flags, Tcl_VarTraceProc *proc, ClientData clientData); /* 247 */ int (*tcl_TraceVar2) (Tcl_Interp *interp, const char *part1, const char *part2, int flags, Tcl_VarTraceProc *proc, ClientData clientData); /* 248 */ char * (*tcl_TranslateFileName) (Tcl_Interp *interp, const char *name, Tcl_DString *bufferPtr); /* 249 */ int (*tcl_Ungets) (Tcl_Channel chan, const char *str, int len, int atHead); /* 250 */ void (*tcl_UnlinkVar) (Tcl_Interp *interp, const char *varName); /* 251 */ int (*tcl_UnregisterChannel) (Tcl_Interp *interp, Tcl_Channel chan); /* 252 */ - int (*tcl_UnsetVar) (Tcl_Interp *interp, const char *varName, int flags); /* 253 */ + TCL_DEPRECATED_API("No longer in use, changed to macro") int (*tcl_UnsetVar) (Tcl_Interp *interp, const char *varName, int flags); /* 253 */ int (*tcl_UnsetVar2) (Tcl_Interp *interp, const char *part1, const char *part2, int flags); /* 254 */ - void (*tcl_UntraceVar) (Tcl_Interp *interp, const char *varName, int flags, Tcl_VarTraceProc *proc, ClientData clientData); /* 255 */ + TCL_DEPRECATED_API("No longer in use, changed to macro") void (*tcl_UntraceVar) (Tcl_Interp *interp, const char *varName, int flags, Tcl_VarTraceProc *proc, ClientData clientData); /* 255 */ void (*tcl_UntraceVar2) (Tcl_Interp *interp, const char *part1, const char *part2, int flags, Tcl_VarTraceProc *proc, ClientData clientData); /* 256 */ void (*tcl_UpdateLinkedVar) (Tcl_Interp *interp, const char *varName); /* 257 */ - int (*tcl_UpVar) (Tcl_Interp *interp, const char *frameName, const char *varName, const char *localName, int flags); /* 258 */ + TCL_DEPRECATED_API("No longer in use, changed to macro") int (*tcl_UpVar) (Tcl_Interp *interp, const char *frameName, const char *varName, const char *localName, int flags); /* 258 */ int (*tcl_UpVar2) (Tcl_Interp *interp, const char *frameName, const char *part1, const char *part2, const char *localName, int flags); /* 259 */ int (*tcl_VarEval) (Tcl_Interp *interp, ...); /* 260 */ - ClientData (*tcl_VarTraceInfo) (Tcl_Interp *interp, const char *varName, int flags, Tcl_VarTraceProc *procPtr, ClientData prevClientData); /* 261 */ + TCL_DEPRECATED_API("No longer in use, changed to macro") ClientData (*tcl_VarTraceInfo) (Tcl_Interp *interp, const char *varName, int flags, Tcl_VarTraceProc *procPtr, ClientData prevClientData); /* 261 */ ClientData (*tcl_VarTraceInfo2) (Tcl_Interp *interp, const char *part1, const char *part2, int flags, Tcl_VarTraceProc *procPtr, ClientData prevClientData); /* 262 */ int (*tcl_Write) (Tcl_Channel chan, const char *s, int slen); /* 263 */ void (*tcl_WrongNumArgs) (Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], const char *message); /* 264 */ @@ -2144,10 +2168,10 @@ typedef struct TclStubs { TCL_DEPRECATED_API("see TIP #422") void (*tcl_AppendStringsToObjVA) (Tcl_Obj *objPtr, va_list argList); /* 268 */ char * (*tcl_HashStats) (Tcl_HashTable *tablePtr); /* 269 */ const char * (*tcl_ParseVar) (Tcl_Interp *interp, const char *start, const char **termPtr); /* 270 */ - const char * (*tcl_PkgPresent) (Tcl_Interp *interp, const char *name, const char *version, int exact); /* 271 */ + TCL_DEPRECATED_API("No longer in use, changed to macro") const char * (*tcl_PkgPresent) (Tcl_Interp *interp, const char *name, const char *version, int exact); /* 271 */ const char * (*tcl_PkgPresentEx) (Tcl_Interp *interp, const char *name, const char *version, int exact, void *clientDataPtr); /* 272 */ - int (*tcl_PkgProvide) (Tcl_Interp *interp, const char *name, const char *version); /* 273 */ - const char * (*tcl_PkgRequire) (Tcl_Interp *interp, const char *name, const char *version, int exact); /* 274 */ + TCL_DEPRECATED_API("No longer in use, changed to macro") int (*tcl_PkgProvide) (Tcl_Interp *interp, const char *name, const char *version); /* 273 */ + TCL_DEPRECATED_API("No longer in use, changed to macro") const char * (*tcl_PkgRequire) (Tcl_Interp *interp, const char *name, const char *version, int exact); /* 274 */ TCL_DEPRECATED_API("see TIP #422") void (*tcl_SetErrorCodeVA) (Tcl_Interp *interp, va_list argList); /* 275 */ TCL_DEPRECATED_API("see TIP #422") int (*tcl_VarEvalVA) (Tcl_Interp *interp, va_list argList); /* 276 */ Tcl_Pid (*tcl_WaitPid) (Tcl_Pid pid, int *statPtr, int options); /* 277 */ @@ -2255,7 +2279,7 @@ typedef struct TclStubs { void (*tcl_SetUnicodeObj) (Tcl_Obj *objPtr, const Tcl_UniChar *unicode, int numChars); /* 379 */ int (*tcl_GetCharLength) (Tcl_Obj *objPtr); /* 380 */ int (*tcl_GetUniChar) (Tcl_Obj *objPtr, int index); /* 381 */ - Tcl_UniChar * (*tcl_GetUnicode) (Tcl_Obj *objPtr); /* 382 */ + TCL_DEPRECATED_API("No longer in use, changed to macro") Tcl_UniChar * (*tcl_GetUnicode) (Tcl_Obj *objPtr); /* 382 */ Tcl_Obj * (*tcl_GetRange) (Tcl_Obj *objPtr, int first, int last); /* 383 */ void (*tcl_AppendUnicodeToObj) (Tcl_Obj *objPtr, const Tcl_UniChar *unicode, int length); /* 384 */ int (*tcl_RegExpMatchObj) (Tcl_Interp *interp, Tcl_Obj *textObj, Tcl_Obj *patternObj); /* 385 */ @@ -3974,9 +3998,11 @@ extern const TclStubs *tclStubsPtr; #undef Tcl_DbNewLongObj #define Tcl_DbNewLongObj(value, file, line) Tcl_DbNewWideIntObj((long)(value), file, line) #undef Tcl_SetIntObj -#define Tcl_SetIntObj(objPtr, value) Tcl_SetWideIntObj(objPtr, (int)(value)) +#define Tcl_SetIntObj(objPtr, value) Tcl_SetWideIntObj((objPtr), (int)(value)) #undef Tcl_SetLongObj -#define Tcl_SetLongObj(objPtr, value) Tcl_SetWideIntObj(objPtr, (long)(value)) +#define Tcl_SetLongObj(objPtr, value) Tcl_SetWideIntObj((objPtr), (long)(value)) +#undef Tcl_GetUnicode +#define Tcl_GetUnicode(objPtr) Tcl_GetUnicodeFromObj((objPtr), NULL) /* * Deprecated Tcl procedures: diff --git a/generic/tclStringObj.c b/generic/tclStringObj.c index bed23a0..3bb6112 100644 --- a/generic/tclStringObj.c +++ b/generic/tclStringObj.c @@ -606,6 +606,8 @@ Tcl_GetUniChar( *---------------------------------------------------------------------- */ +#ifndef TCL_NO_DEPRECATED +#undef Tcl_GetUnicode Tcl_UniChar * Tcl_GetUnicode( Tcl_Obj *objPtr) /* The object to find the unicode string @@ -613,6 +615,7 @@ Tcl_GetUnicode( { return Tcl_GetUnicodeFromObj(objPtr, NULL); } +#endif /* TCL_NO_DEPRECATED */ /* *---------------------------------------------------------------------- diff --git a/generic/tclStubInit.c b/generic/tclStubInit.c index 7ce0758..2bd4de9 100644 --- a/generic/tclStubInit.c +++ b/generic/tclStubInit.c @@ -34,6 +34,7 @@ #undef Tcl_DbNewLongObj #undef Tcl_NewObj #undef Tcl_NewStringObj +#undef Tcl_GetUnicode #undef Tcl_DumpActiveMemory #undef Tcl_ValidateAllMemory #undef Tcl_FindHashEntry @@ -402,6 +403,7 @@ static int uniCharNcasecmp(const Tcl_UniChar *ucs, const Tcl_UniChar *uct, unsig # define TclpGmtime 0 # define TclpLocaltime_unix 0 # define TclpGmtime_unix 0 +# define Tcl_GetUnicode 0 #else /* TCL_NO_DEPRECATED */ # define Tcl_SeekOld seekOld # define Tcl_TellOld tellOld -- cgit v0.12 From 367ce9ad482394057c4d895abb67ffe50f1ac015 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Thu, 5 Jul 2018 19:39:19 +0000 Subject: tclDictObj.c:366: warning: dereferencing type-punned pointer will break strict-aliasing rules Prevent this warning, which gcc 4.4 (a.o.) gives on this construct. void pointers work well already in whatever assignment. --- generic/tclDictObj.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generic/tclDictObj.c b/generic/tclDictObj.c index 2eff1ff..32234a3 100644 --- a/generic/tclDictObj.c +++ b/generic/tclDictObj.c @@ -153,7 +153,7 @@ typedef struct Dict { * must be assignable as well as readable. */ -#define DICT(dictObj) (*((Dict **)&(dictObj)->internalRep.twoPtrValue.ptr1)) +#define DICT(dictObj) ((dictObj)->internalRep.twoPtrValue.ptr1) /* * The structure below defines the dictionary object type by means of -- cgit v0.12 From 969f9f571cda6f6b8db32f8b9cdf922715b37c43 Mon Sep 17 00:00:00 2001 From: dkf Date: Fri, 6 Jul 2018 13:50:54 +0000 Subject: Improving the singleton --- doc/abstract.n | 4 +++- doc/define.n | 2 +- doc/singleton.n | 20 +++++++++++++------- generic/tclOOScript.h | 7 ++++++- tests/ooUtil.test | 25 +++++++++++++++++++++++-- 5 files changed, 46 insertions(+), 12 deletions(-) diff --git a/doc/abstract.n b/doc/abstract.n index c11202b..022c24b 100644 --- a/doc/abstract.n +++ b/doc/abstract.n @@ -36,7 +36,9 @@ The \fBoo::abstract\fR class does not define an explicit constructor; this means that it is effectively the same as the constructor of the \fBoo::class\fR class. .SS DESTRUCTOR -The \fBoo::abstract\fR class does not define an explicit destructor. +The \fBoo::abstract\fR class does not define an explicit destructor; +destroying an instance of it is just like destroying an ordinary class (and +will destroy all its subclasses). .SS "EXPORTED METHODS" The \fBoo::abstract\fR class defines no new exported methods. .SS "NON-EXPORTED METHODS" diff --git a/doc/define.n b/doc/define.n index 099e59f..860218f 100644 --- a/doc/define.n +++ b/doc/define.n @@ -1,5 +1,5 @@ '\" -'\" Copyright (c) 2007 Donal K. Fellows +'\" Copyright (c) 2007-2018 Donal K. Fellows '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. diff --git a/doc/singleton.n b/doc/singleton.n index 6319abe..568a8bd 100644 --- a/doc/singleton.n +++ b/doc/singleton.n @@ -32,16 +32,20 @@ not recommended to inherit from a singleton class; singleton-ness is \fInot\fR inherited. It is not recommended that a singleton class's constructor take any arguments. .PP -Instances have their\fB destroy\fR method (from \fBoo::object\fR) unexported -in order to discourage destruction of the object, but destruction remains -possible if strictly necessary (e.g., by destroying the class or using -\fBrename\fR to delete it). +Instances have their\fB destroy\fR method overridden with a method that always +returns an error in order to discourage destruction of the object, but +destruction remains possible if strictly necessary (e.g., by destroying the +class or using \fBrename\fR to delete it). They also have a (non-exported) +\fB\fR method defined on them that similarly always returns errors to +make attempts to use the singleton instance with \fBoo::copy\fR fail. .SS CONSTRUCTOR The \fBoo::singleton\fR class does not define an explicit constructor; this means that it is effectively the same as the constructor of the \fBoo::class\fR class. .SS DESTRUCTOR -The \fBoo::singleton\fR class does not define an explicit destructor. +The \fBoo::singleton\fR class does not define an explicit destructor; +destroying an instance of it is just like destroying an ordinary class (and +will destroy the singleton object). .SS "EXPORTED METHODS" .TP \fIcls \fBnew \fR?\fIarg ...\fR? @@ -53,11 +57,13 @@ manufactured; that construction is via the \fBoo::class\fR class's \fBnew\fR method. .RS .PP -This is an override of the behaviour of a superclass's method. +This is an override of the behaviour of a superclass's method with an +identical call signature to the superclass's implementation. .RE .SS "NON-EXPORTED METHODS" The \fBoo::singleton\fR class explicitly states that \fBcreate\fR and -\fBcreateWithNamespace\fR are unexported. +\fBcreateWithNamespace\fR are unexported; callers should not assume that they +have control over either the name or the namespace name of the singleton instance. .SH EXAMPLE .PP This example demonstrates that there is only one instance even though the diff --git a/generic/tclOOScript.h b/generic/tclOOScript.h index 237bff5..d96ee76 100644 --- a/generic/tclOOScript.h +++ b/generic/tclOOScript.h @@ -161,7 +161,12 @@ static const char *tclOOSetupScript = " method new args {\n" " if {![info exists object] || ![info object isa object $object]} {\n" " set object [next {*}$args]\n" -" ::oo::objdefine $object unexport destroy\n" +" ::oo::objdefine $object method destroy {} {\n" +" return -code error {may not destroy a singleton object}\n" +" }\n" +" ::oo::objdefine $object method {originObject} {\n" +" return -code error {may not clone a singleton object}\n" +" }\n" " }\n" " return $object\n" " }\n" diff --git a/tests/ooUtil.test b/tests/ooUtil.test index 28ab9c7..e00c70c 100644 --- a/tests/ooUtil.test +++ b/tests/ooUtil.test @@ -298,12 +298,33 @@ test ooUtil-4.1 {TIP 478: singleton} -setup { set z [xyz new] set code [catch {$x destroy} msg] set p [xyz new] - lappend code $msg [catch {rename $x ""}] + lappend code [catch {rename $x ""}] set q [xyz new] string map [list $x ONE $q TWO] [list {*}$code $x $y $z $p $q [xyz new]] } -cleanup { parent destroy -} -result {1 {object "ONE" has no visible methods} 0 ONE ONE ONE ONE TWO TWO} +} -result {1 0 ONE ONE ONE ONE TWO TWO} +test ooUtil-4.2 {TIP 478: singleton errors} -setup { + oo::class create parent +} -body { + oo::singleton create xyz { + superclass parent + } + [xyz new] destroy +} -returnCodes error -cleanup { + parent destroy +} -result {may not destroy a singleton object} +test ooUtil-4.3 {TIP 478: singleton errors} -setup { + oo::class create parent +} -body { + oo::singleton create xyz { + superclass parent + } + oo::copy [xyz new] +} -returnCodes error -cleanup { + parent destroy +} -result {may not clone a singleton object} + test ooUtil-5.1 {TIP 478: abstract} -setup { oo::class create parent -- cgit v0.12 From 5a06fd4bcf87ea7fc607798714be8886927c1b15 Mon Sep 17 00:00:00 2001 From: dkf Date: Sat, 7 Jul 2018 08:22:13 +0000 Subject: Document the [myclass] command; someone might find it useful besides me. --- doc/my.n | 60 +++++++++++++++++++++++++++++++++++++++++++++------ generic/tclOO.c | 34 ++++++++++++++--------------- generic/tclOOScript.h | 2 +- 3 files changed, 72 insertions(+), 24 deletions(-) diff --git a/doc/my.n b/doc/my.n index 26d861a..262186f 100644 --- a/doc/my.n +++ b/doc/my.n @@ -9,30 +9,45 @@ .BS '\" Note: do not modify the .SH NAME line immediately below! .SH NAME -my \- invoke any method of current object +my, myclass \- invoke any method of current object or its class .SH SYNOPSIS .nf package require TclOO \fBmy\fI methodName\fR ?\fIarg ...\fR? +\fBmyclass\fI methodName\fR ?\fIarg ...\fR? .fi .BE .SH DESCRIPTION .PP The \fBmy\fR command is used to allow methods of objects to invoke methods -of the object (or its class). In particular, the set of valid values for +of the object (or its class), +.VS TIP478 +and he \fBmyclass\fR command is used to allow methods of objects to invoke +methods of the current class of the object \fIas an object\fR. +.VE TIP478 +In particular, the set of valid values for \fImethodName\fR is the set of all methods supported by an object and its superclasses, including those that are not exported .VS TIP500 and private methods of the object or class when used within another method defined by that object or class. .VE TIP500 -The object upon which the method is invoked is the one that owns the namespace -that the \fBmy\fR command is contained in initially (\fBNB:\fR the link +.PP +The object upon which the method is invoked via \fBmy\fR is the one that owns +the namespace that the \fBmy\fR command is contained in initially (\fBNB:\fR the link remains if the command is renamed), which is the currently invoked object by default. +.VS TIP478 +Similarly, the object on which the method is invoked via \fBmyclass\fR is the +object that is the current class of the object that owns the namespace that +the \fBmyclass\fR command is contained in initially. As with \fBmy\fR, the +link remains even if the command is renamed into another namespace, and +defaults to being the manufacturing class of the current object. +.VE TIP478 .PP -Each object has its own \fBmy\fR command, contained in its instance namespace. +Each object has its own \fBmy\fR and \fBmyclass\fR commands, contained in its +instance namespace. .SH EXAMPLES .PP This example shows basic use of \fBmy\fR to use the \fBvariables\fR method of @@ -54,7 +69,8 @@ o count \fI\(-> prints "3"\fR .PP This example shows how you can use \fBmy\fR to make callbacks to private methods from outside the object (from a \fBtrace\fR), using -\fBnamespace code\fR to enter the correct context: +\fBnamespace code\fR to enter the correct context. (See the \fBcallback\fR +command for the recommended way of doing this.) .PP .CS oo::class create HasCallback { @@ -73,6 +89,38 @@ set o [HasCallback new] trace add variable xyz write [$o makeCallback] set xyz "called" \fI\(-> prints "callback: xyz {} write"\fR .CE +.PP +.VS TIP478 +This example shows how to access a private method of a class from an instance +of that class. (See the \fBclassmethod\fR declaration in \fBoo::define\fR for +a higher level interface for doing this.) +.PP +.CS +oo::class create CountedSteps { + self { + variable count + method Count {} { + return [incr count] + } + } + method advanceTwice {} { + puts "in [self] step A: [\fBmyclass\fR Count]" + puts "in [self] step B: [\fBmyclass\fR Count]" + } +} + +CountedSteps create x +CountedSteps create y +x advanceTwice \fI\(-> prints "in ::x step A: 1"\fR + \fI\(-> prints "in ::x step B: 2"\fR +y advanceTwice \fI\(-> prints "in ::y step A: 3"\fR + \fI\(-> prints "in ::y step B: 4"\fR +x advanceTwice \fI\(-> prints "in ::x step A: 5"\fR + \fI\(-> prints "in ::x step B: 6"\fR +y advanceTwice \fI\(-> prints "in ::y step A: 7"\fR + \fI\(-> prints "in ::y step B: 8"\fR +.CE +.VE TIP478 .SH "SEE ALSO" next(n), oo::object(n), self(n) .SH KEYWORDS diff --git a/generic/tclOO.c b/generic/tclOO.c index 8229dc1..630e977 100644 --- a/generic/tclOO.c +++ b/generic/tclOO.c @@ -108,7 +108,7 @@ static int MyClassObjCmd(ClientData clientData, static int MyClassNRObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv); -static void MyClassDeletedCmd(ClientData clientData); +static void MyClassDeleted(ClientData clientData); /* * Methods in the oo::object and oo::class classes. First, we define a helper @@ -754,9 +754,9 @@ AllocObject( oPtr->myCommand = TclNRCreateCommandInNs(interp, "my", oPtr->namespacePtr, PrivateObjectCmd, PrivateNRObjectCmd, oPtr, MyDeleted); - oPtr->myclassCommand = TclNRCreateCommandInNs(interp, " :my:class", + oPtr->myclassCommand = TclNRCreateCommandInNs(interp, "myclass", oPtr->namespacePtr, MyClassObjCmd, MyClassNRObjCmd, oPtr, - MyClassDeletedCmd); + MyClassDeleted); return oPtr; } @@ -784,12 +784,12 @@ SquelchCachedName( /* * ---------------------------------------------------------------------- * - * MyDeleted -- + * MyDeleted, MyClassDeleted -- * - * This callback is triggered when the object's [my] command is deleted - * by any mechanism. It just marks the object as not having a [my] - * command, and so prevents cleanup of that when the object itself is - * deleted. + * These callbacks are triggered when the object's [my] or [myclass] + * commands are deleted by any mechanism. They just mark the object as + * not having a [my] command or [myclass] command, and so prevent cleanup + * of those commands when the object itself is deleted. * * ---------------------------------------------------------------------- */ @@ -803,6 +803,14 @@ MyDeleted( oPtr->myCommand = NULL; } + +static void +MyClassDeleted( + ClientData clientData) +{ + Object *oPtr = clientData; + oPtr->myclassCommand = NULL; +} /* * ---------------------------------------------------------------------- @@ -2501,7 +2509,7 @@ TclOOInvokeObject( /* * ---------------------------------------------------------------------- * - * MyClassObjCmd, MyClassNRObjCmd, MyClassDeletedCmd -- + * MyClassObjCmd, MyClassNRObjCmd -- * * Special trap door to allow an object to delegate simply to its class. * @@ -2534,14 +2542,6 @@ MyClassNRObjCmd( return TclOOObjectCmdCore(oPtr->selfCls->thisPtr, interp, objc, objv, 0, NULL); } - -static void -MyClassDeletedCmd( - ClientData clientData) -{ - Object *oPtr = clientData; - oPtr->myclassCommand = NULL; -} /* * ---------------------------------------------------------------------- diff --git a/generic/tclOOScript.h b/generic/tclOOScript.h index d96ee76..4b58337 100644 --- a/generic/tclOOScript.h +++ b/generic/tclOOScript.h @@ -85,7 +85,7 @@ static const char *tclOOSetupScript = " ::oo::define [::oo::DelegateName $cls] method $name $args $body\n" " }\n" " # Make the connection by forwarding\n" -" tailcall forward $name { :my:class} $name\n" +" tailcall forward $name myclass $name\n" "}\n" "proc ::oo::MixinClassDelegates {class} {\n" -- cgit v0.12 From 27110774bd87b00612e7c3ff97d7af542d364d42 Mon Sep 17 00:00:00 2001 From: dkf Date: Sat, 7 Jul 2018 08:45:00 +0000 Subject: Added direct tests for [myclass] --- tests/oo.test | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/tests/oo.test b/tests/oo.test index 7e0f12e..b2c269b 100644 --- a/tests/oo.test +++ b/tests/oo.test @@ -4845,6 +4845,59 @@ test oo-40.3 {TIP 500: private and unexport} -setup { } -cleanup { cls destroy } -result {{} {} foo {} foo {}} + +test oo-41.1 {TIP 478: myclass command, including class morphing} -setup { + oo::class create parent + set result {} +} -body { + oo::class create cls1 { + superclass parent + self method count {} { + my variable c + incr c + } + method act {} { + myclass count + } + } + cls1 create x + lappend result [x act] [x act] + cls1 create y + lappend result [y act] [y act] [x act] + oo::class create cls2 { + superclass cls1 + self method count {} { + my variable d + expr {1.0 * [incr d]} + } + } + oo::objdefine x {class cls2} + lappend result [x act] [y act] [x act] [y act] +} -cleanup { + parent destroy +} -result {1 2 3 4 5 1.0 6 2.0 7} +test oo-41.2 {TIP 478: myclass command cleanup} -setup { + oo::class create parent + set result {} +} -body { + oo::class create cls1 { + superclass parent + self method hi {} { + return "this is [self]" + } + method hi {} { + return "this is [self]" + } + } + cls1 create x + rename [info object namespace x]::my foo + rename [info object namespace x]::myclass bar + lappend result [cls1 hi] [x hi] [foo hi] [bar hi] + x destroy + lappend result [catch {foo hi}] [catch {bar hi}] +} -cleanup { + parent destroy +} -result {{this is ::cls1} {this is ::x} {this is ::x} {this is ::cls1} 1 1} cleanupTests return -- cgit v0.12 From d0f8889c8f63ea1c95b2d89ad98354657cf2f10f Mon Sep 17 00:00:00 2001 From: dkf Date: Sat, 7 Jul 2018 08:57:49 +0000 Subject: And another test --- tests/oo.test | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tests/oo.test b/tests/oo.test index b2c269b..e49ecb3 100644 --- a/tests/oo.test +++ b/tests/oo.test @@ -4898,6 +4898,22 @@ test oo-41.2 {TIP 478: myclass command cleanup} -setup { } -cleanup { parent destroy } -result {{this is ::cls1} {this is ::x} {this is ::x} {this is ::cls1} 1 1} +test oo-41.3 {TIP 478: myclass command calls unexported methods, via forward} -setup { + oo::class create parent + set result {} +} -body { + oo::class create cls1 { + superclass parent + self method Hi {} { + return "this is [self]" + } + forward poke myclass Hi + } + cls1 create x + lappend result [catch {cls1 Hi}] [x poke] +} -cleanup { + parent destroy +} -result {1 {this is ::cls1}} cleanupTests return -- cgit v0.12 From 51aecf205dab16072098f2f5119d6b9026f73e65 Mon Sep 17 00:00:00 2001 From: sebres Date: Mon, 9 Jul 2018 17:18:07 +0000 Subject: closes [270f78ca95b642fb]: fix the race condition for `file mkdir` if some worker deletes directory immediately after the succeded create inside 3rd worker. --- generic/tclFCmd.c | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/generic/tclFCmd.c b/generic/tclFCmd.c index 1363829..da15262 100644 --- a/generic/tclFCmd.c +++ b/generic/tclFCmd.c @@ -243,9 +243,13 @@ TclFileMakeDirsCmd( break; } for (j = 0; j < pobjc; j++) { + int errCount = 2; + target = Tcl_FSJoinPath(split, j + 1); Tcl_IncrRefCount(target); + createDir: + /* * Call Tcl_FSStat() so that if target is a symlink that points to * a directory we will create subdirectories in that directory. @@ -273,24 +277,24 @@ TclFileMakeDirsCmd( */ if (errno == EEXIST) { - if ((Tcl_FSStat(target, &statBuf) == 0) - && S_ISDIR(statBuf.st_mode)) { - /* - * It is a directory that wasn't there before, so keep - * going without error. - */ - - Tcl_ResetResult(interp); - } else { - errfile = target; - goto done; + /* Be aware other workers could delete it immediately after + * creation, so give this worker still one chance (repeat once), + * see [270f78ca95] for description of the race-condition. + * Don't repeat the create always (to avoid endless loop). */ + if (--errCount > 0) { + goto createDir; } - } else { - errfile = target; - goto done; + /* Already tried, with delete in-between directly after + * creation, so just continue (assume created successful). */ + goto nextPart; } + + /* return with error */ + errfile = target; + goto done; } + nextPart: /* * Forget about this sub-path. */ -- cgit v0.12 From 87e508c590246b8559502d220a5e2c7d618ef338 Mon Sep 17 00:00:00 2001 From: sebres Date: Tue, 10 Jul 2018 08:19:08 +0000 Subject: amend to [1830f9f520e2abdd], fixed package.test if built without test - avoids test file error: package "Tcltest" isn't loaded statically --- tests/package.test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/package.test b/tests/package.test index 2843701..69d9ddb 100644 --- a/tests/package.test +++ b/tests/package.test @@ -23,7 +23,7 @@ catch [list package require -exact Tcltest [info patchlevel]] # Do all this in a slave interp to avoid garbaging the package list set i [interp create] tcltest::loadIntoSlaveInterpreter $i {*}$argv -load {} Tcltest $i +catch [list load {} Tcltest $i] interp eval $i { namespace import -force ::tcltest::* #package forget {*}[package names] -- cgit v0.12 From 885a163b3c4ec29beb88d95cf6ff60687aa25223 Mon Sep 17 00:00:00 2001 From: sebres Date: Thu, 12 Jul 2018 14:17:57 +0000 Subject: win: closes [3f7af0e21e13f1f5] - avoid "permissions denied" by `file delete`, if file stat (TclpObjStat) used internally in other worker, for example by usage of `file mkdir` etc. --- win/tclWinFile.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/win/tclWinFile.c b/win/tclWinFile.c index 1536bc0..cbd8814 100755 --- a/win/tclWinFile.c +++ b/win/tclWinFile.c @@ -2093,7 +2093,8 @@ NativeStat( */ fileHandle = (tclWinProcs->createFileProc)(nativePath, GENERIC_READ, - FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, + FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, + NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, NULL); if (fileHandle != INVALID_HANDLE_VALUE) { -- cgit v0.12 From 77aceb5c5fa1c705713e90b474e94be2799f233a Mon Sep 17 00:00:00 2001 From: dkf Date: Sun, 15 Jul 2018 15:46:33 +0000 Subject: Added more tests and made [initialize] an alternate spelling for [initialise]. --- doc/define.n | 2 ++ generic/tclOOScript.h | 45 +++++++++++++++++++++++++++------------------ tests/ooUtil.test | 45 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 74 insertions(+), 18 deletions(-) diff --git a/doc/define.n b/doc/define.n index 860218f..6353d00 100644 --- a/doc/define.n +++ b/doc/define.n @@ -132,6 +132,8 @@ below), this command creates private forwarded methods. .RE .TP \fBinitialise\fI script\fR +.TP +\fBinitialize\fI script\fR .VS TIP478 This evaluates \fIscript\fR in a context which supports local variables and where the current namespace is the instance namespace of the class object diff --git a/generic/tclOOScript.h b/generic/tclOOScript.h index 4b58337..ffdedb8 100644 --- a/generic/tclOOScript.h +++ b/generic/tclOOScript.h @@ -73,21 +73,6 @@ static const char *tclOOSetupScript = " string cat [info object namespace $class] {:: oo ::delegate}\n" "}\n" -"proc ::oo::define::classmethod {name {args {}} {body {}}} {\n" -" # Create the method on the class if the caller gave arguments and body\n" -" set argc [llength [info level 0]]\n" -" if {$argc == 3} {\n" -" return -code error [string cat {wrong # args: should be \"}" -" [lindex [info level 0] 0] { name ?args body?\"}]\n" -" }\n" -" set cls [uplevel 1 self]\n" -" if {$argc == 4} {\n" -" ::oo::define [::oo::DelegateName $cls] method $name $args $body\n" -" }\n" -" # Make the connection by forwarding\n" -" tailcall forward $name myclass $name\n" -"}\n" - "proc ::oo::MixinClassDelegates {class} {\n" " if {![info object isa class $class]} {\n" " return\n" @@ -106,9 +91,33 @@ static const char *tclOOSetupScript = " ::oo::objdefine $class mixin -append $delegate\n" "}\n" -"::proc ::oo::define::initialise {body} {\n" -" set clsns [info object namespace [uplevel 1 self]]\n" -" tailcall apply [list {} $body $clsns]\n" +"::namespace eval ::oo::define {" +" ::proc classmethod {name {args {}} {body {}}} {\n" +" # Create the method on the class if the caller gave arguments and body\n" +" ::set argc [::llength [::info level 0]]\n" +" ::if {$argc == 3} {\n" +" ::return -code error [::string cat {wrong # args: should be \"}" +" [::lindex [::info level 0] 0] { name ?args body?\"}]\n" +" }\n" +" ::set cls [::uplevel 1 self]\n" +" ::if {$argc == 4} {\n" +" ::oo::define [::oo::DelegateName $cls] method $name $args $body\n" +" }\n" +" # Make the connection by forwarding\n" +" ::tailcall forward $name myclass $name\n" +" }\n" + +" ::proc initialise {body} {\n" +" ::set clsns [::info object namespace [::uplevel 1 self]]\n" +" ::tailcall apply [::list {} $body $clsns]\n" +" }\n" + +" # Make the initialise command appear with US spelling too\n" +" ::namespace export initialise\n" +" ::namespace eval tmp {::namespace import ::oo::define::initialise}\n" +" ::rename ::oo::define::tmp::initialise initialize\n" +" ::namespace delete tmp\n" +" ::namespace export -clear\n" "}\n" "::oo::define ::oo::Slot {\n" diff --git a/tests/ooUtil.test b/tests/ooUtil.test index e00c70c..e796637 100644 --- a/tests/ooUtil.test +++ b/tests/ooUtil.test @@ -286,6 +286,51 @@ test ooUtil-3.2 {TIP 478: class variables} -setup { } -cleanup { parent destroy } -result {124 125 126 127 128 129} +test ooUtil-3.3 {TIP 478: class initialisation} -setup { + oo::class create parent + catch {rename ::foobar-3.3 {}} +} -body { + oo::class create ::cls { + superclass parent + initialize { + proc foobar-3.3 {} {return ok} + } + method calls {} { + list [catch foobar-3.3 msg] $msg \ + [namespace eval [info object namespace [self class]] foobar-3.3] + } + } + [cls new] calls +} -cleanup { + parent destroy +} -result {1 {invalid command name "foobar-3.3"} ok} +test ooUtil-3.4 {TIP 478: class initialisation} -setup { + oo::class create parent + catch {rename ::appendToResultVar {}} + proc ::appendToResultVar args { + lappend ::result {*}$args + } + set result {} +} -body { + trace add execution oo::define::initialise enter appendToResultVar + oo::class create ::cls { + superclass parent + initialize {proc xyzzy {} {}} + } + return $result +} -cleanup { + catch { + trace remove execution oo::define::initialise enter appendToResultVar + } + rename ::appendToResultVar {} + parent destroy +} -result {{initialize {proc xyzzy {} {}}} enter} +test ooUtil-3.5 {TIP 478: class initialisation} -body { + oo::define oo::object { + ::list [::namespace which initialise] [::namespace which initialize] \ + [::namespace origin initialise] [::namespace origin initialize] + } +} -result {::oo::define::initialise ::oo::define::initialize ::oo::define::initialise ::oo::define::initialise} test ooUtil-4.1 {TIP 478: singleton} -setup { oo::class create parent -- cgit v0.12 From 4a3f32b84a736f51135c5321007ba7c7fa8ed47e Mon Sep 17 00:00:00 2001 From: sebres Date: Mon, 16 Jul 2018 13:59:29 +0000 Subject: win: fixed test-cases (see [525ccacaef]) running under windows outside of temp-folder --- tests/cmdAH.test | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/tests/cmdAH.test b/tests/cmdAH.test index e334dff..0377064 100644 --- a/tests/cmdAH.test +++ b/tests/cmdAH.test @@ -1040,7 +1040,7 @@ test cmdAH-20.7.1 { Tcl_FileObjCmd: atime (built-in Windows names with dir path and extension) } -constraints {win} -body { file atime [file join [temporaryDirectory] CON.txt] -} -result "could not get access time for file \"[file join [temporaryDirectory] CON.txt]\"" -returnCodes error +} -match regexp -result {could not (?:get access time|read)} -returnCodes error if {[testConstraint unix] && [file exists /tmp]} { removeFile touch.me /tmp @@ -1281,7 +1281,7 @@ test cmdAH-24.14.1 { Tcl_FileObjCmd: mtime (built-in Windows names with dir path and extension) } -constraints {win} -body { file mtime [file join [temporaryDirectory] CON.txt] -} -result "could not get modification time for file \"[file join [temporaryDirectory] CON.txt]\"" -returnCodes error +} -match regexp -result {could not (?:get modification time|read)} -returnCodes error # owned test cmdAH-25.1 {Tcl_FileObjCmd: owned} -returnCodes error -body { @@ -1345,7 +1345,12 @@ test cmdAH-27.4 { test cmdAH-27.4.1 { Tcl_FileObjCmd: size (built-in Windows names with dir path and extension) } -constraints {win} -body { - file size [file join [temporaryDirectory] con.txt] + try { + set res [file size [file join [temporaryDirectory] con.txt]] + } trap {POSIX ENOENT} {} { + set res 0 + } + set res } -result 0 catch {testsetplatform $platform} @@ -1447,8 +1452,13 @@ test cmdAH-28.13 {Tcl_FileObjCmd: stat (built-in Windows names)} -constraints {w test cmdAH-28.13.1 {Tcl_FileObjCmd: stat (built-in Windows names)} -constraints {win} -setup { unset -nocomplain stat } -body { - file stat [file join [temporaryDirectory] CON.txt] stat - lmap elem {atime ctime dev gid ino mode mtime nlink size type uid} {set stat($elem)} + try { + file stat [file join [temporaryDirectory] CON.txt] stat + set res [lmap elem {atime ctime dev gid ino mode mtime nlink size type uid} {set stat($elem)}] + } trap {POSIX ENOENT} {} { + set res {0 0 -1 0 0 8630 0 0 0 characterSpecial 0} + } + set res } -result {0 0 -1 0 0 8630 0 0 0 characterSpecial 0} unset -nocomplain stat @@ -1498,7 +1508,12 @@ test cmdAH-29.6 { test cmdAH-29.6.1 { Tcl_FileObjCmd: type (built-in Windows names, with dir path and extension) } -constraints {win} -body { - file type [file join [temporaryDirectory] CON.txt] + try { + set res [file type [file join [temporaryDirectory] CON.txt]] + } trap {POSIX ENOENT} {} { + set res {characterSpecial} + } + set res } -result "characterSpecial" # Error conditions -- cgit v0.12 From 7fb72851e8562eb2e68ec94d10e1b88fb40b863e Mon Sep 17 00:00:00 2001 From: sebres Date: Fri, 20 Jul 2018 15:54:11 +0000 Subject: win: fixes x64-build within gcc-compile runtime env for (mingw64, etc): "$do64bit" may be "amd64|x64|yes", so it could find & copy wrong zlib.dll. --- win/configure | 2 +- win/configure.in | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/win/configure b/win/configure index be38dc3..03ad68a 100755 --- a/win/configure +++ b/win/configure @@ -4372,7 +4372,7 @@ if test "$tcl_ok" = "yes"; then ZLIB_DLL_FILE=\${ZLIB_DLL_FILE} - if test "$do64bit" = "yes"; then + if test "$do64bit" != "no"; then if test "$GCC" == "yes"; then diff --git a/win/configure.in b/win/configure.in index 5fc17a3..82351f1 100644 --- a/win/configure.in +++ b/win/configure.in @@ -128,7 +128,7 @@ AS_IF([test "${enable_shared+set}" = "set"], [ ]) AS_IF([test "$tcl_ok" = "yes"], [ AC_SUBST(ZLIB_DLL_FILE,[\${ZLIB_DLL_FILE}]) - AS_IF([test "$do64bit" = "yes"], [ + AS_IF([test "$do64bit" != "no"], [ AS_IF([test "$GCC" == "yes"],[ AC_SUBST(ZLIB_LIBS,[\${ZLIB_DIR_NATIVE}/win64/libz.dll.a]) ], [ -- cgit v0.12 From d00a212e82abf97d0bc54b040a3d0a153980d537 Mon Sep 17 00:00:00 2001 From: sebres Date: Fri, 20 Jul 2018 15:58:56 +0000 Subject: win: avoids warning by x64-build in function 'TclWinCPUID' - pointer targets in passing argument 1 of '__cpuid' differ in signedness [-Wpointer-sign] (int* vs unsigned int*) --- win/tclWin32Dll.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/win/tclWin32Dll.c b/win/tclWin32Dll.c index 6c973df..a85dd0c 100644 --- a/win/tclWin32Dll.c +++ b/win/tclWin32Dll.c @@ -640,7 +640,7 @@ TclWinCPUID( #if defined(HAVE_INTRIN_H) && defined(_WIN64) - __cpuid(regsPtr, index); + __cpuid((int *)regsPtr, index); status = TCL_OK; #elif defined(__GNUC__) -- cgit v0.12 From 814c867db47078736aae2dbe18cbc4191fe90aee Mon Sep 17 00:00:00 2001 From: Kevin B Kenny Date: Sat, 21 Jul 2018 18:45:09 +0000 Subject: Add a note in the 'clock' man page about the interpretation of impossible values on [clock scan] --- doc/clock.n | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/doc/clock.n b/doc/clock.n index 889a5da..6efa722 100644 --- a/doc/clock.n +++ b/doc/clock.n @@ -453,6 +453,19 @@ If this situation occurs, the first occurrence of the time is chosen. (For this reason, it is wise to have the input string contain the time zone when converting local times. This caveat does not apply to UTC times.) +.PP +If the interpretation of the groups yields an impossible time because +a field is out of range, enough of that field's unit will be added to +or subtracted from the time to bring it in range. Thus, if attempting to +scan or format day 0 of the month, one day will be subtracted from day +1 of the month, yielding the last day of the previous month. +.PP +If the interpretation of the groups yields an impossible time because +a Daylight Saving Time change skips over that time, or an ambiguous +time because a Daylight Saving Time change skips back so that the clock +observes the given time twice, and no time zone specifier (\fB%z\fR +or \fB%Z\fR) is present in the format, the time is interpreted as +if the clock had not changed. .SH "FORMAT GROUPS" .PP The following format groups are recognized by the \fBclock scan\fR and -- cgit v0.12 From 772d2da10b02fc06220a92d5f9d4f33b752a9553 Mon Sep 17 00:00:00 2001 From: pooryorick Date: Sun, 22 Jul 2018 20:44:16 +0000 Subject: Fix for [ba921a8d98e02a96] - concatenating binary array with empty string yields the empty string. --- generic/tclStringObj.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/generic/tclStringObj.c b/generic/tclStringObj.c index 3bb6112..2cda2c4 100644 --- a/generic/tclStringObj.c +++ b/generic/tclStringObj.c @@ -3065,24 +3065,22 @@ TclStringCat( * Result will be pure byte array. Pre-size it */ + int numBytes; ov = objv; oc = objc; do { Tcl_Obj *objPtr = *ov++; - if (objPtr->bytes == NULL) { - int numBytes; + Tcl_GetByteArrayFromObj(objPtr, &numBytes); /* PANIC? */ - Tcl_GetByteArrayFromObj(objPtr, &numBytes); /* PANIC? */ - if (numBytes) { - last = objc - oc; - if (length == 0) { - first = last; - } else if (numBytes > INT_MAX - length) { - goto overflow; - } - length += numBytes; + if (numBytes) { + last = objc - oc; + if (length == 0) { + first = last; + } else if (numBytes > INT_MAX - length) { + goto overflow; } + length += numBytes; } } while (--oc); } else if (allowUniChar && requestUniChar) { -- cgit v0.12 From 164a7f04c03e56a310d9386fd8ddbd6319c0c788 Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 26 Jul 2018 15:51:28 +0000 Subject: New test for [Bug ba921a8d98]. --- tests/string.test | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/string.test b/tests/string.test index 868fc25..3f5fd81 100644 --- a/tests/string.test +++ b/tests/string.test @@ -2015,6 +2015,9 @@ test string-29.4 {string cat, many args} { list $r1 $r2 } {0 0} +test string-30.1 {[Bug ba921a8d98]} { + string cat [set data [binary format a* hello]] [encoding convertto $data] [unset data] +} hellohello # cleanup -- cgit v0.12 From 7e727bed70653d181a190d921ea951707ad4078a Mon Sep 17 00:00:00 2001 From: sebres Date: Thu, 26 Jul 2018 15:57:38 +0000 Subject: closes [d051b77fc18d7340]: fixed segfault by integer overflow (if width by format like "%4000000000g" overflows to negative values by scan of length) --- generic/tclStringObj.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/generic/tclStringObj.c b/generic/tclStringObj.c index 996be77..462ef04 100644 --- a/generic/tclStringObj.c +++ b/generic/tclStringObj.c @@ -1938,6 +1938,10 @@ Tcl_AppendFormatToObj( width = 0; if (isdigit(UCHAR(ch))) { width = strtoul(format, &end, 10); + if (width < 0) { + msg = overflow; + goto errorMsg; + } format = end; step = Tcl_UtfToUniChar(format, &ch); } else if (ch == '*') { -- cgit v0.12 From c7cdc550c4e27c7ab0e3d4537cff99167b4509fd Mon Sep 17 00:00:00 2001 From: sebres Date: Thu, 26 Jul 2018 16:46:47 +0000 Subject: test cases added to cover width overflow by format (should cause limit exceeded) --- tests/format.test | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/tests/format.test b/tests/format.test index d43b7eb..5797f2b 100644 --- a/tests/format.test +++ b/tests/format.test @@ -565,6 +565,20 @@ test format-19.3 {Bug 2830354} { string length [format %340f 0] } 340 +test format-19.4.1 {Bug d498578df4: width overflow should cause limit exceeded} \ +-constraints {longIs32bit} -body { + # in case of overflow into negative, it produces width -2 (and limit exceeded), + # in case of width will be unsigned, it will be outside limit (2GB for 32bit)... + # and it don't throw an error in case the bug is not fixed (and probably no segfault). + format %[expr {0xffffffff - 1}]g 0 +} -returnCodes error -result "max size for a Tcl value exceeded" + +test format-19.4.2 {Bug d498578df4: width overflow should cause limit exceeded} -body { + # limit should exceeds in any case, + # and it don't throw an error in case the bug is not fixed (and probably no segfault). + format %[expr {0xffffffffffffffff - 1}]g 0 +} -returnCodes error -result "max size for a Tcl value exceeded" + # cleanup catch {unset a} catch {unset b} -- cgit v0.12 From 2133e40e589348c5df1b721c1d0e0ac2f2385505 Mon Sep 17 00:00:00 2001 From: sebres Date: Thu, 26 Jul 2018 18:07:34 +0000 Subject: amend to [d498578df4], still one test for [Bug ba921a8d98] with inplace by subst inside string (compiled as "strcat" instruction) --- tests/string.test | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/string.test b/tests/string.test index 3f5fd81..8fc5b0e 100644 --- a/tests/string.test +++ b/tests/string.test @@ -2015,9 +2015,12 @@ test string-29.4 {string cat, many args} { list $r1 $r2 } {0 0} -test string-30.1 {[Bug ba921a8d98]} { +test string-30.1.1 {[Bug ba921a8d98]: string cat} { string cat [set data [binary format a* hello]] [encoding convertto $data] [unset data] } hellohello +test string-30.1.2 {[Bug ba921a8d98]: inplace cat by subst (compiled to "strcat" instruction)} { + set x "[set data [binary format a* hello]][encoding convertto $data][unset data]" +} hellohello # cleanup -- cgit v0.12 From 590288982511400f0dd0f244fb753b01a8bae140 Mon Sep 17 00:00:00 2001 From: sebres Date: Thu, 26 Jul 2018 18:56:41 +0000 Subject: amend after merge: 8.6th provide additionally an error-code (so missing `errCode = "OVERFLOW"`) --- generic/tclStringObj.c | 1 + 1 file changed, 1 insertion(+) diff --git a/generic/tclStringObj.c b/generic/tclStringObj.c index 3139be4..493378c 100644 --- a/generic/tclStringObj.c +++ b/generic/tclStringObj.c @@ -1878,6 +1878,7 @@ Tcl_AppendFormatToObj( width = strtoul(format, &end, 10); if (width < 0) { msg = overflow; + errCode = "OVERFLOW"; goto errorMsg; } format = end; -- cgit v0.12 From c1ae69114bfdfe97b4c12ad727e4d5accc0df85f Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Tue, 31 Jul 2018 19:49:51 +0000 Subject: Remove some actually dead code --- generic/tcl.decls | 4 +++ generic/tclCmdAH.c | 57 ------------------------------------------ generic/tclIOUtil.c | 29 +++------------------- generic/tclInt.h | 2 +- generic/tclOODefineCmds.c | 63 ----------------------------------------------- 5 files changed, 9 insertions(+), 146 deletions(-) diff --git a/generic/tcl.decls b/generic/tcl.decls index db1f892..b62cd28 100644 --- a/generic/tcl.decls +++ b/generic/tcl.decls @@ -2370,6 +2370,10 @@ export { void Tcl_Main(int argc, char **argv, Tcl_AppInitProc *appInitProc) } export { + void Tcl_MainEx(int argc, char **argv, Tcl_AppInitProc *appInitProc, + Tcl_Interp *interp) +} +export { const char *Tcl_InitStubs(Tcl_Interp *interp, const char *version, int exact) } diff --git a/generic/tclCmdAH.c b/generic/tclCmdAH.c index a48dfc7..7e117af 100644 --- a/generic/tclCmdAH.c +++ b/generic/tclCmdAH.c @@ -513,63 +513,6 @@ Tcl_ContinueObjCmd( } /* - *---------------------------------------------------------------------- - * - * Tcl_EncodingObjCmd -- - * - * This command manipulates encodings. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * See the user documentation. - * - *---------------------------------------------------------------------- - */ - -int -Tcl_EncodingObjCmd( - ClientData dummy, /* Not used. */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ -{ - int index; - - static const char *const optionStrings[] = { - "convertfrom", "convertto", "dirs", "names", "system", - NULL - }; - enum options { - ENC_CONVERTFROM, ENC_CONVERTTO, ENC_DIRS, ENC_NAMES, ENC_SYSTEM - }; - - if (objc < 2) { - Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?"); - return TCL_ERROR; - } - if (Tcl_GetIndexFromObj(interp, objv[1], optionStrings, "option", 0, - &index) != TCL_OK) { - return TCL_ERROR; - } - - switch ((enum options) index) { - case ENC_CONVERTTO: - return EncodingConverttoObjCmd(dummy, interp, objc, objv); - case ENC_CONVERTFROM: - return EncodingConvertfromObjCmd(dummy, interp, objc, objv); - case ENC_DIRS: - return EncodingDirsObjCmd(dummy, interp, objc, objv); - case ENC_NAMES: - return EncodingNamesObjCmd(dummy, interp, objc, objv); - case ENC_SYSTEM: - return EncodingSystemObjCmd(dummy, interp, objc, objv); - } - return TCL_OK; -} - -/* *----------------------------------------------------------------------------- * * TclInitEncodingCmd -- diff --git a/generic/tclIOUtil.c b/generic/tclIOUtil.c index 19620e7..27acbbc 100644 --- a/generic/tclIOUtil.c +++ b/generic/tclIOUtil.c @@ -139,7 +139,6 @@ Tcl_FSRenameFileProc TclpObjRenameFile; Tcl_FSCreateDirectoryProc TclpObjCreateDirectory; Tcl_FSCopyDirectoryProc TclpObjCopyDirectory; Tcl_FSRemoveDirectoryProc TclpObjRemoveDirectory; -Tcl_FSUnloadFileProc TclpUnloadFile; Tcl_FSLinkProc TclpObjLink; Tcl_FSListVolumesProc TclpObjListVolumes; @@ -3159,8 +3158,8 @@ Tcl_FSLoadFile( * present and set to true (any integer > 0) then the unlink is skipped. */ -int -TclSkipUnlink (Tcl_Obj* shlibFile) +static int +skipUnlink (Tcl_Obj* shlibFile) { /* Order of testing: * 1. On hpux we generally want to skip unlink in general @@ -3414,7 +3413,7 @@ Tcl_LoadFile( */ if ( - !TclSkipUnlink (copyToPtr) && + !skipUnlink (copyToPtr) && (Tcl_FSDeleteFile(copyToPtr) == TCL_OK)) { Tcl_DecrRefCount(copyToPtr); @@ -3683,30 +3682,10 @@ Tcl_FSUnloadFile( } return TCL_ERROR; } - TclpUnloadFile(handle); - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * TclpUnloadFile -- - * - * Unloads a library given its handle - * - * This function was once filesystem-specific, but has been made portable by - * having TclpDlopen return a structure that includes procedure pointers. - * - *---------------------------------------------------------------------- - */ - -void -TclpUnloadFile( - Tcl_LoadHandle handle) -{ if (handle->unloadFileProcPtr != NULL) { handle->unloadFileProcPtr(handle); } + return TCL_OK; } /* diff --git a/generic/tclInt.h b/generic/tclInt.h index 0a3285f..432be7a 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -2934,7 +2934,7 @@ MODULE_SCOPE char * TclDStringAppendDString(Tcl_DString *dsPtr, MODULE_SCOPE Tcl_Obj * TclDStringToObj(Tcl_DString *dsPtr); MODULE_SCOPE Tcl_Obj *const * TclFetchEnsembleRoot(Tcl_Interp *interp, Tcl_Obj *const *objv, int objc, int *objcPtr); -Tcl_Namespace * TclEnsureNamespace( +MODULE_SCOPE Tcl_Namespace * TclEnsureNamespace( Tcl_Interp *interp, Tcl_Namespace *namespacePtr); diff --git a/generic/tclOODefineCmds.c b/generic/tclOODefineCmds.c index 648ad02..c924d2b 100644 --- a/generic/tclOODefineCmds.c +++ b/generic/tclOODefineCmds.c @@ -1542,69 +1542,6 @@ TclOODefineMethodObjCmd( /* * ---------------------------------------------------------------------- * - * TclOODefineMixinObjCmd -- - * Implementation of the "mixin" subcommand of the "oo::define" and - * "oo::objdefine" commands. - * - * ---------------------------------------------------------------------- - */ - -int -TclOODefineMixinObjCmd( - ClientData clientData, - Tcl_Interp *interp, - const int objc, - Tcl_Obj *const *objv) -{ - int isInstanceMixin = (clientData != NULL); - Object *oPtr = (Object *) TclOOGetDefineCmdContext(interp); - Class **mixins; - int i; - - if (oPtr == NULL) { - return TCL_ERROR; - } - if (!isInstanceMixin && !oPtr->classPtr) { - Tcl_SetObjResult(interp, Tcl_NewStringObj( - "attempt to misuse API", -1)); - Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", NULL); - return TCL_ERROR; - } - mixins = TclStackAlloc(interp, sizeof(Class *) * (objc-1)); - - for (i=1 ; iclassPtr, clsPtr)) { - Tcl_SetObjResult(interp, Tcl_NewStringObj( - "may not mix a class into itself", -1)); - Tcl_SetErrorCode(interp, "TCL", "OO", "SELF_MIXIN", NULL); - goto freeAndError; - } - mixins[i-1] = clsPtr; - } - - if (isInstanceMixin) { - TclOOObjectSetMixins(oPtr, objc-1, mixins); - } else { - TclOOClassSetMixins(interp, oPtr->classPtr, objc-1, mixins); - } - - TclStackFree(interp, mixins); - return TCL_OK; - - freeAndError: - TclStackFree(interp, mixins); - return TCL_ERROR; -} - -/* - * ---------------------------------------------------------------------- - * * TclOODefineRenameMethodObjCmd -- * Implementation of the "renamemethod" subcommand of the "oo::define" * and "oo::objdefine" commands. -- cgit v0.12 From 40947c7d3eeb124dfd51a08dbdfc556a7a402bd6 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Thu, 2 Aug 2018 22:37:00 +0000 Subject: Purge end-of-line spacing --- doc/NRE.3 | 2 +- doc/clock.n | 2 +- doc/process.n | 10 +++---- generic/tclAssembly.c | 2 +- generic/tclCmdIL.c | 4 +-- generic/tclCompCmdsGR.c | 4 +-- generic/tclCompCmdsSZ.c | 14 +++++----- generic/tclOOInt.h | 2 +- generic/tclPkg.c | 2 +- generic/tclProcess.c | 70 +++++++++++++++++++++++------------------------ generic/tclStringObj.c | 8 +++--- generic/tclUtil.c | 10 +++---- library/msgcat/msgcat.tcl | 8 +++--- tests/chanio.test | 4 +-- tests/env.test | 4 +-- tests/expr.test | 2 +- tests/msgcat.test | 24 ++++++++-------- tests/namespace.test | 2 +- tests/oo.test | 2 +- tests/package.test | 4 +-- tests/process.test | 4 +-- tests/string.test | 4 +-- tests/tcltest.test | 4 +-- unix/tclEpollNotfy.c | 2 +- win/makefile.vc | 2 +- win/nmakehlp.c | 12 ++++---- win/tclWinFile.c | 10 +++---- 27 files changed, 109 insertions(+), 109 deletions(-) diff --git a/doc/NRE.3 b/doc/NRE.3 index 6078a53..6024b6a 100644 --- a/doc/NRE.3 +++ b/doc/NRE.3 @@ -1,6 +1,6 @@ .\" .\" Copyright (c) 2008 by Kevin B. Kenny. -.\" Copyright (c) 2018 by Nathan Coulter. +.\" Copyright (c) 2018 by Nathan Coulter. .\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. diff --git a/doc/clock.n b/doc/clock.n index dd7115b..e8fb8f7 100644 --- a/doc/clock.n +++ b/doc/clock.n @@ -464,7 +464,7 @@ a Daylight Saving Time change skips over that time, or an ambiguous time because a Daylight Saving Time change skips back so that the clock observes the given time twice, and no time zone specifier (\fB%z\fR or \fB%Z\fR) is present in the format, the time is interpreted as -if the clock had not changed. +if the clock had not changed. .SH "FORMAT GROUPS" .PP The following format groups are recognized by the \fBclock scan\fR and diff --git a/doc/process.n b/doc/process.n index fbe307b..536b98b 100644 --- a/doc/process.n +++ b/doc/process.n @@ -24,11 +24,11 @@ Returns the list of subprocess PIDs. .TP \fB::tcl::process status\fR ?\fIswitches\fR? ?\fIpids\fR? . -Returns a dictionary mapping subprocess PIDs to their respective status. If -\fIpids\fR is specified as a list of PIDs then the command only returns the -status of the matching subprocesses if they exist, and raises an error +Returns a dictionary mapping subprocess PIDs to their respective status. If +\fIpids\fR is specified as a list of PIDs then the command only returns the +status of the matching subprocesses if they exist, and raises an error otherwise. For active processes, the status is an empty value. For terminated -processes, the status is a list with the following format: +processes, the status is a list with the following format: .QW "{code ?\fImsg errorCode\fR?}" , where: .RS @@ -45,7 +45,7 @@ is the human-readable error message, . uses the same format as the \fBerrorCode\fR global variable .RE -Note that \fBmsg\fR and \fBerrorCode\fR are only present for abnormally +Note that \fBmsg\fR and \fBerrorCode\fR are only present for abnormally terminated processes (i.e. those where \fBcode\fR is nonzero). Under the hood this command calls \fBTcl_WaitPid\fR with the \fBWNOHANG\fR flag set for non-blocking behavior, unless the \fB\-wait\fR switch is set (see below). diff --git a/generic/tclAssembly.c b/generic/tclAssembly.c index 7368f97..6356a00 100644 --- a/generic/tclAssembly.c +++ b/generic/tclAssembly.c @@ -2253,7 +2253,7 @@ GetListIndexOperand( if (GetNextOperand(assemEnvPtr, tokenPtrPtr, &value) != TCL_OK) { return TCL_ERROR; } - + /* Convert to an integer, advance to the next token and return. */ /* * NOTE: Indexing a list with an index before it yields the diff --git a/generic/tclCmdIL.c b/generic/tclCmdIL.c index 3d058a4..3faaa5a 100644 --- a/generic/tclCmdIL.c +++ b/generic/tclCmdIL.c @@ -3333,7 +3333,7 @@ Tcl_LsearchObjCmd( * sense in doing this when the match sense is inverted. */ - /* + /* * With -stride, lower, upper and i are kept as multiples of groupSize. */ @@ -4015,7 +4015,7 @@ Tcl_LsortObjCmd( /* * Do not shrink the actual memory block used; that doesn't * work with TclStackAlloc-allocated memory. [Bug 2918962] - * + * * TODO: Consider a pointer increment to replace this * array shift. */ diff --git a/generic/tclCompCmdsGR.c b/generic/tclCompCmdsGR.c index 858a0c5..1209caf 100644 --- a/generic/tclCompCmdsGR.c +++ b/generic/tclCompCmdsGR.c @@ -34,7 +34,7 @@ static int IndexTailVarIfKnown(Tcl_Interp *interp, * TclGetIndexFromToken -- * * Parse a token to determine if an index value is known at - * compile time. + * compile time. * * Returns: * TCL_OK if parsing succeeded, and TCL_ERROR if it failed. @@ -1553,7 +1553,7 @@ TclCompileLreplaceCmd( emptyPrefix = 0; } - + /* * [lreplace] raises an error when idx1 points after the list, but * only when the list is not empty. This is maximum stupidity. diff --git a/generic/tclCompCmdsSZ.c b/generic/tclCompCmdsSZ.c index cf088bb..9434e54 100644 --- a/generic/tclCompCmdsSZ.c +++ b/generic/tclCompCmdsSZ.c @@ -1002,13 +1002,13 @@ TclCompileStringReplaceCmd( if (parsePtr->numWords < 4 || parsePtr->numWords > 5) { return TCL_ERROR; } - + /* Bytecode to compute/push string argument being replaced */ valueTokenPtr = TokenAfter(parsePtr->tokenPtr); CompileWord(envPtr, valueTokenPtr, interp, 1); /* - * Check for first index known and useful at compile time. + * Check for first index known and useful at compile time. */ tokenPtr = TokenAfter(valueTokenPtr); if (TclGetIndexFromToken(tokenPtr, TCL_INDEX_BEFORE, TCL_INDEX_AFTER, @@ -1017,7 +1017,7 @@ TclCompileStringReplaceCmd( } /* - * Check for last index known and useful at compile time. + * Check for last index known and useful at compile time. */ tokenPtr = TokenAfter(tokenPtr); if (TclGetIndexFromToken(tokenPtr, TCL_INDEX_BEFORE, TCL_INDEX_AFTER, @@ -1025,7 +1025,7 @@ TclCompileStringReplaceCmd( goto genericReplace; } - /* + /* * [string replace] is an odd bird. For many arguments it is * a conventional substring replacer. However it also goes out * of its way to become a no-op for many cases where it would be @@ -1108,12 +1108,12 @@ TclCompileStringReplaceCmd( * Finally we need, third: * * (first <= last) - * + * * Considered in combination with the constraints we already have, * we see that we can proceed when (first == TCL_INDEX_BEFORE) * or (last == TCL_INDEX_AFTER). These also permit simplification * of the prefix|replace|suffix construction. The other constraints, - * though, interfere with getting a guarantee that first <= last. + * though, interfere with getting a guarantee that first <= last. */ if ((first == TCL_INDEX_BEFORE) && (last >= TCL_INDEX_START)) { @@ -1141,7 +1141,7 @@ TclCompileStringReplaceCmd( /* FLOW THROUGH TO genericReplace */ } else { - /* + /* * When we have no replacement string to worry about, we may * have more luck, because the forbidden empty string replacements * are harmless when they are replaced by another empty string. diff --git a/generic/tclOOInt.h b/generic/tclOOInt.h index a43ab76..acbd2c5 100644 --- a/generic/tclOOInt.h +++ b/generic/tclOOInt.h @@ -597,7 +597,7 @@ MODULE_SCOPE void TclOOSetupVariableResolver(Tcl_Namespace *nsPtr); #define FOREACH(var,ary) \ for(i=0 ; i<(ary).num; i++) if ((ary).list[i] == NULL) { \ continue; \ - } else if (var = (ary).list[i], 1) + } else if (var = (ary).list[i], 1) /* * A variation where the array is an array of structs. There's no issue with diff --git a/generic/tclPkg.c b/generic/tclPkg.c index 223ef93..2c16458 100644 --- a/generic/tclPkg.c +++ b/generic/tclPkg.c @@ -577,7 +577,7 @@ SelectPackage(ClientData data[], Tcl_Interp *interp, int result) { PkgAvail *availPtr, *bestPtr, *bestStablePtr; char *availVersion, *bestVersion, *bestStableVersion; /* Internal rep. of versions */ - int availStable, satisfies; + int availStable, satisfies; Require *reqPtr = data[0]; int reqc = PTR2INT(data[1]); Tcl_Obj **const reqv = data[2]; diff --git a/generic/tclProcess.c b/generic/tclProcess.c index 604b7ce..a781386 100644 --- a/generic/tclProcess.c +++ b/generic/tclProcess.c @@ -1,7 +1,7 @@ /* * tclProcess.c -- * - * This file implements the "tcl::process" ensemble for subprocess + * This file implements the "tcl::process" ensemble for subprocess * management as defined by TIP #462. * * Copyright (c) 2017 Frederic Bonnet. @@ -13,14 +13,14 @@ #include "tclInt.h" /* - * Autopurge flag. Process-global because of the way Tcl manages child + * Autopurge flag. Process-global because of the way Tcl manages child * processes (see tclPipe.c). */ static int autopurge = 1; /* Autopurge flag. */ /* - * Hash tables that keeps track of all child process statuses. Keys are the + * Hash tables that keeps track of all child process statuses. Keys are the * child process ids and resolved pids, values are (ProcessInfo *). */ @@ -29,7 +29,7 @@ typedef struct ProcessInfo { int resolvedPid; /* Resolved process id. */ int purge; /* Purge eventualy. */ TclProcessWaitStatus status;/* Process status. */ - int code; /* Error code, exit status or signal + int code; /* Error code, exit status or signal number. */ Tcl_Obj *msg; /* Error message. */ Tcl_Obj *error; /* Error code. */ @@ -47,7 +47,7 @@ static void InitProcessInfo(ProcessInfo *info, Tcl_Pid pid, int resolvedPid); static void FreeProcessInfo(ProcessInfo *info); static int RefreshProcessInfo(ProcessInfo *info, int options); -static TclProcessWaitStatus WaitProcessStatus(Tcl_Pid pid, int resolvedPid, +static TclProcessWaitStatus WaitProcessStatus(Tcl_Pid pid, int resolvedPid, int options, int *codePtr, Tcl_Obj **msgPtr, Tcl_Obj **errorObjPtr); static Tcl_Obj * BuildProcessStatusObj(ProcessInfo *info); @@ -160,7 +160,7 @@ RefreshProcessInfo( * Refresh & store status. */ - info->status = WaitProcessStatus(info->pid, info->resolvedPid, + info->status = WaitProcessStatus(info->pid, info->resolvedPid, options, &info->code, &info->msg, &info->error); if (info->msg) Tcl_IncrRefCount(info->msg); if (info->error) Tcl_IncrRefCount(info->error); @@ -214,7 +214,7 @@ WaitProcessStatus( /* * No change. */ - + return TCL_PROCESS_UNCHANGED; } @@ -370,7 +370,7 @@ BuildProcessStatusObj( /* * Normal exit, return TCL_OK. */ - + return Tcl_NewIntObj(TCL_OK); } @@ -388,7 +388,7 @@ BuildProcessStatusObj( * * ProcessListObjCmd -- * - * This function implements the 'tcl::process list' Tcl command. + * This function implements the 'tcl::process list' Tcl command. * Refer to the user documentation for details on what it does. * * Results: @@ -423,10 +423,10 @@ ProcessListObjCmd( list = Tcl_NewListObj(0, NULL); Tcl_MutexLock(&infoTablesMutex); - for (entry = Tcl_FirstHashEntry(&infoTablePerResolvedPid, &search); + for (entry = Tcl_FirstHashEntry(&infoTablePerResolvedPid, &search); entry != NULL; entry = Tcl_NextHashEntry(&search)) { info = (ProcessInfo *) Tcl_GetHashValue(entry); - Tcl_ListObjAppendElement(interp, list, + Tcl_ListObjAppendElement(interp, list, Tcl_NewIntObj(info->resolvedPid)); } Tcl_MutexUnlock(&infoTablesMutex); @@ -438,7 +438,7 @@ ProcessListObjCmd( * * ProcessStatusObjCmd -- * - * This function implements the 'tcl::process status' Tcl command. + * This function implements the 'tcl::process status' Tcl command. * Refer to the user documentation for details on what it does. * * Results: @@ -504,7 +504,7 @@ ProcessStatusObjCmd( dict = Tcl_NewDictObj(); Tcl_MutexLock(&infoTablesMutex); - for (entry = Tcl_FirstHashEntry(&infoTablePerResolvedPid, &search); + for (entry = Tcl_FirstHashEntry(&infoTablePerResolvedPid, &search); entry != NULL; entry = Tcl_NextHashEntry(&search)) { info = (ProcessInfo *) Tcl_GetHashValue(entry); RefreshProcessInfo(info, options); @@ -513,7 +513,7 @@ ProcessStatusObjCmd( /* * Purge entry. */ - + Tcl_DeleteHashEntry(entry); entry = Tcl_FindHashEntry(&infoTablePerPid, info->pid); Tcl_DeleteHashEntry(entry); @@ -523,7 +523,7 @@ ProcessStatusObjCmd( * Add to result. */ - Tcl_DictObjPut(interp, dict, Tcl_NewIntObj(info->resolvedPid), + Tcl_DictObjPut(interp, dict, Tcl_NewIntObj(info->resolvedPid), BuildProcessStatusObj(info)); } } @@ -532,7 +532,7 @@ ProcessStatusObjCmd( /* * Only return statuses of provided processes. */ - + result = Tcl_ListObjGetElements(interp, objv[1], &numPids, &pidObjs); if (result != TCL_OK) { return result; @@ -552,10 +552,10 @@ ProcessStatusObjCmd( /* * Skip unknown process. */ - + continue; } - + info = (ProcessInfo *) Tcl_GetHashValue(entry); RefreshProcessInfo(info, options); @@ -563,7 +563,7 @@ ProcessStatusObjCmd( /* * Purge entry. */ - + Tcl_DeleteHashEntry(entry); entry = Tcl_FindHashEntry(&infoTablePerPid, info->pid); Tcl_DeleteHashEntry(entry); @@ -573,7 +573,7 @@ ProcessStatusObjCmd( * Add to result. */ - Tcl_DictObjPut(interp, dict, Tcl_NewIntObj(info->resolvedPid), + Tcl_DictObjPut(interp, dict, Tcl_NewIntObj(info->resolvedPid), BuildProcessStatusObj(info)); } } @@ -587,7 +587,7 @@ ProcessStatusObjCmd( * * ProcessPurgeObjCmd -- * - * This function implements the 'tcl::process purge' Tcl command. + * This function implements the 'tcl::process purge' Tcl command. * Refer to the user documentation for details on what it does. * * Results: @@ -632,7 +632,7 @@ ProcessPurgeObjCmd( */ Tcl_MutexLock(&infoTablesMutex); - for (entry = Tcl_FirstHashEntry(&infoTablePerResolvedPid, &search); + for (entry = Tcl_FirstHashEntry(&infoTablePerResolvedPid, &search); entry != NULL; entry = Tcl_NextHashEntry(&search)) { info = (ProcessInfo *) Tcl_GetHashValue(entry); if (info->purge) { @@ -647,7 +647,7 @@ ProcessPurgeObjCmd( /* * Purge only provided processes. */ - + result = Tcl_ListObjGetElements(interp, objv[1], &numPids, &pidObjs); if (result != TCL_OK) { return result; @@ -665,7 +665,7 @@ ProcessPurgeObjCmd( /* * Skip unknown process. */ - + continue; } @@ -687,7 +687,7 @@ ProcessPurgeObjCmd( * * ProcessAutopurgeObjCmd -- * - * This function implements the 'tcl::process autopurge' Tcl command. + * This function implements the 'tcl::process autopurge' Tcl command. * Refer to the user documentation for details on what it does. * * Results: @@ -715,7 +715,7 @@ ProcessAutopurgeObjCmd( /* * Set given value. */ - + int flag; int result = Tcl_GetBooleanFromObj(interp, objv[1], &flag); if (result != TCL_OK) { @@ -725,8 +725,8 @@ ProcessAutopurgeObjCmd( autopurge = !!flag; } - /* - * Return current value. + /* + * Return current value. */ Tcl_SetObjResult(interp, Tcl_NewBooleanObj(autopurge)); @@ -821,9 +821,9 @@ TclProcessCreated( /* * Pid was reused, free old info and reuse structure. */ - + info = (ProcessInfo *) Tcl_GetHashValue(entry); - entry2 = Tcl_FindHashEntry(&infoTablePerResolvedPid, + entry2 = Tcl_FindHashEntry(&infoTablePerResolvedPid, INT2PTR(resolvedPid)); if (entry2) Tcl_DeleteHashEntry(entry2); FreeProcessInfo(info); @@ -893,8 +893,8 @@ TclProcessWait( /* * Unknown process, just call WaitProcessStatus and return. */ - - result = WaitProcessStatus(pid, TclpGetPid(pid), options, codePtr, + + result = WaitProcessStatus(pid, TclpGetPid(pid), options, codePtr, msgObjPtr, errorObjPtr); if (msgObjPtr && *msgObjPtr) Tcl_IncrRefCount(*msgObjPtr); if (errorObjPtr && *errorObjPtr) Tcl_IncrRefCount(*errorObjPtr); @@ -909,7 +909,7 @@ TclProcessWait( * so report no change. */ Tcl_MutexUnlock(&infoTablesMutex); - + return TCL_PROCESS_UNCHANGED; } @@ -919,7 +919,7 @@ TclProcessWait( * No change, stop there. */ Tcl_MutexUnlock(&infoTablesMutex); - + return TCL_PROCESS_UNCHANGED; } @@ -940,7 +940,7 @@ TclProcessWait( */ Tcl_DeleteHashEntry(entry); - entry = Tcl_FindHashEntry(&infoTablePerResolvedPid, + entry = Tcl_FindHashEntry(&infoTablePerResolvedPid, INT2PTR(info->resolvedPid)); Tcl_DeleteHashEntry(entry); FreeProcessInfo(info); diff --git a/generic/tclStringObj.c b/generic/tclStringObj.c index c106f0e..f98180f 100644 --- a/generic/tclStringObj.c +++ b/generic/tclStringObj.c @@ -490,7 +490,7 @@ TclCheckEmptyString( Tcl_DictObjSize(NULL, objPtr, &length); return length == 0; } - + if (objPtr->bytes == NULL) { return TCL_EMPTYSTRING_UNKNOWN; } @@ -3573,7 +3573,7 @@ TclStringFirst( start = 0; } if (ln == 0) { - /* We don't find empty substrings. Bizarre! + /* We don't find empty substrings. Bizarre! * Whenever this routine is turned into a proper substring * finder, change to `return start` after limits imposed. */ return -1; @@ -3970,7 +3970,7 @@ TclStringReplace( result = Tcl_NewByteArrayObj(NULL, numBytes - count + newBytes); /* PANIC? */ Tcl_SetByteArrayLength(result, 0); - TclAppendBytesToByteArray(result, bytes, first); + TclAppendBytesToByteArray(result, bytes, first); TclAppendBytesToByteArray(result, iBytes, newBytes); TclAppendBytesToByteArray(result, bytes + first + count, numBytes - count - first); @@ -3992,7 +3992,7 @@ TclStringReplace( Tcl_UniChar *ustring = Tcl_GetUnicodeFromObj(objPtr, &numChars); /* TODO: Is there an in-place option worth pursuing here? */ - + result = Tcl_NewUnicodeObj(ustring, first); if (insertPtr) { Tcl_AppendObjToObj(result, insertPtr); diff --git a/generic/tclUtil.c b/generic/tclUtil.c index 0ba6c8e..48602c4 100644 --- a/generic/tclUtil.c +++ b/generic/tclUtil.c @@ -120,7 +120,7 @@ static int FindElement(Tcl_Interp *interp, const char *string, /* * The following is the Tcl object type definition for an object that * represents a list index in the form, "end-offset". It is used as a - * performance optimization in TclGetIntForIndex. The internal rep is + * performance optimization in TclGetIntForIndex. The internal rep is * stored directly in the wideValue, so no memory management is required * for it. This is a caching intrep, keeping the result of a parse * around. This type is only created from a pre-existing string, so an @@ -1673,7 +1673,7 @@ UtfWellFormedEnd( if (Tcl_UtfCharComplete(p, l - p)) { return bytes; } - /* + /* * Malformed utf-8 end, be sure we've NTS to safe compare of end-character, * avoid segfault by access violation out of range. */ @@ -3793,7 +3793,7 @@ GetEndOffsetFromObj( return TCL_OK; } - + /* *---------------------------------------------------------------------- * @@ -3976,12 +3976,12 @@ TclIndexEncode( /* usual case, the absolute index value encodes itself */ } else if (TCL_OK == GetEndOffsetFromObj(objPtr, 0, &idx)) { /* - * We parsed an end+offset index value. + * We parsed an end+offset index value. * idx holds the offset value in the range INT_MIN...INT_MAX. */ if (idx > 0) { /* - * All end+postive or end-negative expressions + * All end+postive or end-negative expressions * always indicate "after the end". */ idx = after; diff --git a/library/msgcat/msgcat.tcl b/library/msgcat/msgcat.tcl index 598330d..129cd9c 100644 --- a/library/msgcat/msgcat.tcl +++ b/library/msgcat/msgcat.tcl @@ -49,7 +49,7 @@ namespace eval msgcat { namespace eval msgcat::mcutil { namespace export getsystemlocale getpreferences namespace ensemble create -prefix 0 - + # Map of language codes used in Windows registry to those of ISO-639 if {[info sharedlibextension] eq ".dll"} { variable WinRegToISO639 [dict create {*}{ @@ -292,7 +292,7 @@ proc msgcat::mcexists {args} { } } set src [lindex $args 0] - + if {![info exists ns]} { set ns [PackageNamespaceGet] } set loclist [PackagePreferences $ns] @@ -537,7 +537,7 @@ proc msgcat::mcpackagelocale {subcommand args} { set - preferences { # set a package locale or add a package locale set fSet [expr {$subcommand eq "set"}] - + # Check parameter if {$fSet && 1 < [llength $args] } { return -code error "wrong # args: should be\ @@ -1241,7 +1241,7 @@ proc ::msgcat::PackageNamespaceGet {} { } } } - + # Initialize the default locale proc msgcat::mcutil::getsystemlocale {} { global env diff --git a/tests/chanio.test b/tests/chanio.test index e7f51b3..300c54a 100644 --- a/tests/chanio.test +++ b/tests/chanio.test @@ -33,7 +33,7 @@ namespace eval ::tcl::test::io { loadTestedCommands catch [list package require -exact Tcltest [info patchlevel]] package require tcltests - + testConstraint testbytestring [llength [info commands testbytestring]] testConstraint testchannel [llength [info commands testchannel]] testConstraint openpipe 1 @@ -5957,7 +5957,7 @@ test chan-io-48.3 {testing readability conditions} -setup { chan close $f } -result {done {0 1 0 1 0 1 0 1 0 1 0 1 0 0}} unset path(bar) -removeFile bar +removeFile bar test chan-io-48.4 {lf write, testing readability, ^Z termination, auto read mode} -setup { file delete $path(test1) diff --git a/tests/env.test b/tests/env.test index 2c077b1..8434943 100644 --- a/tests/env.test +++ b/tests/env.test @@ -399,8 +399,8 @@ test env-8.0 { # cleanup -rename getenv {} -rename envrestore {} +rename getenv {} +rename envrestore {} rename envprep {} rename encodingrestore {} rename encodingswitch {} diff --git a/tests/expr.test b/tests/expr.test index abaf31d..713681a 100644 --- a/tests/expr.test +++ b/tests/expr.test @@ -7164,7 +7164,7 @@ test expr-52.1 { list [expr {$a eq {}}] [expr {$a < {}}] [expr {$a > {}}] [ string match {*no string representation*} [ ::tcl::unsupported::representation $a]] -} {0 0 1 1} +} {0 0 1 1} diff --git a/tests/msgcat.test b/tests/msgcat.test index 12030fb..3dde124 100644 --- a/tests/msgcat.test +++ b/tests/msgcat.test @@ -999,7 +999,7 @@ if {[package vsatisfies [package provide msgcat] 1.7]} { mcpackagelocale isset } -result {0} - + # Tests msgcat-13.*: [mcpackageconfig subcmds] test msgcat-13.1 {mcpackageconfig no subcommand} -body { @@ -1153,7 +1153,7 @@ if {[package vsatisfies [package provide msgcat] 1.7]} { # Tests msgcat-15.*: tcloo coverage - + # There are 4 use-cases, where 3 must be tested now: # - namespace defined, in class definition, class defined oo, classless @@ -1210,7 +1210,7 @@ if {[package vsatisfies [package provide msgcat] 1.7]} { } -body { bar::ObjCur method1 } -result con2bar - + test msgcat-15.4 {mc in classless object with explicite namespace eval}\ -setup { # full namespace is ::msgcat::test:bar @@ -1236,7 +1236,7 @@ if {[package vsatisfies [package provide msgcat] 1.7]} { } -body { bar::ObjCur method1 } -result con2baz - + # Test msgcat-16.*: command mcpackagenamespaceget test msgcat-16.1 {mcpackagenamespaceget in namespace procedure} -body { @@ -1298,7 +1298,7 @@ if {[package vsatisfies [package provide msgcat] 1.7]} { # Test msgcat-17.*: mcn command - + test msgcat-17.1 {mcn no parameters} -body { mcn } -returnCodes 1\ @@ -1328,26 +1328,26 @@ if {[package vsatisfies [package provide msgcat] 1.7]} { mcutil junk } -returnCodes 1\ -result {unknown subcommand "junk": must be getpreferences, or getsystemlocale} - + test msgcat-18.3 {mcutil - partial argument} -body { mcutil getsystem } -returnCodes 1\ -result {unknown subcommand "getsystem": must be getpreferences, or getsystemlocale} - + test msgcat-18.4 {mcutil getpreferences - no argument} -body { mcutil getpreferences } -returnCodes 1\ -result {wrong # args: should be "mcutil getpreferences locale"} - + test msgcat-18.5 {mcutil getpreferences - DE_de} -body { mcutil getpreferences DE_de } -result {de_de de {}} - + test msgcat-18.6 {mcutil getsystemlocale - wrong argument} -body { mcutil getsystemlocale DE_de } -returnCodes 1\ -result {wrong # args: should be "mcutil getsystemlocale"} - + # The result is system dependent # So just test if it runs # The environment variable version was test with test 0.x @@ -1355,8 +1355,8 @@ if {[package vsatisfies [package provide msgcat] 1.7]} { mcutil getsystemlocale set ok ok } -result {ok} - - + + cleanupTests } namespace delete ::msgcat::test diff --git a/tests/namespace.test b/tests/namespace.test index b9e6ead..606139f 100644 --- a/tests/namespace.test +++ b/tests/namespace.test @@ -205,7 +205,7 @@ test namespace-7.8 {Bug ba1419303b4c} -setup { namespace delete ns1 } } -body { - # No segmentation fault given --enable-symbols=mem. + # No segmentation fault given --enable-symbols=mem. namespace delete ns1 } -result {} diff --git a/tests/oo.test b/tests/oo.test index 9a22438..85af233 100644 --- a/tests/oo.test +++ b/tests/oo.test @@ -2153,7 +2153,7 @@ test oo-15.13.1 { } -cleanup { Cls destroy Cls2 destroy -} -result done +} -result done test oo-15.13.2 {OO: object cloning with target NS} -setup { oo::class create Super oo::class create Cls {superclass Super} diff --git a/tests/package.test b/tests/package.test index 69d9ddb..2dca06b 100644 --- a/tests/package.test +++ b/tests/package.test @@ -630,13 +630,13 @@ test package-3.54 {Tcl_PkgRequire procedure, coroutine support} -setup { } -body { coroutine coro1 apply {{} { package ifneeded t 2.1 { - yield + yield package provide t 2.1 } package require t 2.1 }} list [catch {coro1} msg] $msg -} -match glob -result {0 2.1} +} -match glob -result {0 2.1} test package-4.1 {Tcl_PackageCmd procedure} -returnCodes error -body { diff --git a/tests/process.test b/tests/process.test index b88c50a..5aa8354 100644 --- a/tests/process.test +++ b/tests/process.test @@ -63,7 +63,7 @@ test process-4.1 {exec one child} -body { set statuses [tcl::process status -wait] set status [lindex [tcl::process status $pid] 1] expr { - [llength $list] eq 1 + [llength $list] eq 1 && [lindex $list 0] eq $pid && [dict size $statuses] eq 1 && [dict get $statuses $pid] eq $status @@ -139,7 +139,7 @@ test process-5.1 {exec one child} -body { set statuses [tcl::process status -wait] set status [lindex [tcl::process status $pid] 1] expr { - [llength $list] eq 1 + [llength $list] eq 1 && [lindex $list 0] eq $pid && [dict size $statuses] eq 1 && [dict get $statuses $pid] eq $status diff --git a/tests/string.test b/tests/string.test index 772415c..d169193 100644 --- a/tests/string.test +++ b/tests/string.test @@ -280,7 +280,7 @@ test string-3.17.$noComp {string equal, unicode} { } 1 test string-3.18.$noComp {string equal, unicode} { run {string equal \334 \u00fc} -} 0 +} 0 test string-3.19.$noComp {string equal, unicode} { run {string equal \334\334\334\374\374 \334\334\334\334\334} } 0 @@ -307,7 +307,7 @@ test string-3.24.$noComp {string equal -nocase with length} { } 1 test string-3.25.$noComp {string equal -nocase with length} { run {string equal -nocase -length 3 abcde Abxyz} -} 0 +} 0 test string-3.26.$noComp {string equal -nocase with length <= 0} { run {string equal -nocase -length -1 abcde AbCdEf} } 0 diff --git a/tests/tcltest.test b/tests/tcltest.test index 0bcf342..1487865 100644 --- a/tests/tcltest.test +++ b/tests/tcltest.test @@ -908,7 +908,7 @@ removeFile load.tcl # [interpreter] test tcltest-13.1 {interpreter} { - -constraints notValgrind + -constraints notValgrind -setup { #to do: Why is $::tcltest::tcltest being saved and restored here? set old $::tcltest::tcltest @@ -926,7 +926,7 @@ test tcltest-13.1 {interpreter} { # constraint, which involves a call to [exec] that might fail after # "fork" and before "exec", in which case the forked process will not # have a chance to clean itself up before exiting, which causes - # valgrind to issue numerous "still reachable" reports. + # valgrind to issue numerous "still reachable" reports. set ::tcltest::tcltest $old } } diff --git a/unix/tclEpollNotfy.c b/unix/tclEpollNotfy.c index ca194c7..2abfd47 100644 --- a/unix/tclEpollNotfy.c +++ b/unix/tclEpollNotfy.c @@ -88,7 +88,7 @@ typedef struct { LIST_HEAD(PlatformReadyFileHandlerList, FileHandler); typedef struct ThreadSpecificData { - FileHandler *triggerFilePtr; + FileHandler *triggerFilePtr; FileHandler *firstFileHandlerPtr; /* Pointer to head of file handler list. */ struct PlatformReadyFileHandlerList firstReadyFileHandlerPtr; diff --git a/win/makefile.vc b/win/makefile.vc index ceeaa02..1aae9a3 100644 --- a/win/makefile.vc +++ b/win/makefile.vc @@ -55,7 +55,7 @@ # c:\tcl_src\win\>nmake -f makefile.vc release # c:\tcl_src\win\>nmake -f makefile.vc test # c:\tcl_src\win\>nmake -f makefile.vc install INSTALLDIR=c:\progra~1\tcl -# c:\tcl_src\win\>nmake -f makefile.vc release OPTS=pdbs +# c:\tcl_src\win\>nmake -f makefile.vc release OPTS=pdbs # c:\tcl_src\win\>nmake -f makefile.vc release OPTS=symbols # diff --git a/win/nmakehlp.c b/win/nmakehlp.c index b759020..1655d48 100644 --- a/win/nmakehlp.c +++ b/win/nmakehlp.c @@ -686,10 +686,10 @@ SubstituteFile( BOOL FileExists(LPCTSTR szPath) { #ifndef INVALID_FILE_ATTRIBUTES - #define INVALID_FILE_ATTRIBUTES ((DWORD)-1) + #define INVALID_FILE_ATTRIBUTES ((DWORD)-1) #endif DWORD pathAttr = GetFileAttributes(szPath); - return (pathAttr != INVALID_FILE_ATTRIBUTES && + return (pathAttr != INVALID_FILE_ATTRIBUTES && !(pathAttr & FILE_ATTRIBUTE_DIRECTORY)); } @@ -740,7 +740,7 @@ static int LocateDependencyHelper(const char *dir, const char *keypath) #if 0 /* This function is not available in Visual C++ 6 */ /* * Use numerics 0 -> FindExInfoStandard, - * 1 -> FindExSearchLimitToDirectories, + * 1 -> FindExSearchLimitToDirectories, * as these are not defined in Visual C++ 6 */ hSearch = FindFirstFileEx(path, 0, &finfo, 1, NULL, 0); @@ -755,7 +755,7 @@ static int LocateDependencyHelper(const char *dir, const char *keypath) do { int sublen; /* - * We need to check it is a directory despite the + * We need to check it is a directory despite the * FindExSearchLimitToDirectories in the above call. See SDK docs */ if ((finfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) @@ -786,7 +786,7 @@ static int LocateDependencyHelper(const char *dir, const char *keypath) * that is used to confirm it is the correct directory. * The search path for the package directory is currently only * the parent and grandparent of the current working directory. - * If found, the command prints + * If found, the command prints * name_DIRPATH= * and returns 0. If not found, does not print anything and returns 1. */ @@ -794,7 +794,7 @@ static int LocateDependency(const char *keypath) { int i, ret; static char *paths[] = {"..", "..\\..", "..\\..\\.."}; - + for (i = 0; i < (sizeof(paths)/sizeof(paths[0])); ++i) { ret = LocateDependencyHelper(paths[i], keypath); if (ret == 0) diff --git a/win/tclWinFile.c b/win/tclWinFile.c index a88ef72..dfeeef1 100644 --- a/win/tclWinFile.c +++ b/win/tclWinFile.c @@ -1440,9 +1440,9 @@ TclpGetUserHome( domain = Tcl_UtfFindFirst(name, '@'); if (domain == NULL) { const char *ptr; - + /* no domain - firstly check it's the current user */ - if ( (ptr = TclpGetUserName(&ds)) != NULL + if ( (ptr = TclpGetUserName(&ds)) != NULL && strcasecmp(name, ptr) == 0 ) { /* try safest and fastest way to get current user home */ @@ -1465,7 +1465,7 @@ TclpGetUserHome( Tcl_DStringInit(&ds); wName = Tcl_UtfToUniCharDString(name, nameLen, &ds); while (NetUserGetInfo(wDomain, wName, 1, (LPBYTE *) &uiPtr) != 0) { - /* + /* * user does not exists - if domain was not specified, * try again using current domain. */ @@ -1580,7 +1580,7 @@ NativeAccess( return 0; } - /* + /* * If it's not a directory (assume file), do several fast checks: */ if (!(attr & FILE_ATTRIBUTE_DIRECTORY)) { @@ -2009,7 +2009,7 @@ NativeStat( */ fileHandle = CreateFile(nativePath, GENERIC_READ, - FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, + FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, NULL); -- cgit v0.12 From de5637f8531520d3487ac143217d326570a4b0d8 Mon Sep 17 00:00:00 2001 From: sebres Date: Fri, 3 Aug 2018 13:46:30 +0000 Subject: ioTrans.test: fixed cleanup - avoids `error deleting "tempchanfile": permission denied`: file seems to be locked/opened inside interp $idb --- tests/ioTrans.test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/ioTrans.test b/tests/ioTrans.test index 3bebc70..85e427a 100644 --- a/tests/ioTrans.test +++ b/tests/ioTrans.test @@ -1240,8 +1240,8 @@ test iortrans-11.1 {origin interpreter of moved transform destroyed during acces set res }] } -cleanup { - tempdone interp delete $idb + tempdone } -result {Owner lost} test iortrans-11.2 {delete interp of reflected transform} -setup { interp create slave -- cgit v0.12 From d87884d51b4fcfc7d9a09febe9a351dad983d732 Mon Sep 17 00:00:00 2001 From: dkf Date: Sun, 5 Aug 2018 15:01:30 +0000 Subject: Make it much easier to maintain the TclOO initialisation script. --- generic/tclOOScript.h | 44 ++++++------ generic/tclOOScript.tcl | 183 ++++++++++++++++++++++++++++++++++++++++++++++++ tools/makeHeader.tcl | 164 +++++++++++++++++++++++++++++++++++++++++++ unix/Makefile.in | 9 +++ 4 files changed, 379 insertions(+), 21 deletions(-) create mode 100644 generic/tclOOScript.tcl create mode 100644 tools/makeHeader.tcl diff --git a/generic/tclOOScript.h b/generic/tclOOScript.h index ffdedb8..1f345fb 100644 --- a/generic/tclOOScript.h +++ b/generic/tclOOScript.h @@ -21,16 +21,17 @@ */ static const char *tclOOSetupScript = +/* !BEGIN!: Do not edit below this line. */ "::proc ::oo::Helpers::callback {method args} {\n" " list [uplevel 1 {namespace which my}] $method {*}$args\n" "}\n" - +"\n" "::proc ::oo::Helpers::mymethod {method args} {\n" " list [uplevel 1 {namespace which my}] $method {*}$args\n" "}\n" - +"\n" "::proc ::oo::Helpers::classvariable {name args} {\n" -" # Get a reference to the class's namespace\n" +" # Get a reference to the class\'s namespace\n" " set ns [info object namespace [uplevel 1 {self class}]]\n" " # Double up the list of variable names\n" " foreach v [list $name {*}$args] {\n" @@ -42,10 +43,10 @@ static const char *tclOOSetupScript = " }\n" " lappend vs $v $v\n" " }\n" -" # Lastly, link the caller's local variables to the class's variables\n" +" # Lastly, link the caller\'s local variables to the class\'s variables\n" " tailcall namespace upvar $ns {*}$vs\n" "}\n" - +"\n" "::proc ::oo::Helpers::link {args} {\n" " set ns [uplevel 1 {namespace current}]\n" " foreach link $args {\n" @@ -68,11 +69,11 @@ static const char *tclOOSetupScript = " rename $cmd {}\n" " }\n" "}\n" - +"\n" "::proc ::oo::DelegateName {class} {\n" " string cat [info object namespace $class] {:: oo ::delegate}\n" "}\n" - +"\n" "proc ::oo::MixinClassDelegates {class} {\n" " if {![info object isa class $class]} {\n" " return\n" @@ -81,7 +82,7 @@ static const char *tclOOSetupScript = " if {![info object isa class $delegate]} {\n" " return\n" " }\n" -" foreach c [info class superclass $class] {" +" foreach c [info class superclass $class] {\n" " set d [::oo::DelegateName $c]\n" " if {![info object isa class $d]} {\n" " continue\n" @@ -90,14 +91,14 @@ static const char *tclOOSetupScript = " }\n" " ::oo::objdefine $class mixin -append $delegate\n" "}\n" - -"::namespace eval ::oo::define {" +"\n" +"::namespace eval ::oo::define {\n" " ::proc classmethod {name {args {}} {body {}}} {\n" " # Create the method on the class if the caller gave arguments and body\n" " ::set argc [::llength [::info level 0]]\n" " ::if {$argc == 3} {\n" -" ::return -code error [::string cat {wrong # args: should be \"}" -" [::lindex [::info level 0] 0] { name ?args body?\"}]\n" +" ::return -code error [::string cat {wrong # args: should be \"} \\\n" +" [::lindex [::info level 0] 0] { name \?args body\?\"}]\n" " }\n" " ::set cls [::uplevel 1 self]\n" " ::if {$argc == 4} {\n" @@ -106,12 +107,12 @@ static const char *tclOOSetupScript = " # Make the connection by forwarding\n" " ::tailcall forward $name myclass $name\n" " }\n" - +"\n" " ::proc initialise {body} {\n" " ::set clsns [::info object namespace [::uplevel 1 self]]\n" " ::tailcall apply [::list {} $body $clsns]\n" " }\n" - +"\n" " # Make the initialise command appear with US spelling too\n" " ::namespace export initialise\n" " ::namespace eval tmp {::namespace import ::oo::define::initialise}\n" @@ -119,11 +120,11 @@ static const char *tclOOSetupScript = " ::namespace delete tmp\n" " ::namespace export -clear\n" "}\n" - +"\n" "::oo::define ::oo::Slot {\n" " method Get {} {return -code error unimplemented}\n" " method Set list {return -code error unimplemented}\n" - +"\n" " method -set args {tailcall my Set $args}\n" " method -append args {\n" " set current [uplevel 1 [list [namespace which my] Get]]\n" @@ -131,7 +132,7 @@ static const char *tclOOSetupScript = " }\n" " method -clear {} {tailcall my Set {}}\n" " forward --default-operation my -append\n" - +"\n" " method unknown {args} {\n" " set def --default-operation\n" " if {[llength $args] == 0} {\n" @@ -141,7 +142,7 @@ static const char *tclOOSetupScript = " }\n" " next {*}$args\n" " }\n" - +"\n" " export -set -append -clear\n" " unexport unknown destroy\n" "}\n" @@ -149,7 +150,7 @@ static const char *tclOOSetupScript = "::oo::objdefine ::oo::define::superclass forward --default-operation my -set\n" "::oo::objdefine ::oo::define::mixin forward --default-operation my -set\n" "::oo::objdefine ::oo::objdefine::mixin forward --default-operation my -set\n" - +"\n" "::oo::define ::oo::class method {originObject} {\n" " next $originObject\n" " # Rebuild the class inheritance delegation class\n" @@ -162,7 +163,7 @@ static const char *tclOOSetupScript = " }]\n" " }\n" "}\n" - +"\n" "::oo::class create ::oo::singleton {\n" " superclass ::oo::class\n" " variable object\n" @@ -180,11 +181,12 @@ static const char *tclOOSetupScript = " return $object\n" " }\n" "}\n" - +"\n" "::oo::class create ::oo::abstract {\n" " superclass ::oo::class\n" " unexport create createWithNamespace new\n" "}\n" +/* !END!: Do not edit above this line. */ ; /* diff --git a/generic/tclOOScript.tcl b/generic/tclOOScript.tcl new file mode 100644 index 0000000..e0af23f --- /dev/null +++ b/generic/tclOOScript.tcl @@ -0,0 +1,183 @@ +# tclOOScript.h -- +# +# This file contains support scripts for TclOO. They are defined here so +# that the code can be definitely run even in safe interpreters; TclOO's +# core setup is safe. +# +# Copyright (c) 2012-2018 Donal K. Fellows +# Copyright (c) 2013 Andreas Kupries +# Copyright (c) 2017 Gerald Lester +# +# See the file "license.terms" for information on usage and redistribution of +# this file, and for a DISCLAIMER OF ALL WARRANTIES. + +::proc ::oo::Helpers::callback {method args} { + list [uplevel 1 {namespace which my}] $method {*}$args +} + +::proc ::oo::Helpers::mymethod {method args} { + list [uplevel 1 {namespace which my}] $method {*}$args +} + +::proc ::oo::Helpers::classvariable {name args} { + # Get a reference to the class's namespace + set ns [info object namespace [uplevel 1 {self class}]] + # Double up the list of variable names + foreach v [list $name {*}$args] { + if {[string match *(*) $v]} { + return -code error [string cat {bad variable name "} $v {": can't create a scalar variable that looks like an array element}] + } + if {[string match *::* $v]} { + return -code error [string cat {bad variable name "} $v {": can't create a local variable with a namespace separator in it}] + } + lappend vs $v $v + } + # Lastly, link the caller's local variables to the class's variables + tailcall namespace upvar $ns {*}$vs +} + +::proc ::oo::Helpers::link {args} { + set ns [uplevel 1 {namespace current}] + foreach link $args { + if {[llength $link] == 2} { + lassign $link src dst + } else { + lassign $link src + set dst $src + } + if {![string match ::* $src]} { + set src [string cat $ns :: $src] + } + interp alias {} $src {} ${ns}::my $dst + trace add command ${ns}::my delete [list ::oo::Helpers::Unlink $src] + } + return +} +::proc ::oo::Helpers::Unlink {cmd args} { + if {[namespace which $cmd] ne {}} { + rename $cmd {} + } +} + +::proc ::oo::DelegateName {class} { + string cat [info object namespace $class] {:: oo ::delegate} +} + +proc ::oo::MixinClassDelegates {class} { + if {![info object isa class $class]} { + return + } + set delegate [::oo::DelegateName $class] + if {![info object isa class $delegate]} { + return + } + foreach c [info class superclass $class] { + set d [::oo::DelegateName $c] + if {![info object isa class $d]} { + continue + } + ::oo::define $delegate superclass -append $d + } + ::oo::objdefine $class mixin -append $delegate +} + +::namespace eval ::oo::define { + ::proc classmethod {name {args {}} {body {}}} { + # Create the method on the class if the caller gave arguments and body + ::set argc [::llength [::info level 0]] + ::if {$argc == 3} { + ::return -code error [::string cat {wrong # args: should be "} \ + [::lindex [::info level 0] 0] { name ?args body?"}] + } + ::set cls [::uplevel 1 self] + ::if {$argc == 4} { + ::oo::define [::oo::DelegateName $cls] method $name $args $body + } + # Make the connection by forwarding + ::tailcall forward $name myclass $name + } + + ::proc initialise {body} { + ::set clsns [::info object namespace [::uplevel 1 self]] + ::tailcall apply [::list {} $body $clsns] + } + + # Make the initialise command appear with US spelling too + ::namespace export initialise + ::namespace eval tmp {::namespace import ::oo::define::initialise} + ::rename ::oo::define::tmp::initialise initialize + ::namespace delete tmp + ::namespace export -clear +} + +::oo::define ::oo::Slot { + method Get {} {return -code error unimplemented} + method Set list {return -code error unimplemented} + + method -set args {tailcall my Set $args} + method -append args { + set current [uplevel 1 [list [namespace which my] Get]] + tailcall my Set [list {*}$current {*}$args] + } + method -clear {} {tailcall my Set {}} + forward --default-operation my -append + + method unknown {args} { + set def --default-operation + if {[llength $args] == 0} { + tailcall my $def + } elseif {![string match -* [lindex $args 0]]} { + tailcall my $def {*}$args + } + next {*}$args + } + + export -set -append -clear + unexport unknown destroy +} + +::oo::objdefine ::oo::define::superclass forward --default-operation my -set +::oo::objdefine ::oo::define::mixin forward --default-operation my -set +::oo::objdefine ::oo::objdefine::mixin forward --default-operation my -set + +::oo::define ::oo::class method {originObject} { + next $originObject + # Rebuild the class inheritance delegation class + set originDelegate [::oo::DelegateName $originObject] + set targetDelegate [::oo::DelegateName [self]] + if {[info object isa class $originDelegate] && ![info object isa class $targetDelegate]} { + ::oo::copy $originDelegate $targetDelegate + ::oo::objdefine [self] mixin -set {*}[lmap c [info object mixin [self]] { + if {$c eq $originDelegate} {set targetDelegate} {set c} + }] + } +} + +::oo::class create ::oo::singleton { + superclass ::oo::class + variable object + unexport create createWithNamespace + method new args { + if {![info exists object] || ![info object isa object $object]} { + set object [next {*}$args] + ::oo::objdefine $object method destroy {} { + return -code error {may not destroy a singleton object} + } + ::oo::objdefine $object method {originObject} { + return -code error {may not clone a singleton object} + } + } + return $object + } +} + +::oo::class create ::oo::abstract { + superclass ::oo::class + unexport create createWithNamespace new +} + +# Local Variables: +# mode: tcl +# c-basic-offset: 4 +# fill-column: 78 +# End: diff --git a/tools/makeHeader.tcl b/tools/makeHeader.tcl new file mode 100644 index 0000000..8af35fc --- /dev/null +++ b/tools/makeHeader.tcl @@ -0,0 +1,164 @@ +# makeHeader.tcl -- +# +# This script generates embeddable C source (in a .h file) from a .tcl +# script. +# +# Copyright (c) 2018 Donal K. Fellows +# +# See the file "license.terms" for information on usage and redistribution +# of this file, and for a DISCLAIMER OF ALL WARRANTIES. + +package require Tcl 8.6 + +namespace eval makeHeader { + + #################################################################### + # + # mapSpecial -- + # Transform a single line so that it is able to be put in a C string. + # + proc mapSpecial {str} { + # All Tcl metacharacters and key C backslash sequences + set MAP { + \" \\\\\" \\ \\\\\\\\ $ \\$ [ \\[ ] \\] ' \\\\' ? \\\\? + \a \\\\a \b \\\\b \f \\\\f \n \\\\n \r \\\\r \t \\\\t \v \\\\v + } + set XFORM {[format \\\\\\\\u%04x {*}[scan & %c]]} + + subst [regsub -all {[^\u0020-\u007e]} [string map $MAP $str] $XFORM] + } + + #################################################################### + # + # processScript -- + # Transform a whole sequence of lines with [mapSpecial]. + # + proc processScript {scriptLines} { + lmap line $scriptLines { + format {"%s"} [mapSpecial $line\n] + } + } + + #################################################################### + # + # updateTemplate -- + # Rewrite a template to contain the content from the input script. + # + proc updateTemplate {dataVar scriptLines} { + set BEGIN "*!BEGIN!: Do not edit below this line.*" + set END "*!END!: Do not edit above this line.*" + + upvar 1 $dataVar data + + set from [lsearch -glob $data $BEGIN] + set to [lsearch -glob $data $END] + if {$from == -1 || $to == -1 || $from >= $to} { + throw BAD "not a template" + } + + set data [lreplace $data $from+1 $to-1 {*}[processScript $scriptLines]] + } + + #################################################################### + # + # stripSurround -- + # Removes the header and footer comments from a (line-split list of + # lines of) Tcl script code. + # + proc stripSurround {lines} { + set RE {^\s*$|^#} + set state 0 + set lines [lmap line [lreverse $lines] { + if {!$state && [regexp $RE $line]} continue { + set state 1 + set line + } + }] + return [lmap line [lreverse $lines] { + if {$state && [regexp $RE $line]} continue { + set state 0 + set line + } + }] + } + + #################################################################### + # + # updateTemplateFile -- + # Rewrites a template file with the lines of the given script. + # + proc updateTemplateFile {headerFile scriptLines} { + set f [open $headerFile "r+"] + try { + set content [split [chan read -nonewline $f] "\n"] + updateTemplate content [stripSurround $scriptLines] + chan seek $f 0 + chan puts $f [join $content \n] + chan truncate $f + } trap BAD msg { + # Add the filename to the message + throw BAD "${headerFile}: $msg" + } finally { + chan close $f + } + } + + #################################################################### + # + # readScript -- + # Read a script from a file and return its lines. + # + proc readScript {script} { + set f [open $script] + try { + chan configure $f -encoding utf-8 + return [split [string trim [chan read $f]] "\n"] + } finally { + chan close $f + } + } + + #################################################################### + # + # run -- + # The main program of this script. + # + proc run {args} { + try { + if {[llength $args] != 2} { + throw ARGS "inputTclScript templateFile" + } + lassign $args inputTclScript templateFile + + puts "Inserting $inputTclScript into $templateFile" + set scriptLines [readScript $inputTclScript] + updateTemplateFile $templateFile $scriptLines + exit 0 + } trap ARGS msg { + puts stderr "wrong # args: should be \"[file tail $::argv0] $msg\"" + exit 2 + } trap BAD msg { + puts stderr $msg + exit 1 + } trap POSIX msg { + puts stderr $msg + exit 1 + } on error {- opts} { + puts stderr [dict get $opts -errorinfo] + exit 3 + } + } +} + +######################################################################## +# +# Launch the main program +# +if {[info script] eq $::argv0} { + makeHeader::run {*}$::argv +} + +# Local-Variables: +# mode: tcl +# fill-column: 78 +# End: diff --git a/unix/Makefile.in b/unix/Makefile.in index e4d77e6..6ae2b0d 100644 --- a/unix/Makefile.in +++ b/unix/Makefile.in @@ -1895,6 +1895,11 @@ $(GENERIC_DIR)/tclOOStubInit.c: $(GENERIC_DIR)/tclOO.decls @echo "Developers may want to run \"make genstubs\" to regenerate." @echo "This warning can be safely ignored, do not report as a bug!" +$(GENERIC_DIR)/tclOOScript.h: $(GENERIC_DIR)/tclOOScript.tcl + @echo "Warning: tclOOScript.h may be out of date." + @echo "Developers may want to run \"make genscript\" to regenerate." + @echo "This warning can be safely ignored, do not report as a bug!" + genstubs: $(NATIVE_TCLSH) $(TOOL_DIR)/genStubs.tcl $(GENERIC_DIR) \ $(GENERIC_DIR)/tcl.decls $(GENERIC_DIR)/tclInt.decls \ @@ -1902,6 +1907,10 @@ genstubs: $(NATIVE_TCLSH) $(TOOL_DIR)/genStubs.tcl $(GENERIC_DIR) \ $(GENERIC_DIR)/tclOO.decls +genscript: + $(NATIVE_TCLSH) $(TOOL_DIR)/makeHeader.tcl \ + $(GENERIC_DIR)/tclOOScript.tcl $(GENERIC_DIR)/tclOOScript.h + # # Target to check that all exported functions have an entry in the stubs # tables. -- cgit v0.12 From ed3e9c60bac115e7ad38b1169dacc8bf974e99d2 Mon Sep 17 00:00:00 2001 From: dkf Date: Sun, 5 Aug 2018 20:14:04 +0000 Subject: Combine the two bits of scripted code inside TclOO's definition into one. --- generic/tclOO.c | 14 +--- generic/tclOOScript.h | 215 +++++++++++++++++++++++++++--------------------- generic/tclOOScript.tcl | 188 +++++++++++++++++++++++++++--------------- tools/makeHeader.tcl | 2 +- 4 files changed, 244 insertions(+), 175 deletions(-) diff --git a/generic/tclOO.c b/generic/tclOO.c index 630e977..7702b2b 100644 --- a/generic/tclOO.c +++ b/generic/tclOO.c @@ -312,7 +312,7 @@ InitFoundation( ThreadLocalData *tsdPtr = Tcl_GetThreadData(&tsdKey, sizeof(ThreadLocalData)); Foundation *fPtr = ckalloc(sizeof(Foundation)); - Tcl_Obj *namePtr, *argsPtr, *bodyPtr; + Tcl_Obj *namePtr; Tcl_DString buffer; Command *cmdPtr; int i; @@ -392,18 +392,6 @@ InitFoundation( } /* - * Create the default method implementation, used when 'oo::copy' - * is called to finish the copying of one object to another. - */ - - TclNewLiteralStringObj(argsPtr, "originObject"); - Tcl_IncrRefCount(argsPtr); - bodyPtr = Tcl_NewStringObj(clonedBody, -1); - TclOONewProcMethod(interp, fPtr->objectCls, 0, fPtr->clonedName, argsPtr, - bodyPtr, NULL); - TclDecrRefCount(argsPtr); - - /* * Finish setting up the class of classes by marking the 'new' method as * private; classes, unlike general objects, must have explicit names. We * also need to create the constructor for classes. diff --git a/generic/tclOOScript.h b/generic/tclOOScript.h index 1f345fb..d89e81a 100644 --- a/generic/tclOOScript.h +++ b/generic/tclOOScript.h @@ -22,74 +22,103 @@ static const char *tclOOSetupScript = /* !BEGIN!: Do not edit below this line. */ -"::proc ::oo::Helpers::callback {method args} {\n" -" list [uplevel 1 {namespace which my}] $method {*}$args\n" -"}\n" +"::namespace eval ::oo::Helpers {\n" +" ::namespace path {}\n" "\n" -"::proc ::oo::Helpers::mymethod {method args} {\n" -" list [uplevel 1 {namespace which my}] $method {*}$args\n" -"}\n" +" proc callback {method args} {\n" +" list [uplevel 1 {::namespace which my}] $method {*}$args\n" +" }\n" "\n" -"::proc ::oo::Helpers::classvariable {name args} {\n" -" # Get a reference to the class\'s namespace\n" -" set ns [info object namespace [uplevel 1 {self class}]]\n" -" # Double up the list of variable names\n" -" foreach v [list $name {*}$args] {\n" -" if {[string match *(*) $v]} {\n" -" return -code error [string cat {bad variable name \"} $v {\": can\'t create a scalar variable that looks like an array element}]\n" -" }\n" -" if {[string match *::* $v]} {\n" -" return -code error [string cat {bad variable name \"} $v {\": can\'t create a local variable with a namespace separator in it}]\n" -" }\n" -" lappend vs $v $v\n" +" proc mymethod {method args} {\n" +" list [uplevel 1 {::namespace which my}] $method {*}$args\n" " }\n" -" # Lastly, link the caller\'s local variables to the class\'s variables\n" -" tailcall namespace upvar $ns {*}$vs\n" -"}\n" "\n" -"::proc ::oo::Helpers::link {args} {\n" -" set ns [uplevel 1 {namespace current}]\n" -" foreach link $args {\n" -" if {[llength $link] == 2} {\n" -" lassign $link src dst\n" -" } else {\n" -" lassign $link src\n" -" set dst $src\n" -" }\n" -" if {![string match ::* $src]} {\n" -" set src [string cat $ns :: $src]\n" +" proc classvariable {name args} {\n" +" # Get a reference to the class\'s namespace\n" +" set ns [info object namespace [uplevel 1 {self class}]]\n" +" # Double up the list of variable names\n" +" foreach v [list $name {*}$args] {\n" +" if {[string match *(*) $v]} {\n" +" variable \n" +" return -code error [format \\\n" +" {bad variable name \"%s\": can\'t create a scalar variable that looks like an array element} \\\n" +" $v]\n" +" }\n" +" if {[string match *::* $v]} {\n" +" return -code error [format \\\n" +" {bad variable name \"%s\": can\'t create a local variable with a namespace separator in it} \\\n" +" $v]\n" +" }\n" +" lappend vs $v $v\n" " }\n" -" interp alias {} $src {} ${ns}::my $dst\n" -" trace add command ${ns}::my delete [list ::oo::Helpers::Unlink $src]\n" +" # Lastly, link the caller\'s local variables to the class\'s variables\n" +" tailcall namespace upvar $ns {*}$vs\n" " }\n" -" return\n" -"}\n" -"::proc ::oo::Helpers::Unlink {cmd args} {\n" -" if {[namespace which $cmd] ne {}} {\n" -" rename $cmd {}\n" +"\n" +" proc link {args} {\n" +" set ns [uplevel 1 {::namespace current}]\n" +" foreach link $args {\n" +" if {[llength $link] == 2} {\n" +" lassign $link src dst\n" +" } else {\n" +" lassign $link src\n" +" set dst $src\n" +" }\n" +" if {![string match ::* $src]} {\n" +" set src [string cat $ns :: $src]\n" +" }\n" +" interp alias {} $src {} ${ns}::my $dst\n" +" trace add command ${ns}::my delete [list \\\n" +" ::oo::UnlinkLinkedCommand $src]\n" +" }\n" +" return\n" " }\n" "}\n" "\n" -"::proc ::oo::DelegateName {class} {\n" -" string cat [info object namespace $class] {:: oo ::delegate}\n" -"}\n" +"::namespace eval ::oo {\n" +" proc UnlinkLinkedCommand {cmd args} {\n" +" if {[namespace which $cmd] ne {}} {\n" +" rename $cmd {}\n" +" }\n" +" }\n" "\n" -"proc ::oo::MixinClassDelegates {class} {\n" -" if {![info object isa class $class]} {\n" -" return\n" +" proc DelegateName {class} {\n" +" string cat [info object namespace $class] {:: oo ::delegate}\n" " }\n" -" set delegate [::oo::DelegateName $class]\n" -" if {![info object isa class $delegate]} {\n" -" return\n" +"\n" +" proc MixinClassDelegates {class} {\n" +" if {![info object isa class $class]} {\n" +" return\n" +" }\n" +" set delegate [DelegateName $class]\n" +" if {![info object isa class $delegate]} {\n" +" return\n" +" }\n" +" foreach c [info class superclass $class] {\n" +" set d [DelegateName $c]\n" +" if {![info object isa class $d]} {\n" +" continue\n" +" }\n" +" define $delegate superclass -append $d\n" +" }\n" +" objdefine $class mixin -append $delegate\n" " }\n" -" foreach c [info class superclass $class] {\n" -" set d [::oo::DelegateName $c]\n" -" if {![info object isa class $d]} {\n" -" continue\n" +"\n" +" proc UpdateClassDelegatesAfterClone {originObject targetObject} {\n" +" # Rebuild the class inheritance delegation class\n" +" set originDelegate [DelegateName $originObject]\n" +" set targetDelegate [DelegateName $targetObject]\n" +" if {\n" +" [info object isa class $originDelegate]\n" +" && ![info object isa class $targetDelegate]\n" +" } then {\n" +" copy $originDelegate $targetDelegate\n" +" objdefine $targetObject mixin -set \\\n" +" {*}[lmap c [info object mixin $targetObject] {\n" +" if {$c eq $originDelegate} {set targetDelegate} {set c}\n" +" }]\n" " }\n" -" ::oo::define $delegate superclass -append $d\n" " }\n" -" ::oo::objdefine $class mixin -append $delegate\n" "}\n" "\n" "::namespace eval ::oo::define {\n" @@ -97,8 +126,9 @@ static const char *tclOOSetupScript = " # Create the method on the class if the caller gave arguments and body\n" " ::set argc [::llength [::info level 0]]\n" " ::if {$argc == 3} {\n" -" ::return -code error [::string cat {wrong # args: should be \"} \\\n" -" [::lindex [::info level 0] 0] { name \?args body\?\"}]\n" +" ::return -code error [::format \\\n" +" {wrong # args: should be \"%s name \?args body\?\"} \\\n" +" [::lindex [::info level 0] 0]]\n" " }\n" " ::set cls [::uplevel 1 self]\n" " ::if {$argc == 4} {\n" @@ -151,17 +181,43 @@ static const char *tclOOSetupScript = "::oo::objdefine ::oo::define::mixin forward --default-operation my -set\n" "::oo::objdefine ::oo::objdefine::mixin forward --default-operation my -set\n" "\n" +"::oo::define ::oo::object method {originObject} {\n" +" # Copy over the procedures from the original namespace\n" +" foreach p [info procs [info object namespace $originObject]::*] {\n" +" set args [info args $p]\n" +" set idx -1\n" +" foreach a $args {\n" +" if {[info default $p $a d]} {\n" +" lset args [incr idx] [list $a $d]\n" +" } else {\n" +" lset args [incr idx] [list $a]\n" +" }\n" +" }\n" +" set b [info body $p]\n" +" set p [namespace tail $p]\n" +" proc $p $args $b\n" +" }\n" +" # Copy over the variables from the original namespace\n" +" foreach v [info vars [info object namespace $originObject]::*] {\n" +" upvar 0 $v vOrigin\n" +" namespace upvar [namespace current] [namespace tail $v] vNew\n" +" if {[info exists vOrigin]} {\n" +" if {[array exists vOrigin]} {\n" +" array set vNew [array get vOrigin]\n" +" } else {\n" +" set vNew $vOrigin\n" +" }\n" +" }\n" +" }\n" +" # General commands, sub-namespaces and advancd variable config (traces,\n" +" # etc) are *not* copied over. Classes that want that should do it\n" +" # themselves.\n" +"}\n" +"\n" "::oo::define ::oo::class method {originObject} {\n" " next $originObject\n" " # Rebuild the class inheritance delegation class\n" -" set originDelegate [::oo::DelegateName $originObject]\n" -" set targetDelegate [::oo::DelegateName [self]]\n" -" if {[info object isa class $originDelegate] && ![info object isa class $targetDelegate]} {\n" -" ::oo::copy $originDelegate $targetDelegate\n" -" ::oo::objdefine [self] mixin -set {*}[lmap c [info object mixin [self]] {\n" -" if {$c eq $originDelegate} {set targetDelegate} {set c}\n" -" }]\n" -" }\n" +" ::oo::UpdateClassDelegatesAfterClone $originObject [self]\n" "}\n" "\n" "::oo::class create ::oo::singleton {\n" @@ -188,37 +244,6 @@ static const char *tclOOSetupScript = "}\n" /* !END!: Do not edit above this line. */ ; - -/* - * The body of the method of oo::object. - */ - -static const char *clonedBody = -"# Copy over the procedures from the original namespace\n" -"foreach p [info procs [info object namespace $originObject]::*] {\n" -" set args [info args $p]\n" -" set idx -1\n" -" foreach a $args {\n" -" lset args [incr idx]" -" [if {[info default $p $a d]} {list $a $d} {list $a}]\n" -" }\n" -" set b [info body $p]\n" -" set p [namespace tail $p]\n" -" proc $p $args $b\n" -"}\n" -"# Copy over the variables from the original namespace\n" -"foreach v [info vars [info object namespace $originObject]::*] {\n" -" upvar 0 $v vOrigin\n" -" namespace upvar [namespace current] [namespace tail $v] vNew\n" -" if {[info exists vOrigin]} {\n" -" if {[array exists vOrigin]} {\n" -" array set vNew [array get vOrigin]\n" -" } else {\n" -" set vNew $vOrigin\n" -" }\n" -" }\n" -"}\n" -; #endif /* TCL_OO_SCRIPT_H */ diff --git a/generic/tclOOScript.tcl b/generic/tclOOScript.tcl index e0af23f..c0b4d1f 100644 --- a/generic/tclOOScript.tcl +++ b/generic/tclOOScript.tcl @@ -11,74 +11,103 @@ # See the file "license.terms" for information on usage and redistribution of # this file, and for a DISCLAIMER OF ALL WARRANTIES. -::proc ::oo::Helpers::callback {method args} { - list [uplevel 1 {namespace which my}] $method {*}$args -} +::namespace eval ::oo::Helpers { + ::namespace path {} -::proc ::oo::Helpers::mymethod {method args} { - list [uplevel 1 {namespace which my}] $method {*}$args -} + proc callback {method args} { + list [uplevel 1 {::namespace which my}] $method {*}$args + } -::proc ::oo::Helpers::classvariable {name args} { - # Get a reference to the class's namespace - set ns [info object namespace [uplevel 1 {self class}]] - # Double up the list of variable names - foreach v [list $name {*}$args] { - if {[string match *(*) $v]} { - return -code error [string cat {bad variable name "} $v {": can't create a scalar variable that looks like an array element}] - } - if {[string match *::* $v]} { - return -code error [string cat {bad variable name "} $v {": can't create a local variable with a namespace separator in it}] - } - lappend vs $v $v + proc mymethod {method args} { + list [uplevel 1 {::namespace which my}] $method {*}$args } - # Lastly, link the caller's local variables to the class's variables - tailcall namespace upvar $ns {*}$vs -} -::proc ::oo::Helpers::link {args} { - set ns [uplevel 1 {namespace current}] - foreach link $args { - if {[llength $link] == 2} { - lassign $link src dst - } else { - lassign $link src - set dst $src - } - if {![string match ::* $src]} { - set src [string cat $ns :: $src] - } - interp alias {} $src {} ${ns}::my $dst - trace add command ${ns}::my delete [list ::oo::Helpers::Unlink $src] + proc classvariable {name args} { + # Get a reference to the class's namespace + set ns [info object namespace [uplevel 1 {self class}]] + # Double up the list of variable names + foreach v [list $name {*}$args] { + if {[string match *(*) $v]} { + variable + return -code error [format \ + {bad variable name "%s": can't create a scalar variable that looks like an array element} \ + $v] + } + if {[string match *::* $v]} { + return -code error [format \ + {bad variable name "%s": can't create a local variable with a namespace separator in it} \ + $v] + } + lappend vs $v $v + } + # Lastly, link the caller's local variables to the class's variables + tailcall namespace upvar $ns {*}$vs } - return -} -::proc ::oo::Helpers::Unlink {cmd args} { - if {[namespace which $cmd] ne {}} { - rename $cmd {} + + proc link {args} { + set ns [uplevel 1 {::namespace current}] + foreach link $args { + if {[llength $link] == 2} { + lassign $link src dst + } else { + lassign $link src + set dst $src + } + if {![string match ::* $src]} { + set src [string cat $ns :: $src] + } + interp alias {} $src {} ${ns}::my $dst + trace add command ${ns}::my delete [list \ + ::oo::UnlinkLinkedCommand $src] + } + return } } -::proc ::oo::DelegateName {class} { - string cat [info object namespace $class] {:: oo ::delegate} -} +::namespace eval ::oo { + proc UnlinkLinkedCommand {cmd args} { + if {[namespace which $cmd] ne {}} { + rename $cmd {} + } + } -proc ::oo::MixinClassDelegates {class} { - if {![info object isa class $class]} { - return + proc DelegateName {class} { + string cat [info object namespace $class] {:: oo ::delegate} } - set delegate [::oo::DelegateName $class] - if {![info object isa class $delegate]} { - return + + proc MixinClassDelegates {class} { + if {![info object isa class $class]} { + return + } + set delegate [DelegateName $class] + if {![info object isa class $delegate]} { + return + } + foreach c [info class superclass $class] { + set d [DelegateName $c] + if {![info object isa class $d]} { + continue + } + define $delegate superclass -append $d + } + objdefine $class mixin -append $delegate } - foreach c [info class superclass $class] { - set d [::oo::DelegateName $c] - if {![info object isa class $d]} { - continue - } - ::oo::define $delegate superclass -append $d + + proc UpdateClassDelegatesAfterClone {originObject targetObject} { + # Rebuild the class inheritance delegation class + set originDelegate [DelegateName $originObject] + set targetDelegate [DelegateName $targetObject] + if { + [info object isa class $originDelegate] + && ![info object isa class $targetDelegate] + } then { + copy $originDelegate $targetDelegate + objdefine $targetObject mixin -set \ + {*}[lmap c [info object mixin $targetObject] { + if {$c eq $originDelegate} {set targetDelegate} {set c} + }] + } } - ::oo::objdefine $class mixin -append $delegate } ::namespace eval ::oo::define { @@ -86,8 +115,9 @@ proc ::oo::MixinClassDelegates {class} { # Create the method on the class if the caller gave arguments and body ::set argc [::llength [::info level 0]] ::if {$argc == 3} { - ::return -code error [::string cat {wrong # args: should be "} \ - [::lindex [::info level 0] 0] { name ?args body?"}] + ::return -code error [::format \ + {wrong # args: should be "%s name ?args body?"} \ + [::lindex [::info level 0] 0]] } ::set cls [::uplevel 1 self] ::if {$argc == 4} { @@ -140,17 +170,43 @@ proc ::oo::MixinClassDelegates {class} { ::oo::objdefine ::oo::define::mixin forward --default-operation my -set ::oo::objdefine ::oo::objdefine::mixin forward --default-operation my -set +::oo::define ::oo::object method {originObject} { + # Copy over the procedures from the original namespace + foreach p [info procs [info object namespace $originObject]::*] { + set args [info args $p] + set idx -1 + foreach a $args { + if {[info default $p $a d]} { + lset args [incr idx] [list $a $d] + } else { + lset args [incr idx] [list $a] + } + } + set b [info body $p] + set p [namespace tail $p] + proc $p $args $b + } + # Copy over the variables from the original namespace + foreach v [info vars [info object namespace $originObject]::*] { + upvar 0 $v vOrigin + namespace upvar [namespace current] [namespace tail $v] vNew + if {[info exists vOrigin]} { + if {[array exists vOrigin]} { + array set vNew [array get vOrigin] + } else { + set vNew $vOrigin + } + } + } + # General commands, sub-namespaces and advancd variable config (traces, + # etc) are *not* copied over. Classes that want that should do it + # themselves. +} + ::oo::define ::oo::class method {originObject} { next $originObject # Rebuild the class inheritance delegation class - set originDelegate [::oo::DelegateName $originObject] - set targetDelegate [::oo::DelegateName [self]] - if {[info object isa class $originDelegate] && ![info object isa class $targetDelegate]} { - ::oo::copy $originDelegate $targetDelegate - ::oo::objdefine [self] mixin -set {*}[lmap c [info object mixin [self]] { - if {$c eq $originDelegate} {set targetDelegate} {set c} - }] - } + ::oo::UpdateClassDelegatesAfterClone $originObject [self] } ::oo::class create ::oo::singleton { diff --git a/tools/makeHeader.tcl b/tools/makeHeader.tcl index 8af35fc..5197da6 100644 --- a/tools/makeHeader.tcl +++ b/tools/makeHeader.tcl @@ -21,7 +21,7 @@ namespace eval makeHeader { # All Tcl metacharacters and key C backslash sequences set MAP { \" \\\\\" \\ \\\\\\\\ $ \\$ [ \\[ ] \\] ' \\\\' ? \\\\? - \a \\\\a \b \\\\b \f \\\\f \n \\\\n \r \\\\r \t \\\\t \v \\\\v + \a \\\\a \b \\\\b \f \\\\f \n \\\\n \r \\\\r \t { } \v \\\\v } set XFORM {[format \\\\\\\\u%04x {*}[scan & %c]]} -- cgit v0.12 From 8346cad0dd5a449892a1522020403d24f4186179 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 8 Aug 2018 06:45:29 +0000 Subject: Fix harmless gcc warning --- generic/tclDate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generic/tclDate.c b/generic/tclDate.c index e4dd000..717a1b3 100644 --- a/generic/tclDate.c +++ b/generic/tclDate.c @@ -1348,7 +1348,7 @@ yyparse (info) int yychar; /* The semantic value of the look-ahead symbol. */ -YYSTYPE yylval; +YYSTYPE yylval = {0}; /* Number of syntax errors so far. */ int yynerrs; -- cgit v0.12 From 6c78bf0adcb250437f1bb8dd19f13b7c2aa83848 Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 8 Aug 2018 20:48:06 +0000 Subject: Repair breakage in recent refactoring of env.test --- tests/env.test | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/env.test b/tests/env.test index 2c077b1..e6ce44d 100644 --- a/tests/env.test +++ b/tests/env.test @@ -53,7 +53,7 @@ proc envprep {} { foreach name [array names env] { # Keep some environment variables that support operation of the tcltest # package. - if {[string toupper $name] ni $keep} { + if {[string toupper $name] ni [string toupper $keep]} { unset env($name) } } @@ -98,11 +98,11 @@ proc cleanup1 {} { } variable keep { - TCL_LIBRARY PATH LD_LIBRARY_PATH LIBPATH DISPLAY SHLIB_PATH - SYSTEMDRIVE SYSTEMROOT DYLD_LIBRARY_PATH DYLD_FRAMEWORK_PATH + TCL_LIBRARY PATH LD_LIBRARY_PATH LIBPATH PURE_PROG_NAME DISPLAY + SHLIB_PATH SYSTEMDRIVE SYSTEMROOT DYLD_LIBRARY_PATH DYLD_FRAMEWORK_PATH DYLD_NEW_LOCAL_SHARED_REGIONS DYLD_NO_FIX_PREBINDING - SECURITYSESSIONID LANG WINDIR TERM - CONNOMPROGRAMFILES PROGRAMFILES COMMONPROGRAMW6432 PROGRAMW6432 + __CF_USER_TEXT_ENCODING SECURITYSESSIONID LANG WINDIR TERM + CommonProgramFiles ProgramFiles CommonProgramW6432 ProgramW6432 } variable printenvScript [makeFile [string map [list @keep@ [list $keep]] { -- cgit v0.12 From e53f3cf9c69144d698f8b7899817243cd4d8d7e5 Mon Sep 17 00:00:00 2001 From: pooryorick Date: Fri, 10 Aug 2018 15:03:14 +0000 Subject: Tighten up SaveResult.3, make installManPage more robust against newlines. --- doc/SaveResult.3 | 109 ++++++++++++++++++---------------------------------- unix/installManPage | 43 ++++++++++++++------- 2 files changed, 66 insertions(+), 86 deletions(-) diff --git a/doc/SaveResult.3 b/doc/SaveResult.3 index 6dd6cb6..1ddc1ad 100644 --- a/doc/SaveResult.3 +++ b/doc/SaveResult.3 @@ -1,6 +1,7 @@ '\" '\" Copyright (c) 1997 by Sun Microsystems, Inc. '\" Contributions from Don Porter, NIST, 2004. (not subject to US copyright) +'\" Copyright (c) 2018 Nathan Coulter. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. @@ -9,7 +10,9 @@ .so man.macros .BS .SH NAME -Tcl_SaveInterpState, Tcl_RestoreInterpState, Tcl_DiscardInterpState, Tcl_SaveResult, Tcl_RestoreResult, Tcl_DiscardResult \- save and restore an interpreter's state +Tcl_SaveInterpState, Tcl_RestoreInterpState, Tcl_DiscardInterpState, +Tcl_SaveResult, Tcl_RestoreResult, Tcl_DiscardResult \- Save and restore the +state of an an interpreter. .SH SYNOPSIS .nf \fB#include \fR @@ -30,91 +33,53 @@ int .SH ARGUMENTS .AS Tcl_InterpState savedPtr .AP Tcl_Interp *interp in -Interpreter for which state should be saved. +The current interpreter. .AP int status in -Return code value to save as part of interpreter state. +The return code for the state. .AP Tcl_InterpState state in -Saved state token to be restored or discarded. +A token for saved state. .AP Tcl_SavedResult *savedPtr in -Pointer to location where interpreter result should be saved or restored. +A pointer to storage for saved state. .BE .SH DESCRIPTION .PP -These routines allows a C procedure to take a snapshot of the current -state of an interpreter so that it can be restored after a call -to \fBTcl_Eval\fR or some other routine that modifies the interpreter -state. There are two triplets of routines meant to work together. +These routines save the state of an interpreter before a call to a routine such +as \fBTcl_Eval\fR, and restore the state afterwards. .PP -The first triplet stores the snapshot of interpreter state in -an opaque token returned by \fBTcl_SaveInterpState\fR. That token -value may then be passed back to one of \fBTcl_RestoreInterpState\fR -or \fBTcl_DiscardInterpState\fR, depending on whether the interp -state is to be restored. So long as one of the latter two routines -is called, Tcl will take care of memory management. +\fBTcl_SaveInterpState\fR saves the parts of \fIinterp\fR that comprise the +result of a script, including the resulting value, the return code passed as +\fIstatus\fR, and any options such as \fB\-errorinfo\fR and \fB\-errorcode\fR. +It returns a token for the saved state. The interpreter result is not reset +and no interpreter state is changed. .PP -The second triplet stores the snapshot of only the interpreter -result (not its complete state) in memory allocated by the caller. -These routines are passed a pointer to \fBTcl_SavedResult\fR -that is used to store enough information to restore the interpreter result. -\fBTcl_SavedResult\fR can be allocated on the stack of the calling -procedure. These routines do not save the state of any error -information in the interpreter (e.g. the \fB\-errorcode\fR or -\fB\-errorinfo\fR return options, when an error is in progress). +\fBTcl_RestoreInterpState\fR restores the state indicated by \fIstate\fR and +returns the \fIstatus\fR originally passed in the corresponding call to +\fBTcl_SaveInterpState\fR. .PP -Because the routines \fBTcl_SaveInterpState\fR, -\fBTcl_RestoreInterpState\fR, and \fBTcl_DiscardInterpState\fR perform -a superset of the functions provided by the other routines, -any new code should only make use of the more powerful routines. -The older, weaker routines \fBTcl_SaveResult\fR, \fBTcl_RestoreResult\fR, -and \fBTcl_DiscardResult\fR continue to exist only for the sake -of existing programs that may already be using them. +If a saved state is not restored, \fBTcl_DiscardInterpState\fR must be called +to release it. A token used to discard or restore state must not be used +again. .PP -\fBTcl_SaveInterpState\fR takes a snapshot of those portions of -interpreter state that make up the full result of script evaluation. -This include the interpreter result, the return code (passed in -as the \fIstatus\fR argument, and any return options, including -\fB\-errorinfo\fR and \fB\-errorcode\fR when an error is in progress. -This snapshot is returned as an opaque token of type \fBTcl_InterpState\fR. -The call to \fBTcl_SaveInterpState\fR does not itself change the -state of the interpreter. Unlike \fBTcl_SaveResult\fR, it does -not reset the interpreter. +\fBTcl_SaveResult\fR, \fBTcl_RestoreResult\fR, and \fBTcl_DiscardResult\fR are +deprecated. Instead use \fBTcl_SaveInterpState\fR, +\fBTcl_RestoreInterpState\fR, and \fBTcl_DiscardInterpState\fR, which are more +capable. .PP -\fBTcl_RestoreInterpState\fR accepts a \fBTcl_InterpState\fR token -previously returned by \fBTcl_SaveInterpState\fR and restores the -state of the interp to the state held in that snapshot. The return -value of \fBTcl_RestoreInterpState\fR is the status value originally -passed to \fBTcl_SaveInterpState\fR when the snapshot token was -created. +\fBTcl_SaveResult\fR moves the string result and structured result of +\fIinterp\fR to the location \fIstatePtr\fR points to and returns the +interpreter result to its initial state. It does not save options such as +\fB\-errorcode\fR or \fB\-errorinfo\fR. .PP -\fBTcl_DiscardInterpState\fR is called to release a \fBTcl_InterpState\fR -token previously returned by \fBTcl_SaveInterpState\fR when that -snapshot is not to be restored to an interp. +\fBTcl_RestoreResult\fR clears any existing result or error in \fIinterp\fR and +moves the string result and structured result from \fIstatePtr\fR back to +\fIinterp\fR. \fIstatePtr\fR is then in an undefined state and cannot be used +until passed again to \fBTcl_SaveResult\fR. .PP -The \fBTcl_InterpState\fR token returned by \fBTcl_SaveInterpState\fR -must eventually be passed to either \fBTcl_RestoreInterpState\fR -or \fBTcl_DiscardInterpState\fR to avoid a memory leak. Once -the \fBTcl_InterpState\fR token is passed to one of them, the -token is no longer valid and should not be used anymore. -.PP -\fBTcl_SaveResult\fR moves the string and value results -of \fIinterp\fR into the location specified by \fIstatePtr\fR. -\fBTcl_SaveResult\fR clears the result for \fIinterp\fR and -leaves the result in its normal empty initialized state. -.PP -\fBTcl_RestoreResult\fR moves the string and value results from -\fIstatePtr\fR back into \fIinterp\fR. Any result or error that was -already in the interpreter will be cleared. The \fIstatePtr\fR is left -in an uninitialized state and cannot be used until another call to -\fBTcl_SaveResult\fR. -.PP -\fBTcl_DiscardResult\fR releases the saved interpreter state -stored at \fBstatePtr\fR. The state structure is left in an -uninitialized state and cannot be used until another call to +\fBTcl_DiscardResult\fR releases the state stored at \fBstatePtr\fR, which is +then in an undefined state and cannot be used until passed again to \fBTcl_SaveResult\fR. .PP -Once \fBTcl_SaveResult\fR is called to save the interpreter -result, either \fBTcl_RestoreResult\fR or -\fBTcl_DiscardResult\fR must be called to properly clean up the -memory associated with the saved state. +If a saved result is not restored, \fBTcl_DiscardResult\fR must be called to +release it. .SH KEYWORDS result, state, interp diff --git a/unix/installManPage b/unix/installManPage index 1f1cbde..09a31dd 100755 --- a/unix/installManPage +++ b/unix/installManPage @@ -60,20 +60,35 @@ test -z "$SymOrLoc" && SymOrLoc="$Dir/" # Names=`sed -n ' # Look for a line that starts with .SH NAME - /^\.SH NAME/{ -# Read next line - n -# Remove all commas ... - s/,//g -# ... and backslash-escaped spaces. - s/\\\ //g -# Delete from \- to the end of line - s/ \\\-.*// -# Convert all non-space non-alphanum sequences -# to single underscores. - s/[^ A-Za-z0-9][^ A-Za-z0-9]*/_/g -# print the result and exit - p;q + /^\.SH NAME/,/^\./{ + + + /^\./!{ + + # Remove all commas... + s/,//g + + # ... and backslash-escaped spaces. + s/\\\ //g + + /\\\-.*/{ + # Delete from \- to the end of line + s/ \\\-.*// + h + s/.*/./ + x + } + + # Convert all non-space non-alphanum sequences + # to single underscores. + s/[^ A-Za-z0-9][^ A-Za-z0-9]*/_/g + p + g + /^\./{ + q + } + } + }' $ManPage` if test -z "$Names" ; then -- cgit v0.12 From 18c102aa7055571d742e867b44e765ac3ed0213c Mon Sep 17 00:00:00 2001 From: pooryorick Date: Fri, 10 Aug 2018 18:44:41 +0000 Subject: minor changes to documentation --- doc/SaveResult.3 | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/doc/SaveResult.3 b/doc/SaveResult.3 index 1ddc1ad..51ccb23 100644 --- a/doc/SaveResult.3 +++ b/doc/SaveResult.3 @@ -33,7 +33,7 @@ int .SH ARGUMENTS .AS Tcl_InterpState savedPtr .AP Tcl_Interp *interp in -The current interpreter. +The interpreter for the operation. .AP int status in The return code for the state. .AP Tcl_InterpState state in @@ -65,18 +65,18 @@ deprecated. Instead use \fBTcl_SaveInterpState\fR, \fBTcl_RestoreInterpState\fR, and \fBTcl_DiscardInterpState\fR, which are more capable. .PP -\fBTcl_SaveResult\fR moves the string result and structured result of -\fIinterp\fR to the location \fIstatePtr\fR points to and returns the -interpreter result to its initial state. It does not save options such as -\fB\-errorcode\fR or \fB\-errorinfo\fR. +\fBTcl_SaveResult\fR moves the result of \fIinterp\fR to the location +\fIstatePtr\fR points to and returns the interpreter result to its initial +state. It does not save options such as \fB\-errorcode\fR or +\fB\-errorinfo\fR. .PP \fBTcl_RestoreResult\fR clears any existing result or error in \fIinterp\fR and -moves the string result and structured result from \fIstatePtr\fR back to -\fIinterp\fR. \fIstatePtr\fR is then in an undefined state and cannot be used -until passed again to \fBTcl_SaveResult\fR. +moves the result from \fIstatePtr\fR back to \fIinterp\fR. \fIstatePtr\fR is +then in an undefined state and must not be used until passed again to +\fBTcl_SaveResult\fR. .PP \fBTcl_DiscardResult\fR releases the state stored at \fBstatePtr\fR, which is -then in an undefined state and cannot be used until passed again to +then in an undefined state and must not be used until passed again to \fBTcl_SaveResult\fR. .PP If a saved result is not restored, \fBTcl_DiscardResult\fR must be called to -- cgit v0.12 From 245151ad96d79fe7ec45da4d538d344edbfff4cb Mon Sep 17 00:00:00 2001 From: dkf Date: Sat, 11 Aug 2018 11:18:20 +0000 Subject: Improve script compilation. Prove that compilation works with safe interps. --- generic/tclOOScript.h | 416 +++++++++++++++++++++----------------------- generic/tclOOScript.tcl | 447 ++++++++++++++++++++++++++++++++++-------------- tests/ooUtil.test | 39 +++++ tools/makeHeader.tcl | 22 ++- 4 files changed, 572 insertions(+), 352 deletions(-) diff --git a/generic/tclOOScript.h b/generic/tclOOScript.h index d89e81a..741a5c4 100644 --- a/generic/tclOOScript.h +++ b/generic/tclOOScript.h @@ -22,225 +22,205 @@ static const char *tclOOSetupScript = /* !BEGIN!: Do not edit below this line. */ -"::namespace eval ::oo::Helpers {\n" -" ::namespace path {}\n" -"\n" -" proc callback {method args} {\n" -" list [uplevel 1 {::namespace which my}] $method {*}$args\n" -" }\n" -"\n" -" proc mymethod {method args} {\n" -" list [uplevel 1 {::namespace which my}] $method {*}$args\n" -" }\n" -"\n" -" proc classvariable {name args} {\n" -" # Get a reference to the class\'s namespace\n" -" set ns [info object namespace [uplevel 1 {self class}]]\n" -" # Double up the list of variable names\n" -" foreach v [list $name {*}$args] {\n" -" if {[string match *(*) $v]} {\n" -" variable \n" -" return -code error [format \\\n" -" {bad variable name \"%s\": can\'t create a scalar variable that looks like an array element} \\\n" -" $v]\n" -" }\n" -" if {[string match *::* $v]} {\n" -" return -code error [format \\\n" -" {bad variable name \"%s\": can\'t create a local variable with a namespace separator in it} \\\n" -" $v]\n" -" }\n" -" lappend vs $v $v\n" -" }\n" -" # Lastly, link the caller\'s local variables to the class\'s variables\n" -" tailcall namespace upvar $ns {*}$vs\n" -" }\n" -"\n" -" proc link {args} {\n" -" set ns [uplevel 1 {::namespace current}]\n" -" foreach link $args {\n" -" if {[llength $link] == 2} {\n" -" lassign $link src dst\n" -" } else {\n" -" lassign $link src\n" -" set dst $src\n" -" }\n" -" if {![string match ::* $src]} {\n" -" set src [string cat $ns :: $src]\n" -" }\n" -" interp alias {} $src {} ${ns}::my $dst\n" -" trace add command ${ns}::my delete [list \\\n" -" ::oo::UnlinkLinkedCommand $src]\n" -" }\n" -" return\n" -" }\n" -"}\n" -"\n" "::namespace eval ::oo {\n" -" proc UnlinkLinkedCommand {cmd args} {\n" -" if {[namespace which $cmd] ne {}} {\n" -" rename $cmd {}\n" -" }\n" -" }\n" -"\n" -" proc DelegateName {class} {\n" -" string cat [info object namespace $class] {:: oo ::delegate}\n" -" }\n" -"\n" -" proc MixinClassDelegates {class} {\n" -" if {![info object isa class $class]} {\n" -" return\n" -" }\n" -" set delegate [DelegateName $class]\n" -" if {![info object isa class $delegate]} {\n" -" return\n" -" }\n" -" foreach c [info class superclass $class] {\n" -" set d [DelegateName $c]\n" -" if {![info object isa class $d]} {\n" -" continue\n" -" }\n" -" define $delegate superclass -append $d\n" -" }\n" -" objdefine $class mixin -append $delegate\n" -" }\n" -"\n" -" proc UpdateClassDelegatesAfterClone {originObject targetObject} {\n" -" # Rebuild the class inheritance delegation class\n" -" set originDelegate [DelegateName $originObject]\n" -" set targetDelegate [DelegateName $targetObject]\n" -" if {\n" -" [info object isa class $originDelegate]\n" -" && ![info object isa class $targetDelegate]\n" -" } then {\n" -" copy $originDelegate $targetDelegate\n" -" objdefine $targetObject mixin -set \\\n" -" {*}[lmap c [info object mixin $targetObject] {\n" -" if {$c eq $originDelegate} {set targetDelegate} {set c}\n" -" }]\n" -" }\n" -" }\n" -"}\n" -"\n" -"::namespace eval ::oo::define {\n" -" ::proc classmethod {name {args {}} {body {}}} {\n" -" # Create the method on the class if the caller gave arguments and body\n" -" ::set argc [::llength [::info level 0]]\n" -" ::if {$argc == 3} {\n" -" ::return -code error [::format \\\n" -" {wrong # args: should be \"%s name \?args body\?\"} \\\n" -" [::lindex [::info level 0] 0]]\n" -" }\n" -" ::set cls [::uplevel 1 self]\n" -" ::if {$argc == 4} {\n" -" ::oo::define [::oo::DelegateName $cls] method $name $args $body\n" -" }\n" -" # Make the connection by forwarding\n" -" ::tailcall forward $name myclass $name\n" -" }\n" -"\n" -" ::proc initialise {body} {\n" -" ::set clsns [::info object namespace [::uplevel 1 self]]\n" -" ::tailcall apply [::list {} $body $clsns]\n" -" }\n" -"\n" -" # Make the initialise command appear with US spelling too\n" -" ::namespace export initialise\n" -" ::namespace eval tmp {::namespace import ::oo::define::initialise}\n" -" ::rename ::oo::define::tmp::initialise initialize\n" -" ::namespace delete tmp\n" -" ::namespace export -clear\n" -"}\n" -"\n" -"::oo::define ::oo::Slot {\n" -" method Get {} {return -code error unimplemented}\n" -" method Set list {return -code error unimplemented}\n" -"\n" -" method -set args {tailcall my Set $args}\n" -" method -append args {\n" -" set current [uplevel 1 [list [namespace which my] Get]]\n" -" tailcall my Set [list {*}$current {*}$args]\n" -" }\n" -" method -clear {} {tailcall my Set {}}\n" -" forward --default-operation my -append\n" -"\n" -" method unknown {args} {\n" -" set def --default-operation\n" -" if {[llength $args] == 0} {\n" -" tailcall my $def\n" -" } elseif {![string match -* [lindex $args 0]]} {\n" -" tailcall my $def {*}$args\n" -" }\n" -" next {*}$args\n" -" }\n" -"\n" -" export -set -append -clear\n" -" unexport unknown destroy\n" -"}\n" -"\n" -"::oo::objdefine ::oo::define::superclass forward --default-operation my -set\n" -"::oo::objdefine ::oo::define::mixin forward --default-operation my -set\n" -"::oo::objdefine ::oo::objdefine::mixin forward --default-operation my -set\n" -"\n" -"::oo::define ::oo::object method {originObject} {\n" -" # Copy over the procedures from the original namespace\n" -" foreach p [info procs [info object namespace $originObject]::*] {\n" -" set args [info args $p]\n" -" set idx -1\n" -" foreach a $args {\n" -" if {[info default $p $a d]} {\n" -" lset args [incr idx] [list $a $d]\n" -" } else {\n" -" lset args [incr idx] [list $a]\n" -" }\n" -" }\n" -" set b [info body $p]\n" -" set p [namespace tail $p]\n" -" proc $p $args $b\n" -" }\n" -" # Copy over the variables from the original namespace\n" -" foreach v [info vars [info object namespace $originObject]::*] {\n" -" upvar 0 $v vOrigin\n" -" namespace upvar [namespace current] [namespace tail $v] vNew\n" -" if {[info exists vOrigin]} {\n" -" if {[array exists vOrigin]} {\n" -" array set vNew [array get vOrigin]\n" -" } else {\n" -" set vNew $vOrigin\n" -" }\n" -" }\n" -" }\n" -" # General commands, sub-namespaces and advancd variable config (traces,\n" -" # etc) are *not* copied over. Classes that want that should do it\n" -" # themselves.\n" -"}\n" -"\n" -"::oo::define ::oo::class method {originObject} {\n" -" next $originObject\n" -" # Rebuild the class inheritance delegation class\n" -" ::oo::UpdateClassDelegatesAfterClone $originObject [self]\n" -"}\n" -"\n" -"::oo::class create ::oo::singleton {\n" -" superclass ::oo::class\n" -" variable object\n" -" unexport create createWithNamespace\n" -" method new args {\n" -" if {![info exists object] || ![info object isa object $object]} {\n" -" set object [next {*}$args]\n" -" ::oo::objdefine $object method destroy {} {\n" -" return -code error {may not destroy a singleton object}\n" -" }\n" -" ::oo::objdefine $object method {originObject} {\n" -" return -code error {may not clone a singleton object}\n" -" }\n" -" }\n" -" return $object\n" -" }\n" -"}\n" -"\n" -"::oo::class create ::oo::abstract {\n" -" superclass ::oo::class\n" -" unexport create createWithNamespace new\n" +"\t::namespace path {}\n" +"\tnamespace eval Helpers {\n" +"\t\t::namespace path {}\n" +"\t\tproc callback {method args} {\n" +"\t\t\tlist [uplevel 1 {::namespace which my}] $method {*}$args\n" +"\t\t}\n" +"\t\tnamespace export callback\n" +"\t\tnamespace eval tmp {namespace import ::oo::Helpers::callback}\n" +"\t\tnamespace export -clear\n" +"\t\trename tmp::callback mymethod\n" +"\t\tnamespace delete tmp\n" +"\t\tproc classvariable {name args} {\n" +"\t\t\tset ns [info object namespace [uplevel 1 {self class}]]\n" +"\t\t\tforeach v [list $name {*}$args] {\n" +"\t\t\t\tif {[string match *(*) $v]} {\n" +"\t\t\t\t\tset reason \"can\'t create a scalar variable that looks like an array element\"\n" +"\t\t\t\t\treturn -code error -errorcode {TCL UPVAR LOCAL_ELEMENT} \\\n" +"\t\t\t\t\t\t[format {bad variable name \"%s\": %s} $v $reason]\n" +"\t\t\t\t}\n" +"\t\t\t\tif {[string match *::* $v]} {\n" +"\t\t\t\t\tset reason \"can\'t create a local variable with a namespace separator in it\"\n" +"\t\t\t\t\treturn -code error -errorcode {TCL UPVAR INVERTED} \\\n" +"\t\t\t\t\t\t[format {bad variable name \"%s\": %s} $v $reason]\n" +"\t\t\t\t}\n" +"\t\t\t\tlappend vs $v $v\n" +"\t\t\t}\n" +"\t\t\ttailcall namespace upvar $ns {*}$vs\n" +"\t\t}\n" +"\t\tproc link {args} {\n" +"\t\t\tset ns [uplevel 1 {::namespace current}]\n" +"\t\t\tforeach link $args {\n" +"\t\t\t\tif {[llength $link] == 2} {\n" +"\t\t\t\t\tlassign $link src dst\n" +"\t\t\t\t} elseif {[llength $link] == 1} {\n" +"\t\t\t\t\tlassign $link src\n" +"\t\t\t\t\tset dst $src\n" +"\t\t\t\t} else {\n" +"\t\t\t\t\treturn -code error -errorcode {TCLOO CMDLINK FORMAT} \\\n" +"\t\t\t\t\t\t\"bad link description; must only have one or two elements\"\n" +"\t\t\t\t}\n" +"\t\t\t\tif {![string match ::* $src]} {\n" +"\t\t\t\t\tset src [string cat $ns :: $src]\n" +"\t\t\t\t}\n" +"\t\t\t\tinterp alias {} $src {} ${ns}::my $dst\n" +"\t\t\t\ttrace add command ${ns}::my delete [list \\\n" +"\t\t\t\t\t::oo::UnlinkLinkedCommand $src]\n" +"\t\t\t}\n" +"\t\t\treturn\n" +"\t\t}\n" +"\t}\n" +"\tproc UnlinkLinkedCommand {cmd args} {\n" +"\t\tif {[namespace which $cmd] ne {}} {\n" +"\t\t\trename $cmd {}\n" +"\t\t}\n" +"\t}\n" +"\tproc DelegateName {class} {\n" +"\t\tstring cat [info object namespace $class] {:: oo ::delegate}\n" +"\t}\n" +"\tproc MixinClassDelegates {class} {\n" +"\t\tif {![info object isa class $class]} {\n" +"\t\t\treturn\n" +"\t\t}\n" +"\t\tset delegate [DelegateName $class]\n" +"\t\tif {![info object isa class $delegate]} {\n" +"\t\t\treturn\n" +"\t\t}\n" +"\t\tforeach c [info class superclass $class] {\n" +"\t\t\tset d [DelegateName $c]\n" +"\t\t\tif {![info object isa class $d]} {\n" +"\t\t\t\tcontinue\n" +"\t\t\t}\n" +"\t\t\tdefine $delegate superclass -append $d\n" +"\t\t}\n" +"\t\tobjdefine $class mixin -append $delegate\n" +"\t}\n" +"\tproc UpdateClassDelegatesAfterClone {originObject targetObject} {\n" +"\t\tset originDelegate [DelegateName $originObject]\n" +"\t\tset targetDelegate [DelegateName $targetObject]\n" +"\t\tif {\n" +"\t\t\t[info object isa class $originDelegate]\n" +"\t\t\t&& ![info object isa class $targetDelegate]\n" +"\t\t} then {\n" +"\t\t\tcopy $originDelegate $targetDelegate\n" +"\t\t\tobjdefine $targetObject mixin -set \\\n" +"\t\t\t\t{*}[lmap c [info object mixin $targetObject] {\n" +"\t\t\t\t\tif {$c eq $originDelegate} {set targetDelegate} {set c}\n" +"\t\t\t\t}]\n" +"\t\t}\n" +"\t}\n" +"\tproc define::classmethod {name {args {}} {body {}}} {\n" +"\t\t::set argc [::llength [::info level 0]]\n" +"\t\t::if {$argc == 3} {\n" +"\t\t\t::return -code error -errorcode {TCL WRONGARGS} [::format \\\n" +"\t\t\t\t{wrong # args: should be \"%s name \?args body\?\"} \\\n" +"\t\t\t\t[::lindex [::info level 0] 0]]\n" +"\t\t}\n" +"\t\t::set cls [::uplevel 1 self]\n" +"\t\t::if {$argc == 4} {\n" +"\t\t\t::oo::define [::oo::DelegateName $cls] method $name $args $body\n" +"\t\t}\n" +"\t\t::tailcall forward $name myclass $name\n" +"\t}\n" +"\tproc define::initialise {body} {\n" +"\t\t::set clsns [::info object namespace [::uplevel 1 self]]\n" +"\t\t::tailcall apply [::list {} $body $clsns]\n" +"\t}\n" +"\tnamespace eval define {\n" +"\t\t::namespace export initialise\n" +"\t\t::namespace eval tmp {::namespace import ::oo::define::initialise}\n" +"\t\t::namespace export -clear\n" +"\t\t::rename tmp::initialise initialize\n" +"\t\t::namespace delete tmp\n" +"\t}\n" +"\tdefine Slot {\n" +"\t\tmethod Get {} {\n" +"\t\t\treturn -code error -errorcode {TCLOO ABSTRACT_SLOT} \"unimplemented\"\n" +"\t\t}\n" +"\t\tmethod Set list {\n" +"\t\t\treturn -code error -errorcode {TCLOO ABSTRACT_SLOT} \"unimplemented\"\n" +"\t\t}\n" +"\t\tmethod -set args {tailcall my Set $args}\n" +"\t\tmethod -append args {\n" +"\t\t\tset current [uplevel 1 [list [namespace which my] Get]]\n" +"\t\t\ttailcall my Set [list {*}$current {*}$args]\n" +"\t\t}\n" +"\t\tmethod -clear {} {tailcall my Set {}}\n" +"\t\tforward --default-operation my -append\n" +"\t\tmethod unknown {args} {\n" +"\t\t\tset def --default-operation\n" +"\t\t\tif {[llength $args] == 0} {\n" +"\t\t\t\ttailcall my $def\n" +"\t\t\t} elseif {![string match -* [lindex $args 0]]} {\n" +"\t\t\t\ttailcall my $def {*}$args\n" +"\t\t\t}\n" +"\t\t\tnext {*}$args\n" +"\t\t}\n" +"\t\texport -set -append -clear\n" +"\t\tunexport unknown destroy\n" +"\t}\n" +"\tobjdefine define::superclass forward --default-operation my -set\n" +"\tobjdefine define::mixin forward --default-operation my -set\n" +"\tobjdefine objdefine::mixin forward --default-operation my -set\n" +"\tdefine object method {originObject} {\n" +"\t\tforeach p [info procs [info object namespace $originObject]::*] {\n" +"\t\t\tset args [info args $p]\n" +"\t\t\tset idx -1\n" +"\t\t\tforeach a $args {\n" +"\t\t\t\tif {[info default $p $a d]} {\n" +"\t\t\t\t\tlset args [incr idx] [list $a $d]\n" +"\t\t\t\t} else {\n" +"\t\t\t\t\tlset args [incr idx] [list $a]\n" +"\t\t\t\t}\n" +"\t\t\t}\n" +"\t\t\tset b [info body $p]\n" +"\t\t\tset p [namespace tail $p]\n" +"\t\t\tproc $p $args $b\n" +"\t\t}\n" +"\t\tforeach v [info vars [info object namespace $originObject]::*] {\n" +"\t\t\tupvar 0 $v vOrigin\n" +"\t\t\tnamespace upvar [namespace current] [namespace tail $v] vNew\n" +"\t\t\tif {[info exists vOrigin]} {\n" +"\t\t\t\tif {[array exists vOrigin]} {\n" +"\t\t\t\t\tarray set vNew [array get vOrigin]\n" +"\t\t\t\t} else {\n" +"\t\t\t\t\tset vNew $vOrigin\n" +"\t\t\t\t}\n" +"\t\t\t}\n" +"\t\t}\n" +"\t}\n" +"\tdefine class method {originObject} {\n" +"\t\tnext $originObject\n" +"\t\t::oo::UpdateClassDelegatesAfterClone $originObject [self]\n" +"\t}\n" +"\tclass create singleton {\n" +"\t\tsuperclass class\n" +"\t\tvariable object\n" +"\t\tunexport create createWithNamespace\n" +"\t\tmethod new args {\n" +"\t\t\tif {![info exists object] || ![info object isa object $object]} {\n" +"\t\t\t\tset object [next {*}$args]\n" +"\t\t\t\t::oo::objdefine $object {\n" +"\t\t\t\t\tmethod destroy {} {\n" +"\t\t\t\t\t\t::return -code error -errorcode {TCLOO SINGLETON} \\\n" +"\t\t\t\t\t\t\t\"may not destroy a singleton object\"\n" +"\t\t\t\t\t}\n" +"\t\t\t\t\tmethod {originObject} {\n" +"\t\t\t\t\t\t::return -code error -errorcode {TCLOO SINGLETON} \\\n" +"\t\t\t\t\t\t\t\"may not clone a singleton object\"\n" +"\t\t\t\t\t}\n" +"\t\t\t\t}\n" +"\t\t\t}\n" +"\t\t\treturn $object\n" +"\t\t}\n" +"\t}\n" +"\tclass create abstract {\n" +"\t\tsuperclass class\n" +"\t\tunexport create createWithNamespace new\n" +"\t}\n" "}\n" /* !END!: Do not edit above this line. */ ; diff --git a/generic/tclOOScript.tcl b/generic/tclOOScript.tcl index c0b4d1f..d3706ce 100644 --- a/generic/tclOOScript.tcl +++ b/generic/tclOOScript.tcl @@ -11,70 +11,135 @@ # See the file "license.terms" for information on usage and redistribution of # this file, and for a DISCLAIMER OF ALL WARRANTIES. -::namespace eval ::oo::Helpers { +::namespace eval ::oo { ::namespace path {} - proc callback {method args} { - list [uplevel 1 {::namespace which my}] $method {*}$args - } + # + # Commands that are made available to objects by default. + # + namespace eval Helpers { + ::namespace path {} - proc mymethod {method args} { - list [uplevel 1 {::namespace which my}] $method {*}$args - } + # ------------------------------------------------------------------ + # + # callback, mymethod -- + # + # Create a script prefix that calls a method on the current + # object. Same operation, two names. + # + # ------------------------------------------------------------------ - proc classvariable {name args} { - # Get a reference to the class's namespace - set ns [info object namespace [uplevel 1 {self class}]] - # Double up the list of variable names - foreach v [list $name {*}$args] { - if {[string match *(*) $v]} { - variable - return -code error [format \ - {bad variable name "%s": can't create a scalar variable that looks like an array element} \ - $v] - } - if {[string match *::* $v]} { - return -code error [format \ - {bad variable name "%s": can't create a local variable with a namespace separator in it} \ - $v] - } - lappend vs $v $v + proc callback {method args} { + list [uplevel 1 {::namespace which my}] $method {*}$args } - # Lastly, link the caller's local variables to the class's variables - tailcall namespace upvar $ns {*}$vs - } - proc link {args} { - set ns [uplevel 1 {::namespace current}] - foreach link $args { - if {[llength $link] == 2} { - lassign $link src dst - } else { - lassign $link src - set dst $src + # Make the [callback] command appear as [mymethod] too. + namespace export callback + namespace eval tmp {namespace import ::oo::Helpers::callback} + namespace export -clear + rename tmp::callback mymethod + namespace delete tmp + + # ------------------------------------------------------------------ + # + # classvariable -- + # + # Link to a variable in the class of the current object. + # + # ------------------------------------------------------------------ + + proc classvariable {name args} { + # Get a reference to the class's namespace + set ns [info object namespace [uplevel 1 {self class}]] + # Double up the list of variable names + foreach v [list $name {*}$args] { + if {[string match *(*) $v]} { + set reason "can't create a scalar variable that looks like an array element" + return -code error -errorcode {TCL UPVAR LOCAL_ELEMENT} \ + [format {bad variable name "%s": %s} $v $reason] + } + if {[string match *::* $v]} { + set reason "can't create a local variable with a namespace separator in it" + return -code error -errorcode {TCL UPVAR INVERTED} \ + [format {bad variable name "%s": %s} $v $reason] + } + lappend vs $v $v } - if {![string match ::* $src]} { - set src [string cat $ns :: $src] + # Lastly, link the caller's local variables to the class's variables + tailcall namespace upvar $ns {*}$vs + } + + # ------------------------------------------------------------------ + # + # link -- + # + # Make a command that invokes a method on the current object. + # The name of the command and the name of the method match by + # default. + # + # ------------------------------------------------------------------ + + proc link {args} { + set ns [uplevel 1 {::namespace current}] + foreach link $args { + if {[llength $link] == 2} { + lassign $link src dst + } elseif {[llength $link] == 1} { + lassign $link src + set dst $src + } else { + return -code error -errorcode {TCLOO CMDLINK FORMAT} \ + "bad link description; must only have one or two elements" + } + if {![string match ::* $src]} { + set src [string cat $ns :: $src] + } + interp alias {} $src {} ${ns}::my $dst + trace add command ${ns}::my delete [list \ + ::oo::UnlinkLinkedCommand $src] } - interp alias {} $src {} ${ns}::my $dst - trace add command ${ns}::my delete [list \ - ::oo::UnlinkLinkedCommand $src] + return } - return } -} -::namespace eval ::oo { + # ---------------------------------------------------------------------- + # + # UnlinkLinkedCommand -- + # + # Callback used to remove linked command when the underlying mechanism + # that supports it is deleted. + # + # ---------------------------------------------------------------------- + proc UnlinkLinkedCommand {cmd args} { if {[namespace which $cmd] ne {}} { rename $cmd {} } } + # ---------------------------------------------------------------------- + # + # DelegateName -- + # + # Utility that gets the name of the class delegate for a class. It's + # trivial, but makes working with them much easier as delegate names are + # intentionally hard to create by accident. + # + # ---------------------------------------------------------------------- + proc DelegateName {class} { string cat [info object namespace $class] {:: oo ::delegate} } + # ---------------------------------------------------------------------- + # + # MixinClassDelegates -- + # + # Support code called *after* [oo::define] inside the constructor of a + # class that patches in the appropriate class delegates. + # + # ---------------------------------------------------------------------- + proc MixinClassDelegates {class} { if {![info object isa class $class]} { return @@ -93,6 +158,15 @@ objdefine $class mixin -append $delegate } + # ---------------------------------------------------------------------- + # + # UpdateClassDelegatesAfterClone -- + # + # Support code that is like [MixinClassDelegates] except for when a + # class is cloned. + # + # ---------------------------------------------------------------------- + proc UpdateClassDelegatesAfterClone {originObject targetObject} { # Rebuild the class inheritance delegation class set originDelegate [DelegateName $originObject] @@ -108,14 +182,24 @@ }] } } -} -::namespace eval ::oo::define { - ::proc classmethod {name {args {}} {body {}}} { + # ---------------------------------------------------------------------- + # + # oo::define::classmethod -- + # + # Defines a class method. See define(n) for details. + # + # Note that the ::oo::define namespace is semi-public and a bit weird + # anyway, so we don't regard the namespace path as being under control: + # fully qualified names are used for everything. + # + # ---------------------------------------------------------------------- + + proc define::classmethod {name {args {}} {body {}}} { # Create the method on the class if the caller gave arguments and body ::set argc [::llength [::info level 0]] ::if {$argc == 3} { - ::return -code error [::format \ + ::return -code error -errorcode {TCL WRONGARGS} [::format \ {wrong # args: should be "%s name ?args body?"} \ [::lindex [::info level 0] 0]] } @@ -127,109 +211,208 @@ ::tailcall forward $name myclass $name } - ::proc initialise {body} { + # ---------------------------------------------------------------------- + # + # oo::define::initialise, oo::define::initialize -- + # + # Do specific initialisation for a class. See define(n) for details. + # + # Note that the ::oo::define namespace is semi-public and a bit weird + # anyway, so we don't regard the namespace path as being under control: + # fully qualified names are used for everything. + # + # ---------------------------------------------------------------------- + + proc define::initialise {body} { ::set clsns [::info object namespace [::uplevel 1 self]] ::tailcall apply [::list {} $body $clsns] } - # Make the initialise command appear with US spelling too - ::namespace export initialise - ::namespace eval tmp {::namespace import ::oo::define::initialise} - ::rename ::oo::define::tmp::initialise initialize - ::namespace delete tmp - ::namespace export -clear -} + # Make the [initialise] definition appear as [initialize] too + namespace eval define { + ::namespace export initialise + ::namespace eval tmp {::namespace import ::oo::define::initialise} + ::namespace export -clear + ::rename tmp::initialise initialize + ::namespace delete tmp + } -::oo::define ::oo::Slot { - method Get {} {return -code error unimplemented} - method Set list {return -code error unimplemented} + # ---------------------------------------------------------------------- + # + # Slot -- + # + # The class of slot operations, which are basically lists at the low + # level of TclOO; this provides a more consistent interface to them. + # + # ---------------------------------------------------------------------- - method -set args {tailcall my Set $args} - method -append args { - set current [uplevel 1 [list [namespace which my] Get]] - tailcall my Set [list {*}$current {*}$args] - } - method -clear {} {tailcall my Set {}} - forward --default-operation my -append - - method unknown {args} { - set def --default-operation - if {[llength $args] == 0} { - tailcall my $def - } elseif {![string match -* [lindex $args 0]]} { - tailcall my $def {*}$args - } - next {*}$args - } + define Slot { + # ------------------------------------------------------------------ + # + # Slot Get -- + # + # Basic slot getter. Retrieves the contents of the slot. + # Particular slots must provide concrete non-erroring + # implementation. + # + # ------------------------------------------------------------------ - export -set -append -clear - unexport unknown destroy -} + method Get {} { + return -code error -errorcode {TCLOO ABSTRACT_SLOT} "unimplemented" + } -::oo::objdefine ::oo::define::superclass forward --default-operation my -set -::oo::objdefine ::oo::define::mixin forward --default-operation my -set -::oo::objdefine ::oo::objdefine::mixin forward --default-operation my -set - -::oo::define ::oo::object method {originObject} { - # Copy over the procedures from the original namespace - foreach p [info procs [info object namespace $originObject]::*] { - set args [info args $p] - set idx -1 - foreach a $args { - if {[info default $p $a d]} { - lset args [incr idx] [list $a $d] - } else { - lset args [incr idx] [list $a] + # ------------------------------------------------------------------ + # + # Slot Set -- + # + # Basic slot setter. Sets the contents of the slot. Particular + # slots must provide concrete non-erroring implementation. + # + # ------------------------------------------------------------------ + + method Set list { + return -code error -errorcode {TCLOO ABSTRACT_SLOT} "unimplemented" + } + + # ------------------------------------------------------------------ + # + # Slot -set, -append, -clear, --default-operation -- + # + # Standard public slot operations. If a slot can't figure out + # what method to call directly, it uses --default-operation. + # + # ------------------------------------------------------------------ + + method -set args {tailcall my Set $args} + method -append args { + set current [uplevel 1 [list [namespace which my] Get]] + tailcall my Set [list {*}$current {*}$args] + } + method -clear {} {tailcall my Set {}} + + # Default handling + forward --default-operation my -append + method unknown {args} { + set def --default-operation + if {[llength $args] == 0} { + tailcall my $def + } elseif {![string match -* [lindex $args 0]]} { + tailcall my $def {*}$args } + next {*}$args } - set b [info body $p] - set p [namespace tail $p] - proc $p $args $b + + # Set up what is exported and what isn't + export -set -append -clear + unexport unknown destroy } - # Copy over the variables from the original namespace - foreach v [info vars [info object namespace $originObject]::*] { - upvar 0 $v vOrigin - namespace upvar [namespace current] [namespace tail $v] vNew - if {[info exists vOrigin]} { - if {[array exists vOrigin]} { - array set vNew [array get vOrigin] - } else { - set vNew $vOrigin + + # Set the default operation differently for these slots + objdefine define::superclass forward --default-operation my -set + objdefine define::mixin forward --default-operation my -set + objdefine objdefine::mixin forward --default-operation my -set + + # ---------------------------------------------------------------------- + # + # oo::object -- + # + # Handler for cloning objects that clones basic bits (only!) of the + # object's namespace. Non-procedures, traces, sub-namespaces, etc. need + # more complex (and class-specific) handling. + # + # ---------------------------------------------------------------------- + + define object method {originObject} { + # Copy over the procedures from the original namespace + foreach p [info procs [info object namespace $originObject]::*] { + set args [info args $p] + set idx -1 + foreach a $args { + if {[info default $p $a d]} { + lset args [incr idx] [list $a $d] + } else { + lset args [incr idx] [list $a] + } + } + set b [info body $p] + set p [namespace tail $p] + proc $p $args $b + } + # Copy over the variables from the original namespace + foreach v [info vars [info object namespace $originObject]::*] { + upvar 0 $v vOrigin + namespace upvar [namespace current] [namespace tail $v] vNew + if {[info exists vOrigin]} { + if {[array exists vOrigin]} { + array set vNew [array get vOrigin] + } else { + set vNew $vOrigin + } } } + # General commands, sub-namespaces and advancd variable config (traces, + # etc) are *not* copied over. Classes that want that should do it + # themselves. } - # General commands, sub-namespaces and advancd variable config (traces, - # etc) are *not* copied over. Classes that want that should do it - # themselves. -} -::oo::define ::oo::class method {originObject} { - next $originObject - # Rebuild the class inheritance delegation class - ::oo::UpdateClassDelegatesAfterClone $originObject [self] -} + # ---------------------------------------------------------------------- + # + # oo::class -- + # + # Handler for cloning classes, which fixes up the delegates. + # + # ---------------------------------------------------------------------- -::oo::class create ::oo::singleton { - superclass ::oo::class - variable object - unexport create createWithNamespace - method new args { - if {![info exists object] || ![info object isa object $object]} { - set object [next {*}$args] - ::oo::objdefine $object method destroy {} { - return -code error {may not destroy a singleton object} - } - ::oo::objdefine $object method {originObject} { - return -code error {may not clone a singleton object} - } - } - return $object + define class method {originObject} { + next $originObject + # Rebuild the class inheritance delegation class + ::oo::UpdateClassDelegatesAfterClone $originObject [self] } -} -::oo::class create ::oo::abstract { - superclass ::oo::class - unexport create createWithNamespace new + # ---------------------------------------------------------------------- + # + # oo::singleton -- + # + # A metaclass that is used to make classes that only permit one instance + # of them to exist. See singleton(n). + # + # ---------------------------------------------------------------------- + + class create singleton { + superclass class + variable object + unexport create createWithNamespace + method new args { + if {![info exists object] || ![info object isa object $object]} { + set object [next {*}$args] + ::oo::objdefine $object { + method destroy {} { + ::return -code error -errorcode {TCLOO SINGLETON} \ + "may not destroy a singleton object" + } + method {originObject} { + ::return -code error -errorcode {TCLOO SINGLETON} \ + "may not clone a singleton object" + } + } + } + return $object + } + } + + # ---------------------------------------------------------------------- + # + # oo::abstract -- + # + # A metaclass that is used to make classes that can't be directly + # instantiated. See abstract(n). + # + # ---------------------------------------------------------------------- + + class create abstract { + superclass class + unexport create createWithNamespace new + } } # Local Variables: diff --git a/tests/ooUtil.test b/tests/ooUtil.test index e796637..ff7093f 100644 --- a/tests/ooUtil.test +++ b/tests/ooUtil.test @@ -138,6 +138,45 @@ test ooUtil-1.7 {} -setup { } -cleanup { parent destroy } -result {{} {} {} {}} -output "This is in the class; self is ::Foo\nThis is meee\nThis is in the class; self is ::Grill\nThis is meee 2\nThis is in the class; self is ::Foo\nThis is meee\nThis is in the class; self is ::Grill\nThis is meee 2\n" +# Two tests to confirm that we correctly initialise the scripted part of TclOO +# in child interpreters. This is slightly tricky at the implementation level +# because we cannot count on either [source] or [open] being available. +test ooUtil-1.8 {TIP 478: classmethod in child interp} -setup { + set childinterp [interp create] +} -body { + $childinterp eval { + oo::class create ActiveRecord { + classmethod find args { + return "[self] called with arguments: $args" + } + } + oo::class create Table { + superclass ActiveRecord + } + # This is confirming that this is not the master interpreter + list [Table find foo bar] [info globals childinterp] + } +} -cleanup { + interp delete $childinterp +} -result {{::Table called with arguments: foo bar} {}} +test ooUtil-1.9 {TIP 478: classmethod in safe child interp} -setup { + set safeinterp [interp create -safe] +} -body { + $safeinterp eval { + oo::class create ActiveRecord { + classmethod find args { + return "[self] called with arguments: $args" + } + } + oo::class create Table { + superclass ActiveRecord + } + # This is confirming that this is a (basic) safe interpreter + list [Table find foo bar] [info commands source] + } +} -cleanup { + interp delete $safeinterp +} -result {{::Table called with arguments: foo bar} {}} test ooUtil-2.1 {TIP 478: callback generation} -setup { oo::class create parent diff --git a/tools/makeHeader.tcl b/tools/makeHeader.tcl index 5197da6..e9b7ed1 100644 --- a/tools/makeHeader.tcl +++ b/tools/makeHeader.tcl @@ -21,7 +21,7 @@ namespace eval makeHeader { # All Tcl metacharacters and key C backslash sequences set MAP { \" \\\\\" \\ \\\\\\\\ $ \\$ [ \\[ ] \\] ' \\\\' ? \\\\? - \a \\\\a \b \\\\b \f \\\\f \n \\\\n \r \\\\r \t { } \v \\\\v + \a \\\\a \b \\\\b \f \\\\f \n \\\\n \r \\\\r \t \\\\t \v \\\\v } set XFORM {[format \\\\\\\\u%04x {*}[scan & %c]]} @@ -30,12 +30,30 @@ namespace eval makeHeader { #################################################################### # + # compactLeadingSpaces -- + # Converts the leading whitespace on a line into a more compact form. + # + proc compactLeadingSpaces {line} { + set line [string map {\t { }} [string trimright $line]] + if {[regexp {^[ ]+} $line spaces]} { + regsub -all {[ ]{4}} $spaces \t replace + set len [expr {[string length $spaces] - 1}] + set line [string replace $line 0 $len $replace] + } + return $line + } + + #################################################################### + # # processScript -- # Transform a whole sequence of lines with [mapSpecial]. # proc processScript {scriptLines} { lmap line $scriptLines { - format {"%s"} [mapSpecial $line\n] + # Skip blank and comment lines; they're there in the original + # sources so we don't need to copy them over. + if {[regexp {^\s*(?:#|$)} $line]} continue + format {"%s"} [mapSpecial [compactLeadingSpaces $line]\n] } } -- cgit v0.12 From f5efc84600e3a88460bdeb094d1cfa58ad5b3022 Mon Sep 17 00:00:00 2001 From: dkf Date: Sat, 11 Aug 2018 12:01:06 +0000 Subject: Added a note about the genesis of the compiled header. --- generic/tclOOScript.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/generic/tclOOScript.h b/generic/tclOOScript.h index 741a5c4..e63bd86 100644 --- a/generic/tclOOScript.h +++ b/generic/tclOOScript.h @@ -18,6 +18,10 @@ /* * The scripted part of the definitions of TclOO. + * + * Compiled from generic/tclOOScript.tcl by tools/makeHeader.tcl, which + * contains the commented version of everything; *this* file is automatically + * generated. */ static const char *tclOOSetupScript = -- cgit v0.12 From e5270637c01b6fbb0f016048fc9d9735f980421a Mon Sep 17 00:00:00 2001 From: pooryorick Date: Tue, 14 Aug 2018 05:43:17 +0000 Subject: Reposition the MODULE_SCOPE definition so that packages like tbcload don't get an error when they include tclPort.h. --- generic/tclInt.h | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/generic/tclInt.h b/generic/tclInt.h index 64e7c67..5379396 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -38,6 +38,23 @@ #define AVOID_HACKS_FOR_ITCL 1 + +/* + * Used to tag functions that are only to be visible within the module being + * built and not outside it (where this is supported by the linker). + * Also used in the platform-specific *Port.h files. + */ + +#ifndef MODULE_SCOPE +# ifdef __cplusplus +# define MODULE_SCOPE extern "C" +# else +# define MODULE_SCOPE extern +# endif +#endif + + + /* * Common include files needed by most of the Tcl source files are included * here, so that system-dependent personalizations for the include files only @@ -95,19 +112,6 @@ typedef int ptrdiff_t; #endif /* - * Used to tag functions that are only to be visible within the module being - * built and not outside it (where this is supported by the linker). - */ - -#ifndef MODULE_SCOPE -# ifdef __cplusplus -# define MODULE_SCOPE extern "C" -# else -# define MODULE_SCOPE extern -# endif -#endif - -/* * Macros used to cast between pointers and integers (e.g. when storing an int * in ClientData), on 64-bit architectures they avoid gcc warning about "cast * to/from pointer from/to integer of different size". -- cgit v0.12 From 57102e40e92f6bcde3433f2971c5f9c891cbaec5 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Thu, 16 Aug 2018 18:03:27 +0000 Subject: Experiment, resolving platform differences at script level. Don't look ... --- generic/tclBasic.c | 47 +---------- generic/tclCmdMZ.c | 7 +- generic/tclCompCmdsSZ.c | 3 - generic/tclExecute.c | 11 +-- generic/tclInt.h | 4 +- generic/tclObj.c | 6 +- generic/tclStubInit.c | 4 +- tests/compExpr-old.test | 6 +- tests/expr.test | 219 ++++++++++++++++++++++++------------------------ tests/format.test | 15 ++-- tests/obj.test | 16 ++-- tests/scan.test | 4 +- tests/string.test | 12 +-- tests/uplevel.test | 16 ++-- 14 files changed, 149 insertions(+), 221 deletions(-) diff --git a/generic/tclBasic.c b/generic/tclBasic.c index 81e1927..b7a6a24 100644 --- a/generic/tclBasic.c +++ b/generic/tclBasic.c @@ -116,7 +116,6 @@ static Tcl_ObjCmdProc ExprCeilFunc; static Tcl_ObjCmdProc ExprDoubleFunc; static Tcl_ObjCmdProc ExprEntierFunc; static Tcl_ObjCmdProc ExprFloorFunc; -static Tcl_ObjCmdProc ExprIntFunc; static Tcl_ObjCmdProc ExprIsqrtFunc; static Tcl_ObjCmdProc ExprMaxFunc; static Tcl_ObjCmdProc ExprMinFunc; @@ -125,7 +124,7 @@ static Tcl_ObjCmdProc ExprRoundFunc; static Tcl_ObjCmdProc ExprSqrtFunc; static Tcl_ObjCmdProc ExprSrandFunc; static Tcl_ObjCmdProc ExprUnaryFunc; -static Tcl_ObjCmdProc ExprWideFunc; +static Tcl_ObjCmdProc ExprIntFunc; static void MathFuncWrongNumArgs(Tcl_Interp *interp, int expected, int actual, Tcl_Obj *const *objv); static Tcl_NRPostProc NRCoroutineCallerCallback; @@ -336,7 +335,7 @@ static const BuiltinFuncDef BuiltinFuncTable[] = { { "srand", ExprSrandFunc, NULL }, { "tan", ExprUnaryFunc, (ClientData) tan }, { "tanh", ExprUnaryFunc, (ClientData) tanh }, - { "wide", ExprWideFunc, NULL }, + { "wide", ExprIntFunc, NULL }, { NULL, NULL, NULL } }; @@ -3660,16 +3659,8 @@ OldMathFuncProc( args[k].doubleValue = d; break; case TCL_INT: - if (ExprIntFunc(NULL, interp, 2, &objv[j-1]) != TCL_OK) { - ckfree(args); - return TCL_ERROR; - } - valuePtr = Tcl_GetObjResult(interp); - Tcl_GetLongFromObj(NULL, valuePtr, &args[k].intValue); - Tcl_ResetResult(interp); - break; case TCL_WIDE_INT: - if (ExprWideFunc(NULL, interp, 2, &objv[j-1]) != TCL_OK) { + if (ExprIntFunc(NULL, interp, 2, &objv[j-1]) != TCL_OK) { ckfree(args); return TCL_ERROR; } @@ -7680,38 +7671,6 @@ ExprIntFunc( int objc, /* Actual parameter count. */ Tcl_Obj *const *objv) /* Actual parameter vector. */ { - long iResult; - Tcl_Obj *objPtr; - if (ExprEntierFunc(NULL, interp, objc, objv) != TCL_OK) { - return TCL_ERROR; - } - objPtr = Tcl_GetObjResult(interp); - if (TclGetLongFromObj(NULL, objPtr, &iResult) != TCL_OK) { - /* - * Truncate the bignum; keep only bits in long range. - */ - - mp_int big; - - Tcl_GetBignumFromObj(NULL, objPtr, &big); - mp_mod_2d(&big, (int) CHAR_BIT * sizeof(long), &big); - objPtr = Tcl_NewBignumObj(&big); - Tcl_IncrRefCount(objPtr); - TclGetLongFromObj(NULL, objPtr, &iResult); - Tcl_DecrRefCount(objPtr); - } - Tcl_SetObjResult(interp, Tcl_NewLongObj(iResult)); - return TCL_OK; -} - -static int -ExprWideFunc( - ClientData clientData, /* Ignored. */ - Tcl_Interp *interp, /* The interpreter in which to execute the - * function. */ - int objc, /* Actual parameter count. */ - Tcl_Obj *const *objv) /* Actual parameter vector. */ -{ Tcl_WideInt wResult; Tcl_Obj *objPtr; diff --git a/generic/tclCmdMZ.c b/generic/tclCmdMZ.c index 0bd6cb4..f99a4a0 100644 --- a/generic/tclCmdMZ.c +++ b/generic/tclCmdMZ.c @@ -1622,11 +1622,6 @@ StringIsCmd( case STR_IS_GRAPH: chcomp = Tcl_UniCharIsGraph; break; - case STR_IS_INT: - if (TCL_OK == TclGetIntFromObj(NULL, objPtr, &i)) { - break; - } - goto failedIntParse; case STR_IS_ENTIER: if ((objPtr->typePtr == &tclIntType) || (objPtr->typePtr == &tclBignumType)) { @@ -1669,12 +1664,12 @@ StringIsCmd( failat = 0; } break; + case STR_IS_INT: case STR_IS_WIDE: if (TCL_OK == TclGetWideIntFromObj(NULL, objPtr, &w)) { break; } - failedIntParse: string1 = TclGetStringFromObj(objPtr, &length1); if (length1 == 0) { if (strict) { diff --git a/generic/tclCompCmdsSZ.c b/generic/tclCompCmdsSZ.c index 9434e54..8ab1ffa 100644 --- a/generic/tclCompCmdsSZ.c +++ b/generic/tclCompCmdsSZ.c @@ -692,9 +692,6 @@ TclCompileStringIsCmd( switch (t) { case STR_IS_INT: - PUSH( "1"); - OP( EQ); - break; case STR_IS_WIDE: PUSH( "2"); OP( LE); diff --git a/generic/tclExecute.c b/generic/tclExecute.c index 82de752..034bfd2 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -5634,18 +5634,9 @@ TEBCresume( case INST_NUM_TYPE: if (GetNumberFromObj(NULL, OBJ_AT_TOS, &ptr1, &type1) != TCL_OK) { type1 = 0; - } else if (type1 == TCL_NUMBER_WIDE) { - /* value is between LLONG_MIN and LLONG_MAX */ - /* [string is integer] is -UINT_MAX to UINT_MAX range */ - /* [string is wideinteger] is -ULLONG_MAX to ULLONG_MAX range */ - int i; - - if (Tcl_GetIntFromObj(NULL, OBJ_AT_TOS, &i) == TCL_OK) { - type1 = TCL_NUMBER_LONG; - } } else if (type1 == TCL_NUMBER_BIG) { /* value is an integer outside the LLONG_MIN to LLONG_MAX range */ - /* [string is wideinteger] is -ULLONG_MAX to ULLONG_MAX range */ + /* [string is wideinteger] is LLONG_MIN to LLONG_MAX range */ Tcl_WideInt w; if (Tcl_GetWideIntFromObj(NULL, OBJ_AT_TOS, &w) == TCL_OK) { diff --git a/generic/tclInt.h b/generic/tclInt.h index 64e7c67..c1e24f5 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -2493,7 +2493,7 @@ typedef struct List { #else #define TclGetLongFromObj(interp, objPtr, longPtr) \ (((objPtr)->typePtr == &tclIntType \ - && (objPtr)->internalRep.wideValue >= -(Tcl_WideInt)(ULONG_MAX) \ + && (objPtr)->internalRep.wideValue >= (Tcl_WideInt)(LONG_MIN) \ && (objPtr)->internalRep.wideValue <= (Tcl_WideInt)(ULONG_MAX)) \ ? ((*(longPtr) = (long)(objPtr)->internalRep.wideValue), TCL_OK) \ : Tcl_GetLongFromObj((interp), (objPtr), (longPtr))) @@ -2501,7 +2501,7 @@ typedef struct List { #define TclGetIntFromObj(interp, objPtr, intPtr) \ (((objPtr)->typePtr == &tclIntType \ - && (objPtr)->internalRep.wideValue >= -(Tcl_WideInt)(UINT_MAX) \ + && (objPtr)->internalRep.wideValue >= (Tcl_WideInt)(INT_MIN) \ && (objPtr)->internalRep.wideValue <= (Tcl_WideInt)(UINT_MAX)) \ ? ((*(intPtr) = (int)(objPtr)->internalRep.wideValue), TCL_OK) \ : Tcl_GetIntFromObj((interp), (objPtr), (intPtr))) diff --git a/generic/tclObj.c b/generic/tclObj.c index e10cbd7..40c27d5 100644 --- a/generic/tclObj.c +++ b/generic/tclObj.c @@ -2563,7 +2563,7 @@ Tcl_GetIntFromObj( if (TclGetLongFromObj(interp, objPtr, &l) != TCL_OK) { return TCL_ERROR; } - if ((ULONG_MAX > UINT_MAX) && ((l > UINT_MAX) || (l < -(long)UINT_MAX))) { + if ((ULONG_MAX > UINT_MAX) && ((l > (long)(UINT_MAX)) || (l < (long)(INT_MIN)))) { if (interp != NULL) { const char *s = "integer value too large to represent as non-long integer"; @@ -2870,7 +2870,7 @@ Tcl_GetLongFromObj( #else if (objPtr->typePtr == &tclIntType) { /* - * We return any integer in the range -ULONG_MAX to ULONG_MAX + * We return any integer in the range LONG_MIN to ULONG_MAX * converted to a long, ignoring overflow. The rule preserves * existing semantics for conversion of integers on input, but * avoids inadvertent demotion of wide integers to 32-bit ones in @@ -2879,7 +2879,7 @@ Tcl_GetLongFromObj( Tcl_WideInt w = objPtr->internalRep.wideValue; - if (w >= -(Tcl_WideInt)(ULONG_MAX) + if (w >= (Tcl_WideInt)(LONG_MIN) && w <= (Tcl_WideInt)(ULONG_MAX)) { *longPtr = Tcl_WideAsLong(w); return TCL_OK; diff --git a/generic/tclStubInit.c b/generic/tclStubInit.c index a3641f9..94b5561 100644 --- a/generic/tclStubInit.c +++ b/generic/tclStubInit.c @@ -271,7 +271,7 @@ static int exprInt(Tcl_Interp *interp, const char *expr, int *ptr){ long longValue; int result = Tcl_ExprLong(interp, expr, &longValue); if (result == TCL_OK) { - if ((longValue >= -(long)(UINT_MAX)) + if ((longValue >= (long)(INT_MIN)) && (longValue <= (long)(UINT_MAX))) { *ptr = (int)longValue; } else { @@ -287,7 +287,7 @@ static int exprIntObj(Tcl_Interp *interp, Tcl_Obj*expr, int *ptr){ long longValue; int result = Tcl_ExprLongObj(interp, expr, &longValue); if (result == TCL_OK) { - if ((longValue >= -(long)(UINT_MAX)) + if ((longValue >= (long)(INT_MIN)) && (longValue <= (long)(UINT_MAX))) { *ptr = (int)longValue; } else { diff --git a/tests/compExpr-old.test b/tests/compExpr-old.test index 0136ccd..4354520 100644 --- a/tests/compExpr-old.test +++ b/tests/compExpr-old.test @@ -79,7 +79,6 @@ proc testIEEE {} { testConstraint ieeeFloatingPoint [testIEEE] testConstraint longIs32bit [expr {int(0x80000000) < 0}] -testConstraint longIs64bit [expr {int(0x8000000000000000) < 0}] # procedures used below @@ -335,12 +334,9 @@ test compExpr-old-9.4 {CompileRelationalExpr: just shift expr} {expr {1<<3}} 8 # The following test is different for 32-bit versus 64-bit # architectures because LONG_MIN is different -test compExpr-old-9.5a {CompileRelationalExpr: shift expr producing LONG_MIN} longIs64bit { +test compExpr-old-9.5 {CompileRelationalExpr: shift expr producing LONG_MIN} { expr {int(1<<63)} } -9223372036854775808 -test compExpr-old-9.5b {CompileRelationalExpr: shift expr producing LONG_MIN} longIs32bit { - expr {int(1<<31)} -} -2147483648 test compExpr-old-9.6 {CompileRelationalExpr: error in shift expr} -body { expr x>>3 diff --git a/tests/expr.test b/tests/expr.test index 713681a..30a80ad 100644 --- a/tests/expr.test +++ b/tests/expr.test @@ -18,13 +18,10 @@ if {[lsearch [namespace children] ::tcltest] == -1} { ::tcltest::loadTestedCommands catch [list package require -exact Tcltest [info patchlevel]] -# Determine if "long int" type is a 32 bit number and if the wide -# type is a 64 bit number on this machine. +# Determine if "long int" type is a 32 bit number. testConstraint longIs32bit [expr {int(0x80000000) < 0}] testConstraint longIs64bit [expr {int(0x8000000000000000) < 0}] -testConstraint wideIs64bit \ - [expr {(wide(0x80000000) > 0) && (wide(0x8000000000000000) < 0)}] # Big test for correct ordering of data in [expr] @@ -5846,7 +5843,7 @@ test expr-33.2 {parse smallest long value} longIs32bit { [expr {int(-2147483648 - 1) == 0x7FFFFFFF}] \ } {-2147483648 -2147483648 -2147483648 -2147483648 1 1} -test expr-33.3 {parse largest wide value} wideIs64bit { +test expr-33.3 {parse largest wide value} { set max_wide_str 9223372036854775807 set max_wide_hex "0x7FFFFFFFFFFFFFFF " @@ -5863,7 +5860,7 @@ test expr-33.3 {parse largest wide value} wideIs64bit { [expr {wide(9223372036854775807 + 1) < 0}] \ } {9223372036854775807 9223372036854775807 9223372036854775807 9223372036854775807 1 1} -test expr-33.4 {parse smallest wide value} wideIs64bit { +test expr-33.4 {parse smallest wide value} { set min_wide_str -9223372036854775808 set min_wide_hex "-0x8000000000000000 " @@ -6271,341 +6268,341 @@ test expr-35.14 {expr edge cases} { set min -9223372036854775808 set max 9223372036854775807 -test expr-36.1 {expr edge cases} {wideIs64bit} { +test expr-36.1 {expr edge cases} { expr {$min / $min} } {1} -test expr-36.2 {expr edge cases} {wideIs64bit} { +test expr-36.2 {expr edge cases} { expr {$min % $min} } {0} -test expr-36.3 {expr edge cases} {wideIs64bit} { +test expr-36.3 {expr edge cases} { expr {$min / ($min + 1)} } {1} -test expr-36.4 {expr edge cases} {wideIs64bit} { +test expr-36.4 {expr edge cases} { expr {$min % ($min + 1)} } {-1} -test expr-36.5 {expr edge cases} {wideIs64bit} { +test expr-36.5 {expr edge cases} { expr {$min / ($min + 2)} } {1} -test expr-36.6 {expr edge cases} {wideIs64bit} { +test expr-36.6 {expr edge cases} { expr {$min % ($min + 2)} } {-2} -test expr-36.7 {expr edge cases} {wideIs64bit} { +test expr-36.7 {expr edge cases} { expr {$min / ($min + 3)} } {1} -test expr-36.8 {expr edge cases} {wideIs64bit} { +test expr-36.8 {expr edge cases} { expr {$min % ($min + 3)} } {-3} -test expr-36.9 {expr edge cases} {wideIs64bit} { +test expr-36.9 {expr edge cases} { expr {$min / -3} } {3074457345618258602} -test expr-36.10 {expr edge cases} {wideIs64bit} { +test expr-36.10 {expr edge cases} { expr {$min % -3} } {-2} -test expr-36.11 {expr edge cases} {wideIs64bit} { +test expr-36.11 {expr edge cases} { expr {$min / -2} } {4611686018427387904} -test expr-36.12 {expr edge cases} {wideIs64bit} { +test expr-36.12 {expr edge cases} { expr {$min % -2} } {0} -test expr-36.13 {expr edge cases} wideIs64bit { +test expr-36.13 {expr edge cases} { expr {wide($min / -1)} } $min -test expr-36.14 {expr edge cases} {wideIs64bit} { +test expr-36.14 {expr edge cases} { expr {$min % -1} } {0} -test expr-36.15 {expr edge cases} wideIs64bit { +test expr-36.15 {expr edge cases} { expr {wide($min * -1)} } $min -test expr-36.16 {expr edge cases} wideIs64bit { +test expr-36.16 {expr edge cases} { expr {wide(-$min)} } $min -test expr-36.17 {expr edge cases} {wideIs64bit} { +test expr-36.17 {expr edge cases} { expr {$min / 1} } $min -test expr-36.18 {expr edge cases} {wideIs64bit} { +test expr-36.18 {expr edge cases} { expr {$min % 1} } {0} -test expr-36.19 {expr edge cases} {wideIs64bit} { +test expr-36.19 {expr edge cases} { expr {$min / 2} } {-4611686018427387904} -test expr-36.20 {expr edge cases} {wideIs64bit} { +test expr-36.20 {expr edge cases} { expr {$min % 2} } {0} -test expr-36.21 {expr edge cases} {wideIs64bit} { +test expr-36.21 {expr edge cases} { expr {$min / 3} } {-3074457345618258603} -test expr-36.22 {expr edge cases} {wideIs64bit} { +test expr-36.22 {expr edge cases} { expr {$min % 3} } {1} -test expr-36.23 {expr edge cases} {wideIs64bit} { +test expr-36.23 {expr edge cases} { expr {$min / ($max - 3)} } {-2} -test expr-36.24 {expr edge cases} {wideIs64bit} { +test expr-36.24 {expr edge cases} { expr {$min % ($max - 3)} } {9223372036854775800} -test expr-36.25 {expr edge cases} {wideIs64bit} { +test expr-36.25 {expr edge cases} { expr {$min / ($max - 2)} } {-2} -test expr-36.26 {expr edge cases} {wideIs64bit} { +test expr-36.26 {expr edge cases} { expr {$min % ($max - 2)} } {9223372036854775802} -test expr-36.27 {expr edge cases} {wideIs64bit} { +test expr-36.27 {expr edge cases} { expr {$min / ($max - 1)} } {-2} -test expr-36.28 {expr edge cases} {wideIs64bit} { +test expr-36.28 {expr edge cases} { expr {$min % ($max - 1)} } {9223372036854775804} -test expr-36.29 {expr edge cases} {wideIs64bit} { +test expr-36.29 {expr edge cases} { expr {$min / $max} } {-2} -test expr-36.30 {expr edge cases} {wideIs64bit} { +test expr-36.30 {expr edge cases} { expr {$min % $max} } {9223372036854775806} -test expr-36.31 {expr edge cases} {wideIs64bit} { +test expr-36.31 {expr edge cases} { expr {$max / $max} } {1} -test expr-36.32 {expr edge cases} {wideIs64bit} { +test expr-36.32 {expr edge cases} { expr {$max % $max} } {0} -test expr-36.33 {expr edge cases} {wideIs64bit} { +test expr-36.33 {expr edge cases} { expr {$max / ($max - 1)} } {1} -test expr-36.34 {expr edge cases} {wideIs64bit} { +test expr-36.34 {expr edge cases} { expr {$max % ($max - 1)} } {1} -test expr-36.35 {expr edge cases} {wideIs64bit} { +test expr-36.35 {expr edge cases} { expr {$max / ($max - 2)} } {1} -test expr-36.36 {expr edge cases} {wideIs64bit} { +test expr-36.36 {expr edge cases} { expr {$max % ($max - 2)} } {2} -test expr-36.37 {expr edge cases} {wideIs64bit} { +test expr-36.37 {expr edge cases} { expr {$max / ($max - 3)} } {1} -test expr-36.38 {expr edge cases} {wideIs64bit} { +test expr-36.38 {expr edge cases} { expr {$max % ($max - 3)} } {3} -test expr-36.39 {expr edge cases} {wideIs64bit} { +test expr-36.39 {expr edge cases} { expr {$max / 3} } {3074457345618258602} -test expr-36.40 {expr edge cases} {wideIs64bit} { +test expr-36.40 {expr edge cases} { expr {$max % 3} } {1} -test expr-36.41 {expr edge cases} {wideIs64bit} { +test expr-36.41 {expr edge cases} { expr {$max / 2} } {4611686018427387903} -test expr-36.42 {expr edge cases} {wideIs64bit} { +test expr-36.42 {expr edge cases} { expr {$max % 2} } {1} -test expr-36.43 {expr edge cases} {wideIs64bit} { +test expr-36.43 {expr edge cases} { expr {$max / 1} } $max -test expr-36.44 {expr edge cases} {wideIs64bit} { +test expr-36.44 {expr edge cases} { expr {$max % 1} } {0} -test expr-36.45 {expr edge cases} {wideIs64bit} { +test expr-36.45 {expr edge cases} { expr {$max / -1} } "-$max" -test expr-36.46 {expr edge cases} {wideIs64bit} { +test expr-36.46 {expr edge cases} { expr {$max % -1} } {0} -test expr-36.47 {expr edge cases} {wideIs64bit} { +test expr-36.47 {expr edge cases} { expr {$max / -2} } {-4611686018427387904} -test expr-36.48 {expr edge cases} {wideIs64bit} { +test expr-36.48 {expr edge cases} { expr {$max % -2} } {-1} -test expr-36.49 {expr edge cases} {wideIs64bit} { +test expr-36.49 {expr edge cases} { expr {$max / -3} } {-3074457345618258603} -test expr-36.50 {expr edge cases} {wideIs64bit} { +test expr-36.50 {expr edge cases} { expr {$max % -3} } {-2} -test expr-36.51 {expr edge cases} {wideIs64bit} { +test expr-36.51 {expr edge cases} { expr {$max / ($min + 3)} } {-2} -test expr-36.52 {expr edge cases} {wideIs64bit} { +test expr-36.52 {expr edge cases} { expr {$max % ($min + 3)} } {-9223372036854775803} -test expr-36.53 {expr edge cases} {wideIs64bit} { +test expr-36.53 {expr edge cases} { expr {$max / ($min + 2)} } {-2} -test expr-36.54 {expr edge cases} {wideIs64bit} { +test expr-36.54 {expr edge cases} { expr {$max % ($min + 2)} } {-9223372036854775805} -test expr-36.55 {expr edge cases} {wideIs64bit} { +test expr-36.55 {expr edge cases} { expr {$max / ($min + 1)} } {-1} -test expr-36.56 {expr edge cases} {wideIs64bit} { +test expr-36.56 {expr edge cases} { expr {$max % ($min + 1)} } {0} -test expr-36.57 {expr edge cases} {wideIs64bit} { +test expr-36.57 {expr edge cases} { expr {$max / $min} } {-1} -test expr-36.58 {expr edge cases} {wideIs64bit} { +test expr-36.58 {expr edge cases} { expr {$max % $min} } {-1} -test expr-36.59 {expr edge cases} {wideIs64bit} { +test expr-36.59 {expr edge cases} { expr {($min + 1) / ($max - 1)} } {-2} -test expr-36.60 {expr edge cases} {wideIs64bit} { +test expr-36.60 {expr edge cases} { expr {($min + 1) % ($max - 1)} } {9223372036854775805} -test expr-36.61 {expr edge cases} {wideIs64bit} { +test expr-36.61 {expr edge cases} { expr {($max - 1) / ($min + 1)} } {-1} -test expr-36.62 {expr edge cases} {wideIs64bit} { +test expr-36.62 {expr edge cases} { expr {($max - 1) % ($min + 1)} } {-1} -test expr-36.63 {expr edge cases} {wideIs64bit} { +test expr-36.63 {expr edge cases} { expr {($max - 1) / $min} } {-1} -test expr-36.64 {expr edge cases} {wideIs64bit} { +test expr-36.64 {expr edge cases} { expr {($max - 1) % $min} } {-2} -test expr-36.65 {expr edge cases} {wideIs64bit} { +test expr-36.65 {expr edge cases} { expr {($max - 2) / $min} } {-1} -test expr-36.66 {expr edge cases} {wideIs64bit} { +test expr-36.66 {expr edge cases} { expr {($max - 2) % $min} } {-3} -test expr-36.67 {expr edge cases} {wideIs64bit} { +test expr-36.67 {expr edge cases} { expr {($max - 3) / $min} } {-1} -test expr-36.68 {expr edge cases} {wideIs64bit} { +test expr-36.68 {expr edge cases} { expr {($max - 3) % $min} } {-4} -test expr-36.69 {expr edge cases} {wideIs64bit} { +test expr-36.69 {expr edge cases} { expr {-3 / $min} } {0} -test expr-36.70 {expr edge cases} {wideIs64bit} { +test expr-36.70 {expr edge cases} { expr {-3 % $min} } {-3} -test expr-36.71 {expr edge cases} {wideIs64bit} { +test expr-36.71 {expr edge cases} { expr {-2 / $min} } {0} -test expr-36.72 {expr edge cases} {wideIs64bit} { +test expr-36.72 {expr edge cases} { expr {-2 % $min} } {-2} -test expr-36.73 {expr edge cases} {wideIs64bit} { +test expr-36.73 {expr edge cases} { expr {-1 / $min} } {0} -test expr-36.74 {expr edge cases} {wideIs64bit} { +test expr-36.74 {expr edge cases} { expr {-1 % $min} } {-1} -test expr-36.75 {expr edge cases} {wideIs64bit} { +test expr-36.75 {expr edge cases} { expr {0 / $min} } {0} -test expr-36.76 {expr edge cases} {wideIs64bit} { +test expr-36.76 {expr edge cases} { expr {0 % $min} } {0} -test expr-36.77 {expr edge cases} {wideIs64bit} { +test expr-36.77 {expr edge cases} { expr {0 / ($min + 1)} } {0} -test expr-36.78 {expr edge cases} {wideIs64bit} { +test expr-36.78 {expr edge cases} { expr {0 % ($min + 1)} } {0} -test expr-36.79 {expr edge cases} {wideIs64bit} { +test expr-36.79 {expr edge cases} { expr {1 / $min} } {-1} -test expr-36.80 {expr edge cases} {wideIs64bit} { +test expr-36.80 {expr edge cases} { expr {1 % $min} } {-9223372036854775807} -test expr-36.81 {expr edge cases} {wideIs64bit} { +test expr-36.81 {expr edge cases} { expr {1 / ($min + 1)} } {-1} -test expr-36.82 {expr edge cases} {wideIs64bit} { +test expr-36.82 {expr edge cases} { expr {1 % ($min + 1)} } {-9223372036854775806} -test expr-36.83 {expr edge cases} {wideIs64bit} { +test expr-36.83 {expr edge cases} { expr {2 / $min} } {-1} -test expr-36.84 {expr edge cases} {wideIs64bit} { +test expr-36.84 {expr edge cases} { expr {2 % $min} } {-9223372036854775806} -test expr-36.85 {expr edge cases} {wideIs64bit} { +test expr-36.85 {expr edge cases} { expr {2 / ($min + 1)} } {-1} -test expr-36.86 {expr edge cases} {wideIs64bit} { +test expr-36.86 {expr edge cases} { expr {2 % ($min + 1)} } {-9223372036854775805} -test expr-36.87 {expr edge cases} {wideIs64bit} { +test expr-36.87 {expr edge cases} { expr {3 / $min} } {-1} -test expr-36.88 {expr edge cases} {wideIs64bit} { +test expr-36.88 {expr edge cases} { expr {3 % $min} } {-9223372036854775805} -test expr-36.89 {expr edge cases} {wideIs64bit} { +test expr-36.89 {expr edge cases} { expr {3 / ($min + 1)} } {-1} -test expr-36.90 {expr edge cases} {wideIs64bit} { +test expr-36.90 {expr edge cases} { expr {3 % ($min + 1)} } {-9223372036854775804} -test expr-37.1 {expr edge cases} {wideIs64bit} { +test expr-37.1 {expr edge cases} { set dividend $max set divisor 2 set q [expr {$dividend / $divisor}] set r [expr {$dividend % $divisor}] list $q * $divisor + $r = [expr {($divisor * $q) + $r}] } {4611686018427387903 * 2 + 1 = 9223372036854775807} -test expr-37.2 {expr edge cases} {wideIs64bit} { +test expr-37.2 {expr edge cases} { set dividend [expr {$max - 1}] set divisor 2 set q [expr {$dividend / $divisor}] set r [expr {$dividend % $divisor}] list $q * $divisor + $r = [expr {($q * $divisor) + $r}] } {4611686018427387903 * 2 + 0 = 9223372036854775806} -test expr-37.3 {expr edge cases} {wideIs64bit} { +test expr-37.3 {expr edge cases} { set dividend [expr {$max - 2}] set divisor 2 set q [expr {$dividend / $divisor}] set r [expr {$dividend % $divisor}] list $q * $divisor + $r = [expr {($q * $divisor) + $r}] } {4611686018427387902 * 2 + 1 = 9223372036854775805} -test expr-37.4 {expr edge cases} {wideIs64bit} { +test expr-37.4 {expr edge cases} { set dividend $max set divisor 3 set q [expr {$dividend / $divisor}] set r [expr {$dividend % $divisor}] list $q * $divisor + $r = [expr {($q * $divisor) + $r}] } {3074457345618258602 * 3 + 1 = 9223372036854775807} -test expr-37.5 {expr edge cases} {wideIs64bit} { +test expr-37.5 {expr edge cases} { set dividend [expr {$max - 1}] set divisor 3 set q [expr {$dividend / $divisor}] set r [expr {$dividend % $divisor}] list $q * $divisor + $r = [expr {($q * $divisor) + $r}] } {3074457345618258602 * 3 + 0 = 9223372036854775806} -test expr-37.6 {expr edge cases} {wideIs64bit} { +test expr-37.6 {expr edge cases} { set dividend [expr {$max - 2}] set divisor 3 set q [expr {$dividend / $divisor}] set r [expr {$dividend % $divisor}] list $q * $divisor + $r = [expr {($q * $divisor) + $r}] } {3074457345618258601 * 3 + 2 = 9223372036854775805} -test expr-37.7 {expr edge cases} {wideIs64bit} { +test expr-37.7 {expr edge cases} { set dividend $min set divisor 2 set q [expr {$dividend / $divisor}] set r [expr {$dividend % $divisor}] list $q * $divisor + $r = [expr {($q * $divisor) + $r}] } {-4611686018427387904 * 2 + 0 = -9223372036854775808} -test expr-37.8 {expr edge cases} {wideIs64bit} { +test expr-37.8 {expr edge cases} { set dividend [expr {$min + 1}] set divisor 2 set q [expr {$dividend / $divisor}] set r [expr {$dividend % $divisor}] list $q * $divisor + $r = [expr {($q * $divisor) + $r}] } {-4611686018427387904 * 2 + 1 = -9223372036854775807} -test expr-37.9 {expr edge cases} {wideIs64bit} { +test expr-37.9 {expr edge cases} { set dividend [expr {$min + 2}] set divisor 2 set q [expr {$dividend / $divisor}] set r [expr {$dividend % $divisor}] list $q * $divisor + $r = [expr {($q * $divisor) + $r}] } {-4611686018427387903 * 2 + 0 = -9223372036854775806} -test expr-37.10 {expr edge cases} {wideIs64bit} { +test expr-37.10 {expr edge cases} { # Multiplication overflows 64 bit type here, # so when the 1 is added it overflows # again and we end up back at min. @@ -6615,28 +6612,28 @@ test expr-37.10 {expr edge cases} {wideIs64bit} { set r [expr {$dividend % $divisor}] list $q * $divisor + $r = [expr {($q * $divisor) + $r}] } {-3074457345618258603 * 3 + 1 = -9223372036854775808} -test expr-37.11 {expr edge cases} {wideIs64bit} { +test expr-37.11 {expr edge cases} { set dividend $min set divisor -3 set q [expr {$dividend / $divisor}] set r [expr {$dividend % $divisor}] list $q * $divisor + $r = [expr {($q * $divisor) + $r}] } {3074457345618258602 * -3 + -2 = -9223372036854775808} -test expr-37.12 {expr edge cases} {wideIs64bit} { +test expr-37.12 {expr edge cases} { set dividend $min set divisor $min set q [expr {$dividend / $divisor}] set r [expr {$dividend % $divisor}] list $q * $divisor + $r = [expr {($q * $divisor) + $r}] } {1 * -9223372036854775808 + 0 = -9223372036854775808} -test expr-37.13 {expr edge cases} {wideIs64bit} { +test expr-37.13 {expr edge cases} { set dividend $min set divisor [expr {$min + 1}] set q [expr {$dividend / $divisor}] set r [expr {$dividend % $divisor}] list $q * $divisor + $r = [expr {($q * $divisor) + $r}] } {1 * -9223372036854775807 + -1 = -9223372036854775808} -test expr-37.14 {expr edge cases} {wideIs64bit} { +test expr-37.14 {expr edge cases} { set dividend $min set divisor [expr {$min + 2}] set q [expr {$dividend / $divisor}] @@ -6644,7 +6641,7 @@ test expr-37.14 {expr edge cases} {wideIs64bit} { list $q * $divisor + $r = [expr {($q * $divisor) + $r}] } {1 * -9223372036854775806 + -2 = -9223372036854775808} -test expr-38.1 {abs of smallest 32-bit integer [Bug 1241572]} {wideIs64bit} { +test expr-38.1 {abs of smallest 32-bit integer [Bug 1241572]} { expr {abs(-2147483648)} } 2147483648 test expr-38.2 {abs and -0 [Bug 1893815]} { diff --git a/tests/format.test b/tests/format.test index cdea545..ff85cb2 100644 --- a/tests/format.test +++ b/tests/format.test @@ -18,9 +18,6 @@ if {[lsearch [namespace children] ::tcltest] == -1} { # %u output depends on word length, so this test is not portable. testConstraint longIs32bit [expr {int(0x80000000) < 0}] testConstraint longIs64bit [expr {int(0x8000000000000000) < 0}] -testConstraint wideIs64bit \ - [expr {(wide(0x80000000) > 0) && (wide(0x8000000000000000) < 0)}] -testConstraint wideBiggerThanInt [expr {wide(0x80000000) != int(0x80000000)}] testConstraint pointerIs64bit [expr {$tcl_platform(pointerSize) >= 8}] test format-1.1 {integer formatting} { @@ -547,13 +544,13 @@ for {set i 290} {$i < 400} {incr i} { append b "x" } -test format-17.1 {testing %d with wide} {wideIs64bit wideBiggerThanInt} { +test format-17.1 {testing %d with wide} { format %d 7810179016327718216 -} 1819043144 -test format-17.2 {testing %ld with wide} {wideIs64bit} { +} 7810179016327718216 +test format-17.2 {testing %ld with wide} { format %ld 7810179016327718216 } 7810179016327718216 -test format-17.3 {testing %ld with non-wide} {wideIs64bit} { +test format-17.3 {testing %ld with non-wide} { format %ld 42 } 42 test format-17.4 {testing %l with non-integer} { @@ -580,11 +577,11 @@ test format-18.1 {do not demote existing numeric values} { format %08x $b lappend result [expr {$a == $b}] } {1 1 1 1} -test format-18.2 {do not demote existing numeric values} {wideBiggerThanInt} { +test format-18.2 {do not demote existing numeric values} { set a [expr {0xaaaaaaaaaa + 1}] set b 0xaaaaaaaaab list [format %08x $a] [expr {$a == $b}] -} {aaaaaaab 1} +} {aaaaaaaaab 1} test format-19.1 {regression test - tcl-core message by Brian Griffin on 26 0ctober 2004} -body { set x 0x8fedc654 diff --git a/tests/obj.test b/tests/obj.test index cb62d3f..41b1428 100644 --- a/tests/obj.test +++ b/tests/obj.test @@ -20,8 +20,6 @@ if {[lsearch [namespace children] ::tcltest] == -1} { catch [list package require -exact Tcltest [info patchlevel]] testConstraint testobj [llength [info commands testobj]] -testConstraint longIs32bit [expr {int(0x80000000) < 0}] -testConstraint wideBiggerThanInt [expr {wide(0x80000000) != int(0x80000000)}] test obj-1.1 {Tcl_AppendAllObjTypes, and InitTypeTable, Tcl_RegisterObjType} testobj { set r 1 @@ -549,34 +547,34 @@ test obj-32.1 {freeing very large object trees} { unset x } {} -test obj-33.1 {integer overflow on input} {longIs32bit wideBiggerThanInt} { +test obj-33.1 {integer overflow on input} { set x 0x8000; append x 0000 list [string is integer $x] [expr { wide($x) }] } {1 2147483648} -test obj-33.2 {integer overflow on input} {longIs32bit wideBiggerThanInt} { +test obj-33.2 {integer overflow on input} { set x 0xffff; append x ffff list [string is integer $x] [expr { wide($x) }] } {1 4294967295} test obj-33.3 {integer overflow on input} { set x 0x10000; append x 0000 list [string is integer $x] [expr { wide($x) }] -} {0 4294967296} -test obj-33.4 {integer overflow on input} {longIs32bit wideBiggerThanInt} { +} {1 4294967296} +test obj-33.4 {integer overflow on input} { set x -0x8000; append x 0000 list [string is integer $x] [expr { wide($x) }] } {1 -2147483648} -test obj-33.5 {integer overflow on input} {longIs32bit wideBiggerThanInt} { +test obj-33.5 {integer overflow on input} { set x -0x8000; append x 0001 list [string is integer $x] [expr { wide($x) }] } {1 -2147483649} -test obj-33.6 {integer overflow on input} {longIs32bit wideBiggerThanInt} { +test obj-33.6 {integer overflow on input} { set x -0xffff; append x ffff list [string is integer $x] [expr { wide($x) }] } {1 -4294967295} test obj-33.7 {integer overflow on input} { set x -0x10000; append x 0000 list [string is integer $x] [expr { wide($x) }] -} {0 -4294967296} +} {1 -4294967296} test obj-34.1 {mp_iseven} testobj { set result "" diff --git a/tests/scan.test b/tests/scan.test index 1f32b9f..0b7b14a 100644 --- a/tests/scan.test +++ b/tests/scan.test @@ -85,8 +85,6 @@ proc testIEEE {} { } testConstraint ieeeFloatingPoint [testIEEE] -testConstraint wideIs64bit \ - [expr {(wide(0x80000000) > 0) && (wide(0x8000000000000000) < 0)}] test scan-1.1 {BuildCharSet, CharInSet} { list [scan foo {%[^o]} x] $x @@ -521,7 +519,7 @@ test scan-5.11 {integer scanning} -constraints {nonPortable} -setup { list [scan "4294967280 4294967280" "%u %d" a b] $a \ [expr {$b == -16 || $b == 0x7fffffff}] } -result {2 4294967280 1} -test scan-5.12 {integer scanning} -constraints {wideIs64bit} -setup { +test scan-5.12 {integer scanning} -setup { set a {}; set b {}; set c {} } -body { list [scan "7810179016327718216,6c63546f6c6c6548,661432506755433062510" \ diff --git a/tests/string.test b/tests/string.test index d169193..81588ff 100644 --- a/tests/string.test +++ b/tests/string.test @@ -807,20 +807,20 @@ test string-6.91.$noComp {string is double, bad doubles} { } return $result } {1 1 0 0 0 1 0 0} -test string-6.92.$noComp {string is integer, 32-bit overflow} { +test string-6.92.$noComp {string is integer, 64-bit overflow} { # Bug 718878 - set x 0x100000000 + set x 0x10000000000000000 list [run {string is integer -failindex var $x}] $var } {0 -1} -test string-6.93.$noComp {string is integer, 32-bit overflow} { +test string-6.93.$noComp {string is integer, 64-bit overflow} { # Bug 718878 - set x 0x100000000 + set x 0x10000000000000000 append x "" list [run {string is integer -failindex var $x}] $var } {0 -1} -test string-6.94.$noComp {string is integer, 32-bit overflow} { +test string-6.94.$noComp {string is integer, 64-bit overflow} { # Bug 718878 - set x 0x100000000 + set x 0x10000000000000000 list [run {string is integer -failindex var [expr {$x}]}] $var } {0 -1} test string-6.95.$noComp {string is wideinteger, true} { diff --git a/tests/uplevel.test b/tests/uplevel.test index 737c571..83d6b42 100644 --- a/tests/uplevel.test +++ b/tests/uplevel.test @@ -137,18 +137,18 @@ test uplevel-4.15 {level parsing} { test uplevel-4.16 {level parsing} { apply {{} {uplevel #[expr 1] {}}} } {} -test uplevel-4.17 {level parsing} { +test uplevel-4.17 {level parsing} -returnCodes error -body { apply {{} {uplevel -0xffffffff {}}} -} {} -test uplevel-4.18 {level parsing} { +} -result {invalid command name "-0xffffffff"} +test uplevel-4.18 {level parsing} -returnCodes error -body { apply {{} {uplevel #-0xffffffff {}}} -} {} -test uplevel-4.19 {level parsing} { +} -result {bad level "#-0xffffffff"} +test uplevel-4.19 {level parsing} -returnCodes error -body { apply {{} {uplevel [expr -0xffffffff] {}}} -} {} -test uplevel-4.20 {level parsing} { +} -result {invalid command name "-4294967295"} +test uplevel-4.20 {level parsing} -returnCodes error -body { apply {{} {uplevel #[expr -0xffffffff] {}}} -} {} +} -result {bad level "#-4294967295"} test uplevel-4.21 {level parsing} -body { apply {{} {uplevel -1 {}}} } -returnCodes error -result {invalid command name "-1"} -- cgit v0.12 From 51ce0579e8d61cfce32dbe6ad2d2894ec6de60f7 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Thu, 16 Aug 2018 18:13:31 +0000 Subject: Few more test-cases --- tests/compExpr-old.test | 2 -- tests/execute.test | 15 +++++++-------- tests/expr.test | 5 +---- 3 files changed, 8 insertions(+), 14 deletions(-) diff --git a/tests/compExpr-old.test b/tests/compExpr-old.test index 4354520..267b228 100644 --- a/tests/compExpr-old.test +++ b/tests/compExpr-old.test @@ -78,8 +78,6 @@ proc testIEEE {} { } testConstraint ieeeFloatingPoint [testIEEE] -testConstraint longIs32bit [expr {int(0x80000000) < 0}] - # procedures used below proc put_hello_char {c} { diff --git a/tests/execute.test b/tests/execute.test index 6c277f8..ac97c6c 100644 --- a/tests/execute.test +++ b/tests/execute.test @@ -34,7 +34,6 @@ testConstraint testobj [expr { && [llength [info commands teststringobj]] }] -testConstraint longIs32bit [expr {int(0x80000000) < 0}] testConstraint testexprlongobj [llength [info commands testexprlongobj]] # Tests for the omnibus TclExecuteByteCode function: @@ -805,9 +804,9 @@ test execute-7.7 {Wide int handling in INST_EQ and [incr]} { set y [expr {$x+1}] expr {double($x) == double($y)} } 1 -test execute-7.8 {Wide int conversions can change sign} longIs32bit { - set x 0x80000000 - expr {int($x) < wide($x)} +test execute-7.8 {Wide int conversions can change sign} { + set x 0x8000000000000000 + expr {int($x) < $x} } 1 test execute-7.9 {Wide int handling in INST_MOD} { expr {(wide(1)<<60) % ((wide(47)<<45)-1)} @@ -887,11 +886,11 @@ test execute-7.31 {Wide int handling in abs()} { set y 0x123456871234568 concat [expr {abs($x)}] [expr {abs($y)}] } {730503879441204585 81985533099853160} -test execute-7.32 {Wide int handling} longIs32bit { - expr {int(1024 * 1024 * 1024 * 1024)} +test execute-7.32 {Wide int handling} { + expr {int(1024 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024)} } 0 -test execute-7.33 {Wide int handling} longIs32bit { - expr {int(0x1 * 1024 * 1024 * 1024 * 1024)} +test execute-7.33 {Wide int handling} { + expr {int(0x1 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024)} } 0 test execute-7.34 {Wide int handling} { expr {wide(0x1) * 1024 * 1024 * 1024 * 1024} diff --git a/tests/expr.test b/tests/expr.test index 30a80ad..9f36823 100644 --- a/tests/expr.test +++ b/tests/expr.test @@ -414,12 +414,9 @@ test expr-9.1 {CompileRelationalExpr: just shift expr} {expr 3<<2} 12 test expr-9.2 {CompileRelationalExpr: just shift expr} {expr 0xff>>2} 63 test expr-9.3 {CompileRelationalExpr: just shift expr} {expr -1>>2} -1 test expr-9.4 {CompileRelationalExpr: just shift expr} {expr {1<<3}} 8 -test expr-9.5a {CompileRelationalExpr: shift expr producing LONG_MIN} longIs64bit { +test expr-9.5 {CompileRelationalExpr: shift expr producing LONG_MIN} { expr {int(1<<63)} } -9223372036854775808 -test expr-9.5b {CompileRelationalExpr: shift expr producing LONG_MIN} longIs32bit { - expr {int(1<<31)} -} -2147483648 test expr-9.6 {CompileRelationalExpr: error in shift expr} -body { expr x>>3 } -returnCodes error -match glob -result * -- cgit v0.12 From c475df7cfbfab932ff2a21678fa244094c7c49ee Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Thu, 16 Aug 2018 18:54:44 +0000 Subject: Undo various test-case changes, in order to prove platform compatibility --- tests/compExpr-old.test | 8 +- tests/execute.test | 15 ++-- tests/expr.test | 224 +++++++++++++++++++++++++----------------------- tests/format.test | 15 ++-- tests/obj.test | 24 +++--- tests/scan.test | 4 +- 6 files changed, 155 insertions(+), 135 deletions(-) diff --git a/tests/compExpr-old.test b/tests/compExpr-old.test index 267b228..0136ccd 100644 --- a/tests/compExpr-old.test +++ b/tests/compExpr-old.test @@ -78,6 +78,9 @@ proc testIEEE {} { } testConstraint ieeeFloatingPoint [testIEEE] +testConstraint longIs32bit [expr {int(0x80000000) < 0}] +testConstraint longIs64bit [expr {int(0x8000000000000000) < 0}] + # procedures used below proc put_hello_char {c} { @@ -332,9 +335,12 @@ test compExpr-old-9.4 {CompileRelationalExpr: just shift expr} {expr {1<<3}} 8 # The following test is different for 32-bit versus 64-bit # architectures because LONG_MIN is different -test compExpr-old-9.5 {CompileRelationalExpr: shift expr producing LONG_MIN} { +test compExpr-old-9.5a {CompileRelationalExpr: shift expr producing LONG_MIN} longIs64bit { expr {int(1<<63)} } -9223372036854775808 +test compExpr-old-9.5b {CompileRelationalExpr: shift expr producing LONG_MIN} longIs32bit { + expr {int(1<<31)} +} -2147483648 test compExpr-old-9.6 {CompileRelationalExpr: error in shift expr} -body { expr x>>3 diff --git a/tests/execute.test b/tests/execute.test index ac97c6c..6c277f8 100644 --- a/tests/execute.test +++ b/tests/execute.test @@ -34,6 +34,7 @@ testConstraint testobj [expr { && [llength [info commands teststringobj]] }] +testConstraint longIs32bit [expr {int(0x80000000) < 0}] testConstraint testexprlongobj [llength [info commands testexprlongobj]] # Tests for the omnibus TclExecuteByteCode function: @@ -804,9 +805,9 @@ test execute-7.7 {Wide int handling in INST_EQ and [incr]} { set y [expr {$x+1}] expr {double($x) == double($y)} } 1 -test execute-7.8 {Wide int conversions can change sign} { - set x 0x8000000000000000 - expr {int($x) < $x} +test execute-7.8 {Wide int conversions can change sign} longIs32bit { + set x 0x80000000 + expr {int($x) < wide($x)} } 1 test execute-7.9 {Wide int handling in INST_MOD} { expr {(wide(1)<<60) % ((wide(47)<<45)-1)} @@ -886,11 +887,11 @@ test execute-7.31 {Wide int handling in abs()} { set y 0x123456871234568 concat [expr {abs($x)}] [expr {abs($y)}] } {730503879441204585 81985533099853160} -test execute-7.32 {Wide int handling} { - expr {int(1024 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024)} +test execute-7.32 {Wide int handling} longIs32bit { + expr {int(1024 * 1024 * 1024 * 1024)} } 0 -test execute-7.33 {Wide int handling} { - expr {int(0x1 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024)} +test execute-7.33 {Wide int handling} longIs32bit { + expr {int(0x1 * 1024 * 1024 * 1024 * 1024)} } 0 test execute-7.34 {Wide int handling} { expr {wide(0x1) * 1024 * 1024 * 1024 * 1024} diff --git a/tests/expr.test b/tests/expr.test index 9f36823..713681a 100644 --- a/tests/expr.test +++ b/tests/expr.test @@ -18,10 +18,13 @@ if {[lsearch [namespace children] ::tcltest] == -1} { ::tcltest::loadTestedCommands catch [list package require -exact Tcltest [info patchlevel]] -# Determine if "long int" type is a 32 bit number. +# Determine if "long int" type is a 32 bit number and if the wide +# type is a 64 bit number on this machine. testConstraint longIs32bit [expr {int(0x80000000) < 0}] testConstraint longIs64bit [expr {int(0x8000000000000000) < 0}] +testConstraint wideIs64bit \ + [expr {(wide(0x80000000) > 0) && (wide(0x8000000000000000) < 0)}] # Big test for correct ordering of data in [expr] @@ -414,9 +417,12 @@ test expr-9.1 {CompileRelationalExpr: just shift expr} {expr 3<<2} 12 test expr-9.2 {CompileRelationalExpr: just shift expr} {expr 0xff>>2} 63 test expr-9.3 {CompileRelationalExpr: just shift expr} {expr -1>>2} -1 test expr-9.4 {CompileRelationalExpr: just shift expr} {expr {1<<3}} 8 -test expr-9.5 {CompileRelationalExpr: shift expr producing LONG_MIN} { +test expr-9.5a {CompileRelationalExpr: shift expr producing LONG_MIN} longIs64bit { expr {int(1<<63)} } -9223372036854775808 +test expr-9.5b {CompileRelationalExpr: shift expr producing LONG_MIN} longIs32bit { + expr {int(1<<31)} +} -2147483648 test expr-9.6 {CompileRelationalExpr: error in shift expr} -body { expr x>>3 } -returnCodes error -match glob -result * @@ -5840,7 +5846,7 @@ test expr-33.2 {parse smallest long value} longIs32bit { [expr {int(-2147483648 - 1) == 0x7FFFFFFF}] \ } {-2147483648 -2147483648 -2147483648 -2147483648 1 1} -test expr-33.3 {parse largest wide value} { +test expr-33.3 {parse largest wide value} wideIs64bit { set max_wide_str 9223372036854775807 set max_wide_hex "0x7FFFFFFFFFFFFFFF " @@ -5857,7 +5863,7 @@ test expr-33.3 {parse largest wide value} { [expr {wide(9223372036854775807 + 1) < 0}] \ } {9223372036854775807 9223372036854775807 9223372036854775807 9223372036854775807 1 1} -test expr-33.4 {parse smallest wide value} { +test expr-33.4 {parse smallest wide value} wideIs64bit { set min_wide_str -9223372036854775808 set min_wide_hex "-0x8000000000000000 " @@ -6265,341 +6271,341 @@ test expr-35.14 {expr edge cases} { set min -9223372036854775808 set max 9223372036854775807 -test expr-36.1 {expr edge cases} { +test expr-36.1 {expr edge cases} {wideIs64bit} { expr {$min / $min} } {1} -test expr-36.2 {expr edge cases} { +test expr-36.2 {expr edge cases} {wideIs64bit} { expr {$min % $min} } {0} -test expr-36.3 {expr edge cases} { +test expr-36.3 {expr edge cases} {wideIs64bit} { expr {$min / ($min + 1)} } {1} -test expr-36.4 {expr edge cases} { +test expr-36.4 {expr edge cases} {wideIs64bit} { expr {$min % ($min + 1)} } {-1} -test expr-36.5 {expr edge cases} { +test expr-36.5 {expr edge cases} {wideIs64bit} { expr {$min / ($min + 2)} } {1} -test expr-36.6 {expr edge cases} { +test expr-36.6 {expr edge cases} {wideIs64bit} { expr {$min % ($min + 2)} } {-2} -test expr-36.7 {expr edge cases} { +test expr-36.7 {expr edge cases} {wideIs64bit} { expr {$min / ($min + 3)} } {1} -test expr-36.8 {expr edge cases} { +test expr-36.8 {expr edge cases} {wideIs64bit} { expr {$min % ($min + 3)} } {-3} -test expr-36.9 {expr edge cases} { +test expr-36.9 {expr edge cases} {wideIs64bit} { expr {$min / -3} } {3074457345618258602} -test expr-36.10 {expr edge cases} { +test expr-36.10 {expr edge cases} {wideIs64bit} { expr {$min % -3} } {-2} -test expr-36.11 {expr edge cases} { +test expr-36.11 {expr edge cases} {wideIs64bit} { expr {$min / -2} } {4611686018427387904} -test expr-36.12 {expr edge cases} { +test expr-36.12 {expr edge cases} {wideIs64bit} { expr {$min % -2} } {0} -test expr-36.13 {expr edge cases} { +test expr-36.13 {expr edge cases} wideIs64bit { expr {wide($min / -1)} } $min -test expr-36.14 {expr edge cases} { +test expr-36.14 {expr edge cases} {wideIs64bit} { expr {$min % -1} } {0} -test expr-36.15 {expr edge cases} { +test expr-36.15 {expr edge cases} wideIs64bit { expr {wide($min * -1)} } $min -test expr-36.16 {expr edge cases} { +test expr-36.16 {expr edge cases} wideIs64bit { expr {wide(-$min)} } $min -test expr-36.17 {expr edge cases} { +test expr-36.17 {expr edge cases} {wideIs64bit} { expr {$min / 1} } $min -test expr-36.18 {expr edge cases} { +test expr-36.18 {expr edge cases} {wideIs64bit} { expr {$min % 1} } {0} -test expr-36.19 {expr edge cases} { +test expr-36.19 {expr edge cases} {wideIs64bit} { expr {$min / 2} } {-4611686018427387904} -test expr-36.20 {expr edge cases} { +test expr-36.20 {expr edge cases} {wideIs64bit} { expr {$min % 2} } {0} -test expr-36.21 {expr edge cases} { +test expr-36.21 {expr edge cases} {wideIs64bit} { expr {$min / 3} } {-3074457345618258603} -test expr-36.22 {expr edge cases} { +test expr-36.22 {expr edge cases} {wideIs64bit} { expr {$min % 3} } {1} -test expr-36.23 {expr edge cases} { +test expr-36.23 {expr edge cases} {wideIs64bit} { expr {$min / ($max - 3)} } {-2} -test expr-36.24 {expr edge cases} { +test expr-36.24 {expr edge cases} {wideIs64bit} { expr {$min % ($max - 3)} } {9223372036854775800} -test expr-36.25 {expr edge cases} { +test expr-36.25 {expr edge cases} {wideIs64bit} { expr {$min / ($max - 2)} } {-2} -test expr-36.26 {expr edge cases} { +test expr-36.26 {expr edge cases} {wideIs64bit} { expr {$min % ($max - 2)} } {9223372036854775802} -test expr-36.27 {expr edge cases} { +test expr-36.27 {expr edge cases} {wideIs64bit} { expr {$min / ($max - 1)} } {-2} -test expr-36.28 {expr edge cases} { +test expr-36.28 {expr edge cases} {wideIs64bit} { expr {$min % ($max - 1)} } {9223372036854775804} -test expr-36.29 {expr edge cases} { +test expr-36.29 {expr edge cases} {wideIs64bit} { expr {$min / $max} } {-2} -test expr-36.30 {expr edge cases} { +test expr-36.30 {expr edge cases} {wideIs64bit} { expr {$min % $max} } {9223372036854775806} -test expr-36.31 {expr edge cases} { +test expr-36.31 {expr edge cases} {wideIs64bit} { expr {$max / $max} } {1} -test expr-36.32 {expr edge cases} { +test expr-36.32 {expr edge cases} {wideIs64bit} { expr {$max % $max} } {0} -test expr-36.33 {expr edge cases} { +test expr-36.33 {expr edge cases} {wideIs64bit} { expr {$max / ($max - 1)} } {1} -test expr-36.34 {expr edge cases} { +test expr-36.34 {expr edge cases} {wideIs64bit} { expr {$max % ($max - 1)} } {1} -test expr-36.35 {expr edge cases} { +test expr-36.35 {expr edge cases} {wideIs64bit} { expr {$max / ($max - 2)} } {1} -test expr-36.36 {expr edge cases} { +test expr-36.36 {expr edge cases} {wideIs64bit} { expr {$max % ($max - 2)} } {2} -test expr-36.37 {expr edge cases} { +test expr-36.37 {expr edge cases} {wideIs64bit} { expr {$max / ($max - 3)} } {1} -test expr-36.38 {expr edge cases} { +test expr-36.38 {expr edge cases} {wideIs64bit} { expr {$max % ($max - 3)} } {3} -test expr-36.39 {expr edge cases} { +test expr-36.39 {expr edge cases} {wideIs64bit} { expr {$max / 3} } {3074457345618258602} -test expr-36.40 {expr edge cases} { +test expr-36.40 {expr edge cases} {wideIs64bit} { expr {$max % 3} } {1} -test expr-36.41 {expr edge cases} { +test expr-36.41 {expr edge cases} {wideIs64bit} { expr {$max / 2} } {4611686018427387903} -test expr-36.42 {expr edge cases} { +test expr-36.42 {expr edge cases} {wideIs64bit} { expr {$max % 2} } {1} -test expr-36.43 {expr edge cases} { +test expr-36.43 {expr edge cases} {wideIs64bit} { expr {$max / 1} } $max -test expr-36.44 {expr edge cases} { +test expr-36.44 {expr edge cases} {wideIs64bit} { expr {$max % 1} } {0} -test expr-36.45 {expr edge cases} { +test expr-36.45 {expr edge cases} {wideIs64bit} { expr {$max / -1} } "-$max" -test expr-36.46 {expr edge cases} { +test expr-36.46 {expr edge cases} {wideIs64bit} { expr {$max % -1} } {0} -test expr-36.47 {expr edge cases} { +test expr-36.47 {expr edge cases} {wideIs64bit} { expr {$max / -2} } {-4611686018427387904} -test expr-36.48 {expr edge cases} { +test expr-36.48 {expr edge cases} {wideIs64bit} { expr {$max % -2} } {-1} -test expr-36.49 {expr edge cases} { +test expr-36.49 {expr edge cases} {wideIs64bit} { expr {$max / -3} } {-3074457345618258603} -test expr-36.50 {expr edge cases} { +test expr-36.50 {expr edge cases} {wideIs64bit} { expr {$max % -3} } {-2} -test expr-36.51 {expr edge cases} { +test expr-36.51 {expr edge cases} {wideIs64bit} { expr {$max / ($min + 3)} } {-2} -test expr-36.52 {expr edge cases} { +test expr-36.52 {expr edge cases} {wideIs64bit} { expr {$max % ($min + 3)} } {-9223372036854775803} -test expr-36.53 {expr edge cases} { +test expr-36.53 {expr edge cases} {wideIs64bit} { expr {$max / ($min + 2)} } {-2} -test expr-36.54 {expr edge cases} { +test expr-36.54 {expr edge cases} {wideIs64bit} { expr {$max % ($min + 2)} } {-9223372036854775805} -test expr-36.55 {expr edge cases} { +test expr-36.55 {expr edge cases} {wideIs64bit} { expr {$max / ($min + 1)} } {-1} -test expr-36.56 {expr edge cases} { +test expr-36.56 {expr edge cases} {wideIs64bit} { expr {$max % ($min + 1)} } {0} -test expr-36.57 {expr edge cases} { +test expr-36.57 {expr edge cases} {wideIs64bit} { expr {$max / $min} } {-1} -test expr-36.58 {expr edge cases} { +test expr-36.58 {expr edge cases} {wideIs64bit} { expr {$max % $min} } {-1} -test expr-36.59 {expr edge cases} { +test expr-36.59 {expr edge cases} {wideIs64bit} { expr {($min + 1) / ($max - 1)} } {-2} -test expr-36.60 {expr edge cases} { +test expr-36.60 {expr edge cases} {wideIs64bit} { expr {($min + 1) % ($max - 1)} } {9223372036854775805} -test expr-36.61 {expr edge cases} { +test expr-36.61 {expr edge cases} {wideIs64bit} { expr {($max - 1) / ($min + 1)} } {-1} -test expr-36.62 {expr edge cases} { +test expr-36.62 {expr edge cases} {wideIs64bit} { expr {($max - 1) % ($min + 1)} } {-1} -test expr-36.63 {expr edge cases} { +test expr-36.63 {expr edge cases} {wideIs64bit} { expr {($max - 1) / $min} } {-1} -test expr-36.64 {expr edge cases} { +test expr-36.64 {expr edge cases} {wideIs64bit} { expr {($max - 1) % $min} } {-2} -test expr-36.65 {expr edge cases} { +test expr-36.65 {expr edge cases} {wideIs64bit} { expr {($max - 2) / $min} } {-1} -test expr-36.66 {expr edge cases} { +test expr-36.66 {expr edge cases} {wideIs64bit} { expr {($max - 2) % $min} } {-3} -test expr-36.67 {expr edge cases} { +test expr-36.67 {expr edge cases} {wideIs64bit} { expr {($max - 3) / $min} } {-1} -test expr-36.68 {expr edge cases} { +test expr-36.68 {expr edge cases} {wideIs64bit} { expr {($max - 3) % $min} } {-4} -test expr-36.69 {expr edge cases} { +test expr-36.69 {expr edge cases} {wideIs64bit} { expr {-3 / $min} } {0} -test expr-36.70 {expr edge cases} { +test expr-36.70 {expr edge cases} {wideIs64bit} { expr {-3 % $min} } {-3} -test expr-36.71 {expr edge cases} { +test expr-36.71 {expr edge cases} {wideIs64bit} { expr {-2 / $min} } {0} -test expr-36.72 {expr edge cases} { +test expr-36.72 {expr edge cases} {wideIs64bit} { expr {-2 % $min} } {-2} -test expr-36.73 {expr edge cases} { +test expr-36.73 {expr edge cases} {wideIs64bit} { expr {-1 / $min} } {0} -test expr-36.74 {expr edge cases} { +test expr-36.74 {expr edge cases} {wideIs64bit} { expr {-1 % $min} } {-1} -test expr-36.75 {expr edge cases} { +test expr-36.75 {expr edge cases} {wideIs64bit} { expr {0 / $min} } {0} -test expr-36.76 {expr edge cases} { +test expr-36.76 {expr edge cases} {wideIs64bit} { expr {0 % $min} } {0} -test expr-36.77 {expr edge cases} { +test expr-36.77 {expr edge cases} {wideIs64bit} { expr {0 / ($min + 1)} } {0} -test expr-36.78 {expr edge cases} { +test expr-36.78 {expr edge cases} {wideIs64bit} { expr {0 % ($min + 1)} } {0} -test expr-36.79 {expr edge cases} { +test expr-36.79 {expr edge cases} {wideIs64bit} { expr {1 / $min} } {-1} -test expr-36.80 {expr edge cases} { +test expr-36.80 {expr edge cases} {wideIs64bit} { expr {1 % $min} } {-9223372036854775807} -test expr-36.81 {expr edge cases} { +test expr-36.81 {expr edge cases} {wideIs64bit} { expr {1 / ($min + 1)} } {-1} -test expr-36.82 {expr edge cases} { +test expr-36.82 {expr edge cases} {wideIs64bit} { expr {1 % ($min + 1)} } {-9223372036854775806} -test expr-36.83 {expr edge cases} { +test expr-36.83 {expr edge cases} {wideIs64bit} { expr {2 / $min} } {-1} -test expr-36.84 {expr edge cases} { +test expr-36.84 {expr edge cases} {wideIs64bit} { expr {2 % $min} } {-9223372036854775806} -test expr-36.85 {expr edge cases} { +test expr-36.85 {expr edge cases} {wideIs64bit} { expr {2 / ($min + 1)} } {-1} -test expr-36.86 {expr edge cases} { +test expr-36.86 {expr edge cases} {wideIs64bit} { expr {2 % ($min + 1)} } {-9223372036854775805} -test expr-36.87 {expr edge cases} { +test expr-36.87 {expr edge cases} {wideIs64bit} { expr {3 / $min} } {-1} -test expr-36.88 {expr edge cases} { +test expr-36.88 {expr edge cases} {wideIs64bit} { expr {3 % $min} } {-9223372036854775805} -test expr-36.89 {expr edge cases} { +test expr-36.89 {expr edge cases} {wideIs64bit} { expr {3 / ($min + 1)} } {-1} -test expr-36.90 {expr edge cases} { +test expr-36.90 {expr edge cases} {wideIs64bit} { expr {3 % ($min + 1)} } {-9223372036854775804} -test expr-37.1 {expr edge cases} { +test expr-37.1 {expr edge cases} {wideIs64bit} { set dividend $max set divisor 2 set q [expr {$dividend / $divisor}] set r [expr {$dividend % $divisor}] list $q * $divisor + $r = [expr {($divisor * $q) + $r}] } {4611686018427387903 * 2 + 1 = 9223372036854775807} -test expr-37.2 {expr edge cases} { +test expr-37.2 {expr edge cases} {wideIs64bit} { set dividend [expr {$max - 1}] set divisor 2 set q [expr {$dividend / $divisor}] set r [expr {$dividend % $divisor}] list $q * $divisor + $r = [expr {($q * $divisor) + $r}] } {4611686018427387903 * 2 + 0 = 9223372036854775806} -test expr-37.3 {expr edge cases} { +test expr-37.3 {expr edge cases} {wideIs64bit} { set dividend [expr {$max - 2}] set divisor 2 set q [expr {$dividend / $divisor}] set r [expr {$dividend % $divisor}] list $q * $divisor + $r = [expr {($q * $divisor) + $r}] } {4611686018427387902 * 2 + 1 = 9223372036854775805} -test expr-37.4 {expr edge cases} { +test expr-37.4 {expr edge cases} {wideIs64bit} { set dividend $max set divisor 3 set q [expr {$dividend / $divisor}] set r [expr {$dividend % $divisor}] list $q * $divisor + $r = [expr {($q * $divisor) + $r}] } {3074457345618258602 * 3 + 1 = 9223372036854775807} -test expr-37.5 {expr edge cases} { +test expr-37.5 {expr edge cases} {wideIs64bit} { set dividend [expr {$max - 1}] set divisor 3 set q [expr {$dividend / $divisor}] set r [expr {$dividend % $divisor}] list $q * $divisor + $r = [expr {($q * $divisor) + $r}] } {3074457345618258602 * 3 + 0 = 9223372036854775806} -test expr-37.6 {expr edge cases} { +test expr-37.6 {expr edge cases} {wideIs64bit} { set dividend [expr {$max - 2}] set divisor 3 set q [expr {$dividend / $divisor}] set r [expr {$dividend % $divisor}] list $q * $divisor + $r = [expr {($q * $divisor) + $r}] } {3074457345618258601 * 3 + 2 = 9223372036854775805} -test expr-37.7 {expr edge cases} { +test expr-37.7 {expr edge cases} {wideIs64bit} { set dividend $min set divisor 2 set q [expr {$dividend / $divisor}] set r [expr {$dividend % $divisor}] list $q * $divisor + $r = [expr {($q * $divisor) + $r}] } {-4611686018427387904 * 2 + 0 = -9223372036854775808} -test expr-37.8 {expr edge cases} { +test expr-37.8 {expr edge cases} {wideIs64bit} { set dividend [expr {$min + 1}] set divisor 2 set q [expr {$dividend / $divisor}] set r [expr {$dividend % $divisor}] list $q * $divisor + $r = [expr {($q * $divisor) + $r}] } {-4611686018427387904 * 2 + 1 = -9223372036854775807} -test expr-37.9 {expr edge cases} { +test expr-37.9 {expr edge cases} {wideIs64bit} { set dividend [expr {$min + 2}] set divisor 2 set q [expr {$dividend / $divisor}] set r [expr {$dividend % $divisor}] list $q * $divisor + $r = [expr {($q * $divisor) + $r}] } {-4611686018427387903 * 2 + 0 = -9223372036854775806} -test expr-37.10 {expr edge cases} { +test expr-37.10 {expr edge cases} {wideIs64bit} { # Multiplication overflows 64 bit type here, # so when the 1 is added it overflows # again and we end up back at min. @@ -6609,28 +6615,28 @@ test expr-37.10 {expr edge cases} { set r [expr {$dividend % $divisor}] list $q * $divisor + $r = [expr {($q * $divisor) + $r}] } {-3074457345618258603 * 3 + 1 = -9223372036854775808} -test expr-37.11 {expr edge cases} { +test expr-37.11 {expr edge cases} {wideIs64bit} { set dividend $min set divisor -3 set q [expr {$dividend / $divisor}] set r [expr {$dividend % $divisor}] list $q * $divisor + $r = [expr {($q * $divisor) + $r}] } {3074457345618258602 * -3 + -2 = -9223372036854775808} -test expr-37.12 {expr edge cases} { +test expr-37.12 {expr edge cases} {wideIs64bit} { set dividend $min set divisor $min set q [expr {$dividend / $divisor}] set r [expr {$dividend % $divisor}] list $q * $divisor + $r = [expr {($q * $divisor) + $r}] } {1 * -9223372036854775808 + 0 = -9223372036854775808} -test expr-37.13 {expr edge cases} { +test expr-37.13 {expr edge cases} {wideIs64bit} { set dividend $min set divisor [expr {$min + 1}] set q [expr {$dividend / $divisor}] set r [expr {$dividend % $divisor}] list $q * $divisor + $r = [expr {($q * $divisor) + $r}] } {1 * -9223372036854775807 + -1 = -9223372036854775808} -test expr-37.14 {expr edge cases} { +test expr-37.14 {expr edge cases} {wideIs64bit} { set dividend $min set divisor [expr {$min + 2}] set q [expr {$dividend / $divisor}] @@ -6638,7 +6644,7 @@ test expr-37.14 {expr edge cases} { list $q * $divisor + $r = [expr {($q * $divisor) + $r}] } {1 * -9223372036854775806 + -2 = -9223372036854775808} -test expr-38.1 {abs of smallest 32-bit integer [Bug 1241572]} { +test expr-38.1 {abs of smallest 32-bit integer [Bug 1241572]} {wideIs64bit} { expr {abs(-2147483648)} } 2147483648 test expr-38.2 {abs and -0 [Bug 1893815]} { diff --git a/tests/format.test b/tests/format.test index ff85cb2..cdea545 100644 --- a/tests/format.test +++ b/tests/format.test @@ -18,6 +18,9 @@ if {[lsearch [namespace children] ::tcltest] == -1} { # %u output depends on word length, so this test is not portable. testConstraint longIs32bit [expr {int(0x80000000) < 0}] testConstraint longIs64bit [expr {int(0x8000000000000000) < 0}] +testConstraint wideIs64bit \ + [expr {(wide(0x80000000) > 0) && (wide(0x8000000000000000) < 0)}] +testConstraint wideBiggerThanInt [expr {wide(0x80000000) != int(0x80000000)}] testConstraint pointerIs64bit [expr {$tcl_platform(pointerSize) >= 8}] test format-1.1 {integer formatting} { @@ -544,13 +547,13 @@ for {set i 290} {$i < 400} {incr i} { append b "x" } -test format-17.1 {testing %d with wide} { +test format-17.1 {testing %d with wide} {wideIs64bit wideBiggerThanInt} { format %d 7810179016327718216 -} 7810179016327718216 -test format-17.2 {testing %ld with wide} { +} 1819043144 +test format-17.2 {testing %ld with wide} {wideIs64bit} { format %ld 7810179016327718216 } 7810179016327718216 -test format-17.3 {testing %ld with non-wide} { +test format-17.3 {testing %ld with non-wide} {wideIs64bit} { format %ld 42 } 42 test format-17.4 {testing %l with non-integer} { @@ -577,11 +580,11 @@ test format-18.1 {do not demote existing numeric values} { format %08x $b lappend result [expr {$a == $b}] } {1 1 1 1} -test format-18.2 {do not demote existing numeric values} { +test format-18.2 {do not demote existing numeric values} {wideBiggerThanInt} { set a [expr {0xaaaaaaaaaa + 1}] set b 0xaaaaaaaaab list [format %08x $a] [expr {$a == $b}] -} {aaaaaaaaab 1} +} {aaaaaaab 1} test format-19.1 {regression test - tcl-core message by Brian Griffin on 26 0ctober 2004} -body { set x 0x8fedc654 diff --git a/tests/obj.test b/tests/obj.test index 41b1428..ffd1a59 100644 --- a/tests/obj.test +++ b/tests/obj.test @@ -20,6 +20,8 @@ if {[lsearch [namespace children] ::tcltest] == -1} { catch [list package require -exact Tcltest [info patchlevel]] testConstraint testobj [llength [info commands testobj]] +testConstraint longIs32bit [expr {int(0x80000000) < 0}] +testConstraint wideBiggerThanInt [expr {wide(0x80000000) != int(0x80000000)}] test obj-1.1 {Tcl_AppendAllObjTypes, and InitTypeTable, Tcl_RegisterObjType} testobj { set r 1 @@ -547,34 +549,34 @@ test obj-32.1 {freeing very large object trees} { unset x } {} -test obj-33.1 {integer overflow on input} { +test obj-33.1 {integer overflow on input} {longIs32bit wideBiggerThanInt} { set x 0x8000; append x 0000 list [string is integer $x] [expr { wide($x) }] } {1 2147483648} -test obj-33.2 {integer overflow on input} { +test obj-33.2 {integer overflow on input} {longIs32bit wideBiggerThanInt} { set x 0xffff; append x ffff list [string is integer $x] [expr { wide($x) }] } {1 4294967295} test obj-33.3 {integer overflow on input} { - set x 0x10000; append x 0000 - list [string is integer $x] [expr { wide($x) }] -} {1 4294967296} -test obj-33.4 {integer overflow on input} { + set x 0x100000000; append x 00000000 + list [string is integer $x] [expr { $x }] +} {0 18446744073709551616} +test obj-33.4 {integer overflow on input} {longIs32bit wideBiggerThanInt} { set x -0x8000; append x 0000 list [string is integer $x] [expr { wide($x) }] } {1 -2147483648} -test obj-33.5 {integer overflow on input} { +test obj-33.5 {integer overflow on input} {longIs32bit wideBiggerThanInt} { set x -0x8000; append x 0001 list [string is integer $x] [expr { wide($x) }] } {1 -2147483649} -test obj-33.6 {integer overflow on input} { +test obj-33.6 {integer overflow on input} {longIs32bit wideBiggerThanInt} { set x -0xffff; append x ffff list [string is integer $x] [expr { wide($x) }] } {1 -4294967295} test obj-33.7 {integer overflow on input} { - set x -0x10000; append x 0000 - list [string is integer $x] [expr { wide($x) }] -} {1 -4294967296} + set x -0x100000000; append x 00000000 + list [string is integer $x] [expr { $x }] +} {0 -18446744073709551616} test obj-34.1 {mp_iseven} testobj { set result "" diff --git a/tests/scan.test b/tests/scan.test index 0b7b14a..1f32b9f 100644 --- a/tests/scan.test +++ b/tests/scan.test @@ -85,6 +85,8 @@ proc testIEEE {} { } testConstraint ieeeFloatingPoint [testIEEE] +testConstraint wideIs64bit \ + [expr {(wide(0x80000000) > 0) && (wide(0x8000000000000000) < 0)}] test scan-1.1 {BuildCharSet, CharInSet} { list [scan foo {%[^o]} x] $x @@ -519,7 +521,7 @@ test scan-5.11 {integer scanning} -constraints {nonPortable} -setup { list [scan "4294967280 4294967280" "%u %d" a b] $a \ [expr {$b == -16 || $b == 0x7fffffff}] } -result {2 4294967280 1} -test scan-5.12 {integer scanning} -setup { +test scan-5.12 {integer scanning} -constraints {wideIs64bit} -setup { set a {}; set b {}; set c {} } -body { list [scan "7810179016327718216,6c63546f6c6c6548,661432506755433062510" \ -- cgit v0.12 From aed158b5189a8d32312907d0c388e7ae9826f92f Mon Sep 17 00:00:00 2001 From: sebres Date: Fri, 17 Aug 2018 18:26:10 +0000 Subject: win: TclpCreateProcess or [exec process ...] - search for application extended with ".cmd" extension: automatically tries appending ".com", ".exe", ".bat" and ".cmd", in that order, to the name, looking for an executable. (partially cherry-picked from 8.6 branch) --- win/tclWinPipe.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/win/tclWinPipe.c b/win/tclWinPipe.c index b5f035db..e0d8c63 100644 --- a/win/tclWinPipe.c +++ b/win/tclWinPipe.c @@ -900,7 +900,7 @@ TclpGetPid( * * The complete Windows search path is searched to find the specified * executable. If an executable by the given name is not found, - * automatically tries appending ".com", ".exe", and ".bat" to the + * automatically tries appending ".com", ".exe", ".bat" and ".cmd" to the * executable name. * * Results: @@ -1369,11 +1369,11 @@ ApplicationType( Tcl_DString nameBuf, ds; const TCHAR *nativeName; WCHAR nativeFullPath[MAX_PATH]; - static const char extensions[][5] = {"", ".com", ".exe", ".bat"}; + static const char extensions[][5] = {"", ".com", ".exe", ".bat", ".cmd"}; /* * Look for the program as an external program. First try the name as it - * is, then try adding .com, .exe, and .bat, in that order, to the name, + * is, then try adding .com, .exe, .bat and .cmd, in that order, to the name, * looking for an executable. * * Using the raw SearchPath() function doesn't do quite what is necessary. @@ -1414,7 +1414,8 @@ ApplicationType( Tcl_DStringFree(&ds); ext = strrchr(fullName, '.'); - if ((ext != NULL) && (strcasecmp(ext, ".bat") == 0)) { + if ((ext != NULL) && + (strcasecmp(ext, ".cmd") == 0 || strcasecmp(ext, ".bat") == 0)) { applType = APPL_DOS; break; } -- cgit v0.12 From 90afac281e7c26675e3a6816937db7794f49ceef Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Fri, 17 Aug 2018 22:15:49 +0000 Subject: Minor fix to entier(): Allow it to convert to "wideInt" as well when range is appropriate --- generic/tclBasic.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/generic/tclBasic.c b/generic/tclBasic.c index 07f7e5c..e014b06 100644 --- a/generic/tclBasic.c +++ b/generic/tclBasic.c @@ -7606,7 +7606,19 @@ ExprEntierFunc( if (type == TCL_NUMBER_DOUBLE) { d = *((const double *) ptr); - if ((d >= (double)LONG_MAX) || (d <= (double)LONG_MIN)) { + if ((d < (double)LONG_MAX) && (d > (double)LONG_MIN)) { + long result = (long) d; + + Tcl_SetObjResult(interp, Tcl_NewLongObj(result)); + return TCL_OK; +#ifndef TCL_WIDE_INT_IS_LONG + } else if ((d < (double)LLONG_MAX) && (d > (double)LLONG_MIN)) { + Tcl_WideInt result = (Tcl_WideInt) d; + + Tcl_SetObjResult(interp, Tcl_NewWideIntObj(result)); + return TCL_OK; +#endif + } else { mp_int big; if (Tcl_InitBignumFromDouble(interp, d, &big) != TCL_OK) { @@ -7615,11 +7627,6 @@ ExprEntierFunc( } Tcl_SetObjResult(interp, Tcl_NewBignumObj(&big)); return TCL_OK; - } else { - long result = (long) d; - - Tcl_SetObjResult(interp, Tcl_NewLongObj(result)); - return TCL_OK; } } -- cgit v0.12 From b3fc99501ec94bdc4c05736825c08a050cf8046d Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Sun, 19 Aug 2018 09:13:16 +0000 Subject: Still WIP. All test-cases pass now in 32-bit --- generic/tclInt.h | 7 ++-- generic/tclScan.c | 27 ++++----------- generic/tclStringObj.c | 91 +++++++++++--------------------------------------- tests/get.test | 12 +++---- tests/platform.test | 2 +- 5 files changed, 38 insertions(+), 101 deletions(-) diff --git a/generic/tclInt.h b/generic/tclInt.h index c1e24f5..3fb042e 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -2705,8 +2705,11 @@ typedef struct ProcessGlobalValue { *---------------------------------------------------------------------- */ -#define TCL_NUMBER_LONG 1 -#define TCL_NUMBER_WIDE 2 +#define TCL_NUMBER_INT 2 +#if TCL_MAJOR_VERSION < 9 +# define TCL_NUMBER_LONG 1 /* deprecated, not used any more */ +# define TCL_NUMBER_WIDE TCL_NUMBER_INT /* deprecated */ +#endif #define TCL_NUMBER_BIG 3 #define TCL_NUMBER_DOUBLE 4 #define TCL_NUMBER_NAN 5 diff --git a/generic/tclScan.c b/generic/tclScan.c index 0e3da17..458dbd8 100644 --- a/generic/tclScan.c +++ b/generic/tclScan.c @@ -571,11 +571,10 @@ Tcl_ScanObjCmd( const char *format; int numVars, nconversions, totalVars = -1; int objIndex, offset, i, result, code; - long value; + Tcl_WideInt value; const char *string, *end, *baseString; char op = 0; int width, underflow = 0; - Tcl_WideInt wideValue; Tcl_UniChar ch = 0, sch = 0; Tcl_Obj **objs = NULL, *objPtr = NULL; int flags; @@ -924,21 +923,7 @@ Tcl_ScanObjCmd( Tcl_DecrRefCount(objPtr); break; } - if (flags & SCAN_LONGER) { - if (Tcl_GetWideIntFromObj(NULL, objPtr, &wideValue) != TCL_OK) { - wideValue = LLONG_MAX; - if (TclGetString(objPtr)[0] == '-') { - wideValue = LLONG_MIN; - } - } - if ((flags & SCAN_UNSIGNED) && (wideValue < 0)) { - sprintf(buf, "%" TCL_LL_MODIFIER "u", - (Tcl_WideUInt)wideValue); - Tcl_SetStringObj(objPtr, buf, -1); - } else { - TclSetIntObj(objPtr, wideValue); - } - } else if (flags & SCAN_BIG) { + if (flags & SCAN_BIG) { if (flags & SCAN_UNSIGNED) { mp_int big; int code = Tcl_GetBignumFromObj(interp, objPtr, &big); @@ -963,15 +948,15 @@ Tcl_ScanObjCmd( } } } else { - if (TclGetLongFromObj(NULL, objPtr, &value) != TCL_OK) { + if (TclGetWideIntFromObj(NULL, objPtr, &value) != TCL_OK) { if (TclGetString(objPtr)[0] == '-') { - value = LONG_MIN; + value = LLONG_MIN; } else { - value = LONG_MAX; + value = LLONG_MAX; } } if ((flags & SCAN_UNSIGNED) && (value < 0)) { - sprintf(buf, "%lu", value); /* INTL: ISO digit */ + sprintf(buf, "%" TCL_LL_MODIFIER "u", value); /* INTL: ISO digit */ Tcl_SetStringObj(objPtr, buf, -1); } else { TclSetIntObj(objPtr, value); diff --git a/generic/tclStringObj.c b/generic/tclStringObj.c index c103bea..9eaabea 100644 --- a/generic/tclStringObj.c +++ b/generic/tclStringObj.c @@ -1817,9 +1817,6 @@ Tcl_AppendFormatToObj( char *end; int gotMinus = 0, gotHash = 0, gotZero = 0, gotSpace = 0, gotPlus = 0; int width, gotPrecision, precision, sawFlag, useShort = 0, useBig = 0; -#ifndef TCL_WIDE_INT_IS_LONG - int useWide = 0; -#endif int newXpg, numChars, allocSegment = 0, segmentLimit, segmentNumBytes; Tcl_Obj *segment; int step = TclUtfToUniChar(format, &ch); @@ -2010,18 +2007,11 @@ Tcl_AppendFormatToObj( useBig = 1; format += step; step = TclUtfToUniChar(format, &ch); -#ifndef TCL_WIDE_INT_IS_LONG - } else { - useWide = 1; -#endif } } else if (ch == 'I') { if ((format[1] == '6') && (format[2] == '4')) { format += (step + 2); step = TclUtfToUniChar(format, &ch); -#ifndef TCL_WIDE_INT_IS_LONG - useWide = 1; -#endif } else if ((format[1] == '3') && (format[2] == '2')) { format += (step + 2); step = TclUtfToUniChar(format, &ch); @@ -2091,16 +2081,10 @@ Tcl_AppendFormatToObj( case 'b': { short s = 0; /* Silence compiler warning; only defined and * used when useShort is true. */ - long l; Tcl_WideInt w; mp_int big; int toAppend, isNegative = 0; -#ifndef TCL_WIDE_INT_IS_LONG - if (ch == 'p') { - useWide = 1; - } -#endif if (useBig) { int cmpResult; if (Tcl_GetBignumFromObj(interp, segment, &big) != TCL_OK) { @@ -2119,53 +2103,32 @@ Tcl_AppendFormatToObj( ch = 'd'; } } -#ifndef TCL_WIDE_INT_IS_LONG - } else if (useWide) { - if (TclGetWideIntFromObj(NULL, segment, &w) != TCL_OK) { - Tcl_Obj *objPtr; + } else if (TclGetWideIntFromObj(NULL, segment, &w) != TCL_OK) { + Tcl_Obj *objPtr; - if (Tcl_GetBignumFromObj(interp,segment,&big) != TCL_OK) { - goto error; - } - mp_mod_2d(&big, (int) CHAR_BIT*sizeof(Tcl_WideInt), &big); - objPtr = Tcl_NewBignumObj(&big); - Tcl_IncrRefCount(objPtr); - TclGetWideIntFromObj(NULL, objPtr, &w); - Tcl_DecrRefCount(objPtr); - } - isNegative = (w < (Tcl_WideInt) 0); - if (w == (Tcl_WideInt) 0) gotHash = 0; -#endif - } else if (TclGetLongFromObj(NULL, segment, &l) != TCL_OK) { - if (TclGetWideIntFromObj(NULL, segment, &w) != TCL_OK) { - Tcl_Obj *objPtr; - - if (Tcl_GetBignumFromObj(interp,segment,&big) != TCL_OK) { - goto error; - } - mp_mod_2d(&big, (int) CHAR_BIT * sizeof(long), &big); - objPtr = Tcl_NewBignumObj(&big); - Tcl_IncrRefCount(objPtr); - TclGetLongFromObj(NULL, objPtr, &l); - Tcl_DecrRefCount(objPtr); - } else { - l = Tcl_WideAsLong(w); + if (Tcl_GetBignumFromObj(interp,segment,&big) != TCL_OK) { + goto error; } + mp_mod_2d(&big, (int) CHAR_BIT * sizeof(long), &big); + objPtr = Tcl_NewBignumObj(&big); + Tcl_IncrRefCount(objPtr); + TclGetWideIntFromObj(NULL, objPtr, &w); + Tcl_DecrRefCount(objPtr); if (useShort) { - s = (short) l; + s = (short) w; isNegative = (s < (short) 0); if (s == (short) 0) gotHash = 0; } else { - isNegative = (l < (long) 0); - if (l == (long) 0) gotHash = 0; + isNegative = (w < (long) 0); + if (w == (long) 0) gotHash = 0; } } else if (useShort) { - s = (short) l; + s = (short) w; isNegative = (s < (short) 0); if (s == (short) 0) gotHash = 0; } else { - isNegative = (l < (long) 0); - if (l == (long) 0) gotHash = 0; + isNegative = (w < (Tcl_WideInt) 0); + if (w == (Tcl_WideInt) 0) gotHash = 0; } segment = Tcl_NewObj(); @@ -2214,14 +2177,10 @@ Tcl_AppendFormatToObj( if (useShort) { pure = Tcl_NewIntObj((int) s); -#ifndef TCL_WIDE_INT_IS_LONG - } else if (useWide) { - pure = Tcl_NewWideIntObj(w); -#endif } else if (useBig) { pure = Tcl_NewBignumObj(&big); } else { - pure = Tcl_NewLongObj(l); + pure = Tcl_NewWideIntObj(w); } Tcl_IncrRefCount(pure); bytes = TclGetStringFromObj(pure, &length); @@ -2301,16 +2260,6 @@ Tcl_AppendFormatToObj( numDigits++; us /= base; } -#ifndef TCL_WIDE_INT_IS_LONG - } else if (useWide) { - Tcl_WideUInt uw = (Tcl_WideUInt) w; - - bits = uw; - while (uw) { - numDigits++; - uw /= base; - } -#endif } else if (useBig && big.used) { int leftover = (big.used * DIGIT_BIT) % numBits; mp_digit mask = (~(mp_digit)0) << (DIGIT_BIT-leftover); @@ -2327,12 +2276,12 @@ Tcl_AppendFormatToObj( goto errorMsg; } } else if (!useBig) { - unsigned long ul = (unsigned long) l; + Tcl_WideUInt uw = (Tcl_WideUInt) w; - bits = (Tcl_WideUInt) ul; - while (ul) { + bits = (Tcl_WideUInt) uw; + while (uw) { numDigits++; - ul /= base; + uw /= base; } } diff --git a/tests/get.test b/tests/get.test index d6a7206..b02b686 100644 --- a/tests/get.test +++ b/tests/get.test @@ -45,14 +45,14 @@ test get-1.7 {Tcl_GetInt procedure} {testgetint longIs64bit} { list [catch {testgetint 44 18446744073709551616} msg] $msg $errorCode } {1 {integer value too large to represent} {ARITH IOVERFLOW {integer value too large to represent}}} test get-1.8 {Tcl_GetInt procedure} {testgetint longIs64bit} { - list [catch {testgetint 18446744073709551614} msg] $msg -} {0 -2} + list [catch {testgetint 18446744073709551614} msg] $msg $errorCode +} {1 {integer value too large to represent} {ARITH IOVERFLOW {integer value too large to represent}}} test get-1.9 {Tcl_GetInt procedure} {testgetint longIs64bit} { - list [catch {testgetint +18446744073709551614} msg] $msg -} {0 -2} + list [catch {testgetint +18446744073709551614} msg] $msg $errorCode +} {1 {integer value too large to represent} {ARITH IOVERFLOW {integer value too large to represent}}} test get-1.10 {Tcl_GetInt procedure} {testgetint longIs64bit} { - list [catch {testgetint -18446744073709551614} msg] $msg -} {0 2} + list [catch {testgetint -18446744073709551614} msg] $msg $errorCode +} {1 {integer value too large to represent} {ARITH IOVERFLOW {integer value too large to represent}}} test get-1.11 {Tcl_GetInt procedure} {testgetint longIs32bit} { list [catch {testgetint 44 4294967296} msg] $msg $errorCode } {1 {integer value too large to represent} {ARITH IOVERFLOW {integer value too large to represent}}} diff --git a/tests/platform.test b/tests/platform.test index fa533e8..83848e8 100644 --- a/tests/platform.test +++ b/tests/platform.test @@ -43,7 +43,7 @@ test platform-1.1 {TclpSetVariables: tcl_platform} { # everything these days. Note that this does *not* use wide(), and # this is intentional since that could make Tcl's numbers wider than # the machine-integer on some platforms... -test platform-2.1 {tcl_platform(wordSize) indicates size of native word} { +test platform-2.1 {tcl_platform(wordSize) indicates size of native word} nonPortable { set result [expr {int(1 << (8 * $tcl_platform(wordSize) - 1))}] # Result must be the largest bit in a machine word, which this checks # without assuming how wide the word really is -- cgit v0.12 From 26b477b907a50ee208b80c65849b93a8dcfea948 Mon Sep 17 00:00:00 2001 From: sebres Date: Mon, 20 Aug 2018 14:35:44 +0000 Subject: win: fixes [21b0629c81] - exec/open process pipe under windows (0-day vulnerability - insufficient escape) --- tests/winPipe.test | 8 +++--- win/tclWinPipe.c | 77 ++++++++++++++++++++++++++++++------------------------ 2 files changed, 47 insertions(+), 38 deletions(-) diff --git a/tests/winPipe.test b/tests/winPipe.test index f993e0c..c5d3846 100644 --- a/tests/winPipe.test +++ b/tests/winPipe.test @@ -323,22 +323,22 @@ test winpipe-7.2 {BuildCommandLine: null arguments} {win exec} { } {foo "" bar} test winpipe-7.3 {BuildCommandLine: dbl quote quoting #1} {win exec} { exec $env(COMSPEC) /c echo foo "\"" bar -} {foo \" bar} +} {foo "\"" bar} test winpipe-7.4 {BuildCommandLine: dbl quote quoting #2} {win exec} { exec $env(COMSPEC) /c echo foo {""} bar -} {foo \"\" bar} +} {foo "\"\"" bar} test winpipe-7.5 {BuildCommandLine: dbl quote quoting #3} {win exec} { exec $env(COMSPEC) /c echo foo "\" " bar } {foo "\" " bar} test winpipe-7.6 {BuildCommandLine: dbl quote quoting #4} {win exec} { exec $env(COMSPEC) /c echo foo {a="b"} bar -} {foo a=\"b\" bar} +} {foo "a=\"b\"" bar} test winpipe-7.7 {BuildCommandLine: dbl quote quoting #5} {win exec} { exec $env(COMSPEC) /c echo foo {a = "b"} bar } {foo "a = \"b\"" bar} test winpipe-7.8 {BuildCommandLine: dbl quote quoting #6} {win exec} { exec $env(COMSPEC) /c echo {"hello"} {""hello""} {"""hello"""} {"\"hello\""} {he llo} "he \" llo" -} {\"hello\" \"\"hello\"\" \"\"\"hello\"\"\" \"\\\"hello\\\"\" "he llo" "he \" llo"} +} {"\"hello\"" "\"\"hello\"\"" "\"\"\"hello\"\"\"" "\"\\\"hello\\\"\"" "he llo" "he \" llo"} test winpipe-7.9 {BuildCommandLine: N backslashes followed a quote rule #1} {win exec} { exec $env(COMSPEC) /c echo foo \\ bar } {foo \ bar} diff --git a/win/tclWinPipe.c b/win/tclWinPipe.c index e0d8c63..496e35b 100644 --- a/win/tclWinPipe.c +++ b/win/tclWinPipe.c @@ -1540,6 +1540,8 @@ BuildCommandLine( int quote, i; Tcl_DString ds; + const static char *specMetaChars = "&|^<>!%()"; + Tcl_DStringInit(&ds); /* @@ -1567,52 +1569,59 @@ BuildCommandLine( Tcl_UniChar ch; for (start = arg; *start != '\0'; start += count) { count = Tcl_UtfToUniChar(start, &ch); - if (Tcl_UniCharIsSpace(ch)) { /* INTL: ISO space. */ + if (Tcl_UniCharIsSpace(ch) || + (count == 1 && (*start=='"' || strchr(specMetaChars, *start))) + ) { + /* must be quoted */ quote = 1; break; } } } - if (quote) { + if (!quote) { + Tcl_DStringAppend(&ds, arg, -1); + } else { Tcl_DStringAppend(&ds, "\"", 1); - } - start = arg; - for (special = arg; ; ) { - if ((*special == '\\') && (special[1] == '\\' || - special[1] == '"' || (quote && special[1] == '\0'))) { - Tcl_DStringAppend(&ds, start, (int) (special - start)); - start = special; - while (1) { - special++; - if (*special == '"' || (quote && *special == '\0')) { - /* - * N backslashes followed a quote -> insert N * 2 + 1 - * backslashes then a quote. - */ - - Tcl_DStringAppend(&ds, start, - (int) (special - start)); - break; + start = arg; + for (special = arg; *special != '\0'; ) { + if (*special == '\\' && (special[1] == '\\' || special[1] == '"' || special[1] == '\0')) { + if (special > start) { + Tcl_DStringAppend(&ds, start, (int) (special - start)); } - if (*special != '\\') { - break; + Tcl_DStringAppend(&ds, "\\\\", 2); + start = ++special; + continue; + } + if (*special == '"') { + quote ^= 2; /* observe unpaired quotes */ + if (special > start) { + Tcl_DStringAppend(&ds, start, (int) (special - start)); } + Tcl_DStringAppend(&ds, "\\\"", 2); + start = ++special; + continue; } - Tcl_DStringAppend(&ds, start, (int) (special - start)); - start = special; + /* unpaired (escaped) quote causes special handling on meta-chars */ + if ((quote & 2) && strchr(specMetaChars, *special)) { + if (special > start) { + Tcl_DStringAppend(&ds, start, (int) (special - start)); + } + /* unpaired - escape all special chars inside quotes "..." */ + Tcl_DStringAppend(&ds, "\"", 1); + start = special; + do { + special++; + } while(*special && strchr(specMetaChars, *special)); + Tcl_DStringAppend(&ds, start, (int) (special - start)); + Tcl_DStringAppend(&ds, "\"", 1); + start = special; + continue; + } + special++; } - if (*special == '"') { + if (special > start) { Tcl_DStringAppend(&ds, start, (int) (special - start)); - Tcl_DStringAppend(&ds, "\\\"", 2); - start = special + 1; } - if (*special == '\0') { - break; - } - special++; - } - Tcl_DStringAppend(&ds, start, (int) (special - start)); - if (quote) { Tcl_DStringAppend(&ds, "\"", 1); } } -- cgit v0.12 From d660b325b58998ff0627e899550abf58bf260174 Mon Sep 17 00:00:00 2001 From: sebres Date: Mon, 20 Aug 2018 16:15:37 +0000 Subject: small amend: avoid reset of unpaired quote flag between arguments (previous affects next) + test cases extended with several injection checks. --- tests/winPipe.test | 169 ++++++++++++++++++++++++++++++++++------------------- win/tclWinPipe.c | 25 +++++--- 2 files changed, 126 insertions(+), 68 deletions(-) diff --git a/tests/winPipe.test b/tests/winPipe.test index c5d3846..eb0a854 100644 --- a/tests/winPipe.test +++ b/tests/winPipe.test @@ -308,10 +308,35 @@ test winpipe-6.2 {PipeSetupProc & PipeCheckProc: write threads} \ lappend x [catch {close $f} msg] $msg } {writable timeout 0 {}} -set path(echoArgs.tcl) [makeFile { - puts "[list $argv0 $argv]" -} echoArgs.tcl] - +proc _testExecArgs {single args} { + variable path + set path(echoArgs.tcl) [makeFile { + puts "[list [file tail $argv0] {*}$argv]" + } echoArgs.tcl] + set path(echoArgs.bat) [makeFile "@[file native [interpreter]] $path(echoArgs.tcl) %*" echoArgs.bat] + set broken {} + foreach args $args { + if {$single} { + set args [list $args] + } + foreach cmd [list \ + [list [interpreter] $path(echoArgs.tcl)] \ + [list $path(echoArgs.bat)] \ + ] { + set e [list [file tail $path(echoArgs.tcl)] {*}$args] + tcltest::DebugPuts 4 " ## test exec [file extension [lindex $cmd 0]] for $e" + if {[catch { + exec {*}$cmd {*}$args + } r]} { + set r "ERROR: $r" + } + if {$r ne $e} { + append broken "\[ERROR\]: exec [file extension [lindex $cmd 0]] on $args\n -- result:\n$r\n -- expected:\n$e\n" + } + } + } + return $broken +} ### validate the raw output of BuildCommandLine(). ### @@ -370,65 +395,87 @@ test winpipe-7.18 {BuildCommandLine: special chars #5} {win exec} { exec $env(COMSPEC) /c echo foo \} bar } "foo \} bar" +set injectList { + {test"whoami} {test""whoami} + {test"""whoami} {test""""whoami} + + "test\"whoami\\" "test\"\"whoami\\" + "test\"\"\"whoami\\" "test\"\"\"\"whoami\\" + + {test\"&whoami} {test"\"&whoami} + {test""\"&whoami} {test"""\"&whoami} + + {test&whoami} {test|whoami} + {"test&whoami} {"test|whoami} + {test"&whoami} {test"|whoami} + {"test"&whoami} {"test"|whoami} + {""test"&whoami} {""test"|whoami} + + {test&echo "} {test|echo "} + {"test&echo "} {"test|echo "} + {test"&echo "} {test"|echo "} + {"test"&echo "} {"test"|echo "} + {""test"&echo "} {""test"|echo "} + + {test&echo ""} {test|echo ""} + {"test&echo ""} {"test|echo ""} + {test"&echo ""} {test"|echo ""} + {"test"&echo ""} {"test"|echo ""} + {""test"&echo ""} {""test"|echo ""} + + {test>whoami} {testwhoami} {"testwhoami} {test"whoami} {"test"whoami} {""test" start) { Tcl_DStringAppend(&ds, start, (int) (special - start)); } + /* escape using backslash */ Tcl_DStringAppend(&ds, "\\\\", 2); start = ++special; continue; } + /* ["] */ if (*special == '"') { - quote ^= 2; /* observe unpaired quotes */ + quote ^= 2; /* invert unpaired flag - observe unpaired quotes */ if (special > start) { Tcl_DStringAppend(&ds, start, (int) (special - start)); } + /* escape using backslash */ Tcl_DStringAppend(&ds, "\\\"", 2); start = ++special; continue; @@ -1606,7 +1615,7 @@ BuildCommandLine( if (special > start) { Tcl_DStringAppend(&ds, start, (int) (special - start)); } - /* unpaired - escape all special chars inside quotes "..." */ + /* unpaired - escape all special chars inside quotes like `"..."` */ Tcl_DStringAppend(&ds, "\"", 1); start = special; do { @@ -1619,9 +1628,11 @@ BuildCommandLine( } special++; } + /* rest of argument (don't contain special chars) */ if (special > start) { Tcl_DStringAppend(&ds, start, (int) (special - start)); } + /* end of argument (closed quote-char) */ Tcl_DStringAppend(&ds, "\"", 1); } } -- cgit v0.12 From 01dd016ad89794ac85bfc2a7ccbedbb6d4c7f14f Mon Sep 17 00:00:00 2001 From: sebres Date: Mon, 20 Aug 2018 19:58:44 +0000 Subject: because executable (1st argument) always proper escaped now, don't need to replace long path name of batch-executable with short path name (reduced to 16-bit applications only). --- tests/winPipe.test | 44 +++++++++++++++++++++++++++++++++----------- win/tclWinPipe.c | 2 +- 2 files changed, 34 insertions(+), 12 deletions(-) diff --git a/tests/winPipe.test b/tests/winPipe.test index eb0a854..e817e85 100644 --- a/tests/winPipe.test +++ b/tests/winPipe.test @@ -310,21 +310,33 @@ test winpipe-6.2 {PipeSetupProc & PipeCheckProc: write threads} \ proc _testExecArgs {single args} { variable path - set path(echoArgs.tcl) [makeFile { - puts "[list [file tail $argv0] {*}$argv]" - } echoArgs.tcl] - set path(echoArgs.bat) [makeFile "@[file native [interpreter]] $path(echoArgs.tcl) %*" echoArgs.bat] + if {![info exists path(echoArgs.tcl)] || ![file exists $path(echoArgs.tcl)]} { + set path(echoArgs.tcl) [makeFile { + puts "[list [file tail $argv0] {*}$argv]" + } echoArgs.tcl] + } + if {![info exists path(echoArgs.bat)] || ![file exists $path(echoArgs.bat)]} { + set path(echoArgs.bat) [makeFile "@[file native [interpreter]] $path(echoArgs.tcl) %*" "echoArgs.bat"] + } + set cmds [list [list [interpreter] $path(echoArgs.tcl)]] + if {!($single & 2)} { + lappend cmds [list $path(echoArgs.bat)] + } else { + if {![info exists path(echoArgs2.bat)] || ![file exists $path(echoArgs2.bat)]} { + file mkdir [file join [temporaryDirectory] test(Dir)Check] + set path(echoArgs2.bat) [makeFile "@[file native [interpreter]] $path(echoArgs.tcl) %*" \ + "test(Dir)Check/echo(Cmd)Test Args & Batch.bat"] + } + lappend cmds [list $path(echoArgs2.bat)] + } set broken {} foreach args $args { - if {$single} { + if {$single & 1} { set args [list $args] } - foreach cmd [list \ - [list [interpreter] $path(echoArgs.tcl)] \ - [list $path(echoArgs.bat)] \ - ] { + foreach cmd $cmds { set e [list [file tail $path(echoArgs.tcl)] {*}$args] - tcltest::DebugPuts 4 " ## test exec [file extension [lindex $cmd 0]] for $e" + tcltest::DebugPuts 4 " ## test exec [file extension [lindex $cmd 0]] ($cmd) for\n ## $args" if {[catch { exec {*}$cmd {*}$args } r]} { @@ -475,6 +487,15 @@ test winpipe-8.3 {BuildCommandLine/parse_cmdline pass-thru: check injection on s [list "START\"" {*}$injectList "\"END"] } -result {} +test winpipe-8.4 {BuildCommandLine/parse_cmdline pass-thru: check injection on special meta-chars (command/jointly args)} \ +-constraints {win exec} -body { + _testExecArgs 2 \ + [list START {*}$injectList END] \ + [list "START\"" {*}$injectList END] \ + [list START {*}$injectList "\"END"] \ + [list "START\"" {*}$injectList "\"END"] +} -result {} + rename _testExecArgs {} # restore old values for env(TMP) and env(TEMP) @@ -487,6 +508,7 @@ if {[catch {set env(TEMP) $env_temp}]} { } # cleanup -file delete big little stdout stderr nothing echoArgs.tcl +file delete big little stdout stderr nothing echoArgs.tcl echoArgs.bat +file delete -force [file join [temporaryDirectory] test(Dir)Check] ::tcltest::cleanupTests return diff --git a/win/tclWinPipe.c b/win/tclWinPipe.c index cdbf467..a6a8f22 100644 --- a/win/tclWinPipe.c +++ b/win/tclWinPipe.c @@ -1492,7 +1492,7 @@ ApplicationType( return APPL_NONE; } - if ((applType == APPL_DOS) || (applType == APPL_WIN3X)) { + if (applType == APPL_WIN3X) { /* * Replace long path name of executable with short path name for * 16-bit applications. Otherwise the application may not be able to -- cgit v0.12 From fb0bf9d1b9dbcac3d58bef9c86b6353eaf3d0c1e Mon Sep 17 00:00:00 2001 From: sebres Date: Tue, 21 Aug 2018 18:52:21 +0000 Subject: fixes escape for special cases (+ more test-cases): - `%` char to be escaped (quoted) in any case (regardless pairing flag), otherwise `%username%` will be interpolated as username. - escape of multiple backslashes before quote is different (as without following quote) in unpaired quote syntax (upaired flag set) --- tests/winPipe.test | 30 ++++++++++- win/tclWinPipe.c | 142 +++++++++++++++++++++++++++++++++++++++++------------ 2 files changed, 139 insertions(+), 33 deletions(-) diff --git a/tests/winPipe.test b/tests/winPipe.test index e817e85..c375d8f 100644 --- a/tests/winPipe.test +++ b/tests/winPipe.test @@ -332,7 +332,9 @@ proc _testExecArgs {single args} { set broken {} foreach args $args { if {$single & 1} { - set args [list $args] + # enclose single test-arg between 1st/3rd to be sure nothing is truncated + # (e. g. to cover unexpected trim by nts-zero case, and args don't recombined): + set args [list "1st" $args "3rd"] } foreach cmd $cmds { set e [list [file tail $path(echoArgs.tcl)] {*}$args] @@ -414,8 +416,15 @@ set injectList { "test\"whoami\\" "test\"\"whoami\\" "test\"\"\"whoami\\" "test\"\"\"\"whoami\\" + {test\\&\\test} {test"\\&\\test} + {"test\\&\\test} {"test"\\&\\"test"} + {test\\"&"\\test} {test"\\"&"\\test} + {"test\\"&"\\test} {"test"\\"&"\\"test"} + {test\"&whoami} {test"\"&whoami} {test""\"&whoami} {test"""\"&whoami} + {test\"\&whoami} {test"\"\&whoami} + {test""\"\&whoami} {test"""\"\&whoami} {test&whoami} {test|whoami} {"test&whoami} {"test|whoami} @@ -445,6 +454,25 @@ set injectList { {test^whoami} {test^^echo ^^^} {test"^whoami} {test"^^echo ^^^} {test"^echo ^^^"} {test""^echo" ^^^"} + + {test%USERDOMAIN%\%USERNAME%} + {test" %USERDOMAIN%\%USERNAME%} + {test%USERDOMAIN%\\%USERNAME%} + {test" %USERDOMAIN%\\%USERNAME%} + {test%USERDOMAIN%&%USERNAME%} + {test" %USERDOMAIN%&%USERNAME%} + {test%USERDOMAIN%\&\%USERNAME%} + {test" %USERDOMAIN%\&\%USERNAME%} + + {test%USERDOMAIN%\&\test} + {test" %USERDOMAIN%\&\test} + {test%USERDOMAIN%\\&\\test} + {test" %USERDOMAIN%\\&\\test} + + {test%USERDOMAIN%\&\"test} + {test" %USERDOMAIN%\&\"test} + {test%USERDOMAIN%\\&\\"test} + {test" %USERDOMAIN%\\&\\"test} } ### validate the pass-thru from BuildCommandLine() to the crt's parse_cmdline(). diff --git a/win/tclWinPipe.c b/win/tclWinPipe.c index a6a8f22..728e43a 100644 --- a/win/tclWinPipe.c +++ b/win/tclWinPipe.c @@ -1527,6 +1527,86 @@ ApplicationType( *---------------------------------------------------------------------- */ +static const char * +BuildCmdLineBypassBS( + const char *current, + const char **bspos +) { + /* mark first backslash possition */ + if (!*bspos) { + *bspos = current; + } + do { + current++; + } while (*current == '\\'); + return current; +} + +static void +QuoteCmdLineBackslash( + Tcl_DString *dsPtr, + const char *start, + const char *current, + const char *bspos +) { + if (!bspos) { + if (current > start) { /* part before current (special) */ + Tcl_DStringAppend(dsPtr, start, (int) (current - start)); + } + } else { + if (bspos > start) { /* part before first backslash */ + Tcl_DStringAppend(dsPtr, start, (int) (bspos - start)); + } + while (bspos++ < current) { /* each backslash twice */ + Tcl_DStringAppend(dsPtr, "\\\\", 2); + } + } +} + +static const char * +QuoteCmdLinePart( + Tcl_DString *dsPtr, + const char *start, + const char *special, + const char *specMetaChars, + const char **bspos +) { + if (!*bspos) { + /* rest before special (before quote) */ + QuoteCmdLineBackslash(dsPtr, start, special, NULL); + start = special; + } else { + /* rest before first backslash and backslashes into new quoted block */ + QuoteCmdLineBackslash(dsPtr, start, *bspos, NULL); + start = *bspos; + } + /* + * escape all special chars enclosed in quotes like `"..."`, note that here we + * don't must escape `\` (with `\`), because it's outside of the main quotes, + * so `\` remains `\`, but important - not at end of part, because results as + * before the quote, so `%\%\` should be escaped as `"%\%"\\`). + */ + Tcl_DStringAppend(dsPtr, "\"", 1); /* opening escape quote-char */ + do { + *bspos = NULL; + special++; + if (*special == '\\') { + /* bypass backslashes (and mark first backslash possition)*/ + special = BuildCmdLineBypassBS(special, bspos); + if (*special == '\0') break; + } + } while (*special && strchr(specMetaChars, *special)); + if (!*bspos) { + /* unescaped rest before quote */ + QuoteCmdLineBackslash(dsPtr, start, special, NULL); + } else { + /* unescaped rest before first backslash (rather belongs to the main block) */ + QuoteCmdLineBackslash(dsPtr, start, *bspos, NULL); + } + Tcl_DStringAppend(dsPtr, "\"", 1); /* closing escape quote-char */ + return special; +} + static void BuildCommandLine( const char *executable, /* Full path of executable (including @@ -1536,11 +1616,14 @@ BuildCommandLine( Tcl_DString *linePtr) /* Initialized Tcl_DString that receives the * command line (TCHAR). */ { - const char *arg, *start, *special; + const char *arg, *start, *special, *bspos; int quote = 0, i; Tcl_DString ds; - const static char *specMetaChars = "&|^<>!%()"; + /* characters to enclose in quotes if unpaired quote flag set */ + const static char *specMetaChars = "&|^<>!()%"; + /* characters to enclose in quotes in any case (regardless unpaired-flag) */ + const static char *specMetaChars2 = "%"; Tcl_DStringInit(&ds); @@ -1566,6 +1649,7 @@ BuildCommandLine( * 2 - previous arguments chain contains unpaired quote-char; */ quote &= ~1; /* reset escape flag */ + bspos = NULL; if (arg[0] == '\0') { quote = 1; } else { @@ -1585,26 +1669,22 @@ BuildCommandLine( /* nothing to escape */ Tcl_DStringAppend(&ds, arg, -1); } else { - /* start of argument (open quote-char) */ + /* start of argument (main opening quote-char) */ Tcl_DStringAppend(&ds, "\"", 1); start = arg; for (special = arg; *special != '\0'; ) { - /* `\\` or `\"` or `\` at end (so equal `\"` because quoted) */ - if (*special == '\\' && (special[1] == '\\' || special[1] == '"' || special[1] == '\0')) { - if (special > start) { - Tcl_DStringAppend(&ds, start, (int) (special - start)); - } - /* escape using backslash */ - Tcl_DStringAppend(&ds, "\\\\", 2); - start = ++special; - continue; + /* position of `\` is important before quote or at end (equal `\"` because quoted) */ + if (*special == '\\') { + /* bypass backslashes (and mark first backslash possition)*/ + special = BuildCmdLineBypassBS(special, &bspos); + if (*special == '\0') break; } /* ["] */ if (*special == '"') { quote ^= 2; /* invert unpaired flag - observe unpaired quotes */ - if (special > start) { - Tcl_DStringAppend(&ds, start, (int) (special - start)); - } + /* add part before (and escape backslashes before quote) */ + QuoteCmdLineBackslash(&ds, start, special, bspos); + bspos = NULL; /* escape using backslash */ Tcl_DStringAppend(&ds, "\\\"", 2); start = ++special; @@ -1612,27 +1692,25 @@ BuildCommandLine( } /* unpaired (escaped) quote causes special handling on meta-chars */ if ((quote & 2) && strchr(specMetaChars, *special)) { - if (special > start) { - Tcl_DStringAppend(&ds, start, (int) (special - start)); - } - /* unpaired - escape all special chars inside quotes like `"..."` */ - Tcl_DStringAppend(&ds, "\"", 1); - start = special; - do { - special++; - } while(*special && strchr(specMetaChars, *special)); - Tcl_DStringAppend(&ds, start, (int) (special - start)); - Tcl_DStringAppend(&ds, "\"", 1); - start = special; + special = QuoteCmdLinePart(&ds, start, special, specMetaChars, &bspos); + /* start to current or first backslash */ + start = !bspos ? special : bspos; continue; } + /* special case for % - should be enclosed always (paired also) */ + if (strchr(specMetaChars2, *special)) { + special = QuoteCmdLinePart(&ds, start, special, specMetaChars2, &bspos); + /* start to current or first backslash */ + start = !bspos ? special : bspos; + continue; + } + /* other not special (and not meta) character */ + bspos = NULL; /* reset last backslash possition (not interesting) */ special++; } - /* rest of argument (don't contain special chars) */ - if (special > start) { - Tcl_DStringAppend(&ds, start, (int) (special - start)); - } - /* end of argument (closed quote-char) */ + /* rest of argument (and escape backslashes before closing main quote) */ + QuoteCmdLineBackslash(&ds, start, special, bspos); + /* end of argument (main closing quote-char) */ Tcl_DStringAppend(&ds, "\"", 1); } } -- cgit v0.12 From 80d62f05475d6f7a0b3093a0ee583905d3b390c9 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Tue, 21 Aug 2018 21:36:03 +0000 Subject: improved reange checking (also for the Tcl 9.0 proposal). Make platform test platform 32/64-bit independant --- generic/tclBasic.c | 2 +- generic/tclInt.h | 4 ++-- generic/tclObj.c | 41 ++++++++++++++++++++++++++++++----------- generic/tclTest.c | 22 ++++++++++++++++++++++ tests/platform.test | 14 ++++---------- 5 files changed, 59 insertions(+), 24 deletions(-) diff --git a/generic/tclBasic.c b/generic/tclBasic.c index 699975e..0769f24 100644 --- a/generic/tclBasic.c +++ b/generic/tclBasic.c @@ -116,6 +116,7 @@ static Tcl_ObjCmdProc ExprCeilFunc; static Tcl_ObjCmdProc ExprDoubleFunc; static Tcl_ObjCmdProc ExprEntierFunc; static Tcl_ObjCmdProc ExprFloorFunc; +static Tcl_ObjCmdProc ExprIntFunc; static Tcl_ObjCmdProc ExprIsqrtFunc; static Tcl_ObjCmdProc ExprMaxFunc; static Tcl_ObjCmdProc ExprMinFunc; @@ -124,7 +125,6 @@ static Tcl_ObjCmdProc ExprRoundFunc; static Tcl_ObjCmdProc ExprSqrtFunc; static Tcl_ObjCmdProc ExprSrandFunc; static Tcl_ObjCmdProc ExprUnaryFunc; -static Tcl_ObjCmdProc ExprIntFunc; static void MathFuncWrongNumArgs(Tcl_Interp *interp, int expected, int actual, Tcl_Obj *const *objv); static Tcl_NRPostProc NRCoroutineCallerCallback; diff --git a/generic/tclInt.h b/generic/tclInt.h index 038fa88..928d649 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -2498,7 +2498,7 @@ typedef struct List { #define TclGetLongFromObj(interp, objPtr, longPtr) \ (((objPtr)->typePtr == &tclIntType \ && (objPtr)->internalRep.wideValue >= (Tcl_WideInt)(LONG_MIN) \ - && (objPtr)->internalRep.wideValue <= (Tcl_WideInt)(ULONG_MAX)) \ + && (objPtr)->internalRep.wideValue <= (Tcl_WideInt)(LONG_MAX)) \ ? ((*(longPtr) = (long)(objPtr)->internalRep.wideValue), TCL_OK) \ : Tcl_GetLongFromObj((interp), (objPtr), (longPtr))) #endif @@ -2506,7 +2506,7 @@ typedef struct List { #define TclGetIntFromObj(interp, objPtr, intPtr) \ (((objPtr)->typePtr == &tclIntType \ && (objPtr)->internalRep.wideValue >= (Tcl_WideInt)(INT_MIN) \ - && (objPtr)->internalRep.wideValue <= (Tcl_WideInt)(UINT_MAX)) \ + && (objPtr)->internalRep.wideValue <= (Tcl_WideInt)(INT_MAX)) \ ? ((*(intPtr) = (int)(objPtr)->internalRep.wideValue), TCL_OK) \ : Tcl_GetIntFromObj((interp), (objPtr), (intPtr))) #define TclGetIntForIndexM(interp, objPtr, endValue, idxPtr) \ diff --git a/generic/tclObj.c b/generic/tclObj.c index b1e4b29..3bbe7b6 100644 --- a/generic/tclObj.c +++ b/generic/tclObj.c @@ -2516,7 +2516,14 @@ Tcl_GetIntFromObj( if (TclGetLongFromObj(interp, objPtr, &l) != TCL_OK) { return TCL_ERROR; } - if ((ULONG_MAX > UINT_MAX) && ((l > (long)(UINT_MAX)) || (l < (long)(INT_MIN)))) { + if ( +#if !defined(TCL_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9 + (l > (long)(UINT_MAX)) +#else + (l > (long)(INT_MAX)) +#endif + || (l < (long)(INT_MIN)) + ) { if (interp != NULL) { const char *s = "integer value too large to represent as non-long integer"; @@ -2805,8 +2812,13 @@ Tcl_GetLongFromObj( Tcl_WideInt w = objPtr->internalRep.wideValue; - if (w >= (Tcl_WideInt)(LONG_MIN) - && w <= (Tcl_WideInt)(ULONG_MAX)) { + if ( +#if !defined(TCL_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9 + w <= (Tcl_WideInt)(ULONG_MAX)) { +#else + w <= (Tcl_WideInt)(LONG_MAX)) { +#endif + && w >= (Tcl_WideInt)(LONG_MIN) *longPtr = Tcl_WideAsLong(w); return TCL_OK; } @@ -2833,22 +2845,29 @@ Tcl_GetLongFromObj( mp_int big; UNPACK_BIGNUM(objPtr, big); - if ((size_t) big.used <= (CHAR_BIT * sizeof(long) + DIGIT_BIT - 1) + if ((size_t) big.used <= (CHAR_BIT * sizeof(unsigned long) + DIGIT_BIT - 1) / DIGIT_BIT) { - unsigned long value = 0, numBytes = sizeof(long); - long scratch; + unsigned long scratch, value = 0, numBytes = sizeof(unsigned long); unsigned char *bytes = (unsigned char *) &scratch; if (mp_to_unsigned_bin_n(&big, bytes, &numBytes) == MP_OKAY) { while (numBytes-- > 0) { value = (value << CHAR_BIT) | *bytes++; } - if (big.sign) { - *longPtr = - (long) value; - } else { - *longPtr = (long) value; + if ( +#if !defined(TCL_NO_DEPRECATED) && TCL_MAJOR_VERSION < 8 + big.sign ? (value <= 1 + (unsigned long)LONG_MAX) : (value <= (unsigned long)ULONG_MAX) +#else + big.sign ? (value <= 1 + (unsigned long)LONG_MAX) : (value <= (unsigned long)LONG_MAX) +#endif + ) { + if (big.sign) { + *longPtr = - (long) value; + } else { + *longPtr = (long) value; + } + return TCL_OK; } - return TCL_OK; } } #ifndef TCL_WIDE_INT_IS_LONG diff --git a/generic/tclTest.c b/generic/tclTest.c index ac01ecf..48b4761 100644 --- a/generic/tclTest.c +++ b/generic/tclTest.c @@ -293,6 +293,8 @@ static int TestgetassocdataCmd(ClientData dummy, Tcl_Interp *interp, int argc, const char **argv); static int TestgetintCmd(ClientData dummy, Tcl_Interp *interp, int argc, const char **argv); +static int TestlongsizeCmd(ClientData dummy, + Tcl_Interp *interp, int argc, const char **argv); static int TestgetplatformCmd(ClientData dummy, Tcl_Interp *interp, int argc, const char **argv); static int TestgetvarfullnameCmd( @@ -645,6 +647,8 @@ Tcltest_Init( NULL, NULL); Tcl_CreateCommand(interp, "testgetint", TestgetintCmd, NULL, NULL); + Tcl_CreateCommand(interp, "testlongsize", TestlongsizeCmd, + NULL, NULL); Tcl_CreateCommand(interp, "testgetplatform", TestgetplatformCmd, NULL, NULL); Tcl_CreateObjCommand(interp, "testgetvarfullname", @@ -6936,6 +6940,24 @@ TestgetintCmd( } } +/* + * Used for determining sizeof(long) at script level. + */ +static int +TestlongsizeCmd( + ClientData dummy, + Tcl_Interp *interp, + int argc, + const char **argv) +{ + if (argc != 1) { + Tcl_AppendResult(interp, "wrong # args", NULL); + return TCL_ERROR; + } + Tcl_SetObjResult(interp, Tcl_NewIntObj((int)sizeof(long))); + return TCL_OK; +} + static int NREUnwind_callback( ClientData data[], diff --git a/tests/platform.test b/tests/platform.test index 83848e8..5880fb9 100644 --- a/tests/platform.test +++ b/tests/platform.test @@ -25,6 +25,7 @@ namespace eval ::tcl::test::platform { catch [list package require -exact Tcltest [info patchlevel]] testConstraint testCPUID [llength [info commands testcpuid]] +testConstraint testlongsize [llength [info commands testlongsize]] test platform-1.0 {tcl_platform(engine)} { set tcl_platform(engine) @@ -39,16 +40,9 @@ test platform-1.1 {TclpSetVariables: tcl_platform} { set result } {byteOrder engine machine os osVersion pathSeparator platform pointerSize user wordSize} -# Test assumes twos-complement arithmetic, which is true of virtually -# everything these days. Note that this does *not* use wide(), and -# this is intentional since that could make Tcl's numbers wider than -# the machine-integer on some platforms... -test platform-2.1 {tcl_platform(wordSize) indicates size of native word} nonPortable { - set result [expr {int(1 << (8 * $tcl_platform(wordSize) - 1))}] - # Result must be the largest bit in a machine word, which this checks - # without assuming how wide the word really is - list [expr {$result < 0}] [expr {$result ^ int($result - 1)}] -} {1 -1} +test platform-2.1 {tcl_platform(wordSize) indicates size of native word} testlongsize { + expr {$tcl_platform(wordSize) == [testlongsize]} +} {1} # On Windows/UNIX, test that the CPU ID works -- cgit v0.12 From c2d61d8dbcee801a9eef8c388816573f3da4a92a Mon Sep 17 00:00:00 2001 From: sebres Date: Thu, 23 Aug 2018 08:00:32 +0000 Subject: code review, restored backwards compatibility of the simplest escape of quote-chars (so reverted several tests winpipe-7.x) --- tests/winPipe.test | 8 ++++---- win/tclWinPipe.c | 37 +++++++++++++++++++++++++------------ 2 files changed, 29 insertions(+), 16 deletions(-) diff --git a/tests/winPipe.test b/tests/winPipe.test index c375d8f..5c6eac8 100644 --- a/tests/winPipe.test +++ b/tests/winPipe.test @@ -362,22 +362,22 @@ test winpipe-7.2 {BuildCommandLine: null arguments} {win exec} { } {foo "" bar} test winpipe-7.3 {BuildCommandLine: dbl quote quoting #1} {win exec} { exec $env(COMSPEC) /c echo foo "\"" bar -} {foo "\"" bar} +} {foo \" bar} test winpipe-7.4 {BuildCommandLine: dbl quote quoting #2} {win exec} { exec $env(COMSPEC) /c echo foo {""} bar -} {foo "\"\"" bar} +} {foo \"\" bar} test winpipe-7.5 {BuildCommandLine: dbl quote quoting #3} {win exec} { exec $env(COMSPEC) /c echo foo "\" " bar } {foo "\" " bar} test winpipe-7.6 {BuildCommandLine: dbl quote quoting #4} {win exec} { exec $env(COMSPEC) /c echo foo {a="b"} bar -} {foo "a=\"b\"" bar} +} {foo a=\"b\" bar} test winpipe-7.7 {BuildCommandLine: dbl quote quoting #5} {win exec} { exec $env(COMSPEC) /c echo foo {a = "b"} bar } {foo "a = \"b\"" bar} test winpipe-7.8 {BuildCommandLine: dbl quote quoting #6} {win exec} { exec $env(COMSPEC) /c echo {"hello"} {""hello""} {"""hello"""} {"\"hello\""} {he llo} "he \" llo" -} {"\"hello\"" "\"\"hello\"\"" "\"\"\"hello\"\"\"" "\"\\\"hello\\\"\"" "he llo" "he \" llo"} +} {\"hello\" \"\"hello\"\" \"\"\"hello\"\"\" \"\\\"hello\\\"\" "he llo" "he \" llo"} test winpipe-7.9 {BuildCommandLine: N backslashes followed a quote rule #1} {win exec} { exec $env(COMSPEC) /c echo foo \\ bar } {foo \ bar} diff --git a/win/tclWinPipe.c b/win/tclWinPipe.c index 728e43a..21bdcec 100644 --- a/win/tclWinPipe.c +++ b/win/tclWinPipe.c @@ -1647,21 +1647,27 @@ BuildCommandLine( /* Quote flags: * 1 - escape argument; * 2 - previous arguments chain contains unpaired quote-char; + * 4 - enclose in quotes; */ - quote &= ~1; /* reset escape flag */ + quote &= ~5; /* reset escape flags */ bspos = NULL; if (arg[0] == '\0') { - quote = 1; + quote = 5; } else { int count; Tcl_UniChar ch; for (start = arg; *start != '\0'; start += count) { count = Tcl_UtfToUniChar(start, &ch); - if (Tcl_UniCharIsSpace(ch) || - (count == 1 && (*start=='"' || strchr(specMetaChars, *start))) - ) { - quote |= 1; /* set escape flag - must be quoted */ - break; + if (count == 1) { + if (Tcl_UniCharIsSpace(ch) || + strchr(specMetaChars, *start) + ) { + quote |= 5; /* set escape flag & must be quoted */ + break; + } + if (*start == '"') { + quote |= 1; /* set escape flag */ + } } } } @@ -1670,7 +1676,9 @@ BuildCommandLine( Tcl_DStringAppend(&ds, arg, -1); } else { /* start of argument (main opening quote-char) */ - Tcl_DStringAppend(&ds, "\"", 1); + if (quote & 4) { + Tcl_DStringAppend(&ds, "\"", 1); + } start = arg; for (special = arg; *special != '\0'; ) { /* position of `\` is important before quote or at end (equal `\"` because quoted) */ @@ -1708,10 +1716,15 @@ BuildCommandLine( bspos = NULL; /* reset last backslash possition (not interesting) */ special++; } - /* rest of argument (and escape backslashes before closing main quote) */ - QuoteCmdLineBackslash(&ds, start, special, bspos); - /* end of argument (main closing quote-char) */ - Tcl_DStringAppend(&ds, "\"", 1); + if (quote & 4) { + /* rest of argument (and escape backslashes before closing main quote) */ + QuoteCmdLineBackslash(&ds, start, special, bspos); + /* end of argument (main closing quote-char) */ + Tcl_DStringAppend(&ds, "\"", 1); + } else { + /* rest of argument */ + QuoteCmdLineBackslash(&ds, start, special, NULL); + } } } Tcl_DStringFree(linePtr); -- cgit v0.12 From 820a737a2f302b54ee7af88484cbfd694ec65804 Mon Sep 17 00:00:00 2001 From: sebres Date: Thu, 23 Aug 2018 10:26:03 +0000 Subject: code review, skip slow test winpipe-8.2 executed args from injectList particularly (normally winpipe-8.3 covers the same but jointly), to enable use parameter `-constraints slowTest`, added new test with randomly generated potentially dangerous args --- library/tcltest/tcltest.tcl | 4 +++ tests/winPipe.test | 35 ++++++++++++++++++-- win/tclWinPipe.c | 81 ++++++++++++++++++++++++++++----------------- 3 files changed, 87 insertions(+), 33 deletions(-) diff --git a/library/tcltest/tcltest.tcl b/library/tcltest/tcltest.tcl index 8e43859..936acaa 100644 --- a/library/tcltest/tcltest.tcl +++ b/library/tcltest/tcltest.tcl @@ -1243,6 +1243,10 @@ proc tcltest::DefineConstraintInitializers {} { ConstraintInitializer interactive \ {expr {[info exists ::tcl_interactive] && $::tcl_interactive}} + # Skip slow tests (to enable slow tests add parameter `-constraints slowTest`) + + ConstraintInitializer slowTest {format 0} + # Some tests can only be run if the installation came from a CD # image instead of a web image. Some tests must be skipped if you # are running as root on Unix. Other tests can only be run if you diff --git a/tests/winPipe.test b/tests/winPipe.test index 5c6eac8..4385690 100644 --- a/tests/winPipe.test +++ b/tests/winPipe.test @@ -336,8 +336,9 @@ proc _testExecArgs {single args} { # (e. g. to cover unexpected trim by nts-zero case, and args don't recombined): set args [list "1st" $args "3rd"] } + set args [list {*}$args]; # normalized canonical list foreach cmd $cmds { - set e [list [file tail $path(echoArgs.tcl)] {*}$args] + set e [linsert $args 0 [file tail $path(echoArgs.tcl)]] tcltest::DebugPuts 4 " ## test exec [file extension [lindex $cmd 0]] ($cmd) for\n ## $args" if {[catch { exec {*}$cmd {*}$args @@ -502,7 +503,7 @@ test winpipe-8.1 {BuildCommandLine/parse_cmdline pass-thru: dumped arguments are } -result {} test winpipe-8.2 {BuildCommandLine/parse_cmdline pass-thru: check injection on special meta-chars (particular)} \ --constraints {win exec} -body { +-constraints {win exec slowTest} -body { _testExecArgs 1 {*}$injectList } -result {} @@ -524,6 +525,36 @@ test winpipe-8.4 {BuildCommandLine/parse_cmdline pass-thru: check injection on s [list "START\"" {*}$injectList "\"END"] } -result {} +test winpipe-8.5 {BuildCommandLine/parse_cmdline pass-thru: check injection on special meta-chars (random mix)} \ +-constraints {win exec} -body { + set lst {} + set maps { + {\&|^<>!()%} + {\&|^<>!()% } + {"\&|^<>!()%} + {"\&|^<>!()% } + {"""""\\\\\&|^<>!()%} + {"""""\\\\\&|^<>!()% } + } + set i 0 + time { + set args {[incr i].} + time { + set map [lindex $maps [expr {int(rand()*[llength $maps])}]] + # be sure arg has some prefix (avoid special handling, like |& etc) + set a {x} + while {[string length $a] < 50} { + append a [string index $map [expr {int(rand()*[string length $map])}]] + } + lappend args $a + } 20 + lappend lst $args + } 10 + _testExecArgs 0 {*}$lst +} -result {} -cleanup { + unset -nocomplain lst args a map maps +} + rename _testExecArgs {} # restore old values for env(TMP) and env(TEMP) diff --git a/win/tclWinPipe.c b/win/tclWinPipe.c index 21bdcec..e596cac 100644 --- a/win/tclWinPipe.c +++ b/win/tclWinPipe.c @@ -1625,6 +1625,13 @@ BuildCommandLine( /* characters to enclose in quotes in any case (regardless unpaired-flag) */ const static char *specMetaChars2 = "%"; + /* Quote flags: + * CL_ESCAPE - escape argument; + * CL_QUOTE - enclose in quotes; + * CL_UNPAIRED - previous arguments chain contains unpaired quote-char; + */ + enum {CL_ESCAPE = 1, CL_QUOTE = 2, CL_UNPAIRED = 4}; + Tcl_DStringInit(&ds); /* @@ -1644,41 +1651,55 @@ BuildCommandLine( Tcl_DStringAppend(&ds, " ", 1); } - /* Quote flags: - * 1 - escape argument; - * 2 - previous arguments chain contains unpaired quote-char; - * 4 - enclose in quotes; - */ - quote &= ~5; /* reset escape flags */ + quote &= ~(CL_ESCAPE|CL_QUOTE); /* reset escape flags */ bspos = NULL; if (arg[0] == '\0') { - quote = 5; + quote = CL_QUOTE; } else { int count; Tcl_UniChar ch; - for (start = arg; *start != '\0'; start += count) { + for (start = arg; + *start != '\0' && + (quote & (CL_ESCAPE|CL_QUOTE)) != (CL_ESCAPE|CL_QUOTE); + start += count + ) { count = Tcl_UtfToUniChar(start, &ch); - if (count == 1) { - if (Tcl_UniCharIsSpace(ch) || - strchr(specMetaChars, *start) - ) { - quote |= 5; /* set escape flag & must be quoted */ + if (count > 1) continue; + if (Tcl_UniCharIsSpace(ch)) { + quote |= CL_QUOTE; /* quote only */ + if (bspos) { /* if backslash found - escape & quote */ + quote |= CL_ESCAPE; break; } - if (*start == '"') { - quote |= 1; /* set escape flag */ + continue; + } + if (strchr(specMetaChars, *start)) { + quote |= (CL_ESCAPE|CL_QUOTE); /*escape & quote */ + break; + } + if (*start == '"') { + quote |= CL_ESCAPE; /* escape only */ + continue; + } + if (*start == '\\') { + bspos = start; + if (quote & CL_QUOTE) { /* if quote - escape & quote */ + quote |= CL_ESCAPE; + break; } + continue; } } + bspos = NULL; } - if (!(quote & 1)) { + if (quote & CL_QUOTE) { + /* start of argument (main opening quote-char) */ + Tcl_DStringAppend(&ds, "\"", 1); + } + if (!(quote & CL_ESCAPE)) { /* nothing to escape */ Tcl_DStringAppend(&ds, arg, -1); } else { - /* start of argument (main opening quote-char) */ - if (quote & 4) { - Tcl_DStringAppend(&ds, "\"", 1); - } start = arg; for (special = arg; *special != '\0'; ) { /* position of `\` is important before quote or at end (equal `\"` because quoted) */ @@ -1689,7 +1710,7 @@ BuildCommandLine( } /* ["] */ if (*special == '"') { - quote ^= 2; /* invert unpaired flag - observe unpaired quotes */ + quote ^= CL_UNPAIRED; /* invert unpaired flag - observe unpaired quotes */ /* add part before (and escape backslashes before quote) */ QuoteCmdLineBackslash(&ds, start, special, bspos); bspos = NULL; @@ -1699,7 +1720,7 @@ BuildCommandLine( continue; } /* unpaired (escaped) quote causes special handling on meta-chars */ - if ((quote & 2) && strchr(specMetaChars, *special)) { + if ((quote & CL_UNPAIRED) && strchr(specMetaChars, *special)) { special = QuoteCmdLinePart(&ds, start, special, specMetaChars, &bspos); /* start to current or first backslash */ start = !bspos ? special : bspos; @@ -1716,15 +1737,13 @@ BuildCommandLine( bspos = NULL; /* reset last backslash possition (not interesting) */ special++; } - if (quote & 4) { - /* rest of argument (and escape backslashes before closing main quote) */ - QuoteCmdLineBackslash(&ds, start, special, bspos); - /* end of argument (main closing quote-char) */ - Tcl_DStringAppend(&ds, "\"", 1); - } else { - /* rest of argument */ - QuoteCmdLineBackslash(&ds, start, special, NULL); - } + /* rest of argument (and escape backslashes before closing main quote) */ + QuoteCmdLineBackslash(&ds, start, special, + (quote & CL_QUOTE) ? bspos : NULL); + } + if (quote & CL_QUOTE) { + /* end of argument (main closing quote-char) */ + Tcl_DStringAppend(&ds, "\"", 1); } } Tcl_DStringFree(linePtr); -- cgit v0.12 From eeebae7172a523bec78bf30c81cccc2947918d96 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Tue, 28 Aug 2018 22:28:50 +0000 Subject: Now, restore wide(), but make int() the same as entier(). Add new utility function. --- generic/tclBasic.c | 60 +++++++++++--------------------- generic/tclBinary.c | 35 +++++++++---------- generic/tclCmdMZ.c | 2 +- generic/tclCompCmdsSZ.c | 2 +- generic/tclInt.h | 2 ++ generic/tclObj.c | 68 ++++++++++++++++++++++++++++++++++++ generic/tclScan.c | 24 +++++++++---- generic/tclStringObj.c | 91 ++++++++++++++++++++++++++++++++++++++----------- tests/compExpr-old.test | 6 ++-- tests/expr-old.test | 4 +-- tests/expr.test | 6 ++-- tests/format.test | 9 +++-- tests/get.test | 4 +-- tests/obj.test | 17 +++++---- tests/scan.test | 15 ++++---- tests/string.test | 24 ++++++------- 16 files changed, 238 insertions(+), 131 deletions(-) diff --git a/generic/tclBasic.c b/generic/tclBasic.c index 0769f24..b31d5bd 100644 --- a/generic/tclBasic.c +++ b/generic/tclBasic.c @@ -114,7 +114,6 @@ static Tcl_ObjCmdProc ExprBinaryFunc; static Tcl_ObjCmdProc ExprBoolFunc; static Tcl_ObjCmdProc ExprCeilFunc; static Tcl_ObjCmdProc ExprDoubleFunc; -static Tcl_ObjCmdProc ExprEntierFunc; static Tcl_ObjCmdProc ExprFloorFunc; static Tcl_ObjCmdProc ExprIntFunc; static Tcl_ObjCmdProc ExprIsqrtFunc; @@ -125,6 +124,7 @@ static Tcl_ObjCmdProc ExprRoundFunc; static Tcl_ObjCmdProc ExprSqrtFunc; static Tcl_ObjCmdProc ExprSrandFunc; static Tcl_ObjCmdProc ExprUnaryFunc; +static Tcl_ObjCmdProc ExprWideFunc; static void MathFuncWrongNumArgs(Tcl_Interp *interp, int expected, int actual, Tcl_Obj *const *objv); static Tcl_NRPostProc NRCoroutineCallerCallback; @@ -315,7 +315,7 @@ static const BuiltinFuncDef BuiltinFuncTable[] = { { "cos", ExprUnaryFunc, (ClientData) cos }, { "cosh", ExprUnaryFunc, (ClientData) cosh }, { "double", ExprDoubleFunc, NULL }, - { "entier", ExprEntierFunc, NULL }, + { "entier", ExprIntFunc, NULL }, { "exp", ExprUnaryFunc, (ClientData) exp }, { "floor", ExprFloorFunc, NULL }, { "fmod", ExprBinaryFunc, (ClientData) fmod }, @@ -335,7 +335,7 @@ static const BuiltinFuncDef BuiltinFuncTable[] = { { "srand", ExprSrandFunc, NULL }, { "tan", ExprUnaryFunc, (ClientData) tan }, { "tanh", ExprUnaryFunc, (ClientData) tanh }, - { "wide", ExprIntFunc, NULL }, + { "wide", ExprWideFunc, NULL }, { NULL, NULL, NULL } }; @@ -3659,12 +3659,20 @@ OldMathFuncProc( args[k].doubleValue = d; break; case TCL_INT: - case TCL_WIDE_INT: if (ExprIntFunc(NULL, interp, 2, &objv[j-1]) != TCL_OK) { ckfree(args); return TCL_ERROR; } valuePtr = Tcl_GetObjResult(interp); + Tcl_GetLongFromObj(NULL, valuePtr, &args[k].intValue); + Tcl_ResetResult(interp); + break; + case TCL_WIDE_INT: + if (ExprWideFunc(NULL, interp, 2, &objv[j-1]) != TCL_OK) { + ckfree(args); + return TCL_ERROR; + } + valuePtr = Tcl_GetObjResult(interp); TclGetWideIntFromObj(NULL, valuePtr, &args[k].wideValue); Tcl_ResetResult(interp); break; @@ -7608,7 +7616,7 @@ ExprDoubleFunc( } static int -ExprEntierFunc( +ExprIntFunc( ClientData clientData, /* Ignored. */ Tcl_Interp *interp, /* The interpreter in which to execute the * function. */ @@ -7664,7 +7672,7 @@ ExprEntierFunc( } static int -ExprIntFunc( +ExprWideFunc( ClientData clientData, /* Ignored. */ Tcl_Interp *interp, /* The interpreter in which to execute the * function. */ @@ -7672,26 +7680,11 @@ ExprIntFunc( Tcl_Obj *const *objv) /* Actual parameter vector. */ { Tcl_WideInt wResult; - Tcl_Obj *objPtr; - if (ExprEntierFunc(NULL, interp, objc, objv) != TCL_OK) { + if (ExprIntFunc(NULL, interp, objc, objv) != TCL_OK) { return TCL_ERROR; } - objPtr = Tcl_GetObjResult(interp); - if (TclGetWideIntFromObj(NULL, objPtr, &wResult) != TCL_OK) { - /* - * Truncate the bignum; keep only bits in wide int range. - */ - - mp_int big; - - Tcl_GetBignumFromObj(NULL, objPtr, &big); - mp_mod_2d(&big, (int) CHAR_BIT * sizeof(Tcl_WideInt), &big); - objPtr = Tcl_NewBignumObj(&big); - Tcl_IncrRefCount(objPtr); - TclGetWideIntFromObj(NULL, objPtr, &wResult); - Tcl_DecrRefCount(objPtr); - } + TclGetLeastSign64bits(NULL, Tcl_GetObjResult(interp), &wResult); Tcl_SetObjResult(interp, Tcl_NewWideIntObj(wResult)); return TCL_OK; } @@ -7938,7 +7931,7 @@ ExprSrandFunc( Tcl_Obj *const *objv) /* Parameter vector. */ { Interp *iPtr = (Interp *) interp; - long i = 0; /* Initialized to avoid compiler warning. */ + Tcl_WideInt w = 0; /* Initialized to avoid compiler warning. */ /* * Convert argument and use it to reset the seed. @@ -7949,20 +7942,8 @@ ExprSrandFunc( return TCL_ERROR; } - if (TclGetLongFromObj(NULL, objv[1], &i) != TCL_OK) { - Tcl_Obj *objPtr; - mp_int big; - - if (Tcl_GetBignumFromObj(interp, objv[1], &big) != TCL_OK) { - /* TODO: more ::errorInfo here? or in caller? */ - return TCL_ERROR; - } - - mp_mod_2d(&big, (int) CHAR_BIT * sizeof(long), &big); - objPtr = Tcl_NewBignumObj(&big); - Tcl_IncrRefCount(objPtr); - TclGetLongFromObj(NULL, objPtr, &i); - Tcl_DecrRefCount(objPtr); + if (TclGetLeastSign64bits(NULL, objv[1], &w) != TCL_OK) { + return TCL_ERROR; } /* @@ -7971,8 +7952,7 @@ ExprSrandFunc( */ iPtr->flags |= RAND_SEED_INITIALIZED; - iPtr->randSeed = i; - iPtr->randSeed &= (unsigned long) 0x7fffffff; + iPtr->randSeed = w & (unsigned long) 0x7fffffff; if ((iPtr->randSeed == 0) || (iPtr->randSeed == 0x7fffffff)) { iPtr->randSeed ^= 123459876; } diff --git a/generic/tclBinary.c b/generic/tclBinary.c index cb5a5cb..c91611c 100644 --- a/generic/tclBinary.c +++ b/generic/tclBinary.c @@ -1963,7 +1963,6 @@ FormatNumber( Tcl_Obj *src, /* Number to format. */ unsigned char **cursorPtr) /* Pointer to index into destination buffer. */ { - long value; double dvalue; Tcl_WideInt wvalue; float fvalue; @@ -2025,7 +2024,7 @@ FormatNumber( case 'w': case 'W': case 'm': - if (Tcl_GetWideIntFromObj(interp, src, &wvalue) != TCL_OK) { + if (TclGetLeastSign64bits(interp, src, &wvalue) != TCL_OK) { return TCL_ERROR; } if (NeedReversing(type)) { @@ -2055,19 +2054,19 @@ FormatNumber( case 'i': case 'I': case 'n': - if (TclGetLongFromObj(interp, src, &value) != TCL_OK) { + if (TclGetLeastSign64bits(interp, src, &wvalue) != TCL_OK) { return TCL_ERROR; } if (NeedReversing(type)) { - *(*cursorPtr)++ = UCHAR(value); - *(*cursorPtr)++ = UCHAR(value >> 8); - *(*cursorPtr)++ = UCHAR(value >> 16); - *(*cursorPtr)++ = UCHAR(value >> 24); + *(*cursorPtr)++ = UCHAR(wvalue); + *(*cursorPtr)++ = UCHAR(wvalue >> 8); + *(*cursorPtr)++ = UCHAR(wvalue >> 16); + *(*cursorPtr)++ = UCHAR(wvalue >> 24); } else { - *(*cursorPtr)++ = UCHAR(value >> 24); - *(*cursorPtr)++ = UCHAR(value >> 16); - *(*cursorPtr)++ = UCHAR(value >> 8); - *(*cursorPtr)++ = UCHAR(value); + *(*cursorPtr)++ = UCHAR(wvalue >> 24); + *(*cursorPtr)++ = UCHAR(wvalue >> 16); + *(*cursorPtr)++ = UCHAR(wvalue >> 8); + *(*cursorPtr)++ = UCHAR(wvalue); } return TCL_OK; @@ -2077,15 +2076,15 @@ FormatNumber( case 's': case 'S': case 't': - if (TclGetLongFromObj(interp, src, &value) != TCL_OK) { + if (TclGetLeastSign64bits(interp, src, &wvalue) != TCL_OK) { return TCL_ERROR; } if (NeedReversing(type)) { - *(*cursorPtr)++ = UCHAR(value); - *(*cursorPtr)++ = UCHAR(value >> 8); + *(*cursorPtr)++ = UCHAR(wvalue); + *(*cursorPtr)++ = UCHAR(wvalue >> 8); } else { - *(*cursorPtr)++ = UCHAR(value >> 8); - *(*cursorPtr)++ = UCHAR(value); + *(*cursorPtr)++ = UCHAR(wvalue >> 8); + *(*cursorPtr)++ = UCHAR(wvalue); } return TCL_OK; @@ -2093,10 +2092,10 @@ FormatNumber( * 8-bit integer values. */ case 'c': - if (TclGetLongFromObj(interp, src, &value) != TCL_OK) { + if (TclGetLeastSign64bits(interp, src, &wvalue) != TCL_OK) { return TCL_ERROR; } - *(*cursorPtr)++ = UCHAR(value); + *(*cursorPtr)++ = UCHAR(wvalue); return TCL_OK; default: diff --git a/generic/tclCmdMZ.c b/generic/tclCmdMZ.c index f99a4a0..c2b0ba9 100644 --- a/generic/tclCmdMZ.c +++ b/generic/tclCmdMZ.c @@ -1622,6 +1622,7 @@ StringIsCmd( case STR_IS_GRAPH: chcomp = Tcl_UniCharIsGraph; break; + case STR_IS_INT: case STR_IS_ENTIER: if ((objPtr->typePtr == &tclIntType) || (objPtr->typePtr == &tclBignumType)) { @@ -1664,7 +1665,6 @@ StringIsCmd( failat = 0; } break; - case STR_IS_INT: case STR_IS_WIDE: if (TCL_OK == TclGetWideIntFromObj(NULL, objPtr, &w)) { break; diff --git a/generic/tclCompCmdsSZ.c b/generic/tclCompCmdsSZ.c index 8ab1ffa..243f8a9 100644 --- a/generic/tclCompCmdsSZ.c +++ b/generic/tclCompCmdsSZ.c @@ -691,11 +691,11 @@ TclCompileStringIsCmd( } switch (t) { - case STR_IS_INT: case STR_IS_WIDE: PUSH( "2"); OP( LE); break; + case STR_IS_INT: case STR_IS_ENTIER: PUSH( "3"); OP( LE); diff --git a/generic/tclInt.h b/generic/tclInt.h index 928d649..7d93d30 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -3044,6 +3044,8 @@ MODULE_SCOPE char * TclGetStringStorage(Tcl_Obj *objPtr, MODULE_SCOPE int TclGetLoadedPackagesEx(Tcl_Interp *interp, const char *targetName, const char *packageName); +MODULE_SCOPE int TclGetLeastSign64bits(Tcl_Interp *, Tcl_Obj *, + Tcl_WideInt *); MODULE_SCOPE int TclGlob(Tcl_Interp *interp, char *pattern, Tcl_Obj *unquotedPrefix, int globFlags, Tcl_GlobTypeData *types); diff --git a/generic/tclObj.c b/generic/tclObj.c index 3bbe7b6..75f9cb7 100644 --- a/generic/tclObj.c +++ b/generic/tclObj.c @@ -3123,6 +3123,74 @@ Tcl_GetWideIntFromObj( return TCL_ERROR; } + +/* + *---------------------------------------------------------------------- + * + * TclGetLeastSign64bits -- + * + * Attempt to return a wide integer from the Tcl object "objPtr". If the + * object is not already a wide int object, an attempt will be made to + * convert it to one. Integer out-of-range values don't result in an + * error, but only the least significant 64 bit will be returned. + * + * Results: + * The return value is a standard Tcl object result. If an error occurs + * during conversion, an error message is left in the interpreter's + * result unless "interp" is NULL. + * + * Side effects: + * If the object is not already an int object, the conversion will free + * any old internal representation. + * + *---------------------------------------------------------------------- + */ + +int +TclGetLeastSign64bits( + Tcl_Interp *interp, /* Used for error reporting if not NULL. */ + Tcl_Obj *objPtr, /* Object from which to get a wide int. */ + Tcl_WideInt *wideIntPtr) /* Place to store resulting wide integer. */ +{ + do { + if (objPtr->typePtr == &tclIntType) { + *wideIntPtr = objPtr->internalRep.wideValue; + return TCL_OK; + } + if (objPtr->typePtr == &tclDoubleType) { + if (interp != NULL) { + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "expected integer but got \"%s\"", + TclGetString(objPtr))); + Tcl_SetErrorCode(interp, "TCL", "VALUE", "INTEGER", NULL); + } + return TCL_ERROR; + } + if (objPtr->typePtr == &tclBignumType) { + mp_int big; + + Tcl_WideUInt value = 0, scratch; + unsigned long numBytes = sizeof(Tcl_WideInt); + unsigned char *bytes = (unsigned char *) &scratch; + + Tcl_GetBignumFromObj(NULL, objPtr, &big); + mp_mod_2d(&big, (int) CHAR_BIT * sizeof(Tcl_WideInt), &big); + mp_to_unsigned_bin_n(&big, bytes, &numBytes); + while (numBytes-- > 0) { + value = (value << CHAR_BIT) | *bytes++; + } + if (big.sign) { + value = -value; + } + *wideIntPtr = (Tcl_WideInt) value; + mp_clear(&big); + return TCL_OK; + } + } while (TclParseNumber(interp, objPtr, "integer", NULL, -1, NULL, + TCL_PARSE_INTEGER_ONLY)==TCL_OK); + return TCL_ERROR; +} + /* *---------------------------------------------------------------------- * diff --git a/generic/tclScan.c b/generic/tclScan.c index 458dbd8..cfc3a92 100644 --- a/generic/tclScan.c +++ b/generic/tclScan.c @@ -571,10 +571,11 @@ Tcl_ScanObjCmd( const char *format; int numVars, nconversions, totalVars = -1; int objIndex, offset, i, result, code; - Tcl_WideInt value; + long value; const char *string, *end, *baseString; char op = 0; int width, underflow = 0; + Tcl_WideInt wideValue; Tcl_UniChar ch = 0, sch = 0; Tcl_Obj **objs = NULL, *objPtr = NULL; int flags; @@ -923,7 +924,18 @@ Tcl_ScanObjCmd( Tcl_DecrRefCount(objPtr); break; } - if (flags & SCAN_BIG) { + if (flags & SCAN_LONGER) { + if (TclGetLeastSign64bits(NULL, objPtr, &wideValue) != TCL_OK) { + goto done; + } + if ((flags & SCAN_UNSIGNED) && (wideValue < 0)) { + sprintf(buf, "%" TCL_LL_MODIFIER "u", + (Tcl_WideUInt)wideValue); + Tcl_SetStringObj(objPtr, buf, -1); + } else { + TclSetIntObj(objPtr, wideValue); + } + } else if (flags & SCAN_BIG) { if (flags & SCAN_UNSIGNED) { mp_int big; int code = Tcl_GetBignumFromObj(interp, objPtr, &big); @@ -948,15 +960,15 @@ Tcl_ScanObjCmd( } } } else { - if (TclGetWideIntFromObj(NULL, objPtr, &value) != TCL_OK) { + if (TclGetLongFromObj(NULL, objPtr, &value) != TCL_OK) { if (TclGetString(objPtr)[0] == '-') { - value = LLONG_MIN; + value = LONG_MIN; } else { - value = LLONG_MAX; + value = LONG_MAX; } } if ((flags & SCAN_UNSIGNED) && (value < 0)) { - sprintf(buf, "%" TCL_LL_MODIFIER "u", value); /* INTL: ISO digit */ + sprintf(buf, "%lu", value); /* INTL: ISO digit */ Tcl_SetStringObj(objPtr, buf, -1); } else { TclSetIntObj(objPtr, value); diff --git a/generic/tclStringObj.c b/generic/tclStringObj.c index 60df2dd..f98180f 100644 --- a/generic/tclStringObj.c +++ b/generic/tclStringObj.c @@ -1793,6 +1793,9 @@ Tcl_AppendFormatToObj( char *end; int gotMinus = 0, gotHash = 0, gotZero = 0, gotSpace = 0, gotPlus = 0; int width, gotPrecision, precision, sawFlag, useShort = 0, useBig = 0; +#ifndef TCL_WIDE_INT_IS_LONG + int useWide = 0; +#endif int newXpg, numChars, allocSegment = 0, segmentLimit, segmentNumBytes; Tcl_Obj *segment; int step = TclUtfToUniChar(format, &ch); @@ -1983,11 +1986,18 @@ Tcl_AppendFormatToObj( useBig = 1; format += step; step = TclUtfToUniChar(format, &ch); +#ifndef TCL_WIDE_INT_IS_LONG + } else { + useWide = 1; +#endif } } else if (ch == 'I') { if ((format[1] == '6') && (format[2] == '4')) { format += (step + 2); step = TclUtfToUniChar(format, &ch); +#ifndef TCL_WIDE_INT_IS_LONG + useWide = 1; +#endif } else if ((format[1] == '3') && (format[2] == '2')) { format += (step + 2); step = TclUtfToUniChar(format, &ch); @@ -2057,10 +2067,16 @@ Tcl_AppendFormatToObj( case 'b': { short s = 0; /* Silence compiler warning; only defined and * used when useShort is true. */ + long l; Tcl_WideInt w; mp_int big; int toAppend, isNegative = 0; +#ifndef TCL_WIDE_INT_IS_LONG + if (ch == 'p') { + useWide = 1; + } +#endif if (useBig) { int cmpResult; if (Tcl_GetBignumFromObj(interp, segment, &big) != TCL_OK) { @@ -2079,32 +2095,53 @@ Tcl_AppendFormatToObj( ch = 'd'; } } - } else if (TclGetWideIntFromObj(NULL, segment, &w) != TCL_OK) { - Tcl_Obj *objPtr; +#ifndef TCL_WIDE_INT_IS_LONG + } else if (useWide) { + if (TclGetWideIntFromObj(NULL, segment, &w) != TCL_OK) { + Tcl_Obj *objPtr; - if (Tcl_GetBignumFromObj(interp,segment,&big) != TCL_OK) { - goto error; + if (Tcl_GetBignumFromObj(interp,segment,&big) != TCL_OK) { + goto error; + } + mp_mod_2d(&big, (int) CHAR_BIT*sizeof(Tcl_WideInt), &big); + objPtr = Tcl_NewBignumObj(&big); + Tcl_IncrRefCount(objPtr); + TclGetWideIntFromObj(NULL, objPtr, &w); + Tcl_DecrRefCount(objPtr); + } + isNegative = (w < (Tcl_WideInt) 0); + if (w == (Tcl_WideInt) 0) gotHash = 0; +#endif + } else if (TclGetLongFromObj(NULL, segment, &l) != TCL_OK) { + if (TclGetWideIntFromObj(NULL, segment, &w) != TCL_OK) { + Tcl_Obj *objPtr; + + if (Tcl_GetBignumFromObj(interp,segment,&big) != TCL_OK) { + goto error; + } + mp_mod_2d(&big, (int) CHAR_BIT * sizeof(long), &big); + objPtr = Tcl_NewBignumObj(&big); + Tcl_IncrRefCount(objPtr); + TclGetLongFromObj(NULL, objPtr, &l); + Tcl_DecrRefCount(objPtr); + } else { + l = Tcl_WideAsLong(w); } - mp_mod_2d(&big, (int) CHAR_BIT * sizeof(long), &big); - objPtr = Tcl_NewBignumObj(&big); - Tcl_IncrRefCount(objPtr); - TclGetWideIntFromObj(NULL, objPtr, &w); - Tcl_DecrRefCount(objPtr); if (useShort) { - s = (short) w; + s = (short) l; isNegative = (s < (short) 0); if (s == (short) 0) gotHash = 0; } else { - isNegative = (w < (long) 0); - if (w == (long) 0) gotHash = 0; + isNegative = (l < (long) 0); + if (l == (long) 0) gotHash = 0; } } else if (useShort) { - s = (short) w; + s = (short) l; isNegative = (s < (short) 0); if (s == (short) 0) gotHash = 0; } else { - isNegative = (w < (Tcl_WideInt) 0); - if (w == (Tcl_WideInt) 0) gotHash = 0; + isNegative = (l < (long) 0); + if (l == (long) 0) gotHash = 0; } segment = Tcl_NewObj(); @@ -2153,10 +2190,14 @@ Tcl_AppendFormatToObj( if (useShort) { pure = Tcl_NewIntObj((int) s); +#ifndef TCL_WIDE_INT_IS_LONG + } else if (useWide) { + pure = Tcl_NewWideIntObj(w); +#endif } else if (useBig) { pure = Tcl_NewBignumObj(&big); } else { - pure = Tcl_NewWideIntObj(w); + pure = Tcl_NewLongObj(l); } Tcl_IncrRefCount(pure); bytes = TclGetStringFromObj(pure, &length); @@ -2236,6 +2277,16 @@ Tcl_AppendFormatToObj( numDigits++; us /= base; } +#ifndef TCL_WIDE_INT_IS_LONG + } else if (useWide) { + Tcl_WideUInt uw = (Tcl_WideUInt) w; + + bits = uw; + while (uw) { + numDigits++; + uw /= base; + } +#endif } else if (useBig && big.used) { int leftover = (big.used * DIGIT_BIT) % numBits; mp_digit mask = (~(mp_digit)0) << (DIGIT_BIT-leftover); @@ -2252,12 +2303,12 @@ Tcl_AppendFormatToObj( goto errorMsg; } } else if (!useBig) { - Tcl_WideUInt uw = (Tcl_WideUInt) w; + unsigned long ul = (unsigned long) l; - bits = (Tcl_WideUInt) uw; - while (uw) { + bits = (Tcl_WideUInt) ul; + while (ul) { numDigits++; - uw /= base; + ul /= base; } } diff --git a/tests/compExpr-old.test b/tests/compExpr-old.test index 0136ccd..9dfe4c4 100644 --- a/tests/compExpr-old.test +++ b/tests/compExpr-old.test @@ -78,8 +78,8 @@ proc testIEEE {} { } testConstraint ieeeFloatingPoint [testIEEE] -testConstraint longIs32bit [expr {int(0x80000000) < 0}] -testConstraint longIs64bit [expr {int(0x8000000000000000) < 0}] +testConstraint longIs32bit [expr {$tcl_platform(wordSize) == 4}] +testConstraint longIs64bit [expr {$tcl_platform(wordSize) == 8}] # procedures used below @@ -337,7 +337,7 @@ test compExpr-old-9.4 {CompileRelationalExpr: just shift expr} {expr {1<<3}} 8 test compExpr-old-9.5a {CompileRelationalExpr: shift expr producing LONG_MIN} longIs64bit { expr {int(1<<63)} -} -9223372036854775808 +} 9223372036854775808 test compExpr-old-9.5b {CompileRelationalExpr: shift expr producing LONG_MIN} longIs32bit { expr {int(1<<31)} } -2147483648 diff --git a/tests/expr-old.test b/tests/expr-old.test index a73b77a..7f89d99 100644 --- a/tests/expr-old.test +++ b/tests/expr-old.test @@ -813,10 +813,10 @@ test expr-old-32.32 {math functions in expressions} { } {-1} test expr-old-32.33 {math functions in expressions} { expr int(1e60) -} 0 +} 999999999999999949387135297074018866963645011013410073083904 test expr-old-32.34 {math functions in expressions} { expr int(-1e60) -} 0 +} -999999999999999949387135297074018866963645011013410073083904 test expr-old-32.35 {math functions in expressions} { expr round(1.49) } {1} diff --git a/tests/expr.test b/tests/expr.test index 713681a..913df1b 100644 --- a/tests/expr.test +++ b/tests/expr.test @@ -21,8 +21,8 @@ catch [list package require -exact Tcltest [info patchlevel]] # Determine if "long int" type is a 32 bit number and if the wide # type is a 64 bit number on this machine. -testConstraint longIs32bit [expr {int(0x80000000) < 0}] -testConstraint longIs64bit [expr {int(0x8000000000000000) < 0}] +testConstraint longIs32bit [expr {$tcl_platform(wordSize) == 4}] +testConstraint longIs64bit [expr {$tcl_platform(wordSize) == 8}] testConstraint wideIs64bit \ [expr {(wide(0x80000000) > 0) && (wide(0x8000000000000000) < 0)}] @@ -419,7 +419,7 @@ test expr-9.3 {CompileRelationalExpr: just shift expr} {expr -1>>2} -1 test expr-9.4 {CompileRelationalExpr: just shift expr} {expr {1<<3}} 8 test expr-9.5a {CompileRelationalExpr: shift expr producing LONG_MIN} longIs64bit { expr {int(1<<63)} -} -9223372036854775808 +} 9223372036854775808 test expr-9.5b {CompileRelationalExpr: shift expr producing LONG_MIN} longIs32bit { expr {int(1<<31)} } -2147483648 diff --git a/tests/format.test b/tests/format.test index cdea545..2fab1d9 100644 --- a/tests/format.test +++ b/tests/format.test @@ -16,11 +16,10 @@ if {[lsearch [namespace children] ::tcltest] == -1} { } # %u output depends on word length, so this test is not portable. -testConstraint longIs32bit [expr {int(0x80000000) < 0}] -testConstraint longIs64bit [expr {int(0x8000000000000000) < 0}] +testConstraint longIs32bit [expr {$tcl_platform(wordSize) == 4}] +testConstraint longIs64bit [expr {$tcl_platform(wordSize) == 8}] testConstraint wideIs64bit \ [expr {(wide(0x80000000) > 0) && (wide(0x8000000000000000) < 0)}] -testConstraint wideBiggerThanInt [expr {wide(0x80000000) != int(0x80000000)}] testConstraint pointerIs64bit [expr {$tcl_platform(pointerSize) >= 8}] test format-1.1 {integer formatting} { @@ -547,7 +546,7 @@ for {set i 290} {$i < 400} {incr i} { append b "x" } -test format-17.1 {testing %d with wide} {wideIs64bit wideBiggerThanInt} { +test format-17.1 {testing %d with wide} {wideIs64bit longIs32bit} { format %d 7810179016327718216 } 1819043144 test format-17.2 {testing %ld with wide} {wideIs64bit} { @@ -580,7 +579,7 @@ test format-18.1 {do not demote existing numeric values} { format %08x $b lappend result [expr {$a == $b}] } {1 1 1 1} -test format-18.2 {do not demote existing numeric values} {wideBiggerThanInt} { +test format-18.2 {do not demote existing numeric values} {longIs32bit} { set a [expr {0xaaaaaaaaaa + 1}] set b 0xaaaaaaaaab list [format %08x $a] [expr {$a == $b}] diff --git a/tests/get.test b/tests/get.test index b02b686..f85bc01 100644 --- a/tests/get.test +++ b/tests/get.test @@ -20,8 +20,8 @@ catch [list package require -exact Tcltest [info patchlevel]] testConstraint testgetint [llength [info commands testgetint]] testConstraint testdoubleobj [llength [info commands testdoubleobj]] -testConstraint longIs32bit [expr {int(0x80000000) < 0}] -testConstraint longIs64bit [expr {int(0x8000000000000000) < 0}] +testConstraint longIs32bit [expr {$tcl_platform(wordSize) == 4}] +testConstraint longIs64bit [expr {$tcl_platform(wordSize) == 8}] test get-1.1 {Tcl_GetInt procedure} testgetint { testgetint 44 { 22} diff --git a/tests/obj.test b/tests/obj.test index ffd1a59..616564a 100644 --- a/tests/obj.test +++ b/tests/obj.test @@ -21,7 +21,6 @@ catch [list package require -exact Tcltest [info patchlevel]] testConstraint testobj [llength [info commands testobj]] testConstraint longIs32bit [expr {int(0x80000000) < 0}] -testConstraint wideBiggerThanInt [expr {wide(0x80000000) != int(0x80000000)}] test obj-1.1 {Tcl_AppendAllObjTypes, and InitTypeTable, Tcl_RegisterObjType} testobj { set r 1 @@ -549,34 +548,34 @@ test obj-32.1 {freeing very large object trees} { unset x } {} -test obj-33.1 {integer overflow on input} {longIs32bit wideBiggerThanInt} { +test obj-33.1 {integer overflow on input} {longIs32bit} { set x 0x8000; append x 0000 list [string is integer $x] [expr { wide($x) }] } {1 2147483648} -test obj-33.2 {integer overflow on input} {longIs32bit wideBiggerThanInt} { +test obj-33.2 {integer overflow on input} {longIs32bit} { set x 0xffff; append x ffff list [string is integer $x] [expr { wide($x) }] } {1 4294967295} -test obj-33.3 {integer overflow on input} { +test obj-33.3 {no integer overflow on input} { set x 0x100000000; append x 00000000 list [string is integer $x] [expr { $x }] -} {0 18446744073709551616} -test obj-33.4 {integer overflow on input} {longIs32bit wideBiggerThanInt} { +} {1 18446744073709551616} +test obj-33.4 {integer overflow on input} {longIs32bit} { set x -0x8000; append x 0000 list [string is integer $x] [expr { wide($x) }] } {1 -2147483648} -test obj-33.5 {integer overflow on input} {longIs32bit wideBiggerThanInt} { +test obj-33.5 {integer overflow on input} {longIs32bit} { set x -0x8000; append x 0001 list [string is integer $x] [expr { wide($x) }] } {1 -2147483649} -test obj-33.6 {integer overflow on input} {longIs32bit wideBiggerThanInt} { +test obj-33.6 {integer overflow on input} {longIs32bit} { set x -0xffff; append x ffff list [string is integer $x] [expr { wide($x) }] } {1 -4294967295} test obj-33.7 {integer overflow on input} { set x -0x100000000; append x 00000000 list [string is integer $x] [expr { $x }] -} {0 -18446744073709551616} +} {1 -18446744073709551616} test obj-34.1 {mp_iseven} testobj { set result "" diff --git a/tests/scan.test b/tests/scan.test index 1f32b9f..f7f7049 100644 --- a/tests/scan.test +++ b/tests/scan.test @@ -19,11 +19,8 @@ if {"::tcltest" ni [namespace children]} { # procedure that returns the range of integers proc int_range {} { - for { set MIN_INT 1 } { int($MIN_INT) > 0 } {} { - set MIN_INT [expr { $MIN_INT << 1 }] - } - set MIN_INT [expr {int($MIN_INT)}] - set MAX_INT [expr { ~ $MIN_INT }] + set MAX_INT [expr {[format %lu -2]/2}] + set MIN_INT [expr { ~ $MAX_INT }] return [list $MIN_INT $MAX_INT] } @@ -446,14 +443,14 @@ test scan-4.61 {Tcl_ScanObjCmd, set errors} -setup { test scan-4.62 {scanning of large and negative octal integers} { lassign [int_range] MIN_INT MAX_INT - set scanstring [format {%o %o %o} -1 $MIN_INT $MAX_INT] - list [scan $scanstring {%o %o %o} a b c] \ + set scanstring [format {%lo %lo %lo} -1 $MIN_INT $MAX_INT] + list [scan $scanstring {%lo %lo %lo} a b c] \ [expr { $a == -1 }] [expr { $b == $MIN_INT }] [expr { $c == $MAX_INT }] } {3 1 1 1} test scan-4.63 {scanning of large and negative hex integers} { lassign [int_range] MIN_INT MAX_INT - set scanstring [format {%x %x %x} -1 $MIN_INT $MAX_INT] - list [scan $scanstring {%x %x %x} a b c] \ + set scanstring [format {%lx %lx %lx} -1 $MIN_INT $MAX_INT] + list [scan $scanstring {%lx %lx %lx} a b c] \ [expr { $a == -1 }] [expr { $b == $MIN_INT }] [expr { $c == $MAX_INT }] } {3 1 1 1} test scan-4.64 {scanning of hex with %X} { diff --git a/tests/string.test b/tests/string.test index 81588ff..a0eaac8 100644 --- a/tests/string.test +++ b/tests/string.test @@ -674,9 +674,9 @@ test string-6.53.$noComp {string is integer, true with whitespace} { test string-6.54.$noComp {string is integer, false} { list [run {string is integer -fail var 123abc}] $var } {0 3} -test string-6.55.$noComp {string is integer, false on overflow} { - list [run {string is integer -fail var +[largest_int]0}] $var -} {0 -1} +test string-6.55.$noComp {string is integer, no overflow possible} { + run {string is integer +[largest_int]0} +} 1 test string-6.56.$noComp {string is integer, false} { list [run {string is integer -fail var [expr double(1)]}] $var } {0 1} @@ -807,22 +807,22 @@ test string-6.91.$noComp {string is double, bad doubles} { } return $result } {1 1 0 0 0 1 0 0} -test string-6.92.$noComp {string is integer, 64-bit overflow} { +test string-6.92.$noComp {string is integer, no 64-bit overflow} { # Bug 718878 set x 0x10000000000000000 - list [run {string is integer -failindex var $x}] $var -} {0 -1} -test string-6.93.$noComp {string is integer, 64-bit overflow} { + run {string is integer $x} +} 1 +test string-6.93.$noComp {string is integer, no 64-bit overflow} { # Bug 718878 set x 0x10000000000000000 append x "" - list [run {string is integer -failindex var $x}] $var -} {0 -1} -test string-6.94.$noComp {string is integer, 64-bit overflow} { + run {string is integer $x} +} 1 +test string-6.94.$noComp {string is integer, no 64-bit overflow} { # Bug 718878 set x 0x10000000000000000 - list [run {string is integer -failindex var [expr {$x}]}] $var -} {0 -1} + run {string is integer [expr {$x}]} +} 1 test string-6.95.$noComp {string is wideinteger, true} { run {string is wideinteger +1234567890} } 1 -- cgit v0.12 From db610f91eb22c4b49768bf828b6cd6a35dbb98f1 Mon Sep 17 00:00:00 2001 From: sebres Date: Wed, 29 Aug 2018 15:49:19 +0000 Subject: code review after merge with 8.5 (restore usage of some functions, after lost by conflict resolving) --- win/tclWinPipe.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/win/tclWinPipe.c b/win/tclWinPipe.c index be9d920..dd54a27 100644 --- a/win/tclWinPipe.c +++ b/win/tclWinPipe.c @@ -1473,7 +1473,7 @@ QuoteCmdLineBackslash( Tcl_DStringAppend(dsPtr, start, (int) (bspos - start)); } while (bspos++ < current) { /* each backslash twice */ - Tcl_DStringAppend(dsPtr, "\\\\", 2); + TclDStringAppendLiteral(dsPtr, "\\\\"); } } } @@ -1501,7 +1501,7 @@ QuoteCmdLinePart( * so `\` remains `\`, but important - not at end of part, because results as * before the quote, so `%\%\` should be escaped as `"%\%"\\`). */ - Tcl_DStringAppend(dsPtr, "\"", 1); /* opening escape quote-char */ + TclDStringAppendLiteral(dsPtr, "\""); /* opening escape quote-char */ do { *bspos = NULL; special++; @@ -1518,7 +1518,7 @@ QuoteCmdLinePart( /* unescaped rest before first backslash (rather belongs to the main block) */ QuoteCmdLineBackslash(dsPtr, start, *bspos, NULL); } - Tcl_DStringAppend(dsPtr, "\"", 1); /* closing escape quote-char */ + TclDStringAppendLiteral(dsPtr, "\""); /* closing escape quote-char */ return special; } @@ -1553,9 +1553,9 @@ BuildCommandLine( * Prime the path. Add a space separator if we were primed with something. */ - Tcl_DStringAppend(&ds, Tcl_DStringValue(linePtr), -1); + TclDStringAppendDString(&ds, linePtr); if (Tcl_DStringLength(linePtr) > 0) { - Tcl_DStringAppend(&ds, " ", 1); + TclDStringAppendLiteral(&ds, " "); } for (i = 0; i < argc; i++) { @@ -1563,7 +1563,7 @@ BuildCommandLine( arg = executable; } else { arg = argv[i]; - Tcl_DStringAppend(&ds, " ", 1); + TclDStringAppendLiteral(&ds, " "); } quote &= ~(CL_ESCAPE|CL_QUOTE); /* reset escape flags */ @@ -1609,7 +1609,7 @@ BuildCommandLine( } if (quote & CL_QUOTE) { /* start of argument (main opening quote-char) */ - Tcl_DStringAppend(&ds, "\"", 1); + TclDStringAppendLiteral(&ds, "\""); } if (!(quote & CL_ESCAPE)) { /* nothing to escape */ @@ -1630,7 +1630,7 @@ BuildCommandLine( QuoteCmdLineBackslash(&ds, start, special, bspos); bspos = NULL; /* escape using backslash */ - Tcl_DStringAppend(&ds, "\\\"", 2); + TclDStringAppendLiteral(&ds, "\\\""); start = ++special; continue; } @@ -1658,7 +1658,7 @@ BuildCommandLine( } if (quote & CL_QUOTE) { /* end of argument (main closing quote-char) */ - Tcl_DStringAppend(&ds, "\"", 1); + TclDStringAppendLiteral(&ds, "\""); } } Tcl_DStringFree(linePtr); -- cgit v0.12 From 265c9d416fb1297d507560a8bd9651c02e042b22 Mon Sep 17 00:00:00 2001 From: sebres Date: Wed, 29 Aug 2018 15:55:13 +0000 Subject: partially cherry-picking of [5099a81b50], never reached 8.6, so for example build for MINGW breaks tests winpipe-8.1 etc, because "*" will be expanded. --- win/tclAppInit.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/win/tclAppInit.c b/win/tclAppInit.c index e06eaf5..9c919fc 100644 --- a/win/tclAppInit.c +++ b/win/tclAppInit.c @@ -29,6 +29,10 @@ extern Tcl_PackageInitProc Tcltest_Init; extern Tcl_PackageInitProc Tcltest_SafeInit; #endif /* TCL_TEST */ +#if defined(__GNUC__) +int _CRT_glob = 0; +#endif /* __GNUC__ */ + #if defined(STATIC_BUILD) && TCL_USE_STATIC_PACKAGES extern Tcl_PackageInitProc Registry_Init; extern Tcl_PackageInitProc Dde_Init; -- cgit v0.12 From 2f19b0f34600e566052137a580db0921e83332c7 Mon Sep 17 00:00:00 2001 From: sebres Date: Wed, 29 Aug 2018 16:55:36 +0000 Subject: small amend to [cae24931ed] (no _CRT_glob in both cases __GNUC__ || TCL_BROKEN_MAINARGS). --- win/tclAppInit.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/win/tclAppInit.c b/win/tclAppInit.c index 9c919fc..2236da3 100644 --- a/win/tclAppInit.c +++ b/win/tclAppInit.c @@ -29,18 +29,16 @@ extern Tcl_PackageInitProc Tcltest_Init; extern Tcl_PackageInitProc Tcltest_SafeInit; #endif /* TCL_TEST */ -#if defined(__GNUC__) -int _CRT_glob = 0; -#endif /* __GNUC__ */ - #if defined(STATIC_BUILD) && TCL_USE_STATIC_PACKAGES extern Tcl_PackageInitProc Registry_Init; extern Tcl_PackageInitProc Dde_Init; extern Tcl_PackageInitProc Dde_SafeInit; #endif -#ifdef TCL_BROKEN_MAINARGS +#if defined(__GNUC__) || defined(TCL_BROKEN_MAINARGS) int _CRT_glob = 0; +#endif /* __GNUC__ || TCL_BROKEN_MAINARGS */ +#ifdef TCL_BROKEN_MAINARGS static void setargv(int *argcPtr, TCHAR ***argvPtr); #endif /* TCL_BROKEN_MAINARGS */ -- cgit v0.12 From 9cec6bac276f8925b60a49891c272be0b5e3e3f3 Mon Sep 17 00:00:00 2001 From: sebres Date: Wed, 29 Aug 2018 16:58:06 +0000 Subject: tcltest: forgotten built-in constraint "slowTest" --- tests/tcltest.test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/tcltest.test b/tests/tcltest.test index d513856..028d4fa 100644 --- a/tests/tcltest.test +++ b/tests/tcltest.test @@ -311,7 +311,7 @@ test tcltest-5.5 {InitConstraints: list of built-in constraints} \ -result [lsort { 95 98 asyncPipeClose eformat emptyTest exec hasIsoLocale interactive knownBug mac macCrash macOnly macOrPc macOrUnix macOrWin nonBlockFiles - nonPortable notRoot nt pc pcCrash pcOnly root singleTestInterp socket + nonPortable notRoot nt pc pcCrash pcOnly root singleTestInterp slowTest socket stdio tempNotMac tempNotPc tempNotUnix tempNotWin unix unixCrash unixExecs unixOnly unixOrPc unixOrWin userInteraction win winCrash winOnly }] -- cgit v0.12 From c8e7bb76530d11a14efed5988023df2341f51595 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 29 Aug 2018 19:30:37 +0000 Subject: Fix compilation on 32-bit platforms, and fix unit-tests in this environment --- generic/tclObj.c | 6 +++--- tests/compExpr-old.test | 9 +++------ tests/expr.test | 35 ++++++++++++++++------------------- tests/get.test | 2 +- 4 files changed, 23 insertions(+), 29 deletions(-) diff --git a/generic/tclObj.c b/generic/tclObj.c index 75f9cb7..d9d9ca9 100644 --- a/generic/tclObj.c +++ b/generic/tclObj.c @@ -2814,11 +2814,11 @@ Tcl_GetLongFromObj( if ( #if !defined(TCL_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9 - w <= (Tcl_WideInt)(ULONG_MAX)) { + (w <= (Tcl_WideInt)(ULONG_MAX)) #else - w <= (Tcl_WideInt)(LONG_MAX)) { + (w <= (Tcl_WideInt)(LONG_MAX)) #endif - && w >= (Tcl_WideInt)(LONG_MIN) + && (w >= (Tcl_WideInt)(LONG_MIN))) { *longPtr = Tcl_WideAsLong(w); return TCL_OK; } diff --git a/tests/compExpr-old.test b/tests/compExpr-old.test index 9dfe4c4..c80810c 100644 --- a/tests/compExpr-old.test +++ b/tests/compExpr-old.test @@ -332,15 +332,12 @@ test compExpr-old-9.2 {CompileRelationalExpr: just shift expr} {expr 0xff>>2} 63 test compExpr-old-9.3 {CompileRelationalExpr: just shift expr} {expr -1>>2} -1 test compExpr-old-9.4 {CompileRelationalExpr: just shift expr} {expr {1<<3}} 8 -# The following test is different for 32-bit versus 64-bit -# architectures because LONG_MIN is different +# The following test is no longer different for 32-bit versus 64-bit +# architectures -test compExpr-old-9.5a {CompileRelationalExpr: shift expr producing LONG_MIN} longIs64bit { +test compExpr-old-9.5 {CompileRelationalExpr: shift expr producing LONG_MIN} { expr {int(1<<63)} } 9223372036854775808 -test compExpr-old-9.5b {CompileRelationalExpr: shift expr producing LONG_MIN} longIs32bit { - expr {int(1<<31)} -} -2147483648 test compExpr-old-9.6 {CompileRelationalExpr: error in shift expr} -body { expr x>>3 diff --git a/tests/expr.test b/tests/expr.test index 913df1b..3784fa8 100644 --- a/tests/expr.test +++ b/tests/expr.test @@ -417,12 +417,9 @@ test expr-9.1 {CompileRelationalExpr: just shift expr} {expr 3<<2} 12 test expr-9.2 {CompileRelationalExpr: just shift expr} {expr 0xff>>2} 63 test expr-9.3 {CompileRelationalExpr: just shift expr} {expr -1>>2} -1 test expr-9.4 {CompileRelationalExpr: just shift expr} {expr {1<<3}} 8 -test expr-9.5a {CompileRelationalExpr: shift expr producing LONG_MIN} longIs64bit { +test expr-9.5 {CompileRelationalExpr: shift expr producing LONG_MIN} { expr {int(1<<63)} } 9223372036854775808 -test expr-9.5b {CompileRelationalExpr: shift expr producing LONG_MIN} longIs32bit { - expr {int(1<<31)} -} -2147483648 test expr-9.6 {CompileRelationalExpr: error in shift expr} -body { expr x>>3 } -returnCodes error -match glob -result * @@ -1405,8 +1402,8 @@ test expr-24.1 {expr edge cases; shifting} {expr int(5)>>32} 0 test expr-24.2 {expr edge cases; shifting} {expr int(5)>>63} 0 test expr-24.3 {expr edge cases; shifting} {expr wide(5)>>32} 0 test expr-24.4 {expr edge cases; shifting} {expr wide(5)>>63} 0 -test expr-24.5 {expr edge cases; shifting} longIs32bit {expr int(5<<32)} 0 -test expr-24.6 {expr edge cases; shifting} longIs32bit {expr int(5<<63)} 0 +test expr-24.5 {expr edge cases; shifting} {expr int(5<<32)} 21474836480 +test expr-24.6 {expr edge cases; shifting} {expr int(5<<63)} 46116860184273879040 test expr-24.7 {expr edge cases; shifting} {expr wide(5)<<32} 21474836480 test expr-24.8 {expr edge cases; shifting} {expr wide(10<<63)} 0 test expr-24.9 {expr edge cases; shifting} {expr 5>>32} 0 @@ -5809,7 +5806,7 @@ test expr-32.9 {bignum regression} { expr {0%-(1+(1<<63))} } 0 -test expr-33.1 {parse largest long value} longIs32bit { +test expr-33.1 {parse largest long value} { set max_long_str 2147483647 set max_long_hex "0x7FFFFFFF " @@ -5823,7 +5820,7 @@ test expr-33.1 {parse largest long value} longIs32bit { [expr {$max_long + 0}] \ [expr {2147483647 + 0}] \ [expr {$max_long == $max_long_hex}] \ - [expr {int(2147483647 + 1) < 0}] \ + [expr {int(2147483647 + 1) > 0}] \ } {2147483647 2147483647 2147483647 2147483647 1 1} test expr-33.2 {parse smallest long value} longIs32bit { @@ -5843,7 +5840,7 @@ test expr-33.2 {parse smallest long value} longIs32bit { [expr {$min_long + 0}] \ [expr {-2147483648 + 0}] \ [expr {$min_long == $min_long_hex}] \ - [expr {int(-2147483648 - 1) == 0x7FFFFFFF}] \ + [expr {int(-2147483648 - 1) == -0x80000001}] \ } {-2147483648 -2147483648 -2147483648 -2147483648 1 1} test expr-33.3 {parse largest wide value} wideIs64bit { @@ -5923,17 +5920,17 @@ test expr-34.11 {expr edge cases} { test expr-34.12 {expr edge cases} { expr {$min % -2} } {0} -test expr-34.13 {expr edge cases} longIs32bit { +test expr-34.13 {expr edge cases} { expr {int($min / -1)} -} {-2147483648} +} {2147483648} test expr-34.14 {expr edge cases} { expr {$min % -1} } {0} -test expr-34.15 {expr edge cases} longIs32bit { - expr {int($min * -1)} +test expr-34.15 {expr edge cases} { + expr {-int($min * -1)} } $min -test expr-34.16 {expr edge cases} longIs32bit { - expr {int(-$min)} +test expr-34.16 {expr edge cases} { + expr {-int(-$min)} } $min test expr-34.17 {expr edge cases} { expr {$min / 1} @@ -6720,8 +6717,8 @@ test expr-39.8 {Tcl_ExprLongObj handles overflows} testexprlongobj { testexprlongobj -0x80000000 } {This is a result: -2147483648} test expr-39.9 {Tcl_ExprLongObj handles overflows} {testexprlongobj longIs32bit} { - testexprlongobj -0xffffffff -} {This is a result: 1} + testexprlongobj -0x7fffffff +} {This is a result: -2147483647} test expr-39.10 {Tcl_ExprLongObj handles overflows} \ -constraints {testexprlongobj longIs32bit} \ -match glob \ @@ -6746,8 +6743,8 @@ test expr-39.14 {Tcl_ExprLongObj handles overflows} testexprlongobj { testexprlongobj -2147483648. } {This is a result: -2147483648} test expr-39.15 {Tcl_ExprLongObj handles overflows} {testexprlongobj longIs32bit} { - testexprlongobj -4294967295. -} {This is a result: 1} + testexprlongobj -2147483648. +} {This is a result: -2147483648} test expr-39.16 {Tcl_ExprLongObj handles overflows} \ -constraints {testexprlongobj longIs32bit} \ -match glob \ diff --git a/tests/get.test b/tests/get.test index f85bc01..3207d5f 100644 --- a/tests/get.test +++ b/tests/get.test @@ -64,7 +64,7 @@ test get-1.13 {Tcl_GetInt procedure} {testgetint longIs32bit} { } {0 -2} test get-1.14 {Tcl_GetInt procedure} {testgetint longIs32bit} { list [catch {testgetint -4294967294} msg] $msg -} {0 2} +} {1 {integer value too large to represent}} test get-2.1 {Tcl_GetInt procedure} { format %g 1.23 -- cgit v0.12 From 6d88b01d1e2bb2a76d4e0f094f1e895e3b16c859 Mon Sep 17 00:00:00 2001 From: sebres Date: Thu, 30 Aug 2018 11:08:51 +0000 Subject: test-cases to cover quoting of the newline character, and the documentation extended. --- doc/exec.n | 17 +++++++++++++++++ tests/winPipe.test | 30 ++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/doc/exec.n b/doc/exec.n index 3857a71..e40b596 100644 --- a/doc/exec.n +++ b/doc/exec.n @@ -207,6 +207,19 @@ information is instead sent to the console, if one is present, or is discarded. .RS .PP +Note that the current escape resp. quoting of arguments for windows works only +with executables using CommandLineToArgv, CRT-library or similar, as well as +with the windows batch files (excepting the newline, see below). +Although it is the common escape algorithm, but, in fact, the way how the +executable parses the command-line (resp. splits it into single arguments) +is decisive. +.PP +Unfortunately, there is currently no way to supply newline character within +an argument to the batch files (\fB.cmd\fR or \fB.bat\fR) or to the command +processor (\fBcmd.exe /c\fR), because this causes truncation of command-line +(also the argument chain) on the first newline character. +But it works properly with an executable (using CommandLineToArgv, etc). +.PP The Tk console text widget does not provide real standard IO capabilities. Under Tk, when redirecting from standard input, all applications will see an immediate end-of-file; information redirected to standard output or standard @@ -415,6 +428,10 @@ that sometimes pop up: .CE With the file \fIcmp.bat\fR looking something like: .CS +@gcc %* +.CE +or like another variant using single parameters: +.CS @gcc %1 %2 %3 %4 %5 %6 %7 %8 %9 .CE .PP diff --git a/tests/winPipe.test b/tests/winPipe.test index 4385690..6a02147 100644 --- a/tests/winPipe.test +++ b/tests/winPipe.test @@ -348,6 +348,10 @@ proc _testExecArgs {single args} { if {$r ne $e} { append broken "\[ERROR\]: exec [file extension [lindex $cmd 0]] on $args\n -- result:\n$r\n -- expected:\n$e\n" } + if {$single & 8} { + # if test exe only: + break + } } } return $broken @@ -555,6 +559,32 @@ test winpipe-8.5 {BuildCommandLine/parse_cmdline pass-thru: check injection on s unset -nocomplain lst args a map maps } +set injectList { + "test\"\nwhoami" "test\"\"\nwhoami" + "test\"\"\"\nwhoami" "test\"\"\"\"\nwhoami" + "test;\n&echo \"" "\"test;\n&echo \"" + "test\";\n&echo \"" "\"test\";\n&echo \"" + "\"\"test\";\n&echo \"" +} + +test winpipe-8.6 {BuildCommandLine/parse_cmdline pass-thru: check new-line quoted in args} \ +-constraints {win exec} -body { + # test exe only, because currently there is no proper way to escape a new-line char resp. + # to supply a new-line to the batch-files within arguments (command line is truncated). + _testExecArgs 8 \ + [list START {*}$injectList END] \ + [list "START\"" {*}$injectList END] \ + [list START {*}$injectList "\"END"] \ + [list "START\"" {*}$injectList "\"END"] +} -result {} + +test winpipe-8.7 {BuildCommandLine/parse_cmdline pass-thru: check new-line quoted in args (batch)} \ +-constraints {win exec knownBug} -body { + # this will fail if executed batch-file, because currently there is no proper way to escape a new-line char. + _testExecArgs 0 $injectList +} -result {} + + rename _testExecArgs {} # restore old values for env(TMP) and env(TEMP) -- cgit v0.12 From 2f2b7f6ac7122f3b6be07e793e1658cdb5791aa2 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Mon, 3 Sep 2018 12:53:15 +0000 Subject: Eliminate use of wideBiggerThanInt test constraint, since it's the same as {longIs32bit wideIs64bit}. And ... it's name is actually wrong ... Don't use int() any more in any test constraint, since it's semantics might change. We don't want the test constraints to change with it. (See: TIP# 514) Simplify implementation of wideIs64bit test constraint, just testing for 64-bit sign bit is enough. --- generic/tclTest.c | 22 ++++++++++++++++++++++ tests/compExpr-old.test | 4 ++-- tests/execute.test | 2 +- tests/expr-old.test | 3 ++- tests/expr.test | 7 +++---- tests/format.test | 12 +++++------- tests/get.test | 4 ++-- tests/obj.test | 14 +++++++------- tests/platform.test | 14 ++++---------- tests/scan.test | 3 +-- 10 files changed, 49 insertions(+), 36 deletions(-) diff --git a/generic/tclTest.c b/generic/tclTest.c index ac01ecf..48b4761 100644 --- a/generic/tclTest.c +++ b/generic/tclTest.c @@ -293,6 +293,8 @@ static int TestgetassocdataCmd(ClientData dummy, Tcl_Interp *interp, int argc, const char **argv); static int TestgetintCmd(ClientData dummy, Tcl_Interp *interp, int argc, const char **argv); +static int TestlongsizeCmd(ClientData dummy, + Tcl_Interp *interp, int argc, const char **argv); static int TestgetplatformCmd(ClientData dummy, Tcl_Interp *interp, int argc, const char **argv); static int TestgetvarfullnameCmd( @@ -645,6 +647,8 @@ Tcltest_Init( NULL, NULL); Tcl_CreateCommand(interp, "testgetint", TestgetintCmd, NULL, NULL); + Tcl_CreateCommand(interp, "testlongsize", TestlongsizeCmd, + NULL, NULL); Tcl_CreateCommand(interp, "testgetplatform", TestgetplatformCmd, NULL, NULL); Tcl_CreateObjCommand(interp, "testgetvarfullname", @@ -6936,6 +6940,24 @@ TestgetintCmd( } } +/* + * Used for determining sizeof(long) at script level. + */ +static int +TestlongsizeCmd( + ClientData dummy, + Tcl_Interp *interp, + int argc, + const char **argv) +{ + if (argc != 1) { + Tcl_AppendResult(interp, "wrong # args", NULL); + return TCL_ERROR; + } + Tcl_SetObjResult(interp, Tcl_NewIntObj((int)sizeof(long))); + return TCL_OK; +} + static int NREUnwind_callback( ClientData data[], diff --git a/tests/compExpr-old.test b/tests/compExpr-old.test index 0136ccd..798c92a 100644 --- a/tests/compExpr-old.test +++ b/tests/compExpr-old.test @@ -78,8 +78,8 @@ proc testIEEE {} { } testConstraint ieeeFloatingPoint [testIEEE] -testConstraint longIs32bit [expr {int(0x80000000) < 0}] -testConstraint longIs64bit [expr {int(0x8000000000000000) < 0}] +testConstraint longIs32bit [expr {$tcl_platform(wordSize) == 4}] +testConstraint longIs64bit [expr {$tcl_platform(wordSize) == 8}] # procedures used below diff --git a/tests/execute.test b/tests/execute.test index 6c277f8..2c54a71 100644 --- a/tests/execute.test +++ b/tests/execute.test @@ -34,7 +34,7 @@ testConstraint testobj [expr { && [llength [info commands teststringobj]] }] -testConstraint longIs32bit [expr {int(0x80000000) < 0}] +testConstraint longIs32bit [expr {$tcl_platform(wordSize) == 4}] testConstraint testexprlongobj [llength [info commands testexprlongobj]] # Tests for the omnibus TclExecuteByteCode function: diff --git a/tests/expr-old.test b/tests/expr-old.test index a73b77a..3192c74 100644 --- a/tests/expr-old.test +++ b/tests/expr-old.test @@ -22,7 +22,8 @@ catch [list package require -exact Tcltest [info patchlevel]] testConstraint testexprlong [llength [info commands testexprlong]] testConstraint testexprdouble [llength [info commands testexprdouble]] testConstraint testexprstring [llength [info commands testexprstring]] -testConstraint longIs32bit [expr {int(0x80000000) < 0}] +testConstraint longIs32bit [expr {$tcl_platform(wordSize) == 4}] +testConstraint longIs64bit [expr {$tcl_platform(wordSize) == 8}] # Big test for correct ordering of data in [expr] diff --git a/tests/expr.test b/tests/expr.test index 713681a..0762cf2 100644 --- a/tests/expr.test +++ b/tests/expr.test @@ -21,10 +21,9 @@ catch [list package require -exact Tcltest [info patchlevel]] # Determine if "long int" type is a 32 bit number and if the wide # type is a 64 bit number on this machine. -testConstraint longIs32bit [expr {int(0x80000000) < 0}] -testConstraint longIs64bit [expr {int(0x8000000000000000) < 0}] -testConstraint wideIs64bit \ - [expr {(wide(0x80000000) > 0) && (wide(0x8000000000000000) < 0)}] +testConstraint longIs32bit [expr {$tcl_platform(wordSize) == 4}] +testConstraint longIs64bit [expr {$tcl_platform(wordSize) == 8}] +testConstraint wideIs64bit [expr {wide(0x8000000000000000) < 0}] # Big test for correct ordering of data in [expr] diff --git a/tests/format.test b/tests/format.test index cdea545..1bf46a1 100644 --- a/tests/format.test +++ b/tests/format.test @@ -16,11 +16,9 @@ if {[lsearch [namespace children] ::tcltest] == -1} { } # %u output depends on word length, so this test is not portable. -testConstraint longIs32bit [expr {int(0x80000000) < 0}] -testConstraint longIs64bit [expr {int(0x8000000000000000) < 0}] -testConstraint wideIs64bit \ - [expr {(wide(0x80000000) > 0) && (wide(0x8000000000000000) < 0)}] -testConstraint wideBiggerThanInt [expr {wide(0x80000000) != int(0x80000000)}] +testConstraint longIs32bit [expr {$tcl_platform(wordSize) == 4}] +testConstraint longIs64bit [expr {$tcl_platform(wordSize) == 8}] +testConstraint wideIs64bit [expr {wide(0x8000000000000000) < 0}] testConstraint pointerIs64bit [expr {$tcl_platform(pointerSize) >= 8}] test format-1.1 {integer formatting} { @@ -547,7 +545,7 @@ for {set i 290} {$i < 400} {incr i} { append b "x" } -test format-17.1 {testing %d with wide} {wideIs64bit wideBiggerThanInt} { +test format-17.1 {testing %d with wide} {longIs32bit wideIs64bit} { format %d 7810179016327718216 } 1819043144 test format-17.2 {testing %ld with wide} {wideIs64bit} { @@ -580,7 +578,7 @@ test format-18.1 {do not demote existing numeric values} { format %08x $b lappend result [expr {$a == $b}] } {1 1 1 1} -test format-18.2 {do not demote existing numeric values} {wideBiggerThanInt} { +test format-18.2 {do not demote existing numeric values} {longIs32bit wideIs64bit} { set a [expr {0xaaaaaaaaaa + 1}] set b 0xaaaaaaaaab list [format %08x $a] [expr {$a == $b}] diff --git a/tests/get.test b/tests/get.test index d6a7206..c381098 100644 --- a/tests/get.test +++ b/tests/get.test @@ -20,8 +20,8 @@ catch [list package require -exact Tcltest [info patchlevel]] testConstraint testgetint [llength [info commands testgetint]] testConstraint testdoubleobj [llength [info commands testdoubleobj]] -testConstraint longIs32bit [expr {int(0x80000000) < 0}] -testConstraint longIs64bit [expr {int(0x8000000000000000) < 0}] +testConstraint longIs32bit [expr {$tcl_platform(wordSize) == 4}] +testConstraint longIs64bit [expr {$tcl_platform(wordSize) == 8}] test get-1.1 {Tcl_GetInt procedure} testgetint { testgetint 44 { 22} diff --git a/tests/obj.test b/tests/obj.test index cb62d3f..d407669 100644 --- a/tests/obj.test +++ b/tests/obj.test @@ -20,8 +20,8 @@ if {[lsearch [namespace children] ::tcltest] == -1} { catch [list package require -exact Tcltest [info patchlevel]] testConstraint testobj [llength [info commands testobj]] -testConstraint longIs32bit [expr {int(0x80000000) < 0}] -testConstraint wideBiggerThanInt [expr {wide(0x80000000) != int(0x80000000)}] +testConstraint longIs32bit [expr {$tcl_platform(wordSize) == 4}] +testConstraint wideIs64bit [expr {wide(0x8000000000000000) < 0}] test obj-1.1 {Tcl_AppendAllObjTypes, and InitTypeTable, Tcl_RegisterObjType} testobj { set r 1 @@ -549,11 +549,11 @@ test obj-32.1 {freeing very large object trees} { unset x } {} -test obj-33.1 {integer overflow on input} {longIs32bit wideBiggerThanInt} { +test obj-33.1 {integer overflow on input} {longIs32bit wideIs64bit} { set x 0x8000; append x 0000 list [string is integer $x] [expr { wide($x) }] } {1 2147483648} -test obj-33.2 {integer overflow on input} {longIs32bit wideBiggerThanInt} { +test obj-33.2 {integer overflow on input} {longIs32bit wideIs64bit} { set x 0xffff; append x ffff list [string is integer $x] [expr { wide($x) }] } {1 4294967295} @@ -561,15 +561,15 @@ test obj-33.3 {integer overflow on input} { set x 0x10000; append x 0000 list [string is integer $x] [expr { wide($x) }] } {0 4294967296} -test obj-33.4 {integer overflow on input} {longIs32bit wideBiggerThanInt} { +test obj-33.4 {integer overflow on input} {longIs32bit wideIs64bit} { set x -0x8000; append x 0000 list [string is integer $x] [expr { wide($x) }] } {1 -2147483648} -test obj-33.5 {integer overflow on input} {longIs32bit wideBiggerThanInt} { +test obj-33.5 {integer overflow on input} {longIs32bit wideIs64bit} { set x -0x8000; append x 0001 list [string is integer $x] [expr { wide($x) }] } {1 -2147483649} -test obj-33.6 {integer overflow on input} {longIs32bit wideBiggerThanInt} { +test obj-33.6 {integer overflow on input} {longIs32bit wideIs64bit} { set x -0xffff; append x ffff list [string is integer $x] [expr { wide($x) }] } {1 -4294967295} diff --git a/tests/platform.test b/tests/platform.test index fa533e8..5880fb9 100644 --- a/tests/platform.test +++ b/tests/platform.test @@ -25,6 +25,7 @@ namespace eval ::tcl::test::platform { catch [list package require -exact Tcltest [info patchlevel]] testConstraint testCPUID [llength [info commands testcpuid]] +testConstraint testlongsize [llength [info commands testlongsize]] test platform-1.0 {tcl_platform(engine)} { set tcl_platform(engine) @@ -39,16 +40,9 @@ test platform-1.1 {TclpSetVariables: tcl_platform} { set result } {byteOrder engine machine os osVersion pathSeparator platform pointerSize user wordSize} -# Test assumes twos-complement arithmetic, which is true of virtually -# everything these days. Note that this does *not* use wide(), and -# this is intentional since that could make Tcl's numbers wider than -# the machine-integer on some platforms... -test platform-2.1 {tcl_platform(wordSize) indicates size of native word} { - set result [expr {int(1 << (8 * $tcl_platform(wordSize) - 1))}] - # Result must be the largest bit in a machine word, which this checks - # without assuming how wide the word really is - list [expr {$result < 0}] [expr {$result ^ int($result - 1)}] -} {1 -1} +test platform-2.1 {tcl_platform(wordSize) indicates size of native word} testlongsize { + expr {$tcl_platform(wordSize) == [testlongsize]} +} {1} # On Windows/UNIX, test that the CPU ID works diff --git a/tests/scan.test b/tests/scan.test index 1f32b9f..5c38fff 100644 --- a/tests/scan.test +++ b/tests/scan.test @@ -85,8 +85,7 @@ proc testIEEE {} { } testConstraint ieeeFloatingPoint [testIEEE] -testConstraint wideIs64bit \ - [expr {(wide(0x80000000) > 0) && (wide(0x8000000000000000) < 0)}] +testConstraint wideIs64bit [expr {wide(0x8000000000000000) < 0}] test scan-1.1 {BuildCharSet, CharInSet} { list [scan foo {%[^o]} x] $x -- cgit v0.12 From fdf1df3b29531c5031a33f2e3c1f4668937c1c5f Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Tue, 4 Sep 2018 14:37:01 +0000 Subject: Fix [540bed4bde]: binary format can result in "integer value too large to represent". Implemented a new utility function TclGetWideBitsFromObj(), which handles the overflowing of integers using bignums. This function can be used in a _LOT_ of other places, preventing code duplication. Done that as well. Those changes have no effect on other commands, only two new "binary format" test-cases for this specific situation: binary-44.5 and binary-44.6 --- generic/tclBasic.c | 55 ++++++-------------------------------- generic/tclBinary.c | 35 ++++++++++++------------ generic/tclCmdAH.c | 8 +++--- generic/tclInt.h | 2 ++ generic/tclObj.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++--- generic/tclStringObj.c | 26 +++--------------- tests/binary.test | 41 +++++++++++++++++----------- 7 files changed, 129 insertions(+), 110 deletions(-) diff --git a/generic/tclBasic.c b/generic/tclBasic.c index 93776dc..0190c13 100644 --- a/generic/tclBasic.c +++ b/generic/tclBasic.c @@ -7680,27 +7680,14 @@ ExprIntFunc( int objc, /* Actual parameter count. */ Tcl_Obj *const *objv) /* Actual parameter vector. */ { - long iResult; + Tcl_WideInt wResult; Tcl_Obj *objPtr; if (ExprEntierFunc(NULL, interp, objc, objv) != TCL_OK) { return TCL_ERROR; } objPtr = Tcl_GetObjResult(interp); - if (TclGetLongFromObj(NULL, objPtr, &iResult) != TCL_OK) { - /* - * Truncate the bignum; keep only bits in long range. - */ - - mp_int big; - - Tcl_GetBignumFromObj(NULL, objPtr, &big); - mp_mod_2d(&big, (int) CHAR_BIT * sizeof(long), &big); - objPtr = Tcl_NewBignumObj(&big); - Tcl_IncrRefCount(objPtr); - TclGetLongFromObj(NULL, objPtr, &iResult); - Tcl_DecrRefCount(objPtr); - } - Tcl_SetObjResult(interp, Tcl_NewLongObj(iResult)); + TclGetWideBitsFromObj(NULL, objPtr, &wResult); + Tcl_SetObjResult(interp, Tcl_NewLongObj((long)wResult)); return TCL_OK; } @@ -7719,20 +7706,7 @@ ExprWideFunc( return TCL_ERROR; } objPtr = Tcl_GetObjResult(interp); - if (TclGetWideIntFromObj(NULL, objPtr, &wResult) != TCL_OK) { - /* - * Truncate the bignum; keep only bits in wide int range. - */ - - mp_int big; - - Tcl_GetBignumFromObj(NULL, objPtr, &big); - mp_mod_2d(&big, (int) CHAR_BIT * sizeof(Tcl_WideInt), &big); - objPtr = Tcl_NewBignumObj(&big); - Tcl_IncrRefCount(objPtr); - TclGetWideIntFromObj(NULL, objPtr, &wResult); - Tcl_DecrRefCount(objPtr); - } + TclGetWideBitsFromObj(NULL, objPtr, &wResult); Tcl_SetObjResult(interp, Tcl_NewWideIntObj(wResult)); return TCL_OK; } @@ -7979,7 +7953,7 @@ ExprSrandFunc( Tcl_Obj *const *objv) /* Parameter vector. */ { Interp *iPtr = (Interp *) interp; - long i = 0; /* Initialized to avoid compiler warning. */ + Tcl_WideInt w = 0; /* Initialized to avoid compiler warning. */ /* * Convert argument and use it to reset the seed. @@ -7990,20 +7964,8 @@ ExprSrandFunc( return TCL_ERROR; } - if (TclGetLongFromObj(NULL, objv[1], &i) != TCL_OK) { - Tcl_Obj *objPtr; - mp_int big; - - if (Tcl_GetBignumFromObj(interp, objv[1], &big) != TCL_OK) { - /* TODO: more ::errorInfo here? or in caller? */ - return TCL_ERROR; - } - - mp_mod_2d(&big, (int) CHAR_BIT * sizeof(long), &big); - objPtr = Tcl_NewBignumObj(&big); - Tcl_IncrRefCount(objPtr); - TclGetLongFromObj(NULL, objPtr, &i); - Tcl_DecrRefCount(objPtr); + if (TclGetWideBitsFromObj(NULL, objv[1], &w) != TCL_OK) { + return TCL_ERROR; } /* @@ -8012,8 +7974,7 @@ ExprSrandFunc( */ iPtr->flags |= RAND_SEED_INITIALIZED; - iPtr->randSeed = i; - iPtr->randSeed &= (unsigned long) 0x7fffffff; + iPtr->randSeed = (unsigned long) (w & 0x7fffffff); if ((iPtr->randSeed == 0) || (iPtr->randSeed == 0x7fffffff)) { iPtr->randSeed ^= 123459876; } diff --git a/generic/tclBinary.c b/generic/tclBinary.c index cb5a5cb..24f228e 100644 --- a/generic/tclBinary.c +++ b/generic/tclBinary.c @@ -1963,7 +1963,6 @@ FormatNumber( Tcl_Obj *src, /* Number to format. */ unsigned char **cursorPtr) /* Pointer to index into destination buffer. */ { - long value; double dvalue; Tcl_WideInt wvalue; float fvalue; @@ -2025,7 +2024,7 @@ FormatNumber( case 'w': case 'W': case 'm': - if (Tcl_GetWideIntFromObj(interp, src, &wvalue) != TCL_OK) { + if (TclGetWideBitsFromObj(interp, src, &wvalue) != TCL_OK) { return TCL_ERROR; } if (NeedReversing(type)) { @@ -2055,19 +2054,19 @@ FormatNumber( case 'i': case 'I': case 'n': - if (TclGetLongFromObj(interp, src, &value) != TCL_OK) { + if (TclGetWideBitsFromObj(interp, src, &wvalue) != TCL_OK) { return TCL_ERROR; } if (NeedReversing(type)) { - *(*cursorPtr)++ = UCHAR(value); - *(*cursorPtr)++ = UCHAR(value >> 8); - *(*cursorPtr)++ = UCHAR(value >> 16); - *(*cursorPtr)++ = UCHAR(value >> 24); + *(*cursorPtr)++ = UCHAR(wvalue); + *(*cursorPtr)++ = UCHAR(wvalue >> 8); + *(*cursorPtr)++ = UCHAR(wvalue >> 16); + *(*cursorPtr)++ = UCHAR(wvalue >> 24); } else { - *(*cursorPtr)++ = UCHAR(value >> 24); - *(*cursorPtr)++ = UCHAR(value >> 16); - *(*cursorPtr)++ = UCHAR(value >> 8); - *(*cursorPtr)++ = UCHAR(value); + *(*cursorPtr)++ = UCHAR(wvalue >> 24); + *(*cursorPtr)++ = UCHAR(wvalue >> 16); + *(*cursorPtr)++ = UCHAR(wvalue >> 8); + *(*cursorPtr)++ = UCHAR(wvalue); } return TCL_OK; @@ -2077,15 +2076,15 @@ FormatNumber( case 's': case 'S': case 't': - if (TclGetLongFromObj(interp, src, &value) != TCL_OK) { + if (TclGetWideBitsFromObj(interp, src, &wvalue) != TCL_OK) { return TCL_ERROR; } if (NeedReversing(type)) { - *(*cursorPtr)++ = UCHAR(value); - *(*cursorPtr)++ = UCHAR(value >> 8); + *(*cursorPtr)++ = UCHAR(wvalue); + *(*cursorPtr)++ = UCHAR(wvalue >> 8); } else { - *(*cursorPtr)++ = UCHAR(value >> 8); - *(*cursorPtr)++ = UCHAR(value); + *(*cursorPtr)++ = UCHAR(wvalue >> 8); + *(*cursorPtr)++ = UCHAR(wvalue); } return TCL_OK; @@ -2093,10 +2092,10 @@ FormatNumber( * 8-bit integer values. */ case 'c': - if (TclGetLongFromObj(interp, src, &value) != TCL_OK) { + if (TclGetWideBitsFromObj(interp, src, &wvalue) != TCL_OK) { return TCL_ERROR; } - *(*cursorPtr)++ = UCHAR(value); + *(*cursorPtr)++ = UCHAR(wvalue); return TCL_OK; default: diff --git a/generic/tclCmdAH.c b/generic/tclCmdAH.c index 810fac6..94cb8aa 100644 --- a/generic/tclCmdAH.c +++ b/generic/tclCmdAH.c @@ -1398,9 +1398,9 @@ FileAttrAccessTimeCmd( * platforms. [Bug 698146] */ - long newTime; + Tcl_WideInt newTime; - if (TclGetLongFromObj(interp, objv[2], &newTime) != TCL_OK) { + if (TclGetWideIntFromObj(interp, objv[2], &newTime) != TCL_OK) { return TCL_ERROR; } @@ -1479,9 +1479,9 @@ FileAttrModifyTimeCmd( * platforms. [Bug 698146] */ - long newTime; + Tcl_WideInt newTime; - if (TclGetLongFromObj(interp, objv[2], &newTime) != TCL_OK) { + if (TclGetWideIntFromObj(interp, objv[2], &newTime) != TCL_OK) { return TCL_ERROR; } diff --git a/generic/tclInt.h b/generic/tclInt.h index 5379396..e8fecf0 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -3041,6 +3041,8 @@ MODULE_SCOPE char * TclGetStringStorage(Tcl_Obj *objPtr, MODULE_SCOPE int TclGetLoadedPackagesEx(Tcl_Interp *interp, const char *targetName, const char *packageName); +MODULE_SCOPE int TclGetWideBitsFromObj(Tcl_Interp *, Tcl_Obj *, + Tcl_WideInt *); MODULE_SCOPE int TclGlob(Tcl_Interp *interp, char *pattern, Tcl_Obj *unquotedPrefix, int globFlags, Tcl_GlobTypeData *types); diff --git a/generic/tclObj.c b/generic/tclObj.c index 16ef7c3..490e80e 100644 --- a/generic/tclObj.c +++ b/generic/tclObj.c @@ -2833,10 +2833,9 @@ Tcl_GetLongFromObj( mp_int big; UNPACK_BIGNUM(objPtr, big); - if ((size_t) big.used <= (CHAR_BIT * sizeof(long) + DIGIT_BIT - 1) + if ((size_t) big.used <= (CHAR_BIT * sizeof(unsigned long) + DIGIT_BIT - 1) / DIGIT_BIT) { - unsigned long value = 0, numBytes = sizeof(long); - long scratch; + unsigned long scratch, value = 0, numBytes = sizeof(unsigned long); unsigned char *bytes = (unsigned char *) &scratch; if (mp_to_unsigned_bin_n(&big, bytes, &numBytes) == MP_OKAY) { @@ -3107,6 +3106,73 @@ Tcl_GetWideIntFromObj( /* *---------------------------------------------------------------------- * + * TclGetWideBitsFromObj -- + * + * Attempt to return a wide integer from the Tcl object "objPtr". If the + * object is not already a int, double or bignum, an attempt will be made + * to convert it to one of these. Out-of-range values don't result in an + * error, but only the least significant 64 bits will be returned. + * + * Results: + * The return value is a standard Tcl object result. If an error occurs + * during conversion, an error message is left in the interpreter's + * result unless "interp" is NULL. + * + * Side effects: + * If the object is not already an int, double or bignum object, the + * conversion will free any old internal representation. + * + *---------------------------------------------------------------------- + */ + +int +TclGetWideBitsFromObj( + Tcl_Interp *interp, /* Used for error reporting if not NULL. */ + Tcl_Obj *objPtr, /* Object from which to get a wide int. */ + Tcl_WideInt *wideIntPtr) /* Place to store resulting wide integer. */ +{ + do { + if (objPtr->typePtr == &tclIntType) { + *wideIntPtr = objPtr->internalRep.wideValue; + return TCL_OK; + } + if (objPtr->typePtr == &tclDoubleType) { + if (interp != NULL) { + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "expected integer but got \"%s\"", + TclGetString(objPtr))); + Tcl_SetErrorCode(interp, "TCL", "VALUE", "INTEGER", NULL); + } + return TCL_ERROR; + } + if (objPtr->typePtr == &tclBignumType) { + mp_int big; + + Tcl_WideUInt value = 0, scratch; + unsigned long numBytes = sizeof(Tcl_WideInt); + unsigned char *bytes = (unsigned char *) &scratch; + + Tcl_GetBignumFromObj(NULL, objPtr, &big); + mp_mod_2d(&big, (int) (CHAR_BIT * sizeof(Tcl_WideInt)), &big); + mp_to_unsigned_bin_n(&big, bytes, &numBytes); + while (numBytes-- > 0) { + value = (value << CHAR_BIT) | *bytes++; + } + if (big.sign) { + value = -value; + } + *wideIntPtr = (Tcl_WideInt) value; + mp_clear(&big); + return TCL_OK; + } + } while (TclParseNumber(interp, objPtr, "integer", NULL, -1, NULL, + TCL_PARSE_INTEGER_ONLY)==TCL_OK); + return TCL_ERROR; +} + +/* + *---------------------------------------------------------------------- + * * FreeBignum -- * * This function frees the internal rep of a bignum. diff --git a/generic/tclStringObj.c b/generic/tclStringObj.c index f98180f..f238268 100644 --- a/generic/tclStringObj.c +++ b/generic/tclStringObj.c @@ -2097,33 +2097,15 @@ Tcl_AppendFormatToObj( } #ifndef TCL_WIDE_INT_IS_LONG } else if (useWide) { - if (TclGetWideIntFromObj(NULL, segment, &w) != TCL_OK) { - Tcl_Obj *objPtr; - - if (Tcl_GetBignumFromObj(interp,segment,&big) != TCL_OK) { - goto error; - } - mp_mod_2d(&big, (int) CHAR_BIT*sizeof(Tcl_WideInt), &big); - objPtr = Tcl_NewBignumObj(&big); - Tcl_IncrRefCount(objPtr); - TclGetWideIntFromObj(NULL, objPtr, &w); - Tcl_DecrRefCount(objPtr); + if (TclGetWideBitsFromObj(interp, segment, &w) != TCL_OK) { + goto error; } isNegative = (w < (Tcl_WideInt) 0); if (w == (Tcl_WideInt) 0) gotHash = 0; #endif } else if (TclGetLongFromObj(NULL, segment, &l) != TCL_OK) { - if (TclGetWideIntFromObj(NULL, segment, &w) != TCL_OK) { - Tcl_Obj *objPtr; - - if (Tcl_GetBignumFromObj(interp,segment,&big) != TCL_OK) { - goto error; - } - mp_mod_2d(&big, (int) CHAR_BIT * sizeof(long), &big); - objPtr = Tcl_NewBignumObj(&big); - Tcl_IncrRefCount(objPtr); - TclGetLongFromObj(NULL, objPtr, &l); - Tcl_DecrRefCount(objPtr); + if (TclGetWideBitsFromObj(interp, segment, &w) != TCL_OK) { + goto error; } else { l = Tcl_WideAsLong(w); } diff --git a/tests/binary.test b/tests/binary.test index 1ee815b..54e8e94 100644 --- a/tests/binary.test +++ b/tests/binary.test @@ -1647,22 +1647,6 @@ test binary-43.2 {Tcl_BinaryObjCmd: format wide int} {} { binary format W 7810179016327718216 } lcTolleH -test binary-44.1 {Tcl_BinaryObjCmd: scan wide int} {} { - binary scan HelloTcl W x - set x -} 5216694956358656876 -test binary-44.2 {Tcl_BinaryObjCmd: scan wide int} {} { - binary scan lcTolleH w x - set x -} 5216694956358656876 -test binary-44.3 {Tcl_BinaryObjCmd: scan wide int with bit 31 set} {} { - binary scan [binary format w [expr {wide(3) << 31}]] w x - set x -} 6442450944 -test binary-44.4 {Tcl_BinaryObjCmd: scan wide int with bit 31 set} {} { - binary scan [binary format W [expr {wide(3) << 31}]] W x - set x -} 6442450944 test binary-43.5 {Tcl_BinaryObjCmd: scan wide int} {} { unset -nocomplain arg1 list [binary scan \x80[string repeat \x00 7] W arg1] $arg1 @@ -1684,6 +1668,31 @@ test binary-43.9 {Tcl_BinaryObjCmd: scan unsigned wide int} {} { list [binary scan [string repeat \x00 7]\x80[string repeat \x00 7]\x80 wuw arg1 arg2] $arg1 $arg2 } {2 9223372036854775808 -9223372036854775808} +test binary-44.1 {Tcl_BinaryObjCmd: scan wide int} {} { + binary scan HelloTcl W x + set x +} 5216694956358656876 +test binary-44.2 {Tcl_BinaryObjCmd: scan wide int} {} { + binary scan lcTolleH w x + set x +} 5216694956358656876 +test binary-44.3 {Tcl_BinaryObjCmd: scan wide int with bit 31 set} {} { + binary scan [binary format w [expr {wide(3) << 31}]] w x + set x +} 6442450944 +test binary-44.4 {Tcl_BinaryObjCmd: scan wide int with bit 31 set} {} { + binary scan [binary format W [expr {wide(3) << 31}]] W x + set x +} 6442450944 +test binary-44.5 {Tcl_BinaryObjCmd: scan wide int with bit 31 and 64 set} {} { + binary scan [binary format w [expr {(wide(3) << 31) + (wide(3) << 64)}]] w x + set x +} 6442450944 +test binary-44.6 {Tcl_BinaryObjCmd: scan wide int with bit 31 and 64 set} {} { + binary scan [binary format W [expr {(wide(3) << 31) + (wide(3) << 64)}]] W x + set x +} 6442450944 + test binary-45.1 {Tcl_BinaryObjCmd: combined wide int handling} { binary scan [binary format sws 16450 -1 19521] c* x set x -- cgit v0.12 From 5c9968a001208bb4fc6d06ad040c28bd84b7831f Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 5 Sep 2018 12:11:13 +0000 Subject: Minor code cleanup. win/tclWinPipe.c: Eliminate some compiler warnings on mingw-w64 win/tclWinNotify.c: Eliminate tsdPtr->timeout variable, since it's only being written to. other files: code cleanup, eliminate unnecessary type casts --- generic/tclBasic.c | 8 +++----- generic/tclObj.c | 2 +- win/tclWinNotify.c | 4 +--- win/tclWinPipe.c | 14 +++++++------- 4 files changed, 12 insertions(+), 16 deletions(-) diff --git a/generic/tclBasic.c b/generic/tclBasic.c index 0190c13..71a1442 100644 --- a/generic/tclBasic.c +++ b/generic/tclBasic.c @@ -7700,13 +7700,11 @@ ExprWideFunc( Tcl_Obj *const *objv) /* Actual parameter vector. */ { Tcl_WideInt wResult; - Tcl_Obj *objPtr; if (ExprEntierFunc(NULL, interp, objc, objv) != TCL_OK) { return TCL_ERROR; } - objPtr = Tcl_GetObjResult(interp); - TclGetWideBitsFromObj(NULL, objPtr, &wResult); + TclGetWideBitsFromObj(NULL, Tcl_GetObjResult(interp), &wResult); Tcl_SetObjResult(interp, Tcl_NewWideIntObj(wResult)); return TCL_OK; } @@ -7809,7 +7807,7 @@ ExprRandFunc( * Make sure 1 <= randSeed <= (2^31) - 2. See below. */ - iPtr->randSeed &= (unsigned long) 0x7fffffff; + iPtr->randSeed &= 0x7fffffff; if ((iPtr->randSeed == 0) || (iPtr->randSeed == 0x7fffffff)) { iPtr->randSeed ^= 123459876; } @@ -7974,7 +7972,7 @@ ExprSrandFunc( */ iPtr->flags |= RAND_SEED_INITIALIZED; - iPtr->randSeed = (unsigned long) (w & 0x7fffffff); + iPtr->randSeed = (long) w & 0x7fffffff; if ((iPtr->randSeed == 0) || (iPtr->randSeed == 0x7fffffff)) { iPtr->randSeed ^= 123459876; } diff --git a/generic/tclObj.c b/generic/tclObj.c index 490e80e..ce326fe 100644 --- a/generic/tclObj.c +++ b/generic/tclObj.c @@ -3111,7 +3111,7 @@ Tcl_GetWideIntFromObj( * Attempt to return a wide integer from the Tcl object "objPtr". If the * object is not already a int, double or bignum, an attempt will be made * to convert it to one of these. Out-of-range values don't result in an - * error, but only the least significant 64 bits will be returned. + * error, but only the least significant 64 bits will be returned. * * Results: * The return value is a standard Tcl object result. If an error occurs diff --git a/win/tclWinNotify.c b/win/tclWinNotify.c index 28c8445..b34fc4f 100644 --- a/win/tclWinNotify.c +++ b/win/tclWinNotify.c @@ -36,7 +36,6 @@ typedef struct { int pending; /* Alert message pending, this field is locked * by the notifierMutex. */ HWND hwnd; /* Messaging window. */ - int timeout; /* Current timeout value. */ int timerActive; /* 1 if interval timer is running. */ } ThreadSpecificData; @@ -309,11 +308,10 @@ Tcl_SetTimer( timeout = 1; } } - tsdPtr->timeout = timeout; if (timeout != 0) { tsdPtr->timerActive = 1; SetTimer(tsdPtr->hwnd, INTERVAL_TIMER, - (unsigned long) tsdPtr->timeout, NULL); + timeout, NULL); } else { tsdPtr->timerActive = 0; KillTimer(tsdPtr->hwnd, INTERVAL_TIMER); diff --git a/win/tclWinPipe.c b/win/tclWinPipe.c index cf0b80f..bd95ea4 100644 --- a/win/tclWinPipe.c +++ b/win/tclWinPipe.c @@ -869,7 +869,7 @@ TclpGetPid( Tcl_MutexLock(&pipeMutex); for (infoPtr = procList; infoPtr != NULL; infoPtr = infoPtr->nextPtr) { - if (infoPtr->dwProcessId == (DWORD) pid) { + if (infoPtr->dwProcessId == (DWORD) (size_t) pid) { Tcl_MutexUnlock(&pipeMutex); return infoPtr->dwProcessId; } @@ -1163,7 +1163,7 @@ TclpCreateProcess( WaitForInputIdle(procInfo.hProcess, 5000); CloseHandle(procInfo.hThread); - *pidPtr = (Tcl_Pid) procInfo.dwProcessId; + *pidPtr = (Tcl_Pid) (size_t) procInfo.dwProcessId; if (*pidPtr != 0) { TclWinAddProcess(procInfo.hProcess, procInfo.dwProcessId); } @@ -1478,10 +1478,10 @@ QuoteCmdLinePart( QuoteCmdLineBackslash(dsPtr, start, *bspos, NULL); start = *bspos; } - /* - * escape all special chars enclosed in quotes like `"..."`, note that here we + /* + * escape all special chars enclosed in quotes like `"..."`, note that here we * don't must escape `\` (with `\`), because it's outside of the main quotes, - * so `\` remains `\`, but important - not at end of part, because results as + * so `\` remains `\`, but important - not at end of part, because results as * before the quote, so `%\%\` should be escaped as `"%\%"\\`). */ TclDStringAppendLiteral(dsPtr, "\""); /* opening escape quote-char */ @@ -1636,7 +1636,7 @@ BuildCommandLine( special++; } /* rest of argument (and escape backslashes before closing main quote) */ - QuoteCmdLineBackslash(&ds, start, special, + QuoteCmdLineBackslash(&ds, start, special, (quote & CL_QUOTE) ? bspos : NULL); } if (quote & CL_QUOTE) { @@ -2476,7 +2476,7 @@ Tcl_WaitPid( prevPtrPtr = &procList; for (infoPtr = procList; infoPtr != NULL; prevPtrPtr = &infoPtr->nextPtr, infoPtr = infoPtr->nextPtr) { - if (infoPtr->dwProcessId == (DWORD) pid) { + if (infoPtr->dwProcessId == (DWORD) (size_t) pid) { *prevPtrPtr = infoPtr->nextPtr; break; } -- cgit v0.12 From 3e7ffcaf4bde6d7e7a030c603ff78b586704891b Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Thu, 6 Sep 2018 09:47:30 +0000 Subject: Code review --- generic/tclZipfs.c | 71 +++++++++++++++++++++++++++--------------------------- 1 file changed, 36 insertions(+), 35 deletions(-) diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c index b6c8a00..0ab60e7 100644 --- a/generic/tclZipfs.c +++ b/generic/tclZipfs.c @@ -172,23 +172,23 @@ typedef struct ZipFile { char is_membuf; /* When true, not a file but a memory buffer */ Tcl_Channel chan; /* Channel handle or NULL */ unsigned char *data; /* Memory mapped or malloc'ed file */ - long length; /* Length of memory mapped file */ + size_t length; /* Length of memory mapped file */ unsigned char *tofree; /* Non-NULL if malloc'ed file */ - int nfiles; /* Number of files in archive */ - unsigned long baseoffs; /* Archive start */ - long baseoffsp; /* Password start */ - unsigned long centoffs; /* Archive directory start */ - unsigned char pwbuf[264]; /* Password buffer */ + size_t nfiles; /* Number of files in archive */ + size_t baseoffs; /* Archive start */ + size_t baseoffsp; /* Password start */ + size_t centoffs; /* Archive directory start */ + unsigned char pwbuf[264]; /* Password buffer */ #if defined(_WIN32) || defined(_WIN64) HANDLE mh; #endif - unsigned long nopen; /* Number of open files on archive */ + size_t nopen; /* Number of open files on archive */ struct ZipEntry *entries; /* List of files in archive */ struct ZipEntry *topents; /* List of top-level dirs in archive */ #if HAS_DRIVES int mntdrv; /* Drive letter of mount point */ #endif - int mntptlen; + size_t mntptlen; char *mntpt; /* Mount point */ } ZipFile; @@ -220,9 +220,9 @@ typedef struct ZipEntry { typedef struct ZipChannel { ZipFile *zipfile; /* The ZIP file holding this channel */ ZipEntry *zipentry; /* Pointer back to virtual file */ - unsigned long nmax; /* Max. size for write */ - unsigned long nbyte; /* Number of bytes of uncompressed data */ - unsigned long nread; /* Pos of next byte to be read from the channel */ + size_t nmax; /* Max. size for write */ + size_t nbyte; /* Number of bytes of uncompressed data */ + size_t nread; /* Pos of next byte to be read from the channel */ unsigned char *ubuf; /* Pointer to the uncompressed data */ int iscompr; /* True if data is compressed */ int isdir; /* Set to 1 if directory, or -1 if root */ @@ -907,7 +907,7 @@ ZipFSCloseArchive(Tcl_Interp *interp, ZipFile *zf) static int ZipFS_Find_TOC(Tcl_Interp *interp, int needZip, ZipFile *zf) { - int i; + size_t i; unsigned char *p, *q; p = zf->data + zf->length - ZIP_CENTRAL_END_LEN; while (p >= zf->data) { @@ -1012,7 +1012,7 @@ error: static int ZipFSOpenArchive(Tcl_Interp *interp, const char *zipname, int needZip, ZipFile *zf) { - int i; + size_t i; ClientData handle; zf->namelen=0; zf->is_membuf=0; @@ -1060,7 +1060,7 @@ ZipFSOpenArchive(Tcl_Interp *interp, const char *zipname, int needZip, ZipFile * #if defined(_WIN32) || defined(_WIN64) zf->length = GetFileSize((HANDLE) handle, 0); if ( - (zf->length == INVALID_FILE_SIZE) || + (zf->length == (size_t)INVALID_FILE_SIZE) || (zf->length < ZIP_CENTRAL_END_LEN) ) { ZIPFS_ERROR(interp,"invalid file size"); @@ -1079,7 +1079,7 @@ ZipFSOpenArchive(Tcl_Interp *interp, const char *zipname, int needZip, ZipFile * } #else zf->length = lseek((int) (long) handle, 0, SEEK_END); - if ((zf->length == -1) || (zf->length < ZIP_CENTRAL_END_LEN)) { + if ((zf->length == (size_t)-1) || (zf->length < ZIP_CENTRAL_END_LEN)) { ZIPFS_ERROR(interp,"invalid file size"); goto error; } @@ -1118,15 +1118,13 @@ error: static int ZipFS_Catalogue_Filesystem(Tcl_Interp *interp, ZipFile *zf0, const char *mntpt, const char *passwd, const char *zipname) { - int i, pwlen, isNew; + int pwlen, isNew; + size_t i; ZipFile *zf; ZipEntry *z; Tcl_HashEntry *hPtr; Tcl_DString ds, dsm, fpBuf; unsigned char *q; -#if HAS_DRIVES - int drive = 0; -#endif WriteLock(); pwlen = 0; @@ -1220,7 +1218,8 @@ ZipFS_Catalogue_Filesystem(Tcl_Interp *interp, ZipFile *zf0, const char *mntpt, q = zf->data + zf->centoffs; Tcl_DStringInit(&fpBuf); for (i = 0; i < zf->nfiles; i++) { - int pathlen, comlen, extra, isdir = 0, dosTime, dosDate, nbcompr, offs; + int extra, isdir = 0, dosTime, dosDate, nbcompr; + size_t offs, pathlen, comlen; unsigned char *lq, *gq = NULL; char *fullpath, *path; @@ -2358,8 +2357,7 @@ ZipFSMkZipOrImgObjCmd(ClientData clientData, Tcl_Interp *interp, } if (isMounted || (ZipFSOpenArchive(interp, imgName, 0, zf) == TCL_OK)) { - i = Tcl_Write(out, (char *) zf->data, zf->baseoffsp); - if (i != zf->baseoffsp) { + if ((size_t)Tcl_Write(out, (char *) zf->data, zf->baseoffsp) != zf->baseoffsp) { memset(pwbuf, 0, sizeof (pwbuf)); Tcl_DecrRefCount(list); Tcl_SetObjResult(interp, Tcl_NewStringObj("write error", -1)); @@ -2681,7 +2679,7 @@ ZipFSCanonicalObjCmd( Tcl_SetObjResult(interp,Tcl_NewStringObj(result,-1)); return TCL_OK; } - + /* *------------------------------------------------------------------------- * @@ -2888,7 +2886,11 @@ Tcl_Obj *TclZipfs_TclLibrary(void) { } else { Tcl_Obj *vfsinitscript; int found=0; - +#if defined(_WIN32) || defined(_WIN64) + HMODULE hModule = TclWinGetTclInstance(); + WCHAR wName[MAX_PATH + LIBRARY_SIZE]; + char dllname[(MAX_PATH + LIBRARY_SIZE) * TCL_UTF_MAX]; +#endif /* Look for the library file system within the executable */ vfsinitscript=Tcl_NewStringObj(ZIPFS_APP_MOUNT "/tcl_library/init.tcl",-1); Tcl_IncrRefCount(vfsinitscript); @@ -2899,10 +2901,6 @@ Tcl_Obj *TclZipfs_TclLibrary(void) { return Tcl_NewStringObj(zipfs_literal_tcl_library,-1); } #if defined(_WIN32) || defined(_WIN64) - HMODULE hModule = TclWinGetTclInstance(); - WCHAR wName[MAX_PATH + LIBRARY_SIZE]; - char dllname[(MAX_PATH + LIBRARY_SIZE) * TCL_UTF_MAX]; - if (GetModuleFileNameW(hModule, wName, MAX_PATH) == 0) { GetModuleFileNameA(hModule, dllname, MAX_PATH); } else { @@ -3774,7 +3772,8 @@ Zip_FSMatchInDirectoryProc(Tcl_Interp* interp, Tcl_Obj *result, Tcl_HashEntry *hPtr; Tcl_HashSearch search; Tcl_Obj *normPathPtr; - int scnt, len, l, dirOnly = -1, prefixLen, strip = 0; + int scnt, l, dirOnly = -1, prefixLen, strip = 0; + size_t len; char *pat, *prefix, *path; Tcl_DString dsPref; @@ -3788,7 +3787,8 @@ Zip_FSMatchInDirectoryProc(Tcl_Interp* interp, Tcl_Obj *result, prefix = Tcl_GetStringFromObj(pathPtr, &prefixLen); /* the (normalized) path we're searching */ - path = Tcl_GetStringFromObj(normPathPtr, &len); + path = Tcl_GetString(normPathPtr); + len = normPathPtr->length; Tcl_DStringInit(&dsPref); Tcl_DStringAppend(&dsPref, prefix, prefixLen); @@ -3821,7 +3821,7 @@ Zip_FSMatchInDirectoryProc(Tcl_Interp* interp, Tcl_Obj *result, if (zf->mntptlen == 0) { ZipEntry *z = zf->topents; while (z != NULL) { - int lenz = strlen(z->name); + size_t lenz = strlen(z->name); if ( (lenz > len + 1) && (strncmp(z->name, path, len) == 0) @@ -3954,17 +3954,18 @@ Zip_FSPathInFilesystemProc(Tcl_Obj *pathPtr, ClientData *clientDataPtr) Tcl_HashEntry *hPtr; Tcl_HashSearch search; ZipFile *zf; - int ret = -1, len; + int ret = -1; + size_t len; char *path; if (!(pathPtr = Tcl_FSGetNormalizedPath(NULL, pathPtr))) return -1; - path = Tcl_GetStringFromObj(pathPtr, &len); + path = Tcl_GetString(pathPtr); if(strncmp(path,ZIPFS_VOLUME,ZIPFS_VOLUME_LEN)!=0) { return -1; } - len = strlen(path); + len = pathPtr->length; ReadLock(); hPtr = Tcl_FindHashEntry(&ZipFS.fileHash, path); @@ -3978,7 +3979,7 @@ Zip_FSPathInFilesystemProc(Tcl_Obj *pathPtr, ClientData *clientDataPtr) if (zf->mntptlen == 0) { ZipEntry *z = zf->topents; while (z != NULL) { - int lenz = strlen(z->name); + size_t lenz = strlen(z->name); if ( (len >= lenz) && (strncmp(path, z->name, lenz) == 0) ) { -- cgit v0.12 From 6269e32c3bc28d6bca8d70ec499e152648356f5c Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Thu, 6 Sep 2018 11:25:41 +0000 Subject: Bug-fix: Move TclZipfs_AppHook() from 0 -> 2 in the stub table, otherwise it overrides the entry for Tcl_MacOSXOpenBundleResources (since MacOSX is UNIX as well...). --- generic/tcl.decls | 7 ++++--- generic/tclPlatDecls.h | 27 ++++++++++++++++++++------- generic/tclStubInit.c | 7 +++++-- 3 files changed, 29 insertions(+), 12 deletions(-) diff --git a/generic/tcl.decls b/generic/tcl.decls index 1fa9a04..92e87d6 100644 --- a/generic/tcl.decls +++ b/generic/tcl.decls @@ -2330,8 +2330,6 @@ declare 631 { ClientData callbackData) } -# ----- BASELINE -- FOR -- 8.7.0 ----- # - # TIP #430 declare 632 { int TclZipfs_Mount( @@ -2354,6 +2352,9 @@ declare 635 { size_t datalen, int copy) } + +# ----- BASELINE -- FOR -- 8.7.0 ----- # + ############################################################################## # Define the platform specific public Tcl interface. These functions are only @@ -2364,7 +2365,7 @@ interface tclPlat ################################ # Unix specific functions # (none) -declare 0 unix { +declare 2 unix { int TclZipfs_AppHook(int *argc, char ***argv) } diff --git a/generic/tclPlatDecls.h b/generic/tclPlatDecls.h index e746a6d..ac3f921 100644 --- a/generic/tclPlatDecls.h +++ b/generic/tclPlatDecls.h @@ -51,7 +51,9 @@ extern "C" { */ #if !defined(_WIN32) && !defined(__CYGWIN__) && !defined(MAC_OSX_TCL) /* UNIX */ -/* 0 */ +/* Slot 0 is reserved */ +/* Slot 1 is reserved */ +/* 2 */ EXTERN int TclZipfs_AppHook(int *argc, char ***argv); #endif /* UNIX */ #if defined(_WIN32) || defined(__CYGWIN__) /* WIN */ @@ -66,13 +68,17 @@ EXTERN int TclZipfs_AppHook(int *argc, TCHAR ***argv); #endif /* WIN */ #ifdef MAC_OSX_TCL /* MACOSX */ /* 0 */ -EXTERN int TclZipfs_AppHook(int *argc, char ***argv); +EXTERN int Tcl_MacOSXOpenBundleResources(Tcl_Interp *interp, + const char *bundleName, int hasResourceFile, + int maxPathLen, char *libraryPath); /* 1 */ EXTERN int Tcl_MacOSXOpenVersionedBundleResources( Tcl_Interp *interp, const char *bundleName, const char *bundleVersion, int hasResourceFile, int maxPathLen, char *libraryPath); +/* 2 */ +EXTERN int TclZipfs_AppHook(int *argc, char ***argv); #endif /* MACOSX */ typedef struct TclPlatStubs { @@ -80,7 +86,9 @@ typedef struct TclPlatStubs { void *hooks; #if !defined(_WIN32) && !defined(__CYGWIN__) && !defined(MAC_OSX_TCL) /* UNIX */ - int (*tclZipfs_AppHook) (int *argc, char ***argv); /* 0 */ + void (*reserved0)(void); + void (*reserved1)(void); + int (*tclZipfs_AppHook) (int *argc, char ***argv); /* 2 */ #endif /* UNIX */ #if defined(_WIN32) || defined(__CYGWIN__) /* WIN */ TCHAR * (*tcl_WinUtfToTChar) (const char *str, int len, Tcl_DString *dsPtr); /* 0 */ @@ -88,8 +96,9 @@ typedef struct TclPlatStubs { int (*tclZipfs_AppHook) (int *argc, TCHAR ***argv); /* 2 */ #endif /* WIN */ #ifdef MAC_OSX_TCL /* MACOSX */ - int (*tclZipfs_AppHook) (int *argc, char ***argv); /* 0 */ + int (*tcl_MacOSXOpenBundleResources) (Tcl_Interp *interp, const char *bundleName, int hasResourceFile, int maxPathLen, char *libraryPath); /* 0 */ int (*tcl_MacOSXOpenVersionedBundleResources) (Tcl_Interp *interp, const char *bundleName, const char *bundleVersion, int hasResourceFile, int maxPathLen, char *libraryPath); /* 1 */ + int (*tclZipfs_AppHook) (int *argc, char ***argv); /* 2 */ #endif /* MACOSX */ } TclPlatStubs; @@ -106,8 +115,10 @@ extern const TclPlatStubs *tclPlatStubsPtr; */ #if !defined(_WIN32) && !defined(__CYGWIN__) && !defined(MAC_OSX_TCL) /* UNIX */ +/* Slot 0 is reserved */ +/* Slot 1 is reserved */ #define TclZipfs_AppHook \ - (tclPlatStubsPtr->tclZipfs_AppHook) /* 0 */ + (tclPlatStubsPtr->tclZipfs_AppHook) /* 2 */ #endif /* UNIX */ #if defined(_WIN32) || defined(__CYGWIN__) /* WIN */ #define Tcl_WinUtfToTChar \ @@ -118,10 +129,12 @@ extern const TclPlatStubs *tclPlatStubsPtr; (tclPlatStubsPtr->tclZipfs_AppHook) /* 2 */ #endif /* WIN */ #ifdef MAC_OSX_TCL /* MACOSX */ -#define TclZipfs_AppHook \ - (tclPlatStubsPtr->tclZipfs_AppHook) /* 0 */ +#define Tcl_MacOSXOpenBundleResources \ + (tclPlatStubsPtr->tcl_MacOSXOpenBundleResources) /* 0 */ #define Tcl_MacOSXOpenVersionedBundleResources \ (tclPlatStubsPtr->tcl_MacOSXOpenVersionedBundleResources) /* 1 */ +#define TclZipfs_AppHook \ + (tclPlatStubsPtr->tclZipfs_AppHook) /* 2 */ #endif /* MACOSX */ #endif /* defined(USE_TCL_STUBS) */ diff --git a/generic/tclStubInit.c b/generic/tclStubInit.c index 93ec08a..bf3a8d1 100644 --- a/generic/tclStubInit.c +++ b/generic/tclStubInit.c @@ -838,7 +838,9 @@ static const TclPlatStubs tclPlatStubs = { TCL_STUB_MAGIC, 0, #if !defined(_WIN32) && !defined(__CYGWIN__) && !defined(MAC_OSX_TCL) /* UNIX */ - TclZipfs_AppHook, /* 0 */ + 0, /* 0 */ + 0, /* 1 */ + TclZipfs_AppHook, /* 2 */ #endif /* UNIX */ #if defined(_WIN32) || defined(__CYGWIN__) /* WIN */ Tcl_WinUtfToTChar, /* 0 */ @@ -846,8 +848,9 @@ static const TclPlatStubs tclPlatStubs = { TclZipfs_AppHook, /* 2 */ #endif /* WIN */ #ifdef MAC_OSX_TCL /* MACOSX */ - TclZipfs_AppHook, /* 0 */ + Tcl_MacOSXOpenBundleResources, /* 0 */ Tcl_MacOSXOpenVersionedBundleResources, /* 1 */ + TclZipfs_AppHook, /* 2 */ #endif /* MACOSX */ }; -- cgit v0.12 From 833b02bc83665b70d5af4696ad54b3d83c51d11b Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Fri, 7 Sep 2018 09:53:17 +0000 Subject: TIP #515 implementation: Level Value Reform --- doc/uplevel.n | 4 +-- generic/tclProc.c | 90 +++++++++++++++++++----------------------------------- tests/uplevel.test | 26 ++++++++-------- 3 files changed, 46 insertions(+), 74 deletions(-) diff --git a/doc/uplevel.n b/doc/uplevel.n index 4decc6d..cda1652 100644 --- a/doc/uplevel.n +++ b/doc/uplevel.n @@ -24,9 +24,9 @@ the result of that evaluation. If \fIlevel\fR is an integer then it gives a distance (up the procedure calling stack) to move before executing the command. If \fIlevel\fR consists of \fB#\fR followed by -a number then the number gives an absolute level number. If \fIlevel\fR +a integer then the level gives an absolute level. If \fIlevel\fR is omitted then it defaults to \fB1\fR. \fILevel\fR cannot be -defaulted if the first \fIcommand\fR argument starts with a digit or \fB#\fR. +defaulted if the first \fIcommand\fR argument is an integer or starts with \fB#\fR. .PP For example, suppose that procedure \fBa\fR was invoked from top-level, and that it called \fBb\fR, and that \fBb\fR called \fBc\fR. diff --git a/generic/tclProc.c b/generic/tclProc.c index 212b680..b9d309f 100644 --- a/generic/tclProc.c +++ b/generic/tclProc.c @@ -688,51 +688,15 @@ TclGetFrame( CallFrame **framePtrPtr) /* Store pointer to frame here (or NULL if * global frame indicated). */ { - register Interp *iPtr = (Interp *) interp; - int curLevel, level, result; - CallFrame *framePtr; - - /* - * Parse string to figure out which level number to go to. - */ - - result = 1; - curLevel = iPtr->varFramePtr->level; - if (*name== '#') { - if (Tcl_GetInt(interp, name+1, &level) != TCL_OK || level < 0) { - goto levelError; - } - } else if (isdigit(UCHAR(*name))) { /* INTL: digit */ - if (Tcl_GetInt(interp, name, &level) != TCL_OK) { - goto levelError; - } - level = curLevel - level; - } else { - level = curLevel - 1; - result = 0; - } - - /* - * Figure out which frame to use, and return it to the caller. - */ - - for (framePtr = iPtr->varFramePtr; framePtr != NULL; - framePtr = framePtr->callerVarPtr) { - if (framePtr->level == level) { - break; - } - } - if (framePtr == NULL) { - goto levelError; - } - - *framePtrPtr = framePtr; - return result; - - levelError: - Tcl_SetObjResult(interp, Tcl_ObjPrintf("bad level \"%s\"", name)); - Tcl_SetErrorCode(interp, "TCL", "VALUE", "STACKLEVEL", NULL); - return -1; + int result; + Tcl_Obj obj; + + obj.bytes = (char *) name; + obj.length = strlen(name); + obj.typePtr = NULL; + result = TclObjGetFrame(interp, &obj, framePtrPtr); + TclFreeIntRep(&obj); + return result; } /* @@ -770,6 +734,7 @@ TclObjGetFrame( register Interp *iPtr = (Interp *) interp; int curLevel, level, result; const char *name = NULL; + Tcl_WideInt w; /* * Parse object to figure out which level number to go to. @@ -785,25 +750,33 @@ TclObjGetFrame( if (objPtr == NULL) { /* Do nothing */ - } else if (TCL_OK == Tcl_GetIntFromObj(NULL, objPtr, &level) - && (level >= 0)) { - level = curLevel - level; - result = 1; + } else if (TCL_OK == Tcl_GetIntFromObj(NULL, objPtr, &level)) { + Tcl_GetWideIntFromObj(NULL, objPtr, &w); + if (w < 0 || w > INT_MAX || curLevel > w + INT_MAX) { + result = -1; + } else { + level = curLevel - level; + result = 1; + } } else if (objPtr->typePtr == &levelReferenceType) { level = (int) objPtr->internalRep.wideValue; result = 1; } else { name = TclGetString(objPtr); if (name[0] == '#') { - if (TCL_OK == Tcl_GetInt(NULL, name+1, &level) && level >= 0) { - TclFreeIntRep(objPtr); - objPtr->typePtr = &levelReferenceType; - objPtr->internalRep.wideValue = level; - result = 1; + if (TCL_OK == Tcl_GetInt(NULL, name+1, &level)) { + if (level < 0 || (level > 0 && name[1] == '-')) { + result = -1; + } else { + TclFreeIntRep(objPtr); + objPtr->typePtr = &levelReferenceType; + objPtr->internalRep.wideValue = level; + result = 1; + } } else { result = -1; } - } else if (isdigit(UCHAR(name[0]))) { /* INTL: digit */ + } else if (TclGetWideBitsFromObj(interp, objPtr, &w) == TCL_OK) { /* * If this were an integer, we'd have succeeded already. * Docs say we have to treat this as a 'bad level' error. @@ -814,7 +787,6 @@ TclObjGetFrame( if (result == 0) { level = curLevel - 1; - name = "1"; } if (result != -1) { if (level >= 0) { @@ -827,11 +799,11 @@ TclObjGetFrame( } } } - if (name == NULL) { - name = TclGetString(objPtr); - } } + if (name == NULL) { + name = TclGetString(objPtr); + } Tcl_SetObjResult(interp, Tcl_ObjPrintf("bad level \"%s\"", name)); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "LEVEL", name, NULL); return -1; diff --git a/tests/uplevel.test b/tests/uplevel.test index 737c571..be2268a 100644 --- a/tests/uplevel.test +++ b/tests/uplevel.test @@ -137,27 +137,27 @@ test uplevel-4.15 {level parsing} { test uplevel-4.16 {level parsing} { apply {{} {uplevel #[expr 1] {}}} } {} -test uplevel-4.17 {level parsing} { +test uplevel-4.17 {level parsing} -returnCodes error -body { apply {{} {uplevel -0xffffffff {}}} -} {} -test uplevel-4.18 {level parsing} { +} -result {bad level "-0xffffffff"} +test uplevel-4.18 {level parsing} -returnCodes error -body { apply {{} {uplevel #-0xffffffff {}}} -} {} -test uplevel-4.19 {level parsing} { +} -result {bad level "#-0xffffffff"} +test uplevel-4.19 {level parsing} -returnCodes error -body { apply {{} {uplevel [expr -0xffffffff] {}}} -} {} -test uplevel-4.20 {level parsing} { +} -result {bad level "-4294967295"} +test uplevel-4.20 {level parsing} -returnCodes error -body { apply {{} {uplevel #[expr -0xffffffff] {}}} -} {} +} -result {bad level "#-4294967295"} test uplevel-4.21 {level parsing} -body { apply {{} {uplevel -1 {}}} -} -returnCodes error -result {invalid command name "-1"} +} -returnCodes error -result {bad level "-1"} test uplevel-4.22 {level parsing} -body { apply {{} {uplevel #-1 {}}} } -returnCodes error -result {bad level "#-1"} test uplevel-4.23 {level parsing} -body { apply {{} {uplevel [expr -1] {}}} -} -returnCodes error -result {invalid command name "-1"} +} -returnCodes error -result {bad level "-1"} test uplevel-4.24 {level parsing} -body { apply {{} {uplevel #[expr -1] {}}} } -returnCodes error -result {bad level "#-1"} @@ -175,13 +175,13 @@ test uplevel-4.28 {level parsing} -body { } -returnCodes error -result {bad level "#4294967295"} test uplevel-4.29 {level parsing} -body { apply {{} {uplevel 0.2 {}}} -} -returnCodes error -result {bad level "0.2"} +} -returnCodes error -result {invalid command name "0.2"} test uplevel-4.30 {level parsing} -body { apply {{} {uplevel #0.2 {}}} } -returnCodes error -result {bad level "#0.2"} test uplevel-4.31 {level parsing} -body { apply {{} {uplevel [expr 0.2] {}}} -} -returnCodes error -result {bad level "0.2"} +} -returnCodes error -result {invalid command name "0.2"} test uplevel-4.32 {level parsing} -body { apply {{} {uplevel #[expr 0.2] {}}} } -returnCodes error -result {bad level "#0.2"} @@ -193,7 +193,7 @@ test uplevel-4.34 {level parsing} -body { } -returnCodes error -result {bad level "#.2"} test uplevel-4.35 {level parsing} -body { apply {{} {uplevel [expr .2] {}}} -} -returnCodes error -result {bad level "0.2"} +} -returnCodes error -result {invalid command name "0.2"} test uplevel-4.36 {level parsing} -body { apply {{} {uplevel #[expr .2] {}}} } -returnCodes error -result {bad level "#0.2"} -- cgit v0.12 From b9577c0641072a7e7060bad5357e549b75928132 Mon Sep 17 00:00:00 2001 From: sebres Date: Fri, 7 Sep 2018 10:45:30 +0000 Subject: closes [631b4c45df]: segfault by usage of wrong length (no string representation) --- generic/tclProc.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/generic/tclProc.c b/generic/tclProc.c index dc58cb0..e51f5b3 100644 --- a/generic/tclProc.c +++ b/generic/tclProc.c @@ -504,10 +504,11 @@ TclCreateProc( goto procError; } - nameLength = Tcl_NumUtfChars(Tcl_GetString(fieldValues[0]), fieldValues[0]->length); + argname = Tcl_GetStringFromObj(fieldValues[0], &plen); + nameLength = Tcl_NumUtfChars(argname, plen); if (fieldCount == 2) { - valueLength = Tcl_NumUtfChars(Tcl_GetString(fieldValues[1]), - fieldValues[1]->length); + const char * value = TclGetString(fieldValues[1]); + valueLength = Tcl_NumUtfChars(value, fieldValues[1]->length); } else { valueLength = 0; } @@ -516,7 +517,6 @@ TclCreateProc( * Check that the formal parameter name is a scalar. */ - argname = Tcl_GetStringFromObj(fieldValues[0], &plen); argnamei = argname; argnamelast = argname[plen-1]; while (plen--) { -- cgit v0.12 From e80eaec4d3430e0db5f54dde5059821f35e77637 Mon Sep 17 00:00:00 2001 From: sebres Date: Fri, 7 Sep 2018 11:55:01 +0000 Subject: amend to [e8ab4d85fa], proc.test: extended with new test-case to cover situation like [631b4c45df] --- tests/proc.test | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/proc.test b/tests/proc.test index e06720e..f70fcbd 100644 --- a/tests/proc.test +++ b/tests/proc.test @@ -110,6 +110,14 @@ test proc-1.8 {Tcl_ProcObjCmd, check that formal parameter names are simple name proc p {b:a b::a} { } } -returnCodes error -result {formal parameter "b::a" is not a simple name} +test proc-1.9 {Tcl_ProcObjCmd, arguments via canonical list (string-representation bug [631b4c45df])} -body { + set v 2 + binary scan AB cc a b + proc p [list [list a $a] [list b $b] [list v [expr {$v + 2}]]] {expr {$a + $b + $v}} + p +} -result [expr {65+66+4}] -cleanup { + rename p {} +} test proc-2.1 {TclFindProc, simple proc name and proc not in namespace} -setup { catch {namespace delete {*}[namespace children :: test_ns_*]} -- cgit v0.12 From b8d2426e1bcc860c2c743e2baebbd9c57f117bb9 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Fri, 7 Sep 2018 11:56:40 +0000 Subject: Use GetFileSizeEx() in stead of GetFileSize(), to get the file size on Windows. Minor improvement: attach empty .zip file to tclsh.exe (both for Windows and UNIX), zo "zip -A" can be used to modify its zip contents. --- .fossil-settings/binary-glob | 1 + generic/tclZipfs.c | 29 +++++++++++++++-------------- tools/empty.zip | Bin 0 -> 22 bytes unix/Makefile.in | 1 + win/Makefile.in | 1 + 5 files changed, 18 insertions(+), 14 deletions(-) create mode 100644 tools/empty.zip diff --git a/.fossil-settings/binary-glob b/.fossil-settings/binary-glob index ec574be..5eebf07 100644 --- a/.fossil-settings/binary-glob +++ b/.fossil-settings/binary-glob @@ -4,6 +4,7 @@ compat/zlib/win64/zdll.lib compat/zlib/win64/zlib1.dll compat/zlib/win64/libz.dll.a compat/zlib/zlib.3.pdf +tools/empty.zip *.bmp *.gif *.png \ No newline at end of file diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c index 0ab60e7..4d716df 100644 --- a/generic/tclZipfs.c +++ b/generic/tclZipfs.c @@ -172,9 +172,9 @@ typedef struct ZipFile { char is_membuf; /* When true, not a file but a memory buffer */ Tcl_Channel chan; /* Channel handle or NULL */ unsigned char *data; /* Memory mapped or malloc'ed file */ - size_t length; /* Length of memory mapped file */ + Tcl_WideUInt length; /* Length of memory mapped file */ unsigned char *tofree; /* Non-NULL if malloc'ed file */ - size_t nfiles; /* Number of files in archive */ + size_t nfiles; /* Number of files in archive */ size_t baseoffs; /* Archive start */ size_t baseoffsp; /* Password start */ size_t centoffs; /* Archive directory start */ @@ -1039,7 +1039,7 @@ ZipFSOpenArchive(Tcl_Interp *interp, const char *zipname, int needZip, ZipFile * goto error; } zf->length = Tcl_Seek(zf->chan, 0, SEEK_END); - if ((zf->length <= 0) || (zf->length > 64 * 1024 * 1024)) { + if ((zf->length < ZIP_CENTRAL_END_LEN) || (zf->length > 64 * 1024 * 1024)) { ZIPFS_ERROR(interp,"illegal file size"); goto error; } @@ -1058,9 +1058,9 @@ ZipFSOpenArchive(Tcl_Interp *interp, const char *zipname, int needZip, ZipFile * zf->chan = NULL; } else { #if defined(_WIN32) || defined(_WIN64) - zf->length = GetFileSize((HANDLE) handle, 0); + i = GetFileSizeEx((HANDLE) handle, (PLARGE_INTEGER)&zf->length); if ( - (zf->length == (size_t)INVALID_FILE_SIZE) || + (i == 0) || (zf->length < ZIP_CENTRAL_END_LEN) ) { ZIPFS_ERROR(interp,"invalid file size"); @@ -1078,15 +1078,15 @@ ZipFSOpenArchive(Tcl_Interp *interp, const char *zipname, int needZip, ZipFile * goto error; } #else - zf->length = lseek((int) (long) handle, 0, SEEK_END); + zf->length = lseek(PTR2INT(handle), 0, SEEK_END); if ((zf->length == (size_t)-1) || (zf->length < ZIP_CENTRAL_END_LEN)) { ZIPFS_ERROR(interp,"invalid file size"); goto error; } - lseek((int) (long) handle, 0, SEEK_SET); + lseek(PTR2INT(handle), 0, SEEK_SET); zf->data = (unsigned char *) mmap(0, zf->length, PROT_READ, MAP_FILE | MAP_PRIVATE, - (int) (long) handle, 0); + PTR2INT(handle), 0); if (zf->data == MAP_FAILED) { ZIPFS_ERROR(interp,"file mapping failed"); goto error; @@ -2103,7 +2103,7 @@ wrerr: * Compressed file larger than input, * write it again uncompressed. */ - if ((int) Tcl_Seek(in, 0, SEEK_SET) != 0) { + if (Tcl_Seek(in, 0, SEEK_SET) != 0) { goto seekErr; } if ((int) Tcl_Seek(out, pos[2], SEEK_SET) != pos[2]) { @@ -4311,14 +4311,15 @@ TclZipfs_Init(Tcl_Interp *interp) Unlock(); if(interp != NULL) { static const EnsembleImplMap initMap[] = { - {"mount", ZipFSMountObjCmd, NULL, NULL, NULL, 0}, - {"mount_data", ZipFSMountBufferObjCmd, NULL, NULL, NULL, 0}, - {"unmount", ZipFSUnmountObjCmd, NULL, NULL, NULL, 0}, - {"mkkey", ZipFSMkKeyObjCmd, NULL, NULL, NULL, 0}, {"mkimg", ZipFSMkImgObjCmd, NULL, NULL, NULL, 0}, {"mkzip", ZipFSMkZipObjCmd, NULL, NULL, NULL, 0}, {"lmkimg", ZipFSLMkImgObjCmd, NULL, NULL, NULL, 0}, {"lmkzip", ZipFSLMkZipObjCmd, NULL, NULL, NULL, 0}, + /* The 4 entries above are not available in safe interpreters */ + {"mount", ZipFSMountObjCmd, NULL, NULL, NULL, 0}, + {"mount_data", ZipFSMountBufferObjCmd, NULL, NULL, NULL, 0}, + {"unmount", ZipFSUnmountObjCmd, NULL, NULL, NULL, 0}, + {"mkkey", ZipFSMkKeyObjCmd, NULL, NULL, NULL, 0}, {"exists", ZipFSExistsObjCmd, NULL, NULL, NULL, 1}, {"info", ZipFSInfoObjCmd, NULL, NULL, NULL, 1}, {"list", ZipFSListObjCmd, NULL, NULL, NULL, 1}, @@ -4349,7 +4350,7 @@ TclZipfs_Init(Tcl_Interp *interp) "}\n"; Tcl_EvalEx(interp, findproc, -1, TCL_EVAL_GLOBAL); Tcl_LinkVar(interp, "::tcl::zipfs::wrmax", (char *) &ZipFS.wrmax,TCL_LINK_INT); - TclMakeEnsemble(interp, "zipfs", initMap); + TclMakeEnsemble(interp, "zipfs", Tcl_IsSafe(interp) ? (initMap+4) : initMap); Tcl_PkgProvide(interp, "zipfs", "2.0"); } return TCL_OK; diff --git a/tools/empty.zip b/tools/empty.zip new file mode 100644 index 0000000..15cb0ec Binary files /dev/null and b/tools/empty.zip differ diff --git a/unix/Makefile.in b/unix/Makefile.in index 5569b44..2c005b6 100644 --- a/unix/Makefile.in +++ b/unix/Makefile.in @@ -711,6 +711,7 @@ ${TCL_EXE}: ${TCLSH_OBJS} ${TCL_LIB_FILE} ${TCL_STUB_LIB_FILE} ${CC} ${CFLAGS} ${LDFLAGS} ${TCLSH_OBJS} \ @TCL_BUILD_LIB_SPEC@ ${TCL_STUB_LIB_FILE} ${LIBS} @EXTRA_TCLSH_LIBS@ \ ${CC_SEARCH_FLAGS} -o ${TCL_EXE} + cat ${TOOL_DIR}/empty.zip >> ${TCL_EXE} # Must be empty so it doesn't conflict with rule for ${TCL_EXE} above ${NATIVE_TCLSH}: diff --git a/win/Makefile.in b/win/Makefile.in index a7be485..1d9c522 100644 --- a/win/Makefile.in +++ b/win/Makefile.in @@ -492,6 +492,7 @@ $(TCLSH): $(TCLSH_OBJS) @LIBRARIES@ $(TCL_STUB_LIB_FILE) tclsh.$(RES) $(CC) $(CFLAGS) $(TCLSH_OBJS) $(TCL_LIB_FILE) $(TCL_STUB_LIB_FILE) $(LIBS) \ tclsh.$(RES) $(CC_EXENAME) $(LDFLAGS_CONSOLE) @VC_MANIFEST_EMBED_EXE@ + cat ${TOOL_DIR}/empty.zip >> ${TCLSH} cat32.$(OBJEXT): cat.c $(CC) -c $(CC_SWITCHES) @DEPARG@ $(CC_OBJNAME) -- cgit v0.12 From 95db69f27b003d548813280a19d1b290332bf2ef Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 7 Sep 2018 12:04:32 +0000 Subject: Added test for [631b4c45df]. --- tests/proc.test | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/proc.test b/tests/proc.test index f70fcbd..8b25b0a 100644 --- a/tests/proc.test +++ b/tests/proc.test @@ -391,6 +391,14 @@ test proc-7.4 {Proc struct outlives its interp: Bug 3532959} { interp delete slave unset lambda } {} + +test proc-7.5 {[631b4c45df] Crash in argument processing} { + binary scan A c val + proc foo [list [list from $val]] {} + rename foo {} + unset -nocomplain val +} {} + # cleanup catch {rename p ""} -- cgit v0.12 From 9a15a1b58648809ffb208eaa00cd20af4784050d Mon Sep 17 00:00:00 2001 From: sebres Date: Fri, 7 Sep 2018 14:24:49 +0000 Subject: small code review (duplicate code removed) --- generic/tclProc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generic/tclProc.c b/generic/tclProc.c index e51f5b3..232eb93 100644 --- a/generic/tclProc.c +++ b/generic/tclProc.c @@ -611,7 +611,7 @@ TclCreateProc( procPtr->lastLocalPtr = localPtr; } localPtr->nextPtr = NULL; - localPtr->nameLength = Tcl_NumUtfChars(argname, fieldValues[0]->length); + localPtr->nameLength = nameLength; localPtr->frameIndex = i; localPtr->flags = VAR_ARGUMENT; localPtr->resolveInfo = NULL; -- cgit v0.12 From 0d73b8a7c0c6e90b6c3ed7fcde7b69916b23bedd Mon Sep 17 00:00:00 2001 From: dkf Date: Sat, 8 Sep 2018 12:52:06 +0000 Subject: Implementation of TIP 516 --- generic/tclOODefineCmds.c | 86 +++++++++++++++++++++++++++++++++++++++++------ generic/tclOOScript.h | 28 +++++++++++++-- generic/tclOOScript.tcl | 39 +++++++++++++++++++-- tests/oo.test | 16 ++++----- 4 files changed, 144 insertions(+), 25 deletions(-) diff --git a/generic/tclOODefineCmds.c b/generic/tclOODefineCmds.c index 3c27236..e4a30bb 100644 --- a/generic/tclOODefineCmds.c +++ b/generic/tclOODefineCmds.c @@ -37,14 +37,17 @@ struct DeclaredSlot { const char *name; const Tcl_MethodType getterType; const Tcl_MethodType setterType; + const Tcl_MethodType resolverType; }; -#define SLOT(name,getter,setter) \ +#define SLOT(name,getter,setter,resolver) \ {"::oo::" name, \ {TCL_OO_METHOD_VERSION_CURRENT, "core method: " name " Getter", \ getter, NULL, NULL}, \ {TCL_OO_METHOD_VERSION_CURRENT, "core method: " name " Setter", \ - setter, NULL, NULL}} + setter, NULL, NULL}, \ + {TCL_OO_METHOD_VERSION_CURRENT, "core method: " name " Setter", \ + resolver, NULL, NULL}} /* * Forward declarations. @@ -109,20 +112,23 @@ static int ObjVarsGet(ClientData clientData, static int ObjVarsSet(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext context, int objc, Tcl_Obj *const *objv); +static int ResolveClasses(ClientData clientData, + Tcl_Interp *interp, Tcl_ObjectContext context, + int objc, Tcl_Obj *const *objv); /* * Now define the slots used in declarations. */ static const struct DeclaredSlot slots[] = { - SLOT("define::filter", ClassFilterGet, ClassFilterSet), - SLOT("define::mixin", ClassMixinGet, ClassMixinSet), - SLOT("define::superclass", ClassSuperGet, ClassSuperSet), - SLOT("define::variable", ClassVarsGet, ClassVarsSet), - SLOT("objdefine::filter", ObjFilterGet, ObjFilterSet), - SLOT("objdefine::mixin", ObjMixinGet, ObjMixinSet), - SLOT("objdefine::variable", ObjVarsGet, ObjVarsSet), - {NULL, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}} + SLOT("define::filter", ClassFilterGet, ClassFilterSet, NULL), + SLOT("define::mixin", ClassMixinGet, ClassMixinSet, ResolveClasses), + SLOT("define::superclass", ClassSuperGet, ClassSuperSet, ResolveClasses), + SLOT("define::variable", ClassVarsGet, ClassVarsSet, NULL), + SLOT("objdefine::filter", ObjFilterGet, ObjFilterSet, NULL), + SLOT("objdefine::mixin", ObjMixinGet, ObjMixinSet, ResolveClasses), + SLOT("objdefine::variable", ObjVarsGet, ObjVarsSet, NULL), + {NULL, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}} }; /* @@ -2063,6 +2069,7 @@ TclOODefineSlots( const struct DeclaredSlot *slotInfoPtr; Tcl_Obj *getName = Tcl_NewStringObj("Get", -1); Tcl_Obj *setName = Tcl_NewStringObj("Set", -1); + Tcl_Obj *resolveName = Tcl_NewStringObj("Resolve", -1); Class *slotCls; slotCls = ((Object *) Tcl_NewObjectInstance(fPtr->interp, (Tcl_Class) @@ -2072,9 +2079,10 @@ TclOODefineSlots( } Tcl_IncrRefCount(getName); Tcl_IncrRefCount(setName); + Tcl_IncrRefCount(resolveName); for (slotInfoPtr = slots ; slotInfoPtr->name ; slotInfoPtr++) { Tcl_Object slotObject = Tcl_NewObjectInstance(fPtr->interp, - (Tcl_Class) slotCls, slotInfoPtr->name, NULL,-1,NULL,0); + (Tcl_Class) slotCls, slotInfoPtr->name, NULL, -1, NULL, 0); if (slotObject == NULL) { continue; @@ -2083,9 +2091,14 @@ TclOODefineSlots( &slotInfoPtr->getterType, NULL); Tcl_NewInstanceMethod(fPtr->interp, slotObject, setName, 0, &slotInfoPtr->setterType, NULL); + if (slotInfoPtr->resolverType.callProc) { + Tcl_NewInstanceMethod(fPtr->interp, slotObject, resolveName, 0, + &slotInfoPtr->resolverType, NULL); + } } Tcl_DecrRefCount(getName); Tcl_DecrRefCount(setName); + Tcl_DecrRefCount(resolveName); return TCL_OK; } @@ -2814,6 +2827,57 @@ ObjVarsSet( return TCL_OK; } + +static int +ResolveClasses( + ClientData clientData, + Tcl_Interp *interp, + Tcl_ObjectContext context, + int objc, + Tcl_Obj *const *objv) +{ + Object *oPtr = (Object *) TclOOGetDefineCmdContext(interp); + int cmdc, i, mustReset = 0; + Tcl_Obj **cmdv, **cmdv2; + + if (Tcl_ObjectContextSkippedArgs(context)+1 != objc) { + Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv, + "list"); + return TCL_ERROR; + } else if (oPtr == NULL) { + return TCL_ERROR; + } + objv += Tcl_ObjectContextSkippedArgs(context); + if (Tcl_ListObjGetElements(interp, objv[0], &cmdc, + &cmdv) != TCL_OK) { + return TCL_ERROR; + } + + cmdv2 = TclStackAlloc(interp, sizeof(Tcl_Obj *) * cmdc); + + /* + * Resolve each o + */ + + for (i=0 ; ithisPtr); + } + } + + if (mustReset) { + Tcl_ResetResult(interp); + } + Tcl_SetObjResult(interp, Tcl_NewListObj(cmdc, cmdv2)); + TclStackFree(interp, cmdv2); + return TCL_OK; +} + /* * Local Variables: * mode: c diff --git a/generic/tclOOScript.h b/generic/tclOOScript.h index e63bd86..5627bf8 100644 --- a/generic/tclOOScript.h +++ b/generic/tclOOScript.h @@ -147,12 +147,34 @@ static const char *tclOOSetupScript = "\t\tmethod Set list {\n" "\t\t\treturn -code error -errorcode {TCLOO ABSTRACT_SLOT} \"unimplemented\"\n" "\t\t}\n" -"\t\tmethod -set args {tailcall my Set $args}\n" +"\t\tmethod Resolve list {\n" +"\t\t\treturn $list\n" +"\t\t}\n" +"\t\tmethod -set args {\n" +"\t\t\tset args [uplevel 1 [list [namespace which my] Resolve $args]]\n" +"\t\t\ttailcall my Set $args\n" +"\t\t}\n" "\t\tmethod -append args {\n" -"\t\t\tset current [uplevel 1 [list [namespace which my] Get]]\n" +"\t\t\tset my [namespace which my]\n" +"\t\t\tset args [uplevel 1 [list $my Resolve $args]]\n" +"\t\t\tset current [uplevel 1 [list $my Get]]\n" "\t\t\ttailcall my Set [list {*}$current {*}$args]\n" "\t\t}\n" "\t\tmethod -clear {} {tailcall my Set {}}\n" +"\t\tmethod -prepend args {\n" +"\t\t\tset my [namespace which my]\n" +"\t\t\tset args [uplevel 1 [list $my Resolve $args]]\n" +"\t\t\tset current [uplevel 1 [list $my Get]]\n" +"\t\t\ttailcall my Set [list {*}$args {*}$current]\n" +"\t\t}\n" +"\t\tmethod -remove args {\n" +"\t\t\tset my [namespace which my]\n" +"\t\t\tset args [uplevel 1 [list $my Resolve $args]]\n" +"\t\t\tset current [uplevel 1 [list $my Get]]\n" +"\t\t\ttailcall my Set [lmap val $current {\n" +"\t\t\t\tif {$val in $args} continue else {set val}\n" +"\t\t\t}]\n" +"\t\t}\n" "\t\tforward --default-operation my -append\n" "\t\tmethod unknown {args} {\n" "\t\t\tset def --default-operation\n" @@ -163,7 +185,7 @@ static const char *tclOOSetupScript = "\t\t\t}\n" "\t\t\tnext {*}$args\n" "\t\t}\n" -"\t\texport -set -append -clear\n" +"\t\texport -set -append -clear -prepend -remove\n" "\t\tunexport unknown destroy\n" "\t}\n" "\tobjdefine define::superclass forward --default-operation my -set\n" diff --git a/generic/tclOOScript.tcl b/generic/tclOOScript.tcl index d3706ce..30af82a 100644 --- a/generic/tclOOScript.tcl +++ b/generic/tclOOScript.tcl @@ -276,6 +276,20 @@ # ------------------------------------------------------------------ # + # Slot Resolve -- + # + # Helper that lets a slot convert a list of arguments of a + # particular type to their canonical forms. Defaults to doing + # nothing (suitable for simple strings). + # + # ------------------------------------------------------------------ + + method Resolve list { + return $list + } + + # ------------------------------------------------------------------ + # # Slot -set, -append, -clear, --default-operation -- # # Standard public slot operations. If a slot can't figure out @@ -283,12 +297,31 @@ # # ------------------------------------------------------------------ - method -set args {tailcall my Set $args} + method -set args { + set args [uplevel 1 [list [namespace which my] Resolve $args]] + tailcall my Set $args + } method -append args { - set current [uplevel 1 [list [namespace which my] Get]] + set my [namespace which my] + set args [uplevel 1 [list $my Resolve $args]] + set current [uplevel 1 [list $my Get]] tailcall my Set [list {*}$current {*}$args] } method -clear {} {tailcall my Set {}} + method -prepend args { + set my [namespace which my] + set args [uplevel 1 [list $my Resolve $args]] + set current [uplevel 1 [list $my Get]] + tailcall my Set [list {*}$args {*}$current] + } + method -remove args { + set my [namespace which my] + set args [uplevel 1 [list $my Resolve $args]] + set current [uplevel 1 [list $my Get]] + tailcall my Set [lmap val $current { + if {$val in $args} continue else {set val} + }] + } # Default handling forward --default-operation my -append @@ -303,7 +336,7 @@ } # Set up what is exported and what isn't - export -set -append -clear + export -set -append -clear -prepend -remove unexport unknown destroy } diff --git a/tests/oo.test b/tests/oo.test index a303309..2dc9e2a 100644 --- a/tests/oo.test +++ b/tests/oo.test @@ -3920,7 +3920,7 @@ test oo-33.4 {TIP 380: slots - errors} -setup [SampleSlotSetup { } -returnCodes error -cleanup [SampleSlotCleanup { rename $s {} }] -result \ - {unknown method "-grill": must be -append, -clear, -set, contents or ops} + {unknown method "-grill": must be -append, -clear, -prepend, -remove, -set, contents or ops} test oo-34.1 {TIP 380: slots - presence} -setup { set obj [oo::object new] @@ -3950,25 +3950,25 @@ proc getMethods obj { } test oo-34.3 {TIP 380: slots - presence} { getMethods oo::define::filter -} {{-append -clear -set} {Get Set}} +} {{-append -clear -prepend -remove -set} {Get Set}} test oo-34.4 {TIP 380: slots - presence} { getMethods oo::define::mixin -} {{-append -clear -set} {--default-operation Get Set}} +} {{-append -clear -prepend -remove -set} {--default-operation Get Resolve Set}} test oo-34.5 {TIP 380: slots - presence} { getMethods oo::define::superclass -} {{-append -clear -set} {--default-operation Get Set}} +} {{-append -clear -prepend -remove -set} {--default-operation Get Resolve Set}} test oo-34.6 {TIP 380: slots - presence} { getMethods oo::define::variable -} {{-append -clear -set} {Get Set}} +} {{-append -clear -prepend -remove -set} {Get Set}} test oo-34.7 {TIP 380: slots - presence} { getMethods oo::objdefine::filter -} {{-append -clear -set} {Get Set}} +} {{-append -clear -prepend -remove -set} {Get Set}} test oo-34.8 {TIP 380: slots - presence} { getMethods oo::objdefine::mixin -} {{-append -clear -set} {--default-operation Get Set}} +} {{-append -clear -prepend -remove -set} {--default-operation Get Resolve Set}} test oo-34.9 {TIP 380: slots - presence} { getMethods oo::objdefine::variable -} {{-append -clear -set} {Get Set}} +} {{-append -clear -prepend -remove -set} {Get Set}} test oo-35.1 {Bug 9d61624b3d: Empty superclass must not cause crash} -setup { oo::class create fruit { -- cgit v0.12 From 33201eb14cf67e9484e1a711ecda15264dd48d4c Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Sat, 8 Sep 2018 21:34:48 +0000 Subject: Bring back test-cases closer to what they were --- tests/scan.test | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/scan.test b/tests/scan.test index 689a6ba..b488f68 100644 --- a/tests/scan.test +++ b/tests/scan.test @@ -19,7 +19,7 @@ if {"::tcltest" ni [namespace children]} { # procedure that returns the range of integers proc int_range {} { - set MAX_INT [expr {[format %lu -2]/2}] + set MAX_INT [expr {[format %u -2]/2}] set MIN_INT [expr { ~ $MAX_INT }] return [list $MIN_INT $MAX_INT] } @@ -442,14 +442,14 @@ test scan-4.61 {Tcl_ScanObjCmd, set errors} -setup { test scan-4.62 {scanning of large and negative octal integers} { lassign [int_range] MIN_INT MAX_INT - set scanstring [format {%lo %lo %lo} -1 $MIN_INT $MAX_INT] - list [scan $scanstring {%lo %lo %lo} a b c] \ + set scanstring [format {%o %o %o} -1 $MIN_INT $MAX_INT] + list [scan $scanstring {%o %o %o} a b c] \ [expr { $a == -1 }] [expr { $b == $MIN_INT }] [expr { $c == $MAX_INT }] } {3 1 1 1} test scan-4.63 {scanning of large and negative hex integers} { lassign [int_range] MIN_INT MAX_INT - set scanstring [format {%lx %lx %lx} -1 $MIN_INT $MAX_INT] - list [scan $scanstring {%lx %lx %lx} a b c] \ + set scanstring [format {%x %x %x} -1 $MIN_INT $MAX_INT] + list [scan $scanstring {%x %x %x} a b c] \ [expr { $a == -1 }] [expr { $b == $MIN_INT }] [expr { $c == $MAX_INT }] } {3 1 1 1} test scan-4.64 {scanning of hex with %X} { -- cgit v0.12 From b47bd89d441fcfb77be42ca7c4921b9a241d1c8b Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Sat, 8 Sep 2018 21:49:09 +0000 Subject: TCL_NUMBER_WIDE -> TCL_NUMBER_INT. Two test-cases still failing --- generic/tclBasic.c | 4 +-- generic/tclExecute.c | 70 ++++++++++++++++++++++++++-------------------------- generic/tclInt.h | 2 +- generic/tclObj.c | 2 +- 4 files changed, 39 insertions(+), 39 deletions(-) diff --git a/generic/tclBasic.c b/generic/tclBasic.c index 7294dd6..390df8f 100644 --- a/generic/tclBasic.c +++ b/generic/tclBasic.c @@ -6519,7 +6519,7 @@ Tcl_ExprLongObj( resultPtr = Tcl_NewBignumObj(&big); /* FALLTHROUGH */ } - case TCL_NUMBER_WIDE: + case TCL_NUMBER_INT: case TCL_NUMBER_BIG: result = TclGetLongFromObj(interp, resultPtr, ptr); break; @@ -7495,7 +7495,7 @@ ExprAbsFunc( return TCL_ERROR; } - if (type == TCL_NUMBER_WIDE) { + if (type == TCL_NUMBER_INT) { Tcl_WideInt l = *((const Tcl_WideInt *) ptr); if (l > (Tcl_WideInt)0) { diff --git a/generic/tclExecute.c b/generic/tclExecute.c index 034bfd2..a82cf2e 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -500,7 +500,7 @@ VarHashCreateVar( #define GetNumberFromObj(interp, objPtr, ptrPtr, tPtr) \ (((objPtr)->typePtr == &tclIntType) \ - ? (*(tPtr) = TCL_NUMBER_WIDE, \ + ? (*(tPtr) = TCL_NUMBER_INT, \ *(ptrPtr) = (ClientData) \ (&((objPtr)->internalRep.wideValue)), TCL_OK) : \ ((objPtr)->typePtr == &tclDoubleType) \ @@ -3620,7 +3620,7 @@ TEBCresume( objPtr = varPtr->value.objPtr; if (GetNumberFromObj(NULL, objPtr, &ptr, &type) == TCL_OK) { - if (type == TCL_NUMBER_WIDE) { + if (type == TCL_NUMBER_INT) { Tcl_WideInt augend = *((const Tcl_WideInt *)ptr); Tcl_WideInt sum = augend + increment; @@ -3662,7 +3662,7 @@ TEBCresume( TclSetIntObj(objPtr, w+increment); } goto doneIncr; - } /* end if (type == TCL_NUMBER_WIDE) */ + } /* end if (type == TCL_NUMBER_INT) */ } if (Tcl_IsShared(objPtr)) { objPtr->refCount--; /* We know it's shared */ @@ -5640,7 +5640,7 @@ TEBCresume( Tcl_WideInt w; if (Tcl_GetWideIntFromObj(NULL, OBJ_AT_TOS, &w) == TCL_OK) { - type1 = TCL_NUMBER_WIDE; + type1 = TCL_NUMBER_INT; } } TclNewIntObj(objResultPtr, type1); @@ -5686,7 +5686,7 @@ TEBCresume( compare = MP_EQ; goto convertComparison; } - if ((type1 == TCL_NUMBER_WIDE) && (type2 == TCL_NUMBER_WIDE)) { + if ((type1 == TCL_NUMBER_INT) && (type2 == TCL_NUMBER_INT)) { w1 = *((const Tcl_WideInt *)ptr1); w2 = *((const Tcl_WideInt *)ptr2); compare = (w1 < w2) ? MP_LT : ((w1 > w2) ? MP_GT : MP_EQ); @@ -5765,7 +5765,7 @@ TEBCresume( * Check for common, simple case. */ - if ((type1 == TCL_NUMBER_WIDE) && (type2 == TCL_NUMBER_WIDE)) { + if ((type1 == TCL_NUMBER_INT) && (type2 == TCL_NUMBER_INT)) { w1 = *((const Tcl_WideInt *)ptr1); w2 = *((const Tcl_WideInt *)ptr2); @@ -6005,7 +6005,7 @@ TEBCresume( * an external function. */ - if ((type1 == TCL_NUMBER_WIDE) && (type2 == TCL_NUMBER_WIDE)) { + if ((type1 == TCL_NUMBER_INT) && (type2 == TCL_NUMBER_INT)) { w1 = *((const Tcl_WideInt *)ptr1); w2 = *((const Tcl_WideInt *)ptr2); @@ -6148,7 +6148,7 @@ TEBCresume( CACHE_STACK_INFO(); goto gotError; } - if (type1 == TCL_NUMBER_WIDE) { + if (type1 == TCL_NUMBER_INT) { w1 = *((const Tcl_WideInt *) ptr1); if (Tcl_IsShared(valuePtr)) { TclNewIntObj(objResultPtr, ~w1); @@ -6185,7 +6185,7 @@ TEBCresume( /* -NaN => NaN */ TRACE_APPEND(("%s\n", O2S(valuePtr))); NEXT_INST_F(1, 0, 0); - case TCL_NUMBER_WIDE: + case TCL_NUMBER_INT: w1 = *((const Tcl_WideInt *) ptr1); if (w1 != LLONG_MIN) { if (Tcl_IsShared(valuePtr)) { @@ -7864,7 +7864,7 @@ ExecuteExtendedBinaryMathOp( /* TODO: Attempts to re-use unshared operands on stack */ w2 = 0; /* silence gcc warning */ - if (type2 == TCL_NUMBER_WIDE) { + if (type2 == TCL_NUMBER_INT) { w2 = *((const Tcl_WideInt *)ptr2); if (w2 == 0) { return DIVIDED_BY_ZERO; @@ -7877,7 +7877,7 @@ ExecuteExtendedBinaryMathOp( return constants[0]; } } - if (type1 == TCL_NUMBER_WIDE) { + if (type1 == TCL_NUMBER_INT) { w1 = *((const Tcl_WideInt *)ptr1); if (w1 == 0) { @@ -7955,7 +7955,7 @@ ExecuteExtendedBinaryMathOp( */ switch (type2) { - case TCL_NUMBER_WIDE: + case TCL_NUMBER_INT: invalid = (*((const Tcl_WideInt *)ptr2) < (Tcl_WideInt)0); break; case TCL_NUMBER_BIG: @@ -7977,7 +7977,7 @@ ExecuteExtendedBinaryMathOp( * Zero shifted any number of bits is still zero. */ - if ((type1==TCL_NUMBER_WIDE) && (*((const Tcl_WideInt *)ptr1) == (Tcl_WideInt)0)) { + if ((type1==TCL_NUMBER_INT) && (*((const Tcl_WideInt *)ptr1) == (Tcl_WideInt)0)) { return constants[0]; } @@ -7990,7 +7990,7 @@ ExecuteExtendedBinaryMathOp( * counterparts, leading to incorrect results. */ - if ((type2 != TCL_NUMBER_WIDE) + if ((type2 != TCL_NUMBER_INT) || (*((const Tcl_WideInt *)ptr2) > INT_MAX)) { /* * Technically, we could hold the value (1 << (INT_MAX+1)) in @@ -8023,7 +8023,7 @@ ExecuteExtendedBinaryMathOp( * Quickly force large right shifts to 0 or -1. */ - if ((type2 != TCL_NUMBER_WIDE) + if ((type2 != TCL_NUMBER_INT) || (*(const Tcl_WideInt *)ptr2 > INT_MAX)) { /* * Again, technically, the value to be shifted could be an @@ -8034,7 +8034,7 @@ ExecuteExtendedBinaryMathOp( */ switch (type1) { - case TCL_NUMBER_WIDE: + case TCL_NUMBER_INT: zero = (*(const Tcl_WideInt *)ptr1 > (Tcl_WideInt)0); break; case TCL_NUMBER_BIG: @@ -8057,7 +8057,7 @@ ExecuteExtendedBinaryMathOp( * Handle shifts within the native wide range. */ - if (type1 == TCL_NUMBER_WIDE) { + if (type1 == TCL_NUMBER_INT) { w1 = *(const Tcl_WideInt *)ptr1; if ((size_t)shift >= CHAR_BIT*sizeof(Tcl_WideInt)) { if (w1 >= (Tcl_WideInt)0) { @@ -8234,7 +8234,7 @@ ExecuteExtendedBinaryMathOp( BIG_RESULT(&bigResult); } - if ((type1 == TCL_NUMBER_WIDE) || (type2 == TCL_NUMBER_WIDE)) { + if ((type1 == TCL_NUMBER_INT) || (type2 == TCL_NUMBER_INT)) { TclGetWideIntFromObj(NULL, valuePtr, &w1); TclGetWideIntFromObj(NULL, value2Ptr, &w2); @@ -8288,7 +8288,7 @@ ExecuteExtendedBinaryMathOp( goto doubleResult; } w2 = 0; - if (type2 == TCL_NUMBER_WIDE) { + if (type2 == TCL_NUMBER_INT) { w2 = *((const Tcl_WideInt *) ptr2); if (w2 == 0) { /* @@ -8306,7 +8306,7 @@ ExecuteExtendedBinaryMathOp( } switch (type2) { - case TCL_NUMBER_WIDE: + case TCL_NUMBER_INT: w2 = *((const Tcl_WideInt *)ptr2); negativeExponent = (w2 < 0); oddExponent = (int) (w2 & (Tcl_WideInt)1); @@ -8320,11 +8320,11 @@ ExecuteExtendedBinaryMathOp( break; } - if (type1 == TCL_NUMBER_WIDE) { + if (type1 == TCL_NUMBER_INT) { w1 = *((const Tcl_WideInt *)ptr1); } if (negativeExponent) { - if (type1 == TCL_NUMBER_WIDE) { + if (type1 == TCL_NUMBER_INT) { switch (w1) { case 0: /* @@ -8354,7 +8354,7 @@ ExecuteExtendedBinaryMathOp( return constants[0]; } - if (type1 == TCL_NUMBER_WIDE) { + if (type1 == TCL_NUMBER_INT) { switch (w1) { case 0: /* @@ -8381,17 +8381,17 @@ ExecuteExtendedBinaryMathOp( * which means the max exponent value is 2**28-1 = 0x0fffffff = * 268435455, which fits into a signed 32 bit int which is within the * range of the long int type. This means any numeric Tcl_Obj value - * not using TCL_NUMBER_WIDE type must hold a value larger than we + * not using TCL_NUMBER_INT type must hold a value larger than we * accept. */ - if (type2 != TCL_NUMBER_WIDE) { + if (type2 != TCL_NUMBER_INT) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "exponent too large", -1)); return GENERAL_ARITHMETIC_ERROR; } - if (type1 == TCL_NUMBER_WIDE) { + if (type1 == TCL_NUMBER_INT) { if (w1 == 2) { /* * Reduce small powers of 2 to shifts. @@ -8415,7 +8415,7 @@ ExecuteExtendedBinaryMathOp( goto overflowExpon; } } - if (type1 == TCL_NUMBER_WIDE) { + if (type1 == TCL_NUMBER_INT) { w1 = *((const Tcl_WideInt *) ptr1); } else { goto overflowExpon; @@ -8615,7 +8615,7 @@ ExecuteExtendedBinaryMathOp( switch (opcode) { case INST_ADD: wResult = w1 + w2; - if ((type1 == TCL_NUMBER_WIDE) || (type2 == TCL_NUMBER_WIDE)) + if ((type1 == TCL_NUMBER_INT) || (type2 == TCL_NUMBER_INT)) { /* * Check for overflow. @@ -8629,7 +8629,7 @@ ExecuteExtendedBinaryMathOp( case INST_SUB: wResult = w1 - w2; - if ((type1 == TCL_NUMBER_WIDE) || (type2 == TCL_NUMBER_WIDE)) + if ((type1 == TCL_NUMBER_INT) || (type2 == TCL_NUMBER_INT)) { /* * Must check for overflow. The macro tests for overflows @@ -8752,7 +8752,7 @@ ExecuteExtendedUnaryMathOp( switch (opcode) { case INST_BITNOT: - if (type == TCL_NUMBER_WIDE) { + if (type == TCL_NUMBER_INT) { w = *((const Tcl_WideInt *) ptr); WIDE_RESULT(~w); } @@ -8765,7 +8765,7 @@ ExecuteExtendedUnaryMathOp( switch (type) { case TCL_NUMBER_DOUBLE: DOUBLE_RESULT(-(*((const double *) ptr))); - case TCL_NUMBER_WIDE: + case TCL_NUMBER_INT: w = *((const Tcl_WideInt *) ptr); if (w != LLONG_MIN) { WIDE_RESULT(-w); @@ -8819,10 +8819,10 @@ TclCompareTwoNumbers( (void) GetNumberFromObj(NULL, value2Ptr, &ptr2, &type2); switch (type1) { - case TCL_NUMBER_WIDE: + case TCL_NUMBER_INT: w1 = *((const Tcl_WideInt *)ptr1); switch (type2) { - case TCL_NUMBER_WIDE: + case TCL_NUMBER_INT: w2 = *((const Tcl_WideInt *)ptr2); wideCompare: return (w1 < w2) ? MP_LT : ((w1 > w2) ? MP_GT : MP_EQ); @@ -8879,7 +8879,7 @@ TclCompareTwoNumbers( d2 = *((const double *)ptr2); doubleCompare: return (d1 < d2) ? MP_LT : ((d1 > d2) ? MP_GT : MP_EQ); - case TCL_NUMBER_WIDE: + case TCL_NUMBER_INT: w2 = *((const Tcl_WideInt *)ptr2); d2 = (double) w2; if (DBL_MANT_DIG > CHAR_BIT*sizeof(Tcl_WideInt) @@ -8921,7 +8921,7 @@ TclCompareTwoNumbers( case TCL_NUMBER_BIG: Tcl_TakeBignumFromObj(NULL, valuePtr, &big1); switch (type2) { - case TCL_NUMBER_WIDE: + case TCL_NUMBER_INT: compare = mp_cmp_d(&big1, 0); mp_clear(&big1); return compare; diff --git a/generic/tclInt.h b/generic/tclInt.h index 1ed4f37..b08d86c 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -2710,7 +2710,7 @@ typedef struct ProcessGlobalValue { */ #define TCL_NUMBER_INT 2 -#if TCL_MAJOR_VERSION < 9 +#if (TCL_MAJOR_VERSION < 9) && !defined(TCL_NO_DEPRECATED) # define TCL_NUMBER_LONG 1 /* deprecated, not used any more */ # define TCL_NUMBER_WIDE TCL_NUMBER_INT /* deprecated */ #endif diff --git a/generic/tclObj.c b/generic/tclObj.c index 59f3090..aafb045 100644 --- a/generic/tclObj.c +++ b/generic/tclObj.c @@ -3639,7 +3639,7 @@ TclGetNumberFromObj( return TCL_OK; } if (objPtr->typePtr == &tclIntType) { - *typePtr = TCL_NUMBER_WIDE; + *typePtr = TCL_NUMBER_INT; *clientDataPtr = &objPtr->internalRep.wideValue; return TCL_OK; } -- cgit v0.12 From 0babbf966b043a085303889fba4471b02f75cd14 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Sun, 9 Sep 2018 17:05:38 +0000 Subject: slightly better: Use GetFileSizeEx() on win64 and GetFileSize on win32 --- generic/tclZipfs.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c index 4d716df..c65b1a6 100644 --- a/generic/tclZipfs.c +++ b/generic/tclZipfs.c @@ -172,7 +172,7 @@ typedef struct ZipFile { char is_membuf; /* When true, not a file but a memory buffer */ Tcl_Channel chan; /* Channel handle or NULL */ unsigned char *data; /* Memory mapped or malloc'ed file */ - Tcl_WideUInt length; /* Length of memory mapped file */ + size_t length; /* Length of memory mapped file */ unsigned char *tofree; /* Non-NULL if malloc'ed file */ size_t nfiles; /* Number of files in archive */ size_t baseoffs; /* Archive start */ @@ -1057,10 +1057,16 @@ ZipFSOpenArchive(Tcl_Interp *interp, const char *zipname, int needZip, ZipFile * Tcl_Close(interp, zf->chan); zf->chan = NULL; } else { -#if defined(_WIN32) || defined(_WIN64) +#ifdef _WIN32) +# ifdef _WIN64 i = GetFileSizeEx((HANDLE) handle, (PLARGE_INTEGER)&zf->length); if ( (i == 0) || +# else + zf->length = GetFileSize((HANDLE) handle, 0); + if ( + (zf->length == (size_t)INVALID_FILE_SIZE) || +# endif (zf->length < ZIP_CENTRAL_END_LEN) ) { ZIPFS_ERROR(interp,"invalid file size"); -- cgit v0.12 From 4f178616784e701a7b93586556ffbf292dd173aa Mon Sep 17 00:00:00 2001 From: dkf Date: Mon, 10 Sep 2018 08:33:11 +0000 Subject: Tests and docs --- doc/define.n | 64 +++++++++++++++++++++++++++++++++++++++++++++++---- tests/oo.test | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 128 insertions(+), 10 deletions(-) diff --git a/doc/define.n b/doc/define.n index 6353d00..1030096 100644 --- a/doc/define.n +++ b/doc/define.n @@ -426,7 +426,7 @@ Some of the configurable definitions of a class or object are \fIslotted definitions\fR. This means that the configuration is implemented by a slot object, that is an instance of the class \fBoo::Slot\fR, which manages a list of values (class names, variable names, etc.) that comprises the contents of -the slot. The class defines three operations (as methods) that may be done on +the slot. The class defines five operations (as methods) that may be done on the slot: .TP \fIslot\fR \fB\-append\fR ?\fImember ...\fR? @@ -437,6 +437,16 @@ This appends the given \fImember\fR elements to the slot definition. . This sets the slot definition to the empty list. .TP +\fIslot\fR \fB\-prepend\fR ?\fImember ...\fR? +.VS TIP516 +This prepends the given \fImember\fR elements to the slot definition. +.VE TIP516 +.TP +\fIslot\fR \fB\-remove\fR ?\fImember ...\fR? +.VS TIP516 +This removes the given \fImember\fR elements from the slot definition. +.VE TIP516 +.TP \fIslot\fR \fB\-set\fR ?\fImember ...\fR? . This replaces the slot definition with the given \fImember\fR elements. @@ -454,15 +464,53 @@ and these methods which provide the implementation interface: .TP \fIslot\fR \fBGet\fR . -Returns a list that is the current contents of the slot. This method must +Returns a list that is the current contents of the slot, but does not modify +the slot. This method must always be called from a stack frame created by a +call to \fBoo::define\fR or \fBoo::objdefine\fR. This method \fIshould not\fR +return an error unless it is called from outside a definition context or with +the wrong number of arguments. +.RS +.PP +.VS TIP516 +The elements of the list should be fully resolved, if that is a meaningful +concept to the slot. +.VE TIP516 +.RE +.TP +\fIslot\fR \fBResolve\fR \fIelementList\fR +.VS TIP516 +Returns a list that is the elements of \fIelementList\fR with a resolution +operation applied to each of them, but does not modify the slot. For slots of +simple strings, this is an operation that does nothing. For slots of classes, +this maps each class name to its fully qualified class name. This method must always be called from a stack frame created by a call to \fBoo::define\fR or -\fBoo::objdefine\fR. +\fBoo::objdefine\fR. This method \fIshould not\fR return an error unless it +is called from outside a definition context or with the wrong number of +arguments. +.RS +.PP +Implementations \fIshould not\fR reorder or filter elements in this operation; +uniqueness and ordering constraints should be enforced in the \fBSet\fR +method. This is because this method is not normally presented with the full +contents of the slot (except via the \fB\-set\fR slot operation). +.RE +.VE TIP516 .TP \fIslot\fR \fBSet \fIelementList\fR . Sets the contents of the slot to the list \fIelementList\fR and returns the empty string. This method must always be called from a stack frame created by -a call to \fBoo::define\fR or \fBoo::objdefine\fR. +a call to \fBoo::define\fR or \fBoo::objdefine\fR. This method may return an +error if it rejects the change to the slot contents (e.g., because of invalid +values) as well as if it is called from outside a definition context or with +the wrong number of arguments. +.RS +.PP +This method \fImay\fR reorder and filter the elements if this is necessary in +order to satisfy the underlying constraints of the slot. (For example, slots +of classes enforce a uniqueness constraint that places each element in the +earliest location in the slot that it can.) +.RE .PP The implementation of these methods is slot-dependent (and responsible for accessing the correct part of the class or object definition). Slots also have @@ -470,6 +518,14 @@ an unknown method handler to tie all these pieces together, and they hide their \fBdestroy\fR method so that it is not invoked inadvertently. It is \fIrecommended\fR that any user changes to the slot mechanism be restricted to defining new operations whose names start with a hyphen. +.PP +.VS TIP516 +Most slot operations will initially \fBResolve\fR their argument list, combine +it with the results of the \fBGet\fR method, and then \fBSet\fR the result. +Some operations omit one or both of the first two steps; omitting the third +would result in an idempotent read-only operation (but the standard mechanism +for reading from slots is via \fBinfo class\fR and \fBinfo object\fR). +.VE TIP516 .SH EXAMPLES This example demonstrates how to use both forms of the \fBoo::define\fR and \fBoo::objdefine\fR commands (they work in the same way), as well as diff --git a/tests/oo.test b/tests/oo.test index 2dc9e2a..1093f8d 100644 --- a/tests/oo.test +++ b/tests/oo.test @@ -13,13 +13,11 @@ if {"::tcltest" in [namespace children]} { namespace import -force ::tcltest::* } - # The foundational objects oo::object and oo::class are sensitive to reference # counting errors and are deallocated only when an interp is deleted, so in # this test suite, interp creation and interp deletion are often used in # leaktests in order to leverage this sensitivity. - testConstraint memory [llength [info commands memory]] if {[testConstraint memory]} { proc getbytes {} { @@ -3838,6 +3836,11 @@ proc SampleSlotSetup script { lappend ops [info level] Set $lst return } + method Resolve {lst} { + variable ops + lappend ops [info level] Resolve $lst + return $lst + } } } append script0 \n$script @@ -3872,7 +3875,7 @@ test oo-32.3 {TIP 380: slots - class test} -setup [SampleSlotSetup { [sampleSlot contents] [sampleSlot ops] } -cleanup [SampleSlotCleanup { rename sampleSlot {} -}] -result {0 {} {a b c g h i} {1 Get 1 Set {a b c g h i}}} +}] -result {0 {} {a b c g h i} {1 Resolve {g h i} 1 Get 1 Set {a b c g h i}}} test oo-32.4 {TIP 380: slots - class test} -setup [SampleSlotSetup { SampleSlot create sampleSlot }] -body { @@ -3880,7 +3883,7 @@ test oo-32.4 {TIP 380: slots - class test} -setup [SampleSlotSetup { [sampleSlot contents] [sampleSlot ops] } -cleanup [SampleSlotCleanup { rename sampleSlot {} -}] -result {0 {} {d e f} {1 Set {d e f}}} +}] -result {0 {} {d e f} {1 Resolve {d e f} 1 Set {d e f}}} test oo-32.5 {TIP 380: slots - class test} -setup [SampleSlotSetup { SampleSlot create sampleSlot }] -body { @@ -3888,7 +3891,23 @@ test oo-32.5 {TIP 380: slots - class test} -setup [SampleSlotSetup { [sampleSlot contents] [sampleSlot ops] } -cleanup [SampleSlotCleanup { rename sampleSlot {} -}] -result {0 {} {} {d e f g h i} {1 Set {d e f} 1 Get 1 Set {d e f g h i}}} +}] -result {0 {} {} {d e f g h i} {1 Resolve {d e f} 1 Set {d e f} 1 Resolve {g h i} 1 Get 1 Set {d e f g h i}}} +test oo-32.6 {TIP 516: slots - class test} -setup [SampleSlotSetup { + SampleSlot create sampleSlot +}] -body { + list [info level] [sampleSlot -prepend g h i] \ + [sampleSlot contents] [sampleSlot ops] +} -cleanup [SampleSlotCleanup { + rename sampleSlot {} +}] -result {0 {} {g h i a b c} {1 Resolve {g h i} 1 Get 1 Set {g h i a b c}}} +test oo-32.6 {TIP 516: slots - class test} -setup [SampleSlotSetup { + SampleSlot create sampleSlot +}] -body { + list [info level] [sampleSlot -remove c a] \ + [sampleSlot contents] [sampleSlot ops] +} -cleanup [SampleSlotCleanup { + rename sampleSlot {} +}] -result {0 {} b {1 Resolve {c a} 1 Get 1 Set b}} test oo-33.1 {TIP 380: slots - defaulting} -setup [SampleSlotSetup { set s [SampleSlot new] @@ -3911,7 +3930,7 @@ test oo-33.3 {TIP 380: slots - defaulting} -setup [SampleSlotSetup { list [$s destroy; $s unknown] [$s contents] [$s ops] } -cleanup [SampleSlotCleanup { rename $s {} -}] -result {{} unknown {1 Set destroy 1 Set unknown}} +}] -result {{} unknown {1 Resolve destroy 1 Set destroy 1 Resolve unknown 1 Set unknown}} test oo-33.4 {TIP 380: slots - errors} -setup [SampleSlotSetup { set s [SampleSlot new] }] -body { @@ -3969,6 +3988,49 @@ test oo-34.8 {TIP 380: slots - presence} { test oo-34.9 {TIP 380: slots - presence} { getMethods oo::objdefine::variable } {{-append -clear -prepend -remove -set} {Get Set}} +test oo-34.10 {TIP 516: slots - resolution} -setup { + oo::class create parent + set result {} + oo::class create 516a { superclass parent } + oo::class create 516b { superclass parent } + oo::class create 516c { superclass parent } + namespace eval 516test { + oo::class create 516a { superclass parent } + oo::class create 516b { superclass parent } + oo::class create 516c { superclass parent } + } +} -body { + # Must find the right classes when making the mixin + namespace eval 516test { + oo::define 516a { + mixin 516b 516c + } + } + lappend result [info class mixin 516test::516a] + # Must not remove class with just simple name match + oo::define 516test::516a { + mixin -remove 516b + } + lappend result [info class mixin 516test::516a] + # Must remove class with resolved name match + oo::define 516test::516a { + mixin -remove 516test::516c + } + lappend result [info class mixin 516test::516a] + # Must remove class with resolved name match even after renaming, but only + # with the renamed name; it is a slot of classes, not strings! + rename 516test::516b 516test::516d + oo::define 516test::516a { + mixin -remove 516test::516b + } + lappend result [info class mixin 516test::516a] + oo::define 516test::516a { + mixin -remove 516test::516d + } + lappend result [info class mixin 516test::516a] +} -cleanup { + parent destroy +} -result {{::516test::516b ::516test::516c} {::516test::516b ::516test::516c} ::516test::516b ::516test::516d {}} test oo-35.1 {Bug 9d61624b3d: Empty superclass must not cause crash} -setup { oo::class create fruit { -- cgit v0.12 From 90e3bdc291f94c2e3ff1c4e5b0edb6e203966147 Mon Sep 17 00:00:00 2001 From: dkf Date: Tue, 11 Sep 2018 07:44:04 +0000 Subject: Simplify the slot resolution protocol --- doc/define.n | 25 +++++++++-------- generic/tclOODefineCmds.c | 68 ++++++++++++++++++++++++----------------------- generic/tclOOScript.h | 9 ++++--- generic/tclOOScript.tcl | 9 ++++--- tests/oo.test | 10 +++---- 5 files changed, 62 insertions(+), 59 deletions(-) diff --git a/doc/define.n b/doc/define.n index 1030096..883d5fa 100644 --- a/doc/define.n +++ b/doc/define.n @@ -477,22 +477,21 @@ concept to the slot. .VE TIP516 .RE .TP -\fIslot\fR \fBResolve\fR \fIelementList\fR +\fIslot\fR \fBResolve\fR \fIslotElement\fR .VS TIP516 -Returns a list that is the elements of \fIelementList\fR with a resolution -operation applied to each of them, but does not modify the slot. For slots of -simple strings, this is an operation that does nothing. For slots of classes, -this maps each class name to its fully qualified class name. This method must -always be called from a stack frame created by a call to \fBoo::define\fR or -\fBoo::objdefine\fR. This method \fIshould not\fR return an error unless it -is called from outside a definition context or with the wrong number of -arguments. +Returns \fIslotElement\fR with a resolution operation applied to it, but does +not modify the slot. For slots of simple strings, this is an operation that +does nothing, whereas for slots of classes, this maps a class name to its +fully-qualified class name. This method must always be called from a stack +frame created by a call to \fBoo::define\fR or \fBoo::objdefine\fR. This +method \fIshould not\fR return an error unless it is called from outside a +definition context or with the wrong number of arguments; unresolvable +arguments should be returned as is (as not all slot operations strictly +require that values are resolvable to work). .RS .PP -Implementations \fIshould not\fR reorder or filter elements in this operation; -uniqueness and ordering constraints should be enforced in the \fBSet\fR -method. This is because this method is not normally presented with the full -contents of the slot (except via the \fB\-set\fR slot operation). +Implementations \fIshould not\fR enforce uniqueness and ordering constraints +in this method; that is the responsibility of the \fBSet\fR method. .RE .VE TIP516 .TP diff --git a/generic/tclOODefineCmds.c b/generic/tclOODefineCmds.c index e4a30bb..b68cb0c 100644 --- a/generic/tclOODefineCmds.c +++ b/generic/tclOODefineCmds.c @@ -112,7 +112,7 @@ static int ObjVarsGet(ClientData clientData, static int ObjVarsSet(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext context, int objc, Tcl_Obj *const *objv); -static int ResolveClasses(ClientData clientData, +static int ResolveClass(ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext context, int objc, Tcl_Obj *const *objv); @@ -122,11 +122,11 @@ static int ResolveClasses(ClientData clientData, static const struct DeclaredSlot slots[] = { SLOT("define::filter", ClassFilterGet, ClassFilterSet, NULL), - SLOT("define::mixin", ClassMixinGet, ClassMixinSet, ResolveClasses), - SLOT("define::superclass", ClassSuperGet, ClassSuperSet, ResolveClasses), + SLOT("define::mixin", ClassMixinGet, ClassMixinSet, ResolveClass), + SLOT("define::superclass", ClassSuperGet, ClassSuperSet, ResolveClass), SLOT("define::variable", ClassVarsGet, ClassVarsSet, NULL), SLOT("objdefine::filter", ObjFilterGet, ObjFilterSet, NULL), - SLOT("objdefine::mixin", ObjMixinGet, ObjMixinSet, ResolveClasses), + SLOT("objdefine::mixin", ObjMixinGet, ObjMixinSet, ResolveClass), SLOT("objdefine::variable", ObjVarsGet, ObjVarsSet, NULL), {NULL, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}} }; @@ -2827,54 +2827,56 @@ ObjVarsSet( return TCL_OK; } +/* + * ---------------------------------------------------------------------- + * + * ResolveClass -- + * + * Implementation of the "Resolve" support method for some slots (those + * that are slots around a list of classes). This resolves possible class + * names to their fully-qualified names if possible. + * + * ---------------------------------------------------------------------- + */ static int -ResolveClasses( +ResolveClass( ClientData clientData, Tcl_Interp *interp, Tcl_ObjectContext context, int objc, Tcl_Obj *const *objv) { + int idx = Tcl_ObjectContextSkippedArgs(context); Object *oPtr = (Object *) TclOOGetDefineCmdContext(interp); - int cmdc, i, mustReset = 0; - Tcl_Obj **cmdv, **cmdv2; + Class *clsPtr; - if (Tcl_ObjectContextSkippedArgs(context)+1 != objc) { - Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv, - "list"); - return TCL_ERROR; - } else if (oPtr == NULL) { + /* + * Check if were called wrongly. The definition context isn't used... + * except that GetClassInOuterContext() assumes that it is there. + */ + + if (oPtr == NULL) { return TCL_ERROR; - } - objv += Tcl_ObjectContextSkippedArgs(context); - if (Tcl_ListObjGetElements(interp, objv[0], &cmdc, - &cmdv) != TCL_OK) { + } else if (objc != idx + 1) { + Tcl_WrongNumArgs(interp, idx, objv, "slotElement"); return TCL_ERROR; } - cmdv2 = TclStackAlloc(interp, sizeof(Tcl_Obj *) * cmdc); - /* - * Resolve each o + * Resolve the class if possible. If not, remove any resolution error and + * return what we've got anyway as the failure might not be fatal overall. */ - for (i=0 ; ithisPtr); - } - } - - if (mustReset) { + clsPtr = GetClassInOuterContext(interp, objv[idx], + "USER SHOULD NOT SEE THIS MESSAGE"); + if (clsPtr == NULL) { Tcl_ResetResult(interp); + Tcl_SetObjResult(interp, objv[idx]); + } else { + Tcl_SetObjResult(interp, TclOOObjectName(interp, clsPtr->thisPtr)); } - Tcl_SetObjResult(interp, Tcl_NewListObj(cmdc, cmdv2)); - TclStackFree(interp, cmdv2); + return TCL_OK; } diff --git a/generic/tclOOScript.h b/generic/tclOOScript.h index 5627bf8..2213ce3 100644 --- a/generic/tclOOScript.h +++ b/generic/tclOOScript.h @@ -151,25 +151,26 @@ static const char *tclOOSetupScript = "\t\t\treturn $list\n" "\t\t}\n" "\t\tmethod -set args {\n" -"\t\t\tset args [uplevel 1 [list [namespace which my] Resolve $args]]\n" +"\t\t\tset my [namespace which my]\n" +"\t\t\tset args [lmap a $args {uplevel 1 [list $my Resolve $a]}]\n" "\t\t\ttailcall my Set $args\n" "\t\t}\n" "\t\tmethod -append args {\n" "\t\t\tset my [namespace which my]\n" -"\t\t\tset args [uplevel 1 [list $my Resolve $args]]\n" +"\t\t\tset args [lmap a $args {uplevel 1 [list $my Resolve $a]}]\n" "\t\t\tset current [uplevel 1 [list $my Get]]\n" "\t\t\ttailcall my Set [list {*}$current {*}$args]\n" "\t\t}\n" "\t\tmethod -clear {} {tailcall my Set {}}\n" "\t\tmethod -prepend args {\n" "\t\t\tset my [namespace which my]\n" -"\t\t\tset args [uplevel 1 [list $my Resolve $args]]\n" +"\t\t\tset args [lmap a $args {uplevel 1 [list $my Resolve $a]}]\n" "\t\t\tset current [uplevel 1 [list $my Get]]\n" "\t\t\ttailcall my Set [list {*}$args {*}$current]\n" "\t\t}\n" "\t\tmethod -remove args {\n" "\t\t\tset my [namespace which my]\n" -"\t\t\tset args [uplevel 1 [list $my Resolve $args]]\n" +"\t\t\tset args [lmap a $args {uplevel 1 [list $my Resolve $a]}]\n" "\t\t\tset current [uplevel 1 [list $my Get]]\n" "\t\t\ttailcall my Set [lmap val $current {\n" "\t\t\t\tif {$val in $args} continue else {set val}\n" diff --git a/generic/tclOOScript.tcl b/generic/tclOOScript.tcl index 30af82a..a48eab5 100644 --- a/generic/tclOOScript.tcl +++ b/generic/tclOOScript.tcl @@ -298,25 +298,26 @@ # ------------------------------------------------------------------ method -set args { - set args [uplevel 1 [list [namespace which my] Resolve $args]] + set my [namespace which my] + set args [lmap a $args {uplevel 1 [list $my Resolve $a]}] tailcall my Set $args } method -append args { set my [namespace which my] - set args [uplevel 1 [list $my Resolve $args]] + set args [lmap a $args {uplevel 1 [list $my Resolve $a]}] set current [uplevel 1 [list $my Get]] tailcall my Set [list {*}$current {*}$args] } method -clear {} {tailcall my Set {}} method -prepend args { set my [namespace which my] - set args [uplevel 1 [list $my Resolve $args]] + set args [lmap a $args {uplevel 1 [list $my Resolve $a]}] set current [uplevel 1 [list $my Get]] tailcall my Set [list {*}$args {*}$current] } method -remove args { set my [namespace which my] - set args [uplevel 1 [list $my Resolve $args]] + set args [lmap a $args {uplevel 1 [list $my Resolve $a]}] set current [uplevel 1 [list $my Get]] tailcall my Set [lmap val $current { if {$val in $args} continue else {set val} diff --git a/tests/oo.test b/tests/oo.test index 1093f8d..033daf5 100644 --- a/tests/oo.test +++ b/tests/oo.test @@ -3875,7 +3875,7 @@ test oo-32.3 {TIP 380: slots - class test} -setup [SampleSlotSetup { [sampleSlot contents] [sampleSlot ops] } -cleanup [SampleSlotCleanup { rename sampleSlot {} -}] -result {0 {} {a b c g h i} {1 Resolve {g h i} 1 Get 1 Set {a b c g h i}}} +}] -result {0 {} {a b c g h i} {1 Resolve g 1 Resolve h 1 Resolve i 1 Get 1 Set {a b c g h i}}} test oo-32.4 {TIP 380: slots - class test} -setup [SampleSlotSetup { SampleSlot create sampleSlot }] -body { @@ -3883,7 +3883,7 @@ test oo-32.4 {TIP 380: slots - class test} -setup [SampleSlotSetup { [sampleSlot contents] [sampleSlot ops] } -cleanup [SampleSlotCleanup { rename sampleSlot {} -}] -result {0 {} {d e f} {1 Resolve {d e f} 1 Set {d e f}}} +}] -result {0 {} {d e f} {1 Resolve d 1 Resolve e 1 Resolve f 1 Set {d e f}}} test oo-32.5 {TIP 380: slots - class test} -setup [SampleSlotSetup { SampleSlot create sampleSlot }] -body { @@ -3891,7 +3891,7 @@ test oo-32.5 {TIP 380: slots - class test} -setup [SampleSlotSetup { [sampleSlot contents] [sampleSlot ops] } -cleanup [SampleSlotCleanup { rename sampleSlot {} -}] -result {0 {} {} {d e f g h i} {1 Resolve {d e f} 1 Set {d e f} 1 Resolve {g h i} 1 Get 1 Set {d e f g h i}}} +}] -result {0 {} {} {d e f g h i} {1 Resolve d 1 Resolve e 1 Resolve f 1 Set {d e f} 1 Resolve g 1 Resolve h 1 Resolve i 1 Get 1 Set {d e f g h i}}} test oo-32.6 {TIP 516: slots - class test} -setup [SampleSlotSetup { SampleSlot create sampleSlot }] -body { @@ -3899,7 +3899,7 @@ test oo-32.6 {TIP 516: slots - class test} -setup [SampleSlotSetup { [sampleSlot contents] [sampleSlot ops] } -cleanup [SampleSlotCleanup { rename sampleSlot {} -}] -result {0 {} {g h i a b c} {1 Resolve {g h i} 1 Get 1 Set {g h i a b c}}} +}] -result {0 {} {g h i a b c} {1 Resolve g 1 Resolve h 1 Resolve i 1 Get 1 Set {g h i a b c}}} test oo-32.6 {TIP 516: slots - class test} -setup [SampleSlotSetup { SampleSlot create sampleSlot }] -body { @@ -3907,7 +3907,7 @@ test oo-32.6 {TIP 516: slots - class test} -setup [SampleSlotSetup { [sampleSlot contents] [sampleSlot ops] } -cleanup [SampleSlotCleanup { rename sampleSlot {} -}] -result {0 {} b {1 Resolve {c a} 1 Get 1 Set b}} +}] -result {0 {} b {1 Resolve c 1 Resolve a 1 Get 1 Set b}} test oo-33.1 {TIP 380: slots - defaulting} -setup [SampleSlotSetup { set s [SampleSlot new] -- cgit v0.12 From 1a3cef48749dde8d1c1b321f30f665193b89c14d Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Tue, 11 Sep 2018 22:41:00 +0000 Subject: Make ready for TIP #494 compatibility --- generic/tclZipfs.c | 74 +++++++++++++++++++++++++++++------------------------- 1 file changed, 40 insertions(+), 34 deletions(-) diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c index c65b1a6..55b854b 100644 --- a/generic/tclZipfs.c +++ b/generic/tclZipfs.c @@ -186,7 +186,7 @@ typedef struct ZipFile { struct ZipEntry *entries; /* List of files in archive */ struct ZipEntry *topents; /* List of top-level dirs in archive */ #if HAS_DRIVES - int mntdrv; /* Drive letter of mount point */ + int mntdrv; /* Drive letter of mount point */ #endif size_t mntptlen; char *mntpt; /* Mount point */ @@ -199,7 +199,7 @@ typedef struct ZipFile { typedef struct ZipEntry { char *name; /* The full pathname of the virtual file */ ZipFile *zipfile; /* The ZIP file holding this virtual file */ - long offset; /* Data offset into memory mapped ZIP file */ + Tcl_WideInt offset; /* Data offset into memory mapped ZIP file */ int nbyte; /* Uncompressed size of the virtual file */ int nbytecompr; /* Compressed size of the virtual file */ int cmeth; /* Compress method */ @@ -225,7 +225,7 @@ typedef struct ZipChannel { size_t nread; /* Pos of next byte to be read from the channel */ unsigned char *ubuf; /* Pointer to the uncompressed data */ int iscompr; /* True if data is compressed */ - int isdir; /* Set to 1 if directory, or -1 if root */ + int isdir; /* Set to 1 if directory, or -1 if root */ int isenc; /* True if data is encrypted */ int iswr; /* True if open for writing */ unsigned long keys[3]; /* Key for decryption */ @@ -1039,7 +1039,7 @@ ZipFSOpenArchive(Tcl_Interp *interp, const char *zipname, int needZip, ZipFile * goto error; } zf->length = Tcl_Seek(zf->chan, 0, SEEK_END); - if ((zf->length < ZIP_CENTRAL_END_LEN) || (zf->length > 64 * 1024 * 1024)) { + if ((zf->length - ZIP_CENTRAL_END_LEN) > (64 * 1024 * 1024 - ZIP_CENTRAL_END_LEN)) { ZIPFS_ERROR(interp,"illegal file size"); goto error; } @@ -1057,7 +1057,7 @@ ZipFSOpenArchive(Tcl_Interp *interp, const char *zipname, int needZip, ZipFile * Tcl_Close(interp, zf->chan); zf->chan = NULL; } else { -#ifdef _WIN32) +#if defined(_WIN32) || defined(_WIN64) # ifdef _WIN64 i = GetFileSizeEx((HANDLE) handle, (PLARGE_INTEGER)&zf->length); if ( @@ -1919,8 +1919,10 @@ ZipAddFile( ZipEntry *z; z_stream stream; const char *zpath; - int nbyte, nbytecompr, len, crc, flush, pos[3], zpathlen, olen; - int mtime = 0, isNew, align = 0, cmeth; + int crc, flush, zpathlen, olen; + size_t nbyte, nbytecompr, len, align = 0; + Tcl_WideInt pos[3]; + int mtime = 0, isNew, cmeth; unsigned long keys[3], keys0[3]; char obuf[4096]; @@ -1964,11 +1966,11 @@ ZipAddFile( Tcl_ResetResult(interp); crc = 0; nbyte = nbytecompr = 0; - while ((len = Tcl_Read(in, buf, bufsize)) > 0) { + while ((len = Tcl_Read(in, buf, bufsize)) + 1 > 1) { crc = crc32(crc, (unsigned char *) buf, len); nbyte += len; } - if (len == -1) { + if (len == (size_t)-1) { if (nbyte == 0) { if (strcmp("illegal operation on a directory", Tcl_PosixError(interp)) == 0) { @@ -1991,7 +1993,7 @@ ZipAddFile( memset(buf, '\0', ZIP_LOCAL_HEADER_LEN); memcpy(buf + ZIP_LOCAL_HEADER_LEN, zpath, zpathlen); len = zpathlen + ZIP_LOCAL_HEADER_LEN; - if (Tcl_Write(out, buf, len) != len) { + if ((size_t)Tcl_Write(out, buf, len) != len) { wrerr: Tcl_AppendResult(interp, "write error", (char *) NULL); Tcl_Close(interp, in); @@ -2008,7 +2010,7 @@ wrerr: zip_write_short(abuf, 0xffff); zip_write_short(abuf + 2, align - 4); zip_write_int(abuf + 4, 0x03020100); - if (Tcl_Write(out, (const char *)abuf, align) != align) { + if ((size_t)Tcl_Write(out, (const char *)abuf, align) != align) { goto wrerr; } } @@ -2063,7 +2065,7 @@ wrerr: } do { len = Tcl_Read(in, buf, bufsize); - if (len == -1) { + if (len == (size_t)-1) { Tcl_AppendResult(interp, "read error on \"", path, "\"", (char *) NULL); deflateEnd(&stream); @@ -2077,7 +2079,7 @@ wrerr: stream.avail_out = sizeof (obuf); stream.next_out = (unsigned char *) obuf; len = deflate(&stream, flush); - if (len == Z_STREAM_ERROR) { + if (len == (size_t)Z_STREAM_ERROR) { Tcl_AppendResult(interp, "deflate error on \"", path, "\"", (char *) NULL); deflateEnd(&stream); @@ -2112,7 +2114,7 @@ wrerr: if (Tcl_Seek(in, 0, SEEK_SET) != 0) { goto seekErr; } - if ((int) Tcl_Seek(out, pos[2], SEEK_SET) != pos[2]) { + if (Tcl_Seek(out, pos[2], SEEK_SET) != pos[2]) { seekErr: Tcl_Close(interp, in); Tcl_AppendResult(interp, "seek error", (char *) NULL); @@ -2121,7 +2123,7 @@ seekErr: nbytecompr = (passwd != NULL) ? 12 : 0; while (1) { len = Tcl_Read(in, buf, bufsize); - if (len == -1) { + if (len == (size_t)-1) { Tcl_AppendResult(interp, "read error on \"", path, "\"", (char *) NULL); Tcl_Close(interp, in); @@ -2130,13 +2132,14 @@ seekErr: break; } if (passwd != NULL) { - int i, tmp; + size_t i; + int tmp; for (i = 0; i < len; i++) { buf[i] = (char) zencode(keys0, crc32tab, buf[i], tmp); } } - if (Tcl_Write(out, buf, len) != len) { + if ((size_t)Tcl_Write(out, buf, len) != len) { Tcl_AppendResult(interp, "write error", (char *) NULL); Tcl_Close(interp, in); return TCL_ERROR; @@ -2190,7 +2193,7 @@ seekErr: zip_write_int(buf + ZIP_LOCAL_UNCOMPLEN_OFFS, z->nbyte); zip_write_short(buf + ZIP_LOCAL_PATHLEN_OFFS, zpathlen); zip_write_short(buf + ZIP_LOCAL_EXTRALEN_OFFS, align); - if ((int) Tcl_Seek(out, pos[0], SEEK_SET) != pos[0]) { + if (Tcl_Seek(out, pos[0], SEEK_SET) != pos[0]) { Tcl_DeleteHashEntry(hPtr); Tcl_Free((char *) z); Tcl_AppendResult(interp, "seek error", (char *) NULL); @@ -2203,7 +2206,7 @@ seekErr: return TCL_ERROR; } Tcl_Flush(out); - if ((int) Tcl_Seek(out, pos[1], SEEK_SET) != pos[1]) { + if (Tcl_Seek(out, pos[1], SEEK_SET) != pos[1]) { Tcl_DeleteHashEntry(hPtr); Tcl_Free((char *) z); Tcl_AppendResult(interp, "seek error", (char *) NULL); @@ -2236,7 +2239,9 @@ ZipFSMkZipOrImgObjCmd(ClientData clientData, Tcl_Interp *interp, int isImg, int isList, int objc, Tcl_Obj *const objv[]) { Tcl_Channel out; - int len = 0, pwlen = 0, slen = 0, i, count, ret = TCL_ERROR, lobjc, pos[3]; + int pwlen = 0, count, ret = TCL_ERROR, lobjc; + size_t len, slen = 0, i = 0; + Tcl_WideInt pos[3]; Tcl_Obj **lobjv, *list = NULL; ZipEntry *z; Tcl_HashEntry *hPtr; @@ -2385,7 +2390,8 @@ ZipFSMkZipOrImgObjCmd(ClientData clientData, Tcl_Interp *interp, Unlock(); } } else { - int k, m, n; + size_t k; + int m, n; Tcl_Channel in; const char *errMsg = "seek error"; @@ -2405,7 +2411,7 @@ ZipFSMkZipOrImgObjCmd(ClientData clientData, Tcl_Interp *interp, Tcl_SetChannelOption(interp, in, "-translation", "binary"); Tcl_SetChannelOption(interp, in, "-encoding", "binary"); i = Tcl_Seek(in, 0, SEEK_END); - if (i == -1) { + if (i == (size_t)-1) { cperr: memset(pwbuf, 0, sizeof (pwbuf)); Tcl_DecrRefCount(list); @@ -2456,7 +2462,7 @@ cperr: strip = Tcl_GetString(objv[3]); slen = strlen(strip); } - for (i = 0; i < lobjc; i += (isList ? 2 : 1)) { + for (i = 0; i < (size_t)lobjc; i += (isList ? 2 : 1)) { const char *path, *name; path = Tcl_GetString(lobjv[i]); @@ -2485,7 +2491,7 @@ cperr: } pos[1] = Tcl_Tell(out); count = 0; - for (i = 0; i < lobjc; i += (isList ? 2 : 1)) { + for (i = 0; i < (size_t)lobjc; i += (isList ? 2 : 1)) { const char *path, *name; path = Tcl_GetString(lobjv[i]); @@ -2532,7 +2538,7 @@ cperr: zip_write_int(buf + ZIP_CENTRAL_LOCALHDR_OFFS, z->offset - pos[0]); if ( (Tcl_Write(out, buf, ZIP_CENTRAL_HEADER_LEN) != ZIP_CENTRAL_HEADER_LEN) - || (Tcl_Write(out, z->name, len) != len) + || ((size_t)Tcl_Write(out, z->name, len) != len) ) { Tcl_SetObjResult(interp, Tcl_NewStringObj("write error", -1)); goto done; @@ -2685,7 +2691,7 @@ ZipFSCanonicalObjCmd( Tcl_SetObjResult(interp,Tcl_NewStringObj(result,-1)); return TCL_OK; } - + /* *------------------------------------------------------------------------- * @@ -2770,9 +2776,9 @@ ZipFSInfoObjCmd( Tcl_ListObjAppendElement(interp, result, Tcl_NewStringObj(z->zipfile->name, -1)); - Tcl_ListObjAppendElement(interp, result, Tcl_NewIntObj(z->nbyte)); - Tcl_ListObjAppendElement(interp, result, Tcl_NewIntObj(z->nbytecompr)); - Tcl_ListObjAppendElement(interp, result, Tcl_NewIntObj(z->offset)); + Tcl_ListObjAppendElement(interp, result, Tcl_NewWideIntObj(z->nbyte)); + Tcl_ListObjAppendElement(interp, result, Tcl_NewWideIntObj(z->nbytecompr)); + Tcl_ListObjAppendElement(interp, result, Tcl_NewWideIntObj(z->offset)); } Unlock(); return TCL_OK; @@ -3574,7 +3580,7 @@ cerror: } } wrapchan: - sprintf(cname, "zipfs_%lx_%d", (unsigned long) z->offset, ZipFS.idCount++); + sprintf(cname, "zipfs_%" TCL_LL_MODIFIER "x_%d", z->offset, ZipFS.idCount++); z->zipfile->nopen++; Unlock(); return Tcl_CreateChannel(&ZipChannelType, cname, (ClientData) info, flags); @@ -4098,13 +4104,13 @@ Zip_FSFileAttrsGetProc(Tcl_Interp *interp, int index, Tcl_Obj *pathPtr, } switch (index) { case 0: - *objPtrRef = Tcl_NewIntObj(z->nbyte); + *objPtrRef = Tcl_NewWideIntObj(z->nbyte); goto done; case 1: - *objPtrRef= Tcl_NewIntObj(z->nbytecompr); + *objPtrRef = Tcl_NewWideIntObj(z->nbytecompr); goto done; case 2: - *objPtrRef= Tcl_NewLongObj(z->offset); + *objPtrRef= Tcl_NewWideIntObj(z->offset); goto done; case 3: *objPtrRef= Tcl_NewStringObj(z->zipfile->mntpt, z->zipfile->mntptlen); @@ -4407,7 +4413,7 @@ int TclZipfs_AppHook(int *argc, char ***argv) */ char *archive; - Tcl_FindExecutable(*argv[0]); + Tcl_FindExecutable((*argv)[0]); archive=(char *)Tcl_GetNameOfExecutable(); TclZipfs_Init(NULL); /* -- cgit v0.12 From 177528494062f82a82280977e5ea3129515cf955 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Thu, 13 Sep 2018 20:30:20 +0000 Subject: Fix test-case registry-6.20, which started failing starting with the TIP #389 commit. --- generic/tclStubInit.c | 20 +++++++++++++++++--- win/tclWin32Dll.c | 18 ++++++++++++++++-- 2 files changed, 33 insertions(+), 5 deletions(-) diff --git a/generic/tclStubInit.c b/generic/tclStubInit.c index bf3a8d1..36550ea 100644 --- a/generic/tclStubInit.c +++ b/generic/tclStubInit.c @@ -225,17 +225,31 @@ Tcl_WinUtfToTChar( int len, Tcl_DString *dsPtr) { - WCHAR *wp; + WCHAR *wp, *p; int size = MultiByteToWideChar(CP_UTF8, 0, string, len, 0, 0); Tcl_DStringInit(dsPtr); Tcl_DStringSetLength(dsPtr, 2*size+2); - wp = (WCHAR *)Tcl_DStringValue(dsPtr); + p = wp = (WCHAR *)Tcl_DStringValue(dsPtr); MultiByteToWideChar(CP_UTF8, 0, string, len, wp, size+1); if (len == -1) --size; /* account for 0-byte at string end */ + + /* It turns out that MultiByteToWideChar() cannot handle the 'modified' + * UTF-8 as used by Tcl. Every sequence of 0xC0 followed by 0x80 will + * be translated to two 0xfffd characters. This results in a test-failure + * of the registry-6.20 test-case. The simplest solution is to search for + * those two 0xfffd characters and replace them by a \u0000 character. */ + while (p < wp + size - 1) { + if (p[0] == 0xfffd && p[1] == 0xfffd) { + memmove(p+1, p+2, sizeof(WCHAR) * (p - wp + size - 2)); + p[0] = 0; + ++p; --size; + } + ++p; + } Tcl_DStringSetLength(dsPtr, 2*size); wp[size] = 0; - return (char *)wp; + return wp; } char * diff --git a/win/tclWin32Dll.c b/win/tclWin32Dll.c index 74787c5..26da566 100644 --- a/win/tclWin32Dll.c +++ b/win/tclWin32Dll.c @@ -471,14 +471,28 @@ Tcl_WinUtfToTChar( Tcl_DString *dsPtr) /* Uninitialized or free DString in which the * converted string is stored. */ { - TCHAR *wp; + TCHAR *wp, *p; int size = MultiByteToWideChar(CP_UTF8, 0, string, len, 0, 0); Tcl_DStringInit(dsPtr); Tcl_DStringSetLength(dsPtr, 2*size+2); - wp = (TCHAR *)Tcl_DStringValue(dsPtr); + p = wp = (TCHAR *)Tcl_DStringValue(dsPtr); MultiByteToWideChar(CP_UTF8, 0, string, len, wp, size+1); if (len == -1) --size; /* account for 0-byte at string end */ + + /* It turns out that MultiByteToWideChar() cannot handle the 'modified' + * UTF-8 as used by Tcl. Every sequence of 0xC0 followed by 0x80 will + * be translated to two 0xfffd characters. This results in a test-failure + * of the registry-6.20 test-case. The simplest solution is to search for + * those two 0xfffd characters and replace them by a \u0000 character. */ + while (p < wp + size - 1) { + if (p[0] == 0xfffd && p[1] == 0xfffd) { + memmove(p+1, p+2, sizeof(TCHAR) * (p - wp + size - 2)); + p[0] = 0; + ++p; --size; + } + ++p; + } Tcl_DStringSetLength(dsPtr, 2*size); wp[size] = 0; return wp; -- cgit v0.12 From f11320b6b0dd2681bef8470d4fcf7c3b7eb6cbbd Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Thu, 13 Sep 2018 20:31:45 +0000 Subject: Fix various test-cases, which started failing on Windows due to TIP #430 --- tests/env.test | 2 ++ tests/exec.test | 2 ++ tests/platform.test | 2 +- tests/thread.test | 7 +++++-- win/Makefile.in | 4 ++++ 5 files changed, 14 insertions(+), 3 deletions(-) diff --git a/tests/env.test b/tests/env.test index 59d5391..79a353a 100644 --- a/tests/env.test +++ b/tests/env.test @@ -16,6 +16,8 @@ if {[lsearch [namespace children] ::tcltest] == -1} { namespace import -force ::tcltest::* } +loadTestedCommands +catch [list package require -exact Tcltest [info patchlevel]] package require tcltests # [exec] is required here to see the actual environment received by child diff --git a/tests/exec.test b/tests/exec.test index dfc44c4..4fd8b8d 100644 --- a/tests/exec.test +++ b/tests/exec.test @@ -17,6 +17,8 @@ package require tcltest 2 namespace import -force ::tcltest::* +loadTestedCommands +catch [list package require -exact Tcltest [info patchlevel]] package require tcltests # All tests require the "exec" command. diff --git a/tests/platform.test b/tests/platform.test index 5880fb9..53d534e 100644 --- a/tests/platform.test +++ b/tests/platform.test @@ -10,7 +10,6 @@ # of this file, and for a DISCLAIMER OF ALL WARRANTIES. package require tcltest 2 -package require tcltests namespace eval ::tcl::test::platform { namespace import ::tcltest::testConstraint @@ -23,6 +22,7 @@ namespace eval ::tcl::test::platform { ::tcltest::loadTestedCommands catch [list package require -exact Tcltest [info patchlevel]] +package require tcltests testConstraint testCPUID [llength [info commands testcpuid]] testConstraint testlongsize [llength [info commands testlongsize]] diff --git a/tests/thread.test b/tests/thread.test index eaaaa41..2524911 100644 --- a/tests/thread.test +++ b/tests/thread.test @@ -11,14 +11,17 @@ # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. +if {"::tcltest" ni [namespace children]} { + package require tcltest 2 + namespace import -force ::tcltest::* +} # when thread::release is used, -wait is passed in order allow the thread to # be fully finalized, which avoids valgrind "still reachable" reports. -package require tcltests - ::tcltest::loadTestedCommands catch [list package require -exact Tcltest [info patchlevel]] +package require tcltests # Some tests require the testthread command diff --git a/win/Makefile.in b/win/Makefile.in index 1d9c522..b5095e7 100644 --- a/win/Makefile.in +++ b/win/Makefile.in @@ -486,6 +486,8 @@ ${TCL_ZIP_FILE}: ${ZIP_INSTALL_OBJS} rm -rf ${TCL_VFS_ROOT} mkdir -p ${TCL_VFS_PATH} $(COPY) -a $(TOP_DIR)/library/* ${TCL_VFS_PATH} + $(COPY) ${DDE_DLL_FILE} ${TCL_VFS_PATH}/dde + $(COPY) ${REG_DLL_FILE} ${TCL_VFS_PATH}/reg cd ${TCL_VFS_ROOT} ; ${NATIVE_ZIP} ${ZIP_PROG_OPTIONS} ../${TCL_ZIP_FILE} ${ZIP_PROG_VFSSEARCH} $(TCLSH): $(TCLSH_OBJS) @LIBRARIES@ $(TCL_STUB_LIB_FILE) tclsh.$(RES) @@ -864,6 +866,7 @@ test-tcl: binaries $(TCLSH) $(CAT32) $(TEST_DLL_FILE) TCL_LIBRARY="$(LIBRARY_DIR)"; export TCL_LIBRARY; \ ./$(TCLSH) "$(ROOT_DIR_NATIVE)/tests/all.tcl" $(TESTFLAGS) \ -load "package ifneeded Tcltest ${VERSION}@TCL_PATCH_LEVEL@ [list load [file normalize ${TEST_DLL_FILE}] Tcltest]; \ + package ifneeded tcltests 0.1 \"[list source [file normalize $(ROOT_DIR_NATIVE)/tests/tcltests.tcl]];package provide tcltests 0.1\"; \ package ifneeded dde 1.4.0 [list load [file normalize ${DDE_DLL_FILE}] dde]; \ package ifneeded registry 1.3.2 [list load [file normalize ${REG_DLL_FILE}] registry]" | ./$(CAT32) @@ -871,6 +874,7 @@ test-tcl: binaries $(TCLSH) $(CAT32) $(TEST_DLL_FILE) runtest: binaries $(TCLSH) $(TEST_DLL_FILE) @TCL_LIBRARY="$(LIBRARY_DIR)"; export TCL_LIBRARY; \ ./$(TCLSH) $(TESTFLAGS) -load "package ifneeded Tcltest ${VERSION}@TCL_PATCH_LEVEL@ [list load [file normalize ${TEST_DLL_FILE}] Tcltest]; \ + package ifneeded tcltests 0.1 \"[list source [file normalize $(ROOT_DIR_NATIVE)/tests/tcltests.tcl]];package provide tcltests 0.1\"; \ package ifneeded dde 1.4.0 [list load [file normalize ${DDE_DLL_FILE}] dde]; \ package ifneeded registry 1.3.2 [list load [file normalize ${REG_DLL_FILE}] registry]" $(SCRIPT) -- cgit v0.12 From c5943ec574403a010f3065a6d8fdb6d590e68de4 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Thu, 13 Sep 2018 20:33:58 +0000 Subject: Eliminate the use of macro's like LLONG_MAX|MIN, since they assume that Tcl_WideInt equals "long long". Also eliminate uses of Tcl_WideAsLong() and friends, as - often - simple type cases make things more clear. --- generic/tclIO.c | 34 +++++++++++++++++----------------- generic/tclIOCmd.c | 4 ++-- generic/tclIOGT.c | 13 ++++++------- generic/tclIORChan.c | 6 +++--- generic/tclIORTrans.c | 17 ++++++++--------- generic/tclIOUtil.c | 4 ++-- generic/tclObj.c | 4 ++-- generic/tclPort.h | 17 ++--------------- generic/tclStringObj.c | 2 +- generic/tclStubInit.c | 10 ++-------- generic/tclTest.c | 4 ++-- unix/tclUnixChan.c | 8 ++++---- win/tclWinChan.c | 10 +++++----- 13 files changed, 56 insertions(+), 77 deletions(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index ad6c7ee..10362d4 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -482,13 +482,13 @@ ChanSeek( offset, mode, errnoPtr); } - if (offsetTcl_LongAsWide(LONG_MAX)) { + if (offsetLONG_MAX) { *errnoPtr = EOVERFLOW; - return Tcl_LongAsWide(-1); + return -1; } - return Tcl_LongAsWide(chanPtr->typePtr->seekProc(chanPtr->instanceData, - Tcl_WideAsLong(offset), mode, errnoPtr)); + return chanPtr->typePtr->seekProc(chanPtr->instanceData, + offset, mode, errnoPtr); } static inline void @@ -6953,7 +6953,7 @@ Tcl_Seek( * non-blocking mode after the seek. */ if (CheckChannelErrors(statePtr, TCL_WRITABLE | TCL_READABLE) != 0) { - return Tcl_LongAsWide(-1); + return -1; } /* @@ -6964,7 +6964,7 @@ Tcl_Seek( */ if (CheckForDeadChannel(NULL, statePtr)) { - return Tcl_LongAsWide(-1); + return -1; } /* @@ -6980,7 +6980,7 @@ Tcl_Seek( if (chanPtr->typePtr->seekProc == NULL) { Tcl_SetErrno(EINVAL); - return Tcl_LongAsWide(-1); + return -1; } /* @@ -6993,7 +6993,7 @@ Tcl_Seek( if ((inputBuffered != 0) && (outputBuffered != 0)) { Tcl_SetErrno(EFAULT); - return Tcl_LongAsWide(-1); + return -1; } /* @@ -7036,7 +7036,7 @@ Tcl_Seek( wasAsync = 1; result = StackSetBlockMode(chanPtr, TCL_MODE_BLOCKING); if (result != 0) { - return Tcl_LongAsWide(-1); + return -1; } ResetFlag(statePtr, CHANNEL_NONBLOCKING); if (GotFlag(statePtr, BG_FLUSH_SCHEDULED)) { @@ -7061,7 +7061,7 @@ Tcl_Seek( */ curPos = ChanSeek(chanPtr, offset, mode, &result); - if (curPos == Tcl_LongAsWide(-1)) { + if (curPos == -1) { Tcl_SetErrno(result); } } @@ -7077,7 +7077,7 @@ Tcl_Seek( SetFlag(statePtr, CHANNEL_NONBLOCKING); result = StackSetBlockMode(chanPtr, TCL_MODE_NONBLOCKING); if (result != 0) { - return Tcl_LongAsWide(-1); + return -1; } } @@ -7117,7 +7117,7 @@ Tcl_Tell( Tcl_WideInt curPos; /* Position on device. */ if (CheckChannelErrors(statePtr, TCL_WRITABLE | TCL_READABLE) != 0) { - return Tcl_LongAsWide(-1); + return -1; } /* @@ -7128,7 +7128,7 @@ Tcl_Tell( */ if (CheckForDeadChannel(NULL, statePtr)) { - return Tcl_LongAsWide(-1); + return -1; } /* @@ -7144,7 +7144,7 @@ Tcl_Tell( if (chanPtr->typePtr->seekProc == NULL) { Tcl_SetErrno(EINVAL); - return Tcl_LongAsWide(-1); + return -1; } /* @@ -7161,10 +7161,10 @@ Tcl_Tell( * wideSeekProc if that is available and non-NULL... */ - curPos = ChanSeek(chanPtr, Tcl_LongAsWide(0), SEEK_CUR, &result); - if (curPos == Tcl_LongAsWide(-1)) { + curPos = ChanSeek(chanPtr, 0, SEEK_CUR, &result); + if (curPos == -1) { Tcl_SetErrno(result); - return Tcl_LongAsWide(-1); + return -1; } if (inputBuffered != 0) { diff --git a/generic/tclIOCmd.c b/generic/tclIOCmd.c index 87bf415..d38240a 100644 --- a/generic/tclIOCmd.c +++ b/generic/tclIOCmd.c @@ -559,7 +559,7 @@ Tcl_SeekObjCmd( TclChannelPreserve(chan); result = Tcl_Seek(chan, offset, mode); - if (result == Tcl_LongAsWide(-1)) { + if (result == -1) { /* * TIP #219. * Capture error messages put by the driver into the bypass area and @@ -1913,7 +1913,7 @@ ChanTruncateObjCmd( */ length = Tcl_Tell(chan); - if (length == Tcl_WideAsLong(-1)) { + if (length == -1) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "could not determine current location in \"%s\": %s", TclGetString(objv[1]), Tcl_PosixError(interp))); diff --git a/generic/tclIOGT.c b/generic/tclIOGT.c index c1e8c44..9949a0e 100644 --- a/generic/tclIOGT.c +++ b/generic/tclIOGT.c @@ -910,7 +910,7 @@ TransformWideSeekProc( Tcl_ChannelWideSeekProc(parentType); ClientData parentData = Tcl_GetChannelInstanceData(parent); - if ((offset == Tcl_LongAsWide(0)) && (mode == SEEK_CUR)) { + if ((offset == 0) && (mode == SEEK_CUR)) { /* * This is no seek but a request to tell the caller the current * location. Simply pass the request down. @@ -920,8 +920,7 @@ TransformWideSeekProc( return parentWideSeekProc(parentData, offset, mode, errorCodePtr); } - return Tcl_LongAsWide(parentSeekProc(parentData, 0, mode, - errorCodePtr)); + return parentSeekProc(parentData, 0, mode, errorCodePtr); } /* @@ -961,13 +960,13 @@ TransformWideSeekProc( * to go out of the representable range. */ - if (offsetTcl_LongAsWide(LONG_MAX)) { + if (offsetLONG_MAX) { *errorCodePtr = EOVERFLOW; - return Tcl_LongAsWide(-1); + return -1; } - return Tcl_LongAsWide(parentSeekProc(parentData, Tcl_WideAsLong(offset), - mode, errorCodePtr)); + return parentSeekProc(parentData, offset, + mode, errorCodePtr); } /* diff --git a/generic/tclIORChan.c b/generic/tclIORChan.c index 354f1fb..611ee3f 100644 --- a/generic/tclIORChan.c +++ b/generic/tclIORChan.c @@ -1544,7 +1544,7 @@ ReflectSeekWide( goto invalid; } - if (newLoc < Tcl_LongAsWide(0)) { + if (newLoc < 0) { SetChannelErrorStr(rcPtr->chan, msg_seek_beforestart); goto invalid; } @@ -1576,7 +1576,7 @@ ReflectSeek( * routine. */ - return (int) ReflectSeekWide(clientData, Tcl_LongAsWide(offset), seekMode, + return ReflectSeekWide(clientData, offset, seekMode, errorCodePtr); } @@ -3079,7 +3079,7 @@ ForwardProc( Tcl_WideInt newLoc; if (Tcl_GetWideIntFromObj(interp, resObj, &newLoc) == TCL_OK) { - if (newLoc < Tcl_LongAsWide(0)) { + if (newLoc < 0) { ForwardSetStaticError(paramPtr, msg_seek_beforestart); paramPtr->seek.offset = -1; } else { diff --git a/generic/tclIORTrans.c b/generic/tclIORTrans.c index 1a7b940..4841e39 100644 --- a/generic/tclIORTrans.c +++ b/generic/tclIORTrans.c @@ -1340,7 +1340,7 @@ ReflectSeekWide( if (seekProc == NULL) { Tcl_SetErrno(EINVAL); - return Tcl_LongAsWide(-1); + return -1; } /* @@ -1390,16 +1390,15 @@ ReflectSeekWide( parent->typePtr->wideSeekProc != NULL) { curPos = parent->typePtr->wideSeekProc(parent->instanceData, offset, seekMode, errorCodePtr); - } else if (offset < Tcl_LongAsWide(LONG_MIN) || - offset > Tcl_LongAsWide(LONG_MAX)) { + } else if (offset < LONG_MIN || offset > LONG_MAX) { *errorCodePtr = EOVERFLOW; - curPos = Tcl_LongAsWide(-1); + curPos = -1; } else { - curPos = Tcl_LongAsWide(parent->typePtr->seekProc( - parent->instanceData, Tcl_WideAsLong(offset), seekMode, - errorCodePtr)); + curPos = parent->typePtr->seekProc( + parent->instanceData, offset, seekMode, + errorCodePtr); } - if (curPos == Tcl_LongAsWide(-1)) { + if (curPos == -1) { Tcl_SetErrno(*errorCodePtr); } @@ -1422,7 +1421,7 @@ ReflectSeek( * routine. */ - return (int) ReflectSeekWide(clientData, Tcl_LongAsWide(offset), seekMode, + return ReflectSeekWide(clientData, offset, seekMode, errorCodePtr); } diff --git a/generic/tclIOUtil.c b/generic/tclIOUtil.c index bc8b287..11cc22d 100644 --- a/generic/tclIOUtil.c +++ b/generic/tclIOUtil.c @@ -275,8 +275,8 @@ Tcl_Stat( Tcl_WideInt tmp1, tmp2, tmp3 = 0; # define OUT_OF_RANGE(x) \ - (((Tcl_WideInt)(x)) < Tcl_LongAsWide(LONG_MIN) || \ - ((Tcl_WideInt)(x)) > Tcl_LongAsWide(LONG_MAX)) + (((Tcl_WideInt)(x)) < LONG_MIN || \ + ((Tcl_WideInt)(x)) > LONG_MAX) # define OUT_OF_URANGE(x) \ (((Tcl_WideUInt)(x)) > ((Tcl_WideUInt)ULONG_MAX)) diff --git a/generic/tclObj.c b/generic/tclObj.c index ce326fe..d1af60d 100644 --- a/generic/tclObj.c +++ b/generic/tclObj.c @@ -2807,7 +2807,7 @@ Tcl_GetLongFromObj( if (w >= -(Tcl_WideInt)(ULONG_MAX) && w <= (Tcl_WideInt)(ULONG_MAX)) { - *longPtr = Tcl_WideAsLong(w); + *longPtr = (long) w; return TCL_OK; } goto tooLarge; @@ -3536,7 +3536,7 @@ Tcl_SetBignumObj( while (numBytes-- > 0) { value = (value << CHAR_BIT) | *bytes++; } - if (value > (((~(Tcl_WideUInt)0) >> 1) + bignumValue->sign)) { + if (value > ((Tcl_WideUInt)WIDE_MAX + bignumValue->sign)) { goto tooLargeForWide; } if (bignumValue->sign) { diff --git a/generic/tclPort.h b/generic/tclPort.h index 12a60db..33c0db6 100644 --- a/generic/tclPort.h +++ b/generic/tclPort.h @@ -24,20 +24,7 @@ #endif #include "tcl.h" -#if !defined(LLONG_MIN) -# ifdef TCL_WIDE_INT_IS_LONG -# define LLONG_MIN LONG_MIN -# else -# ifdef LLONG_BIT -# define LLONG_MIN ((Tcl_WideInt)(Tcl_LongAsWide(1)<<(LLONG_BIT-1))) -# else -/* Assume we're on a system with a 64-bit 'long long' type */ -# define LLONG_MIN ((Tcl_WideInt)(Tcl_LongAsWide(1)<<63)) -# endif -# endif -/* Assume that if LLONG_MIN is undefined, then so is LLONG_MAX */ -# define LLONG_MAX (~LLONG_MIN) -#endif - +#define WIDE_MAX ((Tcl_WideInt)((~(Tcl_WideUInt)0) >> 1)) +#define WIDE_MIN ((Tcl_WideInt)((Tcl_WideUInt)WIDE_MAX+1)) #endif /* _TCLPORT */ diff --git a/generic/tclStringObj.c b/generic/tclStringObj.c index f238268..fa55bb0 100644 --- a/generic/tclStringObj.c +++ b/generic/tclStringObj.c @@ -2107,7 +2107,7 @@ Tcl_AppendFormatToObj( if (TclGetWideBitsFromObj(interp, segment, &w) != TCL_OK) { goto error; } else { - l = Tcl_WideAsLong(w); + l = (long) w; } if (useShort) { s = (short) l; diff --git a/generic/tclStubInit.c b/generic/tclStubInit.c index 36550ea..cdf547c 100644 --- a/generic/tclStubInit.c +++ b/generic/tclStubInit.c @@ -445,20 +445,14 @@ seekOld( int offset, /* Offset to seek to. */ int mode) /* Relative to which location to seek? */ { - Tcl_WideInt wOffset, wResult; - - wOffset = Tcl_LongAsWide((long) offset); - wResult = Tcl_Seek(chan, wOffset, mode); - return (int) Tcl_WideAsLong(wResult); + return Tcl_Seek(chan, offset, mode); } static int tellOld( Tcl_Channel chan) /* The channel to return pos for. */ { - Tcl_WideInt wResult = Tcl_Tell(chan); - - return (int) Tcl_WideAsLong(wResult); + return Tcl_Tell(chan); } #endif /* !TCL_NO_DEPRECATED */ diff --git a/generic/tclTest.c b/generic/tclTest.c index 48b4761..18bfc1b 100644 --- a/generic/tclTest.c +++ b/generic/tclTest.c @@ -2832,7 +2832,7 @@ TestlinkCmd( static int intVar = 43; static int boolVar = 4; static double realVar = 1.23; - static Tcl_WideInt wideVar = Tcl_LongAsWide(79); + static Tcl_WideInt wideVar = 79; static char *stringVar = NULL; static char charVar = '@'; static unsigned char ucharVar = 130; @@ -2842,7 +2842,7 @@ TestlinkCmd( static long longVar = 123456789L; static unsigned long ulongVar = 3456789012UL; static float floatVar = 4.5; - static Tcl_WideUInt uwideVar = (Tcl_WideUInt) Tcl_LongAsWide(123); + static Tcl_WideUInt uwideVar = 123; static int created = 0; char buffer[2*TCL_DOUBLE_SPACE]; int writable, flag; diff --git a/unix/tclUnixChan.c b/unix/tclUnixChan.c index ced684a..435579a 100644 --- a/unix/tclUnixChan.c +++ b/unix/tclUnixChan.c @@ -383,7 +383,7 @@ FileSeekProc( */ oldLoc = TclOSseek(fsPtr->fd, (Tcl_SeekOffset) 0, SEEK_CUR); - if (oldLoc == Tcl_LongAsWide(-1)) { + if (oldLoc == -1) { /* * Bad things are happening. Error out... */ @@ -398,14 +398,14 @@ FileSeekProc( * Check for expressability in our return type, and roll-back otherwise. */ - if (newLoc > Tcl_LongAsWide(INT_MAX)) { + if (newLoc > INT_MAX) { *errorCodePtr = EOVERFLOW; TclOSseek(fsPtr->fd, (Tcl_SeekOffset) oldLoc, SEEK_SET); return -1; } else { - *errorCodePtr = (newLoc == Tcl_LongAsWide(-1)) ? errno : 0; + *errorCodePtr = (newLoc == -1) ? errno : 0; } - return (int) Tcl_WideAsLong(newLoc); + return (int) newLoc; } /* diff --git a/win/tclWinChan.c b/win/tclWinChan.c index 8ffb31f..8c47be6 100644 --- a/win/tclWinChan.c +++ b/win/tclWinChan.c @@ -554,8 +554,8 @@ FileWideSeekProc( moveMethod = FILE_END; } - newPosHigh = Tcl_WideAsLong(offset >> 32); - newPos = SetFilePointer(infoPtr->handle, Tcl_WideAsLong(offset), + newPosHigh = (LONG)(offset >> 32); + newPos = SetFilePointer(infoPtr->handle, (LONG)offset, &newPosHigh, moveMethod); if (newPos == (LONG) INVALID_SET_FILE_POINTER) { DWORD winError = GetLastError(); @@ -567,7 +567,7 @@ FileWideSeekProc( } } return (((Tcl_WideInt)((unsigned)newPos)) - | (Tcl_LongAsWide(newPosHigh) << 32)); + | ((Tcl_WideInt)newPosHigh << 32)); } /* @@ -613,8 +613,8 @@ FileTruncateProc( * Move to where we want to truncate */ - newPosHigh = Tcl_WideAsLong(length >> 32); - newPos = SetFilePointer(infoPtr->handle, Tcl_WideAsLong(length), + newPosHigh = (LONG)(length >> 32); + newPos = SetFilePointer(infoPtr->handle, (LONG)length, &newPosHigh, FILE_BEGIN); if (newPos == (LONG) INVALID_SET_FILE_POINTER) { DWORD winError = GetLastError(); -- cgit v0.12 From bd42171094d5ada2e2e46978f2e842a66b6fa44e Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Thu, 13 Sep 2018 20:37:44 +0000 Subject: missing type-cast --- generic/tclStubInit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generic/tclStubInit.c b/generic/tclStubInit.c index cdf547c..134b68f 100644 --- a/generic/tclStubInit.c +++ b/generic/tclStubInit.c @@ -249,7 +249,7 @@ Tcl_WinUtfToTChar( } Tcl_DStringSetLength(dsPtr, 2*size); wp[size] = 0; - return wp; + return (char *) wp; } char * -- cgit v0.12 From df89a7f2110fcd0e00738488b7c9e54f7357feb3 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Sat, 22 Sep 2018 10:09:23 +0000 Subject: Prevent possible build order problem, due to missing dde/registry dll's. Make sure that Tcl_WinTChar2Utf() never produces intermediate null-bytes. --- generic/tclStubInit.c | 17 +++++++++++++---- win/Makefile.in | 2 +- win/tclWin32Dll.c | 17 +++++++++++++---- 3 files changed, 27 insertions(+), 9 deletions(-) diff --git a/generic/tclStubInit.c b/generic/tclStubInit.c index 134b68f..cb33288 100644 --- a/generic/tclStubInit.c +++ b/generic/tclStubInit.c @@ -242,7 +242,7 @@ Tcl_WinUtfToTChar( while (p < wp + size - 1) { if (p[0] == 0xfffd && p[1] == 0xfffd) { memmove(p+1, p+2, sizeof(WCHAR) * (p - wp + size - 2)); - p[0] = 0; + p[0] = '\0'; ++p; --size; } ++p; @@ -258,7 +258,7 @@ Tcl_WinTCharToUtf( int len, Tcl_DString *dsPtr) { - char *p; + char *p, *r; int size; if (len > 0) { @@ -266,10 +266,19 @@ Tcl_WinTCharToUtf( } size = WideCharToMultiByte(CP_UTF8, 0, string, len, 0, 0, NULL, NULL); Tcl_DStringInit(dsPtr); - Tcl_DStringSetLength(dsPtr, size+1); - p = (char *)Tcl_DStringValue(dsPtr); + Tcl_DStringSetLength(dsPtr, size+8); /* Add some spare, in case of NULL-bytes */ + r = p = (char *)Tcl_DStringValue(dsPtr); WideCharToMultiByte(CP_UTF8, 0, string, len, p, size, NULL, NULL); if (len == -1) --size; /* account for 0-byte at string end */ + while (r < p+size) { + if (!*r) { + /* Output contains '\0'-byte, but Tcl expect two-bytes: C0 80 */ + memmove(r+2, r+1, p-r+size-1); + memcpy(r++, "\xC0\x80", 2); + Tcl_DStringSetLength(dsPtr, ++size + 1); + } + ++r; + } Tcl_DStringSetLength(dsPtr, size); p[size] = 0; return p; diff --git a/win/Makefile.in b/win/Makefile.in index b5095e7..3e117d1 100644 --- a/win/Makefile.in +++ b/win/Makefile.in @@ -482,7 +482,7 @@ doc: tclzipfile: ${TCL_ZIP_FILE} -${TCL_ZIP_FILE}: ${ZIP_INSTALL_OBJS} +${TCL_ZIP_FILE}: ${ZIP_INSTALL_OBJS} ${DDE_DLL_FILE} ${REG_DLL_FILE} rm -rf ${TCL_VFS_ROOT} mkdir -p ${TCL_VFS_PATH} $(COPY) -a $(TOP_DIR)/library/* ${TCL_VFS_PATH} diff --git a/win/tclWin32Dll.c b/win/tclWin32Dll.c index 26da566..2216a66 100644 --- a/win/tclWin32Dll.c +++ b/win/tclWin32Dll.c @@ -488,7 +488,7 @@ Tcl_WinUtfToTChar( while (p < wp + size - 1) { if (p[0] == 0xfffd && p[1] == 0xfffd) { memmove(p+1, p+2, sizeof(TCHAR) * (p - wp + size - 2)); - p[0] = 0; + p[0] = '\0'; ++p; --size; } ++p; @@ -506,7 +506,7 @@ Tcl_WinTCharToUtf( Tcl_DString *dsPtr) /* Uninitialized or free DString in which the * converted string is stored. */ { - char *p; + char *p, *r; int size; if (len > 0) { @@ -514,10 +514,19 @@ Tcl_WinTCharToUtf( } size = WideCharToMultiByte(CP_UTF8, 0, string, len, 0, 0, NULL, NULL); Tcl_DStringInit(dsPtr); - Tcl_DStringSetLength(dsPtr, size+1); - p = (char *)Tcl_DStringValue(dsPtr); + Tcl_DStringSetLength(dsPtr, size+8); /* Add some spare, in case of NULL-bytes */ + r = p = (char *)Tcl_DStringValue(dsPtr); WideCharToMultiByte(CP_UTF8, 0, string, len, p, size, NULL, NULL); if (len == -1) --size; /* account for 0-byte at string end */ + while (r < p+size) { + if (!*r) { + /* Output contains '\0'-byte, but Tcl expect two-bytes: C0 80 */ + memmove(r+2, r+1, p-r+size-1); + memcpy(r++, "\xC0\x80", 2); + Tcl_DStringSetLength(dsPtr, ++size + 1); + } + ++r; + } Tcl_DStringSetLength(dsPtr, size); p[size] = 0; return p; -- cgit v0.12 From 63ef0e3d26d5ef38c104cb50b97e7cddb70dbba6 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Sat, 22 Sep 2018 10:20:28 +0000 Subject: Update http version number, and fix some related test-cases --- library/http/http.tcl | 2 +- library/http/pkgIndex.tcl | 2 +- tests/http.test | 6 +++--- unix/Makefile.in | 4 ++-- win/Makefile.in | 4 ++-- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/library/http/http.tcl b/library/http/http.tcl index c177374..643a119 100644 --- a/library/http/http.tcl +++ b/library/http/http.tcl @@ -11,7 +11,7 @@ package require Tcl 8.6- # Keep this in sync with pkgIndex.tcl and with the install directories in # Makefiles -package provide http 2.8.13 +package provide http 2.9.0 namespace eval http { # Allow resourcing to not clobber existing data diff --git a/library/http/pkgIndex.tcl b/library/http/pkgIndex.tcl index 3324af9..4f74635 100644 --- a/library/http/pkgIndex.tcl +++ b/library/http/pkgIndex.tcl @@ -1,2 +1,2 @@ if {![package vsatisfies [package provide Tcl] 8.6-]} {return} -package ifneeded http 2.8.13 [list tclPkgSetup $dir http 2.8.13 {{http.tcl source {::http::config ::http::formatQuery ::http::geturl ::http::reset ::http::wait ::http::register ::http::unregister ::http::mapReply}}}] +package ifneeded http 2.9.0 [list tclPkgSetup $dir http 2.9.0 {{http.tcl source {::http::config ::http::formatQuery ::http::geturl ::http::reset ::http::wait ::http::register ::http::unregister ::http::mapReply}}}] diff --git a/tests/http.test b/tests/http.test index 5a00cd5..242dceb 100644 --- a/tests/http.test +++ b/tests/http.test @@ -86,7 +86,7 @@ if {[catch {package present Thread}] == 0 && [file exists $httpdFile]} { test http-1.1 {http::config} { http::config -useragent UserAgent http::config -} [list -accept */* -proxyfilter http::ProxyRequired -proxyhost {} -proxyport {} -urlencoding utf-8 -useragent "UserAgent"] +} [list -accept */* -pipeline 1 -postfresh 0 -proxyfilter http::ProxyRequired -proxyhost {} -proxyport {} -repost 0 -urlencoding utf-8 -useragent UserAgent -zip 1] test http-1.2 {http::config} { http::config -proxyfilter } http::ProxyRequired @@ -101,10 +101,10 @@ test http-1.4 {http::config} { set x [http::config] http::config {*}$savedconf set x -} {-accept */* -proxyfilter myFilter -proxyhost nowhere.come -proxyport 8080 -urlencoding iso8859-1 -useragent {Tcl Test Suite}} +} {-accept */* -pipeline 1 -postfresh 0 -proxyfilter myFilter -proxyhost nowhere.come -proxyport 8080 -repost 0 -urlencoding iso8859-1 -useragent {Tcl Test Suite} -zip 1} test http-1.5 {http::config} -returnCodes error -body { http::config -proxyhost {} -junk 8080 -} -result {Unknown option -junk, must be: -accept, -proxyfilter, -proxyhost, -proxyport, -urlencoding, -useragent} +} -result {Unknown option -junk, must be: -accept, -pipeline, -postfresh, -proxyfilter, -proxyhost, -proxyport, -repost, -urlencoding, -useragent, -zip} test http-1.6 {http::config} -setup { set oldenc [http::config -urlencoding] } -body { diff --git a/unix/Makefile.in b/unix/Makefile.in index 060148f..a2621a3 100644 --- a/unix/Makefile.in +++ b/unix/Makefile.in @@ -842,8 +842,8 @@ install-libraries: libraries do \ $(INSTALL_DATA) $$i "$(SCRIPT_INSTALL_DIR)"/http1.0; \ done; - @echo "Installing package http 2.8.13 as a Tcl Module"; - @$(INSTALL_DATA) $(TOP_DIR)/library/http/http.tcl "$(SCRIPT_INSTALL_DIR)"/../tcl8/8.6/http-2.8.13.tm; + @echo "Installing package http 2.9.0 as a Tcl Module"; + @$(INSTALL_DATA) $(TOP_DIR)/library/http/http.tcl "$(SCRIPT_INSTALL_DIR)"/../tcl8/8.6/http-2.9.0.tm; @echo "Installing package opt0.4 files to $(SCRIPT_INSTALL_DIR)/opt0.4/"; @for i in $(TOP_DIR)/library/opt/*.tcl ; \ do \ diff --git a/win/Makefile.in b/win/Makefile.in index f063da1..eee688b 100644 --- a/win/Makefile.in +++ b/win/Makefile.in @@ -651,8 +651,8 @@ install-libraries: libraries install-tzdata install-msgs do \ $(COPY) "$$j" "$(SCRIPT_INSTALL_DIR)/http1.0"; \ done; - @echo "Installing package http 2.8.13 as a Tcl Module"; - @$(COPY) $(ROOT_DIR)/library/http/http.tcl $(SCRIPT_INSTALL_DIR)/../tcl8/8.6/http-2.8.13.tm; + @echo "Installing package http 2.9.0 as a Tcl Module"; + @$(COPY) $(ROOT_DIR)/library/http/http.tcl $(SCRIPT_INSTALL_DIR)/../tcl8/8.6/http-2.9.0.tm; @echo "Installing library opt0.4 directory"; @for j in $(ROOT_DIR)/library/opt/*.tcl; \ do \ -- cgit v0.12 From 25ac7e62ba116fcef8119b89b050bf4e09059af8 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Sat, 22 Sep 2018 12:05:14 +0000 Subject: forgot one location for http version number --- library/init.tcl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/init.tcl b/library/init.tcl index 61f2c12..51339d0 100644 --- a/library/init.tcl +++ b/library/init.tcl @@ -805,7 +805,7 @@ set isafe [interp issafe] set isafe [interp issafe] set dir [file dirname [info script]] foreach {safe package version file} { - 0 http 2.8.13 {http http.tcl} + 0 http 2.9.0 {http http.tcl} 1 msgcat 1.7.0 {msgcat msgcat.tcl} 1 opt 0.4.7 {opt optparse.tcl} 0 platform 1.0.14 {platform platform.tcl} -- cgit v0.12 From 31b9d1f712fb47f0376a53db5d67d5c2c844d0ce Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Sat, 22 Sep 2018 12:29:46 +0000 Subject: Fix a couple of test-cases, since http1.0 is no longer there --- tests/zipfs.test | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/zipfs.test b/tests/zipfs.test index 5f5b93c..1a5225c 100644 --- a/tests/zipfs.test +++ b/tests/zipfs.test @@ -61,7 +61,7 @@ test zipfs-0.3 {zipfs basics: glob} -constraints zipfs -body { lsort [glob -dir . http*] } -cleanup { cd $pwd -} -result {./http ./http1.0} +} -result {./http} test zipfs-0.4 {zipfs basics: glob} -constraints zipfs -body { set pwd [pwd] @@ -69,23 +69,23 @@ test zipfs-0.4 {zipfs basics: glob} -constraints zipfs -body { lsort [glob -dir [pwd] http*] } -cleanup { cd $pwd -} -result [list $tcl_library/http $tcl_library/http1.0] +} -result [list $tcl_library/http] test zipfs-0.5 {zipfs basics: glob} -constraints zipfs -body { lsort [glob -dir $tcl_library http*] -} -result [list $tcl_library/http $tcl_library/http1.0] +} -result [list $tcl_library/http] test zipfs-0.6 {zipfs basics: glob} -constraints zipfs -body { lsort [glob $tcl_library/http*] -} -result [list $tcl_library/http $tcl_library/http1.0] +} -result [list $tcl_library/http] test zipfs-0.7 {zipfs basics: glob} -constraints zipfs -body { lsort [glob -tails -dir $tcl_library http*] -} -result {http http1.0} +} -result {http} test zipfs-0.8 {zipfs basics: glob} -constraints zipfs -body { lsort [glob -nocomplain -tails -types d -dir $tcl_library http*] -} -result {http http1.0} +} -result {http} test zipfs-0.9 {zipfs basics: glob} -constraints zipfs -body { lsort [glob -nocomplain -tails -types f -dir $tcl_library http*] -- cgit v0.12 From 9f9a9e291d8ef1d9d6183a445c9fe19374261c4d Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Sat, 22 Sep 2018 13:18:49 +0000 Subject: Change ULLONG_MAX -> UWIDE_MAX, LLONG_MAX -> WIDE_MAX and LLONG_MIN -> WIDE_MIN everywhere, because not all platforms equal Tcl_WideInt type as equal to "long long". This should fix test-cases on platforms where Tcl_WideInt != long long, and have no effect on 'normal' platforms --- generic/tclBasic.c | 4 ++-- generic/tclExecute.c | 32 ++++++++++++++++---------------- generic/tclPort.h | 3 ++- generic/tclScan.c | 4 ++-- 4 files changed, 22 insertions(+), 21 deletions(-) diff --git a/generic/tclBasic.c b/generic/tclBasic.c index 84ac87b..1abeeb4 100644 --- a/generic/tclBasic.c +++ b/generic/tclBasic.c @@ -7516,7 +7516,7 @@ ExprAbsFunc( } } goto unChanged; - } else if (l == LLONG_MIN) { + } else if (l == WIDE_MIN) { TclInitBignumFromWideInt(&big, l); goto tooLarge; } @@ -7641,7 +7641,7 @@ ExprEntierFunc( if (type == TCL_NUMBER_DOUBLE) { d = *((const double *) ptr); - if ((d >= (double)LLONG_MAX) || (d <= (double)LLONG_MIN)) { + if ((d >= (double)WIDE_MAX) || (d <= (double)WIDE_MIN)) { mp_int big; if (Tcl_InitBignumFromDouble(interp, d, &big) != TCL_OK) { diff --git a/generic/tclExecute.c b/generic/tclExecute.c index 82de752..cc4da9b 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -5635,17 +5635,17 @@ TEBCresume( if (GetNumberFromObj(NULL, OBJ_AT_TOS, &ptr1, &type1) != TCL_OK) { type1 = 0; } else if (type1 == TCL_NUMBER_WIDE) { - /* value is between LLONG_MIN and LLONG_MAX */ + /* value is between WIDE_MIN and WIDE_MAX */ /* [string is integer] is -UINT_MAX to UINT_MAX range */ - /* [string is wideinteger] is -ULLONG_MAX to ULLONG_MAX range */ + /* [string is wideinteger] is -UWIDE_MAX to UWIDE_MAX range */ int i; if (Tcl_GetIntFromObj(NULL, OBJ_AT_TOS, &i) == TCL_OK) { type1 = TCL_NUMBER_LONG; } } else if (type1 == TCL_NUMBER_BIG) { - /* value is an integer outside the LLONG_MIN to LLONG_MAX range */ - /* [string is wideinteger] is -ULLONG_MAX to ULLONG_MAX range */ + /* value is an integer outside the WIDE_MIN to WIDE_MAX range */ + /* [string is wideinteger] is -UWIDE_MAX to UWIDE_MAX range */ Tcl_WideInt w; if (Tcl_GetWideIntFromObj(NULL, OBJ_AT_TOS, &w) == TCL_OK) { @@ -6061,9 +6061,9 @@ TEBCresume( TRACE(("%s %s => DIVIDE BY ZERO\n", O2S(valuePtr), O2S(value2Ptr))); goto divideByZero; - } else if ((w1 == LLONG_MIN) && (w2 == -1)) { + } else if ((w1 == WIDE_MIN) && (w2 == -1)) { /* - * Can't represent (-LLONG_MIN) as a Tcl_WideInt. + * Can't represent (-WIDE_MIN) as a Tcl_WideInt. */ goto overflow; @@ -6196,7 +6196,7 @@ TEBCresume( NEXT_INST_F(1, 0, 0); case TCL_NUMBER_WIDE: w1 = *((const Tcl_WideInt *) ptr1); - if (w1 != LLONG_MIN) { + if (w1 != WIDE_MIN) { if (Tcl_IsShared(valuePtr)) { TclNewIntObj(objResultPtr, -w1); TRACE_APPEND(("%s\n", O2S(objResultPtr))); @@ -8670,10 +8670,10 @@ ExecuteExtendedBinaryMathOp( } /* - * Need a bignum to represent (LLONG_MIN / -1) + * Need a bignum to represent (WIDE_MIN / -1) */ - if ((w1 == LLONG_MIN) && (w2 == -1)) { + if ((w1 == WIDE_MIN) && (w2 == -1)) { goto overflowBasic; } wResult = w1 / w2; @@ -8776,7 +8776,7 @@ ExecuteExtendedUnaryMathOp( DOUBLE_RESULT(-(*((const double *) ptr))); case TCL_NUMBER_WIDE: w = *((const Tcl_WideInt *) ptr); - if (w != LLONG_MIN) { + if (w != WIDE_MIN) { WIDE_RESULT(-w); } TclInitBignumFromWideInt(&big, w); @@ -8862,10 +8862,10 @@ TclCompareTwoNumbers( * integer comparison can tell the difference. */ - if (d2 < (double)LLONG_MIN) { + if (d2 < (double)WIDE_MIN) { return MP_GT; } - if (d2 > (double)LLONG_MAX) { + if (d2 > (double)WIDE_MAX) { return MP_LT; } w2 = (Tcl_WideInt) d2; @@ -8895,10 +8895,10 @@ TclCompareTwoNumbers( || w2 == (Tcl_WideInt) d2 || modf(d1, &tmp) != 0.0) { goto doubleCompare; } - if (d1 < (double)LLONG_MIN) { + if (d1 < (double)WIDE_MIN) { return MP_LT; } - if (d1 > (double)LLONG_MAX) { + if (d1 > (double)WIDE_MAX) { return MP_GT; } w1 = (Tcl_WideInt) d1; @@ -8908,7 +8908,7 @@ TclCompareTwoNumbers( return (d1 > 0.0) ? MP_GT : MP_LT; } Tcl_TakeBignumFromObj(NULL, value2Ptr, &big2); - if ((d1 < (double)LLONG_MAX) && (d1 > (double)LLONG_MIN)) { + if ((d1 < (double)WIDE_MAX) && (d1 > (double)WIDE_MIN)) { if (mp_isneg(&big2)) { compare = MP_GT; } else { @@ -8941,7 +8941,7 @@ TclCompareTwoNumbers( mp_clear(&big1); return compare; } - if ((d2 < (double)LLONG_MAX) && (d2 > (double)LLONG_MIN)) { + if ((d2 < (double)WIDE_MAX) && (d2 > (double)WIDE_MIN)) { compare = mp_cmp_d(&big1, 0); mp_clear(&big1); return compare; diff --git a/generic/tclPort.h b/generic/tclPort.h index 33c0db6..d3f6233 100644 --- a/generic/tclPort.h +++ b/generic/tclPort.h @@ -24,7 +24,8 @@ #endif #include "tcl.h" -#define WIDE_MAX ((Tcl_WideInt)((~(Tcl_WideUInt)0) >> 1)) +#define UWIDE_MAX ((Tcl_WideUInt)-1) +#define WIDE_MAX ((Tcl_WideInt)(UWIDE_MAX >> 1)) #define WIDE_MIN ((Tcl_WideInt)((Tcl_WideUInt)WIDE_MAX+1)) #endif /* _TCLPORT */ diff --git a/generic/tclScan.c b/generic/tclScan.c index 0e3da17..733409e 100644 --- a/generic/tclScan.c +++ b/generic/tclScan.c @@ -926,9 +926,9 @@ Tcl_ScanObjCmd( } if (flags & SCAN_LONGER) { if (Tcl_GetWideIntFromObj(NULL, objPtr, &wideValue) != TCL_OK) { - wideValue = LLONG_MAX; + wideValue = WIDE_MAX; if (TclGetString(objPtr)[0] == '-') { - wideValue = LLONG_MIN; + wideValue = WIDE_MIN; } } if ((flags & SCAN_UNSIGNED) && (wideValue < 0)) { -- cgit v0.12 From fbdc68b6a22a1be2c7923c6a2ab13214d3655aba Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Sat, 22 Sep 2018 16:51:43 +0000 Subject: Handle the (unlikely) case that Tcl_DStringSetLength() results in a re-allocation of the buffer --- generic/tclStubInit.c | 1 + win/tclWin32Dll.c | 1 + 2 files changed, 2 insertions(+) diff --git a/generic/tclStubInit.c b/generic/tclStubInit.c index cb33288..66ad753 100644 --- a/generic/tclStubInit.c +++ b/generic/tclStubInit.c @@ -276,6 +276,7 @@ Tcl_WinTCharToUtf( memmove(r+2, r+1, p-r+size-1); memcpy(r++, "\xC0\x80", 2); Tcl_DStringSetLength(dsPtr, ++size + 1); + r = p = (char *)Tcl_DStringValue(dsPtr); } ++r; } diff --git a/win/tclWin32Dll.c b/win/tclWin32Dll.c index 2216a66..13a3dec 100644 --- a/win/tclWin32Dll.c +++ b/win/tclWin32Dll.c @@ -524,6 +524,7 @@ Tcl_WinTCharToUtf( memmove(r+2, r+1, p-r+size-1); memcpy(r++, "\xC0\x80", 2); Tcl_DStringSetLength(dsPtr, ++size + 1); + r = p = (char *)Tcl_DStringValue(dsPtr); } ++r; } -- cgit v0.12 From 6d3aeef45e68dc92f69195ab165ce49ecd4738c4 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Sun, 23 Sep 2018 13:27:14 +0000 Subject: Give lambda function a name "ReceiveChunked" for easier testing. New function quoteString and code cleanup --- doc/exec.n | 6 +- doc/http.n | 18 ++++-- library/http/http.tcl | 142 ++++++++++++++--------------------------------- tests/httpPipeline.test | 2 +- tests/httpTestScript.tcl | 2 +- tests/winPipe.test | 6 +- win/tclWinPipe.c | 8 +-- 7 files changed, 67 insertions(+), 117 deletions(-) diff --git a/doc/exec.n b/doc/exec.n index d78c34a..99dfdc5 100644 --- a/doc/exec.n +++ b/doc/exec.n @@ -224,10 +224,10 @@ Although it is the common escape algorithm, but, in fact, the way how the executable parses the command-line (resp. splits it into single arguments) is decisive. .PP -Unfortunately, there is currently no way to supply newline character within -an argument to the batch files (\fB.cmd\fR or \fB.bat\fR) or to the command +Unfortunately, there is currently no way to supply newline character within +an argument to the batch files (\fB.cmd\fR or \fB.bat\fR) or to the command processor (\fBcmd.exe /c\fR), because this causes truncation of command-line -(also the argument chain) on the first newline character. +(also the argument chain) on the first newline character. But it works properly with an executable (using CommandLineToArgv, etc). .PP The Tk console text widget does not provide real standard IO capabilities. diff --git a/doc/http.n b/doc/http.n index e788022..7e633b3 100644 --- a/doc/http.n +++ b/doc/http.n @@ -6,7 +6,7 @@ '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. '\" -.TH "http" n 2.8 http "Tcl Bundled Packages" +.TH "http" n 2.9 http "Tcl Bundled Packages" .so man.macros .BS '\" Note: do not modify the .SH NAME line immediately below! @@ -22,6 +22,8 @@ http \- Client-side implementation of the HTTP/1.1 protocol .sp \fB::http::formatQuery\fR \fIkey value\fR ?\fIkey value\fR ...? .sp +\fB::http::quoteString\fR \fIvalue\fR +.sp \fB::http::reset\fR \fItoken\fR ?\fIwhy\fR? .sp \fB::http::wait \fItoken\fR @@ -146,12 +148,13 @@ default is 0. \fB\-urlencoding\fR \fIencoding\fR . The \fIencoding\fR used for creating the x-url-encoded URLs with -\fB::http::formatQuery\fR. The default is \fButf-8\fR, as specified by RFC +\fB::http::formatQuery\fR and \fB::http::quoteString\fR. +The default is \fButf-8\fR, as specified by RFC 2718. Prior to http 2.5 this was unspecified, and that behavior can be returned by specifying the empty string (\fB{}\fR), although \fIiso8859-1\fR is recommended to restore similar behavior but without the -\fB::http::formatQuery\fR throwing an error processing non-latin-1 -characters. +\fB::http::formatQuery\fR or \fB::http::quoteString\fR +throwing an error processing non-latin-1 characters. .TP \fB\-useragent\fR \fIstring\fR . @@ -375,6 +378,11 @@ encodes the keys and values, and generates one string that has the proper & and = separators. The result is suitable for the \fB\-query\fR value passed to \fB::http::geturl\fR. .TP +\fB::http::quoteString\fR \fIvalue\fR +. +This procedure does x-url-encoding of string. It takes a single argument and +encodes it. +.TP \fB::http::reset\fR \fItoken\fR ?\fIwhy\fR? . This command resets the HTTP transaction identified by \fItoken\fR, if any. @@ -755,7 +763,7 @@ Option \fB-postfresh\fR, if boolean \fBtrue\fR, will override the \fBhttp::getur .PP Option \fB-repost\fR, if \fBtrue\fR, permits automatic retry of a POST request that fails because it uses a persistent connection that the server has -half-closed (an +half-closed (an .QW "asynchronous close event" ). Subsequent GET and HEAD requests in a failed pipeline will also be retried. \fIThe -repost option should be used only if the application understands diff --git a/library/http/http.tcl b/library/http/http.tcl index 643a119..f82bced 100644 --- a/library/http/http.tcl +++ b/library/http/http.tcl @@ -100,7 +100,6 @@ namespace eval http { array set socketWrQueue {} array set socketClosing {} array set socketPlayCmd {} - return } init @@ -128,7 +127,7 @@ namespace eval http { set defaultKeepalive 0 } - namespace export geturl config reset wait formatQuery + namespace export geturl config reset wait formatQuery quoteString namespace export register unregister registerError # - Useful, but not exported: data, size, status, code, cleanup, error, # meta, ncode, mapReply, init. Comments suggest that "init" can be used @@ -161,7 +160,6 @@ if {[info command http::Log] eq {}} {proc http::Log {args} {}} proc http::register {proto port command} { variable urlTypes set urlTypes([string tolower $proto]) [list $port $command] - # N.B. Implicit Return. } # http::unregister -- @@ -219,7 +217,6 @@ proc http::config {args} { } set http($flag) $value } - return } } @@ -293,8 +290,6 @@ proc http::Finish {token {errormsg ""} {skipCB 0}} { } { http::CloseQueuedQueries $connId $token } - - return } # http::KeepSocket - @@ -335,9 +330,6 @@ proc http::KeepSocket {token} { # ONLY for testing reaction to server eof. # No server timeouts will be caught. catch {fileevent $state(sock) readable {}} - } else { - # Normal operation. - # Test constraint normalEof. } if { [info exists state(socketinfo)] @@ -386,7 +378,7 @@ proc http::KeepSocket {token} { # socketWrState has been marked "pending" (in # http::NextPipelinedWrite or http::geturl) so a new pipelined # request cannot jump the queue. - # + # # Tests: # - In this case the read queue (tested above) is empty and this # "pending" write token is in front of the rest of the write @@ -476,8 +468,6 @@ proc http::KeepSocket {token} { } elseif {(!$state(-pipeline))} { set socketWrState($connId) Wready # Rready and Wready and idle: nothing to do. - } else { - # Rready and idle: nothing to do. } } else { @@ -485,7 +475,6 @@ proc http::KeepSocket {token} { # There is no socketMapping($state(socketinfo)), so it does not matter # that CloseQueuedQueries is not called. } - return } # http::CheckEof - @@ -511,7 +500,6 @@ proc http::CheckEof {sock} { # will then be error-handled. CloseSocket $sock } - return } # http::CloseSocket - @@ -539,7 +527,6 @@ proc http::CloseSocket {s {token {}}} { upvar 0 $token state if {[info exists state(socketinfo)]} { set connId $state(socketinfo) - } else { } } else { set map [array get socketMapping] @@ -547,7 +534,6 @@ proc http::CloseSocket {s {token {}}} { if {$ndx != -1} { incr ndx -1 set connId [lindex $map $ndx] - } else { } } if { ($connId ne {}) @@ -557,22 +543,18 @@ proc http::CloseSocket {s {token {}}} { Log "Closing connection $connId (sock $socketMapping($connId))" if {[catch {close $socketMapping($connId)} err]} { Log "Error closing connection: $err" - } else { } if {$token eq {}} { # Cases with a non-empty token are handled by Finish, so the tokens # are finished in connection order. http::CloseQueuedQueries $connId - } else { } } else { Log "Closing socket $s (no connection info)" if {[catch {close $s} err]} { Log "Error closing socket: $err" - } else { } } - return } # http::CloseQueuedQueries @@ -629,7 +611,6 @@ proc http::CloseQueuedQueries {connId {token {}}} { - token $token {*}$unfinished } - return } # http::Unset @@ -655,8 +636,6 @@ proc http::Unset {connId} { unset -nocomplain socketWrQueue($connId) unset -nocomplain socketClosing($connId) unset -nocomplain socketPlayCmd($connId) - - return } # http::reset -- @@ -682,7 +661,6 @@ proc http::reset {token {why reset}} { unset state eval ::error $errorlist } - return } # http::geturl -- @@ -1248,9 +1226,6 @@ proc http::geturl {url args} { #Log re-use nonpipeline, GRANT r/w access to $token in geturl set socketRdState($state(socketinfo)) $token set socketWrState($state(socketinfo)) $token - - } else { - # (!$reusing) } # All (!$reusing) cases come here, and also some $reusing cases if the @@ -1528,17 +1503,12 @@ proc http::Connected {token proto phost srvurl} { registerError $sock {} if {$msg eq {}} { set msg {failed to use socket} - } else { } Finish $token $msg } elseif {$state(status) ne "error"} { Finish $token $err - } else { - # if state(status) is error, it means someone's already called - # Finish to do the above-described clean up. } } - return } # http::registerError @@ -1567,7 +1537,6 @@ proc http::registerError {sock args} { return } set registeredErrors($sock) {*}$args - # N.B. Implicit Return } # http::DoneRequest -- @@ -1645,7 +1614,6 @@ proc http::DoneRequest {token} { # In the nonpipeline case, connection for reading always occurs. ReceiveResponse $token } - return } # http::ReceiveResponse @@ -1666,7 +1634,6 @@ proc http::ReceiveResponse {token} { coroutine ${token}EventCoroutine http::Event $sock $token fileevent $sock readable ${token}EventCoroutine - return } # http::NextPipelinedWrite @@ -1778,12 +1745,7 @@ proc http::NextPipelinedWrite {token} { #Log re-use nonpipeline, GRANT delayed write access to $token in NextP.. set socketWrState($connId) peNding - - } else { - # No requests in socketWrQueue. Nothing to do. } - - return } # http::CancelReadPipeline @@ -1816,7 +1778,6 @@ proc http::CancelReadPipeline {name1 connId op} { } set socketRdQueue($connId) {} } - return } # http::CancelWritePipeline @@ -1850,7 +1811,6 @@ proc http::CancelWritePipeline {name1 connId op} { } set socketWrQueue($connId) {} } - return } # http::ReplayIfDead -- @@ -1907,7 +1867,6 @@ proc http::ReplayIfDead {tokenArg doing} { lappend InFlightR $socketRdState($stateArg(socketinfo)) } elseif {($doing eq "read")} { lappend InFlightR $tokenArg - } else { } if { [info exists socketWrState($stateArg(socketinfo))] @@ -1916,7 +1875,6 @@ proc http::ReplayIfDead {tokenArg doing} { lappend InFlightW $socketWrState($stateArg(socketinfo)) } elseif {($doing eq "write")} { lappend InFlightW $tokenArg - } else { } # Report any inconsistency of $tokenArg with socket*state. @@ -1936,7 +1894,6 @@ proc http::ReplayIfDead {tokenArg doing} { Log WARNING - ReplayIfDead pipelined tokenArg $tokenArg $doing \ ne socketWrState($stateArg(socketinfo)) \ $socketWrState($stateArg(socketinfo)) - } else { } } else { # One transaction should be in flight. @@ -1948,7 +1905,6 @@ proc http::ReplayIfDead {tokenArg doing} { Log WARNING - ReplayIfDead nonpipeline tokenArg $tokenArg $doing \ ne socketRdState($stateArg(socketinfo)) \ $socketRdState($stateArg(socketinfo)) - } else { } # Report the inconsistency that socketRdQueue is non-empty. @@ -1958,7 +1914,6 @@ proc http::ReplayIfDead {tokenArg doing} { Log WARNING - ReplayIfDead nonpipeline tokenArg $tokenArg $doing \ has read queue socketRdQueue($stateArg(socketinfo)) \ $socketRdQueue($stateArg(socketinfo)) ne {} - } else { } lappend InFlightW $socketRdState($stateArg(socketinfo)) @@ -1989,7 +1944,6 @@ proc http::ReplayIfDead {tokenArg doing} { # to new values in ReplayCore. ReplayCore $newQueue - return } # http::ReplayIfClose -- @@ -2029,7 +1983,6 @@ proc http::ReplayIfClose {Wstate Rqueue Wqueue} { # 2. Cleanup - none needed, done by the caller. ReplayCore $newQueue - return } # http::ReInit -- @@ -2236,7 +2189,6 @@ proc http::ReplayCore {newQueue} { # Connect does its own fconfigure. fileevent $sock writable [list http::Connect $token {*}$tmpConnArgs] #Log ---- $sock << conn to $token for HTTP request (e) - return } # Data access functions: @@ -2314,7 +2266,6 @@ proc http::cleanup {token} { if {[info exists state]} { unset state } - return } # http::Connect @@ -2358,7 +2309,6 @@ proc http::Connect {token proto phost srvurl} { fileevent $state(sock) writable {} ::http::Connected $token $proto $phost $srvurl } - return } # http::Write @@ -2463,7 +2413,6 @@ proc http::Write {token} { eval $state(-queryprogress) \ [list $token $state(querylength) $state(queryoffset)] } - return } # http::Event @@ -2560,10 +2509,6 @@ proc http::Event {sock token} { # last use. # If any other requests are in flight or pipelined/queued, they # will be discarded. - } else { - ##Log - connecting 2 - token $token - # nsl is -1 so either fblocked (OK) or (eof and not reusing). - # Continue. Any eof is processed at the end of this proc. } } elseif {$state(state) eq "header"} { if {[catch {gets $sock line} nhl]} { @@ -2795,7 +2740,6 @@ proc http::Event {sock token} { set n 0 set state(state) complete } - } else { } } elseif {[info exists state(transfer_final)]} { # This code forgives EOF in place of the final CRLF. @@ -2955,11 +2899,8 @@ proc http::Event {sock token} { } } elseif {$cc} { return - } else { - # Not eof, continue and yield. } } - return } # http::TestForReplay @@ -3148,7 +3089,6 @@ proc http::CopyStart {sock token {initial 1}} { Finish $token $err } } - return } proc http::CopyChunk {token chunk} { @@ -3178,7 +3118,6 @@ proc http::CopyChunk {token chunk} { } Eot $token ;# FIX ME: pipelining. } - return } # http::CopyDone @@ -3209,7 +3148,6 @@ proc http::CopyDone {token count {error {}}} { } else { CopyStart $sock $token 0 } - return } # http::Eot @@ -3279,7 +3217,6 @@ proc http::Eot {token {reason {}}} { } } Finish $token $reason - return } # http::wait -- @@ -3317,6 +3254,12 @@ proc http::wait {token} { # TODO proc http::formatQuery {args} { + if {[llength $args] % 2} { + return \ + -code error \ + -errorcode [list HTTP BADARGCNT $args] \ + {Incorrect number of arguments, must be an even number.} + } set result "" set sep "" foreach i $args { @@ -3361,6 +3304,7 @@ proc http::mapReply {string} { } return $converted } +interp alias {} http::quoteString {} http::mapReply # http::ProxyRequired -- # Default proxy filter. @@ -3382,7 +3326,6 @@ proc http::ProxyRequired {host} { } return [list $http(-proxyhost) $http(-proxyport)] } - return } # http::CharsetToEncoding -- @@ -3436,8 +3379,7 @@ proc http::ContentEncoding {token} { compress - x-compress { lappend r decompress } identity {} default { - set msg "unsupported content-encoding \"$coding\"" - return -code error $msg + return -code error "unsupported content-encoding \"$coding\"" } } } @@ -3445,39 +3387,39 @@ proc http::ContentEncoding {token} { return $r } -proc http::make-transformation-chunked {chan command} { - set lambda {{chan command} { - set data "" - set size -1 - yield - while {1} { - chan configure $chan -translation {crlf binary} - while {[gets $chan line] < 1} { yield } - chan configure $chan -translation {binary binary} - if {[scan $line %x size] != 1} { - return -code error "invalid size: \"$line\"" - } - set chunk "" - while {$size && ![chan eof $chan]} { - set part [chan read $chan $size] - incr size -[string length $part] - append chunk $part - } - if {[catch { - uplevel #0 [linsert $command end $chunk] - }]} { - http::Log "Error in callback: $::errorInfo" - } - if {[string length $chunk] == 0} { - # channel might have been closed in the callback - catch {chan event $chan readable {}} - return - } +proc http::ReceiveChunked {chan command} { + set data "" + set size -1 + yield + while {1} { + chan configure $chan -translation {crlf binary} + while {[gets $chan line] < 1} { yield } + chan configure $chan -translation {binary binary} + if {[scan $line %x size] != 1} { + return -code error "invalid size: \"$line\"" + } + set chunk "" + while {$size && ![chan eof $chan]} { + set part [chan read $chan $size] + incr size -[string length $part] + append chunk $part + } + if {[catch { + uplevel #0 [linsert $command end $chunk] + }]} { + http::Log "Error in callback: $::errorInfo" + } + if {[string length $chunk] == 0} { + # channel might have been closed in the callback + catch {chan event $chan readable {}} + return } - }} - coroutine dechunk$chan ::apply $lambda $chan $command - chan event $chan readable [namespace origin dechunk$chan] - return + } +} + +proc http::make-transformation-chunked {chan command} { + coroutine [namespace current]::dechunk$chan ::http::ReceiveChunked $chan $command + chan event $chan readable [namespace current]::dechunk$chan } # Local variables: diff --git a/tests/httpPipeline.test b/tests/httpPipeline.test index 5eb02d3..8de79b9 100644 --- a/tests/httpPipeline.test +++ b/tests/httpPipeline.test @@ -532,7 +532,7 @@ proc ReturnTestScriptAndResult {ca cb delay te} { # Proc MakeMessage # ------------------------------------------------------------------------------ # WHD's one-line command to generate multi-line strings from readable code. -# +# # Example: # set blurb [MakeMessage { # |This command allows multi-line strings to be created with readable diff --git a/tests/httpTestScript.tcl b/tests/httpTestScript.tcl index a8ef9c8..a40449a 100644 --- a/tests/httpTestScript.tcl +++ b/tests/httpTestScript.tcl @@ -496,7 +496,7 @@ proc httpTestScript::runHttpTestScript {scr} { proc httpTestScript::cleanupHttpTestScript {} { variable TimeOutDone variable RequestsWhenStopped - + if {![info exists RequestsWhenStopped]} { return -code error {Cleanup Failed: RequestsWhenStopped is undefined} } diff --git a/tests/winPipe.test b/tests/winPipe.test index 9402db1..62cc707 100644 --- a/tests/winPipe.test +++ b/tests/winPipe.test @@ -41,7 +41,7 @@ append big $big append big $big set path(little) [makeFile {} little] -set f [open $path(little) w] +set f [open $path(little) w] puts -nonewline $f "little" close $f @@ -332,7 +332,7 @@ proc _testExecArgs {single args} { set broken {} foreach args $args { if {$single & 1} { - # enclose single test-arg between 1st/3rd to be sure nothing is truncated + # enclose single test-arg between 1st/3rd to be sure nothing is truncated # (e. g. to cover unexpected trim by nts-zero case, and args don't recombined): set args [list "1st" $args "3rd"] } @@ -569,7 +569,7 @@ set injectList { test winpipe-8.6 {BuildCommandLine/parse_cmdline pass-thru: check new-line quoted in args} \ -constraints {win exec} -body { - # test exe only, because currently there is no proper way to escape a new-line char resp. + # test exe only, because currently there is no proper way to escape a new-line char resp. # to supply a new-line to the batch-files within arguments (command line is truncated). _testExecArgs 8 \ [list START {*}$injectList END] \ diff --git a/win/tclWinPipe.c b/win/tclWinPipe.c index dd54a27..826265a 100644 --- a/win/tclWinPipe.c +++ b/win/tclWinPipe.c @@ -1495,10 +1495,10 @@ QuoteCmdLinePart( QuoteCmdLineBackslash(dsPtr, start, *bspos, NULL); start = *bspos; } - /* - * escape all special chars enclosed in quotes like `"..."`, note that here we + /* + * escape all special chars enclosed in quotes like `"..."`, note that here we * don't must escape `\` (with `\`), because it's outside of the main quotes, - * so `\` remains `\`, but important - not at end of part, because results as + * so `\` remains `\`, but important - not at end of part, because results as * before the quote, so `%\%\` should be escaped as `"%\%"\\`). */ TclDStringAppendLiteral(dsPtr, "\""); /* opening escape quote-char */ @@ -1653,7 +1653,7 @@ BuildCommandLine( special++; } /* rest of argument (and escape backslashes before closing main quote) */ - QuoteCmdLineBackslash(&ds, start, special, + QuoteCmdLineBackslash(&ds, start, special, (quote & CL_QUOTE) ? bspos : NULL); } if (quote & CL_QUOTE) { -- cgit v0.12 From be629669a54f0106c40f0bcb78f4493b481d61c6 Mon Sep 17 00:00:00 2001 From: dkf Date: Sun, 23 Sep 2018 17:29:46 +0000 Subject: Added docs --- doc/append.n | 12 +++++++++--- doc/array.n | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++++- doc/dict.n | 35 +++++++++++++++++++++++++++++++++++ doc/incr.n | 9 +++++++++ doc/lappend.n | 10 ++++++++++ 5 files changed, 115 insertions(+), 4 deletions(-) diff --git a/doc/append.n b/doc/append.n index e3bf224..99b4ece 100644 --- a/doc/append.n +++ b/doc/append.n @@ -20,6 +20,11 @@ Append all of the \fIvalue\fR arguments to the current value of variable \fIvarName\fR. If \fIvarName\fR does not exist, it is given a value equal to the concatenation of all the \fIvalue\fR arguments. +.VS TIP508 +If \fIvarName\fR indicate an element that does not exist of an array that has +a default value set, the concatenation of the default value and all the +\fIvalue\fR arguments will be stored in the array element. +.VE TIP508 The result of this command is the new value stored in variable \fIvarName\fR. This command provides an efficient way to build up long @@ -44,6 +49,7 @@ puts $var concat(n), lappend(n) .SH KEYWORDS append, variable -'\" Local Variables: -'\" mode: nroff -'\" End: +.\" Local variables: +.\" mode: nroff +.\" fill-column: 78 +.\" End: diff --git a/doc/array.n b/doc/array.n index d6d4dff..bbfcd9f 100644 --- a/doc/array.n +++ b/doc/array.n @@ -5,7 +5,7 @@ '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. '\" -.TH array n 8.3 Tcl "Tcl Built-In Commands" +.TH array n 8.7 Tcl "Tcl Built-In Commands" .so man.macros .BS '\" Note: do not modify the .SH NAME line immediately below! @@ -36,6 +36,53 @@ with an empty name, since the return value from \fBarray nextelement\fR will not indicate whether the search has been completed. .TP +\fBarray default \fIsubcommand arrayName args...\fR +.VS TIP508 +Manages the default value of the array. Arrays initially have no default +value, but this command allows you to set one; the default value will be +returned when reading from an element of the array \farrayName\fR if the read +would otherwise result in an error. Note that this may cause the \fBappend\fR, +\fBdict\fR, \fBincr\fR and \fBlappend\fR commands to change their behavior in +relation to non-existing array elements. +.RS +.PP +The \fIsubcommand\fR argument controls what exact operation will be performed +on the default value of \fIarrayName\fR. Supported \fIsubcommand\fRs are: +.VE TIP508 +.TP +\fBarray default exists \fIarrayName\fR +.VS TIP508 +This returns a boolean value indicating whether a default value has been set +for the array \fIarrayName\fR. Returns a false value if \fIarrayName\fR does +not exist. Raises an error if \fIarrayName\fR is an existing variable that is +not an array. +.VE TIP508 +.TP +\fBarray default get \fIarrayName\fR +.VS TIP508 +This returns the current default value for the array \fIarrayName\fR. Raises +an error if \fIarrayName\fR is an existing variable that is not an array, or +if \fIarrayName\fR is an array without a default value. +.VE TIP508 +.TP +\fBarray default set \fIarrayName value\fR +.VS TIP508 +This sets the default value for the array \fIarrayName\fR to \fIvalue\fR. +Returns the empty string. Raises an error if \fIarrayName\fR is an existing +variable that is not an array, or if \fIarrayName\fR is an illegal name for an +array. If \fIarrayName\fR does not currently exist, it is created as an empty +array as well as having its default value set. +.VE TIP508 +.TP +\fBarray default unset \fIarrayName\fR +.VS TIP508 +This removes the default value for the array \fIarrayName\fR and returns the +empty string. Does nothing if \fIarrayName\fR does not have a default +value. Raises an error if \fIarrayName\fR is an existing variable that is not +an array. +.VE TIP508 +.RE +.TP \fBarray donesearch \fIarrayName searchId\fR This command terminates an array search and destroys all the state associated with that search. \fISearchId\fR indicates @@ -194,3 +241,7 @@ foreach color [lsort [\fBarray names\fR colorcount]] { list(n), string(n), variable(n), trace(n), foreach(n) .SH KEYWORDS array, element names, search +.\" Local variables: +.\" mode: nroff +.\" fill-column: 78 +.\" End: diff --git a/doc/dict.n b/doc/dict.n index cd7e94c..1829768 100644 --- a/doc/dict.n +++ b/doc/dict.n @@ -27,6 +27,11 @@ key maps to in the dictionary value contained in the given variable, writing the resulting dictionary value back to that variable. Non-existent keys are treated as if they map to an empty string. The updated dictionary value is returned. +.VS TIP508 +If \fIdictionaryVarable\fR indicates an element that does not exist of an +array that has a default value set, the default value and will be used as the +value of the dictionary prior to the appending operation. +.VE TIP508 .TP \fBdict create \fR?\fIkey value ...\fR? . @@ -124,6 +129,11 @@ resulting dictionary value back to that variable. Non-existent keys are treated as if they map to 0. It is an error to increment a value for an existing key if that value is not an integer. The updated dictionary value is returned. +.VS TIP508 +If \fIdictionaryVarable\fR indicates an element that does not exist of an +array that has a default value set, the default value and will be used as the +value of the dictionary prior to the incrementing operation. +.VE TIP508 .TP \fBdict info \fIdictionaryValue\fR . @@ -149,6 +159,11 @@ keys are treated as if they map to an empty list, and it is legal for there to be no items to append to the list. It is an error for the value that the key maps to to not be representable as a list. The updated dictionary value is returned. +.VS TIP508 +If \fIdictionaryVarable\fR indicates an element that does not exist of an +array that has a default value set, the default value and will be used as the +value of the dictionary prior to the list-appending operation. +.VE TIP508 .TP \fBdict map \fR{\fIkeyVariable valueVariable\fR} \fIdictionaryValue body\fR . @@ -206,6 +221,11 @@ value and places an updated dictionary value in that variable containing a mapping from the given key to the given value. When multiple keys are present, this operation creates or updates a chain of nested dictionaries. The updated dictionary value is returned. +.VS TIP508 +If \fIdictionaryVarable\fR indicates an element that does not exist of an +array that has a default value set, the default value and will be used as the +value of the dictionary prior to the value insert/update operation. +.VE TIP508 .TP \fBdict size \fIdictionaryValue\fR . @@ -221,6 +241,11 @@ through nested dictionaries to the mapping to remove. At least one key must be specified, but the last key on the key-path need not exist. All other components on the path must exist. The updated dictionary value is returned. +.VS TIP508 +If \fIdictionaryVarable\fR indicates an element that does not exist of an +array that has a default value set, the default value and will be used as the +value of the dictionary prior to the value remove operation. +.VE TIP508 .TP \fBdict update \fIdictionaryVariable key varName \fR?\fIkey varName ...\fR? \fIbody\fR . @@ -236,6 +261,11 @@ are silently discarded), even if the result of \fIbody\fR is an error or some other kind of exceptional exit. The result of \fBdict update\fR is (unless some kind of error occurs) the result of the evaluation of \fIbody\fR. +.VS TIP508 +If \fIdictionaryVarable\fR indicates an element that does not exist of an +array that has a default value set, the default value and will be used as the +value of the dictionary prior to the update operation. +.VE TIP508 .RS .PP Each \fIvarName\fR is mapped in the scope enclosing the \fBdict update\fR; @@ -270,6 +300,11 @@ dictionary be discarded, and this also happens if the contents of dictionaries no longer exists. The result of \fBdict with\fR is (unless some kind of error occurs) the result of the evaluation of \fIbody\fR. +.VS TIP508 +If \fIdictionaryVarable\fR indicates an element that does not exist of an +array that has a default value set, the default value and will be used as the +value of the dictionary prior to the updating operation. +.VE TIP508 .RS .PP The variables are mapped in the scope enclosing the \fBdict with\fR; diff --git a/doc/incr.n b/doc/incr.n index b4be95c..f491903 100644 --- a/doc/incr.n +++ b/doc/incr.n @@ -27,6 +27,11 @@ and also returned as result. Starting with the Tcl 8.5 release, the variable \fIvarName\fR passed to \fBincr\fR may be unset, and in that case, it will be set to the value \fIincrement\fR or to the default increment value of \fB1\fR. +.VS TIP508 +If \fIvarName\fR indicate an element that does not exist of an array that has +a default value set, the sum of the default value and the \fIincrement\fR (or +1) will be stored in the array element. +.VE TIP508 .SH EXAMPLES .PP Add one to the contents of the variable \fIx\fR: @@ -59,3 +64,7 @@ an error if it is not): expr(n), set(n) .SH KEYWORDS add, increment, variable, value +.\" Local variables: +.\" mode: nroff +.\" fill-column: 78 +.\" End: diff --git a/doc/lappend.n b/doc/lappend.n index 80d075a..66bea5f 100644 --- a/doc/lappend.n +++ b/doc/lappend.n @@ -22,6 +22,12 @@ and appends each of the \fIvalue\fR arguments to that list as a separate element, with spaces between elements. If \fIvarName\fR does not exist, it is created as a list with elements given by the \fIvalue\fR arguments. +.VS TIP508 +If \fIvarName\fR indicate an element that does not exist of an array that has +a default value set, list that is comprised of the default value with all the +\fIvalue\fR arguments appended as elements will be stored in the array +element. +.VE TIP508 \fBLappend\fR is similar to \fBappend\fR except that the \fIvalue\fRs are appended as list elements rather than raw text. This command provides a relatively efficient way to build up @@ -47,3 +53,7 @@ list(n), lindex(n), linsert(n), llength(n), lset(n), lsort(n), lrange(n) .SH KEYWORDS append, element, list, variable +.\" Local variables: +.\" mode: nroff +.\" fill-column: 78 +.\" End: -- cgit v0.12 From 4719e1f68dfa2eefb9988043ea2baa81dbe7ebe5 Mon Sep 17 00:00:00 2001 From: dkf Date: Mon, 24 Sep 2018 08:21:36 +0000 Subject: Add tests. Exposes quite a few bugs in the implementation... --- tests/var.test | 190 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 189 insertions(+), 1 deletion(-) diff --git a/tests/var.test b/tests/var.test index 7b7fc25..a05106f 100644 --- a/tests/var.test +++ b/tests/var.test @@ -1046,7 +1046,7 @@ test var-22.2 {leak in parsedVarName} -constraints memory -body { } -cleanup { unset -nocomplain i x } -result 0 - + unset -nocomplain a k v test var-23.1 {array command, for loop, too many args} -returnCodes error -body { array for {k v} c d e {} @@ -1202,6 +1202,194 @@ test var-23.14 {array for, shared arguments} -setup { } -cleanup { unset -nocomplain $vn vn } -result {} + +test var-24.1 {array default set and get: interpreted} -setup { + unset -nocomplain ary +} -body { + array set ary {a 3} + array default set ary 7 + list $ary(a) $ary(b) [info exist ary(a)] [info exist ary(b)] \ + [array default get ary] +} -cleanup { + unset -nocomplain ary +} -result {3 7 1 0 7} +test var-24.2 {array default set and get: compiled} { + apply {{} { + array set ary {a 3} + array default set ary 7 + list $ary(a) $ary(b) [info exist ary(a)] [info exist ary(b)] \ + [array default get ary] + }} +} {3 7 1 0 7} +test var-24.3 {array default unset: interpreted} -setup { + unset -nocomplain ary +} -body { + array set ary {a 3} + array default set ary 7 + list $ary(a) $ary(b) [array default unset ary] $ary(a) [catch {set ary(b)}] +} -cleanup { + unset -nocomplain ary +} -result {3 7 {} 3 1} +test var-24.4 {array default unset: compiled} { + apply {{} { + array set ary {a 3} + array default set ary 7 + list $ary(a) $ary(b) [array default unset ary] $ary(a) \ + [catch {set ary(b)}] + }} +} {3 7 {} 3 1} +test var-24.5 {array default exists: interpreted} -setup { + unset -nocomplain ary result + set result {} +} -body { + array set ary {a 3} + lappend result [info exists ary],[array exists ary],[array default exists ary] + array default set ary 7 + lappend result [info exists ary],[array exists ary],[array default exists ary] + array default unset ary + lappend result [info exists ary],[array exists ary],[array default exists ary] + unset ary + lappend result [info exists ary],[array exists ary],[array default exists ary] + array default set ary 11 + lappend result [info exists ary],[array exists ary],[array default exists ary] +} -cleanup { + unset -nocomplain ary result +} -result {1,1,0 1,1,1 1,1,0 0,0,0 1,1,1} +test var-24.6 {array default exists: compiled} { + apply {{} { + array set ary {a 3} + lappend result [info exists ary],[array exists ary],[array default exists ary] + array default set ary 7 + lappend result [info exists ary],[array exists ary],[array default exists ary] + array default unset ary + lappend result [info exists ary],[array exists ary],[array default exists ary] + unset ary + lappend result [info exists ary],[array exists ary],[array default exists ary] + array default set ary 11 + lappend result [info exists ary],[array exists ary],[array default exists ary] + }} +} {1,1,0 1,1,1 1,1,0 0,0,0 1,1,1} +test var-24.7 {array default and append: interpreted} -setup { + unset -nocomplain ary result + set result {} +} -body { + array default set ary grill + lappend result [array size ary] [info exist ary(x)] + append ary(x) abc + lappend result [array size ary] $ary(x) + array default unset ary + append ary(x) def + append ary(y) ghi + lappend result [array size ary] $ary(x) $ary(y) +} -cleanup { + unset -nocomplain ary result +} -result {0 0 1 grillabc 2 grillabcdef ghi} +test var-24.8 {array default and append: compiled} { + apply {{} { + array default set ary grill + lappend result [array size ary] [info exist ary(x)] + append ary(x) abc + lappend result [array size ary] $ary(x) + array default unset ary + append ary(x) def + append ary(y) ghi + lappend result [array size ary] $ary(x) $ary(y) + }} +} {0 0 1 grillabc 2 grillabcdef ghi} +test var-24.9 {array default and lappend: interpreted} -setup { + unset -nocomplain ary result + set result {} +} -body { + array default set ary grill + lappend result [array size ary] [info exist ary(x)] + lappend ary(x) abc + lappend result [array size ary] $ary(x) + array default unset ary + lappend ary(x) def + lappend ary(y) ghi + lappend result [array size ary] $ary(x) $ary(y) +} -cleanup { + unset -nocomplain ary result +} -result {0 0 1 {grill abc} 2 {grill abc def} ghi} +test var-24.10 {array default and lappend: compiled} { + apply {{} { + array default set ary grill + lappend result [array size ary] [info exist ary(x)] + lappend ary(x) abc + lappend result [array size ary] $ary(x) + array default unset ary + lappend ary(x) def + lappend ary(y) ghi + lappend result [array size ary] $ary(x) $ary(y) + }} +} {0 0 1 {grill abc} 2 {grill abc def} ghi} +test var-24.11 {array default and incr: interpreted} -setup { + unset -nocomplain ary result + set result {} +} -body { + array default set ary 7 + lappend result [array size ary] [info exist ary(x)] + incr ary(x) 11 + lappend result [array size ary] $ary(x) + array default unset ary + incr ary(x) + incr ary(y) + lappend result [array size ary] $ary(x) $ary(y) +} -cleanup { + unset -nocomplain ary result +} -result {0 0 1 18 2 19 1} +test var-24.12 {array default and incr: compiled} { + apply {{} { + array default set ary 7 + lappend result [array size ary] [info exist ary(x)] + incr ary(x) 11 + lappend result [array size ary] $ary(x) + array default unset ary + incr ary(x) + incr ary(y) + lappend result [array size ary] $ary(x) $ary(y) + }} +} {0 0 1 18 2 19 1} +test var-24.13 {array default and dict: interpreted} -setup { + unset -nocomplain ary x y z +} -body { + array default set ary {x y} + dict lappend ary(p) x z + dict update ary(q) x y { + set y z + } + dict with ary(r) { + set x 123 + } + lsort -stride 2 -index 0 [array get ary] +} -cleanup { + unset -nocomplain ary x y z +} -result {p {x {y z}} q {x z} r {x 123}} +test var-24.14 {array default and dict: compiled} { + lsort -stride 2 -index 0 [apply {{} { + array default set ary {x y} + dict lappend ary(p) x z + dict update ary(q) x y { + set y z + } + dict with ary(r) { + set x 123 + } + array get ary + }}] +} {p {x {y z}} q {x z} r {x 123}} +test var-24.15 {array default set and get: two-level} { + apply {{} { + array set ary {a 3} + array default set ary 7 + apply {{} { + upvar 1 ary ary ary(c) c + lappend result $ary(a) $ary(b) $c + lappend result [info exist ary(a)] [info exist ary(b)] [info exist c] + lappend result [array default get ary] + }} + }} +} {3 7 7 1 0 0 7} catch {namespace delete ns} catch {unset arr} -- cgit v0.12 From 338b9ec9d27a63172d899b020d77c00abc84590c Mon Sep 17 00:00:00 2001 From: dgp Date: Mon, 24 Sep 2018 16:15:25 +0000 Subject: Silence debugging message in test suite. --- tests/httpTest.tcl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/httpTest.tcl b/tests/httpTest.tcl index 9cd7a5d..326b361 100644 --- a/tests/httpTest.tcl +++ b/tests/httpTest.tcl @@ -25,7 +25,7 @@ package require http namespace eval ::http { variable TestStartTimeInMs [clock milliseconds] - catch {puts stdout "Start time (zero ms) is $TestStartTimeInMs"} +# catch {puts stdout "Start time (zero ms) is $TestStartTimeInMs"} } namespace eval ::httpTest { -- cgit v0.12 From ac61d77a4196e4243153563d9cae24f2f20550bc Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Mon, 24 Sep 2018 23:24:00 +0000 Subject: More fixes in Tcl_WinTChar2Utf: Don't restart loop when output contains null-byte. --- generic/tclStubInit.c | 18 +++++++++--------- win/tclWin32Dll.c | 18 +++++++++--------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/generic/tclStubInit.c b/generic/tclStubInit.c index 66ad753..6614764 100644 --- a/generic/tclStubInit.c +++ b/generic/tclStubInit.c @@ -258,8 +258,8 @@ Tcl_WinTCharToUtf( int len, Tcl_DString *dsPtr) { - char *p, *r; - int size; + char *p; + int size, i = 0; if (len > 0) { len /= 2; @@ -267,18 +267,18 @@ Tcl_WinTCharToUtf( size = WideCharToMultiByte(CP_UTF8, 0, string, len, 0, 0, NULL, NULL); Tcl_DStringInit(dsPtr); Tcl_DStringSetLength(dsPtr, size+8); /* Add some spare, in case of NULL-bytes */ - r = p = (char *)Tcl_DStringValue(dsPtr); + p = (char *)Tcl_DStringValue(dsPtr); WideCharToMultiByte(CP_UTF8, 0, string, len, p, size, NULL, NULL); if (len == -1) --size; /* account for 0-byte at string end */ - while (r < p+size) { - if (!*r) { + while (i < size) { + if (!p[i]) { /* Output contains '\0'-byte, but Tcl expect two-bytes: C0 80 */ - memmove(r+2, r+1, p-r+size-1); - memcpy(r++, "\xC0\x80", 2); + memmove(p+i+2, p+i+1, size-i-1); + memcpy(p + i++, "\xC0\x80", 2); Tcl_DStringSetLength(dsPtr, ++size + 1); - r = p = (char *)Tcl_DStringValue(dsPtr); + p = (char *)Tcl_DStringValue(dsPtr); } - ++r; + ++i; } Tcl_DStringSetLength(dsPtr, size); p[size] = 0; diff --git a/win/tclWin32Dll.c b/win/tclWin32Dll.c index 13a3dec..60edbab 100644 --- a/win/tclWin32Dll.c +++ b/win/tclWin32Dll.c @@ -506,8 +506,8 @@ Tcl_WinTCharToUtf( Tcl_DString *dsPtr) /* Uninitialized or free DString in which the * converted string is stored. */ { - char *p, *r; - int size; + char *p; + int size, i = 0; if (len > 0) { len /= 2; @@ -515,18 +515,18 @@ Tcl_WinTCharToUtf( size = WideCharToMultiByte(CP_UTF8, 0, string, len, 0, 0, NULL, NULL); Tcl_DStringInit(dsPtr); Tcl_DStringSetLength(dsPtr, size+8); /* Add some spare, in case of NULL-bytes */ - r = p = (char *)Tcl_DStringValue(dsPtr); + p = (char *)Tcl_DStringValue(dsPtr); WideCharToMultiByte(CP_UTF8, 0, string, len, p, size, NULL, NULL); if (len == -1) --size; /* account for 0-byte at string end */ - while (r < p+size) { - if (!*r) { + while (i < size) { + if (!p[i]) { /* Output contains '\0'-byte, but Tcl expect two-bytes: C0 80 */ - memmove(r+2, r+1, p-r+size-1); - memcpy(r++, "\xC0\x80", 2); + memmove(p+i+2, p+i+1, size-i-1); + memcpy(p + i++, "\xC0\x80", 2); Tcl_DStringSetLength(dsPtr, ++size + 1); - r = p = (char *)Tcl_DStringValue(dsPtr); + p = (char *)Tcl_DStringValue(dsPtr); } - ++r; + ++i; } Tcl_DStringSetLength(dsPtr, size); p[size] = 0; -- cgit v0.12 From 76e2e078e32be366597a31936f3661b3ab42d93e Mon Sep 17 00:00:00 2001 From: dkf Date: Tue, 25 Sep 2018 07:24:44 +0000 Subject: Correct variable existence check in [array default exists] --- generic/tclVar.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/generic/tclVar.c b/generic/tclVar.c index 092d902..6bcd8d8 100644 --- a/generic/tclVar.c +++ b/generic/tclVar.c @@ -247,7 +247,6 @@ static const Tcl_ObjType tclParsedVarNameType = { "parsedVarName", FreeParsedVarName, DupParsedVarName, NULL, NULL }; - Var * TclVarHashCreateVar( @@ -6572,7 +6571,8 @@ ArrayDefaultCmd( */ CleanupVar(varPtr, arrayPtr); - TclObjVarErrMsg(interp, arrayNameObj, NULL, "array default set", needArray, -1); + TclObjVarErrMsg(interp, arrayNameObj, NULL, "array default set", + needArray, -1); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "VARNAME", TclGetString(arrayNameObj), NULL); return TCL_ERROR; @@ -6600,12 +6600,16 @@ ArrayDefaultCmd( Tcl_WrongNumArgs(interp, 2, objv, "arrayName"); return TCL_ERROR; } - if (varPtr && !isArray) { - return NotArrayError(interp, arrayNameObj); - } - if (!varPtr) { + /* + * Undefined variables (whether or not they have storage allocated) do + * not have defaults, and this is not an error case. + */ + + if (!varPtr || TclIsVarUndefined(varPtr)) { Tcl_SetObjResult(interp, Tcl_NewBooleanObj(0)); + } else if (!isArray) { + return NotArrayError(interp, arrayNameObj); } else { defaultValueObj = GetArrayDefault(varPtr); Tcl_SetObjResult(interp, Tcl_NewBooleanObj(!!defaultValueObj)); -- cgit v0.12 From 7b0e9cef6051f9c59269659da34e1744d074080e Mon Sep 17 00:00:00 2001 From: dkf Date: Tue, 25 Sep 2018 07:27:31 +0000 Subject: More correct variable existence checks --- generic/tclVar.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/generic/tclVar.c b/generic/tclVar.c index 6bcd8d8..fbe43ac 100644 --- a/generic/tclVar.c +++ b/generic/tclVar.c @@ -6535,7 +6535,7 @@ ArrayDefaultCmd( Tcl_WrongNumArgs(interp, 2, objv, "arrayName"); return TCL_ERROR; } - if (!varPtr || !isArray) { + if (!varPtr || TclIsVarUndefined(varPtr) || !isArray) { return NotArrayError(interp, arrayNameObj); } @@ -6621,11 +6621,11 @@ ArrayDefaultCmd( Tcl_WrongNumArgs(interp, 2, objv, "arrayName"); return TCL_ERROR; } - if (varPtr && !isArray) { - return NotArrayError(interp, arrayNameObj); - } - - if (varPtr) { + + if (varPtr && !TclIsVarUndefined(varPtr)) { + if (!isArray) { + return NotArrayError(interp, arrayNameObj); + } SetArrayDefault(varPtr, NULL); } return TCL_OK; -- cgit v0.12 From beac2287a9fc876159823c0ca79d713b7851ddae Mon Sep 17 00:00:00 2001 From: dkf Date: Tue, 25 Sep 2018 07:36:09 +0000 Subject: Corrected the semantics of [append] with defaults --- generic/tclVar.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/generic/tclVar.c b/generic/tclVar.c index fbe43ac..ec48984 100644 --- a/generic/tclVar.c +++ b/generic/tclVar.c @@ -1907,8 +1907,27 @@ TclPtrSetVarIdx( */ if (oldValuePtr == NULL) { - varPtr->value.objPtr = newValuePtr; - Tcl_IncrRefCount(newValuePtr); + if (arrayPtr) { + Tcl_Obj *defValuePtr = GetArrayDefault(arrayPtr); + + if (defValuePtr) { + Tcl_Obj *valuePtr = Tcl_DuplicateObj(defValuePtr); + + varPtr->value.objPtr = valuePtr; + TclContinuationsCopy(valuePtr, defValuePtr); + Tcl_IncrRefCount(valuePtr); + Tcl_AppendObjToObj(valuePtr, newValuePtr); + if (newValuePtr->refCount == 0) { + Tcl_DecrRefCount(newValuePtr); + } + } else { + varPtr->value.objPtr = newValuePtr; + Tcl_IncrRefCount(newValuePtr); + } + } else { + varPtr->value.objPtr = newValuePtr; + Tcl_IncrRefCount(newValuePtr); + } } else { if (Tcl_IsShared(oldValuePtr)) { /* Append to copy. */ varPtr->value.objPtr = Tcl_DuplicateObj(oldValuePtr); -- cgit v0.12 From b1f92f488848d8c4cba71716ecd0264bb976d00b Mon Sep 17 00:00:00 2001 From: dkf Date: Tue, 25 Sep 2018 10:18:32 +0000 Subject: Added test cases for errors --- tests/var.test | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/tests/var.test b/tests/var.test index a05106f..36beb3a 100644 --- a/tests/var.test +++ b/tests/var.test @@ -1390,6 +1390,73 @@ test var-24.15 {array default set and get: two-level} { }} }} } {3 7 7 1 0 0 7} +test var-24.16 {array default set: errors} -setup { + unset -nocomplain ary +} -body { + set ary not-an-array + array default set ary 7 +} -returnCodes error -cleanup { + unset -nocomplain ary +} -result {can't array default set "ary": variable isn't array} +test var-24.17 {array default set: errors} -setup { + unset -nocomplain ary +} -body { + array default set ary +} -returnCodes error -cleanup { + unset -nocomplain ary +} -result * -match glob +test var-24.18 {array default set: errors} -setup { + unset -nocomplain ary +} -body { + array default set ary x y +} -returnCodes error -cleanup { + unset -nocomplain ary +} -result * -match glob +test var-24.19 {array default get: errors} -setup { + unset -nocomplain ary +} -body { + set ary not-an-array + array default get ary +} -returnCodes error -cleanup { + unset -nocomplain ary +} -result {"ary" isn't an array} +test var-24.20 {array default get: errors} -setup { + unset -nocomplain ary +} -body { + array default get ary x y +} -returnCodes error -cleanup { + unset -nocomplain ary +} -result * -match glob +test var-24.21 {array default exists: errors} -setup { + unset -nocomplain ary +} -body { + set ary not-an-array + array default exists ary +} -returnCodes error -cleanup { + unset -nocomplain ary +} -result {"ary" isn't an array} +test var-24.22 {array default exists: errors} -setup { + unset -nocomplain ary +} -body { + array default exists ary x +} -returnCodes error -cleanup { + unset -nocomplain ary +} -result * -match glob +test var-24.23 {array default unset: errors} -setup { + unset -nocomplain ary +} -body { + set ary not-an-array + array default unset ary +} -returnCodes error -cleanup { + unset -nocomplain ary +} -result {"ary" isn't an array} +test var-24.24 {array default unset: errors} -setup { + unset -nocomplain ary +} -body { + array default unset ary x +} -returnCodes error -cleanup { + unset -nocomplain ary +} -result * -match glob catch {namespace delete ns} catch {unset arr} -- cgit v0.12 From d5583552c0832cc427f3717df34e19680e4d10e9 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Tue, 25 Sep 2018 21:16:32 +0000 Subject: Contributed patch from Gustaf Neumann, preventing problems where "localCachePtr" can be NULL --- generic/tclProc.c | 36 +++++++++++++++++++----------------- generic/tclVar.c | 53 ++++++++++++++++++++++++++++++----------------------- 2 files changed, 49 insertions(+), 40 deletions(-) diff --git a/generic/tclProc.c b/generic/tclProc.c index 232eb93..533b817 100644 --- a/generic/tclProc.c +++ b/generic/tclProc.c @@ -1035,7 +1035,6 @@ ProcWrongNumArgs( { CallFrame *framePtr = ((Interp *)interp)->varFramePtr; register Proc *procPtr = framePtr->procPtr; - register Var *defPtr; int localCt = procPtr->numCompiledLocals, numArgs, i; Tcl_Obj **desiredObjs; const char *final = NULL; @@ -1059,23 +1058,26 @@ ProcWrongNumArgs( } Tcl_IncrRefCount(desiredObjs[0]); - defPtr = (Var *) (&framePtr->localCachePtr->varName0 + localCt); - for (i=1 ; i<=numArgs ; i++, defPtr++) { - Tcl_Obj *argObj; - Tcl_Obj *namePtr = localName(framePtr, i-1); - - if (defPtr->value.objPtr != NULL) { - TclNewObj(argObj); - Tcl_AppendStringsToObj(argObj, "?", TclGetString(namePtr), "?", NULL); - } else if (defPtr->flags & VAR_IS_ARGS) { - numArgs--; - final = "?arg ...?"; - break; - } else { - argObj = namePtr; - Tcl_IncrRefCount(namePtr); + if (localCt > 0) { + register Var *defPtr = (Var *) (&framePtr->localCachePtr->varName0 + localCt); + + for (i=1 ; i<=numArgs ; i++, defPtr++) { + Tcl_Obj *argObj; + Tcl_Obj *namePtr = localName(framePtr, i-1); + + if (defPtr->value.objPtr != NULL) { + TclNewObj(argObj); + Tcl_AppendStringsToObj(argObj, "?", TclGetString(namePtr), "?", NULL); + } else if (defPtr->flags & VAR_IS_ARGS) { + numArgs--; + final = "?arg ...?"; + break; + } else { + argObj = namePtr; + Tcl_IncrRefCount(namePtr); + } + desiredObjs[i] = argObj; } - desiredObjs[i] = argObj; } Tcl_ResetResult(interp); diff --git a/generic/tclVar.c b/generic/tclVar.c index ed16c9f..7b3db7e 100644 --- a/generic/tclVar.c +++ b/generic/tclVar.c @@ -972,20 +972,24 @@ TclLookupSimpleVar( } } } else { /* Local var: look in frame varFramePtr. */ - int localLen, localCt = varFramePtr->numCompiledLocals; - Tcl_Obj **objPtrPtr = &varFramePtr->localCachePtr->varName0; - const char *localNameStr; + int localCt = varFramePtr->numCompiledLocals; - for (i=0 ; i 0) { + Tcl_Obj **objPtrPtr = &varFramePtr->localCachePtr->varName0; + const char *localNameStr; + int localLen; - if (objPtr) { - localNameStr = TclGetStringFromObj(objPtr, &localLen); + for (i=0 ; icompiledLocals[i]; + *indexPtr = i; + return (Var *) &varFramePtr->compiledLocals[i]; + } } } } @@ -6132,7 +6136,7 @@ AppendLocals( Interp *iPtr = (Interp *) interp; Var *varPtr; int i, localVarCt, added; - Tcl_Obj **varNamePtr, *objNamePtr; + Tcl_Obj *objNamePtr; const char *varName; TclVarHashTable *localVarTablePtr; Tcl_HashSearch search; @@ -6142,27 +6146,30 @@ AppendLocals( localVarCt = iPtr->varFramePtr->numCompiledLocals; varPtr = iPtr->varFramePtr->compiledLocals; localVarTablePtr = iPtr->varFramePtr->varTablePtr; - varNamePtr = &iPtr->varFramePtr->localCachePtr->varName0; if (includeLinks) { Tcl_InitObjHashTable(&addedTable); } - for (i = 0; i < localVarCt; i++, varNamePtr++) { - /* - * Skip nameless (temporary) variables and undefined variables. - */ + if (localVarCt > 0) { + Tcl_Obj **varNamePtr = &iPtr->varFramePtr->localCachePtr->varName0; + + for (i = 0; i < localVarCt; i++, varNamePtr++) { + /* + * Skip nameless (temporary) variables and undefined variables. + */ - if (*varNamePtr && !TclIsVarUndefined(varPtr) + if (*varNamePtr && !TclIsVarUndefined(varPtr) && (includeLinks || !TclIsVarLink(varPtr))) { - varName = TclGetString(*varNamePtr); - if ((pattern == NULL) || Tcl_StringMatch(varName, pattern)) { - Tcl_ListObjAppendElement(interp, listPtr, *varNamePtr); - if (includeLinks) { - Tcl_CreateHashEntry(&addedTable, *varNamePtr, &added); + varName = TclGetString(*varNamePtr); + if ((pattern == NULL) || Tcl_StringMatch(varName, pattern)) { + Tcl_ListObjAppendElement(interp, listPtr, *varNamePtr); + if (includeLinks) { + Tcl_CreateHashEntry(&addedTable, *varNamePtr, &added); + } } } + varPtr++; } - varPtr++; } /* -- cgit v0.12 From 3b77852126dd89aeae123f069e9e8b850b574f21 Mon Sep 17 00:00:00 2001 From: dkf Date: Wed, 26 Sep 2018 08:12:34 +0000 Subject: Fix semantics of [lappend] with defaults in a procedure. --- generic/tclVar.c | 178 +++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 126 insertions(+), 52 deletions(-) diff --git a/generic/tclVar.c b/generic/tclVar.c index ec48984..6676c6c 100644 --- a/generic/tclVar.c +++ b/generic/tclVar.c @@ -1774,6 +1774,130 @@ TclPtrSetVar( /* *---------------------------------------------------------------------- * + * ListAppendInVar, StringAppendInVar -- + * + * Support functions for TclPtrSetVarIdx that implement various types of + * appending operations. + * + * Results: + * ListAppendInVar returns a Tcl result code (from the core list append + * operation). StringAppendInVar has no return value. + * + * Side effects: + * The variable or element of the array is updated. This may make the + * variable/element exist. Reference counts of values may be updated. + * + *---------------------------------------------------------------------- + */ + +static inline int +ListAppendInVar( + Tcl_Interp *interp, + Var *varPtr, + Var *arrayPtr, + Tcl_Obj *oldValuePtr, + Tcl_Obj *newValuePtr) +{ + if (oldValuePtr == NULL) { + /* + * No previous value. Check for defaults if there's an array we can + * ask this of. + */ + + if (arrayPtr) { + Tcl_Obj *defValuePtr = GetArrayDefault(arrayPtr); + + if (defValuePtr) { + oldValuePtr = Tcl_DuplicateObj(defValuePtr); + } + } + + if (oldValuePtr == NULL) { + /* + * No default. [lappend] semantics say this is like being an empty + * string. + */ + + TclNewObj(oldValuePtr); + } + varPtr->value.objPtr = oldValuePtr; + Tcl_IncrRefCount(oldValuePtr); /* Since var is referenced. */ + } else if (Tcl_IsShared(oldValuePtr)) { + varPtr->value.objPtr = Tcl_DuplicateObj(oldValuePtr); + TclDecrRefCount(oldValuePtr); + oldValuePtr = varPtr->value.objPtr; + Tcl_IncrRefCount(oldValuePtr); /* Since var is referenced. */ + } + + return Tcl_ListObjAppendElement(interp, oldValuePtr, newValuePtr); +} + +static inline void +StringAppendInVar( + Var *varPtr, + Var *arrayPtr, + Tcl_Obj *oldValuePtr, + Tcl_Obj *newValuePtr) +{ + /* + * If there was no previous value, either we use the array's default (if + * this is an array with a default at all) or we treat this as a simple + * set. + */ + + if (oldValuePtr == NULL) { + if (arrayPtr) { + Tcl_Obj *defValuePtr = GetArrayDefault(arrayPtr); + + if (defValuePtr) { + /* + * This is *almost* the same as the shared path below, except + * that the original value reference in defValuePtr is not + * decremented. + */ + + Tcl_Obj *valuePtr = Tcl_DuplicateObj(defValuePtr); + + varPtr->value.objPtr = valuePtr; + TclContinuationsCopy(valuePtr, defValuePtr); + Tcl_IncrRefCount(valuePtr); + Tcl_AppendObjToObj(valuePtr, newValuePtr); + if (newValuePtr->refCount == 0) { + Tcl_DecrRefCount(newValuePtr); + } + return; + } + } + varPtr->value.objPtr = newValuePtr; + Tcl_IncrRefCount(newValuePtr); + return; + } + + /* + * We append newValuePtr's bytes but don't change its ref count. Unless + * the reference is shared, when we have to duplicate in order to be safe + * to modify at all. + */ + + if (Tcl_IsShared(oldValuePtr)) { /* Append to copy. */ + varPtr->value.objPtr = Tcl_DuplicateObj(oldValuePtr); + + TclContinuationsCopy(varPtr->value.objPtr, oldValuePtr); + + TclDecrRefCount(oldValuePtr); + oldValuePtr = varPtr->value.objPtr; + Tcl_IncrRefCount(oldValuePtr); /* Since var is ref */ + } + + Tcl_AppendObjToObj(oldValuePtr, newValuePtr); + if (newValuePtr->refCount == 0) { + Tcl_DecrRefCount(newValuePtr); + } +} + +/* + *---------------------------------------------------------------------- + * * TclPtrSetVarIdx -- * * This function is the same as Tcl_SetVar2Ex above, except that it @@ -1886,63 +2010,13 @@ TclPtrSetVarIdx( } if (flags & (TCL_APPEND_VALUE|TCL_LIST_ELEMENT)) { if (flags & TCL_LIST_ELEMENT) { /* Append list element. */ - if (oldValuePtr == NULL) { - TclNewObj(oldValuePtr); - varPtr->value.objPtr = oldValuePtr; - Tcl_IncrRefCount(oldValuePtr); /* Since var is referenced. */ - } else if (Tcl_IsShared(oldValuePtr)) { - varPtr->value.objPtr = Tcl_DuplicateObj(oldValuePtr); - TclDecrRefCount(oldValuePtr); - oldValuePtr = varPtr->value.objPtr; - Tcl_IncrRefCount(oldValuePtr); /* Since var is referenced. */ - } - result = Tcl_ListObjAppendElement(interp, oldValuePtr, + result = ListAppendInVar(interp, varPtr, arrayPtr, oldValuePtr, newValuePtr); if (result != TCL_OK) { goto earlyError; } } else { /* Append string. */ - /* - * We append newValuePtr's bytes but don't change its ref count. - */ - - if (oldValuePtr == NULL) { - if (arrayPtr) { - Tcl_Obj *defValuePtr = GetArrayDefault(arrayPtr); - - if (defValuePtr) { - Tcl_Obj *valuePtr = Tcl_DuplicateObj(defValuePtr); - - varPtr->value.objPtr = valuePtr; - TclContinuationsCopy(valuePtr, defValuePtr); - Tcl_IncrRefCount(valuePtr); - Tcl_AppendObjToObj(valuePtr, newValuePtr); - if (newValuePtr->refCount == 0) { - Tcl_DecrRefCount(newValuePtr); - } - } else { - varPtr->value.objPtr = newValuePtr; - Tcl_IncrRefCount(newValuePtr); - } - } else { - varPtr->value.objPtr = newValuePtr; - Tcl_IncrRefCount(newValuePtr); - } - } else { - if (Tcl_IsShared(oldValuePtr)) { /* Append to copy. */ - varPtr->value.objPtr = Tcl_DuplicateObj(oldValuePtr); - - TclContinuationsCopy(varPtr->value.objPtr, oldValuePtr); - - TclDecrRefCount(oldValuePtr); - oldValuePtr = varPtr->value.objPtr; - Tcl_IncrRefCount(oldValuePtr); /* Since var is ref */ - } - Tcl_AppendObjToObj(oldValuePtr, newValuePtr); - if (newValuePtr->refCount == 0) { - Tcl_DecrRefCount(newValuePtr); - } - } + StringAppendInVar(varPtr, arrayPtr, oldValuePtr, newValuePtr); } } else if (newValuePtr != oldValuePtr) { /* -- cgit v0.12 From 761a7867d59650fe2a632e377c216fc8b39beaf3 Mon Sep 17 00:00:00 2001 From: dkf Date: Wed, 26 Sep 2018 13:08:46 +0000 Subject: Make defaults work even when [upvar]ed to just a non-existent element. --- generic/tclInt.h | 1 + generic/tclVar.c | 104 +++++++++++++++++++++++++++++++++-------------------- tests/set-old.test | 4 +-- 3 files changed, 69 insertions(+), 40 deletions(-) diff --git a/generic/tclInt.h b/generic/tclInt.h index 40fae04..d4992dc 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -4142,6 +4142,7 @@ MODULE_SCOPE TclProcessWaitStatus TclProcessWait(Tcl_Pid pid, int options, */ MODULE_SCOPE void TclInitArrayVar(Var *arrayPtr); +MODULE_SCOPE Tcl_Obj * TclGetArrayDefault(Var *arrayPtr); /* * Utility routines for encoding index values as integers. Used by both diff --git a/generic/tclVar.c b/generic/tclVar.c index b2cbebe..8860df5 100644 --- a/generic/tclVar.c +++ b/generic/tclVar.c @@ -165,6 +165,18 @@ typedef struct ArraySearch { } ArraySearch; /* + * TIP #508: [array default] + * + * The following structure extends the regular TclVarHashTable used by array + * variables to store their optional default value. + */ + +typedef struct ArrayVarHashTable { + TclVarHashTable table; + Tcl_Obj *defaultObj; +} ArrayVarHashTable; + +/* * Forward references to functions defined later in this file: */ @@ -205,7 +217,6 @@ static int ArrayDefaultCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); static void DeleteArrayVar(Var *arrayPtr); -static Tcl_Obj * GetArrayDefault(Var *arrayPtr); static void SetArrayDefault(Var *arrayPtr, Tcl_Obj *defaultObj); /* @@ -1414,8 +1425,21 @@ TclPtrGetVarIdx( /* * Return the array default value if any. */ - if (arrayPtr && TclIsVarArray(arrayPtr) && GetArrayDefault(arrayPtr)) { - return GetArrayDefault(arrayPtr); + + if (arrayPtr && TclIsVarArray(arrayPtr) && TclGetArrayDefault(arrayPtr)) { + return TclGetArrayDefault(arrayPtr); + } + if (TclIsVarArrayElement(varPtr) && !arrayPtr) { + /* + * UGLY! Peek inside the implementation of things. + */ + + ArrayVarHashTable *avhtPtr = (ArrayVarHashTable *) + ((VarInHash *) varPtr)->entry.tablePtr; + + if (avhtPtr->defaultObj) { + return avhtPtr->defaultObj; + } } if (flags & TCL_LEAVE_ERR_MSG) { @@ -1809,7 +1833,7 @@ ListAppendInVar( */ if (arrayPtr) { - Tcl_Obj *defValuePtr = GetArrayDefault(arrayPtr); + Tcl_Obj *defValuePtr = TclGetArrayDefault(arrayPtr); if (defValuePtr) { oldValuePtr = Tcl_DuplicateObj(defValuePtr); @@ -1851,7 +1875,7 @@ StringAppendInVar( if (oldValuePtr == NULL) { if (arrayPtr) { - Tcl_Obj *defValuePtr = GetArrayDefault(arrayPtr); + Tcl_Obj *defValuePtr = TclGetArrayDefault(arrayPtr); if (defValuePtr) { /* @@ -6564,25 +6588,11 @@ CompareVarKeys( return ((l1 == l2) && !memcmp(p1, p2, l1)); } -/* - * TIP #508: [array default] - */ - -/* - * The following structure extends the regular TclVarHashTable used by array - * variables to store their optional default value. - */ - -typedef struct ArrayVarHashTable { - TclVarHashTable table; - Tcl_Obj *defaultObj; -} ArrayVarHashTable; - /*---------------------------------------------------------------------- * * ArrayDefaultCmd -- * - * This function implements the 'array default' Tcl command. + * This function implements the 'array default' Tcl command. * Refer to the user documentation for details on what it does. * * Results: @@ -6639,7 +6649,7 @@ ArrayDefaultCmd( return NotArrayError(interp, arrayNameObj); } - defaultValueObj = GetArrayDefault(varPtr); + defaultValueObj = TclGetArrayDefault(varPtr); if (!defaultValueObj) { /* Array default must exist. */ Tcl_SetObjResult(interp, Tcl_NewStringObj( @@ -6660,7 +6670,7 @@ ArrayDefaultCmd( * Attempt to create array if needed. */ varPtr = TclObjLookupVarEx(interp, arrayNameObj, NULL, - /*flags*/ TCL_LEAVE_ERR_MSG, /*msg*/ "array default set", + /*flags*/ TCL_LEAVE_ERR_MSG, /*msg*/ "array default set", /*createPart1*/ 1, /*createPart2*/ 1, &arrayPtr); if (varPtr == NULL) { return TCL_ERROR; @@ -6669,7 +6679,7 @@ ArrayDefaultCmd( /* * Not a valid array name. */ - + CleanupVar(varPtr, arrayPtr); TclObjVarErrMsg(interp, arrayNameObj, NULL, "array default set", needArray, -1); @@ -6711,7 +6721,7 @@ ArrayDefaultCmd( } else if (!isArray) { return NotArrayError(interp, arrayNameObj); } else { - defaultValueObj = GetArrayDefault(varPtr); + defaultValueObj = TclGetArrayDefault(varPtr); Tcl_SetObjResult(interp, Tcl_NewBooleanObj(!!defaultValueObj)); } return TCL_OK; @@ -6743,17 +6753,25 @@ void TclInitArrayVar( Var *arrayPtr) { - ArrayVarHashTable *tablePtr; + ArrayVarHashTable *tablePtr = ckalloc(sizeof(ArrayVarHashTable)); + + /* + * Mark the variable as an array. + */ TclSetVarArray(arrayPtr); - tablePtr = ckalloc(sizeof(ArrayVarHashTable)); + /* + * Regular TclVarHashTable initialization. + */ - // Regular TclVarHashTable initialization. arrayPtr->value.tablePtr = (TclVarHashTable *) tablePtr; TclInitVarHashTable(arrayPtr->value.tablePtr, TclGetVarNsPtr(arrayPtr)); - // Default value initialization. + /* + * Default value initialization. + */ + tablePtr->defaultObj = NULL; } @@ -6765,14 +6783,20 @@ static void DeleteArrayVar( Var *arrayPtr) { - ArrayVarHashTable *tablePtr = (ArrayVarHashTable *) arrayPtr->value.tablePtr; + ArrayVarHashTable *tablePtr = (ArrayVarHashTable *) + arrayPtr->value.tablePtr; + + /* + * Default value cleanup. + */ - // Default value cleanup. SetArrayDefault(arrayPtr, NULL); - // Regular TclVarHashTable cleanup. - VarHashDeleteTable(arrayPtr->value.tablePtr); + /* + * Regular TclVarHashTable cleanup. + */ + VarHashDeleteTable(arrayPtr->value.tablePtr); ckfree(tablePtr); } @@ -6780,11 +6804,13 @@ DeleteArrayVar( * Get array default value if any. */ -static Tcl_Obj * -GetArrayDefault( +Tcl_Obj * +TclGetArrayDefault( Var *arrayPtr) { - ArrayVarHashTable *tablePtr = (ArrayVarHashTable *) arrayPtr->value.tablePtr; + ArrayVarHashTable *tablePtr = (ArrayVarHashTable *) + arrayPtr->value.tablePtr; + return tablePtr->defaultObj; } @@ -6797,16 +6823,18 @@ SetArrayDefault( Var *arrayPtr, Tcl_Obj *defaultObj) { - ArrayVarHashTable *tablePtr = (ArrayVarHashTable *) arrayPtr->value.tablePtr; - + ArrayVarHashTable *tablePtr = (ArrayVarHashTable *) + arrayPtr->value.tablePtr; + /* * Increment/decrement refcount twice to ensure that the object is shared, * so that it doesn't get modified accidentally by the folling code: - * + * * array default set v 1 * lappend v(a) 2; # returns a new object {1 2} * set v(b); # returns the original default object "1" */ + if (tablePtr->defaultObj) { Tcl_DecrRefCount(tablePtr->defaultObj); Tcl_DecrRefCount(tablePtr->defaultObj); diff --git a/tests/set-old.test b/tests/set-old.test index b2e7aa6..ea5155b 100644 --- a/tests/set-old.test +++ b/tests/set-old.test @@ -340,7 +340,7 @@ test set-old-8.6 {array command} { catch {unset a} set a(22) 3 list [catch {array gorp a} msg] $msg -} {1 {unknown or ambiguous subcommand "gorp": must be anymore, donesearch, exists, for, get, names, nextelement, set, size, startsearch, statistics, or unset}} +} {1 {unknown or ambiguous subcommand "gorp": must be anymore, default, donesearch, exists, for, get, names, nextelement, set, size, startsearch, statistics, or unset}} test set-old-8.7 {array command, anymore option} { catch {unset a} list [catch {array anymore a x} msg] $msg @@ -700,7 +700,7 @@ test set-old-9.1 {ids for array enumeration} { catch {unset a} set a(a) 1 list [array star a] [array star a] [array done a s-1-a; array star a] \ - [array done a s-2-a; array d a s-3-a; array start a] + [array done a s-2-a; array do a s-3-a; array start a] } {s-1-a s-2-a s-3-a s-1-a} test set-old-9.2 {array enumeration} { catch {unset a} -- cgit v0.12 From 9aa47b2cfa64ee148cbc6dace75fbab5a48209b8 Mon Sep 17 00:00:00 2001 From: dkf Date: Wed, 26 Sep 2018 13:09:20 +0000 Subject: Improved comment. --- generic/tclVar.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/generic/tclVar.c b/generic/tclVar.c index 8860df5..cafa6a3 100644 --- a/generic/tclVar.c +++ b/generic/tclVar.c @@ -1431,7 +1431,9 @@ TclPtrGetVarIdx( } if (TclIsVarArrayElement(varPtr) && !arrayPtr) { /* - * UGLY! Peek inside the implementation of things. + * UGLY! Peek inside the implementation of things. This lets us get + * the default of an array even when we've been [upvar]ed to just an + * element of the array. */ ArrayVarHashTable *avhtPtr = (ArrayVarHashTable *) -- cgit v0.12 From 59f808eb7a065aaf628c751e8eb2c7e20505989b Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 26 Sep 2018 19:38:08 +0000 Subject: Improvements for zipfs. Document that TclZipfs_AppHook only works on Windows in UNICODE mode. Also, remove this from the stub table because it should never be called this way. Prevent a possible crash on win32 startup. --- doc/zipfs.3 | 4 +++ generic/tcl.decls | 7 +---- generic/tcl.h | 3 ++ generic/tclDecls.h | 1 + generic/tclPlatDecls.h | 27 ----------------- generic/tclStubInit.c | 7 ----- generic/tclZipfs.c | 80 +++++++++++++++++++++++++------------------------- win/tclAppInit.c | 3 +- 8 files changed, 51 insertions(+), 81 deletions(-) diff --git a/doc/zipfs.3 b/doc/zipfs.3 index 7514525..ce5d5eb 100644 --- a/doc/zipfs.3 +++ b/doc/zipfs.3 @@ -47,6 +47,10 @@ If a file named \fBmain.tcl\fR is located in that file system, it is treated as the startup script for the process. If the file \fIZIPROOT\fR\fB/app/tcl_library/init.tcl\fR is present, \fBtcl_library\fR is set to \fIZIPROOT\fR\fB/app/tcl_library. .PP +On Windows, \fBTclZipfs_AppHook()\fR has a slightly different signature, it uses +WCHAR in stead of char. As a result, it only works if your application is compiled +using -DUNICODE. +.PP If the \fBtcl_library\fR was not found in the application, the system will then search for it as either a VFS attached to the application dynamic library, or as a zip archive named libtcl_\fIMAJOR\fR_\fIMINOR\fR_\fIpatchLevel\fR.zip either in the present working directory diff --git a/generic/tcl.decls b/generic/tcl.decls index 92e87d6..61247e6 100644 --- a/generic/tcl.decls +++ b/generic/tcl.decls @@ -2365,9 +2365,6 @@ interface tclPlat ################################ # Unix specific functions # (none) -declare 2 unix { - int TclZipfs_AppHook(int *argc, char ***argv) -} ################################ # Windows specific functions @@ -2380,9 +2377,7 @@ declare 0 win { declare 1 win { char *Tcl_WinTCharToUtf(const TCHAR *str, int len, Tcl_DString *dsPtr) } -declare 2 win { - int TclZipfs_AppHook(int *argc, TCHAR ***argv) -} + ################################ # Mac OS X specific functions diff --git a/generic/tcl.h b/generic/tcl.h index b44b9c3..2ced16b 100644 --- a/generic/tcl.h +++ b/generic/tcl.h @@ -2402,6 +2402,9 @@ EXTERN void Tcl_MainEx(int argc, char **argv, EXTERN const char * Tcl_PkgInitStubsCheck(Tcl_Interp *interp, const char *version, int exact); EXTERN void Tcl_GetMemoryInfo(Tcl_DString *dsPtr); +#ifndef _WIN32 +EXTERN int TclZipfs_AppHook(int *argc, char ***argv); +#endif /* *---------------------------------------------------------------------------- diff --git a/generic/tclDecls.h b/generic/tclDecls.h index 0449bf1..3fb5355 100644 --- a/generic/tclDecls.h +++ b/generic/tclDecls.h @@ -3873,6 +3873,7 @@ extern const TclStubs *tclStubsPtr; # define Tcl_MainEx Tcl_MainExW EXTERN void Tcl_MainExW(int argc, wchar_t **argv, Tcl_AppInitProc *appInitProc, Tcl_Interp *interp); + EXTERN int TclZipfs_AppHook(int *argc, wchar_t ***argv); #endif #undef TCL_STORAGE_CLASS diff --git a/generic/tclPlatDecls.h b/generic/tclPlatDecls.h index ac3f921..abc8ee8 100644 --- a/generic/tclPlatDecls.h +++ b/generic/tclPlatDecls.h @@ -50,12 +50,6 @@ extern "C" { * Exported function declarations: */ -#if !defined(_WIN32) && !defined(__CYGWIN__) && !defined(MAC_OSX_TCL) /* UNIX */ -/* Slot 0 is reserved */ -/* Slot 1 is reserved */ -/* 2 */ -EXTERN int TclZipfs_AppHook(int *argc, char ***argv); -#endif /* UNIX */ #if defined(_WIN32) || defined(__CYGWIN__) /* WIN */ /* 0 */ EXTERN TCHAR * Tcl_WinUtfToTChar(const char *str, int len, @@ -63,8 +57,6 @@ EXTERN TCHAR * Tcl_WinUtfToTChar(const char *str, int len, /* 1 */ EXTERN char * Tcl_WinTCharToUtf(const TCHAR *str, int len, Tcl_DString *dsPtr); -/* 2 */ -EXTERN int TclZipfs_AppHook(int *argc, TCHAR ***argv); #endif /* WIN */ #ifdef MAC_OSX_TCL /* MACOSX */ /* 0 */ @@ -77,28 +69,19 @@ EXTERN int Tcl_MacOSXOpenVersionedBundleResources( const char *bundleVersion, int hasResourceFile, int maxPathLen, char *libraryPath); -/* 2 */ -EXTERN int TclZipfs_AppHook(int *argc, char ***argv); #endif /* MACOSX */ typedef struct TclPlatStubs { int magic; void *hooks; -#if !defined(_WIN32) && !defined(__CYGWIN__) && !defined(MAC_OSX_TCL) /* UNIX */ - void (*reserved0)(void); - void (*reserved1)(void); - int (*tclZipfs_AppHook) (int *argc, char ***argv); /* 2 */ -#endif /* UNIX */ #if defined(_WIN32) || defined(__CYGWIN__) /* WIN */ TCHAR * (*tcl_WinUtfToTChar) (const char *str, int len, Tcl_DString *dsPtr); /* 0 */ char * (*tcl_WinTCharToUtf) (const TCHAR *str, int len, Tcl_DString *dsPtr); /* 1 */ - int (*tclZipfs_AppHook) (int *argc, TCHAR ***argv); /* 2 */ #endif /* WIN */ #ifdef MAC_OSX_TCL /* MACOSX */ int (*tcl_MacOSXOpenBundleResources) (Tcl_Interp *interp, const char *bundleName, int hasResourceFile, int maxPathLen, char *libraryPath); /* 0 */ int (*tcl_MacOSXOpenVersionedBundleResources) (Tcl_Interp *interp, const char *bundleName, const char *bundleVersion, int hasResourceFile, int maxPathLen, char *libraryPath); /* 1 */ - int (*tclZipfs_AppHook) (int *argc, char ***argv); /* 2 */ #endif /* MACOSX */ } TclPlatStubs; @@ -114,27 +97,17 @@ extern const TclPlatStubs *tclPlatStubsPtr; * Inline function declarations: */ -#if !defined(_WIN32) && !defined(__CYGWIN__) && !defined(MAC_OSX_TCL) /* UNIX */ -/* Slot 0 is reserved */ -/* Slot 1 is reserved */ -#define TclZipfs_AppHook \ - (tclPlatStubsPtr->tclZipfs_AppHook) /* 2 */ -#endif /* UNIX */ #if defined(_WIN32) || defined(__CYGWIN__) /* WIN */ #define Tcl_WinUtfToTChar \ (tclPlatStubsPtr->tcl_WinUtfToTChar) /* 0 */ #define Tcl_WinTCharToUtf \ (tclPlatStubsPtr->tcl_WinTCharToUtf) /* 1 */ -#define TclZipfs_AppHook \ - (tclPlatStubsPtr->tclZipfs_AppHook) /* 2 */ #endif /* WIN */ #ifdef MAC_OSX_TCL /* MACOSX */ #define Tcl_MacOSXOpenBundleResources \ (tclPlatStubsPtr->tcl_MacOSXOpenBundleResources) /* 0 */ #define Tcl_MacOSXOpenVersionedBundleResources \ (tclPlatStubsPtr->tcl_MacOSXOpenVersionedBundleResources) /* 1 */ -#define TclZipfs_AppHook \ - (tclPlatStubsPtr->tclZipfs_AppHook) /* 2 */ #endif /* MACOSX */ #endif /* defined(USE_TCL_STUBS) */ diff --git a/generic/tclStubInit.c b/generic/tclStubInit.c index 6614764..9fa5adb 100644 --- a/generic/tclStubInit.c +++ b/generic/tclStubInit.c @@ -855,20 +855,13 @@ static const TclIntPlatStubs tclIntPlatStubs = { static const TclPlatStubs tclPlatStubs = { TCL_STUB_MAGIC, 0, -#if !defined(_WIN32) && !defined(__CYGWIN__) && !defined(MAC_OSX_TCL) /* UNIX */ - 0, /* 0 */ - 0, /* 1 */ - TclZipfs_AppHook, /* 2 */ -#endif /* UNIX */ #if defined(_WIN32) || defined(__CYGWIN__) /* WIN */ Tcl_WinUtfToTChar, /* 0 */ Tcl_WinTCharToUtf, /* 1 */ - TclZipfs_AppHook, /* 2 */ #endif /* WIN */ #ifdef MAC_OSX_TCL /* MACOSX */ Tcl_MacOSXOpenBundleResources, /* 0 */ Tcl_MacOSXOpenVersionedBundleResources, /* 1 */ - TclZipfs_AppHook, /* 2 */ #endif /* MACOSX */ }; diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c index 55b854b..19673c8 100644 --- a/generic/tclZipfs.c +++ b/generic/tclZipfs.c @@ -18,10 +18,10 @@ #include "tclInt.h" #include "tclFileSystem.h" -#if !defined(_WIN32) && !defined(_WIN64) -#include -#else +#ifdef _WIN32 #include +#else +#include #endif #include #include @@ -142,19 +142,16 @@ * Windows drive letters. */ -#if defined(_WIN32) || defined(_WIN64) -#define HAS_DRIVES 1 +#ifdef _WIN32 static const char drvletters[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; -#else -#define HAS_DRIVES 0 #endif /* * Mutex to protect localtime(3) when no reentrant version available. */ -#if !defined(_WIN32) && !defined(_WIN64) +#ifndef _WIN32 #ifndef HAVE_LOCALTIME_R #ifdef TCL_THREADS TCL_DECLARE_MUTEX(localtimeMutex) @@ -173,23 +170,21 @@ typedef struct ZipFile { Tcl_Channel chan; /* Channel handle or NULL */ unsigned char *data; /* Memory mapped or malloc'ed file */ size_t length; /* Length of memory mapped file */ - unsigned char *tofree; /* Non-NULL if malloc'ed file */ + void *tofree; /* Non-NULL if malloc'ed file */ size_t nfiles; /* Number of files in archive */ size_t baseoffs; /* Archive start */ size_t baseoffsp; /* Password start */ size_t centoffs; /* Archive directory start */ unsigned char pwbuf[264]; /* Password buffer */ -#if defined(_WIN32) || defined(_WIN64) - HANDLE mh; -#endif size_t nopen; /* Number of open files on archive */ struct ZipEntry *entries; /* List of files in archive */ struct ZipEntry *topents; /* List of top-level dirs in archive */ -#if HAS_DRIVES - int mntdrv; /* Drive letter of mount point */ -#endif size_t mntptlen; char *mntpt; /* Mount point */ +#ifdef _WIN32 + HANDLE mh; + int mntdrv; /* Drive letter of mount point */ +#endif } ZipFile; /* @@ -516,7 +511,7 @@ ToDosTime(time_t when) struct tm *tmp, tm; #ifdef TCL_THREADS -#if defined(_WIN32) || defined(_WIN64) +#ifdef _WIN32 /* Win32 uses thread local storage */ tmp = localtime(&when); tm = *tmp; @@ -544,7 +539,7 @@ ToDosDate(time_t when) struct tm *tmp, tm; #ifdef TCL_THREADS -#if defined(_WIN32) || defined(_WIN64) +#ifdef _WIN32 /* Win32 uses thread local storage */ tmp = localtime(&when); tm = *tmp; @@ -621,7 +616,7 @@ CanonicalPath(const char *root, const char *tail, Tcl_DString *dsPtr,int ZIPFSPA char *path; char *result; int i, j, c, isunc = 0, isvfs=0, n=0; -#if HAS_DRIVES +#ifdef _WIN32 int zipfspath=1; if ( (tail[0] != '\0') @@ -655,7 +650,7 @@ CanonicalPath(const char *root, const char *tail, Tcl_DString *dsPtr,int ZIPFSPA isunc = 1; } } -#if HAS_DRIVES +#ifdef _WIN32 } #endif if(isvfs!=2) { @@ -707,7 +702,7 @@ CanonicalPath(const char *root, const char *tail, Tcl_DString *dsPtr,int ZIPFSPA memcpy(path + i, tail, j); } } -#if HAS_DRIVES +#ifdef _WIN32 for (i = 0; path[i] != '\0'; i++) { if (path[i] == '\\') { path[i] = '/'; @@ -857,13 +852,13 @@ ZipFSCloseArchive(Tcl_Interp *interp, ZipFile *zf) if(zf->is_membuf==1) { /* Pointer to memory */ if (zf->tofree != NULL) { - Tcl_Free((char *) zf->tofree); + Tcl_Free(zf->tofree); zf->tofree = NULL; } zf->data = NULL; return; } -#if defined(_WIN32) || defined(_WIN64) +#ifdef _WIN32 if ((zf->data != NULL) && (zf->tofree == NULL)) { UnmapViewOfFile(zf->data); zf->data = NULL; @@ -878,7 +873,7 @@ ZipFSCloseArchive(Tcl_Interp *interp, ZipFile *zf) } #endif if (zf->tofree != NULL) { - Tcl_Free((char *) zf->tofree); + Tcl_Free(zf->tofree); zf->tofree = NULL; } if(zf->chan != NULL) { @@ -1016,7 +1011,7 @@ ZipFSOpenArchive(Tcl_Interp *interp, const char *zipname, int needZip, ZipFile * ClientData handle; zf->namelen=0; zf->is_membuf=0; -#if defined(_WIN32) || defined(_WIN64) +#ifdef _WIN32 zf->data = NULL; zf->mh = INVALID_HANDLE_VALUE; #else @@ -1057,7 +1052,7 @@ ZipFSOpenArchive(Tcl_Interp *interp, const char *zipname, int needZip, ZipFile * Tcl_Close(interp, zf->chan); zf->chan = NULL; } else { -#if defined(_WIN32) || defined(_WIN64) +#ifdef _WIN32 # ifdef _WIN64 i = GetFileSizeEx((HANDLE) handle, (PLARGE_INTEGER)&zf->length); if ( @@ -1919,8 +1914,8 @@ ZipAddFile( ZipEntry *z; z_stream stream; const char *zpath; - int crc, flush, zpathlen, olen; - size_t nbyte, nbytecompr, len, align = 0; + int crc, flush, zpathlen; + size_t nbyte, nbytecompr, len, olen, align = 0; Tcl_WideInt pos[3]; int mtime = 0, isNew, cmeth; unsigned long keys[3], keys0[3]; @@ -1944,7 +1939,7 @@ ZipAddFile( || (Tcl_SetChannelOption(interp, in, "-translation", "binary") != TCL_OK) || (Tcl_SetChannelOption(interp, in, "-encoding", "binary") != TCL_OK) ) { -#if defined(_WIN32) || defined(_WIN64) +#ifdef _WIN32 /* hopefully a directory */ if (strcmp("permission denied", Tcl_PosixError(interp)) == 0) { Tcl_Close(interp, in); @@ -2088,13 +2083,14 @@ wrerr: } olen = sizeof (obuf) - stream.avail_out; if (passwd != NULL) { - int i, tmp; + size_t i; + int tmp; for (i = 0; i < olen; i++) { obuf[i] = (char) zencode(keys, crc32tab, obuf[i], tmp); } } - if (olen && (Tcl_Write(out, obuf, olen) != olen)) { + if (olen && ((size_t)Tcl_Write(out, obuf, olen) != olen)) { Tcl_AppendResult(interp, "write error", (char *) NULL); deflateEnd(&stream); Tcl_Close(interp, in); @@ -2873,7 +2869,7 @@ ZipFSListObjCmd( return TCL_OK; } -#if defined(_WIN32) || defined(_WIN64) +#ifdef _WIN32 #define LIBRARY_SIZE 64 static int ToUtf( @@ -2898,7 +2894,7 @@ Tcl_Obj *TclZipfs_TclLibrary(void) { } else { Tcl_Obj *vfsinitscript; int found=0; -#if defined(_WIN32) || defined(_WIN64) +#ifdef _WIN32 HMODULE hModule = TclWinGetTclInstance(); WCHAR wName[MAX_PATH + LIBRARY_SIZE]; char dllname[(MAX_PATH + LIBRARY_SIZE) * TCL_UTF_MAX]; @@ -2912,7 +2908,7 @@ Tcl_Obj *TclZipfs_TclLibrary(void) { zipfs_literal_tcl_library=ZIPFS_APP_MOUNT "/tcl_library"; return Tcl_NewStringObj(zipfs_literal_tcl_library,-1); } -#if defined(_WIN32) || defined(_WIN64) +#ifdef _WIN32 if (GetModuleFileNameW(hModule, wName, MAX_PATH) == 0) { GetModuleFileNameA(hModule, dllname, MAX_PATH); } else { @@ -4401,12 +4397,15 @@ static int TclZipfs_AppHook_FindTclInit(const char *archive){ return TCL_ERROR; } -#if defined(_WIN32) || defined(_WIN64) +#ifdef _WIN32 int TclZipfs_AppHook(int *argc, TCHAR ***argv) #else int TclZipfs_AppHook(int *argc, char ***argv) #endif { +#ifdef _WIN32 + Tcl_DString ds; +#endif /* * Tclkit_MainHook -- * Performs the argument munging for the shell @@ -4442,14 +4441,13 @@ int TclZipfs_AppHook(int *argc, char ***argv) } } } else if (*argc>1) { -#if defined(_WIN32) || defined(_WIN64) - Tcl_DString ds; - strcpy(archive, Tcl_WinTCharToUtf((*argv)[1], -1, &ds)); - Tcl_DStringFree(&ds); + return TCL_OK; +#ifdef _WIN32 + archive = Tcl_WinTCharToUtf((*argv)[1], -1, &ds); #else archive=(*argv)[1]; #endif - if(strcmp(archive,"install")==0) { + if (strcmp(archive,"install")==0) { /* If the first argument is mkzip, run the mkzip program */ Tcl_Obj *vfsinitscript; /* Run this now to ensure the file is present by the time Tcl_Main wants it */ @@ -4483,10 +4481,12 @@ int TclZipfs_AppHook(int *argc, char ***argv) } } } +#ifdef _WIN32 + Tcl_DStringFree(&ds); +#endif } return TCL_OK; } - #ifndef HAVE_ZLIB diff --git a/win/tclAppInit.c b/win/tclAppInit.c index 6d2bda4..6444b21 100644 --- a/win/tclAppInit.c +++ b/win/tclAppInit.c @@ -126,7 +126,8 @@ _tmain( #ifdef TCL_LOCAL_MAIN_HOOK TCL_LOCAL_MAIN_HOOK(&argc, &argv); -#else +#elif !defined(_WIN32) && !defined(UNICODE) + /* This doesn't work on Windows without UNICODE */ TclZipfs_AppHook(&argc, &argv); #endif -- cgit v0.12 From bf46b6a1dac0ded399af13fb18a2cfa7cec8caea Mon Sep 17 00:00:00 2001 From: dkf Date: Thu, 27 Sep 2018 07:44:50 +0000 Subject: Updated documentation --- doc/lreplace.n | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/doc/lreplace.n b/doc/lreplace.n index d19f0cd..35a9130 100644 --- a/doc/lreplace.n +++ b/doc/lreplace.n @@ -30,13 +30,26 @@ list, and \fBend\fR refers to the last element of the list. If \fIlist\fR is empty, then \fIfirst\fR and \fIlast\fR are ignored. .PP If \fIfirst\fR is less than zero, it is considered to refer to before the -first element of the list. For non-empty lists, the element indicated -by \fIfirst\fR must exist or \fIfirst\fR must indicate before the +first element of the list. +.VS TIP505 +If \fIfirst\fR indicates a position greater than the index of the last element +of the list, it is treated as if it is an index one greater than the last +element. This allows this command to append elements to the list. +.VE TIP505 +For non-empty lists, the element indicated +by \fIfirst\fR must exist, or \fIfirst\fR must indicate before the start of the list. .PP If \fIlast\fR is less than \fIfirst\fR, then any specified elements will be inserted into the list before the point specified by \fIfirst\fR with no elements being deleted. +.VS TIP505 +If \fIlast\fR is greater than the index of the last item of the list, it is +treated as if it is an index one greater than the last element. This means +that if it is also greater than than \fIfirst\fR, all elements from +\fIfirst\fR to the end of the list will be replaced, and otherwise the +elements will be appended. +.VE TIP505 .PP The \fIelement\fR arguments specify zero or more new arguments to be added to the list in place of those that were deleted. @@ -78,9 +91,26 @@ proc lremove {listVariable value} { set var [\fBlreplace\fR $var $idx $idx] } .CE +.PP +.VS TIP505 +Adding elements to the end of the list; note that \fBend+2\fR will initially +be treated as if it is \fB6\fR here, but both that and \fB12345\fR are greater +than the index of the final item so they behave identically: +.PP +.CS +% set var {a b c d e} +a b c d e +% set var [\fBlreplace\fR $var 12345 end+2 f g h i] +a b c d e f g h i +.CE +.VE TIP505 .SH "SEE ALSO" list(n), lappend(n), lindex(n), linsert(n), llength(n), lsearch(n), lset(n), lrange(n), lsort(n), string(n) .SH KEYWORDS element, list, replace +.\" Local variables: +.\" mode: nroff +.\" fill-column: 78 +.\" End: -- cgit v0.12 From 6ec7c04557d86c9e5ddec92b3594634dba89e007 Mon Sep 17 00:00:00 2001 From: dkf Date: Thu, 27 Sep 2018 11:06:59 +0000 Subject: Restricted the information made available to safe interpreters a bit. --- doc/info.n | 8 +++-- generic/tclBasic.c | 1 + generic/tclCmdIL.c | 16 ++++++++-- generic/tclInt.h | 1 + generic/tclInterp.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++++---- tests/info.test | 43 +++++++++++++++++++++++++++ 6 files changed, 142 insertions(+), 11 deletions(-) diff --git a/doc/info.n b/doc/info.n index 99d11d5..5732a13 100644 --- a/doc/info.n +++ b/doc/info.n @@ -45,12 +45,14 @@ Returns a count of the total number of commands that have been invoked in this interpreter. .TP \fBinfo cmdtype \fIcommandName\fR -.VS "info cmdtype feature" +.VS TIP426 Returns a description of the kind of command named by \fIcommandName\fR. The supported types are: .RS .IP \fBalias\fR -Indicates that \fIcommandName\fR was created by \fBinterp alias\fR. +Indicates that \fIcommandName\fR was created by \fBinterp alias\fR. Note that +safe interpreters can only see a subset of aliases (specifically those between +two commands within themselves). .IP \fBcoroutine\fR Indicates that \fIcommandName\fR was created by \fBcoroutine\fR. .IP \fBensemble\fR @@ -76,7 +78,7 @@ Indicates that \fIcommandName\fR was created by \fBzlib stream\fR. There may be other registered types as well; this is a set that is extensible at the implementation level with \fBTcl_RegisterCommandTypeName\fR. .RE -.VE "info cmdtype feature" +.VE TIP426 .TP \fBinfo commands \fR?\fIpattern\fR? . diff --git a/generic/tclBasic.c b/generic/tclBasic.c index 37f0560..da43a5d 100644 --- a/generic/tclBasic.c +++ b/generic/tclBasic.c @@ -530,6 +530,7 @@ Tcl_CreateInterp(void) TclRegisterCommandTypeName(TclObjInterpProc, "proc"); TclRegisterCommandTypeName(TclEnsembleImplementationCmd, "ensemble"); TclRegisterCommandTypeName(TclAliasObjCmd, "alias"); + TclRegisterCommandTypeName(TclLocalAliasObjCmd, "alias"); TclRegisterCommandTypeName(TclSlaveObjCmd, "slave"); TclRegisterCommandTypeName(TclInvokeImportedCmd, "import"); TclRegisterCommandTypeName(TclOOPublicObjectCmd, "object"); diff --git a/generic/tclCmdIL.c b/generic/tclCmdIL.c index 8454db1..1dae740 100644 --- a/generic/tclCmdIL.c +++ b/generic/tclCmdIL.c @@ -158,7 +158,7 @@ static const EnsembleImplMap defaultInfoMap[] = { {"args", InfoArgsCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0}, {"body", InfoBodyCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0}, {"cmdcount", InfoCmdCountCmd, TclCompileBasic0ArgCmd, NULL, NULL, 0}, - {"cmdtype", InfoCmdTypeCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0}, + {"cmdtype", InfoCmdTypeCmd, TclCompileBasic1ArgCmd, NULL, NULL, 1}, {"commands", InfoCommandsCmd, TclCompileInfoCommandsCmd, NULL, NULL, 0}, {"complete", InfoCompleteCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0}, {"coroutine", TclInfoCoroutineCmd, TclCompileInfoCoroutineCmd, NULL, NULL, 0}, @@ -2171,8 +2171,18 @@ InfoCmdTypeCmd( return TCL_ERROR; } - Tcl_SetObjResult(interp, - Tcl_NewStringObj(TclGetCommandTypeName(command), -1)); + /* + * There's one special case: safe slave interpreters can't see aliases as + * aliases as they're part of the security mechanisms. + */ + + if (Tcl_IsSafe(interp) + && (((Command *) command)->objProc == TclAliasObjCmd)) { + Tcl_AppendResult(interp, "native", NULL); + } else { + Tcl_SetObjResult(interp, + Tcl_NewStringObj(TclGetCommandTypeName(command), -1)); + } return TCL_OK; } diff --git a/generic/tclInt.h b/generic/tclInt.h index 19f9d0e..4a1b459 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -4123,6 +4123,7 @@ MODULE_SCOPE int TclFullFinalizationRequested(void); MODULE_SCOPE Tcl_ObjCmdProc TclEnsembleImplementationCmd; MODULE_SCOPE Tcl_ObjCmdProc TclAliasObjCmd; +MODULE_SCOPE Tcl_ObjCmdProc TclLocalAliasObjCmd; MODULE_SCOPE Tcl_ObjCmdProc TclSlaveObjCmd; MODULE_SCOPE Tcl_ObjCmdProc TclInvokeImportedCmd; MODULE_SCOPE Tcl_ObjCmdProc TclOOPublicObjectCmd; diff --git a/generic/tclInterp.c b/generic/tclInterp.c index 08cbef8..550e2fe 100644 --- a/generic/tclInterp.c +++ b/generic/tclInterp.c @@ -1414,7 +1414,8 @@ TclPreventAliasLoop( * create or rename the command. */ - if (cmdPtr->objProc != TclAliasObjCmd) { + if (cmdPtr->objProc != TclAliasObjCmd + && cmdPtr->objProc != TclLocalAliasObjCmd) { return TCL_OK; } @@ -1469,7 +1470,8 @@ TclPreventAliasLoop( * Otherwise we do not have a loop. */ - if (aliasCmdPtr->objProc != TclAliasObjCmd) { + if (aliasCmdPtr->objProc != TclAliasObjCmd + && aliasCmdPtr->objProc != TclLocalAliasObjCmd) { return TCL_OK; } nextAliasPtr = aliasCmdPtr->objClientData; @@ -1535,8 +1537,8 @@ AliasCreate( if (slaveInterp == masterInterp) { aliasPtr->slaveCmd = Tcl_NRCreateCommand(slaveInterp, - TclGetString(namePtr), TclAliasObjCmd, AliasNRCmd, aliasPtr, - AliasObjCmdDeleteProc); + TclGetString(namePtr), TclLocalAliasObjCmd, AliasNRCmd, + aliasPtr, AliasObjCmdDeleteProc); } else { aliasPtr->slaveCmd = Tcl_CreateObjCommand(slaveInterp, TclGetString(namePtr), TclAliasObjCmd, aliasPtr, @@ -1776,7 +1778,7 @@ AliasList( /* *---------------------------------------------------------------------- * - * TclAliasObjCmd -- + * TclAliasObjCmd, TclLocalAliasObjCmd -- * * This is the function that services invocations of aliases in a slave * interpreter. One such command exists for each alias. When invoked, @@ -1784,6 +1786,11 @@ AliasList( * master interpreter as designated by the Alias record associated with * this command. * + * TclLocalAliasObjCmd is a stripped down version used when the source + * and target interpreters of the alias are the same. That lets a number + * of safety precautions be avoided: the state is much more precisely + * known. + * * Results: * A standard Tcl result. * @@ -1933,6 +1940,73 @@ TclAliasObjCmd( return result; #undef ALIAS_CMDV_PREALLOC } + +int +TclLocalAliasObjCmd( + ClientData clientData, /* Alias record. */ + Tcl_Interp *interp, /* Current interpreter. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument vector. */ +{ +#define ALIAS_CMDV_PREALLOC 10 + Alias *aliasPtr = clientData; + int result, prefc, cmdc, i; + Tcl_Obj **prefv, **cmdv; + Tcl_Obj *cmdArr[ALIAS_CMDV_PREALLOC]; + Interp *iPtr = (Interp *) interp; + int isRootEnsemble; + + /* + * Append the arguments to the command prefix and invoke the command in + * the global namespace. + */ + + prefc = aliasPtr->objc; + prefv = &aliasPtr->objPtr; + cmdc = prefc + objc - 1; + if (cmdc <= ALIAS_CMDV_PREALLOC) { + cmdv = cmdArr; + } else { + cmdv = TclStackAlloc(interp, cmdc * sizeof(Tcl_Obj *)); + } + + memcpy(cmdv, prefv, (size_t) (prefc * sizeof(Tcl_Obj *))); + memcpy(cmdv+prefc, objv+1, (size_t) ((objc-1) * sizeof(Tcl_Obj *))); + + for (i=0; i Date: Fri, 28 Sep 2018 07:24:59 +0000 Subject: Fix minor typo --- generic/tclOODefineCmds.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generic/tclOODefineCmds.c b/generic/tclOODefineCmds.c index b68cb0c..17680a0 100644 --- a/generic/tclOODefineCmds.c +++ b/generic/tclOODefineCmds.c @@ -46,7 +46,7 @@ struct DeclaredSlot { getter, NULL, NULL}, \ {TCL_OO_METHOD_VERSION_CURRENT, "core method: " name " Setter", \ setter, NULL, NULL}, \ - {TCL_OO_METHOD_VERSION_CURRENT, "core method: " name " Setter", \ + {TCL_OO_METHOD_VERSION_CURRENT, "core method: " name " Resolver", \ resolver, NULL, NULL}} /* -- cgit v0.12 From eede8c60a140b1ebb3eb6a795ecc703e89f466f4 Mon Sep 17 00:00:00 2001 From: dkf Date: Fri, 28 Sep 2018 09:49:57 +0000 Subject: Clean up code style and add key phrases to documentation. --- doc/Thread.3 | 10 +++- unix/tclUnixThrd.c | 147 ++++++++++++++++++++++++++++++++++------------------- 2 files changed, 103 insertions(+), 54 deletions(-) diff --git a/doc/Thread.3 b/doc/Thread.3 index 5966a71..59bf488 100644 --- a/doc/Thread.3 +++ b/doc/Thread.3 @@ -45,7 +45,9 @@ int .AP Tcl_Condition *condPtr in A condition variable, which must be associated with a mutex lock. .AP Tcl_Mutex *mutexPtr in -A mutex lock. +.VS TIP509 +A recursive mutex lock. +.VE TIP509 .AP "const Tcl_Time" *timePtr in A time limit on the condition wait. NULL to wait forever. Note that a polling value of 0 seconds does not make much sense. @@ -135,7 +137,11 @@ Tcl provides \fBTcl_ThreadQueueEvent\fR and \fBTcl_ThreadAlert\fR for handling event queuing in multithreaded applications. See the \fBNotifier\fR manual page for more information on these procedures. .PP -A mutex is a lock that is used to serialize all threads through a piece +A mutex is a +.VS TIP509 +recursive +.VE TIP509 +lock that is used to serialize all threads through a piece of code by calling \fBTcl_MutexLock\fR and \fBTcl_MutexUnlock\fR. If one thread holds a mutex, any other thread calling \fBTcl_MutexLock\fR will block until \fBTcl_MutexUnlock\fR is called. diff --git a/unix/tclUnixThrd.c b/unix/tclUnixThrd.c index 925f8b8..60340b0 100644 --- a/unix/tclUnixThrd.c +++ b/unix/tclUnixThrd.c @@ -14,37 +14,83 @@ #include "tclInt.h" #if TCL_THREADS - + /* - * TIP #509. + * TIP #509. Ensures that Tcl's mutexes are reentrant. + * + *---------------------------------------------------------------------- + * + * PMutexInit -- + * + * Sets up the memory pointed to by its argument so that it contains the + * implementation of a recursive lock. Caller supplies the space. + * + *---------------------------------------------------------------------- + * + * PMutexDestroy -- + * + * Tears down the implementation of a recursive lock (but does not + * deallocate the space holding the lock). + * + *---------------------------------------------------------------------- + * + * PMutexLock -- + * + * Locks a recursive lock. (Similar to pthread_mutex_lock) + * + *---------------------------------------------------------------------- + * + * PMutexUnlock -- + * + * Unlocks a recursive lock. (Similar to pthread_mutex_unlock) + * + *---------------------------------------------------------------------- + * + * PCondWait -- + * + * Waits on a condition variable linked a recursive lock. (Similar to + * pthread_cond_wait) + * + *---------------------------------------------------------------------- + * + * PCondTimedWait -- + * + * Waits for a limited amount of time on a condition variable linked to a + * recursive lock. (Similar to pthread_cond_timedwait) + * + *---------------------------------------------------------------------- */ -#if defined(HAVE_DECL_PTHREAD_MUTEX_RECURSIVE) \ - && HAVE_DECL_PTHREAD_MUTEX_RECURSIVE +#ifndef HAVE_DECL_PTHREAD_MUTEX_RECURSIVE +#define HAVE_DECL_PTHREAD_MUTEX_RECURSIVE 0 +#endif + +#if HAVE_DECL_PTHREAD_MUTEX_RECURSIVE /* - * Pthread has native reentrant (AKA recursive) mutexes. Use them for Tcl_Mutex. + * Pthread has native reentrant (AKA recursive) mutexes. Use them for + * Tcl_Mutex. */ typedef pthread_mutex_t PMutex; static void PMutexInit( - PMutex *pmutexPtr -) + PMutex *pmutexPtr) { pthread_mutexattr_t attr; + pthread_mutexattr_init(&attr); pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); pthread_mutex_init(pmutexPtr, &attr); } -#define PMutexDestroy pthread_mutex_destroy -#define PMutexLock pthread_mutex_lock -#define PMutexUnlock pthread_mutex_unlock -#define PCondWait pthread_cond_wait -#define PCondTimedWait pthread_cond_timedwait +#define PMutexDestroy pthread_mutex_destroy +#define PMutexLock pthread_mutex_lock +#define PMutexUnlock pthread_mutex_unlock +#define PCondWait pthread_cond_wait +#define PCondTimedWait pthread_cond_timedwait -#else /* HAVE_PTHREAD_MUTEX_RECURSIVE */ +#else /* !HAVE_PTHREAD_MUTEX_RECURSIVE */ /* * No native support for reentrant mutexes. Emulate them with regular mutexes @@ -59,8 +105,7 @@ typedef struct PMutex { static void PMutexInit( - PMutex *pmutexPtr -) + PMutex *pmutexPtr) { pthread_mutex_init(&pmutexPtr->mutex, NULL); pmutexPtr->thread = 0; @@ -69,42 +114,38 @@ PMutexInit( static void PMutexDestroy( - PMutex *pmutexPtr -) + PMutex *pmutexPtr) { - pthread_mutex_destroy(&pmutexPtr->mutex); + pthread_mutex_destroy(&pmutexPtr->mutex); } static void PMutexLock( - PMutex *pmutexPtr -) + PMutex *pmutexPtr) { if (pmutexPtr->thread != pthread_self() || pmutexPtr->counter == 0) { - pthread_mutex_lock(&pmutexPtr->mutex); - pmutexPtr->thread = pthread_self(); - pmutexPtr->counter = 0; + pthread_mutex_lock(&pmutexPtr->mutex); + pmutexPtr->thread = pthread_self(); + pmutexPtr->counter = 0; } pmutexPtr->counter++; } static void PMutexUnlock( - PMutex *pmutexPtr -) + PMutex *pmutexPtr) { pmutexPtr->counter--; if (pmutexPtr->counter == 0) { - pmutexPtr->thread = 0; - pthread_mutex_unlock(&pmutexPtr->mutex); + pmutexPtr->thread = 0; + pthread_mutex_unlock(&pmutexPtr->mutex); } } static void PCondWait( pthread_cond_t *pcondPtr, - PMutex *pmutexPtr -) + PMutex *pmutexPtr) { pthread_cond_wait(pcondPtr, &pmutexPtr->mutex); } @@ -113,20 +154,19 @@ static void PCondTimedWait( pthread_cond_t *pcondPtr, PMutex *pmutexPtr, - struct timespec *ptime -) + struct timespec *ptime) { pthread_cond_timedwait(pcondPtr, &pmutexPtr->mutex, ptime); } #endif /* HAVE_PTHREAD_MUTEX_RECURSIVE */ - + #ifndef TCL_NO_DEPRECATED typedef struct { char nabuf[16]; } ThreadSpecificData; static Tcl_ThreadDataKey dataKey; -#endif +#endif /* TCL_NO_DEPRECATED */ /* * masterLock is used to serialize creation of mutexes, condition variables, @@ -150,8 +190,9 @@ static pthread_mutex_t initLock = PTHREAD_MUTEX_INITIALIZER; static PMutex allocLock; static pthread_once_t allocLockInitOnce = PTHREAD_ONCE_INIT; + static void -allocLockInit() +allocLockInit(void) { PMutexInit(&allocLock); } @@ -220,17 +261,17 @@ TclpThreadCreate( } #endif /* HAVE_PTHREAD_ATTR_SETSTACKSIZE */ - if (! (flags & TCL_THREAD_JOINABLE)) { - pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED); + if (!(flags & TCL_THREAD_JOINABLE)) { + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); } if (pthread_create(&theThread, &attr, - (void * (*)(void *))proc, (void *)clientData) && + (void * (*)(void *)) proc, (void *) clientData) && pthread_create(&theThread, NULL, - (void * (*)(void *))proc, (void *)clientData)) { + (void * (*)(void *)) proc, (void *) clientData)) { result = TCL_ERROR; } else { - *idPtr = (Tcl_ThreadId)theThread; + *idPtr = (Tcl_ThreadId) theThread; result = TCL_OK; } pthread_attr_destroy(&attr); @@ -442,7 +483,6 @@ TclpMasterLock(void) pthread_mutex_lock(&masterLock); #endif } - /* *---------------------------------------------------------------------- @@ -493,6 +533,7 @@ Tcl_GetAllocMutex(void) { #if TCL_THREADS PMutex **allocLockPtrPtr = &allocLockPtr; + pthread_once(&allocLockInitOnce, allocLockInit); return (Tcl_Mutex *) allocLockPtrPtr; #else @@ -538,12 +579,12 @@ Tcl_MutexLock( pmutexPtr = ckalloc(sizeof(PMutex)); PMutexInit(pmutexPtr); - *mutexPtr = (Tcl_Mutex)pmutexPtr; + *mutexPtr = (Tcl_Mutex) pmutexPtr; TclRememberMutex(mutexPtr); } pthread_mutex_unlock(&masterLock); } - pmutexPtr = *((PMutex **)mutexPtr); + pmutexPtr = *((PMutex **) mutexPtr); PMutexLock(pmutexPtr); } @@ -653,8 +694,8 @@ Tcl_ConditionWait( } pthread_mutex_unlock(&masterLock); } - pmutexPtr = *((PMutex **)mutexPtr); - pcondPtr = *((pthread_cond_t **)condPtr); + pmutexPtr = *((PMutex **) mutexPtr); + pcondPtr = *((pthread_cond_t **) condPtr); if (timePtr == NULL) { PCondWait(pcondPtr, pmutexPtr); } else { @@ -696,12 +737,13 @@ void Tcl_ConditionNotify( Tcl_Condition *condPtr) { - pthread_cond_t *pcondPtr = *((pthread_cond_t **)condPtr); + pthread_cond_t *pcondPtr = *((pthread_cond_t **) condPtr); + if (pcondPtr != NULL) { pthread_cond_broadcast(pcondPtr); } else { /* - * Noone has used the condition variable, so there are no waiters. + * No-one has used the condition variable, so there are no waiters. */ } } @@ -729,7 +771,7 @@ void TclpFinalizeCondition( Tcl_Condition *condPtr) { - pthread_cond_t *pcondPtr = *(pthread_cond_t **)condPtr; + pthread_cond_t *pcondPtr = *(pthread_cond_t **) condPtr; if (pcondPtr != NULL) { pthread_cond_destroy(pcondPtr); @@ -796,15 +838,15 @@ static pthread_key_t key; typedef struct { Tcl_Mutex tlock; PMutex plock; -} allocMutex; +} AllocMutex; Tcl_Mutex * TclpNewAllocMutex(void) { - allocMutex *lockPtr; + AllocMutex *lockPtr; register PMutex *plockPtr; - lockPtr = malloc(sizeof(allocMutex)); + lockPtr = malloc(sizeof(AllocMutex)); if (lockPtr == NULL) { Tcl_Panic("could not allocate lock"); } @@ -818,7 +860,8 @@ void TclpFreeAllocMutex( Tcl_Mutex *mutex) /* The alloc mutex to free. */ { - allocMutex* lockPtr = (allocMutex*) mutex; + AllocMutex *lockPtr = (AllocMutex *) mutex; + if (!lockPtr) { return; } @@ -874,7 +917,7 @@ TclpThreadCreateKey(void) { pthread_key_t *ptkeyPtr; - ptkeyPtr = TclpSysAlloc(sizeof *ptkeyPtr, 0); + ptkeyPtr = TclpSysAlloc(sizeof(pthread_key_t), 0); if (NULL == ptkeyPtr) { Tcl_Panic("unable to allocate thread key!"); } -- cgit v0.12 From fd03d49b6f80c194e041a4c2d1364b4f46d59ff3 Mon Sep 17 00:00:00 2001 From: dkf Date: Fri, 28 Sep 2018 09:54:24 +0000 Subject: Better phrasing from TIP 509 --- doc/Thread.3 | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/doc/Thread.3 b/doc/Thread.3 index 59bf488..2005c93 100644 --- a/doc/Thread.3 +++ b/doc/Thread.3 @@ -137,17 +137,17 @@ Tcl provides \fBTcl_ThreadQueueEvent\fR and \fBTcl_ThreadAlert\fR for handling event queuing in multithreaded applications. See the \fBNotifier\fR manual page for more information on these procedures. .PP -A mutex is a -.VS TIP509 -recursive -.VE TIP509 -lock that is used to serialize all threads through a piece +A mutex is a lock that is used to serialize all threads through a piece of code by calling \fBTcl_MutexLock\fR and \fBTcl_MutexUnlock\fR. If one thread holds a mutex, any other thread calling \fBTcl_MutexLock\fR will block until \fBTcl_MutexUnlock\fR is called. A mutex can be destroyed after its use by calling \fBTcl_MutexFinalize\fR. -The result of locking a mutex twice from the same thread is undefined. -On some platforms it will result in a deadlock. +.VS TIP509 +Mutexes are reentrant: they can be locked several times from the same +thread. However there must be exactly one call to +\fBTcl_MutexUnlock\fR for each call to \fBTcl_MutexLock\fR in order +for a thread to release a mutex completely. +.VE TIP509 The \fBTcl_MutexLock\fR, \fBTcl_MutexUnlock\fR and \fBTcl_MutexFinalize\fR procedures are defined as empty macros if not compiling with threads enabled. For declaration of mutexes the \fBTCL_DECLARE_MUTEX\fR macro should be used. -- cgit v0.12 From 4ee2aeb33dcb6c3677a692158ee7d3f7192a735d Mon Sep 17 00:00:00 2001 From: dkf Date: Fri, 28 Sep 2018 13:59:19 +0000 Subject: Small fixes to unix makefile --- unix/Makefile.in | 299 +++++++++++++++++++++++++++---------------------------- 1 file changed, 144 insertions(+), 155 deletions(-) diff --git a/unix/Makefile.in b/unix/Makefile.in index 95e7b80..2432ad5 100644 --- a/unix/Makefile.in +++ b/unix/Makefile.in @@ -83,7 +83,7 @@ HTML_INSTALL_DIR = $(INSTALL_ROOT)$(HTML_DIR) CONFIG_INSTALL_DIR = $(INSTALL_ROOT)$(libdir) # Directory in which to install bundled packages: -PACKAGE_DIR = @PACKAGE_DIR@ +PACKAGE_DIR = @PACKAGE_DIR@ # Package search path. TCL_PACKAGE_PATH = @TCL_PACKAGE_PATH@ @@ -151,8 +151,8 @@ SHELL = @MAKEFILE_SHELL@ # around; better to use the install-sh script that comes with the # distribution, which is slower but guaranteed to work. -INSTALL_STRIP_PROGRAM = -s -INSTALL_STRIP_LIBRARY = -S -x +INSTALL_STRIP_PROGRAM = -s +INSTALL_STRIP_LIBRARY = -S -x INSTALL = $(SHELL) $(UNIX_DIR)/install-sh -c INSTALL_PROGRAM = ${INSTALL} @@ -242,13 +242,13 @@ ZLIB_DIR = ${COMPAT_DIR}/zlib ZLIB_INCLUDE = @ZLIB_INCLUDE@ CC = @CC@ -OBJEXT = @OBJEXT@ +OBJEXT = @OBJEXT@ #CC = purify -best-effort @CC@ -DPURIFY # Flags to be passed to installManPage to control how the manpages should be # installed (symlinks, compression, package name suffix). -MAN_FLAGS = @MAN_FLAGS@ +MAN_FLAGS = @MAN_FLAGS@ # If non-empty, install the timezone files that are included with Tcl, # otherwise use the ones that ship with the OS. @@ -266,8 +266,8 @@ TRACE = strace TRACE_OPTS = VALGRIND = valgrind VALGRINDARGS = --tool=memcheck --num-callers=24 \ - --leak-resolution=high --leak-check=yes --show-reachable=yes -v \ - --suppressions=$(TOOL_DIR)/valgrind_suppress + --leak-resolution=high --leak-check=yes --show-reachable=yes -v \ + --suppressions=$(TOOL_DIR)/valgrind_suppress #-------------------------------------------------------------------------- # The information below should be usable as is. The configure script won't @@ -275,8 +275,9 @@ VALGRINDARGS = --tool=memcheck --num-callers=24 \ #-------------------------------------------------------------------------- STUB_CC_SWITCHES = ${CFLAGS} ${CFLAGS_WARNING} ${SHLIB_CFLAGS} \ --I"${BUILD_DIR}" -I${UNIX_DIR} -I${GENERIC_DIR} -I${TOMMATH_DIR} \ -${AC_FLAGS} ${PROTO_FLAGS} ${ENV_FLAGS} ${EXTRA_CFLAGS} @EXTRA_CC_SWITCHES@ + -I"${BUILD_DIR}" -I${UNIX_DIR} -I${GENERIC_DIR} -I${TOMMATH_DIR} \ + ${AC_FLAGS} ${PROTO_FLAGS} ${ENV_FLAGS} ${EXTRA_CFLAGS} \ + @EXTRA_CC_SWITCHES@ CC_SWITCHES = $(STUB_CC_SWITCHES) ${NO_DEPRECATED_FLAGS} @@ -285,7 +286,7 @@ APP_CC_SWITCHES = $(CC_SWITCHES) @EXTRA_APP_CC_SWITCHES@ LIBS = @TCL_LIBS@ DEPEND_SWITCHES = ${CFLAGS} -I${UNIX_DIR} -I${GENERIC_DIR} \ -${AC_FLAGS} ${PROTO_FLAGS} ${EXTRA_CFLAGS} @EXTRA_CC_SWITCHES@ + ${AC_FLAGS} ${PROTO_FLAGS} ${EXTRA_CFLAGS} @EXTRA_CC_SWITCHES@ TCLSH_OBJS = tclAppInit.o @@ -320,25 +321,26 @@ OO_OBJS = tclOO.o tclOOBasic.o tclOOCall.o tclOODefineCmds.o tclOOInfo.o \ TOMMATH_OBJS = bncore.o bn_reverse.o bn_fast_s_mp_mul_digs.o \ bn_fast_s_mp_sqr.o bn_mp_add.o bn_mp_and.o \ - bn_mp_add_d.o bn_mp_clamp.o bn_mp_clear.o bn_mp_clear_multi.o \ - bn_mp_cmp.o bn_mp_cmp_d.o bn_mp_cmp_mag.o \ + bn_mp_add_d.o bn_mp_clamp.o bn_mp_clear.o bn_mp_clear_multi.o \ + bn_mp_cmp.o bn_mp_cmp_d.o bn_mp_cmp_mag.o \ bn_mp_cnt_lsb.o bn_mp_copy.o \ bn_mp_count_bits.o bn_mp_div.o bn_mp_div_d.o bn_mp_div_2.o \ bn_mp_div_2d.o bn_mp_div_3.o \ - bn_mp_exch.o bn_mp_expt_d.o bn_mp_expt_d_ex.o bn_mp_get_int.o bn_mp_get_long.o bn_mp_get_long_long.o bn_mp_grow.o bn_mp_init.o \ + bn_mp_exch.o bn_mp_expt_d.o bn_mp_expt_d_ex.o bn_mp_get_int.o \ + bn_mp_get_long.o bn_mp_get_long_long.o bn_mp_grow.o bn_mp_init.o \ bn_mp_init_copy.o bn_mp_init_multi.o bn_mp_init_set.o \ bn_mp_init_set_int.o bn_mp_init_size.o bn_mp_karatsuba_mul.o \ bn_mp_karatsuba_sqr.o \ - bn_mp_lshd.o bn_mp_mod.o bn_mp_mod_2d.o bn_mp_mul.o bn_mp_mul_2.o \ - bn_mp_mul_2d.o bn_mp_mul_d.o bn_mp_neg.o bn_mp_or.o \ + bn_mp_lshd.o bn_mp_mod.o bn_mp_mod_2d.o bn_mp_mul.o bn_mp_mul_2.o \ + bn_mp_mul_2d.o bn_mp_mul_d.o bn_mp_neg.o bn_mp_or.o \ bn_mp_radix_size.o bn_mp_radix_smap.o \ - bn_mp_read_radix.o bn_mp_rshd.o bn_mp_set.o bn_mp_set_int.o \ + bn_mp_read_radix.o bn_mp_rshd.o bn_mp_set.o bn_mp_set_int.o \ bn_mp_set_long.o bn_mp_set_long_long.o bn_mp_shrink.o \ bn_mp_sqr.o bn_mp_sqrt.o bn_mp_sub.o bn_mp_sub_d.o \ - bn_mp_to_unsigned_bin.o bn_mp_to_unsigned_bin_n.o \ + bn_mp_to_unsigned_bin.o bn_mp_to_unsigned_bin_n.o \ bn_mp_toom_mul.o bn_mp_toom_sqr.o bn_mp_toradix_n.o \ bn_mp_unsigned_bin_size.o bn_mp_xor.o bn_mp_zero.o bn_s_mp_add.o \ - bn_s_mp_mul_digs.o bn_s_mp_sqr.o bn_s_mp_sub.o + bn_s_mp_mul_digs.o bn_s_mp_sqr.o bn_s_mp_sub.o STUB_LIB_OBJS = tclStubLib.o \ tclTomMathStubLib.o \ @@ -628,38 +630,38 @@ SRCS = $(GENERIC_SRCS) $(TOMMATH_SRCS) $(UNIX_SRCS) $(NOTIFY_SRCS) \ ### TCL_ZIP_FILE = @TCL_ZIP_FILE@ -TCL_VFS_PATH = libtcl.vfs/tcl_library TCL_VFS_ROOT = libtcl.vfs +TCL_VFS_PATH = ${TCL_VFS_ROOT}/tcl_library -HOST_CC = @CC_FOR_BUILD@ -HOST_EXEEXT = @EXEEXT_FOR_BUILD@ -HOST_OBJEXT = @OBJEXT_FOR_BUILD@ -ZIPFS_BUILD = @ZIPFS_BUILD@ +HOST_CC = @CC_FOR_BUILD@ +HOST_EXEEXT = @EXEEXT_FOR_BUILD@ +HOST_OBJEXT = @OBJEXT_FOR_BUILD@ +ZIPFS_BUILD = @ZIPFS_BUILD@ NATIVE_ZIP = @ZIP_PROG@ -ZIP_PROG_OPTIONS = @ZIP_PROG_OPTIONS@ -ZIP_PROG_VFSSEARCH = @ZIP_PROG_VFSSEARCH@ +ZIP_PROG_OPTIONS = @ZIP_PROG_OPTIONS@ +ZIP_PROG_VFSSEARCH = @ZIP_PROG_VFSSEARCH@ SHARED_BUILD = @SHARED_BUILD@ -INSTALL_LIBRARIES = @INSTALL_LIBRARIES@ -INSTALL_MSGS = @INSTALL_MSGS@ +INSTALL_LIBRARIES = @INSTALL_LIBRARIES@ +INSTALL_MSGS = @INSTALL_MSGS@ # Minizip MINIZIP_OBJS = \ - adler32.$(HOST_OBJEXT) \ - compress.$(HOST_OBJEXT) \ - crc32.$(HOST_OBJEXT) \ - deflate.$(HOST_OBJEXT) \ - infback.$(HOST_OBJEXT) \ - inffast.$(HOST_OBJEXT) \ - inflate.$(HOST_OBJEXT) \ - inftrees.$(HOST_OBJEXT) \ - ioapi.$(HOST_OBJEXT) \ - trees.$(HOST_OBJEXT) \ - uncompr.$(HOST_OBJEXT) \ - zip.$(HOST_OBJEXT) \ - zutil.$(HOST_OBJEXT) \ - minizip.$(HOST_OBJEXT) - -ZIP_INSTALL_OBJS = @ZIP_INSTALL_OBJS@ + adler32.$(HOST_OBJEXT) \ + compress.$(HOST_OBJEXT) \ + crc32.$(HOST_OBJEXT) \ + deflate.$(HOST_OBJEXT) \ + infback.$(HOST_OBJEXT) \ + inffast.$(HOST_OBJEXT) \ + inflate.$(HOST_OBJEXT) \ + inftrees.$(HOST_OBJEXT) \ + ioapi.$(HOST_OBJEXT) \ + trees.$(HOST_OBJEXT) \ + uncompr.$(HOST_OBJEXT) \ + zip.$(HOST_OBJEXT) \ + zutil.$(HOST_OBJEXT) \ + minizip.$(HOST_OBJEXT) + +ZIP_INSTALL_OBJS = @ZIP_INSTALL_OBJS@ #-------------------------------------------------------------------------- # Start of rules @@ -676,11 +678,11 @@ doc: tclzipfile: ${TCL_ZIP_FILE} -${TCL_ZIP_FILE}: ${ZIP_INSTALL_OBJS} +${TCL_ZIP_FILE}: ${ZIP_INSTALL_OBJS} rm -rf ${TCL_VFS_ROOT} mkdir -p ${TCL_VFS_PATH} cp -a $(TOP_DIR)/library/* ${TCL_VFS_PATH} - cd ${TCL_VFS_ROOT} ; ${NATIVE_ZIP} ${ZIP_PROG_OPTIONS} ../${TCL_ZIP_FILE} ${ZIP_PROG_VFSSEARCH} + (cd ${TCL_VFS_ROOT} ; ${NATIVE_ZIP} ${ZIP_PROG_OPTIONS} ../${TCL_ZIP_FILE} ${ZIP_PROG_VFSSEARCH}) # The following target is configured by autoconf to generate either a shared # library or non-shared library for Tcl. @@ -712,7 +714,7 @@ ${TCL_EXE}: ${TCLSH_OBJS} ${TCL_LIB_FILE} ${TCL_STUB_LIB_FILE} ${CC} ${CFLAGS} ${LDFLAGS} ${TCLSH_OBJS} \ @TCL_BUILD_LIB_SPEC@ ${TCL_STUB_LIB_FILE} ${LIBS} @EXTRA_TCLSH_LIBS@ \ ${CC_SEARCH_FLAGS} -o ${TCL_EXE} - cat ${TOOL_DIR}/empty.zip >> ${TCL_EXE} + cat ${TOOL_DIR}/empty.zip >> ${TCL_EXE} # Must be empty so it doesn't conflict with rule for ${TCL_EXE} above ${NATIVE_TCLSH}: @@ -726,12 +728,12 @@ clean: clean-packages rm -rf *.a *.o libtcl* core errs *~ \#* TAGS *.E a.out \ errors ${TCL_EXE} ${TCLTEST_EXE} lib.exp Tcl @DTRACE_HDR@ \ minizip${HOST_EXEEXT} *.${HOST_OBJEXT} *.zip *.vfs - cd dltest ; $(MAKE) clean + (cd dltest ; $(MAKE) clean) distclean: distclean-packages clean rm -rf Makefile config.status config.cache config.log tclConfig.sh \ tclConfig.h *.plist Tcl.framework tcl.pc - cd dltest ; $(MAKE) distclean + (cd dltest ; $(MAKE) distclean) depend: makedepend -- $(DEPEND_SWITCHES) -- $(SRCS) @@ -886,54 +888,44 @@ install-binaries: binaries @$(INSTALL_DATA) tcl.pc $(LIB_INSTALL_DIR)/pkgconfig/tcl.pc install-libraries-zipfs-shared: libraries - @for i in "$(SCRIPT_INSTALL_DIR)"; \ - do \ + @for i in "$(SCRIPT_INSTALL_DIR)"; do \ if [ ! -d "$$i" ] ; then \ echo "Making directory $$i"; \ $(INSTALL_DATA_DIR) "$$i"; \ - else true; \ - fi; \ - done; + fi; \ + done @echo "Installing library files to $(SCRIPT_INSTALL_DIR)/"; - @for i in \ - $(UNIX_DIR)/tclAppInit.c @LDAIX_SRC@ @DTRACE_SRC@; \ - do \ + @for i in $(UNIX_DIR)/tclAppInit.c @LDAIX_SRC@ @DTRACE_SRC@; do \ $(INSTALL_DATA) $$i "$(SCRIPT_INSTALL_DIR)"; \ - done; + done install-libraries-zipfs-static: install-libraries-zipfs-shared $(INSTALL_DATA) ${TCL_ZIP_FILE} "$(LIB_INSTALL_DIR)" ;\ install-libraries: libraries - @for i in "$(SCRIPT_INSTALL_DIR)"; \ - do \ + @for i in "$(SCRIPT_INSTALL_DIR)"; do \ if [ ! -d "$$i" ] ; then \ echo "Making directory $$i"; \ $(INSTALL_DATA_DIR) "$$i"; \ - else true; \ - fi; \ - done; - @for i in opt0.4 encoding ../tcl8 ../tcl8/8.4 ../tcl8/8.4/platform ../tcl8/8.5 ../tcl8/8.6 ../tcl8/8.7; \ - do \ + fi; \ + done + @for i in opt0.4 encoding ../tcl8 ../tcl8/8.4 ../tcl8/8.4/platform ../tcl8/8.5 ../tcl8/8.6 ../tcl8/8.7; do \ if [ ! -d "$(SCRIPT_INSTALL_DIR)"/$$i ] ; then \ echo "Making directory $(SCRIPT_INSTALL_DIR)/$$i"; \ $(INSTALL_DATA_DIR) "$(SCRIPT_INSTALL_DIR)"/$$i; \ - else true; \ - fi; \ - done; + fi; \ + done @echo "Installing library files to $(SCRIPT_INSTALL_DIR)/"; @for i in $(TOP_DIR)/library/*.tcl $(TOP_DIR)/library/tclIndex \ - $(UNIX_DIR)/tclAppInit.c @LDAIX_SRC@ @DTRACE_SRC@; \ - do \ + $(UNIX_DIR)/tclAppInit.c @LDAIX_SRC@ @DTRACE_SRC@; do \ $(INSTALL_DATA) $$i "$(SCRIPT_INSTALL_DIR)"; \ - done; + done @echo "Installing package http 2.9.0 as a Tcl Module"; @$(INSTALL_DATA) $(TOP_DIR)/library/http/http.tcl "$(SCRIPT_INSTALL_DIR)"/../tcl8/8.6/http-2.9.0.tm; @echo "Installing package opt0.4 files to $(SCRIPT_INSTALL_DIR)/opt0.4/"; - @for i in $(TOP_DIR)/library/opt/*.tcl ; \ - do \ + @for i in $(TOP_DIR)/library/opt/*.tcl ; do \ $(INSTALL_DATA) $$i "$(SCRIPT_INSTALL_DIR)"/opt0.4; \ - done; + done @echo "Installing package msgcat 1.7.0 as a Tcl Module"; @$(INSTALL_DATA) $(TOP_DIR)/library/msgcat/msgcat.tcl "$(SCRIPT_INSTALL_DIR)"/../tcl8/8.7/msgcat-1.7.0.tm; @echo "Installing package tcltest 2.4.1 as a Tcl Module"; @@ -947,23 +939,20 @@ install-libraries: libraries @echo "Installing encoding files to $(SCRIPT_INSTALL_DIR)/encoding/"; @for i in $(TOP_DIR)/library/encoding/*.enc ; do \ $(INSTALL_DATA) $$i "$(SCRIPT_INSTALL_DIR)"/encoding; \ - done; + done @if [ -n "$(TCL_MODULE_PATH)" -a -f $(TOP_DIR)/library/tm.tcl ]; then \ echo "Customizing tcl module path"; \ echo "if {![interp issafe]} { ::tcl::tm::roots {$(TCL_MODULE_PATH)} }" >> \ "$(SCRIPT_INSTALL_DIR)"/tm.tcl; \ fi - end install-tzdata: - @for i in tzdata; \ - do \ + @for i in tzdata; do \ if [ ! -d "$(SCRIPT_INSTALL_DIR)"/$$i ] ; then \ echo "Making directory $(SCRIPT_INSTALL_DIR)/$$i"; \ $(INSTALL_DATA_DIR) "$(SCRIPT_INSTALL_DIR)"/$$i; \ - else true; \ - fi; \ - done; + fi; \ + done @echo "Installing time zone files to $(SCRIPT_INSTALL_DIR)/tzdata/" @for i in $(TOP_DIR)/library/tzdata/* ; do \ if [ -d $$i ] ; then \ @@ -987,37 +976,33 @@ install-tzdata: else \ $(INSTALL_DATA) $$i "$(SCRIPT_INSTALL_DIR)"/tzdata; \ fi; \ - done; + done install-msgs: - @for i in msgs; \ - do \ + @for i in msgs; do \ if [ ! -d "$(SCRIPT_INSTALL_DIR)"/$$i ] ; then \ echo "Making directory $(SCRIPT_INSTALL_DIR)/$$i"; \ $(INSTALL_DATA_DIR) "$(SCRIPT_INSTALL_DIR)"/$$i; \ - else true; \ - fi; \ - done; + fi; \ + done @echo "Installing message catalog files to $(SCRIPT_INSTALL_DIR)/msgs/" @for i in $(TOP_DIR)/library/msgs/*.msg ; do \ $(INSTALL_DATA) $$i "$(SCRIPT_INSTALL_DIR)"/msgs; \ - done; + done install-doc: doc - @for i in "$(MAN_INSTALL_DIR)" "$(MAN1_INSTALL_DIR)" "$(MAN3_INSTALL_DIR)" "$(MANN_INSTALL_DIR)" ; \ - do \ + @for i in "$(MAN_INSTALL_DIR)" "$(MAN1_INSTALL_DIR)" "$(MAN3_INSTALL_DIR)" "$(MANN_INSTALL_DIR)" ; do \ if [ ! -d "$$i" ] ; then \ echo "Making directory $$i"; \ $(INSTALL_DATA_DIR) "$$i"; \ - else true; \ - fi; \ - done; - @echo "Installing and cross-linking top-level (.1) docs to $(MAN1_INSTALL_DIR)/"; + fi; \ + done + @echo "Installing and cross-linking top-level (.1) docs to $(MAN1_INSTALL_DIR)/" @for i in $(TOP_DIR)/doc/*.1; do \ $(SHELL) $(UNIX_DIR)/installManPage $(MAN_FLAGS) $$i "$(MAN1_INSTALL_DIR)"; \ done - @echo "Installing and cross-linking C API (.3) docs to $(MAN3_INSTALL_DIR)/"; + @echo "Installing and cross-linking C API (.3) docs to $(MAN3_INSTALL_DIR)/" @for i in $(TOP_DIR)/doc/*.3; do \ $(SHELL) $(UNIX_DIR)/installManPage $(MAN_FLAGS) $$i "$(MAN3_INSTALL_DIR)"; \ done @@ -1028,14 +1013,12 @@ install-doc: doc done install-headers: - @for i in "$(INCLUDE_INSTALL_DIR)"; \ - do \ + @for i in "$(INCLUDE_INSTALL_DIR)"; do \ if [ ! -d "$$i" ] ; then \ echo "Making directory $$i"; \ $(INSTALL_DATA_DIR) "$$i"; \ - else true; \ - fi; \ - done; + fi; \ + done @echo "Installing header files to $(INCLUDE_INSTALL_DIR)/"; @for i in $(GENERIC_DIR)/tcl.h $(GENERIC_DIR)/tclDecls.h \ $(GENERIC_DIR)/tclOO.h $(GENERIC_DIR)/tclOODecls.h \ @@ -1043,30 +1026,28 @@ install-headers: $(GENERIC_DIR)/tclTomMath.h \ $(GENERIC_DIR)/tclTomMathDecls.h ; \ do \ - $(INSTALL_DATA) $$i "$(INCLUDE_INSTALL_DIR)"; \ - done; + $(INSTALL_DATA) $$i "$(INCLUDE_INSTALL_DIR)"; \ + done # Optional target to install private headers install-private-headers: - @for i in "$(PRIVATE_INCLUDE_INSTALL_DIR)"; \ - do \ + @for i in "$(PRIVATE_INCLUDE_INSTALL_DIR)"; do \ if [ ! -d "$$i" ] ; then \ echo "Making directory $$i"; \ $(INSTALL_DATA_DIR) "$$i"; \ - else true; \ - fi; \ - done; + fi; \ + done @echo "Installing private header files to $(PRIVATE_INCLUDE_INSTALL_DIR)/"; @for i in $(GENERIC_DIR)/tclInt.h $(GENERIC_DIR)/tclIntDecls.h \ $(GENERIC_DIR)/tclIntPlatDecls.h $(GENERIC_DIR)/tclPort.h \ $(GENERIC_DIR)/tclOOInt.h $(GENERIC_DIR)/tclOOIntDecls.h \ $(UNIX_DIR)/tclUnixPort.h; \ do \ - $(INSTALL_DATA) $$i "$(PRIVATE_INCLUDE_INSTALL_DIR)"; \ - done; + $(INSTALL_DATA) $$i "$(PRIVATE_INCLUDE_INSTALL_DIR)"; \ + done @if test -f tclConfig.h; then\ $(INSTALL_DATA) tclConfig.h "$(PRIVATE_INCLUDE_INSTALL_DIR)"; \ - fi; + fi #-------------------------------------------------------------------------- # Rules for how to compile C files @@ -1085,7 +1066,7 @@ tclTestInit.o: $(UNIX_DIR)/tclAppInit.c ${TCL_EXE} @if test -f tclAppInit.o ; then \ rm -f tclAppInit.sav; \ mv tclAppInit.o tclAppInit.sav; \ - fi; + fi $(CC) -c $(APP_CC_SWITCHES) \ -DTCL_BUILDTIME_LIBRARY="\"${TCL_BUILDTIME_LIBRARY}\"" \ -DTCL_TEST $(UNIX_DIR)/tclAppInit.c @@ -1093,13 +1074,13 @@ tclTestInit.o: $(UNIX_DIR)/tclAppInit.c ${TCL_EXE} mv tclAppInit.o tclTestInit.o @if test -f tclAppInit.sav ; then \ mv tclAppInit.sav tclAppInit.o; \ - fi; + fi xtTestInit.o: $(UNIX_DIR)/tclAppInit.c ${TCL_EXE} @if test -f tclAppInit.o ; then \ rm -f tclAppInit.sav; \ mv tclAppInit.o tclAppInit.sav; \ - fi; + fi $(CC) -c $(APP_CC_SWITCHES) \ -DTCL_BUILDTIME_LIBRARY="\"${TCL_BUILDTIME_LIBRARY}\"" \ -DTCL_TEST -DTCL_XT_TEST $(UNIX_DIR)/tclAppInit.c @@ -1107,20 +1088,23 @@ xtTestInit.o: $(UNIX_DIR)/tclAppInit.c ${TCL_EXE} mv tclAppInit.o xtTestInit.o @if test -f tclAppInit.sav ; then \ mv tclAppInit.sav tclAppInit.o; \ - fi; + fi # Object files used on all Unix systems: -REGHDRS=$(GENERIC_DIR)/regex.h $(GENERIC_DIR)/regguts.h \ - $(GENERIC_DIR)/regcustom.h -TCLREHDRS=$(GENERIC_DIR)/tclRegexp.h -COMPILEHDR=$(GENERIC_DIR)/tclCompile.h -FSHDR=$(GENERIC_DIR)/tclFileSystem.h -IOHDR=$(GENERIC_DIR)/tclIO.h -MATHHDRS=$(GENERIC_DIR)/tommath.h $(GENERIC_DIR)/tclTomMath.h -PARSEHDR=$(GENERIC_DIR)/tclParse.h -NREHDR=$(GENERIC_DIR)/tclInt.h -TRIMHDR=$(GENERIC_DIR)/tclStringTrim.h +REGHDRS = $(GENERIC_DIR)/regex.h $(GENERIC_DIR)/regguts.h \ + $(GENERIC_DIR)/regcustom.h +TCLREHDRS = $(GENERIC_DIR)/tclRegexp.h +COMPILEHDR = $(GENERIC_DIR)/tclCompile.h +FSHDR = $(GENERIC_DIR)/tclFileSystem.h +IOHDR = $(GENERIC_DIR)/tclIO.h +MATHHDRS = $(GENERIC_DIR)/tommath.h $(GENERIC_DIR)/tclTomMath.h +PARSEHDR = $(GENERIC_DIR)/tclParse.h +NREHDR = $(GENERIC_DIR)/tclInt.h +TRIMHDR = $(GENERIC_DIR)/tclStringTrim.h + +TCL_LOCATIONS = -DTCL_LIBRARY="\"${TCL_LIBRARY}\"" \ + -DTCL_PACKAGE_PATH="\"${TCL_PACKAGE_PATH}\"" regcomp.o: $(REGHDRS) $(GENERIC_DIR)/regcomp.c $(GENERIC_DIR)/regc_lex.c \ $(GENERIC_DIR)/regc_color.c $(GENERIC_DIR)/regc_locale.c \ @@ -1349,13 +1333,12 @@ tclPkg.o: $(GENERIC_DIR)/tclPkg.c # prefix/exec_prefix but all the different paths individually. tclPkgConfig.o: $(GENERIC_DIR)/tclPkgConfig.c - $(CC) -c $(CC_SWITCHES) \ + $(CC) -c $(CC_SWITCHES) \ -DCFG_INSTALL_LIBDIR="\"$(LIB_INSTALL_DIR)\"" \ -DCFG_INSTALL_BINDIR="\"$(BIN_INSTALL_DIR)\"" \ -DCFG_INSTALL_SCRDIR="\"$(SCRIPT_INSTALL_DIR)\"" \ -DCFG_INSTALL_INCDIR="\"$(INCLUDE_INSTALL_DIR)\"" \ -DCFG_INSTALL_DOCDIR="\"$(MAN_INSTALL_DIR)\"" \ - \ -DCFG_RUNTIME_LIBDIR="\"$(libdir)\"" \ -DCFG_RUNTIME_BINDIR="\"$(bindir)\"" \ -DCFG_RUNTIME_SCRDIR="\"$(TCL_LIBRARY)\"" \ @@ -1363,7 +1346,6 @@ tclPkgConfig.o: $(GENERIC_DIR)/tclPkgConfig.c -DCFG_RUNTIME_DOCDIR="\"$(mandir)\"" \ -DCFG_RUNTIME_DLLFILE="\"$(TCL_LIB_FILE)\"" \ -DCFG_RUNTIME_ZIPFILE="\"$(TCL_ZIP_FILE)\"" \ - \ $(GENERIC_DIR)/tclPkgConfig.c tclPosixStr.o: $(GENERIC_DIR)/tclPosixStr.c @@ -1416,11 +1398,12 @@ tclZlib.o: $(GENERIC_DIR)/tclZlib.c tclZipfs.o: $(GENERIC_DIR)/tclZipfs.c $(CC) -c $(CC_SWITCHES) \ - -DCFG_RUNTIME_DLLFILE="\"$(TCL_LIB_FILE)\"" \ - -DCFG_RUNTIME_ZIPFILE="\"$(TCL_ZIP_FILE)\"" \ - -DCFG_RUNTIME_LIBDIR="\"$(libdir)\"" \ - -DCFG_RUNTIME_SCRDIR="\"$(TCL_LIBRARY)\"" \ - $(ZLIB_INCLUDE) -I$(ZLIB_DIR)/contrib/minizip $(GENERIC_DIR)/tclZipfs.c + -DCFG_RUNTIME_DLLFILE="\"$(TCL_LIB_FILE)\"" \ + -DCFG_RUNTIME_ZIPFILE="\"$(TCL_ZIP_FILE)\"" \ + -DCFG_RUNTIME_LIBDIR="\"$(libdir)\"" \ + -DCFG_RUNTIME_SCRDIR="\"$(TCL_LIBRARY)\"" \ + $(ZLIB_INCLUDE) -I$(ZLIB_DIR)/contrib/minizip \ + $(GENERIC_DIR)/tclZipfs.c tclTest.o: $(GENERIC_DIR)/tclTest.c $(IOHDR) $(TCLREHDRS) $(CC) -c $(APP_CC_SWITCHES) $(GENERIC_DIR)/tclTest.c @@ -1698,7 +1681,6 @@ tclUnixThrd.o: $(UNIX_DIR)/tclUnixThrd.c tclUnixTime.o: $(UNIX_DIR)/tclUnixTime.c $(CC) -c $(CC_SWITCHES) $(UNIX_DIR)/tclUnixTime.c -TCL_LOCATIONS=-DTCL_LIBRARY="\"${TCL_LIBRARY}\"" -DTCL_PACKAGE_PATH="\"${TCL_PACKAGE_PATH}\"" tclUnixInit.o: $(UNIX_DIR)/tclUnixInit.c tclConfig.sh $(CC) -c $(CC_SWITCHES) $(TCL_LOCATIONS) $(UNIX_DIR)/tclUnixInit.c @@ -1845,7 +1827,8 @@ deflate.$(HOST_OBJEXT): $(HOST_CC) -o $@ -I$(ZLIB_DIR) -c $(ZLIB_DIR)/deflate.c ioapi.$(HOST_OBJEXT): - $(HOST_CC) -o $@ -I$(ZLIB_DIR) -I$(ZLIB_DIR)/contrib/minizip -c $(ZLIB_DIR)/contrib/minizip/ioapi.c + $(HOST_CC) -o $@ -I$(ZLIB_DIR) -I$(ZLIB_DIR)/contrib/minizip -c \ + $(ZLIB_DIR)/contrib/minizip/ioapi.c infback.$(HOST_OBJEXT): $(HOST_CC) -o $@ -I$(ZLIB_DIR) -c $(ZLIB_DIR)/infback.c @@ -1866,13 +1849,15 @@ uncompr.$(HOST_OBJEXT): $(HOST_CC) -o $@ -I$(ZLIB_DIR) -c $(ZLIB_DIR)/uncompr.c zip.$(HOST_OBJEXT): - $(HOST_CC) -o $@ -I$(ZLIB_DIR) -I$(ZLIB_DIR)/contrib/minizip -c $(ZLIB_DIR)/contrib/minizip/zip.c + $(HOST_CC) -o $@ -I$(ZLIB_DIR) -I$(ZLIB_DIR)/contrib/minizip -c \ + $(ZLIB_DIR)/contrib/minizip/zip.c zutil.$(HOST_OBJEXT): $(HOST_CC) -o $@ -I$(ZLIB_DIR) -c $(ZLIB_DIR)/zutil.c minizip.$(HOST_OBJEXT): - $(HOST_CC) -o $@ -I$(ZLIB_DIR) -I$(ZLIB_DIR)/contrib/minizip -c $(ZLIB_DIR)/contrib/minizip/minizip.c + $(HOST_CC) -o $@ -I$(ZLIB_DIR) -I$(ZLIB_DIR)/contrib/minizip -c \ + $(ZLIB_DIR)/contrib/minizip/minizip.c minizip${HOST_EXEEXT}: $(MINIZIP_OBJS) $(HOST_CC) -o $@ $(MINIZIP_OBJS) @@ -1992,9 +1977,9 @@ dist-packages: configure-packages gendate: bison --output-file=$(GENERIC_DIR)/tclDate.c \ - --no-lines \ - --name-prefix=TclDate \ - $(GENERIC_DIR)/tclGetDate.y + --no-lines \ + --name-prefix=TclDate \ + $(GENERIC_DIR)/tclGetDate.y # yacc -l $(GENERIC_DIR)/tclGetDate.y # sed -e 's/yy/TclDate/g' -e '/^#include /d' \ @@ -2055,13 +2040,15 @@ checkstubs: $(TCL_LIB_FILE) -@for i in `nm -p $(TCL_LIB_FILE) \ | awk '$$2 ~ /^[TDBCS]$$/ { sub("^_", "", $$3); print $$3 }' \ | sort -n`; do \ - match=0; \ - for j in $(TCL_DECLS); do \ - if [ `grep -c "$$i *(" $$j` -gt 0 ]; then \ - match=1; \ - fi; \ - done; \ - if [ $$match -eq 0 ]; then echo $$i; fi \ + match=0; \ + for j in $(TCL_DECLS); do \ + if [ `grep -c "$$i *(" $$j` -gt 0 ]; then \ + match=1; \ + fi; \ + done; \ + if [ $$match -eq 0 ]; then \ + echo $$i; \ + fi; \ done # @@ -2072,13 +2059,15 @@ checkstubs: $(TCL_LIB_FILE) checkdoc: $(TCL_LIB_FILE) -@for i in `nm -p $(TCL_LIB_FILE) | awk '$$3 ~ /Tcl_/ { print $$3 }' \ | grep -v 'Cmd$$' | sort -n`; do \ - match=0; \ - for j in $(TOP_DIR)/doc/*.3; do \ - if [ `grep '\-' $$j | grep -c $$i` -gt 0 ]; then \ - match=1; \ - fi; \ - done; \ - if [ $$match -eq 0 ]; then echo $$i; fi \ + match=0; \ + for j in $(TOP_DIR)/doc/*.3; do \ + if [ `grep '\-' $$j | grep -c $$i` -gt 0 ]; then \ + match=1; \ + fi; \ + done; \ + if [ $$match -eq 0 ]; then \ + echo $$i; \ + fi; \ done # @@ -2107,14 +2096,14 @@ checkexports: $(TCL_LIB_FILE) # rpm: all - rm -f THIS.TCL.SPEC + -@rm -f THIS.TCL.SPEC echo "%define _builddir `pwd`" > THIS.TCL.SPEC echo "%define _rpmdir `pwd`/RPMS" >> THIS.TCL.SPEC cat tcl.spec >> THIS.TCL.SPEC mkdir -p RPMS/i386 rpmbuild -bb THIS.TCL.SPEC mv RPMS/i386/*.rpm . - rm -rf RPMS THIS.TCL.SPEC + -rm -rf RPMS THIS.TCL.SPEC # # Target to create a proper Tcl distribution from information in the master @@ -2292,7 +2281,7 @@ BUILD_HTML = \ .PHONY: install-tzdata install-msgs .PHONY: packages configure-packages test-packages clean-packages .PHONY: dist-packages distclean-packages install-packages -.PHONY: iinstall-libraries-zipfs-shared install-libraries-zipfs-static tclzipfile +.PHONY: install-libraries-zipfs-shared install-libraries-zipfs-static tclzipfile #-------------------------------------------------------------------------- # DO NOT DELETE THIS LINE -- make depend depends on it. -- cgit v0.12 From 6d137e77a50138715c97318a4d3501e8b97f38c2 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Fri, 28 Sep 2018 18:21:10 +0000 Subject: nmake build fixes for zipfs (ongoing, zip attachments not done yet) --- win/makefile.vc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/win/makefile.vc b/win/makefile.vc index 1aae9a3..77d56b8 100644 --- a/win/makefile.vc +++ b/win/makefile.vc @@ -236,6 +236,7 @@ COREOBJS = \ $(TMP_DIR)\tclUtf.obj \ $(TMP_DIR)\tclUtil.obj \ $(TMP_DIR)\tclVar.obj \ + $(TMP_DIR)\tclZipfs.obj \ $(TMP_DIR)\tclZlib.obj ZLIBOBJS = \ @@ -686,6 +687,9 @@ $(TMP_DIR)\tclTestObj.obj: $(GENERICDIR)\tclTestObj.c $(TMP_DIR)\tclWinTest.obj: $(WINDIR)\tclWinTest.c $(CCAPPCMD) $? +$(TMP_DIR)\tclZipfs.obj: $(GENERICDIR)\tclZipfs.c + $(cc32) $(pkgcflags) -I$(COMPATDIR)\zlib -I$(COMPATDIR)\zlib\contrib\minizip -Fo$@ $? + $(TMP_DIR)\tclZlib.obj: $(GENERICDIR)\tclZlib.c $(cc32) $(pkgcflags) -I$(COMPATDIR)\zlib -Fo$@ $? @@ -701,6 +705,8 @@ $(TMP_DIR)\tclPkgConfig.obj: $(GENERICDIR)\tclPkgConfig.c -DCFG_RUNTIME_SCRDIR="\"$(SCRIPT_INSTALL_DIR:\=\\)\"" \ -DCFG_RUNTIME_INCDIR="\"$(INCLUDE_INSTALL_DIR:\=\\)\"" \ -DCFG_RUNTIME_DOCDIR="\"$(DOC_INSTALL_DIR:\=\\)\"" \ + -DCFG_RUNTIME_DLLFILE="\"$(CFG_RUNTIME_DLLFILE:\=\\)\"" \ + -DCFG_RUNTIME_ZIPFILE="\"$(CFG_RUNTIME_ZIPFILE:\=\\)\"" \ -Fo$@ $? $(TMP_DIR)\tclAppInit.obj: $(WINDIR)\tclAppInit.c -- cgit v0.12 From 3d5f129cb0f1208fab8b96b4a86777ea25744163 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Fri, 28 Sep 2018 18:45:34 +0000 Subject: Another patch contributed by Gustaf Neumann: shifting negative numbers is undefined behavior in the C standard https://stackoverflow.com/questions/8415895/is-left-and-right-shifting-negative-integers-defined-behavior --- generic/tclCompile.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generic/tclCompile.h b/generic/tclCompile.h index 6aaa855..0466429 100644 --- a/generic/tclCompile.h +++ b/generic/tclCompile.h @@ -1494,7 +1494,7 @@ MODULE_SCOPE int TclPushProcCallFrame(ClientData clientData, #endif #define TclGetInt4AtPtr(p) \ - (((int) TclGetInt1AtPtr(p) << 24) | \ + (((int) (TclGetUInt1AtPtr(p) << 24)) | \ (*((p)+1) << 16) | \ (*((p)+2) << 8) | \ (*((p)+3))) -- cgit v0.12 From a9dab7860411eb424231c5c1218aecda4190e121 Mon Sep 17 00:00:00 2001 From: dkf Date: Sat, 29 Sep 2018 08:51:42 +0000 Subject: More readability improvements to unix makefile --- unix/Makefile.in | 295 +++++++++++++++++++++++++++++-------------------------- 1 file changed, 153 insertions(+), 142 deletions(-) diff --git a/unix/Makefile.in b/unix/Makefile.in index 2432ad5..b30d357 100644 --- a/unix/Makefile.in +++ b/unix/Makefile.in @@ -677,12 +677,12 @@ doc: tclzipfile: ${TCL_ZIP_FILE} - ${TCL_ZIP_FILE}: ${ZIP_INSTALL_OBJS} - rm -rf ${TCL_VFS_ROOT} - mkdir -p ${TCL_VFS_PATH} + @rm -rf ${TCL_VFS_ROOT} + @mkdir -p ${TCL_VFS_PATH} cp -a $(TOP_DIR)/library/* ${TCL_VFS_PATH} - (cd ${TCL_VFS_ROOT} ; ${NATIVE_ZIP} ${ZIP_PROG_OPTIONS} ../${TCL_ZIP_FILE} ${ZIP_PROG_VFSSEARCH}) + ( cd ${TCL_VFS_ROOT} ; \ + ${NATIVE_ZIP} ${ZIP_PROG_OPTIONS} ../${TCL_ZIP_FILE} ${ZIP_PROG_VFSSEARCH}) # The following target is configured by autoconf to generate either a shared # library or non-shared library for Tcl. @@ -694,8 +694,8 @@ ifeq (${ZIPFS_BUILD},1) endif ${STUB_LIB_FILE}: ${STUB_LIB_OBJS} - @if test "x${LIB_FILE}" = "xlibtcl${MAJOR_VERSION}.${MINOR_VERSION}.dll"; then \ - (cd ${TOP_DIR}/win; ${MAKE} winextensions); \ + @if [ "x${LIB_FILE}" = "xlibtcl${MAJOR_VERSION}.${MINOR_VERSION}.dll" ] ; then \ + ( cd ${TOP_DIR}/win; ${MAKE} winextensions ); \ fi rm -f $@ @MAKE_STUB_LIB@ @@ -788,13 +788,14 @@ gdb-test: ${TCLTEST_EXE} @echo "set env TCL_LIBRARY=${TCL_BUILDTIME_LIBRARY}" >> gdb.run @echo "set args $(TOP_DIR)/tests/all.tcl $(TESTFLAGS) -singleproc 1" >> gdb.run $(GDB) ./${TCLTEST_EXE} --command=gdb.run - rm gdb.run + @rm gdb.run lldb-test: ${TCLTEST_EXE} @echo "settings set target.env-vars @LD_LIBRARY_PATH_VAR@=`pwd`:$${@LD_LIBRARY_PATH_VAR@}" > lldb.run @echo "settings set target.env-vars TCL_LIBRARY=${TCL_BUILDTIME_LIBRARY}" >> lldb.run - $(LLDB) --source lldb.run ./${TCLTEST_EXE} -- $(TOP_DIR)/tests/all.tcl $(TESTFLAGS) -singleproc 1 - rm lldb.run + $(LLDB) --source lldb.run ./${TCLTEST_EXE} -- $(TOP_DIR)/tests/all.tcl \ + $(TESTFLAGS) -singleproc 1 + @rm lldb.run # Useful target to launch a built tcltest with the proper path,... runtest: ${TCLTEST_EXE} @@ -828,7 +829,9 @@ gdb: ${TCL_EXE} $(SHELL_ENV) $(GDB) ./${TCL_EXE} valgrind: ${TCL_EXE} ${TCLTEST_EXE} - $(SHELL_ENV) $(VALGRIND) $(VALGRINDARGS) ./${TCLTEST_EXE} $(TOP_DIR)/tests/all.tcl -singleproc 1 -constraints valgrind $(TESTFLAGS) + $(SHELL_ENV) $(VALGRIND) $(VALGRINDARGS) ./${TCLTEST_EXE} \ + $(TOP_DIR)/tests/all.tcl -singleproc 1 -constraints valgrind \ + $(TESTFLAGS) valgrindshell: ${TCL_EXE} $(SHELL_ENV) $(VALGRIND) $(VALGRINDARGS) ./${TCL_EXE} $(SCRIPT) @@ -860,14 +863,12 @@ install-strip: install-binaries: binaries @for i in "$(LIB_INSTALL_DIR)" "$(BIN_INSTALL_DIR)" \ - "$(CONFIG_INSTALL_DIR)"; \ - do \ + "$(CONFIG_INSTALL_DIR)" ; do \ if [ ! -d "$$i" ] ; then \ echo "Making directory $$i"; \ $(INSTALL_DATA_DIR) "$$i"; \ - else true; \ - fi; \ - done; + fi; \ + done @echo "Installing $(LIB_FILE) to $(DLL_INSTALL_DIR)/" @@INSTALL_LIB@ @chmod 555 "$(DLL_INSTALL_DIR)/$(LIB_FILE)" @@ -888,66 +889,71 @@ install-binaries: binaries @$(INSTALL_DATA) tcl.pc $(LIB_INSTALL_DIR)/pkgconfig/tcl.pc install-libraries-zipfs-shared: libraries - @for i in "$(SCRIPT_INSTALL_DIR)"; do \ + @for i in "$(SCRIPT_INSTALL_DIR)" ; do \ if [ ! -d "$$i" ] ; then \ echo "Making directory $$i"; \ $(INSTALL_DATA_DIR) "$$i"; \ fi; \ done - @echo "Installing library files to $(SCRIPT_INSTALL_DIR)/"; - @for i in $(UNIX_DIR)/tclAppInit.c @LDAIX_SRC@ @DTRACE_SRC@; do \ + @echo "Installing library files to $(SCRIPT_INSTALL_DIR)/" + @for i in $(UNIX_DIR)/tclAppInit.c @LDAIX_SRC@ @DTRACE_SRC@ ; do \ $(INSTALL_DATA) $$i "$(SCRIPT_INSTALL_DIR)"; \ done install-libraries-zipfs-static: install-libraries-zipfs-shared - $(INSTALL_DATA) ${TCL_ZIP_FILE} "$(LIB_INSTALL_DIR)" ;\ + $(INSTALL_DATA) ${TCL_ZIP_FILE} "$(LIB_INSTALL_DIR)" + +MODULE_INSTALL_DIR=$(SCRIPT_INSTALL_DIR)/.. install-libraries: libraries - @for i in "$(SCRIPT_INSTALL_DIR)"; do \ + @for i in "$(SCRIPT_INSTALL_DIR)" ; do \ if [ ! -d "$$i" ] ; then \ echo "Making directory $$i"; \ $(INSTALL_DATA_DIR) "$$i"; \ fi; \ done - @for i in opt0.4 encoding ../tcl8 ../tcl8/8.4 ../tcl8/8.4/platform ../tcl8/8.5 ../tcl8/8.6 ../tcl8/8.7; do \ + @for i in opt0.4 encoding ../tcl8 ../tcl8/8.4 ../tcl8/8.4/platform ../tcl8/8.5 ../tcl8/8.6 ../tcl8/8.7 ; do \ if [ ! -d "$(SCRIPT_INSTALL_DIR)"/$$i ] ; then \ echo "Making directory $(SCRIPT_INSTALL_DIR)/$$i"; \ $(INSTALL_DATA_DIR) "$(SCRIPT_INSTALL_DIR)"/$$i; \ fi; \ done - @echo "Installing library files to $(SCRIPT_INSTALL_DIR)/"; + @echo "Installing library files to $(SCRIPT_INSTALL_DIR)/" @for i in $(TOP_DIR)/library/*.tcl $(TOP_DIR)/library/tclIndex \ - $(UNIX_DIR)/tclAppInit.c @LDAIX_SRC@ @DTRACE_SRC@; do \ + $(UNIX_DIR)/tclAppInit.c @LDAIX_SRC@ @DTRACE_SRC@ ; do \ $(INSTALL_DATA) $$i "$(SCRIPT_INSTALL_DIR)"; \ done - @echo "Installing package http 2.9.0 as a Tcl Module"; - @$(INSTALL_DATA) $(TOP_DIR)/library/http/http.tcl "$(SCRIPT_INSTALL_DIR)"/../tcl8/8.6/http-2.9.0.tm; - @echo "Installing package opt0.4 files to $(SCRIPT_INSTALL_DIR)/opt0.4/"; + @echo "Installing package http 2.9.0 as a Tcl Module" + @$(INSTALL_DATA) $(TOP_DIR)/library/http/http.tcl \ + "$(MODULE_INSTALL_DIR)"/tcl8/8.6/http-2.9.0.tm + @echo "Installing package opt0.4 files to $(SCRIPT_INSTALL_DIR)/opt0.4/" @for i in $(TOP_DIR)/library/opt/*.tcl ; do \ $(INSTALL_DATA) $$i "$(SCRIPT_INSTALL_DIR)"/opt0.4; \ done - @echo "Installing package msgcat 1.7.0 as a Tcl Module"; - @$(INSTALL_DATA) $(TOP_DIR)/library/msgcat/msgcat.tcl "$(SCRIPT_INSTALL_DIR)"/../tcl8/8.7/msgcat-1.7.0.tm; - @echo "Installing package tcltest 2.4.1 as a Tcl Module"; - @$(INSTALL_DATA) $(TOP_DIR)/library/tcltest/tcltest.tcl "$(SCRIPT_INSTALL_DIR)"/../tcl8/8.5/tcltest-2.4.1.tm; - - @echo "Installing package platform 1.0.14 as a Tcl Module"; - @$(INSTALL_DATA) $(TOP_DIR)/library/platform/platform.tcl "$(SCRIPT_INSTALL_DIR)"/../tcl8/8.4/platform-1.0.14.tm; - @echo "Installing package platform::shell 1.1.4 as a Tcl Module"; - @$(INSTALL_DATA) $(TOP_DIR)/library/platform/shell.tcl "$(SCRIPT_INSTALL_DIR)"/../tcl8/8.4/platform/shell-1.1.4.tm; - - @echo "Installing encoding files to $(SCRIPT_INSTALL_DIR)/encoding/"; + @echo "Installing package msgcat 1.7.0 as a Tcl Module" + @$(INSTALL_DATA) $(TOP_DIR)/library/msgcat/msgcat.tcl \ + "$(MODULE_INSTALL_DIR)"/tcl8/8.7/msgcat-1.7.0.tm + @echo "Installing package tcltest 2.4.1 as a Tcl Module" + @$(INSTALL_DATA) $(TOP_DIR)/library/tcltest/tcltest.tcl \ + "$(MODULE_INSTALL_DIR)"/tcl8/8.5/tcltest-2.4.1.tm + @echo "Installing package platform 1.0.14 as a Tcl Module" + @$(INSTALL_DATA) $(TOP_DIR)/library/platform/platform.tcl \ + "$(MODULE_INSTALL_DIR)"/tcl8/8.4/platform-1.0.14.tm + @echo "Installing package platform::shell 1.1.4 as a Tcl Module" + @$(INSTALL_DATA) $(TOP_DIR)/library/platform/shell.tcl \ + "$(MODULE_INSTALL_DIR)"/tcl8/8.4/platform/shell-1.1.4.tm + @echo "Installing encoding files to $(SCRIPT_INSTALL_DIR)/encoding/" @for i in $(TOP_DIR)/library/encoding/*.enc ; do \ $(INSTALL_DATA) $$i "$(SCRIPT_INSTALL_DIR)"/encoding; \ done - @if [ -n "$(TCL_MODULE_PATH)" -a -f $(TOP_DIR)/library/tm.tcl ]; then \ + @if [ -n "$(TCL_MODULE_PATH)" -a -f $(TOP_DIR)/library/tm.tcl ] ; then \ echo "Customizing tcl module path"; \ echo "if {![interp issafe]} { ::tcl::tm::roots {$(TCL_MODULE_PATH)} }" >> \ "$(SCRIPT_INSTALL_DIR)"/tm.tcl; \ fi install-tzdata: - @for i in tzdata; do \ + @for i in tzdata ; do \ if [ ! -d "$(SCRIPT_INSTALL_DIR)"/$$i ] ; then \ echo "Making directory $(SCRIPT_INSTALL_DIR)/$$i"; \ $(INSTALL_DATA_DIR) "$(SCRIPT_INSTALL_DIR)"/$$i; \ @@ -979,7 +985,7 @@ install-tzdata: done install-msgs: - @for i in msgs; do \ + @for i in msgs ; do \ if [ ! -d "$(SCRIPT_INSTALL_DIR)"/$$i ] ; then \ echo "Making directory $(SCRIPT_INSTALL_DIR)/$$i"; \ $(INSTALL_DATA_DIR) "$(SCRIPT_INSTALL_DIR)"/$$i; \ @@ -987,7 +993,7 @@ install-msgs: done @echo "Installing message catalog files to $(SCRIPT_INSTALL_DIR)/msgs/" @for i in $(TOP_DIR)/library/msgs/*.msg ; do \ - $(INSTALL_DATA) $$i "$(SCRIPT_INSTALL_DIR)"/msgs; \ + $(INSTALL_DATA) $$i "$(SCRIPT_INSTALL_DIR)"/msgs; \ done install-doc: doc @@ -998,54 +1004,56 @@ install-doc: doc fi; \ done @echo "Installing and cross-linking top-level (.1) docs to $(MAN1_INSTALL_DIR)/" - @for i in $(TOP_DIR)/doc/*.1; do \ + @for i in $(TOP_DIR)/doc/*.1 ; do \ $(SHELL) $(UNIX_DIR)/installManPage $(MAN_FLAGS) $$i "$(MAN1_INSTALL_DIR)"; \ done - @echo "Installing and cross-linking C API (.3) docs to $(MAN3_INSTALL_DIR)/" - @for i in $(TOP_DIR)/doc/*.3; do \ + @for i in $(TOP_DIR)/doc/*.3 ; do \ $(SHELL) $(UNIX_DIR)/installManPage $(MAN_FLAGS) $$i "$(MAN3_INSTALL_DIR)"; \ done - @echo "Installing and cross-linking command (.n) docs to $(MANN_INSTALL_DIR)/"; - @for i in $(TOP_DIR)/doc/*.n; do \ + @for i in $(TOP_DIR)/doc/*.n ; do \ $(SHELL) $(UNIX_DIR)/installManPage $(MAN_FLAGS) $$i "$(MANN_INSTALL_DIR)"; \ done +# Public headers that define Tcl's API +TCL_PUBLIC_HEADERS = $(GENERIC_DIR)/tcl.h $(GENERIC_DIR)/tclDecls.h \ + $(GENERIC_DIR)/tclOO.h $(GENERIC_DIR)/tclOODecls.h \ + $(GENERIC_DIR)/tclPlatDecls.h $(GENERIC_DIR)/tclTomMath.h \ + $(GENERIC_DIR)/tclTomMathDecls.h +# Private headers that define Tcl's internal API +TCL_PRIVATE_HEADERS = $(GENERIC_DIR)/tclInt.h $(GENERIC_DIR)/tclIntDecls.h \ + $(GENERIC_DIR)/tclIntPlatDecls.h $(GENERIC_DIR)/tclPort.h \ + $(GENERIC_DIR)/tclOOInt.h $(GENERIC_DIR)/tclOOIntDecls.h \ + $(UNIX_DIR)/tclUnixPort.h +# Any other headers you find in the Tcl sources are purely part of Tcl's +# implementation, and aren't to be installed. + install-headers: - @for i in "$(INCLUDE_INSTALL_DIR)"; do \ + @for i in "$(INCLUDE_INSTALL_DIR)" ; do \ if [ ! -d "$$i" ] ; then \ echo "Making directory $$i"; \ $(INSTALL_DATA_DIR) "$$i"; \ fi; \ done @echo "Installing header files to $(INCLUDE_INSTALL_DIR)/"; - @for i in $(GENERIC_DIR)/tcl.h $(GENERIC_DIR)/tclDecls.h \ - $(GENERIC_DIR)/tclOO.h $(GENERIC_DIR)/tclOODecls.h \ - $(GENERIC_DIR)/tclPlatDecls.h \ - $(GENERIC_DIR)/tclTomMath.h \ - $(GENERIC_DIR)/tclTomMathDecls.h ; \ - do \ - $(INSTALL_DATA) $$i "$(INCLUDE_INSTALL_DIR)"; \ - done + @for i in $(TCL_PUBLIC_HEADERS) ; do \ + $(INSTALL_DATA) $$i "$(INCLUDE_INSTALL_DIR)"; \ + done # Optional target to install private headers install-private-headers: - @for i in "$(PRIVATE_INCLUDE_INSTALL_DIR)"; do \ + @for i in "$(PRIVATE_INCLUDE_INSTALL_DIR)" ; do \ if [ ! -d "$$i" ] ; then \ echo "Making directory $$i"; \ $(INSTALL_DATA_DIR) "$$i"; \ fi; \ done @echo "Installing private header files to $(PRIVATE_INCLUDE_INSTALL_DIR)/"; - @for i in $(GENERIC_DIR)/tclInt.h $(GENERIC_DIR)/tclIntDecls.h \ - $(GENERIC_DIR)/tclIntPlatDecls.h $(GENERIC_DIR)/tclPort.h \ - $(GENERIC_DIR)/tclOOInt.h $(GENERIC_DIR)/tclOOIntDecls.h \ - $(UNIX_DIR)/tclUnixPort.h; \ - do \ - $(INSTALL_DATA) $$i "$(PRIVATE_INCLUDE_INSTALL_DIR)"; \ - done - @if test -f tclConfig.h; then\ + @for i in $(TCL_PRIVATE_HEADERS) ; do \ + $(INSTALL_DATA) $$i "$(PRIVATE_INCLUDE_INSTALL_DIR)"; \ + done + @if test -f tclConfig.h ; then \ $(INSTALL_DATA) tclConfig.h "$(PRIVATE_INCLUDE_INSTALL_DIR)"; \ fi @@ -1070,7 +1078,7 @@ tclTestInit.o: $(UNIX_DIR)/tclAppInit.c ${TCL_EXE} $(CC) -c $(APP_CC_SWITCHES) \ -DTCL_BUILDTIME_LIBRARY="\"${TCL_BUILDTIME_LIBRARY}\"" \ -DTCL_TEST $(UNIX_DIR)/tclAppInit.c - rm -f tclTestInit.o + @rm -f tclTestInit.o mv tclAppInit.o tclTestInit.o @if test -f tclAppInit.sav ; then \ mv tclAppInit.sav tclAppInit.o; \ @@ -1084,7 +1092,7 @@ xtTestInit.o: $(UNIX_DIR)/tclAppInit.c ${TCL_EXE} $(CC) -c $(APP_CC_SWITCHES) \ -DTCL_BUILDTIME_LIBRARY="\"${TCL_BUILDTIME_LIBRARY}\"" \ -DTCL_TEST -DTCL_XT_TEST $(UNIX_DIR)/tclAppInit.c - rm -f xtTestInit.o + @rm -f xtTestInit.o mv tclAppInit.o xtTestInit.o @if test -f tclAppInit.sav ; then \ mv tclAppInit.sav tclAppInit.o; \ @@ -1875,94 +1883,94 @@ PKG_CFG_ARGS = @PKG_CFG_ARGS@ PKG_DIR = ./pkgs configure-packages: - @for i in $(PKGS_DIR)/*; do \ - if [ -d $$i ]; then \ - if [ -x $$i/configure ]; then \ - pkg=`basename $$i`; \ - echo "Configuring package '$$pkg'"; \ - mkdir -p $(PKG_DIR)/$$pkg; \ - if [ ! -f $(PKG_DIR)/$$pkg/Makefile ]; then \ - ( cd $(PKG_DIR)/$$pkg; \ - $$i/configure --with-tcl=../.. \ - --with-tclinclude=$(GENERIC_DIR) \ - $(PKG_CFG_ARGS) --libdir=$(PACKAGE_DIR) \ - --enable-shared; ) || exit $$?; \ - fi; \ + @for i in $(PKGS_DIR)/* ; do \ + if [ -d $$i ] ; then \ + if [ -x $$i/configure ] ; then \ + pkg=`basename $$i`; \ + echo "Configuring package '$$pkg'"; \ + mkdir -p $(PKG_DIR)/$$pkg; \ + if [ ! -f $(PKG_DIR)/$$pkg/Makefile ] ; then \ + ( cd $(PKG_DIR)/$$pkg; \ + $$i/configure --with-tcl=../.. \ + --with-tclinclude=$(GENERIC_DIR) \ + $(PKG_CFG_ARGS) --libdir=$(PACKAGE_DIR) \ + --enable-shared; ) || exit $$?; \ + fi; \ + fi; \ fi; \ - fi; \ done packages: configure-packages ${STUB_LIB_FILE} - @for i in $(PKGS_DIR)/*; do \ - if [ -d $$i ]; then \ - pkg=`basename $$i`; \ - if [ -f $(PKG_DIR)/$$pkg/Makefile ]; then \ - echo "Building package '$$pkg'"; \ - ( cd $(PKG_DIR)/$$pkg; $(MAKE); ) || exit $$?; \ + @for i in $(PKGS_DIR)/* ; do \ + if [ -d $$i ] ; then \ + pkg=`basename $$i`; \ + if [ -f $(PKG_DIR)/$$pkg/Makefile ] ; then \ + echo "Building package '$$pkg'"; \ + ( cd $(PKG_DIR)/$$pkg; $(MAKE); ) || exit $$?; \ + fi; \ fi; \ - fi; \ done install-packages: packages - @for i in $(PKGS_DIR)/*; do \ - if [ -d $$i ]; then \ - pkg=`basename $$i`; \ - if [ -f $(PKG_DIR)/$$pkg/Makefile ]; then \ - echo "Installing package '$$pkg'"; \ - ( cd $(PKG_DIR)/$$pkg; $(MAKE) install \ - "DESTDIR=$(INSTALL_ROOT)"; ) || exit $$?; \ + @for i in $(PKGS_DIR)/* ; do \ + if [ -d $$i ] ; then \ + pkg=`basename $$i`; \ + if [ -f $(PKG_DIR)/$$pkg/Makefile ] ; then \ + echo "Installing package '$$pkg'"; \ + ( cd $(PKG_DIR)/$$pkg; $(MAKE) install \ + "DESTDIR=$(INSTALL_ROOT)"; ) || exit $$?; \ + fi; \ fi; \ - fi; \ done test-packages: ${TCLTEST_EXE} packages - @for i in $(PKGS_DIR)/*; do \ - if [ -d $$i ]; then \ - pkg=`basename $$i`; \ - if [ -f $(PKG_DIR)/$$pkg/Makefile ]; then \ - echo "Testing package '$$pkg'"; \ - ( cd $(PKG_DIR)/$$pkg; $(MAKE) \ - "@LD_LIBRARY_PATH_VAR@=../..:$${@LD_LIBRARY_PATH_VAR@}" \ - "TCL_LIBRARY=${TCL_BUILDTIME_LIBRARY}" \ - "TCLLIBPATH=../../pkgs" test \ - "TCLSH_PROG=../../${TCLTEST_EXE}"; ) \ + @for i in $(PKGS_DIR)/* ; do \ + if [ -d $$i ] ; then \ + pkg=`basename $$i`; \ + if [ -f $(PKG_DIR)/$$pkg/Makefile ] ; then \ + echo "Testing package '$$pkg'"; \ + ( cd $(PKG_DIR)/$$pkg; $(MAKE) \ + "@LD_LIBRARY_PATH_VAR@=../..:$${@LD_LIBRARY_PATH_VAR@}" \ + "TCL_LIBRARY=${TCL_BUILDTIME_LIBRARY}" \ + "TCLLIBPATH=../../pkgs" test \ + "TCLSH_PROG=../../${TCLTEST_EXE}"; ) \ + fi; \ fi; \ - fi; \ done clean-packages: - @for i in $(PKGS_DIR)/*; do \ - if [ -d $$i ]; then \ - pkg=`basename $$i`; \ - if [ -f $(PKG_DIR)/$$pkg/Makefile ]; then \ - ( cd $(PKG_DIR)/$$pkg; $(MAKE) clean; ) \ + @for i in $(PKGS_DIR)/* ; do \ + if [ -d $$i ] ; then \ + pkg=`basename $$i`; \ + if [ -f $(PKG_DIR)/$$pkg/Makefile ] ; then \ + ( cd $(PKG_DIR)/$$pkg; $(MAKE) clean; ) \ + fi; \ fi; \ - fi; \ done distclean-packages: - @for i in $(PKGS_DIR)/*; do \ - if [ -d $$i ]; then \ - pkg=`basename $$i`; \ - if [ -f $(PKG_DIR)/$$pkg/Makefile ]; then \ - ( cd $(PKG_DIR)/$$pkg; $(MAKE) distclean; ) \ + @for i in $(PKGS_DIR)/* ; do \ + if [ -d $$i ] ; then \ + pkg=`basename $$i`; \ + if [ -f $(PKG_DIR)/$$pkg/Makefile ] ; then \ + ( cd $(PKG_DIR)/$$pkg; $(MAKE) distclean; ) \ + fi; \ + rm -rf $(PKG_DIR)/$$pkg; \ fi; \ - rm -rf $(PKG_DIR)/$$pkg; \ - fi; \ done; \ rm -rf $(PKG_DIR) dist-packages: configure-packages @rm -rf $(DISTROOT)/pkgs; \ mkdir -p $(DISTROOT)/pkgs; \ - for i in $(PKGS_DIR)/*; do \ - if [ -d $$i ]; then \ - pkg=`basename $$i`; \ - if [ -f $(PKG_DIR)/$$pkg/Makefile ]; then \ - ( cd $(PKG_DIR)/$$pkg; $(MAKE) dist \ - "DIST_ROOT=$(DISTROOT)/pkgs"; ) || exit $$?; \ + for i in $(PKGS_DIR)/* ; do \ + if [ -d $$i ] ; then \ + pkg=`basename $$i`; \ + if [ -f $(PKG_DIR)/$$pkg/Makefile ] ; then \ + ( cd $(PKG_DIR)/$$pkg; $(MAKE) dist \ + "DIST_ROOT=$(DISTROOT)/pkgs"; ) || exit $$?; \ + fi; \ fi; \ - fi; \ done #-------------------------------------------------------------------------- @@ -2039,14 +2047,14 @@ genscript: checkstubs: $(TCL_LIB_FILE) -@for i in `nm -p $(TCL_LIB_FILE) \ | awk '$$2 ~ /^[TDBCS]$$/ { sub("^_", "", $$3); print $$3 }' \ - | sort -n`; do \ + | sort -n` ; do \ match=0; \ - for j in $(TCL_DECLS); do \ - if [ `grep -c "$$i *(" $$j` -gt 0 ]; then \ + for j in $(TCL_DECLS) ; do \ + if [ `grep -c "$$i *(" $$j` -gt 0 ] ; then \ match=1; \ fi; \ done; \ - if [ $$match -eq 0 ]; then \ + if [ $$match -eq 0 ] ; then \ echo $$i; \ fi; \ done @@ -2058,14 +2066,14 @@ checkstubs: $(TCL_LIB_FILE) checkdoc: $(TCL_LIB_FILE) -@for i in `nm -p $(TCL_LIB_FILE) | awk '$$3 ~ /Tcl_/ { print $$3 }' \ - | grep -v 'Cmd$$' | sort -n`; do \ + | grep -v 'Cmd$$' | sort -n` ; do \ match=0; \ - for j in $(TOP_DIR)/doc/*.3; do \ - if [ `grep '\-' $$j | grep -c $$i` -gt 0 ]; then \ + for j in $(TOP_DIR)/doc/*.3 ; do \ + if [ `grep '\-' $$j | grep -c $$i` -gt 0 ] ; then \ match=1; \ fi; \ done; \ - if [ $$match -eq 0 ]; then \ + if [ $$match -eq 0 ] ; then \ echo $$i; \ fi; \ done @@ -2115,6 +2123,8 @@ DISTROOT = /tmp/dist DISTNAME = tcl${VERSION}${PATCH_LEVEL} ZIPNAME = tcl${MAJOR_VERSION}${MINOR_VERSION}${PATCH_LEVEL}-src.zip DISTDIR = $(DISTROOT)/$(DISTNAME) +BUILTIN_PACKAGE_LIST = http opt msgcat reg dde tcltest platform + $(UNIX_DIR)/configure: $(UNIX_DIR)/configure.ac $(UNIX_DIR)/tcl.m4 \ $(UNIX_DIR)/aclocal.m4 cd $(UNIX_DIR); autoconf @@ -2149,11 +2159,10 @@ dist: $(UNIX_DIR)/configure $(UNIX_DIR)/tclConfig.h.in $(UNIX_DIR)/tcl.pc.in $(M @mkdir $(DISTDIR)/library cp -p $(TOP_DIR)/license.terms $(TOP_DIR)/library/*.tcl \ $(TOP_DIR)/library/tclIndex $(DISTDIR)/library - for i in http opt msgcat reg dde tcltest platform; \ - do \ - mkdir $(DISTDIR)/library/$$i ;\ - cp -p $(TOP_DIR)/library/$$i/*.tcl $(DISTDIR)/library/$$i; \ - done; + for i in $(BUILTIN_PACKAGE_LIST) ; do \ + mkdir $(DISTDIR)/library/$$i;\ + cp -p $(TOP_DIR)/library/$$i/*.tcl $(DISTDIR)/library/$$i; \ + done @mkdir $(DISTDIR)/library/encoding cp -p $(TOP_DIR)/library/encoding/*.enc $(DISTDIR)/library/encoding @mkdir $(DISTDIR)/library/msgs @@ -2222,14 +2231,16 @@ dist: $(UNIX_DIR)/configure $(UNIX_DIR)/tclConfig.h.in $(UNIX_DIR)/tcl.pc.in $(M @mkdir $(DISTDIR)/pkgs cp $(TOP_DIR)/pkgs/README $(DISTDIR)/pkgs cp $(TOP_DIR)/pkgs/package.list.txt $(DISTDIR)/pkgs - for i in `ls $(DISTROOT)/pkgs/*.tar.gz 2> /dev/null`; do \ + for i in `ls $(DISTROOT)/pkgs/*.tar.gz 2> /dev/null` ; do \ tar -C $(DISTDIR)/pkgs -xzf "$$i"; \ done alldist: dist rm -f $(DISTROOT)/$(DISTNAME)-src.tar.gz $(DISTROOT)/$(ZIPNAME) - cd $(DISTROOT); tar cf $(DISTNAME)-src.tar $(DISTNAME); \ - gzip -9 $(DISTNAME)-src.tar; zip -qr8 $(ZIPNAME) $(DISTNAME) + ( cd $(DISTROOT); \ + tar cf $(DISTNAME)-src.tar $(DISTNAME); \ + gzip -9 $(DISTNAME)-src.tar; \ + zip -qr8 $(ZIPNAME) $(DISTNAME) ) #-------------------------------------------------------------------------- # This target creates the HTML folder for Tcl & Tk and places it in -- cgit v0.12 From acbdbb87fb4a7dca61c34f8e9a3b212c3a144e50 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Sat, 29 Sep 2018 20:39:10 +0000 Subject: Add support for wine. So windows test-cases can now be run on Linux/Mac/whatever. --- tests/oo.test | 2 +- win/Makefile.in | 9 +++++---- win/configure | 38 ++++++++++++++++++++++++++++++++++++++ win/tcl.m4 | 1 + 4 files changed, 45 insertions(+), 5 deletions(-) diff --git a/tests/oo.test b/tests/oo.test index 033daf5..4e50904 100644 --- a/tests/oo.test +++ b/tests/oo.test @@ -4007,7 +4007,7 @@ test oo-34.10 {TIP 516: slots - resolution} -setup { } } lappend result [info class mixin 516test::516a] - # Must not remove class with just simple name match + # Must not remove class with just simple name match oo::define 516test::516a { mixin -remove 516b } diff --git a/win/Makefile.in b/win/Makefile.in index 0f15152..58f778e 100644 --- a/win/Makefile.in +++ b/win/Makefile.in @@ -157,6 +157,7 @@ SHARED_LIBRARIES = $(TCL_DLL_FILE) @ZLIB_DLL_FILE@ STATIC_LIBRARIES = $(TCL_LIB_FILE) TCLSH = tclsh$(VER)${EXESUFFIX} +WINE = @WINE@ CAT32 = cat32$(EXEEXT) MAN2TCL = man2tcl$(EXEEXT) @@ -864,16 +865,16 @@ test: test-tcl test-packages test-tcl: binaries $(TCLSH) $(CAT32) $(TEST_DLL_FILE) TCL_LIBRARY="$(LIBRARY_DIR)"; export TCL_LIBRARY; \ - ./$(TCLSH) "$(ROOT_DIR_NATIVE)/tests/all.tcl" $(TESTFLAGS) \ + $(WINE) ./$(TCLSH) "$(ROOT_DIR_NATIVE)/tests/all.tcl" $(TESTFLAGS) \ -load "package ifneeded Tcltest ${VERSION}@TCL_PATCH_LEVEL@ [list load [file normalize ${TEST_DLL_FILE}] Tcltest]; \ package ifneeded tcltests 0.1 \"[list source [file normalize $(ROOT_DIR_NATIVE)/tests/tcltests.tcl]];package provide tcltests 0.1\"; \ package ifneeded dde 1.4.0 [list load [file normalize ${DDE_DLL_FILE}] dde]; \ - package ifneeded registry 1.3.2 [list load [file normalize ${REG_DLL_FILE}] registry]" | ./$(CAT32) + package ifneeded registry 1.3.2 [list load [file normalize ${REG_DLL_FILE}] registry]" | $(WINE) ./$(CAT32) # Useful target to launch a built tclsh with the proper path,... runtest: binaries $(TCLSH) $(TEST_DLL_FILE) @TCL_LIBRARY="$(LIBRARY_DIR)"; export TCL_LIBRARY; \ - ./$(TCLSH) $(TESTFLAGS) -load "package ifneeded Tcltest ${VERSION}@TCL_PATCH_LEVEL@ [list load [file normalize ${TEST_DLL_FILE}] Tcltest]; \ + $(WINE) ./$(TCLSH) $(TESTFLAGS) -load "package ifneeded Tcltest ${VERSION}@TCL_PATCH_LEVEL@ [list load [file normalize ${TEST_DLL_FILE}] Tcltest]; \ package ifneeded tcltests 0.1 \"[list source [file normalize $(ROOT_DIR_NATIVE)/tests/tcltests.tcl]];package provide tcltests 0.1\"; \ package ifneeded dde 1.4.0 [list load [file normalize ${DDE_DLL_FILE}] dde]; \ package ifneeded registry 1.3.2 [list load [file normalize ${REG_DLL_FILE}] registry]" $(SCRIPT) @@ -882,7 +883,7 @@ runtest: binaries $(TCLSH) $(TEST_DLL_FILE) # `make shell SCRIPT=foo.tcl` shell: binaries @TCL_LIBRARY="$(LIBRARY_DIR)"; export TCL_LIBRARY; \ - ./$(TCLSH) $(SCRIPT) + $(WINE) ./$(TCLSH) $(SCRIPT) # This target can be used to run tclsh inside either gdb or insight gdb: binaries diff --git a/win/configure b/win/configure index 8cecccc..06f1f75 100755 --- a/win/configure +++ b/win/configure @@ -717,6 +717,7 @@ CFLAGS_WARNING CFLAGS_OPTIMIZE CFLAGS_DEBUG DL_LIBS +WINE CYGPATH SHARED_BUILD SET_MAKE @@ -3830,6 +3831,43 @@ $as_echo "no" >&6; } fi + # Extract the first word of "wine", so it can be a program name with args. +set dummy wine; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_WINE+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$WINE"; then + ac_cv_prog_WINE="$WINE" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_WINE="wine" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +WINE=$ac_cv_prog_WINE +if test -n "$WINE"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $WINE" >&5 +$as_echo "$WINE" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + SHLIB_SUFFIX=".dll" diff --git a/win/tcl.m4 b/win/tcl.m4 index a678009..32df552 100644 --- a/win/tcl.m4 +++ b/win/tcl.m4 @@ -517,6 +517,7 @@ AC_DEFUN([SC_CONFIG_CFLAGS], [ AC_DEFINE(MODULE_SCOPE, [extern], [No need to mark inidividual symbols as hidden]) AC_CHECK_PROG(CYGPATH, cygpath, cygpath -m, echo) + AC_CHECK_PROG(WINE, wine, wine,) SHLIB_SUFFIX=".dll" -- cgit v0.12 From f08ec44049c64c8831a7a9ec18d4efb4cab3bc6f Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Sun, 30 Sep 2018 10:17:44 +0000 Subject: Adding logic for static builds to load a properly named zipfile in the present working directory if that zipfile was not present in either the install directory or the source directory. --- generic/tclZipfs.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c index 19673c8..e634754 100644 --- a/generic/tclZipfs.c +++ b/generic/tclZipfs.c @@ -2933,6 +2933,11 @@ Tcl_Obj *TclZipfs_TclLibrary(void) { if(TclZipfs_AppHook_FindTclInit(CFG_RUNTIME_SCRDIR "/" CFG_RUNTIME_ZIPFILE)==TCL_OK) { return Tcl_NewStringObj(zipfs_literal_tcl_library,-1); } + if(TclZipfs_AppHook_FindTclInit(CFG_RUNTIME_ZIPFILE)==TCL_OK) { + return Tcl_NewStringObj(zipfs_literal_tcl_library,-1); + } +#else + #endif } if(zipfs_literal_tcl_library) { -- cgit v0.12 From d0ac3d107b9e4e09f8bdf5f6e1d6f6c7bc24495d Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Sun, 30 Sep 2018 22:21:50 +0000 Subject: Adding Zipfile to the list of products produced for builds --- win/Makefile.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/win/Makefile.in b/win/Makefile.in index 58f778e..f36c38b 100644 --- a/win/Makefile.in +++ b/win/Makefile.in @@ -473,7 +473,7 @@ all: binaries libraries doc packages tcltest: $(TCLSH) $(TEST_DLL_FILE) -binaries: $(TCL_STUB_LIB_FILE) @LIBRARIES@ winextensions $(TCLSH) +binaries: $(TCL_STUB_LIB_FILE) @LIBRARIES@ winextensions ${TCL_ZIP_FILE} $(TCLSH) winextensions: ${DDE_DLL_FILE} ${REG_DLL_FILE} -- cgit v0.12 From 38dcdcb3006ac9a75e0aadd764fa9c456c001568 Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Sun, 30 Sep 2018 23:12:13 +0000 Subject: Fixed the arguments that zipfs mount was sending in auto.tcl. Standardized on 8 spaces instead of tab characters inside of that file. (The indent pattern was not consistent and editing the file in a modern editor was... painful.) Added logic to check the current path for a zipfile with the name of the package being loaded. This allows wish to load tcl_library from a zip file in the same directory as the executable. And in fact, any package which uses the tcl_findLibrary mechanism with get this behavior for free. --- library/auto.tcl | 521 +++++++++++++++++++++++++++---------------------------- 1 file changed, 260 insertions(+), 261 deletions(-) diff --git a/library/auto.tcl b/library/auto.tcl index d8f9d88..5ab056b 100644 --- a/library/auto.tcl +++ b/library/auto.tcl @@ -22,179 +22,178 @@ proc auto_reset {} { global auto_execs auto_index auto_path if {[array exists auto_index]} { - foreach cmdName [array names auto_index] { - set fqcn [namespace which $cmdName] - if {$fqcn eq ""} { - continue - } - rename $fqcn {} - } + foreach cmdName [array names auto_index] { + set fqcn [namespace which $cmdName] + if {$fqcn eq ""} { + continue + } + rename $fqcn {} + } } unset -nocomplain auto_execs auto_index ::tcl::auto_oldpath if {[catch {llength $auto_path}]} { - set auto_path [list [info library]] + set auto_path [list [info library]] } elseif {[info library] ni $auto_path} { - lappend auto_path [info library] + lappend auto_path [info library] } } # tcl_findLibrary -- # -# This is a utility for extensions that searches for a library directory -# using a canonical searching algorithm. A side effect is to source the -# initialization script and set a global library variable. +# This is a utility for extensions that searches for a library directory +# using a canonical searching algorithm. A side effect is to source the +# initialization script and set a global library variable. # # Arguments: -# basename Prefix of the directory name, (e.g., "tk") -# version Version number of the package, (e.g., "8.0") -# patch Patchlevel of the package, (e.g., "8.0.3") -# initScript Initialization script to source (e.g., tk.tcl) -# enVarName environment variable to honor (e.g., TK_LIBRARY) -# varName Global variable to set when done (e.g., tk_library) +# basename Prefix of the directory name, (e.g., "tk") +# version Version number of the package, (e.g., "8.0") +# patch Patchlevel of the package, (e.g., "8.0.3") +# initScript Initialization script to source (e.g., tk.tcl) +# enVarName environment variable to honor (e.g., TK_LIBRARY) +# varName Global variable to set when done (e.g., tk_library) proc tcl_findLibrary {basename version patch initScript enVarName varName} { upvar #0 $varName the_library global auto_path env tcl_platform - set dirs {} set errors {} # The C application may have hardwired a path, which we honor if {[info exists the_library] && $the_library ne ""} { - lappend dirs $the_library + lappend dirs $the_library } else { - # Do the canonical search - - # 1. From an environment variable, if it exists. Placing this first - # gives the end-user ultimate control to work-around any bugs, or - # to customize. - + # Do the canonical search + # + # 1. From an environment variable, if it exists. Placing this first + # gives the end-user ultimate control to work-around any bugs, or + # to customize. if {[info exists env($enVarName)]} { lappend dirs $env($enVarName) } - catch { - set found 0 - set root [zipfs root] - set mountpoint [file join $root lib [string tolower $basename]] - lappend dirs [file join $root app ${basename}_library] - lappend dirs [file join $root lib $mountpoint ${basename}_library] - lappend dirs [file join $root lib $mountpoint] - if {![zipfs exists [file join $root app ${basename}_library]] && ![zipfs exists $mountpoint]} { - set found 0 - foreach pkgdat [info loaded] { - lassign $pkgdat dllfile dllpkg - if {[string tolower $dllpkg] ne [string tolower $basename]} continue - if {$dllfile eq {}} { - # Loaded statically - break - } - set found 1 - zipfs mount $dllfile $mountpoint - break - } - if {!$found} { - set paths {} - lappend paths [file join $root app] - lappend paths [::${basename}::pkgconfig get libdir,runtime] - lappend paths [::${basename}::pkgconfig get bindir,runtime] - if {[catch {::${basename}::pkgconfig get zipfile,runtime} zipfile]} { - set zipfile [string tolower "lib${basename}_[join [list {*}[split $version .] {*}$patch] _].zip"] - } - foreach path $paths { - set archive [file join $path $zipfile] - if {![file exists $archive]} continue - zipfs mount $archive $mountpoint - if {[zipfs exists [file join $mountpoint ${basename}_library $initScript]]} { - lappend dirs [file join $mountpoint ${basename}_library] - set found 1 - break - } elseif {[zipfs exists [file join $mountpoint $initScript]]} { - lappend dirs [file join $mountpoint $initScript] + catch { + set found 0 + set root [zipfs root] + set mountpoint [file join $root lib [string tolower $basename]] + lappend dirs [file join $root app ${basename}_library] + lappend dirs [file join $root lib $mountpoint ${basename}_library] + lappend dirs [file join $root lib $mountpoint] + if {![zipfs exists [file join $root app ${basename}_library]] \ + && ![zipfs exists $mountpoint]} { + set found 0 + foreach pkgdat [info loaded] { + lassign $pkgdat dllfile dllpkg + if {[string tolower $dllpkg] ne [string tolower $basename]} continue + if {$dllfile eq {}} { + # Loaded statically + break + } set found 1 + zipfs mount $mountpoint $dllfile break - } else { - catch {zipfs unmount $archive} + } + if {!$found} { + set paths {} + lappend paths [file join $root app] + lappend paths [::${basename}::pkgconfig get libdir,runtime] + lappend paths [::${basename}::pkgconfig get bindir,runtime] + if {[catch {::${basename}::pkgconfig get zipfile,runtime} zipfile]} { + set zipfile [string tolower \ + "lib${basename}_[join [list {*}[split $version .] {*}$patch] _].zip"] + } + lappend paths [file dirname [file join [pwd] [info nameofexecutable]]] + foreach path $paths { + set archive [file join $path $zipfile] + if {![file exists $archive]} continue + zipfs mount $mountpoint $archive + if {[zipfs exists [file join $mountpoint ${basename}_library $initScript]]} { + lappend dirs [file join $mountpoint ${basename}_library] + set found 1 + break + } elseif {[zipfs exists [file join $mountpoint $initScript]]} { + lappend dirs [file join $mountpoint $initScript] + set found 1 + break + } else { + catch {zipfs unmount $archive} + } } } } - } - } - - # 2. In the package script directory registered within the - # configuration of the package itself. - - catch { - lappend dirs [::${basename}::pkgconfig get scriptdir,runtime] - } - - # 3. Relative to auto_path directories. This checks relative to the - # Tcl library as well as allowing loading of libraries added to the - # auto_path that is not relative to the core library or binary paths. - foreach d $auto_path { - lappend dirs [file join $d $basename$version] - if {$tcl_platform(platform) eq "unix" - && $tcl_platform(os) eq "Darwin"} { - # 4. On MacOSX, check the Resources/Scripts subdir too - lappend dirs [file join $d $basename$version Resources Scripts] - } - } - - # 3. Various locations relative to the executable - # ../lib/foo1.0 (From bin directory in install hierarchy) - # ../../lib/foo1.0 (From bin/arch directory in install hierarchy) - # ../library (From unix directory in build hierarchy) - # - # Remaining locations are out of date (when relevant, they ought to be - # covered by the $::auto_path seach above) and disabled. - # - # ../../library (From unix/arch directory in build hierarchy) - # ../../foo1.0.1/library - # (From unix directory in parallel build hierarchy) - # ../../../foo1.0.1/library - # (From unix/arch directory in parallel build hierarchy) + } ; # catch + + # 2. In the package script directory registered within the + # configuration of the package itself. + catch { + lappend dirs [::${basename}::pkgconfig get scriptdir,runtime] + } + + # 3. Relative to auto_path directories. This checks relative to the + # Tcl library as well as allowing loading of libraries added to the + # auto_path that is not relative to the core library or binary paths. + foreach d $auto_path { + lappend dirs [file join $d $basename$version] + if {$tcl_platform(platform) eq "unix" + && $tcl_platform(os) eq "Darwin"} { + # 4. On MacOSX, check the Resources/Scripts subdir too + lappend dirs [file join $d $basename$version Resources Scripts] + } + } + + # 3. Various locations relative to the executable + # ../lib/foo1.0 (From bin directory in install hierarchy) + # ../../lib/foo1.0 (From bin/arch directory in install hierarchy) + # ../library (From unix directory in build hierarchy) + # + # Remaining locations are out of date (when relevant, they ought to be + # covered by the $::auto_path seach above) and disabled. + # + # ../../library (From unix/arch directory in build hierarchy) + # ../../foo1.0.1/library + # (From unix directory in parallel build hierarchy) + # ../../../foo1.0.1/library + # (From unix/arch directory in parallel build hierarchy) set parentDir [file dirname [file dirname [info nameofexecutable]]] set grandParentDir [file dirname $parentDir] lappend dirs [file join $parentDir lib $basename$version] lappend dirs [file join $grandParentDir lib $basename$version] lappend dirs [file join $parentDir library] - if {0} { - lappend dirs [file join $grandParentDir library] - lappend dirs [file join $grandParentDir $basename$patch library] - lappend dirs [file join [file dirname $grandParentDir] \ - $basename$patch library] - } + if {0} { + lappend dirs [file join $grandParentDir library] + lappend dirs [file join $grandParentDir $basename$patch library] + lappend dirs [file join [file dirname $grandParentDir] \ + $basename$patch library] + } } # uniquify $dirs in order array set seen {} foreach i $dirs { - # Make sure $i is unique under normalization. Avoid repeated [source]. - if {[interp issafe]} { - # Safe interps have no [file normalize]. - set norm $i - } else { - set norm [file normalize $i] - } - if {[info exists seen($norm)]} { - continue - } - set seen($norm) {} - - set the_library $i - set file [file join $i $initScript] - - # source everything when in a safe interpreter because we have a - # source command, but no file exists command - - if {[interp issafe] || [file exists $file]} { - if {![catch {uplevel #0 [list source $file]} msg opts]} { - return - } - append errors "$file: $msg\n" - append errors [dict get $opts -errorinfo]\n + # Make sure $i is unique under normalization. Avoid repeated [source]. + if {[interp issafe]} { + # Safe interps have no [file normalize]. + set norm $i + } else { + set norm [file normalize $i] + } + if {[info exists seen($norm)]} { + continue + } + set seen($norm) {} + set the_library $i + set file [file join $i $initScript] + + # source everything when in a safe interpreter because we have a + # source command, but no file exists command + + if {[interp issafe] || [file exists $file]} { + if {![catch {uplevel #0 [list source $file]} msg opts]} { + return } + append errors "$file: $msg\n" + append errors [dict get $opts -errorinfo]\n + } } unset -nocomplain the_library set msg "Can't find a usable $initScript in the following directories: \n" @@ -215,7 +214,7 @@ proc tcl_findLibrary {basename version patch initScript enVarName varName} { # can't create the special parser and mess with its commands. if {[interp issafe]} { - return ;# Stop sourcing the file here + return ;# Stop sourcing the file here } # auto_mkindex -- @@ -225,11 +224,11 @@ if {[interp issafe]} { # relevant files. # # Arguments: -# dir - Name of the directory in which to create an index. +# dir - Name of the directory in which to create an index. -# args - Any number of additional arguments giving the names of files -# within dir. If no additional are given auto_mkindex will look -# for *.tcl. +# args - Any number of additional arguments giving the names of files +# within dir. If no additional are given auto_mkindex will look +# for *.tcl. proc auto_mkindex {dir args} { if {[interp issafe]} { @@ -247,17 +246,17 @@ proc auto_mkindex {dir args} { append index "# element name is the name of a command and the value is\n" append index "# a script that loads the command.\n\n" if {![llength $args]} { - set args *.tcl + set args *.tcl } auto_mkindex_parser::init foreach file [lsort [glob -- {*}$args]] { - try { - append index [auto_mkindex_parser::mkindex $file] - } on error {msg opts} { - cd $oldDir - return -options $opts $msg - } + try { + append index [auto_mkindex_parser::mkindex $file] + } on error {msg opts} { + cd $oldDir + return -options $opts $msg + } } auto_mkindex_parser::cleanup @@ -282,39 +281,39 @@ proc auto_mkindex_old {dir args} { append index "# element name is the name of a command and the value is\n" append index "# a script that loads the command.\n\n" if {![llength $args]} { - set args *.tcl + set args *.tcl } foreach file [lsort [glob -- {*}$args]] { - set f "" - set error [catch { - set f [open $file] - while {[gets $f line] >= 0} { - if {[regexp {^proc[ ]+([^ ]*)} $line match procName]} { - set procName [lindex [auto_qualify $procName "::"] 0] - append index "set [list auto_index($procName)]" - append index " \[list source \[file join \$dir [list $file]\]\]\n" - } - } - close $f - } msg opts] - if {$error} { - catch {close $f} - cd $oldDir - return -options $opts $msg - } + set f "" + set error [catch { + set f [open $file] + while {[gets $f line] >= 0} { + if {[regexp {^proc[ ]+([^ ]*)} $line match procName]} { + set procName [lindex [auto_qualify $procName "::"] 0] + append index "set [list auto_index($procName)]" + append index " \[list source \[file join \$dir [list $file]\]\]\n" + } + } + close $f + } msg opts] + if {$error} { + catch {close $f} + cd $oldDir + return -options $opts $msg + } } set f "" set error [catch { - set f [open tclIndex w] - puts -nonewline $f $index - close $f - cd $oldDir + set f [open tclIndex w] + puts -nonewline $f $index + close $f + cd $oldDir } msg opts] if {$error} { - catch {close $f} - cd $oldDir - error $msg $info $code - return -options $opts $msg + catch {close $f} + cd $oldDir + error $msg $info $code + return -options $opts $msg } } @@ -331,50 +330,50 @@ namespace eval auto_mkindex_parser { variable imports "" ;# keeps track of all imported cmds variable initCommands ;# list of commands that create aliases if {![info exists initCommands]} { - set initCommands [list] + set initCommands [list] } proc init {} { - variable parser - variable initCommands - - if {![interp issafe]} { - set parser [interp create -safe] - $parser hide info - $parser hide rename - $parser hide proc - $parser hide namespace - $parser hide eval - $parser hide puts - foreach ns [$parser invokehidden namespace children ::] { - # MUST NOT DELETE "::tcl" OR BAD THINGS HAPPEN! - if {$ns eq "::tcl"} continue - $parser invokehidden namespace delete $ns - } - foreach cmd [$parser invokehidden info commands ::*] { - $parser invokehidden rename $cmd {} - } - $parser invokehidden proc unknown {args} {} - - # We'll need access to the "namespace" command within the - # interp. Put it back, but move it out of the way. - - $parser expose namespace - $parser invokehidden rename namespace _%@namespace - $parser expose eval - $parser invokehidden rename eval _%@eval - - # Install all the registered psuedo-command implementations - - foreach cmd $initCommands { - eval $cmd - } - } + variable parser + variable initCommands + + if {![interp issafe]} { + set parser [interp create -safe] + $parser hide info + $parser hide rename + $parser hide proc + $parser hide namespace + $parser hide eval + $parser hide puts + foreach ns [$parser invokehidden namespace children ::] { + # MUST NOT DELETE "::tcl" OR BAD THINGS HAPPEN! + if {$ns eq "::tcl"} continue + $parser invokehidden namespace delete $ns + } + foreach cmd [$parser invokehidden info commands ::*] { + $parser invokehidden rename $cmd {} + } + $parser invokehidden proc unknown {args} {} + + # We'll need access to the "namespace" command within the + # interp. Put it back, but move it out of the way. + + $parser expose namespace + $parser invokehidden rename namespace _%@namespace + $parser expose eval + $parser invokehidden rename eval _%@eval + + # Install all the registered psuedo-command implementations + + foreach cmd $initCommands { + eval $cmd + } + } } proc cleanup {} { - variable parser - interp delete $parser - unset parser + variable parser + interp delete $parser + unset parser } } @@ -386,7 +385,7 @@ namespace eval auto_mkindex_parser { # that represents the index file. # # Arguments: -# file Name of Tcl source file to be indexed. +# file Name of Tcl source file to be indexed. proc auto_mkindex_parser::mkindex {file} { variable parser @@ -463,9 +462,9 @@ proc auto_mkindex_parser::slavehook {cmd} { # "tclIndex" file for auto-loading. # # Arguments: -# name Name of command recognized in Tcl files. -# arglist Argument list for command. -# body Implementation of command to handle indexing. +# name Name of command recognized in Tcl files. +# arglist Argument list for command. +# body Implementation of command to handle indexing. proc auto_mkindex_parser::command {name arglist body} { hook [list auto_mkindex_parser::commandInit $name $arglist $body] @@ -477,9 +476,9 @@ proc auto_mkindex_parser::command {name arglist body} { # called when the interpreter used by the parser is created. # # Arguments: -# name Name of command recognized in Tcl files. -# arglist Argument list for command. -# body Implementation of command to handle indexing. +# name Name of command recognized in Tcl files. +# arglist Argument list for command. +# body Implementation of command to handle indexing. proc auto_mkindex_parser::commandInit {name arglist body} { variable parser @@ -501,15 +500,15 @@ proc auto_mkindex_parser::commandInit {name arglist body} { set exportCmd [list _%@namespace export [namespace tail $name]] $parser eval [list _%@namespace eval $ns $exportCmd] - # The following proc definition does not work if you want to tolerate - # space or something else diabolical in the procedure name, (i.e., - # space in $alias). The following does not work: - # "_%@eval {$alias} \$args" - # because $alias gets concat'ed to $args. The following does not work - # because $cmd is somehow undefined - # "set cmd {$alias} \; _%@eval {\$cmd} \$args" - # A gold star to someone that can make test autoMkindex-3.3 work - # properly + # The following proc definition does not work if you want to tolerate + # space or something else diabolical in the procedure name, (i.e., + # space in $alias). The following does not work: + # "_%@eval {$alias} \$args" + # because $alias gets concat'ed to $args. The following does not work + # because $cmd is somehow undefined + # "set cmd {$alias} \; _%@eval {\$cmd} \$args" + # A gold star to someone that can make test autoMkindex-3.3 work + # properly set alias [namespace tail $fakeName] $parser invokehidden proc $name {args} "_%@eval {$alias} \$args" @@ -531,7 +530,7 @@ proc auto_mkindex_parser::commandInit {name arglist body} { # simple name. That way, the Tcl autoloader will recognize it properly. # # Arguments: -# name - Name that is being added to index. +# name - Name that is being added to index. proc auto_mkindex_parser::fullname {name} { variable contextStack @@ -563,7 +562,7 @@ proc auto_mkindex_parser::fullname {name} { # *right*, in one place. # # Arguments: -# name - Name that is being added to index. +# name - Name that is being added to index. proc auto_mkindex_parser::indexEntry {name} { variable index @@ -577,8 +576,8 @@ proc auto_mkindex_parser::indexEntry {name} { set filenameParts [file split $scriptFile] append index [format \ - {set auto_index(%s) [list source [file join $dir %s]]%s} \ - $name $filenameParts \n] + {set auto_index(%s) [list source [file join $dir %s]]%s} \ + $name $filenameParts \n] return } @@ -606,22 +605,22 @@ auto_mkindex_parser::command proc {name args} { auto_mkindex_parser::hook { try { - package require tbcload + package require tbcload } on error {} { - # OK, don't have it so do nothing + # OK, don't have it so do nothing } on ok {} { - if {[namespace which -command tbcload::bcproc] eq ""} { - auto_load tbcload::bcproc - } - load {} tbcload $auto_mkindex_parser::parser - - # AUTO MKINDEX: tbcload::bcproc name arglist body - # Adds an entry to the auto index list for the given pre-compiled - # procedure name. - - auto_mkindex_parser::commandInit tbcload::bcproc {name args} { - indexEntry $name - } + if {[namespace which -command tbcload::bcproc] eq ""} { + auto_load tbcload::bcproc + } + load {} tbcload $auto_mkindex_parser::parser + + # AUTO MKINDEX: tbcload::bcproc name arglist body + # Adds an entry to the auto index list for the given pre-compiled + # procedure name. + + auto_mkindex_parser::commandInit tbcload::bcproc {name args} { + indexEntry $name + } } } @@ -646,7 +645,7 @@ auto_mkindex_parser::command namespace {op args} { set args [lrange $args 1 end] set contextStack [linsert $contextStack 0 $name] - $parser eval [list _%@namespace eval $name] $args + $parser eval [list _%@namespace eval $name] $args set contextStack [lrange $contextStack 1 end] } import { @@ -659,22 +658,22 @@ auto_mkindex_parser::command namespace {op args} { } catch {$parser eval "_%@namespace import $args"} } - ensemble { - variable parser - variable contextStack - if {[lindex $args 0] eq "create"} { - set name ::[join [lreverse $contextStack] ::] - catch { - set name [dict get [lrange $args 1 end] -command] - if {![string match ::* $name]} { - set name ::[join [lreverse $contextStack] ::]$name - } - regsub -all ::+ $name :: name - } - # create artifical proc to force an entry in the tclIndex - $parser eval [list ::proc $name {} {}] - } - } + ensemble { + variable parser + variable contextStack + if {[lindex $args 0] eq "create"} { + set name ::[join [lreverse $contextStack] ::] + catch { + set name [dict get [lrange $args 1 end] -command] + if {![string match ::* $name]} { + set name ::[join [lreverse $contextStack] ::]$name + } + regsub -all ::+ $name :: name + } + # create artifical proc to force an entry in the tclIndex + $parser eval [list ::proc $name {} {}] + } + } } } @@ -682,12 +681,12 @@ auto_mkindex_parser::command namespace {op args} { # Adds an entry to the auto index list for the given class name. auto_mkindex_parser::command oo::class {op name {body ""}} { if {$op eq "create"} { - indexEntry $name + indexEntry $name } } auto_mkindex_parser::command class {op name {body ""}} { if {$op eq "create"} { - indexEntry $name + indexEntry $name } } -- cgit v0.12 From 3dc49c128c82cd1403c59d289b223f6f48376604 Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Mon, 1 Oct 2018 16:41:12 +0000 Subject: Adjust when tcl consults zipfs until AFTER it has checked that env(TCL_LIBRARY) has not been set --- generic/tclInterp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generic/tclInterp.c b/generic/tclInterp.c index 550e2fe..90f02f9 100644 --- a/generic/tclInterp.c +++ b/generic/tclInterp.c @@ -397,7 +397,6 @@ Tcl_Init( " set scripts {{set tcl_library}}\n" " } else {\n" " set scripts {}\n" -" lappend scripts {zipfs tcl_library}\n" " if {[info exists env(TCL_LIBRARY)] && ($env(TCL_LIBRARY) ne {})} {\n" " lappend scripts {set env(TCL_LIBRARY)}\n" " lappend scripts {\n" @@ -410,6 +409,7 @@ Tcl_Init( " } else {\n" " lappend scripts {::tcl::pkgconfig get scriptdir,runtime}\n" " }\n" +" lappend scripts {zipfs tcl_library}\n" " lappend scripts {\n" "set parentDir [file dirname [file dirname [info nameofexecutable]]]\n" "set grandParentDir [file dirname $parentDir]\n" -- cgit v0.12 From 8f20d609b90b49cc6559eae2a74f8e6da88f6350 Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Mon, 1 Oct 2018 18:01:13 +0000 Subject: Eliminating whitespace changes introduced by the prior checkin --- library/auto.tcl | 524 ++++++++++++++++++++++++++++--------------------------- 1 file changed, 264 insertions(+), 260 deletions(-) diff --git a/library/auto.tcl b/library/auto.tcl index 5ab056b..7ef5681 100644 --- a/library/auto.tcl +++ b/library/auto.tcl @@ -22,178 +22,182 @@ proc auto_reset {} { global auto_execs auto_index auto_path if {[array exists auto_index]} { - foreach cmdName [array names auto_index] { - set fqcn [namespace which $cmdName] - if {$fqcn eq ""} { - continue - } - rename $fqcn {} - } + foreach cmdName [array names auto_index] { + set fqcn [namespace which $cmdName] + if {$fqcn eq ""} { + continue + } + rename $fqcn {} + } } unset -nocomplain auto_execs auto_index ::tcl::auto_oldpath if {[catch {llength $auto_path}]} { - set auto_path [list [info library]] + set auto_path [list [info library]] } elseif {[info library] ni $auto_path} { - lappend auto_path [info library] + lappend auto_path [info library] } } # tcl_findLibrary -- # -# This is a utility for extensions that searches for a library directory -# using a canonical searching algorithm. A side effect is to source the -# initialization script and set a global library variable. +# This is a utility for extensions that searches for a library directory +# using a canonical searching algorithm. A side effect is to source the +# initialization script and set a global library variable. # # Arguments: -# basename Prefix of the directory name, (e.g., "tk") -# version Version number of the package, (e.g., "8.0") -# patch Patchlevel of the package, (e.g., "8.0.3") -# initScript Initialization script to source (e.g., tk.tcl) -# enVarName environment variable to honor (e.g., TK_LIBRARY) -# varName Global variable to set when done (e.g., tk_library) +# basename Prefix of the directory name, (e.g., "tk") +# version Version number of the package, (e.g., "8.0") +# patch Patchlevel of the package, (e.g., "8.0.3") +# initScript Initialization script to source (e.g., tk.tcl) +# enVarName environment variable to honor (e.g., TK_LIBRARY) +# varName Global variable to set when done (e.g., tk_library) proc tcl_findLibrary {basename version patch initScript enVarName varName} { upvar #0 $varName the_library global auto_path env tcl_platform + set dirs {} set errors {} # The C application may have hardwired a path, which we honor if {[info exists the_library] && $the_library ne ""} { - lappend dirs $the_library + lappend dirs $the_library } else { - # Do the canonical search - # - # 1. From an environment variable, if it exists. Placing this first - # gives the end-user ultimate control to work-around any bugs, or - # to customize. + # Do the canonical search + + # 1. From an environment variable, if it exists. Placing this first + # gives the end-user ultimate control to work-around any bugs, or + # to customize. + if {[info exists env($enVarName)]} { lappend dirs $env($enVarName) } - catch { - set found 0 - set root [zipfs root] - set mountpoint [file join $root lib [string tolower $basename]] - lappend dirs [file join $root app ${basename}_library] - lappend dirs [file join $root lib $mountpoint ${basename}_library] - lappend dirs [file join $root lib $mountpoint] - if {![zipfs exists [file join $root app ${basename}_library]] \ - && ![zipfs exists $mountpoint]} { - set found 0 - foreach pkgdat [info loaded] { - lassign $pkgdat dllfile dllpkg - if {[string tolower $dllpkg] ne [string tolower $basename]} continue - if {$dllfile eq {}} { - # Loaded statically - break - } + catch { + set found 0 + set root [zipfs root] + set mountpoint [file join $root lib [string tolower $basename]] + lappend dirs [file join $root app ${basename}_library] + lappend dirs [file join $root lib $mountpoint ${basename}_library] + lappend dirs [file join $root lib $mountpoint] + if {![zipfs exists [file join $root app ${basename}_library]] \ + && ![zipfs exists $mountpoint]} { + set found 0 + foreach pkgdat [info loaded] { + lassign $pkgdat dllfile dllpkg + if {[string tolower $dllpkg] ne [string tolower $basename]} continue + if {$dllfile eq {}} { + # Loaded statically + break + } + set found 1 + zipfs mount $mountpoint $dllfile + break + } + if {!$found} { + set paths {} + lappend paths [file join $root app] + lappend paths [::${basename}::pkgconfig get libdir,runtime] + lappend paths [::${basename}::pkgconfig get bindir,runtime] + if {[catch {::${basename}::pkgconfig get zipfile,runtime} zipfile]} { + set zipfile [string tolower \ + "lib${basename}_[join [list {*}[split $version .] {*}$patch] _].zip"] + } + lappend paths [file dirname [file join [pwd] [info nameofexecutable]]] + foreach path $paths { + set archive [file join $path $zipfile] + if {![file exists $archive]} continue + zipfs mount $mountpoint $archive + if {[zipfs exists [file join $mountpoint ${basename}_library $initScript]]} { + lappend dirs [file join $mountpoint ${basename}_library] set found 1 - zipfs mount $mountpoint $dllfile break - } - if {!$found} { - set paths {} - lappend paths [file join $root app] - lappend paths [::${basename}::pkgconfig get libdir,runtime] - lappend paths [::${basename}::pkgconfig get bindir,runtime] - if {[catch {::${basename}::pkgconfig get zipfile,runtime} zipfile]} { - set zipfile [string tolower \ - "lib${basename}_[join [list {*}[split $version .] {*}$patch] _].zip"] - } - lappend paths [file dirname [file join [pwd] [info nameofexecutable]]] - foreach path $paths { - set archive [file join $path $zipfile] - if {![file exists $archive]} continue - zipfs mount $mountpoint $archive - if {[zipfs exists [file join $mountpoint ${basename}_library $initScript]]} { - lappend dirs [file join $mountpoint ${basename}_library] - set found 1 - break - } elseif {[zipfs exists [file join $mountpoint $initScript]]} { - lappend dirs [file join $mountpoint $initScript] - set found 1 - break - } else { - catch {zipfs unmount $archive} - } + } elseif {[zipfs exists [file join $mountpoint $initScript]]} { + lappend dirs [file join $mountpoint $initScript] + set found 1 + break + } else { + catch {zipfs unmount $archive} } } } - } ; # catch - - # 2. In the package script directory registered within the - # configuration of the package itself. - catch { - lappend dirs [::${basename}::pkgconfig get scriptdir,runtime] - } - - # 3. Relative to auto_path directories. This checks relative to the - # Tcl library as well as allowing loading of libraries added to the - # auto_path that is not relative to the core library or binary paths. - foreach d $auto_path { - lappend dirs [file join $d $basename$version] - if {$tcl_platform(platform) eq "unix" - && $tcl_platform(os) eq "Darwin"} { - # 4. On MacOSX, check the Resources/Scripts subdir too - lappend dirs [file join $d $basename$version Resources Scripts] - } - } - - # 3. Various locations relative to the executable - # ../lib/foo1.0 (From bin directory in install hierarchy) - # ../../lib/foo1.0 (From bin/arch directory in install hierarchy) - # ../library (From unix directory in build hierarchy) - # - # Remaining locations are out of date (when relevant, they ought to be - # covered by the $::auto_path seach above) and disabled. - # - # ../../library (From unix/arch directory in build hierarchy) - # ../../foo1.0.1/library - # (From unix directory in parallel build hierarchy) - # ../../../foo1.0.1/library - # (From unix/arch directory in parallel build hierarchy) + } + } + + # 2. In the package script directory registered within the + # configuration of the package itself. + + catch { + lappend dirs [::${basename}::pkgconfig get scriptdir,runtime] + } + + # 3. Relative to auto_path directories. This checks relative to the + # Tcl library as well as allowing loading of libraries added to the + # auto_path that is not relative to the core library or binary paths. + foreach d $auto_path { + lappend dirs [file join $d $basename$version] + if {$tcl_platform(platform) eq "unix" + && $tcl_platform(os) eq "Darwin"} { + # 4. On MacOSX, check the Resources/Scripts subdir too + lappend dirs [file join $d $basename$version Resources Scripts] + } + } + + # 3. Various locations relative to the executable + # ../lib/foo1.0 (From bin directory in install hierarchy) + # ../../lib/foo1.0 (From bin/arch directory in install hierarchy) + # ../library (From unix directory in build hierarchy) + # + # Remaining locations are out of date (when relevant, they ought to be + # covered by the $::auto_path seach above) and disabled. + # + # ../../library (From unix/arch directory in build hierarchy) + # ../../foo1.0.1/library + # (From unix directory in parallel build hierarchy) + # ../../../foo1.0.1/library + # (From unix/arch directory in parallel build hierarchy) set parentDir [file dirname [file dirname [info nameofexecutable]]] set grandParentDir [file dirname $parentDir] lappend dirs [file join $parentDir lib $basename$version] lappend dirs [file join $grandParentDir lib $basename$version] lappend dirs [file join $parentDir library] - if {0} { - lappend dirs [file join $grandParentDir library] - lappend dirs [file join $grandParentDir $basename$patch library] - lappend dirs [file join [file dirname $grandParentDir] \ - $basename$patch library] - } + if {0} { + lappend dirs [file join $grandParentDir library] + lappend dirs [file join $grandParentDir $basename$patch library] + lappend dirs [file join [file dirname $grandParentDir] \ + $basename$patch library] + } } # uniquify $dirs in order array set seen {} foreach i $dirs { - # Make sure $i is unique under normalization. Avoid repeated [source]. - if {[interp issafe]} { - # Safe interps have no [file normalize]. - set norm $i - } else { - set norm [file normalize $i] - } - if {[info exists seen($norm)]} { - continue - } - set seen($norm) {} - set the_library $i - set file [file join $i $initScript] - - # source everything when in a safe interpreter because we have a - # source command, but no file exists command - - if {[interp issafe] || [file exists $file]} { - if {![catch {uplevel #0 [list source $file]} msg opts]} { - return + # Make sure $i is unique under normalization. Avoid repeated [source]. + if {[interp issafe]} { + # Safe interps have no [file normalize]. + set norm $i + } else { + set norm [file normalize $i] + } + if {[info exists seen($norm)]} { + continue + } + set seen($norm) {} + + set the_library $i + set file [file join $i $initScript] + + # source everything when in a safe interpreter because we have a + # source command, but no file exists command + + if {[interp issafe] || [file exists $file]} { + if {![catch {uplevel #0 [list source $file]} msg opts]} { + return + } + append errors "$file: $msg\n" + append errors [dict get $opts -errorinfo]\n } - append errors "$file: $msg\n" - append errors [dict get $opts -errorinfo]\n - } } unset -nocomplain the_library set msg "Can't find a usable $initScript in the following directories: \n" @@ -214,7 +218,7 @@ proc tcl_findLibrary {basename version patch initScript enVarName varName} { # can't create the special parser and mess with its commands. if {[interp issafe]} { - return ;# Stop sourcing the file here + return ;# Stop sourcing the file here } # auto_mkindex -- @@ -224,11 +228,11 @@ if {[interp issafe]} { # relevant files. # # Arguments: -# dir - Name of the directory in which to create an index. +# dir - Name of the directory in which to create an index. -# args - Any number of additional arguments giving the names of files -# within dir. If no additional are given auto_mkindex will look -# for *.tcl. +# args - Any number of additional arguments giving the names of files +# within dir. If no additional are given auto_mkindex will look +# for *.tcl. proc auto_mkindex {dir args} { if {[interp issafe]} { @@ -246,17 +250,17 @@ proc auto_mkindex {dir args} { append index "# element name is the name of a command and the value is\n" append index "# a script that loads the command.\n\n" if {![llength $args]} { - set args *.tcl + set args *.tcl } auto_mkindex_parser::init foreach file [lsort [glob -- {*}$args]] { - try { - append index [auto_mkindex_parser::mkindex $file] - } on error {msg opts} { - cd $oldDir - return -options $opts $msg - } + try { + append index [auto_mkindex_parser::mkindex $file] + } on error {msg opts} { + cd $oldDir + return -options $opts $msg + } } auto_mkindex_parser::cleanup @@ -281,39 +285,39 @@ proc auto_mkindex_old {dir args} { append index "# element name is the name of a command and the value is\n" append index "# a script that loads the command.\n\n" if {![llength $args]} { - set args *.tcl + set args *.tcl } foreach file [lsort [glob -- {*}$args]] { - set f "" - set error [catch { - set f [open $file] - while {[gets $f line] >= 0} { - if {[regexp {^proc[ ]+([^ ]*)} $line match procName]} { - set procName [lindex [auto_qualify $procName "::"] 0] - append index "set [list auto_index($procName)]" - append index " \[list source \[file join \$dir [list $file]\]\]\n" - } - } - close $f - } msg opts] - if {$error} { - catch {close $f} - cd $oldDir - return -options $opts $msg - } + set f "" + set error [catch { + set f [open $file] + while {[gets $f line] >= 0} { + if {[regexp {^proc[ ]+([^ ]*)} $line match procName]} { + set procName [lindex [auto_qualify $procName "::"] 0] + append index "set [list auto_index($procName)]" + append index " \[list source \[file join \$dir [list $file]\]\]\n" + } + } + close $f + } msg opts] + if {$error} { + catch {close $f} + cd $oldDir + return -options $opts $msg + } } set f "" set error [catch { - set f [open tclIndex w] - puts -nonewline $f $index - close $f - cd $oldDir + set f [open tclIndex w] + puts -nonewline $f $index + close $f + cd $oldDir } msg opts] if {$error} { - catch {close $f} - cd $oldDir - error $msg $info $code - return -options $opts $msg + catch {close $f} + cd $oldDir + error $msg $info $code + return -options $opts $msg } } @@ -330,50 +334,50 @@ namespace eval auto_mkindex_parser { variable imports "" ;# keeps track of all imported cmds variable initCommands ;# list of commands that create aliases if {![info exists initCommands]} { - set initCommands [list] + set initCommands [list] } proc init {} { - variable parser - variable initCommands - - if {![interp issafe]} { - set parser [interp create -safe] - $parser hide info - $parser hide rename - $parser hide proc - $parser hide namespace - $parser hide eval - $parser hide puts - foreach ns [$parser invokehidden namespace children ::] { - # MUST NOT DELETE "::tcl" OR BAD THINGS HAPPEN! - if {$ns eq "::tcl"} continue - $parser invokehidden namespace delete $ns - } - foreach cmd [$parser invokehidden info commands ::*] { - $parser invokehidden rename $cmd {} - } - $parser invokehidden proc unknown {args} {} - - # We'll need access to the "namespace" command within the - # interp. Put it back, but move it out of the way. - - $parser expose namespace - $parser invokehidden rename namespace _%@namespace - $parser expose eval - $parser invokehidden rename eval _%@eval - - # Install all the registered psuedo-command implementations - - foreach cmd $initCommands { - eval $cmd - } - } + variable parser + variable initCommands + + if {![interp issafe]} { + set parser [interp create -safe] + $parser hide info + $parser hide rename + $parser hide proc + $parser hide namespace + $parser hide eval + $parser hide puts + foreach ns [$parser invokehidden namespace children ::] { + # MUST NOT DELETE "::tcl" OR BAD THINGS HAPPEN! + if {$ns eq "::tcl"} continue + $parser invokehidden namespace delete $ns + } + foreach cmd [$parser invokehidden info commands ::*] { + $parser invokehidden rename $cmd {} + } + $parser invokehidden proc unknown {args} {} + + # We'll need access to the "namespace" command within the + # interp. Put it back, but move it out of the way. + + $parser expose namespace + $parser invokehidden rename namespace _%@namespace + $parser expose eval + $parser invokehidden rename eval _%@eval + + # Install all the registered psuedo-command implementations + + foreach cmd $initCommands { + eval $cmd + } + } } proc cleanup {} { - variable parser - interp delete $parser - unset parser + variable parser + interp delete $parser + unset parser } } @@ -385,7 +389,7 @@ namespace eval auto_mkindex_parser { # that represents the index file. # # Arguments: -# file Name of Tcl source file to be indexed. +# file Name of Tcl source file to be indexed. proc auto_mkindex_parser::mkindex {file} { variable parser @@ -462,9 +466,9 @@ proc auto_mkindex_parser::slavehook {cmd} { # "tclIndex" file for auto-loading. # # Arguments: -# name Name of command recognized in Tcl files. -# arglist Argument list for command. -# body Implementation of command to handle indexing. +# name Name of command recognized in Tcl files. +# arglist Argument list for command. +# body Implementation of command to handle indexing. proc auto_mkindex_parser::command {name arglist body} { hook [list auto_mkindex_parser::commandInit $name $arglist $body] @@ -476,9 +480,9 @@ proc auto_mkindex_parser::command {name arglist body} { # called when the interpreter used by the parser is created. # # Arguments: -# name Name of command recognized in Tcl files. -# arglist Argument list for command. -# body Implementation of command to handle indexing. +# name Name of command recognized in Tcl files. +# arglist Argument list for command. +# body Implementation of command to handle indexing. proc auto_mkindex_parser::commandInit {name arglist body} { variable parser @@ -500,15 +504,15 @@ proc auto_mkindex_parser::commandInit {name arglist body} { set exportCmd [list _%@namespace export [namespace tail $name]] $parser eval [list _%@namespace eval $ns $exportCmd] - # The following proc definition does not work if you want to tolerate - # space or something else diabolical in the procedure name, (i.e., - # space in $alias). The following does not work: - # "_%@eval {$alias} \$args" - # because $alias gets concat'ed to $args. The following does not work - # because $cmd is somehow undefined - # "set cmd {$alias} \; _%@eval {\$cmd} \$args" - # A gold star to someone that can make test autoMkindex-3.3 work - # properly + # The following proc definition does not work if you want to tolerate + # space or something else diabolical in the procedure name, (i.e., + # space in $alias). The following does not work: + # "_%@eval {$alias} \$args" + # because $alias gets concat'ed to $args. The following does not work + # because $cmd is somehow undefined + # "set cmd {$alias} \; _%@eval {\$cmd} \$args" + # A gold star to someone that can make test autoMkindex-3.3 work + # properly set alias [namespace tail $fakeName] $parser invokehidden proc $name {args} "_%@eval {$alias} \$args" @@ -530,7 +534,7 @@ proc auto_mkindex_parser::commandInit {name arglist body} { # simple name. That way, the Tcl autoloader will recognize it properly. # # Arguments: -# name - Name that is being added to index. +# name - Name that is being added to index. proc auto_mkindex_parser::fullname {name} { variable contextStack @@ -562,7 +566,7 @@ proc auto_mkindex_parser::fullname {name} { # *right*, in one place. # # Arguments: -# name - Name that is being added to index. +# name - Name that is being added to index. proc auto_mkindex_parser::indexEntry {name} { variable index @@ -576,8 +580,8 @@ proc auto_mkindex_parser::indexEntry {name} { set filenameParts [file split $scriptFile] append index [format \ - {set auto_index(%s) [list source [file join $dir %s]]%s} \ - $name $filenameParts \n] + {set auto_index(%s) [list source [file join $dir %s]]%s} \ + $name $filenameParts \n] return } @@ -605,22 +609,22 @@ auto_mkindex_parser::command proc {name args} { auto_mkindex_parser::hook { try { - package require tbcload + package require tbcload } on error {} { - # OK, don't have it so do nothing + # OK, don't have it so do nothing } on ok {} { - if {[namespace which -command tbcload::bcproc] eq ""} { - auto_load tbcload::bcproc - } - load {} tbcload $auto_mkindex_parser::parser - - # AUTO MKINDEX: tbcload::bcproc name arglist body - # Adds an entry to the auto index list for the given pre-compiled - # procedure name. - - auto_mkindex_parser::commandInit tbcload::bcproc {name args} { - indexEntry $name - } + if {[namespace which -command tbcload::bcproc] eq ""} { + auto_load tbcload::bcproc + } + load {} tbcload $auto_mkindex_parser::parser + + # AUTO MKINDEX: tbcload::bcproc name arglist body + # Adds an entry to the auto index list for the given pre-compiled + # procedure name. + + auto_mkindex_parser::commandInit tbcload::bcproc {name args} { + indexEntry $name + } } } @@ -645,7 +649,7 @@ auto_mkindex_parser::command namespace {op args} { set args [lrange $args 1 end] set contextStack [linsert $contextStack 0 $name] - $parser eval [list _%@namespace eval $name] $args + $parser eval [list _%@namespace eval $name] $args set contextStack [lrange $contextStack 1 end] } import { @@ -658,22 +662,22 @@ auto_mkindex_parser::command namespace {op args} { } catch {$parser eval "_%@namespace import $args"} } - ensemble { - variable parser - variable contextStack - if {[lindex $args 0] eq "create"} { - set name ::[join [lreverse $contextStack] ::] - catch { - set name [dict get [lrange $args 1 end] -command] - if {![string match ::* $name]} { - set name ::[join [lreverse $contextStack] ::]$name - } - regsub -all ::+ $name :: name - } - # create artifical proc to force an entry in the tclIndex - $parser eval [list ::proc $name {} {}] - } - } + ensemble { + variable parser + variable contextStack + if {[lindex $args 0] eq "create"} { + set name ::[join [lreverse $contextStack] ::] + catch { + set name [dict get [lrange $args 1 end] -command] + if {![string match ::* $name]} { + set name ::[join [lreverse $contextStack] ::]$name + } + regsub -all ::+ $name :: name + } + # create artifical proc to force an entry in the tclIndex + $parser eval [list ::proc $name {} {}] + } + } } } @@ -681,12 +685,12 @@ auto_mkindex_parser::command namespace {op args} { # Adds an entry to the auto index list for the given class name. auto_mkindex_parser::command oo::class {op name {body ""}} { if {$op eq "create"} { - indexEntry $name + indexEntry $name } } auto_mkindex_parser::command class {op name {body ""}} { if {$op eq "create"} { - indexEntry $name + indexEntry $name } } -- cgit v0.12 From 50a13754610c04730f483b8100a8b9c0fccb1e3e Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 3 Oct 2018 19:24:13 +0000 Subject: Tcl_UniCharToUtfDString: Don't allocate too much memory for this function. Tcl_UtfToUniCharDString: Don't allocate too much memory for this function. And make sure that we never access more than 'length' bytes from the string, not even when encountering invalid UTF-8. --- generic/tclUtf.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/generic/tclUtf.c b/generic/tclUtf.c index c2963bf..b33bf5f 100644 --- a/generic/tclUtf.c +++ b/generic/tclUtf.c @@ -243,7 +243,7 @@ Tcl_UniCharToUtfDString( */ oldLength = Tcl_DStringLength(dsPtr); - Tcl_DStringSetLength(dsPtr, (oldLength + uniLength + 1) * TCL_UTF_MAX); + Tcl_DStringSetLength(dsPtr, oldLength + (uniLength + 1) * TCL_UTF_MAX); string = Tcl_DStringValue(dsPtr) + oldLength; p = string; @@ -432,17 +432,27 @@ Tcl_UtfToUniCharDString( */ oldLength = Tcl_DStringLength(dsPtr); -/* TODO: fix overreach! */ + Tcl_DStringSetLength(dsPtr, - (int) ((oldLength + length + 1) * sizeof(Tcl_UniChar))); + oldLength + (int) ((length + 1) * sizeof(Tcl_UniChar))); wString = (Tcl_UniChar *) (Tcl_DStringValue(dsPtr) + oldLength); w = wString; - end = src + length; - for (p = src; p < end; ) { + p = src; + end = src + length - TCL_UTF_MAX; + while (p < end) { p += TclUtfToUniChar(p, &ch); *w++ = ch; } + end += TCL_UTF_MAX; + while (p < end) { + if (Tcl_UtfCharComplete(p, end-p)) { + p += TclUtfToUniChar(p, &ch); + } else { + ch = UCHAR(*p++); + } + *w++ = ch; + } *w = '\0'; Tcl_DStringSetLength(dsPtr, (oldLength + ((char *) w - (char *) wString))); -- cgit v0.12 From 9707adf634f1a0daab22f5e13080c552a1a081bf Mon Sep 17 00:00:00 2001 From: dkf Date: Thu, 4 Oct 2018 07:27:32 +0000 Subject: Added Emacs metadata to a bunch of nroff source files. --- doc/cd.n | 4 ++++ doc/eof.n | 4 ++++ doc/exit.n | 4 ++++ doc/fblocked.n | 4 ++++ doc/fileevent.n | 4 ++++ doc/filename.n | 4 ++++ doc/flush.n | 4 ++++ doc/foreach.n | 4 ++++ doc/global.n | 4 ++++ doc/history.n | 4 ++++ doc/join.n | 4 ++++ doc/llength.n | 4 ++++ doc/lrange.n | 4 ++++ doc/lrepeat.n | 5 ++++- doc/packagens.n | 4 ++++ doc/pid.n | 5 ++++- doc/platform_shell.n | 4 ++++ doc/puts.n | 4 ++++ doc/pwd.n | 4 ++++ doc/rename.n | 4 ++++ doc/set.n | 4 ++++ doc/source.n | 4 ++++ doc/tell.n | 4 ++++ doc/unknown.n | 4 ++++ doc/update.n | 4 ++++ doc/while.n | 4 ++++ 26 files changed, 104 insertions(+), 2 deletions(-) diff --git a/doc/cd.n b/doc/cd.n index dceb075..8e19191 100644 --- a/doc/cd.n +++ b/doc/cd.n @@ -41,3 +41,7 @@ current one: filename(n), glob(n), pwd(n) .SH KEYWORDS working directory +'\" Local Variables: +'\" mode: nroff +'\" fill-column: 78 +'\" End: diff --git a/doc/eof.n b/doc/eof.n index a150464..0dcf34a 100644 --- a/doc/eof.n +++ b/doc/eof.n @@ -59,3 +59,7 @@ while {1} { file(n), open(n), close(n), fblocked(n), Tcl_StandardChannels(3) .SH KEYWORDS channel, end of file +'\" Local Variables: +'\" mode: nroff +'\" fill-column: 78 +'\" End: diff --git a/doc/exit.n b/doc/exit.n index a005c08..36676b1 100644 --- a/doc/exit.n +++ b/doc/exit.n @@ -49,3 +49,7 @@ if {[catch {main} msg options]} { exec(n) .SH KEYWORDS abort, exit, process +'\" Local Variables: +'\" mode: nroff +'\" fill-column: 78 +'\" End: diff --git a/doc/fblocked.n b/doc/fblocked.n index 93cfe87..0a28dcf 100644 --- a/doc/fblocked.n +++ b/doc/fblocked.n @@ -65,3 +65,7 @@ vwait forever gets(n), open(n), read(n), socket(n), Tcl_StandardChannels(3) .SH KEYWORDS blocking, nonblocking +'\" Local Variables: +'\" mode: nroff +'\" fill-column: 78 +'\" End: diff --git a/doc/fileevent.n b/doc/fileevent.n index 2751040..bbba997 100644 --- a/doc/fileevent.n +++ b/doc/fileevent.n @@ -154,3 +154,7 @@ fconfigure(n), gets(n), interp(n), puts(n), read(n), Tcl_StandardChannels(3) .SH KEYWORDS asynchronous I/O, blocking, channel, event handler, nonblocking, readable, script, writable. +'\" Local Variables: +'\" mode: nroff +'\" fill-column: 78 +'\" End: diff --git a/doc/filename.n b/doc/filename.n index 87ba467..f160eff 100644 --- a/doc/filename.n +++ b/doc/filename.n @@ -176,3 +176,7 @@ file(n), glob(n) .SH KEYWORDS current directory, absolute file name, relative file name, volume-relative file name, portability +'\" Local Variables: +'\" mode: nroff +'\" fill-column: 78 +'\" End: diff --git a/doc/flush.n b/doc/flush.n index 6b98ab7..1d84383 100644 --- a/doc/flush.n +++ b/doc/flush.n @@ -43,3 +43,7 @@ puts "Hello there, $name!" file(n), open(n), socket(n), Tcl_StandardChannels(3) .SH KEYWORDS blocking, buffer, channel, flush, nonblocking, output +'\" Local Variables: +'\" mode: nroff +'\" fill-column: 78 +'\" End: diff --git a/doc/foreach.n b/doc/foreach.n index 925ec1f..43f961a 100644 --- a/doc/foreach.n +++ b/doc/foreach.n @@ -102,3 +102,7 @@ for(n), while(n), break(n), continue(n) .SH KEYWORDS foreach, iteration, list, loop +'\" Local Variables: +'\" mode: nroff +'\" fill-column: 78 +'\" End: diff --git a/doc/global.n b/doc/global.n index 9848817..e6d2678b 100644 --- a/doc/global.n +++ b/doc/global.n @@ -56,3 +56,7 @@ proc accum {string} { namespace(n), upvar(n), variable(n) .SH KEYWORDS global, namespace, procedure, variable +'\" Local Variables: +'\" mode: nroff +'\" fill-column: 78 +'\" End: diff --git a/doc/history.n b/doc/history.n index 0391948..05d936e 100644 --- a/doc/history.n +++ b/doc/history.n @@ -100,3 +100,7 @@ the \fBevent\fR operation to retrieve some event, and the \fBadd\fR operation to add it to history and execute it. .SH KEYWORDS event, history, record +'\" Local Variables: +'\" mode: nroff +'\" fill-column: 78 +'\" End: diff --git a/doc/join.n b/doc/join.n index 23a7697..7dcde98 100644 --- a/doc/join.n +++ b/doc/join.n @@ -42,3 +42,7 @@ set data {1 {2 3} 4 {5 {6 7} 8}} list(n), lappend(n), split(n) .SH KEYWORDS element, join, list, separator +'\" Local Variables: +'\" mode: nroff +'\" fill-column: 78 +'\" End: diff --git a/doc/llength.n b/doc/llength.n index 79f93c0..7e46064 100644 --- a/doc/llength.n +++ b/doc/llength.n @@ -53,3 +53,7 @@ list(n), lappend(n), lindex(n), linsert(n), lsearch(n), lset(n), lsort(n), lrange(n), lreplace(n) .SH KEYWORDS element, list, length +'\" Local Variables: +'\" mode: nroff +'\" fill-column: 78 +'\" End: diff --git a/doc/lrange.n b/doc/lrange.n index ffa6dba..ba068f6 100644 --- a/doc/lrange.n +++ b/doc/lrange.n @@ -76,3 +76,7 @@ lset(n), lreplace(n), lsort(n), string(n) .SH KEYWORDS element, list, range, sublist +'\" Local Variables: +'\" mode: nroff +'\" fill-column: 78 +'\" End: diff --git a/doc/lrepeat.n b/doc/lrepeat.n index f92792e..4719bfd 100644 --- a/doc/lrepeat.n +++ b/doc/lrepeat.n @@ -33,6 +33,9 @@ is identical to \fBlist element ...\fR. .CE .SH "SEE ALSO" list(n), lappend(n), linsert(n), llength(n), lset(n) - .SH KEYWORDS element, index, list +'\" Local Variables: +'\" mode: nroff +'\" fill-column: 78 +'\" End: diff --git a/doc/packagens.n b/doc/packagens.n index 5bd2e67..a6eee1e 100644 --- a/doc/packagens.n +++ b/doc/packagens.n @@ -48,3 +48,7 @@ At least one \fB\-load\fR or \fB\-source\fR parameter must be given. package(n) .SH KEYWORDS auto-load, index, package, version +'\" Local Variables: +'\" mode: nroff +'\" fill-column: 78 +'\" End: diff --git a/doc/pid.n b/doc/pid.n index 6f8c399..fa0af56 100644 --- a/doc/pid.n +++ b/doc/pid.n @@ -43,6 +43,9 @@ close $pipeline .SH "SEE ALSO" exec(n), open(n) - .SH KEYWORDS file, pipeline, process identifier +'\" Local Variables: +'\" mode: nroff +'\" fill-column: 78 +'\" End: diff --git a/doc/platform_shell.n b/doc/platform_shell.n index 330afa9..f7ae283 100644 --- a/doc/platform_shell.n +++ b/doc/platform_shell.n @@ -55,3 +55,7 @@ This command returns the contents of \fBtcl_platform(platform)\fR for the specified Tcl shell. .SH KEYWORDS operating system, cpu architecture, platform, architecture +'\" Local Variables: +'\" mode: nroff +'\" fill-column: 78 +'\" End: diff --git a/doc/puts.n b/doc/puts.n index f4e1040..0e23c80 100644 --- a/doc/puts.n +++ b/doc/puts.n @@ -96,3 +96,7 @@ close $chan file(n), fileevent(n), Tcl_StandardChannels(3) .SH KEYWORDS channel, newline, output, write +'\" Local Variables: +'\" mode: nroff +'\" fill-column: 78 +'\" End: diff --git a/doc/pwd.n b/doc/pwd.n index 85dd390..e96cae5 100644 --- a/doc/pwd.n +++ b/doc/pwd.n @@ -37,3 +37,7 @@ cd $savedDir file(n), cd(n), glob(n), filename(n) .SH KEYWORDS working directory +'\" Local Variables: +'\" mode: nroff +'\" fill-column: 78 +'\" End: diff --git a/doc/rename.n b/doc/rename.n index f74db5f..b064f66 100644 --- a/doc/rename.n +++ b/doc/rename.n @@ -43,3 +43,7 @@ proc ::source args { namespace(n), proc(n) .SH KEYWORDS command, delete, namespace, rename +'\" Local Variables: +'\" mode: nroff +'\" fill-column: 78 +'\" End: diff --git a/doc/set.n b/doc/set.n index f065087..890ef1d 100644 --- a/doc/set.n +++ b/doc/set.n @@ -73,3 +73,7 @@ practice instead of doing double-dereferencing): expr(n), global(n), namespace(n), proc(n), trace(n), unset(n), upvar(n), variable(n) .SH KEYWORDS read, write, variable +'\" Local Variables: +'\" mode: nroff +'\" fill-column: 78 +'\" End: diff --git a/doc/source.n b/doc/source.n index 82fefa6..3fc001e 100644 --- a/doc/source.n +++ b/doc/source.n @@ -69,3 +69,7 @@ foreach scriptFile {foo.tcl bar.tcl} { file(n), cd(n), encoding(n), info(n) .SH KEYWORDS file, script +'\" Local Variables: +'\" mode: nroff +'\" fill-column: 78 +'\" End: diff --git a/doc/tell.n b/doc/tell.n index a56e9e3..54fbae1 100644 --- a/doc/tell.n +++ b/doc/tell.n @@ -46,3 +46,7 @@ if {[read $chan 6] eq "foobar"} { file(n), open(n), close(n), gets(n), seek(n), Tcl_StandardChannels(3) .SH KEYWORDS access position, channel, seeking +'\" Local Variables: +'\" mode: nroff +'\" fill-column: 78 +'\" End: diff --git a/doc/unknown.n b/doc/unknown.n index 82dcefc..ee8a5be 100644 --- a/doc/unknown.n +++ b/doc/unknown.n @@ -89,3 +89,7 @@ proc \fBunknown\fR args { info(n), proc(n), interp(n), library(n), namespace(n) .SH KEYWORDS error, non-existent command, unknown +'\" Local Variables: +'\" mode: nroff +'\" fill-column: 78 +'\" End: diff --git a/doc/update.n b/doc/update.n index ce0fb25..a85faac 100644 --- a/doc/update.n +++ b/doc/update.n @@ -63,3 +63,7 @@ while {!$done} { after(n), interp(n) .SH KEYWORDS asynchronous I/O, event, flush, handler, idle, update +'\" Local Variables: +'\" mode: nroff +'\" fill-column: 78 +'\" End: diff --git a/doc/while.n b/doc/while.n index 961260c..6acc909 100644 --- a/doc/while.n +++ b/doc/while.n @@ -63,3 +63,7 @@ set lineCount 0 break(n), continue(n), for(n), foreach(n) .SH KEYWORDS boolean, loop, test, while +'\" Local Variables: +'\" mode: nroff +'\" fill-column: 78 +'\" End: -- cgit v0.12 From c365555a694a7e12f74dd012c0487aa8b8f035e8 Mon Sep 17 00:00:00 2001 From: sebres Date: Thu, 4 Oct 2018 08:04:08 +0000 Subject: fixed TclGetWideBitsFromObj - minus applied to unsigned type --- generic/tclObj.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/generic/tclObj.c b/generic/tclObj.c index d1af60d..693f7c9 100644 --- a/generic/tclObj.c +++ b/generic/tclObj.c @@ -3158,10 +3158,7 @@ TclGetWideBitsFromObj( while (numBytes-- > 0) { value = (value << CHAR_BIT) | *bytes++; } - if (big.sign) { - value = -value; - } - *wideIntPtr = (Tcl_WideInt) value; + *wideIntPtr = !big.sign ? (Tcl_WideInt)value : -(Tcl_WideInt)value; mp_clear(&big); return TCL_OK; } -- cgit v0.12 From b45b819dfe273ca5b627145219ea4964cb5541e9 Mon Sep 17 00:00:00 2001 From: dkf Date: Thu, 4 Oct 2018 10:42:11 +0000 Subject: Clean up zipfs implementation a bit. --- doc/zipfs.3 | 102 +- generic/tclZipfs.c | 5329 +++++++++++++++++++++++++++------------------------- 2 files changed, 2843 insertions(+), 2588 deletions(-) diff --git a/doc/zipfs.3 b/doc/zipfs.3 index ce5d5eb..568f461 100644 --- a/doc/zipfs.3 +++ b/doc/zipfs.3 @@ -10,61 +10,87 @@ .so man.macros .BS .SH NAME -TclZipfs_AppHook, Tclzipfs_Mount, Tclzipfs_Unmount, \- handle ZIP files as VFS +TclZipfs_AppHook, Tclzipfs_Mount, Tclzipfs_Unmount \- handle ZIP files as Tcl virtual filesystems .SH SYNOPSIS .nf -.sp int -\fBTclZipfs_AppHook(\fIint *argc, char ***argv\fR) +\fBTclZipfs_AppHook(\fIargcPtr, argvPtr\fR) .sp int -\fBTclzipfs_Mount\fR(\fIinterp, mntpt, zipname, passwd\fR) +\fBTclzipfs_Mount\fR(\fIinterp, mountpoint, zipname, password\fR) .sp int \fBTclzipfs_Unmount\fR(\fIinterp, zipname\fR) +.fi .SH ARGUMENTS -.AP "int" *argc in -Number of command line arguments from main() -.AP "char" ***argv in -Pointer to an array of strings containing the command -line arguments to main() -.AS Tcl_Interp **termPtr +.AS Tcl_Interp *mountpoint in +.AP "int" *argcPtr in +Pointer to a variable holding the number of command line arguments from +\fBmain\fR(). +.AP "char" ***argvPtr in +Pointer to an array of strings containing the command line arguments to +\fBmain\fR(). .AP Tcl_Interp *interp in -Interpreter in which the zip file system is mounted. The interpreter's result is +Interpreter in which the ZIP file system is mounted. The interpreter's result is modified to hold the result or error message from the script. .AP "const char" *zipname in -Name of a zipfile. -.AP "const char" *mntpt in -Name of a mount point. -.AP "const char" *passwd in -An (optional) password. +Name of a ZIP file. Must not be NULL when either mounting or unmounting a ZIP. +.AP "const char" *mountpoint in +Name of a mount point, which must be a legal Tcl file or directory name. May +be NULL to query current mount points. +.AP "const char" *password in +An (optional) password. Use NULL if no password is wanted to read the file. .BE .SH DESCRIPTION -\fBTclZipfs_AppHook()\fR is a utility function to perform standard -application initialization procedures. If the current application has -a mountable zip file system, that file system is mounted under \fIZIPROOT\fR\fB/app\fR. -If a file named \fBmain.tcl\fR is located in that file system, it is treated -as the startup script for the process. If the file \fIZIPROOT\fR\fB/app/tcl_library/init.tcl\fR -is present, \fBtcl_library\fR is set to \fIZIPROOT\fR\fB/app/tcl_library. +\fBTclZipfs_AppHook\fR is a utility function to perform standard application +initialization procedures, taking into account available ZIP archives as +follows: +.IP [1] +If the current application has a mountable ZIP archive, that archive is +mounted under \fIZIPFS_VOLUME\fB/app\fR as a read-only Tcl virtual file +system. \fIZIPFS_VOLUME\fR is usually \fB//zipfs:\fR on all platforms, but +\fBzipfs:\fR may also be used on Windows (due to differences in the +platform's filename parsing). +.IP [2] +If a file named \fBmain.tcl\fR is located in the root directory of that file +system (i.e., at \fIZIPROOT\fB/app/main.tcl\fR after the ZIP archive is +mounted as described above) it is treated as the startup script for the +process. +.IP [3] +If the file \fIZIPROOT\fB/app/tcl_library/init.tcl\fR is present, the +\fBtcl_library\fR global variable in the initial Tcl interpreter is set to +\fIZIPROOT\fB/app/tcl_library\fR. +.IP [4] +If the directory \fBtcl_library\fR was not found in the main application +mount, the system will then search for it as either a VFS attached to the +application dynamic library, or as a zip archive named +\fBlibtcl_\fImajor\fB_\fIminor\fB_\fIpatchlevel\fB.zip\fR either in the +present working directory or in the standard Tcl install location. (For +example, the Tcl 8.7.2 release would be searched for in a file +\fBlibtcl_8_7_2.zip\fR.) That archive, if located, is also mounted read-only. .PP -On Windows, \fBTclZipfs_AppHook()\fR has a slightly different signature, it uses -WCHAR in stead of char. As a result, it only works if your application is compiled -using -DUNICODE. +On Windows, \fBTclZipfs_AppHook\fR has a slightly different signature, since +it uses WCHAR in stead of char. As a result, it requires your application to +be compiled with the UNICODE preprocessor symbol defined (e.g., via the +\fB-DUNICODE\fR compiler flag). .PP -If the \fBtcl_library\fR was not found in the application, the system will then search for it -as either a VFS attached to the application dynamic library, or as a zip archive named -libtcl_\fIMAJOR\fR_\fIMINOR\fR_\fIpatchLevel\fR.zip either in the present working directory -or in the standard tcl install location. +The result of \fBTclZipfs_AppHook\fR is a Tcl result code (e.g., \fBTCL_OK\fR +when the function is successful). The function \fImay\fR modify the variables +pointed to by \fIargcPtr\fR and \fIargvPtr\fR to remove arguments; the +current implementation does not do so, but callers \fIshould not\fR assume +that this will be true in the future. .PP -\fBTclzipfs_Mount()\fR mount the ZIP archive \fIzipname\fR on the mount -point given in \fImntpt\fR using the optional ZIP password \fIpasswd\fR. -Errors during that process are reported in the interpreter \fIinterp\fR. -If \fImountpoint\fR is a NULL pointer, information on all currently mounted -ZIP file systems is written into \fIinterp\fR's result as a sequence of -mount points and ZIP file names. +\fBTclzipfs_Mount\fR mounts the ZIP archive \fIzipname\fR on the mount point +given in \fImountpoint\fR using the optional ZIP password \fIpassword\fR. +Errors during that process are reported in the interpreter \fIinterp\fR. If +\fImountpoint\fR is a NULL pointer, information on all currently mounted ZIP +file systems is written into \fIinterp\fR's result as a sequence of mount +points and ZIP file names. .PP -\fBTclzipfs_Unmount()\fR undoes the effect of \fBTclzipfs_Mount()\fR, -i.e. it unmounts the mounted ZIP file system at \fImountpoint\fR. Errors are -reported in the interpreter \fIinterp\fR. +\fBTclzipfs_Unmount\fR undoes the effect of \fBTclzipfs_Mount\fR, i.e., it +unmounts the mounted ZIP file system that was mounted from \fIzipname\fR (at +\fImountpoint\fR). Errors are reported in the interpreter \fIinterp\fR. +.SH "SEE ALSO" +zipfs(n) .SH KEYWORDS compress, filesystem, zip diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c index e634754..4e6cd8a 100644 --- a/generic/tclZipfs.c +++ b/generic/tclZipfs.c @@ -11,8 +11,9 @@ * this file, and for a DISCLAIMER OF ALL WARRANTIES. * * This file is distributed in two ways: - * generic/tclZipfs.c file in the TIP430 enabled tcl cores - * compat/tclZipfs.c file in the tclconfig (TEA) file system, for pre-tip430 projects + * generic/tclZipfs.c file in the TIP430-enabled Tcl cores. + * compat/tclZipfs.c file in the tclconfig (TEA) file system, for pre-tip430 + * projects. */ #include "tclInt.h" @@ -43,10 +44,10 @@ ** We are compiling as part of the core. ** TIP430 style zipfs prefix */ -#define ZIPFS_VOLUME "//zipfs:/" +#define ZIPFS_VOLUME "//zipfs:/" #define ZIPFS_VOLUME_LEN 9 -#define ZIPFS_APP_MOUNT "//zipfs:/app" -#define ZIPFS_ZIP_MOUNT "//zipfs:/lib/tcl" +#define ZIPFS_APP_MOUNT "//zipfs:/app" +#define ZIPFS_ZIP_MOUNT "//zipfs:/lib/tcl" #else /* ** We are compiling from the /compat folder of tclconfig @@ -54,89 +55,100 @@ ** //zipfs:/ doesn't work straight out of the box on either windows or Unix ** without other changes made to tip 430 */ -#define ZIPFS_VOLUME "zipfs:/" +#define ZIPFS_VOLUME "zipfs:/" #define ZIPFS_VOLUME_LEN 7 -#define ZIPFS_APP_MOUNT "zipfs:/app" -#define ZIPFS_ZIP_MOUNT "zipfs:/lib/tcl" +#define ZIPFS_APP_MOUNT "zipfs:/app" +#define ZIPFS_ZIP_MOUNT "zipfs:/lib/tcl" #endif /* * Various constants and offsets found in ZIP archive files */ -#define ZIP_SIG_LEN 4 +#define ZIP_SIG_LEN 4 /* Local header of ZIP archive member (at very beginning of each member). */ -#define ZIP_LOCAL_HEADER_SIG 0x04034b50 -#define ZIP_LOCAL_HEADER_LEN 30 -#define ZIP_LOCAL_SIG_OFFS 0 -#define ZIP_LOCAL_VERSION_OFFS 4 -#define ZIP_LOCAL_FLAGS_OFFS 6 -#define ZIP_LOCAL_COMPMETH_OFFS 8 -#define ZIP_LOCAL_MTIME_OFFS 10 -#define ZIP_LOCAL_MDATE_OFFS 12 -#define ZIP_LOCAL_CRC32_OFFS 14 -#define ZIP_LOCAL_COMPLEN_OFFS 18 -#define ZIP_LOCAL_UNCOMPLEN_OFFS 22 -#define ZIP_LOCAL_PATHLEN_OFFS 26 -#define ZIP_LOCAL_EXTRALEN_OFFS 28 +#define ZIP_LOCAL_HEADER_SIG 0x04034b50 +#define ZIP_LOCAL_HEADER_LEN 30 +#define ZIP_LOCAL_SIG_OFFS 0 +#define ZIP_LOCAL_VERSION_OFFS 4 +#define ZIP_LOCAL_FLAGS_OFFS 6 +#define ZIP_LOCAL_COMPMETH_OFFS 8 +#define ZIP_LOCAL_MTIME_OFFS 10 +#define ZIP_LOCAL_MDATE_OFFS 12 +#define ZIP_LOCAL_CRC32_OFFS 14 +#define ZIP_LOCAL_COMPLEN_OFFS 18 +#define ZIP_LOCAL_UNCOMPLEN_OFFS 22 +#define ZIP_LOCAL_PATHLEN_OFFS 26 +#define ZIP_LOCAL_EXTRALEN_OFFS 28 /* Central header of ZIP archive member at end of ZIP file. */ -#define ZIP_CENTRAL_HEADER_SIG 0x02014b50 -#define ZIP_CENTRAL_HEADER_LEN 46 -#define ZIP_CENTRAL_SIG_OFFS 0 -#define ZIP_CENTRAL_VERSIONMADE_OFFS 4 -#define ZIP_CENTRAL_VERSION_OFFS 6 -#define ZIP_CENTRAL_FLAGS_OFFS 8 -#define ZIP_CENTRAL_COMPMETH_OFFS 10 -#define ZIP_CENTRAL_MTIME_OFFS 12 -#define ZIP_CENTRAL_MDATE_OFFS 14 -#define ZIP_CENTRAL_CRC32_OFFS 16 -#define ZIP_CENTRAL_COMPLEN_OFFS 20 -#define ZIP_CENTRAL_UNCOMPLEN_OFFS 24 -#define ZIP_CENTRAL_PATHLEN_OFFS 28 -#define ZIP_CENTRAL_EXTRALEN_OFFS 30 -#define ZIP_CENTRAL_FCOMMENTLEN_OFFS 32 -#define ZIP_CENTRAL_DISKFILE_OFFS 34 -#define ZIP_CENTRAL_IATTR_OFFS 36 -#define ZIP_CENTRAL_EATTR_OFFS 38 -#define ZIP_CENTRAL_LOCALHDR_OFFS 42 +#define ZIP_CENTRAL_HEADER_SIG 0x02014b50 +#define ZIP_CENTRAL_HEADER_LEN 46 +#define ZIP_CENTRAL_SIG_OFFS 0 +#define ZIP_CENTRAL_VERSIONMADE_OFFS 4 +#define ZIP_CENTRAL_VERSION_OFFS 6 +#define ZIP_CENTRAL_FLAGS_OFFS 8 +#define ZIP_CENTRAL_COMPMETH_OFFS 10 +#define ZIP_CENTRAL_MTIME_OFFS 12 +#define ZIP_CENTRAL_MDATE_OFFS 14 +#define ZIP_CENTRAL_CRC32_OFFS 16 +#define ZIP_CENTRAL_COMPLEN_OFFS 20 +#define ZIP_CENTRAL_UNCOMPLEN_OFFS 24 +#define ZIP_CENTRAL_PATHLEN_OFFS 28 +#define ZIP_CENTRAL_EXTRALEN_OFFS 30 +#define ZIP_CENTRAL_FCOMMENTLEN_OFFS 32 +#define ZIP_CENTRAL_DISKFILE_OFFS 34 +#define ZIP_CENTRAL_IATTR_OFFS 36 +#define ZIP_CENTRAL_EATTR_OFFS 38 +#define ZIP_CENTRAL_LOCALHDR_OFFS 42 /* Central end signature at very end of ZIP file. */ -#define ZIP_CENTRAL_END_SIG 0x06054b50 -#define ZIP_CENTRAL_END_LEN 22 -#define ZIP_CENTRAL_END_SIG_OFFS 0 -#define ZIP_CENTRAL_DISKNO_OFFS 4 -#define ZIP_CENTRAL_DISKDIR_OFFS 6 -#define ZIP_CENTRAL_ENTS_OFFS 8 -#define ZIP_CENTRAL_TOTALENTS_OFFS 10 -#define ZIP_CENTRAL_DIRSIZE_OFFS 12 -#define ZIP_CENTRAL_DIRSTART_OFFS 16 -#define ZIP_CENTRAL_COMMENTLEN_OFFS 20 - -#define ZIP_MIN_VERSION 20 -#define ZIP_COMPMETH_STORED 0 -#define ZIP_COMPMETH_DEFLATED 8 - -#define ZIP_PASSWORD_END_SIG 0x5a5a4b50 +#define ZIP_CENTRAL_END_SIG 0x06054b50 +#define ZIP_CENTRAL_END_LEN 22 +#define ZIP_CENTRAL_END_SIG_OFFS 0 +#define ZIP_CENTRAL_DISKNO_OFFS 4 +#define ZIP_CENTRAL_DISKDIR_OFFS 6 +#define ZIP_CENTRAL_ENTS_OFFS 8 +#define ZIP_CENTRAL_TOTALENTS_OFFS 10 +#define ZIP_CENTRAL_DIRSIZE_OFFS 12 +#define ZIP_CENTRAL_DIRSTART_OFFS 16 +#define ZIP_CENTRAL_COMMENTLEN_OFFS 20 + +#define ZIP_MIN_VERSION 20 +#define ZIP_COMPMETH_STORED 0 +#define ZIP_COMPMETH_DEFLATED 8 + +#define ZIP_PASSWORD_END_SIG 0x5a5a4b50 /* Macro to report errors only if an interp is present */ #define ZIPFS_ERROR(interp,errstr) \ - if(interp != NULL) Tcl_SetObjResult(interp, Tcl_NewStringObj(errstr, -1)); + do { \ + if (interp != NULL) { \ + Tcl_SetObjResult(interp, Tcl_NewStringObj(errstr, -1)); \ + } \ + } while (0) /* * Macros to read and write 16 and 32 bit integers from/to ZIP archives. */ -#define zip_read_int(p) \ +#define zip_read_int(p) \ ((p)[0] | ((p)[1] << 8) | ((p)[2] << 16) | ((p)[3] << 24)) -#define zip_read_short(p) \ +#define zip_read_short(p) \ ((p)[0] | ((p)[1] << 8)) -#define zip_write_int(p, v) \ - (p)[0] = (v) & 0xff; (p)[1] = ((v) >> 8) & 0xff; \ - (p)[2] = ((v) >> 16) & 0xff; (p)[3] = ((v) >> 24) & 0xff; -#define zip_write_short(p, v) \ - (p)[0] = (v) & 0xff; (p)[1] = ((v) >> 8) & 0xff; +#define zip_write_int(p, v) \ + do { \ + (p)[0] = (v) & 0xff; \ + (p)[1] = ((v) >> 8) & 0xff; \ + (p)[2] = ((v) >> 16) & 0xff; \ + (p)[3] = ((v) >> 24) & 0xff; \ + } while (0) +#define zip_write_short(p, v) \ + do { \ + (p)[0] = (v) & 0xff; \ + (p)[1] = ((v) >> 8) & 0xff; \ + } while (0) /* * Windows drive letters. @@ -151,39 +163,35 @@ static const char drvletters[] = * Mutex to protect localtime(3) when no reentrant version available. */ -#ifndef _WIN32 -#ifndef HAVE_LOCALTIME_R -#ifdef TCL_THREADS +#if !defined(_WIN32) && !defined(HAVE_LOCALTIME_R) && defined(TCL_THREADS) TCL_DECLARE_MUTEX(localtimeMutex) #endif -#endif -#endif /* * In-core description of mounted ZIP archive file. */ typedef struct ZipFile { - char *name; /* Archive name */ + char *name; /* Archive name */ size_t namelen; - char is_membuf; /* When true, not a file but a memory buffer */ - Tcl_Channel chan; /* Channel handle or NULL */ - unsigned char *data; /* Memory mapped or malloc'ed file */ - size_t length; /* Length of memory mapped file */ - void *tofree; /* Non-NULL if malloc'ed file */ - size_t nfiles; /* Number of files in archive */ - size_t baseoffs; /* Archive start */ - size_t baseoffsp; /* Password start */ - size_t centoffs; /* Archive directory start */ - unsigned char pwbuf[264]; /* Password buffer */ - size_t nopen; /* Number of open files on archive */ - struct ZipEntry *entries; /* List of files in archive */ - struct ZipEntry *topents; /* List of top-level dirs in archive */ + char is_membuf; /* When true, not a file but a memory buffer */ + Tcl_Channel chan; /* Channel handle or NULL */ + unsigned char *data; /* Memory mapped or malloc'ed file */ + size_t length; /* Length of memory mapped file */ + void *tofree; /* Non-NULL if malloc'ed file */ + size_t nfiles; /* Number of files in archive */ + size_t baseoffs; /* Archive start */ + size_t baseoffsp; /* Password start */ + size_t centoffs; /* Archive directory start */ + unsigned char pwbuf[264]; /* Password buffer */ + size_t nopen; /* Number of open files on archive */ + struct ZipEntry *entries; /* List of files in archive */ + struct ZipEntry *topents; /* List of top-level dirs in archive */ size_t mntptlen; - char *mntpt; /* Mount point */ + char *mntpt; /* Mount point */ #ifdef _WIN32 HANDLE mh; - int mntdrv; /* Drive letter of mount point */ + int mntdrv; /* Drive letter of mount point */ #endif } ZipFile; @@ -192,20 +200,20 @@ typedef struct ZipFile { */ typedef struct ZipEntry { - char *name; /* The full pathname of the virtual file */ - ZipFile *zipfile; /* The ZIP file holding this virtual file */ - Tcl_WideInt offset; /* Data offset into memory mapped ZIP file */ - int nbyte; /* Uncompressed size of the virtual file */ - int nbytecompr; /* Compressed size of the virtual file */ - int cmeth; /* Compress method */ - int isdir; /* Set to 1 if directory, or -1 if root */ - int depth; /* Number of slashes in path. */ - int crc32; /* CRC-32 */ - int timestamp; /* Modification time */ - int isenc; /* True if data is encrypted */ - unsigned char *data; /* File data if written */ - struct ZipEntry *next; /* Next file in the same archive */ - struct ZipEntry *tnext; /* Next top-level dir in archive */ + char *name; /* The full pathname of the virtual file */ + ZipFile *zipfile; /* The ZIP file holding this virtual file */ + Tcl_WideInt offset; /* Data offset into memory mapped ZIP file */ + int nbyte; /* Uncompressed size of the virtual file */ + int nbytecompr; /* Compressed size of the virtual file */ + int cmeth; /* Compress method */ + int isdir; /* Set to 1 if directory, or -1 if root */ + int depth; /* Number of slashes in path. */ + int crc32; /* CRC-32 */ + int timestamp; /* Modification time */ + int isenc; /* True if data is encrypted */ + unsigned char *data; /* File data if written */ + struct ZipEntry *next; /* Next file in the same archive */ + struct ZipEntry *tnext; /* Next top-level dir in archive */ } ZipEntry; /* @@ -213,40 +221,41 @@ typedef struct ZipEntry { */ typedef struct ZipChannel { - ZipFile *zipfile; /* The ZIP file holding this channel */ - ZipEntry *zipentry; /* Pointer back to virtual file */ - size_t nmax; /* Max. size for write */ - size_t nbyte; /* Number of bytes of uncompressed data */ - size_t nread; /* Pos of next byte to be read from the channel */ - unsigned char *ubuf; /* Pointer to the uncompressed data */ - int iscompr; /* True if data is compressed */ - int isdir; /* Set to 1 if directory, or -1 if root */ - int isenc; /* True if data is encrypted */ - int iswr; /* True if open for writing */ - unsigned long keys[3]; /* Key for decryption */ + ZipFile *zipfile; /* The ZIP file holding this channel */ + ZipEntry *zipentry; /* Pointer back to virtual file */ + size_t nmax; /* Maximum size for write */ + size_t nbyte; /* Number of bytes of uncompressed data */ + size_t nread; /* Position of next byte to be read from the + * channel */ + unsigned char *ubuf; /* Pointer to the uncompressed data */ + int iscompr; /* True if data is compressed */ + int isdir; /* Set to 1 if directory, or -1 if root */ + int isenc; /* True if data is encrypted */ + int iswr; /* True if open for writing */ + unsigned long keys[3]; /* Key for decryption */ } ZipChannel; /* * Global variables. * - * Most are kept in single ZipFS struct. When build with threading - * support this struct is protected by the ZipFSMutex (see below). + * Most are kept in single ZipFS struct. When build with threading support + * this struct is protected by the ZipFSMutex (see below). * - * The "fileHash" component is the process wide global table of all known - * ZIP archive members in all mounted ZIP archives. + * The "fileHash" component is the process wide global table of all known ZIP + * archive members in all mounted ZIP archives. * * The "zipHash" components is the process wide global table of all mounted * ZIP archive files. */ static struct { - int initialized; /* True when initialized */ - int lock; /* RW lock, see below */ - int waiters; /* RW lock, see below */ - int wrmax; /* Maximum write size of a file */ - int idCount; /* Counter for channel names */ - Tcl_HashTable fileHash; /* File name to ZipEntry mapping */ - Tcl_HashTable zipHash; /* Mount to ZipFile mapping */ + int initialized; /* True when initialized */ + int lock; /* RW lock, see below */ + int waiters; /* RW lock, see below */ + int wrmax; /* Maximum write size of a file */ + int idCount; /* Counter for channel names */ + Tcl_HashTable fileHash; /* File name to ZipEntry mapping */ + Tcl_HashTable zipHash; /* Mount to ZipFile mapping */ } ZipFS = { 0, 0, 0, 0, 0, }; @@ -319,47 +328,38 @@ static const z_crc_t crc32tab[256] = { 0x2d02ef8d, }; -const char *zipfs_literal_tcl_library=NULL; +const char *zipfs_literal_tcl_library = NULL; /* Function prototypes */ -int TclZipfs_Mount( - Tcl_Interp *interp, - const char *mntpt, - const char *zipname, - const char *passwd -); -int TclZipfs_Mount_Buffer( - Tcl_Interp *interp, - const char *mntpt, - unsigned char *data, - size_t datalen, - int copy -); -static int TclZipfs_AppHook_FindTclInit(const char *archive); -static int Zip_FSPathInFilesystemProc(Tcl_Obj *pathPtr, ClientData *clientDataPtr); -static Tcl_Obj *Zip_FSFilesystemPathTypeProc(Tcl_Obj *pathPtr); -static Tcl_Obj *Zip_FSFilesystemSeparatorProc(Tcl_Obj *pathPtr); -static int Zip_FSStatProc(Tcl_Obj *pathPtr, Tcl_StatBuf *buf); -static int Zip_FSAccessProc(Tcl_Obj *pathPtr, int mode); -static Tcl_Channel Zip_FSOpenFileChannelProc( - Tcl_Interp *interp, Tcl_Obj *pathPtr, - int mode, int permissions -); -static int Zip_FSMatchInDirectoryProc( - Tcl_Interp* interp, Tcl_Obj *result, - Tcl_Obj *pathPtr, const char *pattern, - Tcl_GlobTypeData *types -); -static Tcl_Obj *Zip_FSListVolumesProc(void); -static const char *const *Zip_FSFileAttrStringsProc(Tcl_Obj *pathPtr, Tcl_Obj** objPtrRef); -static int Zip_FSFileAttrsGetProc( - Tcl_Interp *interp, int index, Tcl_Obj *pathPtr, - Tcl_Obj **objPtrRef -); -static int Zip_FSFileAttrsSetProc(Tcl_Interp *interp, int index, Tcl_Obj *pathPtr,Tcl_Obj *objPtr); -static int Zip_FSLoadFile(Tcl_Interp *interp, Tcl_Obj *path, Tcl_LoadHandle *loadHandle, - Tcl_FSUnloadFileProc **unloadProcPtr, int flags); -static void TclZipfs_C_Init(void); + +int TclZipfs_Mount(Tcl_Interp *interp, const char *mntpt, + const char *zipname, const char *passwd); +int TclZipfs_Mount_Buffer(Tcl_Interp *interp, + const char *mntpt, unsigned char *data, + size_t datalen, int copy); +static int TclZipfs_AppHook_FindTclInit(const char *archive); +static int Zip_FSPathInFilesystemProc(Tcl_Obj *pathPtr, + ClientData *clientDataPtr); +static Tcl_Obj * Zip_FSFilesystemPathTypeProc(Tcl_Obj *pathPtr); +static Tcl_Obj * Zip_FSFilesystemSeparatorProc(Tcl_Obj *pathPtr); +static int Zip_FSStatProc(Tcl_Obj *pathPtr, Tcl_StatBuf *buf); +static int Zip_FSAccessProc(Tcl_Obj *pathPtr, int mode); +static Tcl_Channel Zip_FSOpenFileChannelProc(Tcl_Interp *interp, + Tcl_Obj *pathPtr, int mode, int permissions); +static int Zip_FSMatchInDirectoryProc(Tcl_Interp *interp, + Tcl_Obj *result, Tcl_Obj *pathPtr, + const char *pattern, Tcl_GlobTypeData *types); +static Tcl_Obj * Zip_FSListVolumesProc(void); +static const char *const *Zip_FSFileAttrStringsProc(Tcl_Obj *pathPtr, + Tcl_Obj** objPtrRef); +static int Zip_FSFileAttrsGetProc(Tcl_Interp *interp, int index, + Tcl_Obj *pathPtr, Tcl_Obj **objPtrRef); +static int Zip_FSFileAttrsSetProc(Tcl_Interp *interp, int index, + Tcl_Obj *pathPtr, Tcl_Obj *objPtr); +static int Zip_FSLoadFile(Tcl_Interp *interp, Tcl_Obj *path, + Tcl_LoadHandle *loadHandle, + Tcl_FSUnloadFileProc **unloadProcPtr, int flags); +static void TclZipfs_C_Init(void); /* * Define the ZIP filesystem dispatch table. @@ -400,16 +400,14 @@ const Tcl_Filesystem zipfsFilesystem = { NULL, /* getCwdProc */ NULL, /* chdirProc*/ }; - - /* *------------------------------------------------------------------------- * * ReadLock, WriteLock, Unlock -- * - * POSIX like rwlock functions to support multiple readers - * and single writer on internal structs. + * POSIX like rwlock functions to support multiple readers and single + * writer on internal structs. * * Limitations: * - a read lock cannot be promoted to a write lock @@ -429,9 +427,9 @@ ReadLock(void) { Tcl_MutexLock(&ZipFSMutex); while (ZipFS.lock < 0) { - ZipFS.waiters++; - Tcl_ConditionWait(&ZipFSCond, &ZipFSMutex, NULL); - ZipFS.waiters--; + ZipFS.waiters++; + Tcl_ConditionWait(&ZipFSCond, &ZipFSMutex, NULL); + ZipFS.waiters--; } ZipFS.lock++; Tcl_MutexUnlock(&ZipFSMutex); @@ -442,9 +440,9 @@ WriteLock(void) { Tcl_MutexLock(&ZipFSMutex); while (ZipFS.lock != 0) { - ZipFS.waiters++; - Tcl_ConditionWait(&ZipFSCond, &ZipFSMutex, NULL); - ZipFS.waiters--; + ZipFS.waiters++; + Tcl_ConditionWait(&ZipFSCond, &ZipFSMutex, NULL); + ZipFS.waiters--; } ZipFS.lock = -1; Tcl_MutexUnlock(&ZipFSMutex); @@ -455,42 +453,42 @@ Unlock(void) { Tcl_MutexLock(&ZipFSMutex); if (ZipFS.lock > 0) { - --ZipFS.lock; + --ZipFS.lock; } else if (ZipFS.lock < 0) { - ZipFS.lock = 0; + ZipFS.lock = 0; } if ((ZipFS.lock == 0) && (ZipFS.waiters > 0)) { - Tcl_ConditionNotify(&ZipFSCond); + Tcl_ConditionNotify(&ZipFSCond); } Tcl_MutexUnlock(&ZipFSMutex); } -#else - -#define ReadLock() do {} while (0) -#define WriteLock() do {} while (0) -#define Unlock() do {} while (0) - -#endif +#else /* !TCL_THREADS */ +#define ReadLock() do {} while (0) +#define WriteLock() do {} while (0) +#define Unlock() do {} while (0) +#endif /* TCL_THREADS */ /* *------------------------------------------------------------------------- * * DosTimeDate, ToDosTime, ToDosDate -- * - * Functions to perform conversions between DOS time stamps - * and POSIX time_t. + * Functions to perform conversions between DOS time stamps and POSIX + * time_t. * *------------------------------------------------------------------------- */ static time_t -DosTimeDate(int dosDate, int dosTime) +DosTimeDate( + int dosDate, + int dosTime) { struct tm tm; time_t ret; - memset(&tm, 0, sizeof (tm)); + memset(&tm, 0, sizeof(struct tm)); tm.tm_year = (((dosDate & 0xfe00) >> 9) + 80); tm.tm_mon = ((dosDate & 0x1e0) >> 5) - 1; tm.tm_mday = dosDate & 0x1f; @@ -499,65 +497,65 @@ DosTimeDate(int dosDate, int dosTime) tm.tm_sec = (dosTime & 0x1f) << 1; ret = mktime(&tm); if (ret == (time_t) -1) { - /* fallback to 1980-01-01T00:00:00+00:00 (DOS epoch) */ - ret = (time_t) 315532800; + /* fallback to 1980-01-01T00:00:00+00:00 (DOS epoch) */ + ret = (time_t) 315532800; } return ret; } static int -ToDosTime(time_t when) +ToDosTime( + time_t when) { struct tm *tmp, tm; -#ifdef TCL_THREADS -#ifdef _WIN32 +#if !defined(TCL_THREADS) + /* Not threaded */ + tmp = localtime(&when); + tm = *tmp; +#elif defined(_WIN32) /* Win32 uses thread local storage */ tmp = localtime(&when); tm = *tmp; -#else -#ifdef HAVE_LOCALTIME_R +#elif defined(HAVE_LOCALTIME_R) + /* Threaded, have reentrant API */ tmp = &tm; localtime_r(&when, tmp); -#else +#else /* TCL_THREADS && !_WIN32 && !HAVE_LOCALTIME_R */ + /* Only using a mutex is safe. */ Tcl_MutexLock(&localtimeMutex); tmp = localtime(&when); tm = *tmp; Tcl_MutexUnlock(&localtimeMutex); #endif -#endif -#else - tmp = localtime(&when); - tm = *tmp; -#endif return (tm.tm_hour << 11) | (tm.tm_min << 5) | (tm.tm_sec >> 1); } static int -ToDosDate(time_t when) +ToDosDate( + time_t when) { struct tm *tmp, tm; -#ifdef TCL_THREADS -#ifdef _WIN32 +#if !defined(TCL_THREADS) + /* Not threaded */ + tmp = localtime(&when); + tm = *tmp; +#elif /* TCL_THREADS && */ defined(_WIN32) /* Win32 uses thread local storage */ tmp = localtime(&when); tm = *tmp; -#else -#ifdef HAVE_LOCALTIME_R +#elif /* TCL_THREADS && !_WIN32 && */ defined(HAVE_LOCALTIME_R) + /* Threaded, have reentrant API */ tmp = &tm; localtime_r(&when, tmp); -#else +#else /* TCL_THREADS && !_WIN32 && !HAVE_LOCALTIME_R */ + /* Only using a mutex is safe. */ Tcl_MutexLock(&localtimeMutex); tmp = localtime(&when); tm = *tmp; Tcl_MutexUnlock(&localtimeMutex); #endif -#endif -#else - tmp = localtime(&when); - tm = *tmp; -#endif return ((tm.tm_year - 80) << 9) | ((tm.tm_mon + 1) << 5) | tm.tm_mday; } @@ -566,28 +564,29 @@ ToDosDate(time_t when) * * CountSlashes -- * - * This function counts the number of slashes in a pathname string. + * This function counts the number of slashes in a pathname string. * * Results: - * Number of slashes found in string. + * Number of slashes found in string. * * Side effects: - * None. + * None. * *------------------------------------------------------------------------- */ static int -CountSlashes(const char *string) +CountSlashes( + const char *string) { int count = 0; const char *p = string; while (*p != '\0') { - if (*p == '/') { - count++; - } - p++; + if (*p == '/') { + count++; + } + p++; } return count; } @@ -597,162 +596,171 @@ CountSlashes(const char *string) * * CanonicalPath -- * - * This function computes the canonical path from a directory - * and file name components into the specified Tcl_DString. + * This function computes the canonical path from a directory and file + * name components into the specified Tcl_DString. * * Results: - * Returns the pointer to the canonical path contained in the - * specified Tcl_DString. + * Returns the pointer to the canonical path contained in the specified + * Tcl_DString. * * Side effects: - * Modifies the specified Tcl_DString. + * Modifies the specified Tcl_DString. * *------------------------------------------------------------------------- */ static char * -CanonicalPath(const char *root, const char *tail, Tcl_DString *dsPtr,int ZIPFSPATH) +CanonicalPath( + const char *root, + const char *tail, + Tcl_DString *dsPtr, + int ZIPFSPATH) { char *path; - char *result; - int i, j, c, isunc = 0, isvfs=0, n=0; + int i, j, c, isunc = 0, isvfs = 0, n = 0; + int zipfspath = 1; + #ifdef _WIN32 - int zipfspath=1; - if ( - (tail[0] != '\0') - && (strchr(drvletters, tail[0]) != NULL) - && (tail[1] == ':') - ) { - tail += 2; - zipfspath=0; + if ((tail[0] != '\0') && (strchr(drvletters, tail[0]) != NULL) + && (tail[1] == ':')) { + tail += 2; + zipfspath = 0; } /* UNC style path */ if (tail[0] == '\\') { - root = ""; - ++tail; - zipfspath=0; + root = ""; + ++tail; + zipfspath = 0; } if (tail[0] == '\\') { - root = "/"; - ++tail; - zipfspath=0; - } - if(zipfspath) { -#endif - /* UNC style path */ - if(root && strncmp(root,ZIPFS_VOLUME,ZIPFS_VOLUME_LEN)==0) { - isvfs=1; - } else if (tail && strncmp(tail,ZIPFS_VOLUME,ZIPFS_VOLUME_LEN) == 0) { - isvfs=2; - } - if(isvfs!=1) { - if ((root[0] == '/') && (root[1] == '/')) { - isunc = 1; - } - } -#ifdef _WIN32 - } -#endif - if(isvfs!=2) { - if (tail[0] == '/') { - if(isvfs!=1) { - root = ""; - } - ++tail; - isunc = 0; - } - if (tail[0] == '/') { - if(isvfs!=1) { - root = "/"; - } - ++tail; - isunc = 1; - } + root = "/"; + ++tail; + zipfspath = 0; + } +#endif /* _WIN32 */ + + if (zipfspath) { + /* UNC style path */ + if (root && strncmp(root, ZIPFS_VOLUME, ZIPFS_VOLUME_LEN) == 0) { + isvfs = 1; + } else if (tail && + strncmp(tail, ZIPFS_VOLUME, ZIPFS_VOLUME_LEN) == 0) { + isvfs = 2; + } + if (isvfs != 1) { + if ((root[0] == '/') && (root[1] == '/')) { + isunc = 1; + } + } + } + + if (isvfs != 2) { + if (tail[0] == '/') { + if (isvfs != 1) { + root = ""; + } + ++tail; + isunc = 0; + } + if (tail[0] == '/') { + if (isvfs != 1) { + root = "/"; + } + ++tail; + isunc = 1; + } } i = strlen(root); j = strlen(tail); - if(isvfs==1) { - if(i>ZIPFS_VOLUME_LEN) { - Tcl_DStringSetLength(dsPtr, i + j + 1); - path = Tcl_DStringValue(dsPtr); - memcpy(path, root, i); - path[i++] = '/'; - memcpy(path + i, tail, j); - } else { - Tcl_DStringSetLength(dsPtr, i + j); - path = Tcl_DStringValue(dsPtr); - memcpy(path, root, i); - memcpy(path + i, tail, j); - } - } else if(isvfs==2) { - Tcl_DStringSetLength(dsPtr, j); - path = Tcl_DStringValue(dsPtr); - memcpy(path, tail, j); - } else { - if (ZIPFSPATH) { - Tcl_DStringSetLength(dsPtr, i + j + ZIPFS_VOLUME_LEN); - path = Tcl_DStringValue(dsPtr); - memcpy(path, ZIPFS_VOLUME, ZIPFS_VOLUME_LEN); - memcpy(path + ZIPFS_VOLUME_LEN + i , tail, j); - } else { - Tcl_DStringSetLength(dsPtr, i + j + 1); - path = Tcl_DStringValue(dsPtr); - memcpy(path, root, i); - path[i++] = '/'; - memcpy(path + i, tail, j); - } + + switch (isvfs) { + case 1: + if (i > ZIPFS_VOLUME_LEN) { + Tcl_DStringSetLength(dsPtr, i + j + 1); + path = Tcl_DStringValue(dsPtr); + memcpy(path, root, i); + path[i++] = '/'; + memcpy(path + i, tail, j); + } else { + Tcl_DStringSetLength(dsPtr, i + j); + path = Tcl_DStringValue(dsPtr); + memcpy(path, root, i); + memcpy(path + i, tail, j); + } + break; + case 2: + Tcl_DStringSetLength(dsPtr, j); + path = Tcl_DStringValue(dsPtr); + memcpy(path, tail, j); + break; + default: + if (ZIPFSPATH) { + Tcl_DStringSetLength(dsPtr, i + j + ZIPFS_VOLUME_LEN); + path = Tcl_DStringValue(dsPtr); + memcpy(path, ZIPFS_VOLUME, ZIPFS_VOLUME_LEN); + memcpy(path + ZIPFS_VOLUME_LEN + i , tail, j); + } else { + Tcl_DStringSetLength(dsPtr, i + j + 1); + path = Tcl_DStringValue(dsPtr); + memcpy(path, root, i); + path[i++] = '/'; + memcpy(path + i, tail, j); + } + break; } + #ifdef _WIN32 for (i = 0; path[i] != '\0'; i++) { - if (path[i] == '\\') { - path[i] = '/'; - } + if (path[i] == '\\') { + path[i] = '/'; + } } #endif - if(ZIPFSPATH) { - n=ZIPFS_VOLUME_LEN; + + if (ZIPFSPATH) { + n = ZIPFS_VOLUME_LEN; } else { - n=0; + n = 0; } + for (i = j = n; (c = path[i]) != '\0'; i++) { - if (c == '/') { - int c2 = path[i + 1]; - if (c2 == '/') { - continue; - } - if (c2 == '.') { - int c3 = path[i + 2]; - if ((c3 == '/') || (c3 == '\0')) { - i++; - continue; - } - if ( - (c3 == '.') - && ((path[i + 3] == '/') || (path [i + 3] == '\0')) - ) { - i += 2; - while ((j > 0) && (path[j - 1] != '/')) { - j--; - } - if (j > isunc) { - --j; - while ((j > 1 + isunc) && (path[j - 2] == '/')) { - j--; - } - } - continue; - } - } - } - path[j++] = c; + if (c == '/') { + int c2 = path[i + 1]; + + if (c2 == '\0' || c2 == '/') { + continue; + } + if (c2 == '.') { + int c3 = path[i + 2]; + + if ((c3 == '/') || (c3 == '\0')) { + i++; + continue; + } + if ((c3 == '.') + && ((path[i + 3] == '/') || (path [i + 3] == '\0'))) { + i += 2; + while ((j > 0) && (path[j - 1] != '/')) { + j--; + } + if (j > isunc) { + --j; + while ((j > 1 + isunc) && (path[j - 2] == '/')) { + j--; + } + } + continue; + } + } + } + path[j++] = c; } if (j == 0) { - path[j++] = '/'; + path[j++] = '/'; } path[j] = 0; Tcl_DStringSetLength(dsPtr, j); - result=Tcl_DStringValue(dsPtr); - return result; + return Tcl_DStringValue(dsPtr); } /* @@ -760,263 +768,279 @@ CanonicalPath(const char *root, const char *tail, Tcl_DString *dsPtr,int ZIPFSPA * * ZipFSLookup -- * - * This function returns the ZIP entry struct corresponding to - * the ZIP archive member of the given file name. + * This function returns the ZIP entry struct corresponding to the ZIP + * archive member of the given file name. * * Results: - * Returns the pointer to ZIP entry struct or NULL if the - * the given file name could not be found in the global list - * of ZIP archive members. + * Returns the pointer to ZIP entry struct or NULL if the the given file + * name could not be found in the global list of ZIP archive members. * * Side effects: - * None. + * None. * *------------------------------------------------------------------------- */ static ZipEntry * -ZipFSLookup(char *filename) +ZipFSLookup( + char *filename) { Tcl_HashEntry *hPtr; - ZipEntry *z; - Tcl_DString ds; - Tcl_DStringInit(&ds); + ZipEntry *z = NULL; + hPtr = Tcl_FindHashEntry(&ZipFS.fileHash, filename); - z = hPtr ? (ZipEntry *) Tcl_GetHashValue(hPtr) : NULL; - Tcl_DStringFree(&ds); + if (hPtr != NULL) { + z = Tcl_GetHashValue(hPtr); + } return z; } - -#ifdef NEVER_USED +#ifdef NEVER_USED + /* *------------------------------------------------------------------------- * * ZipFSLookupMount -- * - * This function returns an indication if the given file name - * corresponds to a mounted ZIP archive file. + * This function returns an indication if the given file name corresponds + * to a mounted ZIP archive file. * * Results: - * Returns true, if the given file name is a mounted ZIP archive file. + * Returns true, if the given file name is a mounted ZIP archive file. * * Side effects: - * None. + * None. * *------------------------------------------------------------------------- */ static int -ZipFSLookupMount(char *filename) +ZipFSLookupMount( + char *filename) { Tcl_HashEntry *hPtr; Tcl_HashSearch search; ZipFile *zf; int match = 0; + hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); while (hPtr != NULL) { - if ((zf = (ZipFile *) Tcl_GetHashValue(hPtr)) == NULL) continue; - if (strcmp(zf->mntpt, filename) == 0) { - match = 1; - break; - } - hPtr = Tcl_NextHashEntry(&search); + if ((zf = (ZipFile *) Tcl_GetHashValue(hPtr)) == NULL) { + continue; + } + if (strcmp(zf->mntpt, filename) == 0) { + match = 1; + break; + } + hPtr = Tcl_NextHashEntry(&search); } return match; } -#endif +#endif /* NEVER_USED */ /* *------------------------------------------------------------------------- * * ZipFSCloseArchive -- * - * This function closes a mounted ZIP archive file. + * This function closes a mounted ZIP archive file. * * Results: - * None. + * None. * * Side effects: - * A memory mapped ZIP archive is unmapped, allocated memory is - * released. + * A memory mapped ZIP archive is unmapped, allocated memory is released. + * The ZipFile pointer is *NOT* deallocated by this function. * *------------------------------------------------------------------------- */ static void -ZipFSCloseArchive(Tcl_Interp *interp, ZipFile *zf) +ZipFSCloseArchive( + Tcl_Interp *interp, + ZipFile *zf) { - if(zf->namelen) { - free(zf->name); //Allocated by strdup - } - if(zf->is_membuf==1) { - /* Pointer to memory */ - if (zf->tofree != NULL) { - Tcl_Free(zf->tofree); - zf->tofree = NULL; - } - zf->data = NULL; - return; + if (zf->namelen) { + free(zf->name); /* Allocated by strdup */ } + if (zf->is_membuf == 1) { + /* Pointer to memory */ + if (zf->tofree != NULL) { + Tcl_Free(zf->tofree); + zf->tofree = NULL; + } + zf->data = NULL; + return; + } + #ifdef _WIN32 if ((zf->data != NULL) && (zf->tofree == NULL)) { - UnmapViewOfFile(zf->data); - zf->data = NULL; + UnmapViewOfFile(zf->data); + zf->data = NULL; } if (zf->mh != INVALID_HANDLE_VALUE) { - CloseHandle(zf->mh); + CloseHandle(zf->mh); } -#else +#else /* !_WIN32 */ if ((zf->data != MAP_FAILED) && (zf->tofree == NULL)) { - munmap(zf->data, zf->length); - zf->data = MAP_FAILED; + munmap(zf->data, zf->length); + zf->data = MAP_FAILED; } -#endif +#endif /* _WIN32 */ + if (zf->tofree != NULL) { - Tcl_Free(zf->tofree); - zf->tofree = NULL; + Tcl_Free(zf->tofree); + zf->tofree = NULL; } - if(zf->chan != NULL) { - Tcl_Close(interp, zf->chan); - zf->chan = NULL; + if (zf->chan != NULL) { + Tcl_Close(interp, zf->chan); + zf->chan = NULL; } } - + /* *------------------------------------------------------------------------- * * ZipFS_Find_TOC -- * - * This function takes a memory mapped zip file and indexes the contents. - * When "needZip" is zero an embedded ZIP archive in an executable file is accepted. + * This function takes a memory mapped zip file and indexes the contents. + * When "needZip" is zero an embedded ZIP archive in an executable file + * is accepted. * * Results: - * TCL_OK on success, TCL_ERROR otherwise with an error message - * placed into the given "interp" if it is not NULL. + * TCL_OK on success, TCL_ERROR otherwise with an error message placed + * into the given "interp" if it is not NULL. * * Side effects: - * The given ZipFile struct is filled with information about the ZIP archive file. + * The given ZipFile struct is filled with information about the ZIP + * archive file. * *------------------------------------------------------------------------- */ + static int -ZipFS_Find_TOC(Tcl_Interp *interp, int needZip, ZipFile *zf) +ZipFS_Find_TOC( + Tcl_Interp *interp, + int needZip, + ZipFile *zf) { size_t i; unsigned char *p, *q; + p = zf->data + zf->length - ZIP_CENTRAL_END_LEN; while (p >= zf->data) { - if (*p == (ZIP_CENTRAL_END_SIG & 0xFF)) { - if (zip_read_int(p) == ZIP_CENTRAL_END_SIG) { - break; - } - p -= ZIP_SIG_LEN; - } else { - --p; - } + if (*p == (ZIP_CENTRAL_END_SIG & 0xFF)) { + if (zip_read_int(p) == ZIP_CENTRAL_END_SIG) { + break; + } + p -= ZIP_SIG_LEN; + } else { + --p; + } } if (p < zf->data) { - if (!needZip) { - zf->baseoffs = zf->baseoffsp = zf->length; - return TCL_OK; - } - ZIPFS_ERROR(interp,"wrong end signature"); - goto error; + if (!needZip) { + zf->baseoffs = zf->baseoffsp = zf->length; + return TCL_OK; + } + ZIPFS_ERROR(interp, "wrong end signature"); + goto error; } zf->nfiles = zip_read_short(p + ZIP_CENTRAL_ENTS_OFFS); if (zf->nfiles == 0) { - if (!needZip) { - zf->baseoffs = zf->baseoffsp = zf->length; - return TCL_OK; - } - ZIPFS_ERROR(interp,"empty archive"); - goto error; + if (!needZip) { + zf->baseoffs = zf->baseoffsp = zf->length; + return TCL_OK; + } + ZIPFS_ERROR(interp, "empty archive"); + goto error; } q = zf->data + zip_read_int(p + ZIP_CENTRAL_DIRSTART_OFFS); p -= zip_read_int(p + ZIP_CENTRAL_DIRSIZE_OFFS); - if ( - (p < zf->data) || (p > (zf->data + zf->length)) || - (q < zf->data) || (q > (zf->data + zf->length)) - ) { - if (!needZip) { - zf->baseoffs = zf->baseoffsp = zf->length; - return TCL_OK; - } - ZIPFS_ERROR(interp,"archive directory not found"); - goto error; + if ((p < zf->data) || (p > zf->data + zf->length) + || (q < zf->data) || (q > (zf->data + zf->length))) { + if (!needZip) { + zf->baseoffs = zf->baseoffsp = zf->length; + return TCL_OK; + } + ZIPFS_ERROR(interp, "archive directory not found"); + goto error; } zf->baseoffs = zf->baseoffsp = p - q; zf->centoffs = p - zf->data; q = p; for (i = 0; i < zf->nfiles; i++) { - int pathlen, comlen, extra; - - if ((q + ZIP_CENTRAL_HEADER_LEN) > (zf->data + zf->length)) { - ZIPFS_ERROR(interp,"wrong header length"); - goto error; - } - if (zip_read_int(q) != ZIP_CENTRAL_HEADER_SIG) { - ZIPFS_ERROR(interp,"wrong header signature"); - goto error; - } - pathlen = zip_read_short(q + ZIP_CENTRAL_PATHLEN_OFFS); - comlen = zip_read_short(q + ZIP_CENTRAL_FCOMMENTLEN_OFFS); - extra = zip_read_short(q + ZIP_CENTRAL_EXTRALEN_OFFS); - q += pathlen + comlen + extra + ZIP_CENTRAL_HEADER_LEN; + int pathlen, comlen, extra; + + if (q + ZIP_CENTRAL_HEADER_LEN > zf->data + zf->length) { + ZIPFS_ERROR(interp, "wrong header length"); + goto error; + } + if (zip_read_int(q) != ZIP_CENTRAL_HEADER_SIG) { + ZIPFS_ERROR(interp, "wrong header signature"); + goto error; + } + pathlen = zip_read_short(q + ZIP_CENTRAL_PATHLEN_OFFS); + comlen = zip_read_short(q + ZIP_CENTRAL_FCOMMENTLEN_OFFS); + extra = zip_read_short(q + ZIP_CENTRAL_EXTRALEN_OFFS); + q += pathlen + comlen + extra + ZIP_CENTRAL_HEADER_LEN; } q = zf->data + zf->baseoffs; if ((zf->baseoffs >= 6) && (zip_read_int(q - 4) == ZIP_PASSWORD_END_SIG)) { - i = q[-5]; - if (q - 5 - i > zf->data) { - zf->pwbuf[0] = i; - memcpy(zf->pwbuf + 1, q - 5 - i, i); - zf->baseoffsp -= i ? (5 + i) : 0; - } + i = q[-5]; + if (q - 5 - i > zf->data) { + zf->pwbuf[0] = i; + memcpy(zf->pwbuf + 1, q - 5 - i, i); + zf->baseoffsp -= i ? (5 + i) : 0; + } } - return TCL_OK; -error: + error: ZipFSCloseArchive(interp, zf); return TCL_ERROR; } - + /* *------------------------------------------------------------------------- * * ZipFSOpenArchive -- * - * This function opens a ZIP archive file for reading. An attempt - * is made to memory map that file. Otherwise it is read into - * an allocated memory buffer. The ZIP archive header is verified - * and must be valid for the function to succeed. When "needZip" - * is zero an embedded ZIP archive in an executable file is accepted. + * This function opens a ZIP archive file for reading. An attempt is made + * to memory map that file. Otherwise it is read into an allocated memory + * buffer. The ZIP archive header is verified and must be valid for the + * function to succeed. When "needZip" is zero an embedded ZIP archive in + * an executable file is accepted. * * Results: - * TCL_OK on success, TCL_ERROR otherwise with an error message - * placed into the given "interp" if it is not NULL. + * TCL_OK on success, TCL_ERROR otherwise with an error message placed + * into the given "interp" if it is not NULL. * * Side effects: - * ZIP archive is memory mapped or read into allocated memory, - * the given ZipFile struct is filled with information about - * the ZIP archive file. + * ZIP archive is memory mapped or read into allocated memory, the given + * ZipFile struct is filled with information about the ZIP archive file. * *------------------------------------------------------------------------- */ static int -ZipFSOpenArchive(Tcl_Interp *interp, const char *zipname, int needZip, ZipFile *zf) +ZipFSOpenArchive( + Tcl_Interp *interp, + const char *zipname, + int needZip, + ZipFile *zf) { size_t i; ClientData handle; - zf->namelen=0; - zf->is_membuf=0; + + zf->namelen = 0; + zf->is_membuf = 0; #ifdef _WIN32 zf->data = NULL; zf->mh = INVALID_HANDLE_VALUE; -#else +#else /* !_WIN32 */ zf->data = MAP_FAILED; -#endif +#endif /* _WIN32 */ zf->length = 0; zf->nfiles = 0; zf->baseoffs = zf->baseoffsp = 0; @@ -1024,83 +1048,79 @@ ZipFSOpenArchive(Tcl_Interp *interp, const char *zipname, int needZip, ZipFile * zf->pwbuf[0] = 0; zf->chan = Tcl_OpenFileChannel(interp, zipname, "r", 0); if (zf->chan == NULL) { - return TCL_ERROR; + return TCL_ERROR; } if (Tcl_GetChannelHandle(zf->chan, TCL_READABLE, &handle) != TCL_OK) { - if (Tcl_SetChannelOption(interp, zf->chan, "-translation", "binary") != TCL_OK) { - goto error; - } - if (Tcl_SetChannelOption(interp, zf->chan, "-encoding", "binary") != TCL_OK) { - goto error; - } - zf->length = Tcl_Seek(zf->chan, 0, SEEK_END); - if ((zf->length - ZIP_CENTRAL_END_LEN) > (64 * 1024 * 1024 - ZIP_CENTRAL_END_LEN)) { - ZIPFS_ERROR(interp,"illegal file size"); - goto error; - } - Tcl_Seek(zf->chan, 0, SEEK_SET); - zf->tofree = zf->data = (unsigned char *) Tcl_AttemptAlloc(zf->length); - if (zf->tofree == NULL) { - ZIPFS_ERROR(interp,"out of memory") - goto error; - } - i = Tcl_Read(zf->chan, (char *) zf->data, zf->length); - if (i != zf->length) { - ZIPFS_ERROR(interp,"file read error"); - goto error; - } - Tcl_Close(interp, zf->chan); - zf->chan = NULL; + if (Tcl_SetChannelOption(interp, zf->chan, "-translation", + "binary") != TCL_OK) { + goto error; + } + zf->length = Tcl_Seek(zf->chan, 0, SEEK_END); + if ((zf->length - ZIP_CENTRAL_END_LEN) + > (64 * 1024 * 1024 - ZIP_CENTRAL_END_LEN)) { + ZIPFS_ERROR(interp, "illegal file size"); + goto error; + } + Tcl_Seek(zf->chan, 0, SEEK_SET); + zf->tofree = zf->data = (unsigned char *) Tcl_AttemptAlloc(zf->length); + if (zf->tofree == NULL) { + ZIPFS_ERROR(interp, "out of memory"); + goto error; + } + i = Tcl_Read(zf->chan, (char *) zf->data, zf->length); + if (i != zf->length) { + ZIPFS_ERROR(interp, "file read error"); + goto error; + } + Tcl_Close(interp, zf->chan); + zf->chan = NULL; } else { #ifdef _WIN32 + int readSuccessful; # ifdef _WIN64 - i = GetFileSizeEx((HANDLE) handle, (PLARGE_INTEGER)&zf->length); - if ( - (i == 0) || -# else - zf->length = GetFileSize((HANDLE) handle, 0); - if ( - (zf->length == (size_t)INVALID_FILE_SIZE) || -# endif - (zf->length < ZIP_CENTRAL_END_LEN) - ) { - ZIPFS_ERROR(interp,"invalid file size"); - goto error; - } - zf->mh = CreateFileMapping((HANDLE) handle, 0, PAGE_READONLY, 0, - zf->length, 0); - if (zf->mh == INVALID_HANDLE_VALUE) { - ZIPFS_ERROR(interp,"file mapping failed"); - goto error; - } - zf->data = MapViewOfFile(zf->mh, FILE_MAP_READ, 0, 0, zf->length); - if (zf->data == NULL) { - ZIPFS_ERROR(interp,"file mapping failed"); - goto error; - } -#else - zf->length = lseek(PTR2INT(handle), 0, SEEK_END); - if ((zf->length == (size_t)-1) || (zf->length < ZIP_CENTRAL_END_LEN)) { - ZIPFS_ERROR(interp,"invalid file size"); - goto error; - } - lseek(PTR2INT(handle), 0, SEEK_SET); - zf->data = (unsigned char *) mmap(0, zf->length, PROT_READ, - MAP_FILE | MAP_PRIVATE, - PTR2INT(handle), 0); - if (zf->data == MAP_FAILED) { - ZIPFS_ERROR(interp,"file mapping failed"); - goto error; - } -#endif - } - return ZipFS_Find_TOC(interp,needZip,zf); - -error: + i = GetFileSizeEx((HANDLE) handle, (PLARGE_INTEGER) &zf->length); + readSuccessful = (i != 0); +# else /* !_WIN64 */ + zf->length = GetFileSize((HANDLE) handle, 0); + readSuccessful = (zf->length != (size_t) INVALID_FILE_SIZE); +# endif /* _WIN64 */ + if (!readSuccessful || (zf->length < ZIP_CENTRAL_END_LEN)) { + ZIPFS_ERROR(interp, "invalid file size"); + goto error; + } + zf->mh = CreateFileMapping((HANDLE) handle, 0, PAGE_READONLY, 0, + zf->length, 0); + if (zf->mh == INVALID_HANDLE_VALUE) { + ZIPFS_ERROR(interp, "file mapping failed"); + goto error; + } + zf->data = MapViewOfFile(zf->mh, FILE_MAP_READ, 0, 0, zf->length); + if (zf->data == NULL) { + ZIPFS_ERROR(interp, "file mapping failed"); + goto error; + } +#else /* !_WIN32 */ + zf->length = lseek(PTR2INT(handle), 0, SEEK_END); + if ((zf->length == (size_t)-1) || (zf->length < ZIP_CENTRAL_END_LEN)) { + ZIPFS_ERROR(interp, "invalid file size"); + goto error; + } + lseek(PTR2INT(handle), 0, SEEK_SET); + zf->data = (unsigned char *) mmap(0, zf->length, PROT_READ, + MAP_FILE | MAP_PRIVATE, PTR2INT(handle), 0); + if (zf->data == MAP_FAILED) { + ZIPFS_ERROR(interp, "file mapping failed"); + goto error; + } +#endif /* _WIN32 */ + } + return ZipFS_Find_TOC(interp, needZip, zf); + + error: ZipFSCloseArchive(interp, zf); return TCL_ERROR; } - + /* *------------------------------------------------------------------------- * @@ -1117,7 +1137,12 @@ error: */ static int -ZipFS_Catalogue_Filesystem(Tcl_Interp *interp, ZipFile *zf0, const char *mntpt, const char *passwd, const char *zipname) +ZipFS_Catalogue_Filesystem( + Tcl_Interp *interp, + ZipFile *zf0, + const char *mntpt, + const char *passwd, + const char *zipname) { int pwlen, isNew; size_t i; @@ -1126,259 +1151,269 @@ ZipFS_Catalogue_Filesystem(Tcl_Interp *interp, ZipFile *zf0, const char *mntpt, Tcl_HashEntry *hPtr; Tcl_DString ds, dsm, fpBuf; unsigned char *q; - WriteLock(); + + /* + * Basic verification of the password for sanity. + */ pwlen = 0; if (passwd != NULL) { - pwlen = strlen(passwd); - if ((pwlen > 255) || (strchr(passwd, 0xff) != NULL)) { - if (interp) { - Tcl_SetObjResult(interp, - Tcl_NewStringObj("illegal password", -1)); - } - return TCL_ERROR; - } + pwlen = strlen(passwd); + if ((pwlen > 255) || (strchr(passwd, 0xff) != NULL)) { + if (interp) { + Tcl_SetObjResult(interp, + Tcl_NewStringObj("illegal password", -1)); + } + return TCL_ERROR; + } } + + WriteLock(); + /* * Mount point sometimes is a relative or otherwise denormalized path. * But an absolute name is needed as mount point here. */ + Tcl_DStringInit(&ds); Tcl_DStringInit(&dsm); if (strcmp(mntpt, "/") == 0) { - mntpt = ""; + mntpt = ""; } else { - mntpt = CanonicalPath("",mntpt, &dsm, 1); + mntpt = CanonicalPath("", mntpt, &dsm, 1); } hPtr = Tcl_CreateHashEntry(&ZipFS.zipHash, mntpt, &isNew); if (!isNew) { - zf = (ZipFile *) Tcl_GetHashValue(hPtr); - if (interp != NULL) { - Tcl_AppendResult(interp, zf->name, " is already mounted on ", mntpt, (char *) NULL); - } - Unlock(); - ZipFSCloseArchive(interp, zf0); - return TCL_ERROR; + zf = (ZipFile *) Tcl_GetHashValue(hPtr); + if (interp != NULL) { + Tcl_AppendResult(interp, zf->name, " is already mounted on ", + mntpt, (char *) NULL); + } + Unlock(); + ZipFSCloseArchive(interp, zf0); + return TCL_ERROR; } zf = (ZipFile *) Tcl_AttemptAlloc(sizeof (*zf) + strlen(mntpt) + 1); if (zf == NULL) { - if (interp != NULL) { - Tcl_AppendResult(interp, "out of memory", (char *) NULL); - } - Unlock(); - ZipFSCloseArchive(interp, zf0); - return TCL_ERROR; + if (interp != NULL) { + Tcl_AppendResult(interp, "out of memory", (char *) NULL); + } + Unlock(); + ZipFSCloseArchive(interp, zf0); + return TCL_ERROR; } Unlock(); + *zf = *zf0; zf->mntpt = Tcl_GetHashKey(&ZipFS.zipHash, hPtr); - zf->mntptlen=strlen(zf->mntpt); + zf->mntptlen = strlen(zf->mntpt); zf->name = strdup(zipname); - zf->namelen= strlen(zipname); + zf->namelen = strlen(zipname); zf->entries = NULL; zf->topents = NULL; zf->nopen = 0; - Tcl_SetHashValue(hPtr, (ClientData) zf); + Tcl_SetHashValue(hPtr, zf); if ((zf->pwbuf[0] == 0) && pwlen) { - int k = 0; - i = pwlen; - zf->pwbuf[k++] = i; - while (i > 0) { - zf->pwbuf[k] = (passwd[i - 1] & 0x0f) | - pwrot[(passwd[i - 1] >> 4) & 0x0f]; - k++; - i--; - } - zf->pwbuf[k] = '\0'; + int k = 0; + + i = pwlen; + zf->pwbuf[k++] = i; + while (i > 0) { + zf->pwbuf[k] = (passwd[i - 1] & 0x0f) + | pwrot[(passwd[i - 1] >> 4) & 0x0f]; + k++; + i--; + } + zf->pwbuf[k] = '\0'; } if (mntpt[0] != '\0') { - z = (ZipEntry *) Tcl_Alloc(sizeof (*z)); - z->name = NULL; - z->tnext = NULL; - z->depth = CountSlashes(mntpt); - z->zipfile = zf; - z->isdir = (zf->baseoffs == 0) ? 1 : -1; /* root marker */ - z->isenc = 0; - z->offset = zf->baseoffs; - z->crc32 = 0; - z->timestamp = 0; - z->nbyte = z->nbytecompr = 0; - z->cmeth = ZIP_COMPMETH_STORED; - z->data = NULL; - hPtr = Tcl_CreateHashEntry(&ZipFS.fileHash, mntpt, &isNew); - if (!isNew) { - /* skip it */ - Tcl_Free((char *) z); - } else { - Tcl_SetHashValue(hPtr, (ClientData) z); - z->name = Tcl_GetHashKey(&ZipFS.fileHash, hPtr); - z->next = zf->entries; - zf->entries = z; - } + z = (ZipEntry *) Tcl_Alloc(sizeof(ZipEntry)); + z->name = NULL; + z->tnext = NULL; + z->depth = CountSlashes(mntpt); + z->zipfile = zf; + z->isdir = (zf->baseoffs == 0) ? 1 : -1; /* root marker */ + z->isenc = 0; + z->offset = zf->baseoffs; + z->crc32 = 0; + z->timestamp = 0; + z->nbyte = z->nbytecompr = 0; + z->cmeth = ZIP_COMPMETH_STORED; + z->data = NULL; + hPtr = Tcl_CreateHashEntry(&ZipFS.fileHash, mntpt, &isNew); + if (!isNew) { + /* skip it */ + Tcl_Free((char *) z); + } else { + Tcl_SetHashValue(hPtr, z); + z->name = Tcl_GetHashKey(&ZipFS.fileHash, hPtr); + z->next = zf->entries; + zf->entries = z; + } } q = zf->data + zf->centoffs; Tcl_DStringInit(&fpBuf); for (i = 0; i < zf->nfiles; i++) { - int extra, isdir = 0, dosTime, dosDate, nbcompr; - size_t offs, pathlen, comlen; - unsigned char *lq, *gq = NULL; - char *fullpath, *path; - - pathlen = zip_read_short(q + ZIP_CENTRAL_PATHLEN_OFFS); - comlen = zip_read_short(q + ZIP_CENTRAL_FCOMMENTLEN_OFFS); - extra = zip_read_short(q + ZIP_CENTRAL_EXTRALEN_OFFS); - Tcl_DStringSetLength(&ds, 0); - Tcl_DStringAppend(&ds, (char *) q + ZIP_CENTRAL_HEADER_LEN, pathlen); - path = Tcl_DStringValue(&ds); - if ((pathlen > 0) && (path[pathlen - 1] == '/')) { - Tcl_DStringSetLength(&ds, pathlen - 1); - path = Tcl_DStringValue(&ds); - isdir = 1; - } - if ((strcmp(path, ".") == 0) || (strcmp(path, "..") == 0)) { - goto nextent; - } - lq = zf->data + zf->baseoffs + zip_read_int(q + ZIP_CENTRAL_LOCALHDR_OFFS); - if ((lq < zf->data) || (lq > (zf->data + zf->length))) { - goto nextent; - } - nbcompr = zip_read_int(lq + ZIP_LOCAL_COMPLEN_OFFS); - if ( - !isdir && (nbcompr == 0) - && (zip_read_int(lq + ZIP_LOCAL_UNCOMPLEN_OFFS) == 0) - && (zip_read_int(lq + ZIP_LOCAL_CRC32_OFFS) == 0) - ) { - gq = q; - nbcompr = zip_read_int(gq + ZIP_CENTRAL_COMPLEN_OFFS); - } - offs = (lq - zf->data) - + ZIP_LOCAL_HEADER_LEN - + zip_read_short(lq + ZIP_LOCAL_PATHLEN_OFFS) - + zip_read_short(lq + ZIP_LOCAL_EXTRALEN_OFFS); - if ((offs + nbcompr) > zf->length) { - goto nextent; - } - if (!isdir && (mntpt[0] == '\0') && !CountSlashes(path)) { + int extra, isdir = 0, dosTime, dosDate, nbcompr; + size_t offs, pathlen, comlen; + unsigned char *lq, *gq = NULL; + char *fullpath, *path; + + pathlen = zip_read_short(q + ZIP_CENTRAL_PATHLEN_OFFS); + comlen = zip_read_short(q + ZIP_CENTRAL_FCOMMENTLEN_OFFS); + extra = zip_read_short(q + ZIP_CENTRAL_EXTRALEN_OFFS); + Tcl_DStringSetLength(&ds, 0); + Tcl_DStringAppend(&ds, (char *) q + ZIP_CENTRAL_HEADER_LEN, pathlen); + path = Tcl_DStringValue(&ds); + if ((pathlen > 0) && (path[pathlen - 1] == '/')) { + Tcl_DStringSetLength(&ds, pathlen - 1); + path = Tcl_DStringValue(&ds); + isdir = 1; + } + if ((strcmp(path, ".") == 0) || (strcmp(path, "..") == 0)) { + goto nextent; + } + lq = zf->data + zf->baseoffs + + zip_read_int(q + ZIP_CENTRAL_LOCALHDR_OFFS); + if ((lq < zf->data) || (lq > zf->data + zf->length)) { + goto nextent; + } + nbcompr = zip_read_int(lq + ZIP_LOCAL_COMPLEN_OFFS); + if (!isdir && (nbcompr == 0) + && (zip_read_int(lq + ZIP_LOCAL_UNCOMPLEN_OFFS) == 0) + && (zip_read_int(lq + ZIP_LOCAL_CRC32_OFFS) == 0)) { + gq = q; + nbcompr = zip_read_int(gq + ZIP_CENTRAL_COMPLEN_OFFS); + } + offs = (lq - zf->data) + + ZIP_LOCAL_HEADER_LEN + + zip_read_short(lq + ZIP_LOCAL_PATHLEN_OFFS) + + zip_read_short(lq + ZIP_LOCAL_EXTRALEN_OFFS); + if ((offs + nbcompr) > zf->length) { + goto nextent; + } + if (!isdir && (mntpt[0] == '\0') && !CountSlashes(path)) { #ifdef ANDROID - /* - * When mounting the ZIP archive on the root directory try - * to remap top level regular files of the archive to - * /assets/.root/... since this directory should not be - * in a valid APK due to the leading dot in the file name - * component. This trick should make the files - * AndroidManifest.xml, resources.arsc, and classes.dex - * visible to Tcl. - */ - Tcl_DString ds2; - - Tcl_DStringInit(&ds2); - Tcl_DStringAppend(&ds2, "assets/.root/", -1); - Tcl_DStringAppend(&ds2, path, -1); - hPtr = Tcl_FindHashEntry(&ZipFS.fileHash, Tcl_DStringValue(&ds2)); - if (hPtr != NULL) { - /* should not happen but skip it anyway */ - Tcl_DStringFree(&ds2); - goto nextent; - } - Tcl_DStringSetLength(&ds, 0); - Tcl_DStringAppend(&ds, Tcl_DStringValue(&ds2), Tcl_DStringLength(&ds2)); - path = Tcl_DStringValue(&ds); - Tcl_DStringFree(&ds2); -#else - /* - * Regular files skipped when mounting on root. - */ - goto nextent; -#endif - } - Tcl_DStringSetLength(&fpBuf, 0); - fullpath = CanonicalPath(mntpt, path, &fpBuf, 1); - z = (ZipEntry *) Tcl_Alloc(sizeof (*z)); - z->name = NULL; - z->tnext = NULL; - z->depth = CountSlashes(fullpath); - z->zipfile = zf; - z->isdir = isdir; - z->isenc = (zip_read_short(lq + ZIP_LOCAL_FLAGS_OFFS) & 1) && (nbcompr > 12); - z->offset = offs; - if (gq != NULL) { - z->crc32 = zip_read_int(gq + ZIP_CENTRAL_CRC32_OFFS); - dosDate = zip_read_short(gq + ZIP_CENTRAL_MDATE_OFFS); - dosTime = zip_read_short(gq + ZIP_CENTRAL_MTIME_OFFS); - z->timestamp = DosTimeDate(dosDate, dosTime); - z->nbyte = zip_read_int(gq + ZIP_CENTRAL_UNCOMPLEN_OFFS); - z->cmeth = zip_read_short(gq + ZIP_CENTRAL_COMPMETH_OFFS); - } else { - z->crc32 = zip_read_int(lq + ZIP_LOCAL_CRC32_OFFS); - dosDate = zip_read_short(lq + ZIP_LOCAL_MDATE_OFFS); - dosTime = zip_read_short(lq + ZIP_LOCAL_MTIME_OFFS); - z->timestamp = DosTimeDate(dosDate, dosTime); - z->nbyte = zip_read_int(lq + ZIP_LOCAL_UNCOMPLEN_OFFS); - z->cmeth = zip_read_short(lq + ZIP_LOCAL_COMPMETH_OFFS); - } - z->nbytecompr = nbcompr; - z->data = NULL; - hPtr = Tcl_CreateHashEntry(&ZipFS.fileHash, fullpath, &isNew); - if (!isNew) { - /* should not happen but skip it anyway */ - Tcl_Free((char *) z); - } else { - Tcl_SetHashValue(hPtr, (ClientData) z); - z->name = Tcl_GetHashKey(&ZipFS.fileHash, hPtr); - z->next = zf->entries; - zf->entries = z; - if (isdir && (mntpt[0] == '\0') && (z->depth == 1)) { - z->tnext = zf->topents; - zf->topents = z; - } - if (!z->isdir && (z->depth > 1)) { - char *dir, *end; - ZipEntry *zd; - - Tcl_DStringSetLength(&ds, strlen(z->name) + 8); - Tcl_DStringSetLength(&ds, 0); - Tcl_DStringAppend(&ds, z->name, -1); - dir = Tcl_DStringValue(&ds); - end = strrchr(dir, '/'); - while ((end != NULL) && (end != dir)) { - Tcl_DStringSetLength(&ds, end - dir); - hPtr = Tcl_FindHashEntry(&ZipFS.fileHash, dir); - if (hPtr != NULL) { - break; - } - zd = (ZipEntry *) Tcl_Alloc(sizeof (*zd)); - zd->name = NULL; - zd->tnext = NULL; - zd->depth = CountSlashes(dir); - zd->zipfile = zf; - zd->isdir = 1; - zd->isenc = 0; - zd->offset = z->offset; - zd->crc32 = 0; - zd->timestamp = z->timestamp; - zd->nbyte = zd->nbytecompr = 0; - zd->cmeth = ZIP_COMPMETH_STORED; - zd->data = NULL; - hPtr = Tcl_CreateHashEntry(&ZipFS.fileHash, dir, &isNew); - if (!isNew) { - /* should not happen but skip it anyway */ - Tcl_Free((char *) zd); - } else { - Tcl_SetHashValue(hPtr, (ClientData) zd); - zd->name = Tcl_GetHashKey(&ZipFS.fileHash, hPtr); - zd->next = zf->entries; - zf->entries = zd; - if ((mntpt[0] == '\0') && (zd->depth == 1)) { - zd->tnext = zf->topents; - zf->topents = zd; - } - } - end = strrchr(dir, '/'); - } - } - } -nextent: - q += pathlen + comlen + extra + ZIP_CENTRAL_HEADER_LEN; + /* + * When mounting the ZIP archive on the root directory try to + * remap top level regular files of the archive to + * /assets/.root/... since this directory should not be in a valid + * APK due to the leading dot in the file name component. This + * trick should make the files AndroidManifest.xml, + * resources.arsc, and classes.dex visible to Tcl. + */ + Tcl_DString ds2; + + Tcl_DStringInit(&ds2); + Tcl_DStringAppend(&ds2, "assets/.root/", -1); + Tcl_DStringAppend(&ds2, path, -1); + hPtr = Tcl_FindHashEntry(&ZipFS.fileHash, Tcl_DStringValue(&ds2)); + if (hPtr != NULL) { + /* should not happen but skip it anyway */ + Tcl_DStringFree(&ds2); + goto nextent; + } + Tcl_DStringSetLength(&ds, 0); + Tcl_DStringAppend(&ds, Tcl_DStringValue(&ds2), + Tcl_DStringLength(&ds2)); + path = Tcl_DStringValue(&ds); + Tcl_DStringFree(&ds2); +#else /* !ANDROID */ + /* + * Regular files skipped when mounting on root. + */ + goto nextent; +#endif /* ANDROID */ + } + Tcl_DStringSetLength(&fpBuf, 0); + fullpath = CanonicalPath(mntpt, path, &fpBuf, 1); + z = (ZipEntry *) Tcl_Alloc(sizeof(ZipEntry)); + z->name = NULL; + z->tnext = NULL; + z->depth = CountSlashes(fullpath); + z->zipfile = zf; + z->isdir = isdir; + z->isenc = (zip_read_short(lq + ZIP_LOCAL_FLAGS_OFFS) & 1) + && (nbcompr > 12); + z->offset = offs; + if (gq != NULL) { + z->crc32 = zip_read_int(gq + ZIP_CENTRAL_CRC32_OFFS); + dosDate = zip_read_short(gq + ZIP_CENTRAL_MDATE_OFFS); + dosTime = zip_read_short(gq + ZIP_CENTRAL_MTIME_OFFS); + z->timestamp = DosTimeDate(dosDate, dosTime); + z->nbyte = zip_read_int(gq + ZIP_CENTRAL_UNCOMPLEN_OFFS); + z->cmeth = zip_read_short(gq + ZIP_CENTRAL_COMPMETH_OFFS); + } else { + z->crc32 = zip_read_int(lq + ZIP_LOCAL_CRC32_OFFS); + dosDate = zip_read_short(lq + ZIP_LOCAL_MDATE_OFFS); + dosTime = zip_read_short(lq + ZIP_LOCAL_MTIME_OFFS); + z->timestamp = DosTimeDate(dosDate, dosTime); + z->nbyte = zip_read_int(lq + ZIP_LOCAL_UNCOMPLEN_OFFS); + z->cmeth = zip_read_short(lq + ZIP_LOCAL_COMPMETH_OFFS); + } + z->nbytecompr = nbcompr; + z->data = NULL; + hPtr = Tcl_CreateHashEntry(&ZipFS.fileHash, fullpath, &isNew); + if (!isNew) { + /* should not happen but skip it anyway */ + Tcl_Free((char *) z); + } else { + Tcl_SetHashValue(hPtr, z); + z->name = Tcl_GetHashKey(&ZipFS.fileHash, hPtr); + z->next = zf->entries; + zf->entries = z; + if (isdir && (mntpt[0] == '\0') && (z->depth == 1)) { + z->tnext = zf->topents; + zf->topents = z; + } + if (!z->isdir && (z->depth > 1)) { + char *dir, *end; + ZipEntry *zd; + + Tcl_DStringSetLength(&ds, strlen(z->name) + 8); + Tcl_DStringSetLength(&ds, 0); + Tcl_DStringAppend(&ds, z->name, -1); + dir = Tcl_DStringValue(&ds); + end = strrchr(dir, '/'); + while ((end != NULL) && (end != dir)) { + Tcl_DStringSetLength(&ds, end - dir); + hPtr = Tcl_FindHashEntry(&ZipFS.fileHash, dir); + if (hPtr != NULL) { + break; + } + zd = (ZipEntry *) Tcl_Alloc(sizeof(ZipEntry)); + zd->name = NULL; + zd->tnext = NULL; + zd->depth = CountSlashes(dir); + zd->zipfile = zf; + zd->isdir = 1; + zd->isenc = 0; + zd->offset = z->offset; + zd->crc32 = 0; + zd->timestamp = z->timestamp; + zd->nbyte = zd->nbytecompr = 0; + zd->cmeth = ZIP_COMPMETH_STORED; + zd->data = NULL; + hPtr = Tcl_CreateHashEntry(&ZipFS.fileHash, dir, &isNew); + if (!isNew) { + /* should not happen but skip it anyway */ + Tcl_Free((char *) zd); + } else { + Tcl_SetHashValue(hPtr, zd); + zd->name = Tcl_GetHashKey(&ZipFS.fileHash, hPtr); + zd->next = zf->entries; + zf->entries = zd; + if ((mntpt[0] == '\0') && (zd->depth == 1)) { + zd->tnext = zf->topents; + zf->topents = zd; + } + } + end = strrchr(dir, '/'); + } + } + } + nextent: + q += pathlen + comlen + extra + ZIP_CENTRAL_HEADER_LEN; } Tcl_DStringFree(&fpBuf); Tcl_DStringFree(&ds); @@ -1386,40 +1421,42 @@ nextent: Unlock(); return TCL_OK; } - -static void TclZipfs_C_Init(void) { + +static void +TclZipfs_C_Init(void) +{ static const Tcl_Time t = { 0, 0 }; + if (!ZipFS.initialized) { #ifdef TCL_THREADS - /* - * Inflate condition variable. - */ - Tcl_MutexLock(&ZipFSMutex); - Tcl_ConditionWait(&ZipFSCond, &ZipFSMutex, &t); - Tcl_MutexUnlock(&ZipFSMutex); -#endif - Tcl_FSRegister(NULL, &zipfsFilesystem); - Tcl_InitHashTable(&ZipFS.fileHash, TCL_STRING_KEYS); - Tcl_InitHashTable(&ZipFS.zipHash, TCL_STRING_KEYS); - ZipFS.initialized = ZipFS.idCount = 1; + /* + * Inflate condition variable. + */ + Tcl_MutexLock(&ZipFSMutex); + Tcl_ConditionWait(&ZipFSCond, &ZipFSMutex, &t); + Tcl_MutexUnlock(&ZipFSMutex); +#endif /* TCL_THREADS */ + Tcl_FSRegister(NULL, &zipfsFilesystem); + Tcl_InitHashTable(&ZipFS.fileHash, TCL_STRING_KEYS); + Tcl_InitHashTable(&ZipFS.zipHash, TCL_STRING_KEYS); + ZipFS.initialized = ZipFS.idCount = 1; } } - /* *------------------------------------------------------------------------- * * TclZipfs_Mount -- * - * This procedure is invoked to mount a given ZIP archive file on - * a given mountpoint with optional ZIP password. + * This procedure is invoked to mount a given ZIP archive file on a given + * mountpoint with optional ZIP password. * * Results: - * A standard Tcl result. + * A standard Tcl result. * * Side effects: - * A ZIP archive file is read, analyzed and mounted, resources are - * allocated. + * A ZIP archive file is read, analyzed and mounted, resources are + * allocated. * *------------------------------------------------------------------------- */ @@ -1429,76 +1466,76 @@ TclZipfs_Mount( Tcl_Interp *interp, const char *mntpt, const char *zipname, - const char *passwd -) { + const char *passwd) +{ int i, pwlen; ZipFile *zf; ReadLock(); if (!ZipFS.initialized) { - TclZipfs_C_Init(); + TclZipfs_C_Init(); } if (mntpt == NULL) { - Tcl_HashEntry *hPtr; - Tcl_HashSearch search; - int ret = TCL_OK; - i = 0; - hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); - while (hPtr != NULL) { - if ((zf = (ZipFile *) Tcl_GetHashValue(hPtr)) != NULL) { - if (interp != NULL) { - Tcl_AppendElement(interp, zf->mntpt); - Tcl_AppendElement(interp, zf->name); - } - ++i; - } - hPtr = Tcl_NextHashEntry(&search); - } - if (interp == NULL) { - ret = (i > 0) ? TCL_OK : TCL_BREAK; - } - Unlock(); - return ret; + Tcl_HashEntry *hPtr; + Tcl_HashSearch search; + int ret = TCL_OK; + + i = 0; + hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); + while (hPtr != NULL) { + if ((zf = (ZipFile *) Tcl_GetHashValue(hPtr)) != NULL) { + if (interp != NULL) { + Tcl_AppendElement(interp, zf->mntpt); + Tcl_AppendElement(interp, zf->name); + } + ++i; + } + hPtr = Tcl_NextHashEntry(&search); + } + if (interp == NULL) { + ret = (i > 0) ? TCL_OK : TCL_BREAK; + } + Unlock(); + return ret; } if (zipname == NULL) { - Tcl_HashEntry *hPtr; - if (interp == NULL) { - Unlock(); - return TCL_OK; - } - hPtr = Tcl_FindHashEntry(&ZipFS.zipHash, mntpt); - if (hPtr != NULL) { - if ((zf = Tcl_GetHashValue(hPtr)) != NULL) { - Tcl_SetObjResult(interp,Tcl_NewStringObj(zf->name, -1)); - } - } - Unlock(); - return TCL_OK; + if (interp != NULL) { + Tcl_HashEntry *hPtr; + + hPtr = Tcl_FindHashEntry(&ZipFS.zipHash, mntpt); + if (hPtr != NULL) { + if ((zf = Tcl_GetHashValue(hPtr)) != NULL) { + Tcl_SetObjResult(interp, Tcl_NewStringObj(zf->name, -1)); + } + } + } + Unlock(); + return TCL_OK; } Unlock(); pwlen = 0; if (passwd != NULL) { - pwlen = strlen(passwd); - if ((pwlen > 255) || (strchr(passwd, 0xff) != NULL)) { - if (interp) { - Tcl_SetObjResult(interp, - Tcl_NewStringObj("illegal password", -1)); - } - return TCL_ERROR; - } + pwlen = strlen(passwd); + if ((pwlen > 255) || (strchr(passwd, 0xff) != NULL)) { + if (interp) { + Tcl_SetObjResult(interp, + Tcl_NewStringObj("illegal password", -1)); + } + return TCL_ERROR; + } } zf = (ZipFile *) Tcl_AttemptAlloc(sizeof (*zf) + strlen(mntpt) + 1); if (zf == NULL) { - if (interp != NULL) { - Tcl_AppendResult(interp, "out of memory", (char *) NULL); - } - return TCL_ERROR; + if (interp != NULL) { + Tcl_AppendResult(interp, "out of memory", (char *) NULL); + } + return TCL_ERROR; } if (ZipFSOpenArchive(interp, zipname, 1, zf) != TCL_OK) { - return TCL_ERROR; + return TCL_ERROR; } - return ZipFS_Catalogue_Filesystem(interp,zf,mntpt,passwd,zipname); + return ZipFS_Catalogue_Filesystem(interp, zf, mntpt, passwd, zipname); } /* @@ -1506,15 +1543,15 @@ TclZipfs_Mount( * * TclZipfs_Mount_Buffer -- * - * This procedure is invoked to mount a given ZIP archive file on - * a given mountpoint with optional ZIP password. + * This procedure is invoked to mount a given ZIP archive file on + * a given mountpoint with optional ZIP password. * * Results: - * A standard Tcl result. + * A standard Tcl result. * * Side effects: - * A ZIP archive file is read, analyzed and mounted, resources are - * allocated. + * A ZIP archive file is read, analyzed and mounted, resources are + * allocated. * *------------------------------------------------------------------------- */ @@ -1525,83 +1562,84 @@ TclZipfs_Mount_Buffer( const char *mntpt, unsigned char *data, size_t datalen, - int copy -) { + int copy) +{ int i; ZipFile *zf; ReadLock(); if (!ZipFS.initialized) { - TclZipfs_C_Init(); + TclZipfs_C_Init(); } if (mntpt == NULL) { - Tcl_HashEntry *hPtr; - Tcl_HashSearch search; - int ret = TCL_OK; - - i = 0; - hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); - while (hPtr != NULL) { - if ((zf = (ZipFile *) Tcl_GetHashValue(hPtr)) != NULL) { - if (interp != NULL) { - Tcl_AppendElement(interp, zf->mntpt); - Tcl_AppendElement(interp, zf->name); - } - ++i; - } - hPtr = Tcl_NextHashEntry(&search); - } - if (interp == NULL) { - ret = (i > 0) ? TCL_OK : TCL_BREAK; - } - Unlock(); - return ret; + Tcl_HashEntry *hPtr; + Tcl_HashSearch search; + int ret = TCL_OK; + + i = 0; + hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); + while (hPtr != NULL) { + if ((zf = (ZipFile *) Tcl_GetHashValue(hPtr)) != NULL) { + if (interp != NULL) { + Tcl_AppendElement(interp, zf->mntpt); + Tcl_AppendElement(interp, zf->name); + } + ++i; + } + hPtr = Tcl_NextHashEntry(&search); + } + if (interp == NULL) { + ret = (i > 0) ? TCL_OK : TCL_BREAK; + } + Unlock(); + return ret; } if (data == NULL) { - Tcl_HashEntry *hPtr; - - if (interp == NULL) { - Unlock(); - return TCL_OK; - } - hPtr = Tcl_FindHashEntry(&ZipFS.zipHash, mntpt); - if (hPtr != NULL) { - if ((zf = Tcl_GetHashValue(hPtr)) != NULL) { - Tcl_SetObjResult(interp,Tcl_NewStringObj(zf->name, -1)); - } - } - Unlock(); - return TCL_OK; + if (interp != NULL) { + Tcl_HashEntry *hPtr; + + hPtr = Tcl_FindHashEntry(&ZipFS.zipHash, mntpt); + if (hPtr != NULL) { + zf = Tcl_GetHashValue(hPtr); + if (zf != NULL) { + Tcl_SetObjResult(interp, Tcl_NewStringObj(zf->name, -1)); + } + } + } + Unlock(); + return TCL_OK; } Unlock(); - zf = (ZipFile *) Tcl_AttemptAlloc(sizeof (*zf) + strlen(mntpt) + 1); + + zf = (ZipFile *) Tcl_AttemptAlloc(sizeof(ZipFile) + strlen(mntpt) + 1); if (zf == NULL) { - if (interp != NULL) { - Tcl_AppendResult(interp, "out of memory", (char *) NULL); - } - return TCL_ERROR; - } - zf->is_membuf=1; - zf->length=datalen; - if(copy) { - zf->data=(unsigned char *)Tcl_AttemptAlloc(datalen); - if (zf->data == NULL) { - if (interp != NULL) { - Tcl_AppendResult(interp, "out of memory", (char *) NULL); - } - return TCL_ERROR; - } - memcpy(zf->data,data,datalen); - zf->tofree=zf->data; + if (interp != NULL) { + Tcl_AppendResult(interp, "out of memory", (char *) NULL); + } + return TCL_ERROR; + } + zf->is_membuf = 1; + zf->length = datalen; + if (copy) { + zf->data = (unsigned char *) Tcl_AttemptAlloc(datalen); + if (zf->data == NULL) { + if (interp != NULL) { + Tcl_AppendResult(interp, "out of memory", (char *) NULL); + } + return TCL_ERROR; + } + memcpy(zf->data, data, datalen); + zf->tofree = zf->data; } else { - zf->data=data; - zf->tofree=NULL; + zf->data = data; + zf->tofree = NULL; } - if(ZipFS_Find_TOC(interp,0,zf)!=TCL_OK) { - return TCL_ERROR; + if (ZipFS_Find_TOC(interp, 0, zf) != TCL_OK) { + return TCL_ERROR; } - return ZipFS_Catalogue_Filesystem(interp,zf,mntpt,NULL,"Memory Buffer"); + return ZipFS_Catalogue_Filesystem(interp, zf, mntpt, NULL, + "Memory Buffer"); } /* @@ -1609,19 +1647,21 @@ TclZipfs_Mount_Buffer( * * TclZipfs_Unmount -- * - * This procedure is invoked to unmount a given ZIP archive. + * This procedure is invoked to unmount a given ZIP archive. * * Results: - * A standard Tcl result. + * A standard Tcl result. * * Side effects: - * A mounted ZIP archive file is unmounted, resources are free'd. + * A mounted ZIP archive file is unmounted, resources are free'd. * *------------------------------------------------------------------------- */ int -TclZipfs_Unmount(Tcl_Interp *interp, const char *mntpt) +TclZipfs_Unmount( + Tcl_Interp *interp, + const char *mntpt) { ZipFile *zf; ZipEntry *z, *znext; @@ -1630,44 +1670,49 @@ TclZipfs_Unmount(Tcl_Interp *interp, const char *mntpt) int ret = TCL_OK, unmounted = 0; WriteLock(); - if (!ZipFS.initialized) goto done; + if (!ZipFS.initialized) { + goto done; + } + /* * Mount point sometimes is a relative or otherwise denormalized path. * But an absolute name is needed as mount point here. */ + Tcl_DStringInit(&dsm); mntpt = CanonicalPath("", mntpt, &dsm, 1); hPtr = Tcl_FindHashEntry(&ZipFS.zipHash, mntpt); - - /* don't report error */ - if (hPtr == NULL) goto done; + /* don't report no-such-mount as an error */ + if (hPtr == NULL) { + goto done; + } zf = (ZipFile *) Tcl_GetHashValue(hPtr); if (zf->nopen > 0) { - ZIPFS_ERROR(interp,"filesystem is busy"); - ret = TCL_ERROR; - goto done; + ZIPFS_ERROR(interp, "filesystem is busy"); + ret = TCL_ERROR; + goto done; } Tcl_DeleteHashEntry(hPtr); for (z = zf->entries; z; z = znext) { - znext = z->next; - hPtr = Tcl_FindHashEntry(&ZipFS.fileHash, z->name); - if (hPtr) { - Tcl_DeleteHashEntry(hPtr); - } - if (z->data != NULL) { - Tcl_Free((char *) z->data); - } - Tcl_Free((char *) z); + znext = z->next; + hPtr = Tcl_FindHashEntry(&ZipFS.fileHash, z->name); + if (hPtr) { + Tcl_DeleteHashEntry(hPtr); + } + if (z->data != NULL) { + Tcl_Free((char *) z->data); + } + Tcl_Free((char *) z); } ZipFSCloseArchive(interp, zf); Tcl_Free((char *) zf); unmounted = 1; -done: + done: Unlock(); if (unmounted) { - Tcl_FSMountsChanged(NULL); + Tcl_FSMountsChanged(NULL); } return ret; } @@ -1677,104 +1722,113 @@ done: * * ZipFSMountObjCmd -- * - * This procedure is invoked to process the "zipfs::mount" command. + * This procedure is invoked to process the "zipfs::mount" command. * * Results: - * A standard Tcl result. + * A standard Tcl result. * * Side effects: - * A ZIP archive file is mounted, resources are allocated. + * A ZIP archive file is mounted, resources are allocated. * *------------------------------------------------------------------------- */ static int ZipFSMountObjCmd( - ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[] -) { + ClientData clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *const objv[]) +{ if (objc > 4) { - Tcl_WrongNumArgs(interp, 1, objv, - "?mountpoint? ?zipfile? ?password?"); - return TCL_ERROR; + Tcl_WrongNumArgs(interp, 1, objv, + "?mountpoint? ?zipfile? ?password?"); + return TCL_ERROR; } + return TclZipfs_Mount(interp, (objc > 1) ? Tcl_GetString(objv[1]) : NULL, - (objc > 2) ? Tcl_GetString(objv[2]) : NULL, - (objc > 3) ? Tcl_GetString(objv[3]) : NULL); + (objc > 2) ? Tcl_GetString(objv[2]) : NULL, + (objc > 3) ? Tcl_GetString(objv[3]) : NULL); } - + /* *------------------------------------------------------------------------- * * ZipFSMountObjCmd -- * - * This procedure is invoked to process the "zipfs::mount" command. + * This procedure is invoked to process the "zipfs::mount" command. * * Results: - * A standard Tcl result. + * A standard Tcl result. * * Side effects: - * A ZIP archive file is mounted, resources are allocated. + * A ZIP archive file is mounted, resources are allocated. * *------------------------------------------------------------------------- */ static int ZipFSMountBufferObjCmd( - ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[] -) { + ClientData clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *const objv[]) +{ const char *mntpt; unsigned char *data; int length; + if (objc > 4) { - Tcl_WrongNumArgs(interp, 1, objv, "?mountpoint? ?data?"); - return TCL_ERROR; - } - if(objc<2) { - int i; - Tcl_HashEntry *hPtr; - Tcl_HashSearch search; - int ret = TCL_OK; - ZipFile *zf; - - ReadLock(); - i = 0; - hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); - while (hPtr != NULL) { - if ((zf = (ZipFile *) Tcl_GetHashValue(hPtr)) != NULL) { - if (interp != NULL) { - Tcl_AppendElement(interp, zf->mntpt); - Tcl_AppendElement(interp, zf->name); - } - ++i; - } - hPtr = Tcl_NextHashEntry(&search); - } - if (interp == NULL) { - ret = (i > 0) ? TCL_OK : TCL_BREAK; - } - Unlock(); - return ret; - } - mntpt=Tcl_GetString(objv[1]); - if(objc<3) { - Tcl_HashEntry *hPtr; - ZipFile *zf; - - if (interp == NULL) { - Unlock(); - return TCL_OK; - } - hPtr = Tcl_FindHashEntry(&ZipFS.zipHash, mntpt); - if (hPtr != NULL) { - if ((zf = Tcl_GetHashValue(hPtr)) != NULL) { - Tcl_SetObjResult(interp,Tcl_NewStringObj(zf->name, -1)); - } - } - Unlock(); - return TCL_OK; - } - data=Tcl_GetByteArrayFromObj(objv[2],&length); - return TclZipfs_Mount_Buffer(interp, mntpt,data,length,1); + Tcl_WrongNumArgs(interp, 1, objv, "?mountpoint? ?data?"); + return TCL_ERROR; + } + if (objc < 2) { + int i; + Tcl_HashEntry *hPtr; + Tcl_HashSearch search; + int ret = TCL_OK; + ZipFile *zf; + + ReadLock(); + i = 0; + hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); + while (hPtr != NULL) { + if ((zf = (ZipFile *) Tcl_GetHashValue(hPtr)) != NULL) { + if (interp != NULL) { + Tcl_AppendElement(interp, zf->mntpt); + Tcl_AppendElement(interp, zf->name); + } + ++i; + } + hPtr = Tcl_NextHashEntry(&search); + } + if (interp == NULL) { + ret = (i > 0) ? TCL_OK : TCL_BREAK; + } + Unlock(); + return ret; + } + + mntpt = Tcl_GetString(objv[1]); + if (objc < 3) { + Tcl_HashEntry *hPtr; + ZipFile *zf; + + if (interp != NULL) { + hPtr = Tcl_FindHashEntry(&ZipFS.zipHash, mntpt); + if (hPtr != NULL) { + zf = Tcl_GetHashValue(hPtr); + if (zf != NULL) { + Tcl_SetObjResult(interp, Tcl_NewStringObj(zf->name, -1)); + } + } + } + Unlock(); + return TCL_OK; + } + + data = Tcl_GetByteArrayFromObj(objv[2], &length); + return TclZipfs_Mount_Buffer(interp, mntpt, data, length, 1); } /* @@ -1782,11 +1836,11 @@ ZipFSMountBufferObjCmd( * * ZipFSRootObjCmd -- * - * This procedure is invoked to process the "zipfs::root" command. It - * returns the root that all zipfs file systems are mounted under. + * This procedure is invoked to process the "zipfs::root" command. It + * returns the root that all zipfs file systems are mounted under. * * Results: - * A standard Tcl result. + * A standard Tcl result. * * Side effects: * @@ -1795,9 +1849,12 @@ ZipFSMountBufferObjCmd( static int ZipFSRootObjCmd( - ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[] -) { - Tcl_SetObjResult(interp,Tcl_NewStringObj(ZIPFS_VOLUME, -1)); + ClientData clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *const objv[]) +{ + Tcl_SetObjResult(interp, Tcl_NewStringObj(ZIPFS_VOLUME, -1)); return TCL_OK; } @@ -1806,24 +1863,27 @@ ZipFSRootObjCmd( * * ZipFSUnmountObjCmd -- * - * This procedure is invoked to process the "zipfs::unmount" command. + * This procedure is invoked to process the "zipfs::unmount" command. * * Results: - * A standard Tcl result. + * A standard Tcl result. * * Side effects: - * A mounted ZIP archive file is unmounted, resources are free'd. + * A mounted ZIP archive file is unmounted, resources are free'd. * *------------------------------------------------------------------------- */ static int ZipFSUnmountObjCmd( - ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[] -) { + ClientData clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *const objv[]) +{ if (objc != 2) { - Tcl_WrongNumArgs(interp, 1, objv, "zipfile"); - return TCL_ERROR; + Tcl_WrongNumArgs(interp, 1, objv, "zipfile"); + return TCL_ERROR; } return TclZipfs_Unmount(interp, Tcl_GetString(objv[1])); } @@ -1833,44 +1893,47 @@ ZipFSUnmountObjCmd( * * ZipFSMkKeyObjCmd -- * - * This procedure is invoked to process the "zipfs::mkkey" command. - * It produces a rotated password to be embedded into an image file. + * This procedure is invoked to process the "zipfs::mkkey" command. It + * produces a rotated password to be embedded into an image file. * * Results: - * A standard Tcl result. + * A standard Tcl result. * * Side effects: - * None. + * None. * *------------------------------------------------------------------------- */ static int ZipFSMkKeyObjCmd( - ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[] -) { + ClientData clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *const objv[]) +{ int len, i = 0; char *pw, pwbuf[264]; if (objc != 2) { - Tcl_WrongNumArgs(interp, 1, objv, "password"); - return TCL_ERROR; + Tcl_WrongNumArgs(interp, 1, objv, "password"); + return TCL_ERROR; } pw = Tcl_GetString(objv[1]); len = strlen(pw); if (len == 0) { - return TCL_OK; + return TCL_OK; } if ((len > 255) || (strchr(pw, 0xff) != NULL)) { - Tcl_SetObjResult(interp, Tcl_NewStringObj("illegal password", -1)); - return TCL_ERROR; + Tcl_SetObjResult(interp, Tcl_NewStringObj("illegal password", -1)); + return TCL_ERROR; } while (len > 0) { - int ch = pw[len - 1]; + int ch = pw[len - 1]; - pwbuf[i] = (ch & 0x0f) | pwrot[(ch >> 4) & 0x0f]; - i++; - len--; + pwbuf[i] = (ch & 0x0f) | pwrot[(ch >> 4) & 0x0f]; + i++; + len--; } pwbuf[i] = i; ++i; @@ -1888,27 +1951,32 @@ ZipFSMkKeyObjCmd( * * ZipAddFile -- * - * This procedure is used by ZipFSMkZipOrImgCmd() to add a single - * file to the output ZIP archive file being written. A ZipEntry - * struct about the input file is added to the given fileHash table - * for later creation of the central ZIP directory. + * This procedure is used by ZipFSMkZipOrImgCmd() to add a single file to + * the output ZIP archive file being written. A ZipEntry struct about the + * input file is added to the given fileHash table for later creation of + * the central ZIP directory. * * Results: - * A standard Tcl result. + * A standard Tcl result. * * Side effects: - * Input file is read and (compressed and) written to the output - * ZIP archive file. + * Input file is read and (compressed and) written to the output ZIP + * archive file. * *------------------------------------------------------------------------- */ static int ZipAddFile( - Tcl_Interp *interp, const char *path, const char *name, - Tcl_Channel out, const char *passwd, - char *buf, int bufsize, Tcl_HashTable *fileHash -) { + Tcl_Interp *interp, + const char *path, + const char *name, + Tcl_Channel out, + const char *passwd, + char *buf, + int bufsize, + Tcl_HashTable *fileHash) +{ Tcl_Channel in; Tcl_HashEntry *hPtr; ZipEntry *z; @@ -1923,127 +1991,127 @@ ZipAddFile( zpath = name; while (zpath != NULL && zpath[0] == '/') { - zpath++; + zpath++; } if ((zpath == NULL) || (zpath[0] == '\0')) { - return TCL_OK; + return TCL_OK; } zpathlen = strlen(zpath); if (zpathlen + ZIP_CENTRAL_HEADER_LEN > bufsize) { - Tcl_AppendResult(interp, "path too long for \"", path, "\"", (char *) NULL); - return TCL_ERROR; + Tcl_AppendResult(interp, "path too long for \"", path, "\"", + (char *) NULL); + return TCL_ERROR; } in = Tcl_OpenFileChannel(interp, path, "r", 0); - if ( - (in == NULL) - || (Tcl_SetChannelOption(interp, in, "-translation", "binary") != TCL_OK) - || (Tcl_SetChannelOption(interp, in, "-encoding", "binary") != TCL_OK) - ) { + if ((in == NULL) || Tcl_SetChannelOption(interp, in, + "-translation", "binary") != TCL_OK) { #ifdef _WIN32 - /* hopefully a directory */ - if (strcmp("permission denied", Tcl_PosixError(interp)) == 0) { - Tcl_Close(interp, in); - return TCL_OK; - } -#endif - Tcl_Close(interp, in); - return TCL_ERROR; + /* hopefully a directory */ + if (strcmp("permission denied", Tcl_PosixError(interp)) == 0) { + Tcl_Close(interp, in); + return TCL_OK; + } +#endif /* _WIN32 */ + Tcl_Close(interp, in); + return TCL_ERROR; } else { - Tcl_Obj *pathObj = Tcl_NewStringObj(path, -1); - Tcl_StatBuf statBuf; + Tcl_Obj *pathObj = Tcl_NewStringObj(path, -1); + Tcl_StatBuf statBuf; - Tcl_IncrRefCount(pathObj); - if (Tcl_FSStat(pathObj, &statBuf) != -1) { - mtime = statBuf.st_mtime; - } - Tcl_DecrRefCount(pathObj); + Tcl_IncrRefCount(pathObj); + if (Tcl_FSStat(pathObj, &statBuf) != -1) { + mtime = statBuf.st_mtime; + } + Tcl_DecrRefCount(pathObj); } Tcl_ResetResult(interp); crc = 0; nbyte = nbytecompr = 0; while ((len = Tcl_Read(in, buf, bufsize)) + 1 > 1) { - crc = crc32(crc, (unsigned char *) buf, len); - nbyte += len; + crc = crc32(crc, (unsigned char *) buf, len); + nbyte += len; } if (len == (size_t)-1) { - if (nbyte == 0) { - if (strcmp("illegal operation on a directory", - Tcl_PosixError(interp)) == 0) { - Tcl_Close(interp, in); - return TCL_OK; - } - } - Tcl_AppendResult(interp, "read error on \"", path, "\"", - (char *) NULL); - Tcl_Close(interp, in); - return TCL_ERROR; + if (nbyte == 0) { + if (strcmp("illegal operation on a directory", + Tcl_PosixError(interp)) == 0) { + Tcl_Close(interp, in); + return TCL_OK; + } + } + Tcl_AppendResult(interp, "read error on \"", path, "\"", + (char *) NULL); + Tcl_Close(interp, in); + return TCL_ERROR; } if (Tcl_Seek(in, 0, SEEK_SET) == -1) { - Tcl_AppendResult(interp, "seek error on \"", path, "\"", - (char *) NULL); - Tcl_Close(interp, in); - return TCL_ERROR; + Tcl_AppendResult(interp, "seek error on \"", path, "\"", + (char *) NULL); + Tcl_Close(interp, in); + return TCL_ERROR; } pos[0] = Tcl_Tell(out); memset(buf, '\0', ZIP_LOCAL_HEADER_LEN); memcpy(buf + ZIP_LOCAL_HEADER_LEN, zpath, zpathlen); len = zpathlen + ZIP_LOCAL_HEADER_LEN; if ((size_t)Tcl_Write(out, buf, len) != len) { -wrerr: - Tcl_AppendResult(interp, "write error", (char *) NULL); - Tcl_Close(interp, in); - return TCL_ERROR; + wrerr: + Tcl_AppendResult(interp, "write error", (char *) NULL); + Tcl_Close(interp, in); + return TCL_ERROR; } if ((len + pos[0]) & 3) { - unsigned char abuf[8]; - - /* - * Align payload to next 4-byte boundary using a dummy extra - * entry similar to the zipalign tool from Android's SDK. - */ - align = 4 + ((len + pos[0]) & 3); - zip_write_short(abuf, 0xffff); - zip_write_short(abuf + 2, align - 4); - zip_write_int(abuf + 4, 0x03020100); - if ((size_t)Tcl_Write(out, (const char *)abuf, align) != align) { - goto wrerr; - } + unsigned char abuf[8]; + + /* + * Align payload to next 4-byte boundary using a dummy extra entry + * similar to the zipalign tool from Android's SDK. + */ + + align = 4 + ((len + pos[0]) & 3); + zip_write_short(abuf, 0xffff); + zip_write_short(abuf + 2, align - 4); + zip_write_int(abuf + 4, 0x03020100); + if ((size_t) Tcl_Write(out, (const char *) abuf, align) != align) { + goto wrerr; + } } if (passwd != NULL) { - int i, ch, tmp; - unsigned char kvbuf[24]; - Tcl_Obj *ret; - - init_keys(passwd, keys, crc32tab); - for (i = 0; i < 12 - 2; i++) { - if (Tcl_EvalEx(interp, "expr int(rand() * 256) % 256", -1, 0) != TCL_OK) { - Tcl_AppendResult(interp, "PRNG error", (char *) NULL); - Tcl_Close(interp, in); - return TCL_ERROR; - } - ret = Tcl_GetObjResult(interp); - if (Tcl_GetIntFromObj(interp, ret, &ch) != TCL_OK) { - Tcl_Close(interp, in); - return TCL_ERROR; - } - kvbuf[i + 12] = (unsigned char) zencode(keys, crc32tab, ch, tmp); - } - Tcl_ResetResult(interp); - init_keys(passwd, keys, crc32tab); - for (i = 0; i < 12 - 2; i++) { - kvbuf[i] = (unsigned char) zencode(keys, crc32tab, kvbuf[i + 12], tmp); - } - kvbuf[i++] = (unsigned char) zencode(keys, crc32tab, crc >> 16, tmp); - kvbuf[i++] = (unsigned char) zencode(keys, crc32tab, crc >> 24, tmp); - len = Tcl_Write(out, (char *) kvbuf, 12); - memset(kvbuf, 0, 24); - if (len != 12) { - Tcl_AppendResult(interp, "write error", (char *) NULL); - Tcl_Close(interp, in); - return TCL_ERROR; - } - memcpy(keys0, keys, sizeof (keys0)); - nbytecompr += 12; + int i, ch, tmp; + unsigned char kvbuf[24]; + Tcl_Obj *ret; + + init_keys(passwd, keys, crc32tab); + for (i = 0; i < 12 - 2; i++) { + if (Tcl_EvalEx(interp, "expr int(rand() * 256) % 256", -1, + 0) != TCL_OK) { + Tcl_AppendResult(interp, "PRNG error", (char *) NULL); + Tcl_Close(interp, in); + return TCL_ERROR; + } + ret = Tcl_GetObjResult(interp); + if (Tcl_GetIntFromObj(interp, ret, &ch) != TCL_OK) { + Tcl_Close(interp, in); + return TCL_ERROR; + } + kvbuf[i + 12] = (unsigned char) zencode(keys, crc32tab, ch, tmp); + } + Tcl_ResetResult(interp); + init_keys(passwd, keys, crc32tab); + for (i = 0; i < 12 - 2; i++) { + kvbuf[i] = (unsigned char) zencode(keys, crc32tab, kvbuf[i + 12], tmp); + } + kvbuf[i++] = (unsigned char) zencode(keys, crc32tab, crc >> 16, tmp); + kvbuf[i++] = (unsigned char) zencode(keys, crc32tab, crc >> 24, tmp); + len = Tcl_Write(out, (char *) kvbuf, 12); + memset(kvbuf, 0, 24); + if (len != 12) { + Tcl_AppendResult(interp, "write error", (char *) NULL); + Tcl_Close(interp, in); + return TCL_ERROR; + } + memcpy(keys0, keys, sizeof (keys0)); + nbytecompr += 12; } Tcl_Flush(out); pos[2] = Tcl_Tell(out); @@ -2052,100 +2120,100 @@ wrerr: stream.zalloc = Z_NULL; stream.zfree = Z_NULL; stream.opaque = Z_NULL; - if (deflateInit2(&stream, 9, Z_DEFLATED, -15, 8, Z_DEFAULT_STRATEGY) != Z_OK) { - Tcl_AppendResult(interp, "compression init error on \"", path, "\"", - (char *) NULL); - Tcl_Close(interp, in); - return TCL_ERROR; + if (deflateInit2(&stream, 9, Z_DEFLATED, -15, 8, + Z_DEFAULT_STRATEGY) != Z_OK) { + Tcl_AppendResult(interp, "compression init error on \"", path, "\"", + (char *) NULL); + Tcl_Close(interp, in); + return TCL_ERROR; } do { - len = Tcl_Read(in, buf, bufsize); - if (len == (size_t)-1) { - Tcl_AppendResult(interp, "read error on \"", path, "\"", - (char *) NULL); - deflateEnd(&stream); - Tcl_Close(interp, in); - return TCL_ERROR; - } - stream.avail_in = len; - stream.next_in = (unsigned char *) buf; - flush = Tcl_Eof(in) ? Z_FINISH : Z_NO_FLUSH; - do { - stream.avail_out = sizeof (obuf); - stream.next_out = (unsigned char *) obuf; - len = deflate(&stream, flush); - if (len == (size_t)Z_STREAM_ERROR) { - Tcl_AppendResult(interp, "deflate error on \"", path, "\"", - (char *) NULL); - deflateEnd(&stream); - Tcl_Close(interp, in); - return TCL_ERROR; - } - olen = sizeof (obuf) - stream.avail_out; - if (passwd != NULL) { - size_t i; - int tmp; - - for (i = 0; i < olen; i++) { - obuf[i] = (char) zencode(keys, crc32tab, obuf[i], tmp); - } - } - if (olen && ((size_t)Tcl_Write(out, obuf, olen) != olen)) { - Tcl_AppendResult(interp, "write error", (char *) NULL); - deflateEnd(&stream); - Tcl_Close(interp, in); - return TCL_ERROR; - } - nbytecompr += olen; - } while (stream.avail_out == 0); + len = Tcl_Read(in, buf, bufsize); + if (len == (size_t)-1) { + Tcl_AppendResult(interp, "read error on \"", path, "\"", + (char *) NULL); + deflateEnd(&stream); + Tcl_Close(interp, in); + return TCL_ERROR; + } + stream.avail_in = len; + stream.next_in = (unsigned char *) buf; + flush = Tcl_Eof(in) ? Z_FINISH : Z_NO_FLUSH; + do { + stream.avail_out = sizeof (obuf); + stream.next_out = (unsigned char *) obuf; + len = deflate(&stream, flush); + if (len == (size_t)Z_STREAM_ERROR) { + Tcl_AppendResult(interp, "deflate error on \"", path, "\"", + (char *) NULL); + deflateEnd(&stream); + Tcl_Close(interp, in); + return TCL_ERROR; + } + olen = sizeof (obuf) - stream.avail_out; + if (passwd != NULL) { + size_t i; + int tmp; + + for (i = 0; i < olen; i++) { + obuf[i] = (char) zencode(keys, crc32tab, obuf[i], tmp); + } + } + if (olen && ((size_t)Tcl_Write(out, obuf, olen) != olen)) { + Tcl_AppendResult(interp, "write error", (char *) NULL); + deflateEnd(&stream); + Tcl_Close(interp, in); + return TCL_ERROR; + } + nbytecompr += olen; + } while (stream.avail_out == 0); } while (flush != Z_FINISH); deflateEnd(&stream); Tcl_Flush(out); pos[1] = Tcl_Tell(out); if (nbyte - nbytecompr <= 0) { - /* - * Compressed file larger than input, - * write it again uncompressed. - */ - if (Tcl_Seek(in, 0, SEEK_SET) != 0) { - goto seekErr; - } - if (Tcl_Seek(out, pos[2], SEEK_SET) != pos[2]) { -seekErr: - Tcl_Close(interp, in); - Tcl_AppendResult(interp, "seek error", (char *) NULL); - return TCL_ERROR; - } - nbytecompr = (passwd != NULL) ? 12 : 0; - while (1) { - len = Tcl_Read(in, buf, bufsize); - if (len == (size_t)-1) { - Tcl_AppendResult(interp, "read error on \"", path, "\"", - (char *) NULL); - Tcl_Close(interp, in); - return TCL_ERROR; - } else if (len == 0) { - break; - } - if (passwd != NULL) { - size_t i; - int tmp; - - for (i = 0; i < len; i++) { - buf[i] = (char) zencode(keys0, crc32tab, buf[i], tmp); - } - } - if ((size_t)Tcl_Write(out, buf, len) != len) { - Tcl_AppendResult(interp, "write error", (char *) NULL); - Tcl_Close(interp, in); - return TCL_ERROR; - } - nbytecompr += len; - } - cmeth = ZIP_COMPMETH_STORED; - Tcl_Flush(out); - pos[1] = Tcl_Tell(out); - Tcl_TruncateChannel(out, pos[1]); + /* + * Compressed file larger than input, write it again uncompressed. + */ + if (Tcl_Seek(in, 0, SEEK_SET) != 0) { + goto seekErr; + } + if (Tcl_Seek(out, pos[2], SEEK_SET) != pos[2]) { + seekErr: + Tcl_Close(interp, in); + Tcl_AppendResult(interp, "seek error", (char *) NULL); + return TCL_ERROR; + } + nbytecompr = (passwd != NULL) ? 12 : 0; + while (1) { + len = Tcl_Read(in, buf, bufsize); + if (len == (size_t)-1) { + Tcl_AppendResult(interp, "read error on \"", path, "\"", + (char *) NULL); + Tcl_Close(interp, in); + return TCL_ERROR; + } else if (len == 0) { + break; + } + if (passwd != NULL) { + size_t i; + int tmp; + + for (i = 0; i < len; i++) { + buf[i] = (char) zencode(keys0, crc32tab, buf[i], tmp); + } + } + if ((size_t)Tcl_Write(out, buf, len) != len) { + Tcl_AppendResult(interp, "write error", (char *) NULL); + Tcl_Close(interp, in); + return TCL_ERROR; + } + nbytecompr += len; + } + cmeth = ZIP_COMPMETH_STORED; + Tcl_Flush(out); + pos[1] = Tcl_Tell(out); + Tcl_TruncateChannel(out, pos[1]); } Tcl_Close(interp, in); @@ -2165,14 +2233,14 @@ seekErr: z->data = NULL; hPtr = Tcl_CreateHashEntry(fileHash, zpath, &isNew); if (!isNew) { - Tcl_AppendResult(interp, "non-unique path name \"", path, "\"", - (char *) NULL); - Tcl_Free((char *) z); - return TCL_ERROR; + Tcl_AppendResult(interp, "non-unique path name \"", path, "\"", + (char *) NULL); + Tcl_Free((char *) z); + return TCL_ERROR; } else { - Tcl_SetHashValue(hPtr, (ClientData) z); - z->name = Tcl_GetHashKey(fileHash, hPtr); - z->next = NULL; + Tcl_SetHashValue(hPtr, (ClientData) z); + z->name = Tcl_GetHashKey(fileHash, hPtr); + z->next = NULL; } /* @@ -2190,23 +2258,23 @@ seekErr: zip_write_short(buf + ZIP_LOCAL_PATHLEN_OFFS, zpathlen); zip_write_short(buf + ZIP_LOCAL_EXTRALEN_OFFS, align); if (Tcl_Seek(out, pos[0], SEEK_SET) != pos[0]) { - Tcl_DeleteHashEntry(hPtr); - Tcl_Free((char *) z); - Tcl_AppendResult(interp, "seek error", (char *) NULL); - return TCL_ERROR; + Tcl_DeleteHashEntry(hPtr); + Tcl_Free((char *) z); + Tcl_AppendResult(interp, "seek error", (char *) NULL); + return TCL_ERROR; } if (Tcl_Write(out, buf, ZIP_LOCAL_HEADER_LEN) != ZIP_LOCAL_HEADER_LEN) { - Tcl_DeleteHashEntry(hPtr); - Tcl_Free((char *) z); - Tcl_AppendResult(interp, "write error", (char *) NULL); - return TCL_ERROR; + Tcl_DeleteHashEntry(hPtr); + Tcl_Free((char *) z); + Tcl_AppendResult(interp, "write error", (char *) NULL); + return TCL_ERROR; } Tcl_Flush(out); if (Tcl_Seek(out, pos[1], SEEK_SET) != pos[1]) { - Tcl_DeleteHashEntry(hPtr); - Tcl_Free((char *) z); - Tcl_AppendResult(interp, "seek error", (char *) NULL); - return TCL_ERROR; + Tcl_DeleteHashEntry(hPtr); + Tcl_Free((char *) z); + Tcl_AppendResult(interp, "seek error", (char *) NULL); + return TCL_ERROR; } return TCL_OK; } @@ -2216,23 +2284,28 @@ seekErr: * * ZipFSMkZipOrImgObjCmd -- * - * This procedure is creates a new ZIP archive file or image file - * given output filename, input directory of files to be archived, - * optional password, and optional image to be prepended to the - * output ZIP archive file. + * This procedure is creates a new ZIP archive file or image file given + * output filename, input directory of files to be archived, optional + * password, and optional image to be prepended to the output ZIP archive + * file. * * Results: - * A standard Tcl result. + * A standard Tcl result. * * Side effects: - * A new ZIP archive file or image file is written. + * A new ZIP archive file or image file is written. * *------------------------------------------------------------------------- */ static int -ZipFSMkZipOrImgObjCmd(ClientData clientData, Tcl_Interp *interp, - int isImg, int isList, int objc, Tcl_Obj *const objv[]) +ZipFSMkZipOrImgObjCmd( + ClientData clientData, + Tcl_Interp *interp, + int isImg, + int isList, + int objc, + Tcl_Obj *const objv[]) { Tcl_Channel out; int pwlen = 0, count, ret = TCL_ERROR, lobjc; @@ -2246,300 +2319,297 @@ ZipFSMkZipOrImgObjCmd(ClientData clientData, Tcl_Interp *interp, char *strip = NULL, *pw = NULL, pwbuf[264], buf[4096]; if (isList) { - if ((objc < 3) || (objc > (isImg ? 5 : 4))) { - Tcl_WrongNumArgs(interp, 1, objv, isImg ? - "outfile inlist ?password infile?" : - "outfile inlist ?password?"); - return TCL_ERROR; - } + if ((objc < 3) || (objc > (isImg ? 5 : 4))) { + Tcl_WrongNumArgs(interp, 1, objv, isImg ? + "outfile inlist ?password infile?" : + "outfile inlist ?password?"); + return TCL_ERROR; + } } else { - if ((objc < 3) || (objc > (isImg ? 6 : 5))) { - Tcl_WrongNumArgs(interp, 1, objv, isImg ? - "outfile indir ?strip? ?password? ?infile?" : - "outfile indir ?strip? ?password?"); - return TCL_ERROR; - } + if ((objc < 3) || (objc > (isImg ? 6 : 5))) { + Tcl_WrongNumArgs(interp, 1, objv, isImg ? + "outfile indir ?strip? ?password? ?infile?" : + "outfile indir ?strip? ?password?"); + return TCL_ERROR; + } } pwbuf[0] = 0; if (objc > (isList ? 3 : 4)) { - pw = Tcl_GetString(objv[isList ? 3 : 4]); - pwlen = strlen(pw); - if ((pwlen > 255) || (strchr(pw, 0xff) != NULL)) { - Tcl_SetObjResult(interp, - Tcl_NewStringObj("illegal password", -1)); - return TCL_ERROR; - } + pw = Tcl_GetString(objv[isList ? 3 : 4]); + pwlen = strlen(pw); + if ((pwlen > 255) || (strchr(pw, 0xff) != NULL)) { + Tcl_SetObjResult(interp, + Tcl_NewStringObj("illegal password", -1)); + return TCL_ERROR; + } } if (isList) { - list = objv[2]; - Tcl_IncrRefCount(list); + list = objv[2]; + Tcl_IncrRefCount(list); } else { - Tcl_Obj *cmd[3]; - - cmd[1] = Tcl_NewStringObj("::tcl::zipfs::find", -1); - cmd[2] = objv[2]; - cmd[0] = Tcl_NewListObj(2, cmd + 1); - Tcl_IncrRefCount(cmd[0]); - if (Tcl_EvalObjEx(interp, cmd[0], TCL_EVAL_DIRECT) != TCL_OK) { - Tcl_DecrRefCount(cmd[0]); - return TCL_ERROR; - } - Tcl_DecrRefCount(cmd[0]); - list = Tcl_GetObjResult(interp); - Tcl_IncrRefCount(list); + Tcl_Obj *cmd[3]; + + cmd[1] = Tcl_NewStringObj("::tcl::zipfs::find", -1); + cmd[2] = objv[2]; + cmd[0] = Tcl_NewListObj(2, cmd + 1); + Tcl_IncrRefCount(cmd[0]); + if (Tcl_EvalObjEx(interp, cmd[0], TCL_EVAL_DIRECT) != TCL_OK) { + Tcl_DecrRefCount(cmd[0]); + return TCL_ERROR; + } + Tcl_DecrRefCount(cmd[0]); + list = Tcl_GetObjResult(interp); + Tcl_IncrRefCount(list); } if (Tcl_ListObjGetElements(interp, list, &lobjc, &lobjv) != TCL_OK) { - Tcl_DecrRefCount(list); - return TCL_ERROR; + Tcl_DecrRefCount(list); + return TCL_ERROR; } if (isList && (lobjc % 2)) { - Tcl_DecrRefCount(list); - Tcl_SetObjResult(interp, - Tcl_NewStringObj("need even number of elements", -1)); - return TCL_ERROR; + Tcl_DecrRefCount(list); + Tcl_SetObjResult(interp, + Tcl_NewStringObj("need even number of elements", -1)); + return TCL_ERROR; } if (lobjc == 0) { - Tcl_DecrRefCount(list); - Tcl_SetObjResult(interp, Tcl_NewStringObj("empty archive", -1)); - return TCL_ERROR; + Tcl_DecrRefCount(list); + Tcl_SetObjResult(interp, Tcl_NewStringObj("empty archive", -1)); + return TCL_ERROR; } out = Tcl_OpenFileChannel(interp, Tcl_GetString(objv[1]), "w", 0755); - if ( - (out == NULL) - || (Tcl_SetChannelOption(interp, out, "-translation", "binary") != TCL_OK) - || (Tcl_SetChannelOption(interp, out, "-encoding", "binary") != TCL_OK) - ) { - Tcl_DecrRefCount(list); - Tcl_Close(interp, out); - return TCL_ERROR; + if ((out == NULL) || (Tcl_SetChannelOption(interp, out, + "-translation", "binary") != TCL_OK)) { + Tcl_DecrRefCount(list); + Tcl_Close(interp, out); + return TCL_ERROR; } if (pwlen <= 0) { - pw = NULL; - pwlen = 0; + pw = NULL; + pwlen = 0; } if (isImg) { - ZipFile *zf, zf0; - int isMounted = 0; - const char *imgName; - - if (isList) { - imgName = (objc > 4) ? Tcl_GetString(objv[4]) : Tcl_GetNameOfExecutable(); - } else { - imgName = (objc > 5) ? Tcl_GetString(objv[5]) : Tcl_GetNameOfExecutable(); - } - if (pwlen) { - i = 0; - len = pwlen; - while (len > 0) { - int ch = pw[len - 1]; - - pwbuf[i] = (ch & 0x0f) | pwrot[(ch >> 4) & 0x0f]; - i++; - len--; - } - pwbuf[i] = i; - ++i; - pwbuf[i++] = (char) ZIP_PASSWORD_END_SIG; - pwbuf[i++] = (char) (ZIP_PASSWORD_END_SIG >> 8); - pwbuf[i++] = (char) (ZIP_PASSWORD_END_SIG >> 16); - pwbuf[i++] = (char) (ZIP_PASSWORD_END_SIG >> 24); - pwbuf[i] = '\0'; - } - /* Check for mounted image */ - WriteLock(); - hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); - while (hPtr != NULL) { - if ((zf = (ZipFile *) Tcl_GetHashValue(hPtr)) != NULL) { - if (strcmp(zf->name, imgName) == 0) { - isMounted = 1; - zf->nopen++; - break; - } - } - hPtr = Tcl_NextHashEntry(&search); - } - Unlock(); - if (!isMounted) { - zf = &zf0; - } - if (isMounted || - (ZipFSOpenArchive(interp, imgName, 0, zf) == TCL_OK)) { - if ((size_t)Tcl_Write(out, (char *) zf->data, zf->baseoffsp) != zf->baseoffsp) { - memset(pwbuf, 0, sizeof (pwbuf)); - Tcl_DecrRefCount(list); - Tcl_SetObjResult(interp, Tcl_NewStringObj("write error", -1)); - Tcl_Close(interp, out); - if (zf == &zf0) { - ZipFSCloseArchive(interp, zf); - } else { - WriteLock(); - zf->nopen--; - Unlock(); - } - return TCL_ERROR; - } - if (zf == &zf0) { - ZipFSCloseArchive(interp, zf); - } else { - WriteLock(); - zf->nopen--; - Unlock(); - } - } else { - size_t k; - int m, n; - Tcl_Channel in; - const char *errMsg = "seek error"; - - /* - * Fall back to read it as plain file which - * hopefully is a static tclsh or wish binary - * with proper zipfs infrastructure built in. - */ - Tcl_ResetResult(interp); - in = Tcl_OpenFileChannel(interp, imgName, "r", 0644); - if (in == NULL) { - memset(pwbuf, 0, sizeof (pwbuf)); - Tcl_DecrRefCount(list); - Tcl_Close(interp, out); - return TCL_ERROR; - } - Tcl_SetChannelOption(interp, in, "-translation", "binary"); - Tcl_SetChannelOption(interp, in, "-encoding", "binary"); - i = Tcl_Seek(in, 0, SEEK_END); - if (i == (size_t)-1) { -cperr: - memset(pwbuf, 0, sizeof (pwbuf)); - Tcl_DecrRefCount(list); - Tcl_SetObjResult(interp, Tcl_NewStringObj(errMsg, -1)); - Tcl_Close(interp, out); - Tcl_Close(interp, in); - return TCL_ERROR; - } - Tcl_Seek(in, 0, SEEK_SET); - k = 0; - while (k < i) { - m = i - k; - if (m > (int)sizeof (buf)) { - m = (int)sizeof (buf); - } - n = Tcl_Read(in, buf, m); - if (n == -1) { - errMsg = "read error"; - goto cperr; - } else if (n == 0) { - break; - } - m = Tcl_Write(out, buf, n); - if (m != n) { - errMsg = "write error"; - goto cperr; - } - k += m; - } - Tcl_Close(interp, in); - } - len = strlen(pwbuf); - if (len > 0) { - i = Tcl_Write(out, pwbuf, len); - if (i != len) { - Tcl_DecrRefCount(list); - Tcl_SetObjResult(interp, Tcl_NewStringObj("write error", -1)); - Tcl_Close(interp, out); - return TCL_ERROR; - } - } - memset(pwbuf, 0, sizeof (pwbuf)); - Tcl_Flush(out); + ZipFile *zf, zf0; + int isMounted = 0; + const char *imgName; + + if (isList) { + imgName = (objc > 4) ? Tcl_GetString(objv[4]) : + Tcl_GetNameOfExecutable(); + } else { + imgName = (objc > 5) ? Tcl_GetString(objv[5]) : + Tcl_GetNameOfExecutable(); + } + if (pwlen) { + i = 0; + len = pwlen; + while (len > 0) { + int ch = pw[len - 1]; + + pwbuf[i] = (ch & 0x0f) | pwrot[(ch >> 4) & 0x0f]; + i++; + len--; + } + pwbuf[i] = i; + ++i; + pwbuf[i++] = (char) ZIP_PASSWORD_END_SIG; + pwbuf[i++] = (char) (ZIP_PASSWORD_END_SIG >> 8); + pwbuf[i++] = (char) (ZIP_PASSWORD_END_SIG >> 16); + pwbuf[i++] = (char) (ZIP_PASSWORD_END_SIG >> 24); + pwbuf[i] = '\0'; + } + /* Check for mounted image */ + WriteLock(); + hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); + while (hPtr != NULL) { + if ((zf = (ZipFile *) Tcl_GetHashValue(hPtr)) != NULL) { + if (strcmp(zf->name, imgName) == 0) { + isMounted = 1; + zf->nopen++; + break; + } + } + hPtr = Tcl_NextHashEntry(&search); + } + Unlock(); + if (!isMounted) { + zf = &zf0; + } + if (isMounted || ZipFSOpenArchive(interp, imgName, 0, zf) == TCL_OK) { + if ((size_t) Tcl_Write(out, (char *) zf->data, + zf->baseoffsp) != zf->baseoffsp) { + memset(pwbuf, 0, sizeof (pwbuf)); + Tcl_DecrRefCount(list); + Tcl_SetObjResult(interp, Tcl_NewStringObj("write error", -1)); + Tcl_Close(interp, out); + if (zf == &zf0) { + ZipFSCloseArchive(interp, zf); + } else { + WriteLock(); + zf->nopen--; + Unlock(); + } + return TCL_ERROR; + } + if (zf == &zf0) { + ZipFSCloseArchive(interp, zf); + } else { + WriteLock(); + zf->nopen--; + Unlock(); + } + } else { + size_t k; + int m, n; + Tcl_Channel in; + const char *errMsg = "seek error"; + + /* + * Fall back to read it as plain file which hopefully is a static + * tclsh or wish binary with proper zipfs infrastructure built in. + */ + + Tcl_ResetResult(interp); + in = Tcl_OpenFileChannel(interp, imgName, "r", 0644); + if (in == NULL) { + memset(pwbuf, 0, sizeof (pwbuf)); + Tcl_DecrRefCount(list); + Tcl_Close(interp, out); + return TCL_ERROR; + } + Tcl_SetChannelOption(interp, in, "-translation", "binary"); + i = Tcl_Seek(in, 0, SEEK_END); + if (i == (size_t)-1) { + cperr: + memset(pwbuf, 0, sizeof (pwbuf)); + Tcl_DecrRefCount(list); + Tcl_SetObjResult(interp, Tcl_NewStringObj(errMsg, -1)); + Tcl_Close(interp, out); + Tcl_Close(interp, in); + return TCL_ERROR; + } + Tcl_Seek(in, 0, SEEK_SET); + k = 0; + while (k < i) { + m = i - k; + if (m > (int)sizeof (buf)) { + m = (int)sizeof (buf); + } + n = Tcl_Read(in, buf, m); + if (n == -1) { + errMsg = "read error"; + goto cperr; + } else if (n == 0) { + break; + } + m = Tcl_Write(out, buf, n); + if (m != n) { + errMsg = "write error"; + goto cperr; + } + k += m; + } + Tcl_Close(interp, in); + } + len = strlen(pwbuf); + if (len > 0) { + i = Tcl_Write(out, pwbuf, len); + if (i != len) { + Tcl_DecrRefCount(list); + Tcl_SetObjResult(interp, Tcl_NewStringObj("write error", -1)); + Tcl_Close(interp, out); + return TCL_ERROR; + } + } + memset(pwbuf, 0, sizeof (pwbuf)); + Tcl_Flush(out); } Tcl_InitHashTable(&fileHash, TCL_STRING_KEYS); pos[0] = Tcl_Tell(out); if (!isList && (objc > 3)) { - strip = Tcl_GetString(objv[3]); - slen = strlen(strip); + strip = Tcl_GetString(objv[3]); + slen = strlen(strip); } for (i = 0; i < (size_t)lobjc; i += (isList ? 2 : 1)) { - const char *path, *name; - - path = Tcl_GetString(lobjv[i]); - if (isList) { - name = Tcl_GetString(lobjv[i + 1]); - } else { - name = path; - if (slen > 0) { - len = strlen(name); - if ((len <= slen) || (strncmp(strip, name, slen) != 0)) { - continue; - } - name += slen; - } - } - while (name[0] == '/') { - ++name; - } - if (name[0] == '\0') { - continue; - } - if (ZipAddFile(interp, path, name, out, pw, buf, sizeof (buf), - &fileHash) != TCL_OK) { - goto done; - } + const char *path, *name; + + path = Tcl_GetString(lobjv[i]); + if (isList) { + name = Tcl_GetString(lobjv[i + 1]); + } else { + name = path; + if (slen > 0) { + len = strlen(name); + if ((len <= slen) || (strncmp(strip, name, slen) != 0)) { + continue; + } + name += slen; + } + } + while (name[0] == '/') { + ++name; + } + if (name[0] == '\0') { + continue; + } + if (ZipAddFile(interp, path, name, out, pw, buf, sizeof (buf), + &fileHash) != TCL_OK) { + goto done; + } } pos[1] = Tcl_Tell(out); count = 0; for (i = 0; i < (size_t)lobjc; i += (isList ? 2 : 1)) { - const char *path, *name; - - path = Tcl_GetString(lobjv[i]); - if (isList) { - name = Tcl_GetString(lobjv[i + 1]); - } else { - name = path; - if (slen > 0) { - len = strlen(name); - if ((len <= slen) || (strncmp(strip, name, slen) != 0)) { - continue; - } - name += slen; - } - } - while (name[0] == '/') { - ++name; - } - if (name[0] == '\0') { - continue; - } - hPtr = Tcl_FindHashEntry(&fileHash, name); - if (hPtr == NULL) { - continue; - } - z = (ZipEntry *) Tcl_GetHashValue(hPtr); - len = strlen(z->name); - zip_write_int(buf + ZIP_CENTRAL_SIG_OFFS, ZIP_CENTRAL_HEADER_SIG); - zip_write_short(buf + ZIP_CENTRAL_VERSIONMADE_OFFS, ZIP_MIN_VERSION); - zip_write_short(buf + ZIP_CENTRAL_VERSION_OFFS, ZIP_MIN_VERSION); - zip_write_short(buf + ZIP_CENTRAL_FLAGS_OFFS, z->isenc ? 1 : 0); - zip_write_short(buf + ZIP_CENTRAL_COMPMETH_OFFS, z->cmeth); - zip_write_short(buf + ZIP_CENTRAL_MTIME_OFFS, ToDosTime(z->timestamp)); - zip_write_short(buf + ZIP_CENTRAL_MDATE_OFFS, ToDosDate(z->timestamp)); - zip_write_int(buf + ZIP_CENTRAL_CRC32_OFFS, z->crc32); - zip_write_int(buf + ZIP_CENTRAL_COMPLEN_OFFS, z->nbytecompr); - zip_write_int(buf + ZIP_CENTRAL_UNCOMPLEN_OFFS, z->nbyte); - zip_write_short(buf + ZIP_CENTRAL_PATHLEN_OFFS, len); - zip_write_short(buf + ZIP_CENTRAL_EXTRALEN_OFFS, 0); - zip_write_short(buf + ZIP_CENTRAL_FCOMMENTLEN_OFFS, 0); - zip_write_short(buf + ZIP_CENTRAL_DISKFILE_OFFS, 0); - zip_write_short(buf + ZIP_CENTRAL_IATTR_OFFS, 0); - zip_write_int(buf + ZIP_CENTRAL_EATTR_OFFS, 0); - zip_write_int(buf + ZIP_CENTRAL_LOCALHDR_OFFS, z->offset - pos[0]); - if ( - (Tcl_Write(out, buf, ZIP_CENTRAL_HEADER_LEN) != ZIP_CENTRAL_HEADER_LEN) - || ((size_t)Tcl_Write(out, z->name, len) != len) - ) { - Tcl_SetObjResult(interp, Tcl_NewStringObj("write error", -1)); - goto done; - } - count++; + const char *path, *name; + + path = Tcl_GetString(lobjv[i]); + if (isList) { + name = Tcl_GetString(lobjv[i + 1]); + } else { + name = path; + if (slen > 0) { + len = strlen(name); + if ((len <= slen) || (strncmp(strip, name, slen) != 0)) { + continue; + } + name += slen; + } + } + while (name[0] == '/') { + ++name; + } + if (name[0] == '\0') { + continue; + } + hPtr = Tcl_FindHashEntry(&fileHash, name); + if (hPtr == NULL) { + continue; + } + z = Tcl_GetHashValue(hPtr); + len = strlen(z->name); + zip_write_int(buf + ZIP_CENTRAL_SIG_OFFS, ZIP_CENTRAL_HEADER_SIG); + zip_write_short(buf + ZIP_CENTRAL_VERSIONMADE_OFFS, ZIP_MIN_VERSION); + zip_write_short(buf + ZIP_CENTRAL_VERSION_OFFS, ZIP_MIN_VERSION); + zip_write_short(buf + ZIP_CENTRAL_FLAGS_OFFS, z->isenc ? 1 : 0); + zip_write_short(buf + ZIP_CENTRAL_COMPMETH_OFFS, z->cmeth); + zip_write_short(buf + ZIP_CENTRAL_MTIME_OFFS, ToDosTime(z->timestamp)); + zip_write_short(buf + ZIP_CENTRAL_MDATE_OFFS, ToDosDate(z->timestamp)); + zip_write_int(buf + ZIP_CENTRAL_CRC32_OFFS, z->crc32); + zip_write_int(buf + ZIP_CENTRAL_COMPLEN_OFFS, z->nbytecompr); + zip_write_int(buf + ZIP_CENTRAL_UNCOMPLEN_OFFS, z->nbyte); + zip_write_short(buf + ZIP_CENTRAL_PATHLEN_OFFS, len); + zip_write_short(buf + ZIP_CENTRAL_EXTRALEN_OFFS, 0); + zip_write_short(buf + ZIP_CENTRAL_FCOMMENTLEN_OFFS, 0); + zip_write_short(buf + ZIP_CENTRAL_DISKFILE_OFFS, 0); + zip_write_short(buf + ZIP_CENTRAL_IATTR_OFFS, 0); + zip_write_int(buf + ZIP_CENTRAL_EATTR_OFFS, 0); + zip_write_int(buf + ZIP_CENTRAL_LOCALHDR_OFFS, z->offset - pos[0]); + if ((Tcl_Write(out, buf, + ZIP_CENTRAL_HEADER_LEN) != ZIP_CENTRAL_HEADER_LEN) + || ((size_t)Tcl_Write(out, z->name, len) != len)) { + Tcl_SetObjResult(interp, Tcl_NewStringObj("write error", -1)); + goto done; + } + count++; } Tcl_Flush(out); pos[2] = Tcl_Tell(out); @@ -2552,24 +2622,24 @@ cperr: zip_write_int(buf + ZIP_CENTRAL_DIRSTART_OFFS, pos[1] - pos[0]); zip_write_short(buf + ZIP_CENTRAL_COMMENTLEN_OFFS, 0); if (Tcl_Write(out, buf, ZIP_CENTRAL_END_LEN) != ZIP_CENTRAL_END_LEN) { - Tcl_SetObjResult(interp, Tcl_NewStringObj("write error", -1)); - goto done; + Tcl_SetObjResult(interp, Tcl_NewStringObj("write error", -1)); + goto done; } Tcl_Flush(out); ret = TCL_OK; -done: + done: if (ret == TCL_OK) { - ret = Tcl_Close(interp, out); + ret = Tcl_Close(interp, out); } else { - Tcl_Close(interp, out); + Tcl_Close(interp, out); } Tcl_DecrRefCount(list); hPtr = Tcl_FirstHashEntry(&fileHash, &search); while (hPtr != NULL) { - z = (ZipEntry *) Tcl_GetHashValue(hPtr); - Tcl_Free((char *) z); - Tcl_DeleteHashEntry(hPtr); - hPtr = Tcl_NextHashEntry(&search); + z = (ZipEntry *) Tcl_GetHashValue(hPtr); + Tcl_Free((char *) z); + Tcl_DeleteHashEntry(hPtr); + hPtr = Tcl_NextHashEntry(&search); } Tcl_DeleteHashTable(&fileHash); return ret; @@ -2580,29 +2650,35 @@ done: * * ZipFSMkZipObjCmd -- * - * This procedure is invoked to process the "zipfs::mkzip" command. - * See description of ZipFSMkZipOrImgCmd(). + * This procedure is invoked to process the "zipfs::mkzip" command. See + * description of ZipFSMkZipOrImgCmd(). * * Results: - * A standard Tcl result. + * A standard Tcl result. * * Side effects: - * See description of ZipFSMkZipOrImgCmd(). + * See description of ZipFSMkZipOrImgCmd(). * *------------------------------------------------------------------------- */ static int ZipFSMkZipObjCmd( - ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[] -) { + ClientData clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *const objv[]) +{ return ZipFSMkZipOrImgObjCmd(clientData, interp, 0, 0, objc, objv); } static int ZipFSLMkZipObjCmd( - ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[] -) { + ClientData clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *const objv[]) +{ return ZipFSMkZipOrImgObjCmd(clientData, interp, 0, 1, objc, objv); } @@ -2611,28 +2687,34 @@ ZipFSLMkZipObjCmd( * * ZipFSZipFSOpenArchiveObjCmd -- * - * This procedure is invoked to process the "zipfs::mkimg" command. - * See description of ZipFSMkZipOrImgCmd(). + * This procedure is invoked to process the "zipfs::mkimg" command. See + * description of ZipFSMkZipOrImgCmd(). * * Results: - * A standard Tcl result. + * A standard Tcl result. * * Side effects: - * See description of ZipFSMkZipOrImgCmd(). + * See description of ZipFSMkZipOrImgCmd(). * *------------------------------------------------------------------------- */ static int -ZipFSMkImgObjCmd(ClientData clientData, Tcl_Interp *interp, - int objc, Tcl_Obj *const objv[]) +ZipFSMkImgObjCmd( + ClientData clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *const objv[]) { return ZipFSMkZipOrImgObjCmd(clientData, interp, 1, 0, objc, objv); } static int -ZipFSLMkImgObjCmd(ClientData clientData, Tcl_Interp *interp, - int objc, Tcl_Obj *const objv[]) +ZipFSLMkImgObjCmd( + ClientData clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *const objv[]) { return ZipFSMkZipOrImgObjCmd(clientData, interp, 1, 1, objc, objv); } @@ -2642,87 +2724,97 @@ ZipFSLMkImgObjCmd(ClientData clientData, Tcl_Interp *interp, * * ZipFSCanonicalObjCmd -- * - * This procedure is invoked to process the "zipfs::canonical" command. - * It returns the canonical name for a file within zipfs + * This procedure is invoked to process the "zipfs::canonical" command. + * It returns the canonical name for a file within zipfs * * Results: - * Always TCL_OK. + * Always TCL_OK provided the right number of arguments are supplied. * * Side effects: - * None. + * None. * *------------------------------------------------------------------------- */ static int ZipFSCanonicalObjCmd( - ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[] + ClientData clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *const objv[] ) { - char *mntpoint=NULL; - char *filename=NULL; + char *mntpoint = NULL; + char *filename = NULL; char *result; Tcl_DString dPath; - if (objc != 2 && objc != 3 && objc!=4) { - Tcl_WrongNumArgs(interp, 1, objv, "?mntpnt? filename ?ZIPFS?"); - return TCL_ERROR; + if (objc != 2 && objc != 3 && objc != 4) { + Tcl_WrongNumArgs(interp, 1, objv, "?mntpnt? filename ?ZIPFS?"); + return TCL_ERROR; } Tcl_DStringInit(&dPath); - if(objc==2) { - filename = Tcl_GetString(objv[1]); - result=CanonicalPath("",filename,&dPath,1); - } else if (objc==3) { - mntpoint = Tcl_GetString(objv[1]); - filename = Tcl_GetString(objv[2]); - result=CanonicalPath(mntpoint,filename,&dPath,1); + if (objc == 2) { + filename = Tcl_GetString(objv[1]); + result = CanonicalPath("", filename, &dPath, 1); + } else if (objc == 3) { + mntpoint = Tcl_GetString(objv[1]); + filename = Tcl_GetString(objv[2]); + result = CanonicalPath(mntpoint, filename, &dPath, 1); } else { - int zipfs=0; - if(Tcl_GetBooleanFromObj(interp,objv[3],&zipfs)) { - return TCL_ERROR; - } - mntpoint = Tcl_GetString(objv[1]); - filename = Tcl_GetString(objv[2]); - result=CanonicalPath(mntpoint,filename,&dPath,zipfs); - } - Tcl_SetObjResult(interp,Tcl_NewStringObj(result,-1)); + int zipfs = 0; + + if (Tcl_GetBooleanFromObj(interp, objv[3], &zipfs)) { + return TCL_ERROR; + } + mntpoint = Tcl_GetString(objv[1]); + filename = Tcl_GetString(objv[2]); + result = CanonicalPath(mntpoint, filename, &dPath, zipfs); + } + Tcl_SetObjResult(interp, Tcl_NewStringObj(result, -1)); return TCL_OK; } - + /* *------------------------------------------------------------------------- * * ZipFSExistsObjCmd -- * - * This procedure is invoked to process the "zipfs::exists" command. - * It tests for the existence of a file in the ZIP filesystem and - * places a boolean into the interp's result. + * This procedure is invoked to process the "zipfs::exists" command. It + * tests for the existence of a file in the ZIP filesystem and places a + * boolean into the interp's result. * * Results: - * Always TCL_OK. + * Always TCL_OK provided the right number of arguments are supplied. * * Side effects: - * None. + * None. * *------------------------------------------------------------------------- */ static int ZipFSExistsObjCmd( - ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[] -) { + ClientData clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *const objv[]) +{ char *filename; int exists; Tcl_DString ds; if (objc != 2) { - Tcl_WrongNumArgs(interp, 1, objv, "filename"); - return TCL_ERROR; + Tcl_WrongNumArgs(interp, 1, objv, "filename"); + return TCL_ERROR; } - /* prepend ZIPFS_VOLUME to filename, eliding the final / */ + /* + * Prepend ZIPFS_VOLUME to filename, eliding the final / + */ + filename = Tcl_GetStringFromObj(objv[1], 0); Tcl_DStringInit(&ds); - Tcl_DStringAppend(&ds, ZIPFS_VOLUME, ZIPFS_VOLUME_LEN-1); + Tcl_DStringAppend(&ds, ZIPFS_VOLUME, ZIPFS_VOLUME_LEN - 1); Tcl_DStringAppend(&ds, filename, -1); filename = Tcl_DStringValue(&ds); @@ -2730,7 +2822,7 @@ ZipFSExistsObjCmd( exists = ZipFSLookup(filename) != NULL; Unlock(); - Tcl_SetObjResult(interp,Tcl_NewBooleanObj(exists)); + Tcl_SetObjResult(interp, Tcl_NewBooleanObj(exists)); return TCL_OK; } @@ -2739,42 +2831,46 @@ ZipFSExistsObjCmd( * * ZipFSInfoObjCmd -- * - * This procedure is invoked to process the "zipfs::info" command. - * On success, it returns a Tcl list made up of name of ZIP archive - * file, size uncompressed, size compressed, and archive offset of - * a file in the ZIP filesystem. + * This procedure is invoked to process the "zipfs::info" command. On + * success, it returns a Tcl list made up of name of ZIP archive file, + * size uncompressed, size compressed, and archive offset of a file in + * the ZIP filesystem. * * Results: - * A standard Tcl result. + * A standard Tcl result. * * Side effects: - * None. + * None. * *------------------------------------------------------------------------- */ static int ZipFSInfoObjCmd( - ClientData clientData, Tcl_Interp *interp,int objc, Tcl_Obj *const objv[] -) { + ClientData clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *const objv[]) +{ char *filename; ZipEntry *z; if (objc != 2) { - Tcl_WrongNumArgs(interp, 1, objv, "filename"); - return TCL_ERROR; + Tcl_WrongNumArgs(interp, 1, objv, "filename"); + return TCL_ERROR; } filename = Tcl_GetStringFromObj(objv[1], 0); ReadLock(); z = ZipFSLookup(filename); if (z != NULL) { - Tcl_Obj *result = Tcl_GetObjResult(interp); + Tcl_Obj *result = Tcl_GetObjResult(interp); - Tcl_ListObjAppendElement(interp, result, - Tcl_NewStringObj(z->zipfile->name, -1)); - Tcl_ListObjAppendElement(interp, result, Tcl_NewWideIntObj(z->nbyte)); - Tcl_ListObjAppendElement(interp, result, Tcl_NewWideIntObj(z->nbytecompr)); - Tcl_ListObjAppendElement(interp, result, Tcl_NewWideIntObj(z->offset)); + Tcl_ListObjAppendElement(interp, result, + Tcl_NewStringObj(z->zipfile->name, -1)); + Tcl_ListObjAppendElement(interp, result, Tcl_NewWideIntObj(z->nbyte)); + Tcl_ListObjAppendElement(interp, result, + Tcl_NewWideIntObj(z->nbytecompr)); + Tcl_ListObjAppendElement(interp, result, Tcl_NewWideIntObj(z->offset)); } Unlock(); return TCL_OK; @@ -2785,23 +2881,26 @@ ZipFSInfoObjCmd( * * ZipFSListObjCmd -- * - * This procedure is invoked to process the "zipfs::list" command. - * On success, it returns a Tcl list of files of the ZIP filesystem - * which match a search pattern (glob or regexp). + * This procedure is invoked to process the "zipfs::list" command. On + * success, it returns a Tcl list of files of the ZIP filesystem which + * match a search pattern (glob or regexp). * * Results: - * A standard Tcl result. + * A standard Tcl result. * * Side effects: - * None. + * None. * *------------------------------------------------------------------------- */ static int ZipFSListObjCmd( - ClientData clientData, Tcl_Interp *interp,int objc, Tcl_Obj *const objv[] -) { + ClientData clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *const objv[]) +{ char *pattern = NULL; Tcl_RegExp regexp = NULL; Tcl_HashEntry *hPtr; @@ -2809,68 +2908,64 @@ ZipFSListObjCmd( Tcl_Obj *result = Tcl_GetObjResult(interp); if (objc > 3) { - Tcl_WrongNumArgs(interp, 1, objv, "?(-glob|-regexp)? ?pattern?"); - return TCL_ERROR; + Tcl_WrongNumArgs(interp, 1, objv, "?(-glob|-regexp)? ?pattern?"); + return TCL_ERROR; } if (objc == 3) { - int n; - char *what = Tcl_GetStringFromObj(objv[1], &n); - - if ((n >= 2) && (strncmp(what, "-glob", n) == 0)) { - pattern = Tcl_GetString(objv[2]); - } else if ((n >= 2) && (strncmp(what, "-regexp", n) == 0)) { - regexp = Tcl_RegExpCompile(interp, Tcl_GetString(objv[2])); - if (regexp == NULL) { - return TCL_ERROR; - } - } else { - Tcl_AppendResult(interp, "unknown option \"", what,"\"", (char *) NULL); - return TCL_ERROR; - } + int n; + char *what = Tcl_GetStringFromObj(objv[1], &n); + + if ((n >= 2) && (strncmp(what, "-glob", n) == 0)) { + pattern = Tcl_GetString(objv[2]); + } else if ((n >= 2) && (strncmp(what, "-regexp", n) == 0)) { + regexp = Tcl_RegExpCompile(interp, Tcl_GetString(objv[2])); + if (regexp == NULL) { + return TCL_ERROR; + } + } else { + Tcl_AppendResult(interp, "unknown option \"", what, "\"", + (char *) NULL); + return TCL_ERROR; + } } else if (objc == 2) { - pattern = Tcl_GetStringFromObj(objv[1], 0); + pattern = Tcl_GetStringFromObj(objv[1], 0); } ReadLock(); if (pattern != NULL) { - for ( - hPtr = Tcl_FirstHashEntry(&ZipFS.fileHash, &search); - hPtr != NULL; - hPtr = Tcl_NextHashEntry(&search) - ) { - ZipEntry *z = (ZipEntry *) Tcl_GetHashValue(hPtr); - - if (Tcl_StringMatch(z->name, pattern)) { - Tcl_ListObjAppendElement(interp, result,Tcl_NewStringObj(z->name, -1)); - } - } + for (hPtr = Tcl_FirstHashEntry(&ZipFS.fileHash, &search); + hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) { + ZipEntry *z = Tcl_GetHashValue(hPtr); + + if (Tcl_StringMatch(z->name, pattern)) { + Tcl_ListObjAppendElement(interp, result, + Tcl_NewStringObj(z->name, -1)); + } + } } else if (regexp != NULL) { - for ( - hPtr = Tcl_FirstHashEntry(&ZipFS.fileHash, &search); - hPtr != NULL; - hPtr = Tcl_NextHashEntry(&search) - ) { - ZipEntry *z = (ZipEntry *) Tcl_GetHashValue(hPtr); - if (Tcl_RegExpExec(interp, regexp, z->name, z->name)) { - Tcl_ListObjAppendElement(interp, result,Tcl_NewStringObj(z->name, -1)); - } - } + for (hPtr = Tcl_FirstHashEntry(&ZipFS.fileHash, &search); + hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) { + ZipEntry *z = Tcl_GetHashValue(hPtr); + + if (Tcl_RegExpExec(interp, regexp, z->name, z->name)) { + Tcl_ListObjAppendElement(interp, result, + Tcl_NewStringObj(z->name, -1)); + } + } } else { - for ( - hPtr = Tcl_FirstHashEntry(&ZipFS.fileHash, &search); - hPtr != NULL; - hPtr = Tcl_NextHashEntry(&search) - ) { - ZipEntry *z = (ZipEntry *) Tcl_GetHashValue(hPtr); + for (hPtr = Tcl_FirstHashEntry(&ZipFS.fileHash, &search); + hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) { + ZipEntry *z = Tcl_GetHashValue(hPtr); - Tcl_ListObjAppendElement(interp, result, Tcl_NewStringObj(z->name, -1)); - } + Tcl_ListObjAppendElement(interp, result, + Tcl_NewStringObj(z->name, -1)); + } } Unlock(); return TCL_OK; } - + #ifdef _WIN32 -#define LIBRARY_SIZE 64 +#define LIBRARY_SIZE 64 static int ToUtf( const WCHAR *wSrc, @@ -2880,82 +2975,97 @@ ToUtf( start = dst; while (*wSrc != '\0') { - dst += Tcl_UniCharToUtf(*wSrc, dst); - wSrc++; + dst += Tcl_UniCharToUtf(*wSrc, dst); + wSrc++; } *dst = '\0'; return (int) (dst - start); } #endif -Tcl_Obj *TclZipfs_TclLibrary(void) { - if(zipfs_literal_tcl_library) { - return Tcl_NewStringObj(zipfs_literal_tcl_library,-1); +Tcl_Obj * +TclZipfs_TclLibrary(void) +{ + if (zipfs_literal_tcl_library) { + return Tcl_NewStringObj(zipfs_literal_tcl_library, -1); } else { - Tcl_Obj *vfsinitscript; - int found=0; + Tcl_Obj *vfsinitscript; + int found = 0; #ifdef _WIN32 - HMODULE hModule = TclWinGetTclInstance(); - WCHAR wName[MAX_PATH + LIBRARY_SIZE]; - char dllname[(MAX_PATH + LIBRARY_SIZE) * TCL_UTF_MAX]; -#endif - /* Look for the library file system within the executable */ - vfsinitscript=Tcl_NewStringObj(ZIPFS_APP_MOUNT "/tcl_library/init.tcl",-1); - Tcl_IncrRefCount(vfsinitscript); - found=Tcl_FSAccess(vfsinitscript,F_OK); - Tcl_DecrRefCount(vfsinitscript); - if(found==TCL_OK) { - zipfs_literal_tcl_library=ZIPFS_APP_MOUNT "/tcl_library"; - return Tcl_NewStringObj(zipfs_literal_tcl_library,-1); - } + HMODULE hModule = TclWinGetTclInstance(); + WCHAR wName[MAX_PATH + LIBRARY_SIZE]; + char dllname[(MAX_PATH + LIBRARY_SIZE) * TCL_UTF_MAX]; +#endif /* _WIN32 */ + /* + * Look for the library file system within the executable. + */ + + vfsinitscript = Tcl_NewStringObj( + ZIPFS_APP_MOUNT "/tcl_library/init.tcl", -1); + Tcl_IncrRefCount(vfsinitscript); + found = Tcl_FSAccess(vfsinitscript, F_OK); + Tcl_DecrRefCount(vfsinitscript); + if (found == TCL_OK) { + zipfs_literal_tcl_library = ZIPFS_APP_MOUNT "/tcl_library"; + return Tcl_NewStringObj(zipfs_literal_tcl_library, -1); + } + #ifdef _WIN32 - if (GetModuleFileNameW(hModule, wName, MAX_PATH) == 0) { - GetModuleFileNameA(hModule, dllname, MAX_PATH); - } else { - ToUtf(wName, dllname); - } - /* Mount zip file and dll before releasing to search */ - if(TclZipfs_AppHook_FindTclInit(dllname)==TCL_OK) { - return Tcl_NewStringObj(zipfs_literal_tcl_library,-1); - } -#else + if (GetModuleFileNameW(hModule, wName, MAX_PATH) == 0) { + GetModuleFileNameA(hModule, dllname, MAX_PATH); + } else { + ToUtf(wName, dllname); + } + + /* + * Mount zip file and dll before releasing to search. + */ + + if (TclZipfs_AppHook_FindTclInit(dllname) == TCL_OK) { + return Tcl_NewStringObj(zipfs_literal_tcl_library, -1); + } +#else /* !_WIN32 */ #ifdef CFG_RUNTIME_DLLFILE - /* Mount zip file and dll before releasing to search */ - if(TclZipfs_AppHook_FindTclInit(CFG_RUNTIME_LIBDIR "/" CFG_RUNTIME_DLLFILE)==TCL_OK) { - return Tcl_NewStringObj(zipfs_literal_tcl_library,-1); - } -#endif -#endif -#ifdef CFG_RUNTIME_ZIPFILE - if(TclZipfs_AppHook_FindTclInit(CFG_RUNTIME_LIBDIR "/" CFG_RUNTIME_ZIPFILE)==TCL_OK) { - return Tcl_NewStringObj(zipfs_literal_tcl_library,-1); - } - if(TclZipfs_AppHook_FindTclInit(CFG_RUNTIME_SCRDIR "/" CFG_RUNTIME_ZIPFILE)==TCL_OK) { - return Tcl_NewStringObj(zipfs_literal_tcl_library,-1); - } - if(TclZipfs_AppHook_FindTclInit(CFG_RUNTIME_ZIPFILE)==TCL_OK) { - return Tcl_NewStringObj(zipfs_literal_tcl_library,-1); - } -#else + /* + * Mount zip file and dll before releasing to search. + */ + if (TclZipfs_AppHook_FindTclInit( + CFG_RUNTIME_LIBDIR "/" CFG_RUNTIME_DLLFILE) == TCL_OK) { + return Tcl_NewStringObj(zipfs_literal_tcl_library, -1); + } +#endif /* CFG_RUNTIME_DLLFILE */ +#endif /* _WIN32 */ -#endif - } - if(zipfs_literal_tcl_library) { - return Tcl_NewStringObj(zipfs_literal_tcl_library,-1); +#ifdef CFG_RUNTIME_ZIPFILE + if (TclZipfs_AppHook_FindTclInit( + CFG_RUNTIME_LIBDIR "/" CFG_RUNTIME_ZIPFILE) == TCL_OK) { + return Tcl_NewStringObj(zipfs_literal_tcl_library, -1); + } + if (TclZipfs_AppHook_FindTclInit( + CFG_RUNTIME_SCRDIR "/" CFG_RUNTIME_ZIPFILE) == TCL_OK) { + return Tcl_NewStringObj(zipfs_literal_tcl_library, -1); + } + if (TclZipfs_AppHook_FindTclInit(CFG_RUNTIME_ZIPFILE) == TCL_OK) { + return Tcl_NewStringObj(zipfs_literal_tcl_library, -1); + } +#endif /* CFG_RUNTIME_ZIPFILE */ + } + if (zipfs_literal_tcl_library) { + return Tcl_NewStringObj(zipfs_literal_tcl_library, -1); } return NULL; } - + /* *------------------------------------------------------------------------- * * ZipFSTclLibraryObjCmd -- * - * This procedure is invoked to process the "zipfs::root" command. It - * returns the root that all zipfs file systems are mounted under. + * This procedure is invoked to process the "zipfs::root" command. It + * returns the root that all zipfs file systems are mounted under. * * Results: - * A standard Tcl result. + * A standard Tcl result. * * Side effects: * @@ -2963,16 +3073,18 @@ Tcl_Obj *TclZipfs_TclLibrary(void) { */ static int -ZipFSTclLibraryObjCmd(ClientData clientData, Tcl_Interp *interp, - int objc, Tcl_Obj *const objv[]) +ZipFSTclLibraryObjCmd( + ClientData clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *const objv[]) { - Tcl_Obj *pResult; + Tcl_Obj *pResult = TclZipfs_TclLibrary(); - pResult=TclZipfs_TclLibrary(); - if(!pResult) { - pResult=Tcl_NewObj(); + if (!pResult) { + pResult = Tcl_NewObj(); } - Tcl_SetObjResult(interp,pResult); + Tcl_SetObjResult(interp, pResult); return TCL_OK; } @@ -2981,50 +3093,53 @@ ZipFSTclLibraryObjCmd(ClientData clientData, Tcl_Interp *interp, * * ZipChannelClose -- * - * This function is called to close a channel. + * This function is called to close a channel. * * Results: - * Always TCL_OK. + * Always TCL_OK. * * Side effects: - * Resources are free'd. + * Resources are free'd. * *------------------------------------------------------------------------- */ static int -ZipChannelClose(ClientData instanceData, Tcl_Interp *interp) +ZipChannelClose( + ClientData instanceData, + Tcl_Interp *interp) { ZipChannel *info = (ZipChannel *) instanceData; if (info->iscompr && (info->ubuf != NULL)) { - Tcl_Free((char *) info->ubuf); - info->ubuf = NULL; + Tcl_Free((char *) info->ubuf); + info->ubuf = NULL; } if (info->isenc) { - info->isenc = 0; - memset(info->keys, 0, sizeof (info->keys)); + info->isenc = 0; + memset(info->keys, 0, sizeof (info->keys)); } if (info->iswr) { - ZipEntry *z = info->zipentry; - unsigned char *newdata; - - newdata = (unsigned char *) Tcl_AttemptRealloc((char *) info->ubuf, info->nread); - if (newdata != NULL) { - if (z->data != NULL) { - Tcl_Free((char *) z->data); - } - z->data = newdata; - z->nbyte = z->nbytecompr = info->nbyte; - z->cmeth = ZIP_COMPMETH_STORED; - z->timestamp = time(NULL); - z->isdir = 0; - z->isenc = 0; - z->offset = 0; - z->crc32 = 0; - } else { - Tcl_Free((char *) info->ubuf); - } + ZipEntry *z = info->zipentry; + unsigned char *newdata; + + newdata = (unsigned char *) + Tcl_AttemptRealloc((char *) info->ubuf, info->nread); + if (newdata != NULL) { + if (z->data != NULL) { + Tcl_Free((char *) z->data); + } + z->data = newdata; + z->nbyte = z->nbytecompr = info->nbyte; + z->cmeth = ZIP_COMPMETH_STORED; + z->timestamp = time(NULL); + z->isdir = 0; + z->isenc = 0; + z->offset = 0; + z->crc32 = 0; + } else { + Tcl_Free((char *) info->ubuf); + } } WriteLock(); info->zipfile->nopen--; @@ -3038,62 +3153,66 @@ ZipChannelClose(ClientData instanceData, Tcl_Interp *interp) * * ZipChannelRead -- * - * This function is called to read data from channel. + * This function is called to read data from channel. * * Results: - * Number of bytes read or -1 on error with error number set. + * Number of bytes read or -1 on error with error number set. * * Side effects: - * Data is read and file pointer is advanced. + * Data is read and file pointer is advanced. * *------------------------------------------------------------------------- */ static int -ZipChannelRead(ClientData instanceData, char *buf, int toRead, int *errloc) +ZipChannelRead( + ClientData instanceData, + char *buf, + int toRead, + int *errloc) { ZipChannel *info = (ZipChannel *) instanceData; unsigned long nextpos; if (info->isdir < 0) { - /* - * Special case: when executable combined with ZIP archive file - * read data in front of ZIP, i.e. the executable itself. - */ - nextpos = info->nread + toRead; - if (nextpos > info->zipfile->baseoffs) { - toRead = info->zipfile->baseoffs - info->nread; - nextpos = info->zipfile->baseoffs; - } - if (toRead == 0) { - return 0; - } - memcpy(buf, info->zipfile->data, toRead); - info->nread = nextpos; - *errloc = 0; - return toRead; + /* + * Special case: when executable combined with ZIP archive file read + * data in front of ZIP, i.e. the executable itself. + */ + nextpos = info->nread + toRead; + if (nextpos > info->zipfile->baseoffs) { + toRead = info->zipfile->baseoffs - info->nread; + nextpos = info->zipfile->baseoffs; + } + if (toRead == 0) { + return 0; + } + memcpy(buf, info->zipfile->data, toRead); + info->nread = nextpos; + *errloc = 0; + return toRead; } if (info->isdir) { - *errloc = EISDIR; - return -1; + *errloc = EISDIR; + return -1; } nextpos = info->nread + toRead; if (nextpos > info->nbyte) { - toRead = info->nbyte - info->nread; - nextpos = info->nbyte; + toRead = info->nbyte - info->nread; + nextpos = info->nbyte; } if (toRead == 0) { - return 0; + return 0; } if (info->isenc) { - int i, ch; + int i, ch; - for (i = 0; i < toRead; i++) { - ch = info->ubuf[i + info->nread]; - buf[i] = zdecode(info->keys, crc32tab, ch); - } + for (i = 0; i < toRead; i++) { + ch = info->ubuf[i + info->nread]; + buf[i] = zdecode(info->keys, crc32tab, ch); + } } else { - memcpy(buf, info->ubuf + info->nread, toRead); + memcpy(buf, info->ubuf + info->nread, toRead); } info->nread = nextpos; *errloc = 0; @@ -3105,40 +3224,43 @@ ZipChannelRead(ClientData instanceData, char *buf, int toRead, int *errloc) * * ZipChannelWrite -- * - * This function is called to write data into channel. + * This function is called to write data into channel. * * Results: - * Number of bytes written or -1 on error with error number set. + * Number of bytes written or -1 on error with error number set. * * Side effects: - * Data is written and file pointer is advanced. + * Data is written and file pointer is advanced. * *------------------------------------------------------------------------- */ static int -ZipChannelWrite(ClientData instanceData, const char *buf, - int toWrite, int *errloc) +ZipChannelWrite( + ClientData instanceData, + const char *buf, + int toWrite, + int *errloc) { ZipChannel *info = (ZipChannel *) instanceData; unsigned long nextpos; if (!info->iswr) { - *errloc = EINVAL; - return -1; + *errloc = EINVAL; + return -1; } nextpos = info->nread + toWrite; if (nextpos > info->nmax) { - toWrite = info->nmax - info->nread; - nextpos = info->nmax; + toWrite = info->nmax - info->nread; + nextpos = info->nmax; } if (toWrite == 0) { - return 0; + return 0; } memcpy(info->ubuf + info->nread, buf, toWrite); info->nread = nextpos; if (info->nread > info->nbyte) { - info->nbyte = info->nread; + info->nbyte = info->nread; } *errloc = 0; return toWrite; @@ -3149,63 +3271,67 @@ ZipChannelWrite(ClientData instanceData, const char *buf, * * ZipChannelSeek -- * - * This function is called to position file pointer of channel. + * This function is called to position file pointer of channel. * * Results: - * New file position or -1 on error with error number set. + * New file position or -1 on error with error number set. * * Side effects: - * File pointer is repositioned according to offset and mode. + * File pointer is repositioned according to offset and mode. * *------------------------------------------------------------------------- */ static int -ZipChannelSeek(ClientData instanceData, long offset, int mode, int *errloc) +ZipChannelSeek( + ClientData instanceData, + long offset, + int mode, + int *errloc) { ZipChannel *info = (ZipChannel *) instanceData; unsigned long end; if (!info->iswr && (info->isdir < 0)) { - /* - * Special case: when executable combined with ZIP archive file, - * seek within front of ZIP, i.e. the executable itself. - */ - end = info->zipfile->baseoffs; + /* + * Special case: when executable combined with ZIP archive file, seek + * within front of ZIP, i.e. the executable itself. + */ + end = info->zipfile->baseoffs; } else if (info->isdir) { - *errloc = EINVAL; - return -1; + *errloc = EINVAL; + return -1; } else { - end = info->nbyte; + end = info->nbyte; } switch (mode) { case SEEK_CUR: - offset += info->nread; - break; + offset += info->nread; + break; case SEEK_END: - offset += end; - break; + offset += end; + break; case SEEK_SET: - break; + break; default: - *errloc = EINVAL; - return -1; + *errloc = EINVAL; + return -1; } if (offset < 0) { - *errloc = EINVAL; - return -1; + *errloc = EINVAL; + return -1; } if (info->iswr) { - if ((unsigned long) offset > info->nmax) { - *errloc = EINVAL; - return -1; - } - if ((unsigned long) offset > info->nbyte) { - info->nbyte = offset; - } + if ((unsigned long) offset > info->nmax) { + *errloc = EINVAL; + return -1; + } + if ((unsigned long) offset > info->nbyte) { + info->nbyte = offset; + } } else if ((unsigned long) offset > end) { - *errloc = EINVAL; - return -1; + *errloc = EINVAL; + return -1; } info->nread = (unsigned long) offset; return info->nread; @@ -3216,19 +3342,22 @@ ZipChannelSeek(ClientData instanceData, long offset, int mode, int *errloc) * * ZipChannelWatchChannel -- * - * This function is called for event notifications on channel. + * This function is called for event notifications on channel. Does + * nothing. * * Results: - * None. + * None. * * Side effects: - * None. + * None. * *------------------------------------------------------------------------- */ static void -ZipChannelWatchChannel(ClientData instanceData, int mask) +ZipChannelWatchChannel( + ClientData instanceData, + int mask) { return; } @@ -3238,57 +3367,59 @@ ZipChannelWatchChannel(ClientData instanceData, int mask) * * ZipChannelGetFile -- * - * This function is called to retrieve OS handle for channel. + * This function is called to retrieve OS handle for channel. * * Results: - * Always TCL_ERROR since there's never an OS handle for a - * file within a ZIP archive. + * Always TCL_ERROR since there's never an OS handle for a file within a + * ZIP archive. * * Side effects: - * None. + * None. * *------------------------------------------------------------------------- */ static int ZipChannelGetFile( - ClientData instanceData, int direction,ClientData *handlePtr -) { + ClientData instanceData, + int direction, + ClientData *handlePtr) +{ return TCL_ERROR; } - + /* * The channel type/driver definition used for ZIP archive members. */ static Tcl_ChannelType ZipChannelType = { - "zip", /* Type name. */ + "zip", /* Type name. */ #ifdef TCL_CHANNEL_VERSION_4 TCL_CHANNEL_VERSION_4, - ZipChannelClose, /* Close channel, clean instance data */ - ZipChannelRead, /* Handle read request */ - ZipChannelWrite, /* Handle write request */ - ZipChannelSeek, /* Move location of access point, NULL'able */ - NULL, /* Set options, NULL'able */ - NULL, /* Get options, NULL'able */ + ZipChannelClose, /* Close channel, clean instance data */ + ZipChannelRead, /* Handle read request */ + ZipChannelWrite, /* Handle write request */ + ZipChannelSeek, /* Move location of access point, NULL'able */ + NULL, /* Set options, NULL'able */ + NULL, /* Get options, NULL'able */ ZipChannelWatchChannel, /* Initialize notifier */ - ZipChannelGetFile, /* Get OS handle from the channel */ - NULL, /* 2nd version of close channel, NULL'able */ - NULL, /* Set blocking mode for raw channel, NULL'able */ - NULL, /* Function to flush channel, NULL'able */ - NULL, /* Function to handle event, NULL'able */ - NULL, /* Wide seek function, NULL'able */ - NULL, /* Thread action function, NULL'able */ + ZipChannelGetFile, /* Get OS handle from the channel */ + NULL, /* 2nd version of close channel, NULL'able */ + NULL, /* Set blocking mode for raw channel, NULL'able */ + NULL, /* Function to flush channel, NULL'able */ + NULL, /* Function to handle event, NULL'able */ + NULL, /* Wide seek function, NULL'able */ + NULL, /* Thread action function, NULL'able */ #else - NULL, /* Set blocking/nonblocking behaviour, NULL'able */ - ZipChannelClose, /* Close channel, clean instance data */ - ZipChannelRead, /* Handle read request */ - ZipChannelWrite, /* Handle write request */ - ZipChannelSeek, /* Move location of access point, NULL'able */ - NULL, /* Set options, NULL'able */ - NULL, /* Get options, NULL'able */ + NULL, /* Set blocking/nonblocking behaviour, NULL'able */ + ZipChannelClose, /* Close channel, clean instance data */ + ZipChannelRead, /* Handle read request */ + ZipChannelWrite, /* Handle write request */ + ZipChannelSeek, /* Move location of access point, NULL'able */ + NULL, /* Set options, NULL'able */ + NULL, /* Get options, NULL'able */ ZipChannelWatchChannel, /* Initialize notifier */ - ZipChannelGetFile, /* Get OS handle from the channel */ + ZipChannelGetFile, /* Get OS handle from the channel */ #endif }; @@ -3310,283 +3441,291 @@ static Tcl_ChannelType ZipChannelType = { */ static Tcl_Channel -ZipChannelOpen(Tcl_Interp *interp, char *filename, int mode, int permissions) +ZipChannelOpen( + Tcl_Interp *interp, + char *filename, + int mode, + int permissions) { ZipEntry *z; ZipChannel *info; int i, ch, trunc, wr, flags = 0; char cname[128]; - if ( - (mode & O_APPEND) - || ((ZipFS.wrmax <= 0) && (mode & (O_WRONLY | O_RDWR))) - ) { - if (interp != NULL) { - Tcl_SetObjResult(interp, Tcl_NewStringObj("unsupported open mode", -1)); - } - return NULL; + if ((mode & O_APPEND) + || ((ZipFS.wrmax <= 0) && (mode & (O_WRONLY | O_RDWR)))) { + if (interp != NULL) { + Tcl_SetObjResult(interp, + Tcl_NewStringObj("unsupported open mode", -1)); + } + return NULL; } WriteLock(); z = ZipFSLookup(filename); if (z == NULL) { - if (interp != NULL) { - Tcl_SetObjResult(interp, Tcl_NewStringObj("file not found", -1)); - Tcl_AppendResult(interp, " \"", filename, "\"", NULL); - } - goto error; + if (interp != NULL) { + Tcl_SetObjResult(interp, Tcl_NewStringObj("file not found", -1)); + Tcl_AppendResult(interp, " \"", filename, "\"", NULL); + } + goto error; } trunc = (mode & O_TRUNC) != 0; wr = (mode & (O_WRONLY | O_RDWR)) != 0; - if ((z->cmeth != ZIP_COMPMETH_STORED) && (z->cmeth != ZIP_COMPMETH_DEFLATED)) { - ZIPFS_ERROR(interp,"unsupported compression method"); - goto error; + if ((z->cmeth != ZIP_COMPMETH_STORED) + && (z->cmeth != ZIP_COMPMETH_DEFLATED)) { + ZIPFS_ERROR(interp, "unsupported compression method"); + goto error; } if (wr && z->isdir) { - ZIPFS_ERROR(interp,"unsupported file type"); - goto error; + ZIPFS_ERROR(interp, "unsupported file type"); + goto error; } if (!trunc) { - flags |= TCL_READABLE; - if (z->isenc && (z->zipfile->pwbuf[0] == 0)) { - ZIPFS_ERROR(interp,"decryption failed"); - goto error; - } else if (wr && (z->data == NULL) && (z->nbyte > ZipFS.wrmax)) { - ZIPFS_ERROR(interp,"file too large"); - goto error; - } + flags |= TCL_READABLE; + if (z->isenc && (z->zipfile->pwbuf[0] == 0)) { + ZIPFS_ERROR(interp, "decryption failed"); + goto error; + } else if (wr && (z->data == NULL) && (z->nbyte > ZipFS.wrmax)) { + ZIPFS_ERROR(interp, "file too large"); + goto error; + } } else { - flags = TCL_WRITABLE; + flags = TCL_WRITABLE; } info = (ZipChannel *) Tcl_AttemptAlloc(sizeof (*info)); if (info == NULL) { - ZIPFS_ERROR(interp,"out of memory"); - goto error; + ZIPFS_ERROR(interp, "out of memory"); + goto error; } info->zipfile = z->zipfile; info->zipentry = z; info->nread = 0; if (wr) { - flags |= TCL_WRITABLE; - info->iswr = 1; - info->isdir = 0; - info->nmax = ZipFS.wrmax; - info->iscompr = 0; - info->isenc = 0; - info->ubuf = (unsigned char *) Tcl_AttemptAlloc(info->nmax); - if (info->ubuf == NULL) { -merror0: - if (info->ubuf != NULL) { - Tcl_Free((char *) info->ubuf); - } - Tcl_Free((char *) info); - ZIPFS_ERROR(interp,"out of memory"); - goto error; - } - memset(info->ubuf, 0, info->nmax); - if (trunc) { - info->nbyte = 0; - } else { - if (z->data != NULL) { - unsigned int j = z->nbyte; - - if (j > info->nmax) { - j = info->nmax; - } - memcpy(info->ubuf, z->data, j); - info->nbyte = j; - } else { - unsigned char *zbuf = z->zipfile->data + z->offset; - - if (z->isenc) { - int len = z->zipfile->pwbuf[0]; - char pwbuf[260]; - - for (i = 0; i < len; i++) { - ch = z->zipfile->pwbuf[len - i]; - pwbuf[i] = (ch & 0x0f) | pwrot[(ch >> 4) & 0x0f]; - } - pwbuf[i] = '\0'; - init_keys(pwbuf, info->keys, crc32tab); - memset(pwbuf, 0, sizeof (pwbuf)); - for (i = 0; i < 12; i++) { - ch = info->ubuf[i]; - zdecode(info->keys, crc32tab, ch); - } - zbuf += i; - } - if (z->cmeth == ZIP_COMPMETH_DEFLATED) { - z_stream stream; - int err; - unsigned char *cbuf = NULL; - - memset(&stream, 0, sizeof (stream)); - stream.zalloc = Z_NULL; - stream.zfree = Z_NULL; - stream.opaque = Z_NULL; - stream.avail_in = z->nbytecompr; - if (z->isenc) { - unsigned int j; - - stream.avail_in -= 12; - cbuf = (unsigned char *) - Tcl_AttemptAlloc(stream.avail_in); - if (cbuf == NULL) { - goto merror0; - } - for (j = 0; j < stream.avail_in; j++) { - ch = info->ubuf[j]; - cbuf[j] = zdecode(info->keys, crc32tab, ch); - } - stream.next_in = cbuf; - } else { - stream.next_in = zbuf; - } - stream.next_out = info->ubuf; - stream.avail_out = info->nmax; - if (inflateInit2(&stream, -15) != Z_OK) goto cerror0; - err = inflate(&stream, Z_SYNC_FLUSH); - inflateEnd(&stream); - if ((err == Z_STREAM_END) || ((err == Z_OK) && (stream.avail_in == 0))) { - if (cbuf != NULL) { - memset(info->keys, 0, sizeof (info->keys)); - Tcl_Free((char *) cbuf); - } - goto wrapchan; - } -cerror0: - if (cbuf != NULL) { - memset(info->keys, 0, sizeof (info->keys)); - Tcl_Free((char *) cbuf); - } - if (info->ubuf != NULL) { - Tcl_Free((char *) info->ubuf); - } - Tcl_Free((char *) info); - ZIPFS_ERROR(interp,"decompression error"); - goto error; - } else if (z->isenc) { - for (i = 0; i < z->nbyte - 12; i++) { - ch = zbuf[i]; - info->ubuf[i] = zdecode(info->keys, crc32tab, ch); - } - } else { - memcpy(info->ubuf, zbuf, z->nbyte); - } - memset(info->keys, 0, sizeof (info->keys)); - goto wrapchan; - } - } + flags |= TCL_WRITABLE; + info->iswr = 1; + info->isdir = 0; + info->nmax = ZipFS.wrmax; + info->iscompr = 0; + info->isenc = 0; + info->ubuf = (unsigned char *) Tcl_AttemptAlloc(info->nmax); + if (info->ubuf == NULL) { + merror0: + if (info->ubuf != NULL) { + Tcl_Free((char *) info->ubuf); + } + Tcl_Free((char *) info); + ZIPFS_ERROR(interp, "out of memory"); + goto error; + } + memset(info->ubuf, 0, info->nmax); + if (trunc) { + info->nbyte = 0; + } else { + if (z->data != NULL) { + unsigned int j = z->nbyte; + + if (j > info->nmax) { + j = info->nmax; + } + memcpy(info->ubuf, z->data, j); + info->nbyte = j; + } else { + unsigned char *zbuf = z->zipfile->data + z->offset; + + if (z->isenc) { + int len = z->zipfile->pwbuf[0]; + char pwbuf[260]; + + for (i = 0; i < len; i++) { + ch = z->zipfile->pwbuf[len - i]; + pwbuf[i] = (ch & 0x0f) | pwrot[(ch >> 4) & 0x0f]; + } + pwbuf[i] = '\0'; + init_keys(pwbuf, info->keys, crc32tab); + memset(pwbuf, 0, sizeof (pwbuf)); + for (i = 0; i < 12; i++) { + ch = info->ubuf[i]; + zdecode(info->keys, crc32tab, ch); + } + zbuf += i; + } + if (z->cmeth == ZIP_COMPMETH_DEFLATED) { + z_stream stream; + int err; + unsigned char *cbuf = NULL; + + memset(&stream, 0, sizeof (stream)); + stream.zalloc = Z_NULL; + stream.zfree = Z_NULL; + stream.opaque = Z_NULL; + stream.avail_in = z->nbytecompr; + if (z->isenc) { + unsigned int j; + + stream.avail_in -= 12; + cbuf = (unsigned char *) + Tcl_AttemptAlloc(stream.avail_in); + if (cbuf == NULL) { + goto merror0; + } + for (j = 0; j < stream.avail_in; j++) { + ch = info->ubuf[j]; + cbuf[j] = zdecode(info->keys, crc32tab, ch); + } + stream.next_in = cbuf; + } else { + stream.next_in = zbuf; + } + stream.next_out = info->ubuf; + stream.avail_out = info->nmax; + if (inflateInit2(&stream, -15) != Z_OK) goto cerror0; + err = inflate(&stream, Z_SYNC_FLUSH); + inflateEnd(&stream); + if ((err == Z_STREAM_END) + || ((err == Z_OK) && (stream.avail_in == 0))) { + if (cbuf != NULL) { + memset(info->keys, 0, sizeof (info->keys)); + Tcl_Free((char *) cbuf); + } + goto wrapchan; + } + cerror0: + if (cbuf != NULL) { + memset(info->keys, 0, sizeof (info->keys)); + Tcl_Free((char *) cbuf); + } + if (info->ubuf != NULL) { + Tcl_Free((char *) info->ubuf); + } + Tcl_Free((char *) info); + ZIPFS_ERROR(interp, "decompression error"); + goto error; + } else if (z->isenc) { + for (i = 0; i < z->nbyte - 12; i++) { + ch = zbuf[i]; + info->ubuf[i] = zdecode(info->keys, crc32tab, ch); + } + } else { + memcpy(info->ubuf, zbuf, z->nbyte); + } + memset(info->keys, 0, sizeof (info->keys)); + goto wrapchan; + } + } } else if (z->data != NULL) { - flags |= TCL_READABLE; - info->iswr = 0; - info->iscompr = 0; - info->isdir = 0; - info->isenc = 0; - info->nbyte = z->nbyte; - info->nmax = 0; - info->ubuf = z->data; + flags |= TCL_READABLE; + info->iswr = 0; + info->iscompr = 0; + info->isdir = 0; + info->isenc = 0; + info->nbyte = z->nbyte; + info->nmax = 0; + info->ubuf = z->data; } else { - flags |= TCL_READABLE; - info->iswr = 0; - info->iscompr = z->cmeth == ZIP_COMPMETH_DEFLATED; - info->ubuf = z->zipfile->data + z->offset; - info->isdir = z->isdir; - info->isenc = z->isenc; - info->nbyte = z->nbyte; - info->nmax = 0; - if (info->isenc) { - int len = z->zipfile->pwbuf[0]; - char pwbuf[260]; - - for (i = 0; i < len; i++) { - ch = z->zipfile->pwbuf[len - i]; - pwbuf[i] = (ch & 0x0f) | pwrot[(ch >> 4) & 0x0f]; - } - pwbuf[i] = '\0'; - init_keys(pwbuf, info->keys, crc32tab); - memset(pwbuf, 0, sizeof (pwbuf)); - for (i = 0; i < 12; i++) { - ch = info->ubuf[i]; - zdecode(info->keys, crc32tab, ch); - } - info->ubuf += i; - } - if (info->iscompr) { - z_stream stream; - int err; - unsigned char *ubuf = NULL; - unsigned int j; - - memset(&stream, 0, sizeof (stream)); - stream.zalloc = Z_NULL; - stream.zfree = Z_NULL; - stream.opaque = Z_NULL; - stream.avail_in = z->nbytecompr; - if (info->isenc) { - stream.avail_in -= 12; - ubuf = (unsigned char *) Tcl_AttemptAlloc(stream.avail_in); - if (ubuf == NULL) { - info->ubuf = NULL; - goto merror; - } - for (j = 0; j < stream.avail_in; j++) { - ch = info->ubuf[j]; - ubuf[j] = zdecode(info->keys, crc32tab, ch); - } - stream.next_in = ubuf; - } else { - stream.next_in = info->ubuf; - } - stream.next_out = info->ubuf = (unsigned char *) Tcl_AttemptAlloc(info->nbyte); - if (info->ubuf == NULL) { -merror: - if (ubuf != NULL) { - info->isenc = 0; - memset(info->keys, 0, sizeof (info->keys)); - Tcl_Free((char *) ubuf); - } - Tcl_Free((char *) info); - if (interp != NULL) { - Tcl_SetObjResult(interp, - Tcl_NewStringObj("out of memory", -1)); - } - goto error; - } - stream.avail_out = info->nbyte; - if (inflateInit2(&stream, -15) != Z_OK) { - goto cerror; - } - err = inflate(&stream, Z_SYNC_FLUSH); - inflateEnd(&stream); - if ((err == Z_STREAM_END) || ((err == Z_OK) && (stream.avail_in == 0))) { - if (ubuf != NULL) { - info->isenc = 0; - memset(info->keys, 0, sizeof (info->keys)); - Tcl_Free((char *) ubuf); - } - goto wrapchan; - } -cerror: - if (ubuf != NULL) { - info->isenc = 0; - memset(info->keys, 0, sizeof (info->keys)); - Tcl_Free((char *) ubuf); - } - if (info->ubuf != NULL) { - Tcl_Free((char *) info->ubuf); - } - Tcl_Free((char *) info); - ZIPFS_ERROR(interp,"decompression error"); - goto error; - } - } -wrapchan: - sprintf(cname, "zipfs_%" TCL_LL_MODIFIER "x_%d", z->offset, ZipFS.idCount++); + flags |= TCL_READABLE; + info->iswr = 0; + info->iscompr = z->cmeth == ZIP_COMPMETH_DEFLATED; + info->ubuf = z->zipfile->data + z->offset; + info->isdir = z->isdir; + info->isenc = z->isenc; + info->nbyte = z->nbyte; + info->nmax = 0; + if (info->isenc) { + int len = z->zipfile->pwbuf[0]; + char pwbuf[260]; + + for (i = 0; i < len; i++) { + ch = z->zipfile->pwbuf[len - i]; + pwbuf[i] = (ch & 0x0f) | pwrot[(ch >> 4) & 0x0f]; + } + pwbuf[i] = '\0'; + init_keys(pwbuf, info->keys, crc32tab); + memset(pwbuf, 0, sizeof (pwbuf)); + for (i = 0; i < 12; i++) { + ch = info->ubuf[i]; + zdecode(info->keys, crc32tab, ch); + } + info->ubuf += i; + } + if (info->iscompr) { + z_stream stream; + int err; + unsigned char *ubuf = NULL; + unsigned int j; + + memset(&stream, 0, sizeof (stream)); + stream.zalloc = Z_NULL; + stream.zfree = Z_NULL; + stream.opaque = Z_NULL; + stream.avail_in = z->nbytecompr; + if (info->isenc) { + stream.avail_in -= 12; + ubuf = (unsigned char *) Tcl_AttemptAlloc(stream.avail_in); + if (ubuf == NULL) { + info->ubuf = NULL; + goto merror; + } + for (j = 0; j < stream.avail_in; j++) { + ch = info->ubuf[j]; + ubuf[j] = zdecode(info->keys, crc32tab, ch); + } + stream.next_in = ubuf; + } else { + stream.next_in = info->ubuf; + } + stream.next_out = info->ubuf = (unsigned char *) + Tcl_AttemptAlloc(info->nbyte); + if (info->ubuf == NULL) { + merror: + if (ubuf != NULL) { + info->isenc = 0; + memset(info->keys, 0, sizeof (info->keys)); + Tcl_Free((char *) ubuf); + } + Tcl_Free((char *) info); + if (interp != NULL) { + Tcl_SetObjResult(interp, + Tcl_NewStringObj("out of memory", -1)); + } + goto error; + } + stream.avail_out = info->nbyte; + if (inflateInit2(&stream, -15) != Z_OK) { + goto cerror; + } + err = inflate(&stream, Z_SYNC_FLUSH); + inflateEnd(&stream); + if ((err == Z_STREAM_END) + || ((err == Z_OK) && (stream.avail_in == 0))) { + if (ubuf != NULL) { + info->isenc = 0; + memset(info->keys, 0, sizeof (info->keys)); + Tcl_Free((char *) ubuf); + } + goto wrapchan; + } + cerror: + if (ubuf != NULL) { + info->isenc = 0; + memset(info->keys, 0, sizeof(info->keys)); + Tcl_Free((char *) ubuf); + } + if (info->ubuf != NULL) { + Tcl_Free((char *) info->ubuf); + } + Tcl_Free((char *) info); + ZIPFS_ERROR(interp, "decompression error"); + goto error; + } + } + wrapchan: + sprintf(cname, "zipfs_%" TCL_LL_MODIFIER "x_%d", z->offset, + ZipFS.idCount++); z->zipfile->nopen++; Unlock(); return Tcl_CreateChannel(&ZipChannelType, cname, (ClientData) info, flags); -error: + error: Unlock(); return NULL; } @@ -3596,40 +3735,41 @@ error: * * ZipEntryStat -- * - * This function implements the ZIP filesystem specific version - * of the library version of stat. + * This function implements the ZIP filesystem specific version of the + * library version of stat. * * Results: - * See stat documentation. + * See stat documentation. * * Side effects: - * See stat documentation. + * See stat documentation. * *------------------------------------------------------------------------- */ static int -ZipEntryStat(char *path, Tcl_StatBuf *buf) +ZipEntryStat( + char *path, + Tcl_StatBuf *buf) { ZipEntry *z; int ret = -1; ReadLock(); z = ZipFSLookup(path); - if (z == NULL) goto done; - - memset(buf, 0, sizeof (Tcl_StatBuf)); - if (z->isdir) { - buf->st_mode = S_IFDIR | 0555; - } else { - buf->st_mode = S_IFREG | 0555; - } - buf->st_size = z->nbyte; - buf->st_mtime = z->timestamp; - buf->st_ctime = z->timestamp; - buf->st_atime = z->timestamp; - ret = 0; -done: + if (z != NULL) { + memset(buf, 0, sizeof (Tcl_StatBuf)); + if (z->isdir) { + buf->st_mode = S_IFDIR | 0555; + } else { + buf->st_mode = S_IFREG | 0555; + } + buf->st_size = z->nbyte; + buf->st_mtime = z->timestamp; + buf->st_ctime = z->timestamp; + buf->st_atime = z->timestamp; + ret = 0; + } Unlock(); return ret; } @@ -3639,24 +3779,28 @@ done: * * ZipEntryAccess -- * - * This function implements the ZIP filesystem specific version - * of the library version of access. + * This function implements the ZIP filesystem specific version of the + * library version of access. * * Results: - * See access documentation. + * See access documentation. * * Side effects: - * See access documentation. + * See access documentation. * *------------------------------------------------------------------------- */ static int -ZipEntryAccess(char *path, int mode) +ZipEntryAccess( + char *path, + int mode) { ZipEntry *z; - if (mode & 3) return -1; + if (mode & 3) { + return -1; + } ReadLock(); z = ZipFSLookup(path); Unlock(); @@ -3676,12 +3820,20 @@ ZipEntryAccess(char *path, int mode) */ static Tcl_Channel -Zip_FSOpenFileChannelProc(Tcl_Interp *interp, Tcl_Obj *pathPtr, - int mode, int permissions) +Zip_FSOpenFileChannelProc( + Tcl_Interp *interp, + Tcl_Obj *pathPtr, + int mode, + int permissions) { int len; - if (!(pathPtr = Tcl_FSGetNormalizedPath(NULL, pathPtr))) return NULL; - return ZipChannelOpen(interp, Tcl_GetStringFromObj(pathPtr, &len), mode, permissions); + + pathPtr = Tcl_FSGetNormalizedPath(NULL, pathPtr); + if (!pathPtr) { + return NULL; + } + return ZipChannelOpen(interp, Tcl_GetStringFromObj(pathPtr, &len), mode, + permissions); } /* @@ -3689,23 +3841,29 @@ Zip_FSOpenFileChannelProc(Tcl_Interp *interp, Tcl_Obj *pathPtr, * * Zip_FSStatProc -- * - * This function implements the ZIP filesystem specific version - * of the library version of stat. + * This function implements the ZIP filesystem specific version of the + * library version of stat. * * Results: - * See stat documentation. + * See stat documentation. * * Side effects: - * See stat documentation. + * See stat documentation. * *------------------------------------------------------------------------- */ static int -Zip_FSStatProc(Tcl_Obj *pathPtr, Tcl_StatBuf *buf) +Zip_FSStatProc( + Tcl_Obj *pathPtr, + Tcl_StatBuf *buf) { int len; - if (!(pathPtr = Tcl_FSGetNormalizedPath(NULL, pathPtr))) return -1; + + pathPtr = Tcl_FSGetNormalizedPath(NULL, pathPtr); + if (!pathPtr) { + return -1; + } return ZipEntryStat(Tcl_GetStringFromObj(pathPtr, &len), buf); } @@ -3714,23 +3872,29 @@ Zip_FSStatProc(Tcl_Obj *pathPtr, Tcl_StatBuf *buf) * * Zip_FSAccessProc -- * - * This function implements the ZIP filesystem specific version - * of the library version of access. + * This function implements the ZIP filesystem specific version of the + * library version of access. * * Results: - * See access documentation. + * See access documentation. * * Side effects: - * See access documentation. + * See access documentation. * *------------------------------------------------------------------------- */ static int -Zip_FSAccessProc(Tcl_Obj *pathPtr, int mode) +Zip_FSAccessProc( + Tcl_Obj *pathPtr, + int mode) { int len; - if (!(pathPtr = Tcl_FSGetNormalizedPath(NULL, pathPtr))) return -1; + + pathPtr = Tcl_FSGetNormalizedPath(NULL, pathPtr); + if (!pathPtr) { + return -1; + } return ZipEntryAccess(Tcl_GetStringFromObj(pathPtr, &len), mode); } @@ -3739,22 +3903,23 @@ Zip_FSAccessProc(Tcl_Obj *pathPtr, int mode) * * Zip_FSFilesystemSeparatorProc -- * - * This function returns the separator to be used for a given path. The - * object returned should have a refCount of zero + * This function returns the separator to be used for a given path. The + * object returned should have a refCount of zero * * Results: - * A Tcl object, with a refCount of zero. If the caller needs to retain a - * reference to the object, it should call Tcl_IncrRefCount, and should - * otherwise free the object. + * A Tcl object, with a refCount of zero. If the caller needs to retain a + * reference to the object, it should call Tcl_IncrRefCount, and should + * otherwise free the object. * * Side effects: - * None. + * None. * *------------------------------------------------------------------------- */ static Tcl_Obj * -Zip_FSFilesystemSeparatorProc(Tcl_Obj *pathPtr) +Zip_FSFilesystemSeparatorProc( + Tcl_Obj *pathPtr) { return Tcl_NewStringObj("/", -1); } @@ -3764,23 +3929,26 @@ Zip_FSFilesystemSeparatorProc(Tcl_Obj *pathPtr) * * Zip_FSMatchInDirectoryProc -- * - * This routine is used by the globbing code to search a directory for - * all files which match a given pattern. + * This routine is used by the globbing code to search a directory for + * all files which match a given pattern. * * Results: - * The return value is a standard Tcl result indicating whether an - * error occurred in globbing. Errors are left in interp, good - * results are lappend'ed to resultPtr (which must be a valid object). + * The return value is a standard Tcl result indicating whether an error + * occurred in globbing. Errors are left in interp, good results are + * lappend'ed to resultPtr (which must be a valid object). * * Side effects: - * None. + * None. * *------------------------------------------------------------------------- */ static int -Zip_FSMatchInDirectoryProc(Tcl_Interp* interp, Tcl_Obj *result, - Tcl_Obj *pathPtr, const char *pattern, - Tcl_GlobTypeData *types) +Zip_FSMatchInDirectoryProc( + Tcl_Interp *interp, + Tcl_Obj *result, + Tcl_Obj *pathPtr, + const char *pattern, + Tcl_GlobTypeData *types) { Tcl_HashEntry *hPtr; Tcl_HashSearch search; @@ -3790,10 +3958,12 @@ Zip_FSMatchInDirectoryProc(Tcl_Interp* interp, Tcl_Obj *result, char *pat, *prefix, *path; Tcl_DString dsPref; - if (!(normPathPtr = Tcl_FSGetNormalizedPath(NULL, pathPtr))) return -1; + if (!(normPathPtr = Tcl_FSGetNormalizedPath(NULL, pathPtr))) { + return -1; + } if (types != NULL) { - dirOnly = (types->type & TCL_GLOB_TYPE_DIR) == TCL_GLOB_TYPE_DIR; + dirOnly = (types->type & TCL_GLOB_TYPE_DIR) == TCL_GLOB_TYPE_DIR; } /* the prefix that gets prepended to results */ @@ -3807,138 +3977,130 @@ Zip_FSMatchInDirectoryProc(Tcl_Interp* interp, Tcl_Obj *result, Tcl_DStringAppend(&dsPref, prefix, prefixLen); if (strcmp(prefix, path) == 0) { - prefix = NULL; + prefix = NULL; } else { - strip = len + 1; + strip = len + 1; } if (prefix != NULL) { - Tcl_DStringAppend(&dsPref, "/", 1); - prefixLen++; - prefix = Tcl_DStringValue(&dsPref); + Tcl_DStringAppend(&dsPref, "/", 1); + prefixLen++; + prefix = Tcl_DStringValue(&dsPref); } ReadLock(); if ((types != NULL) && (types->type == TCL_GLOB_TYPE_MOUNT)) { - l = CountSlashes(path); - if (path[len - 1] == '/') { - len--; - } else { - l++; - } - if ((pattern == NULL) || (pattern[0] == '\0')) { - pattern = "*"; - } - hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); - while (hPtr != NULL) { - ZipFile *zf = (ZipFile *) Tcl_GetHashValue(hPtr); - - if (zf->mntptlen == 0) { - ZipEntry *z = zf->topents; - while (z != NULL) { - size_t lenz = strlen(z->name); - if ( - (lenz > len + 1) - && (strncmp(z->name, path, len) == 0) - && (z->name[len] == '/') - && (CountSlashes(z->name) == l) - && Tcl_StringCaseMatch(z->name + len + 1, pattern, 0) - ) { - if (prefix != NULL) { - Tcl_DStringAppend(&dsPref, z->name, lenz); - Tcl_ListObjAppendElement( - NULL, result, - Tcl_NewStringObj(Tcl_DStringValue(&dsPref), - Tcl_DStringLength(&dsPref)) - ); - Tcl_DStringSetLength(&dsPref, prefixLen); - } else { - Tcl_ListObjAppendElement(NULL, result, Tcl_NewStringObj(z->name, lenz)); - } - } - z = z->tnext; - } - } else if ( - (zf->mntptlen > len + 1) - && (strncmp(zf->mntpt, path, len) == 0) - && (zf->mntpt[len] == '/') - && (CountSlashes(zf->mntpt) == l) - && Tcl_StringCaseMatch(zf->mntpt + len + 1, pattern, 0) - ) { - if (prefix != NULL) { - Tcl_DStringAppend(&dsPref, zf->mntpt, zf->mntptlen); - Tcl_ListObjAppendElement(NULL, result, - Tcl_NewStringObj(Tcl_DStringValue(&dsPref), - Tcl_DStringLength(&dsPref))); - Tcl_DStringSetLength(&dsPref, prefixLen); - } else { - Tcl_ListObjAppendElement(NULL, result, - Tcl_NewStringObj(zf->mntpt, zf->mntptlen)); - } - } - hPtr = Tcl_NextHashEntry(&search); - } - goto end; + l = CountSlashes(path); + if (path[len - 1] == '/') { + len--; + } else { + l++; + } + if ((pattern == NULL) || (pattern[0] == '\0')) { + pattern = "*"; + } + hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); + while (hPtr != NULL) { + ZipFile *zf = (ZipFile *) Tcl_GetHashValue(hPtr); + + if (zf->mntptlen == 0) { + ZipEntry *z = zf->topents; + while (z != NULL) { + size_t lenz = strlen(z->name); + if ((lenz > len + 1) && (strncmp(z->name, path, len) == 0) + && (z->name[len] == '/') + && (CountSlashes(z->name) == l) + && Tcl_StringCaseMatch(z->name + len + 1, pattern, + 0)) { + if (prefix != NULL) { + Tcl_DStringAppend(&dsPref, z->name, lenz); + Tcl_ListObjAppendElement(NULL, result, + Tcl_NewStringObj(Tcl_DStringValue(&dsPref), + Tcl_DStringLength(&dsPref))); + Tcl_DStringSetLength(&dsPref, prefixLen); + } else { + Tcl_ListObjAppendElement(NULL, result, + Tcl_NewStringObj(z->name, lenz)); + } + } + z = z->tnext; + } + } else if ((zf->mntptlen > len + 1) + && (strncmp(zf->mntpt, path, len) == 0) + && (zf->mntpt[len] == '/') + && (CountSlashes(zf->mntpt) == l) + && Tcl_StringCaseMatch(zf->mntpt + len + 1, pattern, 0)) { + if (prefix != NULL) { + Tcl_DStringAppend(&dsPref, zf->mntpt, zf->mntptlen); + Tcl_ListObjAppendElement(NULL, result, + Tcl_NewStringObj(Tcl_DStringValue(&dsPref), + Tcl_DStringLength(&dsPref))); + Tcl_DStringSetLength(&dsPref, prefixLen); + } else { + Tcl_ListObjAppendElement(NULL, result, + Tcl_NewStringObj(zf->mntpt, zf->mntptlen)); + } + } + hPtr = Tcl_NextHashEntry(&search); + } + goto end; } + if ((pattern == NULL) || (pattern[0] == '\0')) { - hPtr = Tcl_FindHashEntry(&ZipFS.fileHash, path); - if (hPtr != NULL) { - ZipEntry *z = (ZipEntry *) Tcl_GetHashValue(hPtr); - - if ((dirOnly < 0) || - (!dirOnly && !z->isdir) || - (dirOnly && z->isdir)) { - if (prefix != NULL) { - Tcl_DStringAppend(&dsPref, z->name, -1); - Tcl_ListObjAppendElement(NULL, result, - Tcl_NewStringObj(Tcl_DStringValue(&dsPref), - Tcl_DStringLength(&dsPref))); - Tcl_DStringSetLength(&dsPref, prefixLen); - } else { - Tcl_ListObjAppendElement(NULL, result, - Tcl_NewStringObj(z->name, -1)); - } - } - } - goto end; + hPtr = Tcl_FindHashEntry(&ZipFS.fileHash, path); + if (hPtr != NULL) { + ZipEntry *z = (ZipEntry *) Tcl_GetHashValue(hPtr); + + if ((dirOnly < 0) || (!dirOnly && !z->isdir) + || (dirOnly && z->isdir)) { + if (prefix != NULL) { + Tcl_DStringAppend(&dsPref, z->name, -1); + Tcl_ListObjAppendElement(NULL, result, + Tcl_NewStringObj(Tcl_DStringValue(&dsPref), + Tcl_DStringLength(&dsPref))); + Tcl_DStringSetLength(&dsPref, prefixLen); + } else { + Tcl_ListObjAppendElement(NULL, result, + Tcl_NewStringObj(z->name, -1)); + } + } + } + goto end; } + l = strlen(pattern); pat = Tcl_Alloc(len + l + 2); memcpy(pat, path, len); while ((len > 1) && (pat[len - 1] == '/')) { - --len; + --len; } if ((len > 1) || (pat[0] != '/')) { - pat[len] = '/'; - ++len; + pat[len] = '/'; + ++len; } memcpy(pat + len, pattern, l + 1); scnt = CountSlashes(pat); - for ( - hPtr = Tcl_FirstHashEntry(&ZipFS.fileHash, &search); - hPtr != NULL; - hPtr = Tcl_NextHashEntry(&search) - ) { - ZipEntry *z = (ZipEntry *) Tcl_GetHashValue(hPtr); - if ( - (dirOnly >= 0) && ((dirOnly && !z->isdir) || (!dirOnly && z->isdir)) - ) { - continue; - } - if ((z->depth == scnt) && Tcl_StringCaseMatch(z->name, pat, 0)) { - if (prefix != NULL) { - Tcl_DStringAppend(&dsPref, z->name + strip, -1); - Tcl_ListObjAppendElement( - NULL, result, - Tcl_NewStringObj(Tcl_DStringValue(&dsPref), - Tcl_DStringLength(&dsPref)) - ); - Tcl_DStringSetLength(&dsPref, prefixLen); - } else { - Tcl_ListObjAppendElement(NULL, result, Tcl_NewStringObj(z->name + strip, -1)); - } - } + for (hPtr = Tcl_FirstHashEntry(&ZipFS.fileHash, &search); + hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) { + ZipEntry *z = (ZipEntry *) Tcl_GetHashValue(hPtr); + if ((dirOnly >= 0) && ((dirOnly && !z->isdir) + || (!dirOnly && z->isdir))) { + continue; + } + if ((z->depth == scnt) && Tcl_StringCaseMatch(z->name, pat, 0)) { + if (prefix != NULL) { + Tcl_DStringAppend(&dsPref, z->name + strip, -1); + Tcl_ListObjAppendElement(NULL, result, + Tcl_NewStringObj(Tcl_DStringValue(&dsPref), + Tcl_DStringLength(&dsPref))); + Tcl_DStringSetLength(&dsPref, prefixLen); + } else { + Tcl_ListObjAppendElement(NULL, result, + Tcl_NewStringObj(z->name + strip, -1)); + } + } } Tcl_Free(pat); -end: + + end: Unlock(); Tcl_DStringFree(&dsPref); return TCL_OK; @@ -3949,20 +4111,22 @@ end: * * Zip_FSPathInFilesystemProc -- * - * This function determines if the given path object is in the - * ZIP filesystem. + * This function determines if the given path object is in the ZIP + * filesystem. * * Results: - * TCL_OK when the path object is in the ZIP filesystem, -1 otherwise. + * TCL_OK when the path object is in the ZIP filesystem, -1 otherwise. * * Side effects: - * None. + * None. * *------------------------------------------------------------------------- */ static int -Zip_FSPathInFilesystemProc(Tcl_Obj *pathPtr, ClientData *clientDataPtr) +Zip_FSPathInFilesystemProc( + Tcl_Obj *pathPtr, + ClientData *clientDataPtr) { Tcl_HashEntry *hPtr; Tcl_HashSearch search; @@ -3971,11 +4135,13 @@ Zip_FSPathInFilesystemProc(Tcl_Obj *pathPtr, ClientData *clientDataPtr) size_t len; char *path; - if (!(pathPtr = Tcl_FSGetNormalizedPath(NULL, pathPtr))) return -1; + if (!(pathPtr = Tcl_FSGetNormalizedPath(NULL, pathPtr))) { + return -1; + } path = Tcl_GetString(pathPtr); - if(strncmp(path,ZIPFS_VOLUME,ZIPFS_VOLUME_LEN)!=0) { - return -1; + if (strncmp(path, ZIPFS_VOLUME, ZIPFS_VOLUME_LEN) != 0) { + return -1; } len = pathPtr->length; @@ -3983,33 +4149,33 @@ Zip_FSPathInFilesystemProc(Tcl_Obj *pathPtr, ClientData *clientDataPtr) ReadLock(); hPtr = Tcl_FindHashEntry(&ZipFS.fileHash, path); if (hPtr != NULL) { - ret = TCL_OK; - goto endloop; + ret = TCL_OK; + goto endloop; } + hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); while (hPtr != NULL) { - zf = (ZipFile *) Tcl_GetHashValue(hPtr); - if (zf->mntptlen == 0) { - ZipEntry *z = zf->topents; - while (z != NULL) { - size_t lenz = strlen(z->name); - if ( - (len >= lenz) && (strncmp(path, z->name, lenz) == 0) - ) { - ret = TCL_OK; - goto endloop; - } - z = z->tnext; - } - } else if ( - (len >= zf->mntptlen) && (strncmp(path, zf->mntpt, zf->mntptlen) == 0) - ) { - ret = TCL_OK; - goto endloop; - } - hPtr = Tcl_NextHashEntry(&search); - } -endloop: + zf = (ZipFile *) Tcl_GetHashValue(hPtr); + if (zf->mntptlen == 0) { + ZipEntry *z = zf->topents; + while (z != NULL) { + size_t lenz = strlen(z->name); + + if ((len >= lenz) && (strncmp(path, z->name, lenz) == 0)) { + ret = TCL_OK; + goto endloop; + } + z = z->tnext; + } + } else if ((len >= zf->mntptlen) && + (strncmp(path, zf->mntpt, zf->mntptlen) == 0)) { + ret = TCL_OK; + goto endloop; + } + hPtr = Tcl_NextHashEntry(&search); + } + + endloop: Unlock(); return ret; } @@ -4019,18 +4185,20 @@ endloop: * * Zip_FSListVolumesProc -- * - * Lists the currently mounted ZIP filesystem volumes. + * Lists the currently mounted ZIP filesystem volumes. * * Results: - * The list of volumes. + * The list of volumes. * * Side effects: - * None + * None * *------------------------------------------------------------------------- */ + static Tcl_Obj * -Zip_FSListVolumesProc(void) { +Zip_FSListVolumesProc(void) +{ return Tcl_NewStringObj(ZIPFS_VOLUME, -1); } @@ -4039,29 +4207,32 @@ Zip_FSListVolumesProc(void) { * * Zip_FSFileAttrStringsProc -- * - * This function implements the ZIP filesystem dependent 'file attributes' - * subcommand, for listing the set of possible attribute strings. + * This function implements the ZIP filesystem dependent 'file + * attributes' subcommand, for listing the set of possible attribute + * strings. * * Results: - * An array of strings + * An array of strings * * Side effects: - * None. + * None. * *------------------------------------------------------------------------- */ static const char *const * -Zip_FSFileAttrStringsProc(Tcl_Obj *pathPtr, Tcl_Obj** objPtrRef) +Zip_FSFileAttrStringsProc( + Tcl_Obj *pathPtr, + Tcl_Obj** objPtrRef) { static const char *const attrs[] = { - "-uncompsize", - "-compsize", - "-offset", - "-mount", - "-archive", - "-permissions", - NULL, + "-uncompsize", + "-compsize", + "-offset", + "-mount", + "-archive", + "-permissions", + NULL, }; return attrs; } @@ -4071,61 +4242,66 @@ Zip_FSFileAttrStringsProc(Tcl_Obj *pathPtr, Tcl_Obj** objPtrRef) * * Zip_FSFileAttrsGetProc -- * - * This function implements the ZIP filesystem specific - * 'file attributes' subcommand, for 'get' operations. + * This function implements the ZIP filesystem specific 'file attributes' + * subcommand, for 'get' operations. * * Results: - * Standard Tcl return code. The object placed in objPtrRef (if TCL_OK - * was returned) is likely to have a refCount of zero. Either way we must - * either store it somewhere (e.g. the Tcl result), or Incr/Decr its - * refCount to ensure it is properly freed. + * Standard Tcl return code. The object placed in objPtrRef (if TCL_OK + * was returned) is likely to have a refCount of zero. Either way we must + * either store it somewhere (e.g. the Tcl result), or Incr/Decr its + * refCount to ensure it is properly freed. * * Side effects: - * None. + * None. * *------------------------------------------------------------------------- */ static int -Zip_FSFileAttrsGetProc(Tcl_Interp *interp, int index, Tcl_Obj *pathPtr, - Tcl_Obj **objPtrRef) +Zip_FSFileAttrsGetProc( + Tcl_Interp *interp, + int index, + Tcl_Obj *pathPtr, + Tcl_Obj **objPtrRef) { int len, ret = TCL_OK; char *path; ZipEntry *z; - if (!(pathPtr = Tcl_FSGetNormalizedPath(NULL, pathPtr))) return -1; + if (!(pathPtr = Tcl_FSGetNormalizedPath(NULL, pathPtr))) { + return -1; + } path = Tcl_GetStringFromObj(pathPtr, &len); ReadLock(); z = ZipFSLookup(path); if (z == NULL) { - ZIPFS_ERROR(interp,"file not found"); - ret = TCL_ERROR; - goto done; + ZIPFS_ERROR(interp, "file not found"); + ret = TCL_ERROR; + goto done; } switch (index) { - case 0: - *objPtrRef = Tcl_NewWideIntObj(z->nbyte); - goto done; - case 1: - *objPtrRef = Tcl_NewWideIntObj(z->nbytecompr); - goto done; - case 2: - *objPtrRef= Tcl_NewWideIntObj(z->offset); - goto done; - case 3: - *objPtrRef= Tcl_NewStringObj(z->zipfile->mntpt, z->zipfile->mntptlen); - goto done; - case 4: - *objPtrRef= Tcl_NewStringObj(z->zipfile->name, -1); - goto done; - case 5: - *objPtrRef= Tcl_NewStringObj("0555", -1); - goto done; - } - ZIPFS_ERROR(interp,"unknown attribute"); + case 0: + *objPtrRef = Tcl_NewWideIntObj(z->nbyte); + goto done; + case 1: + *objPtrRef = Tcl_NewWideIntObj(z->nbytecompr); + goto done; + case 2: + *objPtrRef = Tcl_NewWideIntObj(z->offset); + goto done; + case 3: + *objPtrRef = Tcl_NewStringObj(z->zipfile->mntpt, z->zipfile->mntptlen); + goto done; + case 4: + *objPtrRef = Tcl_NewStringObj(z->zipfile->name, -1); + goto done; + case 5: + *objPtrRef = Tcl_NewStringObj("0555", -1); + goto done; + } + ZIPFS_ERROR(interp, "unknown attribute"); ret = TCL_ERROR; -done: + done: Unlock(); return ret; } @@ -4135,23 +4311,27 @@ done: * * Zip_FSFileAttrsSetProc -- * - * This function implements the ZIP filesystem specific - * 'file attributes' subcommand, for 'set' operations. + * This function implements the ZIP filesystem specific 'file attributes' + * subcommand, for 'set' operations. * * Results: - * Standard Tcl return code. + * Standard Tcl return code. * * Side effects: - * None. + * None. * *------------------------------------------------------------------------- */ static int -Zip_FSFileAttrsSetProc(Tcl_Interp *interp, int index, Tcl_Obj *pathPtr,Tcl_Obj *objPtr) +Zip_FSFileAttrsSetProc( + Tcl_Interp *interp, + int index, + Tcl_Obj *pathPtr, + Tcl_Obj *objPtr) { if (interp != NULL) { - Tcl_SetObjResult(interp, Tcl_NewStringObj("unsupported operation", -1)); + Tcl_SetObjResult(interp, Tcl_NewStringObj("unsupported operation", -1)); } return TCL_ERROR; } @@ -4169,358 +4349,407 @@ Zip_FSFileAttrsSetProc(Tcl_Interp *interp, int index, Tcl_Obj *pathPtr,Tcl_Obj * */ static Tcl_Obj * -Zip_FSFilesystemPathTypeProc(Tcl_Obj *pathPtr) +Zip_FSFilesystemPathTypeProc( + Tcl_Obj *pathPtr) { return Tcl_NewStringObj("zip", -1); } - /* *------------------------------------------------------------------------- * * Zip_FSLoadFile -- * - * This functions deals with loading native object code. If - * the given path object refers to a file within the ZIP - * filesystem, an approriate error code is returned to delegate - * loading to the caller (by copying the file to temp store - * and loading from there). As fallback when the file refers - * to the ZIP file system but is not present, it is looked up - * relative to the executable and loaded from there when available. + * This functions deals with loading native object code. If the given + * path object refers to a file within the ZIP filesystem, an approriate + * error code is returned to delegate loading to the caller (by copying + * the file to temp store and loading from there). As fallback when the + * file refers to the ZIP file system but is not present, it is looked up + * relative to the executable and loaded from there when available. * * Results: - * TCL_OK on success, TCL_ERROR otherwise with error message left. + * TCL_OK on success, TCL_ERROR otherwise with error message left. * * Side effects: - * Loads native code into the process address space. + * Loads native code into the process address space. * *------------------------------------------------------------------------- */ static int -Zip_FSLoadFile(Tcl_Interp *interp, Tcl_Obj *path, Tcl_LoadHandle *loadHandle, - Tcl_FSUnloadFileProc **unloadProcPtr, int flags) +Zip_FSLoadFile( + Tcl_Interp *interp, + Tcl_Obj *path, + Tcl_LoadHandle *loadHandle, + Tcl_FSUnloadFileProc **unloadProcPtr, + int flags) { Tcl_FSLoadFileProc2 *loadFileProc; #ifdef ANDROID /* - * Force loadFileProc to native implementation since the - * package manager already extracted the shared libraries - * from the APK at install time. + * Force loadFileProc to native implementation since the package manager + * already extracted the shared libraries from the APK at install time. */ loadFileProc = (Tcl_FSLoadFileProc2 *) tclNativeFilesystem.loadFileProc; if (loadFileProc != NULL) { - return loadFileProc(interp, path, loadHandle, unloadProcPtr, flags); + return loadFileProc(interp, path, loadHandle, unloadProcPtr, flags); } Tcl_SetErrno(ENOENT); - ZIPFS_ERROR(interp,Tcl_PosixError(interp)); + ZIPFS_ERROR(interp, Tcl_PosixError(interp)); return TCL_ERROR; -#else +#else /* !ANDROID */ Tcl_Obj *altPath = NULL; int ret = TCL_ERROR; if (Tcl_FSAccess(path, R_OK) == 0) { - /* - * EXDEV should trigger loading by copying to temp store. - */ + /* + * EXDEV should trigger loading by copying to temp store. + */ - Tcl_SetErrno(EXDEV); - ZIPFS_ERROR(interp,Tcl_PosixError(interp)); - return ret; + Tcl_SetErrno(EXDEV); + ZIPFS_ERROR(interp, Tcl_PosixError(interp)); + return ret; } else { - Tcl_Obj *objs[2] = { NULL, NULL }; - - objs[1] = TclPathPart(interp, path, TCL_PATH_DIRNAME); - if ((objs[1] != NULL) && (Zip_FSAccessProc(objs[1], R_OK) == 0)) { - const char *execName = Tcl_GetNameOfExecutable(); - - /* - * Shared object is not in ZIP but its path prefix is, - * thus try to load from directory where the executable - * came from. - */ - TclDecrRefCount(objs[1]); - objs[1] = TclPathPart(interp, path, TCL_PATH_TAIL); - /* - * Get directory name of executable manually to deal - * with cases where [file dirname [info nameofexecutable]] - * is equal to [info nameofexecutable] due to VFS effects. - */ - if (execName != NULL) { - const char *p = strrchr(execName, '/'); - - if (p > execName + 1) { - --p; - objs[0] = Tcl_NewStringObj(execName, p - execName); - } - } - if (objs[0] == NULL) { - objs[0] = TclPathPart(interp, TclGetObjNameOfExecutable(), - TCL_PATH_DIRNAME); - } - if (objs[0] != NULL) { - altPath = TclJoinPath(2, objs); - if (altPath != NULL) { - Tcl_IncrRefCount(altPath); - if (Tcl_FSAccess(altPath, R_OK) == 0) { - path = altPath; - } - } - } - } - if (objs[0] != NULL) { - Tcl_DecrRefCount(objs[0]); - } - if (objs[1] != NULL) { - Tcl_DecrRefCount(objs[1]); - } + Tcl_Obj *objs[2] = { NULL, NULL }; + + objs[1] = TclPathPart(interp, path, TCL_PATH_DIRNAME); + if ((objs[1] != NULL) && (Zip_FSAccessProc(objs[1], R_OK) == 0)) { + const char *execName = Tcl_GetNameOfExecutable(); + + /* + * Shared object is not in ZIP but its path prefix is, thus try to + * load from directory where the executable came from. + */ + + TclDecrRefCount(objs[1]); + objs[1] = TclPathPart(interp, path, TCL_PATH_TAIL); + + /* + * Get directory name of executable manually to deal with cases + * where [file dirname [info nameofexecutable]] is equal to [info + * nameofexecutable] due to VFS effects. + */ + + if (execName != NULL) { + const char *p = strrchr(execName, '/'); + + if (p > execName + 1) { + --p; + objs[0] = Tcl_NewStringObj(execName, p - execName); + } + } + if (objs[0] == NULL) { + objs[0] = TclPathPart(interp, TclGetObjNameOfExecutable(), + TCL_PATH_DIRNAME); + } + if (objs[0] != NULL) { + altPath = TclJoinPath(2, objs); + if (altPath != NULL) { + Tcl_IncrRefCount(altPath); + if (Tcl_FSAccess(altPath, R_OK) == 0) { + path = altPath; + } + } + } + } + if (objs[0] != NULL) { + Tcl_DecrRefCount(objs[0]); + } + if (objs[1] != NULL) { + Tcl_DecrRefCount(objs[1]); + } } loadFileProc = (Tcl_FSLoadFileProc2 *) tclNativeFilesystem.loadFileProc; if (loadFileProc != NULL) { - ret = loadFileProc(interp, path, loadHandle, unloadProcPtr, flags); + ret = loadFileProc(interp, path, loadHandle, unloadProcPtr, flags); } else { - Tcl_SetErrno(ENOENT); - ZIPFS_ERROR(interp,Tcl_PosixError(interp)); + Tcl_SetErrno(ENOENT); + ZIPFS_ERROR(interp, Tcl_PosixError(interp)); } if (altPath != NULL) { - Tcl_DecrRefCount(altPath); + Tcl_DecrRefCount(altPath); } return ret; -#endif +#endif /* ANDROID */ } #endif /* HAVE_ZLIB */ - - /* *------------------------------------------------------------------------- * * TclZipfs_Init -- * - * Perform per interpreter initialization of this module. + * Perform per interpreter initialization of this module. * * Results: - * The return value is a standard Tcl result. + * The return value is a standard Tcl result. * * Side effects: - * Initializes this module if not already initialized, and adds - * module related commands to the given interpreter. + * Initializes this module if not already initialized, and adds module + * related commands to the given interpreter. * *------------------------------------------------------------------------- */ MODULE_SCOPE int -TclZipfs_Init(Tcl_Interp *interp) +TclZipfs_Init( + Tcl_Interp *interp) { #ifdef HAVE_ZLIB /* one-time initialization */ WriteLock(); /* Tcl_StaticPackage(interp, "zipfs", TclZipfs_Init, TclZipfs_Init); */ if (!ZipFS.initialized) { - TclZipfs_C_Init(); + TclZipfs_C_Init(); } Unlock(); - if(interp != NULL) { - static const EnsembleImplMap initMap[] = { - {"mkimg", ZipFSMkImgObjCmd, NULL, NULL, NULL, 0}, - {"mkzip", ZipFSMkZipObjCmd, NULL, NULL, NULL, 0}, - {"lmkimg", ZipFSLMkImgObjCmd, NULL, NULL, NULL, 0}, - {"lmkzip", ZipFSLMkZipObjCmd, NULL, NULL, NULL, 0}, - /* The 4 entries above are not available in safe interpreters */ - {"mount", ZipFSMountObjCmd, NULL, NULL, NULL, 0}, - {"mount_data", ZipFSMountBufferObjCmd, NULL, NULL, NULL, 0}, - {"unmount", ZipFSUnmountObjCmd, NULL, NULL, NULL, 0}, - {"mkkey", ZipFSMkKeyObjCmd, NULL, NULL, NULL, 0}, - {"exists", ZipFSExistsObjCmd, NULL, NULL, NULL, 1}, - {"info", ZipFSInfoObjCmd, NULL, NULL, NULL, 1}, - {"list", ZipFSListObjCmd, NULL, NULL, NULL, 1}, - {"canonical", ZipFSCanonicalObjCmd, NULL, NULL, NULL, 1}, - {"root", ZipFSRootObjCmd, NULL, NULL, NULL, 1}, - {"tcl_library", ZipFSTclLibraryObjCmd, NULL, NULL, NULL, 0}, - - {NULL, NULL, NULL, NULL, NULL, 0} - }; - static const char findproc[] = - "namespace eval ::tcl::zipfs::zipfs {}\n" - "proc ::tcl::zipfs::find dir {\n" - " set result {}\n" - " if {[catch {glob -directory $dir -tails -nocomplain * .*} list]} {\n" - " return $result\n" - " }\n" - " foreach file $list {\n" - " if {$file eq \".\" || $file eq \"..\"} {\n" - " continue\n" - " }\n" - " set file [file join $dir $file]\n" - " lappend result $file\n" - " foreach file [::tcl::zipfs::find $file] {\n" - " lappend result $file\n" - " }\n" - " }\n" - " return [lsort $result]\n" - "}\n"; - Tcl_EvalEx(interp, findproc, -1, TCL_EVAL_GLOBAL); - Tcl_LinkVar(interp, "::tcl::zipfs::wrmax", (char *) &ZipFS.wrmax,TCL_LINK_INT); - TclMakeEnsemble(interp, "zipfs", Tcl_IsSafe(interp) ? (initMap+4) : initMap); - Tcl_PkgProvide(interp, "zipfs", "2.0"); + if (interp != NULL) { + static const EnsembleImplMap initMap[] = { + {"mkimg", ZipFSMkImgObjCmd, NULL, NULL, NULL, 0}, + {"mkzip", ZipFSMkZipObjCmd, NULL, NULL, NULL, 0}, + {"lmkimg", ZipFSLMkImgObjCmd, NULL, NULL, NULL, 0}, + {"lmkzip", ZipFSLMkZipObjCmd, NULL, NULL, NULL, 0}, + /* The 4 entries above are not available in safe interpreters */ + {"mount", ZipFSMountObjCmd, NULL, NULL, NULL, 0}, + {"mount_data", ZipFSMountBufferObjCmd, NULL, NULL, NULL, 0}, + {"unmount", ZipFSUnmountObjCmd, NULL, NULL, NULL, 0}, + {"mkkey", ZipFSMkKeyObjCmd, NULL, NULL, NULL, 0}, + {"exists", ZipFSExistsObjCmd, NULL, NULL, NULL, 1}, + {"info", ZipFSInfoObjCmd, NULL, NULL, NULL, 1}, + {"list", ZipFSListObjCmd, NULL, NULL, NULL, 1}, + {"canonical", ZipFSCanonicalObjCmd, NULL, NULL, NULL, 1}, + {"root", ZipFSRootObjCmd, NULL, NULL, NULL, 1}, + {"tcl_library", ZipFSTclLibraryObjCmd, NULL, NULL, NULL, 0}, + {NULL, NULL, NULL, NULL, NULL, 0} + }; + static const char findproc[] = + "namespace eval ::tcl::zipfs::zipfs {}\n" + "proc ::tcl::zipfs::find dir {\n" + " set result {}\n" + " if {[catch {glob -directory $dir -tails -nocomplain * .*} list]} {\n" + " return $result\n" + " }\n" + " foreach file $list {\n" + " if {$file eq \".\" || $file eq \"..\"} {\n" + " continue\n" + " }\n" + " set file [file join $dir $file]\n" + " lappend result $file\n" + " foreach file [::tcl::zipfs::find $file] {\n" + " lappend result $file\n" + " }\n" + " }\n" + " return [lsort $result]\n" + "}\n"; + Tcl_EvalEx(interp, findproc, -1, TCL_EVAL_GLOBAL); + Tcl_LinkVar(interp, "::tcl::zipfs::wrmax", (char *) &ZipFS.wrmax, + TCL_LINK_INT); + TclMakeEnsemble(interp, "zipfs", + Tcl_IsSafe(interp) ? (initMap + 4) : initMap); + Tcl_PkgProvide(interp, "zipfs", "2.0"); } return TCL_OK; #else - ZIPFS_ERROR(interp,"no zlib available"); + ZIPFS_ERROR(interp, "no zlib available"); return TCL_ERROR; #endif } - -static int TclZipfs_AppHook_FindTclInit(const char *archive){ + +static int +TclZipfs_AppHook_FindTclInit( + const char *archive) +{ Tcl_Obj *vfsinitscript; int found; - if(zipfs_literal_tcl_library) { - return TCL_ERROR; + + if (zipfs_literal_tcl_library) { + return TCL_ERROR; } - if(TclZipfs_Mount(NULL, ZIPFS_ZIP_MOUNT, archive, NULL)) { - /* Either the file doesn't exist or it is not a zip archive */ - return TCL_ERROR; + if (TclZipfs_Mount(NULL, ZIPFS_ZIP_MOUNT, archive, NULL)) { + /* Either the file doesn't exist or it is not a zip archive */ + return TCL_ERROR; } - vfsinitscript=Tcl_NewStringObj(ZIPFS_ZIP_MOUNT "/init.tcl",-1); + + vfsinitscript = Tcl_NewStringObj(ZIPFS_ZIP_MOUNT "/init.tcl", -1); Tcl_IncrRefCount(vfsinitscript); - found=Tcl_FSAccess(vfsinitscript,F_OK); + found = Tcl_FSAccess(vfsinitscript, F_OK); Tcl_DecrRefCount(vfsinitscript); - if(found==0) { - zipfs_literal_tcl_library=ZIPFS_ZIP_MOUNT; - return TCL_OK; + if (found == 0) { + zipfs_literal_tcl_library = ZIPFS_ZIP_MOUNT; + return TCL_OK; } - vfsinitscript=Tcl_NewStringObj(ZIPFS_ZIP_MOUNT "/tcl_library/init.tcl",-1); + + vfsinitscript = Tcl_NewStringObj( + ZIPFS_ZIP_MOUNT "/tcl_library/init.tcl", -1); Tcl_IncrRefCount(vfsinitscript); - found=Tcl_FSAccess(vfsinitscript,F_OK); + found = Tcl_FSAccess(vfsinitscript, F_OK); Tcl_DecrRefCount(vfsinitscript); - if(found==0) { - zipfs_literal_tcl_library=ZIPFS_ZIP_MOUNT "/tcl_library"; - return TCL_OK; + if (found == 0) { + zipfs_literal_tcl_library = ZIPFS_ZIP_MOUNT "/tcl_library"; + return TCL_OK; } + return TCL_ERROR; } + +/* + *------------------------------------------------------------------------- + * + * Tclkit_MainHook -- + * + * Performs the argument munging for the shell + * + *------------------------------------------------------------------------- + */ +int +TclZipfs_AppHook( + int *argc, #ifdef _WIN32 -int TclZipfs_AppHook(int *argc, TCHAR ***argv) -#else -int TclZipfs_AppHook(int *argc, char ***argv) -#endif + TCHAR +#else /* !_WIN32 */ + char +#endif /* _WIN32 */ + ***argv) { #ifdef _WIN32 Tcl_DString ds; -#endif - /* - * Tclkit_MainHook -- - * Performs the argument munging for the shell - */ +#endif /* _WIN32 */ char *archive; Tcl_FindExecutable((*argv)[0]); - archive=(char *)Tcl_GetNameOfExecutable(); + archive = (char *) Tcl_GetNameOfExecutable(); TclZipfs_Init(NULL); + /* - ** Look for init.tcl in one of the locations mounted later in this function - */ - if(!TclZipfs_Mount(NULL, ZIPFS_APP_MOUNT, archive, NULL)) { - int found; - Tcl_Obj *vfsinitscript; - vfsinitscript=Tcl_NewStringObj(ZIPFS_APP_MOUNT "/main.tcl",-1); - Tcl_IncrRefCount(vfsinitscript); - if(Tcl_FSAccess(vfsinitscript,F_OK)==0) { - /* Startup script should be set before calling Tcl_AppInit */ - Tcl_SetStartupScript(vfsinitscript,NULL); - } else { - Tcl_DecrRefCount(vfsinitscript); - } - /* Set Tcl Encodings */ - if(!zipfs_literal_tcl_library) { - vfsinitscript=Tcl_NewStringObj(ZIPFS_APP_MOUNT "/tcl_library/init.tcl",-1); - Tcl_IncrRefCount(vfsinitscript); - found=Tcl_FSAccess(vfsinitscript,F_OK); - Tcl_DecrRefCount(vfsinitscript); - if(found==TCL_OK) { - zipfs_literal_tcl_library=ZIPFS_APP_MOUNT "/tcl_library"; - return TCL_OK; - } - } + * Look for init.tcl in one of the locations mounted later in this + * function. + */ + + if (!TclZipfs_Mount(NULL, ZIPFS_APP_MOUNT, archive, NULL)) { + int found; + Tcl_Obj *vfsinitscript; + + vfsinitscript = Tcl_NewStringObj(ZIPFS_APP_MOUNT "/main.tcl", -1); + Tcl_IncrRefCount(vfsinitscript); + if (Tcl_FSAccess(vfsinitscript, F_OK) == 0) { + /* + * Startup script should be set before calling Tcl_AppInit + */ + + Tcl_SetStartupScript(vfsinitscript, NULL); + } else { + Tcl_DecrRefCount(vfsinitscript); + } + + /* + * Set Tcl Encodings + */ + + if (!zipfs_literal_tcl_library) { + vfsinitscript = Tcl_NewStringObj( + ZIPFS_APP_MOUNT "/tcl_library/init.tcl", -1); + Tcl_IncrRefCount(vfsinitscript); + found = Tcl_FSAccess(vfsinitscript, F_OK); + Tcl_DecrRefCount(vfsinitscript); + if (found == TCL_OK) { + zipfs_literal_tcl_library = ZIPFS_APP_MOUNT "/tcl_library"; + return TCL_OK; + } + } } else if (*argc>1) { - return TCL_OK; + return TCL_OK; #ifdef _WIN32 - archive = Tcl_WinTCharToUtf((*argv)[1], -1, &ds); + archive = Tcl_WinTCharToUtf((*argv)[1], -1, &ds); #else - archive=(*argv)[1]; + archive = (*argv)[1]; #endif - if (strcmp(archive,"install")==0) { - /* If the first argument is mkzip, run the mkzip program */ - Tcl_Obj *vfsinitscript; - /* Run this now to ensure the file is present by the time Tcl_Main wants it */ - TclZipfs_TclLibrary(); - vfsinitscript=Tcl_NewStringObj(ZIPFS_ZIP_MOUNT "/tcl_library/install.tcl",-1); - Tcl_IncrRefCount(vfsinitscript); - if(Tcl_FSAccess(vfsinitscript,F_OK)==0) { - Tcl_SetStartupScript(vfsinitscript,NULL); - } - return TCL_OK; - } else { - if(!TclZipfs_Mount(NULL, ZIPFS_APP_MOUNT, archive, NULL)) { - int found; - Tcl_Obj *vfsinitscript; - vfsinitscript=Tcl_NewStringObj(ZIPFS_APP_MOUNT "/main.tcl",-1); - Tcl_IncrRefCount(vfsinitscript); - if(Tcl_FSAccess(vfsinitscript,F_OK)==0) { - /* Startup script should be set before calling Tcl_AppInit */ - Tcl_SetStartupScript(vfsinitscript,NULL); - } else { - Tcl_DecrRefCount(vfsinitscript); - } - /* Set Tcl Encodings */ - vfsinitscript=Tcl_NewStringObj(ZIPFS_APP_MOUNT "/tcl_library/init.tcl",-1); - Tcl_IncrRefCount(vfsinitscript); - found=Tcl_FSAccess(vfsinitscript,F_OK); - Tcl_DecrRefCount(vfsinitscript); - if(found==TCL_OK) { - zipfs_literal_tcl_library=ZIPFS_APP_MOUNT "/tcl_library"; - return TCL_OK; - } - } - } + if (strcmp(archive, "install") == 0) { + /* + * If the first argument is mkzip, run the mkzip program. + */ + + Tcl_Obj *vfsinitscript; + + /* + * Run this now to ensure the file is present by the time Tcl_Main + * wants it. + */ + + TclZipfs_TclLibrary(); + vfsinitscript = Tcl_NewStringObj( + ZIPFS_ZIP_MOUNT "/tcl_library/install.tcl", -1); + Tcl_IncrRefCount(vfsinitscript); + if (Tcl_FSAccess(vfsinitscript, F_OK) == 0) { + Tcl_SetStartupScript(vfsinitscript, NULL); + } + return TCL_OK; + } else if (!TclZipfs_Mount(NULL, ZIPFS_APP_MOUNT, archive, NULL)) { + int found; + Tcl_Obj *vfsinitscript; + + vfsinitscript = Tcl_NewStringObj(ZIPFS_APP_MOUNT "/main.tcl", -1); + Tcl_IncrRefCount(vfsinitscript); + if (Tcl_FSAccess(vfsinitscript, F_OK) == 0) { + /* + * Startup script should be set before calling Tcl_AppInit + */ + + Tcl_SetStartupScript(vfsinitscript, NULL); + } else { + Tcl_DecrRefCount(vfsinitscript); + } + /* Set Tcl Encodings */ + vfsinitscript = Tcl_NewStringObj( + ZIPFS_APP_MOUNT "/tcl_library/init.tcl", -1); + Tcl_IncrRefCount(vfsinitscript); + found = Tcl_FSAccess(vfsinitscript, F_OK); + Tcl_DecrRefCount(vfsinitscript); + if (found == TCL_OK) { + zipfs_literal_tcl_library = ZIPFS_APP_MOUNT "/tcl_library"; + return TCL_OK; + } + } #ifdef _WIN32 - Tcl_DStringFree(&ds); -#endif + Tcl_DStringFree(&ds); +#endif /* _WIN32 */ } return TCL_OK; } - #ifndef HAVE_ZLIB - + /* *------------------------------------------------------------------------- * * TclZipfs_Mount, TclZipfs_Unmount -- * - * Dummy version when no ZLIB support available. + * Dummy version when no ZLIB support available. * *------------------------------------------------------------------------- */ int -TclZipfs_Mount(Tcl_Interp *interp, const char *mntpt, const char *zipname, - const char *passwd) +TclZipfs_Mount( + Tcl_Interp *interp, + const char *mntpt, + const char *zipname, + const char *passwd) { return TclZipfs_Init(interp, 1); } int -TclZipfs_Unmount(Tcl_Interp *interp, const char *zipname) +TclZipfs_Unmount( + Tcl_Interp *interp, + const char *zipname) { return TclZipfs_Init(interp, 1); } - -#endif - +#endif /* !HAVE_ZLIB */ + /* * Local Variables: * mode: c -- cgit v0.12 From 9feb8b7c29e253d12a05136bc566bc7e881c04ac Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Thu, 4 Oct 2018 19:22:37 +0000 Subject: In registry, protect "keyName" from being NULL: This actually can lead to crashed (I experienced this ...). Update version to 1.3.3, and align implementation in all branches (core-8-6-branch and higher) --- library/reg/pkgIndex.tcl | 4 ++-- win/tclWinReg.c | 34 +++++++++++++++------------------- 2 files changed, 17 insertions(+), 21 deletions(-) diff --git a/library/reg/pkgIndex.tcl b/library/reg/pkgIndex.tcl index b1fe234..ee559b5 100755 --- a/library/reg/pkgIndex.tcl +++ b/library/reg/pkgIndex.tcl @@ -1,9 +1,9 @@ if {([info commands ::tcl::pkgconfig] eq "") || ([info sharedlibextension] ne ".dll")} return if {[::tcl::pkgconfig get debug]} { - package ifneeded registry 1.3.2 \ + package ifneeded registry 1.3.3 \ [list load [file join $dir tclreg13g.dll] registry] } else { - package ifneeded registry 1.3.2 \ + package ifneeded registry 1.3.3 \ [list load [file join $dir tclreg13.dll] registry] } diff --git a/win/tclWinReg.c b/win/tclWinReg.c index de48b9b..f3d7a07 100644 --- a/win/tclWinReg.c +++ b/win/tclWinReg.c @@ -22,13 +22,6 @@ #endif #include -#ifndef UNICODE -# undef Tcl_WinTCharToUtf -# define Tcl_WinTCharToUtf(a,b,c) Tcl_ExternalToUtfDString(NULL,a,b,c) -# undef Tcl_WinUtfToTChar -# define Tcl_WinUtfToTChar(a,b,c) Tcl_UtfToExternalDString(NULL,a,b,c) -#endif /* !UNICODE */ - /* * Ensure that we can say which registry is being accessed. */ @@ -163,7 +156,7 @@ Registry_Init( cmd = Tcl_CreateObjCommand(interp, "registry", RegistryObjCmd, interp, DeleteCmd); Tcl_SetAssocData(interp, REGISTRY_ASSOC_KEY, NULL, cmd); - return Tcl_PkgProvide(interp, "registry", "1.3.2"); + return Tcl_PkgProvide(interp, "registry", "1.3.3"); } /* @@ -414,12 +407,12 @@ DeleteKey( */ keyName = Tcl_GetString(keyNameObj); - buffer = ckalloc(keyNameObj->length + 1); + buffer = Tcl_Alloc(keyNameObj->length + 1); strcpy(buffer, keyName); if (ParseKeyName(interp, buffer, &hostName, &rootKey, &keyName) != TCL_OK) { - ckfree(buffer); + Tcl_Free(buffer); return TCL_ERROR; } @@ -427,7 +420,7 @@ DeleteKey( Tcl_SetObjResult(interp, Tcl_NewStringObj("bad key: cannot delete root keys", -1)); Tcl_SetErrorCode(interp, "WIN_REG", "DEL_ROOT_KEY", NULL); - ckfree(buffer); + Tcl_Free(buffer); return TCL_ERROR; } @@ -442,7 +435,7 @@ DeleteKey( mode |= KEY_ENUMERATE_SUB_KEYS | DELETE; result = OpenSubKey(hostName, rootKey, keyName, mode, 0, &subkey); if (result != ERROR_SUCCESS) { - ckfree(buffer); + Tcl_Free(buffer); if (result == ERROR_FILE_NOT_FOUND) { return TCL_OK; } @@ -470,7 +463,7 @@ DeleteKey( } RegCloseKey(subkey); - ckfree(buffer); + Tcl_Free(buffer); return result; } @@ -603,8 +596,7 @@ GetKeyNames( } break; } - Tcl_WinTCharToUtf(buffer, bufSize * sizeof(TCHAR), &ds); - name = Tcl_DStringValue(&ds); + name = Tcl_WinTCharToUtf(buffer, bufSize * sizeof(TCHAR), &ds); if (pattern && !Tcl_StringMatch(name, pattern)) { Tcl_DStringFree(&ds); continue; @@ -950,7 +942,7 @@ OpenKey( keyName = Tcl_GetString(keyNameObj); length = keyNameObj->length; - buffer = ckalloc(length + 1); + buffer = Tcl_Alloc(length + 1); strcpy(buffer, keyName); result = ParseKeyName(interp, buffer, &hostName, &rootKey, &keyName); @@ -966,7 +958,7 @@ OpenKey( } } - ckfree(buffer); + Tcl_Free(buffer); return result; } @@ -1019,7 +1011,9 @@ OpenSubKey( * this key must be closed by the caller. */ - keyName = (char *) Tcl_WinUtfToTChar(keyName, -1, &buf); + if (keyName) { + keyName = (char *) Tcl_WinUtfToTChar(keyName, -1, &buf); + } if (flags & REG_CREATE) { DWORD create; @@ -1037,7 +1031,9 @@ OpenSubKey( result = RegOpenKeyEx(rootKey, (TCHAR *)keyName, 0, mode, keyPtr); } - Tcl_DStringFree(&buf); + if (keyName) { + Tcl_DStringFree(&buf); + } /* * Be sure to close the root key since we are done with it now. -- cgit v0.12 From c3c71b5f3cddf06ba73dd3c2db7c72831db606c9 Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 5 Oct 2018 17:20:40 +0000 Subject: Post-TIP 505 editing of [lreplace] documentation. --- doc/lreplace.n | 34 ++++++++++++---------------------- 1 file changed, 12 insertions(+), 22 deletions(-) diff --git a/doc/lreplace.n b/doc/lreplace.n index 35a9130..32b7356 100644 --- a/doc/lreplace.n +++ b/doc/lreplace.n @@ -17,7 +17,7 @@ lreplace \- Replace elements in a list with new elements .BE .SH DESCRIPTION .PP -\fBlreplace\fR returns a new list formed by replacing one or more elements of +\fBlreplace\fR returns a new list formed by replacing zero or more elements of \fIlist\fR with the \fIelement\fR arguments. \fIfirst\fR and \fIlast\fR are index values specifying the first and last elements of the range to replace. @@ -27,36 +27,26 @@ supporting simple index arithmetic and indices relative to the end of the list. 0 refers to the first element of the list, and \fBend\fR refers to the last element of the list. -If \fIlist\fR is empty, then \fIfirst\fR and \fIlast\fR are ignored. .PP -If \fIfirst\fR is less than zero, it is considered to refer to before the -first element of the list. +If either \fIfirst\fR or \fIlast\fR is less than zero, it is considered +to refer to before the first element of the list. This allows \fBlreplace\fR +to prepend elements to \fIlist\fR. .VS TIP505 -If \fIfirst\fR indicates a position greater than the index of the last element -of the list, it is treated as if it is an index one greater than the last -element. This allows this command to append elements to the list. +If either \fIfirst\fR or \fIlast\fR indicates a position greater than the +index of the last element of the list, it is treated as if it is an +index one greater than the last element. This allows \fBlreplace\fR to +append elements to \fIlist\fR. .VE TIP505 -For non-empty lists, the element indicated -by \fIfirst\fR must exist, or \fIfirst\fR must indicate before the -start of the list. .PP If \fIlast\fR is less than \fIfirst\fR, then any specified elements -will be inserted into the list before the point specified by \fIfirst\fR +will be inserted into the list before the element specified by \fIfirst\fR with no elements being deleted. -.VS TIP505 -If \fIlast\fR is greater than the index of the last item of the list, it is -treated as if it is an index one greater than the last element. This means -that if it is also greater than than \fIfirst\fR, all elements from -\fIfirst\fR to the end of the list will be replaced, and otherwise the -elements will be appended. -.VE TIP505 .PP -The \fIelement\fR arguments specify zero or more new arguments to +The \fIelement\fR arguments specify zero or more new elements to be added to the list in place of those that were deleted. Each \fIelement\fR argument will become a separate element of the list. If no \fIelement\fR arguments are specified, then the elements -between \fIfirst\fR and \fIlast\fR are simply deleted. If \fIlist\fR -is empty, any \fIelement\fR arguments are added to the end of the list. +between \fIfirst\fR and \fIlast\fR are simply deleted. .SH EXAMPLES .PP Replacing an element of a list with another: @@ -93,7 +83,7 @@ proc lremove {listVariable value} { .CE .PP .VS TIP505 -Adding elements to the end of the list; note that \fBend+2\fR will initially +Appending elements to the list; note that \fBend+2\fR will initially be treated as if it is \fB6\fR here, but both that and \fB12345\fR are greater than the index of the final item so they behave identically: .PP -- cgit v0.12 From 85aac3aef7c9fa70dc07467858439a6d6f533ac0 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Fri, 5 Oct 2018 19:37:38 +0000 Subject: Fix wrong usage of Tcl_WinTCharToUtf() contract: nativePath should never be NULL, but actually it can be. --- win/tclWinFCmd.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/win/tclWinFCmd.c b/win/tclWinFCmd.c index 52ea8c6..2f28154 100644 --- a/win/tclWinFCmd.c +++ b/win/tclWinFCmd.c @@ -1026,7 +1026,8 @@ DoRemoveJustDirectory( if (nativePath == NULL || nativePath[0] == '\0') { Tcl_SetErrno(ENOENT); - goto end; + Tcl_DStringInit(errorPtr); + return TCL_ERROR; } attr = GetFileAttributes(nativePath); @@ -1108,9 +1109,7 @@ DoRemoveJustDirectory( end: if (errorPtr != NULL) { - char *p; - Tcl_WinTCharToUtf(nativePath, -1, errorPtr); - p = Tcl_DStringValue(errorPtr); + char *p = Tcl_WinTCharToUtf(nativePath, -1, errorPtr); for (; *p; ++p) { if (*p == '\\') *p = '/'; } -- cgit v0.12 From 8985ee2114ddeb7e65148843f592f3270053e269 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Fri, 5 Oct 2018 20:54:59 +0000 Subject: Better implementations of Tcl_WinTCharToUtf() and Tcl_WinUtfToTChar(). They don't make any assumption on whether encodings are initialized, or specific win32 handling of special characters. --- generic/tclStubInit.c | 49 ++++++++--------------------------------------- win/tclWin32Dll.c | 53 ++++----------------------------------------------- 2 files changed, 12 insertions(+), 90 deletions(-) diff --git a/generic/tclStubInit.c b/generic/tclStubInit.c index b28d501..50bb4a2 100644 --- a/generic/tclStubInit.c +++ b/generic/tclStubInit.c @@ -12,6 +12,10 @@ #include "tclInt.h" #include "tommath.h" +#ifdef __CYGWIN__ +# include +#endif + #ifdef __GNUC__ #pragma GCC dependency "tcl.decls" #pragma GCC dependency "tclInt.decls" @@ -106,10 +110,6 @@ static unsigned short TclWinNToHS(unsigned short ns) { # define TclWinFlushDirtyChannels doNothing # define TclWinResetInterfaces doNothing -#if TCL_UTF_MAX < 4 -static Tcl_Encoding winTCharEncoding; -#endif - static int TclpIsAtty(int fd) { @@ -188,25 +188,8 @@ Tcl_WinUtfToTChar( int len, Tcl_DString *dsPtr) { -#if TCL_UTF_MAX > 3 - WCHAR *wp; - int size = MultiByteToWideChar(CP_UTF8, 0, string, len, 0, 0); - Tcl_DStringInit(dsPtr); - Tcl_DStringSetLength(dsPtr, 2*size+2); - wp = (WCHAR *)Tcl_DStringValue(dsPtr); - MultiByteToWideChar(CP_UTF8, 0, string, len, wp, size+1); - if (len == -1) --size; /* account for 0-byte at string end */ - Tcl_DStringSetLength(dsPtr, 2*size); - wp[size] = 0; - return (char *)wp; -#else - if (!winTCharEncoding) { - winTCharEncoding = Tcl_GetEncoding(0, "unicode"); - } - return Tcl_UtfToExternalDString(winTCharEncoding, - string, len, dsPtr); -#endif + return (char *)Tcl_UtfToUniCharDString(string, len, dsPtr); } char * @@ -215,29 +198,13 @@ Tcl_WinTCharToUtf( int len, Tcl_DString *dsPtr) { -#if TCL_UTF_MAX > 3 - char *p; - int size; - if (len > 0) { len /= 2; + } else if (len == -1) { + len = wcslen((wchar_t *)string); } - size = WideCharToMultiByte(CP_UTF8, 0, string, len, 0, 0, NULL, NULL); Tcl_DStringInit(dsPtr); - Tcl_DStringSetLength(dsPtr, size+1); - p = (char *)Tcl_DStringValue(dsPtr); - WideCharToMultiByte(CP_UTF8, 0, string, len, p, size, NULL, NULL); - if (len == -1) --size; /* account for 0-byte at string end */ - Tcl_DStringSetLength(dsPtr, size); - p[size] = 0; - return p; -#else - if (!winTCharEncoding) { - winTCharEncoding = Tcl_GetEncoding(0, "unicode"); - } - return Tcl_ExternalToUtfDString(winTCharEncoding, - string, len, dsPtr); -#endif + return Tcl_UniCharToUtfDString((Tcl_UniChar *)string, len, dsPtr); } #if defined(TCL_WIDE_INT_IS_LONG) diff --git a/win/tclWin32Dll.c b/win/tclWin32Dll.c index a85dd0c..ca1c856 100644 --- a/win/tclWin32Dll.c +++ b/win/tclWin32Dll.c @@ -33,10 +33,6 @@ static int platformId; /* Running under NT, or 95/98? */ #define cpuid __asm __emit 0fh __asm __emit 0a2h #endif -#if TCL_UTF_MAX < 4 -static Tcl_Encoding winTCharEncoding = NULL; -#endif - /* * The following declaration is for the VC++ DLL entry point. */ @@ -201,8 +197,6 @@ TclWinInit( if (platformId == VER_PLATFORM_WIN32_WINDOWS) { Tcl_Panic("Windows 9x is not a supported platform"); } - - TclWinResetInterfaces(); } /* @@ -282,10 +276,6 @@ TclWinNoBackslash( void TclpSetInterfaces(void) { -#if TCL_UTF_MAX < 4 - TclWinResetInterfaces(); - winTCharEncoding = Tcl_GetEncoding(NULL, "unicode"); -#endif } /* @@ -313,8 +303,6 @@ TclWinEncodingsCleanup(void) { MountPointMap *dlIter, *dlIter2; - TclWinResetInterfaces(); - /* * Clean up the mount point map. */ @@ -348,12 +336,6 @@ TclWinEncodingsCleanup(void) void TclWinResetInterfaces(void) { -#if TCL_UTF_MAX < 4 - if (winTCharEncoding != NULL) { - Tcl_FreeEncoding(winTCharEncoding); - winTCharEncoding = NULL; - } -#endif } /* @@ -565,22 +547,8 @@ Tcl_WinUtfToTChar( Tcl_DString *dsPtr) /* Uninitialized or free DString in which the * converted string is stored. */ { -#if TCL_UTF_MAX > 3 - TCHAR *wp; - int size = MultiByteToWideChar(CP_UTF8, 0, string, len, 0, 0); - Tcl_DStringInit(dsPtr); - Tcl_DStringSetLength(dsPtr, 2*size+2); - wp = (TCHAR *)Tcl_DStringValue(dsPtr); - MultiByteToWideChar(CP_UTF8, 0, string, len, wp, size+1); - if (len == -1) --size; /* account for 0-byte at string end */ - Tcl_DStringSetLength(dsPtr, 2*size); - wp[size] = 0; - return wp; -#else - return (TCHAR *) Tcl_UtfToExternalDString(winTCharEncoding, - string, len, dsPtr); -#endif + return Tcl_UtfToUniCharDString(string, len, dsPtr); } char * @@ -591,26 +559,13 @@ Tcl_WinTCharToUtf( Tcl_DString *dsPtr) /* Uninitialized or free DString in which the * converted string is stored. */ { -#if TCL_UTF_MAX > 3 - char *p; - int size; - if (len > 0) { len /= 2; + } else if (len < 0) { + len = wcslen(string); } - size = WideCharToMultiByte(CP_UTF8, 0, string, len, 0, 0, NULL, NULL); Tcl_DStringInit(dsPtr); - Tcl_DStringSetLength(dsPtr, size+1); - p = (char *)Tcl_DStringValue(dsPtr); - WideCharToMultiByte(CP_UTF8, 0, string, len, p, size, NULL, NULL); - if (len == -1) --size; /* account for 0-byte at string end */ - Tcl_DStringSetLength(dsPtr, size); - p[size] = 0; - return p; -#else - return Tcl_ExternalToUtfDString(winTCharEncoding, - (const char *) string, len, dsPtr); -#endif + return Tcl_UniCharToUtfDString(string, len, dsPtr); } /* -- cgit v0.12 From 0efc494b97376d9e9c735047787b9b329b767931 Mon Sep 17 00:00:00 2001 From: dkf Date: Sat, 6 Oct 2018 06:22:57 +0000 Subject: More tidying up of zipfs --- generic/tclZipfs.c | 990 +++++++++++++++++++++++++++-------------------------- 1 file changed, 506 insertions(+), 484 deletions(-) diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c index 4e6cd8a..c66a447 100644 --- a/generic/tclZipfs.c +++ b/generic/tclZipfs.c @@ -1,10 +1,10 @@ /* * tclZipfs.c -- * - * Implementation of the ZIP filesystem used in TIP 430 - * Adapted from the implentation for AndroWish. + * Implementation of the ZIP filesystem used in TIP 430 + * Adapted from the implentation for AndroWish. * - * Coptright (c) 2016-2017 Sean Woods + * Copyright (c) 2016-2017 Sean Woods * Copyright (c) 2013-2015 Christian Werner * * See the file "license.terms" for information on usage and redistribution of @@ -120,21 +120,28 @@ #define ZIP_PASSWORD_END_SIG 0x5a5a4b50 -/* Macro to report errors only if an interp is present */ +/* Macros to report errors only if an interp is present */ #define ZIPFS_ERROR(interp,errstr) \ do { \ if (interp != NULL) { \ Tcl_SetObjResult(interp, Tcl_NewStringObj(errstr, -1)); \ } \ } while (0) +#define ZIPFS_POSIX_ERROR(interp,errstr) \ + do { \ + if (interp != NULL) { \ + Tcl_SetObjResult(interp, Tcl_ObjPrintf( \ + "%s: %s", errstr, Tcl_PosixError(interp))); \ + } \ + } while (0) /* * Macros to read and write 16 and 32 bit integers from/to ZIP archives. */ -#define zip_read_int(p) \ +#define ZipReadInt(p) \ ((p)[0] | ((p)[1] << 8) | ((p)[2] << 16) | ((p)[3] << 24)) -#define zip_read_short(p) \ +#define ZipReadShort(p) \ ((p)[0] | ((p)[1] << 8)) #define zip_write_int(p, v) \ @@ -351,7 +358,7 @@ static int Zip_FSMatchInDirectoryProc(Tcl_Interp *interp, const char *pattern, Tcl_GlobTypeData *types); static Tcl_Obj * Zip_FSListVolumesProc(void); static const char *const *Zip_FSFileAttrStringsProc(Tcl_Obj *pathPtr, - Tcl_Obj** objPtrRef); + Tcl_Obj **objPtrRef); static int Zip_FSFileAttrsGetProc(Tcl_Interp *interp, int index, Tcl_Obj *pathPtr, Tcl_Obj **objPtrRef); static int Zip_FSFileAttrsSetProc(Tcl_Interp *interp, int index, @@ -369,7 +376,7 @@ MODULE_SCOPE const Tcl_Filesystem zipfsFilesystem; const Tcl_Filesystem zipfsFilesystem = { "zipfs", - sizeof (Tcl_Filesystem), + sizeof(Tcl_Filesystem), TCL_FILESYSTEM_VERSION_2, Zip_FSPathInFilesystemProc, NULL, /* dupInternalRepProc */ @@ -398,20 +405,26 @@ const Tcl_Filesystem zipfsFilesystem = { NULL, /* lstatProc */ (Tcl_FSLoadFileProc *) Zip_FSLoadFile, NULL, /* getCwdProc */ - NULL, /* chdirProc*/ + NULL, /* chdirProc */ }; + +/* + * Miscellaneous constants. + */ + +#define ERROR_LENGTH ((size_t) -1) /* *------------------------------------------------------------------------- * * ReadLock, WriteLock, Unlock -- * - * POSIX like rwlock functions to support multiple readers and single - * writer on internal structs. + * POSIX like rwlock functions to support multiple readers and single + * writer on internal structs. * - * Limitations: - * - a read lock cannot be promoted to a write lock - * - a write lock may not be nested + * Limitations: + * - a read lock cannot be promoted to a write lock + * - a write lock may not be nested * *------------------------------------------------------------------------- */ @@ -489,7 +502,7 @@ DosTimeDate( time_t ret; memset(&tm, 0, sizeof(struct tm)); - tm.tm_year = (((dosDate & 0xfe00) >> 9) + 80); + tm.tm_year = ((dosDate & 0xfe00) >> 9) + 80; tm.tm_mon = ((dosDate & 0x1e0) >> 5) - 1; tm.tm_mday = dosDate & 0x1f; tm.tm_hour = (dosTime & 0xf800) >> 11; @@ -647,10 +660,8 @@ CanonicalPath( strncmp(tail, ZIPFS_VOLUME, ZIPFS_VOLUME_LEN) == 0) { isvfs = 2; } - if (isvfs != 1) { - if ((root[0] == '/') && (root[1] == '/')) { - isunc = 1; - } + if (isvfs != 1 && (root[0] == '/') && (root[1] == '/')) { + isunc = 1; } } @@ -738,7 +749,7 @@ CanonicalPath( continue; } if ((c3 == '.') - && ((path[i + 3] == '/') || (path [i + 3] == '\0'))) { + && ((path[i + 3] == '/') || (path[i + 3] == '\0'))) { i += 2; while ((j > 0) && (path[j - 1] != '/')) { j--; @@ -795,8 +806,6 @@ ZipFSLookup( return z; } -#ifdef NEVER_USED - /* *------------------------------------------------------------------------- * @@ -814,27 +823,24 @@ ZipFSLookup( *------------------------------------------------------------------------- */ +#ifdef NEVER_USED static int ZipFSLookupMount( char *filename) { Tcl_HashEntry *hPtr; Tcl_HashSearch search; - ZipFile *zf; - int match = 0; hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); while (hPtr != NULL) { - if ((zf = (ZipFile *) Tcl_GetHashValue(hPtr)) == NULL) { - continue; - } - if (strcmp(zf->mntpt, filename) == 0) { - match = 1; - break; + ZipFile *zf = Tcl_GetHashValue(hPtr); + + if (zf != NULL && strcmp(zf->mntpt, filename) == 0) { + return 1; } hPtr = Tcl_NextHashEntry(&search); } - return match; + return 0; } #endif /* NEVER_USED */ @@ -857,7 +863,7 @@ ZipFSLookupMount( static void ZipFSCloseArchive( - Tcl_Interp *interp, + Tcl_Interp *interp, /* Current interpreter. */ ZipFile *zf) { if (zf->namelen) { @@ -920,7 +926,7 @@ ZipFSCloseArchive( static int ZipFS_Find_TOC( - Tcl_Interp *interp, + Tcl_Interp *interp, /* Current interpreter. NULLable. */ int needZip, ZipFile *zf) { @@ -930,7 +936,7 @@ ZipFS_Find_TOC( p = zf->data + zf->length - ZIP_CENTRAL_END_LEN; while (p >= zf->data) { if (*p == (ZIP_CENTRAL_END_SIG & 0xFF)) { - if (zip_read_int(p) == ZIP_CENTRAL_END_SIG) { + if (ZipReadInt(p) == ZIP_CENTRAL_END_SIG) { break; } p -= ZIP_SIG_LEN; @@ -946,7 +952,7 @@ ZipFS_Find_TOC( ZIPFS_ERROR(interp, "wrong end signature"); goto error; } - zf->nfiles = zip_read_short(p + ZIP_CENTRAL_ENTS_OFFS); + zf->nfiles = ZipReadShort(p + ZIP_CENTRAL_ENTS_OFFS); if (zf->nfiles == 0) { if (!needZip) { zf->baseoffs = zf->baseoffsp = zf->length; @@ -955,10 +961,10 @@ ZipFS_Find_TOC( ZIPFS_ERROR(interp, "empty archive"); goto error; } - q = zf->data + zip_read_int(p + ZIP_CENTRAL_DIRSTART_OFFS); - p -= zip_read_int(p + ZIP_CENTRAL_DIRSIZE_OFFS); + q = zf->data + ZipReadInt(p + ZIP_CENTRAL_DIRSTART_OFFS); + p -= ZipReadInt(p + ZIP_CENTRAL_DIRSIZE_OFFS); if ((p < zf->data) || (p > zf->data + zf->length) - || (q < zf->data) || (q > (zf->data + zf->length))) { + || (q < zf->data) || (q > zf->data + zf->length)) { if (!needZip) { zf->baseoffs = zf->baseoffsp = zf->length; return TCL_OK; @@ -976,17 +982,17 @@ ZipFS_Find_TOC( ZIPFS_ERROR(interp, "wrong header length"); goto error; } - if (zip_read_int(q) != ZIP_CENTRAL_HEADER_SIG) { + if (ZipReadInt(q) != ZIP_CENTRAL_HEADER_SIG) { ZIPFS_ERROR(interp, "wrong header signature"); goto error; } - pathlen = zip_read_short(q + ZIP_CENTRAL_PATHLEN_OFFS); - comlen = zip_read_short(q + ZIP_CENTRAL_FCOMMENTLEN_OFFS); - extra = zip_read_short(q + ZIP_CENTRAL_EXTRALEN_OFFS); + pathlen = ZipReadShort(q + ZIP_CENTRAL_PATHLEN_OFFS); + comlen = ZipReadShort(q + ZIP_CENTRAL_FCOMMENTLEN_OFFS); + extra = ZipReadShort(q + ZIP_CENTRAL_EXTRALEN_OFFS); q += pathlen + comlen + extra + ZIP_CENTRAL_HEADER_LEN; } q = zf->data + zf->baseoffs; - if ((zf->baseoffs >= 6) && (zip_read_int(q - 4) == ZIP_PASSWORD_END_SIG)) { + if ((zf->baseoffs >= 6) && (ZipReadInt(q - 4) == ZIP_PASSWORD_END_SIG)) { i = q[-5]; if (q - 5 - i > zf->data) { zf->pwbuf[0] = i; @@ -1025,10 +1031,10 @@ ZipFS_Find_TOC( static int ZipFSOpenArchive( - Tcl_Interp *interp, - const char *zipname, - int needZip, - ZipFile *zf) + Tcl_Interp *interp, /* Current interpreter. NULLable. */ + const char *zipname, /* Path to ZIP file to open. */ + int needZip, + ZipFile *zf) { size_t i; ClientData handle; @@ -1046,22 +1052,25 @@ ZipFSOpenArchive( zf->baseoffs = zf->baseoffsp = 0; zf->tofree = NULL; zf->pwbuf[0] = 0; - zf->chan = Tcl_OpenFileChannel(interp, zipname, "r", 0); + zf->chan = Tcl_OpenFileChannel(interp, zipname, "rb", 0); if (zf->chan == NULL) { return TCL_ERROR; } if (Tcl_GetChannelHandle(zf->chan, TCL_READABLE, &handle) != TCL_OK) { - if (Tcl_SetChannelOption(interp, zf->chan, "-translation", - "binary") != TCL_OK) { + zf->length = Tcl_Seek(zf->chan, 0, SEEK_END); + if (zf->length == ERROR_LENGTH) { + ZIPFS_POSIX_ERROR(interp, "seek error"); goto error; } - zf->length = Tcl_Seek(zf->chan, 0, SEEK_END); if ((zf->length - ZIP_CENTRAL_END_LEN) > (64 * 1024 * 1024 - ZIP_CENTRAL_END_LEN)) { ZIPFS_ERROR(interp, "illegal file size"); goto error; } - Tcl_Seek(zf->chan, 0, SEEK_SET); + if (Tcl_Seek(zf->chan, 0, SEEK_SET) == -1) { + ZIPFS_POSIX_ERROR(interp, "seek error"); + goto error; + } zf->tofree = zf->data = (unsigned char *) Tcl_AttemptAlloc(zf->length); if (zf->tofree == NULL) { ZIPFS_ERROR(interp, "out of memory"); @@ -1069,7 +1078,7 @@ ZipFSOpenArchive( } i = Tcl_Read(zf->chan, (char *) zf->data, zf->length); if (i != zf->length) { - ZIPFS_ERROR(interp, "file read error"); + ZIPFS_POSIX_ERROR(interp, "file read error"); goto error; } Tcl_Close(interp, zf->chan); @@ -1085,31 +1094,31 @@ ZipFSOpenArchive( readSuccessful = (zf->length != (size_t) INVALID_FILE_SIZE); # endif /* _WIN64 */ if (!readSuccessful || (zf->length < ZIP_CENTRAL_END_LEN)) { - ZIPFS_ERROR(interp, "invalid file size"); + ZIPFS_POSIX_ERROR(interp, "invalid file size"); goto error; } zf->mh = CreateFileMapping((HANDLE) handle, 0, PAGE_READONLY, 0, zf->length, 0); if (zf->mh == INVALID_HANDLE_VALUE) { - ZIPFS_ERROR(interp, "file mapping failed"); + ZIPFS_POSIX_ERROR(interp, "file mapping failed"); goto error; } zf->data = MapViewOfFile(zf->mh, FILE_MAP_READ, 0, 0, zf->length); if (zf->data == NULL) { - ZIPFS_ERROR(interp, "file mapping failed"); + ZIPFS_POSIX_ERROR(interp, "file mapping failed"); goto error; } #else /* !_WIN32 */ zf->length = lseek(PTR2INT(handle), 0, SEEK_END); - if ((zf->length == (size_t)-1) || (zf->length < ZIP_CENTRAL_END_LEN)) { - ZIPFS_ERROR(interp, "invalid file size"); + if (zf->length == ERROR_LENGTH || zf->length < ZIP_CENTRAL_END_LEN) { + ZIPFS_POSIX_ERROR(interp, "invalid file size"); goto error; } lseek(PTR2INT(handle), 0, SEEK_SET); zf->data = (unsigned char *) mmap(0, zf->length, PROT_READ, MAP_FILE | MAP_PRIVATE, PTR2INT(handle), 0); if (zf->data == MAP_FAILED) { - ZIPFS_ERROR(interp, "file mapping failed"); + ZIPFS_POSIX_ERROR(interp, "file mapping failed"); goto error; } #endif /* _WIN32 */ @@ -1126,23 +1135,26 @@ ZipFSOpenArchive( * * ZipFSRootNode -- * - * This function generates the root node for a ZIPFS filesystem + * This function generates the root node for a ZIPFS filesystem. * * Results: - * TCL_OK on success, TCL_ERROR otherwise with an error message - * placed into the given "interp" if it is not NULL. + * TCL_OK on success, TCL_ERROR otherwise with an error message placed + * into the given "interp" if it is not NULL. * * Side effects: + * ... + * *------------------------------------------------------------------------- */ static int ZipFS_Catalogue_Filesystem( - Tcl_Interp *interp, + Tcl_Interp *interp, /* Current interpreter. NULLable. */ ZipFile *zf0, - const char *mntpt, - const char *passwd, - const char *zipname) + const char *mntpt, /* Mount point path. */ + const char *passwd, /* Password for opening the ZIP, or NULL if + * the ZIP is unprotected. */ + const char *zipname) /* Path to ZIP file to build a catalog of. */ { int pwlen, isNew; size_t i; @@ -1184,16 +1196,16 @@ ZipFS_Catalogue_Filesystem( } hPtr = Tcl_CreateHashEntry(&ZipFS.zipHash, mntpt, &isNew); if (!isNew) { - zf = (ZipFile *) Tcl_GetHashValue(hPtr); + zf = Tcl_GetHashValue(hPtr); if (interp != NULL) { - Tcl_AppendResult(interp, zf->name, " is already mounted on ", - mntpt, (char *) NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "%s is already mounted on %s", zf->name, mntpt)); } Unlock(); ZipFSCloseArchive(interp, zf0); return TCL_ERROR; } - zf = (ZipFile *) Tcl_AttemptAlloc(sizeof (*zf) + strlen(mntpt) + 1); + zf = (ZipFile *) Tcl_AttemptAlloc(sizeof(ZipFile) + strlen(mntpt) + 1); if (zf == NULL) { if (interp != NULL) { Tcl_AppendResult(interp, "out of memory", (char *) NULL); @@ -1259,9 +1271,9 @@ ZipFS_Catalogue_Filesystem( unsigned char *lq, *gq = NULL; char *fullpath, *path; - pathlen = zip_read_short(q + ZIP_CENTRAL_PATHLEN_OFFS); - comlen = zip_read_short(q + ZIP_CENTRAL_FCOMMENTLEN_OFFS); - extra = zip_read_short(q + ZIP_CENTRAL_EXTRALEN_OFFS); + pathlen = ZipReadShort(q + ZIP_CENTRAL_PATHLEN_OFFS); + comlen = ZipReadShort(q + ZIP_CENTRAL_FCOMMENTLEN_OFFS); + extra = ZipReadShort(q + ZIP_CENTRAL_EXTRALEN_OFFS); Tcl_DStringSetLength(&ds, 0); Tcl_DStringAppend(&ds, (char *) q + ZIP_CENTRAL_HEADER_LEN, pathlen); path = Tcl_DStringValue(&ds); @@ -1274,22 +1286,22 @@ ZipFS_Catalogue_Filesystem( goto nextent; } lq = zf->data + zf->baseoffs - + zip_read_int(q + ZIP_CENTRAL_LOCALHDR_OFFS); + + ZipReadInt(q + ZIP_CENTRAL_LOCALHDR_OFFS); if ((lq < zf->data) || (lq > zf->data + zf->length)) { goto nextent; } - nbcompr = zip_read_int(lq + ZIP_LOCAL_COMPLEN_OFFS); + nbcompr = ZipReadInt(lq + ZIP_LOCAL_COMPLEN_OFFS); if (!isdir && (nbcompr == 0) - && (zip_read_int(lq + ZIP_LOCAL_UNCOMPLEN_OFFS) == 0) - && (zip_read_int(lq + ZIP_LOCAL_CRC32_OFFS) == 0)) { + && (ZipReadInt(lq + ZIP_LOCAL_UNCOMPLEN_OFFS) == 0) + && (ZipReadInt(lq + ZIP_LOCAL_CRC32_OFFS) == 0)) { gq = q; - nbcompr = zip_read_int(gq + ZIP_CENTRAL_COMPLEN_OFFS); + nbcompr = ZipReadInt(gq + ZIP_CENTRAL_COMPLEN_OFFS); } offs = (lq - zf->data) + ZIP_LOCAL_HEADER_LEN - + zip_read_short(lq + ZIP_LOCAL_PATHLEN_OFFS) - + zip_read_short(lq + ZIP_LOCAL_EXTRALEN_OFFS); - if ((offs + nbcompr) > zf->length) { + + ZipReadShort(lq + ZIP_LOCAL_PATHLEN_OFFS) + + ZipReadShort(lq + ZIP_LOCAL_EXTRALEN_OFFS); + if (offs + nbcompr > zf->length) { goto nextent; } if (!isdir && (mntpt[0] == '\0') && !CountSlashes(path)) { @@ -1333,23 +1345,23 @@ ZipFS_Catalogue_Filesystem( z->depth = CountSlashes(fullpath); z->zipfile = zf; z->isdir = isdir; - z->isenc = (zip_read_short(lq + ZIP_LOCAL_FLAGS_OFFS) & 1) + z->isenc = (ZipReadShort(lq + ZIP_LOCAL_FLAGS_OFFS) & 1) && (nbcompr > 12); z->offset = offs; if (gq != NULL) { - z->crc32 = zip_read_int(gq + ZIP_CENTRAL_CRC32_OFFS); - dosDate = zip_read_short(gq + ZIP_CENTRAL_MDATE_OFFS); - dosTime = zip_read_short(gq + ZIP_CENTRAL_MTIME_OFFS); + z->crc32 = ZipReadInt(gq + ZIP_CENTRAL_CRC32_OFFS); + dosDate = ZipReadShort(gq + ZIP_CENTRAL_MDATE_OFFS); + dosTime = ZipReadShort(gq + ZIP_CENTRAL_MTIME_OFFS); z->timestamp = DosTimeDate(dosDate, dosTime); - z->nbyte = zip_read_int(gq + ZIP_CENTRAL_UNCOMPLEN_OFFS); - z->cmeth = zip_read_short(gq + ZIP_CENTRAL_COMPMETH_OFFS); + z->nbyte = ZipReadInt(gq + ZIP_CENTRAL_UNCOMPLEN_OFFS); + z->cmeth = ZipReadShort(gq + ZIP_CENTRAL_COMPMETH_OFFS); } else { - z->crc32 = zip_read_int(lq + ZIP_LOCAL_CRC32_OFFS); - dosDate = zip_read_short(lq + ZIP_LOCAL_MDATE_OFFS); - dosTime = zip_read_short(lq + ZIP_LOCAL_MTIME_OFFS); + z->crc32 = ZipReadInt(lq + ZIP_LOCAL_CRC32_OFFS); + dosDate = ZipReadShort(lq + ZIP_LOCAL_MDATE_OFFS); + dosTime = ZipReadShort(lq + ZIP_LOCAL_MTIME_OFFS); z->timestamp = DosTimeDate(dosDate, dosTime); - z->nbyte = zip_read_int(lq + ZIP_LOCAL_UNCOMPLEN_OFFS); - z->cmeth = zip_read_short(lq + ZIP_LOCAL_COMPMETH_OFFS); + z->nbyte = ZipReadInt(lq + ZIP_LOCAL_UNCOMPLEN_OFFS); + z->cmeth = ZipReadShort(lq + ZIP_LOCAL_COMPMETH_OFFS); } z->nbytecompr = nbcompr; z->data = NULL; @@ -1377,8 +1389,8 @@ ZipFS_Catalogue_Filesystem( end = strrchr(dir, '/'); while ((end != NULL) && (end != dir)) { Tcl_DStringSetLength(&ds, end - dir); - hPtr = Tcl_FindHashEntry(&ZipFS.fileHash, dir); - if (hPtr != NULL) { + hPtr = Tcl_CreateHashEntry(&ZipFS.fileHash, dir, &isNew); + if (!isNew) { break; } zd = (ZipEntry *) Tcl_Alloc(sizeof(ZipEntry)); @@ -1394,19 +1406,13 @@ ZipFS_Catalogue_Filesystem( zd->nbyte = zd->nbytecompr = 0; zd->cmeth = ZIP_COMPMETH_STORED; zd->data = NULL; - hPtr = Tcl_CreateHashEntry(&ZipFS.fileHash, dir, &isNew); - if (!isNew) { - /* should not happen but skip it anyway */ - Tcl_Free((char *) zd); - } else { - Tcl_SetHashValue(hPtr, zd); - zd->name = Tcl_GetHashKey(&ZipFS.fileHash, hPtr); - zd->next = zf->entries; - zf->entries = zd; - if ((mntpt[0] == '\0') && (zd->depth == 1)) { - zd->tnext = zf->topents; - zf->topents = zd; - } + Tcl_SetHashValue(hPtr, zd); + zd->name = Tcl_GetHashKey(&ZipFS.fileHash, hPtr); + zd->next = zf->entries; + zf->entries = zd; + if ((mntpt[0] == '\0') && (zd->depth == 1)) { + zd->tnext = zf->topents; + zf->topents = zd; } end = strrchr(dir, '/'); } @@ -1463,10 +1469,11 @@ TclZipfs_C_Init(void) int TclZipfs_Mount( - Tcl_Interp *interp, - const char *mntpt, - const char *zipname, - const char *passwd) + Tcl_Interp *interp, /* Current interpreter. NULLable. */ + const char *mntpt, /* Mount point path. */ + const char *zipname, /* Path to ZIP file to mount. */ + const char *passwd) /* Password for opening the ZIP, or NULL if + * the ZIP is unprotected. */ { int i, pwlen; ZipFile *zf; @@ -1483,7 +1490,8 @@ TclZipfs_Mount( i = 0; hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); while (hPtr != NULL) { - if ((zf = (ZipFile *) Tcl_GetHashValue(hPtr)) != NULL) { + zf = Tcl_GetHashValue(hPtr); + if (zf != NULL) { if (interp != NULL) { Tcl_AppendElement(interp, zf->mntpt); Tcl_AppendElement(interp, zf->name); @@ -1501,11 +1509,11 @@ TclZipfs_Mount( if (zipname == NULL) { if (interp != NULL) { - Tcl_HashEntry *hPtr; + Tcl_HashEntry *hPtr = Tcl_FindHashEntry(&ZipFS.zipHash, mntpt); - hPtr = Tcl_FindHashEntry(&ZipFS.zipHash, mntpt); if (hPtr != NULL) { - if ((zf = Tcl_GetHashValue(hPtr)) != NULL) { + zf = Tcl_GetHashValue(hPtr); + if (zf != NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj(zf->name, -1)); } } @@ -1525,7 +1533,7 @@ TclZipfs_Mount( return TCL_ERROR; } } - zf = (ZipFile *) Tcl_AttemptAlloc(sizeof (*zf) + strlen(mntpt) + 1); + zf = (ZipFile *) Tcl_AttemptAlloc(sizeof(ZipFile) + strlen(mntpt) + 1); if (zf == NULL) { if (interp != NULL) { Tcl_AppendResult(interp, "out of memory", (char *) NULL); @@ -1558,13 +1566,12 @@ TclZipfs_Mount( int TclZipfs_Mount_Buffer( - Tcl_Interp *interp, - const char *mntpt, + Tcl_Interp *interp, /* Current interpreter. NULLable. */ + const char *mntpt, /* Mount point path. */ unsigned char *data, size_t datalen, int copy) { - int i; ZipFile *zf; ReadLock(); @@ -1574,32 +1581,33 @@ TclZipfs_Mount_Buffer( if (mntpt == NULL) { Tcl_HashEntry *hPtr; Tcl_HashSearch search; - int ret = TCL_OK; + int ret = (interp ? TCL_BREAK : TCL_OK); - i = 0; hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); while (hPtr != NULL) { - if ((zf = (ZipFile *) Tcl_GetHashValue(hPtr)) != NULL) { + zf = Tcl_GetHashValue(hPtr); + if (zf != NULL) { if (interp != NULL) { Tcl_AppendElement(interp, zf->mntpt); Tcl_AppendElement(interp, zf->name); + } else { + ret = TCL_OK; + /* + * Stop searching here if we're not returning a list. + */ + break; } - ++i; } hPtr = Tcl_NextHashEntry(&search); } - if (interp == NULL) { - ret = (i > 0) ? TCL_OK : TCL_BREAK; - } Unlock(); return ret; } if (data == NULL) { if (interp != NULL) { - Tcl_HashEntry *hPtr; + Tcl_HashEntry *hPtr = Tcl_FindHashEntry(&ZipFS.zipHash, mntpt); - hPtr = Tcl_FindHashEntry(&ZipFS.zipHash, mntpt); if (hPtr != NULL) { zf = Tcl_GetHashValue(hPtr); if (zf != NULL) { @@ -1660,8 +1668,8 @@ TclZipfs_Mount_Buffer( int TclZipfs_Unmount( - Tcl_Interp *interp, - const char *mntpt) + Tcl_Interp *interp, /* Current interpreter. NULLable. */ + const char *mntpt) /* Mount point path. */ { ZipFile *zf; ZipEntry *z, *znext; @@ -1688,7 +1696,7 @@ TclZipfs_Unmount( goto done; } - zf = (ZipFile *) Tcl_GetHashValue(hPtr); + zf = Tcl_GetHashValue(hPtr); if (zf->nopen > 0) { ZIPFS_ERROR(interp, "filesystem is busy"); ret = TCL_ERROR; @@ -1736,7 +1744,7 @@ TclZipfs_Unmount( static int ZipFSMountObjCmd( ClientData clientData, - Tcl_Interp *interp, + Tcl_Interp *interp, /* Current interpreter. */ int objc, Tcl_Obj *const objv[]) { @@ -1747,8 +1755,8 @@ ZipFSMountObjCmd( } return TclZipfs_Mount(interp, (objc > 1) ? Tcl_GetString(objv[1]) : NULL, - (objc > 2) ? Tcl_GetString(objv[2]) : NULL, - (objc > 3) ? Tcl_GetString(objv[3]) : NULL); + (objc > 2) ? Tcl_GetString(objv[2]) : NULL, + (objc > 3) ? Tcl_GetString(objv[3]) : NULL); } /* @@ -1770,11 +1778,11 @@ ZipFSMountObjCmd( static int ZipFSMountBufferObjCmd( ClientData clientData, - Tcl_Interp *interp, + Tcl_Interp *interp, /* Current interpreter. */ int objc, Tcl_Obj *const objv[]) { - const char *mntpt; + const char *mntpt; /* Mount point path. */ unsigned char *data; int length; @@ -1783,28 +1791,21 @@ ZipFSMountBufferObjCmd( return TCL_ERROR; } if (objc < 2) { - int i; Tcl_HashEntry *hPtr; Tcl_HashSearch search; int ret = TCL_OK; - ZipFile *zf; ReadLock(); - i = 0; hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); while (hPtr != NULL) { - if ((zf = (ZipFile *) Tcl_GetHashValue(hPtr)) != NULL) { - if (interp != NULL) { - Tcl_AppendElement(interp, zf->mntpt); - Tcl_AppendElement(interp, zf->name); - } - ++i; + ZipFile *zf = Tcl_GetHashValue(hPtr); + + if (zf != NULL) { + Tcl_AppendElement(interp, zf->mntpt); + Tcl_AppendElement(interp, zf->name); } hPtr = Tcl_NextHashEntry(&search); } - if (interp == NULL) { - ret = (i > 0) ? TCL_OK : TCL_BREAK; - } Unlock(); return ret; } @@ -1812,15 +1813,14 @@ ZipFSMountBufferObjCmd( mntpt = Tcl_GetString(objv[1]); if (objc < 3) { Tcl_HashEntry *hPtr; - ZipFile *zf; - if (interp != NULL) { - hPtr = Tcl_FindHashEntry(&ZipFS.zipHash, mntpt); - if (hPtr != NULL) { - zf = Tcl_GetHashValue(hPtr); - if (zf != NULL) { - Tcl_SetObjResult(interp, Tcl_NewStringObj(zf->name, -1)); - } + ReadLock(); + hPtr = Tcl_FindHashEntry(&ZipFS.zipHash, mntpt); + if (hPtr != NULL) { + ZipFile *zf = Tcl_GetHashValue(hPtr); + + if (zf != NULL) { + Tcl_SetObjResult(interp, Tcl_NewStringObj(zf->name, -1)); } } Unlock(); @@ -1850,7 +1850,7 @@ ZipFSMountBufferObjCmd( static int ZipFSRootObjCmd( ClientData clientData, - Tcl_Interp *interp, + Tcl_Interp *interp, /* Current interpreter. */ int objc, Tcl_Obj *const objv[]) { @@ -1877,7 +1877,7 @@ ZipFSRootObjCmd( static int ZipFSUnmountObjCmd( ClientData clientData, - Tcl_Interp *interp, + Tcl_Interp *interp, /* Current interpreter. */ int objc, Tcl_Obj *const objv[]) { @@ -1908,7 +1908,7 @@ ZipFSUnmountObjCmd( static int ZipFSMkKeyObjCmd( ClientData clientData, - Tcl_Interp *interp, + Tcl_Interp *interp, /* Current interpreter. */ int objc, Tcl_Obj *const objv[]) { @@ -1968,11 +1968,12 @@ ZipFSMkKeyObjCmd( static int ZipAddFile( - Tcl_Interp *interp, + Tcl_Interp *interp, /* Current interpreter. */ const char *path, const char *name, Tcl_Channel out, - const char *passwd, + const char *passwd, /* Password for encoding the file, or NULL if + * the file is to be unprotected. */ char *buf, int bufsize, Tcl_HashTable *fileHash) @@ -1998,16 +1999,15 @@ ZipAddFile( } zpathlen = strlen(zpath); if (zpathlen + ZIP_CENTRAL_HEADER_LEN > bufsize) { - Tcl_AppendResult(interp, "path too long for \"", path, "\"", - (char *) NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "path too long for \"%s\"", path)); return TCL_ERROR; } - in = Tcl_OpenFileChannel(interp, path, "r", 0); - if ((in == NULL) || Tcl_SetChannelOption(interp, in, - "-translation", "binary") != TCL_OK) { + in = Tcl_OpenFileChannel(interp, path, "rb", 0); + if (in == NULL) { #ifdef _WIN32 - /* hopefully a directory */ - if (strcmp("permission denied", Tcl_PosixError(interp)) == 0) { + /* hopefully a directory */ + if (strcmp("permission denied", Tcl_PosixError(interp)) == 0) { Tcl_Close(interp, in); return TCL_OK; } @@ -2031,22 +2031,19 @@ ZipAddFile( crc = crc32(crc, (unsigned char *) buf, len); nbyte += len; } - if (len == (size_t)-1) { - if (nbyte == 0) { - if (strcmp("illegal operation on a directory", - Tcl_PosixError(interp)) == 0) { - Tcl_Close(interp, in); - return TCL_OK; - } + if (len == ERROR_LENGTH) { + if (nbyte == 0 && errno == EISDIR) { + Tcl_Close(interp, in); + return TCL_OK; } - Tcl_AppendResult(interp, "read error on \"", path, "\"", - (char *) NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf("read error on \"%s\": %s", + path, Tcl_PosixError(interp))); Tcl_Close(interp, in); return TCL_ERROR; } if (Tcl_Seek(in, 0, SEEK_SET) == -1) { - Tcl_AppendResult(interp, "seek error on \"", path, "\"", - (char *) NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf("seek error on \"%s\": %s", + path, Tcl_PosixError(interp))); Tcl_Close(interp, in); return TCL_ERROR; } @@ -2054,9 +2051,10 @@ ZipAddFile( memset(buf, '\0', ZIP_LOCAL_HEADER_LEN); memcpy(buf + ZIP_LOCAL_HEADER_LEN, zpath, zpathlen); len = zpathlen + ZIP_LOCAL_HEADER_LEN; - if ((size_t)Tcl_Write(out, buf, len) != len) { + if ((size_t) Tcl_Write(out, buf, len) != len) { wrerr: - Tcl_AppendResult(interp, "write error", (char *) NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "write error on %s: %s", path, Tcl_PosixError(interp))); Tcl_Close(interp, in); return TCL_ERROR; } @@ -2083,55 +2081,60 @@ ZipAddFile( init_keys(passwd, keys, crc32tab); for (i = 0; i < 12 - 2; i++) { - if (Tcl_EvalEx(interp, "expr int(rand() * 256) % 256", -1, - 0) != TCL_OK) { - Tcl_AppendResult(interp, "PRNG error", (char *) NULL); + double r; + + if (Tcl_EvalEx(interp, "::tcl::mathfunc::rand", -1, 0) != TCL_OK) { + Tcl_SetObjResult(interp, Tcl_ObjPrintf("PRNG error: %s", + Tcl_GetString(Tcl_GetObjResult(interp)))); Tcl_Close(interp, in); return TCL_ERROR; } ret = Tcl_GetObjResult(interp); - if (Tcl_GetIntFromObj(interp, ret, &ch) != TCL_OK) { + if (Tcl_GetDoubleFromObj(interp, ret, &r) != TCL_OK) { Tcl_Close(interp, in); return TCL_ERROR; } + ch = (int) (r * 256); kvbuf[i + 12] = (unsigned char) zencode(keys, crc32tab, ch, tmp); } Tcl_ResetResult(interp); init_keys(passwd, keys, crc32tab); for (i = 0; i < 12 - 2; i++) { - kvbuf[i] = (unsigned char) zencode(keys, crc32tab, kvbuf[i + 12], tmp); + kvbuf[i] = (unsigned char) + zencode(keys, crc32tab, kvbuf[i + 12], tmp); } kvbuf[i++] = (unsigned char) zencode(keys, crc32tab, crc >> 16, tmp); kvbuf[i++] = (unsigned char) zencode(keys, crc32tab, crc >> 24, tmp); len = Tcl_Write(out, (char *) kvbuf, 12); memset(kvbuf, 0, 24); if (len != 12) { - Tcl_AppendResult(interp, "write error", (char *) NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "write error on %s: %s", path, Tcl_PosixError(interp))); Tcl_Close(interp, in); return TCL_ERROR; } - memcpy(keys0, keys, sizeof (keys0)); + memcpy(keys0, keys, sizeof(keys0)); nbytecompr += 12; } Tcl_Flush(out); pos[2] = Tcl_Tell(out); cmeth = ZIP_COMPMETH_DEFLATED; - memset(&stream, 0, sizeof (stream)); + memset(&stream, 0, sizeof(z_stream)); stream.zalloc = Z_NULL; stream.zfree = Z_NULL; stream.opaque = Z_NULL; if (deflateInit2(&stream, 9, Z_DEFLATED, -15, 8, Z_DEFAULT_STRATEGY) != Z_OK) { - Tcl_AppendResult(interp, "compression init error on \"", path, "\"", - (char *) NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "compression init error on \"%s\"", path)); Tcl_Close(interp, in); return TCL_ERROR; } do { len = Tcl_Read(in, buf, bufsize); - if (len == (size_t)-1) { - Tcl_AppendResult(interp, "read error on \"", path, "\"", - (char *) NULL); + if (len == ERROR_LENGTH) { + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "read error on %s: %s", path, Tcl_PosixError(interp))); deflateEnd(&stream); Tcl_Close(interp, in); return TCL_ERROR; @@ -2140,17 +2143,17 @@ ZipAddFile( stream.next_in = (unsigned char *) buf; flush = Tcl_Eof(in) ? Z_FINISH : Z_NO_FLUSH; do { - stream.avail_out = sizeof (obuf); + stream.avail_out = sizeof(obuf); stream.next_out = (unsigned char *) obuf; len = deflate(&stream, flush); - if (len == (size_t)Z_STREAM_ERROR) { - Tcl_AppendResult(interp, "deflate error on \"", path, "\"", - (char *) NULL); + if (len == (size_t) Z_STREAM_ERROR) { + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "deflate error on %s", path)); deflateEnd(&stream); Tcl_Close(interp, in); return TCL_ERROR; } - olen = sizeof (obuf) - stream.avail_out; + olen = sizeof(obuf) - stream.avail_out; if (passwd != NULL) { size_t i; int tmp; @@ -2159,8 +2162,9 @@ ZipAddFile( obuf[i] = (char) zencode(keys, crc32tab, obuf[i], tmp); } } - if (olen && ((size_t)Tcl_Write(out, obuf, olen) != olen)) { - Tcl_AppendResult(interp, "write error", (char *) NULL); + if (olen && ((size_t) Tcl_Write(out, obuf, olen) != olen)) { + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "write error: %s", Tcl_PosixError(interp))); deflateEnd(&stream); Tcl_Close(interp, in); return TCL_ERROR; @@ -2181,15 +2185,17 @@ ZipAddFile( if (Tcl_Seek(out, pos[2], SEEK_SET) != pos[2]) { seekErr: Tcl_Close(interp, in); - Tcl_AppendResult(interp, "seek error", (char *) NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "seek error: %s", Tcl_PosixError(interp))); return TCL_ERROR; } nbytecompr = (passwd != NULL) ? 12 : 0; while (1) { len = Tcl_Read(in, buf, bufsize); - if (len == (size_t)-1) { - Tcl_AppendResult(interp, "read error on \"", path, "\"", - (char *) NULL); + if (len == ERROR_LENGTH) { + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "read error on \"%s\": %s", + path, Tcl_PosixError(interp))); Tcl_Close(interp, in); return TCL_ERROR; } else if (len == 0) { @@ -2203,8 +2209,9 @@ ZipAddFile( buf[i] = (char) zencode(keys0, crc32tab, buf[i], tmp); } } - if ((size_t)Tcl_Write(out, buf, len) != len) { - Tcl_AppendResult(interp, "write error", (char *) NULL); + if ((size_t) Tcl_Write(out, buf, len) != len) { + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "write error: %s", Tcl_PosixError(interp))); Tcl_Close(interp, in); return TCL_ERROR; } @@ -2217,7 +2224,7 @@ ZipAddFile( } Tcl_Close(interp, in); - z = (ZipEntry *) Tcl_Alloc(sizeof (*z)); + z = (ZipEntry *) Tcl_Alloc(sizeof(ZipEntry)); z->name = NULL; z->tnext = NULL; z->depth = 0; @@ -2233,8 +2240,8 @@ ZipAddFile( z->data = NULL; hPtr = Tcl_CreateHashEntry(fileHash, zpath, &isNew); if (!isNew) { - Tcl_AppendResult(interp, "non-unique path name \"", path, "\"", - (char *) NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "non-unique path name \"%s\"", path)); Tcl_Free((char *) z); return TCL_ERROR; } else { @@ -2260,20 +2267,23 @@ ZipAddFile( if (Tcl_Seek(out, pos[0], SEEK_SET) != pos[0]) { Tcl_DeleteHashEntry(hPtr); Tcl_Free((char *) z); - Tcl_AppendResult(interp, "seek error", (char *) NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "seek error: %s", Tcl_PosixError(interp))); return TCL_ERROR; } if (Tcl_Write(out, buf, ZIP_LOCAL_HEADER_LEN) != ZIP_LOCAL_HEADER_LEN) { Tcl_DeleteHashEntry(hPtr); Tcl_Free((char *) z); - Tcl_AppendResult(interp, "write error", (char *) NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "write error: %s", Tcl_PosixError(interp))); return TCL_ERROR; } Tcl_Flush(out); if (Tcl_Seek(out, pos[1], SEEK_SET) != pos[1]) { Tcl_DeleteHashEntry(hPtr); Tcl_Free((char *) z); - Tcl_AppendResult(interp, "seek error", (char *) NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "seek error: %s", Tcl_PosixError(interp))); return TCL_ERROR; } return TCL_OK; @@ -2301,7 +2311,7 @@ ZipAddFile( static int ZipFSMkZipOrImgObjCmd( ClientData clientData, - Tcl_Interp *interp, + Tcl_Interp *interp, /* Current interpreter. */ int isImg, int isList, int objc, @@ -2318,21 +2328,10 @@ ZipFSMkZipOrImgObjCmd( Tcl_HashTable fileHash; char *strip = NULL, *pw = NULL, pwbuf[264], buf[4096]; - if (isList) { - if ((objc < 3) || (objc > (isImg ? 5 : 4))) { - Tcl_WrongNumArgs(interp, 1, objv, isImg ? - "outfile inlist ?password infile?" : - "outfile inlist ?password?"); - return TCL_ERROR; - } - } else { - if ((objc < 3) || (objc > (isImg ? 6 : 5))) { - Tcl_WrongNumArgs(interp, 1, objv, isImg ? - "outfile indir ?strip? ?password? ?infile?" : - "outfile indir ?strip? ?password?"); - return TCL_ERROR; - } - } + /* + * Caller has verified that the number of arguments is correct. + */ + pwbuf[0] = 0; if (objc > (isList ? 3 : 4)) { pw = Tcl_GetString(objv[isList ? 3 : 4]); @@ -2376,11 +2375,9 @@ ZipFSMkZipOrImgObjCmd( Tcl_SetObjResult(interp, Tcl_NewStringObj("empty archive", -1)); return TCL_ERROR; } - out = Tcl_OpenFileChannel(interp, Tcl_GetString(objv[1]), "w", 0755); - if ((out == NULL) || (Tcl_SetChannelOption(interp, out, - "-translation", "binary") != TCL_OK)) { + out = Tcl_OpenFileChannel(interp, Tcl_GetString(objv[1]), "wb", 0755); + if (out == NULL) { Tcl_DecrRefCount(list); - Tcl_Close(interp, out); return TCL_ERROR; } if (pwlen <= 0) { @@ -2421,7 +2418,8 @@ ZipFSMkZipOrImgObjCmd( WriteLock(); hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); while (hPtr != NULL) { - if ((zf = (ZipFile *) Tcl_GetHashValue(hPtr)) != NULL) { + zf = Tcl_GetHashValue(hPtr); + if (zf != NULL) { if (strcmp(zf->name, imgName) == 0) { isMounted = 1; zf->nopen++; @@ -2437,9 +2435,10 @@ ZipFSMkZipOrImgObjCmd( if (isMounted || ZipFSOpenArchive(interp, imgName, 0, zf) == TCL_OK) { if ((size_t) Tcl_Write(out, (char *) zf->data, zf->baseoffsp) != zf->baseoffsp) { - memset(pwbuf, 0, sizeof (pwbuf)); + memset(pwbuf, 0, sizeof(pwbuf)); Tcl_DecrRefCount(list); - Tcl_SetObjResult(interp, Tcl_NewStringObj("write error", -1)); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "write error: %s", Tcl_PosixError(interp))); Tcl_Close(interp, out); if (zf == &zf0) { ZipFSCloseArchive(interp, zf); @@ -2469,20 +2468,20 @@ ZipFSMkZipOrImgObjCmd( */ Tcl_ResetResult(interp); - in = Tcl_OpenFileChannel(interp, imgName, "r", 0644); + in = Tcl_OpenFileChannel(interp, imgName, "rb", 0644); if (in == NULL) { - memset(pwbuf, 0, sizeof (pwbuf)); + memset(pwbuf, 0, sizeof(pwbuf)); Tcl_DecrRefCount(list); Tcl_Close(interp, out); return TCL_ERROR; } - Tcl_SetChannelOption(interp, in, "-translation", "binary"); i = Tcl_Seek(in, 0, SEEK_END); - if (i == (size_t)-1) { + if (i == ERROR_LENGTH) { cperr: - memset(pwbuf, 0, sizeof (pwbuf)); + memset(pwbuf, 0, sizeof(pwbuf)); Tcl_DecrRefCount(list); - Tcl_SetObjResult(interp, Tcl_NewStringObj(errMsg, -1)); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "%s: %s", errMsg, Tcl_PosixError(interp))); Tcl_Close(interp, out); Tcl_Close(interp, in); return TCL_ERROR; @@ -2491,8 +2490,8 @@ ZipFSMkZipOrImgObjCmd( k = 0; while (k < i) { m = i - k; - if (m > (int)sizeof (buf)) { - m = (int)sizeof (buf); + if (m > (int) sizeof(buf)) { + m = (int) sizeof(buf); } n = Tcl_Read(in, buf, m); if (n == -1) { @@ -2515,12 +2514,13 @@ ZipFSMkZipOrImgObjCmd( i = Tcl_Write(out, pwbuf, len); if (i != len) { Tcl_DecrRefCount(list); - Tcl_SetObjResult(interp, Tcl_NewStringObj("write error", -1)); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "write error: %s", Tcl_PosixError(interp))); Tcl_Close(interp, out); return TCL_ERROR; } } - memset(pwbuf, 0, sizeof (pwbuf)); + memset(pwbuf, 0, sizeof(pwbuf)); Tcl_Flush(out); } Tcl_InitHashTable(&fileHash, TCL_STRING_KEYS); @@ -2529,7 +2529,7 @@ ZipFSMkZipOrImgObjCmd( strip = Tcl_GetString(objv[3]); slen = strlen(strip); } - for (i = 0; i < (size_t)lobjc; i += (isList ? 2 : 1)) { + for (i = 0; i < (size_t) lobjc; i += (isList ? 2 : 1)) { const char *path, *name; path = Tcl_GetString(lobjv[i]); @@ -2551,14 +2551,14 @@ ZipFSMkZipOrImgObjCmd( if (name[0] == '\0') { continue; } - if (ZipAddFile(interp, path, name, out, pw, buf, sizeof (buf), - &fileHash) != TCL_OK) { + if (ZipAddFile(interp, path, name, out, pw, buf, sizeof(buf), + &fileHash) != TCL_OK) { goto done; } } pos[1] = Tcl_Tell(out); count = 0; - for (i = 0; i < (size_t)lobjc; i += (isList ? 2 : 1)) { + for (i = 0; i < (size_t) lobjc; i += (isList ? 2 : 1)) { const char *path, *name; path = Tcl_GetString(lobjv[i]); @@ -2605,8 +2605,9 @@ ZipFSMkZipOrImgObjCmd( zip_write_int(buf + ZIP_CENTRAL_LOCALHDR_OFFS, z->offset - pos[0]); if ((Tcl_Write(out, buf, ZIP_CENTRAL_HEADER_LEN) != ZIP_CENTRAL_HEADER_LEN) - || ((size_t)Tcl_Write(out, z->name, len) != len)) { - Tcl_SetObjResult(interp, Tcl_NewStringObj("write error", -1)); + || ((size_t) Tcl_Write(out, z->name, len) != len)) { + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "write error: %s", Tcl_PosixError(interp))); goto done; } count++; @@ -2622,11 +2623,13 @@ ZipFSMkZipOrImgObjCmd( zip_write_int(buf + ZIP_CENTRAL_DIRSTART_OFFS, pos[1] - pos[0]); zip_write_short(buf + ZIP_CENTRAL_COMMENTLEN_OFFS, 0); if (Tcl_Write(out, buf, ZIP_CENTRAL_END_LEN) != ZIP_CENTRAL_END_LEN) { - Tcl_SetObjResult(interp, Tcl_NewStringObj("write error", -1)); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "write error: %s", Tcl_PosixError(interp))); goto done; } Tcl_Flush(out); ret = TCL_OK; + done: if (ret == TCL_OK) { ret = Tcl_Close(interp, out); @@ -2636,7 +2639,7 @@ ZipFSMkZipOrImgObjCmd( Tcl_DecrRefCount(list); hPtr = Tcl_FirstHashEntry(&fileHash, &search); while (hPtr != NULL) { - z = (ZipEntry *) Tcl_GetHashValue(hPtr); + z = Tcl_GetHashValue(hPtr); Tcl_Free((char *) z); Tcl_DeleteHashEntry(hPtr); hPtr = Tcl_NextHashEntry(&search); @@ -2665,20 +2668,28 @@ ZipFSMkZipOrImgObjCmd( static int ZipFSMkZipObjCmd( ClientData clientData, - Tcl_Interp *interp, + Tcl_Interp *interp, /* Current interpreter. */ int objc, Tcl_Obj *const objv[]) { + if (objc < 3 || objc > 5) { + Tcl_WrongNumArgs(interp, 1, objv, "outfile indir ?strip? ?password?"); + return TCL_ERROR; + } return ZipFSMkZipOrImgObjCmd(clientData, interp, 0, 0, objc, objv); } static int ZipFSLMkZipObjCmd( ClientData clientData, - Tcl_Interp *interp, + Tcl_Interp *interp, /* Current interpreter. */ int objc, Tcl_Obj *const objv[]) { + if (objc < 3 || objc > 4) { + Tcl_WrongNumArgs(interp, 1, objv, "outfile inlist ?password?"); + return TCL_ERROR; + } return ZipFSMkZipOrImgObjCmd(clientData, interp, 0, 1, objc, objv); } @@ -2702,20 +2713,29 @@ ZipFSLMkZipObjCmd( static int ZipFSMkImgObjCmd( ClientData clientData, - Tcl_Interp *interp, + Tcl_Interp *interp, /* Current interpreter. */ int objc, Tcl_Obj *const objv[]) { + if (objc < 3 || objc > 6) { + Tcl_WrongNumArgs(interp, 1, objv, + "outfile indir ?strip? ?password? ?infile?"); + return TCL_ERROR; + } return ZipFSMkZipOrImgObjCmd(clientData, interp, 1, 0, objc, objv); } static int ZipFSLMkImgObjCmd( ClientData clientData, - Tcl_Interp *interp, + Tcl_Interp *interp, /* Current interpreter. */ int objc, Tcl_Obj *const objv[]) { + if (objc < 3 || objc > 5) { + Tcl_WrongNumArgs(interp, 1, objv, "outfile inlist ?password infile?"); + return TCL_ERROR; + } return ZipFSMkZipOrImgObjCmd(clientData, interp, 1, 1, objc, objv); } @@ -2739,16 +2759,16 @@ ZipFSLMkImgObjCmd( static int ZipFSCanonicalObjCmd( ClientData clientData, - Tcl_Interp *interp, + Tcl_Interp *interp, /* Current interpreter. */ int objc, - Tcl_Obj *const objv[] -) { + Tcl_Obj *const objv[]) +{ char *mntpoint = NULL; char *filename = NULL; char *result; Tcl_DString dPath; - if (objc != 2 && objc != 3 && objc != 4) { + if (objc < 2 || objc > 4) { Tcl_WrongNumArgs(interp, 1, objv, "?mntpnt? filename ?ZIPFS?"); return TCL_ERROR; } @@ -2795,7 +2815,7 @@ ZipFSCanonicalObjCmd( static int ZipFSExistsObjCmd( ClientData clientData, - Tcl_Interp *interp, + Tcl_Interp *interp, /* Current interpreter. */ int objc, Tcl_Obj *const objv[]) { @@ -2848,7 +2868,7 @@ ZipFSExistsObjCmd( static int ZipFSInfoObjCmd( ClientData clientData, - Tcl_Interp *interp, + Tcl_Interp *interp, /* Current interpreter. */ int objc, Tcl_Obj *const objv[]) { @@ -2897,7 +2917,7 @@ ZipFSInfoObjCmd( static int ZipFSListObjCmd( ClientData clientData, - Tcl_Interp *interp, + Tcl_Interp *interp, /* Current interpreter. */ int objc, Tcl_Obj *const objv[]) { @@ -2923,8 +2943,8 @@ ZipFSListObjCmd( return TCL_ERROR; } } else { - Tcl_AppendResult(interp, "unknown option \"", what, "\"", - (char *) NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "unknown option \"%s\"", what)); return TCL_ERROR; } } else if (objc == 2) { @@ -2966,6 +2986,7 @@ ZipFSListObjCmd( #ifdef _WIN32 #define LIBRARY_SIZE 64 + static int ToUtf( const WCHAR *wSrc, @@ -2981,7 +3002,7 @@ ToUtf( *dst = '\0'; return (int) (dst - start); } -#endif +#endif /* _WIN32 */ Tcl_Obj * TclZipfs_TclLibrary(void) @@ -3010,7 +3031,7 @@ TclZipfs_TclLibrary(void) return Tcl_NewStringObj(zipfs_literal_tcl_library, -1); } -#ifdef _WIN32 +#if defined(_WIN32) if (GetModuleFileNameW(hModule, wName, MAX_PATH) == 0) { GetModuleFileNameA(hModule, dllname, MAX_PATH); } else { @@ -3024,8 +3045,7 @@ TclZipfs_TclLibrary(void) if (TclZipfs_AppHook_FindTclInit(dllname) == TCL_OK) { return Tcl_NewStringObj(zipfs_literal_tcl_library, -1); } -#else /* !_WIN32 */ -#ifdef CFG_RUNTIME_DLLFILE +#elif /* !_WIN32 && */ defined(CFG_RUNTIME_DLLFILE) /* * Mount zip file and dll before releasing to search. */ @@ -3033,8 +3053,7 @@ TclZipfs_TclLibrary(void) CFG_RUNTIME_LIBDIR "/" CFG_RUNTIME_DLLFILE) == TCL_OK) { return Tcl_NewStringObj(zipfs_literal_tcl_library, -1); } -#endif /* CFG_RUNTIME_DLLFILE */ -#endif /* _WIN32 */ +#endif /* _WIN32 || CFG_RUNTIME_DLLFILE */ #ifdef CFG_RUNTIME_ZIPFILE if (TclZipfs_AppHook_FindTclInit( @@ -3075,7 +3094,7 @@ TclZipfs_TclLibrary(void) static int ZipFSTclLibraryObjCmd( ClientData clientData, - Tcl_Interp *interp, + Tcl_Interp *interp, /* Current interpreter. */ int objc, Tcl_Obj *const objv[]) { @@ -3107,7 +3126,7 @@ ZipFSTclLibraryObjCmd( static int ZipChannelClose( ClientData instanceData, - Tcl_Interp *interp) + Tcl_Interp *interp) /* Current interpreter. */ { ZipChannel *info = (ZipChannel *) instanceData; @@ -3117,7 +3136,7 @@ ZipChannelClose( } if (info->isenc) { info->isenc = 0; - memset(info->keys, 0, sizeof (info->keys)); + memset(info->keys, 0, sizeof(info->keys)); } if (info->iswr) { ZipEntry *z = info->zipentry; @@ -3153,13 +3172,13 @@ ZipChannelClose( * * ZipChannelRead -- * - * This function is called to read data from channel. + * This function is called to read data from channel. * * Results: - * Number of bytes read or -1 on error with error number set. + * Number of bytes read or -1 on error with error number set. * * Side effects: - * Data is read and file pointer is advanced. + * Data is read and file pointer is advanced. * *------------------------------------------------------------------------- */ @@ -3179,6 +3198,7 @@ ZipChannelRead( * Special case: when executable combined with ZIP archive file read * data in front of ZIP, i.e. the executable itself. */ + nextpos = info->nread + toRead; if (nextpos > info->zipfile->baseoffs) { toRead = info->zipfile->baseoffs - info->nread; @@ -3205,10 +3225,11 @@ ZipChannelRead( return 0; } if (info->isenc) { - int i, ch; + int i; for (i = 0; i < toRead; i++) { - ch = info->ubuf[i + info->nread]; + int ch = info->ubuf[i + info->nread]; + buf[i] = zdecode(info->keys, crc32tab, ch); } } else { @@ -3271,13 +3292,13 @@ ZipChannelWrite( * * ZipChannelSeek -- * - * This function is called to position file pointer of channel. + * This function is called to position file pointer of channel. * * Results: - * New file position or -1 on error with error number set. + * New file position or -1 on error with error number set. * * Side effects: - * File pointer is repositioned according to offset and mode. + * File pointer is repositioned according to offset and mode. * *------------------------------------------------------------------------- */ @@ -3394,8 +3415,7 @@ ZipChannelGetFile( static Tcl_ChannelType ZipChannelType = { "zip", /* Type name. */ -#ifdef TCL_CHANNEL_VERSION_4 - TCL_CHANNEL_VERSION_4, + TCL_CHANNEL_VERSION_5, ZipChannelClose, /* Close channel, clean instance data */ ZipChannelRead, /* Handle read request */ ZipChannelWrite, /* Handle write request */ @@ -3410,17 +3430,7 @@ static Tcl_ChannelType ZipChannelType = { NULL, /* Function to handle event, NULL'able */ NULL, /* Wide seek function, NULL'able */ NULL, /* Thread action function, NULL'able */ -#else - NULL, /* Set blocking/nonblocking behaviour, NULL'able */ - ZipChannelClose, /* Close channel, clean instance data */ - ZipChannelRead, /* Handle read request */ - ZipChannelWrite, /* Handle write request */ - ZipChannelSeek, /* Move location of access point, NULL'able */ - NULL, /* Set options, NULL'able */ - NULL, /* Get options, NULL'able */ - ZipChannelWatchChannel, /* Initialize notifier */ - ZipChannelGetFile, /* Get OS handle from the channel */ -#endif + NULL, /* Truncate function, NULL'able */ }; /* @@ -3428,21 +3438,21 @@ static Tcl_ChannelType ZipChannelType = { * * ZipChannelOpen -- * - * This function opens a Tcl_Channel on a file from a mounted ZIP - * archive according to given open mode. + * This function opens a Tcl_Channel on a file from a mounted ZIP archive + * according to given open mode. * * Results: - * Tcl_Channel on success, or NULL on error. + * Tcl_Channel on success, or NULL on error. * * Side effects: - * Memory is allocated, the file from the ZIP archive is uncompressed. + * Memory is allocated, the file from the ZIP archive is uncompressed. * *------------------------------------------------------------------------- */ static Tcl_Channel ZipChannelOpen( - Tcl_Interp *interp, + Tcl_Interp *interp, /* Current interpreter. */ char *filename, int mode, int permissions) @@ -3464,8 +3474,8 @@ ZipChannelOpen( z = ZipFSLookup(filename); if (z == NULL) { if (interp != NULL) { - Tcl_SetObjResult(interp, Tcl_NewStringObj("file not found", -1)); - Tcl_AppendResult(interp, " \"", filename, "\"", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "file not found \"%s\"", filename)); } goto error; } @@ -3492,7 +3502,7 @@ ZipChannelOpen( } else { flags = TCL_WRITABLE; } - info = (ZipChannel *) Tcl_AttemptAlloc(sizeof (*info)); + info = (ZipChannel *) Tcl_AttemptAlloc(sizeof(ZipChannel)); if (info == NULL) { ZIPFS_ERROR(interp, "out of memory"); goto error; @@ -3520,97 +3530,96 @@ ZipChannelOpen( memset(info->ubuf, 0, info->nmax); if (trunc) { info->nbyte = 0; + } else if (z->data != NULL) { + unsigned int j = z->nbyte; + + if (j > info->nmax) { + j = info->nmax; + } + memcpy(info->ubuf, z->data, j); + info->nbyte = j; } else { - if (z->data != NULL) { - unsigned int j = z->nbyte; + unsigned char *zbuf = z->zipfile->data + z->offset; - if (j > info->nmax) { - j = info->nmax; - } - memcpy(info->ubuf, z->data, j); - info->nbyte = j; - } else { - unsigned char *zbuf = z->zipfile->data + z->offset; + if (z->isenc) { + int len = z->zipfile->pwbuf[0]; + char pwbuf[260]; + for (i = 0; i < len; i++) { + ch = z->zipfile->pwbuf[len - i]; + pwbuf[i] = (ch & 0x0f) | pwrot[(ch >> 4) & 0x0f]; + } + pwbuf[i] = '\0'; + init_keys(pwbuf, info->keys, crc32tab); + memset(pwbuf, 0, sizeof(pwbuf)); + for (i = 0; i < 12; i++) { + ch = info->ubuf[i]; + zdecode(info->keys, crc32tab, ch); + } + zbuf += i; + } + if (z->cmeth == ZIP_COMPMETH_DEFLATED) { + z_stream stream; + int err; + unsigned char *cbuf = NULL; + + memset(&stream, 0, sizeof(z_stream)); + stream.zalloc = Z_NULL; + stream.zfree = Z_NULL; + stream.opaque = Z_NULL; + stream.avail_in = z->nbytecompr; if (z->isenc) { - int len = z->zipfile->pwbuf[0]; - char pwbuf[260]; + unsigned int j; - for (i = 0; i < len; i++) { - ch = z->zipfile->pwbuf[len - i]; - pwbuf[i] = (ch & 0x0f) | pwrot[(ch >> 4) & 0x0f]; + stream.avail_in -= 12; + cbuf = (unsigned char *) Tcl_AttemptAlloc(stream.avail_in); + if (cbuf == NULL) { + goto merror0; } - pwbuf[i] = '\0'; - init_keys(pwbuf, info->keys, crc32tab); - memset(pwbuf, 0, sizeof (pwbuf)); - for (i = 0; i < 12; i++) { - ch = info->ubuf[i]; - zdecode(info->keys, crc32tab, ch); + for (j = 0; j < stream.avail_in; j++) { + ch = info->ubuf[j]; + cbuf[j] = zdecode(info->keys, crc32tab, ch); } - zbuf += i; + stream.next_in = cbuf; + } else { + stream.next_in = zbuf; } - if (z->cmeth == ZIP_COMPMETH_DEFLATED) { - z_stream stream; - int err; - unsigned char *cbuf = NULL; - - memset(&stream, 0, sizeof (stream)); - stream.zalloc = Z_NULL; - stream.zfree = Z_NULL; - stream.opaque = Z_NULL; - stream.avail_in = z->nbytecompr; - if (z->isenc) { - unsigned int j; - - stream.avail_in -= 12; - cbuf = (unsigned char *) - Tcl_AttemptAlloc(stream.avail_in); - if (cbuf == NULL) { - goto merror0; - } - for (j = 0; j < stream.avail_in; j++) { - ch = info->ubuf[j]; - cbuf[j] = zdecode(info->keys, crc32tab, ch); - } - stream.next_in = cbuf; - } else { - stream.next_in = zbuf; - } - stream.next_out = info->ubuf; - stream.avail_out = info->nmax; - if (inflateInit2(&stream, -15) != Z_OK) goto cerror0; - err = inflate(&stream, Z_SYNC_FLUSH); - inflateEnd(&stream); - if ((err == Z_STREAM_END) - || ((err == Z_OK) && (stream.avail_in == 0))) { - if (cbuf != NULL) { - memset(info->keys, 0, sizeof (info->keys)); - Tcl_Free((char *) cbuf); - } - goto wrapchan; - } - cerror0: + stream.next_out = info->ubuf; + stream.avail_out = info->nmax; + if (inflateInit2(&stream, -15) != Z_OK) { + goto cerror0; + } + err = inflate(&stream, Z_SYNC_FLUSH); + inflateEnd(&stream); + if ((err == Z_STREAM_END) + || ((err == Z_OK) && (stream.avail_in == 0))) { if (cbuf != NULL) { - memset(info->keys, 0, sizeof (info->keys)); + memset(info->keys, 0, sizeof(info->keys)); Tcl_Free((char *) cbuf); } - if (info->ubuf != NULL) { - Tcl_Free((char *) info->ubuf); - } - Tcl_Free((char *) info); - ZIPFS_ERROR(interp, "decompression error"); - goto error; - } else if (z->isenc) { - for (i = 0; i < z->nbyte - 12; i++) { - ch = zbuf[i]; - info->ubuf[i] = zdecode(info->keys, crc32tab, ch); - } - } else { - memcpy(info->ubuf, zbuf, z->nbyte); + goto wrapchan; } - memset(info->keys, 0, sizeof (info->keys)); - goto wrapchan; + cerror0: + if (cbuf != NULL) { + memset(info->keys, 0, sizeof(info->keys)); + Tcl_Free((char *) cbuf); + } + if (info->ubuf != NULL) { + Tcl_Free((char *) info->ubuf); + } + Tcl_Free((char *) info); + ZIPFS_ERROR(interp, "decompression error"); + goto error; + } else if (z->isenc) { + for (i = 0; i < z->nbyte - 12; i++) { + ch = zbuf[i]; + info->ubuf[i] = zdecode(info->keys, crc32tab, ch); + } + } else { + memcpy(info->ubuf, zbuf, z->nbyte); } + memset(info->keys, 0, sizeof(info->keys)); + goto wrapchan; } } else if (z->data != NULL) { flags |= TCL_READABLE; @@ -3640,7 +3649,7 @@ ZipChannelOpen( } pwbuf[i] = '\0'; init_keys(pwbuf, info->keys, crc32tab); - memset(pwbuf, 0, sizeof (pwbuf)); + memset(pwbuf, 0, sizeof(pwbuf)); for (i = 0; i < 12; i++) { ch = info->ubuf[i]; zdecode(info->keys, crc32tab, ch); @@ -3653,7 +3662,7 @@ ZipChannelOpen( unsigned char *ubuf = NULL; unsigned int j; - memset(&stream, 0, sizeof (stream)); + memset(&stream, 0, sizeof(z_stream)); stream.zalloc = Z_NULL; stream.zfree = Z_NULL; stream.opaque = Z_NULL; @@ -3679,7 +3688,7 @@ ZipChannelOpen( merror: if (ubuf != NULL) { info->isenc = 0; - memset(info->keys, 0, sizeof (info->keys)); + memset(info->keys, 0, sizeof(info->keys)); Tcl_Free((char *) ubuf); } Tcl_Free((char *) info); @@ -3699,7 +3708,7 @@ ZipChannelOpen( || ((err == Z_OK) && (stream.avail_in == 0))) { if (ubuf != NULL) { info->isenc = 0; - memset(info->keys, 0, sizeof (info->keys)); + memset(info->keys, 0, sizeof(info->keys)); Tcl_Free((char *) ubuf); } goto wrapchan; @@ -3718,6 +3727,7 @@ ZipChannelOpen( goto error; } } + wrapchan: sprintf(cname, "zipfs_%" TCL_LL_MODIFIER "x_%d", z->offset, ZipFS.idCount++); @@ -3758,7 +3768,7 @@ ZipEntryStat( ReadLock(); z = ZipFSLookup(path); if (z != NULL) { - memset(buf, 0, sizeof (Tcl_StatBuf)); + memset(buf, 0, sizeof(Tcl_StatBuf)); if (z->isdir) { buf->st_mode = S_IFDIR | 0555; } else { @@ -3821,7 +3831,7 @@ ZipEntryAccess( static Tcl_Channel Zip_FSOpenFileChannelProc( - Tcl_Interp *interp, + Tcl_Interp *interp, /* Current interpreter. */ Tcl_Obj *pathPtr, int mode, int permissions) @@ -3942,9 +3952,10 @@ Zip_FSFilesystemSeparatorProc( * *------------------------------------------------------------------------- */ + static int Zip_FSMatchInDirectoryProc( - Tcl_Interp *interp, + Tcl_Interp *interp, /* Current interpreter. */ Tcl_Obj *result, Tcl_Obj *pathPtr, const char *pattern, @@ -3952,24 +3963,29 @@ Zip_FSMatchInDirectoryProc( { Tcl_HashEntry *hPtr; Tcl_HashSearch search; - Tcl_Obj *normPathPtr; + Tcl_Obj *normPathPtr = Tcl_FSGetNormalizedPath(NULL, pathPtr); int scnt, l, dirOnly = -1, prefixLen, strip = 0; size_t len; char *pat, *prefix, *path; Tcl_DString dsPref; - if (!(normPathPtr = Tcl_FSGetNormalizedPath(NULL, pathPtr))) { + if (!normPathPtr) { return -1; } - if (types != NULL) { dirOnly = (types->type & TCL_GLOB_TYPE_DIR) == TCL_GLOB_TYPE_DIR; } - /* the prefix that gets prepended to results */ + /* + * The prefix that gets prepended to results. + */ + prefix = Tcl_GetStringFromObj(pathPtr, &prefixLen); - /* the (normalized) path we're searching */ + /* + * The (normalized) path we're searching. + */ + path = Tcl_GetString(normPathPtr); len = normPathPtr->length; @@ -3999,12 +4015,14 @@ Zip_FSMatchInDirectoryProc( } hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); while (hPtr != NULL) { - ZipFile *zf = (ZipFile *) Tcl_GetHashValue(hPtr); + ZipFile *zf = Tcl_GetHashValue(hPtr); if (zf->mntptlen == 0) { - ZipEntry *z = zf->topents; - while (z != NULL) { + ZipEntry *z; + + for (z = zf->topents; z != NULL; z = z->tnext) { size_t lenz = strlen(z->name); + if ((lenz > len + 1) && (strncmp(z->name, path, len) == 0) && (z->name[len] == '/') && (CountSlashes(z->name) == l) @@ -4021,7 +4039,6 @@ Zip_FSMatchInDirectoryProc( Tcl_NewStringObj(z->name, lenz)); } } - z = z->tnext; } } else if ((zf->mntptlen > len + 1) && (strncmp(zf->mntpt, path, len) == 0) @@ -4047,7 +4064,7 @@ Zip_FSMatchInDirectoryProc( if ((pattern == NULL) || (pattern[0] == '\0')) { hPtr = Tcl_FindHashEntry(&ZipFS.fileHash, path); if (hPtr != NULL) { - ZipEntry *z = (ZipEntry *) Tcl_GetHashValue(hPtr); + ZipEntry *z = Tcl_GetHashValue(hPtr); if ((dirOnly < 0) || (!dirOnly && !z->isdir) || (dirOnly && z->isdir)) { @@ -4080,7 +4097,8 @@ Zip_FSMatchInDirectoryProc( scnt = CountSlashes(pat); for (hPtr = Tcl_FirstHashEntry(&ZipFS.fileHash, &search); hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) { - ZipEntry *z = (ZipEntry *) Tcl_GetHashValue(hPtr); + ZipEntry *z = Tcl_GetHashValue(hPtr); + if ((dirOnly >= 0) && ((dirOnly && !z->isdir) || (!dirOnly && z->isdir))) { continue; @@ -4135,7 +4153,8 @@ Zip_FSPathInFilesystemProc( size_t len; char *path; - if (!(pathPtr = Tcl_FSGetNormalizedPath(NULL, pathPtr))) { + pathPtr = Tcl_FSGetNormalizedPath(NULL, pathPtr); + if (!pathPtr) { return -1; } @@ -4155,17 +4174,17 @@ Zip_FSPathInFilesystemProc( hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); while (hPtr != NULL) { - zf = (ZipFile *) Tcl_GetHashValue(hPtr); + zf = Tcl_GetHashValue(hPtr); if (zf->mntptlen == 0) { - ZipEntry *z = zf->topents; - while (z != NULL) { + ZipEntry *z; + + for (z = zf->topents; z != NULL; z = z->tnext) { size_t lenz = strlen(z->name); if ((len >= lenz) && (strncmp(path, z->name, lenz) == 0)) { ret = TCL_OK; goto endloop; } - z = z->tnext; } } else if ((len >= zf->mntptlen) && (strncmp(path, zf->mntpt, zf->mntptlen) == 0)) { @@ -4223,7 +4242,7 @@ Zip_FSListVolumesProc(void) static const char *const * Zip_FSFileAttrStringsProc( Tcl_Obj *pathPtr, - Tcl_Obj** objPtrRef) + Tcl_Obj **objPtrRef) { static const char *const attrs[] = { "-uncompsize", @@ -4259,7 +4278,7 @@ Zip_FSFileAttrStringsProc( static int Zip_FSFileAttrsGetProc( - Tcl_Interp *interp, + Tcl_Interp *interp, /* Current interpreter. */ int index, Tcl_Obj *pathPtr, Tcl_Obj **objPtrRef) @@ -4268,7 +4287,8 @@ Zip_FSFileAttrsGetProc( char *path; ZipEntry *z; - if (!(pathPtr = Tcl_FSGetNormalizedPath(NULL, pathPtr))) { + pathPtr = Tcl_FSGetNormalizedPath(NULL, pathPtr); + if (!pathPtr) { return -1; } path = Tcl_GetStringFromObj(pathPtr, &len); @@ -4325,7 +4345,7 @@ Zip_FSFileAttrsGetProc( static int Zip_FSFileAttrsSetProc( - Tcl_Interp *interp, + Tcl_Interp *interp, /* Current interpreter. */ int index, Tcl_Obj *pathPtr, Tcl_Obj *objPtr) @@ -4378,7 +4398,7 @@ Zip_FSFilesystemPathTypeProc( static int Zip_FSLoadFile( - Tcl_Interp *interp, + Tcl_Interp *interp, /* Current interpreter. */ Tcl_Obj *path, Tcl_LoadHandle *loadHandle, Tcl_FSUnloadFileProc **unloadProcPtr, @@ -4401,6 +4421,7 @@ Zip_FSLoadFile( #else /* !ANDROID */ Tcl_Obj *altPath = NULL; int ret = TCL_ERROR; + Tcl_Obj *objs[2] = { NULL, NULL }; if (Tcl_FSAccess(path, R_OK) == 0) { /* @@ -4410,56 +4431,55 @@ Zip_FSLoadFile( Tcl_SetErrno(EXDEV); ZIPFS_ERROR(interp, Tcl_PosixError(interp)); return ret; - } else { - Tcl_Obj *objs[2] = { NULL, NULL }; + } - objs[1] = TclPathPart(interp, path, TCL_PATH_DIRNAME); - if ((objs[1] != NULL) && (Zip_FSAccessProc(objs[1], R_OK) == 0)) { - const char *execName = Tcl_GetNameOfExecutable(); + objs[1] = TclPathPart(interp, path, TCL_PATH_DIRNAME); + if ((objs[1] != NULL) && (Zip_FSAccessProc(objs[1], R_OK) == 0)) { + const char *execName = Tcl_GetNameOfExecutable(); - /* - * Shared object is not in ZIP but its path prefix is, thus try to - * load from directory where the executable came from. - */ + /* + * Shared object is not in ZIP but its path prefix is, thus try to + * load from directory where the executable came from. + */ - TclDecrRefCount(objs[1]); - objs[1] = TclPathPart(interp, path, TCL_PATH_TAIL); + TclDecrRefCount(objs[1]); + objs[1] = TclPathPart(interp, path, TCL_PATH_TAIL); - /* - * Get directory name of executable manually to deal with cases - * where [file dirname [info nameofexecutable]] is equal to [info - * nameofexecutable] due to VFS effects. - */ + /* + * Get directory name of executable manually to deal with cases where + * [file dirname [info nameofexecutable]] is equal to [info + * nameofexecutable] due to VFS effects. + */ - if (execName != NULL) { - const char *p = strrchr(execName, '/'); + if (execName != NULL) { + const char *p = strrchr(execName, '/'); - if (p > execName + 1) { - --p; - objs[0] = Tcl_NewStringObj(execName, p - execName); - } - } - if (objs[0] == NULL) { - objs[0] = TclPathPart(interp, TclGetObjNameOfExecutable(), - TCL_PATH_DIRNAME); - } - if (objs[0] != NULL) { - altPath = TclJoinPath(2, objs); - if (altPath != NULL) { - Tcl_IncrRefCount(altPath); - if (Tcl_FSAccess(altPath, R_OK) == 0) { - path = altPath; - } - } + if (p > execName + 1) { + --p; + objs[0] = Tcl_NewStringObj(execName, p - execName); } } - if (objs[0] != NULL) { - Tcl_DecrRefCount(objs[0]); + if (objs[0] == NULL) { + objs[0] = TclPathPart(interp, TclGetObjNameOfExecutable(), + TCL_PATH_DIRNAME); } - if (objs[1] != NULL) { - Tcl_DecrRefCount(objs[1]); + if (objs[0] != NULL) { + altPath = TclJoinPath(2, objs); + if (altPath != NULL) { + Tcl_IncrRefCount(altPath); + if (Tcl_FSAccess(altPath, R_OK) == 0) { + path = altPath; + } + } } } + if (objs[0] != NULL) { + Tcl_DecrRefCount(objs[0]); + } + if (objs[1] != NULL) { + Tcl_DecrRefCount(objs[1]); + } + loadFileProc = (Tcl_FSLoadFileProc2 *) tclNativeFilesystem.loadFileProc; if (loadFileProc != NULL) { ret = loadFileProc(interp, path, loadHandle, unloadProcPtr, flags); @@ -4495,7 +4515,7 @@ Zip_FSLoadFile( MODULE_SCOPE int TclZipfs_Init( - Tcl_Interp *interp) + Tcl_Interp *interp) /* Current interpreter. */ { #ifdef HAVE_ZLIB /* one-time initialization */ @@ -4507,10 +4527,10 @@ TclZipfs_Init( Unlock(); if (interp != NULL) { static const EnsembleImplMap initMap[] = { - {"mkimg", ZipFSMkImgObjCmd, NULL, NULL, NULL, 0}, - {"mkzip", ZipFSMkZipObjCmd, NULL, NULL, NULL, 0}, - {"lmkimg", ZipFSLMkImgObjCmd, NULL, NULL, NULL, 0}, - {"lmkzip", ZipFSLMkZipObjCmd, NULL, NULL, NULL, 0}, + {"mkimg", ZipFSMkImgObjCmd, NULL, NULL, NULL, 1}, + {"mkzip", ZipFSMkZipObjCmd, NULL, NULL, NULL, 1}, + {"lmkimg", ZipFSLMkImgObjCmd, NULL, NULL, NULL, 1}, + {"lmkzip", ZipFSLMkZipObjCmd, NULL, NULL, NULL, 1}, /* The 4 entries above are not available in safe interpreters */ {"mount", ZipFSMountObjCmd, NULL, NULL, NULL, 0}, {"mount_data", ZipFSMountBufferObjCmd, NULL, NULL, NULL, 0}, @@ -4525,23 +4545,22 @@ TclZipfs_Init( {NULL, NULL, NULL, NULL, NULL, 0} }; static const char findproc[] = - "namespace eval ::tcl::zipfs::zipfs {}\n" - "proc ::tcl::zipfs::find dir {\n" + "namespace eval ::tcl::zipfs {}\n" + "proc ::tcl::zipfs::Find dir {\n" " set result {}\n" - " if {[catch {glob -directory $dir -tails -nocomplain * .*} list]} {\n" + " if {[catch {glob -directory $dir -nocomplain * .*} list]} {\n" " return $result\n" " }\n" " foreach file $list {\n" - " if {$file eq \".\" || $file eq \"..\"} {\n" + " if {[file tail $file] in {. ..}} {\n" " continue\n" " }\n" - " set file [file join $dir $file]\n" - " lappend result $file\n" - " foreach file [::tcl::zipfs::find $file] {\n" - " lappend result $file\n" - " }\n" + " lappend result $file {*}[Find $file]\n" " }\n" - " return [lsort $result]\n" + " return $result\n" + "}\n" + "proc ::tcl::zipfs::find dir {\n" + " return [lsort [Find $dir]]\n" "}\n"; Tcl_EvalEx(interp, findproc, -1, TCL_EVAL_GLOBAL); Tcl_LinkVar(interp, "::tcl::zipfs::wrmax", (char *) &ZipFS.wrmax, @@ -4606,20 +4625,20 @@ TclZipfs_AppHook_FindTclInit( int TclZipfs_AppHook( - int *argc, + int *argcPtr, #ifdef _WIN32 TCHAR #else /* !_WIN32 */ char #endif /* _WIN32 */ - ***argv) + ***argvPtr) { #ifdef _WIN32 Tcl_DString ds; #endif /* _WIN32 */ char *archive; - Tcl_FindExecutable((*argv)[0]); + Tcl_FindExecutable((*argvPtr)[0]); archive = (char *) Tcl_GetNameOfExecutable(); TclZipfs_Init(NULL); @@ -4659,18 +4678,19 @@ TclZipfs_AppHook( return TCL_OK; } } - } else if (*argc>1) { - return TCL_OK; +#ifdef SUPPORT_BUILTIN_ZIP_INSTALL + } else if (*argcPtr > 1) { + /* + * If the first argument is "install", run the supplied installer + * script. + */ + #ifdef _WIN32 - archive = Tcl_WinTCharToUtf((*argv)[1], -1, &ds); -#else - archive = (*argv)[1]; -#endif + archive = Tcl_WinTCharToUtf((*argvPtr)[1], -1, &ds); +#else /* !_WIN32 */ + archive = (*argvPtr)[1]; +#endif /* _WIN32 */ if (strcmp(archive, "install") == 0) { - /* - * If the first argument is mkzip, run the mkzip program. - */ - Tcl_Obj *vfsinitscript; /* @@ -4715,6 +4735,7 @@ TclZipfs_AppHook( #ifdef _WIN32 Tcl_DStringFree(&ds); #endif /* _WIN32 */ +#endif /* SUPPORT_BUILTIN_ZIP_INSTALL */ } return TCL_OK; } @@ -4733,18 +4754,19 @@ TclZipfs_AppHook( int TclZipfs_Mount( - Tcl_Interp *interp, - const char *mntpt, - const char *zipname, - const char *passwd) + Tcl_Interp *interp, /* Current interpreter. */ + const char *mntpt, /* Mount point path. */ + const char *zipname, /* Path to ZIP file to mount. */ + const char *passwd) /* Password for opening the ZIP, or NULL if + * the ZIP is unprotected. */ { return TclZipfs_Init(interp, 1); } int TclZipfs_Unmount( - Tcl_Interp *interp, - const char *zipname) + Tcl_Interp *interp, /* Current interpreter. */ + const char *mntpt) /* Mount point path. */ { return TclZipfs_Init(interp, 1); } -- cgit v0.12 From a557024511668b3e4b5276a0b5334546d0807ddd Mon Sep 17 00:00:00 2001 From: dkf Date: Sat, 6 Oct 2018 06:41:28 +0000 Subject: Cleanup work on zipfs(n) --- doc/zipfs.n | 127 +++++++++++++++++++++++++++++++++--------------------------- 1 file changed, 70 insertions(+), 57 deletions(-) diff --git a/doc/zipfs.n b/doc/zipfs.n index 31a0707..9a241f4 100644 --- a/doc/zipfs.n +++ b/doc/zipfs.n @@ -19,19 +19,20 @@ zipfs \- Mount and work with ZIP files within Tcl \fBzipfs exists\fR \fIfilename\fR \fBzipfs find\fR \fIdir\fR \fBzipfs info\fR \fIfilename\fR -\fBzipfs list\fR \fB?(-glob|-regexp)?\fR \fI?pattern?\fR -\fBzipfs mkimg\fR \fIoutfile\fR \fIindir\fR \fI?strip?\fR \fI?password?\fR \fI?infile?\fR +\fBzipfs list\fR ?(\fB\-glob\fR|\fB\-regexp\fR)? ?\fIpattern\fR? +\fBzipfs mkimg\fR \fIoutfile indir\fR ?\fIstrip\fR? ?\fIpassword\fR? ?\fIinfile\fR? \fBzipfs mkkey\fR \fIpassword\fR -\fBzipfs mkzip\fR \fIoutfile\fR \fIindir\fR \fI?strip?\fR \fI?password?\fR -\fBzipfs mount\fR \fI?mountpoint?\fR \fI?zipfile?\fR \fI?password?\fR +\fBzipfs mkzip\fR \fIoutfile indir\fR ?\fIstrip\fR? ?\fIpassword\fR? +\fBzipfs mount\fR ?\fImountpoint\fR? ?\fIzipfile\fR? ?\fIpassword\fR? \fBzipfs root\fR \fBzipfs unmount\fR \fImountpoint\fR .fi .BE .SH DESCRIPTION .PP -The \fBzipfs\fR package provides tcl with the ability to mount -the contents of a zip file as a virtual file system. +The \fBzipfs\fR command (the sole public command provided by the built-in +package with the same name) provides Tcl with the ability to mount the +contents of a ZIP file as a virtual file system. .TP \fBzipfs exists\fR \fIfilename\fR . @@ -39,50 +40,84 @@ Return 1 if the given filename exists in the mounted zipfs and 0 if it does not. .TP \fBzipfs find\fR \fIdir\fR . -Recursively lists files including and below the directory \fIdir\fR. -The result list consists of relative path names starting from the -given directory. This command is also used by the \fBzipfs mkzip\fR -and \fBzipfs mkimg\fR commands. +Recursively lists files including and below the directory \fIdir\fR. The +result list consists of relative path names starting from the given +directory. This command is also used by the \fBzipfs mkzip\fR and \fBzipfs +mkimg\fR commands. .TP \fBzipfs info\fR \fIfile\fR . -Return information about the given file in the mounted zipfs. The information -consists of (1) the name of the ZIP archive file that contains the file, -(2) the size of the file after decompressions, (3) the compressed size of -the file, and (4) the offset of the compressed data in the ZIP archive file. +Return information about the given \fIfile\fR in the mounted zipfs. The +information consists of: .RS +.IP (1) +the name of the ZIP archive file that contains the file, +.IP (2) +the size of the file after decompressions, +.IP (3) +the compressed size of the file, and +.IP (4) +the offset of the compressed data in the ZIP archive file. .PP -Note: querying the mount point gives the start of zip data offset in (4), -which can be used to truncate the zip info off an executable. +Note: querying the mount point gives the start of the zip data as the offset +in (4), which can be used to truncate the zip information from an executable. .RE .TP -\fBzipfs list\fR \fB?(-glob|-regexp)?\fR \fI?pattern?\fR +\fBzipfs list\fR ?(\fB\-glob\fR|\fB\-regexp\fR)? \fI?pattern?\fR . -Return a list of all files in the mounted zipfs. The order of the names -in the list is arbitrary. +Return a list of all files in the mounted zipfs, or just those matching +\fIpattern\fR (optionally controlled by the option parameters). The order of +the names in the list is arbitrary. .TP -\fBzipfs mkimg\fR \fIoutfile\fR \fIindir\fR \fI?strip?\fR \fI?password?\fR \fI?infile?\fR +\fBzipfs mount ?\fImountpoint\fR? ?\fIzipfile\fR? ?\fIpassword\fR? +. +The \fBzipfs mount\fR command mounts a ZIP archive file as a Tcl virtual +filesystem at \fImountpoint\fR. After this command executes, files contained +in \fIzipfile\fR will appear to Tcl to be regular files at the mount point. +.RS +.PP +With no \fIzipfile\fR, returns the zipfile mounted at \fImountpoint\fR. With +no \fImountpoint\fR, return all zipfile/mount pairs. If \fImountpoint\fR is +specified as an empty string, mount on file path. +.RE +.TP +\fBzipfs root\fR +. +Returns a constant string which indicates the mount point for zipfs volumes +for the current platform. On Windows, this value is +.QW \fBzipfs:/\fR . +On Unix, this value is +.QW \fB//zipfs:/\fR . +.RE +.TP +\fBzipfs unmount \fImountpoint\fR +. +Unmounts a previously mounted ZIP archive mounted to \fImountpoint\fR. +.SS "ZIP CREATION COMMANDS" +This package also provides several commands to aid the creation of ZIP +archives as Tcl applications. +.TP +\fBzipfs mkimg\fR \fIoutfile indir\fR ?\fIstrip\fR? ?\fIpassword\fR? ?\fIinfile\fR? . -Creates an image (potentially a new executable file) similar to -\fBzipfs mkzip\fR. If the \fIinfile\fR parameter is specified, -this file is prepended in front of the ZIP archive, otherwise the file -returned by \fBTcl_NameOfExecutable(3)\fR (i.e. the executable file of -the running process) is used. If the \fIpassword\fR parameter is not empty, -an obfuscated version of that password is placed between the image and ZIP -chunks of the output file and the contents of the ZIP chunk are protected -with that password. +Creates an image (potentially a new executable file) similar to \fBzipfs +mkzip\fR. If the \fIinfile\fR parameter is specified, this file is prepended +in front of the ZIP archive, otherwise the file returned by \fBinfo +nameofexecutable\fR (i.e., the executable file of the running process) is +used. If the \fIpassword\fR parameter is not empty, an obfuscated version of +that password is placed between the image and ZIP chunks of the output file +and the contents of the ZIP chunk are protected with that password. .RS .PP -Caution: highly experimental, not usable on Android, only partially tested -on Linux and Windows. +Caution: highly experimental, not usable on Android, only partially tested on +Linux and Windows. .RE .TP \fBzipfs mkkey\fR \fIpassword\fR . -For the clear text \fIpassword\fR argument an obfuscated string version -is returned with the same format used in the \fBzipfs mkimg\fR command. +For the clear text \fIpassword\fR argument, an obfuscated string version is +returned with the same format used in the \fBzipfs mkimg\fR command. .TP -\fBzipfs mkzip\fR \fIoutfile\fR \fIindir\fR \fI?strip?\fR \fI?password?\fR +\fBzipfs mkzip\fR \fIoutfile indir\fR ?\fIstrip\fR? ?\fIpassword\fR? . Creates a ZIP archive file named \fIoutfile\fR from the contents of the input directory \fIindir\fR (contained regular files only) with optional ZIP @@ -91,31 +126,9 @@ optional file name prefix given in \fIstrip\fR is stripped off the beginning of the respective file name. .RS .PP -Caution: the choice of the \fIindir\fR parameter -(less the optional stripped prefix) determines the later root name of the -archive's content. +Caution: the choice of the \fIindir\fR parameter (less the optional stripped +prefix) determines the later root name of the archive's content. .RE -.TP -\fBzipfs mount ?\fImountpoint\fR? ?\fIzipfile\fR? ?\fIpassword\fR? -. -The \fBzipfs mount\fR command mounts a ZIP archive file as a VFS. -After this command executes, files contained in \fIzipfile\fR -will appear to Tcl to be regular files at the mount point. -.RS -.PP -With no \fIzipfile\fR, returns the zipfile mounted at \fImountpoint\fR. -With no \fImountpoint\fR, return all zipfile/mount pairs. -If \fImountpoint\fR is specified as an empty string, mount on file path. -.RE -.TP -\fBzipfs root\fR -Returns a constant string which indicates the mount point for zipfs volumes -for the current platform. On Windows, this value is zipfs:/. On Unux, //zipfs:/ -.RE -.TP -\fBzipfs unmount \fImountpoint\fR -. -Unmounts a previously mounted ZIP archive mounted to \fImountpoint\fR. .SH "SEE ALSO" tclsh(1), file(n), zlib(n) .SH "KEYWORDS" -- cgit v0.12 From ffc7a9f0b97478b4efb04f82c7414b24c94409af Mon Sep 17 00:00:00 2001 From: dkf Date: Sat, 6 Oct 2018 13:07:52 +0000 Subject: More cleaning up. --- doc/zipfs.n | 8 +- generic/tclZipfs.c | 977 +++++++++++++++++++++++++++-------------------------- unix/Makefile.in | 4 +- 3 files changed, 508 insertions(+), 481 deletions(-) diff --git a/doc/zipfs.n b/doc/zipfs.n index 9a241f4..3600e64 100644 --- a/doc/zipfs.n +++ b/doc/zipfs.n @@ -101,10 +101,10 @@ archives as Tcl applications. . Creates an image (potentially a new executable file) similar to \fBzipfs mkzip\fR. If the \fIinfile\fR parameter is specified, this file is prepended -in front of the ZIP archive, otherwise the file returned by \fBinfo -nameofexecutable\fR (i.e., the executable file of the running process) is -used. If the \fIpassword\fR parameter is not empty, an obfuscated version of -that password is placed between the image and ZIP chunks of the output file +in front of the ZIP archive, otherwise the file returned by +\fBinfo nameofexecutable\fR (i.e., the executable file of the running process) +is used. If the \fIpassword\fR parameter is not empty, an obfuscated version +of that password is placed between the image and ZIP chunks of the output file and the contents of the ZIP chunk are protected with that password. .RS .PP diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c index c66a447..4a0d24c 100644 --- a/generic/tclZipfs.c +++ b/generic/tclZipfs.c @@ -144,14 +144,14 @@ #define ZipReadShort(p) \ ((p)[0] | ((p)[1] << 8)) -#define zip_write_int(p, v) \ +#define ZipWriteInt(p, v) \ do { \ (p)[0] = (v) & 0xff; \ (p)[1] = ((v) >> 8) & 0xff; \ (p)[2] = ((v) >> 16) & 0xff; \ (p)[3] = ((v) >> 24) & 0xff; \ } while (0) -#define zip_write_short(p, v) \ +#define ZipWriteShort(p, v) \ do { \ (p)[0] = (v) & 0xff; \ (p)[1] = ((v) >> 8) & 0xff; \ @@ -180,25 +180,24 @@ TCL_DECLARE_MUTEX(localtimeMutex) typedef struct ZipFile { char *name; /* Archive name */ - size_t namelen; - char is_membuf; /* When true, not a file but a memory buffer */ + size_t nameLength; + char isMemBuffer; /* When true, not a file but a memory buffer */ Tcl_Channel chan; /* Channel handle or NULL */ unsigned char *data; /* Memory mapped or malloc'ed file */ size_t length; /* Length of memory mapped file */ - void *tofree; /* Non-NULL if malloc'ed file */ - size_t nfiles; /* Number of files in archive */ - size_t baseoffs; /* Archive start */ - size_t baseoffsp; /* Password start */ - size_t centoffs; /* Archive directory start */ - unsigned char pwbuf[264]; /* Password buffer */ - size_t nopen; /* Number of open files on archive */ + void *ptrToFree; /* Non-NULL if malloc'ed file */ + size_t numFiles; /* Number of files in archive */ + size_t baseOffset; /* Archive start */ + size_t passOffset; /* Password start */ + size_t directoryOffset; /* Archive directory start */ + unsigned char passBuf[264]; /* Password buffer */ + size_t numOpen; /* Number of open files on archive */ struct ZipEntry *entries; /* List of files in archive */ - struct ZipEntry *topents; /* List of top-level dirs in archive */ - size_t mntptlen; - char *mntpt; /* Mount point */ + struct ZipEntry *topEnts; /* List of top-level dirs in archive */ + char *mountPoint; /* Mount point */ + size_t mountPointLen; #ifdef _WIN32 - HANDLE mh; - int mntdrv; /* Drive letter of mount point */ + HANDLE mountHandle; #endif } ZipFile; @@ -339,31 +338,32 @@ const char *zipfs_literal_tcl_library = NULL; /* Function prototypes */ -int TclZipfs_Mount(Tcl_Interp *interp, const char *mntpt, - const char *zipname, const char *passwd); +int TclZipfs_Mount(Tcl_Interp *interp, + const char *mountPoint, const char *zipname, + const char *passwd); int TclZipfs_Mount_Buffer(Tcl_Interp *interp, - const char *mntpt, unsigned char *data, + const char *mountPoint, unsigned char *data, size_t datalen, int copy); -static int TclZipfs_AppHook_FindTclInit(const char *archive); -static int Zip_FSPathInFilesystemProc(Tcl_Obj *pathPtr, +static int ZipfsAppHookFindTclInit(const char *archive); +static int ZipFSPathInFilesystemProc(Tcl_Obj *pathPtr, ClientData *clientDataPtr); -static Tcl_Obj * Zip_FSFilesystemPathTypeProc(Tcl_Obj *pathPtr); -static Tcl_Obj * Zip_FSFilesystemSeparatorProc(Tcl_Obj *pathPtr); -static int Zip_FSStatProc(Tcl_Obj *pathPtr, Tcl_StatBuf *buf); -static int Zip_FSAccessProc(Tcl_Obj *pathPtr, int mode); -static Tcl_Channel Zip_FSOpenFileChannelProc(Tcl_Interp *interp, +static Tcl_Obj * ZipFSFilesystemPathTypeProc(Tcl_Obj *pathPtr); +static Tcl_Obj * ZipFSFilesystemSeparatorProc(Tcl_Obj *pathPtr); +static int ZipFSStatProc(Tcl_Obj *pathPtr, Tcl_StatBuf *buf); +static int ZipFSAccessProc(Tcl_Obj *pathPtr, int mode); +static Tcl_Channel ZipFSOpenFileChannelProc(Tcl_Interp *interp, Tcl_Obj *pathPtr, int mode, int permissions); -static int Zip_FSMatchInDirectoryProc(Tcl_Interp *interp, +static int ZipFSMatchInDirectoryProc(Tcl_Interp *interp, Tcl_Obj *result, Tcl_Obj *pathPtr, const char *pattern, Tcl_GlobTypeData *types); -static Tcl_Obj * Zip_FSListVolumesProc(void); -static const char *const *Zip_FSFileAttrStringsProc(Tcl_Obj *pathPtr, +static Tcl_Obj * ZipFSListVolumesProc(void); +static const char *const *ZipFSFileAttrStringsProc(Tcl_Obj *pathPtr, Tcl_Obj **objPtrRef); -static int Zip_FSFileAttrsGetProc(Tcl_Interp *interp, int index, +static int ZipFSFileAttrsGetProc(Tcl_Interp *interp, int index, Tcl_Obj *pathPtr, Tcl_Obj **objPtrRef); -static int Zip_FSFileAttrsSetProc(Tcl_Interp *interp, int index, +static int ZipFSFileAttrsSetProc(Tcl_Interp *interp, int index, Tcl_Obj *pathPtr, Tcl_Obj *objPtr); -static int Zip_FSLoadFile(Tcl_Interp *interp, Tcl_Obj *path, +static int ZipFSLoadFile(Tcl_Interp *interp, Tcl_Obj *path, Tcl_LoadHandle *loadHandle, Tcl_FSUnloadFileProc **unloadProcPtr, int flags); static void TclZipfs_C_Init(void); @@ -378,24 +378,24 @@ const Tcl_Filesystem zipfsFilesystem = { "zipfs", sizeof(Tcl_Filesystem), TCL_FILESYSTEM_VERSION_2, - Zip_FSPathInFilesystemProc, + ZipFSPathInFilesystemProc, NULL, /* dupInternalRepProc */ NULL, /* freeInternalRepProc */ NULL, /* internalToNormalizedProc */ NULL, /* createInternalRepProc */ NULL, /* normalizePathProc */ - Zip_FSFilesystemPathTypeProc, - Zip_FSFilesystemSeparatorProc, - Zip_FSStatProc, - Zip_FSAccessProc, - Zip_FSOpenFileChannelProc, - Zip_FSMatchInDirectoryProc, + ZipFSFilesystemPathTypeProc, + ZipFSFilesystemSeparatorProc, + ZipFSStatProc, + ZipFSAccessProc, + ZipFSOpenFileChannelProc, + ZipFSMatchInDirectoryProc, NULL, /* utimeProc */ NULL, /* linkProc */ - Zip_FSListVolumesProc, - Zip_FSFileAttrStringsProc, - Zip_FSFileAttrsGetProc, - Zip_FSFileAttrsSetProc, + ZipFSListVolumesProc, + ZipFSFileAttrStringsProc, + ZipFSFileAttrsGetProc, + ZipFSFileAttrsSetProc, NULL, /* createDirectoryProc */ NULL, /* removeDirectoryProc */ NULL, /* deleteFileProc */ @@ -403,7 +403,7 @@ const Tcl_Filesystem zipfsFilesystem = { NULL, /* renameFileProc */ NULL, /* copyDirectoryProc */ NULL, /* lstatProc */ - (Tcl_FSLoadFileProc *) Zip_FSLoadFile, + (Tcl_FSLoadFileProc *) ZipFSLoadFile, NULL, /* getCwdProc */ NULL, /* chdirProc */ }; @@ -630,61 +630,61 @@ CanonicalPath( int ZIPFSPATH) { char *path; - int i, j, c, isunc = 0, isvfs = 0, n = 0; - int zipfspath = 1; + int i, j, c, isUNC = 0, isVfs = 0, n = 0; + int haveZipfsPath = 1; #ifdef _WIN32 if ((tail[0] != '\0') && (strchr(drvletters, tail[0]) != NULL) && (tail[1] == ':')) { tail += 2; - zipfspath = 0; + haveZipfsPath = 0; } /* UNC style path */ if (tail[0] == '\\') { root = ""; ++tail; - zipfspath = 0; + haveZipfsPath = 0; } if (tail[0] == '\\') { root = "/"; ++tail; - zipfspath = 0; + haveZipfsPath = 0; } #endif /* _WIN32 */ - if (zipfspath) { + if (haveZipfsPath) { /* UNC style path */ if (root && strncmp(root, ZIPFS_VOLUME, ZIPFS_VOLUME_LEN) == 0) { - isvfs = 1; + isVfs = 1; } else if (tail && strncmp(tail, ZIPFS_VOLUME, ZIPFS_VOLUME_LEN) == 0) { - isvfs = 2; + isVfs = 2; } - if (isvfs != 1 && (root[0] == '/') && (root[1] == '/')) { - isunc = 1; + if (isVfs != 1 && (root[0] == '/') && (root[1] == '/')) { + isUNC = 1; } } - if (isvfs != 2) { + if (isVfs != 2) { if (tail[0] == '/') { - if (isvfs != 1) { + if (isVfs != 1) { root = ""; } ++tail; - isunc = 0; + isUNC = 0; } if (tail[0] == '/') { - if (isvfs != 1) { + if (isVfs != 1) { root = "/"; } ++tail; - isunc = 1; + isUNC = 1; } } i = strlen(root); j = strlen(tail); - switch (isvfs) { + switch (isVfs) { case 1: if (i > ZIPFS_VOLUME_LEN) { Tcl_DStringSetLength(dsPtr, i + j + 1); @@ -754,9 +754,9 @@ CanonicalPath( while ((j > 0) && (path[j - 1] != '/')) { j--; } - if (j > isunc) { + if (j > isUNC) { --j; - while ((j > 1 + isunc) && (path[j - 2] == '/')) { + while ((j > 1 + isUNC) && (path[j - 2] == '/')) { j--; } } @@ -835,7 +835,7 @@ ZipFSLookupMount( while (hPtr != NULL) { ZipFile *zf = Tcl_GetHashValue(hPtr); - if (zf != NULL && strcmp(zf->mntpt, filename) == 0) { + if (strcmp(zf->mountPoint, filename) == 0) { return 1; } hPtr = Tcl_NextHashEntry(&search); @@ -866,37 +866,37 @@ ZipFSCloseArchive( Tcl_Interp *interp, /* Current interpreter. */ ZipFile *zf) { - if (zf->namelen) { - free(zf->name); /* Allocated by strdup */ + if (zf->nameLength) { + ckfree(zf->name); } - if (zf->is_membuf == 1) { + if (zf->isMemBuffer) { /* Pointer to memory */ - if (zf->tofree != NULL) { - Tcl_Free(zf->tofree); - zf->tofree = NULL; + if (zf->ptrToFree != NULL) { + ckfree(zf->ptrToFree); + zf->ptrToFree = NULL; } zf->data = NULL; return; } #ifdef _WIN32 - if ((zf->data != NULL) && (zf->tofree == NULL)) { + if ((zf->data != NULL) && (zf->ptrToFree == NULL)) { UnmapViewOfFile(zf->data); zf->data = NULL; } - if (zf->mh != INVALID_HANDLE_VALUE) { - CloseHandle(zf->mh); + if (zf->mountHandle != INVALID_HANDLE_VALUE) { + CloseHandle(zf->mountHandle); } #else /* !_WIN32 */ - if ((zf->data != MAP_FAILED) && (zf->tofree == NULL)) { + if ((zf->data != MAP_FAILED) && (zf->ptrToFree == NULL)) { munmap(zf->data, zf->length); zf->data = MAP_FAILED; } #endif /* _WIN32 */ - if (zf->tofree != NULL) { - Tcl_Free(zf->tofree); - zf->tofree = NULL; + if (zf->ptrToFree != NULL) { + ckfree(zf->ptrToFree); + zf->ptrToFree = NULL; } if (zf->chan != NULL) { Tcl_Close(interp, zf->chan); @@ -907,7 +907,7 @@ ZipFSCloseArchive( /* *------------------------------------------------------------------------- * - * ZipFS_Find_TOC -- + * ZipFSFindTOC -- * * This function takes a memory mapped zip file and indexes the contents. * When "needZip" is zero an embedded ZIP archive in an executable file @@ -925,7 +925,7 @@ ZipFSCloseArchive( */ static int -ZipFS_Find_TOC( +ZipFSFindTOC( Tcl_Interp *interp, /* Current interpreter. NULLable. */ int needZip, ZipFile *zf) @@ -946,16 +946,16 @@ ZipFS_Find_TOC( } if (p < zf->data) { if (!needZip) { - zf->baseoffs = zf->baseoffsp = zf->length; + zf->baseOffset = zf->passOffset = zf->length; return TCL_OK; } ZIPFS_ERROR(interp, "wrong end signature"); goto error; } - zf->nfiles = ZipReadShort(p + ZIP_CENTRAL_ENTS_OFFS); - if (zf->nfiles == 0) { + zf->numFiles = ZipReadShort(p + ZIP_CENTRAL_ENTS_OFFS); + if (zf->numFiles == 0) { if (!needZip) { - zf->baseoffs = zf->baseoffsp = zf->length; + zf->baseOffset = zf->passOffset = zf->length; return TCL_OK; } ZIPFS_ERROR(interp, "empty archive"); @@ -966,16 +966,16 @@ ZipFS_Find_TOC( if ((p < zf->data) || (p > zf->data + zf->length) || (q < zf->data) || (q > zf->data + zf->length)) { if (!needZip) { - zf->baseoffs = zf->baseoffsp = zf->length; + zf->baseOffset = zf->passOffset = zf->length; return TCL_OK; } ZIPFS_ERROR(interp, "archive directory not found"); goto error; } - zf->baseoffs = zf->baseoffsp = p - q; - zf->centoffs = p - zf->data; + zf->baseOffset = zf->passOffset = p - q; + zf->directoryOffset = p - zf->data; q = p; - for (i = 0; i < zf->nfiles; i++) { + for (i = 0; i < zf->numFiles; i++) { int pathlen, comlen, extra; if (q + ZIP_CENTRAL_HEADER_LEN > zf->data + zf->length) { @@ -991,13 +991,13 @@ ZipFS_Find_TOC( extra = ZipReadShort(q + ZIP_CENTRAL_EXTRALEN_OFFS); q += pathlen + comlen + extra + ZIP_CENTRAL_HEADER_LEN; } - q = zf->data + zf->baseoffs; - if ((zf->baseoffs >= 6) && (ZipReadInt(q - 4) == ZIP_PASSWORD_END_SIG)) { + q = zf->data + zf->baseOffset; + if ((zf->baseOffset >= 6) && (ZipReadInt(q - 4) == ZIP_PASSWORD_END_SIG)) { i = q[-5]; if (q - 5 - i > zf->data) { - zf->pwbuf[0] = i; - memcpy(zf->pwbuf + 1, q - 5 - i, i); - zf->baseoffsp -= i ? (5 + i) : 0; + zf->passBuf[0] = i; + memcpy(zf->passBuf + 1, q - 5 - i, i); + zf->passOffset -= i ? (5 + i) : 0; } } return TCL_OK; @@ -1039,19 +1039,19 @@ ZipFSOpenArchive( size_t i; ClientData handle; - zf->namelen = 0; - zf->is_membuf = 0; + zf->nameLength = 0; + zf->isMemBuffer = 0; #ifdef _WIN32 zf->data = NULL; - zf->mh = INVALID_HANDLE_VALUE; + zf->mountHandle = INVALID_HANDLE_VALUE; #else /* !_WIN32 */ zf->data = MAP_FAILED; #endif /* _WIN32 */ zf->length = 0; - zf->nfiles = 0; - zf->baseoffs = zf->baseoffsp = 0; - zf->tofree = NULL; - zf->pwbuf[0] = 0; + zf->numFiles = 0; + zf->baseOffset = zf->passOffset = 0; + zf->ptrToFree = NULL; + zf->passBuf[0] = 0; zf->chan = Tcl_OpenFileChannel(interp, zipname, "rb", 0); if (zf->chan == NULL) { return TCL_ERROR; @@ -1071,8 +1071,8 @@ ZipFSOpenArchive( ZIPFS_POSIX_ERROR(interp, "seek error"); goto error; } - zf->tofree = zf->data = (unsigned char *) Tcl_AttemptAlloc(zf->length); - if (zf->tofree == NULL) { + zf->ptrToFree = zf->data = attemptckalloc(zf->length); + if (zf->ptrToFree == NULL) { ZIPFS_ERROR(interp, "out of memory"); goto error; } @@ -1097,13 +1097,14 @@ ZipFSOpenArchive( ZIPFS_POSIX_ERROR(interp, "invalid file size"); goto error; } - zf->mh = CreateFileMapping((HANDLE) handle, 0, PAGE_READONLY, 0, - zf->length, 0); - if (zf->mh == INVALID_HANDLE_VALUE) { + zf->mountHandle = CreateFileMapping((HANDLE) handle, 0, PAGE_READONLY, + 0, zf->length, 0); + if (zf->mountHandle == INVALID_HANDLE_VALUE) { ZIPFS_POSIX_ERROR(interp, "file mapping failed"); goto error; } - zf->data = MapViewOfFile(zf->mh, FILE_MAP_READ, 0, 0, zf->length); + zf->data = MapViewOfFile(zf->mountHandle, FILE_MAP_READ, 0, 0, + zf->length); if (zf->data == NULL) { ZIPFS_POSIX_ERROR(interp, "file mapping failed"); goto error; @@ -1123,7 +1124,7 @@ ZipFSOpenArchive( } #endif /* _WIN32 */ } - return ZipFS_Find_TOC(interp, needZip, zf); + return ZipFSFindTOC(interp, needZip, zf); error: ZipFSCloseArchive(interp, zf); @@ -1148,10 +1149,10 @@ ZipFSOpenArchive( */ static int -ZipFS_Catalogue_Filesystem( +ZipFSCatalogFilesystem( Tcl_Interp *interp, /* Current interpreter. NULLable. */ ZipFile *zf0, - const char *mntpt, /* Mount point path. */ + const char *mountPoint, /* Mount point path. */ const char *passwd, /* Password for opening the ZIP, or NULL if * the ZIP is unprotected. */ const char *zipname) /* Path to ZIP file to build a catalog of. */ @@ -1189,23 +1190,23 @@ ZipFS_Catalogue_Filesystem( Tcl_DStringInit(&ds); Tcl_DStringInit(&dsm); - if (strcmp(mntpt, "/") == 0) { - mntpt = ""; + if (strcmp(mountPoint, "/") == 0) { + mountPoint = ""; } else { - mntpt = CanonicalPath("", mntpt, &dsm, 1); + mountPoint = CanonicalPath("", mountPoint, &dsm, 1); } - hPtr = Tcl_CreateHashEntry(&ZipFS.zipHash, mntpt, &isNew); + hPtr = Tcl_CreateHashEntry(&ZipFS.zipHash, mountPoint, &isNew); if (!isNew) { - zf = Tcl_GetHashValue(hPtr); if (interp != NULL) { + zf = Tcl_GetHashValue(hPtr); Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "%s is already mounted on %s", zf->name, mntpt)); + "%s is already mounted on %s", zf->name, mountPoint)); } Unlock(); ZipFSCloseArchive(interp, zf0); return TCL_ERROR; } - zf = (ZipFile *) Tcl_AttemptAlloc(sizeof(ZipFile) + strlen(mntpt) + 1); + zf = attemptckalloc(sizeof(ZipFile) + strlen(mountPoint) + 1); if (zf == NULL) { if (interp != NULL) { Tcl_AppendResult(interp, "out of memory", (char *) NULL); @@ -1217,55 +1218,53 @@ ZipFS_Catalogue_Filesystem( Unlock(); *zf = *zf0; - zf->mntpt = Tcl_GetHashKey(&ZipFS.zipHash, hPtr); - zf->mntptlen = strlen(zf->mntpt); - zf->name = strdup(zipname); - zf->namelen = strlen(zipname); + zf->mountPoint = Tcl_GetHashKey(&ZipFS.zipHash, hPtr); + zf->mountPointLen = strlen(zf->mountPoint); + zf->nameLength = strlen(zipname); + zf->name = ckalloc(zf->nameLength + 1); + memcpy(zf->name, zipname, zf->nameLength + 1); zf->entries = NULL; - zf->topents = NULL; - zf->nopen = 0; + zf->topEnts = NULL; + zf->numOpen = 0; Tcl_SetHashValue(hPtr, zf); - if ((zf->pwbuf[0] == 0) && pwlen) { + if ((zf->passBuf[0] == 0) && pwlen) { int k = 0; i = pwlen; - zf->pwbuf[k++] = i; + zf->passBuf[k++] = i; while (i > 0) { - zf->pwbuf[k] = (passwd[i - 1] & 0x0f) + zf->passBuf[k] = (passwd[i - 1] & 0x0f) | pwrot[(passwd[i - 1] >> 4) & 0x0f]; k++; i--; } - zf->pwbuf[k] = '\0'; + zf->passBuf[k] = '\0'; } - if (mntpt[0] != '\0') { - z = (ZipEntry *) Tcl_Alloc(sizeof(ZipEntry)); - z->name = NULL; - z->tnext = NULL; - z->depth = CountSlashes(mntpt); - z->zipfile = zf; - z->isdir = (zf->baseoffs == 0) ? 1 : -1; /* root marker */ - z->isenc = 0; - z->offset = zf->baseoffs; - z->crc32 = 0; - z->timestamp = 0; - z->nbyte = z->nbytecompr = 0; - z->cmeth = ZIP_COMPMETH_STORED; - z->data = NULL; - hPtr = Tcl_CreateHashEntry(&ZipFS.fileHash, mntpt, &isNew); - if (!isNew) { - /* skip it */ - Tcl_Free((char *) z); - } else { + if (mountPoint[0] != '\0') { + hPtr = Tcl_CreateHashEntry(&ZipFS.fileHash, mountPoint, &isNew); + if (isNew) { + z = ckalloc(sizeof(ZipEntry)); Tcl_SetHashValue(hPtr, z); + + z->tnext = NULL; + z->depth = CountSlashes(mountPoint); + z->zipfile = zf; + z->isdir = (zf->baseOffset == 0) ? 1 : -1; /* root marker */ + z->isenc = 0; + z->offset = zf->baseOffset; + z->crc32 = 0; + z->timestamp = 0; + z->nbyte = z->nbytecompr = 0; + z->cmeth = ZIP_COMPMETH_STORED; + z->data = NULL; z->name = Tcl_GetHashKey(&ZipFS.fileHash, hPtr); z->next = zf->entries; zf->entries = z; } } - q = zf->data + zf->centoffs; + q = zf->data + zf->directoryOffset; Tcl_DStringInit(&fpBuf); - for (i = 0; i < zf->nfiles; i++) { + for (i = 0; i < zf->numFiles; i++) { int extra, isdir = 0, dosTime, dosDate, nbcompr; size_t offs, pathlen, comlen; unsigned char *lq, *gq = NULL; @@ -1285,7 +1284,7 @@ ZipFS_Catalogue_Filesystem( if ((strcmp(path, ".") == 0) || (strcmp(path, "..") == 0)) { goto nextent; } - lq = zf->data + zf->baseoffs + lq = zf->data + zf->baseOffset + ZipReadInt(q + ZIP_CENTRAL_LOCALHDR_OFFS); if ((lq < zf->data) || (lq > zf->data + zf->length)) { goto nextent; @@ -1304,7 +1303,7 @@ ZipFS_Catalogue_Filesystem( if (offs + nbcompr > zf->length) { goto nextent; } - if (!isdir && (mntpt[0] == '\0') && !CountSlashes(path)) { + if (!isdir && (mountPoint[0] == '\0') && !CountSlashes(path)) { #ifdef ANDROID /* * When mounting the ZIP archive on the root directory try to @@ -1338,8 +1337,8 @@ ZipFS_Catalogue_Filesystem( #endif /* ANDROID */ } Tcl_DStringSetLength(&fpBuf, 0); - fullpath = CanonicalPath(mntpt, path, &fpBuf, 1); - z = (ZipEntry *) Tcl_Alloc(sizeof(ZipEntry)); + fullpath = CanonicalPath(mountPoint, path, &fpBuf, 1); + z = ckalloc(sizeof(ZipEntry)); z->name = NULL; z->tnext = NULL; z->depth = CountSlashes(fullpath); @@ -1368,15 +1367,15 @@ ZipFS_Catalogue_Filesystem( hPtr = Tcl_CreateHashEntry(&ZipFS.fileHash, fullpath, &isNew); if (!isNew) { /* should not happen but skip it anyway */ - Tcl_Free((char *) z); + ckfree(z); } else { Tcl_SetHashValue(hPtr, z); z->name = Tcl_GetHashKey(&ZipFS.fileHash, hPtr); z->next = zf->entries; zf->entries = z; - if (isdir && (mntpt[0] == '\0') && (z->depth == 1)) { - z->tnext = zf->topents; - zf->topents = z; + if (isdir && (mountPoint[0] == '\0') && (z->depth == 1)) { + z->tnext = zf->topEnts; + zf->topEnts = z; } if (!z->isdir && (z->depth > 1)) { char *dir, *end; @@ -1393,7 +1392,7 @@ ZipFS_Catalogue_Filesystem( if (!isNew) { break; } - zd = (ZipEntry *) Tcl_Alloc(sizeof(ZipEntry)); + zd = ckalloc(sizeof(ZipEntry)); zd->name = NULL; zd->tnext = NULL; zd->depth = CountSlashes(dir); @@ -1410,9 +1409,9 @@ ZipFS_Catalogue_Filesystem( zd->name = Tcl_GetHashKey(&ZipFS.fileHash, hPtr); zd->next = zf->entries; zf->entries = zd; - if ((mntpt[0] == '\0') && (zd->depth == 1)) { - zd->tnext = zf->topents; - zf->topents = zd; + if ((mountPoint[0] == '\0') && (zd->depth == 1)) { + zd->tnext = zf->topEnts; + zf->topEnts = zd; } end = strrchr(dir, '/'); } @@ -1428,25 +1427,37 @@ ZipFS_Catalogue_Filesystem( return TCL_OK; } +/* + *------------------------------------------------------------------------- + * + * TclZipfs_C_Init -- + * + * Common initialisation code. ZipFS.initialized must *not* be set prior + * to the call. + * + *------------------------------------------------------------------------- + */ + static void TclZipfs_C_Init(void) { +#ifdef TCL_THREADS static const Tcl_Time t = { 0, 0 }; - if (!ZipFS.initialized) { -#ifdef TCL_THREADS - /* - * Inflate condition variable. - */ - Tcl_MutexLock(&ZipFSMutex); - Tcl_ConditionWait(&ZipFSCond, &ZipFSMutex, &t); - Tcl_MutexUnlock(&ZipFSMutex); + /* + * Inflate condition variable. + */ + + Tcl_MutexLock(&ZipFSMutex); + Tcl_ConditionWait(&ZipFSCond, &ZipFSMutex, &t); + Tcl_MutexUnlock(&ZipFSMutex); #endif /* TCL_THREADS */ - Tcl_FSRegister(NULL, &zipfsFilesystem); - Tcl_InitHashTable(&ZipFS.fileHash, TCL_STRING_KEYS); - Tcl_InitHashTable(&ZipFS.zipHash, TCL_STRING_KEYS); - ZipFS.initialized = ZipFS.idCount = 1; - } + + Tcl_FSRegister(NULL, &zipfsFilesystem); + Tcl_InitHashTable(&ZipFS.fileHash, TCL_STRING_KEYS); + Tcl_InitHashTable(&ZipFS.zipHash, TCL_STRING_KEYS); + ZipFS.idCount = 1; + ZipFS.initialized = 1; } /* @@ -1470,7 +1481,7 @@ TclZipfs_C_Init(void) int TclZipfs_Mount( Tcl_Interp *interp, /* Current interpreter. NULLable. */ - const char *mntpt, /* Mount point path. */ + const char *mountPoint, /* Mount point path. */ const char *zipname, /* Path to ZIP file to mount. */ const char *passwd) /* Password for opening the ZIP, or NULL if * the ZIP is unprotected. */ @@ -1482,7 +1493,7 @@ TclZipfs_Mount( if (!ZipFS.initialized) { TclZipfs_C_Init(); } - if (mntpt == NULL) { + if (mountPoint == NULL) { Tcl_HashEntry *hPtr; Tcl_HashSearch search; int ret = TCL_OK; @@ -1491,13 +1502,11 @@ TclZipfs_Mount( hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); while (hPtr != NULL) { zf = Tcl_GetHashValue(hPtr); - if (zf != NULL) { - if (interp != NULL) { - Tcl_AppendElement(interp, zf->mntpt); - Tcl_AppendElement(interp, zf->name); - } - ++i; + if (interp != NULL) { + Tcl_AppendElement(interp, zf->mountPoint); + Tcl_AppendElement(interp, zf->name); } + ++i; hPtr = Tcl_NextHashEntry(&search); } if (interp == NULL) { @@ -1509,13 +1518,12 @@ TclZipfs_Mount( if (zipname == NULL) { if (interp != NULL) { - Tcl_HashEntry *hPtr = Tcl_FindHashEntry(&ZipFS.zipHash, mntpt); + Tcl_HashEntry *hPtr = + Tcl_FindHashEntry(&ZipFS.zipHash, mountPoint); if (hPtr != NULL) { zf = Tcl_GetHashValue(hPtr); - if (zf != NULL) { - Tcl_SetObjResult(interp, Tcl_NewStringObj(zf->name, -1)); - } + Tcl_SetObjResult(interp, Tcl_NewStringObj(zf->name, -1)); } } Unlock(); @@ -1533,7 +1541,7 @@ TclZipfs_Mount( return TCL_ERROR; } } - zf = (ZipFile *) Tcl_AttemptAlloc(sizeof(ZipFile) + strlen(mntpt) + 1); + zf = attemptckalloc(sizeof(ZipFile) + strlen(mountPoint) + 1); if (zf == NULL) { if (interp != NULL) { Tcl_AppendResult(interp, "out of memory", (char *) NULL); @@ -1543,7 +1551,7 @@ TclZipfs_Mount( if (ZipFSOpenArchive(interp, zipname, 1, zf) != TCL_OK) { return TCL_ERROR; } - return ZipFS_Catalogue_Filesystem(interp, zf, mntpt, passwd, zipname); + return ZipFSCatalogFilesystem(interp, zf, mountPoint, passwd, zipname); } /* @@ -1567,7 +1575,7 @@ TclZipfs_Mount( int TclZipfs_Mount_Buffer( Tcl_Interp *interp, /* Current interpreter. NULLable. */ - const char *mntpt, /* Mount point path. */ + const char *mountPoint, /* Mount point path. */ unsigned char *data, size_t datalen, int copy) @@ -1578,7 +1586,7 @@ TclZipfs_Mount_Buffer( if (!ZipFS.initialized) { TclZipfs_C_Init(); } - if (mntpt == NULL) { + if (mountPoint == NULL) { Tcl_HashEntry *hPtr; Tcl_HashSearch search; int ret = (interp ? TCL_BREAK : TCL_OK); @@ -1586,17 +1594,15 @@ TclZipfs_Mount_Buffer( hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); while (hPtr != NULL) { zf = Tcl_GetHashValue(hPtr); - if (zf != NULL) { - if (interp != NULL) { - Tcl_AppendElement(interp, zf->mntpt); - Tcl_AppendElement(interp, zf->name); - } else { - ret = TCL_OK; - /* - * Stop searching here if we're not returning a list. - */ - break; - } + if (interp != NULL) { + Tcl_AppendElement(interp, zf->mountPoint); + Tcl_AppendElement(interp, zf->name); + } else { + ret = TCL_OK; + /* + * Stop searching here if we're not returning a list. + */ + break; } hPtr = Tcl_NextHashEntry(&search); } @@ -1606,13 +1612,12 @@ TclZipfs_Mount_Buffer( if (data == NULL) { if (interp != NULL) { - Tcl_HashEntry *hPtr = Tcl_FindHashEntry(&ZipFS.zipHash, mntpt); + Tcl_HashEntry *hPtr = + Tcl_FindHashEntry(&ZipFS.zipHash, mountPoint); if (hPtr != NULL) { zf = Tcl_GetHashValue(hPtr); - if (zf != NULL) { - Tcl_SetObjResult(interp, Tcl_NewStringObj(zf->name, -1)); - } + Tcl_SetObjResult(interp, Tcl_NewStringObj(zf->name, -1)); } } Unlock(); @@ -1620,17 +1625,17 @@ TclZipfs_Mount_Buffer( } Unlock(); - zf = (ZipFile *) Tcl_AttemptAlloc(sizeof(ZipFile) + strlen(mntpt) + 1); + zf = attemptckalloc(sizeof(ZipFile) + strlen(mountPoint) + 1); if (zf == NULL) { if (interp != NULL) { Tcl_AppendResult(interp, "out of memory", (char *) NULL); } return TCL_ERROR; } - zf->is_membuf = 1; + zf->isMemBuffer = 1; zf->length = datalen; if (copy) { - zf->data = (unsigned char *) Tcl_AttemptAlloc(datalen); + zf->data = attemptckalloc(datalen); if (zf->data == NULL) { if (interp != NULL) { Tcl_AppendResult(interp, "out of memory", (char *) NULL); @@ -1638,15 +1643,15 @@ TclZipfs_Mount_Buffer( return TCL_ERROR; } memcpy(zf->data, data, datalen); - zf->tofree = zf->data; + zf->ptrToFree = zf->data; } else { zf->data = data; - zf->tofree = NULL; + zf->ptrToFree = NULL; } - if (ZipFS_Find_TOC(interp, 0, zf) != TCL_OK) { + if (ZipFSFindTOC(interp, 0, zf) != TCL_OK) { return TCL_ERROR; } - return ZipFS_Catalogue_Filesystem(interp, zf, mntpt, NULL, + return ZipFSCatalogFilesystem(interp, zf, mountPoint, NULL, "Memory Buffer"); } @@ -1669,7 +1674,7 @@ TclZipfs_Mount_Buffer( int TclZipfs_Unmount( Tcl_Interp *interp, /* Current interpreter. NULLable. */ - const char *mntpt) /* Mount point path. */ + const char *mountPoint) /* Mount point path. */ { ZipFile *zf; ZipEntry *z, *znext; @@ -1688,16 +1693,16 @@ TclZipfs_Unmount( */ Tcl_DStringInit(&dsm); - mntpt = CanonicalPath("", mntpt, &dsm, 1); + mountPoint = CanonicalPath("", mountPoint, &dsm, 1); - hPtr = Tcl_FindHashEntry(&ZipFS.zipHash, mntpt); + hPtr = Tcl_FindHashEntry(&ZipFS.zipHash, mountPoint); /* don't report no-such-mount as an error */ if (hPtr == NULL) { goto done; } zf = Tcl_GetHashValue(hPtr); - if (zf->nopen > 0) { + if (zf->numOpen > 0) { ZIPFS_ERROR(interp, "filesystem is busy"); ret = TCL_ERROR; goto done; @@ -1710,12 +1715,12 @@ TclZipfs_Unmount( Tcl_DeleteHashEntry(hPtr); } if (z->data != NULL) { - Tcl_Free((char *) z->data); + ckfree(z->data); } - Tcl_Free((char *) z); + ckfree(z); } ZipFSCloseArchive(interp, zf); - Tcl_Free((char *) zf); + ckfree(zf); unmounted = 1; done: Unlock(); @@ -1782,7 +1787,7 @@ ZipFSMountBufferObjCmd( int objc, Tcl_Obj *const objv[]) { - const char *mntpt; /* Mount point path. */ + const char *mountPoint; /* Mount point path. */ unsigned char *data; int length; @@ -1800,35 +1805,31 @@ ZipFSMountBufferObjCmd( while (hPtr != NULL) { ZipFile *zf = Tcl_GetHashValue(hPtr); - if (zf != NULL) { - Tcl_AppendElement(interp, zf->mntpt); - Tcl_AppendElement(interp, zf->name); - } + Tcl_AppendElement(interp, zf->mountPoint); + Tcl_AppendElement(interp, zf->name); hPtr = Tcl_NextHashEntry(&search); } Unlock(); return ret; } - mntpt = Tcl_GetString(objv[1]); + mountPoint = Tcl_GetString(objv[1]); if (objc < 3) { Tcl_HashEntry *hPtr; ReadLock(); - hPtr = Tcl_FindHashEntry(&ZipFS.zipHash, mntpt); + hPtr = Tcl_FindHashEntry(&ZipFS.zipHash, mountPoint); if (hPtr != NULL) { ZipFile *zf = Tcl_GetHashValue(hPtr); - if (zf != NULL) { - Tcl_SetObjResult(interp, Tcl_NewStringObj(zf->name, -1)); - } + Tcl_SetObjResult(interp, Tcl_NewStringObj(zf->name, -1)); } Unlock(); return TCL_OK; } data = Tcl_GetByteArrayFromObj(objv[2], &length); - return TclZipfs_Mount_Buffer(interp, mntpt, data, length, 1); + return TclZipfs_Mount_Buffer(interp, mountPoint, data, length, 1); } /* @@ -1913,7 +1914,7 @@ ZipFSMkKeyObjCmd( Tcl_Obj *const objv[]) { int len, i = 0; - char *pw, pwbuf[264]; + char *pw, passBuf[264]; if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "password"); @@ -1931,18 +1932,18 @@ ZipFSMkKeyObjCmd( while (len > 0) { int ch = pw[len - 1]; - pwbuf[i] = (ch & 0x0f) | pwrot[(ch >> 4) & 0x0f]; + passBuf[i] = (ch & 0x0f) | pwrot[(ch >> 4) & 0x0f]; i++; len--; } - pwbuf[i] = i; + passBuf[i] = i; ++i; - pwbuf[i++] = (char) ZIP_PASSWORD_END_SIG; - pwbuf[i++] = (char) (ZIP_PASSWORD_END_SIG >> 8); - pwbuf[i++] = (char) (ZIP_PASSWORD_END_SIG >> 16); - pwbuf[i++] = (char) (ZIP_PASSWORD_END_SIG >> 24); - pwbuf[i] = '\0'; - Tcl_AppendResult(interp, pwbuf, (char *) NULL); + passBuf[i++] = (char) ZIP_PASSWORD_END_SIG; + passBuf[i++] = (char) (ZIP_PASSWORD_END_SIG >> 8); + passBuf[i++] = (char) (ZIP_PASSWORD_END_SIG >> 16); + passBuf[i++] = (char) (ZIP_PASSWORD_END_SIG >> 24); + passBuf[i] = '\0'; + Tcl_AppendResult(interp, passBuf, (char *) NULL); return TCL_OK; } @@ -2067,9 +2068,9 @@ ZipAddFile( */ align = 4 + ((len + pos[0]) & 3); - zip_write_short(abuf, 0xffff); - zip_write_short(abuf + 2, align - 4); - zip_write_int(abuf + 4, 0x03020100); + ZipWriteShort(abuf, 0xffff); + ZipWriteShort(abuf + 2, align - 4); + ZipWriteInt(abuf + 4, 0x03020100); if ((size_t) Tcl_Write(out, (const char *) abuf, align) != align) { goto wrerr; } @@ -2224,7 +2225,7 @@ ZipAddFile( } Tcl_Close(interp, in); - z = (ZipEntry *) Tcl_Alloc(sizeof(ZipEntry)); + z = ckalloc(sizeof(ZipEntry)); z->name = NULL; z->tnext = NULL; z->depth = 0; @@ -2242,10 +2243,10 @@ ZipAddFile( if (!isNew) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "non-unique path name \"%s\"", path)); - Tcl_Free((char *) z); + ckfree(z); return TCL_ERROR; } else { - Tcl_SetHashValue(hPtr, (ClientData) z); + Tcl_SetHashValue(hPtr, z); z->name = Tcl_GetHashKey(fileHash, hPtr); z->next = NULL; } @@ -2253,27 +2254,27 @@ ZipAddFile( /* * Write final local header information. */ - zip_write_int(buf + ZIP_LOCAL_SIG_OFFS, ZIP_LOCAL_HEADER_SIG); - zip_write_short(buf + ZIP_LOCAL_VERSION_OFFS, ZIP_MIN_VERSION); - zip_write_short(buf + ZIP_LOCAL_FLAGS_OFFS, z->isenc); - zip_write_short(buf + ZIP_LOCAL_COMPMETH_OFFS, z->cmeth); - zip_write_short(buf + ZIP_LOCAL_MTIME_OFFS, ToDosTime(z->timestamp)); - zip_write_short(buf + ZIP_LOCAL_MDATE_OFFS, ToDosDate(z->timestamp)); - zip_write_int(buf + ZIP_LOCAL_CRC32_OFFS, z->crc32); - zip_write_int(buf + ZIP_LOCAL_COMPLEN_OFFS, z->nbytecompr); - zip_write_int(buf + ZIP_LOCAL_UNCOMPLEN_OFFS, z->nbyte); - zip_write_short(buf + ZIP_LOCAL_PATHLEN_OFFS, zpathlen); - zip_write_short(buf + ZIP_LOCAL_EXTRALEN_OFFS, align); + ZipWriteInt(buf + ZIP_LOCAL_SIG_OFFS, ZIP_LOCAL_HEADER_SIG); + ZipWriteShort(buf + ZIP_LOCAL_VERSION_OFFS, ZIP_MIN_VERSION); + ZipWriteShort(buf + ZIP_LOCAL_FLAGS_OFFS, z->isenc); + ZipWriteShort(buf + ZIP_LOCAL_COMPMETH_OFFS, z->cmeth); + ZipWriteShort(buf + ZIP_LOCAL_MTIME_OFFS, ToDosTime(z->timestamp)); + ZipWriteShort(buf + ZIP_LOCAL_MDATE_OFFS, ToDosDate(z->timestamp)); + ZipWriteInt(buf + ZIP_LOCAL_CRC32_OFFS, z->crc32); + ZipWriteInt(buf + ZIP_LOCAL_COMPLEN_OFFS, z->nbytecompr); + ZipWriteInt(buf + ZIP_LOCAL_UNCOMPLEN_OFFS, z->nbyte); + ZipWriteShort(buf + ZIP_LOCAL_PATHLEN_OFFS, zpathlen); + ZipWriteShort(buf + ZIP_LOCAL_EXTRALEN_OFFS, align); if (Tcl_Seek(out, pos[0], SEEK_SET) != pos[0]) { Tcl_DeleteHashEntry(hPtr); - Tcl_Free((char *) z); + ckfree(z); Tcl_SetObjResult(interp, Tcl_ObjPrintf( "seek error: %s", Tcl_PosixError(interp))); return TCL_ERROR; } if (Tcl_Write(out, buf, ZIP_LOCAL_HEADER_LEN) != ZIP_LOCAL_HEADER_LEN) { Tcl_DeleteHashEntry(hPtr); - Tcl_Free((char *) z); + ckfree(z); Tcl_SetObjResult(interp, Tcl_ObjPrintf( "write error: %s", Tcl_PosixError(interp))); return TCL_ERROR; @@ -2281,7 +2282,7 @@ ZipAddFile( Tcl_Flush(out); if (Tcl_Seek(out, pos[1], SEEK_SET) != pos[1]) { Tcl_DeleteHashEntry(hPtr); - Tcl_Free((char *) z); + ckfree(z); Tcl_SetObjResult(interp, Tcl_ObjPrintf( "seek error: %s", Tcl_PosixError(interp))); return TCL_ERROR; @@ -2326,13 +2327,13 @@ ZipFSMkZipOrImgObjCmd( Tcl_HashEntry *hPtr; Tcl_HashSearch search; Tcl_HashTable fileHash; - char *strip = NULL, *pw = NULL, pwbuf[264], buf[4096]; + char *strip = NULL, *pw = NULL, passBuf[264], buf[4096]; /* * Caller has verified that the number of arguments is correct. */ - pwbuf[0] = 0; + passBuf[0] = 0; if (objc > (isList ? 3 : 4)) { pw = Tcl_GetString(objv[isList ? 3 : 4]); pwlen = strlen(pw); @@ -2402,29 +2403,27 @@ ZipFSMkZipOrImgObjCmd( while (len > 0) { int ch = pw[len - 1]; - pwbuf[i] = (ch & 0x0f) | pwrot[(ch >> 4) & 0x0f]; + passBuf[i] = (ch & 0x0f) | pwrot[(ch >> 4) & 0x0f]; i++; len--; } - pwbuf[i] = i; + passBuf[i] = i; ++i; - pwbuf[i++] = (char) ZIP_PASSWORD_END_SIG; - pwbuf[i++] = (char) (ZIP_PASSWORD_END_SIG >> 8); - pwbuf[i++] = (char) (ZIP_PASSWORD_END_SIG >> 16); - pwbuf[i++] = (char) (ZIP_PASSWORD_END_SIG >> 24); - pwbuf[i] = '\0'; + passBuf[i++] = (char) ZIP_PASSWORD_END_SIG; + passBuf[i++] = (char) (ZIP_PASSWORD_END_SIG >> 8); + passBuf[i++] = (char) (ZIP_PASSWORD_END_SIG >> 16); + passBuf[i++] = (char) (ZIP_PASSWORD_END_SIG >> 24); + passBuf[i] = '\0'; } /* Check for mounted image */ WriteLock(); hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); while (hPtr != NULL) { zf = Tcl_GetHashValue(hPtr); - if (zf != NULL) { - if (strcmp(zf->name, imgName) == 0) { - isMounted = 1; - zf->nopen++; - break; - } + if (strcmp(zf->name, imgName) == 0) { + isMounted = 1; + zf->numOpen++; + break; } hPtr = Tcl_NextHashEntry(&search); } @@ -2434,8 +2433,8 @@ ZipFSMkZipOrImgObjCmd( } if (isMounted || ZipFSOpenArchive(interp, imgName, 0, zf) == TCL_OK) { if ((size_t) Tcl_Write(out, (char *) zf->data, - zf->baseoffsp) != zf->baseoffsp) { - memset(pwbuf, 0, sizeof(pwbuf)); + zf->passOffset) != zf->passOffset) { + memset(passBuf, 0, sizeof(passBuf)); Tcl_DecrRefCount(list); Tcl_SetObjResult(interp, Tcl_ObjPrintf( "write error: %s", Tcl_PosixError(interp))); @@ -2444,7 +2443,7 @@ ZipFSMkZipOrImgObjCmd( ZipFSCloseArchive(interp, zf); } else { WriteLock(); - zf->nopen--; + zf->numOpen--; Unlock(); } return TCL_ERROR; @@ -2453,7 +2452,7 @@ ZipFSMkZipOrImgObjCmd( ZipFSCloseArchive(interp, zf); } else { WriteLock(); - zf->nopen--; + zf->numOpen--; Unlock(); } } else { @@ -2470,7 +2469,7 @@ ZipFSMkZipOrImgObjCmd( Tcl_ResetResult(interp); in = Tcl_OpenFileChannel(interp, imgName, "rb", 0644); if (in == NULL) { - memset(pwbuf, 0, sizeof(pwbuf)); + memset(passBuf, 0, sizeof(passBuf)); Tcl_DecrRefCount(list); Tcl_Close(interp, out); return TCL_ERROR; @@ -2478,7 +2477,7 @@ ZipFSMkZipOrImgObjCmd( i = Tcl_Seek(in, 0, SEEK_END); if (i == ERROR_LENGTH) { cperr: - memset(pwbuf, 0, sizeof(pwbuf)); + memset(passBuf, 0, sizeof(passBuf)); Tcl_DecrRefCount(list); Tcl_SetObjResult(interp, Tcl_ObjPrintf( "%s: %s", errMsg, Tcl_PosixError(interp))); @@ -2509,9 +2508,9 @@ ZipFSMkZipOrImgObjCmd( } Tcl_Close(interp, in); } - len = strlen(pwbuf); + len = strlen(passBuf); if (len > 0) { - i = Tcl_Write(out, pwbuf, len); + i = Tcl_Write(out, passBuf, len); if (i != len) { Tcl_DecrRefCount(list); Tcl_SetObjResult(interp, Tcl_ObjPrintf( @@ -2520,7 +2519,7 @@ ZipFSMkZipOrImgObjCmd( return TCL_ERROR; } } - memset(pwbuf, 0, sizeof(pwbuf)); + memset(passBuf, 0, sizeof(passBuf)); Tcl_Flush(out); } Tcl_InitHashTable(&fileHash, TCL_STRING_KEYS); @@ -2586,23 +2585,23 @@ ZipFSMkZipOrImgObjCmd( } z = Tcl_GetHashValue(hPtr); len = strlen(z->name); - zip_write_int(buf + ZIP_CENTRAL_SIG_OFFS, ZIP_CENTRAL_HEADER_SIG); - zip_write_short(buf + ZIP_CENTRAL_VERSIONMADE_OFFS, ZIP_MIN_VERSION); - zip_write_short(buf + ZIP_CENTRAL_VERSION_OFFS, ZIP_MIN_VERSION); - zip_write_short(buf + ZIP_CENTRAL_FLAGS_OFFS, z->isenc ? 1 : 0); - zip_write_short(buf + ZIP_CENTRAL_COMPMETH_OFFS, z->cmeth); - zip_write_short(buf + ZIP_CENTRAL_MTIME_OFFS, ToDosTime(z->timestamp)); - zip_write_short(buf + ZIP_CENTRAL_MDATE_OFFS, ToDosDate(z->timestamp)); - zip_write_int(buf + ZIP_CENTRAL_CRC32_OFFS, z->crc32); - zip_write_int(buf + ZIP_CENTRAL_COMPLEN_OFFS, z->nbytecompr); - zip_write_int(buf + ZIP_CENTRAL_UNCOMPLEN_OFFS, z->nbyte); - zip_write_short(buf + ZIP_CENTRAL_PATHLEN_OFFS, len); - zip_write_short(buf + ZIP_CENTRAL_EXTRALEN_OFFS, 0); - zip_write_short(buf + ZIP_CENTRAL_FCOMMENTLEN_OFFS, 0); - zip_write_short(buf + ZIP_CENTRAL_DISKFILE_OFFS, 0); - zip_write_short(buf + ZIP_CENTRAL_IATTR_OFFS, 0); - zip_write_int(buf + ZIP_CENTRAL_EATTR_OFFS, 0); - zip_write_int(buf + ZIP_CENTRAL_LOCALHDR_OFFS, z->offset - pos[0]); + ZipWriteInt(buf + ZIP_CENTRAL_SIG_OFFS, ZIP_CENTRAL_HEADER_SIG); + ZipWriteShort(buf + ZIP_CENTRAL_VERSIONMADE_OFFS, ZIP_MIN_VERSION); + ZipWriteShort(buf + ZIP_CENTRAL_VERSION_OFFS, ZIP_MIN_VERSION); + ZipWriteShort(buf + ZIP_CENTRAL_FLAGS_OFFS, z->isenc ? 1 : 0); + ZipWriteShort(buf + ZIP_CENTRAL_COMPMETH_OFFS, z->cmeth); + ZipWriteShort(buf + ZIP_CENTRAL_MTIME_OFFS, ToDosTime(z->timestamp)); + ZipWriteShort(buf + ZIP_CENTRAL_MDATE_OFFS, ToDosDate(z->timestamp)); + ZipWriteInt(buf + ZIP_CENTRAL_CRC32_OFFS, z->crc32); + ZipWriteInt(buf + ZIP_CENTRAL_COMPLEN_OFFS, z->nbytecompr); + ZipWriteInt(buf + ZIP_CENTRAL_UNCOMPLEN_OFFS, z->nbyte); + ZipWriteShort(buf + ZIP_CENTRAL_PATHLEN_OFFS, len); + ZipWriteShort(buf + ZIP_CENTRAL_EXTRALEN_OFFS, 0); + ZipWriteShort(buf + ZIP_CENTRAL_FCOMMENTLEN_OFFS, 0); + ZipWriteShort(buf + ZIP_CENTRAL_DISKFILE_OFFS, 0); + ZipWriteShort(buf + ZIP_CENTRAL_IATTR_OFFS, 0); + ZipWriteInt(buf + ZIP_CENTRAL_EATTR_OFFS, 0); + ZipWriteInt(buf + ZIP_CENTRAL_LOCALHDR_OFFS, z->offset - pos[0]); if ((Tcl_Write(out, buf, ZIP_CENTRAL_HEADER_LEN) != ZIP_CENTRAL_HEADER_LEN) || ((size_t) Tcl_Write(out, z->name, len) != len)) { @@ -2614,14 +2613,14 @@ ZipFSMkZipOrImgObjCmd( } Tcl_Flush(out); pos[2] = Tcl_Tell(out); - zip_write_int(buf + ZIP_CENTRAL_END_SIG_OFFS, ZIP_CENTRAL_END_SIG); - zip_write_short(buf + ZIP_CENTRAL_DISKNO_OFFS, 0); - zip_write_short(buf + ZIP_CENTRAL_DISKDIR_OFFS, 0); - zip_write_short(buf + ZIP_CENTRAL_ENTS_OFFS, count); - zip_write_short(buf + ZIP_CENTRAL_TOTALENTS_OFFS, count); - zip_write_int(buf + ZIP_CENTRAL_DIRSIZE_OFFS, pos[2] - pos[1]); - zip_write_int(buf + ZIP_CENTRAL_DIRSTART_OFFS, pos[1] - pos[0]); - zip_write_short(buf + ZIP_CENTRAL_COMMENTLEN_OFFS, 0); + ZipWriteInt(buf + ZIP_CENTRAL_END_SIG_OFFS, ZIP_CENTRAL_END_SIG); + ZipWriteShort(buf + ZIP_CENTRAL_DISKNO_OFFS, 0); + ZipWriteShort(buf + ZIP_CENTRAL_DISKDIR_OFFS, 0); + ZipWriteShort(buf + ZIP_CENTRAL_ENTS_OFFS, count); + ZipWriteShort(buf + ZIP_CENTRAL_TOTALENTS_OFFS, count); + ZipWriteInt(buf + ZIP_CENTRAL_DIRSIZE_OFFS, pos[2] - pos[1]); + ZipWriteInt(buf + ZIP_CENTRAL_DIRSTART_OFFS, pos[1] - pos[0]); + ZipWriteShort(buf + ZIP_CENTRAL_COMMENTLEN_OFFS, 0); if (Tcl_Write(out, buf, ZIP_CENTRAL_END_LEN) != ZIP_CENTRAL_END_LEN) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "write error: %s", Tcl_PosixError(interp))); @@ -2640,7 +2639,7 @@ ZipFSMkZipOrImgObjCmd( hPtr = Tcl_FirstHashEntry(&fileHash, &search); while (hPtr != NULL) { z = Tcl_GetHashValue(hPtr); - Tcl_Free((char *) z); + ckfree(z); Tcl_DeleteHashEntry(hPtr); hPtr = Tcl_NextHashEntry(&search); } @@ -2676,6 +2675,11 @@ ZipFSMkZipObjCmd( Tcl_WrongNumArgs(interp, 1, objv, "outfile indir ?strip? ?password?"); return TCL_ERROR; } + if (Tcl_IsSafe(interp)) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "operation not permitted in a safe interpreter", -1)); + return TCL_ERROR; + } return ZipFSMkZipOrImgObjCmd(clientData, interp, 0, 0, objc, objv); } @@ -2690,6 +2694,11 @@ ZipFSLMkZipObjCmd( Tcl_WrongNumArgs(interp, 1, objv, "outfile inlist ?password?"); return TCL_ERROR; } + if (Tcl_IsSafe(interp)) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "operation not permitted in a safe interpreter", -1)); + return TCL_ERROR; + } return ZipFSMkZipOrImgObjCmd(clientData, interp, 0, 1, objc, objv); } @@ -2722,6 +2731,11 @@ ZipFSMkImgObjCmd( "outfile indir ?strip? ?password? ?infile?"); return TCL_ERROR; } + if (Tcl_IsSafe(interp)) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "operation not permitted in a safe interpreter", -1)); + return TCL_ERROR; + } return ZipFSMkZipOrImgObjCmd(clientData, interp, 1, 0, objc, objv); } @@ -2736,6 +2750,11 @@ ZipFSLMkImgObjCmd( Tcl_WrongNumArgs(interp, 1, objv, "outfile inlist ?password infile?"); return TCL_ERROR; } + if (Tcl_IsSafe(interp)) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "operation not permitted in a safe interpreter", -1)); + return TCL_ERROR; + } return ZipFSMkZipOrImgObjCmd(clientData, interp, 1, 1, objc, objv); } @@ -3042,29 +3061,29 @@ TclZipfs_TclLibrary(void) * Mount zip file and dll before releasing to search. */ - if (TclZipfs_AppHook_FindTclInit(dllname) == TCL_OK) { + if (ZipfsAppHookFindTclInit(dllname) == TCL_OK) { return Tcl_NewStringObj(zipfs_literal_tcl_library, -1); } #elif /* !_WIN32 && */ defined(CFG_RUNTIME_DLLFILE) /* * Mount zip file and dll before releasing to search. */ - if (TclZipfs_AppHook_FindTclInit( + if (ZipfsAppHookFindTclInit( CFG_RUNTIME_LIBDIR "/" CFG_RUNTIME_DLLFILE) == TCL_OK) { return Tcl_NewStringObj(zipfs_literal_tcl_library, -1); } #endif /* _WIN32 || CFG_RUNTIME_DLLFILE */ #ifdef CFG_RUNTIME_ZIPFILE - if (TclZipfs_AppHook_FindTclInit( + if (ZipfsAppHookFindTclInit( CFG_RUNTIME_LIBDIR "/" CFG_RUNTIME_ZIPFILE) == TCL_OK) { return Tcl_NewStringObj(zipfs_literal_tcl_library, -1); } - if (TclZipfs_AppHook_FindTclInit( + if (ZipfsAppHookFindTclInit( CFG_RUNTIME_SCRDIR "/" CFG_RUNTIME_ZIPFILE) == TCL_OK) { return Tcl_NewStringObj(zipfs_literal_tcl_library, -1); } - if (TclZipfs_AppHook_FindTclInit(CFG_RUNTIME_ZIPFILE) == TCL_OK) { + if (ZipfsAppHookFindTclInit(CFG_RUNTIME_ZIPFILE) == TCL_OK) { return Tcl_NewStringObj(zipfs_literal_tcl_library, -1); } #endif /* CFG_RUNTIME_ZIPFILE */ @@ -3128,10 +3147,10 @@ ZipChannelClose( ClientData instanceData, Tcl_Interp *interp) /* Current interpreter. */ { - ZipChannel *info = (ZipChannel *) instanceData; + ZipChannel *info = instanceData; if (info->iscompr && (info->ubuf != NULL)) { - Tcl_Free((char *) info->ubuf); + ckfree(info->ubuf); info->ubuf = NULL; } if (info->isenc) { @@ -3140,13 +3159,11 @@ ZipChannelClose( } if (info->iswr) { ZipEntry *z = info->zipentry; - unsigned char *newdata; + unsigned char *newdata = attemptckrealloc(info->ubuf, info->nread); - newdata = (unsigned char *) - Tcl_AttemptRealloc((char *) info->ubuf, info->nread); if (newdata != NULL) { if (z->data != NULL) { - Tcl_Free((char *) z->data); + ckfree(z->data); } z->data = newdata; z->nbyte = z->nbytecompr = info->nbyte; @@ -3157,13 +3174,13 @@ ZipChannelClose( z->offset = 0; z->crc32 = 0; } else { - Tcl_Free((char *) info->ubuf); + ckfree(info->ubuf); } } WriteLock(); - info->zipfile->nopen--; + info->zipfile->numOpen--; Unlock(); - Tcl_Free((char *) info); + ckfree(info); return TCL_OK; } @@ -3200,9 +3217,9 @@ ZipChannelRead( */ nextpos = info->nread + toRead; - if (nextpos > info->zipfile->baseoffs) { - toRead = info->zipfile->baseoffs - info->nread; - nextpos = info->zipfile->baseoffs; + if (nextpos > info->zipfile->baseOffset) { + toRead = info->zipfile->baseOffset - info->nread; + nextpos = info->zipfile->baseOffset; } if (toRead == 0) { return 0; @@ -3318,7 +3335,7 @@ ZipChannelSeek( * Special case: when executable combined with ZIP archive file, seek * within front of ZIP, i.e. the executable itself. */ - end = info->zipfile->baseoffs; + end = info->zipfile->baseOffset; } else if (info->isdir) { *errloc = EINVAL; return -1; @@ -3492,7 +3509,7 @@ ZipChannelOpen( } if (!trunc) { flags |= TCL_READABLE; - if (z->isenc && (z->zipfile->pwbuf[0] == 0)) { + if (z->isenc && (z->zipfile->passBuf[0] == 0)) { ZIPFS_ERROR(interp, "decryption failed"); goto error; } else if (wr && (z->data == NULL) && (z->nbyte > ZipFS.wrmax)) { @@ -3502,7 +3519,7 @@ ZipChannelOpen( } else { flags = TCL_WRITABLE; } - info = (ZipChannel *) Tcl_AttemptAlloc(sizeof(ZipChannel)); + info = attemptckalloc(sizeof(ZipChannel)); if (info == NULL) { ZIPFS_ERROR(interp, "out of memory"); goto error; @@ -3517,13 +3534,13 @@ ZipChannelOpen( info->nmax = ZipFS.wrmax; info->iscompr = 0; info->isenc = 0; - info->ubuf = (unsigned char *) Tcl_AttemptAlloc(info->nmax); + info->ubuf = attemptckalloc(info->nmax); if (info->ubuf == NULL) { merror0: if (info->ubuf != NULL) { - Tcl_Free((char *) info->ubuf); + ckfree(info->ubuf); } - Tcl_Free((char *) info); + ckfree(info); ZIPFS_ERROR(interp, "out of memory"); goto error; } @@ -3542,16 +3559,16 @@ ZipChannelOpen( unsigned char *zbuf = z->zipfile->data + z->offset; if (z->isenc) { - int len = z->zipfile->pwbuf[0]; - char pwbuf[260]; + int len = z->zipfile->passBuf[0]; + char passBuf[260]; for (i = 0; i < len; i++) { - ch = z->zipfile->pwbuf[len - i]; - pwbuf[i] = (ch & 0x0f) | pwrot[(ch >> 4) & 0x0f]; + ch = z->zipfile->passBuf[len - i]; + passBuf[i] = (ch & 0x0f) | pwrot[(ch >> 4) & 0x0f]; } - pwbuf[i] = '\0'; - init_keys(pwbuf, info->keys, crc32tab); - memset(pwbuf, 0, sizeof(pwbuf)); + passBuf[i] = '\0'; + init_keys(passBuf, info->keys, crc32tab); + memset(passBuf, 0, sizeof(passBuf)); for (i = 0; i < 12; i++) { ch = info->ubuf[i]; zdecode(info->keys, crc32tab, ch); @@ -3572,7 +3589,7 @@ ZipChannelOpen( unsigned int j; stream.avail_in -= 12; - cbuf = (unsigned char *) Tcl_AttemptAlloc(stream.avail_in); + cbuf = attemptckalloc(stream.avail_in); if (cbuf == NULL) { goto merror0; } @@ -3595,19 +3612,19 @@ ZipChannelOpen( || ((err == Z_OK) && (stream.avail_in == 0))) { if (cbuf != NULL) { memset(info->keys, 0, sizeof(info->keys)); - Tcl_Free((char *) cbuf); + ckfree(cbuf); } goto wrapchan; } cerror0: if (cbuf != NULL) { memset(info->keys, 0, sizeof(info->keys)); - Tcl_Free((char *) cbuf); + ckfree(cbuf); } if (info->ubuf != NULL) { - Tcl_Free((char *) info->ubuf); + ckfree(info->ubuf); } - Tcl_Free((char *) info); + ckfree(info); ZIPFS_ERROR(interp, "decompression error"); goto error; } else if (z->isenc) { @@ -3640,16 +3657,16 @@ ZipChannelOpen( info->nbyte = z->nbyte; info->nmax = 0; if (info->isenc) { - int len = z->zipfile->pwbuf[0]; - char pwbuf[260]; + int len = z->zipfile->passBuf[0]; + char passBuf[260]; for (i = 0; i < len; i++) { - ch = z->zipfile->pwbuf[len - i]; - pwbuf[i] = (ch & 0x0f) | pwrot[(ch >> 4) & 0x0f]; + ch = z->zipfile->passBuf[len - i]; + passBuf[i] = (ch & 0x0f) | pwrot[(ch >> 4) & 0x0f]; } - pwbuf[i] = '\0'; - init_keys(pwbuf, info->keys, crc32tab); - memset(pwbuf, 0, sizeof(pwbuf)); + passBuf[i] = '\0'; + init_keys(passBuf, info->keys, crc32tab); + memset(passBuf, 0, sizeof(passBuf)); for (i = 0; i < 12; i++) { ch = info->ubuf[i]; zdecode(info->keys, crc32tab, ch); @@ -3669,7 +3686,7 @@ ZipChannelOpen( stream.avail_in = z->nbytecompr; if (info->isenc) { stream.avail_in -= 12; - ubuf = (unsigned char *) Tcl_AttemptAlloc(stream.avail_in); + ubuf = attemptckalloc(stream.avail_in); if (ubuf == NULL) { info->ubuf = NULL; goto merror; @@ -3682,19 +3699,18 @@ ZipChannelOpen( } else { stream.next_in = info->ubuf; } - stream.next_out = info->ubuf = (unsigned char *) - Tcl_AttemptAlloc(info->nbyte); + stream.next_out = info->ubuf = attemptckalloc(info->nbyte); if (info->ubuf == NULL) { merror: if (ubuf != NULL) { info->isenc = 0; memset(info->keys, 0, sizeof(info->keys)); - Tcl_Free((char *) ubuf); + ckfree(ubuf); } - Tcl_Free((char *) info); + ckfree(info); if (interp != NULL) { Tcl_SetObjResult(interp, - Tcl_NewStringObj("out of memory", -1)); + Tcl_NewStringObj("out of memory", -1)); } goto error; } @@ -3709,7 +3725,7 @@ ZipChannelOpen( if (ubuf != NULL) { info->isenc = 0; memset(info->keys, 0, sizeof(info->keys)); - Tcl_Free((char *) ubuf); + ckfree(ubuf); } goto wrapchan; } @@ -3717,12 +3733,12 @@ ZipChannelOpen( if (ubuf != NULL) { info->isenc = 0; memset(info->keys, 0, sizeof(info->keys)); - Tcl_Free((char *) ubuf); + ckfree(ubuf); } if (info->ubuf != NULL) { - Tcl_Free((char *) info->ubuf); + ckfree(info->ubuf); } - Tcl_Free((char *) info); + ckfree(info); ZIPFS_ERROR(interp, "decompression error"); goto error; } @@ -3731,7 +3747,7 @@ ZipChannelOpen( wrapchan: sprintf(cname, "zipfs_%" TCL_LL_MODIFIER "x_%d", z->offset, ZipFS.idCount++); - z->zipfile->nopen++; + z->zipfile->numOpen++; Unlock(); return Tcl_CreateChannel(&ZipChannelType, cname, (ClientData) info, flags); @@ -3820,7 +3836,7 @@ ZipEntryAccess( /* *------------------------------------------------------------------------- * - * Zip_FSOpenFileChannelProc -- + * ZipFSOpenFileChannelProc -- * * Results: * @@ -3830,7 +3846,7 @@ ZipEntryAccess( */ static Tcl_Channel -Zip_FSOpenFileChannelProc( +ZipFSOpenFileChannelProc( Tcl_Interp *interp, /* Current interpreter. */ Tcl_Obj *pathPtr, int mode, @@ -3849,7 +3865,7 @@ Zip_FSOpenFileChannelProc( /* *------------------------------------------------------------------------- * - * Zip_FSStatProc -- + * ZipFSStatProc -- * * This function implements the ZIP filesystem specific version of the * library version of stat. @@ -3864,7 +3880,7 @@ Zip_FSOpenFileChannelProc( */ static int -Zip_FSStatProc( +ZipFSStatProc( Tcl_Obj *pathPtr, Tcl_StatBuf *buf) { @@ -3880,7 +3896,7 @@ Zip_FSStatProc( /* *------------------------------------------------------------------------- * - * Zip_FSAccessProc -- + * ZipFSAccessProc -- * * This function implements the ZIP filesystem specific version of the * library version of access. @@ -3895,7 +3911,7 @@ Zip_FSStatProc( */ static int -Zip_FSAccessProc( +ZipFSAccessProc( Tcl_Obj *pathPtr, int mode) { @@ -3911,7 +3927,7 @@ Zip_FSAccessProc( /* *------------------------------------------------------------------------- * - * Zip_FSFilesystemSeparatorProc -- + * ZipFSFilesystemSeparatorProc -- * * This function returns the separator to be used for a given path. The * object returned should have a refCount of zero @@ -3928,7 +3944,7 @@ Zip_FSAccessProc( */ static Tcl_Obj * -Zip_FSFilesystemSeparatorProc( +ZipFSFilesystemSeparatorProc( Tcl_Obj *pathPtr) { return Tcl_NewStringObj("/", -1); @@ -3937,7 +3953,7 @@ Zip_FSFilesystemSeparatorProc( /* *------------------------------------------------------------------------- * - * Zip_FSMatchInDirectoryProc -- + * ZipFSMatchInDirectoryProc -- * * This routine is used by the globbing code to search a directory for * all files which match a given pattern. @@ -3954,7 +3970,7 @@ Zip_FSFilesystemSeparatorProc( */ static int -Zip_FSMatchInDirectoryProc( +ZipFSMatchInDirectoryProc( Tcl_Interp *interp, /* Current interpreter. */ Tcl_Obj *result, Tcl_Obj *pathPtr, @@ -4017,10 +4033,10 @@ Zip_FSMatchInDirectoryProc( while (hPtr != NULL) { ZipFile *zf = Tcl_GetHashValue(hPtr); - if (zf->mntptlen == 0) { + if (zf->mountPointLen == 0) { ZipEntry *z; - for (z = zf->topents; z != NULL; z = z->tnext) { + for (z = zf->topEnts; z != NULL; z = z->tnext) { size_t lenz = strlen(z->name); if ((lenz > len + 1) && (strncmp(z->name, path, len) == 0) @@ -4040,20 +4056,23 @@ Zip_FSMatchInDirectoryProc( } } } - } else if ((zf->mntptlen > len + 1) - && (strncmp(zf->mntpt, path, len) == 0) - && (zf->mntpt[len] == '/') - && (CountSlashes(zf->mntpt) == l) - && Tcl_StringCaseMatch(zf->mntpt + len + 1, pattern, 0)) { + } else if ((zf->mountPointLen > len + 1) + && (strncmp(zf->mountPoint, path, len) == 0) + && (zf->mountPoint[len] == '/') + && (CountSlashes(zf->mountPoint) == l) + && Tcl_StringCaseMatch(zf->mountPoint + len + 1, + pattern, 0)) { if (prefix != NULL) { - Tcl_DStringAppend(&dsPref, zf->mntpt, zf->mntptlen); + Tcl_DStringAppend(&dsPref, zf->mountPoint, + zf->mountPointLen); Tcl_ListObjAppendElement(NULL, result, Tcl_NewStringObj(Tcl_DStringValue(&dsPref), Tcl_DStringLength(&dsPref))); Tcl_DStringSetLength(&dsPref, prefixLen); } else { Tcl_ListObjAppendElement(NULL, result, - Tcl_NewStringObj(zf->mntpt, zf->mntptlen)); + Tcl_NewStringObj(zf->mountPoint, + zf->mountPointLen)); } } hPtr = Tcl_NextHashEntry(&search); @@ -4084,7 +4103,7 @@ Zip_FSMatchInDirectoryProc( } l = strlen(pattern); - pat = Tcl_Alloc(len + l + 2); + pat = ckalloc(len + l + 2); memcpy(pat, path, len); while ((len > 1) && (pat[len - 1] == '/')) { --len; @@ -4116,7 +4135,7 @@ Zip_FSMatchInDirectoryProc( } } } - Tcl_Free(pat); + ckfree(pat); end: Unlock(); @@ -4127,7 +4146,7 @@ Zip_FSMatchInDirectoryProc( /* *------------------------------------------------------------------------- * - * Zip_FSPathInFilesystemProc -- + * ZipFSPathInFilesystemProc -- * * This function determines if the given path object is in the ZIP * filesystem. @@ -4142,7 +4161,7 @@ Zip_FSMatchInDirectoryProc( */ static int -Zip_FSPathInFilesystemProc( +ZipFSPathInFilesystemProc( Tcl_Obj *pathPtr, ClientData *clientDataPtr) { @@ -4175,10 +4194,10 @@ Zip_FSPathInFilesystemProc( hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); while (hPtr != NULL) { zf = Tcl_GetHashValue(hPtr); - if (zf->mntptlen == 0) { + if (zf->mountPointLen == 0) { ZipEntry *z; - for (z = zf->topents; z != NULL; z = z->tnext) { + for (z = zf->topEnts; z != NULL; z = z->tnext) { size_t lenz = strlen(z->name); if ((len >= lenz) && (strncmp(path, z->name, lenz) == 0)) { @@ -4186,8 +4205,8 @@ Zip_FSPathInFilesystemProc( goto endloop; } } - } else if ((len >= zf->mntptlen) && - (strncmp(path, zf->mntpt, zf->mntptlen) == 0)) { + } else if ((len >= zf->mountPointLen) && + (strncmp(path, zf->mountPoint, zf->mountPointLen) == 0)) { ret = TCL_OK; goto endloop; } @@ -4202,7 +4221,7 @@ Zip_FSPathInFilesystemProc( /* *------------------------------------------------------------------------- * - * Zip_FSListVolumesProc -- + * ZipFSListVolumesProc -- * * Lists the currently mounted ZIP filesystem volumes. * @@ -4216,7 +4235,7 @@ Zip_FSPathInFilesystemProc( */ static Tcl_Obj * -Zip_FSListVolumesProc(void) +ZipFSListVolumesProc(void) { return Tcl_NewStringObj(ZIPFS_VOLUME, -1); } @@ -4224,7 +4243,7 @@ Zip_FSListVolumesProc(void) /* *------------------------------------------------------------------------- * - * Zip_FSFileAttrStringsProc -- + * ZipFSFileAttrStringsProc -- * * This function implements the ZIP filesystem dependent 'file * attributes' subcommand, for listing the set of possible attribute @@ -4240,7 +4259,7 @@ Zip_FSListVolumesProc(void) */ static const char *const * -Zip_FSFileAttrStringsProc( +ZipFSFileAttrStringsProc( Tcl_Obj *pathPtr, Tcl_Obj **objPtrRef) { @@ -4259,7 +4278,7 @@ Zip_FSFileAttrStringsProc( /* *------------------------------------------------------------------------- * - * Zip_FSFileAttrsGetProc -- + * ZipFSFileAttrsGetProc -- * * This function implements the ZIP filesystem specific 'file attributes' * subcommand, for 'get' operations. @@ -4277,7 +4296,7 @@ Zip_FSFileAttrStringsProc( */ static int -Zip_FSFileAttrsGetProc( +ZipFSFileAttrsGetProc( Tcl_Interp *interp, /* Current interpreter. */ int index, Tcl_Obj *pathPtr, @@ -4302,25 +4321,28 @@ Zip_FSFileAttrsGetProc( switch (index) { case 0: *objPtrRef = Tcl_NewWideIntObj(z->nbyte); - goto done; + break; case 1: *objPtrRef = Tcl_NewWideIntObj(z->nbytecompr); - goto done; + break; case 2: *objPtrRef = Tcl_NewWideIntObj(z->offset); - goto done; + break; case 3: - *objPtrRef = Tcl_NewStringObj(z->zipfile->mntpt, z->zipfile->mntptlen); - goto done; + *objPtrRef = Tcl_NewStringObj(z->zipfile->mountPoint, + z->zipfile->mountPointLen); + break; case 4: *objPtrRef = Tcl_NewStringObj(z->zipfile->name, -1); - goto done; + break; case 5: *objPtrRef = Tcl_NewStringObj("0555", -1); - goto done; + break; + default: + ZIPFS_ERROR(interp, "unknown attribute"); + ret = TCL_ERROR; } - ZIPFS_ERROR(interp, "unknown attribute"); - ret = TCL_ERROR; + done: Unlock(); return ret; @@ -4329,7 +4351,7 @@ Zip_FSFileAttrsGetProc( /* *------------------------------------------------------------------------- * - * Zip_FSFileAttrsSetProc -- + * ZipFSFileAttrsSetProc -- * * This function implements the ZIP filesystem specific 'file attributes' * subcommand, for 'set' operations. @@ -4344,7 +4366,7 @@ Zip_FSFileAttrsGetProc( */ static int -Zip_FSFileAttrsSetProc( +ZipFSFileAttrsSetProc( Tcl_Interp *interp, /* Current interpreter. */ int index, Tcl_Obj *pathPtr, @@ -4359,7 +4381,7 @@ Zip_FSFileAttrsSetProc( /* *------------------------------------------------------------------------- * - * Zip_FSFilesystemPathTypeProc -- + * ZipFSFilesystemPathTypeProc -- * * Results: * @@ -4369,7 +4391,7 @@ Zip_FSFileAttrsSetProc( */ static Tcl_Obj * -Zip_FSFilesystemPathTypeProc( +ZipFSFilesystemPathTypeProc( Tcl_Obj *pathPtr) { return Tcl_NewStringObj("zip", -1); @@ -4378,7 +4400,7 @@ Zip_FSFilesystemPathTypeProc( /* *------------------------------------------------------------------------- * - * Zip_FSLoadFile -- + * ZipFSLoadFile -- * * This functions deals with loading native object code. If the given * path object refers to a file within the ZIP filesystem, an approriate @@ -4397,7 +4419,7 @@ Zip_FSFilesystemPathTypeProc( */ static int -Zip_FSLoadFile( +ZipFSLoadFile( Tcl_Interp *interp, /* Current interpreter. */ Tcl_Obj *path, Tcl_LoadHandle *loadHandle, @@ -4434,7 +4456,7 @@ Zip_FSLoadFile( } objs[1] = TclPathPart(interp, path, TCL_PATH_DIRNAME); - if ((objs[1] != NULL) && (Zip_FSAccessProc(objs[1], R_OK) == 0)) { + if ((objs[1] != NULL) && (ZipFSAccessProc(objs[1], R_OK) == 0)) { const char *execName = Tcl_GetNameOfExecutable(); /* @@ -4518,50 +4540,55 @@ TclZipfs_Init( Tcl_Interp *interp) /* Current interpreter. */ { #ifdef HAVE_ZLIB - /* one-time initialization */ + static const EnsembleImplMap initMap[] = { + {"mkimg", ZipFSMkImgObjCmd, NULL, NULL, NULL, 0}, + {"mkzip", ZipFSMkZipObjCmd, NULL, NULL, NULL, 0}, + {"lmkimg", ZipFSLMkImgObjCmd, NULL, NULL, NULL, 0}, + {"lmkzip", ZipFSLMkZipObjCmd, NULL, NULL, NULL, 0}, + /* The 4 entries above are not available in safe interpreters */ + {"mount", ZipFSMountObjCmd, NULL, NULL, NULL, 0}, + {"mount_data", ZipFSMountBufferObjCmd, NULL, NULL, NULL, 0}, + {"unmount", ZipFSUnmountObjCmd, NULL, NULL, NULL, 0}, + {"mkkey", ZipFSMkKeyObjCmd, NULL, NULL, NULL, 0}, + {"exists", ZipFSExistsObjCmd, NULL, NULL, NULL, 1}, + {"info", ZipFSInfoObjCmd, NULL, NULL, NULL, 1}, + {"list", ZipFSListObjCmd, NULL, NULL, NULL, 1}, + {"canonical", ZipFSCanonicalObjCmd, NULL, NULL, NULL, 1}, + {"root", ZipFSRootObjCmd, NULL, NULL, NULL, 1}, + {"tcl_library", ZipFSTclLibraryObjCmd, NULL, NULL, NULL, 0}, + {NULL, NULL, NULL, NULL, NULL, 0} + }; + static const char findproc[] = + "namespace eval ::tcl::zipfs {}\n" + "proc ::tcl::zipfs::Find dir {\n" + " set result {}\n" + " if {[catch {glob -directory $dir -nocomplain * .*} list]} {\n" + " return $result\n" + " }\n" + " foreach file $list {\n" + " if {[file tail $file] in {. ..}} {\n" + " continue\n" + " }\n" + " lappend result $file {*}[Find $file]\n" + " }\n" + " return $result\n" + "}\n" + "proc ::tcl::zipfs::find dir {\n" + " return [lsort [Find $dir]]\n" + "}\n"; + + /* + * One-time initialization. + */ + WriteLock(); /* Tcl_StaticPackage(interp, "zipfs", TclZipfs_Init, TclZipfs_Init); */ if (!ZipFS.initialized) { TclZipfs_C_Init(); } Unlock(); + if (interp != NULL) { - static const EnsembleImplMap initMap[] = { - {"mkimg", ZipFSMkImgObjCmd, NULL, NULL, NULL, 1}, - {"mkzip", ZipFSMkZipObjCmd, NULL, NULL, NULL, 1}, - {"lmkimg", ZipFSLMkImgObjCmd, NULL, NULL, NULL, 1}, - {"lmkzip", ZipFSLMkZipObjCmd, NULL, NULL, NULL, 1}, - /* The 4 entries above are not available in safe interpreters */ - {"mount", ZipFSMountObjCmd, NULL, NULL, NULL, 0}, - {"mount_data", ZipFSMountBufferObjCmd, NULL, NULL, NULL, 0}, - {"unmount", ZipFSUnmountObjCmd, NULL, NULL, NULL, 0}, - {"mkkey", ZipFSMkKeyObjCmd, NULL, NULL, NULL, 0}, - {"exists", ZipFSExistsObjCmd, NULL, NULL, NULL, 1}, - {"info", ZipFSInfoObjCmd, NULL, NULL, NULL, 1}, - {"list", ZipFSListObjCmd, NULL, NULL, NULL, 1}, - {"canonical", ZipFSCanonicalObjCmd, NULL, NULL, NULL, 1}, - {"root", ZipFSRootObjCmd, NULL, NULL, NULL, 1}, - {"tcl_library", ZipFSTclLibraryObjCmd, NULL, NULL, NULL, 0}, - {NULL, NULL, NULL, NULL, NULL, 0} - }; - static const char findproc[] = - "namespace eval ::tcl::zipfs {}\n" - "proc ::tcl::zipfs::Find dir {\n" - " set result {}\n" - " if {[catch {glob -directory $dir -nocomplain * .*} list]} {\n" - " return $result\n" - " }\n" - " foreach file $list {\n" - " if {[file tail $file] in {. ..}} {\n" - " continue\n" - " }\n" - " lappend result $file {*}[Find $file]\n" - " }\n" - " return $result\n" - "}\n" - "proc ::tcl::zipfs::find dir {\n" - " return [lsort [Find $dir]]\n" - "}\n"; Tcl_EvalEx(interp, findproc, -1, TCL_EVAL_GLOBAL); Tcl_LinkVar(interp, "::tcl::zipfs::wrmax", (char *) &ZipFS.wrmax, TCL_LINK_INT); @@ -4577,7 +4604,7 @@ TclZipfs_Init( } static int -TclZipfs_AppHook_FindTclInit( +ZipfsAppHookFindTclInit( const char *archive) { Tcl_Obj *vfsinitscript; @@ -4616,7 +4643,7 @@ TclZipfs_AppHook_FindTclInit( /* *------------------------------------------------------------------------- * - * Tclkit_MainHook -- + * TclZipfs_AppHook -- * * Performs the argument munging for the shell * @@ -4625,13 +4652,13 @@ TclZipfs_AppHook_FindTclInit( int TclZipfs_AppHook( - int *argcPtr, + int *argcPtr, /* Pointer to argc */ #ifdef _WIN32 TCHAR #else /* !_WIN32 */ char #endif /* _WIN32 */ - ***argvPtr) + ***argvPtr) /* Pointer to argv */ { #ifdef _WIN32 Tcl_DString ds; @@ -4649,18 +4676,18 @@ TclZipfs_AppHook( if (!TclZipfs_Mount(NULL, ZIPFS_APP_MOUNT, archive, NULL)) { int found; - Tcl_Obj *vfsinitscript; + Tcl_Obj *vfsInitScript; - vfsinitscript = Tcl_NewStringObj(ZIPFS_APP_MOUNT "/main.tcl", -1); - Tcl_IncrRefCount(vfsinitscript); - if (Tcl_FSAccess(vfsinitscript, F_OK) == 0) { + vfsInitScript = Tcl_NewStringObj(ZIPFS_APP_MOUNT "/main.tcl", -1); + Tcl_IncrRefCount(vfsInitScript); + if (Tcl_FSAccess(vfsInitScript, F_OK) == 0) { /* * Startup script should be set before calling Tcl_AppInit */ - Tcl_SetStartupScript(vfsinitscript, NULL); + Tcl_SetStartupScript(vfsInitScript, NULL); } else { - Tcl_DecrRefCount(vfsinitscript); + Tcl_DecrRefCount(vfsInitScript); } /* @@ -4668,11 +4695,11 @@ TclZipfs_AppHook( */ if (!zipfs_literal_tcl_library) { - vfsinitscript = Tcl_NewStringObj( + vfsInitScript = Tcl_NewStringObj( ZIPFS_APP_MOUNT "/tcl_library/init.tcl", -1); - Tcl_IncrRefCount(vfsinitscript); - found = Tcl_FSAccess(vfsinitscript, F_OK); - Tcl_DecrRefCount(vfsinitscript); + Tcl_IncrRefCount(vfsInitScript); + found = Tcl_FSAccess(vfsInitScript, F_OK); + Tcl_DecrRefCount(vfsInitScript); if (found == TCL_OK) { zipfs_literal_tcl_library = ZIPFS_APP_MOUNT "/tcl_library"; return TCL_OK; @@ -4691,7 +4718,7 @@ TclZipfs_AppHook( archive = (*argvPtr)[1]; #endif /* _WIN32 */ if (strcmp(archive, "install") == 0) { - Tcl_Obj *vfsinitscript; + Tcl_Obj *vfsInitScript; /* * Run this now to ensure the file is present by the time Tcl_Main @@ -4699,34 +4726,34 @@ TclZipfs_AppHook( */ TclZipfs_TclLibrary(); - vfsinitscript = Tcl_NewStringObj( + vfsInitScript = Tcl_NewStringObj( ZIPFS_ZIP_MOUNT "/tcl_library/install.tcl", -1); - Tcl_IncrRefCount(vfsinitscript); - if (Tcl_FSAccess(vfsinitscript, F_OK) == 0) { - Tcl_SetStartupScript(vfsinitscript, NULL); + Tcl_IncrRefCount(vfsInitScript); + if (Tcl_FSAccess(vfsInitScript, F_OK) == 0) { + Tcl_SetStartupScript(vfsInitScript, NULL); } return TCL_OK; } else if (!TclZipfs_Mount(NULL, ZIPFS_APP_MOUNT, archive, NULL)) { int found; - Tcl_Obj *vfsinitscript; + Tcl_Obj *vfsInitScript; - vfsinitscript = Tcl_NewStringObj(ZIPFS_APP_MOUNT "/main.tcl", -1); - Tcl_IncrRefCount(vfsinitscript); - if (Tcl_FSAccess(vfsinitscript, F_OK) == 0) { + vfsInitScript = Tcl_NewStringObj(ZIPFS_APP_MOUNT "/main.tcl", -1); + Tcl_IncrRefCount(vfsInitScript); + if (Tcl_FSAccess(vfsInitScript, F_OK) == 0) { /* * Startup script should be set before calling Tcl_AppInit */ - Tcl_SetStartupScript(vfsinitscript, NULL); + Tcl_SetStartupScript(vfsInitScript, NULL); } else { - Tcl_DecrRefCount(vfsinitscript); + Tcl_DecrRefCount(vfsInitScript); } /* Set Tcl Encodings */ - vfsinitscript = Tcl_NewStringObj( + vfsInitScript = Tcl_NewStringObj( ZIPFS_APP_MOUNT "/tcl_library/init.tcl", -1); - Tcl_IncrRefCount(vfsinitscript); - found = Tcl_FSAccess(vfsinitscript, F_OK); - Tcl_DecrRefCount(vfsinitscript); + Tcl_IncrRefCount(vfsInitScript); + found = Tcl_FSAccess(vfsInitScript, F_OK); + Tcl_DecrRefCount(vfsInitScript); if (found == TCL_OK) { zipfs_literal_tcl_library = ZIPFS_APP_MOUNT "/tcl_library"; return TCL_OK; @@ -4755,7 +4782,7 @@ TclZipfs_AppHook( int TclZipfs_Mount( Tcl_Interp *interp, /* Current interpreter. */ - const char *mntpt, /* Mount point path. */ + const char *mountPoint, /* Mount point path. */ const char *zipname, /* Path to ZIP file to mount. */ const char *passwd) /* Password for opening the ZIP, or NULL if * the ZIP is unprotected. */ @@ -4766,7 +4793,7 @@ TclZipfs_Mount( int TclZipfs_Unmount( Tcl_Interp *interp, /* Current interpreter. */ - const char *mntpt) /* Mount point path. */ + const char *mountPoint) /* Mount point path. */ { return TclZipfs_Init(interp, 1); } diff --git a/unix/Makefile.in b/unix/Makefile.in index b30d357..c44cc77 100644 --- a/unix/Makefile.in +++ b/unix/Makefile.in @@ -681,8 +681,8 @@ ${TCL_ZIP_FILE}: ${ZIP_INSTALL_OBJS} @rm -rf ${TCL_VFS_ROOT} @mkdir -p ${TCL_VFS_PATH} cp -a $(TOP_DIR)/library/* ${TCL_VFS_PATH} - ( cd ${TCL_VFS_ROOT} ; \ - ${NATIVE_ZIP} ${ZIP_PROG_OPTIONS} ../${TCL_ZIP_FILE} ${ZIP_PROG_VFSSEARCH}) + -find ${TCL_VFS_ROOT} -type d -empty -delete + ( cd ${TCL_VFS_ROOT} ; ${NATIVE_ZIP} ${ZIP_PROG_OPTIONS} ../${TCL_ZIP_FILE} ${ZIP_PROG_VFSSEARCH}) # The following target is configured by autoconf to generate either a shared # library or non-shared library for Tcl. -- cgit v0.12 From b5f75d3392ae32955aaef38e3d3af58119179a73 Mon Sep 17 00:00:00 2001 From: dkf Date: Sat, 6 Oct 2018 16:49:40 +0000 Subject: More regularizing of function names, field names and testing styles --- doc/zipfs.3 | 30 +- generic/tcl.decls | 17 +- generic/tclDecls.h | 21 +- generic/tclStubInit.c | 2 +- generic/tclZipfs.c | 1020 ++++++++++++++++++++++++++----------------------- tests/zipfs.test | 121 +++--- 6 files changed, 636 insertions(+), 575 deletions(-) diff --git a/doc/zipfs.3 b/doc/zipfs.3 index 568f461..8e2eacc 100644 --- a/doc/zipfs.3 +++ b/doc/zipfs.3 @@ -10,7 +10,7 @@ .so man.macros .BS .SH NAME -TclZipfs_AppHook, Tclzipfs_Mount, Tclzipfs_Unmount \- handle ZIP files as Tcl virtual filesystems +TclZipfs_AppHook, Tclzipfs_Mount, TclZipfs_MountBuffer, Tclzipfs_Unmount \- handle ZIP files as Tcl virtual filesystems .SH SYNOPSIS .nf int @@ -20,7 +20,10 @@ int \fBTclzipfs_Mount\fR(\fIinterp, mountpoint, zipname, password\fR) .sp int -\fBTclzipfs_Unmount\fR(\fIinterp, zipname\fR) +\fBTclZipfs_MountBuffer\fR(\fIinterp, mountpoint, data, dataLen, copy\fR) +.sp +int +\fBTclzipfs_Unmount\fR(\fIinterp, mountpoint\fR) .fi .SH ARGUMENTS .AS Tcl_Interp *mountpoint in @@ -40,6 +43,16 @@ Name of a mount point, which must be a legal Tcl file or directory name. May be NULL to query current mount points. .AP "const char" *password in An (optional) password. Use NULL if no password is wanted to read the file. +.AP "unsigned char" *data in +A data buffer to mount. The data buffer must hold the contents of a ZIP +archive, and must not be NULL. +.AP size_t dataLen in +The number of bytes in the supplied data buffer argument, \fIdata\fR. +.AP int copy in +If non-zero, the ZIP archive in the data buffer will be internally copied +before mounting, allowing the data buffer to be disposed once +\fBTclZipfs_MountBuffer\fR returns. If zero, the caller guarantees that the +buffer will be valid to read from for the duration of the mount. .BE .SH DESCRIPTION \fBTclZipfs_AppHook\fR is a utility function to perform standard application @@ -85,11 +98,20 @@ given in \fImountpoint\fR using the optional ZIP password \fIpassword\fR. Errors during that process are reported in the interpreter \fIinterp\fR. If \fImountpoint\fR is a NULL pointer, information on all currently mounted ZIP file systems is written into \fIinterp\fR's result as a sequence of mount -points and ZIP file names. +points and ZIP file names. The result of this call is a standard Tcl result +code. +.PP +\fBTclzipfs_MountBuffer\fR mounts the ZIP archive in the buffer pointed to by +\fIdata\fR on the mount point given in \fImountpoint\fR. The ZIP archive is +assumed to be not password protected. Errors during that process are reported +in the interpreter \fIinterp\fR. The \fIcopy\fR argument determines whether +the buffer is internally copied before mounting or not. The result of this +call is a standard Tcl result code. .PP \fBTclzipfs_Unmount\fR undoes the effect of \fBTclzipfs_Mount\fR, i.e., it unmounts the mounted ZIP file system that was mounted from \fIzipname\fR (at -\fImountpoint\fR). Errors are reported in the interpreter \fIinterp\fR. +\fImountpoint\fR). Errors are reported in the interpreter \fIinterp\fR. The +result of this call is a standard Tcl result code. .SH "SEE ALSO" zipfs(n) .SH KEYWORDS diff --git a/generic/tcl.decls b/generic/tcl.decls index 61247e6..dfcb822 100644 --- a/generic/tcl.decls +++ b/generic/tcl.decls @@ -2332,25 +2332,18 @@ declare 631 { # TIP #430 declare 632 { - int TclZipfs_Mount( - Tcl_Interp *interp, - const char *mntpt, - const char *zipname, - const char *passwd) + int TclZipfs_Mount(Tcl_Interp *interp, const char *mountPoint, + const char *zipname, const char *passwd) } declare 633 { - int TclZipfs_Unmount(Tcl_Interp *interp, const char *zipname) + int TclZipfs_Unmount(Tcl_Interp *interp, const char *mountPoint) } declare 634 { Tcl_Obj *TclZipfs_TclLibrary(void) } declare 635 { - int TclZipfs_Mount_Buffer( - Tcl_Interp *interp, - const char *mntpt, - unsigned char *data, - size_t datalen, - int copy) + int TclZipfs_MountBuffer(Tcl_Interp *interp, const char *mountPoint, + unsigned char *data, size_t datalen, int copy) } # ----- BASELINE -- FOR -- 8.7.0 ----- # diff --git a/generic/tclDecls.h b/generic/tclDecls.h index 3fb5355..e20782e 100644 --- a/generic/tclDecls.h +++ b/generic/tclDecls.h @@ -1863,16 +1863,17 @@ EXTERN Tcl_Channel Tcl_OpenTcpServerEx(Tcl_Interp *interp, Tcl_TcpAcceptProc *acceptProc, ClientData callbackData); /* 632 */ -EXTERN int TclZipfs_Mount(Tcl_Interp *interp, const char *mntpt, - const char *zipname, const char *passwd); +EXTERN int TclZipfs_Mount(Tcl_Interp *interp, + const char *mountPoint, const char *zipname, + const char *passwd); /* 633 */ EXTERN int TclZipfs_Unmount(Tcl_Interp *interp, - const char *zipname); + const char *mountPoint); /* 634 */ EXTERN Tcl_Obj * TclZipfs_TclLibrary(void); /* 635 */ -EXTERN int TclZipfs_Mount_Buffer(Tcl_Interp *interp, - const char *mntpt, unsigned char *data, +EXTERN int TclZipfs_MountBuffer(Tcl_Interp *interp, + const char *mountPoint, unsigned char *data, size_t datalen, int copy); typedef struct { @@ -2541,10 +2542,10 @@ typedef struct TclStubs { int (*tcl_FSUnloadFile) (Tcl_Interp *interp, Tcl_LoadHandle handlePtr); /* 629 */ void (*tcl_ZlibStreamSetCompressionDictionary) (Tcl_ZlibStream zhandle, Tcl_Obj *compressionDictionaryObj); /* 630 */ Tcl_Channel (*tcl_OpenTcpServerEx) (Tcl_Interp *interp, const char *service, const char *host, unsigned int flags, Tcl_TcpAcceptProc *acceptProc, ClientData callbackData); /* 631 */ - int (*tclZipfs_Mount) (Tcl_Interp *interp, const char *mntpt, const char *zipname, const char *passwd); /* 632 */ - int (*tclZipfs_Unmount) (Tcl_Interp *interp, const char *zipname); /* 633 */ + int (*tclZipfs_Mount) (Tcl_Interp *interp, const char *mountPoint, const char *zipname, const char *passwd); /* 632 */ + int (*tclZipfs_Unmount) (Tcl_Interp *interp, const char *mountPoint); /* 633 */ Tcl_Obj * (*tclZipfs_TclLibrary) (void); /* 634 */ - int (*tclZipfs_Mount_Buffer) (Tcl_Interp *interp, const char *mntpt, unsigned char *data, size_t datalen, int copy); /* 635 */ + int (*tclZipfs_MountBuffer) (Tcl_Interp *interp, const char *mountPoint, unsigned char *data, size_t datalen, int copy); /* 635 */ } TclStubs; extern const TclStubs *tclStubsPtr; @@ -3845,8 +3846,8 @@ extern const TclStubs *tclStubsPtr; (tclStubsPtr->tclZipfs_Unmount) /* 633 */ #define TclZipfs_TclLibrary \ (tclStubsPtr->tclZipfs_TclLibrary) /* 634 */ -#define TclZipfs_Mount_Buffer \ - (tclStubsPtr->tclZipfs_Mount_Buffer) /* 635 */ +#define TclZipfs_MountBuffer \ + (tclStubsPtr->tclZipfs_MountBuffer) /* 635 */ #endif /* defined(USE_TCL_STUBS) */ diff --git a/generic/tclStubInit.c b/generic/tclStubInit.c index 5f3fe7b..2e2aa60 100644 --- a/generic/tclStubInit.c +++ b/generic/tclStubInit.c @@ -1574,7 +1574,7 @@ const TclStubs tclStubs = { TclZipfs_Mount, /* 632 */ TclZipfs_Unmount, /* 633 */ TclZipfs_TclLibrary, /* 634 */ - TclZipfs_Mount_Buffer, /* 635 */ + TclZipfs_MountBuffer, /* 635 */ }; /* !END!: Do not edit above this line. */ diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c index 4a0d24c..b609779 100644 --- a/generic/tclZipfs.c +++ b/generic/tclZipfs.c @@ -21,9 +21,9 @@ #ifdef _WIN32 #include -#else +#else /* !_WIN32 */ #include -#endif +#endif /* _WIN32*/ #include #include #include @@ -33,40 +33,50 @@ #ifndef MAP_FILE #define MAP_FILE 0 -#endif +#endif /* !MAP_FILE */ #ifdef HAVE_ZLIB #include "zlib.h" #include "crypt.h" #ifdef CFG_RUNTIME_DLLFILE + /* ** We are compiling as part of the core. ** TIP430 style zipfs prefix */ + #define ZIPFS_VOLUME "//zipfs:/" #define ZIPFS_VOLUME_LEN 9 #define ZIPFS_APP_MOUNT "//zipfs:/app" #define ZIPFS_ZIP_MOUNT "//zipfs:/lib/tcl" -#else + +#else /* !CFG_RUNTIME_DLLFILE */ + /* ** We are compiling from the /compat folder of tclconfig ** Pre TIP430 style zipfs prefix ** //zipfs:/ doesn't work straight out of the box on either windows or Unix ** without other changes made to tip 430 */ + #define ZIPFS_VOLUME "zipfs:/" #define ZIPFS_VOLUME_LEN 7 #define ZIPFS_APP_MOUNT "zipfs:/app" #define ZIPFS_ZIP_MOUNT "zipfs:/lib/tcl" -#endif + +#endif /* CFG_RUNTIME_DLLFILE */ + /* * Various constants and offsets found in ZIP archive files */ #define ZIP_SIG_LEN 4 -/* Local header of ZIP archive member (at very beginning of each member). */ +/* + * Local header of ZIP archive member (at very beginning of each member). + */ + #define ZIP_LOCAL_HEADER_SIG 0x04034b50 #define ZIP_LOCAL_HEADER_LEN 30 #define ZIP_LOCAL_SIG_OFFS 0 @@ -81,7 +91,10 @@ #define ZIP_LOCAL_PATHLEN_OFFS 26 #define ZIP_LOCAL_EXTRALEN_OFFS 28 -/* Central header of ZIP archive member at end of ZIP file. */ +/* + * Central header of ZIP archive member at end of ZIP file. + */ + #define ZIP_CENTRAL_HEADER_SIG 0x02014b50 #define ZIP_CENTRAL_HEADER_LEN 46 #define ZIP_CENTRAL_SIG_OFFS 0 @@ -102,7 +115,10 @@ #define ZIP_CENTRAL_EATTR_OFFS 38 #define ZIP_CENTRAL_LOCALHDR_OFFS 42 -/* Central end signature at very end of ZIP file. */ +/* + * Central end signature at very end of ZIP file. + */ + #define ZIP_CENTRAL_END_SIG 0x06054b50 #define ZIP_CENTRAL_END_LEN 22 #define ZIP_CENTRAL_END_SIG_OFFS 0 @@ -120,16 +136,19 @@ #define ZIP_PASSWORD_END_SIG 0x5a5a4b50 -/* Macros to report errors only if an interp is present */ +/* + * Macros to report errors only if an interp is present. + */ + #define ZIPFS_ERROR(interp,errstr) \ do { \ - if (interp != NULL) { \ + if (interp) { \ Tcl_SetObjResult(interp, Tcl_NewStringObj(errstr, -1)); \ } \ } while (0) #define ZIPFS_POSIX_ERROR(interp,errstr) \ do { \ - if (interp != NULL) { \ + if (interp) { \ Tcl_SetObjResult(interp, Tcl_ObjPrintf( \ "%s: %s", errstr, Tcl_PosixError(interp))); \ } \ @@ -164,7 +183,7 @@ #ifdef _WIN32 static const char drvletters[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; -#endif +#endif /* _WIN32 */ /* * Mutex to protect localtime(3) when no reentrant version available. @@ -172,7 +191,7 @@ static const char drvletters[] = #if !defined(_WIN32) && !defined(HAVE_LOCALTIME_R) && defined(TCL_THREADS) TCL_DECLARE_MUTEX(localtimeMutex) -#endif +#endif /* !_WIN32 && !HAVE_LOCALTIME_R && TCL_THREADS */ /* * In-core description of mounted ZIP archive file. @@ -180,7 +199,7 @@ TCL_DECLARE_MUTEX(localtimeMutex) typedef struct ZipFile { char *name; /* Archive name */ - size_t nameLength; + size_t nameLength; /* Length of archive name */ char isMemBuffer; /* When true, not a file but a memory buffer */ Tcl_Channel chan; /* Channel handle or NULL */ unsigned char *data; /* Memory mapped or malloc'ed file */ @@ -194,11 +213,11 @@ typedef struct ZipFile { size_t numOpen; /* Number of open files on archive */ struct ZipEntry *entries; /* List of files in archive */ struct ZipEntry *topEnts; /* List of top-level dirs in archive */ - char *mountPoint; /* Mount point */ - size_t mountPointLen; + char *mountPoint; /* Mount point name */ + size_t mountPointLen; /* Length of mount point name */ #ifdef _WIN32 - HANDLE mountHandle; -#endif + HANDLE mountHandle; /* Handle used for direct file access. */ +#endif /* _WIN32 */ } ZipFile; /* @@ -207,16 +226,16 @@ typedef struct ZipFile { typedef struct ZipEntry { char *name; /* The full pathname of the virtual file */ - ZipFile *zipfile; /* The ZIP file holding this virtual file */ + ZipFile *zipFilePtr; /* The ZIP file holding this virtual file */ Tcl_WideInt offset; /* Data offset into memory mapped ZIP file */ - int nbyte; /* Uncompressed size of the virtual file */ - int nbytecompr; /* Compressed size of the virtual file */ - int cmeth; /* Compress method */ - int isdir; /* Set to 1 if directory, or -1 if root */ + int numBytes; /* Uncompressed size of the virtual file */ + int numCompressedBytes; /* Compressed size of the virtual file */ + int compressMethod; /* Compress method */ + int isDirectory; /* Set to 1 if directory, or -1 if root */ int depth; /* Number of slashes in path. */ int crc32; /* CRC-32 */ int timestamp; /* Modification time */ - int isenc; /* True if data is encrypted */ + int isEncrypted; /* True if data is encrypted */ unsigned char *data; /* File data if written */ struct ZipEntry *next; /* Next file in the same archive */ struct ZipEntry *tnext; /* Next top-level dir in archive */ @@ -227,17 +246,17 @@ typedef struct ZipEntry { */ typedef struct ZipChannel { - ZipFile *zipfile; /* The ZIP file holding this channel */ - ZipEntry *zipentry; /* Pointer back to virtual file */ - size_t nmax; /* Maximum size for write */ - size_t nbyte; /* Number of bytes of uncompressed data */ - size_t nread; /* Position of next byte to be read from the + ZipFile *zipFilePtr; /* The ZIP file holding this channel */ + ZipEntry *zipEntryPtr; /* Pointer back to virtual file */ + size_t maxWrite; /* Maximum size for write */ + size_t numBytes; /* Number of bytes of uncompressed data */ + size_t numRead; /* Position of next byte to be read from the * channel */ unsigned char *ubuf; /* Pointer to the uncompressed data */ int iscompr; /* True if data is compressed */ - int isdir; /* Set to 1 if directory, or -1 if root */ - int isenc; /* True if data is encrypted */ - int iswr; /* True if open for writing */ + int isDirectory; /* Set to 1 if directory, or -1 if root */ + int isEncrypted; /* True if data is encrypted */ + int isWriting; /* True if open for writing */ unsigned long keys[3]; /* Key for decryption */ } ZipChannel; @@ -334,16 +353,13 @@ static const z_crc_t crc32tab[256] = { 0x2d02ef8d, }; -const char *zipfs_literal_tcl_library = NULL; +static const char *zipfs_literal_tcl_library = NULL; /* Function prototypes */ -int TclZipfs_Mount(Tcl_Interp *interp, - const char *mountPoint, const char *zipname, - const char *passwd); -int TclZipfs_Mount_Buffer(Tcl_Interp *interp, - const char *mountPoint, unsigned char *data, - size_t datalen, int copy); +static inline int DescribeMounted(Tcl_Interp *interp, + const char *mountPoint); +static inline int ListMountPoints(Tcl_Interp *interp); static int ZipfsAppHookFindTclInit(const char *archive); static int ZipFSPathInFilesystemProc(Tcl_Obj *pathPtr, ClientData *clientDataPtr); @@ -366,7 +382,19 @@ static int ZipFSFileAttrsSetProc(Tcl_Interp *interp, int index, static int ZipFSLoadFile(Tcl_Interp *interp, Tcl_Obj *path, Tcl_LoadHandle *loadHandle, Tcl_FSUnloadFileProc **unloadProcPtr, int flags); -static void TclZipfs_C_Init(void); +static void ZipfsSetup(void); +static int ZipChannelClose(ClientData instanceData, + Tcl_Interp *interp); +static int ZipChannelGetFile(ClientData instanceData, + int direction, ClientData *handlePtr); +static int ZipChannelRead(ClientData instanceData, char *buf, + int toRead, int *errloc); +static int ZipChannelSeek(ClientData instanceData, long offset, + int mode, int *errloc); +static void ZipChannelWatchChannel(ClientData instanceData, + int mask); +static int ZipChannelWrite(ClientData instanceData, + const char *buf, int toWrite, int *errloc); /* * Define the ZIP filesystem dispatch table. @@ -409,6 +437,30 @@ const Tcl_Filesystem zipfsFilesystem = { }; /* + * The channel type/driver definition used for ZIP archive members. + */ + +static Tcl_ChannelType ZipChannelType = { + "zip", /* Type name. */ + TCL_CHANNEL_VERSION_5, + ZipChannelClose, /* Close channel, clean instance data */ + ZipChannelRead, /* Handle read request */ + ZipChannelWrite, /* Handle write request */ + ZipChannelSeek, /* Move location of access point, NULL'able */ + NULL, /* Set options, NULL'able */ + NULL, /* Get options, NULL'able */ + ZipChannelWatchChannel, /* Initialize notifier */ + ZipChannelGetFile, /* Get OS handle from the channel */ + NULL, /* 2nd version of close channel, NULL'able */ + NULL, /* Set blocking mode for raw channel, NULL'able */ + NULL, /* Function to flush channel, NULL'able */ + NULL, /* Function to handle event, NULL'able */ + NULL, /* Wide seek function, NULL'able */ + NULL, /* Thread action function, NULL'able */ + NULL, /* Truncate function, NULL'able */ +}; + +/* * Miscellaneous constants. */ @@ -634,8 +686,7 @@ CanonicalPath( int haveZipfsPath = 1; #ifdef _WIN32 - if ((tail[0] != '\0') && (strchr(drvletters, tail[0]) != NULL) - && (tail[1] == ':')) { + if (tail[0] != '\0' && strchr(drvletters, tail[0]) && tail[1] == ':') { tail += 2; haveZipfsPath = 0; } @@ -726,7 +777,7 @@ CanonicalPath( path[i] = '/'; } } -#endif +#endif /* _WIN32 */ if (ZIPFSPATH) { n = ZIPFS_VOLUME_LEN; @@ -780,7 +831,8 @@ CanonicalPath( * ZipFSLookup -- * * This function returns the ZIP entry struct corresponding to the ZIP - * archive member of the given file name. + * archive member of the given file name. Caller must hold the right + * lock. * * Results: * Returns the pointer to ZIP entry struct or NULL if the the given file @@ -800,7 +852,7 @@ ZipFSLookup( ZipEntry *z = NULL; hPtr = Tcl_FindHashEntry(&ZipFS.fileHash, filename); - if (hPtr != NULL) { + if (hPtr) { z = Tcl_GetHashValue(hPtr); } return z; @@ -831,14 +883,13 @@ ZipFSLookupMount( Tcl_HashEntry *hPtr; Tcl_HashSearch search; - hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); - while (hPtr != NULL) { + for (hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); hPtr; + hPtr = Tcl_NextHashEntry(&search)) { ZipFile *zf = Tcl_GetHashValue(hPtr); if (strcmp(zf->mountPoint, filename) == 0) { return 1; } - hPtr = Tcl_NextHashEntry(&search); } return 0; } @@ -871,7 +922,7 @@ ZipFSCloseArchive( } if (zf->isMemBuffer) { /* Pointer to memory */ - if (zf->ptrToFree != NULL) { + if (zf->ptrToFree) { ckfree(zf->ptrToFree); zf->ptrToFree = NULL; } @@ -880,7 +931,7 @@ ZipFSCloseArchive( } #ifdef _WIN32 - if ((zf->data != NULL) && (zf->ptrToFree == NULL)) { + if (zf->data && !zf->ptrToFree) { UnmapViewOfFile(zf->data); zf->data = NULL; } @@ -888,17 +939,17 @@ ZipFSCloseArchive( CloseHandle(zf->mountHandle); } #else /* !_WIN32 */ - if ((zf->data != MAP_FAILED) && (zf->ptrToFree == NULL)) { + if ((zf->data != MAP_FAILED) && !zf->ptrToFree) { munmap(zf->data, zf->length); zf->data = MAP_FAILED; } #endif /* _WIN32 */ - if (zf->ptrToFree != NULL) { + if (zf->ptrToFree) { ckfree(zf->ptrToFree); zf->ptrToFree = NULL; } - if (zf->chan != NULL) { + if (zf->chan) { Tcl_Close(interp, zf->chan); zf->chan = NULL; } @@ -1053,7 +1104,7 @@ ZipFSOpenArchive( zf->ptrToFree = NULL; zf->passBuf[0] = 0; zf->chan = Tcl_OpenFileChannel(interp, zipname, "rb", 0); - if (zf->chan == NULL) { + if (!zf->chan) { return TCL_ERROR; } if (Tcl_GetChannelHandle(zf->chan, TCL_READABLE, &handle) != TCL_OK) { @@ -1072,7 +1123,7 @@ ZipFSOpenArchive( goto error; } zf->ptrToFree = zf->data = attemptckalloc(zf->length); - if (zf->ptrToFree == NULL) { + if (!zf->ptrToFree) { ZIPFS_ERROR(interp, "out of memory"); goto error; } @@ -1105,7 +1156,7 @@ ZipFSOpenArchive( } zf->data = MapViewOfFile(zf->mountHandle, FILE_MAP_READ, 0, 0, zf->length); - if (zf->data == NULL) { + if (!zf->data) { ZIPFS_POSIX_ERROR(interp, "file mapping failed"); goto error; } @@ -1170,9 +1221,9 @@ ZipFSCatalogFilesystem( */ pwlen = 0; - if (passwd != NULL) { + if (passwd) { pwlen = strlen(passwd); - if ((pwlen > 255) || (strchr(passwd, 0xff) != NULL)) { + if ((pwlen > 255) || strchr(passwd, 0xff)) { if (interp) { Tcl_SetObjResult(interp, Tcl_NewStringObj("illegal password", -1)); @@ -1197,7 +1248,7 @@ ZipFSCatalogFilesystem( } hPtr = Tcl_CreateHashEntry(&ZipFS.zipHash, mountPoint, &isNew); if (!isNew) { - if (interp != NULL) { + if (interp) { zf = Tcl_GetHashValue(hPtr); Tcl_SetObjResult(interp, Tcl_ObjPrintf( "%s is already mounted on %s", zf->name, mountPoint)); @@ -1207,8 +1258,8 @@ ZipFSCatalogFilesystem( return TCL_ERROR; } zf = attemptckalloc(sizeof(ZipFile) + strlen(mountPoint) + 1); - if (zf == NULL) { - if (interp != NULL) { + if (!zf) { + if (interp) { Tcl_AppendResult(interp, "out of memory", (char *) NULL); } Unlock(); @@ -1230,13 +1281,10 @@ ZipFSCatalogFilesystem( if ((zf->passBuf[0] == 0) && pwlen) { int k = 0; - i = pwlen; - zf->passBuf[k++] = i; - while (i > 0) { - zf->passBuf[k] = (passwd[i - 1] & 0x0f) - | pwrot[(passwd[i - 1] >> 4) & 0x0f]; - k++; - i--; + zf->passBuf[k++] = pwlen; + for (i = pwlen; i-- > 0 ;) { + zf->passBuf[k++] = (passwd[i] & 0x0f) + | pwrot[(passwd[i] >> 4) & 0x0f]; } zf->passBuf[k] = '\0'; } @@ -1248,14 +1296,14 @@ ZipFSCatalogFilesystem( z->tnext = NULL; z->depth = CountSlashes(mountPoint); - z->zipfile = zf; - z->isdir = (zf->baseOffset == 0) ? 1 : -1; /* root marker */ - z->isenc = 0; + z->zipFilePtr = zf; + z->isDirectory = (zf->baseOffset == 0) ? 1 : -1; /* root marker */ + z->isEncrypted = 0; z->offset = zf->baseOffset; z->crc32 = 0; z->timestamp = 0; - z->nbyte = z->nbytecompr = 0; - z->cmeth = ZIP_COMPMETH_STORED; + z->numBytes = z->numCompressedBytes = 0; + z->compressMethod = ZIP_COMPMETH_STORED; z->data = NULL; z->name = Tcl_GetHashKey(&ZipFS.fileHash, hPtr); z->next = zf->entries; @@ -1319,7 +1367,7 @@ ZipFSCatalogFilesystem( Tcl_DStringAppend(&ds2, "assets/.root/", -1); Tcl_DStringAppend(&ds2, path, -1); hPtr = Tcl_FindHashEntry(&ZipFS.fileHash, Tcl_DStringValue(&ds2)); - if (hPtr != NULL) { + if (hPtr) { /* should not happen but skip it anyway */ Tcl_DStringFree(&ds2); goto nextent; @@ -1342,27 +1390,27 @@ ZipFSCatalogFilesystem( z->name = NULL; z->tnext = NULL; z->depth = CountSlashes(fullpath); - z->zipfile = zf; - z->isdir = isdir; - z->isenc = (ZipReadShort(lq + ZIP_LOCAL_FLAGS_OFFS) & 1) + z->zipFilePtr = zf; + z->isDirectory = isdir; + z->isEncrypted = (ZipReadShort(lq + ZIP_LOCAL_FLAGS_OFFS) & 1) && (nbcompr > 12); z->offset = offs; - if (gq != NULL) { + if (gq) { z->crc32 = ZipReadInt(gq + ZIP_CENTRAL_CRC32_OFFS); dosDate = ZipReadShort(gq + ZIP_CENTRAL_MDATE_OFFS); dosTime = ZipReadShort(gq + ZIP_CENTRAL_MTIME_OFFS); z->timestamp = DosTimeDate(dosDate, dosTime); - z->nbyte = ZipReadInt(gq + ZIP_CENTRAL_UNCOMPLEN_OFFS); - z->cmeth = ZipReadShort(gq + ZIP_CENTRAL_COMPMETH_OFFS); + z->numBytes = ZipReadInt(gq + ZIP_CENTRAL_UNCOMPLEN_OFFS); + z->compressMethod = ZipReadShort(gq + ZIP_CENTRAL_COMPMETH_OFFS); } else { z->crc32 = ZipReadInt(lq + ZIP_LOCAL_CRC32_OFFS); dosDate = ZipReadShort(lq + ZIP_LOCAL_MDATE_OFFS); dosTime = ZipReadShort(lq + ZIP_LOCAL_MTIME_OFFS); z->timestamp = DosTimeDate(dosDate, dosTime); - z->nbyte = ZipReadInt(lq + ZIP_LOCAL_UNCOMPLEN_OFFS); - z->cmeth = ZipReadShort(lq + ZIP_LOCAL_COMPMETH_OFFS); + z->numBytes = ZipReadInt(lq + ZIP_LOCAL_UNCOMPLEN_OFFS); + z->compressMethod = ZipReadShort(lq + ZIP_LOCAL_COMPMETH_OFFS); } - z->nbytecompr = nbcompr; + z->numCompressedBytes = nbcompr; z->data = NULL; hPtr = Tcl_CreateHashEntry(&ZipFS.fileHash, fullpath, &isNew); if (!isNew) { @@ -1377,7 +1425,7 @@ ZipFSCatalogFilesystem( z->tnext = zf->topEnts; zf->topEnts = z; } - if (!z->isdir && (z->depth > 1)) { + if (!z->isDirectory && (z->depth > 1)) { char *dir, *end; ZipEntry *zd; @@ -1385,8 +1433,8 @@ ZipFSCatalogFilesystem( Tcl_DStringSetLength(&ds, 0); Tcl_DStringAppend(&ds, z->name, -1); dir = Tcl_DStringValue(&ds); - end = strrchr(dir, '/'); - while ((end != NULL) && (end != dir)) { + for (end = strrchr(dir, '/'); end && (end != dir); + end = strrchr(dir, '/')) { Tcl_DStringSetLength(&ds, end - dir); hPtr = Tcl_CreateHashEntry(&ZipFS.fileHash, dir, &isNew); if (!isNew) { @@ -1396,14 +1444,14 @@ ZipFSCatalogFilesystem( zd->name = NULL; zd->tnext = NULL; zd->depth = CountSlashes(dir); - zd->zipfile = zf; - zd->isdir = 1; - zd->isenc = 0; + zd->zipFilePtr = zf; + zd->isDirectory = 1; + zd->isEncrypted = 0; zd->offset = z->offset; zd->crc32 = 0; zd->timestamp = z->timestamp; - zd->nbyte = zd->nbytecompr = 0; - zd->cmeth = ZIP_COMPMETH_STORED; + zd->numBytes = zd->numCompressedBytes = 0; + zd->compressMethod = ZIP_COMPMETH_STORED; zd->data = NULL; Tcl_SetHashValue(hPtr, zd); zd->name = Tcl_GetHashKey(&ZipFS.fileHash, hPtr); @@ -1413,7 +1461,6 @@ ZipFSCatalogFilesystem( zd->tnext = zf->topEnts; zf->topEnts = zd; } - end = strrchr(dir, '/'); } } } @@ -1430,7 +1477,7 @@ ZipFSCatalogFilesystem( /* *------------------------------------------------------------------------- * - * TclZipfs_C_Init -- + * ZipfsSetup -- * * Common initialisation code. ZipFS.initialized must *not* be set prior * to the call. @@ -1439,7 +1486,7 @@ ZipFSCatalogFilesystem( */ static void -TclZipfs_C_Init(void) +ZipfsSetup(void) { #ifdef TCL_THREADS static const Tcl_Time t = { 0, 0 }; @@ -1463,6 +1510,83 @@ TclZipfs_C_Init(void) /* *------------------------------------------------------------------------- * + * ListMountPoints -- + * + * This procedure lists the mount points and what's mounted there, or + * reports whether there are any mounts (if there's no interpreter). The + * read lock must be held by the caller. + * + * Results: + * A standard Tcl result. TCL_OK (or TCL_BREAK if no mounts and no + * interpreter). + * + * Side effects: + * Interpreter result may be updated. + * + *------------------------------------------------------------------------- + */ + +static inline int +ListMountPoints( + Tcl_Interp *interp) +{ + Tcl_HashEntry *hPtr; + Tcl_HashSearch search; + ZipFile *zf; + + for (hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); hPtr; + hPtr = Tcl_NextHashEntry(&search)) { + if (!interp) { + return TCL_OK; + } + zf = Tcl_GetHashValue(hPtr); + Tcl_AppendElement(interp, zf->mountPoint); + Tcl_AppendElement(interp, zf->name); + } + return (interp ? TCL_OK : TCL_BREAK); +} + +/* + *------------------------------------------------------------------------- + * + * DescribeMounted -- + * + * This procedure describes what is mounted at the given the mount point. + * The interpreter result is not updated if there is nothing mounted at + * the given point. The read lock must be held by the caller. + * + * Results: + * A standard Tcl result. TCL_OK (or TCL_BREAK if nothing mounted there + * and no interpreter). + * + * Side effects: + * Interpreter result may be updated. + * + *------------------------------------------------------------------------- + */ + +static inline int +DescribeMounted( + Tcl_Interp *interp, + const char *mountPoint) +{ + Tcl_HashEntry *hPtr; + ZipFile *zf; + + if (interp) { + hPtr = Tcl_FindHashEntry(&ZipFS.zipHash, mountPoint); + if (hPtr) { + zf = Tcl_GetHashValue(hPtr); + Tcl_SetObjResult(interp, Tcl_NewStringObj(zf->name, -1)); + return TCL_OK; + } + } + return (interp ? TCL_OK : TCL_BREAK); +} + +/* + *------------------------------------------------------------------------- + * * TclZipfs_Mount -- * * This procedure is invoked to mount a given ZIP archive file on a given @@ -1486,54 +1610,41 @@ TclZipfs_Mount( const char *passwd) /* Password for opening the ZIP, or NULL if * the ZIP is unprotected. */ { - int i, pwlen; ZipFile *zf; ReadLock(); if (!ZipFS.initialized) { - TclZipfs_C_Init(); + ZipfsSetup(); } - if (mountPoint == NULL) { - Tcl_HashEntry *hPtr; - Tcl_HashSearch search; - int ret = TCL_OK; - i = 0; - hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); - while (hPtr != NULL) { - zf = Tcl_GetHashValue(hPtr); - if (interp != NULL) { - Tcl_AppendElement(interp, zf->mountPoint); - Tcl_AppendElement(interp, zf->name); - } - ++i; - hPtr = Tcl_NextHashEntry(&search); - } - if (interp == NULL) { - ret = (i > 0) ? TCL_OK : TCL_BREAK; - } + /* + * No mount point, so list all mount points and what is mounted there. + */ + + if (!mountPoint) { + int ret = ListMountPoints(interp); Unlock(); return ret; } - if (zipname == NULL) { - if (interp != NULL) { - Tcl_HashEntry *hPtr = - Tcl_FindHashEntry(&ZipFS.zipHash, mountPoint); + /* + * Mount point but no file, so describe what is mounted at that mount + * point. + */ - if (hPtr != NULL) { - zf = Tcl_GetHashValue(hPtr); - Tcl_SetObjResult(interp, Tcl_NewStringObj(zf->name, -1)); - } - } + if (!zipname) { + DescribeMounted(interp, mountPoint); Unlock(); return TCL_OK; } Unlock(); - pwlen = 0; - if (passwd != NULL) { - pwlen = strlen(passwd); - if ((pwlen > 255) || (strchr(passwd, 0xff) != NULL)) { + + /* + * Have both a mount point and a file (name) to mount there. + */ + + if (passwd) { + if ((strlen(passwd) > 255) || strchr(passwd, 0xff)) { if (interp) { Tcl_SetObjResult(interp, Tcl_NewStringObj("illegal password", -1)); @@ -1542,8 +1653,8 @@ TclZipfs_Mount( } } zf = attemptckalloc(sizeof(ZipFile) + strlen(mountPoint) + 1); - if (zf == NULL) { - if (interp != NULL) { + if (!zf) { + if (interp) { Tcl_AppendResult(interp, "out of memory", (char *) NULL); } return TCL_ERROR; @@ -1557,10 +1668,10 @@ TclZipfs_Mount( /* *------------------------------------------------------------------------- * - * TclZipfs_Mount_Buffer -- + * TclZipfs_MountBuffer -- * - * This procedure is invoked to mount a given ZIP archive file on - * a given mountpoint with optional ZIP password. + * This procedure is invoked to mount a given ZIP archive file on a given + * mountpoint with optional ZIP password. * * Results: * A standard Tcl result. @@ -1573,7 +1684,7 @@ TclZipfs_Mount( */ int -TclZipfs_Mount_Buffer( +TclZipfs_MountBuffer( Tcl_Interp *interp, /* Current interpreter. NULLable. */ const char *mountPoint, /* Mount point path. */ unsigned char *data, @@ -1584,50 +1695,38 @@ TclZipfs_Mount_Buffer( ReadLock(); if (!ZipFS.initialized) { - TclZipfs_C_Init(); + ZipfsSetup(); } - if (mountPoint == NULL) { - Tcl_HashEntry *hPtr; - Tcl_HashSearch search; - int ret = (interp ? TCL_BREAK : TCL_OK); - hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); - while (hPtr != NULL) { - zf = Tcl_GetHashValue(hPtr); - if (interp != NULL) { - Tcl_AppendElement(interp, zf->mountPoint); - Tcl_AppendElement(interp, zf->name); - } else { - ret = TCL_OK; - /* - * Stop searching here if we're not returning a list. - */ - break; - } - hPtr = Tcl_NextHashEntry(&search); - } + /* + * No mount point, so list all mount points and what is mounted there. + */ + + if (!mountPoint) { + int ret = ListMountPoints(interp); Unlock(); return ret; } - if (data == NULL) { - if (interp != NULL) { - Tcl_HashEntry *hPtr = - Tcl_FindHashEntry(&ZipFS.zipHash, mountPoint); + /* + * Mount point but no data, so describe what is mounted at that mount + * point. + */ - if (hPtr != NULL) { - zf = Tcl_GetHashValue(hPtr); - Tcl_SetObjResult(interp, Tcl_NewStringObj(zf->name, -1)); - } - } + if (!data) { + DescribeMounted(interp, mountPoint); Unlock(); return TCL_OK; } Unlock(); + /* + * Have both a mount point and data to mount there. + */ + zf = attemptckalloc(sizeof(ZipFile) + strlen(mountPoint) + 1); - if (zf == NULL) { - if (interp != NULL) { + if (!zf) { + if (interp) { Tcl_AppendResult(interp, "out of memory", (char *) NULL); } return TCL_ERROR; @@ -1636,8 +1735,8 @@ TclZipfs_Mount_Buffer( zf->length = datalen; if (copy) { zf->data = attemptckalloc(datalen); - if (zf->data == NULL) { - if (interp != NULL) { + if (!zf->data) { + if (interp) { Tcl_AppendResult(interp, "out of memory", (char *) NULL); } return TCL_ERROR; @@ -1697,7 +1796,7 @@ TclZipfs_Unmount( hPtr = Tcl_FindHashEntry(&ZipFS.zipHash, mountPoint); /* don't report no-such-mount as an error */ - if (hPtr == NULL) { + if (!hPtr) { goto done; } @@ -1714,7 +1813,7 @@ TclZipfs_Unmount( if (hPtr) { Tcl_DeleteHashEntry(hPtr); } - if (z->data != NULL) { + if (z->data) { ckfree(z->data); } ckfree(z); @@ -1767,9 +1866,9 @@ ZipFSMountObjCmd( /* *------------------------------------------------------------------------- * - * ZipFSMountObjCmd -- + * ZipFSMountBufferObjCmd -- * - * This procedure is invoked to process the "zipfs::mount" command. + * This procedure is invoked to process the "zipfs::mount_data" command. * * Results: * A standard Tcl result. @@ -1796,40 +1895,24 @@ ZipFSMountBufferObjCmd( return TCL_ERROR; } if (objc < 2) { - Tcl_HashEntry *hPtr; - Tcl_HashSearch search; - int ret = TCL_OK; + int ret; ReadLock(); - hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); - while (hPtr != NULL) { - ZipFile *zf = Tcl_GetHashValue(hPtr); - - Tcl_AppendElement(interp, zf->mountPoint); - Tcl_AppendElement(interp, zf->name); - hPtr = Tcl_NextHashEntry(&search); - } + ret = ListMountPoints(interp); Unlock(); return ret; } mountPoint = Tcl_GetString(objv[1]); if (objc < 3) { - Tcl_HashEntry *hPtr; - ReadLock(); - hPtr = Tcl_FindHashEntry(&ZipFS.zipHash, mountPoint); - if (hPtr != NULL) { - ZipFile *zf = Tcl_GetHashValue(hPtr); - - Tcl_SetObjResult(interp, Tcl_NewStringObj(zf->name, -1)); - } + DescribeMounted(interp, mountPoint); Unlock(); return TCL_OK; } data = Tcl_GetByteArrayFromObj(objv[2], &length); - return TclZipfs_Mount_Buffer(interp, mountPoint, data, length, 1); + return TclZipfs_MountBuffer(interp, mountPoint, data, length, 1); } /* @@ -1925,7 +2008,7 @@ ZipFSMkKeyObjCmd( if (len == 0) { return TCL_OK; } - if ((len > 255) || (strchr(pw, 0xff) != NULL)) { + if ((len > 255) || strchr(pw, 0xff)) { Tcl_SetObjResult(interp, Tcl_NewStringObj("illegal password", -1)); return TCL_ERROR; } @@ -1987,17 +2070,23 @@ ZipAddFile( int crc, flush, zpathlen; size_t nbyte, nbytecompr, len, olen, align = 0; Tcl_WideInt pos[3]; - int mtime = 0, isNew, cmeth; + int mtime = 0, isNew, compMeth; unsigned long keys[3], keys0[3]; char obuf[4096]; + /* + * Trim leading '/' characters. If this results in an empty string, we've + * nothing to do. + */ + zpath = name; - while (zpath != NULL && zpath[0] == '/') { + while (zpath && zpath[0] == '/') { zpath++; } - if ((zpath == NULL) || (zpath[0] == '\0')) { + if (!zpath || (zpath[0] == '\0')) { return TCL_OK; } + zpathlen = strlen(zpath); if (zpathlen + ZIP_CENTRAL_HEADER_LEN > bufsize) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( @@ -2005,7 +2094,7 @@ ZipAddFile( return TCL_ERROR; } in = Tcl_OpenFileChannel(interp, path, "rb", 0); - if (in == NULL) { + if (!in) { #ifdef _WIN32 /* hopefully a directory */ if (strcmp("permission denied", Tcl_PosixError(interp)) == 0) { @@ -2028,19 +2117,23 @@ ZipAddFile( Tcl_ResetResult(interp); crc = 0; nbyte = nbytecompr = 0; - while ((len = Tcl_Read(in, buf, bufsize)) + 1 > 1) { - crc = crc32(crc, (unsigned char *) buf, len); - nbyte += len; - } - if (len == ERROR_LENGTH) { - if (nbyte == 0 && errno == EISDIR) { + while (1) { + len = Tcl_Read(in, buf, bufsize); + if (len == ERROR_LENGTH) { + if (nbyte == 0 && errno == EISDIR) { + Tcl_Close(interp, in); + return TCL_OK; + } + Tcl_SetObjResult(interp, Tcl_ObjPrintf("read error on \"%s\": %s", + path, Tcl_PosixError(interp))); Tcl_Close(interp, in); - return TCL_OK; + return TCL_ERROR; } - Tcl_SetObjResult(interp, Tcl_ObjPrintf("read error on \"%s\": %s", - path, Tcl_PosixError(interp))); - Tcl_Close(interp, in); - return TCL_ERROR; + if (len == 0) { + break; + } + crc = crc32(crc, (unsigned char *) buf, len); + nbyte += len; } if (Tcl_Seek(in, 0, SEEK_SET) == -1) { Tcl_SetObjResult(interp, Tcl_ObjPrintf("seek error on \"%s\": %s", @@ -2075,7 +2168,7 @@ ZipAddFile( goto wrerr; } } - if (passwd != NULL) { + if (passwd) { int i, ch, tmp; unsigned char kvbuf[24]; Tcl_Obj *ret; @@ -2119,7 +2212,7 @@ ZipAddFile( } Tcl_Flush(out); pos[2] = Tcl_Tell(out); - cmeth = ZIP_COMPMETH_DEFLATED; + compMeth = ZIP_COMPMETH_DEFLATED; memset(&stream, 0, sizeof(z_stream)); stream.zalloc = Z_NULL; stream.zfree = Z_NULL; @@ -2155,7 +2248,7 @@ ZipAddFile( return TCL_ERROR; } olen = sizeof(obuf) - stream.avail_out; - if (passwd != NULL) { + if (passwd) { size_t i; int tmp; @@ -2190,7 +2283,7 @@ ZipAddFile( "seek error: %s", Tcl_PosixError(interp))); return TCL_ERROR; } - nbytecompr = (passwd != NULL) ? 12 : 0; + nbytecompr = (passwd ? 12 : 0); while (1) { len = Tcl_Read(in, buf, bufsize); if (len == ERROR_LENGTH) { @@ -2202,7 +2295,7 @@ ZipAddFile( } else if (len == 0) { break; } - if (passwd != NULL) { + if (passwd) { size_t i; int tmp; @@ -2218,7 +2311,7 @@ ZipAddFile( } nbytecompr += len; } - cmeth = ZIP_COMPMETH_STORED; + compMeth = ZIP_COMPMETH_STORED; Tcl_Flush(out); pos[1] = Tcl_Tell(out); Tcl_TruncateChannel(out, pos[1]); @@ -2229,15 +2322,15 @@ ZipAddFile( z->name = NULL; z->tnext = NULL; z->depth = 0; - z->zipfile = NULL; - z->isdir = 0; - z->isenc = (passwd != NULL) ? 1 : 0; + z->zipFilePtr = NULL; + z->isDirectory = 0; + z->isEncrypted = (passwd ? 1 : 0); z->offset = pos[0]; z->crc32 = crc; z->timestamp = mtime; - z->nbyte = nbyte; - z->nbytecompr = nbytecompr; - z->cmeth = cmeth; + z->numBytes = nbyte; + z->numCompressedBytes = nbytecompr; + z->compressMethod = compMeth; z->data = NULL; hPtr = Tcl_CreateHashEntry(fileHash, zpath, &isNew); if (!isNew) { @@ -2256,13 +2349,13 @@ ZipAddFile( */ ZipWriteInt(buf + ZIP_LOCAL_SIG_OFFS, ZIP_LOCAL_HEADER_SIG); ZipWriteShort(buf + ZIP_LOCAL_VERSION_OFFS, ZIP_MIN_VERSION); - ZipWriteShort(buf + ZIP_LOCAL_FLAGS_OFFS, z->isenc); - ZipWriteShort(buf + ZIP_LOCAL_COMPMETH_OFFS, z->cmeth); + ZipWriteShort(buf + ZIP_LOCAL_FLAGS_OFFS, z->isEncrypted); + ZipWriteShort(buf + ZIP_LOCAL_COMPMETH_OFFS, z->compressMethod); ZipWriteShort(buf + ZIP_LOCAL_MTIME_OFFS, ToDosTime(z->timestamp)); ZipWriteShort(buf + ZIP_LOCAL_MDATE_OFFS, ToDosDate(z->timestamp)); ZipWriteInt(buf + ZIP_LOCAL_CRC32_OFFS, z->crc32); - ZipWriteInt(buf + ZIP_LOCAL_COMPLEN_OFFS, z->nbytecompr); - ZipWriteInt(buf + ZIP_LOCAL_UNCOMPLEN_OFFS, z->nbyte); + ZipWriteInt(buf + ZIP_LOCAL_COMPLEN_OFFS, z->numCompressedBytes); + ZipWriteInt(buf + ZIP_LOCAL_UNCOMPLEN_OFFS, z->numBytes); ZipWriteShort(buf + ZIP_LOCAL_PATHLEN_OFFS, zpathlen); ZipWriteShort(buf + ZIP_LOCAL_EXTRALEN_OFFS, align); if (Tcl_Seek(out, pos[0], SEEK_SET) != pos[0]) { @@ -2337,7 +2430,7 @@ ZipFSMkZipOrImgObjCmd( if (objc > (isList ? 3 : 4)) { pw = Tcl_GetString(objv[isList ? 3 : 4]); pwlen = strlen(pw); - if ((pwlen > 255) || (strchr(pw, 0xff) != NULL)) { + if ((pwlen > 255) || strchr(pw, 0xff)) { Tcl_SetObjResult(interp, Tcl_NewStringObj("illegal password", -1)); return TCL_ERROR; @@ -2399,13 +2492,11 @@ ZipFSMkZipOrImgObjCmd( } if (pwlen) { i = 0; - len = pwlen; - while (len > 0) { - int ch = pw[len - 1]; + for (len = pwlen; len-- > 0;) { + int ch = pw[len]; passBuf[i] = (ch & 0x0f) | pwrot[(ch >> 4) & 0x0f]; i++; - len--; } passBuf[i] = i; ++i; @@ -2415,17 +2506,20 @@ ZipFSMkZipOrImgObjCmd( passBuf[i++] = (char) (ZIP_PASSWORD_END_SIG >> 24); passBuf[i] = '\0'; } - /* Check for mounted image */ + + /* + * Check for mounted image. + */ + WriteLock(); - hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); - while (hPtr != NULL) { + for (hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); hPtr; + hPtr = Tcl_NextHashEntry(&search)) { zf = Tcl_GetHashValue(hPtr); if (strcmp(zf->name, imgName) == 0) { isMounted = 1; zf->numOpen++; break; } - hPtr = Tcl_NextHashEntry(&search); } Unlock(); if (!isMounted) { @@ -2468,7 +2562,7 @@ ZipFSMkZipOrImgObjCmd( Tcl_ResetResult(interp); in = Tcl_OpenFileChannel(interp, imgName, "rb", 0644); - if (in == NULL) { + if (!in) { memset(passBuf, 0, sizeof(passBuf)); Tcl_DecrRefCount(list); Tcl_Close(interp, out); @@ -2486,8 +2580,7 @@ ZipFSMkZipOrImgObjCmd( return TCL_ERROR; } Tcl_Seek(in, 0, SEEK_SET); - k = 0; - while (k < i) { + for (k = 0; k < i; k += m) { m = i - k; if (m > (int) sizeof(buf)) { m = (int) sizeof(buf); @@ -2504,7 +2597,6 @@ ZipFSMkZipOrImgObjCmd( errMsg = "write error"; goto cperr; } - k += m; } Tcl_Close(interp, in); } @@ -2580,7 +2672,7 @@ ZipFSMkZipOrImgObjCmd( continue; } hPtr = Tcl_FindHashEntry(&fileHash, name); - if (hPtr == NULL) { + if (!hPtr) { continue; } z = Tcl_GetHashValue(hPtr); @@ -2588,13 +2680,13 @@ ZipFSMkZipOrImgObjCmd( ZipWriteInt(buf + ZIP_CENTRAL_SIG_OFFS, ZIP_CENTRAL_HEADER_SIG); ZipWriteShort(buf + ZIP_CENTRAL_VERSIONMADE_OFFS, ZIP_MIN_VERSION); ZipWriteShort(buf + ZIP_CENTRAL_VERSION_OFFS, ZIP_MIN_VERSION); - ZipWriteShort(buf + ZIP_CENTRAL_FLAGS_OFFS, z->isenc ? 1 : 0); - ZipWriteShort(buf + ZIP_CENTRAL_COMPMETH_OFFS, z->cmeth); + ZipWriteShort(buf + ZIP_CENTRAL_FLAGS_OFFS, z->isEncrypted); + ZipWriteShort(buf + ZIP_CENTRAL_COMPMETH_OFFS, z->compressMethod); ZipWriteShort(buf + ZIP_CENTRAL_MTIME_OFFS, ToDosTime(z->timestamp)); ZipWriteShort(buf + ZIP_CENTRAL_MDATE_OFFS, ToDosDate(z->timestamp)); ZipWriteInt(buf + ZIP_CENTRAL_CRC32_OFFS, z->crc32); - ZipWriteInt(buf + ZIP_CENTRAL_COMPLEN_OFFS, z->nbytecompr); - ZipWriteInt(buf + ZIP_CENTRAL_UNCOMPLEN_OFFS, z->nbyte); + ZipWriteInt(buf + ZIP_CENTRAL_COMPLEN_OFFS, z->numCompressedBytes); + ZipWriteInt(buf + ZIP_CENTRAL_UNCOMPLEN_OFFS, z->numBytes); ZipWriteShort(buf + ZIP_CENTRAL_PATHLEN_OFFS, len); ZipWriteShort(buf + ZIP_CENTRAL_EXTRALEN_OFFS, 0); ZipWriteShort(buf + ZIP_CENTRAL_FCOMMENTLEN_OFFS, 0); @@ -2636,12 +2728,11 @@ ZipFSMkZipOrImgObjCmd( Tcl_Close(interp, out); } Tcl_DecrRefCount(list); - hPtr = Tcl_FirstHashEntry(&fileHash, &search); - while (hPtr != NULL) { + for (hPtr = Tcl_FirstHashEntry(&fileHash, &search); hPtr; + hPtr = Tcl_NextHashEntry(&search)) { z = Tcl_GetHashValue(hPtr); ckfree(z); Tcl_DeleteHashEntry(hPtr); - hPtr = Tcl_NextHashEntry(&search); } Tcl_DeleteHashTable(&fileHash); return ret; @@ -2901,14 +2992,15 @@ ZipFSInfoObjCmd( filename = Tcl_GetStringFromObj(objv[1], 0); ReadLock(); z = ZipFSLookup(filename); - if (z != NULL) { + if (z) { Tcl_Obj *result = Tcl_GetObjResult(interp); Tcl_ListObjAppendElement(interp, result, - Tcl_NewStringObj(z->zipfile->name, -1)); - Tcl_ListObjAppendElement(interp, result, Tcl_NewWideIntObj(z->nbyte)); + Tcl_NewStringObj(z->zipFilePtr->name, -1)); Tcl_ListObjAppendElement(interp, result, - Tcl_NewWideIntObj(z->nbytecompr)); + Tcl_NewWideIntObj(z->numBytes)); + Tcl_ListObjAppendElement(interp, result, + Tcl_NewWideIntObj(z->numCompressedBytes)); Tcl_ListObjAppendElement(interp, result, Tcl_NewWideIntObj(z->offset)); } Unlock(); @@ -2958,7 +3050,7 @@ ZipFSListObjCmd( pattern = Tcl_GetString(objv[2]); } else if ((n >= 2) && (strncmp(what, "-regexp", n) == 0)) { regexp = Tcl_RegExpCompile(interp, Tcl_GetString(objv[2])); - if (regexp == NULL) { + if (!regexp) { return TCL_ERROR; } } else { @@ -2970,7 +3062,7 @@ ZipFSListObjCmd( pattern = Tcl_GetStringFromObj(objv[1], 0); } ReadLock(); - if (pattern != NULL) { + if (pattern) { for (hPtr = Tcl_FirstHashEntry(&ZipFS.fileHash, &search); hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) { ZipEntry *z = Tcl_GetHashValue(hPtr); @@ -2980,9 +3072,9 @@ ZipFSListObjCmd( Tcl_NewStringObj(z->name, -1)); } } - } else if (regexp != NULL) { + } else if (regexp) { for (hPtr = Tcl_FirstHashEntry(&ZipFS.fileHash, &search); - hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) { + hPtr; hPtr = Tcl_NextHashEntry(&search)) { ZipEntry *z = Tcl_GetHashValue(hPtr); if (Tcl_RegExpExec(interp, regexp, z->name, z->name)) { @@ -2992,7 +3084,7 @@ ZipFSListObjCmd( } } else { for (hPtr = Tcl_FirstHashEntry(&ZipFS.fileHash, &search); - hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) { + hPtr; hPtr = Tcl_NextHashEntry(&search)) { ZipEntry *z = Tcl_GetHashValue(hPtr); Tcl_ListObjAppendElement(interp, result, @@ -3099,8 +3191,8 @@ TclZipfs_TclLibrary(void) * * ZipFSTclLibraryObjCmd -- * - * This procedure is invoked to process the "zipfs::root" command. It - * returns the root that all zipfs file systems are mounted under. + * This procedure is invoked to process the "zipfs::tcl_library" command. + * It returns the root that all zipfs file systems are mounted under. * * Results: * A standard Tcl result. @@ -3149,28 +3241,28 @@ ZipChannelClose( { ZipChannel *info = instanceData; - if (info->iscompr && (info->ubuf != NULL)) { + if (info->iscompr && info->ubuf) { ckfree(info->ubuf); info->ubuf = NULL; } - if (info->isenc) { - info->isenc = 0; + if (info->isEncrypted) { + info->isEncrypted = 0; memset(info->keys, 0, sizeof(info->keys)); } - if (info->iswr) { - ZipEntry *z = info->zipentry; - unsigned char *newdata = attemptckrealloc(info->ubuf, info->nread); + if (info->isWriting) { + ZipEntry *z = info->zipEntryPtr; + unsigned char *newdata = attemptckrealloc(info->ubuf, info->numRead); - if (newdata != NULL) { - if (z->data != NULL) { + if (newdata) { + if (z->data) { ckfree(z->data); } z->data = newdata; - z->nbyte = z->nbytecompr = info->nbyte; - z->cmeth = ZIP_COMPMETH_STORED; + z->numBytes = z->numCompressedBytes = info->numBytes; + z->compressMethod = ZIP_COMPMETH_STORED; z->timestamp = time(NULL); - z->isdir = 0; - z->isenc = 0; + z->isDirectory = 0; + z->isEncrypted = 0; z->offset = 0; z->crc32 = 0; } else { @@ -3178,7 +3270,7 @@ ZipChannelClose( } } WriteLock(); - info->zipfile->numOpen--; + info->zipFilePtr->numOpen--; Unlock(); ckfree(info); return TCL_OK; @@ -3210,49 +3302,49 @@ ZipChannelRead( ZipChannel *info = (ZipChannel *) instanceData; unsigned long nextpos; - if (info->isdir < 0) { + if (info->isDirectory < 0) { /* * Special case: when executable combined with ZIP archive file read * data in front of ZIP, i.e. the executable itself. */ - nextpos = info->nread + toRead; - if (nextpos > info->zipfile->baseOffset) { - toRead = info->zipfile->baseOffset - info->nread; - nextpos = info->zipfile->baseOffset; + nextpos = info->numRead + toRead; + if (nextpos > info->zipFilePtr->baseOffset) { + toRead = info->zipFilePtr->baseOffset - info->numRead; + nextpos = info->zipFilePtr->baseOffset; } if (toRead == 0) { return 0; } - memcpy(buf, info->zipfile->data, toRead); - info->nread = nextpos; + memcpy(buf, info->zipFilePtr->data, toRead); + info->numRead = nextpos; *errloc = 0; return toRead; } - if (info->isdir) { + if (info->isDirectory) { *errloc = EISDIR; return -1; } - nextpos = info->nread + toRead; - if (nextpos > info->nbyte) { - toRead = info->nbyte - info->nread; - nextpos = info->nbyte; + nextpos = info->numRead + toRead; + if (nextpos > info->numBytes) { + toRead = info->numBytes - info->numRead; + nextpos = info->numBytes; } if (toRead == 0) { return 0; } - if (info->isenc) { + if (info->isEncrypted) { int i; for (i = 0; i < toRead; i++) { - int ch = info->ubuf[i + info->nread]; + int ch = info->ubuf[i + info->numRead]; buf[i] = zdecode(info->keys, crc32tab, ch); } } else { - memcpy(buf, info->ubuf + info->nread, toRead); + memcpy(buf, info->ubuf + info->numRead, toRead); } - info->nread = nextpos; + info->numRead = nextpos; *errloc = 0; return toRead; } @@ -3283,22 +3375,22 @@ ZipChannelWrite( ZipChannel *info = (ZipChannel *) instanceData; unsigned long nextpos; - if (!info->iswr) { + if (!info->isWriting) { *errloc = EINVAL; return -1; } - nextpos = info->nread + toWrite; - if (nextpos > info->nmax) { - toWrite = info->nmax - info->nread; - nextpos = info->nmax; + nextpos = info->numRead + toWrite; + if (nextpos > info->maxWrite) { + toWrite = info->maxWrite - info->numRead; + nextpos = info->maxWrite; } if (toWrite == 0) { return 0; } - memcpy(info->ubuf + info->nread, buf, toWrite); - info->nread = nextpos; - if (info->nread > info->nbyte) { - info->nbyte = info->nread; + memcpy(info->ubuf + info->numRead, buf, toWrite); + info->numRead = nextpos; + if (info->numRead > info->numBytes) { + info->numBytes = info->numRead; } *errloc = 0; return toWrite; @@ -3330,21 +3422,21 @@ ZipChannelSeek( ZipChannel *info = (ZipChannel *) instanceData; unsigned long end; - if (!info->iswr && (info->isdir < 0)) { + if (!info->isWriting && (info->isDirectory < 0)) { /* * Special case: when executable combined with ZIP archive file, seek * within front of ZIP, i.e. the executable itself. */ - end = info->zipfile->baseOffset; - } else if (info->isdir) { + end = info->zipFilePtr->baseOffset; + } else if (info->isDirectory) { *errloc = EINVAL; return -1; } else { - end = info->nbyte; + end = info->numBytes; } switch (mode) { case SEEK_CUR: - offset += info->nread; + offset += info->numRead; break; case SEEK_END: offset += end; @@ -3359,20 +3451,20 @@ ZipChannelSeek( *errloc = EINVAL; return -1; } - if (info->iswr) { - if ((unsigned long) offset > info->nmax) { + if (info->isWriting) { + if ((unsigned long) offset > info->maxWrite) { *errloc = EINVAL; return -1; } - if ((unsigned long) offset > info->nbyte) { - info->nbyte = offset; + if ((unsigned long) offset > info->numBytes) { + info->numBytes = offset; } } else if ((unsigned long) offset > end) { *errloc = EINVAL; return -1; } - info->nread = (unsigned long) offset; - return info->nread; + info->numRead = (unsigned long) offset; + return info->numRead; } /* @@ -3427,30 +3519,6 @@ ZipChannelGetFile( } /* - * The channel type/driver definition used for ZIP archive members. - */ - -static Tcl_ChannelType ZipChannelType = { - "zip", /* Type name. */ - TCL_CHANNEL_VERSION_5, - ZipChannelClose, /* Close channel, clean instance data */ - ZipChannelRead, /* Handle read request */ - ZipChannelWrite, /* Handle write request */ - ZipChannelSeek, /* Move location of access point, NULL'able */ - NULL, /* Set options, NULL'able */ - NULL, /* Get options, NULL'able */ - ZipChannelWatchChannel, /* Initialize notifier */ - ZipChannelGetFile, /* Get OS handle from the channel */ - NULL, /* 2nd version of close channel, NULL'able */ - NULL, /* Set blocking mode for raw channel, NULL'able */ - NULL, /* Function to flush channel, NULL'able */ - NULL, /* Function to handle event, NULL'able */ - NULL, /* Wide seek function, NULL'able */ - NULL, /* Thread action function, NULL'able */ - NULL, /* Truncate function, NULL'able */ -}; - -/* *------------------------------------------------------------------------- * * ZipChannelOpen -- @@ -3481,7 +3549,7 @@ ZipChannelOpen( if ((mode & O_APPEND) || ((ZipFS.wrmax <= 0) && (mode & (O_WRONLY | O_RDWR)))) { - if (interp != NULL) { + if (interp) { Tcl_SetObjResult(interp, Tcl_NewStringObj("unsupported open mode", -1)); } @@ -3489,8 +3557,8 @@ ZipChannelOpen( } WriteLock(); z = ZipFSLookup(filename); - if (z == NULL) { - if (interp != NULL) { + if (!z) { + if (interp) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "file not found \"%s\"", filename)); } @@ -3498,21 +3566,21 @@ ZipChannelOpen( } trunc = (mode & O_TRUNC) != 0; wr = (mode & (O_WRONLY | O_RDWR)) != 0; - if ((z->cmeth != ZIP_COMPMETH_STORED) - && (z->cmeth != ZIP_COMPMETH_DEFLATED)) { + if ((z->compressMethod != ZIP_COMPMETH_STORED) + && (z->compressMethod != ZIP_COMPMETH_DEFLATED)) { ZIPFS_ERROR(interp, "unsupported compression method"); goto error; } - if (wr && z->isdir) { + if (wr && z->isDirectory) { ZIPFS_ERROR(interp, "unsupported file type"); goto error; } if (!trunc) { flags |= TCL_READABLE; - if (z->isenc && (z->zipfile->passBuf[0] == 0)) { + if (z->isEncrypted && (z->zipFilePtr->passBuf[0] == 0)) { ZIPFS_ERROR(interp, "decryption failed"); goto error; - } else if (wr && (z->data == NULL) && (z->nbyte > ZipFS.wrmax)) { + } else if (wr && !z->data && (z->numBytes > ZipFS.wrmax)) { ZIPFS_ERROR(interp, "file too large"); goto error; } @@ -3520,50 +3588,50 @@ ZipChannelOpen( flags = TCL_WRITABLE; } info = attemptckalloc(sizeof(ZipChannel)); - if (info == NULL) { + if (!info) { ZIPFS_ERROR(interp, "out of memory"); goto error; } - info->zipfile = z->zipfile; - info->zipentry = z; - info->nread = 0; + info->zipFilePtr = z->zipFilePtr; + info->zipEntryPtr = z; + info->numRead = 0; if (wr) { flags |= TCL_WRITABLE; - info->iswr = 1; - info->isdir = 0; - info->nmax = ZipFS.wrmax; + info->isWriting = 1; + info->isDirectory = 0; + info->maxWrite = ZipFS.wrmax; info->iscompr = 0; - info->isenc = 0; - info->ubuf = attemptckalloc(info->nmax); - if (info->ubuf == NULL) { + info->isEncrypted = 0; + info->ubuf = attemptckalloc(info->maxWrite); + if (!info->ubuf) { merror0: - if (info->ubuf != NULL) { + if (info->ubuf) { ckfree(info->ubuf); } ckfree(info); ZIPFS_ERROR(interp, "out of memory"); goto error; } - memset(info->ubuf, 0, info->nmax); + memset(info->ubuf, 0, info->maxWrite); if (trunc) { - info->nbyte = 0; - } else if (z->data != NULL) { - unsigned int j = z->nbyte; + info->numBytes = 0; + } else if (z->data) { + unsigned int j = z->numBytes; - if (j > info->nmax) { - j = info->nmax; + if (j > info->maxWrite) { + j = info->maxWrite; } memcpy(info->ubuf, z->data, j); - info->nbyte = j; + info->numBytes = j; } else { - unsigned char *zbuf = z->zipfile->data + z->offset; + unsigned char *zbuf = z->zipFilePtr->data + z->offset; - if (z->isenc) { - int len = z->zipfile->passBuf[0]; + if (z->isEncrypted) { + int len = z->zipFilePtr->passBuf[0]; char passBuf[260]; for (i = 0; i < len; i++) { - ch = z->zipfile->passBuf[len - i]; + ch = z->zipFilePtr->passBuf[len - i]; passBuf[i] = (ch & 0x0f) | pwrot[(ch >> 4) & 0x0f]; } passBuf[i] = '\0'; @@ -3575,7 +3643,7 @@ ZipChannelOpen( } zbuf += i; } - if (z->cmeth == ZIP_COMPMETH_DEFLATED) { + if (z->compressMethod == ZIP_COMPMETH_DEFLATED) { z_stream stream; int err; unsigned char *cbuf = NULL; @@ -3584,13 +3652,13 @@ ZipChannelOpen( stream.zalloc = Z_NULL; stream.zfree = Z_NULL; stream.opaque = Z_NULL; - stream.avail_in = z->nbytecompr; - if (z->isenc) { + stream.avail_in = z->numCompressedBytes; + if (z->isEncrypted) { unsigned int j; stream.avail_in -= 12; cbuf = attemptckalloc(stream.avail_in); - if (cbuf == NULL) { + if (!cbuf) { goto merror0; } for (j = 0; j < stream.avail_in; j++) { @@ -3602,7 +3670,7 @@ ZipChannelOpen( stream.next_in = zbuf; } stream.next_out = info->ubuf; - stream.avail_out = info->nmax; + stream.avail_out = info->maxWrite; if (inflateInit2(&stream, -15) != Z_OK) { goto cerror0; } @@ -3610,58 +3678,58 @@ ZipChannelOpen( inflateEnd(&stream); if ((err == Z_STREAM_END) || ((err == Z_OK) && (stream.avail_in == 0))) { - if (cbuf != NULL) { + if (cbuf) { memset(info->keys, 0, sizeof(info->keys)); ckfree(cbuf); } goto wrapchan; } cerror0: - if (cbuf != NULL) { + if (cbuf) { memset(info->keys, 0, sizeof(info->keys)); ckfree(cbuf); } - if (info->ubuf != NULL) { + if (info->ubuf) { ckfree(info->ubuf); } ckfree(info); ZIPFS_ERROR(interp, "decompression error"); goto error; - } else if (z->isenc) { - for (i = 0; i < z->nbyte - 12; i++) { + } else if (z->isEncrypted) { + for (i = 0; i < z->numBytes - 12; i++) { ch = zbuf[i]; info->ubuf[i] = zdecode(info->keys, crc32tab, ch); } } else { - memcpy(info->ubuf, zbuf, z->nbyte); + memcpy(info->ubuf, zbuf, z->numBytes); } memset(info->keys, 0, sizeof(info->keys)); goto wrapchan; } - } else if (z->data != NULL) { + } else if (z->data) { flags |= TCL_READABLE; - info->iswr = 0; + info->isWriting = 0; info->iscompr = 0; - info->isdir = 0; - info->isenc = 0; - info->nbyte = z->nbyte; - info->nmax = 0; + info->isDirectory = 0; + info->isEncrypted = 0; + info->numBytes = z->numBytes; + info->maxWrite = 0; info->ubuf = z->data; } else { flags |= TCL_READABLE; - info->iswr = 0; - info->iscompr = z->cmeth == ZIP_COMPMETH_DEFLATED; - info->ubuf = z->zipfile->data + z->offset; - info->isdir = z->isdir; - info->isenc = z->isenc; - info->nbyte = z->nbyte; - info->nmax = 0; - if (info->isenc) { - int len = z->zipfile->passBuf[0]; + info->isWriting = 0; + info->iscompr = (z->compressMethod == ZIP_COMPMETH_DEFLATED); + info->ubuf = z->zipFilePtr->data + z->offset; + info->isDirectory = z->isDirectory; + info->isEncrypted = z->isEncrypted; + info->numBytes = z->numBytes; + info->maxWrite = 0; + if (info->isEncrypted) { + int len = z->zipFilePtr->passBuf[0]; char passBuf[260]; for (i = 0; i < len; i++) { - ch = z->zipfile->passBuf[len - i]; + ch = z->zipFilePtr->passBuf[len - i]; passBuf[i] = (ch & 0x0f) | pwrot[(ch >> 4) & 0x0f]; } passBuf[i] = '\0'; @@ -3683,11 +3751,11 @@ ZipChannelOpen( stream.zalloc = Z_NULL; stream.zfree = Z_NULL; stream.opaque = Z_NULL; - stream.avail_in = z->nbytecompr; - if (info->isenc) { + stream.avail_in = z->numCompressedBytes; + if (info->isEncrypted) { stream.avail_in -= 12; ubuf = attemptckalloc(stream.avail_in); - if (ubuf == NULL) { + if (!ubuf) { info->ubuf = NULL; goto merror; } @@ -3699,22 +3767,22 @@ ZipChannelOpen( } else { stream.next_in = info->ubuf; } - stream.next_out = info->ubuf = attemptckalloc(info->nbyte); - if (info->ubuf == NULL) { + stream.next_out = info->ubuf = attemptckalloc(info->numBytes); + if (!info->ubuf) { merror: - if (ubuf != NULL) { - info->isenc = 0; + if (ubuf) { + info->isEncrypted = 0; memset(info->keys, 0, sizeof(info->keys)); ckfree(ubuf); } ckfree(info); - if (interp != NULL) { + if (interp) { Tcl_SetObjResult(interp, Tcl_NewStringObj("out of memory", -1)); } goto error; } - stream.avail_out = info->nbyte; + stream.avail_out = info->numBytes; if (inflateInit2(&stream, -15) != Z_OK) { goto cerror; } @@ -3722,20 +3790,20 @@ ZipChannelOpen( inflateEnd(&stream); if ((err == Z_STREAM_END) || ((err == Z_OK) && (stream.avail_in == 0))) { - if (ubuf != NULL) { - info->isenc = 0; + if (ubuf) { + info->isEncrypted = 0; memset(info->keys, 0, sizeof(info->keys)); ckfree(ubuf); } goto wrapchan; } cerror: - if (ubuf != NULL) { - info->isenc = 0; + if (ubuf) { + info->isEncrypted = 0; memset(info->keys, 0, sizeof(info->keys)); ckfree(ubuf); } - if (info->ubuf != NULL) { + if (info->ubuf) { ckfree(info->ubuf); } ckfree(info); @@ -3747,9 +3815,9 @@ ZipChannelOpen( wrapchan: sprintf(cname, "zipfs_%" TCL_LL_MODIFIER "x_%d", z->offset, ZipFS.idCount++); - z->zipfile->numOpen++; + z->zipFilePtr->numOpen++; Unlock(); - return Tcl_CreateChannel(&ZipChannelType, cname, (ClientData) info, flags); + return Tcl_CreateChannel(&ZipChannelType, cname, info, flags); error: Unlock(); @@ -3783,14 +3851,14 @@ ZipEntryStat( ReadLock(); z = ZipFSLookup(path); - if (z != NULL) { + if (z) { memset(buf, 0, sizeof(Tcl_StatBuf)); - if (z->isdir) { + if (z->isDirectory) { buf->st_mode = S_IFDIR | 0555; } else { buf->st_mode = S_IFREG | 0555; } - buf->st_size = z->nbyte; + buf->st_size = z->numBytes; buf->st_mtime = z->timestamp; buf->st_ctime = z->timestamp; buf->st_atime = z->timestamp; @@ -3830,7 +3898,7 @@ ZipEntryAccess( ReadLock(); z = ZipFSLookup(path); Unlock(); - return (z != NULL) ? 0 : -1; + return (z ? 0 : -1); } /* @@ -3988,7 +4056,7 @@ ZipFSMatchInDirectoryProc( if (!normPathPtr) { return -1; } - if (types != NULL) { + if (types) { dirOnly = (types->type & TCL_GLOB_TYPE_DIR) == TCL_GLOB_TYPE_DIR; } @@ -4013,30 +4081,30 @@ ZipFSMatchInDirectoryProc( } else { strip = len + 1; } - if (prefix != NULL) { + if (prefix) { Tcl_DStringAppend(&dsPref, "/", 1); prefixLen++; prefix = Tcl_DStringValue(&dsPref); } ReadLock(); - if ((types != NULL) && (types->type == TCL_GLOB_TYPE_MOUNT)) { + if (types && (types->type == TCL_GLOB_TYPE_MOUNT)) { l = CountSlashes(path); if (path[len - 1] == '/') { len--; } else { l++; } - if ((pattern == NULL) || (pattern[0] == '\0')) { + if (!pattern || (pattern[0] == '\0')) { pattern = "*"; } - hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); - while (hPtr != NULL) { + for (hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); hPtr; + hPtr = Tcl_NextHashEntry(&search)) { ZipFile *zf = Tcl_GetHashValue(hPtr); if (zf->mountPointLen == 0) { ZipEntry *z; - for (z = zf->topEnts; z != NULL; z = z->tnext) { + for (z = zf->topEnts; z; z = z->tnext) { size_t lenz = strlen(z->name); if ((lenz > len + 1) && (strncmp(z->name, path, len) == 0) @@ -4044,7 +4112,7 @@ ZipFSMatchInDirectoryProc( && (CountSlashes(z->name) == l) && Tcl_StringCaseMatch(z->name + len + 1, pattern, 0)) { - if (prefix != NULL) { + if (prefix) { Tcl_DStringAppend(&dsPref, z->name, lenz); Tcl_ListObjAppendElement(NULL, result, Tcl_NewStringObj(Tcl_DStringValue(&dsPref), @@ -4062,7 +4130,7 @@ ZipFSMatchInDirectoryProc( && (CountSlashes(zf->mountPoint) == l) && Tcl_StringCaseMatch(zf->mountPoint + len + 1, pattern, 0)) { - if (prefix != NULL) { + if (prefix) { Tcl_DStringAppend(&dsPref, zf->mountPoint, zf->mountPointLen); Tcl_ListObjAppendElement(NULL, result, @@ -4075,19 +4143,18 @@ ZipFSMatchInDirectoryProc( zf->mountPointLen)); } } - hPtr = Tcl_NextHashEntry(&search); } goto end; } - if ((pattern == NULL) || (pattern[0] == '\0')) { + if (!pattern || (pattern[0] == '\0')) { hPtr = Tcl_FindHashEntry(&ZipFS.fileHash, path); - if (hPtr != NULL) { + if (hPtr) { ZipEntry *z = Tcl_GetHashValue(hPtr); - if ((dirOnly < 0) || (!dirOnly && !z->isdir) - || (dirOnly && z->isdir)) { - if (prefix != NULL) { + if ((dirOnly < 0) || (!dirOnly && !z->isDirectory) + || (dirOnly && z->isDirectory)) { + if (prefix) { Tcl_DStringAppend(&dsPref, z->name, -1); Tcl_ListObjAppendElement(NULL, result, Tcl_NewStringObj(Tcl_DStringValue(&dsPref), @@ -4115,15 +4182,15 @@ ZipFSMatchInDirectoryProc( memcpy(pat + len, pattern, l + 1); scnt = CountSlashes(pat); for (hPtr = Tcl_FirstHashEntry(&ZipFS.fileHash, &search); - hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) { + hPtr; hPtr = Tcl_NextHashEntry(&search)) { ZipEntry *z = Tcl_GetHashValue(hPtr); - if ((dirOnly >= 0) && ((dirOnly && !z->isdir) - || (!dirOnly && z->isdir))) { + if ((dirOnly >= 0) && ((dirOnly && !z->isDirectory) + || (!dirOnly && z->isDirectory))) { continue; } if ((z->depth == scnt) && Tcl_StringCaseMatch(z->name, pat, 0)) { - if (prefix != NULL) { + if (prefix) { Tcl_DStringAppend(&dsPref, z->name + strip, -1); Tcl_ListObjAppendElement(NULL, result, Tcl_NewStringObj(Tcl_DStringValue(&dsPref), @@ -4167,7 +4234,6 @@ ZipFSPathInFilesystemProc( { Tcl_HashEntry *hPtr; Tcl_HashSearch search; - ZipFile *zf; int ret = -1; size_t len; char *path; @@ -4186,14 +4252,15 @@ ZipFSPathInFilesystemProc( ReadLock(); hPtr = Tcl_FindHashEntry(&ZipFS.fileHash, path); - if (hPtr != NULL) { + if (hPtr) { ret = TCL_OK; goto endloop; } - hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); - while (hPtr != NULL) { - zf = Tcl_GetHashValue(hPtr); + for (hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); hPtr; + hPtr = Tcl_NextHashEntry(&search)) { + ZipFile *zf = Tcl_GetHashValue(hPtr); + if (zf->mountPointLen == 0) { ZipEntry *z; @@ -4208,9 +4275,8 @@ ZipFSPathInFilesystemProc( } else if ((len >= zf->mountPointLen) && (strncmp(path, zf->mountPoint, zf->mountPointLen) == 0)) { ret = TCL_OK; - goto endloop; + break; } - hPtr = Tcl_NextHashEntry(&search); } endloop: @@ -4313,27 +4379,27 @@ ZipFSFileAttrsGetProc( path = Tcl_GetStringFromObj(pathPtr, &len); ReadLock(); z = ZipFSLookup(path); - if (z == NULL) { + if (!z) { ZIPFS_ERROR(interp, "file not found"); ret = TCL_ERROR; goto done; } switch (index) { case 0: - *objPtrRef = Tcl_NewWideIntObj(z->nbyte); + *objPtrRef = Tcl_NewWideIntObj(z->numBytes); break; case 1: - *objPtrRef = Tcl_NewWideIntObj(z->nbytecompr); + *objPtrRef = Tcl_NewWideIntObj(z->numCompressedBytes); break; case 2: *objPtrRef = Tcl_NewWideIntObj(z->offset); break; case 3: - *objPtrRef = Tcl_NewStringObj(z->zipfile->mountPoint, - z->zipfile->mountPointLen); + *objPtrRef = Tcl_NewStringObj(z->zipFilePtr->mountPoint, + z->zipFilePtr->mountPointLen); break; case 4: - *objPtrRef = Tcl_NewStringObj(z->zipfile->name, -1); + *objPtrRef = Tcl_NewStringObj(z->zipFilePtr->name, -1); break; case 5: *objPtrRef = Tcl_NewStringObj("0555", -1); @@ -4372,7 +4438,7 @@ ZipFSFileAttrsSetProc( Tcl_Obj *pathPtr, Tcl_Obj *objPtr) { - if (interp != NULL) { + if (interp) { Tcl_SetObjResult(interp, Tcl_NewStringObj("unsupported operation", -1)); } return TCL_ERROR; @@ -4434,7 +4500,7 @@ ZipFSLoadFile( */ loadFileProc = (Tcl_FSLoadFileProc2 *) tclNativeFilesystem.loadFileProc; - if (loadFileProc != NULL) { + if (loadFileProc) { return loadFileProc(interp, path, loadHandle, unloadProcPtr, flags); } Tcl_SetErrno(ENOENT); @@ -4456,7 +4522,7 @@ ZipFSLoadFile( } objs[1] = TclPathPart(interp, path, TCL_PATH_DIRNAME); - if ((objs[1] != NULL) && (ZipFSAccessProc(objs[1], R_OK) == 0)) { + if (objs[1] && (ZipFSAccessProc(objs[1], R_OK) == 0)) { const char *execName = Tcl_GetNameOfExecutable(); /* @@ -4473,7 +4539,7 @@ ZipFSLoadFile( * nameofexecutable] due to VFS effects. */ - if (execName != NULL) { + if (execName) { const char *p = strrchr(execName, '/'); if (p > execName + 1) { @@ -4481,13 +4547,13 @@ ZipFSLoadFile( objs[0] = Tcl_NewStringObj(execName, p - execName); } } - if (objs[0] == NULL) { + if (!objs[0]) { objs[0] = TclPathPart(interp, TclGetObjNameOfExecutable(), TCL_PATH_DIRNAME); } - if (objs[0] != NULL) { + if (objs[0]) { altPath = TclJoinPath(2, objs); - if (altPath != NULL) { + if (altPath) { Tcl_IncrRefCount(altPath); if (Tcl_FSAccess(altPath, R_OK) == 0) { path = altPath; @@ -4495,21 +4561,21 @@ ZipFSLoadFile( } } } - if (objs[0] != NULL) { + if (objs[0]) { Tcl_DecrRefCount(objs[0]); } - if (objs[1] != NULL) { + if (objs[1]) { Tcl_DecrRefCount(objs[1]); } loadFileProc = (Tcl_FSLoadFileProc2 *) tclNativeFilesystem.loadFileProc; - if (loadFileProc != NULL) { + if (loadFileProc) { ret = loadFileProc(interp, path, loadHandle, unloadProcPtr, flags); } else { Tcl_SetErrno(ENOENT); ZIPFS_ERROR(interp, Tcl_PosixError(interp)); } - if (altPath != NULL) { + if (altPath) { Tcl_DecrRefCount(altPath); } return ret; @@ -4584,11 +4650,11 @@ TclZipfs_Init( WriteLock(); /* Tcl_StaticPackage(interp, "zipfs", TclZipfs_Init, TclZipfs_Init); */ if (!ZipFS.initialized) { - TclZipfs_C_Init(); + ZipfsSetup(); } Unlock(); - if (interp != NULL) { + if (interp) { Tcl_EvalEx(interp, findproc, -1, TCL_EVAL_GLOBAL); Tcl_LinkVar(interp, "::tcl::zipfs::wrmax", (char *) &ZipFS.wrmax, TCL_LINK_INT); @@ -4607,7 +4673,7 @@ static int ZipfsAppHookFindTclInit( const char *archive) { - Tcl_Obj *vfsinitscript; + Tcl_Obj *vfsInitScript; int found; if (zipfs_literal_tcl_library) { @@ -4618,20 +4684,20 @@ ZipfsAppHookFindTclInit( return TCL_ERROR; } - vfsinitscript = Tcl_NewStringObj(ZIPFS_ZIP_MOUNT "/init.tcl", -1); - Tcl_IncrRefCount(vfsinitscript); - found = Tcl_FSAccess(vfsinitscript, F_OK); - Tcl_DecrRefCount(vfsinitscript); + TclNewLiteralStringObj(vfsInitScript, ZIPFS_ZIP_MOUNT "/init.tcl"); + Tcl_IncrRefCount(vfsInitScript); + found = Tcl_FSAccess(vfsInitScript, F_OK); + Tcl_DecrRefCount(vfsInitScript); if (found == 0) { zipfs_literal_tcl_library = ZIPFS_ZIP_MOUNT; return TCL_OK; } - vfsinitscript = Tcl_NewStringObj( - ZIPFS_ZIP_MOUNT "/tcl_library/init.tcl", -1); - Tcl_IncrRefCount(vfsinitscript); - found = Tcl_FSAccess(vfsinitscript, F_OK); - Tcl_DecrRefCount(vfsinitscript); + TclNewLiteralStringObj(vfsInitScript, + ZIPFS_ZIP_MOUNT "/tcl_library/init.tcl"); + Tcl_IncrRefCount(vfsInitScript); + found = Tcl_FSAccess(vfsInitScript, F_OK); + Tcl_DecrRefCount(vfsInitScript); if (found == 0) { zipfs_literal_tcl_library = ZIPFS_ZIP_MOUNT "/tcl_library"; return TCL_OK; @@ -4678,7 +4744,7 @@ TclZipfs_AppHook( int found; Tcl_Obj *vfsInitScript; - vfsInitScript = Tcl_NewStringObj(ZIPFS_APP_MOUNT "/main.tcl", -1); + TclNewLiteralStringObj(vfsInitScript, ZIPFS_APP_MOUNT "/main.tcl"); Tcl_IncrRefCount(vfsInitScript); if (Tcl_FSAccess(vfsInitScript, F_OK) == 0) { /* @@ -4695,8 +4761,8 @@ TclZipfs_AppHook( */ if (!zipfs_literal_tcl_library) { - vfsInitScript = Tcl_NewStringObj( - ZIPFS_APP_MOUNT "/tcl_library/init.tcl", -1); + TclNewLiteralStringObj(vfsInitScript, + ZIPFS_APP_MOUNT "/tcl_library/init.tcl"); Tcl_IncrRefCount(vfsInitScript); found = Tcl_FSAccess(vfsInitScript, F_OK); Tcl_DecrRefCount(vfsInitScript); @@ -4726,8 +4792,8 @@ TclZipfs_AppHook( */ TclZipfs_TclLibrary(); - vfsInitScript = Tcl_NewStringObj( - ZIPFS_ZIP_MOUNT "/tcl_library/install.tcl", -1); + TclNewLiteralStringObj(vfsInitScript, + ZIPFS_ZIP_MOUNT "/tcl_library/install.tcl"); Tcl_IncrRefCount(vfsInitScript); if (Tcl_FSAccess(vfsInitScript, F_OK) == 0) { Tcl_SetStartupScript(vfsInitScript, NULL); @@ -4737,7 +4803,7 @@ TclZipfs_AppHook( int found; Tcl_Obj *vfsInitScript; - vfsInitScript = Tcl_NewStringObj(ZIPFS_APP_MOUNT "/main.tcl", -1); + TclNewLiteralStringObj(vfsInitScript, ZIPFS_APP_MOUNT "/main.tcl"); Tcl_IncrRefCount(vfsInitScript); if (Tcl_FSAccess(vfsInitScript, F_OK) == 0) { /* @@ -4749,8 +4815,8 @@ TclZipfs_AppHook( Tcl_DecrRefCount(vfsInitScript); } /* Set Tcl Encodings */ - vfsInitScript = Tcl_NewStringObj( - ZIPFS_APP_MOUNT "/tcl_library/init.tcl", -1); + TclNewLiteralStringObj(vfsInitScript, + ZIPFS_APP_MOUNT "/tcl_library/init.tcl"); Tcl_IncrRefCount(vfsInitScript); found = Tcl_FSAccess(vfsInitScript, F_OK); Tcl_DecrRefCount(vfsInitScript); @@ -4772,7 +4838,7 @@ TclZipfs_AppHook( /* *------------------------------------------------------------------------- * - * TclZipfs_Mount, TclZipfs_Unmount -- + * TclZipfs_Mount, TclZipfs_MountBuffer, TclZipfs_Unmount -- * * Dummy version when no ZLIB support available. * @@ -4787,7 +4853,20 @@ TclZipfs_Mount( const char *passwd) /* Password for opening the ZIP, or NULL if * the ZIP is unprotected. */ { - return TclZipfs_Init(interp, 1); + ZIPFS_ERROR(interp, "no zlib available"); + return TCL_ERROR; +} + +int +TclZipfs_MountBuffer( + Tcl_Interp *interp, /* Current interpreter. NULLable. */ + const char *mountPoint, /* Mount point path. */ + unsigned char *data, + size_t datalen, + int copy) +{ + ZIPFS_ERROR(interp, "no zlib available"); + return TCL_ERROR; } int @@ -4795,7 +4874,8 @@ TclZipfs_Unmount( Tcl_Interp *interp, /* Current interpreter. */ const char *mountPoint) /* Mount point path. */ { - return TclZipfs_Init(interp, 1); + ZIPFS_ERROR(interp, "no zlib available"); + return TCL_ERROR; } #endif /* !HAVE_ZLIB */ diff --git a/tests/zipfs.test b/tests/zipfs.test index 1a5225c..9d60f8d 100644 --- a/tests/zipfs.test +++ b/tests/zipfs.test @@ -15,7 +15,10 @@ if {"::tcltest" ni [namespace children]} { namespace import -force ::tcltest::* } -testConstraint zipfs [expr {[llength [info commands zlib]] && [regexp tcltest [info nameofexecutable]]}] +testConstraint zipfs [expr { + [llength [info commands zlib]] && [regexp tcltest [info nameofexecutable]] +}] +testConstraint zipfslib 1 # Removed in tip430 - zipfs is no longer a static package #test zipfs-0.0 {zipfs basics} -constraints zipfs -body { @@ -27,10 +30,9 @@ set CWD [pwd] set tmpdir [file join $CWD tmp] file mkdir $tmpdir -test zipfs-0.1 {zipfs basics} -constraints zipfs -body { +test zipfs-0.0 {zipfs basics} -constraints zipfs -body { package require zipfs } -result {2.0} - test zipfs-0.1 {zipfs basics} -constraints zipfs -body { expr {${ziproot} in [file volumes]} } -result 1 @@ -43,114 +45,95 @@ if {![string match ${ziproot}* $tcl_library]} { # archive ### set tclzip [file join $CWD [::tcl::pkgconfig get zipfile,runtime]] - if {[file exists $tclzip]} { + testConstraint zipfslib [file exists $tclzip] + if {[testConstraint zipfslib]} { zipfs mount /lib/tcl $tclzip set ::tcl_library ${ziproot}lib/tcl/tcl_library - } else { - tcltest::skip zipfs-0.* } } -test zipfs-0.2 {zipfs basics} -constraints zipfs -body { +test zipfs-0.2 {zipfs basics} -constraints zipfslib -body { string match ${ziproot}* $tcl_library } -result 1 - -test zipfs-0.3 {zipfs basics: glob} -constraints zipfs -body { +test zipfs-0.3 {zipfs basics: glob} -constraints zipfslib -setup { set pwd [pwd] +} -body { cd $tcl_library lsort [glob -dir . http*] } -cleanup { cd $pwd } -result {./http} - -test zipfs-0.4 {zipfs basics: glob} -constraints zipfs -body { +test zipfs-0.4 {zipfs basics: glob} -constraints zipfslib -setup { set pwd [pwd] +} -body { cd $tcl_library lsort [glob -dir [pwd] http*] } -cleanup { cd $pwd } -result [list $tcl_library/http] - -test zipfs-0.5 {zipfs basics: glob} -constraints zipfs -body { +test zipfs-0.5 {zipfs basics: glob} -constraints zipfslib -body { lsort [glob -dir $tcl_library http*] } -result [list $tcl_library/http] - -test zipfs-0.6 {zipfs basics: glob} -constraints zipfs -body { +test zipfs-0.6 {zipfs basics: glob} -constraints zipfslib -body { lsort [glob $tcl_library/http*] } -result [list $tcl_library/http] - -test zipfs-0.7 {zipfs basics: glob} -constraints zipfs -body { +test zipfs-0.7 {zipfs basics: glob} -constraints zipfslib -body { lsort [glob -tails -dir $tcl_library http*] } -result {http} - -test zipfs-0.8 {zipfs basics: glob} -constraints zipfs -body { +test zipfs-0.8 {zipfs basics: glob} -constraints zipfslib -body { lsort [glob -nocomplain -tails -types d -dir $tcl_library http*] } -result {http} - -test zipfs-0.9 {zipfs basics: glob} -constraints zipfs -body { +test zipfs-0.9 {zipfs basics: glob} -constraints zipfslib -body { lsort [glob -nocomplain -tails -types f -dir $tcl_library http*] } -result {} - -test zipfs-0.10 {zipfs basics: join} -constraints zipfs -body { +test zipfs-0.10 {zipfs basics: join} -constraints {zipfs zipfslib} -body { file join [zipfs root] bar baz } -result "[zipfs root]bar/baz" - -test zipfs-0.11 {zipfs basics: join} -constraints zipfs -body { +test zipfs-0.11 {zipfs basics: join} -constraints {zipfs zipfslib} -body { file normalize [zipfs root] } -result "[zipfs root]" - -test zipfs-0.12 {zipfs basics: join} -constraints zipfs -body { +test zipfs-0.12 {zipfs basics: join} -constraints {zipfs zipfslib} -body { file normalize [zipfs root]//bar/baz//qux/../ } -result "[zipfs root]bar/baz" test zipfs-1.3 {zipfs errors} -constraints zipfs -returnCodes error -body { zipfs mount a b c d e f } -result {wrong # args: should be "zipfs mount ?mountpoint? ?zipfile? ?password?"} - test zipfs-1.4 {zipfs errors} -constraints zipfs -returnCodes error -body { zipfs unmount a b c d e f } -result {wrong # args: should be "zipfs unmount zipfile"} - test zipfs-1.5 {zipfs errors} -constraints zipfs -returnCodes error -body { zipfs mkkey a b c d e f } -result {wrong # args: should be "zipfs mkkey password"} - test zipfs-1.6 {zipfs errors} -constraints zipfs -returnCodes error -body { zipfs mkimg a b c d e f } -result {wrong # args: should be "zipfs mkimg outfile indir ?strip? ?password? ?infile?"} - test zipfs-1.7 {zipfs errors} -constraints zipfs -returnCodes error -body { zipfs mkzip a b c d e f } -result {wrong # args: should be "zipfs mkzip outfile indir ?strip? ?password?"} - test zipfs-1.8 {zipfs errors} -constraints zipfs -returnCodes error -body { zipfs exists a b c d e f } -result {wrong # args: should be "zipfs exists filename"} - test zipfs-1.9 {zipfs errors} -constraints zipfs -returnCodes error -body { zipfs info a b c d e f } -result {wrong # args: should be "zipfs info filename"} - test zipfs-1.10 {zipfs errors} -constraints zipfs -returnCodes error -body { zipfs list a b c d e f } -result {wrong # args: should be "zipfs list ?(-glob|-regexp)? ?pattern?"} file mkdir tmp - test zipfs-2.1 {zipfs mkzip empty archive} -constraints zipfs -returnCodes error -body { zipfs mkzip [file join $tmpdir empty.zip] $tcl_library/xxxx } -result {empty archive} - ### -# The 2.2 series of tests operate within -# a zipfile created a temporary directory +# The next series of tests operate within a zipfile created a temporary +# directory. ### set zipfile [file join $tmpdir abc.zip] if {[file exists $zipfile]} { file delete $zipfile } - -test zipfs-2.2.0 {zipfs mkzip} -constraints zipfs -body { +test zipfs-2.2 {zipfs mkzip} -constraints zipfs -body { cd $tcl_library/encoding zipfs mkzip $zipfile . zipfs mount ${ziproot}abc $zipfile @@ -158,17 +141,12 @@ test zipfs-2.2.0 {zipfs mkzip} -constraints zipfs -body { } -cleanup { cd $CWD } -result "[zipfs root]abc/cp850.enc" - -if {![zipfs exists /abc/cp850.enc]} { - skip [concat [skip] zipfs-2.2.*] -} - -test zipfs-2.2.1 {zipfs info} -constraints zipfs -body { +testConstraint zipfsenc [zipfs exists /abc/cp850.enc] +test zipfs-2.3 {zipfs info} -constraints {zipfs zipfsenc} -body { set r [zipfs info ${ziproot}abc/cp850.enc] lrange $r 0 2 } -result [list $zipfile 1090 527] ;# NOTE: Only the first 3 results are stable - -test zipfs-2.2.3 {zipfs data} -constraints zipfs -body { +test zipfs-2.4 {zipfs data} -constraints {zipfs zipfsenc} -body { set zipfd [open ${ziproot}/abc/cp850.enc] ;# FIXME: leave open - see later test read $zipfd } -result {# Encoding file: cp850, single-byte @@ -192,48 +170,38 @@ S 00D300DF00D400D200F500D500B500FE00DE00DA00DB00D900FD00DD00AF00B4 00AD00B1201700BE00B600A700F700B800B000A800B700B900B300B225A000A0 } ;# FIXME: result depends on content of encodings dir - -test zipfs-2.2.4 {zipfs exists} -constraints zipfs -body { +test zipfs-2.5 {zipfs exists} -constraints {zipfs zipfsenc} -body { zipfs exists /abc/cp850.enc } -result 1 - -test zipfs-2.2.5 {zipfs unmount while busy} -constraints zipfs -body { +test zipfs-2.6 {zipfs unmount while busy} -constraints {zipfs zipfsenc} -body { zipfs unmount /abc } -returnCodes error -result {filesystem is busy} - -test zipfs-2.2.6 {zipfs unmount} -constraints zipfs -body { +test zipfs-2.7 {zipfs unmount} -constraints {zipfs zipfsenc} -body { close $zipfd zipfs unmount /abc zipfs exists /abc/cp850.enc } -result 0 - - ### # Repeat the tests for a buffer mounted archive ### -test zipfs-2.3.0 {zipfs mkzip} -constraints zipfs -body { - cd $tcl_library/encoding - zipfs mkzip $zipfile . - set fin [open $zipfile r] - fconfigure $fin -translation binary - set dat [read $fin] - close $fin - zipfs mount_data def $dat +test zipfs-2.8 {zipfs mkzip} -constraints zipfs -body { + cd $tcl_library/encoding + zipfs mkzip $zipfile . + set fin [open $zipfile r] + fconfigure $fin -translation binary + set dat [read $fin] + close $fin + zipfs mount_data def $dat zipfs list -glob ${ziproot}def/cp850.* } -cleanup { cd $CWD } -result "[zipfs root]def/cp850.enc" - -if {![zipfs exists /def/cp850.enc]} { - skip [concat [skip] zipfs-2.3.*] -} - -test zipfs-2.3.1 {zipfs info} -constraints zipfs -body { +testConstraint zipfsencbuf [zipfs exists /def/cp850.enc] +test zipfs-2.9 {zipfs info} -constraints {zipfs zipfsencbuf} -body { set r [zipfs info ${ziproot}def/cp850.enc] lrange $r 0 2 } -result [list {Memory Buffer} 1090 527] ;# NOTE: Only the first 3 results are stable - -test zipfs-2.3.3 {zipfs data} -constraints zipfs -body { +test zipfs-2.10 {zipfs data} -constraints {zipfs zipfsencbuf} -body { set zipfd [open ${ziproot}/def/cp850.enc] ;# FIXME: leave open - see later test read $zipfd } -result {# Encoding file: cp850, single-byte @@ -257,16 +225,13 @@ S 00D300DF00D400D200F500D500B500FE00DE00DA00DB00D900FD00DD00AF00B4 00AD00B1201700BE00B600A700F700B800B000A800B700B900B300B225A000A0 } ;# FIXME: result depends on content of encodings dir - -test zipfs-2.3.4 {zipfs exists} -constraints zipfs -body { +test zipfs-2.11 {zipfs exists} -constraints {zipfs zipfsencbuf} -body { zipfs exists /def/cp850.enc } -result 1 - -test zipfs-2.3.5 {zipfs unmount while busy} -constraints zipfs -body { +test zipfs-2.12 {zipfs unmount while busy} -constraints {zipfs zipfsencbuf} -body { zipfs unmount /def } -returnCodes error -result {filesystem is busy} - -test zipfs-2.3.6 {zipfs unmount} -constraints zipfs -body { +test zipfs-2.13 {zipfs unmount} -constraints {zipfs zipfsencbuf} -body { close $zipfd zipfs unmount /def zipfs exists /def/cp850.enc -- cgit v0.12 From ac711bcf45a5b5bd09e3102e5ea08f726237212f Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Sat, 6 Oct 2018 17:12:46 +0000 Subject: protect Tcl_WinUtfToTChar/Tcl_WinTCharToUtf against NULL input values: return empty string in that case. Add TIP #494-compatible definitions of TCL_IO_FAILURE/TCL_AUTO_LENGTH, and use it in some appropriate places. --- generic/tcl.h | 9 ++++++++- generic/tclIOCmd.c | 2 +- generic/tclIOUtil.c | 8 ++++---- generic/tclZipfs.c | 6 +++--- generic/tclZlib.c | 6 +++--- win/tclWin32Dll.c | 8 +++++++- 6 files changed, 26 insertions(+), 13 deletions(-) diff --git a/generic/tcl.h b/generic/tcl.h index 2ced16b..0971066 100644 --- a/generic/tcl.h +++ b/generic/tcl.h @@ -224,7 +224,7 @@ extern "C" { * to be included in a shared library, then it should have the DLLEXPORT * storage class. If is being declared for use by a module that is going to * link against the shared library, then it should have the DLLIMPORT storage - * class. If the symbol is beind declared for a static build or for use from a + * class. If the symbol is being declared for a static build or for use from a * stub library, then the storage class should be empty. * * The convention is that a macro called BUILD_xxxx, where xxxx is the name of @@ -2334,6 +2334,13 @@ typedef int (Tcl_ArgvGenFuncProc)(ClientData clientData, Tcl_Interp *interp, #define TCL_TCPSERVER_REUSEPORT (1<<1) /* + * Constants for special int-typed values, see TIP #494 + */ + +#define TCL_IO_FAILURE (-1) +#define TCL_AUTO_LENGTH (-1) + +/* *---------------------------------------------------------------------------- * Single public declaration for NRE. */ diff --git a/generic/tclIOCmd.c b/generic/tclIOCmd.c index d38240a..1dd8666 100644 --- a/generic/tclIOCmd.c +++ b/generic/tclIOCmd.c @@ -991,7 +991,7 @@ Tcl_ExecObjCmd( resultPtr = Tcl_NewObj(); if (Tcl_GetChannelHandle(chan, TCL_READABLE, NULL) == TCL_OK) { - if (Tcl_ReadChars(chan, resultPtr, -1, 0) < 0) { + if (Tcl_ReadChars(chan, resultPtr, -1, 0) == TCL_IO_FAILURE) { /* * TIP #219. * Capture error messages put by the driver into the bypass area diff --git a/generic/tclIOUtil.c b/generic/tclIOUtil.c index 11cc22d..63d16be 100644 --- a/generic/tclIOUtil.c +++ b/generic/tclIOUtil.c @@ -1807,7 +1807,7 @@ Tcl_FSEvalFileEx( * be handled especially. */ - if (Tcl_ReadChars(chan, objPtr, 1, 0) < 0) { + if (Tcl_ReadChars(chan, objPtr, 1, 0) == TCL_IO_FAILURE) { Tcl_Close(interp, chan); Tcl_SetObjResult(interp, Tcl_ObjPrintf( "couldn't read file \"%s\": %s", @@ -1822,7 +1822,7 @@ Tcl_FSEvalFileEx( */ if (Tcl_ReadChars(chan, objPtr, -1, - memcmp(string, "\xef\xbb\xbf", 3)) < 0) { + memcmp(string, "\xef\xbb\xbf", 3)) == TCL_IO_FAILURE) { Tcl_Close(interp, chan); Tcl_SetObjResult(interp, Tcl_ObjPrintf( "couldn't read file \"%s\": %s", @@ -1942,7 +1942,7 @@ TclNREvalFile( * be handled especially. */ - if (Tcl_ReadChars(chan, objPtr, 1, 0) < 0) { + if (Tcl_ReadChars(chan, objPtr, 1, 0) == TCL_IO_FAILURE) { Tcl_Close(interp, chan); Tcl_SetObjResult(interp, Tcl_ObjPrintf( "couldn't read file \"%s\": %s", @@ -1958,7 +1958,7 @@ TclNREvalFile( */ if (Tcl_ReadChars(chan, objPtr, -1, - memcmp(string, "\xef\xbb\xbf", 3)) < 0) { + memcmp(string, "\xef\xbb\xbf", 3)) == TCL_IO_FAILURE) { Tcl_Close(interp, chan); Tcl_SetObjResult(interp, Tcl_ObjPrintf( "couldn't read file \"%s\": %s", diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c index b609779..5342fb1 100644 --- a/generic/tclZipfs.c +++ b/generic/tclZipfs.c @@ -4726,9 +4726,6 @@ TclZipfs_AppHook( #endif /* _WIN32 */ ***argvPtr) /* Pointer to argv */ { -#ifdef _WIN32 - Tcl_DString ds; -#endif /* _WIN32 */ char *archive; Tcl_FindExecutable((*argvPtr)[0]); @@ -4773,6 +4770,9 @@ TclZipfs_AppHook( } #ifdef SUPPORT_BUILTIN_ZIP_INSTALL } else if (*argcPtr > 1) { +#ifdef _WIN32 + Tcl_DString ds; +#endif /* _WIN32 */ /* * If the first argument is "install", run the supplied installer * script. diff --git a/generic/tclZlib.c b/generic/tclZlib.c index 644ac8b..9bad36d 100644 --- a/generic/tclZlib.c +++ b/generic/tclZlib.c @@ -2931,7 +2931,7 @@ ZlibTransformClose( result = TCL_ERROR; break; } - if (written && Tcl_WriteRaw(cd->parent, cd->outBuffer, written) < 0) { + if (written && Tcl_WriteRaw(cd->parent, cd->outBuffer, written) == TCL_IO_FAILURE) { /* TODO: is this the right way to do errors on close? * Note: when close is called from FinalizeIOSubsystem then * interp may be NULL */ @@ -3130,7 +3130,7 @@ ZlibTransformOutput( break; } - if (Tcl_WriteRaw(cd->parent, cd->outBuffer, produced) < 0) { + if (Tcl_WriteRaw(cd->parent, cd->outBuffer, produced) == TCL_IO_FAILURE) { *errorCodePtr = Tcl_GetErrno(); return -1; } @@ -3186,7 +3186,7 @@ ZlibTransformFlush( * Write the bytes we've received to the next layer. */ - if (len > 0 && Tcl_WriteRaw(cd->parent, cd->outBuffer, len) < 0) { + if (len > 0 && Tcl_WriteRaw(cd->parent, cd->outBuffer, len) == TCL_IO_FAILURE) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "problem flushing channel: %s", Tcl_PosixError(interp))); diff --git a/win/tclWin32Dll.c b/win/tclWin32Dll.c index 1a33514..04d27dd 100644 --- a/win/tclWin32Dll.c +++ b/win/tclWin32Dll.c @@ -472,6 +472,9 @@ Tcl_WinUtfToTChar( * converted string is stored. */ { Tcl_DStringInit(dsPtr); + if (!string) { + return (TCHAR *)Tcl_DStringValue(dsPtr); + } return Tcl_UtfToUniCharDString(string, len, dsPtr); } @@ -483,12 +486,15 @@ Tcl_WinTCharToUtf( Tcl_DString *dsPtr) /* Uninitialized or free DString in which the * converted string is stored. */ { + Tcl_DStringInit(dsPtr); + if (!string) { + return Tcl_DStringValue(dsPtr); + } if (len > 0) { len /= 2; } else if (len < 0) { len = wcslen(string); } - Tcl_DStringInit(dsPtr); return Tcl_UniCharToUtfDString(string, len, dsPtr); } -- cgit v0.12 From 045e0f533db5ea623b4ea0b519b089b23e2c332e Mon Sep 17 00:00:00 2001 From: dkf Date: Sun, 7 Oct 2018 12:25:34 +0000 Subject: Add better error reporting to zipfs. --- generic/tclZipfs.c | 423 ++++++++++++++++++++++++++++++++++------------------- 1 file changed, 269 insertions(+), 154 deletions(-) diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c index 5342fb1..ea6d5ad 100644 --- a/generic/tclZipfs.c +++ b/generic/tclZipfs.c @@ -136,6 +136,8 @@ #define ZIP_PASSWORD_END_SIG 0x5a5a4b50 +#define DEFAULT_WRITE_MAX_SIZE (2 * 1024 * 1024) + /* * Macros to report errors only if an interp is present. */ @@ -282,7 +284,7 @@ static struct { Tcl_HashTable fileHash; /* File name to ZipEntry mapping */ Tcl_HashTable zipHash; /* Mount to ZipFile mapping */ } ZipFS = { - 0, 0, 0, 0, 0, + 0, 0, 0, DEFAULT_WRITE_MAX_SIZE, 0, }; /* @@ -574,12 +576,8 @@ ToDosTime( { struct tm *tmp, tm; -#if !defined(TCL_THREADS) - /* Not threaded */ - tmp = localtime(&when); - tm = *tmp; -#elif defined(_WIN32) - /* Win32 uses thread local storage */ +#if !defined(TCL_THREADS) || defined(_WIN32) + /* Not threaded, or on Win32 which uses thread local storage */ tmp = localtime(&when); tm = *tmp; #elif defined(HAVE_LOCALTIME_R) @@ -602,12 +600,8 @@ ToDosDate( { struct tm *tmp, tm; -#if !defined(TCL_THREADS) - /* Not threaded */ - tmp = localtime(&when); - tm = *tmp; -#elif /* TCL_THREADS && */ defined(_WIN32) - /* Win32 uses thread local storage */ +#if !defined(TCL_THREADS) || defined(_WIN32) + /* Not threaded, or on Win32 which uses thread local storage */ tmp = localtime(&when); tm = *tmp; #elif /* TCL_THREADS && !_WIN32 && */ defined(HAVE_LOCALTIME_R) @@ -1001,6 +995,9 @@ ZipFSFindTOC( return TCL_OK; } ZIPFS_ERROR(interp, "wrong end signature"); + if (interp) { + Tcl_SetErrorCode(interp, "TCL", "ZIPFS", "END_SIG", NULL); + } goto error; } zf->numFiles = ZipReadShort(p + ZIP_CENTRAL_ENTS_OFFS); @@ -1010,6 +1007,9 @@ ZipFSFindTOC( return TCL_OK; } ZIPFS_ERROR(interp, "empty archive"); + if (interp) { + Tcl_SetErrorCode(interp, "TCL", "ZIPFS", "EMPTY", NULL); + } goto error; } q = zf->data + ZipReadInt(p + ZIP_CENTRAL_DIRSTART_OFFS); @@ -1021,6 +1021,9 @@ ZipFSFindTOC( return TCL_OK; } ZIPFS_ERROR(interp, "archive directory not found"); + if (interp) { + Tcl_SetErrorCode(interp, "TCL", "ZIPFS", "NO_DIR", NULL); + } goto error; } zf->baseOffset = zf->passOffset = p - q; @@ -1031,10 +1034,16 @@ ZipFSFindTOC( if (q + ZIP_CENTRAL_HEADER_LEN > zf->data + zf->length) { ZIPFS_ERROR(interp, "wrong header length"); + if (interp) { + Tcl_SetErrorCode(interp, "TCL", "ZIPFS", "HDR_LEN", NULL); + } goto error; } if (ZipReadInt(q) != ZIP_CENTRAL_HEADER_SIG) { ZIPFS_ERROR(interp, "wrong header signature"); + if (interp) { + Tcl_SetErrorCode(interp, "TCL", "ZIPFS", "HDR_SIG", NULL); + } goto error; } pathlen = ZipReadShort(q + ZIP_CENTRAL_PATHLEN_OFFS); @@ -1116,6 +1125,9 @@ ZipFSOpenArchive( if ((zf->length - ZIP_CENTRAL_END_LEN) > (64 * 1024 * 1024 - ZIP_CENTRAL_END_LEN)) { ZIPFS_ERROR(interp, "illegal file size"); + if (interp) { + Tcl_SetErrorCode(interp, "TCL", "ZIPFS", "FILE_SIZE", NULL); + } goto error; } if (Tcl_Seek(zf->chan, 0, SEEK_SET) == -1) { @@ -1125,6 +1137,9 @@ ZipFSOpenArchive( zf->ptrToFree = zf->data = attemptckalloc(zf->length); if (!zf->ptrToFree) { ZIPFS_ERROR(interp, "out of memory"); + if (interp) { + Tcl_SetErrorCode(interp, "TCL", "MALLOC", NULL); + } goto error; } i = Tcl_Read(zf->chan, (char *) zf->data, zf->length); @@ -1227,6 +1242,7 @@ ZipFSCatalogFilesystem( if (interp) { Tcl_SetObjResult(interp, Tcl_NewStringObj("illegal password", -1)); + Tcl_SetErrorCode(interp, "TCL", "ZIPFS", "BAD_PASS", NULL); } return TCL_ERROR; } @@ -1252,6 +1268,7 @@ ZipFSCatalogFilesystem( zf = Tcl_GetHashValue(hPtr); Tcl_SetObjResult(interp, Tcl_ObjPrintf( "%s is already mounted on %s", zf->name, mountPoint)); + Tcl_SetErrorCode(interp, "TCL", "ZIPFS", "MOUNTED", NULL); } Unlock(); ZipFSCloseArchive(interp, zf0); @@ -1261,6 +1278,7 @@ ZipFSCatalogFilesystem( if (!zf) { if (interp) { Tcl_AppendResult(interp, "out of memory", (char *) NULL); + Tcl_SetErrorCode(interp, "TCL", "MALLOC", NULL); } Unlock(); ZipFSCloseArchive(interp, zf0); @@ -1504,6 +1522,7 @@ ZipfsSetup(void) Tcl_InitHashTable(&ZipFS.fileHash, TCL_STRING_KEYS); Tcl_InitHashTable(&ZipFS.zipHash, TCL_STRING_KEYS); ZipFS.idCount = 1; + ZipFS.wrmax = DEFAULT_WRITE_MAX_SIZE; ZipFS.initialized = 1; } @@ -1648,6 +1667,7 @@ TclZipfs_Mount( if (interp) { Tcl_SetObjResult(interp, Tcl_NewStringObj("illegal password", -1)); + Tcl_SetErrorCode(interp, "TCL", "ZIPFS", "BAD_PASS", NULL); } return TCL_ERROR; } @@ -1656,6 +1676,7 @@ TclZipfs_Mount( if (!zf) { if (interp) { Tcl_AppendResult(interp, "out of memory", (char *) NULL); + Tcl_SetErrorCode(interp, "TCL", "MALLOC", NULL); } return TCL_ERROR; } @@ -1728,6 +1749,7 @@ TclZipfs_MountBuffer( if (!zf) { if (interp) { Tcl_AppendResult(interp, "out of memory", (char *) NULL); + Tcl_SetErrorCode(interp, "TCL", "MALLOC", NULL); } return TCL_ERROR; } @@ -1738,6 +1760,7 @@ TclZipfs_MountBuffer( if (!zf->data) { if (interp) { Tcl_AppendResult(interp, "out of memory", (char *) NULL); + Tcl_SetErrorCode(interp, "TCL", "MALLOC", NULL); } return TCL_ERROR; } @@ -1834,7 +1857,7 @@ TclZipfs_Unmount( * * ZipFSMountObjCmd -- * - * This procedure is invoked to process the "zipfs::mount" command. + * This procedure is invoked to process the [zipfs mount] command. * * Results: * A standard Tcl result. @@ -1847,10 +1870,10 @@ TclZipfs_Unmount( static int ZipFSMountObjCmd( - ClientData clientData, + ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ - int objc, - Tcl_Obj *const objv[]) + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument objects. */ { if (objc > 4) { Tcl_WrongNumArgs(interp, 1, objv, @@ -1868,7 +1891,7 @@ ZipFSMountObjCmd( * * ZipFSMountBufferObjCmd -- * - * This procedure is invoked to process the "zipfs::mount_data" command. + * This procedure is invoked to process the [zipfs mount_data] command. * * Results: * A standard Tcl result. @@ -1881,10 +1904,10 @@ ZipFSMountObjCmd( static int ZipFSMountBufferObjCmd( - ClientData clientData, + ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ - int objc, - Tcl_Obj *const objv[]) + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument objects. */ { const char *mountPoint; /* Mount point path. */ unsigned char *data; @@ -1920,7 +1943,7 @@ ZipFSMountBufferObjCmd( * * ZipFSRootObjCmd -- * - * This procedure is invoked to process the "zipfs::root" command. It + * This procedure is invoked to process the [zipfs root] command. It * returns the root that all zipfs file systems are mounted under. * * Results: @@ -1933,10 +1956,10 @@ ZipFSMountBufferObjCmd( static int ZipFSRootObjCmd( - ClientData clientData, + ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ - int objc, - Tcl_Obj *const objv[]) + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument objects. */ { Tcl_SetObjResult(interp, Tcl_NewStringObj(ZIPFS_VOLUME, -1)); return TCL_OK; @@ -1947,7 +1970,7 @@ ZipFSRootObjCmd( * * ZipFSUnmountObjCmd -- * - * This procedure is invoked to process the "zipfs::unmount" command. + * This procedure is invoked to process the [zipfs unmount] command. * * Results: * A standard Tcl result. @@ -1960,10 +1983,10 @@ ZipFSRootObjCmd( static int ZipFSUnmountObjCmd( - ClientData clientData, + ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ - int objc, - Tcl_Obj *const objv[]) + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument objects. */ { if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "zipfile"); @@ -1977,7 +2000,7 @@ ZipFSUnmountObjCmd( * * ZipFSMkKeyObjCmd -- * - * This procedure is invoked to process the "zipfs::mkkey" command. It + * This procedure is invoked to process the [zipfs mkkey] command. It * produces a rotated password to be embedded into an image file. * * Results: @@ -1991,10 +2014,10 @@ ZipFSUnmountObjCmd( static int ZipFSMkKeyObjCmd( - ClientData clientData, + ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ - int objc, - Tcl_Obj *const objv[]) + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument objects. */ { int len, i = 0; char *pw, passBuf[264]; @@ -2091,6 +2114,7 @@ ZipAddFile( if (zpathlen + ZIP_CENTRAL_HEADER_LEN > bufsize) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "path too long for \"%s\"", path)); + Tcl_SetErrorCode(interp, "TCL", "ZIPFS", "PATH_LEN", NULL); return TCL_ERROR; } in = Tcl_OpenFileChannel(interp, path, "rb", 0); @@ -2178,13 +2202,21 @@ ZipAddFile( double r; if (Tcl_EvalEx(interp, "::tcl::mathfunc::rand", -1, 0) != TCL_OK) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf("PRNG error: %s", - Tcl_GetString(Tcl_GetObjResult(interp)))); + Tcl_Obj *eiPtr = Tcl_ObjPrintf( + "\n (evaluating PRNG step %d for password encoding)", + i); + + Tcl_AppendObjToErrorInfo(interp, eiPtr); Tcl_Close(interp, in); return TCL_ERROR; } ret = Tcl_GetObjResult(interp); if (Tcl_GetDoubleFromObj(interp, ret, &r) != TCL_OK) { + Tcl_Obj *eiPtr = Tcl_ObjPrintf( + "\n (evaluating PRNG step %d for password encoding)", + i); + + Tcl_AppendObjToErrorInfo(interp, eiPtr); Tcl_Close(interp, in); return TCL_ERROR; } @@ -2221,6 +2253,7 @@ ZipAddFile( Z_DEFAULT_STRATEGY) != Z_OK) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "compression init error on \"%s\"", path)); + Tcl_SetErrorCode(interp, "TCL", "ZIPFS", "DEFLATE_INIT", NULL); Tcl_Close(interp, in); return TCL_ERROR; } @@ -2243,6 +2276,7 @@ ZipAddFile( if (len == (size_t) Z_STREAM_ERROR) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "deflate error on %s", path)); + Tcl_SetErrorCode(interp, "TCL", "ZIPFS", "DEFLATE", NULL); deflateEnd(&stream); Tcl_Close(interp, in); return TCL_ERROR; @@ -2318,7 +2352,16 @@ ZipAddFile( } Tcl_Close(interp, in); + hPtr = Tcl_CreateHashEntry(fileHash, zpath, &isNew); + if (!isNew) { + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "non-unique path name \"%s\"", path)); + Tcl_SetErrorCode(interp, "TCL", "ZIPFS", "DUPLICATE_PATH", NULL); + return TCL_ERROR; + } + z = ckalloc(sizeof(ZipEntry)); + Tcl_SetHashValue(hPtr, z); z->name = NULL; z->tnext = NULL; z->depth = 0; @@ -2332,17 +2375,8 @@ ZipAddFile( z->numCompressedBytes = nbytecompr; z->compressMethod = compMeth; z->data = NULL; - hPtr = Tcl_CreateHashEntry(fileHash, zpath, &isNew); - if (!isNew) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "non-unique path name \"%s\"", path)); - ckfree(z); - return TCL_ERROR; - } else { - Tcl_SetHashValue(hPtr, z); - z->name = Tcl_GetHashKey(fileHash, hPtr); - z->next = NULL; - } + z->name = Tcl_GetHashKey(fileHash, hPtr); + z->next = NULL; /* * Write final local header information. @@ -2404,12 +2438,11 @@ ZipAddFile( static int ZipFSMkZipOrImgObjCmd( - ClientData clientData, Tcl_Interp *interp, /* Current interpreter. */ int isImg, int isList, - int objc, - Tcl_Obj *const objv[]) + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument objects. */ { Tcl_Channel out; int pwlen = 0, count, ret = TCL_ERROR, lobjc; @@ -2433,6 +2466,7 @@ ZipFSMkZipOrImgObjCmd( if ((pwlen > 255) || strchr(pw, 0xff)) { Tcl_SetObjResult(interp, Tcl_NewStringObj("illegal password", -1)); + Tcl_SetErrorCode(interp, "TCL", "ZIPFS", "BAD_PASS", NULL); return TCL_ERROR; } } @@ -2462,11 +2496,13 @@ ZipFSMkZipOrImgObjCmd( Tcl_DecrRefCount(list); Tcl_SetObjResult(interp, Tcl_NewStringObj("need even number of elements", -1)); + Tcl_SetErrorCode(interp, "TCL", "ZIPFS", "LIST_LENGTH", NULL); return TCL_ERROR; } if (lobjc == 0) { Tcl_DecrRefCount(list); Tcl_SetObjResult(interp, Tcl_NewStringObj("empty archive", -1)); + Tcl_SetErrorCode(interp, "TCL", "ZIPFS", "EMPTY", NULL); return TCL_ERROR; } out = Tcl_OpenFileChannel(interp, Tcl_GetString(objv[1]), "wb", 0755); @@ -2741,10 +2777,10 @@ ZipFSMkZipOrImgObjCmd( /* *------------------------------------------------------------------------- * - * ZipFSMkZipObjCmd -- + * ZipFSMkZipObjCmd, ZipFSLMkZipObjCmd -- * - * This procedure is invoked to process the "zipfs::mkzip" command. See - * description of ZipFSMkZipOrImgCmd(). + * These procedures are invoked to process the [zipfs mkzip] and [zipfs + * lmkzip] commands. See description of ZipFSMkZipOrImgCmd(). * * Results: * A standard Tcl result. @@ -2757,10 +2793,10 @@ ZipFSMkZipOrImgObjCmd( static int ZipFSMkZipObjCmd( - ClientData clientData, + ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ - int objc, - Tcl_Obj *const objv[]) + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument objects. */ { if (objc < 3 || objc > 5) { Tcl_WrongNumArgs(interp, 1, objv, "outfile indir ?strip? ?password?"); @@ -2769,17 +2805,18 @@ ZipFSMkZipObjCmd( if (Tcl_IsSafe(interp)) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "operation not permitted in a safe interpreter", -1)); + Tcl_SetErrorCode(interp, "TCL", "ZIPFS", "SAFE_INTERP", NULL); return TCL_ERROR; } - return ZipFSMkZipOrImgObjCmd(clientData, interp, 0, 0, objc, objv); + return ZipFSMkZipOrImgObjCmd(interp, 0, 0, objc, objv); } static int ZipFSLMkZipObjCmd( - ClientData clientData, + ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ - int objc, - Tcl_Obj *const objv[]) + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument objects. */ { if (objc < 3 || objc > 4) { Tcl_WrongNumArgs(interp, 1, objv, "outfile inlist ?password?"); @@ -2788,18 +2825,19 @@ ZipFSLMkZipObjCmd( if (Tcl_IsSafe(interp)) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "operation not permitted in a safe interpreter", -1)); + Tcl_SetErrorCode(interp, "TCL", "ZIPFS", "SAFE_INTERP", NULL); return TCL_ERROR; } - return ZipFSMkZipOrImgObjCmd(clientData, interp, 0, 1, objc, objv); + return ZipFSMkZipOrImgObjCmd(interp, 0, 1, objc, objv); } /* *------------------------------------------------------------------------- * - * ZipFSZipFSOpenArchiveObjCmd -- + * ZipFSMkImgObjCmd, ZipFSLMkImgObjCmd -- * - * This procedure is invoked to process the "zipfs::mkimg" command. See - * description of ZipFSMkZipOrImgCmd(). + * These procedures are invoked to process the [zipfs mkimg] and [zipfs + * lmkimg] commands. See description of ZipFSMkZipOrImgCmd(). * * Results: * A standard Tcl result. @@ -2812,10 +2850,10 @@ ZipFSLMkZipObjCmd( static int ZipFSMkImgObjCmd( - ClientData clientData, + ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ - int objc, - Tcl_Obj *const objv[]) + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument objects. */ { if (objc < 3 || objc > 6) { Tcl_WrongNumArgs(interp, 1, objv, @@ -2825,17 +2863,18 @@ ZipFSMkImgObjCmd( if (Tcl_IsSafe(interp)) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "operation not permitted in a safe interpreter", -1)); + Tcl_SetErrorCode(interp, "TCL", "ZIPFS", "SAFE_INTERP", NULL); return TCL_ERROR; } - return ZipFSMkZipOrImgObjCmd(clientData, interp, 1, 0, objc, objv); + return ZipFSMkZipOrImgObjCmd(interp, 1, 0, objc, objv); } static int ZipFSLMkImgObjCmd( - ClientData clientData, + ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ - int objc, - Tcl_Obj *const objv[]) + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument objects. */ { if (objc < 3 || objc > 5) { Tcl_WrongNumArgs(interp, 1, objv, "outfile inlist ?password infile?"); @@ -2844,9 +2883,10 @@ ZipFSLMkImgObjCmd( if (Tcl_IsSafe(interp)) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "operation not permitted in a safe interpreter", -1)); + Tcl_SetErrorCode(interp, "TCL", "ZIPFS", "SAFE_INTERP", NULL); return TCL_ERROR; } - return ZipFSMkZipOrImgObjCmd(clientData, interp, 1, 1, objc, objv); + return ZipFSMkZipOrImgObjCmd(interp, 1, 1, objc, objv); } /* @@ -2854,7 +2894,7 @@ ZipFSLMkImgObjCmd( * * ZipFSCanonicalObjCmd -- * - * This procedure is invoked to process the "zipfs::canonical" command. + * This procedure is invoked to process the [zipfs canonical] command. * It returns the canonical name for a file within zipfs * * Results: @@ -2868,10 +2908,10 @@ ZipFSLMkImgObjCmd( static int ZipFSCanonicalObjCmd( - ClientData clientData, + ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ - int objc, - Tcl_Obj *const objv[]) + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument objects. */ { char *mntpoint = NULL; char *filename = NULL; @@ -2909,7 +2949,7 @@ ZipFSCanonicalObjCmd( * * ZipFSExistsObjCmd -- * - * This procedure is invoked to process the "zipfs::exists" command. It + * This procedure is invoked to process the [zipfs exists] command. It * tests for the existence of a file in the ZIP filesystem and places a * boolean into the interp's result. * @@ -2924,10 +2964,10 @@ ZipFSCanonicalObjCmd( static int ZipFSExistsObjCmd( - ClientData clientData, + ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ - int objc, - Tcl_Obj *const objv[]) + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument objects. */ { char *filename; int exists; @@ -2961,7 +3001,7 @@ ZipFSExistsObjCmd( * * ZipFSInfoObjCmd -- * - * This procedure is invoked to process the "zipfs::info" command. On + * This procedure is invoked to process the [zipfs info] command. On * success, it returns a Tcl list made up of name of ZIP archive file, * size uncompressed, size compressed, and archive offset of a file in * the ZIP filesystem. @@ -2977,10 +3017,10 @@ ZipFSExistsObjCmd( static int ZipFSInfoObjCmd( - ClientData clientData, + ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ - int objc, - Tcl_Obj *const objv[]) + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument objects. */ { char *filename; ZipEntry *z; @@ -3012,7 +3052,7 @@ ZipFSInfoObjCmd( * * ZipFSListObjCmd -- * - * This procedure is invoked to process the "zipfs::list" command. On + * This procedure is invoked to process the [zipfs list] command. On * success, it returns a Tcl list of files of the ZIP filesystem which * match a search pattern (glob or regexp). * @@ -3027,10 +3067,10 @@ ZipFSInfoObjCmd( static int ZipFSListObjCmd( - ClientData clientData, + ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ - int objc, - Tcl_Obj *const objv[]) + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument objects. */ { char *pattern = NULL; Tcl_RegExp regexp = NULL; @@ -3056,6 +3096,7 @@ ZipFSListObjCmd( } else { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "unknown option \"%s\"", what)); + Tcl_SetErrorCode(interp, "TCL", "ZIPFS", "BAD_OPT", NULL); return TCL_ERROR; } } else if (objc == 2) { @@ -3095,17 +3136,35 @@ ZipFSListObjCmd( return TCL_OK; } +/* + *------------------------------------------------------------------------- + * + * TclZipfs_TclLibrary -- + * + * This procedure gets (and possibly finds) the root that Tcl's library + * files are mounted under. + * + * Results: + * A Tcl object holding the location (with zero refcount), or NULL if no + * Tcl library can be found. + * + * Side effects: + * May initialise the cache of where such library files are to be found. + * This cache is never cleared. + * + *------------------------------------------------------------------------- + */ + #ifdef _WIN32 #define LIBRARY_SIZE 64 -static int -ToUtf( +static inline int +WCharToUtf( const WCHAR *wSrc, char *dst) { - char *start; + char *start = dst; - start = dst; while (*wSrc != '\0') { dst += Tcl_UniCharToUtf(*wSrc, dst); wSrc++; @@ -3118,68 +3177,83 @@ ToUtf( Tcl_Obj * TclZipfs_TclLibrary(void) { - if (zipfs_literal_tcl_library) { - return Tcl_NewStringObj(zipfs_literal_tcl_library, -1); - } else { - Tcl_Obj *vfsinitscript; - int found = 0; + Tcl_Obj *vfsInitScript; + int found; #ifdef _WIN32 - HMODULE hModule = TclWinGetTclInstance(); - WCHAR wName[MAX_PATH + LIBRARY_SIZE]; - char dllname[(MAX_PATH + LIBRARY_SIZE) * TCL_UTF_MAX]; + HMODULE hModule; + WCHAR wName[MAX_PATH + LIBRARY_SIZE]; + char dllName[(MAX_PATH + LIBRARY_SIZE) * TCL_UTF_MAX]; #endif /* _WIN32 */ - /* - * Look for the library file system within the executable. - */ - vfsinitscript = Tcl_NewStringObj( - ZIPFS_APP_MOUNT "/tcl_library/init.tcl", -1); - Tcl_IncrRefCount(vfsinitscript); - found = Tcl_FSAccess(vfsinitscript, F_OK); - Tcl_DecrRefCount(vfsinitscript); - if (found == TCL_OK) { - zipfs_literal_tcl_library = ZIPFS_APP_MOUNT "/tcl_library"; - return Tcl_NewStringObj(zipfs_literal_tcl_library, -1); - } + /* + * Use the cached value if that has been set; we don't want to repeat the + * searching and mounting. + */ -#if defined(_WIN32) - if (GetModuleFileNameW(hModule, wName, MAX_PATH) == 0) { - GetModuleFileNameA(hModule, dllname, MAX_PATH); - } else { - ToUtf(wName, dllname); - } + if (zipfs_literal_tcl_library) { + return Tcl_NewStringObj(zipfs_literal_tcl_library, -1); + } - /* - * Mount zip file and dll before releasing to search. - */ + /* + * Look for the library file system within the executable. + */ - if (ZipfsAppHookFindTclInit(dllname) == TCL_OK) { - return Tcl_NewStringObj(zipfs_literal_tcl_library, -1); - } + vfsInitScript = Tcl_NewStringObj(ZIPFS_APP_MOUNT "/tcl_library/init.tcl", + -1); + Tcl_IncrRefCount(vfsInitScript); + found = Tcl_FSAccess(vfsInitScript, F_OK); + Tcl_DecrRefCount(vfsInitScript); + if (found == TCL_OK) { + zipfs_literal_tcl_library = ZIPFS_APP_MOUNT "/tcl_library"; + return Tcl_NewStringObj(zipfs_literal_tcl_library, -1); + } + + /* + * Look for the library file system within the DLL/shared library. Note + * that we must mount the zip file and dll before releasing to search. + */ + +#if defined(_WIN32) + hModule = TclWinGetTclInstance(); + if (GetModuleFileNameW(hModule, wName, MAX_PATH) == 0) { + GetModuleFileNameA(hModule, dllName, MAX_PATH); + } else { + WCharToUtf(wName, dllName); + } + + if (ZipfsAppHookFindTclInit(dllName) == TCL_OK) { + return Tcl_NewStringObj(zipfs_literal_tcl_library, -1); + } #elif /* !_WIN32 && */ defined(CFG_RUNTIME_DLLFILE) - /* - * Mount zip file and dll before releasing to search. - */ - if (ZipfsAppHookFindTclInit( - CFG_RUNTIME_LIBDIR "/" CFG_RUNTIME_DLLFILE) == TCL_OK) { - return Tcl_NewStringObj(zipfs_literal_tcl_library, -1); - } + if (ZipfsAppHookFindTclInit( + CFG_RUNTIME_LIBDIR "/" CFG_RUNTIME_DLLFILE) == TCL_OK) { + return Tcl_NewStringObj(zipfs_literal_tcl_library, -1); + } #endif /* _WIN32 || CFG_RUNTIME_DLLFILE */ + /* + * If we're configured to know about a ZIP archive we should use, do that. + */ + #ifdef CFG_RUNTIME_ZIPFILE - if (ZipfsAppHookFindTclInit( - CFG_RUNTIME_LIBDIR "/" CFG_RUNTIME_ZIPFILE) == TCL_OK) { - return Tcl_NewStringObj(zipfs_literal_tcl_library, -1); - } - if (ZipfsAppHookFindTclInit( - CFG_RUNTIME_SCRDIR "/" CFG_RUNTIME_ZIPFILE) == TCL_OK) { - return Tcl_NewStringObj(zipfs_literal_tcl_library, -1); - } - if (ZipfsAppHookFindTclInit(CFG_RUNTIME_ZIPFILE) == TCL_OK) { - return Tcl_NewStringObj(zipfs_literal_tcl_library, -1); - } -#endif /* CFG_RUNTIME_ZIPFILE */ + if (ZipfsAppHookFindTclInit( + CFG_RUNTIME_LIBDIR "/" CFG_RUNTIME_ZIPFILE) == TCL_OK) { + return Tcl_NewStringObj(zipfs_literal_tcl_library, -1); + } + if (ZipfsAppHookFindTclInit( + CFG_RUNTIME_SCRDIR "/" CFG_RUNTIME_ZIPFILE) == TCL_OK) { + return Tcl_NewStringObj(zipfs_literal_tcl_library, -1); } + if (ZipfsAppHookFindTclInit(CFG_RUNTIME_ZIPFILE) == TCL_OK) { + return Tcl_NewStringObj(zipfs_literal_tcl_library, -1); + } +#endif /* CFG_RUNTIME_ZIPFILE */ + + /* + * If anything set the cache (but subsequently failed) go with that + * anyway. + */ + if (zipfs_literal_tcl_library) { return Tcl_NewStringObj(zipfs_literal_tcl_library, -1); } @@ -3191,23 +3265,25 @@ TclZipfs_TclLibrary(void) * * ZipFSTclLibraryObjCmd -- * - * This procedure is invoked to process the "zipfs::tcl_library" command. - * It returns the root that all zipfs file systems are mounted under. + * This procedure is invoked to process the [zipfs tcl_library] command. + * It returns the root that Tcl's library files are mounted under. * * Results: * A standard Tcl result. * * Side effects: + * May initialise the cache of where such library files are to be found. + * This cache is never cleared. * *------------------------------------------------------------------------- */ static int ZipFSTclLibraryObjCmd( - ClientData clientData, + ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ - int objc, - Tcl_Obj *const objv[]) + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument objects. */ { Tcl_Obj *pResult = TclZipfs_TclLibrary(); @@ -3552,15 +3628,18 @@ ZipChannelOpen( if (interp) { Tcl_SetObjResult(interp, Tcl_NewStringObj("unsupported open mode", -1)); + Tcl_SetErrorCode(interp, "TCL", "ZIPFS", "BAD_MODE", NULL); } return NULL; } WriteLock(); z = ZipFSLookup(filename); if (!z) { + Tcl_SetErrno(ENOENT); if (interp) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "file not found \"%s\"", filename)); + "file not found \"%s\": %s", filename, + Tcl_PosixError(interp))); } goto error; } @@ -3569,19 +3648,31 @@ ZipChannelOpen( if ((z->compressMethod != ZIP_COMPMETH_STORED) && (z->compressMethod != ZIP_COMPMETH_DEFLATED)) { ZIPFS_ERROR(interp, "unsupported compression method"); + if (interp) { + Tcl_SetErrorCode(interp, "TCL", "ZIPFS", "COMP_METHOD", NULL); + } goto error; } if (wr && z->isDirectory) { ZIPFS_ERROR(interp, "unsupported file type"); + if (interp) { + Tcl_SetErrorCode(interp, "TCL", "ZIPFS", "FILE_TYPE", NULL); + } goto error; } if (!trunc) { flags |= TCL_READABLE; if (z->isEncrypted && (z->zipFilePtr->passBuf[0] == 0)) { ZIPFS_ERROR(interp, "decryption failed"); + if (interp) { + Tcl_SetErrorCode(interp, "TCL", "ZIPFS", "DECRYPT", NULL); + } goto error; } else if (wr && !z->data && (z->numBytes > ZipFS.wrmax)) { ZIPFS_ERROR(interp, "file too large"); + if (interp) { + Tcl_SetErrorCode(interp, "TCL", "ZIPFS", "FILE_SIZE", NULL); + } goto error; } } else { @@ -3590,6 +3681,9 @@ ZipChannelOpen( info = attemptckalloc(sizeof(ZipChannel)); if (!info) { ZIPFS_ERROR(interp, "out of memory"); + if (interp) { + Tcl_SetErrorCode(interp, "TCL", "MALLOC", NULL); + } goto error; } info->zipFilePtr = z->zipFilePtr; @@ -3610,6 +3704,9 @@ ZipChannelOpen( } ckfree(info); ZIPFS_ERROR(interp, "out of memory"); + if (interp) { + Tcl_SetErrorCode(interp, "TCL", "MALLOC", NULL); + } goto error; } memset(info->ubuf, 0, info->maxWrite); @@ -3694,6 +3791,9 @@ ZipChannelOpen( } ckfree(info); ZIPFS_ERROR(interp, "decompression error"); + if (interp) { + Tcl_SetErrorCode(interp, "TCL", "ZIPFS", "CORRUPT", NULL); + } goto error; } else if (z->isEncrypted) { for (i = 0; i < z->numBytes - 12; i++) { @@ -3779,6 +3879,7 @@ ZipChannelOpen( if (interp) { Tcl_SetObjResult(interp, Tcl_NewStringObj("out of memory", -1)); + Tcl_SetErrorCode(interp, "TCL", "MALLOC", NULL); } goto error; } @@ -3808,6 +3909,9 @@ ZipChannelOpen( } ckfree(info); ZIPFS_ERROR(interp, "decompression error"); + if (interp) { + Tcl_SetErrorCode(interp, "TCL", "ZIPFS", "CORRUPT", NULL); + } goto error; } } @@ -4380,7 +4484,8 @@ ZipFSFileAttrsGetProc( ReadLock(); z = ZipFSLookup(path); if (!z) { - ZIPFS_ERROR(interp, "file not found"); + Tcl_SetErrno(ENOENT); + ZIPFS_POSIX_ERROR(interp, "file not found"); ret = TCL_ERROR; goto done; } @@ -4440,6 +4545,7 @@ ZipFSFileAttrsSetProc( { if (interp) { Tcl_SetObjResult(interp, Tcl_NewStringObj("unsupported operation", -1)); + Tcl_SetErrorCode(interp, "TCL", "ZIPFS", "UNSUPPORTED_OP", NULL); } return TCL_ERROR; } @@ -4663,10 +4769,11 @@ TclZipfs_Init( Tcl_PkgProvide(interp, "zipfs", "2.0"); } return TCL_OK; -#else +#else /* !HAVE_ZLIB */ ZIPFS_ERROR(interp, "no zlib available"); + Tcl_SetErrorCode(interp, "TCL", "ZIPFS", "NO_ZLIB", NULL); return TCL_ERROR; -#endif +#endif /* HAVE_ZLIB */ } static int @@ -4770,15 +4877,14 @@ TclZipfs_AppHook( } #ifdef SUPPORT_BUILTIN_ZIP_INSTALL } else if (*argcPtr > 1) { -#ifdef _WIN32 - Tcl_DString ds; -#endif /* _WIN32 */ /* * If the first argument is "install", run the supplied installer * script. */ #ifdef _WIN32 + Tcl_DString ds; + archive = Tcl_WinTCharToUtf((*argvPtr)[1], -1, &ds); #else /* !_WIN32 */ archive = (*argvPtr)[1]; @@ -4854,6 +4960,9 @@ TclZipfs_Mount( * the ZIP is unprotected. */ { ZIPFS_ERROR(interp, "no zlib available"); + if (interp) { + Tcl_SetErrorCode(interp, "TCL", "ZIPFS", "NO_ZLIB", NULL); + } return TCL_ERROR; } @@ -4866,6 +4975,9 @@ TclZipfs_MountBuffer( int copy) { ZIPFS_ERROR(interp, "no zlib available"); + if (interp) { + Tcl_SetErrorCode(interp, "TCL", "ZIPFS", "NO_ZLIB", NULL); + } return TCL_ERROR; } @@ -4875,6 +4987,9 @@ TclZipfs_Unmount( const char *mountPoint) /* Mount point path. */ { ZIPFS_ERROR(interp, "no zlib available"); + if (interp) { + Tcl_SetErrorCode(interp, "TCL", "ZIPFS", "NO_ZLIB", NULL); + } return TCL_ERROR; } #endif /* !HAVE_ZLIB */ -- cgit v0.12 From 3826a26f8a75540c7f3ff0b45f76498e85486dc9 Mon Sep 17 00:00:00 2001 From: dkf Date: Sun, 7 Oct 2018 19:34:52 +0000 Subject: Centralise the de-fanging of standard ensembles in safe interpreters. Doing it right once is easier than repeating hacks... --- generic/tclBasic.c | 158 ++++++++++++++++++++++++++- generic/tclCmdAH.c | 306 ++++++----------------------------------------------- generic/tclCmdIL.c | 2 +- generic/tclInt.h | 2 - generic/tclZipfs.c | 28 ++--- library/safe.tcl | 47 ++++---- tests/info.test | 12 +-- tests/interp.test | 2 +- tests/safe.test | 12 +-- tests/zipfs.test | 36 +++++++ 10 files changed, 269 insertions(+), 336 deletions(-) diff --git a/generic/tclBasic.c b/generic/tclBasic.c index da43a5d..d3ecbf3 100644 --- a/generic/tclBasic.c +++ b/generic/tclBasic.c @@ -105,6 +105,7 @@ TCL_DECLARE_MUTEX(commandTypeLock); * Static functions in this file: */ +static Tcl_ObjCmdProc BadEnsembleSubcommand; static char * CallCommandTraces(Interp *iPtr, Command *cmdPtr, const char *oldName, const char *newName, int flags); @@ -207,6 +208,24 @@ typedef struct { * it for it. Defined in tclInt.h. */ /* + * The following struct states that the command it talks about (a subcommand + * of one of Tcl's built-in ensembles) is unsafe and must be hidden when an + * interpreter is made safe. (TclHideUnsafeCommands accesses an array of these + * structs.) Alas, we can't sensibly just store the information directly in + * the commands. + */ + +typedef struct { + const char *ensembleNsName; /* The ensemble's name within ::tcl. NULL for + * the end of the list of commands to hide. */ + const char *commandName; /* The name of the command within the + * ensemble. If this is NULL, we want to also + * make the overall command be hidden, an ugly + * hack because it is expected by security + * policies in the wild. */ +} UnsafeEnsembleInfo; + +/* * The built-in commands, and the functions that implement them: */ @@ -307,6 +326,69 @@ static const CmdInfo builtInCmds[] = { }; /* + * Information about which pieces of ensembles to hide when making an + * interpreter safe: + */ + +static const UnsafeEnsembleInfo unsafeEnsembleCommands[] = { + /* [encoding] has two unsafe commands. Assumed by older security policies + * to be overall unsafe; it isn't but... */ + {"encoding", NULL}, + {"encoding", "dirs"}, + {"encoding", "system"}, + /* [file] has MANY unsafe commands! Assumed by older security policies to + * be overall unsafe; it isn't but... */ + {"file", NULL}, + {"file", "atime"}, + {"file", "attributes"}, + {"file", "copy"}, + {"file", "delete"}, + {"file", "dirname"}, + {"file", "executable"}, + {"file", "exists"}, + {"file", "extension"}, + {"file", "isdirectory"}, + {"file", "isfile"}, + {"file", "link"}, + {"file", "lstat"}, + {"file", "mtime"}, + {"file", "mkdir"}, + {"file", "nativename"}, + {"file", "normalize"}, + {"file", "owned"}, + {"file", "readable"}, + {"file", "readlink"}, + {"file", "rename"}, + {"file", "rootname"}, + {"file", "size"}, + {"file", "stat"}, + {"file", "tail"}, + {"file", "tempfile"}, + {"file", "type"}, + {"file", "volumes"}, + {"file", "writable"}, + /* [info] has two unsafe commands */ + {"info", "cmdtype"}, + {"info", "nameofexecutable"}, + /* [tcl::process] has ONLY unsafe commands! */ + {"process", "list"}, + {"process", "status"}, + {"process", "purge"}, + {"process", "autopurge"}, + /* [zipfs] has MANY unsafe commands! */ + {"zipfs", "lmkimg"}, + {"zipfs", "lmkzip"}, + {"zipfs", "mkimg"}, + {"zipfs", "mkkey"}, + {"zipfs", "mkzip"}, + {"zipfs", "mount"}, + {"zipfs", "mount_data"}, + {"zipfs", "tcl_library"}, + {"zipfs", "unmount"}, + {NULL, NULL} +}; + +/* * Math functions. All are safe. */ @@ -1135,6 +1217,7 @@ TclHideUnsafeCommands( Tcl_Interp *interp) /* Hide commands in this interpreter. */ { register const CmdInfo *cmdInfoPtr; + register const UnsafeEnsembleInfo *unsafePtr; if (interp == NULL) { return TCL_ERROR; @@ -1144,12 +1227,83 @@ TclHideUnsafeCommands( Tcl_HideCommand(interp, cmdInfoPtr->name, cmdInfoPtr->name); } } - TclMakeEncodingCommandSafe(interp); /* Ugh! */ - TclMakeFileCommandSafe(interp); /* Ugh! */ + + for (unsafePtr = unsafeEnsembleCommands; + unsafePtr->ensembleNsName; unsafePtr++) { + if (unsafePtr->commandName) { + /* + * Hide an ensemble subcommand. + */ + + Tcl_Obj *cmdName = Tcl_ObjPrintf("::tcl::%s::%s", + unsafePtr->ensembleNsName, unsafePtr->commandName); + Tcl_Obj *hideName = Tcl_ObjPrintf("tcl:%s:%s", + unsafePtr->ensembleNsName, unsafePtr->commandName); + + if (TclRenameCommand(interp, TclGetString(cmdName), + "___tmp") != TCL_OK + || Tcl_HideCommand(interp, "___tmp", + TclGetString(hideName)) != TCL_OK) { + Tcl_Panic("problem making '%s %s' safe: %s", + unsafePtr->ensembleNsName, unsafePtr->commandName, + Tcl_GetString(Tcl_GetObjResult(interp))); + } + Tcl_CreateObjCommand(interp, TclGetString(cmdName), + BadEnsembleSubcommand, (ClientData) unsafePtr, NULL); + TclDecrRefCount(cmdName); + TclDecrRefCount(hideName); + } else { + /* + * Hide an ensemble main command (for compatibility). + */ + + if (Tcl_HideCommand(interp, unsafePtr->ensembleNsName, + unsafePtr->ensembleNsName) != TCL_OK) { + Tcl_Panic("problem making '%s' safe: %s", + unsafePtr->ensembleNsName, + Tcl_GetString(Tcl_GetObjResult(interp))); + } + } + } + return TCL_OK; } /* + *---------------------------------------------------------------------- + * + * BadEnsembleSubcommand -- + * + * Command used to act as a backstop implementation when subcommands of + * ensembles are unsafe (the real implementations of the subcommands are + * hidden). The clientData is description of what was hidden. + * + * Results: + * A standard Tcl result (always a TCL_ERROR). + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +static int +BadEnsembleSubcommand( + ClientData clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *const objv[]) +{ + const UnsafeEnsembleInfo *infoPtr = clientData; + + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "not allowed to invoke subcommand %s of %s", + infoPtr->commandName, infoPtr->ensembleNsName)); + Tcl_SetErrorCode(interp, "TCL", "SAFE", "SUBCOMMAND", NULL); + return TCL_ERROR; +} + +/* *-------------------------------------------------------------- * * Tcl_CallWhenDeleted -- diff --git a/generic/tclCmdAH.c b/generic/tclCmdAH.c index 94cb8aa..334121f 100644 --- a/generic/tclCmdAH.c +++ b/generic/tclCmdAH.c @@ -46,9 +46,6 @@ struct ForeachState { static int CheckAccess(Tcl_Interp *interp, Tcl_Obj *pathPtr, int mode); -static int BadEncodingSubcommand(ClientData dummy, - Tcl_Interp *interp, int objc, - Tcl_Obj *const objv[]); static int EncodingConvertfromObjCmd(ClientData dummy, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); @@ -84,7 +81,6 @@ static Tcl_NRPostProc ForPostNextCallback; static Tcl_NRPostProc ForeachLoopStep; static Tcl_NRPostProc EvalCmdErrMsg; -static Tcl_ObjCmdProc BadFileSubcommand; static Tcl_ObjCmdProc FileAttrAccessTimeCmd; static Tcl_ObjCmdProc FileAttrIsDirectoryCmd; static Tcl_ObjCmdProc FileAttrIsExecutableCmd; @@ -536,9 +532,9 @@ TclInitEncodingCmd( static const EnsembleImplMap encodingImplMap[] = { {"convertfrom", EncodingConvertfromObjCmd, TclCompileBasic1Or2ArgCmd, NULL, NULL, 0}, {"convertto", EncodingConverttoObjCmd, TclCompileBasic1Or2ArgCmd, NULL, NULL, 0}, - {"dirs", EncodingDirsObjCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0}, + {"dirs", EncodingDirsObjCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 1}, {"names", EncodingNamesObjCmd, TclCompileBasic0ArgCmd, NULL, NULL, 0}, - {"system", EncodingSystemObjCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0}, + {"system", EncodingSystemObjCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 1}, {NULL, NULL, NULL, NULL, NULL, 0} }; @@ -546,113 +542,6 @@ TclInitEncodingCmd( } /* - *----------------------------------------------------------------------------- - * - * TclMakeEncodingCommandSafe -- - * - * This function hides the unsafe 'dirs' and 'system' subcommands of - * the "encoding" Tcl command ensemble. It must be called only from - * TclHideUnsafeCommands. - * - * Results: - * A standard Tcl result - * - * Side effects: - * Adds commands to the table of hidden commands. - * - *----------------------------------------------------------------------------- - */ - -int -TclMakeEncodingCommandSafe( - Tcl_Interp* interp) /* Tcl interpreter */ -{ - static const struct { - const char *cmdName; - int unsafe; - } unsafeInfo[] = { - {"convertfrom", 0}, - {"convertto", 0}, - {"dirs", 1}, - {"names", 0}, - {"system", 0}, - {NULL, 0} - }; - - int i; - Tcl_DString oldBuf, newBuf; - - Tcl_DStringInit(&oldBuf); - TclDStringAppendLiteral(&oldBuf, "::tcl::encoding::"); - Tcl_DStringInit(&newBuf); - TclDStringAppendLiteral(&newBuf, "tcl:encoding:"); - for (i=0 ; unsafeInfo[i].cmdName != NULL ; i++) { - if (unsafeInfo[i].unsafe) { - const char *oldName, *newName; - - Tcl_DStringSetLength(&oldBuf, 17); - oldName = Tcl_DStringAppend(&oldBuf, unsafeInfo[i].cmdName, -1); - Tcl_DStringSetLength(&newBuf, 13); - newName = Tcl_DStringAppend(&newBuf, unsafeInfo[i].cmdName, -1); - if (TclRenameCommand(interp, oldName, "___tmp") != TCL_OK - || Tcl_HideCommand(interp, "___tmp", newName) != TCL_OK) { - Tcl_Panic("problem making 'encoding %s' safe: %s", - unsafeInfo[i].cmdName, - Tcl_GetString(Tcl_GetObjResult(interp))); - } - Tcl_CreateObjCommand(interp, oldName, BadEncodingSubcommand, - (ClientData) unsafeInfo[i].cmdName, NULL); - } - } - Tcl_DStringFree(&oldBuf); - Tcl_DStringFree(&newBuf); - - /* - * Ugh. The [encoding] command is now actually safe, but it is assumed by - * scripts that it is not, which messes up security policies. - */ - - if (Tcl_HideCommand(interp, "encoding", "encoding") != TCL_OK) { - Tcl_Panic("problem making 'encoding' safe: %s", - Tcl_GetString(Tcl_GetObjResult(interp))); - } - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * BadEncodingSubcommand -- - * - * Command used to act as a backstop implementation when subcommands of - * "encoding" are unsafe (the real implementations of the subcommands are - * hidden). The clientData is always the full official subcommand name. - * - * Results: - * A standard Tcl result (always a TCL_ERROR). - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -static int -BadEncodingSubcommand( - ClientData clientData, - Tcl_Interp *interp, - int objc, - Tcl_Obj *const objv[]) -{ - const char *subcommandName = (const char *) clientData; - - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "not allowed to invoke subcommand %s of encoding", subcommandName)); - Tcl_SetErrorCode(interp, "TCL", "SAFE", "SUBCOMMAND", NULL); - return TCL_ERROR; -} - -/* *---------------------------------------------------------------------- * * EncodingConvertfromObjCmd -- @@ -1174,40 +1063,40 @@ TclInitFileCmd( */ static const EnsembleImplMap initMap[] = { - {"atime", FileAttrAccessTimeCmd, TclCompileBasic1Or2ArgCmd, NULL, NULL, 0}, - {"attributes", TclFileAttrsCmd, NULL, NULL, NULL, 0}, + {"atime", FileAttrAccessTimeCmd, TclCompileBasic1Or2ArgCmd, NULL, NULL, 1}, + {"attributes", TclFileAttrsCmd, NULL, NULL, NULL, 1}, {"channels", TclChannelNamesCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0}, - {"copy", TclFileCopyCmd, NULL, NULL, NULL, 0}, - {"delete", TclFileDeleteCmd, TclCompileBasicMin0ArgCmd, NULL, NULL, 0}, - {"dirname", PathDirNameCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0}, - {"executable", FileAttrIsExecutableCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0}, - {"exists", FileAttrIsExistingCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0}, - {"extension", PathExtensionCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0}, - {"isdirectory", FileAttrIsDirectoryCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0}, - {"isfile", FileAttrIsFileCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0}, + {"copy", TclFileCopyCmd, NULL, NULL, NULL, 1}, + {"delete", TclFileDeleteCmd, TclCompileBasicMin0ArgCmd, NULL, NULL, 1}, + {"dirname", PathDirNameCmd, TclCompileBasic1ArgCmd, NULL, NULL, 1}, + {"executable", FileAttrIsExecutableCmd, TclCompileBasic1ArgCmd, NULL, NULL, 1}, + {"exists", FileAttrIsExistingCmd, TclCompileBasic1ArgCmd, NULL, NULL, 1}, + {"extension", PathExtensionCmd, TclCompileBasic1ArgCmd, NULL, NULL, 1}, + {"isdirectory", FileAttrIsDirectoryCmd, TclCompileBasic1ArgCmd, NULL, NULL, 1}, + {"isfile", FileAttrIsFileCmd, TclCompileBasic1ArgCmd, NULL, NULL, 1}, {"join", PathJoinCmd, TclCompileBasicMin1ArgCmd, NULL, NULL, 0}, - {"link", TclFileLinkCmd, TclCompileBasic1To3ArgCmd, NULL, NULL, 0}, - {"lstat", FileAttrLinkStatCmd, TclCompileBasic2ArgCmd, NULL, NULL, 0}, - {"mtime", FileAttrModifyTimeCmd, TclCompileBasic1Or2ArgCmd, NULL, NULL, 0}, - {"mkdir", TclFileMakeDirsCmd, TclCompileBasicMin0ArgCmd, NULL, NULL, 0}, - {"nativename", PathNativeNameCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0}, - {"normalize", PathNormalizeCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0}, - {"owned", FileAttrIsOwnedCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0}, + {"link", TclFileLinkCmd, TclCompileBasic1To3ArgCmd, NULL, NULL, 1}, + {"lstat", FileAttrLinkStatCmd, TclCompileBasic2ArgCmd, NULL, NULL, 1}, + {"mtime", FileAttrModifyTimeCmd, TclCompileBasic1Or2ArgCmd, NULL, NULL, 1}, + {"mkdir", TclFileMakeDirsCmd, TclCompileBasicMin0ArgCmd, NULL, NULL, 1}, + {"nativename", PathNativeNameCmd, TclCompileBasic1ArgCmd, NULL, NULL, 1}, + {"normalize", PathNormalizeCmd, TclCompileBasic1ArgCmd, NULL, NULL, 1}, + {"owned", FileAttrIsOwnedCmd, TclCompileBasic1ArgCmd, NULL, NULL, 1}, {"pathtype", PathTypeCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0}, - {"readable", FileAttrIsReadableCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0}, - {"readlink", TclFileReadLinkCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0}, - {"rename", TclFileRenameCmd, NULL, NULL, NULL, 0}, - {"rootname", PathRootNameCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0}, + {"readable", FileAttrIsReadableCmd, TclCompileBasic1ArgCmd, NULL, NULL, 1}, + {"readlink", TclFileReadLinkCmd, TclCompileBasic1ArgCmd, NULL, NULL, 1}, + {"rename", TclFileRenameCmd, NULL, NULL, NULL, 1}, + {"rootname", PathRootNameCmd, TclCompileBasic1ArgCmd, NULL, NULL, 1}, {"separator", FilesystemSeparatorCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0}, - {"size", FileAttrSizeCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0}, + {"size", FileAttrSizeCmd, TclCompileBasic1ArgCmd, NULL, NULL, 1}, {"split", PathSplitCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0}, - {"stat", FileAttrStatCmd, TclCompileBasic2ArgCmd, NULL, NULL, 0}, + {"stat", FileAttrStatCmd, TclCompileBasic2ArgCmd, NULL, NULL, 1}, {"system", PathFilesystemCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0}, - {"tail", PathTailCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0}, - {"tempfile", TclFileTemporaryCmd, TclCompileBasic0To2ArgCmd, NULL, NULL, 0}, - {"type", FileAttrTypeCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0}, - {"volumes", FilesystemVolumesCmd, TclCompileBasic0ArgCmd, NULL, NULL, 0}, - {"writable", FileAttrIsWritableCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0}, + {"tail", PathTailCmd, TclCompileBasic1ArgCmd, NULL, NULL, 1}, + {"tempfile", TclFileTemporaryCmd, TclCompileBasic0To2ArgCmd, NULL, NULL, 1}, + {"type", FileAttrTypeCmd, TclCompileBasic1ArgCmd, NULL, NULL, 1}, + {"volumes", FilesystemVolumesCmd, TclCompileBasic0ArgCmd, NULL, NULL, 1}, + {"writable", FileAttrIsWritableCmd, TclCompileBasic1ArgCmd, NULL, NULL, 1}, {NULL, NULL, NULL, NULL, NULL, 0} }; return TclMakeEnsemble(interp, "file", initMap); @@ -1216,141 +1105,6 @@ TclInitFileCmd( /* *---------------------------------------------------------------------- * - * TclMakeFileCommandSafe -- - * - * This function hides the unsafe subcommands of the "file" Tcl command - * ensemble. It must only be called from TclHideUnsafeCommands. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * Adds commands to the table of hidden commands. - * - *---------------------------------------------------------------------- - */ - -int -TclMakeFileCommandSafe( - Tcl_Interp *interp) -{ - static const struct { - const char *cmdName; - int unsafe; - } unsafeInfo[] = { - {"atime", 1}, - {"attributes", 1}, - {"channels", 0}, - {"copy", 1}, - {"delete", 1}, - {"dirname", 1}, - {"executable", 1}, - {"exists", 1}, - {"extension", 1}, - {"isdirectory", 1}, - {"isfile", 1}, - {"join", 0}, - {"link", 1}, - {"lstat", 1}, - {"mtime", 1}, - {"mkdir", 1}, - {"nativename", 1}, - {"normalize", 1}, - {"owned", 1}, - {"pathtype", 0}, - {"readable", 1}, - {"readlink", 1}, - {"rename", 1}, - {"rootname", 1}, - {"separator", 0}, - {"size", 1}, - {"split", 0}, - {"stat", 1}, - {"system", 0}, - {"tail", 1}, - {"tempfile", 1}, - {"type", 1}, - {"volumes", 1}, - {"writable", 1}, - {NULL, 0} - }; - int i; - Tcl_DString oldBuf, newBuf; - - Tcl_DStringInit(&oldBuf); - TclDStringAppendLiteral(&oldBuf, "::tcl::file::"); - Tcl_DStringInit(&newBuf); - TclDStringAppendLiteral(&newBuf, "tcl:file:"); - for (i=0 ; unsafeInfo[i].cmdName != NULL ; i++) { - if (unsafeInfo[i].unsafe) { - const char *oldName, *newName; - - Tcl_DStringSetLength(&oldBuf, 13); - oldName = Tcl_DStringAppend(&oldBuf, unsafeInfo[i].cmdName, -1); - Tcl_DStringSetLength(&newBuf, 9); - newName = Tcl_DStringAppend(&newBuf, unsafeInfo[i].cmdName, -1); - if (TclRenameCommand(interp, oldName, "___tmp") != TCL_OK - || Tcl_HideCommand(interp, "___tmp", newName) != TCL_OK) { - Tcl_Panic("problem making 'file %s' safe: %s", - unsafeInfo[i].cmdName, - Tcl_GetString(Tcl_GetObjResult(interp))); - } - Tcl_CreateObjCommand(interp, oldName, BadFileSubcommand, - (ClientData) unsafeInfo[i].cmdName, NULL); - } - } - Tcl_DStringFree(&oldBuf); - Tcl_DStringFree(&newBuf); - - /* - * Ugh. The [file] command is now actually safe, but it is assumed by - * scripts that it is not, which messes up security policies. [Bug - * 3211758] - */ - - if (Tcl_HideCommand(interp, "file", "file") != TCL_OK) { - Tcl_Panic("problem making 'file' safe: %s", - Tcl_GetString(Tcl_GetObjResult(interp))); - } - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * BadFileSubcommand -- - * - * Command used to act as a backstop implementation when subcommands of - * "file" are unsafe (the real implementations of the subcommands are - * hidden). The clientData is always the full official subcommand name. - * - * Results: - * A standard Tcl result (always a TCL_ERROR). - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -static int -BadFileSubcommand( - ClientData clientData, - Tcl_Interp *interp, - int objc, - Tcl_Obj *const objv[]) -{ - const char *subcommandName = (const char *) clientData; - - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "not allowed to invoke subcommand %s of file", subcommandName)); - Tcl_SetErrorCode(interp, "TCL", "SAFE", "SUBCOMMAND", NULL); - return TCL_ERROR; -} - -/* - *---------------------------------------------------------------------- - * * FileAttrAccessTimeCmd -- * * This function is invoked to process the "file atime" Tcl command. See diff --git a/generic/tclCmdIL.c b/generic/tclCmdIL.c index 1dae740..434840e 100644 --- a/generic/tclCmdIL.c +++ b/generic/tclCmdIL.c @@ -173,7 +173,7 @@ static const EnsembleImplMap defaultInfoMap[] = { {"library", InfoLibraryCmd, TclCompileBasic0ArgCmd, NULL, NULL, 0}, {"loaded", InfoLoadedCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0}, {"locals", TclInfoLocalsCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0}, - {"nameofexecutable", InfoNameOfExecutableCmd, TclCompileBasic0ArgCmd, NULL, NULL, 0}, + {"nameofexecutable", InfoNameOfExecutableCmd, TclCompileBasic0ArgCmd, NULL, NULL, 1}, {"patchlevel", InfoPatchLevelCmd, TclCompileBasic0ArgCmd, NULL, NULL, 0}, {"procs", InfoProcsCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0}, {"script", InfoScriptCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0}, diff --git a/generic/tclInt.h b/generic/tclInt.h index 4a1b459..8ef0218 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -3360,7 +3360,6 @@ MODULE_SCOPE int TclNRAssembleObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); MODULE_SCOPE Tcl_Command TclInitEncodingCmd(Tcl_Interp *interp); -MODULE_SCOPE int TclMakeEncodingCommandSafe(Tcl_Interp *interp); MODULE_SCOPE int Tcl_EofObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); @@ -3389,7 +3388,6 @@ MODULE_SCOPE int Tcl_FcopyObjCmd(ClientData dummy, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); MODULE_SCOPE Tcl_Command TclInitFileCmd(Tcl_Interp *interp); -MODULE_SCOPE int TclMakeFileCommandSafe(Tcl_Interp *interp); MODULE_SCOPE int Tcl_FileEventObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c index ea6d5ad..ff04971 100644 --- a/generic/tclZipfs.c +++ b/generic/tclZipfs.c @@ -4713,21 +4713,21 @@ TclZipfs_Init( { #ifdef HAVE_ZLIB static const EnsembleImplMap initMap[] = { - {"mkimg", ZipFSMkImgObjCmd, NULL, NULL, NULL, 0}, - {"mkzip", ZipFSMkZipObjCmd, NULL, NULL, NULL, 0}, - {"lmkimg", ZipFSLMkImgObjCmd, NULL, NULL, NULL, 0}, - {"lmkzip", ZipFSLMkZipObjCmd, NULL, NULL, NULL, 0}, + {"mkimg", ZipFSMkImgObjCmd, NULL, NULL, NULL, 1}, + {"mkzip", ZipFSMkZipObjCmd, NULL, NULL, NULL, 1}, + {"lmkimg", ZipFSLMkImgObjCmd, NULL, NULL, NULL, 1}, + {"lmkzip", ZipFSLMkZipObjCmd, NULL, NULL, NULL, 1}, /* The 4 entries above are not available in safe interpreters */ - {"mount", ZipFSMountObjCmd, NULL, NULL, NULL, 0}, - {"mount_data", ZipFSMountBufferObjCmd, NULL, NULL, NULL, 0}, - {"unmount", ZipFSUnmountObjCmd, NULL, NULL, NULL, 0}, - {"mkkey", ZipFSMkKeyObjCmd, NULL, NULL, NULL, 0}, - {"exists", ZipFSExistsObjCmd, NULL, NULL, NULL, 1}, - {"info", ZipFSInfoObjCmd, NULL, NULL, NULL, 1}, - {"list", ZipFSListObjCmd, NULL, NULL, NULL, 1}, - {"canonical", ZipFSCanonicalObjCmd, NULL, NULL, NULL, 1}, - {"root", ZipFSRootObjCmd, NULL, NULL, NULL, 1}, - {"tcl_library", ZipFSTclLibraryObjCmd, NULL, NULL, NULL, 0}, + {"mount", ZipFSMountObjCmd, NULL, NULL, NULL, 1}, + {"mount_data", ZipFSMountBufferObjCmd, NULL, NULL, NULL, 1}, + {"unmount", ZipFSUnmountObjCmd, NULL, NULL, NULL, 1}, + {"mkkey", ZipFSMkKeyObjCmd, NULL, NULL, NULL, 1}, + {"exists", ZipFSExistsObjCmd, NULL, NULL, NULL, 0}, + {"info", ZipFSInfoObjCmd, NULL, NULL, NULL, 0}, + {"list", ZipFSListObjCmd, NULL, NULL, NULL, 0}, + {"canonical", ZipFSCanonicalObjCmd, NULL, NULL, NULL, 0}, + {"root", ZipFSRootObjCmd, NULL, NULL, NULL, 0}, + {"tcl_library", ZipFSTclLibraryObjCmd, NULL, NULL, NULL, 1}, {NULL, NULL, NULL, NULL, NULL, 0} }; static const char findproc[] = diff --git a/library/safe.tcl b/library/safe.tcl index ea6391d..7b165d2 100644 --- a/library/safe.tcl +++ b/library/safe.tcl @@ -455,37 +455,35 @@ proc ::safe::InterpInit { foreach {command alias} { source AliasSource load AliasLoad - encoding AliasEncoding exit interpDelete glob AliasGlob } { ::interp alias $slave $command {} [namespace current]::$alias $slave } + # UGLY POINT! These commands are safe (they're ensembles with unsafe + # subcommands), but is assumed to not be by existing policies so it is + # hidden by default. Hack it... + foreach command {encoding file} { + ::interp alias $slave $command {} interp invokehidden $slave $command + } + # This alias lets the slave have access to a subset of the 'file' # command functionality. - ::interp expose $slave file foreach subcommand {dirname extension rootname tail} { ::interp alias $slave ::tcl::file::$subcommand {} \ ::safe::AliasFileSubcommand $slave $subcommand } - foreach subcommand { - atime attributes copy delete executable exists isdirectory isfile - link lstat mtime mkdir nativename normalize owned readable readlink - rename size stat tempfile type volumes writable - } { - ::interp alias $slave ::tcl::file::$subcommand {} \ - ::safe::BadSubcommand $slave file $subcommand - } + + # Subcommand of 'encoding' that has special handling; [encoding system] is + # OK provided it has no other arguments passed to it. + ::interp alias $slave ::tcl::encoding::system {} \ + ::safe::AliasEncodingSystem $slave # Subcommands of info - foreach {subcommand alias} { - nameofexecutable AliasExeName - } { - ::interp alias $slave ::tcl::info::$subcommand \ - {} [namespace current]::$alias $slave - } + ::interp alias $slave ::tcl::info::nameofexecutable {} \ + ::safe::AliasExeName $slave # The allowed slave variables already have been set by Tcl_MakeSafe(3) @@ -1027,16 +1025,13 @@ proc ::safe::BadSubcommand {slave command subcommand args} { return -code error -errorcode {TCL SAFE SUBCOMMAND} $msg } -# AliasEncoding is the target of the "encoding" alias in safe interpreters. - -proc ::safe::AliasEncoding {slave option args} { - # Note that [encoding dirs] is not supported in safe slaves at all - set subcommands {convertfrom convertto names system} +# AliasEncodingSystem is the target of the "encoding system" alias in safe +# interpreters. +proc ::safe::AliasEncodingSystem {slave args} { try { - set option [tcl::prefix match -error [list -level 1 -errorcode \ - [list TCL LOOKUP INDEX option $option]] $subcommands $option] - # Special case: [encoding system] ok, but [encoding system foo] not - if {$option eq "system" && [llength $args]} { + # Must not pass extra arguments; safe slaves may not set the system + # encoding but they may read it. + if {[llength $args]} { return -code error -errorcode {TCL WRONGARGS} \ "wrong # args: should be \"encoding system\"" } @@ -1044,7 +1039,7 @@ proc ::safe::AliasEncoding {slave option args} { Log $slave $msg return -options $options $msg } - tailcall ::interp invokehidden $slave encoding $option {*}$args + tailcall ::interp invokehidden $slave tcl:encoding:system } # Various minor hiding of platform features. [Bug 2913625] diff --git a/tests/info.test b/tests/info.test index 0de1510..a12d45c 100644 --- a/tests/info.test +++ b/tests/info.test @@ -2535,9 +2535,9 @@ test info-40.18 {info cmdtype: aliases in slave interpreters} -setup { $safe eval { info cmdtype foo } -} -cleanup { +} -returnCodes error -cleanup { interp delete $safe -} -result native +} -result {not allowed to invoke subcommand cmdtype of info} test info-40.19 {info cmdtype: aliases in slave interpreters} -setup { set safe [interp create -safe] } -body { @@ -2548,9 +2548,9 @@ test info-40.19 {info cmdtype: aliases in slave interpreters} -setup { info cmdtype foo } } -} -cleanup { +} -returnCodes error -cleanup { interp delete $safe -} -result native +} -result {not allowed to invoke subcommand cmdtype of info} test info-40.20 {info cmdtype: aliases in slave interpreters} -setup { set safe [interp create -safe] } -body { @@ -2558,9 +2558,9 @@ test info-40.20 {info cmdtype: aliases in slave interpreters} -setup { interp alias {} foo {} gorp info cmdtype foo } -} -cleanup { +} -returnCodes error -cleanup { interp delete $safe -} -result alias +} -result {not allowed to invoke subcommand cmdtype of info} namespace delete ::testinfocmdtype # ------------------------------------------------------------------------- diff --git a/tests/interp.test b/tests/interp.test index 4ea04e3..e9f95d7 100644 --- a/tests/interp.test +++ b/tests/interp.test @@ -20,7 +20,7 @@ catch [list package require -exact Tcltest [info patchlevel]] testConstraint testinterpdelete [llength [info commands testinterpdelete]] -set hidden_cmds {cd encoding exec exit fconfigure file glob load open pwd socket source tcl:encoding:dirs tcl:file:atime tcl:file:attributes tcl:file:copy tcl:file:delete tcl:file:dirname tcl:file:executable tcl:file:exists tcl:file:extension tcl:file:isdirectory tcl:file:isfile tcl:file:link tcl:file:lstat tcl:file:mkdir tcl:file:mtime tcl:file:nativename tcl:file:normalize tcl:file:owned tcl:file:readable tcl:file:readlink tcl:file:rename tcl:file:rootname tcl:file:size tcl:file:stat tcl:file:tail tcl:file:tempfile tcl:file:type tcl:file:volumes tcl:file:writable unload} +set hidden_cmds {cd encoding exec exit fconfigure file glob load open pwd socket source tcl:encoding:dirs tcl:encoding:system tcl:file:atime tcl:file:attributes tcl:file:copy tcl:file:delete tcl:file:dirname tcl:file:executable tcl:file:exists tcl:file:extension tcl:file:isdirectory tcl:file:isfile tcl:file:link tcl:file:lstat tcl:file:mkdir tcl:file:mtime tcl:file:nativename tcl:file:normalize tcl:file:owned tcl:file:readable tcl:file:readlink tcl:file:rename tcl:file:rootname tcl:file:size tcl:file:stat tcl:file:tail tcl:file:tempfile tcl:file:type tcl:file:volumes tcl:file:writable tcl:info:cmdtype tcl:info:nameofexecutable tcl:process:autopurge tcl:process:list tcl:process:purge tcl:process:status tcl:zipfs:lmkimg tcl:zipfs:lmkzip tcl:zipfs:mkimg tcl:zipfs:mkkey tcl:zipfs:mkzip tcl:zipfs:mount tcl:zipfs:mount_data tcl:zipfs:tcl_library tcl:zipfs:unmount unload} foreach i [interp slaves] { interp delete $i diff --git a/tests/safe.test b/tests/safe.test index 217507e..356e176 100644 --- a/tests/safe.test +++ b/tests/safe.test @@ -92,7 +92,7 @@ test safe-3.2 {calling safe::interpCreate on trusted interp} -setup { lsort [a aliases] } -cleanup { safe::interpDelete a -} -result {::tcl::file::atime ::tcl::file::attributes ::tcl::file::copy ::tcl::file::delete ::tcl::file::dirname ::tcl::file::executable ::tcl::file::exists ::tcl::file::extension ::tcl::file::isdirectory ::tcl::file::isfile ::tcl::file::link ::tcl::file::lstat ::tcl::file::mkdir ::tcl::file::mtime ::tcl::file::nativename ::tcl::file::normalize ::tcl::file::owned ::tcl::file::readable ::tcl::file::readlink ::tcl::file::rename ::tcl::file::rootname ::tcl::file::size ::tcl::file::stat ::tcl::file::tail ::tcl::file::tempfile ::tcl::file::type ::tcl::file::volumes ::tcl::file::writable ::tcl::info::nameofexecutable clock encoding exit glob load source} +} -result {::tcl::encoding::system ::tcl::file::dirname ::tcl::file::extension ::tcl::file::rootname ::tcl::file::tail ::tcl::info::nameofexecutable clock encoding exit file glob load source} test safe-3.3 {calling safe::interpCreate on trusted interp} -setup { catch {safe::interpDelete a} } -body { @@ -464,14 +464,14 @@ test safe-11.1 {testing safe encoding} -setup { interp eval $i encoding } -returnCodes error -cleanup { safe::interpDelete $i -} -result {wrong # args: should be "encoding option ?arg ...?"} +} -result {wrong # args: should be "encoding subcommand ?arg ...?"} test safe-11.1a {testing safe encoding} -setup { set i [safe::interpCreate] } -body { interp eval $i encoding foobar } -returnCodes error -cleanup { safe::interpDelete $i -} -match glob -result {bad option "foobar": must be *} +} -match glob -result {unknown or ambiguous subcommand "foobar": must be *} test safe-11.2 {testing safe encoding} -setup { set i [safe::interpCreate] } -body { @@ -526,8 +526,6 @@ test safe-11.7.1 {testing safe encoding} -setup { while executing "encoding convertfrom" invoked from within -"::interp invokehidden interp* encoding convertfrom" - invoked from within "encoding convertfrom" invoked from within "interp eval $i encoding convertfrom"} @@ -550,8 +548,6 @@ test safe-11.8.1 {testing safe encoding} -setup { while executing "encoding convertto" invoked from within -"::interp invokehidden interp* encoding convertto" - invoked from within "encoding convertto" invoked from within "interp eval $i encoding convertto"} @@ -765,7 +761,7 @@ test safe-15.1 {safe file ensemble does not surprise code} -setup { unset -nocomplain msg interp delete $i } -result {1 {a b c} 1 {a b c} 1 {invalid command name "file"} 1 0 {a b c} 1 {not allowed to invoke subcommand isdirectory of file}} -test safe-15.1.1 {safe file ensemble does not surprise code} -setup { +test safe-15.2 {safe file ensemble does not surprise code} -setup { set i [interp create -safe] } -body { set result [expr {"file" in [interp hidden $i]}] diff --git a/tests/zipfs.test b/tests/zipfs.test index 9d60f8d..631b525 100644 --- a/tests/zipfs.test +++ b/tests/zipfs.test @@ -239,6 +239,42 @@ test zipfs-2.13 {zipfs unmount} -constraints {zipfs zipfsencbuf} -body { catch {file delete -force $tmpdir} +test zipfs-3.1 {zipfs in child interpreters} -constraints zipfs -setup { + set interp [interp create] +} -body { + interp eval $interp { + zipfs ? + } +} -returnCodes error -cleanup { + interp delete $interp +} -result {unknown or ambiguous subcommand "?": must be canonical, exists, info, list, lmkimg, lmkzip, mkimg, mkkey, mkzip, mount, mount_data, root, tcl_library, or unmount} +test zipfs-3.2 {zipfs in child interpreters} -constraints zipfs -setup { + set interp [interp create] +} -body { + interp eval $interp { + zipfs mkzip + } +} -returnCodes error -cleanup { + interp delete $interp +} -result {wrong # args: should be "zipfs mkzip outfile indir ?strip? ?password?"} +test zipfs-3.3 {zipfs in child interpreters} -constraints zipfs -setup { + set safe [interp create -safe] +} -body { + interp eval $safe { + zipfs ? + } +} -returnCodes error -cleanup { + interp delete $safe +} -result {unknown or ambiguous subcommand "?": must be canonical, exists, info, list, lmkimg, lmkzip, mkimg, mkkey, mkzip, mount, mount_data, root, tcl_library, or unmount} +test zipfs-3.4 {zipfs in child interpreters} -constraints zipfs -setup { + set safe [interp create -safe] +} -body { + interp eval $safe { + zipfs mkzip + } +} -returnCodes error -cleanup { + interp delete $safe +} -result {not allowed to invoke subcommand mkzip of zipfs} ::tcltest::cleanupTests return -- cgit v0.12 From cc4dae5c0f418d304a44bb10c87c624b478b6441 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Sun, 7 Oct 2018 20:26:33 +0000 Subject: Streamline: Tcl_WinTCharToUtf/Tcl_WinUtfToTChar(): Always initialize DString, and let it return NULL when imput is NULL. That's what seem to assume the callers. --- generic/tclStubInit.c | 14 ++++++++++---- win/tclWin32Dll.c | 14 ++++++++++---- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/generic/tclStubInit.c b/generic/tclStubInit.c index 50bb4a2..cbf4084 100644 --- a/generic/tclStubInit.c +++ b/generic/tclStubInit.c @@ -189,6 +189,9 @@ Tcl_WinUtfToTChar( Tcl_DString *dsPtr) { Tcl_DStringInit(dsPtr); + if (!string) { + return NULL; + } return (char *)Tcl_UtfToUniCharDString(string, len, dsPtr); } @@ -198,12 +201,15 @@ Tcl_WinTCharToUtf( int len, Tcl_DString *dsPtr) { - if (len > 0) { - len /= 2; - } else if (len == -1) { + Tcl_DStringInit(dsPtr); + if (!string) { + return NULL; + } + if (len < 0) { len = wcslen((wchar_t *)string); + } else { + len /= 2; } - Tcl_DStringInit(dsPtr); return Tcl_UniCharToUtfDString((Tcl_UniChar *)string, len, dsPtr); } diff --git a/win/tclWin32Dll.c b/win/tclWin32Dll.c index ca1c856..6fc2401 100644 --- a/win/tclWin32Dll.c +++ b/win/tclWin32Dll.c @@ -548,6 +548,9 @@ Tcl_WinUtfToTChar( * converted string is stored. */ { Tcl_DStringInit(dsPtr); + if (!string) { + return NULL; + } return Tcl_UtfToUniCharDString(string, len, dsPtr); } @@ -559,12 +562,15 @@ Tcl_WinTCharToUtf( Tcl_DString *dsPtr) /* Uninitialized or free DString in which the * converted string is stored. */ { - if (len > 0) { - len /= 2; - } else if (len < 0) { + Tcl_DStringInit(dsPtr); + if (!string) { + return NULL; + } + if (len < 0) { len = wcslen(string); + } else { + len /= 2; } - Tcl_DStringInit(dsPtr); return Tcl_UniCharToUtfDString(string, len, dsPtr); } -- cgit v0.12 From 4b7747b505d177db96c71d43bae93c77f303c568 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Mon, 8 Oct 2018 20:47:26 +0000 Subject: Fix MSVC warning: warning C4146: unary minus operator applied to unsigned type, result still unsigned (hopefully) --- generic/tclObj.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generic/tclObj.c b/generic/tclObj.c index a704b52..01a7498 100644 --- a/generic/tclObj.c +++ b/generic/tclObj.c @@ -3087,7 +3087,7 @@ Tcl_GetWideIntFromObj( value = (value << CHAR_BIT) | *bytes++; } if (big.sign) { - if (value <= -(Tcl_WideUInt)WIDE_MIN) { + if (value <= 1 + ~(Tcl_WideUInt)WIDE_MIN) { *wideIntPtr = - (Tcl_WideInt) value; return TCL_OK; } -- cgit v0.12 From c9301353fc0ecd289ea6bf809c50bbbae9dd3545 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Mon, 8 Oct 2018 22:32:08 +0000 Subject: Tcl_GetStringFromObj -> Tcl_GetString --- generic/tclZipfs.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c index 829b5d2..d8a3f84 100644 --- a/generic/tclZipfs.c +++ b/generic/tclZipfs.c @@ -2974,7 +2974,7 @@ ZipFSExistsObjCmd( * Prepend ZIPFS_VOLUME to filename, eliding the final / */ - filename = Tcl_GetStringFromObj(objv[1], 0); + filename = Tcl_GetString(objv[1]); Tcl_DStringInit(&ds); Tcl_DStringAppend(&ds, ZIPFS_VOLUME, ZIPFS_VOLUME_LEN - 1); Tcl_DStringAppend(&ds, filename, -1); @@ -3021,7 +3021,7 @@ ZipFSInfoObjCmd( Tcl_WrongNumArgs(interp, 1, objv, "filename"); return TCL_ERROR; } - filename = Tcl_GetStringFromObj(objv[1], 0); + filename = Tcl_GetString(objv[1]); ReadLock(); z = ZipFSLookup(filename); if (z) { @@ -3092,7 +3092,7 @@ ZipFSListObjCmd( return TCL_ERROR; } } else if (objc == 2) { - pattern = Tcl_GetStringFromObj(objv[1], 0); + pattern = Tcl_GetString(objv[1]); } ReadLock(); if (pattern) { -- cgit v0.12 From 77282aad9667ef12c78a6a040b17dbd6d27681c6 Mon Sep 17 00:00:00 2001 From: dkf Date: Tue, 9 Oct 2018 08:21:32 +0000 Subject: Improve documentation of [tcl::process] --- doc/process.n | 89 ++++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 54 insertions(+), 35 deletions(-) diff --git a/doc/process.n b/doc/process.n index 536b98b..165e413 100644 --- a/doc/process.n +++ b/doc/process.n @@ -16,11 +16,31 @@ tcl::process \- Subprocess management .SH DESCRIPTION .PP This command provides a way to manage subprocesses created by the \fBopen\fR -and \fBexec\fR commands. The legal \fIoptions\fR (which may be abbreviated) are: +and \fBexec\fR commands, as identified by the process identifiers (PIDs) of +those subprocesses. The legal \fIoptions\fR (which may be abbreviated) are: +.TP +\fB::tcl::process autopurge\fR ?\fIflag\fR? +. +Automatic purge facility. If \fIflag\fR is specified as a boolean value then +it activates or deactivate autopurge. In all cases it returns the current +status as a boolean value. When autopurge is active, +\fBTcl_ReapDetachedProcs\fR is called each time the \fBexec\fR command is +executed or a pipe channel created by \fBopen\fR is closed. When autopurge is +inactive, \fB::tcl::process\fR purge must be called explicitly. By default +autopurge is active. .TP \fB::tcl::process list\fR . -Returns the list of subprocess PIDs. +Returns the list of subprocess PIDs. This includes all currently executing +subprocesses and all terminated subprocesses that have not yet had their +corresponding process table entries purged. +.TP +\fB::tcl::process purge\fR ?\fIpids\fR? +. +Cleans up all data associated with terminated subprocesses. If \fIpids\fR is +specified as a list of PIDs then the command only cleanup data for the matching +subprocesses if they exist, and raises an error otherwise. If a process listed is +still active, this command does nothing to that process. .TP \fB::tcl::process status\fR ?\fIswitches\fR? ?\fIpids\fR? . @@ -29,62 +49,48 @@ Returns a dictionary mapping subprocess PIDs to their respective status. If status of the matching subprocesses if they exist, and raises an error otherwise. For active processes, the status is an empty value. For terminated processes, the status is a list with the following format: -.QW "{code ?\fImsg errorCode\fR?}" , +.QW "\fB{\fIcode\fR ?\fImsg errorCode\fR?\fB}\fR" , where: .RS .TP -\fBcode\fR\0 +\fIcode\fR\0 . -is a standard Tcl return code, +is a standard Tcl return code, i.e., \fB0\fR for TCL_OK and \fB1\fR +for TCL_ERROR, .TP -\fBmsg\fR\0 +\fImsg\fR\0 . is the human-readable error message, .TP -\fBerrorCode\fR\0 +\fIerrorCode\fR\0 . uses the same format as the \fBerrorCode\fR global variable -.RE +.PP Note that \fBmsg\fR and \fBerrorCode\fR are only present for abnormally -terminated processes (i.e. those where \fBcode\fR is nonzero). Under the hood -this command calls \fBTcl_WaitPid\fR with the \fBWNOHANG\fR flag set for +terminated processes (i.e. those where the \fIcode\fR is nonzero). Under the +hood this command calls \fBTcl_WaitPid\fR with the \fBWNOHANG\fR flag set for non-blocking behavior, unless the \fB\-wait\fR switch is set (see below). -.RS .PP Additionally, \fB::tcl::process status\fR accepts the following switches: .TP \fB\-wait\fR\0 . By default the command returns immediately (the underlying \fBTcl_WaitPid\fR is -called with the \fBWNOHANG\fR flag set) unless this switch is set. If \fBpids\fR +called with the \fBWNOHANG\fR flag set) unless this switch is set. If \fIpids\fR is specified as a list of PIDs then the command waits until the status of the -matching subprocesses are available. If \fBpids\fR is not specified then it -waits for all known subprocesses. +matching subprocesses are available. If \fIpids\fR was not specified, this +command will wait for all known subprocesses. .TP \fB\-\|\-\fR . Marks the end of switches. The argument following this one will be treated as the first \fIarg\fR even if it starts with a \fB\-\fR. .RE -.TP -\fB::tcl::process purge ?\fIpids\fR? -. -Cleans up all data associated with terminated subprocesses. If \fBpids\fR is -specified as a list of PIDs then the command only cleanup data for the matching -subprocesses if they exist, and raises an error otherwise. If the process is -still active then it does nothing. -.TP -\fB::tcl::process autopurge ?\fIflag\fR? -. -Automatic purge facility. If \fBflag\fR is specified as a boolean value then it -activates or deactivate autopurge. In all cases it returns the current status as -a boolean value. When autopurge is active, \fBTcl_ReapDetachedProcs\fR is called -each time the exec command is executed or a pipe channel created by open is -closed. When autopurge is inactive, \fB::tcl::process\fR purge must be called -explicitly. By default autopurge is active. -.RE .SH "EXAMPLES" .PP +These show the use of \fB::tcl::process\fR. Some of the results from +\fB::tcl::process status\fR are split over multiple lines for readability. +.PP .CS \fB::tcl::process autopurge\fR \fI\(-> true\fR @@ -102,7 +108,12 @@ set pid2 [pid $chan] \fI\(-> 123 456 789 1011\fR \fB::tcl::process status\fR - \fI\(-> 123 0 456 {1 "child killed: write on pipe with no readers" {CHILDKILLED 456 SIGPIPE "write on pipe with no readers"}} 789 {1 "child suspended: background tty read" {CHILDSUSP 789 SIGTTIN "background tty read"}} 1011 {}\fR + \fI\(-> 123 0 + 456 {1 "child killed: write on pipe with no readers" { + CHILDKILLED 456 SIGPIPE "write on pipe with no readers"}} + 789 {1 "child suspended: background tty read" { + CHILDSUSP 789 SIGTTIN "background tty read"}} + 1011 {}\fR \fB::tcl::process status\fR 123 \fI\(-> 123 0\fR @@ -111,10 +122,17 @@ set pid2 [pid $chan] \fI\(-> 1011 {}\fR \fB::tcl::process status\fR -wait - \fI\(-> 123 0 456 {1 "child killed: write on pipe with no readers" {CHILDKILLED 456 SIGPIPE "write on pipe with no readers"}} 789 {1 "child suspended: background tty read" {CHILDSUSP 789 SIGTTIN "background tty read"}} 1011 {1 "child process exited abnormally" {CHILDSTATUS 1011 -1}}\fR + \fI\(-> 123 0 + 456 {1 "child killed: write on pipe with no readers" { + CHILDKILLED 456 SIGPIPE "write on pipe with no readers"}} + 789 {1 "child suspended: background tty read" { + CHILDSUSP 789 SIGTTIN "background tty read"}} + 1011 {1 "child process exited abnormally" { + CHILDSTATUS 1011 -1}}\fR \fB::tcl::process status\fR 1011 - \fI\(-> 1011 {1 "child process exited abnormally" {CHILDSTATUS 1011 -1}}\fR + \fI\(-> 1011 {1 "child process exited abnormally" { + CHILDSTATUS 1011 -1}}\fR \fB::tcl::process purge\fR exec command1 1 2 3 & @@ -123,7 +141,8 @@ exec command1 1 2 3 & \fI\(-> 1213\fR .CE .SH "SEE ALSO" -exec(n), open(n), Tcl_DetachPids(3), Tcl_WaitPid(3), Tcl_ReapDetachedProcs(3) +exec(n), open(n), pid(n), +Tcl_DetachPids(3), Tcl_WaitPid(3), Tcl_ReapDetachedProcs(3) .SH "KEYWORDS" background, child, detach, process, wait '\" Local Variables: -- cgit v0.12 From 1a664df87f7f2471bf4c2ad40f19f946f7daae23 Mon Sep 17 00:00:00 2001 From: sebres Date: Tue, 9 Oct 2018 16:59:13 +0000 Subject: Balance the [makeFile/makeDirectory] and [removeFile/removeDirectory] calls (conditional now, so avoids warnings in filter/constraint cases). --- tests/winPipe.test | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/tests/winPipe.test b/tests/winPipe.test index 62cc707..3c051b0 100644 --- a/tests/winPipe.test +++ b/tests/winPipe.test @@ -323,9 +323,8 @@ proc _testExecArgs {single args} { lappend cmds [list $path(echoArgs.bat)] } else { if {![info exists path(echoArgs2.bat)] || ![file exists $path(echoArgs2.bat)]} { - file mkdir [file join [temporaryDirectory] test(Dir)Check] set path(echoArgs2.bat) [makeFile "@[file native [interpreter]] $path(echoArgs.tcl) %*" \ - "test(Dir)Check/echo(Cmd)Test Args & Batch.bat"] + "[makeDirectory test(Dir)Check]/echo(Cmd)Test Args & Batch.bat"] } lappend cmds [list $path(echoArgs2.bat)] } @@ -603,9 +602,9 @@ removeFile more removeFile stdout removeFile stderr removeFile nothing -removeFile echoArgs.tcl -removeFile echoArgs.bat -file delete -force [file join [temporaryDirectory] test(Dir)Check] +if {[info exists path(echoArgs.tcl)]} { removeFile echoArgs.tcl } +if {[info exists path(echoArgs.bat)]} { removeFile echoArgs.bat } +if {[info exists path(echoArgs2.bat)]} { removeDirectory test(Dir)Check } ::tcltest::cleanupTests return -- cgit v0.12 From bbdb1f12a0518cfc2a81cd7ec057703ca92e0ffe Mon Sep 17 00:00:00 2001 From: dgp Date: Tue, 9 Oct 2018 18:24:57 +0000 Subject: Use the 4 argument form of [makeFile]. --- tests/winPipe.test | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/winPipe.test b/tests/winPipe.test index 3c051b0..2f59e96 100644 --- a/tests/winPipe.test +++ b/tests/winPipe.test @@ -323,8 +323,9 @@ proc _testExecArgs {single args} { lappend cmds [list $path(echoArgs.bat)] } else { if {![info exists path(echoArgs2.bat)] || ![file exists $path(echoArgs2.bat)]} { - set path(echoArgs2.bat) [makeFile "@[file native [interpreter]] $path(echoArgs.tcl) %*" \ - "[makeDirectory test(Dir)Check]/echo(Cmd)Test Args & Batch.bat"] + set path(echoArgs2.bat) [makeFile \ + "@[file native [interpreter]] $path(echoArgs.tcl) %*" \ + "echo(Cmd)Test Args & Batch.bat" [makeDirectory test(Dir)Check]] } lappend cmds [list $path(echoArgs2.bat)] } -- cgit v0.12 From 0591917a06fb80bebd5396d4a8dff438b8d02dbc Mon Sep 17 00:00:00 2001 From: dkf Date: Tue, 9 Oct 2018 18:52:52 +0000 Subject: Avoid making question marks bold or italic in docs UNLESS EXACTLY MEANINGFUL --- doc/clock.n | 26 ++++++++++++++++---------- doc/http.n | 4 ++-- doc/interp.n | 2 +- doc/lindex.n | 2 +- doc/platform.n | 2 +- doc/platform_shell.n | 2 +- doc/prefix.n | 12 ++++++------ doc/string.n | 2 +- doc/trace.n | 3 ++- doc/zipfs.n | 2 +- 10 files changed, 32 insertions(+), 25 deletions(-) diff --git a/doc/clock.n b/doc/clock.n index e8fb8f7..a85f29f 100644 --- a/doc/clock.n +++ b/doc/clock.n @@ -886,40 +886,46 @@ The \fIinputString\fR argument consists of zero or more specifications of the following form: .TP \fItime\fR -A time of day, which is of the form: \fBhh?:mm?:ss?? ?meridian? ?zone?\fR -or \fBhhmm ?meridian? ?zone?\fR -If no meridian is specified, \fBhh\fR is interpreted on +. +A time of day, which is of the form: +.QW "\fIhh\fR?\fB:\fImm\fR?\fB:\fIss\fR?? ?\fImeridian\fR? ?\fIzone\fR?" +or +.QW "\fBhhmm \fR?\fBmeridian\fR? ?\fBzone\fR?" . +If no \fImeridian\fR is specified, \fIhh\fR is interpreted on a 24-hour clock. .TP \fIdate\fR +. A specific month and day with optional year. The acceptable formats are -.QW "\fBmm/dd\fR?\fB/yy\fR?" , -.QW "\fBmonthname dd\fR?\fB, yy\fR?" , -.QW "\fBday, dd monthname \fR?\fByy\fR?" , -.QW "\fBdd monthname yy\fR" , -.QW "?\fBCC\fR?\fByymmdd\fR" , +.QW "\fImm\fB/\fIdd\fR?\fB/\fIyy\fR?" , +.QW "\fImonthname dd\fR?\fB, \fIyy\fR?" , +.QW "\fIday\fB, \fIdd monthname \fR?\fIyy\fR?" , +.QW "\fIdd monthname yy\fR" , +.QW "?\fICC\fR?\fIyymmdd\fR" , and -.QW "\fBdd-monthname-\fR?\fBCC\fR?\fByy\fR" . +.QW "\fIdd\fB-\fImonthname\fB-\fR?\fICC\fR?\fIyy\fR" . The default year is the current year. If the year is less than 100, we treat the years 00-68 as 2000-2068 and the years 69-99 as 1969-1999. Not all platforms can represent the years 38-70, so an error may result if these years are used. .TP \fIISO 8601 point-in-time\fR +. An ISO 8601 point-in-time specification, such as .QW \fICCyymmdd\fBT\fIhhmmss\fR, where \fBT\fR is the literal .QW T , .QW "\fICCyymmdd hhmmss\fR" , or -.QW \fICCyymmdd\fBT\fIhh:mm:ss\fR . +.QW \fICCyymmdd\fBT\fIhh\fB:\fImm\fB:\fIss\fR . Note that only these three formats are accepted. The command does \fInot\fR accept the full range of point-in-time specifications specified in ISO8601. Other formats can be recognized by giving an explicit \fB\-format\fR option to the \fBclock scan\fR command. .TP \fIrelative time\fR +. A specification relative to the current time. The format is \fBnumber unit\fR. Acceptable units are \fByear\fR, \fBfortnight\fR, \fBmonth\fR, \fBweek\fR, \fBday\fR, diff --git a/doc/http.n b/doc/http.n index 7e633b3..a986704 100644 --- a/doc/http.n +++ b/doc/http.n @@ -13,10 +13,10 @@ .SH NAME http \- Client-side implementation of the HTTP/1.1 protocol .SH SYNOPSIS -\fBpackage require http ?2.8?\fR +\fBpackage require http\fI ?\fB2.8\fR? .\" See Also -useragent option documentation in body! .sp -\fB::http::config ?\fI\-option value\fR ...? +\fB::http::config\fR ?\fI\-option value\fR ...? .sp \fB::http::geturl \fIurl\fR ?\fI\-option value\fR ...? .sp diff --git a/doc/interp.n b/doc/interp.n index ac07fb7..e91e403 100644 --- a/doc/interp.n +++ b/doc/interp.n @@ -236,7 +236,7 @@ attempts are silently ignored. This is needed to maintain the consistency of the underlying interpreter's state. .RE .TP -\fBinterp\fR \fBdelete \fR?\fIpath ...?\fR +\fBinterp\fR \fBdelete \fR?\fIpath ...\fR? . Deletes zero or more interpreters given by the optional \fIpath\fR arguments, and for each interpreter, it also deletes its slaves. The diff --git a/doc/lindex.n b/doc/lindex.n index d5605bc..be4f169 100644 --- a/doc/lindex.n +++ b/doc/lindex.n @@ -13,7 +13,7 @@ .SH NAME lindex \- Retrieve an element from a list .SH SYNOPSIS -\fBlindex \fIlist ?index ...?\fR +\fBlindex \fIlist\fR ?\fIindex ...\fR? .BE .SH DESCRIPTION .PP diff --git a/doc/platform.n b/doc/platform.n index 5380ff4..7cb685d 100644 --- a/doc/platform.n +++ b/doc/platform.n @@ -12,7 +12,7 @@ platform \- System identification support code and utilities .SH SYNOPSIS .nf -\fBpackage require platform ?1.0.10?\fR +\fBpackage require platform\fR ?\fB1.0.10\fR? .sp \fBplatform::generic\fR \fBplatform::identify\fR diff --git a/doc/platform_shell.n b/doc/platform_shell.n index f7ae283..a9e14d0 100644 --- a/doc/platform_shell.n +++ b/doc/platform_shell.n @@ -12,7 +12,7 @@ platform::shell \- System identification support code and utilities .SH SYNOPSIS .nf -\fBpackage require platform::shell ?1.1.4?\fR +\fBpackage require platform::shell\fR ?\fB1.1.4\fR? .sp \fBplatform::shell::generic \fIshell\fR \fBplatform::shell::identify \fIshell\fR diff --git a/doc/prefix.n b/doc/prefix.n index 50aa2fb..d327a78 100644 --- a/doc/prefix.n +++ b/doc/prefix.n @@ -12,9 +12,9 @@ tcl::prefix \- facilities for prefix matching .SH SYNOPSIS .nf -\fB::tcl::prefix all\fR \fItable\fR \fIstring\fR -\fB::tcl::prefix longest\fR \fItable\fR \fIstring\fR -\fB::tcl::prefix match\fR \fI?option ...?\fR \fItable\fR \fIstring\fR +\fB::tcl::prefix all\fR \fItable string\fR +\fB::tcl::prefix longest\fR \fItable string\fR +\fB::tcl::prefix match\fR ?\fIoption ...\fR? \fItable string\fR .fi .BE .SH DESCRIPTION @@ -22,17 +22,17 @@ tcl::prefix \- facilities for prefix matching This document describes commands looking up a prefix in a list of strings. The following commands are supported: .TP -\fB::tcl::prefix all\fR \fItable\fR \fIstring\fR +\fB::tcl::prefix all\fR \fItable string\fR . Returns a list of all elements in \fItable\fR that begin with the prefix \fIstring\fR. .TP -\fB::tcl::prefix longest\fR \fItable\fR \fIstring\fR +\fB::tcl::prefix longest\fR \fItable string\fR . Returns the longest common prefix of all elements in \fItable\fR that begin with the prefix \fIstring\fR. .TP -\fB::tcl::prefix match\fR ?\fIoptions\fR? \fItable\fR \fIstring\fR +\fB::tcl::prefix match\fR ?\fIoptions\fR? \fItable string\fR . If \fIstring\fR equals one element in \fItable\fR or is a prefix to exactly one element, the matched element is returned. If not, the result depends diff --git a/doc/string.n b/doc/string.n index 7e666ea..439f3b7 100644 --- a/doc/string.n +++ b/doc/string.n @@ -12,7 +12,7 @@ .SH NAME string \- Manipulate strings .SH SYNOPSIS -\fBstring \fIoption arg \fR?\fIarg ...?\fR +\fBstring \fIoption arg \fR?\fIarg ...\fR? .BE .SH DESCRIPTION .PP diff --git a/doc/trace.n b/doc/trace.n index 5482e59..570b263 100644 --- a/doc/trace.n +++ b/doc/trace.n @@ -20,7 +20,8 @@ trace \- Monitor variable accesses, command usages and command executions This command causes Tcl commands to be executed whenever certain operations are invoked. The legal \fIoption\fRs (which may be abbreviated) are: .TP -\fBtrace add \fItype name ops ?args?\fR +\fBtrace add \fItype name ops\fR ?\fIargs\fR? +. Where \fItype\fR is \fBcommand\fR, \fBexecution\fR, or \fBvariable\fR. .RS .TP diff --git a/doc/zipfs.n b/doc/zipfs.n index 3600e64..705faa1 100644 --- a/doc/zipfs.n +++ b/doc/zipfs.n @@ -63,7 +63,7 @@ Note: querying the mount point gives the start of the zip data as the offset in (4), which can be used to truncate the zip information from an executable. .RE .TP -\fBzipfs list\fR ?(\fB\-glob\fR|\fB\-regexp\fR)? \fI?pattern?\fR +\fBzipfs list\fR ?(\fB\-glob\fR|\fB\-regexp\fR)? ?\fIpattern\fR? . Return a list of all files in the mounted zipfs, or just those matching \fIpattern\fR (optionally controlled by the option parameters). The order of -- cgit v0.12 From 398efeba2dbc75beb921548c7668531e122af18d Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Tue, 9 Oct 2018 19:27:26 +0000 Subject: Fix test-case macOSXFCmd-4.1, by assuring the files are sorted alphabetically always. The file-sytem cannot be thrusted doing this. --- tests/macOSXFCmd.test | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/tests/macOSXFCmd.test b/tests/macOSXFCmd.test index 071f11b..132b2fe 100644 --- a/tests/macOSXFCmd.test +++ b/tests/macOSXFCmd.test @@ -151,16 +151,16 @@ test macOSXFCmd-4.1 {TclMacOSXMatchType} {macosxFileAttr notRoot} { file attributes dir.test -hidden 1 } set res [list \ - [catch {glob *.test} msg] $msg \ - [catch {glob -types FOOT *.test} msg] $msg \ - [catch {glob -types {{macintosh type FOOT}} *.test} msg] $msg \ - [catch {glob -types FOOTT *.test} msg] $msg \ - [catch {glob -types {{macintosh type FOOTT}} *.test} msg] $msg \ - [catch {glob -types {{macintosh type {}}} *.test} msg] $msg \ - [catch {glob -types {{macintosh creator FOOC}} *.test} msg] $msg \ - [catch {glob -types {{macintosh creator FOOC} {macintosh type FOOT}} *.test} msg] $msg \ - [catch {glob -types hidden *.test} msg] $msg \ - [catch {glob -types {hidden FOOT} *.test} msg] $msg \ + [catch {lsort [glob *.test]} msg] $msg \ + [catch {lsort [glob -types FOOT *.test]} msg] $msg \ + [catch {lsort [glob -types {{macintosh type FOOT}} *.test]} msg] $msg \ + [catch {lsort [glob -types FOOTT *.test]} msg] $msg \ + [catch {lsort [glob -types {{macintosh type FOOTT}} *.test]} msg] $msg \ + [catch {lsort [glob -types {{macintosh type {}}} *.test]} msg] $msg \ + [catch {lsort [glob -types {{macintosh creator FOOC}} *.test]} msg] $msg \ + [catch {lsort [glob -types {{macintosh creator FOOC} {macintosh type FOOT}} *.test]} msg] $msg \ + [catch {lsort [glob -types hidden *.test]} msg] $msg \ + [catch {lsort [glob -types {hidden FOOT} *.test]} msg] $msg \ ] cd .. file delete -force globtest -- cgit v0.12 From 1f2c3cb141703d6795e040e3a5dbf59da362b6e9 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Tue, 9 Oct 2018 19:43:38 +0000 Subject: isspace -> TclIsSpaceProc in various places. Re-generate tclDate.c with Bision 3.1 --- generic/tclBinary.c | 16 +- generic/tclCmdMZ.c | 2 +- generic/tclCompCmdsSZ.c | 2 +- generic/tclDate.c | 1896 +++++++++++++++++++++++------------------------ generic/tclGetDate.y | 2 +- generic/tclObj.c | 4 +- 6 files changed, 961 insertions(+), 961 deletions(-) diff --git a/generic/tclBinary.c b/generic/tclBinary.c index 24f228e..fdc60e7 100644 --- a/generic/tclBinary.c +++ b/generic/tclBinary.c @@ -2483,8 +2483,8 @@ BinaryDecodeHex( } c = *data++; - if (!isxdigit((int) c)) { - if (strict || !isspace(c)) { + if (!isxdigit(UCHAR(c))) { + if (strict || !TclIsSpaceProc(c)) { goto badChar; } i--; @@ -2831,7 +2831,7 @@ BinaryDecodeUu( if (lineLen < 0) { c = *data++; if (c < 32 || c > 96) { - if (strict || !isspace(c)) { + if (strict || !TclIsSpaceProc(c)) { goto badUu; } i--; @@ -2849,7 +2849,7 @@ BinaryDecodeUu( d[i] = c = *data++; if (c < 32 || c > 96) { if (strict) { - if (!isspace(c)) { + if (!TclIsSpaceProc(c)) { goto badUu; } else if (c == '\n') { goto shortUu; @@ -2893,7 +2893,7 @@ BinaryDecodeUu( } else if (c >= 32 && c <= 96) { data--; break; - } else if (strict || !isspace(c)) { + } else if (strict || !TclIsSpaceProc(c)) { goto badUu; } } while (data < dataend); @@ -3018,7 +3018,7 @@ BinaryDecode64( if (c == '=' && i > 1) { value <<= 6; cut++; - } else if (!strict && isspace(c)) { + } else if (!strict && TclIsSpaceProc(c)) { i--; } else { goto bad64; @@ -3036,7 +3036,7 @@ BinaryDecode64( } else if (c == '=') { value <<= 6; cut++; - } else if (strict || !isspace(c)) { + } else if (strict || !TclIsSpaceProc(c)) { goto bad64; } else { i--; @@ -3057,7 +3057,7 @@ BinaryDecode64( goto bad64; } for (; data < dataend; data++) { - if (!isspace(*data)) { + if (!TclIsSpaceProc(*data)) { goto bad64; } } diff --git a/generic/tclCmdMZ.c b/generic/tclCmdMZ.c index c2b0ba9..e6e2a2e 100644 --- a/generic/tclCmdMZ.c +++ b/generic/tclCmdMZ.c @@ -1844,7 +1844,7 @@ static int UniCharIsHexDigit( int character) { - return (character >= 0) && (character < 0x80) && isxdigit(character); + return (character >= 0) && (character < 0x80) && isxdigit(UCHAR(character)); } /* diff --git a/generic/tclCompCmdsSZ.c b/generic/tclCompCmdsSZ.c index 243f8a9..b16b8b3 100644 --- a/generic/tclCompCmdsSZ.c +++ b/generic/tclCompCmdsSZ.c @@ -1350,7 +1350,7 @@ static int UniCharIsHexDigit( int character) { - return (character >= 0) && (character < 0x80) && isxdigit(character); + return (character >= 0) && (character < 0x80) && isxdigit(UCHAR(character)); } StringClassDesc const tclStringClassTable[] = { diff --git a/generic/tclDate.c b/generic/tclDate.c index 717a1b3..f720325 100644 --- a/generic/tclDate.c +++ b/generic/tclDate.c @@ -1,14 +1,13 @@ -/* A Bison parser, made by GNU Bison 2.3. */ +/* A Bison parser, made by GNU Bison 3.1. */ -/* Skeleton implementation for Bison's Yacc-like parsers in C +/* Bison implementation for Yacc-like parsers in C - Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 - Free Software Foundation, Inc. + Copyright (C) 1984, 1989-1990, 2000-2015, 2018 Free Software Foundation, Inc. - This program is free software; you can redistribute it and/or modify + This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -16,9 +15,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. */ + along with this program. If not, see . */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work @@ -47,7 +44,7 @@ #define YYBISON 1 /* Bison version. */ -#define YYBISON_VERSION "2.3" +#define YYBISON_VERSION "3.1" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" @@ -55,64 +52,19 @@ /* Pure parsers. */ #define YYPURE 1 -/* Using locations. */ -#define YYLSP_NEEDED 1 +/* Push parsers. */ +#define YYPUSH 0 -/* Substitute the variable and function names. */ -#define yyparse TclDateparse -#define yylex TclDatelex -#define yyerror TclDateerror -#define yylval TclDatelval -#define yychar TclDatechar -#define yydebug TclDatedebug -#define yynerrs TclDatenerrs -#define yylloc TclDatelloc - -/* Tokens. */ -#ifndef YYTOKENTYPE -# define YYTOKENTYPE - /* Put the tokens into the symbol table, so that GDB and other debuggers - know about them. */ - enum yytokentype { - tAGO = 258, - tDAY = 259, - tDAYZONE = 260, - tID = 261, - tMERIDIAN = 262, - tMONTH = 263, - tMONTH_UNIT = 264, - tSTARDATE = 265, - tSEC_UNIT = 266, - tSNUMBER = 267, - tUNUMBER = 268, - tZONE = 269, - tEPOCH = 270, - tDST = 271, - tISOBASE = 272, - tDAY_UNIT = 273, - tNEXT = 274 - }; -#endif -/* Tokens. */ -#define tAGO 258 -#define tDAY 259 -#define tDAYZONE 260 -#define tID 261 -#define tMERIDIAN 262 -#define tMONTH 263 -#define tMONTH_UNIT 264 -#define tSTARDATE 265 -#define tSEC_UNIT 266 -#define tSNUMBER 267 -#define tUNUMBER 268 -#define tZONE 269 -#define tEPOCH 270 -#define tDST 271 -#define tISOBASE 272 -#define tDAY_UNIT 273 -#define tNEXT 274 +/* Pull parsers. */ +#define YYPULL 1 +/* Substitute the variable and function names. */ +#define yyparse TclDateparse +#define yylex TclDatelex +#define yyerror TclDateerror +#define yydebug TclDatedebug +#define yynerrs TclDatenerrs /* Copy the first part of user declarations. */ @@ -129,6 +81,7 @@ * * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. + * */ #include "tclInt.h" @@ -256,10 +209,14 @@ typedef enum _MERIDIAN { -/* Enabling traces. */ -#ifndef YYDEBUG -# define YYDEBUG 0 -#endif + +# ifndef YY_NULLPTR +# if defined __cplusplus && 201103L <= __cplusplus +# define YY_NULLPTR nullptr +# else +# define YY_NULLPTR 0 +# endif +# endif /* Enabling verbose error messages. */ #ifdef YYERROR_VERBOSE @@ -269,40 +226,78 @@ typedef enum _MERIDIAN { # define YYERROR_VERBOSE 0 #endif -/* Enabling the token table. */ -#ifndef YYTOKEN_TABLE -# define YYTOKEN_TABLE 0 + +/* Debug traces. */ +#ifndef YYDEBUG +# define YYDEBUG 0 +#endif +#if YYDEBUG +extern int TclDatedebug; #endif +/* Token type. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + enum yytokentype + { + tAGO = 258, + tDAY = 259, + tDAYZONE = 260, + tID = 261, + tMERIDIAN = 262, + tMONTH = 263, + tMONTH_UNIT = 264, + tSTARDATE = 265, + tSEC_UNIT = 266, + tSNUMBER = 267, + tUNUMBER = 268, + tZONE = 269, + tEPOCH = 270, + tDST = 271, + tISOBASE = 272, + tDAY_UNIT = 273, + tNEXT = 274 + }; +#endif + +/* Value type. */ #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED -typedef union YYSTYPE +union YYSTYPE { + + time_t Number; enum _MERIDIAN Meridian; -} -/* Line 187 of yacc.c. */ - YYSTYPE; -# define yystype YYSTYPE /* obsolescent; will be withdrawn */ -# define YYSTYPE_IS_DECLARED 1 + +}; + +typedef union YYSTYPE YYSTYPE; # define YYSTYPE_IS_TRIVIAL 1 +# define YYSTYPE_IS_DECLARED 1 #endif +/* Location type. */ #if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED -typedef struct YYLTYPE +typedef struct YYLTYPE YYLTYPE; +struct YYLTYPE { int first_line; int first_column; int last_line; int last_column; -} YYLTYPE; -# define yyltype YYLTYPE /* obsolescent; will be withdrawn */ +}; # define YYLTYPE_IS_DECLARED 1 # define YYLTYPE_IS_TRIVIAL 1 #endif + +int TclDateparse (DateInfo* info); + + + /* Copy the second part of user declarations. */ @@ -322,8 +317,6 @@ MODULE_SCOPE int yyparse(DateInfo*); -/* Line 216 of yacc.c. */ - #ifdef short # undef short @@ -337,72 +330,103 @@ typedef unsigned char yytype_uint8; #ifdef YYTYPE_INT8 typedef YYTYPE_INT8 yytype_int8; -#elif (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -typedef signed char yytype_int8; #else -typedef short int yytype_int8; +typedef signed char yytype_int8; #endif #ifdef YYTYPE_UINT16 typedef YYTYPE_UINT16 yytype_uint16; #else -typedef unsigned short int yytype_uint16; +typedef unsigned short yytype_uint16; #endif #ifdef YYTYPE_INT16 typedef YYTYPE_INT16 yytype_int16; #else -typedef short int yytype_int16; +typedef short yytype_int16; #endif #ifndef YYSIZE_T # ifdef __SIZE_TYPE__ # define YYSIZE_T __SIZE_TYPE__ -# else +# elif defined size_t # define YYSIZE_T size_t +# elif ! defined YYSIZE_T +# include /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t +# else +# define YYSIZE_T unsigned # endif #endif #define YYSIZE_MAXIMUM ((YYSIZE_T) -1) #ifndef YY_ -# if YYENABLE_NLS +# if defined YYENABLE_NLS && YYENABLE_NLS # if ENABLE_NLS # include /* INFRINGES ON USER NAME SPACE */ -# define YY_(msgid) dgettext ("bison-runtime", msgid) +# define YY_(Msgid) dgettext ("bison-runtime", Msgid) # endif # endif # ifndef YY_ -# define YY_(msgid) msgid +# define YY_(Msgid) Msgid +# endif +#endif + +#ifndef YY_ATTRIBUTE +# if (defined __GNUC__ \ + && (2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__))) \ + || defined __SUNPRO_C && 0x5110 <= __SUNPRO_C +# define YY_ATTRIBUTE(Spec) __attribute__(Spec) +# else +# define YY_ATTRIBUTE(Spec) /* empty */ +# endif +#endif + +#ifndef YY_ATTRIBUTE_PURE +# define YY_ATTRIBUTE_PURE YY_ATTRIBUTE ((__pure__)) +#endif + +#ifndef YY_ATTRIBUTE_UNUSED +# define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__)) +#endif + +#if !defined _Noreturn \ + && (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112) +# if defined _MSC_VER && 1200 <= _MSC_VER +# define _Noreturn __declspec (noreturn) +# else +# define _Noreturn YY_ATTRIBUTE ((__noreturn__)) # endif #endif /* Suppress unused-variable warnings by "using" E. */ #if ! defined lint || defined __GNUC__ -# define YYUSE(e) ((void) (e)) +# define YYUSE(E) ((void) (E)) #else -# define YYUSE(e) /* empty */ +# define YYUSE(E) /* empty */ #endif -/* Identity function, used to suppress warnings about constant conditions. */ -#ifndef lint -# define YYID(n) (n) -#else -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static int -YYID (int i) +#if defined __GNUC__ && ! defined __ICC && 407 <= __GNUC__ * 100 + __GNUC_MINOR__ +/* Suppress an incorrect diagnostic about yylval being uninitialized. */ +# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ + _Pragma ("GCC diagnostic push") \ + _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\ + _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") +# define YY_IGNORE_MAYBE_UNINITIALIZED_END \ + _Pragma ("GCC diagnostic pop") #else -static int -YYID (i) - int i; +# define YY_INITIAL_VALUE(Value) Value #endif -{ - return i; -} +#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN +# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN +# define YY_IGNORE_MAYBE_UNINITIALIZED_END +#endif +#ifndef YY_INITIAL_VALUE +# define YY_INITIAL_VALUE(Value) /* Nothing. */ #endif + #if ! defined yyoverflow || YYERROR_VERBOSE /* The parser invokes alloca or malloc; define the necessary symbols. */ @@ -420,11 +444,11 @@ YYID (i) # define alloca _alloca # else # define YYSTACK_ALLOC alloca -# if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) +# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS # include /* INFRINGES ON USER NAME SPACE */ -# ifndef _STDLIB_H -# define _STDLIB_H 1 + /* Use EXIT_SUCCESS as a witness for stdlib.h. */ +# ifndef EXIT_SUCCESS +# define EXIT_SUCCESS 0 # endif # endif # endif @@ -432,8 +456,8 @@ YYID (i) # endif # ifdef YYSTACK_ALLOC - /* Pacify GCC's `empty if-body' warning. */ -# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) + /* Pacify GCC's 'empty if-body' warning. */ +# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) # ifndef YYSTACK_ALLOC_MAXIMUM /* The OS might guarantee only one guard page at the bottom of the stack, and a page size can be as small as 4096 bytes. So we cannot safely @@ -447,25 +471,23 @@ YYID (i) # ifndef YYSTACK_ALLOC_MAXIMUM # define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM # endif -# if (defined __cplusplus && ! defined _STDLIB_H \ +# if (defined __cplusplus && ! defined EXIT_SUCCESS \ && ! ((defined YYMALLOC || defined malloc) \ - && (defined YYFREE || defined free))) + && (defined YYFREE || defined free))) # include /* INFRINGES ON USER NAME SPACE */ -# ifndef _STDLIB_H -# define _STDLIB_H 1 +# ifndef EXIT_SUCCESS +# define EXIT_SUCCESS 0 # endif # endif # ifndef YYMALLOC # define YYMALLOC malloc -# if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) +# if ! defined malloc && ! defined EXIT_SUCCESS void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ # endif # endif # ifndef YYFREE # define YYFREE free -# if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) +# if ! defined free && ! defined EXIT_SUCCESS void free (void *); /* INFRINGES ON USER NAME SPACE */ # endif # endif @@ -475,15 +497,15 @@ void free (void *); /* INFRINGES ON USER NAME SPACE */ #if (! defined yyoverflow \ && (! defined __cplusplus \ - || (defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \ - && defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) + || (defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \ + && defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) /* A type that is properly aligned for any stack member. */ union yyalloc { - yytype_int16 yyss; - YYSTYPE yyvs; - YYLTYPE yyls; + yytype_int16 yyss_alloc; + YYSTYPE yyvs_alloc; + YYLTYPE yyls_alloc; }; /* The size of the maximum gap between one aligned stack and the next. */ @@ -495,42 +517,46 @@ union yyalloc ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE) + sizeof (YYLTYPE)) \ + 2 * YYSTACK_GAP_MAXIMUM) -/* Copy COUNT objects from FROM to TO. The source and destination do - not overlap. */ -# ifndef YYCOPY -# if defined __GNUC__ && 1 < __GNUC__ -# define YYCOPY(To, From, Count) \ - __builtin_memcpy (To, From, (Count) * sizeof (*(From))) -# else -# define YYCOPY(To, From, Count) \ - do \ - { \ - YYSIZE_T yyi; \ - for (yyi = 0; yyi < (Count); yyi++) \ - (To)[yyi] = (From)[yyi]; \ - } \ - while (YYID (0)) -# endif -# endif +# define YYCOPY_NEEDED 1 /* Relocate STACK from its old location to the new one. The local variables YYSIZE and YYSTACKSIZE give the old and new number of elements in the stack, and YYPTR gives the new location of the stack. Advance YYPTR to a properly aligned location for the next stack. */ -# define YYSTACK_RELOCATE(Stack) \ - do \ - { \ - YYSIZE_T yynewbytes; \ - YYCOPY (&yyptr->Stack, Stack, yysize); \ - Stack = &yyptr->Stack; \ - yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ - yyptr += yynewbytes / sizeof (*yyptr); \ - } \ - while (YYID (0)) +# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ + do \ + { \ + YYSIZE_T yynewbytes; \ + YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ + Stack = &yyptr->Stack_alloc; \ + yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ + yyptr += yynewbytes / sizeof (*yyptr); \ + } \ + while (0) #endif +#if defined YYCOPY_NEEDED && YYCOPY_NEEDED +/* Copy COUNT objects from SRC to DST. The source and destination do + not overlap. */ +# ifndef YYCOPY +# if defined __GNUC__ && 1 < __GNUC__ +# define YYCOPY(Dst, Src, Count) \ + __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src))) +# else +# define YYCOPY(Dst, Src, Count) \ + do \ + { \ + YYSIZE_T yyi; \ + for (yyi = 0; yyi < (Count); yyi++) \ + (Dst)[yyi] = (Src)[yyi]; \ + } \ + while (0) +# endif +# endif +#endif /* !YYCOPY_NEEDED */ + /* YYFINAL -- State number of the termination state. */ #define YYFINAL 2 /* YYLAST -- Last index in YYTABLE. */ @@ -542,17 +568,19 @@ union yyalloc #define YYNNTS 16 /* YYNRULES -- Number of rules. */ #define YYNRULES 56 -/* YYNRULES -- Number of states. */ +/* YYNSTATES -- Number of states. */ #define YYNSTATES 83 -/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ +/* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned + by yylex, with out-of-bounds checking. */ #define YYUNDEFTOK 2 #define YYMAXUTOK 274 -#define YYTRANSLATE(YYX) \ - ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) +#define YYTRANSLATE(YYX) \ + ((unsigned) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) -/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ +/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM + as returned by yylex, without out-of-bounds checking. */ static const yytype_uint8 yytranslate[] = { 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, @@ -586,54 +614,19 @@ static const yytype_uint8 yytranslate[] = }; #if YYDEBUG -/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in - YYRHS. */ -static const yytype_uint8 yyprhs[] = -{ - 0, 0, 3, 4, 7, 9, 11, 13, 15, 17, - 19, 21, 23, 25, 28, 33, 39, 46, 54, 57, - 59, 61, 63, 66, 69, 73, 76, 80, 86, 88, - 94, 100, 103, 108, 111, 113, 117, 120, 124, 128, - 136, 139, 144, 147, 149, 153, 156, 159, 163, 165, - 167, 169, 171, 173, 175, 177, 178 -}; - -/* YYRHS -- A `-1'-separated list of the rules' RHS. */ -static const yytype_int8 yyrhs[] = -{ - 27, 0, -1, -1, 27, 28, -1, 29, -1, 30, - -1, 32, -1, 33, -1, 31, -1, 36, -1, 34, - -1, 35, -1, 40, -1, 13, 7, -1, 13, 20, - 13, 41, -1, 13, 20, 13, 21, 13, -1, 13, - 20, 13, 20, 13, 41, -1, 13, 20, 13, 20, - 13, 21, 13, -1, 14, 16, -1, 14, -1, 5, - -1, 4, -1, 4, 22, -1, 13, 4, -1, 38, - 13, 4, -1, 19, 4, -1, 13, 23, 13, -1, - 13, 23, 13, 23, 13, -1, 17, -1, 13, 21, - 8, 21, 13, -1, 13, 21, 13, 21, 13, -1, - 8, 13, -1, 8, 13, 22, 13, -1, 13, 8, - -1, 15, -1, 13, 8, 13, -1, 19, 8, -1, - 19, 13, 8, -1, 17, 14, 17, -1, 17, 14, - 13, 20, 13, 20, 13, -1, 17, 17, -1, 10, - 13, 24, 13, -1, 37, 3, -1, 37, -1, 38, - 13, 39, -1, 13, 39, -1, 19, 39, -1, 19, - 13, 39, -1, 39, -1, 21, -1, 25, -1, 11, - -1, 18, -1, 9, -1, 13, -1, -1, 7, -1 -}; - -/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ + /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ static const yytype_uint16 yyrline[] = { - 0, 225, 225, 226, 229, 232, 235, 238, 241, 244, - 247, 251, 256, 259, 265, 271, 279, 285, 296, 300, - 304, 310, 314, 318, 322, 326, 332, 336, 341, 346, - 351, 356, 360, 365, 369, 374, 381, 385, 391, 400, - 409, 419, 433, 438, 441, 444, 447, 450, 453, 458, - 461, 466, 470, 474, 480, 498, 501 + 0, 223, 223, 224, 227, 230, 233, 236, 239, 242, + 245, 249, 254, 257, 263, 269, 277, 283, 294, 298, + 302, 308, 312, 316, 320, 324, 330, 334, 339, 344, + 349, 354, 358, 363, 367, 372, 379, 383, 389, 398, + 407, 417, 431, 436, 439, 442, 445, 448, 451, 456, + 459, 464, 468, 472, 478, 496, 499 }; #endif -#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE +#if YYDEBUG || YYERROR_VERBOSE || 0 /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. First, the terminals, then, starting at YYNTOKENS, nonterminals. */ static const char *const yytname[] = @@ -644,13 +637,13 @@ static const char *const yytname[] = "tDAY_UNIT", "tNEXT", "':'", "'-'", "','", "'/'", "'.'", "'+'", "$accept", "spec", "item", "time", "zone", "day", "date", "ordMonth", "iso", "trek", "relspec", "relunits", "sign", "unit", "number", - "o_merid", 0 + "o_merid", YY_NULLPTR }; #endif # ifdef YYPRINT -/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to - token YYLEX-NUM. */ +/* YYTOKNUM[NUM] -- (External) token number corresponding to the + (internal) symbol number NUM (which must be that of a token). */ static const yytype_uint16 yytoknum[] = { 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, @@ -659,54 +652,18 @@ static const yytype_uint16 yytoknum[] = }; # endif -/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ -static const yytype_uint8 yyr1[] = -{ - 0, 26, 27, 27, 28, 28, 28, 28, 28, 28, - 28, 28, 28, 29, 29, 29, 29, 29, 30, 30, - 30, 31, 31, 31, 31, 31, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 33, 33, 34, 34, - 34, 35, 36, 36, 37, 37, 37, 37, 37, 38, - 38, 39, 39, 39, 40, 41, 41 -}; +#define YYPACT_NINF -22 -/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ -static const yytype_uint8 yyr2[] = -{ - 0, 2, 0, 2, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 2, 4, 5, 6, 7, 2, 1, - 1, 1, 2, 2, 3, 2, 3, 5, 1, 5, - 5, 2, 4, 2, 1, 3, 2, 3, 3, 7, - 2, 4, 2, 1, 3, 2, 2, 3, 1, 1, - 1, 1, 1, 1, 1, 0, 1 -}; +#define yypact_value_is_default(Yystate) \ + (!!((Yystate) == (-22))) -/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state - STATE-NUM when YYTABLE doesn't specify something else to do. Zero - means the default is an error. */ -static const yytype_uint8 yydefact[] = -{ - 2, 0, 1, 21, 20, 0, 53, 0, 51, 54, - 19, 34, 28, 52, 0, 49, 50, 3, 4, 5, - 8, 6, 7, 10, 11, 9, 43, 0, 48, 12, - 22, 31, 0, 23, 13, 33, 0, 0, 0, 45, - 18, 0, 40, 25, 36, 0, 46, 42, 0, 0, - 0, 35, 55, 0, 0, 26, 0, 38, 37, 47, - 24, 44, 32, 41, 56, 0, 0, 14, 0, 0, - 0, 0, 55, 15, 29, 30, 27, 0, 0, 16, - 0, 17, 39 -}; +#define YYTABLE_NINF -1 -/* YYDEFGOTO[NTERM-NUM]. */ -static const yytype_int8 yydefgoto[] = -{ - -1, 1, 17, 18, 19, 20, 21, 22, 23, 24, - 25, 26, 27, 28, 29, 67 -}; +#define yytable_value_is_error(Yytable_value) \ + 0 -/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing - STATE-NUM. */ -#define YYPACT_NINF -22 + /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing + STATE-NUM. */ static const yytype_int8 yypact[] = { -22, 2, -22, -21, -22, -4, -22, 1, -22, 22, @@ -720,18 +677,39 @@ static const yytype_int8 yypact[] = 64, -22, -22 }; -/* YYPGOTO[NTERM-NUM]. */ + /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. + Performed when YYTABLE does not specify something else to do. Zero + means the default is an error. */ +static const yytype_uint8 yydefact[] = +{ + 2, 0, 1, 21, 20, 0, 53, 0, 51, 54, + 19, 34, 28, 52, 0, 49, 50, 3, 4, 5, + 8, 6, 7, 10, 11, 9, 43, 0, 48, 12, + 22, 31, 0, 23, 13, 33, 0, 0, 0, 45, + 18, 0, 40, 25, 36, 0, 46, 42, 0, 0, + 0, 35, 55, 0, 0, 26, 0, 38, 37, 47, + 24, 44, 32, 41, 56, 0, 0, 14, 0, 0, + 0, 0, 55, 15, 29, 30, 27, 0, 0, 16, + 0, 17, 39 +}; + + /* YYPGOTO[NTERM-NUM]. */ static const yytype_int8 yypgoto[] = { -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -22, -9, -22, 6 }; -/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If - positive, shift that token. If negative, reduce the rule which - number is the opposite. If zero, do what YYDEFACT says. - If YYTABLE_NINF, syntax error. */ -#define YYTABLE_NINF -1 + /* YYDEFGOTO[NTERM-NUM]. */ +static const yytype_int8 yydefgoto[] = +{ + -1, 1, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 67 +}; + + /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If + positive, shift that token. If negative, reduce the rule whose + number is the opposite. If YYTABLE_NINF, syntax error. */ static const yytype_uint8 yytable[] = { 39, 30, 2, 53, 64, 46, 3, 4, 54, 31, @@ -756,8 +734,8 @@ static const yytype_uint8 yycheck[] = 13, 13, 20, 13, 13, 13, 13, 13, 72, 20 }; -/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing - symbol of state STATE-NUM. */ + /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing + symbol of state STATE-NUM. */ static const yytype_uint8 yystos[] = { 0, 27, 0, 4, 5, 8, 9, 10, 11, 13, @@ -771,156 +749,179 @@ static const yytype_uint8 yystos[] = 20, 13, 13 }; -#define yyerrok (yyerrstatus = 0) -#define yyclearin (yychar = YYEMPTY) -#define YYEMPTY (-2) -#define YYEOF 0 + /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ +static const yytype_uint8 yyr1[] = +{ + 0, 26, 27, 27, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 29, 29, 29, 29, 29, 30, 30, + 30, 31, 31, 31, 31, 31, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 33, 33, 34, 34, + 34, 35, 36, 36, 37, 37, 37, 37, 37, 38, + 38, 39, 39, 39, 40, 41, 41 +}; + + /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */ +static const yytype_uint8 yyr2[] = +{ + 0, 2, 0, 2, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 2, 4, 5, 6, 7, 2, 1, + 1, 1, 2, 2, 3, 2, 3, 5, 1, 5, + 5, 2, 4, 2, 1, 3, 2, 3, 3, 7, + 2, 4, 2, 1, 3, 2, 2, 3, 1, 1, + 1, 1, 1, 1, 1, 0, 1 +}; -#define YYACCEPT goto yyacceptlab -#define YYABORT goto yyabortlab -#define YYERROR goto yyerrorlab +#define yyerrok (yyerrstatus = 0) +#define yyclearin (yychar = YYEMPTY) +#define YYEMPTY (-2) +#define YYEOF 0 -/* Like YYERROR except do call yyerror. This remains here temporarily - to ease the transition to the new meaning of YYERROR, for GCC. - Once GCC version 2 has supplanted version 1, this can go. */ +#define YYACCEPT goto yyacceptlab +#define YYABORT goto yyabortlab +#define YYERROR goto yyerrorlab -#define YYFAIL goto yyerrlab #define YYRECOVERING() (!!yyerrstatus) -#define YYBACKUP(Token, Value) \ -do \ - if (yychar == YYEMPTY && yylen == 1) \ - { \ - yychar = (Token); \ - yylval = (Value); \ - yytoken = YYTRANSLATE (yychar); \ - YYPOPSTACK (1); \ - goto yybackup; \ - } \ - else \ - { \ +#define YYBACKUP(Token, Value) \ +do \ + if (yychar == YYEMPTY) \ + { \ + yychar = (Token); \ + yylval = (Value); \ + YYPOPSTACK (yylen); \ + yystate = *yyssp; \ + goto yybackup; \ + } \ + else \ + { \ yyerror (&yylloc, info, YY_("syntax error: cannot back up")); \ - YYERROR; \ - } \ -while (YYID (0)) + YYERROR; \ + } \ +while (0) - -#define YYTERROR 1 -#define YYERRCODE 256 +/* Error token number */ +#define YYTERROR 1 +#define YYERRCODE 256 /* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. If N is 0, then set CURRENT to the empty location which ends the previous symbol: RHS[0] (always defined). */ -#define YYRHSLOC(Rhs, K) ((Rhs)[K]) #ifndef YYLLOC_DEFAULT -# define YYLLOC_DEFAULT(Current, Rhs, N) \ - do \ - if (YYID (N)) \ - { \ - (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ - (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ - (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ - (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ - } \ - else \ - { \ - (Current).first_line = (Current).last_line = \ - YYRHSLOC (Rhs, 0).last_line; \ - (Current).first_column = (Current).last_column = \ - YYRHSLOC (Rhs, 0).last_column; \ - } \ - while (YYID (0)) +# define YYLLOC_DEFAULT(Current, Rhs, N) \ + do \ + if (N) \ + { \ + (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ + (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ + (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ + (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ + } \ + else \ + { \ + (Current).first_line = (Current).last_line = \ + YYRHSLOC (Rhs, 0).last_line; \ + (Current).first_column = (Current).last_column = \ + YYRHSLOC (Rhs, 0).last_column; \ + } \ + while (0) #endif +#define YYRHSLOC(Rhs, K) ((Rhs)[K]) + + +/* Enable debugging if requested. */ +#if YYDEBUG + +# ifndef YYFPRINTF +# include /* INFRINGES ON USER NAME SPACE */ +# define YYFPRINTF fprintf +# endif + +# define YYDPRINTF(Args) \ +do { \ + if (yydebug) \ + YYFPRINTF Args; \ +} while (0) + /* YY_LOCATION_PRINT -- Print the location on the stream. This macro was not mandated originally: define only if we know we won't break user code: when these are the locations we know. */ #ifndef YY_LOCATION_PRINT -# if YYLTYPE_IS_TRIVIAL -# define YY_LOCATION_PRINT(File, Loc) \ - fprintf (File, "%d.%d-%d.%d", \ - (Loc).first_line, (Loc).first_column, \ - (Loc).last_line, (Loc).last_column) -# else -# define YY_LOCATION_PRINT(File, Loc) ((void) 0) -# endif -#endif - +# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL -/* YYLEX -- calling `yylex' with the right arguments. */ +/* Print *YYLOCP on YYO. Private, do not rely on its existence. */ -#ifdef YYLEX_PARAM -# define YYLEX yylex (&yylval, &yylloc, YYLEX_PARAM) -#else -# define YYLEX yylex (&yylval, &yylloc, info) -#endif +YY_ATTRIBUTE_UNUSED +static unsigned +yy_location_print_ (FILE *yyo, YYLTYPE const * const yylocp) +{ + unsigned res = 0; + int end_col = 0 != yylocp->last_column ? yylocp->last_column - 1 : 0; + if (0 <= yylocp->first_line) + { + res += YYFPRINTF (yyo, "%d", yylocp->first_line); + if (0 <= yylocp->first_column) + res += YYFPRINTF (yyo, ".%d", yylocp->first_column); + } + if (0 <= yylocp->last_line) + { + if (yylocp->first_line < yylocp->last_line) + { + res += YYFPRINTF (yyo, "-%d", yylocp->last_line); + if (0 <= end_col) + res += YYFPRINTF (yyo, ".%d", end_col); + } + else if (0 <= end_col && yylocp->first_column < end_col) + res += YYFPRINTF (yyo, "-%d", end_col); + } + return res; + } -/* Enable debugging if requested. */ -#if YYDEBUG +# define YY_LOCATION_PRINT(File, Loc) \ + yy_location_print_ (File, &(Loc)) -# ifndef YYFPRINTF -# include /* INFRINGES ON USER NAME SPACE */ -# define YYFPRINTF fprintf +# else +# define YY_LOCATION_PRINT(File, Loc) ((void) 0) # endif +#endif -# define YYDPRINTF(Args) \ -do { \ - if (yydebug) \ - YYFPRINTF Args; \ -} while (YYID (0)) -# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ -do { \ - if (yydebug) \ - { \ - YYFPRINTF (stderr, "%s ", Title); \ - yy_symbol_print (stderr, \ - Type, Value, Location, info); \ - YYFPRINTF (stderr, "\n"); \ - } \ -} while (YYID (0)) +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ +do { \ + if (yydebug) \ + { \ + YYFPRINTF (stderr, "%s ", Title); \ + yy_symbol_print (stderr, \ + Type, Value, Location, info); \ + YYFPRINTF (stderr, "\n"); \ + } \ +} while (0) -/*--------------------------------. -| Print this symbol on YYOUTPUT. | -`--------------------------------*/ +/*----------------------------------------. +| Print this symbol's value on YYOUTPUT. | +`----------------------------------------*/ -/*ARGSUSED*/ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) static void yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, DateInfo* info) -#else -static void -yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp, info) - FILE *yyoutput; - int yytype; - YYSTYPE const * const yyvaluep; - YYLTYPE const * const yylocationp; - DateInfo* info; -#endif { - if (!yyvaluep) - return; + FILE *yyo = yyoutput; + YYUSE (yyo); YYUSE (yylocationp); YYUSE (info); + if (!yyvaluep) + return; # ifdef YYPRINT if (yytype < YYNTOKENS) YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); -# else - YYUSE (yyoutput); # endif - switch (yytype) - { - default: - break; - } + YYUSE (yytype); } @@ -928,24 +929,11 @@ yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp, info) | Print this symbol on YYOUTPUT. | `--------------------------------*/ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) static void yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, DateInfo* info) -#else -static void -yy_symbol_print (yyoutput, yytype, yyvaluep, yylocationp, info) - FILE *yyoutput; - int yytype; - YYSTYPE const * const yyvaluep; - YYLTYPE const * const yylocationp; - DateInfo* info; -#endif { - if (yytype < YYNTOKENS) - YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); - else - YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); + YYFPRINTF (yyoutput, "%s %s (", + yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]); YY_LOCATION_PRINT (yyoutput, *yylocationp); YYFPRINTF (yyoutput, ": "); @@ -958,68 +946,54 @@ yy_symbol_print (yyoutput, yytype, yyvaluep, yylocationp, info) | TOP (included). | `------------------------------------------------------------------*/ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yy_stack_print (yytype_int16 *bottom, yytype_int16 *top) -#else static void -yy_stack_print (bottom, top) - yytype_int16 *bottom; - yytype_int16 *top; -#endif +yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) { YYFPRINTF (stderr, "Stack now"); - for (; bottom <= top; ++bottom) - YYFPRINTF (stderr, " %d", *bottom); + for (; yybottom <= yytop; yybottom++) + { + int yybot = *yybottom; + YYFPRINTF (stderr, " %d", yybot); + } YYFPRINTF (stderr, "\n"); } -# define YY_STACK_PRINT(Bottom, Top) \ -do { \ - if (yydebug) \ - yy_stack_print ((Bottom), (Top)); \ -} while (YYID (0)) +# define YY_STACK_PRINT(Bottom, Top) \ +do { \ + if (yydebug) \ + yy_stack_print ((Bottom), (Top)); \ +} while (0) /*------------------------------------------------. | Report that the YYRULE is going to be reduced. | `------------------------------------------------*/ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) static void -yy_reduce_print (YYSTYPE *yyvsp, YYLTYPE *yylsp, int yyrule, DateInfo* info) -#else -static void -yy_reduce_print (yyvsp, yylsp, yyrule, info) - YYSTYPE *yyvsp; - YYLTYPE *yylsp; - int yyrule; - DateInfo* info; -#endif +yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, YYLTYPE *yylsp, int yyrule, DateInfo* info) { + unsigned long yylno = yyrline[yyrule]; int yynrhs = yyr2[yyrule]; int yyi; - unsigned long int yylno = yyrline[yyrule]; YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", - yyrule - 1, yylno); + yyrule - 1, yylno); /* The symbols being reduced. */ for (yyi = 0; yyi < yynrhs; yyi++) { - fprintf (stderr, " $%d = ", yyi + 1); - yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], - &(yyvsp[(yyi + 1) - (yynrhs)]) - , &(yylsp[(yyi + 1) - (yynrhs)]) , info); - fprintf (stderr, "\n"); + YYFPRINTF (stderr, " $%d = ", yyi + 1); + yy_symbol_print (stderr, + yystos[yyssp[yyi + 1 - yynrhs]], + &(yyvsp[(yyi + 1) - (yynrhs)]) + , &(yylsp[(yyi + 1) - (yynrhs)]) , info); + YYFPRINTF (stderr, "\n"); } } -# define YY_REDUCE_PRINT(Rule) \ -do { \ - if (yydebug) \ - yy_reduce_print (yyvsp, yylsp, Rule, info); \ -} while (YYID (0)) +# define YY_REDUCE_PRINT(Rule) \ +do { \ + if (yydebug) \ + yy_reduce_print (yyssp, yyvsp, yylsp, Rule, info); \ +} while (0) /* Nonzero means print parse trace. It is left uninitialized so that multiple parsers can coexist. */ @@ -1033,7 +1007,7 @@ int yydebug; /* YYINITDEPTH -- initial size of the parser's stacks. */ -#ifndef YYINITDEPTH +#ifndef YYINITDEPTH # define YYINITDEPTH 200 #endif @@ -1048,7 +1022,6 @@ int yydebug; # define YYMAXDEPTH 10000 #endif - #if YYERROR_VERBOSE @@ -1057,15 +1030,8 @@ int yydebug; # define yystrlen strlen # else /* Return the length of YYSTR. */ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) static YYSIZE_T yystrlen (const char *yystr) -#else -static YYSIZE_T -yystrlen (yystr) - const char *yystr; -#endif { YYSIZE_T yylen; for (yylen = 0; yystr[yylen]; yylen++) @@ -1081,16 +1047,8 @@ yystrlen (yystr) # else /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in YYDEST. */ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) static char * yystpcpy (char *yydest, const char *yysrc) -#else -static char * -yystpcpy (yydest, yysrc) - char *yydest; - const char *yysrc; -#endif { char *yyd = yydest; const char *yys = yysrc; @@ -1120,27 +1078,27 @@ yytnamerr (char *yyres, const char *yystr) char const *yyp = yystr; for (;;) - switch (*++yyp) - { - case '\'': - case ',': - goto do_not_strip_quotes; - - case '\\': - if (*++yyp != '\\') - goto do_not_strip_quotes; - /* Fall through. */ - default: - if (yyres) - yyres[yyn] = *yyp; - yyn++; - break; - - case '"': - if (yyres) - yyres[yyn] = '\0'; - return yyn; - } + switch (*++yyp) + { + case '\'': + case ',': + goto do_not_strip_quotes; + + case '\\': + if (*++yyp != '\\') + goto do_not_strip_quotes; + /* Fall through. */ + default: + if (yyres) + yyres[yyn] = *yyp; + yyn++; + break; + + case '"': + if (yyres) + yyres[yyn] = '\0'; + return yyn; + } do_not_strip_quotes: ; } @@ -1151,169 +1109,161 @@ yytnamerr (char *yyres, const char *yystr) } # endif -/* Copy into YYRESULT an error message about the unexpected token - YYCHAR while in state YYSTATE. Return the number of bytes copied, - including the terminating null byte. If YYRESULT is null, do not - copy anything; just return the number of bytes that would be - copied. As a special case, return 0 if an ordinary "syntax error" - message will do. Return YYSIZE_MAXIMUM if overflow occurs during - size calculation. */ -static YYSIZE_T -yysyntax_error (char *yyresult, int yystate, int yychar) +/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message + about the unexpected token YYTOKEN for the state stack whose top is + YYSSP. + + Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is + not large enough to hold the message. In that case, also set + *YYMSG_ALLOC to the required number of bytes. Return 2 if the + required number of bytes is too large to store. */ +static int +yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, + yytype_int16 *yyssp, int yytoken) { - int yyn = yypact[yystate]; + YYSIZE_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]); + YYSIZE_T yysize = yysize0; + enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; + /* Internationalized format string. */ + const char *yyformat = YY_NULLPTR; + /* Arguments of yyformat. */ + char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; + /* Number of reported tokens (one for the "unexpected", one per + "expected"). */ + int yycount = 0; + + /* There are many possibilities here to consider: + - If this state is a consistent state with a default action, then + the only way this function was invoked is if the default action + is an error action. In that case, don't check for expected + tokens because there are none. + - The only way there can be no lookahead present (in yychar) is if + this state is a consistent state with a default action. Thus, + detecting the absence of a lookahead is sufficient to determine + that there is no unexpected or expected token to report. In that + case, just report a simple "syntax error". + - Don't assume there isn't a lookahead just because this state is a + consistent state with a default action. There might have been a + previous inconsistent state, consistent state with a non-default + action, or user semantic action that manipulated yychar. + - Of course, the expected token list depends on states to have + correct lookahead information, and it depends on the parser not + to perform extra reductions after fetching a lookahead from the + scanner and before detecting a syntax error. Thus, state merging + (from LALR or IELR) and default reductions corrupt the expected + token list. However, the list is correct for canonical LR with + one exception: it will still contain any token that will not be + accepted due to an error action in a later state. + */ + if (yytoken != YYEMPTY) + { + int yyn = yypact[*yyssp]; + yyarg[yycount++] = yytname[yytoken]; + if (!yypact_value_is_default (yyn)) + { + /* Start YYX at -YYN if negative to avoid negative indexes in + YYCHECK. In other words, skip the first -YYN actions for + this state because they are default actions. */ + int yyxbegin = yyn < 0 ? -yyn : 0; + /* Stay within bounds of both yycheck and yytname. */ + int yychecklim = YYLAST - yyn + 1; + int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; + int yyx; + + for (yyx = yyxbegin; yyx < yyxend; ++yyx) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR + && !yytable_value_is_error (yytable[yyx + yyn])) + { + if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) + { + yycount = 1; + yysize = yysize0; + break; + } + yyarg[yycount++] = yytname[yyx]; + { + YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]); + if (! (yysize <= yysize1 + && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) + return 2; + yysize = yysize1; + } + } + } + } - if (! (YYPACT_NINF < yyn && yyn <= YYLAST)) - return 0; - else + switch (yycount) + { +# define YYCASE_(N, S) \ + case N: \ + yyformat = S; \ + break + default: /* Avoid compiler warnings. */ + YYCASE_(0, YY_("syntax error")); + YYCASE_(1, YY_("syntax error, unexpected %s")); + YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s")); + YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s")); + YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s")); + YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s")); +# undef YYCASE_ + } + + { + YYSIZE_T yysize1 = yysize + yystrlen (yyformat); + if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) + return 2; + yysize = yysize1; + } + + if (*yymsg_alloc < yysize) { - int yytype = YYTRANSLATE (yychar); - YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]); - YYSIZE_T yysize = yysize0; - YYSIZE_T yysize1; - int yysize_overflow = 0; - enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; - char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; - int yyx; - -# if 0 - /* This is so xgettext sees the translatable formats that are - constructed on the fly. */ - YY_("syntax error, unexpected %s"); - YY_("syntax error, unexpected %s, expecting %s"); - YY_("syntax error, unexpected %s, expecting %s or %s"); - YY_("syntax error, unexpected %s, expecting %s or %s or %s"); - YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"); -# endif - char *yyfmt; - char const *yyf; - static char const yyunexpected[] = "syntax error, unexpected %s"; - static char const yyexpecting[] = ", expecting %s"; - static char const yyor[] = " or %s"; - char yyformat[sizeof yyunexpected - + sizeof yyexpecting - 1 - + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2) - * (sizeof yyor - 1))]; - char const *yyprefix = yyexpecting; - - /* Start YYX at -YYN if negative to avoid negative indexes in - YYCHECK. */ - int yyxbegin = yyn < 0 ? -yyn : 0; - - /* Stay within bounds of both yycheck and yytname. */ - int yychecklim = YYLAST - yyn + 1; - int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; - int yycount = 1; - - yyarg[0] = yytname[yytype]; - yyfmt = yystpcpy (yyformat, yyunexpected); - - for (yyx = yyxbegin; yyx < yyxend; ++yyx) - if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) - { - if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) - { - yycount = 1; - yysize = yysize0; - yyformat[sizeof yyunexpected - 1] = '\0'; - break; - } - yyarg[yycount++] = yytname[yyx]; - yysize1 = yysize + yytnamerr (0, yytname[yyx]); - yysize_overflow |= (yysize1 < yysize); - yysize = yysize1; - yyfmt = yystpcpy (yyfmt, yyprefix); - yyprefix = yyor; - } - - yyf = YY_(yyformat); - yysize1 = yysize + yystrlen (yyf); - yysize_overflow |= (yysize1 < yysize); - yysize = yysize1; - - if (yysize_overflow) - return YYSIZE_MAXIMUM; - - if (yyresult) - { - /* Avoid sprintf, as that infringes on the user's name space. - Don't have undefined behavior even if the translation - produced a string with the wrong number of "%s"s. */ - char *yyp = yyresult; - int yyi = 0; - while ((*yyp = *yyf) != '\0') - { - if (*yyp == '%' && yyf[1] == 's' && yyi < yycount) - { - yyp += yytnamerr (yyp, yyarg[yyi++]); - yyf += 2; - } - else - { - yyp++; - yyf++; - } - } - } - return yysize; + *yymsg_alloc = 2 * yysize; + if (! (yysize <= *yymsg_alloc + && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM)) + *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM; + return 1; } + + /* Avoid sprintf, as that infringes on the user's name space. + Don't have undefined behavior even if the translation + produced a string with the wrong number of "%s"s. */ + { + char *yyp = *yymsg; + int yyi = 0; + while ((*yyp = *yyformat) != '\0') + if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount) + { + yyp += yytnamerr (yyp, yyarg[yyi++]); + yyformat += 2; + } + else + { + yyp++; + yyformat++; + } + } + return 0; } #endif /* YYERROR_VERBOSE */ - /*-----------------------------------------------. | Release the memory associated to this symbol. | `-----------------------------------------------*/ -/*ARGSUSED*/ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) static void yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, YYLTYPE *yylocationp, DateInfo* info) -#else -static void -yydestruct (yymsg, yytype, yyvaluep, yylocationp, info) - const char *yymsg; - int yytype; - YYSTYPE *yyvaluep; - YYLTYPE *yylocationp; - DateInfo* info; -#endif { YYUSE (yyvaluep); YYUSE (yylocationp); YYUSE (info); - if (!yymsg) yymsg = "Deleting"; YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); - switch (yytype) - { - - default: - break; - } + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN + YYUSE (yytype); + YY_IGNORE_MAYBE_UNINITIALIZED_END } - - -/* Prevent warnings from -Wmissing-prototypes. */ - -#ifdef YYPARSE_PARAM -#if defined __STDC__ || defined __cplusplus -int yyparse (void *YYPARSE_PARAM); -#else -int yyparse (); -#endif -#else /* ! YYPARSE_PARAM */ -#if defined __STDC__ || defined __cplusplus -int yyparse (DateInfo* info); -#else -int yyparse (); -#endif -#endif /* ! YYPARSE_PARAM */ - - @@ -1322,112 +1272,96 @@ int yyparse (); | yyparse. | `----------*/ -#ifdef YYPARSE_PARAM -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -int -yyparse (void *YYPARSE_PARAM) -#else -int -yyparse (YYPARSE_PARAM) - void *YYPARSE_PARAM; -#endif -#else /* ! YYPARSE_PARAM */ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) int yyparse (DateInfo* info) -#else -int -yyparse (info) - DateInfo* info; -#endif -#endif { - /* The look-ahead symbol. */ +/* The lookahead symbol. */ int yychar; -/* The semantic value of the look-ahead symbol. */ -YYSTYPE yylval = {0}; -/* Number of syntax errors so far. */ -int yynerrs; -/* Location data for the look-ahead symbol. */ -YYLTYPE yylloc; +/* The semantic value of the lookahead symbol. */ +/* Default value used for initialization, for pacifying older GCCs + or non-GCC compilers. */ +YY_INITIAL_VALUE (static YYSTYPE yyval_default;) +YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); - int yystate; - int yyn; - int yyresult; - /* Number of tokens to shift before error messages enabled. */ - int yyerrstatus; - /* Look-ahead token as an internal (translated) token number. */ - int yytoken = 0; -#if YYERROR_VERBOSE - /* Buffer for error messages, and its allocated size. */ - char yymsgbuf[128]; - char *yymsg = yymsgbuf; - YYSIZE_T yymsg_alloc = sizeof yymsgbuf; -#endif +/* Location data for the lookahead symbol. */ +static YYLTYPE yyloc_default +# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL + = { 1, 1, 1, 1 } +# endif +; +YYLTYPE yylloc = yyloc_default; - /* Three stacks and their tools: - `yyss': related to states, - `yyvs': related to semantic values, - `yyls': related to locations. + /* Number of syntax errors so far. */ + int yynerrs; - Refer to the stacks thru separate pointers, to allow yyoverflow - to reallocate them elsewhere. */ + int yystate; + /* Number of tokens to shift before error messages enabled. */ + int yyerrstatus; - /* The state stack. */ - yytype_int16 yyssa[YYINITDEPTH]; - yytype_int16 *yyss = yyssa; - yytype_int16 *yyssp; + /* The stacks and their tools: + 'yyss': related to states. + 'yyvs': related to semantic values. + 'yyls': related to locations. - /* The semantic value stack. */ - YYSTYPE yyvsa[YYINITDEPTH]; - YYSTYPE *yyvs = yyvsa; - YYSTYPE *yyvsp; + Refer to the stacks through separate pointers, to allow yyoverflow + to reallocate them elsewhere. */ - /* The location stack. */ - YYLTYPE yylsa[YYINITDEPTH]; - YYLTYPE *yyls = yylsa; - YYLTYPE *yylsp; - /* The locations where the error started and ended. */ - YYLTYPE yyerror_range[2]; + /* The state stack. */ + yytype_int16 yyssa[YYINITDEPTH]; + yytype_int16 *yyss; + yytype_int16 *yyssp; -#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N), yylsp -= (N)) + /* The semantic value stack. */ + YYSTYPE yyvsa[YYINITDEPTH]; + YYSTYPE *yyvs; + YYSTYPE *yyvsp; - YYSIZE_T yystacksize = YYINITDEPTH; + /* The location stack. */ + YYLTYPE yylsa[YYINITDEPTH]; + YYLTYPE *yyls; + YYLTYPE *yylsp; + /* The locations where the error started and ended. */ + YYLTYPE yyerror_range[3]; + + YYSIZE_T yystacksize; + + int yyn; + int yyresult; + /* Lookahead token as an internal (translated) token number. */ + int yytoken = 0; /* The variables used to return semantic value and location from the action routines. */ YYSTYPE yyval; YYLTYPE yyloc; +#if YYERROR_VERBOSE + /* Buffer for error messages, and its allocated size. */ + char yymsgbuf[128]; + char *yymsg = yymsgbuf; + YYSIZE_T yymsg_alloc = sizeof yymsgbuf; +#endif + +#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N), yylsp -= (N)) + /* The number of symbols on the RHS of the reduced rule. Keep to zero when no symbol should be popped. */ int yylen = 0; + yyssp = yyss = yyssa; + yyvsp = yyvs = yyvsa; + yylsp = yyls = yylsa; + yystacksize = YYINITDEPTH; + YYDPRINTF ((stderr, "Starting parse\n")); yystate = 0; yyerrstatus = 0; yynerrs = 0; - yychar = YYEMPTY; /* Cause a token to be read. */ - - /* Initialize stack pointers. - Waste one element of value and location stack - so that they stay on the same level as the state stack. - The wasted elements are never initialized. */ - - yyssp = yyss; - yyvsp = yyvs; - yylsp = yyls; -#if YYLTYPE_IS_TRIVIAL - /* Initialize the default location before parsing starts. */ - yylloc.first_line = yylloc.last_line = 1; - yylloc.first_column = yylloc.last_column = 0; -#endif - + yychar = YYEMPTY; /* Cause a token to be read. */ + yylsp[0] = yylloc; goto yysetstate; /*------------------------------------------------------------. @@ -1448,25 +1382,26 @@ YYLTYPE yylloc; #ifdef yyoverflow { - /* Give user a chance to reallocate the stack. Use copies of - these so that the &'s don't force the real ones into - memory. */ - YYSTYPE *yyvs1 = yyvs; - yytype_int16 *yyss1 = yyss; - YYLTYPE *yyls1 = yyls; - - /* Each stack pointer address is followed by the size of the - data in use in that stack, in bytes. This used to be a - conditional around just the two extra args, but that might - be undefined if yyoverflow is a macro. */ - yyoverflow (YY_("memory exhausted"), - &yyss1, yysize * sizeof (*yyssp), - &yyvs1, yysize * sizeof (*yyvsp), - &yyls1, yysize * sizeof (*yylsp), - &yystacksize); - yyls = yyls1; - yyss = yyss1; - yyvs = yyvs1; + /* Give user a chance to reallocate the stack. Use copies of + these so that the &'s don't force the real ones into + memory. */ + YYSTYPE *yyvs1 = yyvs; + yytype_int16 *yyss1 = yyss; + YYLTYPE *yyls1 = yyls; + + /* Each stack pointer address is followed by the size of the + data in use in that stack, in bytes. This used to be a + conditional around just the two extra args, but that might + be undefined if yyoverflow is a macro. */ + yyoverflow (YY_("memory exhausted"), + &yyss1, yysize * sizeof (*yyssp), + &yyvs1, yysize * sizeof (*yyvsp), + &yyls1, yysize * sizeof (*yylsp), + &yystacksize); + + yyls = yyls1; + yyss = yyss1; + yyvs = yyvs1; } #else /* no yyoverflow */ # ifndef YYSTACK_RELOCATE @@ -1474,23 +1409,23 @@ YYLTYPE yylloc; # else /* Extend the stack our own way. */ if (YYMAXDEPTH <= yystacksize) - goto yyexhaustedlab; + goto yyexhaustedlab; yystacksize *= 2; if (YYMAXDEPTH < yystacksize) - yystacksize = YYMAXDEPTH; + yystacksize = YYMAXDEPTH; { - yytype_int16 *yyss1 = yyss; - union yyalloc *yyptr = - (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); - if (! yyptr) - goto yyexhaustedlab; - YYSTACK_RELOCATE (yyss); - YYSTACK_RELOCATE (yyvs); - YYSTACK_RELOCATE (yyls); + yytype_int16 *yyss1 = yyss; + union yyalloc *yyptr = + (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); + if (! yyptr) + goto yyexhaustedlab; + YYSTACK_RELOCATE (yyss_alloc, yyss); + YYSTACK_RELOCATE (yyvs_alloc, yyvs); + YYSTACK_RELOCATE (yyls_alloc, yyls); # undef YYSTACK_RELOCATE - if (yyss1 != yyssa) - YYSTACK_FREE (yyss1); + if (yyss1 != yyssa) + YYSTACK_FREE (yyss1); } # endif #endif /* no yyoverflow */ @@ -1500,14 +1435,17 @@ YYLTYPE yylloc; yylsp = yyls + yysize - 1; YYDPRINTF ((stderr, "Stack size increased to %lu\n", - (unsigned long int) yystacksize)); + (unsigned long) yystacksize)); if (yyss + yystacksize - 1 <= yyssp) - YYABORT; + YYABORT; } YYDPRINTF ((stderr, "Entering state %d\n", yystate)); + if (yystate == YYFINAL) + YYACCEPT; + goto yybackup; /*-----------. @@ -1516,20 +1454,20 @@ YYLTYPE yylloc; yybackup: /* Do appropriate processing given the current state. Read a - look-ahead token if we need one and don't already have one. */ + lookahead token if we need one and don't already have one. */ - /* First try to decide what to do without reference to look-ahead token. */ + /* First try to decide what to do without reference to lookahead token. */ yyn = yypact[yystate]; - if (yyn == YYPACT_NINF) + if (yypact_value_is_default (yyn)) goto yydefault; - /* Not known => get a look-ahead token if don't already have one. */ + /* Not known => get a lookahead token if don't already have one. */ - /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */ + /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ if (yychar == YYEMPTY) { YYDPRINTF ((stderr, "Reading a token: ")); - yychar = YYLEX; + yychar = yylex (&yylval, &yylloc, info); } if (yychar <= YYEOF) @@ -1551,29 +1489,27 @@ yybackup: yyn = yytable[yyn]; if (yyn <= 0) { - if (yyn == 0 || yyn == YYTABLE_NINF) - goto yyerrlab; + if (yytable_value_is_error (yyn)) + goto yyerrlab; yyn = -yyn; goto yyreduce; } - if (yyn == YYFINAL) - YYACCEPT; - /* Count tokens shifted since error; after three, turn off error status. */ if (yyerrstatus) yyerrstatus--; - /* Shift the look-ahead token. */ + /* Shift the lookahead token. */ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); - /* Discard the shifted token unless it is eof. */ - if (yychar != YYEOF) - yychar = YYEMPTY; + /* Discard the shifted token. */ + yychar = YYEMPTY; yystate = yyn; + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN *++yyvsp = yylval; + YY_IGNORE_MAYBE_UNINITIALIZED_END *++yylsp = yylloc; goto yynewstate; @@ -1596,7 +1532,7 @@ yyreduce: yylen = yyr2[yyn]; /* If YYLEN is nonzero, implement the default value of the action: - `$$ = $1'. + '$$ = $1'. Otherwise, the following line sets YYVAL to garbage. This behavior is undocumented and Bison @@ -1605,8 +1541,9 @@ yyreduce: GCC warning that YYVAL may be used uninitialized. */ yyval = yyvsp[1-yylen]; - /* Default location. */ + /* Default location. */ YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen); + yyerror_range[1] = yyloc; YY_REDUCE_PRINT (yyn); switch (yyn) { @@ -1614,42 +1551,48 @@ yyreduce: { yyHaveTime++; - ;} + } + break; case 5: { yyHaveZone++; - ;} + } + break; case 6: { yyHaveDate++; - ;} + } + break; case 7: { yyHaveOrdinalMonth++; - ;} + } + break; case 8: { yyHaveDay++; - ;} + } + break; case 9: { yyHaveRel++; - ;} + } + break; case 10: @@ -1657,7 +1600,8 @@ yyreduce: { yyHaveTime++; yyHaveDate++; - ;} + } + break; case 11: @@ -1666,195 +1610,217 @@ yyreduce: yyHaveTime++; yyHaveDate++; yyHaveRel++; - ;} + } + break; case 13: { - yyHour = (yyvsp[(1) - (2)].Number); + yyHour = (yyvsp[-1].Number); yyMinutes = 0; yySeconds = 0; - yyMeridian = (yyvsp[(2) - (2)].Meridian); - ;} + yyMeridian = (yyvsp[0].Meridian); + } + break; case 14: { - yyHour = (yyvsp[(1) - (4)].Number); - yyMinutes = (yyvsp[(3) - (4)].Number); + yyHour = (yyvsp[-3].Number); + yyMinutes = (yyvsp[-1].Number); yySeconds = 0; - yyMeridian = (yyvsp[(4) - (4)].Meridian); - ;} + yyMeridian = (yyvsp[0].Meridian); + } + break; case 15: { - yyHour = (yyvsp[(1) - (5)].Number); - yyMinutes = (yyvsp[(3) - (5)].Number); + yyHour = (yyvsp[-4].Number); + yyMinutes = (yyvsp[-2].Number); yyMeridian = MER24; yyDSTmode = DSToff; - yyTimezone = ((yyvsp[(5) - (5)].Number) % 100 + ((yyvsp[(5) - (5)].Number) / 100) * 60); + yyTimezone = ((yyvsp[0].Number) % 100 + ((yyvsp[0].Number) / 100) * 60); ++yyHaveZone; - ;} + } + break; case 16: { - yyHour = (yyvsp[(1) - (6)].Number); - yyMinutes = (yyvsp[(3) - (6)].Number); - yySeconds = (yyvsp[(5) - (6)].Number); - yyMeridian = (yyvsp[(6) - (6)].Meridian); - ;} + yyHour = (yyvsp[-5].Number); + yyMinutes = (yyvsp[-3].Number); + yySeconds = (yyvsp[-1].Number); + yyMeridian = (yyvsp[0].Meridian); + } + break; case 17: { - yyHour = (yyvsp[(1) - (7)].Number); - yyMinutes = (yyvsp[(3) - (7)].Number); - yySeconds = (yyvsp[(5) - (7)].Number); + yyHour = (yyvsp[-6].Number); + yyMinutes = (yyvsp[-4].Number); + yySeconds = (yyvsp[-2].Number); yyMeridian = MER24; yyDSTmode = DSToff; - yyTimezone = ((yyvsp[(7) - (7)].Number) % 100 + ((yyvsp[(7) - (7)].Number) / 100) * 60); + yyTimezone = ((yyvsp[0].Number) % 100 + ((yyvsp[0].Number) / 100) * 60); ++yyHaveZone; - ;} + } + break; case 18: { - yyTimezone = (yyvsp[(1) - (2)].Number); + yyTimezone = (yyvsp[-1].Number); yyDSTmode = DSTon; - ;} + } + break; case 19: { - yyTimezone = (yyvsp[(1) - (1)].Number); + yyTimezone = (yyvsp[0].Number); yyDSTmode = DSToff; - ;} + } + break; case 20: { - yyTimezone = (yyvsp[(1) - (1)].Number); + yyTimezone = (yyvsp[0].Number); yyDSTmode = DSTon; - ;} + } + break; case 21: { yyDayOrdinal = 1; - yyDayNumber = (yyvsp[(1) - (1)].Number); - ;} + yyDayNumber = (yyvsp[0].Number); + } + break; case 22: { yyDayOrdinal = 1; - yyDayNumber = (yyvsp[(1) - (2)].Number); - ;} + yyDayNumber = (yyvsp[-1].Number); + } + break; case 23: { - yyDayOrdinal = (yyvsp[(1) - (2)].Number); - yyDayNumber = (yyvsp[(2) - (2)].Number); - ;} + yyDayOrdinal = (yyvsp[-1].Number); + yyDayNumber = (yyvsp[0].Number); + } + break; case 24: { - yyDayOrdinal = (yyvsp[(1) - (3)].Number) * (yyvsp[(2) - (3)].Number); - yyDayNumber = (yyvsp[(3) - (3)].Number); - ;} + yyDayOrdinal = (yyvsp[-2].Number) * (yyvsp[-1].Number); + yyDayNumber = (yyvsp[0].Number); + } + break; case 25: { yyDayOrdinal = 2; - yyDayNumber = (yyvsp[(2) - (2)].Number); - ;} + yyDayNumber = (yyvsp[0].Number); + } + break; case 26: { - yyMonth = (yyvsp[(1) - (3)].Number); - yyDay = (yyvsp[(3) - (3)].Number); - ;} + yyMonth = (yyvsp[-2].Number); + yyDay = (yyvsp[0].Number); + } + break; case 27: { - yyMonth = (yyvsp[(1) - (5)].Number); - yyDay = (yyvsp[(3) - (5)].Number); - yyYear = (yyvsp[(5) - (5)].Number); - ;} + yyMonth = (yyvsp[-4].Number); + yyDay = (yyvsp[-2].Number); + yyYear = (yyvsp[0].Number); + } + break; case 28: { - yyYear = (yyvsp[(1) - (1)].Number) / 10000; - yyMonth = ((yyvsp[(1) - (1)].Number) % 10000)/100; - yyDay = (yyvsp[(1) - (1)].Number) % 100; - ;} + yyYear = (yyvsp[0].Number) / 10000; + yyMonth = ((yyvsp[0].Number) % 10000)/100; + yyDay = (yyvsp[0].Number) % 100; + } + break; case 29: { - yyDay = (yyvsp[(1) - (5)].Number); - yyMonth = (yyvsp[(3) - (5)].Number); - yyYear = (yyvsp[(5) - (5)].Number); - ;} + yyDay = (yyvsp[-4].Number); + yyMonth = (yyvsp[-2].Number); + yyYear = (yyvsp[0].Number); + } + break; case 30: { - yyMonth = (yyvsp[(3) - (5)].Number); - yyDay = (yyvsp[(5) - (5)].Number); - yyYear = (yyvsp[(1) - (5)].Number); - ;} + yyMonth = (yyvsp[-2].Number); + yyDay = (yyvsp[0].Number); + yyYear = (yyvsp[-4].Number); + } + break; case 31: { - yyMonth = (yyvsp[(1) - (2)].Number); - yyDay = (yyvsp[(2) - (2)].Number); - ;} + yyMonth = (yyvsp[-1].Number); + yyDay = (yyvsp[0].Number); + } + break; case 32: { - yyMonth = (yyvsp[(1) - (4)].Number); - yyDay = (yyvsp[(2) - (4)].Number); - yyYear = (yyvsp[(4) - (4)].Number); - ;} + yyMonth = (yyvsp[-3].Number); + yyDay = (yyvsp[-2].Number); + yyYear = (yyvsp[0].Number); + } + break; case 33: { - yyMonth = (yyvsp[(2) - (2)].Number); - yyDay = (yyvsp[(1) - (2)].Number); - ;} + yyMonth = (yyvsp[0].Number); + yyDay = (yyvsp[-1].Number); + } + break; case 34: @@ -1863,70 +1829,77 @@ yyreduce: yyMonth = 1; yyDay = 1; yyYear = EPOCH; - ;} + } + break; case 35: { - yyMonth = (yyvsp[(2) - (3)].Number); - yyDay = (yyvsp[(1) - (3)].Number); - yyYear = (yyvsp[(3) - (3)].Number); - ;} + yyMonth = (yyvsp[-1].Number); + yyDay = (yyvsp[-2].Number); + yyYear = (yyvsp[0].Number); + } + break; case 36: { yyMonthOrdinal = 1; - yyMonth = (yyvsp[(2) - (2)].Number); - ;} + yyMonth = (yyvsp[0].Number); + } + break; case 37: { - yyMonthOrdinal = (yyvsp[(2) - (3)].Number); - yyMonth = (yyvsp[(3) - (3)].Number); - ;} + yyMonthOrdinal = (yyvsp[-1].Number); + yyMonth = (yyvsp[0].Number); + } + break; case 38: { - if ((yyvsp[(2) - (3)].Number) != HOUR( 7)) YYABORT; - yyYear = (yyvsp[(1) - (3)].Number) / 10000; - yyMonth = ((yyvsp[(1) - (3)].Number) % 10000)/100; - yyDay = (yyvsp[(1) - (3)].Number) % 100; - yyHour = (yyvsp[(3) - (3)].Number) / 10000; - yyMinutes = ((yyvsp[(3) - (3)].Number) % 10000)/100; - yySeconds = (yyvsp[(3) - (3)].Number) % 100; - ;} + if ((yyvsp[-1].Number) != HOUR( 7)) YYABORT; + yyYear = (yyvsp[-2].Number) / 10000; + yyMonth = ((yyvsp[-2].Number) % 10000)/100; + yyDay = (yyvsp[-2].Number) % 100; + yyHour = (yyvsp[0].Number) / 10000; + yyMinutes = ((yyvsp[0].Number) % 10000)/100; + yySeconds = (yyvsp[0].Number) % 100; + } + break; case 39: { - if ((yyvsp[(2) - (7)].Number) != HOUR( 7)) YYABORT; - yyYear = (yyvsp[(1) - (7)].Number) / 10000; - yyMonth = ((yyvsp[(1) - (7)].Number) % 10000)/100; - yyDay = (yyvsp[(1) - (7)].Number) % 100; - yyHour = (yyvsp[(3) - (7)].Number); - yyMinutes = (yyvsp[(5) - (7)].Number); - yySeconds = (yyvsp[(7) - (7)].Number); - ;} + if ((yyvsp[-5].Number) != HOUR( 7)) YYABORT; + yyYear = (yyvsp[-6].Number) / 10000; + yyMonth = ((yyvsp[-6].Number) % 10000)/100; + yyDay = (yyvsp[-6].Number) % 100; + yyHour = (yyvsp[-4].Number); + yyMinutes = (yyvsp[-2].Number); + yySeconds = (yyvsp[0].Number); + } + break; case 40: { - yyYear = (yyvsp[(1) - (2)].Number) / 10000; - yyMonth = ((yyvsp[(1) - (2)].Number) % 10000)/100; - yyDay = (yyvsp[(1) - (2)].Number) % 100; - yyHour = (yyvsp[(2) - (2)].Number) / 10000; - yyMinutes = ((yyvsp[(2) - (2)].Number) % 10000)/100; - yySeconds = (yyvsp[(2) - (2)].Number) % 100; - ;} + yyYear = (yyvsp[-1].Number) / 10000; + yyMonth = ((yyvsp[-1].Number) % 10000)/100; + yyDay = (yyvsp[-1].Number) % 100; + yyHour = (yyvsp[0].Number) / 10000; + yyMinutes = ((yyvsp[0].Number) % 10000)/100; + yySeconds = (yyvsp[0].Number) % 100; + } + break; case 41: @@ -1937,12 +1910,13 @@ yyreduce: * in a range accessible with a 32 bit clock seconds value. */ - yyYear = (yyvsp[(2) - (4)].Number)/1000 + 2323 - 377; + yyYear = (yyvsp[-2].Number)/1000 + 2323 - 377; yyDay = 1; yyMonth = 1; - yyRelDay += (((yyvsp[(2) - (4)].Number)%1000)*(365 + IsLeapYear(yyYear)))/1000; - yyRelSeconds += (yyvsp[(4) - (4)].Number) * 144 * 60; - ;} + yyRelDay += (((yyvsp[-2].Number)%1000)*(365 + IsLeapYear(yyYear)))/1000; + yyRelSeconds += (yyvsp[0].Number) * 144 * 60; + } + break; case 42: @@ -1951,121 +1925,145 @@ yyreduce: yyRelSeconds *= -1; yyRelMonth *= -1; yyRelDay *= -1; - ;} + } + break; case 44: { - *yyRelPointer += (yyvsp[(1) - (3)].Number) * (yyvsp[(2) - (3)].Number) * (yyvsp[(3) - (3)].Number); - ;} + *yyRelPointer += (yyvsp[-2].Number) * (yyvsp[-1].Number) * (yyvsp[0].Number); + } + break; case 45: { - *yyRelPointer += (yyvsp[(1) - (2)].Number) * (yyvsp[(2) - (2)].Number); - ;} + *yyRelPointer += (yyvsp[-1].Number) * (yyvsp[0].Number); + } + break; case 46: { - *yyRelPointer += (yyvsp[(2) - (2)].Number); - ;} + *yyRelPointer += (yyvsp[0].Number); + } + break; case 47: { - *yyRelPointer += (yyvsp[(2) - (3)].Number) * (yyvsp[(3) - (3)].Number); - ;} + *yyRelPointer += (yyvsp[-1].Number) * (yyvsp[0].Number); + } + break; case 48: { - *yyRelPointer += (yyvsp[(1) - (1)].Number); - ;} + *yyRelPointer += (yyvsp[0].Number); + } + break; case 49: { (yyval.Number) = -1; - ;} + } + break; case 50: { (yyval.Number) = 1; - ;} + } + break; case 51: { - (yyval.Number) = (yyvsp[(1) - (1)].Number); + (yyval.Number) = (yyvsp[0].Number); yyRelPointer = &yyRelSeconds; - ;} + } + break; case 52: { - (yyval.Number) = (yyvsp[(1) - (1)].Number); + (yyval.Number) = (yyvsp[0].Number); yyRelPointer = &yyRelDay; - ;} + } + break; case 53: { - (yyval.Number) = (yyvsp[(1) - (1)].Number); + (yyval.Number) = (yyvsp[0].Number); yyRelPointer = &yyRelMonth; - ;} + } + break; case 54: { if (yyHaveTime && yyHaveDate && !yyHaveRel) { - yyYear = (yyvsp[(1) - (1)].Number); + yyYear = (yyvsp[0].Number); } else { yyHaveTime++; if (yyDigitCount <= 2) { - yyHour = (yyvsp[(1) - (1)].Number); + yyHour = (yyvsp[0].Number); yyMinutes = 0; } else { - yyHour = (yyvsp[(1) - (1)].Number) / 100; - yyMinutes = (yyvsp[(1) - (1)].Number) % 100; + yyHour = (yyvsp[0].Number) / 100; + yyMinutes = (yyvsp[0].Number) % 100; } yySeconds = 0; yyMeridian = MER24; } - ;} + } + break; case 55: { (yyval.Meridian) = MER24; - ;} + } + break; case 56: { - (yyval.Meridian) = (yyvsp[(1) - (1)].Meridian); - ;} + (yyval.Meridian) = (yyvsp[0].Meridian); + } + break; -/* Line 1267 of yacc.c. */ default: break; } + /* User semantic actions sometimes alter yychar, and that requires + that yytoken be updated with the new translation. We take the + approach of translating immediately before every use of yytoken. + One alternative is translating here after every semantic action, + but that translation would be missed if the semantic action invokes + YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or + if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an + incorrect destructor might then be invoked immediately. In the + case of YYERROR or YYBACKUP, subsequent parser actions might lead + to an incorrect destructor call or verbose syntax error message + before the lookahead is translated. */ YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); YYPOPSTACK (yylen); @@ -2075,7 +2073,7 @@ yyreduce: *++yyvsp = yyval; *++yylsp = yyloc; - /* Now `shift' the result of the reduction. Determine what state + /* Now 'shift' the result of the reduction. Determine what state that goes to, based on the state we popped back to and the rule number reduced by. */ @@ -2090,10 +2088,14 @@ yyreduce: goto yynewstate; -/*------------------------------------. -| yyerrlab -- here on detecting error | -`------------------------------------*/ +/*--------------------------------------. +| yyerrlab -- here on detecting error. | +`--------------------------------------*/ yyerrlab: + /* Make sure we have latest lookahead translation. See comments at + user semantic actions for why this is necessary. */ + yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar); + /* If not already recovering from an error, report this error. */ if (!yyerrstatus) { @@ -2101,62 +2103,61 @@ yyerrlab: #if ! YYERROR_VERBOSE yyerror (&yylloc, info, YY_("syntax error")); #else +# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \ + yyssp, yytoken) { - YYSIZE_T yysize = yysyntax_error (0, yystate, yychar); - if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM) - { - YYSIZE_T yyalloc = 2 * yysize; - if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM)) - yyalloc = YYSTACK_ALLOC_MAXIMUM; - if (yymsg != yymsgbuf) - YYSTACK_FREE (yymsg); - yymsg = (char *) YYSTACK_ALLOC (yyalloc); - if (yymsg) - yymsg_alloc = yyalloc; - else - { - yymsg = yymsgbuf; - yymsg_alloc = sizeof yymsgbuf; - } - } - - if (0 < yysize && yysize <= yymsg_alloc) - { - (void) yysyntax_error (yymsg, yystate, yychar); - yyerror (&yylloc, info, yymsg); - } - else - { - yyerror (&yylloc, info, YY_("syntax error")); - if (yysize != 0) - goto yyexhaustedlab; - } + char const *yymsgp = YY_("syntax error"); + int yysyntax_error_status; + yysyntax_error_status = YYSYNTAX_ERROR; + if (yysyntax_error_status == 0) + yymsgp = yymsg; + else if (yysyntax_error_status == 1) + { + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); + yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc); + if (!yymsg) + { + yymsg = yymsgbuf; + yymsg_alloc = sizeof yymsgbuf; + yysyntax_error_status = 2; + } + else + { + yysyntax_error_status = YYSYNTAX_ERROR; + yymsgp = yymsg; + } + } + yyerror (&yylloc, info, yymsgp); + if (yysyntax_error_status == 2) + goto yyexhaustedlab; } +# undef YYSYNTAX_ERROR #endif } - yyerror_range[0] = yylloc; + yyerror_range[1] = yylloc; if (yyerrstatus == 3) { - /* If just tried and failed to reuse look-ahead token after an - error, discard it. */ + /* If just tried and failed to reuse lookahead token after an + error, discard it. */ if (yychar <= YYEOF) - { - /* Return failure if at end of input. */ - if (yychar == YYEOF) - YYABORT; - } + { + /* Return failure if at end of input. */ + if (yychar == YYEOF) + YYABORT; + } else - { - yydestruct ("Error: discarding", - yytoken, &yylval, &yylloc, info); - yychar = YYEMPTY; - } + { + yydestruct ("Error: discarding", + yytoken, &yylval, &yylloc, info); + yychar = YYEMPTY; + } } - /* Else will try to reuse look-ahead token after shifting the error + /* Else will try to reuse lookahead token after shifting the error token. */ goto yyerrlab1; @@ -2172,8 +2173,7 @@ yyerrorlab: if (/*CONSTCOND*/ 0) goto yyerrorlab; - yyerror_range[0] = yylsp[1-yylen]; - /* Do not reclaim the symbols of the rule which action triggered + /* Do not reclaim the symbols of the rule whose action triggered this YYERROR. */ YYPOPSTACK (yylen); yylen = 0; @@ -2186,43 +2186,42 @@ yyerrorlab: | yyerrlab1 -- common code for both syntax error and YYERROR. | `-------------------------------------------------------------*/ yyerrlab1: - yyerrstatus = 3; /* Each real token shifted decrements this. */ + yyerrstatus = 3; /* Each real token shifted decrements this. */ for (;;) { yyn = yypact[yystate]; - if (yyn != YYPACT_NINF) - { - yyn += YYTERROR; - if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) - { - yyn = yytable[yyn]; - if (0 < yyn) - break; - } - } + if (!yypact_value_is_default (yyn)) + { + yyn += YYTERROR; + if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) + { + yyn = yytable[yyn]; + if (0 < yyn) + break; + } + } /* Pop the current state because it cannot handle the error token. */ if (yyssp == yyss) - YYABORT; + YYABORT; - yyerror_range[0] = *yylsp; + yyerror_range[1] = *yylsp; yydestruct ("Error: popping", - yystos[yystate], yyvsp, yylsp, info); + yystos[yystate], yyvsp, yylsp, info); YYPOPSTACK (1); yystate = *yyssp; YY_STACK_PRINT (yyss, yyssp); } - if (yyn == YYFINAL) - YYACCEPT; - + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN *++yyvsp = yylval; + YY_IGNORE_MAYBE_UNINITIALIZED_END - yyerror_range[1] = yylloc; + yyerror_range[2] = yylloc; /* Using YYLLOC is tempting, but would change the location of - the look-ahead. YYLOC is available though. */ - YYLLOC_DEFAULT (yyloc, (yyerror_range - 1), 2); + the lookahead. YYLOC is available though. */ + YYLLOC_DEFAULT (yyloc, yyerror_range, 2); *++yylsp = yyloc; /* Shift the error token. */ @@ -2246,7 +2245,7 @@ yyabortlab: yyresult = 1; goto yyreturn; -#ifndef yyoverflow +#if !defined yyoverflow || YYERROR_VERBOSE /*-------------------------------------------------. | yyexhaustedlab -- memory exhaustion comes here. | `-------------------------------------------------*/ @@ -2257,17 +2256,22 @@ yyexhaustedlab: #endif yyreturn: - if (yychar != YYEOF && yychar != YYEMPTY) - yydestruct ("Cleanup: discarding lookahead", - yytoken, &yylval, &yylloc, info); - /* Do not reclaim the symbols of the rule which action triggered + if (yychar != YYEMPTY) + { + /* Make sure we have latest lookahead translation. See comments at + user semantic actions for why this is necessary. */ + yytoken = YYTRANSLATE (yychar); + yydestruct ("Cleanup: discarding lookahead", + yytoken, &yylval, &yylloc, info); + } + /* Do not reclaim the symbols of the rule whose action triggered this YYABORT or YYACCEPT. */ YYPOPSTACK (yylen); YY_STACK_PRINT (yyss, yyssp); while (yyssp != yyss) { yydestruct ("Cleanup: popping", - yystos[*yyssp], yyvsp, yylsp, info); + yystos[*yyssp], yyvsp, yylsp, info); YYPOPSTACK (1); } #ifndef yyoverflow @@ -2278,13 +2282,10 @@ yyreturn: if (yymsg != yymsgbuf) YYSTACK_FREE (yymsg); #endif - /* Make sure YYID is used. */ - return YYID (yyresult); + return yyresult; } - - /* * Month and day table. */ @@ -2680,7 +2681,7 @@ TclDatelex( location->first_column = yyInput - info->dateStart; for ( ; ; ) { - while (TclIsSpaceProc(*yyInput)) { + while (TclIsSpaceProc(UCHAR(*yyInput))) { yyInput++; } @@ -2911,4 +2912,3 @@ TclClockOldscanObjCmd( * fill-column: 78 * End: */ - diff --git a/generic/tclGetDate.y b/generic/tclGetDate.y index da4c3fd..9c67227 100644 --- a/generic/tclGetDate.y +++ b/generic/tclGetDate.y @@ -897,7 +897,7 @@ TclDatelex( location->first_column = yyInput - info->dateStart; for ( ; ; ) { - while (isspace(UCHAR(*yyInput))) { + while (TclIsSpaceProc(UCHAR(*yyInput))) { yyInput++; } diff --git a/generic/tclObj.c b/generic/tclObj.c index 01a7498..5a8ce3b 100644 --- a/generic/tclObj.c +++ b/generic/tclObj.c @@ -2843,12 +2843,12 @@ Tcl_GetLongFromObj( value = (value << CHAR_BIT) | *bytes++; } if (big.sign) { - if (value <= 1 + (unsigned long)LONG_MAX) { + if (value <= 1 + (unsigned long)LONG_MAX) { *longPtr = - (long) value; return TCL_OK; } } else { - if (value <= (unsigned long)ULONG_MAX) { + if (value <= (unsigned long)ULONG_MAX) { *longPtr = (long) value; return TCL_OK; } -- cgit v0.12 From 58d332cff948e96f4a0f554ebe7ab3b43724669b Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Tue, 9 Oct 2018 21:13:42 +0000 Subject: Use TCL_THREADS in stead of defined(TCL_THREADS) everywhere, otherwise it will give unexpected results with TCL_THREADS=0 --- generic/tclZipfs.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c index d8a3f84..e60d94d 100644 --- a/generic/tclZipfs.c +++ b/generic/tclZipfs.c @@ -183,7 +183,7 @@ static const char drvletters[] = * Mutex to protect localtime(3) when no reentrant version available. */ -#if !defined(_WIN32) && !defined(HAVE_LOCALTIME_R) && defined(TCL_THREADS) +#if !defined(_WIN32) && !defined(HAVE_LOCALTIME_R) && TCL_THREADS TCL_DECLARE_MUTEX(localtimeMutex) #endif /* !_WIN32 && !HAVE_LOCALTIME_R && TCL_THREADS */ @@ -477,7 +477,7 @@ static Tcl_ChannelType ZipChannelType = { TCL_DECLARE_MUTEX(ZipFSMutex) -#ifdef TCL_THREADS +#if TCL_THREADS static Tcl_Condition ZipFSCond; @@ -568,7 +568,7 @@ ToDosTime( { struct tm *tmp, tm; -#if !defined(TCL_THREADS) || defined(_WIN32) +#if !TCL_THREADS || defined(_WIN32) /* Not threaded, or on Win32 which uses thread local storage */ tmp = localtime(&when); tm = *tmp; @@ -592,7 +592,7 @@ ToDosDate( { struct tm *tmp, tm; -#if !defined(TCL_THREADS) || defined(_WIN32) +#if !TCL_THREADS || defined(_WIN32) /* Not threaded, or on Win32 which uses thread local storage */ tmp = localtime(&when); tm = *tmp; @@ -1498,7 +1498,7 @@ ZipFSCatalogFilesystem( static void ZipfsSetup(void) { -#ifdef TCL_THREADS +#if TCL_THREADS static const Tcl_Time t = { 0, 0 }; /* -- cgit v0.12 From 5719d6ca309368052fc677e594c4c480e15ae526 Mon Sep 17 00:00:00 2001 From: dkf Date: Thu, 11 Oct 2018 07:24:40 +0000 Subject: Put documented [zipfs find] in ensemble. Add examples to docs. --- doc/zipfs.n | 80 +++++++++++++++++++++++++++++++++++++++++++----------- generic/tclZipfs.c | 17 ++++++++++-- tests/zipfs.test | 4 +-- 3 files changed, 80 insertions(+), 21 deletions(-) diff --git a/doc/zipfs.n b/doc/zipfs.n index 705faa1..99ab1d3 100644 --- a/doc/zipfs.n +++ b/doc/zipfs.n @@ -17,7 +17,7 @@ zipfs \- Mount and work with ZIP files within Tcl \fBpackage require zipfs \fR?\fB1.0\fR? .sp \fBzipfs exists\fR \fIfilename\fR -\fBzipfs find\fR \fIdir\fR +\fBzipfs find\fR \fIdirectoryName\fR \fBzipfs info\fR \fIfilename\fR \fBzipfs list\fR ?(\fB\-glob\fR|\fB\-regexp\fR)? ?\fIpattern\fR? \fBzipfs mkimg\fR \fIoutfile indir\fR ?\fIstrip\fR? ?\fIpassword\fR? ?\fIinfile\fR? @@ -27,6 +27,12 @@ zipfs \- Mount and work with ZIP files within Tcl \fBzipfs root\fR \fBzipfs unmount\fR \fImountpoint\fR .fi +'\" The following subcommands are *UNDOCUMENTED* (the list here is not documentation) +'\" \fBzipfs canonical\fR ?\fImntpnt\fR? \fIfilename\fR ?\fIZIPFS\fR? +'\" \fBzipfs lmkimg\fR \fIoutfile inlist\fR ?\fIpassword infile\fR? +'\" \fBzipfs lmkzip\fR \fIoutfile inlist\fR ?\fIpassword\fR? +'\" \fBzipfs mount_data\fR ?\fImountpoint\fR? ?\fIdata\fR? +'\" \fBzipfs tcl_library\fR .BE .SH DESCRIPTION .PP @@ -38,10 +44,10 @@ contents of a ZIP file as a virtual file system. . Return 1 if the given filename exists in the mounted zipfs and 0 if it does not. .TP -\fBzipfs find\fR \fIdir\fR +\fBzipfs find\fR \fIdirectoryName\fR . -Recursively lists files including and below the directory \fIdir\fR. The -result list consists of relative path names starting from the given +Recursively lists files including and below the directory \fIdirectoryName\fR. +The result list consists of relative path names starting from the given directory. This command is also used by the \fBzipfs mkzip\fR and \fBzipfs mkimg\fR commands. .TP @@ -79,6 +85,13 @@ in \fIzipfile\fR will appear to Tcl to be regular files at the mount point. With no \fIzipfile\fR, returns the zipfile mounted at \fImountpoint\fR. With no \fImountpoint\fR, return all zipfile/mount pairs. If \fImountpoint\fR is specified as an empty string, mount on file path. +.PP +\fBNB:\fR because the current working directory is a concept maintained by the +operating system, using \fBcd\fR into a mounted archive will only work in the +current process, and then not entirely consistently (e.g., if a shared library +uses direct access to the OS rather than through Tcl's filesystem API, it will +not see the current directory as being inside the mount and will not be able +to access the files inside the mount). .RE .TP \fBzipfs root\fR @@ -100,21 +113,25 @@ archives as Tcl applications. \fBzipfs mkimg\fR \fIoutfile indir\fR ?\fIstrip\fR? ?\fIpassword\fR? ?\fIinfile\fR? . Creates an image (potentially a new executable file) similar to \fBzipfs -mkzip\fR. If the \fIinfile\fR parameter is specified, this file is prepended -in front of the ZIP archive, otherwise the file returned by -\fBinfo nameofexecutable\fR (i.e., the executable file of the running process) -is used. If the \fIpassword\fR parameter is not empty, an obfuscated version -of that password is placed between the image and ZIP chunks of the output file -and the contents of the ZIP chunk are protected with that password. +mkzip\fR; see that subcommand for a description of most parameters to this +subcommand, as they behave identically here. .RS .PP -Caution: highly experimental, not usable on Android, only partially tested on -Linux and Windows. +If the \fIinfile\fR parameter is specified, this file is prepended in front of +the ZIP archive, otherwise the file returned by \fBinfo nameofexecutable\fR +(i.e., the executable file of the running process) is used. If the +\fIpassword\fR parameter is not empty, an obfuscated version of that password +(see \fBzipfs mkkey\fR) is placed between the image and ZIP chunks of the +output file and the contents of the ZIP chunk are protected with that +password. +.PP +\fBCaution:\fR highly experimental, not usable on Android, only partially +tested on Linux and Windows. .RE .TP \fBzipfs mkkey\fR \fIpassword\fR . -For the clear text \fIpassword\fR argument, an obfuscated string version is +Given the clear text \fIpassword\fR argument, an obfuscated string version is returned with the same format used in the \fBzipfs mkimg\fR command. .TP \fBzipfs mkzip\fR \fIoutfile indir\fR ?\fIstrip\fR? ?\fIpassword\fR? @@ -123,12 +140,43 @@ Creates a ZIP archive file named \fIoutfile\fR from the contents of the input directory \fIindir\fR (contained regular files only) with optional ZIP password \fIpassword\fR. While processing the files below \fIindir\fR the optional file name prefix given in \fIstrip\fR is stripped off the beginning -of the respective file name. +of the respective file name. When stripping, it is common to remove either +the whole source directory name or the name of its parent directory. .RS .PP -Caution: the choice of the \fIindir\fR parameter (less the optional stripped -prefix) determines the later root name of the archive's content. +\fBCaution:\fR the choice of the \fIindir\fR parameter (less the optional +stripped prefix) determines the later root name of the archive's content. .RE +.SH "EXAMPLES" +.PP +Mounting an ZIP archive as an application directory and running code out of it +before unmounting it again: +.PP +.CS +set zip myApp.zip +set base [file join [\fbzipfs root\fR] myApp] + +\fBzipfs mount\fR $base $zip +\fI# $base now has the contents of myApp.zip\fR + +source [file join $base app.tcl] +\fI# use the contents, load libraries from it, etc...\fR + +\fBzipfs unmount\fR $zip +.CE +.PP +Creating a ZIP archive, given that a directory exists containing the content +to put in the archive. Note that the source directory is given twice, in order +to strip the exterior directory name from each filename in the archive. +.PP +.CS +set sourceDirectory [file normalize myApp] +set targetZip myApp.zip + +\fBzipfs mkzip\fR $targetZip $sourceDirectory $sourceDirectory +.CE +'\" WANTED: How to use the passwords +'\" WANTED: How to package an application .SH "SEE ALSO" tclsh(1), file(n), zlib(n) .SH "KEYWORDS" diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c index e60d94d..c9b1a63 100644 --- a/generic/tclZipfs.c +++ b/generic/tclZipfs.c @@ -4737,8 +4737,8 @@ TclZipfs_Init( " }\n" " return $result\n" "}\n" - "proc ::tcl::zipfs::find dir {\n" - " return [lsort [Find $dir]]\n" + "proc ::tcl::zipfs::find {directoryName} {\n" + " return [lsort [Find $directoryName]]\n" "}\n"; /* @@ -4753,11 +4753,22 @@ TclZipfs_Init( Unlock(); if (interp) { + Tcl_Command ensemble; + Tcl_Obj *mapObj; + Tcl_EvalEx(interp, findproc, -1, TCL_EVAL_GLOBAL); Tcl_LinkVar(interp, "::tcl::zipfs::wrmax", (char *) &ZipFS.wrmax, TCL_LINK_INT); - TclMakeEnsemble(interp, "zipfs", + ensemble = TclMakeEnsemble(interp, "zipfs", Tcl_IsSafe(interp) ? (initMap + 4) : initMap); + + /* + * Add the [zipfs find] subcommand. + */ + + Tcl_GetEnsembleMappingDict(NULL, ensemble, &mapObj); + Tcl_DictObjPut(NULL, mapObj, Tcl_NewStringObj("find", -1), + Tcl_NewStringObj("::tcl::zipfs::find", -1)); Tcl_PkgProvide(interp, "zipfs", "2.0"); } return TCL_OK; diff --git a/tests/zipfs.test b/tests/zipfs.test index 631b525..abf9d3f 100644 --- a/tests/zipfs.test +++ b/tests/zipfs.test @@ -247,7 +247,7 @@ test zipfs-3.1 {zipfs in child interpreters} -constraints zipfs -setup { } } -returnCodes error -cleanup { interp delete $interp -} -result {unknown or ambiguous subcommand "?": must be canonical, exists, info, list, lmkimg, lmkzip, mkimg, mkkey, mkzip, mount, mount_data, root, tcl_library, or unmount} +} -result {unknown or ambiguous subcommand "?": must be canonical, exists, find, info, list, lmkimg, lmkzip, mkimg, mkkey, mkzip, mount, mount_data, root, tcl_library, or unmount} test zipfs-3.2 {zipfs in child interpreters} -constraints zipfs -setup { set interp [interp create] } -body { @@ -265,7 +265,7 @@ test zipfs-3.3 {zipfs in child interpreters} -constraints zipfs -setup { } } -returnCodes error -cleanup { interp delete $safe -} -result {unknown or ambiguous subcommand "?": must be canonical, exists, info, list, lmkimg, lmkzip, mkimg, mkkey, mkzip, mount, mount_data, root, tcl_library, or unmount} +} -result {unknown or ambiguous subcommand "?": must be canonical, exists, find, info, list, lmkimg, lmkzip, mkimg, mkkey, mkzip, mount, mount_data, root, tcl_library, or unmount} test zipfs-3.4 {zipfs in child interpreters} -constraints zipfs -setup { set safe [interp create -safe] } -body { -- cgit v0.12 From 45e6ca04f5132d1f57cee45a475fe1d8371de5e9 Mon Sep 17 00:00:00 2001 From: dkf Date: Fri, 12 Oct 2018 07:36:19 +0000 Subject: Document [zipfs canonical] and add examples of how to use passwords. --- doc/zipfs.n | 30 ++++++++++++++++++++++++++++-- generic/tclZipfs.c | 10 +++++----- 2 files changed, 33 insertions(+), 7 deletions(-) diff --git a/doc/zipfs.n b/doc/zipfs.n index 99ab1d3..6e3d6ff 100644 --- a/doc/zipfs.n +++ b/doc/zipfs.n @@ -16,6 +16,7 @@ zipfs \- Mount and work with ZIP files within Tcl .nf \fBpackage require zipfs \fR?\fB1.0\fR? .sp +\fBzipfs canonical\fR ?\fImntpnt\fR? \fIfilename\fR ?\fIZIPFS\fR? \fBzipfs exists\fR \fIfilename\fR \fBzipfs find\fR \fIdirectoryName\fR \fBzipfs info\fR \fIfilename\fR @@ -28,7 +29,6 @@ zipfs \- Mount and work with ZIP files within Tcl \fBzipfs unmount\fR \fImountpoint\fR .fi '\" The following subcommands are *UNDOCUMENTED* (the list here is not documentation) -'\" \fBzipfs canonical\fR ?\fImntpnt\fR? \fIfilename\fR ?\fIZIPFS\fR? '\" \fBzipfs lmkimg\fR \fIoutfile inlist\fR ?\fIpassword infile\fR? '\" \fBzipfs lmkzip\fR \fIoutfile inlist\fR ?\fIpassword\fR? '\" \fBzipfs mount_data\fR ?\fImountpoint\fR? ?\fIdata\fR? @@ -38,7 +38,17 @@ zipfs \- Mount and work with ZIP files within Tcl .PP The \fBzipfs\fR command (the sole public command provided by the built-in package with the same name) provides Tcl with the ability to mount the -contents of a ZIP file as a virtual file system. +contents of a ZIP archive file as a virtual file system. ZIP archives support +simple encryption, sufficient to prevent casual inspection of their contents +but not able to prevent access by even a moderately determined attacker. +.TP +\fBzipfs canonical\fR ?\fImountpoint\fR? \fIfilename\fR ?\fIinZipfs\fR? +. +This takes the name of a file, \fIfilename\fR, and produces where it would be +mapped into a zipfs mount as its result. If specified, \fImountpoint\fR says +within which mount the mapping will be done; if omitted, the main root of the +zipfs system is used. The \fIinZipfs\fR argument is a an optional boolean +which controls whether to fully canonicalise the name; it defaults to true. .TP \fBzipfs exists\fR \fIfilename\fR . @@ -175,6 +185,22 @@ set targetZip myApp.zip \fBzipfs mkzip\fR $targetZip $sourceDirectory $sourceDirectory .CE +.PP +Encryption can be applied to ZIP archives by providing a password when +building the ZIP and when mounting it. +.PP +.CS +set zip myApp.zip +set sourceDir [file normalize myApp] +set password "hunter2" +set base [file join [\fbzipfs root\fR] myApp] + +# Create with password +\fBzipfs mkzip\fR $targetZip $sourceDir $sourceDir $password + +# Mount with password +\fBzipfs mount\fR $base $zip $password +.CE '\" WANTED: How to use the passwords '\" WANTED: How to package an application .SH "SEE ALSO" diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c index c9b1a63..7802c45 100644 --- a/generic/tclZipfs.c +++ b/generic/tclZipfs.c @@ -183,7 +183,7 @@ static const char drvletters[] = * Mutex to protect localtime(3) when no reentrant version available. */ -#if !defined(_WIN32) && !defined(HAVE_LOCALTIME_R) && TCL_THREADS +#if !defined(_WIN32) && !defined(HAVE_LOCALTIME_R) && inZipfsTCL_THREADS TCL_DECLARE_MUTEX(localtimeMutex) #endif /* !_WIN32 && !HAVE_LOCALTIME_R && TCL_THREADS */ @@ -665,7 +665,7 @@ CanonicalPath( const char *root, const char *tail, Tcl_DString *dsPtr, - int ZIPFSPATH) + int inZipfs) { char *path; int i, j, c, isUNC = 0, isVfs = 0, n = 0; @@ -742,7 +742,7 @@ CanonicalPath( memcpy(path, tail, j); break; default: - if (ZIPFSPATH) { + if (inZipfs) { Tcl_DStringSetLength(dsPtr, i + j + ZIPFS_VOLUME_LEN); path = Tcl_DStringValue(dsPtr); memcpy(path, ZIPFS_VOLUME, ZIPFS_VOLUME_LEN); @@ -765,7 +765,7 @@ CanonicalPath( } #endif /* _WIN32 */ - if (ZIPFSPATH) { + if (inZipfs) { n = ZIPFS_VOLUME_LEN; } else { n = 0; @@ -2911,7 +2911,7 @@ ZipFSCanonicalObjCmd( Tcl_DString dPath; if (objc < 2 || objc > 4) { - Tcl_WrongNumArgs(interp, 1, objv, "?mntpnt? filename ?ZIPFS?"); + Tcl_WrongNumArgs(interp, 1, objv, "?mountpoint? filename ?inZipfs?"); return TCL_ERROR; } Tcl_DStringInit(&dPath); -- cgit v0.12 From 13e35220c21ac2798f32b53f4e052014b17e4f4b Mon Sep 17 00:00:00 2001 From: dkf Date: Fri, 12 Oct 2018 09:52:56 +0000 Subject: Better document how to package an executable script in a zipfs --- doc/zipfs.n | 38 +++++++++++++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 3 deletions(-) diff --git a/doc/zipfs.n b/doc/zipfs.n index 6e3d6ff..d82b4d3 100644 --- a/doc/zipfs.n +++ b/doc/zipfs.n @@ -135,6 +135,13 @@ the ZIP archive, otherwise the file returned by \fBinfo nameofexecutable\fR output file and the contents of the ZIP chunk are protected with that password. .PP +If there is a file, \fBmain.tcl\fR, in the root directory of the resulting +archive and the image file that the archive is attached to is a \fBtclsh\fR +(or \fBwish\fR) instance (true by default, but depends on your configuration), +then the resulting image is an executable that will \fBsource\fR the script in +that \fBmain.tcl\fR after mounting the ZIP archive, and will \fBexit\fR once +that script has been executed. +.PP \fBCaution:\fR highly experimental, not usable on Android, only partially tested on Linux and Windows. .RE @@ -167,10 +174,10 @@ set zip myApp.zip set base [file join [\fbzipfs root\fR] myApp] \fBzipfs mount\fR $base $zip -\fI# $base now has the contents of myApp.zip\fR +# $base now has the contents of myApp.zip source [file join $base app.tcl] -\fI# use the contents, load libraries from it, etc...\fR +# use the contents, load libraries from it, etc... \fBzipfs unmount\fR $zip .CE @@ -201,10 +208,35 @@ set base [file join [\fbzipfs root\fR] myApp] # Mount with password \fBzipfs mount\fR $base $zip $password .CE +.PP +When creating an executable image with a password, the password is placed +within the executable in a shrouded form so that the application can read +files inside the embedded ZIP archive yet casual inspection cannot read it. +.PP +.CS +set appDir [file normalize myApp] +set img "myApp.bin" +set password "hunter2" + +# Create some simple content to define a basic application +file mkdir $appDir +set f [open $appDir/main.tcl] +puts $f { + puts "Hi. This is [info script]" +} +close $f + +# Create the executable +\fBzipfs mkimg\fR $img $appDir $appDir $password + +# Launch the executable, printing its output to stdout +exec $img >@stdout +# prints: \fI Hi. This is //zipfs:/app/main.tcl\fR +.CE '\" WANTED: How to use the passwords '\" WANTED: How to package an application .SH "SEE ALSO" -tclsh(1), file(n), zlib(n) +tclsh(1), file(n), zipfs(3), zlib(n) .SH "KEYWORDS" compress, filesystem, zip '\" Local Variables: -- cgit v0.12 From 621251ae2e2fd50bbee979906ce537aae53f1e33 Mon Sep 17 00:00:00 2001 From: dkf Date: Fri, 12 Oct 2018 12:07:13 +0000 Subject: Added docs for [zipfs lmkimg] and [zipfs lmkzip] --- doc/zipfs.n | 46 ++++++++++++++++++++++++++++++---------------- 1 file changed, 30 insertions(+), 16 deletions(-) diff --git a/doc/zipfs.n b/doc/zipfs.n index d82b4d3..9ed136d 100644 --- a/doc/zipfs.n +++ b/doc/zipfs.n @@ -21,6 +21,8 @@ zipfs \- Mount and work with ZIP files within Tcl \fBzipfs find\fR \fIdirectoryName\fR \fBzipfs info\fR \fIfilename\fR \fBzipfs list\fR ?(\fB\-glob\fR|\fB\-regexp\fR)? ?\fIpattern\fR? +\fBzipfs lmkimg\fR \fIoutfile inlist\fR ?\fIpassword infile\fR? +\fBzipfs lmkzip\fR \fIoutfile inlist\fR ?\fIpassword\fR? \fBzipfs mkimg\fR \fIoutfile indir\fR ?\fIstrip\fR? ?\fIpassword\fR? ?\fIinfile\fR? \fBzipfs mkkey\fR \fIpassword\fR \fBzipfs mkzip\fR \fIoutfile indir\fR ?\fIstrip\fR? ?\fIpassword\fR? @@ -29,8 +31,6 @@ zipfs \- Mount and work with ZIP files within Tcl \fBzipfs unmount\fR \fImountpoint\fR .fi '\" The following subcommands are *UNDOCUMENTED* (the list here is not documentation) -'\" \fBzipfs lmkimg\fR \fIoutfile inlist\fR ?\fIpassword infile\fR? -'\" \fBzipfs lmkzip\fR \fIoutfile inlist\fR ?\fIpassword\fR? '\" \fBzipfs mount_data\fR ?\fImountpoint\fR? ?\fIdata\fR? '\" \fBzipfs tcl_library\fR .BE @@ -120,11 +120,25 @@ Unmounts a previously mounted ZIP archive mounted to \fImountpoint\fR. This package also provides several commands to aid the creation of ZIP archives as Tcl applications. .TP +\fBzipfs mkzip\fR \fIoutfile indir\fR ?\fIstrip\fR? ?\fIpassword\fR? +. +Creates a ZIP archive file named \fIoutfile\fR from the contents of the input +directory \fIindir\fR (contained regular files only) with optional ZIP +password \fIpassword\fR. While processing the files below \fIindir\fR the +optional file name prefix given in \fIstrip\fR is stripped off the beginning +of the respective file name. When stripping, it is common to remove either +the whole source directory name or the name of its parent directory. +.RS +.PP +\fBCaution:\fR the choice of the \fIindir\fR parameter (less the optional +stripped prefix) determines the later root name of the archive's content. +.RE +.TP \fBzipfs mkimg\fR \fIoutfile indir\fR ?\fIstrip\fR? ?\fIpassword\fR? ?\fIinfile\fR? . Creates an image (potentially a new executable file) similar to \fBzipfs -mkzip\fR; see that subcommand for a description of most parameters to this -subcommand, as they behave identically here. +mkzip\fR; see that command for a description of most parameters to this +command, as they behave identically here. .RS .PP If the \fIinfile\fR parameter is specified, this file is prepended in front of @@ -151,19 +165,19 @@ tested on Linux and Windows. Given the clear text \fIpassword\fR argument, an obfuscated string version is returned with the same format used in the \fBzipfs mkimg\fR command. .TP -\fBzipfs mkzip\fR \fIoutfile indir\fR ?\fIstrip\fR? ?\fIpassword\fR? +\fBzipfs lmkimg\fR \fIoutfile inlist\fR ?\fIpassword infile\fR? . -Creates a ZIP archive file named \fIoutfile\fR from the contents of the input -directory \fIindir\fR (contained regular files only) with optional ZIP -password \fIpassword\fR. While processing the files below \fIindir\fR the -optional file name prefix given in \fIstrip\fR is stripped off the beginning -of the respective file name. When stripping, it is common to remove either -the whole source directory name or the name of its parent directory. -.RS -.PP -\fBCaution:\fR the choice of the \fIindir\fR parameter (less the optional -stripped prefix) determines the later root name of the archive's content. -.RE +This command is like \fBzipfs mkimg\fR, but instead of an input directory, +\fIinlist\fR must be a Tcl list where the odd elements are the names of files +to be copied into the archive in the image, and the even elements are their +respective names within that archive. +.TP +\fBzipfs lmkzip\fR \fIoutfile inlist\fR ?\fIpassword\fR? +. +This command is like \fBzipfs mkzip\fR, but instead of an input directory, +\fIinlist\fR must be a Tcl list where the odd elements are the names of files +to be copied into the archive, and the even elements are their respective +names within that archive. .SH "EXAMPLES" .PP Mounting an ZIP archive as an application directory and running code out of it -- cgit v0.12 From cc945fabb73c3733169f7441140a7b2f2c57572c Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Fri, 12 Oct 2018 17:54:42 +0000 Subject: Fix test for UNICODE in win/tclAppInit.c. No longer check for "tclsh install", because tclsh is not compiled with that. Fix minizip.c compilation on systems without open64() --- compat/zlib/contrib/minizip/minizip.c | 4 +- generic/tclZipfs.c | 2 +- generic/tclZlib.c | 6 +-- unix/Makefile.in | 5 ++- unix/configure | 71 ++++++++++++++--------------------- unix/tcl.m4 | 67 ++++++++++++++------------------- win/Makefile.in | 5 ++- win/configure | 69 +++++++++++++--------------------- win/tcl.m4 | 67 ++++++++++++++------------------- win/tclAppInit.c | 2 +- 10 files changed, 124 insertions(+), 174 deletions(-) diff --git a/compat/zlib/contrib/minizip/minizip.c b/compat/zlib/contrib/minizip/minizip.c index b5c67cc..17582d0 100644 --- a/compat/zlib/contrib/minizip/minizip.c +++ b/compat/zlib/contrib/minizip/minizip.c @@ -27,7 +27,7 @@ #endif #endif -#ifdef __APPLE__ +#if defined(__APPLE__) || defined(IOAPI_NO_64) // In darwin and perhaps other BSD variants off_t is a 64 bit value, hence no need for specific 64 bit functions #define FOPEN_FUNC(filename, mode) fopen(filename, mode) #define FTELLO_FUNC(stream) ftello(stream) @@ -359,7 +359,7 @@ void addFileToZip(zipFile zf, const char *filenameinzip, const char *password, i void addPathToZip(zipFile zf, const char *filenameinzip, const char *password, int opt_exclude_path,int opt_compress_level) { tinydir_dir dir; int i; - char *newname[512]; + char newname[512]; tinydir_open_sorted(&dir, filenameinzip); diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c index 7802c45..bd2ae13 100644 --- a/generic/tclZipfs.c +++ b/generic/tclZipfs.c @@ -183,7 +183,7 @@ static const char drvletters[] = * Mutex to protect localtime(3) when no reentrant version available. */ -#if !defined(_WIN32) && !defined(HAVE_LOCALTIME_R) && inZipfsTCL_THREADS +#if !defined(_WIN32) && !defined(HAVE_LOCALTIME_R) && TCL_THREADS TCL_DECLARE_MUTEX(localtimeMutex) #endif /* !_WIN32 && !HAVE_LOCALTIME_R && TCL_THREADS */ diff --git a/generic/tclZlib.c b/generic/tclZlib.c index 9bad36d..d4a8ecb 100644 --- a/generic/tclZlib.c +++ b/generic/tclZlib.c @@ -117,7 +117,7 @@ typedef struct { z_stream outStream; /* Structure used by zlib for compression of * output. */ char *inBuffer, *outBuffer; /* Working buffers. */ - int inAllocated, outAllocated; + size_t inAllocated, outAllocated; /* Sizes of working buffers. */ GzipHeader inHeader; /* Header read from input stream, when * decompressing a gzip stream. */ @@ -1515,7 +1515,7 @@ Tcl_ZlibStreamGet( Tcl_ListObjIndex(NULL, zshPtr->outData, 0, &itemObj); itemPtr = Tcl_GetByteArrayFromObj(itemObj, &itemLen); if (itemLen-zshPtr->outPos >= count-dataPos) { - unsigned len = count - dataPos; + size_t len = count - dataPos; memcpy(dataPtr + dataPos, itemPtr + zshPtr->outPos, len); zshPtr->outPos += len; @@ -1524,7 +1524,7 @@ Tcl_ZlibStreamGet( zshPtr->outPos = 0; } } else { - unsigned len = itemLen - zshPtr->outPos; + size_t len = itemLen - zshPtr->outPos; memcpy(dataPtr + dataPos, itemPtr + zshPtr->outPos, len); dataPos += len; diff --git a/unix/Makefile.in b/unix/Makefile.in index d5324dc..487ae61 100644 --- a/unix/Makefile.in +++ b/unix/Makefile.in @@ -691,6 +691,7 @@ ${LIB_FILE}: ${STUB_LIB_FILE} ${OBJS} ${TCL_ZIP_FILE} @MAKE_LIB@ ifeq (${ZIPFS_BUILD},1) cat ${TCL_ZIP_FILE} >> ${LIB_FILE} + ${NATIVE_ZIP} -A ${LIB_FILE} endif ${STUB_LIB_FILE}: ${STUB_LIB_OBJS} @@ -1834,7 +1835,7 @@ deflate.$(HOST_OBJEXT): $(HOST_CC) -o $@ -I$(ZLIB_DIR) -c $(ZLIB_DIR)/deflate.c ioapi.$(HOST_OBJEXT): - $(HOST_CC) -o $@ -I$(ZLIB_DIR) -I$(ZLIB_DIR)/contrib/minizip -c \ + $(HOST_CC) -o $@ -DIOAPI_NO_64 -I$(ZLIB_DIR) -I$(ZLIB_DIR)/contrib/minizip -c \ $(ZLIB_DIR)/contrib/minizip/ioapi.c infback.$(HOST_OBJEXT): @@ -1863,7 +1864,7 @@ zutil.$(HOST_OBJEXT): $(HOST_CC) -o $@ -I$(ZLIB_DIR) -c $(ZLIB_DIR)/zutil.c minizip.$(HOST_OBJEXT): - $(HOST_CC) -o $@ -I$(ZLIB_DIR) -I$(ZLIB_DIR)/contrib/minizip -c \ + $(HOST_CC) -o $@ -DIOAPI_NO_64 -I$(ZLIB_DIR) -I$(ZLIB_DIR)/contrib/minizip -c \ $(ZLIB_DIR)/contrib/minizip/minizip.c minizip${HOST_EXEEXT}: $(MINIZIP_OBJS) diff --git a/unix/configure b/unix/configure index aa7953b..2af5144 100755 --- a/unix/configure +++ b/unix/configure @@ -10209,61 +10209,46 @@ $as_echo "$bfd_cv_build_exeext" >&6; } ZIP_PROG_OPTIONS="" ZIP_PROG_VFSSEARCH="" ZIP_INSTALL_OBJS="" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for zip" >&5 -$as_echo_n "checking for zip... " >&6; } - # If our native tclsh processes the "install" command line option - # we can use it to mint zip files - if $TCLSH_PROG install; then : - - ZIP_PROG=${TCLSH_PROG} - ZIP_PROG_OPTIONS="install mkzip" - ZIP_PROG_VFSSEARCH="." - { $as_echo "$as_me:${as_lineno-$LINENO}: result: Can use Native Tclsh for Zip encoding" >&5 -$as_echo "Can use Native Tclsh for Zip encoding" >&6; } -fi - - if test "x$ZIP_PROG" = "x" ; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for zip" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for zip" >&5 $as_echo_n "checking for zip... " >&6; } - if ${ac_cv_path_zip+:} false; then : + if ${ac_cv_path_zip+:} false; then : $as_echo_n "(cached) " >&6 else - search_path=`echo ${PATH} | sed -e 's/:/ /g'` - for dir in $search_path ; do - for j in `ls -r $dir/zip 2> /dev/null` \ - `ls -r $dir/zip 2> /dev/null` ; do - if test x"$ac_cv_path_zip" = x ; then - if test -f "$j" ; then - ac_cv_path_zip=$j - break - fi + search_path=`echo ${PATH} | sed -e 's/:/ /g'` + for dir in $search_path ; do + for j in `ls -r $dir/zip 2> /dev/null` \ + `ls -r $dir/zip 2> /dev/null` ; do + if test x"$ac_cv_path_zip" = x ; then + if test -f "$j" ; then + ac_cv_path_zip=$j + break fi - done + fi done + done fi - if test -f "$ac_cv_path_zip" ; then - ZIP_PROG="$ac_cv_path_zip " - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ZIP_PROG" >&5 + if test -f "$ac_cv_path_zip" ; then + ZIP_PROG="$ac_cv_path_zip " + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ZIP_PROG" >&5 $as_echo "$ZIP_PROG" >&6; } - ZIP_PROG_OPTIONS="-rq" - ZIP_PROG_VFSSEARCH="." - { $as_echo "$as_me:${as_lineno-$LINENO}: result: Found INFO Zip in environment" >&5 + ZIP_PROG_OPTIONS="-rq" + ZIP_PROG_VFSSEARCH="." + { $as_echo "$as_me:${as_lineno-$LINENO}: result: Found INFO Zip in environment" >&5 $as_echo "Found INFO Zip in environment" >&6; } - # Use standard arguments for zip - else - # It is not an error if an installed version of Zip can't be located. - # We can use the locally distributed minizip instead - ZIP_PROG="../minizip${EXEEXT_FOR_BUILD}" - ZIP_PROG_OPTIONS="-o -r" - ZIP_PROG_VFSSEARCH="." - ZIP_INSTALL_OBJS="minizip${EXEEXT_FOR_BUILD}" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: No zip found on PATH building minizip" >&5 -$as_echo "No zip found on PATH building minizip" >&6; } - fi + # Use standard arguments for zip + else + # It is not an error if an installed version of Zip can't be located. + # We can use the locally distributed minizip instead + ZIP_PROG="../minizip${EXEEXT_FOR_BUILD}" + ZIP_PROG_OPTIONS="-o -r" + ZIP_PROG_VFSSEARCH="." + ZIP_INSTALL_OBJS="minizip${EXEEXT_FOR_BUILD}" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: No zip found on PATH. Building minizip" >&5 +$as_echo "No zip found on PATH. Building minizip" >&6; } fi diff --git a/unix/tcl.m4 b/unix/tcl.m4 index 44403dc..b77387a 100644 --- a/unix/tcl.m4 +++ b/unix/tcl.m4 @@ -3047,48 +3047,37 @@ AC_DEFUN([SC_ZIPFS_SUPPORT], [ ZIP_PROG_OPTIONS="" ZIP_PROG_VFSSEARCH="" ZIP_INSTALL_OBJS="" - AC_MSG_CHECKING([for zip]) - # If our native tclsh processes the "install" command line option - # we can use it to mint zip files - AS_IF([$TCLSH_PROG install],[ - ZIP_PROG=${TCLSH_PROG} - ZIP_PROG_OPTIONS="install mkzip" - ZIP_PROG_VFSSEARCH="." - AC_MSG_RESULT([Can use Native Tclsh for Zip encoding]) - ]) - if test "x$ZIP_PROG" = "x" ; then - AC_MSG_CHECKING([for zip]) - AC_CACHE_VAL(ac_cv_path_zip, [ - search_path=`echo ${PATH} | sed -e 's/:/ /g'` - for dir in $search_path ; do - for j in `ls -r $dir/zip 2> /dev/null` \ - `ls -r $dir/zip 2> /dev/null` ; do - if test x"$ac_cv_path_zip" = x ; then - if test -f "$j" ; then - ac_cv_path_zip=$j - break - fi + AC_MSG_CHECKING([for zip]) + AC_CACHE_VAL(ac_cv_path_zip, [ + search_path=`echo ${PATH} | sed -e 's/:/ /g'` + for dir in $search_path ; do + for j in `ls -r $dir/zip 2> /dev/null` \ + `ls -r $dir/zip 2> /dev/null` ; do + if test x"$ac_cv_path_zip" = x ; then + if test -f "$j" ; then + ac_cv_path_zip=$j + break fi - done - done - ]) - if test -f "$ac_cv_path_zip" ; then - ZIP_PROG="$ac_cv_path_zip " - AC_MSG_RESULT([$ZIP_PROG]) - ZIP_PROG_OPTIONS="-rq" - ZIP_PROG_VFSSEARCH="." - AC_MSG_RESULT([Found INFO Zip in environment]) - # Use standard arguments for zip - else - # It is not an error if an installed version of Zip can't be located. - # We can use the locally distributed minizip instead - ZIP_PROG="../minizip${EXEEXT_FOR_BUILD}" - ZIP_PROG_OPTIONS="-o -r" - ZIP_PROG_VFSSEARCH="." - ZIP_INSTALL_OBJS="minizip${EXEEXT_FOR_BUILD}" - AC_MSG_RESULT([No zip found on PATH building minizip]) fi + done + done + ]) + if test -f "$ac_cv_path_zip" ; then + ZIP_PROG="$ac_cv_path_zip " + AC_MSG_RESULT([$ZIP_PROG]) + ZIP_PROG_OPTIONS="-rq" + ZIP_PROG_VFSSEARCH="." + AC_MSG_RESULT([Found INFO Zip in environment]) + # Use standard arguments for zip + else + # It is not an error if an installed version of Zip can't be located. + # We can use the locally distributed minizip instead + ZIP_PROG="../minizip${EXEEXT_FOR_BUILD}" + ZIP_PROG_OPTIONS="-o -r" + ZIP_PROG_VFSSEARCH="." + ZIP_INSTALL_OBJS="minizip${EXEEXT_FOR_BUILD}" + AC_MSG_RESULT([No zip found on PATH. Building minizip]) fi AC_SUBST(ZIP_PROG) AC_SUBST(ZIP_PROG_OPTIONS) diff --git a/win/Makefile.in b/win/Makefile.in index e2acb1b..99cf327 100644 --- a/win/Makefile.in +++ b/win/Makefile.in @@ -516,6 +516,7 @@ ${TCL_DLL_FILE}: ${TCL_OBJS} tcl.$(RES) @ZLIB_DLL_FILE@ ${TCL_ZIP_FILE} @VC_MANIFEST_EMBED_DLL@ ifeq (${ZIPFS_BUILD},1) cat ${TCL_ZIP_FILE} >> ${TCL_DLL_FILE} + ${NATIVE_ZIP} -A ${TCL_DLL_FILE} endif ${TCL_LIB_FILE}: ${TCL_OBJS} ${DDE_OBJS} ${REG_OBJS} @@ -640,7 +641,7 @@ deflate.$(HOST_OBJEXT): $(HOST_CC) -o $@ -I$(ZLIB_DIR) -c $(ZLIB_DIR)/deflate.c ioapi.$(HOST_OBJEXT): - $(HOST_CC) -o $@ -I$(ZLIB_DIR) -I$(ZLIB_DIR)/contrib/minizip -c $(ZLIB_DIR)/contrib/minizip/ioapi.c + $(HOST_CC) -o $@ -DIOAPI_NO_64 -I$(ZLIB_DIR) -I$(ZLIB_DIR)/contrib/minizip -c $(ZLIB_DIR)/contrib/minizip/ioapi.c iowin32.$(HOST_OBJEXT): $(HOST_CC) -o $@ -I$(ZLIB_DIR) -I$(ZLIB_DIR)/contrib/minizip -c $(ZLIB_DIR)/contrib/minizip/iowin32.c @@ -670,7 +671,7 @@ zutil.$(HOST_OBJEXT): $(HOST_CC) -o $@ -I$(ZLIB_DIR) -c $(ZLIB_DIR)/zutil.c minizip.$(HOST_OBJEXT): - $(HOST_CC) -o $@ -I$(ZLIB_DIR) -I$(ZLIB_DIR)/contrib/minizip -c $(ZLIB_DIR)/contrib/minizip/minizip.c + $(HOST_CC) -o $@ -I$(ZLIB_DIR) -DIOAPI_NO_64 -I$(ZLIB_DIR)/contrib/minizip -c $(ZLIB_DIR)/contrib/minizip/minizip.c minizip${HOST_EXEEXT}: $(MINIZIP_OBJS) $(HOST_CC) -o $@ $(MINIZIP_OBJS) diff --git a/win/configure b/win/configure index 06f1f75..21c3cc7 100755 --- a/win/configure +++ b/win/configure @@ -4832,61 +4832,46 @@ $as_echo "No tclsh found on PATH" >&6; } ZIP_PROG_OPTIONS="" ZIP_PROG_VFSSEARCH="" ZIP_INSTALL_OBJS="" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for zip" >&5 -$as_echo_n "checking for zip... " >&6; } - # If our native tclsh processes the "install" command line option - # we can use it to mint zip files - if $TCLSH_PROG install; then : - - ZIP_PROG=${TCLSH_PROG} - ZIP_PROG_OPTIONS="install mkzip" - ZIP_PROG_VFSSEARCH="." - { $as_echo "$as_me:${as_lineno-$LINENO}: result: Can use Native Tclsh for Zip encoding" >&5 -$as_echo "Can use Native Tclsh for Zip encoding" >&6; } - -fi - if test "x$ZIP_PROG" = "x" ; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for zip" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for zip" >&5 $as_echo_n "checking for zip... " >&6; } - if ${ac_cv_path_zip+:} false; then : + if ${ac_cv_path_zip+:} false; then : $as_echo_n "(cached) " >&6 else - search_path=`echo ${PATH} | sed -e 's/:/ /g'` - for dir in $search_path ; do - for j in `ls -r $dir/zip 2> /dev/null` \ - `ls -r $dir/zip 2> /dev/null` ; do - if test x"$ac_cv_path_zip" = x ; then - if test -f "$j" ; then - ac_cv_path_zip=$j - break - fi + search_path=`echo ${PATH} | sed -e 's/:/ /g'` + for dir in $search_path ; do + for j in `ls -r $dir/zip 2> /dev/null` \ + `ls -r $dir/zip 2> /dev/null` ; do + if test x"$ac_cv_path_zip" = x ; then + if test -f "$j" ; then + ac_cv_path_zip=$j + break fi - done + fi done + done fi - if test -f "$ac_cv_path_zip" ; then - ZIP_PROG="$ac_cv_path_zip " - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ZIP_PROG" >&5 + if test -f "$ac_cv_path_zip" ; then + ZIP_PROG="$ac_cv_path_zip " + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ZIP_PROG" >&5 $as_echo "$ZIP_PROG" >&6; } - ZIP_PROG_OPTIONS="-rq" - ZIP_PROG_VFSSEARCH="." - { $as_echo "$as_me:${as_lineno-$LINENO}: result: Found INFO Zip in environment" >&5 + ZIP_PROG_OPTIONS="-rq" + ZIP_PROG_VFSSEARCH="." + { $as_echo "$as_me:${as_lineno-$LINENO}: result: Found INFO Zip in environment" >&5 $as_echo "Found INFO Zip in environment" >&6; } - # Use standard arguments for zip - else - # It is not an error if an installed version of Zip can't be located. - # We can use the locally distributed minizip instead - ZIP_PROG="../minizip${EXEEXT_FOR_BUILD}" - ZIP_PROG_OPTIONS="-o -r" - ZIP_PROG_VFSSEARCH="." - ZIP_INSTALL_OBJS="minizip${EXEEXT_FOR_BUILD}" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: No zip found on PATH building minizip" >&5 + # Use standard arguments for zip + else + # It is not an error if an installed version of Zip can't be located. + # We can use the locally distributed minizip instead + ZIP_PROG="../minizip${EXEEXT_FOR_BUILD}" + ZIP_PROG_OPTIONS="-o -r" + ZIP_PROG_VFSSEARCH="." + ZIP_INSTALL_OBJS="minizip${EXEEXT_FOR_BUILD}" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: No zip found on PATH building minizip" >&5 $as_echo "No zip found on PATH building minizip" >&6; } - fi fi diff --git a/win/tcl.m4 b/win/tcl.m4 index 32df552..bdcd8ea 100644 --- a/win/tcl.m4 +++ b/win/tcl.m4 @@ -1250,48 +1250,37 @@ AC_DEFUN([SC_ZIPFS_SUPPORT], [ ZIP_PROG_OPTIONS="" ZIP_PROG_VFSSEARCH="" ZIP_INSTALL_OBJS="" - AC_MSG_CHECKING([for zip]) - # If our native tclsh processes the "install" command line option - # we can use it to mint zip files - AS_IF([$TCLSH_PROG install],[ - ZIP_PROG=${TCLSH_PROG} - ZIP_PROG_OPTIONS="install mkzip" - ZIP_PROG_VFSSEARCH="." - AC_MSG_RESULT([Can use Native Tclsh for Zip encoding]) - ]) - if test "x$ZIP_PROG" = "x" ; then - AC_MSG_CHECKING([for zip]) - AC_CACHE_VAL(ac_cv_path_zip, [ - search_path=`echo ${PATH} | sed -e 's/:/ /g'` - for dir in $search_path ; do - for j in `ls -r $dir/zip 2> /dev/null` \ - `ls -r $dir/zip 2> /dev/null` ; do - if test x"$ac_cv_path_zip" = x ; then - if test -f "$j" ; then - ac_cv_path_zip=$j - break - fi + AC_MSG_CHECKING([for zip]) + AC_CACHE_VAL(ac_cv_path_zip, [ + search_path=`echo ${PATH} | sed -e 's/:/ /g'` + for dir in $search_path ; do + for j in `ls -r $dir/zip 2> /dev/null` \ + `ls -r $dir/zip 2> /dev/null` ; do + if test x"$ac_cv_path_zip" = x ; then + if test -f "$j" ; then + ac_cv_path_zip=$j + break fi - done - done - ]) - if test -f "$ac_cv_path_zip" ; then - ZIP_PROG="$ac_cv_path_zip " - AC_MSG_RESULT([$ZIP_PROG]) - ZIP_PROG_OPTIONS="-rq" - ZIP_PROG_VFSSEARCH="." - AC_MSG_RESULT([Found INFO Zip in environment]) - # Use standard arguments for zip - else - # It is not an error if an installed version of Zip can't be located. - # We can use the locally distributed minizip instead - ZIP_PROG="../minizip${EXEEXT_FOR_BUILD}" - ZIP_PROG_OPTIONS="-o -r" - ZIP_PROG_VFSSEARCH="." - ZIP_INSTALL_OBJS="minizip${EXEEXT_FOR_BUILD}" - AC_MSG_RESULT([No zip found on PATH building minizip]) fi + done + done + ]) + if test -f "$ac_cv_path_zip" ; then + ZIP_PROG="$ac_cv_path_zip " + AC_MSG_RESULT([$ZIP_PROG]) + ZIP_PROG_OPTIONS="-rq" + ZIP_PROG_VFSSEARCH="." + AC_MSG_RESULT([Found INFO Zip in environment]) + # Use standard arguments for zip + else + # It is not an error if an installed version of Zip can't be located. + # We can use the locally distributed minizip instead + ZIP_PROG="../minizip${EXEEXT_FOR_BUILD}" + ZIP_PROG_OPTIONS="-o -r" + ZIP_PROG_VFSSEARCH="." + ZIP_INSTALL_OBJS="minizip${EXEEXT_FOR_BUILD}" + AC_MSG_RESULT([No zip found on PATH building minizip]) fi AC_SUBST(ZIP_PROG) AC_SUBST(ZIP_PROG_OPTIONS) diff --git a/win/tclAppInit.c b/win/tclAppInit.c index 6444b21..fa27756 100644 --- a/win/tclAppInit.c +++ b/win/tclAppInit.c @@ -126,7 +126,7 @@ _tmain( #ifdef TCL_LOCAL_MAIN_HOOK TCL_LOCAL_MAIN_HOOK(&argc, &argv); -#elif !defined(_WIN32) && !defined(UNICODE) +#elif !defined(_WIN32) || defined(UNICODE) /* This doesn't work on Windows without UNICODE */ TclZipfs_AppHook(&argc, &argv); #endif -- cgit v0.12 From 7fcc213b7aa1313c6bbe4ee2f794913e6776b0db Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Fri, 12 Oct 2018 18:24:20 +0000 Subject: TCL_NUMBER_WIDE is deprecated --- generic/tclUtil.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/generic/tclUtil.c b/generic/tclUtil.c index 97879c7..4ea9c2e 100644 --- a/generic/tclUtil.c +++ b/generic/tclUtil.c @@ -3696,7 +3696,7 @@ GetWideForIndex( int code = TclGetNumberFromObj(NULL, objPtr, &cd, &numType); if (code == TCL_OK) { - if (numType == TCL_NUMBER_WIDE) { + if (numType == TCL_NUMBER_INT) { /* objPtr holds an integer in the signed wide range */ *widePtr = (Tcl_WideInt)(*(Tcl_WideInt *)cd); return TCL_OK; @@ -3753,7 +3753,7 @@ GetWideForIndex( /* Save first integer as wide if possible */ TclGetNumberFromObj(NULL, objPtr, &cd, &t1); - if (t1 == TCL_NUMBER_WIDE) { + if (t1 == TCL_NUMBER_INT) { w1 = (*(Tcl_WideInt *)cd); } @@ -3763,7 +3763,7 @@ GetWideForIndex( /* Save second integer as wide if possible */ TclGetNumberFromObj(NULL, objPtr, &cd, &t2); - if (t2 == TCL_NUMBER_WIDE) { + if (t2 == TCL_NUMBER_INT) { w2 = (*(Tcl_WideInt *)cd); } } @@ -3773,7 +3773,7 @@ GetWideForIndex( if (t1 && t2) { /* We have both integer values */ - if ((t1 == TCL_NUMBER_WIDE) && (t2 == TCL_NUMBER_WIDE)) { + if ((t1 == TCL_NUMBER_INT) && (t2 == TCL_NUMBER_INT)) { /* Both are wide, do wide-integer math */ if (*opPtr == '-') { if ((w2 == LLONG_MIN) && (interp != NULL)) { @@ -3818,7 +3818,7 @@ GetWideForIndex( Tcl_ExprObj(interp, objPtr, &sum); TclGetNumberFromObj(NULL, sum, &cd, &numType); - if (numType == TCL_NUMBER_WIDE) { + if (numType == TCL_NUMBER_INT) { /* sum holds an integer in the signed wide range */ *widePtr = (Tcl_WideInt)(*(Tcl_WideInt *)cd); } else { @@ -4123,7 +4123,7 @@ TclIndexEncode( Tcl_WideInt wide; int idx, numType, code = TclGetNumberFromObj(NULL, objPtr, &cd, &numType); - if ((code == TCL_OK) && (numType == TCL_NUMBER_WIDE)) { + if ((code == TCL_OK) && (numType == TCL_NUMBER_INT)) { /* We parsed a value in the range LLONG_MIN...LLONG_MAX */ wide = (*(Tcl_WideInt *)cd); integerEncode: -- cgit v0.12 From de2192ab2097c8b53fd997775bbd1b74b4e8b8f0 Mon Sep 17 00:00:00 2001 From: dkf Date: Fri, 12 Oct 2018 18:44:25 +0000 Subject: Turn [zipfs tcl_library] into more internal [tcl::zipfs::tcl_library_init]. It wasn't documented and isn't very useful outside of Tcl's startup code. --- generic/tclBasic.c | 1 - generic/tclInterp.c | 2 +- generic/tclZipfs.c | 19 ++++++++++++------- tests/interp.test | 2 +- tests/zipfs.test | 4 ++-- 5 files changed, 16 insertions(+), 12 deletions(-) diff --git a/generic/tclBasic.c b/generic/tclBasic.c index 321b124..179306d 100644 --- a/generic/tclBasic.c +++ b/generic/tclBasic.c @@ -382,7 +382,6 @@ static const UnsafeEnsembleInfo unsafeEnsembleCommands[] = { {"zipfs", "mkzip"}, {"zipfs", "mount"}, {"zipfs", "mount_data"}, - {"zipfs", "tcl_library"}, {"zipfs", "unmount"}, {NULL, NULL} }; diff --git a/generic/tclInterp.c b/generic/tclInterp.c index 90f02f9..1e75298 100644 --- a/generic/tclInterp.c +++ b/generic/tclInterp.c @@ -409,7 +409,7 @@ Tcl_Init( " } else {\n" " lappend scripts {::tcl::pkgconfig get scriptdir,runtime}\n" " }\n" -" lappend scripts {zipfs tcl_library}\n" +" lappend scripts {::tcl::zipfs::tcl_library_init}\n" " lappend scripts {\n" "set parentDir [file dirname [file dirname [info nameofexecutable]]]\n" "set grandParentDir [file dirname $parentDir]\n" diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c index bd2ae13..428be15 100644 --- a/generic/tclZipfs.c +++ b/generic/tclZipfs.c @@ -3257,8 +3257,10 @@ TclZipfs_TclLibrary(void) * * ZipFSTclLibraryObjCmd -- * - * This procedure is invoked to process the [zipfs tcl_library] command. - * It returns the root that Tcl's library files are mounted under. + * This procedure is invoked to process the + * [::tcl::zipfs::tcl_library_init] command, usually called during the + * execution of Tcl's interpreter startup. It returns the root that Tcl's + * library files are mounted under. * * Results: * A standard Tcl result. @@ -3277,12 +3279,14 @@ ZipFSTclLibraryObjCmd( int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { - Tcl_Obj *pResult = TclZipfs_TclLibrary(); + if (!Tcl_IsSafe(interp)) { + Tcl_Obj *pResult = TclZipfs_TclLibrary(); - if (!pResult) { - pResult = Tcl_NewObj(); + if (!pResult) { + pResult = Tcl_NewObj(); + } + Tcl_SetObjResult(interp, pResult); } - Tcl_SetObjResult(interp, pResult); return TCL_OK; } @@ -4719,7 +4723,6 @@ TclZipfs_Init( {"list", ZipFSListObjCmd, NULL, NULL, NULL, 0}, {"canonical", ZipFSCanonicalObjCmd, NULL, NULL, NULL, 0}, {"root", ZipFSRootObjCmd, NULL, NULL, NULL, 0}, - {"tcl_library", ZipFSTclLibraryObjCmd, NULL, NULL, NULL, 1}, {NULL, NULL, NULL, NULL, NULL, 0} }; static const char findproc[] = @@ -4769,6 +4772,8 @@ TclZipfs_Init( Tcl_GetEnsembleMappingDict(NULL, ensemble, &mapObj); Tcl_DictObjPut(NULL, mapObj, Tcl_NewStringObj("find", -1), Tcl_NewStringObj("::tcl::zipfs::find", -1)); + Tcl_CreateObjCommand(interp, "::tcl::zipfs::tcl_library_init", + ZipFSTclLibraryObjCmd, NULL, NULL); Tcl_PkgProvide(interp, "zipfs", "2.0"); } return TCL_OK; diff --git a/tests/interp.test b/tests/interp.test index e9f95d7..29e3b2d 100644 --- a/tests/interp.test +++ b/tests/interp.test @@ -20,7 +20,7 @@ catch [list package require -exact Tcltest [info patchlevel]] testConstraint testinterpdelete [llength [info commands testinterpdelete]] -set hidden_cmds {cd encoding exec exit fconfigure file glob load open pwd socket source tcl:encoding:dirs tcl:encoding:system tcl:file:atime tcl:file:attributes tcl:file:copy tcl:file:delete tcl:file:dirname tcl:file:executable tcl:file:exists tcl:file:extension tcl:file:isdirectory tcl:file:isfile tcl:file:link tcl:file:lstat tcl:file:mkdir tcl:file:mtime tcl:file:nativename tcl:file:normalize tcl:file:owned tcl:file:readable tcl:file:readlink tcl:file:rename tcl:file:rootname tcl:file:size tcl:file:stat tcl:file:tail tcl:file:tempfile tcl:file:type tcl:file:volumes tcl:file:writable tcl:info:cmdtype tcl:info:nameofexecutable tcl:process:autopurge tcl:process:list tcl:process:purge tcl:process:status tcl:zipfs:lmkimg tcl:zipfs:lmkzip tcl:zipfs:mkimg tcl:zipfs:mkkey tcl:zipfs:mkzip tcl:zipfs:mount tcl:zipfs:mount_data tcl:zipfs:tcl_library tcl:zipfs:unmount unload} +set hidden_cmds {cd encoding exec exit fconfigure file glob load open pwd socket source tcl:encoding:dirs tcl:encoding:system tcl:file:atime tcl:file:attributes tcl:file:copy tcl:file:delete tcl:file:dirname tcl:file:executable tcl:file:exists tcl:file:extension tcl:file:isdirectory tcl:file:isfile tcl:file:link tcl:file:lstat tcl:file:mkdir tcl:file:mtime tcl:file:nativename tcl:file:normalize tcl:file:owned tcl:file:readable tcl:file:readlink tcl:file:rename tcl:file:rootname tcl:file:size tcl:file:stat tcl:file:tail tcl:file:tempfile tcl:file:type tcl:file:volumes tcl:file:writable tcl:info:cmdtype tcl:info:nameofexecutable tcl:process:autopurge tcl:process:list tcl:process:purge tcl:process:status tcl:zipfs:lmkimg tcl:zipfs:lmkzip tcl:zipfs:mkimg tcl:zipfs:mkkey tcl:zipfs:mkzip tcl:zipfs:mount tcl:zipfs:mount_data tcl:zipfs:unmount unload} foreach i [interp slaves] { interp delete $i diff --git a/tests/zipfs.test b/tests/zipfs.test index abf9d3f..5715ce8 100644 --- a/tests/zipfs.test +++ b/tests/zipfs.test @@ -247,7 +247,7 @@ test zipfs-3.1 {zipfs in child interpreters} -constraints zipfs -setup { } } -returnCodes error -cleanup { interp delete $interp -} -result {unknown or ambiguous subcommand "?": must be canonical, exists, find, info, list, lmkimg, lmkzip, mkimg, mkkey, mkzip, mount, mount_data, root, tcl_library, or unmount} +} -result {unknown or ambiguous subcommand "?": must be canonical, exists, find, info, list, lmkimg, lmkzip, mkimg, mkkey, mkzip, mount, mount_data, root, or unmount} test zipfs-3.2 {zipfs in child interpreters} -constraints zipfs -setup { set interp [interp create] } -body { @@ -265,7 +265,7 @@ test zipfs-3.3 {zipfs in child interpreters} -constraints zipfs -setup { } } -returnCodes error -cleanup { interp delete $safe -} -result {unknown or ambiguous subcommand "?": must be canonical, exists, find, info, list, lmkimg, lmkzip, mkimg, mkkey, mkzip, mount, mount_data, root, tcl_library, or unmount} +} -result {unknown or ambiguous subcommand "?": must be canonical, exists, find, info, list, lmkimg, lmkzip, mkimg, mkkey, mkzip, mount, mount_data, root, or unmount} test zipfs-3.4 {zipfs in child interpreters} -constraints zipfs -setup { set safe [interp create -safe] } -body { -- cgit v0.12 From 2482413c83a6fc4c661a24357b0972212d5586e3 Mon Sep 17 00:00:00 2001 From: dkf Date: Fri, 12 Oct 2018 18:45:54 +0000 Subject: Minor doc update --- doc/zipfs.n | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/doc/zipfs.n b/doc/zipfs.n index 9ed136d..c27b5d5 100644 --- a/doc/zipfs.n +++ b/doc/zipfs.n @@ -30,9 +30,8 @@ zipfs \- Mount and work with ZIP files within Tcl \fBzipfs root\fR \fBzipfs unmount\fR \fImountpoint\fR .fi -'\" The following subcommands are *UNDOCUMENTED* (the list here is not documentation) +'\" The following subcommand is *UNDOCUMENTED* '\" \fBzipfs mount_data\fR ?\fImountpoint\fR? ?\fIdata\fR? -'\" \fBzipfs tcl_library\fR .BE .SH DESCRIPTION .PP @@ -245,10 +244,8 @@ close $f # Launch the executable, printing its output to stdout exec $img >@stdout -# prints: \fI Hi. This is //zipfs:/app/main.tcl\fR +# prints: \fIHi. This is //zipfs:/app/main.tcl\fR .CE -'\" WANTED: How to use the passwords -'\" WANTED: How to package an application .SH "SEE ALSO" tclsh(1), file(n), zipfs(3), zlib(n) .SH "KEYWORDS" -- cgit v0.12 From ac4291f473c3967c6d9ee72d0076147c7a53d76f Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 17 Oct 2018 16:03:54 +0000 Subject: Backport test fix. --- tests/macOSXFCmd.test | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/tests/macOSXFCmd.test b/tests/macOSXFCmd.test index 071f11b..132b2fe 100644 --- a/tests/macOSXFCmd.test +++ b/tests/macOSXFCmd.test @@ -151,16 +151,16 @@ test macOSXFCmd-4.1 {TclMacOSXMatchType} {macosxFileAttr notRoot} { file attributes dir.test -hidden 1 } set res [list \ - [catch {glob *.test} msg] $msg \ - [catch {glob -types FOOT *.test} msg] $msg \ - [catch {glob -types {{macintosh type FOOT}} *.test} msg] $msg \ - [catch {glob -types FOOTT *.test} msg] $msg \ - [catch {glob -types {{macintosh type FOOTT}} *.test} msg] $msg \ - [catch {glob -types {{macintosh type {}}} *.test} msg] $msg \ - [catch {glob -types {{macintosh creator FOOC}} *.test} msg] $msg \ - [catch {glob -types {{macintosh creator FOOC} {macintosh type FOOT}} *.test} msg] $msg \ - [catch {glob -types hidden *.test} msg] $msg \ - [catch {glob -types {hidden FOOT} *.test} msg] $msg \ + [catch {lsort [glob *.test]} msg] $msg \ + [catch {lsort [glob -types FOOT *.test]} msg] $msg \ + [catch {lsort [glob -types {{macintosh type FOOT}} *.test]} msg] $msg \ + [catch {lsort [glob -types FOOTT *.test]} msg] $msg \ + [catch {lsort [glob -types {{macintosh type FOOTT}} *.test]} msg] $msg \ + [catch {lsort [glob -types {{macintosh type {}}} *.test]} msg] $msg \ + [catch {lsort [glob -types {{macintosh creator FOOC}} *.test]} msg] $msg \ + [catch {lsort [glob -types {{macintosh creator FOOC} {macintosh type FOOT}} *.test]} msg] $msg \ + [catch {lsort [glob -types hidden *.test]} msg] $msg \ + [catch {lsort [glob -types {hidden FOOT} *.test]} msg] $msg \ ] cd .. file delete -force globtest -- cgit v0.12 From 56b431c4c29b4b9e992e71d6db46a34189006e93 Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 17 Oct 2018 16:06:38 +0000 Subject: Mark test macOSXFCmf-2.8 non-portable. It appears to pass when the older HFS+ filesystem is in use, often on disk drives in older systems. It appears to fail when APFS is in use, more typical on newer SSD storage. --- tests/macOSXFCmd.test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/macOSXFCmd.test b/tests/macOSXFCmd.test index 132b2fe..f1758f5 100644 --- a/tests/macOSXFCmd.test +++ b/tests/macOSXFCmd.test @@ -99,7 +99,7 @@ test macOSXFCmd-2.6 {MacOSXSetFileAttribute - hidden} {macosxFileAttr notRoot} { [catch {file attributes foo.test -hidden} msg] $msg \ [file delete -force -- foo.test] } {0 {} 0 1 {}} -test macOSXFCmd-2.7 {MacOSXSetFileAttribute - rsrclength} {macosxFileAttr notRoot} { +test macOSXFCmd-2.7 {MacOSXSetFileAttribute - rsrclength} {macosxFileAttr notRoot nonPortable} { catch {file delete -force -- foo.test} close [open foo.test w] catch { -- cgit v0.12 From e1196c53f256897cfdf6549eae9bdd88eb1aa930 Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 17 Oct 2018 16:12:42 +0000 Subject: Revert addition of "slowTest" as built-in constraint. (no TIP; no version bump). Let the test file that needs the constraint define it with existing facilities. --- library/tcltest/tcltest.tcl | 4 ---- tests/tcltest.test | 2 +- tests/winPipe.test | 1 + 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/library/tcltest/tcltest.tcl b/library/tcltest/tcltest.tcl index eb42ff1..f1b6082 100644 --- a/library/tcltest/tcltest.tcl +++ b/library/tcltest/tcltest.tcl @@ -1254,10 +1254,6 @@ proc tcltest::DefineConstraintInitializers {} { ConstraintInitializer interactive \ {expr {[info exists ::tcl_interactive] && $::tcl_interactive}} - # Skip slow tests (to enable slow tests add parameter `-constraints slowTest`) - - ConstraintInitializer slowTest {format 0} - # Some tests can only be run if the installation came from a CD # image instead of a web image. Some tests must be skipped if you # are running as root on Unix. Other tests can only be run if you diff --git a/tests/tcltest.test b/tests/tcltest.test index e176b0c..0bcf342 100644 --- a/tests/tcltest.test +++ b/tests/tcltest.test @@ -312,7 +312,7 @@ test tcltest-5.5 {InitConstraints: list of built-in constraints} \ -result [lsort { 95 98 asyncPipeClose eformat emptyTest exec hasIsoLocale interactive knownBug mac macCrash macOnly macOrPc macOrUnix macOrWin nonBlockFiles - nonPortable notRoot nt pc pcCrash pcOnly root singleTestInterp slowTest socket + nonPortable notRoot nt pc pcCrash pcOnly root singleTestInterp socket stdio tempNotMac tempNotPc tempNotUnix tempNotWin unix unixCrash unixExecs unixOnly unixOrPc unixOrWin userInteraction win winCrash winOnly }] diff --git a/tests/winPipe.test b/tests/winPipe.test index 2f59e96..b3624c2 100644 --- a/tests/winPipe.test +++ b/tests/winPipe.test @@ -30,6 +30,7 @@ testConstraint cat32 [file exists $cat32] testConstraint AllocConsole [catch {puts console1 ""}] testConstraint RealConsole [expr {![testConstraint AllocConsole]}] testConstraint testexcept [llength [info commands testexcept]] +testConstraint slowTest 0 set big bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n -- cgit v0.12 From e0209e39ea32294ee016d240fd1dfe9411469832 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 17 Oct 2018 19:51:47 +0000 Subject: Fix test-cases running on Windows 10: [string index $tcl_platform(osVersion) 0] doesn't give the correct answer then (it gives "1", but "10" was expected) --- tests/cmdAH.test | 2 +- tests/fCmd.test | 18 +++++++++--------- tests/fileName.test | 2 +- tests/winFCmd.test | 5 ++--- 4 files changed, 13 insertions(+), 14 deletions(-) diff --git a/tests/cmdAH.test b/tests/cmdAH.test index 45a867a..6cc8c0f 100644 --- a/tests/cmdAH.test +++ b/tests/cmdAH.test @@ -20,7 +20,7 @@ testConstraint testsetplatform [llength [info commands testsetplatform]] testConstraint testvolumetype [llength [info commands testvolumetype]] testConstraint linkDirectory [expr { ![testConstraint win] || - ([string index $tcl_platform(osVersion) 0] >= 5 + ($::tcl_platform(osVersion) >= 5.0 && [lindex [file system [temporaryDirectory]] 1] eq "NTFS") }] diff --git a/tests/fCmd.test b/tests/fCmd.test index 2860001..f53128d 100644 --- a/tests/fCmd.test +++ b/tests/fCmd.test @@ -50,11 +50,10 @@ if {[testConstraint unix]} { # Also used in winFCmd... if {[testConstraint winOnly]} { - set major [string index $tcl_platform(osVersion) 0] - if {[testConstraint nt] && $major > 4} { - if {$major > 5} { + if {[testConstraint nt] && $::tcl_platform(osVersion) >= 5.0} { + if {$::tcl_platform(osVersion) >= 6.0} { testConstraint winVista 1 - } elseif {$major == 5} { + } else { testConstraint win2000orXP 1 } } else { @@ -62,10 +61,11 @@ if {[testConstraint winOnly]} { } } -testConstraint darwin9 [expr {[testConstraint unix] && - $tcl_platform(os) eq "Darwin" && - int([string range $tcl_platform(osVersion) 0 \ - [string first . $tcl_platform(osVersion)]]) >= 9}] +testConstraint darwin9 [expr { + [testConstraint unix] + && $tcl_platform(os) eq "Darwin" + && [package vsatisfies 1.$::tcl_platform(osVersion) 1.9] +}] testConstraint notDarwin9 [expr {![testConstraint darwin9]}] testConstraint fileSharing 0 @@ -2282,7 +2282,7 @@ test fCmd-27.6 {TclFileAttrsCmd - setting more than one option} -setup { if { [testConstraint win] && - ([string index $tcl_platform(osVersion) 0] < 5 + ($::tcl_platform(osVersion) < 5.0 || [lindex [file system [temporaryDirectory]] 1] ne "NTFS") } then { testConstraint linkDirectory 0 diff --git a/tests/fileName.test b/tests/fileName.test index 0851e94..a4c8efe 100644 --- a/tests/fileName.test +++ b/tests/fileName.test @@ -20,7 +20,7 @@ testConstraint testtranslatefilename [llength [info commands testtranslatefilena testConstraint linkDirectory 1 testConstraint symbolicLinkFile 1 if {[testConstraint win]} { - if {[string index $tcl_platform(osVersion) 0] < 5 \ + if {$::tcl_platform(osVersion) < 5.0 \ || [lindex [file system [temporaryDirectory]] 1] ne "NTFS"} { testConstraint linkDirectory 0 } diff --git a/tests/winFCmd.test b/tests/winFCmd.test index f1f2afa..f93f225 100644 --- a/tests/winFCmd.test +++ b/tests/winFCmd.test @@ -53,10 +53,9 @@ proc cleanup {args} { } if {[testConstraint win]} { - set major [string index $tcl_platform(osVersion) 0] - if {$major > 5} { + if {$::tcl_platform(osVersion) >= 5.0} { testConstraint winVista 1 - } elseif {$major == 5} { + } elseif {$::tcl_platform(osVersion) >= 4.0} { testConstraint winXP 1 } } -- cgit v0.12 From 49ebd1264d9cff42e9e5963f2a2f3c0eb732f375 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 17 Oct 2018 22:37:43 +0000 Subject: Add -Wpointer-arith compiler flag to gcc --- unix/configure | 2 +- unix/tcl.m4 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/unix/configure b/unix/configure index 2af5144..013a8b3 100755 --- a/unix/configure +++ b/unix/configure @@ -4947,7 +4947,7 @@ fi if test "$GCC" = yes; then : CFLAGS_OPTIMIZE=-O2 - CFLAGS_WARNING="-Wall -Wwrite-strings -Wsign-compare -Wdeclaration-after-statement" + CFLAGS_WARNING="-Wall -Wwrite-strings -Wsign-compare -Wdeclaration-after-statement -Wpointer-arith" else diff --git a/unix/tcl.m4 b/unix/tcl.m4 index b77387a..e27cc2c 100644 --- a/unix/tcl.m4 +++ b/unix/tcl.m4 @@ -986,7 +986,7 @@ AC_DEFUN([SC_CONFIG_CFLAGS], [ CFLAGS_DEBUG=-g AS_IF([test "$GCC" = yes], [ CFLAGS_OPTIMIZE=-O2 - CFLAGS_WARNING="-Wall -Wwrite-strings -Wsign-compare -Wdeclaration-after-statement" + CFLAGS_WARNING="-Wall -Wwrite-strings -Wsign-compare -Wdeclaration-after-statement -Wpointer-arith" ], [ CFLAGS_OPTIMIZE=-O CFLAGS_WARNING="" -- cgit v0.12