From 55787f4f08c9af4d70e2f0b8445be85ddec3b7c4 Mon Sep 17 00:00:00 2001 From: dkf Date: Tue, 11 Jun 2013 08:19:56 +0000 Subject: Move the disassembler to its own file. --- generic/tclCompile.c | 785 ---------------------------------- generic/tclCompile.h | 18 +- generic/tclDisassemble.c | 1045 ++++++++++++++++++++++++++++++++++++++++++++++ generic/tclProc.c | 258 +----------- unix/Makefile.in | 11 +- win/Makefile.in | 1 + win/makefile.bc | 5 + win/makefile.vc | 7 +- 8 files changed, 1091 insertions(+), 1039 deletions(-) create mode 100644 generic/tclDisassemble.c diff --git a/generic/tclCompile.c b/generic/tclCompile.c index c361430..f93bbad 100644 --- a/generic/tclCompile.c +++ b/generic/tclCompile.c @@ -576,11 +576,6 @@ static void RegisterAuxDataType(const AuxDataType *typePtr); static int SetByteCodeFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr); static void StartExpanding(CompileEnv *envPtr); -static int FormatInstruction(ByteCode *codePtr, - const unsigned char *pc, Tcl_Obj *bufferObj); -static void PrintSourceToObj(Tcl_Obj *appendObj, - const char *stringPtr, int maxChars); -static void UpdateStringOfInstName(Tcl_Obj *objPtr); /* * TIP #280: Helper for building the per-word line information of all compiled @@ -619,19 +614,6 @@ static const Tcl_ObjType substCodeType = { }; /* - * The structure below defines an instruction name Tcl object to allow - * reporting of inner contexts in errorstack without string allocation. - */ - -static const Tcl_ObjType tclInstNameType = { - "instname", /* name */ - NULL, /* freeIntRepProc */ - NULL, /* dupIntRepProc */ - UpdateStringOfInstName, /* updateStringProc */ - NULL, /* setFromAnyProc */ -}; - -/* * Helper macros. */ @@ -4411,773 +4393,6 @@ EncodeCmdLocMap( return p; } -#ifdef TCL_COMPILE_DEBUG -/* - *---------------------------------------------------------------------- - * - * TclPrintByteCodeObj -- - * - * This procedure prints ("disassembles") the instructions of a bytecode - * object to stdout. - * - * Results: - * None. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -void -TclPrintByteCodeObj( - Tcl_Interp *interp, /* Used only for Tcl_GetStringFromObj. */ - Tcl_Obj *objPtr) /* The bytecode object to disassemble. */ -{ - Tcl_Obj *bufPtr = TclDisassembleByteCodeObj(objPtr); - - fprintf(stdout, "\n%s", TclGetString(bufPtr)); - Tcl_DecrRefCount(bufPtr); -} - -/* - *---------------------------------------------------------------------- - * - * TclPrintInstruction -- - * - * This procedure prints ("disassembles") one instruction from a bytecode - * object to stdout. - * - * Results: - * Returns the length in bytes of the current instruiction. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -int -TclPrintInstruction( - ByteCode *codePtr, /* Bytecode containing the instruction. */ - const unsigned char *pc) /* Points to first byte of instruction. */ -{ - Tcl_Obj *bufferObj; - int numBytes; - - TclNewObj(bufferObj); - numBytes = FormatInstruction(codePtr, pc, bufferObj); - fprintf(stdout, "%s", TclGetString(bufferObj)); - Tcl_DecrRefCount(bufferObj); - return numBytes; -} - -/* - *---------------------------------------------------------------------- - * - * TclPrintObject -- - * - * This procedure prints up to a specified number of characters from the - * argument Tcl object's string representation to a specified file. - * - * Results: - * None. - * - * Side effects: - * Outputs characters to the specified file. - * - *---------------------------------------------------------------------- - */ - -void -TclPrintObject( - FILE *outFile, /* The file to print the source to. */ - Tcl_Obj *objPtr, /* Points to the Tcl object whose string - * representation should be printed. */ - int maxChars) /* Maximum number of chars to print. */ -{ - char *bytes; - int length; - - bytes = Tcl_GetStringFromObj(objPtr, &length); - TclPrintSource(outFile, bytes, TclMin(length, maxChars)); -} - -/* - *---------------------------------------------------------------------- - * - * TclPrintSource -- - * - * This procedure prints up to a specified number of characters from the - * argument string to a specified file. It tries to produce legible - * output by adding backslashes as necessary. - * - * Results: - * None. - * - * Side effects: - * Outputs characters to the specified file. - * - *---------------------------------------------------------------------- - */ - -void -TclPrintSource( - FILE *outFile, /* The file to print the source to. */ - const char *stringPtr, /* The string to print. */ - int maxChars) /* Maximum number of chars to print. */ -{ - Tcl_Obj *bufferObj; - - TclNewObj(bufferObj); - PrintSourceToObj(bufferObj, stringPtr, maxChars); - fprintf(outFile, "%s", TclGetString(bufferObj)); - Tcl_DecrRefCount(bufferObj); -} -#endif /* TCL_COMPILE_DEBUG */ - -/* - *---------------------------------------------------------------------- - * - * TclDisassembleByteCodeObj -- - * - * Given an object which is of bytecode type, return a disassembled - * version of the bytecode (in a new refcount 0 object). No guarantees - * are made about the details of the contents of the result. - * - *---------------------------------------------------------------------- - */ - -Tcl_Obj * -TclDisassembleByteCodeObj( - Tcl_Obj *objPtr) /* The bytecode object to disassemble. */ -{ - ByteCode *codePtr = objPtr->internalRep.twoPtrValue.ptr1; - unsigned char *codeStart, *codeLimit, *pc; - unsigned char *codeDeltaNext, *codeLengthNext; - unsigned char *srcDeltaNext, *srcLengthNext; - int codeOffset, codeLen, srcOffset, srcLen, numCmds, delta, i; - Interp *iPtr = (Interp *) *codePtr->interpHandle; - Tcl_Obj *bufferObj; - char ptrBuf1[20], ptrBuf2[20]; - - TclNewObj(bufferObj); - if (codePtr->refCount <= 0) { - return bufferObj; /* Already freed. */ - } - - codeStart = codePtr->codeStart; - codeLimit = codeStart + codePtr->numCodeBytes; - numCmds = codePtr->numCommands; - - /* - * Print header lines describing the ByteCode. - */ - - sprintf(ptrBuf1, "%p", codePtr); - sprintf(ptrBuf2, "%p", iPtr); - Tcl_AppendPrintfToObj(bufferObj, - "ByteCode 0x%s, refCt %u, epoch %u, interp 0x%s (epoch %u)\n", - ptrBuf1, codePtr->refCount, codePtr->compileEpoch, ptrBuf2, - iPtr->compileEpoch); - Tcl_AppendToObj(bufferObj, " Source ", -1); - PrintSourceToObj(bufferObj, codePtr->source, - TclMin(codePtr->numSrcBytes, 55)); - Tcl_AppendPrintfToObj(bufferObj, - "\n Cmds %d, src %d, inst %d, litObjs %u, aux %d, stkDepth %u, code/src %.2f\n", - numCmds, codePtr->numSrcBytes, codePtr->numCodeBytes, - codePtr->numLitObjects, codePtr->numAuxDataItems, - codePtr->maxStackDepth, -#ifdef TCL_COMPILE_STATS - codePtr->numSrcBytes? - codePtr->structureSize/(float)codePtr->numSrcBytes : -#endif - 0.0); - -#ifdef TCL_COMPILE_STATS - Tcl_AppendPrintfToObj(bufferObj, - " Code %lu = header %lu+inst %d+litObj %lu+exc %lu+aux %lu+cmdMap %d\n", - (unsigned long) codePtr->structureSize, - (unsigned long) (sizeof(ByteCode) - sizeof(size_t) - sizeof(Tcl_Time)), - codePtr->numCodeBytes, - (unsigned long) (codePtr->numLitObjects * sizeof(Tcl_Obj *)), - (unsigned long) (codePtr->numExceptRanges*sizeof(ExceptionRange)), - (unsigned long) (codePtr->numAuxDataItems * sizeof(AuxData)), - codePtr->numCmdLocBytes); -#endif /* TCL_COMPILE_STATS */ - - /* - * If the ByteCode is the compiled body of a Tcl procedure, print - * information about that procedure. Note that we don't know the - * procedure's name since ByteCode's can be shared among procedures. - */ - - if (codePtr->procPtr != NULL) { - Proc *procPtr = codePtr->procPtr; - int numCompiledLocals = procPtr->numCompiledLocals; - - sprintf(ptrBuf1, "%p", procPtr); - Tcl_AppendPrintfToObj(bufferObj, - " Proc 0x%s, refCt %d, args %d, compiled locals %d\n", - ptrBuf1, procPtr->refCount, procPtr->numArgs, - numCompiledLocals); - if (numCompiledLocals > 0) { - CompiledLocal *localPtr = procPtr->firstLocalPtr; - - for (i = 0; i < numCompiledLocals; i++) { - Tcl_AppendPrintfToObj(bufferObj, - " slot %d%s%s%s%s%s%s", i, - (localPtr->flags & (VAR_ARRAY|VAR_LINK)) ? "" : ", scalar", - (localPtr->flags & VAR_ARRAY) ? ", array" : "", - (localPtr->flags & VAR_LINK) ? ", link" : "", - (localPtr->flags & VAR_ARGUMENT) ? ", arg" : "", - (localPtr->flags & VAR_TEMPORARY) ? ", temp" : "", - (localPtr->flags & VAR_RESOLVED) ? ", resolved" : ""); - if (TclIsVarTemporary(localPtr)) { - Tcl_AppendToObj(bufferObj, "\n", -1); - } else { - Tcl_AppendPrintfToObj(bufferObj, ", \"%s\"\n", - localPtr->name); - } - localPtr = localPtr->nextPtr; - } - } - } - - /* - * Print the ExceptionRange array. - */ - - if (codePtr->numExceptRanges > 0) { - Tcl_AppendPrintfToObj(bufferObj, " Exception ranges %d, depth %d:\n", - codePtr->numExceptRanges, codePtr->maxExceptDepth); - for (i = 0; i < codePtr->numExceptRanges; i++) { - ExceptionRange *rangePtr = &codePtr->exceptArrayPtr[i]; - - Tcl_AppendPrintfToObj(bufferObj, - " %d: level %d, %s, pc %d-%d, ", - i, rangePtr->nestingLevel, - (rangePtr->type==LOOP_EXCEPTION_RANGE ? "loop" : "catch"), - rangePtr->codeOffset, - (rangePtr->codeOffset + rangePtr->numCodeBytes - 1)); - switch (rangePtr->type) { - case LOOP_EXCEPTION_RANGE: - Tcl_AppendPrintfToObj(bufferObj, "continue %d, break %d\n", - rangePtr->continueOffset, rangePtr->breakOffset); - break; - case CATCH_EXCEPTION_RANGE: - Tcl_AppendPrintfToObj(bufferObj, "catch %d\n", - rangePtr->catchOffset); - break; - default: - Tcl_Panic("TclDisassembleByteCodeObj: bad ExceptionRange type %d", - rangePtr->type); - } - } - } - - /* - * If there were no commands (e.g., an expression or an empty string was - * compiled), just print all instructions and return. - */ - - if (numCmds == 0) { - pc = codeStart; - while (pc < codeLimit) { - Tcl_AppendToObj(bufferObj, " ", -1); - pc += FormatInstruction(codePtr, pc, bufferObj); - } - return bufferObj; - } - - /* - * Print table showing the code offset, source offset, and source length - * for each command. These are encoded as a sequence of bytes. - */ - - Tcl_AppendPrintfToObj(bufferObj, " Commands %d:", numCmds); - codeDeltaNext = codePtr->codeDeltaStart; - codeLengthNext = codePtr->codeLengthStart; - srcDeltaNext = codePtr->srcDeltaStart; - srcLengthNext = codePtr->srcLengthStart; - codeOffset = srcOffset = 0; - for (i = 0; i < numCmds; i++) { - if ((unsigned) *codeDeltaNext == (unsigned) 0xFF) { - codeDeltaNext++; - delta = TclGetInt4AtPtr(codeDeltaNext); - codeDeltaNext += 4; - } else { - delta = TclGetInt1AtPtr(codeDeltaNext); - codeDeltaNext++; - } - codeOffset += delta; - - if ((unsigned) *codeLengthNext == (unsigned) 0xFF) { - codeLengthNext++; - codeLen = TclGetInt4AtPtr(codeLengthNext); - codeLengthNext += 4; - } else { - codeLen = TclGetInt1AtPtr(codeLengthNext); - codeLengthNext++; - } - - if ((unsigned) *srcDeltaNext == (unsigned) 0xFF) { - srcDeltaNext++; - delta = TclGetInt4AtPtr(srcDeltaNext); - srcDeltaNext += 4; - } else { - delta = TclGetInt1AtPtr(srcDeltaNext); - srcDeltaNext++; - } - srcOffset += delta; - - if ((unsigned) *srcLengthNext == (unsigned) 0xFF) { - srcLengthNext++; - srcLen = TclGetInt4AtPtr(srcLengthNext); - srcLengthNext += 4; - } else { - srcLen = TclGetInt1AtPtr(srcLengthNext); - srcLengthNext++; - } - - Tcl_AppendPrintfToObj(bufferObj, "%s%4d: pc %d-%d, src %d-%d", - ((i % 2)? " " : "\n "), - (i+1), codeOffset, (codeOffset + codeLen - 1), - srcOffset, (srcOffset + srcLen - 1)); - } - if (numCmds > 0) { - Tcl_AppendToObj(bufferObj, "\n", -1); - } - - /* - * Print each instruction. If the instruction corresponds to the start of - * a command, print the command's source. Note that we don't need the code - * length here. - */ - - codeDeltaNext = codePtr->codeDeltaStart; - srcDeltaNext = codePtr->srcDeltaStart; - srcLengthNext = codePtr->srcLengthStart; - codeOffset = srcOffset = 0; - pc = codeStart; - for (i = 0; i < numCmds; i++) { - if ((unsigned) *codeDeltaNext == (unsigned) 0xFF) { - codeDeltaNext++; - delta = TclGetInt4AtPtr(codeDeltaNext); - codeDeltaNext += 4; - } else { - delta = TclGetInt1AtPtr(codeDeltaNext); - codeDeltaNext++; - } - codeOffset += delta; - - if ((unsigned) *srcDeltaNext == (unsigned) 0xFF) { - srcDeltaNext++; - delta = TclGetInt4AtPtr(srcDeltaNext); - srcDeltaNext += 4; - } else { - delta = TclGetInt1AtPtr(srcDeltaNext); - srcDeltaNext++; - } - srcOffset += delta; - - if ((unsigned) *srcLengthNext == (unsigned) 0xFF) { - srcLengthNext++; - srcLen = TclGetInt4AtPtr(srcLengthNext); - srcLengthNext += 4; - } else { - srcLen = TclGetInt1AtPtr(srcLengthNext); - srcLengthNext++; - } - - /* - * Print instructions before command i. - */ - - while ((pc-codeStart) < codeOffset) { - Tcl_AppendToObj(bufferObj, " ", -1); - pc += FormatInstruction(codePtr, pc, bufferObj); - } - - Tcl_AppendPrintfToObj(bufferObj, " Command %d: ", i+1); - PrintSourceToObj(bufferObj, (codePtr->source + srcOffset), - TclMin(srcLen, 55)); - Tcl_AppendToObj(bufferObj, "\n", -1); - } - if (pc < codeLimit) { - /* - * Print instructions after the last command. - */ - - while (pc < codeLimit) { - Tcl_AppendToObj(bufferObj, " ", -1); - pc += FormatInstruction(codePtr, pc, bufferObj); - } - } - return bufferObj; -} - -/* - *---------------------------------------------------------------------- - * - * FormatInstruction -- - * - * Appends a representation of a bytecode instruction to a Tcl_Obj. - * - *---------------------------------------------------------------------- - */ - -static int -FormatInstruction( - ByteCode *codePtr, /* Bytecode containing the instruction. */ - const unsigned char *pc, /* Points to first byte of instruction. */ - Tcl_Obj *bufferObj) /* Object to append instruction info to. */ -{ - Proc *procPtr = codePtr->procPtr; - unsigned char opCode = *pc; - register const InstructionDesc *instDesc = &tclInstructionTable[opCode]; - unsigned char *codeStart = codePtr->codeStart; - unsigned pcOffset = pc - codeStart; - int opnd = 0, i, j, numBytes = 1; - int localCt = procPtr ? procPtr->numCompiledLocals : 0; - CompiledLocal *localPtr = procPtr ? procPtr->firstLocalPtr : NULL; - char suffixBuffer[128]; /* Additional info to print after main opcode - * and immediates. */ - char *suffixSrc = NULL; - Tcl_Obj *suffixObj = NULL; - AuxData *auxPtr = NULL; - - suffixBuffer[0] = '\0'; - Tcl_AppendPrintfToObj(bufferObj, "(%u) %s ", pcOffset, instDesc->name); - for (i = 0; i < instDesc->numOperands; i++) { - switch (instDesc->opTypes[i]) { - case OPERAND_INT1: - opnd = TclGetInt1AtPtr(pc+numBytes); numBytes++; - if (opCode == INST_JUMP1 || opCode == INST_JUMP_TRUE1 - || opCode == INST_JUMP_FALSE1) { - sprintf(suffixBuffer, "pc %u", pcOffset+opnd); - } - Tcl_AppendPrintfToObj(bufferObj, "%+d ", opnd); - break; - case OPERAND_INT4: - opnd = TclGetInt4AtPtr(pc+numBytes); numBytes += 4; - if (opCode == INST_JUMP4 || opCode == INST_JUMP_TRUE4 - || opCode == INST_JUMP_FALSE4) { - sprintf(suffixBuffer, "pc %u", pcOffset+opnd); - } else if (opCode == INST_START_CMD) { - sprintf(suffixBuffer, "next cmd at pc %u", pcOffset+opnd); - } - Tcl_AppendPrintfToObj(bufferObj, "%+d ", opnd); - break; - case OPERAND_UINT1: - opnd = TclGetUInt1AtPtr(pc+numBytes); numBytes++; - if (opCode == INST_PUSH1) { - suffixObj = codePtr->objArrayPtr[opnd]; - } - Tcl_AppendPrintfToObj(bufferObj, "%u ", (unsigned) opnd); - break; - case OPERAND_AUX4: - case OPERAND_UINT4: - opnd = TclGetUInt4AtPtr(pc+numBytes); numBytes += 4; - if (opCode == INST_PUSH4) { - suffixObj = codePtr->objArrayPtr[opnd]; - } else if (opCode == INST_START_CMD && opnd != 1) { - sprintf(suffixBuffer+strlen(suffixBuffer), - ", %u cmds start here", opnd); - } - Tcl_AppendPrintfToObj(bufferObj, "%u ", (unsigned) opnd); - if (instDesc->opTypes[i] == OPERAND_AUX4) { - auxPtr = &codePtr->auxDataArrayPtr[opnd]; - } - break; - case OPERAND_IDX4: - opnd = TclGetInt4AtPtr(pc+numBytes); numBytes += 4; - if (opnd >= -1) { - Tcl_AppendPrintfToObj(bufferObj, "%d ", opnd); - } else if (opnd == -2) { - Tcl_AppendPrintfToObj(bufferObj, "end "); - } else { - Tcl_AppendPrintfToObj(bufferObj, "end-%d ", -2-opnd); - } - break; - case OPERAND_LVT1: - opnd = TclGetUInt1AtPtr(pc+numBytes); - numBytes++; - goto printLVTindex; - case OPERAND_LVT4: - opnd = TclGetUInt4AtPtr(pc+numBytes); - numBytes += 4; - printLVTindex: - if (localPtr != NULL) { - if (opnd >= localCt) { - Tcl_Panic("FormatInstruction: bad local var index %u (%u locals)", - (unsigned) opnd, localCt); - } - for (j = 0; j < opnd; j++) { - localPtr = localPtr->nextPtr; - } - if (TclIsVarTemporary(localPtr)) { - sprintf(suffixBuffer, "temp var %u", (unsigned) opnd); - } else { - sprintf(suffixBuffer, "var "); - suffixSrc = localPtr->name; - } - } - Tcl_AppendPrintfToObj(bufferObj, "%%v%u ", (unsigned) opnd); - break; - case OPERAND_NONE: - default: - break; - } - } - if (suffixObj) { - const char *bytes; - int length; - - Tcl_AppendToObj(bufferObj, "\t# ", -1); - bytes = Tcl_GetStringFromObj(codePtr->objArrayPtr[opnd], &length); - PrintSourceToObj(bufferObj, bytes, TclMin(length, 40)); - } else if (suffixBuffer[0]) { - Tcl_AppendPrintfToObj(bufferObj, "\t# %s", suffixBuffer); - if (suffixSrc) { - PrintSourceToObj(bufferObj, suffixSrc, 40); - } - } - Tcl_AppendToObj(bufferObj, "\n", -1); - if (auxPtr && auxPtr->type->printProc) { - Tcl_AppendToObj(bufferObj, "\t\t[", -1); - auxPtr->type->printProc(auxPtr->clientData, bufferObj, codePtr, - pcOffset); - Tcl_AppendToObj(bufferObj, "]\n", -1); - } - return numBytes; -} - -/* - *---------------------------------------------------------------------- - * - * TclGetInnerContext -- - * - * If possible, returns a list capturing the inner context. Otherwise - * return NULL. - * - *---------------------------------------------------------------------- - */ - -Tcl_Obj * -TclGetInnerContext( - Tcl_Interp *interp, - const unsigned char *pc, - Tcl_Obj **tosPtr) -{ - int objc = 0, off = 0; - Tcl_Obj *result; - Interp *iPtr = (Interp *) interp; - - switch (*pc) { - case INST_STR_LEN: - case INST_LNOT: - case INST_BITNOT: - case INST_UMINUS: - case INST_UPLUS: - case INST_TRY_CVT_TO_NUMERIC: - case INST_EXPAND_STKTOP: - case INST_EXPR_STK: - objc = 1; - break; - - case INST_LIST_IN: - case INST_LIST_NOT_IN: /* Basic list containment operators. */ - case INST_STR_EQ: - case INST_STR_NEQ: /* String (in)equality check */ - case INST_STR_CMP: /* String compare. */ - case INST_STR_INDEX: - case INST_STR_MATCH: - case INST_REGEXP: - case INST_EQ: - case INST_NEQ: - case INST_LT: - case INST_GT: - case INST_LE: - case INST_GE: - case INST_MOD: - case INST_LSHIFT: - case INST_RSHIFT: - case INST_BITOR: - case INST_BITXOR: - case INST_BITAND: - case INST_EXPON: - case INST_ADD: - case INST_SUB: - case INST_DIV: - case INST_MULT: - objc = 2; - break; - - case INST_RETURN_STK: - /* early pop. TODO: dig out opt dict too :/ */ - objc = 1; - break; - - case INST_SYNTAX: - case INST_RETURN_IMM: - objc = 2; - break; - - case INST_INVOKE_STK4: - objc = TclGetUInt4AtPtr(pc+1); - break; - - case INST_INVOKE_STK1: - objc = TclGetUInt1AtPtr(pc+1); - break; - } - - result = iPtr->innerContext; - if (Tcl_IsShared(result)) { - Tcl_DecrRefCount(result); - iPtr->innerContext = result = Tcl_NewListObj(objc + 1, NULL); - Tcl_IncrRefCount(result); - } else { - int len; - - /* - * Reset while keeping the list intrep as much as possible. - */ - - Tcl_ListObjLength(interp, result, &len); - Tcl_ListObjReplace(interp, result, 0, len, 0, NULL); - } - Tcl_ListObjAppendElement(NULL, result, TclNewInstNameObj(*pc)); - - for (; objc>0 ; objc--) { - Tcl_Obj *objPtr; - - objPtr = tosPtr[1 - objc + off]; - if (!objPtr) { - Tcl_Panic("InnerContext: bad tos -- appending null object"); - } - if ((objPtr->refCount<=0) -#ifdef TCL_MEM_DEBUG - || (objPtr->refCount==0x61616161) -#endif - ) { - Tcl_Panic("InnerContext: bad tos -- appending freed object %p", - objPtr); - } - Tcl_ListObjAppendElement(NULL, result, objPtr); - } - - return result; -} - -/* - *---------------------------------------------------------------------- - * - * TclNewInstNameObj -- - * - * Creates a new InstName Tcl_Obj based on the given instruction - * - *---------------------------------------------------------------------- - */ - -Tcl_Obj * -TclNewInstNameObj( - unsigned char inst) -{ - Tcl_Obj *objPtr = Tcl_NewObj(); - - objPtr->typePtr = &tclInstNameType; - objPtr->internalRep.longValue = (long) inst; - objPtr->bytes = NULL; - - return objPtr; -} - -/* - *---------------------------------------------------------------------- - * - * UpdateStringOfInstName -- - * - * Update the string representation for an instruction name object. - * - *---------------------------------------------------------------------- - */ - -static void -UpdateStringOfInstName( - Tcl_Obj *objPtr) -{ - int inst = objPtr->internalRep.longValue; - char *s, buf[20]; - int len; - - if ((inst < 0) || (inst > LAST_INST_OPCODE)) { - sprintf(buf, "inst_%d", inst); - s = buf; - } else { - s = (char *) tclInstructionTable[objPtr->internalRep.longValue].name; - } - len = strlen(s); - objPtr->bytes = ckalloc(len + 1); - memcpy(objPtr->bytes, s, len + 1); - objPtr->length = len; -} - -/* - *---------------------------------------------------------------------- - * - * PrintSourceToObj -- - * - * Appends a quoted representation of a string to a Tcl_Obj. - * - *---------------------------------------------------------------------- - */ - -static void -PrintSourceToObj( - Tcl_Obj *appendObj, /* The object to print the source to. */ - const char *stringPtr, /* The string to print. */ - int maxChars) /* Maximum number of chars to print. */ -{ - register const char *p; - register int i = 0; - - if (stringPtr == NULL) { - Tcl_AppendToObj(appendObj, "\"\"", -1); - return; - } - - Tcl_AppendToObj(appendObj, "\"", -1); - p = stringPtr; - for (; (*p != '\0') && (i < maxChars); p++, i++) { - switch (*p) { - case '"': - Tcl_AppendToObj(appendObj, "\\\"", -1); - continue; - case '\f': - Tcl_AppendToObj(appendObj, "\\f", -1); - continue; - case '\n': - Tcl_AppendToObj(appendObj, "\\n", -1); - continue; - case '\r': - Tcl_AppendToObj(appendObj, "\\r", -1); - continue; - case '\t': - Tcl_AppendToObj(appendObj, "\\t", -1); - continue; - case '\v': - Tcl_AppendToObj(appendObj, "\\v", -1); - continue; - default: - Tcl_AppendPrintfToObj(appendObj, "%c", *p); - continue; - } - } - Tcl_AppendToObj(appendObj, "\"", -1); -} - #ifdef TCL_COMPILE_STATS /* *---------------------------------------------------------------------- diff --git a/generic/tclCompile.h b/generic/tclCompile.h index 9af4911..f28403d 100644 --- a/generic/tclCompile.h +++ b/generic/tclCompile.h @@ -48,6 +48,13 @@ MODULE_SCOPE int tclTraceCompile; MODULE_SCOPE int tclTraceExec; #endif + +/* + * The type of lambda expressions. Note that every lambda will *always* have a + * string representation. + */ + +MODULE_SCOPE const Tcl_ObjType tclLambdaType; /* *------------------------------------------------------------------------ @@ -1099,12 +1106,15 @@ MODULE_SCOPE void TclVerifyLocalLiteralTable(CompileEnv *envPtr); MODULE_SCOPE int TclWordKnownAtCompileTime(Tcl_Token *tokenPtr, Tcl_Obj *valuePtr); MODULE_SCOPE void TclLogCommandInfo(Tcl_Interp *interp, - const char *script, - const char *command, int length, - const unsigned char *pc, Tcl_Obj **tosPtr); + const char *script, const char *command, + int length, const unsigned char *pc, + Tcl_Obj **tosPtr); MODULE_SCOPE Tcl_Obj *TclGetInnerContext(Tcl_Interp *interp, - const unsigned char *pc, Tcl_Obj **tosPtr); + const unsigned char *pc, Tcl_Obj **tosPtr); MODULE_SCOPE Tcl_Obj *TclNewInstNameObj(unsigned char inst); +MODULE_SCOPE int TclPushProcCallFrame(ClientData clientData, + register Tcl_Interp *interp, int objc, + Tcl_Obj *const objv[], int isLambda); /* diff --git a/generic/tclDisassemble.c b/generic/tclDisassemble.c new file mode 100644 index 0000000..bc84763 --- /dev/null +++ b/generic/tclDisassemble.c @@ -0,0 +1,1045 @@ +/* + * tclDisassemble.c -- + * + * This file contains procedures that disassemble bytecode into either + * human-readable or Tcl-processable forms. + * + * Copyright (c) 1996-1998 Sun Microsystems, Inc. + * Copyright (c) 2001 by Kevin B. Kenny. All rights reserved. + * Copyright (c) 2013 Donal K. Fellows. + * + * 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 "tclCompile.h" +#include "tclOOInt.h" +#include + +/* + * Prototypes for procedures defined later in this file: + */ + +static int FormatInstruction(ByteCode *codePtr, + const unsigned char *pc, Tcl_Obj *bufferObj); +static void PrintSourceToObj(Tcl_Obj *appendObj, + const char *stringPtr, int maxChars); +static void UpdateStringOfInstName(Tcl_Obj *objPtr); + +/* + * The structure below defines an instruction name Tcl object to allow + * reporting of inner contexts in errorstack without string allocation. + */ + +static const Tcl_ObjType tclInstNameType = { + "instname", /* name */ + NULL, /* freeIntRepProc */ + NULL, /* dupIntRepProc */ + UpdateStringOfInstName, /* updateStringProc */ + NULL, /* setFromAnyProc */ +}; + +#ifdef TCL_COMPILE_DEBUG +/* + *---------------------------------------------------------------------- + * + * TclPrintByteCodeObj -- + * + * This procedure prints ("disassembles") the instructions of a bytecode + * object to stdout. + * + * Results: + * None. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +void +TclPrintByteCodeObj( + Tcl_Interp *interp, /* Used only for Tcl_GetStringFromObj. */ + Tcl_Obj *objPtr) /* The bytecode object to disassemble. */ +{ + Tcl_Obj *bufPtr = TclDisassembleByteCodeObj(objPtr); + + fprintf(stdout, "\n%s", TclGetString(bufPtr)); + Tcl_DecrRefCount(bufPtr); +} + +/* + *---------------------------------------------------------------------- + * + * TclPrintInstruction -- + * + * This procedure prints ("disassembles") one instruction from a bytecode + * object to stdout. + * + * Results: + * Returns the length in bytes of the current instruiction. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +int +TclPrintInstruction( + ByteCode *codePtr, /* Bytecode containing the instruction. */ + const unsigned char *pc) /* Points to first byte of instruction. */ +{ + Tcl_Obj *bufferObj; + int numBytes; + + TclNewObj(bufferObj); + numBytes = FormatInstruction(codePtr, pc, bufferObj); + fprintf(stdout, "%s", TclGetString(bufferObj)); + Tcl_DecrRefCount(bufferObj); + return numBytes; +} + +/* + *---------------------------------------------------------------------- + * + * TclPrintObject -- + * + * This procedure prints up to a specified number of characters from the + * argument Tcl object's string representation to a specified file. + * + * Results: + * None. + * + * Side effects: + * Outputs characters to the specified file. + * + *---------------------------------------------------------------------- + */ + +void +TclPrintObject( + FILE *outFile, /* The file to print the source to. */ + Tcl_Obj *objPtr, /* Points to the Tcl object whose string + * representation should be printed. */ + int maxChars) /* Maximum number of chars to print. */ +{ + char *bytes; + int length; + + bytes = Tcl_GetStringFromObj(objPtr, &length); + TclPrintSource(outFile, bytes, TclMin(length, maxChars)); +} + +/* + *---------------------------------------------------------------------- + * + * TclPrintSource -- + * + * This procedure prints up to a specified number of characters from the + * argument string to a specified file. It tries to produce legible + * output by adding backslashes as necessary. + * + * Results: + * None. + * + * Side effects: + * Outputs characters to the specified file. + * + *---------------------------------------------------------------------- + */ + +void +TclPrintSource( + FILE *outFile, /* The file to print the source to. */ + const char *stringPtr, /* The string to print. */ + int maxChars) /* Maximum number of chars to print. */ +{ + Tcl_Obj *bufferObj; + + TclNewObj(bufferObj); + PrintSourceToObj(bufferObj, stringPtr, maxChars); + fprintf(outFile, "%s", TclGetString(bufferObj)); + Tcl_DecrRefCount(bufferObj); +} +#endif /* TCL_COMPILE_DEBUG */ + +/* + *---------------------------------------------------------------------- + * + * TclDisassembleByteCodeObj -- + * + * Given an object which is of bytecode type, return a disassembled + * version of the bytecode (in a new refcount 0 object). No guarantees + * are made about the details of the contents of the result. + * + *---------------------------------------------------------------------- + */ + +Tcl_Obj * +TclDisassembleByteCodeObj( + Tcl_Obj *objPtr) /* The bytecode object to disassemble. */ +{ + ByteCode *codePtr = objPtr->internalRep.twoPtrValue.ptr1; + unsigned char *codeStart, *codeLimit, *pc; + unsigned char *codeDeltaNext, *codeLengthNext; + unsigned char *srcDeltaNext, *srcLengthNext; + int codeOffset, codeLen, srcOffset, srcLen, numCmds, delta, i; + Interp *iPtr = (Interp *) *codePtr->interpHandle; + Tcl_Obj *bufferObj; + char ptrBuf1[20], ptrBuf2[20]; + + TclNewObj(bufferObj); + if (codePtr->refCount <= 0) { + return bufferObj; /* Already freed. */ + } + + codeStart = codePtr->codeStart; + codeLimit = codeStart + codePtr->numCodeBytes; + numCmds = codePtr->numCommands; + + /* + * Print header lines describing the ByteCode. + */ + + sprintf(ptrBuf1, "%p", codePtr); + sprintf(ptrBuf2, "%p", iPtr); + Tcl_AppendPrintfToObj(bufferObj, + "ByteCode 0x%s, refCt %u, epoch %u, interp 0x%s (epoch %u)\n", + ptrBuf1, codePtr->refCount, codePtr->compileEpoch, ptrBuf2, + iPtr->compileEpoch); + Tcl_AppendToObj(bufferObj, " Source ", -1); + PrintSourceToObj(bufferObj, codePtr->source, + TclMin(codePtr->numSrcBytes, 55)); + Tcl_AppendPrintfToObj(bufferObj, + "\n Cmds %d, src %d, inst %d, litObjs %u, aux %d, stkDepth %u, code/src %.2f\n", + numCmds, codePtr->numSrcBytes, codePtr->numCodeBytes, + codePtr->numLitObjects, codePtr->numAuxDataItems, + codePtr->maxStackDepth, +#ifdef TCL_COMPILE_STATS + codePtr->numSrcBytes? + codePtr->structureSize/(float)codePtr->numSrcBytes : +#endif + 0.0); + +#ifdef TCL_COMPILE_STATS + Tcl_AppendPrintfToObj(bufferObj, + " Code %lu = header %lu+inst %d+litObj %lu+exc %lu+aux %lu+cmdMap %d\n", + (unsigned long) codePtr->structureSize, + (unsigned long) (sizeof(ByteCode) - sizeof(size_t) - sizeof(Tcl_Time)), + codePtr->numCodeBytes, + (unsigned long) (codePtr->numLitObjects * sizeof(Tcl_Obj *)), + (unsigned long) (codePtr->numExceptRanges*sizeof(ExceptionRange)), + (unsigned long) (codePtr->numAuxDataItems * sizeof(AuxData)), + codePtr->numCmdLocBytes); +#endif /* TCL_COMPILE_STATS */ + + /* + * If the ByteCode is the compiled body of a Tcl procedure, print + * information about that procedure. Note that we don't know the + * procedure's name since ByteCode's can be shared among procedures. + */ + + if (codePtr->procPtr != NULL) { + Proc *procPtr = codePtr->procPtr; + int numCompiledLocals = procPtr->numCompiledLocals; + + sprintf(ptrBuf1, "%p", procPtr); + Tcl_AppendPrintfToObj(bufferObj, + " Proc 0x%s, refCt %d, args %d, compiled locals %d\n", + ptrBuf1, procPtr->refCount, procPtr->numArgs, + numCompiledLocals); + if (numCompiledLocals > 0) { + CompiledLocal *localPtr = procPtr->firstLocalPtr; + + for (i = 0; i < numCompiledLocals; i++) { + Tcl_AppendPrintfToObj(bufferObj, + " slot %d%s%s%s%s%s%s", i, + (localPtr->flags & (VAR_ARRAY|VAR_LINK)) ? "" : ", scalar", + (localPtr->flags & VAR_ARRAY) ? ", array" : "", + (localPtr->flags & VAR_LINK) ? ", link" : "", + (localPtr->flags & VAR_ARGUMENT) ? ", arg" : "", + (localPtr->flags & VAR_TEMPORARY) ? ", temp" : "", + (localPtr->flags & VAR_RESOLVED) ? ", resolved" : ""); + if (TclIsVarTemporary(localPtr)) { + Tcl_AppendToObj(bufferObj, "\n", -1); + } else { + Tcl_AppendPrintfToObj(bufferObj, ", \"%s\"\n", + localPtr->name); + } + localPtr = localPtr->nextPtr; + } + } + } + + /* + * Print the ExceptionRange array. + */ + + if (codePtr->numExceptRanges > 0) { + Tcl_AppendPrintfToObj(bufferObj, " Exception ranges %d, depth %d:\n", + codePtr->numExceptRanges, codePtr->maxExceptDepth); + for (i = 0; i < codePtr->numExceptRanges; i++) { + ExceptionRange *rangePtr = &codePtr->exceptArrayPtr[i]; + + Tcl_AppendPrintfToObj(bufferObj, + " %d: level %d, %s, pc %d-%d, ", + i, rangePtr->nestingLevel, + (rangePtr->type==LOOP_EXCEPTION_RANGE ? "loop" : "catch"), + rangePtr->codeOffset, + (rangePtr->codeOffset + rangePtr->numCodeBytes - 1)); + switch (rangePtr->type) { + case LOOP_EXCEPTION_RANGE: + Tcl_AppendPrintfToObj(bufferObj, "continue %d, break %d\n", + rangePtr->continueOffset, rangePtr->breakOffset); + break; + case CATCH_EXCEPTION_RANGE: + Tcl_AppendPrintfToObj(bufferObj, "catch %d\n", + rangePtr->catchOffset); + break; + default: + Tcl_Panic("TclDisassembleByteCodeObj: bad ExceptionRange type %d", + rangePtr->type); + } + } + } + + /* + * If there were no commands (e.g., an expression or an empty string was + * compiled), just print all instructions and return. + */ + + if (numCmds == 0) { + pc = codeStart; + while (pc < codeLimit) { + Tcl_AppendToObj(bufferObj, " ", -1); + pc += FormatInstruction(codePtr, pc, bufferObj); + } + return bufferObj; + } + + /* + * Print table showing the code offset, source offset, and source length + * for each command. These are encoded as a sequence of bytes. + */ + + Tcl_AppendPrintfToObj(bufferObj, " Commands %d:", numCmds); + codeDeltaNext = codePtr->codeDeltaStart; + codeLengthNext = codePtr->codeLengthStart; + srcDeltaNext = codePtr->srcDeltaStart; + srcLengthNext = codePtr->srcLengthStart; + codeOffset = srcOffset = 0; + for (i = 0; i < numCmds; i++) { + if ((unsigned) *codeDeltaNext == (unsigned) 0xFF) { + codeDeltaNext++; + delta = TclGetInt4AtPtr(codeDeltaNext); + codeDeltaNext += 4; + } else { + delta = TclGetInt1AtPtr(codeDeltaNext); + codeDeltaNext++; + } + codeOffset += delta; + + if ((unsigned) *codeLengthNext == (unsigned) 0xFF) { + codeLengthNext++; + codeLen = TclGetInt4AtPtr(codeLengthNext); + codeLengthNext += 4; + } else { + codeLen = TclGetInt1AtPtr(codeLengthNext); + codeLengthNext++; + } + + if ((unsigned) *srcDeltaNext == (unsigned) 0xFF) { + srcDeltaNext++; + delta = TclGetInt4AtPtr(srcDeltaNext); + srcDeltaNext += 4; + } else { + delta = TclGetInt1AtPtr(srcDeltaNext); + srcDeltaNext++; + } + srcOffset += delta; + + if ((unsigned) *srcLengthNext == (unsigned) 0xFF) { + srcLengthNext++; + srcLen = TclGetInt4AtPtr(srcLengthNext); + srcLengthNext += 4; + } else { + srcLen = TclGetInt1AtPtr(srcLengthNext); + srcLengthNext++; + } + + Tcl_AppendPrintfToObj(bufferObj, "%s%4d: pc %d-%d, src %d-%d", + ((i % 2)? " " : "\n "), + (i+1), codeOffset, (codeOffset + codeLen - 1), + srcOffset, (srcOffset + srcLen - 1)); + } + if (numCmds > 0) { + Tcl_AppendToObj(bufferObj, "\n", -1); + } + + /* + * Print each instruction. If the instruction corresponds to the start of + * a command, print the command's source. Note that we don't need the code + * length here. + */ + + codeDeltaNext = codePtr->codeDeltaStart; + srcDeltaNext = codePtr->srcDeltaStart; + srcLengthNext = codePtr->srcLengthStart; + codeOffset = srcOffset = 0; + pc = codeStart; + for (i = 0; i < numCmds; i++) { + if ((unsigned) *codeDeltaNext == (unsigned) 0xFF) { + codeDeltaNext++; + delta = TclGetInt4AtPtr(codeDeltaNext); + codeDeltaNext += 4; + } else { + delta = TclGetInt1AtPtr(codeDeltaNext); + codeDeltaNext++; + } + codeOffset += delta; + + if ((unsigned) *srcDeltaNext == (unsigned) 0xFF) { + srcDeltaNext++; + delta = TclGetInt4AtPtr(srcDeltaNext); + srcDeltaNext += 4; + } else { + delta = TclGetInt1AtPtr(srcDeltaNext); + srcDeltaNext++; + } + srcOffset += delta; + + if ((unsigned) *srcLengthNext == (unsigned) 0xFF) { + srcLengthNext++; + srcLen = TclGetInt4AtPtr(srcLengthNext); + srcLengthNext += 4; + } else { + srcLen = TclGetInt1AtPtr(srcLengthNext); + srcLengthNext++; + } + + /* + * Print instructions before command i. + */ + + while ((pc-codeStart) < codeOffset) { + Tcl_AppendToObj(bufferObj, " ", -1); + pc += FormatInstruction(codePtr, pc, bufferObj); + } + + Tcl_AppendPrintfToObj(bufferObj, " Command %d: ", i+1); + PrintSourceToObj(bufferObj, (codePtr->source + srcOffset), + TclMin(srcLen, 55)); + Tcl_AppendToObj(bufferObj, "\n", -1); + } + if (pc < codeLimit) { + /* + * Print instructions after the last command. + */ + + while (pc < codeLimit) { + Tcl_AppendToObj(bufferObj, " ", -1); + pc += FormatInstruction(codePtr, pc, bufferObj); + } + } + return bufferObj; +} + +/* + *---------------------------------------------------------------------- + * + * FormatInstruction -- + * + * Appends a representation of a bytecode instruction to a Tcl_Obj. + * + *---------------------------------------------------------------------- + */ + +static int +FormatInstruction( + ByteCode *codePtr, /* Bytecode containing the instruction. */ + const unsigned char *pc, /* Points to first byte of instruction. */ + Tcl_Obj *bufferObj) /* Object to append instruction info to. */ +{ + Proc *procPtr = codePtr->procPtr; + unsigned char opCode = *pc; + register const InstructionDesc *instDesc = &tclInstructionTable[opCode]; + unsigned char *codeStart = codePtr->codeStart; + unsigned pcOffset = pc - codeStart; + int opnd = 0, i, j, numBytes = 1; + int localCt = procPtr ? procPtr->numCompiledLocals : 0; + CompiledLocal *localPtr = procPtr ? procPtr->firstLocalPtr : NULL; + char suffixBuffer[128]; /* Additional info to print after main opcode + * and immediates. */ + char *suffixSrc = NULL; + Tcl_Obj *suffixObj = NULL; + AuxData *auxPtr = NULL; + + suffixBuffer[0] = '\0'; + Tcl_AppendPrintfToObj(bufferObj, "(%u) %s ", pcOffset, instDesc->name); + for (i = 0; i < instDesc->numOperands; i++) { + switch (instDesc->opTypes[i]) { + case OPERAND_INT1: + opnd = TclGetInt1AtPtr(pc+numBytes); numBytes++; + if (opCode == INST_JUMP1 || opCode == INST_JUMP_TRUE1 + || opCode == INST_JUMP_FALSE1) { + sprintf(suffixBuffer, "pc %u", pcOffset+opnd); + } + Tcl_AppendPrintfToObj(bufferObj, "%+d ", opnd); + break; + case OPERAND_INT4: + opnd = TclGetInt4AtPtr(pc+numBytes); numBytes += 4; + if (opCode == INST_JUMP4 || opCode == INST_JUMP_TRUE4 + || opCode == INST_JUMP_FALSE4) { + sprintf(suffixBuffer, "pc %u", pcOffset+opnd); + } else if (opCode == INST_START_CMD) { + sprintf(suffixBuffer, "next cmd at pc %u", pcOffset+opnd); + } + Tcl_AppendPrintfToObj(bufferObj, "%+d ", opnd); + break; + case OPERAND_UINT1: + opnd = TclGetUInt1AtPtr(pc+numBytes); numBytes++; + if (opCode == INST_PUSH1) { + suffixObj = codePtr->objArrayPtr[opnd]; + } + Tcl_AppendPrintfToObj(bufferObj, "%u ", (unsigned) opnd); + break; + case OPERAND_AUX4: + case OPERAND_UINT4: + opnd = TclGetUInt4AtPtr(pc+numBytes); numBytes += 4; + if (opCode == INST_PUSH4) { + suffixObj = codePtr->objArrayPtr[opnd]; + } else if (opCode == INST_START_CMD && opnd != 1) { + sprintf(suffixBuffer+strlen(suffixBuffer), + ", %u cmds start here", opnd); + } + Tcl_AppendPrintfToObj(bufferObj, "%u ", (unsigned) opnd); + if (instDesc->opTypes[i] == OPERAND_AUX4) { + auxPtr = &codePtr->auxDataArrayPtr[opnd]; + } + break; + case OPERAND_IDX4: + opnd = TclGetInt4AtPtr(pc+numBytes); numBytes += 4; + if (opnd >= -1) { + Tcl_AppendPrintfToObj(bufferObj, "%d ", opnd); + } else if (opnd == -2) { + Tcl_AppendPrintfToObj(bufferObj, "end "); + } else { + Tcl_AppendPrintfToObj(bufferObj, "end-%d ", -2-opnd); + } + break; + case OPERAND_LVT1: + opnd = TclGetUInt1AtPtr(pc+numBytes); + numBytes++; + goto printLVTindex; + case OPERAND_LVT4: + opnd = TclGetUInt4AtPtr(pc+numBytes); + numBytes += 4; + printLVTindex: + if (localPtr != NULL) { + if (opnd >= localCt) { + Tcl_Panic("FormatInstruction: bad local var index %u (%u locals)", + (unsigned) opnd, localCt); + } + for (j = 0; j < opnd; j++) { + localPtr = localPtr->nextPtr; + } + if (TclIsVarTemporary(localPtr)) { + sprintf(suffixBuffer, "temp var %u", (unsigned) opnd); + } else { + sprintf(suffixBuffer, "var "); + suffixSrc = localPtr->name; + } + } + Tcl_AppendPrintfToObj(bufferObj, "%%v%u ", (unsigned) opnd); + break; + case OPERAND_NONE: + default: + break; + } + } + if (suffixObj) { + const char *bytes; + int length; + + Tcl_AppendToObj(bufferObj, "\t# ", -1); + bytes = Tcl_GetStringFromObj(codePtr->objArrayPtr[opnd], &length); + PrintSourceToObj(bufferObj, bytes, TclMin(length, 40)); + } else if (suffixBuffer[0]) { + Tcl_AppendPrintfToObj(bufferObj, "\t# %s", suffixBuffer); + if (suffixSrc) { + PrintSourceToObj(bufferObj, suffixSrc, 40); + } + } + Tcl_AppendToObj(bufferObj, "\n", -1); + if (auxPtr && auxPtr->type->printProc) { + Tcl_AppendToObj(bufferObj, "\t\t[", -1); + auxPtr->type->printProc(auxPtr->clientData, bufferObj, codePtr, + pcOffset); + Tcl_AppendToObj(bufferObj, "]\n", -1); + } + return numBytes; +} + +/* + *---------------------------------------------------------------------- + * + * TclGetInnerContext -- + * + * If possible, returns a list capturing the inner context. Otherwise + * return NULL. + * + *---------------------------------------------------------------------- + */ + +Tcl_Obj * +TclGetInnerContext( + Tcl_Interp *interp, + const unsigned char *pc, + Tcl_Obj **tosPtr) +{ + int objc = 0, off = 0; + Tcl_Obj *result; + Interp *iPtr = (Interp *) interp; + + switch (*pc) { + case INST_STR_LEN: + case INST_LNOT: + case INST_BITNOT: + case INST_UMINUS: + case INST_UPLUS: + case INST_TRY_CVT_TO_NUMERIC: + case INST_EXPAND_STKTOP: + case INST_EXPR_STK: + objc = 1; + break; + + case INST_LIST_IN: + case INST_LIST_NOT_IN: /* Basic list containment operators. */ + case INST_STR_EQ: + case INST_STR_NEQ: /* String (in)equality check */ + case INST_STR_CMP: /* String compare. */ + case INST_STR_INDEX: + case INST_STR_MATCH: + case INST_REGEXP: + case INST_EQ: + case INST_NEQ: + case INST_LT: + case INST_GT: + case INST_LE: + case INST_GE: + case INST_MOD: + case INST_LSHIFT: + case INST_RSHIFT: + case INST_BITOR: + case INST_BITXOR: + case INST_BITAND: + case INST_EXPON: + case INST_ADD: + case INST_SUB: + case INST_DIV: + case INST_MULT: + objc = 2; + break; + + case INST_RETURN_STK: + /* early pop. TODO: dig out opt dict too :/ */ + objc = 1; + break; + + case INST_SYNTAX: + case INST_RETURN_IMM: + objc = 2; + break; + + case INST_INVOKE_STK4: + objc = TclGetUInt4AtPtr(pc+1); + break; + + case INST_INVOKE_STK1: + objc = TclGetUInt1AtPtr(pc+1); + break; + } + + result = iPtr->innerContext; + if (Tcl_IsShared(result)) { + Tcl_DecrRefCount(result); + iPtr->innerContext = result = Tcl_NewListObj(objc + 1, NULL); + Tcl_IncrRefCount(result); + } else { + int len; + + /* + * Reset while keeping the list intrep as much as possible. + */ + + Tcl_ListObjLength(interp, result, &len); + Tcl_ListObjReplace(interp, result, 0, len, 0, NULL); + } + Tcl_ListObjAppendElement(NULL, result, TclNewInstNameObj(*pc)); + + for (; objc>0 ; objc--) { + Tcl_Obj *objPtr; + + objPtr = tosPtr[1 - objc + off]; + if (!objPtr) { + Tcl_Panic("InnerContext: bad tos -- appending null object"); + } + if ((objPtr->refCount<=0) +#ifdef TCL_MEM_DEBUG + || (objPtr->refCount==0x61616161) +#endif + ) { + Tcl_Panic("InnerContext: bad tos -- appending freed object %p", + objPtr); + } + Tcl_ListObjAppendElement(NULL, result, objPtr); + } + + return result; +} + +/* + *---------------------------------------------------------------------- + * + * TclNewInstNameObj -- + * + * Creates a new InstName Tcl_Obj based on the given instruction + * + *---------------------------------------------------------------------- + */ + +Tcl_Obj * +TclNewInstNameObj( + unsigned char inst) +{ + Tcl_Obj *objPtr = Tcl_NewObj(); + + objPtr->typePtr = &tclInstNameType; + objPtr->internalRep.longValue = (long) inst; + objPtr->bytes = NULL; + + return objPtr; +} + +/* + *---------------------------------------------------------------------- + * + * UpdateStringOfInstName -- + * + * Update the string representation for an instruction name object. + * + *---------------------------------------------------------------------- + */ + +static void +UpdateStringOfInstName( + Tcl_Obj *objPtr) +{ + int inst = objPtr->internalRep.longValue; + char *s, buf[20]; + int len; + + if ((inst < 0) || (inst > LAST_INST_OPCODE)) { + sprintf(buf, "inst_%d", inst); + s = buf; + } else { + s = (char *) tclInstructionTable[objPtr->internalRep.longValue].name; + } + len = strlen(s); + objPtr->bytes = ckalloc(len + 1); + memcpy(objPtr->bytes, s, len + 1); + objPtr->length = len; +} + +/* + *---------------------------------------------------------------------- + * + * PrintSourceToObj -- + * + * Appends a quoted representation of a string to a Tcl_Obj. + * + *---------------------------------------------------------------------- + */ + +static void +PrintSourceToObj( + Tcl_Obj *appendObj, /* The object to print the source to. */ + const char *stringPtr, /* The string to print. */ + int maxChars) /* Maximum number of chars to print. */ +{ + register const char *p; + register int i = 0; + + if (stringPtr == NULL) { + Tcl_AppendToObj(appendObj, "\"\"", -1); + return; + } + + Tcl_AppendToObj(appendObj, "\"", -1); + p = stringPtr; + for (; (*p != '\0') && (i < maxChars); p++, i++) { + switch (*p) { + case '"': + Tcl_AppendToObj(appendObj, "\\\"", -1); + continue; + case '\f': + Tcl_AppendToObj(appendObj, "\\f", -1); + continue; + case '\n': + Tcl_AppendToObj(appendObj, "\\n", -1); + continue; + case '\r': + Tcl_AppendToObj(appendObj, "\\r", -1); + continue; + case '\t': + Tcl_AppendToObj(appendObj, "\\t", -1); + continue; + case '\v': + Tcl_AppendToObj(appendObj, "\\v", -1); + continue; + default: + Tcl_AppendPrintfToObj(appendObj, "%c", *p); + continue; + } + } + Tcl_AppendToObj(appendObj, "\"", -1); +} + +/* + *---------------------------------------------------------------------- + * + * Tcl_DisassembleObjCmd -- + * + * Implementation of the "::tcl::unsupported::disassemble" command. This + * command is not documented, but will disassemble procedures, lambda + * terms and general scripts. Note that will compile terms if necessary + * in order to disassemble them. + * + *---------------------------------------------------------------------- + */ + +int +Tcl_DisassembleObjCmd( + ClientData dummy, /* Not used. */ + Tcl_Interp *interp, /* Current interpreter. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument objects. */ +{ + static const char *const types[] = { + "lambda", "method", "objmethod", "proc", "script", NULL + }; + enum Types { + DISAS_LAMBDA, DISAS_CLASS_METHOD, DISAS_OBJECT_METHOD, DISAS_PROC, + DISAS_SCRIPT + }; + int idx, result; + Tcl_Obj *codeObjPtr = NULL; + Proc *procPtr = NULL; + Tcl_HashEntry *hPtr; + Object *oPtr; + + if (objc < 2) { + Tcl_WrongNumArgs(interp, 1, objv, "type ..."); + return TCL_ERROR; + } + if (Tcl_GetIndexFromObj(interp, objv[1], types, "type", 0, &idx)!=TCL_OK){ + return TCL_ERROR; + } + + switch ((enum Types) idx) { + case DISAS_LAMBDA: { + Command cmd; + Tcl_Obj *nsObjPtr; + Tcl_Namespace *nsPtr; + + /* + * Compile (if uncompiled) and disassemble a lambda term. + */ + + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "lambdaTerm"); + return TCL_ERROR; + } + if (objv[2]->typePtr == &tclLambdaType) { + procPtr = objv[2]->internalRep.twoPtrValue.ptr1; + } + if (procPtr == NULL || procPtr->iPtr != (Interp *) interp) { + result = tclLambdaType.setFromAnyProc(interp, objv[2]); + if (result != TCL_OK) { + return result; + } + procPtr = objv[2]->internalRep.twoPtrValue.ptr1; + } + + memset(&cmd, 0, sizeof(Command)); + nsObjPtr = objv[2]->internalRep.twoPtrValue.ptr2; + result = TclGetNamespaceFromObj(interp, nsObjPtr, &nsPtr); + if (result != TCL_OK) { + return result; + } + cmd.nsPtr = (Namespace *) nsPtr; + procPtr->cmdPtr = &cmd; + result = TclPushProcCallFrame(procPtr, interp, objc, objv, 1); + if (result != TCL_OK) { + return result; + } + TclPopStackFrame(interp); + codeObjPtr = procPtr->bodyPtr; + break; + } + case DISAS_PROC: + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "procName"); + return TCL_ERROR; + } + + procPtr = TclFindProc((Interp *) interp, TclGetString(objv[2])); + if (procPtr == NULL) { + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "\"%s\" isn't a procedure", TclGetString(objv[2]))); + Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "PROC", + TclGetString(objv[2]), NULL); + return TCL_ERROR; + } + + /* + * Compile (if uncompiled) and disassemble a procedure. + */ + + result = TclPushProcCallFrame(procPtr, interp, 2, objv+1, 1); + if (result != TCL_OK) { + return result; + } + TclPopStackFrame(interp); + codeObjPtr = procPtr->bodyPtr; + break; + case DISAS_SCRIPT: + /* + * Compile and disassemble a script. + */ + + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "script"); + return TCL_ERROR; + } + if ((objv[2]->typePtr != &tclByteCodeType) + && (TclSetByteCodeFromAny(interp, objv[2], NULL, NULL) != TCL_OK)) { + return TCL_ERROR; + } + codeObjPtr = objv[2]; + break; + + case DISAS_CLASS_METHOD: + if (objc != 4) { + Tcl_WrongNumArgs(interp, 2, objv, "className methodName"); + return TCL_ERROR; + } + + /* + * Look up the body of a class method. + */ + + oPtr = (Object *) Tcl_GetObjectFromObj(interp, objv[2]); + if (oPtr == NULL) { + return TCL_ERROR; + } + if (oPtr->classPtr == NULL) { + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "\"%s\" is not a class", TclGetString(objv[2]))); + Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "CLASS", + TclGetString(objv[2]), NULL); + return TCL_ERROR; + } + hPtr = Tcl_FindHashEntry(&oPtr->classPtr->classMethods, + (char *) objv[3]); + goto methodBody; + case DISAS_OBJECT_METHOD: + if (objc != 4) { + Tcl_WrongNumArgs(interp, 2, objv, "objectName methodName"); + return TCL_ERROR; + } + + /* + * Look up the body of an instance method. + */ + + oPtr = (Object *) Tcl_GetObjectFromObj(interp, objv[2]); + if (oPtr == NULL) { + return TCL_ERROR; + } + if (oPtr->methodsPtr == NULL) { + goto unknownMethod; + } + hPtr = Tcl_FindHashEntry(oPtr->methodsPtr, (char *) objv[3]); + + /* + * Compile (if necessary) and disassemble a method body. + */ + + methodBody: + if (hPtr == NULL) { + unknownMethod: + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "unknown method \"%s\"", TclGetString(objv[3]))); + Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD", + TclGetString(objv[3]), NULL); + return TCL_ERROR; + } + procPtr = TclOOGetProcFromMethod(Tcl_GetHashValue(hPtr)); + if (procPtr == NULL) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "body not available for this kind of method", -1)); + Tcl_SetErrorCode(interp, "TCL", "OPERATION", "DISASSEMBLE", + "METHODTYPE", NULL); + return TCL_ERROR; + } + if (procPtr->bodyPtr->typePtr != &tclByteCodeType) { + Command cmd; + + /* + * Yes, this is ugly, but we need to pass the namespace in to the + * compiler in two places. + */ + + cmd.nsPtr = (Namespace *) oPtr->namespacePtr; + procPtr->cmdPtr = &cmd; + result = TclProcCompileProc(interp, procPtr, procPtr->bodyPtr, + (Namespace *) oPtr->namespacePtr, "body of method", + TclGetString(objv[3])); + procPtr->cmdPtr = NULL; + if (result != TCL_OK) { + return result; + } + } + codeObjPtr = procPtr->bodyPtr; + break; + default: + CLANG_ASSERT(0); + } + + /* + * Do the actual disassembly. + */ + + if (((ByteCode *) codeObjPtr->internalRep.twoPtrValue.ptr1)->flags + & TCL_BYTECODE_PRECOMPILED) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "may not disassemble prebuilt bytecode", -1)); + Tcl_SetErrorCode(interp, "TCL", "OPERATION", "DISASSEMBLE", + "BYTECODE", NULL); + return TCL_ERROR; + } + Tcl_SetObjResult(interp, TclDisassembleByteCodeObj(codeObjPtr)); + return TCL_OK; +} + +/* + * Local Variables: + * mode: c + * c-basic-offset: 4 + * fill-column: 78 + * tab-width: 8 + * End: + */ diff --git a/generic/tclProc.c b/generic/tclProc.c index 18985a1..23d8e70 100644 --- a/generic/tclProc.c +++ b/generic/tclProc.c @@ -15,7 +15,6 @@ #include "tclInt.h" #include "tclCompile.h" -#include "tclOOInt.h" /* * Variables that are part of the [apply] command implementation and which @@ -41,9 +40,6 @@ static void InitResolvedLocals(Tcl_Interp *interp, ByteCode *codePtr, Var *defPtr, Namespace *nsPtr); static void InitLocalCache(Proc *procPtr); -static int PushProcCallFrame(ClientData clientData, - register Tcl_Interp *interp, int objc, - Tcl_Obj *const objv[], int isLambda); static void ProcBodyDup(Tcl_Obj *srcPtr, Tcl_Obj *dupPtr); static void ProcBodyFree(Tcl_Obj *objPtr); static int ProcWrongNumArgs(Tcl_Interp *interp, int skip); @@ -95,7 +91,7 @@ static const Tcl_ObjType levelReferenceType = { * will execute within. */ -static const Tcl_ObjType lambdaType = { +const Tcl_ObjType tclLambdaType = { "lambdaExpr", /* name */ FreeLambdaInternalRep, /* freeIntRepProc */ DupLambdaInternalRep, /* dupIntRepProc */ @@ -221,7 +217,7 @@ Tcl_ProcObjCmd( * * This code is nearly identical to the #280 code in SetLambdaFromAny, see * this file. The differences are the different index of the body in the - * line array of the context, and the lamdba code requires some special + * line array of the context, and the lambda code requires some special * processing. Find a way to factor the common elements into a single * function. */ @@ -1571,7 +1567,7 @@ InitArgsAndLocals( /* *---------------------------------------------------------------------- * - * PushProcCallFrame -- + * TclPushProcCallFrame -- * * Compiles a proc body if necessary, then pushes a CallFrame suitable * for executing it. @@ -1586,8 +1582,8 @@ InitArgsAndLocals( *---------------------------------------------------------------------- */ -static int -PushProcCallFrame( +int +TclPushProcCallFrame( ClientData clientData, /* Record describing procedure to be * interpreted. */ register Tcl_Interp *interp,/* Interpreter in which procedure was @@ -1708,7 +1704,7 @@ TclNRInterpProc( * procedure. */ Tcl_Obj *const objv[]) /* Argument value objects. */ { - int result = PushProcCallFrame(clientData, interp, objc, objv, + int result = TclPushProcCallFrame(clientData, interp, objc, objv, /*isLambda*/ 0); if (result != TCL_OK) { @@ -2451,7 +2447,7 @@ DupLambdaInternalRep( procPtr->refCount++; Tcl_IncrRefCount(nsObjPtr); - copyPtr->typePtr = &lambdaType; + copyPtr->typePtr = &tclLambdaType; } static void @@ -2488,7 +2484,7 @@ SetLambdaFromAny( /* * Convert objPtr to list type first; if it cannot be converted, or if its - * length is not 2, then it cannot be converted to lambdaType. + * length is not 2, then it cannot be converted to tclLambdaType. */ result = TclListObjGetElements(NULL, objPtr, &objc, &objv); @@ -2634,14 +2630,14 @@ SetLambdaFromAny( /* * Free the list internalrep of objPtr - this will free argsPtr, but * bodyPtr retains a reference from the Proc structure. Then finish the - * conversion to lambdaType. + * conversion to tclLambdaType. */ TclFreeIntRep(objPtr); objPtr->internalRep.twoPtrValue.ptr1 = procPtr; objPtr->internalRep.twoPtrValue.ptr2 = nsObjPtr; - objPtr->typePtr = &lambdaType; + objPtr->typePtr = &tclLambdaType; return TCL_OK; } @@ -2692,12 +2688,12 @@ TclNRApplyObjCmd( } /* - * Set lambdaPtr, convert it to lambdaType in the current interp if + * Set lambdaPtr, convert it to tclLambdaType in the current interp if * necessary. */ lambdaPtr = objv[1]; - if (lambdaPtr->typePtr == &lambdaType) { + if (lambdaPtr->typePtr == &tclLambdaType) { procPtr = lambdaPtr->internalRep.twoPtrValue.ptr1; } @@ -2775,7 +2771,7 @@ TclNRApplyObjCmd( } extraPtr->isRootEnsemble = isRootEnsemble; - result = PushProcCallFrame(procPtr, interp, objc, objv, 1); + result = TclPushProcCallFrame(procPtr, interp, objc, objv, 1); if (result == TCL_OK) { TclNRAddCallback(interp, ApplyNR2, extraPtr, NULL, NULL, NULL); result = TclNRInterpProcCore(interp, objv[1], 2, &MakeLambdaError); @@ -2835,234 +2831,6 @@ MakeLambdaError( } /* - *---------------------------------------------------------------------- - * - * Tcl_DisassembleObjCmd -- - * - * Implementation of the "::tcl::unsupported::disassemble" command. This - * command is not documented, but will disassemble procedures, lambda - * terms and general scripts. Note that will compile terms if necessary - * in order to disassemble them. - * - *---------------------------------------------------------------------- - */ - -int -Tcl_DisassembleObjCmd( - ClientData dummy, /* Not used. */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ -{ - static const char *const types[] = { - "lambda", "method", "objmethod", "proc", "script", NULL - }; - enum Types { - DISAS_LAMBDA, DISAS_CLASS_METHOD, DISAS_OBJECT_METHOD, DISAS_PROC, - DISAS_SCRIPT - }; - int idx, result; - Tcl_Obj *codeObjPtr = NULL; - Proc *procPtr = NULL; - Tcl_HashEntry *hPtr; - Object *oPtr; - - if (objc < 2) { - Tcl_WrongNumArgs(interp, 1, objv, "type ..."); - return TCL_ERROR; - } - if (Tcl_GetIndexFromObj(interp, objv[1], types, "type", 0, &idx)!=TCL_OK){ - return TCL_ERROR; - } - - switch ((enum Types) idx) { - case DISAS_LAMBDA: { - Command cmd; - Tcl_Obj *nsObjPtr; - Tcl_Namespace *nsPtr; - - /* - * Compile (if uncompiled) and disassemble a lambda term. - */ - - if (objc != 3) { - Tcl_WrongNumArgs(interp, 2, objv, "lambdaTerm"); - return TCL_ERROR; - } - if (objv[2]->typePtr == &lambdaType) { - procPtr = objv[2]->internalRep.twoPtrValue.ptr1; - } - if (procPtr == NULL || procPtr->iPtr != (Interp *) interp) { - result = SetLambdaFromAny(interp, objv[2]); - if (result != TCL_OK) { - return result; - } - procPtr = objv[2]->internalRep.twoPtrValue.ptr1; - } - - memset(&cmd, 0, sizeof(Command)); - nsObjPtr = objv[2]->internalRep.twoPtrValue.ptr2; - result = TclGetNamespaceFromObj(interp, nsObjPtr, &nsPtr); - if (result != TCL_OK) { - return result; - } - cmd.nsPtr = (Namespace *) nsPtr; - procPtr->cmdPtr = &cmd; - result = PushProcCallFrame(procPtr, interp, objc, objv, 1); - if (result != TCL_OK) { - return result; - } - TclPopStackFrame(interp); - codeObjPtr = procPtr->bodyPtr; - break; - } - case DISAS_PROC: - if (objc != 3) { - Tcl_WrongNumArgs(interp, 2, objv, "procName"); - return TCL_ERROR; - } - - procPtr = TclFindProc((Interp *) interp, TclGetString(objv[2])); - if (procPtr == NULL) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "\"%s\" isn't a procedure", TclGetString(objv[2]))); - Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "PROC", - TclGetString(objv[2]), NULL); - return TCL_ERROR; - } - - /* - * Compile (if uncompiled) and disassemble a procedure. - */ - - result = PushProcCallFrame(procPtr, interp, 2, objv+1, 1); - if (result != TCL_OK) { - return result; - } - TclPopStackFrame(interp); - codeObjPtr = procPtr->bodyPtr; - break; - case DISAS_SCRIPT: - /* - * Compile and disassemble a script. - */ - - if (objc != 3) { - Tcl_WrongNumArgs(interp, 2, objv, "script"); - return TCL_ERROR; - } - if ((objv[2]->typePtr != &tclByteCodeType) - && (TclSetByteCodeFromAny(interp, objv[2], NULL, NULL) != TCL_OK)) { - return TCL_ERROR; - } - codeObjPtr = objv[2]; - break; - - case DISAS_CLASS_METHOD: - if (objc != 4) { - Tcl_WrongNumArgs(interp, 2, objv, "className methodName"); - return TCL_ERROR; - } - - /* - * Look up the body of a class method. - */ - - oPtr = (Object *) Tcl_GetObjectFromObj(interp, objv[2]); - if (oPtr == NULL) { - return TCL_ERROR; - } - if (oPtr->classPtr == NULL) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "\"%s\" is not a class", TclGetString(objv[2]))); - Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "CLASS", - TclGetString(objv[2]), NULL); - return TCL_ERROR; - } - hPtr = Tcl_FindHashEntry(&oPtr->classPtr->classMethods, - (char *) objv[3]); - goto methodBody; - case DISAS_OBJECT_METHOD: - if (objc != 4) { - Tcl_WrongNumArgs(interp, 2, objv, "objectName methodName"); - return TCL_ERROR; - } - - /* - * Look up the body of an instance method. - */ - - oPtr = (Object *) Tcl_GetObjectFromObj(interp, objv[2]); - if (oPtr == NULL) { - return TCL_ERROR; - } - if (oPtr->methodsPtr == NULL) { - goto unknownMethod; - } - hPtr = Tcl_FindHashEntry(oPtr->methodsPtr, (char *) objv[3]); - - /* - * Compile (if necessary) and disassemble a method body. - */ - - methodBody: - if (hPtr == NULL) { - unknownMethod: - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "unknown method \"%s\"", TclGetString(objv[3]))); - Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD", - TclGetString(objv[3]), NULL); - return TCL_ERROR; - } - procPtr = TclOOGetProcFromMethod(Tcl_GetHashValue(hPtr)); - if (procPtr == NULL) { - Tcl_SetObjResult(interp, Tcl_NewStringObj( - "body not available for this kind of method", -1)); - Tcl_SetErrorCode(interp, "TCL", "OPERATION", "DISASSEMBLE", - "METHODTYPE", NULL); - return TCL_ERROR; - } - if (procPtr->bodyPtr->typePtr != &tclByteCodeType) { - Command cmd; - - /* - * Yes, this is ugly, but we need to pass the namespace in to the - * compiler in two places. - */ - - cmd.nsPtr = (Namespace *) oPtr->namespacePtr; - procPtr->cmdPtr = &cmd; - result = TclProcCompileProc(interp, procPtr, procPtr->bodyPtr, - (Namespace *) oPtr->namespacePtr, "body of method", - TclGetString(objv[3])); - procPtr->cmdPtr = NULL; - if (result != TCL_OK) { - return result; - } - } - codeObjPtr = procPtr->bodyPtr; - break; - default: - CLANG_ASSERT(0); - } - - /* - * Do the actual disassembly. - */ - - if (((ByteCode *) codeObjPtr->internalRep.twoPtrValue.ptr1)->flags - & TCL_BYTECODE_PRECOMPILED) { - Tcl_SetObjResult(interp, Tcl_NewStringObj( - "may not disassemble prebuilt bytecode", -1)); - Tcl_SetErrorCode(interp, "TCL", "OPERATION", "DISASSEMBLE", - "BYTECODE", NULL); - return TCL_ERROR; - } - Tcl_SetObjResult(interp, TclDisassembleByteCodeObj(codeObjPtr)); - return TCL_OK; -} - -/* * Local Variables: * mode: c * c-basic-offset: 4 diff --git a/unix/Makefile.in b/unix/Makefile.in index 3e4a6f6..ab351ca 100644 --- a/unix/Makefile.in +++ b/unix/Makefile.in @@ -294,7 +294,7 @@ GENERIC_OBJS = regcomp.o regexec.o regfree.o regerror.o tclAlloc.o \ tclAssembly.o tclAsync.o tclBasic.o tclBinary.o tclCkalloc.o \ tclClock.o tclCmdAH.o tclCmdIL.o tclCmdMZ.o \ tclCompCmds.o tclCompCmdsGR.o tclCompCmdsSZ.o tclCompExpr.o \ - tclCompile.o tclConfig.o tclDate.o tclDictObj.o \ + tclCompile.o tclConfig.o tclDate.o tclDictObj.o tclDisassemble.o \ tclEncoding.o tclEnsemble.o \ tclEnv.o tclEvent.o tclExecute.o tclFCmd.o tclFileName.o tclGet.o \ tclHash.o tclHistory.o tclIndexObj.o tclInterp.o tclIO.o tclIOCmd.o \ @@ -402,6 +402,7 @@ GENERIC_SRCS = \ $(GENERIC_DIR)/tclConfig.c \ $(GENERIC_DIR)/tclDate.c \ $(GENERIC_DIR)/tclDictObj.c \ + $(GENERIC_DIR)/tclDisassemble.c \ $(GENERIC_DIR)/tclEncoding.c \ $(GENERIC_DIR)/tclEnsemble.c \ $(GENERIC_DIR)/tclEnv.c \ @@ -1097,6 +1098,9 @@ tclConfig.o: $(GENERIC_DIR)/tclConfig.c tclDictObj.o: $(GENERIC_DIR)/tclDictObj.c $(MATHHDRS) $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclDictObj.c +tclDisassemble.o: $(GENERIC_DIR)/tclDisassemble.c $(COMPILEHDR) + $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclDisassemble.c + tclEncoding.o: $(GENERIC_DIR)/tclEncoding.c $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclEncoding.c @@ -1562,10 +1566,9 @@ 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) -DTCL_LIBRARY=\"${TCL_LIBRARY}\" \ - -DTCL_PACKAGE_PATH="\"${TCL_PACKAGE_PATH}\"" \ - $(UNIX_DIR)/tclUnixInit.c + $(CC) -c $(CC_SWITCHES) $(TCL_LOCATIONS) $(UNIX_DIR)/tclUnixInit.c tclUnixCompat.o: $(UNIX_DIR)/tclUnixCompat.c $(CC) -c $(CC_SWITCHES) $(UNIX_DIR)/tclUnixCompat.c diff --git a/win/Makefile.in b/win/Makefile.in index 18993fe..dc54d59 100644 --- a/win/Makefile.in +++ b/win/Makefile.in @@ -232,6 +232,7 @@ GENERIC_OBJS = \ tclConfig.$(OBJEXT) \ tclDate.$(OBJEXT) \ tclDictObj.$(OBJEXT) \ + tclDisassemble.$(OBJEXT) \ tclEncoding.$(OBJEXT) \ tclEnsemble.$(OBJEXT) \ tclEnv.$(OBJEXT) \ diff --git a/win/makefile.bc b/win/makefile.bc index 0b17cea..31a927e 100644 --- a/win/makefile.bc +++ b/win/makefile.bc @@ -207,6 +207,7 @@ TCLOBJS = \ $(TMPDIR)\tclConfig.obj \ $(TMPDIR)\tclDate.obj \ $(TMPDIR)\tclDictObj.obj \ + $(TMPDIR)\tclDisassemble.obj \ $(TMPDIR)\tclEncoding.obj \ $(TMPDIR)\tclEnsemble.obj \ $(TMPDIR)\tclEnv.obj \ @@ -587,3 +588,7 @@ clean: -@$(RM) $(TMPDIR)\*.exe -@$(RMDIR) $(OUTDIR) -@$(RMDIR) $(TMPDIR) + +# Local Variables: +# mode: makefile +# End: diff --git a/win/makefile.vc b/win/makefile.vc index cddb253..09a1135 100644 --- a/win/makefile.vc +++ b/win/makefile.vc @@ -1,4 +1,4 @@ -#------------------------------------------------------------- -*- makefile -*- +#------------------------------------------------------------- # makefile.vc -- # # Microsoft Visual C++ makefile for use with nmake.exe v1.62+ (VC++ 5.0+) @@ -281,6 +281,7 @@ COREOBJS = \ $(TMP_DIR)\tclConfig.obj \ $(TMP_DIR)\tclDate.obj \ $(TMP_DIR)\tclDictObj.obj \ + $(TMP_DIR)\tclDisassemble.obj \ $(TMP_DIR)\tclEncoding.obj \ $(TMP_DIR)\tclEnsemble.obj \ $(TMP_DIR)\tclEnv.obj \ @@ -1221,3 +1222,7 @@ realclean: hose hose: @echo Hosing $(OUT_DIR)\* ... @if exist $(OUT_DIR)\nul $(RMDIR) $(OUT_DIR) + +# Local Variables: +# mode: makefile +# End: -- cgit v0.12 From 6b65756937327c4f47d78b0493f39943ace02dee Mon Sep 17 00:00:00 2001 From: dkf Date: Tue, 11 Jun 2013 21:33:33 +0000 Subject: Code-readable disassembler: tcl::unsupported::getbytecode --- generic/tclBasic.c | 4 +- generic/tclDisassemble.c | 231 ++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 232 insertions(+), 3 deletions(-) diff --git a/generic/tclBasic.c b/generic/tclBasic.c index b2a505a..f805a94 100644 --- a/generic/tclBasic.c +++ b/generic/tclBasic.c @@ -837,7 +837,9 @@ Tcl_CreateInterp(void) */ Tcl_CreateObjCommand(interp, "::tcl::unsupported::disassemble", - Tcl_DisassembleObjCmd, NULL, NULL); + Tcl_DisassembleObjCmd, INT2PTR(0), NULL); + Tcl_CreateObjCommand(interp, "::tcl::unsupported::getbytecode", + Tcl_DisassembleObjCmd, INT2PTR(1), NULL); Tcl_CreateObjCommand(interp, "::tcl::unsupported::representation", Tcl_RepresentationCmd, NULL, NULL); diff --git a/generic/tclDisassemble.c b/generic/tclDisassemble.c index bc84763..2404b99 100644 --- a/generic/tclDisassemble.c +++ b/generic/tclDisassemble.c @@ -810,6 +810,229 @@ PrintSourceToObj( /* *---------------------------------------------------------------------- * + * DisassembleByteCodeAsDicts -- + * + * Given an object which is of bytecode type, return a disassembled + * version of the bytecode (in a new refcount 0 object) in a dictionary. + * No guarantees are made about the details of the contents of the + * result, but it is intended to be more readable than the old output + * format. + * + *---------------------------------------------------------------------- + */ + +static Tcl_Obj * +DisassembleByteCodeAsDicts( + Tcl_Obj *objPtr) /* The bytecode-holding value to take apart */ +{ + ByteCode *codePtr = objPtr->internalRep.twoPtrValue.ptr1; + Tcl_Obj *description, *literals, *variables, *instructions, *inst; + Tcl_Obj *aux, *exn; + unsigned char *pc, *opnd; + int i, val; + + /* + * Get the literals from the bytecode. + */ + + literals = Tcl_NewObj(); + for (i=0 ; inumLitObjects ; i++) { + Tcl_ListObjAppendElement(NULL, literals, codePtr->objArrayPtr[i]); + } + + /* + * Get the variables from the bytecode. + */ + + variables = Tcl_NewObj(); + if (codePtr->procPtr) { + int localCount = codePtr->procPtr->numCompiledLocals; + CompiledLocal *localPtr = codePtr->procPtr->firstLocalPtr; + + for (i=0 ; inextPtr) { + Tcl_Obj *descriptor[2]; + + descriptor[0] = Tcl_NewObj(); + if (!(localPtr->flags & (VAR_ARRAY|VAR_LINK))) { + Tcl_ListObjAppendElement(NULL, descriptor[0], + Tcl_NewStringObj("scalar", -1)); + } + if (localPtr->flags & VAR_ARRAY) { + Tcl_ListObjAppendElement(NULL, descriptor[0], + Tcl_NewStringObj("array", -1)); + } + if (localPtr->flags & VAR_LINK) { + Tcl_ListObjAppendElement(NULL, descriptor[0], + Tcl_NewStringObj("link", -1)); + } + if (localPtr->flags & VAR_ARGUMENT) { + Tcl_ListObjAppendElement(NULL, descriptor[0], + Tcl_NewStringObj("arg", -1)); + } + if (localPtr->flags & VAR_TEMPORARY) { + Tcl_ListObjAppendElement(NULL, descriptor[0], + Tcl_NewStringObj("temp", -1)); + } + if (localPtr->flags & VAR_RESOLVED) { + Tcl_ListObjAppendElement(NULL, descriptor[0], + Tcl_NewStringObj("resolved", -1)); + } + if (localPtr->flags & VAR_TEMPORARY) { + Tcl_ListObjAppendElement(NULL, variables, + Tcl_NewListObj(1, descriptor)); + } else { + descriptor[1] = Tcl_NewStringObj(localPtr->name, -1); + Tcl_ListObjAppendElement(NULL, variables, + Tcl_NewListObj(2, descriptor)); + } + } + } + + /* + * Get the instructions from the bytecode. + */ + + instructions = Tcl_NewObj(); + for (pc=codePtr->codeStart; pccodeStart+codePtr->numCodeBytes;){ + const InstructionDesc *instDesc = &tclInstructionTable[*pc]; + + inst = Tcl_NewIntObj(pc - codePtr->codeStart); + Tcl_ListObjAppendElement(NULL, inst, + Tcl_NewStringObj(instDesc->name, -1)); + opnd = pc + 1; + for (i=0 ; inumOperands ; i++) { + switch (instDesc->opTypes[i]) { + case OPERAND_INT1: + val = TclGetInt1AtPtr(opnd); + opnd += 1; + if (*pc == INST_JUMP1 || *pc == INST_JUMP_TRUE1 + || *pc == INST_JUMP_FALSE1) { + Tcl_ListObjAppendElement(NULL, inst, Tcl_ObjPrintf( + "pc %d (%d)", pc+val-codePtr->codeStart, val)); + } else { + Tcl_ListObjAppendElement(NULL, inst, Tcl_NewIntObj(val)); + } + break; + case OPERAND_INT4: + val = TclGetInt4AtPtr(opnd); + opnd += 4; + if (*pc == INST_JUMP4 || *pc == INST_JUMP_TRUE4 + || *pc == INST_JUMP_FALSE4 || *pc == INST_START_CMD) { + Tcl_ListObjAppendElement(NULL, inst, Tcl_ObjPrintf( + "pc %d (%d)", pc+val-codePtr->codeStart, val)); + } else { + Tcl_ListObjAppendElement(NULL, inst, Tcl_NewIntObj(val)); + } + break; + case OPERAND_UINT1: + val = TclGetUInt1AtPtr(opnd); + opnd += 1; + Tcl_ListObjAppendElement(NULL, inst, Tcl_NewIntObj(val)); + break; + case OPERAND_UINT4: + val = TclGetUInt4AtPtr(opnd); + opnd += 4; + Tcl_ListObjAppendElement(NULL, inst, Tcl_NewIntObj(val)); + break; + case OPERAND_IDX4: + val = TclGetInt4AtPtr(opnd); + opnd += 4; + if (val >= -1) { + Tcl_ListObjAppendElement(NULL, inst, Tcl_NewIntObj(val)); + } else if (val == -2) { + Tcl_ListObjAppendElement(NULL, inst, + Tcl_NewStringObj("end", -1)); + } else { + Tcl_ListObjAppendElement(NULL, inst, + Tcl_ObjPrintf("end-%d", -2-val)); + } + break; + case OPERAND_LVT1: + val = TclGetUInt1AtPtr(opnd); + opnd += 1; + Tcl_ListObjAppendElement(NULL, inst, + Tcl_ObjPrintf("%%%d", val)); + break; + case OPERAND_LVT4: + val = TclGetUInt4AtPtr(opnd); + opnd += 4; + Tcl_ListObjAppendElement(NULL, inst, + Tcl_ObjPrintf("%%%d", val)); + break; + case OPERAND_AUX4: + val = TclGetInt4AtPtr(opnd); + opnd += 4; + Tcl_ListObjAppendElement(NULL, inst, Tcl_NewIntObj(val)); + break; + case OPERAND_NONE: + Tcl_Panic("opcode %d with more than zero 'no' operands", *pc); + } + } + Tcl_ListObjAppendElement(NULL, instructions, inst); + pc += instDesc->numBytes; + } + + /* + * Get the auxiliary data from the bytecode. + */ + + aux = Tcl_NewObj(); + for (i=0 ; inumAuxDataItems ; i++) { + AuxData *auxData = &codePtr->auxDataArrayPtr[i]; + Tcl_Obj *auxDesc = Tcl_NewStringObj(auxData->type->name, -1); + + if (auxData->type->printProc) { + Tcl_AppendToObj(auxDesc, " ", -1); + auxData->type->printProc(auxData->clientData, auxDesc, codePtr,0); + } + Tcl_ListObjAppendElement(NULL, aux, auxDesc); + } + + /* + * Get the exception ranges from the bytecode. + */ + + exn = Tcl_NewObj(); + for (i=0 ; inumExceptRanges ; i++) { + ExceptionRange *rangePtr = &codePtr->exceptArrayPtr[i]; + + switch (rangePtr->type) { + case LOOP_EXCEPTION_RANGE: + Tcl_ListObjAppendElement(NULL, exn, Tcl_ObjPrintf( + "type %s level %d from %d to %d break %d continue %d", + "loop", rangePtr->nestingLevel, rangePtr->codeOffset, + rangePtr->codeOffset + rangePtr->numCodeBytes - 1, + rangePtr->breakOffset, rangePtr->continueOffset)); + break; + case CATCH_EXCEPTION_RANGE: + Tcl_ListObjAppendElement(NULL, exn, Tcl_ObjPrintf( + "type %s level %d from %d to %d catch %d", + "catch", rangePtr->nestingLevel, rangePtr->codeOffset, + rangePtr->codeOffset + rangePtr->numCodeBytes - 1, + rangePtr->catchOffset)); + break; + } + } + + /* + * Build the overall result. + */ + + description = Tcl_NewObj(); + Tcl_DictObjPut(NULL, description, Tcl_NewStringObj("literals", -1), + literals); + Tcl_DictObjPut(NULL, description, Tcl_NewStringObj("variables", -1), + variables); + Tcl_DictObjPut(NULL, description, Tcl_NewStringObj("exception", -1), exn); + Tcl_DictObjPut(NULL, description, Tcl_NewStringObj("instructions", -1), + instructions); + Tcl_DictObjPut(NULL, description, Tcl_NewStringObj("auxiliary", -1), aux); + return description; +} + +/* + *---------------------------------------------------------------------- + * * Tcl_DisassembleObjCmd -- * * Implementation of the "::tcl::unsupported::disassemble" command. This @@ -822,7 +1045,7 @@ PrintSourceToObj( int Tcl_DisassembleObjCmd( - ClientData dummy, /* Not used. */ + ClientData clientData, /* What type of operation. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ @@ -1031,7 +1254,11 @@ Tcl_DisassembleObjCmd( "BYTECODE", NULL); return TCL_ERROR; } - Tcl_SetObjResult(interp, TclDisassembleByteCodeObj(codeObjPtr)); + if (PTR2INT(clientData)) { + Tcl_SetObjResult(interp, DisassembleByteCodeAsDicts(codeObjPtr)); + } else { + Tcl_SetObjResult(interp, TclDisassembleByteCodeObj(codeObjPtr)); + } return TCL_OK; } -- cgit v0.12 From 9fb06ec1c981ed49d2dcba71378f5e1db966e1bf Mon Sep 17 00:00:00 2001 From: dkf Date: Wed, 12 Jun 2013 08:55:15 +0000 Subject: Extract more of the info from the bytecode. --- generic/tclDisassemble.c | 65 ++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 60 insertions(+), 5 deletions(-) diff --git a/generic/tclDisassemble.c b/generic/tclDisassemble.c index 2404b99..0d2b844 100644 --- a/generic/tclDisassemble.c +++ b/generic/tclDisassemble.c @@ -827,8 +827,9 @@ DisassembleByteCodeAsDicts( { ByteCode *codePtr = objPtr->internalRep.twoPtrValue.ptr1; Tcl_Obj *description, *literals, *variables, *instructions, *inst; - Tcl_Obj *aux, *exn; - unsigned char *pc, *opnd; + Tcl_Obj *aux, *exn, *commands; + unsigned char *pc, *opnd, *codeOffPtr, *codeLenPtr, *srcOffPtr, *srcLenPtr; + int codeOffset, codeLength, sourceOffset, sourceLength; int i, val; /* @@ -896,7 +897,7 @@ DisassembleByteCodeAsDicts( for (pc=codePtr->codeStart; pccodeStart+codePtr->numCodeBytes;){ const InstructionDesc *instDesc = &tclInstructionTable[*pc]; - inst = Tcl_NewIntObj(pc - codePtr->codeStart); + inst = Tcl_NewObj(); Tcl_ListObjAppendElement(NULL, inst, Tcl_NewStringObj(instDesc->name, -1)); opnd = pc + 1; @@ -962,13 +963,15 @@ DisassembleByteCodeAsDicts( case OPERAND_AUX4: val = TclGetInt4AtPtr(opnd); opnd += 4; - Tcl_ListObjAppendElement(NULL, inst, Tcl_NewIntObj(val)); + Tcl_ListObjAppendElement(NULL, inst, + Tcl_ObjPrintf("?%d", val)); break; case OPERAND_NONE: Tcl_Panic("opcode %d with more than zero 'no' operands", *pc); } } - Tcl_ListObjAppendElement(NULL, instructions, inst); + Tcl_DictObjPut(NULL, instructions, + Tcl_NewIntObj(pc - codePtr->codeStart), inst); pc += instDesc->numBytes; } @@ -1015,6 +1018,48 @@ DisassembleByteCodeAsDicts( } /* + * Get the command information from the bytecode. + */ + + commands = Tcl_NewObj(); + codeOffPtr = codePtr->codeDeltaStart; + codeLenPtr = codePtr->codeLengthStart; + srcOffPtr = codePtr->srcDeltaStart; + srcLenPtr = codePtr->srcLengthStart; + codeOffset = sourceOffset = 0; +#define Decode(ptr) \ + ((TclGetUInt1AtPtr(ptr) == 0xFF) \ + ? ((ptr)+=5,TclGetInt4AtPtr((ptr)-4)) \ + : ((ptr)+=1,TclGetInt1AtPtr((ptr)-1))) + for (i=0 ; inumCommands ; i++) { + Tcl_Obj *cmd; + + codeOffset += Decode(codeOffPtr); + codeLength = Decode(codeLenPtr); + sourceOffset += Decode(srcOffPtr); + sourceLength = Decode(srcLenPtr); + cmd = Tcl_NewObj(); + Tcl_DictObjPut(NULL, cmd, Tcl_NewStringObj("codefrom", -1), + Tcl_NewIntObj(codeOffset)); + Tcl_DictObjPut(NULL, cmd, Tcl_NewStringObj("codeto", -1), + Tcl_NewIntObj(codeOffset + codeLength - 1)); + /* + * Convert byte offsets to character offsets; important if multibyte + * characters are present in the source! + */ + Tcl_DictObjPut(NULL, cmd, Tcl_NewStringObj("scriptfrom", -1), + Tcl_NewIntObj(Tcl_NumUtfChars(codePtr->source, + sourceOffset))); + Tcl_DictObjPut(NULL, cmd, Tcl_NewStringObj("scriptto", -1), + Tcl_NewIntObj(Tcl_NumUtfChars(codePtr->source, + sourceOffset + sourceLength - 1))); + Tcl_DictObjPut(NULL, cmd, Tcl_NewStringObj("script", -1), + Tcl_NewStringObj(codePtr->source+sourceOffset, sourceLength)); + Tcl_ListObjAppendElement(NULL, commands, cmd); + } +#undef Decode + + /* * Build the overall result. */ @@ -1027,6 +1072,16 @@ DisassembleByteCodeAsDicts( Tcl_DictObjPut(NULL, description, Tcl_NewStringObj("instructions", -1), instructions); Tcl_DictObjPut(NULL, description, Tcl_NewStringObj("auxiliary", -1), aux); + Tcl_DictObjPut(NULL, description, Tcl_NewStringObj("commands", -1), + commands); + Tcl_DictObjPut(NULL, description, Tcl_NewStringObj("script", -1), + Tcl_NewStringObj(codePtr->source, codePtr->numSrcBytes)); + Tcl_DictObjPut(NULL, description, Tcl_NewStringObj("namespace", -1), + Tcl_NewStringObj(codePtr->nsPtr->fullName, -1)); + Tcl_DictObjPut(NULL, description, Tcl_NewStringObj("stackdepth", -1), + Tcl_NewIntObj(codePtr->maxStackDepth)); + Tcl_DictObjPut(NULL, description, Tcl_NewStringObj("exceptdepth", -1), + Tcl_NewIntObj(codePtr->maxExceptDepth)); return description; } -- cgit v0.12 From 50cc521ee358939e480cc2b05b5b9d48ab3340e7 Mon Sep 17 00:00:00 2001 From: dkf Date: Thu, 13 Jun 2013 21:21:22 +0000 Subject: Improved rendering of some opcode arguments and auxdata. --- generic/tclCompCmds.c | 86 +++++++++++++++++++++++++++++++++++++++++++++--- generic/tclCompCmdsSZ.c | 32 +++++++++++++++++- generic/tclCompile.h | 10 ++++++ generic/tclDisassemble.c | 36 +++++++++++++++----- 4 files changed, 150 insertions(+), 14 deletions(-) diff --git a/generic/tclCompCmds.c b/generic/tclCompCmds.c index fddf152..0740490 100644 --- a/generic/tclCompCmds.c +++ b/generic/tclCompCmds.c @@ -26,11 +26,17 @@ static void FreeDictUpdateInfo(ClientData clientData); static void PrintDictUpdateInfo(ClientData clientData, Tcl_Obj *appendObj, ByteCode *codePtr, unsigned int pcOffset); +static void DisassembleDictUpdateInfo(ClientData clientData, + Tcl_Obj *dictObj, ByteCode *codePtr, + unsigned int pcOffset); static ClientData DupForeachInfo(ClientData clientData); static void FreeForeachInfo(ClientData clientData); static void PrintForeachInfo(ClientData clientData, Tcl_Obj *appendObj, ByteCode *codePtr, unsigned int pcOffset); +static void DisassembleForeachInfo(ClientData clientData, + Tcl_Obj *dictObj, ByteCode *codePtr, + unsigned int pcOffset); static int CompileEachloopCmd(Tcl_Interp *interp, Tcl_Parse *parsePtr, Command *cmdPtr, CompileEnv *envPtr, int collect); @@ -46,14 +52,16 @@ const AuxDataType tclForeachInfoType = { "ForeachInfo", /* name */ DupForeachInfo, /* dupProc */ FreeForeachInfo, /* freeProc */ - PrintForeachInfo /* printProc */ + PrintForeachInfo, /* printProc */ + DisassembleForeachInfo /* disassembleProc */ }; const AuxDataType tclDictUpdateInfoType = { "DictUpdateInfo", /* name */ DupDictUpdateInfo, /* dupProc */ FreeDictUpdateInfo, /* freeProc */ - PrintDictUpdateInfo /* printProc */ + PrintDictUpdateInfo, /* printProc */ + DisassembleDictUpdateInfo /* disassembleProc */ }; /* @@ -2065,11 +2073,13 @@ TclCompileDictWithCmd( * DupDictUpdateInfo: a copy of the auxiliary data * FreeDictUpdateInfo: none * PrintDictUpdateInfo: none + * DisassembleDictUpdateInfo: none * * Side effects: * DupDictUpdateInfo: allocates memory * FreeDictUpdateInfo: releases memory * PrintDictUpdateInfo: none + * DisassembleDictUpdateInfo: none * *---------------------------------------------------------------------- */ @@ -2112,6 +2122,25 @@ PrintDictUpdateInfo( Tcl_AppendPrintfToObj(appendObj, "%%v%u", duiPtr->varIndices[i]); } } + +static void +DisassembleDictUpdateInfo( + ClientData clientData, + Tcl_Obj *dictObj, + ByteCode *codePtr, + unsigned int pcOffset) +{ + DictUpdateInfo *duiPtr = clientData; + int i; + Tcl_Obj *variables = Tcl_NewObj(); + + for (i=0 ; ilength ; i++) { + Tcl_ListObjAppendElement(NULL, variables, + Tcl_NewIntObj(duiPtr->varIndices[i])); + } + Tcl_DictObjPut(NULL, dictObj, Tcl_NewStringObj("variables", -1), + variables); +} /* *---------------------------------------------------------------------- @@ -2856,10 +2885,10 @@ FreeForeachInfo( /* *---------------------------------------------------------------------- * - * PrintForeachInfo -- + * PrintForeachInfo, DisassembleForeachInfo -- * - * Function to write a human-readable representation of a ForeachInfo - * structure to stdout for debugging. + * Functions to write a human-readable or script-readablerepresentation + * of a ForeachInfo structure to a Tcl_Obj for debugging. * * Results: * None. @@ -2909,6 +2938,53 @@ PrintForeachInfo( Tcl_AppendToObj(appendObj, "]", -1); } } + +static void +DisassembleForeachInfo( + ClientData clientData, + Tcl_Obj *dictObj, + ByteCode *codePtr, + unsigned int pcOffset) +{ + register ForeachInfo *infoPtr = clientData; + register ForeachVarList *varsPtr; + int i, j; + Tcl_Obj *objPtr, *innerPtr; + + /* + * Data stores. + */ + + objPtr = Tcl_NewObj(); + for (i=0 ; inumLists ; i++) { + Tcl_ListObjAppendElement(NULL, objPtr, + Tcl_NewIntObj(infoPtr->firstValueTemp + i)); + } + Tcl_DictObjPut(NULL, dictObj, Tcl_NewStringObj("data", -1), objPtr); + + /* + * Loop counter. + */ + + Tcl_DictObjPut(NULL, dictObj, Tcl_NewStringObj("loop", -1), + Tcl_NewIntObj(infoPtr->loopCtTemp)); + + /* + * Assignment targets. + */ + + objPtr = Tcl_NewObj(); + for (i=0 ; inumLists ; i++) { + innerPtr = Tcl_NewObj(); + varsPtr = infoPtr->varLists[i]; + for (j=0 ; jnumVars ; j++) { + Tcl_ListObjAppendElement(NULL, innerPtr, + Tcl_NewIntObj(varsPtr->varIndexes[j])); + } + Tcl_ListObjAppendElement(NULL, objPtr, innerPtr); + } + Tcl_DictObjPut(NULL, dictObj, Tcl_NewStringObj("assign", -1), objPtr); +} /* *---------------------------------------------------------------------- diff --git a/generic/tclCompCmdsSZ.c b/generic/tclCompCmdsSZ.c index 855dd8f..3639032 100644 --- a/generic/tclCompCmdsSZ.c +++ b/generic/tclCompCmdsSZ.c @@ -27,6 +27,9 @@ static void FreeJumptableInfo(ClientData clientData); static void PrintJumptableInfo(ClientData clientData, Tcl_Obj *appendObj, ByteCode *codePtr, unsigned int pcOffset); +static void DisassembleJumptableInfo(ClientData clientData, + Tcl_Obj *dictObj, ByteCode *codePtr, + unsigned int pcOffset); static int CompileAssociativeBinaryOpCmd(Tcl_Interp *interp, Tcl_Parse *parsePtr, const char *identity, int instruction, CompileEnv *envPtr); @@ -74,7 +77,8 @@ const AuxDataType tclJumptableInfoType = { "JumptableInfo", /* name */ DupJumptableInfo, /* dupProc */ FreeJumptableInfo, /* freeProc */ - PrintJumptableInfo /* printProc */ + PrintJumptableInfo, /* printProc */ + DisassembleJumptableInfo /* disassembleProc */ }; /* @@ -1784,11 +1788,13 @@ IssueSwitchJumpTable( * DupJumptableInfo: a copy of the jump-table * FreeJumptableInfo: none * PrintJumptableInfo: none + * DisassembleJumptableInfo: none * * Side effects: * DupJumptableInfo: allocates memory * FreeJumptableInfo: releases memory * PrintJumptableInfo: none + * DisassembleJumptableInfo: none * *---------------------------------------------------------------------- */ @@ -1851,6 +1857,30 @@ PrintJumptableInfo( keyPtr, pcOffset + offset); } } + +static void +DisassembleJumptableInfo( + ClientData clientData, + Tcl_Obj *dictObj, + ByteCode *codePtr, + unsigned int pcOffset) +{ + register JumptableInfo *jtPtr = clientData; + Tcl_Obj *mapping = Tcl_NewObj(); + Tcl_HashEntry *hPtr; + Tcl_HashSearch search; + const char *keyPtr; + int offset; + + hPtr = Tcl_FirstHashEntry(&jtPtr->hashTable, &search); + for (; hPtr ; hPtr = Tcl_NextHashEntry(&search)) { + keyPtr = Tcl_GetHashKey(&jtPtr->hashTable, hPtr); + offset = PTR2INT(Tcl_GetHashValue(hPtr)); + Tcl_DictObjPut(NULL, mapping, Tcl_NewStringObj(keyPtr, -1), + Tcl_NewIntObj(offset)); + } + Tcl_DictObjPut(NULL, dictObj, Tcl_NewStringObj("mapping", -1), mapping); +} /* *---------------------------------------------------------------------- diff --git a/generic/tclCompile.h b/generic/tclCompile.h index f28403d..cf7b563 100644 --- a/generic/tclCompile.h +++ b/generic/tclCompile.h @@ -252,6 +252,16 @@ typedef struct AuxDataType { AuxDataPrintProc *printProc;/* Callback function to invoke when printing * the aux data as part of debugging. NULL * means that the data can't be printed. */ + AuxDataPrintProc *disassembleProc; + /* Callback function to invoke when doing a + * disassembly of the aux data (like the + * printProc, except that the output is + * intended to be script-readable). The + * appendObj argument should be filled in with + * a descriptive dictionary; it will start out + * with "name" mapped to the content of the + * name field. NULL means that the printProc + * should be used instead. */ } AuxDataType; /* diff --git a/generic/tclDisassemble.c b/generic/tclDisassemble.c index 0d2b844..fa99eaf 100644 --- a/generic/tclDisassemble.c +++ b/generic/tclDisassemble.c @@ -928,24 +928,35 @@ DisassembleByteCodeAsDicts( case OPERAND_UINT1: val = TclGetUInt1AtPtr(opnd); opnd += 1; - Tcl_ListObjAppendElement(NULL, inst, Tcl_NewIntObj(val)); + if (*pc == INST_PUSH1) { + Tcl_ListObjAppendElement(NULL, inst, Tcl_ObjPrintf( + "@%d", val)); + } else { + Tcl_ListObjAppendElement(NULL, inst, Tcl_NewIntObj(val)); + } break; case OPERAND_UINT4: val = TclGetUInt4AtPtr(opnd); opnd += 4; - Tcl_ListObjAppendElement(NULL, inst, Tcl_NewIntObj(val)); + if (*pc == INST_PUSH4) { + Tcl_ListObjAppendElement(NULL, inst, Tcl_ObjPrintf( + "@%d", val)); + } else { + Tcl_ListObjAppendElement(NULL, inst, Tcl_NewIntObj(val)); + } break; case OPERAND_IDX4: val = TclGetInt4AtPtr(opnd); opnd += 4; if (val >= -1) { - Tcl_ListObjAppendElement(NULL, inst, Tcl_NewIntObj(val)); + Tcl_ListObjAppendElement(NULL, inst, Tcl_ObjPrintf( + ".%d", val)); } else if (val == -2) { Tcl_ListObjAppendElement(NULL, inst, - Tcl_NewStringObj("end", -1)); + Tcl_NewStringObj(".end", -1)); } else { Tcl_ListObjAppendElement(NULL, inst, - Tcl_ObjPrintf("end-%d", -2-val)); + Tcl_ObjPrintf(".end-%d", -2-val)); } break; case OPERAND_LVT1: @@ -984,9 +995,18 @@ DisassembleByteCodeAsDicts( AuxData *auxData = &codePtr->auxDataArrayPtr[i]; Tcl_Obj *auxDesc = Tcl_NewStringObj(auxData->type->name, -1); - if (auxData->type->printProc) { - Tcl_AppendToObj(auxDesc, " ", -1); - auxData->type->printProc(auxData->clientData, auxDesc, codePtr,0); + if (auxData->type->disassembleProc) { + Tcl_Obj *desc = Tcl_NewObj(); + + Tcl_DictObjPut(NULL, desc, Tcl_NewStringObj("name", -1), auxDesc); + auxDesc = desc; + auxData->type->disassembleProc(auxData->clientData, auxDesc, + codePtr, 0); + } else if (auxData->type->printProc) { + Tcl_Obj *desc = Tcl_NewObj(); + + auxData->type->printProc(auxData->clientData, desc, codePtr, 0); + Tcl_ListObjAppendElement(NULL, auxDesc, desc); } Tcl_ListObjAppendElement(NULL, aux, auxDesc); } -- cgit v0.12 From a261f7d4135387e230cbc9597908c39a5c8fa936 Mon Sep 17 00:00:00 2001 From: dkf Date: Mon, 17 Jun 2013 14:04:28 +0000 Subject: Remove extra scribblings not normally needed. Thanks to jdc for suggestion. --- generic/tclDisassemble.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/generic/tclDisassemble.c b/generic/tclDisassemble.c index fa99eaf..7f0b11a 100644 --- a/generic/tclDisassemble.c +++ b/generic/tclDisassemble.c @@ -909,7 +909,7 @@ DisassembleByteCodeAsDicts( if (*pc == INST_JUMP1 || *pc == INST_JUMP_TRUE1 || *pc == INST_JUMP_FALSE1) { Tcl_ListObjAppendElement(NULL, inst, Tcl_ObjPrintf( - "pc %d (%d)", pc+val-codePtr->codeStart, val)); + "pc %d", pc+val-codePtr->codeStart)); } else { Tcl_ListObjAppendElement(NULL, inst, Tcl_NewIntObj(val)); } @@ -920,7 +920,7 @@ DisassembleByteCodeAsDicts( if (*pc == INST_JUMP4 || *pc == INST_JUMP_TRUE4 || *pc == INST_JUMP_FALSE4 || *pc == INST_START_CMD) { Tcl_ListObjAppendElement(NULL, inst, Tcl_ObjPrintf( - "pc %d (%d)", pc+val-codePtr->codeStart, val)); + "pc %d", pc+val-codePtr->codeStart)); } else { Tcl_ListObjAppendElement(NULL, inst, Tcl_NewIntObj(val)); } -- cgit v0.12 From df623b6abec77e920120a039c5cc0fedb63736ba Mon Sep 17 00:00:00 2001 From: dkf Date: Thu, 20 Jun 2013 11:05:20 +0000 Subject: Properly encode more operand types to reduce the number of special cases in the disassembler. --- generic/tclCompile.c | 18 +++--- generic/tclCompile.h | 8 ++- generic/tclDisassemble.c | 164 ++++++++++++++++++++++++++--------------------- 3 files changed, 106 insertions(+), 84 deletions(-) diff --git a/generic/tclCompile.c b/generic/tclCompile.c index 65fc218..aee711c 100644 --- a/generic/tclCompile.c +++ b/generic/tclCompile.c @@ -55,9 +55,9 @@ InstructionDesc const tclInstructionTable[] = { /* Name Bytes stackEffect #Opnds Operand types */ {"done", 1, -1, 0, {OPERAND_NONE}}, /* Finish ByteCode execution and return stktop (top stack item) */ - {"push1", 2, +1, 1, {OPERAND_UINT1}}, + {"push1", 2, +1, 1, {OPERAND_LIT1}}, /* Push object at ByteCode objArray[op1] */ - {"push4", 5, +1, 1, {OPERAND_UINT4}}, + {"push4", 5, +1, 1, {OPERAND_LIT4}}, /* Push object at ByteCode objArray[op4] */ {"pop", 1, -1, 0, {OPERAND_NONE}}, /* Pop the topmost stack object */ @@ -125,17 +125,17 @@ InstructionDesc const tclInstructionTable[] = { {"incrStkImm", 2, 0, 1, {OPERAND_INT1}}, /* Incr general variable; unparsed name is top, amount is op1 */ - {"jump1", 2, 0, 1, {OPERAND_INT1}}, + {"jump1", 2, 0, 1, {OPERAND_OFFSET1}}, /* Jump relative to (pc + op1) */ - {"jump4", 5, 0, 1, {OPERAND_INT4}}, + {"jump4", 5, 0, 1, {OPERAND_OFFSET4}}, /* Jump relative to (pc + op4) */ - {"jumpTrue1", 2, -1, 1, {OPERAND_INT1}}, + {"jumpTrue1", 2, -1, 1, {OPERAND_OFFSET1}}, /* Jump relative to (pc + op1) if stktop expr object is true */ - {"jumpTrue4", 5, -1, 1, {OPERAND_INT4}}, + {"jumpTrue4", 5, -1, 1, {OPERAND_OFFSET4}}, /* Jump relative to (pc + op4) if stktop expr object is true */ - {"jumpFalse1", 2, -1, 1, {OPERAND_INT1}}, + {"jumpFalse1", 2, -1, 1, {OPERAND_OFFSET1}}, /* Jump relative to (pc + op1) if stktop expr object is false */ - {"jumpFalse4", 5, -1, 1, {OPERAND_INT4}}, + {"jumpFalse4", 5, -1, 1, {OPERAND_OFFSET4}}, /* Jump relative to (pc + op4) if stktop expr object is false */ {"lor", 1, -1, 0, {OPERAND_NONE}}, @@ -298,7 +298,7 @@ InstructionDesc const tclInstructionTable[] = { /* List Index: push (lindex stktop op4) */ {"listRangeImm", 9, 0, 2, {OPERAND_IDX4, OPERAND_IDX4}}, /* List Range: push (lrange stktop op4 op4) */ - {"startCommand", 9, 0, 2, {OPERAND_INT4,OPERAND_UINT4}}, + {"startCommand", 9, 0, 2, {OPERAND_OFFSET4, OPERAND_UINT4}}, /* Start of bytecoded command: op is the length of the cmd's code, op2 * is number of commands here */ diff --git a/generic/tclCompile.h b/generic/tclCompile.h index cf7b563..1f42b05 100644 --- a/generic/tclCompile.h +++ b/generic/tclCompile.h @@ -822,8 +822,14 @@ typedef enum InstOperandType { * variable table. */ OPERAND_LVT4, /* Four byte unsigned index into the local * variable table. */ - OPERAND_AUX4 /* Four byte unsigned index into the aux data + OPERAND_AUX4, /* Four byte unsigned index into the aux data * table. */ + OPERAND_OFFSET1, /* One byte signed jump offset. */ + OPERAND_OFFSET4, /* Four byte signed jump offset. */ + OPERAND_LIT1, /* One byte unsigned index into table of + * literals. */ + OPERAND_LIT4 /* Four byte unsigned index into table of + * literals. */ } InstOperandType; typedef struct InstructionDesc { diff --git a/generic/tclDisassemble.c b/generic/tclDisassemble.c index 7f0b11a..c7072ee 100644 --- a/generic/tclDisassemble.c +++ b/generic/tclDisassemble.c @@ -482,42 +482,52 @@ FormatInstruction( switch (instDesc->opTypes[i]) { case OPERAND_INT1: opnd = TclGetInt1AtPtr(pc+numBytes); numBytes++; - if (opCode == INST_JUMP1 || opCode == INST_JUMP_TRUE1 - || opCode == INST_JUMP_FALSE1) { - sprintf(suffixBuffer, "pc %u", pcOffset+opnd); - } Tcl_AppendPrintfToObj(bufferObj, "%+d ", opnd); break; case OPERAND_INT4: opnd = TclGetInt4AtPtr(pc+numBytes); numBytes += 4; - if (opCode == INST_JUMP4 || opCode == INST_JUMP_TRUE4 - || opCode == INST_JUMP_FALSE4) { - sprintf(suffixBuffer, "pc %u", pcOffset+opnd); - } else if (opCode == INST_START_CMD) { - sprintf(suffixBuffer, "next cmd at pc %u", pcOffset+opnd); - } Tcl_AppendPrintfToObj(bufferObj, "%+d ", opnd); break; case OPERAND_UINT1: opnd = TclGetUInt1AtPtr(pc+numBytes); numBytes++; - if (opCode == INST_PUSH1) { - suffixObj = codePtr->objArrayPtr[opnd]; - } Tcl_AppendPrintfToObj(bufferObj, "%u ", (unsigned) opnd); break; - case OPERAND_AUX4: case OPERAND_UINT4: opnd = TclGetUInt4AtPtr(pc+numBytes); numBytes += 4; - if (opCode == INST_PUSH4) { - suffixObj = codePtr->objArrayPtr[opnd]; - } else if (opCode == INST_START_CMD && opnd != 1) { + if (opCode == INST_START_CMD) { sprintf(suffixBuffer+strlen(suffixBuffer), ", %u cmds start here", opnd); } Tcl_AppendPrintfToObj(bufferObj, "%u ", (unsigned) opnd); - if (instDesc->opTypes[i] == OPERAND_AUX4) { - auxPtr = &codePtr->auxDataArrayPtr[opnd]; + break; + case OPERAND_OFFSET1: + opnd = TclGetInt1AtPtr(pc+numBytes); numBytes++; + sprintf(suffixBuffer, "pc %u", pcOffset+opnd); + Tcl_AppendPrintfToObj(bufferObj, "%+d ", opnd); + break; + case OPERAND_OFFSET4: + opnd = TclGetInt4AtPtr(pc+numBytes); numBytes += 4; + if (opCode == INST_START_CMD) { + sprintf(suffixBuffer, "next cmd at pc %u", pcOffset+opnd); + } else { + sprintf(suffixBuffer, "pc %u", pcOffset+opnd); } + Tcl_AppendPrintfToObj(bufferObj, "%+d ", opnd); + break; + case OPERAND_LIT1: + opnd = TclGetUInt1AtPtr(pc+numBytes); numBytes++; + suffixObj = codePtr->objArrayPtr[opnd]; + Tcl_AppendPrintfToObj(bufferObj, "%u ", (unsigned) opnd); + break; + case OPERAND_LIT4: + opnd = TclGetUInt4AtPtr(pc+numBytes); numBytes += 4; + suffixObj = codePtr->objArrayPtr[opnd]; + Tcl_AppendPrintfToObj(bufferObj, "%u ", (unsigned) opnd); + break; + case OPERAND_AUX4: + opnd = TclGetUInt4AtPtr(pc+numBytes); numBytes += 4; + Tcl_AppendPrintfToObj(bufferObj, "%u ", (unsigned) opnd); + auxPtr = &codePtr->auxDataArrayPtr[opnd]; break; case OPERAND_IDX4: opnd = TclGetInt4AtPtr(pc+numBytes); numBytes += 4; @@ -896,54 +906,67 @@ DisassembleByteCodeAsDicts( instructions = Tcl_NewObj(); for (pc=codePtr->codeStart; pccodeStart+codePtr->numCodeBytes;){ const InstructionDesc *instDesc = &tclInstructionTable[*pc]; + int address = pc - codePtr->codeStart; inst = Tcl_NewObj(); - Tcl_ListObjAppendElement(NULL, inst, - Tcl_NewStringObj(instDesc->name, -1)); + Tcl_ListObjAppendElement(NULL, inst, Tcl_NewStringObj( + instDesc->name, -1)); opnd = pc + 1; for (i=0 ; inumOperands ; i++) { switch (instDesc->opTypes[i]) { case OPERAND_INT1: val = TclGetInt1AtPtr(opnd); opnd += 1; - if (*pc == INST_JUMP1 || *pc == INST_JUMP_TRUE1 - || *pc == INST_JUMP_FALSE1) { - Tcl_ListObjAppendElement(NULL, inst, Tcl_ObjPrintf( - "pc %d", pc+val-codePtr->codeStart)); - } else { - Tcl_ListObjAppendElement(NULL, inst, Tcl_NewIntObj(val)); - } - break; + goto formatNumber; + case OPERAND_UINT1: + val = TclGetUInt1AtPtr(opnd); + opnd += 1; + goto formatNumber; case OPERAND_INT4: val = TclGetInt4AtPtr(opnd); opnd += 4; - if (*pc == INST_JUMP4 || *pc == INST_JUMP_TRUE4 - || *pc == INST_JUMP_FALSE4 || *pc == INST_START_CMD) { - Tcl_ListObjAppendElement(NULL, inst, Tcl_ObjPrintf( - "pc %d", pc+val-codePtr->codeStart)); - } else { - Tcl_ListObjAppendElement(NULL, inst, Tcl_NewIntObj(val)); - } + goto formatNumber; + case OPERAND_UINT4: + val = TclGetUInt4AtPtr(opnd); + opnd += 4; + formatNumber: + Tcl_ListObjAppendElement(NULL, inst, Tcl_NewIntObj(val)); break; - case OPERAND_UINT1: + + case OPERAND_OFFSET1: + val = TclGetInt1AtPtr(opnd); + opnd += 1; + goto formatAddress; + case OPERAND_OFFSET4: + val = TclGetInt4AtPtr(opnd); + opnd += 4; + formatAddress: + Tcl_ListObjAppendElement(NULL, inst, Tcl_ObjPrintf( + "pc %d", address + val)); + break; + + case OPERAND_LIT1: val = TclGetUInt1AtPtr(opnd); opnd += 1; - if (*pc == INST_PUSH1) { - Tcl_ListObjAppendElement(NULL, inst, Tcl_ObjPrintf( - "@%d", val)); - } else { - Tcl_ListObjAppendElement(NULL, inst, Tcl_NewIntObj(val)); - } + goto formatLiteral; + case OPERAND_LIT4: + val = TclGetUInt4AtPtr(opnd); + opnd += 4; + formatLiteral: + Tcl_ListObjAppendElement(NULL, inst, Tcl_ObjPrintf( + "@%d", val)); break; - case OPERAND_UINT4: + + case OPERAND_LVT1: + val = TclGetUInt1AtPtr(opnd); + opnd += 1; + goto formatVariable; + case OPERAND_LVT4: val = TclGetUInt4AtPtr(opnd); opnd += 4; - if (*pc == INST_PUSH4) { - Tcl_ListObjAppendElement(NULL, inst, Tcl_ObjPrintf( - "@%d", val)); - } else { - Tcl_ListObjAppendElement(NULL, inst, Tcl_NewIntObj(val)); - } + formatVariable: + Tcl_ListObjAppendElement(NULL, inst, Tcl_ObjPrintf( + "%%%d", val)); break; case OPERAND_IDX4: val = TclGetInt4AtPtr(opnd); @@ -952,37 +975,24 @@ DisassembleByteCodeAsDicts( Tcl_ListObjAppendElement(NULL, inst, Tcl_ObjPrintf( ".%d", val)); } else if (val == -2) { - Tcl_ListObjAppendElement(NULL, inst, - Tcl_NewStringObj(".end", -1)); + Tcl_ListObjAppendElement(NULL, inst, Tcl_NewStringObj( + ".end", -1)); } else { - Tcl_ListObjAppendElement(NULL, inst, - Tcl_ObjPrintf(".end-%d", -2-val)); + Tcl_ListObjAppendElement(NULL, inst, Tcl_ObjPrintf( + ".end-%d", -2-val)); } break; - case OPERAND_LVT1: - val = TclGetUInt1AtPtr(opnd); - opnd += 1; - Tcl_ListObjAppendElement(NULL, inst, - Tcl_ObjPrintf("%%%d", val)); - break; - case OPERAND_LVT4: - val = TclGetUInt4AtPtr(opnd); - opnd += 4; - Tcl_ListObjAppendElement(NULL, inst, - Tcl_ObjPrintf("%%%d", val)); - break; case OPERAND_AUX4: val = TclGetInt4AtPtr(opnd); opnd += 4; - Tcl_ListObjAppendElement(NULL, inst, - Tcl_ObjPrintf("?%d", val)); + Tcl_ListObjAppendElement(NULL, inst, Tcl_ObjPrintf( + "?%d", val)); break; case OPERAND_NONE: Tcl_Panic("opcode %d with more than zero 'no' operands", *pc); } } - Tcl_DictObjPut(NULL, instructions, - Tcl_NewIntObj(pc - codePtr->codeStart), inst); + Tcl_DictObjPut(NULL, instructions, Tcl_NewIntObj(address), inst); pc += instDesc->numBytes; } @@ -1039,18 +1049,23 @@ DisassembleByteCodeAsDicts( /* * Get the command information from the bytecode. + * + * The way these are encoded in the bytecode is non-trivial; the Decode + * macro (which updates its argument and returns the next decoded value) + * handles this so that the rest of the code does not. */ +#define Decode(ptr) \ + ((TclGetUInt1AtPtr(ptr) == 0xFF) \ + ? ((ptr)+=5 , TclGetInt4AtPtr((ptr)-4)) \ + : ((ptr)+=1 , TclGetInt1AtPtr((ptr)-1))) + commands = Tcl_NewObj(); codeOffPtr = codePtr->codeDeltaStart; codeLenPtr = codePtr->codeLengthStart; srcOffPtr = codePtr->srcDeltaStart; srcLenPtr = codePtr->srcLengthStart; codeOffset = sourceOffset = 0; -#define Decode(ptr) \ - ((TclGetUInt1AtPtr(ptr) == 0xFF) \ - ? ((ptr)+=5,TclGetInt4AtPtr((ptr)-4)) \ - : ((ptr)+=1,TclGetInt1AtPtr((ptr)-1))) for (i=0 ; inumCommands ; i++) { Tcl_Obj *cmd; @@ -1077,6 +1092,7 @@ DisassembleByteCodeAsDicts( Tcl_NewStringObj(codePtr->source+sourceOffset, sourceLength)); Tcl_ListObjAppendElement(NULL, commands, cmd); } + #undef Decode /* -- cgit v0.12 From 72fa9a96c812fbddb1485ae81350eda877dba808 Mon Sep 17 00:00:00 2001 From: dgp Date: Tue, 21 Jan 2014 21:32:53 +0000 Subject: Backport of bytearray append machinery to support bug fixes in ReadBytes. --- generic/tclBinary.c | 92 +++++++++++++++++++++++++++++++++++++++++++++++++++++ generic/tclIO.c | 17 +++------- generic/tclInt.h | 2 ++ 3 files changed, 98 insertions(+), 13 deletions(-) diff --git a/generic/tclBinary.c b/generic/tclBinary.c index dbb296b..68289f2 100644 --- a/generic/tclBinary.c +++ b/generic/tclBinary.c @@ -549,6 +549,98 @@ UpdateStringOfByteArray( /* *---------------------------------------------------------------------- * + * TclAppendBytesToByteArray -- + * + * This function appends an array of bytes to a byte array object. Note + * that the object *must* be unshared, and the array of bytes *must not* + * refer to the object being appended to. + * + * Results: + * None. + * + * Side effects: + * Allocates enough memory for an array of bytes of the requested total + * size, or possibly larger. [Bug 2992970] + * + *---------------------------------------------------------------------- + */ + +#define TCL_MIN_GROWTH 1024 +void +TclAppendBytesToByteArray( + Tcl_Obj *objPtr, + const unsigned char *bytes, + int len) +{ + ByteArray *byteArrayPtr; + int needed; + + if (Tcl_IsShared(objPtr)) { + Tcl_Panic("%s called with shared object","TclAppendBytesToByteArray"); + } + if (len < 0) { + Tcl_Panic("%s must be called with definite number of bytes to append", + "TclAppendBytesToByteArray"); + } + if (len == 0) { + /* Append zero bytes is a no-op. */ + return; + } + if (objPtr->typePtr != &tclByteArrayType) { + SetByteArrayFromAny(NULL, objPtr); + } + byteArrayPtr = GET_BYTEARRAY(objPtr); + + if (len > INT_MAX - byteArrayPtr->used) { + Tcl_Panic("max size for a Tcl value (%d bytes) exceeded", INT_MAX); + } + + needed = byteArrayPtr->used + len; + /* + * If we need to, resize the allocated space in the byte array. + */ + + if (needed > byteArrayPtr->allocated) { + ByteArray *ptr = NULL; + int attempt; + + if (needed <= INT_MAX/2) { + /* Try to allocate double the total space that is needed. */ + attempt = 2 * needed; + ptr = (ByteArray *) attemptckrealloc((void *) byteArrayPtr, + BYTEARRAY_SIZE(attempt)); + } + if (ptr == NULL) { + /* Try to allocate double the increment that is needed (plus). */ + unsigned int limit = INT_MAX - needed; + unsigned int extra = len + TCL_MIN_GROWTH; + int growth = (int) ((extra > limit) ? limit : extra); + + attempt = needed + growth; + ptr = (ByteArray *) attemptckrealloc((void *) byteArrayPtr, + BYTEARRAY_SIZE(attempt)); + } + if (ptr == NULL) { + /* Last chance: Try to allocate exactly what is needed. */ + attempt = needed; + ptr = (ByteArray *) ckrealloc((void *)byteArrayPtr, + BYTEARRAY_SIZE(attempt)); + } + byteArrayPtr = ptr; + byteArrayPtr->allocated = attempt; + SET_BYTEARRAY(objPtr, byteArrayPtr); + } + + if (bytes) { + memcpy(byteArrayPtr->bytes + byteArrayPtr->used, bytes, len); + } + byteArrayPtr->used += len; + TclInvalidateStringRep(objPtr); +} + +/* + *---------------------------------------------------------------------- + * * Tcl_BinaryObjCmd -- * * This procedure implements the "binary" Tcl command. diff --git a/generic/tclIO.c b/generic/tclIO.c index f1d8909..c1b7ee9 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -5586,20 +5586,8 @@ ReadBytes( toRead = srcLen; } + TclAppendBytesToByteArray(objPtr, NULL, toRead); dst = (char *) Tcl_GetByteArrayFromObj(objPtr, &length); - if (toRead > length - offset - 1) { - /* - * Double the existing size of the object or make enough room to hold - * all the characters we may get from the source buffer, whichever is - * larger. - */ - - length = offset * 2; - if (offset < toRead) { - length = offset + toRead + 1; - } - dst = (char *) Tcl_SetByteArrayLength(objPtr, length); - } dst += offset; if (statePtr->flags & INPUT_NEED_NL) { @@ -5607,6 +5595,7 @@ ReadBytes( if ((srcLen == 0) || (*src != '\n')) { *dst = '\r'; *offsetPtr += 1; + Tcl_SetByteArrayLength(objPtr, *offsetPtr); return 1; } *dst++ = '\n'; @@ -5619,11 +5608,13 @@ ReadBytes( dstWrote = toRead; if (TranslateInputEOL(statePtr, dst, src, &dstWrote, &srcRead) != 0) { if (dstWrote == 0) { + Tcl_SetByteArrayLength(objPtr, *offsetPtr); return -1; } } bufPtr->nextRemoved += srcRead; *offsetPtr += dstWrote; + Tcl_SetByteArrayLength(objPtr, *offsetPtr); return dstWrote; } diff --git a/generic/tclInt.h b/generic/tclInt.h index dc28b97..64d39a0 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -2477,6 +2477,8 @@ MODULE_SCOPE char tclEmptyString; *---------------------------------------------------------------- */ +MODULE_SCOPE void TclAppendBytesToByteArray(Tcl_Obj *objPtr, + const unsigned char *bytes, int len); MODULE_SCOPE void TclAdvanceContinuations(int* line, int** next, int loc); MODULE_SCOPE void TclAdvanceLines(int *line, const char *start, const char *end); -- cgit v0.12 From e99699b00876c6e8699412433a7d97ac2529a28c Mon Sep 17 00:00:00 2001 From: dgp Date: Tue, 21 Jan 2014 22:08:16 +0000 Subject: There is no need for ReadBytes() or its caller(s) to track how many bytes are actually stored in objPtr. The ByteArray Tcl_ObjType already has the machinery to take care of this. --- generic/tclIO.c | 47 ++++++++++++++++++----------------------------- 1 file changed, 18 insertions(+), 29 deletions(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index c1b7ee9..4a5d8f1 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -208,7 +208,7 @@ static int HaveVersion(const Tcl_ChannelType *typePtr, static void PeekAhead(Channel *chanPtr, char **dstEndPtr, GetsState *gsPtr); static int ReadBytes(ChannelState *statePtr, Tcl_Obj *objPtr, - int charsLeft, int *offsetPtr); + int charsLeft); static int ReadChars(ChannelState *statePtr, Tcl_Obj *objPtr, int charsLeft, int *offsetPtr, int *factorPtr); static void RecycleBuffer(ChannelState *statePtr, @@ -5448,12 +5448,10 @@ DoReadChars( */ TclGetString(objPtr); + offset = 0; } - offset = 0; } else { - if (encoding == NULL) { - Tcl_GetByteArrayFromObj(objPtr, &offset); - } else { + if (encoding) { TclGetStringFromObj(objPtr, &offset); } } @@ -5462,7 +5460,7 @@ DoReadChars( copiedNow = -1; if (statePtr->inQueueHead != NULL) { if (encoding == NULL) { - copiedNow = ReadBytes(statePtr, objPtr, toRead, &offset); + copiedNow = ReadBytes(statePtr, objPtr, toRead); } else { copiedNow = ReadChars(statePtr, objPtr, toRead, &offset, &factor); @@ -5510,9 +5508,7 @@ DoReadChars( } ResetFlag(statePtr, CHANNEL_BLOCKED); - if (encoding == NULL) { - Tcl_SetByteArrayLength(objPtr, offset); - } else { + if (encoding) { Tcl_SetObjLength(objPtr, offset); } @@ -5540,13 +5536,11 @@ DoReadChars( * allocated to hold data read from the channel as needed. * * Results: - * The return value is the number of bytes appended to the object and - * *offsetPtr is filled with the total number of bytes in the object - * (greater than the return value if there were already bytes in the - * object). + * The return value is the number of bytes appended to the object, or + * -1 to indicate that zero bytes were read due to an EOF. * * Side effects: - * None. + * The storage of bytes in objPtr can cause (re-)allocation of memory. * *--------------------------------------------------------------------------- */ @@ -5559,24 +5553,18 @@ ReadBytes( * been allocated to hold data, not how many * bytes of data have been stored in the * object. */ - int bytesToRead, /* Maximum number of bytes to store, or < 0 to + int bytesToRead) /* Maximum number of bytes to store, or < 0 to * get all available bytes. Bytes are obtained * from the first buffer in the queue - even * if this number is larger than the number of * bytes available in the first buffer, only * the bytes from the first buffer are * returned. */ - int *offsetPtr) /* On input, contains how many bytes of objPtr - * have been used to hold data. On output, - * filled with how many bytes are now being - * used. */ { - int toRead, srcLen, offset, length, srcRead, dstWrote; + int toRead, srcLen, length, srcRead, dstWrote; ChannelBuffer *bufPtr; char *src, *dst; - offset = *offsetPtr; - bufPtr = statePtr->inQueueHead; src = RemovePoint(bufPtr); srcLen = BytesLeft(bufPtr); @@ -5586,16 +5574,17 @@ ReadBytes( toRead = srcLen; } + (void) Tcl_GetByteArrayFromObj(objPtr, &length); TclAppendBytesToByteArray(objPtr, NULL, toRead); - dst = (char *) Tcl_GetByteArrayFromObj(objPtr, &length); - dst += offset; + dst = (char *) Tcl_GetByteArrayFromObj(objPtr, NULL); + dst += length; if (statePtr->flags & INPUT_NEED_NL) { ResetFlag(statePtr, INPUT_NEED_NL); if ((srcLen == 0) || (*src != '\n')) { *dst = '\r'; - *offsetPtr += 1; - Tcl_SetByteArrayLength(objPtr, *offsetPtr); + length += 1; + Tcl_SetByteArrayLength(objPtr, length); return 1; } *dst++ = '\n'; @@ -5608,13 +5597,13 @@ ReadBytes( dstWrote = toRead; if (TranslateInputEOL(statePtr, dst, src, &dstWrote, &srcRead) != 0) { if (dstWrote == 0) { - Tcl_SetByteArrayLength(objPtr, *offsetPtr); + Tcl_SetByteArrayLength(objPtr, length); return -1; } } bufPtr->nextRemoved += srcRead; - *offsetPtr += dstWrote; - Tcl_SetByteArrayLength(objPtr, *offsetPtr); + length += dstWrote; + Tcl_SetByteArrayLength(objPtr, length); return dstWrote; } -- cgit v0.12 From 490384e3e70ec65bf05e296d2af7947108de7766 Mon Sep 17 00:00:00 2001 From: dgp Date: Mon, 27 Jan 2014 17:35:27 +0000 Subject: Revise the Tcl_Append* machinery to tolerate NULL bytes to append. Then have ReadChars() use that machinery to resize buffer receiving input, rather than invent its own version. Simplify ReadChars() callers. --- generic/tclIO.c | 67 +++++++++++--------------------------------------- generic/tclStringObj.c | 29 ++++++++++++++-------- 2 files changed, 34 insertions(+), 62 deletions(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index 972cbd8..40573d7 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -210,7 +210,7 @@ static void PeekAhead(Channel *chanPtr, char **dstEndPtr, static int ReadBytes(ChannelState *statePtr, Tcl_Obj *objPtr, int charsLeft); static int ReadChars(ChannelState *statePtr, Tcl_Obj *objPtr, - int charsLeft, int *offsetPtr, int *factorPtr); + int charsLeft, int *factorPtr); static void RecycleBuffer(ChannelState *statePtr, ChannelBuffer *bufPtr, int mustDiscard); static int StackSetBlockMode(Channel *chanPtr, int mode); @@ -5425,7 +5425,7 @@ DoReadChars( ChannelState *statePtr = chanPtr->state; /* State info for channel */ ChannelBuffer *bufPtr; - int offset, factor, copied, copiedNow, result; + int factor, copied, copiedNow, result; Tcl_Encoding encoding; #define UTF_EXPANSION_FACTOR 1024 @@ -5447,14 +5447,11 @@ DoReadChars( * We're going to access objPtr->bytes directly, so we must ensure * that this is actually a string object (otherwise it might have * been pure Unicode). + * + * Probably not needed anymore. */ TclGetString(objPtr); - offset = 0; - } - } else { - if (encoding) { - TclGetStringFromObj(objPtr, &offset); } } @@ -5464,8 +5461,7 @@ DoReadChars( if (encoding == NULL) { copiedNow = ReadBytes(statePtr, objPtr, toRead); } else { - copiedNow = ReadChars(statePtr, objPtr, toRead, &offset, - &factor); + copiedNow = ReadChars(statePtr, objPtr, toRead, &factor); } /* @@ -5510,9 +5506,6 @@ DoReadChars( } ResetFlag(statePtr, CHANNEL_BLOCKED); - if (encoding) { - Tcl_SetObjLength(objPtr, offset); - } /* * Update the notifier state so we don't block while there is still data @@ -5651,17 +5644,13 @@ ReadChars( * available in the first buffer, only the * characters from the first buffer are * returned. */ - int *offsetPtr, /* On input, contains how many bytes of objPtr - * have been used to hold data. On output, - * filled with how many bytes are now being - * used. */ int *factorPtr) /* On input, contains a guess of how many * bytes need to be allocated to hold the * result of converting N source bytes to * UTF-8. On output, contains another guess * based on the data seen so far. */ { - int toRead, factor, offset, spaceLeft, srcLen, dstNeeded; + int toRead, factor, srcLen, dstNeeded, numBytes; int srcRead, dstWrote, numChars, dstRead; ChannelBuffer *bufPtr; char *src, *dst; @@ -5669,7 +5658,6 @@ ReadChars( int encEndFlagSuppressed = 0; factor = *factorPtr; - offset = *offsetPtr; bufPtr = statePtr->inQueueHead; src = RemovePoint(bufPtr); @@ -5687,37 +5675,9 @@ ReadChars( */ dstNeeded = TCL_UTF_MAX - 1 + toRead * factor / UTF_EXPANSION_FACTOR; - spaceLeft = objPtr->length - offset; - - if (dstNeeded > spaceLeft) { - /* - * Double the existing size of the object or make enough room to hold - * all the characters we want from the source buffer, whichever is - * larger. - */ - - int length = offset + ((offset < dstNeeded) ? dstNeeded : offset); - - if (Tcl_AttemptSetObjLength(objPtr, length) == 0) { - length = offset + dstNeeded; - if (Tcl_AttemptSetObjLength(objPtr, length) == 0) { - dstNeeded = TCL_UTF_MAX - 1 + toRead; - length = offset + dstNeeded; - Tcl_SetObjLength(objPtr, length); - } - } - spaceLeft = length - offset; - } - if (toRead == srcLen) { - /* - * Want to convert the whole buffer in one pass. If we have enough - * space, convert it using all available space in object rather than - * using the factor. - */ - - dstNeeded = spaceLeft; - } - dst = objPtr->bytes + offset; + (void) TclGetStringFromObj(objPtr, &numBytes); + Tcl_AppendToObj(objPtr, NULL, dstNeeded); + dst = TclGetString(objPtr) + numBytes; /* * [Bug 1462248]: The cause of the crash reported in this bug is this: @@ -5788,7 +5748,7 @@ ReadChars( *dst = '\r'; } statePtr->inputEncodingFlags &= ~TCL_ENCODING_START; - *offsetPtr += 1; + Tcl_SetObjLength(objPtr, numBytes + 1); if (encEndFlagSuppressed) { statePtr->inputEncodingFlags |= TCL_ENCODING_END; @@ -5829,6 +5789,7 @@ ReadChars( SetFlag(statePtr, CHANNEL_NEED_MORE_DATA); } + Tcl_SetObjLength(objPtr, numBytes); return -1; } @@ -5853,7 +5814,8 @@ ReadChars( memcpy(RemovePoint(nextPtr), src, (size_t) srcLen); RecycleBuffer(statePtr, bufPtr, 0); statePtr->inQueueHead = nextPtr; - return ReadChars(statePtr, objPtr, charsToRead, offsetPtr, factorPtr); + Tcl_SetObjLength(objPtr, numBytes); + return ReadChars(statePtr, objPtr, charsToRead, factorPtr); } dstRead = dstWrote; @@ -5866,6 +5828,7 @@ ReadChars( */ if (dstWrote == 0) { + Tcl_SetObjLength(objPtr, numBytes); return -1; } statePtr->inputEncodingState = oldState; @@ -5905,7 +5868,7 @@ ReadChars( if (dstWrote > srcRead + 1) { *factorPtr = dstWrote * UTF_EXPANSION_FACTOR / srcRead; } - *offsetPtr += dstWrote; + Tcl_SetObjLength(objPtr, numBytes + dstWrote); return numChars; } diff --git a/generic/tclStringObj.c b/generic/tclStringObj.c index a929d04..d96d814 100644 --- a/generic/tclStringObj.c +++ b/generic/tclStringObj.c @@ -1139,7 +1139,8 @@ Tcl_AppendLimitedToObj( if (ellipsis == NULL) { ellipsis = "..."; } - toCopy = Tcl_UtfPrev(bytes+limit+1-strlen(ellipsis), bytes) - bytes; + toCopy = (bytes == NULL) ? limit + : Tcl_UtfPrev(bytes+limit+1-strlen(ellipsis), bytes) - bytes; } /* @@ -1386,7 +1387,8 @@ AppendUnicodeToUnicodeRep( * due to the reallocs below. */ int offset = -1; - if (unicode >= stringPtr->unicode && unicode <= stringPtr->unicode + if (unicode && unicode >= stringPtr->unicode + && unicode <= stringPtr->unicode + stringPtr->uallocated / sizeof(Tcl_UniChar)) { offset = unicode - stringPtr->unicode; } @@ -1405,8 +1407,10 @@ AppendUnicodeToUnicodeRep( * trailing null. */ - memcpy(stringPtr->unicode + stringPtr->numChars, unicode, - appendNumChars * sizeof(Tcl_UniChar)); + if (unicode) { + memcpy(stringPtr->unicode + stringPtr->numChars, unicode, + appendNumChars * sizeof(Tcl_UniChar)); + } stringPtr->unicode[numChars] = 0; stringPtr->numChars = numChars; stringPtr->allocated = 0; @@ -1478,8 +1482,8 @@ AppendUtfToUnicodeRep( int numBytes) /* Number of bytes of "bytes" to convert. */ { Tcl_DString dsPtr; - int numChars; - Tcl_UniChar *unicode; + int numChars = numBytes; + Tcl_UniChar *unicode = NULL; if (numBytes < 0) { numBytes = (bytes ? strlen(bytes) : 0); @@ -1489,8 +1493,11 @@ AppendUtfToUnicodeRep( } Tcl_DStringInit(&dsPtr); - numChars = Tcl_NumUtfChars(bytes, numBytes); - unicode = (Tcl_UniChar *)Tcl_UtfToUniCharDString(bytes, numBytes, &dsPtr); + if (bytes) { + numChars = Tcl_NumUtfChars(bytes, numBytes); + unicode = (Tcl_UniChar *) Tcl_UtfToUniCharDString(bytes, numBytes, + &dsPtr); + } AppendUnicodeToUnicodeRep(objPtr, unicode, numChars); Tcl_DStringFree(&dsPtr); } @@ -1547,7 +1554,7 @@ AppendUtfToUtfRep( * due to the reallocs below. */ int offset = -1; - if (bytes >= objPtr->bytes + if (bytes && bytes >= objPtr->bytes && bytes <= objPtr->bytes + objPtr->length) { offset = bytes - objPtr->bytes; } @@ -1585,7 +1592,9 @@ AppendUtfToUtfRep( stringPtr->numChars = -1; stringPtr->hasUnicode = 0; - memcpy(objPtr->bytes + oldLength, bytes, (size_t) numBytes); + if (bytes) { + memcpy(objPtr->bytes + oldLength, bytes, (size_t) numBytes); + } objPtr->bytes[newLength] = 0; objPtr->length = newLength; } -- cgit v0.12 From cad363e97d6e49c6a0e691c9efa55d2a02f8514d Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 6 Feb 2014 19:04:36 +0000 Subject: Revised ReadChars to restore an attempt to make sure we do not short read because of a false notion of limited storage space. The test suite does not appear to demonstrate any case where this matters. Could be an incomplete test suite, or an example of pointless code. --- generic/tclIO.c | 8 +++++++- generic/tclInt.h | 2 ++ generic/tclStringObj.c | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 41 insertions(+), 1 deletion(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index f8baba3..cedf3f6 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -5310,7 +5310,13 @@ ReadChars( dstNeeded = TCL_UTF_MAX - 1 + toRead * factor / UTF_EXPANSION_FACTOR; (void) TclGetStringFromObj(objPtr, &numBytes); Tcl_AppendToObj(objPtr, NULL, dstNeeded); - dst = TclGetString(objPtr) + numBytes; + if (toRead == srcLen) { + unsigned int size; + dst = TclGetStringStorage(objPtr, &size) + numBytes; + dstNeeded = size - numBytes; + } else { + dst = TclGetString(objPtr) + numBytes; + } /* * [Bug 1462248]: The cause of the crash reported in this bug is this: diff --git a/generic/tclInt.h b/generic/tclInt.h index a998460..0c09ec0 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -2571,6 +2571,8 @@ MODULE_SCOPE int TclGetOpenModeEx(Tcl_Interp *interp, int *binaryPtr); MODULE_SCOPE Tcl_Obj * TclGetProcessGlobalValue(ProcessGlobalValue *pgvPtr); MODULE_SCOPE const char *TclGetSrcInfoForCmd(Interp *iPtr, int *lenPtr); +MODULE_SCOPE char * TclGetStringStorage(Tcl_Obj *objPtr, + unsigned int *sizePtr); MODULE_SCOPE int TclGlob(Tcl_Interp *interp, char *pattern, Tcl_Obj *unquotedPrefix, int globFlags, Tcl_GlobTypeData *types); diff --git a/generic/tclStringObj.c b/generic/tclStringObj.c index d96d814..8c6a376 100644 --- a/generic/tclStringObj.c +++ b/generic/tclStringObj.c @@ -2711,6 +2711,38 @@ Tcl_ObjPrintf( /* *--------------------------------------------------------------------------- * + * TclGetStringStorage -- + * + * Returns the string storage space of a Tcl_Obj. + * + * Results: + * The pointer value objPtr->bytes is returned and the number of bytes + * allocated there is written to *sizePtr (if known). + * + * Side effects: + * May set objPtr->bytes. + * + *--------------------------------------------------------------------------- + */ + +char * +TclGetStringStorage( + Tcl_Obj *objPtr, + unsigned int *sizePtr) +{ + String *stringPtr; + + if (objPtr->typePtr != &tclStringType || objPtr->bytes == NULL) { + return TclGetStringFromObj(objPtr, (int *)sizePtr); + } + + stringPtr = GET_STRING(objPtr); + *sizePtr = stringPtr->allocated; + return objPtr->bytes; +} +/* + *--------------------------------------------------------------------------- + * * TclStringObjReverse -- * * Implements the [string reverse] operation. -- cgit v0.12 From 39ddd8c91b11194bc3b71b9db2dfbc63e4c8fa41 Mon Sep 17 00:00:00 2001 From: dkf Date: Sat, 8 Feb 2014 07:54:04 +0000 Subject: improve the testing of the disassembly commands --- tests/compile.test | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 81 insertions(+), 1 deletion(-) diff --git a/tests/compile.test b/tests/compile.test index 2852bf2..22ebc7d 100644 --- a/tests/compile.test +++ b/tests/compile.test @@ -658,12 +658,15 @@ test compile-17.2 {Command interpretation binding for non-compiled code} -setup # does not check the format of disassembled bytecode though; that's liable to # change without warning. +set disassemblables [linsert [join { + lambda method objmethod proc script +} ", "] end-1 or] test compile-18.1 {disassembler - basics} -returnCodes error -body { tcl::unsupported::disassemble } -match glob -result {wrong # args: should be "*"} test compile-18.2 {disassembler - basics} -returnCodes error -body { tcl::unsupported::disassemble ? -} -match glob -result {bad type "?": must be *} +} -result "bad type \"?\": must be $disassemblables" test compile-18.3 {disassembler - basics} -returnCodes error -body { tcl::unsupported::disassemble lambda } -match glob -result {wrong # args: should be "* lambda lambdaTerm"} @@ -737,6 +740,83 @@ test compile-18.19 {disassembler - basics} -setup { } -cleanup { foo destroy } -match glob -result * +# There never was a compile-18.20. +# The keys of the dictionary produced by [getbytecode] are defined. +set bytecodekeys {literals variables exception instructions auxiliary commands script namespace stackdepth exceptdepth} +test compile-18.21 {disassembler - basics} -returnCodes error -body { + tcl::unsupported::getbytecode +} -match glob -result {wrong # args: should be "*"} +test compile-18.22 {disassembler - basics} -returnCodes error -body { + tcl::unsupported::getbytecode ? +} -result "bad type \"?\": must be $disassemblables" +test compile-18.23 {disassembler - basics} -returnCodes error -body { + tcl::unsupported::getbytecode lambda +} -match glob -result {wrong # args: should be "* lambda lambdaTerm"} +test compile-18.24 {disassembler - basics} -returnCodes error -body { + tcl::unsupported::getbytecode lambda \{ +} -result "can't interpret \"\{\" as a lambda expression" +test compile-18.25 {disassembler - basics} -body { + dict keys [tcl::unsupported::getbytecode lambda {{} {}}] +} -result $bytecodekeys +test compile-18.26 {disassembler - basics} -returnCodes error -body { + tcl::unsupported::getbytecode proc +} -match glob -result {wrong # args: should be "* proc procName"} +test compile-18.27 {disassembler - basics} -returnCodes error -body { + tcl::unsupported::getbytecode proc nosuchproc +} -result {"nosuchproc" isn't a procedure} +test compile-18.28 {disassembler - basics} -setup { + proc chewonthis {} {} +} -body { + dict keys [tcl::unsupported::getbytecode proc chewonthis] +} -cleanup { + rename chewonthis {} +} -result $bytecodekeys +test compile-18.29 {disassembler - basics} -returnCodes error -body { + tcl::unsupported::getbytecode script +} -match glob -result {wrong # args: should be "* script script"} +test compile-18.30 {disassembler - basics} -body { + dict keys [tcl::unsupported::getbytecode script {}] +} -result $bytecodekeys +test compile-18.31 {disassembler - basics} -returnCodes error -body { + tcl::unsupported::getbytecode method +} -match glob -result {wrong # args: should be "* method className methodName"} +test compile-18.32 {disassembler - basics} -returnCodes error -body { + tcl::unsupported::getbytecode method nosuchclass foo +} -result {nosuchclass does not refer to an object} +test compile-18.33 {disassembler - basics} -returnCodes error -setup { + oo::object create justanobject +} -body { + tcl::unsupported::getbytecode method justanobject foo +} -cleanup { + justanobject destroy +} -result {"justanobject" is not a class} +test compile-18.34 {disassembler - basics} -returnCodes error -body { + tcl::unsupported::getbytecode method oo::object nosuchmethod +} -result {unknown method "nosuchmethod"} +test compile-18.35 {disassembler - basics} -setup { + oo::class create foo {method bar {} {}} +} -body { + dict keys [tcl::unsupported::getbytecode method foo bar] +} -cleanup { + foo destroy +} -result $bytecodekeys +test compile-18.36 {disassembler - basics} -returnCodes error -body { + tcl::unsupported::getbytecode objmethod +} -match glob -result {wrong # args: should be "* objmethod objectName methodName"} +test compile-18.37 {disassembler - basics} -returnCodes error -body { + tcl::unsupported::getbytecode objmethod nosuchobject foo +} -result {nosuchobject does not refer to an object} +test compile-18.38 {disassembler - basics} -returnCodes error -body { + tcl::unsupported::getbytecode objmethod oo::object nosuchmethod +} -result {unknown method "nosuchmethod"} +test compile-18.39 {disassembler - basics} -setup { + oo::object create foo + oo::objdefine foo {method bar {} {}} +} -body { + dict keys [tcl::unsupported::getbytecode objmethod foo bar] +} -cleanup { + foo destroy +} -result $bytecodekeys test compile-19.0 {Bug 3614102: reset stack housekeeping} -body { # This will panic in a --enable-symbols=compile build, unless bug is fixed. -- cgit v0.12 From 342aec668484f8c8eaf839297e998f0fe6ee1a26 Mon Sep 17 00:00:00 2001 From: dgp Date: Tue, 11 Feb 2014 19:53:41 +0000 Subject: Refactor so that CopyAndTranslateBuffer() calls on TranslateInputEOL() instead of duplicating so much of its function. Note the testing gaps. --- generic/tclIO.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index cedf3f6..09b8191 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -8805,8 +8805,6 @@ CopyAndTranslateBuffer( * in the current input buffer? */ int copied; /* How many characters were already copied * into the destination space? */ - int i; /* Iterates over the copied input looking for - * the input eofChar. */ /* * If there is no input at all, return zero. The invariant is that either @@ -8821,6 +8819,15 @@ CopyAndTranslateBuffer( bufPtr = statePtr->inQueueHead; bytesInBuffer = BytesLeft(bufPtr); +#if 1 + copied = space; + if (bytesInBuffer <= copied) { + copied = bytesInBuffer; + } + TranslateInputEOL(statePtr, result, RemovePoint(bufPtr), + &copied, &bytesInBuffer); + bufPtr->nextRemoved += copied; +#else copied = 0; switch (statePtr->inputTranslation) { case TCL_TRANSLATE_LF: @@ -8842,6 +8849,7 @@ CopyAndTranslateBuffer( case TCL_TRANSLATE_CR: { char *end; + Tcl_Panic("Untested"); if (bytesInBuffer == 0) { return 0; } @@ -8873,6 +8881,7 @@ CopyAndTranslateBuffer( * If there is a held-back "\r" at EOF, produce it now. */ + Tcl_Panic("Untested"); if (bytesInBuffer == 0) { if ((statePtr->flags & (INPUT_SAW_CR | CHANNEL_EOF)) == (INPUT_SAW_CR | CHANNEL_EOF)) { @@ -8940,6 +8949,7 @@ CopyAndTranslateBuffer( for (src = result; src < end; src++) { curByte = *src; if (curByte == '\r') { + Tcl_Panic("Untested"); SetFlag(statePtr, INPUT_SAW_CR); *dst = '\n'; dst++; @@ -8965,6 +8975,9 @@ CopyAndTranslateBuffer( */ if (statePtr->inEofChar != 0) { + int i; + + Tcl_Panic("Untested"); for (i = 0; i < copied; i++) { if (result[i] == (char) statePtr->inEofChar) { /* @@ -8979,6 +8992,7 @@ CopyAndTranslateBuffer( } } } +#endif /* * If the current buffer is empty recycle it. -- cgit v0.12 From 06a0036a49375ed0efd5f5fe8334f9c530da944a Mon Sep 17 00:00:00 2001 From: dgp Date: Tue, 18 Feb 2014 17:54:06 +0000 Subject: Coverage test for -translation auto handling of INPUT_SAW_CR flag. Demonstrates refactor failure. --- generic/tclIO.c | 1 - tests/io.test | 15 +++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index 09b8191..20101c2 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -8949,7 +8949,6 @@ CopyAndTranslateBuffer( for (src = result; src < end; src++) { curByte = *src; if (curByte == '\r') { - Tcl_Panic("Untested"); SetFlag(statePtr, INPUT_SAW_CR); *dst = '\n'; dst++; diff --git a/tests/io.test b/tests/io.test index 68051d7..e08c57a 100644 --- a/tests/io.test +++ b/tests/io.test @@ -6730,6 +6730,21 @@ test io-52.11 {TclCopyChannel & encodings} {fcopy} { file size $path(kyrillic.txt) } 3 +test io-52.12 {coverage of -translation auto} { + file delete $path(test1) $path(test2) + set out [open $path(test1) wb] + chan configure $out -translation lf + puts -nonewline $out abcdefg\rhijklmn\nopqrstu\r\nvwxyz + close $out + set in [open $path(test1)] + chan configure $in -buffersize 8 + set out [open $path(test2) w] + fcopy $in $out + close $in + close $out + file size $path(test2) +} 29 + test io-53.1 {CopyData} {fcopy} { file delete $path(test1) set f1 [open $thisScript] -- cgit v0.12 From 521821debf216a705df7667ef2dc51fbfa104727 Mon Sep 17 00:00:00 2001 From: dgp Date: Tue, 18 Feb 2014 18:26:22 +0000 Subject: Refactor correction exposed by coverage test. --- generic/tclIO.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index 20101c2..01af6dc 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -8826,7 +8826,7 @@ CopyAndTranslateBuffer( } TranslateInputEOL(statePtr, result, RemovePoint(bufPtr), &copied, &bytesInBuffer); - bufPtr->nextRemoved += copied; + bufPtr->nextRemoved += bytesInBuffer; #else copied = 0; switch (statePtr->inputTranslation) { -- cgit v0.12 From e51a0bd096c1323c5008a1156d5565ed4aef05fb Mon Sep 17 00:00:00 2001 From: dgp Date: Tue, 18 Feb 2014 18:35:19 +0000 Subject: coverage test for -translation cr --- generic/tclIO.c | 1 - tests/io.test | 14 ++++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index 01af6dc..4197dc0 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -8849,7 +8849,6 @@ CopyAndTranslateBuffer( case TCL_TRANSLATE_CR: { char *end; - Tcl_Panic("Untested"); if (bytesInBuffer == 0) { return 0; } diff --git a/tests/io.test b/tests/io.test index e08c57a..0c2944b 100644 --- a/tests/io.test +++ b/tests/io.test @@ -6744,6 +6744,20 @@ test io-52.12 {coverage of -translation auto} { close $out file size $path(test2) } 29 +test io-52.13 {coverage of -translation cr} { + file delete $path(test1) $path(test2) + set out [open $path(test1) wb] + chan configure $out -translation lf + puts -nonewline $out abcdefg\rhijklmn\nopqrstu\r\nvwxyz + close $out + set in [open $path(test1)] + chan configure $in -buffersize 8 -translation cr + set out [open $path(test2) w] + fcopy $in $out + close $in + close $out + file size $path(test2) +} 30 test io-53.1 {CopyData} {fcopy} { file delete $path(test1) -- cgit v0.12 From d4cb991846ecd7a5593109f219c79a1c6d8e9e85 Mon Sep 17 00:00:00 2001 From: dgp Date: Tue, 18 Feb 2014 21:27:35 +0000 Subject: Another coverage test that reveals refactoring error. --- generic/tclIO.c | 2 +- tests/io.test | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index 4197dc0..c862923 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -8880,10 +8880,10 @@ CopyAndTranslateBuffer( * If there is a held-back "\r" at EOF, produce it now. */ - Tcl_Panic("Untested"); if (bytesInBuffer == 0) { if ((statePtr->flags & (INPUT_SAW_CR | CHANNEL_EOF)) == (INPUT_SAW_CR | CHANNEL_EOF)) { + Tcl_Panic("Untested"); result[0] = '\r'; ResetFlag(statePtr, INPUT_SAW_CR); return 1; diff --git a/tests/io.test b/tests/io.test index 0c2944b..4df44a3 100644 --- a/tests/io.test +++ b/tests/io.test @@ -6758,6 +6758,20 @@ test io-52.13 {coverage of -translation cr} { close $out file size $path(test2) } 30 +test io-52.14 {coverage of -translation crlf} { + file delete $path(test1) $path(test2) + set out [open $path(test1) wb] + chan configure $out -translation lf + puts -nonewline $out abcdefg\rhijklmn\nopqrstu\r\nvwxyz + close $out + set in [open $path(test1)] + chan configure $in -buffersize 8 -translation crlf + set out [open $path(test2) w] + fcopy $in $out + close $in + close $out + file size $path(test2) +} 29 test io-53.1 {CopyData} {fcopy} { file delete $path(test1) -- cgit v0.12 From 0e8e132acafb234142d03ccfd047bf5cc8a7623b Mon Sep 17 00:00:00 2001 From: dgp Date: Tue, 18 Feb 2014 23:20:06 +0000 Subject: Callers of TranslateInputEOL are expected to manage the INPUT_NEED_NL flag. --- generic/tclIO.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/generic/tclIO.c b/generic/tclIO.c index c862923..68d370a 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -8824,6 +8824,20 @@ CopyAndTranslateBuffer( if (bytesInBuffer <= copied) { copied = bytesInBuffer; } + if (copied == 0) { + return 0; + } + if (statePtr->flags & INPUT_NEED_NL) { + ResetFlag(statePtr, INPUT_NEED_NL); + + if (RemovePoint(bufPtr)[0] == '\n') { + bufPtr->nextRemoved++; + *result = '\n'; + } else { + *result = '\r'; + } + return 1; + } TranslateInputEOL(statePtr, result, RemovePoint(bufPtr), &copied, &bytesInBuffer); bufPtr->nextRemoved += bytesInBuffer; -- cgit v0.12 From c65342141a7a8187a03d678aaa06d007b41b13b4 Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 19 Feb 2014 03:36:15 +0000 Subject: Shortcut ReadBytes() when it's a no-op. --- generic/tclIO.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index 68d370a..7820242 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -5201,6 +5201,9 @@ ReadBytes( if ((unsigned) toRead > (unsigned) srcLen) { toRead = srcLen; } + if (toRead == 0) { + return 0; + } (void) Tcl_GetByteArrayFromObj(objPtr, &length); TclAppendBytesToByteArray(objPtr, NULL, toRead); @@ -5209,7 +5212,7 @@ ReadBytes( if (statePtr->flags & INPUT_NEED_NL) { ResetFlag(statePtr, INPUT_NEED_NL); - if ((srcLen == 0) || (*src != '\n')) { + if (*src != '\n') { *dst = '\r'; length += 1; Tcl_SetByteArrayLength(objPtr, length); -- cgit v0.12 From 3ac01c586fffb31c1ea15215de23dc8ed4743dd9 Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 19 Feb 2014 03:45:17 +0000 Subject: Next coverage test to expose another refactoring error. --- generic/tclIO.c | 1 - tests/io.test | 14 ++++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index 7820242..3b2b53e 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -8900,7 +8900,6 @@ CopyAndTranslateBuffer( if (bytesInBuffer == 0) { if ((statePtr->flags & (INPUT_SAW_CR | CHANNEL_EOF)) == (INPUT_SAW_CR | CHANNEL_EOF)) { - Tcl_Panic("Untested"); result[0] = '\r'; ResetFlag(statePtr, INPUT_SAW_CR); return 1; diff --git a/tests/io.test b/tests/io.test index 4df44a3..8c066ca 100644 --- a/tests/io.test +++ b/tests/io.test @@ -6772,6 +6772,20 @@ test io-52.14 {coverage of -translation crlf} { close $out file size $path(test2) } 29 +test io-52.15 {coverage of -translation crlf} { + file delete $path(test1) $path(test2) + set out [open $path(test1) wb] + chan configure $out -translation lf + puts -nonewline $out abcdefg\r + close $out + set in [open $path(test1)] + chan configure $in -buffersize 8 -translation crlf + set out [open $path(test2) w] + fcopy $in $out + close $in + close $out + file size $path(test2) +} 8 test io-53.1 {CopyData} {fcopy} { file delete $path(test1) -- cgit v0.12 From 90d32945723d9fb68d14d6896d47ad5fa571d66f Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 20 Feb 2014 03:51:16 +0000 Subject: Refactoring repair to fix failing test. --- generic/tclIO.c | 52 +++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 37 insertions(+), 15 deletions(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index 3b2b53e..3cddc29 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -8808,6 +8808,7 @@ CopyAndTranslateBuffer( * in the current input buffer? */ int copied; /* How many characters were already copied * into the destination space? */ + int toCopy; /* * If there is no input at all, return zero. The invariant is that either @@ -8822,30 +8823,51 @@ CopyAndTranslateBuffer( bufPtr = statePtr->inQueueHead; bytesInBuffer = BytesLeft(bufPtr); + copied = 0; #if 1 - copied = space; - if (bytesInBuffer <= copied) { - copied = bytesInBuffer; - } - if (copied == 0) { - return 0; - } if (statePtr->flags & INPUT_NEED_NL) { - ResetFlag(statePtr, INPUT_NEED_NL); - if (RemovePoint(bufPtr)[0] == '\n') { - bufPtr->nextRemoved++; - *result = '\n'; - } else { + /* + * An earlier call to TranslateInputEOL ended in the read of a \r . + * Only the next read from the same channel can complete the + * translation sequence to tell us what character we should read. + */ + + if (bytesInBuffer) { + /* There's a next byte. It will settle things. */ + ResetFlag(statePtr, INPUT_NEED_NL); + + if (RemovePoint(bufPtr)[0] == '\n') { + bufPtr->nextRemoved++; + bytesInBuffer--; + *result++ = '\n'; + } else { + *result++ = '\r'; + } + copied++; + space--; + } else if (statePtr->flags & CHANNEL_EOF) { + /* There is no next byte, and there never will be (EOF). */ + ResetFlag(statePtr, INPUT_NEED_NL); *result = '\r'; + return 1; + } else { + /* There is no next byte. Ask the caller to read more. */ + return 0; } - return 1; + } + toCopy = space; + if (bytesInBuffer <= toCopy) { + toCopy = bytesInBuffer; + } + if (toCopy == 0) { + return copied; } TranslateInputEOL(statePtr, result, RemovePoint(bufPtr), - &copied, &bytesInBuffer); + &toCopy, &bytesInBuffer); bufPtr->nextRemoved += bytesInBuffer; + copied += toCopy; #else - copied = 0; switch (statePtr->inputTranslation) { case TCL_TRANSLATE_LF: if (bytesInBuffer == 0) { -- cgit v0.12 From 90725c211bd31be692705c3d09b72d3f374e97f3 Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 20 Feb 2014 20:31:55 +0000 Subject: Can we send some binary reads down the char-reading path? --- generic/tclIO.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index 3636861..4d7133a 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -5096,7 +5096,8 @@ DoReadChars( for (copied = 0; (unsigned) toRead > 0; ) { copiedNow = -1; if (statePtr->inQueueHead != NULL) { - if (encoding == NULL) { + if (encoding == NULL + && statePtr->inputTranslation == TCL_TRANSLATE_LF) { copiedNow = ReadBytes(statePtr, objPtr, toRead, &offset); } else { copiedNow = ReadChars(statePtr, objPtr, toRead, &offset, @@ -5320,6 +5321,8 @@ ReadChars( char *src, *dst; Tcl_EncodingState oldState; int encEndFlagSuppressed = 0; + Tcl_Encoding encoding = statePtr->encoding? statePtr->encoding + : GetBinaryEncoding(); factor = *factorPtr; offset = *offsetPtr; @@ -5424,7 +5427,7 @@ ReadChars( */ ResetFlag(statePtr, INPUT_NEED_NL); - Tcl_ExternalToUtf(NULL, statePtr->encoding, src, srcLen, + Tcl_ExternalToUtf(NULL, encoding, src, srcLen, statePtr->inputEncodingFlags, &statePtr->inputEncodingState, dst, TCL_UTF_MAX + 1, &srcRead, &dstWrote, &numChars); if ((dstWrote > 0) && (*dst == '\n')) { @@ -5449,7 +5452,7 @@ ReadChars( return 1; } - Tcl_ExternalToUtf(NULL, statePtr->encoding, src, srcLen, + Tcl_ExternalToUtf(NULL, encoding, src, srcLen, statePtr->inputEncodingFlags, &statePtr->inputEncodingState, dst, dstNeeded + 1, &srcRead, &dstWrote, &numChars); @@ -5522,7 +5525,7 @@ ReadChars( return -1; } statePtr->inputEncodingState = oldState; - Tcl_ExternalToUtf(NULL, statePtr->encoding, src, srcLen, + Tcl_ExternalToUtf(NULL, encoding, src, srcLen, statePtr->inputEncodingFlags, &statePtr->inputEncodingState, dst, dstRead + TCL_UTF_MAX, &srcRead, &dstWrote, &numChars); TranslateInputEOL(statePtr, dst, dst, &dstWrote, &dstRead); @@ -5545,7 +5548,7 @@ ReadChars( eof = Tcl_UtfAtIndex(dst, toRead); statePtr->inputEncodingState = oldState; - Tcl_ExternalToUtf(NULL, statePtr->encoding, src, srcLen, + Tcl_ExternalToUtf(NULL, encoding, src, srcLen, statePtr->inputEncodingFlags, &statePtr->inputEncodingState, dst, eof - dst + TCL_UTF_MAX, &srcRead, &dstWrote, &numChars); dstRead = dstWrote; -- cgit v0.12 From 01eab1e2cdd065cfd329a594417fe4fe84a75451 Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 20 Feb 2014 21:23:33 +0000 Subject: Switch consistently on the narrower def of binary mode. --- generic/tclIO.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index 4d7133a..eae063b 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -5060,6 +5060,7 @@ DoReadChars( ChannelBuffer *bufPtr; int offset, factor, copied, copiedNow, result; Tcl_Encoding encoding; + int binaryMode; #define UTF_EXPANSION_FACTOR 1024 /* @@ -5070,8 +5071,12 @@ DoReadChars( encoding = statePtr->encoding; factor = UTF_EXPANSION_FACTOR; + binaryMode = (encoding == NULL) + && (statePtr->inputTranslation == TCL_TRANSLATE_LF) + && (statePtr->inEofChar == NULL); + if (appendFlag == 0) { - if (encoding == NULL) { + if (binaryMode) { Tcl_SetByteArrayLength(objPtr, 0); } else { Tcl_SetObjLength(objPtr, 0); @@ -5086,7 +5091,7 @@ DoReadChars( } offset = 0; } else { - if (encoding == NULL) { + if (binaryMode) { Tcl_GetByteArrayFromObj(objPtr, &offset); } else { TclGetStringFromObj(objPtr, &offset); @@ -5096,8 +5101,7 @@ DoReadChars( for (copied = 0; (unsigned) toRead > 0; ) { copiedNow = -1; if (statePtr->inQueueHead != NULL) { - if (encoding == NULL - && statePtr->inputTranslation == TCL_TRANSLATE_LF) { + if (binaryMode) { copiedNow = ReadBytes(statePtr, objPtr, toRead, &offset); } else { copiedNow = ReadChars(statePtr, objPtr, toRead, &offset, @@ -5146,7 +5150,7 @@ DoReadChars( } ResetFlag(statePtr, CHANNEL_BLOCKED); - if (encoding == NULL) { + if (binaryMode) { Tcl_SetByteArrayLength(objPtr, offset); } else { Tcl_SetObjLength(objPtr, offset); -- cgit v0.12 From b6212a88b3edaba0d5c5430ad72bb4b3cc8f11f1 Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 21 Feb 2014 15:02:35 +0000 Subject: fix type error --- generic/tclIO.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index eae063b..ac28ec0 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -5073,7 +5073,7 @@ DoReadChars( binaryMode = (encoding == NULL) && (statePtr->inputTranslation == TCL_TRANSLATE_LF) - && (statePtr->inEofChar == NULL); + && (statePtr->inEofChar == '\0'); if (appendFlag == 0) { if (binaryMode) { -- cgit v0.12 From b3bfa3ee1d03a57a8c3e08e515e4c82a72e74d2a Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 21 Feb 2014 15:12:16 +0000 Subject: Simplify ReadBytes based on new constraints. --- generic/tclIO.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/generic/tclIO.c b/generic/tclIO.c index ac28ec0..23e1fbf 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -5242,6 +5242,10 @@ ReadBytes( } dst += offset; +#if 1 + memcpy(dst, src, (size_t) toRead); + srcRead = dstWrote = toRead; +#else if (statePtr->flags & INPUT_NEED_NL) { ResetFlag(statePtr, INPUT_NEED_NL); if ((srcLen == 0) || (*src != '\n')) { @@ -5262,6 +5266,7 @@ ReadBytes( return -1; } } +#endif bufPtr->nextRemoved += srcRead; *offsetPtr += dstWrote; return dstWrote; -- cgit v0.12 From 6733e578355af3fb98418aa44f016530f6eaa9d3 Mon Sep 17 00:00:00 2001 From: dgp Date: Mon, 24 Feb 2014 21:01:07 +0000 Subject: simplification trims --- generic/tclIO.c | 34 ++++------------------------------ 1 file changed, 4 insertions(+), 30 deletions(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index 5625ff2..1c5fed4 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -5194,7 +5194,7 @@ ReadBytes( * the bytes from the first buffer are * returned. */ { - int toRead, srcLen, length, srcRead, dstWrote; + int toRead, srcLen, length; ChannelBuffer *bufPtr; char *src, *dst; @@ -5215,37 +5215,11 @@ ReadBytes( dst = (char *) Tcl_GetByteArrayFromObj(objPtr, NULL); dst += length; -#if 1 memcpy(dst, src, (size_t) toRead); - srcRead = dstWrote = toRead; -#else - if (statePtr->flags & INPUT_NEED_NL) { - ResetFlag(statePtr, INPUT_NEED_NL); - if (*src != '\n') { - *dst = '\r'; - length += 1; - Tcl_SetByteArrayLength(objPtr, length); - return 1; - } - *dst++ = '\n'; - src++; - srcLen--; - toRead--; - } - - srcRead = srcLen; - dstWrote = toRead; - if (TranslateInputEOL(statePtr, dst, src, &dstWrote, &srcRead) != 0) { - if (dstWrote == 0) { - Tcl_SetByteArrayLength(objPtr, length); - return -1; - } - } -#endif - bufPtr->nextRemoved += srcRead; - length += dstWrote; + bufPtr->nextRemoved += toRead; + length += toRead; Tcl_SetByteArrayLength(objPtr, length); - return dstWrote; + return toRead; } /* -- cgit v0.12 From e8e909f1cdd4848bf73c85117a5d0062dc386839 Mon Sep 17 00:00:00 2001 From: dgp Date: Mon, 24 Feb 2014 21:25:08 +0000 Subject: Reduce ReadBytes to simplest expression. --- generic/tclIO.c | 28 +++++----------------------- 1 file changed, 5 insertions(+), 23 deletions(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index 1c5fed4..a73f041 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -5194,31 +5194,13 @@ ReadBytes( * the bytes from the first buffer are * returned. */ { - int toRead, srcLen, length; - ChannelBuffer *bufPtr; - char *src, *dst; - - bufPtr = statePtr->inQueueHead; - src = RemovePoint(bufPtr); - srcLen = BytesLeft(bufPtr); - - toRead = bytesToRead; - if ((unsigned) toRead > (unsigned) srcLen) { - toRead = srcLen; - } - if (toRead == 0) { - return 0; - } - - (void) Tcl_GetByteArrayFromObj(objPtr, &length); - TclAppendBytesToByteArray(objPtr, NULL, toRead); - dst = (char *) Tcl_GetByteArrayFromObj(objPtr, NULL); - dst += length; + ChannelBuffer *bufPtr = statePtr->inQueueHead; + int srcLen = BytesLeft(bufPtr); + int toRead = bytesToRead>srcLen || bytesToRead<0 ? srcLen : bytesToRead; - memcpy(dst, src, (size_t) toRead); + TclAppendBytesToByteArray(objPtr, (unsigned char *) RemovePoint(bufPtr), + toRead); bufPtr->nextRemoved += toRead; - length += toRead; - Tcl_SetByteArrayLength(objPtr, length); return toRead; } -- cgit v0.12 From 2207a65968067f338adedf3dd97e3970908e803f Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 26 Feb 2014 11:26:00 +0000 Subject: More coverage tests and bug fixes. --- generic/tclIO.c | 3 +-- tests/io.test | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+), 2 deletions(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index a73f041..c2a8cab 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -5644,7 +5644,7 @@ TranslateInputEOL( SetFlag(statePtr, CHANNEL_EOF | CHANNEL_STICKY_EOF); statePtr->inputEncodingFlags |= TCL_ENCODING_END; - ResetFlag(statePtr, INPUT_SAW_CR | INPUT_NEED_NL); +// ResetFlag(statePtr, INPUT_SAW_CR | INPUT_NEED_NL); return 1; } @@ -8981,7 +8981,6 @@ CopyAndTranslateBuffer( if (statePtr->inEofChar != 0) { int i; - Tcl_Panic("Untested"); for (i = 0; i < copied; i++) { if (result[i] == (char) statePtr->inEofChar) { /* diff --git a/tests/io.test b/tests/io.test index 8c066ca..6f4877f 100644 --- a/tests/io.test +++ b/tests/io.test @@ -6786,6 +6786,62 @@ test io-52.15 {coverage of -translation crlf} { close $out file size $path(test2) } 8 +test io-52.16 {coverage of eofChar handling} { + file delete $path(test1) $path(test2) + set out [open $path(test1) wb] + chan configure $out -translation lf + puts -nonewline $out abcdefg\rhijklmn\nopqrstu\r\nvwxyz + close $out + set in [open $path(test1)] + chan configure $in -buffersize 8 -translation lf -eofchar a + set out [open $path(test2) w] + fcopy $in $out + close $in + close $out + file size $path(test2) +} 0 +test io-52.17 {coverage of eofChar handling} { + file delete $path(test1) $path(test2) + set out [open $path(test1) wb] + chan configure $out -translation lf + puts -nonewline $out abcdefg\rhijklmn\nopqrstu\r\nvwxyz + close $out + set in [open $path(test1)] + chan configure $in -buffersize 8 -translation lf -eofchar d + set out [open $path(test2) w] + fcopy $in $out + close $in + close $out + file size $path(test2) +} 3 +test io-52.18 {coverage of eofChar handling} { + file delete $path(test1) $path(test2) + set out [open $path(test1) wb] + chan configure $out -translation lf + puts -nonewline $out abcdefg\rhijklmn\nopqrstu\r\nvwxyz + close $out + set in [open $path(test1)] + chan configure $in -buffersize 8 -translation crlf -eofchar h + set out [open $path(test2) w] + fcopy $in $out + close $in + close $out + file size $path(test2) +} 8 +test io-52.19 {coverage of eofChar handling} { + file delete $path(test1) $path(test2) + set out [open $path(test1) wb] + chan configure $out -translation lf + puts -nonewline $out abcdefg\rhijklmn\nopqrstu\r\nvwxyz + close $out + set in [open $path(test1)] + chan configure $in -buffersize 10 -translation crlf -eofchar h + set out [open $path(test2) w] + fcopy $in $out + close $in + close $out + file size $path(test2) +} 8 test io-53.1 {CopyData} {fcopy} { file delete $path(test1) -- cgit v0.12 From 378008089c0aa4f283ed6265f02e00d9d0065bc0 Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 27 Feb 2014 20:11:47 +0000 Subject: remove comment --- generic/tclIO.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index c2a8cab..8d75bf2 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -5644,7 +5644,7 @@ TranslateInputEOL( SetFlag(statePtr, CHANNEL_EOF | CHANNEL_STICKY_EOF); statePtr->inputEncodingFlags |= TCL_ENCODING_END; -// ResetFlag(statePtr, INPUT_SAW_CR | INPUT_NEED_NL); + ResetFlag(statePtr, INPUT_SAW_CR | INPUT_NEED_NL); return 1; } -- cgit v0.12 From 2f73d6810cef3cf1786b1b40066daa396e152ca3 Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 27 Feb 2014 20:21:10 +0000 Subject: Work in progress attempting a ReadChars rewrite. --- generic/tclIO.c | 120 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 119 insertions(+), 1 deletion(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index 3636861..20428b5 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -5372,6 +5372,120 @@ ReadChars( } dst = objPtr->bytes + offset; +#if 1 + + /* + * This routine is burdened with satisfying several constraints. + * It cannot append more than 'charsToRead` chars onto objPtr. + * This is measured after encoding and translation transformations + * are completed. There is no precise number of src bytes that can + * be associated with the limit. Yet, when we are done, we must know + * precisely the number of src bytes that were consumed to produce + * the appended chars, so that all subsequent bytes are left in + * the buffers for future read operations. + * + * The consequence is that we have no choice but to implement a + * "trial and error" approach, where in general we may need to + * perform transformations and copies multiple times to achieve + * a consistent set of results. This takes the shape of a loop. + */ + + int dstLimit = dstNeeded + 1; + int savedFlags = statePtr->flags; + int savedIEFlags = statePtr->inputEncodingFlags; + Tcl_EncodingState savedState = statePtr->inputEncodingState; + + while (1) { + int dstDecoded; + + /* + * Perform the encoding transformation. Read no more than + * srcLen bytes, write no more than dstLimit bytes. + */ + +//fprintf(stdout, "Start %d %d\n", dstLimit, srcLen); fflush(stdout); + int code = Tcl_ExternalToUtf(NULL, statePtr->encoding, src, srcLen, + statePtr->inputEncodingFlags & (bufPtr->nextPtr + ? ~0 : ~TCL_ENCODING_END), &statePtr->inputEncodingState, + dst, dstLimit, &srcRead, &dstDecoded, &numChars); + + /* + * Perform the translation transformation in place. Read no more + * than the dstDecoded bytes the encoding transformation actually + * produced. Capture the number of bytes written in dstWrote. + * Capture the number of bytes actually consumed in dstRead. + */ + +//fprintf(stdout, "Key NS=%d MB=%d S=%d\n", TCL_CONVERT_NOSPACE, +//TCL_CONVERT_MULTIBYTE, TCL_CONVERT_SYNTAX); fflush(stdout); +//fprintf(stdout, "Decoded %d %d\n", dstDecoded,code); fflush(stdout); + dstWrote = dstRead = dstDecoded; + TranslateInputEOL(statePtr, dst, dst, &dstWrote, &dstRead); + + if (dstRead < dstDecoded) { + + /* + * The encoding transformation produced bytes that the + * translation transformation did not consume. Start over + * and impose new limits so that doesn't happen again. + */ +//fprintf(stdout, "X! %d %d\n", dstRead, dstDecoded); fflush(stdout); + + dstLimit = dstRead + TCL_UTF_MAX; + statePtr->flags = savedFlags; + statePtr->inputEncodingFlags = savedIEFlags; + statePtr->inputEncodingState = savedState; + continue; + } + +//fprintf(stdout, "check %d %d %d\n", dstWrote, dstRead, dstDecoded); +//fflush(stdout); + + /* + * The translation transformation can only reduce the number + * of chars when it converts \r\n into \n. The reduction in + * the number of chars is the difference in bytes read and written. + */ + + numChars -= (dstRead - dstWrote); + + if (charsToRead > 0 && numChars > charsToRead) { + + /* + * We read more chars than allowed. Reset limits to + * prevent that and try again. + */ +//fprintf(stdout, "Y!\n"); fflush(stdout); + + dstLimit = Tcl_UtfAtIndex(dst, charsToRead + 1) - dst; + statePtr->flags = savedFlags; + statePtr->inputEncodingFlags = savedIEFlags; + statePtr->inputEncodingState = savedState; + continue; + } + + if (dstWrote == 0) { + +//fprintf(stdout, "Z!\n"); fflush(stdout); + /* + * Could not read anything. Ask caller to get more data. + */ + + return -1; + } + + statePtr->inputEncodingFlags &= ~TCL_ENCODING_START; + + bufPtr->nextRemoved += srcRead; + if (dstWrote > srcRead + 1) { + *factorPtr = dstWrote * UTF_EXPANSION_FACTOR / srcRead; + } + *offsetPtr += dstWrote; +//fprintf(stdout, "OK: %d\n", numChars); fflush(stdout); + return numChars; + } + +#else /* * [Bug 1462248]: The cause of the crash reported in this bug is this: * @@ -5560,6 +5674,7 @@ ReadChars( } *offsetPtr += dstWrote; return numChars; +#endif } /* @@ -5661,7 +5776,9 @@ TranslateInputEOL( if (*src == '\r') { src++; if (src >= srcMax) { - SetFlag(statePtr, INPUT_NEED_NL); +// SetFlag(statePtr, INPUT_NEED_NL); +//fprintf(stdout, "BREAK!\n"); fflush(stdout); +src--; break; } else if (*src == '\n') { *dst++ = *src++; } else { @@ -5673,6 +5790,7 @@ TranslateInputEOL( } srcLen = src - srcStart; dstLen = dst - dstStart; +//fprintf(stdout, "eh? %d %d\n", srcLen, dstLen); fflush(stdout); break; } case TCL_TRANSLATE_AUTO: { -- cgit v0.12 From ff27c27a2701787b7ad63c3de1ae7a17db72e0b9 Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 28 Feb 2014 18:25:20 +0000 Subject: More ReadChars rewriting. Test suite now passes. Note that this reform simplifies ReadChars a fair bit (at least in my eyes). Also it does away with the use of an INPUT_NEED_NL flag, using the same strategy for partial \r\n sequences as is used for incomplete multibyte chars. --- generic/tclIO.c | 194 ++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 173 insertions(+), 21 deletions(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index 20428b5..ec71991 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -5403,7 +5403,6 @@ ReadChars( * srcLen bytes, write no more than dstLimit bytes. */ -//fprintf(stdout, "Start %d %d\n", dstLimit, srcLen); fflush(stdout); int code = Tcl_ExternalToUtf(NULL, statePtr->encoding, src, srcLen, statePtr->inputEncodingFlags & (bufPtr->nextPtr ? ~0 : ~TCL_ENCODING_END), &statePtr->inputEncodingState, @@ -5416,9 +5415,6 @@ ReadChars( * Capture the number of bytes actually consumed in dstRead. */ -//fprintf(stdout, "Key NS=%d MB=%d S=%d\n", TCL_CONVERT_NOSPACE, -//TCL_CONVERT_MULTIBYTE, TCL_CONVERT_SYNTAX); fflush(stdout); -//fprintf(stdout, "Decoded %d %d\n", dstDecoded,code); fflush(stdout); dstWrote = dstRead = dstDecoded; TranslateInputEOL(statePtr, dst, dst, &dstWrote, &dstRead); @@ -5426,20 +5422,144 @@ ReadChars( /* * The encoding transformation produced bytes that the - * translation transformation did not consume. Start over - * and impose new limits so that doesn't happen again. + * translation transformation did not consume. Why did + * this happen? */ -//fprintf(stdout, "X! %d %d\n", dstRead, dstDecoded); fflush(stdout); - dstLimit = dstRead + TCL_UTF_MAX; - statePtr->flags = savedFlags; - statePtr->inputEncodingFlags = savedIEFlags; - statePtr->inputEncodingState = savedState; - continue; - } + if (statePtr->inEofChar && dst[dstRead] == statePtr->inEofChar) { + /* + * 1) There's an eof char set on the channel, and + * we saw it and stopped translating at that point. + * + * NOTE the bizarre spec of TranslateInputEOL in this case. + * Clearly the eof char had to be read in order to account + * for the stopping, but the value of dstRead does not + * include it. + * + * Also rather bizarre, our caller can only notice an + * EOF condition if we return the value -1 as the number + * of chars read. This forces us to perform a 2-call + * dance where the first call can read all the chars + * up to the eof char, and the second call is solely + * for consuming the encoded eof char then pointed at + * by src so that we can return that magic -1 value. + * This seems really wasteful, especially since + * the first decoding pass of each call is likely to + * decode many bytes beyond that eof char that's all we + * care about. + */ + + if (dstRead == 0) { + /* + * Curious choice in the eof char handling. We leave + * the eof char in the buffer. So, no need to compute + * a proper srcRead value. At this point, there + * are no chars before the eof char in the buffer. + */ + return -1; + } + + { + /* + * There are chars leading the buffer before the eof + * char. Adjust the dstLimit so we go back and read + * only those and do not encounter the eof char this + * time. + */ + + dstLimit = dstRead + TCL_UTF_MAX; + statePtr->flags = savedFlags; + statePtr->inputEncodingFlags = savedIEFlags; + statePtr->inputEncodingState = savedState; + continue; + } + } + + /* + * 2) The other way to read fewer bytes than are decoded + * is when the final byte is \r and we're in a CRLF + * translation mode so we cannot decide whether to + * record \r or \n yet. + */ + + assert(dstRead + 1 == dstDecoded); + assert(dst[dstRead] == '\r'); + assert(statePtr->inputTranslation == TCL_TRANSLATE_CRLF); + + if (dstWrote > 0) { + /* + * There are chars we can read before we hit the bare cr. + * Go back with a smaller dstLimit so we get them in the + * next pass, compute a matching srcRead, and don't end + * up back here in this call. + */ + + dstLimit = dstRead + TCL_UTF_MAX; + statePtr->flags = savedFlags; + statePtr->inputEncodingFlags = savedIEFlags; + statePtr->inputEncodingState = savedState; + continue; + } + + assert(dstWrote == 0); + assert(dstRead == 0); + assert(dstDecoded == 1); + + /* + * We decoded only the bare cr, and we cannot read a + * translated char from that alone. We have to know what's + * next. So why do we only have the one decoded char? + */ + + if (code != TCL_OK) { + char buffer[TCL_UTF_MAX + 2]; + int read, decoded, count; + + /* + * Didn't get everything the buffer could offer + */ + + statePtr->flags = savedFlags; + statePtr->inputEncodingFlags = savedIEFlags; + statePtr->inputEncodingState = savedState; + + Tcl_ExternalToUtf(NULL, statePtr->encoding, src, srcLen, + statePtr->inputEncodingFlags & (bufPtr->nextPtr + ? ~0 : ~TCL_ENCODING_END), &statePtr->inputEncodingState, + buffer, TCL_UTF_MAX + 2, &read, &decoded, &count); + + if (count == 2) { + if (buffer[1] == '\n') { + /* \r\n translate to \n */ + dst[0] = '\n'; + bufPtr->nextRemoved += read; + } else { + dst[0] = '\r'; + bufPtr->nextRemoved += srcRead; + } + + dst[1] = '\0'; + statePtr->inputEncodingFlags &= ~TCL_ENCODING_START; + + *offsetPtr += 1; + return 1; + } -//fprintf(stdout, "check %d %d %d\n", dstWrote, dstRead, dstDecoded); -//fflush(stdout); + } else if (statePtr->flags & CHANNEL_EOF) { + + /* + * The bare \r is the only char and we will never read + * a subsequent char to make the determination. + */ + + dst[0] = '\r'; + bufPtr->nextRemoved = bufPtr->nextAdded; + *offsetPtr += 1; + return 1; + } + + /* FALL THROUGH - get more data (dstWrote == 0) */ + } /* * The translation transformation can only reduce the number @@ -5455,7 +5575,6 @@ ReadChars( * We read more chars than allowed. Reset limits to * prevent that and try again. */ -//fprintf(stdout, "Y!\n"); fflush(stdout); dstLimit = Tcl_UtfAtIndex(dst, charsToRead + 1) - dst; statePtr->flags = savedFlags; @@ -5466,12 +5585,46 @@ ReadChars( if (dstWrote == 0) { -//fprintf(stdout, "Z!\n"); fflush(stdout); - /* - * Could not read anything. Ask caller to get more data. + /* + * We were not able to read any chars. Maybe there were + * not enough src bytes to decode into a char. Maybe + * a lone \r could not be translated (crlf mode). Need + * to combine any unused src bytes we have in the first + * buffer with subsequent bytes to try again. */ - return -1; + ChannelBuffer *nextPtr = bufPtr->nextPtr; + + if (nextPtr == NULL) { + if (srcLen > 0) { + SetFlag(statePtr, CHANNEL_NEED_MORE_DATA); + } + return -1; + } + + /* + * Space is made at the beginning of the buffer to copy the + * previous unused bytes there. Check first if the buffer we + * are using actually has enough space at its beginning for + * the data we are copying. Because if not we will write over + * the buffer management information, especially the 'nextPtr'. + * + * Note that the BUFFER_PADDING (See AllocChannelBuffer) is + * used to prevent exactly this situation. I.e. it should never + * happen. Therefore it is ok to panic should it happen despite + * the precautions. + */ + + if (nextPtr->nextRemoved - srcLen < 0) { + Tcl_Panic("Buffer Underflow, BUFFER_PADDING not enough"); + } + + nextPtr->nextRemoved -= srcLen; + memcpy(RemovePoint(nextPtr), src, (size_t) srcLen); + RecycleBuffer(statePtr, bufPtr, 0); + statePtr->inQueueHead = nextPtr; + return ReadChars(statePtr, objPtr, charsToRead, + offsetPtr, factorPtr); } statePtr->inputEncodingFlags &= ~TCL_ENCODING_START; @@ -5481,7 +5634,6 @@ ReadChars( *factorPtr = dstWrote * UTF_EXPANSION_FACTOR / srcRead; } *offsetPtr += dstWrote; -//fprintf(stdout, "OK: %d\n", numChars); fflush(stdout); return numChars; } -- cgit v0.12 From 45f1f6013203e367c80e943b8dae0d2c77052384 Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 28 Feb 2014 18:28:16 +0000 Subject: tidy up. --- generic/tclIO.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index ec71991..a0a349f 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -5928,9 +5928,8 @@ TranslateInputEOL( if (*src == '\r') { src++; if (src >= srcMax) { -// SetFlag(statePtr, INPUT_NEED_NL); -//fprintf(stdout, "BREAK!\n"); fflush(stdout); -src--; break; + src--; + break; } else if (*src == '\n') { *dst++ = *src++; } else { @@ -5942,7 +5941,6 @@ src--; break; } srcLen = src - srcStart; dstLen = dst - dstStart; -//fprintf(stdout, "eh? %d %d\n", srcLen, dstLen); fflush(stdout); break; } case TCL_TRANSLATE_AUTO: { -- cgit v0.12 From c98d05520706416ea910435025efdce7d0ab8406 Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 28 Feb 2014 18:36:00 +0000 Subject: another coverage test. --- tests/io.test | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/tests/io.test b/tests/io.test index 0941e02..c325809 100644 --- a/tests/io.test +++ b/tests/io.test @@ -4772,6 +4772,21 @@ test io-35.19 {Tcl_Eof, eof char in middle, cr write, crlf read} { close $f list $c $l $e [scan [string index $in end] %c] } {17 8 1 13} +test io-35.20 {Tcl_Eof, eof char in middle, cr write, crlf read} { + file delete $path(test1) + set f [open $path(test1) w] + fconfigure $f -translation cr -eofchar {} + set i [format \n%cqrsuvw 26] + puts $f $i + close $f + set c [file size $path(test1)] + set f [open $path(test1) r] + fconfigure $f -translation crlf -eofchar \x1a + set l [string length [set in [read $f]]] + set e [eof $f] + close $f + list $c $l $e [scan [string index $in end] %c] +} {9 1 1 13} # Test Tcl_InputBlocked -- cgit v0.12 From ecec9dacef9a203febd8693525f25bf62523515a Mon Sep 17 00:00:00 2001 From: dgp Date: Sat, 1 Mar 2014 03:01:41 +0000 Subject: Fixups make the test suite almost pass (except *io-39.17) --- generic/tclIO.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index 7b798af..139a05e 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -5289,7 +5289,7 @@ ReadChars( dst = TclGetString(objPtr) + numBytes; } -#if 0 +#if 1 /* * This routine is burdened with satisfying several constraints. @@ -5373,6 +5373,7 @@ ReadChars( * a proper srcRead value. At this point, there * are no chars before the eof char in the buffer. */ + Tcl_SetObjLength(objPtr, numBytes); return -1; } @@ -5459,7 +5460,6 @@ ReadChars( statePtr->inputEncodingFlags &= ~TCL_ENCODING_START; Tcl_SetObjLength(objPtr, numBytes + 1); - // *offsetPtr += 1; return 1; } @@ -5473,7 +5473,6 @@ ReadChars( dst[0] = '\r'; bufPtr->nextRemoved = bufPtr->nextAdded; Tcl_SetObjLength(objPtr, numBytes + 1); - //*offsetPtr += 1; return 1; } @@ -5518,6 +5517,7 @@ ReadChars( if (srcLen > 0) { SetFlag(statePtr, CHANNEL_NEED_MORE_DATA); } + Tcl_SetObjLength(objPtr, numBytes); return -1; } @@ -5542,6 +5542,7 @@ ReadChars( memcpy(RemovePoint(nextPtr), src, (size_t) srcLen); RecycleBuffer(statePtr, bufPtr, 0); statePtr->inQueueHead = nextPtr; + Tcl_SetObjLength(objPtr, numBytes); return ReadChars(statePtr, objPtr, charsToRead, factorPtr); } @@ -5552,7 +5553,6 @@ ReadChars( *factorPtr = dstWrote * UTF_EXPANSION_FACTOR / srcRead; } Tcl_SetObjLength(objPtr, numBytes + dstWrote); - //*offsetPtr += dstWrote; return numChars; } @@ -5850,9 +5850,8 @@ TranslateInputEOL( if (*src == '\r') { src++; if (src >= srcMax) { -SetFlag(statePtr, INPUT_NEED_NL); -// src--; -// break; + src--; + break; } else if (*src == '\n') { *dst++ = *src++; } else { -- cgit v0.12 From e5f7fb59c4950943ebf8c8b5c7ce5996a03fe40d Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 5 Mar 2014 14:23:38 +0000 Subject: Merge repair to correct failing tests. --- generic/tclIO.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index 139a05e..6e3f0cf 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -5320,7 +5320,7 @@ ReadChars( * srcLen bytes, write no more than dstLimit bytes. */ - int code = Tcl_ExternalToUtf(NULL, statePtr->encoding, src, srcLen, + int code = Tcl_ExternalToUtf(NULL, encoding, src, srcLen, statePtr->inputEncodingFlags & (bufPtr->nextPtr ? ~0 : ~TCL_ENCODING_END), &statePtr->inputEncodingState, dst, dstLimit, &srcRead, &dstDecoded, &numChars); @@ -5441,7 +5441,7 @@ ReadChars( statePtr->inputEncodingFlags = savedIEFlags; statePtr->inputEncodingState = savedState; - Tcl_ExternalToUtf(NULL, statePtr->encoding, src, srcLen, + Tcl_ExternalToUtf(NULL, encoding, src, srcLen, statePtr->inputEncodingFlags & (bufPtr->nextPtr ? ~0 : ~TCL_ENCODING_END), &statePtr->inputEncodingState, buffer, TCL_UTF_MAX + 2, &read, &decoded, &count); -- cgit v0.12 From 5fe3c1fbee83514f449dc78f927d0587b24d071b Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 5 Mar 2014 17:16:35 +0000 Subject: Adapt CopyAndTranslateBuffer() to changes in TranslateInputEOL(). Notably no longer using the INPUT_NEED_NL flag. --- generic/tclIO.c | 117 +++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 77 insertions(+), 40 deletions(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index 6e3f0cf..013f8dd 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -5914,7 +5914,7 @@ TranslateInputEOL( SetFlag(statePtr, CHANNEL_EOF | CHANNEL_STICKY_EOF); statePtr->inputEncodingFlags |= TCL_ENCODING_END; - ResetFlag(statePtr, INPUT_SAW_CR | INPUT_NEED_NL); + ResetFlag(statePtr, INPUT_SAW_CR); return 1; } @@ -9046,7 +9046,6 @@ CopyAndTranslateBuffer( * in the current input buffer? */ int copied; /* How many characters were already copied * into the destination space? */ - int toCopy; /* * If there is no input at all, return zero. The invariant is that either @@ -9061,51 +9060,90 @@ CopyAndTranslateBuffer( bufPtr = statePtr->inQueueHead; bytesInBuffer = BytesLeft(bufPtr); - copied = 0; -#if 0 - if (statePtr->flags & INPUT_NEED_NL) { +#if 1 + copied = space; + if (bytesInBuffer <= copied) { + copied = bytesInBuffer; + } + if (copied == 0) { + return copied; + } + TranslateInputEOL(statePtr, result, RemovePoint(bufPtr), + &copied, &bytesInBuffer); + bufPtr->nextRemoved += bytesInBuffer; - /* - * An earlier call to TranslateInputEOL ended in the read of a \r . - * Only the next read from the same channel can complete the - * translation sequence to tell us what character we should read. - */ + /* + * If the current buffer is empty recycle it. + */ + + if (IsBufferEmpty(bufPtr)) { + statePtr->inQueueHead = bufPtr->nextPtr; + if (statePtr->inQueueHead == NULL) { + statePtr->inQueueTail = NULL; + } + RecycleBuffer(statePtr, bufPtr, 0); + } else { + + if (copied > 0) { + return copied; + } - if (bytesInBuffer) { - /* There's a next byte. It will settle things. */ - ResetFlag(statePtr, INPUT_NEED_NL); + if (statePtr->inEofChar + && RemovePoint(bufPtr)[0] == statePtr->inEofChar) { + return 0; + } - if (RemovePoint(bufPtr)[0] == '\n') { - bufPtr->nextRemoved++; - bytesInBuffer--; - *result++ = '\n'; - } else { - *result++ = '\r'; + if (BytesLeft(bufPtr) == 1) { + + ChannelBuffer *nextPtr = bufPtr->nextPtr; + + if (nextPtr == NULL) { + + if (statePtr->flags & CHANNEL_EOF) { + *result = '\r'; + bufPtr->nextRemoved += 1; + return 1; + } + + SetFlag(statePtr, CHANNEL_NEED_MORE_DATA); + return 0; } - copied++; - space--; - } else if (statePtr->flags & CHANNEL_EOF) { - /* There is no next byte, and there never will be (EOF). */ - ResetFlag(statePtr, INPUT_NEED_NL); + + nextPtr->nextRemoved -= 1; + memcpy(RemovePoint(nextPtr), RemovePoint(bufPtr), 1); + RecycleBuffer(statePtr, bufPtr, 0); + statePtr->inQueueHead = nextPtr; + return 0; + } + + if (statePtr->inEofChar + && RemovePoint(bufPtr)[1] == statePtr->inEofChar) { *result = '\r'; + bufPtr->nextRemoved += 1; return 1; - } else { - /* There is no next byte. Ask the caller to read more. */ - return 0; } + /* + * Buffer is not empty. How can that be? + * 0) We stopped early due to the value of "space". + * => copied > 0 and all is fine. + * 1) We saw eof char and stopped the translation copy. + * => if (copied > 0) or ((copied == 0) and @ eof char), + * return is fine. + * 2) The buffer holds a \r while in CRLF translation, followed + * by either the end of the buffer, or the eof char. + */ + } - toCopy = space; - if (bytesInBuffer <= toCopy) { - toCopy = bytesInBuffer; - } - if (toCopy == 0) { - return copied; - } - TranslateInputEOL(statePtr, result, RemovePoint(bufPtr), - &toCopy, &bytesInBuffer); - bufPtr->nextRemoved += bytesInBuffer; - copied += toCopy; + + /* + * Return the number of characters copied into the result buffer. This may + * be different from the number of bytes consumed, because of EOL + * translations. + */ + + return copied; #else + copied = 0; switch (statePtr->inputTranslation) { case TCL_TRANSLATE_LF: if (bytesInBuffer == 0) { @@ -9265,7 +9303,6 @@ CopyAndTranslateBuffer( } } } -#endif /* * If the current buffer is empty recycle it. @@ -9286,6 +9323,7 @@ CopyAndTranslateBuffer( */ return copied; +#endif } /* @@ -10726,7 +10764,6 @@ DumpFlags( ChanFlag('S', CHANNEL_STICKY_EOF); ChanFlag('B', CHANNEL_BLOCKED); ChanFlag('/', INPUT_SAW_CR); - ChanFlag('*', INPUT_NEED_NL); ChanFlag('D', CHANNEL_DEAD); ChanFlag('R', CHANNEL_RAW_MODE); #ifdef TCL_IO_TRACK_OS_FOR_DRIVER_WITH_BAD_BLOCKING -- cgit v0.12 From 57182d5ef37bc41f0eac64880ef3c5ceb4cf7b61 Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 5 Mar 2014 19:41:51 +0000 Subject: Remove old dead code; silence compiler warnings; tidy up. --- generic/tclIO.c | 415 ++------------------------------------------------------ generic/tclIO.h | 3 - 2 files changed, 12 insertions(+), 406 deletions(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index 013f8dd..821d111 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -5252,33 +5252,25 @@ ReadChars( * UTF-8. On output, contains another guess * based on the data seen so far. */ { - int toRead, factor, srcLen, dstNeeded, numBytes; - int srcRead, dstWrote, numChars, dstRead; - ChannelBuffer *bufPtr; - char *src, *dst; - Tcl_EncodingState oldState; - int encEndFlagSuppressed = 0; Tcl_Encoding encoding = statePtr->encoding? statePtr->encoding : GetBinaryEncoding(); - - factor = *factorPtr; - - bufPtr = statePtr->inQueueHead; - src = RemovePoint(bufPtr); - srcLen = BytesLeft(bufPtr); - - toRead = charsToRead; - if ((unsigned)toRead > (unsigned)srcLen) { - toRead = srcLen; - } + Tcl_EncodingState savedState = statePtr->inputEncodingState; + ChannelBuffer *bufPtr = statePtr->inQueueHead; + int savedIEFlags = statePtr->inputEncodingFlags; + int savedFlags = statePtr->flags; + char *dst, *src = RemovePoint(bufPtr); + int dstLimit, numBytes, srcLen = BytesLeft(bufPtr); + int toRead = ((unsigned) charsToRead > srcLen) ? srcLen : charsToRead; /* * 'factor' is how much we guess that the bytes in the source buffer will * expand when converted to UTF-8 chars. This guess comes from analyzing * how many characters were produced by the previous pass. */ + + int factor = *factorPtr; + int dstNeeded = TCL_UTF_MAX - 1 + toRead * factor / UTF_EXPANSION_FACTOR; - dstNeeded = TCL_UTF_MAX - 1 + toRead * factor / UTF_EXPANSION_FACTOR; (void) TclGetStringFromObj(objPtr, &numBytes); Tcl_AppendToObj(objPtr, NULL, dstNeeded); if (toRead == srcLen) { @@ -5289,8 +5281,6 @@ ReadChars( dst = TclGetString(objPtr) + numBytes; } -#if 1 - /* * This routine is burdened with satisfying several constraints. * It cannot append more than 'charsToRead` chars onto objPtr. @@ -5307,13 +5297,9 @@ ReadChars( * a consistent set of results. This takes the shape of a loop. */ - int dstLimit = dstNeeded + 1; - int savedFlags = statePtr->flags; - int savedIEFlags = statePtr->inputEncodingFlags; - Tcl_EncodingState savedState = statePtr->inputEncodingState; - + dstLimit = dstNeeded + 1; while (1) { - int dstDecoded; + int dstDecoded, dstRead, dstWrote, srcRead, numChars; /* * Perform the encoding transformation. Read no more than @@ -5555,200 +5541,6 @@ ReadChars( Tcl_SetObjLength(objPtr, numBytes + dstWrote); return numChars; } - -#else - /* - * [Bug 1462248]: The cause of the crash reported in this bug is this: - * - * - ReadChars, called with a single buffer, with a incomplete - * multi-byte character at the end (only the first byte of it). - * - Encoding translation fails, asks for more data - * - Data is read, and eof is reached, TCL_ENCODING_END (TEE) is set. - * - ReadChar is called again, converts the first buffer, but due to TEE - * it does not check for incomplete multi-byte data, and the character - * just after the end of the first buffer is a valid completion of the - * multi-byte header in the actual buffer. The conversion reads more - * characters from the buffer then present. This causes nextRemoved to - * overshoot nextAdded and the next reads compute a negative srcLen, - * cause further translations to fail, causing copying of data into the - * next buffer using bad arguments, causing the mecpy for to eventually - * fail. - * - * In the end it is a memory access bug spiraling out of control if the - * conditions are _just so_. And ultimate cause is that TEE is given to a - * conversion where it should not. TEE signals that this is the last - * buffer. Except in our case it is not. - * - * My solution is to suppress TEE if the first buffer is not the last. We - * will eventually need it given that EOF has been reached, but not right - * now. This is what the new flag "endEncSuppressFlag" is for. - * - * The bug in 'Tcl_Utf2UtfProc' where it read from memory behind the - * actual buffer has been fixed as well, and fixes the problem with the - * crash too, but this would still allow the generic layer to - * accidentially break a multi-byte sequence if the conditions are just - * right, because again the ExternalToUtf would be successful where it - * should not. - */ - - if ((statePtr->inputEncodingFlags & TCL_ENCODING_END) && - (bufPtr->nextPtr != NULL)) { - /* - * TEE is set for a buffer which is not the last. Squash it for now, - * and restore it later, before yielding control to our caller. - */ - - statePtr->inputEncodingFlags &= ~TCL_ENCODING_END; - encEndFlagSuppressed = 1; - } - - oldState = statePtr->inputEncodingState; - if (statePtr->flags & INPUT_NEED_NL) { - /* - * We want a '\n' because the last character we saw was '\r'. - */ - - ResetFlag(statePtr, INPUT_NEED_NL); - Tcl_ExternalToUtf(NULL, encoding, src, srcLen, - statePtr->inputEncodingFlags, &statePtr->inputEncodingState, - dst, TCL_UTF_MAX + 1, &srcRead, &dstWrote, &numChars); - if ((dstWrote > 0) && (*dst == '\n')) { - /* - * The next char was a '\n'. Consume it and produce a '\n'. - */ - - bufPtr->nextRemoved += srcRead; - } else { - /* - * The next char was not a '\n'. Produce a '\r'. - */ - - *dst = '\r'; - } - statePtr->inputEncodingFlags &= ~TCL_ENCODING_START; - Tcl_SetObjLength(objPtr, numBytes + 1); - - if (encEndFlagSuppressed) { - statePtr->inputEncodingFlags |= TCL_ENCODING_END; - } - return 1; - } - - Tcl_ExternalToUtf(NULL, encoding, src, srcLen, - statePtr->inputEncodingFlags, &statePtr->inputEncodingState, dst, - dstNeeded + 1, &srcRead, &dstWrote, &numChars); - - if (encEndFlagSuppressed) { - statePtr->inputEncodingFlags |= TCL_ENCODING_END; - } - - if (srcRead == 0) { - /* - * Not enough bytes in src buffer to make a complete char. Copy the - * bytes to the next buffer to make a new contiguous string, then tell - * the caller to fill the buffer with more bytes. - */ - - ChannelBuffer *nextPtr; - - nextPtr = bufPtr->nextPtr; - if (nextPtr == NULL) { - if (srcLen > 0) { - /* - * There isn't enough data in the buffers to complete the next - * character, so we need to wait for more data before the next - * file event can be delivered. [Bug 478856] - * - * The exception to this is if the input buffer was completely - * empty before we tried to convert its contents. Nothing in, - * nothing out, and no incomplete character data. The - * conversion before the current one was complete. - */ - - SetFlag(statePtr, CHANNEL_NEED_MORE_DATA); - } - Tcl_SetObjLength(objPtr, numBytes); - return -1; - } - - /* - * Space is made at the beginning of the buffer to copy the previous - * unused bytes there. Check first if the buffer we are using actually - * has enough space at its beginning for the data we are copying. - * Because if not we will write over the buffer management - * information, especially the 'nextPtr'. - * - * Note that the BUFFER_PADDING (See AllocChannelBuffer) is used to - * prevent exactly this situation. I.e. it should never happen. - * Therefore it is ok to panic should it happen despite the - * precautions. - */ - - if (nextPtr->nextRemoved - srcLen < 0) { - Tcl_Panic("Buffer Underflow, BUFFER_PADDING not enough"); - } - - nextPtr->nextRemoved -= srcLen; - memcpy(RemovePoint(nextPtr), src, (size_t) srcLen); - RecycleBuffer(statePtr, bufPtr, 0); - statePtr->inQueueHead = nextPtr; - Tcl_SetObjLength(objPtr, numBytes); - return ReadChars(statePtr, objPtr, charsToRead, factorPtr); - } - - dstRead = dstWrote; - if (TranslateInputEOL(statePtr, dst, dst, &dstWrote, &dstRead) != 0) { - /* - * Hit EOF char. How many bytes of src correspond to where the EOF was - * located in dst? Run the conversion again with an output buffer just - * big enough to hold the data so we can get the correct value for - * srcRead. - */ - - if (dstWrote == 0) { - Tcl_SetObjLength(objPtr, numBytes); - return -1; - } - statePtr->inputEncodingState = oldState; - Tcl_ExternalToUtf(NULL, encoding, src, srcLen, - statePtr->inputEncodingFlags, &statePtr->inputEncodingState, - dst, dstRead + TCL_UTF_MAX, &srcRead, &dstWrote, &numChars); - TranslateInputEOL(statePtr, dst, dst, &dstWrote, &dstRead); - } - - /* - * The number of characters that we got may be less than the number that - * we started with because "\r\n" sequences may have been turned into just - * '\n' in dst. - */ - - numChars -= (dstRead - dstWrote); - - if ((unsigned) numChars > (unsigned) toRead) { - /* - * Got too many chars. - */ - - const char *eof; - - eof = Tcl_UtfAtIndex(dst, toRead); - statePtr->inputEncodingState = oldState; - Tcl_ExternalToUtf(NULL, encoding, src, srcLen, - statePtr->inputEncodingFlags, &statePtr->inputEncodingState, - dst, eof - dst + TCL_UTF_MAX, &srcRead, &dstWrote, &numChars); - dstRead = dstWrote; - TranslateInputEOL(statePtr, dst, dst, &dstWrote, &dstRead); - numChars -= (dstRead - dstWrote); - } - statePtr->inputEncodingFlags &= ~TCL_ENCODING_START; - - bufPtr->nextRemoved += srcRead; - if (dstWrote > srcRead + 1) { - *factorPtr = dstWrote * UTF_EXPANSION_FACTOR / srcRead; - } - Tcl_SetObjLength(objPtr, numBytes + dstWrote); - return numChars; -#endif } /* @@ -9060,7 +8852,6 @@ CopyAndTranslateBuffer( bufPtr = statePtr->inQueueHead; bytesInBuffer = BytesLeft(bufPtr); -#if 1 copied = space; if (bytesInBuffer <= copied) { copied = bytesInBuffer; @@ -9142,188 +8933,6 @@ CopyAndTranslateBuffer( */ return copied; -#else - copied = 0; - switch (statePtr->inputTranslation) { - case TCL_TRANSLATE_LF: - if (bytesInBuffer == 0) { - return 0; - } - - /* - * Copy the current chunk into the result buffer. - */ - - if (bytesInBuffer < space) { - space = bytesInBuffer; - } - memcpy(result, RemovePoint(bufPtr), (size_t) space); - bufPtr->nextRemoved += space; - copied = space; - break; - case TCL_TRANSLATE_CR: { - char *end; - - if (bytesInBuffer == 0) { - return 0; - } - - /* - * Copy the current chunk into the result buffer, then replace all \r - * with \n. - */ - - if (bytesInBuffer < space) { - space = bytesInBuffer; - } - memcpy(result, RemovePoint(bufPtr), (size_t) space); - bufPtr->nextRemoved += space; - copied = space; - - for (end = result + copied; result < end; result++) { - if (*result == '\r') { - *result = '\n'; - } - } - break; - } - case TCL_TRANSLATE_CRLF: { - char *src, *end, *dst; - int curByte; - - /* - * If there is a held-back "\r" at EOF, produce it now. - */ - - if (bytesInBuffer == 0) { - if ((statePtr->flags & (INPUT_SAW_CR | CHANNEL_EOF)) == - (INPUT_SAW_CR | CHANNEL_EOF)) { - result[0] = '\r'; - ResetFlag(statePtr, INPUT_SAW_CR); - return 1; - } - return 0; - } - - /* - * Copy the current chunk and replace "\r\n" with "\n" (but not - * standalone "\r"!). - */ - - if (bytesInBuffer < space) { - space = bytesInBuffer; - } - memcpy(result, RemovePoint(bufPtr), (size_t) space); - bufPtr->nextRemoved += space; - copied = space; - - end = result + copied; - dst = result; - for (src = result; src < end; src++) { - curByte = *src; - if (curByte == '\n') { - ResetFlag(statePtr, INPUT_SAW_CR); - } else if (statePtr->flags & INPUT_SAW_CR) { - ResetFlag(statePtr, INPUT_SAW_CR); - *dst = '\r'; - dst++; - } - if (curByte == '\r') { - SetFlag(statePtr, INPUT_SAW_CR); - } else { - *dst = (char) curByte; - dst++; - } - } - copied = dst - result; - break; - } - case TCL_TRANSLATE_AUTO: { - char *src, *end, *dst; - int curByte; - - if (bytesInBuffer == 0) { - return 0; - } - - /* - * Loop over the current buffer, converting "\r" and "\r\n" to "\n". - */ - - if (bytesInBuffer < space) { - space = bytesInBuffer; - } - memcpy(result, RemovePoint(bufPtr), (size_t) space); - bufPtr->nextRemoved += space; - copied = space; - - end = result + copied; - dst = result; - for (src = result; src < end; src++) { - curByte = *src; - if (curByte == '\r') { - SetFlag(statePtr, INPUT_SAW_CR); - *dst = '\n'; - dst++; - } else { - if ((curByte != '\n') || !(statePtr->flags & INPUT_SAW_CR)) { - *dst = (char) curByte; - dst++; - } - ResetFlag(statePtr, INPUT_SAW_CR); - } - } - copied = dst - result; - break; - } - default: - Tcl_Panic("unknown eol translation mode"); - } - - /* - * If an in-stream EOF character is set for this channel, check that the - * input we copied so far does not contain the EOF char. If it does, copy - * only up to and excluding that character. - */ - - if (statePtr->inEofChar != 0) { - int i; - - for (i = 0; i < copied; i++) { - if (result[i] == (char) statePtr->inEofChar) { - /* - * Set sticky EOF so that no further input is presented to the - * caller. - */ - - SetFlag(statePtr, CHANNEL_EOF | CHANNEL_STICKY_EOF); - statePtr->inputEncodingFlags |= TCL_ENCODING_END; - copied = i; - break; - } - } - } - - /* - * If the current buffer is empty recycle it. - */ - - if (IsBufferEmpty(bufPtr)) { - statePtr->inQueueHead = bufPtr->nextPtr; - if (statePtr->inQueueHead == NULL) { - statePtr->inQueueTail = NULL; - } - RecycleBuffer(statePtr, bufPtr, 0); - } - - /* - * Return the number of characters copied into the result buffer. This may - * be different from the number of bytes consumed, because of EOL - * translations. - */ - - return copied; -#endif } /* diff --git a/generic/tclIO.h b/generic/tclIO.h index ebf2ef7..a57d4c5 100644 --- a/generic/tclIO.h +++ b/generic/tclIO.h @@ -252,9 +252,6 @@ typedef struct ChannelState { #define INPUT_SAW_CR (1<<12) /* Channel is in CRLF eol input * translation mode and the last byte * seen was a "\r". */ -#define INPUT_NEED_NL (1<<15) /* Saw a '\r' at end of last buffer, - * and there should be a '\n' at - * beginning of next buffer. */ #define CHANNEL_DEAD (1<<13) /* The channel has been closed by the * exit handler (on exit) but not * deallocated. When any IO operation -- cgit v0.12 From f3343892a7a54503396fdc2b9eb222a92c1c4ade Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 6 Mar 2014 15:51:06 +0000 Subject: Variable "rawStart" serves no purpose. --- generic/tclIO.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index 821d111..b0d0e32 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -4464,7 +4464,7 @@ FilterInputBytes( ChannelState *statePtr = chanPtr->state; /* State info for channel */ ChannelBuffer *bufPtr; - char *raw, *rawStart, *dst; + char *raw, *dst; int offset, toRead, dstNeeded, spaceLeft, result, rawLen; Tcl_Obj *objPtr; #define ENCODING_LINESIZE 20 /* Lower bound on how many bytes to convert at @@ -4521,8 +4521,7 @@ FilterInputBytes( * string rep if we need more space. */ - rawStart = RemovePoint(bufPtr); - raw = rawStart; + raw = RemovePoint(bufPtr); rawLen = BytesLeft(bufPtr); dst = *gsPtr->dstPtr; -- cgit v0.12 From 5350ed1efee8da26d454e9cf6e0ba69d9fd64949 Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 7 Mar 2014 19:43:16 +0000 Subject: Simplify the input eof char scan. Update some comments. --- generic/tclIO.c | 64 +++++++++++++++++++++++++++++---------------------------- 1 file changed, 33 insertions(+), 31 deletions(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index b0d0e32..03aac32 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -5244,7 +5244,11 @@ ReadChars( * is larger than the number of characters * available in the first buffer, only the * characters from the first buffer are - * returned. */ + * returned. The execption is when there is + * not any complete character in the first + * buffer. In that case, a recursive call + * effectively obtains chars from the + * second buffer. */ int *factorPtr) /* On input, contains a guess of how many * bytes need to be allocated to hold the * result of converting N source bytes to @@ -5259,6 +5263,15 @@ ReadChars( int savedFlags = statePtr->flags; char *dst, *src = RemovePoint(bufPtr); int dstLimit, numBytes, srcLen = BytesLeft(bufPtr); + + /* + * One src byte can yield at most one character. So when the + * number of src bytes we plan to read is less than the limit on + * character count to be read, clearly we will remain within that + * limit, and we can use the value of "srcLen" as a tighter limit + * for sizing receiving buffers. + */ + int toRead = ((unsigned) charsToRead > srcLen) ? srcLen : charsToRead; /* @@ -5569,43 +5582,32 @@ TranslateInputEOL( * characters. */ const char *srcStart, /* Source characters. */ int *dstLenPtr, /* On entry, the maximum length of output - * buffer in bytes; must be <= *srcLenPtr. On - * exit, the number of bytes actually used in - * output buffer. */ + * buffer in bytes. On exit, the number of + * bytes actually used in output buffer. */ int *srcLenPtr) /* On entry, the length of source buffer. On * exit, the number of bytes read from the * source buffer. */ { - int dstLen, srcLen, inEofChar; - const char *eof; + const char *eof = NULL; + int dstLen = *dstLenPtr; + int srcLen = *srcLenPtr; + int inEofChar = statePtr->inEofChar; - dstLen = *dstLenPtr; - - eof = NULL; - inEofChar = statePtr->inEofChar; if (inEofChar != '\0') { /* - * Find EOF in translated buffer then compress out the EOL. The source - * buffer may be much longer than the destination buffer - we only - * want to return EOF if the EOF has been copied to the destination - * buffer. + * Make sure we do not read past any logical end of channel input + * created by the presence of the input eof char. */ - const char *src, *srcMax; - - srcMax = srcStart + *srcLenPtr; - for (src = srcStart; src < srcMax; src++) { - if (*src == inEofChar) { - eof = src; - srcLen = src - srcStart; - if (srcLen < dstLen) { - dstLen = srcLen; - } - *srcLenPtr = srcLen; - break; - } + if ((eof = memchr(srcStart, inEofChar, srcLen))) { + srcLen = eof - srcStart; } } + + if (dstLen > srcLen) { + dstLen = srcLen; + } + switch (statePtr->inputTranslation) { case TCL_TRANSLATE_LF: if (dstStart != srcStart) { @@ -5635,7 +5637,7 @@ TranslateInputEOL( dst = dstStart; src = srcStart; srcEnd = srcStart + dstLen; - srcMax = srcStart + *srcLenPtr; + srcMax = srcStart + srcLen; for ( ; src < srcEnd; ) { if (*src == '\r') { @@ -5663,7 +5665,7 @@ TranslateInputEOL( dst = dstStart; src = srcStart; srcEnd = srcStart + dstLen; - srcMax = srcStart + *srcLenPtr; + srcMax = srcStart + srcLen; if ((statePtr->flags & INPUT_SAW_CR) && (src < srcMax)) { if (*src == '\n') { @@ -5692,9 +5694,10 @@ TranslateInputEOL( break; } default: - return 0; + Tcl_Panic("unknown input translation %d", statePtr->inputTranslation); } *dstLenPtr = dstLen; + *srcLenPtr = srcLen; if ((eof != NULL) && (srcStart + srcLen >= eof)) { /* @@ -5709,7 +5712,6 @@ TranslateInputEOL( return 1; } - *srcLenPtr = srcLen; return 0; } -- cgit v0.12 From 61e8875498ce5699cb344bd2580656b7015ca3ed Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 7 Mar 2014 20:15:12 +0000 Subject: TranslateInputEOL() callers no longer need assert dstLen <= srcLen. --- generic/tclIO.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index 03aac32..d23ca03 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -5330,7 +5330,8 @@ ReadChars( * Capture the number of bytes actually consumed in dstRead. */ - dstWrote = dstRead = dstDecoded; + dstWrote = dstLimit; + dstRead = dstDecoded; TranslateInputEOL(statePtr, dst, dst, &dstWrote, &dstRead); if (dstRead < dstDecoded) { @@ -8852,14 +8853,11 @@ CopyAndTranslateBuffer( } bufPtr = statePtr->inQueueHead; bytesInBuffer = BytesLeft(bufPtr); + if (bytesInBuffer == 0) { + return 0; + } copied = space; - if (bytesInBuffer <= copied) { - copied = bytesInBuffer; - } - if (copied == 0) { - return copied; - } TranslateInputEOL(statePtr, result, RemovePoint(bufPtr), &copied, &bytesInBuffer); bufPtr->nextRemoved += bytesInBuffer; -- cgit v0.12 From 12a4d297b91592de98a14aa47fa8dd6e394765ef Mon Sep 17 00:00:00 2001 From: dgp Date: Mon, 10 Mar 2014 03:09:03 +0000 Subject: TranslateInputEOL doesn't need to return anything. No caller cares. Other optimizations and simplifications. --- generic/tclIO.c | 79 +++++++++++++++++++++++++++++++-------------------------- 1 file changed, 43 insertions(+), 36 deletions(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index d23ca03..6dfdd03 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -214,7 +214,7 @@ static int StackSetBlockMode(Channel *chanPtr, int mode); static int SetBlockMode(Tcl_Interp *interp, Channel *chanPtr, int mode); static void StopCopy(CopyState *csPtr); -static int TranslateInputEOL(ChannelState *statePtr, char *dst, +static void TranslateInputEOL(ChannelState *statePtr, char *dst, const char *src, int *dstLenPtr, int *srcLenPtr); static void UpdateInterest(Channel *chanPtr); static int Write(Channel *chanPtr, const char *src, @@ -5574,7 +5574,7 @@ ReadChars( *--------------------------------------------------------------------------- */ -static int +static void TranslateInputEOL( ChannelState *statePtr, /* Channel being read, for EOL translation and * EOF character. */ @@ -5594,6 +5594,29 @@ TranslateInputEOL( int srcLen = *srcLenPtr; int inEofChar = statePtr->inEofChar; + /* + * Depending on the translation mode in use, there's no need + * to scan more srcLen bytes at srcStart than can possibly transform + * to dstLen bytes. This keeps the scan for eof char below from + * being pointlessly long. + */ + + switch (statePtr->inputTranslation) { + case TCL_TRANSLATE_LF: + case TCL_TRANSLATE_CR: + if (srcLen > dstLen) { + /* In these modes, each src byte become a dst byte. */ + srcLen = dstLen; + } + break; + default: + /* In other modes, at most 2 src bytes become a dst byte. */ + if (srcLen > 2 * dstLen) { + srcLen = 2 * dstLen; + } + break; + } + if (inEofChar != '\0') { /* * Make sure we do not read past any logical end of channel input @@ -5605,36 +5628,29 @@ TranslateInputEOL( } } - if (dstLen > srcLen) { - dstLen = srcLen; - } - switch (statePtr->inputTranslation) { case TCL_TRANSLATE_LF: + case TCL_TRANSLATE_CR: if (dstStart != srcStart) { - memcpy(dstStart, srcStart, (size_t) dstLen); + memcpy(dstStart, srcStart, (size_t) srcLen); } - srcLen = dstLen; - break; - case TCL_TRANSLATE_CR: { - char *dst, *dstEnd; + if (statePtr->inputTranslation == TCL_TRANSLATE_CR) { + char *dst = dstStart; + char *dstEnd = dstStart + srcLen; - if (dstStart != srcStart) { - memcpy(dstStart, srcStart, (size_t) dstLen); - } - dstEnd = dstStart + dstLen; - for (dst = dstStart; dst < dstEnd; dst++) { - if (*dst == '\r') { - *dst = '\n'; + while ((dst = memchr(dst, '\r', dstEnd - dst))) { + *dst++ = '\n'; } } - srcLen = dstLen; + dstLen = srcLen; break; - } case TCL_TRANSLATE_CRLF: { char *dst; const char *src, *srcEnd, *srcMax; + if (dstLen > srcLen) { + dstLen = srcLen; + } dst = dstStart; src = srcStart; srcEnd = srcStart + dstLen; @@ -5660,29 +5676,23 @@ TranslateInputEOL( break; } case TCL_TRANSLATE_AUTO: { - char *dst; - const char *src, *srcEnd, *srcMax; + const char *srcEnd = srcStart + srcLen; + const char *dstEnd = dstStart + dstLen; + const char *src = srcStart; + char *dst = dstStart; - dst = dstStart; - src = srcStart; - srcEnd = srcStart + dstLen; - srcMax = srcStart + srcLen; - - if ((statePtr->flags & INPUT_SAW_CR) && (src < srcMax)) { + if ((statePtr->flags & INPUT_SAW_CR) && srcLen) { if (*src == '\n') { src++; } ResetFlag(statePtr, INPUT_SAW_CR); } - for ( ; src < srcEnd; ) { + for ( ; dst < dstEnd && src < srcEnd; ) { if (*src == '\r') { src++; - if (src >= srcMax) { + if (src == srcEnd) { SetFlag(statePtr, INPUT_SAW_CR); } else if (*src == '\n') { - if (srcEnd < srcMax) { - srcEnd++; - } src++; } *dst++ = '\n'; @@ -5710,10 +5720,7 @@ TranslateInputEOL( SetFlag(statePtr, CHANNEL_EOF | CHANNEL_STICKY_EOF); statePtr->inputEncodingFlags |= TCL_ENCODING_END; ResetFlag(statePtr, INPUT_SAW_CR); - return 1; } - - return 0; } /* -- cgit v0.12 From baf55bba6a897da4f22fea1871a24dd8f14c2305 Mon Sep 17 00:00:00 2001 From: dgp Date: Mon, 10 Mar 2014 17:58:32 +0000 Subject: Bring CRLF translation in parallel with others. --- generic/tclIO.c | 20 +++++++------------- tests/io.test | 14 ++++++++++++++ 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index 6dfdd03..2971838 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -5645,21 +5645,15 @@ TranslateInputEOL( dstLen = srcLen; break; case TCL_TRANSLATE_CRLF: { - char *dst; - const char *src, *srcEnd, *srcMax; - - if (dstLen > srcLen) { - dstLen = srcLen; - } - dst = dstStart; - src = srcStart; - srcEnd = srcStart + dstLen; - srcMax = srcStart + srcLen; + const char *srcEnd = srcStart + srcLen; + const char *dstEnd = dstStart + dstLen; + const char *src = srcStart; + char *dst = dstStart; - for ( ; src < srcEnd; ) { + for ( ; dst < dstEnd && src < srcEnd; ) { if (*src == '\r') { src++; - if (src >= srcMax) { + if (src == srcEnd) { src--; break; } else if (*src == '\n') { @@ -5710,7 +5704,7 @@ TranslateInputEOL( *dstLenPtr = dstLen; *srcLenPtr = srcLen; - if ((eof != NULL) && (srcStart + srcLen >= eof)) { + if (srcStart + srcLen == eof) { /* * EOF character was seen in EOL translated range. Leave current file * position pointing at the EOF character, but don't store the EOF diff --git a/tests/io.test b/tests/io.test index c325809..e3fff32 100644 --- a/tests/io.test +++ b/tests/io.test @@ -6858,6 +6858,20 @@ test io-52.14 {coverage of -translation crlf} { close $out file size $path(test2) } 29 +test io-52.14.1 {coverage of -translation crlf} { + file delete $path(test1) $path(test2) + set out [open $path(test1) wb] + chan configure $out -translation lf + puts -nonewline $out abcdefg\rhijklmn\nopqrstu\r\nvwxyz + close $out + set in [open $path(test1)] + chan configure $in -buffersize 8 -translation crlf + set out [open $path(test2) w] + fcopy $in $out -size 2 + close $in + close $out + file size $path(test2) +} 2 test io-52.15 {coverage of -translation crlf} { file delete $path(test1) $path(test2) set out [open $path(test1) wb] -- cgit v0.12 From ee4aa52d4251a185f8b4aeddef86dc8d098c6f81 Mon Sep 17 00:00:00 2001 From: dgp Date: Mon, 10 Mar 2014 19:00:19 +0000 Subject: Rewrite CRLF translation to use more system calls. --- generic/tclIO.c | 46 ++++++++++++++++++++++++++++------------------ 1 file changed, 28 insertions(+), 18 deletions(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index 2971838..1070f0a 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -5645,28 +5645,38 @@ TranslateInputEOL( dstLen = srcLen; break; case TCL_TRANSLATE_CRLF: { - const char *srcEnd = srcStart + srcLen; - const char *dstEnd = dstStart + dstLen; - const char *src = srcStart; + const char *crFound, *src = srcStart; char *dst = dstStart; - - for ( ; dst < dstEnd && src < srcEnd; ) { - if (*src == '\r') { - src++; - if (src == srcEnd) { - src--; - break; - } else if (*src == '\n') { - *dst++ = *src++; - } else { - *dst++ = '\r'; - } + int lesser = (dstLen < srcLen) ? dstLen : srcLen; + + while ((crFound = memchr(src, '\r', lesser))) { + int numBytes = crFound - src; + memmove(dst, src, numBytes); + + dst += numBytes; + src += numBytes; + dstLen -= numBytes; + srcLen -= numBytes; + if (srcLen == 1) { + /* valid src bytes end in \r */ + lesser = 0; + break; + } + if (src[1] == '\n') { + *dst++ = '\n'; + srcLen -= 2; + src += 2; } else { - *dst++ = *src++; + *dst++ = '\r'; + srcLen--; + src++; } + dstLen++; + lesser = (dstLen < srcLen) ? dstLen : srcLen; } - srcLen = src - srcStart; - dstLen = dst - dstStart; + memmove(dst, src, lesser); + srcLen = src + lesser - srcStart; + dstLen = dst + lesser - dstStart; break; } case TCL_TRANSLATE_AUTO: { -- cgit v0.12 From f8cfd0ecd013de352e19827f8d9900978dccef11 Mon Sep 17 00:00:00 2001 From: dgp Date: Mon, 10 Mar 2014 19:29:54 +0000 Subject: Test for the bug I just committed. --- tests/io.test | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/tests/io.test b/tests/io.test index e3fff32..1bc3799 100644 --- a/tests/io.test +++ b/tests/io.test @@ -6872,6 +6872,20 @@ test io-52.14.1 {coverage of -translation crlf} { close $out file size $path(test2) } 2 +test io-52.14.2 {coverage of -translation crlf} { + file delete $path(test1) $path(test2) + set out [open $path(test1) wb] + chan configure $out -translation lf + puts -nonewline $out abcdefg\rhijklmn\nopqrstu\r\nvwxyz + close $out + set in [open $path(test1)] + chan configure $in -translation crlf + set out [open $path(test2) w] + fcopy $in $out -size 9 + close $in + close $out + file size $path(test2) +} 9 test io-52.15 {coverage of -translation crlf} { file delete $path(test1) $path(test2) set out [open $path(test1) wb] -- cgit v0.12 From 080aa64c3d3e6eedebb7971b38c7db43b0159474 Mon Sep 17 00:00:00 2001 From: dgp Date: Mon, 10 Mar 2014 19:30:22 +0000 Subject: .... and then the bug fix. --- generic/tclIO.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index 1070f0a..6194637 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -5671,7 +5671,7 @@ TranslateInputEOL( srcLen--; src++; } - dstLen++; + dstLen--; lesser = (dstLen < srcLen) ? dstLen : srcLen; } memmove(dst, src, lesser); -- cgit v0.12 From 47b051259154b9d508a641b05233bc67bf15c2f9 Mon Sep 17 00:00:00 2001 From: dgp Date: Tue, 11 Mar 2014 03:38:55 +0000 Subject: Trial rewrite of AUTO input translation. --- generic/tclIO.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/generic/tclIO.c b/generic/tclIO.c index 6194637..8d8e30f 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -5680,6 +5680,40 @@ TranslateInputEOL( break; } case TCL_TRANSLATE_AUTO: { +#if 1 + const char *crFound, *src = srcStart; + char *dst = dstStart; + int lesser; + + if ((statePtr->flags & INPUT_SAW_CR) && srcLen) { + if (*src == '\n') { + src++; + srcLen--; + } + ResetFlag(statePtr, INPUT_SAW_CR); + } + lesser = (dstLen < srcLen) ? dstLen : srcLen; + while ((crFound = memchr(src, '\r', lesser))) { + int numBytes = crFound - src; + memmove(dst, src, numBytes); + + dst[numBytes] = '\n'; + dst += numBytes + 1; + dstLen -= numBytes + 1; + src += numBytes + 1; + srcLen -= numBytes + 1; + if (srcLen == 0) { + SetFlag(statePtr, INPUT_SAW_CR); + } else if (*src == '\n') { + src++; + srcLen--; + } + lesser = (dstLen < srcLen) ? dstLen : srcLen; + } + memmove(dst, src, lesser); + srcLen = src + lesser - srcStart; + dstLen = dst + lesser - dstStart; +#else const char *srcEnd = srcStart + srcLen; const char *dstEnd = dstStart + dstLen; const char *src = srcStart; @@ -5706,6 +5740,7 @@ TranslateInputEOL( } srcLen = src - srcStart; dstLen = dst - dstStart; +#endif break; } default: -- cgit v0.12 From 6c5d496711e189450d15ae761b78bfdcedb40181 Mon Sep 17 00:00:00 2001 From: dgp Date: Tue, 11 Mar 2014 16:51:38 +0000 Subject: Compress code for better single screen viewing. --- generic/tclIO.c | 55 ++++++++----------------------------------------------- 1 file changed, 8 insertions(+), 47 deletions(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index 8d8e30f..b4f1c0c 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -5653,10 +5653,8 @@ TranslateInputEOL( int numBytes = crFound - src; memmove(dst, src, numBytes); - dst += numBytes; - src += numBytes; - dstLen -= numBytes; - srcLen -= numBytes; + dst += numBytes; dstLen -= numBytes; + src += numBytes; srcLen -= numBytes; if (srcLen == 1) { /* valid src bytes end in \r */ lesser = 0; @@ -5664,12 +5662,10 @@ TranslateInputEOL( } if (src[1] == '\n') { *dst++ = '\n'; - srcLen -= 2; - src += 2; + src += 2; srcLen -= 2; } else { *dst++ = '\r'; - srcLen--; - src++; + src++; srcLen--; } dstLen--; lesser = (dstLen < srcLen) ? dstLen : srcLen; @@ -5680,16 +5676,12 @@ TranslateInputEOL( break; } case TCL_TRANSLATE_AUTO: { -#if 1 const char *crFound, *src = srcStart; char *dst = dstStart; int lesser; if ((statePtr->flags & INPUT_SAW_CR) && srcLen) { - if (*src == '\n') { - src++; - srcLen--; - } + if (*src == '\n') { src++; srcLen--; } ResetFlag(statePtr, INPUT_SAW_CR); } lesser = (dstLen < srcLen) ? dstLen : srcLen; @@ -5698,49 +5690,18 @@ TranslateInputEOL( memmove(dst, src, numBytes); dst[numBytes] = '\n'; - dst += numBytes + 1; - dstLen -= numBytes + 1; - src += numBytes + 1; - srcLen -= numBytes + 1; + dst += numBytes + 1; dstLen -= numBytes + 1; + src += numBytes + 1; srcLen -= numBytes + 1; if (srcLen == 0) { SetFlag(statePtr, INPUT_SAW_CR); } else if (*src == '\n') { - src++; - srcLen--; + src++; srcLen--; } lesser = (dstLen < srcLen) ? dstLen : srcLen; } memmove(dst, src, lesser); srcLen = src + lesser - srcStart; dstLen = dst + lesser - dstStart; -#else - const char *srcEnd = srcStart + srcLen; - const char *dstEnd = dstStart + dstLen; - const char *src = srcStart; - char *dst = dstStart; - - if ((statePtr->flags & INPUT_SAW_CR) && srcLen) { - if (*src == '\n') { - src++; - } - ResetFlag(statePtr, INPUT_SAW_CR); - } - for ( ; dst < dstEnd && src < srcEnd; ) { - if (*src == '\r') { - src++; - if (src == srcEnd) { - SetFlag(statePtr, INPUT_SAW_CR); - } else if (*src == '\n') { - src++; - } - *dst++ = '\n'; - } else { - *dst++ = *src++; - } - } - srcLen = src - srcStart; - dstLen = dst - dstStart; -#endif break; } default: -- cgit v0.12 From b9409ecdff577e766260d91d4b9a00f84a1c274a Mon Sep 17 00:00:00 2001 From: dgp Date: Mon, 17 Mar 2014 17:56:47 +0000 Subject: Remove long dead "BAD_BLOCKING" support code so it no longer confuses people reading/editing this code. --- generic/tclIO.c | 133 +++++--------------------------------------------------- generic/tclIO.h | 23 ---------- 2 files changed, 10 insertions(+), 146 deletions(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index b4f1c0c..0f894e4 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -4873,42 +4873,18 @@ Tcl_ReadRaw( ResetFlag(statePtr, CHANNEL_BLOCKED); } -#ifdef TCL_IO_TRACK_OS_FOR_DRIVER_WITH_BAD_BLOCKING /* - * [Bug 943274]. Better emulation of non-blocking channels for - * channels without BlockModeProc, by keeping track of true - * fileevents generated by the OS == Data waiting and reading if - * and only if we are sure to have data. + * Now go to the driver to get as much as is possible to + * fill the remaining request. Do all the error handling by + * ourselves. The code was stolen from 'GetInput' and + * slightly adapted (different return value here). + * + * The case of 'bytesToRead == 0' at this point cannot + * happen. */ - if ((statePtr->flags & CHANNEL_NONBLOCKING) && - (Tcl_ChannelBlockModeProc(chanPtr->typePtr) == NULL) && - !(statePtr->flags & CHANNEL_HAS_MORE_DATA)) { - /* - * We bypass the driver; it would block as no data is - * available. - */ - - nread = -1; - result = EWOULDBLOCK; - } else { -#endif /* TCL_IO_TRACK_OS_FOR_DRIVER_WITH_BAD_BLOCKING */ - - /* - * Now go to the driver to get as much as is possible to fill - * the remaining request. Do all the error handling by - * ourselves. The code was stolen from 'GetInput' and slightly - * adapted (different return value here). - * - * The case of 'bytesToRead == 0' at this point cannot happen. - */ - - nread = ChanRead(chanPtr, bufPtr + copied, - bytesToRead - copied, &result); - -#ifdef TCL_IO_TRACK_OS_FOR_DRIVER_WITH_BAD_BLOCKING - } -#endif /* TCL_IO_TRACK_OS_FOR_DRIVER_WITH_BAD_BLOCKING */ + nread = ChanRead(chanPtr, bufPtr + copied, + bytesToRead - copied, &result); if (nread > 0) { /* @@ -4921,18 +4897,6 @@ Tcl_ReadRaw( if (nread < (bytesToRead - copied)) { SetFlag(statePtr, CHANNEL_BLOCKED); } - -#ifdef TCL_IO_TRACK_OS_FOR_DRIVER_WITH_BAD_BLOCKING - if (nread <= (bytesToRead - copied)) { - /* - * [Bug 943274] We have read the available data, clear - * flag. - */ - - ResetFlag(statePtr, CHANNEL_HAS_MORE_DATA); - } -#endif /* TCL_IO_TRACK_OS_FOR_DRIVER_WITH_BAD_BLOCKING */ - } else if (nread == 0) { SetFlag(statePtr, CHANNEL_EOF); statePtr->inputEncodingFlags |= TCL_ENCODING_END; @@ -6041,32 +6005,7 @@ GetInput( return 0; } -#ifdef TCL_IO_TRACK_OS_FOR_DRIVER_WITH_BAD_BLOCKING - /* - * [SF Tcl Bug 943274]. Better emulation of non-blocking channels for - * channels without BlockModeProc, by keeping track of true fileevents - * generated by the OS == Data waiting and reading if and only if we are - * sure to have data. - */ - - if ((statePtr->flags & CHANNEL_NONBLOCKING) && - (Tcl_ChannelBlockModeProc(chanPtr->typePtr) == NULL) && - !(statePtr->flags & CHANNEL_HAS_MORE_DATA)) { - /* - * Bypass the driver, it would block, as no data is available - */ - - nread = -1; - result = EWOULDBLOCK; - } else { -#endif /* TCL_IO_TRACK_OS_FOR_DRIVER_WITH_BAD_BLOCKING */ - - nread = ChanRead(chanPtr, InsertPoint(bufPtr), toRead, &result); - -#ifdef TCL_IO_TRACK_OS_FOR_DRIVER_WITH_BAD_BLOCKING - } -#endif /* TCL_IO_TRACK_OS_FOR_DRIVER_WITH_BAD_BLOCKING */ - + nread = ChanRead(chanPtr, InsertPoint(bufPtr), toRead, &result); if (nread > 0) { bufPtr->nextAdded += nread; @@ -6080,18 +6019,6 @@ GetInput( if (nread < toRead) { SetFlag(statePtr, CHANNEL_BLOCKED); } - -#ifdef TCL_IO_TRACK_OS_FOR_DRIVER_WITH_BAD_BLOCKING - if (nread <= toRead) { - /* - * [SF Tcl Bug 943274] We have read the available data, clear - * flag. - */ - - ResetFlag(statePtr, CHANNEL_HAS_MORE_DATA); - } -#endif /* TCL_IO_TRACK_OS_FOR_DRIVER_WITH_BAD_BLOCKING */ - } else if (nread == 0) { SetFlag(statePtr, CHANNEL_EOF); statePtr->inputEncodingFlags |= TCL_ENCODING_END; @@ -7548,21 +7475,6 @@ Tcl_NotifyChannel( Channel *upChanPtr; const Tcl_ChannelType *upTypePtr; -#ifdef TCL_IO_TRACK_OS_FOR_DRIVER_WITH_BAD_BLOCKING - /* - * [SF Tcl Bug 943274] For a non-blocking channel without blockmodeproc we - * keep track of actual input coming from the OS so that we can do a - * credible imitation of non-blocking behaviour. - */ - - if ((mask & TCL_READABLE) && - (statePtr->flags & CHANNEL_NONBLOCKING) && - (Tcl_ChannelBlockModeProc(chanPtr->typePtr) == NULL) && - !(statePtr->flags & CHANNEL_TIMER_FEV)) { - SetFlag(statePtr, CHANNEL_HAS_MORE_DATA); - } -#endif /* TCL_IO_TRACK_OS_FOR_DRIVER_WITH_BAD_BLOCKING */ - /* * In contrast to the other API functions this procedure walks towards the * top of a stack and not down from it. @@ -7797,29 +7709,8 @@ ChannelTimerProc( */ statePtr->timer = Tcl_CreateTimerHandler(0, ChannelTimerProc,chanPtr); - -#ifdef TCL_IO_TRACK_OS_FOR_DRIVER_WITH_BAD_BLOCKING - /* - * Set the TIMER flag to notify the higher levels that the driver - * might have no data for us. We do this only if we are in - * non-blocking mode and the driver has no BlockModeProc because only - * then we really don't know if the driver will block or not. A - * similar test is done in "PeekAhead". - */ - - if ((statePtr->flags & CHANNEL_NONBLOCKING) && - (Tcl_ChannelBlockModeProc(chanPtr->typePtr) == NULL)) { - SetFlag(statePtr, CHANNEL_TIMER_FEV); - } -#endif /* TCL_IO_TRACK_OS_FOR_DRIVER_WITH_BAD_BLOCKING */ - Tcl_Preserve(statePtr); Tcl_NotifyChannel((Tcl_Channel)chanPtr, TCL_READABLE); - -#ifdef TCL_IO_TRACK_OS_FOR_DRIVER_WITH_BAD_BLOCKING - ResetFlag(statePtr, CHANNEL_TIMER_FEV); -#endif /* TCL_IO_TRACK_OS_FOR_DRIVER_WITH_BAD_BLOCKING */ - Tcl_Release(statePtr); } else { statePtr->timer = NULL; @@ -10381,10 +10272,6 @@ DumpFlags( ChanFlag('/', INPUT_SAW_CR); ChanFlag('D', CHANNEL_DEAD); ChanFlag('R', CHANNEL_RAW_MODE); -#ifdef TCL_IO_TRACK_OS_FOR_DRIVER_WITH_BAD_BLOCKING - ChanFlag('T', CHANNEL_TIMER_FEV); - ChanFlag('H', CHANNEL_HAS_MORE_DATA); -#endif /* TCL_IO_TRACK_OS_FOR_DRIVER_WITH_BAD_BLOCKING */ ChanFlag('x', CHANNEL_INCLOSE); buf[i] ='\0'; diff --git a/generic/tclIO.h b/generic/tclIO.h index a57d4c5..59754cf 100644 --- a/generic/tclIO.h +++ b/generic/tclIO.h @@ -271,29 +271,6 @@ typedef struct ChannelState { * changes. */ #define CHANNEL_RAW_MODE (1<<16) /* When set, notes that the Raw API is * being used. */ -#ifdef TCL_IO_TRACK_OS_FOR_DRIVER_WITH_BAD_BLOCKING -#define CHANNEL_TIMER_FEV (1<<17) /* When set the event we are notified - * by is a fileevent generated by a - * timer. We don't know if the driver - * has more data and should not try to - * read from it. If the system needs - * more than is in the buffers out - * read routines will simulate a short - * read (0 characters read) */ -#define CHANNEL_HAS_MORE_DATA (1<<18) /* Set by NotifyChannel for a channel - * if and only if the channel is - * configured non-blocking, the driver - * for said channel has no - * blockmodeproc, and data has arrived - * for reading at the OS level). A - * GetInput will pass reading from the - * driver if the channel is - * non-blocking, without blockmode - * proc and the flag has not been set. - * A read will be performed if the - * flag is set. This will reset the - * flag as well. */ -#endif /* TCL_IO_TRACK_OS_FOR_DRIVER_WITH_BAD_BLOCKING */ #define CHANNEL_INCLOSE (1<<19) /* Channel is currently being closed. * Its structures are still live and -- cgit v0.12 From 3e8c032e35406e5980add3c3985858191f30eed3 Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 19 Mar 2014 20:32:37 +0000 Subject: Complete rewrite of DoRead(). --- generic/tclIO.c | 288 ++++++++++++++++++++++++++------------------------------ 1 file changed, 132 insertions(+), 156 deletions(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index 0f894e4..2d22942 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -11,6 +11,7 @@ * this file, and for a DISCLAIMER OF ALL WARRANTIES. */ +#undef NDEBUG #include "tclInt.h" #include "tclIO.h" #include @@ -173,8 +174,6 @@ static void CleanupChannelHandlers(Tcl_Interp *interp, static int CloseChannel(Tcl_Interp *interp, Channel *chanPtr, int errorCode); static void CommonGetsCleanup(Channel *chanPtr); -static int CopyAndTranslateBuffer(ChannelState *statePtr, - char *result, int space); static int CopyBuffer(Channel *chanPtr, char *result, int space); static int CopyData(CopyState *csPtr, int mask); static void CopyEventProc(ClientData clientData, int mask); @@ -188,7 +187,7 @@ static int DetachChannel(Tcl_Interp *interp, Tcl_Channel chan); static void DiscardInputQueued(ChannelState *statePtr, int discardSavedBuffers); static void DiscardOutputQueued(ChannelState *chanPtr); -static int DoRead(Channel *chanPtr, char *srcPtr, int slen); +static int DoRead(Channel *chanPtr, char *dst, int bytesToRead); static int DoReadChars(Channel *chan, Tcl_Obj *objPtr, int toRead, int appendFlag); static int FilterInputBytes(Channel *chanPtr, @@ -5363,7 +5362,7 @@ ReadChars( * record \r or \n yet. */ - assert(dstRead + 1 == dstDecoded); +// assert(dstRead + 1 == dstDecoded); assert(dst[dstRead] == '\r'); assert(statePtr->inputTranslation == TCL_TRANSLATE_CRLF); @@ -5384,7 +5383,7 @@ ReadChars( assert(dstWrote == 0); assert(dstRead == 0); - assert(dstDecoded == 1); +// assert(dstDecoded == 1); /* * We decoded only the bare cr, and we cannot read a @@ -5882,6 +5881,9 @@ DiscardInputQueued( * * Reads input data from a device into a channel buffer. * + * IMPORTANT! This routine is only called on a chanPtr argument + * that is the top channel of a stack! + * * Results: * The return value is the Posix error code if an error occurred while * reading from the file, or 0 otherwise. @@ -8633,13 +8635,24 @@ CopyData( * * DoRead -- * - * Reads a given number of bytes from a channel. + * Stores up to "bytesToRead" bytes in memory pointed to by "dst". + * These bytes come from reading the channel "chanPtr" and + * performing the configured translations. * * No encoding conversions are applied to the bytes being read. * * Results: - * The number of characters read, or -1 on error. Use Tcl_GetErrno() to - * retrieve the error code for the error that occurred. + * The number of bytes actually stored (<= bytesToRead), + * or -1 if there is an error in reading the channel. Use + * Tcl_GetErrno() to retrieve the error code for the error + * that occurred. + * + * The number of bytes stored can be less than the number + * requested when + * - EOF is reached on the channel; or + * - the channel is non-blocking, and we've read all we can + * without blocking. + * - a channel reading error occurs (and we return -1) * * Side effects: * May cause input to be buffered. @@ -8650,186 +8663,149 @@ CopyData( static int DoRead( Channel *chanPtr, /* The channel from which to read. */ - char *bufPtr, /* Where to store input read. */ - int toRead) /* Maximum number of bytes to read. */ + char *dst, /* Where to store input read. */ + int bytesToRead) /* Maximum number of bytes to read. */ { ChannelState *statePtr = chanPtr->state; - /* State info for channel */ - int copied; /* How many characters were copied into the - * result string? */ - int copiedNow; /* How many characters were copied from the - * current input buffer? */ - int result; /* Of calling GetInput. */ + char *p = dst; - /* - * If we have not encountered a sticky EOF, clear the EOF bit. Either way - * clear the BLOCKED bit. We want to discover these anew during each - * operation. - */ + while (bytesToRead) { + /* + * Each pass through the loop is intended to process up to + * one channel buffer. + * + * First, if there is no full buffer, we attempt to + * create and/or fill one. + */ - if (!(statePtr->flags & CHANNEL_STICKY_EOF)) { - ResetFlag(statePtr, CHANNEL_EOF); - } - ResetFlag(statePtr, CHANNEL_BLOCKED | CHANNEL_NEED_MORE_DATA); + ChannelBuffer *bufPtr = statePtr->inQueueHead; - for (copied = 0; copied < toRead; copied += copiedNow) { - copiedNow = CopyAndTranslateBuffer(statePtr, bufPtr + copied, - toRead - copied); - if (copiedNow == 0) { - if (statePtr->flags & CHANNEL_EOF) { - goto done; - } - if (statePtr->flags & CHANNEL_BLOCKED) { - if (statePtr->flags & CHANNEL_NONBLOCKING) { - goto done; - } - ResetFlag(statePtr, CHANNEL_BLOCKED); + if (statePtr->flags & CHANNEL_EOF + && (bufPtr == NULL || IsBufferEmpty(bufPtr))) { + break; + } + + while (bufPtr == NULL || !IsBufferFull(bufPtr)) { + int code; + + ResetFlag(statePtr, CHANNEL_BLOCKED); + moreData: + code = GetInput(chanPtr); + bufPtr = statePtr->inQueueHead; + if (statePtr->flags & (CHANNEL_EOF|CHANNEL_BLOCKED)) { + /* Further reads cannot do any more */ + break; } - result = GetInput(chanPtr); - if (result != 0) { - if (result != EAGAIN) { - copied = -1; - } - goto done; + + if (code) { + /* Read error */ + UpdateInterest(chanPtr); + return -1; } } - } - ResetFlag(statePtr, CHANNEL_BLOCKED); + /* Here we know bufPtr != NULL */ + int bytesRead = BytesLeft(bufPtr); + int bytesWritten = bytesToRead; - /* - * Update the notifier state so we don't block while there is still data - * in the buffers. - */ + if (bytesRead == 0 && statePtr->flags & CHANNEL_NONBLOCKING + && statePtr->flags & CHANNEL_BLOCKED) { + break; + } - done: - UpdateInterest(chanPtr); - return copied; -} - -/* - *---------------------------------------------------------------------- - * - * CopyAndTranslateBuffer -- - * - * Copy at most one buffer of input to the result space, doing eol - * translations according to mode in effect currently. - * - * Results: - * Number of bytes stored in the result buffer (as opposed to the number - * of bytes read from the channel). May return zero if no input is - * available to be translated. - * - * Side effects: - * Consumes buffered input. May deallocate one buffer. - * - *---------------------------------------------------------------------- - */ + TranslateInputEOL(statePtr, p, RemovePoint(bufPtr), + &bytesWritten, &bytesRead); + bufPtr->nextRemoved += bytesRead; + p += bytesWritten; + bytesToRead -= bytesWritten; -static int -CopyAndTranslateBuffer( - ChannelState *statePtr, /* Channel state from which to read input. */ - char *result, /* Where to store the copied input. */ - int space) /* How many bytes are available in result to - * store the copied input? */ -{ - ChannelBuffer *bufPtr; /* The buffer from which to copy bytes. */ - int bytesInBuffer; /* How many bytes are available to be copied - * in the current input buffer? */ - int copied; /* How many characters were already copied - * into the destination space? */ + if (!IsBufferEmpty(bufPtr)) { + /* + * Buffer is not empty. How can that be? + * + * 0) We stopped early because we got all the bytes + * we were seeking. That's fine. + */ - /* - * If there is no input at all, return zero. The invariant is that either - * there is no buffer in the queue, or if the first buffer is empty, it is - * also the last buffer (and thus there is no input in the queue). Note - * also that if the buffer is empty, we leave it in the queue. - */ + if (bytesToRead == 0) { + UpdateInterest(chanPtr); + break; + } - if (statePtr->inQueueHead == NULL) { - return 0; - } - bufPtr = statePtr->inQueueHead; - bytesInBuffer = BytesLeft(bufPtr); - if (bytesInBuffer == 0) { - return 0; - } + /* + * 1) We're @EOF because we saw eof char. + */ - copied = space; - TranslateInputEOL(statePtr, result, RemovePoint(bufPtr), - &copied, &bytesInBuffer); - bufPtr->nextRemoved += bytesInBuffer; + if (statePtr->inEofChar + && RemovePoint(bufPtr)[0] == statePtr->inEofChar) { + UpdateInterest(chanPtr); + break; + } - /* - * If the current buffer is empty recycle it. - */ + /* + * 2) The buffer holds a \r while in CRLF translation, followed + * by either the end of the buffer, or the eof char. + */ - if (IsBufferEmpty(bufPtr)) { - statePtr->inQueueHead = bufPtr->nextPtr; - if (statePtr->inQueueHead == NULL) { - statePtr->inQueueTail = NULL; - } - RecycleBuffer(statePtr, bufPtr, 0); - } else { + assert(statePtr->inputTranslation == TCL_TRANSLATE_CRLF); + assert(RemovePoint(bufPtr)[0] == '\r'); - if (copied > 0) { - return copied; - } + if (BytesLeft(bufPtr) > 1) { - if (statePtr->inEofChar - && RemovePoint(bufPtr)[0] == statePtr->inEofChar) { - return 0; - } + /* TODO: shift this to TIEOL */ + assert(statePtr->inEofChar); + assert(RemovePoint(bufPtr)[1] == statePtr->inEofChar); - if (BytesLeft(bufPtr) == 1) { + bufPtr->nextRemoved++; + *p++ = '\r'; + bytesToRead--; + UpdateInterest(chanPtr); + break; + } - ChannelBuffer *nextPtr = bufPtr->nextPtr; + assert(BytesLeft(bufPtr) == 1); - if (nextPtr == NULL) { + if (bufPtr->nextPtr == NULL) { + /* There's no more buffered data.... */ if (statePtr->flags & CHANNEL_EOF) { - *result = '\r'; - bufPtr->nextRemoved += 1; - return 1; - } + /* ...and there never will be. */ - SetFlag(statePtr, CHANNEL_NEED_MORE_DATA); - return 0; + *p++ = '\r'; + bytesToRead--; + bufPtr->nextRemoved++; + } else if (statePtr->flags & CHANNEL_BLOCKED) { + /* ...and we cannot get more now. */ + SetFlag(statePtr, CHANNEL_NEED_MORE_DATA); + UpdateInterest(chanPtr); + break; + } else { + /* ... so we need to get some. */ + goto moreData; + } } - nextPtr->nextRemoved -= 1; - memcpy(RemovePoint(nextPtr), RemovePoint(bufPtr), 1); - RecycleBuffer(statePtr, bufPtr, 0); - statePtr->inQueueHead = nextPtr; - return 0; - } + if (bufPtr->nextPtr) { + /* There's a next buffer. Shift orphan \r to it. */ - if (statePtr->inEofChar - && RemovePoint(bufPtr)[1] == statePtr->inEofChar) { - *result = '\r'; - bufPtr->nextRemoved += 1; - return 1; + ChannelBuffer *nextPtr = bufPtr->nextPtr; + + nextPtr->nextRemoved -= 1; + RemovePoint(nextPtr)[0] = '\r'; + bufPtr->nextRemoved++; + } } - /* - * Buffer is not empty. How can that be? - * 0) We stopped early due to the value of "space". - * => copied > 0 and all is fine. - * 1) We saw eof char and stopped the translation copy. - * => if (copied > 0) or ((copied == 0) and @ eof char), - * return is fine. - * 2) The buffer holds a \r while in CRLF translation, followed - * by either the end of the buffer, or the eof char. - */ + if (IsBufferEmpty(bufPtr)) { + statePtr->inQueueHead = bufPtr->nextPtr; + if (statePtr->inQueueHead == NULL) { + statePtr->inQueueTail = NULL; + } + RecycleBuffer(statePtr, bufPtr, 0); + } } - /* - * Return the number of characters copied into the result buffer. This may - * be different from the number of bytes consumed, because of EOL - * translations. - */ - - return copied; + return (int)(p - dst); } /* -- cgit v0.12 From 02d7d5af4c5e9f0d21f627c866ee942270363954 Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 19 Mar 2014 21:43:31 +0000 Subject: Let TranslateInputEOL handle the "\r$eofChar" sequence in CRLF mode. --- generic/tclIO.c | 44 +++++++++++++++++--------------------------- 1 file changed, 17 insertions(+), 27 deletions(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index 2d22942..267b659 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -5362,7 +5362,7 @@ ReadChars( * record \r or \n yet. */ -// assert(dstRead + 1 == dstDecoded); + assert(dstRead + 1 == dstDecoded); assert(dst[dstRead] == '\r'); assert(statePtr->inputTranslation == TCL_TRANSLATE_CRLF); @@ -5383,7 +5383,7 @@ ReadChars( assert(dstWrote == 0); assert(dstRead == 0); -// assert(dstDecoded == 1); + assert(dstDecoded == 1); /* * We decoded only the bare cr, and we cannot read a @@ -5620,10 +5620,14 @@ TranslateInputEOL( src += numBytes; srcLen -= numBytes; if (srcLen == 1) { /* valid src bytes end in \r */ - lesser = 0; - break; - } - if (src[1] == '\n') { + if (eof) { + *dst++ = '\r'; + src++; srcLen--; + } else { + lesser = 0; + break; + } + } else if (src[1] == '\n') { *dst++ = '\n'; src += 2; srcLen -= 2; } else { @@ -8708,11 +8712,6 @@ DoRead( int bytesRead = BytesLeft(bufPtr); int bytesWritten = bytesToRead; - if (bytesRead == 0 && statePtr->flags & CHANNEL_NONBLOCKING - && statePtr->flags & CHANNEL_BLOCKED) { - break; - } - TranslateInputEOL(statePtr, p, RemovePoint(bufPtr), &bytesWritten, &bytesRead); bufPtr->nextRemoved += bytesRead; @@ -8743,26 +8742,12 @@ DoRead( } /* - * 2) The buffer holds a \r while in CRLF translation, followed - * by either the end of the buffer, or the eof char. + * 2) The buffer holds a \r while in CRLF translation, + * followed by the end of the buffer. */ assert(statePtr->inputTranslation == TCL_TRANSLATE_CRLF); assert(RemovePoint(bufPtr)[0] == '\r'); - - if (BytesLeft(bufPtr) > 1) { - - /* TODO: shift this to TIEOL */ - assert(statePtr->inEofChar); - assert(RemovePoint(bufPtr)[1] == statePtr->inEofChar); - - bufPtr->nextRemoved++; - *p++ = '\r'; - bytesToRead--; - UpdateInterest(chanPtr); - break; - } - assert(BytesLeft(bufPtr) == 1); if (bufPtr->nextPtr == NULL) { @@ -8803,6 +8788,11 @@ DoRead( } RecycleBuffer(statePtr, bufPtr, 0); } + + if (statePtr->flags & CHANNEL_NONBLOCKING + && statePtr->flags & CHANNEL_BLOCKED) { + break; + } } return (int)(p - dst); -- cgit v0.12 From 16dcfe4b5f5329a1b56f5a9eee442d00fb058eba Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 20 Mar 2014 16:31:11 +0000 Subject: Use assertions about the pushback buffers to simplify their handling. Mark several things left TODO. Some tidying. --- generic/tclIO.c | 60 +++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 37 insertions(+), 23 deletions(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index 267b659..b423bcc 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -6,6 +6,7 @@ * * Copyright (c) 1998-2000 Ajuba Solutions * Copyright (c) 1995-1997 Sun Microsystems, Inc. + * Contributions from Don Porter, NIST, 2014. (not subject to US copyright) * * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. @@ -1679,17 +1680,17 @@ Tcl_StackChannel( */ if (((mask & TCL_READABLE) != 0) && (statePtr->inQueueHead != NULL)) { + /* - * Remark: It is possible that the channel buffers contain data from - * some earlier push-backs. + * When statePtr->inQueueHead is not NULL, we know + * prevChanPtr->inQueueHead must be NULL. */ - statePtr->inQueueTail->nextPtr = prevChanPtr->inQueueHead; - prevChanPtr->inQueueHead = statePtr->inQueueHead; + assert(prevChanPtr->inQueueHead == NULL); + assert(prevChanPtr->inQueueTail == NULL); - if (prevChanPtr->inQueueTail == NULL) { - prevChanPtr->inQueueTail = statePtr->inQueueTail; - } + prevChanPtr->inQueueHead = statePtr->inQueueHead; + prevChanPtr->inQueueTail = statePtr->inQueueTail; statePtr->inQueueHead = NULL; statePtr->inQueueTail = NULL; @@ -2254,6 +2255,7 @@ RecycleBuffer( } /* + * TODO * Only save buffers which are at least as big as the requested buffersize * for the channel. This is to honor dynamic changes of the buffersize * made by the user. @@ -3696,9 +3698,7 @@ Write( &statePtr->outputEncodingState, dst, dstLen + BUFFER_PADDING, &srcRead, &dstWrote, NULL); - if (srcRead != nlLen) { - Tcl_Panic("Can This Happen?"); - } + assert (srcRead == nlLen); bufPtr->nextAdded += dstWrote; src++; @@ -4837,6 +4837,7 @@ Tcl_ReadRaw( int nread, result, copied, copiedNow; /* + * TODO VERIFY * The check below does too much because it will reject a call to this * function with a channel which is part of an 'fcopy'. But we have to * allow this here or else the chaining in the transformation drivers will @@ -5925,16 +5926,11 @@ GetInput( * channel in the stack and use them. They can be the result of a * transformation which went away without reading all the information * placed in the area when it was stacked. - * - * Two possibilities for the state: No buffers in it, or a single empty - * buffer. In the latter case we can recycle it now. */ if (chanPtr->inQueueHead != NULL) { - if (statePtr->inQueueHead != NULL) { - RecycleBuffer(statePtr, statePtr->inQueueHead, 0); - statePtr->inQueueHead = NULL; - } + + assert(statePtr->inQueueHead == NULL); statePtr->inQueueHead = chanPtr->inQueueHead; statePtr->inQueueTail = chanPtr->inQueueTail; @@ -5962,6 +5958,7 @@ GetInput( statePtr->saveInBufPtr = NULL; /* + * TODO * Check the actual buffersize against the requested buffersize. * Buffers which are smaller than requested are squashed. This is done * to honor dynamic changes of the buffersize made by the user. @@ -5979,6 +5976,7 @@ GetInput( bufPtr->nextPtr = NULL; /* + * TODO * SF #427196: Use the actual size of the buffer to determine the * number of bytes to read from the channel and not the size for new * buffers. They can be different if the buffersize was changed @@ -6003,6 +6001,7 @@ GetInput( } /* + * TODO * If EOF is set, we should avoid calling the driver because on some * platforms it is impossible to read from a device after EOF. */ @@ -6524,6 +6523,7 @@ CheckChannelErrors( if (direction == TCL_READABLE) { /* + * TODO * If we have not encountered a sticky EOF, clear the EOF bit (sticky * EOF is set if we have seen the input eofChar, to prevent reading * beyond the eofChar). Also, always clear the BLOCKED bit. We want to @@ -6739,6 +6739,7 @@ Tcl_SetChannelBufferSize( ChannelState *statePtr; /* State of real channel structure. */ /* + * TODO * Clip the buffer size to force it into the [1,1M] range */ @@ -7375,6 +7376,7 @@ Tcl_SetChannelOption( } /* + * TODO * If bufsize changes, need to get rid of old utility buffer. */ @@ -8677,18 +8679,23 @@ DoRead( /* * Each pass through the loop is intended to process up to * one channel buffer. - * - * First, if there is no full buffer, we attempt to - * create and/or fill one. */ + int bytesRead, bytesWritten; ChannelBuffer *bufPtr = statePtr->inQueueHead; + /* + * When there's no buffered data to read, and we're at EOF, + * escape to the caller. + */ + if (statePtr->flags & CHANNEL_EOF && (bufPtr == NULL || IsBufferEmpty(bufPtr))) { break; } + /* If there is no full buffer, attempt to create and/or fill one. */ + while (bufPtr == NULL || !IsBufferFull(bufPtr)) { int code; @@ -8696,6 +8703,9 @@ DoRead( moreData: code = GetInput(chanPtr); bufPtr = statePtr->inQueueHead; + + assert (bufPtr != NULL); + if (statePtr->flags & (CHANNEL_EOF|CHANNEL_BLOCKED)) { /* Further reads cannot do any more */ break; @@ -8706,11 +8716,14 @@ DoRead( UpdateInterest(chanPtr); return -1; } + + assert (IsBufferFull(bufPtr)); } - /* Here we know bufPtr != NULL */ - int bytesRead = BytesLeft(bufPtr); - int bytesWritten = bytesToRead; + assert (bufPtr != NULL); + + bytesRead = BytesLeft(bufPtr); + bytesWritten = bytesToRead; TranslateInputEOL(statePtr, p, RemovePoint(bufPtr), &bytesWritten, &bytesRead); @@ -10155,6 +10168,7 @@ SetChannelFromAny( } if (objPtr->typePtr == &chanObjType) { /* + * TODO: TAINT Flag and dup'd channel values? * The channel is valid until any call to DetachChannel occurs. * Ensure consistency checks are done. */ -- cgit v0.12 From 88abf586de9aba5d37c1d71448a3123c3d9e2c77 Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 20 Mar 2014 19:25:11 +0000 Subject: Stop routine clearing of CHANNEL_EOF. Only clear when there's a reason (seek, eofchar change, ungets). Otherwise, once you hit EOF you stay there. --- generic/tclIO.c | 24 ++++++------------------ 1 file changed, 6 insertions(+), 18 deletions(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index b423bcc..1a56811 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -4837,7 +4837,6 @@ Tcl_ReadRaw( int nread, result, copied, copiedNow; /* - * TODO VERIFY * The check below does too much because it will reject a call to this * function with a channel which is part of an 'fcopy'. But we have to * allow this here or else the chaining in the transformation drivers will @@ -5742,16 +5741,11 @@ Tcl_Ungets( statePtr->flags = flags; /* - * If we have encountered a sticky EOF, just punt without storing (sticky - * EOF is set if we have seen the input eofChar, to prevent reading beyond - * the eofChar). Otherwise, clear the EOF flags, and clear the BLOCKED - * bit. We want to discover these conditions anew in each operation. + * Clear the EOF flags, and clear the BLOCKED bit. */ - if (statePtr->flags & CHANNEL_STICKY_EOF) { - goto done; - } - ResetFlag(statePtr, CHANNEL_BLOCKED | CHANNEL_EOF); + ResetFlag(statePtr, + CHANNEL_BLOCKED | CHANNEL_STICKY_EOF | CHANNEL_EOF | INPUT_SAW_CR); bufPtr = AllocChannelBuffer(len); memcpy(InsertPoint(bufPtr), str, (size_t) len); @@ -6001,7 +5995,7 @@ GetInput( } /* - * TODO + * TODO - consider escape before buffer alloc * If EOF is set, we should avoid calling the driver because on some * platforms it is impossible to read from a device after EOF. */ @@ -6523,16 +6517,10 @@ CheckChannelErrors( if (direction == TCL_READABLE) { /* - * TODO - * If we have not encountered a sticky EOF, clear the EOF bit (sticky - * EOF is set if we have seen the input eofChar, to prevent reading - * beyond the eofChar). Also, always clear the BLOCKED bit. We want to - * discover these conditions anew in each operation. + * Clear the BLOCKED bit. We want to discover this condition + * anew in each operation. */ - if ((statePtr->flags & CHANNEL_STICKY_EOF) == 0) { - ResetFlag(statePtr, CHANNEL_EOF); - } ResetFlag(statePtr, CHANNEL_BLOCKED | CHANNEL_NEED_MORE_DATA); } -- cgit v0.12 From c6fabad70e61ae53d00b6b3dd252b5526aa5355f Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 20 Mar 2014 20:18:20 +0000 Subject: Don't allow buffer recycling to prevent or delay buffersize shrinkage. --- generic/tclIO.c | 68 ++++++++++++++++++++++++--------------------------------- 1 file changed, 28 insertions(+), 40 deletions(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index 1a56811..e7653f6 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -2255,13 +2255,12 @@ RecycleBuffer( } /* - * TODO - * Only save buffers which are at least as big as the requested buffersize - * for the channel. This is to honor dynamic changes of the buffersize + * Only save buffers which have the requested buffersize for the + * channel. This is to honor dynamic changes of the buffersize * made by the user. */ - if ((bufPtr->bufLength - BUFFER_PADDING) < statePtr->bufSize) { + if ((bufPtr->bufLength - BUFFER_PADDING) != statePtr->bufSize) { ckfree((char *) bufPtr); return; } @@ -5952,14 +5951,13 @@ GetInput( statePtr->saveInBufPtr = NULL; /* - * TODO * Check the actual buffersize against the requested buffersize. - * Buffers which are smaller than requested are squashed. This is done + * Saved buffers of the wrong size are squashed. This is done * to honor dynamic changes of the buffersize made by the user. */ if ((bufPtr != NULL) - && (bufPtr->bufLength - BUFFER_PADDING < statePtr->bufSize)) { + && (bufPtr->bufLength - BUFFER_PADDING != statePtr->bufSize)) { ckfree((char *) bufPtr); bufPtr = NULL; } @@ -5969,22 +5967,8 @@ GetInput( } bufPtr->nextPtr = NULL; - /* - * TODO - * SF #427196: Use the actual size of the buffer to determine the - * number of bytes to read from the channel and not the size for new - * buffers. They can be different if the buffersize was changed - * between reads. - * - * Note: This affects performance negatively if the buffersize was - * extended but this small buffer is reused for all subsequent reads. - * The system never uses buffers with the requested bigger size in - * that case. An adjunct patch could try and delete all unused buffers - * it encounters and which are smaller than the formally requested - * buffersize. - */ - toRead = SpaceLeft(bufPtr); + assert(toRead == statePtr->bufSize); if (statePtr->inQueueTail == NULL) { statePtr->inQueueHead = bufPtr; @@ -6727,7 +6711,6 @@ Tcl_SetChannelBufferSize( ChannelState *statePtr; /* State of real channel structure. */ /* - * TODO * Clip the buffer size to force it into the [1,1M] range */ @@ -6738,7 +6721,27 @@ Tcl_SetChannelBufferSize( } statePtr = ((Channel *) chan)->state; + + if (statePtr->bufSize == sz) { + return; + } statePtr->bufSize = sz; + + /* + * If bufsize changes, need to get rid of old utility buffer. + */ + + if (statePtr->saveInBufPtr != NULL) { + RecycleBuffer(statePtr, statePtr->saveInBufPtr, 1); + statePtr->saveInBufPtr = NULL; + } + if ((statePtr->inQueueHead != NULL) + && (statePtr->inQueueHead->nextPtr == NULL) + && IsBufferEmpty(statePtr->inQueueHead)) { + RecycleBuffer(statePtr, statePtr->inQueueHead, 1); + statePtr->inQueueHead = NULL; + statePtr->inQueueTail = NULL; + } } /* @@ -7172,6 +7175,7 @@ Tcl_SetChannelOption( return TCL_ERROR; } Tcl_SetChannelBufferSize(chan, newBufferSize); + return TCL_OK; } else if (HaveOpt(2, "-encoding")) { Tcl_Encoding encoding; @@ -7202,6 +7206,7 @@ Tcl_SetChannelOption( statePtr->outputEncodingFlags = TCL_ENCODING_START; ResetFlag(statePtr, CHANNEL_NEED_MORE_DATA); UpdateInterest(chanPtr); + return TCL_OK; } else if (HaveOpt(2, "-eofchar")) { if (Tcl_SplitList(interp, newValue, &argc, &argv) == TCL_ERROR) { return TCL_ERROR; @@ -7363,23 +7368,6 @@ Tcl_SetChannelOption( return Tcl_BadChannelOption(interp, optionName, NULL); } - /* - * TODO - * If bufsize changes, need to get rid of old utility buffer. - */ - - if (statePtr->saveInBufPtr != NULL) { - RecycleBuffer(statePtr, statePtr->saveInBufPtr, 1); - statePtr->saveInBufPtr = NULL; - } - if ((statePtr->inQueueHead != NULL) - && (statePtr->inQueueHead->nextPtr == NULL) - && IsBufferEmpty(statePtr->inQueueHead)) { - RecycleBuffer(statePtr, statePtr->inQueueHead, 1); - statePtr->inQueueHead = NULL; - statePtr->inQueueTail = NULL; - } - return TCL_OK; } -- cgit v0.12 From e9bb48106af82e24cbd802a9b0b7f1eec6717679 Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 20 Mar 2014 23:21:48 +0000 Subject: Both callers of ChanRead() have simlar epilogs. Shift that into ChanRead and refactor. --- generic/tclIO.c | 123 +++++++++++++++++++++++--------------------------------- 1 file changed, 50 insertions(+), 73 deletions(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index e7653f6..18dab5a 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -348,15 +348,39 @@ static inline int ChanRead( Channel *chanPtr, char *dst, - int dstSize, - int *errnoPtr) + int dstSize) { + int bytesRead, result; + if (WillRead(chanPtr) < 0) { return -1; } - return chanPtr->typePtr->inputProc(chanPtr->instanceData, dst, dstSize, - errnoPtr); + bytesRead = chanPtr->typePtr->inputProc(chanPtr->instanceData, + dst, dstSize, &result); + + if (bytesRead > 0) { + /* + * If we get a short read, signal up that we may be BLOCKED. We should + * avoid calling the driver because on some platforms we will block in + * the low level reading code even though the channel is set into + * nonblocking mode. + */ + + if (bytesRead < dstSize) { + SetFlag(chanPtr->state, CHANNEL_BLOCKED); + } + } else if (bytesRead == 0) { + SetFlag(chanPtr->state, CHANNEL_EOF); + chanPtr->state->inputEncodingFlags |= TCL_ENCODING_END; + } else { /* bytesRead < 0 */ + if ((result == EWOULDBLOCK) || (result == EAGAIN)) { + SetFlag(chanPtr->state, CHANNEL_BLOCKED); + result = EAGAIN; + } + Tcl_SetErrno(result); + } + return bytesRead; } static inline Tcl_WideInt @@ -4833,7 +4857,7 @@ Tcl_ReadRaw( Channel *chanPtr = (Channel *) chan; ChannelState *statePtr = chanPtr->state; /* State info for channel */ - int nread, result, copied, copiedNow; + int nread, copied, copiedNow; /* * The check below does too much because it will reject a call to this @@ -4862,11 +4886,11 @@ Tcl_ReadRaw( bytesToRead - copied); if (copiedNow == 0) { if (statePtr->flags & CHANNEL_EOF) { - goto done; + break; } if (statePtr->flags & CHANNEL_BLOCKED) { if (statePtr->flags & CHANNEL_NONBLOCKING) { - goto done; + break; } ResetFlag(statePtr, CHANNEL_BLOCKED); } @@ -4881,48 +4905,21 @@ Tcl_ReadRaw( * happen. */ - nread = ChanRead(chanPtr, bufPtr + copied, - bytesToRead - copied, &result); - - if (nread > 0) { - /* - * If we get a short read, signal up that we may be BLOCKED. - * We should avoid calling the driver because on some - * platforms we will block in the low level reading code even - * though the channel is set into nonblocking mode. - */ - - if (nread < (bytesToRead - copied)) { - SetFlag(statePtr, CHANNEL_BLOCKED); - } - } else if (nread == 0) { - SetFlag(statePtr, CHANNEL_EOF); - statePtr->inputEncodingFlags |= TCL_ENCODING_END; - - } else if (nread < 0) { - if ((result == EWOULDBLOCK) || (result == EAGAIN)) { - if (copied > 0) { - /* - * Information that was copied earlier has precedence - * over EAGAIN/WOULDBLOCK handling. - */ - - return copied; - } + nread = ChanRead(chanPtr, bufPtr+copied, bytesToRead-copied); - SetFlag(statePtr, CHANNEL_BLOCKED); - result = EAGAIN; + if (nread < 0) { + if (statePtr->flags & CHANNEL_BLOCKED && copied > 0) { + ResetFlag(statePtr, CHANNEL_BLOCKED); + break; } - - Tcl_SetErrno(result); return -1; } - return copied + nread; + copied += nread; + break; } } - done: return copied; } @@ -5019,7 +5016,7 @@ DoReadChars( ChannelState *statePtr = chanPtr->state; /* State info for channel */ ChannelBuffer *bufPtr; - int factor, copied, copiedNow, result; + int factor, copied, copiedNow; Tcl_Encoding encoding; int binaryMode; #define UTF_EXPANSION_FACTOR 1024 @@ -5090,9 +5087,8 @@ DoReadChars( } ResetFlag(statePtr, CHANNEL_BLOCKED); } - result = GetInput(chanPtr); - if (result != 0) { - if (result == EAGAIN) { + if (GetInput(chanPtr) != 0) { + if (statePtr->flags & CHANNEL_BLOCKED) { break; } copied = -1; @@ -5883,8 +5879,9 @@ DiscardInputQueued( * that is the top channel of a stack! * * Results: - * The return value is the Posix error code if an error occurred while - * reading from the file, or 0 otherwise. + * The return value is 0 to indicate success, or -1 if an error + * occurred while reading from the channel. Call Tcl_GetErrno() + * to get the Posix error code. * * Side effects: * Reads from the underlying device. @@ -5897,7 +5894,6 @@ GetInput( Channel *chanPtr) /* Channel to read input from. */ { int toRead; /* How much to read? */ - int result; /* Of calling driver. */ int nread; /* How much was read from channel? */ ChannelBuffer *bufPtr; /* New buffer to add to input queue. */ ChannelState *statePtr = chanPtr->state; @@ -5911,7 +5907,8 @@ GetInput( */ if (CheckForDeadChannel(NULL, statePtr)) { - return EINVAL; + Tcl_SetErrno(EINVAL); + return -1; } /* @@ -5988,31 +5985,11 @@ GetInput( return 0; } - nread = ChanRead(chanPtr, InsertPoint(bufPtr), toRead, &result); - if (nread > 0) { - bufPtr->nextAdded += nread; - - /* - * If we get a short read, signal up that we may be BLOCKED. We should - * avoid calling the driver because on some platforms we will block in - * the low level reading code even though the channel is set into - * nonblocking mode. - */ - - if (nread < toRead) { - SetFlag(statePtr, CHANNEL_BLOCKED); - } - } else if (nread == 0) { - SetFlag(statePtr, CHANNEL_EOF); - statePtr->inputEncodingFlags |= TCL_ENCODING_END; - } else if (nread < 0) { - if ((result == EWOULDBLOCK) || (result == EAGAIN)) { - SetFlag(statePtr, CHANNEL_BLOCKED); - result = EAGAIN; - } - Tcl_SetErrno(result); - return result; + nread = ChanRead(chanPtr, InsertPoint(bufPtr), toRead); + if (nread < 0) { + return -1; } + bufPtr->nextAdded += nread; return 0; } -- cgit v0.12 From 0530d01b6322bcec62e77511414d2f76204c693c Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 21 Mar 2014 02:36:47 +0000 Subject: Documentation header for ChanRead() --- generic/tclIO.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index 18dab5a..6e5dc05 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -342,9 +342,30 @@ static Tcl_ObjType chanObjType = { #define MAX_CHANNEL_BUFFER_SIZE (1024*1024) /* - * ChanRead, dropped here by a time traveler, see 8.6 + *--------------------------------------------------------------------------- + * + * ChanRead -- + * + * Read up to bytes using the inputProc of chanPtr, store them at dst, + * and return the number of bytes stored. + * + * Results: + * The return value of the driver inputProc, + * - number of bytes stored at dst, or + * - -1 on error, with a Posix error code available to the + * caller by calling Tcl_GetErrno(). + * + * Side effects: + * The CHANNEL_BLOCKED and CHANNEL_EOF flags of the channel + * state are set as appropriate. + * On EOF, the inputEncodingFlags are set to perform ending + * operations on decoding. + * TODO - Is this really the right place for that? + * + *--------------------------------------------------------------------------- */ -static inline int + +static int ChanRead( Channel *chanPtr, char *dst, -- cgit v0.12 From 2a7cf86d3009255dc8f6a2a7d327c76b5ca231f7 Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 21 Mar 2014 12:56:46 +0000 Subject: io-34.21 - fix bugs in normally skipped test. io-35.18b - knownBug is not buggy on this branch. --- tests/io.test | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/io.test b/tests/io.test index cedb337..7f1a357 100644 --- a/tests/io.test +++ b/tests/io.test @@ -41,7 +41,7 @@ testConstraint testthread [llength [info commands testthread]] # You need a *very* special environment to do some tests. In # particular, many file systems do not support large-files... -testConstraint largefileSupport 0 +testConstraint largefileSupport 1 # some tests can only be run is umask is 2 # if "umask" cannot be run, the tests will be skipped. @@ -4433,10 +4433,10 @@ test io-34.21 {Tcl_Seek and Tcl_Tell on large files} {largefileSupport} { puts -nonewline $f abcdef lappend l [tell $f] close $f - lappend l [file size $f] + lappend l [file size $path(test3)] # truncate... close [open $path(test3) w] - lappend l [file size $f] + lappend l [file size $path(test3)] set l } {0 6 6 4294967296 4294967302 4294967302 0} @@ -4729,7 +4729,7 @@ test io-35.18a {Tcl_Eof, eof char, cr write, crlf read} -body { close $f list $s $l $e [scan [string index $in end] %c] } -result {9 8 1 13} -test io-35.18b {Tcl_Eof, eof char, cr write, crlf read} -constraints knownBug -body { +test io-35.18b {Tcl_Eof, eof char, cr write, crlf read} -body { file delete $path(test1) set f [open $path(test1) w] fconfigure $f -translation cr -eofchar \x1a -- cgit v0.12 From ff8fef8c8dda63391a0c88c52f35ff191cbed302 Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 21 Mar 2014 12:57:58 +0000 Subject: Fixup ChanRead() header. Note (dstSize > 0) precondition. --- generic/tclIO.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index 6e5dc05..e7eaefa 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -346,8 +346,8 @@ static Tcl_ObjType chanObjType = { * * ChanRead -- * - * Read up to bytes using the inputProc of chanPtr, store them at dst, - * and return the number of bytes stored. + * Read up to dstsize bytes using the inputProc of chanPtr, store + * them at dst, and return the number of bytes stored. * * Results: * The return value of the driver inputProc, @@ -373,6 +373,12 @@ ChanRead( { int bytesRead, result; + /* + * If the caller asked for zero bytes, we'd force the inputProc + * to return zero bytes, and then misinterpret that as EOF + */ + assert(dstSize > 0); + if (WillRead(chanPtr) < 0) { return -1; } -- cgit v0.12 From 183b5fd25792ef145ff6c8e8a2df3559dddf2d49 Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 21 Mar 2014 12:58:29 +0000 Subject: Restore default suppression of large file test. --- tests/io.test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/io.test b/tests/io.test index 7f1a357..bfe6051 100644 --- a/tests/io.test +++ b/tests/io.test @@ -41,7 +41,7 @@ testConstraint testthread [llength [info commands testthread]] # You need a *very* special environment to do some tests. In # particular, many file systems do not support large-files... -testConstraint largefileSupport 1 +testConstraint largefileSupport 0 # some tests can only be run is umask is 2 # if "umask" cannot be run, the tests will be skipped. -- cgit v0.12 From 88cddf0b808cb97bab7185156cf61b239e8abbe5 Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 21 Mar 2014 13:20:06 +0000 Subject: Convert "impossible" test to a "knownBug" test. Exposes a segfault! --- tests/ioCmd.test | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/tests/ioCmd.test b/tests/ioCmd.test index 768a748..8f0bfbf 100644 --- a/tests/ioCmd.test +++ b/tests/ioCmd.test @@ -1927,6 +1927,8 @@ test iocmd-32.0 {origin interpreter of moved channel gone} -match glob -body { test iocmd-32.1 {origin interpreter of moved channel destroyed during access} -match glob -body { + # This test segfaults; Ought to fix that. + set ida [interp create];#puts <<$ida>> set idb [interp create];#puts <<$idb>> @@ -1940,13 +1942,12 @@ test iocmd-32.1 {origin interpreter of moved channel destroyed during access} -m proc foo {args} { oninit; onfinal; track; # destroy interpreter during channel access - # Actually not possible for an interp to destroy itself. - interp delete {} - return} + suicide} set chan [chan create {r w} foo] fconfigure $chan -buffering none set chan }] + interp alias $ida suicide {} interp delete $ida # Move channel to 2nd thread. interp eval $ida [list testchannel cut $chan] @@ -1965,7 +1966,7 @@ test iocmd-32.1 {origin interpreter of moved channel destroyed during access} -m set res }] set res -} -constraints {testchannel impossible} \ +} -constraints {testchannel knownBug} \ -result {Owner lost} test iocmd-32.2 {delete interp of reflected chan} { -- cgit v0.12 From 56214ea49a63010fb49b064e8e8eb3d953517a9f Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 21 Mar 2014 13:40:58 +0000 Subject: Added comment explaining the "knownBug" --- tests/iogt.test | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/iogt.test b/tests/iogt.test index 3882ecc..3b94747 100644 --- a/tests/iogt.test +++ b/tests/iogt.test @@ -916,6 +916,15 @@ test iogt-6.0 {Push back} testchannel { } {xxx} test iogt-6.1 {Push back and up} {testchannel knownBug} { + + # This test demonstrates the bug/misfeature in the stacked + # channel implementation that data can be discarded if it is + # read into the buffers of one channel in the stack, and then + # that channel is popped before anything above it reads. + # + # This bug can be worked around by always setting -buffersize + # to 1, but who wants to do that? + set f [open $path(dummy) r] # contents of dummy = "abcdefghi..." -- cgit v0.12 From 4d2bb24e845c799e6478418d097923f198ca84af Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 21 Mar 2014 14:07:40 +0000 Subject: Correct namespace bugs in normally skipped tests. Constrain them as "knownBug" rather than "unknownFailure". --- tests/iogt.test | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/tests/iogt.test b/tests/iogt.test index 3b94747..0a25418 100644 --- a/tests/iogt.test +++ b/tests/iogt.test @@ -159,8 +159,8 @@ proc fevent {fdelay idelay blocks script data} { #puts stdout ">>>>>" ; flush stdout - uplevel #0 set sock $sk - set res [uplevel #0 $script] + uplevel 1 set sock $sk + set res [uplevel 1 $script] catch {close $sk} return $res @@ -634,7 +634,7 @@ delete/write {} *ignored*} test iogt-3.0 {Tcl_Channel valid after stack/unstack, fevent handling} \ - {testchannel unknownFailure} { + {testchannel knownBug} { # This test to check the validity of aquired 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 @@ -651,6 +651,7 @@ test iogt-3.0 {Tcl_Channel valid after stack/unstack, fevent handling} \ set fin [open $path(dummy) r] fevent 1000 500 {20 20 20 10 1 1} { + variable copy close $fin set fout [open dummyout w] @@ -688,7 +689,7 @@ test iogt-3.0 {Tcl_Channel valid after stack/unstack, fevent handling} \ } {1 {create/write create/read write flush/write flush/read delete/write delete/read}} -test iogt-4.0 {fileevent readable, after transform} {testchannel unknownFailure} { +test iogt-4.0 {fileevent readable, after transform} {testchannel knownBug} { set fin [open $path(dummy) r] set data [read $fin] close $fin @@ -718,10 +719,11 @@ test iogt-4.0 {fileevent readable, after transform} {testchannel unknownFailure} } fevent 1000 500 {20 20 20 10 1} { + variable stop audit_flow trail -attach $sock rblocks_t rbuf trail 23 -attach $sock - fileevent $sock readable [list Get $sock] + fileevent $sock readable [namespace code [list Get $sock]] flush $sock ; # now, or fcopy will error us out # But the 1 second delay should be enough to @@ -819,7 +821,7 @@ delete/write {} *ignored* delete/read {} *ignored*} ; # catch unescaped quote " -test iogt-5.0 {EOF simulation} {testchannel unknownFailure} { +test iogt-5.0 {EOF simulation} {testchannel knownBug} { set fin [open $path(dummy) r] set fout [open $path(dummyout) w] -- cgit v0.12 From 71680aec07053532b34eda5bda040da83c35bc50 Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 21 Mar 2014 14:45:00 +0000 Subject: missing declaration --- generic/tclIO.c | 1 + 1 file changed, 1 insertion(+) diff --git a/generic/tclIO.c b/generic/tclIO.c index e7eaefa..a62f80e 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -165,6 +165,7 @@ typedef struct CloseCallback { static ChannelBuffer * AllocChannelBuffer(int length); static void ChannelTimerProc(ClientData clientData); +static int ChanRead(Channel *chanPtr, char *dst, int dstSize); static int CheckChannelErrors(ChannelState *statePtr, int direction); static int CheckForDeadChannel(Tcl_Interp *interp, -- cgit v0.12 From 15df01c93d14aa590853f8de9e5014cb1489fa09 Mon Sep 17 00:00:00 2001 From: ferrieux Date: Mon, 24 Mar 2014 21:42:56 +0000 Subject: Add test io-53.12 to verify proper unbuffered sync-fcopy [Bug #3096275] --- tests/io.test | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/tests/io.test b/tests/io.test index 19cd9a5..d3f249c 100644 --- a/tests/io.test +++ b/tests/io.test @@ -7450,6 +7450,25 @@ test io-53.11 {Bug 2895565} -setup { removeFile out removeFile in } -result {40 bytes copied} +test io-53.12 {CopyData: foreground short reads, aka bug 3096275} {stdio unix openpipe fcopy} { + file delete $path(pipe) + set f1 [open $path(pipe) w] + puts -nonewline $f1 { + fconfigure stdin -translation binary -blocking 0 + fconfigure stdout -buffering none -translation binary + fcopy stdin stdout + } + close $f1 + set f1 [open "|[list [interpreter] $path(pipe)]" r+] + fconfigure $f1 -translation binary -buffering none + puts -nonewline $f1 A + after 2000 {set ::done timeout} + fileevent $f1 readable {set ::done ok} + vwait ::done + set ch [read $f1 1] + close $f1 + list $::done $ch +} {ok A} test io-54.1 {Recursive channel events} {socket fileevent} { # This test checks to see if file events are delivered during recursive -- cgit v0.12 From 269a88ebaf3152969fa5c01b427a1b524fc51d0a Mon Sep 17 00:00:00 2001 From: oehhar Date: Fri, 4 Apr 2014 16:27:39 +0000 Subject: Avoid multiple returns of connect errors --- win/tclWinSock.c | 146 +++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 103 insertions(+), 43 deletions(-) diff --git a/win/tclWinSock.c b/win/tclWinSock.c index 036f3b9..ed9fa32 100644 --- a/win/tclWinSock.c +++ b/win/tclWinSock.c @@ -172,7 +172,7 @@ struct TcpState { struct addrinfo *addr; /* Iterator over addrlist. */ struct addrinfo *myaddrlist;/* Local address. */ struct addrinfo *myaddr; /* Iterator over myaddrlist. */ - int status; /* Cache status of async socket. */ + int error; /* Cache status of async socket. */ int cachedBlocking; /* Cache blocking mode of async socket. */ volatile int connectError; /* Async connect error set by notifier thread. * Set by notifier thread, access must be @@ -255,8 +255,7 @@ static LRESULT CALLBACK SocketProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); static int SocketsEnabled(void); static void TcpAccept(TcpFdList *fds, SOCKET newSocket, address addr); -static int WaitForConnect(TcpState *statePtr, int *errorCodePtr, - int noblock); +static int WaitForConnect(TcpState *statePtr, int *errorCodePtr); static int WaitForSocketEvent(TcpState *statePtr, int events, int *errorCodePtr); static void AddSocketInfoFd(TcpState *statePtr, SOCKET socket); @@ -573,8 +572,13 @@ TcpBlockModeProc( static int WaitForConnect( TcpState *statePtr, /* State of the socket. */ - int *errorCodePtr, /* Where to store errors? */ - int noblock) /* Don't wait, even for sockets in blocking mode */ + int *errorCodePtr) /* Where to store errors? + * A passed null-pointer activates background mode. + * In this case, an eventual error is stored in + * statePtr->error. + * In addition, we do never block and allow a next + * processing cycle to happen. + */ { int result; int oldMode; @@ -605,10 +609,11 @@ WaitForConnect( statePtr->readyEvents &= ~(FD_CONNECT); /* - * For blocking sockets disable async connect - * as we continue now synchoneously + * For blocking sockets and foreground processing + * disable async connect as we continue now synchoneously */ - if ( !(noblock || (statePtr->flags & TCP_ASYNC_SOCKET)) ) { + if ( errorCodePtr != NULL && + ! (statePtr->flags & TCP_ASYNC_SOCKET) ) { CLEAR_BITS(statePtr->flags, TCP_ASYNC_CONNECT); } @@ -624,13 +629,19 @@ WaitForConnect( /* Succesfully connected or async connect restarted */ if (result == TCL_OK) { if ( statePtr->flags & TCP_ASYNC_CONNECT_REENTER_PENDING ) { - *errorCodePtr = EWOULDBLOCK; + if (errorCodePtr != NULL) { + *errorCodePtr = EWOULDBLOCK; + } return -1; } return 0; } /* error case */ - *errorCodePtr = Tcl_GetErrno(); + if (errorCodePtr != NULL) { + *errorCodePtr = Tcl_GetErrno(); + } else { + statePtr->error = Tcl_GetErrno(); + } return -1; } @@ -641,7 +652,11 @@ WaitForConnect( * A non blocking socket waiting for an asyncronous connect * returns directly an error */ - if ( noblock || (statePtr->flags & TCP_ASYNC_SOCKET) ) { + if ( errorCodePtr == NULL ) { + /* Backround operation */ + return -1; + } else if (statePtr->flags & TCP_ASYNC_SOCKET) { + /* foreground operation but non blocking socket */ *errorCodePtr = EWOULDBLOCK; return -1; } @@ -715,7 +730,7 @@ TcpInputProc( * For a non blocking socket return EWOULDBLOCK if connect not terminated */ - if (WaitForConnect(statePtr, errorCodePtr, 0) != 0) { + if (WaitForConnect(statePtr, errorCodePtr) != 0) { return -1; } @@ -844,7 +859,7 @@ TcpOutputProc( * For a non blocking socket return EWOULDBLOCK if connect not terminated */ - if (WaitForConnect(statePtr, errorCodePtr, 0) != 0) { + if (WaitForConnect(statePtr, errorCodePtr) != 0) { return -1; } @@ -1184,7 +1199,7 @@ TcpGetOptionProc( char host[NI_MAXHOST], port[NI_MAXSERV]; SOCKET sock; size_t len = 0; - int errorCode; + int errorCode = 0; int reverseDNS = 0; #define SUPPRESS_RDNS_VAR "::tcl::unsupported::noReverseDNS" @@ -1202,8 +1217,11 @@ TcpGetOptionProc( return TCL_ERROR; } - /* Go one step in async connect */ - WaitForConnect(statePtr, &errorCode, 1); + /* + * Go one step in async connect + * If any error is thrown save it as backround error to report eventually below + */ + WaitForConnect(statePtr, NULL); sock = statePtr->sockets->fd; if (optionName != NULL) { @@ -1216,30 +1234,52 @@ TcpGetOptionProc( /* * Do not return any errors if async connect is running */ - if (! (statePtr->flags & TCP_ASYNC_CONNECT_REENTER_PENDING) ) { - int optlen; - int ret; - DWORD err; + if ( ! (statePtr->flags & TCP_ASYNC_CONNECT_REENTER_PENDING) ) { - /* - * Populater the err Variable with a possix error - */ - optlen = sizeof(int); - ret = TclWinGetSockOpt(sock, SOL_SOCKET, SO_ERROR, - (char *)&err, &optlen); - /* - * The error was not returned directly but should be - * taken from WSA - */ - if (ret == SOCKET_ERROR) { - err = WSAGetLastError(); - } - /* - * Return error message - */ - if (err) { - TclWinConvertError(err); - Tcl_DStringAppend(dsPtr, Tcl_ErrnoMsg(Tcl_GetErrno()), -1); + + if ( statePtr->flags & TCP_ASYNC_CONNECT_FAILED ) { + + /* + * In case of a failed async connect, eventually report the + * connect error only once. + * Do not report the system error, as this comes again and again. + */ + + if ( statePtr->error != 0 ) { + Tcl_DStringAppend(dsPtr, Tcl_ErrnoMsg(statePtr->error), -1); + statePtr->error = 0; + } + + } else { + + /* + * Report an eventual last error of the socket system + */ + + int optlen; + int ret; + DWORD err; + + /* + * Populater the err Variable with a possix error + */ + optlen = sizeof(int); + ret = TclWinGetSockOpt(sock, SOL_SOCKET, SO_ERROR, + (char *)&err, &optlen); + /* + * The error was not returned directly but should be + * taken from WSA + */ + if (ret == SOCKET_ERROR) { + err = WSAGetLastError(); + } + /* + * Return error message + */ + if (err) { + TclWinConvertError(err); + Tcl_DStringAppend(dsPtr, Tcl_ErrnoMsg(Tcl_GetErrno()), -1); + } } } return TCL_OK; @@ -2555,16 +2595,36 @@ SocketEventProc( return 1; } + /* + * Clear flag that (this) event is pending + */ + statePtr->flags &= ~SOCKET_PENDING; - /* Continue async connect if pending and ready */ + /* + * Continue async connect if pending and ready + */ + if ( statePtr->readyEvents & FD_CONNECT ) { - statePtr->readyEvents &= ~(FD_CONNECT); if ( statePtr->flags & TCP_ASYNC_CONNECT_REENTER_PENDING ) { + + /* + * Do one step and save eventual connect error + */ + + SetEvent(tsdPtr->socketListLock); + WaitForConnect(statePtr,NULL); + + } else { + + /* + * No async connect reenter pending. Just clear event. + */ + + statePtr->readyEvents &= ~(FD_CONNECT); SetEvent(tsdPtr->socketListLock); - CreateClientSocket(NULL, statePtr); - return 1; } + return 1; } /* -- cgit v0.12 From d0e001a334ba54ee8a911997f0cce16dcab4176b Mon Sep 17 00:00:00 2001 From: oehhar Date: Mon, 7 Apr 2014 12:34:18 +0000 Subject: Return async connect error by first following read or write operation. --- win/tclWinSock.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/win/tclWinSock.c b/win/tclWinSock.c index ed9fa32..b05dc32 100644 --- a/win/tclWinSock.c +++ b/win/tclWinSock.c @@ -585,11 +585,22 @@ WaitForConnect( ThreadSpecificData *tsdPtr; /* + * Check if an async connect error is not jet reported. + * If yes, report it now. + */ + + if ( errorCodePtr != NULL && statePtr->error != 0 ) { + *errorCodePtr = statePtr->error; + statePtr->error = 0; + return -1; + } + + /* * Check if an async connect is running. If not return ok */ if ( !(statePtr->flags & TCP_ASYNC_CONNECT_REENTER_PENDING) ) return 0; - + /* * Be sure to disable event servicing so we are truly modal. */ -- cgit v0.12 From 3d4fa091022cad368491a90e859e2783ba3ccd17 Mon Sep 17 00:00:00 2001 From: oehhar Date: Mon, 7 Apr 2014 15:08:31 +0000 Subject: Renamed function CreateClientSocket to TcpConnect and variable error to connectError --- win/tclWinSock.c | 51 ++++++++++++++++++++++++++++----------------------- 1 file changed, 28 insertions(+), 23 deletions(-) diff --git a/win/tclWinSock.c b/win/tclWinSock.c index b05dc32..7593396 100644 --- a/win/tclWinSock.c +++ b/win/tclWinSock.c @@ -172,11 +172,10 @@ struct TcpState { struct addrinfo *addr; /* Iterator over addrlist. */ struct addrinfo *myaddrlist;/* Local address. */ struct addrinfo *myaddr; /* Iterator over myaddrlist. */ - int error; /* Cache status of async socket. */ + int connectError; /* Cache status of async socket. */ int cachedBlocking; /* Cache blocking mode of async socket. */ volatile int connectError; /* Async connect error set by notifier thread. - * Set by notifier thread, access must be - * protected by semaphore */ + * Access must be protected by semaphore */ struct TcpState *nextPtr; /* The next socket on the per-thread socket * list. */ }; @@ -193,7 +192,7 @@ struct TcpState { #define SOCKET_PENDING (1<<3) /* A message has been sent for this * socket */ #define TCP_ASYNC_CONNECT_REENTER_PENDING (1<<4) - /* CreateClientSocket was called to + /* TcpConnect was called to * process an async connect. This * flag indicates that reentry is * still pending */ @@ -246,7 +245,7 @@ static WNDCLASS windowClass; * Static routines for this file: */ -static int CreateClientSocket(Tcl_Interp *interp, +static int TcpConnect(Tcl_Interp *interp, TcpState *state); static void InitSockets(void); static TcpState * NewSocketInfo(SOCKET socket); @@ -553,10 +552,14 @@ TcpBlockModeProc( * * WaitForConnect -- * - * Wait for a connection on an asynchronously opened socket to be - * completed. In nonblocking mode, just test if the connection - * has completed without blocking. The noblock parameter allows to - * enforce nonblocking behaviour even on sockets in blocking mode. + * Check the state of an async connect process. If a connection + * attempt terminated, process it, which may finalize it or may + * start the next attempt. + * There are two modes of operation, defined by errorCodePtr: + * * non-NULL: Called by explicite read/write command. block if + * socket is blocking. Return a possible error and clear it. + * * Null: Called by a backround operation. Never block and + * save eventual error in statePtr->connectError. * * Results: * 0 if the connection has completed, -1 if still in progress @@ -574,9 +577,9 @@ WaitForConnect( TcpState *statePtr, /* State of the socket. */ int *errorCodePtr) /* Where to store errors? * A passed null-pointer activates background mode. - * In this case, an eventual error is stored in - * statePtr->error. - * In addition, we do never block and allow a next + * In this case, a possible error is stored in + * statePtr->connectError. + * In addition, we do never block and allow the next * processing cycle to happen. */ { @@ -589,15 +592,16 @@ WaitForConnect( * If yes, report it now. */ - if ( errorCodePtr != NULL && statePtr->error != 0 ) { - *errorCodePtr = statePtr->error; - statePtr->error = 0; + if ( errorCodePtr != NULL && statePtr->connectError != 0 ) { + *errorCodePtr = statePtr->connectError; + statePtr->connectError = 0; return -1; } /* * Check if an async connect is running. If not return ok */ + if ( !(statePtr->flags & TCP_ASYNC_CONNECT_REENTER_PENDING) ) return 0; @@ -632,7 +636,7 @@ WaitForConnect( SetEvent(tsdPtr->socketListLock); /* continue connect */ - result = CreateClientSocket(NULL, statePtr); + result = TcpConnect(NULL, statePtr); /* Restore event service mode */ (void) Tcl_SetServiceMode(oldMode); @@ -651,7 +655,7 @@ WaitForConnect( if (errorCodePtr != NULL) { *errorCodePtr = Tcl_GetErrno(); } else { - statePtr->error = Tcl_GetErrno(); + statePtr->connectError = Tcl_GetErrno(); } return -1; } @@ -1256,9 +1260,10 @@ TcpGetOptionProc( * Do not report the system error, as this comes again and again. */ - if ( statePtr->error != 0 ) { - Tcl_DStringAppend(dsPtr, Tcl_ErrnoMsg(statePtr->error), -1); - statePtr->error = 0; + if ( statePtr->connectError != 0 ) { + Tcl_DStringAppend(dsPtr, + Tcl_ErrnoMsg(statePtr->connectError), -1); + statePtr->connectError = 0; } } else { @@ -1558,7 +1563,7 @@ TcpGetHandleProc( /* *---------------------------------------------------------------------- * - * CreateClientSocket -- + * TcpConnect -- * * This function opens a new socket in client mode. * @@ -1592,7 +1597,7 @@ TcpGetHandleProc( */ static int -CreateClientSocket( +TcpConnect( Tcl_Interp *interp, /* For error reporting; can be NULL. */ TcpState *statePtr) { @@ -1904,7 +1909,7 @@ Tcl_OpenTcpClient( /* * Create a new client socket and wrap it in a channel. */ - if (CreateClientSocket(interp, statePtr) != TCL_OK) { + if (TcpConnect(interp, statePtr) != TCL_OK) { TcpCloseProc(statePtr, NULL); return NULL; } -- cgit v0.12 From 59e40535f513391098cc394813a756239bfeecf2 Mon Sep 17 00:00:00 2001 From: max Date: Mon, 7 Apr 2014 15:11:32 +0000 Subject: Rename CreateClientSocket to TcpConnect --- unix/tclUnixSock.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/unix/tclUnixSock.c b/unix/tclUnixSock.c index d4b7b62..f428811 100644 --- a/unix/tclUnixSock.c +++ b/unix/tclUnixSock.c @@ -110,7 +110,7 @@ struct TcpState { * Static routines for this file: */ -static int CreateClientSocket(Tcl_Interp *interp, +static int TcpConnect(Tcl_Interp *interp, TcpState *state); static void TcpAccept(ClientData data, int mask); static int TcpBlockModeProc(ClientData data, int mode); @@ -409,13 +409,13 @@ WaitForConnect( if (noblock || (statePtr->flags & TCP_ASYNC_SOCKET)) { if (TclUnixWaitForFile(statePtr->fds.fd, TCL_WRITABLE | TCL_EXCEPTION, 0) != 0) { - CreateClientSocket(NULL, statePtr); + TcpConnect(NULL, statePtr); } } else { while (statePtr->flags & TCP_ASYNC_CONNECT) { if (TclUnixWaitForFile(statePtr->fds.fd, TCL_WRITABLE | TCL_EXCEPTION, -1) != 0) { - CreateClientSocket(NULL, statePtr); + TcpConnect(NULL, statePtr); } } } @@ -936,7 +936,7 @@ TcpGetHandleProc( * * TcpAsyncCallback -- * - * Called by the event handler that CreateClientSocket sets up + * Called by the event handler that TcpConnect sets up * internally for [socket -async] to get notified when the * asyncronous connection attempt has succeeded or failed. * @@ -949,13 +949,13 @@ TcpAsyncCallback( * TCL_READABLE, TCL_WRITABLE and * TCL_EXCEPTION. */ { - CreateClientSocket(NULL, clientData); + TcpConnect(NULL, clientData); } /* *---------------------------------------------------------------------- * - * CreateClientSocket -- + * TcpConnect -- * * This function opens a new socket in client mode. * @@ -983,7 +983,7 @@ TcpAsyncCallback( */ static int -CreateClientSocket( +TcpConnect( Tcl_Interp *interp, /* For error reporting; can be NULL. */ TcpState *statePtr) { @@ -1198,7 +1198,7 @@ Tcl_OpenTcpClient( /* * Create a new client socket and wrap it in a channel. */ - if (CreateClientSocket(interp, statePtr) != TCL_OK) { + if (TcpConnect(interp, statePtr) != TCL_OK) { TcpCloseProc(statePtr, NULL); return NULL; } -- cgit v0.12 From e92b34ab12a9ce2b870124bf980fccac62c7bc65 Mon Sep 17 00:00:00 2001 From: max Date: Mon, 7 Apr 2014 15:18:09 +0000 Subject: Rename error to connectError in struct TcpState. --- unix/tclUnixSock.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/unix/tclUnixSock.c b/unix/tclUnixSock.c index f428811..adc6243 100644 --- a/unix/tclUnixSock.c +++ b/unix/tclUnixSock.c @@ -73,7 +73,7 @@ struct TcpState { struct addrinfo *myaddr; /* Iterator over myaddrlist. */ int filehandlers; /* Caches FileHandlers that get set up while * an async socket is not yet connected. */ - int error; /* Cache SO_ERROR of async socket. */ + int connectError; /* Cache SO_ERROR of async socket. */ int cachedBlocking; /* Cache blocking mode of async socket. */ }; @@ -420,7 +420,7 @@ WaitForConnect( } } } - if (statePtr->error != 0) { + if (statePtr->connectError != 0) { return -1; } else { return 0; @@ -463,8 +463,8 @@ TcpInputProc( *errorCodePtr = 0; if (WaitForConnect(statePtr, 0) != 0) { - *errorCodePtr = statePtr->error; - statePtr->error = 0; + *errorCodePtr = statePtr->connectError; + statePtr->connectError = 0; return -1; } bytesRead = recv(statePtr->fds.fd, buf, (size_t) bufSize, 0); @@ -515,8 +515,8 @@ TcpOutputProc( *errorCodePtr = 0; if (WaitForConnect(statePtr, 0) != 0) { - *errorCodePtr = statePtr->error; - statePtr->error = 0; + *errorCodePtr = statePtr->connectError; + statePtr->connectError = 0; return -1; } written = send(statePtr->fds.fd, buf, (size_t) toWrite, 0); @@ -757,9 +757,9 @@ TcpGetOptionProc( if (statePtr->flags & TCP_ASYNC_CONNECT) { /* Suppress errors as long as we are not done */ errno = 0; - } else if (statePtr->error != 0) { - errno = statePtr->error; - statePtr->error = 0; + } else if (statePtr->connectError != 0) { + errno = statePtr->connectError; + statePtr->connectError = 0; } else { int err; getsockopt(statePtr->fds.fd, SOL_SOCKET, SO_ERROR, @@ -1070,7 +1070,7 @@ TcpConnect( if (ret < 0 && errno == EINPROGRESS) { Tcl_CreateFileHandler(statePtr->fds.fd, TCL_WRITABLE|TCL_EXCEPTION, TcpAsyncCallback, statePtr); - statePtr->error = errno = EWOULDBLOCK; + statePtr->connectError = errno = EWOULDBLOCK; return TCL_OK; reenter: @@ -1096,7 +1096,7 @@ TcpConnect( } out: - statePtr->error = error; + statePtr->connectError = error; CLEAR_BITS(statePtr->flags, TCP_ASYNC_CONNECT); if (async_callback) { /* -- cgit v0.12 From 1abf8e4ad80fd58c66ce919eab45b7166424a216 Mon Sep 17 00:00:00 2001 From: oehhar Date: Tue, 8 Apr 2014 14:40:20 +0000 Subject: Changed error report logic, that an async connect error is only reported by 'fconfigure -error' and not by a possible last command terminating the async connect. The terminating command always returns "socket is not connected" on connect error. In addition, some flags were renamed: TCP_ASYNC_SOCKET to TCP_NONBLOCKING and also the new state flags. --- tests/socket.test | 12 ++--- win/tclWinPort.h | 6 +++ win/tclWinSock.c | 146 +++++++++++++++++++++++++++++++++++------------------- 3 files changed, 106 insertions(+), 58 deletions(-) diff --git a/tests/socket.test b/tests/socket.test index d36d2b3..648ade5 100644 --- a/tests/socket.test +++ b/tests/socket.test @@ -1981,10 +1981,10 @@ test socket-14.7.2 {pending [socket -async] and blocking [gets], no listener} \ -body { set sock [socket -async localhost [randport]] catch {gets $sock} x - list $x [fconfigure $sock -error] + list $x [fconfigure $sock -error] [fconfigure $sock -error] } -cleanup { close $sock - } -match glob -result {{error reading "sock*": connection refused} {}} + } -match glob -result {{error reading "sock*": socket is not connected} {connection refused} {}} test socket-14.8.0 {pending [socket -async] and nonblocking [gets], server is IPv4} \ -constraints {socket supported_inet supported_inet6} \ -setup { @@ -2046,10 +2046,10 @@ test socket-14.8.2 {pending [socket -async] and nonblocking [gets], no listener} if {[catch {gets $sock} x] || $x ne "" || ![fblocked $sock]} break after 200 } - list $x [fconfigure $sock -error] + list $x [fconfigure $sock -error] [fconfigure $sock -error] } -cleanup { close $sock - } -match glob -result {{error reading "sock*": connection refused} {}} + } -match glob -result {{error reading "sock*": socket is not connected} {connection refused} {}} test socket-14.9.0 {pending [socket -async] and blocking [puts], server is IPv4} \ -constraints {socket supported_inet supported_inet6} \ -setup { @@ -2164,7 +2164,7 @@ test socket-14.11.0 {pending [socket -async] and blocking [puts], no listener, n } -cleanup { catch {close $sock} unset x - } -result {connection refused} -returnCodes 1 + } -result {socket is not connected} -returnCodes 1 test socket-14.11.1 {pending [socket -async] and blocking [puts], no listener, flush} \ -constraints {socket supported_inet supported_inet6} \ -body { @@ -2178,7 +2178,7 @@ test socket-14.11.1 {pending [socket -async] and blocking [puts], no listener, f } -cleanup { catch {close $sock} unset x - } -result {connection refused} -returnCodes 1 + } -result {socket is not connected} -returnCodes 1 test socket-14.12 {[socket -async] background progress triggered by [fconfigure -error]} \ -constraints {socket supported_inet supported_inet6} \ -body { diff --git a/win/tclWinPort.h b/win/tclWinPort.h index 61f149b..1104b53 100644 --- a/win/tclWinPort.h +++ b/win/tclWinPort.h @@ -532,6 +532,12 @@ typedef DWORD_PTR * PDWORD_PTR; * The following defines map from standard socket names to our internal * wrappers that redirect through the winSock function table (see the * file tclWinSock.c). + * + * Warning: + * This check was useful in times of Windows98 where WinSock may + * not be available. This is not the case any more. + * This function may be removed with TCL 9.0 + * */ #define getservbyname TclWinGetServByName diff --git a/win/tclWinSock.c b/win/tclWinSock.c index 7593396..dc67c4b 100644 --- a/win/tclWinSock.c +++ b/win/tclWinSock.c @@ -174,7 +174,9 @@ struct TcpState { struct addrinfo *myaddr; /* Iterator over myaddrlist. */ int connectError; /* Cache status of async socket. */ int cachedBlocking; /* Cache blocking mode of async socket. */ - volatile int connectError; /* Async connect error set by notifier thread. + volatile int notifierConnectError; + /* Async connect error set by notifier thread. + * This error is still a windows error code. * Access must be protected by semaphore */ struct TcpState *nextPtr; /* The next socket on the per-thread socket * list. */ @@ -185,19 +187,17 @@ struct TcpState { * structure. */ -#define TCP_ASYNC_SOCKET (1<<0) /* Asynchronous socket. */ +#define TCP_NONBLOCKING (1<<0) /* Socket with non-blocking I/O */ #define TCP_ASYNC_CONNECT (1<<1) /* Async connect in progress. */ #define SOCKET_EOF (1<<2) /* A zero read happened on the * socket. */ #define SOCKET_PENDING (1<<3) /* A message has been sent for this * socket */ -#define TCP_ASYNC_CONNECT_REENTER_PENDING (1<<4) - /* TcpConnect was called to +#define TCP_ASYNC_PENDING (1<<4) /* TcpConnect was called to * process an async connect. This * flag indicates that reentry is * still pending */ -#define TCP_ASYNC_CONNECT_FAILED (1<<5) - /* An async connect finally failed */ +#define TCP_ASYNC_FAILED (1<<5) /* An async connect finally failed */ /* * The following structure is what is added to the Tcl event queue when a @@ -540,9 +540,9 @@ TcpBlockModeProc( TcpState *statePtr = instanceData; if (mode == TCL_MODE_NONBLOCKING) { - statePtr->flags |= TCP_ASYNC_SOCKET; + statePtr->flags |= TCP_NONBLOCKING; } else { - statePtr->flags &= ~(TCP_ASYNC_SOCKET); + statePtr->flags &= ~(TCP_NONBLOCKING); } return 0; } @@ -554,12 +554,19 @@ TcpBlockModeProc( * * Check the state of an async connect process. If a connection * attempt terminated, process it, which may finalize it or may - * start the next attempt. + * start the next attempt. If a connect error occures, it is saved + * in statePtr->connectError to be reported by 'fconfigure -error'. + * * There are two modes of operation, defined by errorCodePtr: * * non-NULL: Called by explicite read/write command. block if - * socket is blocking. Return a possible error and clear it. - * * Null: Called by a backround operation. Never block and - * save eventual error in statePtr->connectError. + * socket is blocking. + * May return two error codes: + * * EWOULDBLOCK: if connect is still in progress + * * ENOTCONN: if connect failed. This would be the error + * message of a rect or sendto syscall so this is + * emulated here. + * * Null: Called by a backround operation. Do not block and + * don't return any error code. * * Results: * 0 if the connection has completed, -1 if still in progress @@ -577,10 +584,6 @@ WaitForConnect( TcpState *statePtr, /* State of the socket. */ int *errorCodePtr) /* Where to store errors? * A passed null-pointer activates background mode. - * In this case, a possible error is stored in - * statePtr->connectError. - * In addition, we do never block and allow the next - * processing cycle to happen. */ { int result; @@ -588,21 +591,21 @@ WaitForConnect( ThreadSpecificData *tsdPtr; /* - * Check if an async connect error is not jet reported. - * If yes, report it now. + * Check if an async connect failed already and error reporting is demanded, + * return the error ENOTCONN */ - if ( errorCodePtr != NULL && statePtr->connectError != 0 ) { - *errorCodePtr = statePtr->connectError; - statePtr->connectError = 0; + if ( errorCodePtr != NULL && + (statePtr->flags & TCP_ASYNC_FAILED) ) { + *errorCodePtr = ENOTCONN; return -1; } /* * Check if an async connect is running. If not return ok */ - - if ( !(statePtr->flags & TCP_ASYNC_CONNECT_REENTER_PENDING) ) + + if ( !(statePtr->flags & TCP_ASYNC_PENDING) ) return 0; /* @@ -611,6 +614,10 @@ WaitForConnect( oldMode = Tcl_SetServiceMode(TCL_SERVICE_NONE); + /* + * Loop in the blocking case until the connect signal is present + */ + while (1) { /* get statePtr lock */ @@ -628,22 +635,32 @@ WaitForConnect( * disable async connect as we continue now synchoneously */ if ( errorCodePtr != NULL && - ! (statePtr->flags & TCP_ASYNC_SOCKET) ) { + ! (statePtr->flags & TCP_NONBLOCKING) ) { CLEAR_BITS(statePtr->flags, TCP_ASYNC_CONNECT); } /* Free list lock */ SetEvent(tsdPtr->socketListLock); - /* continue connect */ + /* + * Continue connect. + * If switched to synchroneous connect, the connect is terminated. + */ result = TcpConnect(NULL, statePtr); /* Restore event service mode */ (void) Tcl_SetServiceMode(oldMode); - /* Succesfully connected or async connect restarted */ + /* + * Check for Succesfull connect or async connect restart + */ + if (result == TCL_OK) { - if ( statePtr->flags & TCP_ASYNC_CONNECT_REENTER_PENDING ) { + /* + * Check for async connect restart + * (not possible for foreground blocking operation) + */ + if ( statePtr->flags & TCP_ASYNC_PENDING ) { if (errorCodePtr != NULL) { *errorCodePtr = EWOULDBLOCK; } @@ -651,11 +668,14 @@ WaitForConnect( } return 0; } - /* error case */ + + /* + * Connect finally failed. + * For foreground operation return ENOTCONN. + */ + if (errorCodePtr != NULL) { - *errorCodePtr = Tcl_GetErrno(); - } else { - statePtr->connectError = Tcl_GetErrno(); + *errorCodePtr = ENOTCONN; } return -1; } @@ -664,14 +684,20 @@ WaitForConnect( SetEvent(tsdPtr->socketListLock); /* - * A non blocking socket waiting for an asyncronous connect - * returns directly an error + * Background operation returns with no action as there was no connect + * event */ + if ( errorCodePtr == NULL ) { - /* Backround operation */ return -1; - } else if (statePtr->flags & TCP_ASYNC_SOCKET) { - /* foreground operation but non blocking socket */ + } + + /* + * A non blocking socket waiting for an asyncronous connect + * returns directly the error EWOULDBLOCK + */ + + if (statePtr->flags & TCP_NONBLOCKING) { *errorCodePtr = EWOULDBLOCK; return -1; } @@ -803,7 +829,7 @@ TcpInputProc( * Check for error condition or underflow in non-blocking case. */ - if ((statePtr->flags & TCP_ASYNC_SOCKET) || (error != WSAEWOULDBLOCK)) { + if ((statePtr->flags & TCP_NONBLOCKING) || (error != WSAEWOULDBLOCK)) { TclWinConvertError(error); *errorCodePtr = Tcl_GetErrno(); bytesRead = -1; @@ -908,7 +934,7 @@ TcpOutputProc( error = WSAGetLastError(); if (error == WSAEWOULDBLOCK) { statePtr->readyEvents &= ~(FD_WRITE); - if (statePtr->flags & TCP_ASYNC_SOCKET) { + if (statePtr->flags & TCP_NONBLOCKING) { *errorCodePtr = EWOULDBLOCK; written = -1; break; @@ -1249,10 +1275,10 @@ TcpGetOptionProc( /* * Do not return any errors if async connect is running */ - if ( ! (statePtr->flags & TCP_ASYNC_CONNECT_REENTER_PENDING) ) { + if ( ! (statePtr->flags & TCP_ASYNC_PENDING) ) { - if ( statePtr->flags & TCP_ASYNC_CONNECT_FAILED ) { + if ( statePtr->flags & TCP_ASYNC_FAILED ) { /* * In case of a failed async connect, eventually report the @@ -1280,7 +1306,7 @@ TcpGetOptionProc( * Populater the err Variable with a possix error */ optlen = sizeof(int); - ret = TclWinGetSockOpt(sock, SOL_SOCKET, SO_ERROR, + ret = getsockopt(sock, SOL_SOCKET, SO_ERROR, (char *)&err, &optlen); /* * The error was not returned directly but should be @@ -1305,7 +1331,7 @@ TcpGetOptionProc( (strncmp(optionName, "-connecting", len) == 0)) { Tcl_DStringAppend(dsPtr, - (statePtr->flags & TCP_ASYNC_CONNECT_REENTER_PENDING) + (statePtr->flags & TCP_ASYNC_PENDING) ? "1" : "0", -1); return TCL_OK; } @@ -1645,7 +1671,7 @@ TcpConnect( /* * Reset last error from last try */ - statePtr->connectError = 0; + statePtr->notifierConnectError = 0; Tcl_SetErrno(0); statePtr->sockets->fd = socket(statePtr->myaddr->ai_family, SOCK_STREAM, 0); @@ -1747,7 +1773,7 @@ TcpConnect( /* * Remember that we jump back behind this next round */ - statePtr->flags |= TCP_ASYNC_CONNECT_REENTER_PENDING; + statePtr->flags |= TCP_ASYNC_PENDING; return TCL_OK; reenter: @@ -1757,11 +1783,11 @@ TcpConnect( * * Clear the reenter flag */ - statePtr->flags &= ~(TCP_ASYNC_CONNECT_REENTER_PENDING); + statePtr->flags &= ~(TCP_ASYNC_PENDING); /* get statePtr lock */ WaitForSingleObject(tsdPtr->socketListLock, INFINITE); /* Get signaled connect error */ - Tcl_SetErrno(statePtr->connectError); + TclWinConvertError((DWORD) statePtr->notifierConnectError); /* Clear eventual connect flag */ statePtr->selectEvents &= ~(FD_CONNECT); /* Free list lock */ @@ -1819,7 +1845,9 @@ out: /* Signal ready readable and writable events */ statePtr->readyEvents |= FD_WRITE | FD_READ; /* Flag error to event routine */ - statePtr->flags |= TCP_ASYNC_CONNECT_FAILED; + statePtr->flags |= TCP_ASYNC_FAILED; + /* Save connect error to be reported by 'fconfigure -error' */ + statePtr->connectError = Tcl_GetErrno(); /* Free list lock */ SetEvent(tsdPtr->socketListLock); } @@ -2260,6 +2288,12 @@ TcpAccept( * * Assumes socketMutex is held. * + * Warning: + * This check was useful in times of Windows98 where WinSock may + * not be available. This is not the case any more. + * This function may be removed with TCL 9.0. + * Any failures may be reported as panics. + * * Results: * None. * @@ -2393,6 +2427,11 @@ InitSockets(void) * * Check that the WinSock was successfully initialized. * + * Warning: + * This check was useful in times of Windows98 where WinSock may + * not be available. This is not the case any more. + * This function may be removed with TCL 9.0 + * * Results: * 1 if it is. * @@ -2622,7 +2661,7 @@ SocketEventProc( */ if ( statePtr->readyEvents & FD_CONNECT ) { - if ( statePtr->flags & TCP_ASYNC_CONNECT_REENTER_PENDING ) { + if ( statePtr->flags & TCP_ASYNC_PENDING ) { /* * Do one step and save eventual connect error @@ -2735,7 +2774,7 @@ SocketEventProc( * Throw the readable event if an async connect failed. */ - if ( statePtr->flags & TCP_ASYNC_CONNECT_FAILED ) { + if ( statePtr->flags & TCP_ASYNC_FAILED ) { mask |= TCL_READABLE; @@ -2928,7 +2967,7 @@ WaitForSocketEvent( } /* Exit loop if event did not occur but this is a non-blocking channel */ - if (statePtr->flags & TCP_ASYNC_SOCKET) { + if (statePtr->flags & TCP_NONBLOCKING) { *errorCodePtr = EWOULDBLOCK; result = 0; break; @@ -3122,8 +3161,7 @@ SocketProc( * connection failures. */ if (error != ERROR_SUCCESS) { - TclWinConvertError((DWORD) error); - statePtr->connectError = Tcl_GetErrno(); + statePtr->notifierConnectError = error; } } /* @@ -3203,6 +3241,10 @@ FindFDInList( * dynamically so we can run on systems that don't have the wsock32.dll. * We need wrappers for these interfaces because they are called from the * generic Tcl code. + * Those functions are exported by the stubs table. + * + * Warning: + * Those functions are depreciated and will be removed with TCL 9.0. * * Results: * As defined for each function. -- cgit v0.12 From 42143bf4e9bde53837496b5fbaf808670cb2914c Mon Sep 17 00:00:00 2001 From: oehhar Date: Tue, 8 Apr 2014 15:15:31 +0000 Subject: Beautify check for async connect reentry --- win/tclWinSock.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/win/tclWinSock.c b/win/tclWinSock.c index dc67c4b..de4c519 100644 --- a/win/tclWinSock.c +++ b/win/tclWinSock.c @@ -595,8 +595,7 @@ WaitForConnect( * return the error ENOTCONN */ - if ( errorCodePtr != NULL && - (statePtr->flags & TCP_ASYNC_FAILED) ) { + if (errorCodePtr != NULL && (statePtr->flags & TCP_ASYNC_FAILED)) { *errorCodePtr = ENOTCONN; return -1; } @@ -605,8 +604,9 @@ WaitForConnect( * Check if an async connect is running. If not return ok */ - if ( !(statePtr->flags & TCP_ASYNC_PENDING) ) + if (!(statePtr->flags & TCP_ASYNC_CONNECT)) { return 0; + } /* * Be sure to disable event servicing so we are truly modal. @@ -1635,7 +1635,7 @@ TcpConnect( */ int async_connect = statePtr->flags & TCP_ASYNC_CONNECT; /* We were called by the event procedure and continue our loop */ - int async_callback = statePtr->sockets->fd != INVALID_SOCKET; + int async_callback = statePtr->flags & TCP_ASYNC_PENDING; ThreadSpecificData *tsdPtr = TclThreadDataKeyGet(&dataKey); if (async_callback) { @@ -1811,6 +1811,12 @@ out: * Socket connected or connection failed */ + /* + * Async connect terminated + */ + + CLEAR_BITS(statePtr->flags, TCP_ASYNC_CONNECT); + if ( Tcl_GetErrno() == 0 ) { /* * Succesfully connected -- cgit v0.12 From 32d3c7b2a1cd2769bd166956a5d4796b5820b969 Mon Sep 17 00:00:00 2001 From: max Date: Tue, 8 Apr 2014 18:00:35 +0000 Subject: * Give clearer names to some of the state flags and sync them with Windows where it makes sense. * Rework WaitForConnect once more to always report ENOTCONN on I/O operations on failed async sockets. * Fix synchronous connections to a server that only listens on IPv6 (or whatever comes later in the list returned by getaddrinfo(), socket-15.*) * Fix spurious writable event on async sockets (socket-14.15). --- tests/socket.test | 34 ++++++++++++++ unix/tclUnixSock.c | 131 ++++++++++++++++++++++++++++++++++++----------------- 2 files changed, 124 insertions(+), 41 deletions(-) diff --git a/tests/socket.test b/tests/socket.test index 648ade5..5ff2109 100644 --- a/tests/socket.test +++ b/tests/socket.test @@ -2225,6 +2225,40 @@ test socket-14.14 {testing fileevent readable on failed async socket connect} -c after cancel $a1 } -result readable +test socket-14.15 {blocking read on async socket should not trigger event handlers} \ + -constraints socket -body { + set s [socket -async localhost [randport]] + set x ok + fileevent $s writable {set x fail} + catch {read $s} + set x + } -result ok + +set num 0 +foreach servip {127.0.0.1 ::1 localhost} { + foreach cliip {127.0.0.1 ::1 localhost} { + if {$servip eq $cliip || "localhost" in [list $servip $cliip]} { + set result {-result "sock*" -match glob} + } else { + set result { + -result {couldn't open socket: connection refused} + -returnCodes 1 + } + } + test socket-15.1.$num "Connect to $servip from $cliip" \ + -constraints {socket supported_inet supported_inet6} -setup { + set server [socket -server accept -myaddr $servip 0] + proc accept {s h p} { close $s } + set port [lindex [fconfigure $server -sockname] 2] + } -body { + set s [socket $cliip $port] + } -cleanup { + close $server + catch {close $s} + } {*}$result + incr num + } +} ::tcltest::cleanupTests flush stdout diff --git a/unix/tclUnixSock.c b/unix/tclUnixSock.c index adc6243..08a14d3 100644 --- a/unix/tclUnixSock.c +++ b/unix/tclUnixSock.c @@ -82,8 +82,13 @@ struct TcpState { * structure. */ -#define TCP_ASYNC_SOCKET (1<<0) /* Asynchronous socket. */ +#define TCP_NONBLOCKING (1<<0) /* Socket with non-blocking I/O */ #define TCP_ASYNC_CONNECT (1<<1) /* Async connect in progress. */ +#define TCP_ASYNC_PENDING (1<<4) /* TcpConnect was called to + * process an async connect. This + * flag indicates that reentry is + * still pending */ +#define TCP_ASYNC_FAILED (1<<5) /* An async connect finally failed */ /* * The following defines the maximum length of the listen queue. This is the @@ -128,7 +133,7 @@ static int TcpInputProc(ClientData instanceData, char *buf, static int TcpOutputProc(ClientData instanceData, const char *buf, int toWrite, int *errorCode); static void TcpWatchProc(ClientData instanceData, int mask); -static int WaitForConnect(TcpState *statePtr, int noblock); +static int WaitForConnect(TcpState *statePtr, int *errorCodePtr); /* * This structure describes the channel type structure for TCP socket @@ -364,9 +369,9 @@ TcpBlockModeProc( TcpState *statePtr = instanceData; if (mode == TCL_MODE_BLOCKING) { - CLEAR_BITS(statePtr->flags, TCP_ASYNC_SOCKET); + CLEAR_BITS(statePtr->flags, TCP_NONBLOCKING); } else { - SET_BITS(statePtr->flags, TCP_ASYNC_SOCKET); + SET_BITS(statePtr->flags, TCP_NONBLOCKING); } if (statePtr->flags & TCP_ASYNC_CONNECT) { statePtr->cachedBlocking = mode; @@ -383,48 +388,82 @@ TcpBlockModeProc( * * WaitForConnect -- * - * Wait for a connection on an asynchronously opened socket to be - * completed. In nonblocking mode, just test if the connection - * has completed without blocking. The noblock parameter allows to - * enforce nonblocking behaviour even on sockets in blocking mode. + * Check the state of an async connect process. If a connection + * attempt terminated, process it, which may finalize it or may + * start the next attempt. If a connect error occures, it is saved + * in statePtr->connectError to be reported by 'fconfigure -error'. + * + * There are two modes of operation, defined by errorCodePtr: + * * non-NULL: Called by explicite read/write command. block if + * socket is blocking. + * May return two error codes: + * * EWOULDBLOCK: if connect is still in progress + * * ENOTCONN: if connect failed. This would be the error + * message of a rect or sendto syscall so this is + * emulated here. + * * NULL: Called by a backround operation. Do not block and + * don't return any error code. * * Results: * 0 if the connection has completed, -1 if still in progress * or there is an error. * + * Side effects: + * Processes socket events off the system queue. + * May process asynchroneous connect. + * *---------------------------------------------------------------------- */ static int WaitForConnect( TcpState *statePtr, /* State of the socket. */ - int noblock) /* Don't wait, even for sockets in blocking mode */ + int *errorCodePtr) { + int timeout; + /* - * If an asynchronous connect is in progress, attempt to wait for it to - * complete before reading. + * Check if an async connect failed already and error reporting is demanded, + * return the error ENOTCONN */ - if (statePtr->flags & TCP_ASYNC_CONNECT) { - if (noblock || (statePtr->flags & TCP_ASYNC_SOCKET)) { - if (TclUnixWaitForFile(statePtr->fds.fd, - TCL_WRITABLE | TCL_EXCEPTION, 0) != 0) { - TcpConnect(NULL, statePtr); - } - } else { - while (statePtr->flags & TCP_ASYNC_CONNECT) { - if (TclUnixWaitForFile(statePtr->fds.fd, - TCL_WRITABLE | TCL_EXCEPTION, -1) != 0) { - TcpConnect(NULL, statePtr); - } - } - } + if (errorCodePtr != NULL && (statePtr->flags & TCP_ASYNC_FAILED)) { + *errorCodePtr = ENOTCONN; + return -1; + } + + /* + * Check if an async connect is running. If not return ok + */ + + if (!(statePtr->flags & TCP_ASYNC_PENDING)) { + return 0; } - if (statePtr->connectError != 0) { - return -1; + + if (errorCodePtr == NULL || (statePtr->flags & TCP_NONBLOCKING)) { + timeout = 0; } else { - return 0; + timeout = -1; + } + do { + if (TclUnixWaitForFile(statePtr->fds.fd, + TCL_WRITABLE | TCL_EXCEPTION, timeout) != 0) { + TcpConnect(NULL, statePtr); + } + /* Do this only once in the nonblocking case and repeat it until the + * socket is final when blocking */ + } while (timeout == -1 && statePtr->flags & TCP_ASYNC_CONNECT); + + if (errorCodePtr != NULL) { + if (statePtr->flags & TCP_ASYNC_PENDING) { + *errorCodePtr = EAGAIN; + return -1; + } else if (statePtr->connectError != 0) { + *errorCodePtr = ENOTCONN; + return -1; + } } + return 0; } /* @@ -462,9 +501,7 @@ TcpInputProc( int bytesRead; *errorCodePtr = 0; - if (WaitForConnect(statePtr, 0) != 0) { - *errorCodePtr = statePtr->connectError; - statePtr->connectError = 0; + if (WaitForConnect(statePtr, errorCodePtr) != 0) { return -1; } bytesRead = recv(statePtr->fds.fd, buf, (size_t) bufSize, 0); @@ -514,9 +551,7 @@ TcpOutputProc( int written; *errorCodePtr = 0; - if (WaitForConnect(statePtr, 0) != 0) { - *errorCodePtr = statePtr->connectError; - statePtr->connectError = 0; + if (WaitForConnect(statePtr, errorCodePtr) != 0) { return -1; } written = send(statePtr->fds.fd, buf, (size_t) toWrite, 0); @@ -744,7 +779,7 @@ TcpGetOptionProc( TcpState *statePtr = instanceData; size_t len = 0; - WaitForConnect(statePtr, 1); + WaitForConnect(statePtr, NULL); if (optionName != NULL) { len = strlen(optionName); @@ -888,7 +923,7 @@ TcpWatchProc( return; } - if (statePtr->flags & TCP_ASYNC_CONNECT) { + if (statePtr->flags & TCP_ASYNC_PENDING) { /* Async sockets use a FileHandler internally while connecting, so we * need to cache this request until the connection has succeeded. */ statePtr->filehandlers = mask; @@ -988,8 +1023,8 @@ TcpConnect( TcpState *statePtr) { socklen_t optlen; - int async_callback = (statePtr->addr != NULL); - int ret = -1, error = 0; + int async_callback = statePtr->flags & TCP_ASYNC_PENDING; + int ret = -1, error; int async = statePtr->flags & TCP_ASYNC_CONNECT; if (async_callback) { @@ -998,9 +1033,10 @@ TcpConnect( for (statePtr->addr = statePtr->addrlist; statePtr->addr != NULL; statePtr->addr = statePtr->addr->ai_next) { + for (statePtr->myaddr = statePtr->myaddrlist; statePtr->myaddr != NULL; statePtr->myaddr = statePtr->myaddr->ai_next) { - int reuseaddr; + int reuseaddr = 1; /* * No need to try combinations of local and remote addresses of @@ -1047,7 +1083,10 @@ TcpConnect( } } - reuseaddr = 1; + /* Gotta reset the error variable here, before we use it for the + * first time in this iteration. */ + error = 0; + (void) setsockopt(statePtr->fds.fd, SOL_SOCKET, SO_REUSEADDR, (char *) &reuseaddr, sizeof(reuseaddr)); ret = bind(statePtr->fds.fd, statePtr->myaddr->ai_addr, @@ -1070,10 +1109,12 @@ TcpConnect( if (ret < 0 && errno == EINPROGRESS) { Tcl_CreateFileHandler(statePtr->fds.fd, TCL_WRITABLE|TCL_EXCEPTION, TcpAsyncCallback, statePtr); - statePtr->connectError = errno = EWOULDBLOCK; + errno = EWOULDBLOCK; + SET_BITS(statePtr->flags, TCP_ASYNC_PENDING); return TCL_OK; reenter: + CLEAR_BITS(statePtr->flags, TCP_ASYNC_PENDING); Tcl_DeleteFileHandler(statePtr->fds.fd); /* @@ -1106,6 +1147,10 @@ out: TcpWatchProc(statePtr, statePtr->filehandlers); TclUnixSetBlockingMode(statePtr->fds.fd, statePtr->cachedBlocking); + if (error != 0) { + SET_BITS(statePtr->flags, TCP_ASYNC_FAILED); + } + /* * We need to forward the writable event that brought us here, bcasue * upon reading of getsockopt(SO_ERROR), at least some OSes clear the @@ -1115,7 +1160,11 @@ out: * the event mechanism one roundtrip through select(). */ + /* Note: disabling this for now as it causes spurious event triggering + * under Linux (see test socket-14.15). */ +#if 0 Tcl_NotifyChannel(statePtr->channel, TCL_WRITABLE); +#endif } if (error != 0) { /* -- cgit v0.12 From e3220aa63174d2d49368a02ce956eb6a0b7e8ae0 Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 25 Apr 2014 17:34:11 +0000 Subject: Test iortrans-4.8.2 demos an infinite loop. Possible trouble with pushback buffers. --- generic/tclIO.c | 5 +++++ tests/ioTrans.test | 20 ++++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/generic/tclIO.c b/generic/tclIO.c index e6439ef..41ac1e1 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -5611,6 +5611,11 @@ DoReadChars( ResetFlag(statePtr, CHANNEL_BLOCKED); } result = GetInput(chanPtr); +if (chanPtr != statePtr->topChanPtr) { +Tcl_Release(chanPtr); +chanPtr = statePtr->topChanPtr; +Tcl_Preserve(chanPtr); +} if (result != 0) { if (result == EAGAIN) { break; diff --git a/tests/ioTrans.test b/tests/ioTrans.test index b21d894..3bbd170 100644 --- a/tests/ioTrans.test +++ b/tests/ioTrans.test @@ -559,6 +559,26 @@ test iortrans-4.8.1 {chan read, bug 721ec69271} -setup { rename foo {} } -result {{read rt* {test data }} file*} +test iortrans-4.8.2 {chan read, bug 721ec69271} -setup { + set res {} +} -match glob -body { + proc foo {fd args} { + handle.initialize + handle.finalize + lappend ::res $args + # Kill and recreate transform while it is operating + chan pop $fd + chan push $fd [list foo $fd] + return x + } + set c [chan push [set c [tempchan]] [list foo $c]] + chan configure $c -buffersize 1 + lappend res [read $c] +} -cleanup { + tempdone + rename foo {} +} -result {{read rt* {test data +}} file*} test iortrans-4.9 {chan read, gets, bug 2921116} -setup { set res {} } -match glob -body { -- cgit v0.12 From e024894c53ffc2dec708a84210d4000e6a9c7209 Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 25 Apr 2014 19:51:36 +0000 Subject: Disable buffer recycling, which creates mysteries. --- generic/tclIO.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index 41ac1e1..df863cc 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -2342,7 +2342,7 @@ RecycleBuffer( * Do we have to free the buffer to the OS? */ - if (mustDiscard) { + if (1 || mustDiscard) { ReleaseChannelBuffer(bufPtr); return; } -- cgit v0.12 From 8e5e88f4dbbd30500ce43e26c083e19cd44c217b Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 1 May 2014 16:33:39 +0000 Subject: Stop the segfault in iogt-2.4. First by changing the UpdateInterest() call that triggers it. "downChanPtr" may no longer be the right argument at that point. Second, after ending the segfault, the test became an infinite loop (nested unstacking?! whoa.), so revised the test to one that terminates (and passes). Left behind a comment that the recursive unstacking case may require more examination. --- generic/tclIO.c | 9 ++++++++- tests/iogt.test | 2 +- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index 776ff12..a83cdcd 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -1876,6 +1876,13 @@ Tcl_UnstackChannel( * into the old structure. */ + /* + * TODO: Figure out how to handle the situation where the chan + * operations called below by this unstacking operation cause + * another unstacking recursively. In that case the downChanPtr + * value we're holding on to will not be the right thing. + */ + Channel *downChanPtr = chanPtr->downChanPtr; /* @@ -1980,7 +1987,7 @@ Tcl_UnstackChannel( */ Tcl_EventuallyFree(chanPtr, TCL_DYNAMIC); - UpdateInterest(downChanPtr); + UpdateInterest(statePtr->topChanPtr); if (result != 0) { Tcl_SetErrno(result); diff --git a/tests/iogt.test b/tests/iogt.test index bd3c67b..ded8bb9 100644 --- a/tests/iogt.test +++ b/tests/iogt.test @@ -228,7 +228,7 @@ proc id_torture {chan op data} { delete/read - clear_read {;#ignore} flush/write - - flush/read - + flush/read {} write - read { testchannel unstack $chan -- cgit v0.12 From c09e2ded082244a2dd009a6f46fdfc75158e555d Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 2 May 2014 12:39:14 +0000 Subject: Re-enable buffer recycling. --- generic/tclIO.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index a83cdcd..8ae2fd2 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -2360,7 +2360,7 @@ RecycleBuffer( mustDiscard = 1; } - if (1 || mustDiscard) { + if (mustDiscard) { ReleaseChannelBuffer(bufPtr); return; } -- cgit v0.12 From fd83709b456fbbfab52d30daa8dc327491ac4cca Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 2 May 2014 13:02:48 +0000 Subject: Fully restore topChan resetting to accommodate self-restacking channels. --- generic/tclIO.c | 43 ++++++++++++++++++++++++++----------------- 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index 8ae2fd2..adea32e 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -4554,9 +4554,12 @@ Tcl_GetsObj( * Regenerate the top channel, in case it was changed due to * self-modifying reflected transforms. */ - /* - chanPtr = statePtr->topChanPtr; - */ + + if (chanPtr != statePtr->topChanPtr) { + Tcl_Release(chanPtr); + chanPtr = statePtr->topChanPtr; + Tcl_Preserve(chanPtr); + } bufPtr = gs.bufPtr; if (bufPtr == NULL) { @@ -4590,9 +4593,11 @@ Tcl_GetsObj( * Regenerate the top channel, in case it was changed due to * self-modifying reflected transforms. */ - /* - chanPtr = statePtr->topChanPtr; - */ + if (chanPtr != statePtr->topChanPtr) { + Tcl_Release(chanPtr); + chanPtr = statePtr->topChanPtr; + Tcl_Preserve(chanPtr); + } bufPtr = statePtr->inQueueHead; if (bufPtr != NULL) { bufPtr->nextRemoved = oldRemoved; @@ -4632,9 +4637,11 @@ Tcl_GetsObj( * Regenerate the top channel, in case it was changed due to * self-modifying reflected transforms. */ - /* - chanPtr = statePtr->topChanPtr; - */ + if (chanPtr != statePtr->topChanPtr) { + Tcl_Release(chanPtr); + chanPtr = statePtr->topChanPtr; + Tcl_Preserve(chanPtr); + } UpdateInterest(chanPtr); Tcl_Release(chanPtr); return copiedTotal; @@ -5638,11 +5645,11 @@ DoReadChars( ResetFlag(statePtr, CHANNEL_BLOCKED); } result = GetInput(chanPtr); -if (chanPtr != statePtr->topChanPtr) { -Tcl_Release(chanPtr); -chanPtr = statePtr->topChanPtr; -Tcl_Preserve(chanPtr); -} + if (chanPtr != statePtr->topChanPtr) { + Tcl_Release(chanPtr); + chanPtr = statePtr->topChanPtr; + Tcl_Preserve(chanPtr); + } if (result != 0) { if (result == EAGAIN) { break; @@ -5673,9 +5680,11 @@ Tcl_Preserve(chanPtr); * Regenerate the top channel, in case it was changed due to * self-modifying reflected transforms. */ - /* - chanPtr = statePtr->topChanPtr; - */ + if (chanPtr != statePtr->topChanPtr) { + Tcl_Release(chanPtr); + chanPtr = statePtr->topChanPtr; + Tcl_Preserve(chanPtr); + } UpdateInterest(chanPtr); Tcl_Release(chanPtr); return copied; -- cgit v0.12 From 322ea4d71ddf82436ab84f2b3d24c4c75444257c Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 2 May 2014 14:45:03 +0000 Subject: Add some comments about possible other self-restacking troubles. --- generic/tclIO.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index adea32e..58c7b3c 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -1747,6 +1747,10 @@ Tcl_StackChannel( statePtr->csPtrR = NULL; statePtr->csPtrW = NULL; + /* + * TODO: Examine what can go wrong if Tcl_Flush() call disturbs + * the stacking state of this channel during its operations. + */ if (Tcl_Flush((Tcl_Channel) prevChanPtr) != TCL_OK) { statePtr->csPtrR = csPtrR; statePtr->csPtrW = csPtrW; @@ -9786,12 +9790,15 @@ StackSetBlockMode( { int result = 0; Tcl_DriverBlockModeProc *blockModeProc; + ChannelState *statePtr = chanPtr->state; /* * Start at the top of the channel stack + * TODO: Examine what can go wrong when blockModeProc calls + * disturb the stacking state of the channel. */ - chanPtr = chanPtr->state->topChanPtr; + chanPtr = statePtr->topChanPtr; while (chanPtr != NULL) { blockModeProc = Tcl_ChannelBlockModeProc(chanPtr->typePtr); if (blockModeProc != NULL) { -- cgit v0.12 From 9bed70dea46200cece274e91624f42d97feb95ba Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 2 May 2014 15:19:57 +0000 Subject: Fixup restacking tests to expect the right results. --- tests/ioTrans.test | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/ioTrans.test b/tests/ioTrans.test index 3bbd170..7f4f7f0 100644 --- a/tests/ioTrans.test +++ b/tests/ioTrans.test @@ -539,7 +539,7 @@ test iortrans-4.8 {chan read, read, bug 2921116} -setup { tempdone rename foo {} } -result {{read rt* {test data -}} file*} +}} {}} test iortrans-4.8.1 {chan read, bug 721ec69271} -setup { set res {} } -match glob -body { @@ -557,8 +557,8 @@ test iortrans-4.8.1 {chan read, bug 721ec69271} -setup { } -cleanup { tempdone rename foo {} -} -result {{read rt* {test data -}} file*} +} -result {{read rt* te} {read rt* st} {read rt* { d}} {read rt* at} {read rt* {a +}} {}} test iortrans-4.8.2 {chan read, bug 721ec69271} -setup { set res {} } -match glob -body { @@ -577,8 +577,8 @@ test iortrans-4.8.2 {chan read, bug 721ec69271} -setup { } -cleanup { tempdone rename foo {} -} -result {{read rt* {test data -}} file*} +} -result {{read rt* t} {read rt* e} {read rt* s} {read rt* t} {read rt* { }} {read rt* d} {read rt* a} {read rt* t} {read rt* a} {read rt* { +}} {}} test iortrans-4.9 {chan read, gets, bug 2921116} -setup { set res {} } -match glob -body { @@ -596,7 +596,7 @@ test iortrans-4.9 {chan read, gets, bug 2921116} -setup { tempdone rename foo {} } -result {{read rt* {test data -}} file*} +}} {}} # --- === *** ########################### # method write (via puts) -- cgit v0.12 From 988827526189ee6c77752e42d11ba8672c6d506a Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Fri, 2 May 2014 15:35:14 +0000 Subject: Re-apply [3010352], bringing back the symbol exports of shared libraries as it was in 8.6.0/8.6.1. --- generic/tcl.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/generic/tcl.h b/generic/tcl.h index b93b3ac..e557290 100644 --- a/generic/tcl.h +++ b/generic/tcl.h @@ -2433,9 +2433,15 @@ EXTERN void Tcl_GetMemoryInfo(Tcl_DString *dsPtr); /* * Include platform specific public function declarations that are accessible - * via the stubs table. + * via the stubs table. Make all TclOO symbols MODULE_SCOPE (which only + * has effect on building it as a shared library). See ticket [3010352]. */ +#if defined(BUILD_tcl) +# undef TCLAPI +# define TCLAPI MODULE_SCOPE +#endif + #include "tclPlatDecls.h" /* -- cgit v0.12 From acdf0e593a1a9ab5f04882544ee898a6f6d2d251 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Mon, 5 May 2014 09:17:46 +0000 Subject: Backport "GotFlag" macro from Tcl 8.6. Makes code more readable. No change in functionality. --- generic/tclIO.c | 186 +++++++++++++++++++++++++++----------------------------- 1 file changed, 89 insertions(+), 97 deletions(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index 46a17f5..2f652e7 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -298,6 +298,7 @@ static int WillRead(Channel *chanPtr); #define SetFlag(statePtr, flag) ((statePtr)->flags |= (flag)) #define ResetFlag(statePtr, flag) ((statePtr)->flags &= ~(flag)) +#define GotFlag(statePtr, flag) ((statePtr)->flags & (flag)) /* * Macro for testing whether a string (in optionName, length len) matches a @@ -463,7 +464,7 @@ TclFinalizeIOSubsystem(void) statePtr != NULL; statePtr = statePtr->nextCSPtr) { chanPtr = statePtr->topChanPtr; - if (!(statePtr->flags & (CHANNEL_INCLOSE|CHANNEL_CLOSED|CHANNEL_DEAD))) { + if (!GotFlag(statePtr, CHANNEL_INCLOSE|CHANNEL_CLOSED|CHANNEL_DEAD)) { active = 1; break; } @@ -560,6 +561,7 @@ Tcl_SetStdChannel( int type) /* One of TCL_STDIN, TCL_STDOUT, TCL_STDERR. */ { ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); + switch (type) { case TCL_STDIN: tsdPtr->stdinInitialized = 1; @@ -676,11 +678,9 @@ Tcl_CreateCloseHandler( ClientData clientData) /* Arbitrary data to pass to the close * callback. */ { - ChannelState *statePtr; + ChannelState *statePtr = ((Channel *) chan)->state; CloseCallback *cbPtr; - statePtr = ((Channel *) chan)->state; - cbPtr = (CloseCallback *) ckalloc(sizeof(CloseCallback)); cbPtr->proc = proc; cbPtr->clientData = clientData; @@ -716,10 +716,9 @@ Tcl_DeleteCloseHandler( ClientData clientData) /* The callback data for the callback to * remove. */ { - ChannelState *statePtr; + ChannelState *statePtr = ((Channel *) chan)->state; CloseCallback *cbPtr, *cbPrevPtr; - statePtr = ((Channel *) chan)->state; for (cbPtr = statePtr->closeCbPtr, cbPrevPtr = NULL; cbPtr != NULL; cbPtr = cbPtr->nextPtr) { if ((cbPtr->proc == proc) && (cbPtr->clientData == clientData)) { @@ -873,7 +872,7 @@ DeleteChannelTable( SetFlag(statePtr, CHANNEL_TAINTED); statePtr->refCount--; if (statePtr->refCount <= 0) { - if (!(statePtr->flags & BG_FLUSH_SCHEDULED)) { + if (!GotFlag(statePtr, BG_FLUSH_SCHEDULED)) { (void) Tcl_Close(interp, (Tcl_Channel) chanPtr); } } @@ -1064,7 +1063,7 @@ Tcl_UnregisterChannel( statePtr = ((Channel *) chan)->state->bottomChanPtr->state; - if (statePtr->flags & CHANNEL_INCLOSE) { + if (GotFlag(statePtr, CHANNEL_INCLOSE)) { if (interp != NULL) { Tcl_AppendResult(interp, "Illegal recursive call to close " "through close-handler of channel", NULL); @@ -1103,12 +1102,12 @@ Tcl_UnregisterChannel( SetFlag(statePtr, BUFFER_READY); } Tcl_Preserve((ClientData)statePtr); - if (!(statePtr->flags & BG_FLUSH_SCHEDULED)) { + if (!GotFlag(statePtr, BG_FLUSH_SCHEDULED)) { /* * We don't want to re-enter Tcl_Close(). */ - if (!(statePtr->flags & CHANNEL_CLOSED)) { + if (!GotFlag(statePtr, CHANNEL_CLOSED)) { if (Tcl_Close(interp, chan) != TCL_OK) { SetFlag(statePtr, CHANNEL_CLOSED); Tcl_Release((ClientData)statePtr); @@ -1317,7 +1316,7 @@ Tcl_GetChannel( chanPtr = Tcl_GetHashValue(hPtr); chanPtr = chanPtr->state->bottomChanPtr; if (modePtr != NULL) { - *modePtr = (chanPtr->state->flags & (TCL_READABLE|TCL_WRITABLE)); + *modePtr = chanPtr->state->flags & (TCL_READABLE|TCL_WRITABLE); } return (Tcl_Channel) chanPtr; @@ -1365,7 +1364,7 @@ TclGetChannelFromObj( *channelPtr = (Tcl_Channel) (statePtr->bottomChanPtr); if (modePtr != NULL) { - *modePtr = (statePtr->flags & (TCL_READABLE|TCL_WRITABLE)); + *modePtr = statePtr->flags & (TCL_READABLE|TCL_WRITABLE); } return TCL_OK; @@ -1645,13 +1644,10 @@ Tcl_StackChannel( */ if ((mask & TCL_WRITABLE) != 0) { - CopyState *csPtrR; - CopyState *csPtrW; + CopyState *csPtrR = statePtr->csPtrR; + CopyState *csPtrW = statePtr->csPtrW; - csPtrR = statePtr->csPtrR; statePtr->csPtrR = NULL; - - csPtrW = statePtr->csPtrW; statePtr->csPtrW = NULL; /* @@ -1807,14 +1803,11 @@ Tcl_UnstackChannel( * CheckForChannelErrors inside. */ - if (statePtr->flags & TCL_WRITABLE) { - CopyState *csPtrR; - CopyState *csPtrW; + if (GotFlag(statePtr, TCL_WRITABLE)) { + CopyState *csPtrR = statePtr->csPtrR; + CopyState *csPtrW = statePtr->csPtrW; - csPtrR = statePtr->csPtrR; statePtr->csPtrR = NULL; - - csPtrW = statePtr->csPtrW; statePtr->csPtrW = NULL; if (Tcl_Flush((Tcl_Channel) chanPtr) != TCL_OK) { @@ -1851,16 +1844,14 @@ Tcl_UnstackChannel( * 'DiscardInputQueued' on that. */ - if ((((statePtr->flags & TCL_READABLE) != 0)) && + if (GotFlag(statePtr, TCL_READABLE) && ((statePtr->inQueueHead != NULL) || (chanPtr->inQueueHead != NULL))) { - if ((statePtr->inQueueHead != NULL) && (chanPtr->inQueueHead != NULL)) { statePtr->inQueueTail->nextPtr = chanPtr->inQueueHead; statePtr->inQueueTail = chanPtr->inQueueTail; statePtr->inQueueHead = statePtr->inQueueTail; - } else if (chanPtr->inQueueHead != NULL) { statePtr->inQueueHead = chanPtr->inQueueHead; statePtr->inQueueTail = chanPtr->inQueueTail; @@ -2312,7 +2303,7 @@ RecycleBuffer( * Only save buffers for the input queue if the channel is readable. */ - if (statePtr->flags & TCL_READABLE) { + if (GotFlag(statePtr, TCL_READABLE)) { if (statePtr->inQueueHead == NULL) { statePtr->inQueueHead = bufPtr; statePtr->inQueueTail = bufPtr; @@ -2328,7 +2319,7 @@ RecycleBuffer( * Only save buffers for the output queue if the channel is writable. */ - if (statePtr->flags & TCL_WRITABLE) { + if (GotFlag(statePtr, TCL_WRITABLE)) { if (statePtr->curOutPtr == NULL) { statePtr->curOutPtr = bufPtr; goto keepBuffer; @@ -2401,7 +2392,7 @@ CheckForDeadChannel( Tcl_Interp *interp, /* For error reporting (can be NULL) */ ChannelState *statePtr) /* The channel state to check. */ { - if (statePtr->flags & CHANNEL_DEAD) { + if (GotFlag(statePtr, CHANNEL_DEAD)) { Tcl_SetErrno(EINVAL); if (interp) { Tcl_AppendResult(interp, @@ -2477,7 +2468,7 @@ FlushChannel( if (((statePtr->curOutPtr != NULL) && IsBufferFull(statePtr->curOutPtr)) - || ((statePtr->flags & BUFFER_READY) && + || (GotFlag(statePtr, BUFFER_READY) && (statePtr->outQueueHead == NULL))) { ResetFlag(statePtr, BUFFER_READY); statePtr->curOutPtr->nextPtr = NULL; @@ -2496,8 +2487,7 @@ FlushChannel( * is active, we just return without producing any output. */ - if ((!calledFromAsyncFlush) && - (statePtr->flags & BG_FLUSH_SCHEDULED)) { + if (!calledFromAsyncFlush && GotFlag(statePtr, BG_FLUSH_SCHEDULED)) { return 0; } @@ -2551,7 +2541,7 @@ FlushChannel( * it's a tty channel (dup'ed underneath) */ - if (!(statePtr->flags & BG_FLUSH_SCHEDULED)) { + if (!GotFlag(statePtr, BG_FLUSH_SCHEDULED)) { SetFlag(statePtr, BG_FLUSH_SCHEDULED); UpdateInterest(chanPtr); } @@ -2651,7 +2641,7 @@ FlushChannel( * data has been flushed at the system level. */ - if (statePtr->flags & BG_FLUSH_SCHEDULED) { + if (GotFlag(statePtr, BG_FLUSH_SCHEDULED)) { if (wroteSome) { return errorCode; } else if (statePtr->outQueueHead == NULL) { @@ -2667,7 +2657,7 @@ FlushChannel( * current output buffer. */ - if ((statePtr->flags & CHANNEL_CLOSED) && (statePtr->refCount <= 0) && + if (GotFlag(statePtr, CHANNEL_CLOSED) && (statePtr->refCount <= 0) && (statePtr->outQueueHead == NULL) && ((statePtr->curOutPtr == NULL) || IsBufferEmpty(statePtr->curOutPtr))) { @@ -2743,7 +2733,7 @@ CloseChannel( * device. */ - if ((statePtr->outEofChar != 0) && (statePtr->flags & TCL_WRITABLE)) { + if ((statePtr->outEofChar != 0) && GotFlag(statePtr, TCL_WRITABLE)) { int dummy; char c = (char) statePtr->outEofChar; @@ -3148,7 +3138,7 @@ Tcl_Close( Tcl_Panic("called Tcl_Close on channel with refCount > 0"); } - if (statePtr->flags & CHANNEL_INCLOSE) { + if (GotFlag(statePtr, CHANNEL_INCLOSE)) { if (interp) { Tcl_AppendResult(interp, "Illegal recursive call to close " "through close-handler of channel", NULL); @@ -3673,7 +3663,7 @@ Write( endEncoding = ((statePtr->outputEncodingFlags & TCL_ENCODING_END) != 0); - if ((statePtr->flags & CHANNEL_LINEBUFFERED) + if (GotFlag(statePtr, CHANNEL_LINEBUFFERED) || (statePtr->outputTranslation != TCL_TRANSLATE_LF)) { nextNewLine = memchr(src, '\n', srcLen); } @@ -3803,8 +3793,8 @@ Write( } ReleaseChannelBuffer(bufPtr); } - if ((flushed < total) && (statePtr->flags & CHANNEL_UNBUFFERED || - (needNlFlush && statePtr->flags & CHANNEL_LINEBUFFERED))) { + if ((flushed < total) && (GotFlag(statePtr, CHANNEL_UNBUFFERED) || + (needNlFlush && GotFlag(statePtr, CHANNEL_LINEBUFFERED)))) { SetFlag(statePtr, BUFFER_READY); if (FlushChannel(NULL, chanPtr, 0) != 0) { return -1; @@ -4049,7 +4039,7 @@ Tcl_GetsObj( case TCL_TRANSLATE_AUTO: eol = dst; skip = 1; - if (statePtr->flags & INPUT_SAW_CR) { + if (GotFlag(statePtr, INPUT_SAW_CR)) { ResetFlag(statePtr, INPUT_SAW_CR); if ((eol < dstEnd) && (*eol == '\n')) { /* @@ -4117,7 +4107,7 @@ Tcl_GetsObj( SetFlag(statePtr, CHANNEL_EOF | CHANNEL_STICKY_EOF); statePtr->inputEncodingFlags |= TCL_ENCODING_END; } - if (statePtr->flags & CHANNEL_EOF) { + if (GotFlag(statePtr, CHANNEL_EOF)) { skip = 0; eol = dstEnd; if (eol == objPtr->bytes + oldLength) { @@ -4328,8 +4318,8 @@ TclGetsObjBinary( * device. Side effect is to allocate another channel buffer. */ - if (statePtr->flags & CHANNEL_BLOCKED) { - if (statePtr->flags & CHANNEL_NONBLOCKING) { + if (GotFlag(statePtr, CHANNEL_BLOCKED)) { + if (GotFlag(statePtr, CHANNEL_NONBLOCKING)) { goto restore; } ResetFlag(statePtr, CHANNEL_BLOCKED); @@ -4383,7 +4373,7 @@ TclGetsObjBinary( SetFlag(statePtr, CHANNEL_EOF | CHANNEL_STICKY_EOF); statePtr->inputEncodingFlags |= TCL_ENCODING_END; } - if (statePtr->flags & CHANNEL_EOF) { + if (GotFlag(statePtr, CHANNEL_EOF)) { skip = 0; eol = dstEnd; if ((dst == dstEnd) && (byteLen == oldLength)) { @@ -4598,8 +4588,8 @@ FilterInputBytes( */ read: - if (statePtr->flags & CHANNEL_BLOCKED) { - if (statePtr->flags & CHANNEL_NONBLOCKING) { + if (GotFlag(statePtr, CHANNEL_BLOCKED)) { + if (GotFlag(statePtr, CHANNEL_NONBLOCKING)) { gsPtr->charsWrote = 0; gsPtr->rawRead = 0; return -1; @@ -4684,7 +4674,7 @@ FilterInputBytes( * returning those UTF-8 characters because a EOL might be * present in them. */ - } else if (statePtr->flags & CHANNEL_EOF) { + } else if (GotFlag(statePtr, CHANNEL_EOF)) { /* * There was a partial character followed by EOF on the * device. Fall through, returning that nothing was found. @@ -4706,7 +4696,7 @@ FilterInputBytes( statePtr->inQueueTail = nextPtr; } extra = rawLen - gsPtr->rawRead; - memcpy(nextPtr->buf + BUFFER_PADDING - extra, + memcpy(nextPtr->buf + (BUFFER_PADDING - extra), raw + gsPtr->rawRead, (size_t) extra); nextPtr->nextRemoved -= extra; bufPtr->nextAdded -= extra; @@ -4773,7 +4763,7 @@ PeekAhead( goto cleanup; } - if ((statePtr->flags & CHANNEL_NONBLOCKING) == 0) { + if (!GotFlag(statePtr, CHANNEL_NONBLOCKING)) { blockModeProc = Tcl_ChannelBlockModeProc(chanPtr->typePtr); if (blockModeProc == NULL) { /* @@ -4970,11 +4960,11 @@ Tcl_ReadRaw( copiedNow = CopyBuffer(chanPtr, bufPtr + copied, bytesToRead - copied); if (copiedNow == 0) { - if (statePtr->flags & CHANNEL_EOF) { + if (GotFlag(statePtr, CHANNEL_EOF)) { goto done; } - if (statePtr->flags & CHANNEL_BLOCKED) { - if (statePtr->flags & CHANNEL_NONBLOCKING) { + if (GotFlag(statePtr, CHANNEL_BLOCKED)) { + if (GotFlag(statePtr, CHANNEL_NONBLOCKING)) { goto done; } ResetFlag(statePtr, CHANNEL_BLOCKED); @@ -4988,9 +4978,9 @@ Tcl_ReadRaw( * and only if we are sure to have data. */ - if ((statePtr->flags & CHANNEL_NONBLOCKING) && + if (GotFlag(statePtr, CHANNEL_NONBLOCKING) && (Tcl_ChannelBlockModeProc(chanPtr->typePtr) == NULL) && - !(statePtr->flags & CHANNEL_HAS_MORE_DATA)) { + !GotFlag(statePtr, CHANNEL_HAS_MORE_DATA)) { /* * We bypass the driver; it would block as no data is * available. @@ -5231,11 +5221,11 @@ DoReadChars( } if (copiedNow < 0) { - if (statePtr->flags & CHANNEL_EOF) { + if (GotFlag(statePtr, CHANNEL_EOF)) { break; } - if (statePtr->flags & CHANNEL_BLOCKED) { - if (statePtr->flags & CHANNEL_NONBLOCKING) { + if (GotFlag(statePtr, CHANNEL_BLOCKED)) { + if (GotFlag(statePtr, CHANNEL_NONBLOCKING)) { break; } ResetFlag(statePtr, CHANNEL_BLOCKED); @@ -5362,7 +5352,7 @@ ReadBytes( } dst += offset; - if (statePtr->flags & INPUT_NEED_NL) { + if (GotFlag(statePtr, INPUT_NEED_NL)) { ResetFlag(statePtr, INPUT_NEED_NL); if ((srcLen == 0) || (*src != '\n')) { *dst = '\r'; @@ -5543,7 +5533,7 @@ ReadChars( } oldState = statePtr->inputEncodingState; - if (statePtr->flags & INPUT_NEED_NL) { + if (GotFlag(statePtr, INPUT_NEED_NL)) { /* * We want a '\n' because the last character we saw was '\r'. */ @@ -5809,7 +5799,7 @@ TranslateInputEOL( srcEnd = srcStart + dstLen; srcMax = srcStart + *srcLenPtr; - if ((statePtr->flags & INPUT_SAW_CR) && (src < srcMax)) { + if (GotFlag(statePtr, INPUT_SAW_CR) && (src < srcMax)) { if (*src == '\n') { src++; } @@ -5914,7 +5904,7 @@ Tcl_Ungets( * bit. We want to discover these conditions anew in each operation. */ - if (statePtr->flags & CHANNEL_STICKY_EOF) { + if (GotFlag(statePtr, CHANNEL_STICKY_EOF)) { goto done; } ResetFlag(statePtr, CHANNEL_BLOCKED | CHANNEL_EOF); @@ -6171,7 +6161,7 @@ GetInput( * platforms it is impossible to read from a device after EOF. */ - if (statePtr->flags & CHANNEL_EOF) { + if (GotFlag(statePtr, CHANNEL_EOF)) { return 0; } @@ -6183,9 +6173,9 @@ GetInput( * sure to have data. */ - if ((statePtr->flags & CHANNEL_NONBLOCKING) && + if (GotFlag(statePtr, CHANNEL_NONBLOCKING) && (Tcl_ChannelBlockModeProc(chanPtr->typePtr) == NULL) && - !(statePtr->flags & CHANNEL_HAS_MORE_DATA)) { + !GotFlag(statePtr, CHANNEL_HAS_MORE_DATA)) { /* * Bypass the driver, it would block, as no data is available */ @@ -6355,14 +6345,14 @@ Tcl_Seek( */ wasAsync = 0; - if (statePtr->flags & CHANNEL_NONBLOCKING) { + if (GotFlag(statePtr, CHANNEL_NONBLOCKING)) { wasAsync = 1; result = StackSetBlockMode(chanPtr, TCL_MODE_BLOCKING); if (result != 0) { return Tcl_LongAsWide(-1); } ResetFlag(statePtr, CHANNEL_NONBLOCKING); - if (statePtr->flags & BG_FLUSH_SCHEDULED) { + if (GotFlag(statePtr, BG_FLUSH_SCHEDULED)) { ResetFlag(statePtr, BG_FLUSH_SCHEDULED); } } @@ -6698,8 +6688,7 @@ CheckChannelErrors( * order to drain data from stacked channels. */ - if ((statePtr->flags & CHANNEL_CLOSED) && - ((flags & CHANNEL_RAW_MODE) == 0)) { + if (GotFlag(statePtr, CHANNEL_CLOSED) && !(flags & CHANNEL_RAW_MODE)) { Tcl_SetErrno(EACCES); return -1; } @@ -6721,7 +6710,7 @@ CheckChannelErrors( * retrieving and transforming the data to copy. */ - if (BUSY_STATE(statePtr,flags) && ((flags & CHANNEL_RAW_MODE) == 0)) { + if (BUSY_STATE(statePtr, flags) && ((flags & CHANNEL_RAW_MODE) == 0)) { Tcl_SetErrno(EBUSY); return -1; } @@ -6734,7 +6723,7 @@ CheckChannelErrors( * discover these conditions anew in each operation. */ - if ((statePtr->flags & CHANNEL_STICKY_EOF) == 0) { + if (!GotFlag(statePtr, CHANNEL_STICKY_EOF)) { ResetFlag(statePtr, CHANNEL_EOF); } ResetFlag(statePtr, CHANNEL_BLOCKED | CHANNEL_NEED_MORE_DATA); @@ -6766,8 +6755,8 @@ Tcl_Eof( ChannelState *statePtr = ((Channel *) chan)->state; /* State of real channel structure. */ - return ((statePtr->flags & CHANNEL_STICKY_EOF) || - ((statePtr->flags & CHANNEL_EOF) && + return (GotFlag(statePtr, CHANNEL_STICKY_EOF) || + (GotFlag(statePtr, CHANNEL_EOF) && (Tcl_InputBuffered(chan) == 0))) ? 1 : 0; } @@ -6794,7 +6783,7 @@ Tcl_InputBlocked( ChannelState *statePtr = ((Channel *) chan)->state; /* State of real channel structure. */ - return (statePtr->flags & CHANNEL_BLOCKED) ? 1 : 0; + return GotFlag(statePtr, CHANNEL_BLOCKED) ? 1 : 0; } /* @@ -7437,10 +7426,10 @@ Tcl_SetChannelOption( ckfree((char *) argv); return TCL_ERROR; } - if (statePtr->flags & TCL_READABLE) { + if (GotFlag(statePtr, TCL_READABLE)) { statePtr->inEofChar = inValue; } - if (statePtr->flags & TCL_WRITABLE) { + if (GotFlag(statePtr, TCL_WRITABLE)) { statePtr->outEofChar = outValue; } } else { @@ -7474,11 +7463,11 @@ Tcl_SetChannelOption( } if (argc == 1) { - readMode = (statePtr->flags & TCL_READABLE) ? argv[0] : NULL; - writeMode = (statePtr->flags & TCL_WRITABLE) ? argv[0] : NULL; + readMode = GotFlag(statePtr, TCL_READABLE) ? argv[0] : NULL; + writeMode = GotFlag(statePtr, TCL_WRITABLE) ? argv[0] : NULL; } else if (argc == 2) { - readMode = (statePtr->flags & TCL_READABLE) ? argv[0] : NULL; - writeMode = (statePtr->flags & TCL_WRITABLE) ? argv[1] : NULL; + readMode = GotFlag(statePtr, TCL_READABLE) ? argv[0] : NULL; + writeMode = GotFlag(statePtr, TCL_WRITABLE) ? argv[1] : NULL; } else { if (interp) { Tcl_AppendResult(interp, @@ -7694,9 +7683,9 @@ Tcl_NotifyChannel( */ if ((mask & TCL_READABLE) && - (statePtr->flags & CHANNEL_NONBLOCKING) && + GotFlag(statePtr, CHANNEL_NONBLOCKING) && (Tcl_ChannelBlockModeProc(chanPtr->typePtr) == NULL) && - !(statePtr->flags & CHANNEL_TIMER_FEV)) { + !GotFlag(statePtr, CHANNEL_TIMER_FEV)) { SetFlag(statePtr, CHANNEL_HAS_MORE_DATA); } #endif /* TCL_IO_TRACK_OS_FOR_DRIVER_WITH_BAD_BLOCKING */ @@ -7759,7 +7748,7 @@ Tcl_NotifyChannel( * don't call any write handlers before the flush is complete. */ - if ((statePtr->flags & BG_FLUSH_SCHEDULED) && (mask & TCL_WRITABLE)) { + if (GotFlag(statePtr, BG_FLUSH_SCHEDULED) && (mask & TCL_WRITABLE)) { FlushChannel(NULL, chanPtr, 1); mask &= ~TCL_WRITABLE; } @@ -7839,7 +7828,7 @@ UpdateInterest( * watch for the channel to become writable. */ - if (statePtr->flags & BG_FLUSH_SCHEDULED) { + if (GotFlag(statePtr, BG_FLUSH_SCHEDULED)) { mask |= TCL_WRITABLE; } @@ -7851,7 +7840,7 @@ UpdateInterest( */ if (mask & TCL_READABLE) { - if (!(statePtr->flags & CHANNEL_NEED_MORE_DATA) + if (!GotFlag(statePtr, CHANNEL_NEED_MORE_DATA) && (statePtr->inQueueHead != NULL) && IsBufferReady(statePtr->inQueueHead)) { mask &= ~TCL_READABLE; @@ -7930,7 +7919,7 @@ ChannelTimerProc( ChannelState *statePtr = chanPtr->state; /* State info for channel */ - if (!(statePtr->flags & CHANNEL_NEED_MORE_DATA) + if (!GotFlag(statePtr, CHANNEL_NEED_MORE_DATA) && (statePtr->interestMask & TCL_READABLE) && (statePtr->inQueueHead != NULL) && IsBufferReady(statePtr->inQueueHead)) { @@ -7950,14 +7939,14 @@ ChannelTimerProc( * similar test is done in "PeekAhead". */ - if ((statePtr->flags & CHANNEL_NONBLOCKING) && - (Tcl_ChannelBlockModeProc(chanPtr->typePtr) == NULL)) { + if (GotFlag(statePtr, CHANNEL_NONBLOCKING) && + (Tcl_ChannelBlockModeProc(chanPtr->typePtr) == NULL)) { SetFlag(statePtr, CHANNEL_TIMER_FEV); } #endif /* TCL_IO_TRACK_OS_FOR_DRIVER_WITH_BAD_BLOCKING */ Tcl_Preserve(statePtr); - Tcl_NotifyChannel((Tcl_Channel)chanPtr, TCL_READABLE); + Tcl_NotifyChannel((Tcl_Channel) chanPtr, TCL_READABLE); #ifdef TCL_IO_TRACK_OS_FOR_DRIVER_WITH_BAD_BLOCKING ResetFlag(statePtr, CHANNEL_TIMER_FEV); @@ -8920,7 +8909,7 @@ DoRead( */ Tcl_Preserve(chanPtr); - if (!(statePtr->flags & CHANNEL_STICKY_EOF)) { + if (!GotFlag(statePtr, CHANNEL_STICKY_EOF)) { ResetFlag(statePtr, CHANNEL_EOF); } ResetFlag(statePtr, CHANNEL_BLOCKED | CHANNEL_NEED_MORE_DATA); @@ -8929,11 +8918,11 @@ DoRead( copiedNow = CopyAndTranslateBuffer(statePtr, bufPtr + copied, toRead - copied); if (copiedNow == 0) { - if (statePtr->flags & CHANNEL_EOF) { + if (GotFlag(statePtr, CHANNEL_EOF)) { goto done; } - if (statePtr->flags & CHANNEL_BLOCKED) { - if (statePtr->flags & CHANNEL_NONBLOCKING) { + if (GotFlag(statePtr, CHANNEL_BLOCKED)) { + if (GotFlag(statePtr, CHANNEL_NONBLOCKING)) { goto done; } ResetFlag(statePtr, CHANNEL_BLOCKED); @@ -9088,7 +9077,7 @@ CopyAndTranslateBuffer( curByte = *src; if (curByte == '\n') { ResetFlag(statePtr, INPUT_SAW_CR); - } else if (statePtr->flags & INPUT_SAW_CR) { + } else if (GotFlag(statePtr, INPUT_SAW_CR)) { ResetFlag(statePtr, INPUT_SAW_CR); *dst = '\r'; dst++; @@ -9131,7 +9120,7 @@ CopyAndTranslateBuffer( *dst = '\n'; dst++; } else { - if ((curByte != '\n') || !(statePtr->flags & INPUT_SAW_CR)) { + if ((curByte != '\n') || !GotFlag(statePtr, INPUT_SAW_CR)) { *dst = (char) curByte; dst++; } @@ -10551,8 +10540,9 @@ SetChannelFromAny( * The channel is valid until any call to DetachChannel occurs. * Ensure consistency checks are done. */ - statePtr = GET_CHANNELSTATE(objPtr); - if (statePtr->flags & (CHANNEL_TAINTED|CHANNEL_CLOSED)) { + + statePtr = GET_CHANNELSTATE(objPtr); + if (GotFlag(statePtr, CHANNEL_TAINTED|CHANNEL_CLOSED)) { ResetFlag(statePtr, CHANNEL_TAINTED); Tcl_Release((ClientData) statePtr); objPtr->typePtr = NULL; @@ -10650,5 +10640,7 @@ DumpFlags( * mode: c * c-basic-offset: 4 * fill-column: 78 + * tab-width: 8 + * indent-tabs-mode: nil * End: */ -- cgit v0.12 From b8c001575a86863e6ee5002f7232c8f9cab7b274 Mon Sep 17 00:00:00 2001 From: dgp Date: Mon, 5 May 2014 17:18:51 +0000 Subject: Segfaulting test (backport of iortrans-5.11). --- tests/iogt.test | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/tests/iogt.test b/tests/iogt.test index d81acd6..abe4246 100644 --- a/tests/iogt.test +++ b/tests/iogt.test @@ -251,7 +251,17 @@ proc id_torture {chan op data} { clear_read {;#ignore} flush/write - flush/read {} - write - + write { + global level + if {$level} { + return + } + incr level + testchannel unstack $chan + testchannel transform $chan \ + -command [namespace code [list id_torture $chan]] + return $data + } read { testchannel unstack $chan testchannel transform $chan \ @@ -665,6 +675,16 @@ test iogt-2.4 {basic I/O, mixed trail} {testchannel} { close $fh set x } {} +test iogt-2.5 {basic I/O, mixed trail} {testchannel} { + set ::level 0 + set fh [open $path(dummyout) w] + torture -attach $fh + puts -nonewline $fh abcdef + flush $fh + testchannel unstack $fh + close $fh + set x +} {} test iogt-3.0 {Tcl_Channel valid after stack/unstack, fevent handling} \ {testchannel unknownFailure} { -- cgit v0.12 From d8b36a021654bbe21bf6bd9a907e8457fdb5b52b Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Tue, 6 May 2014 11:17:28 +0000 Subject: Start working on [3389978]. Appears to work, but some clean-up needed. --- tests/winFCmd.test | 4 ++-- win/tclWinFile.c | 32 ++++++++++++++++++++++++++++++-- 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/tests/winFCmd.test b/tests/winFCmd.test index bd50328..28257c6 100644 --- a/tests/winFCmd.test +++ b/tests/winFCmd.test @@ -1385,10 +1385,10 @@ test winFCmd-19.5 {Windows extended path names} -constraints nt -setup { list [catch { set f [open $tmpfile [list WRONLY CREAT]] close $f - } res] errormsg ;#$res + } res] $res } -cleanup { catch {file delete $tmpfile} -} -result [list 1 errormsg] +} -result [list 0 {}] test winFCmd-19.6 {Windows extended path names} -constraints nt -setup { set tmpfile [file join $::env(TEMP) tcl[string repeat x 248].tmp] set tmpfile //?/[file normalize $tmpfile] diff --git a/win/tclWinFile.c b/win/tclWinFile.c index fc0ac9e..e32cd94 100644 --- a/win/tclWinFile.c +++ b/win/tclWinFile.c @@ -2930,8 +2930,36 @@ TclNativeCreateNativeRep( Tcl_WinUtfToTChar(str, len, &ds); len = Tcl_DStringLength(&ds) + sizeof(WCHAR); wp = (WCHAR *) Tcl_DStringValue(&ds); - for (i=sizeof(WCHAR); i|", *wp) ){ + i=sizeof(WCHAR); + if ((wp[0]=='/'||wp[0]=='\\') && (wp[1]=='/'||wp[1]=='\\')) { + if (wp[2]=='?'){ + /* Extended path prefix: convert slashes but not the '?' */ + wp[0] = wp[1] = wp[3] = '\\'; + i += 8; wp+=4; + if (((wp[0]>='A'&&wp[0]<='Z') || (wp[0]>='a'&&wp[0]<='z')) + && (wp[1]==':') && (wp[2]=='/' || wp[2]=='\\')) { + /* With drive, don't convert the ':' */ + i += 4; wp+=2; + } + } + } else { + if (((wp[0]>='A'&&wp[0]<='Z') || (wp[0]>='a'&&wp[0]<='z')) + && (wp[1]==':') && (wp[2]=='/' || wp[2]=='\\')) { + /* With drive, don't convert the ':' */ + i += 4; wp+=2; + if (len > (MAX_PATH * sizeof(WCHAR))){ + /* Path is too long, needs an extended path prefix. */ + Tcl_DStringSetLength(&ds, len+=8); + Tcl_DStringSetLength(&ds, len+1); /* Must end with two NUL bytes */ + wp = (WCHAR *) Tcl_DStringValue(&ds); /* wp might be re-allocated */ + memmove(wp+4, wp, len-8); + memcpy(wp, L"\\\\?\\", 8); + i+=12; wp += 6; + } + } + } + for (; i?|", *wp) ){ if (!*wp){ /* See bug [3118489]: NUL in filenames */ Tcl_DecrRefCount(validPathPtr); -- cgit v0.12 From ba89a15d53a14ebf8bd49c38ce10a665f6f26181 Mon Sep 17 00:00:00 2001 From: dgp Date: Tue, 6 May 2014 13:56:29 +0000 Subject: Have to manage the lifetime of the self handle in testchannel transform. --- generic/tclIOGT.c | 15 +++++++++++++-- tests/iogt.test | 1 - 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/generic/tclIOGT.c b/generic/tclIOGT.c index beddf4f..c5372b1 100644 --- a/generic/tclIOGT.c +++ b/generic/tclIOGT.c @@ -298,7 +298,6 @@ TclChannelTransform( } Tcl_DStringFree(&ds); - dataPtr->self = chan; dataPtr->watchMask = 0; dataPtr->mode = mode; dataPtr->timer = NULL; @@ -317,6 +316,7 @@ TclChannelTransform( ReleaseData(dataPtr); return TCL_ERROR; } + Tcl_Preserve(dataPtr->self); /* * At last initialize the transformation at the script level. @@ -437,6 +437,9 @@ ExecuteCallback( break; case TRANSMIT_DOWN: + if (dataPtr->self == NULL) { + break; + } resObj = Tcl_GetObjResult(eval); resBuf = Tcl_GetByteArrayFromObj(resObj, &resLen); Tcl_WriteRaw(Tcl_GetStackedChannel(dataPtr->self), (char *) resBuf, @@ -444,6 +447,9 @@ ExecuteCallback( break; case TRANSMIT_SELF: + if (dataPtr->self == NULL) { + break; + } resObj = Tcl_GetObjResult(eval); resBuf = Tcl_GetByteArrayFromObj(resObj, &resLen); Tcl_WriteRaw(dataPtr->self, (char *) resBuf, resLen); @@ -579,6 +585,8 @@ TransformCloseProc( * General cleanup. */ + Tcl_Release(dataPtr->self); + dataPtr->self = NULL; ReleaseData(dataPtr); return TCL_OK; } @@ -614,7 +622,7 @@ TransformInputProc( * Should assert(dataPtr->mode & TCL_READABLE); */ - if (toRead == 0) { + if (toRead == 0 || dataPtr->self == NULL) { /* * Catch a no-op. */ @@ -1083,6 +1091,9 @@ TransformWatchProc( * unchanged. */ + if (dataPtr->self == NULL) { + return; + } downChan = Tcl_GetStackedChannel(dataPtr->self); Tcl_GetChannelType(downChan)->watchProc( diff --git a/tests/iogt.test b/tests/iogt.test index abe4246..d4291b3 100644 --- a/tests/iogt.test +++ b/tests/iogt.test @@ -683,7 +683,6 @@ test iogt-2.5 {basic I/O, mixed trail} {testchannel} { flush $fh testchannel unstack $fh close $fh - set x } {} test iogt-3.0 {Tcl_Channel valid after stack/unstack, fevent handling} \ -- cgit v0.12 From c4669a8b0c841482ec4a6b86c4d8a3a12578fefa Mon Sep 17 00:00:00 2001 From: dgp Date: Tue, 6 May 2014 15:23:43 +0000 Subject: Add Panic call to better identify where iogt-2.5 goes wrong. --- generic/tclIO.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/generic/tclIO.c b/generic/tclIO.c index 58c7b3c..6bf28a1 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -2311,6 +2311,9 @@ static void PreserveChannelBuffer( ChannelBuffer *bufPtr) { + if (bufPtr->refCount == 0) { + Tcl_Panic("Reuse of ChannelBuffer!"); + } bufPtr->refCount++; } -- cgit v0.12 From cc1b3e8ddcb21cf10e67fee7c26f89b40498eb53 Mon Sep 17 00:00:00 2001 From: dgp Date: Tue, 6 May 2014 17:33:55 +0000 Subject: Symptom relief. Make test stop panicking. This is not the proper final answer. ChannelBuffer management in FlushChannel is simply not robustly correct yet. --- generic/tclIO.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index 6bf28a1..dd4d489 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -2713,8 +2713,11 @@ FlushChannel( statePtr->outQueueTail = NULL; } RecycleBuffer(statePtr, bufPtr, 0); + bufPtr = NULL; + } + if (bufPtr) { + ReleaseChannelBuffer(bufPtr); } - ReleaseChannelBuffer(bufPtr); } /* Closes "while (1)". */ /* -- cgit v0.12 From 7218e5967c732e29387a5daed448c1784e490c6c Mon Sep 17 00:00:00 2001 From: dgp Date: Tue, 6 May 2014 22:34:45 +0000 Subject: Stop memory leak in io-29.27. --- generic/tclIO.c | 1 + 1 file changed, 1 insertion(+) diff --git a/generic/tclIO.c b/generic/tclIO.c index 2f652e7..fc3722c 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -2613,6 +2613,7 @@ FlushChannel( */ DiscardOutputQueued(statePtr); + ReleaseChannelBuffer(bufPtr); continue; } else { wroteSome = 1; -- cgit v0.12 From 3fd76e6ba7344534a329e50176ce30046e3c3aa2 Mon Sep 17 00:00:00 2001 From: dgp Date: Tue, 6 May 2014 23:23:43 +0000 Subject: Stop memory leak in io-29.34 --- generic/tclIO.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/generic/tclIO.c b/generic/tclIO.c index fc3722c..b2b4e5c 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -2525,6 +2525,7 @@ FlushChannel( if (errorCode == EINTR) { errorCode = 0; + ReleaseChannelBuffer(bufPtr); continue; } @@ -2546,6 +2547,7 @@ FlushChannel( UpdateInterest(chanPtr); } errorCode = 0; + ReleaseChannelBuffer(bufPtr); break; } -- cgit v0.12 From 01ccb9ccaa82c43b65c93a6a43c9f2083ec60f7e Mon Sep 17 00:00:00 2001 From: dgp Date: Tue, 6 May 2014 23:51:32 +0000 Subject: Stop leak in io-33.7. --- generic/tclIOCmd.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/generic/tclIOCmd.c b/generic/tclIOCmd.c index b206303..afd6272 100644 --- a/generic/tclIOCmd.c +++ b/generic/tclIOCmd.c @@ -345,7 +345,8 @@ Tcl_GetsObjCmd( if (objc == 3) { if (Tcl_ObjSetVar2(interp, objv[2], NULL, linePtr, TCL_LEAVE_ERR_MSG) == NULL) { - return TCL_ERROR; + code = TCL_ERROR; + goto done; } Tcl_SetObjResult(interp, Tcl_NewIntObj(lineLen)); } else { -- cgit v0.12 From 68f4187dd1e16b0dfdc6b4e03787028f0009efca Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 7 May 2014 02:28:56 +0000 Subject: Stop leak in io-53.5. --- generic/tclIO.c | 1 + 1 file changed, 1 insertion(+) diff --git a/generic/tclIO.c b/generic/tclIO.c index b2b4e5c..f2d1f44 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -3787,6 +3787,7 @@ Write( if (IsBufferFull(bufPtr)) { if (FlushChannel(NULL, chanPtr, 0) != 0) { + ReleaseChannelBuffer(bufPtr); return -1; } flushed += statePtr->bufSize; -- cgit v0.12 From 643b20e2b21c2980154dfff9a4869d5d72d4d456 Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 7 May 2014 03:30:55 +0000 Subject: Stop leaks of cloned Tcl_ChannelTypes. --- generic/tclIORChan.c | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/generic/tclIORChan.c b/generic/tclIORChan.c index 17c1593..7630473 100644 --- a/generic/tclIORChan.c +++ b/generic/tclIORChan.c @@ -1019,6 +1019,7 @@ ReflectClose( Tcl_Obj *resObj; /* Result data for 'close' */ ReflectedChannelMap* rcmPtr; /* Map of reflected channels with handlers in this interp */ Tcl_HashEntry* hPtr; /* Entry in the above map */ + Tcl_ChannelType *tctPtr; if (TclInThreadExit()) { /* @@ -1055,6 +1056,11 @@ ReflectClose( } #endif + tctPtr = ((Channel *)rcPtr->chan)->typePtr; + if (tctPtr && tctPtr != &tclRChannelType) { + ckfree((char *)tctPtr); + ((Channel *)rcPtr->chan)->typePtr = NULL; + } Tcl_EventuallyFree (rcPtr, (Tcl_FreeProc *) FreeReflectedChannel); return EOK; } @@ -1118,6 +1124,11 @@ ReflectClose( } #endif + tctPtr = ((Channel *)rcPtr->chan)->typePtr; + if (tctPtr && tctPtr != &tclRChannelType) { + ckfree((char *)tctPtr); + ((Channel *)rcPtr->chan)->typePtr = NULL; + } Tcl_EventuallyFree (rcPtr, (Tcl_FreeProc *) FreeReflectedChannel); #ifdef TCL_THREADS } @@ -2033,13 +2044,6 @@ FreeReflectedChannel( { Channel *chanPtr = (Channel *) rcPtr->chan; - if (chanPtr->typePtr != &tclRChannelType) { - /* - * Delete a cloned ChannelType structure. - */ - - ckfree((char*) chanPtr->typePtr); - } Tcl_Release(chanPtr); Tcl_DecrRefCount(rcPtr->name); Tcl_DecrRefCount(rcPtr->methods); @@ -2698,11 +2702,13 @@ ForwardProc( * call upon for the driver. */ - case ForwardedClose: + case ForwardedClose: { /* * No parameters/results. */ + Tcl_ChannelType *tctPtr; + if (InvokeTclMethod(rcPtr, METH_FINAL, NULL, NULL, &resObj)!=TCL_OK) { ForwardSetObjError(paramPtr, resObj); } @@ -2727,8 +2733,14 @@ ForwardProc( Tcl_GetChannelName (rcPtr->chan)); Tcl_DeleteHashEntry (hPtr); + tctPtr = ((Channel *)rcPtr->chan)->typePtr; + if (tctPtr && tctPtr != &tclRChannelType) { + ckfree((char *)tctPtr); + ((Channel *)rcPtr->chan)->typePtr = NULL; + } Tcl_EventuallyFree (rcPtr, (Tcl_FreeProc *) FreeReflectedChannel); break; + } case ForwardedInput: { Tcl_Obj *toReadObj = Tcl_NewIntObj(paramPtr->input.toRead); -- cgit v0.12 From 84a26717efe2e36e1a7e4dce9d9ffa12afe4271f Mon Sep 17 00:00:00 2001 From: dkf Date: Wed, 7 May 2014 22:19:30 +0000 Subject: Corrected description of where tcl_platform(user) comes from on Unix. --- doc/tclvars.n | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/tclvars.n b/doc/tclvars.n index b3e1bee..84823e0 100644 --- a/doc/tclvars.n +++ b/doc/tclvars.n @@ -284,8 +284,8 @@ was compiled with threads enabled. \fBuser\fR This identifies the current user based on the login information available on the platform. -This comes from the USER or LOGNAME environment variable on Unix, -and the value from GetUserName on Windows. +This value comes from the getuid() and getpwuid() system calls on Unix, +and the value from the GetUserName() system call on Windows. .TP \fBwordSize\fR This gives the size of the native-machine word in bytes (strictly, it -- cgit v0.12 From e29e8eee24f3d89cc4ad8db75e14d9a6fc77b026 Mon Sep 17 00:00:00 2001 From: dkf Date: Wed, 7 May 2014 22:22:02 +0000 Subject: Corrected description of where tcl_platform(user) comes from on Unix. --- doc/tclvars.n | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/tclvars.n b/doc/tclvars.n index 9d7a4ce..48ab83a 100644 --- a/doc/tclvars.n +++ b/doc/tclvars.n @@ -347,8 +347,8 @@ was compiled with threads enabled. . This identifies the current user based on the login information available on the platform. -This comes from the USER or LOGNAME environment variable on Unix, -and the value from GetUserName on Windows. +This value comes from the getuid() and getpwuid() system calls on Unix, +and the value from the GetUserName() system call on Windows. .TP \fBwordSize\fR . -- cgit v0.12 From 75e37a235a36345c619f547889a0e4663e53d599 Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 8 May 2014 02:38:52 +0000 Subject: Stop leak in iocmd-21.22. --- generic/tclIO.c | 1 + 1 file changed, 1 insertion(+) diff --git a/generic/tclIO.c b/generic/tclIO.c index f2d1f44..4628e90 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -3607,6 +3607,7 @@ static int WillRead(Channel *chanPtr) { if (chanPtr->typePtr == NULL) { /* Prevent read attempts on a closed channel */ + DiscardInputQueued(chanPtr->state, 0); Tcl_SetErrno(EINVAL); return -1; } -- cgit v0.12 From e083b8e9bb2f218ebd4ec4767953a47b1fe42773 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Thu, 8 May 2014 12:46:47 +0000 Subject: More efficient/robust implementation of function TclNativeCreateNativeRep(). - No more intermediate results in a Tcl_DString, just allocate space directly. - Let MultiByteToWideChar() do all the difficult work, inclusive checking for invalid byte sequences. - Handled extended win32 paths, inclusive UNC paths. Implementation for a great deal taken over from fossil. --- win/tclWinFile.c | 109 ++++++++++++++++++++++++++++++++----------------------- 1 file changed, 63 insertions(+), 46 deletions(-) diff --git a/win/tclWinFile.c b/win/tclWinFile.c index e32cd94..5761eeb 100644 --- a/win/tclWinFile.c +++ b/win/tclWinFile.c @@ -2897,10 +2897,10 @@ ClientData TclNativeCreateNativeRep( Tcl_Obj *pathPtr) { - char *nativePathPtr, *str; - Tcl_DString ds; + WCHAR *nativePathPtr; + const char *str; Tcl_Obj *validPathPtr; - int len, i = 2; + int len; WCHAR *wp; if (TclFSCwdIsNative()) { @@ -2927,55 +2927,72 @@ TclNativeCreateNativeRep( } str = Tcl_GetStringFromObj(validPathPtr, &len); - Tcl_WinUtfToTChar(str, len, &ds); - len = Tcl_DStringLength(&ds) + sizeof(WCHAR); - wp = (WCHAR *) Tcl_DStringValue(&ds); - i=sizeof(WCHAR); - if ((wp[0]=='/'||wp[0]=='\\') && (wp[1]=='/'||wp[1]=='\\')) { - if (wp[2]=='?'){ - /* Extended path prefix: convert slashes but not the '?' */ - wp[0] = wp[1] = wp[3] = '\\'; - i += 8; wp+=4; - if (((wp[0]>='A'&&wp[0]<='Z') || (wp[0]>='a'&&wp[0]<='z')) - && (wp[1]==':') && (wp[2]=='/' || wp[2]=='\\')) { - /* With drive, don't convert the ':' */ - i += 4; wp+=2; - } - } - } else { - if (((wp[0]>='A'&&wp[0]<='Z') || (wp[0]>='a'&&wp[0]<='z')) - && (wp[1]==':') && (wp[2]=='/' || wp[2]=='\\')) { - /* With drive, don't convert the ':' */ - i += 4; wp+=2; - if (len > (MAX_PATH * sizeof(WCHAR))){ - /* Path is too long, needs an extended path prefix. */ - Tcl_DStringSetLength(&ds, len+=8); - Tcl_DStringSetLength(&ds, len+1); /* Must end with two NUL bytes */ - wp = (WCHAR *) Tcl_DStringValue(&ds); /* wp might be re-allocated */ - memmove(wp+4, wp, len-8); - memcpy(wp, L"\\\\?\\", 8); - i+=12; wp += 6; - } + + if (strlen(str)!=len) { + /* String contains NUL-bytes. This is invalid. */ + return 0; + } + /* Let MultiByteToWideChar check for other invalid sequences, like + * 0xC0 0x80 (== overlong NUL). See bug [3118489]: NUL in filenames */ + len = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, str, -1, 0, 0); + if (len==0) { + return 0; + } + /* Overallocate 6 chars, making some room for extended paths */ + wp = nativePathPtr = ckalloc( (len+6) * sizeof(WCHAR) ); + if (nativePathPtr==0) { + return 0; + } + MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, str, -1, nativePathPtr, len); + /* + ** If path starts with "//?/" or "\\?\" (extended path), translate + ** any slashes to backslashes but leave the '?' intact + */ + if ((str[0]=='\\' || str[0]=='/') && (str[1]=='\\' || str[1]=='/') + && str[2]=='?' && (str[3]=='\\' || str[3]=='/')) { + wp[0] = wp[1] = wp[3] = '\\'; + str += 4; + wp += 4; + } + /* + ** If there is no "\\?\" prefix but there is a drive or UNC + ** path prefix and the path is larger than MAX_PATH chars, + ** no Win32 API function can handle that unless it is + ** prefixed with the extended path prefix. See: + ** + **/ + if (((str[0]>='A'&&str[0]<='Z') || (str[0]>='a'&&str[0]<='z')) + && str[1]==':' && (str[2]=='\\' || str[2]=='/')) { + if (wp==nativePathPtr && len>MAX_PATH) { + memmove(wp+4, wp, len*sizeof(WCHAR)); + memcpy(wp, L"\\\\?\\", 4*sizeof(WCHAR)); + wp += 4; } + /* + ** If (remainder of) path starts with ":/" or ":\", + ** leave the ':' intact but translate the backslash to a slash. + */ + wp[2] = '\\'; + wp += 3; + } else if (wp==nativePathPtr && len>MAX_PATH + && (str[0]=='\\' || str[0]=='/') + && (str[1]=='\\' || str[1]=='/') && str[2]!='?') { + memmove(wp+6, wp, len*sizeof(WCHAR)); + memcpy(wp, L"\\\\?\\UNC", 7*sizeof(WCHAR)); + wp += 7; } - for (; i?|", *wp) ){ - if (!*wp){ - /* See bug [3118489]: NUL in filenames */ - Tcl_DecrRefCount(validPathPtr); - Tcl_DStringFree(&ds); - return NULL; - } + /* + ** In the remainder of the path, translate invalid characters to + ** characters in the Unicode private use area. + */ + while (*wp != '\0') { + if ((*wp < ' ') || wcschr(L"\"*:<>?|", *wp)) { *wp |= 0xF000; - }else if (*wp=='/') { + } else if (*wp == '/') { *wp = '\\'; } + ++wp; } - Tcl_DecrRefCount(validPathPtr); - nativePathPtr = ckalloc(len); - memcpy(nativePathPtr, Tcl_DStringValue(&ds), (size_t) len); - - Tcl_DStringFree(&ds); return nativePathPtr; } -- cgit v0.12 From 04fbce15ca31469ea16a9969a13f06d384454d30 Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 8 May 2014 13:01:47 +0000 Subject: Revert the iogt-2.5 fix. For now one panic is better than widespread memory leaks. --- generic/tclIO.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index d69a3d9..678dc4b 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -2716,11 +2716,8 @@ FlushChannel( statePtr->outQueueTail = NULL; } RecycleBuffer(statePtr, bufPtr, 0); - bufPtr = NULL; - } - if (bufPtr) { - ReleaseChannelBuffer(bufPtr); } + ReleaseChannelBuffer(bufPtr); } /* Closes "while (1)". */ /* -- cgit v0.12 From f54edc88cf77d0730beab7375ae4e3f4c3e87585 Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 8 May 2014 16:03:50 +0000 Subject: Fix the panic in iogt-2.5. Back in 2011, Bugs 3384654 and 3393276 first noticed troubles with ChannelBuffer sharing, but the magnitude of the problem wasn't truly grasped. A fix was applied that turned out to be more of a band-aid workaround. Now that the real fix is in place, the band-aid is actually preventing it working properly in thie case. Rip it off! --- generic/tclIO.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index 678dc4b..8dd9218 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -2312,7 +2312,7 @@ PreserveChannelBuffer( ChannelBuffer *bufPtr) { if (bufPtr->refCount == 0) { - Tcl_Panic("Reuse of ChannelBuffer!"); + Tcl_Panic("Reuse of ChannelBuffer! %p", bufPtr); } bufPtr->refCount++; } @@ -2702,9 +2702,7 @@ FlushChannel( wroteSome = 1; } - if (!IsBufferEmpty(bufPtr)) { - bufPtr->nextRemoved += written; - } + bufPtr->nextRemoved += written; /* * If this buffer is now empty, recycle it. -- cgit v0.12 From fa53de3d9074955a4c9f6281ca1e8750c470c85f Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 8 May 2014 16:21:12 +0000 Subject: silence compiler warning --- generic/tclIORChan.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/generic/tclIORChan.c b/generic/tclIORChan.c index 12fa4a0..0b462c4 100644 --- a/generic/tclIORChan.c +++ b/generic/tclIORChan.c @@ -1111,7 +1111,7 @@ ReflectClose( ReflectedChannelMap *rcmPtr;/* Map of reflected channels with handlers in * this interp */ Tcl_HashEntry *hPtr; /* Entry in the above map */ - Tcl_ChannelType *tctPtr; + const Tcl_ChannelType *tctPtr; if (TclInThreadExit()) { /* @@ -2881,7 +2881,7 @@ ForwardProc( * No parameters/results. */ - Tcl_ChannelType *tctPtr; + const Tcl_ChannelType *tctPtr; if (InvokeTclMethod(rcPtr, METH_FINAL, NULL, NULL, &resObj)!=TCL_OK) { ForwardSetObjError(paramPtr, resObj); -- cgit v0.12 From 61c463f55f3324d94a9142319ccb1bfe535f196c Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Fri, 9 May 2014 10:08:56 +0000 Subject: Make Cygwin's "configure" work from another directory than /unix. (Not everything works this way!) --- unix/configure | 4 ++-- unix/tcl.m4 | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/unix/configure b/unix/configure index 02a3725..d268647 100755 --- a/unix/configure +++ b/unix/configure @@ -7010,9 +7010,9 @@ echo "$as_me: error: CYGWIN compile is only supported with --enable-threads" >&2 fi do64bit_ok=yes if test "x${SHARED_BUILD}" = "x1"; then - echo "running cd ../win; ${CONFIG_SHELL-/bin/sh} ./configure $ac_configure_args" + echo "running cd ${TCL_SRC_DIR}/win; ${CONFIG_SHELL-/bin/sh} ./configure $ac_configure_args" # The eval makes quoting arguments work. - if cd ../win; eval ${CONFIG_SHELL-/bin/sh} ./configure $ac_configure_args; cd ../unix + if cd ${TCL_SRC_DIR}/win; eval ${CONFIG_SHELL-/bin/sh} ./configure $ac_configure_args; cd ../unix then : else { echo "configure: error: configure failed for ../win" 1>&2; exit 1; } diff --git a/unix/tcl.m4 b/unix/tcl.m4 index 10408a8..b6c86b6 100644 --- a/unix/tcl.m4 +++ b/unix/tcl.m4 @@ -1266,9 +1266,9 @@ AC_DEFUN([SC_CONFIG_CFLAGS], [ fi do64bit_ok=yes if test "x${SHARED_BUILD}" = "x1"; then - echo "running cd ../win; ${CONFIG_SHELL-/bin/sh} ./configure $ac_configure_args" + echo "running cd ${TCL_SRC_DIR}/win; ${CONFIG_SHELL-/bin/sh} ./configure $ac_configure_args" # The eval makes quoting arguments work. - if cd ../win; eval ${CONFIG_SHELL-/bin/sh} ./configure $ac_configure_args; cd ../unix + if cd ${TCL_SRC_DIR}/win; eval ${CONFIG_SHELL-/bin/sh} ./configure $ac_configure_args; cd ../unix then : else { echo "configure: error: configure failed for ../win" 1>&2; exit 1; } -- cgit v0.12 From a84b51c1b4d6b6279e7ee1dbb533cc9b9dab6085 Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 9 May 2014 13:19:30 +0000 Subject: Test iocmd-32.1 is not "impossible" but after writing it properly it does segfault trying to use a deleted interp. Fixed. --- generic/tclIORChan.c | 12 +++++++++++- tests/ioCmd.test | 9 ++++----- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/generic/tclIORChan.c b/generic/tclIORChan.c index 7630473..3107f9e 100644 --- a/generic/tclIORChan.c +++ b/generic/tclIORChan.c @@ -438,8 +438,8 @@ static const char *msg_write_nothing = "{write wrote nothing}"; static const char *msg_seek_beforestart = "{Tried to seek before origin}"; #ifdef TCL_THREADS static const char *msg_send_originlost = "{Channel thread lost}"; -static const char *msg_send_dstlost = "{Owner lost}"; #endif /* TCL_THREADS */ +static const char *msg_send_dstlost = "{Owner lost}"; static const char *msg_dstlost = "-code 1 -level 0 -errorcode NONE -errorinfo {} -errorline 1 {Owner lost}"; /* @@ -1302,6 +1302,7 @@ ReflectOutput( /* ASSERT: rcPtr->mode & TCL_WRITABLE */ Tcl_Preserve(rcPtr); + Tcl_Preserve(rcPtr->interp); bufObj = Tcl_NewByteArrayObj((unsigned char *) buf, toWrite); Tcl_IncrRefCount(bufObj); @@ -1318,6 +1319,14 @@ ReflectOutput( goto invalid; } + if (Tcl_InterpDeleted(rcPtr->interp)) { + /* + * The interp was destroyed during InvokeTclMethod(). + */ + + SetChannelErrorStr(rcPtr->chan, msg_send_dstlost); + goto invalid; + } if (Tcl_GetIntFromObj(rcPtr->interp, resObj, &written) != TCL_OK) { Tcl_SetChannelError(rcPtr->chan, MarshallError(rcPtr->interp)); goto invalid; @@ -1347,6 +1356,7 @@ ReflectOutput( stop: Tcl_DecrRefCount(bufObj); Tcl_DecrRefCount(resObj); /* Remove reference held from invoke */ + Tcl_Release(rcPtr->interp); Tcl_Release(rcPtr); return written; invalid: diff --git a/tests/ioCmd.test b/tests/ioCmd.test index bb133f9..5a76d48 100644 --- a/tests/ioCmd.test +++ b/tests/ioCmd.test @@ -2038,13 +2038,13 @@ test iocmd-32.1 {origin interpreter of moved channel destroyed during access} -m proc foo {args} { oninit; onfinal; track; # destroy interpreter during channel access - # Actually not possible for an interp to destroy itself. - interp delete {} - return} + suicide + } set chan [chan create {r w} foo] fconfigure $chan -buffering none set chan }] + interp alias $ida suicide {} interp delete $ida # Move channel to 2nd thread. interp eval $ida [list testchannel cut $chan] @@ -2063,8 +2063,7 @@ test iocmd-32.1 {origin interpreter of moved channel destroyed during access} -m set res }] set res -} -constraints {testchannel impossible} \ - -result {Owner lost} +} -constraints {testchannel} -result {Owner lost} test iocmd-32.2 {delete interp of reflected chan} { # Bug 3034840 -- cgit v0.12 From d7461d07ad79630ccb7605ea15e47e50aaea44a9 Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 9 May 2014 16:31:06 +0000 Subject: Tests (chan)io-34.21 are constrained for largefileSupport, and that's disabled by default, which means never tested, which means the ridiculous bugs in them are never found and fixed. Fixed the bugs, changed the default. Large File Suppport (4GB) is commonplace now. Let those without it suffer a few failing tests reporting that fact to them. --- tests/chanio.test | 6 +++--- tests/io.test | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/chanio.test b/tests/chanio.test index b195f7b..5ea7ec1 100644 --- a/tests/chanio.test +++ b/tests/chanio.test @@ -41,7 +41,7 @@ namespace eval ::tcl::test::io { # You need a *very* special environment to do some tests. In # particular, many file systems do not support large-files... - testConstraint largefileSupport 0 + testConstraint largefileSupport 1 # some tests can only be run is umask is 2 # if "umask" cannot be run, the tests will be skipped. @@ -4427,10 +4427,10 @@ test chan-io-34.21 {Tcl_Seek and Tcl_Tell on large files} {largefileSupport} { chan puts -nonewline $f abcdef lappend l [chan tell $f] chan close $f - lappend l [file size $f] + lappend l [file size $path(test3)] # truncate... chan close [open $path(test3) w] - lappend l [file size $f] + lappend l [file size $path(test3)] set l } {0 6 6 4294967296 4294967302 4294967302 0} diff --git a/tests/io.test b/tests/io.test index 7707a28..7f1a357 100644 --- a/tests/io.test +++ b/tests/io.test @@ -41,7 +41,7 @@ testConstraint testthread [llength [info commands testthread]] # You need a *very* special environment to do some tests. In # particular, many file systems do not support large-files... -testConstraint largefileSupport 0 +testConstraint largefileSupport 1 # some tests can only be run is umask is 2 # if "umask" cannot be run, the tests will be skipped. @@ -4433,10 +4433,10 @@ test io-34.21 {Tcl_Seek and Tcl_Tell on large files} {largefileSupport} { puts -nonewline $f abcdef lappend l [tell $f] close $f - lappend l [file size $f] + lappend l [file size $path(test3)] # truncate... close [open $path(test3) w] - lappend l [file size $f] + lappend l [file size $path(test3)] set l } {0 6 6 4294967296 4294967302 4294967302 0} -- cgit v0.12 From 8b4cb6f5d95d707abacdcfbcb75153cd12edb59f Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 9 May 2014 16:38:23 +0000 Subject: Added comment explaining the "knownBug" in iogt-6.1 --- tests/iogt.test | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/iogt.test b/tests/iogt.test index d4291b3..20d7538 100644 --- a/tests/iogt.test +++ b/tests/iogt.test @@ -968,6 +968,15 @@ test iogt-6.0 {Push back} testchannel { } {xxx} test iogt-6.1 {Push back and up} {testchannel knownBug} { + + # This test demonstrates the bug/misfeature in the stacked + # channel implementation that data can be discarded if it is + # read into the buffers of one channel in the stack, and then + # that channel is popped before anything above it reads. + # + # This bug can be worked around by always setting -buffersize + # to 1, but who wants to do that? + set f [open $path(dummy) r] # contents of dummy = "abcdefghi..." -- cgit v0.12 From 1b7b5e839ce087299e2b57ad508743da5c88b0ea Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 9 May 2014 16:55:34 +0000 Subject: Correct namespace bugs in normally skipped tests. Constrain them as "knownBug" rather than "unknownFailure". --- tests/iogt.test | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/tests/iogt.test b/tests/iogt.test index 20d7538..0e2eb3c 100644 --- a/tests/iogt.test +++ b/tests/iogt.test @@ -159,8 +159,8 @@ proc fevent {fdelay idelay blocks script data} { #puts stdout ">>>>>" ; flush stdout - uplevel #0 set sock $sk - set res [uplevel #0 $script] + uplevel 1 set sock $sk + set res [uplevel 1 $script] catch {close $sk} return $res @@ -686,7 +686,7 @@ test iogt-2.5 {basic I/O, mixed trail} {testchannel} { } {} test iogt-3.0 {Tcl_Channel valid after stack/unstack, fevent handling} \ - {testchannel unknownFailure} { + {testchannel knownBug} { # This test to check the validity of aquired 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 @@ -703,6 +703,7 @@ test iogt-3.0 {Tcl_Channel valid after stack/unstack, fevent handling} \ set fin [open $path(dummy) r] fevent 1000 500 {20 20 20 10 1 1} { + variable copy close $fin set fout [open dummyout w] @@ -740,7 +741,7 @@ test iogt-3.0 {Tcl_Channel valid after stack/unstack, fevent handling} \ } {1 {create/write create/read write flush/write flush/read delete/write delete/read}} -test iogt-4.0 {fileevent readable, after transform} {testchannel unknownFailure} { +test iogt-4.0 {fileevent readable, after transform} {testchannel knownBug} { set fin [open $path(dummy) r] set data [read $fin] close $fin @@ -770,10 +771,11 @@ test iogt-4.0 {fileevent readable, after transform} {testchannel unknownFailure} } fevent 1000 500 {20 20 20 10 1} { + variable stop audit_flow trail -attach $sock rblocks_t rbuf trail 23 -attach $sock - fileevent $sock readable [list Get $sock] + fileevent $sock readable [namespace code [list Get $sock]] flush $sock ; # now, or fcopy will error us out # But the 1 second delay should be enough to @@ -871,7 +873,7 @@ delete/write {} *ignored* delete/read {} *ignored*} ; # catch unescaped quote " -test iogt-5.0 {EOF simulation} {testchannel unknownFailure} { +test iogt-5.0 {EOF simulation} {testchannel knownBug} { set fin [open $path(dummy) r] set fout [open $path(dummyout) w] -- cgit v0.12 From 73f53667edbf72a3b3f591e5af3fe5abbc405377 Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 9 May 2014 17:46:45 +0000 Subject: Repair another "impossible" test and the segfault it reveals. --- generic/tclIORTrans.c | 2 ++ tests/ioTrans.test | 10 +++++----- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/generic/tclIORTrans.c b/generic/tclIORTrans.c index 1de635f..1dff4b3 100644 --- a/generic/tclIORTrans.c +++ b/generic/tclIORTrans.c @@ -2010,6 +2010,7 @@ InvokeTclMethod( sr = Tcl_SaveInterpState(rtPtr->interp, 0 /* Dummy */); Tcl_Preserve(rtPtr); + Tcl_Preserve(rtPtr->interp); result = Tcl_EvalObjv(rtPtr->interp, cmdc, rtPtr->argv, TCL_EVAL_GLOBAL); /* @@ -2054,6 +2055,7 @@ InvokeTclMethod( Tcl_IncrRefCount(resObj); } Tcl_RestoreInterpState(rtPtr->interp, sr); + Tcl_Release(rtPtr->interp); Tcl_Release(rtPtr); /* diff --git a/tests/ioTrans.test b/tests/ioTrans.test index 7f4f7f0..c40621b 100644 --- a/tests/ioTrans.test +++ b/tests/ioTrans.test @@ -1034,7 +1034,7 @@ test iortrans-11.1 {origin interpreter of moved transform destroyed during acces # Magic to get the test* commands in the slaves load {} Tcltest $ida load {} Tcltest $idb -} -constraints {testchannel impossible} -match glob -body { +} -constraints {testchannel} -match glob -body { # Set up channel in thread set chan [interp eval $ida $helperscript] set chan [interp eval $ida { @@ -1042,14 +1042,14 @@ test iortrans-11.1 {origin interpreter of moved transform destroyed during acces handle.initialize clear drain flush limit? read write handle.finalize lappend ::res $args - # Destroy interpreter during channel access. Actually not - # possible for an interp to destroy itself. - interp delete {} - return} + # Destroy interpreter during channel access. + suicide + } set chan [chan push [tempchan] foo] fconfigure $chan -buffering none set chan }] + interp alias $ida suicide {} interp delete $ida # Move channel to 2nd thread, transform goes with it. interp eval $ida [list testchannel cut $chan] interp eval $idb [list testchannel splice $chan] -- cgit v0.12 From a4eef46453e48d4ee14d21d20e9b484c4da21e4d Mon Sep 17 00:00:00 2001 From: dkf Date: Sun, 11 May 2014 10:39:14 +0000 Subject: [6d2f249a01] Handle a failure to comprehend half-way through the compilation of a chain of compileable ensembles. --- generic/tclEnsemble.c | 24 +++++++++++++++++------- tests/namespace.test | 4 ++++ 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/generic/tclEnsemble.c b/generic/tclEnsemble.c index 9bb7a0c..022dafa 100644 --- a/generic/tclEnsemble.c +++ b/generic/tclEnsemble.c @@ -2751,13 +2751,6 @@ TclCompileEnsemble( const char *word; Tcl_IncrRefCount(replaced); - - /* - * This is where we return to if we are parsing multiple nested compiled - * ensembles. [info object] is such a beast. - */ - - checkNextWord: if (parsePtr->numWords < depth + 1) { goto failed; } @@ -2769,6 +2762,12 @@ TclCompileEnsemble( goto failed; } + /* + * This is where we return to if we are parsing multiple nested compiled + * ensembles. [info object] is such a beast. + */ + + checkNextWord: word = tokenPtr[1].start; numBytes = tokenPtr[1].size; @@ -2979,6 +2978,17 @@ TclCompileEnsemble( if (cmdPtr->compileProc == TclCompileEnsemble) { tokenPtr = TokenAfter(tokenPtr); + if (parsePtr->numWords < depth + 1 + || tokenPtr->type != TCL_TOKEN_SIMPLE_WORD) { + /* + * Too hard because the user has done something unpleasant like + * omitting the sub-ensemble's command name or used a non-constant + * name for a sub-ensemble's command name; we respond by bailing + * out completely (this is a rare case). [Bug 6d2f249a01] + */ + + goto cleanup; + } ensemble = (Tcl_Command) cmdPtr; goto checkNextWord; } diff --git a/tests/namespace.test b/tests/namespace.test index fab0040..cded1f4 100644 --- a/tests/namespace.test +++ b/tests/namespace.test @@ -2949,6 +2949,10 @@ test namespace-54.1 {leak on namespace deletion} -constraints {memory} \ rename getbytes {} unset i ns start end } -result 0 + +test namespace-55.1 {compiled ensembles inside compiled ensembles: Bug 6d2f249a01} { + info class [format %s constructor] oo::object +} "" # cleanup catch {rename cmd1 {}} -- cgit v0.12 From 5d76c6e6c02e0031a79e9862097b2b9ad84274e0 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Mon, 12 May 2014 13:09:00 +0000 Subject: Possible fix for [47d66253c92197d30bff280b02e0a9e62f07cee2|47d66253c9]: "lsearch -sorted -integer" on 64bit system --- generic/tclCmdIL.c | 29 +++++++++++++++-------------- generic/tclExecute.c | 24 ------------------------ generic/tclInt.h | 24 ++++++++++++++++++++++++ 3 files changed, 39 insertions(+), 38 deletions(-) diff --git a/generic/tclCmdIL.c b/generic/tclCmdIL.c index 41c1eb6..db216e5 100644 --- a/generic/tclCmdIL.c +++ b/generic/tclCmdIL.c @@ -29,7 +29,7 @@ typedef struct SortElement { union { /* The value that we sorting by. */ const char *strValuePtr; - long intValue; + Tcl_WideInt wideValue; double doubleValue; Tcl_Obj *objValuePtr; } collationKey; @@ -2893,7 +2893,8 @@ Tcl_LsearchObjCmd( { const char *bytes, *patternBytes; int i, match, index, result, listc, length, elemLen, bisect; - int dataType, isIncreasing, lower, upper, patInt, objInt, offset; + int dataType, isIncreasing, lower, upper, offset; + Tcl_WideInt patWide, objWide; int allMatches, inlineReturn, negatedMatch, returnSubindices, noCase; double patDouble, objDouble; SortInfo sortInfo; @@ -3212,7 +3213,7 @@ Tcl_LsearchObjCmd( patternBytes = TclGetStringFromObj(patObj, &length); break; case INTEGER: - result = TclGetIntFromObj(interp, patObj, &patInt); + result = TclGetWideIntFromObj(interp, patObj, &patWide); if (result != TCL_OK) { goto done; } @@ -3281,13 +3282,13 @@ Tcl_LsearchObjCmd( match = DictionaryCompare(patternBytes, bytes); break; case INTEGER: - result = TclGetIntFromObj(interp, itemPtr, &objInt); + result = TclGetWideIntFromObj(interp, itemPtr, &objWide); if (result != TCL_OK) { goto done; } - if (patInt == objInt) { + if (patWide == objWide) { match = 0; - } else if (patInt < objInt) { + } else if (patWide < objWide) { match = -1; } else { match = 1; @@ -3400,14 +3401,14 @@ Tcl_LsearchObjCmd( break; case INTEGER: - result = TclGetIntFromObj(interp, itemPtr, &objInt); + result = TclGetWideIntFromObj(interp, itemPtr, &objWide); if (result != TCL_OK) { if (listPtr != NULL) { Tcl_DecrRefCount(listPtr); } goto done; } - match = (objInt == patInt); + match = (objWide == patWide); break; case REAL: @@ -3971,13 +3972,13 @@ Tcl_LsortObjCmd( if (sortMode == SORTMODE_ASCII) { elementArray[i].collationKey.strValuePtr = TclGetString(indexPtr); } else if (sortMode == SORTMODE_INTEGER) { - long a; + Tcl_WideInt a; - if (TclGetLongFromObj(sortInfo.interp, indexPtr, &a) != TCL_OK) { + if (TclGetWideIntFromObj(sortInfo.interp, indexPtr, &a) != TCL_OK) { sortInfo.resultCode = TCL_ERROR; goto done1; } - elementArray[i].collationKey.intValue = a; + elementArray[i].collationKey.wideValue = a; } else if (sortMode == SORTMODE_REAL) { double a; @@ -4226,10 +4227,10 @@ SortCompare( order = DictionaryCompare(elemPtr1->collationKey.strValuePtr, elemPtr2->collationKey.strValuePtr); } else if (infoPtr->sortMode == SORTMODE_INTEGER) { - long a, b; + Tcl_WideInt a, b; - a = elemPtr1->collationKey.intValue; - b = elemPtr2->collationKey.intValue; + a = elemPtr1->collationKey.wideValue; + b = elemPtr2->collationKey.wideValue; order = ((a >= b) - (a <= b)); } else if (infoPtr->sortMode == SORTMODE_REAL) { double a, b; diff --git a/generic/tclExecute.c b/generic/tclExecute.c index 4ecca5b..d8c5935 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -556,30 +556,6 @@ VarHashCreateVar( : Tcl_GetBooleanFromObj((interp), (objPtr), (boolPtr))) /* - * Macro used in this file to save a function call for common uses of - * Tcl_GetWideIntFromObj(). The ANSI C "prototype" is: - * - * MODULE_SCOPE int TclGetWideIntFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, - * Tcl_WideInt *wideIntPtr); - */ - -#ifdef TCL_WIDE_INT_IS_LONG -#define TclGetWideIntFromObj(interp, objPtr, wideIntPtr) \ - (((objPtr)->typePtr == &tclIntType) \ - ? (*(wideIntPtr) = (Tcl_WideInt) \ - ((objPtr)->internalRep.longValue), TCL_OK) : \ - Tcl_GetWideIntFromObj((interp), (objPtr), (wideIntPtr))) -#else /* !TCL_WIDE_INT_IS_LONG */ -#define TclGetWideIntFromObj(interp, objPtr, wideIntPtr) \ - (((objPtr)->typePtr == &tclWideIntType) \ - ? (*(wideIntPtr) = (objPtr)->internalRep.wideValue, TCL_OK) : \ - ((objPtr)->typePtr == &tclIntType) \ - ? (*(wideIntPtr) = (Tcl_WideInt) \ - ((objPtr)->internalRep.longValue), TCL_OK) : \ - Tcl_GetWideIntFromObj((interp), (objPtr), (wideIntPtr))) -#endif /* TCL_WIDE_INT_IS_LONG */ - -/* * Macro used to make the check for type overflow more mnemonic. This works by * comparing sign bits; the rest of the word is irrelevant. The ANSI C * "prototype" (where inttype_t is any integer type) is: diff --git a/generic/tclInt.h b/generic/tclInt.h index d775a4a..b1a368e 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -2453,6 +2453,30 @@ typedef struct List { #endif /* + * Macro used to save a function call for common uses of + * Tcl_GetWideIntFromObj(). The ANSI C "prototype" is: + * + * MODULE_SCOPE int TclGetWideIntFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, + * Tcl_WideInt *wideIntPtr); + */ + +#ifdef TCL_WIDE_INT_IS_LONG +#define TclGetWideIntFromObj(interp, objPtr, wideIntPtr) \ + (((objPtr)->typePtr == &tclIntType) \ + ? (*(wideIntPtr) = (Tcl_WideInt) \ + ((objPtr)->internalRep.longValue), TCL_OK) : \ + Tcl_GetWideIntFromObj((interp), (objPtr), (wideIntPtr))) +#else /* !TCL_WIDE_INT_IS_LONG */ +#define TclGetWideIntFromObj(interp, objPtr, wideIntPtr) \ + (((objPtr)->typePtr == &tclWideIntType) \ + ? (*(wideIntPtr) = (objPtr)->internalRep.wideValue, TCL_OK) : \ + ((objPtr)->typePtr == &tclIntType) \ + ? (*(wideIntPtr) = (Tcl_WideInt) \ + ((objPtr)->internalRep.longValue), TCL_OK) : \ + Tcl_GetWideIntFromObj((interp), (objPtr), (wideIntPtr))) +#endif /* TCL_WIDE_INT_IS_LONG */ + +/* * Flag values for TclTraceDictPath(). * * DICT_PATH_READ indicates that all entries on the path must exist but no -- cgit v0.12 From 7156085860588c9eeff8cbef15d94d3d4db8da0c Mon Sep 17 00:00:00 2001 From: dgp Date: Mon, 12 May 2014 17:19:16 +0000 Subject: Have the [chan push] machinery ReadRaw() directly into the argument to be passed to the read method of the channel transformation command. Save a copy. --- generic/tclIORTrans.c | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/generic/tclIORTrans.c b/generic/tclIORTrans.c index 1dff4b3..b9dd1d6 100644 --- a/generic/tclIORTrans.c +++ b/generic/tclIORTrans.c @@ -457,8 +457,7 @@ static void TimerKill(ReflectedTransform *rtPtr); static void TimerSetup(ReflectedTransform *rtPtr); static void TimerRun(ClientData clientData); static int TransformRead(ReflectedTransform *rtPtr, - int *errorCodePtr, unsigned char *buf, - int toRead); + int *errorCodePtr, Tcl_Obj *bufObj); static int TransformWrite(ReflectedTransform *rtPtr, int *errorCodePtr, unsigned char *buf, int toWrite); @@ -1063,6 +1062,7 @@ ReflectInput( { ReflectedTransform *rtPtr = clientData; int gotBytes, copied, readBytes; + Tcl_Obj *bufObj; /* * The following check can be done before thread redirection, because we @@ -1078,6 +1078,9 @@ ReflectInput( Tcl_Preserve(rtPtr); + /* TODO: Consider a more appropriate buffer size. */ + bufObj = Tcl_NewByteArrayObj(NULL, toRead); + Tcl_IncrRefCount(bufObj); gotBytes = 0; while (toRead > 0) { /* @@ -1129,7 +1132,9 @@ ReflectInput( goto stop; } - readBytes = Tcl_ReadRaw(rtPtr->parent, buf, toRead); + + readBytes = Tcl_ReadRaw(rtPtr->parent, + (char *) Tcl_SetByteArrayLength(bufObj, toRead), toRead); if (readBytes < 0) { /* * Report errors to caller. The state of the seek system is @@ -1213,12 +1218,20 @@ ReflectInput( * iteration will put it into the result. */ - if (!TransformRead(rtPtr, errorCodePtr, UCHARP(buf), readBytes)) { + Tcl_SetByteArrayLength(bufObj, readBytes); + if (!TransformRead(rtPtr, errorCodePtr, bufObj)) { goto error; } + if (Tcl_IsShared(bufObj)) { + Tcl_DecrRefCount(bufObj); + bufObj = Tcl_NewObj(); + Tcl_IncrRefCount(bufObj); + } + Tcl_SetByteArrayLength(bufObj, 0); } /* while toRead > 0 */ stop: + Tcl_DecrRefCount(bufObj); Tcl_Release(rtPtr); return gotBytes; @@ -3067,10 +3080,8 @@ static int TransformRead( ReflectedTransform *rtPtr, int *errorCodePtr, - unsigned char *buf, - int toRead) + Tcl_Obj *bufObj) { - Tcl_Obj *bufObj; Tcl_Obj *resObj; int bytec; /* Number of returned bytes */ unsigned char *bytev; /* Array of returned bytes */ @@ -3083,8 +3094,8 @@ TransformRead( if (rtPtr->thread != Tcl_GetCurrentThread()) { ForwardParam p; - p.transform.buf = (char *) buf; - p.transform.size = toRead; + p.transform.buf = (char *) Tcl_GetByteArrayFromObj(bufObj, + &(p.transform.size)); ForwardOpToOwnerThread(rtPtr, ForwardedInput, &p); @@ -3104,12 +3115,8 @@ TransformRead( /* ASSERT: rtPtr->method & FLAG(METH_READ) */ /* ASSERT: rtPtr->mode & TCL_READABLE */ - bufObj = Tcl_NewByteArrayObj((unsigned char *) buf, toRead); - Tcl_IncrRefCount(bufObj); - if (InvokeTclMethod(rtPtr, "read", bufObj, NULL, &resObj) != TCL_OK) { Tcl_SetChannelError(rtPtr->chan, resObj); - Tcl_DecrRefCount(bufObj); Tcl_DecrRefCount(resObj); /* Remove reference held from invoke */ *errorCodePtr = EINVAL; return 0; @@ -3118,7 +3125,6 @@ TransformRead( bytev = Tcl_GetByteArrayFromObj(resObj, &bytec); ResultAdd(&rtPtr->result, bytev, bytec); - Tcl_DecrRefCount(bufObj); Tcl_DecrRefCount(resObj); /* Remove reference held from invoke */ return 1; } -- cgit v0.12 From 29055898b0e66169e5fa34f0299b603afcdbb49c Mon Sep 17 00:00:00 2001 From: dgp Date: Mon, 12 May 2014 21:50:55 +0000 Subject: Restore the largefileSupport constraint on Darwin, where tests (chan)io-34.21 take an unbearable 90 seconds each to complete. --- tests/chanio.test | 2 +- tests/io.test | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/chanio.test b/tests/chanio.test index 5ea7ec1..2f2540e 100644 --- a/tests/chanio.test +++ b/tests/chanio.test @@ -41,7 +41,7 @@ namespace eval ::tcl::test::io { # You need a *very* special environment to do some tests. In # particular, many file systems do not support large-files... - testConstraint largefileSupport 1 + testConstraint largefileSupport [expr {$::tcl_platform(os) ne "Darwin"}] # some tests can only be run is umask is 2 # if "umask" cannot be run, the tests will be skipped. diff --git a/tests/io.test b/tests/io.test index 7f1a357..f692e43 100644 --- a/tests/io.test +++ b/tests/io.test @@ -41,7 +41,7 @@ testConstraint testthread [llength [info commands testthread]] # You need a *very* special environment to do some tests. In # particular, many file systems do not support large-files... -testConstraint largefileSupport 1 +testConstraint largefileSupport [expr {$::tcl_platform(os) ne "Darwin"}] # some tests can only be run is umask is 2 # if "umask" cannot be run, the tests will be skipped. -- cgit v0.12 From 7974460313615cd1fa65bf570b8e5d87d01d2add Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Tue, 13 May 2014 11:23:40 +0000 Subject: [958bc05fbe]: Clarify "clock format" using "%R" --- doc/clock.n | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/doc/clock.n b/doc/clock.n index 7c4c3df..a0cc63e 100644 --- a/doc/clock.n +++ b/doc/clock.n @@ -626,8 +626,9 @@ On output, produces a locale-dependent time of day representation on a 12-hour clock. On input, accepts whatever \fB%r\fR produces. .TP \fB%R\fR -On output, produces a locale-dependent time of day representation on a -24-hour clock. On input, accepts whatever \fB%R\fR produces. +On output, the time in 24-hour notation (%H:%M). For a version +including the seconds, see \fB%T\fR below. On input, accepts whatever +\fB%R\fR produces. .TP \fB%s\fR On output, simply formats the \fItimeVal\fR argument as a decimal -- cgit v0.12 From 63543e9ad0130ddeba54d3a9f97d49e4c7216189 Mon Sep 17 00:00:00 2001 From: dgp Date: Tue, 13 May 2014 18:24:23 +0000 Subject: Rework Tcl_ReadRaw() mostly taking things out of the loop that never repeat. --- generic/tclIO.c | 56 ++++++++++++++++++++------------------------------------ 1 file changed, 20 insertions(+), 36 deletions(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index 41f555b..a82c36b 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -4985,7 +4985,7 @@ Tcl_ReadRaw( Channel *chanPtr = (Channel *) chan; ChannelState *statePtr = chanPtr->state; /* State info for channel */ - int nread, copied, copiedNow; + int nread, copied, copiedNow = INT_MAX; /* * The check below does too much because it will reject a call to this @@ -5010,44 +5010,28 @@ Tcl_ReadRaw( */ Tcl_Preserve(chanPtr); - for (copied = 0; copied < bytesToRead; copied += copiedNow) { - copiedNow = CopyBuffer(chanPtr, bufPtr + copied, - bytesToRead - copied); - if (copiedNow == 0) { - if (GotFlag(statePtr, CHANNEL_EOF)) { - break; - } - if (GotFlag(statePtr, CHANNEL_BLOCKED)) { - if (GotFlag(statePtr, CHANNEL_NONBLOCKING)) { - break; - } - ResetFlag(statePtr, CHANNEL_BLOCKED); - } - - /* - * Now go to the driver to get as much as is possible to - * fill the remaining request. Do all the error handling by - * ourselves. The code was stolen from 'GetInput' and - * slightly adapted (different return value here). - * - * The case of 'bytesToRead == 0' at this point cannot - * happen. - */ + for (copied = 0; bytesToRead > 0 && copiedNow > 0; + bufPtr+=copiedNow, bytesToRead-=copiedNow, copied+=copiedNow) { + copiedNow = CopyBuffer(chanPtr, bufPtr, bytesToRead); + } - nread = ChanRead(chanPtr, bufPtr + copied, - bytesToRead - copied); + if (bytesToRead > 0) { + /* + * Now go to the driver to get as much as is possible to + * fill the remaining request. Since we're directly filling + * the caller's buffer, retain the blocked flag. + */ - if (nread < 0) { - if (GotFlag(statePtr, CHANNEL_BLOCKED) && copied > 0) { -/* TODO: comment out? */ -// ResetFlag(statePtr, CHANNEL_BLOCKED); - } else { - copied = -1; - } - } else { - copied += nread; + nread = ChanRead(chanPtr, bufPtr, bytesToRead); + if (nread < 0) { + if (!GotFlag(statePtr, CHANNEL_BLOCKED) || copied == 0) { + copied = -1; } - break; + } else { + copied += nread; + } + if (copied != 0) { + ResetFlag(statePtr, CHANNEL_EOF); } } -- cgit v0.12 From 2e71d669fe81b7911acde1deb7df892f531d1c8d Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 14 May 2014 09:11:42 +0000 Subject: Fix 3 test-cases which started failing on Windows --- tests/io.test | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/io.test b/tests/io.test index f692e43..b99c4e9 100644 --- a/tests/io.test +++ b/tests/io.test @@ -6825,6 +6825,7 @@ test io-52.12 {coverage of -translation auto} { set in [open $path(test1)] chan configure $in -buffersize 8 set out [open $path(test2) w] + chan configure $out -translation lf fcopy $in $out close $in close $out @@ -6839,6 +6840,7 @@ test io-52.13 {coverage of -translation cr} { set in [open $path(test1)] chan configure $in -buffersize 8 -translation cr set out [open $path(test2) w] + chan configure $out -translation lf fcopy $in $out close $in close $out @@ -6853,6 +6855,7 @@ test io-52.14 {coverage of -translation crlf} { set in [open $path(test1)] chan configure $in -buffersize 8 -translation crlf set out [open $path(test2) w] + chan configure $out -translation lf fcopy $in $out close $in close $out -- cgit v0.12 From 3bb92ad0055b8f3e56c9d5d988f5cacc622f8775 Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 15 May 2014 11:04:35 +0000 Subject: Push the setting and clearing of CHANNEL_BLOCKED flag to the more inner parts of the channel read machinery. --- generic/tclIO.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index a82c36b..3416b64 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -383,6 +383,11 @@ ChanRead( */ assert(dstSize > 0); + /* + * Each read op must set the blocked and eof states anew, not let + * the effect of prior reads leak through. + */ + ResetFlag(chanPtr->state, CHANNEL_BLOCKED | CHANNEL_EOF); if (WillRead(chanPtr) < 0) { return -1; } @@ -3944,6 +3949,9 @@ Tcl_GetsObj( goto done; } + /* TODO: Locate better place(s) to reset this flag */ + ResetFlag(statePtr, CHANNEL_BLOCKED); + /* * A binary version of Tcl_GetsObj. This could also handle encodings that * are ascii-7 pure (iso8859, utf-8, ...) with a final encoding conversion @@ -4377,7 +4385,6 @@ TclGetsObjBinary( if (GotFlag(statePtr, CHANNEL_NONBLOCKING)) { goto restore; } - ResetFlag(statePtr, CHANNEL_BLOCKED); } if (GetInput(chanPtr) != 0) { goto restore; @@ -4643,13 +4650,13 @@ FilterInputBytes( */ read: + /* TODO: Move this check to the goto */ if (GotFlag(statePtr, CHANNEL_BLOCKED)) { if (GotFlag(statePtr, CHANNEL_NONBLOCKING)) { gsPtr->charsWrote = 0; gsPtr->rawRead = 0; return -1; } - ResetFlag(statePtr, CHANNEL_BLOCKED); } if (GetInput(chanPtr) != 0) { gsPtr->charsWrote = 0; @@ -5168,6 +5175,8 @@ DoReadChars( } } + /* Must clear the BLOCKED flag here since we check before reading */ + ResetFlag(statePtr, CHANNEL_BLOCKED); for (copied = 0; (unsigned) toRead > 0; ) { copiedNow = -1; if (statePtr->inQueueHead != NULL) { @@ -5202,7 +5211,6 @@ DoReadChars( if (GotFlag(statePtr, CHANNEL_NONBLOCKING)) { break; } - ResetFlag(statePtr, CHANNEL_BLOCKED); } result = GetInput(chanPtr); if (chanPtr != statePtr->topChanPtr) { @@ -6619,12 +6627,7 @@ CheckChannelErrors( } if (direction == TCL_READABLE) { - /* - * Clear the BLOCKED bit. We want to discover this condition - * anew in each operation. - */ - - ResetFlag(statePtr, CHANNEL_BLOCKED | CHANNEL_NEED_MORE_DATA); + ResetFlag(statePtr, CHANNEL_NEED_MORE_DATA); } return 0; @@ -8801,9 +8804,7 @@ DoRead( while (bufPtr == NULL || !IsBufferFull(bufPtr)) { int code; - ResetFlag(statePtr, CHANNEL_BLOCKED); moreData: - code = GetInput(chanPtr); bufPtr = statePtr->inQueueHead; -- cgit v0.12 From c6cd29b3f9a97c7692732aad516cbd176870261a Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Thu, 15 May 2014 14:54:45 +0000 Subject: Fix [3118489]: NUL in filenames. (On Windows, protect against invalid use of ':' in filenames as well) --- tests/cmdAH.test | 3 +++ unix/tclUnixFile.c | 6 ++++++ win/tclWinFile.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 70 insertions(+), 2 deletions(-) diff --git a/tests/cmdAH.test b/tests/cmdAH.test index dc61ac6..4ca90c6 100644 --- a/tests/cmdAH.test +++ b/tests/cmdAH.test @@ -104,6 +104,9 @@ test cmdAH-2.6.1 {Tcl_CdObjCmd} { list [catch {cd ""} msg] $msg } {1 {couldn't change working directory to "": no such file or directory}} +test cmdAH-2.6.3 {Tcl_CdObjCmd, bug #3118489} -returnCodes error -body { + cd .\0 +} -result "couldn't change working directory to \".\0\": no such file or directory" test cmdAH-2.7 {Tcl_ConcatObjCmd} { concat } {} diff --git a/unix/tclUnixFile.c b/unix/tclUnixFile.c index 29f1aba..c5f75a7 100644 --- a/unix/tclUnixFile.c +++ b/unix/tclUnixFile.c @@ -1111,6 +1111,12 @@ TclNativeCreateNativeRep( str = Tcl_GetStringFromObj(validPathPtr, &len); Tcl_UtfToExternalDString(NULL, str, len, &ds); len = Tcl_DStringLength(&ds) + sizeof(char); + if (strlen(Tcl_DStringValue(&ds)) < len - sizeof(char)) { + /* See bug [3118489]: NUL in filenames */ + Tcl_DecrRefCount(validPathPtr); + Tcl_DStringFree(&ds); + return NULL; + } Tcl_DecrRefCount(validPathPtr); nativePathPtr = ckalloc((unsigned) len); memcpy((void*)nativePathPtr, (void*)Tcl_DStringValue(&ds), (size_t) len); diff --git a/win/tclWinFile.c b/win/tclWinFile.c index ed0c40f..9bf63b1 100644 --- a/win/tclWinFile.c +++ b/win/tclWinFile.c @@ -1856,6 +1856,9 @@ TclpObjChdir( nativePath = (const TCHAR *) Tcl_FSGetNativePath(pathPtr); + if (!nativePath) { + return -1; + } result = (*tclWinProcs->setCurrentDirectoryProc)(nativePath); if (result == 0) { @@ -3200,13 +3203,69 @@ TclNativeCreateNativeRep( Tcl_WinUtfToTChar(str, len, &ds); if (tclWinProcs->useWide) { WCHAR *wp = (WCHAR *) Tcl_DStringValue(&ds); - for (; *wp; ++wp) { - if (*wp=='/') { + len = Tcl_DStringLength(&ds)>>1; + /* + ** If path starts with "//?/" or "\\?\" (extended path), translate + ** any slashes to backslashes but accept the '?' as being valid. + */ + if ((str[0]=='\\' || str[0]=='/') && (str[1]=='\\' || str[1]=='/') + && str[2]=='?' && (str[3]=='\\' || str[3]=='/')) { + wp[0] = wp[1] = wp[3] = '\\'; + str += 4; + wp += 4; + len -= 4; + } + /* + ** If there is a drive prefix, the ':' must be considered valid. + **/ + if (((str[0]>='A'&&str[0]<='Z') || (str[0]>='a'&&str[0]<='z')) + && str[1]==':') { + wp += 2; + len -= 2; + } + while (len-->0) { + if ((*wp < ' ') || wcschr(L"\"*:<>?|", *wp)) { + Tcl_DecrRefCount(validPathPtr); + Tcl_DStringFree(&ds); + return NULL; + } else if (*wp=='/') { *wp = '\\'; } + ++wp; } len = Tcl_DStringLength(&ds) + sizeof(WCHAR); } else { + char *p = Tcl_DStringValue(&ds); + len = Tcl_DStringLength(&ds); + /* + ** If path starts with "//?/" or "\\?\" (extended path), translate + ** any slashes to backslashes but accept the '?' as being valid. + */ + if ((str[0]=='\\' || str[0]=='/') && (str[1]=='\\' || str[1]=='/') + && str[2]=='?' && (str[3]=='\\' || str[3]=='/')) { + p[0] = p[1] = p[3] = '\\'; + str += 4; + p += 4; + len -= 4; + } + /* + ** If there is a drive prefix, the ':' must be considered valid. + **/ + if (((str[0]>='A'&&str[0]<='Z') || (str[0]>='a'&&str[0]<='z')) + && str[1]==':') { + p += 2; + len -= 2; + } + while (len-->0) { + if ((*p < ' ') || strchr("\"*:<>?|", *p)) { + Tcl_DecrRefCount(validPathPtr); + Tcl_DStringFree(&ds); + return NULL; + } else if (*p=='/') { + *p = '\\'; + } + ++p; + } len = Tcl_DStringLength(&ds) + sizeof(char); } Tcl_DecrRefCount(validPathPtr); -- cgit v0.12 From b4ca74a5629b1e6ef5e8af2fc3db7f04cb3cbef9 Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 15 May 2014 16:48:43 +0000 Subject: Portable test to demo bug otherwise seen only on Windows. --- tests/io.test | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/tests/io.test b/tests/io.test index b99c4e9..b82f403 100644 --- a/tests/io.test +++ b/tests/io.test @@ -3960,6 +3960,26 @@ test io-32.11 {Tcl_Read from a pipe} {stdio openpipe} { } {{hello } {hello }} +test io-32.11.1 {Tcl_Read from a pipe} {stdio openpipe} { + file delete $path(pipe) + set f1 [open $path(pipe) w] + puts $f1 {chan configure stdout -translation crlf} + puts $f1 {puts [gets stdin]} + puts $f1 {puts [gets stdin]} + close $f1 + set f1 [open "|[list [interpreter] $path(pipe)]" r+] + puts $f1 hello + flush $f1 + set x "" + lappend x [read $f1 6] + puts $f1 hello + flush $f1 + lappend x [read $f1] + close $f1 + set x +} {{hello +} {hello +}} test io-32.12 {Tcl_Read, -nonewline} { file delete $path(test1) set f1 [open $path(test1) w] -- cgit v0.12 From 61f362f9a4c262856f8b21eade121e61cb1fd697 Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 15 May 2014 18:38:22 +0000 Subject: Branch to demo bug introduced in the parent commit. --- tests/io.test | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/tests/io.test b/tests/io.test index c325809..b28566b 100644 --- a/tests/io.test +++ b/tests/io.test @@ -3960,6 +3960,26 @@ test io-32.11 {Tcl_Read from a pipe} {stdio openpipe} { } {{hello } {hello }} +test io-32.11.1 {Tcl_Read from a pipe} {stdio openpipe} { + file delete $path(pipe) + set f1 [open $path(pipe) w] + puts $f1 {chan configure stdout -translation crlf} + puts $f1 {puts [gets stdin]} + puts $f1 {puts [gets stdin]} + close $f1 + set f1 [open "|[list [interpreter] $path(pipe)]" r+] + puts $f1 hello + flush $f1 + set x "" + lappend x [read $f1 6] + puts $f1 hello + flush $f1 + lappend x [read $f1] + close $f1 + set x +} {{hello +} {hello +}} test io-32.12 {Tcl_Read, -nonewline} { file delete $path(test1) set f1 [open $path(test1) w] -- cgit v0.12 From d32b2d81713aeb33ff38dabe354908a4c9fc38a2 Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 16 May 2014 12:56:01 +0000 Subject: More tests to demo the bug more directly. --- tests/io.test | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/tests/io.test b/tests/io.test index b28566b..53b7105 100644 --- a/tests/io.test +++ b/tests/io.test @@ -1559,6 +1559,45 @@ test io-13.8 {TranslateInputEOL: auto mode: \r\n} { close $f set x } "abcd\ndef" +test io-13.8.1 {TranslateInputEOL: auto mode: \r\n} { + set f [open $path(test1) w] + fconfigure $f -translation lf + puts -nonewline $f "abcd\r\ndef" + close $f + set f [open $path(test1)] + fconfigure $f -translation auto + set x {} + lappend x [read $f 5] + lappend x [read $f] + close $f + set x +} [list "abcd\n" "def"] +test io-13.8.2 {TranslateInputEOL: auto mode: \r\n} { + set f [open $path(test1) w] + fconfigure $f -translation lf + puts -nonewline $f "abcd\r\ndef" + close $f + set f [open $path(test1)] + fconfigure $f -translation auto -buffersize 6 + set x {} + lappend x [read $f 5] + lappend x [read $f] + close $f + set x +} [list "abcd\n" "def"] +test io-13.8.3 {TranslateInputEOL: auto mode: \r\n} { + set f [open $path(test1) w] + fconfigure $f -translation lf + puts -nonewline $f "abcd\r\n\r\ndef" + close $f + set f [open $path(test1)] + fconfigure $f -translation auto -buffersize 7 + set x {} + lappend x [read $f 5] + lappend x [read $f] + close $f + set x +} [list "abcd\n" "\ndef"] test io-13.9 {TranslateInputEOL: auto mode: \r followed by not \n} { set f [open $path(test1) w] fconfigure $f -translation lf -- cgit v0.12 From 47912a0cab3f90ca4c7bad70f007885b7c82fa4f Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 16 May 2014 14:40:39 +0000 Subject: Bug fix - accept consumption of the trailing newline in crlf with no characters produced. Also delete false assertions. --- generic/tclIO.c | 46 +++++++++++++++++++++++++++++++++++++--------- 1 file changed, 37 insertions(+), 9 deletions(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index 139a05e..16fc685 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -5400,7 +5400,6 @@ ReadChars( * record \r or \n yet. */ - assert(dstRead + 1 == dstDecoded); assert(dst[dstRead] == '\r'); assert(statePtr->inputTranslation == TCL_TRANSLATE_CRLF); @@ -5421,7 +5420,6 @@ ReadChars( assert(dstWrote == 0); assert(dstRead == 0); - assert(dstDecoded == 1); /* * We decoded only the bare cr, and we cannot read a @@ -5476,6 +5474,13 @@ ReadChars( return 1; } + /* + * Revise the dstRead value so that the numChars calc + * below correctly computes zero characters read. + */ + + dstRead = numChars; + /* FALL THROUGH - get more data (dstWrote == 0) */ } @@ -5502,16 +5507,38 @@ ReadChars( } if (dstWrote == 0) { + ChannelBuffer *nextPtr; - /* - * We were not able to read any chars. Maybe there were - * not enough src bytes to decode into a char. Maybe - * a lone \r could not be translated (crlf mode). Need - * to combine any unused src bytes we have in the first - * buffer with subsequent bytes to try again. + /* We were not able to read any chars. */ + + assert (numChars == 0); + + /* + * There is one situation where this is the correct final + * result. If the src buffer contains only a single \n + * byte, and we are in TCL_TRANSLATE_AUTO mode, and + * when the translation pass was made the INPUT_SAW_CR + * flag was set on the channel. In that case, the + * correct behavior is to consume that \n and produce the + * empty string. + */ + + if (dst[0] == '\n') { + assert(statePtr->inputTranslation == TCL_TRANSLATE_AUTO); + assert(dstRead == 1); + + goto consume; + } + + /* Otherwise, reading zero characters indicates there's + * something incomplete at the end of the src buffer. + * Maybe there were not enough src bytes to decode into + * a char. Maybe a lone \r could not be translated (crlf + * mode). Need to combine any unused src bytes we have + * in the first buffer with subsequent bytes to try again. */ - ChannelBuffer *nextPtr = bufPtr->nextPtr; + nextPtr = bufPtr->nextPtr; if (nextPtr == NULL) { if (srcLen > 0) { @@ -5548,6 +5575,7 @@ ReadChars( statePtr->inputEncodingFlags &= ~TCL_ENCODING_START; + consume: bufPtr->nextRemoved += srcRead; if (dstWrote > srcRead + 1) { *factorPtr = dstWrote * UTF_EXPANSION_FACTOR / srcRead; -- cgit v0.12 From 28721acb58b69d239e98cc2d8b852a56bc5ab27b Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 16 May 2014 18:45:37 +0000 Subject: Move the resets and testings of the BLOCKED flag to where they make more sense. --- generic/tclIO.c | 39 +++++++++++++++++---------------------- 1 file changed, 17 insertions(+), 22 deletions(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index a5c77e8..a128d7c 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -3949,9 +3949,6 @@ Tcl_GetsObj( goto done; } - /* TODO: Locate better place(s) to reset this flag */ - ResetFlag(statePtr, CHANNEL_BLOCKED); - /* * A binary version of Tcl_GetsObj. This could also handle encodings that * are ascii-7 pure (iso8859, utf-8, ...) with a final encoding conversion @@ -4182,6 +4179,7 @@ Tcl_GetsObj( Tcl_SetObjLength(objPtr, oldLength); CommonGetsCleanup(chanPtr); copiedTotal = -1; + ResetFlag(statePtr, CHANNEL_BLOCKED); goto done; } goto gotEOL; @@ -4381,10 +4379,9 @@ TclGetsObjBinary( * device. Side effect is to allocate another channel buffer. */ - if (GotFlag(statePtr, CHANNEL_BLOCKED)) { - if (GotFlag(statePtr, CHANNEL_NONBLOCKING)) { - goto restore; - } + if (GotFlag(statePtr, CHANNEL_BLOCKED|CHANNEL_NONBLOCKING) + == (CHANNEL_BLOCKED|CHANNEL_NONBLOCKING)) { + goto restore; } if (GetInput(chanPtr) != 0) { goto restore; @@ -4447,6 +4444,7 @@ TclGetsObjBinary( byteArray = Tcl_SetByteArrayLength(objPtr, oldLength); CommonGetsCleanup(chanPtr); copiedTotal = -1; + ResetFlag(statePtr, CHANNEL_BLOCKED); goto done; } goto gotEOL; @@ -4650,14 +4648,6 @@ FilterInputBytes( */ read: - /* TODO: Move this check to the goto */ - if (GotFlag(statePtr, CHANNEL_BLOCKED)) { - if (GotFlag(statePtr, CHANNEL_NONBLOCKING)) { - gsPtr->charsWrote = 0; - gsPtr->rawRead = 0; - return -1; - } - } if (GetInput(chanPtr) != 0) { gsPtr->charsWrote = 0; gsPtr->rawRead = 0; @@ -4745,9 +4735,15 @@ FilterInputBytes( } else { /* * There are no more cached raw bytes left. See if we can get - * some more. + * some more, but avoid blocking on a non-blocking channel. */ + if (GotFlag(statePtr, CHANNEL_NONBLOCKING|CHANNEL_BLOCKED) + == (CHANNEL_NONBLOCKING|CHANNEL_BLOCKED)) { + gsPtr->charsWrote = 0; + gsPtr->rawRead = 0; + return -1; + } goto read; } } else { @@ -5207,10 +5203,9 @@ DoReadChars( if (GotFlag(statePtr, CHANNEL_EOF)) { break; } - if (GotFlag(statePtr, CHANNEL_BLOCKED)) { - if (GotFlag(statePtr, CHANNEL_NONBLOCKING)) { - break; - } + if (GotFlag(statePtr, CHANNEL_NONBLOCKING|CHANNEL_BLOCKED) + == (CHANNEL_NONBLOCKING|CHANNEL_BLOCKED)) { + break; } result = GetInput(chanPtr); if (chanPtr != statePtr->topChanPtr) { @@ -8935,8 +8930,8 @@ DoRead( RecycleBuffer(statePtr, bufPtr, 0); } - if (GotFlag(statePtr, CHANNEL_NONBLOCKING) - && GotFlag(statePtr, CHANNEL_BLOCKED)) { + if (GotFlag(statePtr, CHANNEL_NONBLOCKING|CHANNEL_BLOCKED) + == (CHANNEL_NONBLOCKING|CHANNEL_BLOCKED)) { break; } } -- cgit v0.12 From 5db8831fb0c3a4a23f76522925253fc64e07ff9d Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 16 May 2014 19:11:49 +0000 Subject: Improved use of EOF state to avoid worthless allocations. --- generic/tclIO.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index a128d7c..09fa55e 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -6079,6 +6079,18 @@ GetInput( return EINVAL; } + /* + * For a channel at EOF do not bother allocating buffers; there's + * nothing more to read. Avoid calling the driver inputproc in + * case some of them do not react well to additional calls after + * they've reported an eof state.. + * TODO: Candidate for a can't happen panic. + */ + + if (GotFlag(statePtr, CHANNEL_EOF)) { + return 0; + } + /* * First check for more buffers in the pushback area of the topmost * channel in the stack and use them. They can be the result of a @@ -6143,16 +6155,6 @@ GetInput( statePtr->inQueueTail = bufPtr; } - /* - * TODO - consider escape before buffer alloc - * If EOF is set, we should avoid calling the driver because on some - * platforms it is impossible to read from a device after EOF. - */ - - if (GotFlag(statePtr, CHANNEL_EOF)) { - return 0; - } - PreserveChannelBuffer(bufPtr); nread = ChanRead(chanPtr, InsertPoint(bufPtr), toRead); -- cgit v0.12 From 3afefe3d81673a4438727323510cfbfa57626e1a Mon Sep 17 00:00:00 2001 From: ferrieux Date: Fri, 16 May 2014 21:33:41 +0000 Subject: Let the generated Makefile be emacs-friendly by avoiding spurious empty lines and misplaced tabs. Useful e.g. to just set CFLAGS to debug and save. --- unix/Makefile.in | 2 ++ unix/configure | 3 +++ unix/configure.in | 3 +++ win/Makefile.in | 2 ++ 4 files changed, 10 insertions(+) diff --git a/unix/Makefile.in b/unix/Makefile.in index 69dd14f..f151ebb 100644 --- a/unix/Makefile.in +++ b/unix/Makefile.in @@ -2089,9 +2089,11 @@ alldist: dist html: ${NATIVE_TCLSH} $(BUILD_HTML) @EXTRA_BUILD_HTML@ + html-tcl: ${NATIVE_TCLSH} $(BUILD_HTML) --tcl @EXTRA_BUILD_HTML@ + html-tk: ${NATIVE_TCLSH} $(BUILD_HTML) --tk @EXTRA_BUILD_HTML@ diff --git a/unix/configure b/unix/configure index ce5db6a..bd85ba4 100755 --- a/unix/configure +++ b/unix/configure @@ -1338,6 +1338,9 @@ TCL_MINOR_VERSION=6 TCL_PATCH_LEVEL=".1" VERSION=${TCL_VERSION} +EXTRA_INSTALL_BINARIES=${EXTRA_INSTALL_BINARIES:-"@:"} +EXTRA_BUILD_HTML=${EXTRA_BUILD_HTML:-"@:"} + #------------------------------------------------------------------------ # Setup configure arguments for bundled packages #------------------------------------------------------------------------ diff --git a/unix/configure.in b/unix/configure.in index 61ad30f..cb6cf82 100644 --- a/unix/configure.in +++ b/unix/configure.in @@ -28,6 +28,9 @@ TCL_MINOR_VERSION=6 TCL_PATCH_LEVEL=".1" VERSION=${TCL_VERSION} +EXTRA_INSTALL_BINARIES=${EXTRA_INSTALL_BINARIES:-"@:"} +EXTRA_BUILD_HTML=${EXTRA_BUILD_HTML:-"@:"} + #------------------------------------------------------------------------ # Setup configure arguments for bundled packages #------------------------------------------------------------------------ diff --git a/win/Makefile.in b/win/Makefile.in index fd80010..67cf66a 100644 --- a/win/Makefile.in +++ b/win/Makefile.in @@ -850,8 +850,10 @@ 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" -- cgit v0.12 From 604007076c603547027f855daf1225ad0f470489 Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 16 May 2014 23:17:15 +0000 Subject: Merge flag changes. - Wow, no trouble with [chan push] demonstrated. --- generic/tclIO.c | 76 ++++++++++++++++++++++++++++----------------------------- 1 file changed, 37 insertions(+), 39 deletions(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index fd1ce4f..8d9d3d8 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -421,6 +421,11 @@ ChanRead( */ assert(dstSize > 0); + /* + * Each read op must set the blocked and eof states anew, not let + * the effect of prior reads leak through. + */ + ResetFlag(chanPtr->state, CHANNEL_BLOCKED | CHANNEL_EOF); if (WillRead(chanPtr) < 0) { return -1; } @@ -4598,6 +4603,7 @@ Tcl_GetsObj( Tcl_SetObjLength(objPtr, oldLength); CommonGetsCleanup(chanPtr); copiedTotal = -1; + ResetFlag(statePtr, CHANNEL_BLOCKED); goto done; } goto gotEOL; @@ -4801,11 +4807,9 @@ TclGetsObjBinary( * device. Side effect is to allocate another channel buffer. */ - if (GotFlag(statePtr, CHANNEL_BLOCKED)) { - if (GotFlag(statePtr, CHANNEL_NONBLOCKING)) { - goto restore; - } - ResetFlag(statePtr, CHANNEL_BLOCKED); + if (GotFlag(statePtr, CHANNEL_BLOCKED|CHANNEL_NONBLOCKING) + == (CHANNEL_BLOCKED|CHANNEL_NONBLOCKING)) { + goto restore; } if (GetInput(chanPtr) != 0) { goto restore; @@ -4868,6 +4872,7 @@ TclGetsObjBinary( byteArray = Tcl_SetByteArrayLength(objPtr, oldLength); CommonGetsCleanup(chanPtr); copiedTotal = -1; + ResetFlag(statePtr, CHANNEL_BLOCKED); goto done; } goto gotEOL; @@ -5071,14 +5076,6 @@ FilterInputBytes( */ read: - if (GotFlag(statePtr, CHANNEL_BLOCKED)) { - if (GotFlag(statePtr, CHANNEL_NONBLOCKING)) { - gsPtr->charsWrote = 0; - gsPtr->rawRead = 0; - return -1; - } - ResetFlag(statePtr, CHANNEL_BLOCKED); - } if (GetInput(chanPtr) != 0) { gsPtr->charsWrote = 0; gsPtr->rawRead = 0; @@ -5166,9 +5163,15 @@ FilterInputBytes( } else { /* * There are no more cached raw bytes left. See if we can get - * some more. + * some more, but avoid blocking on a non-blocking channel. */ + if (GotFlag(statePtr, CHANNEL_NONBLOCKING|CHANNEL_BLOCKED) + == (CHANNEL_NONBLOCKING|CHANNEL_BLOCKED)) { + gsPtr->charsWrote = 0; + gsPtr->rawRead = 0; + return -1; + } goto read; } } else { @@ -5596,6 +5599,8 @@ DoReadChars( } } + /* Must clear the BLOCKED flag here since we check before reading */ + ResetFlag(statePtr, CHANNEL_BLOCKED); for (copied = 0; (unsigned) toRead > 0; ) { copiedNow = -1; if (statePtr->inQueueHead != NULL) { @@ -5625,11 +5630,9 @@ DoReadChars( if (GotFlag(statePtr, CHANNEL_EOF)) { break; } - if (GotFlag(statePtr, CHANNEL_BLOCKED)) { - if (GotFlag(statePtr, CHANNEL_NONBLOCKING)) { - break; - } - ResetFlag(statePtr, CHANNEL_BLOCKED); + if (GotFlag(statePtr, CHANNEL_NONBLOCKING|CHANNEL_BLOCKED) + == (CHANNEL_NONBLOCKING|CHANNEL_BLOCKED)) { + break; } result = GetInput(chanPtr); if (chanPtr != statePtr->topChanPtr) { @@ -6503,6 +6506,18 @@ GetInput( return EINVAL; } + /* + * For a channel at EOF do not bother allocating buffers; there's + * nothing more to read. Avoid calling the driver inputproc in + * case some of them do not react well to additional calls after + * they've reported an eof state.. + * TODO: Candidate for a can't happen panic. + */ + + if (GotFlag(statePtr, CHANNEL_EOF)) { + return 0; + } + /* * First check for more buffers in the pushback area of the topmost * channel in the stack and use them. They can be the result of a @@ -6567,16 +6582,6 @@ GetInput( statePtr->inQueueTail = bufPtr; } - /* - * TODO - consider escape before buffer alloc - * If EOF is set, we should avoid calling the driver because on some - * platforms it is impossible to read from a device after EOF. - */ - - if (GotFlag(statePtr, CHANNEL_EOF)) { - return 0; - } - PreserveChannelBuffer(bufPtr); nread = ChanRead(chanPtr, InsertPoint(bufPtr), toRead); @@ -7048,12 +7053,7 @@ CheckChannelErrors( } if (direction == TCL_READABLE) { - /* - * Clear the BLOCKED bit. We want to discover this condition - * anew in each operation. - */ - - ResetFlag(statePtr, CHANNEL_BLOCKED | CHANNEL_NEED_MORE_DATA); + ResetFlag(statePtr, CHANNEL_NEED_MORE_DATA); } return 0; @@ -9248,9 +9248,7 @@ DoRead( while (bufPtr == NULL || !IsBufferFull(bufPtr)) { int code; - ResetFlag(statePtr, CHANNEL_BLOCKED); moreData: - code = GetInput(chanPtr); bufPtr = statePtr->inQueueHead; @@ -9353,8 +9351,8 @@ DoRead( RecycleBuffer(statePtr, bufPtr, 0); } - if ((statePtr->flags & CHANNEL_NONBLOCKING || allowShortReads) - && statePtr->flags & CHANNEL_BLOCKED) { + if ((GotFlag(statePtr, CHANNEL_NONBLOCKING) || allowShortReads) + && GotFlag(statePtr, CHANNEL_BLOCKED)) { break; } } -- cgit v0.12 From 94d4975fa21a86c1c9872a5492a83e867d8dfe65 Mon Sep 17 00:00:00 2001 From: dgp Date: Sat, 17 May 2014 02:53:34 +0000 Subject: Repair broken tests iogt-2.[123]. What happened is that now that EOF flags no loger leak acros channel stack layers, an EOF in the bottom channel isn't detected in the top one until the ChanRead call at the top level actually returns 0 bytes. This causes one more query/ma --- tests/iogt.test | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/iogt.test b/tests/iogt.test index 0e2eb3c..5fe3dc2 100644 --- a/tests/iogt.test +++ b/tests/iogt.test @@ -552,6 +552,7 @@ query/maxRead read query/maxRead flush/read +query/maxRead delete/read -------- create/write @@ -604,6 +605,7 @@ read { } query/maxRead {} -1 flush/read {} {} +query/maxRead {} -1 delete/read {} *ignored* -------- create/write {} *ignored* @@ -658,6 +660,7 @@ read {%^&*()_+-= } query/maxRead {} -1 flush/read {} {} +query/maxRead {} -1 write %^&*()_+-= %^&*()_+-= write { } { -- cgit v0.12 From 48b8a3755c6849e8173b129ac8f0f398fa486b70 Mon Sep 17 00:00:00 2001 From: dgp Date: Sat, 17 May 2014 03:05:36 +0000 Subject: Revise results of tests iogt-2.[123] to account for EOF flags no longer leaking across channel stacks. --- tests/iogt.test | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/iogt.test b/tests/iogt.test index dd58df0..6cc0542 100644 --- a/tests/iogt.test +++ b/tests/iogt.test @@ -480,6 +480,7 @@ query/maxRead read query/maxRead flush/read +query/maxRead delete/read -------- create/write @@ -526,6 +527,7 @@ read { } query/maxRead {} -1 flush/read {} {} +query/maxRead {} -1 delete/read {} *ignored* -------- create/write {} *ignored* @@ -577,6 +579,7 @@ write %^&*()_+-= %^&*()_+-= write { } { } +query/maxRead {} -1 delete/read {} *ignored* flush/write {} {} delete/write {} *ignored*} -- cgit v0.12 From 5b5dffa38645173f362493a606b5e0461b857d19 Mon Sep 17 00:00:00 2001 From: dgp Date: Sat, 17 May 2014 03:32:27 +0000 Subject: Simplify the inputProc of [testchannel transform]. --- generic/tclIOGT.c | 39 ++++++++++++++++++--------------------- 1 file changed, 18 insertions(+), 21 deletions(-) diff --git a/generic/tclIOGT.c b/generic/tclIOGT.c index c5372b1..fe0a880 100644 --- a/generic/tclIOGT.c +++ b/generic/tclIOGT.c @@ -683,38 +683,35 @@ TransformInputProc( read = Tcl_ReadRaw(downChan, buf, toRead); if (read < 0) { - /* - * Report errors to caller. EAGAIN is a special situation. If we - * had some data before we report that instead of the request to - * re-try. - */ - if ((Tcl_GetErrno() == EAGAIN) && (gotBytes > 0)) { + if (Tcl_InputBlocked(downChan) && (gotBytes > 0)) { + /* + * Zero bytes available from downChan because blocked. + * But nonzero bytes already copied, so total is a + * valid blocked short read. Return to caller. + */ + break; } + /* + * Either downChan is not blocked (there's a real error). + * or it is and there are no bytes copied yet. In either + * case we want to pass the "error" along to the caller, + * either to report an error, or to signal to the caller + * that zero bytes are available because blocked. + */ + *errorCodePtr = Tcl_GetErrno(); gotBytes = -1; break; } else if (read == 0) { + /* - * Check wether we hit on EOF in the underlying channel or not. If - * not differentiate between blocking and non-blocking modes. In - * non-blocking mode we ran temporarily out of data. Signal this - * to the caller via EWOULDBLOCK and error return (-1). In the - * other cases we simply return what we got and let the caller - * wait for more. On the other hand, if we got an EOF we have to - * convert and flush all waiting partial data. + * Zero returned from Tcl_ReadRaw() always indicates EOF + * on the down channel. */ - if (!Tcl_Eof(downChan)) { - if ((gotBytes == 0) && (dataPtr->flags & CHANNEL_ASYNC)) { - *errorCodePtr = EWOULDBLOCK; - gotBytes = -1; - } - break; - } - if (dataPtr->readIsFlushed) { /* * Already flushed, nothing to do anymore. -- cgit v0.12 From 125a9f8a25ace2982ec8a17f165171b32c7dee69 Mon Sep 17 00:00:00 2001 From: dgp Date: Sat, 17 May 2014 03:38:28 +0000 Subject: Simplify the inputProc of [testchannel transform]. --- generic/tclIOGT.c | 41 ++++++++++++++++++----------------------- 1 file changed, 18 insertions(+), 23 deletions(-) diff --git a/generic/tclIOGT.c b/generic/tclIOGT.c index 6cc33eb..9c4347d 100644 --- a/generic/tclIOGT.c +++ b/generic/tclIOGT.c @@ -683,39 +683,34 @@ TransformInputProc( read = Tcl_ReadRaw(downChan, buf, toRead); if (read < 0) { - /* - * Report errors to caller. EAGAIN is a special situation. If we - * had some data before we report that instead of the request to - * re-try. - */ - int error = Tcl_GetErrno(); + if (Tcl_InputBlocked(downChan) && (gotBytes > 0)) { + /* + * Zero bytes available from downChan because blocked. + * But nonzero bytes already copied, so total is a + * valid blocked short read. Return to caller. + */ - if ((error == EAGAIN) && (gotBytes > 0)) { break; } - *errorCodePtr = error; + /* + * Either downChan is not blocked (there's a real error). + * or it is and there are no bytes copied yet. In either + * case we want to pass the "error" along to the caller, + * either to report an error, or to signal to the caller + * that zero bytes are available because blocked. + */ + + *errorCodePtr = Tcl_GetErrno(); gotBytes = -1; break; } else if (read == 0) { + /* - * Check wether we hit on EOF in the underlying channel or not. If - * not differentiate between blocking and non-blocking modes. In - * non-blocking mode we ran temporarily out of data. Signal this - * to the caller via EWOULDBLOCK and error return (-1). In the - * other cases we simply return what we got and let the caller - * wait for more. On the other hand, if we got an EOF we have to - * convert and flush all waiting partial data. + * Zero returned from Tcl_ReadRaw() always indicates EOF + * on the down channel. */ - if (!Tcl_Eof(downChan)) { - if ((gotBytes == 0) && (dataPtr->flags & CHANNEL_ASYNC)) { - *errorCodePtr = EWOULDBLOCK; - gotBytes = -1; - } - break; - } - if (dataPtr->readIsFlushed) { /* * Already flushed, nothing to do anymore. -- cgit v0.12 From 7f2205461cadb5ef1cfe3081eab0b850d6cfe845 Mon Sep 17 00:00:00 2001 From: dgp Date: Mon, 19 May 2014 18:08:05 +0000 Subject: Simplify ReflectInput(). Also stop intruding on channel internals with direct clearing of CHANNEL_EOF flag. --- generic/tclIORTrans.c | 52 ++++++++++++++++----------------------------------- 1 file changed, 16 insertions(+), 36 deletions(-) diff --git a/generic/tclIORTrans.c b/generic/tclIORTrans.c index b9dd1d6..e6e552f 100644 --- a/generic/tclIORTrans.c +++ b/generic/tclIORTrans.c @@ -1136,50 +1136,36 @@ ReflectInput( readBytes = Tcl_ReadRaw(rtPtr->parent, (char *) Tcl_SetByteArrayLength(bufObj, toRead), toRead); if (readBytes < 0) { - /* - * Report errors to caller. The state of the seek system is - * unchanged! - */ + if (Tcl_InputBlocked(rtPtr->parent) && (gotBytes > 0)) { - if ((Tcl_GetErrno() == EAGAIN) && (gotBytes > 0)) { /* - * EAGAIN is a special situation. If we had some data before - * we report that instead of the request to re-try. + * Down channel is blocked and offers zero additional bytes. + * The nonzero gotBytes already returned makes the total + * operation a valid short read. Return to caller. */ goto stop; } + /* + * Either the down channel is not blocked (a real error) + * or it is and there are gotBytes==0 byte copied so far. + * In either case, pass up the error, so we either report + * any real error, or do not mistakenly signal EOF by + * returning 0 to the caller. + */ + *errorCodePtr = Tcl_GetErrno(); goto error; } if (readBytes == 0) { + /* - * Check wether we hit on EOF in 'parent' or not. If not - * differentiate between blocking and non-blocking modes. In - * non-blocking mode we ran temporarily out of data. Signal this - * to the caller via EWOULDBLOCK and error return (-1). In the - * other cases we simply return what we got and let the caller - * wait for more. On the other hand, if we got an EOF we have to - * convert and flush all waiting partial data. + * Zero returned from Tcl_ReadRaw() always indicates EOF + * on the down channel. */ - - if (!Tcl_Eof(rtPtr->parent)) { - /* - * The state of the seek system is unchanged! - */ - - if ((gotBytes == 0) && rtPtr->nonblocking) { - *errorCodePtr = EWOULDBLOCK; - goto error; - } - goto stop; - } else { - /* - * Eof in parent. - */ - + if (rtPtr->readIsDrained) { goto stop; } @@ -1203,13 +1189,7 @@ ReflectInput( goto stop; } - /* - * Reset eof, force caller to drain result buffer. - */ - - ((Channel *) rtPtr->parent)->state->flags &= ~CHANNEL_EOF; continue; /* at: while (toRead > 0) */ - } } /* readBytes == 0 */ /* -- cgit v0.12 From 090475cc9c8935959209d5bfd09d1dba9a3d6b07 Mon Sep 17 00:00:00 2001 From: dgp Date: Mon, 19 May 2014 18:29:26 +0000 Subject: Same improvements to the zlib transform operations. --- generic/tclZlib.c | 45 +++++---------------------------------------- 1 file changed, 5 insertions(+), 40 deletions(-) diff --git a/generic/tclZlib.c b/generic/tclZlib.c index 9bceb4c..2e27303 100644 --- a/generic/tclZlib.c +++ b/generic/tclZlib.c @@ -2994,47 +2994,18 @@ ZlibTransformInput( */ if (readBytes < 0) { - /* - * Report errors to caller. The state of the seek system is - * unchanged! - */ - - if ((Tcl_GetErrno() == EAGAIN) && (gotBytes > 0)) { - /* - * EAGAIN is a special situation. If we had some data before - * we report that instead of the request to re-try. - */ + /* See ReflectInput() in tclIORTrans.c */ + if (Tcl_InputBlocked(cd->parent) && (gotBytes > 0)) { return gotBytes; } *errorCodePtr = Tcl_GetErrno(); return -1; - } else if (readBytes == 0) { - /* - * Check wether we hit on EOF in 'parent' or not. If not, - * differentiate between blocking and non-blocking modes. In - * non-blocking mode we ran temporarily out of data. Signal this - * to the caller via EWOULDBLOCK and error return (-1). In the - * other cases we simply return what we got and let the caller - * wait for more. On the other hand, if we got an EOF we have to - * convert and flush all waiting partial data. - */ - - if (!Tcl_Eof(cd->parent)) { - /* - * The state of the seek system is unchanged! - */ - - if ((gotBytes == 0) && (cd->flags & ASYNC)) { - *errorCodePtr = EWOULDBLOCK; - return -1; - } - return gotBytes; - } - + } + if (readBytes == 0) { /* - * (Semi-)Eof in parent. + * Eof in parent. * * Now this is a bit different. The partial data waiting is * converted and returned. @@ -3052,12 +3023,6 @@ ZlibTransformInput( return gotBytes; } - - /* - * Reset eof, force caller to drain result buffer. - */ - - ((Channel *) cd->parent)->state->flags &= ~CHANNEL_EOF; } else /* readBytes > 0 */ { /* * Transform the read chunk, which was not empty. Anything we get -- cgit v0.12 From 052f13167e094adfdc8f89800c8e897d642e24e7 Mon Sep 17 00:00:00 2001 From: max Date: Wed, 21 May 2014 10:37:10 +0000 Subject: Fix c&p errors in test descriptions --- tests/socket.test | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/socket.test b/tests/socket.test index 5ff2109..5c5b7c3 100644 --- a/tests/socket.test +++ b/tests/socket.test @@ -2098,7 +2098,7 @@ test socket-14.9.1 {pending [socket -async] and blocking [puts], server is IPv6} close $sock close $fd } -result {{} ok} -test socket-14.10.0 {pending [socket -async] and blocking [puts], server is IPv4} \ +test socket-14.10.0 {pending [socket -async] and nonblocking [puts], server is IPv4} \ -constraints {socket supported_inet supported_inet6} \ -setup { makeFile { @@ -2125,7 +2125,7 @@ test socket-14.10.0 {pending [socket -async] and blocking [puts], server is IPv4 close $sock close $fd } -result {{} ok} -test socket-14.10.1 {pending [socket -async] and blocking [puts], server is IPv6} \ +test socket-14.10.1 {pending [socket -async] and nonblocking [puts], server is IPv6} \ -constraints {socket supported_inet supported_inet6} \ -setup { makeFile { @@ -2152,7 +2152,7 @@ test socket-14.10.1 {pending [socket -async] and blocking [puts], server is IPv6 close $sock close $fd } -result {{} ok} -test socket-14.11.0 {pending [socket -async] and blocking [puts], no listener, no flush} \ +test socket-14.11.0 {pending [socket -async] and nonblocking [puts], no listener, no flush} \ -constraints {socket supported_inet supported_inet6} \ -body { set sock [socket -async localhost [randport]] @@ -2165,7 +2165,7 @@ test socket-14.11.0 {pending [socket -async] and blocking [puts], no listener, n catch {close $sock} unset x } -result {socket is not connected} -returnCodes 1 -test socket-14.11.1 {pending [socket -async] and blocking [puts], no listener, flush} \ +test socket-14.11.1 {pending [socket -async] and nonblocking [puts], no listener, flush} \ -constraints {socket supported_inet supported_inet6} \ -body { set sock [socket -async localhost [randport]] -- cgit v0.12 From e55620ed06abb051977f73d06048a429ad3fc624 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 21 May 2014 14:37:57 +0000 Subject: Fix gcc warning (signed-unsigned compare) --- generic/tclIO.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index c6bb5e3..0c13bc0 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -5797,7 +5797,7 @@ ReadChars( * for sizing receiving buffers. */ - int toRead = ((unsigned) charsToRead > srcLen) ? srcLen : charsToRead; + int toRead = ((charsToRead<0)||(charsToRead > srcLen)) ? srcLen : charsToRead; /* * 'factor' is how much we guess that the bytes in the source buffer will -- cgit v0.12 From ff04f434c479b7813bd75f9e9bd55618cc31e532 Mon Sep 17 00:00:00 2001 From: andy Date: Wed, 21 May 2014 21:32:44 +0000 Subject: Update dict man page to state that [dict set] returns the updated dictionary value. --- doc/dict.n | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/dict.n b/doc/dict.n index 77c460b..a75d8fb 100644 --- a/doc/dict.n +++ b/doc/dict.n @@ -202,7 +202,7 @@ This operation takes the name of a variable containing a dictionary 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. +of nested dictionaries. The updated dictionary value is returned. .TP \fBdict size \fIdictionaryValue\fR . -- cgit v0.12 From 47089ed2b30ef2b776f77fe0029605bc42c0217b Mon Sep 17 00:00:00 2001 From: andy Date: Wed, 21 May 2014 21:40:09 +0000 Subject: Ditto [dict unset]. --- doc/dict.n | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/dict.n b/doc/dict.n index a75d8fb..32d7ea8 100644 --- a/doc/dict.n +++ b/doc/dict.n @@ -216,7 +216,8 @@ dictionary value in that variable that does not contain a mapping for the given key. Where multiple keys are present, this describes a path 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. +All other components on the path must exist. The updated dictionary +value is returned. .TP \fBdict update \fIdictionaryVariable key varName \fR?\fIkey varName ...\fR? \fIbody\fR . -- cgit v0.12 From 461b9f3322656e2fe108db9a393175453a8cbff7 Mon Sep 17 00:00:00 2001 From: andy Date: Wed, 21 May 2014 22:00:52 +0000 Subject: Ditto [dict append], [dict incr], and [dict lappend]. Update description of [dict create] to explicitly state that it returns the new dictionary. --- doc/dict.n | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/doc/dict.n b/doc/dict.n index 32d7ea8..3bb5465 100644 --- a/doc/dict.n +++ b/doc/dict.n @@ -25,11 +25,12 @@ below for a description), depending on \fIoption\fR. The legal This appends the given string (or strings) to the value that the given 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. +Non-existent keys are treated as if they map to an empty string. The +updated dictionary value is returned. .TP \fBdict create \fR?\fIkey value ...\fR? . -Create a new dictionary that contains each of the key/value mappings +Return a new dictionary that contains each of the key/value mappings listed as arguments (keys and values alternating, with each key being followed by its associated value.) .TP @@ -121,7 +122,8 @@ not specified) to the value that the given 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 0. It is an error to increment a value -for an existing key if that value is not an integer. +for an existing key if that value is not an integer. The updated +dictionary value is returned. .TP \fBdict info \fIdictionaryValue\fR . @@ -145,7 +147,8 @@ 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 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. +value that the key maps to to not be representable as a list. The +updated dictionary value is returned. .TP \fBdict map \fR{\fIkeyVar valueVar\fR} \fIdictionaryValue body\fR . -- cgit v0.12 From cc63d97f54b28d904f4c315b8aeff5359ffe2fc0 Mon Sep 17 00:00:00 2001 From: andreask Date: Thu, 22 May 2014 17:17:12 +0000 Subject: Workarounds and fixes for wrapped executables on various platforms regarding the handling of wrapped dynamic libraries. The basic flow of operation is to copy such libraries into a temp file, hand them to the OS loader for processing, and then to delete them immediately, to prevent them from being accessible to other executables. On platforms where that is not possible the library is left in place and things are arranged to delete it on regular process exit. An example of the latter are older revisions of HPUX which report that the file is busy when trying to delete it. Younger revisions of HPUX have changed to allow the deletion, but are also buggy, the OS loader mangles its data structures so that a second library loaded in this manner fails. More recently it was found that Linux which is usually ok with deleting the file and gets everything right shows the same trouble as modern HPUX when the "docker" containerization system is involved, or more specifically the AUFS in use there. Deleting the loaded library file mangles data structures and breaks loading of the following libraries. For a demonstration which does not involve Tcl at all see the ticket https://github.com/dotcloud/docker/issues/1911 in the docker tracker. This of course breaks the use of wrapped executables within docker containers. This commit introduces the function TclSkipUnlink() which centralizes the handling of such exceptions to unlinking the library after unload, and provides code handling the known cases. IOW HPUX is generally forced to not unlink, and ditto when we detect that the copied library file resides within an AUFS. The latter must however be explicitly activated by setting the define -DTCL_TEMPLOAD_NO_UNLINK during build. We still need proper configure tests to set it on the relevant platforms (i.e. Linux). The AUFS detection and handling can be overridden by the environment variable TCL_TEMPLOAD_NO_UNLINK which can force the behaviour either way (skip or not). In case the user knows best, or wishes to test if the problem with AUFS has been fixed. --- generic/tclIOUtil.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 86 insertions(+), 1 deletion(-) diff --git a/generic/tclIOUtil.c b/generic/tclIOUtil.c index 295e313..3d33992 100644 --- a/generic/tclIOUtil.c +++ b/generic/tclIOUtil.c @@ -24,6 +24,12 @@ #endif #include "tclFileSystem.h" +#ifdef TCL_TEMPLOAD_NO_UNLINK +#ifndef NO_FSTATFS +#include +#endif +#endif + /* * struct FilesystemRecord -- * @@ -3149,6 +3155,83 @@ Tcl_FSLoadFile( typedef int (Tcl_FSLoadFileProc2) (Tcl_Interp *interp, Tcl_Obj *pathPtr, Tcl_LoadHandle *handlePtr, Tcl_FSUnloadFileProc **unloadProcPtr, int flags); +/* + * Workaround for issue with modern HPUX which do allow the unlink (no ETXTBSY + * error) yet somehow trash some internal data structures which prevents the + * second and further shared libraries from getting properly loaded. Only the + * first is ok. We try to get around the issue by not unlinking, + * i.e. emulating the behaviour of the older HPUX which denied removal. + * + * Doing the unlink is also an issue within docker containers, whose AUFS + * bungles this as well, see + * https://github.com/dotcloud/docker/issues/1911 + * + * For these situations the change below makes the execution of the unlink + * semi-controllable at runtime. + * + * An AUFS filesystem (if it can be detected) will force avoidance of + * unlink. The env variable TCL_TEMPLOAD_NO_UNLINK allows detection of a + * users general request (unlink and not. + * + * By default the unlink is done (if not in AUFS). However if the variable is + * present and set to true (any integer > 0) then the unlink is skipped. + */ + +int +TclSkipUnlink (Tcl_Obj* shlibFile) +{ + /* Order of testing: + * 1. On hpux we generally want to skip unlink in general + * + * Outside of hpux then: + * 2. For a general user request (TCL_TEMPLOAD_NO_UNLINK present, non-empty, => int) + * 3. For general AUFS environment (statfs, if available). + * + * Ad 2: This variable can disable/override the AUFS detection, i.e. for + * testing if a newer AUFS does not have the bug any more. + * + * Ad 3: This is conditionally compiled in. Condition currently must be set manually. + * This part needs proper tests in the configure(.in). + */ + +#ifdef hpux + return 1; +#else + int skip = 0; + char* skipstr; + + skipstr = getenv ("TCL_TEMPLOAD_NO_UNLINK"); + if (skipstr && (skipstr[0] != '\0')) { + return atoi(skipstr); + } + +#ifdef TCL_TEMPLOAD_NO_UNLINK +#ifndef NO_FSTATFS + { + struct statfs fs; + /* Have fstatfs. May not have the AUFS super magic ... Indeed our build + * box is too old to have it directly in the headers. Define taken from + * http://mooon.googlecode.com/svn/trunk/linux_include/linux/aufs_type.h + * http://aufs.sourceforge.net/ + * Better reference will be gladly taken. + */ +#ifndef AUFS_SUPER_MAGIC +#define AUFS_SUPER_MAGIC ('a' << 24 | 'u' << 16 | 'f' << 8 | 's') +#endif /* AUFS_SUPER_MAGIC */ + if ((statfs(Tcl_GetString (shlibFile), &fs) == 0) && + (fs.f_type == AUFS_SUPER_MAGIC)) { + return 1; + } + } +#endif /* ... NO_FSTATFS */ +#endif /* ... TCL_TEMPLOAD_NO_UNLINK */ + + /* Fallback: !hpux, no EV override, no AUFS (detection, nor detected): + * Don't skip */ + return 0; +#endif /* hpux */ +} + int TclLoadFile( Tcl_Interp *interp, /* Used for error reporting. */ @@ -3353,7 +3436,9 @@ TclLoadFile( * avoids any worries about leaving the copy laying around on exit. */ - if (Tcl_FSDeleteFile(copyToPtr) == TCL_OK) { + if ( + !TclSkipUnlink (copyToPtr) && + (Tcl_FSDeleteFile(copyToPtr) == TCL_OK)) { Tcl_DecrRefCount(copyToPtr); /* -- cgit v0.12 From a74fb9ea315494e283a69ceb1cddf5ef7567e234 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Fri, 23 May 2014 14:59:03 +0000 Subject: eliminate two unused variables. --- win/tclWinSock.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/win/tclWinSock.c b/win/tclWinSock.c index 28dfef0..f343f82 100644 --- a/win/tclWinSock.c +++ b/win/tclWinSock.c @@ -1233,7 +1233,6 @@ TcpGetOptionProc( char host[NI_MAXHOST], port[NI_MAXSERV]; SOCKET sock; size_t len = 0; - int errorCode = 0; int reverseDNS = 0; #define SUPPRESS_RDNS_VAR "::tcl::unsupported::noReverseDNS" @@ -1621,7 +1620,6 @@ TcpConnect( TcpState *statePtr) { DWORD error; - u_long flag = 1; /* Indicates nonblocking mode. */ /* * We are started with async connect and the connect notification * was not jet received -- cgit v0.12 From ceae73bd2872786586283029576d72532b89b659 Mon Sep 17 00:00:00 2001 From: andreask Date: Fri, 23 May 2014 17:17:35 +0000 Subject: Followup on [72c54e1659]. Removed unused variable. --- generic/tclIOUtil.c | 1 - 1 file changed, 1 deletion(-) diff --git a/generic/tclIOUtil.c b/generic/tclIOUtil.c index 3d33992..82ffd88 100644 --- a/generic/tclIOUtil.c +++ b/generic/tclIOUtil.c @@ -3197,7 +3197,6 @@ TclSkipUnlink (Tcl_Obj* shlibFile) #ifdef hpux return 1; #else - int skip = 0; char* skipstr; skipstr = getenv ("TCL_TEMPLOAD_NO_UNLINK"); -- cgit v0.12 From 5f8f27387d73b4da427fb6e29ddd143686a0bddc Mon Sep 17 00:00:00 2001 From: dgp Date: Sat, 24 May 2014 19:56:37 +0000 Subject: Comment out lines of test io-53.4 that appear to do nothing of any value. --- tests/io.test | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/io.test b/tests/io.test index a2e2397..c7da8e6 100644 --- a/tests/io.test +++ b/tests/io.test @@ -7120,17 +7120,17 @@ test io-53.4 {CopyData: background write overflow} {stdio unix openpipe fileeven for {set x 0} {$x < 12} {incr x} { append big $big } - file delete $path(test1) +# file delete $path(test1) file delete $path(pipe) set f1 [open $path(pipe) w] puts $f1 { puts ready fcopy stdin stdout -command { set x } vwait x - set f [open $path(test1) w] - fconfigure $f -translation lf - puts $f "done" - close $f +# set f [open $path(test1) w] +# fconfigure $f -translation lf +# puts $f "done" +# close $f } close $f1 set f1 [open "|[list [interpreter] $path(pipe)]" r+] -- cgit v0.12 From 88ab76b3b8d6f0bce701aa143b37d6167c885c9e Mon Sep 17 00:00:00 2001 From: dgp Date: Tue, 27 May 2014 13:28:41 +0000 Subject: Move code that can only matter in the first loop iteration out of the loop. --- generic/tclIO.c | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index 9e1a723..4e325ba 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -2510,12 +2510,6 @@ FlushChannel( return -1; } - /* - * Loop over the queued buffers and attempt to flush as much as possible - * of the queued output to the channel. - */ - - while (1) { /* * If the queue is empty and there is a ready current buffer, OR if * the current buffer is full, then move the current buffer to the @@ -2536,7 +2530,6 @@ FlushChannel( statePtr->outQueueTail = statePtr->curOutPtr; statePtr->curOutPtr = NULL; } - bufPtr = statePtr->outQueueHead; /* * If we are not being called from an async flush and an async flush @@ -2547,13 +2540,13 @@ FlushChannel( return 0; } - /* - * If the output queue is still empty, break out of the while loop. - */ + /* + * Loop over the queued buffers and attempt to flush as much as possible + * of the queued output to the channel. + */ - if (bufPtr == NULL) { - break; /* Out of the "while (1)". */ - } + while (statePtr->outQueueHead) { + bufPtr = statePtr->outQueueHead; /* * Produce the output on the channel. -- cgit v0.12 From a60da763ba80a364d4f77d4c04b40dbf02f557e7 Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 28 May 2014 16:54:02 +0000 Subject: Increase size of test io-29.34 so that it more portably tests the case where the OS networking machinery gets backed up and blocks. Added several TODO comments on potential simplifications. --- generic/tclIO.c | 9 +++++++++ tests/io.test | 4 ++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index 4e325ba..9e0d7f1 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -2555,6 +2555,7 @@ FlushChannel( PreserveChannelBuffer(bufPtr); toWrite = BytesLeft(bufPtr); if (toWrite == 0) { + /* TODO: This cannot happen. */ written = 0; } else { written = (chanPtr->typePtr->outputProc)(chanPtr->instanceData, @@ -2667,6 +2668,8 @@ FlushChannel( ReleaseChannelBuffer(bufPtr); continue; } else { + /* TODO: Consider detecting and reacting to short writes + * on blocking channels. Ought not happen. See iocmd-24.2. */ wroteSome = 1; } @@ -2700,6 +2703,12 @@ FlushChannel( ResetFlag(statePtr, BG_FLUSH_SCHEDULED); (chanPtr->typePtr->watchProc)(chanPtr->instanceData, statePtr->interestMask); + } else { + /* TODO: If code reaches this point, it means a writable + * event is being handled on the channel, but the channel + * could not in fact be written to. This ought not happen, + * but Unix pipes appear to act this way (see io-53.4). + * Also can imagine broken reflected channels. */ } } diff --git a/tests/io.test b/tests/io.test index c7da8e6..f1248b9 100644 --- a/tests/io.test +++ b/tests/io.test @@ -2786,7 +2786,7 @@ test io-29.34 {Tcl_Close, async flush on close, using sockets} {socket tempNotMa variable x running set l abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz proc writelots {s l} { - for {set i 0} {$i < 2000} {incr i} { + for {set i 0} {$i < 9000} {incr i} { puts $s $l } } @@ -2817,7 +2817,7 @@ test io-29.34 {Tcl_Close, async flush on close, using sockets} {socket tempNotMa close $ss vwait [namespace which -variable x] set c -} 2000 +} 9000 test io-29.35 {Tcl_Close vs fileevent vs multiple interpreters} {socket tempNotMac fileevent} { # On Mac, this test screws up sockets such that subsequent tests using port 2828 # either cause errors or panic(). -- cgit v0.12 From c08a9df4d6f77032655cfedda1c62c5c3d171758 Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 28 May 2014 17:14:11 +0000 Subject: Expand the IsBufferFull() macro to check non-NULL bufPtr.. --- generic/tclIO.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index 9e0d7f1..17efa1e 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -12,6 +12,7 @@ * this file, and for a DISCLAIMER OF ALL WARRANTIES. */ +#undef NDEBUG #include "tclInt.h" #include "tclIO.h" #include @@ -284,7 +285,7 @@ static int WillRead(Channel *chanPtr); #define IsBufferEmpty(bufPtr) ((bufPtr)->nextAdded == (bufPtr)->nextRemoved) -#define IsBufferFull(bufPtr) ((bufPtr)->nextAdded >= (bufPtr)->bufLength) +#define IsBufferFull(bufPtr) ((bufPtr) && (bufPtr)->nextAdded >= (bufPtr)->bufLength) #define IsBufferOverflowing(bufPtr) ((bufPtr)->nextAdded > (bufPtr)->bufLength) @@ -2516,8 +2517,7 @@ FlushChannel( * queue. */ - if (((statePtr->curOutPtr != NULL) && - IsBufferFull(statePtr->curOutPtr)) + if (IsBufferFull(statePtr->curOutPtr) || (GotFlag(statePtr, BUFFER_READY) && (statePtr->outQueueHead == NULL))) { ResetFlag(statePtr, BUFFER_READY); @@ -2531,6 +2531,8 @@ FlushChannel( statePtr->curOutPtr = NULL; } + assert(!IsBufferFull(statePtr->curOutPtr)); + /* * If we are not being called from an async flush and an async flush * is active, we just return without producing any output. @@ -6122,9 +6124,8 @@ GetInput( */ bufPtr = statePtr->inQueueTail; - if ((bufPtr != NULL) && !IsBufferFull(bufPtr)) { - toRead = SpaceLeft(bufPtr); - } else { + + if ((bufPtr == NULL) || IsBufferFull(bufPtr)) { bufPtr = statePtr->saveInBufPtr; statePtr->saveInBufPtr = NULL; @@ -6154,6 +6155,8 @@ GetInput( statePtr->inQueueTail->nextPtr = bufPtr; } statePtr->inQueueTail = bufPtr; + } else { + toRead = SpaceLeft(bufPtr); } PreserveChannelBuffer(bufPtr); @@ -8827,7 +8830,7 @@ DoRead( /* If there is no full buffer, attempt to create and/or fill one. */ - while (bufPtr == NULL || !IsBufferFull(bufPtr)) { + while (!IsBufferFull(bufPtr)) { int code; moreData: -- cgit v0.12 From 0fe50b37a2a0e487e648136d0f3e77cd4428f1e0 Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 28 May 2014 18:24:56 +0000 Subject: Further simplifications to FlushChannel(). This makes clear the BUFFER_READY flag serves no necessary purpose, so it is removed. --- generic/tclIO.c | 114 +++++++++++++++++++------------------------------------- generic/tclIO.h | 5 --- 2 files changed, 38 insertions(+), 81 deletions(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index 17efa1e..911fa97 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -1149,15 +1149,6 @@ Tcl_UnregisterChannel( */ if (statePtr->refCount <= 0) { - /* - * Ensure that if there is another buffer, it gets flushed whether or - * not we are doing a background flush. - */ - - if ((statePtr->curOutPtr != NULL) && - IsBufferReady(statePtr->curOutPtr)) { - SetFlag(statePtr, BUFFER_READY); - } Tcl_Preserve((ClientData)statePtr); if (!GotFlag(statePtr, BG_FLUSH_SCHEDULED)) { /* @@ -2491,8 +2482,6 @@ FlushChannel( ChannelState *statePtr = chanPtr->state; /* State of the channel stack. */ ChannelBuffer *bufPtr; /* Iterates over buffered output queue. */ - int toWrite; /* Amount of output data in current buffer - * available to be written. */ int written; /* Amount of output data actually written in * current round. */ int errorCode = 0; /* Stores POSIX error codes from channel @@ -2511,36 +2500,42 @@ FlushChannel( return -1; } - /* - * If the queue is empty and there is a ready current buffer, OR if - * the current buffer is full, then move the current buffer to the - * queue. - */ + /* + * Should we shift the current output buffer over to the output queue? + * First check that there are bytes in it. If so then... + * If the output queue is empty, then yes, trusting the caller called + * us only when written bytes ought to be flushed. + * If the current output buffer is full, then yes, so we can meet + * the post-condition that on a successful return to caller we've + * left space in the current output buffer for more writing (the flush + * call was to make new room). + * Otherwise, no. Keep the current output buffer where it is so more + * can be written to it, possibly filling it, to promote more efficient + * buffer usage. + */ - if (IsBufferFull(statePtr->curOutPtr) - || (GotFlag(statePtr, BUFFER_READY) && - (statePtr->outQueueHead == NULL))) { - ResetFlag(statePtr, BUFFER_READY); - statePtr->curOutPtr->nextPtr = NULL; - if (statePtr->outQueueHead == NULL) { - statePtr->outQueueHead = statePtr->curOutPtr; - } else { - statePtr->outQueueTail->nextPtr = statePtr->curOutPtr; - } - statePtr->outQueueTail = statePtr->curOutPtr; - statePtr->curOutPtr = NULL; + bufPtr = statePtr->curOutPtr; + if (bufPtr && BytesLeft(bufPtr) && /* Keep empties off queue */ + (statePtr->outQueueHead == NULL || IsBufferFull(bufPtr))) { + if (statePtr->outQueueHead == NULL) { + statePtr->outQueueHead = bufPtr; + } else { + statePtr->outQueueTail->nextPtr = bufPtr; } + statePtr->outQueueTail = bufPtr; + statePtr->curOutPtr = NULL; + } assert(!IsBufferFull(statePtr->curOutPtr)); - /* - * If we are not being called from an async flush and an async flush - * is active, we just return without producing any output. - */ + /* + * If we are not being called from an async flush and an async flush + * is active, we just return without producing any output. + */ - if (!calledFromAsyncFlush && GotFlag(statePtr, BG_FLUSH_SCHEDULED)) { - return 0; - } + if (!calledFromAsyncFlush && GotFlag(statePtr, BG_FLUSH_SCHEDULED)) { + return 0; + } /* * Loop over the queued buffers and attempt to flush as much as possible @@ -2555,14 +2550,8 @@ FlushChannel( */ PreserveChannelBuffer(bufPtr); - toWrite = BytesLeft(bufPtr); - if (toWrite == 0) { - /* TODO: This cannot happen. */ - written = 0; - } else { - written = (chanPtr->typePtr->outputProc)(chanPtr->instanceData, - RemovePoint(bufPtr), toWrite, &errorCode); - } + written = (chanPtr->typePtr->outputProc)(chanPtr->instanceData, + RemovePoint(bufPtr), BytesLeft(bufPtr), &errorCode); /* * If the write failed completely attempt to start the asynchronous @@ -2668,7 +2657,7 @@ FlushChannel( DiscardOutputQueued(statePtr); ReleaseChannelBuffer(bufPtr); - continue; + break; } else { /* TODO: Consider detecting and reacting to short writes * on blocking channels. Ought not happen. See iocmd-24.2. */ @@ -2689,7 +2678,7 @@ FlushChannel( RecycleBuffer(statePtr, bufPtr, 0); } ReleaseChannelBuffer(bufPtr); - } /* Closes "while (1)". */ + } /* Closes "while". */ /* * If we wrote some data while flushing in the background, we are done. @@ -3256,14 +3245,6 @@ Tcl_Close( ResetFlag(statePtr, CHANNEL_INCLOSE); /* - * Ensure that the last output buffer will be flushed. - */ - - if ((statePtr->curOutPtr != NULL) && IsBufferReady(statePtr->curOutPtr)) { - SetFlag(statePtr, BUFFER_READY); - } - - /* * If this channel supports it, close the read side, since we don't need * it anymore and this will help avoid deadlocks on some channel types. */ @@ -3673,10 +3654,10 @@ static int WillRead(Channel *chanPtr) } if ((chanPtr->typePtr->seekProc != NULL) && (Tcl_OutputBuffered((Tcl_Channel) chanPtr) > 0)) { - if ((chanPtr->state->curOutPtr != NULL) - && IsBufferReady(chanPtr->state->curOutPtr)) { - SetFlag(chanPtr->state, BUFFER_READY); - } + + /* TODO: Consider when channel is nonblocking and this + * FlushChannel() call may not finish the task of shoving + * bytes out. Then what? */ if (FlushChannel(NULL, chanPtr, 0) != 0) { return -1; } @@ -3858,7 +3839,6 @@ Write( } if ((flushed < total) && (GotFlag(statePtr, CHANNEL_UNBUFFERED) || (needNlFlush && GotFlag(statePtr, CHANNEL_LINEBUFFERED)))) { - SetFlag(statePtr, BUFFER_READY); if (FlushChannel(NULL, chanPtr, 0) != 0) { return -1; } @@ -5977,14 +5957,6 @@ Tcl_Flush( return -1; } - /* - * Force current output buffer to be output also. - */ - - if ((statePtr->curOutPtr != NULL) && IsBufferReady(statePtr->curOutPtr)) { - SetFlag(statePtr, BUFFER_READY); - } - result = FlushChannel(NULL, chanPtr, 0); if (result != 0) { return TCL_ERROR; @@ -6298,15 +6270,6 @@ Tcl_Seek( } /* - * If there is data buffered in statePtr->curOutPtr then mark the channel - * as ready to flush before invoking FlushChannel. - */ - - if ((statePtr->curOutPtr != NULL) && IsBufferReady(statePtr->curOutPtr)) { - SetFlag(statePtr, BUFFER_READY); - } - - /* * If the flush fails we cannot recover the original position. In that * case the seek is not attempted because we do not know where the access * position is - instead we return the error. FlushChannel has already @@ -10385,7 +10348,6 @@ DumpFlags( ChanFlag('n', CHANNEL_NONBLOCKING); ChanFlag('l', CHANNEL_LINEBUFFERED); ChanFlag('u', CHANNEL_UNBUFFERED); - ChanFlag('R', BUFFER_READY); ChanFlag('F', BG_FLUSH_SCHEDULED); ChanFlag('c', CHANNEL_CLOSED); ChanFlag('E', CHANNEL_EOF); diff --git a/generic/tclIO.h b/generic/tclIO.h index b8fb5be..59182ec 100644 --- a/generic/tclIO.h +++ b/generic/tclIO.h @@ -227,11 +227,6 @@ typedef struct ChannelState { * flushed after every newline. */ #define CHANNEL_UNBUFFERED (1<<5) /* Output to the channel must always * be flushed immediately. */ -#define BUFFER_READY (1<<6) /* Current output buffer (the - * curOutPtr field in the channel - * structure) should be output as soon - * as possible even though it may not - * be full. */ #define BG_FLUSH_SCHEDULED (1<<7) /* A background flush of the queued * output buffers has been * scheduled. */ -- cgit v0.12 From 4b98569f897cfeb52b74ea8c8957cc84244d4944 Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 28 May 2014 18:49:02 +0000 Subject: Update comment to explain assumptions. --- generic/tclIO.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index 911fa97..ccd5708 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -3655,9 +3655,16 @@ static int WillRead(Channel *chanPtr) if ((chanPtr->typePtr->seekProc != NULL) && (Tcl_OutputBuffered((Tcl_Channel) chanPtr) > 0)) { - /* TODO: Consider when channel is nonblocking and this - * FlushChannel() call may not finish the task of shoving - * bytes out. Then what? */ + /* + * CAVEAT - The assumption here is that FlushChannel() will + * push out the bytes of any writes that are in progress. + * Since this is a seekable channel, we assume it is not one + * that can block and force bg flushing. Channels we know that + * can do that -- sockets, pipes -- are not seekable. If the + * assumption is wrong, more drastic measures may be required here + * like temporarily setting the channel into blocking mode. + */ + if (FlushChannel(NULL, chanPtr, 0) != 0) { return -1; } -- cgit v0.12 From 78bb5378e9246dab5774d2d17c3397f36f0658cf Mon Sep 17 00:00:00 2001 From: oehhar Date: Thu, 29 May 2014 14:56:10 +0000 Subject: Try not to loose FD_CONNECT by switching monitoring off. --- win/tclWinSock.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/win/tclWinSock.c b/win/tclWinSock.c index e18a3dd..ae9ba17 100644 --- a/win/tclWinSock.c +++ b/win/tclWinSock.c @@ -1239,13 +1239,17 @@ WaitForSocketEvent( /* * Reset WSAAsyncSelect so we have a fresh set of events pending. + * Don't do that if we are waiting for a connect as this may ignore + * a failed connect. */ - SendMessage(tsdPtr->hwnd, SOCKET_SELECT, (WPARAM) UNSELECT, - (LPARAM) infoPtr); - - SendMessage(tsdPtr->hwnd, SOCKET_SELECT, (WPARAM) SELECT, - (LPARAM) infoPtr); + if ( 0 == (events & FD_CONNECT) ) { + SendMessage(tsdPtr->hwnd, SOCKET_SELECT, (WPARAM) UNSELECT, + (LPARAM) infoPtr); + + SendMessage(tsdPtr->hwnd, SOCKET_SELECT, (WPARAM) SELECT, + (LPARAM) infoPtr); + } while (1) { if (infoPtr->lastError) { -- cgit v0.12 From 1f197f004a8ea114fe3cd6d3c8ec925200584e1c Mon Sep 17 00:00:00 2001 From: dgp Date: Sat, 31 May 2014 02:30:53 +0000 Subject: Correct the interest masks in the Tcl_CreateFileHandler() calls in PipeWatchProc(). When we are interested in both readable and writable events of a command pipeline channel, we only want the readable from the read end of the pipe, and the writable from the write end of the pipe. --- generic/tclIO.c | 17 ++++++++++++----- tests/io.test | 6 ------ unix/tclUnixPipe.c | 4 ++-- 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index 0716074..1c4a5b3 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -2694,11 +2694,18 @@ FlushChannel( (chanPtr->typePtr->watchProc)(chanPtr->instanceData, statePtr->interestMask); } else { - /* TODO: If code reaches this point, it means a writable - * event is being handled on the channel, but the channel - * could not in fact be written to. This ought not happen, - * but Unix pipes appear to act this way (see io-53.4). - * Also can imagine broken reflected channels. */ + + /* + * When we are calledFromAsyncFlush, that means a writable + * state on the channel triggered the call, so we should be + * able to write something. Either we did write something + * and wroteSome should be set, or there was nothing left to + * write in this call, and we've completed the BG flush. + * These are the two cases above. If we get here, that means + * there is some kind failure in the writable event machinery. + */ + + assert(!calledFromAsyncFlush); } } diff --git a/tests/io.test b/tests/io.test index f1248b9..2296986 100644 --- a/tests/io.test +++ b/tests/io.test @@ -7120,17 +7120,12 @@ test io-53.4 {CopyData: background write overflow} {stdio unix openpipe fileeven for {set x 0} {$x < 12} {incr x} { append big $big } -# file delete $path(test1) file delete $path(pipe) set f1 [open $path(pipe) w] puts $f1 { puts ready fcopy stdin stdout -command { set x } vwait x -# set f [open $path(test1) w] -# fconfigure $f -translation lf -# puts $f "done" -# close $f } close $f1 set f1 [open "|[list [interpreter] $path(pipe)]" r+] @@ -7138,7 +7133,6 @@ test io-53.4 {CopyData: background write overflow} {stdio unix openpipe fileeven fconfigure $f1 -blocking 0 puts $f1 $big flush $f1 - after 500 set result "" fileevent $f1 read [namespace code { append result [read $f1 1024] diff --git a/unix/tclUnixPipe.c b/unix/tclUnixPipe.c index d0a5e53..57be08f 100644 --- a/unix/tclUnixPipe.c +++ b/unix/tclUnixPipe.c @@ -1125,7 +1125,7 @@ PipeWatchProc( if (psPtr->inFile) { newmask = mask & (TCL_READABLE | TCL_EXCEPTION); if (newmask) { - Tcl_CreateFileHandler(GetFd(psPtr->inFile), mask, + Tcl_CreateFileHandler(GetFd(psPtr->inFile), newmask, (Tcl_FileProc *) Tcl_NotifyChannel, (ClientData) psPtr->channel); } else { @@ -1135,7 +1135,7 @@ PipeWatchProc( if (psPtr->outFile) { newmask = mask & (TCL_WRITABLE | TCL_EXCEPTION); if (newmask) { - Tcl_CreateFileHandler(GetFd(psPtr->outFile), mask, + Tcl_CreateFileHandler(GetFd(psPtr->outFile), newmask, (Tcl_FileProc *) Tcl_NotifyChannel, (ClientData) psPtr->channel); } else { -- cgit v0.12 From 744e7bfe511513ce1937354615cf3a83da7c388f Mon Sep 17 00:00:00 2001 From: max Date: Mon, 2 Jun 2014 10:57:38 +0000 Subject: Improve robustness of the socket tests against systems that support IPv6, but don't resolve localhost to ::1 (and vice versa for IPv4 and 127.0.0.1). --- tests/socket.test | 135 ++++++++++++++++++++++++++++++------------------------ 1 file changed, 75 insertions(+), 60 deletions(-) diff --git a/tests/socket.test b/tests/socket.test index 5c5b7c3..88d8767 100644 --- a/tests/socket.test +++ b/tests/socket.test @@ -99,7 +99,7 @@ set lat2 [expr {($t2-$t1)*3}] # Use the maximum of the two latency calculations, but at least 100ms set latency [expr {$lat1 > $lat2 ? $lat1 : $lat2}] -set latency [expr {$latency > 100 ? $latency : 100}] +set latency [expr {$latency > 100 ? $latency : 1000}] unset t1 t2 s1 s2 lat1 lat2 server # If remoteServerIP or remoteServerPort are not set, check in the environment @@ -137,7 +137,6 @@ foreach {af localhost} { testConstraint supported_$af [expr {![catch {socket -server foo -myaddr $localhost 0} sock]}] catch {close $sock} } -testConstraint supported_any [expr {[testConstraint supported_inet] || [testConstraint supported_inet6]}] set sock [socket -server foo -myaddr localhost 0] set sockname [fconfigure $sock -sockname] @@ -151,6 +150,9 @@ foreach {af localhost} { inet 127.0.0.1 inet6 ::1 } { + if {![testConstraint supported_$af]} { + continue + } set ::tcl::unsupported::socketAF $af # # Check if we're supposed to do tests against the remote server @@ -1728,7 +1730,7 @@ catch {close $remoteProcChan} } unset ::tcl::unsupported::socketAF test socket-14.0.0 {[socket -async] when server only listens on IPv4} \ - -constraints [list socket supported_any localhost_v4] \ + -constraints {socket supported_inet localhost_v4} \ -setup { proc accept {s a p} { global x @@ -1750,7 +1752,7 @@ test socket-14.0.0 {[socket -async] when server only listens on IPv4} \ unset x } -result ok test socket-14.0.1 {[socket -async] when server only listens on IPv6} \ - -constraints [list socket supported_any localhost_v6] \ + -constraints {socket supported_inet6 localhost_v6} \ -setup { proc accept {s a p} { global x @@ -1772,7 +1774,7 @@ test socket-14.0.1 {[socket -async] when server only listens on IPv6} \ unset x } -result ok test socket-14.1 {[socket -async] fileevent while still connecting} \ - -constraints [list socket supported_any] \ + -constraints {socket} \ -setup { proc accept {s a p} { global x @@ -1801,7 +1803,7 @@ test socket-14.1 {[socket -async] fileevent while still connecting} \ unset x } -result {{} ok} test socket-14.2 {[socket -async] fileevent connection refused} \ - -constraints [list socket supported_any] \ + -constraints {socket} \ -body { set client [socket -async localhost [randport]] fileevent $client writable {set x ok} @@ -1815,7 +1817,7 @@ test socket-14.2 {[socket -async] fileevent connection refused} \ unset x after client } -result {ok {connection refused}} test socket-14.3 {[socket -async] when server only listens on IPv6} \ - -constraints [list socket supported_any localhost_v6] \ + -constraints {socket supported_inet6 localhost_v6} \ -setup { proc accept {s a p} { global x @@ -1837,7 +1839,7 @@ test socket-14.3 {[socket -async] when server only listens on IPv6} \ unset x } -result ok test socket-14.4 {[socket -async] and both, readdable and writable fileevents} \ - -constraints [list socket supported_any] \ + -constraints {socket} \ -setup { proc accept {s a p} { puts $s bye @@ -1864,8 +1866,9 @@ test socket-14.4 {[socket -async] and both, readdable and writable fileevents} \ close $server unset x } -result {{} bye} +# FIXME: we should also have an IPv6 counterpart of this test socket-14.5 {[socket -async] which fails before any connect() can be made} \ - -constraints [list socket supported_any] \ + -constraints {socket supported_inet} \ -body { # address from rfc5737 socket -async -myaddr 192.0.2.42 127.0.0.1 [randport] @@ -1873,7 +1876,7 @@ test socket-14.5 {[socket -async] which fails before any connect() can be made} -returnCodes 1 \ -result {couldn't open socket: cannot assign requested address} test socket-14.6.0 {[socket -async] with no event loop and server listening on IPv4} \ - -constraints [list socket supported_inet supported_inet6] \ + -constraints {socket supported_inet localhost_v4} \ -setup { proc accept {s a p} { global x @@ -1904,7 +1907,7 @@ test socket-14.6.0 {[socket -async] with no event loop and server listening on I } \ -result {ok bye} test socket-14.6.1 {[socket -async] with no event loop and server listening on IPv6} \ - -constraints [list socket supported_inet supported_inet6] \ + -constraints {socket supported_inet6 localhost_v6} \ -setup { proc accept {s a p} { global x @@ -1935,9 +1938,10 @@ test socket-14.6.1 {[socket -async] with no event loop and server listening on I } \ -result {ok bye} test socket-14.7.0 {pending [socket -async] and blocking [gets], server is IPv4} \ - -constraints {socket supported_inet supported_inet6} \ + -constraints {socket supported_inet localhost_v4} \ -setup { makeFile { + fileevent stdin readable exit set server [socket -server accept -myaddr 127.0.0.1 0] proc accept {s h p} {puts $s ok; close $s; set ::x 1} puts [lindex [fconfigure $server -sockname] 2] @@ -1950,15 +1954,14 @@ test socket-14.7.0 {pending [socket -async] and blocking [gets], server is IPv4} set sock [socket -async localhost $port] list [fconfigure $sock -error] [gets $sock] [fconfigure $sock -error] } -cleanup { - # make sure the server exits - catch {socket 127.0.0.1 $port} - close $sock close $fd + close $sock } -result {{} ok {}} test socket-14.7.1 {pending [socket -async] and blocking [gets], server is IPv6} \ - -constraints {socket supported_inet supported_inet6} \ + -constraints {socket supported_inet6 localhost_v6} \ -setup { makeFile { + fileevent stdin readable exit set server [socket -server accept -myaddr ::1 0] proc accept {s h p} {puts $s ok; close $s; set ::x 1} puts [lindex [fconfigure $server -sockname] 2] @@ -1971,13 +1974,11 @@ test socket-14.7.1 {pending [socket -async] and blocking [gets], server is IPv6} set sock [socket -async localhost $port] list [fconfigure $sock -error] [gets $sock] [fconfigure $sock -error] } -cleanup { - # make sure the server exits - catch {socket ::1 $port} - close $sock close $fd + close $sock } -result {{} ok {}} test socket-14.7.2 {pending [socket -async] and blocking [gets], no listener} \ - -constraints {socket supported_inet supported_inet6} \ + -constraints {socket} \ -body { set sock [socket -async localhost [randport]] catch {gets $sock} x @@ -1986,9 +1987,10 @@ test socket-14.7.2 {pending [socket -async] and blocking [gets], no listener} \ close $sock } -match glob -result {{error reading "sock*": socket is not connected} {connection refused} {}} test socket-14.8.0 {pending [socket -async] and nonblocking [gets], server is IPv4} \ - -constraints {socket supported_inet supported_inet6} \ + -constraints {socket supported_inet localhost_v4} \ -setup { makeFile { + fileevent stdin readable exit set server [socket -server accept -myaddr 127.0.0.1 0] proc accept {s h p} {puts $s ok; close $s; set ::x 1} puts [lindex [fconfigure $server -sockname] 2] @@ -2006,15 +2008,14 @@ test socket-14.8.0 {pending [socket -async] and nonblocking [gets], server is IP } set x } -cleanup { - # make sure the server exits - catch {socket 127.0.0.1 $port} - close $sock close $fd + close $sock } -result {ok} test socket-14.8.1 {pending [socket -async] and nonblocking [gets], server is IPv6} \ - -constraints {socket supported_inet supported_inet6} \ + -constraints {socket supported_inet6 localhost_v6} \ -setup { makeFile { + fileevent stdin readable exit set server [socket -server accept -myaddr ::1 0] proc accept {s h p} {puts $s ok; close $s; set ::x 1} puts [lindex [fconfigure $server -sockname] 2] @@ -2032,13 +2033,11 @@ test socket-14.8.1 {pending [socket -async] and nonblocking [gets], server is IP } set x } -cleanup { - # make sure the server exits - catch {socket ::1 $port} - close $sock close $fd + close $sock } -result {ok} test socket-14.8.2 {pending [socket -async] and nonblocking [gets], no listener} \ - -constraints {socket supported_inet supported_inet6} \ + -constraints {socket} \ -body { set sock [socket -async localhost [randport]] fconfigure $sock -blocking 0 @@ -2051,9 +2050,10 @@ test socket-14.8.2 {pending [socket -async] and nonblocking [gets], no listener} close $sock } -match glob -result {{error reading "sock*": socket is not connected} {connection refused} {}} test socket-14.9.0 {pending [socket -async] and blocking [puts], server is IPv4} \ - -constraints {socket supported_inet supported_inet6} \ + -constraints {socket supported_inet localhost_v4} \ -setup { makeFile { + fileevent stdin readable exit set server [socket -server accept -myaddr 127.0.0.1 0] proc accept {s h p} {set ::x $s} puts [lindex [fconfigure $server -sockname] 2] @@ -2069,15 +2069,14 @@ test socket-14.9.0 {pending [socket -async] and blocking [puts], server is IPv4} flush $sock list [fconfigure $sock -error] [gets $fd] } -cleanup { - # make sure the server exits - catch {socket 127.0.0.1 $port} - close $sock close $fd + close $sock } -result {{} ok} test socket-14.9.1 {pending [socket -async] and blocking [puts], server is IPv6} \ - -constraints {socket supported_inet supported_inet6} \ + -constraints {socket supported_inet6 localhost_v6} \ -setup { makeFile { + fileevent stdin readable exit set server [socket -server accept -myaddr ::1 0] proc accept {s h p} {set ::x $s} puts [lindex [fconfigure $server -sockname] 2] @@ -2093,15 +2092,14 @@ test socket-14.9.1 {pending [socket -async] and blocking [puts], server is IPv6} flush $sock list [fconfigure $sock -error] [gets $fd] } -cleanup { - # make sure the server exits - catch {socket ::1 $port} - close $sock close $fd + close $sock } -result {{} ok} test socket-14.10.0 {pending [socket -async] and nonblocking [puts], server is IPv4} \ - -constraints {socket supported_inet supported_inet6} \ + -constraints {socket supported_inet localhost_v4} \ -setup { makeFile { + fileevent stdin readable exit set server [socket -server accept -myaddr 127.0.0.1 0] proc accept {s h p} {set ::x $s} puts [lindex [fconfigure $server -sockname] 2] @@ -2120,15 +2118,14 @@ test socket-14.10.0 {pending [socket -async] and nonblocking [puts], server is I vwait x list [fconfigure $sock -error] [gets $fd] } -cleanup { - # make sure the server exits - catch {socket 127.0.0.1 $port} - close $sock close $fd + close $sock } -result {{} ok} test socket-14.10.1 {pending [socket -async] and nonblocking [puts], server is IPv6} \ - -constraints {socket supported_inet supported_inet6} \ + -constraints {socket supported_inet6 localhost_v6} \ -setup { makeFile { + fileevent stdin readable exit set server [socket -server accept -myaddr ::1 0] proc accept {s h p} {set ::x $s} puts [lindex [fconfigure $server -sockname] 2] @@ -2147,13 +2144,11 @@ test socket-14.10.1 {pending [socket -async] and nonblocking [puts], server is I vwait x list [fconfigure $sock -error] [gets $fd] } -cleanup { - # make sure the server exits - catch {socket ::1 $port} - close $sock close $fd + close $sock } -result {{} ok} test socket-14.11.0 {pending [socket -async] and nonblocking [puts], no listener, no flush} \ - -constraints {socket supported_inet supported_inet6} \ + -constraints {socket} \ -body { set sock [socket -async localhost [randport]] fconfigure $sock -blocking 0 @@ -2166,7 +2161,7 @@ test socket-14.11.0 {pending [socket -async] and nonblocking [puts], no listener unset x } -result {socket is not connected} -returnCodes 1 test socket-14.11.1 {pending [socket -async] and nonblocking [puts], no listener, flush} \ - -constraints {socket supported_inet supported_inet6} \ + -constraints {socket knownBug} \ -body { set sock [socket -async localhost [randport]] fconfigure $sock -blocking 0 @@ -2177,10 +2172,10 @@ test socket-14.11.1 {pending [socket -async] and nonblocking [puts], no listener close $sock } -cleanup { catch {close $sock} - unset x + catch {unset x} } -result {socket is not connected} -returnCodes 1 test socket-14.12 {[socket -async] background progress triggered by [fconfigure -error]} \ - -constraints {socket supported_inet supported_inet6} \ + -constraints {socket} \ -body { set s [socket -async localhost [randport]] for {set i 0} {$i < 50} {incr i} { @@ -2194,7 +2189,9 @@ test socket-14.12 {[socket -async] background progress triggered by [fconfigure unset x s } -result {connection refused} -test socket-14.13 {testing writable event when quick failure} -constraints {socket win supported_inet} -body { +test socket-14.13 {testing writable event when quick failure} \ + -constraints {socket win supported_inet} \ + -body { # Test for bug 336441ed59 where a quick background fail was ignored # Test only for windows as socket -async 255.255.255.255 fails @@ -2211,7 +2208,8 @@ test socket-14.13 {testing writable event when quick failure} -constraints {sock after cancel $a1 } -result writable -test socket-14.14 {testing fileevent readable on failed async socket connect} -constraints [list socket] -body { +test socket-14.14 {testing fileevent readable on failed async socket connect} \ + -constraints {socket} -body { # Test for bug 581937ab1e set a1 [after 5000 {set x timeout}] @@ -2235,18 +2233,35 @@ test socket-14.15 {blocking read on async socket should not trigger event handle } -result ok set num 0 -foreach servip {127.0.0.1 ::1 localhost} { - foreach cliip {127.0.0.1 ::1 localhost} { - if {$servip eq $cliip || "localhost" in [list $servip $cliip]} { - set result {-result "sock*" -match glob} - } else { - set result { - -result {couldn't open socket: connection refused} - -returnCodes 1 + +set x {localhost {socket} 127.0.0.1 {supported_inet} ::1 {supported_inet6}} +set resultok {-result "sock*" -match glob} +set resulterr { + -result {couldn't open socket: connection refused} + -returnCodes 1 +} +foreach {servip sc} $x { + foreach {cliip cc} $x { + set constraints socket + lappend constraints $sc $cc + set result $resulterr + switch -- [lsort -unique [list $servip $cliip]] { + localhost - 127.0.0.1 - ::1 { + set result $resultok + } + {127.0.0.1 localhost} { + if {[testConstraint localhost_v4]} { + set result $resultok + } + } + {::1 localhost} { + if {[testConstraint localhost_v6]} { + set result $resultok + } } } test socket-15.1.$num "Connect to $servip from $cliip" \ - -constraints {socket supported_inet supported_inet6} -setup { + -constraints $constraints -setup { set server [socket -server accept -myaddr $servip 0] proc accept {s h p} { close $s } set port [lindex [fconfigure $server -sockname] 2] -- cgit v0.12 From 004361c91defcf9afeb7de00e9d4fcb6a043ae24 Mon Sep 17 00:00:00 2001 From: dgp Date: Mon, 2 Jun 2014 20:03:14 +0000 Subject: These edits make the tests socket-14.11.[01] stop hanging, but also introduce a whole raft of test failures. WIP. --- generic/tclIO.c | 18 ++++++++++++------ tests/socket.test | 2 +- unix/tclUnixSock.c | 8 +++----- 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index 7d94037..5552329 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -3288,10 +3288,15 @@ Tcl_Close( stickyError = 0; if ((statePtr->encoding != NULL) - && !(statePtr->outputEncodingFlags & TCL_ENCODING_START) - && (CheckChannelErrors(statePtr, TCL_WRITABLE) == 0)) { - statePtr->outputEncodingFlags |= TCL_ENCODING_END; - if (WriteChars(chanPtr, "", 0) < 0) { + && !(statePtr->outputEncodingFlags & TCL_ENCODING_START)) { + + int code = CheckChannelErrors(statePtr, TCL_WRITABLE); + + if (code == 0) { + statePtr->outputEncodingFlags |= TCL_ENCODING_END; + code = WriteChars(chanPtr, "", 0); + } + if (code < 0) { stickyError = Tcl_GetErrno(); } @@ -8034,8 +8039,9 @@ Tcl_NotifyChannel( */ if (GotFlag(statePtr, BG_FLUSH_SCHEDULED) && (mask & TCL_WRITABLE)) { - FlushChannel(NULL, chanPtr, 1); - mask &= ~TCL_WRITABLE; + if (0 == FlushChannel(NULL, chanPtr, 1)) { + mask &= ~TCL_WRITABLE; + } } /* diff --git a/tests/socket.test b/tests/socket.test index 88d8767..0c9320a 100644 --- a/tests/socket.test +++ b/tests/socket.test @@ -2161,7 +2161,7 @@ test socket-14.11.0 {pending [socket -async] and nonblocking [puts], no listener unset x } -result {socket is not connected} -returnCodes 1 test socket-14.11.1 {pending [socket -async] and nonblocking [puts], no listener, flush} \ - -constraints {socket knownBug} \ + -constraints {socket} \ -body { set sock [socket -async localhost [randport]] fconfigure $sock -blocking 0 diff --git a/unix/tclUnixSock.c b/unix/tclUnixSock.c index 08a14d3..47d0681 100644 --- a/unix/tclUnixSock.c +++ b/unix/tclUnixSock.c @@ -1160,11 +1160,9 @@ out: * the event mechanism one roundtrip through select(). */ - /* Note: disabling this for now as it causes spurious event triggering - * under Linux (see test socket-14.15). */ -#if 0 - Tcl_NotifyChannel(statePtr->channel, TCL_WRITABLE); -#endif + if (statePtr->cachedBlocking == TCL_MODE_NONBLOCKING) { + Tcl_NotifyChannel(statePtr->channel, TCL_WRITABLE); + } } if (error != 0) { /* -- cgit v0.12 From 6c7e545b80e6ce72b0bf64749efedcd61153043a Mon Sep 17 00:00:00 2001 From: dgp Date: Tue, 3 Jun 2014 02:26:07 +0000 Subject: These edits make all tests outside of socket-14.* pass on OSX Mavericks. Several socket-14.* tests failing there, and those that pass are very slow about it. Firewall or poor networking configuration may be playing a role. --- generic/tclIO.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index 5552329..998fe5e 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -3287,7 +3287,7 @@ Tcl_Close( stickyError = 0; - if ((statePtr->encoding != NULL) + if (GotFlag(statePtr, TCL_WRITABLE) && (statePtr->encoding != NULL) && !(statePtr->outputEncodingFlags & TCL_ENCODING_START)) { int code = CheckChannelErrors(statePtr, TCL_WRITABLE); @@ -3295,6 +3295,8 @@ Tcl_Close( if (code == 0) { statePtr->outputEncodingFlags |= TCL_ENCODING_END; code = WriteChars(chanPtr, "", 0); + statePtr->outputEncodingFlags &= ~TCL_ENCODING_END; + statePtr->outputEncodingFlags |= TCL_ENCODING_START; } if (code < 0) { stickyError = Tcl_GetErrno(); -- cgit v0.12 From 10caa9b482786c7c4010b25d33f05249709aa37c Mon Sep 17 00:00:00 2001 From: dkf Date: Tue, 3 Jun 2014 07:26:11 +0000 Subject: [1b0266d8bb] Working towards ensuring that all dict operations are sufficiently strict. --- generic/tclDictObj.c | 46 +++++++++++++++++++++------------------------- tests/dict.test | 42 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+), 25 deletions(-) diff --git a/generic/tclDictObj.c b/generic/tclDictObj.c index e31d708..71d5f5d 100644 --- a/generic/tclDictObj.c +++ b/generic/tclDictObj.c @@ -1026,11 +1026,11 @@ Tcl_DictObjRemove( } } - if (dictPtr->bytes != NULL) { - TclInvalidateStringRep(dictPtr); - } dict = dictPtr->internalRep.twoPtrValue.ptr1; if (DeleteChainEntry(dict, keyPtr)) { + if (dictPtr->bytes != NULL) { + TclInvalidateStringRep(dictPtr); + } dict->epoch++; } return TCL_OK; @@ -1629,8 +1629,7 @@ DictReplaceCmd( Tcl_Obj *const *objv) { Tcl_Obj *dictPtr; - int i, result; - int allocatedDict = 0; + int i; if ((objc < 2) || (objc & 1)) { Tcl_WrongNumArgs(interp, 1, objv, "dictionary ?key value ...?"); @@ -1638,18 +1637,17 @@ DictReplaceCmd( } dictPtr = objv[1]; - if (Tcl_IsShared(dictPtr)) { - dictPtr = Tcl_DuplicateObj(dictPtr); - allocatedDict = 1; + if (dictPtr->typePtr != &tclDictType) { + int result = SetDictFromAny(interp, dictPtr); + if (result != TCL_OK) { + return result; + } } for (i=2 ; itypePtr != &tclDictType) { + int result = SetDictFromAny(interp, dictPtr); + if (result != TCL_OK) { + return result; + } } for (i=2 ; i Date: Wed, 4 Jun 2014 03:25:44 +0000 Subject: Valgrind doesn't like use of uninitialized variables. --- unix/tclUnixSock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/unix/tclUnixSock.c b/unix/tclUnixSock.c index 47d0681..a9323c4 100644 --- a/unix/tclUnixSock.c +++ b/unix/tclUnixSock.c @@ -1024,7 +1024,7 @@ TcpConnect( { socklen_t optlen; int async_callback = statePtr->flags & TCP_ASYNC_PENDING; - int ret = -1, error; + int ret = -1, error = errno; int async = statePtr->flags & TCP_ASYNC_CONNECT; if (async_callback) { -- cgit v0.12 From 6a91e192f8c18d0a05947f6a8129357fe145d945 Mon Sep 17 00:00:00 2001 From: dkf Date: Wed, 4 Jun 2014 08:15:26 +0000 Subject: more tests, cleaning up the code a bit --- generic/tclDictObj.c | 29 +++++++++++++---------------- tests/dict.test | 29 +++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 16 deletions(-) diff --git a/generic/tclDictObj.c b/generic/tclDictObj.c index 71d5f5d..f3c582c 100644 --- a/generic/tclDictObj.c +++ b/generic/tclDictObj.c @@ -600,7 +600,7 @@ SetDictFromAny( Tcl_Obj *objPtr) { Tcl_HashEntry *hPtr; - int isNew, result; + int isNew; Dict *dict = ckalloc(sizeof(Dict)); InitChainTable(dict); @@ -651,10 +651,9 @@ SetDictFromAny( const char *elemStart; int elemSize, literal; - result = TclFindElement(interp, nextElem, (limit - nextElem), - &elemStart, &nextElem, &elemSize, &literal); - if (result != TCL_OK) { - goto errorExit; + if (TclFindElement(interp, nextElem, (limit - nextElem), + &elemStart, &nextElem, &elemSize, &literal) != TCL_OK) { + goto errorInFindElement; } if (elemStart == limit) { break; @@ -673,11 +672,10 @@ SetDictFromAny( keyPtr->bytes); } - result = TclFindElement(interp, nextElem, (limit - nextElem), - &elemStart, &nextElem, &elemSize, &literal); - if (result != TCL_OK) { + if (TclFindElement(interp, nextElem, (limit - nextElem), + &elemStart, &nextElem, &elemSize, &literal) != TCL_OK) { TclDecrRefCount(keyPtr); - goto errorExit; + goto errorInFindElement; } if (literal) { @@ -722,16 +720,15 @@ SetDictFromAny( Tcl_SetObjResult(interp, Tcl_NewStringObj( "missing value to go with key", -1)); Tcl_SetErrorCode(interp, "TCL", "VALUE", "DICTIONARY", NULL); - } - result = TCL_ERROR; - - errorExit: - if (interp != NULL) { - Tcl_SetErrorCode(interp, "TCL", "VALUE", "DICTIONARY", NULL); + } else { + errorInFindElement: + if (interp != NULL) { + Tcl_SetErrorCode(interp, "TCL", "VALUE", "DICTIONARY", NULL); + } } DeleteChainTable(dict); ckfree(dict); - return result; + return TCL_ERROR; } /* diff --git a/tests/dict.test b/tests/dict.test index 1ccad7c..ae6f42a 100644 --- a/tests/dict.test +++ b/tests/dict.test @@ -176,9 +176,38 @@ test dict-4.12 {dict replace command: canonicality forced by update} { test dict-4.13 {dict replace command: type check is mandatory} -body { dict replace { a b c d e } } -returnCodes error -result {missing value to go with key} +test dict-4.13a {dict replace command: type check is mandatory} { + catch {dict replace { a b c d e }} -> opt + dict get $opt -errorcode +} {TCL VALUE DICTIONARY} test dict-4.14 {dict replace command: type check is mandatory} -body { dict replace { a b {}c d } } -returnCodes error -result {list element in braces followed by "c" instead of space} +test dict-4.14a {dict replace command: type check is mandatory} { + catch {dict replace { a b {}c d }} -> opt + dict get $opt -errorcode +} {TCL VALUE DICTIONARY} +test dict-4.15 {dict replace command: type check is mandatory} -body { + dict replace { a b ""c d } +} -returnCodes error -result {list element in quotes followed by "c" instead of space} +test dict-4.15a {dict replace command: type check is mandatory} { + catch {dict replace { a b ""c d }} -> opt + dict get $opt -errorcode +} {TCL VALUE DICTIONARY} +test dict-4.16 {dict replace command: type check is mandatory} -body { + dict replace " a b \"c d " +} -returnCodes error -result {unmatched open quote in list} +test dict-4.16a {dict replace command: type check is mandatory} { + catch {dict replace " a b \"c d "} -> opt + dict get $opt -errorcode +} {TCL VALUE DICTIONARY} +test dict-4.17 {dict replace command: type check is mandatory} -body { + dict replace " a b \{c d " +} -returnCodes error -result {unmatched open brace in list} +test dict-4.17a {dict replace command: type check is mandatory} { + catch {dict replace " a b \{c d "} -> opt + dict get $opt -errorcode +} {TCL VALUE DICTIONARY} test dict-5.1 {dict remove command} {dict remove {a b c d} a} {c d} test dict-5.2 {dict remove command} {dict remove {a b c d} c} {a b} -- cgit v0.12 From 3189f48d19ee5fe595f856ca7d755f61414cfbef Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 4 Jun 2014 16:36:25 +0000 Subject: Revise DiscardOutput() to account for revisions to the loop in FlushChannel() which is its only caller. We need to discard the curOutPtr buffer as well, and not count on another pass through the loop to attempt to flush it (and raise the same failure again?). --- generic/tclIO.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/generic/tclIO.c b/generic/tclIO.c index ed94bfe..b7135e9 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -2415,6 +2415,11 @@ DiscardOutputQueued( } statePtr->outQueueHead = NULL; statePtr->outQueueTail = NULL; + bufPtr = statePtr->curOutPtr; + if (bufPtr && BytesLeft(bufPtr)) { + statePtr->curOutPtr = NULL; + RecycleBuffer(statePtr, bufPtr, 0); + } } /* -- cgit v0.12 From 45fd54872fa0bcff3d89f8077d9a7ca220bba89f Mon Sep 17 00:00:00 2001 From: andy Date: Wed, 4 Jun 2014 21:45:29 +0000 Subject: Add missing calls to Tcl_DecrRefCount() in string object man page examples. --- doc/StringObj.3 | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/doc/StringObj.3 b/doc/StringObj.3 index d81f23d..cf8f6d3 100644 --- a/doc/StringObj.3 +++ b/doc/StringObj.3 @@ -293,6 +293,7 @@ of \fBTcl_Format\fR with functionality equivalent to: Tcl_Obj *newPtr = \fBTcl_Format\fR(interp, format, objc, objv); if (newPtr == NULL) return TCL_ERROR; \fBTcl_AppendObjToObj\fR(objPtr, newPtr); +\fBTcl_DecrRefCount\fR(newPtr); return TCL_OK; .CE .PP @@ -337,7 +338,9 @@ Compile-time protection may be provided by some compilers. of \fBTcl_ObjPrintf\fR with functionality equivalent to .PP .CS -\fBTcl_AppendObjToObj\fR(objPtr, \fBTcl_ObjPrintf\fR(format, ...)); +Tcl_Obj *newPtr = \fBTcl_ObjPrintf\fR(format, ...); +\fBTcl_AppendObjToObj\fR(objPtr, newPtr); +\fBTcl_DecrRefCount\fR(newPtr); .CE .PP but with greater convenience and efficiency when the appending -- cgit v0.12 From ba7b49d9c4a0bf981789fd0a2b29ea5244b4680b Mon Sep 17 00:00:00 2001 From: andreask Date: Thu, 5 Jun 2014 00:22:59 +0000 Subject: Fixed a tricky interaction of IO system and encodings which could result in a panic. The relevant function is ReadChars() (short RC in the following). When the encoding and translation transforms deliver more characters than were requested the iterative algorithm used by RC reduces the value of "dstLimit" (= the number of bytes allowed to be copied into the destination buffer) to force the next round to deliver less characters, hopefully the number requested. The existing code used the byte located just after the last wanted character to determine the new limit. The resulting value could _undershoot_ the best possible limit because Tcl_ExternalToUtf would effectively reduce this limit further, by TCL_UTF_MAX+1, to have enough space for a single multi-byte character in the buffer, and a closing '\0' as well. One effect of this were additional calls to ReadChars() to retrieve the characters missed by a call with an undershot limit. In the limit (sic) however this was also able to cause a full-blown "Buffer Underflow" panic if the original request was for less than TCL_UTF_MAX characters (*), and we are using a single-byte encoding like iso-8859-1. Because then the undershot dstLimit would prevent the next round from copying anything, and causing it to try and consolidate the current buffer with the next buffer, thinking that it had to merge a multi-byte character split across buffer boundaries. (Ad *) For example because the previous call had undershot already and left only such a small amount of characters behind! The basic fix to the problem is to add TCL_UTF_MAX back to the limit, like is done in all the (three) other places in RC setting a new one. Note however that this naive fix may generate a new limit which is the same as the old, or possibly larger. If that happens we act very conservatively and reduce the limit by only one byte instead. While I believe that this last conservative approach will never reduce the limit to TCL_UTF_MAX or less before reaching a state where it returnds the exact amount of requested characters I still added a check against this situation anyway, causing a new panic if triggered. --- generic/tclIO.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index b7135e9..e414668 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -5596,9 +5596,27 @@ ReadChars( /* * We read more chars than allowed. Reset limits to * prevent that and try again. + * + * Note how we are adding back TCL_UTF_MAX to ensure that the + * Tcl_External2Utf invoked by the next round will have enough + * space in the destination for at least one multi-byte + * character. Without that nothing will be copied and the system + * will try to consolidate the entire current and next buffer, + * likely triggering the "Buffer Underflow" panic. */ - dstLimit = Tcl_UtfAtIndex(dst, charsToRead + 1) - dst; + int newLimit = Tcl_UtfAtIndex(dst, charsToRead + 1) - dst + TCL_UTF_MAX; + + if (newLimit >= dstLimit) { + dstLimit --; + } else { + dstLimit = newLimit; + } + + if (dstLimit <= TCL_UTF_MAX) { + Tcl_Panic ("Not enough space left for a single multi-byte character."); + } + statePtr->flags = savedFlags; statePtr->inputEncodingFlags = savedIEFlags; statePtr->inputEncodingState = savedState; @@ -5661,7 +5679,8 @@ ReadChars( */ if (nextPtr->nextRemoved - srcLen < 0) { - Tcl_Panic("Buffer Underflow, BUFFER_PADDING not enough"); + Tcl_Panic("Buffer Underflow, BUFFER_PADDING not enough (%d < %d)", + nextPtr->nextRemoved, srcLen); } nextPtr->nextRemoved -= srcLen; -- cgit v0.12 From 3eb959fc935f4f1a92c7527be675245c0def5dfd Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 5 Jun 2014 15:17:29 +0000 Subject: When too many chars are read by ReadChars() and we trim the limits to get it right on the next pass, don't forget the TCL_UTF_MAX padding demanded by Tcl_ExternalToUtf(). (Thanks for finding that, aku!) Fix the factorPtr management. It was just totaly wrong. The factor should be a ratio of the record of bytes read to the record of chars read. With those fixes, new test io-12.6 covers the "too many chars" code. --- generic/tclIO.c | 15 +++++++++++---- tests/io.test | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 4 deletions(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index b7135e9..308e7a9 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -5595,10 +5595,13 @@ ReadChars( /* * We read more chars than allowed. Reset limits to - * prevent that and try again. + * prevent that and try again. Don't forget the extra + * padding of TCL_UTF_MAX - 1 bytes demanded by the + * Tcl_ExternalToUtf() call! */ - dstLimit = Tcl_UtfAtIndex(dst, charsToRead + 1) - dst; + dstLimit = Tcl_UtfAtIndex(dst, charsToRead + 1) + + TCL_UTF_MAX - 1 - dst; statePtr->flags = savedFlags; statePtr->inputEncodingFlags = savedIEFlags; statePtr->inputEncodingState = savedState; @@ -5676,8 +5679,12 @@ ReadChars( consume: bufPtr->nextRemoved += srcRead; - if (dstWrote > srcRead + 1) { - *factorPtr = dstWrote * UTF_EXPANSION_FACTOR / srcRead; + /* + * If this read contained multibyte characters, revise factorPtr + * so the next read will allocate bigger buffers. + */ + if (numChars && numChars < srcRead) { + *factorPtr = srcRead * UTF_EXPANSION_FACTOR / numChars; } Tcl_SetObjLength(objPtr, numBytes + dstWrote); return numChars; diff --git a/tests/io.test b/tests/io.test index f1248b9..a1625ba 100644 --- a/tests/io.test +++ b/tests/io.test @@ -1445,6 +1445,39 @@ test io-12.5 {ReadChars: fileevents on partial characters} {stdio openpipe filee lappend x [catch {close $f} msg] $msg set x } "{} timeout {} timeout \u7266 {} eof 0 {}" +test io-12.6 {ReadChars: too many chars read} { + proc driver {cmd args} { + variable buffer + variable index + set chan [lindex $args 0] + switch -- $cmd { + initialize { + set index($chan) 0 + set buffer($chan) [encoding convertto utf-8 \ + [string repeat \uBEEF 20][string repeat . 20]] + return {initialize finalize watch read} + } + finalize { + unset index($chan) buffer($chan) + return + } + watch {} + read { + set n [lindex $args 1] + set new [expr {$index($chan) + $n}] + set result [string range $buffer($chan) $index($chan) $new-1] + set index($chan) $new + return $result + } + } + } + set c [chan create read [namespace which driver]] + chan configure $c -encoding utf-8 + while {![eof $c]} { + read $c 15 + } + close $c +} {} test io-13.1 {TranslateInputEOL: cr mode} {} { set f [open $path(test1) w] -- cgit v0.12 From bb4c894bca0bed064a485d8896bc22bb352d3d66 Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 5 Jun 2014 19:06:08 +0000 Subject: Test socket-2.12 covers the DiscardOutput() update. --- tests/socket.test | 40 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/tests/socket.test b/tests/socket.test index 1b7c5fa..2953c39 100644 --- a/tests/socket.test +++ b/tests/socket.test @@ -577,7 +577,45 @@ test socket-2.11 {detecting new data} {socket} { close $sock set result } {a:one b: c:two} - +test socket-2.12 {} {socket stdio} { + file delete $path(script) + set f [open $path(script) w] + puts $f { + set server [socket -server accept_client 0] + puts [lindex [chan configure $server -sockname] 2] + proc accept_client { client host port } { + chan configure $client -blocking 0 -buffering line + write_line $client + } + proc write_line client { + if { [catch { chan puts $client [string repeat . 720000]}] } { + puts [catch {chan close $client}] + } else { + puts signal1 + after 0 write_line $client + } + } + chan event stdin readable {set forever now} + vwait forever + exit + } + close $f + set f [open "|[list [interpreter] $path(script)]" r+] + gets $f port + set sock [socket 127.0.0.1 $port] + chan event $sock readable [list read_lines $sock $f] + proc read_lines { sock pipe } { + gets $pipe + chan close $sock + chan event $pipe readable [list readpipe $pipe] + } + proc readpipe {pipe} { + while {![string is integer [set ::done [gets $pipe]]]} {} + } + vwait ::done + close $f + set ::done +} 0 test socket-3.1 {socket conflict} {socket stdio} { file delete $path(script) -- cgit v0.12 From 6a99b9a54626111350b21ac428bb850942170ba4 Mon Sep 17 00:00:00 2001 From: dkf Date: Sat, 7 Jun 2014 14:18:40 +0000 Subject: Improved the error messages. We do not want parsing an invalid dictionary to give errors about lists! As compensation, we get greater precision in the errorcode. --- generic/tclDictObj.c | 14 +++---- generic/tclInt.h | 4 ++ generic/tclUtil.c | 105 +++++++++++++++++++++++++++++++++++++++++---------- tests/dict.test | 20 +++++----- 4 files changed, 104 insertions(+), 39 deletions(-) diff --git a/generic/tclDictObj.c b/generic/tclDictObj.c index f3c582c..77f66fb 100644 --- a/generic/tclDictObj.c +++ b/generic/tclDictObj.c @@ -651,9 +651,9 @@ SetDictFromAny( const char *elemStart; int elemSize, literal; - if (TclFindElement(interp, nextElem, (limit - nextElem), + if (TclFindDictElement(interp, nextElem, (limit - nextElem), &elemStart, &nextElem, &elemSize, &literal) != TCL_OK) { - goto errorInFindElement; + goto errorInFindDictElement; } if (elemStart == limit) { break; @@ -672,10 +672,10 @@ SetDictFromAny( keyPtr->bytes); } - if (TclFindElement(interp, nextElem, (limit - nextElem), + if (TclFindDictElement(interp, nextElem, (limit - nextElem), &elemStart, &nextElem, &elemSize, &literal) != TCL_OK) { TclDecrRefCount(keyPtr); - goto errorInFindElement; + goto errorInFindDictElement; } if (literal) { @@ -720,12 +720,8 @@ SetDictFromAny( Tcl_SetObjResult(interp, Tcl_NewStringObj( "missing value to go with key", -1)); Tcl_SetErrorCode(interp, "TCL", "VALUE", "DICTIONARY", NULL); - } else { - errorInFindElement: - if (interp != NULL) { - Tcl_SetErrorCode(interp, "TCL", "VALUE", "DICTIONARY", NULL); - } } + errorInFindDictElement: DeleteChainTable(dict); ckfree(dict); return TCL_ERROR; diff --git a/generic/tclInt.h b/generic/tclInt.h index b1a368e..9a2e8dd 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -2881,6 +2881,10 @@ MODULE_SCOPE void TclContinuationsCopy(Tcl_Obj *objPtr, MODULE_SCOPE int TclConvertElement(const char *src, int length, char *dst, int flags); MODULE_SCOPE void TclDeleteNamespaceVars(Namespace *nsPtr); +MODULE_SCOPE int TclFindDictElement(Tcl_Interp *interp, + const char *dict, int dictLength, + const char **elementPtr, const char **nextPtr, + int *sizePtr, int *literalPtr); /* TIP #280 - Modified token based evulation, with line information. */ MODULE_SCOPE int TclEvalEx(Tcl_Interp *interp, const char *script, int numBytes, int flags, int line, diff --git a/generic/tclUtil.c b/generic/tclUtil.c index 2d00adf..ae3adae 100644 --- a/generic/tclUtil.c +++ b/generic/tclUtil.c @@ -111,7 +111,11 @@ static Tcl_HashTable * GetThreadHash(Tcl_ThreadDataKey *keyPtr); static int SetEndOffsetFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr); static void UpdateStringOfEndOffset(Tcl_Obj *objPtr); - +static int FindElement(Tcl_Interp *interp, const char *string, + int stringLength, const char *typeStr, + const char *typeCode, const char **elementPtr, + const char **nextPtr, int *sizePtr, + int *literalPtr); /* * 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 @@ -237,7 +241,7 @@ const Tcl_ObjType tclEndOffsetType = { * of either braces or quotes to delimit it. * * This collection of parsing rules is implemented in the routine - * TclFindElement(). + * FindElement(). * * In order to produce lists that can be parsed by these rules, we need the * ability to distinguish between characters that are part of a list element @@ -505,9 +509,70 @@ TclFindElement( * does not/does require a call to * TclCopyAndCollapse() by the caller. */ { - const char *p = list; + return FindElement(interp, list, listLength, "list", "LIST", elementPtr, + nextPtr, sizePtr, literalPtr); +} + +int +TclFindDictElement( + Tcl_Interp *interp, /* Interpreter to use for error reporting. If + * NULL, then no error message is left after + * errors. */ + const char *dict, /* Points to the first byte of a string + * containing a Tcl dictionary with zero or + * more keys and values (possibly in + * braces). */ + int dictLength, /* Number of bytes in the dict's string. */ + const char **elementPtr, /* Where to put address of first significant + * character in the first element (i.e., key + * or value) of dict. */ + const char **nextPtr, /* Fill in with location of character just + * after all white space following end of + * element (next arg or end of list). */ + int *sizePtr, /* If non-zero, fill in with size of + * element. */ + int *literalPtr) /* If non-zero, fill in with non-zero/zero to + * indicate that the substring of *sizePtr + * bytes starting at **elementPtr is/is not + * the literal key or value and therefore + * does not/does require a call to + * TclCopyAndCollapse() by the caller. */ +{ + return FindElement(interp, dict, dictLength, "dict", "DICTIONARY", + elementPtr, nextPtr, sizePtr, literalPtr); +} + +static int +FindElement( + Tcl_Interp *interp, /* Interpreter to use for error reporting. If + * NULL, then no error message is left after + * errors. */ + const char *string, /* Points to the first byte of a string + * containing a Tcl list or dictionary with + * zero or more elements (possibly in + * braces). */ + int stringLength, /* Number of bytes in the string. */ + const char *typeStr, /* The name of the type of thing we are + * parsing, for error messages. */ + const char *typeCode, /* The type code for thing we are parsing, for + * error messages. */ + const char **elementPtr, /* Where to put address of first significant + * character in first element. */ + const char **nextPtr, /* Fill in with location of character just + * after all white space following end of + * argument (next arg or end of list/dict). */ + int *sizePtr, /* If non-zero, fill in with size of + * element. */ + int *literalPtr) /* If non-zero, fill in with non-zero/zero to + * indicate that the substring of *sizePtr + * bytes starting at **elementPtr is/is not + * the literal list/dict element and therefore + * does not/does require a call to + * TclCopyAndCollapse() by the caller. */ +{ + const char *p = string; const char *elemStart; /* Points to first byte of first element. */ - const char *limit; /* Points just after list's last byte. */ + const char *limit; /* Points just after list/dict's last byte. */ int openBraces = 0; /* Brace nesting level during parse. */ int inQuotes = 0; int size = 0; /* lint. */ @@ -517,11 +582,11 @@ TclFindElement( /* * Skim off leading white space and check for an opening brace or quote. - * We treat embedded NULLs in the list as bytes belonging to a list - * element. + * We treat embedded NULLs in the list/dict as bytes belonging to a list + * element (or dictionary key or value). */ - limit = (list + listLength); + limit = (string + stringLength); while ((p < limit) && (TclIsSpaceProc(*p))) { p++; } @@ -582,9 +647,9 @@ TclFindElement( p2++; } Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "list element in braces followed by \"%.*s\" " - "instead of space", (int) (p2-p), p)); - Tcl_SetErrorCode(interp, "TCL", "VALUE", "LIST", "JUNK", + "%s element in braces followed by \"%.*s\" " + "instead of space", typeStr, (int) (p2-p), p)); + Tcl_SetErrorCode(interp, "TCL", "VALUE", typeCode, "JUNK", NULL); } return TCL_ERROR; @@ -651,9 +716,9 @@ TclFindElement( p2++; } Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "list element in quotes followed by \"%.*s\" " - "instead of space", (int) (p2-p), p)); - Tcl_SetErrorCode(interp, "TCL", "VALUE", "LIST", "JUNK", + "%s element in quotes followed by \"%.*s\" " + "instead of space", typeStr, (int) (p2-p), p)); + Tcl_SetErrorCode(interp, "TCL", "VALUE", typeCode, "JUNK", NULL); } return TCL_ERROR; @@ -664,23 +729,23 @@ TclFindElement( } /* - * End of list: terminate element. + * End of list/dict: terminate element. */ if (p == limit) { if (openBraces != 0) { if (interp != NULL) { - Tcl_SetObjResult(interp, Tcl_NewStringObj( - "unmatched open brace in list", -1)); - Tcl_SetErrorCode(interp, "TCL", "VALUE", "LIST", "BRACE", + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "unmatched open brace in %s", typeStr)); + Tcl_SetErrorCode(interp, "TCL", "VALUE", typeCode, "BRACE", NULL); } return TCL_ERROR; } else if (inQuotes) { if (interp != NULL) { - Tcl_SetObjResult(interp, Tcl_NewStringObj( - "unmatched open quote in list", -1)); - Tcl_SetErrorCode(interp, "TCL", "VALUE", "LIST", "QUOTE", + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "unmatched open quote in %s", typeStr)); + Tcl_SetErrorCode(interp, "TCL", "VALUE", typeCode, "QUOTE", NULL); } return TCL_ERROR; diff --git a/tests/dict.test b/tests/dict.test index ae6f42a..1439af9 100644 --- a/tests/dict.test +++ b/tests/dict.test @@ -182,32 +182,32 @@ test dict-4.13a {dict replace command: type check is mandatory} { } {TCL VALUE DICTIONARY} test dict-4.14 {dict replace command: type check is mandatory} -body { dict replace { a b {}c d } -} -returnCodes error -result {list element in braces followed by "c" instead of space} +} -returnCodes error -result {dict element in braces followed by "c" instead of space} test dict-4.14a {dict replace command: type check is mandatory} { catch {dict replace { a b {}c d }} -> opt dict get $opt -errorcode -} {TCL VALUE DICTIONARY} +} {TCL VALUE DICTIONARY JUNK} test dict-4.15 {dict replace command: type check is mandatory} -body { dict replace { a b ""c d } -} -returnCodes error -result {list element in quotes followed by "c" instead of space} +} -returnCodes error -result {dict element in quotes followed by "c" instead of space} test dict-4.15a {dict replace command: type check is mandatory} { catch {dict replace { a b ""c d }} -> opt dict get $opt -errorcode -} {TCL VALUE DICTIONARY} +} {TCL VALUE DICTIONARY JUNK} test dict-4.16 {dict replace command: type check is mandatory} -body { dict replace " a b \"c d " -} -returnCodes error -result {unmatched open quote in list} +} -returnCodes error -result {unmatched open quote in dict} test dict-4.16a {dict replace command: type check is mandatory} { catch {dict replace " a b \"c d "} -> opt dict get $opt -errorcode -} {TCL VALUE DICTIONARY} +} {TCL VALUE DICTIONARY QUOTE} test dict-4.17 {dict replace command: type check is mandatory} -body { dict replace " a b \{c d " -} -returnCodes error -result {unmatched open brace in list} +} -returnCodes error -result {unmatched open brace in dict} test dict-4.17a {dict replace command: type check is mandatory} { catch {dict replace " a b \{c d "} -> opt dict get $opt -errorcode -} {TCL VALUE DICTIONARY} +} {TCL VALUE DICTIONARY BRACE} test dict-5.1 {dict remove command} {dict remove {a b c d} a} {c d} test dict-5.2 {dict remove command} {dict remove {a b c d} c} {a b} @@ -234,7 +234,7 @@ test dict-5.11 {dict remove command: type check is mandatory} -body { } -returnCodes error -result {missing value to go with key} test dict-5.12 {dict remove command: type check is mandatory} -body { dict remove { a b {}c d } -} -returnCodes error -result {list element in braces followed by "c" instead of space} +} -returnCodes error -result {dict element in braces followed by "c" instead of space} test dict-6.1 {dict keys command} {dict keys {a b}} a test dict-6.2 {dict keys command} {dict keys {c d}} c @@ -1296,7 +1296,7 @@ test dict-20.24 {dict merge command: type check is mandatory} -body { } -returnCodes error -result {missing value to go with key} test dict-20.25 {dict merge command: type check is mandatory} -body { dict merge { a b {}c d } -} -returnCodes error -result {list element in braces followed by "c" instead of space} +} -returnCodes error -result {dict element in braces followed by "c" instead of space} test dict-21.1 {dict update command} -returnCodes 1 -body { dict update -- cgit v0.12 From 86b84b6d213aa12182dd2809dbea0e5121bf9add Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 11 Jun 2014 17:24:58 +0000 Subject: Workaround the broken select() in some Linux kernels that fails to report a writable state on a socket when an error condition (or remote close) is present. Would be good to add actual test suite tests for this, but until then see demo scripts in the ticket 1758a0b603. --- unix/tclUnixChan.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 52 insertions(+), 3 deletions(-) diff --git a/unix/tclUnixChan.c b/unix/tclUnixChan.c index 93bb1fe..fc3c10f 100644 --- a/unix/tclUnixChan.c +++ b/unix/tclUnixChan.c @@ -150,6 +150,7 @@ typedef struct TcpState { int fd; /* The socket itself. */ int flags; /* ORed combination of the bitfields defined * below. */ + int interest; /* Events types of interest. */ Tcl_TcpAcceptProc *acceptProc; /* Proc to call on accept. */ ClientData acceptProcData; /* The data for the accept proc. */ @@ -2198,6 +2199,30 @@ TcpGetOptionProc( */ static void +WrapNotify( + ClientData clientData, + int mask) +{ + TcpState *statePtr = (TcpState *) clientData; + int newmask = mask & statePtr->interest; + + if (newmask == 0) { + /* + * There was no overlap between the states the channel is + * interested in notifications for, and the states that are + * reported present on the file descriptor by select(). The + * only way that can happen is when the channel is interested + * in a writable condition, and only a readable state is reported + * present (see TcpWatchProc() below). In that case, signal back + * to the caller the writable state, which is really an error + * condition. + */ + newmask = TCL_WRITABLE; + } + Tcl_NotifyChannel(statePtr->channel, newmask); +} + +static void TcpWatchProc( ClientData instanceData, /* The socket state. */ int mask) /* Events of interest; an OR-ed combination of @@ -2214,9 +2239,30 @@ TcpWatchProc( if (!statePtr->acceptProc) { if (mask) { - Tcl_CreateFileHandler(statePtr->fd, mask, - (Tcl_FileProc *) Tcl_NotifyChannel, - (ClientData) statePtr->channel); + + /* + * Whether it is a bug or feature or otherwise, it is a fact + * of life that on at least some Linux kernels select() fails + * to report that a socket file descriptor is writable when + * the other end of the socket is closed. This is in contrast + * to the guarantees Tcl makes that its channels become + * writable and fire writable events on an error conditon. + * This has caused a leak of file descriptors in a state of + * background flushing. See Tcl ticket 1758a0b603. + * + * As a workaround, when our caller indicates an interest in + * writable notifications, we must tell the notifier built + * around select() that we are interested in the readable state + * of the file descriptor as well, as that is the only reliable + * means to get notified of error conditions. Then it is the + * task of WrapNotify() above to untangle the meaning of these + * channel states and report the chan events as best it can. + * We save a copy of the mask passed in to assist with that. + */ + + statePtr->interest = mask; + Tcl_CreateFileHandler(statePtr->fd, mask|TCL_READABLE, + (Tcl_FileProc *) WrapNotify, (ClientData) statePtr); } else { Tcl_DeleteFileHandler(statePtr->fd); } @@ -2404,6 +2450,7 @@ CreateSocket( if (asyncConnect) { statePtr->flags = TCP_ASYNC_CONNECT; } + statePtr->interest = 0; statePtr->fd = sock; return statePtr; @@ -2675,6 +2722,7 @@ MakeTcpClientChannelMode( statePtr = (TcpState *) ckalloc((unsigned) sizeof(TcpState)); statePtr->fd = PTR2INT(sock); statePtr->flags = 0; + statePtr->interest = 0; statePtr->acceptProc = NULL; statePtr->acceptProcData = NULL; @@ -2792,6 +2840,7 @@ TcpAccept( newSockState = (TcpState *) ckalloc((unsigned) sizeof(TcpState)); newSockState->flags = 0; + newSockState->interest = 0; newSockState->fd = newsock; newSockState->acceptProc = NULL; newSockState->acceptProcData = NULL; -- cgit v0.12 From 4e3fe86fc26ba3d4a51bf7abfbf11ff039228b19 Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 12 Jun 2014 13:36:18 +0000 Subject: Additional check for an error condition on the socket. --- unix/tclUnixChan.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/unix/tclUnixChan.c b/unix/tclUnixChan.c index fc3c10f..1d60340 100644 --- a/unix/tclUnixChan.c +++ b/unix/tclUnixChan.c @@ -249,6 +249,7 @@ static int TtySetOptionProc(ClientData instanceData, static int WaitForConnect(TcpState *statePtr, int *errorCodePtr); static Tcl_Channel MakeTcpClientChannelMode(ClientData tcpSocket, int mode); +static void WrapNotify(ClientData clientData, int mask); /* * This structure describes the channel type structure for file based IO: @@ -2215,8 +2216,13 @@ WrapNotify( * in a writable condition, and only a readable state is reported * present (see TcpWatchProc() below). In that case, signal back * to the caller the writable state, which is really an error - * condition. + * condition. As an extra check on that assumption, check for + * a non-zero value of errno before reporting an artificial + * writable state. */ + if (errno == 0) { + return; + } newmask = TCL_WRITABLE; } Tcl_NotifyChannel(statePtr->channel, newmask); -- cgit v0.12 From 2621d5a21a7d9f2313adcc8d3ea4595ee65c1c20 Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 13 Jun 2014 21:15:13 +0000 Subject: Draft test for [1758a0b603]. --- tests/socket.test | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/tests/socket.test b/tests/socket.test index 2953c39..b390627 100644 --- a/tests/socket.test +++ b/tests/socket.test @@ -616,6 +616,47 @@ test socket-2.12 {} {socket stdio} { close $f set ::done } 0 +test socket-2.13 {Bug 1758a0b603} {socket stdio} { + file delete $path(script) + set f [open $path(script) w] + puts $f { + set server [socket -server accept 0] + puts [lindex [chan configure $server -sockname] 2] + proc accept { client host port } { + chan configure $client -blocking 0 -buffering line -buffersize 1 + puts $client [string repeat . 720000] + puts ready + chan event $client writable [list setup $client] + } + proc setup client { + chan event $client writable {set forever write} + after 5 {set forever timeout} + } + vwait forever + puts $forever + } + close $f + set pipe [open |[list [interpreter] $path(script)] r] + gets $pipe port + set sock [socket localhost $port] + chan configure $sock -blocking 0 -buffering line + chan event $sock readable [list read_lines $sock $pipe ] + proc read_lines { sock pipe } { + gets $pipe + gets $sock line + after idle [list stop $sock $pipe] + chan event $sock readable {} + } + proc stop {sock pipe} { + variable done + close $sock + set done [gets $pipe] + } + variable done + vwait [namespace which -variable done] + close $pipe + set done +} write test socket-3.1 {socket conflict} {socket stdio} { file delete $path(script) -- cgit v0.12 From 08d90963621681f9cbaed569b85284792c3faa51 Mon Sep 17 00:00:00 2001 From: dkf Date: Sun, 15 Jun 2014 07:52:57 +0000 Subject: Make [dict replace] and [dict remove] guarantee result canonicality. --- generic/tclDictObj.c | 149 ++++++++++++++++++++++----------------------------- tests/dict.test | 30 +++++++---- 2 files changed, 84 insertions(+), 95 deletions(-) diff --git a/generic/tclDictObj.c b/generic/tclDictObj.c index 77f66fb..a057b8a 100644 --- a/generic/tclDictObj.c +++ b/generic/tclDictObj.c @@ -770,10 +770,9 @@ TclTraceDictPath( Dict *dict, *newDict; int i; - if (dictPtr->typePtr != &tclDictType) { - if (SetDictFromAny(interp, dictPtr) != TCL_OK) { - return NULL; - } + if (dictPtr->typePtr != &tclDictType + && SetDictFromAny(interp, dictPtr) != TCL_OK) { + return NULL; } dict = dictPtr->internalRep.twoPtrValue.ptr1; if (flags & DICT_PATH_UPDATE) { @@ -811,10 +810,9 @@ TclTraceDictPath( Tcl_SetHashValue(hPtr, tmpObj); } else { tmpObj = Tcl_GetHashValue(hPtr); - if (tmpObj->typePtr != &tclDictType) { - if (SetDictFromAny(interp, tmpObj) != TCL_OK) { - return NULL; - } + if (tmpObj->typePtr != &tclDictType + && SetDictFromAny(interp, tmpObj) != TCL_OK) { + return NULL; } } @@ -909,12 +907,9 @@ Tcl_DictObjPut( Tcl_Panic("%s called with shared object", "Tcl_DictObjPut"); } - if (dictPtr->typePtr != &tclDictType) { - int result = SetDictFromAny(interp, dictPtr); - - if (result != TCL_OK) { - return result; - } + if (dictPtr->typePtr != &tclDictType + && SetDictFromAny(interp, dictPtr) != TCL_OK) { + return TCL_ERROR; } if (dictPtr->bytes != NULL) { @@ -963,12 +958,10 @@ Tcl_DictObjGet( Dict *dict; Tcl_HashEntry *hPtr; - if (dictPtr->typePtr != &tclDictType) { - int result = SetDictFromAny(interp, dictPtr); - if (result != TCL_OK) { - *valuePtrPtr = NULL; - return result; - } + if (dictPtr->typePtr != &tclDictType + && SetDictFromAny(interp, dictPtr) != TCL_OK) { + *valuePtrPtr = NULL; + return TCL_ERROR; } dict = dictPtr->internalRep.twoPtrValue.ptr1; @@ -1012,11 +1005,9 @@ Tcl_DictObjRemove( Tcl_Panic("%s called with shared object", "Tcl_DictObjRemove"); } - if (dictPtr->typePtr != &tclDictType) { - int result = SetDictFromAny(interp, dictPtr); - if (result != TCL_OK) { - return result; - } + if (dictPtr->typePtr != &tclDictType + && SetDictFromAny(interp, dictPtr) != TCL_OK) { + return TCL_ERROR; } dict = dictPtr->internalRep.twoPtrValue.ptr1; @@ -1055,11 +1046,9 @@ Tcl_DictObjSize( { Dict *dict; - if (dictPtr->typePtr != &tclDictType) { - int result = SetDictFromAny(interp, dictPtr); - if (result != TCL_OK) { - return result; - } + if (dictPtr->typePtr != &tclDictType + && SetDictFromAny(interp, dictPtr) != TCL_OK) { + return TCL_ERROR; } dict = dictPtr->internalRep.twoPtrValue.ptr1; @@ -1109,12 +1098,9 @@ Tcl_DictObjFirst( Dict *dict; ChainEntry *cPtr; - if (dictPtr->typePtr != &tclDictType) { - int result = SetDictFromAny(interp, dictPtr); - - if (result != TCL_OK) { - return result; - } + if (dictPtr->typePtr != &tclDictType + && SetDictFromAny(interp, dictPtr) != TCL_OK) { + return TCL_ERROR; } dict = dictPtr->internalRep.twoPtrValue.ptr1; @@ -1497,7 +1483,7 @@ DictCreateCmd( /* * The next command is assumed to never fail... */ - Tcl_DictObjPut(interp, dictObj, objv[i], objv[i+1]); + Tcl_DictObjPut(NULL, dictObj, objv[i], objv[i+1]); } Tcl_SetObjResult(interp, dictObj); return TCL_OK; @@ -1630,17 +1616,18 @@ DictReplaceCmd( } dictPtr = objv[1]; - if (dictPtr->typePtr != &tclDictType) { - int result = SetDictFromAny(interp, dictPtr); - if (result != TCL_OK) { - return result; - } + if (dictPtr->typePtr != &tclDictType + && SetDictFromAny(interp, dictPtr) != TCL_OK) { + return TCL_ERROR; + } + if (Tcl_IsShared(dictPtr)) { + dictPtr = Tcl_DuplicateObj(dictPtr); + } + if (dictPtr->bytes != NULL) { + TclInvalidateStringRep(dictPtr); } for (i=2 ; itypePtr != &tclDictType) { - int result = SetDictFromAny(interp, dictPtr); - if (result != TCL_OK) { - return result; - } + if (dictPtr->typePtr != &tclDictType + && SetDictFromAny(interp, dictPtr) != TCL_OK) { + return TCL_ERROR; + } + if (Tcl_IsShared(dictPtr)) { + dictPtr = Tcl_DuplicateObj(dictPtr); + } + if (dictPtr->bytes != NULL) { + TclInvalidateStringRep(dictPtr); } for (i=2 ; itypePtr != &tclDictType) { - if (SetDictFromAny(interp, targetObj) != TCL_OK) { - return TCL_ERROR; - } + if (targetObj->typePtr != &tclDictType + && SetDictFromAny(interp, targetObj) != TCL_OK) { + return TCL_ERROR; } if (objc == 2) { @@ -1824,12 +1811,9 @@ DictKeysCmd( * need. [Bug 1705778, leak K04] */ - if (objv[1]->typePtr != &tclDictType) { - int result = SetDictFromAny(interp, objv[1]); - - if (result != TCL_OK) { - return result; - } + if (objv[1]->typePtr != &tclDictType + && SetDictFromAny(interp, objv[1]) != TCL_OK) { + return TCL_ERROR; } if (objc == 3) { @@ -2045,11 +2029,9 @@ DictInfoCmd( } dictPtr = objv[1]; - if (dictPtr->typePtr != &tclDictType) { - int result = SetDictFromAny(interp, dictPtr); - if (result != TCL_OK) { - return result; - } + if (dictPtr->typePtr != &tclDictType + && SetDictFromAny(interp, dictPtr) != TCL_OK) { + return TCL_ERROR; } dict = dictPtr->internalRep.twoPtrValue.ptr1; @@ -2141,10 +2123,10 @@ DictIncrCmd( */ mp_clear(&increment); - Tcl_DictObjPut(interp, dictPtr, objv[2], objv[3]); + Tcl_DictObjPut(NULL, dictPtr, objv[2], objv[3]); } } else { - Tcl_DictObjPut(interp, dictPtr, objv[2], Tcl_NewIntObj(1)); + Tcl_DictObjPut(NULL, dictPtr, objv[2], Tcl_NewIntObj(1)); } } else { /* @@ -2153,7 +2135,7 @@ DictIncrCmd( if (Tcl_IsShared(valuePtr)) { valuePtr = Tcl_DuplicateObj(valuePtr); - Tcl_DictObjPut(interp, dictPtr, objv[2], valuePtr); + Tcl_DictObjPut(NULL, dictPtr, objv[2], valuePtr); } if (objc == 4) { code = TclIncrObj(interp, valuePtr, objv[3]); @@ -2253,7 +2235,7 @@ DictLappendCmd( } if (allocatedValue) { - Tcl_DictObjPut(interp, dictPtr, objv[2], valuePtr); + Tcl_DictObjPut(NULL, dictPtr, objv[2], valuePtr); } else if (dictPtr->bytes != NULL) { TclInvalidateStringRep(dictPtr); } @@ -2328,7 +2310,7 @@ DictAppendCmd( Tcl_AppendObjToObj(valuePtr, objv[i]); } - Tcl_DictObjPut(interp, dictPtr, objv[2], valuePtr); + Tcl_DictObjPut(NULL, dictPtr, objv[2], valuePtr); resultPtr = Tcl_ObjSetVar2(interp, objv[1], NULL, dictPtr, TCL_LEAVE_ERR_MSG); @@ -2938,12 +2920,12 @@ DictFilterCmd( Tcl_DictObjDone(&search); Tcl_DictObjGet(interp, objv[1], objv[3], &valueObj); if (valueObj != NULL) { - Tcl_DictObjPut(interp, resultObj, objv[3], valueObj); + Tcl_DictObjPut(NULL, resultObj, objv[3], valueObj); } } else { while (!done) { if (Tcl_StringMatch(TclGetString(keyObj), pattern)) { - Tcl_DictObjPut(interp, resultObj, keyObj, valueObj); + Tcl_DictObjPut(NULL, resultObj, keyObj, valueObj); } Tcl_DictObjNext(&search, &keyObj, &valueObj, &done); } @@ -2961,7 +2943,7 @@ DictFilterCmd( for (i=3 ; i opt dict get $opt -errorcode } {TCL VALUE DICTIONARY BRACE} +test dict-4.18 {dict replace command: canonicality forcing doesn't leak} { + set example { a b c d } + list $example [dict replace $example] +} {{ a b c d } {a b c d}} test dict-5.1 {dict remove command} {dict remove {a b c d} a} {c d} test dict-5.2 {dict remove command} {dict remove {a b c d} c} {a b} @@ -220,12 +224,12 @@ test dict-5.6 {dict remove command} {dict remove {a b} c} {a b} test dict-5.7 {dict remove command} -returnCodes error -body { dict remove } -result {wrong # args: should be "dict remove dictionary ?key ...?"} -test dict-5.8 {dict remove command: canonicality not forced} { - dict remove { a b c d } -} { a b c d } -test dict-5.9 {dict remove command: canonicality not forced} { - dict remove { a b c d } e -} { a b c d } +test dict-5.8 {dict remove command: canonicality is forced} { + dict remove { a b c d } +} {a b c d} +test dict-5.9 {dict remove command: canonicality is forced} { + dict remove {a b c d a e} +} {a e c d} test dict-5.10 {dict remove command: canonicality forced by update} { dict remove { a b c d } c } {a b} @@ -235,6 +239,10 @@ test dict-5.11 {dict remove command: type check is mandatory} -body { test dict-5.12 {dict remove command: type check is mandatory} -body { dict remove { a b {}c d } } -returnCodes error -result {dict element in braces followed by "c" instead of space} +test dict-5.13 {dict remove command: canonicality forcing doesn't leak} { + set example { a b c d } + list $example [dict remove $example] +} {{ a b c d } {a b c d}} test dict-6.1 {dict keys command} {dict keys {a b}} a test dict-6.2 {dict keys command} {dict keys {c d}} c -- cgit v0.12 From 17751a998c8d965247ded100b90e4a2e51e0925d Mon Sep 17 00:00:00 2001 From: dkf Date: Sun, 15 Jun 2014 16:11:56 +0000 Subject: Some more cleaning up --- generic/tclDictObj.c | 80 +++++++++++++++++++++++++++++----------------------- 1 file changed, 44 insertions(+), 36 deletions(-) diff --git a/generic/tclDictObj.c b/generic/tclDictObj.c index a057b8a..9e606f7 100644 --- a/generic/tclDictObj.c +++ b/generic/tclDictObj.c @@ -155,6 +155,13 @@ typedef struct Dict { } Dict; /* + * Accessor macro for converting between a Tcl_Obj* and a Dict. Note that this + * must be assignable as well as readable. + */ + +#define DICT(dictObj) (*((Dict **)&(dictObj)->internalRep.twoPtrValue.ptr1)) + +/* * The structure below defines the dictionary object type by means of * functions that can be invoked by generic object code. */ @@ -312,6 +319,7 @@ DeleteChainEntry( return 0; } else { Tcl_Obj *valuePtr = Tcl_GetHashValue(&cPtr->entry); + TclDecrRefCount(valuePtr); } @@ -361,7 +369,7 @@ DupDictInternalRep( Tcl_Obj *srcPtr, Tcl_Obj *copyPtr) { - Dict *oldDict = srcPtr->internalRep.twoPtrValue.ptr1; + Dict *oldDict = DICT(srcPtr); Dict *newDict = ckalloc(sizeof(Dict)); ChainEntry *cPtr; @@ -396,7 +404,7 @@ DupDictInternalRep( * Store in the object. */ - copyPtr->internalRep.twoPtrValue.ptr1 = newDict; + DICT(copyPtr) = newDict; copyPtr->typePtr = &tclDictType; } @@ -422,7 +430,7 @@ static void FreeDictInternalRep( Tcl_Obj *dictPtr) { - Dict *dict = dictPtr->internalRep.twoPtrValue.ptr1; + Dict *dict = DICT(dictPtr); dict->refcount--; if (dict->refcount <= 0) { @@ -487,7 +495,7 @@ UpdateStringOfDict( { #define LOCAL_SIZE 20 int localFlags[LOCAL_SIZE], *flagPtr = NULL; - Dict *dict = dictPtr->internalRep.twoPtrValue.ptr1; + Dict *dict = DICT(dictPtr); ChainEntry *cPtr; Tcl_Obj *keyPtr, *valuePtr; int i, length, bytesNeeded = 0; @@ -711,7 +719,7 @@ SetDictFromAny( dict->epoch = 0; dict->chain = NULL; dict->refcount = 1; - objPtr->internalRep.twoPtrValue.ptr1 = dict; + DICT(objPtr) = dict; objPtr->typePtr = &tclDictType; return TCL_OK; @@ -774,7 +782,7 @@ TclTraceDictPath( && SetDictFromAny(interp, dictPtr) != TCL_OK) { return NULL; } - dict = dictPtr->internalRep.twoPtrValue.ptr1; + dict = DICT(dictPtr); if (flags & DICT_PATH_UPDATE) { dict->chain = NULL; } @@ -816,7 +824,7 @@ TclTraceDictPath( } } - newDict = tmpObj->internalRep.twoPtrValue.ptr1; + newDict = DICT(tmpObj); if (flags & DICT_PATH_UPDATE) { if (Tcl_IsShared(tmpObj)) { TclDecrRefCount(tmpObj); @@ -824,7 +832,7 @@ TclTraceDictPath( Tcl_IncrRefCount(tmpObj); Tcl_SetHashValue(hPtr, tmpObj); dict->epoch++; - newDict = tmpObj->internalRep.twoPtrValue.ptr1; + newDict = DICT(tmpObj); } newDict->chain = dictPtr; @@ -859,7 +867,7 @@ static void InvalidateDictChain( Tcl_Obj *dictObj) { - Dict *dict = dictObj->internalRep.twoPtrValue.ptr1; + Dict *dict = DICT(dictObj); do { TclInvalidateStringRep(dictObj); @@ -869,7 +877,7 @@ InvalidateDictChain( break; } dict->chain = NULL; - dict = dictObj->internalRep.twoPtrValue.ptr1; + dict = DICT(dictObj); } while (dict != NULL); } @@ -915,7 +923,7 @@ Tcl_DictObjPut( if (dictPtr->bytes != NULL) { TclInvalidateStringRep(dictPtr); } - dict = dictPtr->internalRep.twoPtrValue.ptr1; + dict = DICT(dictPtr); hPtr = CreateChainEntry(dict, keyPtr, &isNew); Tcl_IncrRefCount(valuePtr); if (!isNew) { @@ -964,7 +972,7 @@ Tcl_DictObjGet( return TCL_ERROR; } - dict = dictPtr->internalRep.twoPtrValue.ptr1; + dict = DICT(dictPtr); hPtr = Tcl_FindHashEntry(&dict->table, keyPtr); if (hPtr == NULL) { *valuePtrPtr = NULL; @@ -1010,7 +1018,7 @@ Tcl_DictObjRemove( return TCL_ERROR; } - dict = dictPtr->internalRep.twoPtrValue.ptr1; + dict = DICT(dictPtr); if (DeleteChainEntry(dict, keyPtr)) { if (dictPtr->bytes != NULL) { TclInvalidateStringRep(dictPtr); @@ -1051,7 +1059,7 @@ Tcl_DictObjSize( return TCL_ERROR; } - dict = dictPtr->internalRep.twoPtrValue.ptr1; + dict = DICT(dictPtr); *sizePtr = dict->table.numEntries; return TCL_OK; } @@ -1103,7 +1111,7 @@ Tcl_DictObjFirst( return TCL_ERROR; } - dict = dictPtr->internalRep.twoPtrValue.ptr1; + dict = DICT(dictPtr); cPtr = dict->entryChainHead; if (cPtr == NULL) { searchPtr->epoch = -1; @@ -1278,11 +1286,12 @@ Tcl_DictObjPutKeyList( return TCL_ERROR; } - dict = dictPtr->internalRep.twoPtrValue.ptr1; + dict = DICT(dictPtr); hPtr = CreateChainEntry(dict, keyv[keyc-1], &isNew); Tcl_IncrRefCount(valuePtr); if (!isNew) { Tcl_Obj *oldValuePtr = Tcl_GetHashValue(hPtr); + TclDecrRefCount(oldValuePtr); } Tcl_SetHashValue(hPtr, valuePtr); @@ -1334,7 +1343,7 @@ Tcl_DictObjRemoveKeyList( return TCL_ERROR; } - dict = dictPtr->internalRep.twoPtrValue.ptr1; + dict = DICT(dictPtr); DeleteChainEntry(dict, keyv[keyc-1]); InvalidateDictChain(dictPtr); return TCL_OK; @@ -1380,7 +1389,7 @@ Tcl_NewDictObj(void) dict->epoch = 0; dict->chain = NULL; dict->refcount = 1; - dictPtr->internalRep.twoPtrValue.ptr1 = dict; + DICT(dictPtr) = dict; dictPtr->typePtr = &tclDictType; return dictPtr; #endif @@ -1429,7 +1438,7 @@ Tcl_DbNewDictObj( dict->epoch = 0; dict->chain = NULL; dict->refcount = 1; - dictPtr->internalRep.twoPtrValue.ptr1 = dict; + DICT(dictPtr) = dict; dictPtr->typePtr = &tclDictType; return dictPtr; #else /* !TCL_MEM_DEBUG */ @@ -2033,7 +2042,7 @@ DictInfoCmd( && SetDictFromAny(interp, dictPtr) != TCL_OK) { return TCL_ERROR; } - dict = dictPtr->internalRep.twoPtrValue.ptr1; + dict = DICT(dictPtr); statsStr = Tcl_HashStats(&dict->table); Tcl_SetObjResult(interp, Tcl_NewStringObj(statsStr, -1)); @@ -2144,7 +2153,7 @@ DictIncrCmd( Tcl_IncrRefCount(incrPtr); code = TclIncrObj(interp, valuePtr, incrPtr); - Tcl_DecrRefCount(incrPtr); + TclDecrRefCount(incrPtr); } } if (code == TCL_OK) { @@ -2157,7 +2166,7 @@ DictIncrCmd( Tcl_SetObjResult(interp, valuePtr); } } else if (dictPtr->refCount == 0) { - Tcl_DecrRefCount(dictPtr); + TclDecrRefCount(dictPtr); } return code; } @@ -2300,10 +2309,8 @@ DictAppendCmd( if (valuePtr == NULL) { TclNewObj(valuePtr); - } else { - if (Tcl_IsShared(valuePtr)) { - valuePtr = Tcl_DuplicateObj(valuePtr); - } + } else if (Tcl_IsShared(valuePtr)) { + valuePtr = Tcl_DuplicateObj(valuePtr); } for (i=3 ; i Date: Sun, 15 Jun 2014 16:50:32 +0000 Subject: [cb042d294e] Improve consistency of [dict] wrong-args error messages. --- doc/dict.n | 10 +++++----- generic/tclDictObj.c | 20 ++++++++++---------- tests/dict.test | 52 ++++++++++++++++++++++++++-------------------------- 3 files changed, 41 insertions(+), 41 deletions(-) diff --git a/doc/dict.n b/doc/dict.n index 3bb5465..fecad85 100644 --- a/doc/dict.n +++ b/doc/dict.n @@ -54,10 +54,10 @@ The key rule only matches those key/value pairs whose keys match any of the given patterns (in the style of \fBstring match\fR.) .VE 8.6 .TP -\fBdict filter \fIdictionaryValue \fBscript {\fIkeyVar valueVar\fB} \fIscript\fR +\fBdict filter \fIdictionaryValue \fBscript {\fIkeyVariable valueVariable\fB} \fIscript\fR . The script rule tests for matching by assigning the key to the -\fIkeyVar\fR and the value to the \fIvalueVar\fR, and then evaluating +\fIkeyVariable\fR and the value to the \fIvalueVariable\fR, and then evaluating the given script which should return a boolean value (with the key/value pair only being included in the result of the \fBdict filter\fR when a true value is returned.) Note that the first @@ -75,7 +75,7 @@ of the given patterns (in the style of \fBstring match\fR.) .VE 8.6 .RE .TP -\fBdict for {\fIkeyVar valueVar\fB} \fIdictionaryValue body\fR +\fBdict for {\fIkeyVariable valueVariable\fB} \fIdictionaryValue body\fR . This command takes three arguments, the first a two-element list of variable names (for the key and value respectively of each mapping in @@ -150,7 +150,7 @@ 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. .TP -\fBdict map \fR{\fIkeyVar valueVar\fR} \fIdictionaryValue body\fR +\fBdict map \fR{\fIkeyVariable valueVariable\fR} \fIdictionaryValue body\fR . This command applies a transformation to each element of a dictionary, returning a new dictionary. It takes three arguments: the first is a @@ -160,7 +160,7 @@ and the third a script to be evaluated for each mapping with the key and value variables set appropriately (in the manner of \fBlmap\fR). In an iteration where the evaluated script completes normally (\fBTCL_OK\fR, as opposed to an \fBerror\fR, etc.) the result of the script is put into an accumulator -dictionary using the key that is the current contents of the \fIkeyVar\fR +dictionary using the key that is the current contents of the \fIkeyVariable\fR variable at that point. The result of the \fBdict map\fR command is the accumulator dictionary after all keys have been iterated over. .RS diff --git a/generic/tclDictObj.c b/generic/tclDictObj.c index 9e606f7..3c0ddd8 100644 --- a/generic/tclDictObj.c +++ b/generic/tclDictObj.c @@ -2079,7 +2079,7 @@ DictIncrCmd( Tcl_Obj *dictPtr, *valuePtr = NULL; if (objc < 3 || objc > 4) { - Tcl_WrongNumArgs(interp, 1, objv, "varName key ?increment?"); + Tcl_WrongNumArgs(interp, 1, objv, "dictVarName key ?increment?"); return TCL_ERROR; } @@ -2200,7 +2200,7 @@ DictLappendCmd( int i, allocatedDict = 0, allocatedValue = 0; if (objc < 3) { - Tcl_WrongNumArgs(interp, 1, objv, "varName key ?value ...?"); + Tcl_WrongNumArgs(interp, 1, objv, "dictVarName key ?value ...?"); return TCL_ERROR; } @@ -2287,7 +2287,7 @@ DictAppendCmd( int i, allocatedDict = 0; if (objc < 3) { - Tcl_WrongNumArgs(interp, 1, objv, "varName key ?value ...?"); + Tcl_WrongNumArgs(interp, 1, objv, "dictVarName key ?value ...?"); return TCL_ERROR; } @@ -2361,7 +2361,7 @@ DictForNRCmd( if (objc != 4) { Tcl_WrongNumArgs(interp, 1, objv, - "{keyVar valueVar} dictionary script"); + "{keyVarName valueVarName} dictionary script"); return TCL_ERROR; } @@ -2555,7 +2555,7 @@ DictMapNRCmd( if (objc != 4) { Tcl_WrongNumArgs(interp, 1, objv, - "{keyVar valueVar} dictionary script"); + "{keyVarName valueVarName} dictionary script"); return TCL_ERROR; } @@ -2764,7 +2764,7 @@ DictSetCmd( int result, allocatedDict = 0; if (objc < 4) { - Tcl_WrongNumArgs(interp, 1, objv, "varName key ?key ...? value"); + Tcl_WrongNumArgs(interp, 1, objv, "dictVarName key ?key ...? value"); return TCL_ERROR; } @@ -2824,7 +2824,7 @@ DictUnsetCmd( int result, allocatedDict = 0; if (objc < 3) { - Tcl_WrongNumArgs(interp, 1, objv, "varName key ?key ...?"); + Tcl_WrongNumArgs(interp, 1, objv, "dictVarName key ?key ...?"); return TCL_ERROR; } @@ -2992,7 +2992,7 @@ DictFilterCmd( case FILTER_SCRIPT: if (objc != 5) { Tcl_WrongNumArgs(interp, 1, objv, - "dictionary script {keyVar valueVar} filterScript"); + "dictionary script {keyVarName valueVarName} filterScript"); return TCL_ERROR; } @@ -3169,7 +3169,7 @@ DictUpdateCmd( if (objc < 5 || !(objc & 1)) { Tcl_WrongNumArgs(interp, 1, objv, - "varName key varName ?key varName ...? script"); + "dictVarName key varName ?key varName ...? script"); return TCL_ERROR; } @@ -3325,7 +3325,7 @@ DictWithCmd( Tcl_Obj *dictPtr, *keysPtr, *pathPtr; if (objc < 3) { - Tcl_WrongNumArgs(interp, 1, objv, "dictVar ?key ...? script"); + Tcl_WrongNumArgs(interp, 1, objv, "dictVarName ?key ...? script"); return TCL_ERROR; } diff --git a/tests/dict.test b/tests/dict.test index 642abd8..d5406d0 100644 --- a/tests/dict.test +++ b/tests/dict.test @@ -409,13 +409,13 @@ test dict-11.13 {dict incr command} -returnCodes error -body { dict incr dictv a a a } -cleanup { unset dictv -} -result {wrong # args: should be "dict incr varName key ?increment?"} +} -result {wrong # args: should be "dict incr dictVarName key ?increment?"} test dict-11.14 {dict incr command} -returnCodes error -body { set dictv a dict incr dictv } -cleanup { unset dictv -} -result {wrong # args: should be "dict incr varName key ?increment?"} +} -result {wrong # args: should be "dict incr dictVarName key ?increment?"} test dict-11.15 {dict incr command: write failure} -setup { unset -nocomplain dictVar } -body { @@ -486,10 +486,10 @@ test dict-12.6 {dict lappend command} -returnCodes error -body { } -result {missing value to go with key} test dict-12.7 {dict lappend command} -returnCodes error -body { dict lappend -} -result {wrong # args: should be "dict lappend varName key ?value ...?"} +} -result {wrong # args: should be "dict lappend dictVarName key ?value ...?"} test dict-12.8 {dict lappend command} -returnCodes error -body { dict lappend dictv -} -result {wrong # args: should be "dict lappend varName key ?value ...?"} +} -result {wrong # args: should be "dict lappend dictVarName key ?value ...?"} test dict-12.9 {dict lappend command} -returnCodes error -body { set dictv [dict create a "\{"] dict lappend dictv a a @@ -553,10 +553,10 @@ test dict-13.6 {dict append command} -returnCodes error -body { } -result {missing value to go with key} test dict-13.7 {dict append command} -returnCodes error -body { dict append -} -result {wrong # args: should be "dict append varName key ?value ...?"} +} -result {wrong # args: should be "dict append dictVarName key ?value ...?"} test dict-13.8 {dict append command} -returnCodes error -body { dict append dictv -} -result {wrong # args: should be "dict append varName key ?value ...?"} +} -result {wrong # args: should be "dict append dictVarName key ?value ...?"} test dict-13.9 {dict append command: write failure} -setup { unset -nocomplain dictVar } -body { @@ -574,16 +574,16 @@ test dict-13.11 {compiled dict append: invalidate string rep - Bug 3079830} { test dict-14.1 {dict for command: syntax} -returnCodes error -body { dict for -} -result {wrong # args: should be "dict for {keyVar valueVar} dictionary script"} +} -result {wrong # args: should be "dict for {keyVarName valueVarName} dictionary script"} test dict-14.2 {dict for command: syntax} -returnCodes error -body { dict for x -} -result {wrong # args: should be "dict for {keyVar valueVar} dictionary script"} +} -result {wrong # args: should be "dict for {keyVarName valueVarName} dictionary script"} test dict-14.3 {dict for command: syntax} -returnCodes error -body { dict for x x -} -result {wrong # args: should be "dict for {keyVar valueVar} dictionary script"} +} -result {wrong # args: should be "dict for {keyVarName valueVarName} dictionary script"} test dict-14.4 {dict for command: syntax} -returnCodes error -body { dict for x x x x -} -result {wrong # args: should be "dict for {keyVar valueVar} dictionary script"} +} -result {wrong # args: should be "dict for {keyVarName valueVarName} dictionary script"} test dict-14.5 {dict for command: syntax} -returnCodes error -body { dict for x x x } -result {must have exactly two variable names} @@ -813,13 +813,13 @@ test dict-15.9 {dict set command: write failure} -setup { } -result {can't set "dictVar": variable is array} test dict-15.10 {dict set command: syntax} -returnCodes error -body { dict set -} -result {wrong # args: should be "dict set varName key ?key ...? value"} +} -result {wrong # args: should be "dict set dictVarName key ?key ...? value"} test dict-15.11 {dict set command: syntax} -returnCodes error -body { dict set a -} -result {wrong # args: should be "dict set varName key ?key ...? value"} +} -result {wrong # args: should be "dict set dictVarName key ?key ...? value"} test dict-15.12 {dict set command: syntax} -returnCodes error -body { dict set a a -} -result {wrong # args: should be "dict set varName key ?key ...? value"} +} -result {wrong # args: should be "dict set dictVarName key ?key ...? value"} test dict-15.13 {dict set command} -returnCodes error -body { set dictVar a dict set dictVar b c @@ -872,7 +872,7 @@ test dict-16.7 {dict unset command} -setup { } -result {0 {} 1} test dict-16.8 {dict unset command} -returnCodes error -body { dict unset dictVar -} -result {wrong # args: should be "dict unset varName key ?key ...?"} +} -result {wrong # args: should be "dict unset dictVarName key ?key ...?"} test dict-16.9 {dict unset command: write failure} -setup { unset -nocomplain dictVar } -body { @@ -923,7 +923,7 @@ test dict-16.16 {dict unset command} -body { } -result {0 {} 1} test dict-16.17 {dict unset command} -returnCodes error -body { apply {{} {dict unset dictVar}} -} -result {wrong # args: should be "dict unset varName key ?key ...?"} +} -result {wrong # args: should be "dict unset dictVarName key ?key ...?"} test dict-16.18 {dict unset command: write failure} -body { apply {{} { set dictVar(block) {} @@ -1052,7 +1052,7 @@ test dict-17.17 {dict filter command: script} -body { } -result b test dict-17.18 {dict filter command: script} -returnCodes error -body { dict filter {a b} script {k k} -} -result {wrong # args: should be "dict filter dictionary script {keyVar valueVar} filterScript"} +} -result {wrong # args: should be "dict filter dictionary script {keyVarName valueVarName} filterScript"} test dict-17.19 {dict filter command: script} -returnCodes error -body { dict filter {a b} script k {continue} } -result {must have exactly two variable names} @@ -1308,16 +1308,16 @@ test dict-20.25 {dict merge command: type check is mandatory} -body { test dict-21.1 {dict update command} -returnCodes 1 -body { dict update -} -result {wrong # args: should be "dict update varName key varName ?key varName ...? script"} +} -result {wrong # args: should be "dict update dictVarName key varName ?key varName ...? script"} test dict-21.2 {dict update command} -returnCodes 1 -body { dict update v -} -result {wrong # args: should be "dict update varName key varName ?key varName ...? script"} +} -result {wrong # args: should be "dict update dictVarName key varName ?key varName ...? script"} test dict-21.3 {dict update command} -returnCodes 1 -body { dict update v k -} -result {wrong # args: should be "dict update varName key varName ?key varName ...? script"} +} -result {wrong # args: should be "dict update dictVarName key varName ?key varName ...? script"} test dict-21.4 {dict update command} -returnCodes 1 -body { dict update v k v -} -result {wrong # args: should be "dict update varName key varName ?key varName ...? script"} +} -result {wrong # args: should be "dict update dictVarName key varName ?key varName ...? script"} test dict-21.5 {dict update command} -body { set a {b c} set result {} @@ -1455,10 +1455,10 @@ test dict-21.17 {dict update command: no recursive structures [Bug 1786481]} { test dict-22.1 {dict with command} -body { dict with -} -returnCodes 1 -result {wrong # args: should be "dict with dictVar ?key ...? script"} +} -returnCodes 1 -result {wrong # args: should be "dict with dictVarName ?key ...? script"} test dict-22.2 {dict with command} -body { dict with v -} -returnCodes 1 -result {wrong # args: should be "dict with dictVar ?key ...? script"} +} -returnCodes 1 -result {wrong # args: should be "dict with dictVarName ?key ...? script"} test dict-22.3 {dict with command} -body { unset -nocomplain v dict with v {error "in body"} @@ -1718,16 +1718,16 @@ rename linenumber {} test dict-24.1 {dict map command: syntax} -returnCodes error -body { dict map -} -result {wrong # args: should be "dict map {keyVar valueVar} dictionary script"} +} -result {wrong # args: should be "dict map {keyVarName valueVarName} dictionary script"} test dict-24.2 {dict map command: syntax} -returnCodes error -body { dict map x -} -result {wrong # args: should be "dict map {keyVar valueVar} dictionary script"} +} -result {wrong # args: should be "dict map {keyVarName valueVarName} dictionary script"} test dict-24.3 {dict map command: syntax} -returnCodes error -body { dict map x x -} -result {wrong # args: should be "dict map {keyVar valueVar} dictionary script"} +} -result {wrong # args: should be "dict map {keyVarName valueVarName} dictionary script"} test dict-24.4 {dict map command: syntax} -returnCodes error -body { dict map x x x x -} -result {wrong # args: should be "dict map {keyVar valueVar} dictionary script"} +} -result {wrong # args: should be "dict map {keyVarName valueVarName} dictionary script"} test dict-24.5 {dict map command: syntax} -returnCodes error -body { dict map x x x } -result {must have exactly two variable names} -- cgit v0.12 From ab6933ef6bad77e36a80b261ffd48e2cc8d7575f Mon Sep 17 00:00:00 2001 From: dkf Date: Mon, 16 Jun 2014 09:24:39 +0000 Subject: [311e61d12a] Generate error code in *all* places where commands are looked up. --- library/init.tcl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/library/init.tcl b/library/init.tcl index f63eedf..bb17319 100644 --- a/library/init.tcl +++ b/library/init.tcl @@ -398,7 +398,8 @@ proc unknown args { return -code error "ambiguous command name \"$name\": [lsort $cmds]" } } - return -code error "invalid command name \"$name\"" + return -code error -errorcode [list TCL LOOKUP COMMAND $name] \ + "invalid command name \"$name\"" } # auto_load -- -- cgit v0.12 From 7bde9467424438f3430f9d2ece72a604f856ff43 Mon Sep 17 00:00:00 2001 From: dkf Date: Tue, 17 Jun 2014 14:30:06 +0000 Subject: [f0f876c141] Improve consistency in error messages. --- generic/tclClock.c | 6 +++--- generic/tclCmdMZ.c | 16 +++++++++------- generic/tclFCmd.c | 2 +- generic/tclIOCmd.c | 6 +++--- library/clock.tcl | 8 ++++---- tests/clock.test | 12 ++++++------ tests/exec.test | 6 +++--- tests/fCmd.test | 4 ++-- tests/ioCmd.test | 2 +- tests/regexp.test | 16 ++++++++-------- tests/regexpComp.test | 16 ++++++++-------- tests/string.test | 4 ++-- tests/subst.test | 8 ++++---- tests/switch.test | 8 ++++---- 14 files changed, 58 insertions(+), 56 deletions(-) diff --git a/generic/tclClock.c b/generic/tclClock.c index 15f29e5..7e917f6 100644 --- a/generic/tclClock.c +++ b/generic/tclClock.c @@ -1703,7 +1703,7 @@ ClockClicksObjCmd( case 1: break; case 2: - if (Tcl_GetIndexFromObj(interp, objv[1], clicksSwitches, "switch", 0, + if (Tcl_GetIndexFromObj(interp, objv[1], clicksSwitches, "option", 0, &index) != TCL_OK) { return TCL_ERROR; } @@ -1873,9 +1873,9 @@ ClockParseformatargsObjCmd( localeObj = litPtr[LIT_C]; timezoneObj = litPtr[LIT__NIL]; for (i = 2; i < objc; i+=2) { - if (Tcl_GetIndexFromObj(interp, objv[i], options, "switch", 0, + if (Tcl_GetIndexFromObj(interp, objv[i], options, "option", 0, &optionIndex) != TCL_OK) { - Tcl_SetErrorCode(interp, "CLOCK", "badSwitch", + Tcl_SetErrorCode(interp, "CLOCK", "badOption", Tcl_GetString(objv[i]), NULL); return TCL_ERROR; } diff --git a/generic/tclCmdMZ.c b/generic/tclCmdMZ.c index 00c9f2f..0f7f20a 100644 --- a/generic/tclCmdMZ.c +++ b/generic/tclCmdMZ.c @@ -161,7 +161,7 @@ Tcl_RegexpObjCmd( if (name[0] != '-') { break; } - if (Tcl_GetIndexFromObj(interp, objv[i], options, "switch", TCL_EXACT, + if (Tcl_GetIndexFromObj(interp, objv[i], options, "option", TCL_EXACT, &index) != TCL_OK) { goto optionError; } @@ -217,7 +217,7 @@ Tcl_RegexpObjCmd( endOfForLoop: if ((objc - i) < (2 - about)) { Tcl_WrongNumArgs(interp, 1, objv, - "?-switch ...? exp string ?matchVar? ?subMatchVar ...?"); + "?-option ...? exp string ?matchVar? ?subMatchVar ...?"); goto optionError; } objc -= i; @@ -231,6 +231,8 @@ Tcl_RegexpObjCmd( if (doinline && ((objc - 2) != 0)) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "regexp match variables not allowed when using -inline", -1)); + Tcl_SetErrorCode(interp, "TCL", "OPERATION", "REGEXP", + "MIX_VAR_INLINE", NULL); goto optionError; } @@ -519,7 +521,7 @@ Tcl_RegsubObjCmd( if (name[0] != '-') { break; } - if (Tcl_GetIndexFromObj(interp, objv[idx], options, "switch", + if (Tcl_GetIndexFromObj(interp, objv[idx], options, "option", TCL_EXACT, &index) != TCL_OK) { goto optionError; } @@ -566,7 +568,7 @@ Tcl_RegsubObjCmd( endOfForLoop: if (objc-idx < 3 || objc-idx > 4) { Tcl_WrongNumArgs(interp, 1, objv, - "?-switch ...? exp string subSpec ?varName?"); + "?-option ...? exp string subSpec ?varName?"); optionError: if (startIndex) { Tcl_DecrRefCount(startIndex); @@ -3391,7 +3393,7 @@ TclSubstOptions( for (i = 0; i < numOpts; i++) { int optionIndex; - if (Tcl_GetIndexFromObj(interp, opts[i], substOptions, "switch", 0, + if (Tcl_GetIndexFromObj(interp, opts[i], substOptions, "option", 0, &optionIndex) != TCL_OK) { return TCL_ERROR; } @@ -3591,7 +3593,7 @@ TclNRSwitchObjCmd( finishedOptions: if (objc - i < 2) { Tcl_WrongNumArgs(interp, 1, objv, - "?-switch ...? string ?pattern body ...? ?default body?"); + "?-option ...? string ?pattern body ...? ?default body?"); return TCL_ERROR; } if (indexVarObj != NULL && mode != OPT_REGEXP) { @@ -3638,7 +3640,7 @@ TclNRSwitchObjCmd( if (objc < 1) { Tcl_WrongNumArgs(interp, 1, savedObjv, - "?-switch ...? string {?pattern body ...? ?default body?}"); + "?-option ...? string {?pattern body ...? ?default body?}"); return TCL_ERROR; } objv = listv; diff --git a/generic/tclFCmd.c b/generic/tclFCmd.c index 6452fff..8bf0a5a 100644 --- a/generic/tclFCmd.c +++ b/generic/tclFCmd.c @@ -1196,7 +1196,7 @@ TclFileLinkCmd( static const char *const linkTypes[] = { "-symbolic", "-hard", NULL }; - if (Tcl_GetIndexFromObj(interp, objv[1], linkTypes, "switch", 0, + if (Tcl_GetIndexFromObj(interp, objv[1], linkTypes, "option", 0, &linkAction) != TCL_OK) { return TCL_ERROR; } diff --git a/generic/tclIOCmd.c b/generic/tclIOCmd.c index 084cefb..3368a76 100644 --- a/generic/tclIOCmd.c +++ b/generic/tclIOCmd.c @@ -919,7 +919,7 @@ Tcl_ExecObjCmd( if (string[0] != '-') { break; } - if (Tcl_GetIndexFromObj(interp, objv[skip], options, "switch", + if (Tcl_GetIndexFromObj(interp, objv[skip], options, "option", TCL_EXACT, &index) != TCL_OK) { return TCL_ERROR; } @@ -933,7 +933,7 @@ Tcl_ExecObjCmd( } } if (objc <= skip) { - Tcl_WrongNumArgs(interp, 1, objv, "?-switch ...? arg ?arg ...?"); + Tcl_WrongNumArgs(interp, 1, objv, "?-option ...? arg ?arg ...?"); return TCL_ERROR; } @@ -1696,7 +1696,7 @@ Tcl_FcopyObjCmd( toRead = -1; cmdPtr = NULL; for (i = 3; i < objc; i += 2) { - if (Tcl_GetIndexFromObj(interp, objv[i], switches, "switch", 0, + if (Tcl_GetIndexFromObj(interp, objv[i], switches, "option", 0, &index) != TCL_OK) { return TCL_ERROR; } diff --git a/library/clock.tcl b/library/clock.tcl index 1e652b4..67d15b1 100644 --- a/library/clock.tcl +++ b/library/clock.tcl @@ -1227,8 +1227,8 @@ proc ::tcl::clock::scan { args } { } default { return -code error \ - -errorcode [list CLOCK badSwitch $flag] \ - "bad switch \"$flag\",\ + -errorcode [list CLOCK badOption $flag] \ + "bad option \"$flag\",\ must be -base, -format, -gmt, -locale or -timezone" } } @@ -4295,8 +4295,8 @@ proc ::tcl::clock::add { clockval args } { set timezone $b } default { - throw [list CLOCK badSwitch $a] \ - "bad switch \"$a\",\ + throw [list CLOCK badOption $a] \ + "bad option \"$a\",\ must be -gmt, -locale or -timezone" } } diff --git a/tests/clock.test b/tests/clock.test index 8debba1..2abeab9 100644 --- a/tests/clock.test +++ b/tests/clock.test @@ -273,7 +273,7 @@ test clock-1.4 "clock format - bad flag" {*}{ list [catch {clock format 0 -oops badflag} msg] $msg $::errorCode } -match glob - -result {1 {bad switch "-oops": must be -format, -gmt, -locale, or -timezone} {CLOCK badSwitch -oops}} + -result {1 {bad option "-oops": must be -format, -gmt, -locale, or -timezone} {CLOCK badOption -oops}} } test clock-1.5 "clock format - bad timezone" { @@ -35450,7 +35450,7 @@ test clock-33.2 {clock clicks tests} { } {1} test clock-33.3 {clock clicks tests} { list [catch {clock clicks foo} msg] $msg -} {1 {bad switch "foo": must be -milliseconds or -microseconds}} +} {1 {bad option "foo": must be -milliseconds or -microseconds}} test clock-33.4 {clock clicks tests} { expr [clock clicks -milliseconds]+1 concat {} @@ -35485,10 +35485,10 @@ test clock-33.5a {clock tests, millisecond timing test} { } {ok} test clock-33.6 {clock clicks, milli with too much abbreviation} { list [catch { clock clicks ? } msg] $msg -} {1 {bad switch "?": must be -milliseconds or -microseconds}} +} {1 {bad option "?": must be -milliseconds or -microseconds}} test clock-33.7 {clock clicks, milli with too much abbreviation} { list [catch { clock clicks - } msg] $msg -} {1 {ambiguous switch "-": must be -milliseconds or -microseconds}} +} {1 {ambiguous option "-": must be -milliseconds or -microseconds}} test clock-33.8 {clock clicks test, microsecond timing test} { # This test can fail on a system that is so heavily loaded that @@ -35607,7 +35607,7 @@ test clock-34.8 {clock scan tests} { } {Oct 23,1992 15:00 GMT} test clock-34.9 {clock scan tests} { list [catch {clock scan "Jan 12" -bad arg} msg] $msg -} {1 {bad switch "-bad", must be -base, -format, -gmt, -locale or -timezone}} +} {1 {bad option "-bad", must be -base, -format, -gmt, -locale or -timezone}} # The following two two tests test the two year date policy test clock-34.10 {clock scan tests} { set time [clock scan "1/1/71" -gmt true] @@ -36907,7 +36907,7 @@ test clock-65.1 {clock add, bad option [Bug 2481670]} {*}{ } -match glob -returnCodes error - -result {bad switch "-foo"*} + -result {bad option "-foo"*} } test clock-66.1 {clock scan, no date, never-before-seen timezone} {*}{ diff --git a/tests/exec.test b/tests/exec.test index 871c0c5..16a8320 100644 --- a/tests/exec.test +++ b/tests/exec.test @@ -370,7 +370,7 @@ err} test exec-10.1 {errors in exec invocation} -constraints {exec} -body { exec -} -returnCodes error -result {wrong # args: should be "exec ?-switch ...? arg ?arg ...?"} +} -returnCodes error -result {wrong # args: should be "exec ?-option ...? arg ?arg ...?"} test exec-10.2 {errors in exec invocation} -constraints {exec} -body { exec | cat } -returnCodes error -result {illegal use of | or |& in command} @@ -545,10 +545,10 @@ test exec-14.1 {-keepnewline switch} {exec} { } "foo\n" test exec-14.2 {-keepnewline switch} -constraints {exec} -body { exec -keepnewline -} -returnCodes error -result {wrong # args: should be "exec ?-switch ...? arg ?arg ...?"} +} -returnCodes error -result {wrong # args: should be "exec ?-option ...? arg ?arg ...?"} test exec-14.3 {unknown switch} -constraints {exec} -body { exec -gorp -} -returnCodes error -result {bad switch "-gorp": must be -ignorestderr, -keepnewline, or --} +} -returnCodes error -result {bad option "-gorp": must be -ignorestderr, -keepnewline, or --} test exec-14.4 {-- switch} -constraints {exec} -body { exec -- -gorp } -returnCodes error -result {couldn't execute "-gorp": no such file or directory} diff --git a/tests/fCmd.test b/tests/fCmd.test index 3d22b09..5836e00 100644 --- a/tests/fCmd.test +++ b/tests/fCmd.test @@ -2324,10 +2324,10 @@ test fCmd-28.2 {file link} -returnCodes error -body { } -result {wrong # args: should be "file link ?-linktype? linkname ?target?"} test fCmd-28.3 {file link} -returnCodes error -body { file link abc b c -} -result {bad switch "abc": must be -symbolic or -hard} +} -result {bad option "abc": must be -symbolic or -hard} test fCmd-28.4 {file link} -returnCodes error -body { file link -abc b c -} -result {bad switch "-abc": must be -symbolic or -hard} +} -result {bad option "-abc": must be -symbolic or -hard} cd [workingDirectory] makeDirectory abc.dir makeDirectory abc2.dir diff --git a/tests/ioCmd.test b/tests/ioCmd.test index ff93719..8d35ec7 100644 --- a/tests/ioCmd.test +++ b/tests/ioCmd.test @@ -639,7 +639,7 @@ test iocmd-15.9 {Tcl_FcopyObjCmd} {fcopy} { } "1 {channel \"$rfile\" wasn't opened for writing}" test iocmd-15.10 {Tcl_FcopyObjCmd} {fcopy} { list [catch {fcopy $rfile $wfile foo bar} msg] $msg -} {1 {bad switch "foo": must be -size or -command}} +} {1 {bad option "foo": must be -size or -command}} test iocmd-15.11 {Tcl_FcopyObjCmd} {fcopy} { list [catch {fcopy $rfile $wfile -size foo} msg] $msg } {1 {expected integer but got "foo"}} diff --git a/tests/regexp.test b/tests/regexp.test index 1b2bec9..a83c99b 100644 --- a/tests/regexp.test +++ b/tests/regexp.test @@ -241,13 +241,13 @@ test regexp-5.5 {exercise cache of compiled expressions} { test regexp-6.1 {regexp errors} { list [catch {regexp a} msg] $msg -} {1 {wrong # args: should be "regexp ?-switch ...? exp string ?matchVar? ?subMatchVar ...?"}} +} {1 {wrong # args: should be "regexp ?-option ...? exp string ?matchVar? ?subMatchVar ...?"}} test regexp-6.2 {regexp errors} { list [catch {regexp -nocase a} msg] $msg -} {1 {wrong # args: should be "regexp ?-switch ...? exp string ?matchVar? ?subMatchVar ...?"}} +} {1 {wrong # args: should be "regexp ?-option ...? exp string ?matchVar? ?subMatchVar ...?"}} test regexp-6.3 {regexp errors} { list [catch {regexp -gorp a} msg] $msg -} {1 {bad switch "-gorp": must be -all, -about, -indices, -inline, -expanded, -line, -linestop, -lineanchor, -nocase, -start, or --}} +} {1 {bad option "-gorp": must be -all, -about, -indices, -inline, -expanded, -line, -linestop, -lineanchor, -nocase, -start, or --}} test regexp-6.4 {regexp errors} { list [catch {regexp a( b} msg] $msg } {1 {couldn't compile regular expression pattern: parentheses () not balanced}} @@ -441,19 +441,19 @@ test regexp-10.5 {inverse partial newline sensitivity in regsub} { test regexp-11.1 {regsub errors} { list [catch {regsub a b} msg] $msg -} {1 {wrong # args: should be "regsub ?-switch ...? exp string subSpec ?varName?"}} +} {1 {wrong # args: should be "regsub ?-option ...? exp string subSpec ?varName?"}} test regexp-11.2 {regsub errors} { list [catch {regsub -nocase a b} msg] $msg -} {1 {wrong # args: should be "regsub ?-switch ...? exp string subSpec ?varName?"}} +} {1 {wrong # args: should be "regsub ?-option ...? exp string subSpec ?varName?"}} test regexp-11.3 {regsub errors} { list [catch {regsub -nocase -all a b} msg] $msg -} {1 {wrong # args: should be "regsub ?-switch ...? exp string subSpec ?varName?"}} +} {1 {wrong # args: should be "regsub ?-option ...? exp string subSpec ?varName?"}} test regexp-11.4 {regsub errors} { list [catch {regsub a b c d e f} msg] $msg -} {1 {wrong # args: should be "regsub ?-switch ...? exp string subSpec ?varName?"}} +} {1 {wrong # args: should be "regsub ?-option ...? exp string subSpec ?varName?"}} test regexp-11.5 {regsub errors} { list [catch {regsub -gorp a b c} msg] $msg -} {1 {bad switch "-gorp": must be -all, -nocase, -expanded, -line, -linestop, -lineanchor, -start, or --}} +} {1 {bad option "-gorp": must be -all, -nocase, -expanded, -line, -linestop, -lineanchor, -start, or --}} test regexp-11.6 {regsub errors} { list [catch {regsub -nocase a( b c d} msg] $msg } {1 {couldn't compile regular expression pattern: parentheses () not balanced}} diff --git a/tests/regexpComp.test b/tests/regexpComp.test index 94fb90e..7be1195 100644 --- a/tests/regexpComp.test +++ b/tests/regexpComp.test @@ -316,17 +316,17 @@ test regexpComp-6.1 {regexp errors} { evalInProc { list [catch {regexp a} msg] $msg } -} {1 {wrong # args: should be "regexp ?-switch ...? exp string ?matchVar? ?subMatchVar ...?"}} +} {1 {wrong # args: should be "regexp ?-option ...? exp string ?matchVar? ?subMatchVar ...?"}} test regexpComp-6.2 {regexp errors} { evalInProc { list [catch {regexp -nocase a} msg] $msg } -} {1 {wrong # args: should be "regexp ?-switch ...? exp string ?matchVar? ?subMatchVar ...?"}} +} {1 {wrong # args: should be "regexp ?-option ...? exp string ?matchVar? ?subMatchVar ...?"}} test regexpComp-6.3 {regexp errors} { evalInProc { list [catch {regexp -gorp a} msg] $msg } -} {1 {bad switch "-gorp": must be -all, -about, -indices, -inline, -expanded, -line, -linestop, -lineanchor, -nocase, -start, or --}} +} {1 {bad option "-gorp": must be -all, -about, -indices, -inline, -expanded, -line, -linestop, -lineanchor, -nocase, -start, or --}} test regexpComp-6.4 {regexp errors} { evalInProc { list [catch {regexp a( b} msg] $msg @@ -562,27 +562,27 @@ test regexpComp-11.1 {regsub errors} { evalInProc { list [catch {regsub a b} msg] $msg } -} {1 {wrong # args: should be "regsub ?-switch ...? exp string subSpec ?varName?"}} +} {1 {wrong # args: should be "regsub ?-option ...? exp string subSpec ?varName?"}} test regexpComp-11.2 {regsub errors} { evalInProc { list [catch {regsub -nocase a b} msg] $msg } -} {1 {wrong # args: should be "regsub ?-switch ...? exp string subSpec ?varName?"}} +} {1 {wrong # args: should be "regsub ?-option ...? exp string subSpec ?varName?"}} test regexpComp-11.3 {regsub errors} { evalInProc { list [catch {regsub -nocase -all a b} msg] $msg } -} {1 {wrong # args: should be "regsub ?-switch ...? exp string subSpec ?varName?"}} +} {1 {wrong # args: should be "regsub ?-option ...? exp string subSpec ?varName?"}} test regexpComp-11.4 {regsub errors} { evalInProc { list [catch {regsub a b c d e f} msg] $msg } -} {1 {wrong # args: should be "regsub ?-switch ...? exp string subSpec ?varName?"}} +} {1 {wrong # args: should be "regsub ?-option ...? exp string subSpec ?varName?"}} test regexpComp-11.5 {regsub errors} { evalInProc { list [catch {regsub -gorp a b c} msg] $msg } -} {1 {bad switch "-gorp": must be -all, -nocase, -expanded, -line, -linestop, -lineanchor, -start, or --}} +} {1 {bad option "-gorp": must be -all, -nocase, -expanded, -line, -linestop, -lineanchor, -start, or --}} test regexpComp-11.6 {regsub errors} { evalInProc { list [catch {regsub -nocase a( b c d} msg] $msg diff --git a/tests/string.test b/tests/string.test index cf658a2..a8a83d9 100644 --- a/tests/string.test +++ b/tests/string.test @@ -1801,8 +1801,8 @@ test string-26.7 {tcl::prefix} -body { tcl::prefix match -exact {apa bepa cepa depa} be } -returnCodes 1 -result {bad option "be": must be apa, bepa, cepa, or depa} test string-26.8 {tcl::prefix} -body { - tcl::prefix match -message switch {apa bepa bear depa} be -} -returnCodes 1 -result {ambiguous switch "be": must be apa, bepa, bear, or depa} + tcl::prefix match -message wombat {apa bepa bear depa} be +} -returnCodes 1 -result {ambiguous wombat "be": must be apa, bepa, bear, or depa} test string-26.9 {tcl::prefix} -body { tcl::prefix match -error {} {apa bepa bear depa} be } -returnCodes 0 -result {} diff --git a/tests/subst.test b/tests/subst.test index 7466895..498512d 100644 --- a/tests/subst.test +++ b/tests/subst.test @@ -21,7 +21,7 @@ test subst-1.1 {basics} -returnCodes error -body { } -result {wrong # args: should be "subst ?-nobackslashes? ?-nocommands? ?-novariables? string"} test subst-1.2 {basics} -returnCodes error -body { subst a b c -} -result {bad switch "a": must be -nobackslashes, -nocommands, or -novariables} +} -result {bad option "a": must be -nobackslashes, -nocommands, or -novariables} test subst-2.1 {simple strings} { subst {} @@ -119,13 +119,13 @@ test subst-6.1 {clear the result after command substitution} -body { test subst-7.1 {switches} -returnCodes error -body { subst foo bar -} -result {bad switch "foo": must be -nobackslashes, -nocommands, or -novariables} +} -result {bad option "foo": must be -nobackslashes, -nocommands, or -novariables} test subst-7.2 {switches} -returnCodes error -body { subst -no bar -} -result {ambiguous switch "-no": must be -nobackslashes, -nocommands, or -novariables} +} -result {ambiguous option "-no": must be -nobackslashes, -nocommands, or -novariables} test subst-7.3 {switches} -returnCodes error -body { subst -bogus bar -} -result {bad switch "-bogus": must be -nobackslashes, -nocommands, or -novariables} +} -result {bad option "-bogus": must be -nobackslashes, -nocommands, or -novariables} test subst-7.4 {switches} { set x 123 subst -nobackslashes {abc $x [expr 1+2] \\\x41} diff --git a/tests/switch.test b/tests/switch.test index a03948b..4d204bb 100644 --- a/tests/switch.test +++ b/tests/switch.test @@ -169,7 +169,7 @@ test switch-4.1 {error in executed command} { "switch a a {error "Just a test"} default {subst 1}"}} test switch-4.2 {error: not enough args} -returnCodes error -body { switch -} -result {wrong # args: should be "switch ?-switch ...? string ?pattern body ...? ?default body?"} +} -result {wrong # args: should be "switch ?-option ...? string ?pattern body ...? ?default body?"} test switch-4.3 {error: pattern with no body} -body { switch a b } -returnCodes error -result {extra switch pattern with no body} @@ -269,16 +269,16 @@ test switch-8.3 {weird body text, variable} { test switch-9.1 {empty pattern/body list} -returnCodes error -body { switch x -} -result {wrong # args: should be "switch ?-switch ...? string ?pattern body ...? ?default body?"} +} -result {wrong # args: should be "switch ?-option ...? string ?pattern body ...? ?default body?"} test switch-9.2 {unpaired pattern} -returnCodes error -body { switch -- x } -result {extra switch pattern with no body} test switch-9.3 {empty pattern/body list} -body { switch x {} -} -returnCodes error -result {wrong # args: should be "switch ?-switch ...? string {?pattern body ...? ?default body?}"} +} -returnCodes error -result {wrong # args: should be "switch ?-option ...? string {?pattern body ...? ?default body?}"} test switch-9.4 {empty pattern/body list} -body { switch -- x {} -} -returnCodes error -result {wrong # args: should be "switch ?-switch ...? string {?pattern body ...? ?default body?}"} +} -returnCodes error -result {wrong # args: should be "switch ?-option ...? string {?pattern body ...? ?default body?}"} test switch-9.5 {unpaired pattern} -body { switch x a {} b } -returnCodes error -result {extra switch pattern with no body} -- cgit v0.12 From 7834f2fe96420221f0b47ff335972fa7850d7554 Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 19 Jun 2014 16:38:33 +0000 Subject: [b47b176adf] Stop segfault when variability in mutex lock schedules cause a ForwardingResult to remain on the forwardList after it has been processed. --- generic/tclIORTrans.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/generic/tclIORTrans.c b/generic/tclIORTrans.c index e6e552f..d2707a1 100644 --- a/generic/tclIORTrans.c +++ b/generic/tclIORTrans.c @@ -2225,6 +2225,9 @@ DeleteReflectedTransformMap( */ evPtr = resultPtr->evPtr; + if (evPtr == NULL) { + continue; + } paramPtr = evPtr->param; evPtr->resultPtr = NULL; @@ -2350,6 +2353,9 @@ DeleteThreadReflectedTransformMap( */ evPtr = resultPtr->evPtr; + if (evPtr == NULL) { + continue; + } paramPtr = evPtr->param; evPtr->resultPtr = NULL; -- cgit v0.12 From f326f97897cf1deebbeb48e3f4298afb4f2e53d7 Mon Sep 17 00:00:00 2001 From: aku Date: Fri, 20 Jun 2014 05:05:21 +0000 Subject: [b47b176adf] Stop possible segfaults when variability in mutex lock schedules cause a ForwardingResult to remain on the forwardList after it has been processed (IORChan is the origin of the code in IORTrans). --- generic/tclIORChan.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/generic/tclIORChan.c b/generic/tclIORChan.c index 3107f9e..e1bd6e1 100644 --- a/generic/tclIORChan.c +++ b/generic/tclIORChan.c @@ -2384,10 +2384,18 @@ DeleteReflectedChannelMap( /* * The receiver for the event exited, before processing the event. We * detach the result now, wake the originator up and signal failure. + * + * Attention: Results may have been detached already, by either the + * receiver, or this thread, as part of other parts in the thread + * teardown. Such results are ignored. See ticket [b47b176adf] for the + * identical race condition in Tcl 8.6 IORTrans. */ evPtr = resultPtr->evPtr; paramPtr = evPtr->param; + if (!evPtr) { + continue; + } evPtr->resultPtr = NULL; resultPtr->evPtr = NULL; @@ -2515,10 +2523,18 @@ DeleteThreadReflectedChannelMap( /* * The receiver for the event exited, before processing the event. We * detach the result now, wake the originator up and signal failure. + * + * Attention: Results may have been detached already, by either the + * receiver, or this thread, as part of other parts in the thread + * teardown. Such results are ignored. See ticket [b47b176adf] for the + * identical race condition in Tcl 8.6 IORTrans. */ evPtr = resultPtr->evPtr; paramPtr = evPtr->param; + if (!evPtr) { + continue; + } evPtr->resultPtr = NULL; resultPtr->evPtr = NULL; -- cgit v0.12 From 24b0f264c3d39f99abfaeb34757ccc32e093ff61 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Fri, 20 Jun 2014 20:21:50 +0000 Subject: ticket [2f9df4c4fa]: tcltest - request to move -cleanup script execution until after -output compare --- library/tcltest/pkgIndex.tcl | 2 +- library/tcltest/tcltest.tcl | 14 +++++++------- unix/Makefile.in | 4 ++-- win/Makefile.in | 4 ++-- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/library/tcltest/pkgIndex.tcl b/library/tcltest/pkgIndex.tcl index c99ad2a..987725f 100644 --- a/library/tcltest/pkgIndex.tcl +++ b/library/tcltest/pkgIndex.tcl @@ -9,4 +9,4 @@ # full path name of this file's directory. if {![package vsatisfies [package provide Tcl] 8.5]} {return} -package ifneeded tcltest 2.3.7 [list source [file join $dir tcltest.tcl]] +package ifneeded tcltest 2.3.8 [list source [file join $dir tcltest.tcl]] diff --git a/library/tcltest/tcltest.tcl b/library/tcltest/tcltest.tcl index 4b94312..7dd969b 100644 --- a/library/tcltest/tcltest.tcl +++ b/library/tcltest/tcltest.tcl @@ -22,7 +22,7 @@ namespace eval tcltest { # When the version number changes, be sure to update the pkgIndex.tcl file, # and the install directory in the Makefiles. When the minor version # changes (new feature) be sure to update the man page as well. - variable Version 2.3.7 + variable Version 2.3.8 # Compatibility support for dumb variables defined in tcltest 1 # Do not use these. Call [package provide Tcl] and [info patchlevel] @@ -1991,6 +1991,12 @@ proc tcltest::test {name description args} { } } + # check if the return code matched the expected return code + set codeFailure 0 + if {!$setupFailure && ($returnCode ni $returnCodes)} { + set codeFailure 1 + } + # Always run the cleanup script set code [catch {uplevel 1 $cleanup} cleanupMsg] if {$code == 1} { @@ -2032,12 +2038,6 @@ proc tcltest::test {name description args} { } } - # check if the return code matched the expected return code - set codeFailure 0 - if {!$setupFailure && ($returnCode ni $returnCodes)} { - set codeFailure 1 - } - # If expected output/error strings exist, we have to compare # them. If the comparison fails, then so did the test. set outputFailure 0 diff --git a/unix/Makefile.in b/unix/Makefile.in index 746abde..1738570 100644 --- a/unix/Makefile.in +++ b/unix/Makefile.in @@ -785,8 +785,8 @@ install-libraries: libraries $(INSTALL_TZDATA) install-msgs done; @echo "Installing package msgcat 1.5.2 as a Tcl Module"; @$(INSTALL_DATA) $(TOP_DIR)/library/msgcat/msgcat.tcl "$(SCRIPT_INSTALL_DIR)"/../tcl8/8.5/msgcat-1.5.2.tm; - @echo "Installing package tcltest 2.3.7 as a Tcl Module"; - @$(INSTALL_DATA) $(TOP_DIR)/library/tcltest/tcltest.tcl "$(SCRIPT_INSTALL_DIR)"/../tcl8/8.5/tcltest-2.3.7.tm; + @echo "Installing package tcltest 2.3.8 as a Tcl Module"; + @$(INSTALL_DATA) $(TOP_DIR)/library/tcltest/tcltest.tcl "$(SCRIPT_INSTALL_DIR)"/../tcl8/8.5/tcltest-2.3.8.tm; @echo "Installing package platform 1.0.12 as a Tcl Module"; @$(INSTALL_DATA) $(TOP_DIR)/library/platform/platform.tcl "$(SCRIPT_INSTALL_DIR)"/../tcl8/8.4/platform-1.0.12.tm; diff --git a/win/Makefile.in b/win/Makefile.in index b962fb4..a80d2fa 100644 --- a/win/Makefile.in +++ b/win/Makefile.in @@ -651,8 +651,8 @@ install-libraries: libraries install-tzdata install-msgs done; @echo "Installing package msgcat 1.5.2 as a Tcl Module"; @$(COPY) $(ROOT_DIR)/library/msgcat/msgcat.tcl $(SCRIPT_INSTALL_DIR)/../tcl8/8.5/msgcat-1.5.2.tm; - @echo "Installing package tcltest 2.3.7 as a Tcl Module"; - @$(COPY) $(ROOT_DIR)/library/tcltest/tcltest.tcl $(SCRIPT_INSTALL_DIR)/../tcl8/8.5/tcltest-2.3.7.tm; + @echo "Installing package tcltest 2.3.8 as a Tcl Module"; + @$(COPY) $(ROOT_DIR)/library/tcltest/tcltest.tcl $(SCRIPT_INSTALL_DIR)/../tcl8/8.5/tcltest-2.3.8.tm; @echo "Installing package platform 1.0.12 as a Tcl Module"; @$(COPY) $(ROOT_DIR)/library/platform/platform.tcl $(SCRIPT_INSTALL_DIR)/../tcl8/8.4/platform-1.0.12.tm; @echo "Installing package platform::shell 1.1.4 as a Tcl Module"; -- cgit v0.12 From efcc2252599e8e2e97a97a4c1d28b138ac31e520 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Fri, 20 Jun 2014 20:50:48 +0000 Subject: previous commit was not quite right, this one should be better --- library/tcltest/tcltest.tcl | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/library/tcltest/tcltest.tcl b/library/tcltest/tcltest.tcl index 7dd969b..22d79e1 100644 --- a/library/tcltest/tcltest.tcl +++ b/library/tcltest/tcltest.tcl @@ -1991,20 +1991,6 @@ proc tcltest::test {name description args} { } } - # check if the return code matched the expected return code - set codeFailure 0 - if {!$setupFailure && ($returnCode ni $returnCodes)} { - set codeFailure 1 - } - - # Always run the cleanup script - set code [catch {uplevel 1 $cleanup} cleanupMsg] - if {$code == 1} { - set errorInfo(cleanup) $::errorInfo - set errorCode(cleanup) $::errorCode - } - set cleanupFailure [expr {$code != 0}] - set coreFailure 0 set coreMsg "" # check for a core file first - if one was created by the test, @@ -2038,6 +2024,12 @@ proc tcltest::test {name description args} { } } + # check if the return code matched the expected return code + set codeFailure 0 + if {!$setupFailure && ($returnCode ni $returnCodes)} { + set codeFailure 1 + } + # If expected output/error strings exist, we have to compare # them. If the comparison fails, then so did the test. set outputFailure 0 @@ -2076,6 +2068,14 @@ proc tcltest::test {name description args} { set scriptFailure 1 } + # Always run the cleanup script + set code [catch {uplevel 1 $cleanup} cleanupMsg] + if {$code == 1} { + set errorInfo(cleanup) $::errorInfo + set errorCode(cleanup) $::errorCode + } + set cleanupFailure [expr {$code != 0}] + # if we didn't experience any failures, then we passed variable numTests if {!($setupFailure || $cleanupFailure || $coreFailure -- cgit v0.12 From 6ab9c80ea142f1f6683b2c3eb62f6572fbe211f0 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Mon, 23 Jun 2014 12:48:16 +0000 Subject: Fix execute-6.5 test failure on trunk: the "preserveCore" part of tcltest::test assumes that the cleanup is done first, so moving the cleanup means the the "preserverCore" part needs to move with it. --- library/tcltest/tcltest.tcl | 66 ++++++++++++++++++++++----------------------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/library/tcltest/tcltest.tcl b/library/tcltest/tcltest.tcl index 22d79e1..8e43859 100644 --- a/library/tcltest/tcltest.tcl +++ b/library/tcltest/tcltest.tcl @@ -1991,39 +1991,6 @@ proc tcltest::test {name description args} { } } - set coreFailure 0 - set coreMsg "" - # check for a core file first - if one was created by the test, - # then the test failed - if {[preserveCore]} { - if {[file exists [file join [workingDirectory] core]]} { - # There's only a test failure if there is a core file - # and (1) there previously wasn't one or (2) the new - # one is different from the old one. - if {[info exists coreModTime]} { - if {$coreModTime != [file mtime \ - [file join [workingDirectory] core]]} { - set coreFailure 1 - } - } else { - set coreFailure 1 - } - - if {([preserveCore] > 1) && ($coreFailure)} { - append coreMsg "\nMoving file to:\ - [file join [temporaryDirectory] core-$name]" - catch {file rename -force -- \ - [file join [workingDirectory] core] \ - [file join [temporaryDirectory] core-$name] - } msg - if {$msg ne {}} { - append coreMsg "\nError:\ - Problem renaming core file: $msg" - } - } - } - } - # check if the return code matched the expected return code set codeFailure 0 if {!$setupFailure && ($returnCode ni $returnCodes)} { @@ -2076,6 +2043,39 @@ proc tcltest::test {name description args} { } set cleanupFailure [expr {$code != 0}] + set coreFailure 0 + set coreMsg "" + # check for a core file first - if one was created by the test, + # then the test failed + if {[preserveCore]} { + if {[file exists [file join [workingDirectory] core]]} { + # There's only a test failure if there is a core file + # and (1) there previously wasn't one or (2) the new + # one is different from the old one. + if {[info exists coreModTime]} { + if {$coreModTime != [file mtime \ + [file join [workingDirectory] core]]} { + set coreFailure 1 + } + } else { + set coreFailure 1 + } + + if {([preserveCore] > 1) && ($coreFailure)} { + append coreMsg "\nMoving file to:\ + [file join [temporaryDirectory] core-$name]" + catch {file rename -force -- \ + [file join [workingDirectory] core] \ + [file join [temporaryDirectory] core-$name] + } msg + if {$msg ne {}} { + append coreMsg "\nError:\ + Problem renaming core file: $msg" + } + } + } + } + # if we didn't experience any failures, then we passed variable numTests if {!($setupFailure || $cleanupFailure || $coreFailure -- cgit v0.12 From ddeb3ab35c7dbc8cb9219a99b6f1804c7e955179 Mon Sep 17 00:00:00 2001 From: dgp Date: Tue, 24 Jun 2014 16:34:05 +0000 Subject: Simplify / refactor Tcl_ReadRaw(). No need for CopyBuffer(). --- generic/tclIO.c | 177 ++++++++++++++++---------------------------------------- 1 file changed, 50 insertions(+), 127 deletions(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index 308e7a9..c2a705c 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -178,7 +178,6 @@ static void CleanupChannelHandlers(Tcl_Interp *interp, static int CloseChannel(Tcl_Interp *interp, Channel *chanPtr, int errorCode); static void CommonGetsCleanup(Channel *chanPtr); -static int CopyBuffer(Channel *chanPtr, char *result, int space); static int CopyData(CopyState *csPtr, int mask); static void CopyEventProc(ClientData clientData, int mask); static void CreateScriptRecord(Tcl_Interp *interp, @@ -4983,63 +4982,77 @@ Tcl_Read( int Tcl_ReadRaw( Tcl_Channel chan, /* The channel from which to read. */ - char *bufPtr, /* Where to store input read. */ + char *readBuf, /* Where to store input read. */ int bytesToRead) /* Maximum number of bytes to read. */ { Channel *chanPtr = (Channel *) chan; ChannelState *statePtr = chanPtr->state; /* State info for channel */ - int nread, copied, copiedNow = INT_MAX; - - /* - * The check below does too much because it will reject a call to this - * function with a channel which is part of an 'fcopy'. But we have to - * allow this here or else the chaining in the transformation drivers will - * fail with 'file busy' error instead of retrieving and transforming the - * data to copy. - * - * We let the check procedure now believe that there is no fcopy in - * progress. A better solution than this might be an additional flag - * argument to switch off specific checks. - */ + int copied = 0; if (CheckChannelErrors(statePtr, TCL_READABLE | CHANNEL_RAW_MODE) != 0) { return -1; } - /* - * Check for information in the push-back buffers. If there is some, use - * it. Go to the driver only if there is none (anymore) and the caller - * requests more bytes. - */ + /* First read bytes from the push-back buffers. */ - Tcl_Preserve(chanPtr); - for (copied = 0; bytesToRead > 0 && copiedNow > 0; - bufPtr+=copiedNow, bytesToRead-=copiedNow, copied+=copiedNow) { - copiedNow = CopyBuffer(chanPtr, bufPtr, bytesToRead); + while (chanPtr->inQueueHead && bytesToRead > 0) { + ChannelBuffer *bufPtr = chanPtr->inQueueHead; + int bytesInBuffer = BytesLeft(bufPtr); + int toCopy = (bytesInBuffer < bytesToRead) ? bytesInBuffer + : bytesToRead; + + /* Copy the current chunk into the read buffer. */ + + memcpy(readBuf, RemovePoint(bufPtr), (size_t) toCopy); + bufPtr->nextRemoved += toCopy; + copied += toCopy; + readBuf += toCopy; + bytesToRead -= toCopy; + + /* If the current buffer is empty recycle it. */ + + if (IsBufferEmpty(bufPtr)) { + chanPtr->inQueueHead = bufPtr->nextPtr; + if (chanPtr->inQueueHead == NULL) { + chanPtr->inQueueTail = NULL; + } + RecycleBuffer(chanPtr->state, bufPtr, 0); + } } + /* Go to the driver if more data needed. */ + if (bytesToRead > 0) { - /* - * Now go to the driver to get as much as is possible to - * fill the remaining request. Since we're directly filling - * the caller's buffer, retain the blocked flag. - */ - nread = ChanRead(chanPtr, bufPtr, bytesToRead); - if (nread < 0) { + int nread = ChanRead(chanPtr, readBuf+copied, bytesToRead); + + if (nread > 0) { + /* Successful read (short is OK) - add to bytes copied */ + copied += nread; + } else if (nread < 0) { + /* + * An error signaled. If CHANNEL_BLOCKED, then the error + * is not real, but an indication of blocked state. In + * that case, retain the flag and let caller receive the + * short read of copied bytes from the pushback. + * HOWEVER, if copied==0 bytes from pushback then repeat + * signalling the blocked state as an error to caller so + * there is no false report of an EOF. + * When !CHANNEL_BLOCKED, the error is real and passes on + * to caller. + */ if (!GotFlag(statePtr, CHANNEL_BLOCKED) || copied == 0) { copied = -1; } - } else { - copied += nread; - } - if (copied != 0) { + } else if (copied > 0) { + /* + * nread == 0. Driver is at EOF, but if copied>0 bytes + * from pushback, then we should not signal it yet. + */ ResetFlag(statePtr, CHANNEL_EOF); } } - - Tcl_Release(chanPtr); return copied; } @@ -8941,96 +8954,6 @@ DoRead( /* *---------------------------------------------------------------------- * - * CopyBuffer -- - * - * Copy at most one buffer of input to the result space. - * - * Results: - * Number of bytes stored in the result buffer. May return zero if no - * input is available. - * - * Side effects: - * Consumes buffered input. May deallocate one buffer. - * - *---------------------------------------------------------------------- - */ - -static int -CopyBuffer( - Channel *chanPtr, /* Channel from which to read input. */ - char *result, /* Where to store the copied input. */ - int space) /* How many bytes are available in result to - * store the copied input? */ -{ - ChannelBuffer *bufPtr; /* The buffer from which to copy bytes. */ - int bytesInBuffer; /* How many bytes are available to be copied - * in the current input buffer? */ - int copied; /* How many characters were already copied - * into the destination space? */ - - /* - * If there is no input at all, return zero. The invariant is that either - * there is no buffer in the queue, or if the first buffer is empty, it is - * also the last buffer (and thus there is no input in the queue). Note - * also that if the buffer is empty, we don't leave it in the queue, but - * recycle it. - */ - - if (chanPtr->inQueueHead == NULL) { - return 0; - } - bufPtr = chanPtr->inQueueHead; - bytesInBuffer = BytesLeft(bufPtr); - - copied = 0; - - if (bytesInBuffer == 0) { - RecycleBuffer(chanPtr->state, bufPtr, 0); - chanPtr->inQueueHead = NULL; - chanPtr->inQueueTail = NULL; - return 0; - } - - /* - * Copy the current chunk into the result buffer. - */ - - if (bytesInBuffer < space) { - space = bytesInBuffer; - } - - memcpy(result, RemovePoint(bufPtr), (size_t) space); - bufPtr->nextRemoved += space; - copied = space; - - /* - * We don't care about in-stream EOF characters here as the data read here - * may still flow through one or more transformations, i.e. is not in its - * final state yet. - */ - - /* - * If the current buffer is empty recycle it. - */ - - if (IsBufferEmpty(bufPtr)) { - chanPtr->inQueueHead = bufPtr->nextPtr; - if (chanPtr->inQueueHead == NULL) { - chanPtr->inQueueTail = NULL; - } - RecycleBuffer(chanPtr->state, bufPtr, 0); - } - - /* - * Return the number of characters copied into the result buffer. - */ - - return copied; -} - -/* - *---------------------------------------------------------------------- - * * CopyEventProc -- * * This routine is invoked as a channel event handler for the background -- cgit v0.12 From 6bc046c0bcdaa67b312ec8fe8a467bd206ea3e8c Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 26 Jun 2014 15:59:27 +0000 Subject: Fix mismatch of Tcl_Preserve() / Tcl_Release(). --- generic/tclIO.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index c2a705c..85b015c 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -3945,8 +3945,7 @@ Tcl_GetsObj( Tcl_EncodingState oldState; if (CheckChannelErrors(statePtr, TCL_READABLE) != 0) { - copiedTotal = -1; - goto done; + return -1; } /* -- cgit v0.12 From 0cf246c1744d8a924a73a784cb44b0390b5b5b16 Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 2 Jul 2014 16:20:30 +0000 Subject: [c31ca233ca] Fix TclGetsObjBinary() so that each [gets] rediscovers whether a nonblocking channel is blocked. --- generic/tclIO.c | 9 ++++----- tests/io.test | 20 ++++++++++++++++++++ 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index 85b015c..9deec87 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -4377,11 +4377,6 @@ TclGetsObjBinary( * hasn't seen EOL. Need to read more bytes from the channel * device. Side effect is to allocate another channel buffer. */ - - if (GotFlag(statePtr, CHANNEL_BLOCKED|CHANNEL_NONBLOCKING) - == (CHANNEL_BLOCKED|CHANNEL_NONBLOCKING)) { - goto restore; - } if (GetInput(chanPtr) != 0) { goto restore; } @@ -4448,6 +4443,10 @@ TclGetsObjBinary( } goto gotEOL; } + if (GotFlag(statePtr, CHANNEL_BLOCKED|CHANNEL_NONBLOCKING) + == (CHANNEL_BLOCKED|CHANNEL_NONBLOCKING)) { + goto restore; + } /* * Copy bytes from the channel buffer to the ByteArray. diff --git a/tests/io.test b/tests/io.test index a1625ba..c1938a1 100644 --- a/tests/io.test +++ b/tests/io.test @@ -4921,6 +4921,26 @@ test io-36.1 {Tcl_InputBlocked on nonblocking pipe} {stdio openpipe} { close $f1 set x } {{} 1 hello 0 {} 1} +test io-36.1.1 {Tcl_InputBlocked on nonblocking binary pipe} {stdio openpipe} { + set f1 [open "|[list [interpreter]]" r+] + chan configure $f1 -encoding binary -translation lf -eofchar {} + puts $f1 {puts hello_from_pipe} + flush $f1 + gets $f1 + fconfigure $f1 -blocking off -buffering full + puts $f1 {puts hello} + set x "" + lappend x [gets $f1] + lappend x [fblocked $f1] + flush $f1 + after 200 + lappend x [gets $f1] + lappend x [fblocked $f1] + lappend x [gets $f1] + lappend x [fblocked $f1] + close $f1 + set x +} {{} 1 hello 0 {} 1} test io-36.2 {Tcl_InputBlocked on blocking pipe} {stdio openpipe} { set f1 [open "|[list [interpreter]]" r+] fconfigure $f1 -buffering line -- cgit v0.12 From 8d689510217a41efc49cccc31e77f88c8c9270f5 Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 2 Jul 2014 20:22:43 +0000 Subject: Clarify http::config and http::geturl -headers roles in setting request headers. --- doc/http.n | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/http.n b/doc/http.n index 26054cd..cdf9c56 100644 --- a/doc/http.n +++ b/doc/http.n @@ -210,7 +210,8 @@ proc httpHandlerCallback {socket token} { .TP \fB\-headers\fR \fIkeyvaluelist\fR . -This option is used to add extra headers to the HTTP request. The +This option is used to add headers not already specified +by \fB::http::config\fR to the HTTP request. The \fIkeyvaluelist\fR argument must be a list with an even number of elements that alternate between keys and values. The keys become header field names. Newlines are stripped from the values so the -- cgit v0.12 From 53df9e36da5db3c0319ea6995bb0237c8a9d1467 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Fri, 4 Jul 2014 12:47:21 +0000 Subject: Update Unicode tables to Unicode 7.0 --- generic/regc_locale.c | 637 ++++++++++--------- generic/tclUniData.c | 1620 ++++++++++++++++++++++++++----------------------- 2 files changed, 1194 insertions(+), 1063 deletions(-) diff --git a/generic/regc_locale.c b/generic/regc_locale.c index 69459f1..8dba520 100644 --- a/generic/regc_locale.c +++ b/generic/regc_locale.c @@ -137,97 +137,107 @@ 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, 0x527}, {0x531, 0x556}, {0x561, 0x587}, + {0x3f7, 0x481}, {0x48a, 0x52f}, {0x531, 0x556}, {0x561, 0x587}, {0x5d0, 0x5ea}, {0x5f0, 0x5f2}, {0x620, 0x64a}, {0x671, 0x6d3}, {0x6fa, 0x6fc}, {0x712, 0x72f}, {0x74d, 0x7a5}, {0x7ca, 0x7ea}, - {0x800, 0x815}, {0x840, 0x858}, {0x8a2, 0x8ac}, {0x904, 0x939}, - {0x958, 0x961}, {0x971, 0x977}, {0x979, 0x97f}, {0x985, 0x98c}, - {0x993, 0x9a8}, {0x9aa, 0x9b0}, {0x9b6, 0x9b9}, {0x9df, 0x9e1}, - {0xa05, 0xa0a}, {0xa13, 0xa28}, {0xa2a, 0xa30}, {0xa59, 0xa5c}, - {0xa72, 0xa74}, {0xa85, 0xa8d}, {0xa8f, 0xa91}, {0xa93, 0xaa8}, - {0xaaa, 0xab0}, {0xab5, 0xab9}, {0xb05, 0xb0c}, {0xb13, 0xb28}, - {0xb2a, 0xb30}, {0xb35, 0xb39}, {0xb5f, 0xb61}, {0xb85, 0xb8a}, - {0xb8e, 0xb90}, {0xb92, 0xb95}, {0xba8, 0xbaa}, {0xbae, 0xbb9}, - {0xc05, 0xc0c}, {0xc0e, 0xc10}, {0xc12, 0xc28}, {0xc2a, 0xc33}, - {0xc35, 0xc39}, {0xc85, 0xc8c}, {0xc8e, 0xc90}, {0xc92, 0xca8}, - {0xcaa, 0xcb3}, {0xcb5, 0xcb9}, {0xd05, 0xd0c}, {0xd0e, 0xd10}, - {0xd12, 0xd3a}, {0xd7a, 0xd7f}, {0xd85, 0xd96}, {0xd9a, 0xdb1}, - {0xdb3, 0xdbb}, {0xdc0, 0xdc6}, {0xe01, 0xe30}, {0xe40, 0xe46}, - {0xe94, 0xe97}, {0xe99, 0xe9f}, {0xea1, 0xea3}, {0xead, 0xeb0}, - {0xec0, 0xec4}, {0xedc, 0xedf}, {0xf40, 0xf47}, {0xf49, 0xf6c}, - {0xf88, 0xf8c}, {0x1000, 0x102a}, {0x1050, 0x1055}, {0x105a, 0x105d}, - {0x106e, 0x1070}, {0x1075, 0x1081}, {0x10a0, 0x10c5}, {0x10d0, 0x10fa}, - {0x10fc, 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}, {0x1380, 0x138f}, {0x13a0, 0x13f4}, - {0x1401, 0x166c}, {0x166f, 0x167f}, {0x1681, 0x169a}, {0x16a0, 0x16ea}, - {0x1700, 0x170c}, {0x170e, 0x1711}, {0x1720, 0x1731}, {0x1740, 0x1751}, - {0x1760, 0x176c}, {0x176e, 0x1770}, {0x1780, 0x17b3}, {0x1820, 0x1877}, - {0x1880, 0x18a8}, {0x18b0, 0x18f5}, {0x1900, 0x191c}, {0x1950, 0x196d}, - {0x1970, 0x1974}, {0x1980, 0x19ab}, {0x19c1, 0x19c7}, {0x1a00, 0x1a16}, - {0x1a20, 0x1a54}, {0x1b05, 0x1b33}, {0x1b45, 0x1b4b}, {0x1b83, 0x1ba0}, - {0x1bba, 0x1be5}, {0x1c00, 0x1c23}, {0x1c4d, 0x1c4f}, {0x1c5a, 0x1c7d}, - {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, 0x312d}, {0x3131, 0x318e}, {0x31a0, 0x31ba}, - {0x31f0, 0x31ff}, {0x3400, 0x4db5}, {0x4e00, 0x9fcc}, {0xa000, 0xa48c}, - {0xa4d0, 0xa4fd}, {0xa500, 0xa60c}, {0xa610, 0xa61f}, {0xa640, 0xa66e}, - {0xa67f, 0xa697}, {0xa6a0, 0xa6e5}, {0xa717, 0xa71f}, {0xa722, 0xa788}, - {0xa78b, 0xa78e}, {0xa790, 0xa793}, {0xa7a0, 0xa7aa}, {0xa7f8, 0xa801}, - {0xa803, 0xa805}, {0xa807, 0xa80a}, {0xa80c, 0xa822}, {0xa840, 0xa873}, - {0xa882, 0xa8b3}, {0xa8f2, 0xa8f7}, {0xa90a, 0xa925}, {0xa930, 0xa946}, - {0xa960, 0xa97c}, {0xa984, 0xa9b2}, {0xaa00, 0xaa28}, {0xaa40, 0xaa42}, - {0xaa44, 0xaa4b}, {0xaa60, 0xaa76}, {0xaa80, 0xaaaf}, {0xaab9, 0xaabd}, - {0xaadb, 0xaadd}, {0xaae0, 0xaaea}, {0xaaf2, 0xaaf4}, {0xab01, 0xab06}, - {0xab09, 0xab0e}, {0xab11, 0xab16}, {0xab20, 0xab26}, {0xab28, 0xab2e}, - {0xabc0, 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} + {0x800, 0x815}, {0x840, 0x858}, {0x8a0, 0x8b2}, {0x904, 0x939}, + {0x958, 0x961}, {0x971, 0x980}, {0x985, 0x98c}, {0x993, 0x9a8}, + {0x9aa, 0x9b0}, {0x9b6, 0x9b9}, {0x9df, 0x9e1}, {0xa05, 0xa0a}, + {0xa13, 0xa28}, {0xa2a, 0xa30}, {0xa59, 0xa5c}, {0xa72, 0xa74}, + {0xa85, 0xa8d}, {0xa8f, 0xa91}, {0xa93, 0xaa8}, {0xaaa, 0xab0}, + {0xab5, 0xab9}, {0xb05, 0xb0c}, {0xb13, 0xb28}, {0xb2a, 0xb30}, + {0xb35, 0xb39}, {0xb5f, 0xb61}, {0xb85, 0xb8a}, {0xb8e, 0xb90}, + {0xb92, 0xb95}, {0xba8, 0xbaa}, {0xbae, 0xbb9}, {0xc05, 0xc0c}, + {0xc0e, 0xc10}, {0xc12, 0xc28}, {0xc2a, 0xc39}, {0xc85, 0xc8c}, + {0xc8e, 0xc90}, {0xc92, 0xca8}, {0xcaa, 0xcb3}, {0xcb5, 0xcb9}, + {0xd05, 0xd0c}, {0xd0e, 0xd10}, {0xd12, 0xd3a}, {0xd7a, 0xd7f}, + {0xd85, 0xd96}, {0xd9a, 0xdb1}, {0xdb3, 0xdbb}, {0xdc0, 0xdc6}, + {0xe01, 0xe30}, {0xe40, 0xe46}, {0xe94, 0xe97}, {0xe99, 0xe9f}, + {0xea1, 0xea3}, {0xead, 0xeb0}, {0xec0, 0xec4}, {0xedc, 0xedf}, + {0xf40, 0xf47}, {0xf49, 0xf6c}, {0xf88, 0xf8c}, {0x1000, 0x102a}, + {0x1050, 0x1055}, {0x105a, 0x105d}, {0x106e, 0x1070}, {0x1075, 0x1081}, + {0x10a0, 0x10c5}, {0x10d0, 0x10fa}, {0x10fc, 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}, + {0x1380, 0x138f}, {0x13a0, 0x13f4}, {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, 0x18a8}, + {0x18b0, 0x18f5}, {0x1900, 0x191e}, {0x1950, 0x196d}, {0x1970, 0x1974}, + {0x1980, 0x19ab}, {0x19c1, 0x19c7}, {0x1a00, 0x1a16}, {0x1a20, 0x1a54}, + {0x1b05, 0x1b33}, {0x1b45, 0x1b4b}, {0x1b83, 0x1ba0}, {0x1bba, 0x1be5}, + {0x1c00, 0x1c23}, {0x1c4d, 0x1c4f}, {0x1c5a, 0x1c7d}, {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, 0x312d}, {0x3131, 0x318e}, {0x31a0, 0x31ba}, {0x31f0, 0x31ff}, + {0x3400, 0x4db5}, {0x4e00, 0x9fcc}, {0xa000, 0xa48c}, {0xa4d0, 0xa4fd}, + {0xa500, 0xa60c}, {0xa610, 0xa61f}, {0xa640, 0xa66e}, {0xa67f, 0xa69d}, + {0xa6a0, 0xa6e5}, {0xa717, 0xa71f}, {0xa722, 0xa788}, {0xa78b, 0xa78e}, + {0xa790, 0xa7ad}, {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, 0xab5f}, {0xabc0, 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 TCL_UTF_MAX > 4 ,{0x10000, 0x1000b}, {0x1000d, 0x10026}, {0x10028, 0x1003a}, {0x1003f, 0x1004d}, {0x10050, 0x1005d}, {0x10080, 0x100fa}, {0x10280, 0x1029c}, {0x102a0, 0x102d0}, - {0x10300, 0x1031e}, {0x10330, 0x10340}, {0x10342, 0x10349}, {0x10380, 0x1039d}, - {0x103a0, 0x103c3}, {0x103c8, 0x103cf}, {0x10400, 0x1049d}, {0x10800, 0x10805}, - {0x1080a, 0x10835}, {0x1083f, 0x10855}, {0x10900, 0x10915}, {0x10920, 0x10939}, + {0x10300, 0x1031f}, {0x10330, 0x10340}, {0x10342, 0x10349}, {0x10350, 0x10375}, + {0x10380, 0x1039d}, {0x103a0, 0x103c3}, {0x103c8, 0x103cf}, {0x10400, 0x1049d}, + {0x10500, 0x10527}, {0x10530, 0x10563}, {0x10600, 0x10736}, {0x10740, 0x10755}, + {0x10760, 0x10767}, {0x10800, 0x10805}, {0x1080a, 0x10835}, {0x1083f, 0x10855}, + {0x10860, 0x10876}, {0x10880, 0x1089e}, {0x10900, 0x10915}, {0x10920, 0x10939}, {0x10980, 0x109b7}, {0x10a10, 0x10a13}, {0x10a15, 0x10a17}, {0x10a19, 0x10a33}, - {0x10a60, 0x10a7c}, {0x10b00, 0x10b35}, {0x10b40, 0x10b55}, {0x10b60, 0x10b72}, + {0x10a60, 0x10a7c}, {0x10a80, 0x10a9c}, {0x10ac0, 0x10ac7}, {0x10ac9, 0x10ae4}, + {0x10b00, 0x10b35}, {0x10b40, 0x10b55}, {0x10b60, 0x10b72}, {0x10b80, 0x10b91}, {0x10c00, 0x10c48}, {0x11003, 0x11037}, {0x11083, 0x110af}, {0x110d0, 0x110e8}, - {0x11103, 0x11126}, {0x11183, 0x111b2}, {0x111c1, 0x111c4}, {0x11680, 0x116aa}, - {0x12000, 0x1236e}, {0x13000, 0x1342e}, {0x16800, 0x16a38}, {0x16f00, 0x16f44}, - {0x16f93, 0x16f9f}, {0x1d400, 0x1d454}, {0x1d456, 0x1d49c}, {0x1d4a9, 0x1d4ac}, + {0x11103, 0x11126}, {0x11150, 0x11172}, {0x11183, 0x111b2}, {0x111c1, 0x111c4}, + {0x11200, 0x11211}, {0x11213, 0x1122b}, {0x112b0, 0x112de}, {0x11305, 0x1130c}, + {0x11313, 0x11328}, {0x1132a, 0x11330}, {0x11335, 0x11339}, {0x1135d, 0x11361}, + {0x11480, 0x114af}, {0x11580, 0x115ae}, {0x11600, 0x1162f}, {0x11680, 0x116aa}, + {0x118a0, 0x118df}, {0x11ac0, 0x11af8}, {0x12000, 0x12398}, {0x13000, 0x1342e}, + {0x16800, 0x16a38}, {0x16a40, 0x16a5e}, {0x16ad0, 0x16aed}, {0x16b00, 0x16b2f}, + {0x16b40, 0x16b43}, {0x16b63, 0x16b77}, {0x16b7d, 0x16b8f}, {0x16f00, 0x16f44}, + {0x16f93, 0x16f9f}, {0x1bc00, 0x1bc6a}, {0x1bc70, 0x1bc7c}, {0x1bc80, 0x1bc88}, + {0x1bc90, 0x1bc99}, {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, 0x1d6c0}, {0x1d6c2, 0x1d6da}, {0x1d6dc, 0x1d6fa}, {0x1d6fc, 0x1d714}, {0x1d716, 0x1d734}, {0x1d736, 0x1d74e}, {0x1d750, 0x1d76e}, {0x1d770, 0x1d788}, {0x1d78a, 0x1d7a8}, - {0x1d7aa, 0x1d7c2}, {0x1d7c4, 0x1d7cb}, {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}, - {0x20000, 0x2a6d6}, {0x2a700, 0x2b734}, {0x2b740, 0x2b81d}, {0x2f800, 0x2fa1d} + {0x1d7aa, 0x1d7c2}, {0x1d7c4, 0x1d7cb}, {0x1e800, 0x1e8c4}, {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}, {0x20000, 0x2a6d6}, {0x2a700, 0x2b734}, {0x2b740, 0x2b81d}, + {0x2f800, 0x2fa1d} #endif }; #define NUM_ALPHA_RANGE (sizeof(alphaRangeTable)/sizeof(crange)) static const chr alphaCharTable[] = { - 0xaa, 0xb5, 0xba, 0x2ec, 0x2ee, 0x376, 0x377, 0x386, 0x38c, - 0x559, 0x66e, 0x66f, 0x6d5, 0x6e5, 0x6e6, 0x6ee, 0x6ef, 0x6ff, - 0x710, 0x7b1, 0x7f4, 0x7f5, 0x7fa, 0x81a, 0x824, 0x828, 0x8a0, + 0xaa, 0xb5, 0xba, 0x2ec, 0x2ee, 0x376, 0x377, 0x37f, 0x386, + 0x38c, 0x559, 0x66e, 0x66f, 0x6d5, 0x6e5, 0x6e6, 0x6ee, 0x6ef, + 0x6ff, 0x710, 0x7b1, 0x7f4, 0x7f5, 0x7fa, 0x81a, 0x824, 0x828, 0x93d, 0x950, 0x98f, 0x990, 0x9b2, 0x9bd, 0x9ce, 0x9dc, 0x9dd, 0x9f0, 0x9f1, 0xa0f, 0xa10, 0xa32, 0xa33, 0xa35, 0xa36, 0xa38, 0xa39, 0xa5e, 0xab2, 0xab3, 0xabd, 0xad0, 0xae0, 0xae1, 0xb0f, @@ -241,14 +251,16 @@ static const chr alphaCharTable[] = { 0x1bae, 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, 0xa9cf, 0xaa7a, 0xaab1, 0xaab5, - 0xaab6, 0xaac0, 0xaac2, 0xfb1d, 0xfb3e, 0xfb40, 0xfb41, 0xfb43, 0xfb44 + 0x303b, 0x303c, 0xa62a, 0xa62b, 0xa7b0, 0xa7b1, 0xa8fb, 0xa9cf, 0xaa7a, + 0xaab1, 0xaab5, 0xaab6, 0xaac0, 0xaac2, 0xab64, 0xab65, 0xfb1d, 0xfb3e, + 0xfb40, 0xfb41, 0xfb43, 0xfb44 #if TCL_UTF_MAX > 4 ,0x1003c, 0x1003d, 0x10808, 0x10837, 0x10838, 0x1083c, 0x109be, 0x109bf, 0x10a00, - 0x16f50, 0x1b000, 0x1b001, 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 + 0x11176, 0x111da, 0x1130f, 0x11310, 0x11332, 0x11333, 0x1133d, 0x114c4, 0x114c5, + 0x114c7, 0x11644, 0x118ff, 0x16f50, 0x1b000, 0x1b001, 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 }; @@ -259,11 +271,12 @@ static const chr alphaCharTable[] = { */ static const crange controlRangeTable[] = { - {0x0, 0x1f}, {0x7f, 0x9f}, {0x600, 0x604}, {0x200b, 0x200f}, + {0x0, 0x1f}, {0x7f, 0x9f}, {0x600, 0x605}, {0x200b, 0x200f}, {0x202a, 0x202e}, {0x2060, 0x2064}, {0x2066, 0x206f}, {0xe000, 0xf8ff}, {0xfff9, 0xfffb} #if TCL_UTF_MAX > 4 - ,{0x1d173, 0x1d17a}, {0xe0020, 0xe007f}, {0xf0000, 0xffffd}, {0x100000, 0x10fffd} + ,{0x1bca0, 0x1bca3}, {0x1d173, 0x1d17a}, {0xe0020, 0xe007f}, {0xf0000, 0xffffd}, + {0x100000, 0x10fffd} #endif }; @@ -286,15 +299,18 @@ static const crange digitRangeTable[] = { {0x30, 0x39}, {0x660, 0x669}, {0x6f0, 0x6f9}, {0x7c0, 0x7c9}, {0x966, 0x96f}, {0x9e6, 0x9ef}, {0xa66, 0xa6f}, {0xae6, 0xaef}, {0xb66, 0xb6f}, {0xbe6, 0xbef}, {0xc66, 0xc6f}, {0xce6, 0xcef}, - {0xd66, 0xd6f}, {0xe50, 0xe59}, {0xed0, 0xed9}, {0xf20, 0xf29}, - {0x1040, 0x1049}, {0x1090, 0x1099}, {0x17e0, 0x17e9}, {0x1810, 0x1819}, - {0x1946, 0x194f}, {0x19d0, 0x19d9}, {0x1a80, 0x1a89}, {0x1a90, 0x1a99}, - {0x1b50, 0x1b59}, {0x1bb0, 0x1bb9}, {0x1c40, 0x1c49}, {0x1c50, 0x1c59}, - {0xa620, 0xa629}, {0xa8d0, 0xa8d9}, {0xa900, 0xa909}, {0xa9d0, 0xa9d9}, - {0xaa50, 0xaa59}, {0xabf0, 0xabf9}, {0xff10, 0xff19} + {0xd66, 0xd6f}, {0xde6, 0xdef}, {0xe50, 0xe59}, {0xed0, 0xed9}, + {0xf20, 0xf29}, {0x1040, 0x1049}, {0x1090, 0x1099}, {0x17e0, 0x17e9}, + {0x1810, 0x1819}, {0x1946, 0x194f}, {0x19d0, 0x19d9}, {0x1a80, 0x1a89}, + {0x1a90, 0x1a99}, {0x1b50, 0x1b59}, {0x1bb0, 0x1bb9}, {0x1c40, 0x1c49}, + {0x1c50, 0x1c59}, {0xa620, 0xa629}, {0xa8d0, 0xa8d9}, {0xa900, 0xa909}, + {0xa9d0, 0xa9d9}, {0xa9f0, 0xa9f9}, {0xaa50, 0xaa59}, {0xabf0, 0xabf9}, + {0xff10, 0xff19} #if TCL_UTF_MAX > 4 ,{0x104a0, 0x104a9}, {0x11066, 0x1106f}, {0x110f0, 0x110f9}, {0x11136, 0x1113f}, - {0x111d0, 0x111d9}, {0x116c0, 0x116c9}, {0x1d7ce, 0x1d7ff} + {0x111d0, 0x111d9}, {0x112f0, 0x112f9}, {0x114d0, 0x114d9}, {0x11650, 0x11659}, + {0x116c0, 0x116c9}, {0x118e0, 0x118e9}, {0x16a60, 0x16a69}, {0x16b50, 0x16b59}, + {0x1d7ce, 0x1d7ff} #endif }; @@ -317,15 +333,17 @@ 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, 0x2e3b}, + {0x29d8, 0x29db}, {0x2cf9, 0x2cfc}, {0x2e00, 0x2e2e}, {0x2e30, 0x2e42}, {0x3001, 0x3003}, {0x3008, 0x3011}, {0x3014, 0x301f}, {0xa60d, 0xa60f}, {0xa6f2, 0xa6f7}, {0xa874, 0xa877}, {0xa8f8, 0xa8fa}, {0xa9c1, 0xa9cd}, {0xaa5c, 0xaa5f}, {0xfe10, 0xfe19}, {0xfe30, 0xfe52}, {0xfe54, 0xfe61}, {0xff01, 0xff03}, {0xff05, 0xff0a}, {0xff0c, 0xff0f}, {0xff3b, 0xff3d}, {0xff5f, 0xff65} #if TCL_UTF_MAX > 4 - ,{0x10100, 0x10102}, {0x10a50, 0x10a58}, {0x10b39, 0x10b3f}, {0x11047, 0x1104d}, - {0x110be, 0x110c1}, {0x11140, 0x11143}, {0x111c5, 0x111c8}, {0x12470, 0x12473} + ,{0x10100, 0x10102}, {0x10a50, 0x10a58}, {0x10af0, 0x10af6}, {0x10b39, 0x10b3f}, + {0x10b99, 0x10b9c}, {0x11047, 0x1104d}, {0x110be, 0x110c1}, {0x11140, 0x11143}, + {0x111c5, 0x111c8}, {0x11238, 0x1123d}, {0x115c1, 0x115c9}, {0x11641, 0x11643}, + {0x12470, 0x12474}, {0x16b37, 0x16b3b} #endif }; @@ -345,7 +363,8 @@ static const chr punctCharTable[] = { 0xaaf0, 0xaaf1, 0xabeb, 0xfd3e, 0xfd3f, 0xfe63, 0xfe68, 0xfe6a, 0xfe6b, 0xff1a, 0xff1b, 0xff1f, 0xff20, 0xff3f, 0xff5b, 0xff5d #if TCL_UTF_MAX > 4 - ,0x1039f, 0x103d0, 0x10857, 0x1091f, 0x1093f, 0x10a7f, 0x110bb, 0x110bc + ,0x1039f, 0x103d0, 0x1056f, 0x10857, 0x1091f, 0x1093f, 0x10a7f, 0x110bb, 0x110bc, + 0x11174, 0x11175, 0x111cd, 0x114c6, 0x16a6e, 0x16a6f, 0x16af5, 0x16b44, 0x1bc9f #endif }; @@ -383,15 +402,16 @@ static const crange lowerRangeTable[] = { {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}, {0xfb00, 0xfb06}, {0xfb13, 0xfb17}, {0xff41, 0xff5a} + {0xa771, 0xa778}, {0xa793, 0xa795}, {0xab30, 0xab5a}, {0xfb00, 0xfb06}, + {0xfb13, 0xfb17}, {0xff41, 0xff5a} #if TCL_UTF_MAX > 4 - ,{0x10428, 0x1044f}, {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} + ,{0x10428, 0x1044f}, {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} #endif }; @@ -427,39 +447,41 @@ static const chr lowerCharTable[] = { 0x4f1, 0x4f3, 0x4f5, 0x4f7, 0x4f9, 0x4fb, 0x4fd, 0x4ff, 0x501, 0x503, 0x505, 0x507, 0x509, 0x50b, 0x50d, 0x50f, 0x511, 0x513, 0x515, 0x517, 0x519, 0x51b, 0x51d, 0x51f, 0x521, 0x523, 0x525, - 0x527, 0x1e01, 0x1e03, 0x1e05, 0x1e07, 0x1e09, 0x1e0b, 0x1e0d, 0x1e0f, - 0x1e11, 0x1e13, 0x1e15, 0x1e17, 0x1e19, 0x1e1b, 0x1e1d, 0x1e1f, 0x1e21, - 0x1e23, 0x1e25, 0x1e27, 0x1e29, 0x1e2b, 0x1e2d, 0x1e2f, 0x1e31, 0x1e33, - 0x1e35, 0x1e37, 0x1e39, 0x1e3b, 0x1e3d, 0x1e3f, 0x1e41, 0x1e43, 0x1e45, - 0x1e47, 0x1e49, 0x1e4b, 0x1e4d, 0x1e4f, 0x1e51, 0x1e53, 0x1e55, 0x1e57, - 0x1e59, 0x1e5b, 0x1e5d, 0x1e5f, 0x1e61, 0x1e63, 0x1e65, 0x1e67, 0x1e69, - 0x1e6b, 0x1e6d, 0x1e6f, 0x1e71, 0x1e73, 0x1e75, 0x1e77, 0x1e79, 0x1e7b, - 0x1e7d, 0x1e7f, 0x1e81, 0x1e83, 0x1e85, 0x1e87, 0x1e89, 0x1e8b, 0x1e8d, - 0x1e8f, 0x1e91, 0x1e93, 0x1e9f, 0x1ea1, 0x1ea3, 0x1ea5, 0x1ea7, 0x1ea9, - 0x1eab, 0x1ead, 0x1eaf, 0x1eb1, 0x1eb3, 0x1eb5, 0x1eb7, 0x1eb9, 0x1ebb, - 0x1ebd, 0x1ebf, 0x1ec1, 0x1ec3, 0x1ec5, 0x1ec7, 0x1ec9, 0x1ecb, 0x1ecd, - 0x1ecf, 0x1ed1, 0x1ed3, 0x1ed5, 0x1ed7, 0x1ed9, 0x1edb, 0x1edd, 0x1edf, - 0x1ee1, 0x1ee3, 0x1ee5, 0x1ee7, 0x1ee9, 0x1eeb, 0x1eed, 0x1eef, 0x1ef1, - 0x1ef3, 0x1ef5, 0x1ef7, 0x1ef9, 0x1efb, 0x1efd, 0x1fb6, 0x1fb7, 0x1fbe, - 0x1fc6, 0x1fc7, 0x1fd6, 0x1fd7, 0x1ff6, 0x1ff7, 0x210a, 0x210e, 0x210f, - 0x2113, 0x212f, 0x2134, 0x2139, 0x213c, 0x213d, 0x214e, 0x2184, 0x2c61, - 0x2c65, 0x2c66, 0x2c68, 0x2c6a, 0x2c6c, 0x2c71, 0x2c73, 0x2c74, 0x2c81, - 0x2c83, 0x2c85, 0x2c87, 0x2c89, 0x2c8b, 0x2c8d, 0x2c8f, 0x2c91, 0x2c93, - 0x2c95, 0x2c97, 0x2c99, 0x2c9b, 0x2c9d, 0x2c9f, 0x2ca1, 0x2ca3, 0x2ca5, - 0x2ca7, 0x2ca9, 0x2cab, 0x2cad, 0x2caf, 0x2cb1, 0x2cb3, 0x2cb5, 0x2cb7, - 0x2cb9, 0x2cbb, 0x2cbd, 0x2cbf, 0x2cc1, 0x2cc3, 0x2cc5, 0x2cc7, 0x2cc9, - 0x2ccb, 0x2ccd, 0x2ccf, 0x2cd1, 0x2cd3, 0x2cd5, 0x2cd7, 0x2cd9, 0x2cdb, - 0x2cdd, 0x2cdf, 0x2ce1, 0x2ce3, 0x2ce4, 0x2cec, 0x2cee, 0x2cf3, 0x2d27, - 0x2d2d, 0xa641, 0xa643, 0xa645, 0xa647, 0xa649, 0xa64b, 0xa64d, 0xa64f, - 0xa651, 0xa653, 0xa655, 0xa657, 0xa659, 0xa65b, 0xa65d, 0xa65f, 0xa661, - 0xa663, 0xa665, 0xa667, 0xa669, 0xa66b, 0xa66d, 0xa681, 0xa683, 0xa685, - 0xa687, 0xa689, 0xa68b, 0xa68d, 0xa68f, 0xa691, 0xa693, 0xa695, 0xa697, - 0xa723, 0xa725, 0xa727, 0xa729, 0xa72b, 0xa72d, 0xa733, 0xa735, 0xa737, - 0xa739, 0xa73b, 0xa73d, 0xa73f, 0xa741, 0xa743, 0xa745, 0xa747, 0xa749, - 0xa74b, 0xa74d, 0xa74f, 0xa751, 0xa753, 0xa755, 0xa757, 0xa759, 0xa75b, - 0xa75d, 0xa75f, 0xa761, 0xa763, 0xa765, 0xa767, 0xa769, 0xa76b, 0xa76d, - 0xa76f, 0xa77a, 0xa77c, 0xa77f, 0xa781, 0xa783, 0xa785, 0xa787, 0xa78c, - 0xa78e, 0xa791, 0xa793, 0xa7a1, 0xa7a3, 0xa7a5, 0xa7a7, 0xa7a9, 0xa7fa + 0x527, 0x529, 0x52b, 0x52d, 0x52f, 0x1e01, 0x1e03, 0x1e05, 0x1e07, + 0x1e09, 0x1e0b, 0x1e0d, 0x1e0f, 0x1e11, 0x1e13, 0x1e15, 0x1e17, 0x1e19, + 0x1e1b, 0x1e1d, 0x1e1f, 0x1e21, 0x1e23, 0x1e25, 0x1e27, 0x1e29, 0x1e2b, + 0x1e2d, 0x1e2f, 0x1e31, 0x1e33, 0x1e35, 0x1e37, 0x1e39, 0x1e3b, 0x1e3d, + 0x1e3f, 0x1e41, 0x1e43, 0x1e45, 0x1e47, 0x1e49, 0x1e4b, 0x1e4d, 0x1e4f, + 0x1e51, 0x1e53, 0x1e55, 0x1e57, 0x1e59, 0x1e5b, 0x1e5d, 0x1e5f, 0x1e61, + 0x1e63, 0x1e65, 0x1e67, 0x1e69, 0x1e6b, 0x1e6d, 0x1e6f, 0x1e71, 0x1e73, + 0x1e75, 0x1e77, 0x1e79, 0x1e7b, 0x1e7d, 0x1e7f, 0x1e81, 0x1e83, 0x1e85, + 0x1e87, 0x1e89, 0x1e8b, 0x1e8d, 0x1e8f, 0x1e91, 0x1e93, 0x1e9f, 0x1ea1, + 0x1ea3, 0x1ea5, 0x1ea7, 0x1ea9, 0x1eab, 0x1ead, 0x1eaf, 0x1eb1, 0x1eb3, + 0x1eb5, 0x1eb7, 0x1eb9, 0x1ebb, 0x1ebd, 0x1ebf, 0x1ec1, 0x1ec3, 0x1ec5, + 0x1ec7, 0x1ec9, 0x1ecb, 0x1ecd, 0x1ecf, 0x1ed1, 0x1ed3, 0x1ed5, 0x1ed7, + 0x1ed9, 0x1edb, 0x1edd, 0x1edf, 0x1ee1, 0x1ee3, 0x1ee5, 0x1ee7, 0x1ee9, + 0x1eeb, 0x1eed, 0x1eef, 0x1ef1, 0x1ef3, 0x1ef5, 0x1ef7, 0x1ef9, 0x1efb, + 0x1efd, 0x1fb6, 0x1fb7, 0x1fbe, 0x1fc6, 0x1fc7, 0x1fd6, 0x1fd7, 0x1ff6, + 0x1ff7, 0x210a, 0x210e, 0x210f, 0x2113, 0x212f, 0x2134, 0x2139, 0x213c, + 0x213d, 0x214e, 0x2184, 0x2c61, 0x2c65, 0x2c66, 0x2c68, 0x2c6a, 0x2c6c, + 0x2c71, 0x2c73, 0x2c74, 0x2c81, 0x2c83, 0x2c85, 0x2c87, 0x2c89, 0x2c8b, + 0x2c8d, 0x2c8f, 0x2c91, 0x2c93, 0x2c95, 0x2c97, 0x2c99, 0x2c9b, 0x2c9d, + 0x2c9f, 0x2ca1, 0x2ca3, 0x2ca5, 0x2ca7, 0x2ca9, 0x2cab, 0x2cad, 0x2caf, + 0x2cb1, 0x2cb3, 0x2cb5, 0x2cb7, 0x2cb9, 0x2cbb, 0x2cbd, 0x2cbf, 0x2cc1, + 0x2cc3, 0x2cc5, 0x2cc7, 0x2cc9, 0x2ccb, 0x2ccd, 0x2ccf, 0x2cd1, 0x2cd3, + 0x2cd5, 0x2cd7, 0x2cd9, 0x2cdb, 0x2cdd, 0x2cdf, 0x2ce1, 0x2ce3, 0x2ce4, + 0x2cec, 0x2cee, 0x2cf3, 0x2d27, 0x2d2d, 0xa641, 0xa643, 0xa645, 0xa647, + 0xa649, 0xa64b, 0xa64d, 0xa64f, 0xa651, 0xa653, 0xa655, 0xa657, 0xa659, + 0xa65b, 0xa65d, 0xa65f, 0xa661, 0xa663, 0xa665, 0xa667, 0xa669, 0xa66b, + 0xa66d, 0xa681, 0xa683, 0xa685, 0xa687, 0xa689, 0xa68b, 0xa68d, 0xa68f, + 0xa691, 0xa693, 0xa695, 0xa697, 0xa699, 0xa69b, 0xa723, 0xa725, 0xa727, + 0xa729, 0xa72b, 0xa72d, 0xa733, 0xa735, 0xa737, 0xa739, 0xa73b, 0xa73d, + 0xa73f, 0xa741, 0xa743, 0xa745, 0xa747, 0xa749, 0xa74b, 0xa74d, 0xa74f, + 0xa751, 0xa753, 0xa755, 0xa757, 0xa759, 0xa75b, 0xa75d, 0xa75f, 0xa761, + 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, + 0xa7fa, 0xab64, 0xab65 #if TCL_UTF_MAX > 4 ,0x1d4bb, 0x1d7cb #endif @@ -481,14 +503,15 @@ static const crange upperRangeTable[] = { {0x1fd8, 0x1fdb}, {0x1fe8, 0x1fec}, {0x1ff8, 0x1ffb}, {0x210b, 0x210d}, {0x2110, 0x2112}, {0x2119, 0x211d}, {0x212a, 0x212d}, {0x2130, 0x2133}, {0x2c00, 0x2c2e}, {0x2c62, 0x2c64}, {0x2c6d, 0x2c70}, {0x2c7e, 0x2c80}, - {0xff21, 0xff3a} + {0xa7aa, 0xa7ad}, {0xff21, 0xff3a} #if TCL_UTF_MAX > 4 - ,{0x10400, 0x10427}, {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} + ,{0x10400, 0x10427}, {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} #endif }; @@ -511,52 +534,54 @@ static const chr upperCharTable[] = { 0x20c, 0x20e, 0x210, 0x212, 0x214, 0x216, 0x218, 0x21a, 0x21c, 0x21e, 0x220, 0x222, 0x224, 0x226, 0x228, 0x22a, 0x22c, 0x22e, 0x230, 0x232, 0x23a, 0x23b, 0x23d, 0x23e, 0x241, 0x248, 0x24a, - 0x24c, 0x24e, 0x370, 0x372, 0x376, 0x386, 0x38c, 0x38e, 0x38f, - 0x3cf, 0x3d8, 0x3da, 0x3dc, 0x3de, 0x3e0, 0x3e2, 0x3e4, 0x3e6, - 0x3e8, 0x3ea, 0x3ec, 0x3ee, 0x3f4, 0x3f7, 0x3f9, 0x3fa, 0x460, - 0x462, 0x464, 0x466, 0x468, 0x46a, 0x46c, 0x46e, 0x470, 0x472, - 0x474, 0x476, 0x478, 0x47a, 0x47c, 0x47e, 0x480, 0x48a, 0x48c, - 0x48e, 0x490, 0x492, 0x494, 0x496, 0x498, 0x49a, 0x49c, 0x49e, - 0x4a0, 0x4a2, 0x4a4, 0x4a6, 0x4a8, 0x4aa, 0x4ac, 0x4ae, 0x4b0, - 0x4b2, 0x4b4, 0x4b6, 0x4b8, 0x4ba, 0x4bc, 0x4be, 0x4c0, 0x4c1, - 0x4c3, 0x4c5, 0x4c7, 0x4c9, 0x4cb, 0x4cd, 0x4d0, 0x4d2, 0x4d4, - 0x4d6, 0x4d8, 0x4da, 0x4dc, 0x4de, 0x4e0, 0x4e2, 0x4e4, 0x4e6, - 0x4e8, 0x4ea, 0x4ec, 0x4ee, 0x4f0, 0x4f2, 0x4f4, 0x4f6, 0x4f8, - 0x4fa, 0x4fc, 0x4fe, 0x500, 0x502, 0x504, 0x506, 0x508, 0x50a, - 0x50c, 0x50e, 0x510, 0x512, 0x514, 0x516, 0x518, 0x51a, 0x51c, - 0x51e, 0x520, 0x522, 0x524, 0x526, 0x10c7, 0x10cd, 0x1e00, 0x1e02, - 0x1e04, 0x1e06, 0x1e08, 0x1e0a, 0x1e0c, 0x1e0e, 0x1e10, 0x1e12, 0x1e14, - 0x1e16, 0x1e18, 0x1e1a, 0x1e1c, 0x1e1e, 0x1e20, 0x1e22, 0x1e24, 0x1e26, - 0x1e28, 0x1e2a, 0x1e2c, 0x1e2e, 0x1e30, 0x1e32, 0x1e34, 0x1e36, 0x1e38, - 0x1e3a, 0x1e3c, 0x1e3e, 0x1e40, 0x1e42, 0x1e44, 0x1e46, 0x1e48, 0x1e4a, - 0x1e4c, 0x1e4e, 0x1e50, 0x1e52, 0x1e54, 0x1e56, 0x1e58, 0x1e5a, 0x1e5c, - 0x1e5e, 0x1e60, 0x1e62, 0x1e64, 0x1e66, 0x1e68, 0x1e6a, 0x1e6c, 0x1e6e, - 0x1e70, 0x1e72, 0x1e74, 0x1e76, 0x1e78, 0x1e7a, 0x1e7c, 0x1e7e, 0x1e80, - 0x1e82, 0x1e84, 0x1e86, 0x1e88, 0x1e8a, 0x1e8c, 0x1e8e, 0x1e90, 0x1e92, - 0x1e94, 0x1e9e, 0x1ea0, 0x1ea2, 0x1ea4, 0x1ea6, 0x1ea8, 0x1eaa, 0x1eac, - 0x1eae, 0x1eb0, 0x1eb2, 0x1eb4, 0x1eb6, 0x1eb8, 0x1eba, 0x1ebc, 0x1ebe, - 0x1ec0, 0x1ec2, 0x1ec4, 0x1ec6, 0x1ec8, 0x1eca, 0x1ecc, 0x1ece, 0x1ed0, - 0x1ed2, 0x1ed4, 0x1ed6, 0x1ed8, 0x1eda, 0x1edc, 0x1ede, 0x1ee0, 0x1ee2, - 0x1ee4, 0x1ee6, 0x1ee8, 0x1eea, 0x1eec, 0x1eee, 0x1ef0, 0x1ef2, 0x1ef4, - 0x1ef6, 0x1ef8, 0x1efa, 0x1efc, 0x1efe, 0x1f59, 0x1f5b, 0x1f5d, 0x1f5f, - 0x2102, 0x2107, 0x2115, 0x2124, 0x2126, 0x2128, 0x213e, 0x213f, 0x2145, - 0x2183, 0x2c60, 0x2c67, 0x2c69, 0x2c6b, 0x2c72, 0x2c75, 0x2c82, 0x2c84, - 0x2c86, 0x2c88, 0x2c8a, 0x2c8c, 0x2c8e, 0x2c90, 0x2c92, 0x2c94, 0x2c96, - 0x2c98, 0x2c9a, 0x2c9c, 0x2c9e, 0x2ca0, 0x2ca2, 0x2ca4, 0x2ca6, 0x2ca8, - 0x2caa, 0x2cac, 0x2cae, 0x2cb0, 0x2cb2, 0x2cb4, 0x2cb6, 0x2cb8, 0x2cba, - 0x2cbc, 0x2cbe, 0x2cc0, 0x2cc2, 0x2cc4, 0x2cc6, 0x2cc8, 0x2cca, 0x2ccc, - 0x2cce, 0x2cd0, 0x2cd2, 0x2cd4, 0x2cd6, 0x2cd8, 0x2cda, 0x2cdc, 0x2cde, - 0x2ce0, 0x2ce2, 0x2ceb, 0x2ced, 0x2cf2, 0xa640, 0xa642, 0xa644, 0xa646, - 0xa648, 0xa64a, 0xa64c, 0xa64e, 0xa650, 0xa652, 0xa654, 0xa656, 0xa658, - 0xa65a, 0xa65c, 0xa65e, 0xa660, 0xa662, 0xa664, 0xa666, 0xa668, 0xa66a, - 0xa66c, 0xa680, 0xa682, 0xa684, 0xa686, 0xa688, 0xa68a, 0xa68c, 0xa68e, - 0xa690, 0xa692, 0xa694, 0xa696, 0xa722, 0xa724, 0xa726, 0xa728, 0xa72a, - 0xa72c, 0xa72e, 0xa732, 0xa734, 0xa736, 0xa738, 0xa73a, 0xa73c, 0xa73e, - 0xa740, 0xa742, 0xa744, 0xa746, 0xa748, 0xa74a, 0xa74c, 0xa74e, 0xa750, - 0xa752, 0xa754, 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, - 0xa7a0, 0xa7a2, 0xa7a4, 0xa7a6, 0xa7a8, 0xa7aa + 0x24c, 0x24e, 0x370, 0x372, 0x376, 0x37f, 0x386, 0x38c, 0x38e, + 0x38f, 0x3cf, 0x3d8, 0x3da, 0x3dc, 0x3de, 0x3e0, 0x3e2, 0x3e4, + 0x3e6, 0x3e8, 0x3ea, 0x3ec, 0x3ee, 0x3f4, 0x3f7, 0x3f9, 0x3fa, + 0x460, 0x462, 0x464, 0x466, 0x468, 0x46a, 0x46c, 0x46e, 0x470, + 0x472, 0x474, 0x476, 0x478, 0x47a, 0x47c, 0x47e, 0x480, 0x48a, + 0x48c, 0x48e, 0x490, 0x492, 0x494, 0x496, 0x498, 0x49a, 0x49c, + 0x49e, 0x4a0, 0x4a2, 0x4a4, 0x4a6, 0x4a8, 0x4aa, 0x4ac, 0x4ae, + 0x4b0, 0x4b2, 0x4b4, 0x4b6, 0x4b8, 0x4ba, 0x4bc, 0x4be, 0x4c0, + 0x4c1, 0x4c3, 0x4c5, 0x4c7, 0x4c9, 0x4cb, 0x4cd, 0x4d0, 0x4d2, + 0x4d4, 0x4d6, 0x4d8, 0x4da, 0x4dc, 0x4de, 0x4e0, 0x4e2, 0x4e4, + 0x4e6, 0x4e8, 0x4ea, 0x4ec, 0x4ee, 0x4f0, 0x4f2, 0x4f4, 0x4f6, + 0x4f8, 0x4fa, 0x4fc, 0x4fe, 0x500, 0x502, 0x504, 0x506, 0x508, + 0x50a, 0x50c, 0x50e, 0x510, 0x512, 0x514, 0x516, 0x518, 0x51a, + 0x51c, 0x51e, 0x520, 0x522, 0x524, 0x526, 0x528, 0x52a, 0x52c, + 0x52e, 0x10c7, 0x10cd, 0x1e00, 0x1e02, 0x1e04, 0x1e06, 0x1e08, 0x1e0a, + 0x1e0c, 0x1e0e, 0x1e10, 0x1e12, 0x1e14, 0x1e16, 0x1e18, 0x1e1a, 0x1e1c, + 0x1e1e, 0x1e20, 0x1e22, 0x1e24, 0x1e26, 0x1e28, 0x1e2a, 0x1e2c, 0x1e2e, + 0x1e30, 0x1e32, 0x1e34, 0x1e36, 0x1e38, 0x1e3a, 0x1e3c, 0x1e3e, 0x1e40, + 0x1e42, 0x1e44, 0x1e46, 0x1e48, 0x1e4a, 0x1e4c, 0x1e4e, 0x1e50, 0x1e52, + 0x1e54, 0x1e56, 0x1e58, 0x1e5a, 0x1e5c, 0x1e5e, 0x1e60, 0x1e62, 0x1e64, + 0x1e66, 0x1e68, 0x1e6a, 0x1e6c, 0x1e6e, 0x1e70, 0x1e72, 0x1e74, 0x1e76, + 0x1e78, 0x1e7a, 0x1e7c, 0x1e7e, 0x1e80, 0x1e82, 0x1e84, 0x1e86, 0x1e88, + 0x1e8a, 0x1e8c, 0x1e8e, 0x1e90, 0x1e92, 0x1e94, 0x1e9e, 0x1ea0, 0x1ea2, + 0x1ea4, 0x1ea6, 0x1ea8, 0x1eaa, 0x1eac, 0x1eae, 0x1eb0, 0x1eb2, 0x1eb4, + 0x1eb6, 0x1eb8, 0x1eba, 0x1ebc, 0x1ebe, 0x1ec0, 0x1ec2, 0x1ec4, 0x1ec6, + 0x1ec8, 0x1eca, 0x1ecc, 0x1ece, 0x1ed0, 0x1ed2, 0x1ed4, 0x1ed6, 0x1ed8, + 0x1eda, 0x1edc, 0x1ede, 0x1ee0, 0x1ee2, 0x1ee4, 0x1ee6, 0x1ee8, 0x1eea, + 0x1eec, 0x1eee, 0x1ef0, 0x1ef2, 0x1ef4, 0x1ef6, 0x1ef8, 0x1efa, 0x1efc, + 0x1efe, 0x1f59, 0x1f5b, 0x1f5d, 0x1f5f, 0x2102, 0x2107, 0x2115, 0x2124, + 0x2126, 0x2128, 0x213e, 0x213f, 0x2145, 0x2183, 0x2c60, 0x2c67, 0x2c69, + 0x2c6b, 0x2c72, 0x2c75, 0x2c82, 0x2c84, 0x2c86, 0x2c88, 0x2c8a, 0x2c8c, + 0x2c8e, 0x2c90, 0x2c92, 0x2c94, 0x2c96, 0x2c98, 0x2c9a, 0x2c9c, 0x2c9e, + 0x2ca0, 0x2ca2, 0x2ca4, 0x2ca6, 0x2ca8, 0x2caa, 0x2cac, 0x2cae, 0x2cb0, + 0x2cb2, 0x2cb4, 0x2cb6, 0x2cb8, 0x2cba, 0x2cbc, 0x2cbe, 0x2cc0, 0x2cc2, + 0x2cc4, 0x2cc6, 0x2cc8, 0x2cca, 0x2ccc, 0x2cce, 0x2cd0, 0x2cd2, 0x2cd4, + 0x2cd6, 0x2cd8, 0x2cda, 0x2cdc, 0x2cde, 0x2ce0, 0x2ce2, 0x2ceb, 0x2ced, + 0x2cf2, 0xa640, 0xa642, 0xa644, 0xa646, 0xa648, 0xa64a, 0xa64c, 0xa64e, + 0xa650, 0xa652, 0xa654, 0xa656, 0xa658, 0xa65a, 0xa65c, 0xa65e, 0xa660, + 0xa662, 0xa664, 0xa666, 0xa668, 0xa66a, 0xa66c, 0xa680, 0xa682, 0xa684, + 0xa686, 0xa688, 0xa68a, 0xa68c, 0xa68e, 0xa690, 0xa692, 0xa694, 0xa696, + 0xa698, 0xa69a, 0xa722, 0xa724, 0xa726, 0xa728, 0xa72a, 0xa72c, 0xa72e, + 0xa732, 0xa734, 0xa736, 0xa738, 0xa73a, 0xa73c, 0xa73e, 0xa740, 0xa742, + 0xa744, 0xa746, 0xa748, 0xa74a, 0xa74c, 0xa74e, 0xa750, 0xa752, 0xa754, + 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, 0xa7b0, + 0xa7b1 #if TCL_UTF_MAX > 4 ,0x1d49c, 0x1d49e, 0x1d49f, 0x1d4a2, 0x1d4a5, 0x1d4a6, 0x1d504, 0x1d505, 0x1d538, 0x1d539, 0x1d546, 0x1d7ca @@ -570,34 +595,34 @@ static const chr upperCharTable[] = { */ static const crange graphRangeTable[] = { - {0x21, 0x7e}, {0xa1, 0xac}, {0xae, 0x377}, {0x37a, 0x37e}, - {0x384, 0x38a}, {0x38e, 0x3a1}, {0x3a3, 0x527}, {0x531, 0x556}, - {0x559, 0x55f}, {0x561, 0x587}, {0x591, 0x5c7}, {0x5d0, 0x5ea}, - {0x5f0, 0x5f4}, {0x606, 0x61b}, {0x61e, 0x6dc}, {0x6de, 0x70d}, - {0x710, 0x74a}, {0x74d, 0x7b1}, {0x7c0, 0x7fa}, {0x800, 0x82d}, - {0x830, 0x83e}, {0x840, 0x85b}, {0x8a2, 0x8ac}, {0x8e4, 0x8fe}, - {0x900, 0x977}, {0x979, 0x97f}, {0x981, 0x983}, {0x985, 0x98c}, - {0x993, 0x9a8}, {0x9aa, 0x9b0}, {0x9b6, 0x9b9}, {0x9bc, 0x9c4}, - {0x9cb, 0x9ce}, {0x9df, 0x9e3}, {0x9e6, 0x9fb}, {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}, {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}, - {0xc01, 0xc03}, {0xc05, 0xc0c}, {0xc0e, 0xc10}, {0xc12, 0xc28}, - {0xc2a, 0xc33}, {0xc35, 0xc39}, {0xc3d, 0xc44}, {0xc46, 0xc48}, - {0xc4a, 0xc4d}, {0xc60, 0xc63}, {0xc66, 0xc6f}, {0xc78, 0xc7f}, - {0xc85, 0xc8c}, {0xc8e, 0xc90}, {0xc92, 0xca8}, {0xcaa, 0xcb3}, - {0xcb5, 0xcb9}, {0xcbc, 0xcc4}, {0xcc6, 0xcc8}, {0xcca, 0xccd}, - {0xce0, 0xce3}, {0xce6, 0xcef}, {0xd05, 0xd0c}, {0xd0e, 0xd10}, - {0xd12, 0xd3a}, {0xd3d, 0xd44}, {0xd46, 0xd48}, {0xd4a, 0xd4e}, - {0xd60, 0xd63}, {0xd66, 0xd75}, {0xd79, 0xd7f}, {0xd85, 0xd96}, - {0xd9a, 0xdb1}, {0xdb3, 0xdbb}, {0xdc0, 0xdc6}, {0xdcf, 0xdd4}, - {0xdd8, 0xddf}, {0xdf2, 0xdf4}, {0xe01, 0xe3a}, {0xe3f, 0xe5b}, + {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}, {0x8a0, 0x8b2}, + {0x8e4, 0x983}, {0x985, 0x98c}, {0x993, 0x9a8}, {0x9aa, 0x9b0}, + {0x9b6, 0x9b9}, {0x9bc, 0x9c4}, {0x9cb, 0x9ce}, {0x9df, 0x9e3}, + {0x9e6, 0x9fb}, {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}, + {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}, {0xc60, 0xc63}, {0xc66, 0xc6f}, + {0xc78, 0xc7f}, {0xc81, 0xc83}, {0xc85, 0xc8c}, {0xc8e, 0xc90}, + {0xc92, 0xca8}, {0xcaa, 0xcb3}, {0xcb5, 0xcb9}, {0xcbc, 0xcc4}, + {0xcc6, 0xcc8}, {0xcca, 0xccd}, {0xce0, 0xce3}, {0xce6, 0xcef}, + {0xd01, 0xd03}, {0xd05, 0xd0c}, {0xd0e, 0xd10}, {0xd12, 0xd3a}, + {0xd3d, 0xd44}, {0xd46, 0xd48}, {0xd4a, 0xd4e}, {0xd60, 0xd63}, + {0xd66, 0xd75}, {0xd79, 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}, @@ -606,105 +631,123 @@ static const crange graphRangeTable[] = { {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, 0x13f4}, {0x1400, 0x167f}, {0x1681, 0x169c}, {0x16a0, 0x16f0}, + {0x13a0, 0x13f4}, {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, 0x191c}, {0x1920, 0x192b}, + {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}, - {0x1b00, 0x1b4b}, {0x1b50, 0x1b7c}, {0x1b80, 0x1bf3}, {0x1bfc, 0x1c37}, - {0x1c3b, 0x1c49}, {0x1c4d, 0x1c7f}, {0x1cc0, 0x1cc7}, {0x1cd0, 0x1cf6}, - {0x1d00, 0x1de6}, {0x1dfc, 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, 0x20ba}, {0x20d0, 0x20f0}, - {0x2100, 0x2189}, {0x2190, 0x23f3}, {0x2400, 0x2426}, {0x2440, 0x244a}, - {0x2460, 0x26ff}, {0x2701, 0x2b4c}, {0x2b50, 0x2b59}, {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, 0x2e3b}, {0x2e80, 0x2e99}, {0x2e9b, 0x2ef3}, - {0x2f00, 0x2fd5}, {0x2ff0, 0x2ffb}, {0x3001, 0x303f}, {0x3041, 0x3096}, - {0x3099, 0x30ff}, {0x3105, 0x312d}, {0x3131, 0x318e}, {0x3190, 0x31ba}, - {0x31c0, 0x31e3}, {0x31f0, 0x321e}, {0x3220, 0x32fe}, {0x3300, 0x4db5}, - {0x4dc0, 0x9fcc}, {0xa000, 0xa48c}, {0xa490, 0xa4c6}, {0xa4d0, 0xa62b}, - {0xa640, 0xa697}, {0xa69f, 0xa6f7}, {0xa700, 0xa78e}, {0xa790, 0xa793}, - {0xa7a0, 0xa7aa}, {0xa7f8, 0xa82b}, {0xa830, 0xa839}, {0xa840, 0xa877}, - {0xa880, 0xa8c4}, {0xa8ce, 0xa8d9}, {0xa8e0, 0xa8fb}, {0xa900, 0xa953}, - {0xa95f, 0xa97c}, {0xa980, 0xa9cd}, {0xa9cf, 0xa9d9}, {0xaa00, 0xaa36}, - {0xaa40, 0xaa4d}, {0xaa50, 0xaa59}, {0xaa5c, 0xaa7b}, {0xaa80, 0xaac2}, - {0xaadb, 0xaaf6}, {0xab01, 0xab06}, {0xab09, 0xab0e}, {0xab11, 0xab16}, - {0xab20, 0xab26}, {0xab28, 0xab2e}, {0xabc0, 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, 0xfe26}, - {0xfe30, 0xfe52}, {0xfe54, 0xfe66}, {0xfe68, 0xfe6b}, {0xfe70, 0xfe74}, - {0xfe76, 0xfefc}, {0xff01, 0xffbe}, {0xffc2, 0xffc7}, {0xffca, 0xffcf}, - {0xffd2, 0xffd7}, {0xffda, 0xffdc}, {0xffe0, 0xffe6}, {0xffe8, 0xffee} + {0x1ab0, 0x1abe}, {0x1b00, 0x1b4b}, {0x1b50, 0x1b7c}, {0x1b80, 0x1bf3}, + {0x1bfc, 0x1c37}, {0x1c3b, 0x1c49}, {0x1c4d, 0x1c7f}, {0x1cc0, 0x1cc7}, + {0x1cd0, 0x1cf6}, {0x1d00, 0x1df5}, {0x1dfc, 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, 0x20bd}, + {0x20d0, 0x20f0}, {0x2100, 0x2189}, {0x2190, 0x23fa}, {0x2400, 0x2426}, + {0x2440, 0x244a}, {0x2460, 0x2b73}, {0x2b76, 0x2b95}, {0x2b98, 0x2bb9}, + {0x2bbd, 0x2bc8}, {0x2bca, 0x2bd1}, {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, 0x2e42}, {0x2e80, 0x2e99}, {0x2e9b, 0x2ef3}, {0x2f00, 0x2fd5}, + {0x2ff0, 0x2ffb}, {0x3001, 0x303f}, {0x3041, 0x3096}, {0x3099, 0x30ff}, + {0x3105, 0x312d}, {0x3131, 0x318e}, {0x3190, 0x31ba}, {0x31c0, 0x31e3}, + {0x31f0, 0x321e}, {0x3220, 0x32fe}, {0x3300, 0x4db5}, {0x4dc0, 0x9fcc}, + {0xa000, 0xa48c}, {0xa490, 0xa4c6}, {0xa4d0, 0xa62b}, {0xa640, 0xa69d}, + {0xa69f, 0xa6f7}, {0xa700, 0xa78e}, {0xa790, 0xa7ad}, {0xa7f7, 0xa82b}, + {0xa830, 0xa839}, {0xa840, 0xa877}, {0xa880, 0xa8c4}, {0xa8ce, 0xa8d9}, + {0xa8e0, 0xa8fb}, {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, 0xab5f}, {0xabc0, 0xabed}, {0xabf0, 0xabf9}, {0xac00, 0xd7a3}, + {0xd7b0, 0xd7c6}, {0xd7cb, 0xd7fb}, {0xdc00, 0xdc3e}, {0xdc40, 0xdc7e}, + {0xdc80, 0xdcbe}, {0xdcc0, 0xdcfe}, {0xdd80, 0xddbe}, {0xddc0, 0xddfe}, + {0xde80, 0xdebe}, {0xdec0, 0xdefe}, {0xdf00, 0xdf3e}, {0xdf40, 0xdf7e}, + {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, 0xfe2d}, {0xfe30, 0xfe52}, {0xfe54, 0xfe66}, {0xfe68, 0xfe6b}, + {0xfe70, 0xfe74}, {0xfe76, 0xfefc}, {0xff01, 0xffbe}, {0xffc2, 0xffc7}, + {0xffca, 0xffcf}, {0xffd2, 0xffd7}, {0xffda, 0xffdc}, {0xffe0, 0xffe6}, + {0xffe8, 0xffee} #if TCL_UTF_MAX > 4 ,{0x10000, 0x1000b}, {0x1000d, 0x10026}, {0x10028, 0x1003a}, {0x1003f, 0x1004d}, {0x10050, 0x1005d}, {0x10080, 0x100fa}, {0x10100, 0x10102}, {0x10107, 0x10133}, - {0x10137, 0x1018a}, {0x10190, 0x1019b}, {0x101d0, 0x101fd}, {0x10280, 0x1029c}, - {0x102a0, 0x102d0}, {0x10300, 0x1031e}, {0x10320, 0x10323}, {0x10330, 0x1034a}, - {0x10380, 0x1039d}, {0x1039f, 0x103c3}, {0x103c8, 0x103d5}, {0x10400, 0x1049d}, - {0x104a0, 0x104a9}, {0x10800, 0x10805}, {0x1080a, 0x10835}, {0x1083f, 0x10855}, - {0x10857, 0x1085f}, {0x10900, 0x1091b}, {0x1091f, 0x10939}, {0x10980, 0x109b7}, - {0x10a00, 0x10a03}, {0x10a0c, 0x10a13}, {0x10a15, 0x10a17}, {0x10a19, 0x10a33}, - {0x10a38, 0x10a3a}, {0x10a3f, 0x10a47}, {0x10a50, 0x10a58}, {0x10a60, 0x10a7f}, - {0x10b00, 0x10b35}, {0x10b39, 0x10b55}, {0x10b58, 0x10b72}, {0x10b78, 0x10b7f}, - {0x10c00, 0x10c48}, {0x10e60, 0x10e7e}, {0x11000, 0x1104d}, {0x11052, 0x1106f}, - {0x11080, 0x110bc}, {0x110be, 0x110c1}, {0x110d0, 0x110e8}, {0x110f0, 0x110f9}, - {0x11100, 0x11134}, {0x11136, 0x11143}, {0x11180, 0x111c8}, {0x111d0, 0x111d9}, - {0x11680, 0x116b7}, {0x116c0, 0x116c9}, {0x12000, 0x1236e}, {0x12400, 0x12462}, - {0x12470, 0x12473}, {0x13000, 0x1342e}, {0x16800, 0x16a38}, {0x16f00, 0x16f44}, - {0x16f50, 0x16f7e}, {0x16f8f, 0x16f9f}, {0x1d000, 0x1d0f5}, {0x1d100, 0x1d126}, - {0x1d129, 0x1d172}, {0x1d17b, 0x1d1dd}, {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, 0x1d7ff}, {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, 0x1f0be}, {0x1f0c1, 0x1f0cf}, - {0x1f0d1, 0x1f0df}, {0x1f100, 0x1f10a}, {0x1f110, 0x1f12e}, {0x1f130, 0x1f16b}, - {0x1f170, 0x1f19a}, {0x1f1e6, 0x1f202}, {0x1f210, 0x1f23a}, {0x1f240, 0x1f248}, - {0x1f300, 0x1f320}, {0x1f330, 0x1f335}, {0x1f337, 0x1f37c}, {0x1f380, 0x1f393}, - {0x1f3a0, 0x1f3c4}, {0x1f3c6, 0x1f3ca}, {0x1f3e0, 0x1f3f0}, {0x1f400, 0x1f43e}, - {0x1f442, 0x1f4f7}, {0x1f4f9, 0x1f4fc}, {0x1f500, 0x1f53d}, {0x1f540, 0x1f543}, - {0x1f550, 0x1f567}, {0x1f5fb, 0x1f640}, {0x1f645, 0x1f64f}, {0x1f680, 0x1f6c5}, - {0x1f700, 0x1f773}, {0x20000, 0x2a6d6}, {0x2a700, 0x2b734}, {0x2b740, 0x2b81d}, - {0x2f800, 0x2fa1d}, {0xe0100, 0xe01ef} + {0x10137, 0x1018c}, {0x10190, 0x1019b}, {0x101d0, 0x101fd}, {0x10280, 0x1029c}, + {0x102a0, 0x102d0}, {0x102e0, 0x102fb}, {0x10300, 0x10323}, {0x10330, 0x1034a}, + {0x10350, 0x1037a}, {0x10380, 0x1039d}, {0x1039f, 0x103c3}, {0x103c8, 0x103d5}, + {0x10400, 0x1049d}, {0x104a0, 0x104a9}, {0x10500, 0x10527}, {0x10530, 0x10563}, + {0x10600, 0x10736}, {0x10740, 0x10755}, {0x10760, 0x10767}, {0x10800, 0x10805}, + {0x1080a, 0x10835}, {0x1083f, 0x10855}, {0x10857, 0x1089e}, {0x108a7, 0x108af}, + {0x10900, 0x1091b}, {0x1091f, 0x10939}, {0x10980, 0x109b7}, {0x10a00, 0x10a03}, + {0x10a0c, 0x10a13}, {0x10a15, 0x10a17}, {0x10a19, 0x10a33}, {0x10a38, 0x10a3a}, + {0x10a3f, 0x10a47}, {0x10a50, 0x10a58}, {0x10a60, 0x10a9f}, {0x10ac0, 0x10ae6}, + {0x10aeb, 0x10af6}, {0x10b00, 0x10b35}, {0x10b39, 0x10b55}, {0x10b58, 0x10b72}, + {0x10b78, 0x10b91}, {0x10b99, 0x10b9c}, {0x10ba9, 0x10baf}, {0x10c00, 0x10c48}, + {0x10e60, 0x10e7e}, {0x11000, 0x1104d}, {0x11052, 0x1106f}, {0x1107f, 0x110bc}, + {0x110be, 0x110c1}, {0x110d0, 0x110e8}, {0x110f0, 0x110f9}, {0x11100, 0x11134}, + {0x11136, 0x11143}, {0x11150, 0x11176}, {0x11180, 0x111c8}, {0x111d0, 0x111da}, + {0x111e1, 0x111f4}, {0x11200, 0x11211}, {0x11213, 0x1123d}, {0x112b0, 0x112ea}, + {0x112f0, 0x112f9}, {0x11301, 0x11303}, {0x11305, 0x1130c}, {0x11313, 0x11328}, + {0x1132a, 0x11330}, {0x11335, 0x11339}, {0x1133c, 0x11344}, {0x1134b, 0x1134d}, + {0x1135d, 0x11363}, {0x11366, 0x1136c}, {0x11370, 0x11374}, {0x11480, 0x114c7}, + {0x114d0, 0x114d9}, {0x11580, 0x115b5}, {0x115b8, 0x115c9}, {0x11600, 0x11644}, + {0x11650, 0x11659}, {0x11680, 0x116b7}, {0x116c0, 0x116c9}, {0x118a0, 0x118f2}, + {0x11ac0, 0x11af8}, {0x12000, 0x12398}, {0x12400, 0x1246e}, {0x12470, 0x12474}, + {0x13000, 0x1342e}, {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}, {0x1bc00, 0x1bc6a}, {0x1bc70, 0x1bc7c}, + {0x1bc80, 0x1bc88}, {0x1bc90, 0x1bc99}, {0x1bc9c, 0x1bc9f}, {0x1d000, 0x1d0f5}, + {0x1d100, 0x1d126}, {0x1d129, 0x1d172}, {0x1d17b, 0x1d1dd}, {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, 0x1d7ff}, {0x1e800, 0x1e8c4}, {0x1e8c7, 0x1e8d6}, + {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, 0x1f19a}, + {0x1f1e6, 0x1f202}, {0x1f210, 0x1f23a}, {0x1f240, 0x1f248}, {0x1f300, 0x1f32c}, + {0x1f330, 0x1f37d}, {0x1f380, 0x1f3ce}, {0x1f3d4, 0x1f3f7}, {0x1f400, 0x1f4fe}, + {0x1f500, 0x1f54a}, {0x1f550, 0x1f579}, {0x1f57b, 0x1f5a3}, {0x1f5a5, 0x1f642}, + {0x1f645, 0x1f6cf}, {0x1f6e0, 0x1f6ec}, {0x1f6f0, 0x1f6f3}, {0x1f700, 0x1f773}, + {0x1f780, 0x1f7d4}, {0x1f800, 0x1f80b}, {0x1f810, 0x1f847}, {0x1f850, 0x1f859}, + {0x1f860, 0x1f887}, {0x1f890, 0x1f8ad}, {0x20000, 0x2a6d6}, {0x2a700, 0x2b734}, + {0x2b740, 0x2b81d}, {0x2f800, 0x2fa1d}, {0xe0100, 0xe01ef} #endif }; #define NUM_GRAPH_RANGE (sizeof(graphRangeTable)/sizeof(crange)) static const chr graphCharTable[] = { - 0x38c, 0x589, 0x58a, 0x58f, 0x85e, 0x8a0, 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, 0xc58, - 0xc59, 0xc82, 0xc83, 0xcd5, 0xcd6, 0xcde, 0xcf1, 0xcf2, 0xd02, - 0xd03, 0xd57, 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, 0xa9de, - 0xa9df, 0xfb3e, 0xfb40, 0xfb41, 0xfb43, 0xfb44, 0xfffc, 0xfffd + 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, 0xc58, 0xc59, 0xcd5, + 0xcd6, 0xcde, 0xcf1, 0xcf2, 0xd57, 0xd82, 0xd83, 0xdbd, 0xdca, + 0xdd6, 0xe81, 0xe82, 0xe84, 0xe87, 0xe88, 0xe8a, 0xe8d, 0xea5, + 0xea7, 0xeaa, 0xeab, 0xec6, 0x10c7, 0x10cd, 0x1258, 0x12c0, 0x1772, + 0x1773, 0x1940, 0x1cf8, 0x1cf9, 0x1f59, 0x1f5b, 0x1f5d, 0x2070, 0x2071, + 0x2d27, 0x2d2d, 0x2d6f, 0x2d70, 0xa7b0, 0xa7b1, 0xab64, 0xab65, 0xfb3e, + 0xfb40, 0xfb41, 0xfb43, 0xfb44, 0xfffc, 0xfffd #if TCL_UTF_MAX > 4 - ,0x1003c, 0x1003d, 0x10808, 0x10837, 0x10838, 0x1083c, 0x1093f, 0x109be, 0x109bf, - 0x10a05, 0x10a06, 0x1b000, 0x1b001, 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, 0x1eef0, 0x1eef1, 0x1f250, - 0x1f251, 0x1f440 + ,0x1003c, 0x1003d, 0x101a0, 0x1056f, 0x10808, 0x10837, 0x10838, 0x1083c, 0x1093f, + 0x109be, 0x109bf, 0x10a05, 0x10a06, 0x111cd, 0x1130f, 0x11310, 0x11332, 0x11333, + 0x11347, 0x11348, 0x11357, 0x118ff, 0x16a6e, 0x16a6f, 0x1b000, 0x1b001, 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, 0x1eef0, 0x1eef1, 0x1f250, 0x1f251 #endif }; diff --git a/generic/tclUniData.c b/generic/tclUniData.c index a0d4ccc..78e7d17 100644 --- a/generic/tclUniData.c +++ b/generic/tclUniData.c @@ -30,35 +30,35 @@ static const unsigned short pageMap[] = { 1120, 1152, 1184, 1216, 1248, 1280, 1312, 1344, 1376, 1408, 1344, 1344, 1440, 1472, 1504, 1536, 1568, 1344, 1344, 1600, 1632, 1664, 1696, 1728, 1760, 1792, 1792, 1824, 1792, 1856, 1888, 1920, 1952, 1984, 2016, 2048, - 2080, 2112, 2144, 2176, 2208, 2240, 2272, 2304, 2336, 2368, 2016, 2400, - 2432, 2464, 2496, 2528, 2560, 2592, 2624, 2656, 2688, 2720, 2752, 2784, - 2816, 2848, 2752, 2880, 2912, 2944, 2976, 3008, 3040, 3072, 3104, 3136, - 3168, 1792, 3200, 3232, 3264, 1792, 3296, 3328, 3360, 3392, 3424, 3456, - 3488, 1792, 1344, 3520, 3552, 3584, 3616, 3648, 3680, 3712, 1344, 1344, - 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 3744, 1344, 3776, 3808, - 3840, 1344, 3872, 1344, 3904, 3936, 3968, 1344, 1344, 4000, 4032, 1344, + 2080, 2112, 2144, 2176, 2208, 2240, 2272, 2304, 2336, 2368, 2400, 2432, + 2464, 2496, 2528, 2560, 2592, 2624, 2656, 2688, 2720, 2752, 2784, 2816, + 2848, 2880, 2784, 2912, 2944, 2976, 3008, 3040, 3072, 3104, 3136, 3168, + 3200, 1792, 3232, 3264, 3296, 1792, 3328, 3360, 3392, 3424, 3456, 3488, + 3520, 1792, 1344, 3552, 3584, 3616, 3648, 3680, 3712, 3744, 1344, 1344, + 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 3776, 1344, 3808, 3840, + 3872, 1344, 3904, 1344, 3936, 3968, 4000, 1344, 1344, 4032, 4064, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, - 1344, 1344, 1344, 1344, 1344, 4064, 4096, 1344, 1344, 4128, 4160, 4192, - 4224, 4256, 1344, 4288, 4320, 4352, 4384, 1344, 4416, 4448, 1344, 4480, - 1344, 4512, 4544, 4576, 4608, 4640, 1344, 4672, 4704, 4736, 4768, 1344, - 4800, 4832, 4864, 4896, 1792, 1792, 4928, 4960, 4992, 5024, 5056, 5088, - 1344, 5120, 1344, 5152, 5184, 5216, 1792, 1792, 5248, 5280, 5312, 5344, - 5376, 5408, 5440, 5376, 704, 5472, 224, 224, 224, 224, 5504, 224, 224, - 224, 5536, 5568, 5600, 5632, 5664, 5696, 5728, 5760, 5792, 5824, 5856, - 5888, 5920, 5952, 5984, 6016, 6048, 6080, 6112, 6144, 6176, 6208, 6240, - 6272, 6304, 6304, 6304, 6304, 6304, 6304, 6304, 6304, 6336, 6368, 4736, - 6400, 6432, 6464, 6496, 6528, 4736, 6560, 6592, 6624, 6656, 6688, 6720, - 6752, 4736, 4736, 4736, 4736, 4736, 6784, 6816, 6848, 4736, 4736, 4736, - 6880, 4736, 4736, 4736, 4736, 6912, 4736, 4736, 6944, 6976, 4736, 7008, - 7040, 4736, 4736, 4736, 4736, 4736, 4736, 4736, 4736, 6304, 6304, 6304, - 6304, 7072, 6304, 7104, 7136, 6304, 6304, 6304, 6304, 6304, 6304, 6304, - 6304, 4736, 7168, 7200, 1792, 1792, 1792, 1792, 1792, 7232, 7264, 7296, - 7328, 224, 224, 224, 7360, 7392, 7424, 1344, 7456, 7488, 7520, 7520, - 704, 7552, 7584, 1792, 1792, 7616, 4736, 4736, 7648, 4736, 4736, 4736, - 4736, 4736, 4736, 7680, 7712, 7744, 7776, 3104, 1344, 7808, 4032, 1344, - 7840, 7872, 7904, 1344, 1344, 7936, 7968, 4736, 8000, 8032, 8064, 8096, - 4736, 8064, 8128, 4736, 8032, 4736, 4736, 4736, 4736, 4736, 4736, 4736, - 4736, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 1344, 1344, 1344, 1344, 1344, 4096, 4128, 1344, 1344, 4160, 4192, 4224, + 4256, 4288, 1344, 4320, 4352, 4384, 4416, 1344, 4448, 4480, 1344, 4512, + 1344, 4544, 4576, 4608, 4640, 4672, 1344, 4704, 4736, 4768, 4800, 1344, + 4832, 4864, 4896, 4928, 1792, 1792, 4960, 4992, 5024, 5056, 5088, 5120, + 1344, 5152, 1344, 5184, 5216, 5248, 1792, 1792, 5280, 5312, 5344, 5376, + 5408, 5440, 5472, 5408, 704, 5504, 224, 224, 224, 224, 5536, 224, 224, + 224, 5568, 5600, 5632, 5664, 5696, 5728, 5760, 5792, 5824, 5856, 5888, + 5920, 5952, 5984, 6016, 6048, 6080, 6112, 6144, 6176, 6208, 6240, 6272, + 6304, 6336, 6336, 6336, 6336, 6336, 6336, 6336, 6336, 6368, 6400, 4768, + 6432, 6464, 6496, 6528, 6560, 4768, 6592, 6624, 6656, 6688, 6720, 6752, + 6784, 4768, 4768, 4768, 4768, 4768, 6816, 6848, 6880, 4768, 4768, 4768, + 6912, 4768, 4768, 4768, 4768, 4768, 4768, 4768, 6944, 6976, 4768, 7008, + 7040, 4768, 4768, 4768, 4768, 4768, 4768, 4768, 4768, 6336, 6336, 6336, + 6336, 7072, 6336, 7104, 7136, 6336, 6336, 6336, 6336, 6336, 6336, 6336, + 6336, 4768, 7168, 7200, 7232, 7264, 7296, 7328, 1792, 7360, 7392, 7424, + 7456, 224, 224, 224, 7488, 7520, 7552, 1344, 7584, 7616, 7648, 7648, + 704, 7680, 7712, 7744, 1792, 7776, 4768, 4768, 7808, 4768, 4768, 4768, + 4768, 4768, 4768, 7840, 7872, 7904, 7936, 3136, 1344, 7968, 4064, 1344, + 8000, 8032, 8064, 1344, 1344, 8096, 8128, 4768, 8160, 8192, 8224, 8256, + 4768, 8224, 8288, 4768, 8192, 4768, 4768, 4768, 4768, 4768, 4768, 4768, + 4768, 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, @@ -75,7 +75,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, 4512, 4736, 4736, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 1344, 1344, 4544, 4768, 4768, 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, @@ -129,16 +129,16 @@ 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, 8160, - 1792, 8192, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 8320, + 1792, 8352, 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, 8224, 4736, 8256, 5216, 1344, 1344, 1344, 1344, 1344, 1344, 1344, - 1344, 8288, 8320, 224, 8352, 8384, 1344, 1344, 8416, 8448, 8480, 224, - 8512, 8544, 8576, 1792, 8608, 8640, 8672, 1344, 8704, 8736, 8768, 8800, - 8832, 1632, 8864, 8896, 4544, 1888, 8928, 8960, 1792, 1344, 8992, 9024, - 9056, 1344, 9088, 9120, 9152, 9184, 9216, 1792, 1792, 1792, 1792, 1344, - 9248, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 1344, 8384, 4768, 8416, 5248, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 1344, 8448, 8480, 224, 8512, 8544, 1344, 1344, 8576, 8608, 8640, 224, + 8672, 8704, 8736, 1792, 8768, 8800, 8832, 1344, 8864, 8896, 8928, 8960, + 8992, 1632, 9024, 9056, 9088, 1888, 9120, 9152, 9184, 1344, 9216, 9248, + 9280, 1344, 9312, 9344, 9376, 9408, 9440, 9472, 9504, 1792, 1792, 1344, + 9536, 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, @@ -167,72 +167,72 @@ 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, 9280, 9312, 9344, 9376, 9376, 9376, 9376, 9376, 9376, 9376, - 9376, 9376, 9376, 9376, 9376, 9376, 9376, 9376, 9376, 9376, 9376, 9376, - 9376, 9376, 9376, 9376, 9376, 9376, 9376, 9376, 9376, 9376, 9376, 9376, - 9376, 9376, 9376, 9376, 9376, 9376, 9376, 9376, 9376, 9376, 9376, 9376, - 9376, 9376, 9376, 9376, 9376, 9376, 9376, 9376, 9376, 9376, 9376, 9376, - 9376, 9376, 9376, 9376, 9376, 9376, 9376, 9376, 9376, 9408, 9408, 9408, - 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, - 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, - 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, - 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, - 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, - 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, - 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, - 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, - 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, - 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, - 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, - 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, - 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, - 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, - 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, - 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, 9408, - 9408, 9408, 9408, 9408, 9408, 1344, 1344, 1344, 1344, 1344, 1344, 1344, - 1344, 1344, 1344, 1344, 9440, 1344, 1344, 9472, 1792, 9504, 9536, 9568, - 1344, 1344, 9600, 9632, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, - 1344, 1344, 9664, 9696, 1344, 9728, 1344, 9760, 9792, 9824, 9856, 9888, - 9920, 1344, 1344, 1344, 9952, 9984, 64, 10016, 10048, 10080, 10112, - 10144, 10176 + 1344, 1344, 9568, 9600, 9632, 9664, 9664, 9664, 9664, 9664, 9664, 9664, + 9664, 9664, 9664, 9664, 9664, 9664, 9664, 9664, 9664, 9664, 9664, 9664, + 9664, 9664, 9664, 9664, 9664, 9664, 9664, 9664, 9664, 9664, 9664, 9664, + 9664, 9664, 9664, 9664, 9664, 9664, 9664, 9664, 9664, 9664, 9664, 9664, + 9664, 9664, 9664, 9664, 9664, 9664, 9664, 9664, 9664, 9664, 9664, 9664, + 9664, 9664, 9664, 9664, 9664, 9664, 9664, 9664, 9664, 9696, 9696, 9696, + 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, + 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, + 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, + 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, + 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, + 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, + 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, + 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, + 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, + 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, + 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, + 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, + 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, + 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, + 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, + 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, + 9696, 9696, 9696, 9696, 9696, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 1344, 1344, 1344, 1344, 9728, 1344, 1344, 9760, 1792, 9792, 9824, 9856, + 1344, 1344, 9888, 9920, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 1344, 1344, 9952, 9984, 1344, 10016, 1344, 10048, 10080, 10112, 10144, + 10176, 10208, 1344, 1344, 1344, 10240, 10272, 64, 10304, 10336, 10368, + 4576, 10400, 10432 #if TCL_UTF_MAX > 3 - ,10208, 10240, 10272, 1792, 1344, 1344, 1344, 7968, 10304, 10336, 10368, - 10400, 10432, 1792, 10464, 10496, 1792, 1792, 1792, 1792, 4544, 1344, - 10528, 1792, 10112, 10560, 10592, 1792, 10624, 1344, 10656, 1792, 10688, - 10720, 10752, 1344, 10784, 10816, 1792, 1792, 1792, 1792, 1792, 1792, + ,10464, 10496, 10528, 1792, 1344, 1344, 1344, 8128, 10560, 10592, 10624, + 10656, 10688, 10720, 10752, 10784, 1792, 1792, 1792, 1792, 9088, 1344, + 10816, 10848, 1344, 10880, 10912, 10944, 10976, 1344, 11008, 1792, + 11040, 11072, 11104, 1344, 11136, 11168, 1792, 1792, 1344, 11200, 1344, + 11232, 1792, 1792, 1792, 1792, 1344, 1344, 1344, 1344, 1344, 1344, + 1344, 1344, 1344, 7616, 4544, 10048, 1792, 1792, 1792, 1792, 11264, + 11296, 11328, 11360, 4576, 11392, 1792, 1792, 11424, 11456, 1792, 1792, + 1344, 11488, 1792, 1792, 11520, 11552, 11584, 11616, 11648, 1792, 11680, + 11712, 1344, 11744, 11776, 11808, 11840, 11872, 1792, 1792, 1344, 1344, + 11904, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, + 1792, 1792, 1792, 1792, 1792, 1792, 11936, 1792, 1792, 1792, 1792, + 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 11968, 12000, 12032, + 12064, 5088, 12096, 12128, 12160, 12192, 12224, 12256, 12288, 5088, + 12320, 12352, 12384, 12416, 12448, 1792, 1792, 1792, 9984, 12480, 12512, + 2400, 2304, 12544, 12576, 1792, 1792, 1792, 1792, 1792, 1792, 1792, + 1792, 1344, 12608, 12640, 1792, 1792, 1792, 1792, 1792, 1344, 12672, + 12704, 1792, 1344, 12736, 12768, 1792, 1344, 12800, 11168, 1792, 1792, + 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, + 12832, 12864, 12896, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, + 1792, 1792, 1792, 1792, 1792, 1792, 1344, 12928, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 10848, 10880, 10912, - 1792, 1792, 1792, 1792, 1792, 10944, 10976, 1792, 1792, 1344, 11008, - 1792, 1792, 11040, 11072, 11104, 11136, 1792, 1792, 1792, 1792, 1344, - 11168, 11200, 11232, 1792, 1792, 1792, 1792, 1344, 1344, 11264, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 11296, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 11328, 11360, 11392, 11424, 5056, 11456, - 11488, 11520, 11552, 11584, 11616, 1792, 5056, 11648, 11680, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1344, 11712, 10816, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 1792, 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, 11744, 1792, 1792, - 1792, 1792, 10368, 10368, 10368, 11776, 1792, 1792, 1792, 1792, 1792, + 1344, 1344, 1344, 1344, 1344, 12928, 1792, 1792, 1792, 10624, 10624, + 10624, 12960, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 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, - 11744, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, + 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 12992, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, @@ -266,13 +266,13 @@ static const unsigned short pageMap[] = { 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1344, 1344, 1344, 1344, - 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, - 1344, 11808, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, + 1792, 1792, 1792, 1792, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 12928, 4576, + 13024, 1792, 1792, 9984, 13056, 1344, 13088, 13120, 13152, 13184, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1344, 1344, 11840, 11872, 11904, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, + 1792, 1792, 1344, 1344, 13216, 13248, 13280, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, @@ -314,8 +314,8 @@ static const unsigned short pageMap[] = { 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 11936, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, + 1792, 1792, 1792, 1792, 1792, 1792, 1792, 13312, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, @@ -323,6 +323,8 @@ static const unsigned short pageMap[] = { 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, + 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1344, 1344, 1344, 13344, + 13376, 13408, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, @@ -335,14 +337,14 @@ static const unsigned short pageMap[] = { 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, + 1792, 4768, 4768, 4768, 4768, 4768, 4768, 4768, 7840, 4768, 13440, + 4768, 13472, 13504, 13536, 13568, 1792, 4768, 4768, 13600, 1792, 1792, + 1792, 1792, 1792, 4768, 4768, 13632, 13664, 1792, 1792, 1792, 1792, + 13696, 13728, 13760, 13792, 13824, 13856, 13888, 13920, 13952, 13984, + 14016, 14048, 14080, 13696, 13728, 14112, 13792, 14144, 14176, 14208, + 13920, 14240, 14272, 14304, 14336, 14368, 14400, 14432, 14464, 14496, + 14528, 14560, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 4736, 4736, 4736, 4736, 4736, 4736, 4736, 7680, 4736, - 11968, 4736, 12000, 12032, 12064, 12096, 1792, 4736, 4736, 12128, 1792, - 1792, 1792, 1792, 1792, 4736, 4736, 12160, 12192, 1792, 1792, 1792, - 1792, 12224, 12256, 12288, 12320, 12352, 12384, 12416, 12448, 12480, - 12512, 12544, 12576, 12608, 12224, 12256, 12640, 12320, 12672, 12704, - 12736, 12448, 12768, 12800, 12832, 12864, 12896, 12928, 12960, 12992, - 13024, 13056, 13088, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, @@ -351,26 +353,24 @@ static const unsigned short pageMap[] = { 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, + 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1344, + 1344, 1344, 1344, 1344, 1344, 14592, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, + 14624, 14656, 14688, 14720, 14752, 14784, 1792, 14816, 1792, 1792, + 1792, 1792, 1792, 1792, 1792, 1792, 4768, 14848, 4768, 4768, 7808, + 14880, 14912, 7840, 14944, 14976, 4768, 14848, 15008, 1792, 1792, 15040, + 15072, 15008, 15104, 1792, 1792, 1792, 1792, 1792, 4768, 15136, 4768, + 13568, 4768, 4768, 15168, 15200, 4768, 4768, 4768, 4768, 4768, 4768, + 4768, 8192, 4768, 4768, 15232, 7776, 4768, 15264, 4768, 4768, 4768, + 4768, 15296, 4768, 4768, 4768, 15328, 15360, 4768, 4768, 4768, 7808, + 4768, 4768, 15392, 1792, 14848, 4768, 15424, 4768, 15456, 15488, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 13120, 13152, 13184, 13216, 13248, 13280, 1792, 13312, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 4736, 13344, 4736, 4736, 7648, - 13376, 13408, 1792, 13440, 13472, 4736, 13344, 13504, 1792, 1792, 13536, - 13568, 13504, 13600, 1792, 1792, 1792, 1792, 1792, 4736, 13632, 4736, - 13664, 7648, 4736, 13696, 13728, 4736, 8032, 13760, 4736, 4736, 4736, - 4736, 13792, 4736, 12096, 13824, 13856, 1792, 1792, 1792, 13888, 4736, - 4736, 13920, 1792, 4736, 4736, 13952, 1792, 4736, 4736, 4736, 7648, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1344, 1344, 1344, 1344, - 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 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, @@ -480,8 +480,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, 1344, 1344, 1344, 1344, 7488, 1792, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 7616, + 1792, 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, @@ -491,8 +492,8 @@ 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, 4000, 1344, 1344, - 1344, 1344, 1344, 1344, 10784, 1792, 1792, 1792, 1792, 1792, 1792, + 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 4032, 1344, + 1344, 1344, 1344, 1344, 1344, 11136, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, @@ -535,8 +536,8 @@ static const unsigned short pageMap[] = { 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, - 1344, 1344, 1344, 1344, 1344, 10784 + 1792, 1792, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 1344, 1344, 1344, 1344, 1344, 1344, 11136 #endif /* TCL_UTF_MAX > 3 */ }; @@ -577,324 +578,327 @@ static const unsigned char groupMap[] = { 21, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 21, 21, 21, 21, 21, 21, 55, 23, 24, 56, 57, 58, 58, 23, 24, 59, 60, 61, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 62, 63, 64, 65, - 66, 21, 67, 67, 21, 68, 21, 69, 21, 21, 21, 21, 67, 21, 21, 70, 21, - 71, 72, 21, 73, 74, 21, 75, 21, 21, 21, 74, 21, 76, 77, 21, 21, 78, - 21, 21, 21, 21, 21, 21, 21, 79, 21, 21, 80, 21, 21, 80, 21, 21, 21, - 21, 80, 81, 82, 82, 83, 21, 21, 21, 21, 21, 84, 21, 15, 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, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, - 85, 85, 85, 85, 85, 85, 85, 85, 11, 11, 11, 11, 85, 85, 85, 85, 85, - 85, 85, 85, 85, 85, 85, 85, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 85, 85, 85, 85, 85, 11, 11, 11, 11, 11, 11, 11, 85, - 11, 85, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, - 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, - 86, 86, 86, 86, 86, 87, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, - 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, - 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 23, 24, 23, - 24, 85, 11, 23, 24, 0, 0, 85, 42, 42, 42, 3, 0, 0, 0, 0, 0, 11, 11, - 88, 3, 89, 89, 89, 0, 90, 0, 91, 91, 21, 10, 10, 10, 10, 10, 10, 10, + 66, 21, 67, 67, 21, 68, 21, 69, 70, 21, 21, 21, 67, 71, 21, 72, 21, + 73, 74, 21, 75, 76, 21, 77, 78, 21, 21, 76, 21, 79, 80, 21, 21, 81, + 21, 21, 21, 21, 21, 21, 21, 82, 21, 21, 83, 21, 21, 83, 21, 21, 21, + 84, 83, 85, 86, 86, 87, 21, 21, 21, 21, 21, 88, 21, 15, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 89, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, 11, 11, 11, 11, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 90, 90, 90, 90, 90, 11, 11, 11, 11, 11, 11, 11, 90, + 11, 90, 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, 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, 92, 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, 23, 24, 23, + 24, 90, 11, 23, 24, 0, 0, 90, 42, 42, 42, 3, 93, 0, 0, 0, 0, 11, 11, + 94, 3, 95, 95, 95, 0, 96, 0, 97, 97, 21, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 0, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 92, 93, 93, 93, 21, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 94, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 95, 96, 96, 97, 98, 99, 100, 100, 100, 101, 102, 103, 23, 24, 23, + 10, 10, 10, 98, 99, 99, 99, 21, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 100, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 101, 102, 102, 103, 104, 105, 106, 106, 106, 107, 108, 109, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, - 23, 24, 23, 24, 104, 105, 106, 21, 107, 108, 7, 23, 24, 109, 23, 24, - 21, 54, 54, 54, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, - 110, 110, 110, 110, 110, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 23, 24, 23, 24, 23, 24, 110, 111, 112, 113, 114, 115, 7, 23, 24, 116, + 23, 24, 21, 54, 54, 54, 117, 117, 117, 117, 117, 117, 117, 117, 117, + 117, 117, 117, 117, 117, 117, 117, 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, + 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, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, - 105, 105, 105, 105, 23, 24, 14, 86, 86, 86, 86, 86, 111, 111, 23, 24, + 13, 13, 13, 13, 13, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, + 111, 111, 111, 111, 111, 111, 23, 24, 14, 91, 91, 91, 91, 91, 118, + 118, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, + 23, 24, 23, 24, 23, 24, 119, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, + 23, 24, 23, 24, 120, 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, 23, 24, 112, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, - 24, 113, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, - 24, 23, 24, 23, 24, 23, 24, 23, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 114, - 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, - 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, - 114, 114, 114, 114, 114, 114, 114, 114, 114, 0, 0, 85, 3, 3, 3, 3, - 3, 3, 0, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, - 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, - 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 21, 0, - 3, 8, 0, 0, 0, 0, 4, 0, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, - 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, - 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, - 8, 86, 3, 86, 86, 3, 86, 86, 3, 86, 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, 0, 7, 7, 7, 3, 3, - 4, 3, 3, 14, 14, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 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, - 85, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 86, 86, 86, 86, 86, 86, - 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 3, 3, 3, 3, 15, 15, 86, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 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, 86, 86, 86, - 86, 86, 86, 86, 17, 14, 86, 86, 86, 86, 86, 86, 85, 85, 86, 86, 14, - 86, 86, 86, 86, 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, 86, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 86, 86, 86, 86, 86, - 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, - 86, 86, 86, 86, 86, 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, 86, 86, 86, - 86, 86, 86, 86, 86, 86, 86, 86, 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, 86, 86, 86, 86, 86, 86, 86, 86, - 86, 85, 85, 14, 3, 3, 3, 85, 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, 86, - 86, 86, 86, 85, 86, 86, 86, 86, 86, 86, 86, 86, 86, 85, 86, 86, 86, - 85, 86, 86, 86, 86, 86, 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, 86, 86, 86, 0, 0, 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, 0, 0, 0, 15, 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, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, - 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 0, 86, 86, 86, 116, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 86, 116, 86, 15, 116, 116, 116, 86, 86, 86, 86, 86, 86, - 86, 86, 116, 116, 116, 116, 86, 116, 116, 15, 86, 86, 86, 86, 86, 86, - 86, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 86, 86, 3, 3, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 3, 85, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, - 15, 15, 15, 15, 0, 86, 116, 116, 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, 86, 15, 116, 116, 116, 86, - 86, 86, 86, 0, 0, 116, 116, 0, 0, 116, 116, 86, 15, 0, 0, 0, 0, 0, - 0, 0, 0, 116, 0, 0, 0, 0, 15, 15, 0, 15, 15, 15, 86, 86, 0, 0, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 15, 15, 4, 4, 18, 18, 18, 18, 18, 18, 14, 4, - 0, 0, 0, 0, 0, 86, 86, 116, 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, 86, 0, 116, 116, 116, 86, 86, 0, 0, - 0, 0, 86, 86, 0, 0, 86, 86, 86, 0, 0, 0, 86, 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, 86, 86, 15, 15, 15, 86, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 86, - 116, 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, 86, 15, 116, 116, 116, 86, 86, 86, 86, 86, 0, 86, 86, - 116, 0, 116, 116, 86, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 15, 15, 86, 86, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 3, 4, - 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, 0, 15, 15, 0, 15, 15, 15, 15, - 15, 0, 0, 86, 15, 116, 86, 116, 86, 86, 86, 86, 0, 0, 116, 116, 0, - 0, 116, 116, 86, 0, 0, 0, 0, 0, 0, 0, 0, 86, 116, 0, 0, 0, 0, 15, 15, - 0, 15, 15, 15, 86, 86, 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, 86, 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, 116, - 116, 86, 116, 116, 0, 0, 0, 116, 116, 116, 0, 116, 116, 116, 86, 0, - 0, 15, 0, 0, 0, 0, 0, 0, 116, 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, 0, 116, 116, 116, 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, 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, 0, 15, 86, 86, - 86, 116, 116, 116, 116, 0, 86, 86, 86, 0, 86, 86, 86, 86, 0, 0, 0, - 0, 0, 0, 0, 86, 86, 0, 15, 15, 0, 0, 0, 0, 0, 0, 15, 15, 86, 86, 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, 0, 0, 116, 116, 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, 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, 86, 15, 116, 86, 116, - 116, 116, 116, 116, 0, 86, 116, 116, 0, 116, 116, 86, 86, 0, 0, 0, - 0, 0, 0, 0, 116, 116, 0, 0, 0, 0, 0, 0, 0, 15, 0, 15, 15, 86, 86, 0, - 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 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, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 15, 116, - 116, 116, 86, 86, 86, 86, 0, 116, 116, 116, 0, 116, 116, 116, 86, 15, - 0, 0, 0, 0, 0, 0, 0, 0, 116, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 86, 86, - 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 18, 18, 18, 18, 18, 18, 0, 0, 0, - 14, 15, 15, 15, 15, 15, 15, 0, 0, 116, 116, 0, 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, - 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 0, - 0, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 86, 0, 0, 0, 0, 116, 116, 116, - 86, 86, 86, 0, 86, 0, 116, 116, 116, 116, 116, 116, 116, 116, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 116, 116, 3, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 24, 23, 24, 0, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 0, + 0, 90, 3, 3, 3, 3, 3, 3, 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, 21, 0, 3, 8, 0, 0, 14, 14, 4, 0, 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, 8, 91, 3, 91, 91, 3, 91, 91, 3, 91, 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, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 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, 90, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 3, 3, 3, 3, 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, 15, 15, 15, + 15, 3, 15, 91, 91, 91, 91, 91, 91, 91, 17, 14, 91, 91, 91, 91, 91, + 91, 90, 90, 91, 91, 14, 91, 91, 91, 91, 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, 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, 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, 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, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 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, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 90, 90, 14, 3, 3, 3, 90, 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, 91, 91, 91, 91, 90, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 90, 91, 91, 91, 90, 91, 91, 91, 91, 91, 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, 91, + 91, 91, 0, 0, 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, 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, 0, 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, 123, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 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, 123, 91, 15, 123, 123, + 123, 91, 91, 91, 91, 91, 91, 91, 91, 123, 123, 123, 123, 91, 123, 123, + 15, 91, 91, 91, 91, 91, 91, 91, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 91, 91, 3, 3, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 3, 90, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 91, 123, 123, 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, + 91, 15, 123, 123, 123, 91, 91, 91, 91, 0, 0, 123, 123, 0, 0, 123, 123, + 91, 15, 0, 0, 0, 0, 0, 0, 0, 0, 123, 0, 0, 0, 0, 15, 15, 0, 15, 15, + 15, 91, 91, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 15, 15, 4, 4, 18, 18, + 18, 18, 18, 18, 14, 4, 0, 0, 0, 0, 0, 91, 91, 123, 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, 91, 0, 123, + 123, 123, 91, 91, 0, 0, 0, 0, 91, 91, 0, 0, 91, 91, 91, 0, 0, 0, 91, + 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, 91, 91, 15, 15, 15, 91, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 91, 91, 123, 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, 91, 15, 123, 123, 123, 91, + 91, 91, 91, 91, 0, 91, 91, 123, 0, 123, 123, 91, 0, 0, 15, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 91, 91, 0, 0, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 91, 123, 123, 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, 91, 15, 123, 91, 123, 91, 91, 91, 91, 0, + 0, 123, 123, 0, 0, 123, 123, 91, 0, 0, 0, 0, 0, 0, 0, 0, 91, 123, 0, + 0, 0, 0, 15, 15, 0, 15, 15, 15, 91, 91, 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, 91, 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, 123, 123, 91, 123, 123, 0, 0, 0, 123, 123, 123, 0, 123, + 123, 123, 91, 0, 0, 15, 0, 0, 0, 0, 0, 0, 123, 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, 91, 123, 123, 123, 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, 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, 91, 91, 91, 123, 123, 123, 123, 0, 91, 91, 91, 0, 91, + 91, 91, 91, 0, 0, 0, 0, 0, 0, 0, 91, 91, 0, 15, 15, 0, 0, 0, 0, 0, + 0, 15, 15, 91, 91, 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, 0, 91, 123, 123, 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, 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, 91, 15, 123, 91, 123, 123, 123, 123, 123, 0, 91, 123, 123, 0, 123, + 123, 91, 91, 0, 0, 0, 0, 0, 0, 0, 123, 123, 0, 0, 0, 0, 0, 0, 0, 15, + 0, 15, 15, 91, 91, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 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, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 86, 15, 15, 86, 86, 86, 86, 86, 86, 86, 0, 0, 0, 0, - 4, 15, 15, 15, 15, 15, 15, 85, 86, 86, 86, 86, 86, 86, 86, 86, 3, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 3, 3, 0, 0, 0, 0, 0, 15, 15, 0, 15, 0, 0, - 15, 15, 0, 15, 0, 0, 15, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 0, 15, 15, - 15, 15, 15, 15, 15, 0, 15, 15, 15, 0, 15, 0, 15, 0, 0, 15, 15, 0, 15, - 15, 15, 15, 86, 15, 15, 86, 86, 86, 86, 86, 86, 0, 86, 86, 15, 0, 0, - 15, 15, 15, 15, 15, 0, 85, 0, 86, 86, 86, 86, 86, 86, 0, 0, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 0, 0, 15, 15, 15, 15, 15, 14, 14, 14, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 14, 3, 14, 14, 14, 86, 86, 14, - 14, 14, 14, 14, 14, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 14, 86, 14, 86, 14, 86, 5, 6, 5, 6, 116, 116, 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, 0, 0, 0, 0, 86, 86, 86, 86, - 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 116, 86, 86, 86, 86, 86, 3, - 86, 86, 15, 15, 15, 15, 15, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, - 86, 0, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, - 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, - 86, 86, 86, 86, 0, 14, 14, 14, 14, 14, 14, 14, 14, 86, 14, 14, 14, - 14, 14, 14, 0, 14, 14, 3, 3, 3, 3, 3, 14, 14, 14, 14, 3, 3, 0, 0, 0, - 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 116, 116, 86, 86, - 86, 86, 116, 86, 86, 86, 86, 86, 86, 116, 86, 86, 116, 116, 86, 86, - 15, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 3, 3, 3, 3, 3, 3, 15, 15, 15, 15, - 15, 15, 116, 116, 86, 86, 15, 15, 15, 15, 86, 86, 86, 15, 116, 116, - 116, 15, 15, 116, 116, 116, 116, 116, 116, 116, 15, 15, 15, 86, 86, - 86, 86, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 86, 116, - 116, 86, 86, 116, 116, 116, 116, 116, 116, 86, 15, 116, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 116, 116, 116, 86, 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, 0, 117, 0, 0, 0, 0, 0, 117, 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, 85, 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, 0, 0, 15, 123, 123, 123, 91, 91, 91, 91, 0, 123, 123, 123, + 0, 123, 123, 123, 91, 15, 0, 0, 0, 0, 0, 0, 0, 0, 123, 0, 0, 0, 0, + 0, 0, 0, 0, 15, 15, 91, 91, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 18, + 18, 18, 18, 18, 18, 0, 0, 0, 14, 15, 15, 15, 15, 15, 15, 0, 0, 123, + 123, 0, 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, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 0, 15, 0, 0, 15, 15, 15, 15, 15, 15, 15, 0, 0, + 0, 91, 0, 0, 0, 0, 123, 123, 123, 91, 91, 91, 0, 91, 0, 123, 123, 123, + 123, 123, 123, 123, 123, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 0, 0, 123, 123, 3, 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, 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, 91, 91, + 91, 91, 91, 91, 91, 0, 0, 0, 0, 4, 15, 15, 15, 15, 15, 15, 90, 91, + 91, 91, 91, 91, 91, 91, 91, 3, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 3, 3, + 0, 0, 0, 0, 0, 15, 15, 0, 15, 0, 0, 15, 15, 0, 15, 0, 0, 15, 0, 0, + 0, 0, 0, 0, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, + 15, 0, 15, 0, 15, 0, 0, 15, 15, 0, 15, 15, 15, 15, 91, 15, 15, 91, + 91, 91, 91, 91, 91, 0, 91, 91, 15, 0, 0, 15, 15, 15, 15, 15, 0, 90, + 0, 91, 91, 91, 91, 91, 91, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, + 15, 15, 15, 15, 15, 14, 14, 14, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 14, 3, 14, 14, 14, 91, 91, 14, 14, 14, 14, 14, 14, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 14, 91, + 14, 91, 14, 91, 5, 6, 5, 6, 123, 123, 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, 15, 15, 0, 0, 86, 86, 86, 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, 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, 8, 15, 15, 15, + 15, 15, 15, 0, 0, 0, 0, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 123, 91, 91, 91, 91, 91, 3, 91, 91, 15, 15, 15, 15, 15, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 0, 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, 0, 14, 14, + 14, 14, 14, 14, 14, 14, 91, 14, 14, 14, 14, 14, 14, 0, 14, 14, 3, 3, + 3, 3, 3, 14, 14, 14, 14, 3, 3, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 123, 123, 91, 91, 91, 91, 123, 91, 91, 91, 91, + 91, 91, 123, 91, 91, 123, 123, 91, 91, 15, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 3, 3, 3, 3, 3, 3, 15, 15, 15, 15, 15, 15, 123, 123, 91, 91, 15, + 15, 15, 15, 91, 91, 91, 15, 123, 123, 123, 15, 15, 123, 123, 123, 123, + 123, 123, 123, 15, 15, 15, 91, 91, 91, 91, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 91, 123, 123, 91, 91, 123, 123, 123, 123, + 123, 123, 91, 15, 123, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 123, 123, 123, + 91, 14, 14, 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, 124, 124, 124, 124, 0, + 124, 0, 0, 0, 0, 0, 124, 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, 90, 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, 91, 91, 91, 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, 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, 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, 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, 118, 118, 118, 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, 15, 15, 15, 15, - 86, 86, 86, 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, 86, 86, 86, 3, 3, 0, + 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, 125, 125, 125, 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, 91, 91, 91, 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, 86, 86, 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, 86, 86, 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, 86, 86, - 116, 86, 86, 86, 86, 86, 86, 86, 116, 116, 116, 116, 116, 116, 116, - 116, 86, 116, 116, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 3, 3, - 3, 85, 3, 3, 3, 4, 15, 86, 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, 86, 86, 86, 17, 0, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 15, 15, 15, 85, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 91, 91, 91, 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, 91, 91, 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, 91, 91, 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, 91, 91, 123, 91, 91, 91, 91, + 91, 91, 91, 123, 123, 123, 123, 123, 123, 123, 123, 91, 123, 123, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 3, 3, 3, 90, 3, 3, 3, 4, 15, + 91, 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, 91, 91, 91, 17, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, + 0, 0, 0, 0, 15, 15, 15, 90, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 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, 15, 15, 15, 15, 86, 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, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 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, 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, + 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, 0, 0, 0, 86, 86, 86, 116, 116, 116, 116, - 86, 86, 116, 116, 116, 0, 0, 0, 0, 116, 116, 86, 116, 116, 116, 116, - 116, 116, 86, 86, 86, 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, 0, 91, 91, 91, 123, 123, 123, 123, 91, 91, 123, 123, + 123, 0, 0, 0, 0, 123, 123, 91, 123, 123, 123, 123, 123, 123, 91, 91, + 91, 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, - 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, 116, 116, 116, - 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, - 15, 15, 15, 15, 15, 15, 15, 116, 116, 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, + 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, 123, 123, 123, 123, 123, 123, 123, 123, + 123, 123, 123, 123, 123, 123, 123, 123, 123, 15, 15, 15, 15, 15, 15, + 15, 123, 123, 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, 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, 86, 86, 116, - 116, 86, 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, 116, 86, 116, 86, 86, 86, 86, 86, - 86, 86, 0, 86, 116, 86, 116, 116, 86, 86, 86, 86, 86, 86, 86, 86, 116, - 116, 116, 116, 116, 116, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 0, - 0, 86, 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, 85, 3, 3, - 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, - 86, 86, 86, 116, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 86, 116, 86, 86, 86, 86, 86, 116, 86, 116, 116, 116, 116, 116, 86, - 116, 116, 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, 86, 86, 86, 86, 86, 86, 86, 86, 86, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 0, 0, 0, 86, 86, 116, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 116, 86, 86, 86, 86, 116, 116, 86, 86, 116, 86, 116, 116, - 15, 15, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 86, 116, 86, 86, 116, 116, 116, 86, 116, 86, 86, 86, - 116, 116, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 15, 15, 15, 15, 116, - 116, 116, 116, 116, 116, 116, 116, 86, 86, 86, 86, 86, 86, 86, 86, - 116, 116, 86, 86, 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, 85, 85, 85, 85, 85, 85, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 86, 86, 86, 3, 86, 86, - 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 116, 86, 86, 86, 86, 86, - 86, 86, 15, 15, 15, 15, 86, 15, 15, 15, 15, 116, 116, 86, 15, 15, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 14, 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, 123, 123, 91, 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, 123, 91, 123, 91, 91, 91, 91, 91, 91, 91, 0, 91, 123, 91, 123, + 123, 91, 91, 91, 91, 91, 91, 91, 91, 123, 123, 123, 123, 123, 123, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 0, 0, 91, 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, 90, 3, 3, 3, 3, 3, 3, 0, 0, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 118, 0, 91, 91, 91, 91, + 123, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 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, 123, 91, + 91, 91, 91, 91, 123, 91, 123, 123, 123, 123, 123, 91, 123, 123, 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, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, + 91, 91, 123, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 123, + 91, 91, 91, 91, 123, 123, 91, 91, 123, 91, 91, 91, 15, 15, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 91, 123, 91, 91, 123, 123, 123, 91, 123, 91, 91, 91, 123, 123, 0, 0, + 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 15, 15, 15, 15, 123, 123, 123, 123, 123, + 123, 123, 123, 91, 91, 91, 91, 91, 91, 91, 91, 123, 123, 91, 91, 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, 90, 90, 90, 90, 90, 90, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 0, 0, 0, 0, 0, 0, 0, 0, 91, 91, 91, 3, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 123, 91, 91, 91, 91, 91, 91, 91, 15, 15, 15, + 15, 91, 15, 15, 15, 15, 123, 123, 91, 15, 15, 0, 91, 91, 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, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 85, - 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, - 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, - 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, - 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 85, 119, 21, 21, 21, 120, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 90, 126, 21, 21, 21, 127, 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, 85, 85, 85, 85, 85, 86, 86, 86, 86, - 86, 86, 86, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 86, 86, 86, 86, 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, 121, 21, - 21, 122, 21, 123, 123, 123, 123, 123, 123, 123, 123, 124, 124, 124, - 124, 124, 124, 124, 124, 123, 123, 123, 123, 123, 123, 0, 0, 124, 124, - 124, 124, 124, 124, 0, 0, 123, 123, 123, 123, 123, 123, 123, 123, 124, - 124, 124, 124, 124, 124, 124, 124, 123, 123, 123, 123, 123, 123, 123, - 123, 124, 124, 124, 124, 124, 124, 124, 124, 123, 123, 123, 123, 123, - 123, 0, 0, 124, 124, 124, 124, 124, 124, 0, 0, 21, 123, 21, 123, 21, - 123, 21, 123, 0, 124, 0, 124, 0, 124, 0, 124, 123, 123, 123, 123, 123, - 123, 123, 123, 124, 124, 124, 124, 124, 124, 124, 124, 125, 125, 126, - 126, 126, 126, 127, 127, 128, 128, 129, 129, 130, 130, 0, 0, 123, 123, - 123, 123, 123, 123, 123, 123, 131, 131, 131, 131, 131, 131, 131, 131, - 123, 123, 123, 123, 123, 123, 123, 123, 131, 131, 131, 131, 131, 131, - 131, 131, 123, 123, 123, 123, 123, 123, 123, 123, 131, 131, 131, 131, - 131, 131, 131, 131, 123, 123, 21, 132, 21, 0, 21, 21, 124, 124, 133, - 133, 134, 11, 135, 11, 11, 11, 21, 132, 21, 0, 21, 21, 136, 136, 136, - 136, 134, 11, 11, 11, 123, 123, 21, 21, 0, 0, 21, 21, 124, 124, 137, - 137, 0, 11, 11, 11, 123, 123, 21, 21, 21, 106, 21, 21, 124, 124, 138, - 138, 109, 11, 11, 11, 0, 0, 21, 132, 21, 0, 21, 21, 139, 139, 140, - 140, 134, 11, 11, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 17, 17, 17, 17, + 21, 21, 21, 90, 90, 90, 90, 90, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 0, 0, 0, 0, 0, + 0, 91, 91, 91, 91, 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, 128, 21, + 21, 129, 21, 130, 130, 130, 130, 130, 130, 130, 130, 131, 131, 131, + 131, 131, 131, 131, 131, 130, 130, 130, 130, 130, 130, 0, 0, 131, 131, + 131, 131, 131, 131, 0, 0, 130, 130, 130, 130, 130, 130, 130, 130, 131, + 131, 131, 131, 131, 131, 131, 131, 130, 130, 130, 130, 130, 130, 130, + 130, 131, 131, 131, 131, 131, 131, 131, 131, 130, 130, 130, 130, 130, + 130, 0, 0, 131, 131, 131, 131, 131, 131, 0, 0, 21, 130, 21, 130, 21, + 130, 21, 130, 0, 131, 0, 131, 0, 131, 0, 131, 130, 130, 130, 130, 130, + 130, 130, 130, 131, 131, 131, 131, 131, 131, 131, 131, 132, 132, 133, + 133, 133, 133, 134, 134, 135, 135, 136, 136, 137, 137, 0, 0, 130, 130, + 130, 130, 130, 130, 130, 130, 138, 138, 138, 138, 138, 138, 138, 138, + 130, 130, 130, 130, 130, 130, 130, 130, 138, 138, 138, 138, 138, 138, + 138, 138, 130, 130, 130, 130, 130, 130, 130, 130, 138, 138, 138, 138, + 138, 138, 138, 138, 130, 130, 21, 139, 21, 0, 21, 21, 131, 131, 140, + 140, 141, 11, 142, 11, 11, 11, 21, 139, 21, 0, 21, 21, 143, 143, 143, + 143, 141, 11, 11, 11, 130, 130, 21, 21, 0, 0, 21, 21, 131, 131, 144, + 144, 0, 11, 11, 11, 130, 130, 21, 21, 21, 112, 21, 21, 131, 131, 145, + 145, 116, 11, 11, 11, 0, 0, 21, 139, 21, 0, 21, 21, 146, 146, 147, + 147, 141, 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, 141, 142, 17, 17, 17, 17, 17, 2, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 148, 149, 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, 85, 0, 0, - 18, 18, 18, 18, 18, 18, 7, 7, 7, 5, 6, 85, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 7, 7, 7, 5, 6, 0, 85, 85, 85, 85, 85, 85, 85, 85, 85, - 85, 85, 85, 85, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 86, 86, 86, 86, 86, 86, 86, 86, - 86, 86, 86, 86, 111, 111, 111, 111, 86, 111, 111, 111, 86, 86, 86, - 86, 86, 86, 86, 86, 86, 86, 86, 86, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 14, 14, 100, 14, 14, 14, 14, 100, 14, 14, 21, 100, 100, - 100, 21, 21, 100, 100, 100, 21, 14, 100, 14, 14, 7, 100, 100, 100, - 100, 100, 14, 14, 14, 14, 14, 14, 100, 14, 143, 14, 100, 14, 144, 145, - 100, 100, 14, 21, 100, 100, 146, 100, 21, 15, 15, 15, 15, 21, 14, 14, - 21, 21, 100, 100, 7, 7, 7, 7, 7, 100, 21, 21, 21, 21, 14, 7, 14, 14, - 147, 14, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, - 148, 148, 148, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, - 149, 149, 149, 149, 149, 118, 118, 118, 23, 24, 118, 118, 118, 118, + 17, 17, 17, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 18, 90, 0, 0, + 18, 18, 18, 18, 18, 18, 7, 7, 7, 5, 6, 90, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 7, 7, 7, 5, 6, 0, 90, 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 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, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 118, 118, 118, 118, 91, 118, 118, 118, 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, 14, 14, 106, 14, 14, 14, 14, 106, 14, 14, 21, 106, 106, + 106, 21, 21, 106, 106, 106, 21, 14, 106, 14, 14, 7, 106, 106, 106, + 106, 106, 14, 14, 14, 14, 14, 14, 106, 14, 150, 14, 106, 14, 151, 152, + 106, 106, 14, 21, 106, 106, 153, 106, 21, 15, 15, 15, 15, 21, 14, 14, + 21, 21, 106, 106, 7, 7, 7, 7, 7, 106, 21, 21, 21, 21, 14, 7, 14, 14, + 154, 14, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, + 155, 155, 155, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, + 156, 156, 156, 156, 156, 125, 125, 125, 23, 24, 125, 125, 125, 125, 18, 0, 0, 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, @@ -914,209 +918,222 @@ static const unsigned char groupMap[] = { 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, 7, 7, 7, 7, 7, 7, 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, 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, 14, 14, 14, 14, + 14, 14, 0, 0, 0, 0, 0, 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, 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, 150, 150, 150, 150, 150, 150, 150, 150, - 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, - 150, 150, 150, 150, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, - 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, - 151, 151, 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, + 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, 157, 157, 157, 157, 157, 157, 157, + 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, + 157, 157, 157, 157, 157, 158, 158, 158, 158, 158, 158, 158, 158, 158, + 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, + 158, 158, 158, 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, 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, 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, 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, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 18, 18, 18, 18, + 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, 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, 7, 7, + 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, 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, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 0, 0, 0, 0, 0, 0, 114, 114, 114, 114, 114, 114, 114, 114, - 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, - 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, - 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, 0, 115, 115, - 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, - 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, - 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, - 115, 115, 115, 0, 23, 24, 152, 153, 154, 155, 156, 23, 24, 23, 24, - 23, 24, 157, 158, 159, 160, 21, 23, 24, 21, 23, 24, 21, 21, 21, 21, - 21, 85, 85, 161, 161, 23, 24, 23, 24, 21, 14, 14, 14, 14, 14, 14, 23, - 24, 23, 24, 86, 86, 86, 23, 24, 0, 0, 0, 0, 0, 3, 3, 3, 3, 18, 3, 3, - 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, - 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, - 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 0, 162, 0, 0, 0, - 0, 0, 162, 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, 85, - 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 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, 85, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 8, 8, 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, 0, 14, 14, 14, + 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, 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, 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, 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, 85, 15, 118, 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, 118, 118, 118, 118, - 118, 118, 118, 118, 118, 86, 86, 86, 86, 116, 116, 8, 85, 85, 85, 85, - 85, 14, 14, 118, 118, 118, 85, 15, 3, 14, 14, 15, 15, 15, 15, 15, 15, + 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, 121, 121, 121, 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, 122, 122, 122, 122, 0, 23, + 24, 159, 160, 161, 162, 163, 23, 24, 23, 24, 23, 24, 164, 165, 166, + 167, 21, 23, 24, 21, 23, 24, 21, 21, 21, 21, 21, 90, 90, 168, 168, + 23, 24, 23, 24, 21, 14, 14, 14, 14, 14, 14, 23, 24, 23, 24, 91, 91, + 91, 23, 24, 0, 0, 0, 0, 0, 3, 3, 3, 3, 18, 3, 3, 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, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 0, 169, 0, 0, 0, 0, 0, 169, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 0, 0, 86, 86, 11, 11, 85, 85, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 90, 3, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 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, 90, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 8, 8, 3, 3, 3, + 3, 8, 3, 5, 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, 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, 90, 15, 125, 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, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 91, 91, 91, 91, 123, 123, 8, 90, + 90, 90, 90, 90, 14, 14, 125, 125, 125, 90, 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, 3, 85, 85, 85, 15, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 0, 0, 91, 91, 11, 11, 90, 90, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 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, 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, 3, 90, 90, 90, 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, 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, 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, 85, 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, 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, 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, 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, 15, 85, 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, 86, 111, 111, 111, 3, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, - 3, 85, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, - 24, 23, 24, 23, 24, 23, 24, 23, 24, 0, 0, 0, 0, 0, 0, 0, 86, 15, 15, - 15, 15, 15, 15, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 86, - 86, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 11, 11, 11, 11, 11, 11, + 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, 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, 90, 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, 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, 15, 15, 15, 15, 15, 15, 15, 90, 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, 91, 118, 118, 118, 3, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 3, 90, 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, 90, + 90, 0, 91, 15, 15, 15, 15, 15, 15, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 91, 91, 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, - 85, 85, 85, 85, 85, 85, 85, 85, 85, 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, 85, 21, 21, 21, 21, 21, 21, 21, 21, 23, 24, - 23, 24, 163, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 85, 11, 11, 23, - 24, 164, 21, 0, 23, 24, 23, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 165, 0, 0, 0, 0, 0, 0, 0, 0, + 11, 11, 11, 11, 11, 90, 90, 90, 90, 90, 90, 90, 90, 90, 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, 90, 21, 21, 21, 21, 21, + 21, 21, 21, 23, 24, 23, 24, 170, 23, 24, 23, 24, 23, 24, 23, 24, 23, + 24, 90, 11, 11, 23, 24, 171, 21, 0, 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, 172, 173, 174, 175, 0, 0, 176, 177, 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, 85, 85, 21, 15, 15, 15, 15, - 15, 15, 15, 86, 15, 15, 15, 86, 15, 15, 15, 15, 86, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 116, 116, 86, 86, 116, 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, 116, 116, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 116, 116, 116, 116, 116, 116, 116, - 116, 116, 116, 116, 116, 116, 116, 116, 116, 86, 0, 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, 86, - 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, - 15, 15, 15, 15, 15, 15, 3, 3, 3, 15, 0, 0, 0, 0, 15, 15, 15, 15, 15, - 15, 86, 86, 86, 86, 86, 86, 86, 86, 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, 86, - 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 116, 116, 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, 86, 116, 116, 86, 86, 86, 86, 116, 116, 86, - 116, 116, 116, 116, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 85, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 3, 3, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 86, 86, 86, 86, 86, 86, 116, 116, 86, 86, 116, 116, 86, - 86, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 86, 15, 15, 15, 15, 15, - 15, 15, 15, 86, 116, 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, - 85, 15, 15, 15, 15, 15, 15, 14, 14, 14, 15, 116, 0, 0, 0, 0, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 86, 15, 86, - 86, 86, 15, 15, 86, 86, 15, 15, 15, 15, 15, 86, 86, 15, 86, 15, 0, + 0, 0, 0, 0, 0, 15, 90, 90, 21, 15, 15, 15, 15, 15, 15, 15, 91, 15, + 15, 15, 91, 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, 123, 123, 91, + 91, 123, 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, 123, 123, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, + 123, 123, 123, 123, 91, 0, 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, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 15, 15, 15, 15, 15, 15, 3, + 3, 3, 15, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 91, 91, 91, 91, 91, 91, + 91, 91, 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, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 123, 123, 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, 91, 123, 123, 91, + 91, 91, 91, 123, 123, 91, 123, 123, 123, 123, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 0, 90, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, + 3, 3, 15, 15, 15, 15, 15, 91, 90, 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, 91, 91, 91, 91, 91, 91, 123, 123, 91, 91, 123, + 123, 91, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 91, 15, 15, 15, + 15, 15, 15, 15, 15, 91, 123, 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, 90, 15, 15, 15, 15, 15, 15, 14, 14, 14, 15, 123, 91, 123, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 91, 15, 91, 91, 91, 15, 15, 91, 91, 15, 15, 15, 15, 15, 91, 91, + 15, 91, 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, 90, 3, 3, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 123, 91, 91, 123, 123, 3, 3, 15, 90, 90, 123, 91, 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, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 11, 90, 90, 90, 90, 0, 0, 0, 0, 21, 21, 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, 85, 3, 3, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 116, - 86, 86, 116, 116, 3, 3, 15, 85, 85, 116, 86, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 116, 116, 86, 116, 116, 86, 116, 116, - 3, 116, 86, 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, 15, 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, 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, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 15, 15, 15, 15, + 0, 0, 15, 15, 15, 123, 123, 91, 123, 123, 91, 123, 123, 3, 123, 91, + 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, 15, 0, + 0, 0, 0, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, + 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, + 178, 178, 178, 178, 178, 178, 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, 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, 0, 0, 0, 0, 0, 0, 21, 21, 21, 21, 21, 21, 21, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 21, 21, 21, 21, 0, 0, 0, 0, 0, 15, - 86, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 7, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 0, 15, 0, 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, 15, 15, 15, 15, 15, 15, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 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, 0, 0, 0, 0, 0, 21, 21, 21, 21, 21, 21, 21, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 21, 21, 21, 21, 21, 0, 0, 0, 0, 0, 15, 91, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 7, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 0, 15, 0, 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, 15, 15, 15, 15, 15, 15, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 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, 15, - 15, 5, 6, 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, 6, + 5, 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, 15, 15, 15, 15, 15, 15, 15, 0, 0, 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, - 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, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 4, 14, 0, 0, 86, 86, 86, 86, 86, - 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 3, 3, 3, 3, 3, 3, 3, 5, - 6, 3, 0, 0, 0, 0, 0, 0, 86, 86, 86, 86, 86, 86, 86, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 3, 8, 8, 12, 12, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, - 6, 5, 6, 3, 3, 5, 6, 3, 3, 3, 3, 12, 12, 12, 3, 3, 3, 0, 3, 3, 3, 3, - 8, 5, 6, 5, 6, 5, 6, 3, 3, 3, 7, 8, 7, 7, 7, 0, 3, 4, 3, 3, 0, 0, 0, - 0, 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, 15, 15, 0, 0, 17, 0, 3, 3, 3, 4, - 3, 3, 3, 5, 6, 3, 7, 3, 8, 3, 3, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 3, 3, - 7, 7, 7, 3, 11, 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, 5, 7, 6, 7, 5, - 6, 3, 5, 6, 3, 3, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 85, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 85, 85, 15, 15, 15, 15, 15, 15, - 15, 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, 0, - 0, 15, 15, 15, 15, 15, 15, 0, 0, 15, 15, 15, 15, 15, 15, 0, 0, 15, - 15, 15, 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 + 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, 4, 14, 0, 0, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 3, 3, 3, 3, 3, 3, 3, 5, 6, + 3, 0, 0, 0, 0, 0, 0, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 0, 0, 3, 8, 8, 12, 12, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, + 5, 6, 5, 6, 3, 3, 5, 6, 3, 3, 3, 3, 12, 12, 12, 3, 3, 3, 0, 3, 3, 3, + 3, 8, 5, 6, 5, 6, 5, 6, 3, 3, 3, 7, 8, 7, 7, 7, 0, 3, 4, 3, 3, 0, 0, + 0, 0, 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, 15, 15, 0, 0, 17, 0, 3, 3, + 3, 4, 3, 3, 3, 5, 6, 3, 7, 3, 8, 3, 3, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 3, 3, 7, 7, 7, 3, 11, 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, 5, 7, 6, 7, + 5, 6, 3, 5, 6, 3, 3, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 90, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 90, 90, 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, 15, 15, 15, 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 #if TCL_UTF_MAX > 3 ,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, @@ -1127,213 +1144,282 @@ 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, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, - 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, - 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, - 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 118, 18, + 14, 14, 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, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 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, 18, 18, 14, 0, 0, 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, 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, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 86, 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, 18, 18, 18, 18, 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, 118, 15, 15, 15, 15, 15, 15, 15, 15, 118, 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, 15, 15, 15, 15, 0, 3, 15, 15, 15, 15, 0, 0, 0, - 0, 15, 15, 15, 15, 15, 15, 15, 15, 3, 118, 118, 118, 118, 118, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 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, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, - 168, 168, 168, 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, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, - 169, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 0, 0, 15, 0, 15, 15, 15, - 15, 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, 91, 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, 91, 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, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 125, 15, 15, 15, 15, 15, 15, 15, 15, + 125, 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, 0, 15, 15, 0, 0, 0, 15, 0, 0, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 91, 91, 91, 91, 91, 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, 125, 125, 125, + 125, 125, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 180, 180, 180, 180, 180, 180, + 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, + 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, + 180, 180, 180, 180, 180, 180, 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, 181, 181, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 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, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 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, + 15, 0, 0, 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, 0, 3, 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, 15, 15, + 0, 0, 0, 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, 0, 3, 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, 15, 15, 14, 14, 18, 18, 18, 18, 18, 18, + 18, 0, 0, 0, 0, 0, 0, 0, 18, 18, 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, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 18, 18, + 18, 18, 18, 18, 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, 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, 0, 0, 0, 0, 0, 0, 15, 15, + 15, 91, 91, 91, 0, 91, 91, 0, 0, 0, 0, 0, 91, 91, 91, 91, 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, 91, 91, 91, 0, 0, 0, 0, 91, 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, - 18, 18, 18, 18, 18, 18, 0, 0, 0, 3, 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, 15, 15, 15, 15, - 15, 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, 0, 0, 0, 0, 0, 0, 15, - 15, 15, 86, 86, 86, 0, 86, 86, 0, 0, 0, 0, 0, 86, 86, 86, 86, 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, 86, 86, 86, 0, 0, 0, 0, 86, 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, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 18, 18, 3, 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, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 91, 91, + 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, 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, 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, + 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, 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, + 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, 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, 116, 86, 116, 15, + 18, 0, 123, 91, 123, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 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, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 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, 91, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 123, 123, 123, 91, 91, 91, 91, 123, 123, 91, 91, 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, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, 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, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 116, 116, 116, 86, - 86, 86, 86, 116, 116, 86, 86, 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, 86, 86, - 86, 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, 91, 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, - 15, 15, 15, 86, 86, 86, 86, 86, 116, 86, 86, 86, 86, 86, 86, 86, 86, - 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, 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, 91, 91, 91, 91, 91, 123, 91, 91, 91, + 91, 91, 91, 91, 91, 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, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 116, 116, 116, 86, 86, 86, 86, 86, 86, 86, 86, 86, 116, 116, 15, 15, - 15, 15, 3, 3, 3, 3, 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, 86, - 116, 86, 116, 116, 86, 86, 86, 86, 86, 86, 116, 86, 0, 0, 0, 0, 0, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 91, 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, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 118, 118, 118, 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, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 123, 123, 123, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 123, 123, 15, 15, 15, 15, 3, 3, 3, 3, 0, 0, 0, 0, 3, 0, 0, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 15, 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, 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, 123, 123, + 123, 91, 91, 91, 123, 123, 91, 123, 91, 91, 3, 3, 3, 3, 3, 3, 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, 91, 123, 123, + 123, 91, 91, 91, 91, 91, 91, 91, 91, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 91, 123, 123, 123, 123, 0, 0, 123, + 123, 0, 0, 123, 123, 123, 0, 0, 0, 0, 0, 0, 0, 0, 0, 123, 0, 0, 0, + 0, 0, 15, 15, 15, 15, 15, 123, 123, 0, 0, 91, 91, 91, 91, 91, 91, 91, + 0, 0, 0, 91, 91, 91, 91, 91, 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, 123, 123, 123, + 91, 91, 91, 91, 91, 91, 123, 91, 123, 123, 123, 123, 91, 91, 123, 91, + 91, 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, 123, 123, 123, 91, 91, 91, 91, 0, 0, 123, 123, 123, + 123, 91, 91, 123, 91, 91, 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, 0, 0, 0, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 123, 123, 123, 91, + 91, 91, 91, 91, 91, 91, 91, 123, 123, 91, 123, 91, 91, 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, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 91, 123, 91, + 123, 123, 91, 91, 91, 91, 91, 91, 123, 91, 0, 0, 0, 0, 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, 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, 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, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 0, 3, 3, 3, 3, 3, 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, 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, 91, 91, 91, + 91, 91, 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, 91, 91, 91, 91, 91, 91, 91, 3, + 3, 3, 3, 3, 14, 14, 14, 14, 90, 90, 90, 90, 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, - 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 116, 116, - 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, - 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, - 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, - 116, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, 86, 86, - 86, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 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, 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, 116, 116, 86, 86, 86, 14, 14, 14, 116, - 116, 116, 116, 116, 116, 17, 17, 17, 17, 17, 17, 17, 17, 86, 86, 86, - 86, 86, 86, 86, 86, 14, 14, 86, 86, 86, 86, 86, 86, 86, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 86, 86, 86, 86, 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, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 15, 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, 123, 123, 123, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 91, 91, 91, 91, 90, 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 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, 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, + 91, 91, 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, 123, 123, 91, 91, 91, + 14, 14, 14, 123, 123, 123, 123, 123, 123, 17, 17, 17, 17, 17, 17, 17, + 17, 91, 91, 91, 91, 91, 91, 91, 91, 14, 14, 91, 91, 91, 91, 91, 91, + 91, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 91, 91, 91, + 91, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 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, 86, 86, 86, - 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, 100, 100, 100, 100, 100, - 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, - 100, 100, 100, 100, 100, 100, 100, 21, 21, 21, 21, 21, 21, 21, 21, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 14, + 14, 91, 91, 91, 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, 106, 106, + 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, + 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, - 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 21, + 21, 21, 21, 21, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, + 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, + 106, 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, 106, 106, 106, 106, 106, 106, + 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, + 106, 106, 106, 106, 106, 106, 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, 106, + 0, 106, 106, 0, 0, 106, 0, 0, 106, 106, 0, 0, 106, 106, 106, 106, 0, + 106, 106, 106, 106, 106, 106, 106, 106, 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, 21, 21, 21, 21, 21, 21, 21, 100, 100, 100, 100, 100, 100, 100, - 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, - 100, 100, 100, 100, 100, 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, 100, 0, - 100, 100, 0, 0, 100, 0, 0, 100, 100, 0, 0, 100, 100, 100, 100, 0, 100, - 100, 100, 100, 100, 100, 100, 100, 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, - 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, - 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 21, 21, + 21, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, + 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 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, 100, 100, 0, 100, 100, 100, 100, 0, 0, - 100, 100, 100, 100, 100, 100, 100, 100, 0, 100, 100, 100, 100, 100, - 100, 100, 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, 100, 100, 0, 100, 100, - 100, 100, 0, 100, 100, 100, 100, 100, 0, 100, 0, 0, 0, 100, 100, 100, - 100, 100, 100, 100, 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, 100, 100, - 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, - 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 106, 106, 0, 106, 106, 106, 106, 0, + 0, 106, 106, 106, 106, 106, 106, 106, 106, 0, 106, 106, 106, 106, 106, + 106, 106, 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, 106, 106, 0, 106, 106, + 106, 106, 0, 106, 106, 106, 106, 106, 0, 106, 0, 0, 0, 106, 106, 106, + 106, 106, 106, 106, 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, 106, 106, + 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, + 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 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, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, - 100, 100, 100, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 100, 100, 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, 100, - 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, - 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 21, 21, 21, + 21, 21, 21, 21, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, + 106, 106, 106, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 106, 106, 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, 106, + 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, + 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 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, 100, 100, 100, 100, 100, 100, 100, 100, 100, - 100, 100, 100, 100, 100, 100, 100, 21, 21, 21, 21, 21, 21, 0, 0, 100, - 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, - 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 7, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 106, 106, 106, 106, 106, 106, 106, 106, 106, + 106, 106, 106, 106, 106, 106, 106, 21, 21, 21, 21, 21, 21, 0, 0, 106, + 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, + 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 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, 100, 100, 100, 100, 100, - 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, - 100, 100, 100, 100, 100, 100, 7, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 7, 21, 21, 21, 21, 21, 21, 106, 106, 106, 106, 106, + 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, + 106, 106, 106, 106, 106, 106, 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, 100, 100, 100, 100, 100, 100, 100, 100, 100, - 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, - 100, 100, 7, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 106, 106, 106, 106, 106, 106, 106, 106, 106, + 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, + 106, 106, 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, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, - 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 7, 21, + 21, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, + 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 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, 100, 100, 100, - 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, - 100, 100, 100, 100, 100, 100, 100, 100, 7, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 7, 21, 21, 21, 21, 21, 21, 106, 106, 106, + 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, + 106, 106, 106, 106, 106, 106, 106, 106, 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, 100, 21, 0, 0, 9, 9, 9, 9, 9, 9, + 21, 21, 7, 21, 21, 21, 21, 21, 21, 106, 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, 15, + 15, 15, 15, 15, 0, 0, 18, 18, 18, 18, 18, 18, 18, 18, 18, 91, 91, 91, + 91, 91, 91, 91, 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, 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, + 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, 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, 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, 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, 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, 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, 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, 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, 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, + 14, 14, 14, 14, 14, 14, 14, 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, + 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 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, 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, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 14, - 14, 14, 14, 0, 0, 0, 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, 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, - 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 + 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, + 0, 0, 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, 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, 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, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 #endif /* TCL_UTF_MAX > 3 */ }; @@ -1361,11 +1447,12 @@ static const int groups[] = { 53057, -24702, 54081, 53569, -41598, 54593, -33150, 54849, 55873, 55617, 56129, -14206, 609, 451, 674, 20354, -24767, -14271, -33215, 2763585, -41663, 2762817, -2768510, -49855, 17729, 18241, -2760318, - -2759550, -2760062, 53890, 52866, 52610, 51842, 52098, 53122, - -10823550, -10830718, 53634, 54146, -2750078, -2751614, 54658, - 54914, -2745982, 55938, 17794, 55682, 18306, 56194, 4, 6, -21370, - 9793, 9537, 16449, 16193, 9858, 9602, 8066, 16514, 16258, 2113, - 16002, 14722, 1, 12162, 13954, 2178, 22146, 20610, -1662, -15295, + -2759550, -2760062, 53890, 52866, 52610, 51842, 52098, -10833534, + -10832510, 53122, -10823550, -10830718, 53634, 54146, -2750078, + -10829950, -2751614, 54658, 54914, -2745982, 55938, -10824062, + 17794, 55682, 18306, 56194, -10817918, 4, 6, -21370, 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, 10, -9044862, -976254, 15234, -1949375, -1918, -1983, -18814, -21886, -25470, -32638, -28542, -32126, -1981, -2174, -18879, @@ -1373,7 +1460,8 @@ static const int groups[] = { -1924287, -2145983, -2115007, 7233, 7298, 4170, 4234, 6749, 6813, -2750143, -976319, -2746047, 2763650, 2762882, -2759615, -2751679, -2760383, -2760127, -2768575, 1859714, -9044927, -10823615, -10830783, - 18, 17, 10305, 10370 + -10833599, -10832575, -10830015, -10817983, -10824127, 18, 17, + 10305, 10370 }; #if TCL_UTF_MAX > 3 -- cgit v0.12 From d5ffff621454dd0faed32b101f845006bbaef40b Mon Sep 17 00:00:00 2001 From: dgp Date: Tue, 8 Jul 2014 13:45:09 +0000 Subject: The write and flush operations of reflected transforms ([chan push]) have been converting all lower level channel errors from Tcl_WriteRaw() into EINVAL. Generally this is a perplexing discard of useful information, but worse it interferes with the EAGAIN signalling that is required to manage the BLOCKED state of a nonblocking channel. Thanks to aspect for demo scripts that pointed to the bug. --- generic/tclIORTrans.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/generic/tclIORTrans.c b/generic/tclIORTrans.c index d2707a1..45ee08d 100644 --- a/generic/tclIORTrans.c +++ b/generic/tclIORTrans.c @@ -3178,7 +3178,7 @@ TransformWrite( } if (res < 0) { - *errorCodePtr = EINVAL; + *errorCodePtr = Tcl_GetErrno(); return 0; } @@ -3288,7 +3288,7 @@ TransformFlush( } if (res < 0) { - *errorCodePtr = EINVAL; + *errorCodePtr = Tcl_GetErrno(); return 0; } -- cgit v0.12 From da31ff7eb892963804fbc37cda1cdeebe3516f87 Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 9 Jul 2014 14:44:13 +0000 Subject: First draft of using buffer moves in place of buffer copies to create an efficient [chan copy]. --- generic/tclIO.c | 119 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 117 insertions(+), 2 deletions(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index 5cdf2c3..1938173 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -182,6 +182,7 @@ static int CloseChannelPart(Tcl_Interp *interp, Channel *chanPtr, static int CloseWrite(Tcl_Interp *interp, Channel *chanPtr); static void CommonGetsCleanup(Channel *chanPtr); static int CopyData(CopyState *csPtr, int mask); +static int MoveBytes(CopyState *csPtr); static void CopyEventProc(ClientData clientData, int mask); static void CreateScriptRecord(Tcl_Interp *interp, Channel *chanPtr, int mask, Tcl_Obj *scriptPtr); @@ -8778,6 +8779,7 @@ TclCopyChannel( int readFlags, writeFlags; CopyState *csPtr; int nonBlocking = (cmdPtr) ? CHANNEL_NONBLOCKING : 0; + int moveBytes; inStatePtr = inPtr->state; outStatePtr = outPtr->state; @@ -8829,13 +8831,27 @@ TclCopyChannel( | CHANNEL_UNBUFFERED; /* + * Very strict set of conditions where we know we can just move bytes + * from input channel to output channel with no transformation or even + * examination of the bytes themselves. + * TODO: Find ways to relax this. + */ + + moveBytes = inStatePtr->inEofChar == '\0' /* No eofChar to stop input */ + && inStatePtr->inputTranslation == TCL_TRANSLATE_LF + && outStatePtr->outputTranslation == TCL_TRANSLATE_LF + && inStatePtr->encoding == NULL + && outStatePtr->encoding == NULL + && !nonBlocking; /* First draft do only blocking case */ + + /* * Allocate a new CopyState to maintain info about the current copy in * progress. This structure will be deallocated when the copy is * completed. */ - csPtr = ckalloc(sizeof(CopyState) + inStatePtr->bufSize); - csPtr->bufSize = inStatePtr->bufSize; + csPtr = ckalloc(sizeof(CopyState) + !moveBytes * inStatePtr->bufSize); + csPtr->bufSize = !moveBytes * inStatePtr->bufSize; csPtr->readPtr = inPtr; csPtr->writePtr = outPtr; csPtr->readFlags = readFlags; @@ -8851,6 +8867,10 @@ TclCopyChannel( inStatePtr->csPtrR = csPtr; outStatePtr->csPtrW = csPtr; + if (moveBytes) { + return MoveBytes(csPtr); + } + /* * Special handling of -size 0 async transfers, so that the -command is * still called asynchronously. @@ -8886,6 +8906,101 @@ TclCopyChannel( */ static int +MoveBytes( + CopyState *csPtr) /* State of copy operation. */ +{ + ChannelState *inStatePtr = csPtr->readPtr->state; + ChannelState *outStatePtr = csPtr->writePtr->state; + ChannelBuffer *bufPtr = outStatePtr->curOutPtr; + int code = TCL_OK; + + if (bufPtr && BytesLeft(bufPtr)) { + /* If we start with unflushed bytes in the destination + * channel, flush them out of the way first. */ + + if (0 != FlushChannel(csPtr->interp, outStatePtr->topChanPtr, 0)) { + code = TCL_ERROR; + goto done; + } + } + + while (csPtr->toRead != 0) { + ChannelBuffer *bufPtr = inStatePtr->inQueueHead; + ChannelBuffer *tail = NULL; + int inBytes = 0; + + if (bufPtr == NULL || BytesLeft(bufPtr) == 0) { + /* Nothing in the input queue; Get more input. */ + + if (0 != GetInput(inStatePtr->topChanPtr)) { + code = TCL_ERROR; + break; + } + bufPtr = inStatePtr->inQueueHead; + } + + /* Count up number of bytes waiting in the input queue */ + while (bufPtr) { + inBytes += BytesLeft(bufPtr); + tail = bufPtr; + if (csPtr->toRead != -1 && csPtr->toRead < inBytes) { + /* Queue has enough bytes to complete the copy */ + break; + } + bufPtr = bufPtr->nextPtr; + } + + if (bufPtr) { + /* Split the overflowing buffer in two */ + int extra = inBytes - csPtr->toRead; + + bufPtr = AllocChannelBuffer(extra); + + tail->nextAdded -= extra; + memcpy(InsertPoint(bufPtr), InsertPoint(tail), extra); + bufPtr->nextAdded += extra; + bufPtr->nextPtr = tail->nextPtr; + tail->nextPtr = NULL; + inBytes = csPtr->toRead; + } + + /* Update the byte counts */ + if (csPtr->toRead != -1) { + csPtr->toRead -= inBytes; + } + csPtr->total += inBytes; + + /* Move buffers from input to output channels */ + if (outStatePtr->outQueueTail) { + outStatePtr->outQueueTail->nextPtr = inStatePtr->inQueueHead; + } else { + outStatePtr->outQueueHead = inStatePtr->inQueueHead; + } + outStatePtr->outQueueTail = tail; + inStatePtr->inQueueHead = bufPtr; + if (bufPtr == NULL) { + inStatePtr->inQueueTail = NULL; + } + + /* Flush destination */ + if (0 != FlushChannel(csPtr->interp, outStatePtr->topChanPtr, 0)) { + code = TCL_ERROR; + break; + } + if (GotFlag(inStatePtr, CHANNEL_EOF)) { + break; + } + } + + if (code == TCL_OK) { + Tcl_SetObjResult(csPtr->interp, Tcl_NewWideIntObj(csPtr->total)); + } + done: + StopCopy(csPtr); + return code; +} + +static int CopyData( CopyState *csPtr, /* State of copy operation. */ int mask) /* Current channel event flags. */ -- cgit v0.12 From a07299438938e767364dc68775ccb15355b2b916 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 9 Jul 2014 18:49:38 +0000 Subject: Don't use Tcl_GetCommandInfo when Tcl_FindCommand suffices. --- generic/tclZlib.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/generic/tclZlib.c b/generic/tclZlib.c index 2e27303..4ccda3b 100644 --- a/generic/tclZlib.c +++ b/generic/tclZlib.c @@ -643,7 +643,6 @@ Tcl_ZlibStreamInit( int e; ZlibStreamHandle *zshPtr = NULL; Tcl_DString cmdname; - Tcl_CmdInfo cmdinfo; GzipHeader *gzHeaderPtr = NULL; switch (mode) { @@ -769,8 +768,8 @@ Tcl_ZlibStreamInit( Tcl_DStringInit(&cmdname); TclDStringAppendLiteral(&cmdname, "::tcl::zlib::streamcmd_"); TclDStringAppendObj(&cmdname, Tcl_GetObjResult(interp)); - if (Tcl_GetCommandInfo(interp, Tcl_DStringValue(&cmdname), - &cmdinfo) == 1) { + if (Tcl_FindCommand(interp, Tcl_DStringValue(&cmdname), + NULL, 0) != NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "BUG: Stream command name already exists", -1)); Tcl_SetErrorCode(interp, "TCL", "BUG", "EXISTING_CMD", NULL); -- cgit v0.12 From 61f8119019659d9aa43dc2833938475de8f1a85a Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 10 Jul 2014 12:52:10 +0000 Subject: Repair buffer indexing error in Tcl_ReadRaw() exposed by iogt-6.0 and valgrind. --- generic/tclIO.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index 9deec87..1a9ff65 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -5023,7 +5023,7 @@ Tcl_ReadRaw( if (bytesToRead > 0) { - int nread = ChanRead(chanPtr, readBuf+copied, bytesToRead); + int nread = ChanRead(chanPtr, readBuf, bytesToRead); if (nread > 0) { /* Successful read (short is OK) - add to bytes copied */ -- cgit v0.12 From b81d871afb75e89084b40119c3668bf010d43786 Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 10 Jul 2014 15:45:32 +0000 Subject: [7368d225a6] Extend the auto-cleanup of zero ref count values passed in to the Tcl_*SetVar*() family of routines to cover the missing case where the flags value of TCL_APPEND_VALUE is passed in alone. *** POTENTIAL INCOMAPTIBILITY*** --- generic/tclVar.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/generic/tclVar.c b/generic/tclVar.c index 12d6911..fda5ff5 100644 --- a/generic/tclVar.c +++ b/generic/tclVar.c @@ -1916,6 +1916,9 @@ TclPtrSetVar( Tcl_IncrRefCount(oldValuePtr); /* Since var is ref */ } Tcl_AppendObjToObj(oldValuePtr, newValuePtr); + if (newValuePtr->refCount == 0) { + Tcl_DecrRefCount(newValuePtr); + } } } } else if (newValuePtr != oldValuePtr) { -- cgit v0.12 From b406c00842fecc6fbe4fc0f3672f9a56e5c3c9fb Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 10 Jul 2014 17:21:23 +0000 Subject: [f652ae79ed] Close sockets used in tests, so as not to corrupt other tests in the suite. --- tests/socket.test | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/socket.test b/tests/socket.test index 2bd2731..93fdb2d 100644 --- a/tests/socket.test +++ b/tests/socket.test @@ -2309,6 +2309,7 @@ test socket-14.15 {blocking read on async socket should not trigger event handle set x ok fileevent $s writable {set x fail} catch {read $s} + close $s set x } -result ok -- cgit v0.12 From 8fd7a480121db00d224778ec4bcb923e41775f43 Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 10 Jul 2014 18:00:42 +0000 Subject: dup test name --- tests/io.test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/io.test b/tests/io.test index c1938a1..925f8c6 100644 --- a/tests/io.test +++ b/tests/io.test @@ -4052,7 +4052,7 @@ test io-32.11.1 {Tcl_Read from a pipe} {stdio openpipe} { } {{hello } {hello }} -test io-32.11.1 {Tcl_Read from a pipe} {stdio openpipe} { +test io-32.11.2 {Tcl_Read from a pipe} {stdio openpipe} { file delete $path(pipe) set f1 [open $path(pipe) w] puts $f1 {chan configure stdout -translation crlf} -- cgit v0.12 From 0992240c655285334833946aa1af4de36602ca8f Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 10 Jul 2014 18:11:39 +0000 Subject: makeFile / removeFile balance --- tests/socket.test | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/socket.test b/tests/socket.test index 93fdb2d..c50730c 100644 --- a/tests/socket.test +++ b/tests/socket.test @@ -2036,6 +2036,7 @@ test socket-14.7.0 {pending [socket -async] and blocking [gets], server is IPv4} } -cleanup { close $fd close $sock + removeFile script } -result {{} ok {}} test socket-14.7.1 {pending [socket -async] and blocking [gets], server is IPv6} \ -constraints {socket supported_inet6 localhost_v6} \ @@ -2056,6 +2057,7 @@ test socket-14.7.1 {pending [socket -async] and blocking [gets], server is IPv6} } -cleanup { close $fd close $sock + removeFile script } -result {{} ok {}} test socket-14.7.2 {pending [socket -async] and blocking [gets], no listener} \ -constraints {socket} \ @@ -2090,6 +2092,7 @@ test socket-14.8.0 {pending [socket -async] and nonblocking [gets], server is IP } -cleanup { close $fd close $sock + removeFile script } -result {ok} test socket-14.8.1 {pending [socket -async] and nonblocking [gets], server is IPv6} \ -constraints {socket supported_inet6 localhost_v6} \ @@ -2115,6 +2118,7 @@ test socket-14.8.1 {pending [socket -async] and nonblocking [gets], server is IP } -cleanup { close $fd close $sock + removeFile script } -result {ok} test socket-14.8.2 {pending [socket -async] and nonblocking [gets], no listener} \ -constraints {socket} \ @@ -2151,6 +2155,7 @@ test socket-14.9.0 {pending [socket -async] and blocking [puts], server is IPv4} } -cleanup { close $fd close $sock + removeFile script } -result {{} ok} test socket-14.9.1 {pending [socket -async] and blocking [puts], server is IPv6} \ -constraints {socket supported_inet6 localhost_v6} \ @@ -2174,6 +2179,7 @@ test socket-14.9.1 {pending [socket -async] and blocking [puts], server is IPv6} } -cleanup { close $fd close $sock + removeFile script } -result {{} ok} test socket-14.10.0 {pending [socket -async] and nonblocking [puts], server is IPv4} \ -constraints {socket supported_inet localhost_v4} \ @@ -2200,6 +2206,7 @@ test socket-14.10.0 {pending [socket -async] and nonblocking [puts], server is I } -cleanup { close $fd close $sock + removeFile script } -result {{} ok} test socket-14.10.1 {pending [socket -async] and nonblocking [puts], server is IPv6} \ -constraints {socket supported_inet6 localhost_v6} \ @@ -2226,6 +2233,7 @@ test socket-14.10.1 {pending [socket -async] and nonblocking [puts], server is I } -cleanup { close $fd close $sock + removeFile script } -result {{} ok} test socket-14.11.0 {pending [socket -async] and nonblocking [puts], no listener, no flush} \ -constraints {socket} \ -- cgit v0.12 From d6605e905724412821ae97debb75bfb90641538a Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 10 Jul 2014 18:17:28 +0000 Subject: makeFile / removeFile balance. --- tests/ioTrans.test | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/ioTrans.test b/tests/ioTrans.test index c40621b..53078f7 100644 --- a/tests/ioTrans.test +++ b/tests/ioTrans.test @@ -1037,6 +1037,8 @@ test iortrans-11.1 {origin interpreter of moved transform destroyed during acces } -constraints {testchannel} -match glob -body { # Set up channel in thread set chan [interp eval $ida $helperscript] + interp eval $ida [list ::variable tempchan [tempchan]] + interp transfer {} $::tempchan $ida set chan [interp eval $ida { proc foo {args} { handle.initialize clear drain flush limit? read write @@ -1045,7 +1047,7 @@ test iortrans-11.1 {origin interpreter of moved transform destroyed during acces # Destroy interpreter during channel access. suicide } - set chan [chan push [tempchan] foo] + set chan [chan push $tempchan foo] fconfigure $chan -buffering none set chan }] -- cgit v0.12 From dbed3f80890d0dac9b09204d0a7ffd69049b72cc Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 11 Jul 2014 04:49:49 +0000 Subject: [3479689] Plug memory leak due to incomplete bug fix. --- generic/tclPathObj.c | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/generic/tclPathObj.c b/generic/tclPathObj.c index fe6063f..99d576d 100644 --- a/generic/tclPathObj.c +++ b/generic/tclPathObj.c @@ -2437,19 +2437,13 @@ SetFsPathFromAny( } TclDecrRefCount(parts); } else { - /* - * Simple case. "rest" is relative path. Just join it. The - * "rest" object will be freed when Tcl_FSJoinToPath returns - * (unless something else claims a refCount on it). - */ - - Tcl_Obj *joined; - Tcl_Obj *rest = Tcl_NewStringObj(name+split+1, -1); + Tcl_Obj *pair[2]; - Tcl_IncrRefCount(transPtr); - joined = Tcl_FSJoinToPath(transPtr, 1, &rest); - TclDecrRefCount(transPtr); - transPtr = joined; + pair[0] = transPtr; + pair[1] = Tcl_NewStringObj(name+split+1, -1); + transPtr = TclJoinPath(2, pair); + Tcl_DecrRefCount(pair[0]); + Tcl_DecrRefCount(pair[1]); } } } else { -- cgit v0.12 From 0a0d095f202cb17e7d3231292f26d22205bd2cf9 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Fri, 11 Jul 2014 10:38:55 +0000 Subject: Starting with Unicode 6.3, the mongolian vowel separator (U+180e) is no longer a whitespace, but for Tcl it still is. "NEL/Next Line" (U+0085) should have been a Unicode whitespace, but never was in Tcl. This is corrected in Tcl 8.6, but for legacy reasons not in Tcl 8.5. Update documentation accordingly, and extend test-cases for Unicode 7 compliance. --- doc/string.n | 3 ++- generic/regc_locale.c | 4 ++-- tests/utf.test | 30 +++++++++++++++--------------- 3 files changed, 19 insertions(+), 18 deletions(-) diff --git a/doc/string.n b/doc/string.n index f39d57c..7e427ab 100644 --- a/doc/string.n +++ b/doc/string.n @@ -161,7 +161,8 @@ Any Unicode printing character, including space. .IP \fBpunct\fR 12 Any Unicode punctuation character. .IP \fBspace\fR 12 -Any Unicode space character. +Any Unicode whitespace character or mongolian vowel separator (U+180e), +but not NEL/Next Line (U+0085). .IP \fBtrue\fR 12 Any of the forms allowed to \fBTcl_GetBoolean\fR where the value is true. diff --git a/generic/regc_locale.c b/generic/regc_locale.c index 8dba520..e056078 100644 --- a/generic/regc_locale.c +++ b/generic/regc_locale.c @@ -381,8 +381,8 @@ static const crange spaceRangeTable[] = { #define NUM_SPACE_RANGE (sizeof(spaceRangeTable)/sizeof(crange)) static const chr spaceCharTable[] = { - 0x20, 0xa0, 0x1680, 0x180e, 0x2028, 0x2029, 0x202f, 0x205f, 0x2060, - 0x3000, 0xfeff + 0x20, 0xa0, 0x1680, 0x180e, 0x2028, 0x2029, 0x202f, 0x205f, + 0x3000 }; #define NUM_SPACE_CHAR (sizeof(spaceCharTable)/sizeof(chr)) diff --git a/tests/utf.test b/tests/utf.test index 35c5f73..30200c1 100644 --- a/tests/utf.test +++ b/tests/utf.test @@ -278,15 +278,15 @@ test utf-20.1 {TclUniCharNcmp} { } {} test utf-21.1 {TclUniCharIsAlnum} { - # this returns 1 with Unicode 6 compliance + # this returns 1 with Unicode 7 compliance string is alnum \u1040\u021f\u0220 } {1} test utf-21.2 {unicode alnum char in regc_locale.c} { - # this returns 1 with Unicode 6 compliance + # this returns 1 with Unicode 7 compliance list [regexp {^[[:alnum:]]+$} \u1040\u021f\u0220] [regexp {^\w+$} \u1040\u021f\u0220] } {1 1} test utf-21.3 {unicode print char in regc_locale.c} { - # this returns 1 with Unicode 6 compliance + # this returns 1 with Unicode 7 compliance regexp {^[[:print:]]+$} \ufbc1 } 1 test utf-21.4 {TclUniCharIsGraph} { @@ -319,11 +319,11 @@ test utf-21.10 {unicode print char in regc_locale.c} { } {0} test utf-21.11 {TclUniCharIsControl} { # [Bug 3464428] - string is control \u00ad + string is control \u0000\u001f\u00ad\u0605\u061c\u180e\u2066\ufeff } {1} test utf-21.12 {unicode control char in regc_locale.c} { # [Bug 3464428], [Bug a876646efe] - regexp {^[[:cntrl:]]*$} \u0000\u001f\u00ad + regexp {^[[:cntrl:]]*$} \u0000\u001f\u00ad\u0605\u061c\u180e\u2066\ufeff } {1} test utf-22.1 {TclUniCharIsWordChar} { @@ -334,30 +334,30 @@ test utf-22.2 {TclUniCharIsWordChar} { } 10 test utf-23.1 {TclUniCharIsAlpha} { - # this returns 1 with Unicode 6 compliance - string is alpha \u021f\u0220 + # this returns 1 with Unicode 7 compliance + string is alpha \u021f\u0220\u037f\u052f } {1} test utf-23.2 {unicode alpha char in regc_locale.c} { - # this returns 1 with Unicode 6 compliance - regexp {^[[:alpha:]]+$} \u021f\u0220 + # this returns 1 with Unicode 7 compliance + regexp {^[[:alpha:]]+$} \u021f\u0220\u037f\u052f } {1} test utf-24.1 {TclUniCharIsDigit} { - # this returns 1 with Unicode 6 compliance + # this returns 1 with Unicode 7 compliance string is digit \u1040\uabf0 } {1} test utf-24.2 {unicode digit char in regc_locale.c} { - # this returns 1 with Unicode 6 compliance + # this returns 1 with Unicode 7 compliance list [regexp {^[[:digit:]]+$} \u1040\uabf0] [regexp {^\d+$} \u1040\uabf0] } {1 1} test utf-24.3 {TclUniCharIsSpace} { - # this returns 1 with Unicode 6 compliance - string is space \u1680\u180e + # this returns 1 with Unicode 7 compliance + string is space \u1680\u180e\u202f } {1} test utf-24.4 {unicode space char in regc_locale.c} { - # this returns 1 with Unicode 6 compliance - list [regexp {^[[:space:]]+$} \u1680\u180e] [regexp {^\s+$} \u1680\u180e] + # this returns 1 with Unicode 7 compliance + list [regexp {^[[:space:]]+$} \u1680\u180e\u202f] [regexp {^\s+$} \u1680\u180e\u202f] } {1 1} testConstraint teststringobj [llength [info commands teststringobj]] -- cgit v0.12 From 4822b65c03cbbe8f8d2fe3da5f39ffcdd06bea82 Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 11 Jul 2014 12:56:16 +0000 Subject: Stop memleak in [info frame]. --- generic/tclCmdIL.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/generic/tclCmdIL.c b/generic/tclCmdIL.c index db216e5..f870245 100644 --- a/generic/tclCmdIL.c +++ b/generic/tclCmdIL.c @@ -1288,6 +1288,9 @@ TclInfoFrame( }; Proc *procPtr = framePtr->framePtr ? framePtr->framePtr->procPtr : NULL; + /* Super ugly hack added to the pile so we can plug memleak */ + int needsFree = -1; + /* * Pull the information and construct the dictionary to return, as list. * Regarding use of the CmdFrame fields see tclInt.h, and its definition. @@ -1360,6 +1363,7 @@ TclInfoFrame( } ADD_PAIR("cmd", TclGetSourceFromFrame(fPtr, 0, NULL)); + needsFree = lc-1; TclStackFree(interp, fPtr); break; } @@ -1447,7 +1451,11 @@ TclInfoFrame( } } - return Tcl_NewListObj(lc, lv); + tmpObj = Tcl_NewListObj(lc, lv); + if (needsFree >= 0) { + Tcl_DecrRefCount(lv[needsFree]); + } + return tmpObj; } /* -- cgit v0.12 From 431189b805c68785e4237217c47b1dd10a87b7f5 Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 11 Jul 2014 15:44:42 +0000 Subject: [9b352768e6] Plug memleak in INST_DICT_FIRST. --- generic/tclExecute.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/generic/tclExecute.c b/generic/tclExecute.c index d8c5935..2f9aac3 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -7474,6 +7474,14 @@ TEBCresume( searchPtr = ckalloc(sizeof(Tcl_DictSearch)); if (Tcl_DictObjFirst(interp, dictPtr, searchPtr, &keyPtr, &valuePtr, &done) != TCL_OK) { + + /* + * dictPtr is no longer on the stack, and we're not + * moving it into the intrep of an iterator. We need + * to drop the refcount [Tcl Bug 9b352768e6]. + */ + + Tcl_DecrRefCount(dictPtr); ckfree(searchPtr); TRACE_ERROR(interp); goto gotError; -- cgit v0.12 From 5af71fcbffd57da1e03cc84d9dbe3cc636068629 Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 11 Jul 2014 18:20:42 +0000 Subject: [1211aceef2] Fix refcount management of TclpTempFileName() that caused leak. --- unix/tclUnixPipe.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/unix/tclUnixPipe.c b/unix/tclUnixPipe.c index a02044e..95bc8d1 100644 --- a/unix/tclUnixPipe.c +++ b/unix/tclUnixPipe.c @@ -229,7 +229,7 @@ TclpCreateTempFile( Tcl_Obj * TclpTempFileName(void) { - Tcl_Obj *nameObj = Tcl_NewObj(); + Tcl_Obj *retVal, *nameObj = Tcl_NewObj(); int fd; Tcl_IncrRefCount(nameObj); @@ -242,7 +242,9 @@ TclpTempFileName(void) fcntl(fd, F_SETFD, FD_CLOEXEC); TclpObjDeleteFile(nameObj); close(fd); - return nameObj; + retVal = Tcl_DuplicateObj(nameObj); + Tcl_DecrRefCount(nameObj); + return retVal; } /* -- cgit v0.12 From 8825fb59d7242d78fd579f9626a4196f6323a680 Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 11 Jul 2014 20:40:24 +0000 Subject: Suppress valgrind warnings about uninitialized values. --- generic/tclDictObj.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/generic/tclDictObj.c b/generic/tclDictObj.c index 3c0ddd8..15fbe1e 100644 --- a/generic/tclDictObj.c +++ b/generic/tclDictObj.c @@ -405,6 +405,7 @@ DupDictInternalRep( */ DICT(copyPtr) = newDict; + copyPtr->internalRep.twoPtrValue.ptr2 = NULL; copyPtr->typePtr = &tclDictType; } @@ -720,6 +721,7 @@ SetDictFromAny( dict->chain = NULL; dict->refcount = 1; DICT(objPtr) = dict; + objPtr->internalRep.twoPtrValue.ptr2 = NULL; objPtr->typePtr = &tclDictType; return TCL_OK; @@ -1390,6 +1392,7 @@ Tcl_NewDictObj(void) dict->chain = NULL; dict->refcount = 1; DICT(dictPtr) = dict; + dictPtr->internalRep.twoPtrValue.ptr2 = NULL; dictPtr->typePtr = &tclDictType; return dictPtr; #endif @@ -1439,6 +1442,7 @@ Tcl_DbNewDictObj( dict->chain = NULL; dict->refcount = 1; DICT(dictPtr) = dict; + dictPtr->internalRep.twoPtrValue.ptr2 = NULL; dictPtr->typePtr = &tclDictType; return dictPtr; #else /* !TCL_MEM_DEBUG */ -- cgit v0.12 From 0fac79a0fb83abfb15db0859305772d7a64fdc30 Mon Sep 17 00:00:00 2001 From: dgp Date: Tue, 15 Jul 2014 15:10:32 +0000 Subject: [726349fab8] Stop leaking compression dictionary on zlib xform channel close. --- generic/tclZlib.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/generic/tclZlib.c b/generic/tclZlib.c index 4ccda3b..06e18fe 100644 --- a/generic/tclZlib.c +++ b/generic/tclZlib.c @@ -2910,6 +2910,10 @@ ZlibTransformClose( * Release all memory. */ + if (cd->compDictObj) { + Tcl_DecrRefCount(cd->compDictObj); + cd->compDictObj = NULL; + } Tcl_DStringFree(&cd->decompressed); if (cd->inBuffer) { -- cgit v0.12 From 1797998aed8933171252159e04897185043b779a Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 16 Jul 2014 10:02:02 +0000 Subject: Modify the "gettimes" test-command to use the Tcl_Obj API. New "testbytestring" command which can be used to replace the (to-be-deprecated) "bytestring" command from tcltest and/or the "indentity" encoding. Adapt many testcases to use the "testbytestring" command. --- generic/tclTest.c | 55 ++++++++++++++++++++++++++---- tests/chanio.test | 16 ++++++--- tests/io.test | 12 ++++--- tests/parse.test | 29 ++++++++-------- tests/parseExpr.test | 5 +-- tests/parseOld.test | 13 ++++---- tests/stringObj.test | 17 +++++----- tests/subst.test | 12 ++++--- tests/utf.test | 94 +++++++++++++++++++++++++++------------------------- tests/util.test | 5 +-- 10 files changed, 159 insertions(+), 99 deletions(-) diff --git a/generic/tclTest.c b/generic/tclTest.c index a27c95a..0f4b6d4 100644 --- a/generic/tclTest.c +++ b/generic/tclTest.c @@ -201,8 +201,9 @@ static int EncodingFromUtfProc(ClientData clientData, int *dstCharsPtr); static void ExitProcEven(ClientData clientData); static void ExitProcOdd(ClientData clientData); -static int GetTimesCmd(ClientData clientData, - Tcl_Interp *interp, int argc, const char **argv); +static int GetTimesObjCmd(ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *const objv[]); static void MainLoop(void); static int NoopCmd(ClientData clientData, Tcl_Interp *interp, int argc, const char **argv); @@ -219,6 +220,9 @@ static void SpecialFree(char *blockPtr); static int StaticInitProc(Tcl_Interp *interp); static int TestasyncCmd(ClientData dummy, Tcl_Interp *interp, int argc, const char **argv); +static int TestbytestringObjCmd(ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *const objv[]); static int TestcmdinfoCmd(ClientData dummy, Tcl_Interp *interp, int argc, const char **argv); static int TestcmdtokenCmd(ClientData dummy, @@ -556,9 +560,10 @@ Tcltest_Init( * Create additional commands and math functions for testing Tcl. */ - Tcl_CreateCommand(interp, "gettimes", GetTimesCmd, NULL, NULL); + Tcl_CreateObjCommand(interp, "gettimes", GetTimesObjCmd, NULL, NULL); Tcl_CreateCommand(interp, "noop", NoopCmd, NULL, NULL); Tcl_CreateObjCommand(interp, "noop", NoopObjCmd, NULL, NULL); + Tcl_CreateObjCommand(interp, "testbytestring", TestbytestringObjCmd, NULL, NULL); Tcl_CreateObjCommand(interp, "testwrongnumargs", TestWrongNumArgsObjCmd, NULL, NULL); Tcl_CreateObjCommand(interp, "testfilesystem", TestFilesystemObjCmd, @@ -4717,7 +4722,7 @@ TestgetvarfullnameCmd( /* *---------------------------------------------------------------------- * - * GetTimesCmd -- + * GetTimesObjCmd -- * * This procedure implements the "gettimes" command. It is used for * computing the time needed for various basic operations such as reading @@ -4733,11 +4738,11 @@ TestgetvarfullnameCmd( */ static int -GetTimesCmd( +GetTimesObjCmd( ClientData unused, /* Unused. */ Tcl_Interp *interp, /* The current interpreter. */ - int argc, /* The number of arguments. */ - const char **argv) /* The argument strings. */ + int notused1, /* Number of arguments. */ + Tcl_Obj *const notused2[]) /* The argument objects. */ { Interp *iPtr = (Interp *) interp; int i, n; @@ -4951,6 +4956,42 @@ NoopObjCmd( /* *---------------------------------------------------------------------- * + * TestbytestringObjCmd -- + * + * This object-based procedure constructs a string which can + * possibly contain invalid UTF-8 bytes. + * + * Results: + * Returns the TCL_OK result code. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +static int +TestbytestringObjCmd( + ClientData unused, /* Not used. */ + Tcl_Interp *interp, /* Current interpreter. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* The argument objects. */ +{ + int n; + const char *p; + + if (objc != 2) { + Tcl_WrongNumArgs(interp, 1, objv, "bytearray"); + return TCL_ERROR; + } + p = (const char *)Tcl_GetByteArrayFromObj(objv[1], &n); + Tcl_SetObjResult(interp, Tcl_NewStringObj(p, n)); + return TCL_OK; +} + +/* + *---------------------------------------------------------------------- + * * TestsetCmd -- * * Implements the "testset{err,noerr}" cmds that are used when testing diff --git a/tests/chanio.test b/tests/chanio.test index e53f059..2738fc6 100644 --- a/tests/chanio.test +++ b/tests/chanio.test @@ -13,10 +13,16 @@ # See the file "license.terms" for information on usage and redistribution of # this file, and for a DISCLAIMER OF ALL WARRANTIES. -if {[catch {package require tcltest 2}]} { - chan puts stderr "Skipping tests in [info script]. tcltest 2 required." - return +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::* @@ -7426,11 +7432,11 @@ test chan-io-59.1 {Thread reference of channels} {testmainthread testchannel} { string equal $result [testmainthread] } {1} -test chan-io-60.1 {writing illegal utf sequences} {openpipe fileevent} { +test chan-io-60.1 {writing illegal utf sequences} {openpipe fileevent testbytestring} { # This test will hang in older revisions of the core. set out [open $path(script) w] chan puts $out { - chan puts [encoding convertfrom identity \xe2] + chan puts [testbytestring \xe2] exit 1 } proc readit {pipe} { diff --git a/tests/io.test b/tests/io.test index a7a666a..bf5adb0 100644 --- a/tests/io.test +++ b/tests/io.test @@ -13,14 +13,16 @@ # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. -if {[catch {package require tcltest 2}]} { - puts stderr "Skipping tests in [info script]. tcltest 2 required." - return +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::* @@ -7860,12 +7862,12 @@ test io-59.1 {Thread reference of channels} {testmainthread testchannel} { string equal $result [testmainthread] } {1} -test io-60.1 {writing illegal utf sequences} {openpipe fileevent} { +test io-60.1 {writing illegal utf sequences} {openpipe fileevent testbytestring} { # This test will hang in older revisions of the core. set out [open $path(script) w] puts $out { - puts [encoding convertfrom identity \xe2] + puts [testbytestring \xe2] exit 1 } proc readit {pipe} { diff --git a/tests/parse.test b/tests/parse.test index 01443c9..fe6026d 100644 --- a/tests/parse.test +++ b/tests/parse.test @@ -20,6 +20,7 @@ namespace eval ::tcl::test::parse { catch [list package require -exact Tcltest [info patchlevel]] testConstraint testparser [llength [info commands testparser]] +testConstraint testbytestring [llength [info commands testbytestring]] testConstraint testevalobjv [llength [info commands testevalobjv]] testConstraint testevalex [llength [info commands testevalex]] testConstraint testparsevarname [llength [info commands testparsevarname]] @@ -29,8 +30,8 @@ testConstraint testcmdtrace [llength [info commands testcmdtrace]] testConstraint testevent [llength [info commands testevent]] testConstraint memory [llength [info commands memory]] -test parse-1.1 {Tcl_ParseCommand procedure, computing string length} testparser { - testparser [bytestring "foo\0 bar"] -1 +test parse-1.1 {Tcl_ParseCommand procedure, computing string length} {testparser testbytestring} { + testparser [testbytestring "foo\0 bar"] -1 } {- foo 1 simple foo 1 text foo 0 {}} test parse-1.2 {Tcl_ParseCommand procedure, computing string length} testparser { testparser "foo bar" -1 @@ -301,9 +302,9 @@ test parse-6.15 {ParseTokens procedure, backslash-newline} testparser { test parse-6.16 {ParseTokens procedure, backslash substitution} testparser { testparser {\n\a\x7f} 0 } {- {\n\a\x7f} 1 word {\n\a\x7f} 3 backslash {\n} 0 backslash {\a} 0 backslash {\x7f} 0 {}} -test parse-6.17 {ParseTokens procedure, null characters} testparser { - testparser [bytestring "foo\0zz"] 0 -} "- [bytestring foo\0zz] 1 word [bytestring foo\0zz] 3 text foo 0 text [bytestring \0] 0 text zz 0 {}" +test parse-6.17 {ParseTokens procedure, null characters} {testparser testbytestring} { + testparser [testbytestring "foo\0zz"] 0 +} "- [testbytestring foo\0zz] 1 word [testbytestring foo\0zz] 3 text foo 0 text [testbytestring \0] 0 text zz 0 {}" test parse-6.18 {ParseTokens procedure, seek past numBytes for close-bracket} testparser { # Test for Bug 681841 list [catch {testparser {[a]} 2} msg] $msg @@ -700,8 +701,8 @@ test parse-13.6 {Tcl_ParseVar memory leak} -constraints memory -setup { rename getbytes {} } -result 0 -test parse-14.1 {Tcl_ParseBraces procedure, computing string length} testparser { - testparser [bytestring "foo\0 bar"] -1 +test parse-14.1 {Tcl_ParseBraces procedure, computing string length} {testparser testbytestring} { + testparser [testbytestring "foo\0 bar"] -1 } {- foo 1 simple foo 1 text foo 0 {}} test parse-14.2 {Tcl_ParseBraces procedure, computing string length} testparser { testparser "foo bar" -1 @@ -737,8 +738,8 @@ test parse-14.12 {Tcl_ParseBraces procedure, missing close brace} testparser { list [catch {testparser "foo \{xy\\\nz" 0} msg] $msg $::errorInfo } {1 {missing close-brace} missing\ close-brace\n\ \ \ \ (remainder\ of\ script:\ \"\{xy\\\nz\")\n\ \ \ \ invoked\ from\ within\n\"testparser\ \"foo\ \\\{xy\\\\\\nz\"\ 0\"} -test parse-15.1 {Tcl_ParseQuotedString procedure, computing string length} testparser { - testparser [bytestring "foo\0 bar"] -1 +test parse-15.1 {Tcl_ParseQuotedString procedure, computing string length} {testparser testbytestring} { + testparser [testbytestring "foo\0 bar"] -1 } {- foo 1 simple foo 1 text foo 0 {}} test parse-15.2 {Tcl_ParseQuotedString procedure, computing string length} testparser { testparser "foo bar" -1 @@ -903,11 +904,11 @@ test parse-15.53 {CommandComplete procedure} " test parse-15.54 {CommandComplete procedure} " info complete \"foo bar;# \{\" " 1 -test parse-15.55 {CommandComplete procedure} { - info complete "set x [bytestring \0]; puts hi" +test parse-15.55 {CommandComplete procedure} testbytestring { + info complete "set x [testbytestring \0]; puts hi" } 1 -test parse-15.56 {CommandComplete procedure} { - info complete "set x [bytestring \0]; \{" +test parse-15.56 {CommandComplete procedure} testbytestring { + info complete "set x [testbytestring \0]; \{" } 0 test parse-15.57 {CommandComplete procedure} { info complete "# Comment should be complete command" @@ -917,7 +918,7 @@ test parse-15.58 {CommandComplete procedure, memory leaks} { } 1 test parse-15.59 {CommandComplete procedure} { # Test for Tcl Bug 684744 - info complete [encoding convertfrom identity "\x00;if 1 \{"] + info complete [testbytestring "\x00;if 1 \{"] } 0 test parse-15.60 {CommandComplete procedure} { # Test for Tcl Bug 1968882 diff --git a/tests/parseExpr.test b/tests/parseExpr.test index 714c45b..5c7986a 100644 --- a/tests/parseExpr.test +++ b/tests/parseExpr.test @@ -20,6 +20,7 @@ catch [list package require -exact Tcltest [info patchlevel]] # of "<<" are integers. testConstraint testexprparser [llength [info commands testexprparser]] +testConstraint testbytestring [llength [info commands testbytestring]] # Big test for correct ordering of data in [expr] @@ -81,8 +82,8 @@ testConstraint ieeeFloatingPoint [testIEEE] ###################################################################### -test parseExpr-1.1 {Tcl_ParseExpr procedure, computing string length} testexprparser { - testexprparser [bytestring "1+2\0 +3"] -1 +test parseExpr-1.1 {Tcl_ParseExpr procedure, computing string length} {testexprparser testbytestring} { + testexprparser [testbytestring "1+2\0 +3"] -1 } {- {} 0 subexpr 1+2 5 operator + 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 {}} test parseExpr-1.2 {Tcl_ParseExpr procedure, computing string length} testexprparser { testexprparser "1 + 2" -1 diff --git a/tests/parseOld.test b/tests/parseOld.test index f3b1591..4c08b5d 100644 --- a/tests/parseOld.test +++ b/tests/parseOld.test @@ -20,6 +20,7 @@ namespace import ::tcltest::* catch [list package require -exact Tcltest [info patchlevel]] testConstraint testwordend [llength [info commands testwordend]] +testConstraint testbytestring [llength [info commands testbytestring]] # Save the argv value for restoration later set savedArgv $argv @@ -261,15 +262,15 @@ test parseOld-7.10 {backslash substitution} { test parseOld-7.11 {backslash substitution} { eval "list a \"b c\"\\\nd e" } {a {b c} d e} -test parseOld-7.12 {backslash substitution} { +test parseOld-7.12 {backslash substitution} testbytestring { list \ua2 -} [bytestring "\xc2\xa2"] -test parseOld-7.13 {backslash substitution} { +} [testbytestring "\xc2\xa2"] +test parseOld-7.13 {backslash substitution} testbytestring { list \u4e21 -} [bytestring "\xe4\xb8\xa1"] -test parseOld-7.14 {backslash substitution} { +} [testbytestring "\xe4\xb8\xa1"] +test parseOld-7.14 {backslash substitution} testbytestring { list \u4e2k -} [bytestring "\xd3\xa2k"] +} [testbytestring "\xd3\xa2k"] # Semi-colon. diff --git a/tests/stringObj.test b/tests/stringObj.test index 6f331d3..ec7b819 100644 --- a/tests/stringObj.test +++ b/tests/stringObj.test @@ -21,6 +21,7 @@ if {[lsearch [namespace children] ::tcltest] == -1} { catch [list package require -exact Tcltest [info patchlevel]] testConstraint testobj [llength [info commands testobj]] +testConstraint testbytestring [llength [info commands testbytestring]] testConstraint testdstring [llength [info commands testdstring]] test stringObj-1.1 {string type registration} testobj { @@ -338,7 +339,7 @@ test stringObj-10.2 {Tcl_GetRange with some mixed width chars} {testobj testdstr # Because this test does not use \uXXXX notation below instead of # hardcoding the values, it may fail in multibyte locales. However, we # need to test that the parser produces untyped objects even when there - # are high-ASCII characters in the input (like "ï"). I don't know what + # are high-ASCII characters in the input (like "�"). I don't know what # else to do but inline those characters here. testdstring free testdstring append "abc\u00ef\u00efdef" -1 @@ -347,7 +348,7 @@ test stringObj-10.2 {Tcl_GetRange with some mixed width chars} {testobj testdstr [testobj objtype $x] [testobj objtype $y] } [list none "bc\u00EF\u00EFde" string string] test stringObj-10.3 {Tcl_GetRange with some mixed width chars} testobj { - # set x "abcïïdef" + # set x "abc��def" # Use \uXXXX notation below instead of hardcoding the values, otherwise # the test will fail in multibyte locales. set x "abc\u00EF\u00EFdef" @@ -356,7 +357,7 @@ test stringObj-10.3 {Tcl_GetRange with some mixed width chars} testobj { [testobj objtype $x] [testobj objtype $y] } [list string "bc\u00EF\u00EFde" string string] test stringObj-10.4 {Tcl_GetRange with some mixed width chars} testobj { - # set a "ïa¿b®cï¿d®" + # set a "�a�b�c�d�" # Use \uXXXX notation below instead of hardcoding the values, otherwise # the test will fail in multibyte locales. set a "\u00EFa\u00BFb\u00AEc\u00EF\u00BFd\u00AE" @@ -422,18 +423,18 @@ test stringObj-13.5 {Tcl_GetCharLength with mixed width chars} testobj { string length "\u00EF\u00BF\u00AE\u00EF\u00BF\u00AE" } 6 test stringObj-13.6 {Tcl_GetCharLength with mixed width chars} testobj { - # set a "ïa¿b®cï¿d®" + # set a "�a�b�c�d�" # Use \uXXXX notation below instead of hardcoding the values, otherwise # the test will fail in multibyte locales. set a "\u00EFa\u00BFb\u00AEc\u00EF\u00BFd\u00AE" list [string length $a] [string length $a] } {10 10} -test stringObj-13.7 {Tcl_GetCharLength with identity nulls} testobj { +test stringObj-13.7 {Tcl_GetCharLength with identity nulls} {testobj testbytestring} { # SF bug #684699 - string length [encoding convertfrom identity \x00] + string length [testbytestring \x00] } 1 -test stringObj-13.8 {Tcl_GetCharLength with identity nulls} testobj { - string length [encoding convertfrom identity \x01\x00\x02] +test stringObj-13.8 {Tcl_GetCharLength with identity nulls} {testobj testbytestring} { + string length [testbytestring \x01\x00\x02] } 3 test stringObj-14.1 {Tcl_SetObjLength on pure unicode object} testobj { diff --git a/tests/subst.test b/tests/subst.test index 498512d..747438e 100644 --- a/tests/subst.test +++ b/tests/subst.test @@ -15,6 +15,10 @@ if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest 2.1 namespace import -force ::tcltest::* } +::tcltest::loadTestedCommands +catch [list package require -exact Tcltest [info patchlevel]] + +testConstraint testbytestring [llength [info commands testbytestring]] test subst-1.1 {basics} -returnCodes error -body { subst @@ -32,16 +36,16 @@ test subst-2.2 {simple strings} { test subst-2.3 {simple strings} { subst abcdefg } abcdefg -test subst-2.4 {simple strings} { +test subst-2.4 {simple strings} testbytestring { # Tcl Bug 685106 - subst [bytestring bar\x00soom] -} [bytestring bar\x00soom] + subst [testbytestring bar\x00soom] +} [testbytestring bar\x00soom] test subst-3.1 {backslash substitutions} { subst {\x\$x\[foo bar]\\} } "x\$x\[foo bar]\\" test subst-3.2 {backslash substitutions with utf chars} { - # 'j' is just a char that doesn't mean anything, and \344 is 'ä' + # 'j' is just a char that doesn't mean anything, and \344 is '�' # that also doesn't mean anything, but is multi-byte in UTF-8. list [subst \j] [subst \\j] [subst \\344] [subst \\\344] } "j j \344 \344" diff --git a/tests/utf.test b/tests/utf.test index 2d62fa0..2fcac49 100644 --- a/tests/utf.test +++ b/tests/utf.test @@ -16,50 +16,52 @@ if {[lsearch [namespace children] ::tcltest] == -1} { ::tcltest::loadTestedCommands catch [list package require -exact Tcltest [info patchlevel]] +testConstraint testbytestring [llength [info commands testbytestring]] + catch {unset x} -test utf-1.1 {Tcl_UniCharToUtf: 1 byte sequences} { +test utf-1.1 {Tcl_UniCharToUtf: 1 byte sequences} testbytestring { set x \x01 -} [bytestring "\x01"] -test utf-1.2 {Tcl_UniCharToUtf: 2 byte sequences} { +} [testbytestring "\x01"] +test utf-1.2 {Tcl_UniCharToUtf: 2 byte sequences} testbytestring { set x "\x00" -} [bytestring "\xc0\x80"] -test utf-1.3 {Tcl_UniCharToUtf: 2 byte sequences} { +} [testbytestring "\xc0\x80"] +test utf-1.3 {Tcl_UniCharToUtf: 2 byte sequences} testbytestring { set x "\xe0" -} [bytestring "\xc3\xa0"] -test utf-1.4 {Tcl_UniCharToUtf: 3 byte sequences} { +} [testbytestring "\xc3\xa0"] +test utf-1.4 {Tcl_UniCharToUtf: 3 byte sequences} testbytestring { set x "\u4e4e" -} [bytestring "\xe4\xb9\x8e"] -test utf-1.5 {Tcl_UniCharToUtf: overflowed Tcl_UniChar} { +} [testbytestring "\xe4\xb9\x8e"] +test utf-1.5 {Tcl_UniCharToUtf: overflowed Tcl_UniChar} testbytestring { format %c 0x110000 -} [bytestring "\xef\xbf\xbd"] -test utf-1.6 {Tcl_UniCharToUtf: negative Tcl_UniChar} { +} [testbytestring "\xef\xbf\xbd"] +test utf-1.6 {Tcl_UniCharToUtf: negative Tcl_UniChar} testbytestring { format %c -1 -} [bytestring "\xef\xbf\xbd"] +} [testbytestring "\xef\xbf\xbd"] test utf-2.1 {Tcl_UtfToUniChar: low ascii} { string length "abc" } {3} -test utf-2.2 {Tcl_UtfToUniChar: naked trail bytes} { - string length [bytestring "\x82\x83\x84"] +test utf-2.2 {Tcl_UtfToUniChar: naked trail bytes} testbytestring { + string length [testbytestring "\x82\x83\x84"] } {3} -test utf-2.3 {Tcl_UtfToUniChar: lead (2-byte) followed by non-trail} { - string length [bytestring "\xC2"] +test utf-2.3 {Tcl_UtfToUniChar: lead (2-byte) followed by non-trail} testbytestring { + string length [testbytestring "\xC2"] } {1} -test utf-2.4 {Tcl_UtfToUniChar: lead (2-byte) followed by trail} { - string length [bytestring "\xC2\xa2"] +test utf-2.4 {Tcl_UtfToUniChar: lead (2-byte) followed by trail} testbytestring { + string length [testbytestring "\xC2\xa2"] } {1} -test utf-2.5 {Tcl_UtfToUniChar: lead (3-byte) followed by non-trail} { - string length [bytestring "\xE2"] +test utf-2.5 {Tcl_UtfToUniChar: lead (3-byte) followed by non-trail} testbytestring { + string length [testbytestring "\xE2"] } {1} -test utf-2.6 {Tcl_UtfToUniChar: lead (3-byte) followed by 1 trail} { - string length [bytestring "\xE2\xA2"] +test utf-2.6 {Tcl_UtfToUniChar: lead (3-byte) followed by 1 trail} testbytestring { + string length [testbytestring "\xE2\xA2"] } {2} -test utf-2.7 {Tcl_UtfToUniChar: lead (3-byte) followed by 2 trail} { - string length [bytestring "\xE4\xb9\x8e"] +test utf-2.7 {Tcl_UtfToUniChar: lead (3-byte) followed by 2 trail} testbytestring { + string length [testbytestring "\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: longer UTF sequences not supported} testbytestring { + string length [testbytestring "\xF4\xA2\xA2\xA2"] } {4} test utf-3.1 {Tcl_UtfCharComplete} { @@ -69,26 +71,26 @@ testConstraint testnumutfchars [llength [info commands testnumutfchars]] test utf-4.1 {Tcl_NumUtfChars: zero length} testnumutfchars { testnumutfchars "" } {0} -test utf-4.2 {Tcl_NumUtfChars: length 1} testnumutfchars { - testnumutfchars [bytestring "\xC2\xA2"] +test utf-4.2 {Tcl_NumUtfChars: length 1} {testnumutfchars testbytestring} { + testnumutfchars [testbytestring "\xC2\xA2"] } {1} -test utf-4.3 {Tcl_NumUtfChars: long string} testnumutfchars { - testnumutfchars [bytestring "abc\xC2\xA2\xe4\xb9\x8e\uA2\u4e4e"] +test utf-4.3 {Tcl_NumUtfChars: long string} {testnumutfchars testbytestring} { + testnumutfchars [testbytestring "abc\xC2\xA2\xe4\xb9\x8e\uA2\u4e4e"] } {7} -test utf-4.4 {Tcl_NumUtfChars: #u0000} testnumutfchars { - testnumutfchars [bytestring "\xC0\x80"] +test utf-4.4 {Tcl_NumUtfChars: #u0000} {testnumutfchars testbytestring} { + testnumutfchars [testbytestring "\xC0\x80"] } {1} test utf-4.5 {Tcl_NumUtfChars: zero length, calc len} testnumutfchars { testnumutfchars "" 1 } {0} -test utf-4.6 {Tcl_NumUtfChars: length 1, calc len} testnumutfchars { - testnumutfchars [bytestring "\xC2\xA2"] 1 +test utf-4.6 {Tcl_NumUtfChars: length 1, calc len} {testnumutfchars testbytestring} { + testnumutfchars [testbytestring "\xC2\xA2"] 1 } {1} -test utf-4.7 {Tcl_NumUtfChars: long string, calc len} testnumutfchars { - testnumutfchars [bytestring "abc\xC2\xA2\xe4\xb9\x8e\uA2\u4e4e"] 1 +test utf-4.7 {Tcl_NumUtfChars: long string, calc len} {testnumutfchars testbytestring} { + testnumutfchars [testbytestring "abc\xC2\xA2\xe4\xb9\x8e\uA2\u4e4e"] 1 } {7} -test utf-4.8 {Tcl_NumUtfChars: #u0000, calc len} testnumutfchars { - testnumutfchars [bytestring "\xC0\x80"] 1 +test utf-4.8 {Tcl_NumUtfChars: #u0000, calc len} {testnumutfchars testbytestring} { + testnumutfchars [testbytestring "\xC0\x80"] 1 } {1} test utf-5.1 {Tcl_UtfFindFirsts} { @@ -125,18 +127,18 @@ test utf-10.1 {Tcl_UtfBackslash: dst == NULL} { set x \n } { } -test utf-10.2 {Tcl_UtfBackslash: \u subst} { +test utf-10.2 {Tcl_UtfBackslash: \u subst} testbytestring { set x \ua2 -} [bytestring "\xc2\xa2"] -test utf-10.3 {Tcl_UtfBackslash: longer \u subst} { +} [testbytestring "\xc2\xa2"] +test utf-10.3 {Tcl_UtfBackslash: longer \u subst} testbytestring { set x \u4e21 -} [bytestring "\xe4\xb8\xa1"] -test utf-10.4 {Tcl_UtfBackslash: stops at first non-hex} { +} [testbytestring "\xe4\xb8\xa1"] +test utf-10.4 {Tcl_UtfBackslash: stops at first non-hex} testbytestring { set x \u4e2k -} "[bytestring \xd3\xa2]k" -test utf-10.5 {Tcl_UtfBackslash: stops after 4 hex chars} { +} "[testbytestring \xd3\xa2]k" +test utf-10.5 {Tcl_UtfBackslash: stops after 4 hex chars} testbytestring { set x \u4e216 -} "[bytestring \xe4\xb8\xa1]6" +} "[testbytestring \xe4\xb8\xa1]6" proc bsCheck {char num} { global errNum test utf-10.$errNum {backslash substitution} { diff --git a/tests/util.test b/tests/util.test index 0e50483..7782f35 100644 --- a/tests/util.test +++ b/tests/util.test @@ -16,6 +16,7 @@ if {[lsearch [namespace children] ::tcltest] == -1} { catch [list package require -exact Tcltest [info patchlevel]] testConstraint controversialNaN 1 +testConstraint testbytestring [llength [info commands testbytestring]] testConstraint testdstring [llength [info commands testdstring]] testConstraint testconcatobj [llength [info commands testconcatobj]] testConstraint testdoubledigits [llength [info commands testdoubledigits]] @@ -274,10 +275,10 @@ test util-5.17 {Tcl_StringMatch: UTF-8} { # get 1 UTF-8 character Wrapper_Tcl_StringMatch "a\[a\u4e4fc]c" "a\u4e4fc" } 1 -test util-5.18 {Tcl_StringMatch: UTF-8} { +test util-5.18 {Tcl_StringMatch: UTF-8} testbytestring { # pattern += Tcl_UtfToUniChar(pattern, &endChar); # proper advance: wrong answer would match on UTF trail byte of \u4e4f - Wrapper_Tcl_StringMatch {a[a\u4e4fc]c} [bytestring a\u008fc] + Wrapper_Tcl_StringMatch {a[a\u4e4fc]c} [testbytestring a\u008fc] } 0 test util-5.19 {Tcl_StringMatch: UTF-8} { # pattern += Tcl_UtfToUniChar(pattern, &endChar); -- cgit v0.12 From 4870917293242f27965c3ddafa880c1822763a22 Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 16 Jul 2014 15:59:00 +0000 Subject: [6a2d339e50] Plug memleak in INST_STR_REPLACE instruction. --- generic/tclExecute.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/generic/tclExecute.c b/generic/tclExecute.c index 2f9aac3..0d485c2 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -5601,6 +5601,7 @@ TEBCresume( ((int *) objResultPtr->internalRep.otherValuePtr)[1] = 0; } Tcl_InvalidateStringRep(objResultPtr); + TclDecrRefCount(value3Ptr); TRACE_APPEND(("\"%.30s\"\n", O2S(objResultPtr))); NEXT_INST_F(1, 1, 1); } else { @@ -5627,6 +5628,7 @@ TEBCresume( ((int *) objResultPtr->internalRep.otherValuePtr)[1] = 0; } Tcl_InvalidateStringRep(valuePtr); + TclDecrRefCount(value3Ptr); TRACE_APPEND(("\"%.30s\"\n", O2S(valuePtr))); NEXT_INST_F(1, 0, 0); } -- cgit v0.12 From 0d27a4b905777c328279b4a37e837bd49afac12c Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 16 Jul 2014 21:46:30 +0000 Subject: Assert an equality test, not an assignment. --- generic/regc_nfa.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generic/regc_nfa.c b/generic/regc_nfa.c index 2fc3a05..2de7e14 100644 --- a/generic/regc_nfa.c +++ b/generic/regc_nfa.c @@ -1332,7 +1332,7 @@ fixempties( for (s = nfa->states; s != NULL && !NISERR(); s = nexts) { nexts = s->next; /* Ensure tmp fields are clear for next step */ - assert(s->tmp = NULL); + assert(s->tmp == NULL); if (s->flag || s->nins != 1) { continue; } -- cgit v0.12 From b58f928be59711d567a629fc5a2579de4ab73aee Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 16 Jul 2014 22:01:57 +0000 Subject: Repair improper assertion. --- generic/tclCmdIL.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generic/tclCmdIL.c b/generic/tclCmdIL.c index f870245..99d9332 100644 --- a/generic/tclCmdIL.c +++ b/generic/tclCmdIL.c @@ -2663,7 +2663,7 @@ Tcl_LrepeatObjCmd( * number of times. */ - CLANG_ASSERT(dataArray); + CLANG_ASSERT(dataArray || totalElems == 0 ); if (objc == 1) { register Tcl_Obj *tmpPtr = objv[0]; -- cgit v0.12 From d586b47d44f07d8ec29304c59c566f74b817fda5 Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 16 Jul 2014 23:58:54 +0000 Subject: Backout checkin that broke test io-39.1. --- generic/tclCmdIL.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/generic/tclCmdIL.c b/generic/tclCmdIL.c index 99d9332..a26d6cc 100644 --- a/generic/tclCmdIL.c +++ b/generic/tclCmdIL.c @@ -1288,9 +1288,6 @@ TclInfoFrame( }; Proc *procPtr = framePtr->framePtr ? framePtr->framePtr->procPtr : NULL; - /* Super ugly hack added to the pile so we can plug memleak */ - int needsFree = -1; - /* * Pull the information and construct the dictionary to return, as list. * Regarding use of the CmdFrame fields see tclInt.h, and its definition. @@ -1363,7 +1360,6 @@ TclInfoFrame( } ADD_PAIR("cmd", TclGetSourceFromFrame(fPtr, 0, NULL)); - needsFree = lc-1; TclStackFree(interp, fPtr); break; } @@ -1451,11 +1447,7 @@ TclInfoFrame( } } - tmpObj = Tcl_NewListObj(lc, lv); - if (needsFree >= 0) { - Tcl_DecrRefCount(lv[needsFree]); - } - return tmpObj; + return Tcl_NewListObj(lc, lv); } /* -- cgit v0.12 From 07d1de7a4fc07c3c672102f92e0cbd0a2dcc38fa Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 17 Jul 2014 04:24:23 +0000 Subject: [9969cf8ca6] Move the bailout when the ->rewind flag is set down after all the housekeeping matters tearing down frames (trace data) is complete. --- generic/tclExecute.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/generic/tclExecute.c b/generic/tclExecute.c index 0d485c2..0cd074d 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -2204,10 +2204,6 @@ TEBCresume( } else { /* resume from invocation */ CACHE_STACK_INFO(); - if (iPtr->execEnvPtr->rewind) { - result = TCL_ERROR; - goto abnormalReturn; - } NRE_ASSERT(iPtr->cmdFramePtr == bcFramePtr); if (bcFramePtr->cmdObj) { @@ -2219,6 +2215,10 @@ TEBCresume( if (iPtr->flags & INTERP_DEBUG_FRAME) { TclArgumentBCRelease(interp, bcFramePtr); } + if (iPtr->execEnvPtr->rewind) { + result = TCL_ERROR; + goto abnormalReturn; + } if (codePtr->flags & TCL_BYTECODE_RECOMPILE) { iPtr->flags |= ERR_ALREADY_LOGGED; codePtr->flags &= ~TCL_BYTECODE_RECOMPILE; -- cgit v0.12 From f7c255fa173cd4132aad1d142f00927ed82def11 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Thu, 17 Jul 2014 07:39:00 +0000 Subject: Convert some non-ASCII characters in testcase comments - which were mangled by my editor in [79ace7b793] - to valid UTF-8: This way my editor will not mangle them again, and fossil will show in the UI which characters are supposed to be there. --- tests/stringObj.test | 12 ++++++------ tests/subst.test | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/stringObj.test b/tests/stringObj.test index ec7b819..8209142 100644 --- a/tests/stringObj.test +++ b/tests/stringObj.test @@ -339,7 +339,7 @@ test stringObj-10.2 {Tcl_GetRange with some mixed width chars} {testobj testdstr # Because this test does not use \uXXXX notation below instead of # hardcoding the values, it may fail in multibyte locales. However, we # need to test that the parser produces untyped objects even when there - # are high-ASCII characters in the input (like "�"). I don't know what + # are high-ASCII characters in the input (like "ï"). I don't know what # else to do but inline those characters here. testdstring free testdstring append "abc\u00ef\u00efdef" -1 @@ -348,7 +348,7 @@ test stringObj-10.2 {Tcl_GetRange with some mixed width chars} {testobj testdstr [testobj objtype $x] [testobj objtype $y] } [list none "bc\u00EF\u00EFde" string string] test stringObj-10.3 {Tcl_GetRange with some mixed width chars} testobj { - # set x "abc��def" + # set x "abcïïdef" # Use \uXXXX notation below instead of hardcoding the values, otherwise # the test will fail in multibyte locales. set x "abc\u00EF\u00EFdef" @@ -357,7 +357,7 @@ test stringObj-10.3 {Tcl_GetRange with some mixed width chars} testobj { [testobj objtype $x] [testobj objtype $y] } [list string "bc\u00EF\u00EFde" string string] test stringObj-10.4 {Tcl_GetRange with some mixed width chars} testobj { - # set a "�a�b�c�d�" + # set a "ïa¿b®cï¿d®" # Use \uXXXX notation below instead of hardcoding the values, otherwise # the test will fail in multibyte locales. set a "\u00EFa\u00BFb\u00AEc\u00EF\u00BFd\u00AE" @@ -417,13 +417,13 @@ test stringObj-13.4 {Tcl_GetCharLength with mixed width chars} testobj { string length "\u00ae" } 1 test stringObj-13.5 {Tcl_GetCharLength with mixed width chars} testobj { - # string length "○○" + # string length "○○" # Use \uXXXX notation below instead of hardcoding the values, otherwise # the test will fail in multibyte locales. string length "\u00EF\u00BF\u00AE\u00EF\u00BF\u00AE" } 6 test stringObj-13.6 {Tcl_GetCharLength with mixed width chars} testobj { - # set a "�a�b�c�d�" + # set a "ïa¿b®cï¿d®" # Use \uXXXX notation below instead of hardcoding the values, otherwise # the test will fail in multibyte locales. set a "\u00EFa\u00BFb\u00AEc\u00EF\u00BFd\u00AE" @@ -433,7 +433,7 @@ test stringObj-13.7 {Tcl_GetCharLength with identity nulls} {testobj testbytestr # SF bug #684699 string length [testbytestring \x00] } 1 -test stringObj-13.8 {Tcl_GetCharLength with identity nulls} {testobj testbytestring} { +test stringObj-13.8 {Tcl_GetCharLength with identity nulls} {testobj testbytestring} { string length [testbytestring \x01\x00\x02] } 3 diff --git a/tests/subst.test b/tests/subst.test index 747438e..256b7f7 100644 --- a/tests/subst.test +++ b/tests/subst.test @@ -45,7 +45,7 @@ test subst-3.1 {backslash substitutions} { subst {\x\$x\[foo bar]\\} } "x\$x\[foo bar]\\" test subst-3.2 {backslash substitutions with utf chars} { - # 'j' is just a char that doesn't mean anything, and \344 is '�' + # 'j' is just a char that doesn't mean anything, and \344 is 'ä' # that also doesn't mean anything, but is multi-byte in UTF-8. list [subst \j] [subst \\j] [subst \\344] [subst \\\344] } "j j \344 \344" -- cgit v0.12 From 7571df843a7468cda6a5504dd3de1d32aef11060 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Thu, 17 Jul 2014 11:02:03 +0000 Subject: Fix [3cdcfa40809ffd2b9d3d71f77dc57da615243730|3cdcfa4080]: tclWinFile.c does not compile with Win VC6 --- win/tclWinFile.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/win/tclWinFile.c b/win/tclWinFile.c index ad4a5c4..1cdd53f 100644 --- a/win/tclWinFile.c +++ b/win/tclWinFile.c @@ -2900,7 +2900,7 @@ TclNativeCreateNativeRep( WCHAR *nativePathPtr; const char *str; Tcl_Obj *validPathPtr; - int len; + size_t len; WCHAR *wp; if (TclFSCwdIsNative()) { @@ -2926,7 +2926,8 @@ TclNativeCreateNativeRep( Tcl_IncrRefCount(validPathPtr); } - str = Tcl_GetStringFromObj(validPathPtr, &len); + str = Tcl_GetString(validPathPtr); + len = validPathPtr->length; if (strlen(str)!=len) { /* String contains NUL-bytes. This is invalid. */ -- cgit v0.12 From f07fe1c911aa8a0e14476fab4e4be5d9ddcfd923 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Thu, 17 Jul 2014 14:08:30 +0000 Subject: Make sure that all "testchmod" arguments start with '0', making it more obvious that the value is octal. dgp: Isn't the better way to make it obvious the values are octal to use the explicit octal notation? For example, [testchmod 0o777 $path] ? Really seems like a bad idea to me to introduce *more* incompatibilities for the planned conversion for having the value 0777 stop meaning 255 and start meaning 777 in Tcl 9. Answer (Jan). You guessed exactly what's my follow-up plan. This was an intermediate step which keeps all test-cases running. --- tests/fCmd.test | 86 ++++++++++++++++++++++++++--------------------------- tests/tcltest.test | 36 +++++++++++----------- tests/unixFCmd.test | 2 +- tests/winFCmd.test | 46 ++++++++++++++-------------- 4 files changed, 85 insertions(+), 85 deletions(-) diff --git a/tests/fCmd.test b/tests/fCmd.test index 5836e00..c479e35 100644 --- a/tests/fCmd.test +++ b/tests/fCmd.test @@ -128,7 +128,7 @@ proc checkcontent {file matchString} { } proc openup {path} { - testchmod 777 $path + testchmod 0777 $path if {[file isdirectory $path]} { catch { foreach p [glob -directory $path *] { @@ -362,10 +362,10 @@ test fCmd-4.11 {TclFileMakeDirsCmd: doesn't exist: errno != ENOENT} -setup { cleanup } -constraints {unix notRoot testchmod} -returnCodes error -body { file mkdir td1/td2/td3 - testchmod 000 td1/td2 + testchmod 0 td1/td2 file mkdir td1/td2/td3/td4 } -cleanup { - testchmod 755 td1/td2 + testchmod 0755 td1/td2 cleanup } -result {can't create directory "td1/td2/td3": permission denied} test fCmd-4.13 {TclFileMakeDirsCmd: doesn't exist: errno == ENOENT} -setup { @@ -505,11 +505,11 @@ test fCmd-6.6 {CopyRenameOneFile: errno != ENOENT} -setup { cleanup } -constraints {unix notRoot testchmod} -body { file mkdir td1 - testchmod 000 td1 + testchmod 0 td1 createfile tf1 file rename tf1 td1 } -returnCodes error -cleanup { - testchmod 755 td1 + testchmod 0755 td1 } -result {error renaming "tf1" to "td1/tf1": permission denied} test fCmd-6.9 {CopyRenameOneFile: errno == ENOENT} -setup { cleanup @@ -785,7 +785,7 @@ test fCmd-9.3 {file rename: comprehensive: file to new name} -setup { } -constraints {notRoot testchmod} -body { createfile tf1 createfile tf2 - testchmod 444 tf2 + testchmod 0444 tf2 file rename tf1 tf3 file rename tf2 tf4 list [lsort [glob tf*]] [file writable tf3] [file writable tf4] @@ -794,7 +794,7 @@ test fCmd-9.4.a {file rename: comprehensive: dir to new name} -setup { cleanup } -constraints {win win2000orXP testchmod} -body { file mkdir td1 td2 - testchmod 555 td2 + testchmod 0555 td2 file rename td1 td3 file rename td2 td4 list [lsort [glob td*]] [file writable td3] [file writable td4] @@ -805,7 +805,7 @@ test fCmd-9.4.b {file rename: comprehensive: dir to new name} -setup { cleanup } -constraints {unix notRoot testchmod notDarwin9} -body { file mkdir td1 td2 - testchmod 555 td2 + testchmod 0555 td2 file rename td1 td3 file rename td2 td4 list [lsort [glob td*]] [file writable td3] [file writable td4] @@ -817,7 +817,7 @@ test fCmd-9.5 {file rename: comprehensive: file to self} -setup { } -constraints {notRoot testchmod} -body { createfile tf1 tf1 createfile tf2 tf2 - testchmod 444 tf2 + testchmod 0444 tf2 file rename -force tf1 tf1 file rename -force tf2 tf2 list [contents tf1] [contents tf2] [file writable tf1] [file writable tf2] @@ -827,7 +827,7 @@ test fCmd-9.6.a {file rename: comprehensive: dir to self} -setup { } -constraints {win win2000orXP testchmod} -body { file mkdir td1 file mkdir td2 - testchmod 555 td2 + testchmod 0555 td2 file rename -force td1 . file rename -force td2 . list [lsort [glob td*]] [file writable td1] [file writable td2] @@ -837,7 +837,7 @@ test fCmd-9.6.b {file rename: comprehensive: dir to self} -setup { } -constraints {unix notRoot testchmod} -body { file mkdir td1 file mkdir td2 - testchmod 555 td2 + testchmod 0555 td2 file rename -force td1 . file rename -force td2 . list [lsort [glob td*]] [file writable td1] [file writable td2] @@ -855,10 +855,10 @@ test fCmd-9.7 {file rename: comprehensive: file to existing file} -setup { createfile tfd2 createfile tfd3 createfile tfd4 - testchmod 444 tfs3 - testchmod 444 tfs4 - testchmod 444 tfd2 - testchmod 444 tfd4 + testchmod 0444 tfs3 + testchmod 0444 tfs4 + testchmod 0444 tfd2 + testchmod 0444 tfd4 set msg [list [catch {file rename tf1 tf2} msg] $msg] file rename -force tfs1 tfd1 file rename -force tfs2 tfd2 @@ -882,11 +882,11 @@ test fCmd-9.8 {file rename: comprehensive: dir to empty dir} -setup { file mkdir [file join tdd3 tds3] file mkdir [file join tdd4 tds4] if {![testConstraint unix]} { - testchmod 555 tds3 - testchmod 555 tds4 + testchmod 0555 tds3 + testchmod 0555 tds4 } - testchmod 555 [file join tdd2 tds2] - testchmod 555 [file join tdd4 tds4] + testchmod 0555 [file join tdd2 tds2] + testchmod 0555 [file join tdd4 tds4] set msg [list [catch {file rename td1 td2} msg] $msg] file rename -force tds1 tdd1 file rename -force tds2 tdd2 @@ -911,7 +911,7 @@ test fCmd-9.9 {file rename: comprehensive: dir to non-empty dir} -setup { file mkdir [file join tdd1 tds1 xxx] file mkdir [file join tdd2 tds2 xxx] if {!([testConstraint unix] || [testConstraint winVista])} { - testchmod 555 tds2 + testchmod 0555 tds2 } set a1 [list [catch {file rename -force tds1 tdd1} msg] $msg] set a2 [list [catch {file rename -force tds2 tdd2} msg] $msg] @@ -929,7 +929,7 @@ test fCmd-9.10 {file rename: comprehensive: file to new name and dir} -setup { createfile tf1 createfile tf2 file mkdir td1 - testchmod 444 tf2 + testchmod 0444 tf2 file rename tf1 [file join td1 tf3] file rename tf2 [file join td1 tf4] list [catch {glob tf*}] [lsort [glob -directory td1 t*]] \ @@ -942,7 +942,7 @@ test fCmd-9.11 {file rename: comprehensive: dir to new name and dir} -setup { file mkdir td2 file mkdir td3 if {!([testConstraint unix] || [testConstraint winVista])} { - testchmod 555 td2 + testchmod 0555 td2 } file rename td1 [file join td3 td3] file rename td2 [file join td3 td4] @@ -958,13 +958,13 @@ test fCmd-9.12 {file rename: comprehensive: target exists} -setup { cleanup } -constraints {notRoot testchmod notNetworkFilesystem} -body { file mkdir [file join td1 td2] [file join td2 td1] - testchmod 555 [file join td2 td1] + testchmod 0555 [file join td2 td1] file mkdir [file join td3 td4] [file join td4 td3] file rename -force td3 td4 list [file exists td3] [file exists [file join td4 td3 td4]] \ [catch {file rename td1 td2} msg] $msg } -cleanup { - testchmod 755 [file join td2 td1] + testchmod 0755 [file join td2 td1] } -result [subst {0 1 1 {error renaming "td1" to "[file join td2 td1]": file already exists}}] # Test can hit EEXIST or EBUSY, depending on underlying filesystem test fCmd-9.13 {file rename: comprehensive: can't overwrite target} -setup { @@ -1035,7 +1035,7 @@ test fCmd-10.2 {file copy: comprehensive: file to new name} -setup { } -constraints {notRoot testchmod} -body { createfile tf1 tf1 createfile tf2 tf2 - testchmod 444 tf2 + testchmod 0444 tf2 file copy tf1 tf3 file copy tf2 tf4 list [lsort [glob tf*]] [contents tf3] [contents tf4] [file writable tf3] [file writable tf4] @@ -1045,14 +1045,14 @@ test fCmd-10.3 {file copy: comprehensive: dir to new name} -setup { } -constraints {unix notRoot testchmod} -body { file mkdir [file join td1 tdx] file mkdir [file join td2 tdy] - testchmod 555 td2 + testchmod 0555 td2 file copy td1 td3 file copy td2 td4 list [lsort [glob td*]] [glob -directory td3 t*] \ [glob -directory td4 t*] [file writable td3] [file writable td4] } -cleanup { - testchmod 755 td2 - testchmod 755 td4 + testchmod 0755 td2 + testchmod 0755 td4 } -result [list {td1 td2 td3 td4} [file join td3 tdx] [file join td4 tdy] 1 0] test fCmd-10.3.1 {file copy: comprehensive: dir to new name} -setup { cleanup @@ -1060,14 +1060,14 @@ test fCmd-10.3.1 {file copy: comprehensive: dir to new name} -setup { # On Windows with ACLs, copying a directory is defined like this file mkdir [file join td1 tdx] file mkdir [file join td2 tdy] - testchmod 555 td2 + testchmod 0555 td2 file copy td1 td3 file copy td2 td4 list [lsort [glob td*]] [glob -directory td3 t*] \ [glob -directory td4 t*] [file writable td3] [file writable td4] } -cleanup { - testchmod 755 td2 - testchmod 755 td4 + testchmod 0755 td2 + testchmod 0755 td4 } -result [list {td1 td2 td3 td4} [file join td3 tdx] [file join td4 tdy] 1 1] test fCmd-10.4 {file copy: comprehensive: file to existing file} -setup { cleanup @@ -1082,10 +1082,10 @@ test fCmd-10.4 {file copy: comprehensive: file to existing file} -setup { createfile tfd2 createfile tfd3 createfile tfd4 - testchmod 444 tfs3 - testchmod 444 tfs4 - testchmod 444 tfd2 - testchmod 444 tfd4 + testchmod 0444 tfs3 + testchmod 0444 tfs4 + testchmod 0444 tfd2 + testchmod 0444 tfd4 set msg [list [catch {file copy tf1 tf2} msg] $msg] file copy -force tfs1 tfd1 file copy -force tfs2 tfd2 @@ -1106,10 +1106,10 @@ test fCmd-10.5 {file copy: comprehensive: dir to empty dir} -setup { file mkdir [file join tdd2 tds2] file mkdir [file join tdd3 tds3] file mkdir [file join tdd4 tds4] - testchmod 555 tds3 - testchmod 555 tds4 - testchmod 555 [file join tdd2 tds2] - testchmod 555 [file join tdd4 tds4] + testchmod 0555 tds3 + testchmod 0555 tds4 + testchmod 0555 [file join tdd2 tds2] + testchmod 0555 [file join tdd4 tds4] set a1 [list [catch {file copy td1 td2} msg] $msg] set a2 [list [catch {file copy -force tds1 tdd1} msg] $msg] set a3 [catch {file copy -force tds2 tdd2}] @@ -1124,7 +1124,7 @@ test fCmd-10.6 {file copy: comprehensive: dir to non-empty dir} -setup { file mkdir tds2 file mkdir [file join tdd1 tds1 xxx] file mkdir [file join tdd2 tds2 xxx] - testchmod 555 tds2 + testchmod 0555 tds2 set a1 [list [catch {file copy -force tds1 tdd1} msg] $msg] set a2 [list [catch {file copy -force tds2 tdd2} msg] $msg] list [lsort [glob td*]] $a1 $a2 [file writable tds1] [file writable tds2] @@ -1135,7 +1135,7 @@ test fCmd-10.7 {file rename: comprehensive: file to new name and dir} -setup { createfile tf1 createfile tf2 file mkdir td1 - testchmod 444 tf2 + testchmod 0444 tf2 file copy tf1 [file join td1 tf3] file copy tf2 [file join td1 tf4] list [lsort [glob tf*]] [lsort [glob -directory td1 t*]] \ @@ -1147,7 +1147,7 @@ test fCmd-10.8 {file rename: comprehensive: dir to new name and dir} -setup { file mkdir td1 file mkdir td2 file mkdir td3 - testchmod 555 td2 + testchmod 0555 td2 file copy td1 [file join td3 td3] file copy td2 [file join td3 td4] list [lsort [glob td*]] [lsort [glob -directory td3 t*]] \ @@ -1160,7 +1160,7 @@ test fCmd-10.8.1 {file rename: comprehensive: dir to new name and dir} -setup { file mkdir td1 file mkdir td2 file mkdir td3 - testchmod 555 td2 + testchmod 0555 td2 file copy td1 [file join td3 td3] file copy td2 [file join td3 td4] list [lsort [glob td*]] [lsort [glob -directory td3 t*]] \ diff --git a/tests/tcltest.test b/tests/tcltest.test index ce8d617..5894308 100644 --- a/tests/tcltest.test +++ b/tests/tcltest.test @@ -142,7 +142,7 @@ test tcltest-2.5a {tcltest -verbose 'pass skip body'} {unixOrPc} { } {0 1 1 1 1} test tcltest-2.6 {tcltest -verbose 't'} { - -constraints {unixOrPc} + -constraints {unixOrPc} -body { set result [slave msg test.tcl -verbose 't'] list $result $msg @@ -152,7 +152,7 @@ test tcltest-2.6 {tcltest -verbose 't'} { } test tcltest-2.6a {tcltest -verbose 'start'} { - -constraints {unixOrPc} + -constraints {unixOrPc} -body { set result [slave msg test.tcl -verbose start] list $result $msg @@ -169,7 +169,7 @@ test tcltest-2.7 {tcltest::verbose} { verbose foo set newVerbosity [verbose] verbose $oldVerbosity - list $currentVerbosity $newVerbosity + list $currentVerbosity $newVerbosity } -result {body {}} } @@ -217,7 +217,7 @@ test tcltest-3.5 {tcltest::match} { } -result {foo bar} } - + # -skip, [skip] test tcltest-4.1 {tcltest -skip 'a*'} {unixOrPc} { set result [slave msg test.tcl -skip a* -verbose 'ps'] @@ -299,8 +299,8 @@ test tcltest-5.3 {testConstraint - constraint empty (tcltest::safeFetch)} { # -result {{} tcltestFakeConstraint1 {tcltestFakeConstraint1 tcltestFakeConstraint2}} # -cleanup { # set ::tcltest::constraintsSpecified $constraintlist -# unset ::tcltest::testConstraints(tcltestFakeConstraint1) -# unset ::tcltest::testConstraints(tcltestFakeConstraint2) +# unset ::tcltest::testConstraints(tcltestFakeConstraint1) +# unset ::tcltest::testConstraints(tcltestFakeConstraint2) # } #} @@ -348,7 +348,7 @@ set printerror [makeFile { ::tcltest::PrintError "a really really long string containing a \ \"Path/that/is/really/long/and/contains/no/spaces\"" ::tcltest::PrintError "a really really long string containing a \ - \"Really/Long/Path/that/contains/no/spaces/and/is/longer/than/eighty/characters/to/see/what/happens\"" + \"Really/Long/Path/that/contains/no/spaces/and/is/longer/than/eighty/characters/to/see/what/happens\"" ::tcltest::PrintError "Problem renaming file: error renaming \"Z:/ws/tcl8.2/win32-ix86/tests/core\" to \"Z:/ws/tcl8.2/win32-ix86/tests/movecore-core\"" exit } printerror.tcl] @@ -367,7 +367,7 @@ test tcltest-6.2 {tcltest -outfile a.tmp} {unixOrPc unixExecs} { set result1 [catch {exec grep "a test" a.tmp}] set result2 [catch {exec grep "a really" a.tmp}] list [regexp "a test" $msg] [regexp "a really" $msg] \ - $result1 $result2 [file exists a.tmp] [file delete a.tmp] + $result1 $result2 [file exists a.tmp] [file delete a.tmp] } {0 1 0 1 1 {}} test tcltest-6.3 {tcltest -errfile a.tmp} {unixOrPc unixExecs} { slave msg $printerror -errfile a.tmp @@ -413,7 +413,7 @@ test tcltest-6.6 {tcltest::errorFile (implicit errorChannel)} { set f2 [errorFile $ef] set f3 [errorChannel] set f4 [errorFile] - subst {$f0;$f1;$f2;$f3;$f4} + subst {$f0;$f1;$f2;$f3;$f4} } -result {stderr;stderr;.*efile;file[0-9a-f]+;.*efile} -match regexp @@ -449,7 +449,7 @@ test tcltest-6.8 {tcltest::outputFile (implicit outputFile)} { set f2 [outputFile $ef] set f3 [outputChannel] set f4 [outputFile] - subst {$f0;$f1;$f2;$f3;$f4} + subst {$f0;$f1;$f2;$f3;$f4} } -result {stdout;stdout;.*efile;file[0-9a-f]+;.*efile} -match regexp @@ -550,7 +550,7 @@ switch -- $::tcl_platform(platform) { } default { catch {file attributes $notWriteableDir -readonly 1} - catch {testchmod 000 $notWriteableDir} + catch {testchmod 0 $notWriteableDir} } } test tcltest-8.3 {tcltest a.tcl -tmpdir notReadableDir} { @@ -717,7 +717,7 @@ switch -- $::tcl_platform(platform) { file attributes $notWriteableDir -permissions 777 } default { - catch {testchmod 777 $notWriteableDir} + catch {testchmod 0777 $notWriteableDir} catch {file attributes $notWriteableDir -readonly 0} } } @@ -758,7 +758,7 @@ test tcltest-9.3 {matchFiles} { set new [matchFiles] matchFiles $old list $current $new - } + } -result {foo bar} } @@ -771,7 +771,7 @@ test tcltest-9.4 {skipFiles} { set new [skipFiles] skipFiles $old list $current $new - } + } -result {foo bar} } @@ -1146,7 +1146,7 @@ test tcltest-19.1 {TCLTEST_OPTIONS default} -setup { interp delete slave2 interp delete slave1 if {$oldoptions eq "none"} { - unset ::env(TCLTEST_OPTIONS) + unset ::env(TCLTEST_OPTIONS) } else { set ::env(TCLTEST_OPTIONS) $oldoptions } @@ -1260,7 +1260,7 @@ test tcltest-21.6 {test command - setup occurs before cleanup & before script} { } set foo 1 set expected 2 - } + } -body { incr foo set foo @@ -1424,7 +1424,7 @@ test tcltest-23.1 {makeFile} { } -cleanup { file delete -force $mfdir \ - [file join [temporaryDirectory] t1.tmp] + [file join [temporaryDirectory] t1.tmp] } -result {1 1} } @@ -1447,7 +1447,7 @@ test tcltest-23.2 {removeFile} { } -cleanup { file delete -force $mfdir \ - [file join [temporaryDirectory] t1.tmp] + [file join [temporaryDirectory] t1.tmp] } -result {0 0} } diff --git a/tests/unixFCmd.test b/tests/unixFCmd.test index e4613ed..3755fed 100644 --- a/tests/unixFCmd.test +++ b/tests/unixFCmd.test @@ -59,7 +59,7 @@ if {[testConstraint unix]} { } proc openup {path} { - testchmod 777 $path + testchmod 0777 $path if {[file isdirectory $path]} { catch { foreach p [glob -directory $path *] { diff --git a/tests/winFCmd.test b/tests/winFCmd.test index 28257c6..14d3d07 100644 --- a/tests/winFCmd.test +++ b/tests/winFCmd.test @@ -335,12 +335,12 @@ test winFCmd-1.32 {TclpRenameFile: TclpRemoveDirectory succeeds} -setup { test winFCmd-1.33 {TclpRenameFile: After removing dst dir, MoveFile fails} \ -constraints {win exdev testfile testchmod} -body { file mkdir d:/td1 - testchmod 000 d:/td1 + testchmod 0 d:/td1 file mkdir c:/tf1 catch {testfile mv c:/tf1 d:/td1} msg list $msg [file writable d:/td1] } -cleanup { - catch {testchmod 666 d:/td1} + catch {testchmod 0666 d:/td1} file delete d:/td1 file delete -force c:/tf1 } -result {EXDEV 0} @@ -489,11 +489,11 @@ test winFCmd-2.12 {TclpCopyFile: CopyFile succeeds} -setup { cleanup } -constraints {win testfile} -body { createfile tf1 tf1 - testchmod 000 tf1 + testchmod 0 tf1 testfile cp tf1 tf2 list [contents tf2] [file writable tf2] } -cleanup { - catch {testchmod 666 tf1} + catch {testchmod 0666 tf1} cleanup } -result {tf1 0} test winFCmd-2.13 {TclpCopyFile: CopyFile fails} -setup { @@ -535,11 +535,11 @@ test winFCmd-2.17 {TclpCopyFile: dst is readonly} -setup { } -constraints {win testfile testchmod} -body { createfile tf1 tf1 createfile tf2 tf2 - testchmod 000 tf2 + testchmod 0 tf2 testfile cp tf1 tf2 list [file writable tf2] [contents tf2] } -cleanup { - catch {testchmod 666 tf2} + catch {testchmod 0666 tf2} cleanup } -result {1 tf1} @@ -605,7 +605,7 @@ test winFCmd-3.10 {TclpDeleteFile: path is readonly} -setup { cleanup } -constraints {win testfile testchmod} -body { createfile tf1 - testchmod 000 tf1 + testchmod 0 tf1 testfile rm tf1 file exists tf1 } -result {0} @@ -613,11 +613,11 @@ test winFCmd-3.11 {TclpDeleteFile: still can't remove path} -setup { cleanup } -constraints {win testfile testchmod} -body { set fd [open tf1 w] - testchmod 000 tf1 + testchmod 0 tf1 testfile rm tf1 } -cleanup { close $fd - catch {testchmod 666 tf1} + catch {testchmod 0666 tf1} cleanup } -returnCodes error -result EACCES @@ -658,11 +658,11 @@ test winFCmd-6.1 {TclpRemoveDirectory: errno: EACCES} -setup { cleanup } -constraints {winVista testfile testchmod} -body { file mkdir td1 - testchmod 000 td1 + testchmod 0 td1 testfile rmdir td1 file exists td1 } -returnCodes error -cleanup { - catch {testchmod 666 td1} + catch {testchmod 0666 td1} cleanup } -result {td1 EACCES} # This next test has a very hokey way of matching... @@ -712,11 +712,11 @@ test winFCmd-6.9 {TclpRemoveDirectory: errno == EACCES} -setup { cleanup } -constraints {winVista testfile testchmod} -body { file mkdir td1 - testchmod 000 td1 + testchmod 0 td1 testfile rmdir td1 file exists td1 } -returnCodes error -cleanup { - catch {testchmod 666 td1} + catch {testchmod 0666 td1} cleanup } -result {td1 EACCES} test winFCmd-6.11 {TclpRemoveDirectory: attr == -1} -setup { @@ -730,11 +730,11 @@ test winFCmd-6.13 {TclpRemoveDirectory: write-protected} -setup { cleanup } -constraints {winVista testfile testchmod} -body { file mkdir td1 - testchmod 000 td1 + testchmod 0 td1 testfile rmdir td1 file exists td1 } -cleanup { - catch {testchmod 666 td1} + catch {testchmod 0666 td1} cleanup } -returnCodes error -result {td1 EACCES} # This next test has a very hokey way of matching... @@ -830,11 +830,11 @@ test winFCmd-7.11 {TraverseWinTree: call TraversalCopy: DOTREE_PRED} -setup { } -constraints {win testfile testchmod} -body { file mkdir td1 createfile td1/tf1 tf1 - testchmod 000 td1 + testchmod 0 td1 testfile cpdir td1 td2 list [file exists td2] [file writable td2] } -cleanup { - catch {testchmod 666 td1} + catch {testchmod 0666 td1} cleanup } -result {1 1} test winFCmd-7.12 {TraverseWinTree: call TraversalDelete: DOTREE_PRED} -setup { @@ -901,11 +901,11 @@ test winFCmd-7.19 {TraverseWinTree: call TraversalCopy: DOTREE_POSTD} -setup { } -constraints {win testfile testchmod} -body { file mkdir td1 createfile td1/tf1 tf1 - testchmod 000 td1 + testchmod 0 td1 testfile cpdir td1 td2 list [file exists td2] [file writable td2] } -cleanup { - catch {testchmod 666 td1} + catch {testchmod 0666 td1} cleanup } -result {1 1} test winFCmd-7.20 {TraverseWinTree: call TraversalDelete: DOTREE_POSTD} -setup { @@ -932,11 +932,11 @@ test winFCmd-8.2 {TraversalCopy: DOTREE_PRED} -setup { cleanup } -constraints {win testfile testchmod} -body { file mkdir td1/td2 - testchmod 000 td1 + testchmod 0 td1 testfile cpdir td1 td2 list [file writable td1] [file writable td1/td2] } -cleanup { - catch {testchmod 666 td1} + catch {testchmod 0666 td1} cleanup } -result {0 1} test winFCmd-8.3 {TraversalCopy: DOTREE_POSTD} -setup { @@ -959,11 +959,11 @@ test winFCmd-9.3 {TraversalDelete: DOTREE_PRED} -setup { cleanup } -constraints {winVista testfile testchmod} -body { file mkdir td1/td2 - testchmod 000 td1 + testchmod 0 td1 testfile rmdir -force td1 file exists td1 } -cleanup { - catch {testchmod 666 td1} + catch {testchmod 0666 td1} cleanup } -returnCodes error -result {td1 EACCES} test winFCmd-9.4 {TraversalDelete: DOTREE_POSTD} -setup { -- cgit v0.12 From 5203cce0e0bb8bd2a34dbf347ec26f8e69246167 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Thu, 17 Jul 2014 15:15:28 +0000 Subject: Convert TesteventloopCmd and TestchmodCmd to Tcl_Obj-API form. --- unix/tclUnixTest.c | 24 ++++++++++-------------- unix/tclXtTest.c | 19 +++++++++---------- win/tclWinTest.c | 47 +++++++++++++++++++++-------------------------- 3 files changed, 40 insertions(+), 50 deletions(-) diff --git a/unix/tclUnixTest.c b/unix/tclUnixTest.c index 4b0f369..c5ac52a 100644 --- a/unix/tclUnixTest.c +++ b/unix/tclUnixTest.c @@ -63,7 +63,7 @@ static const char *gotsig = "0"; */ static Tcl_CmdProc TestalarmCmd; -static Tcl_CmdProc TestchmodCmd; +static Tcl_ObjCmdProc TestchmodCmd; static Tcl_CmdProc TestfilehandlerCmd; static Tcl_CmdProc TestfilewaitCmd; static Tcl_CmdProc TestfindexecutableCmd; @@ -96,7 +96,7 @@ int TclplatformtestInit( Tcl_Interp *interp) /* Interpreter to add commands to. */ { - Tcl_CreateCommand(interp, "testchmod", TestchmodCmd, + Tcl_CreateObjCommand(interp, "testchmod", TestchmodCmd, NULL, NULL); Tcl_CreateCommand(interp, "testfilehandler", TestfilehandlerCmd, NULL, NULL); @@ -740,29 +740,25 @@ static int TestchmodCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ - int argc, /* Number of arguments. */ - const char **argv) /* Argument strings. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const *objv) /* Argument strings. */ { int i, mode; - char *rest; - if (argc < 2) { - usage: - Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], - " mode file ?file ...?", NULL); + if (objc < 2) { + Tcl_WrongNumArgs(interp, 1, objv, "mode file ?file ...?"); return TCL_ERROR; } - mode = (int) strtol(argv[1], &rest, 8); - if ((rest == argv[1]) || (*rest != '\0')) { - goto usage; + if (Tcl_GetIntFromObj(interp, objv[1], &mode) != TCL_OK) { + return TCL_ERROR; } - for (i = 2; i < argc; i++) { + for (i = 2; i < objc; i++) { Tcl_DString buffer; const char *translated; - translated = Tcl_TranslateFileName(interp, argv[i], &buffer); + translated = Tcl_TranslateFileName(interp, Tcl_GetString(objv[i]), &buffer); if (translated == NULL) { return TCL_ERROR; } diff --git a/unix/tclXtTest.c b/unix/tclXtTest.c index fcb0773..f7c2652 100644 --- a/unix/tclXtTest.c +++ b/unix/tclXtTest.c @@ -15,7 +15,7 @@ #include #include "tcl.h" -static Tcl_CmdProc TesteventloopCmd; +static Tcl_ObjCmdProc TesteventloopCmd; extern DLLEXPORT Tcl_PackageInitProc Tclxttest_Init; /* @@ -53,7 +53,7 @@ Tclxttest_Init( } XtToolkitInitialize(); InitNotifier(); - Tcl_CreateCommand(interp, "testeventloop", TesteventloopCmd, + Tcl_CreateObjCommand(interp, "testeventloop", TesteventloopCmd, NULL, NULL); return TCL_OK; } @@ -80,21 +80,20 @@ static int TesteventloopCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ - int argc, /* Number of arguments. */ - const char **argv) /* Argument strings. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument objects. */ { static int *framePtr = NULL;/* Pointer to integer on stack frame of * innermost invocation of the "wait" * subcommand. */ - if (argc < 2) { - Tcl_AppendResult(interp, "wrong # arguments: should be \"", argv[0], - " option ... \"", NULL); + if (objc < 2) { + Tcl_WrongNumArgs(interp, 1, objv, "option ..."); return TCL_ERROR; } - if (strcmp(argv[1], "done") == 0) { + if (strcmp(Tcl_GetString(objv[1]), "done") == 0) { *framePtr = 1; - } else if (strcmp(argv[1], "wait") == 0) { + } else if (strcmp(Tcl_GetString(objv[1]), "wait") == 0) { int *oldFramePtr; int done; int oldMode = Tcl_SetServiceMode(TCL_SERVICE_ALL); @@ -118,7 +117,7 @@ TesteventloopCmd( (void) Tcl_SetServiceMode(oldMode); framePtr = oldFramePtr; } else { - Tcl_AppendResult(interp, "bad option \"", argv[1], + Tcl_AppendResult(interp, "bad option \"", Tcl_GetString(objv[1]), "\": must be done or wait", NULL); return TCL_ERROR; } diff --git a/win/tclWinTest.c b/win/tclWinTest.c index 6027e32..b3ad626 100644 --- a/win/tclWinTest.c +++ b/win/tclWinTest.c @@ -32,8 +32,8 @@ * Forward declarations of functions defined later in this file: */ -static int TesteventloopCmd(ClientData dummy, Tcl_Interp *interp, - int argc, const char **argv); +static int TesteventloopCmd(ClientData dummy, Tcl_Interp* interp, + int objc, Tcl_Obj *const objv[]); static int TestvolumetypeCmd(ClientData dummy, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); @@ -43,8 +43,8 @@ static int TestwinsleepCmd(ClientData dummy, Tcl_Interp* interp, int objc, Tcl_Obj *const objv[]); static Tcl_ObjCmdProc TestExceptionCmd; static int TestplatformChmod(const char *nativePath, int pmode); -static int TestchmodCmd(ClientData dummy, - Tcl_Interp *interp, int argc, const char **argv); +static int TestchmodCmd(ClientData dummy, Tcl_Interp* interp, + int objc, Tcl_Obj *const objv[]); /* *---------------------------------------------------------------------- @@ -71,8 +71,8 @@ TclplatformtestInit( * Add commands for platform specific tests for Windows here. */ - Tcl_CreateCommand(interp, "testchmod", TestchmodCmd, NULL, NULL); - Tcl_CreateCommand(interp, "testeventloop", TesteventloopCmd, NULL, NULL); + Tcl_CreateObjCommand(interp, "testchmod", TestchmodCmd, NULL, NULL); + Tcl_CreateObjCommand(interp, "testeventloop", TesteventloopCmd, NULL, NULL); Tcl_CreateObjCommand(interp, "testvolumetype", TestvolumetypeCmd, NULL, NULL); Tcl_CreateObjCommand(interp, "testwinclock", TestwinclockCmd, NULL, NULL); @@ -103,21 +103,20 @@ static int TesteventloopCmd( ClientData clientData, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ - int argc, /* Number of arguments. */ - const char **argv) /* Argument strings. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument objects. */ { static int *framePtr = NULL;/* Pointer to integer on stack frame of * innermost invocation of the "wait" * subcommand. */ - if (argc < 2) { - Tcl_AppendResult(interp, "wrong # arguments: should be \"", argv[0], - " option ... \"", NULL); + if (objc < 2) { + Tcl_WrongNumArgs(interp, 1, objv, "option ..."); return TCL_ERROR; } - if (strcmp(argv[1], "done") == 0) { + if (strcmp(Tcl_GetString(objv[1]), "done") == 0) { *framePtr = 1; - } else if (strcmp(argv[1], "wait") == 0) { + } else if (strcmp(Tcl_GetString(objv[1]), "wait") == 0) { int *oldFramePtr, done; int oldMode = Tcl_SetServiceMode(TCL_SERVICE_ALL); @@ -152,7 +151,7 @@ TesteventloopCmd( (void) Tcl_SetServiceMode(oldMode); framePtr = oldFramePtr; } else { - Tcl_AppendResult(interp, "bad option \"", argv[1], + Tcl_AppendResult(interp, "bad option \"", Tcl_GetString(objv[1]), "\": must be done or wait", NULL); return TCL_ERROR; } @@ -623,29 +622,25 @@ static int TestchmodCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ - int argc, /* Number of arguments. */ - const char **argv) /* Argument strings. */ + int objc, /* Parameter count */ + Tcl_Obj *const * objv) /* Parameter vector */ { int i, mode; - char *rest; - if (argc < 2) { - usage: - Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], - " mode file ?file ...?", NULL); + if (objc < 2) { + Tcl_WrongNumArgs(interp, 1, objv, "mode file ?file ...?"); return TCL_ERROR; } - mode = (int) strtol(argv[1], &rest, 8); - if ((rest == argv[1]) || (*rest != '\0')) { - goto usage; + if (Tcl_GetIntFromObj(interp, objv[1], &mode) != TCL_OK) { + return TCL_ERROR; } - for (i = 2; i < argc; i++) { + for (i = 2; i < objc; i++) { Tcl_DString buffer; const char *translated; - translated = Tcl_TranslateFileName(interp, argv[i], &buffer); + translated = Tcl_TranslateFileName(interp, Tcl_GetString(objv[i]), &buffer); if (translated == NULL) { return TCL_ERROR; } -- cgit v0.12 From f345a78f27405687b67e234daf63f3464d1aacec Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 17 Jul 2014 15:48:59 +0000 Subject: Revised fix for memleak in [info frame]. Still pretty ugly, but not more so than a lot of TIP 280 machinery. --- generic/tclCmdIL.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/generic/tclCmdIL.c b/generic/tclCmdIL.c index a26d6cc..d723e4b 100644 --- a/generic/tclCmdIL.c +++ b/generic/tclCmdIL.c @@ -1287,6 +1287,7 @@ TclInfoFrame( "eval", "eval", "eval", "precompiled", "source", "proc" }; Proc *procPtr = framePtr->framePtr ? framePtr->framePtr->procPtr : NULL; + int needsFree = -1; /* * Pull the information and construct the dictionary to return, as list. @@ -1360,6 +1361,9 @@ TclInfoFrame( } ADD_PAIR("cmd", TclGetSourceFromFrame(fPtr, 0, NULL)); + if (fPtr->cmdObj && framePtr->cmdObj == NULL) { + needsFree = lc - 1; + } TclStackFree(interp, fPtr); break; } @@ -1447,7 +1451,11 @@ TclInfoFrame( } } - return Tcl_NewListObj(lc, lv); + tmpObj = Tcl_NewListObj(lc, lv); + if (needsFree >= 0) { + Tcl_DecrRefCount(lv[needsFree]); + } + return tmpObj; } /* -- cgit v0.12 From d2d54ff3de674eadeb05d439b443e1c2658caf8f Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Thu, 17 Jul 2014 18:43:55 +0000 Subject: Finally, use correct octal notation which works in Tcl 9 as well. --- tests/cmdAH.test | 10 +++---- tests/fCmd.test | 82 ++++++++++++++++++++++++++--------------------------- tests/tcltest.test | 2 +- tests/unixFCmd.test | 2 +- tests/winFCmd.test | 22 +++++++------- 5 files changed, 59 insertions(+), 59 deletions(-) diff --git a/tests/cmdAH.test b/tests/cmdAH.test index 04a86fa..64cfeba 100644 --- a/tests/cmdAH.test +++ b/tests/cmdAH.test @@ -829,13 +829,13 @@ test cmdAH-16.1 {Tcl_FileObjCmd: readable} { } test cmdAH-16.2 {Tcl_FileObjCmd: readable} { -constraints testchmod - -setup {testchmod 0444 $gorpfile} + -setup {testchmod 0o444 $gorpfile} -body {file readable $gorpfile} -result 1 } test cmdAH-16.3 {Tcl_FileObjCmd: readable} { -constraints {unix notRoot testchmod} - -setup {testchmod 0333 $gorpfile} + -setup {testchmod 0o333 $gorpfile} -body {file readable $gorpfile} -result 0 } @@ -848,13 +848,13 @@ test cmdAH-17.1 {Tcl_FileObjCmd: writable} { } test cmdAH-17.2 {Tcl_FileObjCmd: writable} { -constraints {notRoot testchmod} - -setup {testchmod 0555 $gorpfile} + -setup {testchmod 0o555 $gorpfile} -body {file writable $gorpfile} -result 0 } test cmdAH-17.3 {Tcl_FileObjCmd: writable} { -constraints testchmod - -setup {testchmod 0222 $gorpfile} + -setup {testchmod 0o222 $gorpfile} -body {file writable $gorpfile} -result 1 } @@ -873,7 +873,7 @@ test cmdAH-18.2 {Tcl_FileObjCmd: executable} {notRoot} { test cmdAH-18.3 {Tcl_FileObjCmd: executable} {unix testchmod} { # Only on unix will setting the execute bit on a regular file cause that # file to be executable. - testchmod 0775 $gorpfile + testchmod 0o775 $gorpfile file exe $gorpfile } 1 test cmdAH-18.5 {Tcl_FileObjCmd: executable} -constraints {win} -body { diff --git a/tests/fCmd.test b/tests/fCmd.test index c479e35..c8264b2 100644 --- a/tests/fCmd.test +++ b/tests/fCmd.test @@ -128,7 +128,7 @@ proc checkcontent {file matchString} { } proc openup {path} { - testchmod 0777 $path + testchmod 0o777 $path if {[file isdirectory $path]} { catch { foreach p [glob -directory $path *] { @@ -365,7 +365,7 @@ test fCmd-4.11 {TclFileMakeDirsCmd: doesn't exist: errno != ENOENT} -setup { testchmod 0 td1/td2 file mkdir td1/td2/td3/td4 } -cleanup { - testchmod 0755 td1/td2 + testchmod 0o755 td1/td2 cleanup } -result {can't create directory "td1/td2/td3": permission denied} test fCmd-4.13 {TclFileMakeDirsCmd: doesn't exist: errno == ENOENT} -setup { @@ -509,7 +509,7 @@ test fCmd-6.6 {CopyRenameOneFile: errno != ENOENT} -setup { createfile tf1 file rename tf1 td1 } -returnCodes error -cleanup { - testchmod 0755 td1 + testchmod 0o755 td1 } -result {error renaming "tf1" to "td1/tf1": permission denied} test fCmd-6.9 {CopyRenameOneFile: errno == ENOENT} -setup { cleanup @@ -785,7 +785,7 @@ test fCmd-9.3 {file rename: comprehensive: file to new name} -setup { } -constraints {notRoot testchmod} -body { createfile tf1 createfile tf2 - testchmod 0444 tf2 + testchmod 0o444 tf2 file rename tf1 tf3 file rename tf2 tf4 list [lsort [glob tf*]] [file writable tf3] [file writable tf4] @@ -794,7 +794,7 @@ test fCmd-9.4.a {file rename: comprehensive: dir to new name} -setup { cleanup } -constraints {win win2000orXP testchmod} -body { file mkdir td1 td2 - testchmod 0555 td2 + testchmod 0o555 td2 file rename td1 td3 file rename td2 td4 list [lsort [glob td*]] [file writable td3] [file writable td4] @@ -805,7 +805,7 @@ test fCmd-9.4.b {file rename: comprehensive: dir to new name} -setup { cleanup } -constraints {unix notRoot testchmod notDarwin9} -body { file mkdir td1 td2 - testchmod 0555 td2 + testchmod 0o555 td2 file rename td1 td3 file rename td2 td4 list [lsort [glob td*]] [file writable td3] [file writable td4] @@ -817,7 +817,7 @@ test fCmd-9.5 {file rename: comprehensive: file to self} -setup { } -constraints {notRoot testchmod} -body { createfile tf1 tf1 createfile tf2 tf2 - testchmod 0444 tf2 + testchmod 0o444 tf2 file rename -force tf1 tf1 file rename -force tf2 tf2 list [contents tf1] [contents tf2] [file writable tf1] [file writable tf2] @@ -827,7 +827,7 @@ test fCmd-9.6.a {file rename: comprehensive: dir to self} -setup { } -constraints {win win2000orXP testchmod} -body { file mkdir td1 file mkdir td2 - testchmod 0555 td2 + testchmod 0o555 td2 file rename -force td1 . file rename -force td2 . list [lsort [glob td*]] [file writable td1] [file writable td2] @@ -837,7 +837,7 @@ test fCmd-9.6.b {file rename: comprehensive: dir to self} -setup { } -constraints {unix notRoot testchmod} -body { file mkdir td1 file mkdir td2 - testchmod 0555 td2 + testchmod 0o555 td2 file rename -force td1 . file rename -force td2 . list [lsort [glob td*]] [file writable td1] [file writable td2] @@ -855,10 +855,10 @@ test fCmd-9.7 {file rename: comprehensive: file to existing file} -setup { createfile tfd2 createfile tfd3 createfile tfd4 - testchmod 0444 tfs3 - testchmod 0444 tfs4 - testchmod 0444 tfd2 - testchmod 0444 tfd4 + testchmod 0o444 tfs3 + testchmod 0o444 tfs4 + testchmod 0o444 tfd2 + testchmod 0o444 tfd4 set msg [list [catch {file rename tf1 tf2} msg] $msg] file rename -force tfs1 tfd1 file rename -force tfs2 tfd2 @@ -882,11 +882,11 @@ test fCmd-9.8 {file rename: comprehensive: dir to empty dir} -setup { file mkdir [file join tdd3 tds3] file mkdir [file join tdd4 tds4] if {![testConstraint unix]} { - testchmod 0555 tds3 - testchmod 0555 tds4 + testchmod 0o555 tds3 + testchmod 0o555 tds4 } - testchmod 0555 [file join tdd2 tds2] - testchmod 0555 [file join tdd4 tds4] + testchmod 0o555 [file join tdd2 tds2] + testchmod 0o555 [file join tdd4 tds4] set msg [list [catch {file rename td1 td2} msg] $msg] file rename -force tds1 tdd1 file rename -force tds2 tdd2 @@ -911,7 +911,7 @@ test fCmd-9.9 {file rename: comprehensive: dir to non-empty dir} -setup { file mkdir [file join tdd1 tds1 xxx] file mkdir [file join tdd2 tds2 xxx] if {!([testConstraint unix] || [testConstraint winVista])} { - testchmod 0555 tds2 + testchmod 0o555 tds2 } set a1 [list [catch {file rename -force tds1 tdd1} msg] $msg] set a2 [list [catch {file rename -force tds2 tdd2} msg] $msg] @@ -929,7 +929,7 @@ test fCmd-9.10 {file rename: comprehensive: file to new name and dir} -setup { createfile tf1 createfile tf2 file mkdir td1 - testchmod 0444 tf2 + testchmod 0o444 tf2 file rename tf1 [file join td1 tf3] file rename tf2 [file join td1 tf4] list [catch {glob tf*}] [lsort [glob -directory td1 t*]] \ @@ -942,7 +942,7 @@ test fCmd-9.11 {file rename: comprehensive: dir to new name and dir} -setup { file mkdir td2 file mkdir td3 if {!([testConstraint unix] || [testConstraint winVista])} { - testchmod 0555 td2 + testchmod 0o555 td2 } file rename td1 [file join td3 td3] file rename td2 [file join td3 td4] @@ -958,13 +958,13 @@ test fCmd-9.12 {file rename: comprehensive: target exists} -setup { cleanup } -constraints {notRoot testchmod notNetworkFilesystem} -body { file mkdir [file join td1 td2] [file join td2 td1] - testchmod 0555 [file join td2 td1] + testchmod 0o555 [file join td2 td1] file mkdir [file join td3 td4] [file join td4 td3] file rename -force td3 td4 list [file exists td3] [file exists [file join td4 td3 td4]] \ [catch {file rename td1 td2} msg] $msg } -cleanup { - testchmod 0755 [file join td2 td1] + testchmod 0o755 [file join td2 td1] } -result [subst {0 1 1 {error renaming "td1" to "[file join td2 td1]": file already exists}}] # Test can hit EEXIST or EBUSY, depending on underlying filesystem test fCmd-9.13 {file rename: comprehensive: can't overwrite target} -setup { @@ -1035,7 +1035,7 @@ test fCmd-10.2 {file copy: comprehensive: file to new name} -setup { } -constraints {notRoot testchmod} -body { createfile tf1 tf1 createfile tf2 tf2 - testchmod 0444 tf2 + testchmod 0o444 tf2 file copy tf1 tf3 file copy tf2 tf4 list [lsort [glob tf*]] [contents tf3] [contents tf4] [file writable tf3] [file writable tf4] @@ -1045,14 +1045,14 @@ test fCmd-10.3 {file copy: comprehensive: dir to new name} -setup { } -constraints {unix notRoot testchmod} -body { file mkdir [file join td1 tdx] file mkdir [file join td2 tdy] - testchmod 0555 td2 + testchmod 0o555 td2 file copy td1 td3 file copy td2 td4 list [lsort [glob td*]] [glob -directory td3 t*] \ [glob -directory td4 t*] [file writable td3] [file writable td4] } -cleanup { - testchmod 0755 td2 - testchmod 0755 td4 + testchmod 0o755 td2 + testchmod 0o755 td4 } -result [list {td1 td2 td3 td4} [file join td3 tdx] [file join td4 tdy] 1 0] test fCmd-10.3.1 {file copy: comprehensive: dir to new name} -setup { cleanup @@ -1060,14 +1060,14 @@ test fCmd-10.3.1 {file copy: comprehensive: dir to new name} -setup { # On Windows with ACLs, copying a directory is defined like this file mkdir [file join td1 tdx] file mkdir [file join td2 tdy] - testchmod 0555 td2 + testchmod 0o555 td2 file copy td1 td3 file copy td2 td4 list [lsort [glob td*]] [glob -directory td3 t*] \ [glob -directory td4 t*] [file writable td3] [file writable td4] } -cleanup { - testchmod 0755 td2 - testchmod 0755 td4 + testchmod 0o755 td2 + testchmod 0o755 td4 } -result [list {td1 td2 td3 td4} [file join td3 tdx] [file join td4 tdy] 1 1] test fCmd-10.4 {file copy: comprehensive: file to existing file} -setup { cleanup @@ -1082,10 +1082,10 @@ test fCmd-10.4 {file copy: comprehensive: file to existing file} -setup { createfile tfd2 createfile tfd3 createfile tfd4 - testchmod 0444 tfs3 - testchmod 0444 tfs4 - testchmod 0444 tfd2 - testchmod 0444 tfd4 + testchmod 0o444 tfs3 + testchmod 0o444 tfs4 + testchmod 0o444 tfd2 + testchmod 0o444 tfd4 set msg [list [catch {file copy tf1 tf2} msg] $msg] file copy -force tfs1 tfd1 file copy -force tfs2 tfd2 @@ -1106,10 +1106,10 @@ test fCmd-10.5 {file copy: comprehensive: dir to empty dir} -setup { file mkdir [file join tdd2 tds2] file mkdir [file join tdd3 tds3] file mkdir [file join tdd4 tds4] - testchmod 0555 tds3 - testchmod 0555 tds4 - testchmod 0555 [file join tdd2 tds2] - testchmod 0555 [file join tdd4 tds4] + testchmod 0o555 tds3 + testchmod 0o555 tds4 + testchmod 0o555 [file join tdd2 tds2] + testchmod 0o555 [file join tdd4 tds4] set a1 [list [catch {file copy td1 td2} msg] $msg] set a2 [list [catch {file copy -force tds1 tdd1} msg] $msg] set a3 [catch {file copy -force tds2 tdd2}] @@ -1124,7 +1124,7 @@ test fCmd-10.6 {file copy: comprehensive: dir to non-empty dir} -setup { file mkdir tds2 file mkdir [file join tdd1 tds1 xxx] file mkdir [file join tdd2 tds2 xxx] - testchmod 0555 tds2 + testchmod 0o555 tds2 set a1 [list [catch {file copy -force tds1 tdd1} msg] $msg] set a2 [list [catch {file copy -force tds2 tdd2} msg] $msg] list [lsort [glob td*]] $a1 $a2 [file writable tds1] [file writable tds2] @@ -1135,7 +1135,7 @@ test fCmd-10.7 {file rename: comprehensive: file to new name and dir} -setup { createfile tf1 createfile tf2 file mkdir td1 - testchmod 0444 tf2 + testchmod 0o444 tf2 file copy tf1 [file join td1 tf3] file copy tf2 [file join td1 tf4] list [lsort [glob tf*]] [lsort [glob -directory td1 t*]] \ @@ -1147,7 +1147,7 @@ test fCmd-10.8 {file rename: comprehensive: dir to new name and dir} -setup { file mkdir td1 file mkdir td2 file mkdir td3 - testchmod 0555 td2 + testchmod 0o555 td2 file copy td1 [file join td3 td3] file copy td2 [file join td3 td4] list [lsort [glob td*]] [lsort [glob -directory td3 t*]] \ @@ -1160,7 +1160,7 @@ test fCmd-10.8.1 {file rename: comprehensive: dir to new name and dir} -setup { file mkdir td1 file mkdir td2 file mkdir td3 - testchmod 0555 td2 + testchmod 0o555 td2 file copy td1 [file join td3 td3] file copy td2 [file join td3 td4] list [lsort [glob td*]] [lsort [glob -directory td3 t*]] \ diff --git a/tests/tcltest.test b/tests/tcltest.test index 5894308..e66678b 100644 --- a/tests/tcltest.test +++ b/tests/tcltest.test @@ -717,7 +717,7 @@ switch -- $::tcl_platform(platform) { file attributes $notWriteableDir -permissions 777 } default { - catch {testchmod 0777 $notWriteableDir} + catch {testchmod 0o777 $notWriteableDir} catch {file attributes $notWriteableDir -readonly 0} } } diff --git a/tests/unixFCmd.test b/tests/unixFCmd.test index 3755fed..2d227fe 100644 --- a/tests/unixFCmd.test +++ b/tests/unixFCmd.test @@ -59,7 +59,7 @@ if {[testConstraint unix]} { } proc openup {path} { - testchmod 0777 $path + testchmod 0o777 $path if {[file isdirectory $path]} { catch { foreach p [glob -directory $path *] { diff --git a/tests/winFCmd.test b/tests/winFCmd.test index 14d3d07..ab675d7 100644 --- a/tests/winFCmd.test +++ b/tests/winFCmd.test @@ -340,7 +340,7 @@ test winFCmd-1.33 {TclpRenameFile: After removing dst dir, MoveFile fails} \ catch {testfile mv c:/tf1 d:/td1} msg list $msg [file writable d:/td1] } -cleanup { - catch {testchmod 0666 d:/td1} + catch {testchmod 0o666 d:/td1} file delete d:/td1 file delete -force c:/tf1 } -result {EXDEV 0} @@ -493,7 +493,7 @@ test winFCmd-2.12 {TclpCopyFile: CopyFile succeeds} -setup { testfile cp tf1 tf2 list [contents tf2] [file writable tf2] } -cleanup { - catch {testchmod 0666 tf1} + catch {testchmod 0o666 tf1} cleanup } -result {tf1 0} test winFCmd-2.13 {TclpCopyFile: CopyFile fails} -setup { @@ -539,7 +539,7 @@ test winFCmd-2.17 {TclpCopyFile: dst is readonly} -setup { testfile cp tf1 tf2 list [file writable tf2] [contents tf2] } -cleanup { - catch {testchmod 0666 tf2} + catch {testchmod 0o666 tf2} cleanup } -result {1 tf1} @@ -617,7 +617,7 @@ test winFCmd-3.11 {TclpDeleteFile: still can't remove path} -setup { testfile rm tf1 } -cleanup { close $fd - catch {testchmod 0666 tf1} + catch {testchmod 0o666 tf1} cleanup } -returnCodes error -result EACCES @@ -662,7 +662,7 @@ test winFCmd-6.1 {TclpRemoveDirectory: errno: EACCES} -setup { testfile rmdir td1 file exists td1 } -returnCodes error -cleanup { - catch {testchmod 0666 td1} + catch {testchmod 0o666 td1} cleanup } -result {td1 EACCES} # This next test has a very hokey way of matching... @@ -716,7 +716,7 @@ test winFCmd-6.9 {TclpRemoveDirectory: errno == EACCES} -setup { testfile rmdir td1 file exists td1 } -returnCodes error -cleanup { - catch {testchmod 0666 td1} + catch {testchmod 0o666 td1} cleanup } -result {td1 EACCES} test winFCmd-6.11 {TclpRemoveDirectory: attr == -1} -setup { @@ -734,7 +734,7 @@ test winFCmd-6.13 {TclpRemoveDirectory: write-protected} -setup { testfile rmdir td1 file exists td1 } -cleanup { - catch {testchmod 0666 td1} + catch {testchmod 0o666 td1} cleanup } -returnCodes error -result {td1 EACCES} # This next test has a very hokey way of matching... @@ -834,7 +834,7 @@ test winFCmd-7.11 {TraverseWinTree: call TraversalCopy: DOTREE_PRED} -setup { testfile cpdir td1 td2 list [file exists td2] [file writable td2] } -cleanup { - catch {testchmod 0666 td1} + catch {testchmod 0o666 td1} cleanup } -result {1 1} test winFCmd-7.12 {TraverseWinTree: call TraversalDelete: DOTREE_PRED} -setup { @@ -905,7 +905,7 @@ test winFCmd-7.19 {TraverseWinTree: call TraversalCopy: DOTREE_POSTD} -setup { testfile cpdir td1 td2 list [file exists td2] [file writable td2] } -cleanup { - catch {testchmod 0666 td1} + catch {testchmod 0o666 td1} cleanup } -result {1 1} test winFCmd-7.20 {TraverseWinTree: call TraversalDelete: DOTREE_POSTD} -setup { @@ -936,7 +936,7 @@ test winFCmd-8.2 {TraversalCopy: DOTREE_PRED} -setup { testfile cpdir td1 td2 list [file writable td1] [file writable td1/td2] } -cleanup { - catch {testchmod 0666 td1} + catch {testchmod 0o666 td1} cleanup } -result {0 1} test winFCmd-8.3 {TraversalCopy: DOTREE_POSTD} -setup { @@ -963,7 +963,7 @@ test winFCmd-9.3 {TraversalDelete: DOTREE_PRED} -setup { testfile rmdir -force td1 file exists td1 } -cleanup { - catch {testchmod 0666 td1} + catch {testchmod 0o666 td1} cleanup } -returnCodes error -result {td1 EACCES} test winFCmd-9.4 {TraversalDelete: DOTREE_POSTD} -setup { -- cgit v0.12 From 6cd3ffa2465b9f50cbb6baeab7cc2b8b072e680d Mon Sep 17 00:00:00 2001 From: dkf Date: Fri, 18 Jul 2014 12:18:44 +0000 Subject: [b43f2b49f7] New compilation strategy for lappend that allows multi-value lappend to not have quadratic performance (through better reference management). --- generic/tclAssembly.c | 4 ++ generic/tclCompCmdsGR.c | 60 +++++------------ generic/tclCompile.c | 13 ++++ generic/tclCompile.h | 7 +- generic/tclExecute.c | 167 +++++++++++++++++++++++++++++++++++++++++++++++- 5 files changed, 206 insertions(+), 45 deletions(-) diff --git a/generic/tclAssembly.c b/generic/tclAssembly.c index d1866c8..6d5676b 100644 --- a/generic/tclAssembly.c +++ b/generic/tclAssembly.c @@ -410,6 +410,10 @@ static const TalInstDesc TalInstructionTable[] = { {"lappendArray", ASSEM_LVT, (INST_LAPPEND_ARRAY1<<8 | INST_LAPPEND_ARRAY4),2, 1}, {"lappendArrayStk", ASSEM_1BYTE, INST_LAPPEND_ARRAY_STK, 3, 1}, + {"lappendList", ASSEM_LVT4, INST_LAPPEND_LIST, 1, 1}, + {"lappendListArray",ASSEM_LVT4, INST_LAPPEND_LIST_ARRAY,2, 1}, + {"lappendListArrayStk", ASSEM_1BYTE,INST_LAPPEND_LIST_ARRAY_STK, 3, 1}, + {"lappendListStk", ASSEM_1BYTE, INST_LAPPEND_LIST_STK, 2, 1}, {"lappendStk", ASSEM_1BYTE, INST_LAPPEND_STK, 2, 1}, {"le", ASSEM_1BYTE, INST_LE, 2, 1}, {"lindexMulti", ASSEM_LINDEX_MULTI, diff --git a/generic/tclCompCmdsGR.c b/generic/tclCompCmdsGR.c index b3e273f..166fea0 100644 --- a/generic/tclCompCmdsGR.c +++ b/generic/tclCompCmdsGR.c @@ -868,28 +868,16 @@ TclCompileLappendCmd( CompileEnv *envPtr) /* Holds resulting instructions. */ { Tcl_Token *varTokenPtr, *valueTokenPtr; - int isScalar, localIndex, numWords, i, fwd, offsetFwd; + int isScalar, localIndex, numWords, i; DefineLineInformation; /* TIP #280 */ - /* - * If we're not in a procedure, don't compile. - */ - - if (envPtr->procPtr == NULL) { - return TCL_ERROR; - } - /* TODO: Consider support for compiling expanded args. */ numWords = parsePtr->numWords; if (numWords == 1) { return TCL_ERROR; } - if (numWords != 3) { - /* - * LAPPEND instructions currently only handle one value, but we can - * handle some multi-value cases by stringing them together. - */ + if (numWords != 3 || envPtr->procPtr == NULL) { goto lappendMultiple; } @@ -943,42 +931,28 @@ TclCompileLappendCmd( return TCL_OK; lappendMultiple: - /* - * Can only handle the case where we are appending to a local scalar when - * there are multiple values to append. Fortunately, this is common. - */ - - if (envPtr->procPtr == NULL) { - return TCL_ERROR; - } varTokenPtr = TokenAfter(parsePtr->tokenPtr); - PushVarNameWord(interp, varTokenPtr, envPtr, TCL_NO_ELEMENT, + PushVarNameWord(interp, varTokenPtr, envPtr, 0, &localIndex, &isScalar, 1); - if (!isScalar || localIndex < 0) { - return TCL_ERROR; - } - - /* - * Definitely appending to a local scalar; generate the words and append - * them. - */ - valueTokenPtr = TokenAfter(varTokenPtr); for (i = 2 ; i < numWords ; i++) { CompileWord(envPtr, valueTokenPtr, interp, i); valueTokenPtr = TokenAfter(valueTokenPtr); } - TclEmitInstInt4( INST_LIST, numWords-2, envPtr); - TclEmitInstInt4( INST_EXIST_SCALAR, localIndex, envPtr); - offsetFwd = CurrentOffset(envPtr); - TclEmitInstInt1( INST_JUMP_FALSE1, 0, envPtr); - Emit14Inst( INST_LOAD_SCALAR, localIndex, envPtr); - TclEmitInstInt4( INST_REVERSE, 2, envPtr); - TclEmitOpcode( INST_LIST_CONCAT, envPtr); - fwd = CurrentOffset(envPtr) - offsetFwd; - TclStoreInt1AtPtr(fwd, envPtr->codeStart+offsetFwd+1); - Emit14Inst( INST_STORE_SCALAR, localIndex, envPtr); - + TclEmitInstInt4( INST_LIST, numWords-2, envPtr); + if (isScalar) { + if (localIndex < 0) { + TclEmitOpcode( INST_LAPPEND_LIST_STK, envPtr); + } else { + TclEmitInstInt4(INST_LAPPEND_LIST, localIndex, envPtr); + } + } else { + if (localIndex < 0) { + TclEmitOpcode( INST_LAPPEND_LIST_ARRAY_STK, envPtr); + } else { + TclEmitInstInt4(INST_LAPPEND_LIST_ARRAY, localIndex,envPtr); + } + } return TCL_OK; } diff --git a/generic/tclCompile.c b/generic/tclCompile.c index 347e3f0..838b195 100644 --- a/generic/tclCompile.c +++ b/generic/tclCompile.c @@ -650,6 +650,19 @@ InstructionDesc const tclInstructionTable[] = { * satisfy the class check (standard definition of "all"). * Stack: ... stringValue => ... boolean */ + {"lappendList", 5, 0, 1, {OPERAND_LVT4}}, + /* Lappend list to scalar variable at op4 in frame. + * Stack: ... list => ... listVarContents */ + {"lappendListArray", 5, -1, 1, {OPERAND_LVT4}}, + /* Lappend list to array element; array at op4. + * Stack: ... elem list => ... listVarContents */ + {"lappendListArrayStk", 1, -2, 0, {OPERAND_NONE}}, + /* Lappend list to array element. + * Stack: ... arrayName elem list => ... listVarContents */ + {"lappendListStk", 1, -1, 0, {OPERAND_NONE}}, + /* Lappend list to general variable. + * Stack: ... varName list => ... listVarContents */ + {NULL, 0, 0, 0, {OPERAND_NONE}} }; diff --git a/generic/tclCompile.h b/generic/tclCompile.h index 5665ca9..fa4a360 100644 --- a/generic/tclCompile.h +++ b/generic/tclCompile.h @@ -799,8 +799,13 @@ typedef struct ByteCode { #define INST_TRY_CVT_TO_BOOLEAN 183 #define INST_STR_CLASS 184 +#define INST_LAPPEND_LIST 185 +#define INST_LAPPEND_LIST_ARRAY 186 +#define INST_LAPPEND_LIST_ARRAY_STK 187 +#define INST_LAPPEND_LIST_STK 188 + /* The last opcode */ -#define LAST_INST_OPCODE 184 +#define LAST_INST_OPCODE 188 /* * Table describing the Tcl bytecode instructions: their name (for displaying diff --git a/generic/tclExecute.c b/generic/tclExecute.c index 0cd074d..2098e50 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -3347,7 +3347,7 @@ TEBCresume( */ { - int storeFlags; + int storeFlags, len; case INST_STORE_ARRAY4: opnd = TclGetUInt4AtPtr(pc+1); @@ -3587,6 +3587,171 @@ TEBCresume( #endif TRACE_APPEND(("%.30s\n", O2S(objResultPtr))); NEXT_INST_V(pcAdjustment, cleanup, 1); + + case INST_LAPPEND_LIST: + opnd = TclGetUInt4AtPtr(pc+1); + valuePtr = OBJ_AT_TOS; + varPtr = LOCAL(opnd); + cleanup = 1; + pcAdjustment = 5; + while (TclIsVarLink(varPtr)) { + varPtr = varPtr->value.linkPtr; + } + TRACE(("%u <- \"%.30s\" => ", opnd, O2S(valuePtr))); + if (TclListObjGetElements(interp, valuePtr, &objc, &objv) + != TCL_OK) { + TRACE_ERROR(interp); + goto gotError; + } + if (TclIsVarDirectReadable(varPtr) + && TclIsVarDirectWritable(varPtr)) { + goto lappendListDirect; + } + arrayPtr = NULL; + part1Ptr = part2Ptr = NULL; + goto lappendListPtr; + + case INST_LAPPEND_LIST_ARRAY: + opnd = TclGetUInt4AtPtr(pc+1); + valuePtr = OBJ_AT_TOS; + part1Ptr = NULL; + part2Ptr = OBJ_UNDER_TOS; + arrayPtr = LOCAL(opnd); + cleanup = 2; + pcAdjustment = 5; + while (TclIsVarLink(arrayPtr)) { + arrayPtr = arrayPtr->value.linkPtr; + } + TRACE(("%u \"%.30s\" \"%.30s\" => ", + opnd, O2S(part2Ptr), O2S(valuePtr))); + if (TclListObjGetElements(interp, valuePtr, &objc, &objv) + != TCL_OK) { + TRACE_ERROR(interp); + goto gotError; + } + if (TclIsVarArray(arrayPtr) && !ReadTraced(arrayPtr) + && !WriteTraced(arrayPtr)) { + varPtr = VarHashFindVar(arrayPtr->value.tablePtr, part2Ptr); + if (varPtr && TclIsVarDirectReadable(varPtr) + && TclIsVarDirectWritable(varPtr)) { + goto lappendListDirect; + } + } + varPtr = TclLookupArrayElement(interp, part1Ptr, part2Ptr, + TCL_LEAVE_ERR_MSG, "set", 1, 1, arrayPtr, opnd); + if (varPtr == NULL) { + TRACE_ERROR(interp); + goto gotError; + } + goto lappendListPtr; + + case INST_LAPPEND_LIST_ARRAY_STK: + pcAdjustment = 1; + cleanup = 3; + valuePtr = OBJ_AT_TOS; + part2Ptr = OBJ_UNDER_TOS; /* element name */ + part1Ptr = OBJ_AT_DEPTH(2); /* array name */ + TRACE(("\"%.30s(%.30s)\" \"%.30s\" => ", + O2S(part1Ptr), O2S(part2Ptr), O2S(valuePtr))); + goto lappendList; + + case INST_LAPPEND_LIST_STK: + pcAdjustment = 1; + cleanup = 2; + valuePtr = OBJ_AT_TOS; + part2Ptr = NULL; + part1Ptr = OBJ_UNDER_TOS; /* variable name */ + TRACE(("\"%.30s\" \"%.30s\" => ", O2S(part1Ptr), O2S(valuePtr))); + goto lappendList; + + lappendListDirect: + objResultPtr = varPtr->value.objPtr; + if (TclListObjLength(interp, objResultPtr, &len) != TCL_OK) { + TRACE_ERROR(interp); + goto gotError; + } + if (Tcl_IsShared(objResultPtr)) { + Tcl_Obj *newValue = Tcl_DuplicateObj(objResultPtr); + + TclDecrRefCount(objResultPtr); + varPtr->value.objPtr = objResultPtr = newValue; + Tcl_IncrRefCount(newValue); + } + if (Tcl_ListObjReplace(interp, objResultPtr, len, 0, objc, objv) + != TCL_OK) { + TRACE_ERROR(interp); + goto gotError; + } + TRACE_APPEND(("%.30s\n", O2S(objResultPtr))); + NEXT_INST_V(pcAdjustment, cleanup, 1); + + lappendList: + opnd = -1; + if (TclListObjGetElements(interp, valuePtr, &objc, &objv) + != TCL_OK) { + TRACE_ERROR(interp); + goto gotError; + } + DECACHE_STACK_INFO(); + varPtr = TclObjLookupVarEx(interp, part1Ptr, part2Ptr, + TCL_LEAVE_ERR_MSG, "set", 1, 1, &arrayPtr); + CACHE_STACK_INFO(); + if (!varPtr) { + TRACE_ERROR(interp); + goto gotError; + } + + lappendListPtr: + if (TclIsVarInHash(varPtr)) { + VarHashRefCount(varPtr)++; + } + if (arrayPtr && TclIsVarInHash(arrayPtr)) { + VarHashRefCount(arrayPtr)++; + } + DECACHE_STACK_INFO(); + objResultPtr = TclPtrGetVar(interp, varPtr, arrayPtr, + part1Ptr, part2Ptr, TCL_LEAVE_ERR_MSG, opnd); + CACHE_STACK_INFO(); + if (TclIsVarInHash(varPtr)) { + VarHashRefCount(varPtr)--; + } + if (arrayPtr && TclIsVarInHash(arrayPtr)) { + VarHashRefCount(arrayPtr)--; + } + + { + int createdNewObj = 0; + + if (!objResultPtr) { + objResultPtr = valuePtr; + } else if (TclListObjLength(interp, objResultPtr, &len)!=TCL_OK) { + TRACE_ERROR(interp); + goto gotError; + } else { + if (Tcl_IsShared(objResultPtr)) { + objResultPtr = Tcl_DuplicateObj(objResultPtr); + createdNewObj = 1; + } + if (Tcl_ListObjReplace(interp, objResultPtr, len,0, objc,objv) + != TCL_OK) { + goto errorInLappendListPtr; + } + } + DECACHE_STACK_INFO(); + objResultPtr = TclPtrSetVar(interp, varPtr, arrayPtr, part1Ptr, + part2Ptr, objResultPtr, TCL_LEAVE_ERR_MSG, opnd); + CACHE_STACK_INFO(); + if (!objResultPtr) { + errorInLappendListPtr: + if (createdNewObj) { + TclDecrRefCount(objResultPtr); + } + TRACE_ERROR(interp); + goto gotError; + } + } + TRACE_APPEND(("%.30s\n", O2S(objResultPtr))); + NEXT_INST_V(pcAdjustment, cleanup, 1); } /* -- cgit v0.12 From 4e4b5a7e5395eb6d333aa2cfd17172507cd4d82b Mon Sep 17 00:00:00 2001 From: dkf Date: Fri, 18 Jul 2014 22:05:16 +0000 Subject: [75b8433707] Plug a subtle memory leak in TclOO. Test suite very unhappy with this. Shoving into a mistake branch until that's sorted. --- generic/tclOO.c | 1 + tests/oo.test | 13 +++++++++++++ 2 files changed, 14 insertions(+) diff --git a/generic/tclOO.c b/generic/tclOO.c index de00733..74de6d0 100644 --- a/generic/tclOO.c +++ b/generic/tclOO.c @@ -1280,6 +1280,7 @@ TclOORemoveFromInstances( removeInstance: if (Deleted(clsPtr->thisPtr)) { + DelRef(clsPtr->instances.list[i]); clsPtr->instances.list[i] = NULL; } else { clsPtr->instances.num--; diff --git a/tests/oo.test b/tests/oo.test index d63e931..fcd9818 100644 --- a/tests/oo.test +++ b/tests/oo.test @@ -258,6 +258,19 @@ test oo-1.18 {OO: create object in NS with same name as global cmd} -setup { rename test-oo-1.18 {} A destroy } -result ::C +test oo-1.18.1 {Bug 75b8433707: memory leak in oo-1.18} -setup { + proc test-oo-1.18 {} return +} -constraints memory -body { + leaktest { + oo::class create A + oo::class create B {superclass A} + oo::define B constructor {} {A create test-oo-1.18} + B create C + A destroy + } +} -cleanup { + rename test-oo-1.18 {} +} -result 0 test oo-1.19 {basic test of OO functionality: teardown order} -body { oo::object create o namespace delete [info object namespace o] -- cgit v0.12 From d19b7190cbf9b1827e5999bfd67a9aa73b74478a Mon Sep 17 00:00:00 2001 From: dgp Date: Mon, 21 Jul 2014 14:26:56 +0000 Subject: [e6477e1b0f] Plug memleak in AtForkChild() detected in iocmd-11.4. --- unix/tclUnixNotfy.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/unix/tclUnixNotfy.c b/unix/tclUnixNotfy.c index b234667..b2bea45 100644 --- a/unix/tclUnixNotfy.c +++ b/unix/tclUnixNotfy.c @@ -311,6 +311,7 @@ Tcl_InitNotifier(void) * pipe to the original notifier thread */ if (notifierCount > 0 && processIDInitialized != getpid()) { + Tcl_ConditionFinalize(¬ifierCV); notifierCount = 0; processIDInitialized = 0; close(triggerPipe); @@ -1375,8 +1376,7 @@ AtForkParent(void) static void AtForkChild(void) { - notifierMutex = NULL; - notifierCV = NULL; + Tcl_MutexFinalize(¬ifierMutex); Tcl_InitNotifier(); } #endif /* HAVE_PTHREAD_ATFORK */ -- cgit v0.12 From bfab4c718b8cd415943b3e505a2c4433efaa2f05 Mon Sep 17 00:00:00 2001 From: dgp Date: Tue, 22 Jul 2014 16:44:38 +0000 Subject: [12b0997ce7] Plug memleak in iocmd.tf-32.0 . --- generic/tclIORChan.c | 63 +++++++++++++++++++++++++++++++++------------------- 1 file changed, 40 insertions(+), 23 deletions(-) diff --git a/generic/tclIORChan.c b/generic/tclIORChan.c index ff602c6..3506a44 100644 --- a/generic/tclIORChan.c +++ b/generic/tclIORChan.c @@ -436,6 +436,7 @@ static ReflectedChannelMap * GetReflectedChannelMap(Tcl_Interp *interp); static void DeleteReflectedChannelMap(ClientData clientData, Tcl_Interp *interp); static int ErrnoReturn(ReflectedChannel *rcPtr, Tcl_Obj *resObj); +static void MarkDead(ReflectedChannel *rcPtr); /* * Global constant strings (messages). ================== @@ -1146,7 +1147,6 @@ ReflectClose( if (result != TCL_OK) { FreeReceivedError(&p); } - return EOK; } #endif @@ -1217,17 +1217,14 @@ ReflectClose( if (hPtr) { Tcl_DeleteHashEntry(hPtr); } + } #endif - - tctPtr = ((Channel *)rcPtr->chan)->typePtr; - if (tctPtr && tctPtr != &tclRChannelType) { + tctPtr = ((Channel *)rcPtr->chan)->typePtr; + if (tctPtr && tctPtr != &tclRChannelType) { ckfree((char *)tctPtr); ((Channel *)rcPtr->chan)->typePtr = NULL; - } - Tcl_EventuallyFree(rcPtr, (Tcl_FreeProc *) FreeReflectedChannel); -#ifdef TCL_THREADS } -#endif + Tcl_EventuallyFree(rcPtr, (Tcl_FreeProc *) FreeReflectedChannel); return (result == TCL_OK) ? EOK : EINVAL; } @@ -2192,9 +2189,15 @@ FreeReflectedChannel( Channel *chanPtr = (Channel *) rcPtr->chan; Tcl_Release(chanPtr); - Tcl_DecrRefCount(rcPtr->name); - Tcl_DecrRefCount(rcPtr->methods); - Tcl_DecrRefCount(rcPtr->cmd); + if (rcPtr->name) { + Tcl_DecrRefCount(rcPtr->name); + } + if (rcPtr->methods) { + Tcl_DecrRefCount(rcPtr->methods); + } + if (rcPtr->cmd) { + Tcl_DecrRefCount(rcPtr->cmd); + } ckfree(rcPtr); } @@ -2460,6 +2463,28 @@ GetReflectedChannelMap( */ static void +MarkDead( + ReflectedChannel *rcPtr) +{ + if (rcPtr->dead) { + return; + } + if (rcPtr->name) { + Tcl_DecrRefCount(rcPtr->name); + rcPtr->name = NULL; + } + if (rcPtr->methods) { + Tcl_DecrRefCount(rcPtr->methods); + rcPtr->methods = NULL; + } + if (rcPtr->cmd) { + Tcl_DecrRefCount(rcPtr->cmd); + rcPtr->cmd = NULL; + } + rcPtr->dead = 1; +} + +static void DeleteReflectedChannelMap( ClientData clientData, /* The per-interpreter data structure. */ Tcl_Interp *interp) /* The interpreter being deleted. */ @@ -2494,7 +2519,7 @@ DeleteReflectedChannelMap( chan = Tcl_GetHashValue(hPtr); rcPtr = Tcl_GetChannelInstanceData(chan); - rcPtr->dead = 1; + MarkDead(rcPtr); Tcl_DeleteHashEntry(hPtr); } Tcl_DeleteHashTable(&rcmPtr->map); @@ -2577,7 +2602,7 @@ DeleteReflectedChannelMap( continue; } - rcPtr->dead = 1; + MarkDead(rcPtr); Tcl_DeleteHashEntry(hPtr); } #endif @@ -2724,7 +2749,7 @@ DeleteThreadReflectedChannelMap( Tcl_Channel chan = Tcl_GetHashValue(hPtr); ReflectedChannel *rcPtr = Tcl_GetChannelInstanceData(chan); - rcPtr->dead = 1; + MarkDead(rcPtr); Tcl_DeleteHashEntry(hPtr); } ckfree(rcmPtr); @@ -2907,8 +2932,6 @@ ForwardProc( * No parameters/results. */ - const Tcl_ChannelType *tctPtr; - if (InvokeTclMethod(rcPtr, METH_FINAL, NULL, NULL, &resObj)!=TCL_OK) { ForwardSetObjError(paramPtr, resObj); } @@ -2932,13 +2955,7 @@ ForwardProc( hPtr = Tcl_FindHashEntry(&rcmPtr->map, Tcl_GetChannelName(rcPtr->chan)); Tcl_DeleteHashEntry(hPtr); - - tctPtr = ((Channel *)rcPtr->chan)->typePtr; - if (tctPtr && tctPtr != &tclRChannelType) { - ckfree((char *)tctPtr); - ((Channel *)rcPtr->chan)->typePtr = NULL; - } - Tcl_EventuallyFree(rcPtr, (Tcl_FreeProc *) FreeReflectedChannel); + MarkDead(rcPtr); break; } -- cgit v0.12 From 5eaa2197549763a6fdadd43b3ba152cb452e7de7 Mon Sep 17 00:00:00 2001 From: dgp Date: Tue, 22 Jul 2014 18:12:27 +0000 Subject: Avoid [thread::exit]; Using it leads to memleaks. --- tests/ioCmd.test | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/ioCmd.test b/tests/ioCmd.test index 8d35ec7..dcca1f5 100644 --- a/tests/ioCmd.test +++ b/tests/ioCmd.test @@ -2814,7 +2814,9 @@ test iocmd.tf-24.17.bug3522560 {postevent for transfered channel} \ update } LOG THREAD-LOOP-DONE - thread::exit + #thread::exit + # Thread exits cause leaks; Use clean thread shutdown + set forever yourGirl } LOG MAIN_WAITING -- cgit v0.12 From 2ad2aba317b1528ae464c945ddc20175b989b63c Mon Sep 17 00:00:00 2001 From: dgp Date: Tue, 22 Jul 2014 19:57:51 +0000 Subject: Workaround [info frame] troubles with -singleproc 1 testing operations. --- tests/all.tcl | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/all.tcl b/tests/all.tcl index 05d3024..0a6f57f 100644 --- a/tests/all.tcl +++ b/tests/all.tcl @@ -15,5 +15,8 @@ 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 +} runAllTests proc exit args {} -- cgit v0.12 From 72c15c0c4e3788a01e0a60ce3257474f38d62e19 Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 23 Jul 2014 12:26:21 +0000 Subject: Bump to 8.5.16 for release. --- README | 2 +- generic/tcl.h | 4 ++-- library/init.tcl | 2 +- tools/tcl.wse.in | 2 +- unix/configure | 4 ++-- unix/configure.in | 2 +- unix/tcl.spec | 2 +- win/configure | 2 +- win/configure.in | 2 +- 9 files changed, 11 insertions(+), 11 deletions(-) diff --git a/README b/README index 2ad171f..256174f 100644 --- a/README +++ b/README @@ -1,5 +1,5 @@ README: Tcl - This is the Tcl 8.5.15 source distribution. + This is the Tcl 8.5.16 source distribution. http://sourceforge.net/projects/tcl/files/Tcl/ You can get any source release of Tcl from the URL above. diff --git a/generic/tcl.h b/generic/tcl.h index 5300bba..af1af58 100644 --- a/generic/tcl.h +++ b/generic/tcl.h @@ -58,10 +58,10 @@ extern "C" { #define TCL_MAJOR_VERSION 8 #define TCL_MINOR_VERSION 5 #define TCL_RELEASE_LEVEL TCL_FINAL_RELEASE -#define TCL_RELEASE_SERIAL 15 +#define TCL_RELEASE_SERIAL 16 #define TCL_VERSION "8.5" -#define TCL_PATCH_LEVEL "8.5.15" +#define TCL_PATCH_LEVEL "8.5.16" /* * The following definitions set up the proper options for Windows compilers. diff --git a/library/init.tcl b/library/init.tcl index 38c6bb3..61a80a5 100644 --- a/library/init.tcl +++ b/library/init.tcl @@ -16,7 +16,7 @@ if {[info commands package] == ""} { error "version mismatch: library\nscripts expect Tcl version 7.5b1 or later but the loaded version is\nonly [info patchlevel]" } -package require -exact Tcl 8.5.15 +package require -exact Tcl 8.5.16 # Compute the auto path to use in this interpreter. # The values on the path come from several locations: diff --git a/tools/tcl.wse.in b/tools/tcl.wse.in index e22b74a..e1810ef 100644 --- a/tools/tcl.wse.in +++ b/tools/tcl.wse.in @@ -12,7 +12,7 @@ item: Global Log Pathname=%MAINDIR%\INSTALL.LOG Message Font=MS Sans Serif Font Size=8 - Disk Label=tcl8.5.15 + Disk Label=tcl8.5.16 Disk Filename=setup Patch Flags=0000000000000001 Patch Threshold=85 diff --git a/unix/configure b/unix/configure index d268647..e4ff106 100755 --- a/unix/configure +++ b/unix/configure @@ -1335,7 +1335,7 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu TCL_VERSION=8.5 TCL_MAJOR_VERSION=8 TCL_MINOR_VERSION=5 -TCL_PATCH_LEVEL=".15" +TCL_PATCH_LEVEL=".16" VERSION=${TCL_VERSION} #------------------------------------------------------------------------ @@ -18915,7 +18915,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 diff --git a/unix/configure.in b/unix/configure.in index 318bcf8..3228353 100644 --- a/unix/configure.in +++ b/unix/configure.in @@ -25,7 +25,7 @@ m4_ifdef([SC_USE_CONFIG_HEADERS], [ TCL_VERSION=8.5 TCL_MAJOR_VERSION=8 TCL_MINOR_VERSION=5 -TCL_PATCH_LEVEL=".15" +TCL_PATCH_LEVEL=".16" VERSION=${TCL_VERSION} #------------------------------------------------------------------------ diff --git a/unix/tcl.spec b/unix/tcl.spec index b61f4bf..bdc6e27 100644 --- a/unix/tcl.spec +++ b/unix/tcl.spec @@ -4,7 +4,7 @@ Name: tcl Summary: Tcl scripting language development environment -Version: 8.5.15 +Version: 8.5.16 Release: 2 License: BSD Group: Development/Languages diff --git a/win/configure b/win/configure index cec352b..8e33eb3 100755 --- a/win/configure +++ b/win/configure @@ -1311,7 +1311,7 @@ SHELL=/bin/sh TCL_VERSION=8.5 TCL_MAJOR_VERSION=8 TCL_MINOR_VERSION=5 -TCL_PATCH_LEVEL=".15" +TCL_PATCH_LEVEL=".16" VER=$TCL_MAJOR_VERSION$TCL_MINOR_VERSION TCL_DDE_VERSION=1.3 diff --git a/win/configure.in b/win/configure.in index cde3ab4..aa42036 100644 --- a/win/configure.in +++ b/win/configure.in @@ -14,7 +14,7 @@ SHELL=/bin/sh TCL_VERSION=8.5 TCL_MAJOR_VERSION=8 TCL_MINOR_VERSION=5 -TCL_PATCH_LEVEL=".15" +TCL_PATCH_LEVEL=".16" VER=$TCL_MAJOR_VERSION$TCL_MINOR_VERSION TCL_DDE_VERSION=1.3 -- cgit v0.12 From 0bc839ec64cbbb514dbdaa358496d85dc4779a5e Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 23 Jul 2014 13:10:34 +0000 Subject: Revert the EOLFIX changes of checkin [a803608ed5] (2013-10-28). They do not work on the one machine where they must -- the release managers! Appears that the NATIVE_TCLSH support isn't found on the 8.5 branch, so we shouldn't expect to use it. --- unix/Makefile.in | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/unix/Makefile.in b/unix/Makefile.in index 1738570..d3b810c 100644 --- a/unix/Makefile.in +++ b/unix/Makefile.in @@ -1660,7 +1660,6 @@ $(MAC_OSX_DIR)/configure: $(MAC_OSX_DIR)/configure.ac $(UNIX_DIR)/configure $(UNIX_DIR)/tclConfig.h.in: $(MAC_OSX_DIR)/configure cd $(MAC_OSX_DIR); autoheader; touch $@ -EOLFIX=$(NATIVE_TCLSH) $(TOOL_DIR)/eolFix.tcl dist: $(UNIX_DIR)/configure $(UNIX_DIR)/tclConfig.h.in $(UNIX_DIR)/tcl.pc.in $(MAC_OSX_DIR)/configure genstubs rm -rf $(DISTDIR) mkdir -p $(DISTDIR)/unix @@ -1720,17 +1719,17 @@ dist: $(UNIX_DIR)/configure $(UNIX_DIR)/tclConfig.h.in $(UNIX_DIR)/tcl.pc.in $(M cp -p $(TOP_DIR)/win/*.[ch] $(TOP_DIR)/win/*.ico $(TOP_DIR)/win/*.rc \ $(DISTDIR)/win cp -p $(TOP_DIR)/win/*.bat $(DISTDIR)/win - @$(EOLFIX) -crlf $(DISTDIR)/win/*.bat + @$(TCL_EXE) $(TOOL_DIR)/eolFix.tcl -crlf $(DISTDIR)/win/*.bat cp -p $(TOP_DIR)/win/makefile.* $(DISTDIR)/win - @$(EOLFIX) -crlf $(DISTDIR)/win/makefile.bc $(DISTDIR)/win/makefile.vc + @$(TCL_EXE) $(TOOL_DIR)/eolFix.tcl -crlf $(DISTDIR)/win/makefile.bc $(DISTDIR)/win/makefile.vc cp -p $(TOP_DIR)/win/rules.vc $(DISTDIR)/win - @$(EOLFIX) -crlf $(DISTDIR)/win/rules.vc + @$(TCL_EXE) $(TOOL_DIR)/eolFix.tcl -crlf $(DISTDIR)/win/rules.vc cp -p $(TOP_DIR)/win/coffbase.txt $(DISTDIR)/win - @$(EOLFIX) -crlf $(DISTDIR)/win/coffbase.txt + @$(TCL_EXE) $(TOOL_DIR)/eolFix.tcl -crlf $(DISTDIR)/win/coffbase.txt cp -p $(TOP_DIR)/win/tcl.hpj.in $(DISTDIR)/win - @$(EOLFIX) -crlf $(DISTDIR)/win/tcl.hpj.in + @$(TCL_EXE) $(TOOL_DIR)/eolFix.tcl -crlf $(DISTDIR)/win/tcl.hpj.in cp -p $(TOP_DIR)/win/tcl.ds* $(DISTDIR)/win - @$(EOLFIX) -crlf $(DISTDIR)/win/tcl.ds* + @$(TCL_EXE) $(TOOL_DIR)/eolFix.tcl -crlf $(DISTDIR)/win/tcl.ds* cp -p $(TOP_DIR)/win/README $(DISTDIR)/win cp -p $(TOP_DIR)/license.terms $(DISTDIR)/win @mkdir $(DISTDIR)/macosx @@ -1756,7 +1755,7 @@ dist: $(UNIX_DIR)/configure $(UNIX_DIR)/tclConfig.h.in $(UNIX_DIR)/tcl.pc.in $(M $(TOOL_DIR)/tcl.wse.in $(TOOL_DIR)/*.bmp \ $(TOOL_DIR)/tcl.hpj.in \ $(DISTDIR)/tools - @$(EOLFIX)-crlf $(DISTDIR)/tools/tcl.hpj.in \ + @$(TCL_EXE) $(TOOL_DIR)/eolFix.tcl -crlf $(DISTDIR)/tools/tcl.hpj.in \ $(DISTDIR)/tools/tcl.wse.in @mkdir $(DISTDIR)/libtommath cp -p $(TOMMATH_SRCS) $(TOMMATH_DIR)/*.h \ -- cgit v0.12 From 213c040089e7919b994ef1890b678beb1adce90b Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 23 Jul 2014 17:10:26 +0000 Subject: Extend the buffer move optimization to the "same encodings" case. --- generic/tclIO.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index 256b411..6718788 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -8840,8 +8840,9 @@ TclCopyChannel( moveBytes = inStatePtr->inEofChar == '\0' /* No eofChar to stop input */ && inStatePtr->inputTranslation == TCL_TRANSLATE_LF && outStatePtr->outputTranslation == TCL_TRANSLATE_LF - && inStatePtr->encoding == NULL - && outStatePtr->encoding == NULL + && ((inStatePtr->encoding == NULL + && outStatePtr->encoding == NULL) + || (inStatePtr->encoding == outStatePtr->encoding)) && !nonBlocking; /* First draft do only blocking case */ /* -- cgit v0.12 From 631849ea86945767eb1a5ab437bf161cfc447bff Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 24 Jul 2014 15:00:07 +0000 Subject: Test read error during binary [chan copy]. --- tests/io.test | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/tests/io.test b/tests/io.test index bf5adb0..b707c01 100644 --- a/tests/io.test +++ b/tests/io.test @@ -7612,6 +7612,36 @@ test io-53.12 {CopyData: foreground short reads, aka bug 3096275} {stdio unix op close $f1 list $::done $ch } {ok A} +test io-53.13 {TclCopyChannel: read error reporting} -setup { + proc driver {cmd args} { + variable buffer + variable index + set chan [lindex $args 0] + switch -- $cmd { + initialize { + return {initialize finalize watch read} + } + finalize { + return + } + watch {} + read { + error FAIL + } + } + } + set outFile [makeFile {} out] +} -body { + set in [chan create read [namespace which driver]] + chan configure $in -translation binary + set out [open $outFile wb] + chan copy $in $out +} -cleanup { + catch {close $in} + catch {close $out} + removeFile out + rename driver {} +} -result {error reading "*": *} -returnCodes error -match glob test io-54.1 {Recursive channel events} {socket fileevent} { # This test checks to see if file events are delivered during recursive -- cgit v0.12 From 97d74c549dd10fe31903f76e25ed9267b2e32388 Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 24 Jul 2014 15:02:09 +0000 Subject: Make sure MoveBytes records read error messages. --- generic/tclIO.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index 6718788..017494e 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -8931,9 +8931,13 @@ MoveBytes( int inBytes = 0; if (bufPtr == NULL || BytesLeft(bufPtr) == 0) { - /* Nothing in the input queue; Get more input. */ + /* Nothing in the input queue; Get more input. */ if (0 != GetInput(inStatePtr->topChanPtr)) { + Tcl_SetObjResult(csPtr->interp, Tcl_ObjPrintf( + "error reading \"%s\": %s", + Tcl_GetChannelName((Tcl_Channel)csPtr->readPtr), + Tcl_PosixError(csPtr->interp))); code = TCL_ERROR; break; } -- cgit v0.12 From bfe912517c91c6b7c7ab1c330017f3886544edf3 Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 24 Jul 2014 15:17:19 +0000 Subject: Test format of write error messages during binary [chan copy] --- tests/io.test | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/tests/io.test b/tests/io.test index b707c01..cef3e81 100644 --- a/tests/io.test +++ b/tests/io.test @@ -7642,6 +7642,36 @@ test io-53.13 {TclCopyChannel: read error reporting} -setup { removeFile out rename driver {} } -result {error reading "*": *} -returnCodes error -match glob +test io-53.14 {TclCopyChannel: write error reporting} -setup { + proc driver {cmd args} { + variable buffer + variable index + set chan [lindex $args 0] + switch -- $cmd { + initialize { + return {initialize finalize watch write} + } + finalize { + return + } + watch {} + write { + error FAIL + } + } + } + set inFile [makeFile {aaa} in] +} -body { + set in [open $inFile rb] + set out [chan create write [namespace which driver]] + chan configure $out -translation binary + chan copy $in $out +} -cleanup { + catch {close $in} + catch {close $out} + removeFile in + rename driver {} +} -result {error writing "*": *} -returnCodes error -match glob test io-54.1 {Recursive channel events} {socket fileevent} { # This test checks to see if file events are delivered during recursive -- cgit v0.12 From 841ecebfa51d8efd3a77ff22cdfec76e4bd7a43b Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 24 Jul 2014 15:24:11 +0000 Subject: Make sure MoveBytes error reporting reproduces what CopyData does. Bugward compatibility! --- generic/tclIO.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/generic/tclIO.c b/generic/tclIO.c index 017494e..7e793a9 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -8920,6 +8920,10 @@ MoveBytes( * channel, flush them out of the way first. */ if (0 != FlushChannel(csPtr->interp, outStatePtr->topChanPtr, 0)) { + Tcl_SetObjResult(csPtr->interp, Tcl_ObjPrintf( + "error writing \"%s\": %s", + Tcl_GetChannelName((Tcl_Channel)csPtr->writePtr), + Tcl_PosixError(csPtr->interp))); code = TCL_ERROR; goto done; } @@ -8989,6 +8993,10 @@ MoveBytes( /* Flush destination */ if (0 != FlushChannel(csPtr->interp, outStatePtr->topChanPtr, 0)) { + Tcl_SetObjResult(csPtr->interp, Tcl_ObjPrintf( + "error writing \"%s\": %s", + Tcl_GetChannelName((Tcl_Channel)csPtr->writePtr), + Tcl_PosixError(csPtr->interp))); code = TCL_ERROR; break; } -- cgit v0.12 From 0a9367fbc97d46f8ce576938b3930fb4a8f451c9 Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 24 Jul 2014 15:34:05 +0000 Subject: simplify moveBytes selection logic --- generic/tclIO.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index 7e793a9..6052c43 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -8840,9 +8840,7 @@ TclCopyChannel( moveBytes = inStatePtr->inEofChar == '\0' /* No eofChar to stop input */ && inStatePtr->inputTranslation == TCL_TRANSLATE_LF && outStatePtr->outputTranslation == TCL_TRANSLATE_LF - && ((inStatePtr->encoding == NULL - && outStatePtr->encoding == NULL) - || (inStatePtr->encoding == outStatePtr->encoding)) + && inStatePtr->encoding == outStatePtr->encoding && !nonBlocking; /* First draft do only blocking case */ /* -- cgit v0.12 From ef647d7ccdca81e6becddb7eb1eea3549828a04c Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 24 Jul 2014 17:17:41 +0000 Subject: [9d19af7adb] Make sure all timer events get canceled. --- tests/ioCmd.test | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/ioCmd.test b/tests/ioCmd.test index dcca1f5..57f8d47 100644 --- a/tests/ioCmd.test +++ b/tests/ioCmd.test @@ -2748,10 +2748,9 @@ test iocmd.tf-24.17.bug3522560 {postevent for transfered channel} \ init* {set ret {initialize finalize watch read}} watch { set l [lindex $args 0] + catch {after cancel $::timer} if {[llength $l]} { set ::timer [after $::drive [list POST $ch]] - } else { - after cancel $::timer } } finalize { -- cgit v0.12 From 7f4563705c2110315118d03f3cdfcc111c0fde42 Mon Sep 17 00:00:00 2001 From: dgp Date: Sat, 26 Jul 2014 15:02:09 +0000 Subject: Extend the "move buffer" implementation to cover the async case. --- generic/tclIO.c | 186 ++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 175 insertions(+), 11 deletions(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index 6052c43..724c20f 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -183,6 +183,12 @@ static int CloseWrite(Tcl_Interp *interp, Channel *chanPtr); static void CommonGetsCleanup(Channel *chanPtr); static int CopyData(CopyState *csPtr, int mask); static int MoveBytes(CopyState *csPtr); + +static void MBCallback(CopyState *csPtr, Tcl_Obj *errObj); +static void MBError(CopyState *csPtr, int mask, int errorCode); +static void MBRead(ClientData clientData, int mask); +static void MBWrite(ClientData clientData, int mask); + static void CopyEventProc(ClientData clientData, int mask); static void CreateScriptRecord(Tcl_Interp *interp, Channel *chanPtr, int mask, Tcl_Obj *scriptPtr); @@ -8831,17 +8837,15 @@ TclCopyChannel( | CHANNEL_UNBUFFERED; /* - * Very strict set of conditions where we know we can just move bytes - * from input channel to output channel with no transformation or even - * examination of the bytes themselves. - * TODO: Find ways to relax this. + * Test for conditions where we know we can just move bytes from input + * channel to output channel with no transformation or even examination + * of the bytes themselves. */ moveBytes = inStatePtr->inEofChar == '\0' /* No eofChar to stop input */ && inStatePtr->inputTranslation == TCL_TRANSLATE_LF && outStatePtr->outputTranslation == TCL_TRANSLATE_LF - && inStatePtr->encoding == outStatePtr->encoding - && !nonBlocking; /* First draft do only blocking case */ + && inStatePtr->encoding == outStatePtr->encoding; /* * Allocate a new CopyState to maintain info about the current copy in @@ -8904,6 +8908,156 @@ TclCopyChannel( *---------------------------------------------------------------------- */ +static void +MBCallback( + CopyState *csPtr, + Tcl_Obj *errObj) +{ + Tcl_Obj *cmdPtr = Tcl_DuplicateObj(csPtr->cmdPtr); + Tcl_WideInt total = csPtr->total; + Tcl_Interp *interp = csPtr->interp; + int code; + + Tcl_IncrRefCount(cmdPtr); + StopCopy(csPtr); + + /* TODO: What if cmdPtr is not a list?! */ + + Tcl_ListObjAppendElement(NULL, cmdPtr, Tcl_NewWideIntObj(total)); + if (errObj) { + Tcl_ListObjAppendElement(NULL, cmdPtr, errObj); + } + + Tcl_Preserve(interp); + code = Tcl_EvalObjEx(interp, cmdPtr, TCL_EVAL_GLOBAL); + if (code != TCL_OK) { + Tcl_BackgroundException(interp, code); + } + Tcl_Release(interp); + TclDecrRefCount(cmdPtr); +} + +static void +MBError( + CopyState *csPtr, + int mask, + int errorCode) +{ + Tcl_Channel inChan = (Tcl_Channel) csPtr->readPtr; + Tcl_Channel outChan = (Tcl_Channel) csPtr->writePtr; + + Tcl_SetErrno(errorCode); + MBCallback(csPtr, Tcl_ObjPrintf( "error %sing \"%s\": %s", + (mask & TCL_READABLE) ? "read" : "writ", + Tcl_GetChannelName((mask & TCL_READABLE) ? inChan : outChan), + Tcl_PosixError(csPtr->interp))); +} + +static void +MBRead( + ClientData clientData, + int mask) +{ + CopyState *csPtr = (CopyState *) clientData; + ChannelState *inStatePtr = csPtr->readPtr->state; + + Tcl_Channel inChan = (Tcl_Channel) csPtr->readPtr; + Tcl_Channel outChan = (Tcl_Channel) csPtr->writePtr; + + int code = GetInput(inStatePtr->topChanPtr); + + assert (mask & TCL_READABLE); + + if (code == 0) { + /* Successful read -- set up to write the bytes we read */ + Tcl_CreateChannelHandler(outChan, TCL_WRITABLE, MBWrite, csPtr); + + /* When at least one full buffer is present, stop reading. */ + if (IsBufferFull(inStatePtr->inQueueHead) + || !Tcl_InputBlocked(inChan)) { + Tcl_DeleteChannelHandler(inChan, MBRead, csPtr); + } + } else { + MBError(csPtr, mask, code); + } +} + +static void +MBWrite( + ClientData clientData, + int mask) +{ + CopyState *csPtr = (CopyState *) clientData; + ChannelState *inStatePtr = csPtr->readPtr->state; + ChannelState *outStatePtr = csPtr->writePtr->state; + + Tcl_Channel inChan = (Tcl_Channel) csPtr->readPtr; + Tcl_Channel outChan = (Tcl_Channel) csPtr->writePtr; + + ChannelBuffer *bufPtr = inStatePtr->inQueueHead; + ChannelBuffer *tail = NULL; + int code, inBytes = 0; + + assert (mask & TCL_WRITABLE); + + Tcl_DeleteChannelHandler(inChan, MBRead, csPtr); + Tcl_DeleteChannelHandler(outChan, MBWrite, csPtr); + + /* Count up number of bytes waiting in the input queue */ + while (bufPtr) { + inBytes += BytesLeft(bufPtr); + tail = bufPtr; + if (csPtr->toRead != -1 && csPtr->toRead < inBytes) { + /* Queue has enough bytes to complete the copy */ + break; + } + bufPtr = bufPtr->nextPtr; + } + + if (bufPtr) { + /* Split the overflowing buffer in two */ + int extra = inBytes - csPtr->toRead; + + bufPtr = AllocChannelBuffer(extra); + + tail->nextAdded -= extra; + memcpy(InsertPoint(bufPtr), InsertPoint(tail), extra); + bufPtr->nextAdded += extra; + bufPtr->nextPtr = tail->nextPtr; + tail->nextPtr = NULL; + inBytes = csPtr->toRead; + } + + /* Update the byte counts */ + if (csPtr->toRead != -1) { + csPtr->toRead -= inBytes; + } + csPtr->total += inBytes; + + /* Move buffers from input to output channels */ + if (outStatePtr->outQueueTail) { + outStatePtr->outQueueTail->nextPtr = inStatePtr->inQueueHead; + } else { + outStatePtr->outQueueHead = inStatePtr->inQueueHead; + } + outStatePtr->outQueueTail = tail; + inStatePtr->inQueueHead = bufPtr; + if (bufPtr == NULL) { + inStatePtr->inQueueTail = NULL; + } + + code = FlushChannel(csPtr->interp, outStatePtr->topChanPtr, 0); + if (code == 0) { + if (csPtr->toRead == 0 || Tcl_Eof(inChan)) { + MBCallback(csPtr, NULL); + } else { + Tcl_CreateChannelHandler(inChan, TCL_READABLE, MBRead, csPtr); + } + } else { + MBError(csPtr, mask, code); + } +} + static int MoveBytes( CopyState *csPtr) /* State of copy operation. */ @@ -8927,6 +9081,12 @@ MoveBytes( } } + if (csPtr->cmdPtr) { + Tcl_Channel inChan = (Tcl_Channel) csPtr->readPtr; + Tcl_CreateChannelHandler(inChan, TCL_READABLE, MBRead, csPtr); + return TCL_OK; + } + while (csPtr->toRead != 0) { ChannelBuffer *bufPtr = inStatePtr->inQueueHead; ChannelBuffer *tail = NULL; @@ -9536,12 +9696,16 @@ StopCopy( CopyState *csPtr) /* State for bg copy to stop . */ { ChannelState *inStatePtr, *outStatePtr; + Tcl_Channel inChan, outChan; + int nonBlocking; if (!csPtr) { return; } + inChan = (Tcl_Channel) csPtr->readPtr; + outChan = (Tcl_Channel) csPtr->writePtr; inStatePtr = csPtr->readPtr->state; outStatePtr = csPtr->writePtr->state; @@ -9566,12 +9730,12 @@ StopCopy( csPtr->writeFlags & (CHANNEL_LINEBUFFERED | CHANNEL_UNBUFFERED); if (csPtr->cmdPtr) { - Tcl_DeleteChannelHandler((Tcl_Channel) csPtr->readPtr, CopyEventProc, - csPtr); - if (csPtr->readPtr != csPtr->writePtr) { - Tcl_DeleteChannelHandler((Tcl_Channel) csPtr->writePtr, - CopyEventProc, csPtr); + Tcl_DeleteChannelHandler(inChan, CopyEventProc, csPtr); + if (inChan != outChan) { + Tcl_DeleteChannelHandler(outChan, CopyEventProc, csPtr); } + Tcl_DeleteChannelHandler(inChan, MBRead, csPtr); + Tcl_DeleteChannelHandler(outChan, MBWrite, csPtr); TclDecrRefCount(csPtr->cmdPtr); } inStatePtr->csPtrR = NULL; -- cgit v0.12 From 19d6bd367d5c483e6e6ea6a703a8052a3659f92d Mon Sep 17 00:00:00 2001 From: dgp Date: Sat, 26 Jul 2014 15:44:32 +0000 Subject: Use common MBError() routine for sync and async operations. --- generic/tclIO.c | 49 ++++++++++++++++++++++++------------------------- 1 file changed, 24 insertions(+), 25 deletions(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index 724c20f..aed2abf 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -8945,12 +8945,21 @@ MBError( { Tcl_Channel inChan = (Tcl_Channel) csPtr->readPtr; Tcl_Channel outChan = (Tcl_Channel) csPtr->writePtr; + Tcl_Obj *errObj; Tcl_SetErrno(errorCode); - MBCallback(csPtr, Tcl_ObjPrintf( "error %sing \"%s\": %s", + + errObj = Tcl_ObjPrintf( "error %sing \"%s\": %s", (mask & TCL_READABLE) ? "read" : "writ", Tcl_GetChannelName((mask & TCL_READABLE) ? inChan : outChan), - Tcl_PosixError(csPtr->interp))); + Tcl_PosixError(csPtr->interp)); + + if (csPtr->cmdPtr) { + MBCallback(csPtr, errObj); + } else { + Tcl_SetObjResult(csPtr->interp, errObj); + StopCopy(csPtr); + } } static void @@ -9065,19 +9074,16 @@ MoveBytes( ChannelState *inStatePtr = csPtr->readPtr->state; ChannelState *outStatePtr = csPtr->writePtr->state; ChannelBuffer *bufPtr = outStatePtr->curOutPtr; - int code = TCL_OK; + int errorCode, code = TCL_OK; if (bufPtr && BytesLeft(bufPtr)) { /* If we start with unflushed bytes in the destination * channel, flush them out of the way first. */ - if (0 != FlushChannel(csPtr->interp, outStatePtr->topChanPtr, 0)) { - Tcl_SetObjResult(csPtr->interp, Tcl_ObjPrintf( - "error writing \"%s\": %s", - Tcl_GetChannelName((Tcl_Channel)csPtr->writePtr), - Tcl_PosixError(csPtr->interp))); - code = TCL_ERROR; - goto done; + errorCode = FlushChannel(csPtr->interp, outStatePtr->topChanPtr, 0); + if (errorCode != 0) { + MBError(csPtr, TCL_WRITABLE, errorCode); + return TCL_ERROR; } } @@ -9095,13 +9101,10 @@ MoveBytes( if (bufPtr == NULL || BytesLeft(bufPtr) == 0) { /* Nothing in the input queue; Get more input. */ - if (0 != GetInput(inStatePtr->topChanPtr)) { - Tcl_SetObjResult(csPtr->interp, Tcl_ObjPrintf( - "error reading \"%s\": %s", - Tcl_GetChannelName((Tcl_Channel)csPtr->readPtr), - Tcl_PosixError(csPtr->interp))); - code = TCL_ERROR; - break; + errorCode = GetInput(inStatePtr->topChanPtr); + if (errorCode != 0) { + MBError(csPtr, TCL_READABLE, errorCode); + return TCL_ERROR; } bufPtr = inStatePtr->inQueueHead; } @@ -9150,13 +9153,10 @@ MoveBytes( } /* Flush destination */ - if (0 != FlushChannel(csPtr->interp, outStatePtr->topChanPtr, 0)) { - Tcl_SetObjResult(csPtr->interp, Tcl_ObjPrintf( - "error writing \"%s\": %s", - Tcl_GetChannelName((Tcl_Channel)csPtr->writePtr), - Tcl_PosixError(csPtr->interp))); - code = TCL_ERROR; - break; + errorCode = FlushChannel(csPtr->interp, outStatePtr->topChanPtr, 0); + if (errorCode != 0) { + MBError(csPtr, TCL_WRITABLE, errorCode); + return TCL_ERROR; } if (GotFlag(inStatePtr, CHANNEL_EOF)) { break; @@ -9166,7 +9166,6 @@ MoveBytes( if (code == TCL_OK) { Tcl_SetObjResult(csPtr->interp, Tcl_NewWideIntObj(csPtr->total)); } - done: StopCopy(csPtr); return code; } -- cgit v0.12 From 3eb6318d9ba66cdb78f777a81c8b2be175b6a341 Mon Sep 17 00:00:00 2001 From: dgp Date: Sun, 27 Jul 2014 17:20:32 +0000 Subject: Rework MBWrite() so it can be used in both sync and async modes. Reduce code duplication. --- generic/tclIO.c | 109 +++++++++++++++++++++----------------------------------- 1 file changed, 41 insertions(+), 68 deletions(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index aed2abf..907a070 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -187,7 +187,8 @@ static int MoveBytes(CopyState *csPtr); static void MBCallback(CopyState *csPtr, Tcl_Obj *errObj); static void MBError(CopyState *csPtr, int mask, int errorCode); static void MBRead(ClientData clientData, int mask); -static void MBWrite(ClientData clientData, int mask); +static int MBWrite(CopyState *csPtr, int mask); +static void MBEvent(ClientData clientData, int mask); static void CopyEventProc(ClientData clientData, int mask); static void CreateScriptRecord(Tcl_Interp *interp, @@ -8963,6 +8964,20 @@ MBError( } static void +MBEvent( + ClientData clientData, + int mask) +{ + CopyState *csPtr = (CopyState *) clientData; + + if (mask & TCL_WRITABLE) { + (void) MBWrite(csPtr, mask); + } else if (mask & TCL_READABLE) { + (void) MBRead(clientData, mask); + } +} + +static void MBRead( ClientData clientData, int mask) @@ -8979,7 +8994,7 @@ MBRead( if (code == 0) { /* Successful read -- set up to write the bytes we read */ - Tcl_CreateChannelHandler(outChan, TCL_WRITABLE, MBWrite, csPtr); + Tcl_CreateChannelHandler(outChan, TCL_WRITABLE, MBEvent, csPtr); /* When at least one full buffer is present, stop reading. */ if (IsBufferFull(inStatePtr->inQueueHead) @@ -8991,12 +9006,11 @@ MBRead( } } -static void +static int MBWrite( - ClientData clientData, + CopyState *csPtr, int mask) { - CopyState *csPtr = (CopyState *) clientData; ChannelState *inStatePtr = csPtr->readPtr->state; ChannelState *outStatePtr = csPtr->writePtr->state; @@ -9010,7 +9024,7 @@ MBWrite( assert (mask & TCL_WRITABLE); Tcl_DeleteChannelHandler(inChan, MBRead, csPtr); - Tcl_DeleteChannelHandler(outChan, MBWrite, csPtr); + Tcl_DeleteChannelHandler(outChan, MBEvent, csPtr); /* Count up number of bytes waiting in the input queue */ while (bufPtr) { @@ -9058,12 +9072,21 @@ MBWrite( code = FlushChannel(csPtr->interp, outStatePtr->topChanPtr, 0); if (code == 0) { if (csPtr->toRead == 0 || Tcl_Eof(inChan)) { - MBCallback(csPtr, NULL); - } else { + if (csPtr->cmdPtr) { + MBCallback(csPtr, NULL); + } else { + Tcl_SetObjResult(csPtr->interp, + Tcl_NewWideIntObj(csPtr->total)); + StopCopy(csPtr); + } + return TCL_OK; + } else if (csPtr->cmdPtr) { Tcl_CreateChannelHandler(inChan, TCL_READABLE, MBRead, csPtr); } + return TCL_CONTINUE; } else { MBError(csPtr, mask, code); + return TCL_ERROR; } } @@ -9074,7 +9097,7 @@ MoveBytes( ChannelState *inStatePtr = csPtr->readPtr->state; ChannelState *outStatePtr = csPtr->writePtr->state; ChannelBuffer *bufPtr = outStatePtr->curOutPtr; - int errorCode, code = TCL_OK; + int errorCode; if (bufPtr && BytesLeft(bufPtr)) { /* If we start with unflushed bytes in the destination @@ -9093,10 +9116,9 @@ MoveBytes( return TCL_OK; } - while (csPtr->toRead != 0) { + while (1) { ChannelBuffer *bufPtr = inStatePtr->inQueueHead; - ChannelBuffer *tail = NULL; - int inBytes = 0; + int code; if (bufPtr == NULL || BytesLeft(bufPtr) == 0) { @@ -9108,66 +9130,17 @@ MoveBytes( } bufPtr = inStatePtr->inQueueHead; } - - /* Count up number of bytes waiting in the input queue */ - while (bufPtr) { - inBytes += BytesLeft(bufPtr); - tail = bufPtr; - if (csPtr->toRead != -1 && csPtr->toRead < inBytes) { - /* Queue has enough bytes to complete the copy */ - break; - } - bufPtr = bufPtr->nextPtr; - } - - if (bufPtr) { - /* Split the overflowing buffer in two */ - int extra = inBytes - csPtr->toRead; - - bufPtr = AllocChannelBuffer(extra); - - tail->nextAdded -= extra; - memcpy(InsertPoint(bufPtr), InsertPoint(tail), extra); - bufPtr->nextAdded += extra; - bufPtr->nextPtr = tail->nextPtr; - tail->nextPtr = NULL; - inBytes = csPtr->toRead; - } - - /* Update the byte counts */ - if (csPtr->toRead != -1) { - csPtr->toRead -= inBytes; + code = MBWrite(csPtr, TCL_WRITABLE); + if (code == TCL_CONTINUE) { + continue; } - csPtr->total += inBytes; - - /* Move buffers from input to output channels */ - if (outStatePtr->outQueueTail) { - outStatePtr->outQueueTail->nextPtr = inStatePtr->inQueueHead; + if (code == TCL_OK) { + return TCL_OK; } else { - outStatePtr->outQueueHead = inStatePtr->inQueueHead; - } - outStatePtr->outQueueTail = tail; - inStatePtr->inQueueHead = bufPtr; - if (bufPtr == NULL) { - inStatePtr->inQueueTail = NULL; - } - - /* Flush destination */ - errorCode = FlushChannel(csPtr->interp, outStatePtr->topChanPtr, 0); - if (errorCode != 0) { - MBError(csPtr, TCL_WRITABLE, errorCode); return TCL_ERROR; } - if (GotFlag(inStatePtr, CHANNEL_EOF)) { - break; - } } - - if (code == TCL_OK) { - Tcl_SetObjResult(csPtr->interp, Tcl_NewWideIntObj(csPtr->total)); - } - StopCopy(csPtr); - return code; + return TCL_OK; /* Silence compiler warnings */ } static int @@ -9734,7 +9707,7 @@ StopCopy( Tcl_DeleteChannelHandler(outChan, CopyEventProc, csPtr); } Tcl_DeleteChannelHandler(inChan, MBRead, csPtr); - Tcl_DeleteChannelHandler(outChan, MBWrite, csPtr); + Tcl_DeleteChannelHandler(outChan, MBEvent, csPtr); TclDecrRefCount(csPtr->cmdPtr); } inStatePtr->csPtrR = NULL; -- cgit v0.12 From 1db9d005b60fedd68e3de574d077de4be163f602 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Sun, 27 Jul 2014 22:44:36 +0000 Subject: correct EOLFIX macro, broken by [a803608ed5] --- unix/Makefile.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/unix/Makefile.in b/unix/Makefile.in index 1738570..4f32c87 100644 --- a/unix/Makefile.in +++ b/unix/Makefile.in @@ -1660,7 +1660,7 @@ $(MAC_OSX_DIR)/configure: $(MAC_OSX_DIR)/configure.ac $(UNIX_DIR)/configure $(UNIX_DIR)/tclConfig.h.in: $(MAC_OSX_DIR)/configure cd $(MAC_OSX_DIR); autoheader; touch $@ -EOLFIX=$(NATIVE_TCLSH) $(TOOL_DIR)/eolFix.tcl +EOLFIX=$(TCL_EXE) $(TOOL_DIR)/eolFix.tcl dist: $(UNIX_DIR)/configure $(UNIX_DIR)/tclConfig.h.in $(UNIX_DIR)/tcl.pc.in $(MAC_OSX_DIR)/configure genstubs rm -rf $(DISTDIR) mkdir -p $(DISTDIR)/unix @@ -1756,7 +1756,7 @@ dist: $(UNIX_DIR)/configure $(UNIX_DIR)/tclConfig.h.in $(UNIX_DIR)/tcl.pc.in $(M $(TOOL_DIR)/tcl.wse.in $(TOOL_DIR)/*.bmp \ $(TOOL_DIR)/tcl.hpj.in \ $(DISTDIR)/tools - @$(EOLFIX)-crlf $(DISTDIR)/tools/tcl.hpj.in \ + @$(EOLFIX) -crlf $(DISTDIR)/tools/tcl.hpj.in \ $(DISTDIR)/tools/tcl.wse.in @mkdir $(DISTDIR)/libtommath cp -p $(TOMMATH_SRCS) $(TOMMATH_DIR)/*.h \ -- cgit v0.12 From cf106cdda63ef90e183b7c2bc638b768b0a2f156 Mon Sep 17 00:00:00 2001 From: dgp Date: Sun, 27 Jul 2014 22:53:01 +0000 Subject: Push MBWrite() differences out to callers. --- generic/tclIO.c | 49 ++++++++++++++++++++++--------------------------- 1 file changed, 22 insertions(+), 27 deletions(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index 907a070..73e1274 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -8969,9 +8969,20 @@ MBEvent( int mask) { CopyState *csPtr = (CopyState *) clientData; + Tcl_Channel inChan = (Tcl_Channel) csPtr->readPtr; + Tcl_Channel outChan = (Tcl_Channel) csPtr->writePtr; if (mask & TCL_WRITABLE) { - (void) MBWrite(csPtr, mask); + Tcl_DeleteChannelHandler(inChan, MBRead, csPtr); + Tcl_DeleteChannelHandler(outChan, MBEvent, csPtr); + switch (MBWrite(csPtr, mask)) { + case TCL_OK: + MBCallback(csPtr, NULL); + break; + case TCL_CONTINUE: + Tcl_CreateChannelHandler(inChan, TCL_READABLE, MBRead, csPtr); + break; + } } else if (mask & TCL_READABLE) { (void) MBRead(clientData, mask); } @@ -9013,19 +9024,12 @@ MBWrite( { ChannelState *inStatePtr = csPtr->readPtr->state; ChannelState *outStatePtr = csPtr->writePtr->state; - - Tcl_Channel inChan = (Tcl_Channel) csPtr->readPtr; - Tcl_Channel outChan = (Tcl_Channel) csPtr->writePtr; - ChannelBuffer *bufPtr = inStatePtr->inQueueHead; ChannelBuffer *tail = NULL; int code, inBytes = 0; assert (mask & TCL_WRITABLE); - Tcl_DeleteChannelHandler(inChan, MBRead, csPtr); - Tcl_DeleteChannelHandler(outChan, MBEvent, csPtr); - /* Count up number of bytes waiting in the input queue */ while (bufPtr) { inBytes += BytesLeft(bufPtr); @@ -9070,24 +9074,14 @@ MBWrite( } code = FlushChannel(csPtr->interp, outStatePtr->topChanPtr, 0); - if (code == 0) { - if (csPtr->toRead == 0 || Tcl_Eof(inChan)) { - if (csPtr->cmdPtr) { - MBCallback(csPtr, NULL); - } else { - Tcl_SetObjResult(csPtr->interp, - Tcl_NewWideIntObj(csPtr->total)); - StopCopy(csPtr); - } - return TCL_OK; - } else if (csPtr->cmdPtr) { - Tcl_CreateChannelHandler(inChan, TCL_READABLE, MBRead, csPtr); - } - return TCL_CONTINUE; - } else { + if (code) { MBError(csPtr, mask, code); return TCL_ERROR; } + if (csPtr->toRead == 0 || GotFlag(inStatePtr, CHANNEL_EOF)) { + return TCL_OK; + } + return TCL_CONTINUE; } static int @@ -9131,14 +9125,15 @@ MoveBytes( bufPtr = inStatePtr->inQueueHead; } code = MBWrite(csPtr, TCL_WRITABLE); - if (code == TCL_CONTINUE) { - continue; - } if (code == TCL_OK) { + Tcl_SetObjResult(csPtr->interp, Tcl_NewWideIntObj(csPtr->total)); + StopCopy(csPtr); return TCL_OK; - } else { + } + if (code == TCL_ERROR) { return TCL_ERROR; } + /* code == TCL_CONTINUE --> continue the loop */ } return TCL_OK; /* Silence compiler warnings */ } -- cgit v0.12 From 51be2107eaf8e1317b50aa0234a36dc921c65a6b Mon Sep 17 00:00:00 2001 From: dgp Date: Mon, 28 Jul 2014 01:42:42 +0000 Subject: Revise MBRead() to be used in both sync and async modes. --- generic/tclIO.c | 78 +++++++++++++++++++++++++-------------------------------- 1 file changed, 34 insertions(+), 44 deletions(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index 73e1274..d9d37a2 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -186,8 +186,8 @@ static int MoveBytes(CopyState *csPtr); static void MBCallback(CopyState *csPtr, Tcl_Obj *errObj); static void MBError(CopyState *csPtr, int mask, int errorCode); -static void MBRead(ClientData clientData, int mask); -static int MBWrite(CopyState *csPtr, int mask); +static int MBRead(CopyState *csPtr); +static int MBWrite(CopyState *csPtr); static void MBEvent(ClientData clientData, int mask); static void CopyEventProc(ClientData clientData, int mask); @@ -8971,56 +8971,57 @@ MBEvent( CopyState *csPtr = (CopyState *) clientData; Tcl_Channel inChan = (Tcl_Channel) csPtr->readPtr; Tcl_Channel outChan = (Tcl_Channel) csPtr->writePtr; + ChannelState *inStatePtr = csPtr->readPtr->state; if (mask & TCL_WRITABLE) { - Tcl_DeleteChannelHandler(inChan, MBRead, csPtr); + Tcl_DeleteChannelHandler(inChan, MBEvent, csPtr); Tcl_DeleteChannelHandler(outChan, MBEvent, csPtr); - switch (MBWrite(csPtr, mask)) { + switch (MBWrite(csPtr)) { case TCL_OK: MBCallback(csPtr, NULL); break; case TCL_CONTINUE: - Tcl_CreateChannelHandler(inChan, TCL_READABLE, MBRead, csPtr); + Tcl_CreateChannelHandler(inChan, TCL_READABLE, MBEvent, csPtr); break; } } else if (mask & TCL_READABLE) { - (void) MBRead(clientData, mask); + if (TCL_OK == MBRead(csPtr)) { + /* When at least one full buffer is present, stop reading. */ + if (IsBufferFull(inStatePtr->inQueueHead) + || !Tcl_InputBlocked(inChan)) { + Tcl_DeleteChannelHandler(inChan, MBEvent, csPtr); + } + + /* Successful read -- set up to write the bytes we read */ + Tcl_CreateChannelHandler(outChan, TCL_WRITABLE, MBEvent, csPtr); + } } } -static void +static int MBRead( - ClientData clientData, - int mask) + CopyState *csPtr) { - CopyState *csPtr = (CopyState *) clientData; ChannelState *inStatePtr = csPtr->readPtr->state; + ChannelBuffer *bufPtr = inStatePtr->inQueueHead; + int code; - Tcl_Channel inChan = (Tcl_Channel) csPtr->readPtr; - Tcl_Channel outChan = (Tcl_Channel) csPtr->writePtr; - - int code = GetInput(inStatePtr->topChanPtr); - - assert (mask & TCL_READABLE); + if (bufPtr && BytesLeft(bufPtr) > 0) { + return TCL_OK; + } + code = GetInput(inStatePtr->topChanPtr); if (code == 0) { - /* Successful read -- set up to write the bytes we read */ - Tcl_CreateChannelHandler(outChan, TCL_WRITABLE, MBEvent, csPtr); - - /* When at least one full buffer is present, stop reading. */ - if (IsBufferFull(inStatePtr->inQueueHead) - || !Tcl_InputBlocked(inChan)) { - Tcl_DeleteChannelHandler(inChan, MBRead, csPtr); - } + return TCL_OK; } else { - MBError(csPtr, mask, code); + MBError(csPtr, TCL_READABLE, code); + return TCL_ERROR; } } static int MBWrite( - CopyState *csPtr, - int mask) + CopyState *csPtr) { ChannelState *inStatePtr = csPtr->readPtr->state; ChannelState *outStatePtr = csPtr->writePtr->state; @@ -9028,8 +9029,6 @@ MBWrite( ChannelBuffer *tail = NULL; int code, inBytes = 0; - assert (mask & TCL_WRITABLE); - /* Count up number of bytes waiting in the input queue */ while (bufPtr) { inBytes += BytesLeft(bufPtr); @@ -9075,7 +9074,7 @@ MBWrite( code = FlushChannel(csPtr->interp, outStatePtr->topChanPtr, 0); if (code) { - MBError(csPtr, mask, code); + MBError(csPtr, TCL_WRITABLE, code); return TCL_ERROR; } if (csPtr->toRead == 0 || GotFlag(inStatePtr, CHANNEL_EOF)) { @@ -9088,7 +9087,6 @@ static int MoveBytes( CopyState *csPtr) /* State of copy operation. */ { - ChannelState *inStatePtr = csPtr->readPtr->state; ChannelState *outStatePtr = csPtr->writePtr->state; ChannelBuffer *bufPtr = outStatePtr->curOutPtr; int errorCode; @@ -9106,25 +9104,17 @@ MoveBytes( if (csPtr->cmdPtr) { Tcl_Channel inChan = (Tcl_Channel) csPtr->readPtr; - Tcl_CreateChannelHandler(inChan, TCL_READABLE, MBRead, csPtr); + Tcl_CreateChannelHandler(inChan, TCL_READABLE, MBEvent, csPtr); return TCL_OK; } while (1) { - ChannelBuffer *bufPtr = inStatePtr->inQueueHead; int code; - if (bufPtr == NULL || BytesLeft(bufPtr) == 0) { - - /* Nothing in the input queue; Get more input. */ - errorCode = GetInput(inStatePtr->topChanPtr); - if (errorCode != 0) { - MBError(csPtr, TCL_READABLE, errorCode); - return TCL_ERROR; - } - bufPtr = inStatePtr->inQueueHead; + if (TCL_ERROR == MBRead(csPtr)) { + return TCL_ERROR; } - code = MBWrite(csPtr, TCL_WRITABLE); + code = MBWrite(csPtr); if (code == TCL_OK) { Tcl_SetObjResult(csPtr->interp, Tcl_NewWideIntObj(csPtr->total)); StopCopy(csPtr); @@ -9701,7 +9691,7 @@ StopCopy( if (inChan != outChan) { Tcl_DeleteChannelHandler(outChan, CopyEventProc, csPtr); } - Tcl_DeleteChannelHandler(inChan, MBRead, csPtr); + Tcl_DeleteChannelHandler(inChan, MBEvent, csPtr); Tcl_DeleteChannelHandler(outChan, MBEvent, csPtr); TclDecrRefCount(csPtr->cmdPtr); } -- cgit v0.12 From cfb0ea03eccc0800bce85e0bd11ba96f66c43a8e Mon Sep 17 00:00:00 2001 From: dgp Date: Mon, 28 Jul 2014 14:50:06 +0000 Subject: Bump to 8.6.2 for release. --- README | 2 +- generic/tcl.h | 4 ++-- library/init.tcl | 2 +- unix/configure | 2 +- unix/configure.in | 2 +- unix/tcl.spec | 2 +- win/configure | 2 +- win/configure.in | 2 +- 8 files changed, 9 insertions(+), 9 deletions(-) diff --git a/README b/README index 7004bc5..66e1b76 100644 --- a/README +++ b/README @@ -1,5 +1,5 @@ README: Tcl - This is the Tcl 8.6.1 source distribution. + This is the Tcl 8.6.2 source distribution. http://sourceforge.net/projects/tcl/files/Tcl/ You can get any source release of Tcl from the URL above. diff --git a/generic/tcl.h b/generic/tcl.h index e557290..7531242 100644 --- a/generic/tcl.h +++ b/generic/tcl.h @@ -56,10 +56,10 @@ extern "C" { #define TCL_MAJOR_VERSION 8 #define TCL_MINOR_VERSION 6 #define TCL_RELEASE_LEVEL TCL_FINAL_RELEASE -#define TCL_RELEASE_SERIAL 1 +#define TCL_RELEASE_SERIAL 2 #define TCL_VERSION "8.6" -#define TCL_PATCH_LEVEL "8.6.1" +#define TCL_PATCH_LEVEL "8.6.2" /* *---------------------------------------------------------------------------- diff --git a/library/init.tcl b/library/init.tcl index bb17319..265f928 100644 --- a/library/init.tcl +++ b/library/init.tcl @@ -16,7 +16,7 @@ if {[info commands package] == ""} { error "version mismatch: library\nscripts expect Tcl version 7.5b1 or later but the loaded version is\nonly [info patchlevel]" } -package require -exact Tcl 8.6.1 +package require -exact Tcl 8.6.2 # Compute the auto path to use in this interpreter. # The values on the path come from several locations: diff --git a/unix/configure b/unix/configure index bd85ba4..ec5e0ed 100755 --- a/unix/configure +++ b/unix/configure @@ -1335,7 +1335,7 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu TCL_VERSION=8.6 TCL_MAJOR_VERSION=8 TCL_MINOR_VERSION=6 -TCL_PATCH_LEVEL=".1" +TCL_PATCH_LEVEL=".2" VERSION=${TCL_VERSION} EXTRA_INSTALL_BINARIES=${EXTRA_INSTALL_BINARIES:-"@:"} diff --git a/unix/configure.in b/unix/configure.in index cb6cf82..85bd7ee 100644 --- a/unix/configure.in +++ b/unix/configure.in @@ -25,7 +25,7 @@ m4_ifdef([SC_USE_CONFIG_HEADERS], [ TCL_VERSION=8.6 TCL_MAJOR_VERSION=8 TCL_MINOR_VERSION=6 -TCL_PATCH_LEVEL=".1" +TCL_PATCH_LEVEL=".2" VERSION=${TCL_VERSION} EXTRA_INSTALL_BINARIES=${EXTRA_INSTALL_BINARIES:-"@:"} diff --git a/unix/tcl.spec b/unix/tcl.spec index 678222c..50aacc6 100644 --- a/unix/tcl.spec +++ b/unix/tcl.spec @@ -4,7 +4,7 @@ Name: tcl Summary: Tcl scripting language development environment -Version: 8.6.1 +Version: 8.6.2 Release: 2 License: BSD Group: Development/Languages diff --git a/win/configure b/win/configure index 2affd38..cf2b201 100755 --- a/win/configure +++ b/win/configure @@ -1311,7 +1311,7 @@ SHELL=/bin/sh TCL_VERSION=8.6 TCL_MAJOR_VERSION=8 TCL_MINOR_VERSION=6 -TCL_PATCH_LEVEL=".1" +TCL_PATCH_LEVEL=".2" VER=$TCL_MAJOR_VERSION$TCL_MINOR_VERSION TCL_DDE_VERSION=1.4 diff --git a/win/configure.in b/win/configure.in index 77e0327..aa47505 100644 --- a/win/configure.in +++ b/win/configure.in @@ -14,7 +14,7 @@ SHELL=/bin/sh TCL_VERSION=8.6 TCL_MAJOR_VERSION=8 TCL_MINOR_VERSION=6 -TCL_PATCH_LEVEL=".1" +TCL_PATCH_LEVEL=".2" VER=$TCL_MAJOR_VERSION$TCL_MINOR_VERSION TCL_DDE_VERSION=1.4 -- cgit v0.12 From 2cbe892d4875e644e77899b287c4e3ef47e92c61 Mon Sep 17 00:00:00 2001 From: dgp Date: Tue, 29 Jul 2014 00:22:32 +0000 Subject: [3757cdf808] Refactoring seems to reduce (maybe somewhat kinda sorta) a bizarre performance regression. Still not what it was. Damn Heisenbugs. --- generic/tclClock.c | 54 ++++++++++++++++++++++++++++++++---------------------- 1 file changed, 32 insertions(+), 22 deletions(-) diff --git a/generic/tclClock.c b/generic/tclClock.c index 7e917f6..524a9e8 100644 --- a/generic/tclClock.c +++ b/generic/tclClock.c @@ -522,6 +522,26 @@ ClockGetdatefieldsObjCmd( */ static int +FetchIntField( + Tcl_Interp *interp, + Tcl_Obj *dict, + Tcl_Obj *key, + int *storePtr) +{ + Tcl_Obj *value = NULL; + + if (Tcl_DictObjGet(interp, dict, key, &value) != TCL_OK) { + return TCL_ERROR; + } + if (value == NULL) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "expected key(s) not found in dictionary", -1)); + return TCL_ERROR; + } + return TclGetIntFromObj(interp, value, storePtr); +} + +static int ClockGetjuliandayfromerayearmonthdayObjCmd( ClientData clientData, /* Opaque pointer to literal pool, etc. */ Tcl_Interp *interp, /* Tcl interpreter */ @@ -551,18 +571,13 @@ ClockGetjuliandayfromerayearmonthdayObjCmd( || fieldPtr == NULL || Tcl_GetIndexFromObj(interp, fieldPtr, eras, "era", TCL_EXACT, &era) != TCL_OK - || Tcl_DictObjGet(interp, dict, literals[LIT_YEAR], &fieldPtr) != TCL_OK - || fieldPtr == NULL - || TclGetIntFromObj(interp, fieldPtr, &fields.year) != TCL_OK - || Tcl_DictObjGet(interp, dict, literals[LIT_MONTH], &fieldPtr) != TCL_OK - || fieldPtr == NULL - || TclGetIntFromObj(interp, fieldPtr, &fields.month) != TCL_OK - || Tcl_DictObjGet(interp, dict, literals[LIT_DAYOFMONTH], &fieldPtr) != TCL_OK - || fieldPtr == NULL - || TclGetIntFromObj(interp, fieldPtr, &fields.dayOfMonth)!=TCL_OK + || FetchIntField(interp, dict, literals[LIT_YEAR], &fields.year) + != TCL_OK + || FetchIntField(interp, dict, literals[LIT_MONTH], &fields.month) + != TCL_OK + || FetchIntField(interp, dict, literals[LIT_DAYOFMONTH], + &fields.dayOfMonth) != TCL_OK || TclGetIntFromObj(interp, objv[2], &changeover) != TCL_OK) { - if (fieldPtr == NULL) - Tcl_SetObjResult(interp, Tcl_NewStringObj("expected key(s) not found in dictionary", -1)); return TCL_ERROR; } fields.era = era; @@ -644,18 +659,13 @@ ClockGetjuliandayfromerayearweekdayObjCmd( || fieldPtr == NULL || Tcl_GetIndexFromObj(interp, fieldPtr, eras, "era", TCL_EXACT, &era) != TCL_OK - || Tcl_DictObjGet(interp, dict, literals[LIT_ISO8601YEAR], &fieldPtr) != TCL_OK - || fieldPtr == NULL - || TclGetIntFromObj(interp, fieldPtr, &(fields.iso8601Year)) != TCL_OK - || Tcl_DictObjGet(interp, dict, literals[LIT_ISO8601WEEK], &fieldPtr) != TCL_OK - || fieldPtr == NULL - || TclGetIntFromObj(interp, fieldPtr, &(fields.iso8601Week)) != TCL_OK - || Tcl_DictObjGet(interp, dict, literals[LIT_DAYOFWEEK], &fieldPtr) != TCL_OK - || fieldPtr == NULL - || TclGetIntFromObj(interp, fieldPtr, &(fields.dayOfWeek)) != TCL_OK + || FetchIntField(interp, dict, literals[LIT_ISO8601YEAR], + &fields.iso8601Year) != TCL_OK + || FetchIntField(interp, dict, literals[LIT_ISO8601WEEK], + &fields.iso8601Week) != TCL_OK + || FetchIntField(interp, dict, literals[LIT_DAYOFWEEK], + &fields.dayOfWeek) != TCL_OK || TclGetIntFromObj(interp, objv[2], &changeover) != TCL_OK) { - if (fieldPtr == NULL) - Tcl_SetObjResult(interp, Tcl_NewStringObj("expected key(s) not found in dictionary", -1)); return TCL_ERROR; } fields.era = era; -- cgit v0.12 From d9ab63098e3446a3af1730eab564635d115574cf Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 30 Jul 2014 00:22:33 +0000 Subject: Reduce the cost of Preserve/Release on channels --- generic/tclIO.c | 77 +++++++++++++++++++++++++++++++++++----------------- generic/tclIO.h | 2 ++ generic/tclIOCmd.c | 32 +++++++++++----------- generic/tclIORChan.c | 4 +-- generic/tclInt.h | 2 ++ 5 files changed, 74 insertions(+), 43 deletions(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index d9d37a2..36ec903 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -1652,6 +1652,7 @@ Tcl_CreateChannel( chanPtr->upChanPtr = NULL; chanPtr->inQueueHead = NULL; chanPtr->inQueueTail = NULL; + chanPtr->refCount = 0; /* * TIP #219, Tcl Channel Reflection API @@ -1872,6 +1873,7 @@ Tcl_StackChannel( chanPtr->upChanPtr = NULL; chanPtr->inQueueHead = NULL; chanPtr->inQueueTail = NULL; + chanPtr->refCount = 0; /* * Place new block at the head of a possibly existing list of previously @@ -1896,6 +1898,31 @@ Tcl_StackChannel( return (Tcl_Channel) chanPtr; } + +void +TclChannelPreserve( + Tcl_Channel chan) +{ + Channel *chanPtr = (Channel *) chan; + + if (chanPtr->refCount == 0) { + Tcl_Preserve(chan); + } + chanPtr->refCount++; +} + +void +TclChannelRelease( + Tcl_Channel chan) +{ + Channel *chanPtr = (Channel *) chan; + + if (--chanPtr->refCount) { + return; + } + Tcl_Release(chan); +} + /* *---------------------------------------------------------------------- @@ -2642,7 +2669,7 @@ FlushChannel( * of the queued output to the channel. */ - Tcl_Preserve(chanPtr); + TclChannelPreserve((Tcl_Channel)chanPtr); while (statePtr->outQueueHead) { bufPtr = statePtr->outQueueHead; @@ -2833,7 +2860,7 @@ FlushChannel( } done: - Tcl_Release(chanPtr); + TclChannelRelease((Tcl_Channel)chanPtr); return errorCode; } @@ -4391,7 +4418,7 @@ Tcl_GetsObj( */ chanPtr = statePtr->topChanPtr; - Tcl_Preserve(chanPtr); + TclChannelPreserve((Tcl_Channel)chanPtr); bufPtr = statePtr->inQueueHead; encoding = statePtr->encoding; @@ -4627,9 +4654,9 @@ Tcl_GetsObj( */ if (chanPtr != statePtr->topChanPtr) { - Tcl_Release(chanPtr); + TclChannelRelease((Tcl_Channel)chanPtr); chanPtr = statePtr->topChanPtr; - Tcl_Preserve(chanPtr); + TclChannelPreserve((Tcl_Channel)chanPtr); } bufPtr = gs.bufPtr; @@ -4665,9 +4692,9 @@ Tcl_GetsObj( * self-modifying reflected transforms. */ if (chanPtr != statePtr->topChanPtr) { - Tcl_Release(chanPtr); + TclChannelRelease((Tcl_Channel)chanPtr); chanPtr = statePtr->topChanPtr; - Tcl_Preserve(chanPtr); + TclChannelPreserve((Tcl_Channel)chanPtr); } bufPtr = statePtr->inQueueHead; if (bufPtr != NULL) { @@ -4709,12 +4736,12 @@ Tcl_GetsObj( * self-modifying reflected transforms. */ if (chanPtr != statePtr->topChanPtr) { - Tcl_Release(chanPtr); + TclChannelRelease((Tcl_Channel)chanPtr); chanPtr = statePtr->topChanPtr; - Tcl_Preserve(chanPtr); + TclChannelPreserve((Tcl_Channel)chanPtr); } UpdateInterest(chanPtr); - Tcl_Release(chanPtr); + TclChannelRelease((Tcl_Channel)chanPtr); return copiedTotal; } @@ -4760,7 +4787,7 @@ TclGetsObjBinary( */ chanPtr = statePtr->topChanPtr; - Tcl_Preserve(chanPtr); + TclChannelPreserve((Tcl_Channel)chanPtr); bufPtr = statePtr->inQueueHead; @@ -4965,7 +4992,7 @@ TclGetsObjBinary( done: UpdateInterest(chanPtr); - Tcl_Release(chanPtr); + TclChannelRelease((Tcl_Channel)chanPtr); return copiedTotal; } @@ -5589,7 +5616,7 @@ DoReadChars( chanPtr = statePtr->topChanPtr; encoding = statePtr->encoding; factor = UTF_EXPANSION_FACTOR; - Tcl_Preserve(chanPtr); + TclChannelPreserve((Tcl_Channel)chanPtr); binaryMode = (encoding == NULL) && (statePtr->inputTranslation == TCL_TRANSLATE_LF) @@ -5650,9 +5677,9 @@ DoReadChars( } result = GetInput(chanPtr); if (chanPtr != statePtr->topChanPtr) { - Tcl_Release(chanPtr); + TclChannelRelease((Tcl_Channel)chanPtr); chanPtr = statePtr->topChanPtr; - Tcl_Preserve(chanPtr); + TclChannelPreserve((Tcl_Channel)chanPtr); } if (result != 0) { if (!GotFlag(statePtr, CHANNEL_BLOCKED)) { @@ -5680,9 +5707,9 @@ DoReadChars( * self-modifying reflected transforms. */ if (chanPtr != statePtr->topChanPtr) { - Tcl_Release(chanPtr); + TclChannelRelease((Tcl_Channel)chanPtr); chanPtr = statePtr->topChanPtr; - Tcl_Preserve(chanPtr); + TclChannelPreserve((Tcl_Channel)chanPtr); } /* @@ -5690,7 +5717,7 @@ DoReadChars( * in the buffers. */ UpdateInterest(chanPtr); - Tcl_Release(chanPtr); + TclChannelRelease((Tcl_Channel)chanPtr); return copied; } @@ -8062,7 +8089,7 @@ Tcl_NotifyChannel( * Preserve the channel struct in case the script closes it. */ - Tcl_Preserve(channel); + TclChannelPreserve((Tcl_Channel)channel); Tcl_Preserve(statePtr); /* @@ -8112,7 +8139,7 @@ Tcl_NotifyChannel( } Tcl_Release(statePtr); - Tcl_Release(channel); + TclChannelRelease(channel); tsdPtr->nestedHandlerPtr = nh.nestedHandlerPtr; } @@ -8594,7 +8621,7 @@ TclChannelEventScriptInvoker( */ Tcl_Preserve(interp); - Tcl_Preserve(chanPtr); + TclChannelPreserve((Tcl_Channel)chanPtr); result = Tcl_EvalObjEx(interp, esPtr->scriptPtr, TCL_EVAL_GLOBAL); /* @@ -8611,7 +8638,7 @@ TclChannelEventScriptInvoker( } Tcl_BackgroundException(interp, result); } - Tcl_Release(chanPtr); + TclChannelRelease((Tcl_Channel)chanPtr); Tcl_Release(interp); } @@ -9464,7 +9491,7 @@ DoRead( ChannelState *statePtr = chanPtr->state; char *p = dst; - Tcl_Preserve(chanPtr); + TclChannelPreserve((Tcl_Channel)chanPtr); while (bytesToRead) { /* * Each pass through the loop is intended to process up to @@ -9503,7 +9530,7 @@ DoRead( if (code) { /* Read error */ UpdateInterest(chanPtr); - Tcl_Release(chanPtr); + TclChannelRelease((Tcl_Channel)chanPtr); return -1; } @@ -9601,7 +9628,7 @@ DoRead( ResetFlag(statePtr, CHANNEL_BLOCKED); } - Tcl_Release(chanPtr); + TclChannelRelease((Tcl_Channel)chanPtr); return (int)(p - dst); } diff --git a/generic/tclIO.h b/generic/tclIO.h index 097cd61..ca74c3e 100644 --- a/generic/tclIO.h +++ b/generic/tclIO.h @@ -112,6 +112,8 @@ typedef struct Channel { ChannelBuffer *inQueueHead; /* Points at first buffer in input queue. */ ChannelBuffer *inQueueTail; /* Points at last buffer in input queue. */ + + int refCount; } Channel; /* diff --git a/generic/tclIOCmd.c b/generic/tclIOCmd.c index 3368a76..834f225 100644 --- a/generic/tclIOCmd.c +++ b/generic/tclIOCmd.c @@ -181,7 +181,7 @@ Tcl_PutsObjCmd( return TCL_ERROR; } - Tcl_Preserve(chan); + TclChannelPreserve(chan); result = Tcl_WriteObj(chan, string); if (result < 0) { goto error; @@ -192,7 +192,7 @@ Tcl_PutsObjCmd( goto error; } } - Tcl_Release(chan); + TclChannelRelease(chan); return TCL_OK; /* @@ -207,7 +207,7 @@ Tcl_PutsObjCmd( Tcl_SetObjResult(interp, Tcl_ObjPrintf("error writing \"%s\": %s", TclGetString(chanObjPtr), Tcl_PosixError(interp))); } - Tcl_Release(chan); + TclChannelRelease(chan); return TCL_ERROR; } @@ -255,7 +255,7 @@ Tcl_FlushObjCmd( return TCL_ERROR; } - Tcl_Preserve(chan); + TclChannelPreserve(chan); if (Tcl_Flush(chan) != TCL_OK) { /* * TIP #219. @@ -269,10 +269,10 @@ Tcl_FlushObjCmd( "error flushing \"%s\": %s", TclGetString(chanObjPtr), Tcl_PosixError(interp))); } - Tcl_Release(chan); + TclChannelRelease(chan); return TCL_ERROR; } - Tcl_Release(chan); + TclChannelRelease(chan); return TCL_OK; } @@ -322,7 +322,7 @@ Tcl_GetsObjCmd( return TCL_ERROR; } - Tcl_Preserve(chan); + TclChannelPreserve(chan); linePtr = Tcl_NewObj(); lineLen = Tcl_GetsObj(chan, linePtr); if (lineLen < 0) { @@ -357,7 +357,7 @@ Tcl_GetsObjCmd( Tcl_SetObjResult(interp, linePtr); } done: - Tcl_Release(chan); + TclChannelRelease(chan); return code; } @@ -465,7 +465,7 @@ Tcl_ReadObjCmd( resultPtr = Tcl_NewObj(); Tcl_IncrRefCount(resultPtr); - Tcl_Preserve(chan); + TclChannelPreserve(chan); charactersRead = Tcl_ReadChars(chan, resultPtr, toRead, 0); if (charactersRead < 0) { /* @@ -480,7 +480,7 @@ Tcl_ReadObjCmd( "error reading \"%s\": %s", TclGetString(chanObjPtr), Tcl_PosixError(interp))); } - Tcl_Release(chan); + TclChannelRelease(chan); Tcl_DecrRefCount(resultPtr); return TCL_ERROR; } @@ -499,7 +499,7 @@ Tcl_ReadObjCmd( } } Tcl_SetObjResult(interp, resultPtr); - Tcl_Release(chan); + TclChannelRelease(chan); Tcl_DecrRefCount(resultPtr); return TCL_OK; } @@ -559,7 +559,7 @@ Tcl_SeekObjCmd( mode = modeArray[optionIndex]; } - Tcl_Preserve(chan); + TclChannelPreserve(chan); result = Tcl_Seek(chan, offset, mode); if (result == Tcl_LongAsWide(-1)) { /* @@ -574,10 +574,10 @@ Tcl_SeekObjCmd( "error during seek on \"%s\": %s", TclGetString(objv[1]), Tcl_PosixError(interp))); } - Tcl_Release(chan); + TclChannelRelease(chan); return TCL_ERROR; } - Tcl_Release(chan); + TclChannelRelease(chan); return TCL_OK; } @@ -624,7 +624,7 @@ Tcl_TellObjCmd( return TCL_ERROR; } - Tcl_Preserve(chan); + TclChannelPreserve(chan); newLoc = Tcl_Tell(chan); /* @@ -635,7 +635,7 @@ Tcl_TellObjCmd( code = TclChanCaughtErrorBypass(interp, chan); - Tcl_Release(chan); + TclChannelRelease(chan); if (code) { return TCL_ERROR; } diff --git a/generic/tclIORChan.c b/generic/tclIORChan.c index 3506a44..21c766e 100644 --- a/generic/tclIORChan.c +++ b/generic/tclIORChan.c @@ -658,7 +658,7 @@ TclChanCreateObjCmd( chan = Tcl_CreateChannel(&tclRChannelType, TclGetString(rcId), rcPtr, mode); rcPtr->chan = chan; - Tcl_Preserve(chan); + TclChannelPreserve(chan); chanPtr = (Channel *) chan; if ((methods & NULLABLE_METHODS) != NULLABLE_METHODS) { @@ -2188,7 +2188,7 @@ FreeReflectedChannel( { Channel *chanPtr = (Channel *) rcPtr->chan; - Tcl_Release(chanPtr); + TclChannelRelease((Tcl_Channel)chanPtr); if (rcPtr->name) { Tcl_DecrRefCount(rcPtr->name); } diff --git a/generic/tclInt.h b/generic/tclInt.h index 9a2e8dd..1bb2103 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -2864,6 +2864,8 @@ MODULE_SCOPE int TclByteArrayMatch(const unsigned char *string, int strLen, const unsigned char *pattern, int ptnLen, int flags); MODULE_SCOPE double TclCeil(const mp_int *a); +MODULE_SCOPE void TclChannelPreserve(Tcl_Channel chan); +MODULE_SCOPE void TclChannelRelease(Tcl_Channel chan); MODULE_SCOPE int TclCheckBadOctal(Tcl_Interp *interp, const char *value); MODULE_SCOPE int TclChanCaughtErrorBypass(Tcl_Interp *interp, -- cgit v0.12 From fd5a54c8dd66798f9562fa5738b16d8531ca9097 Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 30 Jul 2014 02:58:27 +0000 Subject: Complete transformation off Tcl_Preserve() legacy onto ref counting. --- generic/tclIO.c | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index 36ec903..7381f4d 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -1903,12 +1903,7 @@ void TclChannelPreserve( Tcl_Channel chan) { - Channel *chanPtr = (Channel *) chan; - - if (chanPtr->refCount == 0) { - Tcl_Preserve(chan); - } - chanPtr->refCount++; + ((Channel *)chan)->refCount++; } void @@ -1917,10 +1912,15 @@ TclChannelRelease( { Channel *chanPtr = (Channel *) chan; + if (chanPtr->refCount == 0) { + Tcl_Panic("Channel released more than preserved"); + } if (--chanPtr->refCount) { return; } - Tcl_Release(chan); + if (chanPtr->typePtr == NULL) { + ckfree(chanPtr); + } } @@ -2071,11 +2071,6 @@ Tcl_UnstackChannel( result = ChanClose(chanPtr, interp); chanPtr->typePtr = NULL; - /* - * AK: Tcl_NotifyChannel may hold a reference to this block of memory - */ - - Tcl_EventuallyFree(chanPtr, TCL_DYNAMIC); UpdateInterest(statePtr->topChanPtr); if (result != 0) { @@ -3028,7 +3023,6 @@ CloseChannel( downChanPtr->upChanPtr = NULL; chanPtr->typePtr = NULL; - Tcl_EventuallyFree(chanPtr, TCL_DYNAMIC); return Tcl_Close(interp, (Tcl_Channel) downChanPtr); } @@ -3036,13 +3030,11 @@ CloseChannel( * There is only the TOP Channel, so we free the remaining pointers we * have and then ourselves. Since this is the last of the channels in the * stack, make sure to free the ChannelState structure associated with it. - * We use Tcl_EventuallyFree to allow for any last references. */ chanPtr->typePtr = NULL; Tcl_EventuallyFree(statePtr, TCL_DYNAMIC); - Tcl_EventuallyFree(chanPtr, TCL_DYNAMIC); return errorCode; } -- cgit v0.12 From 6c55284908a1e202a6a64ad3cb9d45569cdfcfad Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 30 Jul 2014 16:41:24 +0000 Subject: [3757cdf808] More clock refactoring with spooky impact on [string match] performance. --- generic/tclClock.c | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/generic/tclClock.c b/generic/tclClock.c index 524a9e8..9d4bcd6 100644 --- a/generic/tclClock.c +++ b/generic/tclClock.c @@ -522,6 +522,26 @@ ClockGetdatefieldsObjCmd( */ static int +FetchEraField( + Tcl_Interp *interp, + Tcl_Obj *dict, + Tcl_Obj *key, + int *storePtr) +{ + Tcl_Obj *value = NULL; + + if (Tcl_DictObjGet(interp, dict, key, &value) != TCL_OK) { + return TCL_ERROR; + } + if (value == NULL) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "expected key(s) not found in dictionary", -1)); + return TCL_ERROR; + } + return Tcl_GetIndexFromObj(interp, value, eras, "era", TCL_EXACT, storePtr); +} + +static int FetchIntField( Tcl_Interp *interp, Tcl_Obj *dict, @@ -552,7 +572,6 @@ ClockGetjuliandayfromerayearmonthdayObjCmd( Tcl_Obj *dict; ClockClientData *data = clientData; Tcl_Obj *const *literals = data->literals; - Tcl_Obj *fieldPtr; int changeover; int copied = 0; int status; @@ -567,10 +586,7 @@ ClockGetjuliandayfromerayearmonthdayObjCmd( return TCL_ERROR; } dict = objv[1]; - if (Tcl_DictObjGet(interp, dict, literals[LIT_ERA], &fieldPtr) != TCL_OK - || fieldPtr == NULL - || Tcl_GetIndexFromObj(interp, fieldPtr, eras, "era", TCL_EXACT, - &era) != TCL_OK + if (FetchEraField(interp, dict, literals[LIT_ERA], &era) != TCL_OK || FetchIntField(interp, dict, literals[LIT_YEAR], &fields.year) != TCL_OK || FetchIntField(interp, dict, literals[LIT_MONTH], &fields.month) @@ -640,7 +656,6 @@ ClockGetjuliandayfromerayearweekdayObjCmd( Tcl_Obj *dict; ClockClientData *data = clientData; Tcl_Obj *const *literals = data->literals; - Tcl_Obj *fieldPtr; int changeover; int copied = 0; int status; @@ -655,10 +670,7 @@ ClockGetjuliandayfromerayearweekdayObjCmd( return TCL_ERROR; } dict = objv[1]; - if (Tcl_DictObjGet(interp, dict, literals[LIT_ERA], &fieldPtr) != TCL_OK - || fieldPtr == NULL - || Tcl_GetIndexFromObj(interp, fieldPtr, eras, "era", TCL_EXACT, - &era) != TCL_OK + if (FetchEraField(interp, dict, literals[LIT_ERA], &era) != TCL_OK || FetchIntField(interp, dict, literals[LIT_ISO8601YEAR], &fields.iso8601Year) != TCL_OK || FetchIntField(interp, dict, literals[LIT_ISO8601WEEK], -- cgit v0.12 From 5191ece51608923ffe06ba71d44ebe0b029b4f34 Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 31 Jul 2014 19:58:53 +0000 Subject: [a84a720966] Protect against double free in TclOO classChainCache teardown. --- generic/tclOOCall.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generic/tclOOCall.c b/generic/tclOOCall.c index 26fd09f..897f635 100644 --- a/generic/tclOOCall.c +++ b/generic/tclOOCall.c @@ -150,7 +150,7 @@ void TclOODeleteChain( CallChain *callPtr) { - if (--callPtr->refCount >= 1) { + if (callPtr == NULL || --callPtr->refCount >= 1) { return; } if (callPtr->chain != callPtr->staticChain) { -- cgit v0.12 From c62d8b25aaf949ffb4b9b3524d300d9dd4f67a23 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Thu, 31 Jul 2014 21:23:45 +0000 Subject: Fix part of [d19aef1487] (broken --disable-load on MacOSX), broken by [4d417791c9] --- generic/tclLoadNone.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/generic/tclLoadNone.c b/generic/tclLoadNone.c index c22c4c4..6cb4378 100644 --- a/generic/tclLoadNone.c +++ b/generic/tclLoadNone.c @@ -104,7 +104,9 @@ TclpLoadMemory( int size, /* Dummy: unused by this implementation */ int codeSize, /* Dummy: unused by this implementation */ Tcl_LoadHandle *loadHandle, /* Dummy: unused by this implementation */ - Tcl_FSUnloadFileProc **unloadProcPtr) + Tcl_FSUnloadFileProc **unloadProcPtr, + /* Dummy: unused by this implementation */ + int flags) /* Dummy: unused by this implementation */ { Tcl_SetObjResult(interp, Tcl_NewStringObj("dynamic loading from memory " -- cgit v0.12 From 232336fbee9f13bfc26a51eaaa3c89d816588e7d Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 1 Aug 2014 14:36:30 +0000 Subject: Correction and commentary in the details of ensemble compiling. --- generic/tclEnsemble.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/generic/tclEnsemble.c b/generic/tclEnsemble.c index 022dafa..763f5a0 100644 --- a/generic/tclEnsemble.c +++ b/generic/tclEnsemble.c @@ -3019,8 +3019,24 @@ TclCompileEnsemble( cmdPtr = oldCmdPtr; depth--; } - (void) Tcl_ListObjReplace(NULL, replaced, depth, 2, 0, NULL); } + /* + * The length of the "replaced" list must be depth-1. Trim back + * any extra elements that might have been appended by failing + * pathways above. + */ + (void) Tcl_ListObjReplace(NULL, replaced, depth-1, INT_MAX, 0, NULL); + + /* + * TODO: Reconsider whether we ought to call CompileToInvokedCommand() + * when depth==1. In that case we are choosing to emit the + * INST_INVOKE_REPLACE bytecode when there is in fact no replacing + * to be done. It would be equally functional and presumably more + * performant to fall through to cleanup below, return TCL_ERROR, + * and let the compiler harness emit the INST_INVOKE_STK + * implementation for us. + */ + CompileToInvokedCommand(interp, parsePtr, replaced, cmdPtr, envPtr); ourResult = TCL_OK; } -- cgit v0.12 From a745e85067376c134070918cc967998ee4cc0594 Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 1 Aug 2014 16:01:30 +0000 Subject: [e75fabac06] Teardown line information after failed ensemble subcommand compile attempts. Copy/paste from CompileCmdCompileProc(). May be refactor opportunity here. --- generic/tclEnsemble.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/generic/tclEnsemble.c b/generic/tclEnsemble.c index 763f5a0..473c4bb 100644 --- a/generic/tclEnsemble.c +++ b/generic/tclEnsemble.c @@ -2749,6 +2749,7 @@ TclCompileEnsemble( int ourResult = TCL_ERROR; unsigned numBytes; const char *word; + DefineLineInformation; Tcl_IncrRefCount(replaced); if (parsePtr->numWords < depth + 1) { @@ -3008,6 +3009,23 @@ TclCompileEnsemble( } /* + * Throw out any line information generated by the failed compile attempt. + */ + + while (mapPtr->nuloc - 1 > eclIndex) { + mapPtr->nuloc--; + ckfree(mapPtr->loc[mapPtr->nuloc].line); + mapPtr->loc[mapPtr->nuloc].line = NULL; + } + + /* + * Reset the index of next command. Toss out any from failed nested + * partial compiles. + */ + + envPtr->numCommands = mapPtr->nuloc; + + /* * Failed to do a full compile for some reason. Try to do a direct invoke * instead of going through the ensemble lookup process again. */ -- cgit v0.12 From 0b7630c23f5b4ffb389836b9bba2b1e1b6c683e3 Mon Sep 17 00:00:00 2001 From: andreask Date: Fri, 1 Aug 2014 18:36:50 +0000 Subject: Updated package "platform" to version 1.0.13. Separated the identifiers "macosx*-i386-x86_64" and "macosx-universal" as incompatible with each other. Plus addition of a cast in tclIO.c to match types in a comparison which otherwise bugs a Windows debug build (warnings are errors). --- generic/tclIO.c | 2 +- library/platform/pkgIndex.tcl | 2 +- library/platform/platform.tcl | 43 +++++++++++++++++++++++-------------------- library/platform/shell.tcl | 2 +- unix/Makefile.in | 4 ++-- win/Makefile.in | 4 ++-- 6 files changed, 30 insertions(+), 27 deletions(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index 7216423..57a934b 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -5405,7 +5405,7 @@ ReadChars( * for sizing receiving buffers. */ - int toRead = ((unsigned) charsToRead > srcLen) ? srcLen : charsToRead; + int toRead = ((unsigned) charsToRead > (unsigned) srcLen) ? srcLen : charsToRead; /* * 'factor' is how much we guess that the bytes in the source buffer will diff --git a/library/platform/pkgIndex.tcl b/library/platform/pkgIndex.tcl index 23a3408..5250163 100644 --- a/library/platform/pkgIndex.tcl +++ b/library/platform/pkgIndex.tcl @@ -1,3 +1,3 @@ -package ifneeded platform 1.0.12 [list source [file join $dir platform.tcl]] +package ifneeded platform 1.0.13 [list source [file join $dir platform.tcl]] package ifneeded platform::shell 1.1.4 [list source [file join $dir shell.tcl]] diff --git a/library/platform/platform.tcl b/library/platform/platform.tcl index 5698425..1bce7b5 100644 --- a/library/platform/platform.tcl +++ b/library/platform/platform.tcl @@ -313,13 +313,25 @@ proc ::platform::patterns {id} { } } } + macosx-powerpc { + lappend res macosx-universal + } + macosx-x86_64 { + lappend res macosx-i386-x86_64 + } + macosx-ix86 { + lappend res macosx-universal macosx-i386-x86_64 + } macosx*-* { # 10.5+ if {[regexp {macosx([^-]*)-(.*)} $id -> v cpu]} { switch -exact -- $cpu { - ix86 - - x86_64 { set alt i386-x86_64 } + ix86 { + lappend alt i386-x86_64 + lappend alt universal + } + x86_64 { lappend alt i386-x86_64 } default { set alt {} } } @@ -330,35 +342,26 @@ proc ::platform::patterns {id} { set res {} for {set j $minor} {$j >= 5} {incr j -1} { lappend res macosx${major}.${j}-${cpu} - lappend res macosx${major}.${j}-universal - if {$alt ne {}} { - lappend res macosx${major}.${j}-$alt + foreach a $alt { + lappend res macosx${major}.${j}-$a } } # Add unversioned patterns for 10.3/10.4 builds. lappend res macosx-${cpu} - lappend res macosx-universal - if {$alt ne {}} { - lappend res macosx-$alt + foreach a $alt { + lappend res macosx-$a } } else { - lappend res macosx-universal - if {$alt ne {}} { - lappend res macosx-$alt + # No version, just do unversioned patterns. + foreach a $alt { + lappend res macosx-$a } } } else { - lappend res macosx-universal + # no v, no cpu ... nothing } } - macosx-powerpc { - lappend res macosx-universal - } - macosx-x86_64 - - macosx-ix86 { - lappend res macosx-universal macosx-i386-x86_64 - } } lappend res tcl ; # Pure tcl packages are always compatible. return $res @@ -368,7 +371,7 @@ proc ::platform::patterns {id} { # ### ### ### ######### ######### ######### ## Ready -package provide platform 1.0.12 +package provide platform 1.0.13 # ### ### ### ######### ######### ######### ## Demo application diff --git a/library/platform/shell.tcl b/library/platform/shell.tcl index d37cdcd..6eb9691 100644 --- a/library/platform/shell.tcl +++ b/library/platform/shell.tcl @@ -187,7 +187,7 @@ proc ::platform::shell::TEMP {} { } } } - if {$channel != ""} { + if {$channel ne ""} { return -code error "Failed to open a temporary file: $channel" } else { return -code error "Failed to find an unused temporary file name" diff --git a/unix/Makefile.in b/unix/Makefile.in index 4f32c87..dc0affc 100644 --- a/unix/Makefile.in +++ b/unix/Makefile.in @@ -788,8 +788,8 @@ install-libraries: libraries $(INSTALL_TZDATA) install-msgs @echo "Installing package tcltest 2.3.8 as a Tcl Module"; @$(INSTALL_DATA) $(TOP_DIR)/library/tcltest/tcltest.tcl "$(SCRIPT_INSTALL_DIR)"/../tcl8/8.5/tcltest-2.3.8.tm; - @echo "Installing package platform 1.0.12 as a Tcl Module"; - @$(INSTALL_DATA) $(TOP_DIR)/library/platform/platform.tcl "$(SCRIPT_INSTALL_DIR)"/../tcl8/8.4/platform-1.0.12.tm; + @echo "Installing package platform 1.0.13 as a Tcl Module"; + @$(INSTALL_DATA) $(TOP_DIR)/library/platform/platform.tcl "$(SCRIPT_INSTALL_DIR)"/../tcl8/8.4/platform-1.0.13.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; diff --git a/win/Makefile.in b/win/Makefile.in index a80d2fa..dd568ba 100644 --- a/win/Makefile.in +++ b/win/Makefile.in @@ -653,8 +653,8 @@ install-libraries: libraries install-tzdata install-msgs @$(COPY) $(ROOT_DIR)/library/msgcat/msgcat.tcl $(SCRIPT_INSTALL_DIR)/../tcl8/8.5/msgcat-1.5.2.tm; @echo "Installing package tcltest 2.3.8 as a Tcl Module"; @$(COPY) $(ROOT_DIR)/library/tcltest/tcltest.tcl $(SCRIPT_INSTALL_DIR)/../tcl8/8.5/tcltest-2.3.8.tm; - @echo "Installing package platform 1.0.12 as a Tcl Module"; - @$(COPY) $(ROOT_DIR)/library/platform/platform.tcl $(SCRIPT_INSTALL_DIR)/../tcl8/8.4/platform-1.0.12.tm; + @echo "Installing package platform 1.0.13 as a Tcl Module"; + @$(COPY) $(ROOT_DIR)/library/platform/platform.tcl $(SCRIPT_INSTALL_DIR)/../tcl8/8.4/platform-1.0.13.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"; -- cgit v0.12 From a3cfa0d708e397ec44bd69a830b36e04125f755c Mon Sep 17 00:00:00 2001 From: andreask Date: Fri, 1 Aug 2014 20:07:40 +0000 Subject: Addition of a cast in tclWinFile.c to match types in a comparison, and fix of a TRACE string literal in tclExecute.c with a bogus escape. Both would otherwise bug a Windows debug build (where warnings are errors). --- generic/tclExecute.c | 2 +- win/tclWinFile.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/generic/tclExecute.c b/generic/tclExecute.c index 2098e50..2e03ab4 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -5079,7 +5079,7 @@ TEBCresume( valuePtr = OBJ_AT_TOS; opnd = TclGetInt4AtPtr(pc+1); - TRACE(("\%.30s\" %d => ", O2S(valuePtr), opnd)); + TRACE(("\"%.30s\" %d => ", O2S(valuePtr), opnd)); /* * Get the contents of the list, making sure that it really is a list diff --git a/win/tclWinFile.c b/win/tclWinFile.c index 1cdd53f..fe84a26 100644 --- a/win/tclWinFile.c +++ b/win/tclWinFile.c @@ -2929,7 +2929,7 @@ TclNativeCreateNativeRep( str = Tcl_GetString(validPathPtr); len = validPathPtr->length; - if (strlen(str)!=len) { + if (strlen(str)!=(unsigned int)len) { /* String contains NUL-bytes. This is invalid. */ return 0; } -- cgit v0.12 From 592bd0b065169966705a7f17105cadebe28598b6 Mon Sep 17 00:00:00 2001 From: dgp Date: Sat, 2 Aug 2014 04:25:27 +0000 Subject: Another Preserve/Release on channels is needed during IO finalization. --- generic/tclIO.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/generic/tclIO.c b/generic/tclIO.c index 57a934b..ed40e0d 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -535,6 +535,8 @@ TclFinalizeIOSubsystem(void) * for all data to flush out. */ + TclChannelPreserve((Tcl_Channel)chanPtr); + (void) Tcl_SetChannelOption(NULL, (Tcl_Channel) chanPtr, "-blocking", "on"); @@ -586,6 +588,7 @@ TclFinalizeIOSubsystem(void) chanPtr->instanceData = NULL; SetFlag(statePtr, CHANNEL_DEAD); } + TclChannelRelease((Tcl_Channel)chanPtr); } } -- cgit v0.12 From 1cecac9cad8965f4053790ebbbcc0359de70cf7a Mon Sep 17 00:00:00 2001 From: ferrieux Date: Sat, 2 Aug 2014 13:04:16 +0000 Subject: TIP 429 Implementation: [string cat] --- doc/string.n | 8 ++++++ generic/tclCmdMZ.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++++ generic/tclCompCmdsSZ.c | 33 +++++++++++++++++++++++ generic/tclInt.h | 3 +++ tests/string.test | 34 +++++++++++++++++++---- tests/stringComp.test | 38 ++++++++++++++++++++++++-- 6 files changed, 180 insertions(+), 7 deletions(-) diff --git a/doc/string.n b/doc/string.n index 72a69ff..9108e7c 100644 --- a/doc/string.n +++ b/doc/string.n @@ -19,6 +19,14 @@ string \- Manipulate strings Performs one of several string operations, depending on \fIoption\fR. The legal \fIoption\fRs (which may be abbreviated) are: .TP +\fBstring cat\fR ?\fIstring1\fR? ?\fIstring2...\fR? +. +Concatenate the given strings just like direct juxtaposition +would. This primitive is occasionally handier than juxtaposition when +mixed quoting is wanted, or when the aim is to return the result of a +concatenation without resorting to \fB[return -level 0]\fR. If no arg +is present, an empty string is returned. +.TP \fBstring compare\fR ?\fB\-nocase\fR? ?\fB\-length\fI length\fR? \fIstring1 string2\fR . Perform a character-by-character comparison of strings \fIstring1\fR diff --git a/generic/tclCmdMZ.c b/generic/tclCmdMZ.c index 0f7f20a..ea5d7a4 100644 --- a/generic/tclCmdMZ.c +++ b/generic/tclCmdMZ.c @@ -2838,6 +2838,76 @@ StringCmpCmd( /* *---------------------------------------------------------------------- * + * StringCatCmd -- + * + * This procedure is invoked to process the "string cat" Tcl command. + * See the user documentation for details on what it does. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * See the user documentation. + * + *---------------------------------------------------------------------- + */ + +static int +StringCatCmd( + ClientData dummy, /* Not used. */ + Tcl_Interp *interp, /* Current interpreter. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument objects. */ +{ + int tot, i, length; + char *bytes, *p; + Tcl_Obj *objResultPtr; + + /* + * NOTE: this implementation aims for simplicity, not speed, because all + * speed-critical uses of [string cat] will involve the compiled variant + * anyway. Thus we avoid code duplication (from TEBC/INST_CONCAT1) without + * sacrificing perf. + */ + + if (objc < 2) { + /* + * If there are no args, the result is an empty object. + * Just leave the preset empty interp result. + */ + return TCL_OK; + } + tot = 0; + for(i = 1;i < objc;i++) { + bytes = TclGetStringFromObj(objv[i], &length); + if (bytes != NULL) { + tot += length; + } + } + if (tot < 0) { + /* TODO: convert panic to error ? */ + Tcl_Panic("max size for a Tcl value (%d bytes) exceeded", INT_MAX); + } + p = ckalloc(tot + 1); + TclNewObj(objResultPtr); + objResultPtr->bytes = p; + objResultPtr->length = tot; + for (i = 1;i < objc;i++) { + bytes = TclGetStringFromObj(objv[i], &length); + if (bytes != NULL) { + memcpy(p, bytes, (size_t) length); + p += length; + } + } + *p = '\0'; + Tcl_SetObjResult(interp,objResultPtr); + + return TCL_OK; +} + +/* + *---------------------------------------------------------------------- + * * StringBytesCmd -- * * This procedure is invoked to process the "string bytelength" Tcl @@ -3330,6 +3400,7 @@ TclInitStringCmd( { static const EnsembleImplMap stringImplMap[] = { {"bytelength", StringBytesCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0}, + {"cat", StringCatCmd, TclCompileStringCatCmd, NULL, NULL, 0}, {"compare", StringCmpCmd, TclCompileStringCmpCmd, NULL, NULL, 0}, {"equal", StringEqualCmd, TclCompileStringEqualCmd, NULL, NULL, 0}, {"first", StringFirstCmd, TclCompileStringFirstCmd, NULL, NULL, 0}, diff --git a/generic/tclCompCmdsSZ.c b/generic/tclCompCmdsSZ.c index e6ec0a6..8ade6a5 100644 --- a/generic/tclCompCmdsSZ.c +++ b/generic/tclCompCmdsSZ.c @@ -269,6 +269,39 @@ TclCompileSetCmd( */ int +TclCompileStringCatCmd( + Tcl_Interp *interp, /* Used for error reporting. */ + Tcl_Parse *parsePtr, /* Points to a parse structure for the command + * created by Tcl_ParseCommand. */ + Command *cmdPtr, /* Points to defintion of command being + * compiled. */ + CompileEnv *envPtr) /* Holds resulting instructions. */ +{ + int numWords = parsePtr->numWords; + Tcl_Token *wordTokenPtr = TokenAfter(parsePtr->tokenPtr); + DefineLineInformation; /* TIP #280 */ + + if (numWords>=2) { + int i; + + for (i = 1; i < numWords; i++) { + CompileWord(envPtr, wordTokenPtr, interp, i); + wordTokenPtr = TokenAfter(wordTokenPtr); + } + while (numWords > 256) { + TclEmitInstInt1(INST_STR_CONCAT1, 255, envPtr); + numWords -= 254; /* concat pushes 1 obj, the result */ + } + if (numWords > 2) { + TclEmitInstInt1(INST_STR_CONCAT1, numWords - 1, envPtr); + } + } else { + PushStringLiteral(envPtr, ""); + } + return TCL_OK; +} + +int TclCompileStringCmpCmd( Tcl_Interp *interp, /* Used for error reporting. */ Tcl_Parse *parsePtr, /* Points to a parse structure for the command diff --git a/generic/tclInt.h b/generic/tclInt.h index 1bb2103..6bf1ef9 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -3646,6 +3646,9 @@ MODULE_SCOPE int TclCompileReturnCmd(Tcl_Interp *interp, MODULE_SCOPE int TclCompileSetCmd(Tcl_Interp *interp, Tcl_Parse *parsePtr, Command *cmdPtr, struct CompileEnv *envPtr); +MODULE_SCOPE int TclCompileStringCatCmd(Tcl_Interp *interp, + Tcl_Parse *parsePtr, Command *cmdPtr, + struct CompileEnv *envPtr); MODULE_SCOPE int TclCompileStringCmpCmd(Tcl_Interp *interp, Tcl_Parse *parsePtr, Command *cmdPtr, struct CompileEnv *envPtr); diff --git a/tests/string.test b/tests/string.test index a8a83d9..54d02e8 100644 --- a/tests/string.test +++ b/tests/string.test @@ -30,7 +30,7 @@ testConstraint memory [llength [info commands memory]] test string-1.1 {error conditions} { list [catch {string gorp a b} msg] $msg -} {1 {unknown or ambiguous subcommand "gorp": must be bytelength, compare, equal, first, index, is, last, length, map, match, range, repeat, replace, reverse, tolower, totitle, toupper, trim, trimleft, trimright, wordend, or wordstart}} +} {1 {unknown or ambiguous subcommand "gorp": must be bytelength, cat, compare, equal, first, index, is, last, length, map, match, range, repeat, replace, reverse, tolower, totitle, toupper, trim, trimleft, trimright, wordend, or wordstart}} test string-1.2 {error conditions} { list [catch {string} msg] $msg } {1 {wrong # args: should be "string subcommand ?arg ...?"}} @@ -54,7 +54,7 @@ test string-2.6 {string compare} { string compare abcde abdef } -1 test string-2.7 {string compare, shortest method name} { - string c abcde ABCDE + string co abcde ABCDE } 1 test string-2.8 {string compare} { string compare abcde abcde @@ -81,7 +81,7 @@ test string-2.13 {string compare -nocase} { string compare -nocase abcde abdef } -1 test string-2.14 {string compare -nocase} { - string c -nocase abcde ABCDE + string compare -nocase abcde ABCDE } 0 test string-2.15 {string compare -nocase} { string compare -nocase abcde abcde @@ -1513,7 +1513,7 @@ test string-20.1 {string trimright errors} { } {1 {wrong # args: should be "string trimright string ?chars?"}} test string-20.2 {string trimright errors} { list [catch {string trimg a} msg] $msg -} {1 {unknown or ambiguous subcommand "trimg": must be bytelength, compare, equal, first, index, is, last, length, map, match, range, repeat, replace, reverse, tolower, totitle, toupper, trim, trimleft, trimright, wordend, or wordstart}} +} {1 {unknown or ambiguous subcommand "trimg": must be bytelength, cat, compare, equal, first, index, is, last, length, map, match, range, repeat, replace, reverse, tolower, totitle, toupper, trim, trimleft, trimright, wordend, or wordstart}} test string-20.3 {string trimright} { string trimright " XYZ " } { XYZ} @@ -1572,7 +1572,7 @@ test string-21.14 {string wordend, unicode} { test string-22.1 {string wordstart} { list [catch {string word a} msg] $msg -} {1 {unknown or ambiguous subcommand "word": must be bytelength, compare, equal, first, index, is, last, length, map, match, range, repeat, replace, reverse, tolower, totitle, toupper, trim, trimleft, trimright, wordend, or wordstart}} +} {1 {unknown or ambiguous subcommand "word": must be bytelength, cat, compare, equal, first, index, is, last, length, map, match, range, repeat, replace, reverse, tolower, totitle, toupper, trim, trimleft, trimright, wordend, or wordstart}} test string-22.2 {string wordstart} { list [catch {string wordstart a} msg] $msg } {1 {wrong # args: should be "string wordstart string index"}} @@ -1969,6 +1969,30 @@ test string-28.13 {tcl::prefix longest} { tcl::prefix longest {ax\x90 bep ax\x91} a } ax +test string-29.1 {string cat, no arg} { + string cat +} "" +test string-29.2 {string cat, single arg} { + set x [pid] + string compare $x [string cat $x] +} 0 +test string-29.3 {string cat, two args} { + set x [pid] + string compare $x$x [string cat $x $x] +} 0 +test string-29.4 {string cat, many args} { + set x [pid] + set n 260 + set xx [string repeat $x $n] + set vv [string repeat {$x} $n] + set vvs [string repeat {$x } $n] + set r1 [string compare $xx [subst $vv]] + set r2 [string compare $xx [eval "string cat $vvs"]] + list $r1 $r2 +} {0 0} + + + # cleanup rename MemStress {} catch {rename foo {}} diff --git a/tests/stringComp.test b/tests/stringComp.test index 165ef20..083399b 100644 --- a/tests/stringComp.test +++ b/tests/stringComp.test @@ -46,7 +46,7 @@ if {[testConstraint memory]} { test stringComp-1.1 {error conditions} { proc foo {} {string gorp a b} list [catch {foo} msg] $msg -} {1 {unknown or ambiguous subcommand "gorp": must be bytelength, compare, equal, first, index, is, last, length, map, match, range, repeat, replace, reverse, tolower, totitle, toupper, trim, trimleft, trimright, wordend, or wordstart}} +} {1 {unknown or ambiguous subcommand "gorp": must be bytelength, cat, compare, equal, first, index, is, last, length, map, match, range, repeat, replace, reverse, tolower, totitle, toupper, trim, trimleft, trimright, wordend, or wordstart}} test stringComp-1.2 {error conditions} { proc foo {} {string} list [catch {foo} msg] $msg @@ -210,7 +210,7 @@ foreach {tname tbody tresult tcode} { # need a few extra tests short abbr cmd test stringComp-3.1 {string compare, shortest method name} { - proc foo {} {string c abcde ABCDE} + proc foo {} {string co abcde ABCDE} foo } 1 test stringComp-3.2 {string equal, shortest method name} { @@ -735,6 +735,40 @@ test stringComp-14.2 {Bug 82e7f67325} memory { ## string word* ## not yet bc + +## string cat +test stringComp-29.1 {string cat, no arg} { + proc foo {} {string cat} + foo +} "" +test stringComp-29.2 {string cat, single arg} { + proc foo {} { + set x [pid] + string compare $x [string cat $x] + } + foo +} 0 +test stringComp-29.3 {string cat, two args} { + proc foo {} { + set x [pid] + string compare $x$x [string cat $x $x] + } + foo +} 0 +test stringComp-29.4 {string cat, many args} { + proc foo {} { + set x [pid] + set n 260 + set xx [string repeat $x $n] + set vv [string repeat {$x} $n] + set vvs [string repeat {$x } $n] + set r1 [string compare $xx [subst $vv]] + set r2 [string compare $xx [eval "string cat $vvs"]] + list $r1 $r2 + } + foo +} {0 0} + # cleanup catch {rename foo {}} -- cgit v0.12 From 25860d9071aa5e499460765990c73bd915d76130 Mon Sep 17 00:00:00 2001 From: ferrieux Date: Sat, 2 Aug 2014 15:26:46 +0000 Subject: Don't use [pid] in tests, stick to constant literals. --- doc/string.n | 2 ++ tests/string.test | 6 +++--- tests/stringComp.test | 6 +++--- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/doc/string.n b/doc/string.n index 9108e7c..450a97b 100644 --- a/doc/string.n +++ b/doc/string.n @@ -19,6 +19,7 @@ string \- Manipulate strings Performs one of several string operations, depending on \fIoption\fR. The legal \fIoption\fRs (which may be abbreviated) are: .TP +.VS 8.6.2 \fBstring cat\fR ?\fIstring1\fR? ?\fIstring2...\fR? . Concatenate the given strings just like direct juxtaposition @@ -26,6 +27,7 @@ would. This primitive is occasionally handier than juxtaposition when mixed quoting is wanted, or when the aim is to return the result of a concatenation without resorting to \fB[return -level 0]\fR. If no arg is present, an empty string is returned. +.VE .TP \fBstring compare\fR ?\fB\-nocase\fR? ?\fB\-length\fI length\fR? \fIstring1 string2\fR . diff --git a/tests/string.test b/tests/string.test index 54d02e8..3611753 100644 --- a/tests/string.test +++ b/tests/string.test @@ -1973,15 +1973,15 @@ test string-29.1 {string cat, no arg} { string cat } "" test string-29.2 {string cat, single arg} { - set x [pid] + set x FOO string compare $x [string cat $x] } 0 test string-29.3 {string cat, two args} { - set x [pid] + set x FOO string compare $x$x [string cat $x $x] } 0 test string-29.4 {string cat, many args} { - set x [pid] + set x FOO set n 260 set xx [string repeat $x $n] set vv [string repeat {$x} $n] diff --git a/tests/stringComp.test b/tests/stringComp.test index 083399b..f9f6bda 100644 --- a/tests/stringComp.test +++ b/tests/stringComp.test @@ -743,21 +743,21 @@ test stringComp-29.1 {string cat, no arg} { } "" test stringComp-29.2 {string cat, single arg} { proc foo {} { - set x [pid] + set x FOO string compare $x [string cat $x] } foo } 0 test stringComp-29.3 {string cat, two args} { proc foo {} { - set x [pid] + set x FOO string compare $x$x [string cat $x $x] } foo } 0 test stringComp-29.4 {string cat, many args} { proc foo {} { - set x [pid] + set x FOO set n 260 set xx [string repeat $x $n] set vv [string repeat {$x} $n] -- cgit v0.12 From 239374cbb83d917a831c9b093be64ee311c31afc Mon Sep 17 00:00:00 2001 From: dkf Date: Sun, 3 Aug 2014 22:43:42 +0000 Subject: Tidy up the docs --- doc/string.n | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/doc/string.n b/doc/string.n index 450a97b..33780ff 100644 --- a/doc/string.n +++ b/doc/string.n @@ -19,14 +19,19 @@ string \- Manipulate strings Performs one of several string operations, depending on \fIoption\fR. The legal \fIoption\fRs (which may be abbreviated) are: .TP -.VS 8.6.2 \fBstring cat\fR ?\fIstring1\fR? ?\fIstring2...\fR? -. -Concatenate the given strings just like direct juxtaposition -would. This primitive is occasionally handier than juxtaposition when -mixed quoting is wanted, or when the aim is to return the result of a -concatenation without resorting to \fB[return -level 0]\fR. If no arg -is present, an empty string is returned. +.VS 8.6.2 +Concatenate the given \fIstring\fRs just like placing them directly +next to each other and return the resulting compound string. If no +\fIstring\fRs are present, the result is an empty string. +.RS +.PP +This primitive is occasionally handier than juxtaposition of strings +when mixed quoting is wanted, or when the aim is to return the result +of a concatenation without resorting to \fBreturn\fR \fB\-level 0\fR, +and is more efficient than building a list of arguments and using +\fBjoin\fR with an empty join string. +.RE .VE .TP \fBstring compare\fR ?\fB\-nocase\fR? ?\fB\-length\fI length\fR? \fIstring1 string2\fR -- cgit v0.12 From 67fcf44a821dcad20d12a0ca185dcafcfa1b80c6 Mon Sep 17 00:00:00 2001 From: dgp Date: Mon, 4 Aug 2014 13:35:06 +0000 Subject: Add tclsh.exe.manifest.in to the distribution. --- unix/Makefile.in | 1 + 1 file changed, 1 insertion(+) diff --git a/unix/Makefile.in b/unix/Makefile.in index dc0affc..faec411 100644 --- a/unix/Makefile.in +++ b/unix/Makefile.in @@ -1716,6 +1716,7 @@ dist: $(UNIX_DIR)/configure $(UNIX_DIR)/tclConfig.h.in $(UNIX_DIR)/tcl.pc.in $(M cp $(TOP_DIR)/win/configure.in $(TOP_DIR)/win/configure \ $(TOP_DIR)/win/tclConfig.sh.in \ $(TOP_DIR)/win/tcl.m4 $(TOP_DIR)/win/aclocal.m4 \ + $(TOP_DIR)/win/tclsh.exe.manifest.in \ $(DISTDIR)/win cp -p $(TOP_DIR)/win/*.[ch] $(TOP_DIR)/win/*.ico $(TOP_DIR)/win/*.rc \ $(DISTDIR)/win -- cgit v0.12 From 5863c1e1b9daf1140ec3cd35a922695e987afcd1 Mon Sep 17 00:00:00 2001 From: ferrieux Date: Tue, 5 Aug 2014 09:55:54 +0000 Subject: More optimized non-BC [string cat] using Tcl_AppendObjToObj() - thx Donal --- generic/tclCmdMZ.c | 45 ++++++++++++++------------------------------- 1 file changed, 14 insertions(+), 31 deletions(-) diff --git a/generic/tclCmdMZ.c b/generic/tclCmdMZ.c index ea5d7a4..841002f 100644 --- a/generic/tclCmdMZ.c +++ b/generic/tclCmdMZ.c @@ -2859,17 +2859,9 @@ StringCatCmd( int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { - int tot, i, length; - char *bytes, *p; + int i; Tcl_Obj *objResultPtr; - /* - * NOTE: this implementation aims for simplicity, not speed, because all - * speed-critical uses of [string cat] will involve the compiled variant - * anyway. Thus we avoid code duplication (from TEBC/INST_CONCAT1) without - * sacrificing perf. - */ - if (objc < 2) { /* * If there are no args, the result is an empty object. @@ -2877,30 +2869,21 @@ StringCatCmd( */ return TCL_OK; } - tot = 0; - for(i = 1;i < objc;i++) { - bytes = TclGetStringFromObj(objv[i], &length); - if (bytes != NULL) { - tot += length; - } + if (objc == 2) { + /* + * Other trivial case, single arg, just return it. + */ + Tcl_SetObjResult(interp, objv[1]); + return TCL_OK; } - if (tot < 0) { - /* TODO: convert panic to error ? */ - Tcl_Panic("max size for a Tcl value (%d bytes) exceeded", INT_MAX); - } - p = ckalloc(tot + 1); - TclNewObj(objResultPtr); - objResultPtr->bytes = p; - objResultPtr->length = tot; - for (i = 1;i < objc;i++) { - bytes = TclGetStringFromObj(objv[i], &length); - if (bytes != NULL) { - memcpy(p, bytes, (size_t) length); - p += length; - } + objResultPtr = objv[1]; + if (Tcl_IsShared(objResultPtr)) { + objResultPtr = Tcl_DuplicateObj(objResultPtr); + } + for(i = 2;i < objc;i++) { + Tcl_AppendObjToObj(objResultPtr, objv[i]); } - *p = '\0'; - Tcl_SetObjResult(interp,objResultPtr); + Tcl_SetObjResult(interp, objResultPtr); return TCL_OK; } -- cgit v0.12 From 76e87312ed61ae91fdf567f60d39dca66464ecc1 Mon Sep 17 00:00:00 2001 From: ferrieux Date: Tue, 5 Aug 2014 10:34:10 +0000 Subject: Add constant folding to [string cat]. Mixed-quote idiom is now compiled to a single push. --- generic/tclCompCmdsSZ.c | 62 ++++++++++++++++++++++++++++++++++++------------- 1 file changed, 46 insertions(+), 16 deletions(-) diff --git a/generic/tclCompCmdsSZ.c b/generic/tclCompCmdsSZ.c index 8ade6a5..bd8b463 100644 --- a/generic/tclCompCmdsSZ.c +++ b/generic/tclCompCmdsSZ.c @@ -277,27 +277,57 @@ TclCompileStringCatCmd( * compiled. */ CompileEnv *envPtr) /* Holds resulting instructions. */ { - int numWords = parsePtr->numWords; - Tcl_Token *wordTokenPtr = TokenAfter(parsePtr->tokenPtr); + int i,numWords = parsePtr->numWords; + Tcl_Token *wordTokenPtr; + Tcl_Obj *obj, *folded; DefineLineInformation; /* TIP #280 */ - if (numWords>=2) { - int i; + /* Trivial case, no arg */ - for (i = 1; i < numWords; i++) { - CompileWord(envPtr, wordTokenPtr, interp, i); - wordTokenPtr = TokenAfter(wordTokenPtr); - } - while (numWords > 256) { - TclEmitInstInt1(INST_STR_CONCAT1, 255, envPtr); - numWords -= 254; /* concat pushes 1 obj, the result */ - } - if (numWords > 2) { - TclEmitInstInt1(INST_STR_CONCAT1, numWords - 1, envPtr); - } - } else { + if (numWords<2) { PushStringLiteral(envPtr, ""); + return TCL_OK; } + + /* Detection of foldable constants. Often used for mixed quoting. */ + + folded = Tcl_NewObj(); + wordTokenPtr = TokenAfter(parsePtr->tokenPtr); + for (i = 1; i < numWords; i++) { + obj = Tcl_NewObj(); + if (TclWordKnownAtCompileTime(wordTokenPtr, obj)) { + Tcl_AppendObjToObj(folded, obj); + } else { + Tcl_DecrRefCount(obj); + Tcl_DecrRefCount(folded); + folded = NULL; + break; + } + wordTokenPtr = TokenAfter(wordTokenPtr); + } + if (folded) { + int len; + const char *bytes = Tcl_GetStringFromObj(folded, &len); + + PushLiteral(envPtr, bytes, len); + return TCL_OK; + } + + /* General case: just issue CONCAT1's (by chunks of 255 if needed) */ + + wordTokenPtr = TokenAfter(parsePtr->tokenPtr); + for (i = 1; i < numWords; i++) { + CompileWord(envPtr, wordTokenPtr, interp, i); + wordTokenPtr = TokenAfter(wordTokenPtr); + } + while (numWords > 256) { + TclEmitInstInt1(INST_STR_CONCAT1, 255, envPtr); + numWords -= 254; /* concat pushes 1 obj, the result */ + } + if (numWords > 2) { + TclEmitInstInt1(INST_STR_CONCAT1, numWords - 1, envPtr); + } + return TCL_OK; } -- cgit v0.12 From 796e087b9cba02223f442765f8c4f54f79ab7275 Mon Sep 17 00:00:00 2001 From: ferrieux Date: Tue, 5 Aug 2014 11:29:16 +0000 Subject: Better organize [string cat] by chunks of 255 args. --- generic/tclCompCmdsSZ.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/generic/tclCompCmdsSZ.c b/generic/tclCompCmdsSZ.c index bd8b463..87b1ebb 100644 --- a/generic/tclCompCmdsSZ.c +++ b/generic/tclCompCmdsSZ.c @@ -277,7 +277,7 @@ TclCompileStringCatCmd( * compiled. */ CompileEnv *envPtr) /* Holds resulting instructions. */ { - int i,numWords = parsePtr->numWords; + int i, numWords = parsePtr->numWords, numArgs; Tcl_Token *wordTokenPtr; Tcl_Obj *obj, *folded; DefineLineInformation; /* TIP #280 */ @@ -315,17 +315,19 @@ TclCompileStringCatCmd( /* General case: just issue CONCAT1's (by chunks of 255 if needed) */ + numArgs = 0; wordTokenPtr = TokenAfter(parsePtr->tokenPtr); for (i = 1; i < numWords; i++) { CompileWord(envPtr, wordTokenPtr, interp, i); + numArgs ++; + if (numArgs == 255) { + TclEmitInstInt1(INST_STR_CONCAT1, 255, envPtr); + numArgs = 1; /* concat pushes 1 obj, the result */ + } wordTokenPtr = TokenAfter(wordTokenPtr); } - while (numWords > 256) { - TclEmitInstInt1(INST_STR_CONCAT1, 255, envPtr); - numWords -= 254; /* concat pushes 1 obj, the result */ - } - if (numWords > 2) { - TclEmitInstInt1(INST_STR_CONCAT1, numWords - 1, envPtr); + if (numArgs > 1) { + TclEmitInstInt1(INST_STR_CONCAT1, numArgs, envPtr); } return TCL_OK; -- cgit v0.12 From d544f36344dcaa90d08fbd94e278143edbe0112f Mon Sep 17 00:00:00 2001 From: ferrieux Date: Tue, 5 Aug 2014 18:20:48 +0000 Subject: More aggressive constant folding in [string cat]. Thanks AndreasK for kicking. --- generic/tclCompCmdsSZ.c | 47 +++++++++++++++++++++++++++-------------------- 1 file changed, 27 insertions(+), 20 deletions(-) diff --git a/generic/tclCompCmdsSZ.c b/generic/tclCompCmdsSZ.c index 87b1ebb..fb26430 100644 --- a/generic/tclCompCmdsSZ.c +++ b/generic/tclCompCmdsSZ.c @@ -289,19 +289,38 @@ TclCompileStringCatCmd( return TCL_OK; } - /* Detection of foldable constants. Often used for mixed quoting. */ + /* General case: issue CONCAT1's (by chunks of 255 if needed), folding + contiguous constants along the way */ - folded = Tcl_NewObj(); + numArgs = 0; + folded = NULL; wordTokenPtr = TokenAfter(parsePtr->tokenPtr); for (i = 1; i < numWords; i++) { obj = Tcl_NewObj(); if (TclWordKnownAtCompileTime(wordTokenPtr, obj)) { - Tcl_AppendObjToObj(folded, obj); + if (folded) { + Tcl_AppendObjToObj(folded, obj); + Tcl_DecrRefCount(obj); + } else { + folded = obj; + } } else { Tcl_DecrRefCount(obj); - Tcl_DecrRefCount(folded); - folded = NULL; - break; + if (folded) { + int len; + const char *bytes = Tcl_GetStringFromObj(folded, &len); + + PushLiteral(envPtr, bytes, len); + Tcl_DecrRefCount(folded); + folded = NULL; + numArgs ++; + } + CompileWord(envPtr, wordTokenPtr, interp, i); + numArgs ++; + if (numArgs >= 254) { /* 254 to take care of the possible +1 of "folded" above */ + TclEmitInstInt1(INST_STR_CONCAT1, 254, envPtr); + numArgs -= 253; /* concat pushes 1 obj, the result */ + } } wordTokenPtr = TokenAfter(wordTokenPtr); } @@ -310,21 +329,9 @@ TclCompileStringCatCmd( const char *bytes = Tcl_GetStringFromObj(folded, &len); PushLiteral(envPtr, bytes, len); - return TCL_OK; - } - - /* General case: just issue CONCAT1's (by chunks of 255 if needed) */ - - numArgs = 0; - wordTokenPtr = TokenAfter(parsePtr->tokenPtr); - for (i = 1; i < numWords; i++) { - CompileWord(envPtr, wordTokenPtr, interp, i); + Tcl_DecrRefCount(folded); + folded = NULL; numArgs ++; - if (numArgs == 255) { - TclEmitInstInt1(INST_STR_CONCAT1, 255, envPtr); - numArgs = 1; /* concat pushes 1 obj, the result */ - } - wordTokenPtr = TokenAfter(wordTokenPtr); } if (numArgs > 1) { TclEmitInstInt1(INST_STR_CONCAT1, numArgs, envPtr); -- cgit v0.12 From 91b9c5690e5e6cec713077c007a883dbf40243ad Mon Sep 17 00:00:00 2001 From: ferrieux Date: Tue, 5 Aug 2014 22:10:58 +0000 Subject: Fix comment inaccuracy. --- generic/tclCompCmdsSZ.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generic/tclCompCmdsSZ.c b/generic/tclCompCmdsSZ.c index fb26430..f2e5dd2 100644 --- a/generic/tclCompCmdsSZ.c +++ b/generic/tclCompCmdsSZ.c @@ -289,7 +289,7 @@ TclCompileStringCatCmd( return TCL_OK; } - /* General case: issue CONCAT1's (by chunks of 255 if needed), folding + /* General case: issue CONCAT1's (by chunks of 254 if needed), folding contiguous constants along the way */ numArgs = 0; -- cgit v0.12 From 582c164dc34e3ea0ca7eaa231b6d996f92c54b7e Mon Sep 17 00:00:00 2001 From: andreask Date: Wed, 6 Aug 2014 18:20:56 +0000 Subject: Fixed type conversion warnings which break a Win32 debug build (MSVC). --- generic/tclIO.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index c142917..66c0be6 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -9048,7 +9048,8 @@ MBWrite( ChannelState *outStatePtr = csPtr->writePtr->state; ChannelBuffer *bufPtr = inStatePtr->inQueueHead; ChannelBuffer *tail = NULL; - int code, inBytes = 0; + int code; + Tcl_WideInt inBytes = 0; /* Count up number of bytes waiting in the input queue */ while (bufPtr) { @@ -9063,7 +9064,14 @@ MBWrite( if (bufPtr) { /* Split the overflowing buffer in two */ - int extra = inBytes - csPtr->toRead; + int extra = (int) (inBytes - csPtr->toRead); + /* Note that going with int for extra assumes that inBytes is not too + * much over toRead to require a wide itself. If that gets violated + * then the calculations involving extra must be made wide too. + * + * Noted with Win32/MSVC debug build treating the warning (possible of + * data in int64 to int conversion) as error. + */ bufPtr = AllocChannelBuffer(extra); -- cgit v0.12 From c93483448e724b85c9b710945ca3c70688ac68f6 Mon Sep 17 00:00:00 2001 From: dgp Date: Tue, 12 Aug 2014 15:28:09 +0000 Subject: Accommodate the "udp" package, and any other Tcl package that expects a [read] on a channel @ EOF to attempt another pass through the channel drivers instead of immediately returning an empty string. Correcting this misbehavior appears too disruptive in a patch release to a long stable branch. --- generic/tclIO.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index ed40e0d..afffeb8 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -5209,7 +5209,7 @@ DoReadChars( } /* Must clear the BLOCKED flag here since we check before reading */ - ResetFlag(statePtr, CHANNEL_BLOCKED); + ResetFlag(statePtr, CHANNEL_BLOCKED|CHANNEL_EOF); for (copied = 0; (unsigned) toRead > 0; ) { copiedNow = -1; if (statePtr->inQueueHead != NULL) { -- cgit v0.12 From 8c3d28816cd8c0e7fa31bd521ccae21f9e3a1aff Mon Sep 17 00:00:00 2001 From: dgp Date: Tue, 12 Aug 2014 21:41:29 +0000 Subject: Update changes file --- changes | 103 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 103 insertions(+) diff --git a/changes b/changes index 5d6ef97..78765f2 100644 --- a/changes +++ b/changes @@ -7791,3 +7791,106 @@ Many revisions to better support a Cygwin environment (nijtmans) 2013-09-13 (bug fix)[bdd91c] crash in exec stack mem management (azazel) --- Released 8.5.15, September 16, 2013 --- http://core.tcl.tk/tcl/ for details + +2013-09-19 (bug fix)[3487626] [dict] compile segfaults (porter) + +2013-09-19 (bug fix) [info frame] line OBOEs in bytecode (porter) + +2013-09-25 (bug fix)[d614d63] namespace matching *:: deletion fail (fellows) + +2013-10-05 tzdata updated to Olson's tzdata2013g (kenny) + +2013-10-22 (bug fix)[3556215] [scan %E%G%X] support (fellows) + +2013-10-25 (bug fix)[3eb2ec1] upper case scheme names in url. (nijtmans) +=> http 2.7.13 + +2013-10-29 (bug fix)[414d103] HP-UX: restore [exec] in threaded Tcl (nijtmans) + +2013-11-04 (bug fix) C++ friendly stubs struct declarations (nijtmans) + +2013-11-05 (bug fix)[426679e] OpenBSD man page rendering (nijtmans) + +2013-11-20 (bug fix) Improved environment variable management (nijtmans) +=> tcltest 2.3.7 + +2013-11-21 (platforms) Support for Windows 8.1 (nijtmans) + +2014-02-06 (bug fix)[a4494e2] panic in test namespace-13.2 (porter) + +2014-02-24 (bug fix)[2413550] Win: avoid serial double open (oehlmann) + +2014-03-20 (bug fix)[2f7cbd0] FreeBSD 10.0 build failure (nijtmans) + +2014-03-27 (bug fix) segfault iocmd-23.11 (porter) + +2014-04-02 (bug fix)[336441e] Win: async socket connect stall (oehlmann) + +2014-04-04 (bug fix)[581937a,97069ea] async socket connect fail (oehlmann) + +2014-04-10 (bug fix)[792641f] Win: no \ in normalized path (nijtmans) + +2014-04-15 (bug fix)[88aef05] segfault iocmd-21.20 (porter) + +2014-04-16 (update) Win: use Winsock 2.2 (nijtmans) + +2014-04-16 (bug fix)[d19a30d] segfault clock-67.[23] (sebres) + +2014-04-21 (bug fix) segfault iocmd-21.2[12] (porter) + +2014-04-22 (bug fix) segfault iogt-2.4 (porter) + +2014-04-23 (bug fix)[3493120] memleak in thread exit + +2014-04-30 (bug fix) segfault iocmd-21.2[34] (porter) + +2014-05-01 (bug fix)[0e92c40] bytearray optimization validity (nijtmans) + +2014-05-06 (bug fix) segfault iogt-2.5 (porter) + +2014-05-06 (memleaks) io-29.27 io-29.34 io-33.7 (porter) + +2014-05-07 (memleaks) io-53.5, cloned Tcl_ChannelTypes (porter) + +2014-05-08 (memleak) iocmd-21.22 (porter) + +2014-05-08 refactoring of core I/O functions (porter) + +2014-05-09 (bug fix) segfault iocmd-32.1 (porter) + +2014-05-15 (bug fix)[3118489] protect NUL in filenames (nijtmans) + +2014-05-16 (bug fix) Fix for failing tests *io-32.11* (porter) + +2014-05-20 (bug fix) Stop eof and blocked state leaking thru stacks (porter) + *** POTENTIAL INCOMPATIBILITY *** + +2014-05-22 (platforms) work around systems that fail when a shared library +is deleted after it is [load]ed (kupries) + +2014-05-31 (bug fix) chan events on pipes must be on proper ends (porter) + +2014-06-04 (bug fix) socket-2.12 (porter) + +2014-06-05 (bug fix) io-12.6 (kupries,porter) + +2014-06-16 (bug fix) socket-2.13 workaround broken select() (porter) + +2014-06-20 (bug fix)[b47b176] iortrans.tf-11.0 (porter) + +2014-06-22 (RFE)[2f9df4c] -cleanup scripts before -out compare (nijtmans) + +2014-07-04 (update) Update Unicode data to 7.0 (nijtmans) + *** POTENTIAL INCOMPATIBILITY *** + +2014-07-10 (bug fix)[7368d2] memleak Tcl_SetVar2(..,TCL_APPEND_VALUE) (porter) + *** POTENTIAL INCOMPATIBILITY *** + +2014-08-01 (enhancement) use refcounts, not Tcl_Preserve to manage lifetime +of Tcl_Channel (porter) + *** POTENTIAL INCOMPATIBILITY *** + +2014-08-01 (update) "macosx*-i386-x86_64" "macosx-universal" no longer compatible (kupries) +=> platform 1.0.13 + +--- Released 8.5.16, August, 2014 --- http://core.tcl.tk/tcl/ for details -- cgit v0.12 From ac5fa7c959eb615cad08a5d5d4c155a61e05b45e Mon Sep 17 00:00:00 2001 From: Kevin B Kenny Date: Wed, 13 Aug 2014 01:42:17 +0000 Subject: tzdata2014f from ietf.org --- library/tzdata/Africa/Accra | 32 ++ library/tzdata/Africa/Bamako | 9 +- library/tzdata/Africa/Banjul | 9 +- library/tzdata/Africa/Cairo | 184 ++++++++++++ library/tzdata/Africa/Casablanca | 231 +++++++++------ library/tzdata/Africa/Conakry | 9 +- library/tzdata/Africa/Dakar | 8 +- library/tzdata/Africa/El_Aaiun | 215 ++++++++++++++ library/tzdata/Africa/Freetown | 37 +-- library/tzdata/Africa/Lome | 7 +- library/tzdata/Africa/Nouakchott | 9 +- library/tzdata/Africa/Ouagadougou | 7 +- library/tzdata/Africa/Sao_Tome | 8 +- library/tzdata/Africa/Timbuktu | 6 +- library/tzdata/Africa/Tripoli | 174 +---------- library/tzdata/America/Eirunepe | 1 + library/tzdata/America/Havana | 2 +- library/tzdata/America/Metlakatla | 2 +- library/tzdata/America/Rio_Branco | 1 + library/tzdata/Antarctica/Casey | 6 +- library/tzdata/Antarctica/Macquarie | 180 ++++++------ library/tzdata/Asia/Amman | 174 ++++++++++- library/tzdata/Asia/Chongqing | 20 +- library/tzdata/Asia/Chungking | 6 +- library/tzdata/Asia/Gaza | 4 +- library/tzdata/Asia/Harbin | 23 +- library/tzdata/Asia/Hebron | 4 +- library/tzdata/Asia/Irkutsk | 7 +- library/tzdata/Asia/Jayapura | 2 +- library/tzdata/Asia/Jerusalem | 4 +- library/tzdata/Asia/Kashgar | 21 +- library/tzdata/Asia/Khandyga | 1 + library/tzdata/Asia/Krasnoyarsk | 1 + library/tzdata/Asia/Magadan | 1 + library/tzdata/Asia/Novokuznetsk | 1 + library/tzdata/Asia/Novosibirsk | 1 + library/tzdata/Asia/Omsk | 1 + library/tzdata/Asia/Pyongyang | 6 +- library/tzdata/Asia/Riyadh | 2 +- library/tzdata/Asia/Sakhalin | 5 +- library/tzdata/Asia/Seoul | 6 +- library/tzdata/Asia/Shanghai | 4 +- library/tzdata/Asia/Taipei | 16 +- library/tzdata/Asia/Tashkent | 4 +- library/tzdata/Asia/Tbilisi | 6 +- library/tzdata/Asia/Tokyo | 4 +- library/tzdata/Asia/Urumqi | 15 +- library/tzdata/Asia/Ust-Nera | 1 + library/tzdata/Asia/Vladivostok | 11 +- library/tzdata/Asia/Yakutsk | 1 + library/tzdata/Asia/Yekaterinburg | 5 +- library/tzdata/Atlantic/St_Helena | 8 +- library/tzdata/Australia/Adelaide | 536 +++++++++++++++++----------------- library/tzdata/Australia/Brisbane | 36 +-- library/tzdata/Australia/Broken_Hill | 540 +++++++++++++++++----------------- library/tzdata/Australia/Currie | 536 +++++++++++++++++----------------- library/tzdata/Australia/Darwin | 20 +- library/tzdata/Australia/Eucla | 40 +-- library/tzdata/Australia/Hobart | 552 +++++++++++++++++------------------ library/tzdata/Australia/Lindeman | 46 +-- library/tzdata/Australia/Lord_Howe | 240 +++++++-------- library/tzdata/Australia/Melbourne | 534 ++++++++++++++++----------------- library/tzdata/Australia/Perth | 40 +-- library/tzdata/Australia/Sydney | 534 ++++++++++++++++----------------- library/tzdata/Europe/Budapest | 10 +- library/tzdata/Europe/Helsinki | 8 +- library/tzdata/Europe/Istanbul | 3 +- library/tzdata/Europe/Kaliningrad | 1 + library/tzdata/Europe/Kiev | 6 +- library/tzdata/Europe/Moscow | 22 +- library/tzdata/Europe/Riga | 14 +- library/tzdata/Europe/Samara | 14 +- library/tzdata/Europe/Simferopol | 174 +---------- library/tzdata/Europe/Volgograd | 79 ++--- library/tzdata/Pacific/Apia | 188 ++++++------ library/tzdata/Pacific/Chatham | 3 +- library/tzdata/Pacific/Fiji | 172 +++++------ library/tzdata/Pacific/Pago_Pago | 3 +- library/tzdata/SystemV/AST4 | 5 - library/tzdata/SystemV/AST4ADT | 5 - library/tzdata/SystemV/CST6 | 5 - library/tzdata/SystemV/CST6CDT | 5 - library/tzdata/SystemV/EST5 | 5 - library/tzdata/SystemV/EST5EDT | 5 - library/tzdata/SystemV/HST10 | 5 - library/tzdata/SystemV/MST7 | 5 - library/tzdata/SystemV/MST7MDT | 5 - library/tzdata/SystemV/PST8 | 5 - library/tzdata/SystemV/PST8PDT | 5 - library/tzdata/SystemV/YST9 | 5 - library/tzdata/SystemV/YST9YDT | 5 - 91 files changed, 3044 insertions(+), 2874 deletions(-) delete mode 100644 library/tzdata/SystemV/AST4 delete mode 100644 library/tzdata/SystemV/AST4ADT delete mode 100644 library/tzdata/SystemV/CST6 delete mode 100644 library/tzdata/SystemV/CST6CDT delete mode 100644 library/tzdata/SystemV/EST5 delete mode 100644 library/tzdata/SystemV/EST5EDT delete mode 100644 library/tzdata/SystemV/HST10 delete mode 100644 library/tzdata/SystemV/MST7 delete mode 100644 library/tzdata/SystemV/MST7MDT delete mode 100644 library/tzdata/SystemV/PST8 delete mode 100644 library/tzdata/SystemV/PST8PDT delete mode 100644 library/tzdata/SystemV/YST9 delete mode 100644 library/tzdata/SystemV/YST9YDT diff --git a/library/tzdata/Africa/Accra b/library/tzdata/Africa/Accra index faf58fb..39db976 100644 --- a/library/tzdata/Africa/Accra +++ b/library/tzdata/Africa/Accra @@ -3,6 +3,38 @@ set TZData(:Africa/Accra) { {-9223372036854775808 -52 0 LMT} {-1640995148 0 0 GMT} + {-1556841600 1200 1 GHST} + {-1546388400 0 0 GMT} + {-1525305600 1200 1 GHST} + {-1514852400 0 0 GMT} + {-1493769600 1200 1 GHST} + {-1483316400 0 0 GMT} + {-1462233600 1200 1 GHST} + {-1451780400 0 0 GMT} + {-1430611200 1200 1 GHST} + {-1420158000 0 0 GMT} + {-1399075200 1200 1 GHST} + {-1388622000 0 0 GMT} + {-1367539200 1200 1 GHST} + {-1357086000 0 0 GMT} + {-1336003200 1200 1 GHST} + {-1325550000 0 0 GMT} + {-1304380800 1200 1 GHST} + {-1293927600 0 0 GMT} + {-1272844800 1200 1 GHST} + {-1262391600 0 0 GMT} + {-1241308800 1200 1 GHST} + {-1230855600 0 0 GMT} + {-1209772800 1200 1 GHST} + {-1199319600 0 0 GMT} + {-1178150400 1200 1 GHST} + {-1167697200 0 0 GMT} + {-1146614400 1200 1 GHST} + {-1136161200 0 0 GMT} + {-1115078400 1200 1 GHST} + {-1104625200 0 0 GMT} + {-1083542400 1200 1 GHST} + {-1073089200 0 0 GMT} {-1051920000 1200 1 GHST} {-1041466800 0 0 GMT} {-1020384000 1200 1 GHST} diff --git a/library/tzdata/Africa/Bamako b/library/tzdata/Africa/Bamako index 7ed62e0..0818378 100644 --- a/library/tzdata/Africa/Bamako +++ b/library/tzdata/Africa/Bamako @@ -1,8 +1,5 @@ # created by tools/tclZIC.tcl - do not edit - -set TZData(:Africa/Bamako) { - {-9223372036854775808 -1920 0 LMT} - {-1830382080 0 0 GMT} - {-1131235200 -3600 0 WAT} - {-300841200 0 0 GMT} +if {![info exists TZData(Africa/Abidjan)]} { + LoadTimeZoneFile Africa/Abidjan } +set TZData(:Africa/Bamako) $TZData(:Africa/Abidjan) diff --git a/library/tzdata/Africa/Banjul b/library/tzdata/Africa/Banjul index a7f0168..ded0e57 100644 --- a/library/tzdata/Africa/Banjul +++ b/library/tzdata/Africa/Banjul @@ -1,8 +1,5 @@ # created by tools/tclZIC.tcl - do not edit - -set TZData(:Africa/Banjul) { - {-9223372036854775808 -3996 0 LMT} - {-1830380004 -3996 0 BMT} - {-1104533604 -3600 0 WAT} - {-189385200 0 0 GMT} +if {![info exists TZData(Africa/Abidjan)]} { + LoadTimeZoneFile Africa/Abidjan } +set TZData(:Africa/Banjul) $TZData(:Africa/Abidjan) diff --git a/library/tzdata/Africa/Cairo b/library/tzdata/Africa/Cairo index 842b7b2..f453da2 100644 --- a/library/tzdata/Africa/Cairo +++ b/library/tzdata/Africa/Cairo @@ -125,4 +125,188 @@ set TZData(:Africa/Cairo) { {1281474000 7200 0 EET} {1284069600 10800 1 EEST} {1285880400 7200 0 EET} + {1400191200 10800 1 EEST} + {1403816400 7200 0 EET} + {1406844000 10800 1 EEST} + {1411678800 7200 0 EET} + {1429826400 10800 1 EEST} + {1434056400 7200 0 EET} + {1437688800 10800 1 EEST} + {1443128400 7200 0 EET} + {1461880800 10800 1 EEST} + {1464901200 7200 0 EET} + {1467928800 10800 1 EEST} + {1475182800 7200 0 EET} + {1493330400 10800 1 EEST} + {1495746000 7200 0 EET} + {1498773600 10800 1 EEST} + {1506632400 7200 0 EET} + {1524780000 10800 1 EEST} + {1525986000 7200 0 EET} + {1529013600 10800 1 EEST} + {1538082000 7200 0 EET} + {1556229600 10800 1 EEST} + {1556830800 7200 0 EET} + {1559858400 10800 1 EEST} + {1569531600 7200 0 EET} + {1590703200 10800 1 EEST} + {1600981200 7200 0 EET} + {1620943200 10800 1 EEST} + {1633035600 7200 0 EET} + {1651788000 10800 1 EEST} + {1664485200 7200 0 EET} + {1682632800 10800 1 EEST} + {1695934800 7200 0 EET} + {1714082400 10800 1 EEST} + {1727384400 7200 0 EET} + {1745532000 10800 1 EEST} + {1758834000 7200 0 EET} + {1776981600 10800 1 EEST} + {1790283600 7200 0 EET} + {1809036000 10800 1 EEST} + {1822338000 7200 0 EET} + {1840485600 10800 1 EEST} + {1853787600 7200 0 EET} + {1871935200 10800 1 EEST} + {1885237200 7200 0 EET} + {1903384800 10800 1 EEST} + {1916686800 7200 0 EET} + {1934834400 10800 1 EEST} + {1948136400 7200 0 EET} + {1966888800 10800 1 EEST} + {1980190800 7200 0 EET} + {1998338400 10800 1 EEST} + {2011640400 7200 0 EET} + {2029788000 10800 1 EEST} + {2043090000 7200 0 EET} + {2061237600 10800 1 EEST} + {2074539600 7200 0 EET} + {2092687200 10800 1 EEST} + {2105989200 7200 0 EET} + {2124136800 10800 1 EEST} + {2137438800 7200 0 EET} + {2156191200 10800 1 EEST} + {2169493200 7200 0 EET} + {2187640800 10800 1 EEST} + {2200942800 7200 0 EET} + {2219090400 10800 1 EEST} + {2232392400 7200 0 EET} + {2250540000 10800 1 EEST} + {2263842000 7200 0 EET} + {2281989600 10800 1 EEST} + {2295291600 7200 0 EET} + {2313439200 10800 1 EEST} + {2326741200 7200 0 EET} + {2345493600 10800 1 EEST} + {2358795600 7200 0 EET} + {2376943200 10800 1 EEST} + {2390245200 7200 0 EET} + {2408392800 10800 1 EEST} + {2421694800 7200 0 EET} + {2439842400 10800 1 EEST} + {2453144400 7200 0 EET} + {2471292000 10800 1 EEST} + {2484594000 7200 0 EET} + {2503346400 10800 1 EEST} + {2516648400 7200 0 EET} + {2534796000 10800 1 EEST} + {2548098000 7200 0 EET} + {2566245600 10800 1 EEST} + {2579547600 7200 0 EET} + {2597695200 10800 1 EEST} + {2610997200 7200 0 EET} + {2629144800 10800 1 EEST} + {2642446800 7200 0 EET} + {2660594400 10800 1 EEST} + {2673896400 7200 0 EET} + {2692648800 10800 1 EEST} + {2705950800 7200 0 EET} + {2724098400 10800 1 EEST} + {2737400400 7200 0 EET} + {2755548000 10800 1 EEST} + {2768850000 7200 0 EET} + {2786997600 10800 1 EEST} + {2800299600 7200 0 EET} + {2818447200 10800 1 EEST} + {2831749200 7200 0 EET} + {2850501600 10800 1 EEST} + {2863803600 7200 0 EET} + {2881951200 10800 1 EEST} + {2895253200 7200 0 EET} + {2913400800 10800 1 EEST} + {2926702800 7200 0 EET} + {2944850400 10800 1 EEST} + {2958152400 7200 0 EET} + {2976300000 10800 1 EEST} + {2989602000 7200 0 EET} + {3007749600 10800 1 EEST} + {3021051600 7200 0 EET} + {3039804000 10800 1 EEST} + {3053106000 7200 0 EET} + {3071253600 10800 1 EEST} + {3084555600 7200 0 EET} + {3102703200 10800 1 EEST} + {3116005200 7200 0 EET} + {3134152800 10800 1 EEST} + {3147454800 7200 0 EET} + {3165602400 10800 1 EEST} + {3178904400 7200 0 EET} + {3197052000 10800 1 EEST} + {3210354000 7200 0 EET} + {3229106400 10800 1 EEST} + {3242408400 7200 0 EET} + {3260556000 10800 1 EEST} + {3273858000 7200 0 EET} + {3292005600 10800 1 EEST} + {3305307600 7200 0 EET} + {3323455200 10800 1 EEST} + {3336757200 7200 0 EET} + {3354904800 10800 1 EEST} + {3368206800 7200 0 EET} + {3386959200 10800 1 EEST} + {3400261200 7200 0 EET} + {3418408800 10800 1 EEST} + {3431710800 7200 0 EET} + {3449858400 10800 1 EEST} + {3463160400 7200 0 EET} + {3481308000 10800 1 EEST} + {3494610000 7200 0 EET} + {3512757600 10800 1 EEST} + {3526059600 7200 0 EET} + {3544207200 10800 1 EEST} + {3557509200 7200 0 EET} + {3576261600 10800 1 EEST} + {3589563600 7200 0 EET} + {3607711200 10800 1 EEST} + {3621013200 7200 0 EET} + {3639160800 10800 1 EEST} + {3652462800 7200 0 EET} + {3670610400 10800 1 EEST} + {3683912400 7200 0 EET} + {3702060000 10800 1 EEST} + {3715362000 7200 0 EET} + {3734114400 10800 1 EEST} + {3747416400 7200 0 EET} + {3765564000 10800 1 EEST} + {3778866000 7200 0 EET} + {3797013600 10800 1 EEST} + {3810315600 7200 0 EET} + {3828463200 10800 1 EEST} + {3841765200 7200 0 EET} + {3859912800 10800 1 EEST} + {3873214800 7200 0 EET} + {3891362400 10800 1 EEST} + {3904664400 7200 0 EET} + {3923416800 10800 1 EEST} + {3936718800 7200 0 EET} + {3954866400 10800 1 EEST} + {3968168400 7200 0 EET} + {3986316000 10800 1 EEST} + {3999618000 7200 0 EET} + {4017765600 10800 1 EEST} + {4031067600 7200 0 EET} + {4049215200 10800 1 EEST} + {4062517200 7200 0 EET} + {4080664800 10800 1 EEST} + {4093966800 7200 0 EET} } diff --git a/library/tzdata/Africa/Casablanca b/library/tzdata/Africa/Casablanca index dec2778..224e5c2 100644 --- a/library/tzdata/Africa/Casablanca +++ b/library/tzdata/Africa/Casablanca @@ -38,46 +38,46 @@ set TZData(:Africa/Casablanca) { {1376100000 3600 1 WEST} {1382839200 0 0 WET} {1396144800 3600 1 WEST} - {1404007200 0 0 WET} - {1406599200 3600 1 WEST} + {1403920800 0 0 WET} + {1406944800 3600 1 WEST} {1414288800 0 0 WET} {1427594400 3600 1 WEST} - {1434592800 0 0 WET} + {1434160800 0 0 WET} {1437184800 3600 1 WEST} {1445738400 0 0 WET} {1459044000 3600 1 WEST} - {1465264800 0 0 WET} - {1467856800 3600 1 WEST} + {1465005600 0 0 WET} + {1468029600 3600 1 WEST} {1477792800 0 0 WET} {1490493600 3600 1 WEST} - {1495850400 0 0 WET} - {1498442400 3600 1 WEST} + {1495245600 0 0 WET} + {1498874400 3600 1 WEST} {1509242400 0 0 WET} {1521943200 3600 1 WEST} - {1526436000 0 0 WET} - {1529028000 3600 1 WEST} + {1526090400 0 0 WET} + {1529114400 3600 1 WEST} {1540692000 0 0 WET} {1553997600 3600 1 WEST} - {1557108000 0 0 WET} - {1559700000 3600 1 WEST} + {1556935200 0 0 WET} + {1559959200 3600 1 WEST} {1572141600 0 0 WET} {1585447200 3600 1 WEST} - {1587693600 0 0 WET} - {1590285600 3600 1 WEST} + {1587175200 0 0 WET} + {1590804000 3600 1 WEST} {1603591200 0 0 WET} {1616896800 3600 1 WEST} - {1618279200 0 0 WET} - {1620871200 3600 1 WEST} + {1618020000 0 0 WET} + {1621044000 3600 1 WEST} {1635645600 0 0 WET} {1648346400 3600 1 WEST} - {1648951200 0 0 WET} - {1651543200 3600 1 WEST} + {1648864800 0 0 WET} + {1651888800 3600 1 WEST} {1667095200 0 0 WET} {1682128800 3600 1 WEST} {1698544800 0 0 WET} - {1712714400 3600 1 WEST} + {1712973600 3600 1 WEST} {1729994400 0 0 WET} - {1743386400 3600 1 WEST} + {1743818400 3600 1 WEST} {1761444000 0 0 WET} {1774749600 3600 1 WEST} {1792893600 0 0 WET} @@ -98,71 +98,136 @@ set TZData(:Africa/Casablanca) { {2026951200 3600 1 WEST} {2045700000 0 0 WET} {2058400800 3600 1 WEST} - {2077149600 0 0 WET} + {2077063200 0 0 WET} + {2077153200 0 0 WET} {2090455200 3600 1 WEST} - {2108167200 0 0 WET} + {2107908000 0 0 WET} + {2108602800 0 0 WET} {2121904800 3600 1 WEST} - {2138839200 0 0 WET} + {2138752800 0 0 WET} + {2140052400 0 0 WET} {2153354400 3600 1 WEST} - {2184800400 3600 1 WEST} - {2216250000 3600 1 WEST} - {2248304400 3600 1 WEST} - {2279754000 3600 1 WEST} - {2311203600 3600 1 WEST} - {2342653200 3600 1 WEST} - {2374102800 3600 1 WEST} - {2405552400 3600 1 WEST} - {2437606800 3600 1 WEST} - {2469056400 3600 1 WEST} - {2500506000 3600 1 WEST} - {2531955600 3600 1 WEST} - {2563405200 3600 1 WEST} - {2595459600 3600 1 WEST} - {2626909200 3600 1 WEST} - {2658358800 3600 1 WEST} - {2689808400 3600 1 WEST} - {2721258000 3600 1 WEST} - {2752707600 3600 1 WEST} - {2784762000 3600 1 WEST} - {2816211600 3600 1 WEST} - {2847661200 3600 1 WEST} - {2879110800 3600 1 WEST} - {2910560400 3600 1 WEST} - {2942010000 3600 1 WEST} - {2974064400 3600 1 WEST} - {3005514000 3600 1 WEST} - {3036963600 3600 1 WEST} - {3068413200 3600 1 WEST} - {3099862800 3600 1 WEST} - {3131917200 3600 1 WEST} - {3163366800 3600 1 WEST} - {3194816400 3600 1 WEST} - {3226266000 3600 1 WEST} - {3257715600 3600 1 WEST} - {3289165200 3600 1 WEST} - {3321219600 3600 1 WEST} - {3352669200 3600 1 WEST} - {3384118800 3600 1 WEST} - {3415568400 3600 1 WEST} - {3447018000 3600 1 WEST} - {3479072400 3600 1 WEST} - {3510522000 3600 1 WEST} - {3541971600 3600 1 WEST} - {3573421200 3600 1 WEST} - {3604870800 3600 1 WEST} - {3636320400 3600 1 WEST} - {3668374800 3600 1 WEST} - {3699824400 3600 1 WEST} - {3731274000 3600 1 WEST} - {3762723600 3600 1 WEST} - {3794173200 3600 1 WEST} - {3825622800 3600 1 WEST} - {3857677200 3600 1 WEST} - {3889126800 3600 1 WEST} - {3920576400 3600 1 WEST} - {3952026000 3600 1 WEST} - {3983475600 3600 1 WEST} - {4015530000 3600 1 WEST} - {4046979600 3600 1 WEST} - {4078429200 3600 1 WEST} + {2172103200 0 0 WET} + {2184804000 3600 1 WEST} + {2203552800 0 0 WET} + {2216253600 3600 1 WEST} + {2235002400 0 0 WET} + {2248308000 3600 1 WEST} + {2266452000 0 0 WET} + {2279757600 3600 1 WEST} + {2297901600 0 0 WET} + {2311207200 3600 1 WEST} + {2329351200 0 0 WET} + {2342656800 3600 1 WEST} + {2361405600 0 0 WET} + {2374106400 3600 1 WEST} + {2392855200 0 0 WET} + {2405556000 3600 1 WEST} + {2424304800 0 0 WET} + {2437610400 3600 1 WEST} + {2455754400 0 0 WET} + {2469060000 3600 1 WEST} + {2487204000 0 0 WET} + {2500509600 3600 1 WEST} + {2519258400 0 0 WET} + {2531959200 3600 1 WEST} + {2550708000 0 0 WET} + {2563408800 3600 1 WEST} + {2582157600 0 0 WET} + {2595463200 3600 1 WEST} + {2613607200 0 0 WET} + {2626912800 3600 1 WEST} + {2645056800 0 0 WET} + {2658362400 3600 1 WEST} + {2676506400 0 0 WET} + {2689812000 3600 1 WEST} + {2708560800 0 0 WET} + {2721261600 3600 1 WEST} + {2740010400 0 0 WET} + {2752711200 3600 1 WEST} + {2771460000 0 0 WET} + {2784765600 3600 1 WEST} + {2802909600 0 0 WET} + {2816215200 3600 1 WEST} + {2834359200 0 0 WET} + {2847664800 3600 1 WEST} + {2866413600 0 0 WET} + {2879114400 3600 1 WEST} + {2897863200 0 0 WET} + {2910564000 3600 1 WEST} + {2929312800 0 0 WET} + {2942013600 3600 1 WEST} + {2960762400 0 0 WET} + {2974068000 3600 1 WEST} + {2992212000 0 0 WET} + {3005517600 3600 1 WEST} + {3023661600 0 0 WET} + {3036967200 3600 1 WEST} + {3055716000 0 0 WET} + {3068416800 3600 1 WEST} + {3087165600 0 0 WET} + {3099866400 3600 1 WEST} + {3118615200 0 0 WET} + {3131920800 3600 1 WEST} + {3150064800 0 0 WET} + {3163370400 3600 1 WEST} + {3181514400 0 0 WET} + {3194820000 3600 1 WEST} + {3212964000 0 0 WET} + {3226269600 3600 1 WEST} + {3245018400 0 0 WET} + {3257719200 3600 1 WEST} + {3276468000 0 0 WET} + {3289168800 3600 1 WEST} + {3307917600 0 0 WET} + {3321223200 3600 1 WEST} + {3339367200 0 0 WET} + {3352672800 3600 1 WEST} + {3370816800 0 0 WET} + {3384122400 3600 1 WEST} + {3402871200 0 0 WET} + {3415572000 3600 1 WEST} + {3434320800 0 0 WET} + {3447021600 3600 1 WEST} + {3465770400 0 0 WET} + {3479076000 3600 1 WEST} + {3497220000 0 0 WET} + {3510525600 3600 1 WEST} + {3528669600 0 0 WET} + {3541975200 3600 1 WEST} + {3560119200 0 0 WET} + {3573424800 3600 1 WEST} + {3592173600 0 0 WET} + {3604874400 3600 1 WEST} + {3623623200 0 0 WET} + {3636324000 3600 1 WEST} + {3655072800 0 0 WET} + {3668378400 3600 1 WEST} + {3686522400 0 0 WET} + {3699828000 3600 1 WEST} + {3717972000 0 0 WET} + {3731277600 3600 1 WEST} + {3750026400 0 0 WET} + {3762727200 3600 1 WEST} + {3781476000 0 0 WET} + {3794176800 3600 1 WEST} + {3812925600 0 0 WET} + {3825626400 3600 1 WEST} + {3844375200 0 0 WET} + {3857680800 3600 1 WEST} + {3875824800 0 0 WET} + {3889130400 3600 1 WEST} + {3907274400 0 0 WET} + {3920580000 3600 1 WEST} + {3939328800 0 0 WET} + {3952029600 3600 1 WEST} + {3970778400 0 0 WET} + {3983479200 3600 1 WEST} + {4002228000 0 0 WET} + {4015533600 3600 1 WEST} + {4033677600 0 0 WET} + {4046983200 3600 1 WEST} + {4065127200 0 0 WET} + {4078432800 3600 1 WEST} + {4096576800 0 0 WET} } diff --git a/library/tzdata/Africa/Conakry b/library/tzdata/Africa/Conakry index d17ce4b..4373720 100644 --- a/library/tzdata/Africa/Conakry +++ b/library/tzdata/Africa/Conakry @@ -1,8 +1,5 @@ # created by tools/tclZIC.tcl - do not edit - -set TZData(:Africa/Conakry) { - {-9223372036854775808 -3292 0 LMT} - {-1830380708 0 0 GMT} - {-1131235200 -3600 0 WAT} - {-315615600 0 0 GMT} +if {![info exists TZData(Africa/Abidjan)]} { + LoadTimeZoneFile Africa/Abidjan } +set TZData(:Africa/Conakry) $TZData(:Africa/Abidjan) diff --git a/library/tzdata/Africa/Dakar b/library/tzdata/Africa/Dakar index 487dc62..78e800c 100644 --- a/library/tzdata/Africa/Dakar +++ b/library/tzdata/Africa/Dakar @@ -1,7 +1,5 @@ # created by tools/tclZIC.tcl - do not edit - -set TZData(:Africa/Dakar) { - {-9223372036854775808 -4184 0 LMT} - {-1830379816 -3600 0 WAT} - {-902098800 0 0 GMT} +if {![info exists TZData(Africa/Abidjan)]} { + LoadTimeZoneFile Africa/Abidjan } +set TZData(:Africa/Dakar) $TZData(:Africa/Abidjan) diff --git a/library/tzdata/Africa/El_Aaiun b/library/tzdata/Africa/El_Aaiun index a8b9d34..3a5c934 100644 --- a/library/tzdata/Africa/El_Aaiun +++ b/library/tzdata/Africa/El_Aaiun @@ -4,4 +4,219 @@ set TZData(:Africa/El_Aaiun) { {-9223372036854775808 -3168 0 LMT} {-1136070432 -3600 0 WAT} {198291600 0 0 WET} + {199756800 3600 1 WEST} + {207702000 0 0 WET} + {231292800 3600 1 WEST} + {244249200 0 0 WET} + {265507200 3600 1 WEST} + {271033200 0 0 WET} + {1212278400 3600 1 WEST} + {1220223600 0 0 WET} + {1243814400 3600 1 WEST} + {1250809200 0 0 WET} + {1272758400 3600 1 WEST} + {1281222000 0 0 WET} + {1301788800 3600 1 WEST} + {1312066800 0 0 WET} + {1335664800 3600 1 WEST} + {1342749600 0 0 WET} + {1345428000 3600 1 WEST} + {1348970400 0 0 WET} + {1367114400 3600 1 WEST} + {1373162400 0 0 WET} + {1376100000 3600 1 WEST} + {1382839200 0 0 WET} + {1396144800 3600 1 WEST} + {1403920800 0 0 WET} + {1406944800 3600 1 WEST} + {1414288800 0 0 WET} + {1427594400 3600 1 WEST} + {1434160800 0 0 WET} + {1437184800 3600 1 WEST} + {1445738400 0 0 WET} + {1459044000 3600 1 WEST} + {1465005600 0 0 WET} + {1468029600 3600 1 WEST} + {1477792800 0 0 WET} + {1490493600 3600 1 WEST} + {1495245600 0 0 WET} + {1498874400 3600 1 WEST} + {1509242400 0 0 WET} + {1521943200 3600 1 WEST} + {1526090400 0 0 WET} + {1529114400 3600 1 WEST} + {1540692000 0 0 WET} + {1553997600 3600 1 WEST} + {1556935200 0 0 WET} + {1559959200 3600 1 WEST} + {1572141600 0 0 WET} + {1585447200 3600 1 WEST} + {1587175200 0 0 WET} + {1590804000 3600 1 WEST} + {1603591200 0 0 WET} + {1616896800 3600 1 WEST} + {1618020000 0 0 WET} + {1621044000 3600 1 WEST} + {1635645600 0 0 WET} + {1648346400 3600 1 WEST} + {1648864800 0 0 WET} + {1651888800 3600 1 WEST} + {1667095200 0 0 WET} + {1682128800 3600 1 WEST} + {1698544800 0 0 WET} + {1712973600 3600 1 WEST} + {1729994400 0 0 WET} + {1743818400 3600 1 WEST} + {1761444000 0 0 WET} + {1774749600 3600 1 WEST} + {1792893600 0 0 WET} + {1806199200 3600 1 WEST} + {1824948000 0 0 WET} + {1837648800 3600 1 WEST} + {1856397600 0 0 WET} + {1869098400 3600 1 WEST} + {1887847200 0 0 WET} + {1901152800 3600 1 WEST} + {1919296800 0 0 WET} + {1932602400 3600 1 WEST} + {1950746400 0 0 WET} + {1964052000 3600 1 WEST} + {1982800800 0 0 WET} + {1995501600 3600 1 WEST} + {2014250400 0 0 WET} + {2026951200 3600 1 WEST} + {2045700000 0 0 WET} + {2058400800 3600 1 WEST} + {2077063200 0 0 WET} + {2077153200 0 0 WET} + {2090455200 3600 1 WEST} + {2107908000 0 0 WET} + {2108602800 0 0 WET} + {2121904800 3600 1 WEST} + {2138752800 0 0 WET} + {2140052400 0 0 WET} + {2153354400 3600 1 WEST} + {2172103200 0 0 WET} + {2184804000 3600 1 WEST} + {2203552800 0 0 WET} + {2216253600 3600 1 WEST} + {2235002400 0 0 WET} + {2248308000 3600 1 WEST} + {2266452000 0 0 WET} + {2279757600 3600 1 WEST} + {2297901600 0 0 WET} + {2311207200 3600 1 WEST} + {2329351200 0 0 WET} + {2342656800 3600 1 WEST} + {2361405600 0 0 WET} + {2374106400 3600 1 WEST} + {2392855200 0 0 WET} + {2405556000 3600 1 WEST} + {2424304800 0 0 WET} + {2437610400 3600 1 WEST} + {2455754400 0 0 WET} + {2469060000 3600 1 WEST} + {2487204000 0 0 WET} + {2500509600 3600 1 WEST} + {2519258400 0 0 WET} + {2531959200 3600 1 WEST} + {2550708000 0 0 WET} + {2563408800 3600 1 WEST} + {2582157600 0 0 WET} + {2595463200 3600 1 WEST} + {2613607200 0 0 WET} + {2626912800 3600 1 WEST} + {2645056800 0 0 WET} + {2658362400 3600 1 WEST} + {2676506400 0 0 WET} + {2689812000 3600 1 WEST} + {2708560800 0 0 WET} + {2721261600 3600 1 WEST} + {2740010400 0 0 WET} + {2752711200 3600 1 WEST} + {2771460000 0 0 WET} + {2784765600 3600 1 WEST} + {2802909600 0 0 WET} + {2816215200 3600 1 WEST} + {2834359200 0 0 WET} + {2847664800 3600 1 WEST} + {2866413600 0 0 WET} + {2879114400 3600 1 WEST} + {2897863200 0 0 WET} + {2910564000 3600 1 WEST} + {2929312800 0 0 WET} + {2942013600 3600 1 WEST} + {2960762400 0 0 WET} + {2974068000 3600 1 WEST} + {2992212000 0 0 WET} + {3005517600 3600 1 WEST} + {3023661600 0 0 WET} + {3036967200 3600 1 WEST} + {3055716000 0 0 WET} + {3068416800 3600 1 WEST} + {3087165600 0 0 WET} + {3099866400 3600 1 WEST} + {3118615200 0 0 WET} + {3131920800 3600 1 WEST} + {3150064800 0 0 WET} + {3163370400 3600 1 WEST} + {3181514400 0 0 WET} + {3194820000 3600 1 WEST} + {3212964000 0 0 WET} + {3226269600 3600 1 WEST} + {3245018400 0 0 WET} + {3257719200 3600 1 WEST} + {3276468000 0 0 WET} + {3289168800 3600 1 WEST} + {3307917600 0 0 WET} + {3321223200 3600 1 WEST} + {3339367200 0 0 WET} + {3352672800 3600 1 WEST} + {3370816800 0 0 WET} + {3384122400 3600 1 WEST} + {3402871200 0 0 WET} + {3415572000 3600 1 WEST} + {3434320800 0 0 WET} + {3447021600 3600 1 WEST} + {3465770400 0 0 WET} + {3479076000 3600 1 WEST} + {3497220000 0 0 WET} + {3510525600 3600 1 WEST} + {3528669600 0 0 WET} + {3541975200 3600 1 WEST} + {3560119200 0 0 WET} + {3573424800 3600 1 WEST} + {3592173600 0 0 WET} + {3604874400 3600 1 WEST} + {3623623200 0 0 WET} + {3636324000 3600 1 WEST} + {3655072800 0 0 WET} + {3668378400 3600 1 WEST} + {3686522400 0 0 WET} + {3699828000 3600 1 WEST} + {3717972000 0 0 WET} + {3731277600 3600 1 WEST} + {3750026400 0 0 WET} + {3762727200 3600 1 WEST} + {3781476000 0 0 WET} + {3794176800 3600 1 WEST} + {3812925600 0 0 WET} + {3825626400 3600 1 WEST} + {3844375200 0 0 WET} + {3857680800 3600 1 WEST} + {3875824800 0 0 WET} + {3889130400 3600 1 WEST} + {3907274400 0 0 WET} + {3920580000 3600 1 WEST} + {3939328800 0 0 WET} + {3952029600 3600 1 WEST} + {3970778400 0 0 WET} + {3983479200 3600 1 WEST} + {4002228000 0 0 WET} + {4015533600 3600 1 WEST} + {4033677600 0 0 WET} + {4046983200 3600 1 WEST} + {4065127200 0 0 WET} + {4078432800 3600 1 WEST} + {4096576800 0 0 WET} } diff --git a/library/tzdata/Africa/Freetown b/library/tzdata/Africa/Freetown index c3f2d2e..4a8e2e1 100644 --- a/library/tzdata/Africa/Freetown +++ b/library/tzdata/Africa/Freetown @@ -1,36 +1,5 @@ # created by tools/tclZIC.tcl - do not edit - -set TZData(:Africa/Freetown) { - {-9223372036854775808 -3180 0 LMT} - {-2776979220 -3180 0 FMT} - {-1785712020 -3600 0 WAT} - {-1091487600 -1200 1 SLST} - {-1080949200 -3600 0 WAT} - {-1059865200 -1200 1 SLST} - {-1049326800 -3600 0 WAT} - {-1028329200 -1200 1 SLST} - {-1017790800 -3600 0 WAT} - {-996793200 -1200 1 SLST} - {-986254800 -3600 0 WAT} - {-965257200 -1200 1 SLST} - {-954718800 -3600 0 WAT} - {-933634800 -1200 1 SLST} - {-923096400 -3600 0 WAT} - {-902098800 -1200 1 SLST} - {-891560400 -3600 0 WAT} - {-870562800 -1200 1 SLST} - {-860024400 -3600 0 WAT} - {-410223600 0 0 WAT} - {-397180800 3600 1 SLST} - {-389235600 0 0 GMT} - {-365644800 3600 1 SLST} - {-357699600 0 0 GMT} - {-334108800 3600 1 SLST} - {-326163600 0 0 GMT} - {-302486400 3600 1 SLST} - {-294541200 0 0 GMT} - {-270950400 3600 1 SLST} - {-263005200 0 0 GMT} - {-239414400 3600 1 SLST} - {-231469200 0 0 GMT} +if {![info exists TZData(Africa/Abidjan)]} { + LoadTimeZoneFile Africa/Abidjan } +set TZData(:Africa/Freetown) $TZData(:Africa/Abidjan) diff --git a/library/tzdata/Africa/Lome b/library/tzdata/Africa/Lome index 606625c..9adecc7 100644 --- a/library/tzdata/Africa/Lome +++ b/library/tzdata/Africa/Lome @@ -1,6 +1,5 @@ # created by tools/tclZIC.tcl - do not edit - -set TZData(:Africa/Lome) { - {-9223372036854775808 292 0 LMT} - {-2429827492 0 0 GMT} +if {![info exists TZData(Africa/Abidjan)]} { + LoadTimeZoneFile Africa/Abidjan } +set TZData(:Africa/Lome) $TZData(:Africa/Abidjan) diff --git a/library/tzdata/Africa/Nouakchott b/library/tzdata/Africa/Nouakchott index f7369d0..d33b6bc 100644 --- a/library/tzdata/Africa/Nouakchott +++ b/library/tzdata/Africa/Nouakchott @@ -1,8 +1,5 @@ # created by tools/tclZIC.tcl - do not edit - -set TZData(:Africa/Nouakchott) { - {-9223372036854775808 -3828 0 LMT} - {-1830380172 0 0 GMT} - {-1131235200 -3600 0 WAT} - {-286930800 0 0 GMT} +if {![info exists TZData(Africa/Abidjan)]} { + LoadTimeZoneFile Africa/Abidjan } +set TZData(:Africa/Nouakchott) $TZData(:Africa/Abidjan) diff --git a/library/tzdata/Africa/Ouagadougou b/library/tzdata/Africa/Ouagadougou index 88a7145..8178c82 100644 --- a/library/tzdata/Africa/Ouagadougou +++ b/library/tzdata/Africa/Ouagadougou @@ -1,6 +1,5 @@ # created by tools/tclZIC.tcl - do not edit - -set TZData(:Africa/Ouagadougou) { - {-9223372036854775808 -364 0 LMT} - {-1830383636 0 0 GMT} +if {![info exists TZData(Africa/Abidjan)]} { + LoadTimeZoneFile Africa/Abidjan } +set TZData(:Africa/Ouagadougou) $TZData(:Africa/Abidjan) diff --git a/library/tzdata/Africa/Sao_Tome b/library/tzdata/Africa/Sao_Tome index ab1590d..078591d 100644 --- a/library/tzdata/Africa/Sao_Tome +++ b/library/tzdata/Africa/Sao_Tome @@ -1,7 +1,5 @@ # created by tools/tclZIC.tcl - do not edit - -set TZData(:Africa/Sao_Tome) { - {-9223372036854775808 1616 0 LMT} - {-2713912016 -2192 0 LMT} - {-1830381808 0 0 GMT} +if {![info exists TZData(Africa/Abidjan)]} { + LoadTimeZoneFile Africa/Abidjan } +set TZData(:Africa/Sao_Tome) $TZData(:Africa/Abidjan) diff --git a/library/tzdata/Africa/Timbuktu b/library/tzdata/Africa/Timbuktu index 8057eed..9852d7a 100644 --- a/library/tzdata/Africa/Timbuktu +++ b/library/tzdata/Africa/Timbuktu @@ -1,5 +1,5 @@ # created by tools/tclZIC.tcl - do not edit -if {![info exists TZData(Africa/Bamako)]} { - LoadTimeZoneFile Africa/Bamako +if {![info exists TZData(Africa/Abidjan)]} { + LoadTimeZoneFile Africa/Abidjan } -set TZData(:Africa/Timbuktu) $TZData(:Africa/Bamako) +set TZData(:Africa/Timbuktu) $TZData(:Africa/Abidjan) diff --git a/library/tzdata/Africa/Tripoli b/library/tzdata/Africa/Tripoli index ac78218..0e72df4 100644 --- a/library/tzdata/Africa/Tripoli +++ b/library/tzdata/Africa/Tripoli @@ -30,177 +30,5 @@ set TZData(:Africa/Tripoli) { {875919600 7200 0 EET} {1352505600 3600 0 CET} {1364515200 7200 1 CEST} - {1382659200 3600 0 CET} - {1395964800 7200 1 CEST} - {1414713600 3600 0 CET} - {1427414400 7200 1 CEST} - {1446163200 3600 0 CET} - {1458864000 7200 1 CEST} - {1477612800 3600 0 CET} - {1490918400 7200 1 CEST} - {1509062400 3600 0 CET} - {1522368000 7200 1 CEST} - {1540512000 3600 0 CET} - {1553817600 7200 1 CEST} - {1571961600 3600 0 CET} - {1585267200 7200 1 CEST} - {1604016000 3600 0 CET} - {1616716800 7200 1 CEST} - {1635465600 3600 0 CET} - {1648166400 7200 1 CEST} - {1666915200 3600 0 CET} - {1680220800 7200 1 CEST} - {1698364800 3600 0 CET} - {1711670400 7200 1 CEST} - {1729814400 3600 0 CET} - {1743120000 7200 1 CEST} - {1761868800 3600 0 CET} - {1774569600 7200 1 CEST} - {1793318400 3600 0 CET} - {1806019200 7200 1 CEST} - {1824768000 3600 0 CET} - {1838073600 7200 1 CEST} - {1856217600 3600 0 CET} - {1869523200 7200 1 CEST} - {1887667200 3600 0 CET} - {1900972800 7200 1 CEST} - {1919116800 3600 0 CET} - {1932422400 7200 1 CEST} - {1951171200 3600 0 CET} - {1963872000 7200 1 CEST} - {1982620800 3600 0 CET} - {1995321600 7200 1 CEST} - {2014070400 3600 0 CET} - {2027376000 7200 1 CEST} - {2045520000 3600 0 CET} - {2058825600 7200 1 CEST} - {2076969600 3600 0 CET} - {2090275200 7200 1 CEST} - {2109024000 3600 0 CET} - {2121724800 7200 1 CEST} - {2140473600 3600 0 CET} - {2153174400 7200 1 CEST} - {2171923200 3600 0 CET} - {2184624000 7200 1 CEST} - {2203372800 3600 0 CET} - {2216678400 7200 1 CEST} - {2234822400 3600 0 CET} - {2248128000 7200 1 CEST} - {2266272000 3600 0 CET} - {2279577600 7200 1 CEST} - {2298326400 3600 0 CET} - {2311027200 7200 1 CEST} - {2329776000 3600 0 CET} - {2342476800 7200 1 CEST} - {2361225600 3600 0 CET} - {2374531200 7200 1 CEST} - {2392675200 3600 0 CET} - {2405980800 7200 1 CEST} - {2424124800 3600 0 CET} - {2437430400 7200 1 CEST} - {2455574400 3600 0 CET} - {2468880000 7200 1 CEST} - {2487628800 3600 0 CET} - {2500329600 7200 1 CEST} - {2519078400 3600 0 CET} - {2531779200 7200 1 CEST} - {2550528000 3600 0 CET} - {2563833600 7200 1 CEST} - {2581977600 3600 0 CET} - {2595283200 7200 1 CEST} - {2613427200 3600 0 CET} - {2626732800 7200 1 CEST} - {2645481600 3600 0 CET} - {2658182400 7200 1 CEST} - {2676931200 3600 0 CET} - {2689632000 7200 1 CEST} - {2708380800 3600 0 CET} - {2721686400 7200 1 CEST} - {2739830400 3600 0 CET} - {2753136000 7200 1 CEST} - {2771280000 3600 0 CET} - {2784585600 7200 1 CEST} - {2802729600 3600 0 CET} - {2816035200 7200 1 CEST} - {2834784000 3600 0 CET} - {2847484800 7200 1 CEST} - {2866233600 3600 0 CET} - {2878934400 7200 1 CEST} - {2897683200 3600 0 CET} - {2910988800 7200 1 CEST} - {2929132800 3600 0 CET} - {2942438400 7200 1 CEST} - {2960582400 3600 0 CET} - {2973888000 7200 1 CEST} - {2992636800 3600 0 CET} - {3005337600 7200 1 CEST} - {3024086400 3600 0 CET} - {3036787200 7200 1 CEST} - {3055536000 3600 0 CET} - {3068236800 7200 1 CEST} - {3086985600 3600 0 CET} - {3100291200 7200 1 CEST} - {3118435200 3600 0 CET} - {3131740800 7200 1 CEST} - {3149884800 3600 0 CET} - {3163190400 7200 1 CEST} - {3181939200 3600 0 CET} - {3194640000 7200 1 CEST} - {3213388800 3600 0 CET} - {3226089600 7200 1 CEST} - {3244838400 3600 0 CET} - {3258144000 7200 1 CEST} - {3276288000 3600 0 CET} - {3289593600 7200 1 CEST} - {3307737600 3600 0 CET} - {3321043200 7200 1 CEST} - {3339187200 3600 0 CET} - {3352492800 7200 1 CEST} - {3371241600 3600 0 CET} - {3383942400 7200 1 CEST} - {3402691200 3600 0 CET} - {3415392000 7200 1 CEST} - {3434140800 3600 0 CET} - {3447446400 7200 1 CEST} - {3465590400 3600 0 CET} - {3478896000 7200 1 CEST} - {3497040000 3600 0 CET} - {3510345600 7200 1 CEST} - {3529094400 3600 0 CET} - {3541795200 7200 1 CEST} - {3560544000 3600 0 CET} - {3573244800 7200 1 CEST} - {3591993600 3600 0 CET} - {3605299200 7200 1 CEST} - {3623443200 3600 0 CET} - {3636748800 7200 1 CEST} - {3654892800 3600 0 CET} - {3668198400 7200 1 CEST} - {3686342400 3600 0 CET} - {3699648000 7200 1 CEST} - {3718396800 3600 0 CET} - {3731097600 7200 1 CEST} - {3749846400 3600 0 CET} - {3762547200 7200 1 CEST} - {3781296000 3600 0 CET} - {3794601600 7200 1 CEST} - {3812745600 3600 0 CET} - {3826051200 7200 1 CEST} - {3844195200 3600 0 CET} - {3857500800 7200 1 CEST} - {3876249600 3600 0 CET} - {3888950400 7200 1 CEST} - {3907699200 3600 0 CET} - {3920400000 7200 1 CEST} - {3939148800 3600 0 CET} - {3951849600 7200 1 CEST} - {3970598400 3600 0 CET} - {3983904000 7200 1 CEST} - {4002048000 3600 0 CET} - {4015353600 7200 1 CEST} - {4033497600 3600 0 CET} - {4046803200 7200 1 CEST} - {4065552000 3600 0 CET} - {4078252800 7200 1 CEST} - {4097001600 3600 0 CET} + {1382662800 7200 0 EET} } diff --git a/library/tzdata/America/Eirunepe b/library/tzdata/America/Eirunepe index 86dcd8f..a05631f 100644 --- a/library/tzdata/America/Eirunepe +++ b/library/tzdata/America/Eirunepe @@ -37,4 +37,5 @@ set TZData(:America/Eirunepe) { {761716800 -18000 0 ACT} {780206400 -18000 0 ACT} {1214283600 -14400 0 AMT} + {1384056000 -18000 0 ACT} } diff --git a/library/tzdata/America/Havana b/library/tzdata/America/Havana index 89cbc9a..5901dae 100644 --- a/library/tzdata/America/Havana +++ b/library/tzdata/America/Havana @@ -94,7 +94,7 @@ set TZData(:America/Havana) { {1035694800 -18000 0 CST} {1049605200 -14400 1 CDT} {1067144400 -18000 0 CST} - {1081054800 -14400 1 CDT} + {1080450000 -14400 1 CDT} {1162098000 -18000 0 CST} {1173589200 -14400 1 CDT} {1193547600 -18000 0 CST} diff --git a/library/tzdata/America/Metlakatla b/library/tzdata/America/Metlakatla index e8af1c0..8ea80fa 100644 --- a/library/tzdata/America/Metlakatla +++ b/library/tzdata/America/Metlakatla @@ -39,5 +39,5 @@ set TZData(:America/Metlakatla) { {388576800 -25200 1 PDT} {404902800 -28800 0 PST} {420026400 -25200 1 PDT} - {436356000 -28800 0 MeST} + {436356000 -28800 0 PST} } diff --git a/library/tzdata/America/Rio_Branco b/library/tzdata/America/Rio_Branco index 20889cb..f0ff7fa 100644 --- a/library/tzdata/America/Rio_Branco +++ b/library/tzdata/America/Rio_Branco @@ -33,4 +33,5 @@ set TZData(:America/Rio_Branco) { {571204800 -18000 0 ACT} {590040000 -18000 0 ACT} {1214283600 -14400 0 AMT} + {1384056000 -18000 0 ACT} } diff --git a/library/tzdata/Antarctica/Casey b/library/tzdata/Antarctica/Casey index cbe3e3c..56d5df7 100644 --- a/library/tzdata/Antarctica/Casey +++ b/library/tzdata/Antarctica/Casey @@ -2,9 +2,9 @@ set TZData(:Antarctica/Casey) { {-9223372036854775808 0 0 zzz} - {-31536000 28800 0 WST} + {-31536000 28800 0 AWST} {1255802400 39600 0 CAST} - {1267714800 28800 0 WST} + {1267714800 28800 0 AWST} {1319738400 39600 0 CAST} - {1329843600 28800 0 WST} + {1329843600 28800 0 AWST} } diff --git a/library/tzdata/Antarctica/Macquarie b/library/tzdata/Antarctica/Macquarie index bd5cf8a..07ddff6 100644 --- a/library/tzdata/Antarctica/Macquarie +++ b/library/tzdata/Antarctica/Macquarie @@ -2,96 +2,96 @@ set TZData(:Antarctica/Macquarie) { {-9223372036854775808 0 0 zzz} - {-2214259200 36000 0 EST} - {-1680508800 39600 1 EST} - {-1669892400 39600 0 EST} - {-1665392400 36000 0 EST} + {-2214259200 36000 0 AEST} + {-1680508800 39600 1 AEDT} + {-1669892400 39600 0 AEDT} + {-1665392400 36000 0 AEST} {-1601719200 0 0 zzz} - {-94730400 36000 0 EST} - {-71136000 39600 1 EST} - {-55411200 36000 0 EST} - {-37267200 39600 1 EST} - {-25776000 36000 0 EST} - {-5817600 39600 1 EST} - {5673600 36000 0 EST} - {25632000 39600 1 EST} - {37728000 36000 0 EST} - {57686400 39600 1 EST} - {67968000 36000 0 EST} - {89136000 39600 1 EST} - {100022400 36000 0 EST} - {120585600 39600 1 EST} - {131472000 36000 0 EST} - {152035200 39600 1 EST} - {162921600 36000 0 EST} - {183484800 39600 1 EST} - {194976000 36000 0 EST} - {215539200 39600 1 EST} - {226425600 36000 0 EST} - {246988800 39600 1 EST} - {257875200 36000 0 EST} - {278438400 39600 1 EST} - {289324800 36000 0 EST} - {309888000 39600 1 EST} - {320774400 36000 0 EST} - {341337600 39600 1 EST} - {352224000 36000 0 EST} - {372787200 39600 1 EST} - {386092800 36000 0 EST} - {404841600 39600 1 EST} - {417542400 36000 0 EST} - {436291200 39600 1 EST} - {447177600 36000 0 EST} - {467740800 39600 1 EST} - {478627200 36000 0 EST} - {499190400 39600 1 EST} - {510076800 36000 0 EST} - {530035200 39600 1 EST} - {542736000 36000 0 EST} - {562089600 39600 1 EST} - {574790400 36000 0 EST} - {594144000 39600 1 EST} - {606240000 36000 0 EST} - {625593600 39600 1 EST} - {637689600 36000 0 EST} - {657043200 39600 1 EST} - {670348800 36000 0 EST} - {686678400 39600 1 EST} - {701798400 36000 0 EST} - {718128000 39600 1 EST} - {733248000 36000 0 EST} - {749577600 39600 1 EST} - {764697600 36000 0 EST} - {781027200 39600 1 EST} - {796147200 36000 0 EST} - {812476800 39600 1 EST} - {828201600 36000 0 EST} - {844531200 39600 1 EST} - {859651200 36000 0 EST} - {875980800 39600 1 EST} - {891100800 36000 0 EST} - {907430400 39600 1 EST} - {922550400 36000 0 EST} - {938880000 39600 1 EST} - {954000000 36000 0 EST} - {967305600 39600 1 EST} - {985449600 36000 0 EST} - {1002384000 39600 1 EST} - {1017504000 36000 0 EST} - {1033833600 39600 1 EST} - {1048953600 36000 0 EST} - {1065283200 39600 1 EST} - {1080403200 36000 0 EST} - {1096732800 39600 1 EST} - {1111852800 36000 0 EST} - {1128182400 39600 1 EST} - {1143907200 36000 0 EST} - {1159632000 39600 1 EST} - {1174752000 36000 0 EST} - {1191686400 39600 1 EST} - {1207411200 36000 0 EST} - {1223136000 39600 1 EST} - {1238860800 36000 0 EST} - {1254585600 39600 1 EST} + {-94730400 36000 0 AEST} + {-71136000 39600 1 AEDT} + {-55411200 36000 0 AEST} + {-37267200 39600 1 AEDT} + {-25776000 36000 0 AEST} + {-5817600 39600 1 AEDT} + {5673600 36000 0 AEST} + {25632000 39600 1 AEDT} + {37728000 36000 0 AEST} + {57686400 39600 1 AEDT} + {67968000 36000 0 AEST} + {89136000 39600 1 AEDT} + {100022400 36000 0 AEST} + {120585600 39600 1 AEDT} + {131472000 36000 0 AEST} + {152035200 39600 1 AEDT} + {162921600 36000 0 AEST} + {183484800 39600 1 AEDT} + {194976000 36000 0 AEST} + {215539200 39600 1 AEDT} + {226425600 36000 0 AEST} + {246988800 39600 1 AEDT} + {257875200 36000 0 AEST} + {278438400 39600 1 AEDT} + {289324800 36000 0 AEST} + {309888000 39600 1 AEDT} + {320774400 36000 0 AEST} + {341337600 39600 1 AEDT} + {352224000 36000 0 AEST} + {372787200 39600 1 AEDT} + {386092800 36000 0 AEST} + {404841600 39600 1 AEDT} + {417542400 36000 0 AEST} + {436291200 39600 1 AEDT} + {447177600 36000 0 AEST} + {467740800 39600 1 AEDT} + {478627200 36000 0 AEST} + {499190400 39600 1 AEDT} + {510076800 36000 0 AEST} + {530035200 39600 1 AEDT} + {542736000 36000 0 AEST} + {562089600 39600 1 AEDT} + {574790400 36000 0 AEST} + {594144000 39600 1 AEDT} + {606240000 36000 0 AEST} + {625593600 39600 1 AEDT} + {637689600 36000 0 AEST} + {657043200 39600 1 AEDT} + {670348800 36000 0 AEST} + {686678400 39600 1 AEDT} + {701798400 36000 0 AEST} + {718128000 39600 1 AEDT} + {733248000 36000 0 AEST} + {749577600 39600 1 AEDT} + {764697600 36000 0 AEST} + {781027200 39600 1 AEDT} + {796147200 36000 0 AEST} + {812476800 39600 1 AEDT} + {828201600 36000 0 AEST} + {844531200 39600 1 AEDT} + {859651200 36000 0 AEST} + {875980800 39600 1 AEDT} + {891100800 36000 0 AEST} + {907430400 39600 1 AEDT} + {922550400 36000 0 AEST} + {938880000 39600 1 AEDT} + {954000000 36000 0 AEST} + {967305600 39600 1 AEDT} + {985449600 36000 0 AEST} + {1002384000 39600 1 AEDT} + {1017504000 36000 0 AEST} + {1033833600 39600 1 AEDT} + {1048953600 36000 0 AEST} + {1065283200 39600 1 AEDT} + {1080403200 36000 0 AEST} + {1096732800 39600 1 AEDT} + {1111852800 36000 0 AEST} + {1128182400 39600 1 AEDT} + {1143907200 36000 0 AEST} + {1159632000 39600 1 AEDT} + {1174752000 36000 0 AEST} + {1191686400 39600 1 AEDT} + {1207411200 36000 0 AEST} + {1223136000 39600 1 AEDT} + {1238860800 36000 0 AEST} + {1254585600 39600 1 AEDT} {1270310400 39600 0 MIST} } diff --git a/library/tzdata/Asia/Amman b/library/tzdata/Asia/Amman index d5e8616..c2f6904 100644 --- a/library/tzdata/Asia/Amman +++ b/library/tzdata/Asia/Amman @@ -70,5 +70,177 @@ set TZData(:Asia/Amman) { {1301608800 10800 1 EEST} {1319752800 7200 0 EET} {1333058400 10800 1 EEST} - {1351202400 10800 0 AST} + {1387486800 7200 0 EET} + {1395957600 10800 1 EEST} + {1414706400 7200 0 EET} + {1427407200 10800 1 EEST} + {1446156000 7200 0 EET} + {1459461600 10800 1 EEST} + {1477605600 7200 0 EET} + {1490911200 10800 1 EEST} + {1509055200 7200 0 EET} + {1522360800 10800 1 EEST} + {1540504800 7200 0 EET} + {1553810400 10800 1 EEST} + {1571954400 7200 0 EET} + {1585260000 10800 1 EEST} + {1604008800 7200 0 EET} + {1616709600 10800 1 EEST} + {1635458400 7200 0 EET} + {1648764000 10800 1 EEST} + {1666908000 7200 0 EET} + {1680213600 10800 1 EEST} + {1698357600 7200 0 EET} + {1711663200 10800 1 EEST} + {1729807200 7200 0 EET} + {1743112800 10800 1 EEST} + {1761861600 7200 0 EET} + {1774562400 10800 1 EEST} + {1793311200 7200 0 EET} + {1806012000 10800 1 EEST} + {1824760800 7200 0 EET} + {1838066400 10800 1 EEST} + {1856210400 7200 0 EET} + {1869516000 10800 1 EEST} + {1887660000 7200 0 EET} + {1900965600 10800 1 EEST} + {1919109600 7200 0 EET} + {1932415200 10800 1 EEST} + {1951164000 7200 0 EET} + {1963864800 10800 1 EEST} + {1982613600 7200 0 EET} + {1995919200 10800 1 EEST} + {2014063200 7200 0 EET} + {2027368800 10800 1 EEST} + {2045512800 7200 0 EET} + {2058818400 10800 1 EEST} + {2076962400 7200 0 EET} + {2090268000 10800 1 EEST} + {2109016800 7200 0 EET} + {2121717600 10800 1 EEST} + {2140466400 7200 0 EET} + {2153167200 10800 1 EEST} + {2171916000 7200 0 EET} + {2185221600 10800 1 EEST} + {2203365600 7200 0 EET} + {2216671200 10800 1 EEST} + {2234815200 7200 0 EET} + {2248120800 10800 1 EEST} + {2266264800 7200 0 EET} + {2279570400 10800 1 EEST} + {2298319200 7200 0 EET} + {2311020000 10800 1 EEST} + {2329768800 7200 0 EET} + {2343074400 10800 1 EEST} + {2361218400 7200 0 EET} + {2374524000 10800 1 EEST} + {2392668000 7200 0 EET} + {2405973600 10800 1 EEST} + {2424117600 7200 0 EET} + {2437423200 10800 1 EEST} + {2455567200 7200 0 EET} + {2468872800 10800 1 EEST} + {2487621600 7200 0 EET} + {2500322400 10800 1 EEST} + {2519071200 7200 0 EET} + {2532376800 10800 1 EEST} + {2550520800 7200 0 EET} + {2563826400 10800 1 EEST} + {2581970400 7200 0 EET} + {2595276000 10800 1 EEST} + {2613420000 7200 0 EET} + {2626725600 10800 1 EEST} + {2645474400 7200 0 EET} + {2658175200 10800 1 EEST} + {2676924000 7200 0 EET} + {2689624800 10800 1 EEST} + {2708373600 7200 0 EET} + {2721679200 10800 1 EEST} + {2739823200 7200 0 EET} + {2753128800 10800 1 EEST} + {2771272800 7200 0 EET} + {2784578400 10800 1 EEST} + {2802722400 7200 0 EET} + {2816028000 10800 1 EEST} + {2834776800 7200 0 EET} + {2847477600 10800 1 EEST} + {2866226400 7200 0 EET} + {2879532000 10800 1 EEST} + {2897676000 7200 0 EET} + {2910981600 10800 1 EEST} + {2929125600 7200 0 EET} + {2942431200 10800 1 EEST} + {2960575200 7200 0 EET} + {2973880800 10800 1 EEST} + {2992629600 7200 0 EET} + {3005330400 10800 1 EEST} + {3024079200 7200 0 EET} + {3036780000 10800 1 EEST} + {3055528800 7200 0 EET} + {3068834400 10800 1 EEST} + {3086978400 7200 0 EET} + {3100284000 10800 1 EEST} + {3118428000 7200 0 EET} + {3131733600 10800 1 EEST} + {3149877600 7200 0 EET} + {3163183200 10800 1 EEST} + {3181932000 7200 0 EET} + {3194632800 10800 1 EEST} + {3213381600 7200 0 EET} + {3226687200 10800 1 EEST} + {3244831200 7200 0 EET} + {3258136800 10800 1 EEST} + {3276280800 7200 0 EET} + {3289586400 10800 1 EEST} + {3307730400 7200 0 EET} + {3321036000 10800 1 EEST} + {3339180000 7200 0 EET} + {3352485600 10800 1 EEST} + {3371234400 7200 0 EET} + {3383935200 10800 1 EEST} + {3402684000 7200 0 EET} + {3415989600 10800 1 EEST} + {3434133600 7200 0 EET} + {3447439200 10800 1 EEST} + {3465583200 7200 0 EET} + {3478888800 10800 1 EEST} + {3497032800 7200 0 EET} + {3510338400 10800 1 EEST} + {3529087200 7200 0 EET} + {3541788000 10800 1 EEST} + {3560536800 7200 0 EET} + {3573237600 10800 1 EEST} + {3591986400 7200 0 EET} + {3605292000 10800 1 EEST} + {3623436000 7200 0 EET} + {3636741600 10800 1 EEST} + {3654885600 7200 0 EET} + {3668191200 10800 1 EEST} + {3686335200 7200 0 EET} + {3699640800 10800 1 EEST} + {3718389600 7200 0 EET} + {3731090400 10800 1 EEST} + {3749839200 7200 0 EET} + {3763144800 10800 1 EEST} + {3781288800 7200 0 EET} + {3794594400 10800 1 EEST} + {3812738400 7200 0 EET} + {3826044000 10800 1 EEST} + {3844188000 7200 0 EET} + {3857493600 10800 1 EEST} + {3876242400 7200 0 EET} + {3888943200 10800 1 EEST} + {3907692000 7200 0 EET} + {3920392800 10800 1 EEST} + {3939141600 7200 0 EET} + {3952447200 10800 1 EEST} + {3970591200 7200 0 EET} + {3983896800 10800 1 EEST} + {4002040800 7200 0 EET} + {4015346400 10800 1 EEST} + {4033490400 7200 0 EET} + {4046796000 10800 1 EEST} + {4065544800 7200 0 EET} + {4078245600 10800 1 EEST} + {4096994400 7200 0 EET} } diff --git a/library/tzdata/Asia/Chongqing b/library/tzdata/Asia/Chongqing index eff3536..ba515fe 100644 --- a/library/tzdata/Asia/Chongqing +++ b/library/tzdata/Asia/Chongqing @@ -1,19 +1,5 @@ # created by tools/tclZIC.tcl - do not edit - -set TZData(:Asia/Chongqing) { - {-9223372036854775808 25580 0 LMT} - {-1325487980 25200 0 LONT} - {325962000 28800 0 CST} - {515520000 32400 1 CDT} - {527007600 28800 0 CST} - {545155200 32400 1 CDT} - {558457200 28800 0 CST} - {576604800 32400 1 CDT} - {589906800 28800 0 CST} - {608659200 32400 1 CDT} - {621961200 28800 0 CST} - {640108800 32400 1 CDT} - {653410800 28800 0 CST} - {671558400 32400 1 CDT} - {684860400 28800 0 CST} +if {![info exists TZData(Asia/Shanghai)]} { + LoadTimeZoneFile Asia/Shanghai } +set TZData(:Asia/Chongqing) $TZData(:Asia/Shanghai) diff --git a/library/tzdata/Asia/Chungking b/library/tzdata/Asia/Chungking index f10d8a1..fa857dd 100644 --- a/library/tzdata/Asia/Chungking +++ b/library/tzdata/Asia/Chungking @@ -1,5 +1,5 @@ # created by tools/tclZIC.tcl - do not edit -if {![info exists TZData(Asia/Chongqing)]} { - LoadTimeZoneFile Asia/Chongqing +if {![info exists TZData(Asia/Shanghai)]} { + LoadTimeZoneFile Asia/Shanghai } -set TZData(:Asia/Chungking) $TZData(:Asia/Chongqing) +set TZData(:Asia/Chungking) $TZData(:Asia/Shanghai) diff --git a/library/tzdata/Asia/Gaza b/library/tzdata/Asia/Gaza index 7d62a96..8ec9c5b 100644 --- a/library/tzdata/Asia/Gaza +++ b/library/tzdata/Asia/Gaza @@ -46,8 +46,8 @@ set TZData(:Asia/Gaza) { {526424400 7200 0 IST} {545436000 10800 1 IDT} {558478800 7200 0 IST} - {576540000 10800 1 IDT} - {589237200 7200 0 IST} + {576626400 10800 1 IDT} + {589323600 7200 0 IST} {609890400 10800 1 IDT} {620773200 7200 0 IST} {638316000 10800 1 IDT} diff --git a/library/tzdata/Asia/Harbin b/library/tzdata/Asia/Harbin index 0eb0c12..dfcb549 100644 --- a/library/tzdata/Asia/Harbin +++ b/library/tzdata/Asia/Harbin @@ -1,22 +1,5 @@ # created by tools/tclZIC.tcl - do not edit - -set TZData(:Asia/Harbin) { - {-9223372036854775808 30404 0 LMT} - {-1325492804 30600 0 CHAT} - {-1194078600 28800 0 CST} - {-946800000 32400 0 CHAT} - {-115894800 30600 0 CHAT} - {325956600 28800 0 CST} - {515520000 32400 1 CDT} - {527007600 28800 0 CST} - {545155200 32400 1 CDT} - {558457200 28800 0 CST} - {576604800 32400 1 CDT} - {589906800 28800 0 CST} - {608659200 32400 1 CDT} - {621961200 28800 0 CST} - {640108800 32400 1 CDT} - {653410800 28800 0 CST} - {671558400 32400 1 CDT} - {684860400 28800 0 CST} +if {![info exists TZData(Asia/Shanghai)]} { + LoadTimeZoneFile Asia/Shanghai } +set TZData(:Asia/Harbin) $TZData(:Asia/Shanghai) diff --git a/library/tzdata/Asia/Hebron b/library/tzdata/Asia/Hebron index 1333d5a..900ffad 100644 --- a/library/tzdata/Asia/Hebron +++ b/library/tzdata/Asia/Hebron @@ -46,8 +46,8 @@ set TZData(:Asia/Hebron) { {526424400 7200 0 IST} {545436000 10800 1 IDT} {558478800 7200 0 IST} - {576540000 10800 1 IDT} - {589237200 7200 0 IST} + {576626400 10800 1 IDT} + {589323600 7200 0 IST} {609890400 10800 1 IDT} {620773200 7200 0 IST} {638316000 10800 1 IDT} diff --git a/library/tzdata/Asia/Irkutsk b/library/tzdata/Asia/Irkutsk index bca1dcc..e344181 100644 --- a/library/tzdata/Asia/Irkutsk +++ b/library/tzdata/Asia/Irkutsk @@ -1,9 +1,9 @@ # created by tools/tclZIC.tcl - do not edit set TZData(:Asia/Irkutsk) { - {-9223372036854775808 25040 0 LMT} - {-2840165840 25040 0 IMT} - {-1575874640 25200 0 IRKT} + {-9223372036854775808 25035 0 LMT} + {-2840165835 25035 0 IMT} + {-1575874635 25200 0 IRKT} {-1247554800 28800 0 IRKMMTT} {354902400 32400 1 IRKST} {370710000 28800 0 IRKT} @@ -68,4 +68,5 @@ set TZData(:Asia/Irkutsk) { {1269712800 32400 1 IRKST} {1288461600 28800 0 IRKT} {1301162400 32400 0 IRKT} + {1414256400 28800 0 IRKT} } diff --git a/library/tzdata/Asia/Jayapura b/library/tzdata/Asia/Jayapura index a71228f..f3a4c44 100644 --- a/library/tzdata/Asia/Jayapura +++ b/library/tzdata/Asia/Jayapura @@ -3,6 +3,6 @@ set TZData(:Asia/Jayapura) { {-9223372036854775808 33768 0 LMT} {-1172913768 32400 0 WIT} - {-799491600 34200 0 CST} + {-799491600 34200 0 ACST} {-189423000 32400 0 WIT} } diff --git a/library/tzdata/Asia/Jerusalem b/library/tzdata/Asia/Jerusalem index 7662680..2714963 100644 --- a/library/tzdata/Asia/Jerusalem +++ b/library/tzdata/Asia/Jerusalem @@ -45,8 +45,8 @@ set TZData(:Asia/Jerusalem) { {526424400 7200 0 IST} {545436000 10800 1 IDT} {558478800 7200 0 IST} - {576540000 10800 1 IDT} - {589237200 7200 0 IST} + {576626400 10800 1 IDT} + {589323600 7200 0 IST} {609890400 10800 1 IDT} {620773200 7200 0 IST} {638316000 10800 1 IDT} diff --git a/library/tzdata/Asia/Kashgar b/library/tzdata/Asia/Kashgar index 2f64f42..f67cbf1 100644 --- a/library/tzdata/Asia/Kashgar +++ b/library/tzdata/Asia/Kashgar @@ -1,20 +1,5 @@ # created by tools/tclZIC.tcl - do not edit - -set TZData(:Asia/Kashgar) { - {-9223372036854775808 18236 0 LMT} - {-1325480636 19800 0 KAST} - {-946791000 18000 0 KAST} - {325969200 28800 0 CST} - {515520000 32400 1 CDT} - {527007600 28800 0 CST} - {545155200 32400 1 CDT} - {558457200 28800 0 CST} - {576604800 32400 1 CDT} - {589906800 28800 0 CST} - {608659200 32400 1 CDT} - {621961200 28800 0 CST} - {640108800 32400 1 CDT} - {653410800 28800 0 CST} - {671558400 32400 1 CDT} - {684860400 28800 0 CST} +if {![info exists TZData(Asia/Urumqi)]} { + LoadTimeZoneFile Asia/Urumqi } +set TZData(:Asia/Kashgar) $TZData(:Asia/Urumqi) diff --git a/library/tzdata/Asia/Khandyga b/library/tzdata/Asia/Khandyga index 2464b9f..b2dc97a 100644 --- a/library/tzdata/Asia/Khandyga +++ b/library/tzdata/Asia/Khandyga @@ -69,4 +69,5 @@ set TZData(:Asia/Khandyga) { {1288454400 36000 0 VLAT} {1301155200 39600 0 VLAT} {1315832400 36000 0 YAKT} + {1414252800 32400 0 YAKT} } diff --git a/library/tzdata/Asia/Krasnoyarsk b/library/tzdata/Asia/Krasnoyarsk index 13dfeb5..2770a51 100644 --- a/library/tzdata/Asia/Krasnoyarsk +++ b/library/tzdata/Asia/Krasnoyarsk @@ -67,4 +67,5 @@ set TZData(:Asia/Krasnoyarsk) { {1269716400 28800 1 KRAST} {1288465200 25200 0 KRAT} {1301166000 28800 0 KRAT} + {1414260000 25200 0 KRAT} } diff --git a/library/tzdata/Asia/Magadan b/library/tzdata/Asia/Magadan index 62e01c5..bf796a7 100644 --- a/library/tzdata/Asia/Magadan +++ b/library/tzdata/Asia/Magadan @@ -67,4 +67,5 @@ set TZData(:Asia/Magadan) { {1269702000 43200 1 MAGST} {1288450800 39600 0 MAGT} {1301151600 43200 0 MAGT} + {1414245600 36000 0 MAGT} } diff --git a/library/tzdata/Asia/Novokuznetsk b/library/tzdata/Asia/Novokuznetsk index 9cd45c0..d7e308e 100644 --- a/library/tzdata/Asia/Novokuznetsk +++ b/library/tzdata/Asia/Novokuznetsk @@ -68,4 +68,5 @@ set TZData(:Asia/Novokuznetsk) { {1269720000 25200 1 NOVST} {1288468800 21600 0 NOVT} {1301169600 25200 0 NOVT} + {1414263600 25200 0 KRAT} } diff --git a/library/tzdata/Asia/Novosibirsk b/library/tzdata/Asia/Novosibirsk index 5032eec..7227780 100644 --- a/library/tzdata/Asia/Novosibirsk +++ b/library/tzdata/Asia/Novosibirsk @@ -68,4 +68,5 @@ set TZData(:Asia/Novosibirsk) { {1269720000 25200 1 NOVST} {1288468800 21600 0 NOVT} {1301169600 25200 0 NOVT} + {1414263600 21600 0 NOVT} } diff --git a/library/tzdata/Asia/Omsk b/library/tzdata/Asia/Omsk index ca90d2e..a6b0db3 100644 --- a/library/tzdata/Asia/Omsk +++ b/library/tzdata/Asia/Omsk @@ -67,4 +67,5 @@ set TZData(:Asia/Omsk) { {1269720000 25200 1 OMSST} {1288468800 21600 0 OMST} {1301169600 25200 0 OMST} + {1414263600 21600 0 OMST} } diff --git a/library/tzdata/Asia/Pyongyang b/library/tzdata/Asia/Pyongyang index 21c9a68..dd40311 100644 --- a/library/tzdata/Asia/Pyongyang +++ b/library/tzdata/Asia/Pyongyang @@ -3,9 +3,11 @@ set TZData(:Asia/Pyongyang) { {-9223372036854775808 30180 0 LMT} {-2524551780 30600 0 KST} - {-2053931400 32400 0 KST} + {-2053931400 32400 0 JCST} {-1325494800 30600 0 KST} - {-1199262600 32400 0 KST} + {-1199262600 32400 0 JCST} + {-1017824400 32400 0 JST} + {-768646800 32400 0 KST} {-498128400 28800 0 KST} {-264931200 32400 0 KST} } diff --git a/library/tzdata/Asia/Riyadh b/library/tzdata/Asia/Riyadh index 0ef28a9..12c9e24 100644 --- a/library/tzdata/Asia/Riyadh +++ b/library/tzdata/Asia/Riyadh @@ -2,5 +2,5 @@ set TZData(:Asia/Riyadh) { {-9223372036854775808 11212 0 LMT} - {-631163212 10800 0 AST} + {-719636812 10800 0 AST} } diff --git a/library/tzdata/Asia/Sakhalin b/library/tzdata/Asia/Sakhalin index 0b29e82..eed20ba 100644 --- a/library/tzdata/Asia/Sakhalin +++ b/library/tzdata/Asia/Sakhalin @@ -2,8 +2,8 @@ set TZData(:Asia/Sakhalin) { {-9223372036854775808 34248 0 LMT} - {-2031039048 32400 0 CJT} - {-1009875600 32400 0 JST} + {-2031039048 32400 0 JCST} + {-1017824400 32400 0 JST} {-768560400 39600 0 SAKMMTT} {354891600 43200 1 SAKST} {370699200 39600 0 SAKT} @@ -69,4 +69,5 @@ set TZData(:Asia/Sakhalin) { {1269705600 39600 1 SAKST} {1288454400 36000 0 SAKT} {1301155200 39600 0 SAKT} + {1414249200 36000 0 SAKT} } diff --git a/library/tzdata/Asia/Seoul b/library/tzdata/Asia/Seoul index 9c83e30..9625291 100644 --- a/library/tzdata/Asia/Seoul +++ b/library/tzdata/Asia/Seoul @@ -3,9 +3,11 @@ set TZData(:Asia/Seoul) { {-9223372036854775808 30472 0 LMT} {-2524552072 30600 0 KST} - {-2053931400 32400 0 KST} + {-2053931400 32400 0 JCST} {-1325494800 30600 0 KST} - {-1199262600 32400 0 KST} + {-1199262600 32400 0 JCST} + {-1017824400 32400 0 JST} + {-767350800 32400 0 KST} {-498128400 28800 0 KST} {-303984000 32400 1 KDT} {-293533200 28800 0 KST} diff --git a/library/tzdata/Asia/Shanghai b/library/tzdata/Asia/Shanghai index 4b3cc3b..ff2d2b5 100644 --- a/library/tzdata/Asia/Shanghai +++ b/library/tzdata/Asia/Shanghai @@ -1,8 +1,8 @@ # created by tools/tclZIC.tcl - do not edit set TZData(:Asia/Shanghai) { - {-9223372036854775808 29157 0 LMT} - {-1325491557 28800 0 CST} + {-9223372036854775808 29143 0 LMT} + {-2177481943 28800 0 CST} {-933494400 32400 1 CDT} {-923130000 28800 0 CST} {-908784000 32400 1 CDT} diff --git a/library/tzdata/Asia/Taipei b/library/tzdata/Asia/Taipei index a3c7ecf..61c77ef 100644 --- a/library/tzdata/Asia/Taipei +++ b/library/tzdata/Asia/Taipei @@ -2,13 +2,13 @@ set TZData(:Asia/Taipei) { {-9223372036854775808 29160 0 LMT} - {-2335248360 28800 0 CST} - {-778579200 32400 1 CDT} - {-765363600 28800 0 CST} - {-747043200 32400 1 CDT} + {-2335248360 28800 0 JWST} + {-1017820800 32400 0 JST} + {-766224000 28800 0 CST} + {-745833600 32400 1 CDT} {-733827600 28800 0 CST} - {-715507200 32400 1 CDT} - {-702291600 28800 0 CST} + {-716889600 32400 1 CDT} + {-699613200 28800 0 CST} {-683884800 32400 1 CDT} {-670669200 28800 0 CST} {-652348800 32400 1 CDT} @@ -41,6 +41,6 @@ set TZData(:Asia/Taipei) { {149785200 28800 0 CST} {165513600 32400 1 CDT} {181321200 28800 0 CST} - {299520000 32400 1 CDT} - {307465200 28800 0 CST} + {299606400 32400 1 CDT} + {307551600 28800 0 CST} } diff --git a/library/tzdata/Asia/Tashkent b/library/tzdata/Asia/Tashkent index fcee755..1477376 100644 --- a/library/tzdata/Asia/Tashkent +++ b/library/tzdata/Asia/Tashkent @@ -1,8 +1,8 @@ # created by tools/tclZIC.tcl - do not edit set TZData(:Asia/Tashkent) { - {-9223372036854775808 16632 0 LMT} - {-1441168632 18000 0 TAST} + {-9223372036854775808 16631 0 LMT} + {-1441168631 18000 0 TAST} {-1247547600 21600 0 TAST} {354909600 25200 1 TASST} {370717200 21600 0 TAST} diff --git a/library/tzdata/Asia/Tbilisi b/library/tzdata/Asia/Tbilisi index a716917..9f4a4bf 100644 --- a/library/tzdata/Asia/Tbilisi +++ b/library/tzdata/Asia/Tbilisi @@ -1,9 +1,9 @@ # created by tools/tclZIC.tcl - do not edit set TZData(:Asia/Tbilisi) { - {-9223372036854775808 10756 0 LMT} - {-2840151556 10756 0 TBMT} - {-1441162756 10800 0 TBIT} + {-9223372036854775808 10746 0 LMT} + {-2840151546 10746 0 TBMT} + {-1441162746 10800 0 TBIT} {-405140400 14400 0 TBIT} {354916800 18000 1 TBIST} {370724400 14400 0 TBIT} diff --git a/library/tzdata/Asia/Tokyo b/library/tzdata/Asia/Tokyo index 8d1ce11..5bfc75c 100644 --- a/library/tzdata/Asia/Tokyo +++ b/library/tzdata/Asia/Tokyo @@ -3,8 +3,8 @@ set TZData(:Asia/Tokyo) { {-9223372036854775808 33539 0 LMT} {-2587712400 32400 0 JST} - {-2335251600 32400 0 CJT} - {-1009875600 32400 0 JST} + {-2335251600 32400 0 JCST} + {-1017824400 32400 0 JST} {-683794800 36000 1 JDT} {-672393600 32400 0 JST} {-654764400 36000 1 JDT} diff --git a/library/tzdata/Asia/Urumqi b/library/tzdata/Asia/Urumqi index 93fc909..4f3cd67 100644 --- a/library/tzdata/Asia/Urumqi +++ b/library/tzdata/Asia/Urumqi @@ -2,18 +2,5 @@ set TZData(:Asia/Urumqi) { {-9223372036854775808 21020 0 LMT} - {-1325483420 21600 0 URUT} - {325965600 28800 0 CST} - {515520000 32400 1 CDT} - {527007600 28800 0 CST} - {545155200 32400 1 CDT} - {558457200 28800 0 CST} - {576604800 32400 1 CDT} - {589906800 28800 0 CST} - {608659200 32400 1 CDT} - {621961200 28800 0 CST} - {640108800 32400 1 CDT} - {653410800 28800 0 CST} - {671558400 32400 1 CDT} - {684860400 28800 0 CST} + {-1325483420 21600 0 XJT} } diff --git a/library/tzdata/Asia/Ust-Nera b/library/tzdata/Asia/Ust-Nera index c8de7a5..90fa7d5 100644 --- a/library/tzdata/Asia/Ust-Nera +++ b/library/tzdata/Asia/Ust-Nera @@ -67,4 +67,5 @@ set TZData(:Asia/Ust-Nera) { {1288450800 39600 0 MAGT} {1301151600 43200 0 MAGT} {1315828800 39600 0 VLAT} + {1414249200 36000 0 VLAT} } diff --git a/library/tzdata/Asia/Vladivostok b/library/tzdata/Asia/Vladivostok index 54101a5..396840d 100644 --- a/library/tzdata/Asia/Vladivostok +++ b/library/tzdata/Asia/Vladivostok @@ -1,8 +1,8 @@ # created by tools/tclZIC.tcl - do not edit set TZData(:Asia/Vladivostok) { - {-9223372036854775808 31664 0 LMT} - {-1487321264 32400 0 VLAT} + {-9223372036854775808 31654 0 LMT} + {-1487321254 32400 0 VLAT} {-1247562000 36000 0 VLAMMTT} {354895200 39600 1 VLAST} {370702800 36000 0 VLAT} @@ -24,9 +24,9 @@ set TZData(:Asia/Vladivostok) { {622569600 36000 0 VLAT} {638294400 39600 1 VLAST} {654624000 36000 0 VLAT} - {670348800 32400 0 VLAMMTST} - {670352400 36000 1 VLASST} - {686077200 32400 0 VLAST} + {670348800 32400 0 VLAMMTT} + {670352400 36000 1 VLAST} + {686077200 32400 0 VLAT} {695754000 36000 0 VLAMMTT} {701787600 39600 1 VLAST} {717508800 36000 0 VLAT} @@ -67,4 +67,5 @@ set TZData(:Asia/Vladivostok) { {1269705600 39600 1 VLAST} {1288454400 36000 0 VLAT} {1301155200 39600 0 VLAT} + {1414249200 36000 0 VLAT} } diff --git a/library/tzdata/Asia/Yakutsk b/library/tzdata/Asia/Yakutsk index 5c32cc9..98953c9 100644 --- a/library/tzdata/Asia/Yakutsk +++ b/library/tzdata/Asia/Yakutsk @@ -67,4 +67,5 @@ set TZData(:Asia/Yakutsk) { {1269709200 36000 1 YAKST} {1288458000 32400 0 YAKT} {1301158800 36000 0 YAKT} + {1414252800 32400 0 YAKT} } diff --git a/library/tzdata/Asia/Yekaterinburg b/library/tzdata/Asia/Yekaterinburg index 2045496..688ceca 100644 --- a/library/tzdata/Asia/Yekaterinburg +++ b/library/tzdata/Asia/Yekaterinburg @@ -1,8 +1,8 @@ # created by tools/tclZIC.tcl - do not edit set TZData(:Asia/Yekaterinburg) { - {-9223372036854775808 14544 0 LMT} - {-1592611344 14400 0 SVET} + {-9223372036854775808 14553 0 LMT} + {-1592611353 14400 0 SVET} {-1247544000 18000 0 SVEMMTT} {354913200 21600 1 SVEST} {370720800 18000 0 SVET} @@ -67,4 +67,5 @@ set TZData(:Asia/Yekaterinburg) { {1269723600 21600 1 YEKST} {1288472400 18000 0 YEKT} {1301173200 21600 0 YEKT} + {1414267200 18000 0 YEKT} } diff --git a/library/tzdata/Atlantic/St_Helena b/library/tzdata/Atlantic/St_Helena index 6d0c00d..bf36c6a 100644 --- a/library/tzdata/Atlantic/St_Helena +++ b/library/tzdata/Atlantic/St_Helena @@ -1,7 +1,5 @@ # created by tools/tclZIC.tcl - do not edit - -set TZData(:Atlantic/St_Helena) { - {-9223372036854775808 -1368 0 LMT} - {-2524520232 -1368 0 JMT} - {-599614632 0 0 GMT} +if {![info exists TZData(Africa/Abidjan)]} { + LoadTimeZoneFile Africa/Abidjan } +set TZData(:Atlantic/St_Helena) $TZData(:Africa/Abidjan) diff --git a/library/tzdata/Australia/Adelaide b/library/tzdata/Australia/Adelaide index 9abe192..7e1b04e 100644 --- a/library/tzdata/Australia/Adelaide +++ b/library/tzdata/Australia/Adelaide @@ -2,272 +2,272 @@ set TZData(:Australia/Adelaide) { {-9223372036854775808 33260 0 LMT} - {-2364110060 32400 0 CST} - {-2230189200 34200 0 CST} - {-1672565340 37800 1 CST} - {-1665390600 34200 0 CST} - {-883639800 37800 1 CST} - {-876126600 34200 0 CST} - {-860398200 37800 1 CST} - {-844677000 34200 0 CST} - {-828343800 37800 1 CST} - {-813227400 34200 0 CST} - {31501800 34200 0 CST} - {57688200 37800 1 CST} - {67969800 34200 0 CST} - {89137800 37800 1 CST} - {100024200 34200 0 CST} - {120587400 37800 1 CST} - {131473800 34200 0 CST} - {152037000 37800 1 CST} - {162923400 34200 0 CST} - {183486600 37800 1 CST} - {194977800 34200 0 CST} - {215541000 37800 1 CST} - {226427400 34200 0 CST} - {246990600 37800 1 CST} - {257877000 34200 0 CST} - {278440200 37800 1 CST} - {289326600 34200 0 CST} - {309889800 37800 1 CST} - {320776200 34200 0 CST} - {341339400 37800 1 CST} - {352225800 34200 0 CST} - {372789000 37800 1 CST} - {384280200 34200 0 CST} - {404843400 37800 1 CST} - {415729800 34200 0 CST} - {436293000 37800 1 CST} - {447179400 34200 0 CST} - {467742600 37800 1 CST} - {478629000 34200 0 CST} - {499192200 37800 1 CST} - {511288200 34200 0 CST} - {530037000 37800 1 CST} - {542737800 34200 0 CST} - {562091400 37800 1 CST} - {574792200 34200 0 CST} - {594145800 37800 1 CST} - {606241800 34200 0 CST} - {625595400 37800 1 CST} - {637691400 34200 0 CST} - {657045000 37800 1 CST} - {667931400 34200 0 CST} - {688494600 37800 1 CST} - {701195400 34200 0 CST} - {719944200 37800 1 CST} - {731435400 34200 0 CST} - {751998600 37800 1 CST} - {764094600 34200 0 CST} - {783448200 37800 1 CST} - {796149000 34200 0 CST} - {814897800 37800 1 CST} - {828203400 34200 0 CST} - {846347400 37800 1 CST} - {859653000 34200 0 CST} - {877797000 37800 1 CST} - {891102600 34200 0 CST} - {909246600 37800 1 CST} - {922552200 34200 0 CST} - {941301000 37800 1 CST} - {954001800 34200 0 CST} - {972750600 37800 1 CST} - {985451400 34200 0 CST} - {1004200200 37800 1 CST} - {1017505800 34200 0 CST} - {1035649800 37800 1 CST} - {1048955400 34200 0 CST} - {1067099400 37800 1 CST} - {1080405000 34200 0 CST} - {1099153800 37800 1 CST} - {1111854600 34200 0 CST} - {1130603400 37800 1 CST} - {1143909000 34200 0 CST} - {1162053000 37800 1 CST} - {1174753800 34200 0 CST} - {1193502600 37800 1 CST} - {1207413000 34200 0 CST} - {1223137800 37800 1 CST} - {1238862600 34200 0 CST} - {1254587400 37800 1 CST} - {1270312200 34200 0 CST} - {1286037000 37800 1 CST} - {1301761800 34200 0 CST} - {1317486600 37800 1 CST} - {1333211400 34200 0 CST} - {1349541000 37800 1 CST} - {1365265800 34200 0 CST} - {1380990600 37800 1 CST} - {1396715400 34200 0 CST} - {1412440200 37800 1 CST} - {1428165000 34200 0 CST} - {1443889800 37800 1 CST} - {1459614600 34200 0 CST} - {1475339400 37800 1 CST} - {1491064200 34200 0 CST} - {1506789000 37800 1 CST} - {1522513800 34200 0 CST} - {1538843400 37800 1 CST} - {1554568200 34200 0 CST} - {1570293000 37800 1 CST} - {1586017800 34200 0 CST} - {1601742600 37800 1 CST} - {1617467400 34200 0 CST} - {1633192200 37800 1 CST} - {1648917000 34200 0 CST} - {1664641800 37800 1 CST} - {1680366600 34200 0 CST} - {1696091400 37800 1 CST} - {1712421000 34200 0 CST} - {1728145800 37800 1 CST} - {1743870600 34200 0 CST} - {1759595400 37800 1 CST} - {1775320200 34200 0 CST} - {1791045000 37800 1 CST} - {1806769800 34200 0 CST} - {1822494600 37800 1 CST} - {1838219400 34200 0 CST} - {1853944200 37800 1 CST} - {1869669000 34200 0 CST} - {1885998600 37800 1 CST} - {1901723400 34200 0 CST} - {1917448200 37800 1 CST} - {1933173000 34200 0 CST} - {1948897800 37800 1 CST} - {1964622600 34200 0 CST} - {1980347400 37800 1 CST} - {1996072200 34200 0 CST} - {2011797000 37800 1 CST} - {2027521800 34200 0 CST} - {2043246600 37800 1 CST} - {2058971400 34200 0 CST} - {2075301000 37800 1 CST} - {2091025800 34200 0 CST} - {2106750600 37800 1 CST} - {2122475400 34200 0 CST} - {2138200200 37800 1 CST} - {2153925000 34200 0 CST} - {2169649800 37800 1 CST} - {2185374600 34200 0 CST} - {2201099400 37800 1 CST} - {2216824200 34200 0 CST} - {2233153800 37800 1 CST} - {2248878600 34200 0 CST} - {2264603400 37800 1 CST} - {2280328200 34200 0 CST} - {2296053000 37800 1 CST} - {2311777800 34200 0 CST} - {2327502600 37800 1 CST} - {2343227400 34200 0 CST} - {2358952200 37800 1 CST} - {2374677000 34200 0 CST} - {2390401800 37800 1 CST} - {2406126600 34200 0 CST} - {2422456200 37800 1 CST} - {2438181000 34200 0 CST} - {2453905800 37800 1 CST} - {2469630600 34200 0 CST} - {2485355400 37800 1 CST} - {2501080200 34200 0 CST} - {2516805000 37800 1 CST} - {2532529800 34200 0 CST} - {2548254600 37800 1 CST} - {2563979400 34200 0 CST} - {2579704200 37800 1 CST} - {2596033800 34200 0 CST} - {2611758600 37800 1 CST} - {2627483400 34200 0 CST} - {2643208200 37800 1 CST} - {2658933000 34200 0 CST} - {2674657800 37800 1 CST} - {2690382600 34200 0 CST} - {2706107400 37800 1 CST} - {2721832200 34200 0 CST} - {2737557000 37800 1 CST} - {2753281800 34200 0 CST} - {2769611400 37800 1 CST} - {2785336200 34200 0 CST} - {2801061000 37800 1 CST} - {2816785800 34200 0 CST} - {2832510600 37800 1 CST} - {2848235400 34200 0 CST} - {2863960200 37800 1 CST} - {2879685000 34200 0 CST} - {2895409800 37800 1 CST} - {2911134600 34200 0 CST} - {2926859400 37800 1 CST} - {2942584200 34200 0 CST} - {2958913800 37800 1 CST} - {2974638600 34200 0 CST} - {2990363400 37800 1 CST} - {3006088200 34200 0 CST} - {3021813000 37800 1 CST} - {3037537800 34200 0 CST} - {3053262600 37800 1 CST} - {3068987400 34200 0 CST} - {3084712200 37800 1 CST} - {3100437000 34200 0 CST} - {3116766600 37800 1 CST} - {3132491400 34200 0 CST} - {3148216200 37800 1 CST} - {3163941000 34200 0 CST} - {3179665800 37800 1 CST} - {3195390600 34200 0 CST} - {3211115400 37800 1 CST} - {3226840200 34200 0 CST} - {3242565000 37800 1 CST} - {3258289800 34200 0 CST} - {3274014600 37800 1 CST} - {3289739400 34200 0 CST} - {3306069000 37800 1 CST} - {3321793800 34200 0 CST} - {3337518600 37800 1 CST} - {3353243400 34200 0 CST} - {3368968200 37800 1 CST} - {3384693000 34200 0 CST} - {3400417800 37800 1 CST} - {3416142600 34200 0 CST} - {3431867400 37800 1 CST} - {3447592200 34200 0 CST} - {3463317000 37800 1 CST} - {3479646600 34200 0 CST} - {3495371400 37800 1 CST} - {3511096200 34200 0 CST} - {3526821000 37800 1 CST} - {3542545800 34200 0 CST} - {3558270600 37800 1 CST} - {3573995400 34200 0 CST} - {3589720200 37800 1 CST} - {3605445000 34200 0 CST} - {3621169800 37800 1 CST} - {3636894600 34200 0 CST} - {3653224200 37800 1 CST} - {3668949000 34200 0 CST} - {3684673800 37800 1 CST} - {3700398600 34200 0 CST} - {3716123400 37800 1 CST} - {3731848200 34200 0 CST} - {3747573000 37800 1 CST} - {3763297800 34200 0 CST} - {3779022600 37800 1 CST} - {3794747400 34200 0 CST} - {3810472200 37800 1 CST} - {3826197000 34200 0 CST} - {3842526600 37800 1 CST} - {3858251400 34200 0 CST} - {3873976200 37800 1 CST} - {3889701000 34200 0 CST} - {3905425800 37800 1 CST} - {3921150600 34200 0 CST} - {3936875400 37800 1 CST} - {3952600200 34200 0 CST} - {3968325000 37800 1 CST} - {3984049800 34200 0 CST} - {4000379400 37800 1 CST} - {4016104200 34200 0 CST} - {4031829000 37800 1 CST} - {4047553800 34200 0 CST} - {4063278600 37800 1 CST} - {4079003400 34200 0 CST} - {4094728200 37800 1 CST} + {-2364110060 32400 0 ACST} + {-2230189200 34200 0 ACST} + {-1672565340 37800 1 ACDT} + {-1665390600 34200 0 ACST} + {-883639800 37800 1 ACDT} + {-876126600 34200 0 ACST} + {-860398200 37800 1 ACDT} + {-844677000 34200 0 ACST} + {-828343800 37800 1 ACDT} + {-813227400 34200 0 ACST} + {31501800 34200 0 ACST} + {57688200 37800 1 ACDT} + {67969800 34200 0 ACST} + {89137800 37800 1 ACDT} + {100024200 34200 0 ACST} + {120587400 37800 1 ACDT} + {131473800 34200 0 ACST} + {152037000 37800 1 ACDT} + {162923400 34200 0 ACST} + {183486600 37800 1 ACDT} + {194977800 34200 0 ACST} + {215541000 37800 1 ACDT} + {226427400 34200 0 ACST} + {246990600 37800 1 ACDT} + {257877000 34200 0 ACST} + {278440200 37800 1 ACDT} + {289326600 34200 0 ACST} + {309889800 37800 1 ACDT} + {320776200 34200 0 ACST} + {341339400 37800 1 ACDT} + {352225800 34200 0 ACST} + {372789000 37800 1 ACDT} + {384280200 34200 0 ACST} + {404843400 37800 1 ACDT} + {415729800 34200 0 ACST} + {436293000 37800 1 ACDT} + {447179400 34200 0 ACST} + {467742600 37800 1 ACDT} + {478629000 34200 0 ACST} + {499192200 37800 1 ACDT} + {511288200 34200 0 ACST} + {530037000 37800 1 ACDT} + {542737800 34200 0 ACST} + {562091400 37800 1 ACDT} + {574792200 34200 0 ACST} + {594145800 37800 1 ACDT} + {606241800 34200 0 ACST} + {625595400 37800 1 ACDT} + {637691400 34200 0 ACST} + {657045000 37800 1 ACDT} + {667931400 34200 0 ACST} + {688494600 37800 1 ACDT} + {701195400 34200 0 ACST} + {719944200 37800 1 ACDT} + {731435400 34200 0 ACST} + {751998600 37800 1 ACDT} + {764094600 34200 0 ACST} + {783448200 37800 1 ACDT} + {796149000 34200 0 ACST} + {814897800 37800 1 ACDT} + {828203400 34200 0 ACST} + {846347400 37800 1 ACDT} + {859653000 34200 0 ACST} + {877797000 37800 1 ACDT} + {891102600 34200 0 ACST} + {909246600 37800 1 ACDT} + {922552200 34200 0 ACST} + {941301000 37800 1 ACDT} + {954001800 34200 0 ACST} + {972750600 37800 1 ACDT} + {985451400 34200 0 ACST} + {1004200200 37800 1 ACDT} + {1017505800 34200 0 ACST} + {1035649800 37800 1 ACDT} + {1048955400 34200 0 ACST} + {1067099400 37800 1 ACDT} + {1080405000 34200 0 ACST} + {1099153800 37800 1 ACDT} + {1111854600 34200 0 ACST} + {1130603400 37800 1 ACDT} + {1143909000 34200 0 ACST} + {1162053000 37800 1 ACDT} + {1174753800 34200 0 ACST} + {1193502600 37800 1 ACDT} + {1207413000 34200 0 ACST} + {1223137800 37800 1 ACDT} + {1238862600 34200 0 ACST} + {1254587400 37800 1 ACDT} + {1270312200 34200 0 ACST} + {1286037000 37800 1 ACDT} + {1301761800 34200 0 ACST} + {1317486600 37800 1 ACDT} + {1333211400 34200 0 ACST} + {1349541000 37800 1 ACDT} + {1365265800 34200 0 ACST} + {1380990600 37800 1 ACDT} + {1396715400 34200 0 ACST} + {1412440200 37800 1 ACDT} + {1428165000 34200 0 ACST} + {1443889800 37800 1 ACDT} + {1459614600 34200 0 ACST} + {1475339400 37800 1 ACDT} + {1491064200 34200 0 ACST} + {1506789000 37800 1 ACDT} + {1522513800 34200 0 ACST} + {1538843400 37800 1 ACDT} + {1554568200 34200 0 ACST} + {1570293000 37800 1 ACDT} + {1586017800 34200 0 ACST} + {1601742600 37800 1 ACDT} + {1617467400 34200 0 ACST} + {1633192200 37800 1 ACDT} + {1648917000 34200 0 ACST} + {1664641800 37800 1 ACDT} + {1680366600 34200 0 ACST} + {1696091400 37800 1 ACDT} + {1712421000 34200 0 ACST} + {1728145800 37800 1 ACDT} + {1743870600 34200 0 ACST} + {1759595400 37800 1 ACDT} + {1775320200 34200 0 ACST} + {1791045000 37800 1 ACDT} + {1806769800 34200 0 ACST} + {1822494600 37800 1 ACDT} + {1838219400 34200 0 ACST} + {1853944200 37800 1 ACDT} + {1869669000 34200 0 ACST} + {1885998600 37800 1 ACDT} + {1901723400 34200 0 ACST} + {1917448200 37800 1 ACDT} + {1933173000 34200 0 ACST} + {1948897800 37800 1 ACDT} + {1964622600 34200 0 ACST} + {1980347400 37800 1 ACDT} + {1996072200 34200 0 ACST} + {2011797000 37800 1 ACDT} + {2027521800 34200 0 ACST} + {2043246600 37800 1 ACDT} + {2058971400 34200 0 ACST} + {2075301000 37800 1 ACDT} + {2091025800 34200 0 ACST} + {2106750600 37800 1 ACDT} + {2122475400 34200 0 ACST} + {2138200200 37800 1 ACDT} + {2153925000 34200 0 ACST} + {2169649800 37800 1 ACDT} + {2185374600 34200 0 ACST} + {2201099400 37800 1 ACDT} + {2216824200 34200 0 ACST} + {2233153800 37800 1 ACDT} + {2248878600 34200 0 ACST} + {2264603400 37800 1 ACDT} + {2280328200 34200 0 ACST} + {2296053000 37800 1 ACDT} + {2311777800 34200 0 ACST} + {2327502600 37800 1 ACDT} + {2343227400 34200 0 ACST} + {2358952200 37800 1 ACDT} + {2374677000 34200 0 ACST} + {2390401800 37800 1 ACDT} + {2406126600 34200 0 ACST} + {2422456200 37800 1 ACDT} + {2438181000 34200 0 ACST} + {2453905800 37800 1 ACDT} + {2469630600 34200 0 ACST} + {2485355400 37800 1 ACDT} + {2501080200 34200 0 ACST} + {2516805000 37800 1 ACDT} + {2532529800 34200 0 ACST} + {2548254600 37800 1 ACDT} + {2563979400 34200 0 ACST} + {2579704200 37800 1 ACDT} + {2596033800 34200 0 ACST} + {2611758600 37800 1 ACDT} + {2627483400 34200 0 ACST} + {2643208200 37800 1 ACDT} + {2658933000 34200 0 ACST} + {2674657800 37800 1 ACDT} + {2690382600 34200 0 ACST} + {2706107400 37800 1 ACDT} + {2721832200 34200 0 ACST} + {2737557000 37800 1 ACDT} + {2753281800 34200 0 ACST} + {2769611400 37800 1 ACDT} + {2785336200 34200 0 ACST} + {2801061000 37800 1 ACDT} + {2816785800 34200 0 ACST} + {2832510600 37800 1 ACDT} + {2848235400 34200 0 ACST} + {2863960200 37800 1 ACDT} + {2879685000 34200 0 ACST} + {2895409800 37800 1 ACDT} + {2911134600 34200 0 ACST} + {2926859400 37800 1 ACDT} + {2942584200 34200 0 ACST} + {2958913800 37800 1 ACDT} + {2974638600 34200 0 ACST} + {2990363400 37800 1 ACDT} + {3006088200 34200 0 ACST} + {3021813000 37800 1 ACDT} + {3037537800 34200 0 ACST} + {3053262600 37800 1 ACDT} + {3068987400 34200 0 ACST} + {3084712200 37800 1 ACDT} + {3100437000 34200 0 ACST} + {3116766600 37800 1 ACDT} + {3132491400 34200 0 ACST} + {3148216200 37800 1 ACDT} + {3163941000 34200 0 ACST} + {3179665800 37800 1 ACDT} + {3195390600 34200 0 ACST} + {3211115400 37800 1 ACDT} + {3226840200 34200 0 ACST} + {3242565000 37800 1 ACDT} + {3258289800 34200 0 ACST} + {3274014600 37800 1 ACDT} + {3289739400 34200 0 ACST} + {3306069000 37800 1 ACDT} + {3321793800 34200 0 ACST} + {3337518600 37800 1 ACDT} + {3353243400 34200 0 ACST} + {3368968200 37800 1 ACDT} + {3384693000 34200 0 ACST} + {3400417800 37800 1 ACDT} + {3416142600 34200 0 ACST} + {3431867400 37800 1 ACDT} + {3447592200 34200 0 ACST} + {3463317000 37800 1 ACDT} + {3479646600 34200 0 ACST} + {3495371400 37800 1 ACDT} + {3511096200 34200 0 ACST} + {3526821000 37800 1 ACDT} + {3542545800 34200 0 ACST} + {3558270600 37800 1 ACDT} + {3573995400 34200 0 ACST} + {3589720200 37800 1 ACDT} + {3605445000 34200 0 ACST} + {3621169800 37800 1 ACDT} + {3636894600 34200 0 ACST} + {3653224200 37800 1 ACDT} + {3668949000 34200 0 ACST} + {3684673800 37800 1 ACDT} + {3700398600 34200 0 ACST} + {3716123400 37800 1 ACDT} + {3731848200 34200 0 ACST} + {3747573000 37800 1 ACDT} + {3763297800 34200 0 ACST} + {3779022600 37800 1 ACDT} + {3794747400 34200 0 ACST} + {3810472200 37800 1 ACDT} + {3826197000 34200 0 ACST} + {3842526600 37800 1 ACDT} + {3858251400 34200 0 ACST} + {3873976200 37800 1 ACDT} + {3889701000 34200 0 ACST} + {3905425800 37800 1 ACDT} + {3921150600 34200 0 ACST} + {3936875400 37800 1 ACDT} + {3952600200 34200 0 ACST} + {3968325000 37800 1 ACDT} + {3984049800 34200 0 ACST} + {4000379400 37800 1 ACDT} + {4016104200 34200 0 ACST} + {4031829000 37800 1 ACDT} + {4047553800 34200 0 ACST} + {4063278600 37800 1 ACDT} + {4079003400 34200 0 ACST} + {4094728200 37800 1 ACDT} } diff --git a/library/tzdata/Australia/Brisbane b/library/tzdata/Australia/Brisbane index fe6d154..8422ae6 100644 --- a/library/tzdata/Australia/Brisbane +++ b/library/tzdata/Australia/Brisbane @@ -2,22 +2,22 @@ set TZData(:Australia/Brisbane) { {-9223372036854775808 36728 0 LMT} - {-2366791928 36000 0 EST} - {-1672567140 39600 1 EST} - {-1665392400 36000 0 EST} - {-883641600 39600 1 EST} - {-876128400 36000 0 EST} - {-860400000 39600 1 EST} - {-844678800 36000 0 EST} - {-828345600 39600 1 EST} - {-813229200 36000 0 EST} - {31500000 36000 0 EST} - {57686400 39600 1 EST} - {67968000 36000 0 EST} - {625593600 39600 1 EST} - {636480000 36000 0 EST} - {657043200 39600 1 EST} - {667929600 36000 0 EST} - {688492800 39600 1 EST} - {699379200 36000 0 EST} + {-2366791928 36000 0 AEST} + {-1672567140 39600 1 AEDT} + {-1665392400 36000 0 AEST} + {-883641600 39600 1 AEDT} + {-876128400 36000 0 AEST} + {-860400000 39600 1 AEDT} + {-844678800 36000 0 AEST} + {-828345600 39600 1 AEDT} + {-813229200 36000 0 AEST} + {31500000 36000 0 AEST} + {57686400 39600 1 AEDT} + {67968000 36000 0 AEST} + {625593600 39600 1 AEDT} + {636480000 36000 0 AEST} + {657043200 39600 1 AEDT} + {667929600 36000 0 AEST} + {688492800 39600 1 AEDT} + {699379200 36000 0 AEST} } diff --git a/library/tzdata/Australia/Broken_Hill b/library/tzdata/Australia/Broken_Hill index 35cbb7e..c428061 100644 --- a/library/tzdata/Australia/Broken_Hill +++ b/library/tzdata/Australia/Broken_Hill @@ -2,274 +2,274 @@ set TZData(:Australia/Broken_Hill) { {-9223372036854775808 33948 0 LMT} - {-2364110748 36000 0 EST} - {-2314951200 32400 0 CST} - {-2230189200 34200 0 CST} - {-1672565340 37800 1 CST} - {-1665390600 34200 0 CST} - {-883639800 37800 1 CST} - {-876126600 34200 0 CST} - {-860398200 37800 1 CST} - {-844677000 34200 0 CST} - {-828343800 37800 1 CST} - {-813227400 34200 0 CST} - {31501800 34200 0 CST} - {57688200 37800 1 CST} - {67969800 34200 0 CST} - {89137800 37800 1 CST} - {100024200 34200 0 CST} - {120587400 37800 1 CST} - {131473800 34200 0 CST} - {152037000 37800 1 CST} - {162923400 34200 0 CST} - {183486600 37800 1 CST} - {194977800 34200 0 CST} - {215541000 37800 1 CST} - {226427400 34200 0 CST} - {246990600 37800 1 CST} - {257877000 34200 0 CST} - {278440200 37800 1 CST} - {289326600 34200 0 CST} - {309889800 37800 1 CST} - {320776200 34200 0 CST} - {341339400 37800 1 CST} - {352225800 34200 0 CST} - {372789000 37800 1 CST} - {386699400 34200 0 CST} - {404843400 37800 1 CST} - {415729800 34200 0 CST} - {436293000 37800 1 CST} - {447179400 34200 0 CST} - {467742600 37800 1 CST} - {478629000 34200 0 CST} - {499192200 37800 1 CST} - {511288200 34200 0 CST} - {530037000 37800 1 CST} - {542737800 34200 0 CST} - {562091400 37800 1 CST} - {574792200 34200 0 CST} - {594145800 37800 1 CST} - {606241800 34200 0 CST} - {625595400 37800 1 CST} - {636481800 34200 0 CST} - {657045000 37800 1 CST} - {667931400 34200 0 CST} - {688494600 37800 1 CST} - {699381000 34200 0 CST} - {719944200 37800 1 CST} - {731435400 34200 0 CST} - {751998600 37800 1 CST} - {762885000 34200 0 CST} - {783448200 37800 1 CST} - {794334600 34200 0 CST} - {814897800 37800 1 CST} - {828203400 34200 0 CST} - {846347400 37800 1 CST} - {859653000 34200 0 CST} - {877797000 37800 1 CST} - {891102600 34200 0 CST} - {909246600 37800 1 CST} - {922552200 34200 0 CST} - {941301000 37800 1 CST} - {946647000 37800 0 CST} - {954001800 34200 0 CST} - {972750600 37800 1 CST} - {985451400 34200 0 CST} - {1004200200 37800 1 CST} - {1017505800 34200 0 CST} - {1035649800 37800 1 CST} - {1048955400 34200 0 CST} - {1067099400 37800 1 CST} - {1080405000 34200 0 CST} - {1099153800 37800 1 CST} - {1111854600 34200 0 CST} - {1130603400 37800 1 CST} - {1143909000 34200 0 CST} - {1162053000 37800 1 CST} - {1174753800 34200 0 CST} - {1193502600 37800 1 CST} - {1207413000 34200 0 CST} - {1223137800 37800 1 CST} - {1238862600 34200 0 CST} - {1254587400 37800 1 CST} - {1270312200 34200 0 CST} - {1286037000 37800 1 CST} - {1301761800 34200 0 CST} - {1317486600 37800 1 CST} - {1333211400 34200 0 CST} - {1349541000 37800 1 CST} - {1365265800 34200 0 CST} - {1380990600 37800 1 CST} - {1396715400 34200 0 CST} - {1412440200 37800 1 CST} - {1428165000 34200 0 CST} - {1443889800 37800 1 CST} - {1459614600 34200 0 CST} - {1475339400 37800 1 CST} - {1491064200 34200 0 CST} - {1506789000 37800 1 CST} - {1522513800 34200 0 CST} - {1538843400 37800 1 CST} - {1554568200 34200 0 CST} - {1570293000 37800 1 CST} - {1586017800 34200 0 CST} - {1601742600 37800 1 CST} - {1617467400 34200 0 CST} - {1633192200 37800 1 CST} - {1648917000 34200 0 CST} - {1664641800 37800 1 CST} - {1680366600 34200 0 CST} - {1696091400 37800 1 CST} - {1712421000 34200 0 CST} - {1728145800 37800 1 CST} - {1743870600 34200 0 CST} - {1759595400 37800 1 CST} - {1775320200 34200 0 CST} - {1791045000 37800 1 CST} - {1806769800 34200 0 CST} - {1822494600 37800 1 CST} - {1838219400 34200 0 CST} - {1853944200 37800 1 CST} - {1869669000 34200 0 CST} - {1885998600 37800 1 CST} - {1901723400 34200 0 CST} - {1917448200 37800 1 CST} - {1933173000 34200 0 CST} - {1948897800 37800 1 CST} - {1964622600 34200 0 CST} - {1980347400 37800 1 CST} - {1996072200 34200 0 CST} - {2011797000 37800 1 CST} - {2027521800 34200 0 CST} - {2043246600 37800 1 CST} - {2058971400 34200 0 CST} - {2075301000 37800 1 CST} - {2091025800 34200 0 CST} - {2106750600 37800 1 CST} - {2122475400 34200 0 CST} - {2138200200 37800 1 CST} - {2153925000 34200 0 CST} - {2169649800 37800 1 CST} - {2185374600 34200 0 CST} - {2201099400 37800 1 CST} - {2216824200 34200 0 CST} - {2233153800 37800 1 CST} - {2248878600 34200 0 CST} - {2264603400 37800 1 CST} - {2280328200 34200 0 CST} - {2296053000 37800 1 CST} - {2311777800 34200 0 CST} - {2327502600 37800 1 CST} - {2343227400 34200 0 CST} - {2358952200 37800 1 CST} - {2374677000 34200 0 CST} - {2390401800 37800 1 CST} - {2406126600 34200 0 CST} - {2422456200 37800 1 CST} - {2438181000 34200 0 CST} - {2453905800 37800 1 CST} - {2469630600 34200 0 CST} - {2485355400 37800 1 CST} - {2501080200 34200 0 CST} - {2516805000 37800 1 CST} - {2532529800 34200 0 CST} - {2548254600 37800 1 CST} - {2563979400 34200 0 CST} - {2579704200 37800 1 CST} - {2596033800 34200 0 CST} - {2611758600 37800 1 CST} - {2627483400 34200 0 CST} - {2643208200 37800 1 CST} - {2658933000 34200 0 CST} - {2674657800 37800 1 CST} - {2690382600 34200 0 CST} - {2706107400 37800 1 CST} - {2721832200 34200 0 CST} - {2737557000 37800 1 CST} - {2753281800 34200 0 CST} - {2769611400 37800 1 CST} - {2785336200 34200 0 CST} - {2801061000 37800 1 CST} - {2816785800 34200 0 CST} - {2832510600 37800 1 CST} - {2848235400 34200 0 CST} - {2863960200 37800 1 CST} - {2879685000 34200 0 CST} - {2895409800 37800 1 CST} - {2911134600 34200 0 CST} - {2926859400 37800 1 CST} - {2942584200 34200 0 CST} - {2958913800 37800 1 CST} - {2974638600 34200 0 CST} - {2990363400 37800 1 CST} - {3006088200 34200 0 CST} - {3021813000 37800 1 CST} - {3037537800 34200 0 CST} - {3053262600 37800 1 CST} - {3068987400 34200 0 CST} - {3084712200 37800 1 CST} - {3100437000 34200 0 CST} - {3116766600 37800 1 CST} - {3132491400 34200 0 CST} - {3148216200 37800 1 CST} - {3163941000 34200 0 CST} - {3179665800 37800 1 CST} - {3195390600 34200 0 CST} - {3211115400 37800 1 CST} - {3226840200 34200 0 CST} - {3242565000 37800 1 CST} - {3258289800 34200 0 CST} - {3274014600 37800 1 CST} - {3289739400 34200 0 CST} - {3306069000 37800 1 CST} - {3321793800 34200 0 CST} - {3337518600 37800 1 CST} - {3353243400 34200 0 CST} - {3368968200 37800 1 CST} - {3384693000 34200 0 CST} - {3400417800 37800 1 CST} - {3416142600 34200 0 CST} - {3431867400 37800 1 CST} - {3447592200 34200 0 CST} - {3463317000 37800 1 CST} - {3479646600 34200 0 CST} - {3495371400 37800 1 CST} - {3511096200 34200 0 CST} - {3526821000 37800 1 CST} - {3542545800 34200 0 CST} - {3558270600 37800 1 CST} - {3573995400 34200 0 CST} - {3589720200 37800 1 CST} - {3605445000 34200 0 CST} - {3621169800 37800 1 CST} - {3636894600 34200 0 CST} - {3653224200 37800 1 CST} - {3668949000 34200 0 CST} - {3684673800 37800 1 CST} - {3700398600 34200 0 CST} - {3716123400 37800 1 CST} - {3731848200 34200 0 CST} - {3747573000 37800 1 CST} - {3763297800 34200 0 CST} - {3779022600 37800 1 CST} - {3794747400 34200 0 CST} - {3810472200 37800 1 CST} - {3826197000 34200 0 CST} - {3842526600 37800 1 CST} - {3858251400 34200 0 CST} - {3873976200 37800 1 CST} - {3889701000 34200 0 CST} - {3905425800 37800 1 CST} - {3921150600 34200 0 CST} - {3936875400 37800 1 CST} - {3952600200 34200 0 CST} - {3968325000 37800 1 CST} - {3984049800 34200 0 CST} - {4000379400 37800 1 CST} - {4016104200 34200 0 CST} - {4031829000 37800 1 CST} - {4047553800 34200 0 CST} - {4063278600 37800 1 CST} - {4079003400 34200 0 CST} - {4094728200 37800 1 CST} + {-2364110748 36000 0 AEST} + {-2314951200 32400 0 ACST} + {-2230189200 34200 0 ACST} + {-1672565340 37800 1 ACDT} + {-1665390600 34200 0 ACST} + {-883639800 37800 1 ACDT} + {-876126600 34200 0 ACST} + {-860398200 37800 1 ACDT} + {-844677000 34200 0 ACST} + {-828343800 37800 1 ACDT} + {-813227400 34200 0 ACST} + {31501800 34200 0 ACST} + {57688200 37800 1 ACDT} + {67969800 34200 0 ACST} + {89137800 37800 1 ACDT} + {100024200 34200 0 ACST} + {120587400 37800 1 ACDT} + {131473800 34200 0 ACST} + {152037000 37800 1 ACDT} + {162923400 34200 0 ACST} + {183486600 37800 1 ACDT} + {194977800 34200 0 ACST} + {215541000 37800 1 ACDT} + {226427400 34200 0 ACST} + {246990600 37800 1 ACDT} + {257877000 34200 0 ACST} + {278440200 37800 1 ACDT} + {289326600 34200 0 ACST} + {309889800 37800 1 ACDT} + {320776200 34200 0 ACST} + {341339400 37800 1 ACDT} + {352225800 34200 0 ACST} + {372789000 37800 1 ACDT} + {386699400 34200 0 ACST} + {404843400 37800 1 ACDT} + {415729800 34200 0 ACST} + {436293000 37800 1 ACDT} + {447179400 34200 0 ACST} + {467742600 37800 1 ACDT} + {478629000 34200 0 ACST} + {499192200 37800 1 ACDT} + {511288200 34200 0 ACST} + {530037000 37800 1 ACDT} + {542737800 34200 0 ACST} + {562091400 37800 1 ACDT} + {574792200 34200 0 ACST} + {594145800 37800 1 ACDT} + {606241800 34200 0 ACST} + {625595400 37800 1 ACDT} + {636481800 34200 0 ACST} + {657045000 37800 1 ACDT} + {667931400 34200 0 ACST} + {688494600 37800 1 ACDT} + {699381000 34200 0 ACST} + {719944200 37800 1 ACDT} + {731435400 34200 0 ACST} + {751998600 37800 1 ACDT} + {762885000 34200 0 ACST} + {783448200 37800 1 ACDT} + {794334600 34200 0 ACST} + {814897800 37800 1 ACDT} + {828203400 34200 0 ACST} + {846347400 37800 1 ACDT} + {859653000 34200 0 ACST} + {877797000 37800 1 ACDT} + {891102600 34200 0 ACST} + {909246600 37800 1 ACDT} + {922552200 34200 0 ACST} + {941301000 37800 1 ACDT} + {946647000 37800 0 ACST} + {954001800 34200 0 ACST} + {972750600 37800 1 ACDT} + {985451400 34200 0 ACST} + {1004200200 37800 1 ACDT} + {1017505800 34200 0 ACST} + {1035649800 37800 1 ACDT} + {1048955400 34200 0 ACST} + {1067099400 37800 1 ACDT} + {1080405000 34200 0 ACST} + {1099153800 37800 1 ACDT} + {1111854600 34200 0 ACST} + {1130603400 37800 1 ACDT} + {1143909000 34200 0 ACST} + {1162053000 37800 1 ACDT} + {1174753800 34200 0 ACST} + {1193502600 37800 1 ACDT} + {1207413000 34200 0 ACST} + {1223137800 37800 1 ACDT} + {1238862600 34200 0 ACST} + {1254587400 37800 1 ACDT} + {1270312200 34200 0 ACST} + {1286037000 37800 1 ACDT} + {1301761800 34200 0 ACST} + {1317486600 37800 1 ACDT} + {1333211400 34200 0 ACST} + {1349541000 37800 1 ACDT} + {1365265800 34200 0 ACST} + {1380990600 37800 1 ACDT} + {1396715400 34200 0 ACST} + {1412440200 37800 1 ACDT} + {1428165000 34200 0 ACST} + {1443889800 37800 1 ACDT} + {1459614600 34200 0 ACST} + {1475339400 37800 1 ACDT} + {1491064200 34200 0 ACST} + {1506789000 37800 1 ACDT} + {1522513800 34200 0 ACST} + {1538843400 37800 1 ACDT} + {1554568200 34200 0 ACST} + {1570293000 37800 1 ACDT} + {1586017800 34200 0 ACST} + {1601742600 37800 1 ACDT} + {1617467400 34200 0 ACST} + {1633192200 37800 1 ACDT} + {1648917000 34200 0 ACST} + {1664641800 37800 1 ACDT} + {1680366600 34200 0 ACST} + {1696091400 37800 1 ACDT} + {1712421000 34200 0 ACST} + {1728145800 37800 1 ACDT} + {1743870600 34200 0 ACST} + {1759595400 37800 1 ACDT} + {1775320200 34200 0 ACST} + {1791045000 37800 1 ACDT} + {1806769800 34200 0 ACST} + {1822494600 37800 1 ACDT} + {1838219400 34200 0 ACST} + {1853944200 37800 1 ACDT} + {1869669000 34200 0 ACST} + {1885998600 37800 1 ACDT} + {1901723400 34200 0 ACST} + {1917448200 37800 1 ACDT} + {1933173000 34200 0 ACST} + {1948897800 37800 1 ACDT} + {1964622600 34200 0 ACST} + {1980347400 37800 1 ACDT} + {1996072200 34200 0 ACST} + {2011797000 37800 1 ACDT} + {2027521800 34200 0 ACST} + {2043246600 37800 1 ACDT} + {2058971400 34200 0 ACST} + {2075301000 37800 1 ACDT} + {2091025800 34200 0 ACST} + {2106750600 37800 1 ACDT} + {2122475400 34200 0 ACST} + {2138200200 37800 1 ACDT} + {2153925000 34200 0 ACST} + {2169649800 37800 1 ACDT} + {2185374600 34200 0 ACST} + {2201099400 37800 1 ACDT} + {2216824200 34200 0 ACST} + {2233153800 37800 1 ACDT} + {2248878600 34200 0 ACST} + {2264603400 37800 1 ACDT} + {2280328200 34200 0 ACST} + {2296053000 37800 1 ACDT} + {2311777800 34200 0 ACST} + {2327502600 37800 1 ACDT} + {2343227400 34200 0 ACST} + {2358952200 37800 1 ACDT} + {2374677000 34200 0 ACST} + {2390401800 37800 1 ACDT} + {2406126600 34200 0 ACST} + {2422456200 37800 1 ACDT} + {2438181000 34200 0 ACST} + {2453905800 37800 1 ACDT} + {2469630600 34200 0 ACST} + {2485355400 37800 1 ACDT} + {2501080200 34200 0 ACST} + {2516805000 37800 1 ACDT} + {2532529800 34200 0 ACST} + {2548254600 37800 1 ACDT} + {2563979400 34200 0 ACST} + {2579704200 37800 1 ACDT} + {2596033800 34200 0 ACST} + {2611758600 37800 1 ACDT} + {2627483400 34200 0 ACST} + {2643208200 37800 1 ACDT} + {2658933000 34200 0 ACST} + {2674657800 37800 1 ACDT} + {2690382600 34200 0 ACST} + {2706107400 37800 1 ACDT} + {2721832200 34200 0 ACST} + {2737557000 37800 1 ACDT} + {2753281800 34200 0 ACST} + {2769611400 37800 1 ACDT} + {2785336200 34200 0 ACST} + {2801061000 37800 1 ACDT} + {2816785800 34200 0 ACST} + {2832510600 37800 1 ACDT} + {2848235400 34200 0 ACST} + {2863960200 37800 1 ACDT} + {2879685000 34200 0 ACST} + {2895409800 37800 1 ACDT} + {2911134600 34200 0 ACST} + {2926859400 37800 1 ACDT} + {2942584200 34200 0 ACST} + {2958913800 37800 1 ACDT} + {2974638600 34200 0 ACST} + {2990363400 37800 1 ACDT} + {3006088200 34200 0 ACST} + {3021813000 37800 1 ACDT} + {3037537800 34200 0 ACST} + {3053262600 37800 1 ACDT} + {3068987400 34200 0 ACST} + {3084712200 37800 1 ACDT} + {3100437000 34200 0 ACST} + {3116766600 37800 1 ACDT} + {3132491400 34200 0 ACST} + {3148216200 37800 1 ACDT} + {3163941000 34200 0 ACST} + {3179665800 37800 1 ACDT} + {3195390600 34200 0 ACST} + {3211115400 37800 1 ACDT} + {3226840200 34200 0 ACST} + {3242565000 37800 1 ACDT} + {3258289800 34200 0 ACST} + {3274014600 37800 1 ACDT} + {3289739400 34200 0 ACST} + {3306069000 37800 1 ACDT} + {3321793800 34200 0 ACST} + {3337518600 37800 1 ACDT} + {3353243400 34200 0 ACST} + {3368968200 37800 1 ACDT} + {3384693000 34200 0 ACST} + {3400417800 37800 1 ACDT} + {3416142600 34200 0 ACST} + {3431867400 37800 1 ACDT} + {3447592200 34200 0 ACST} + {3463317000 37800 1 ACDT} + {3479646600 34200 0 ACST} + {3495371400 37800 1 ACDT} + {3511096200 34200 0 ACST} + {3526821000 37800 1 ACDT} + {3542545800 34200 0 ACST} + {3558270600 37800 1 ACDT} + {3573995400 34200 0 ACST} + {3589720200 37800 1 ACDT} + {3605445000 34200 0 ACST} + {3621169800 37800 1 ACDT} + {3636894600 34200 0 ACST} + {3653224200 37800 1 ACDT} + {3668949000 34200 0 ACST} + {3684673800 37800 1 ACDT} + {3700398600 34200 0 ACST} + {3716123400 37800 1 ACDT} + {3731848200 34200 0 ACST} + {3747573000 37800 1 ACDT} + {3763297800 34200 0 ACST} + {3779022600 37800 1 ACDT} + {3794747400 34200 0 ACST} + {3810472200 37800 1 ACDT} + {3826197000 34200 0 ACST} + {3842526600 37800 1 ACDT} + {3858251400 34200 0 ACST} + {3873976200 37800 1 ACDT} + {3889701000 34200 0 ACST} + {3905425800 37800 1 ACDT} + {3921150600 34200 0 ACST} + {3936875400 37800 1 ACDT} + {3952600200 34200 0 ACST} + {3968325000 37800 1 ACDT} + {3984049800 34200 0 ACST} + {4000379400 37800 1 ACDT} + {4016104200 34200 0 ACST} + {4031829000 37800 1 ACDT} + {4047553800 34200 0 ACST} + {4063278600 37800 1 ACDT} + {4079003400 34200 0 ACST} + {4094728200 37800 1 ACDT} } diff --git a/library/tzdata/Australia/Currie b/library/tzdata/Australia/Currie index ae6d1f0..936327b 100644 --- a/library/tzdata/Australia/Currie +++ b/library/tzdata/Australia/Currie @@ -2,272 +2,272 @@ set TZData(:Australia/Currie) { {-9223372036854775808 34528 0 LMT} - {-2345794528 36000 0 EST} - {-1680508800 39600 1 EST} - {-1669892400 39600 0 EST} - {-1665392400 36000 0 EST} - {-883641600 39600 1 EST} - {-876128400 36000 0 EST} - {-860400000 39600 1 EST} - {-844678800 36000 0 EST} - {-828345600 39600 1 EST} - {-813229200 36000 0 EST} - {47138400 36000 0 EST} - {57686400 39600 1 EST} - {67968000 36000 0 EST} - {89136000 39600 1 EST} - {100022400 36000 0 EST} - {120585600 39600 1 EST} - {131472000 36000 0 EST} - {152035200 39600 1 EST} - {162921600 36000 0 EST} - {183484800 39600 1 EST} - {194976000 36000 0 EST} - {215539200 39600 1 EST} - {226425600 36000 0 EST} - {246988800 39600 1 EST} - {257875200 36000 0 EST} - {278438400 39600 1 EST} - {289324800 36000 0 EST} - {309888000 39600 1 EST} - {320774400 36000 0 EST} - {341337600 39600 1 EST} - {352224000 36000 0 EST} - {372787200 39600 1 EST} - {386092800 36000 0 EST} - {404841600 39600 1 EST} - {417542400 36000 0 EST} - {436291200 39600 1 EST} - {447177600 36000 0 EST} - {467740800 39600 1 EST} - {478627200 36000 0 EST} - {499190400 39600 1 EST} - {510076800 36000 0 EST} - {530035200 39600 1 EST} - {542736000 36000 0 EST} - {562089600 39600 1 EST} - {574790400 36000 0 EST} - {594144000 39600 1 EST} - {606240000 36000 0 EST} - {625593600 39600 1 EST} - {637689600 36000 0 EST} - {657043200 39600 1 EST} - {670348800 36000 0 EST} - {686678400 39600 1 EST} - {701798400 36000 0 EST} - {718128000 39600 1 EST} - {733248000 36000 0 EST} - {749577600 39600 1 EST} - {764697600 36000 0 EST} - {781027200 39600 1 EST} - {796147200 36000 0 EST} - {812476800 39600 1 EST} - {828201600 36000 0 EST} - {844531200 39600 1 EST} - {859651200 36000 0 EST} - {875980800 39600 1 EST} - {891100800 36000 0 EST} - {907430400 39600 1 EST} - {922550400 36000 0 EST} - {938880000 39600 1 EST} - {954000000 36000 0 EST} - {967305600 39600 1 EST} - {985449600 36000 0 EST} - {1002384000 39600 1 EST} - {1017504000 36000 0 EST} - {1033833600 39600 1 EST} - {1048953600 36000 0 EST} - {1065283200 39600 1 EST} - {1080403200 36000 0 EST} - {1096732800 39600 1 EST} - {1111852800 36000 0 EST} - {1128182400 39600 1 EST} - {1143907200 36000 0 EST} - {1159632000 39600 1 EST} - {1174752000 36000 0 EST} - {1191686400 39600 1 EST} - {1207411200 36000 0 EST} - {1223136000 39600 1 EST} - {1238860800 36000 0 EST} - {1254585600 39600 1 EST} - {1270310400 36000 0 EST} - {1286035200 39600 1 EST} - {1301760000 36000 0 EST} - {1317484800 39600 1 EST} - {1333209600 36000 0 EST} - {1349539200 39600 1 EST} - {1365264000 36000 0 EST} - {1380988800 39600 1 EST} - {1396713600 36000 0 EST} - {1412438400 39600 1 EST} - {1428163200 36000 0 EST} - {1443888000 39600 1 EST} - {1459612800 36000 0 EST} - {1475337600 39600 1 EST} - {1491062400 36000 0 EST} - {1506787200 39600 1 EST} - {1522512000 36000 0 EST} - {1538841600 39600 1 EST} - {1554566400 36000 0 EST} - {1570291200 39600 1 EST} - {1586016000 36000 0 EST} - {1601740800 39600 1 EST} - {1617465600 36000 0 EST} - {1633190400 39600 1 EST} - {1648915200 36000 0 EST} - {1664640000 39600 1 EST} - {1680364800 36000 0 EST} - {1696089600 39600 1 EST} - {1712419200 36000 0 EST} - {1728144000 39600 1 EST} - {1743868800 36000 0 EST} - {1759593600 39600 1 EST} - {1775318400 36000 0 EST} - {1791043200 39600 1 EST} - {1806768000 36000 0 EST} - {1822492800 39600 1 EST} - {1838217600 36000 0 EST} - {1853942400 39600 1 EST} - {1869667200 36000 0 EST} - {1885996800 39600 1 EST} - {1901721600 36000 0 EST} - {1917446400 39600 1 EST} - {1933171200 36000 0 EST} - {1948896000 39600 1 EST} - {1964620800 36000 0 EST} - {1980345600 39600 1 EST} - {1996070400 36000 0 EST} - {2011795200 39600 1 EST} - {2027520000 36000 0 EST} - {2043244800 39600 1 EST} - {2058969600 36000 0 EST} - {2075299200 39600 1 EST} - {2091024000 36000 0 EST} - {2106748800 39600 1 EST} - {2122473600 36000 0 EST} - {2138198400 39600 1 EST} - {2153923200 36000 0 EST} - {2169648000 39600 1 EST} - {2185372800 36000 0 EST} - {2201097600 39600 1 EST} - {2216822400 36000 0 EST} - {2233152000 39600 1 EST} - {2248876800 36000 0 EST} - {2264601600 39600 1 EST} - {2280326400 36000 0 EST} - {2296051200 39600 1 EST} - {2311776000 36000 0 EST} - {2327500800 39600 1 EST} - {2343225600 36000 0 EST} - {2358950400 39600 1 EST} - {2374675200 36000 0 EST} - {2390400000 39600 1 EST} - {2406124800 36000 0 EST} - {2422454400 39600 1 EST} - {2438179200 36000 0 EST} - {2453904000 39600 1 EST} - {2469628800 36000 0 EST} - {2485353600 39600 1 EST} - {2501078400 36000 0 EST} - {2516803200 39600 1 EST} - {2532528000 36000 0 EST} - {2548252800 39600 1 EST} - {2563977600 36000 0 EST} - {2579702400 39600 1 EST} - {2596032000 36000 0 EST} - {2611756800 39600 1 EST} - {2627481600 36000 0 EST} - {2643206400 39600 1 EST} - {2658931200 36000 0 EST} - {2674656000 39600 1 EST} - {2690380800 36000 0 EST} - {2706105600 39600 1 EST} - {2721830400 36000 0 EST} - {2737555200 39600 1 EST} - {2753280000 36000 0 EST} - {2769609600 39600 1 EST} - {2785334400 36000 0 EST} - {2801059200 39600 1 EST} - {2816784000 36000 0 EST} - {2832508800 39600 1 EST} - {2848233600 36000 0 EST} - {2863958400 39600 1 EST} - {2879683200 36000 0 EST} - {2895408000 39600 1 EST} - {2911132800 36000 0 EST} - {2926857600 39600 1 EST} - {2942582400 36000 0 EST} - {2958912000 39600 1 EST} - {2974636800 36000 0 EST} - {2990361600 39600 1 EST} - {3006086400 36000 0 EST} - {3021811200 39600 1 EST} - {3037536000 36000 0 EST} - {3053260800 39600 1 EST} - {3068985600 36000 0 EST} - {3084710400 39600 1 EST} - {3100435200 36000 0 EST} - {3116764800 39600 1 EST} - {3132489600 36000 0 EST} - {3148214400 39600 1 EST} - {3163939200 36000 0 EST} - {3179664000 39600 1 EST} - {3195388800 36000 0 EST} - {3211113600 39600 1 EST} - {3226838400 36000 0 EST} - {3242563200 39600 1 EST} - {3258288000 36000 0 EST} - {3274012800 39600 1 EST} - {3289737600 36000 0 EST} - {3306067200 39600 1 EST} - {3321792000 36000 0 EST} - {3337516800 39600 1 EST} - {3353241600 36000 0 EST} - {3368966400 39600 1 EST} - {3384691200 36000 0 EST} - {3400416000 39600 1 EST} - {3416140800 36000 0 EST} - {3431865600 39600 1 EST} - {3447590400 36000 0 EST} - {3463315200 39600 1 EST} - {3479644800 36000 0 EST} - {3495369600 39600 1 EST} - {3511094400 36000 0 EST} - {3526819200 39600 1 EST} - {3542544000 36000 0 EST} - {3558268800 39600 1 EST} - {3573993600 36000 0 EST} - {3589718400 39600 1 EST} - {3605443200 36000 0 EST} - {3621168000 39600 1 EST} - {3636892800 36000 0 EST} - {3653222400 39600 1 EST} - {3668947200 36000 0 EST} - {3684672000 39600 1 EST} - {3700396800 36000 0 EST} - {3716121600 39600 1 EST} - {3731846400 36000 0 EST} - {3747571200 39600 1 EST} - {3763296000 36000 0 EST} - {3779020800 39600 1 EST} - {3794745600 36000 0 EST} - {3810470400 39600 1 EST} - {3826195200 36000 0 EST} - {3842524800 39600 1 EST} - {3858249600 36000 0 EST} - {3873974400 39600 1 EST} - {3889699200 36000 0 EST} - {3905424000 39600 1 EST} - {3921148800 36000 0 EST} - {3936873600 39600 1 EST} - {3952598400 36000 0 EST} - {3968323200 39600 1 EST} - {3984048000 36000 0 EST} - {4000377600 39600 1 EST} - {4016102400 36000 0 EST} - {4031827200 39600 1 EST} - {4047552000 36000 0 EST} - {4063276800 39600 1 EST} - {4079001600 36000 0 EST} - {4094726400 39600 1 EST} + {-2345794528 36000 0 AEST} + {-1680508800 39600 1 AEDT} + {-1669892400 39600 0 AEDT} + {-1665392400 36000 0 AEST} + {-883641600 39600 1 AEDT} + {-876128400 36000 0 AEST} + {-860400000 39600 1 AEDT} + {-844678800 36000 0 AEST} + {-828345600 39600 1 AEDT} + {-813229200 36000 0 AEST} + {47138400 36000 0 AEST} + {57686400 39600 1 AEDT} + {67968000 36000 0 AEST} + {89136000 39600 1 AEDT} + {100022400 36000 0 AEST} + {120585600 39600 1 AEDT} + {131472000 36000 0 AEST} + {152035200 39600 1 AEDT} + {162921600 36000 0 AEST} + {183484800 39600 1 AEDT} + {194976000 36000 0 AEST} + {215539200 39600 1 AEDT} + {226425600 36000 0 AEST} + {246988800 39600 1 AEDT} + {257875200 36000 0 AEST} + {278438400 39600 1 AEDT} + {289324800 36000 0 AEST} + {309888000 39600 1 AEDT} + {320774400 36000 0 AEST} + {341337600 39600 1 AEDT} + {352224000 36000 0 AEST} + {372787200 39600 1 AEDT} + {386092800 36000 0 AEST} + {404841600 39600 1 AEDT} + {417542400 36000 0 AEST} + {436291200 39600 1 AEDT} + {447177600 36000 0 AEST} + {467740800 39600 1 AEDT} + {478627200 36000 0 AEST} + {499190400 39600 1 AEDT} + {510076800 36000 0 AEST} + {530035200 39600 1 AEDT} + {542736000 36000 0 AEST} + {562089600 39600 1 AEDT} + {574790400 36000 0 AEST} + {594144000 39600 1 AEDT} + {606240000 36000 0 AEST} + {625593600 39600 1 AEDT} + {637689600 36000 0 AEST} + {657043200 39600 1 AEDT} + {670348800 36000 0 AEST} + {686678400 39600 1 AEDT} + {701798400 36000 0 AEST} + {718128000 39600 1 AEDT} + {733248000 36000 0 AEST} + {749577600 39600 1 AEDT} + {764697600 36000 0 AEST} + {781027200 39600 1 AEDT} + {796147200 36000 0 AEST} + {812476800 39600 1 AEDT} + {828201600 36000 0 AEST} + {844531200 39600 1 AEDT} + {859651200 36000 0 AEST} + {875980800 39600 1 AEDT} + {891100800 36000 0 AEST} + {907430400 39600 1 AEDT} + {922550400 36000 0 AEST} + {938880000 39600 1 AEDT} + {954000000 36000 0 AEST} + {967305600 39600 1 AEDT} + {985449600 36000 0 AEST} + {1002384000 39600 1 AEDT} + {1017504000 36000 0 AEST} + {1033833600 39600 1 AEDT} + {1048953600 36000 0 AEST} + {1065283200 39600 1 AEDT} + {1080403200 36000 0 AEST} + {1096732800 39600 1 AEDT} + {1111852800 36000 0 AEST} + {1128182400 39600 1 AEDT} + {1143907200 36000 0 AEST} + {1159632000 39600 1 AEDT} + {1174752000 36000 0 AEST} + {1191686400 39600 1 AEDT} + {1207411200 36000 0 AEST} + {1223136000 39600 1 AEDT} + {1238860800 36000 0 AEST} + {1254585600 39600 1 AEDT} + {1270310400 36000 0 AEST} + {1286035200 39600 1 AEDT} + {1301760000 36000 0 AEST} + {1317484800 39600 1 AEDT} + {1333209600 36000 0 AEST} + {1349539200 39600 1 AEDT} + {1365264000 36000 0 AEST} + {1380988800 39600 1 AEDT} + {1396713600 36000 0 AEST} + {1412438400 39600 1 AEDT} + {1428163200 36000 0 AEST} + {1443888000 39600 1 AEDT} + {1459612800 36000 0 AEST} + {1475337600 39600 1 AEDT} + {1491062400 36000 0 AEST} + {1506787200 39600 1 AEDT} + {1522512000 36000 0 AEST} + {1538841600 39600 1 AEDT} + {1554566400 36000 0 AEST} + {1570291200 39600 1 AEDT} + {1586016000 36000 0 AEST} + {1601740800 39600 1 AEDT} + {1617465600 36000 0 AEST} + {1633190400 39600 1 AEDT} + {1648915200 36000 0 AEST} + {1664640000 39600 1 AEDT} + {1680364800 36000 0 AEST} + {1696089600 39600 1 AEDT} + {1712419200 36000 0 AEST} + {1728144000 39600 1 AEDT} + {1743868800 36000 0 AEST} + {1759593600 39600 1 AEDT} + {1775318400 36000 0 AEST} + {1791043200 39600 1 AEDT} + {1806768000 36000 0 AEST} + {1822492800 39600 1 AEDT} + {1838217600 36000 0 AEST} + {1853942400 39600 1 AEDT} + {1869667200 36000 0 AEST} + {1885996800 39600 1 AEDT} + {1901721600 36000 0 AEST} + {1917446400 39600 1 AEDT} + {1933171200 36000 0 AEST} + {1948896000 39600 1 AEDT} + {1964620800 36000 0 AEST} + {1980345600 39600 1 AEDT} + {1996070400 36000 0 AEST} + {2011795200 39600 1 AEDT} + {2027520000 36000 0 AEST} + {2043244800 39600 1 AEDT} + {2058969600 36000 0 AEST} + {2075299200 39600 1 AEDT} + {2091024000 36000 0 AEST} + {2106748800 39600 1 AEDT} + {2122473600 36000 0 AEST} + {2138198400 39600 1 AEDT} + {2153923200 36000 0 AEST} + {2169648000 39600 1 AEDT} + {2185372800 36000 0 AEST} + {2201097600 39600 1 AEDT} + {2216822400 36000 0 AEST} + {2233152000 39600 1 AEDT} + {2248876800 36000 0 AEST} + {2264601600 39600 1 AEDT} + {2280326400 36000 0 AEST} + {2296051200 39600 1 AEDT} + {2311776000 36000 0 AEST} + {2327500800 39600 1 AEDT} + {2343225600 36000 0 AEST} + {2358950400 39600 1 AEDT} + {2374675200 36000 0 AEST} + {2390400000 39600 1 AEDT} + {2406124800 36000 0 AEST} + {2422454400 39600 1 AEDT} + {2438179200 36000 0 AEST} + {2453904000 39600 1 AEDT} + {2469628800 36000 0 AEST} + {2485353600 39600 1 AEDT} + {2501078400 36000 0 AEST} + {2516803200 39600 1 AEDT} + {2532528000 36000 0 AEST} + {2548252800 39600 1 AEDT} + {2563977600 36000 0 AEST} + {2579702400 39600 1 AEDT} + {2596032000 36000 0 AEST} + {2611756800 39600 1 AEDT} + {2627481600 36000 0 AEST} + {2643206400 39600 1 AEDT} + {2658931200 36000 0 AEST} + {2674656000 39600 1 AEDT} + {2690380800 36000 0 AEST} + {2706105600 39600 1 AEDT} + {2721830400 36000 0 AEST} + {2737555200 39600 1 AEDT} + {2753280000 36000 0 AEST} + {2769609600 39600 1 AEDT} + {2785334400 36000 0 AEST} + {2801059200 39600 1 AEDT} + {2816784000 36000 0 AEST} + {2832508800 39600 1 AEDT} + {2848233600 36000 0 AEST} + {2863958400 39600 1 AEDT} + {2879683200 36000 0 AEST} + {2895408000 39600 1 AEDT} + {2911132800 36000 0 AEST} + {2926857600 39600 1 AEDT} + {2942582400 36000 0 AEST} + {2958912000 39600 1 AEDT} + {2974636800 36000 0 AEST} + {2990361600 39600 1 AEDT} + {3006086400 36000 0 AEST} + {3021811200 39600 1 AEDT} + {3037536000 36000 0 AEST} + {3053260800 39600 1 AEDT} + {3068985600 36000 0 AEST} + {3084710400 39600 1 AEDT} + {3100435200 36000 0 AEST} + {3116764800 39600 1 AEDT} + {3132489600 36000 0 AEST} + {3148214400 39600 1 AEDT} + {3163939200 36000 0 AEST} + {3179664000 39600 1 AEDT} + {3195388800 36000 0 AEST} + {3211113600 39600 1 AEDT} + {3226838400 36000 0 AEST} + {3242563200 39600 1 AEDT} + {3258288000 36000 0 AEST} + {3274012800 39600 1 AEDT} + {3289737600 36000 0 AEST} + {3306067200 39600 1 AEDT} + {3321792000 36000 0 AEST} + {3337516800 39600 1 AEDT} + {3353241600 36000 0 AEST} + {3368966400 39600 1 AEDT} + {3384691200 36000 0 AEST} + {3400416000 39600 1 AEDT} + {3416140800 36000 0 AEST} + {3431865600 39600 1 AEDT} + {3447590400 36000 0 AEST} + {3463315200 39600 1 AEDT} + {3479644800 36000 0 AEST} + {3495369600 39600 1 AEDT} + {3511094400 36000 0 AEST} + {3526819200 39600 1 AEDT} + {3542544000 36000 0 AEST} + {3558268800 39600 1 AEDT} + {3573993600 36000 0 AEST} + {3589718400 39600 1 AEDT} + {3605443200 36000 0 AEST} + {3621168000 39600 1 AEDT} + {3636892800 36000 0 AEST} + {3653222400 39600 1 AEDT} + {3668947200 36000 0 AEST} + {3684672000 39600 1 AEDT} + {3700396800 36000 0 AEST} + {3716121600 39600 1 AEDT} + {3731846400 36000 0 AEST} + {3747571200 39600 1 AEDT} + {3763296000 36000 0 AEST} + {3779020800 39600 1 AEDT} + {3794745600 36000 0 AEST} + {3810470400 39600 1 AEDT} + {3826195200 36000 0 AEST} + {3842524800 39600 1 AEDT} + {3858249600 36000 0 AEST} + {3873974400 39600 1 AEDT} + {3889699200 36000 0 AEST} + {3905424000 39600 1 AEDT} + {3921148800 36000 0 AEST} + {3936873600 39600 1 AEDT} + {3952598400 36000 0 AEST} + {3968323200 39600 1 AEDT} + {3984048000 36000 0 AEST} + {4000377600 39600 1 AEDT} + {4016102400 36000 0 AEST} + {4031827200 39600 1 AEDT} + {4047552000 36000 0 AEST} + {4063276800 39600 1 AEDT} + {4079001600 36000 0 AEST} + {4094726400 39600 1 AEDT} } diff --git a/library/tzdata/Australia/Darwin b/library/tzdata/Australia/Darwin index 9be372d..e77605d 100644 --- a/library/tzdata/Australia/Darwin +++ b/library/tzdata/Australia/Darwin @@ -2,14 +2,14 @@ set TZData(:Australia/Darwin) { {-9223372036854775808 31400 0 LMT} - {-2364108200 32400 0 CST} - {-2230189200 34200 0 CST} - {-1672565340 37800 1 CST} - {-1665390600 34200 0 CST} - {-883639800 37800 1 CST} - {-876126600 34200 0 CST} - {-860398200 37800 1 CST} - {-844677000 34200 0 CST} - {-828343800 37800 1 CST} - {-813227400 34200 0 CST} + {-2364108200 32400 0 ACST} + {-2230189200 34200 0 ACST} + {-1672565340 37800 1 ACDT} + {-1665390600 34200 0 ACST} + {-883639800 37800 1 ACDT} + {-876126600 34200 0 ACST} + {-860398200 37800 1 ACDT} + {-844677000 34200 0 ACST} + {-828343800 37800 1 ACDT} + {-813227400 34200 0 ACST} } diff --git a/library/tzdata/Australia/Eucla b/library/tzdata/Australia/Eucla index 0f8ed4d..08a1948 100644 --- a/library/tzdata/Australia/Eucla +++ b/library/tzdata/Australia/Eucla @@ -2,24 +2,24 @@ set TZData(:Australia/Eucla) { {-9223372036854775808 30928 0 LMT} - {-2337928528 31500 0 CWST} - {-1672562640 35100 1 CWST} - {-1665387900 31500 0 CWST} - {-883637100 35100 1 CWST} - {-876123900 31500 0 CWST} - {-860395500 35100 1 CWST} - {-844674300 31500 0 CWST} - {-836473500 35100 0 CWST} - {152039700 35100 1 CWST} - {162926100 31500 0 CWST} - {436295700 35100 1 CWST} - {447182100 31500 0 CWST} - {690311700 35100 1 CWST} - {699383700 31500 0 CWST} - {1165079700 35100 1 CWST} - {1174756500 31500 0 CWST} - {1193505300 35100 1 CWST} - {1206810900 31500 0 CWST} - {1224954900 35100 1 CWST} - {1238260500 31500 0 CWST} + {-2337928528 31500 0 ACWST} + {-1672562640 35100 1 ACWDT} + {-1665387900 31500 0 ACWST} + {-883637100 35100 1 ACWDT} + {-876123900 31500 0 ACWST} + {-860395500 35100 1 ACWDT} + {-844674300 31500 0 ACWST} + {-836473500 35100 0 ACWST} + {152039700 35100 1 ACWDT} + {162926100 31500 0 ACWST} + {436295700 35100 1 ACWDT} + {447182100 31500 0 ACWST} + {690311700 35100 1 ACWDT} + {699383700 31500 0 ACWST} + {1165079700 35100 1 ACWDT} + {1174756500 31500 0 ACWST} + {1193505300 35100 1 ACWDT} + {1206810900 31500 0 ACWST} + {1224954900 35100 1 ACWDT} + {1238260500 31500 0 ACWST} } diff --git a/library/tzdata/Australia/Hobart b/library/tzdata/Australia/Hobart index 8f27110..bf5adf0 100644 --- a/library/tzdata/Australia/Hobart +++ b/library/tzdata/Australia/Hobart @@ -2,280 +2,280 @@ set TZData(:Australia/Hobart) { {-9223372036854775808 35356 0 LMT} - {-2345795356 36000 0 EST} - {-1680508800 39600 1 EST} - {-1669892400 39600 0 EST} - {-1665392400 36000 0 EST} - {-883641600 39600 1 EST} - {-876128400 36000 0 EST} - {-860400000 39600 1 EST} - {-844678800 36000 0 EST} - {-828345600 39600 1 EST} - {-813229200 36000 0 EST} - {-94730400 36000 0 EST} - {-71136000 39600 1 EST} - {-55411200 36000 0 EST} - {-37267200 39600 1 EST} - {-25776000 36000 0 EST} - {-5817600 39600 1 EST} - {5673600 36000 0 EST} - {25632000 39600 1 EST} - {37728000 36000 0 EST} - {57686400 39600 1 EST} - {67968000 36000 0 EST} - {89136000 39600 1 EST} - {100022400 36000 0 EST} - {120585600 39600 1 EST} - {131472000 36000 0 EST} - {152035200 39600 1 EST} - {162921600 36000 0 EST} - {183484800 39600 1 EST} - {194976000 36000 0 EST} - {215539200 39600 1 EST} - {226425600 36000 0 EST} - {246988800 39600 1 EST} - {257875200 36000 0 EST} - {278438400 39600 1 EST} - {289324800 36000 0 EST} - {309888000 39600 1 EST} - {320774400 36000 0 EST} - {341337600 39600 1 EST} - {352224000 36000 0 EST} - {372787200 39600 1 EST} - {386092800 36000 0 EST} - {404841600 39600 1 EST} - {417542400 36000 0 EST} - {436291200 39600 1 EST} - {447177600 36000 0 EST} - {467740800 39600 1 EST} - {478627200 36000 0 EST} - {499190400 39600 1 EST} - {510076800 36000 0 EST} - {530035200 39600 1 EST} - {542736000 36000 0 EST} - {562089600 39600 1 EST} - {574790400 36000 0 EST} - {594144000 39600 1 EST} - {606240000 36000 0 EST} - {625593600 39600 1 EST} - {637689600 36000 0 EST} - {657043200 39600 1 EST} - {670348800 36000 0 EST} - {686678400 39600 1 EST} - {701798400 36000 0 EST} - {718128000 39600 1 EST} - {733248000 36000 0 EST} - {749577600 39600 1 EST} - {764697600 36000 0 EST} - {781027200 39600 1 EST} - {796147200 36000 0 EST} - {812476800 39600 1 EST} - {828201600 36000 0 EST} - {844531200 39600 1 EST} - {859651200 36000 0 EST} - {875980800 39600 1 EST} - {891100800 36000 0 EST} - {907430400 39600 1 EST} - {922550400 36000 0 EST} - {938880000 39600 1 EST} - {954000000 36000 0 EST} - {967305600 39600 1 EST} - {985449600 36000 0 EST} - {1002384000 39600 1 EST} - {1017504000 36000 0 EST} - {1033833600 39600 1 EST} - {1048953600 36000 0 EST} - {1065283200 39600 1 EST} - {1080403200 36000 0 EST} - {1096732800 39600 1 EST} - {1111852800 36000 0 EST} - {1128182400 39600 1 EST} - {1143907200 36000 0 EST} - {1159632000 39600 1 EST} - {1174752000 36000 0 EST} - {1191686400 39600 1 EST} - {1207411200 36000 0 EST} - {1223136000 39600 1 EST} - {1238860800 36000 0 EST} - {1254585600 39600 1 EST} - {1270310400 36000 0 EST} - {1286035200 39600 1 EST} - {1301760000 36000 0 EST} - {1317484800 39600 1 EST} - {1333209600 36000 0 EST} - {1349539200 39600 1 EST} - {1365264000 36000 0 EST} - {1380988800 39600 1 EST} - {1396713600 36000 0 EST} - {1412438400 39600 1 EST} - {1428163200 36000 0 EST} - {1443888000 39600 1 EST} - {1459612800 36000 0 EST} - {1475337600 39600 1 EST} - {1491062400 36000 0 EST} - {1506787200 39600 1 EST} - {1522512000 36000 0 EST} - {1538841600 39600 1 EST} - {1554566400 36000 0 EST} - {1570291200 39600 1 EST} - {1586016000 36000 0 EST} - {1601740800 39600 1 EST} - {1617465600 36000 0 EST} - {1633190400 39600 1 EST} - {1648915200 36000 0 EST} - {1664640000 39600 1 EST} - {1680364800 36000 0 EST} - {1696089600 39600 1 EST} - {1712419200 36000 0 EST} - {1728144000 39600 1 EST} - {1743868800 36000 0 EST} - {1759593600 39600 1 EST} - {1775318400 36000 0 EST} - {1791043200 39600 1 EST} - {1806768000 36000 0 EST} - {1822492800 39600 1 EST} - {1838217600 36000 0 EST} - {1853942400 39600 1 EST} - {1869667200 36000 0 EST} - {1885996800 39600 1 EST} - {1901721600 36000 0 EST} - {1917446400 39600 1 EST} - {1933171200 36000 0 EST} - {1948896000 39600 1 EST} - {1964620800 36000 0 EST} - {1980345600 39600 1 EST} - {1996070400 36000 0 EST} - {2011795200 39600 1 EST} - {2027520000 36000 0 EST} - {2043244800 39600 1 EST} - {2058969600 36000 0 EST} - {2075299200 39600 1 EST} - {2091024000 36000 0 EST} - {2106748800 39600 1 EST} - {2122473600 36000 0 EST} - {2138198400 39600 1 EST} - {2153923200 36000 0 EST} - {2169648000 39600 1 EST} - {2185372800 36000 0 EST} - {2201097600 39600 1 EST} - {2216822400 36000 0 EST} - {2233152000 39600 1 EST} - {2248876800 36000 0 EST} - {2264601600 39600 1 EST} - {2280326400 36000 0 EST} - {2296051200 39600 1 EST} - {2311776000 36000 0 EST} - {2327500800 39600 1 EST} - {2343225600 36000 0 EST} - {2358950400 39600 1 EST} - {2374675200 36000 0 EST} - {2390400000 39600 1 EST} - {2406124800 36000 0 EST} - {2422454400 39600 1 EST} - {2438179200 36000 0 EST} - {2453904000 39600 1 EST} - {2469628800 36000 0 EST} - {2485353600 39600 1 EST} - {2501078400 36000 0 EST} - {2516803200 39600 1 EST} - {2532528000 36000 0 EST} - {2548252800 39600 1 EST} - {2563977600 36000 0 EST} - {2579702400 39600 1 EST} - {2596032000 36000 0 EST} - {2611756800 39600 1 EST} - {2627481600 36000 0 EST} - {2643206400 39600 1 EST} - {2658931200 36000 0 EST} - {2674656000 39600 1 EST} - {2690380800 36000 0 EST} - {2706105600 39600 1 EST} - {2721830400 36000 0 EST} - {2737555200 39600 1 EST} - {2753280000 36000 0 EST} - {2769609600 39600 1 EST} - {2785334400 36000 0 EST} - {2801059200 39600 1 EST} - {2816784000 36000 0 EST} - {2832508800 39600 1 EST} - {2848233600 36000 0 EST} - {2863958400 39600 1 EST} - {2879683200 36000 0 EST} - {2895408000 39600 1 EST} - {2911132800 36000 0 EST} - {2926857600 39600 1 EST} - {2942582400 36000 0 EST} - {2958912000 39600 1 EST} - {2974636800 36000 0 EST} - {2990361600 39600 1 EST} - {3006086400 36000 0 EST} - {3021811200 39600 1 EST} - {3037536000 36000 0 EST} - {3053260800 39600 1 EST} - {3068985600 36000 0 EST} - {3084710400 39600 1 EST} - {3100435200 36000 0 EST} - {3116764800 39600 1 EST} - {3132489600 36000 0 EST} - {3148214400 39600 1 EST} - {3163939200 36000 0 EST} - {3179664000 39600 1 EST} - {3195388800 36000 0 EST} - {3211113600 39600 1 EST} - {3226838400 36000 0 EST} - {3242563200 39600 1 EST} - {3258288000 36000 0 EST} - {3274012800 39600 1 EST} - {3289737600 36000 0 EST} - {3306067200 39600 1 EST} - {3321792000 36000 0 EST} - {3337516800 39600 1 EST} - {3353241600 36000 0 EST} - {3368966400 39600 1 EST} - {3384691200 36000 0 EST} - {3400416000 39600 1 EST} - {3416140800 36000 0 EST} - {3431865600 39600 1 EST} - {3447590400 36000 0 EST} - {3463315200 39600 1 EST} - {3479644800 36000 0 EST} - {3495369600 39600 1 EST} - {3511094400 36000 0 EST} - {3526819200 39600 1 EST} - {3542544000 36000 0 EST} - {3558268800 39600 1 EST} - {3573993600 36000 0 EST} - {3589718400 39600 1 EST} - {3605443200 36000 0 EST} - {3621168000 39600 1 EST} - {3636892800 36000 0 EST} - {3653222400 39600 1 EST} - {3668947200 36000 0 EST} - {3684672000 39600 1 EST} - {3700396800 36000 0 EST} - {3716121600 39600 1 EST} - {3731846400 36000 0 EST} - {3747571200 39600 1 EST} - {3763296000 36000 0 EST} - {3779020800 39600 1 EST} - {3794745600 36000 0 EST} - {3810470400 39600 1 EST} - {3826195200 36000 0 EST} - {3842524800 39600 1 EST} - {3858249600 36000 0 EST} - {3873974400 39600 1 EST} - {3889699200 36000 0 EST} - {3905424000 39600 1 EST} - {3921148800 36000 0 EST} - {3936873600 39600 1 EST} - {3952598400 36000 0 EST} - {3968323200 39600 1 EST} - {3984048000 36000 0 EST} - {4000377600 39600 1 EST} - {4016102400 36000 0 EST} - {4031827200 39600 1 EST} - {4047552000 36000 0 EST} - {4063276800 39600 1 EST} - {4079001600 36000 0 EST} - {4094726400 39600 1 EST} + {-2345795356 36000 0 AEST} + {-1680508800 39600 1 AEDT} + {-1669892400 39600 0 AEDT} + {-1665392400 36000 0 AEST} + {-883641600 39600 1 AEDT} + {-876128400 36000 0 AEST} + {-860400000 39600 1 AEDT} + {-844678800 36000 0 AEST} + {-828345600 39600 1 AEDT} + {-813229200 36000 0 AEST} + {-94730400 36000 0 AEST} + {-71136000 39600 1 AEDT} + {-55411200 36000 0 AEST} + {-37267200 39600 1 AEDT} + {-25776000 36000 0 AEST} + {-5817600 39600 1 AEDT} + {5673600 36000 0 AEST} + {25632000 39600 1 AEDT} + {37728000 36000 0 AEST} + {57686400 39600 1 AEDT} + {67968000 36000 0 AEST} + {89136000 39600 1 AEDT} + {100022400 36000 0 AEST} + {120585600 39600 1 AEDT} + {131472000 36000 0 AEST} + {152035200 39600 1 AEDT} + {162921600 36000 0 AEST} + {183484800 39600 1 AEDT} + {194976000 36000 0 AEST} + {215539200 39600 1 AEDT} + {226425600 36000 0 AEST} + {246988800 39600 1 AEDT} + {257875200 36000 0 AEST} + {278438400 39600 1 AEDT} + {289324800 36000 0 AEST} + {309888000 39600 1 AEDT} + {320774400 36000 0 AEST} + {341337600 39600 1 AEDT} + {352224000 36000 0 AEST} + {372787200 39600 1 AEDT} + {386092800 36000 0 AEST} + {404841600 39600 1 AEDT} + {417542400 36000 0 AEST} + {436291200 39600 1 AEDT} + {447177600 36000 0 AEST} + {467740800 39600 1 AEDT} + {478627200 36000 0 AEST} + {499190400 39600 1 AEDT} + {510076800 36000 0 AEST} + {530035200 39600 1 AEDT} + {542736000 36000 0 AEST} + {562089600 39600 1 AEDT} + {574790400 36000 0 AEST} + {594144000 39600 1 AEDT} + {606240000 36000 0 AEST} + {625593600 39600 1 AEDT} + {637689600 36000 0 AEST} + {657043200 39600 1 AEDT} + {670348800 36000 0 AEST} + {686678400 39600 1 AEDT} + {701798400 36000 0 AEST} + {718128000 39600 1 AEDT} + {733248000 36000 0 AEST} + {749577600 39600 1 AEDT} + {764697600 36000 0 AEST} + {781027200 39600 1 AEDT} + {796147200 36000 0 AEST} + {812476800 39600 1 AEDT} + {828201600 36000 0 AEST} + {844531200 39600 1 AEDT} + {859651200 36000 0 AEST} + {875980800 39600 1 AEDT} + {891100800 36000 0 AEST} + {907430400 39600 1 AEDT} + {922550400 36000 0 AEST} + {938880000 39600 1 AEDT} + {954000000 36000 0 AEST} + {967305600 39600 1 AEDT} + {985449600 36000 0 AEST} + {1002384000 39600 1 AEDT} + {1017504000 36000 0 AEST} + {1033833600 39600 1 AEDT} + {1048953600 36000 0 AEST} + {1065283200 39600 1 AEDT} + {1080403200 36000 0 AEST} + {1096732800 39600 1 AEDT} + {1111852800 36000 0 AEST} + {1128182400 39600 1 AEDT} + {1143907200 36000 0 AEST} + {1159632000 39600 1 AEDT} + {1174752000 36000 0 AEST} + {1191686400 39600 1 AEDT} + {1207411200 36000 0 AEST} + {1223136000 39600 1 AEDT} + {1238860800 36000 0 AEST} + {1254585600 39600 1 AEDT} + {1270310400 36000 0 AEST} + {1286035200 39600 1 AEDT} + {1301760000 36000 0 AEST} + {1317484800 39600 1 AEDT} + {1333209600 36000 0 AEST} + {1349539200 39600 1 AEDT} + {1365264000 36000 0 AEST} + {1380988800 39600 1 AEDT} + {1396713600 36000 0 AEST} + {1412438400 39600 1 AEDT} + {1428163200 36000 0 AEST} + {1443888000 39600 1 AEDT} + {1459612800 36000 0 AEST} + {1475337600 39600 1 AEDT} + {1491062400 36000 0 AEST} + {1506787200 39600 1 AEDT} + {1522512000 36000 0 AEST} + {1538841600 39600 1 AEDT} + {1554566400 36000 0 AEST} + {1570291200 39600 1 AEDT} + {1586016000 36000 0 AEST} + {1601740800 39600 1 AEDT} + {1617465600 36000 0 AEST} + {1633190400 39600 1 AEDT} + {1648915200 36000 0 AEST} + {1664640000 39600 1 AEDT} + {1680364800 36000 0 AEST} + {1696089600 39600 1 AEDT} + {1712419200 36000 0 AEST} + {1728144000 39600 1 AEDT} + {1743868800 36000 0 AEST} + {1759593600 39600 1 AEDT} + {1775318400 36000 0 AEST} + {1791043200 39600 1 AEDT} + {1806768000 36000 0 AEST} + {1822492800 39600 1 AEDT} + {1838217600 36000 0 AEST} + {1853942400 39600 1 AEDT} + {1869667200 36000 0 AEST} + {1885996800 39600 1 AEDT} + {1901721600 36000 0 AEST} + {1917446400 39600 1 AEDT} + {1933171200 36000 0 AEST} + {1948896000 39600 1 AEDT} + {1964620800 36000 0 AEST} + {1980345600 39600 1 AEDT} + {1996070400 36000 0 AEST} + {2011795200 39600 1 AEDT} + {2027520000 36000 0 AEST} + {2043244800 39600 1 AEDT} + {2058969600 36000 0 AEST} + {2075299200 39600 1 AEDT} + {2091024000 36000 0 AEST} + {2106748800 39600 1 AEDT} + {2122473600 36000 0 AEST} + {2138198400 39600 1 AEDT} + {2153923200 36000 0 AEST} + {2169648000 39600 1 AEDT} + {2185372800 36000 0 AEST} + {2201097600 39600 1 AEDT} + {2216822400 36000 0 AEST} + {2233152000 39600 1 AEDT} + {2248876800 36000 0 AEST} + {2264601600 39600 1 AEDT} + {2280326400 36000 0 AEST} + {2296051200 39600 1 AEDT} + {2311776000 36000 0 AEST} + {2327500800 39600 1 AEDT} + {2343225600 36000 0 AEST} + {2358950400 39600 1 AEDT} + {2374675200 36000 0 AEST} + {2390400000 39600 1 AEDT} + {2406124800 36000 0 AEST} + {2422454400 39600 1 AEDT} + {2438179200 36000 0 AEST} + {2453904000 39600 1 AEDT} + {2469628800 36000 0 AEST} + {2485353600 39600 1 AEDT} + {2501078400 36000 0 AEST} + {2516803200 39600 1 AEDT} + {2532528000 36000 0 AEST} + {2548252800 39600 1 AEDT} + {2563977600 36000 0 AEST} + {2579702400 39600 1 AEDT} + {2596032000 36000 0 AEST} + {2611756800 39600 1 AEDT} + {2627481600 36000 0 AEST} + {2643206400 39600 1 AEDT} + {2658931200 36000 0 AEST} + {2674656000 39600 1 AEDT} + {2690380800 36000 0 AEST} + {2706105600 39600 1 AEDT} + {2721830400 36000 0 AEST} + {2737555200 39600 1 AEDT} + {2753280000 36000 0 AEST} + {2769609600 39600 1 AEDT} + {2785334400 36000 0 AEST} + {2801059200 39600 1 AEDT} + {2816784000 36000 0 AEST} + {2832508800 39600 1 AEDT} + {2848233600 36000 0 AEST} + {2863958400 39600 1 AEDT} + {2879683200 36000 0 AEST} + {2895408000 39600 1 AEDT} + {2911132800 36000 0 AEST} + {2926857600 39600 1 AEDT} + {2942582400 36000 0 AEST} + {2958912000 39600 1 AEDT} + {2974636800 36000 0 AEST} + {2990361600 39600 1 AEDT} + {3006086400 36000 0 AEST} + {3021811200 39600 1 AEDT} + {3037536000 36000 0 AEST} + {3053260800 39600 1 AEDT} + {3068985600 36000 0 AEST} + {3084710400 39600 1 AEDT} + {3100435200 36000 0 AEST} + {3116764800 39600 1 AEDT} + {3132489600 36000 0 AEST} + {3148214400 39600 1 AEDT} + {3163939200 36000 0 AEST} + {3179664000 39600 1 AEDT} + {3195388800 36000 0 AEST} + {3211113600 39600 1 AEDT} + {3226838400 36000 0 AEST} + {3242563200 39600 1 AEDT} + {3258288000 36000 0 AEST} + {3274012800 39600 1 AEDT} + {3289737600 36000 0 AEST} + {3306067200 39600 1 AEDT} + {3321792000 36000 0 AEST} + {3337516800 39600 1 AEDT} + {3353241600 36000 0 AEST} + {3368966400 39600 1 AEDT} + {3384691200 36000 0 AEST} + {3400416000 39600 1 AEDT} + {3416140800 36000 0 AEST} + {3431865600 39600 1 AEDT} + {3447590400 36000 0 AEST} + {3463315200 39600 1 AEDT} + {3479644800 36000 0 AEST} + {3495369600 39600 1 AEDT} + {3511094400 36000 0 AEST} + {3526819200 39600 1 AEDT} + {3542544000 36000 0 AEST} + {3558268800 39600 1 AEDT} + {3573993600 36000 0 AEST} + {3589718400 39600 1 AEDT} + {3605443200 36000 0 AEST} + {3621168000 39600 1 AEDT} + {3636892800 36000 0 AEST} + {3653222400 39600 1 AEDT} + {3668947200 36000 0 AEST} + {3684672000 39600 1 AEDT} + {3700396800 36000 0 AEST} + {3716121600 39600 1 AEDT} + {3731846400 36000 0 AEST} + {3747571200 39600 1 AEDT} + {3763296000 36000 0 AEST} + {3779020800 39600 1 AEDT} + {3794745600 36000 0 AEST} + {3810470400 39600 1 AEDT} + {3826195200 36000 0 AEST} + {3842524800 39600 1 AEDT} + {3858249600 36000 0 AEST} + {3873974400 39600 1 AEDT} + {3889699200 36000 0 AEST} + {3905424000 39600 1 AEDT} + {3921148800 36000 0 AEST} + {3936873600 39600 1 AEDT} + {3952598400 36000 0 AEST} + {3968323200 39600 1 AEDT} + {3984048000 36000 0 AEST} + {4000377600 39600 1 AEDT} + {4016102400 36000 0 AEST} + {4031827200 39600 1 AEDT} + {4047552000 36000 0 AEST} + {4063276800 39600 1 AEDT} + {4079001600 36000 0 AEST} + {4094726400 39600 1 AEDT} } diff --git a/library/tzdata/Australia/Lindeman b/library/tzdata/Australia/Lindeman index de11c35..91ad0a6 100644 --- a/library/tzdata/Australia/Lindeman +++ b/library/tzdata/Australia/Lindeman @@ -2,27 +2,27 @@ set TZData(:Australia/Lindeman) { {-9223372036854775808 35756 0 LMT} - {-2366790956 36000 0 EST} - {-1672567140 39600 1 EST} - {-1665392400 36000 0 EST} - {-883641600 39600 1 EST} - {-876128400 36000 0 EST} - {-860400000 39600 1 EST} - {-844678800 36000 0 EST} - {-828345600 39600 1 EST} - {-813229200 36000 0 EST} - {31500000 36000 0 EST} - {57686400 39600 1 EST} - {67968000 36000 0 EST} - {625593600 39600 1 EST} - {636480000 36000 0 EST} - {657043200 39600 1 EST} - {667929600 36000 0 EST} - {688492800 39600 1 EST} - {699379200 36000 0 EST} - {709912800 36000 0 EST} - {719942400 39600 1 EST} - {731433600 36000 0 EST} - {751996800 39600 1 EST} - {762883200 36000 0 EST} + {-2366790956 36000 0 AEST} + {-1672567140 39600 1 AEDT} + {-1665392400 36000 0 AEST} + {-883641600 39600 1 AEDT} + {-876128400 36000 0 AEST} + {-860400000 39600 1 AEDT} + {-844678800 36000 0 AEST} + {-828345600 39600 1 AEDT} + {-813229200 36000 0 AEST} + {31500000 36000 0 AEST} + {57686400 39600 1 AEDT} + {67968000 36000 0 AEST} + {625593600 39600 1 AEDT} + {636480000 36000 0 AEST} + {657043200 39600 1 AEDT} + {667929600 36000 0 AEST} + {688492800 39600 1 AEDT} + {699379200 36000 0 AEST} + {709912800 36000 0 AEST} + {719942400 39600 1 AEDT} + {731433600 36000 0 AEST} + {751996800 39600 1 AEDT} + {762883200 36000 0 AEST} } diff --git a/library/tzdata/Australia/Lord_Howe b/library/tzdata/Australia/Lord_Howe index da094e5..a8ff80e 100644 --- a/library/tzdata/Australia/Lord_Howe +++ b/library/tzdata/Australia/Lord_Howe @@ -2,243 +2,243 @@ set TZData(:Australia/Lord_Howe) { {-9223372036854775808 38180 0 LMT} - {-2364114980 36000 0 EST} + {-2364114980 36000 0 AEST} {352216800 37800 0 LHST} - {372785400 41400 1 LHST} + {372785400 41400 1 LHDT} {384273000 37800 0 LHST} - {404839800 41400 1 LHST} + {404839800 41400 1 LHDT} {415722600 37800 0 LHST} - {436289400 41400 1 LHST} + {436289400 41400 1 LHDT} {447172200 37800 0 LHST} - {467739000 41400 1 LHST} + {467739000 41400 1 LHDT} {478621800 37800 0 LHST} - {499188600 39600 1 LHST} + {499188600 39600 1 LHDT} {511282800 37800 0 LHST} - {530033400 39600 1 LHST} + {530033400 39600 1 LHDT} {542732400 37800 0 LHST} - {562087800 39600 1 LHST} + {562087800 39600 1 LHDT} {574786800 37800 0 LHST} - {594142200 39600 1 LHST} + {594142200 39600 1 LHDT} {606236400 37800 0 LHST} - {625591800 39600 1 LHST} + {625591800 39600 1 LHDT} {636476400 37800 0 LHST} - {657041400 39600 1 LHST} + {657041400 39600 1 LHDT} {667926000 37800 0 LHST} - {688491000 39600 1 LHST} + {688491000 39600 1 LHDT} {699375600 37800 0 LHST} - {719940600 39600 1 LHST} + {719940600 39600 1 LHDT} {731430000 37800 0 LHST} - {751995000 39600 1 LHST} + {751995000 39600 1 LHDT} {762879600 37800 0 LHST} - {783444600 39600 1 LHST} + {783444600 39600 1 LHDT} {794329200 37800 0 LHST} - {814894200 39600 1 LHST} + {814894200 39600 1 LHDT} {828198000 37800 0 LHST} - {846343800 39600 1 LHST} + {846343800 39600 1 LHDT} {859647600 37800 0 LHST} - {877793400 39600 1 LHST} + {877793400 39600 1 LHDT} {891097200 37800 0 LHST} - {909243000 39600 1 LHST} + {909243000 39600 1 LHDT} {922546800 37800 0 LHST} - {941297400 39600 1 LHST} + {941297400 39600 1 LHDT} {953996400 37800 0 LHST} - {967303800 39600 1 LHST} + {967303800 39600 1 LHDT} {985446000 37800 0 LHST} - {1004196600 39600 1 LHST} + {1004196600 39600 1 LHDT} {1017500400 37800 0 LHST} - {1035646200 39600 1 LHST} + {1035646200 39600 1 LHDT} {1048950000 37800 0 LHST} - {1067095800 39600 1 LHST} + {1067095800 39600 1 LHDT} {1080399600 37800 0 LHST} - {1099150200 39600 1 LHST} + {1099150200 39600 1 LHDT} {1111849200 37800 0 LHST} - {1130599800 39600 1 LHST} + {1130599800 39600 1 LHDT} {1143903600 37800 0 LHST} - {1162049400 39600 1 LHST} + {1162049400 39600 1 LHDT} {1174748400 37800 0 LHST} - {1193499000 39600 1 LHST} + {1193499000 39600 1 LHDT} {1207407600 37800 0 LHST} - {1223134200 39600 1 LHST} + {1223134200 39600 1 LHDT} {1238857200 37800 0 LHST} - {1254583800 39600 1 LHST} + {1254583800 39600 1 LHDT} {1270306800 37800 0 LHST} - {1286033400 39600 1 LHST} + {1286033400 39600 1 LHDT} {1301756400 37800 0 LHST} - {1317483000 39600 1 LHST} + {1317483000 39600 1 LHDT} {1333206000 37800 0 LHST} - {1349537400 39600 1 LHST} + {1349537400 39600 1 LHDT} {1365260400 37800 0 LHST} - {1380987000 39600 1 LHST} + {1380987000 39600 1 LHDT} {1396710000 37800 0 LHST} - {1412436600 39600 1 LHST} + {1412436600 39600 1 LHDT} {1428159600 37800 0 LHST} - {1443886200 39600 1 LHST} + {1443886200 39600 1 LHDT} {1459609200 37800 0 LHST} - {1475335800 39600 1 LHST} + {1475335800 39600 1 LHDT} {1491058800 37800 0 LHST} - {1506785400 39600 1 LHST} + {1506785400 39600 1 LHDT} {1522508400 37800 0 LHST} - {1538839800 39600 1 LHST} + {1538839800 39600 1 LHDT} {1554562800 37800 0 LHST} - {1570289400 39600 1 LHST} + {1570289400 39600 1 LHDT} {1586012400 37800 0 LHST} - {1601739000 39600 1 LHST} + {1601739000 39600 1 LHDT} {1617462000 37800 0 LHST} - {1633188600 39600 1 LHST} + {1633188600 39600 1 LHDT} {1648911600 37800 0 LHST} - {1664638200 39600 1 LHST} + {1664638200 39600 1 LHDT} {1680361200 37800 0 LHST} - {1696087800 39600 1 LHST} + {1696087800 39600 1 LHDT} {1712415600 37800 0 LHST} - {1728142200 39600 1 LHST} + {1728142200 39600 1 LHDT} {1743865200 37800 0 LHST} - {1759591800 39600 1 LHST} + {1759591800 39600 1 LHDT} {1775314800 37800 0 LHST} - {1791041400 39600 1 LHST} + {1791041400 39600 1 LHDT} {1806764400 37800 0 LHST} - {1822491000 39600 1 LHST} + {1822491000 39600 1 LHDT} {1838214000 37800 0 LHST} - {1853940600 39600 1 LHST} + {1853940600 39600 1 LHDT} {1869663600 37800 0 LHST} - {1885995000 39600 1 LHST} + {1885995000 39600 1 LHDT} {1901718000 37800 0 LHST} - {1917444600 39600 1 LHST} + {1917444600 39600 1 LHDT} {1933167600 37800 0 LHST} - {1948894200 39600 1 LHST} + {1948894200 39600 1 LHDT} {1964617200 37800 0 LHST} - {1980343800 39600 1 LHST} + {1980343800 39600 1 LHDT} {1996066800 37800 0 LHST} - {2011793400 39600 1 LHST} + {2011793400 39600 1 LHDT} {2027516400 37800 0 LHST} - {2043243000 39600 1 LHST} + {2043243000 39600 1 LHDT} {2058966000 37800 0 LHST} - {2075297400 39600 1 LHST} + {2075297400 39600 1 LHDT} {2091020400 37800 0 LHST} - {2106747000 39600 1 LHST} + {2106747000 39600 1 LHDT} {2122470000 37800 0 LHST} - {2138196600 39600 1 LHST} + {2138196600 39600 1 LHDT} {2153919600 37800 0 LHST} - {2169646200 39600 1 LHST} + {2169646200 39600 1 LHDT} {2185369200 37800 0 LHST} - {2201095800 39600 1 LHST} + {2201095800 39600 1 LHDT} {2216818800 37800 0 LHST} - {2233150200 39600 1 LHST} + {2233150200 39600 1 LHDT} {2248873200 37800 0 LHST} - {2264599800 39600 1 LHST} + {2264599800 39600 1 LHDT} {2280322800 37800 0 LHST} - {2296049400 39600 1 LHST} + {2296049400 39600 1 LHDT} {2311772400 37800 0 LHST} - {2327499000 39600 1 LHST} + {2327499000 39600 1 LHDT} {2343222000 37800 0 LHST} - {2358948600 39600 1 LHST} + {2358948600 39600 1 LHDT} {2374671600 37800 0 LHST} - {2390398200 39600 1 LHST} + {2390398200 39600 1 LHDT} {2406121200 37800 0 LHST} - {2422452600 39600 1 LHST} + {2422452600 39600 1 LHDT} {2438175600 37800 0 LHST} - {2453902200 39600 1 LHST} + {2453902200 39600 1 LHDT} {2469625200 37800 0 LHST} - {2485351800 39600 1 LHST} + {2485351800 39600 1 LHDT} {2501074800 37800 0 LHST} - {2516801400 39600 1 LHST} + {2516801400 39600 1 LHDT} {2532524400 37800 0 LHST} - {2548251000 39600 1 LHST} + {2548251000 39600 1 LHDT} {2563974000 37800 0 LHST} - {2579700600 39600 1 LHST} + {2579700600 39600 1 LHDT} {2596028400 37800 0 LHST} - {2611755000 39600 1 LHST} + {2611755000 39600 1 LHDT} {2627478000 37800 0 LHST} - {2643204600 39600 1 LHST} + {2643204600 39600 1 LHDT} {2658927600 37800 0 LHST} - {2674654200 39600 1 LHST} + {2674654200 39600 1 LHDT} {2690377200 37800 0 LHST} - {2706103800 39600 1 LHST} + {2706103800 39600 1 LHDT} {2721826800 37800 0 LHST} - {2737553400 39600 1 LHST} + {2737553400 39600 1 LHDT} {2753276400 37800 0 LHST} - {2769607800 39600 1 LHST} + {2769607800 39600 1 LHDT} {2785330800 37800 0 LHST} - {2801057400 39600 1 LHST} + {2801057400 39600 1 LHDT} {2816780400 37800 0 LHST} - {2832507000 39600 1 LHST} + {2832507000 39600 1 LHDT} {2848230000 37800 0 LHST} - {2863956600 39600 1 LHST} + {2863956600 39600 1 LHDT} {2879679600 37800 0 LHST} - {2895406200 39600 1 LHST} + {2895406200 39600 1 LHDT} {2911129200 37800 0 LHST} - {2926855800 39600 1 LHST} + {2926855800 39600 1 LHDT} {2942578800 37800 0 LHST} - {2958910200 39600 1 LHST} + {2958910200 39600 1 LHDT} {2974633200 37800 0 LHST} - {2990359800 39600 1 LHST} + {2990359800 39600 1 LHDT} {3006082800 37800 0 LHST} - {3021809400 39600 1 LHST} + {3021809400 39600 1 LHDT} {3037532400 37800 0 LHST} - {3053259000 39600 1 LHST} + {3053259000 39600 1 LHDT} {3068982000 37800 0 LHST} - {3084708600 39600 1 LHST} + {3084708600 39600 1 LHDT} {3100431600 37800 0 LHST} - {3116763000 39600 1 LHST} + {3116763000 39600 1 LHDT} {3132486000 37800 0 LHST} - {3148212600 39600 1 LHST} + {3148212600 39600 1 LHDT} {3163935600 37800 0 LHST} - {3179662200 39600 1 LHST} + {3179662200 39600 1 LHDT} {3195385200 37800 0 LHST} - {3211111800 39600 1 LHST} + {3211111800 39600 1 LHDT} {3226834800 37800 0 LHST} - {3242561400 39600 1 LHST} + {3242561400 39600 1 LHDT} {3258284400 37800 0 LHST} - {3274011000 39600 1 LHST} + {3274011000 39600 1 LHDT} {3289734000 37800 0 LHST} - {3306065400 39600 1 LHST} + {3306065400 39600 1 LHDT} {3321788400 37800 0 LHST} - {3337515000 39600 1 LHST} + {3337515000 39600 1 LHDT} {3353238000 37800 0 LHST} - {3368964600 39600 1 LHST} + {3368964600 39600 1 LHDT} {3384687600 37800 0 LHST} - {3400414200 39600 1 LHST} + {3400414200 39600 1 LHDT} {3416137200 37800 0 LHST} - {3431863800 39600 1 LHST} + {3431863800 39600 1 LHDT} {3447586800 37800 0 LHST} - {3463313400 39600 1 LHST} + {3463313400 39600 1 LHDT} {3479641200 37800 0 LHST} - {3495367800 39600 1 LHST} + {3495367800 39600 1 LHDT} {3511090800 37800 0 LHST} - {3526817400 39600 1 LHST} + {3526817400 39600 1 LHDT} {3542540400 37800 0 LHST} - {3558267000 39600 1 LHST} + {3558267000 39600 1 LHDT} {3573990000 37800 0 LHST} - {3589716600 39600 1 LHST} + {3589716600 39600 1 LHDT} {3605439600 37800 0 LHST} - {3621166200 39600 1 LHST} + {3621166200 39600 1 LHDT} {3636889200 37800 0 LHST} - {3653220600 39600 1 LHST} + {3653220600 39600 1 LHDT} {3668943600 37800 0 LHST} - {3684670200 39600 1 LHST} + {3684670200 39600 1 LHDT} {3700393200 37800 0 LHST} - {3716119800 39600 1 LHST} + {3716119800 39600 1 LHDT} {3731842800 37800 0 LHST} - {3747569400 39600 1 LHST} + {3747569400 39600 1 LHDT} {3763292400 37800 0 LHST} - {3779019000 39600 1 LHST} + {3779019000 39600 1 LHDT} {3794742000 37800 0 LHST} - {3810468600 39600 1 LHST} + {3810468600 39600 1 LHDT} {3826191600 37800 0 LHST} - {3842523000 39600 1 LHST} + {3842523000 39600 1 LHDT} {3858246000 37800 0 LHST} - {3873972600 39600 1 LHST} + {3873972600 39600 1 LHDT} {3889695600 37800 0 LHST} - {3905422200 39600 1 LHST} + {3905422200 39600 1 LHDT} {3921145200 37800 0 LHST} - {3936871800 39600 1 LHST} + {3936871800 39600 1 LHDT} {3952594800 37800 0 LHST} - {3968321400 39600 1 LHST} + {3968321400 39600 1 LHDT} {3984044400 37800 0 LHST} - {4000375800 39600 1 LHST} + {4000375800 39600 1 LHDT} {4016098800 37800 0 LHST} - {4031825400 39600 1 LHST} + {4031825400 39600 1 LHDT} {4047548400 37800 0 LHST} - {4063275000 39600 1 LHST} + {4063275000 39600 1 LHDT} {4078998000 37800 0 LHST} - {4094724600 39600 1 LHST} + {4094724600 39600 1 LHDT} } diff --git a/library/tzdata/Australia/Melbourne b/library/tzdata/Australia/Melbourne index 907b8b9..81777df 100644 --- a/library/tzdata/Australia/Melbourne +++ b/library/tzdata/Australia/Melbourne @@ -2,271 +2,271 @@ set TZData(:Australia/Melbourne) { {-9223372036854775808 34792 0 LMT} - {-2364111592 36000 0 EST} - {-1672567140 39600 1 EST} - {-1665392400 36000 0 EST} - {-883641600 39600 1 EST} - {-876128400 36000 0 EST} - {-860400000 39600 1 EST} - {-844678800 36000 0 EST} - {-828345600 39600 1 EST} - {-813229200 36000 0 EST} - {31500000 36000 0 EST} - {57686400 39600 1 EST} - {67968000 36000 0 EST} - {89136000 39600 1 EST} - {100022400 36000 0 EST} - {120585600 39600 1 EST} - {131472000 36000 0 EST} - {152035200 39600 1 EST} - {162921600 36000 0 EST} - {183484800 39600 1 EST} - {194976000 36000 0 EST} - {215539200 39600 1 EST} - {226425600 36000 0 EST} - {246988800 39600 1 EST} - {257875200 36000 0 EST} - {278438400 39600 1 EST} - {289324800 36000 0 EST} - {309888000 39600 1 EST} - {320774400 36000 0 EST} - {341337600 39600 1 EST} - {352224000 36000 0 EST} - {372787200 39600 1 EST} - {384278400 36000 0 EST} - {404841600 39600 1 EST} - {415728000 36000 0 EST} - {436291200 39600 1 EST} - {447177600 36000 0 EST} - {467740800 39600 1 EST} - {478627200 36000 0 EST} - {499190400 39600 1 EST} - {511286400 36000 0 EST} - {530035200 39600 1 EST} - {542736000 36000 0 EST} - {561484800 39600 1 EST} - {574790400 36000 0 EST} - {594144000 39600 1 EST} - {606240000 36000 0 EST} - {625593600 39600 1 EST} - {637689600 36000 0 EST} - {657043200 39600 1 EST} - {667929600 36000 0 EST} - {688492800 39600 1 EST} - {699379200 36000 0 EST} - {719942400 39600 1 EST} - {731433600 36000 0 EST} - {751996800 39600 1 EST} - {762883200 36000 0 EST} - {783446400 39600 1 EST} - {796147200 36000 0 EST} - {814896000 39600 1 EST} - {828201600 36000 0 EST} - {846345600 39600 1 EST} - {859651200 36000 0 EST} - {877795200 39600 1 EST} - {891100800 36000 0 EST} - {909244800 39600 1 EST} - {922550400 36000 0 EST} - {941299200 39600 1 EST} - {954000000 36000 0 EST} - {967305600 39600 1 EST} - {985449600 36000 0 EST} - {1004198400 39600 1 EST} - {1017504000 36000 0 EST} - {1035648000 39600 1 EST} - {1048953600 36000 0 EST} - {1067097600 39600 1 EST} - {1080403200 36000 0 EST} - {1099152000 39600 1 EST} - {1111852800 36000 0 EST} - {1130601600 39600 1 EST} - {1143907200 36000 0 EST} - {1162051200 39600 1 EST} - {1174752000 36000 0 EST} - {1193500800 39600 1 EST} - {1207411200 36000 0 EST} - {1223136000 39600 1 EST} - {1238860800 36000 0 EST} - {1254585600 39600 1 EST} - {1270310400 36000 0 EST} - {1286035200 39600 1 EST} - {1301760000 36000 0 EST} - {1317484800 39600 1 EST} - {1333209600 36000 0 EST} - {1349539200 39600 1 EST} - {1365264000 36000 0 EST} - {1380988800 39600 1 EST} - {1396713600 36000 0 EST} - {1412438400 39600 1 EST} - {1428163200 36000 0 EST} - {1443888000 39600 1 EST} - {1459612800 36000 0 EST} - {1475337600 39600 1 EST} - {1491062400 36000 0 EST} - {1506787200 39600 1 EST} - {1522512000 36000 0 EST} - {1538841600 39600 1 EST} - {1554566400 36000 0 EST} - {1570291200 39600 1 EST} - {1586016000 36000 0 EST} - {1601740800 39600 1 EST} - {1617465600 36000 0 EST} - {1633190400 39600 1 EST} - {1648915200 36000 0 EST} - {1664640000 39600 1 EST} - {1680364800 36000 0 EST} - {1696089600 39600 1 EST} - {1712419200 36000 0 EST} - {1728144000 39600 1 EST} - {1743868800 36000 0 EST} - {1759593600 39600 1 EST} - {1775318400 36000 0 EST} - {1791043200 39600 1 EST} - {1806768000 36000 0 EST} - {1822492800 39600 1 EST} - {1838217600 36000 0 EST} - {1853942400 39600 1 EST} - {1869667200 36000 0 EST} - {1885996800 39600 1 EST} - {1901721600 36000 0 EST} - {1917446400 39600 1 EST} - {1933171200 36000 0 EST} - {1948896000 39600 1 EST} - {1964620800 36000 0 EST} - {1980345600 39600 1 EST} - {1996070400 36000 0 EST} - {2011795200 39600 1 EST} - {2027520000 36000 0 EST} - {2043244800 39600 1 EST} - {2058969600 36000 0 EST} - {2075299200 39600 1 EST} - {2091024000 36000 0 EST} - {2106748800 39600 1 EST} - {2122473600 36000 0 EST} - {2138198400 39600 1 EST} - {2153923200 36000 0 EST} - {2169648000 39600 1 EST} - {2185372800 36000 0 EST} - {2201097600 39600 1 EST} - {2216822400 36000 0 EST} - {2233152000 39600 1 EST} - {2248876800 36000 0 EST} - {2264601600 39600 1 EST} - {2280326400 36000 0 EST} - {2296051200 39600 1 EST} - {2311776000 36000 0 EST} - {2327500800 39600 1 EST} - {2343225600 36000 0 EST} - {2358950400 39600 1 EST} - {2374675200 36000 0 EST} - {2390400000 39600 1 EST} - {2406124800 36000 0 EST} - {2422454400 39600 1 EST} - {2438179200 36000 0 EST} - {2453904000 39600 1 EST} - {2469628800 36000 0 EST} - {2485353600 39600 1 EST} - {2501078400 36000 0 EST} - {2516803200 39600 1 EST} - {2532528000 36000 0 EST} - {2548252800 39600 1 EST} - {2563977600 36000 0 EST} - {2579702400 39600 1 EST} - {2596032000 36000 0 EST} - {2611756800 39600 1 EST} - {2627481600 36000 0 EST} - {2643206400 39600 1 EST} - {2658931200 36000 0 EST} - {2674656000 39600 1 EST} - {2690380800 36000 0 EST} - {2706105600 39600 1 EST} - {2721830400 36000 0 EST} - {2737555200 39600 1 EST} - {2753280000 36000 0 EST} - {2769609600 39600 1 EST} - {2785334400 36000 0 EST} - {2801059200 39600 1 EST} - {2816784000 36000 0 EST} - {2832508800 39600 1 EST} - {2848233600 36000 0 EST} - {2863958400 39600 1 EST} - {2879683200 36000 0 EST} - {2895408000 39600 1 EST} - {2911132800 36000 0 EST} - {2926857600 39600 1 EST} - {2942582400 36000 0 EST} - {2958912000 39600 1 EST} - {2974636800 36000 0 EST} - {2990361600 39600 1 EST} - {3006086400 36000 0 EST} - {3021811200 39600 1 EST} - {3037536000 36000 0 EST} - {3053260800 39600 1 EST} - {3068985600 36000 0 EST} - {3084710400 39600 1 EST} - {3100435200 36000 0 EST} - {3116764800 39600 1 EST} - {3132489600 36000 0 EST} - {3148214400 39600 1 EST} - {3163939200 36000 0 EST} - {3179664000 39600 1 EST} - {3195388800 36000 0 EST} - {3211113600 39600 1 EST} - {3226838400 36000 0 EST} - {3242563200 39600 1 EST} - {3258288000 36000 0 EST} - {3274012800 39600 1 EST} - {3289737600 36000 0 EST} - {3306067200 39600 1 EST} - {3321792000 36000 0 EST} - {3337516800 39600 1 EST} - {3353241600 36000 0 EST} - {3368966400 39600 1 EST} - {3384691200 36000 0 EST} - {3400416000 39600 1 EST} - {3416140800 36000 0 EST} - {3431865600 39600 1 EST} - {3447590400 36000 0 EST} - {3463315200 39600 1 EST} - {3479644800 36000 0 EST} - {3495369600 39600 1 EST} - {3511094400 36000 0 EST} - {3526819200 39600 1 EST} - {3542544000 36000 0 EST} - {3558268800 39600 1 EST} - {3573993600 36000 0 EST} - {3589718400 39600 1 EST} - {3605443200 36000 0 EST} - {3621168000 39600 1 EST} - {3636892800 36000 0 EST} - {3653222400 39600 1 EST} - {3668947200 36000 0 EST} - {3684672000 39600 1 EST} - {3700396800 36000 0 EST} - {3716121600 39600 1 EST} - {3731846400 36000 0 EST} - {3747571200 39600 1 EST} - {3763296000 36000 0 EST} - {3779020800 39600 1 EST} - {3794745600 36000 0 EST} - {3810470400 39600 1 EST} - {3826195200 36000 0 EST} - {3842524800 39600 1 EST} - {3858249600 36000 0 EST} - {3873974400 39600 1 EST} - {3889699200 36000 0 EST} - {3905424000 39600 1 EST} - {3921148800 36000 0 EST} - {3936873600 39600 1 EST} - {3952598400 36000 0 EST} - {3968323200 39600 1 EST} - {3984048000 36000 0 EST} - {4000377600 39600 1 EST} - {4016102400 36000 0 EST} - {4031827200 39600 1 EST} - {4047552000 36000 0 EST} - {4063276800 39600 1 EST} - {4079001600 36000 0 EST} - {4094726400 39600 1 EST} + {-2364111592 36000 0 AEST} + {-1672567140 39600 1 AEDT} + {-1665392400 36000 0 AEST} + {-883641600 39600 1 AEDT} + {-876128400 36000 0 AEST} + {-860400000 39600 1 AEDT} + {-844678800 36000 0 AEST} + {-828345600 39600 1 AEDT} + {-813229200 36000 0 AEST} + {31500000 36000 0 AEST} + {57686400 39600 1 AEDT} + {67968000 36000 0 AEST} + {89136000 39600 1 AEDT} + {100022400 36000 0 AEST} + {120585600 39600 1 AEDT} + {131472000 36000 0 AEST} + {152035200 39600 1 AEDT} + {162921600 36000 0 AEST} + {183484800 39600 1 AEDT} + {194976000 36000 0 AEST} + {215539200 39600 1 AEDT} + {226425600 36000 0 AEST} + {246988800 39600 1 AEDT} + {257875200 36000 0 AEST} + {278438400 39600 1 AEDT} + {289324800 36000 0 AEST} + {309888000 39600 1 AEDT} + {320774400 36000 0 AEST} + {341337600 39600 1 AEDT} + {352224000 36000 0 AEST} + {372787200 39600 1 AEDT} + {384278400 36000 0 AEST} + {404841600 39600 1 AEDT} + {415728000 36000 0 AEST} + {436291200 39600 1 AEDT} + {447177600 36000 0 AEST} + {467740800 39600 1 AEDT} + {478627200 36000 0 AEST} + {499190400 39600 1 AEDT} + {511286400 36000 0 AEST} + {530035200 39600 1 AEDT} + {542736000 36000 0 AEST} + {561484800 39600 1 AEDT} + {574790400 36000 0 AEST} + {594144000 39600 1 AEDT} + {606240000 36000 0 AEST} + {625593600 39600 1 AEDT} + {637689600 36000 0 AEST} + {657043200 39600 1 AEDT} + {667929600 36000 0 AEST} + {688492800 39600 1 AEDT} + {699379200 36000 0 AEST} + {719942400 39600 1 AEDT} + {731433600 36000 0 AEST} + {751996800 39600 1 AEDT} + {762883200 36000 0 AEST} + {783446400 39600 1 AEDT} + {796147200 36000 0 AEST} + {814896000 39600 1 AEDT} + {828201600 36000 0 AEST} + {846345600 39600 1 AEDT} + {859651200 36000 0 AEST} + {877795200 39600 1 AEDT} + {891100800 36000 0 AEST} + {909244800 39600 1 AEDT} + {922550400 36000 0 AEST} + {941299200 39600 1 AEDT} + {954000000 36000 0 AEST} + {967305600 39600 1 AEDT} + {985449600 36000 0 AEST} + {1004198400 39600 1 AEDT} + {1017504000 36000 0 AEST} + {1035648000 39600 1 AEDT} + {1048953600 36000 0 AEST} + {1067097600 39600 1 AEDT} + {1080403200 36000 0 AEST} + {1099152000 39600 1 AEDT} + {1111852800 36000 0 AEST} + {1130601600 39600 1 AEDT} + {1143907200 36000 0 AEST} + {1162051200 39600 1 AEDT} + {1174752000 36000 0 AEST} + {1193500800 39600 1 AEDT} + {1207411200 36000 0 AEST} + {1223136000 39600 1 AEDT} + {1238860800 36000 0 AEST} + {1254585600 39600 1 AEDT} + {1270310400 36000 0 AEST} + {1286035200 39600 1 AEDT} + {1301760000 36000 0 AEST} + {1317484800 39600 1 AEDT} + {1333209600 36000 0 AEST} + {1349539200 39600 1 AEDT} + {1365264000 36000 0 AEST} + {1380988800 39600 1 AEDT} + {1396713600 36000 0 AEST} + {1412438400 39600 1 AEDT} + {1428163200 36000 0 AEST} + {1443888000 39600 1 AEDT} + {1459612800 36000 0 AEST} + {1475337600 39600 1 AEDT} + {1491062400 36000 0 AEST} + {1506787200 39600 1 AEDT} + {1522512000 36000 0 AEST} + {1538841600 39600 1 AEDT} + {1554566400 36000 0 AEST} + {1570291200 39600 1 AEDT} + {1586016000 36000 0 AEST} + {1601740800 39600 1 AEDT} + {1617465600 36000 0 AEST} + {1633190400 39600 1 AEDT} + {1648915200 36000 0 AEST} + {1664640000 39600 1 AEDT} + {1680364800 36000 0 AEST} + {1696089600 39600 1 AEDT} + {1712419200 36000 0 AEST} + {1728144000 39600 1 AEDT} + {1743868800 36000 0 AEST} + {1759593600 39600 1 AEDT} + {1775318400 36000 0 AEST} + {1791043200 39600 1 AEDT} + {1806768000 36000 0 AEST} + {1822492800 39600 1 AEDT} + {1838217600 36000 0 AEST} + {1853942400 39600 1 AEDT} + {1869667200 36000 0 AEST} + {1885996800 39600 1 AEDT} + {1901721600 36000 0 AEST} + {1917446400 39600 1 AEDT} + {1933171200 36000 0 AEST} + {1948896000 39600 1 AEDT} + {1964620800 36000 0 AEST} + {1980345600 39600 1 AEDT} + {1996070400 36000 0 AEST} + {2011795200 39600 1 AEDT} + {2027520000 36000 0 AEST} + {2043244800 39600 1 AEDT} + {2058969600 36000 0 AEST} + {2075299200 39600 1 AEDT} + {2091024000 36000 0 AEST} + {2106748800 39600 1 AEDT} + {2122473600 36000 0 AEST} + {2138198400 39600 1 AEDT} + {2153923200 36000 0 AEST} + {2169648000 39600 1 AEDT} + {2185372800 36000 0 AEST} + {2201097600 39600 1 AEDT} + {2216822400 36000 0 AEST} + {2233152000 39600 1 AEDT} + {2248876800 36000 0 AEST} + {2264601600 39600 1 AEDT} + {2280326400 36000 0 AEST} + {2296051200 39600 1 AEDT} + {2311776000 36000 0 AEST} + {2327500800 39600 1 AEDT} + {2343225600 36000 0 AEST} + {2358950400 39600 1 AEDT} + {2374675200 36000 0 AEST} + {2390400000 39600 1 AEDT} + {2406124800 36000 0 AEST} + {2422454400 39600 1 AEDT} + {2438179200 36000 0 AEST} + {2453904000 39600 1 AEDT} + {2469628800 36000 0 AEST} + {2485353600 39600 1 AEDT} + {2501078400 36000 0 AEST} + {2516803200 39600 1 AEDT} + {2532528000 36000 0 AEST} + {2548252800 39600 1 AEDT} + {2563977600 36000 0 AEST} + {2579702400 39600 1 AEDT} + {2596032000 36000 0 AEST} + {2611756800 39600 1 AEDT} + {2627481600 36000 0 AEST} + {2643206400 39600 1 AEDT} + {2658931200 36000 0 AEST} + {2674656000 39600 1 AEDT} + {2690380800 36000 0 AEST} + {2706105600 39600 1 AEDT} + {2721830400 36000 0 AEST} + {2737555200 39600 1 AEDT} + {2753280000 36000 0 AEST} + {2769609600 39600 1 AEDT} + {2785334400 36000 0 AEST} + {2801059200 39600 1 AEDT} + {2816784000 36000 0 AEST} + {2832508800 39600 1 AEDT} + {2848233600 36000 0 AEST} + {2863958400 39600 1 AEDT} + {2879683200 36000 0 AEST} + {2895408000 39600 1 AEDT} + {2911132800 36000 0 AEST} + {2926857600 39600 1 AEDT} + {2942582400 36000 0 AEST} + {2958912000 39600 1 AEDT} + {2974636800 36000 0 AEST} + {2990361600 39600 1 AEDT} + {3006086400 36000 0 AEST} + {3021811200 39600 1 AEDT} + {3037536000 36000 0 AEST} + {3053260800 39600 1 AEDT} + {3068985600 36000 0 AEST} + {3084710400 39600 1 AEDT} + {3100435200 36000 0 AEST} + {3116764800 39600 1 AEDT} + {3132489600 36000 0 AEST} + {3148214400 39600 1 AEDT} + {3163939200 36000 0 AEST} + {3179664000 39600 1 AEDT} + {3195388800 36000 0 AEST} + {3211113600 39600 1 AEDT} + {3226838400 36000 0 AEST} + {3242563200 39600 1 AEDT} + {3258288000 36000 0 AEST} + {3274012800 39600 1 AEDT} + {3289737600 36000 0 AEST} + {3306067200 39600 1 AEDT} + {3321792000 36000 0 AEST} + {3337516800 39600 1 AEDT} + {3353241600 36000 0 AEST} + {3368966400 39600 1 AEDT} + {3384691200 36000 0 AEST} + {3400416000 39600 1 AEDT} + {3416140800 36000 0 AEST} + {3431865600 39600 1 AEDT} + {3447590400 36000 0 AEST} + {3463315200 39600 1 AEDT} + {3479644800 36000 0 AEST} + {3495369600 39600 1 AEDT} + {3511094400 36000 0 AEST} + {3526819200 39600 1 AEDT} + {3542544000 36000 0 AEST} + {3558268800 39600 1 AEDT} + {3573993600 36000 0 AEST} + {3589718400 39600 1 AEDT} + {3605443200 36000 0 AEST} + {3621168000 39600 1 AEDT} + {3636892800 36000 0 AEST} + {3653222400 39600 1 AEDT} + {3668947200 36000 0 AEST} + {3684672000 39600 1 AEDT} + {3700396800 36000 0 AEST} + {3716121600 39600 1 AEDT} + {3731846400 36000 0 AEST} + {3747571200 39600 1 AEDT} + {3763296000 36000 0 AEST} + {3779020800 39600 1 AEDT} + {3794745600 36000 0 AEST} + {3810470400 39600 1 AEDT} + {3826195200 36000 0 AEST} + {3842524800 39600 1 AEDT} + {3858249600 36000 0 AEST} + {3873974400 39600 1 AEDT} + {3889699200 36000 0 AEST} + {3905424000 39600 1 AEDT} + {3921148800 36000 0 AEST} + {3936873600 39600 1 AEDT} + {3952598400 36000 0 AEST} + {3968323200 39600 1 AEDT} + {3984048000 36000 0 AEST} + {4000377600 39600 1 AEDT} + {4016102400 36000 0 AEST} + {4031827200 39600 1 AEDT} + {4047552000 36000 0 AEST} + {4063276800 39600 1 AEDT} + {4079001600 36000 0 AEST} + {4094726400 39600 1 AEDT} } diff --git a/library/tzdata/Australia/Perth b/library/tzdata/Australia/Perth index 5d8f116..6ccbca8 100644 --- a/library/tzdata/Australia/Perth +++ b/library/tzdata/Australia/Perth @@ -2,24 +2,24 @@ set TZData(:Australia/Perth) { {-9223372036854775808 27804 0 LMT} - {-2337925404 28800 0 WST} - {-1672559940 32400 1 WST} - {-1665385200 28800 0 WST} - {-883634400 32400 1 WST} - {-876121200 28800 0 WST} - {-860392800 32400 1 WST} - {-844671600 28800 0 WST} - {-836470800 32400 0 WST} - {152042400 32400 1 WST} - {162928800 28800 0 WST} - {436298400 32400 1 WST} - {447184800 28800 0 WST} - {690314400 32400 1 WST} - {699386400 28800 0 WST} - {1165082400 32400 1 WST} - {1174759200 28800 0 WST} - {1193508000 32400 1 WST} - {1206813600 28800 0 WST} - {1224957600 32400 1 WST} - {1238263200 28800 0 WST} + {-2337925404 28800 0 AWST} + {-1672559940 32400 1 AWDT} + {-1665385200 28800 0 AWST} + {-883634400 32400 1 AWDT} + {-876121200 28800 0 AWST} + {-860392800 32400 1 AWDT} + {-844671600 28800 0 AWST} + {-836470800 32400 0 AWST} + {152042400 32400 1 AWDT} + {162928800 28800 0 AWST} + {436298400 32400 1 AWDT} + {447184800 28800 0 AWST} + {690314400 32400 1 AWDT} + {699386400 28800 0 AWST} + {1165082400 32400 1 AWDT} + {1174759200 28800 0 AWST} + {1193508000 32400 1 AWDT} + {1206813600 28800 0 AWST} + {1224957600 32400 1 AWDT} + {1238263200 28800 0 AWST} } diff --git a/library/tzdata/Australia/Sydney b/library/tzdata/Australia/Sydney index 84b1d14..b1c4411 100644 --- a/library/tzdata/Australia/Sydney +++ b/library/tzdata/Australia/Sydney @@ -2,271 +2,271 @@ set TZData(:Australia/Sydney) { {-9223372036854775808 36292 0 LMT} - {-2364113092 36000 0 EST} - {-1672567140 39600 1 EST} - {-1665392400 36000 0 EST} - {-883641600 39600 1 EST} - {-876128400 36000 0 EST} - {-860400000 39600 1 EST} - {-844678800 36000 0 EST} - {-828345600 39600 1 EST} - {-813229200 36000 0 EST} - {31500000 36000 0 EST} - {57686400 39600 1 EST} - {67968000 36000 0 EST} - {89136000 39600 1 EST} - {100022400 36000 0 EST} - {120585600 39600 1 EST} - {131472000 36000 0 EST} - {152035200 39600 1 EST} - {162921600 36000 0 EST} - {183484800 39600 1 EST} - {194976000 36000 0 EST} - {215539200 39600 1 EST} - {226425600 36000 0 EST} - {246988800 39600 1 EST} - {257875200 36000 0 EST} - {278438400 39600 1 EST} - {289324800 36000 0 EST} - {309888000 39600 1 EST} - {320774400 36000 0 EST} - {341337600 39600 1 EST} - {352224000 36000 0 EST} - {372787200 39600 1 EST} - {386697600 36000 0 EST} - {404841600 39600 1 EST} - {415728000 36000 0 EST} - {436291200 39600 1 EST} - {447177600 36000 0 EST} - {467740800 39600 1 EST} - {478627200 36000 0 EST} - {499190400 39600 1 EST} - {511286400 36000 0 EST} - {530035200 39600 1 EST} - {542736000 36000 0 EST} - {562089600 39600 1 EST} - {574790400 36000 0 EST} - {594144000 39600 1 EST} - {606240000 36000 0 EST} - {625593600 39600 1 EST} - {636480000 36000 0 EST} - {657043200 39600 1 EST} - {667929600 36000 0 EST} - {688492800 39600 1 EST} - {699379200 36000 0 EST} - {719942400 39600 1 EST} - {731433600 36000 0 EST} - {751996800 39600 1 EST} - {762883200 36000 0 EST} - {783446400 39600 1 EST} - {794332800 36000 0 EST} - {814896000 39600 1 EST} - {828201600 36000 0 EST} - {846345600 39600 1 EST} - {859651200 36000 0 EST} - {877795200 39600 1 EST} - {891100800 36000 0 EST} - {909244800 39600 1 EST} - {922550400 36000 0 EST} - {941299200 39600 1 EST} - {954000000 36000 0 EST} - {967305600 39600 1 EST} - {985449600 36000 0 EST} - {1004198400 39600 1 EST} - {1017504000 36000 0 EST} - {1035648000 39600 1 EST} - {1048953600 36000 0 EST} - {1067097600 39600 1 EST} - {1080403200 36000 0 EST} - {1099152000 39600 1 EST} - {1111852800 36000 0 EST} - {1130601600 39600 1 EST} - {1143907200 36000 0 EST} - {1162051200 39600 1 EST} - {1174752000 36000 0 EST} - {1193500800 39600 1 EST} - {1207411200 36000 0 EST} - {1223136000 39600 1 EST} - {1238860800 36000 0 EST} - {1254585600 39600 1 EST} - {1270310400 36000 0 EST} - {1286035200 39600 1 EST} - {1301760000 36000 0 EST} - {1317484800 39600 1 EST} - {1333209600 36000 0 EST} - {1349539200 39600 1 EST} - {1365264000 36000 0 EST} - {1380988800 39600 1 EST} - {1396713600 36000 0 EST} - {1412438400 39600 1 EST} - {1428163200 36000 0 EST} - {1443888000 39600 1 EST} - {1459612800 36000 0 EST} - {1475337600 39600 1 EST} - {1491062400 36000 0 EST} - {1506787200 39600 1 EST} - {1522512000 36000 0 EST} - {1538841600 39600 1 EST} - {1554566400 36000 0 EST} - {1570291200 39600 1 EST} - {1586016000 36000 0 EST} - {1601740800 39600 1 EST} - {1617465600 36000 0 EST} - {1633190400 39600 1 EST} - {1648915200 36000 0 EST} - {1664640000 39600 1 EST} - {1680364800 36000 0 EST} - {1696089600 39600 1 EST} - {1712419200 36000 0 EST} - {1728144000 39600 1 EST} - {1743868800 36000 0 EST} - {1759593600 39600 1 EST} - {1775318400 36000 0 EST} - {1791043200 39600 1 EST} - {1806768000 36000 0 EST} - {1822492800 39600 1 EST} - {1838217600 36000 0 EST} - {1853942400 39600 1 EST} - {1869667200 36000 0 EST} - {1885996800 39600 1 EST} - {1901721600 36000 0 EST} - {1917446400 39600 1 EST} - {1933171200 36000 0 EST} - {1948896000 39600 1 EST} - {1964620800 36000 0 EST} - {1980345600 39600 1 EST} - {1996070400 36000 0 EST} - {2011795200 39600 1 EST} - {2027520000 36000 0 EST} - {2043244800 39600 1 EST} - {2058969600 36000 0 EST} - {2075299200 39600 1 EST} - {2091024000 36000 0 EST} - {2106748800 39600 1 EST} - {2122473600 36000 0 EST} - {2138198400 39600 1 EST} - {2153923200 36000 0 EST} - {2169648000 39600 1 EST} - {2185372800 36000 0 EST} - {2201097600 39600 1 EST} - {2216822400 36000 0 EST} - {2233152000 39600 1 EST} - {2248876800 36000 0 EST} - {2264601600 39600 1 EST} - {2280326400 36000 0 EST} - {2296051200 39600 1 EST} - {2311776000 36000 0 EST} - {2327500800 39600 1 EST} - {2343225600 36000 0 EST} - {2358950400 39600 1 EST} - {2374675200 36000 0 EST} - {2390400000 39600 1 EST} - {2406124800 36000 0 EST} - {2422454400 39600 1 EST} - {2438179200 36000 0 EST} - {2453904000 39600 1 EST} - {2469628800 36000 0 EST} - {2485353600 39600 1 EST} - {2501078400 36000 0 EST} - {2516803200 39600 1 EST} - {2532528000 36000 0 EST} - {2548252800 39600 1 EST} - {2563977600 36000 0 EST} - {2579702400 39600 1 EST} - {2596032000 36000 0 EST} - {2611756800 39600 1 EST} - {2627481600 36000 0 EST} - {2643206400 39600 1 EST} - {2658931200 36000 0 EST} - {2674656000 39600 1 EST} - {2690380800 36000 0 EST} - {2706105600 39600 1 EST} - {2721830400 36000 0 EST} - {2737555200 39600 1 EST} - {2753280000 36000 0 EST} - {2769609600 39600 1 EST} - {2785334400 36000 0 EST} - {2801059200 39600 1 EST} - {2816784000 36000 0 EST} - {2832508800 39600 1 EST} - {2848233600 36000 0 EST} - {2863958400 39600 1 EST} - {2879683200 36000 0 EST} - {2895408000 39600 1 EST} - {2911132800 36000 0 EST} - {2926857600 39600 1 EST} - {2942582400 36000 0 EST} - {2958912000 39600 1 EST} - {2974636800 36000 0 EST} - {2990361600 39600 1 EST} - {3006086400 36000 0 EST} - {3021811200 39600 1 EST} - {3037536000 36000 0 EST} - {3053260800 39600 1 EST} - {3068985600 36000 0 EST} - {3084710400 39600 1 EST} - {3100435200 36000 0 EST} - {3116764800 39600 1 EST} - {3132489600 36000 0 EST} - {3148214400 39600 1 EST} - {3163939200 36000 0 EST} - {3179664000 39600 1 EST} - {3195388800 36000 0 EST} - {3211113600 39600 1 EST} - {3226838400 36000 0 EST} - {3242563200 39600 1 EST} - {3258288000 36000 0 EST} - {3274012800 39600 1 EST} - {3289737600 36000 0 EST} - {3306067200 39600 1 EST} - {3321792000 36000 0 EST} - {3337516800 39600 1 EST} - {3353241600 36000 0 EST} - {3368966400 39600 1 EST} - {3384691200 36000 0 EST} - {3400416000 39600 1 EST} - {3416140800 36000 0 EST} - {3431865600 39600 1 EST} - {3447590400 36000 0 EST} - {3463315200 39600 1 EST} - {3479644800 36000 0 EST} - {3495369600 39600 1 EST} - {3511094400 36000 0 EST} - {3526819200 39600 1 EST} - {3542544000 36000 0 EST} - {3558268800 39600 1 EST} - {3573993600 36000 0 EST} - {3589718400 39600 1 EST} - {3605443200 36000 0 EST} - {3621168000 39600 1 EST} - {3636892800 36000 0 EST} - {3653222400 39600 1 EST} - {3668947200 36000 0 EST} - {3684672000 39600 1 EST} - {3700396800 36000 0 EST} - {3716121600 39600 1 EST} - {3731846400 36000 0 EST} - {3747571200 39600 1 EST} - {3763296000 36000 0 EST} - {3779020800 39600 1 EST} - {3794745600 36000 0 EST} - {3810470400 39600 1 EST} - {3826195200 36000 0 EST} - {3842524800 39600 1 EST} - {3858249600 36000 0 EST} - {3873974400 39600 1 EST} - {3889699200 36000 0 EST} - {3905424000 39600 1 EST} - {3921148800 36000 0 EST} - {3936873600 39600 1 EST} - {3952598400 36000 0 EST} - {3968323200 39600 1 EST} - {3984048000 36000 0 EST} - {4000377600 39600 1 EST} - {4016102400 36000 0 EST} - {4031827200 39600 1 EST} - {4047552000 36000 0 EST} - {4063276800 39600 1 EST} - {4079001600 36000 0 EST} - {4094726400 39600 1 EST} + {-2364113092 36000 0 AEST} + {-1672567140 39600 1 AEDT} + {-1665392400 36000 0 AEST} + {-883641600 39600 1 AEDT} + {-876128400 36000 0 AEST} + {-860400000 39600 1 AEDT} + {-844678800 36000 0 AEST} + {-828345600 39600 1 AEDT} + {-813229200 36000 0 AEST} + {31500000 36000 0 AEST} + {57686400 39600 1 AEDT} + {67968000 36000 0 AEST} + {89136000 39600 1 AEDT} + {100022400 36000 0 AEST} + {120585600 39600 1 AEDT} + {131472000 36000 0 AEST} + {152035200 39600 1 AEDT} + {162921600 36000 0 AEST} + {183484800 39600 1 AEDT} + {194976000 36000 0 AEST} + {215539200 39600 1 AEDT} + {226425600 36000 0 AEST} + {246988800 39600 1 AEDT} + {257875200 36000 0 AEST} + {278438400 39600 1 AEDT} + {289324800 36000 0 AEST} + {309888000 39600 1 AEDT} + {320774400 36000 0 AEST} + {341337600 39600 1 AEDT} + {352224000 36000 0 AEST} + {372787200 39600 1 AEDT} + {386697600 36000 0 AEST} + {404841600 39600 1 AEDT} + {415728000 36000 0 AEST} + {436291200 39600 1 AEDT} + {447177600 36000 0 AEST} + {467740800 39600 1 AEDT} + {478627200 36000 0 AEST} + {499190400 39600 1 AEDT} + {511286400 36000 0 AEST} + {530035200 39600 1 AEDT} + {542736000 36000 0 AEST} + {562089600 39600 1 AEDT} + {574790400 36000 0 AEST} + {594144000 39600 1 AEDT} + {606240000 36000 0 AEST} + {625593600 39600 1 AEDT} + {636480000 36000 0 AEST} + {657043200 39600 1 AEDT} + {667929600 36000 0 AEST} + {688492800 39600 1 AEDT} + {699379200 36000 0 AEST} + {719942400 39600 1 AEDT} + {731433600 36000 0 AEST} + {751996800 39600 1 AEDT} + {762883200 36000 0 AEST} + {783446400 39600 1 AEDT} + {794332800 36000 0 AEST} + {814896000 39600 1 AEDT} + {828201600 36000 0 AEST} + {846345600 39600 1 AEDT} + {859651200 36000 0 AEST} + {877795200 39600 1 AEDT} + {891100800 36000 0 AEST} + {909244800 39600 1 AEDT} + {922550400 36000 0 AEST} + {941299200 39600 1 AEDT} + {954000000 36000 0 AEST} + {967305600 39600 1 AEDT} + {985449600 36000 0 AEST} + {1004198400 39600 1 AEDT} + {1017504000 36000 0 AEST} + {1035648000 39600 1 AEDT} + {1048953600 36000 0 AEST} + {1067097600 39600 1 AEDT} + {1080403200 36000 0 AEST} + {1099152000 39600 1 AEDT} + {1111852800 36000 0 AEST} + {1130601600 39600 1 AEDT} + {1143907200 36000 0 AEST} + {1162051200 39600 1 AEDT} + {1174752000 36000 0 AEST} + {1193500800 39600 1 AEDT} + {1207411200 36000 0 AEST} + {1223136000 39600 1 AEDT} + {1238860800 36000 0 AEST} + {1254585600 39600 1 AEDT} + {1270310400 36000 0 AEST} + {1286035200 39600 1 AEDT} + {1301760000 36000 0 AEST} + {1317484800 39600 1 AEDT} + {1333209600 36000 0 AEST} + {1349539200 39600 1 AEDT} + {1365264000 36000 0 AEST} + {1380988800 39600 1 AEDT} + {1396713600 36000 0 AEST} + {1412438400 39600 1 AEDT} + {1428163200 36000 0 AEST} + {1443888000 39600 1 AEDT} + {1459612800 36000 0 AEST} + {1475337600 39600 1 AEDT} + {1491062400 36000 0 AEST} + {1506787200 39600 1 AEDT} + {1522512000 36000 0 AEST} + {1538841600 39600 1 AEDT} + {1554566400 36000 0 AEST} + {1570291200 39600 1 AEDT} + {1586016000 36000 0 AEST} + {1601740800 39600 1 AEDT} + {1617465600 36000 0 AEST} + {1633190400 39600 1 AEDT} + {1648915200 36000 0 AEST} + {1664640000 39600 1 AEDT} + {1680364800 36000 0 AEST} + {1696089600 39600 1 AEDT} + {1712419200 36000 0 AEST} + {1728144000 39600 1 AEDT} + {1743868800 36000 0 AEST} + {1759593600 39600 1 AEDT} + {1775318400 36000 0 AEST} + {1791043200 39600 1 AEDT} + {1806768000 36000 0 AEST} + {1822492800 39600 1 AEDT} + {1838217600 36000 0 AEST} + {1853942400 39600 1 AEDT} + {1869667200 36000 0 AEST} + {1885996800 39600 1 AEDT} + {1901721600 36000 0 AEST} + {1917446400 39600 1 AEDT} + {1933171200 36000 0 AEST} + {1948896000 39600 1 AEDT} + {1964620800 36000 0 AEST} + {1980345600 39600 1 AEDT} + {1996070400 36000 0 AEST} + {2011795200 39600 1 AEDT} + {2027520000 36000 0 AEST} + {2043244800 39600 1 AEDT} + {2058969600 36000 0 AEST} + {2075299200 39600 1 AEDT} + {2091024000 36000 0 AEST} + {2106748800 39600 1 AEDT} + {2122473600 36000 0 AEST} + {2138198400 39600 1 AEDT} + {2153923200 36000 0 AEST} + {2169648000 39600 1 AEDT} + {2185372800 36000 0 AEST} + {2201097600 39600 1 AEDT} + {2216822400 36000 0 AEST} + {2233152000 39600 1 AEDT} + {2248876800 36000 0 AEST} + {2264601600 39600 1 AEDT} + {2280326400 36000 0 AEST} + {2296051200 39600 1 AEDT} + {2311776000 36000 0 AEST} + {2327500800 39600 1 AEDT} + {2343225600 36000 0 AEST} + {2358950400 39600 1 AEDT} + {2374675200 36000 0 AEST} + {2390400000 39600 1 AEDT} + {2406124800 36000 0 AEST} + {2422454400 39600 1 AEDT} + {2438179200 36000 0 AEST} + {2453904000 39600 1 AEDT} + {2469628800 36000 0 AEST} + {2485353600 39600 1 AEDT} + {2501078400 36000 0 AEST} + {2516803200 39600 1 AEDT} + {2532528000 36000 0 AEST} + {2548252800 39600 1 AEDT} + {2563977600 36000 0 AEST} + {2579702400 39600 1 AEDT} + {2596032000 36000 0 AEST} + {2611756800 39600 1 AEDT} + {2627481600 36000 0 AEST} + {2643206400 39600 1 AEDT} + {2658931200 36000 0 AEST} + {2674656000 39600 1 AEDT} + {2690380800 36000 0 AEST} + {2706105600 39600 1 AEDT} + {2721830400 36000 0 AEST} + {2737555200 39600 1 AEDT} + {2753280000 36000 0 AEST} + {2769609600 39600 1 AEDT} + {2785334400 36000 0 AEST} + {2801059200 39600 1 AEDT} + {2816784000 36000 0 AEST} + {2832508800 39600 1 AEDT} + {2848233600 36000 0 AEST} + {2863958400 39600 1 AEDT} + {2879683200 36000 0 AEST} + {2895408000 39600 1 AEDT} + {2911132800 36000 0 AEST} + {2926857600 39600 1 AEDT} + {2942582400 36000 0 AEST} + {2958912000 39600 1 AEDT} + {2974636800 36000 0 AEST} + {2990361600 39600 1 AEDT} + {3006086400 36000 0 AEST} + {3021811200 39600 1 AEDT} + {3037536000 36000 0 AEST} + {3053260800 39600 1 AEDT} + {3068985600 36000 0 AEST} + {3084710400 39600 1 AEDT} + {3100435200 36000 0 AEST} + {3116764800 39600 1 AEDT} + {3132489600 36000 0 AEST} + {3148214400 39600 1 AEDT} + {3163939200 36000 0 AEST} + {3179664000 39600 1 AEDT} + {3195388800 36000 0 AEST} + {3211113600 39600 1 AEDT} + {3226838400 36000 0 AEST} + {3242563200 39600 1 AEDT} + {3258288000 36000 0 AEST} + {3274012800 39600 1 AEDT} + {3289737600 36000 0 AEST} + {3306067200 39600 1 AEDT} + {3321792000 36000 0 AEST} + {3337516800 39600 1 AEDT} + {3353241600 36000 0 AEST} + {3368966400 39600 1 AEDT} + {3384691200 36000 0 AEST} + {3400416000 39600 1 AEDT} + {3416140800 36000 0 AEST} + {3431865600 39600 1 AEDT} + {3447590400 36000 0 AEST} + {3463315200 39600 1 AEDT} + {3479644800 36000 0 AEST} + {3495369600 39600 1 AEDT} + {3511094400 36000 0 AEST} + {3526819200 39600 1 AEDT} + {3542544000 36000 0 AEST} + {3558268800 39600 1 AEDT} + {3573993600 36000 0 AEST} + {3589718400 39600 1 AEDT} + {3605443200 36000 0 AEST} + {3621168000 39600 1 AEDT} + {3636892800 36000 0 AEST} + {3653222400 39600 1 AEDT} + {3668947200 36000 0 AEST} + {3684672000 39600 1 AEDT} + {3700396800 36000 0 AEST} + {3716121600 39600 1 AEDT} + {3731846400 36000 0 AEST} + {3747571200 39600 1 AEDT} + {3763296000 36000 0 AEST} + {3779020800 39600 1 AEDT} + {3794745600 36000 0 AEST} + {3810470400 39600 1 AEDT} + {3826195200 36000 0 AEST} + {3842524800 39600 1 AEDT} + {3858249600 36000 0 AEST} + {3873974400 39600 1 AEDT} + {3889699200 36000 0 AEST} + {3905424000 39600 1 AEDT} + {3921148800 36000 0 AEST} + {3936873600 39600 1 AEDT} + {3952598400 36000 0 AEST} + {3968323200 39600 1 AEDT} + {3984048000 36000 0 AEST} + {4000377600 39600 1 AEDT} + {4016102400 36000 0 AEST} + {4031827200 39600 1 AEDT} + {4047552000 36000 0 AEST} + {4063276800 39600 1 AEDT} + {4079001600 36000 0 AEST} + {4094726400 39600 1 AEDT} } diff --git a/library/tzdata/Europe/Budapest b/library/tzdata/Europe/Budapest index fd41acc..e660ad1 100644 --- a/library/tzdata/Europe/Budapest +++ b/library/tzdata/Europe/Budapest @@ -9,12 +9,10 @@ set TZData(:Europe/Budapest) { {-1650150000 3600 0 CET} {-1640998800 3600 0 CET} {-1633212000 7200 1 CEST} - {-1617577200 3600 0 CET} + {-1618700400 3600 0 CET} {-1600466400 7200 1 CEST} - {-1587250800 3600 0 CET} - {-1569708000 7200 1 CEST} - {-1554332400 3600 0 CET} - {-906937200 3600 0 CET} + {-1581202800 3600 0 CET} + {-906771600 3600 0 CET} {-857257200 3600 0 CET} {-844556400 7200 1 CEST} {-828226800 3600 0 CET} @@ -22,7 +20,7 @@ set TZData(:Europe/Budapest) { {-796777200 3600 0 CET} {-788922000 3600 0 CET} {-778471200 7200 1 CEST} - {-762487200 3600 0 CET} + {-762660000 3600 0 CET} {-749689200 7200 1 CEST} {-733359600 3600 0 CET} {-717634800 7200 1 CEST} diff --git a/library/tzdata/Europe/Helsinki b/library/tzdata/Europe/Helsinki index 3abf790..39c5e78 100644 --- a/library/tzdata/Europe/Helsinki +++ b/library/tzdata/Europe/Helsinki @@ -1,11 +1,11 @@ # created by tools/tclZIC.tcl - do not edit set TZData(:Europe/Helsinki) { - {-9223372036854775808 5992 0 LMT} - {-2890258792 5992 0 HMT} - {-1535938792 7200 0 EET} + {-9223372036854775808 5989 0 LMT} + {-2890258789 5989 0 HMT} + {-1535938789 7200 0 EET} {-875671200 10800 1 EEST} - {-859863600 7200 0 EET} + {-859773600 7200 0 EET} {354672000 10800 1 EEST} {370396800 7200 0 EET} {386121600 10800 1 EEST} diff --git a/library/tzdata/Europe/Istanbul b/library/tzdata/Europe/Istanbul index 7737d75..7cb4820 100644 --- a/library/tzdata/Europe/Istanbul +++ b/library/tzdata/Europe/Istanbul @@ -129,7 +129,8 @@ set TZData(:Europe/Istanbul) { {1351386000 7200 0 EET} {1364691600 10800 1 EEST} {1382835600 7200 0 EET} - {1396141200 10800 1 EEST} + {1396141200 7200 0 EET} + {1396227600 10800 0 EEST} {1414285200 7200 0 EET} {1427590800 10800 1 EEST} {1445734800 7200 0 EET} diff --git a/library/tzdata/Europe/Kaliningrad b/library/tzdata/Europe/Kaliningrad index d5be459..d03f7d0 100644 --- a/library/tzdata/Europe/Kaliningrad +++ b/library/tzdata/Europe/Kaliningrad @@ -81,4 +81,5 @@ set TZData(:Europe/Kaliningrad) { {1269734400 10800 1 EEST} {1288483200 7200 0 EET} {1301184000 10800 0 FET} + {1414278000 7200 0 EET} } diff --git a/library/tzdata/Europe/Kiev b/library/tzdata/Europe/Kiev index 0206be7..55015fa 100644 --- a/library/tzdata/Europe/Kiev +++ b/library/tzdata/Europe/Kiev @@ -28,9 +28,9 @@ set TZData(:Europe/Kiev) { {591145200 10800 0 MSK} {606870000 14400 1 MSD} {622594800 10800 0 MSK} - {631141200 10800 0 MSK} - {646786800 7200 0 EET} - {694216800 7200 0 EET} + {638319600 14400 1 MSD} + {646786800 10800 1 EEST} + {686102400 7200 0 EET} {701820000 10800 1 EEST} {717541200 7200 0 EET} {733269600 10800 1 EEST} diff --git a/library/tzdata/Europe/Moscow b/library/tzdata/Europe/Moscow index 8f40741..686b3d0 100644 --- a/library/tzdata/Europe/Moscow +++ b/library/tzdata/Europe/Moscow @@ -1,20 +1,19 @@ # created by tools/tclZIC.tcl - do not edit set TZData(:Europe/Moscow) { - {-9223372036854775808 9020 0 LMT} - {-2840149820 9000 0 MMT} - {-1688265000 9048 0 MMT} - {-1656819048 12648 1 MST} - {-1641353448 9048 0 MMT} - {-1627965048 16248 1 MDST} - {-1618716648 12648 1 MST} - {-1596429048 16248 1 MDST} - {-1593822648 14400 0 MSD} + {-9223372036854775808 9017 0 LMT} + {-2840149817 9017 0 MMT} + {-1688265017 9079 0 MMT} + {-1656819079 12679 1 MST} + {-1641353479 9079 0 MMT} + {-1627965079 16279 1 MDST} + {-1618716679 12679 1 MST} + {-1596429079 16279 1 MDST} + {-1593822679 14400 0 MSD} {-1589860800 10800 0 MSK} {-1542427200 14400 1 MSD} - {-1539493200 18000 1 MSD} + {-1539493200 18000 1 MSM} {-1525323600 14400 1 MSD} - {-1522728000 10800 0 MSK} {-1491188400 7200 0 EET} {-1247536800 10800 0 MSD} {354920400 14400 1 MSD} @@ -80,4 +79,5 @@ set TZData(:Europe/Moscow) { {1269730800 14400 1 MSD} {1288479600 10800 0 MSK} {1301180400 14400 0 MSK} + {1414274400 10800 0 MSK} } diff --git a/library/tzdata/Europe/Riga b/library/tzdata/Europe/Riga index 9fad0f8..98cccc2 100644 --- a/library/tzdata/Europe/Riga +++ b/library/tzdata/Europe/Riga @@ -1,13 +1,13 @@ # created by tools/tclZIC.tcl - do not edit set TZData(:Europe/Riga) { - {-9223372036854775808 5784 0 LMT} - {-2840146584 5784 0 RMT} - {-1632008184 9384 1 LST} - {-1618702584 5784 0 RMT} - {-1601681784 9384 1 LST} - {-1597275384 5784 0 RMT} - {-1377308184 7200 0 EET} + {-9223372036854775808 5788 0 LMT} + {-2840146588 5788 0 RMT} + {-1632008188 9388 1 LST} + {-1618702588 5788 0 RMT} + {-1601681788 9388 1 LST} + {-1597275388 5788 0 RMT} + {-1377308188 7200 0 EET} {-928029600 10800 0 MSK} {-899521200 3600 0 CET} {-857257200 3600 0 CET} diff --git a/library/tzdata/Europe/Samara b/library/tzdata/Europe/Samara index f2ac911..243a42f 100644 --- a/library/tzdata/Europe/Samara +++ b/library/tzdata/Europe/Samara @@ -21,13 +21,13 @@ set TZData(:Europe/Samara) { {559692000 14400 0 KUYT} {575416800 18000 1 KUYST} {591141600 14400 0 KUYT} - {606866400 10800 0 KUYMMTT} - {606870000 14400 1 KUYST} - {622594800 10800 0 KUYT} - {638319600 14400 1 KUYST} - {654649200 10800 0 KUYT} - {670374000 7200 0 KUYMMTT} - {670377600 10800 1 KUYST} + {606866400 10800 0 MSD} + {606870000 14400 1 MSD} + {622594800 10800 0 MSK} + {638319600 14400 1 MSD} + {654649200 10800 0 MSK} + {670374000 7200 0 EEMMTT} + {670377600 10800 1 EEST} {686102400 10800 0 KUYT} {687916800 14400 0 SAMT} {701809200 18000 1 SAMST} diff --git a/library/tzdata/Europe/Simferopol b/library/tzdata/Europe/Simferopol index 9836560..f6431fa 100644 --- a/library/tzdata/Europe/Simferopol +++ b/library/tzdata/Europe/Simferopol @@ -78,176 +78,6 @@ set TZData(:Europe/Simferopol) { {1351386000 7200 0 EET} {1364691600 10800 1 EEST} {1382835600 7200 0 EET} - {1396141200 10800 1 EEST} - {1414285200 7200 0 EET} - {1427590800 10800 1 EEST} - {1445734800 7200 0 EET} - {1459040400 10800 1 EEST} - {1477789200 7200 0 EET} - {1490490000 10800 1 EEST} - {1509238800 7200 0 EET} - {1521939600 10800 1 EEST} - {1540688400 7200 0 EET} - {1553994000 10800 1 EEST} - {1572138000 7200 0 EET} - {1585443600 10800 1 EEST} - {1603587600 7200 0 EET} - {1616893200 10800 1 EEST} - {1635642000 7200 0 EET} - {1648342800 10800 1 EEST} - {1667091600 7200 0 EET} - {1679792400 10800 1 EEST} - {1698541200 7200 0 EET} - {1711846800 10800 1 EEST} - {1729990800 7200 0 EET} - {1743296400 10800 1 EEST} - {1761440400 7200 0 EET} - {1774746000 10800 1 EEST} - {1792890000 7200 0 EET} - {1806195600 10800 1 EEST} - {1824944400 7200 0 EET} - {1837645200 10800 1 EEST} - {1856394000 7200 0 EET} - {1869094800 10800 1 EEST} - {1887843600 7200 0 EET} - {1901149200 10800 1 EEST} - {1919293200 7200 0 EET} - {1932598800 10800 1 EEST} - {1950742800 7200 0 EET} - {1964048400 10800 1 EEST} - {1982797200 7200 0 EET} - {1995498000 10800 1 EEST} - {2014246800 7200 0 EET} - {2026947600 10800 1 EEST} - {2045696400 7200 0 EET} - {2058397200 10800 1 EEST} - {2077146000 7200 0 EET} - {2090451600 10800 1 EEST} - {2108595600 7200 0 EET} - {2121901200 10800 1 EEST} - {2140045200 7200 0 EET} - {2153350800 10800 1 EEST} - {2172099600 7200 0 EET} - {2184800400 10800 1 EEST} - {2203549200 7200 0 EET} - {2216250000 10800 1 EEST} - {2234998800 7200 0 EET} - {2248304400 10800 1 EEST} - {2266448400 7200 0 EET} - {2279754000 10800 1 EEST} - {2297898000 7200 0 EET} - {2311203600 10800 1 EEST} - {2329347600 7200 0 EET} - {2342653200 10800 1 EEST} - {2361402000 7200 0 EET} - {2374102800 10800 1 EEST} - {2392851600 7200 0 EET} - {2405552400 10800 1 EEST} - {2424301200 7200 0 EET} - {2437606800 10800 1 EEST} - {2455750800 7200 0 EET} - {2469056400 10800 1 EEST} - {2487200400 7200 0 EET} - {2500506000 10800 1 EEST} - {2519254800 7200 0 EET} - {2531955600 10800 1 EEST} - {2550704400 7200 0 EET} - {2563405200 10800 1 EEST} - {2582154000 7200 0 EET} - {2595459600 10800 1 EEST} - {2613603600 7200 0 EET} - {2626909200 10800 1 EEST} - {2645053200 7200 0 EET} - {2658358800 10800 1 EEST} - {2676502800 7200 0 EET} - {2689808400 10800 1 EEST} - {2708557200 7200 0 EET} - {2721258000 10800 1 EEST} - {2740006800 7200 0 EET} - {2752707600 10800 1 EEST} - {2771456400 7200 0 EET} - {2784762000 10800 1 EEST} - {2802906000 7200 0 EET} - {2816211600 10800 1 EEST} - {2834355600 7200 0 EET} - {2847661200 10800 1 EEST} - {2866410000 7200 0 EET} - {2879110800 10800 1 EEST} - {2897859600 7200 0 EET} - {2910560400 10800 1 EEST} - {2929309200 7200 0 EET} - {2942010000 10800 1 EEST} - {2960758800 7200 0 EET} - {2974064400 10800 1 EEST} - {2992208400 7200 0 EET} - {3005514000 10800 1 EEST} - {3023658000 7200 0 EET} - {3036963600 10800 1 EEST} - {3055712400 7200 0 EET} - {3068413200 10800 1 EEST} - {3087162000 7200 0 EET} - {3099862800 10800 1 EEST} - {3118611600 7200 0 EET} - {3131917200 10800 1 EEST} - {3150061200 7200 0 EET} - {3163366800 10800 1 EEST} - {3181510800 7200 0 EET} - {3194816400 10800 1 EEST} - {3212960400 7200 0 EET} - {3226266000 10800 1 EEST} - {3245014800 7200 0 EET} - {3257715600 10800 1 EEST} - {3276464400 7200 0 EET} - {3289165200 10800 1 EEST} - {3307914000 7200 0 EET} - {3321219600 10800 1 EEST} - {3339363600 7200 0 EET} - {3352669200 10800 1 EEST} - {3370813200 7200 0 EET} - {3384118800 10800 1 EEST} - {3402867600 7200 0 EET} - {3415568400 10800 1 EEST} - {3434317200 7200 0 EET} - {3447018000 10800 1 EEST} - {3465766800 7200 0 EET} - {3479072400 10800 1 EEST} - {3497216400 7200 0 EET} - {3510522000 10800 1 EEST} - {3528666000 7200 0 EET} - {3541971600 10800 1 EEST} - {3560115600 7200 0 EET} - {3573421200 10800 1 EEST} - {3592170000 7200 0 EET} - {3604870800 10800 1 EEST} - {3623619600 7200 0 EET} - {3636320400 10800 1 EEST} - {3655069200 7200 0 EET} - {3668374800 10800 1 EEST} - {3686518800 7200 0 EET} - {3699824400 10800 1 EEST} - {3717968400 7200 0 EET} - {3731274000 10800 1 EEST} - {3750022800 7200 0 EET} - {3762723600 10800 1 EEST} - {3781472400 7200 0 EET} - {3794173200 10800 1 EEST} - {3812922000 7200 0 EET} - {3825622800 10800 1 EEST} - {3844371600 7200 0 EET} - {3857677200 10800 1 EEST} - {3875821200 7200 0 EET} - {3889126800 10800 1 EEST} - {3907270800 7200 0 EET} - {3920576400 10800 1 EEST} - {3939325200 7200 0 EET} - {3952026000 10800 1 EEST} - {3970774800 7200 0 EET} - {3983475600 10800 1 EEST} - {4002224400 7200 0 EET} - {4015530000 10800 1 EEST} - {4033674000 7200 0 EET} - {4046979600 10800 1 EEST} - {4065123600 7200 0 EET} - {4078429200 10800 1 EEST} - {4096573200 7200 0 EET} + {1396137600 14400 0 MSK} + {1414274400 10800 0 MSK} } diff --git a/library/tzdata/Europe/Volgograd b/library/tzdata/Europe/Volgograd index c3f148f..8c29c58 100644 --- a/library/tzdata/Europe/Volgograd +++ b/library/tzdata/Europe/Volgograd @@ -28,43 +28,44 @@ set TZData(:Europe/Volgograd) { {638319600 14400 1 VOLST} {654649200 10800 0 VOLT} {670374000 14400 0 VOLT} - {701820000 14400 0 VOLST} - {717534000 10800 0 VOLT} - {733273200 14400 1 VOLST} - {748998000 10800 0 VOLT} - {764722800 14400 1 VOLST} - {780447600 10800 0 VOLT} - {796172400 14400 1 VOLST} - {811897200 10800 0 VOLT} - {828226800 14400 1 VOLST} - {846370800 10800 0 VOLT} - {859676400 14400 1 VOLST} - {877820400 10800 0 VOLT} - {891126000 14400 1 VOLST} - {909270000 10800 0 VOLT} - {922575600 14400 1 VOLST} - {941324400 10800 0 VOLT} - {954025200 14400 1 VOLST} - {972774000 10800 0 VOLT} - {985474800 14400 1 VOLST} - {1004223600 10800 0 VOLT} - {1017529200 14400 1 VOLST} - {1035673200 10800 0 VOLT} - {1048978800 14400 1 VOLST} - {1067122800 10800 0 VOLT} - {1080428400 14400 1 VOLST} - {1099177200 10800 0 VOLT} - {1111878000 14400 1 VOLST} - {1130626800 10800 0 VOLT} - {1143327600 14400 1 VOLST} - {1162076400 10800 0 VOLT} - {1174777200 14400 1 VOLST} - {1193526000 10800 0 VOLT} - {1206831600 14400 1 VOLST} - {1224975600 10800 0 VOLT} - {1238281200 14400 1 VOLST} - {1256425200 10800 0 VOLT} - {1269730800 14400 1 VOLST} - {1288479600 10800 0 VOLT} - {1301180400 14400 0 VOLT} + {701820000 14400 0 MSK} + {717534000 10800 0 MSK} + {733273200 14400 1 MSK} + {748998000 10800 0 MSK} + {764722800 14400 1 MSK} + {780447600 10800 0 MSK} + {796172400 14400 1 MSK} + {811897200 10800 0 MSK} + {828226800 14400 1 MSK} + {846370800 10800 0 MSK} + {859676400 14400 1 MSK} + {877820400 10800 0 MSK} + {891126000 14400 1 MSK} + {909270000 10800 0 MSK} + {922575600 14400 1 MSK} + {941324400 10800 0 MSK} + {954025200 14400 1 MSK} + {972774000 10800 0 MSK} + {985474800 14400 1 MSK} + {1004223600 10800 0 MSK} + {1017529200 14400 1 MSK} + {1035673200 10800 0 MSK} + {1048978800 14400 1 MSK} + {1067122800 10800 0 MSK} + {1080428400 14400 1 MSK} + {1099177200 10800 0 MSK} + {1111878000 14400 1 MSK} + {1130626800 10800 0 MSK} + {1143327600 14400 1 MSK} + {1162076400 10800 0 MSK} + {1174777200 14400 1 MSK} + {1193526000 10800 0 MSK} + {1206831600 14400 1 MSK} + {1224975600 10800 0 MSK} + {1238281200 14400 1 MSK} + {1256425200 10800 0 MSK} + {1269730800 14400 1 MSK} + {1288479600 10800 0 MSK} + {1301180400 14400 0 MSK} + {1414274400 10800 0 MSK} } diff --git a/library/tzdata/Pacific/Apia b/library/tzdata/Pacific/Apia index e6f33ad..21d6669 100644 --- a/library/tzdata/Pacific/Apia +++ b/library/tzdata/Pacific/Apia @@ -3,186 +3,186 @@ set TZData(:Pacific/Apia) { {-9223372036854775808 45184 0 LMT} {-2855737984 -41216 0 LMT} - {-1861878784 -41400 0 SAMT} - {-631110600 -39600 0 WST} - {1285498800 -36000 1 WSDT} - {1301752800 -39600 0 WST} - {1316872800 -36000 1 WSDT} - {1325239200 50400 1 WSDT} - {1333202400 46800 0 WST} + {-1861878784 -41400 0 WSST} + {-631110600 -39600 0 SST} + {1285498800 -36000 1 SDT} + {1301752800 -39600 0 SST} + {1316872800 -36000 1 SDT} + {1325239200 50400 0 WSDT} + {1333202400 46800 0 WSST} {1348927200 50400 1 WSDT} - {1365256800 46800 0 WST} + {1365256800 46800 0 WSST} {1380376800 50400 1 WSDT} - {1396706400 46800 0 WST} + {1396706400 46800 0 WSST} {1411826400 50400 1 WSDT} - {1428156000 46800 0 WST} + {1428156000 46800 0 WSST} {1443276000 50400 1 WSDT} - {1459605600 46800 0 WST} + {1459605600 46800 0 WSST} {1474725600 50400 1 WSDT} - {1491055200 46800 0 WST} + {1491055200 46800 0 WSST} {1506175200 50400 1 WSDT} - {1522504800 46800 0 WST} + {1522504800 46800 0 WSST} {1538229600 50400 1 WSDT} - {1554559200 46800 0 WST} + {1554559200 46800 0 WSST} {1569679200 50400 1 WSDT} - {1586008800 46800 0 WST} + {1586008800 46800 0 WSST} {1601128800 50400 1 WSDT} - {1617458400 46800 0 WST} + {1617458400 46800 0 WSST} {1632578400 50400 1 WSDT} - {1648908000 46800 0 WST} + {1648908000 46800 0 WSST} {1664028000 50400 1 WSDT} - {1680357600 46800 0 WST} + {1680357600 46800 0 WSST} {1695477600 50400 1 WSDT} - {1712412000 46800 0 WST} + {1712412000 46800 0 WSST} {1727532000 50400 1 WSDT} - {1743861600 46800 0 WST} + {1743861600 46800 0 WSST} {1758981600 50400 1 WSDT} - {1775311200 46800 0 WST} + {1775311200 46800 0 WSST} {1790431200 50400 1 WSDT} - {1806760800 46800 0 WST} + {1806760800 46800 0 WSST} {1821880800 50400 1 WSDT} - {1838210400 46800 0 WST} + {1838210400 46800 0 WSST} {1853330400 50400 1 WSDT} - {1869660000 46800 0 WST} + {1869660000 46800 0 WSST} {1885384800 50400 1 WSDT} - {1901714400 46800 0 WST} + {1901714400 46800 0 WSST} {1916834400 50400 1 WSDT} - {1933164000 46800 0 WST} + {1933164000 46800 0 WSST} {1948284000 50400 1 WSDT} - {1964613600 46800 0 WST} + {1964613600 46800 0 WSST} {1979733600 50400 1 WSDT} - {1996063200 46800 0 WST} + {1996063200 46800 0 WSST} {2011183200 50400 1 WSDT} - {2027512800 46800 0 WST} + {2027512800 46800 0 WSST} {2042632800 50400 1 WSDT} - {2058962400 46800 0 WST} + {2058962400 46800 0 WSST} {2074687200 50400 1 WSDT} - {2091016800 46800 0 WST} + {2091016800 46800 0 WSST} {2106136800 50400 1 WSDT} - {2122466400 46800 0 WST} + {2122466400 46800 0 WSST} {2137586400 50400 1 WSDT} - {2153916000 46800 0 WST} + {2153916000 46800 0 WSST} {2169036000 50400 1 WSDT} - {2185365600 46800 0 WST} + {2185365600 46800 0 WSST} {2200485600 50400 1 WSDT} - {2216815200 46800 0 WST} + {2216815200 46800 0 WSST} {2232540000 50400 1 WSDT} - {2248869600 46800 0 WST} + {2248869600 46800 0 WSST} {2263989600 50400 1 WSDT} - {2280319200 46800 0 WST} + {2280319200 46800 0 WSST} {2295439200 50400 1 WSDT} - {2311768800 46800 0 WST} + {2311768800 46800 0 WSST} {2326888800 50400 1 WSDT} - {2343218400 46800 0 WST} + {2343218400 46800 0 WSST} {2358338400 50400 1 WSDT} - {2374668000 46800 0 WST} + {2374668000 46800 0 WSST} {2389788000 50400 1 WSDT} - {2406117600 46800 0 WST} + {2406117600 46800 0 WSST} {2421842400 50400 1 WSDT} - {2438172000 46800 0 WST} + {2438172000 46800 0 WSST} {2453292000 50400 1 WSDT} - {2469621600 46800 0 WST} + {2469621600 46800 0 WSST} {2484741600 50400 1 WSDT} - {2501071200 46800 0 WST} + {2501071200 46800 0 WSST} {2516191200 50400 1 WSDT} - {2532520800 46800 0 WST} + {2532520800 46800 0 WSST} {2547640800 50400 1 WSDT} - {2563970400 46800 0 WST} + {2563970400 46800 0 WSST} {2579090400 50400 1 WSDT} - {2596024800 46800 0 WST} + {2596024800 46800 0 WSST} {2611144800 50400 1 WSDT} - {2627474400 46800 0 WST} + {2627474400 46800 0 WSST} {2642594400 50400 1 WSDT} - {2658924000 46800 0 WST} + {2658924000 46800 0 WSST} {2674044000 50400 1 WSDT} - {2690373600 46800 0 WST} + {2690373600 46800 0 WSST} {2705493600 50400 1 WSDT} - {2721823200 46800 0 WST} + {2721823200 46800 0 WSST} {2736943200 50400 1 WSDT} - {2753272800 46800 0 WST} + {2753272800 46800 0 WSST} {2768997600 50400 1 WSDT} - {2785327200 46800 0 WST} + {2785327200 46800 0 WSST} {2800447200 50400 1 WSDT} - {2816776800 46800 0 WST} + {2816776800 46800 0 WSST} {2831896800 50400 1 WSDT} - {2848226400 46800 0 WST} + {2848226400 46800 0 WSST} {2863346400 50400 1 WSDT} - {2879676000 46800 0 WST} + {2879676000 46800 0 WSST} {2894796000 50400 1 WSDT} - {2911125600 46800 0 WST} + {2911125600 46800 0 WSST} {2926245600 50400 1 WSDT} - {2942575200 46800 0 WST} + {2942575200 46800 0 WSST} {2958300000 50400 1 WSDT} - {2974629600 46800 0 WST} + {2974629600 46800 0 WSST} {2989749600 50400 1 WSDT} - {3006079200 46800 0 WST} + {3006079200 46800 0 WSST} {3021199200 50400 1 WSDT} - {3037528800 46800 0 WST} + {3037528800 46800 0 WSST} {3052648800 50400 1 WSDT} - {3068978400 46800 0 WST} + {3068978400 46800 0 WSST} {3084098400 50400 1 WSDT} - {3100428000 46800 0 WST} + {3100428000 46800 0 WSST} {3116152800 50400 1 WSDT} - {3132482400 46800 0 WST} + {3132482400 46800 0 WSST} {3147602400 50400 1 WSDT} - {3163932000 46800 0 WST} + {3163932000 46800 0 WSST} {3179052000 50400 1 WSDT} - {3195381600 46800 0 WST} + {3195381600 46800 0 WSST} {3210501600 50400 1 WSDT} - {3226831200 46800 0 WST} + {3226831200 46800 0 WSST} {3241951200 50400 1 WSDT} - {3258280800 46800 0 WST} + {3258280800 46800 0 WSST} {3273400800 50400 1 WSDT} - {3289730400 46800 0 WST} + {3289730400 46800 0 WSST} {3305455200 50400 1 WSDT} - {3321784800 46800 0 WST} + {3321784800 46800 0 WSST} {3336904800 50400 1 WSDT} - {3353234400 46800 0 WST} + {3353234400 46800 0 WSST} {3368354400 50400 1 WSDT} - {3384684000 46800 0 WST} + {3384684000 46800 0 WSST} {3399804000 50400 1 WSDT} - {3416133600 46800 0 WST} + {3416133600 46800 0 WSST} {3431253600 50400 1 WSDT} - {3447583200 46800 0 WST} + {3447583200 46800 0 WSST} {3462703200 50400 1 WSDT} - {3479637600 46800 0 WST} + {3479637600 46800 0 WSST} {3494757600 50400 1 WSDT} - {3511087200 46800 0 WST} + {3511087200 46800 0 WSST} {3526207200 50400 1 WSDT} - {3542536800 46800 0 WST} + {3542536800 46800 0 WSST} {3557656800 50400 1 WSDT} - {3573986400 46800 0 WST} + {3573986400 46800 0 WSST} {3589106400 50400 1 WSDT} - {3605436000 46800 0 WST} + {3605436000 46800 0 WSST} {3620556000 50400 1 WSDT} - {3636885600 46800 0 WST} + {3636885600 46800 0 WSST} {3652610400 50400 1 WSDT} - {3668940000 46800 0 WST} + {3668940000 46800 0 WSST} {3684060000 50400 1 WSDT} - {3700389600 46800 0 WST} + {3700389600 46800 0 WSST} {3715509600 50400 1 WSDT} - {3731839200 46800 0 WST} + {3731839200 46800 0 WSST} {3746959200 50400 1 WSDT} - {3763288800 46800 0 WST} + {3763288800 46800 0 WSST} {3778408800 50400 1 WSDT} - {3794738400 46800 0 WST} + {3794738400 46800 0 WSST} {3809858400 50400 1 WSDT} - {3826188000 46800 0 WST} + {3826188000 46800 0 WSST} {3841912800 50400 1 WSDT} - {3858242400 46800 0 WST} + {3858242400 46800 0 WSST} {3873362400 50400 1 WSDT} - {3889692000 46800 0 WST} + {3889692000 46800 0 WSST} {3904812000 50400 1 WSDT} - {3921141600 46800 0 WST} + {3921141600 46800 0 WSST} {3936261600 50400 1 WSDT} - {3952591200 46800 0 WST} + {3952591200 46800 0 WSST} {3967711200 50400 1 WSDT} - {3984040800 46800 0 WST} + {3984040800 46800 0 WSST} {3999765600 50400 1 WSDT} - {4016095200 46800 0 WST} + {4016095200 46800 0 WSST} {4031215200 50400 1 WSDT} - {4047544800 46800 0 WST} + {4047544800 46800 0 WSST} {4062664800 50400 1 WSDT} - {4078994400 46800 0 WST} + {4078994400 46800 0 WSST} {4094114400 50400 1 WSDT} } diff --git a/library/tzdata/Pacific/Chatham b/library/tzdata/Pacific/Chatham index 0ed2260..94a5512 100644 --- a/library/tzdata/Pacific/Chatham +++ b/library/tzdata/Pacific/Chatham @@ -2,7 +2,8 @@ set TZData(:Pacific/Chatham) { {-9223372036854775808 44028 0 LMT} - {-410271228 45900 0 CHAST} + {-3192437628 44100 0 CHAST} + {-757426500 45900 0 CHAST} {152632800 49500 1 CHADT} {162309600 45900 0 CHAST} {183477600 49500 1 CHADT} diff --git a/library/tzdata/Pacific/Fiji b/library/tzdata/Pacific/Fiji index 454ee87..e1602ee 100644 --- a/library/tzdata/Pacific/Fiji +++ b/library/tzdata/Pacific/Fiji @@ -16,176 +16,176 @@ set TZData(:Pacific/Fiji) { {1350741600 46800 1 FJST} {1358604000 43200 0 FJT} {1382796000 46800 1 FJST} - {1390053600 43200 0 FJT} + {1390050000 43200 0 FJT} {1414245600 46800 1 FJST} - {1421503200 43200 0 FJT} + {1421499600 43200 0 FJT} {1445695200 46800 1 FJST} - {1453557600 43200 0 FJT} + {1453554000 43200 0 FJT} {1477144800 46800 1 FJST} - {1485007200 43200 0 FJT} + {1485003600 43200 0 FJT} {1508594400 46800 1 FJST} - {1516456800 43200 0 FJT} + {1516453200 43200 0 FJT} {1540044000 46800 1 FJST} - {1547906400 43200 0 FJT} + {1547902800 43200 0 FJT} {1572098400 46800 1 FJST} - {1579356000 43200 0 FJT} + {1579352400 43200 0 FJT} {1603548000 46800 1 FJST} - {1611410400 43200 0 FJT} + {1611406800 43200 0 FJT} {1634997600 46800 1 FJST} - {1642860000 43200 0 FJT} + {1642856400 43200 0 FJT} {1666447200 46800 1 FJST} - {1674309600 43200 0 FJT} + {1674306000 43200 0 FJT} {1697896800 46800 1 FJST} - {1705759200 43200 0 FJT} + {1705755600 43200 0 FJT} {1729951200 46800 1 FJST} - {1737208800 43200 0 FJT} + {1737205200 43200 0 FJT} {1761400800 46800 1 FJST} - {1768658400 43200 0 FJT} + {1768654800 43200 0 FJT} {1792850400 46800 1 FJST} - {1800712800 43200 0 FJT} + {1800709200 43200 0 FJT} {1824300000 46800 1 FJST} - {1832162400 43200 0 FJT} + {1832158800 43200 0 FJT} {1855749600 46800 1 FJST} - {1863612000 43200 0 FJT} + {1863608400 43200 0 FJT} {1887199200 46800 1 FJST} - {1895061600 43200 0 FJT} + {1895058000 43200 0 FJT} {1919253600 46800 1 FJST} - {1926511200 43200 0 FJT} + {1926507600 43200 0 FJT} {1950703200 46800 1 FJST} - {1957960800 43200 0 FJT} + {1957957200 43200 0 FJT} {1982152800 46800 1 FJST} - {1990015200 43200 0 FJT} + {1990011600 43200 0 FJT} {2013602400 46800 1 FJST} - {2021464800 43200 0 FJT} + {2021461200 43200 0 FJT} {2045052000 46800 1 FJST} - {2052914400 43200 0 FJT} + {2052910800 43200 0 FJT} {2076501600 46800 1 FJST} - {2084364000 43200 0 FJT} + {2084360400 43200 0 FJT} {2108556000 46800 1 FJST} - {2115813600 43200 0 FJT} + {2115810000 43200 0 FJT} {2140005600 46800 1 FJST} - {2147868000 43200 0 FJT} + {2147864400 43200 0 FJT} {2171455200 46800 1 FJST} - {2179317600 43200 0 FJT} + {2179314000 43200 0 FJT} {2202904800 46800 1 FJST} - {2210767200 43200 0 FJT} + {2210763600 43200 0 FJT} {2234354400 46800 1 FJST} - {2242216800 43200 0 FJT} + {2242213200 43200 0 FJT} {2266408800 46800 1 FJST} - {2273666400 43200 0 FJT} + {2273662800 43200 0 FJT} {2297858400 46800 1 FJST} - {2305116000 43200 0 FJT} + {2305112400 43200 0 FJT} {2329308000 46800 1 FJST} - {2337170400 43200 0 FJT} + {2337166800 43200 0 FJT} {2360757600 46800 1 FJST} - {2368620000 43200 0 FJT} + {2368616400 43200 0 FJT} {2392207200 46800 1 FJST} - {2400069600 43200 0 FJT} + {2400066000 43200 0 FJT} {2423656800 46800 1 FJST} - {2431519200 43200 0 FJT} + {2431515600 43200 0 FJT} {2455711200 46800 1 FJST} - {2462968800 43200 0 FJT} + {2462965200 43200 0 FJT} {2487160800 46800 1 FJST} - {2495023200 43200 0 FJT} + {2495019600 43200 0 FJT} {2518610400 46800 1 FJST} - {2526472800 43200 0 FJT} + {2526469200 43200 0 FJT} {2550060000 46800 1 FJST} - {2557922400 43200 0 FJT} + {2557918800 43200 0 FJT} {2581509600 46800 1 FJST} - {2589372000 43200 0 FJT} + {2589368400 43200 0 FJT} {2613564000 46800 1 FJST} - {2620821600 43200 0 FJT} + {2620818000 43200 0 FJT} {2645013600 46800 1 FJST} - {2652271200 43200 0 FJT} + {2652267600 43200 0 FJT} {2676463200 46800 1 FJST} - {2684325600 43200 0 FJT} + {2684322000 43200 0 FJT} {2707912800 46800 1 FJST} - {2715775200 43200 0 FJT} + {2715771600 43200 0 FJT} {2739362400 46800 1 FJST} - {2747224800 43200 0 FJT} + {2747221200 43200 0 FJT} {2770812000 46800 1 FJST} - {2778674400 43200 0 FJT} + {2778670800 43200 0 FJT} {2802866400 46800 1 FJST} - {2810124000 43200 0 FJT} + {2810120400 43200 0 FJT} {2834316000 46800 1 FJST} - {2841573600 43200 0 FJT} + {2841570000 43200 0 FJT} {2865765600 46800 1 FJST} - {2873628000 43200 0 FJT} + {2873624400 43200 0 FJT} {2897215200 46800 1 FJST} - {2905077600 43200 0 FJT} + {2905074000 43200 0 FJT} {2928664800 46800 1 FJST} - {2936527200 43200 0 FJT} + {2936523600 43200 0 FJT} {2960114400 46800 1 FJST} - {2967976800 43200 0 FJT} + {2967973200 43200 0 FJT} {2992168800 46800 1 FJST} - {2999426400 43200 0 FJT} + {2999422800 43200 0 FJT} {3023618400 46800 1 FJST} - {3031480800 43200 0 FJT} + {3031477200 43200 0 FJT} {3055068000 46800 1 FJST} - {3062930400 43200 0 FJT} + {3062926800 43200 0 FJT} {3086517600 46800 1 FJST} - {3094380000 43200 0 FJT} + {3094376400 43200 0 FJT} {3117967200 46800 1 FJST} - {3125829600 43200 0 FJT} + {3125826000 43200 0 FJT} {3150021600 46800 1 FJST} - {3157279200 43200 0 FJT} + {3157275600 43200 0 FJT} {3181471200 46800 1 FJST} - {3188728800 43200 0 FJT} + {3188725200 43200 0 FJT} {3212920800 46800 1 FJST} - {3220783200 43200 0 FJT} + {3220779600 43200 0 FJT} {3244370400 46800 1 FJST} - {3252232800 43200 0 FJT} + {3252229200 43200 0 FJT} {3275820000 46800 1 FJST} - {3283682400 43200 0 FJT} + {3283678800 43200 0 FJT} {3307269600 46800 1 FJST} - {3315132000 43200 0 FJT} + {3315128400 43200 0 FJT} {3339324000 46800 1 FJST} - {3346581600 43200 0 FJT} + {3346578000 43200 0 FJT} {3370773600 46800 1 FJST} - {3378636000 43200 0 FJT} + {3378632400 43200 0 FJT} {3402223200 46800 1 FJST} - {3410085600 43200 0 FJT} + {3410082000 43200 0 FJT} {3433672800 46800 1 FJST} - {3441535200 43200 0 FJT} + {3441531600 43200 0 FJT} {3465122400 46800 1 FJST} - {3472984800 43200 0 FJT} + {3472981200 43200 0 FJT} {3497176800 46800 1 FJST} - {3504434400 43200 0 FJT} + {3504430800 43200 0 FJT} {3528626400 46800 1 FJST} - {3535884000 43200 0 FJT} + {3535880400 43200 0 FJT} {3560076000 46800 1 FJST} - {3567938400 43200 0 FJT} + {3567934800 43200 0 FJT} {3591525600 46800 1 FJST} - {3599388000 43200 0 FJT} + {3599384400 43200 0 FJT} {3622975200 46800 1 FJST} - {3630837600 43200 0 FJT} + {3630834000 43200 0 FJT} {3654424800 46800 1 FJST} - {3662287200 43200 0 FJT} + {3662283600 43200 0 FJT} {3686479200 46800 1 FJST} - {3693736800 43200 0 FJT} + {3693733200 43200 0 FJT} {3717928800 46800 1 FJST} - {3725186400 43200 0 FJT} + {3725182800 43200 0 FJT} {3749378400 46800 1 FJST} - {3757240800 43200 0 FJT} + {3757237200 43200 0 FJT} {3780828000 46800 1 FJST} - {3788690400 43200 0 FJT} + {3788686800 43200 0 FJT} {3812277600 46800 1 FJST} - {3820140000 43200 0 FJT} + {3820136400 43200 0 FJT} {3843727200 46800 1 FJST} - {3851589600 43200 0 FJT} + {3851586000 43200 0 FJT} {3875781600 46800 1 FJST} - {3883039200 43200 0 FJT} + {3883035600 43200 0 FJT} {3907231200 46800 1 FJST} - {3915093600 43200 0 FJT} + {3915090000 43200 0 FJT} {3938680800 46800 1 FJST} - {3946543200 43200 0 FJT} + {3946539600 43200 0 FJT} {3970130400 46800 1 FJST} - {3977992800 43200 0 FJT} + {3977989200 43200 0 FJT} {4001580000 46800 1 FJST} - {4009442400 43200 0 FJT} + {4009438800 43200 0 FJT} {4033634400 46800 1 FJST} - {4040892000 43200 0 FJT} + {4040888400 43200 0 FJT} {4065084000 46800 1 FJST} - {4072341600 43200 0 FJT} + {4072338000 43200 0 FJT} {4096533600 46800 1 FJST} } diff --git a/library/tzdata/Pacific/Pago_Pago b/library/tzdata/Pacific/Pago_Pago index 830f9ee..ca261d0 100644 --- a/library/tzdata/Pacific/Pago_Pago +++ b/library/tzdata/Pacific/Pago_Pago @@ -3,8 +3,7 @@ set TZData(:Pacific/Pago_Pago) { {-9223372036854775808 45432 0 LMT} {-2855738232 -40968 0 LMT} - {-1861879032 -41400 0 SAMT} - {-631110600 -39600 0 NST} + {-1861879032 -39600 0 NST} {-86878800 -39600 0 BST} {439038000 -39600 0 SST} } diff --git a/library/tzdata/SystemV/AST4 b/library/tzdata/SystemV/AST4 deleted file mode 100644 index eced0d2..0000000 --- a/library/tzdata/SystemV/AST4 +++ /dev/null @@ -1,5 +0,0 @@ -# created by ../tools/tclZIC.tcl - do not edit -if {![info exists TZData(America/Puerto_Rico)]} { - LoadTimeZoneFile America/Puerto_Rico -} -set TZData(:SystemV/AST4) $TZData(:America/Puerto_Rico) diff --git a/library/tzdata/SystemV/AST4ADT b/library/tzdata/SystemV/AST4ADT deleted file mode 100644 index c24308f..0000000 --- a/library/tzdata/SystemV/AST4ADT +++ /dev/null @@ -1,5 +0,0 @@ -# created by ../tools/tclZIC.tcl - do not edit -if {![info exists TZData(America/Halifax)]} { - LoadTimeZoneFile America/Halifax -} -set TZData(:SystemV/AST4ADT) $TZData(:America/Halifax) diff --git a/library/tzdata/SystemV/CST6 b/library/tzdata/SystemV/CST6 deleted file mode 100644 index d46c015..0000000 --- a/library/tzdata/SystemV/CST6 +++ /dev/null @@ -1,5 +0,0 @@ -# created by ../tools/tclZIC.tcl - do not edit -if {![info exists TZData(America/Regina)]} { - LoadTimeZoneFile America/Regina -} -set TZData(:SystemV/CST6) $TZData(:America/Regina) diff --git a/library/tzdata/SystemV/CST6CDT b/library/tzdata/SystemV/CST6CDT deleted file mode 100644 index 234af89..0000000 --- a/library/tzdata/SystemV/CST6CDT +++ /dev/null @@ -1,5 +0,0 @@ -# created by ../tools/tclZIC.tcl - do not edit -if {![info exists TZData(America/Chicago)]} { - LoadTimeZoneFile America/Chicago -} -set TZData(:SystemV/CST6CDT) $TZData(:America/Chicago) diff --git a/library/tzdata/SystemV/EST5 b/library/tzdata/SystemV/EST5 deleted file mode 100644 index 52818c1..0000000 --- a/library/tzdata/SystemV/EST5 +++ /dev/null @@ -1,5 +0,0 @@ -# created by ../tools/tclZIC.tcl - do not edit -if {![info exists TZData(America/Indianapolis)]} { - LoadTimeZoneFile America/Indianapolis -} -set TZData(:SystemV/EST5) $TZData(:America/Indianapolis) diff --git a/library/tzdata/SystemV/EST5EDT b/library/tzdata/SystemV/EST5EDT deleted file mode 100644 index 6cf2743..0000000 --- a/library/tzdata/SystemV/EST5EDT +++ /dev/null @@ -1,5 +0,0 @@ -# created by ../tools/tclZIC.tcl - do not edit -if {![info exists TZData(America/New_York)]} { - LoadTimeZoneFile America/New_York -} -set TZData(:SystemV/EST5EDT) $TZData(:America/New_York) diff --git a/library/tzdata/SystemV/HST10 b/library/tzdata/SystemV/HST10 deleted file mode 100644 index a4316af..0000000 --- a/library/tzdata/SystemV/HST10 +++ /dev/null @@ -1,5 +0,0 @@ -# created by ../tools/tclZIC.tcl - do not edit -if {![info exists TZData(Pacific/Honolulu)]} { - LoadTimeZoneFile Pacific/Honolulu -} -set TZData(:SystemV/HST10) $TZData(:Pacific/Honolulu) diff --git a/library/tzdata/SystemV/MST7 b/library/tzdata/SystemV/MST7 deleted file mode 100644 index e67a781..0000000 --- a/library/tzdata/SystemV/MST7 +++ /dev/null @@ -1,5 +0,0 @@ -# created by ../tools/tclZIC.tcl - do not edit -if {![info exists TZData(America/Phoenix)]} { - LoadTimeZoneFile America/Phoenix -} -set TZData(:SystemV/MST7) $TZData(:America/Phoenix) diff --git a/library/tzdata/SystemV/MST7MDT b/library/tzdata/SystemV/MST7MDT deleted file mode 100644 index fda5bf1..0000000 --- a/library/tzdata/SystemV/MST7MDT +++ /dev/null @@ -1,5 +0,0 @@ -# created by ../tools/tclZIC.tcl - do not edit -if {![info exists TZData(America/Denver)]} { - LoadTimeZoneFile America/Denver -} -set TZData(:SystemV/MST7MDT) $TZData(:America/Denver) diff --git a/library/tzdata/SystemV/PST8 b/library/tzdata/SystemV/PST8 deleted file mode 100644 index 8e30bb8..0000000 --- a/library/tzdata/SystemV/PST8 +++ /dev/null @@ -1,5 +0,0 @@ -# created by ../tools/tclZIC.tcl - do not edit -if {![info exists TZData(Pacific/Pitcairn)]} { - LoadTimeZoneFile Pacific/Pitcairn -} -set TZData(:SystemV/PST8) $TZData(:Pacific/Pitcairn) diff --git a/library/tzdata/SystemV/PST8PDT b/library/tzdata/SystemV/PST8PDT deleted file mode 100644 index 8281a9a..0000000 --- a/library/tzdata/SystemV/PST8PDT +++ /dev/null @@ -1,5 +0,0 @@ -# created by ../tools/tclZIC.tcl - do not edit -if {![info exists TZData(America/Los_Angeles)]} { - LoadTimeZoneFile America/Los_Angeles -} -set TZData(:SystemV/PST8PDT) $TZData(:America/Los_Angeles) diff --git a/library/tzdata/SystemV/YST9 b/library/tzdata/SystemV/YST9 deleted file mode 100644 index 32d3717..0000000 --- a/library/tzdata/SystemV/YST9 +++ /dev/null @@ -1,5 +0,0 @@ -# created by ../tools/tclZIC.tcl - do not edit -if {![info exists TZData(Pacific/Gambier)]} { - LoadTimeZoneFile Pacific/Gambier -} -set TZData(:SystemV/YST9) $TZData(:Pacific/Gambier) diff --git a/library/tzdata/SystemV/YST9YDT b/library/tzdata/SystemV/YST9YDT deleted file mode 100644 index fba405f..0000000 --- a/library/tzdata/SystemV/YST9YDT +++ /dev/null @@ -1,5 +0,0 @@ -# created by ../tools/tclZIC.tcl - do not edit -if {![info exists TZData(America/Anchorage)]} { - LoadTimeZoneFile America/Anchorage -} -set TZData(:SystemV/YST9YDT) $TZData(:America/Anchorage) -- cgit v0.12 From e4a9f37030eadaf359a6f5e0e92ca0ef54bd7963 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 13 Aug 2014 09:04:55 +0000 Subject: Put back SystemV timezone files, which were removed in previous commit. Don't know if that was by accident, but seems unwise in a Tcl patch release. --- library/tzdata/SystemV/AST4 | 5 +++++ library/tzdata/SystemV/AST4ADT | 5 +++++ library/tzdata/SystemV/CST6 | 5 +++++ library/tzdata/SystemV/CST6CDT | 5 +++++ library/tzdata/SystemV/EST5 | 5 +++++ library/tzdata/SystemV/EST5EDT | 5 +++++ library/tzdata/SystemV/HST10 | 5 +++++ library/tzdata/SystemV/MST7 | 5 +++++ library/tzdata/SystemV/MST7MDT | 5 +++++ library/tzdata/SystemV/PST8 | 5 +++++ library/tzdata/SystemV/PST8PDT | 5 +++++ library/tzdata/SystemV/YST9 | 5 +++++ library/tzdata/SystemV/YST9YDT | 5 +++++ 13 files changed, 65 insertions(+) create mode 100644 library/tzdata/SystemV/AST4 create mode 100644 library/tzdata/SystemV/AST4ADT create mode 100644 library/tzdata/SystemV/CST6 create mode 100644 library/tzdata/SystemV/CST6CDT create mode 100644 library/tzdata/SystemV/EST5 create mode 100644 library/tzdata/SystemV/EST5EDT create mode 100644 library/tzdata/SystemV/HST10 create mode 100644 library/tzdata/SystemV/MST7 create mode 100644 library/tzdata/SystemV/MST7MDT create mode 100644 library/tzdata/SystemV/PST8 create mode 100644 library/tzdata/SystemV/PST8PDT create mode 100644 library/tzdata/SystemV/YST9 create mode 100644 library/tzdata/SystemV/YST9YDT diff --git a/library/tzdata/SystemV/AST4 b/library/tzdata/SystemV/AST4 new file mode 100644 index 0000000..eced0d2 --- /dev/null +++ b/library/tzdata/SystemV/AST4 @@ -0,0 +1,5 @@ +# created by ../tools/tclZIC.tcl - do not edit +if {![info exists TZData(America/Puerto_Rico)]} { + LoadTimeZoneFile America/Puerto_Rico +} +set TZData(:SystemV/AST4) $TZData(:America/Puerto_Rico) diff --git a/library/tzdata/SystemV/AST4ADT b/library/tzdata/SystemV/AST4ADT new file mode 100644 index 0000000..c24308f --- /dev/null +++ b/library/tzdata/SystemV/AST4ADT @@ -0,0 +1,5 @@ +# created by ../tools/tclZIC.tcl - do not edit +if {![info exists TZData(America/Halifax)]} { + LoadTimeZoneFile America/Halifax +} +set TZData(:SystemV/AST4ADT) $TZData(:America/Halifax) diff --git a/library/tzdata/SystemV/CST6 b/library/tzdata/SystemV/CST6 new file mode 100644 index 0000000..d46c015 --- /dev/null +++ b/library/tzdata/SystemV/CST6 @@ -0,0 +1,5 @@ +# created by ../tools/tclZIC.tcl - do not edit +if {![info exists TZData(America/Regina)]} { + LoadTimeZoneFile America/Regina +} +set TZData(:SystemV/CST6) $TZData(:America/Regina) diff --git a/library/tzdata/SystemV/CST6CDT b/library/tzdata/SystemV/CST6CDT new file mode 100644 index 0000000..234af89 --- /dev/null +++ b/library/tzdata/SystemV/CST6CDT @@ -0,0 +1,5 @@ +# created by ../tools/tclZIC.tcl - do not edit +if {![info exists TZData(America/Chicago)]} { + LoadTimeZoneFile America/Chicago +} +set TZData(:SystemV/CST6CDT) $TZData(:America/Chicago) diff --git a/library/tzdata/SystemV/EST5 b/library/tzdata/SystemV/EST5 new file mode 100644 index 0000000..52818c1 --- /dev/null +++ b/library/tzdata/SystemV/EST5 @@ -0,0 +1,5 @@ +# created by ../tools/tclZIC.tcl - do not edit +if {![info exists TZData(America/Indianapolis)]} { + LoadTimeZoneFile America/Indianapolis +} +set TZData(:SystemV/EST5) $TZData(:America/Indianapolis) diff --git a/library/tzdata/SystemV/EST5EDT b/library/tzdata/SystemV/EST5EDT new file mode 100644 index 0000000..6cf2743 --- /dev/null +++ b/library/tzdata/SystemV/EST5EDT @@ -0,0 +1,5 @@ +# created by ../tools/tclZIC.tcl - do not edit +if {![info exists TZData(America/New_York)]} { + LoadTimeZoneFile America/New_York +} +set TZData(:SystemV/EST5EDT) $TZData(:America/New_York) diff --git a/library/tzdata/SystemV/HST10 b/library/tzdata/SystemV/HST10 new file mode 100644 index 0000000..a4316af --- /dev/null +++ b/library/tzdata/SystemV/HST10 @@ -0,0 +1,5 @@ +# created by ../tools/tclZIC.tcl - do not edit +if {![info exists TZData(Pacific/Honolulu)]} { + LoadTimeZoneFile Pacific/Honolulu +} +set TZData(:SystemV/HST10) $TZData(:Pacific/Honolulu) diff --git a/library/tzdata/SystemV/MST7 b/library/tzdata/SystemV/MST7 new file mode 100644 index 0000000..e67a781 --- /dev/null +++ b/library/tzdata/SystemV/MST7 @@ -0,0 +1,5 @@ +# created by ../tools/tclZIC.tcl - do not edit +if {![info exists TZData(America/Phoenix)]} { + LoadTimeZoneFile America/Phoenix +} +set TZData(:SystemV/MST7) $TZData(:America/Phoenix) diff --git a/library/tzdata/SystemV/MST7MDT b/library/tzdata/SystemV/MST7MDT new file mode 100644 index 0000000..fda5bf1 --- /dev/null +++ b/library/tzdata/SystemV/MST7MDT @@ -0,0 +1,5 @@ +# created by ../tools/tclZIC.tcl - do not edit +if {![info exists TZData(America/Denver)]} { + LoadTimeZoneFile America/Denver +} +set TZData(:SystemV/MST7MDT) $TZData(:America/Denver) diff --git a/library/tzdata/SystemV/PST8 b/library/tzdata/SystemV/PST8 new file mode 100644 index 0000000..8e30bb8 --- /dev/null +++ b/library/tzdata/SystemV/PST8 @@ -0,0 +1,5 @@ +# created by ../tools/tclZIC.tcl - do not edit +if {![info exists TZData(Pacific/Pitcairn)]} { + LoadTimeZoneFile Pacific/Pitcairn +} +set TZData(:SystemV/PST8) $TZData(:Pacific/Pitcairn) diff --git a/library/tzdata/SystemV/PST8PDT b/library/tzdata/SystemV/PST8PDT new file mode 100644 index 0000000..8281a9a --- /dev/null +++ b/library/tzdata/SystemV/PST8PDT @@ -0,0 +1,5 @@ +# created by ../tools/tclZIC.tcl - do not edit +if {![info exists TZData(America/Los_Angeles)]} { + LoadTimeZoneFile America/Los_Angeles +} +set TZData(:SystemV/PST8PDT) $TZData(:America/Los_Angeles) diff --git a/library/tzdata/SystemV/YST9 b/library/tzdata/SystemV/YST9 new file mode 100644 index 0000000..32d3717 --- /dev/null +++ b/library/tzdata/SystemV/YST9 @@ -0,0 +1,5 @@ +# created by ../tools/tclZIC.tcl - do not edit +if {![info exists TZData(Pacific/Gambier)]} { + LoadTimeZoneFile Pacific/Gambier +} +set TZData(:SystemV/YST9) $TZData(:Pacific/Gambier) diff --git a/library/tzdata/SystemV/YST9YDT b/library/tzdata/SystemV/YST9YDT new file mode 100644 index 0000000..fba405f --- /dev/null +++ b/library/tzdata/SystemV/YST9YDT @@ -0,0 +1,5 @@ +# created by ../tools/tclZIC.tcl - do not edit +if {![info exists TZData(America/Anchorage)]} { + LoadTimeZoneFile America/Anchorage +} +set TZData(:SystemV/YST9YDT) $TZData(:America/Anchorage) -- cgit v0.12 From d5113635d3553dac4edf4c2523c91a26c38676de Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 14 Aug 2014 16:48:08 +0000 Subject: Reconcile changes file with 8.6.1. --- changes | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changes b/changes index 9970cbc..5c90fd5 100644 --- a/changes +++ b/changes @@ -7792,7 +7792,7 @@ Many revisions to better support a Cygwin environment (nijtmans) --- Released 8.5.15, September 16, 2013 --- http://core.tcl.tk/tcl/ for details -2013-09-19 (bug fix)[3487626] [dict] compile segfaults (porter) +2013-09-19 (bug fix)[3487626] segfaults in [dict] compilers (porter) 2013-09-19 (bug fix) [info frame] line OBOEs in bytecode (porter) -- cgit v0.12 From 02b159d09e8d7f2a07070efa9a6a3a8f94a33945 Mon Sep 17 00:00:00 2001 From: dkf Date: Sun, 17 Aug 2014 15:23:49 +0000 Subject: [7d52e1101b] oo::object should know that oo::class is a subclass. --- generic/tclOO.c | 1 + tests/oo.test | 17 +++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/generic/tclOO.c b/generic/tclOO.c index 02e00c9..ace47fe 100644 --- a/generic/tclOO.c +++ b/generic/tclOO.c @@ -394,6 +394,7 @@ InitFoundation( fPtr->classCls->flags |= ROOT_CLASS; TclOOAddToInstances(fPtr->objectCls->thisPtr, fPtr->classCls); TclOOAddToInstances(fPtr->classCls->thisPtr, fPtr->classCls); + TclOOAddToSubclasses(fPtr->classCls, fPtr->objectCls); AddRef(fPtr->objectCls->thisPtr); AddRef(fPtr->objectCls); diff --git a/tests/oo.test b/tests/oo.test index fcd9818..8c515da 100644 --- a/tests/oo.test +++ b/tests/oo.test @@ -283,6 +283,23 @@ test oo-1.20 {basic test of OO functionality: my teardown post rename} -body { obj destroy info commands ::AGlobalName } -result {} +test oo-1.21 {basic test of OO functionality: default relations} -setup { + set fresh [interp create] +} -body { + lmap x [$fresh eval { + foreach cmd {instances subclasses mixins superclass} { + foreach initial {object class Slot} { + lappend x [info class $cmd ::oo::$initial] + } + } + foreach initial {object class Slot} { + lappend x [info object class ::oo::$initial] + } + return $x + }] {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} 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 36c74f50331351cde256504f59bad153e8a63fad Mon Sep 17 00:00:00 2001 From: dgp Date: Mon, 18 Aug 2014 13:28:58 +0000 Subject: Improved credit --- changes | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changes b/changes index 5c90fd5..0b56ec0 100644 --- a/changes +++ b/changes @@ -7816,7 +7816,7 @@ Many revisions to better support a Cygwin environment (nijtmans) 2014-02-06 (bug fix)[a4494e2] panic in test namespace-13.2 (porter) -2014-02-24 (bug fix)[2413550] Win: avoid serial double open (oehlmann) +2014-02-24 (bug fix)[2413550] Win: avoid serial double open (schroeter) 2014-03-20 (bug fix)[2f7cbd0] FreeBSD 10.0 build failure (nijtmans) -- cgit v0.12 From 344b547cd41344377fd6044104c7e624155c6e7e Mon Sep 17 00:00:00 2001 From: dgp Date: Tue, 19 Aug 2014 18:34:09 +0000 Subject: Update changes file. --- changes | 146 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 144 insertions(+), 2 deletions(-) diff --git a/changes b/changes index 659319c..ab01bed 100644 --- a/changes +++ b/changes @@ -8274,7 +8274,7 @@ Dropped support for OS X versions less than 10.4 (Tiger) (fellows) 2013-08-01 (bug fix)[1905562] RE recursion limit increased to support reported usage of large expressions (porter) -2013-08-02 (bug fix)[9d6162] superclass slot empty crash (vdgoot,fellows)2013-08-02 (bug fix)[9d6162] superclass slot empty crash (vdgoot,fellows) +2013-08-02 (bug fix)[9d6162] superclass slot empty crash (vdgoot,fellows) 2013-08-03 (enhancement)[3611643] [auto_mkindex] support TclOO (fellows) @@ -8303,4 +8303,146 @@ reported usage of large expressions (porter) Many optmizations, improvements, and tightened stack management in bytecode. ---- Released 8.6.1, Septemer 20, 2013 --- http://core.tcl.tk/tcl/ for details +--- Released 8.6.1, September 20, 2013 --- http://core.tcl.tk/tcl/ for details + +2013-09-27 (enhancement) improved ::env synchronization (fellows) + +2013-10-20 (bug fix)[2835313] segfault from +[apply {{} {while 1 {a {*}[return -level 0 -code continue]}}}] (fellows) + +2013-10-22 (bug fix)[3556215] [scan %E%G%X] support (fellows) + +2013-10-25 (bug fix)[3eb2ec1] upper case scheme names in url. (nijtmans) +=> http 2.8.8 + +2013-10-29 (bug fix)[414d103] HP-UX: restore [exec] in threaded Tcl (nijtmans) + +2013-11-04 (bug fix) C++ friendly stubs struct declarations (nijtmans) + +2013-11-05 (bug fix)[426679e] OpenBSD man page rendering (nijtmans) + +2013-11-12 (bug fix)[5425f2c] [fconfigure -error] breaks [socket -async] + +2013-11-20 (bug fix) Improved environment variable management (nijtmans) +=> tcltest 2.3.7 + +2013-11-21 (platforms) Support for Windows 8.1 (nijtmans) + +2013-12-06 (RFE) improved [foreach] bytecode (fellows) + +2013-12-10 (RFE) improved [lmap] bytecode (sofer) + +2013-12-11 (RFE) improved [catch] bytecode (sofer) + +2013-12-18 (bug fix)[0b874c3] SEGV [coroutine X coroutine Y info frame] (porter) + +2013-12-20 (RFE) reduced numeric conversion in bytecode (sofer) + +2014-01-07 (RFE) compilers for [concat], [linsert], [namespace origin], +[next], [string replace], [string tolower], [string totitle], [string toupper], +[string trim], [string trimleft], [string trimright] (fellows) + +2014-01-22 (RFE) compilers for [nextto], [yieldto] (fellows) + +2014-02-02 (RFE) compiler for [string is] (fellows) + +2014-02-06 (bug fix)[a4494e2] panic in test namespace-13.2 (porter) + +2014-03-20 (bug fix)[2f7cbd0] FreeBSD 10.0 build failure (nijtmans) + +2014-03-26 (RFE)[b42b208] Cygwin: [file attr -readonly -archive -hidden -system] +(nijtmans) + +2014-03-27 (bug fix) segfault iocmd-23.11 (porter) + +2014-04-04 (bug fix)[581937a,97069ea] async socket connect fail (oehlmann) + +2014-04-10 (bug fix)[792641f] Win: no \ in normalized path (nijtmans) + +2014-04-11 (bug fix)[3118489] protect NUL in filenames (nijtmans) + +2014-04-15 (bug fix)[88aef05] segfault iocmd-21.20 (porter) + +2014-04-16 (update) Win: use Winsock 2.2 (nijtmans) + +2014-04-16 (bug fix)[d19a30d] segfault clock-67.[23] (sebres) + +2014-04-21 (bug fix) segfault iocmd-21.2[12] (porter) + +2014-04-22 (bug fix) segfault iogt-2.4 (porter) + +2014-04-23 (bug fix)[3493120] memleak in thread exit + +2014-05-08 refactoring of core I/O functions (porter) + +2014-05-09 (bug fix)[3389978] Win: extended paths support (nijtmans) + +2014-05-09 (bug fix) segfault iocmd-32.1 (porter) + +2014-05-11 (bug fix)[6d2f249] nested ensemble compile failure (fellows) + +2014-05-17 (RFE)[47d6625] wideint support in [lsearch -integer] [lsort -integer] (nijtmans) + *** POTENTIAL INCOMPATIBILITY *** + +2014-05-20 (bug fix) Stop eof and blocked state leaking thru stacks (porter) + *** POTENTIAL INCOMPATIBILITY *** + +2014-05-28 (platforms) work around systems that fail when a shared library +is deleted after it is [load]ed (kupries) + +2014-05-31 (bug fix) chan events on pipes must be on proper ends (porter) + +2014-06-04 (bug fix) socket-2.12 (porter) + +2014-06-05 (bug fix) io-12.6 (kupries,porter) + +2014-06-15 (RFE)[1b0266d] [dict replace|remove] return canonical dict (fellows) + *** POTENTIAL INCOMPATIBILITY *** + +2014-06-16 (bug fix) socket-2.13 workaround broken select() (porter) + +2014-06-20 (bug fix)[b47b176] iortrans.tf-11.0 (porter) + +2014-06-22 (RFE)[2f9df4c] -cleanup scripts before -out compare (nijtmans) + +2014-07-04 (update) Update Unicode data to 7.0 (nijtmans) + *** POTENTIAL INCOMPATIBILITY *** + +2014-07-08 (bug) [chan push] converts blocked writes to error (aspect,porter) + +2014-07-10 (bug fix)[7368d2] memleak Tcl_SetVar2(..,TCL_APPEND_VALUE) (porter) + *** POTENTIAL INCOMPATIBILITY *** + +2014-07-11 (bug) leaks in SetFsPathFromAny, [info frame] (porter) + +2014-07-15 (bug) compress dict leak in zlib xform channel close (porter) + +2014-07-17 (bug fix)[9969cf8] leak trace data in coroutine deletion (porter) + +2014-07-18 (RFE)[b43f2b4] fix [lappend] multi performance collapse (fellows) + +2014-07-19 (bug fix)[75b8433] memleak managing oo instance lists (porter) + +2014-07-21 (bug fix)[e6477e1] memleak in AtForkChild() (porter) + +2014-07-22 (bug fix)[12b0997] memleak in iocmd.tf-32.0 (porter) + +2014-07-28 (RFE) Optimized binary [chan copy] by moving buffers (porter) + +2014-07-30 (enhancement) use refcounts, not Tcl_Preserve to manage lifetime +of Tcl_Channel (porter) + *** POTENTIAL INCOMPATIBILITY *** + +2014-07-31 (bug fix)[a84a720] double free in oo chain deletion (porter) + +2014-08-01 (bug fix)[e75faba] SEGV [apply {{} {namespace upvar a b [x]}}] (porter) + +2014-08-01 (update) "macosx*-i386-x86_64" "macosx-universal" no longer compatible (kupries) +=> platform 1.0.13 + +2014-08-12 tzdata updated to Olson's tzdata2014f (kenny) + +2014-08-17 (bug fix)[7d52e11] [info class subclasses oo::object] should +include ::oo::class (fellows) + +--- Released 8.6.2, August, 2014 --- http://core.tcl.tk/tcl/ for details -- cgit v0.12 From 71f6f450b22f7638365f550dde4690b93e20a251 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 20 Aug 2014 11:13:29 +0000 Subject: [74e073599e5e7c5eb535e2f60f1b06feb468eaae|74e073599e]: tclsh is using old style dialogs when Tk is loaded on Windows --- win/tclsh.exe.manifest.in | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/win/tclsh.exe.manifest.in b/win/tclsh.exe.manifest.in index aaa34e1..b7c4381 100644 --- a/win/tclsh.exe.manifest.in +++ b/win/tclsh.exe.manifest.in @@ -30,4 +30,22 @@ + + + true + + + + + + + -- cgit v0.12 From f8a968fdb89d8b439ed14ef8053db587cf99d931 Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 20 Aug 2014 14:28:36 +0000 Subject: Additions to changes. --- changes | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/changes b/changes index ab01bed..6cf3321 100644 --- a/changes +++ b/changes @@ -8355,6 +8355,8 @@ Many optmizations, improvements, and tightened stack management in bytecode. 2014-03-27 (bug fix) segfault iocmd-23.11 (porter) +2014-04-02 (bug fix)[581937a] Win: readable event on async connect failure + 2014-04-04 (bug fix)[581937a,97069ea] async socket connect fail (oehlmann) 2014-04-10 (bug fix)[792641f] Win: no \ in normalized path (nijtmans) @@ -8387,6 +8389,8 @@ Many optmizations, improvements, and tightened stack management in bytecode. 2014-05-20 (bug fix) Stop eof and blocked state leaking thru stacks (porter) *** POTENTIAL INCOMPATIBILITY *** +2014-05-20 (bug fix)[13d3af3] Win: socket -async tried only first IP address + 2014-05-28 (platforms) work around systems that fail when a shared library is deleted after it is [load]ed (kupries) -- cgit v0.12 From bc9dca8ca6394f96d81662b4eb6a97e77d31bdb5 Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 20 Aug 2014 17:50:41 +0000 Subject: Docs for Tcl_CreateChannelHandler() state that the registered handler proc will be called back with a mask value. "Mask is an integer mask indicating which of the requested conditions actually exists for the channel; it will contain ***a subset of the bits from the mask argument*** to Tcl_CreateChannelHandler when the handler was created." (emhpasis added). Tcl_NotifyChannel is not honoring this. It passes a mask value that may contain bits not in common with the mask argument to T_CCH(). This commit is a one-liner patch adding in the masking step to make things behave as documented. Thanks to apn for digging this out. (In combination with other questionable code, this led to a hang in test http-4.6 on Windows) Tcl_NotifyChannel() has had this error in all of recorded Tcl history. It's hard to imagine any code dependent on it though. If any exists, it can be revised to pass the mask value it truly needs to T_CCH() and end up with code suitable both before and after this change. If you concur, please merge to core-8-5-branch, and I'll take it from there. --- generic/tclIO.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index afffeb8..4452ae9 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -7716,7 +7716,7 @@ Tcl_NotifyChannel( if ((chPtr->mask & mask) != 0) { nh.nextHandlerPtr = chPtr->nextPtr; - (*(chPtr->proc))(chPtr->clientData, mask); + (*(chPtr->proc))(chPtr->clientData, chPtr->mask & mask); chPtr = nh.nextHandlerPtr; } else { chPtr = chPtr->nextPtr; -- cgit v0.12 From eda831ff7e1ffa43a792a3acb3504b1c2d7a2237 Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 20 Aug 2014 18:40:07 +0000 Subject: Make test io-36.1.1 more portable. --- tests/io.test | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/io.test b/tests/io.test index 925f8c6..7698cea 100644 --- a/tests/io.test +++ b/tests/io.test @@ -4924,7 +4924,10 @@ test io-36.1 {Tcl_InputBlocked on nonblocking pipe} {stdio openpipe} { test io-36.1.1 {Tcl_InputBlocked on nonblocking binary pipe} {stdio openpipe} { set f1 [open "|[list [interpreter]]" r+] chan configure $f1 -encoding binary -translation lf -eofchar {} - puts $f1 {puts hello_from_pipe} + puts $f1 { + chan configure stdout -encoding binary -translation lf -eofchar {} + puts hello_from_pipe + } flush $f1 gets $f1 fconfigure $f1 -blocking off -buffering full -- cgit v0.12 From 92f9aca55f1770a3bd88a0f48e2da3d17856d61b Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 21 Aug 2014 23:07:34 +0000 Subject: Test fix for likely cause of reported I/O slowdown. In a DoRead() revision, it came to favor making every effort to fill buffers, in preference to a more sensible goal of favoring avoiding calls out to the driver if there's already enough data in the buffers to satisfy the read operation. Result is many more calls out to recv() than are a good idea. Ought to show up most glaringly when many Tcl_Read() calls asking for small numbers of bytes (compared to buffer size) each, and that matches the reported case. --- generic/tclIO.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/generic/tclIO.c b/generic/tclIO.c index 4452ae9..4f81770 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -8855,6 +8855,7 @@ DoRead( /* If there is no full buffer, attempt to create and/or fill one. */ +if (bufPtr == NULL || BytesLeft(bufPtr) < bytesToRead) { while (!IsBufferFull(bufPtr)) { int code; @@ -8880,6 +8881,7 @@ DoRead( } assert (bufPtr != NULL); +} bytesRead = BytesLeft(bufPtr); bytesWritten = bytesToRead; -- cgit v0.12 From b08dc28c80317173b7bcfdf2eee65f68255b0d52 Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 22 Aug 2014 13:20:21 +0000 Subject: Same results; simpler logic. --- generic/tclIO.c | 28 +++++++--------------------- 1 file changed, 7 insertions(+), 21 deletions(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index 4f81770..93ac937 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -8853,36 +8853,22 @@ DoRead( break; } - /* If there is no full buffer, attempt to create and/or fill one. */ - -if (bufPtr == NULL || BytesLeft(bufPtr) < bytesToRead) { - while (!IsBufferFull(bufPtr)) { - int code; + /* + * If there is not enough data in the buffers to possibly + * complete the read, then go get more. + */ + if (bufPtr == NULL || BytesLeft(bufPtr) < bytesToRead) { moreData: - code = GetInput(chanPtr); - bufPtr = statePtr->inQueueHead; - - assert (bufPtr != NULL); - - if (GotFlag(statePtr, CHANNEL_EOF|CHANNEL_BLOCKED)) { - /* Further reads cannot do any more */ - break; - } - - if (code) { + if (GetInput(chanPtr)) { /* Read error */ UpdateInterest(chanPtr); TclChannelRelease((Tcl_Channel)chanPtr); return -1; } - - assert (IsBufferFull(bufPtr)); + bufPtr = statePtr->inQueueHead; } - assert (bufPtr != NULL); -} - bytesRead = BytesLeft(bufPtr); bytesWritten = bytesToRead; -- cgit v0.12 From 7ab1ebdc324c4251377faeedada72839835c2de7 Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 22 Aug 2014 21:52:37 +0000 Subject: Bump to TclOO 1.0.2 --- generic/tclOO.h | 2 +- unix/tclooConfig.sh | 2 +- win/tclooConfig.sh | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/generic/tclOO.h b/generic/tclOO.h index a6e8a22..24d3e6f 100644 --- a/generic/tclOO.h +++ b/generic/tclOO.h @@ -24,7 +24,7 @@ * win/tclooConfig.sh */ -#define TCLOO_VERSION "1.0.1" +#define TCLOO_VERSION "1.0.2" #define TCLOO_PATCHLEVEL TCLOO_VERSION #include "tcl.h" diff --git a/unix/tclooConfig.sh b/unix/tclooConfig.sh index 08cc4c5..14b0d8d 100644 --- a/unix/tclooConfig.sh +++ b/unix/tclooConfig.sh @@ -16,4 +16,4 @@ TCLOO_STUB_LIB_SPEC="" TCLOO_INCLUDE_SPEC="" TCLOO_PRIVATE_INCLUDE_SPEC="" TCLOO_CFLAGS="" -TCLOO_VERSION=1.0.1 +TCLOO_VERSION=1.0.2 diff --git a/win/tclooConfig.sh b/win/tclooConfig.sh index 08cc4c5..14b0d8d 100644 --- a/win/tclooConfig.sh +++ b/win/tclooConfig.sh @@ -16,4 +16,4 @@ TCLOO_STUB_LIB_SPEC="" TCLOO_INCLUDE_SPEC="" TCLOO_PRIVATE_INCLUDE_SPEC="" TCLOO_CFLAGS="" -TCLOO_VERSION=1.0.1 +TCLOO_VERSION=1.0.2 -- cgit v0.12 From dbacb46d52c18eeaee349a5f0780004d4e802a5c Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 22 Aug 2014 22:11:13 +0000 Subject: Bump to zlib 2.0.1. --- generic/tclZlib.c | 2 +- tests/zlib.test | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/generic/tclZlib.c b/generic/tclZlib.c index 06e18fe..956e3f9 100644 --- a/generic/tclZlib.c +++ b/generic/tclZlib.c @@ -26,7 +26,7 @@ * interface, even if that is mostly true). */ -#define TCL_ZLIB_VERSION "2.0" +#define TCL_ZLIB_VERSION "2.0.1" /* * Magic flags used with wbits fields to indicate that we're handling the gzip diff --git a/tests/zlib.test b/tests/zlib.test index 2346ec7..b1d43fb 100644 --- a/tests/zlib.test +++ b/tests/zlib.test @@ -35,7 +35,7 @@ test zlib-1.3 {zlib basics} -constraints zlib -body { } -result zlibVersion test zlib-1.4 {zlib basics} -constraints zlib -body { package present zlib -} -result 2.0 +} -result 2.0.1 test zlib-2.1 {zlib compress/decompress} zlib { zlib decompress [zlib compress abcdefghijklm] -- cgit v0.12 From a9c6d7868022ca853fee5927f7a888e19d9bc296 Mon Sep 17 00:00:00 2001 From: dgp Date: Mon, 25 Aug 2014 13:31:10 +0000 Subject: `make dist` allowed README-* fossil droppings to leak into the distribution. --- unix/Makefile.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/unix/Makefile.in b/unix/Makefile.in index f6e3b17..4fcdd14 100644 --- a/unix/Makefile.in +++ b/unix/Makefile.in @@ -1680,7 +1680,7 @@ dist: $(UNIX_DIR)/configure $(UNIX_DIR)/tclConfig.h.in $(UNIX_DIR)/tcl.pc.in $(M cp -p $(GENERIC_DIR)/*.decls $(DISTDIR)/generic cp -p $(GENERIC_DIR)/README $(DISTDIR)/generic cp -p $(GENERIC_DIR)/tclGetDate.y $(DISTDIR)/generic - cp -p $(TOP_DIR)/changes $(TOP_DIR)/ChangeLog $(TOP_DIR)/README* \ + cp -p $(TOP_DIR)/changes $(TOP_DIR)/ChangeLog $(TOP_DIR)/README \ $(TOP_DIR)/ChangeLog.[12]??? $(TOP_DIR)/license.terms \ $(DISTDIR) @mkdir $(DISTDIR)/library -- cgit v0.12 From ae0f801eaf658d7d34f14e5230e76082e9992cbb Mon Sep 17 00:00:00 2001 From: dgp Date: Mon, 25 Aug 2014 13:51:31 +0000 Subject: Do not let fossil README droppings leak into distribuion --- unix/Makefile.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/unix/Makefile.in b/unix/Makefile.in index 1b2ccf1..0d9b9f0 100644 --- a/unix/Makefile.in +++ b/unix/Makefile.in @@ -1975,7 +1975,7 @@ dist: $(UNIX_DIR)/configure $(UNIX_DIR)/tclConfig.h.in $(UNIX_DIR)/tcl.pc.in $(M cp -p $(GENERIC_DIR)/*.decls $(DISTDIR)/generic cp -p $(GENERIC_DIR)/README $(DISTDIR)/generic cp -p $(GENERIC_DIR)/tclGetDate.y $(DISTDIR)/generic - cp -p $(TOP_DIR)/changes $(TOP_DIR)/ChangeLog $(TOP_DIR)/README* \ + cp -p $(TOP_DIR)/changes $(TOP_DIR)/ChangeLog $(TOP_DIR)/README \ $(TOP_DIR)/ChangeLog.[12]??? $(TOP_DIR)/license.terms \ $(DISTDIR) @mkdir $(DISTDIR)/library -- cgit v0.12 From 77e18bafa56b3c0008480d1f6ae5ae752ef3f855 Mon Sep 17 00:00:00 2001 From: dkf Date: Thu, 28 Aug 2014 07:53:24 +0000 Subject: [b9e1a3032e] Implement the documented method search order for TclOO. This corrects the relative positions of object-defined methods and class mixins. --- generic/tclOOCall.c | 97 +++++++++++++++++++++++++++++++++++++++-------------- tests/ooNext2.test | 87 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 158 insertions(+), 26 deletions(-) diff --git a/generic/tclOOCall.c b/generic/tclOOCall.c index 897f635..2a81091 100644 --- a/generic/tclOOCall.c +++ b/generic/tclOOCall.c @@ -38,6 +38,12 @@ struct ChainBuilder { #define DEFINITE_PUBLIC 0x200000 #define KNOWN_STATE (DEFINITE_PROTECTED | DEFINITE_PUBLIC) #define SPECIAL (CONSTRUCTOR | DESTRUCTOR | FORCE_UNKNOWN) +#define BUILDING_MIXINS 0x400000 +#define TRAVERSED_MIXIN 0x800000 +#define OBJECT_MIXIN 0x1000000 +#define MIXIN_CONSISTENT(flags) \ + (((flags) & OBJECT_MIXIN) || \ + !((flags) & BUILDING_MIXINS) == !((flags) & TRAVERSED_MIXIN)) /* * Function declarations for things defined in this file. @@ -45,13 +51,13 @@ struct ChainBuilder { static void AddClassFiltersToCallContext(Object *const oPtr, Class *clsPtr, struct ChainBuilder *const cbPtr, - Tcl_HashTable *const doneFilters); + Tcl_HashTable *const doneFilters, int flags); static void AddClassMethodNames(Class *clsPtr, const int flags, Tcl_HashTable *const namesPtr); static inline void AddMethodToCallChain(Method *const mPtr, struct ChainBuilder *const cbPtr, Tcl_HashTable *const doneFilters, - Class *const filterDecl); + Class *const filterDecl, int flags); static inline void AddSimpleChainToCallContext(Object *const oPtr, Tcl_Obj *const methodNameObj, struct ChainBuilder *const cbPtr, @@ -434,7 +440,7 @@ TclOOGetSortedMethodList( AddClassMethodNames(oPtr->selfCls, flags, &names); FOREACH(mixinPtr, oPtr->mixins) { - AddClassMethodNames(mixinPtr, flags, &names); + AddClassMethodNames(mixinPtr, flags|TRAVERSED_MIXIN, &names); } /* @@ -598,7 +604,7 @@ AddClassMethodNames( /* TODO: Beware of infinite loops! */ FOREACH(mixinPtr, clsPtr->mixins) { - AddClassMethodNames(mixinPtr, flags, namesPtr); + AddClassMethodNames(mixinPtr, flags|TRAVERSED_MIXIN, namesPtr); } } @@ -695,13 +701,13 @@ AddSimpleChainToCallContext( FOREACH(mixinPtr, oPtr->mixins) { AddSimpleClassChainToCallContext(mixinPtr, methodNameObj, cbPtr, - doneFilters, flags, filterDecl); + doneFilters, flags|TRAVERSED_MIXIN, filterDecl); } if (oPtr->methodsPtr) { hPtr = Tcl_FindHashEntry(oPtr->methodsPtr, (char*) methodNameObj); if (hPtr != NULL) { AddMethodToCallChain(Tcl_GetHashValue(hPtr), cbPtr, - doneFilters, filterDecl); + doneFilters, filterDecl, flags); } } } @@ -732,9 +738,15 @@ AddMethodToCallChain( * processed. If NULL, not processing filters. * Note that this function does not update * this hashtable. */ - Class *const filterDecl) /* The class that declared the filter. If + Class *const filterDecl, /* The class that declared the filter. If * NULL, either the filter was declared by the * object or this isn't a filter. */ + int flags) /* Used to check if we're mixin-consistent + * only. Mixin-consistent means that either + * we're looking to add things from a mixin + * and we have passed a mixin, or we're not + * looking to add things from a mixin and have + * not passed a mixin. */ { register CallChain *callPtr = cbPtr->callChainPtr; int i; @@ -743,9 +755,11 @@ AddMethodToCallChain( * Return if this is just an entry used to record whether this is a public * method. If so, there's nothing real to call and so nothing to add to * the call chain. + * + * This is also where we enforce mixin-consistency. */ - if (mPtr == NULL || mPtr->typePtr == NULL) { + if (mPtr == NULL || mPtr->typePtr == NULL || !MIXIN_CONSISTENT(flags)) { return; } @@ -1001,6 +1015,8 @@ TclOOGetCallContext( if (flags & FORCE_UNKNOWN) { AddSimpleChainToCallContext(oPtr, oPtr->fPtr->unknownMethodNameObj, + &cb, NULL, BUILDING_MIXINS, NULL); + AddSimpleChainToCallContext(oPtr, oPtr->fPtr->unknownMethodNameObj, &cb, NULL, 0, NULL); callPtr->flags |= OO_UNKNOWN_METHOD; callPtr->epoch = -1; @@ -1024,21 +1040,32 @@ TclOOGetCallContext( doFilters = 1; Tcl_InitObjHashTable(&doneFilters); FOREACH(mixinPtr, oPtr->mixins) { - AddClassFiltersToCallContext(oPtr, mixinPtr, &cb, &doneFilters); + AddClassFiltersToCallContext(oPtr, mixinPtr, &cb, &doneFilters, + TRAVERSED_MIXIN|BUILDING_MIXINS|OBJECT_MIXIN); + AddClassFiltersToCallContext(oPtr, mixinPtr, &cb, &doneFilters, + OBJECT_MIXIN); } FOREACH(filterObj, oPtr->filters) { + AddSimpleChainToCallContext(oPtr, filterObj, &cb, &doneFilters, + BUILDING_MIXINS, NULL); AddSimpleChainToCallContext(oPtr, filterObj, &cb, &doneFilters, 0, NULL); } - AddClassFiltersToCallContext(oPtr, oPtr->selfCls, &cb, &doneFilters); + AddClassFiltersToCallContext(oPtr, oPtr->selfCls, &cb, &doneFilters, + BUILDING_MIXINS); + AddClassFiltersToCallContext(oPtr, oPtr->selfCls, &cb, &doneFilters, + 0); Tcl_DeleteHashTable(&doneFilters); } count = cb.filterLength = callPtr->numChain; /* - * Add the actual method implementations. + * Add the actual method implementations. We have to do this twice to + * handle class mixins right. */ + AddSimpleChainToCallContext(oPtr, methodNameObj, &cb, NULL, + flags|BUILDING_MIXINS, NULL); AddSimpleChainToCallContext(oPtr, methodNameObj, &cb, NULL, flags, NULL); /* @@ -1058,6 +1085,8 @@ TclOOGetCallContext( return NULL; } AddSimpleChainToCallContext(oPtr, oPtr->fPtr->unknownMethodNameObj, + &cb, NULL, BUILDING_MIXINS, NULL); + AddSimpleChainToCallContext(oPtr, oPtr->fPtr->unknownMethodNameObj, &cb, NULL, 0, NULL); callPtr->flags |= OO_UNKNOWN_METHOD; callPtr->epoch = -1; @@ -1201,7 +1230,9 @@ TclOOGetStereotypeCallChain( */ Tcl_InitObjHashTable(&doneFilters); - AddClassFiltersToCallContext(&obj, clsPtr, &cb, &doneFilters); + AddClassFiltersToCallContext(&obj, clsPtr, &cb, &doneFilters, + BUILDING_MIXINS); + AddClassFiltersToCallContext(&obj, clsPtr, &cb, &doneFilters, 0); Tcl_DeleteHashTable(&doneFilters); count = cb.filterLength = callPtr->numChain; @@ -1209,6 +1240,8 @@ TclOOGetStereotypeCallChain( * Add the actual method implementations. */ + AddSimpleChainToCallContext(&obj, methodNameObj, &cb, NULL, + flags|BUILDING_MIXINS, NULL); AddSimpleChainToCallContext(&obj, methodNameObj, &cb, NULL, flags, NULL); /* @@ -1219,6 +1252,8 @@ TclOOGetStereotypeCallChain( if (count == callPtr->numChain) { AddSimpleChainToCallContext(&obj, fPtr->unknownMethodNameObj, &cb, + NULL, BUILDING_MIXINS, NULL); + AddSimpleChainToCallContext(&obj, fPtr->unknownMethodNameObj, &cb, NULL, 0, NULL); callPtr->flags |= OO_UNKNOWN_METHOD; callPtr->epoch = -1; @@ -1259,12 +1294,15 @@ AddClassFiltersToCallContext( Class *clsPtr, /* Class to get the filters from. */ struct ChainBuilder *const cbPtr, /* Context to fill with call chain entries. */ - Tcl_HashTable *const doneFilters) + Tcl_HashTable *const doneFilters, /* Where to record what filters have been * processed. Keys are objects, values are * ignored. */ + int flags) /* Whether we've gone along a mixin link + * yet. */ { - int i; + int i, clearedFlags = + flags & ~(TRAVERSED_MIXIN|OBJECT_MIXIN|BUILDING_MIXINS); Class *superPtr, *mixinPtr; Tcl_Obj *filterObj; @@ -1279,7 +1317,8 @@ AddClassFiltersToCallContext( */ FOREACH(mixinPtr, clsPtr->mixins) { - AddClassFiltersToCallContext(oPtr, mixinPtr, cbPtr, doneFilters); + AddClassFiltersToCallContext(oPtr, mixinPtr, cbPtr, doneFilters, + flags|TRAVERSED_MIXIN); } /* @@ -1288,13 +1327,18 @@ AddClassFiltersToCallContext( * override how filters work to extend their behaviour. */ - FOREACH(filterObj, clsPtr->filters) { - int isNew; + if (MIXIN_CONSISTENT(flags)) { + FOREACH(filterObj, clsPtr->filters) { + int isNew; - (void) Tcl_CreateHashEntry(doneFilters, (char *) filterObj, &isNew); - if (isNew) { - AddSimpleChainToCallContext(oPtr, filterObj, cbPtr, doneFilters, - 0, clsPtr); + (void) Tcl_CreateHashEntry(doneFilters, (char *) filterObj, + &isNew); + if (isNew) { + AddSimpleChainToCallContext(oPtr, filterObj, cbPtr, + doneFilters, clearedFlags|BUILDING_MIXINS, clsPtr); + AddSimpleChainToCallContext(oPtr, filterObj, cbPtr, + doneFilters, clearedFlags, clsPtr); + } } } @@ -1308,7 +1352,8 @@ AddClassFiltersToCallContext( goto tailRecurse; default: FOREACH(superPtr, clsPtr->superclasses) { - AddClassFiltersToCallContext(oPtr, superPtr, cbPtr, doneFilters); + AddClassFiltersToCallContext(oPtr, superPtr, cbPtr, doneFilters, + flags); } case 0: return; @@ -1355,16 +1400,16 @@ AddSimpleClassChainToCallContext( tailRecurse: FOREACH(superPtr, classPtr->mixins) { AddSimpleClassChainToCallContext(superPtr, methodNameObj, cbPtr, - doneFilters, flags, filterDecl); + doneFilters, flags|TRAVERSED_MIXIN, filterDecl); } if (flags & CONSTRUCTOR) { AddMethodToCallChain(classPtr->constructorPtr, cbPtr, doneFilters, - filterDecl); + filterDecl, flags); } else if (flags & DESTRUCTOR) { AddMethodToCallChain(classPtr->destructorPtr, cbPtr, doneFilters, - filterDecl); + filterDecl, flags); } else { Tcl_HashEntry *hPtr = Tcl_FindHashEntry(&classPtr->classMethods, (char *) methodNameObj); @@ -1383,7 +1428,7 @@ AddSimpleClassChainToCallContext( flags |= DEFINITE_PROTECTED; } } - AddMethodToCallChain(mPtr, cbPtr, doneFilters, filterDecl); + AddMethodToCallChain(mPtr, cbPtr, doneFilters, filterDecl, flags); } } diff --git a/tests/ooNext2.test b/tests/ooNext2.test index a47aa91..9a63577 100644 --- a/tests/ooNext2.test +++ b/tests/ooNext2.test @@ -526,6 +526,93 @@ test oo-call-1.19 {object call introspection - memory leaks} -setup { } -cleanup { leaktester destroy } -constraints memory -result 0 +test oo-call-1.20 {object call introspection - complex case} -setup { + oo::class create root +} -body { + oo::class create ::A { + superclass root + method x {} {} + } + oo::class create ::B { + superclass A + method x {} {} + } + oo::class create ::C { + superclass root + method x {} {} + mixin B + } + oo::class create ::D { + superclass C + method x {} {} + } + oo::class create ::E { + superclass root + method x {} {} + } + oo::class create ::F { + superclass E + method x {} {} + } + oo::class create ::G { + superclass root + method x {} {} + } + oo::class create ::H { + superclass G + method x {} {} + } + oo::define F mixin H + F create y + oo::objdefine y { + method x {} {} + mixin D + } + info object call y x +} -cleanup { + root destroy +} -result {{method x ::D method} {method x ::B method} {method x ::A method} {method x ::C method} {method x ::H method} {method x ::G method} {method x object method} {method x ::F method} {method x ::E method}} +test oo-call-1.21 {object call introspection - complex case} -setup { + oo::class create root +} -body { + oo::class create ::A { + superclass root + method y {} {} + filter y + } + oo::class create ::B { + superclass A + method y {} {} + } + oo::class create ::C { + superclass root + method x {} {} + mixin B + } + oo::class create ::D { + superclass C + filter x + } + oo::class create ::E { + superclass root + method y {} {} + method x {} {} + } + oo::class create ::F { + superclass E + method z {} {} + method q {} {} + } + F create y + oo::objdefine y { + method unknown {} {} + mixin D + filter q + } + info object call y z +} -cleanup { + root destroy +} -result {{filter x ::C method} {filter x ::E method} {filter y ::B method} {filter y ::A method} {filter y ::E method} {filter q ::F method} {method z ::F method}} test oo-call-2.1 {class call introspection} -setup { oo::class create root -- cgit v0.12 From 6e00c594ea10a9f7912c9076342e8a325e9c8777 Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 29 Aug 2014 17:33:06 +0000 Subject: Use TclpSys* macros, not direct system calls. --- generic/tclThreadAlloc.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/generic/tclThreadAlloc.c b/generic/tclThreadAlloc.c index ddf888a..5cb8027 100644 --- a/generic/tclThreadAlloc.c +++ b/generic/tclThreadAlloc.c @@ -287,7 +287,7 @@ TclFreeAllocCache( *nextPtrPtr = cachePtr->nextPtr; cachePtr->nextPtr = NULL; Tcl_MutexUnlock(listLockPtr); - free(cachePtr); + TclpSysFree(cachePtr); } /* @@ -332,7 +332,7 @@ TclpAlloc( /* * Increment the requested size to include room for the Block structure. - * Call malloc() directly if the required amount is greater than the + * Call TclpSysAlloc() directly if the required amount is greater than the * largest block, otherwise pop the smallest block large enough, * allocating more blocks if necessary. */ @@ -344,7 +344,7 @@ TclpAlloc( #endif if (size > MAXALLOC) { bucket = NBUCKETS; - blockPtr = malloc(size); + blockPtr = TclpSysAlloc(size, 0); if (blockPtr != NULL) { cachePtr->totalAssigned += reqSize; } @@ -407,7 +407,7 @@ TclpFree( bucket = blockPtr->sourceBucket; if (bucket == NBUCKETS) { cachePtr->totalAssigned -= blockPtr->blockReqSize; - free(blockPtr); + TclpSysFree(blockPtr); return; } @@ -472,7 +472,7 @@ TclpRealloc( /* * If the block is not a system block and fits in place, simply return the * existing pointer. Otherwise, if the block is a system block and the new - * size would also require a system block, call realloc() directly. + * size would also require a system block, call TclpSysRealloc() directly. */ blockPtr = Ptr2Block(ptr); @@ -495,7 +495,7 @@ TclpRealloc( } else if (size > MAXALLOC) { cachePtr->totalAssigned -= blockPtr->blockReqSize; cachePtr->totalAssigned += reqSize; - blockPtr = realloc(blockPtr, size); + blockPtr = TclpSysRealloc(blockPtr, size); if (blockPtr == NULL) { return NULL; } @@ -567,7 +567,7 @@ TclThreadAllocObj(void) Tcl_Obj *newObjsPtr; cachePtr->numObjects = numMove = NOBJALLOC; - newObjsPtr = malloc(sizeof(Tcl_Obj) * numMove); + newObjsPtr = TclpSysAlloc(sizeof(Tcl_Obj) * numMove, 0); if (newObjsPtr == NULL) { Tcl_Panic("alloc: could not allocate %d new objects", numMove); } @@ -964,7 +964,7 @@ GetBlocks( if (blockPtr == NULL) { size = MAXALLOC; - blockPtr = malloc(size); + blockPtr = TclpSysAlloc(size, 0); if (blockPtr == NULL) { return 0; } -- cgit v0.12 From 6d02d4e9dc3e8e56e9dbc4d1199a7f0abd8ad859 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Mon, 1 Sep 2014 08:11:52 +0000 Subject: Combine TCL_SHLIB_LD_EXTRAS+TK_SHLIB_LD_EXTRAS (for Cygwin and FreeBSD) to a single SHLIB_LD_LIBS usable for both Tcl and Tk. --- unix/configure | 6 ++---- unix/tcl.m4 | 6 ++---- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/unix/configure b/unix/configure index e4ff106..d11e7d2 100755 --- a/unix/configure +++ b/unix/configure @@ -6938,8 +6938,7 @@ fi LD_SEARCH_FLAGS="" TCL_NEEDS_EXP_FILE=1 TCL_EXPORT_FILE_SUFFIX='${VERSION}\$\{DBGX\}.dll.a' - TCL_SHLIB_LD_EXTRAS='-Wl,--out-implib,$@.a' - TK_SHLIB_LD_EXTRAS='-Wl,--out-implib,$@.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 @@ -7644,8 +7643,7 @@ fi # This configuration from FreeBSD Ports. SHLIB_CFLAGS="-fPIC" SHLIB_LD="${CC} -shared" - TCL_SHLIB_LD_EXTRAS="-Wl,-soname,\$@" - TK_SHLIB_LD_EXTRAS="-Wl,-soname,\$@" + SHLIB_LD_LIBS="${SHLIB_LD_LIBS} -Wl,-soname,\$@" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" diff --git a/unix/tcl.m4 b/unix/tcl.m4 index b6c86b6..437ce3d 100644 --- a/unix/tcl.m4 +++ b/unix/tcl.m4 @@ -1246,8 +1246,7 @@ AC_DEFUN([SC_CONFIG_CFLAGS], [ LD_SEARCH_FLAGS="" TCL_NEEDS_EXP_FILE=1 TCL_EXPORT_FILE_SUFFIX='${VERSION}\$\{DBGX\}.dll.a' - TCL_SHLIB_LD_EXTRAS='-Wl,--out-implib,$[@].a' - TK_SHLIB_LD_EXTRAS='-Wl,--out-implib,$[@].a' + SHLIB_LD_LIBS="${SHLIB_LD_LIBS} -Wl,--out-implib,\$[@].a" AC_CACHE_CHECK(for Cygwin version of gcc, ac_cv_cygwin, AC_TRY_COMPILE([ @@ -1555,8 +1554,7 @@ AC_DEFUN([SC_CONFIG_CFLAGS], [ # This configuration from FreeBSD Ports. SHLIB_CFLAGS="-fPIC" SHLIB_LD="${CC} -shared" - TCL_SHLIB_LD_EXTRAS="-Wl,-soname,\$[@]" - TK_SHLIB_LD_EXTRAS="-Wl,-soname,\$[@]" + SHLIB_LD_LIBS="${SHLIB_LD_LIBS} -Wl,-soname,\$[@]" SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" DL_LIBS="" -- cgit v0.12 From 2e4f40528bb5671c3fdb9fb219ad3a971ba0e805 Mon Sep 17 00:00:00 2001 From: ferrieux Date: Tue, 2 Sep 2014 21:57:20 +0000 Subject: Add test cases in very first position for hang-on-exit, both in (normal) quick-exit and TCL_FINALIZE_ON_EXIT=1 modes. --- tests/aaa_exit.test | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 tests/aaa_exit.test diff --git a/tests/aaa_exit.test b/tests/aaa_exit.test new file mode 100644 index 0000000..51a94d7 --- /dev/null +++ b/tests/aaa_exit.test @@ -0,0 +1,41 @@ +# Commands covered: exit, emphasis on finalization hangs +# +# 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) 1991-1993 The Regents of the University of California. +# Copyright (c) 1994-1997 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 {[lsearch [namespace children] ::tcltest] == -1} { + package require tcltest 2 + namespace import -force ::tcltest::* +} + + +test exit-1.1 {normal, quick exit} { + set f [open "|[interpreter] << \"exec [interpreter] << {set ::env(TCL_FINALIZE_ON_EXIT) 0;exit}\" 2>@ stderr" r] + set aft [after 5000 {set done "Quick exit hangs !!!"}] + fileevent $f readable {after cancel $aft;set done OK} + vwait done + catch {fconfigure $f -blocking 0;close $f} + set done +} OK + +test exit-1.2 {full-finalized exit} { + set f [open "|[interpreter] << \"exec [interpreter] << {set ::env(TCL_FINALIZE_ON_EXIT) 1;exit}\" 2>@ stderr" r] + set aft [after 5000 {set done "Full-finalized exit hangs !!!"}] + fileevent $f readable {after cancel $aft;set done OK} + vwait done + catch {fconfigure $f -blocking 0;close $f} + set done +} OK + + +# cleanup +::tcltest::cleanupTests +return -- cgit v0.12 From a024a5233549ac0d0334b87616ec74a760fe3e82 Mon Sep 17 00:00:00 2001 From: ferrieux Date: Tue, 2 Sep 2014 22:00:03 +0000 Subject: Refrain from calling TclFinalizeThreadData() in quick-exit case as it is useless (just memory freeing). Superficially fixes [Bug 132fad6f]; that bug is still exerciseable thanks to recent additions to the test suite that exercise full finalization. --- generic/tclEvent.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/generic/tclEvent.c b/generic/tclEvent.c index 941d566..ab219a6 100644 --- a/generic/tclEvent.c +++ b/generic/tclEvent.c @@ -1299,18 +1299,20 @@ Tcl_FinalizeThread(void) TclFinalizeAsync(); TclFinalizeThreadObjects(); } + if (TclFullFinalizationRequested()) { /* useless if we are facing a quick-exit */ - /* - * 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(); + /* + * 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 996c102b1f3669d09e1278c3a6155392aab3e70e Mon Sep 17 00:00:00 2001 From: ashok Date: Wed, 3 Sep 2014 15:48:56 +0000 Subject: [132fad6fde]. Fixed GetCache to use TclpSysAlloc+memset instead of calloc. Now consistent with tclWinThrd.c which no longer uses malloc in its TclpSysAlloc implementation. --- generic/tclThreadAlloc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/generic/tclThreadAlloc.c b/generic/tclThreadAlloc.c index 5cb8027..560556d 100644 --- a/generic/tclThreadAlloc.c +++ b/generic/tclThreadAlloc.c @@ -217,10 +217,11 @@ GetCache(void) cachePtr = TclpGetAllocCache(); if (cachePtr == NULL) { - cachePtr = calloc(1, sizeof(Cache)); + cachePtr = TclpSysAlloc(sizeof(Cache), 0); if (cachePtr == NULL) { Tcl_Panic("alloc: could not allocate new cache"); } + memset(cachePtr, 0, sizeof(Cache)); Tcl_MutexLock(listLockPtr); cachePtr->nextPtr = firstCachePtr; firstCachePtr = cachePtr; -- cgit v0.12 From b47df5123eeee492ff6a0032731ace1407f42928 Mon Sep 17 00:00:00 2001 From: ferrieux Date: Wed, 3 Sep 2014 19:44:29 +0000 Subject: Distinguish hanging from crashing in exit tests. --- tests/aaa_exit.test | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/tests/aaa_exit.test b/tests/aaa_exit.test index 51a94d7..3ba5167 100644 --- a/tests/aaa_exit.test +++ b/tests/aaa_exit.test @@ -16,22 +16,35 @@ if {[lsearch [namespace children] ::tcltest] == -1} { namespace import -force ::tcltest::* } - test exit-1.1 {normal, quick exit} { - set f [open "|[interpreter] << \"exec [interpreter] << {set ::env(TCL_FINALIZE_ON_EXIT) 0;exit}\" 2>@ stderr" r] - set aft [after 5000 {set done "Quick exit hangs !!!"}] + set f [open "|[interpreter] << \"exec [interpreter] << {set ::env(TCL_FINALIZE_ON_EXIT) 0;exit}\"" r] + set aft [after 1000 {set done "Quick exit hangs !!!"}] fileevent $f readable {after cancel $aft;set done OK} vwait done - catch {fconfigure $f -blocking 0;close $f} + if {$done != "OK"} { + fconfigure $f -blocking 0 + close $f + } else { + if {[catch {close $f} err]} { + set done "Quick exit misbehaves: $err" + } + } set done } OK test exit-1.2 {full-finalized exit} { - set f [open "|[interpreter] << \"exec [interpreter] << {set ::env(TCL_FINALIZE_ON_EXIT) 1;exit}\" 2>@ stderr" r] - set aft [after 5000 {set done "Full-finalized exit hangs !!!"}] + set f [open "|[interpreter] << \"exec [interpreter] << {set ::env(TCL_FINALIZE_ON_EXIT) 1;exit}\"" r] + set aft [after 1000 {set done "Full-finalized exit hangs !!!"}] fileevent $f readable {after cancel $aft;set done OK} vwait done - catch {fconfigure $f -blocking 0;close $f} + if {$done != "OK"} { + fconfigure $f -blocking 0 + close $f + } else { + if {[catch {close $f} err]} { + set done "Full-finalized exit misbehaves: $err" + } + } set done } OK -- cgit v0.12 From 3f8809d6ec49dd37307bd26a43df7f6be1275863 Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 4 Sep 2014 22:05:21 +0000 Subject: Remove ChannelHandlerEvent struct, which has never been used in all of recorded Tcl history. Still need to purge comments of mentions of ChannelHandlerEventProc() which is similarly pre-historic. --- generic/tclIO.c | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index eaa0aeb..4bd90cc 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -58,17 +58,6 @@ typedef struct NextChannelHandler { } NextChannelHandler; /* - * The following structure describes the event that is added to the Tcl - * event queue by the channel handler check procedure. - */ - -typedef struct ChannelHandlerEvent { - Tcl_Event header; /* Standard header for all events. */ - Channel *chanPtr; /* The channel that is ready. */ - int readyMask; /* Events that have occurred. */ -} ChannelHandlerEvent; - -/* * The following structure is used by Tcl_GetsObj() to encapsulates the * state for a "gets" operation. */ -- cgit v0.12 From 303cced03d9d9084e4a555b719040fe9d261ff92 Mon Sep 17 00:00:00 2001 From: dkf Date: Fri, 5 Sep 2014 10:05:05 +0000 Subject: [ccc2c2cc98]: lreplace edge case --- generic/tclCompCmdsGR.c | 14 +++++++++++++- tests/lreplace.test | 14 +++++++++++++- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/generic/tclCompCmdsGR.c b/generic/tclCompCmdsGR.c index 166fea0..64dcaa6 100644 --- a/generic/tclCompCmdsGR.c +++ b/generic/tclCompCmdsGR.c @@ -1480,7 +1480,7 @@ TclCompileLreplaceCmd( Tcl_Token *tokenPtr, *listTokenPtr; DefineLineInformation; /* TIP #280 */ Tcl_Obj *tmpObj; - int idx1, idx2, i, offset; + int idx1, idx2, i, offset, offset2; if (parsePtr->numWords < 4) { return TCL_ERROR; @@ -1586,12 +1586,18 @@ TclCompileLreplaceCmd( TclEmitOpcode( INST_GT, envPtr); offset = CurrentOffset(envPtr); TclEmitInstInt1( INST_JUMP_TRUE1, 0, envPtr); + TclEmitOpcode( INST_DUP, envPtr); + TclEmitOpcode( INST_LIST_LENGTH, envPtr); + offset2 = CurrentOffset(envPtr); + TclEmitInstInt1( INST_JUMP_FALSE1, 0, envPtr); 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); + TclStoreInt1AtPtr(CurrentOffset(envPtr) - offset2, + envPtr->codeStart + offset2 + 1); TclAdjustStackDepth(-1, envPtr); } TclEmitOpcode( INST_DUP, envPtr); @@ -1636,12 +1642,18 @@ TclCompileLreplaceCmd( TclEmitOpcode( INST_GT, envPtr); offset = CurrentOffset(envPtr); TclEmitInstInt1( INST_JUMP_TRUE1, 0, envPtr); + TclEmitOpcode( INST_DUP, envPtr); + TclEmitOpcode( INST_LIST_LENGTH, envPtr); + offset2 = CurrentOffset(envPtr); + TclEmitInstInt1( INST_JUMP_TRUE1, 0, envPtr); 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); + TclStoreInt1AtPtr(CurrentOffset(envPtr) - offset2, + envPtr->codeStart + offset2 + 1); TclAdjustStackDepth(-1, envPtr); } TclEmitOpcode( INST_DUP, envPtr); diff --git a/tests/lreplace.test b/tests/lreplace.test index 5f675bc..b976788 100644 --- a/tests/lreplace.test +++ b/tests/lreplace.test @@ -15,7 +15,7 @@ if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest namespace import -force ::tcltest::* } - + test lreplace-1.1 {lreplace command} { lreplace {1 2 3 4 5} 0 0 a } {a 2 3 4 5} @@ -130,7 +130,19 @@ test lreplace-3.1 {lreplace won't modify shared argument objects} { p } "a b c" +test lreplace-4.1 {Bug ccc2c2cc98: lreplace edge case} { + lreplace {} 1 1 +} {} +# Note that this test will fail in 8.5 +test lreplace-4.2 {Bug ccc2c2cc98: lreplace edge case} { + lreplace { } 1 1 +} {} + # cleanup catch {unset foo} ::tcltest::cleanupTests return + +# Local Variables: +# mode: tcl +# End: -- cgit v0.12 From 13d8cae7241ccb88e051d01e0dd612d67b7a443e Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 5 Sep 2014 18:30:57 +0000 Subject: Make corrections to long-false comments. --- generic/tclIO.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index 4bd90cc..dcde8d1 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -35,15 +35,15 @@ typedef struct ChannelHandler { /* * This structure keeps track of the current ChannelHandler being invoked in - * the current invocation of ChannelHandlerEventProc. There is a potential + * the current invocation of Tcl_NotifyChannel. There is a potential * problem if a ChannelHandler is deleted while it is the current one, since - * ChannelHandlerEventProc needs to look at the nextPtr field. To handle this + * Tcl_NotifyChannel needs to look at the nextPtr field. To handle this * problem, structures of the type below indicate the next handler to be * processed for any (recursively nested) dispatches in progress. The * nextHandlerPtr field is updated if the handler being pointed to is deleted. - * The nextPtr field is used to chain together all recursive invocations, so - * that Tcl_DeleteChannelHandler can find all the recursively nested - * invocations of ChannelHandlerEventProc and compare the handler being + * The nestedHandlerPtr field is used to chain together all recursive + * invocations, so that Tcl_DeleteChannelHandler can find all the recursively + * nested invocations of Tcl_NotifyChannel and compare the handler being * deleted against the NEXT handler to be invoked in that invocation; when it * finds such a situation, Tcl_DeleteChannelHandler updates the nextHandlerPtr * field of the structure to the next handler. @@ -54,7 +54,7 @@ typedef struct NextChannelHandler { * this invocation. */ struct NextChannelHandler *nestedHandlerPtr; /* Next nested invocation of - * ChannelHandlerEventProc. */ + * Tcl_NotifyChannel. */ } NextChannelHandler; /* @@ -119,7 +119,7 @@ typedef struct CopyState { typedef struct ThreadSpecificData { NextChannelHandler *nestedHandlerPtr; /* This variable holds the list of nested - * ChannelHandlerEventProc invocations. */ + * Tcl_NotifyChannel invocations. */ ChannelState *firstCSPtr; /* List of all channels currently open, * indexed by ChannelState, as only one * ChannelState exists per set of stacked @@ -8089,7 +8089,7 @@ Tcl_NotifyChannel( /* * Add this invocation to the list of recursive invocations of - * ChannelHandlerEventProc. + * Tcl_NotifyChannel. */ nh.nextHandlerPtr = NULL; @@ -8408,7 +8408,7 @@ Tcl_DeleteChannelHandler( } /* - * If ChannelHandlerEventProc is about to process this handler, tell it to + * If Tcl_NotifyChannel is about to process this handler, tell it to * process the next one instead - we are going to delete *this* one. */ -- cgit v0.12 From a3b501f125586ba5ecf07e4805f2e965cd5a6b9c Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 5 Sep 2014 19:04:43 +0000 Subject: Remove unused macros. --- unix/tclUnixTime.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/unix/tclUnixTime.c b/unix/tclUnixTime.c index 926e8f4..4452022 100644 --- a/unix/tclUnixTime.c +++ b/unix/tclUnixTime.c @@ -16,9 +16,6 @@ #include #endif -#define TM_YEAR_BASE 1900 -#define IsLeapYear(x) (((x)%4 == 0) && ((x)%100 != 0 || (x)%400 == 0)) - /* * TclpGetDate is coded to return a pointer to a 'struct tm'. For thread * safety, this structure must be in thread-specific data. The 'tmKey' -- cgit v0.12 From 976c48a7f14df997ad05c82dae867c8622236e70 Mon Sep 17 00:00:00 2001 From: stwo Date: Mon, 8 Sep 2014 00:37:22 +0000 Subject: Change one '#ifdef' to '#if defined()' for improved consistency within the file, as in checkin [211aa43013]. --- unix/tclUnixCompat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/unix/tclUnixCompat.c b/unix/tclUnixCompat.c index 0fc51b7..3d2b7b8 100644 --- a/unix/tclUnixCompat.c +++ b/unix/tclUnixCompat.c @@ -370,7 +370,7 @@ TclpGetGrNam( #else ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); -#ifdef HAVE_GETGRNAM_R_5 +#if defined(HAVE_GETGRNAM_R_5) struct group *grPtr = NULL; /* -- cgit v0.12 From 62004c9fb4615797aed60a748235f07e37bb9802 Mon Sep 17 00:00:00 2001 From: dgp Date: Mon, 8 Sep 2014 21:22:05 +0000 Subject: Exceptional handling of oo::class has to be consistent throughout. --- generic/tclOO.c | 4 +++- tests/oo.test | 10 ++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/generic/tclOO.c b/generic/tclOO.c index ace47fe..77e668b 100644 --- a/generic/tclOO.c +++ b/generic/tclOO.c @@ -1287,7 +1287,9 @@ TclOORemoveFromInstances( removeInstance: if (Deleted(clsPtr->thisPtr)) { - DelRef(clsPtr->instances.list[i]); + if (!IsRootClass(clsPtr)) { + DelRef(clsPtr->instances.list[i]); + } clsPtr->instances.list[i] = NULL; } else { clsPtr->instances.num--; diff --git a/tests/oo.test b/tests/oo.test index 8c515da..2c189ca 100644 --- a/tests/oo.test +++ b/tests/oo.test @@ -271,6 +271,16 @@ test oo-1.18.1 {Bug 75b8433707: memory leak in oo-1.18} -setup { } -cleanup { rename test-oo-1.18 {} } -result 0 +test oo-1.18.2 {Bug 21c144f0f5} -setup { + interp create slave +} -body { + slave eval { + oo::define [oo::class create foo] superclass oo::class + oo::class destroy + } +} -cleanup { + interp delete slave +} test oo-1.19 {basic test of OO functionality: teardown order} -body { oo::object create o namespace delete [info object namespace o] -- cgit v0.12 From 600ace1c4bfd50763dd250e2c271e7fed0fc3bec Mon Sep 17 00:00:00 2001 From: ferrieux Date: Mon, 8 Sep 2014 22:50:11 +0000 Subject: Refine TclFinalizeThreadData so that the quick-exit optimization really only affects exit. --- generic/tclEvent.c | 23 ++++++++++------------- generic/tclThread.c | 7 ++++++- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/generic/tclEvent.c b/generic/tclEvent.c index ab219a6..3985767 100644 --- a/generic/tclEvent.c +++ b/generic/tclEvent.c @@ -1299,20 +1299,17 @@ Tcl_FinalizeThread(void) TclFinalizeAsync(); TclFinalizeThreadObjects(); } - if (TclFullFinalizationRequested()) { /* useless if we are facing a quick-exit */ - /* - * 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(); - } + /* + * 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(); } /* diff --git a/generic/tclThread.c b/generic/tclThread.c index 8c972a8..5ac6a8d 100644 --- a/generic/tclThread.c +++ b/generic/tclThread.c @@ -357,7 +357,12 @@ TclFinalizeThreadData(void) { TclFinalizeThreadDataThread(); #if defined(TCL_THREADS) && defined(USE_THREAD_ALLOC) - TclFinalizeThreadAllocThread(); + if ((!TclInExit())||TclFullFinalizationRequested()) { + /* + * Quick exit principle makes it useless to terminate allocators + */ + TclFinalizeThreadAllocThread(); + } #endif } -- cgit v0.12 From 7bce68fe3bd6110ef4948e72c66a00b48775d634 Mon Sep 17 00:00:00 2001 From: dkf Date: Tue, 9 Sep 2014 19:49:08 +0000 Subject: [84af1192f5]: [regsub] compiler no longer confused by quantification handling. --- generic/tclCompCmdsGR.c | 7 ++++--- generic/tclCompCmdsSZ.c | 2 +- generic/tclInt.h | 3 ++- generic/tclRegexp.c | 3 ++- generic/tclUtil.c | 9 ++++++++- tests/regexpComp.test | 5 +++++ 6 files changed, 22 insertions(+), 7 deletions(-) diff --git a/generic/tclCompCmdsGR.c b/generic/tclCompCmdsGR.c index 64dcaa6..603c51d 100644 --- a/generic/tclCompCmdsGR.c +++ b/generic/tclCompCmdsGR.c @@ -2270,7 +2270,7 @@ TclCompileRegexpCmd( * converted pattern as a literal. */ - if (TclReToGlob(NULL, varTokenPtr[1].start, len, &ds, &exact) + if (TclReToGlob(NULL, varTokenPtr[1].start, len, &ds, &exact, NULL) == TCL_OK) { simple = 1; PushLiteral(envPtr, Tcl_DStringValue(&ds),Tcl_DStringLength(&ds)); @@ -2362,7 +2362,7 @@ TclCompileRegsubCmd( Tcl_Obj *patternObj = NULL, *replacementObj = NULL; Tcl_DString pattern; const char *bytes; - int len, exact, result = TCL_ERROR; + int len, exact, quantified, result = TCL_ERROR; if (parsePtr->numWords < 5 || parsePtr->numWords > 6) { return TCL_ERROR; @@ -2422,7 +2422,8 @@ TclCompileRegsubCmd( */ bytes = Tcl_GetStringFromObj(patternObj, &len); - if (TclReToGlob(NULL, bytes, len, &pattern, &exact) != TCL_OK || exact) { + if (TclReToGlob(NULL, bytes, len, &pattern, &exact, &quantified) + != TCL_OK || exact || quantified) { goto done; } bytes = Tcl_DStringValue(&pattern); diff --git a/generic/tclCompCmdsSZ.c b/generic/tclCompCmdsSZ.c index f2e5dd2..28cab1e 100644 --- a/generic/tclCompCmdsSZ.c +++ b/generic/tclCompCmdsSZ.c @@ -2091,7 +2091,7 @@ IssueSwitchChainedTests( */ if (TclReToGlob(NULL, bodyToken[i]->start, - bodyToken[i]->size, &ds, &exact) == TCL_OK) { + bodyToken[i]->size, &ds, &exact, NULL) == TCL_OK){ simple = 1; PushLiteral(envPtr, Tcl_DStringValue(&ds), Tcl_DStringLength(&ds)); diff --git a/generic/tclInt.h b/generic/tclInt.h index 6bf1ef9..7287a13 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -3095,7 +3095,8 @@ MODULE_SCOPE void TclRememberJoinableThread(Tcl_ThreadId id); MODULE_SCOPE void TclRememberMutex(Tcl_Mutex *mutex); MODULE_SCOPE void TclRemoveScriptLimitCallbacks(Tcl_Interp *interp); MODULE_SCOPE int TclReToGlob(Tcl_Interp *interp, const char *reStr, - int reStrLen, Tcl_DString *dsPtr, int *flagsPtr); + int reStrLen, Tcl_DString *dsPtr, int *flagsPtr, + int *quantifiersFoundPtr); MODULE_SCOPE int TclScanElement(const char *string, int length, int *flagPtr); MODULE_SCOPE void TclSetBgErrorHandler(Tcl_Interp *interp, diff --git a/generic/tclRegexp.c b/generic/tclRegexp.c index 6348e4a..5bc3aa2 100644 --- a/generic/tclRegexp.c +++ b/generic/tclRegexp.c @@ -946,7 +946,8 @@ CompileRegexp( * Tcl_RegExpExecObj to optionally do a fast match (avoids RE engine). */ - if (TclReToGlob(NULL, string, length, &stringBuf, &exact) == TCL_OK) { + if (TclReToGlob(NULL, string, length, &stringBuf, &exact, + NULL) == TCL_OK) { regexpPtr->globObjPtr = TclDStringToObj(&stringBuf); Tcl_IncrRefCount(regexpPtr->globObjPtr); } else { diff --git a/generic/tclUtil.c b/generic/tclUtil.c index ae3adae..64589a2 100644 --- a/generic/tclUtil.c +++ b/generic/tclUtil.c @@ -4249,7 +4249,8 @@ TclReToGlob( const char *reStr, int reStrLen, Tcl_DString *dsPtr, - int *exactPtr) + int *exactPtr, + int *quantifiersFoundPtr) { int anchorLeft, anchorRight, lastIsStar, numStars; char *dsStr, *dsStrStart; @@ -4257,6 +4258,9 @@ TclReToGlob( strEnd = reStr + reStrLen; Tcl_DStringInit(dsPtr); + if (quantifiersFoundPtr != NULL) { + *quantifiersFoundPtr = 0; + } /* * "***=xxx" == "*xxx*", watch for glob-sensitive chars. @@ -4369,6 +4373,9 @@ TclReToGlob( } break; case '.': + if (quantifiersFoundPtr != NULL) { + *quantifiersFoundPtr = 1; + } anchorLeft = 0; /* prevent exact match */ if (p+1 < strEnd) { if (p[1] == '*') { diff --git a/tests/regexpComp.test b/tests/regexpComp.test index 7be1195..01ef06d 100644 --- a/tests/regexpComp.test +++ b/tests/regexpComp.test @@ -526,6 +526,11 @@ test regexpComp-9.6 {-all option to regsub} { list [regsub -all ^ xxx 123 foo] $foo } } {1 123xxx} +test regexpComp-9.7 {Bug 84af1192f5: -all option to regsub} { + evalInProc { + regsub -all {\(.*} 123(qwe) "" + } +} 123 test regexpComp-10.1 {expanded syntax in regsub} { evalInProc { -- cgit v0.12 From 5f9519213f1ee34452f4fa7bd495a4c1ddada792 Mon Sep 17 00:00:00 2001 From: dkf Date: Wed, 10 Sep 2014 08:20:46 +0000 Subject: [2486824] Improve error message; not all that upvars is an upvar. --- generic/tclVar.c | 9 ++++----- tests/upvar.test | 11 +++++++---- tests/var.test | 2 +- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/generic/tclVar.c b/generic/tclVar.c index fda5ff5..a6f6cf4 100644 --- a/generic/tclVar.c +++ b/generic/tclVar.c @@ -3605,9 +3605,8 @@ ObjMakeUpvar( || !HasLocalVars(varFramePtr) || (strstr(TclGetString(myNamePtr), "::") != NULL))) { Tcl_AppendResult((Tcl_Interp *) iPtr, "bad variable name \"", - TclGetString(myNamePtr), "\": upvar won't create " - "namespace variable that refers to procedure variable", - NULL); + TclGetString(myNamePtr), "\": can't create namespace " + "variable that refers to procedure variable", NULL); return TCL_ERROR; } } @@ -3705,8 +3704,8 @@ TclPtrObjMakeUpvar( */ Tcl_AppendResult((Tcl_Interp *) iPtr, "bad variable name \"", - myName, "\": upvar won't create a scalar variable " - "that looks like an array element", NULL); + myName, "\": can't create a scalar variable that " + "looks like an array element", NULL); return TCL_ERROR; } } diff --git a/tests/upvar.test b/tests/upvar.test index 79c2d53..d18fd3b 100644 --- a/tests/upvar.test +++ b/tests/upvar.test @@ -17,7 +17,7 @@ if {[lsearch [namespace children] ::tcltest] == -1} { } testConstraint testupvar [llength [info commands testupvar]] - + test upvar-1.1 {reading variables with upvar} { proc p1 {a b} {set c 22; set d 33; p2} proc p2 {} {upvar a x1 b x2 c x3 d x4; set a abc; list $x1 $x2 $x3 $x4 $a} @@ -332,7 +332,7 @@ test upvar-8.9 {upvar won't create namespace variable that refers to procedure v unset ::test_ns_1::a } list [catch {MakeLink 1} msg] $msg -} {1 {bad variable name "a": upvar won't create namespace variable that refers to procedure variable}} +} {1 {bad variable name "a": can't create namespace variable that refers to procedure variable}} test upvar-8.10 {upvar will create element alias for new array element} { catch {unset upvarArray} array set upvarArray {} @@ -583,8 +583,11 @@ test upvar-NS-3.3 {CompileWord OBOE} -setup { } -cleanup { rename linenumber {} } -result 1 - - + # cleanup ::tcltest::cleanupTests return + +# Local Variables: +# mode: tcl +# End: diff --git a/tests/var.test b/tests/var.test index 45b7207..c852ca9 100644 --- a/tests/var.test +++ b/tests/var.test @@ -275,7 +275,7 @@ test var-3.11 {MakeUpvar, my var looks like array elem} -body { catch {unset aaaaa} set aaaaa 789789 upvar #0 aaaaa foo(bar) -} -returnCodes 1 -result {bad variable name "foo(bar)": upvar won't create a scalar variable that looks like an array element} +} -returnCodes 1 -result {bad variable name "foo(bar)": can't create a scalar variable that looks like an array element} test var-4.1 {Tcl_GetVariableName, global variable} testgetvarfullname { catch {unset a} -- cgit v0.12 From d75135cca196056a72935f75055f30b95e2d81e3 Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 10 Sep 2014 22:17:21 +0000 Subject: [cee90e4e88] Correct error in stack depth checking. --- generic/tclCompCmdsSZ.c | 1 + tests/error.test | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/generic/tclCompCmdsSZ.c b/generic/tclCompCmdsSZ.c index 28cab1e..ed9c088 100644 --- a/generic/tclCompCmdsSZ.c +++ b/generic/tclCompCmdsSZ.c @@ -3038,6 +3038,7 @@ IssueTryClausesInstructions( if (!handlerTokens[i]) { forwardsNeedFixing = 1; JUMP4( JUMP, forwardsToFix[i]); + TclAdjustStackDepth(1, envPtr); } else { int dontChangeOptions; diff --git a/tests/error.test b/tests/error.test index 0de644c..af07ed7 100644 --- a/tests/error.test +++ b/tests/error.test @@ -1184,6 +1184,12 @@ test error-21.8 {memory leaks in try: Bug 2910044} memory { } } 0 +test error-21.9 {Bug cee90e4e88} { + # Just don't panic. + apply {{} {try {} on ok {} - on return {} {}}} +} {} + + # negative case try tests - bad "trap" handler # what is the effect if we attempt to trap an errorcode that is not a list? # nested try -- cgit v0.12 From 5e0835667dd2d77d981b5266b438e6ce2a746e6e Mon Sep 17 00:00:00 2001 From: dkf Date: Sun, 14 Sep 2014 17:11:33 +0000 Subject: whitespace tweak --- generic/tclDisassemble.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/generic/tclDisassemble.c b/generic/tclDisassemble.c index 00b5549..9556d46 100644 --- a/generic/tclDisassemble.c +++ b/generic/tclDisassemble.c @@ -1107,10 +1107,12 @@ DisassembleByteCodeAsDicts( Tcl_NewIntObj(codeOffset)); Tcl_DictObjPut(NULL, cmd, Tcl_NewStringObj("codeto", -1), Tcl_NewIntObj(codeOffset + codeLength - 1)); + /* * Convert byte offsets to character offsets; important if multibyte * characters are present in the source! */ + Tcl_DictObjPut(NULL, cmd, Tcl_NewStringObj("scriptfrom", -1), Tcl_NewIntObj(Tcl_NumUtfChars(codePtr->source, sourceOffset))); -- cgit v0.12 From 85f3786d9c41c283a79da67ee6e54bd05f7a8613 Mon Sep 17 00:00:00 2001 From: stwo Date: Tue, 16 Sep 2014 15:48:48 +0000 Subject: Better pic flag for OpenBSD. --- unix/configure | 9 ++++++++- unix/tcl.m4 | 9 ++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/unix/configure b/unix/configure index a82c692..5291bf7 100755 --- a/unix/configure +++ b/unix/configure @@ -7676,7 +7676,14 @@ fi LDFLAGS="" ;; *) - SHLIB_CFLAGS="-fPIC" + case "$arch" in + alpha|sparc64) + SHLIB_CFLAGS="-fPIC" + ;; + *) + SHLIB_CFLAGS="-fpic" + ;; + esac SHLIB_LD='${CC} -shared ${SHLIB_CFLAGS}' SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" diff --git a/unix/tcl.m4 b/unix/tcl.m4 index 3ca65d8..277fe0b 100644 --- a/unix/tcl.m4 +++ b/unix/tcl.m4 @@ -1475,7 +1475,14 @@ AC_DEFUN([SC_CONFIG_CFLAGS], [ LDFLAGS="" ;; *) - SHLIB_CFLAGS="-fPIC" + case "$arch" in + alpha|sparc64) + SHLIB_CFLAGS="-fPIC" + ;; + *) + SHLIB_CFLAGS="-fpic" + ;; + esac SHLIB_LD='${CC} -shared ${SHLIB_CFLAGS}' SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" -- cgit v0.12 From 76db7c5c047f92589956c4c5d0ae3eb6997dd69d Mon Sep 17 00:00:00 2001 From: stwo Date: Tue, 16 Sep 2014 15:52:44 +0000 Subject: Better pic flag for OpenBSD. --- unix/configure | 9 ++++++++- unix/tcl.m4 | 9 ++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/unix/configure b/unix/configure index d11e7d2..ff7791e 100755 --- a/unix/configure +++ b/unix/configure @@ -7576,7 +7576,14 @@ fi LDFLAGS="" ;; *) - SHLIB_CFLAGS="-fPIC" + case "$arch" in + alpha|sparc64) + SHLIB_CFLAGS="-fPIC" + ;; + *) + SHLIB_CFLAGS="-fpic" + ;; + esac SHLIB_LD='${CC} -shared ${SHLIB_CFLAGS}' SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" diff --git a/unix/tcl.m4 b/unix/tcl.m4 index 437ce3d..c4e4675 100644 --- a/unix/tcl.m4 +++ b/unix/tcl.m4 @@ -1499,7 +1499,14 @@ AC_DEFUN([SC_CONFIG_CFLAGS], [ LDFLAGS="" ;; *) - SHLIB_CFLAGS="-fPIC" + case "$arch" in + alpha|sparc64) + SHLIB_CFLAGS="-fPIC" + ;; + *) + SHLIB_CFLAGS="-fpic" + ;; + esac SHLIB_LD='${CC} -shared ${SHLIB_CFLAGS}' SHLIB_SUFFIX=".so" DL_OBJS="tclLoadDl.o" -- cgit v0.12 From 1598658a83c78f82eed031ae6bccbd02a7d21c7b Mon Sep 17 00:00:00 2001 From: dkf Date: Sat, 20 Sep 2014 11:40:35 +0000 Subject: Tidy things up a bit more. --- generic/tclDisassemble.c | 17 +++++++++++++---- generic/tclProc.c | 2 +- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/generic/tclDisassemble.c b/generic/tclDisassemble.c index 9556d46..b3753c31 100644 --- a/generic/tclDisassemble.c +++ b/generic/tclDisassemble.c @@ -21,6 +21,7 @@ * Prototypes for procedures defined later in this file: */ +static Tcl_Obj * DisassembleByteCodeAsDicts(Tcl_Obj *objPtr); static int FormatInstruction(ByteCode *codePtr, const unsigned char *pc, Tcl_Obj *bufferObj); static void PrintSourceToObj(Tcl_Obj *appendObj, @@ -39,6 +40,13 @@ static const Tcl_ObjType tclInstNameType = { UpdateStringOfInstName, /* updateStringProc */ NULL, /* setFromAnyProc */ }; + +/* + * How to get the bytecode out of a Tcl_Obj. + */ + +#define BYTECODE(objPtr) \ + ((ByteCode *) (objPtr)->internalRep.twoPtrValue.ptr1) #ifdef TCL_COMPILE_DEBUG /* @@ -181,7 +189,7 @@ Tcl_Obj * TclDisassembleByteCodeObj( Tcl_Obj *objPtr) /* The bytecode object to disassemble. */ { - ByteCode *codePtr = objPtr->internalRep.twoPtrValue.ptr1; + ByteCode *codePtr = BYTECODE(objPtr); unsigned char *codeStart, *codeLimit, *pc; unsigned char *codeDeltaNext, *codeLengthNext; unsigned char *srcDeltaNext, *srcLengthNext; @@ -858,7 +866,7 @@ static Tcl_Obj * DisassembleByteCodeAsDicts( Tcl_Obj *objPtr) /* The bytecode-holding value to take apart */ { - ByteCode *codePtr = objPtr->internalRep.twoPtrValue.ptr1; + ByteCode *codePtr = BYTECODE(objPtr); Tcl_Obj *description, *literals, *variables, *instructions, *inst; Tcl_Obj *aux, *exn, *commands; unsigned char *pc, *opnd, *codeOffPtr, *codeLenPtr, *srcOffPtr, *srcLenPtr; @@ -1201,6 +1209,8 @@ Tcl_DisassembleObjCmd( /* * Compile (if uncompiled) and disassemble a lambda term. + * + * WARNING! Pokes inside the lambda objtype. */ if (objc != 3) { @@ -1368,8 +1378,7 @@ Tcl_DisassembleObjCmd( * Do the actual disassembly. */ - if (((ByteCode *) codeObjPtr->internalRep.twoPtrValue.ptr1)->flags - & TCL_BYTECODE_PRECOMPILED) { + if (BYTECODE(codeObjPtr)->flags & TCL_BYTECODE_PRECOMPILED) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "may not disassemble prebuilt bytecode", -1)); Tcl_SetErrorCode(interp, "TCL", "OPERATION", "DISASSEMBLE", diff --git a/generic/tclProc.c b/generic/tclProc.c index 42c9a72..e0d6ec7 100644 --- a/generic/tclProc.c +++ b/generic/tclProc.c @@ -88,7 +88,7 @@ static const Tcl_ObjType levelReferenceType = { * * Internally, ptr1 is a pointer to a Proc instance that is not bound to a * command name, and ptr2 is a pointer to the namespace that the Proc instance - * will execute within. + * will execute within. IF YOU CHANGE THIS, CHECK IN tclDisassemble.c TOO. */ const Tcl_ObjType tclLambdaType = { -- cgit v0.12 From fc21aee8149d870eb415300d7153cc1627c84fea Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 25 Sep 2014 18:47:32 +0000 Subject: comment fix --- generic/tclInt.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generic/tclInt.h b/generic/tclInt.h index 7287a13..860c2a3 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -1741,7 +1741,7 @@ enum PkgPreferOptions { * definition there. * Some macros require knowledge of some fields in the struct in order to * avoid hitting the TSD unnecessarily. In order to facilitate this, a pointer - * to the relevant fields is kept in the objCache field in struct Interp. + * to the relevant fields is kept in the allocCache field in struct Interp. *---------------------------------------------------------------- */ -- cgit v0.12 From 822a2b50f72950b1305cf1a2983427b05c80859d Mon Sep 17 00:00:00 2001 From: oehhar Date: Fri, 26 Sep 2014 12:05:30 +0000 Subject: Implemented tip-427: socket fconfigure option -connecting plus no -peername,-sockname when still connecting. --- unix/tclUnixSock.c | 34 +++++++++++++++---- win/tclWinSock.c | 97 ++++++++++++++++++++++++++++++++---------------------- 2 files changed, 85 insertions(+), 46 deletions(-) diff --git a/unix/tclUnixSock.c b/unix/tclUnixSock.c index 96700ce..ca25435 100644 --- a/unix/tclUnixSock.c +++ b/unix/tclUnixSock.c @@ -823,7 +823,20 @@ TcpGetOptionProc( address peername; socklen_t size = sizeof(peername); - if (getpeername(statePtr->fds.fd, &peername.sa, &size) >= 0) { + if ( (statePtr->flags & TCP_ASYNC_CONNECT) ) { + /* + * In async connect output an empty string + */ + if (len == 0) { + Tcl_DStringAppendElement(dsPtr, "-peername"); + Tcl_DStringAppendElement(dsPtr, ""); + } else { + return TCL_OK; + } + } else if (getpeername(statePtr->fds.fd, &peername.sa, &size) >= 0) { + /* + * Peername fetch succeeded - output list + */ if (len == 0) { Tcl_DStringAppendElement(dsPtr, "-peername"); Tcl_DStringStartSublist(dsPtr); @@ -863,11 +876,18 @@ TcpGetOptionProc( Tcl_DStringAppendElement(dsPtr, "-sockname"); Tcl_DStringStartSublist(dsPtr); } - for (fds = &statePtr->fds; fds != NULL; fds = fds->next) { - size = sizeof(sockname); - if (getsockname(fds->fd, &(sockname.sa), &size) >= 0) { - found = 1; - TcpHostPortList(interp, dsPtr, sockname, size); + if ( (statePtr->flags & TCP_ASYNC_CONNECT) ) { + /* + * In async connect output an empty string + */ + found = 1; + } else { + for (fds = &statePtr->fds; fds != NULL; fds = fds->next) { + size = sizeof(sockname); + if (getsockname(fds->fd, &(sockname.sa), &size) >= 0) { + found = 1; + TcpHostPortList(interp, dsPtr, sockname, size); + } } } if (found) { @@ -885,7 +905,7 @@ TcpGetOptionProc( } if (len > 0) { - return Tcl_BadChannelOption(interp, optionName, "peername sockname"); + return Tcl_BadChannelOption(interp, optionName, "connecting peername sockname"); } return TCL_OK; diff --git a/win/tclWinSock.c b/win/tclWinSock.c index f343f82..900f7c4 100644 --- a/win/tclWinSock.c +++ b/win/tclWinSock.c @@ -1337,7 +1337,20 @@ TcpGetOptionProc( address peername; socklen_t size = sizeof(peername); - if (getpeername(sock, (LPSOCKADDR) &(peername.sa), &size) == 0) { + if ( (statePtr->flags & TCP_ASYNC_PENDING) ) { + /* + * In async connect output an empty string + */ + if (len == 0) { + Tcl_DStringAppendElement(dsPtr, "-peername"); + Tcl_DStringAppendElement(dsPtr, ""); + } else { + return TCL_OK; + } + } else if ( getpeername(sock, (LPSOCKADDR) &(peername.sa), &size) == 0) { + /* + * Peername fetch succeeded - output list + */ if (len == 0) { Tcl_DStringAppendElement(dsPtr, "-peername"); Tcl_DStringStartSublist(dsPtr); @@ -1386,49 +1399,55 @@ TcpGetOptionProc( Tcl_DStringAppendElement(dsPtr, "-sockname"); Tcl_DStringStartSublist(dsPtr); } - for (fds = statePtr->sockets; fds != NULL; fds = fds->next) { - sock = fds->fd; - size = sizeof(sockname); - if (getsockname(sock, &(sockname.sa), &size) >= 0) { - int flags = reverseDNS; - - found = 1; - getnameinfo(&sockname.sa, size, host, sizeof(host), - NULL, 0, NI_NUMERICHOST); - Tcl_DStringAppendElement(dsPtr, host); - - /* - * We don't want to resolve INADDR_ANY and sin6addr_any; they - * can sometimes cause problems (and never have a name). - */ - flags |= NI_NUMERICSERV; - if (sockname.sa.sa_family == AF_INET) { - if (sockname.sa4.sin_addr.s_addr == INADDR_ANY) { - flags |= NI_NUMERICHOST; - } - } else if (sockname.sa.sa_family == AF_INET6) { - if ((IN6_ARE_ADDR_EQUAL(&sockname.sa6.sin6_addr, - &in6addr_any)) || - (IN6_IS_ADDR_V4MAPPED(&sockname.sa6.sin6_addr) - && sockname.sa6.sin6_addr.s6_addr[12] == 0 - && sockname.sa6.sin6_addr.s6_addr[13] == 0 - && sockname.sa6.sin6_addr.s6_addr[14] == 0 - && sockname.sa6.sin6_addr.s6_addr[15] == 0)) { - flags |= NI_NUMERICHOST; + if ( (statePtr->flags & TCP_ASYNC_PENDING ) ) { + /* + * In async connect output an empty string + */ + found = 1; + } else { + for (fds = statePtr->sockets; fds != NULL; fds = fds->next) { + sock = fds->fd; + size = sizeof(sockname); + if (getsockname(sock, &(sockname.sa), &size) >= 0) { + int flags = reverseDNS; + + found = 1; + getnameinfo(&sockname.sa, size, host, sizeof(host), + NULL, 0, NI_NUMERICHOST); + Tcl_DStringAppendElement(dsPtr, host); + + /* + * We don't want to resolve INADDR_ANY and sin6addr_any; they + * can sometimes cause problems (and never have a name). + */ + flags |= NI_NUMERICSERV; + if (sockname.sa.sa_family == AF_INET) { + if (sockname.sa4.sin_addr.s_addr == INADDR_ANY) { + flags |= NI_NUMERICHOST; + } + } else if (sockname.sa.sa_family == AF_INET6) { + if ((IN6_ARE_ADDR_EQUAL(&sockname.sa6.sin6_addr, + &in6addr_any)) || + (IN6_IS_ADDR_V4MAPPED(&sockname.sa6.sin6_addr) + && sockname.sa6.sin6_addr.s6_addr[12] == 0 + && sockname.sa6.sin6_addr.s6_addr[13] == 0 + && sockname.sa6.sin6_addr.s6_addr[14] == 0 + && sockname.sa6.sin6_addr.s6_addr[15] == 0)) { + flags |= NI_NUMERICHOST; + } } + getnameinfo(&sockname.sa, size, host, sizeof(host), + port, sizeof(port), flags); + Tcl_DStringAppendElement(dsPtr, host); + Tcl_DStringAppendElement(dsPtr, port); } - getnameinfo(&sockname.sa, size, host, sizeof(host), - port, sizeof(port), flags); - Tcl_DStringAppendElement(dsPtr, host); - Tcl_DStringAppendElement(dsPtr, port); } } if (found) { - if (len == 0) { - Tcl_DStringEndSublist(dsPtr); - } else { + if (len) { return TCL_OK; } + Tcl_DStringEndSublist(dsPtr); } else { if (interp) { TclWinConvertError((DWORD) WSAGetLastError()); @@ -1482,9 +1501,9 @@ TcpGetOptionProc( if (len > 0) { #ifdef TCL_FEATURE_KEEPALIVE_NAGLE return Tcl_BadChannelOption(interp, optionName, - "peername sockname keepalive nagle"); + "connecting peername sockname keepalive nagle"); #else - return Tcl_BadChannelOption(interp, optionName, "peername sockname"); + return Tcl_BadChannelOption(interp, optionName, "connecting peername sockname"); #endif /*TCL_FEATURE_KEEPALIVE_NAGLE*/ } -- cgit v0.12 From 11db57d05815ec16e0955c80286da2ebee975156 Mon Sep 17 00:00:00 2001 From: ferrieux Date: Sat, 27 Sep 2014 20:28:47 +0000 Subject: Applied patch by Andreas Leitgeb so that [string cat]'s compiled bytecode optimally groups args by 255 for INSTR_STR_CONCAT1. --- generic/tclCompCmdsSZ.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/generic/tclCompCmdsSZ.c b/generic/tclCompCmdsSZ.c index 2b83fd2..617a520 100644 --- a/generic/tclCompCmdsSZ.c +++ b/generic/tclCompCmdsSZ.c @@ -322,8 +322,8 @@ TclCompileStringCatCmd( CompileWord(envPtr, wordTokenPtr, interp, i); numArgs ++; if (numArgs >= 254) { /* 254 to take care of the possible +1 of "folded" above */ - TclEmitInstInt1(INST_STR_CONCAT1, 254, envPtr); - numArgs -= 253; /* concat pushes 1 obj, the result */ + TclEmitInstInt1(INST_STR_CONCAT1, numArgs, envPtr); + numArgs = 1; /* concat pushes 1 obj, the result */ } } wordTokenPtr = TokenAfter(wordTokenPtr); -- cgit v0.12 From 78fcaa358001767a51161316acbc429666bf86dd Mon Sep 17 00:00:00 2001 From: Miguel Sofer Date: Sat, 27 Sep 2014 21:36:06 +0000 Subject: Backing out commit [cddbfc3081], fix for bug [82521bfb6734f891dd] The "optimisation" in that commit assumes that the last byte in the generated bytecodes is an INST_TRY_CONVERT if it equals 64. This is an invalid assumption, it could be 64 and not be an instruction. --- generic/tclCompCmds.c | 1 - generic/tclCompCmdsGR.c | 2 -- generic/tclCompCmdsSZ.c | 1 - generic/tclCompile.h | 12 ------------ 4 files changed, 16 deletions(-) diff --git a/generic/tclCompCmds.c b/generic/tclCompCmds.c index 431f0af..496d44f 100644 --- a/generic/tclCompCmds.c +++ b/generic/tclCompCmds.c @@ -2401,7 +2401,6 @@ TclCompileForCmd( SetLineInformation(2); TclCompileExprWords(interp, testTokenPtr, 1, envPtr); - TclClearNumConversion(envPtr); jumpDist = CurrentOffset(envPtr) - bodyCodeOffset; if (jumpDist > 127) { diff --git a/generic/tclCompCmdsGR.c b/generic/tclCompCmdsGR.c index 603c51d..9d258fc 100644 --- a/generic/tclCompCmdsGR.c +++ b/generic/tclCompCmdsGR.c @@ -281,7 +281,6 @@ TclCompileIfCmd( SetLineInformation(wordIdx); Tcl_ResetResult(interp); TclCompileExprWords(interp, testTokenPtr, 1, envPtr); - TclClearNumConversion(envPtr); if (jumpFalseFixupArray.next >= jumpFalseFixupArray.end) { TclExpandJumpFixupArray(&jumpFalseFixupArray); } @@ -531,7 +530,6 @@ TclCompileIncrCmd( } else { SetLineInformation(2); CompileTokens(envPtr, incrTokenPtr, interp); - TclClearNumConversion(envPtr); } } else { /* No incr amount given so use 1. */ haveImmValue = 1; diff --git a/generic/tclCompCmdsSZ.c b/generic/tclCompCmdsSZ.c index 617a520..382d2d1 100644 --- a/generic/tclCompCmdsSZ.c +++ b/generic/tclCompCmdsSZ.c @@ -3782,7 +3782,6 @@ TclCompileWhileCmd( } SetLineInformation(1); TclCompileExprWords(interp, testTokenPtr, 1, envPtr); - TclClearNumConversion(envPtr); jumpDist = CurrentOffset(envPtr) - bodyCodeOffset; if (jumpDist > 127) { diff --git a/generic/tclCompile.h b/generic/tclCompile.h index 01b78d9..51f0b34 100644 --- a/generic/tclCompile.h +++ b/generic/tclCompile.h @@ -1414,18 +1414,6 @@ MODULE_SCOPE int TclPushProcCallFrame(ClientData clientData, } while (0) /* - * If the expr compiler finished with TRY_CONVERT, macro to remove it when the - * job is done by the following instruction. - */ - -#define TclClearNumConversion(envPtr) \ - do { \ - if (*(envPtr->codeNext - 1) == INST_TRY_CVT_TO_NUMERIC) { \ - envPtr->codeNext--; \ - } \ - } while (0) - -/* * Macros to update a (signed or unsigned) integer starting at a pointer. The * two variants depend on the number of bytes. The ANSI C "prototypes" for * these macros are: -- cgit v0.12 From 5e53c4c296a76474cabecdca52916f8608d84b2b Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 2 Oct 2014 14:43:10 +0000 Subject: [bc5b790099] Improper calculation of new dstLimit value. New test io-12.7. --- generic/tclIO.c | 5 ++--- tests/io.test | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index 93ac937..3119db5 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -5632,12 +5632,11 @@ ReadChars( /* * We read more chars than allowed. Reset limits to * prevent that and try again. Don't forget the extra - * padding of TCL_UTF_MAX - 1 bytes demanded by the + * padding of TCL_UTF_MAX bytes demanded by the * Tcl_ExternalToUtf() call! */ - dstLimit = Tcl_UtfAtIndex(dst, charsToRead + 1) - + TCL_UTF_MAX - 1 - dst; + dstLimit = Tcl_UtfAtIndex(dst, charsToRead) + TCL_UTF_MAX - dst; statePtr->flags = savedFlags; statePtr->inputEncodingFlags = savedIEFlags; statePtr->inputEncodingState = savedState; diff --git a/tests/io.test b/tests/io.test index 7698cea..b8a5ab4 100644 --- a/tests/io.test +++ b/tests/io.test @@ -1478,6 +1478,39 @@ test io-12.6 {ReadChars: too many chars read} { } close $c } {} +test io-12.7 {ReadChars: too many chars read [bc5b790099]} { + proc driver {cmd args} { + variable buffer + variable index + set chan [lindex $args 0] + switch -- $cmd { + initialize { + set index($chan) 0 + set buffer($chan) [encoding convertto utf-8 \ + [string repeat \uBEEF 10]....\uBEEF] + return {initialize finalize watch read} + } + finalize { + unset index($chan) buffer($chan) + return + } + watch {} + read { + set n [lindex $args 1] + set new [expr {$index($chan) + $n}] + set result [string range $buffer($chan) $index($chan) $new-1] + set index($chan) $new + return $result + } + } + } + set c [chan create read [namespace which driver]] + chan configure $c -encoding utf-8 + while {![eof $c]} { + read $c 7 + } + close $c +} {} test io-13.1 {TranslateInputEOL: cr mode} {} { set f [open $path(test1) w] -- cgit v0.12 From 7c4da917a70dbd0998ae98d1595fe01df87d646e Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 2 Oct 2014 17:43:16 +0000 Subject: [bc1a96407a] Partial solution should avoid crash, but may lead to wrong behavior. --- generic/tclTrace.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/generic/tclTrace.c b/generic/tclTrace.c index c0cde49..2a348e6 100644 --- a/generic/tclTrace.c +++ b/generic/tclTrace.c @@ -2511,7 +2511,11 @@ TclObjCallVarTraces( if (!part1Ptr) { part1Ptr = localName(iPtr->varFramePtr, index); } - part1 = TclGetString(part1Ptr); + if (part1Ptr) { + part1 = TclGetString(part1Ptr); + } else { + part1 = tclEmptyString; + } part2 = part2Ptr? TclGetString(part2Ptr) : NULL; return TclCallVarTraces(iPtr, arrayPtr, varPtr, part1, part2, flags, -- cgit v0.12 From 3b4cf982e3722b4e97880437e65db834841c8754 Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 2 Oct 2014 21:40:13 +0000 Subject: Possible fix for testing. --- generic/tclCompCmds.c | 8 +++++--- generic/tclTrace.c | 7 +++---- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/generic/tclCompCmds.c b/generic/tclCompCmds.c index 496d44f..18f4564 100644 --- a/generic/tclCompCmds.c +++ b/generic/tclCompCmds.c @@ -301,7 +301,8 @@ TclCompileArraySetCmd( * a proc, we cannot do a better compile than generic. */ - if (envPtr->procPtr == NULL && !(isDataEven && len == 0)) { + if ((varTokenPtr->type != TCL_TOKEN_SIMPLE_WORD) || + (envPtr->procPtr == NULL && !(isDataEven && len == 0))) { code = TclCompileBasic2ArgCmd(interp, parsePtr, cmdPtr, envPtr); goto done; } @@ -342,8 +343,9 @@ TclCompileArraySetCmd( * a non-local variable: upvar from a local one! This consumes the * variable name that was left at stacktop. */ - - localIndex = AnonymousLocal(envPtr); + + localIndex = TclFindCompiledLocal(varTokenPtr->start, + varTokenPtr->size, 1, envPtr); PushStringLiteral(envPtr, "0"); TclEmitInstInt4(INST_REVERSE, 2, envPtr); TclEmitInstInt4(INST_UPVAR, localIndex, envPtr); diff --git a/generic/tclTrace.c b/generic/tclTrace.c index 2a348e6..6184a89 100644 --- a/generic/tclTrace.c +++ b/generic/tclTrace.c @@ -2511,11 +2511,10 @@ TclObjCallVarTraces( if (!part1Ptr) { part1Ptr = localName(iPtr->varFramePtr, index); } - if (part1Ptr) { - part1 = TclGetString(part1Ptr); - } else { - part1 = tclEmptyString; + if (!part1Ptr) { + Tcl_Panic("Cannot trace a variable with no name"); } + part1 = TclGetString(part1Ptr); part2 = part2Ptr? TclGetString(part2Ptr) : NULL; return TclCallVarTraces(iPtr, arrayPtr, varPtr, part1, part2, flags, -- cgit v0.12 From cd1372b52d30c46ca122d45ed9031de427ff735d Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 3 Oct 2014 15:47:38 +0000 Subject: test cases --- tests/var.test | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tests/var.test b/tests/var.test index 8e862f7..a7950be 100644 --- a/tests/var.test +++ b/tests/var.test @@ -865,6 +865,17 @@ test var-20.8 {array set compilation correctness: Bug 3603163} -setup { }} array size x } -result 0 +test var-20.9 {[bc1a96407a] array set compiled w/ trace} { + variable foo + lappend lambda {} + lappend lambda [list array set [namespace which -variable foo] {a 1}] + after 0 [list apply $lambda] + vwait [namespace which -variable foo] + unset -nocomplain lambda foo +} {} +test var-20.10 {[bc1a96407a] array set don't compile bad varname} -body { + apply {{} {set name foo(bar); array set $name {a 1}}} +} -returnCodes error -match glob -result * test var-21.0 {PushVarNameWord OBOE in compiled unset} -setup { proc linenumber {} {dict get [info frame -1] line} -- cgit v0.12 From ea97de415f86eb70b3342e31f93ad04a0479382d Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 8 Oct 2014 07:02:34 +0000 Subject: Fix [59a2e78e54d3361c33b8cd6eef55d384d8abecd7|59a2e78e54] : tclWinTime.c does not compile with MSVC14. Eliminate use of __MINGW32__ macro everywhare, as it is deprecated. --- generic/tcl.h | 2 +- generic/tclAlloc.c | 2 +- win/tclWinPort.h | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/generic/tcl.h b/generic/tcl.h index af1af58..e915452 100644 --- a/generic/tcl.h +++ b/generic/tcl.h @@ -69,7 +69,7 @@ extern "C" { */ #ifndef __WIN32__ -# if defined(_WIN32) || defined(WIN32) || defined(__MINGW32__) || defined(__BORLANDC__) || (defined(__WATCOMC__) && defined(__WINDOWS_386__)) +# if defined(_WIN32) || defined(WIN32) || defined(__MSVCRT__) || defined(__BORLANDC__) || (defined(__WATCOMC__) && defined(__WINDOWS_386__)) # define __WIN32__ # ifndef WIN32 # define WIN32 diff --git a/generic/tclAlloc.c b/generic/tclAlloc.c index 8d0a2cc..675e1a4 100644 --- a/generic/tclAlloc.c +++ b/generic/tclAlloc.c @@ -31,7 +31,7 @@ * until Tcl uses config.h properly. */ -#if defined(_MSC_VER) || defined(__MINGW32__) || defined(__BORLANDC__) +#if defined(_MSC_VER) || defined(__MSVCRT__) || defined(__BORLANDC__) typedef unsigned long caddr_t; #endif diff --git a/win/tclWinPort.h b/win/tclWinPort.h index ea6d8f8..b2bf1d7 100644 --- a/win/tclWinPort.h +++ b/win/tclWinPort.h @@ -346,17 +346,17 @@ typedef DWORD_PTR * PDWORD_PTR; * EDEADLK as the same value, which confuses Tcl_ErrnoId(). */ -#if defined(_MSC_VER) || defined(__MINGW32__) +#if defined(_MSC_VER) || defined(__MSVCRT__) # define environ _environ # if defined(_MSC_VER) && (_MSC_VER < 1600) # define hypot _hypot # endif # define exception _exception # undef EDEADLOCK -# if defined(__MINGW32__) && !defined(__MSVCRT__) +# if defined(_MSC_VER) && (_MSC_VER >= 1700) # define timezone _timezone # endif -#endif /* _MSC_VER || __MINGW32__ */ +#endif /* _MSC_VER || __MSVCRT__ */ /* * Borland's timezone and environ functions. @@ -425,7 +425,7 @@ typedef DWORD_PTR * PDWORD_PTR; * Msvcrt's putenv() copies the string rather than takes ownership of it. */ -#if defined(_MSC_VER) || defined(__MINGW32__) +#if defined(_MSC_VER) || defined(__MSVCRT__) # define HAVE_PUTENV_THAT_COPIES 1 #endif -- cgit v0.12 From 891a0ade43d14a32a842ceef4e02ed99d43fea97 Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 9 Oct 2014 14:52:48 +0000 Subject: [2039178] Remove false claims about TCL_INTERP_DESTROYED flag bit in command traces. --- doc/TraceCmd.3 | 33 ++++++++++----------------------- 1 file changed, 10 insertions(+), 23 deletions(-) diff --git a/doc/TraceCmd.3 b/doc/TraceCmd.3 index b15face..7ff26e4 100644 --- a/doc/TraceCmd.3 +++ b/doc/TraceCmd.3 @@ -84,11 +84,14 @@ operation is being performed on the command. The bit \fBTCL_TRACE_DESTROYED\fR will be set in \fIflags\fR if the trace is about to be destroyed; this information may be useful to \fIproc\fR so that it can clean up its own internal data structures (see the section -\fBTCL_TRACE_DESTROYED\fR below for more details). Lastly, the bit -\fBTCL_INTERP_DESTROYED\fR will be set if the entire interpreter is being -destroyed. When this bit is set, \fIproc\fR must be especially -careful in the things it does (see the section \fBTCL_INTERP_DESTROYED\fR -below). +\fBTCL_TRACE_DESTROYED\fR below for more details). Because the +deletion of commands can take place as part of the deletion of the interp +that contains them, \fIproc\fR must be careful about checking what +the passed in \fIinterp\fR value can be called upon to do. +The routine \fBTcl_InterpDeleted\fR is an important tool for this. +When \fBTcl_InterpDeleted\fR returns 1, \fIproc\fR will not be able +to invoke any scripts in \fIinterp\fR. The function of \fIproc\fR +in that circumstance is limited to the cleanup of its own data structures. .PP \fBTcl_UntraceCommand\fR may be used to remove a trace. If the command specified by \fIinterp\fR, \fIcmdName\fR, and \fIflags\fR has @@ -121,7 +124,8 @@ traces for a given command that have the same \fIproc\fR. .PP During rename traces, the command being renamed is visible with both names simultaneously, and the command still exists during delete -traces (if \fBTCL_INTERP_DESTROYED\fR is not set). However, there is no +traces, unless the interp that contains it is being deleted. +However, there is no mechanism for signaling that an error occurred in a trace procedure, so great care should be taken that errors do not get silently lost. .SH "MULTIPLE TRACES" @@ -140,22 +144,5 @@ rename the command, the last renaming takes precedence. In a delete callback to \fIproc\fR, the \fBTCL_TRACE_DESTROYED\fR bit is set in \fIflags\fR. .\" Perhaps need some more comments here? - DKF -.SH "TCL_INTERP_DESTROYED" -.PP -When an interpreter is destroyed, unset traces are called for -all of its commands. -The \fBTCL_INTERP_DESTROYED\fR bit will be set in the \fIflags\fR -argument passed to the trace procedures. -Trace procedures must be extremely careful in what they do if -the \fBTCL_INTERP_DESTROYED\fR bit is set. -It is not safe for the procedures to invoke any Tcl procedures -on the interpreter, since its state is partially deleted. -All that trace procedures should do under these circumstances is -to clean up and free their own internal data structures. -.SH BUGS -.PP -Tcl does not do any error checking to prevent trace procedures -from misusing the interpreter during traces with \fBTCL_INTERP_DESTROYED\fR -set. .SH KEYWORDS clientData, trace, command -- cgit v0.12 From 1df1505d690829ae6b10569aaefc7bf012de486b Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 10 Oct 2014 15:38:15 +0000 Subject: New test io-53.15 for [ed29c4da21]. --- tests/io.test | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/tests/io.test b/tests/io.test index b8a5ab4..d1faf65 100644 --- a/tests/io.test +++ b/tests/io.test @@ -7610,6 +7610,51 @@ test io-53.11 {Bug 2895565} -setup { removeFile in } -result {40 bytes copied} +test io-53.15 {[ed29c4da21] DoRead: fblocked seen as error} -setup { + proc driver {cmd args} { + variable buffer + variable index + variable blocked + set chan [lindex $args 0] + switch -- $cmd { + initialize { + set index($chan) 0 + set buffer($chan) [encoding convertto utf-8 \ + [string repeat a 100]] + set blocked($chan) 1 + return {initialize finalize watch read} + } + finalize { + unset index($chan) buffer($chan) blocked($chan) + return + } + watch {} + read { + if {$blocked($chan)} { + set blocked($chan) [expr {!$blocked($chan)}] + return -code error EAGAIN + } + set n [lindex $args 1] + set new [expr {$index($chan) + $n}] + set result [string range $buffer($chan) $index($chan) $new-1] + set index($chan) $new + return $result + } + } + } + set c [chan create read [namespace which driver]] + chan configure $c -encoding utf-8 + set out [makeFile {} out] + set outChan [open $out w] + chan configure $outChan -encoding utf-8 +} -body { + chan copy $c $outChan +} -cleanup { + close $outChan + close $c + removeFile out +} -result 100 + test io-54.1 {Recursive channel events} {socket fileevent} { # This test checks to see if file events are delivered during recursive # event loops when there is buffered data on the channel. -- cgit v0.12 From 186ecf8003e9aea2b7ce651b4e1507a462cd4345 Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 10 Oct 2014 18:24:32 +0000 Subject: [ed29c4da21] Don't let BLOCKED state get converted into a channel error. --- generic/tclIO.c | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index 3119db5..2fd3792 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -8853,21 +8853,39 @@ DoRead( } /* - * If there is not enough data in the buffers to possibly - * complete the read, then go get more. + * Don't read more data if we have what we need. */ - if (bufPtr == NULL || BytesLeft(bufPtr) < bytesToRead) { + while (!bufPtr || /* We got no buffer! OR */ + (!IsBufferFull(bufPtr) && /* Our buffer has room AND */ + (BytesLeft(bufPtr) < bytesToRead) ) ) { + /* Not enough bytes in it + * yet to fill the dst */ + int code; + moreData: - if (GetInput(chanPtr)) { + code = GetInput(chanPtr); + bufPtr = statePtr->inQueueHead; + + assert (bufPtr != NULL); + + if (GotFlag(statePtr, CHANNEL_EOF|CHANNEL_BLOCKED)) { + /* Further reads cannot do any more */ + break; + } + + if (code) { /* Read error */ UpdateInterest(chanPtr); TclChannelRelease((Tcl_Channel)chanPtr); return -1; } - bufPtr = statePtr->inQueueHead; + + assert (IsBufferFull(bufPtr)); } + assert (bufPtr != NULL); + bytesRead = BytesLeft(bufPtr); bytesWritten = bytesToRead; -- cgit v0.12 From 1f33c7ae12c829e870b7bf7ac5db2a49ae551701 Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 10 Oct 2014 19:02:37 +0000 Subject: Another test so both DoRead and MBRead are covered. --- tests/io.test | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/tests/io.test b/tests/io.test index b657999..d9a5167 100644 --- a/tests/io.test +++ b/tests/io.test @@ -7752,6 +7752,50 @@ test io-53.15 {[ed29c4da21] DoRead: fblocked seen as error} -setup { close $c removeFile out } -result 100 +test io-53.16 {[ed29c4da21] MBRead: fblocked seen as error} -setup { + proc driver {cmd args} { + variable buffer + variable index + variable blocked + set chan [lindex $args 0] + switch -- $cmd { + initialize { + set index($chan) 0 + set buffer($chan) [encoding convertto utf-8 \ + [string repeat a 100]] + set blocked($chan) 1 + return {initialize finalize watch read} + } + finalize { + unset index($chan) buffer($chan) blocked($chan) + return + } + watch {} + read { + if {$blocked($chan)} { + set blocked($chan) [expr {!$blocked($chan)}] + return -code error EAGAIN + } + set n [lindex $args 1] + set new [expr {$index($chan) + $n}] + set result [string range $buffer($chan) $index($chan) $new-1] + set index($chan) $new + return $result + } + } + } + set c [chan create read [namespace which driver]] + chan configure $c -encoding utf-8 -translation lf + set out [makeFile {} out] + set outChan [open $out w] + chan configure $outChan -encoding utf-8 -translation lf +} -body { + chan copy $c $outChan +} -cleanup { + close $outChan + close $c + removeFile out +} -result 100 test io-54.1 {Recursive channel events} {socket fileevent} { # This test checks to see if file events are delivered during recursive -- cgit v0.12 From 182bace1e3066600b76ac9a242df2a4803f51f07 Mon Sep 17 00:00:00 2001 From: ferrieux Date: Fri, 10 Oct 2014 19:36:17 +0000 Subject: Add Colin's test for coro floor above street level [Bug #3008307] --- tests/coroutine.test | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/tests/coroutine.test b/tests/coroutine.test index 05b58c9..205da67 100644 --- a/tests/coroutine.test +++ b/tests/coroutine.test @@ -726,6 +726,20 @@ test coroutine-7.11 {yieldto context nuke: Bug a90d9331bc} -setup { catch {namespace delete ::cotest} catch {rename cotest ""} } -result {yieldto called in deleted namespace} +test coroutine-7.12 {coro floor above street level #3008307} -body { + proc c {} { + yield + } + proc cc {} { + coroutine C c + } + proc boom {} { + cc ; # coro created at level 2 + C ; # and called at level 1 + } + boom ; # does not crash: the coro floor is a good insulator + list +} -result {} # cleanup -- cgit v0.12 From 4977df535f65baabad14a446107f94bbdace5dfd Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 10 Oct 2014 19:44:54 +0000 Subject: [ed29c4da21] Completed fix for [chan copy] handling [chan blocked]. --- generic/tclIO.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index 3d36d45..2810372 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -9020,7 +9020,7 @@ MBRead( } code = GetInput(inStatePtr->topChanPtr); - if (code == 0) { + if (code == 0 || GotFlag(inStatePtr, CHANNEL_BLOCKED)) { return TCL_OK; } else { MBError(csPtr, TCL_READABLE, code); @@ -9270,6 +9270,10 @@ CopyData( csPtr); } if (size == 0) { + if (!GotFlag(inStatePtr, CHANNEL_NONBLOCKING)) { + /* We allowed a short read. Keep trying. */ + continue; + } if (bufObj != NULL) { TclDecrRefCount(bufObj); bufObj = NULL; -- cgit v0.12 From c2be2a28e0541de49216935f4245f53884d17ee0 Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 10 Oct 2014 19:54:19 +0000 Subject: [bf7135428c] Restore the Tcl_Write() return value logic. --- generic/tclIO.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index 2fd3792..d1f22c1 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -3484,7 +3484,10 @@ Tcl_Write( if (srcLen < 0) { srcLen = strlen(src); } - return WriteBytes(chanPtr, src, srcLen); + if (WriteBytes(chanPtr, src, srcLen) < 0) { + return -1; + } + return srcLen; } /* -- cgit v0.12 From 59f2031ac54d010c84ee64e6626a119959c645a6 Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 10 Oct 2014 20:02:00 +0000 Subject: backport those tests that can be --- tests/io.test | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/tests/io.test b/tests/io.test index d1faf65..006b403 100644 --- a/tests/io.test +++ b/tests/io.test @@ -7610,6 +7610,68 @@ test io-53.11 {Bug 2895565} -setup { removeFile in } -result {40 bytes copied} +# test io-53.12 not backported. Tests feature only in 8.6+ + +test io-53.13 {TclCopyChannel: read error reporting} -setup { + proc driver {cmd args} { + variable buffer + variable index + set chan [lindex $args 0] + switch -- $cmd { + initialize { + return {initialize finalize watch read} + } + finalize { + return + } + watch {} + read { + error FAIL + } + } + } + set outFile [makeFile {} out] +} -body { + set in [chan create read [namespace which driver]] + chan configure $in -translation binary + set out [open $outFile wb] + chan copy $in $out +} -cleanup { + catch {close $in} + catch {close $out} + removeFile out + rename driver {} +} -result {error reading "*": *} -returnCodes error -match glob +test io-53.14 {TclCopyChannel: write error reporting} -setup { + proc driver {cmd args} { + variable buffer + variable index + set chan [lindex $args 0] + switch -- $cmd { + initialize { + return {initialize finalize watch write} + } + finalize { + return + } + watch {} + write { + error FAIL + } + } + } + set inFile [makeFile {aaa} in] +} -body { + set in [open $inFile rb] + set out [chan create write [namespace which driver]] + chan configure $out -translation binary + chan copy $in $out +} -cleanup { + catch {close $in} + catch {close $out} + removeFile in + rename driver {} +} -result {error writing "*": *} -returnCodes error -match glob test io-53.15 {[ed29c4da21] DoRead: fblocked seen as error} -setup { proc driver {cmd args} { variable buffer -- cgit v0.12 From 1ce240e90ff9c5fd4b853ee04982b142bc6f6536 Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 10 Oct 2014 20:17:12 +0000 Subject: Bump to 8.5.17 --- README | 2 +- generic/tcl.h | 2 +- library/init.tcl | 2 +- unix/configure | 2 +- unix/configure.in | 2 +- unix/tcl.spec | 2 +- win/configure | 2 +- win/configure.in | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/README b/README index 256174f..425ca16 100644 --- a/README +++ b/README @@ -1,5 +1,5 @@ README: Tcl - This is the Tcl 8.5.16 source distribution. + This is the Tcl 8.5.17 source distribution. http://sourceforge.net/projects/tcl/files/Tcl/ You can get any source release of Tcl from the URL above. diff --git a/generic/tcl.h b/generic/tcl.h index e915452..07e48c3 100644 --- a/generic/tcl.h +++ b/generic/tcl.h @@ -61,7 +61,7 @@ extern "C" { #define TCL_RELEASE_SERIAL 16 #define TCL_VERSION "8.5" -#define TCL_PATCH_LEVEL "8.5.16" +#define TCL_PATCH_LEVEL "8.5.17" /* * The following definitions set up the proper options for Windows compilers. diff --git a/library/init.tcl b/library/init.tcl index 61a80a5..5004e0c 100644 --- a/library/init.tcl +++ b/library/init.tcl @@ -16,7 +16,7 @@ if {[info commands package] == ""} { error "version mismatch: library\nscripts expect Tcl version 7.5b1 or later but the loaded version is\nonly [info patchlevel]" } -package require -exact Tcl 8.5.16 +package require -exact Tcl 8.5.17 # Compute the auto path to use in this interpreter. # The values on the path come from several locations: diff --git a/unix/configure b/unix/configure index ff7791e..1264916 100755 --- a/unix/configure +++ b/unix/configure @@ -1335,7 +1335,7 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu TCL_VERSION=8.5 TCL_MAJOR_VERSION=8 TCL_MINOR_VERSION=5 -TCL_PATCH_LEVEL=".16" +TCL_PATCH_LEVEL=".17" VERSION=${TCL_VERSION} #------------------------------------------------------------------------ diff --git a/unix/configure.in b/unix/configure.in index 3228353..22c8985 100644 --- a/unix/configure.in +++ b/unix/configure.in @@ -25,7 +25,7 @@ m4_ifdef([SC_USE_CONFIG_HEADERS], [ TCL_VERSION=8.5 TCL_MAJOR_VERSION=8 TCL_MINOR_VERSION=5 -TCL_PATCH_LEVEL=".16" +TCL_PATCH_LEVEL=".17" VERSION=${TCL_VERSION} #------------------------------------------------------------------------ diff --git a/unix/tcl.spec b/unix/tcl.spec index bdc6e27..4b6a6a0 100644 --- a/unix/tcl.spec +++ b/unix/tcl.spec @@ -4,7 +4,7 @@ Name: tcl Summary: Tcl scripting language development environment -Version: 8.5.16 +Version: 8.5.17 Release: 2 License: BSD Group: Development/Languages diff --git a/win/configure b/win/configure index 8e33eb3..dc24431 100755 --- a/win/configure +++ b/win/configure @@ -1311,7 +1311,7 @@ SHELL=/bin/sh TCL_VERSION=8.5 TCL_MAJOR_VERSION=8 TCL_MINOR_VERSION=5 -TCL_PATCH_LEVEL=".16" +TCL_PATCH_LEVEL=".17" VER=$TCL_MAJOR_VERSION$TCL_MINOR_VERSION TCL_DDE_VERSION=1.3 diff --git a/win/configure.in b/win/configure.in index aa42036..14d9b0f 100644 --- a/win/configure.in +++ b/win/configure.in @@ -14,7 +14,7 @@ SHELL=/bin/sh TCL_VERSION=8.5 TCL_MAJOR_VERSION=8 TCL_MINOR_VERSION=5 -TCL_PATCH_LEVEL=".16" +TCL_PATCH_LEVEL=".17" VER=$TCL_MAJOR_VERSION$TCL_MINOR_VERSION TCL_DDE_VERSION=1.3 -- cgit v0.12 From ef89704696f7ce48c9e84dff959c72e2fd887959 Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 10 Oct 2014 20:37:58 +0000 Subject: Resolve test conflicts over global vars --- tests/utf.test | 6 ++++-- tests/var.test | 9 +++++++-- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/tests/utf.test b/tests/utf.test index 2fcac49..83daddf 100644 --- a/tests/utf.test +++ b/tests/utf.test @@ -287,9 +287,11 @@ test utf-18.5 {Tcl_UniCharToTitle, no delta} { string totitle ! } ! -test utf-19.1 {TclUniCharLen} { +test utf-19.1 {TclUniCharLen} -body { list [regexp \\d abc456def foo] $foo -} {1 4} +} -cleanup { + unset -nocomplain foo +} -result {1 4} test utf-20.1 {TclUniCharNcmp} { } {} diff --git a/tests/var.test b/tests/var.test index a7950be..7ff394e 100644 --- a/tests/var.test +++ b/tests/var.test @@ -865,14 +865,19 @@ test var-20.8 {array set compilation correctness: Bug 3603163} -setup { }} array size x } -result 0 -test var-20.9 {[bc1a96407a] array set compiled w/ trace} { +test var-20.9 {[bc1a96407a] array set compiled w/ trace} -setup { variable foo + variable lambda + unset -nocomplain lambda foo + array set foo {} lappend lambda {} lappend lambda [list array set [namespace which -variable foo] {a 1}] +} -body { after 0 [list apply $lambda] vwait [namespace which -variable foo] +} -cleanup { unset -nocomplain lambda foo -} {} +} -result {} test var-20.10 {[bc1a96407a] array set don't compile bad varname} -body { apply {{} {set name foo(bar); array set $name {a 1}}} } -returnCodes error -match glob -result * -- cgit v0.12 From 59491ce8ca3e24c6d1bc7c36f15f0b160d04f5dd Mon Sep 17 00:00:00 2001 From: dgp Date: Mon, 13 Oct 2014 17:15:55 +0000 Subject: update changes file --- changes | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/changes b/changes index 4b5ba55..4bfe0e4 100644 --- a/changes +++ b/changes @@ -7894,3 +7894,13 @@ of Tcl_Channel (porter) 2014-08-12 tzdata updated to Olson's tzdata2014f (kenny) --- Released 8.5.16, August 25, 2014 --- http://core.tcl.tk/tcl/ for details + +2014-10-02 (bug)[bc5b79] Hang in some [read]s of limited size (rogers,porter) + +2014-10-08 (bug)[59a2e7] MSVC14 compile support (dower,nijtmans) + +2014-10-10 (bug)[ed29c4] [fcopy] treats [blocked] as error (rowen,porter) + +2014-10-10 (bug)[bf7135] regression in Tcl_Write() interface (porter) + +--- Released 8.5.17, October 25, 2014 --- http://core.tcl.tk/tcl/ for details -- cgit v0.12 From 1234267c928003fe9b7620f09eb38f68844b6989 Mon Sep 17 00:00:00 2001 From: dgp Date: Mon, 13 Oct 2014 17:34:12 +0000 Subject: missed a bump --- generic/tcl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generic/tcl.h b/generic/tcl.h index 07e48c3..98cd577 100644 --- a/generic/tcl.h +++ b/generic/tcl.h @@ -58,7 +58,7 @@ extern "C" { #define TCL_MAJOR_VERSION 8 #define TCL_MINOR_VERSION 5 #define TCL_RELEASE_LEVEL TCL_FINAL_RELEASE -#define TCL_RELEASE_SERIAL 16 +#define TCL_RELEASE_SERIAL 17 #define TCL_VERSION "8.5" #define TCL_PATCH_LEVEL "8.5.17" -- cgit v0.12 From d31d85870254e265c5e12a212e3ade58e63c247e Mon Sep 17 00:00:00 2001 From: dgp Date: Tue, 14 Oct 2014 18:12:36 +0000 Subject: Bump to Tcl 8.6.3, TclOO 1.0.3, and update changes file. --- README | 2 +- changes | 29 +++++++++++++++++++++++++++++ generic/tcl.h | 4 ++-- generic/tclOO.h | 2 +- library/init.tcl | 2 +- tests/oo.test | 2 +- tests/ooNext2.test | 2 +- unix/configure | 2 +- unix/configure.in | 2 +- unix/tcl.spec | 2 +- unix/tclooConfig.sh | 2 +- win/configure | 2 +- win/configure.in | 2 +- win/tclooConfig.sh | 2 +- 14 files changed, 43 insertions(+), 14 deletions(-) diff --git a/README b/README index 66e1b76..0fb128d 100644 --- a/README +++ b/README @@ -1,5 +1,5 @@ README: Tcl - This is the Tcl 8.6.2 source distribution. + This is the Tcl 8.6.3 source distribution. http://sourceforge.net/projects/tcl/files/Tcl/ You can get any source release of Tcl from the URL above. diff --git a/changes b/changes index ba0854b..02b6ddc 100644 --- a/changes +++ b/changes @@ -8452,3 +8452,32 @@ 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-28 (bug)[b9e1a3] Correct Method Search Order (nadkarni,fellows) +=> TclOO 1.0.3 + +2014-09-05 (bug)[ccc2c2] Regression [lreplace {} 1 1] (bron,fellows) + +2014-09-08 (bug) Crash regression in [oo::class destroy] (porter) + +2014-09-09 (bug)[84af11] Regress [regsub -all {\(.*} a(b) {}] (oehlmann,fellows) + +2014-09-10 (bug)[cee90e] [try {} on ok {} - on return {} {}] panic (porter) + +2014-09-20 (feature) [tcl::unsupported::getbytecode] disassember (fellows) + +2014-09-27 (enhancement) [string cat] bytecode optimization (leitgeb,ferrieux) + +2014-09-27 (bug)[82521b] segfault in mangled bytecode (ogilvie,sofer) + +2014-10-02 (bug)[bc5b79] Hang in some [read]s of limited size (rogers,porter) + +2014-10-03 (bug)[bc1a96] segfault in [array set] of traced array (tab,porter) + +2014-10-08 (bug)[59a2e7] MSVC14 compile support (dower,nijtmans) + +2014-10-10 (bug)[ed29c4] [fcopy] treats [blocked] as error (rowen,porter) + +2014-10-10 (bug)[bf7135] regression in Tcl_Write() interface (porter) + +--- Released 8.6.3, October 29, 2014 --- http://core.tcl.tk/tcl/ for details diff --git a/generic/tcl.h b/generic/tcl.h index 7531242..fc477f2 100644 --- a/generic/tcl.h +++ b/generic/tcl.h @@ -56,10 +56,10 @@ extern "C" { #define TCL_MAJOR_VERSION 8 #define TCL_MINOR_VERSION 6 #define TCL_RELEASE_LEVEL TCL_FINAL_RELEASE -#define TCL_RELEASE_SERIAL 2 +#define TCL_RELEASE_SERIAL 3 #define TCL_VERSION "8.6" -#define TCL_PATCH_LEVEL "8.6.2" +#define TCL_PATCH_LEVEL "8.6.3" /* *---------------------------------------------------------------------------- diff --git a/generic/tclOO.h b/generic/tclOO.h index 24d3e6f..a7116dc 100644 --- a/generic/tclOO.h +++ b/generic/tclOO.h @@ -24,7 +24,7 @@ * win/tclooConfig.sh */ -#define TCLOO_VERSION "1.0.2" +#define TCLOO_VERSION "1.0.3" #define TCLOO_PATCHLEVEL TCLOO_VERSION #include "tcl.h" diff --git a/library/init.tcl b/library/init.tcl index 265f928..f1f7704 100644 --- a/library/init.tcl +++ b/library/init.tcl @@ -16,7 +16,7 @@ if {[info commands package] == ""} { error "version mismatch: library\nscripts expect Tcl version 7.5b1 or later but the loaded version is\nonly [info patchlevel]" } -package require -exact Tcl 8.6.2 +package require -exact Tcl 8.6.3 # Compute the auto path to use in this interpreter. # The values on the path come from several locations: diff --git a/tests/oo.test b/tests/oo.test index 2c189ca..5fa760b 100644 --- a/tests/oo.test +++ b/tests/oo.test @@ -7,7 +7,7 @@ # 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.1 +package require TclOO 1.0.3 package require tcltest 2 if {"::tcltest" in [namespace children]} { namespace import -force ::tcltest::* diff --git a/tests/ooNext2.test b/tests/ooNext2.test index 9a63577..5ecd209 100644 --- a/tests/ooNext2.test +++ b/tests/ooNext2.test @@ -7,7 +7,7 @@ # 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.1 +package require TclOO 1.0.3 package require tcltest 2 if {"::tcltest" in [namespace children]} { namespace import -force ::tcltest::* diff --git a/unix/configure b/unix/configure index 5291bf7..a9837d9 100755 --- a/unix/configure +++ b/unix/configure @@ -1335,7 +1335,7 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu TCL_VERSION=8.6 TCL_MAJOR_VERSION=8 TCL_MINOR_VERSION=6 -TCL_PATCH_LEVEL=".2" +TCL_PATCH_LEVEL=".3" VERSION=${TCL_VERSION} EXTRA_INSTALL_BINARIES=${EXTRA_INSTALL_BINARIES:-"@:"} diff --git a/unix/configure.in b/unix/configure.in index 85bd7ee..e44d554 100644 --- a/unix/configure.in +++ b/unix/configure.in @@ -25,7 +25,7 @@ m4_ifdef([SC_USE_CONFIG_HEADERS], [ TCL_VERSION=8.6 TCL_MAJOR_VERSION=8 TCL_MINOR_VERSION=6 -TCL_PATCH_LEVEL=".2" +TCL_PATCH_LEVEL=".3" VERSION=${TCL_VERSION} EXTRA_INSTALL_BINARIES=${EXTRA_INSTALL_BINARIES:-"@:"} diff --git a/unix/tcl.spec b/unix/tcl.spec index 50aacc6..d660f74 100644 --- a/unix/tcl.spec +++ b/unix/tcl.spec @@ -4,7 +4,7 @@ Name: tcl Summary: Tcl scripting language development environment -Version: 8.6.2 +Version: 8.6.3 Release: 2 License: BSD Group: Development/Languages diff --git a/unix/tclooConfig.sh b/unix/tclooConfig.sh index 14b0d8d..55fe75f 100644 --- a/unix/tclooConfig.sh +++ b/unix/tclooConfig.sh @@ -16,4 +16,4 @@ TCLOO_STUB_LIB_SPEC="" TCLOO_INCLUDE_SPEC="" TCLOO_PRIVATE_INCLUDE_SPEC="" TCLOO_CFLAGS="" -TCLOO_VERSION=1.0.2 +TCLOO_VERSION=1.0.3 diff --git a/win/configure b/win/configure index cf2b201..b270648 100755 --- a/win/configure +++ b/win/configure @@ -1311,7 +1311,7 @@ SHELL=/bin/sh TCL_VERSION=8.6 TCL_MAJOR_VERSION=8 TCL_MINOR_VERSION=6 -TCL_PATCH_LEVEL=".2" +TCL_PATCH_LEVEL=".3" VER=$TCL_MAJOR_VERSION$TCL_MINOR_VERSION TCL_DDE_VERSION=1.4 diff --git a/win/configure.in b/win/configure.in index aa47505..1bf901a 100644 --- a/win/configure.in +++ b/win/configure.in @@ -14,7 +14,7 @@ SHELL=/bin/sh TCL_VERSION=8.6 TCL_MAJOR_VERSION=8 TCL_MINOR_VERSION=6 -TCL_PATCH_LEVEL=".2" +TCL_PATCH_LEVEL=".3" VER=$TCL_MAJOR_VERSION$TCL_MINOR_VERSION TCL_DDE_VERSION=1.4 diff --git a/win/tclooConfig.sh b/win/tclooConfig.sh index 14b0d8d..55fe75f 100644 --- a/win/tclooConfig.sh +++ b/win/tclooConfig.sh @@ -16,4 +16,4 @@ TCLOO_STUB_LIB_SPEC="" TCLOO_INCLUDE_SPEC="" TCLOO_PRIVATE_INCLUDE_SPEC="" TCLOO_CFLAGS="" -TCLOO_VERSION=1.0.2 +TCLOO_VERSION=1.0.3 -- cgit v0.12 From d7604e5728758d9d4d1efb8124548d3df914bf9b Mon Sep 17 00:00:00 2001 From: oehhar Date: Fri, 17 Oct 2014 12:28:55 +0000 Subject: New tests: 14.16: -peername empty while async connect running, 14.17: -sockname --- tests/socket.test | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/tests/socket.test b/tests/socket.test index c50730c..d6cee30 100644 --- a/tests/socket.test +++ b/tests/socket.test @@ -2321,6 +2321,28 @@ test socket-14.15 {blocking read on async socket should not trigger event handle set x } -result ok +# v4 and v6 is required to prevent that the async connect does not terminate +# before the fconfigure command. There is always an additional ip to try. +test socket-14.16 {empty -peername while [socket -async] connecting} \ + -constraints {socket localhost_v4 localhost_v6} \ + -body { + set client [socket -async localhost [randport]] + fconfigure $client -peername + } -cleanup { + catch {close $client} + } -result {} + +# v4 and v6 is required to prevent that the async connect does not terminate +# before the fconfigure command. There is always an additional ip to try. +test socket-14.17 {empty -sockname while [socket -async] connecting} \ + -constraints {socket localhost_v4 localhost_v6} \ + -body { + set client [socket -async localhost [randport]] + fconfigure $client -sockname + } -cleanup { + catch {close $client} + } -result {} + set num 0 set x {localhost {socket} 127.0.0.1 {supported_inet} ::1 {supported_inet6}} -- cgit v0.12 From 592ab670f31771d34eb4ff0d879ce894696c061c Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 17 Oct 2014 15:20:34 +0000 Subject: [10dc6daa37] [gets] on a non-blocking channel must take care so that 1) At least one call to the channel driver input proc gets made. Failure to do this locks up the channel - catastrophic FAIL. 2) After any driver call reports BLOCKED, don't call again. This is less serious, but FAILs to respect the non-blocking setting. Code corrections and tests included, to restore 8.5.15 compat. --- generic/tclIO.c | 6 +++++ tests/io.test | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+) diff --git a/generic/tclIO.c b/generic/tclIO.c index d1f22c1..e786946 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -4042,6 +4042,7 @@ Tcl_GetsObj( eof = NULL; inEofChar = statePtr->inEofChar; + ResetFlag(statePtr, CHANNEL_BLOCKED); while (1) { if (dst >= dstEnd) { if (FilterInputBytes(chanPtr, &gs) != 0) { @@ -4211,6 +4212,10 @@ Tcl_GetsObj( } goto gotEOL; } + if (GotFlag(statePtr, CHANNEL_BLOCKED|CHANNEL_NONBLOCKING) + == (CHANNEL_BLOCKED|CHANNEL_NONBLOCKING)) { + goto restore; + } dst = dstEnd; } @@ -4386,6 +4391,7 @@ TclGetsObjBinary( /* Only handle TCL_TRANSLATE_LF and TCL_TRANSLATE_CR */ eolChar = (statePtr->inputTranslation == TCL_TRANSLATE_LF) ? '\n' : '\r'; + ResetFlag(statePtr, CHANNEL_BLOCKED); while (1) { /* * Subtract the number of bytes that were removed from channel diff --git a/tests/io.test b/tests/io.test index 006b403..0d9468d 100644 --- a/tests/io.test +++ b/tests/io.test @@ -4299,6 +4299,74 @@ test io-33.10 {Tcl_Gets, exercising double buffering} { close $f set y } 300 +test io-33.11 {TclGetsObjBinary, [10dc6daa37]} -setup { + proc driver {cmd args} { + variable buffer + variable index + set chan [lindex $args 0] + switch -- $cmd { + initialize { + set index($chan) 0 + set buffer($chan) ....... + return {initialize finalize watch read} + } + finalize { + unset index($chan) buffer($chan) + return + } + watch {} + read { + set n [lindex $args 1] + if {$n > 3} {set n 3} + set new [expr {$index($chan) + $n}] + set result [string range $buffer($chan) $index($chan) $new-1] + set index($chan) $new + return $result + } + } + } +} -body { + set c [chan create read [namespace which driver]] + chan configure $c -translation binary -blocking 0 + list [gets $c] [gets $c] [gets $c] [gets $c] +} -cleanup { + close $c + rename driver {} +} -result {{} {} {} .......} +test io-33.12 {TclGetsObjBinary, [10dc6daa37]} -setup { + proc driver {cmd args} { + variable buffer + variable index + set chan [lindex $args 0] + switch -- $cmd { + initialize { + set index($chan) 0 + set buffer($chan) ....... + return {initialize finalize watch read} + } + finalize { + unset index($chan) buffer($chan) + return + } + watch {} + read { + set n [lindex $args 1] + if {$n > 3} {set n 3} + set new [expr {$index($chan) + $n}] + set result [string range $buffer($chan) $index($chan) $new-1] + set index($chan) $new + return $result + } + } + } +} -body { + set c [chan create read [namespace which driver]] + chan configure $c -blocking 0 + list [gets $c] [gets $c] [gets $c] [gets $c] +} -cleanup { + close $c + rename driver {} +} -result {{} {} {} .......} # Test Tcl_Seek and Tcl_Tell. -- cgit v0.12 From eee56ee95a29c04992fbef72c0b71aedad5d3828 Mon Sep 17 00:00:00 2001 From: dgp Date: Sat, 18 Oct 2014 20:11:36 +0000 Subject: update changes --- changes | 2 ++ 1 file changed, 2 insertions(+) diff --git a/changes b/changes index 4bfe0e4..6a617fa 100644 --- a/changes +++ b/changes @@ -7903,4 +7903,6 @@ of Tcl_Channel (porter) 2014-10-10 (bug)[bf7135] regression in Tcl_Write() interface (porter) +2014-10-18 (bug)[10dc6d] fix [gets] on non-blocking channels (fassel,porter) + --- Released 8.5.17, October 25, 2014 --- http://core.tcl.tk/tcl/ for details -- cgit v0.12 From 91d5ac9d0b03b6717bf3adc4610c5a07aa8b46ff Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 22 Oct 2014 14:46:33 +0000 Subject: by request --- changes | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changes b/changes index 3e6e53b..03184e4 100644 --- a/changes +++ b/changes @@ -8460,7 +8460,7 @@ include ::oo::class (fellows) 2014-09-08 (bug) Crash regression in [oo::class destroy] (porter) -2014-09-09 (bug)[84af11] Regress [regsub -all {\(.*} a(b) {}] (oehlmann,fellows) +2014-09-09 (bug)[84af11] Regress [regsub -all {\(.*} a(b) {}] (fellows) 2014-09-10 (bug)[cee90e] [try {} on ok {} - on return {} {}] panic (porter) -- cgit v0.12 From 999c88ea06627d4c3dc57cb5f588cdd136622682 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Sun, 26 Oct 2014 07:51:22 +0000 Subject: Support for Windows 10 --- win/tclsh.exe.manifest.in | 2 ++ 1 file changed, 2 insertions(+) diff --git a/win/tclsh.exe.manifest.in b/win/tclsh.exe.manifest.in index b7c4381..8b06fce 100644 --- a/win/tclsh.exe.manifest.in +++ b/win/tclsh.exe.manifest.in @@ -20,6 +20,8 @@ + + -- cgit v0.12 From df4391e23fc406eaba4bd156bf17a9672d205e2b Mon Sep 17 00:00:00 2001 From: dgp Date: Tue, 28 Oct 2014 20:10:32 +0000 Subject: Work in progress restoring ability to [read] after [eof] and get non-empty strings back in those cases where the channel has them to offer. Also working through all the implications of this possibility on Tcl's more exotic channel features, like stacking. --- generic/tclIO.c | 88 ++++++++++++++++++++++++++++++++++++++++++------------- generic/tclIOGT.c | 20 ++++++++----- 2 files changed, 79 insertions(+), 29 deletions(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index 0122ec9..c55c118 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -4414,6 +4414,17 @@ TclGetsObjBinary( if (bufPtr == NULL) { goto restore; } + } else { + /* + * There's something already in the buffer. If + * CHANNEL_STICKY_EOF is set we know that something begins + * with the eofchar. Otherwise, if CHANNEL_EOF is set, we + * know some earlier inputproc call returned zero bytes when + * we were trying to get more bytes to put in the buffer. + * which means..... ???? Place to probe with tests. + */ + assert (GotFlag(statePtr, CHANNEL_STICKY_EOF) + || !GotFlag(statePtr, CHANNEL_EOF) ); } dst = (unsigned char *) RemovePoint(bufPtr); @@ -4694,6 +4705,9 @@ FilterInputBytes( gsPtr->rawRead = 0; return -1; } + } else { + assert( GotFlag(statePtr, CHANNEL_STICKY_EOF) + || !GotFlag(statePtr, CHANNEL_EOF) ); } /* @@ -5018,6 +5032,7 @@ Tcl_ReadRaw( /* State info for channel */ int copied = 0; + assert(bytesToRead > 0); if (CheckChannelErrors(statePtr, TCL_READABLE | CHANNEL_RAW_MODE) != 0) { return -1; } @@ -5049,8 +5064,19 @@ Tcl_ReadRaw( } } - /* Go to the driver if more data needed. */ + /* + * Go to the driver only if we got nothing from pushback. + * Have to do it this way to avoid EOF mis-timings when we + * consider the ability that EOF may not be a permanent + * condition in the driver, and in that case we have to + * synchronize. + */ + + if (copied) { + return copied; + } + /* This test not needed. */ if (bytesToRead > 0) { int nread = ChanRead(chanPtr, readBuf, bytesToRead); @@ -5073,12 +5099,10 @@ Tcl_ReadRaw( if (!GotFlag(statePtr, CHANNEL_BLOCKED) || copied == 0) { copied = -1; } - } else if (copied > 0) { + } else { /* - * nread == 0. Driver is at EOF, but if copied>0 bytes - * from pushback, then we should not signal it yet. + * nread == 0. Driver is at EOF. Let that state filter up. */ - ResetFlag(statePtr, CHANNEL_EOF); } } return copied; @@ -6120,18 +6144,39 @@ GetInput( } /* - * For a channel at EOF do not bother allocating buffers; there's - * nothing more to read. Avoid calling the driver inputproc in - * case some of them do not react well to additional calls after - * they've reported an eof state.. - * TODO: Candidate for a can't happen panic. + * Strangely named "STICKY_EOF" really means we've seen the + * eofchar for this channel, and nothing since has reset it. + * (changed the eofchar, [seek]ed to a new offset, etc.) So, + * we know we're still poised to read that eofchar again, and + * there's no need to actually do it. */ - if (GotFlag(statePtr, CHANNEL_EOF)) { + if (GotFlag(statePtr, CHANNEL_STICKY_EOF)) { + assert(statePtr->inEofChar); + assert(statePtr->inQueueHead); + assert(RemovePoint(statePtr->inQueueHead)[0] == statePtr->inEofChar); return 0; } /* + * WARNING: There was once a comment here claiming that it was + * a bad idea to make another call to the inputproc of a channel + * driver when EOF has already been detected on the channel. Through + * much of Tcl's history, this warning was then completely negated + * by having all (most?) read paths clear the EOF setting before + * reaching here. So we had a guard that was never triggered. + * + * Don't be tempted to restore the guard. Even if EOF is set on + * the channel, continue through and call the inputproc again. This + * is the way to enable the ability to [read] again beyond the EOF, + * which seems a strange thing to do, but for which use cases exist + * [Tcl Bug 5adc350683] and which may even be essential for channels + * representing things like ttys or other devices where the stream + * might take the logical form of a series of 'files' separated by + * an EOF condition. + */ + + /* * First check for more buffers in the pushback area of the topmost * channel in the stack and use them. They can be the result of a * transformation which went away without reading all the information @@ -8848,16 +8893,6 @@ DoRead( ChannelBuffer *bufPtr = statePtr->inQueueHead; /* - * When there's no buffered data to read, and we're at EOF, - * escape to the caller. - */ - - if (GotFlag(statePtr, CHANNEL_EOF) - && (bufPtr == NULL || IsBufferEmpty(bufPtr))) { - break; - } - - /* * Don't read more data if we have what we need. */ @@ -8969,12 +9004,23 @@ DoRead( statePtr->inQueueTail = NULL; } RecycleBuffer(statePtr, bufPtr, 0); + bufPtr = statePtr->inQueueHead; } if (GotFlag(statePtr, CHANNEL_NONBLOCKING|CHANNEL_BLOCKED) == (CHANNEL_NONBLOCKING|CHANNEL_BLOCKED)) { break; } + + /* + * When there's no buffered data to read, and we're at EOF, + * escape to the caller. + */ + + if (GotFlag(statePtr, CHANNEL_EOF) + && (bufPtr == NULL || IsBufferEmpty(bufPtr))) { + break; + } } if (bytesToRead == 0) { ResetFlag(statePtr, CHANNEL_BLOCKED); diff --git a/generic/tclIOGT.c b/generic/tclIOGT.c index fe0a880..a78a5b4 100644 --- a/generic/tclIOGT.c +++ b/generic/tclIOGT.c @@ -677,6 +677,18 @@ TransformInputProc( break; } + if (dataPtr->readIsFlushed) { + /* + * Already saw EOF from downChan; don't ask again. + * NOTE: Could move this up to avoid the last maxRead + * execution. Believe this would still be correct behavior, + * but the test suite tests the whole command callback + * sequence, so leave it unchanged for now. + */ + + break; + } + /* * Get bytes from the underlying channel. */ @@ -712,14 +724,6 @@ TransformInputProc( * on the down channel. */ - if (dataPtr->readIsFlushed) { - /* - * Already flushed, nothing to do anymore. - */ - - break; - } - dataPtr->readIsFlushed = 1; ExecuteCallback(dataPtr, NULL, A_FLUSH_READ, NULL, 0, TRANSMIT_IBUF, P_PRESERVE); -- cgit v0.12 From 54d28836947092e8b7d97edb969105e54dc2a734 Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 29 Oct 2014 14:54:11 +0000 Subject: Base test for [5adc350683]. --- tests/io.test | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/tests/io.test b/tests/io.test index f6690ad..d533957 100644 --- a/tests/io.test +++ b/tests/io.test @@ -8399,6 +8399,26 @@ test io-73.2 {channel Tcl_Obj SetChannelFromAny, bug 2407783} {} { list $code [string map [list $f @@] $msg] } {1 {can not find channel named "@@"}} +test io-73.3 {[5adc350683] [gets] after EOF} -setup { + set fn [makeFile {} io-73.3] + set rfd [open $fn r] + set wfd [open $fn a] + chan configure $wfd -buffering line + read $rfd +} -body { + set result [eof $rfd] + puts $wfd "more data" + lappend result [eof $rfd] + lappend result [gets $rfd] + lappend result [eof $rfd] + lappend result [gets $rfd] + lappend result [eof $rfd] +} -cleanup { + close $wfd + close $rfd + removeFile io-73.3 +} -result {1 1 {more data} 0 {} 1} + # ### ### ### ######### ######### ######### # cleanup -- cgit v0.12 From 476a68cbe549a2c2b03a9bd89d3e59dae94fc2a4 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Fri, 31 Oct 2014 09:59:36 +0000 Subject: When translating a reserved devicename to native pathname, strip ':' postfix. Possible fix for [dcc03414f5], but anyway a good idea. --- win/tclWinFile.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/win/tclWinFile.c b/win/tclWinFile.c index 9bf63b1..163050e 100644 --- a/win/tclWinFile.c +++ b/win/tclWinFile.c @@ -3203,7 +3203,10 @@ TclNativeCreateNativeRep( Tcl_WinUtfToTChar(str, len, &ds); if (tclWinProcs->useWide) { WCHAR *wp = (WCHAR *) Tcl_DStringValue(&ds); - len = Tcl_DStringLength(&ds)>>1; + /* For a reserved device, strip a possible postfix ':' */ + len = WinIsReserved(str); + /* For normal devices */ + if (len == 0) len = Tcl_DStringLength(&ds)>>1; /* ** If path starts with "//?/" or "\\?\" (extended path), translate ** any slashes to backslashes but accept the '?' as being valid. -- cgit v0.12 From 1e769e4b57a93366904bacf51192d6bf73203d99 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Fri, 31 Oct 2014 10:57:25 +0000 Subject: Extend WinIsReserved() to recognize COM[5-9]: as valid com ports as well. --- win/tclWinFile.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/win/tclWinFile.c b/win/tclWinFile.c index 163050e..7487022 100644 --- a/win/tclWinFile.c +++ b/win/tclWinFile.c @@ -1225,9 +1225,9 @@ WinIsReserved( if ((path[0] == 'c' || path[0] == 'C') && (path[1] == 'o' || path[1] == 'O')) { if ((path[2] == 'm' || path[2] == 'M') - && path[3] >= '1' && path[3] <= '4') { + && path[3] >= '1' && path[3] <= '9') { /* - * May have match for 'com[1-4]:?', which is a serial port. + * May have match for 'com[1-9]:?', which is a serial port. */ if (path[4] == '\0') { -- cgit v0.12 From d95273cf0eb1e28a3c4b1043658585dc3119f832 Mon Sep 17 00:00:00 2001 From: dgp Date: Sat, 1 Nov 2014 14:52:55 +0000 Subject: Disable assertion until tls bug it detects is fixed. --- generic/tclIO.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index 207ce19..9cbc72c 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -2811,9 +2811,15 @@ FlushChannel( * write in this call, and we've completed the BG flush. * These are the two cases above. If we get here, that means * there is some kind failure in the writable event machinery. - */ + * + * The tls extension indeed suffers from flaws in its channel + * event mgmt. See http://core.tcl.tk/tcl/info/c31ca233ca. + * Until that patch is broadly distributed, disable the + * assertion checking here, so that programs using Tcl and + * tls can be debugged. assert(!calledFromAsyncFlush); + */ } } -- cgit v0.12 From 7ec17e20d3b45d7e573de0a37cde54001cae0e30 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Mon, 3 Nov 2014 10:14:48 +0000 Subject: Better errormessage when file path contains invalid characters. See: [03414f517b7a74]. --- win/tclWinChan.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/win/tclWinChan.c b/win/tclWinChan.c index 6d480a8..a271919 100644 --- a/win/tclWinChan.c +++ b/win/tclWinChan.c @@ -840,6 +840,11 @@ TclpOpenFileChannel( nativeName = (TCHAR*) Tcl_FSGetNativePath(pathPtr); if (nativeName == NULL) { + if (interp != (Tcl_Interp *) NULL) { + Tcl_AppendResult(interp, "couldn't open \"", + TclGetString(pathPtr), "\": filename is invalid on this platform", + NULL); + } return NULL; } -- cgit v0.12 From 48ab03f3cd8e637c9cdd52bdbb93737f07d2bb60 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Mon, 3 Nov 2014 12:44:55 +0000 Subject: Add test-case for previous commit, which shows that when trying to open a filename with invalid characters gives the right error-message. (same bug existed on UNIX too, which is now fixed) --- tests/fileSystem.test | 3 +++ unix/tclUnixChan.c | 5 +++++ 2 files changed, 8 insertions(+) diff --git a/tests/fileSystem.test b/tests/fileSystem.test index 161ebc3..c255b1e 100644 --- a/tests/fileSystem.test +++ b/tests/fileSystem.test @@ -708,6 +708,9 @@ test filesystem-6.32 {empty file name} { test filesystem-6.33 {empty file name} { list [catch {file writable ""} msg] $msg } {0 0} +test filesystem-6.34 {file name with (invalid) nul character} { + list [catch "open foo\x00" msg] $msg +} [list 1 "couldn't open \"foo\x00\": filename is invalid on this platform"] # Make sure the testfilesystem hasn't been registered. if {[testConstraint testfilesystem]} { diff --git a/unix/tclUnixChan.c b/unix/tclUnixChan.c index 1d60340..89c9a27 100644 --- a/unix/tclUnixChan.c +++ b/unix/tclUnixChan.c @@ -1647,6 +1647,11 @@ TclpOpenFileChannel( native = Tcl_FSGetNativePath(pathPtr); if (native == NULL) { + if (interp != (Tcl_Interp *) NULL) { + Tcl_AppendResult(interp, "couldn't open \"", + TclGetString(pathPtr), "\": filename is invalid on this platform", + NULL); + } return NULL; } -- cgit v0.12 From cb0895755d880bb33b11b98f341b588ae29c525a Mon Sep 17 00:00:00 2001 From: dgp Date: Mon, 3 Nov 2014 20:39:25 +0000 Subject: [5adc350683] Reworked the management of the EOF states to re-enable the ability to read beyond EOF. Plenty of assert()s to keep thing from going off track again. --- generic/tclIO.c | 182 +++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 139 insertions(+), 43 deletions(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index c55c118..b3af1f5 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -3977,6 +3977,21 @@ Tcl_GetsObj( } /* + * If we're sitting ready to read the eofchar, there's no need to + * do it. + */ + + if (GotFlag(statePtr, CHANNEL_STICKY_EOF)) { + SetFlag(statePtr, CHANNEL_EOF); + assert( statePtr->inputEncodingFlags & TCL_ENCODING_END ); + assert( !GotFlag(statePtr, CHANNEL_BLOCKED|INPUT_SAW_CR) ); + + /* TODO: Do we need this? */ + UpdateInterest(chanPtr); + return -1; + } + + /* * A binary version of Tcl_GetsObj. This could also handle encodings that * are ascii-7 pure (iso8859, utf-8, ...) with a final encoding conversion * done on objPtr. @@ -4194,6 +4209,7 @@ Tcl_GetsObj( dstEnd = eof; SetFlag(statePtr, CHANNEL_EOF | CHANNEL_STICKY_EOF); statePtr->inputEncodingFlags |= TCL_ENCODING_END; + ResetFlag(statePtr, CHANNEL_BLOCKED|INPUT_SAW_CR); } if (GotFlag(statePtr, CHANNEL_EOF)) { skip = 0; @@ -4307,6 +4323,13 @@ Tcl_GetsObj( */ done: + assert(!GotFlag(statePtr, CHANNEL_EOF) + || GotFlag(statePtr, CHANNEL_STICKY_EOF) + || Tcl_InputBuffered((Tcl_Channel)chanPtr) == 0); + + assert( !(GotFlag(statePtr, CHANNEL_EOF|CHANNEL_BLOCKED) + == (CHANNEL_EOF|CHANNEL_BLOCKED)) ); + /* * Regenerate the top channel, in case it was changed due to * self-modifying reflected transforms. @@ -4330,6 +4353,11 @@ Tcl_GetsObj( * end-of-line or end-of-file has been seen. Bytes read from the input * channel return as a ByteArray obj. * + * WARNING! The notion of "binary" used here is different from + * notions of "binary" used in other places. In particular, this + * "binary" routine may be called when an -eofchar is set on the + * channel. + * * Results: * Number of characters accumulated in the object or -1 if error, * blocked, or EOF. If -1, use Tcl_GetErrno() to retrieve the POSIX error @@ -4416,15 +4444,15 @@ TclGetsObjBinary( } } else { /* - * There's something already in the buffer. If - * CHANNEL_STICKY_EOF is set we know that something begins - * with the eofchar. Otherwise, if CHANNEL_EOF is set, we - * know some earlier inputproc call returned zero bytes when - * we were trying to get more bytes to put in the buffer. - * which means..... ???? Place to probe with tests. - */ - assert (GotFlag(statePtr, CHANNEL_STICKY_EOF) - || !GotFlag(statePtr, CHANNEL_EOF) ); + * Incoming CHANNEL_STICKY_EOF is filtered out on entry. + * A new CHANNEL_STICKY_EOF set in this routine leads to + * return before coming back here. When we are not dealing + * with CHANNEL_STICKY_EOF, a CHANNEL_EOF implies an + * empty buffer. Here the buffer is non-empty so we know + * we're a non-EOF */ + + assert ( !GotFlag(statePtr, CHANNEL_STICKY_EOF) ); + assert ( !GotFlag(statePtr, CHANNEL_EOF) ); } dst = (unsigned char *) RemovePoint(bufPtr); @@ -4466,6 +4494,7 @@ TclGetsObjBinary( SetFlag(statePtr, CHANNEL_EOF | CHANNEL_STICKY_EOF); statePtr->inputEncodingFlags |= TCL_ENCODING_END; + ResetFlag(statePtr, CHANNEL_BLOCKED|INPUT_SAW_CR); } if (GotFlag(statePtr, CHANNEL_EOF)) { skip = 0; @@ -4575,6 +4604,11 @@ TclGetsObjBinary( */ done: + assert(!GotFlag(statePtr, CHANNEL_EOF) + || GotFlag(statePtr, CHANNEL_STICKY_EOF) + || Tcl_InputBuffered((Tcl_Channel)chanPtr) == 0); + assert( !(GotFlag(statePtr, CHANNEL_EOF|CHANNEL_BLOCKED) + == (CHANNEL_EOF|CHANNEL_BLOCKED)) ); UpdateInterest(chanPtr); TclChannelRelease((Tcl_Channel)chanPtr); return copiedTotal; @@ -4706,8 +4740,16 @@ FilterInputBytes( return -1; } } else { - assert( GotFlag(statePtr, CHANNEL_STICKY_EOF) - || !GotFlag(statePtr, CHANNEL_EOF) ); + /* + * Incoming CHANNEL_STICKY_EOF is filtered out on entry. + * A new CHANNEL_STICKY_EOF set in this routine leads to + * return before coming back here. When we are not dealing + * with CHANNEL_STICKY_EOF, a CHANNEL_EOF implies an + * empty buffer. Here the buffer is non-empty so we know + * we're a non-EOF */ + + assert ( !GotFlag(statePtr, CHANNEL_STICKY_EOF) ); + assert ( !GotFlag(statePtr, CHANNEL_EOF) ); } /* @@ -5201,19 +5243,11 @@ DoReadChars( ChannelState *statePtr = chanPtr->state; /* State info for channel */ ChannelBuffer *bufPtr; - int factor, copied, copiedNow, result; - Tcl_Encoding encoding; + int copied, copiedNow, result; + Tcl_Encoding encoding = statePtr->encoding; int binaryMode; #define UTF_EXPANSION_FACTOR 1024 - - /* - * This operation should occur at the top of a channel stack. - */ - - chanPtr = statePtr->topChanPtr; - encoding = statePtr->encoding; - factor = UTF_EXPANSION_FACTOR; - TclChannelPreserve((Tcl_Channel)chanPtr); + int factor = UTF_EXPANSION_FACTOR; binaryMode = (encoding == NULL) && (statePtr->inputTranslation == TCL_TRANSLATE_LF) @@ -5237,6 +5271,36 @@ DoReadChars( } } + /* + * Early out when next read will see eofchar. + * + * NOTE: See DoRead for argument that it's a bug (one we're keeping) + * to have this escape before the one for zero-char read request. + */ + + if (GotFlag(statePtr, CHANNEL_STICKY_EOF)) { + SetFlag(statePtr, CHANNEL_EOF); + assert( statePtr->inputEncodingFlags & TCL_ENCODING_END ); + assert( !GotFlag(statePtr, CHANNEL_BLOCKED|INPUT_SAW_CR) ); + + UpdateInterest(chanPtr); + return 0; + } + + /* Special handling for zero-char read request. */ + if (toRead == 0) { + ResetFlag(statePtr, CHANNEL_BLOCKED|CHANNEL_EOF); + UpdateInterest(chanPtr); + return 0; + } + + /* + * This operation should occur at the top of a channel stack. + */ + + chanPtr = statePtr->topChanPtr; + TclChannelPreserve((Tcl_Channel)chanPtr); + /* Must clear the BLOCKED flag here since we check before reading */ ResetFlag(statePtr, CHANNEL_BLOCKED|CHANNEL_EOF); for (copied = 0; (unsigned) toRead > 0; ) { @@ -5314,6 +5378,11 @@ DoReadChars( * Update the notifier state so we don't block while there is still data * in the buffers. */ + assert(!GotFlag(statePtr, CHANNEL_EOF) + || GotFlag(statePtr, CHANNEL_STICKY_EOF) + || Tcl_InputBuffered((Tcl_Channel)chanPtr) == 0); + assert( !(GotFlag(statePtr, CHANNEL_EOF|CHANNEL_BLOCKED) + == (CHANNEL_EOF|CHANNEL_BLOCKED)) ); UpdateInterest(chanPtr); TclChannelRelease((Tcl_Channel)chanPtr); return copied; @@ -5922,7 +5991,7 @@ TranslateInputEOL( SetFlag(statePtr, CHANNEL_EOF | CHANNEL_STICKY_EOF); statePtr->inputEncodingFlags |= TCL_ENCODING_END; - ResetFlag(statePtr, INPUT_SAW_CR); + ResetFlag(statePtr, CHANNEL_BLOCKED|INPUT_SAW_CR); } } @@ -6132,6 +6201,14 @@ GetInput( ChannelState *statePtr = chanPtr->state; /* State info for channel */ + /* + * Verify that all callers know better than to call us when + * it's recorded that the next char waiting to be read is the + * eofchar. + */ + + assert( !GotFlag(statePtr, CHANNEL_STICKY_EOF) ); + /* * Prevent reading from a dead channel -- a channel that has been closed * but not yet deallocated, which can happen if the exit handler for @@ -6143,21 +6220,6 @@ GetInput( return EINVAL; } - /* - * Strangely named "STICKY_EOF" really means we've seen the - * eofchar for this channel, and nothing since has reset it. - * (changed the eofchar, [seek]ed to a new offset, etc.) So, - * we know we're still poised to read that eofchar again, and - * there's no need to actually do it. - */ - - if (GotFlag(statePtr, CHANNEL_STICKY_EOF)) { - assert(statePtr->inEofChar); - assert(statePtr->inQueueHead); - assert(RemovePoint(statePtr->inQueueHead)[0] == statePtr->inEofChar); - return 0; - } - /* * WARNING: There was once a comment here claiming that it was * a bad idea to make another call to the inputproc of a channel @@ -6185,6 +6247,7 @@ GetInput( if (chanPtr->inQueueHead != NULL) { + /* TODO: Tests to cover this. */ assert(statePtr->inQueueHead == NULL); statePtr->inQueueHead = chanPtr->inQueueHead; @@ -6215,6 +6278,7 @@ GetInput( * Check the actual buffersize against the requested buffersize. * Saved buffers of the wrong size are squashed. This is done * to honor dynamic changes of the buffersize made by the user. + * TODO: Tests to cover this. */ if ((bufPtr != NULL) @@ -6758,9 +6822,7 @@ Tcl_Eof( ChannelState *statePtr = ((Channel *) chan)->state; /* State of real channel structure. */ - return (GotFlag(statePtr, CHANNEL_STICKY_EOF) || - (GotFlag(statePtr, CHANNEL_EOF) && - (Tcl_InputBuffered(chan) == 0))) ? 1 : 0; + return GotFlag(statePtr, CHANNEL_EOF) ? 1 : 0; } /* @@ -8882,6 +8944,36 @@ DoRead( ChannelState *statePtr = chanPtr->state; char *p = dst; + assert (bytesToRead >= 0); + + /* + * Early out when we know a read will get the eofchar. + * + * NOTE: This seems to be a bug. The special handling for + * a zero-char read request ought to come first. As coded + * the EOF due to eofchar has distinguishing behavior from + * the EOF due to reported EOF on the underlying device, and + * that seems undesirable. However recent history indicates + * that new inconsistent behavior in a patchlevel has problems + * too. Keep on keeping on for now. + */ + + if (GotFlag(statePtr, CHANNEL_STICKY_EOF)) { + SetFlag(statePtr, CHANNEL_EOF); + assert( statePtr->inputEncodingFlags & TCL_ENCODING_END ); + assert( !GotFlag(statePtr, CHANNEL_BLOCKED|INPUT_SAW_CR) ); + + UpdateInterest(chanPtr); + return 0; + } + + /* Special handling for zero-char read request. */ + if (bytesToRead == 0) { + ResetFlag(statePtr, CHANNEL_BLOCKED|CHANNEL_EOF); + UpdateInterest(chanPtr); + return 0; + } + TclChannelPreserve((Tcl_Channel)chanPtr); while (bytesToRead) { /* @@ -8952,8 +9044,7 @@ DoRead( * 1) We're @EOF because we saw eof char. */ - if (statePtr->inEofChar - && RemovePoint(bufPtr)[0] == statePtr->inEofChar) { + if (GotFlag(statePtr, CHANNEL_STICKY_EOF)) { UpdateInterest(chanPtr); break; } @@ -9026,6 +9117,11 @@ DoRead( ResetFlag(statePtr, CHANNEL_BLOCKED); } + assert(!GotFlag(statePtr, CHANNEL_EOF) + || GotFlag(statePtr, CHANNEL_STICKY_EOF) + || Tcl_InputBuffered((Tcl_Channel)chanPtr) == 0); + assert( !(GotFlag(statePtr, CHANNEL_EOF|CHANNEL_BLOCKED) + == (CHANNEL_EOF|CHANNEL_BLOCKED)) ); TclChannelRelease((Tcl_Channel)chanPtr); return (int)(p - dst); } -- cgit v0.12 From 3fa4ffc77a8b49b2bc6803bdeaf2a79227c83800 Mon Sep 17 00:00:00 2001 From: dgp Date: Mon, 3 Nov 2014 21:37:37 +0000 Subject: Make sure reflected channels do not make a double call to Tcl_ReadRaw(), with the unwarranted assumption that EOF is a permanent condition. --- generic/tclIORTrans.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/generic/tclIORTrans.c b/generic/tclIORTrans.c index 45ee08d..8f3ef3c 100644 --- a/generic/tclIORTrans.c +++ b/generic/tclIORTrans.c @@ -1097,6 +1097,11 @@ ReflectInput( goto stop; } + if (rtPtr->readIsDrained) { + goto stop; + } + + /* * The buffer is exhausted, but the caller wants even more. We now * have to go to the underlying channel, get more bytes and then @@ -1166,10 +1171,6 @@ ReflectInput( * on the down channel. */ - if (rtPtr->readIsDrained) { - goto stop; - } - /* * Now this is a bit different. The partial data waiting is * converted and returned. -- cgit v0.12 From 71d27bd9c608100eb261b8ce58a86963aa871a68 Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 5 Nov 2014 06:36:07 +0000 Subject: [214cc0eb22] Restore [lappend $var] return value to the 8.6.1- behavior. If this is going to change, lets not do it by accident. --- generic/tclCompCmdsGR.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generic/tclCompCmdsGR.c b/generic/tclCompCmdsGR.c index 9d258fc..98407f7 100644 --- a/generic/tclCompCmdsGR.c +++ b/generic/tclCompCmdsGR.c @@ -871,7 +871,7 @@ TclCompileLappendCmd( /* TODO: Consider support for compiling expanded args. */ numWords = parsePtr->numWords; - if (numWords == 1) { + if (numWords < 3) { return TCL_ERROR; } -- cgit v0.12 From 57de194b09b9615d3d63aa26469a3681fce1ab23 Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 5 Nov 2014 16:47:00 +0000 Subject: New test iortrans-4.10 to demo failure of channel transformation to handle fleeting EOF in the base channel. Falls into infinite block. Regression compared with Tcl 8.6.1. --- tests/ioTrans.test | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/tests/ioTrans.test b/tests/ioTrans.test index 53078f7..f1fa733 100644 --- a/tests/ioTrans.test +++ b/tests/ioTrans.test @@ -597,6 +597,62 @@ test iortrans-4.9 {chan read, gets, bug 2921116} -setup { rename foo {} } -result {{read rt* {test data }} {}} +test iortrans-4.10 {[5adbc350683] chan read, handle fleeting EOF} -setup { + proc driver {cmd args} { + variable buffer + variable index + set chan [lindex $args 0] + switch -- $cmd { + initialize { + set index($chan) 0 + set buffer($chan) ..... + return {initialize finalize watch read} + } + finalize { + if {![info exists index($chan)]} {return} + unset index($chan) buffer($chan) + return + } + watch {} + read { + set n [lindex $args 1] + if {![info exists index($chan)]} { + driver initialize $chan + } + set new [expr {$index($chan) + $n}] + set result [string range $buffer($chan) $index($chan) $new-1] + set index($chan) $new + if {[string length $result] == 0} { + driver finalize $chan + } + return $result + } + } + } + proc idxform {cmd handle args} { + switch -- $cmd { + initialize { + return {initialize finalize read} + } + finalize { + return + } + read { + lassign $args buffer + return $buffer + } + } + } +} -body { + set chan [chan push [chan create read driver] idxform] + list [eof $chan] [read $chan] [eof $chan] [read $chan 0] [eof $chan] \ + [read $chan] [eof $chan] +} -cleanup { + close $chan + rename idxform {} + rename driver {} +} -result {0 ..... 1 {} 0 ..... 1} + # --- === *** ########################### # method write (via puts) -- cgit v0.12 From 53ae61158324ab9af6102e58c1e86e88cf852891 Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 5 Nov 2014 20:34:03 +0000 Subject: Reflected Transform channel fix. Be sure each EOF on the base channel gets passed up to become an eof of the transform before continuing on to additional ReadRaw() from the base channel. This way we don't miss fleeting EOFs. --- generic/tclIORTrans.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/generic/tclIORTrans.c b/generic/tclIORTrans.c index 8f3ef3c..8baa9ad 100644 --- a/generic/tclIORTrans.c +++ b/generic/tclIORTrans.c @@ -161,6 +161,7 @@ typedef struct { int mode; /* Mask of R/W mode */ int nonblocking; /* Flag: Channel is blocking or not. */ int readIsDrained; /* Flag: Read buffers are flushed. */ + int eofPending; /* Flag: EOF seen down, but not raised up */ int dead; /* Boolean signal that some operations * should no longer be attempted. */ ResultBuffer result; @@ -1082,6 +1083,10 @@ ReflectInput( bufObj = Tcl_NewByteArrayObj(NULL, toRead); Tcl_IncrRefCount(bufObj); gotBytes = 0; + if (rtPtr->eofPending) { + goto stop; + } + rtPtr->readIsDrained = 0; while (toRead > 0) { /* * Loop until the request is satisfied (or no data available from @@ -1097,9 +1102,9 @@ ReflectInput( goto stop; } - if (rtPtr->readIsDrained) { - goto stop; - } + if (rtPtr->eofPending) { + goto stop; + } /* @@ -1170,6 +1175,8 @@ ReflectInput( * Zero returned from Tcl_ReadRaw() always indicates EOF * on the down channel. */ + + rtPtr->eofPending = 1; /* * Now this is a bit different. The partial data waiting is @@ -1212,6 +1219,9 @@ ReflectInput( } /* while toRead > 0 */ stop: + if (gotBytes == 0) { + rtPtr->eofPending = 0; + } Tcl_DecrRefCount(bufObj); Tcl_Release(rtPtr); return gotBytes; @@ -1767,6 +1777,7 @@ NewReflectedTransform( rtPtr->timer = NULL; rtPtr->mode = 0; rtPtr->readIsDrained = 0; + rtPtr->eofPending = 0; rtPtr->nonblocking = (((Channel *) parentChan)->state->flags & CHANNEL_NONBLOCKING); rtPtr->dead = 0; @@ -3319,6 +3330,7 @@ TransformClear( (void) InvokeTclMethod(rtPtr, "clear", NULL, NULL, NULL); rtPtr->readIsDrained = 0; + rtPtr->eofPending = 0; ResultClear(&rtPtr->result); } -- cgit v0.12 From dac552ac0bac0ce5b0b8805adc5d4ef7403ad4d1 Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 6 Nov 2014 13:38:01 +0000 Subject: New tests iortrans-4.11* demonstrate what was wrong with the "leaky EOF flag" approach in 8.6.1 and earlier. If each level of the channel stack is to have control over its EOF independently, we have to provide for that, even though the Filesystem read APIs make it a big pain. Also test robustness against varing buffer sizes. --- tests/ioTrans.test | 89 +++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 85 insertions(+), 4 deletions(-) diff --git a/tests/ioTrans.test b/tests/ioTrans.test index f1fa733..faae9d8 100644 --- a/tests/ioTrans.test +++ b/tests/ioTrans.test @@ -597,7 +597,9 @@ test iortrans-4.9 {chan read, gets, bug 2921116} -setup { rename foo {} } -result {{read rt* {test data }} {}} -test iortrans-4.10 {[5adbc350683] chan read, handle fleeting EOF} -setup { + +# Driver for a base channel that emits several short "files" +# with each terminated by a fleeting EOF proc driver {cmd args} { variable buffer variable index @@ -629,6 +631,8 @@ test iortrans-4.10 {[5adbc350683] chan read, handle fleeting EOF} -setup { } } } + +# Channel read transform that is just the identity - pass all through proc idxform {cmd handle args} { switch -- $cmd { initialize { @@ -643,15 +647,92 @@ test iortrans-4.10 {[5adbc350683] chan read, handle fleeting EOF} -setup { } } } -} -body { + +# Test that all EOFs pass through full xform stack. Proper data boundaries. +# Check robustness against buffer sizes. +test iortrans-4.10 {[5adbc350683] chan read, handle fleeting EOF} -body { set chan [chan push [chan create read driver] idxform] list [eof $chan] [read $chan] [eof $chan] [read $chan 0] [eof $chan] \ [read $chan] [eof $chan] } -cleanup { close $chan - rename idxform {} - rename driver {} } -result {0 ..... 1 {} 0 ..... 1} +test iortrans-4.10.1 {[5adbc350683] chan read, handle fleeting EOF} -body { + set chan [chan push [chan create read driver] idxform] + chan configure $chan -buffersize 3 + list [eof $chan] [read $chan] [eof $chan] [read $chan 0] [eof $chan] \ + [read $chan] [eof $chan] +} -cleanup { + close $chan +} -result {0 ..... 1 {} 0 ..... 1} +test iortrans-4.10.2 {[5adbc350683] chan read, handle fleeting EOF} -body { + set chan [chan push [chan create read driver] idxform] + chan configure $chan -buffersize 5 + list [eof $chan] [read $chan] [eof $chan] [read $chan 0] [eof $chan] \ + [read $chan] [eof $chan] +} -cleanup { + close $chan +} -result {0 ..... 1 {} 0 ..... 1} + +rename idxform {} + +# Channel read transform that delays the data + proc delayxform {cmd handle args} { + variable store + switch -- $cmd { + initialize { + set store($handle) {} + return {initialize finalize read drain} + } + finalize { + unset store($handle) + return + } + read { + lassign $args buffer + if {$store($handle) eq {}} { + set reply [string index $buffer 0] + set store($handle) [string range $buffer 1 end] + } else { + set reply $store($handle) + set store($handle) $buffer + } + return $reply + } + drain { + delayxform read $handle {} + } + } + } + +# Test that all EOFs pass through full xform stack. Proper data boundaries. +# Check robustness against buffer sizes. +test iortrans-4.11 {[5adbc350683] chan read, handle fleeting EOF} -body { + set chan [chan push [chan create read driver] delayxform] + list [eof $chan] [read $chan] [eof $chan] [read $chan 0] [eof $chan] \ + [read $chan] [eof $chan] +} -cleanup { + close $chan +} -result {0 ..... 1 {} 0 ..... 1} +test iortrans-4.11.1 {[5adbc350683] chan read, handle fleeting EOF} -body { + set chan [chan push [chan create read driver] delayxform] + chan configure $chan -buffersize 3 + list [eof $chan] [read $chan] [eof $chan] [read $chan 0] [eof $chan] \ + [read $chan] [eof $chan] +} -cleanup { + close $chan +} -result {0 ..... 1 {} 0 ..... 1} +test iortrans-4.11.2 {[5adbc350683] chan read, handle fleeting EOF} -body { + set chan [chan push [chan create read driver] delayxform] + chan configure $chan -buffersize 5 + list [eof $chan] [read $chan] [eof $chan] [read $chan 0] [eof $chan] \ + [read $chan] [eof $chan] +} -cleanup { + close $chan +} -result {0 ..... 1 {} 0 ..... 1} + + rename delayxform {} + rename driver {} # --- === *** ########################### -- cgit v0.12 From 2f8dae1cec98e8c0664280a413a5c0773051a389 Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 6 Nov 2014 14:52:36 +0000 Subject: Another test checking that handling when transform returns nothing is right. --- tests/ioTrans.test | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/tests/ioTrans.test b/tests/ioTrans.test index faae9d8..aa2fbc7 100644 --- a/tests/ioTrans.test +++ b/tests/ioTrans.test @@ -676,7 +676,7 @@ test iortrans-4.10.2 {[5adbc350683] chan read, handle fleeting EOF} -body { rename idxform {} -# Channel read transform that delays the data +# Channel read transform that delays the data and always returns something proc delayxform {cmd handle args} { variable store switch -- $cmd { @@ -732,6 +732,40 @@ test iortrans-4.11.2 {[5adbc350683] chan read, handle fleeting EOF} -body { } -result {0 ..... 1 {} 0 ..... 1} rename delayxform {} + +# Channel read transform that delays the data and may return {} + proc delay2xform {cmd handle args} { + variable store + switch -- $cmd { + initialize { + set store($handle) {} + return {initialize finalize read drain} + } + finalize { + unset store($handle) + return + } + read { + lassign $args buffer + set reply $store($handle) + set store($handle) $buffer + return $reply + } + drain { + delay2xform read $handle {} + } + } + } + +test iortrans-4.12 {[5adbc350683] chan read, handle fleeting EOF} -body { + set chan [chan push [chan create read driver] delay2xform] + list [eof $chan] [read $chan] [eof $chan] [read $chan 0] [eof $chan] \ + [read $chan] [eof $chan] +} -cleanup { + close $chan +} -result {0 ..... 1 {} 0 ..... 1} + + rename delay2xform {} rename driver {} -- cgit v0.12 From 5c6717b7d59cd081a7e24a588756c9c14aa4c555 Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 6 Nov 2014 15:06:52 +0000 Subject: New test iogt-7.0 demos bug in [testchannel transform]. --- tests/iogt.test | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/tests/iogt.test b/tests/iogt.test index 5fe3dc2..1a18afc 100644 --- a/tests/iogt.test +++ b/tests/iogt.test @@ -996,6 +996,48 @@ test iogt-6.1 {Push back and up} {testchannel knownBug} { set res } {xxxghi} +# Driver for a base channel that emits several short "files" +# with each terminated by a fleeting EOF + proc driver {cmd args} { + variable buffer + variable index + set chan [lindex $args 0] + switch -- $cmd { + initialize { + set index($chan) 0 + set buffer($chan) ..... + return {initialize finalize watch read} + } + finalize { + if {![info exists index($chan)]} {return} + unset index($chan) buffer($chan) + return + } + watch {} + read { + set n [lindex $args 1] + if {![info exists index($chan)]} { + driver initialize $chan + } + set new [expr {$index($chan) + $n}] + set result [string range $buffer($chan) $index($chan) $new-1] + set index($chan) $new + if {[string length $result] == 0} { + driver finalize $chan + } + return $result + } + } + } + +test iogt-7.0 {Handle fleeting EOF} -constraints {testchannel} -body { + set chan [chan create read [namespace which driver]] + identity -attach $chan + list [eof $chan] [read $chan] [eof $chan] [read $chan 0] [eof $chan] \ + [read $chan] [eof $chan] +} -cleanup { + close $chan +} -result {0 ..... 1 {} 0 ..... 1} # cleanup foreach file [list dummy dummyout __echo_srv__.tcl] { -- cgit v0.12 From 60ef43cb8cfe3c26e4e48d6af300ef5011ac44f9 Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 6 Nov 2014 15:49:30 +0000 Subject: fix failing test --- generic/tclIOGT.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/generic/tclIOGT.c b/generic/tclIOGT.c index a78a5b4..7ba2f2a 100644 --- a/generic/tclIOGT.c +++ b/generic/tclIOGT.c @@ -187,6 +187,7 @@ struct TransformChannelData { Tcl_Channel self; /* Our own Channel handle. */ int readIsFlushed; /* Flag to note whether in.flushProc was * called or not. */ + int eofPending; /* Flag: EOF seen down, not raised up */ int flags; /* Currently CHANNEL_ASYNC or zero. */ int watchMask; /* Current watch/event/interest mask. */ int mode; /* Mode of parent channel, OR'ed combination @@ -292,6 +293,7 @@ TclChannelTransform( Tcl_DStringInit(&ds); Tcl_GetChannelOption(interp, chan, "-blocking", &ds); dataPtr->readIsFlushed = 0; + dataPtr->eofPending = 0; dataPtr->flags = 0; if (ds.string[0] == '0') { dataPtr->flags |= CHANNEL_ASYNC; @@ -624,7 +626,7 @@ TransformInputProc( if (toRead == 0 || dataPtr->self == NULL) { /* - * Catch a no-op. + * Catch a no-op. TODO: Is this a panic()? */ return 0; } @@ -676,8 +678,7 @@ TransformInputProc( if (toRead <= 0) { break; } - - if (dataPtr->readIsFlushed) { + if (dataPtr->eofPending) { /* * Already saw EOF from downChan; don't ask again. * NOTE: Could move this up to avoid the last maxRead @@ -724,6 +725,7 @@ TransformInputProc( * on the down channel. */ + dataPtr->eofPending = 1; dataPtr->readIsFlushed = 1; ExecuteCallback(dataPtr, NULL, A_FLUSH_READ, NULL, 0, TRANSMIT_IBUF, P_PRESERVE); @@ -751,8 +753,11 @@ TransformInputProc( break; } } /* while toRead > 0 */ - ReleaseData(dataPtr); + if (gotBytes == 0) { + dataPtr->eofPending = 0; + } + ReleaseData(dataPtr); return gotBytes; } @@ -863,6 +868,7 @@ TransformSeekProc( P_NO_PRESERVE); ResultClear(&dataPtr->result); dataPtr->readIsFlushed = 0; + dataPtr->eofPending = 0; } ReleaseData(dataPtr); @@ -936,6 +942,7 @@ TransformWideSeekProc( P_NO_PRESERVE); ResultClear(&dataPtr->result); dataPtr->readIsFlushed = 0; + dataPtr->eofPending = 0; } ReleaseData(dataPtr); -- cgit v0.12 From 559b8ab9de85a070d0dc00c5a8fb397c9baa7d6c Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 6 Nov 2014 16:12:26 +0000 Subject: Also test transfroms that delay. --- tests/iogt.test | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/tests/iogt.test b/tests/iogt.test index 1a18afc..89e62d4 100644 --- a/tests/iogt.test +++ b/tests/iogt.test @@ -1039,6 +1039,36 @@ test iogt-7.0 {Handle fleeting EOF} -constraints {testchannel} -body { close $chan } -result {0 ..... 1 {} 0 ..... 1} +proc delay {op data} { + variable store + switch -- $op { + create/write - create/read - + delete/write - delete/read - + flush/write - write - + clear_read {;#ignore} + flush/read - + read { + if {![info exists store]} {set store {}} + set reply $store + set store $data + return $reply + } + query/maxRead {return -1} + } +} + +test iogt-7.1 {Handle fleeting EOF} -constraints {testchannel} -body { + set chan [chan create read [namespace which driver]] + testchannel transform $chan -command [namespace code delay] + list [eof $chan] [read $chan] [eof $chan] [read $chan 0] [eof $chan] \ + [read $chan] [eof $chan] +} -cleanup { + close $chan +} -result {0 ..... 1 {} 0 ..... 1} + +rename delay {} +rename driver {} + # cleanup foreach file [list dummy dummyout __echo_srv__.tcl] { removeFile $file -- cgit v0.12 From 0c027bb7066b06799c1eb4b062985bf37facc302 Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 6 Nov 2014 17:34:40 +0000 Subject: cleanup global namespace litter --- tests/ioTrans.test | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/ioTrans.test b/tests/ioTrans.test index aa2fbc7..f82c610 100644 --- a/tests/ioTrans.test +++ b/tests/ioTrans.test @@ -613,6 +613,8 @@ test iortrans-4.9 {chan read, gets, bug 2921116} -setup { finalize { if {![info exists index($chan)]} {return} unset index($chan) buffer($chan) + array unset index + array unset buffer return } watch {} -- cgit v0.12 From 7565b9ff1e4da5e96bea024326dba1b3d405d7fb Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 7 Nov 2014 13:59:27 +0000 Subject: Make sure all uses of the [testbytestring] command are constrained. --- tests/parse.test | 6 ++++-- tests/parseOld.test | 12 ++++++------ tests/subst.test | 4 ++-- tests/utf.test | 40 ++++++++++++++++++++-------------------- 4 files changed, 32 insertions(+), 30 deletions(-) diff --git a/tests/parse.test b/tests/parse.test index fe6026d..4e3139c 100644 --- a/tests/parse.test +++ b/tests/parse.test @@ -303,8 +303,10 @@ test parse-6.16 {ParseTokens procedure, backslash substitution} testparser { testparser {\n\a\x7f} 0 } {- {\n\a\x7f} 1 word {\n\a\x7f} 3 backslash {\n} 0 backslash {\a} 0 backslash {\x7f} 0 {}} test parse-6.17 {ParseTokens procedure, null characters} {testparser testbytestring} { - testparser [testbytestring "foo\0zz"] 0 -} "- [testbytestring foo\0zz] 1 word [testbytestring foo\0zz] 3 text foo 0 text [testbytestring \0] 0 text zz 0 {}" + expr {[testparser [testbytestring "foo\0zz"] 0] eq +"- [testbytestring foo\0zz] 1 word [testbytestring foo\0zz] 3 text foo 0 text [testbytestring \0] 0 text zz 0 {}" + } +} 1 test parse-6.18 {ParseTokens procedure, seek past numBytes for close-bracket} testparser { # Test for Bug 681841 list [catch {testparser {[a]} 2} msg] $msg diff --git a/tests/parseOld.test b/tests/parseOld.test index 4c08b5d..a6e07a2b 100644 --- a/tests/parseOld.test +++ b/tests/parseOld.test @@ -263,14 +263,14 @@ test parseOld-7.11 {backslash substitution} { eval "list a \"b c\"\\\nd e" } {a {b c} d e} test parseOld-7.12 {backslash substitution} testbytestring { - list \ua2 -} [testbytestring "\xc2\xa2"] + expr {[list \ua2] eq [testbytestring "\xc2\xa2"]} +} 1 test parseOld-7.13 {backslash substitution} testbytestring { - list \u4e21 -} [testbytestring "\xe4\xb8\xa1"] + expr {[list \u4e21] eq [testbytestring "\xe4\xb8\xa1"]} +} 1 test parseOld-7.14 {backslash substitution} testbytestring { - list \u4e2k -} [testbytestring "\xd3\xa2k"] + expr {[list \u4e2k] eq [testbytestring "\xd3\xa2k"]} +} 1 # Semi-colon. diff --git a/tests/subst.test b/tests/subst.test index 256b7f7..2115772 100644 --- a/tests/subst.test +++ b/tests/subst.test @@ -38,8 +38,8 @@ test subst-2.3 {simple strings} { } abcdefg test subst-2.4 {simple strings} testbytestring { # Tcl Bug 685106 - subst [testbytestring bar\x00soom] -} [testbytestring bar\x00soom] + expr {[subst [testbytestring bar\x00soom]] eq [testbytestring bar\x00soom]} +} 1 test subst-3.1 {backslash substitutions} { subst {\x\$x\[foo bar]\\} diff --git a/tests/utf.test b/tests/utf.test index 83daddf..ceb1af7 100644 --- a/tests/utf.test +++ b/tests/utf.test @@ -21,23 +21,23 @@ testConstraint testbytestring [llength [info commands testbytestring]] catch {unset x} test utf-1.1 {Tcl_UniCharToUtf: 1 byte sequences} testbytestring { - set x \x01 -} [testbytestring "\x01"] + expr {"\x01" eq [testbytestring "\x01"]} +} 1 test utf-1.2 {Tcl_UniCharToUtf: 2 byte sequences} testbytestring { - set x "\x00" -} [testbytestring "\xc0\x80"] + expr {"\x00" eq [testbytestring "\xc0\x80"]} +} 1 test utf-1.3 {Tcl_UniCharToUtf: 2 byte sequences} testbytestring { - set x "\xe0" -} [testbytestring "\xc3\xa0"] + expr {"\xe0" eq [testbytestring "\xc3\xa0"]} +} 1 test utf-1.4 {Tcl_UniCharToUtf: 3 byte sequences} testbytestring { - set x "\u4e4e" -} [testbytestring "\xe4\xb9\x8e"] + expr {"\u4e4e" eq [testbytestring "\xe4\xb9\x8e"]} +} 1 test utf-1.5 {Tcl_UniCharToUtf: overflowed Tcl_UniChar} testbytestring { - format %c 0x110000 -} [testbytestring "\xef\xbf\xbd"] + expr {[format %c 0x110000] eq [testbytestring "\xef\xbf\xbd"]} +} 1 test utf-1.6 {Tcl_UniCharToUtf: negative Tcl_UniChar} testbytestring { - format %c -1 -} [testbytestring "\xef\xbf\xbd"] + expr {[format %c -1] eq [testbytestring "\xef\xbf\xbd"]} +} 1 test utf-2.1 {Tcl_UtfToUniChar: low ascii} { string length "abc" @@ -128,17 +128,17 @@ test utf-10.1 {Tcl_UtfBackslash: dst == NULL} { } { } test utf-10.2 {Tcl_UtfBackslash: \u subst} testbytestring { - set x \ua2 -} [testbytestring "\xc2\xa2"] + expr {"\ua2" eq [testbytestring "\xc2\xa2"]} +} 1 test utf-10.3 {Tcl_UtfBackslash: longer \u subst} testbytestring { - set x \u4e21 -} [testbytestring "\xe4\xb8\xa1"] + expr {"\u4e21" eq [testbytestring "\xe4\xb8\xa1"]} +} 1 test utf-10.4 {Tcl_UtfBackslash: stops at first non-hex} testbytestring { - set x \u4e2k -} "[testbytestring \xd3\xa2]k" + expr {"\u4e2k" eq "[testbytestring \xd3\xa2]k"} +} 1 test utf-10.5 {Tcl_UtfBackslash: stops after 4 hex chars} testbytestring { - set x \u4e216 -} "[testbytestring \xe4\xb8\xa1]6" + expr {"\u4e216" eq "[testbytestring \xe4\xb8\xa1]6"} +} 1 proc bsCheck {char num} { global errNum test utf-10.$errNum {backslash substitution} { -- cgit v0.12 From 5e0d1d6bc5f6e86208345eec906f21df57e5f410 Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 7 Nov 2014 14:10:23 +0000 Subject: update changes; more test suite polishing. --- changes | 10 +++++++++- tests/parse.test | 2 +- tests/socket.test | 2 +- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/changes b/changes index 03184e4..945b167 100644 --- a/changes +++ b/changes @@ -8482,4 +8482,12 @@ include ::oo::class (fellows) 2014-10-18 (bug)[10dc6d] fix [gets] on non-blocking channels (fassel,porter) ---- Released 8.6.3, October 29, 2014 --- http://core.tcl.tk/tcl/ for details +2014-10-26 Support for Windows 10 (nijtmans) + +2014-10-31 (bug)[dcc034] restore [open comX: r+] (lll,nijtmans) + +2014-11-05 (bug)[214cc0] Restore [lappend v] return value (sayers,porter) + +2014-11-06 (bug)[5adc35] Stop forcing EOF to be permanent (porter) + +--- Released 8.6.3, November 12, 2014 --- http://core.tcl.tk/tcl/ for details diff --git a/tests/parse.test b/tests/parse.test index 4e3139c..5d8afeb 100644 --- a/tests/parse.test +++ b/tests/parse.test @@ -918,7 +918,7 @@ test parse-15.57 {CommandComplete procedure} { test parse-15.58 {CommandComplete procedure, memory leaks} { info complete "1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22" } 1 -test parse-15.59 {CommandComplete procedure} { +test parse-15.59 {CommandComplete procedure} testbytestring { # Test for Tcl Bug 684744 info complete [testbytestring "\x00;if 1 \{"] } 0 diff --git a/tests/socket.test b/tests/socket.test index d6cee30..eeea044 100644 --- a/tests/socket.test +++ b/tests/socket.test @@ -2249,7 +2249,7 @@ test socket-14.11.0 {pending [socket -async] and nonblocking [puts], no listener unset x } -result {socket is not connected} -returnCodes 1 test socket-14.11.1 {pending [socket -async] and nonblocking [puts], no listener, flush} \ - -constraints {socket} \ + -constraints {socket nonportable} \ -body { set sock [socket -async localhost [randport]] fconfigure $sock -blocking 0 -- cgit v0.12 From eb64ed3cf0f46df62592a5b842c87deec3e8b399 Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 7 Nov 2014 17:48:31 +0000 Subject: Correct -singleproc 1 testing flaws. --- tests/interp.test | 4 ++-- tests/ioTrans.test | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/interp.test b/tests/interp.test index ad99fac..4bc9fe2 100644 --- a/tests/interp.test +++ b/tests/interp.test @@ -3615,10 +3615,10 @@ test interp-38.3 {interp debug wrong args} -body { } -returnCodes { error } -result {wrong # args: should be "interp debug path ?-frame ?bool??"} -test interp-38.4 {interp debug basic setup} -body { +test interp-38.4 {interp debug basic setup} -constraints {!singleTestInterp} -body { interp debug {} } -result {-frame 0} -test interp-38.5 {interp debug basic setup} -body { +test interp-38.5 {interp debug basic setup} -constraints {!singleTestInterp} -body { interp debug {} -f } -result {0} test interp-38.6 {interp debug basic setup} -body { diff --git a/tests/ioTrans.test b/tests/ioTrans.test index f82c610..e179eab 100644 --- a/tests/ioTrans.test +++ b/tests/ioTrans.test @@ -601,8 +601,8 @@ test iortrans-4.9 {chan read, gets, bug 2921116} -setup { # Driver for a base channel that emits several short "files" # with each terminated by a fleeting EOF proc driver {cmd args} { - variable buffer - variable index + variable ::tcl::buffer + variable ::tcl::index set chan [lindex $args 0] switch -- $cmd { initialize { -- cgit v0.12 From 98e4ac55d27f9cac4ef9dd91410384418319fb71 Mon Sep 17 00:00:00 2001 From: dkf Date: Sat, 8 Nov 2014 07:06:52 +0000 Subject: [214cc0eb22] Add tests to make sure that this bug stays fixed. --- tests/append.test | 17 +++++++++++++++++ tests/appendComp.test | 21 +++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/tests/append.test b/tests/append.test index 69c6381..8fa4e61 100644 --- a/tests/append.test +++ b/tests/append.test @@ -292,6 +292,23 @@ test append-9.3 {bug 3057639, append direct eval, read trace on non-existing env } -cleanup { unset -nocomplain ::env(__DUMMY__) } -result {0 {new value}} + +test append-10.1 {Bug 214cc0eb22: lappend with no values} { + set lst "# 1 2 3" + [subst lappend] lst +} "# 1 2 3" +test append-10.2 {Bug 214cc0eb22: lappend with no values} -body { + set lst "1 \{ 2" + [subst lappend] lst +} -returnCodes error -result {unmatched open brace in list} +test append-10.3 {Bug 214cc0eb22: expanded lappend with no values} { + set lst "# 1 2 3" + [subst lappend] lst {*}[list] +} "# 1 2 3" +test append-10.4 {Bug 214cc0eb22: expanded lappend with no values} -body { + set lst "1 \{ 2" + [subst lappend] lst {*}[list] +} -returnCodes error -result {unmatched open brace in list} unset -nocomplain i x result y catch {rename foo ""} diff --git a/tests/appendComp.test b/tests/appendComp.test index f85c3ba..bbf5f9c 100644 --- a/tests/appendComp.test +++ b/tests/appendComp.test @@ -438,6 +438,27 @@ test appendComp-9.3 {bug 3057639, append direct eval, read trace on non-existing } -cleanup { unset -nocomplain ::env(__DUMMY__) } -result {0 {new value}} + +test appendComp-10.1 {Bug 214cc0eb22: lappend with no values} { + apply {lst { + lappend lst + }} "# 1 2 3" +} "# 1 2 3" +test appendComp-10.2 {Bug 214cc0eb22: lappend with no values} -body { + apply {lst { + lappend lst + }} "1 \{ 2" +} -returnCodes error -result {unmatched open brace in list} +test appendComp-10.3 {Bug 214cc0eb22: expanded lappend with no values} { + apply {lst { + lappend lst {*}[list] + }} "# 1 2 3" +} "# 1 2 3" +test appendComp-10.4 {Bug 214cc0eb22: expanded lappend with no values} -body { + apply {lst { + lappend lst {*}[list] + }} "1 \{ 2" +} -returnCodes error -result {unmatched open brace in list} catch {unset i x result y} catch {rename foo ""} -- cgit v0.12 From 620cf6fa02dbbb41fb375bcad80ec0b5851462b4 Mon Sep 17 00:00:00 2001 From: dgp Date: Tue, 11 Nov 2014 22:23:57 +0000 Subject: Likely fix for channel mem leaks. --- generic/tclIO.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index 8ec2a1e..2025742 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -155,6 +155,7 @@ static ChannelBuffer * AllocChannelBuffer(int length); static void PreserveChannelBuffer(ChannelBuffer *bufPtr); static void ReleaseChannelBuffer(ChannelBuffer *bufPtr); static int IsShared(ChannelBuffer *bufPtr); +static void ChannelFree(Channel *chanPtr); static void ChannelTimerProc(ClientData clientData); static int ChanRead(Channel *chanPtr, char *dst, int dstSize); static int CheckChannelErrors(ChannelState *statePtr, @@ -1914,6 +1915,16 @@ TclChannelRelease( } } +static void +ChannelFree( + Channel *chanPtr) +{ + if (chanPtr->refCount == 0) { + ckfree(chanPtr); + return; + } + chanPtr->typePtr = NULL; +} /* *---------------------------------------------------------------------- @@ -2060,7 +2071,7 @@ Tcl_UnstackChannel( */ result = ChanClose(chanPtr, interp); - chanPtr->typePtr = NULL; + ChannelFree(chanPtr); UpdateInterest(statePtr->topChanPtr); @@ -3018,7 +3029,8 @@ CloseChannel( statePtr->topChanPtr = downChanPtr; downChanPtr->upChanPtr = NULL; - chanPtr->typePtr = NULL; + + ChannelFree(chanPtr); return Tcl_Close(interp, (Tcl_Channel) downChanPtr); } @@ -3029,7 +3041,7 @@ CloseChannel( * stack, make sure to free the ChannelState structure associated with it. */ - chanPtr->typePtr = NULL; + ChannelFree(chanPtr); Tcl_EventuallyFree(statePtr, TCL_DYNAMIC); -- cgit v0.12 From 3bbc2317b3c2fb91fe9afbe04708c7e15db60f55 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Thu, 13 Nov 2014 12:29:04 +0000 Subject: Improve documentation on the use of com ports (remove references to Windows 95, deprecate the use of postfix ':'). Allow lpt[5-9] just as com[5-9], and make sure that path normalization works as expected for ports > 4. --- doc/open.n | 60 +++++++++++---------------------------------------- generic/tclFileName.c | 8 +++---- tests/winFCmd.test | 13 +++++++---- win/tclWinFile.c | 4 ++-- 4 files changed, 28 insertions(+), 57 deletions(-) diff --git a/doc/open.n b/doc/open.n index b888126..7216607 100644 --- a/doc/open.n +++ b/doc/open.n @@ -331,61 +331,27 @@ may cause this error. A BREAK condition has been detected by your UART (see above). .SH "PORTABILITY ISSUES" .TP -\fBWindows \fR(all versions) +\fBWindows \fR Valid values for \fIfileName\fR to open a serial port are of the form -\fBcom\fIX\fB:\fR, where \fIX\fR is a number, generally from 1 to 4. -This notation only works for serial ports from 1 to 9, if the system -happens to have more than four. An attempt to open a serial port that +\fBcom\fIX\fB\fR, where \fIX\fR is a number, generally from 1 to 9. +A legacy form accepted as well is \fBcom\fIX\fB:\fR. This notation only +works for serial ports from 1 to 9. An attempt to open a serial port that does not exist or has a number greater than 9 will fail. An alternate -form of opening serial ports is to use the filename \fB\e\e.\ecomX\fR, -where X is any number that corresponds to a serial port; please note -that this method is considerably slower on Windows 95 and Windows 98. -.TP -\fBWindows NT\fR +form of opening serial ports is to use the filename \fB//./comX\fR, +where X is any number that corresponds to a serial port. +.RS +.PP When running Tcl interactively, there may be some strange interactions between the real console, if one is present, and a command pipeline that uses standard input or output. If a command pipeline is opened for reading, some of the lines entered at the console will be sent to the command pipeline and some will be sent to the Tcl evaluator. If a command pipeline is opened for writing, keystrokes entered into the console are not visible until the -pipe is closed. This behavior occurs whether the command pipeline is -executing 16-bit or 32-bit applications. These problems only occur because -both Tcl and the child application are competing for the console at -the same time. If the command pipeline is started from a script, so that Tcl -is not accessing the console, or if the command pipeline does not use -standard input or output, but is redirected from or to a file, then the -above problems do not occur. -.TP -\fBWindows 95\fR -A command pipeline that executes a 16-bit DOS application cannot be opened -for both reading and writing, since 16-bit DOS applications that receive -standard input from a pipe and send standard output to a pipe run -synchronously. Command pipelines that do not execute 16-bit DOS -applications run asynchronously and can be opened for both reading and -writing. -.RS -.PP -When running Tcl interactively, there may be some strange interactions -between the real console, if one is present, and a command pipeline that uses -standard input or output. If a command pipeline is opened for reading from -a 32-bit application, some of the keystrokes entered at the console will be -sent to the command pipeline and some will be sent to the Tcl evaluator. If -a command pipeline is opened for writing to a 32-bit application, no output -is visible on the console until the pipe is closed. These problems only -occur because both Tcl and the child application are competing for the -console at the same time. If the command pipeline is started from a script, -so that Tcl is not accessing the console, or if the command pipeline does -not use standard input or output, but is redirected from or to a file, then -the above problems do not occur. -.PP -Whether or not Tcl is running interactively, if a command pipeline is opened -for reading from a 16-bit DOS application, the call to \fBopen\fR will not -return until end-of-file has been received from the command pipeline's -standard output. If a command pipeline is opened for writing to a 16-bit DOS -application, no data will be sent to the command pipeline's standard output -until the pipe is actually closed. This problem occurs because 16-bit DOS -applications are run synchronously, as described above. -.RE +pipe is closed. These problems only occur because both Tcl and the child +application are competing for the console at the same time. If the command +pipeline is started from a script, so that Tcl is not accessing the console, +or if the command pipeline does not use standard input or output, but is +redirected from or to a file, then the above problems do not occur. .TP \fBUnix\fR\0\0\0\0\0\0\0 Valid values for \fIfileName\fR to open a serial port are generally of the diff --git a/generic/tclFileName.c b/generic/tclFileName.c index 07757d9..a8360fc 100644 --- a/generic/tclFileName.c +++ b/generic/tclFileName.c @@ -225,9 +225,9 @@ ExtractWinRoot( if ((path[0] == 'c' || path[0] == 'C') && (path[1] == 'o' || path[1] == 'O')) { if ((path[2] == 'm' || path[2] == 'M') - && path[3] >= '1' && path[3] <= '4') { + && path[3] >= '1' && path[3] <= '9') { /* - * May have match for 'com[1-4]:?', which is a serial port. + * May have match for 'com[1-9]:?', which is a serial port. */ if (path[4] == '\0') { @@ -247,9 +247,9 @@ ExtractWinRoot( } else if ((path[0] == 'l' || path[0] == 'L') && (path[1] == 'p' || path[1] == 'P') && (path[2] == 't' || path[2] == 'T')) { - if (path[3] >= '1' && path[3] <= '3') { + if (path[3] >= '1' && path[3] <= '9') { /* - * May have match for 'lpt[1-3]:?' + * May have match for 'lpt[1-9]:?' */ if (path[4] == '\0') { diff --git a/tests/winFCmd.test b/tests/winFCmd.test index ef1c4e7..f0cb406 100644 --- a/tests/winFCmd.test +++ b/tests/winFCmd.test @@ -1110,16 +1110,16 @@ test winFCmd-18.1.2 {Windows reserved path names} -constraints win -body { } -result "absolute" test winFCmd-18.1.3 {Windows reserved path names} -constraints win -body { - file pathtype com5 -} -result "relative" + file pathtype com9 +} -result "absolute" test winFCmd-18.1.4 {Windows reserved path names} -constraints win -body { file pathtype lpt3 } -result "absolute" test winFCmd-18.1.5 {Windows reserved path names} -constraints win -body { - file pathtype lpt4 -} -result "relative" + file pathtype lpt9 +} -result "absolute" test winFCmd-18.1.6 {Windows reserved path names} -constraints win -body { file pathtype nul @@ -1238,6 +1238,11 @@ test winFCmd-19.8 {Windows extended path names} -constraints nt -setup { catch {file delete $tmpfile} } -result [list 0 {} [list "tcl[pid].tmp "]] +test winFCmd-19.9 {Windows devices path names} -constraints nt -body { + file normalize //./com1 +} -result //./com1 + + # This block of code used to occur after the "return" call, so I'm # commenting it out and assuming that this code is still under construction. #foreach source {tef ted tnf tnd "" nul com1} { diff --git a/win/tclWinFile.c b/win/tclWinFile.c index 7487022..76cd561 100644 --- a/win/tclWinFile.c +++ b/win/tclWinFile.c @@ -1246,9 +1246,9 @@ WinIsReserved( } else if ((path[0] == 'l' || path[0] == 'L') && (path[1] == 'p' || path[1] == 'P') && (path[2] == 't' || path[2] == 'T')) { - if (path[3] >= '1' && path[3] <= '3') { + if (path[3] >= '1' && path[3] <= '9') { /* - * May have match for 'lpt[1-3]:?' + * May have match for 'lpt[1-9]:?' */ if (path[4] == '\0') { -- cgit v0.12 From 6e056b1e14ac49bab5da26577d54d00489144066 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Thu, 13 Nov 2014 16:08:47 +0000 Subject: Simplify NativeIsComPort() implementation: native paths never end in ':', and never use forward slashes (any more), so no need to check for that. --- win/tclWinChan.c | 32 ++++++++++++-------------------- 1 file changed, 12 insertions(+), 20 deletions(-) diff --git a/win/tclWinChan.c b/win/tclWinChan.c index 2d6c42c..cca0dab 100644 --- a/win/tclWinChan.c +++ b/win/tclWinChan.c @@ -971,7 +971,7 @@ TclpOpenFileChannel( switch (FileGetType(handle)) { case FILE_TYPE_SERIAL: /* - * Natively named serial ports "com1-9", "\\\\.\\comXX" are + * Natively named serial ports "com1-9", "\\\\.\\comXX" are * already done with the code above. * Here we handle all other serial port names. * @@ -1525,12 +1525,11 @@ FileGetType( * NativeIsComPort -- * * Determines if a path refers to a Windows serial port. - * A simple and efficient solution is to use a "name hint" to detect - * COM ports by their filename instead of resorting to a syscall + * A simple and efficient solution is to use a "name hint" to detect + * COM ports by their filename instead of resorting to a syscall * to detect serialness after the fact. * The following patterns cover common serial port names: - * COM[1-9]:? - * //./COM[0-9]+ + * COM[1-9] * \\.\COM[0-9]+ * * Results: @@ -1550,33 +1549,26 @@ NativeIsComPort( * 1. Look for com[1-9]:? */ - if ( (len >= 4) && (len <= 5) - && (_wcsnicmp(p, L"com", 3) == 0) ) { + if ( (len == 4) && (_wcsnicmp(p, L"com", 3) == 0) ) { /* - * The 4th character must be a digit 1..9 optionally followed by a ":" + * The 4th character must be a digit 1..9 */ - + if ( (p[3] < L'1') || (p[3] > L'9') ) { return 0; } - if ( (len == 5) && (p[4] != L':') ) { - return 0; - } return 1; } - + /* - * 2. Look for //./com[0-9]+ or \\.\com[0-9]+ + * 2. Look for \\.\com[0-9]+ */ - - if ( (len >= 8) && ( - (_wcsnicmp(p, L"//./com", 7) == 0) - || (_wcsnicmp(p, L"\\\\.\\com", 7) == 0) ) ) - { + + if ((len >= 8) && (_wcsnicmp(p, L"\\\\.\\com", 7) == 0)) { /* * Charaters 8..end must be a digits 0..9 */ - + for ( i=7; i '9') ) { return 0; -- cgit v0.12 From 9c2149012b89058326868f392e85d2f48b3bb24a Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Fri, 14 Nov 2014 09:44:34 +0000 Subject: Remove a number of eol-spaces. No change in functionality. --- changes | 6 ++-- license.terms | 4 +-- macosx/configure.ac | 2 +- pkgs/README | 4 +-- unix/ldAix | 6 ++-- unix/tcl.spec | 2 +- unix/tclUnixChan.c | 8 ++--- unix/tclUnixInit.c | 2 +- unix/tclUnixPipe.c | 4 +-- unix/tclUnixSock.c | 50 ++++++++++++++--------------- unix/tclUnixThrd.h | 2 +- unix/tclUnixTime.c | 2 +- win/tclConfig.sh.in | 2 +- win/tclWinConsole.c | 2 +- win/tclWinSerial.c | 2 +- win/tclWinSock.c | 90 ++++++++++++++++++++++++++--------------------------- 16 files changed, 94 insertions(+), 94 deletions(-) diff --git a/changes b/changes index 945b167..1decfe2 100644 --- a/changes +++ b/changes @@ -8303,11 +8303,11 @@ reported usage of large expressions (porter) Many optmizations, improvements, and tightened stack management in bytecode. ---- Released 8.6.1, September 20, 2013 --- http://core.tcl.tk/tcl/ for details +--- Released 8.6.1, September 20, 2013 --- http://core.tcl.tk/tcl/ for details 2013-09-27 (enhancement) improved ::env synchronization (fellows) -2013-10-20 (bug fix)[2835313] segfault from +2013-10-20 (bug fix)[2835313] segfault from [apply {{} {while 1 {a {*}[return -level 0 -code continue]}}}] (fellows) 2013-10-22 (bug fix)[3556215] [scan %E%G%X] support (fellows) @@ -8451,7 +8451,7 @@ 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 +--- Released 8.6.2, August 27, 2014 --- http://core.tcl.tk/tcl/ for details 2014-08-28 (bug)[b9e1a3] Correct Method Search Order (nadkarni,fellows) => TclOO 1.0.3 diff --git a/license.terms b/license.terms index 164d65e..d8049cd 100644 --- a/license.terms +++ b/license.terms @@ -29,7 +29,7 @@ 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 +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 @@ -37,4 +37,4 @@ Government shall have only "Restricted Rights" as defined in Clause 252.227-7014 (b) (3) 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. +terms specified in this license. diff --git a/macosx/configure.ac b/macosx/configure.ac index 01c3697..f7a8bb3 100644 --- a/macosx/configure.ac +++ b/macosx/configure.ac @@ -3,7 +3,7 @@ dnl This file is an input file used by the GNU "autoconf" program to dnl generate the file "configure", which is run during Tcl installation dnl to configure the system for the local environment. -dnl Ensure that the config (auto)headers support is used, then just +dnl Ensure that the config (auto)headers support is used, then just dnl include the configure sources from ../unix: m4_include(../unix/aclocal.m4) diff --git a/pkgs/README b/pkgs/README index 868bd4f..159a237 100644 --- a/pkgs/README +++ b/pkgs/README @@ -36,14 +36,14 @@ needs to conform to the following conventions. clean: Delete all files generated by the default build target. - distclean: Delete all generated files. + distclean: Delete all generated files. dist: Produce a copy of the package's source code distribution. Must respect the DIST_ROOT variable determining where to write the generated directory. Packages that are written to make use of the Tcl Extension Architecture (TEA) -and that make use of the tclconfig collection of support files, should +and that make use of the tclconfig collection of support files, should conform to these conventions without further efforts. These conventions are subject to revision and refinement over time to diff --git a/unix/ldAix b/unix/ldAix index 51b2995..f115ea8 100755 --- a/unix/ldAix +++ b/unix/ldAix @@ -1,5 +1,5 @@ #!/bin/sh -# +# # ldAix ldCmd ldArg ldArg ... # # This shell script provides a wrapper for ld under AIX in order to @@ -40,8 +40,8 @@ rm -f lib.exp echo "#! $outputFile" >lib.exp /usr/ccs/bin/nm $nmopts $ofiles | sed -e '/:$/d' -e '/ U /d' -e 's/^\.//' -e 's/[ |].*//' | sort | uniq >>lib.exp -# If we're linking a .a file, then link all the objects together into a -# single file "shr.o" and then put that into the archive. Otherwise link +# If we're linking a .a file, then link all the objects together into a +# single file "shr.o" and then put that into the archive. Otherwise link # the object files directly into the .a file. noDotA=`echo $outputFile | sed -e '/\.a$/d'` diff --git a/unix/tcl.spec b/unix/tcl.spec index d660f74..81f31da 100644 --- a/unix/tcl.spec +++ b/unix/tcl.spec @@ -30,7 +30,7 @@ CFLAGS="%optflags" ./configure \ --prefix=%{directory} \ --exec-prefix=%{directory} \ --libdir=%{directory}/%{_lib} -make +make %install cd unix diff --git a/unix/tclUnixChan.c b/unix/tclUnixChan.c index 2eca714..a1fe090 100644 --- a/unix/tclUnixChan.c +++ b/unix/tclUnixChan.c @@ -792,7 +792,7 @@ TtySetOptionProc( * * Results: * A standard Tcl result. Also sets the supplied DString to the string - * value of the option(s) returned. Sets error message if needed + * value of the option(s) returned. Sets error message if needed * (by calling Tcl_BadChannelOption). * *---------------------------------------------------------------------- @@ -1201,7 +1201,7 @@ TtyParseMode( char parity; const char *bad = "bad value for -mode"; - i = sscanf(mode, "%d,%c,%d,%d%n", + i = sscanf(mode, "%d,%c,%d,%d%n", &ttyPtr->baud, &parity, &ttyPtr->data, @@ -1292,7 +1292,7 @@ TtyInit( || iostate.c_lflag != 0 || iostate.c_cflag & CREAD || iostate.c_cc[VMIN] != 1 - || iostate.c_cc[VTIME] != 0) + || iostate.c_cc[VTIME] != 0) { iostate.c_iflag = IGNBRK; iostate.c_oflag = 0; @@ -1824,7 +1824,7 @@ TclUnixWaitForFile( if (FD_ISSET(fd, &writableMask)) { SET_BITS(result, TCL_WRITABLE); } - if (FD_ISSET(fd, &exceptionMask)) { + if (FD_ISSET(fd, &exceptionMask)) { SET_BITS(result, TCL_EXCEPTION); } result &= mask; diff --git a/unix/tclUnixInit.c b/unix/tclUnixInit.c index 1617cba..520c8e5 100644 --- a/unix/tclUnixInit.c +++ b/unix/tclUnixInit.c @@ -768,7 +768,7 @@ TclpSetVariables( */ CFLocaleRef localeRef; - + if (CFLocaleCopyCurrent != NULL && CFLocaleGetIdentifier != NULL && (localeRef = CFLocaleCopyCurrent())) { CFStringRef locale = CFLocaleGetIdentifier(localeRef); diff --git a/unix/tclUnixPipe.c b/unix/tclUnixPipe.c index 95bc8d1..8b26694 100644 --- a/unix/tclUnixPipe.c +++ b/unix/tclUnixPipe.c @@ -261,7 +261,7 @@ TclpTempFileName(void) * * On Unix, it works to load a shared object from a file of any name, so this * function is merely a thin wrapper around TclpTempFileName(). - * + * *---------------------------------------------------------------------------- */ @@ -969,7 +969,7 @@ PipeClose2Proc( pipePtr->outFile = NULL; } } - + /* * If half-closing, stop here. */ diff --git a/unix/tclUnixSock.c b/unix/tclUnixSock.c index d06e7f1..0188ea6 100644 --- a/unix/tclUnixSock.c +++ b/unix/tclUnixSock.c @@ -438,11 +438,11 @@ WaitForConnect( /* * Check if an async connect is running. If not return ok */ - + if (!(statePtr->flags & TCP_ASYNC_PENDING)) { return 0; } - + if (errorCodePtr == NULL || (statePtr->flags & TCP_NONBLOCKING)) { timeout = 0; } else { @@ -601,7 +601,7 @@ TcpCloseProc( * handlers are already deleted in the generic IO channel closing code * that called this function, so we do not have to delete them here. */ - + for (fds = &statePtr->fds; fds != NULL; fds = fds->next) { if (fds->fd < 0) { continue; @@ -610,7 +610,7 @@ TcpCloseProc( if (close(fds->fd) < 0) { errorCode = errno; } - + } fds = statePtr->fds.next; while (fds != NULL) { @@ -974,7 +974,7 @@ TcpWatchProc( */ return; } - + if (statePtr->flags & TCP_ASYNC_PENDING) { /* Async sockets use a FileHandler internally while connecting, so we * need to cache this request until the connection has succeeded. */ @@ -1111,7 +1111,7 @@ TcpConnect( for (statePtr->myaddr = statePtr->myaddrlist; statePtr->myaddr != NULL; statePtr->myaddr = statePtr->myaddr->ai_next) { int reuseaddr = 1; - + /* * No need to try combinations of local and remote addresses of * different families. @@ -1141,15 +1141,15 @@ TcpConnect( * Set the close-on-exec flag so that the socket will not get * inherited by child processes. */ - + fcntl(statePtr->fds.fd, F_SETFD, FD_CLOEXEC); - + /* * Set kernel space buffering */ - + TclSockMinimumBuffers(INT2PTR(statePtr->fds.fd), SOCKET_BUFSIZE); - + if (async) { ret = TclUnixSetBlockingMode(statePtr->fds.fd,TCL_MODE_NONBLOCKING); if (ret < 0) { @@ -1160,7 +1160,7 @@ TcpConnect( /* Gotta reset the error variable here, before we use it for the * first time in this iteration. */ error = 0; - + (void) setsockopt(statePtr->fds.fd, SOL_SOCKET, SO_REUSEADDR, (char *) &reuseaddr, sizeof(reuseaddr)); ret = bind(statePtr->fds.fd, statePtr->myaddr->ai_addr, @@ -1176,7 +1176,7 @@ TcpConnect( * will set up a file handler on the socket if she is interested * in being informed when the connect completes. */ - + ret = connect(statePtr->fds.fd, statePtr->addr->ai_addr, statePtr->addr->ai_addrlen); if (ret < 0) error = errno; @@ -1459,28 +1459,28 @@ Tcl_OpenTcpServer( } continue; } - + /* * Set the close-on-exec flag so that the socket will not get * inherited by child processes. */ - + fcntl(sock, F_SETFD, FD_CLOEXEC); - + /* * Set kernel space buffering */ - + TclSockMinimumBuffers(INT2PTR(sock), SOCKET_BUFSIZE); - + /* * Set up to reuse server addresses automatically and bind to the * specified port. */ - - (void) setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, + + (void) setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &reuseaddr, sizeof(reuseaddr)); - + /* * Make sure we use the same port number when opening two server * sockets for IPv4 and IPv6 on a random port. @@ -1509,7 +1509,7 @@ Tcl_OpenTcpServer( if (howfar < BIND) { howfar = BIND; my_errno = errno; - } + } close(sock); sock = -1; continue; @@ -1541,7 +1541,7 @@ Tcl_OpenTcpServer( /* * Allocate a new TcpState for this socket. */ - + statePtr = ckalloc(sizeof(TcpState)); memset(statePtr, 0, sizeof(TcpState)); statePtr->acceptProc = acceptProc; @@ -1556,12 +1556,12 @@ Tcl_OpenTcpServer( newfds->fd = sock; newfds->statePtr = statePtr; fds = newfds; - + /* * Set up the callback mechanism for accepting connections from new * clients. */ - + Tcl_CreateFileHandler(sock, TCL_READABLE, TcpAccept, fds); } @@ -1620,7 +1620,7 @@ TcpAccept( socklen_t len; /* For accept interface */ char channelName[SOCK_CHAN_LENGTH]; char host[NI_MAXHOST], port[NI_MAXSERV]; - + len = sizeof(addr); newsock = accept(fds->fd, &addr.sa, &len); if (newsock < 0) { diff --git a/unix/tclUnixThrd.h b/unix/tclUnixThrd.h index 6a73132..f03b530 100644 --- a/unix/tclUnixThrd.h +++ b/unix/tclUnixThrd.h @@ -8,7 +8,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. */ - + #ifndef _TCLUNIXTHRD #define _TCLUNIXTHRD diff --git a/unix/tclUnixTime.c b/unix/tclUnixTime.c index 4452022..315bcf9 100644 --- a/unix/tclUnixTime.c +++ b/unix/tclUnixTime.c @@ -199,7 +199,7 @@ TclpWideClicksToNanoseconds( #ifdef MAC_OSX_TCL static mach_timebase_info_data_t tb; static uint64_t maxClicksForUInt64; - + if (!tb.denom) { mach_timebase_info(&tb); maxClicksForUInt64 = UINT64_MAX / tb.numer; diff --git a/win/tclConfig.sh.in b/win/tclConfig.sh.in index 00a8790..75324b2 100644 --- a/win/tclConfig.sh.in +++ b/win/tclConfig.sh.in @@ -1,5 +1,5 @@ # tclConfig.sh -- -# +# # This shell script (for sh) is generated automatically by Tcl's # configure script. It will create shell variables for most of # the configuration options discovered by the configure script. diff --git a/win/tclWinConsole.c b/win/tclWinConsole.c index 6630083..63150ef 100644 --- a/win/tclWinConsole.c +++ b/win/tclWinConsole.c @@ -761,7 +761,7 @@ ConsoleInputProc( * by the caller. In practice this is harmless, since all writes * are into ChannelBuffers, and those have padding, but still * ought to remove this, unless some Windows wizard can give - * a reason not to. + * a reason not to. */ buf[count] = '\0'; return count; diff --git a/win/tclWinSerial.c b/win/tclWinSerial.c index 6487fe4..0730a46 100644 --- a/win/tclWinSerial.c +++ b/win/tclWinSerial.c @@ -1415,7 +1415,7 @@ SerialWriterThread( * Opens or Reopens the serial port with the OVERLAPPED FLAG set * * Results: - * Returns the new handle, or INVALID_HANDLE_VALUE. + * Returns the new handle, or INVALID_HANDLE_VALUE. * If an existing channel is specified it is closed and reopened. * * Side effects: diff --git a/win/tclWinSock.c b/win/tclWinSock.c index 66df291..2c58224 100644 --- a/win/tclWinSock.c +++ b/win/tclWinSock.c @@ -596,7 +596,7 @@ WaitForConnect( /* * Check if an async connect is running. If not return ok */ - + if (!(statePtr->flags & TCP_ASYNC_CONNECT)) { return 0; } @@ -616,7 +616,7 @@ WaitForConnect( /* get statePtr lock */ tsdPtr = TclThreadDataKeyGet(&dataKey); WaitForSingleObject(tsdPtr->socketListLock, INFINITE); - + /* Check for connect event */ if (statePtr->readyEvents & FD_CONNECT) { @@ -1250,7 +1250,7 @@ TcpGetOptionProc( return TCL_ERROR; } - /* + /* * Go one step in async connect * If any error is thrown save it as backround error to report eventually below */ @@ -1647,14 +1647,14 @@ TcpConnect( /* We were called by the event procedure and continue our loop */ int async_callback = statePtr->flags & TCP_ASYNC_PENDING; ThreadSpecificData *tsdPtr = TclThreadDataKeyGet(&dataKey); - + if (async_callback) { goto reenter; } - + for (statePtr->addr = statePtr->addrlist; statePtr->addr != NULL; statePtr->addr = statePtr->addr->ai_next) { - + for (statePtr->myaddr = statePtr->myaddrlist; statePtr->myaddr != NULL; statePtr->myaddr = statePtr->myaddr->ai_next) { @@ -1670,7 +1670,7 @@ TcpConnect( /* * Close the socket if it is still open from the last unsuccessful * iteration. - */ + */ if (statePtr->sockets->fd != INVALID_SOCKET) { closesocket(statePtr->sockets->fd); } @@ -1683,9 +1683,9 @@ TcpConnect( */ statePtr->notifierConnectError = 0; Tcl_SetErrno(0); - + statePtr->sockets->fd = socket(statePtr->myaddr->ai_family, SOCK_STREAM, 0); - + /* Free list lock */ SetEvent(tsdPtr->socketListLock); @@ -1754,7 +1754,7 @@ TcpConnect( * thread. */ statePtr->selectEvents |= FD_CONNECT; - + /* * Free list lock */ @@ -1768,7 +1768,7 @@ TcpConnect( /* * Attempt to connect to the remote socket. */ - + connect(statePtr->sockets->fd, statePtr->addr->ai_addr, statePtr->addr->ai_addrlen); @@ -1809,7 +1809,7 @@ TcpConnect( * the FD_CONNECT asyncroneously */ tsdPtr->pendingTcpState = NULL; - + if (Tcl_GetErrno() == 0) { goto out; } @@ -1835,12 +1835,12 @@ out: * Set up the select mask for read/write events. */ statePtr->selectEvents = FD_READ | FD_WRITE | FD_CLOSE; - + /* * Register for interest in events in the select mask. Note that this * automatically places the socket into non-blocking mode. */ - + SendMessage(tsdPtr->hwnd, SOCKET_SELECT, (WPARAM) SELECT, (LPARAM) statePtr); } else { @@ -2092,20 +2092,20 @@ Tcl_OpenTcpServer( TclWinConvertError((DWORD) WSAGetLastError()); continue; } - + /* * Win-NT has a misfeature that sockets are inherited in child * processes by default. Turn off the inherit bit. */ - + SetHandleInformation((HANDLE) sock, HANDLE_FLAG_INHERIT, 0); - + /* * Set kernel space buffering */ - + TclSockMinimumBuffers((void *)sock, TCP_BUFFER_SIZE); - + /* * Make sure we use the same port when opening two server sockets * for IPv4 and IPv6. @@ -2113,12 +2113,12 @@ Tcl_OpenTcpServer( * As sockaddr_in6 uses the same offset and size for the port * member as sockaddr_in, we can handle both through the IPv4 API. */ - + if (port == 0 && chosenport != 0) { ((struct sockaddr_in *) addrPtr->ai_addr)->sin_port = htons(chosenport); } - + /* * Bind to the specified port. Note that we must not call * setsockopt with SO_REUSEADDR because Microsoft allows addresses @@ -2128,7 +2128,7 @@ Tcl_OpenTcpServer( * set into nonblocking mode. If there is trouble, this is one * place to look for bugs. */ - + if (bind(sock, addrPtr->ai_addr, addrPtr->ai_addrlen) == SOCKET_ERROR) { TclWinConvertError((DWORD) WSAGetLastError()); @@ -2138,29 +2138,29 @@ Tcl_OpenTcpServer( if (port == 0 && chosenport == 0) { address sockname; socklen_t namelen = sizeof(sockname); - + /* * Synchronize port numbers when binding to port 0 of multiple * addresses. */ - + if (getsockname(sock, &sockname.sa, &namelen) >= 0) { chosenport = ntohs(sockname.sa4.sin_port); } } - + /* * Set the maximum number of pending connect requests to the max * value allowed on each platform (Win32 and Win32s may be * different, and there may be differences between TCP/IP stacks). */ - + if (listen(sock, SOMAXCONN) == SOCKET_ERROR) { TclWinConvertError((DWORD) WSAGetLastError()); closesocket(sock); continue; } - + if (statePtr == NULL) { /* * Add this socket to the global list of sockets. @@ -2186,9 +2186,9 @@ error: /* * Set up the select mask for connection request events. */ - + statePtr->selectEvents = FD_ACCEPT; - + /* * Register for interest in events in the select mask. Note that this * automatically places the socket into non-blocking mode. @@ -2652,7 +2652,7 @@ SocketEventProc( WaitForConnect(statePtr,NULL); } else { - + /* * No async connect reenter pending. Just clear event. */ @@ -2681,7 +2681,7 @@ SocketEventProc( * network stack conditions that can result in FD_ACCEPT but a subsequent * failure on accept() by the time we get around to it. * Access to sockets (acceptEventCount, readyEvents) in socketList - * is still protected by the lock (prevents reintroduction of + * is still protected by the lock (prevents reintroduction of * SF Tcl Bug 3056775. */ @@ -2713,9 +2713,9 @@ SocketEventProc( return 1; } - /* Loop terminated with no sockets accepted; clear the ready mask so - * we can detect the next connection request. Note that connection - * requests are level triggered, so if there is a request already + /* Loop terminated with no sockets accepted; clear the ready mask so + * we can detect the next connection request. Note that connection + * requests are level triggered, so if there is a request already * pending, a new event will be generated. */ statePtr->acceptEventCount = 0; @@ -2758,7 +2758,7 @@ SocketEventProc( if ( statePtr->flags & TCP_ASYNC_FAILED ) { mask |= TCL_READABLE; - + } else { fd_set readFds; struct timeval timeout; @@ -2796,11 +2796,11 @@ SocketEventProc( if (events & FD_WRITE) { mask |= TCL_WRITABLE; } - + /* * Call registered event procedures */ - + if (mask) { Tcl_NotifyChannel(statePtr->channel, mask); } @@ -2812,7 +2812,7 @@ SocketEventProc( * * AddSocketInfoFd -- * - * This function adds a SOCKET file descriptor to the 'sockets' linked + * This function adds a SOCKET file descriptor to the 'sockets' linked * list of a TcpState structure. * * Results: @@ -2826,7 +2826,7 @@ SocketEventProc( static void AddSocketInfoFd( - TcpState *statePtr, + TcpState *statePtr, SOCKET socket) { TcpFdList *fds = statePtr->sockets; @@ -2840,7 +2840,7 @@ AddSocketInfoFd( while ( fds->next != NULL ) { fds = fds->next; } - + fds->next = ckalloc(sizeof(TcpFdList)); fds = fds->next; } @@ -2851,7 +2851,7 @@ AddSocketInfoFd( fds->next = NULL; } - + /* *---------------------------------------------------------------------- * @@ -2935,7 +2935,7 @@ WaitForSocketEvent( /* get statePtr lock */ WaitForSingleObject(tsdPtr->socketListLock, INFINITE); - + /* Check if event occured */ event_found = (statePtr->readyEvents & events); @@ -2946,7 +2946,7 @@ WaitForSocketEvent( if (event_found) { break; } - + /* Exit loop if event did not occur but this is a non-blocking channel */ if (statePtr->flags & TCP_NONBLOCKING) { *errorCodePtr = EWOULDBLOCK; @@ -3313,11 +3313,11 @@ TcpThreadActionProc( WaitForSingleObject(tsdPtr->socketListLock, INFINITE); statePtr->nextPtr = tsdPtr->socketList; tsdPtr->socketList = statePtr; - + if (statePtr == tsdPtr->pendingTcpState) { tsdPtr->pendingTcpState = NULL; } - + SetEvent(tsdPtr->socketListLock); notifyCmd = SELECT; -- cgit v0.12 From 164250cf8605bbfb0f361e639d8bfc656526dd15 Mon Sep 17 00:00:00 2001 From: dgp Date: Sat, 15 Nov 2014 21:08:57 +0000 Subject: Tcl_ExternalToUtf appends a terminating NUL to its encoded results. Perhaps this is a welcome convenience for some callers, but not for Tcl's I/O system, which has no need for that. Added a new flag value TCL_ENCODING_NO_TERMINATE that callers can use to suppress this behavior. This means buffers don't require so much padding, and a tiny bit of processing is saved. Update I/O callers to use the feature. --- generic/tcl.h | 17 +++++++++++++++++ generic/tclEncoding.c | 22 +++++++++++++++------- generic/tclIO.c | 44 +++++++++++++++++++++++--------------------- 3 files changed, 55 insertions(+), 28 deletions(-) diff --git a/generic/tcl.h b/generic/tcl.h index fc477f2..95f2b3f 100644 --- a/generic/tcl.h +++ b/generic/tcl.h @@ -2144,11 +2144,28 @@ typedef struct Tcl_EncodingType { * substituting one or more "close" characters in * the destination buffer and then continue to * convert the source. + * TCL_ENCODING_NO_TERMINATE - If set, Tcl_ExternalToUtf will not append a + * terminating NUL byte. Knowing that it will + * not need space to do so, it will fill all + * dstLen bytes with encoded UTF-8 content, as + * other circumstances permit. If clear, the + * default behavior is to reserve a byte in + * the dst space for NUL termination, and to + * append the NUL byte. + * TCL_ENCODING_CHAR_LIMIT - If set and dstCharsPtr is not NULL, then + * Tcl_ExternalToUtf takes the initial value + * of *dstCharsPtr is taken as a limit of the + * maximum number of chars to produce in the + * encoded UTF-8 content. Otherwise, the + * number of chars produced is controlled only + * by other limiting factors. */ #define TCL_ENCODING_START 0x01 #define TCL_ENCODING_END 0x02 #define TCL_ENCODING_STOPONERROR 0x04 +#define TCL_ENCODING_NO_TERMINATE 0x08 +#define TCL_ENCODING_CHAR_LIMIT 0x10 /* * The following definitions are the error codes returned by the conversion diff --git a/generic/tclEncoding.c b/generic/tclEncoding.c index d246cb2..0446816 100644 --- a/generic/tclEncoding.c +++ b/generic/tclEncoding.c @@ -1204,6 +1204,7 @@ Tcl_ExternalToUtf( { const Encoding *encodingPtr; int result, srcRead, dstWrote, dstChars; + int noTerminate = flags & TCL_ENCODING_NO_TERMINATE; Tcl_EncodingState state; if (encoding == NULL) { @@ -1230,17 +1231,24 @@ Tcl_ExternalToUtf( dstCharsPtr = &dstChars; } - /* - * If there are any null characters in the middle of the buffer, they will - * converted to the UTF-8 null character (\xC080). To get the actual \0 at - * the end of the destination buffer, we need to append it manually. - */ + if (!noTerminate) { + /* + * If there are any null characters in the middle of the buffer, + * they will converted to the UTF-8 null character (\xC080). To get + * the actual \0 at the end of the destination buffer, we need to + * append it manually. First make room for it... + */ - dstLen--; + dstLen--; + } result = encodingPtr->toUtfProc(encodingPtr->clientData, src, srcLen, flags, statePtr, dst, dstLen, srcReadPtr, dstWrotePtr, dstCharsPtr); - dst[*dstWrotePtr] = '\0'; + if (!noTerminate) { + /* ...and then append it */ + + dst[*dstWrotePtr] = '\0'; + } return result; } diff --git a/generic/tclIO.c b/generic/tclIO.c index 2025742..b759c0e 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -4578,14 +4578,14 @@ Tcl_GetsObj( * Skip the raw bytes that make up the '\n'. */ - char tmp[1 + TCL_UTF_MAX]; + char tmp[TCL_UTF_MAX]; int rawRead; bufPtr = gs.bufPtr; Tcl_ExternalToUtf(NULL, gs.encoding, RemovePoint(bufPtr), - gs.rawRead, statePtr->inputEncodingFlags, - &gs.state, tmp, 1 + TCL_UTF_MAX, &rawRead, NULL, - NULL); + gs.rawRead, statePtr->inputEncodingFlags + | TCL_ENCODING_NO_TERMINATE, &gs.state, tmp, + TCL_UTF_MAX, &rawRead, NULL, NULL); bufPtr->nextRemoved += rawRead; gs.rawRead -= rawRead; gs.bytesWrote--; @@ -4686,8 +4686,9 @@ Tcl_GetsObj( } statePtr->inputEncodingState = gs.state; Tcl_ExternalToUtf(NULL, gs.encoding, RemovePoint(bufPtr), gs.rawRead, - statePtr->inputEncodingFlags, &statePtr->inputEncodingState, dst, - eol - dst + skip + TCL_UTF_MAX, &gs.rawRead, NULL, + statePtr->inputEncodingFlags | TCL_ENCODING_NO_TERMINATE, + &statePtr->inputEncodingState, dst, + eol - dst + skip + TCL_UTF_MAX - 1, &gs.rawRead, NULL, &gs.charsWrote); bufPtr->nextRemoved += gs.rawRead; @@ -5219,9 +5220,9 @@ FilterInputBytes( } gsPtr->state = statePtr->inputEncodingState; result = Tcl_ExternalToUtf(NULL, gsPtr->encoding, raw, rawLen, - statePtr->inputEncodingFlags, &statePtr->inputEncodingState, - dst, spaceLeft+1, &gsPtr->rawRead, &gsPtr->bytesWrote, - &gsPtr->charsWrote); + statePtr->inputEncodingFlags | TCL_ENCODING_NO_TERMINATE, + &statePtr->inputEncodingState, dst, spaceLeft, &gsPtr->rawRead, + &gsPtr->bytesWrote, &gsPtr->charsWrote); /* * Make sure that if we go through 'gets', that we reset the @@ -5975,7 +5976,7 @@ ReadChars( * a consistent set of results. This takes the shape of a loop. */ - dstLimit = dstNeeded + 1; + dstLimit = dstNeeded; while (1) { int dstDecoded, dstRead, dstWrote, srcRead, numChars; @@ -5985,9 +5986,10 @@ ReadChars( */ int code = Tcl_ExternalToUtf(NULL, encoding, src, srcLen, - statePtr->inputEncodingFlags & (bufPtr->nextPtr - ? ~0 : ~TCL_ENCODING_END), &statePtr->inputEncodingState, - dst, dstLimit, &srcRead, &dstDecoded, &numChars); + (statePtr->inputEncodingFlags | TCL_ENCODING_NO_TERMINATE) + & (bufPtr->nextPtr ? ~0 : ~TCL_ENCODING_END), + &statePtr->inputEncodingState, dst, dstLimit, &srcRead, + &dstDecoded, &numChars); /* * Perform the translation transformation in place. Read no more @@ -6050,7 +6052,7 @@ ReadChars( * time. */ - dstLimit = dstRead + TCL_UTF_MAX; + dstLimit = dstRead - 1 + TCL_UTF_MAX; statePtr->flags = savedFlags; statePtr->inputEncodingFlags = savedIEFlags; statePtr->inputEncodingState = savedState; @@ -6076,7 +6078,7 @@ ReadChars( * up back here in this call. */ - dstLimit = dstRead + TCL_UTF_MAX; + dstLimit = dstRead - 1 + TCL_UTF_MAX; statePtr->flags = savedFlags; statePtr->inputEncodingFlags = savedIEFlags; statePtr->inputEncodingState = savedState; @@ -6093,7 +6095,7 @@ ReadChars( */ if (code != TCL_OK) { - char buffer[TCL_UTF_MAX + 2]; + char buffer[TCL_UTF_MAX + 1]; int read, decoded, count; /* @@ -6105,9 +6107,10 @@ ReadChars( statePtr->inputEncodingState = savedState; Tcl_ExternalToUtf(NULL, encoding, src, srcLen, - statePtr->inputEncodingFlags & (bufPtr->nextPtr - ? ~0 : ~TCL_ENCODING_END), &statePtr->inputEncodingState, - buffer, TCL_UTF_MAX + 2, &read, &decoded, &count); + (statePtr->inputEncodingFlags | TCL_ENCODING_NO_TERMINATE) + & (bufPtr->nextPtr ? ~0 : ~TCL_ENCODING_END), + &statePtr->inputEncodingState, buffer, TCL_UTF_MAX + 1, + &read, &decoded, &count); if (count == 2) { if (buffer[1] == '\n') { @@ -6119,7 +6122,6 @@ ReadChars( bufPtr->nextRemoved += srcRead; } - dst[1] = '\0'; statePtr->inputEncodingFlags &= ~TCL_ENCODING_START; Tcl_SetObjLength(objPtr, numBytes + 1); @@ -6166,7 +6168,7 @@ ReadChars( * Tcl_ExternalToUtf() call! */ - dstLimit = Tcl_UtfAtIndex(dst, charsToRead) + TCL_UTF_MAX - dst; + dstLimit = Tcl_UtfAtIndex(dst, charsToRead) - 1 + TCL_UTF_MAX - dst; statePtr->flags = savedFlags; statePtr->inputEncodingFlags = savedIEFlags; statePtr->inputEncodingState = savedState; -- cgit v0.12 From 3185389da2f0df0ad90dc3564934575fcfa7dca5 Mon Sep 17 00:00:00 2001 From: dgp Date: Sat, 15 Nov 2014 21:13:52 +0000 Subject: With no padding needed for a terminating NUL, there no need for a distinction between the dstNeeded and dstLimit values. --- generic/tclIO.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index b759c0e..f8b9bfa 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -5929,7 +5929,7 @@ ReadChars( int savedIEFlags = statePtr->inputEncodingFlags; int savedFlags = statePtr->flags; char *dst, *src = RemovePoint(bufPtr); - int dstLimit, numBytes, srcLen = BytesLeft(bufPtr); + int numBytes, srcLen = BytesLeft(bufPtr); /* * One src byte can yield at most one character. So when the @@ -5948,14 +5948,14 @@ ReadChars( */ int factor = *factorPtr; - int dstNeeded = TCL_UTF_MAX - 1 + toRead * factor / UTF_EXPANSION_FACTOR; + int dstLimit = TCL_UTF_MAX - 1 + toRead * factor / UTF_EXPANSION_FACTOR; (void) TclGetStringFromObj(objPtr, &numBytes); - Tcl_AppendToObj(objPtr, NULL, dstNeeded); + Tcl_AppendToObj(objPtr, NULL, dstLimit); if (toRead == srcLen) { unsigned int size; dst = TclGetStringStorage(objPtr, &size) + numBytes; - dstNeeded = size - numBytes; + dstLimit = size - numBytes; } else { dst = TclGetString(objPtr) + numBytes; } @@ -5976,7 +5976,6 @@ ReadChars( * a consistent set of results. This takes the shape of a loop. */ - dstLimit = dstNeeded; while (1) { int dstDecoded, dstRead, dstWrote, srcRead, numChars; -- cgit v0.12 From 24d57ad4ffaf7d8caef8902d37021866e73f8dbf Mon Sep 17 00:00:00 2001 From: dgp Date: Sat, 15 Nov 2014 21:46:19 +0000 Subject: Add to Tcl_ExternalToUtf() a capability to impose a limit on the number of chars produce in the encoding result. When the flag TCL_ENCODING_CHAR_LIMIT is set and dstCharsPtr is not NULL, then the initial value of *dstCharsPtr is taken as the max number of chars to produce. The limit is imposed in a way that does not require the assistance of the encoding's driver procs, but the flag is passed on to them in case they can do better when they know they should. No callers updated yet. No drivers updated yet. One difficulty is that this necessarily imposes a pre-translation limit, and the I/O system has a history of wanting to impose only a post-translation limit. --- generic/tclEncoding.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/generic/tclEncoding.c b/generic/tclEncoding.c index 0446816..f33e0e6 100644 --- a/generic/tclEncoding.c +++ b/generic/tclEncoding.c @@ -1203,8 +1203,10 @@ Tcl_ExternalToUtf( * output buffer. */ { const Encoding *encodingPtr; - int result, srcRead, dstWrote, dstChars; + int result, srcRead, dstWrote, dstChars = 0; int noTerminate = flags & TCL_ENCODING_NO_TERMINATE; + int charLimited = (flags & TCL_ENCODING_CHAR_LIMIT) && dstCharsPtr; + int maxChars = INT_MAX; Tcl_EncodingState state; if (encoding == NULL) { @@ -1229,6 +1231,9 @@ Tcl_ExternalToUtf( } if (dstCharsPtr == NULL) { dstCharsPtr = &dstChars; + flags &= ~TCL_ENCODING_CHAR_LIMIT; + } else if (charLimited) { + maxChars = *dstCharsPtr; } if (!noTerminate) { @@ -1241,9 +1246,20 @@ Tcl_ExternalToUtf( dstLen--; } - result = encodingPtr->toUtfProc(encodingPtr->clientData, src, srcLen, - flags, statePtr, dst, dstLen, srcReadPtr, dstWrotePtr, - dstCharsPtr); + do { + int savedFlags = flags; + Tcl_EncodingState savedState = *statePtr; + + result = encodingPtr->toUtfProc(encodingPtr->clientData, src, srcLen, + flags, statePtr, dst, dstLen, srcReadPtr, dstWrotePtr, + dstCharsPtr); + if (*dstCharsPtr <= maxChars) { + break; + } + dstLen = Tcl_UtfAtIndex(dst, maxChars) - 1 - dst + TCL_UTF_MAX; + flags = savedFlags; + *statePtr = savedState; + } while (1); if (!noTerminate) { /* ...and then append it */ -- cgit v0.12 From 2b3e4035506666e8a68af0748051d9798b08afca Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Fri, 21 Nov 2014 13:05:31 +0000 Subject: Fix [743338466549f09e3956d8a86e6f9a8030f227cb|7433384665]: socket error encoding bug. --- generic/tclIOSock.c | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/generic/tclIOSock.c b/generic/tclIOSock.c index 694501f..f69d30f 100644 --- a/generic/tclIOSock.c +++ b/generic/tclIOSock.c @@ -12,9 +12,26 @@ #include "tclInt.h" #if defined(_WIN32) && defined(UNICODE) -/* On Windows, we always need the ASCII version. */ -# undef gai_strerror -# define gai_strerror gai_strerrorA +/* On Windows, we need to do proper Unicode->UTF-8 conversion. */ + +typedef struct ThreadSpecificData { + int initialized; + Tcl_DString errorMsg; /* UTF-8 encoded error-message */ +} ThreadSpecificData; +static Tcl_ThreadDataKey dataKey; + +#undef gai_strerror +static const char *gai_strerror(int code) { + ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); + + if (tsdPtr->initialized) { + Tcl_DStringFree(&tsdPtr->errorMsg); + } else { + tsdPtr->initialized = 1; + } + Tcl_WinTCharToUtf(gai_strerrorW(code), -1, &tsdPtr->errorMsg); + return Tcl_DStringValue(&tsdPtr->errorMsg); +} #endif /* -- cgit v0.12 From 484de8b9879c4344a7f31bf0940aa2eaf943d30f Mon Sep 17 00:00:00 2001 From: dgp Date: Mon, 24 Nov 2014 03:00:03 +0000 Subject: [e087812465] Trim back operatorStrings array to just the entries that are needed. Trims away the part of the array that was out of sync with the opcodes. --- generic/tclExecute.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/generic/tclExecute.c b/generic/tclExecute.c index c4f9836..b9415e5 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -75,9 +75,7 @@ int tclTraceExec = 0; static const char *const operatorStrings[] = { "||", "&&", "|", "^", "&", "==", "!=", "<", ">", "<=", ">=", "<<", ">>", - "+", "-", "*", "/", "%", "+", "-", "~", "!", - "BUILTIN FUNCTION", "FUNCTION", - "", "", "", "", "", "", "", "", "eq", "ne" + "+", "-", "*", "/", "%", "+", "-", "~", "!" }; /* @@ -7714,7 +7712,7 @@ IllegalExprOperandType( if (opcode == INST_EXPON) { operator = "**"; - } else if (opcode <= INST_STR_NEQ) { + } else if (opcode <= INST_LNOT) { operator = operatorStrings[opcode - INST_LOR]; } -- cgit v0.12 From d9465a5be23e98e24bdbbc57ffee7b9459a565f8 Mon Sep 17 00:00:00 2001 From: dgp Date: Tue, 25 Nov 2014 21:24:06 +0000 Subject: One way to fix the parser of $-substitution accepting non-ASCII varnames. --- generic/tclParse.c | 3 +++ tests/parse.test | 3 +++ 2 files changed, 6 insertions(+) diff --git a/generic/tclParse.c b/generic/tclParse.c index e475fb8..1523eb3 100644 --- a/generic/tclParse.c +++ b/generic/tclParse.c @@ -1438,6 +1438,9 @@ Tcl_ParseVarName( offset = Tcl_UtfToUniChar(utfBytes, &ch); } c = UCHAR(ch); + if (c != ch) { + break; + } if (isalnum(c) || (c == '_')) { /* INTL: ISO only, UCHAR. */ src += offset; numBytes -= offset; diff --git a/tests/parse.test b/tests/parse.test index d7de5ff..cd02386 100644 --- a/tests/parse.test +++ b/tests/parse.test @@ -656,6 +656,9 @@ test parse-12.24 {Tcl_ParseVarName procedure, missing close paren in array refer test parse-12.25 {Tcl_ParseVarName procedure, nested array reference} testparser { testparser {$x(a$y(b$z))} 0 } {- {$x(a$y(b$z))} 1 word {$x(a$y(b$z))} 8 variable {$x(a$y(b$z))} 7 text x 0 text a 0 variable {$y(b$z)} 4 text y 0 text b 0 variable {$z} 1 text z 0 {}} +test parse-12.26 {Tcl_ParseVarName [d2ffcca163] non-ascii} testparser { + testparser "$\u0433" -1 +} "- {$\u0433} 1 word {$\u0433} 2 text {$} 0 text \u0433 0 {}" test parse-13.1 {Tcl_ParseVar procedure} testparsevar { set abc 24 -- cgit v0.12 From 92402afe21c8b0391c1727986781792eff7dbe86 Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 26 Nov 2014 16:22:40 +0000 Subject: I like this patch better. Retain the byte orientation of the parser. --- generic/tclParse.c | 21 ++++----------------- 1 file changed, 4 insertions(+), 17 deletions(-) diff --git a/generic/tclParse.c b/generic/tclParse.c index 1523eb3..90ec43d 100644 --- a/generic/tclParse.c +++ b/generic/tclParse.c @@ -1344,8 +1344,7 @@ Tcl_ParseVarName( Tcl_Token *tokenPtr; register const char *src; unsigned char c; - int varIndex, offset; - Tcl_UniChar ch; + int varIndex; unsigned array; if ((numBytes == 0) || (start == NULL)) { @@ -1428,22 +1427,10 @@ Tcl_ParseVarName( tokenPtr->numComponents = 0; while (numBytes) { - if (Tcl_UtfCharComplete(src, numBytes)) { - offset = Tcl_UtfToUniChar(src, &ch); - } else { - char utfBytes[TCL_UTF_MAX]; - - memcpy(utfBytes, src, (size_t) numBytes); - utfBytes[numBytes] = '\0'; - offset = Tcl_UtfToUniChar(utfBytes, &ch); - } - c = UCHAR(ch); - if (c != ch) { - break; - } + c = UCHAR(*src); if (isalnum(c) || (c == '_')) { /* INTL: ISO only, UCHAR. */ - src += offset; - numBytes -= offset; + src += 1; + numBytes -= 1; continue; } if ((c == ':') && (numBytes != 1) && (src[1] == ':')) { -- cgit v0.12 From 03f0d60f88e00392c71063d8617a35c685d2c474 Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 26 Nov 2014 17:00:55 +0000 Subject: Same issue in expr parser also tested and fixed. --- generic/tclCompExpr.c | 32 ++++++++++++-------------------- tests/parseExpr.test | 6 ++++++ 2 files changed, 18 insertions(+), 20 deletions(-) diff --git a/generic/tclCompExpr.c b/generic/tclCompExpr.c index 9142e2b..dde4e56 100644 --- a/generic/tclCompExpr.c +++ b/generic/tclCompExpr.c @@ -1969,31 +1969,23 @@ ParseLexeme( } } - if (Tcl_UtfCharComplete(start, numBytes)) { - scanned = Tcl_UtfToUniChar(start, &ch); - } else { - char utfBytes[TCL_UTF_MAX]; - memcpy(utfBytes, start, (size_t) numBytes); - utfBytes[numBytes] = '\0'; - scanned = Tcl_UtfToUniChar(utfBytes, &ch); - } - if (!isalnum(UCHAR(ch))) { - *lexemePtr = INVALID; - Tcl_DecrRefCount(literal); - return scanned; - } - end = start; - while (isalnum(UCHAR(ch)) || (UCHAR(ch) == '_')) { - end += scanned; - numBytes -= scanned; - if (Tcl_UtfCharComplete(end, numBytes)) { - scanned = Tcl_UtfToUniChar(end, &ch); + if (!isalnum(UCHAR(*start))) { + if (Tcl_UtfCharComplete(start, numBytes)) { + scanned = Tcl_UtfToUniChar(start, &ch); } else { char utfBytes[TCL_UTF_MAX]; - memcpy(utfBytes, end, (size_t) numBytes); + memcpy(utfBytes, start, (size_t) numBytes); utfBytes[numBytes] = '\0'; scanned = Tcl_UtfToUniChar(utfBytes, &ch); } + *lexemePtr = INVALID; + Tcl_DecrRefCount(literal); + return scanned; + } + end = start; + while (numBytes && (isalnum(UCHAR(*end)) || (UCHAR(*end) == '_'))) { + end += 1; + numBytes -= 1; } *lexemePtr = BAREWORD; if (literalPtr) { diff --git a/tests/parseExpr.test b/tests/parseExpr.test index c1c489b..3e0df29 100644 --- a/tests/parseExpr.test +++ b/tests/parseExpr.test @@ -1051,6 +1051,12 @@ test parseExpr-22.18 {Bug 3401704} -constraints testexprparser -body { testexprparser 0b02 -1 } -returnCodes error -match glob -result {*invalid binary number*} +test parseExpr-22.19 {Bug d2ffcca163} -constraints testexprparser -body { + testexprparser \u0433 -1 +} -returnCodes error -match glob -result {*invalid character*} +test parseExpr-22.20 {Bug d2ffcca163} -constraints testexprparser -body { + testexprparser \u043f -1 +} -returnCodes error -match glob -result {*invalid character*} # cleanup cleanupTests -- cgit v0.12 From d7cf041bab9ace3408763b9c55dcc337e53d4600 Mon Sep 17 00:00:00 2001 From: andreask Date: Mon, 1 Dec 2014 20:17:04 +0000 Subject: Fix missing export of the "NewForeachInfoType" AuxData structure for tbcload/tclcompiler packages. --- generic/tclCompile.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/generic/tclCompile.c b/generic/tclCompile.c index 3736498..0f4dfaf 100644 --- a/generic/tclCompile.c +++ b/generic/tclCompile.c @@ -4342,10 +4342,11 @@ TclInitAuxDataTypeTable(void) Tcl_InitHashTable(&auxDataTypeTable, TCL_STRING_KEYS); /* - * There are only three AuxData types at this time, so register them here. + * There are only four AuxData types at this time, so register them here. */ RegisterAuxDataType(&tclForeachInfoType); + RegisterAuxDataType(&tclNewForeachInfoType); RegisterAuxDataType(&tclJumptableInfoType); RegisterAuxDataType(&tclDictUpdateInfoType); } -- cgit v0.12 From 730a9a132cbd0a3b3ff36b842957b1cda50ed3a6 Mon Sep 17 00:00:00 2001 From: Miguel Sofer Date: Wed, 3 Dec 2014 13:22:53 +0000 Subject: adding a test for the bug --- tests/compile.test | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/tests/compile.test b/tests/compile.test index 22ebc7d..8150622 100644 --- a/tests/compile.test +++ b/tests/compile.test @@ -455,14 +455,22 @@ test compile-13.1 {testing underestimate of maxStackSize in list cmd} {exec} { list [catch {exec [interpreter] << $script} msg] $msg } {0 OK} -# Special test for compiling tokens from a copy of the source string. [Bug -# 599788] +# Tests compile-14.* for compiling tokens from a copy of the source string. +# [Bug 599788] [Bug 0c043a175a47da8c2342] test compile-14.1 {testing errors in element name; segfault?} {} { catch {set a([error])} msg1 catch {set bubba([join $abba $jubba]) $vol} msg2 list $msg1 $msg2 } {{wrong # args: should be "error message ?errorInfo? ?errorCode?"} {can't read "abba": no such variable}} +test compile-14.2 {testing element name "$"} -body { + unset a + set a() 1 + set a($) 2 + list [set a()] [set a($)] [unset a(); lindex [array names a] 0] +} -cleanup {unset a} -result {1 2 $} + + # Tests compile-15.* cover Tcl Bug 633204 test compile-15.1 {proper TCL_RETURN code from [return]} { apply {{} {catch return}} -- cgit v0.12 From 58cd08bb7d984dd94fd4b1203984f24d5b2c5484 Mon Sep 17 00:00:00 2001 From: dkf Date: Wed, 3 Dec 2014 23:05:15 +0000 Subject: [0dca3bfa8f] Strengthen validity checks on fast-path string comparison. --- generic/tclExecute.c | 8 +++++--- tests/stringComp.test | 8 ++++++++ 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/generic/tclExecute.c b/generic/tclExecute.c index 337a75f..b9da8fc 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -5410,8 +5410,8 @@ TEBCresume( s1 = (char *) Tcl_GetByteArrayFromObj(valuePtr, &s1len); s2 = (char *) Tcl_GetByteArrayFromObj(value2Ptr, &s2len); memCmpFn = memcmp; - } else if (((valuePtr->typePtr == &tclStringType) - && (value2Ptr->typePtr == &tclStringType))) { + } else if ((valuePtr->typePtr == &tclStringType) + && (value2Ptr->typePtr == &tclStringType)) { /* * Do a unicode-specific comparison if both of the args are of * String type. If the char length == byte length, we can do a @@ -5422,7 +5422,9 @@ TEBCresume( s1len = Tcl_GetCharLength(valuePtr); s2len = Tcl_GetCharLength(value2Ptr); if ((s1len == valuePtr->length) - && (s2len == value2Ptr->length)) { + && (valuePtr->bytes != NULL) + && (s2len == value2Ptr->length) + && (value2Ptr->bytes != NULL)) { s1 = valuePtr->bytes; s2 = value2Ptr->bytes; memCmpFn = memcmp; diff --git a/tests/stringComp.test b/tests/stringComp.test index f9f6bda..a66525e 100644 --- a/tests/stringComp.test +++ b/tests/stringComp.test @@ -720,6 +720,14 @@ test stringComp-14.2 {Bug 82e7f67325} memory { }} {a b} } } {0} +test stringComp-14.3 {Bug 0dca3bfa8f} { + apply {arg { + set argCopy $arg + set arg [string replace $arg 1 2 aa] + # Crashes in comparison before fix + expr {$arg ne $argCopy} + }} abcde +} 1 ## string tolower ## not yet bc -- cgit v0.12 From 8694763c10584bbaed0097318fcaa55a7b86425a Mon Sep 17 00:00:00 2001 From: Miguel Sofer Date: Wed, 3 Dec 2014 23:17:16 +0000 Subject: test and fix (thx dgp) --- generic/tclCompCmds.c | 2 +- tests/compile.test | 9 +++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/generic/tclCompCmds.c b/generic/tclCompCmds.c index 18f4564..4e7ef97 100644 --- a/generic/tclCompCmds.c +++ b/generic/tclCompCmds.c @@ -3373,7 +3373,7 @@ TclPushVarName( nameChars = p - varTokenPtr[1].start; elName = p + 1; remainingChars = (varTokenPtr[2].start - p) - 1; - elNameChars = (varTokenPtr[n].start-p) + varTokenPtr[n].size - 2; + elNameChars = (varTokenPtr[n].start-p) + varTokenPtr[n].size - 1; if (remainingChars) { /* diff --git a/tests/compile.test b/tests/compile.test index 8150622..45d69e9 100644 --- a/tests/compile.test +++ b/tests/compile.test @@ -464,11 +464,12 @@ test compile-14.1 {testing errors in element name; segfault?} {} { } {{wrong # args: should be "error message ?errorInfo? ?errorCode?"} {can't read "abba": no such variable}} test compile-14.2 {testing element name "$"} -body { - unset a + unset -nocomplain a set a() 1 - set a($) 2 - list [set a()] [set a($)] [unset a(); lindex [array names a] 0] -} -cleanup {unset a} -result {1 2 $} + set a(1) 2 + set a($) 3 + list [set a()] [set a(1)] [set a($)] [unset a(); lindex [array names a] 0] +} -cleanup {unset a} -result [list 1 2 3 {$}] # Tests compile-15.* cover Tcl Bug 633204 -- cgit v0.12 From 0c0be357100d28784d29e88ef2af8e61ffd7aeb1 Mon Sep 17 00:00:00 2001 From: Miguel Sofer Date: Wed, 3 Dec 2014 23:34:36 +0000 Subject: missing unset in new test --- tests/compile.test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/compile.test b/tests/compile.test index 45d69e9..7335293 100644 --- a/tests/compile.test +++ b/tests/compile.test @@ -468,7 +468,7 @@ test compile-14.2 {testing element name "$"} -body { set a() 1 set a(1) 2 set a($) 3 - list [set a()] [set a(1)] [set a($)] [unset a(); lindex [array names a] 0] + list [set a()] [set a(1)] [set a($)] [unset a() a(1); lindex [array names a] 0] } -cleanup {unset a} -result [list 1 2 3 {$}] -- cgit v0.12 From 7dfd9c5a9656fd1b66fcdc8111b3b49f7d3e1f8a Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 3 Dec 2014 23:54:16 +0000 Subject: Now make the patch by hand that fossil could not merge. --- tests/compile.test | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/compile.test b/tests/compile.test index 7335293..d4a31d4 100644 --- a/tests/compile.test +++ b/tests/compile.test @@ -455,8 +455,7 @@ test compile-13.1 {testing underestimate of maxStackSize in list cmd} {exec} { list [catch {exec [interpreter] << $script} msg] $msg } {0 OK} -# Tests compile-14.* for compiling tokens from a copy of the source string. -# [Bug 599788] [Bug 0c043a175a47da8c2342] +# Tests compile-14.* for [Bug 599788] [Bug 0c043a175a47da8c2342] test compile-14.1 {testing errors in element name; segfault?} {} { catch {set a([error])} msg1 catch {set bubba([join $abba $jubba]) $vol} msg2 -- cgit v0.12 From dd4c175c818027548fd867fe331db5239880b1fd Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 4 Dec 2014 18:26:31 +0000 Subject: Stop using isalnum(.). Its results are not portable. Replace with our own private routine TclIsBareword() that does exactly what we want. --- generic/tclCompExpr.c | 15 ++++++++++----- generic/tclInt.h | 1 + generic/tclParse.c | 47 +++++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 54 insertions(+), 9 deletions(-) diff --git a/generic/tclCompExpr.c b/generic/tclCompExpr.c index dde4e56..2470931 100644 --- a/generic/tclCompExpr.c +++ b/generic/tclCompExpr.c @@ -1920,8 +1920,7 @@ ParseLexeme( literal = Tcl_NewObj(); if (TclParseNumber(NULL, literal, NULL, start, numBytes, &end, TCL_PARSE_NO_WHITESPACE) == TCL_OK) { - if (end < start + numBytes && !isalnum(UCHAR(*end)) - && UCHAR(*end) != '_') { + if (end < start + numBytes && !TclIsBareword(*end)) { number: TclInitStringRep(literal, start, end-start); @@ -1945,7 +1944,7 @@ ParseLexeme( if (literal->typePtr == &tclDoubleType) { const char *p = start; while (p < end) { - if (!isalnum(UCHAR(*p++))) { + if (!TclIsBareword(*p++)) { /* * The number has non-bareword characters, so we * must treat it as a number. @@ -1969,7 +1968,13 @@ ParseLexeme( } } - if (!isalnum(UCHAR(*start))) { + /* + * We reject leading underscores in bareword. No sensible reason why. + * Might be inspired by reserved identifier rules in C, which of course + * have no direct relevance here. + */ + + if (!TclIsBareword(*start) || *start == '_') { if (Tcl_UtfCharComplete(start, numBytes)) { scanned = Tcl_UtfToUniChar(start, &ch); } else { @@ -1983,7 +1988,7 @@ ParseLexeme( return scanned; } end = start; - while (numBytes && (isalnum(UCHAR(*end)) || (UCHAR(*end) == '_'))) { + while (numBytes && TclIsBareword(*end)) { end += 1; numBytes -= 1; } diff --git a/generic/tclInt.h b/generic/tclInt.h index dd66d76..255ee23 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -2608,6 +2608,7 @@ MODULE_SCOPE void TclInitSubsystems(void); MODULE_SCOPE int TclInterpReady(Tcl_Interp *interp); MODULE_SCOPE int TclIsLocalScalar(const char *src, int len); MODULE_SCOPE int TclIsSpaceProc(char byte); +MODULE_SCOPE int TclIsBareword(char byte); MODULE_SCOPE int TclJoinThread(Tcl_ThreadId id, int *result); MODULE_SCOPE void TclLimitRemoveAllHandlers(Tcl_Interp *interp); MODULE_SCOPE Tcl_Obj * TclLindexList(Tcl_Interp *interp, diff --git a/generic/tclParse.c b/generic/tclParse.c index 90ec43d..025304c 100644 --- a/generic/tclParse.c +++ b/generic/tclParse.c @@ -628,6 +628,47 @@ TclIsSpaceProc( /* *---------------------------------------------------------------------- * + * TclIsBareword-- + * + * Report whether byte is one that can be part of a "bareword". + * This concept is named in expression parsing, where it determines + * what can be a legal function name, but is the same definition used + * in determining what variable names can be parsed as variable + * substitutions without the benefit of enclosing braces. The set of + * ASCII chars that are accepted are the numeric chars ('0'-'9'), + * the alphabetic chars ('a'-'z', 'A'-'Z') and underscore ('_'). + * + * Results: + * Returns 1, if byte is in the accepted set of chars, 0 otherwise. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +int +TclIsBareword( + char byte) +{ + if (byte < '0' || byte > 'z') { + return 0; + } + if (byte <= '9' || byte >= 'a') { + return 1; + } + if (byte == '_') { + return 1; + } + if (byte < 'A' || byte > 'Z') { + return 0; + } + return 1; +} + +/* + *---------------------------------------------------------------------- + * * ParseWhiteSpace -- * * Scans up to numBytes bytes starting at src, consuming white space @@ -1343,7 +1384,6 @@ Tcl_ParseVarName( { Tcl_Token *tokenPtr; register const char *src; - unsigned char c; int varIndex; unsigned array; @@ -1427,13 +1467,12 @@ Tcl_ParseVarName( tokenPtr->numComponents = 0; while (numBytes) { - c = UCHAR(*src); - if (isalnum(c) || (c == '_')) { /* INTL: ISO only, UCHAR. */ + if (TclIsBareword(*src)) { src += 1; numBytes -= 1; continue; } - if ((c == ':') && (numBytes != 1) && (src[1] == ':')) { + if ((src[0] == ':') && (numBytes != 1) && (src[1] == ':')) { src += 2; numBytes -= 2; while (numBytes && (*src == ':')) { -- cgit v0.12 From 6d936db4a3aa4bed9449e2810de3dd9b20ecc6b2 Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 4 Dec 2014 20:45:11 +0000 Subject: The isalpha(.) calls remaining in the expr parser still bring nonportability. Commit a test that demonstrates that. --- tests/parseExpr.test | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/parseExpr.test b/tests/parseExpr.test index 3e0df29..c3b0d71 100644 --- a/tests/parseExpr.test +++ b/tests/parseExpr.test @@ -1057,6 +1057,9 @@ test parseExpr-22.19 {Bug d2ffcca163} -constraints testexprparser -body { test parseExpr-22.20 {Bug d2ffcca163} -constraints testexprparser -body { testexprparser \u043f -1 } -returnCodes error -match glob -result {*invalid character*} +test parseExpr-22.21 {Bug d2ffcca163} -constraints testexprparser -body { + testexprparser in\u0433(0) -1 +} -returnCodes error -match glob -result {missing operand*} # cleanup cleanupTests -- cgit v0.12 From 5c1b9fefdfb50cee5cd7d053101a033b2b6bb0d3 Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 4 Dec 2014 21:29:18 +0000 Subject: Limit isalpha(.) calls in the expr parser to only apply to known ASCII arguments to make the results portable. --- generic/tclCompExpr.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/generic/tclCompExpr.c b/generic/tclCompExpr.c index 2470931..7b67970 100644 --- a/generic/tclCompExpr.c +++ b/generic/tclCompExpr.c @@ -1883,7 +1883,7 @@ ParseLexeme( case 'i': if ((numBytes > 1) && (start[1] == 'n') - && ((numBytes == 2) || !isalpha(UCHAR(start[2])))) { + && ((numBytes == 2) || start[2] & 0x80 || !isalpha(start[2]))) { /* * Must make this check so we can tell the difference between @@ -1898,14 +1898,15 @@ ParseLexeme( case 'e': if ((numBytes > 1) && (start[1] == 'q') - && ((numBytes == 2) || !isalpha(UCHAR(start[2])))) { + && ((numBytes == 2) || start[2] & 0x80 || !isalpha(start[2]))) { *lexemePtr = STREQ; return 2; } break; case 'n': - if ((numBytes > 1) && ((numBytes == 2) || !isalpha(UCHAR(start[2])))) { + if ((numBytes > 1) + && ((numBytes == 2) || start[2] & 0x80 || !isalpha(start[2]))) { switch (start[1]) { case 'e': *lexemePtr = STRNEQ; -- cgit v0.12 From b52476a5cdc6924d597f7bc9dbd89f0717058009 Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 5 Dec 2014 21:05:17 +0000 Subject: Ever since (Tcl)PushVarName() stopped making a recursive call to Tcl_ParseCommand() (in the pre-8.4.0 timeframe), there's been no need for special protections for brace-quoted varname words. A simple word is a simple word is a simple word. --- generic/tclCompCmds.c | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/generic/tclCompCmds.c b/generic/tclCompCmds.c index 2f72263..c8ca828 100644 --- a/generic/tclCompCmds.c +++ b/generic/tclCompCmds.c @@ -4890,16 +4890,7 @@ PushVarName( nameChars = elNameChars = 0; localIndex = -1; - /* - * Check not only that the type is TCL_TOKEN_SIMPLE_WORD, but whether - * curly braces surround the variable name. This really matters for array - * elements to handle things like - * set {x($foo)} 5 - * which raises an undefined var error if we are not careful here. - */ - - if ((varTokenPtr->type == TCL_TOKEN_SIMPLE_WORD) && - (varTokenPtr->start[0] != '{')) { + if (varTokenPtr->type == TCL_TOKEN_SIMPLE_WORD) { /* * A simple variable name. Divide it up into "name" and "elName" * strings. If it is not a local variable, look it up at runtime. -- cgit v0.12 From 58bde2cb77be95dfc210c6b7448b9c82cf140025 Mon Sep 17 00:00:00 2001 From: ashok Date: Sat, 6 Dec 2014 11:19:32 +0000 Subject: Potential fix for [c6ed4acfd8]. Simple typo in original fix for [336441ed59]. Was looping on statePtr->next instead of statePtr2->next. Would result in an infinite loop. Definitely a bug but whether it completely fixes the above in all cases needs to be tested. --- win/tclWinSock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/win/tclWinSock.c b/win/tclWinSock.c index 2c58224..f5658ba 100644 --- a/win/tclWinSock.c +++ b/win/tclWinSock.c @@ -1739,7 +1739,7 @@ TcpConnect( */ for (statePtr2 = tsdPtr->socketList; statePtr2 != NULL; - statePtr2 = statePtr->nextPtr) { + statePtr2 = statePtr2->nextPtr) { if (statePtr2 == statePtr) { in_socket_list = 1; break; -- cgit v0.12 From 7466351c908df509ab68c9cd3fdafa793bebfc75 Mon Sep 17 00:00:00 2001 From: oehhar Date: Sun, 7 Dec 2014 12:17:24 +0000 Subject: test for bug [c6ed4acfd8]: running async socket connect with other connect established will block tcl as it goes in an infinite loop in vwait --- tests/socket.test | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/tests/socket.test b/tests/socket.test index eeea044..4f90e51 100644 --- a/tests/socket.test +++ b/tests/socket.test @@ -2343,6 +2343,24 @@ test socket-14.17 {empty -sockname while [socket -async] connecting} \ catch {close $client} } -result {} +# test for bug c6ed4acfd8: running async socket connect with other connect +# established will block tcl as it goes in an infinite loop in vwait +test socket-14.18 {bug c6ed4acfd8: running async socket connect made other connect block} \ + -constraints {socket} \ + -body { + proc accept {channel address port} {} + set port [randport] + set ssock [socket -server accept $port] + set csock1 [socket -async localhost [randport]] + set csock2 [socket localhost $port] + after 1000 {set done ok} + vwait done +} -cleanup { + catch {close $ssock} + catch {close $csock1} + catch {close $csock2} + } -result {} + set num 0 set x {localhost {socket} 127.0.0.1 {supported_inet} ::1 {supported_inet6}} -- cgit v0.12 From b27238fbbb6ee992d3f908e53606d862a8100c46 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Mon, 8 Dec 2014 16:05:19 +0000 Subject: Fix some gcc compiler warnings (probably cygwin-only) --- generic/tclCompExpr.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/generic/tclCompExpr.c b/generic/tclCompExpr.c index 7b67970..23dc0a4 100644 --- a/generic/tclCompExpr.c +++ b/generic/tclCompExpr.c @@ -1883,7 +1883,7 @@ ParseLexeme( case 'i': if ((numBytes > 1) && (start[1] == 'n') - && ((numBytes == 2) || start[2] & 0x80 || !isalpha(start[2]))) { + && ((numBytes == 2) || start[2] & 0x80 || !isalpha(UCHAR(start[2])))) { /* * Must make this check so we can tell the difference between @@ -1898,7 +1898,7 @@ ParseLexeme( case 'e': if ((numBytes > 1) && (start[1] == 'q') - && ((numBytes == 2) || start[2] & 0x80 || !isalpha(start[2]))) { + && ((numBytes == 2) || start[2] & 0x80 || !isalpha(UCHAR(start[2])))) { *lexemePtr = STREQ; return 2; } @@ -1906,7 +1906,7 @@ ParseLexeme( case 'n': if ((numBytes > 1) - && ((numBytes == 2) || start[2] & 0x80 || !isalpha(start[2]))) { + && ((numBytes == 2) || start[2] & 0x80 || !isalpha(UCHAR(start[2])))) { switch (start[1]) { case 'e': *lexemePtr = STRNEQ; -- cgit v0.12 From 916f1716f3f7dcdc6dc158c684aac96698e9e726 Mon Sep 17 00:00:00 2001 From: dgp Date: Tue, 9 Dec 2014 20:29:09 +0000 Subject: [e711ffb458] Replace TclIsLocalScalar() (which does the wrong thing).... with PushVarNameWord() (which doesn't) in the compiler for [dict lappend]. --- generic/tclCompCmds.c | 18 ++++++------------ generic/tclCompile.c | 4 ++-- 2 files changed, 8 insertions(+), 14 deletions(-) diff --git a/generic/tclCompCmds.c b/generic/tclCompCmds.c index c8ca828..7ecdc9b 100644 --- a/generic/tclCompCmds.c +++ b/generic/tclCompCmds.c @@ -1284,32 +1284,26 @@ TclCompileDictLappendCmd( * compiled. */ CompileEnv *envPtr) /* Holds resulting instructions. */ { - Proc *procPtr = envPtr->procPtr; - DefineLineInformation; /* TIP #280 */ Tcl_Token *varTokenPtr, *keyTokenPtr, *valueTokenPtr; - int dictVarIndex, nameChars; - const char *name; + int isSimple, dictVarIndex = -1, isScalar = 0; + DefineLineInformation; /* TIP #280 */ /* * There must be three arguments after the command. */ - if (parsePtr->numWords != 4 || procPtr == NULL) { + if (parsePtr->numWords != 4) { return TCL_ERROR; } varTokenPtr = TokenAfter(parsePtr->tokenPtr); keyTokenPtr = TokenAfter(varTokenPtr); valueTokenPtr = TokenAfter(keyTokenPtr); - if (varTokenPtr->type != TCL_TOKEN_SIMPLE_WORD) { - return TCL_ERROR; - } - name = varTokenPtr[1].start; - nameChars = varTokenPtr[1].size; - if (!TclIsLocalScalar(name, nameChars)) { + PushVarNameWord(interp, varTokenPtr, envPtr, TCL_CREATE_VAR, + &dictVarIndex, &isSimple, &isScalar, 1); + if (!isScalar || dictVarIndex < 0) { return TCL_ERROR; } - dictVarIndex = TclFindCompiledLocal(name, nameChars, 1, procPtr); CompileWord(envPtr, keyTokenPtr, interp, 2); CompileWord(envPtr, valueTokenPtr, interp, 3); TclEmitInstInt4( INST_DICT_LAPPEND, dictVarIndex, envPtr); diff --git a/generic/tclCompile.c b/generic/tclCompile.c index f982359..5030f89 100644 --- a/generic/tclCompile.c +++ b/generic/tclCompile.c @@ -2288,8 +2288,8 @@ TclFindCompiledLocal( * scalar or array variable. If NULL, a * temporary var should be created. */ int nameBytes, /* Number of bytes in the name. */ - int create, /* If 1, allocate a local frame entry for the - * variable if it is new. */ + int create, /* If non-zero, allocate a local frame entry + * for the variable if it is new. */ register Proc *procPtr) /* Points to structure describing procedure * containing the variable reference. */ { -- cgit v0.12 From 2d415cbf59016e2af60ee20e8b75f9cb26103aed Mon Sep 17 00:00:00 2001 From: dgp Date: Tue, 9 Dec 2014 20:45:30 +0000 Subject: [e711ffb458] Replace TclIsLocalScalar() with PushVarNameWord() in the compiler for [dict set]. --- generic/tclCompCmds.c | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/generic/tclCompCmds.c b/generic/tclCompCmds.c index 7ecdc9b..ec22f65 100644 --- a/generic/tclCompCmds.c +++ b/generic/tclCompCmds.c @@ -683,17 +683,15 @@ TclCompileDictSetCmd( CompileEnv *envPtr) /* Holds resulting instructions. */ { Tcl_Token *tokenPtr; - Proc *procPtr = envPtr->procPtr; - DefineLineInformation; /* TIP #280 */ Tcl_Token *varTokenPtr; - int i, dictVarIndex, nameChars; - const char *name; + int i, isSimple, isScalar = 0, dictVarIndex = -1; + DefineLineInformation; /* TIP #280 */ /* - * There must be at least one argument after the command. + * There must be at least three arguments after the (sub-)command. */ - if (parsePtr->numWords < 4 || procPtr == NULL) { + if (parsePtr->numWords < 4) { return TCL_ERROR; } @@ -704,15 +702,11 @@ TclCompileDictSetCmd( */ varTokenPtr = TokenAfter(parsePtr->tokenPtr); - if (varTokenPtr->type != TCL_TOKEN_SIMPLE_WORD) { - return TCL_ERROR; - } - name = varTokenPtr[1].start; - nameChars = varTokenPtr[1].size; - if (!TclIsLocalScalar(name, nameChars)) { + PushVarNameWord(interp, varTokenPtr, envPtr, TCL_CREATE_VAR, + &dictVarIndex, &isSimple, &isScalar, 1); + if (!isScalar || dictVarIndex < 0) { return TCL_ERROR; } - dictVarIndex = TclFindCompiledLocal(name, nameChars, 1, procPtr); /* * Remaining words (key path and value to set) can be handled normally. -- cgit v0.12 From 704532c57a71d3fbf3bb41e8de6896c3da9b01b6 Mon Sep 17 00:00:00 2001 From: venkat Date: Wed, 10 Dec 2014 00:35:37 +0000 Subject: tzdata2014j from ietf.org --- library/tzdata/Africa/Addis_Ababa | 8 +- library/tzdata/Africa/Asmara | 9 +- library/tzdata/Africa/Bangui | 7 +- library/tzdata/Africa/Bissau | 2 +- library/tzdata/Africa/Blantyre | 7 +- library/tzdata/Africa/Brazzaville | 7 +- library/tzdata/Africa/Bujumbura | 7 +- library/tzdata/Africa/Dar_es_Salaam | 9 +- library/tzdata/Africa/Djibouti | 7 +- library/tzdata/Africa/Douala | 7 +- library/tzdata/Africa/Gaborone | 10 +- library/tzdata/Africa/Harare | 7 +- library/tzdata/Africa/Kampala | 10 +- library/tzdata/Africa/Kigali | 7 +- library/tzdata/Africa/Kinshasa | 7 +- library/tzdata/Africa/Libreville | 7 +- library/tzdata/Africa/Luanda | 8 +- library/tzdata/Africa/Lubumbashi | 7 +- library/tzdata/Africa/Lusaka | 7 +- library/tzdata/Africa/Malabo | 8 +- library/tzdata/Africa/Maseru | 9 +- library/tzdata/Africa/Mbabane | 7 +- library/tzdata/Africa/Mogadishu | 9 +- library/tzdata/Africa/Niamey | 9 +- library/tzdata/Africa/Porto-Novo | 8 +- library/tzdata/America/Grand_Turk | 171 +----------------- library/tzdata/America/Jamaica | 3 +- library/tzdata/Antarctica/Troll | 196 +++++++++++++++++++++ library/tzdata/Asia/Chita | 71 ++++++++ library/tzdata/Asia/Dhaka | 2 +- library/tzdata/Asia/Ho_Chi_Minh | 13 +- library/tzdata/Asia/Irkutsk | 6 +- library/tzdata/Asia/Krasnoyarsk | 4 +- library/tzdata/Asia/Novokuznetsk | 4 +- library/tzdata/Asia/Omsk | 4 +- library/tzdata/Asia/Phnom_Penh | 10 +- library/tzdata/Asia/Pyongyang | 8 +- library/tzdata/Asia/Samarkand | 4 +- library/tzdata/Asia/Seoul | 33 ++-- library/tzdata/Asia/Srednekolymsk | 71 ++++++++ library/tzdata/Asia/Tbilisi | 6 +- library/tzdata/Asia/Vientiane | 10 +- library/tzdata/Asia/Vladivostok | 4 +- library/tzdata/Asia/Yakutsk | 4 +- library/tzdata/Asia/Yekaterinburg | 3 +- library/tzdata/Atlantic/Azores | 2 +- library/tzdata/Atlantic/Madeira | 2 +- library/tzdata/Europe/Lisbon | 6 +- library/tzdata/Europe/Minsk | 1 + library/tzdata/Europe/Riga | 14 +- library/tzdata/Europe/Samara | 4 +- library/tzdata/Indian/Antananarivo | 9 +- library/tzdata/Indian/Comoro | 7 +- library/tzdata/Indian/Mayotte | 7 +- library/tzdata/Pacific/Bougainville | 10 ++ library/tzdata/Pacific/Fiji | 342 ++++++++++++++++++------------------ 56 files changed, 678 insertions(+), 543 deletions(-) create mode 100644 library/tzdata/Antarctica/Troll create mode 100644 library/tzdata/Asia/Chita create mode 100644 library/tzdata/Asia/Srednekolymsk create mode 100644 library/tzdata/Pacific/Bougainville diff --git a/library/tzdata/Africa/Addis_Ababa b/library/tzdata/Africa/Addis_Ababa index 4b92483..7aa5653 100644 --- a/library/tzdata/Africa/Addis_Ababa +++ b/library/tzdata/Africa/Addis_Ababa @@ -1,7 +1,5 @@ # created by tools/tclZIC.tcl - do not edit - -set TZData(:Africa/Addis_Ababa) { - {-9223372036854775808 9288 0 LMT} - {-3155682888 9320 0 ADMT} - {-1062210920 10800 0 EAT} +if {![info exists TZData(Africa/Nairobi)]} { + LoadTimeZoneFile Africa/Nairobi } +set TZData(:Africa/Addis_Ababa) $TZData(:Africa/Nairobi) diff --git a/library/tzdata/Africa/Asmara b/library/tzdata/Africa/Asmara index 1f0f13e..3d33c94 100644 --- a/library/tzdata/Africa/Asmara +++ b/library/tzdata/Africa/Asmara @@ -1,8 +1,5 @@ # created by tools/tclZIC.tcl - do not edit - -set TZData(:Africa/Asmara) { - {-9223372036854775808 9332 0 LMT} - {-3155682932 9332 0 AMT} - {-2524530932 9320 0 ADMT} - {-1062210920 10800 0 EAT} +if {![info exists TZData(Africa/Nairobi)]} { + LoadTimeZoneFile Africa/Nairobi } +set TZData(:Africa/Asmara) $TZData(:Africa/Nairobi) diff --git a/library/tzdata/Africa/Bangui b/library/tzdata/Africa/Bangui index 94f5058..0326a6c 100644 --- a/library/tzdata/Africa/Bangui +++ b/library/tzdata/Africa/Bangui @@ -1,6 +1,5 @@ # created by tools/tclZIC.tcl - do not edit - -set TZData(:Africa/Bangui) { - {-9223372036854775808 4460 0 LMT} - {-1830388460 3600 0 WAT} +if {![info exists TZData(Africa/Lagos)]} { + LoadTimeZoneFile Africa/Lagos } +set TZData(:Africa/Bangui) $TZData(:Africa/Lagos) diff --git a/library/tzdata/Africa/Bissau b/library/tzdata/Africa/Bissau index d51cb9f..5693228 100644 --- a/library/tzdata/Africa/Bissau +++ b/library/tzdata/Africa/Bissau @@ -2,6 +2,6 @@ set TZData(:Africa/Bissau) { {-9223372036854775808 -3740 0 LMT} - {-1849388260 -3600 0 WAT} + {-1830380260 -3600 0 WAT} {157770000 0 0 GMT} } diff --git a/library/tzdata/Africa/Blantyre b/library/tzdata/Africa/Blantyre index 17b58f4..9a404c5 100644 --- a/library/tzdata/Africa/Blantyre +++ b/library/tzdata/Africa/Blantyre @@ -1,6 +1,5 @@ # created by tools/tclZIC.tcl - do not edit - -set TZData(:Africa/Blantyre) { - {-9223372036854775808 8400 0 LMT} - {-2109291600 7200 0 CAT} +if {![info exists TZData(Africa/Maputo)]} { + LoadTimeZoneFile Africa/Maputo } +set TZData(:Africa/Blantyre) $TZData(:Africa/Maputo) diff --git a/library/tzdata/Africa/Brazzaville b/library/tzdata/Africa/Brazzaville index b4e0923..111eff4 100644 --- a/library/tzdata/Africa/Brazzaville +++ b/library/tzdata/Africa/Brazzaville @@ -1,6 +1,5 @@ # created by tools/tclZIC.tcl - do not edit - -set TZData(:Africa/Brazzaville) { - {-9223372036854775808 3668 0 LMT} - {-1830387668 3600 0 WAT} +if {![info exists TZData(Africa/Lagos)]} { + LoadTimeZoneFile Africa/Lagos } +set TZData(:Africa/Brazzaville) $TZData(:Africa/Lagos) diff --git a/library/tzdata/Africa/Bujumbura b/library/tzdata/Africa/Bujumbura index c26d053..1e463d8 100644 --- a/library/tzdata/Africa/Bujumbura +++ b/library/tzdata/Africa/Bujumbura @@ -1,6 +1,5 @@ # created by tools/tclZIC.tcl - do not edit - -set TZData(:Africa/Bujumbura) { - {-9223372036854775808 7048 0 LMT} - {-2524528648 7200 0 CAT} +if {![info exists TZData(Africa/Maputo)]} { + LoadTimeZoneFile Africa/Maputo } +set TZData(:Africa/Bujumbura) $TZData(:Africa/Maputo) diff --git a/library/tzdata/Africa/Dar_es_Salaam b/library/tzdata/Africa/Dar_es_Salaam index 98151ec..00e8d4e 100644 --- a/library/tzdata/Africa/Dar_es_Salaam +++ b/library/tzdata/Africa/Dar_es_Salaam @@ -1,8 +1,5 @@ # created by tools/tclZIC.tcl - do not edit - -set TZData(:Africa/Dar_es_Salaam) { - {-9223372036854775808 9428 0 LMT} - {-1230777428 10800 0 EAT} - {-694321200 9900 0 BEAUT} - {-284006700 10800 0 EAT} +if {![info exists TZData(Africa/Nairobi)]} { + LoadTimeZoneFile Africa/Nairobi } +set TZData(:Africa/Dar_es_Salaam) $TZData(:Africa/Nairobi) diff --git a/library/tzdata/Africa/Djibouti b/library/tzdata/Africa/Djibouti index 0ec510c..859ea32 100644 --- a/library/tzdata/Africa/Djibouti +++ b/library/tzdata/Africa/Djibouti @@ -1,6 +1,5 @@ # created by tools/tclZIC.tcl - do not edit - -set TZData(:Africa/Djibouti) { - {-9223372036854775808 10356 0 LMT} - {-1846291956 10800 0 EAT} +if {![info exists TZData(Africa/Nairobi)]} { + LoadTimeZoneFile Africa/Nairobi } +set TZData(:Africa/Djibouti) $TZData(:Africa/Nairobi) diff --git a/library/tzdata/Africa/Douala b/library/tzdata/Africa/Douala index 301a530..892b16a 100644 --- a/library/tzdata/Africa/Douala +++ b/library/tzdata/Africa/Douala @@ -1,6 +1,5 @@ # created by tools/tclZIC.tcl - do not edit - -set TZData(:Africa/Douala) { - {-9223372036854775808 2328 0 LMT} - {-1830386328 3600 0 WAT} +if {![info exists TZData(Africa/Lagos)]} { + LoadTimeZoneFile Africa/Lagos } +set TZData(:Africa/Douala) $TZData(:Africa/Lagos) diff --git a/library/tzdata/Africa/Gaborone b/library/tzdata/Africa/Gaborone index bd38673..56c0772 100644 --- a/library/tzdata/Africa/Gaborone +++ b/library/tzdata/Africa/Gaborone @@ -1,9 +1,5 @@ # created by tools/tclZIC.tcl - do not edit - -set TZData(:Africa/Gaborone) { - {-9223372036854775808 6220 0 LMT} - {-2682294220 5400 0 SAST} - {-2109288600 7200 0 CAT} - {-829526400 10800 1 CAST} - {-813805200 7200 0 CAT} +if {![info exists TZData(Africa/Maputo)]} { + LoadTimeZoneFile Africa/Maputo } +set TZData(:Africa/Gaborone) $TZData(:Africa/Maputo) diff --git a/library/tzdata/Africa/Harare b/library/tzdata/Africa/Harare index 7482b15..644be26 100644 --- a/library/tzdata/Africa/Harare +++ b/library/tzdata/Africa/Harare @@ -1,6 +1,5 @@ # created by tools/tclZIC.tcl - do not edit - -set TZData(:Africa/Harare) { - {-9223372036854775808 7452 0 LMT} - {-2109290652 7200 0 CAT} +if {![info exists TZData(Africa/Maputo)]} { + LoadTimeZoneFile Africa/Maputo } +set TZData(:Africa/Harare) $TZData(:Africa/Maputo) diff --git a/library/tzdata/Africa/Kampala b/library/tzdata/Africa/Kampala index 4cc9be1..1fbaffc 100644 --- a/library/tzdata/Africa/Kampala +++ b/library/tzdata/Africa/Kampala @@ -1,9 +1,5 @@ # created by tools/tclZIC.tcl - do not edit - -set TZData(:Africa/Kampala) { - {-9223372036854775808 7780 0 LMT} - {-1309745380 10800 0 EAT} - {-1262314800 9000 0 BEAT} - {-694319400 9900 0 BEAUT} - {-410237100 10800 0 EAT} +if {![info exists TZData(Africa/Nairobi)]} { + LoadTimeZoneFile Africa/Nairobi } +set TZData(:Africa/Kampala) $TZData(:Africa/Nairobi) diff --git a/library/tzdata/Africa/Kigali b/library/tzdata/Africa/Kigali index f723bcd..192e0e8 100644 --- a/library/tzdata/Africa/Kigali +++ b/library/tzdata/Africa/Kigali @@ -1,6 +1,5 @@ # created by tools/tclZIC.tcl - do not edit - -set TZData(:Africa/Kigali) { - {-9223372036854775808 7216 0 LMT} - {-1091498416 7200 0 CAT} +if {![info exists TZData(Africa/Maputo)]} { + LoadTimeZoneFile Africa/Maputo } +set TZData(:Africa/Kigali) $TZData(:Africa/Maputo) diff --git a/library/tzdata/Africa/Kinshasa b/library/tzdata/Africa/Kinshasa index 050c1fa..04dc62e 100644 --- a/library/tzdata/Africa/Kinshasa +++ b/library/tzdata/Africa/Kinshasa @@ -1,6 +1,5 @@ # created by tools/tclZIC.tcl - do not edit - -set TZData(:Africa/Kinshasa) { - {-9223372036854775808 3672 0 LMT} - {-2276643672 3600 0 WAT} +if {![info exists TZData(Africa/Lagos)]} { + LoadTimeZoneFile Africa/Lagos } +set TZData(:Africa/Kinshasa) $TZData(:Africa/Lagos) diff --git a/library/tzdata/Africa/Libreville b/library/tzdata/Africa/Libreville index 8427551..ba1f686 100644 --- a/library/tzdata/Africa/Libreville +++ b/library/tzdata/Africa/Libreville @@ -1,6 +1,5 @@ # created by tools/tclZIC.tcl - do not edit - -set TZData(:Africa/Libreville) { - {-9223372036854775808 2268 0 LMT} - {-1830386268 3600 0 WAT} +if {![info exists TZData(Africa/Lagos)]} { + LoadTimeZoneFile Africa/Lagos } +set TZData(:Africa/Libreville) $TZData(:Africa/Lagos) diff --git a/library/tzdata/Africa/Luanda b/library/tzdata/Africa/Luanda index cd1b29e..8dcd107 100644 --- a/library/tzdata/Africa/Luanda +++ b/library/tzdata/Africa/Luanda @@ -1,7 +1,5 @@ # created by tools/tclZIC.tcl - do not edit - -set TZData(:Africa/Luanda) { - {-9223372036854775808 3176 0 LMT} - {-2461452776 3124 0 AOT} - {-1849395124 3600 0 WAT} +if {![info exists TZData(Africa/Lagos)]} { + LoadTimeZoneFile Africa/Lagos } +set TZData(:Africa/Luanda) $TZData(:Africa/Lagos) diff --git a/library/tzdata/Africa/Lubumbashi b/library/tzdata/Africa/Lubumbashi index bd67221..7da101a 100644 --- a/library/tzdata/Africa/Lubumbashi +++ b/library/tzdata/Africa/Lubumbashi @@ -1,6 +1,5 @@ # created by tools/tclZIC.tcl - do not edit - -set TZData(:Africa/Lubumbashi) { - {-9223372036854775808 6592 0 LMT} - {-2276646592 7200 0 CAT} +if {![info exists TZData(Africa/Maputo)]} { + LoadTimeZoneFile Africa/Maputo } +set TZData(:Africa/Lubumbashi) $TZData(:Africa/Maputo) diff --git a/library/tzdata/Africa/Lusaka b/library/tzdata/Africa/Lusaka index ed9c30d..bcf519d 100644 --- a/library/tzdata/Africa/Lusaka +++ b/library/tzdata/Africa/Lusaka @@ -1,6 +1,5 @@ # created by tools/tclZIC.tcl - do not edit - -set TZData(:Africa/Lusaka) { - {-9223372036854775808 6788 0 LMT} - {-2109289988 7200 0 CAT} +if {![info exists TZData(Africa/Maputo)]} { + LoadTimeZoneFile Africa/Maputo } +set TZData(:Africa/Lusaka) $TZData(:Africa/Maputo) diff --git a/library/tzdata/Africa/Malabo b/library/tzdata/Africa/Malabo index bec0524..7dcee39 100644 --- a/library/tzdata/Africa/Malabo +++ b/library/tzdata/Africa/Malabo @@ -1,7 +1,5 @@ # created by tools/tclZIC.tcl - do not edit - -set TZData(:Africa/Malabo) { - {-9223372036854775808 2108 0 LMT} - {-1830386108 0 0 GMT} - {-190857600 3600 0 WAT} +if {![info exists TZData(Africa/Lagos)]} { + LoadTimeZoneFile Africa/Lagos } +set TZData(:Africa/Malabo) $TZData(:Africa/Lagos) diff --git a/library/tzdata/Africa/Maseru b/library/tzdata/Africa/Maseru index 21ca968..665f15d 100644 --- a/library/tzdata/Africa/Maseru +++ b/library/tzdata/Africa/Maseru @@ -1,8 +1,5 @@ # created by tools/tclZIC.tcl - do not edit - -set TZData(:Africa/Maseru) { - {-9223372036854775808 6600 0 LMT} - {-2109289800 7200 0 SAST} - {-829526400 10800 1 SAST} - {-813805200 7200 0 SAST} +if {![info exists TZData(Africa/Johannesburg)]} { + LoadTimeZoneFile Africa/Johannesburg } +set TZData(:Africa/Maseru) $TZData(:Africa/Johannesburg) diff --git a/library/tzdata/Africa/Mbabane b/library/tzdata/Africa/Mbabane index 4d174d5..0edb590 100644 --- a/library/tzdata/Africa/Mbabane +++ b/library/tzdata/Africa/Mbabane @@ -1,6 +1,5 @@ # created by tools/tclZIC.tcl - do not edit - -set TZData(:Africa/Mbabane) { - {-9223372036854775808 7464 0 LMT} - {-2109290664 7200 0 SAST} +if {![info exists TZData(Africa/Johannesburg)]} { + LoadTimeZoneFile Africa/Johannesburg } +set TZData(:Africa/Mbabane) $TZData(:Africa/Johannesburg) diff --git a/library/tzdata/Africa/Mogadishu b/library/tzdata/Africa/Mogadishu index 570d3ea..4220655 100644 --- a/library/tzdata/Africa/Mogadishu +++ b/library/tzdata/Africa/Mogadishu @@ -1,8 +1,5 @@ # created by tools/tclZIC.tcl - do not edit - -set TZData(:Africa/Mogadishu) { - {-9223372036854775808 10888 0 LMT} - {-2403572488 10800 0 EAT} - {-1230778800 9000 0 BEAT} - {-410236200 10800 0 EAT} +if {![info exists TZData(Africa/Nairobi)]} { + LoadTimeZoneFile Africa/Nairobi } +set TZData(:Africa/Mogadishu) $TZData(:Africa/Nairobi) diff --git a/library/tzdata/Africa/Niamey b/library/tzdata/Africa/Niamey index 40ded06b..278571d 100644 --- a/library/tzdata/Africa/Niamey +++ b/library/tzdata/Africa/Niamey @@ -1,8 +1,5 @@ # created by tools/tclZIC.tcl - do not edit - -set TZData(:Africa/Niamey) { - {-9223372036854775808 508 0 LMT} - {-1830384508 -3600 0 WAT} - {-1131231600 0 0 GMT} - {-315619200 3600 0 WAT} +if {![info exists TZData(Africa/Lagos)]} { + LoadTimeZoneFile Africa/Lagos } +set TZData(:Africa/Niamey) $TZData(:Africa/Lagos) diff --git a/library/tzdata/Africa/Porto-Novo b/library/tzdata/Africa/Porto-Novo index b89cf1b..3fa2b51 100644 --- a/library/tzdata/Africa/Porto-Novo +++ b/library/tzdata/Africa/Porto-Novo @@ -1,7 +1,5 @@ # created by tools/tclZIC.tcl - do not edit - -set TZData(:Africa/Porto-Novo) { - {-9223372036854775808 628 0 LMT} - {-1830384628 0 0 GMT} - {-1131235200 3600 0 WAT} +if {![info exists TZData(Africa/Lagos)]} { + LoadTimeZoneFile Africa/Lagos } +set TZData(:Africa/Porto-Novo) $TZData(:Africa/Lagos) diff --git a/library/tzdata/America/Grand_Turk b/library/tzdata/America/Grand_Turk index 6c8ea4a..0edcf0b 100644 --- a/library/tzdata/America/Grand_Turk +++ b/library/tzdata/America/Grand_Turk @@ -4,6 +4,7 @@ set TZData(:America/Grand_Turk) { {-9223372036854775808 -17072 0 LMT} {-2524504528 -18431 0 KMT} {-1827687169 -18000 0 EST} + {284014800 -18000 0 EST} {294217200 -14400 1 EDT} {309938400 -18000 0 EST} {325666800 -14400 1 EDT} @@ -77,173 +78,5 @@ set TZData(:America/Grand_Turk) { {1394348400 -14400 1 EDT} {1414908000 -18000 0 EST} {1425798000 -14400 1 EDT} - {1446357600 -18000 0 EST} - {1457852400 -14400 1 EDT} - {1478412000 -18000 0 EST} - {1489302000 -14400 1 EDT} - {1509861600 -18000 0 EST} - {1520751600 -14400 1 EDT} - {1541311200 -18000 0 EST} - {1552201200 -14400 1 EDT} - {1572760800 -18000 0 EST} - {1583650800 -14400 1 EDT} - {1604210400 -18000 0 EST} - {1615705200 -14400 1 EDT} - {1636264800 -18000 0 EST} - {1647154800 -14400 1 EDT} - {1667714400 -18000 0 EST} - {1678604400 -14400 1 EDT} - {1699164000 -18000 0 EST} - {1710054000 -14400 1 EDT} - {1730613600 -18000 0 EST} - {1741503600 -14400 1 EDT} - {1762063200 -18000 0 EST} - {1772953200 -14400 1 EDT} - {1793512800 -18000 0 EST} - {1805007600 -14400 1 EDT} - {1825567200 -18000 0 EST} - {1836457200 -14400 1 EDT} - {1857016800 -18000 0 EST} - {1867906800 -14400 1 EDT} - {1888466400 -18000 0 EST} - {1899356400 -14400 1 EDT} - {1919916000 -18000 0 EST} - {1930806000 -14400 1 EDT} - {1951365600 -18000 0 EST} - {1962860400 -14400 1 EDT} - {1983420000 -18000 0 EST} - {1994310000 -14400 1 EDT} - {2014869600 -18000 0 EST} - {2025759600 -14400 1 EDT} - {2046319200 -18000 0 EST} - {2057209200 -14400 1 EDT} - {2077768800 -18000 0 EST} - {2088658800 -14400 1 EDT} - {2109218400 -18000 0 EST} - {2120108400 -14400 1 EDT} - {2140668000 -18000 0 EST} - {2152162800 -14400 1 EDT} - {2172722400 -18000 0 EST} - {2183612400 -14400 1 EDT} - {2204172000 -18000 0 EST} - {2215062000 -14400 1 EDT} - {2235621600 -18000 0 EST} - {2246511600 -14400 1 EDT} - {2267071200 -18000 0 EST} - {2277961200 -14400 1 EDT} - {2298520800 -18000 0 EST} - {2309410800 -14400 1 EDT} - {2329970400 -18000 0 EST} - {2341465200 -14400 1 EDT} - {2362024800 -18000 0 EST} - {2372914800 -14400 1 EDT} - {2393474400 -18000 0 EST} - {2404364400 -14400 1 EDT} - {2424924000 -18000 0 EST} - {2435814000 -14400 1 EDT} - {2456373600 -18000 0 EST} - {2467263600 -14400 1 EDT} - {2487823200 -18000 0 EST} - {2499318000 -14400 1 EDT} - {2519877600 -18000 0 EST} - {2530767600 -14400 1 EDT} - {2551327200 -18000 0 EST} - {2562217200 -14400 1 EDT} - {2582776800 -18000 0 EST} - {2593666800 -14400 1 EDT} - {2614226400 -18000 0 EST} - {2625116400 -14400 1 EDT} - {2645676000 -18000 0 EST} - {2656566000 -14400 1 EDT} - {2677125600 -18000 0 EST} - {2688620400 -14400 1 EDT} - {2709180000 -18000 0 EST} - {2720070000 -14400 1 EDT} - {2740629600 -18000 0 EST} - {2751519600 -14400 1 EDT} - {2772079200 -18000 0 EST} - {2782969200 -14400 1 EDT} - {2803528800 -18000 0 EST} - {2814418800 -14400 1 EDT} - {2834978400 -18000 0 EST} - {2846473200 -14400 1 EDT} - {2867032800 -18000 0 EST} - {2877922800 -14400 1 EDT} - {2898482400 -18000 0 EST} - {2909372400 -14400 1 EDT} - {2929932000 -18000 0 EST} - {2940822000 -14400 1 EDT} - {2961381600 -18000 0 EST} - {2972271600 -14400 1 EDT} - {2992831200 -18000 0 EST} - {3003721200 -14400 1 EDT} - {3024280800 -18000 0 EST} - {3035775600 -14400 1 EDT} - {3056335200 -18000 0 EST} - {3067225200 -14400 1 EDT} - {3087784800 -18000 0 EST} - {3098674800 -14400 1 EDT} - {3119234400 -18000 0 EST} - {3130124400 -14400 1 EDT} - {3150684000 -18000 0 EST} - {3161574000 -14400 1 EDT} - {3182133600 -18000 0 EST} - {3193023600 -14400 1 EDT} - {3213583200 -18000 0 EST} - {3225078000 -14400 1 EDT} - {3245637600 -18000 0 EST} - {3256527600 -14400 1 EDT} - {3277087200 -18000 0 EST} - {3287977200 -14400 1 EDT} - {3308536800 -18000 0 EST} - {3319426800 -14400 1 EDT} - {3339986400 -18000 0 EST} - {3350876400 -14400 1 EDT} - {3371436000 -18000 0 EST} - {3382930800 -14400 1 EDT} - {3403490400 -18000 0 EST} - {3414380400 -14400 1 EDT} - {3434940000 -18000 0 EST} - {3445830000 -14400 1 EDT} - {3466389600 -18000 0 EST} - {3477279600 -14400 1 EDT} - {3497839200 -18000 0 EST} - {3508729200 -14400 1 EDT} - {3529288800 -18000 0 EST} - {3540178800 -14400 1 EDT} - {3560738400 -18000 0 EST} - {3572233200 -14400 1 EDT} - {3592792800 -18000 0 EST} - {3603682800 -14400 1 EDT} - {3624242400 -18000 0 EST} - {3635132400 -14400 1 EDT} - {3655692000 -18000 0 EST} - {3666582000 -14400 1 EDT} - {3687141600 -18000 0 EST} - {3698031600 -14400 1 EDT} - {3718591200 -18000 0 EST} - {3730086000 -14400 1 EDT} - {3750645600 -18000 0 EST} - {3761535600 -14400 1 EDT} - {3782095200 -18000 0 EST} - {3792985200 -14400 1 EDT} - {3813544800 -18000 0 EST} - {3824434800 -14400 1 EDT} - {3844994400 -18000 0 EST} - {3855884400 -14400 1 EDT} - {3876444000 -18000 0 EST} - {3887334000 -14400 1 EDT} - {3907893600 -18000 0 EST} - {3919388400 -14400 1 EDT} - {3939948000 -18000 0 EST} - {3950838000 -14400 1 EDT} - {3971397600 -18000 0 EST} - {3982287600 -14400 1 EDT} - {4002847200 -18000 0 EST} - {4013737200 -14400 1 EDT} - {4034296800 -18000 0 EST} - {4045186800 -14400 1 EDT} - {4065746400 -18000 0 EST} - {4076636400 -14400 1 EDT} - {4097196000 -18000 0 EST} + {1446361200 -14400 0 AST} } diff --git a/library/tzdata/America/Jamaica b/library/tzdata/America/Jamaica index 682e47c..f752842 100644 --- a/library/tzdata/America/Jamaica +++ b/library/tzdata/America/Jamaica @@ -4,7 +4,8 @@ set TZData(:America/Jamaica) { {-9223372036854775808 -18431 0 LMT} {-2524503169 -18431 0 KMT} {-1827687169 -18000 0 EST} - {136364400 -14400 0 EDT} + {126248400 -18000 0 EST} + {126687600 -14400 1 EDT} {152085600 -18000 0 EST} {162370800 -14400 1 EDT} {183535200 -18000 0 EST} diff --git a/library/tzdata/Antarctica/Troll b/library/tzdata/Antarctica/Troll new file mode 100644 index 0000000..7d2b042 --- /dev/null +++ b/library/tzdata/Antarctica/Troll @@ -0,0 +1,196 @@ +# created by tools/tclZIC.tcl - do not edit + +set TZData(:Antarctica/Troll) { + {-9223372036854775808 0 0 zzz} + {1108166400 0 0 UTC} + {1111885200 7200 1 CEST} + {1130634000 0 0 UTC} + {1143334800 7200 1 CEST} + {1162083600 0 0 UTC} + {1174784400 7200 1 CEST} + {1193533200 0 0 UTC} + {1206838800 7200 1 CEST} + {1224982800 0 0 UTC} + {1238288400 7200 1 CEST} + {1256432400 0 0 UTC} + {1269738000 7200 1 CEST} + {1288486800 0 0 UTC} + {1301187600 7200 1 CEST} + {1319936400 0 0 UTC} + {1332637200 7200 1 CEST} + {1351386000 0 0 UTC} + {1364691600 7200 1 CEST} + {1382835600 0 0 UTC} + {1396141200 7200 1 CEST} + {1414285200 0 0 UTC} + {1427590800 7200 1 CEST} + {1445734800 0 0 UTC} + {1459040400 7200 1 CEST} + {1477789200 0 0 UTC} + {1490490000 7200 1 CEST} + {1509238800 0 0 UTC} + {1521939600 7200 1 CEST} + {1540688400 0 0 UTC} + {1553994000 7200 1 CEST} + {1572138000 0 0 UTC} + {1585443600 7200 1 CEST} + {1603587600 0 0 UTC} + {1616893200 7200 1 CEST} + {1635642000 0 0 UTC} + {1648342800 7200 1 CEST} + {1667091600 0 0 UTC} + {1679792400 7200 1 CEST} + {1698541200 0 0 UTC} + {1711846800 7200 1 CEST} + {1729990800 0 0 UTC} + {1743296400 7200 1 CEST} + {1761440400 0 0 UTC} + {1774746000 7200 1 CEST} + {1792890000 0 0 UTC} + {1806195600 7200 1 CEST} + {1824944400 0 0 UTC} + {1837645200 7200 1 CEST} + {1856394000 0 0 UTC} + {1869094800 7200 1 CEST} + {1887843600 0 0 UTC} + {1901149200 7200 1 CEST} + {1919293200 0 0 UTC} + {1932598800 7200 1 CEST} + {1950742800 0 0 UTC} + {1964048400 7200 1 CEST} + {1982797200 0 0 UTC} + {1995498000 7200 1 CEST} + {2014246800 0 0 UTC} + {2026947600 7200 1 CEST} + {2045696400 0 0 UTC} + {2058397200 7200 1 CEST} + {2077146000 0 0 UTC} + {2090451600 7200 1 CEST} + {2108595600 0 0 UTC} + {2121901200 7200 1 CEST} + {2140045200 0 0 UTC} + {2153350800 7200 1 CEST} + {2172099600 0 0 UTC} + {2184800400 7200 1 CEST} + {2203549200 0 0 UTC} + {2216250000 7200 1 CEST} + {2234998800 0 0 UTC} + {2248304400 7200 1 CEST} + {2266448400 0 0 UTC} + {2279754000 7200 1 CEST} + {2297898000 0 0 UTC} + {2311203600 7200 1 CEST} + {2329347600 0 0 UTC} + {2342653200 7200 1 CEST} + {2361402000 0 0 UTC} + {2374102800 7200 1 CEST} + {2392851600 0 0 UTC} + {2405552400 7200 1 CEST} + {2424301200 0 0 UTC} + {2437606800 7200 1 CEST} + {2455750800 0 0 UTC} + {2469056400 7200 1 CEST} + {2487200400 0 0 UTC} + {2500506000 7200 1 CEST} + {2519254800 0 0 UTC} + {2531955600 7200 1 CEST} + {2550704400 0 0 UTC} + {2563405200 7200 1 CEST} + {2582154000 0 0 UTC} + {2595459600 7200 1 CEST} + {2613603600 0 0 UTC} + {2626909200 7200 1 CEST} + {2645053200 0 0 UTC} + {2658358800 7200 1 CEST} + {2676502800 0 0 UTC} + {2689808400 7200 1 CEST} + {2708557200 0 0 UTC} + {2721258000 7200 1 CEST} + {2740006800 0 0 UTC} + {2752707600 7200 1 CEST} + {2771456400 0 0 UTC} + {2784762000 7200 1 CEST} + {2802906000 0 0 UTC} + {2816211600 7200 1 CEST} + {2834355600 0 0 UTC} + {2847661200 7200 1 CEST} + {2866410000 0 0 UTC} + {2879110800 7200 1 CEST} + {2897859600 0 0 UTC} + {2910560400 7200 1 CEST} + {2929309200 0 0 UTC} + {2942010000 7200 1 CEST} + {2960758800 0 0 UTC} + {2974064400 7200 1 CEST} + {2992208400 0 0 UTC} + {3005514000 7200 1 CEST} + {3023658000 0 0 UTC} + {3036963600 7200 1 CEST} + {3055712400 0 0 UTC} + {3068413200 7200 1 CEST} + {3087162000 0 0 UTC} + {3099862800 7200 1 CEST} + {3118611600 0 0 UTC} + {3131917200 7200 1 CEST} + {3150061200 0 0 UTC} + {3163366800 7200 1 CEST} + {3181510800 0 0 UTC} + {3194816400 7200 1 CEST} + {3212960400 0 0 UTC} + {3226266000 7200 1 CEST} + {3245014800 0 0 UTC} + {3257715600 7200 1 CEST} + {3276464400 0 0 UTC} + {3289165200 7200 1 CEST} + {3307914000 0 0 UTC} + {3321219600 7200 1 CEST} + {3339363600 0 0 UTC} + {3352669200 7200 1 CEST} + {3370813200 0 0 UTC} + {3384118800 7200 1 CEST} + {3402867600 0 0 UTC} + {3415568400 7200 1 CEST} + {3434317200 0 0 UTC} + {3447018000 7200 1 CEST} + {3465766800 0 0 UTC} + {3479072400 7200 1 CEST} + {3497216400 0 0 UTC} + {3510522000 7200 1 CEST} + {3528666000 0 0 UTC} + {3541971600 7200 1 CEST} + {3560115600 0 0 UTC} + {3573421200 7200 1 CEST} + {3592170000 0 0 UTC} + {3604870800 7200 1 CEST} + {3623619600 0 0 UTC} + {3636320400 7200 1 CEST} + {3655069200 0 0 UTC} + {3668374800 7200 1 CEST} + {3686518800 0 0 UTC} + {3699824400 7200 1 CEST} + {3717968400 0 0 UTC} + {3731274000 7200 1 CEST} + {3750022800 0 0 UTC} + {3762723600 7200 1 CEST} + {3781472400 0 0 UTC} + {3794173200 7200 1 CEST} + {3812922000 0 0 UTC} + {3825622800 7200 1 CEST} + {3844371600 0 0 UTC} + {3857677200 7200 1 CEST} + {3875821200 0 0 UTC} + {3889126800 7200 1 CEST} + {3907270800 0 0 UTC} + {3920576400 7200 1 CEST} + {3939325200 0 0 UTC} + {3952026000 7200 1 CEST} + {3970774800 0 0 UTC} + {3983475600 7200 1 CEST} + {4002224400 0 0 UTC} + {4015530000 7200 1 CEST} + {4033674000 0 0 UTC} + {4046979600 7200 1 CEST} + {4065123600 0 0 UTC} + {4078429200 7200 1 CEST} + {4096573200 0 0 UTC} +} diff --git a/library/tzdata/Asia/Chita b/library/tzdata/Asia/Chita new file mode 100644 index 0000000..eabce7f --- /dev/null +++ b/library/tzdata/Asia/Chita @@ -0,0 +1,71 @@ +# created by tools/tclZIC.tcl - do not edit + +set TZData(:Asia/Chita) { + {-9223372036854775808 27232 0 LMT} + {-1579419232 28800 0 YAKT} + {-1247558400 32400 0 YAKMMTT} + {354898800 36000 1 YAKST} + {370706400 32400 0 YAKT} + {386434800 36000 1 YAKST} + {402242400 32400 0 YAKT} + {417970800 36000 1 YAKST} + {433778400 32400 0 YAKT} + {449593200 36000 1 YAKST} + {465325200 32400 0 YAKT} + {481050000 36000 1 YAKST} + {496774800 32400 0 YAKT} + {512499600 36000 1 YAKST} + {528224400 32400 0 YAKT} + {543949200 36000 1 YAKST} + {559674000 32400 0 YAKT} + {575398800 36000 1 YAKST} + {591123600 32400 0 YAKT} + {606848400 36000 1 YAKST} + {622573200 32400 0 YAKT} + {638298000 36000 1 YAKST} + {654627600 32400 0 YAKT} + {670352400 28800 0 YAKMMTT} + {670356000 32400 1 YAKST} + {686080800 28800 0 YAKT} + {695757600 32400 0 YAKMMTT} + {701791200 36000 1 YAKST} + {717512400 32400 0 YAKT} + {733251600 36000 1 YAKST} + {748976400 32400 0 YAKT} + {764701200 36000 1 YAKST} + {780426000 32400 0 YAKT} + {796150800 36000 1 YAKST} + {811875600 32400 0 YAKT} + {828205200 36000 1 YAKST} + {846349200 32400 0 YAKT} + {859654800 36000 1 YAKST} + {877798800 32400 0 YAKT} + {891104400 36000 1 YAKST} + {909248400 32400 0 YAKT} + {922554000 36000 1 YAKST} + {941302800 32400 0 YAKT} + {954003600 36000 1 YAKST} + {972752400 32400 0 YAKT} + {985453200 36000 1 YAKST} + {1004202000 32400 0 YAKT} + {1017507600 36000 1 YAKST} + {1035651600 32400 0 YAKT} + {1048957200 36000 1 YAKST} + {1067101200 32400 0 YAKT} + {1080406800 36000 1 YAKST} + {1099155600 32400 0 YAKT} + {1111856400 36000 1 YAKST} + {1130605200 32400 0 YAKT} + {1143306000 36000 1 YAKST} + {1162054800 32400 0 YAKT} + {1174755600 36000 1 YAKST} + {1193504400 32400 0 YAKT} + {1206810000 36000 1 YAKST} + {1224954000 32400 0 YAKT} + {1238259600 36000 1 YAKST} + {1256403600 32400 0 YAKT} + {1269709200 36000 1 YAKST} + {1288458000 32400 0 YAKT} + {1301158800 36000 0 YAKT} + {1414252800 28800 0 IRKT} +} diff --git a/library/tzdata/Asia/Dhaka b/library/tzdata/Asia/Dhaka index e0c270d..6e8a334 100644 --- a/library/tzdata/Asia/Dhaka +++ b/library/tzdata/Asia/Dhaka @@ -10,5 +10,5 @@ set TZData(:Asia/Dhaka) { {38772000 21600 0 BDT} {1230746400 21600 0 BDT} {1245430800 25200 1 BDST} - {1262278740 21600 0 BDT} + {1262278800 21600 0 BDT} } diff --git a/library/tzdata/Asia/Ho_Chi_Minh b/library/tzdata/Asia/Ho_Chi_Minh index 777c8db..9da89f4 100644 --- a/library/tzdata/Asia/Ho_Chi_Minh +++ b/library/tzdata/Asia/Ho_Chi_Minh @@ -2,8 +2,13 @@ set TZData(:Asia/Ho_Chi_Minh) { {-9223372036854775808 25600 0 LMT} - {-2005974400 25580 0 SMT} - {-1855983920 25200 0 ICT} - {-1819954800 28800 0 ICT} - {-1220428800 25200 0 ICT} + {-2004073600 25590 0 PLMT} + {-1851577590 25200 0 ICT} + {-852105600 28800 0 IDT} + {-782643600 32400 0 JST} + {-767869200 25200 0 ICT} + {-718095600 28800 0 IDT} + {-457776000 25200 0 ICT} + {-315648000 28800 0 IDT} + {171820800 25200 0 ICT} } diff --git a/library/tzdata/Asia/Irkutsk b/library/tzdata/Asia/Irkutsk index e344181..08e5798 100644 --- a/library/tzdata/Asia/Irkutsk +++ b/library/tzdata/Asia/Irkutsk @@ -1,9 +1,9 @@ # created by tools/tclZIC.tcl - do not edit set TZData(:Asia/Irkutsk) { - {-9223372036854775808 25035 0 LMT} - {-2840165835 25035 0 IMT} - {-1575874635 25200 0 IRKT} + {-9223372036854775808 25025 0 LMT} + {-2840165825 25025 0 IMT} + {-1575874625 25200 0 IRKT} {-1247554800 28800 0 IRKMMTT} {354902400 32400 1 IRKST} {370710000 28800 0 IRKT} diff --git a/library/tzdata/Asia/Krasnoyarsk b/library/tzdata/Asia/Krasnoyarsk index 2770a51..17ea6c0 100644 --- a/library/tzdata/Asia/Krasnoyarsk +++ b/library/tzdata/Asia/Krasnoyarsk @@ -1,8 +1,8 @@ # created by tools/tclZIC.tcl - do not edit set TZData(:Asia/Krasnoyarsk) { - {-9223372036854775808 22280 0 LMT} - {-1577513480 21600 0 KRAT} + {-9223372036854775808 22286 0 LMT} + {-1577513486 21600 0 KRAT} {-1247551200 25200 0 KRAMMTT} {354906000 28800 1 KRAST} {370713600 25200 0 KRAT} diff --git a/library/tzdata/Asia/Novokuznetsk b/library/tzdata/Asia/Novokuznetsk index d7e308e..ab3c2d5 100644 --- a/library/tzdata/Asia/Novokuznetsk +++ b/library/tzdata/Asia/Novokuznetsk @@ -1,8 +1,8 @@ # created by tools/tclZIC.tcl - do not edit set TZData(:Asia/Novokuznetsk) { - {-9223372036854775808 20928 0 NMT} - {-1577512128 21600 0 KRAT} + {-9223372036854775808 20928 0 LMT} + {-1441259328 21600 0 KRAT} {-1247551200 25200 0 KRAMMTT} {354906000 28800 1 KRAST} {370713600 25200 0 KRAT} diff --git a/library/tzdata/Asia/Omsk b/library/tzdata/Asia/Omsk index a6b0db3..f25b8d4 100644 --- a/library/tzdata/Asia/Omsk +++ b/library/tzdata/Asia/Omsk @@ -1,8 +1,8 @@ # created by tools/tclZIC.tcl - do not edit set TZData(:Asia/Omsk) { - {-9223372036854775808 17616 0 LMT} - {-1582088016 18000 0 OMST} + {-9223372036854775808 17610 0 LMT} + {-1582088010 18000 0 OMST} {-1247547600 21600 0 OMSMMTT} {354909600 25200 1 OMSST} {370717200 21600 0 OMST} diff --git a/library/tzdata/Asia/Phnom_Penh b/library/tzdata/Asia/Phnom_Penh index 4f28420..114c786 100644 --- a/library/tzdata/Asia/Phnom_Penh +++ b/library/tzdata/Asia/Phnom_Penh @@ -1,9 +1,5 @@ # created by tools/tclZIC.tcl - do not edit - -set TZData(:Asia/Phnom_Penh) { - {-9223372036854775808 25180 0 LMT} - {-2005973980 25580 0 SMT} - {-1855983920 25200 0 ICT} - {-1819954800 28800 0 ICT} - {-1220428800 25200 0 ICT} +if {![info exists TZData(Asia/Bangkok)]} { + LoadTimeZoneFile Asia/Bangkok } +set TZData(:Asia/Phnom_Penh) $TZData(:Asia/Bangkok) diff --git a/library/tzdata/Asia/Pyongyang b/library/tzdata/Asia/Pyongyang index dd40311..fafed54 100644 --- a/library/tzdata/Asia/Pyongyang +++ b/library/tzdata/Asia/Pyongyang @@ -2,12 +2,8 @@ set TZData(:Asia/Pyongyang) { {-9223372036854775808 30180 0 LMT} - {-2524551780 30600 0 KST} - {-2053931400 32400 0 JCST} - {-1325494800 30600 0 KST} - {-1199262600 32400 0 JCST} + {-1948782180 30600 0 KST} + {-1830414600 32400 0 JCST} {-1017824400 32400 0 JST} {-768646800 32400 0 KST} - {-498128400 28800 0 KST} - {-264931200 32400 0 KST} } diff --git a/library/tzdata/Asia/Samarkand b/library/tzdata/Asia/Samarkand index 6a1be11..4b3b49f 100644 --- a/library/tzdata/Asia/Samarkand +++ b/library/tzdata/Asia/Samarkand @@ -1,8 +1,8 @@ # created by tools/tclZIC.tcl - do not edit set TZData(:Asia/Samarkand) { - {-9223372036854775808 16032 0 LMT} - {-1441168032 14400 0 SAMT} + {-9223372036854775808 16073 0 LMT} + {-1441168073 14400 0 SAMT} {-1247544000 18000 0 SAMT} {354913200 21600 1 SAMST} {370720800 21600 0 TAST} diff --git a/library/tzdata/Asia/Seoul b/library/tzdata/Asia/Seoul index 9625291..c24a1d8 100644 --- a/library/tzdata/Asia/Seoul +++ b/library/tzdata/Asia/Seoul @@ -2,19 +2,26 @@ set TZData(:Asia/Seoul) { {-9223372036854775808 30472 0 LMT} - {-2524552072 30600 0 KST} - {-2053931400 32400 0 JCST} - {-1325494800 30600 0 KST} - {-1199262600 32400 0 JCST} + {-1948782472 30600 0 KST} + {-1830414600 32400 0 JCST} {-1017824400 32400 0 JST} {-767350800 32400 0 KST} - {-498128400 28800 0 KST} - {-303984000 32400 1 KDT} - {-293533200 28800 0 KST} - {-264931200 30600 0 KST} - {-39515400 32400 0 KST} - {547570800 36000 1 KDT} - {560872800 32400 0 KST} - {579020400 36000 1 KDT} - {592322400 32400 0 KST} + {-498128400 30600 0 KST} + {-462702600 34200 1 KDT} + {-451733400 30600 0 KST} + {-429784200 34200 1 KDT} + {-418296600 30600 0 KST} + {-399544200 34200 1 KDT} + {-387451800 30600 0 KST} + {-368094600 34200 1 KDT} + {-356002200 30600 0 KST} + {-336645000 34200 1 KDT} + {-324552600 30600 0 KST} + {-305195400 34200 1 KDT} + {-293103000 30600 0 KST} + {-264933000 32400 0 KST} + {547578000 36000 1 KDT} + {560883600 32400 0 KST} + {579027600 36000 1 KDT} + {592333200 32400 0 KST} } diff --git a/library/tzdata/Asia/Srednekolymsk b/library/tzdata/Asia/Srednekolymsk new file mode 100644 index 0000000..d1dd879 --- /dev/null +++ b/library/tzdata/Asia/Srednekolymsk @@ -0,0 +1,71 @@ +# created by tools/tclZIC.tcl - do not edit + +set TZData(:Asia/Srednekolymsk) { + {-9223372036854775808 36892 0 LMT} + {-1441188892 36000 0 MAGT} + {-1247565600 39600 0 MAGMMTT} + {354891600 43200 1 MAGST} + {370699200 39600 0 MAGT} + {386427600 43200 1 MAGST} + {402235200 39600 0 MAGT} + {417963600 43200 1 MAGST} + {433771200 39600 0 MAGT} + {449586000 43200 1 MAGST} + {465318000 39600 0 MAGT} + {481042800 43200 1 MAGST} + {496767600 39600 0 MAGT} + {512492400 43200 1 MAGST} + {528217200 39600 0 MAGT} + {543942000 43200 1 MAGST} + {559666800 39600 0 MAGT} + {575391600 43200 1 MAGST} + {591116400 39600 0 MAGT} + {606841200 43200 1 MAGST} + {622566000 39600 0 MAGT} + {638290800 43200 1 MAGST} + {654620400 39600 0 MAGT} + {670345200 36000 0 MAGMMTT} + {670348800 39600 1 MAGST} + {686073600 36000 0 MAGT} + {695750400 39600 0 MAGMMTT} + {701784000 43200 1 MAGST} + {717505200 39600 0 MAGT} + {733244400 43200 1 MAGST} + {748969200 39600 0 MAGT} + {764694000 43200 1 MAGST} + {780418800 39600 0 MAGT} + {796143600 43200 1 MAGST} + {811868400 39600 0 MAGT} + {828198000 43200 1 MAGST} + {846342000 39600 0 MAGT} + {859647600 43200 1 MAGST} + {877791600 39600 0 MAGT} + {891097200 43200 1 MAGST} + {909241200 39600 0 MAGT} + {922546800 43200 1 MAGST} + {941295600 39600 0 MAGT} + {953996400 43200 1 MAGST} + {972745200 39600 0 MAGT} + {985446000 43200 1 MAGST} + {1004194800 39600 0 MAGT} + {1017500400 43200 1 MAGST} + {1035644400 39600 0 MAGT} + {1048950000 43200 1 MAGST} + {1067094000 39600 0 MAGT} + {1080399600 43200 1 MAGST} + {1099148400 39600 0 MAGT} + {1111849200 43200 1 MAGST} + {1130598000 39600 0 MAGT} + {1143298800 43200 1 MAGST} + {1162047600 39600 0 MAGT} + {1174748400 43200 1 MAGST} + {1193497200 39600 0 MAGT} + {1206802800 43200 1 MAGST} + {1224946800 39600 0 MAGT} + {1238252400 43200 1 MAGST} + {1256396400 39600 0 MAGT} + {1269702000 43200 1 MAGST} + {1288450800 39600 0 MAGT} + {1301151600 43200 0 MAGT} + {1414245600 39600 0 SRET} +} diff --git a/library/tzdata/Asia/Tbilisi b/library/tzdata/Asia/Tbilisi index 9f4a4bf..54b278a 100644 --- a/library/tzdata/Asia/Tbilisi +++ b/library/tzdata/Asia/Tbilisi @@ -1,9 +1,9 @@ # created by tools/tclZIC.tcl - do not edit set TZData(:Asia/Tbilisi) { - {-9223372036854775808 10746 0 LMT} - {-2840151546 10746 0 TBMT} - {-1441162746 10800 0 TBIT} + {-9223372036854775808 10751 0 LMT} + {-2840151551 10751 0 TBMT} + {-1441162751 10800 0 TBIT} {-405140400 14400 0 TBIT} {354916800 18000 1 TBIST} {370724400 14400 0 TBIT} diff --git a/library/tzdata/Asia/Vientiane b/library/tzdata/Asia/Vientiane index 18ade4d..27b20ce 100644 --- a/library/tzdata/Asia/Vientiane +++ b/library/tzdata/Asia/Vientiane @@ -1,9 +1,5 @@ # created by tools/tclZIC.tcl - do not edit - -set TZData(:Asia/Vientiane) { - {-9223372036854775808 24624 0 LMT} - {-2005973424 25580 0 SMT} - {-1855983920 25200 0 ICT} - {-1819954800 28800 0 ICT} - {-1220428800 25200 0 ICT} +if {![info exists TZData(Asia/Bangkok)]} { + LoadTimeZoneFile Asia/Bangkok } +set TZData(:Asia/Vientiane) $TZData(:Asia/Bangkok) diff --git a/library/tzdata/Asia/Vladivostok b/library/tzdata/Asia/Vladivostok index 396840d..119ff57 100644 --- a/library/tzdata/Asia/Vladivostok +++ b/library/tzdata/Asia/Vladivostok @@ -1,8 +1,8 @@ # created by tools/tclZIC.tcl - do not edit set TZData(:Asia/Vladivostok) { - {-9223372036854775808 31654 0 LMT} - {-1487321254 32400 0 VLAT} + {-9223372036854775808 31651 0 LMT} + {-1487321251 32400 0 VLAT} {-1247562000 36000 0 VLAMMTT} {354895200 39600 1 VLAST} {370702800 36000 0 VLAT} diff --git a/library/tzdata/Asia/Yakutsk b/library/tzdata/Asia/Yakutsk index 98953c9..17493a6 100644 --- a/library/tzdata/Asia/Yakutsk +++ b/library/tzdata/Asia/Yakutsk @@ -1,8 +1,8 @@ # created by tools/tclZIC.tcl - do not edit set TZData(:Asia/Yakutsk) { - {-9223372036854775808 31120 0 LMT} - {-1579423120 28800 0 YAKT} + {-9223372036854775808 31138 0 LMT} + {-1579423138 28800 0 YAKT} {-1247558400 32400 0 YAKMMTT} {354898800 36000 1 YAKST} {370706400 32400 0 YAKT} diff --git a/library/tzdata/Asia/Yekaterinburg b/library/tzdata/Asia/Yekaterinburg index 688ceca..2678958 100644 --- a/library/tzdata/Asia/Yekaterinburg +++ b/library/tzdata/Asia/Yekaterinburg @@ -2,7 +2,8 @@ set TZData(:Asia/Yekaterinburg) { {-9223372036854775808 14553 0 LMT} - {-1592611353 14400 0 SVET} + {-1688270553 13505 0 PMT} + {-1592610305 14400 0 SVET} {-1247544000 18000 0 SVEMMTT} {354913200 21600 1 SVEST} {370720800 18000 0 SVET} diff --git a/library/tzdata/Atlantic/Azores b/library/tzdata/Atlantic/Azores index c476191..fd47ba5 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} - {-1849557928 -7200 0 AZOT} + {-1830377128 -7200 0 AZOT} {-1689548400 -3600 1 AZOST} {-1677794400 -7200 0 AZOT} {-1667430000 -3600 1 AZOST} diff --git a/library/tzdata/Atlantic/Madeira b/library/tzdata/Atlantic/Madeira index 4960eeb..fac7f92 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} - {-1849560744 -3600 0 MADT} + {-1830379944 -3600 0 MADT} {-1689552000 0 1 MADST} {-1677798000 -3600 0 MADT} {-1667433600 0 1 MADST} diff --git a/library/tzdata/Europe/Lisbon b/library/tzdata/Europe/Lisbon index 79c688a..7168f96 100644 --- a/library/tzdata/Europe/Lisbon +++ b/library/tzdata/Europe/Lisbon @@ -1,9 +1,9 @@ # created by tools/tclZIC.tcl - do not edit set TZData(:Europe/Lisbon) { - {-9223372036854775808 -2192 0 LMT} - {-2713908208 -2192 0 LMT} - {-1830381808 0 0 WET} + {-9223372036854775808 -2205 0 LMT} + {-2713908195 -2205 0 LMT} + {-1830381795 0 0 WET} {-1689555600 3600 1 WEST} {-1677801600 0 0 WET} {-1667437200 3600 1 WEST} diff --git a/library/tzdata/Europe/Minsk b/library/tzdata/Europe/Minsk index 1adcff8..0acb4aa 100644 --- a/library/tzdata/Europe/Minsk +++ b/library/tzdata/Europe/Minsk @@ -71,4 +71,5 @@ set TZData(:Europe/Minsk) { {1269734400 10800 1 EEST} {1288483200 7200 0 EET} {1301184000 10800 0 FET} + {1414274400 10800 0 MSK} } diff --git a/library/tzdata/Europe/Riga b/library/tzdata/Europe/Riga index 98cccc2..c829ffb 100644 --- a/library/tzdata/Europe/Riga +++ b/library/tzdata/Europe/Riga @@ -1,13 +1,13 @@ # created by tools/tclZIC.tcl - do not edit set TZData(:Europe/Riga) { - {-9223372036854775808 5788 0 LMT} - {-2840146588 5788 0 RMT} - {-1632008188 9388 1 LST} - {-1618702588 5788 0 RMT} - {-1601681788 9388 1 LST} - {-1597275388 5788 0 RMT} - {-1377308188 7200 0 EET} + {-9223372036854775808 5794 0 LMT} + {-2840146594 5794 0 RMT} + {-1632008194 9394 1 LST} + {-1618702594 5794 0 RMT} + {-1601681794 9394 1 LST} + {-1597275394 5794 0 RMT} + {-1377308194 7200 0 EET} {-928029600 10800 0 MSK} {-899521200 3600 0 CET} {-857257200 3600 0 CET} diff --git a/library/tzdata/Europe/Samara b/library/tzdata/Europe/Samara index 243a42f..ee9d989 100644 --- a/library/tzdata/Europe/Samara +++ b/library/tzdata/Europe/Samara @@ -1,8 +1,8 @@ # created by tools/tclZIC.tcl - do not edit set TZData(:Europe/Samara) { - {-9223372036854775808 12036 0 LMT} - {-1593825636 10800 0 SAMT} + {-9223372036854775808 12020 0 LMT} + {-1593825620 10800 0 SAMT} {-1247540400 14400 0 SAMT} {-1102305600 14400 0 KUYMMTT} {354916800 18000 1 KUYST} diff --git a/library/tzdata/Indian/Antananarivo b/library/tzdata/Indian/Antananarivo index 217715e..c56a893 100644 --- a/library/tzdata/Indian/Antananarivo +++ b/library/tzdata/Indian/Antananarivo @@ -1,8 +1,5 @@ # created by tools/tclZIC.tcl - do not edit - -set TZData(:Indian/Antananarivo) { - {-9223372036854775808 11404 0 LMT} - {-1846293004 10800 0 EAT} - {-499924800 14400 1 EAST} - {-492062400 10800 0 EAT} +if {![info exists TZData(Africa/Nairobi)]} { + LoadTimeZoneFile Africa/Nairobi } +set TZData(:Indian/Antananarivo) $TZData(:Africa/Nairobi) diff --git a/library/tzdata/Indian/Comoro b/library/tzdata/Indian/Comoro index 0b3c33a..06071de 100644 --- a/library/tzdata/Indian/Comoro +++ b/library/tzdata/Indian/Comoro @@ -1,6 +1,5 @@ # created by tools/tclZIC.tcl - do not edit - -set TZData(:Indian/Comoro) { - {-9223372036854775808 10384 0 LMT} - {-1846291984 10800 0 EAT} +if {![info exists TZData(Africa/Nairobi)]} { + LoadTimeZoneFile Africa/Nairobi } +set TZData(:Indian/Comoro) $TZData(:Africa/Nairobi) diff --git a/library/tzdata/Indian/Mayotte b/library/tzdata/Indian/Mayotte index 0fe5f56..da55521 100644 --- a/library/tzdata/Indian/Mayotte +++ b/library/tzdata/Indian/Mayotte @@ -1,6 +1,5 @@ # created by tools/tclZIC.tcl - do not edit - -set TZData(:Indian/Mayotte) { - {-9223372036854775808 10856 0 LMT} - {-1846292456 10800 0 EAT} +if {![info exists TZData(Africa/Nairobi)]} { + LoadTimeZoneFile Africa/Nairobi } +set TZData(:Indian/Mayotte) $TZData(:Africa/Nairobi) diff --git a/library/tzdata/Pacific/Bougainville b/library/tzdata/Pacific/Bougainville new file mode 100644 index 0000000..06996f9 --- /dev/null +++ b/library/tzdata/Pacific/Bougainville @@ -0,0 +1,10 @@ +# created by tools/tclZIC.tcl - do not edit + +set TZData(:Pacific/Bougainville) { + {-9223372036854775808 37336 0 LMT} + {-2840178136 35312 0 PMMT} + {-2366790512 36000 0 PGT} + {-868010400 32400 0 JST} + {-768906000 36000 0 PGT} + {1419696000 39600 0 BST} +} diff --git a/library/tzdata/Pacific/Fiji b/library/tzdata/Pacific/Fiji index e1602ee..4aae330 100644 --- a/library/tzdata/Pacific/Fiji +++ b/library/tzdata/Pacific/Fiji @@ -17,175 +17,175 @@ set TZData(:Pacific/Fiji) { {1358604000 43200 0 FJT} {1382796000 46800 1 FJST} {1390050000 43200 0 FJT} - {1414245600 46800 1 FJST} - {1421499600 43200 0 FJT} - {1445695200 46800 1 FJST} - {1453554000 43200 0 FJT} - {1477144800 46800 1 FJST} - {1485003600 43200 0 FJT} - {1508594400 46800 1 FJST} - {1516453200 43200 0 FJT} - {1540044000 46800 1 FJST} - {1547902800 43200 0 FJT} - {1572098400 46800 1 FJST} - {1579352400 43200 0 FJT} - {1603548000 46800 1 FJST} - {1611406800 43200 0 FJT} - {1634997600 46800 1 FJST} - {1642856400 43200 0 FJT} - {1666447200 46800 1 FJST} - {1674306000 43200 0 FJT} - {1697896800 46800 1 FJST} - {1705755600 43200 0 FJT} - {1729951200 46800 1 FJST} - {1737205200 43200 0 FJT} - {1761400800 46800 1 FJST} - {1768654800 43200 0 FJT} - {1792850400 46800 1 FJST} - {1800709200 43200 0 FJT} - {1824300000 46800 1 FJST} - {1832158800 43200 0 FJT} - {1855749600 46800 1 FJST} - {1863608400 43200 0 FJT} - {1887199200 46800 1 FJST} - {1895058000 43200 0 FJT} - {1919253600 46800 1 FJST} - {1926507600 43200 0 FJT} - {1950703200 46800 1 FJST} - {1957957200 43200 0 FJT} - {1982152800 46800 1 FJST} - {1990011600 43200 0 FJT} - {2013602400 46800 1 FJST} - {2021461200 43200 0 FJT} - {2045052000 46800 1 FJST} - {2052910800 43200 0 FJT} - {2076501600 46800 1 FJST} - {2084360400 43200 0 FJT} - {2108556000 46800 1 FJST} - {2115810000 43200 0 FJT} - {2140005600 46800 1 FJST} - {2147864400 43200 0 FJT} - {2171455200 46800 1 FJST} - {2179314000 43200 0 FJT} - {2202904800 46800 1 FJST} - {2210763600 43200 0 FJT} - {2234354400 46800 1 FJST} - {2242213200 43200 0 FJT} - {2266408800 46800 1 FJST} - {2273662800 43200 0 FJT} - {2297858400 46800 1 FJST} - {2305112400 43200 0 FJT} - {2329308000 46800 1 FJST} - {2337166800 43200 0 FJT} - {2360757600 46800 1 FJST} - {2368616400 43200 0 FJT} - {2392207200 46800 1 FJST} - {2400066000 43200 0 FJT} - {2423656800 46800 1 FJST} - {2431515600 43200 0 FJT} - {2455711200 46800 1 FJST} - {2462965200 43200 0 FJT} - {2487160800 46800 1 FJST} - {2495019600 43200 0 FJT} - {2518610400 46800 1 FJST} - {2526469200 43200 0 FJT} - {2550060000 46800 1 FJST} - {2557918800 43200 0 FJT} - {2581509600 46800 1 FJST} - {2589368400 43200 0 FJT} - {2613564000 46800 1 FJST} - {2620818000 43200 0 FJT} - {2645013600 46800 1 FJST} - {2652267600 43200 0 FJT} - {2676463200 46800 1 FJST} - {2684322000 43200 0 FJT} - {2707912800 46800 1 FJST} - {2715771600 43200 0 FJT} - {2739362400 46800 1 FJST} - {2747221200 43200 0 FJT} - {2770812000 46800 1 FJST} - {2778670800 43200 0 FJT} - {2802866400 46800 1 FJST} - {2810120400 43200 0 FJT} - {2834316000 46800 1 FJST} - {2841570000 43200 0 FJT} - {2865765600 46800 1 FJST} - {2873624400 43200 0 FJT} - {2897215200 46800 1 FJST} - {2905074000 43200 0 FJT} - {2928664800 46800 1 FJST} - {2936523600 43200 0 FJT} - {2960114400 46800 1 FJST} - {2967973200 43200 0 FJT} - {2992168800 46800 1 FJST} - {2999422800 43200 0 FJT} - {3023618400 46800 1 FJST} - {3031477200 43200 0 FJT} - {3055068000 46800 1 FJST} - {3062926800 43200 0 FJT} - {3086517600 46800 1 FJST} - {3094376400 43200 0 FJT} - {3117967200 46800 1 FJST} - {3125826000 43200 0 FJT} - {3150021600 46800 1 FJST} - {3157275600 43200 0 FJT} - {3181471200 46800 1 FJST} - {3188725200 43200 0 FJT} - {3212920800 46800 1 FJST} - {3220779600 43200 0 FJT} - {3244370400 46800 1 FJST} - {3252229200 43200 0 FJT} - {3275820000 46800 1 FJST} - {3283678800 43200 0 FJT} - {3307269600 46800 1 FJST} - {3315128400 43200 0 FJT} - {3339324000 46800 1 FJST} - {3346578000 43200 0 FJT} - {3370773600 46800 1 FJST} - {3378632400 43200 0 FJT} - {3402223200 46800 1 FJST} - {3410082000 43200 0 FJT} - {3433672800 46800 1 FJST} - {3441531600 43200 0 FJT} - {3465122400 46800 1 FJST} - {3472981200 43200 0 FJT} - {3497176800 46800 1 FJST} - {3504430800 43200 0 FJT} - {3528626400 46800 1 FJST} - {3535880400 43200 0 FJT} - {3560076000 46800 1 FJST} - {3567934800 43200 0 FJT} - {3591525600 46800 1 FJST} - {3599384400 43200 0 FJT} - {3622975200 46800 1 FJST} - {3630834000 43200 0 FJT} - {3654424800 46800 1 FJST} - {3662283600 43200 0 FJT} - {3686479200 46800 1 FJST} - {3693733200 43200 0 FJT} - {3717928800 46800 1 FJST} - {3725182800 43200 0 FJT} - {3749378400 46800 1 FJST} - {3757237200 43200 0 FJT} - {3780828000 46800 1 FJST} - {3788686800 43200 0 FJT} - {3812277600 46800 1 FJST} - {3820136400 43200 0 FJT} - {3843727200 46800 1 FJST} - {3851586000 43200 0 FJT} - {3875781600 46800 1 FJST} - {3883035600 43200 0 FJT} - {3907231200 46800 1 FJST} - {3915090000 43200 0 FJT} - {3938680800 46800 1 FJST} - {3946539600 43200 0 FJT} - {3970130400 46800 1 FJST} - {3977989200 43200 0 FJT} - {4001580000 46800 1 FJST} - {4009438800 43200 0 FJT} - {4033634400 46800 1 FJST} - {4040888400 43200 0 FJT} - {4065084000 46800 1 FJST} - {4072338000 43200 0 FJT} - {4096533600 46800 1 FJST} + {1414850400 46800 1 FJST} + {1421503200 43200 0 FJT} + {1446300000 46800 1 FJST} + {1453557600 43200 0 FJT} + {1478354400 46800 1 FJST} + {1485007200 43200 0 FJT} + {1509804000 46800 1 FJST} + {1516456800 43200 0 FJT} + {1541253600 46800 1 FJST} + {1547906400 43200 0 FJT} + {1572703200 46800 1 FJST} + {1579356000 43200 0 FJT} + {1604152800 46800 1 FJST} + {1611410400 43200 0 FJT} + {1636207200 46800 1 FJST} + {1642860000 43200 0 FJT} + {1667656800 46800 1 FJST} + {1674309600 43200 0 FJT} + {1699106400 46800 1 FJST} + {1705759200 43200 0 FJT} + {1730556000 46800 1 FJST} + {1737208800 43200 0 FJT} + {1762005600 46800 1 FJST} + {1768658400 43200 0 FJT} + {1793455200 46800 1 FJST} + {1800712800 43200 0 FJT} + {1825509600 46800 1 FJST} + {1832162400 43200 0 FJT} + {1856959200 46800 1 FJST} + {1863612000 43200 0 FJT} + {1888408800 46800 1 FJST} + {1895061600 43200 0 FJT} + {1919858400 46800 1 FJST} + {1926511200 43200 0 FJT} + {1951308000 46800 1 FJST} + {1957960800 43200 0 FJT} + {1983362400 46800 1 FJST} + {1990015200 43200 0 FJT} + {2014812000 46800 1 FJST} + {2021464800 43200 0 FJT} + {2046261600 46800 1 FJST} + {2052914400 43200 0 FJT} + {2077711200 46800 1 FJST} + {2084364000 43200 0 FJT} + {2109160800 46800 1 FJST} + {2115813600 43200 0 FJT} + {2140610400 46800 1 FJST} + {2147868000 43200 0 FJT} + {2172664800 46800 1 FJST} + {2179317600 43200 0 FJT} + {2204114400 46800 1 FJST} + {2210767200 43200 0 FJT} + {2235564000 46800 1 FJST} + {2242216800 43200 0 FJT} + {2267013600 46800 1 FJST} + {2273666400 43200 0 FJT} + {2298463200 46800 1 FJST} + {2305116000 43200 0 FJT} + {2329912800 46800 1 FJST} + {2337170400 43200 0 FJT} + {2361967200 46800 1 FJST} + {2368620000 43200 0 FJT} + {2393416800 46800 1 FJST} + {2400069600 43200 0 FJT} + {2424866400 46800 1 FJST} + {2431519200 43200 0 FJT} + {2456316000 46800 1 FJST} + {2462968800 43200 0 FJT} + {2487765600 46800 1 FJST} + {2495023200 43200 0 FJT} + {2519820000 46800 1 FJST} + {2526472800 43200 0 FJT} + {2551269600 46800 1 FJST} + {2557922400 43200 0 FJT} + {2582719200 46800 1 FJST} + {2589372000 43200 0 FJT} + {2614168800 46800 1 FJST} + {2620821600 43200 0 FJT} + {2645618400 46800 1 FJST} + {2652271200 43200 0 FJT} + {2677068000 46800 1 FJST} + {2684325600 43200 0 FJT} + {2709122400 46800 1 FJST} + {2715775200 43200 0 FJT} + {2740572000 46800 1 FJST} + {2747224800 43200 0 FJT} + {2772021600 46800 1 FJST} + {2778674400 43200 0 FJT} + {2803471200 46800 1 FJST} + {2810124000 43200 0 FJT} + {2834920800 46800 1 FJST} + {2841573600 43200 0 FJT} + {2866975200 46800 1 FJST} + {2873628000 43200 0 FJT} + {2898424800 46800 1 FJST} + {2905077600 43200 0 FJT} + {2929874400 46800 1 FJST} + {2936527200 43200 0 FJT} + {2961324000 46800 1 FJST} + {2967976800 43200 0 FJT} + {2992773600 46800 1 FJST} + {2999426400 43200 0 FJT} + {3024223200 46800 1 FJST} + {3031480800 43200 0 FJT} + {3056277600 46800 1 FJST} + {3062930400 43200 0 FJT} + {3087727200 46800 1 FJST} + {3094380000 43200 0 FJT} + {3119176800 46800 1 FJST} + {3125829600 43200 0 FJT} + {3150626400 46800 1 FJST} + {3157279200 43200 0 FJT} + {3182076000 46800 1 FJST} + {3188728800 43200 0 FJT} + {3213525600 46800 1 FJST} + {3220783200 43200 0 FJT} + {3245580000 46800 1 FJST} + {3252232800 43200 0 FJT} + {3277029600 46800 1 FJST} + {3283682400 43200 0 FJT} + {3308479200 46800 1 FJST} + {3315132000 43200 0 FJT} + {3339928800 46800 1 FJST} + {3346581600 43200 0 FJT} + {3371378400 46800 1 FJST} + {3378636000 43200 0 FJT} + {3403432800 46800 1 FJST} + {3410085600 43200 0 FJT} + {3434882400 46800 1 FJST} + {3441535200 43200 0 FJT} + {3466332000 46800 1 FJST} + {3472984800 43200 0 FJT} + {3497781600 46800 1 FJST} + {3504434400 43200 0 FJT} + {3529231200 46800 1 FJST} + {3535884000 43200 0 FJT} + {3560680800 46800 1 FJST} + {3567938400 43200 0 FJT} + {3592735200 46800 1 FJST} + {3599388000 43200 0 FJT} + {3624184800 46800 1 FJST} + {3630837600 43200 0 FJT} + {3655634400 46800 1 FJST} + {3662287200 43200 0 FJT} + {3687084000 46800 1 FJST} + {3693736800 43200 0 FJT} + {3718533600 46800 1 FJST} + {3725186400 43200 0 FJT} + {3750588000 46800 1 FJST} + {3757240800 43200 0 FJT} + {3782037600 46800 1 FJST} + {3788690400 43200 0 FJT} + {3813487200 46800 1 FJST} + {3820140000 43200 0 FJT} + {3844936800 46800 1 FJST} + {3851589600 43200 0 FJT} + {3876386400 46800 1 FJST} + {3883039200 43200 0 FJT} + {3907836000 46800 1 FJST} + {3915093600 43200 0 FJT} + {3939890400 46800 1 FJST} + {3946543200 43200 0 FJT} + {3971340000 46800 1 FJST} + {3977992800 43200 0 FJT} + {4002789600 46800 1 FJST} + {4009442400 43200 0 FJT} + {4034239200 46800 1 FJST} + {4040892000 43200 0 FJT} + {4065688800 46800 1 FJST} + {4072341600 43200 0 FJT} + {4097138400 46800 1 FJST} } -- cgit v0.12 From 26326004c63514e3b84d7a3268d5177bf0d18894 Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 11 Dec 2014 14:40:02 +0000 Subject: [e711ffb458] Same conversion for [catch] compiler. --- generic/tclCompCmds.c | 43 +++++++------------------------------------ 1 file changed, 7 insertions(+), 36 deletions(-) diff --git a/generic/tclCompCmds.c b/generic/tclCompCmds.c index ec22f65..10cba39 100644 --- a/generic/tclCompCmds.c +++ b/generic/tclCompCmds.c @@ -379,8 +379,7 @@ TclCompileCatchCmd( { JumpFixup jumpFixup; Tcl_Token *cmdTokenPtr, *resultNameTokenPtr, *optsNameTokenPtr; - const char *name; - int resultIndex, optsIndex, nameChars, range; + int resultIndex, optsIndex, isSimple, isScalar, range; int initStackDepth = envPtr->currStackDepth; int savedStackDepth; DefineLineInformation; /* TIP #280 */ @@ -395,15 +394,6 @@ TclCompileCatchCmd( } /* - * If variables were specified and the catch command is at global level - * (not in a procedure), don't compile it inline: the payoff is too small. - */ - - if ((parsePtr->numWords >= 3) && (envPtr->procPtr == NULL)) { - return TCL_ERROR; - } - - /* * Make sure the variable names, if any, have no substitutions and just * refer to local scalars. */ @@ -412,36 +402,17 @@ TclCompileCatchCmd( cmdTokenPtr = TokenAfter(parsePtr->tokenPtr); if (parsePtr->numWords >= 3) { resultNameTokenPtr = TokenAfter(cmdTokenPtr); - /* DGP */ - if (resultNameTokenPtr->type != TCL_TOKEN_SIMPLE_WORD) { + PushVarNameWord(interp, resultNameTokenPtr, envPtr, TCL_CREATE_VAR, + &resultIndex, &isSimple, &isScalar, 2); + if (!isScalar || resultIndex < 0) { return TCL_ERROR; } - name = resultNameTokenPtr[1].start; - nameChars = resultNameTokenPtr[1].size; - if (!TclIsLocalScalar(name, nameChars)) { - return TCL_ERROR; - } - resultIndex = TclFindCompiledLocal(resultNameTokenPtr[1].start, - resultNameTokenPtr[1].size, /*create*/ 1, envPtr->procPtr); - if (resultIndex < 0) { - return TCL_ERROR; - } - - /* DKF */ if (parsePtr->numWords == 4) { optsNameTokenPtr = TokenAfter(resultNameTokenPtr); - if (optsNameTokenPtr->type != TCL_TOKEN_SIMPLE_WORD) { - return TCL_ERROR; - } - name = optsNameTokenPtr[1].start; - nameChars = optsNameTokenPtr[1].size; - if (!TclIsLocalScalar(name, nameChars)) { - return TCL_ERROR; - } - optsIndex = TclFindCompiledLocal(optsNameTokenPtr[1].start, - optsNameTokenPtr[1].size, /*create*/ 1, envPtr->procPtr); - if (optsIndex < 0) { + PushVarNameWord(interp, optsNameTokenPtr, envPtr, TCL_CREATE_VAR, + &optsIndex, &isSimple, &isScalar, 2); + if (!isScalar || resultIndex < 0) { return TCL_ERROR; } } -- cgit v0.12 From a417c667a52117af242053c93f3526069187ef95 Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 11 Dec 2014 14:41:09 +0000 Subject: Get the word number right, even though it has no effect. --- generic/tclCompCmds.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generic/tclCompCmds.c b/generic/tclCompCmds.c index 10cba39..e0dee13 100644 --- a/generic/tclCompCmds.c +++ b/generic/tclCompCmds.c @@ -411,7 +411,7 @@ TclCompileCatchCmd( if (parsePtr->numWords == 4) { optsNameTokenPtr = TokenAfter(resultNameTokenPtr); PushVarNameWord(interp, optsNameTokenPtr, envPtr, TCL_CREATE_VAR, - &optsIndex, &isSimple, &isScalar, 2); + &optsIndex, &isSimple, &isScalar, 3); if (!isScalar || resultIndex < 0) { return TCL_ERROR; } -- cgit v0.12 From 8e80c62f6f65a921aa7f69158b13f2e849f17439 Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 11 Dec 2014 15:19:38 +0000 Subject: Similar revisions to [dict incr] compiler. --- generic/tclCompCmds.c | 60 +++++++++++++++++++-------------------------------- 1 file changed, 22 insertions(+), 38 deletions(-) diff --git a/generic/tclCompCmds.c b/generic/tclCompCmds.c index e0dee13..33598e7 100644 --- a/generic/tclCompCmds.c +++ b/generic/tclCompCmds.c @@ -707,20 +707,31 @@ TclCompileDictIncrCmd( * compiled. */ CompileEnv *envPtr) /* Holds resulting instructions. */ { - Proc *procPtr = envPtr->procPtr; - DefineLineInformation; /* TIP #280 */ Tcl_Token *varTokenPtr, *keyTokenPtr; - int dictVarIndex, nameChars, incrAmount; - const char *name; + int dictVarIndex, incrAmount, isScalar, isSimple; + DefineLineInformation; /* TIP #280 */ /* * There must be at least two arguments after the command. */ - if (parsePtr->numWords < 3 || parsePtr->numWords > 4 || procPtr == NULL) { + if (parsePtr->numWords < 3 || parsePtr->numWords > 4) { return TCL_ERROR; } + + /* + * The dictionary variable must be a local scalar that is knowable at + * compile time; anything else exceeds the complexity of the opcode. So + * discover what the index is. + */ + varTokenPtr = TokenAfter(parsePtr->tokenPtr); + PushVarNameWord(interp, varTokenPtr, envPtr, TCL_CREATE_VAR, + &dictVarIndex, &isSimple, &isScalar, 1); + if (!isScalar || dictVarIndex < 0) { + return TCL_ERROR; + } + keyTokenPtr = TokenAfter(varTokenPtr); /* @@ -728,23 +739,12 @@ TclCompileDictIncrCmd( */ if (parsePtr->numWords == 4) { - const char *word; - int numBytes, code; - Tcl_Token *incrTokenPtr; - Tcl_Obj *intObj; - - incrTokenPtr = TokenAfter(keyTokenPtr); - if (incrTokenPtr->type != TCL_TOKEN_SIMPLE_WORD) { - return TCL_ERROR; - } - word = incrTokenPtr[1].start; - numBytes = incrTokenPtr[1].size; - - intObj = Tcl_NewStringObj(word, numBytes); - Tcl_IncrRefCount(intObj); - code = TclGetIntFromObj(NULL, intObj, &incrAmount); - TclDecrRefCount(intObj); - if (code != TCL_OK) { + Tcl_Token *incrTokenPtr = TokenAfter(keyTokenPtr); + Tcl_Obj *intObj = Tcl_NewObj(); + int fail = (!TclWordKnownAtCompileTime(incrTokenPtr, intObj) + || TCL_ERROR == TclGetIntFromObj(NULL, intObj, &incrAmount)); + Tcl_DecrRefCount(intObj); + if (fail) { return TCL_ERROR; } } else { @@ -752,22 +752,6 @@ TclCompileDictIncrCmd( } /* - * The dictionary variable must be a local scalar that is knowable at - * compile time; anything else exceeds the complexity of the opcode. So - * discover what the index is. - */ - - if (varTokenPtr->type != TCL_TOKEN_SIMPLE_WORD) { - return TCL_ERROR; - } - name = varTokenPtr[1].start; - nameChars = varTokenPtr[1].size; - if (!TclIsLocalScalar(name, nameChars)) { - return TCL_ERROR; - } - dictVarIndex = TclFindCompiledLocal(name, nameChars, 1, procPtr); - - /* * Emit the key and the code to actually do the increment. */ -- cgit v0.12 From 604faa265f3f4197582673cddb2acd4c7a0ef6a5 Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 11 Dec 2014 15:45:16 +0000 Subject: Similar conversion for [dict update] compiler. --- generic/tclCompCmds.c | 45 +++++++++++++++------------------------------ 1 file changed, 15 insertions(+), 30 deletions(-) diff --git a/generic/tclCompCmds.c b/generic/tclCompCmds.c index 33598e7..0c5b19d 100644 --- a/generic/tclCompCmds.c +++ b/generic/tclCompCmds.c @@ -818,7 +818,7 @@ TclCompileDictForCmd( Tcl_DString buffer; /* - * There must be at least three argument after the command. + * There must be exactly three arguments after the command. */ if (parsePtr->numWords != 4 || procPtr == NULL) { @@ -1004,21 +1004,11 @@ TclCompileDictUpdateCmd( * compiled. */ CompileEnv *envPtr) /* Holds resulting instructions. */ { - Proc *procPtr = envPtr->procPtr; - DefineLineInformation; /* TIP #280 */ - const char *name; - int i, nameChars, dictIndex, numVars, range, infoIndex; + int i, dictIndex, numVars, range, infoIndex, isSimple, isScalar; Tcl_Token **keyTokenPtrs, *dictVarTokenPtr, *bodyTokenPtr, *tokenPtr; DictUpdateInfo *duiPtr; JumpFixup jumpFixup; - - /* - * There must be at least one argument after the command. - */ - - if (parsePtr->numWords < 5 || procPtr == NULL) { - return TCL_ERROR; - } + DefineLineInformation; /* TIP #280 */ /* * Parse the command. Expect the following: @@ -1029,6 +1019,9 @@ TclCompileDictUpdateCmd( return TCL_ERROR; } numVars = (parsePtr->numWords - 3) / 2; + if (numVars < 1) { + return TCL_ERROR; + } /* * The dictionary variable must be a local scalar that is knowable at @@ -1037,15 +1030,11 @@ TclCompileDictUpdateCmd( */ dictVarTokenPtr = TokenAfter(parsePtr->tokenPtr); - if (dictVarTokenPtr->type != TCL_TOKEN_SIMPLE_WORD) { - return TCL_ERROR; - } - name = dictVarTokenPtr[1].start; - nameChars = dictVarTokenPtr[1].size; - if (!TclIsLocalScalar(name, nameChars)) { + PushVarNameWord(interp, dictVarTokenPtr, envPtr, TCL_CREATE_VAR, + &dictIndex, &isSimple, &isScalar, 1); + if (!isScalar || dictIndex < 0) { return TCL_ERROR; } - dictIndex = TclFindCompiledLocal(name, nameChars, 1, procPtr); /* * Assemble the instruction metadata. This is complex enough that it is @@ -1061,6 +1050,8 @@ TclCompileDictUpdateCmd( tokenPtr = TokenAfter(dictVarTokenPtr); for (i=0 ; itype != TCL_TOKEN_SIMPLE_WORD) { - ckfree((char *) duiPtr); - TclStackFree(interp, keyTokenPtrs); - return TCL_ERROR; - } - name = tokenPtr[1].start; - nameChars = tokenPtr[1].size; - if (!TclIsLocalScalar(name, nameChars)) { + PushVarNameWord(interp, tokenPtr, envPtr, TCL_CREATE_VAR, + &index, &isSimple, &isScalar, 1); + if (!isScalar || index < 0) { ckfree((char *) duiPtr); TclStackFree(interp, keyTokenPtrs); return TCL_ERROR; @@ -1089,8 +1075,7 @@ TclCompileDictUpdateCmd( * Stash the index in the auxiliary data. */ - duiPtr->varIndices[i] = - TclFindCompiledLocal(name, nameChars, 1, procPtr); + duiPtr->varIndices[i] = index; tokenPtr = TokenAfter(tokenPtr); } if (tokenPtr->type != TCL_TOKEN_SIMPLE_WORD) { -- cgit v0.12 From ee5c231ff5dde87b4436f0de5fa6a6059df4b774 Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 11 Dec 2014 16:00:19 +0000 Subject: Similar conversion of the [dict append] compiler. --- generic/tclCompCmds.c | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/generic/tclCompCmds.c b/generic/tclCompCmds.c index 0c5b19d..a0f493c 100644 --- a/generic/tclCompCmds.c +++ b/generic/tclCompCmds.c @@ -1156,18 +1156,17 @@ TclCompileDictAppendCmd( * compiled. */ CompileEnv *envPtr) /* Holds resulting instructions. */ { - Proc *procPtr = envPtr->procPtr; - DefineLineInformation; /* TIP #280 */ Tcl_Token *tokenPtr; - int i, dictVarIndex; + int i, isSimple, isScalar, dictVarIndex; + DefineLineInformation; /* TIP #280 */ /* - * There must be at least two argument after the command. And we impose an - * (arbirary) safe limit; anyone exceeding it should stop worrying about - * speed quite so much. ;-) + * There must be at least two argument after the command. Since we + * implement using INST_CONCAT1, make sure the number of arguments + * stays within its range. */ - if (parsePtr->numWords<4 || parsePtr->numWords>100 || procPtr==NULL) { + if (parsePtr->numWords<4 || parsePtr->numWords>258) { return TCL_ERROR; } @@ -1176,16 +1175,10 @@ TclCompileDictAppendCmd( */ tokenPtr = TokenAfter(parsePtr->tokenPtr); - if (tokenPtr->type != TCL_TOKEN_SIMPLE_WORD) { + PushVarNameWord(interp, tokenPtr, envPtr, TCL_CREATE_VAR, + &dictVarIndex, &isSimple, &isScalar, 1); + if (!isScalar || dictVarIndex < 0) { return TCL_ERROR; - } else { - register const char *name = tokenPtr[1].start; - register int nameChars = tokenPtr[1].size; - - if (!TclIsLocalScalar(name, nameChars)) { - return TCL_ERROR; - } - dictVarIndex = TclFindCompiledLocal(name, nameChars, 1, procPtr); } /* -- cgit v0.12 From 59cb45cc1611009330228462969fc508b57498bd Mon Sep 17 00:00:00 2001 From: Kevin Walzer Date: Sat, 13 Dec 2014 02:47:25 +0000 Subject: Add header install flag to OS X GNUMakefile; thanks to Stephan Houben for patch --- macosx/GNUmakefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/macosx/GNUmakefile b/macosx/GNUmakefile index d7b0d1d..54eea8e 100644 --- a/macosx/GNUmakefile +++ b/macosx/GNUmakefile @@ -100,7 +100,7 @@ INSTALL_TARGET := install export CPPROG := cp -p -INSTALL_TARGETS = install-binaries install-libraries +INSTALL_TARGETS = install-binaries install-headers install-libraries ifeq (${EMBEDDED_BUILD},) INSTALL_TARGETS += install-private-headers endif -- cgit v0.12 From 2f8ea1be7c95d40944c24fc6c432e0bbbd73ebe3 Mon Sep 17 00:00:00 2001 From: Kevin Walzer Date: Sat, 13 Dec 2014 02:50:07 +0000 Subject: Add header install flag to OS X GNUMakefile; thanks to Stephan Houben for patch --- macosx/GNUmakefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/macosx/GNUmakefile b/macosx/GNUmakefile index 7d19fc6..3598b3a 100644 --- a/macosx/GNUmakefile +++ b/macosx/GNUmakefile @@ -100,7 +100,7 @@ INSTALL_TARGET := install export CPPROG := cp -p -INSTALL_TARGETS = install-binaries install-libraries +INSTALL_TARGETS = install-binaries install-headers install-libraries ifeq (${EMBEDDED_BUILD},) INSTALL_TARGETS += install-private-headers endif -- cgit v0.12 From 4e0313afe2507b8fb3f6dbfb4b8470e098c9f53f Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Mon, 15 Dec 2014 10:20:39 +0000 Subject: 85 -> 86 --- win/README | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/win/README b/win/README index 1a2d501..5e060ef 100644 --- a/win/README +++ b/win/README @@ -79,7 +79,7 @@ Use the Makefile "install" target to install Tcl. It will install it according to the prefix options you provided in the correct directory structure. -Note that in order to run tclsh85.exe, you must ensure that tcl85.dll is +Note that in order to run tclsh86.exe, you must ensure that tcl86.dll is on your path, in the system directory, or in the directory containing tclsh86.exe. -- cgit v0.12 From d7a9d635208125f64de188de24122509d0c624dc Mon Sep 17 00:00:00 2001 From: oehhar Date: Wed, 17 Dec 2014 08:22:23 +0000 Subject: Documented "fconfigure $h -connecting" on socket man page --- doc/socket.n | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/doc/socket.n b/doc/socket.n index b7a4a45..492ca66 100644 --- a/doc/socket.n +++ b/doc/socket.n @@ -97,6 +97,10 @@ writable channel event on the socket to get notified when the asynchronous connection has succeeded or failed. See the \fBvwait\fR and the \fBchan\fR commands for more details on the event loop and channel events. +.PP +The \fBchan configure\fR option \fB-connecting\fR may be used to check if the connect is still running. To verify a successful connect, the option \fB-error\fR may be checked when \fB-connecting\fR returned 0. +.PP +Operation without the event queue requires at the moment calls to \fBchan configure\fR to advance the internal state machine. .RE .SH "SERVER SOCKETS" .PP @@ -186,6 +190,11 @@ sockets, this option returns a list of three elements; these are the address, the host name and the port to which the peer socket is connected or bound. If the host name cannot be computed, the second element of the list is identical to the address, its first element. +.RE +.TP +\fB\-connecting\fR +. +This option is not supported by server sockets. For client sockets, this option returns 1 if an asyncroneous connect is still in progress, 0 otherwise. .PP .SH "EXAMPLES" .PP -- cgit v0.12 From 3b7664e77fa5643a858e66e21458dc0eaeaffeb6 Mon Sep 17 00:00:00 2001 From: oehhar Date: Wed, 17 Dec 2014 08:42:24 +0000 Subject: Include option -connecting in test iocmd-8.15.1 --- tests/ioCmd.test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/ioCmd.test b/tests/ioCmd.test index 57f8d47..4fbc380 100644 --- a/tests/ioCmd.test +++ b/tests/ioCmd.test @@ -294,7 +294,7 @@ test iocmd-8.15.1 {fconfigure command / tcp channel} -constraints {socket unixOr close $srv unset cli srv port rename iocmdSRV {} -} -returnCodes error -result {bad option "-blah": should be one of -blocking, -buffering, -buffersize, -encoding, -eofchar, -translation, -peername, or -sockname} +} -returnCodes error -result {bad option "-blah": should be one of -blocking, -buffering, -buffersize, -encoding, -eofchar, -translation, -connecting, -peername, or -sockname} test iocmd-8.16 {fconfigure command / tcp channel} -constraints socket -setup { set srv [socket -server iocmdSRV -myaddr 127.0.0.1 0] set port [lindex [fconfigure $srv -sockname] 2] -- cgit v0.12 From 68b5780dde6d75819809b071fb27d935cee69fdc Mon Sep 17 00:00:00 2001 From: oehhar Date: Wed, 17 Dec 2014 11:21:16 +0000 Subject: changes for TIP427 --- changes | 2 ++ 1 file changed, 2 insertions(+) diff --git a/changes b/changes index 1decfe2..79a242d 100644 --- a/changes +++ b/changes @@ -8491,3 +8491,5 @@ include ::oo::class (fellows) 2014-11-06 (bug)[5adc35] Stop forcing EOF to be permanent (porter) --- Released 8.6.3, November 12, 2014 --- http://core.tcl.tk/tcl/ for details + +2014-12-17 (TIP 427) [fconfigure $h -connecting, -peername, -sockname] (oehlmann,rmax) -- cgit v0.12 From e942227f6e2651032ec7a070d1562c4b050de9b3 Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 17 Dec 2014 19:57:40 +0000 Subject: Revise encoding finalization so that it does a more complete job of restoring the pre-initialized state. This makes finalization errors more repeatable and cross-platform. --- generic/tclEncoding.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/generic/tclEncoding.c b/generic/tclEncoding.c index d246cb2..95c59c0 100644 --- a/generic/tclEncoding.c +++ b/generic/tclEncoding.c @@ -180,9 +180,9 @@ TCL_DECLARE_MUTEX(encodingMutex) * the system encoding will be used to perform the conversion. */ -static Tcl_Encoding defaultEncoding; -static Tcl_Encoding systemEncoding; -Tcl_Encoding tclIdentityEncoding; +static Tcl_Encoding defaultEncoding = NULL; +static Tcl_Encoding systemEncoding = NULL; +Tcl_Encoding tclIdentityEncoding = NULL; /* * The following variable is used in the sparse matrix code for a @@ -652,7 +652,10 @@ TclFinalizeEncodingSubsystem(void) Tcl_MutexLock(&encodingMutex); encodingsInitialized = 0; FreeEncoding(systemEncoding); + systemEncoding = NULL; + defaultEncoding = NULL; FreeEncoding(tclIdentityEncoding); + tclIdentityEncoding = NULL; hPtr = Tcl_FirstHashEntry(&encodingTable, &search); while (hPtr != NULL) { @@ -2960,7 +2963,9 @@ TableFreeProc( */ ckfree(dataPtr->toUnicode); + dataPtr->toUnicode = NULL; ckfree(dataPtr->fromUnicode); + dataPtr->fromUnicode = NULL; ckfree(dataPtr); } @@ -3433,6 +3438,7 @@ EscapeFreeProc( subTablePtr = dataPtr->subTables; for (i = 0; i < dataPtr->numSubTables; i++) { FreeEncoding((Tcl_Encoding) subTablePtr->encodingPtr); + subTablePtr->encodingPtr = NULL; subTablePtr++; } } -- cgit v0.12 From 955507f6352c466740d348d8d89adb8de24de9fd Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 17 Dec 2014 20:47:58 +0000 Subject: Rework the *FinalizeThread*() routines so that the quick exit preference is respected without need to run afoul of encoding finalizations. tests pass now. All changes are fully internal. --- generic/tclEvent.c | 14 +++++++++++--- generic/tclInt.h | 2 +- generic/tclThread.c | 4 ++-- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/generic/tclEvent.c b/generic/tclEvent.c index 3985767..6ca22a6 100644 --- a/generic/tclEvent.c +++ b/generic/tclEvent.c @@ -119,6 +119,7 @@ static char * VwaitVarProc(ClientData clientData, Tcl_Interp *interp, const char *name1, const char *name2, int flags); static void InvokeExitHandlers(void); +static void FinalizeThread(int quick); /* *---------------------------------------------------------------------- @@ -983,7 +984,7 @@ Tcl_Exit( * Tcl_Channels that may have data enqueued. */ - Tcl_FinalizeThread(); + FinalizeThread(/* quick */ 1); } TclpExit(status); Tcl_Panic("OS exit failed!"); @@ -1183,7 +1184,7 @@ Tcl_Finalize(void) * This fixes the Tcl Bug #990552. */ - TclFinalizeThreadData(); + TclFinalizeThreadData(/* quick */ 0); /* * Now we can free constants for conversions to/from double. @@ -1269,6 +1270,13 @@ Tcl_Finalize(void) void Tcl_FinalizeThread(void) { + FinalizeThread(/* quick */ 0); +} + +void +FinalizeThread( + int quick) +{ ExitHandler *exitPtr; ThreadSpecificData *tsdPtr; @@ -1309,7 +1317,7 @@ Tcl_FinalizeThread(void) * * Fix [Bug #571002] */ - TclFinalizeThreadData(); + TclFinalizeThreadData(quick); } /* diff --git a/generic/tclInt.h b/generic/tclInt.h index c989eda..995da48 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -2927,7 +2927,7 @@ MODULE_SCOPE void TclFinalizePreserve(void); MODULE_SCOPE void TclFinalizeSynchronization(void); MODULE_SCOPE void TclFinalizeThreadAlloc(void); MODULE_SCOPE void TclFinalizeThreadAllocThread(void); -MODULE_SCOPE void TclFinalizeThreadData(void); +MODULE_SCOPE void TclFinalizeThreadData(int quick); MODULE_SCOPE void TclFinalizeThreadObjects(void); MODULE_SCOPE double TclFloor(const mp_int *a); MODULE_SCOPE void TclFormatNaN(double value, char *buffer); diff --git a/generic/tclThread.c b/generic/tclThread.c index 5ac6a8d..198fa6a 100644 --- a/generic/tclThread.c +++ b/generic/tclThread.c @@ -353,11 +353,11 @@ Tcl_ConditionFinalize( */ void -TclFinalizeThreadData(void) +TclFinalizeThreadData(int quick) { TclFinalizeThreadDataThread(); #if defined(TCL_THREADS) && defined(USE_THREAD_ALLOC) - if ((!TclInExit())||TclFullFinalizationRequested()) { + if (!quick) { /* * Quick exit principle makes it useless to terminate allocators */ -- cgit v0.12 From 559113cc4c38b5bc99f503e300671df52b991d13 Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 18 Dec 2014 18:06:51 +0000 Subject: [7c187a3773] Fix error in managing inStatePtr->inQueueTail value in the byte-moving optimized path of [chan copy]. Thanks to Benno. --- generic/tclIO.c | 3 +++ tests/io.test | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/generic/tclIO.c b/generic/tclIO.c index 2025742..8a35aee 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -9215,6 +9215,9 @@ MBWrite( } outStatePtr->outQueueTail = tail; inStatePtr->inQueueHead = bufPtr; + if (inStatePtr->inQueueTail == tail) { + inStatePtr->inQueueTail = bufPtr; + } if (bufPtr == NULL) { inStatePtr->inQueueTail = NULL; } diff --git a/tests/io.test b/tests/io.test index b09d55a..cd8b014 100644 --- a/tests/io.test +++ b/tests/io.test @@ -7900,6 +7900,44 @@ test io-53.16 {[ed29c4da21] MBRead: fblocked seen as error} -setup { close $c removeFile out } -result 100 +test io-53.17 {[7c187a3773] MBWrite: proper inQueueTail handling} -setup { + proc driver {cmd args} { + variable buffer + variable index + set chan [lindex $args 0] + switch -- $cmd { + initialize { + set index($chan) 0 + set buffer($chan) [encoding convertto utf-8 \ + line\n[string repeat a 100]line\n] + return {initialize finalize watch read} + } + finalize { + unset index($chan) buffer($chan) + return + } + watch {} + read { + set n [lindex $args 1] + set new [expr {$index($chan) + $n}] + set result [string range $buffer($chan) $index($chan) $new-1] + set index($chan) $new + return $result + } + } + } + set c [chan create read [namespace which driver]] + chan configure $c -encoding utf-8 -translation lf -buffersize 107 + set out [makeFile {} out] + set outChan [open $out w] + chan configure $outChan -encoding utf-8 -translation lf +} -body { + list [gets $c] [chan copy $c $outChan -size 100] [gets $c] +} -cleanup { + close $outChan + close $c + removeFile out +} -result {line 100 line} test io-54.1 {Recursive channel events} {socket fileevent} { # This test checks to see if file events are delivered during recursive -- cgit v0.12 From d56e61b246f06cd10844c54a54f2d04aa4d47ade Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 18 Dec 2014 19:21:31 +0000 Subject: Shift the allocation of AuxData earlier in the [foreach] compiler. --- generic/tclCompCmds.c | 41 +++++++++++++++++++++++++---------------- 1 file changed, 25 insertions(+), 16 deletions(-) diff --git a/generic/tclCompCmds.c b/generic/tclCompCmds.c index a0f493c..f07b19f 100644 --- a/generic/tclCompCmds.c +++ b/generic/tclCompCmds.c @@ -1536,7 +1536,7 @@ TclCompileForeachCmd( CompileEnv *envPtr) /* Holds resulting instructions. */ { Proc *procPtr = envPtr->procPtr; - ForeachInfo *infoPtr; /* Points to the structure describing this + ForeachInfo *infoPtr = NULL;/* Points to the structure describing this * foreach command. Stored in a AuxData * record in the ByteCode. */ int firstValueTemp; /* Index of the first temp var in the frame @@ -1599,6 +1599,16 @@ TclCompileForeachCmd( memset((char*) varvList, 0, numLists * sizeof(const char **)); /* + * Create and initialize the ForeachInfo and ForeachVarList data + * structures describing this command. Then create a AuxData record + * pointing to the ForeachInfo structure. + */ + + infoPtr = (ForeachInfo *) ckalloc((unsigned) + sizeof(ForeachInfo) + numLists*sizeof(ForeachVarList *)); + infoPtr->numLists = 0; /* Count this up as we go */ + + /* * Break up each var list and set the varcList and varvList arrays. Don't * compile the foreach inline if any var name needs substitutions or isn't * a scalar, or if any var list needs substitutions. @@ -1609,6 +1619,7 @@ TclCompileForeachCmd( i < numWords-1; i++, tokenPtr = TokenAfter(tokenPtr)) { Tcl_DString varList; + ForeachVarList *varListPtr; if (i%2 != 1) { continue; @@ -1634,6 +1645,12 @@ TclCompileForeachCmd( } numVars = varcList[loopIndex]; + varListPtr = (ForeachVarList *) ckalloc((unsigned) + sizeof(ForeachVarList) + numVars*sizeof(int)); + varListPtr->numVars = numVars; + infoPtr->varLists[loopIndex] = varListPtr; + infoPtr->numLists++; + /* * If the variable list is empty, we can enter an infinite loop when * the interpreted version would not. Take care to ensure this does @@ -1678,23 +1695,11 @@ TclCompileForeachCmd( loopCtTemp = TclFindCompiledLocal(NULL, /*nameChars*/ 0, /*create*/ 1, procPtr); - /* - * Create and initialize the ForeachInfo and ForeachVarList data - * structures describing this command. Then create a AuxData record - * pointing to the ForeachInfo structure. - */ - - infoPtr = (ForeachInfo *) ckalloc((unsigned) - sizeof(ForeachInfo) + numLists*sizeof(ForeachVarList *)); - infoPtr->numLists = numLists; infoPtr->firstValueTemp = firstValueTemp; infoPtr->loopCtTemp = loopCtTemp; for (loopIndex = 0; loopIndex < numLists; loopIndex++) { - ForeachVarList *varListPtr; - numVars = varcList[loopIndex]; - varListPtr = (ForeachVarList *) ckalloc((unsigned) - sizeof(ForeachVarList) + numVars*sizeof(int)); - varListPtr->numVars = numVars; + ForeachVarList *varListPtr = infoPtr->varLists[loopIndex]; + numVars = varListPtr->numVars; for (j = 0; j < numVars; j++) { const char *varName = varvList[loopIndex][j]; int nameChars = strlen(varName); @@ -1702,7 +1707,6 @@ TclCompileForeachCmd( varListPtr->varIndexes[j] = TclFindCompiledLocal(varName, nameChars, /*create*/ 1, procPtr); } - infoPtr->varLists[loopIndex] = varListPtr; } infoIndex = TclCreateAuxData(infoPtr, &tclForeachInfoType, envPtr); @@ -1816,6 +1820,11 @@ TclCompileForeachCmd( envPtr->currStackDepth = savedStackDepth + 1; done: + if (code == TCL_ERROR) { + if (infoPtr) { + FreeForeachInfo(infoPtr); + } + } for (loopIndex = 0; loopIndex < numLists; loopIndex++) { if (varvList[loopIndex] != NULL) { ckfree((char *) varvList[loopIndex]); -- cgit v0.12 From f664d633e6a5f16b3af12c6b9fa406636711068c Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 18 Dec 2014 20:34:12 +0000 Subject: With that shift, varcList is no longer needed. --- generic/tclCompCmds.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/generic/tclCompCmds.c b/generic/tclCompCmds.c index f07b19f..739bf21 100644 --- a/generic/tclCompCmds.c +++ b/generic/tclCompCmds.c @@ -1553,11 +1553,9 @@ TclCompileForeachCmd( /* * We parse the variable list argument words and create two arrays: - * varcList[i] is number of variables in i-th var list. * varvList[i] points to array of var names in i-th var list. */ - int *varcList; const char ***varvList; /* @@ -1592,8 +1590,6 @@ TclCompileForeachCmd( */ numLists = (numWords - 2)/2; - varcList = (int *) TclStackAlloc(interp, numLists * sizeof(int)); - memset(varcList, 0, numLists * sizeof(int)); varvList = (const char ***) TclStackAlloc(interp, numLists * sizeof(const char **)); memset((char*) varvList, 0, numLists * sizeof(const char **)); @@ -1637,13 +1633,12 @@ TclCompileForeachCmd( Tcl_DStringInit(&varList); Tcl_DStringAppend(&varList, tokenPtr[1].start, tokenPtr[1].size); code = Tcl_SplitList(interp, Tcl_DStringValue(&varList), - &varcList[loopIndex], &varvList[loopIndex]); + &numVars, &varvList[loopIndex]); Tcl_DStringFree(&varList); if (code != TCL_OK) { code = TCL_ERROR; goto done; } - numVars = varcList[loopIndex]; varListPtr = (ForeachVarList *) ckalloc((unsigned) sizeof(ForeachVarList) + numVars*sizeof(int)); @@ -1831,7 +1826,6 @@ TclCompileForeachCmd( } } TclStackFree(interp, (void *)varvList); - TclStackFree(interp, varcList); return code; } -- cgit v0.12 From 89e6a65411bda475baf46fcc2b3cf36c2eb81b4c Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 18 Dec 2014 20:38:53 +0000 Subject: Simplify creation and storage of temporaries --- generic/tclCompCmds.c | 24 +++++++----------------- 1 file changed, 7 insertions(+), 17 deletions(-) diff --git a/generic/tclCompCmds.c b/generic/tclCompCmds.c index 739bf21..d2d14f0 100644 --- a/generic/tclCompCmds.c +++ b/generic/tclCompCmds.c @@ -1539,10 +1539,6 @@ TclCompileForeachCmd( ForeachInfo *infoPtr = NULL;/* Points to the structure describing this * foreach command. Stored in a AuxData * record in the ByteCode. */ - int firstValueTemp; /* Index of the first temp var in the frame - * used to point to a value list. */ - int loopCtTemp; /* Index of temp var holding the loop's - * iteration count. */ Tcl_Token *tokenPtr, *bodyTokenPtr; unsigned char *jumpPc; JumpFixup jumpFalseFixup; @@ -1679,19 +1675,14 @@ TclCompileForeachCmd( */ code = TCL_OK; - firstValueTemp = -1; - for (loopIndex = 0; loopIndex < numLists; loopIndex++) { - tempVar = TclFindCompiledLocal(NULL, /*nameChars*/ 0, - /*create*/ 1, procPtr); - if (loopIndex == 0) { - firstValueTemp = tempVar; - } + + tempVar = TclFindCompiledLocal(NULL, 0, 1, procPtr); + infoPtr->firstValueTemp = tempVar; + for (loopIndex = 1; loopIndex < numLists; loopIndex++) { + TclFindCompiledLocal(NULL, 0, 1, procPtr); } - loopCtTemp = TclFindCompiledLocal(NULL, /*nameChars*/ 0, - /*create*/ 1, procPtr); + infoPtr->loopCtTemp = TclFindCompiledLocal(NULL, 0, 1, procPtr); - infoPtr->firstValueTemp = firstValueTemp; - infoPtr->loopCtTemp = loopCtTemp; for (loopIndex = 0; loopIndex < numLists; loopIndex++) { ForeachVarList *varListPtr = infoPtr->varLists[loopIndex]; numVars = varListPtr->numVars; @@ -1722,14 +1713,13 @@ TclCompileForeachCmd( if ((i%2 == 0) && (i > 0)) { SetLineInformation (i); CompileTokens(envPtr, tokenPtr, interp); - tempVar = (firstValueTemp + loopIndex); if (tempVar <= 255) { TclEmitInstInt1(INST_STORE_SCALAR1, tempVar, envPtr); } else { TclEmitInstInt4(INST_STORE_SCALAR4, tempVar, envPtr); } TclEmitOpcode(INST_POP, envPtr); - loopIndex++; + loopIndex++; tempVar++; } } -- cgit v0.12 From 24817641b1ed1c0c461993db32e92d2a947319de Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 18 Dec 2014 21:08:53 +0000 Subject: Replace use of TclIsLocalScalar() and late setting of varIndexes with an earlier setting of varIndexes using PushVarNameWord(). --- generic/tclCompCmds.c | 44 +++++++++++++++++++++++++++++--------------- 1 file changed, 29 insertions(+), 15 deletions(-) diff --git a/generic/tclCompCmds.c b/generic/tclCompCmds.c index d2d14f0..bae1fd1 100644 --- a/generic/tclCompCmds.c +++ b/generic/tclCompCmds.c @@ -1545,6 +1545,7 @@ TclCompileForeachCmd( int jumpBackDist, jumpBackOffset, infoIndex, range; int numWords, numLists, numVars, loopIndex, tempVar, i, j, code; int savedStackDepth = envPtr->currStackDepth; + Tcl_Obj *varListObj = NULL; DefineLineInformation; /* TIP #280 */ /* @@ -1607,6 +1608,7 @@ TclCompileForeachCmd( */ loopIndex = 0; + varListObj = Tcl_NewObj(); for (i = 0, tokenPtr = parsePtr->tokenPtr; i < numWords-1; i++, tokenPtr = TokenAfter(tokenPtr)) { @@ -1616,7 +1618,16 @@ TclCompileForeachCmd( if (i%2 != 1) { continue; } - if (tokenPtr->type != TCL_TOKEN_SIMPLE_WORD) { + + /* + * If the variable list is empty, we can enter an infinite loop when + * the interpreted version would not. Take care to ensure this does + * not happen. [Bug 1671138] + */ + + if (!TclWordKnownAtCompileTime(tokenPtr, varListObj) || + TCL_OK != Tcl_ListObjLength(NULL, varListObj, &numVars) || + numVars == 0) { code = TCL_ERROR; goto done; } @@ -1642,25 +1653,23 @@ TclCompileForeachCmd( infoPtr->varLists[loopIndex] = varListPtr; infoPtr->numLists++; - /* - * If the variable list is empty, we can enter an infinite loop when - * the interpreted version would not. Take care to ensure this does - * not happen. [Bug 1671138] - */ - - if (numVars == 0) { - code = TCL_ERROR; - goto done; - } - for (j = 0; j < numVars; j++) { - const char *varName = varvList[loopIndex][j]; - - if (!TclIsLocalScalar(varName, (int) strlen(varName))) { + Tcl_Obj *varNameObj; + Tcl_Token token; + int varIndex, isSimple, isScalar; + + Tcl_ListObjIndex(NULL, varListObj, j, &varNameObj); + token.start = Tcl_GetStringFromObj(varNameObj, &token.size); + PushVarNameWord(interp, &token, envPtr, TCL_CREATE_VAR, + &varIndex, &isSimple, &isScalar, 0 /* ignored */); + if (!isScalar || varIndex < 0) { code = TCL_ERROR; goto done; } + varListPtr->varIndexes[j] = varIndex; } + + Tcl_SetObjLength(varListObj, 0); loopIndex++; } @@ -1683,6 +1692,7 @@ TclCompileForeachCmd( } infoPtr->loopCtTemp = TclFindCompiledLocal(NULL, 0, 1, procPtr); +#if 0 for (loopIndex = 0; loopIndex < numLists; loopIndex++) { ForeachVarList *varListPtr = infoPtr->varLists[loopIndex]; numVars = varListPtr->numVars; @@ -1694,6 +1704,7 @@ TclCompileForeachCmd( nameChars, /*create*/ 1, procPtr); } } +#endif infoIndex = TclCreateAuxData(infoPtr, &tclForeachInfoType, envPtr); /* @@ -1810,6 +1821,9 @@ TclCompileForeachCmd( FreeForeachInfo(infoPtr); } } + if (varListObj) { + Tcl_DecrRefCount(varListObj); + } for (loopIndex = 0; loopIndex < numLists; loopIndex++) { if (varvList[loopIndex] != NULL) { ckfree((char *) varvList[loopIndex]); -- cgit v0.12 From 893c9c730286e9cdb5d98d190d4ff5877fd47efb Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 18 Dec 2014 21:29:07 +0000 Subject: Fix up the token array passed to PushVarNameWord. Remove string list parse. --- generic/tclCompCmds.c | 39 ++++++--------------------------------- 1 file changed, 6 insertions(+), 33 deletions(-) diff --git a/generic/tclCompCmds.c b/generic/tclCompCmds.c index bae1fd1..6fa1e71 100644 --- a/generic/tclCompCmds.c +++ b/generic/tclCompCmds.c @@ -1543,7 +1543,7 @@ TclCompileForeachCmd( unsigned char *jumpPc; JumpFixup jumpFalseFixup; int jumpBackDist, jumpBackOffset, infoIndex, range; - int numWords, numLists, numVars, loopIndex, tempVar, i, j, code; + int numWords, numLists, numVars, loopIndex, tempVar, i, j, code = TCL_OK; int savedStackDepth = envPtr->currStackDepth; Tcl_Obj *varListObj = NULL; DefineLineInformation; /* TIP #280 */ @@ -1612,7 +1612,6 @@ TclCompileForeachCmd( for (i = 0, tokenPtr = parsePtr->tokenPtr; i < numWords-1; i++, tokenPtr = TokenAfter(tokenPtr)) { - Tcl_DString varList; ForeachVarList *varListPtr; if (i%2 != 1) { @@ -1632,21 +1631,6 @@ TclCompileForeachCmd( goto done; } - /* - * Lots of copying going on here. Need a ListObj wizard to show a - * better way. - */ - - Tcl_DStringInit(&varList); - Tcl_DStringAppend(&varList, tokenPtr[1].start, tokenPtr[1].size); - code = Tcl_SplitList(interp, Tcl_DStringValue(&varList), - &numVars, &varvList[loopIndex]); - Tcl_DStringFree(&varList); - if (code != TCL_OK) { - code = TCL_ERROR; - goto done; - } - varListPtr = (ForeachVarList *) ckalloc((unsigned) sizeof(ForeachVarList) + numVars*sizeof(int)); varListPtr->numVars = numVars; @@ -1655,12 +1639,14 @@ TclCompileForeachCmd( for (j = 0; j < numVars; j++) { Tcl_Obj *varNameObj; - Tcl_Token token; + Tcl_Token token[2]; int varIndex, isSimple, isScalar; Tcl_ListObjIndex(NULL, varListObj, j, &varNameObj); - token.start = Tcl_GetStringFromObj(varNameObj, &token.size); - PushVarNameWord(interp, &token, envPtr, TCL_CREATE_VAR, + token[0].type = TCL_TOKEN_SIMPLE_WORD; + token[0].numComponents = 1; + token[1].start = Tcl_GetStringFromObj(varNameObj, &token[1].size); + PushVarNameWord(interp, token, envPtr, TCL_CREATE_VAR, &varIndex, &isSimple, &isScalar, 0 /* ignored */); if (!isScalar || varIndex < 0) { code = TCL_ERROR; @@ -1692,19 +1678,6 @@ TclCompileForeachCmd( } infoPtr->loopCtTemp = TclFindCompiledLocal(NULL, 0, 1, procPtr); -#if 0 - for (loopIndex = 0; loopIndex < numLists; loopIndex++) { - ForeachVarList *varListPtr = infoPtr->varLists[loopIndex]; - numVars = varListPtr->numVars; - for (j = 0; j < numVars; j++) { - const char *varName = varvList[loopIndex][j]; - int nameChars = strlen(varName); - - varListPtr->varIndexes[j] = TclFindCompiledLocal(varName, - nameChars, /*create*/ 1, procPtr); - } - } -#endif infoIndex = TclCreateAuxData(infoPtr, &tclForeachInfoType, envPtr); /* -- cgit v0.12 From f65cb994d8c1ae7358d383f10c983758eb59fdf0 Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 18 Dec 2014 22:00:08 +0000 Subject: No need for varvList any more. --- generic/tclCompCmds.c | 27 ++------------------------- 1 file changed, 2 insertions(+), 25 deletions(-) diff --git a/generic/tclCompCmds.c b/generic/tclCompCmds.c index 6fa1e71..1bafbe2 100644 --- a/generic/tclCompCmds.c +++ b/generic/tclCompCmds.c @@ -1549,13 +1549,6 @@ TclCompileForeachCmd( DefineLineInformation; /* TIP #280 */ /* - * We parse the variable list argument words and create two arrays: - * varvList[i] points to array of var names in i-th var list. - */ - - const char ***varvList; - - /* * If the foreach command isn't in a procedure, don't compile it inline: * the payoff is too small. */ @@ -1583,26 +1576,18 @@ TclCompileForeachCmd( } /* - * Allocate storage for the varcList and varvList arrays if necessary. - */ - - numLists = (numWords - 2)/2; - varvList = (const char ***) TclStackAlloc(interp, - numLists * sizeof(const char **)); - memset((char*) varvList, 0, numLists * sizeof(const char **)); - - /* * Create and initialize the ForeachInfo and ForeachVarList data * structures describing this command. Then create a AuxData record * pointing to the ForeachInfo structure. */ + numLists = (numWords - 2)/2; infoPtr = (ForeachInfo *) ckalloc((unsigned) sizeof(ForeachInfo) + numLists*sizeof(ForeachVarList *)); infoPtr->numLists = 0; /* Count this up as we go */ /* - * Break up each var list and set the varcList and varvList arrays. Don't + * Parse each var list into sequence of var names. Don't * compile the foreach inline if any var name needs substitutions or isn't * a scalar, or if any var list needs substitutions. */ @@ -1669,8 +1654,6 @@ TclCompileForeachCmd( * nonoverlapping foreach loops, they don't share any temps. */ - code = TCL_OK; - tempVar = TclFindCompiledLocal(NULL, 0, 1, procPtr); infoPtr->firstValueTemp = tempVar; for (loopIndex = 1; loopIndex < numLists; loopIndex++) { @@ -1797,12 +1780,6 @@ TclCompileForeachCmd( if (varListObj) { Tcl_DecrRefCount(varListObj); } - for (loopIndex = 0; loopIndex < numLists; loopIndex++) { - if (varvList[loopIndex] != NULL) { - ckfree((char *) varvList[loopIndex]); - } - } - TclStackFree(interp, (void *)varvList); return code; } -- cgit v0.12 From aed72bee30f449ec04643ceb42df9d45b635892e Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 18 Dec 2014 22:13:11 +0000 Subject: No need for a loopIndex. --- generic/tclCompCmds.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/generic/tclCompCmds.c b/generic/tclCompCmds.c index 1bafbe2..0030f62 100644 --- a/generic/tclCompCmds.c +++ b/generic/tclCompCmds.c @@ -1543,7 +1543,7 @@ TclCompileForeachCmd( unsigned char *jumpPc; JumpFixup jumpFalseFixup; int jumpBackDist, jumpBackOffset, infoIndex, range; - int numWords, numLists, numVars, loopIndex, tempVar, i, j, code = TCL_OK; + int numWords, numLists, numVars, tempVar, i, j, code = TCL_OK; int savedStackDepth = envPtr->currStackDepth; Tcl_Obj *varListObj = NULL; DefineLineInformation; /* TIP #280 */ @@ -1592,7 +1592,6 @@ TclCompileForeachCmd( * a scalar, or if any var list needs substitutions. */ - loopIndex = 0; varListObj = Tcl_NewObj(); for (i = 0, tokenPtr = parsePtr->tokenPtr; i < numWords-1; @@ -1619,7 +1618,7 @@ TclCompileForeachCmd( varListPtr = (ForeachVarList *) ckalloc((unsigned) sizeof(ForeachVarList) + numVars*sizeof(int)); varListPtr->numVars = numVars; - infoPtr->varLists[loopIndex] = varListPtr; + infoPtr->varLists[i/2] = varListPtr; infoPtr->numLists++; for (j = 0; j < numVars; j++) { @@ -1641,7 +1640,6 @@ TclCompileForeachCmd( } Tcl_SetObjLength(varListObj, 0); - loopIndex++; } /* @@ -1656,7 +1654,7 @@ TclCompileForeachCmd( tempVar = TclFindCompiledLocal(NULL, 0, 1, procPtr); infoPtr->firstValueTemp = tempVar; - for (loopIndex = 1; loopIndex < numLists; loopIndex++) { + for (i= 1; i < numLists; i++) { TclFindCompiledLocal(NULL, 0, 1, procPtr); } infoPtr->loopCtTemp = TclFindCompiledLocal(NULL, 0, 1, procPtr); @@ -1673,7 +1671,6 @@ TclCompileForeachCmd( * Evaluate then store each value list in the associated temporary. */ - loopIndex = 0; for (i = 0, tokenPtr = parsePtr->tokenPtr; i < numWords-1; i++, tokenPtr = TokenAfter(tokenPtr)) { @@ -1686,7 +1683,7 @@ TclCompileForeachCmd( TclEmitInstInt4(INST_STORE_SCALAR4, tempVar, envPtr); } TclEmitOpcode(INST_POP, envPtr); - loopIndex++; tempVar++; + tempVar++; } } -- cgit v0.12 From ad195509092cfe037495a4817597fccf012bf686 Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 18 Dec 2014 22:25:27 +0000 Subject: A bit more tidying... --- generic/tclCompCmds.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/generic/tclCompCmds.c b/generic/tclCompCmds.c index 0030f62..002012e 100644 --- a/generic/tclCompCmds.c +++ b/generic/tclCompCmds.c @@ -1540,6 +1540,7 @@ TclCompileForeachCmd( * foreach command. Stored in a AuxData * record in the ByteCode. */ Tcl_Token *tokenPtr, *bodyTokenPtr; + Tcl_Token token[2]; unsigned char *jumpPc; JumpFixup jumpFalseFixup; int jumpBackDist, jumpBackOffset, infoIndex, range; @@ -1593,6 +1594,8 @@ TclCompileForeachCmd( */ varListObj = Tcl_NewObj(); + token[0].type = TCL_TOKEN_SIMPLE_WORD; + token[0].numComponents = 1; for (i = 0, tokenPtr = parsePtr->tokenPtr; i < numWords-1; i++, tokenPtr = TokenAfter(tokenPtr)) { @@ -1623,12 +1626,9 @@ TclCompileForeachCmd( for (j = 0; j < numVars; j++) { Tcl_Obj *varNameObj; - Tcl_Token token[2]; int varIndex, isSimple, isScalar; Tcl_ListObjIndex(NULL, varListObj, j, &varNameObj); - token[0].type = TCL_TOKEN_SIMPLE_WORD; - token[0].numComponents = 1; token[1].start = Tcl_GetStringFromObj(varNameObj, &token[1].size); PushVarNameWord(interp, token, envPtr, TCL_CREATE_VAR, &varIndex, &isSimple, &isScalar, 0 /* ignored */); @@ -1638,13 +1638,11 @@ TclCompileForeachCmd( } varListPtr->varIndexes[j] = varIndex; } - Tcl_SetObjLength(varListObj, 0); } /* - * We will compile the foreach command. Reserve (numLists + 1) temporary - * variables: + * Reserve (numLists + 1) temporary variables: * - numLists temps to hold each value list * - 1 temp for the loop counter (index of next element in each list) * -- cgit v0.12 From 88ec3c9772a4b3e03d7e18067452ae8b67a7b3c7 Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 19 Dec 2014 03:31:09 +0000 Subject: Narrow scope of numVars. --- generic/tclCompCmds.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/generic/tclCompCmds.c b/generic/tclCompCmds.c index 002012e..48eafe5 100644 --- a/generic/tclCompCmds.c +++ b/generic/tclCompCmds.c @@ -1544,7 +1544,7 @@ TclCompileForeachCmd( unsigned char *jumpPc; JumpFixup jumpFalseFixup; int jumpBackDist, jumpBackOffset, infoIndex, range; - int numWords, numLists, numVars, tempVar, i, j, code = TCL_OK; + int numWords, numLists, tempVar, i, j, code = TCL_OK; int savedStackDepth = envPtr->currStackDepth; Tcl_Obj *varListObj = NULL; DefineLineInformation; /* TIP #280 */ @@ -1600,6 +1600,7 @@ TclCompileForeachCmd( i < numWords-1; i++, tokenPtr = TokenAfter(tokenPtr)) { ForeachVarList *varListPtr; + int numVars; if (i%2 != 1) { continue; -- cgit v0.12 From baf649278ac11f772a6921121574bb6fe65ed127 Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 19 Dec 2014 14:17:03 +0000 Subject: Replace TclIsLocalScalar() with PushVarNameWord() in [dict for] compiler. --- generic/tclCompCmds.c | 53 ++++++++++++++++++++++++++------------------------- 1 file changed, 27 insertions(+), 26 deletions(-) diff --git a/generic/tclCompCmds.c b/generic/tclCompCmds.c index 48eafe5..9ccfcb6 100644 --- a/generic/tclCompCmds.c +++ b/generic/tclCompCmds.c @@ -806,16 +806,17 @@ TclCompileDictForCmd( CompileEnv *envPtr) /* Holds resulting instructions. */ { Proc *procPtr = envPtr->procPtr; - DefineLineInformation; /* TIP #280 */ Tcl_Token *varsTokenPtr, *dictTokenPtr, *bodyTokenPtr; - int keyVarIndex, valueVarIndex, nameChars, loopRange, catchRange; + int keyVarIndex, valueVarIndex, loopRange, catchRange; int infoIndex, jumpDisplacement, bodyTargetOffset, emptyTargetOffset; - int numVars, endTargetOffset; + int numVars, endTargetOffset, isSimple, isScalar; int savedStackDepth = envPtr->currStackDepth; /* Needed because jumps confuse the stack * space calculator. */ - const char **argv; - Tcl_DString buffer; + Tcl_Obj *varNameObj, *varListObj = NULL; + Tcl_Token token[2] = {{TCL_TOKEN_SIMPLE_WORD, NULL, 0, 1}, + {TCL_TOKEN_TEXT, NULL, 0, 0}}; + DefineLineInformation; /* TIP #280 */ /* * There must be exactly three arguments after the command. @@ -828,8 +829,8 @@ TclCompileDictForCmd( varsTokenPtr = TokenAfter(parsePtr->tokenPtr); dictTokenPtr = TokenAfter(varsTokenPtr); bodyTokenPtr = TokenAfter(dictTokenPtr); - if (varsTokenPtr->type != TCL_TOKEN_SIMPLE_WORD || - bodyTokenPtr->type != TCL_TOKEN_SIMPLE_WORD) { + + if (bodyTokenPtr->type != TCL_TOKEN_SIMPLE_WORD) { return TCL_ERROR; } @@ -838,33 +839,33 @@ TclCompileDictForCmd( * Then extract their indices in the LVT. */ - Tcl_DStringInit(&buffer); - Tcl_DStringAppend(&buffer, varsTokenPtr[1].start, varsTokenPtr[1].size); - if (Tcl_SplitList(NULL, Tcl_DStringValue(&buffer), &numVars, - &argv) != TCL_OK) { - Tcl_DStringFree(&buffer); - return TCL_ERROR; - } - Tcl_DStringFree(&buffer); - if (numVars != 2) { - ckfree((char *) argv); + varListObj = Tcl_NewObj(); + if (!TclWordKnownAtCompileTime(varsTokenPtr, varListObj) || + TCL_OK != Tcl_ListObjLength(NULL, varListObj, &numVars) || + numVars != 2) { + Tcl_DecrRefCount(varListObj); return TCL_ERROR; } - nameChars = strlen(argv[0]); - if (!TclIsLocalScalar(argv[0], nameChars)) { - ckfree((char *) argv); + Tcl_ListObjIndex(NULL, varListObj, 0, &varNameObj); + token[1].start = Tcl_GetStringFromObj(varNameObj, &token[1].size); + PushVarNameWord(interp, token, envPtr, TCL_CREATE_VAR, + &keyVarIndex, &isSimple, &isScalar, 0 /* ignored */); + if (!isScalar || keyVarIndex < 0) { + Tcl_DecrRefCount(varListObj); return TCL_ERROR; } - keyVarIndex = TclFindCompiledLocal(argv[0], nameChars, 1, procPtr); - nameChars = strlen(argv[1]); - if (!TclIsLocalScalar(argv[1], nameChars)) { - ckfree((char *) argv); + Tcl_ListObjIndex(NULL, varListObj, 1, &varNameObj); + token[1].start = Tcl_GetStringFromObj(varNameObj, &token[1].size); + PushVarNameWord(interp, token, envPtr, TCL_CREATE_VAR, + &valueVarIndex, &isSimple, &isScalar, 0 /* ignored */); + if (!isScalar || valueVarIndex < 0) { + Tcl_DecrRefCount(varListObj); return TCL_ERROR; } - valueVarIndex = TclFindCompiledLocal(argv[1], nameChars, 1, procPtr); - ckfree((char *) argv); + + Tcl_DecrRefCount(varListObj); /* * Allocate a temporary variable to store the iterator reference. The -- cgit v0.12 From 18131f9c09f735616d65001add027710eee6ad27 Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 19 Dec 2014 14:21:42 +0000 Subject: With no callers left, TclIsLocalScalar() is removed. --- generic/tclInt.h | 1 - generic/tclParse.c | 50 -------------------------------------------------- 2 files changed, 51 deletions(-) diff --git a/generic/tclInt.h b/generic/tclInt.h index 255ee23..18574c3 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -2606,7 +2606,6 @@ MODULE_SCOPE void TclInitNotifier(void); MODULE_SCOPE void TclInitObjSubsystem(void); MODULE_SCOPE void TclInitSubsystems(void); MODULE_SCOPE int TclInterpReady(Tcl_Interp *interp); -MODULE_SCOPE int TclIsLocalScalar(const char *src, int len); MODULE_SCOPE int TclIsSpaceProc(char byte); MODULE_SCOPE int TclIsBareword(char byte); MODULE_SCOPE int TclJoinThread(Tcl_ThreadId id, int *result); diff --git a/generic/tclParse.c b/generic/tclParse.c index 025304c..c07336f 100644 --- a/generic/tclParse.c +++ b/generic/tclParse.c @@ -2563,56 +2563,6 @@ TclObjCommandComplete( } /* - *---------------------------------------------------------------------- - * - * TclIsLocalScalar -- - * - * Check to see if a given string is a legal scalar variable name with no - * namespace qualifiers or substitutions. - * - * Results: - * Returns 1 if the variable is a local scalar. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -int -TclIsLocalScalar( - const char *src, - int len) -{ - const char *p; - const char *lastChar = src + (len - 1); - - for (p=src ; p<=lastChar ; p++) { - if ((CHAR_TYPE(*p) != TYPE_NORMAL) && - (CHAR_TYPE(*p) != TYPE_COMMAND_END)) { - /* - * TCL_COMMAND_END is returned for the last character of the - * string. By this point we know it isn't an array or namespace - * reference. - */ - - return 0; - } - if (*p == '(') { - if (*lastChar == ')') { /* We have an array element */ - return 0; - } - } else if (*p == ':') { - if ((p != lastChar) && *(p+1) == ':') { /* qualified name */ - return 0; - } - } - } - - return 1; -} - -/* * Local Variables: * mode: c * c-basic-offset: 4 -- cgit v0.12 From 2613112a13e8acb4974fb7006cc44581299dd3ce Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 19 Dec 2014 15:13:11 +0000 Subject: Use interp==NULL argument to PushVarName to signal that only an index into the CLT is sought, and no time should be wasted compiling other cases which the caller is just going to discard. --- generic/tclCompCmds.c | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/generic/tclCompCmds.c b/generic/tclCompCmds.c index 9ccfcb6..7577bd3 100644 --- a/generic/tclCompCmds.c +++ b/generic/tclCompCmds.c @@ -402,7 +402,7 @@ TclCompileCatchCmd( cmdTokenPtr = TokenAfter(parsePtr->tokenPtr); if (parsePtr->numWords >= 3) { resultNameTokenPtr = TokenAfter(cmdTokenPtr); - PushVarNameWord(interp, resultNameTokenPtr, envPtr, TCL_CREATE_VAR, + PushVarNameWord(NULL, resultNameTokenPtr, envPtr, TCL_CREATE_VAR, &resultIndex, &isSimple, &isScalar, 2); if (!isScalar || resultIndex < 0) { return TCL_ERROR; @@ -410,7 +410,7 @@ TclCompileCatchCmd( if (parsePtr->numWords == 4) { optsNameTokenPtr = TokenAfter(resultNameTokenPtr); - PushVarNameWord(interp, optsNameTokenPtr, envPtr, TCL_CREATE_VAR, + PushVarNameWord(NULL, optsNameTokenPtr, envPtr, TCL_CREATE_VAR, &optsIndex, &isSimple, &isScalar, 3); if (!isScalar || resultIndex < 0) { return TCL_ERROR; @@ -673,7 +673,7 @@ TclCompileDictSetCmd( */ varTokenPtr = TokenAfter(parsePtr->tokenPtr); - PushVarNameWord(interp, varTokenPtr, envPtr, TCL_CREATE_VAR, + PushVarNameWord(NULL, varTokenPtr, envPtr, TCL_CREATE_VAR, &dictVarIndex, &isSimple, &isScalar, 1); if (!isScalar || dictVarIndex < 0) { return TCL_ERROR; @@ -726,7 +726,7 @@ TclCompileDictIncrCmd( */ varTokenPtr = TokenAfter(parsePtr->tokenPtr); - PushVarNameWord(interp, varTokenPtr, envPtr, TCL_CREATE_VAR, + PushVarNameWord(NULL, varTokenPtr, envPtr, TCL_CREATE_VAR, &dictVarIndex, &isSimple, &isScalar, 1); if (!isScalar || dictVarIndex < 0) { return TCL_ERROR; @@ -849,7 +849,7 @@ TclCompileDictForCmd( Tcl_ListObjIndex(NULL, varListObj, 0, &varNameObj); token[1].start = Tcl_GetStringFromObj(varNameObj, &token[1].size); - PushVarNameWord(interp, token, envPtr, TCL_CREATE_VAR, + PushVarNameWord(NULL, token, envPtr, TCL_CREATE_VAR, &keyVarIndex, &isSimple, &isScalar, 0 /* ignored */); if (!isScalar || keyVarIndex < 0) { Tcl_DecrRefCount(varListObj); @@ -858,7 +858,7 @@ TclCompileDictForCmd( Tcl_ListObjIndex(NULL, varListObj, 1, &varNameObj); token[1].start = Tcl_GetStringFromObj(varNameObj, &token[1].size); - PushVarNameWord(interp, token, envPtr, TCL_CREATE_VAR, + PushVarNameWord(NULL, token, envPtr, TCL_CREATE_VAR, &valueVarIndex, &isSimple, &isScalar, 0 /* ignored */); if (!isScalar || valueVarIndex < 0) { Tcl_DecrRefCount(varListObj); @@ -1031,7 +1031,7 @@ TclCompileDictUpdateCmd( */ dictVarTokenPtr = TokenAfter(parsePtr->tokenPtr); - PushVarNameWord(interp, dictVarTokenPtr, envPtr, TCL_CREATE_VAR, + PushVarNameWord(NULL, dictVarTokenPtr, envPtr, TCL_CREATE_VAR, &dictIndex, &isSimple, &isScalar, 1); if (!isScalar || dictIndex < 0) { return TCL_ERROR; @@ -1064,7 +1064,7 @@ TclCompileDictUpdateCmd( */ tokenPtr = TokenAfter(tokenPtr); - PushVarNameWord(interp, tokenPtr, envPtr, TCL_CREATE_VAR, + PushVarNameWord(NULL, tokenPtr, envPtr, TCL_CREATE_VAR, &index, &isSimple, &isScalar, 1); if (!isScalar || index < 0) { ckfree((char *) duiPtr); @@ -1176,7 +1176,7 @@ TclCompileDictAppendCmd( */ tokenPtr = TokenAfter(parsePtr->tokenPtr); - PushVarNameWord(interp, tokenPtr, envPtr, TCL_CREATE_VAR, + PushVarNameWord(NULL, tokenPtr, envPtr, TCL_CREATE_VAR, &dictVarIndex, &isSimple, &isScalar, 1); if (!isScalar || dictVarIndex < 0) { return TCL_ERROR; @@ -1227,7 +1227,7 @@ TclCompileDictLappendCmd( varTokenPtr = TokenAfter(parsePtr->tokenPtr); keyTokenPtr = TokenAfter(varTokenPtr); valueTokenPtr = TokenAfter(keyTokenPtr); - PushVarNameWord(interp, varTokenPtr, envPtr, TCL_CREATE_VAR, + PushVarNameWord(NULL, varTokenPtr, envPtr, TCL_CREATE_VAR, &dictVarIndex, &isSimple, &isScalar, 1); if (!isScalar || dictVarIndex < 0) { return TCL_ERROR; @@ -1632,7 +1632,7 @@ TclCompileForeachCmd( Tcl_ListObjIndex(NULL, varListObj, j, &varNameObj); token[1].start = Tcl_GetStringFromObj(varNameObj, &token[1].size); - PushVarNameWord(interp, token, envPtr, TCL_CREATE_VAR, + PushVarNameWord(NULL, token, envPtr, TCL_CREATE_VAR, &varIndex, &isSimple, &isScalar, 0 /* ignored */); if (!isScalar || varIndex < 0) { code = TCL_ERROR; @@ -4805,7 +4805,7 @@ PushVarName( elemTokenCount = 1; } } - } else if (((n = varTokenPtr->numComponents) > 1) + } else if (interp && ((n = varTokenPtr->numComponents) > 1) && (varTokenPtr[1].type == TCL_TOKEN_TEXT) && (varTokenPtr[n].type == TCL_TOKEN_TEXT) && (varTokenPtr[n].start[varTokenPtr[n].size - 1] == ')')) { @@ -4907,7 +4907,7 @@ PushVarName( localIndex = -1; } } - if (localIndex < 0) { + if (interp && localIndex < 0) { PushLiteral(envPtr, name, nameChars); } @@ -4915,7 +4915,7 @@ PushVarName( * Compile the element script, if any. */ - if (elName != NULL) { + if (interp && elName != NULL) { if (elNameChars) { envPtr->line = line; envPtr->clNext = clNext; @@ -4924,7 +4924,7 @@ PushVarName( PushLiteral(envPtr, "", 0); } } - } else { + } else if (interp) { /* * The var name isn't simple: compile and push it. */ @@ -5708,7 +5708,7 @@ TclCompileUpvarCmd( localTokenPtr = TokenAfter(otherTokenPtr); CompileWord(envPtr, otherTokenPtr, interp, i); - PushVarNameWord(interp, localTokenPtr, envPtr, TCL_CREATE_VAR, + PushVarNameWord(NULL, localTokenPtr, envPtr, TCL_CREATE_VAR, &localIndex, &simpleVarName, &isScalar, i+1); if((localIndex < 0) || !isScalar) { @@ -5800,7 +5800,7 @@ TclCompileNamespaceCmd( localTokenPtr = TokenAfter(otherTokenPtr); CompileWord(envPtr, otherTokenPtr, interp, i); - PushVarNameWord(interp, localTokenPtr, envPtr, TCL_CREATE_VAR, + PushVarNameWord(NULL, localTokenPtr, envPtr, TCL_CREATE_VAR, &localIndex, &simpleVarName, &isScalar, i+1); if((localIndex < 0) || !isScalar) { -- cgit v0.12 From cfefe7127b6d560629dbcfee782578099e42d895 Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 19 Dec 2014 15:55:21 +0000 Subject: New utility routine GetLocalScalarIndex() reduces common caller boilerplate (and fixes a bug!) --- generic/tclCompCmds.c | 112 ++++++++++++++++++++++++++------------------------ 1 file changed, 58 insertions(+), 54 deletions(-) diff --git a/generic/tclCompCmds.c b/generic/tclCompCmds.c index 7577bd3..6821637 100644 --- a/generic/tclCompCmds.c +++ b/generic/tclCompCmds.c @@ -152,6 +152,8 @@ static void FreeJumptableInfo(ClientData clientData); static void PrintJumptableInfo(ClientData clientData, Tcl_Obj *appendObj, ByteCode *codePtr, unsigned int pcOffset); +static int GetLocalScalarIndex(Tcl_Token *tokenPtr, + CompileEnv *envPtr, int *indexPtr); static int PushVarName(Tcl_Interp *interp, Tcl_Token *varTokenPtr, CompileEnv *envPtr, int flags, int *localIndexPtr, @@ -379,7 +381,7 @@ TclCompileCatchCmd( { JumpFixup jumpFixup; Tcl_Token *cmdTokenPtr, *resultNameTokenPtr, *optsNameTokenPtr; - int resultIndex, optsIndex, isSimple, isScalar, range; + int resultIndex, optsIndex, range; int initStackDepth = envPtr->currStackDepth; int savedStackDepth; DefineLineInformation; /* TIP #280 */ @@ -402,17 +404,13 @@ TclCompileCatchCmd( cmdTokenPtr = TokenAfter(parsePtr->tokenPtr); if (parsePtr->numWords >= 3) { resultNameTokenPtr = TokenAfter(cmdTokenPtr); - PushVarNameWord(NULL, resultNameTokenPtr, envPtr, TCL_CREATE_VAR, - &resultIndex, &isSimple, &isScalar, 2); - if (!isScalar || resultIndex < 0) { + if (!GetLocalScalarIndex(resultNameTokenPtr, envPtr, &resultIndex)) { return TCL_ERROR; } if (parsePtr->numWords == 4) { optsNameTokenPtr = TokenAfter(resultNameTokenPtr); - PushVarNameWord(NULL, optsNameTokenPtr, envPtr, TCL_CREATE_VAR, - &optsIndex, &isSimple, &isScalar, 3); - if (!isScalar || resultIndex < 0) { + if (!GetLocalScalarIndex(optsNameTokenPtr, envPtr, &optsIndex)) { return TCL_ERROR; } } @@ -653,9 +651,8 @@ TclCompileDictSetCmd( * compiled. */ CompileEnv *envPtr) /* Holds resulting instructions. */ { - Tcl_Token *tokenPtr; - Tcl_Token *varTokenPtr; - int i, isSimple, isScalar = 0, dictVarIndex = -1; + Tcl_Token *tokenPtr, *varTokenPtr; + int i, dictVarIndex; DefineLineInformation; /* TIP #280 */ /* @@ -673,9 +670,7 @@ TclCompileDictSetCmd( */ varTokenPtr = TokenAfter(parsePtr->tokenPtr); - PushVarNameWord(NULL, varTokenPtr, envPtr, TCL_CREATE_VAR, - &dictVarIndex, &isSimple, &isScalar, 1); - if (!isScalar || dictVarIndex < 0) { + if (!GetLocalScalarIndex(varTokenPtr, envPtr, &dictVarIndex)) { return TCL_ERROR; } @@ -708,7 +703,7 @@ TclCompileDictIncrCmd( CompileEnv *envPtr) /* Holds resulting instructions. */ { Tcl_Token *varTokenPtr, *keyTokenPtr; - int dictVarIndex, incrAmount, isScalar, isSimple; + int dictVarIndex, incrAmount; DefineLineInformation; /* TIP #280 */ /* @@ -726,9 +721,7 @@ TclCompileDictIncrCmd( */ varTokenPtr = TokenAfter(parsePtr->tokenPtr); - PushVarNameWord(NULL, varTokenPtr, envPtr, TCL_CREATE_VAR, - &dictVarIndex, &isSimple, &isScalar, 1); - if (!isScalar || dictVarIndex < 0) { + if (!GetLocalScalarIndex(varTokenPtr, envPtr, &dictVarIndex)) { return TCL_ERROR; } @@ -809,7 +802,7 @@ TclCompileDictForCmd( Tcl_Token *varsTokenPtr, *dictTokenPtr, *bodyTokenPtr; int keyVarIndex, valueVarIndex, loopRange, catchRange; int infoIndex, jumpDisplacement, bodyTargetOffset, emptyTargetOffset; - int numVars, endTargetOffset, isSimple, isScalar; + int numVars, endTargetOffset; int savedStackDepth = envPtr->currStackDepth; /* Needed because jumps confuse the stack * space calculator. */ @@ -849,18 +842,14 @@ TclCompileDictForCmd( Tcl_ListObjIndex(NULL, varListObj, 0, &varNameObj); token[1].start = Tcl_GetStringFromObj(varNameObj, &token[1].size); - PushVarNameWord(NULL, token, envPtr, TCL_CREATE_VAR, - &keyVarIndex, &isSimple, &isScalar, 0 /* ignored */); - if (!isScalar || keyVarIndex < 0) { + if (!GetLocalScalarIndex(token, envPtr, &keyVarIndex)) { Tcl_DecrRefCount(varListObj); return TCL_ERROR; } Tcl_ListObjIndex(NULL, varListObj, 1, &varNameObj); token[1].start = Tcl_GetStringFromObj(varNameObj, &token[1].size); - PushVarNameWord(NULL, token, envPtr, TCL_CREATE_VAR, - &valueVarIndex, &isSimple, &isScalar, 0 /* ignored */); - if (!isScalar || valueVarIndex < 0) { + if (!GetLocalScalarIndex(token, envPtr, &valueVarIndex)) { Tcl_DecrRefCount(varListObj); return TCL_ERROR; } @@ -1005,7 +994,7 @@ TclCompileDictUpdateCmd( * compiled. */ CompileEnv *envPtr) /* Holds resulting instructions. */ { - int i, dictIndex, numVars, range, infoIndex, isSimple, isScalar; + int i, dictIndex, numVars, range, infoIndex; Tcl_Token **keyTokenPtrs, *dictVarTokenPtr, *bodyTokenPtr, *tokenPtr; DictUpdateInfo *duiPtr; JumpFixup jumpFixup; @@ -1031,9 +1020,7 @@ TclCompileDictUpdateCmd( */ dictVarTokenPtr = TokenAfter(parsePtr->tokenPtr); - PushVarNameWord(NULL, dictVarTokenPtr, envPtr, TCL_CREATE_VAR, - &dictIndex, &isSimple, &isScalar, 1); - if (!isScalar || dictIndex < 0) { + if (!GetLocalScalarIndex(dictVarTokenPtr, envPtr, &dictIndex)) { return TCL_ERROR; } @@ -1064,9 +1051,7 @@ TclCompileDictUpdateCmd( */ tokenPtr = TokenAfter(tokenPtr); - PushVarNameWord(NULL, tokenPtr, envPtr, TCL_CREATE_VAR, - &index, &isSimple, &isScalar, 1); - if (!isScalar || index < 0) { + if (!GetLocalScalarIndex(tokenPtr, envPtr, &index)) { ckfree((char *) duiPtr); TclStackFree(interp, keyTokenPtrs); return TCL_ERROR; @@ -1158,7 +1143,7 @@ TclCompileDictAppendCmd( CompileEnv *envPtr) /* Holds resulting instructions. */ { Tcl_Token *tokenPtr; - int i, isSimple, isScalar, dictVarIndex; + int i, dictVarIndex; DefineLineInformation; /* TIP #280 */ /* @@ -1176,9 +1161,7 @@ TclCompileDictAppendCmd( */ tokenPtr = TokenAfter(parsePtr->tokenPtr); - PushVarNameWord(NULL, tokenPtr, envPtr, TCL_CREATE_VAR, - &dictVarIndex, &isSimple, &isScalar, 1); - if (!isScalar || dictVarIndex < 0) { + if (!GetLocalScalarIndex(tokenPtr, envPtr, &dictVarIndex)) { return TCL_ERROR; } @@ -1213,7 +1196,7 @@ TclCompileDictLappendCmd( CompileEnv *envPtr) /* Holds resulting instructions. */ { Tcl_Token *varTokenPtr, *keyTokenPtr, *valueTokenPtr; - int isSimple, dictVarIndex = -1, isScalar = 0; + int dictVarIndex; DefineLineInformation; /* TIP #280 */ /* @@ -1227,9 +1210,7 @@ TclCompileDictLappendCmd( varTokenPtr = TokenAfter(parsePtr->tokenPtr); keyTokenPtr = TokenAfter(varTokenPtr); valueTokenPtr = TokenAfter(keyTokenPtr); - PushVarNameWord(NULL, varTokenPtr, envPtr, TCL_CREATE_VAR, - &dictVarIndex, &isSimple, &isScalar, 1); - if (!isScalar || dictVarIndex < 0) { + if (!GetLocalScalarIndex(varTokenPtr, envPtr, &dictVarIndex)) { return TCL_ERROR; } CompileWord(envPtr, keyTokenPtr, interp, 2); @@ -1628,17 +1609,14 @@ TclCompileForeachCmd( for (j = 0; j < numVars; j++) { Tcl_Obj *varNameObj; - int varIndex, isSimple, isScalar; Tcl_ListObjIndex(NULL, varListObj, j, &varNameObj); token[1].start = Tcl_GetStringFromObj(varNameObj, &token[1].size); - PushVarNameWord(NULL, token, envPtr, TCL_CREATE_VAR, - &varIndex, &isSimple, &isScalar, 0 /* ignored */); - if (!isScalar || varIndex < 0) { + if (!GetLocalScalarIndex(token, envPtr, + varListPtr->varIndexes + j)) { code = TCL_ERROR; goto done; } - varListPtr->varIndexes[j] = varIndex; } Tcl_SetObjLength(varListObj, 0); } @@ -4717,6 +4695,38 @@ TclCompileWhileCmd( /* *---------------------------------------------------------------------- * + * GetLocalScalarIndex -- + * + * Procedure used in the compiling where pushing a variable name is + * necessary (append, lappend, set). + * + * Results: + * Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer + * evaluation to runtime. + * + * Side effects: + * Instructions are added to envPtr to execute the "set" command at + * runtime. + * + *---------------------------------------------------------------------- + */ + +static int +GetLocalScalarIndex( + Tcl_Token *tokenPtr, + CompileEnv *envPtr, + int *indexPtr) +{ + int isSimple, isScalar; + + PushVarName(NULL, tokenPtr, envPtr, TCL_CREATE_VAR, indexPtr, + &isSimple, &isScalar, 0 /* ignored */, NULL /* ignored */); + return (isScalar && *indexPtr >= 0); +} + +/* + *---------------------------------------------------------------------- + * * PushVarName -- * * Procedure used in the compiling where pushing a variable name is @@ -5645,7 +5655,7 @@ TclCompileUpvarCmd( CompileEnv *envPtr) /* Holds resulting instructions. */ { Tcl_Token *tokenPtr, *otherTokenPtr, *localTokenPtr; - int simpleVarName, isScalar, localIndex, numWords, i; + int localIndex, numWords, i; DefineLineInformation; /* TIP #280 */ Tcl_Obj *objPtr; @@ -5708,10 +5718,7 @@ TclCompileUpvarCmd( localTokenPtr = TokenAfter(otherTokenPtr); CompileWord(envPtr, otherTokenPtr, interp, i); - PushVarNameWord(NULL, localTokenPtr, envPtr, TCL_CREATE_VAR, - &localIndex, &simpleVarName, &isScalar, i+1); - - if((localIndex < 0) || !isScalar) { + if (!GetLocalScalarIndex(localTokenPtr, envPtr, &localIndex)) { return TCL_ERROR; } TclEmitInstInt4(INST_UPVAR, localIndex, envPtr); @@ -5755,7 +5762,7 @@ TclCompileNamespaceCmd( CompileEnv *envPtr) /* Holds resulting instructions. */ { Tcl_Token *tokenPtr, *otherTokenPtr, *localTokenPtr; - int simpleVarName, isScalar, localIndex, numWords, i; + int localIndex, numWords, i; DefineLineInformation; /* TIP #280 */ if (envPtr->procPtr == NULL) { @@ -5800,10 +5807,7 @@ TclCompileNamespaceCmd( localTokenPtr = TokenAfter(otherTokenPtr); CompileWord(envPtr, otherTokenPtr, interp, i); - PushVarNameWord(NULL, localTokenPtr, envPtr, TCL_CREATE_VAR, - &localIndex, &simpleVarName, &isScalar, i+1); - - if((localIndex < 0) || !isScalar) { + if (!GetLocalScalarIndex(localTokenPtr, envPtr, &localIndex)) { return TCL_ERROR; } TclEmitInstInt4(INST_NSUPVAR, localIndex, envPtr); -- cgit v0.12 From f6d6b394ebc2f2b0bfc50edf3a14fb5e4414e8f7 Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 19 Dec 2014 17:09:32 +0000 Subject: Revise name and interface of new utility routines to match work already in place on the trunk. --- generic/tclCompCmds.c | 105 ++++++++++++++++++++++++++++++++------------------ 1 file changed, 67 insertions(+), 38 deletions(-) diff --git a/generic/tclCompCmds.c b/generic/tclCompCmds.c index 6821637..b3568e8 100644 --- a/generic/tclCompCmds.c +++ b/generic/tclCompCmds.c @@ -152,8 +152,10 @@ static void FreeJumptableInfo(ClientData clientData); static void PrintJumptableInfo(ClientData clientData, Tcl_Obj *appendObj, ByteCode *codePtr, unsigned int pcOffset); -static int GetLocalScalarIndex(Tcl_Token *tokenPtr, - CompileEnv *envPtr, int *indexPtr); +static int LocalScalarFromToken(Tcl_Token *tokenPtr, + CompileEnv *envPtr); +static int LocalScalar(const char *bytes, int numBytes, + CompileEnv *envPtr); static int PushVarName(Tcl_Interp *interp, Tcl_Token *varTokenPtr, CompileEnv *envPtr, int flags, int *localIndexPtr, @@ -404,13 +406,15 @@ TclCompileCatchCmd( cmdTokenPtr = TokenAfter(parsePtr->tokenPtr); if (parsePtr->numWords >= 3) { resultNameTokenPtr = TokenAfter(cmdTokenPtr); - if (!GetLocalScalarIndex(resultNameTokenPtr, envPtr, &resultIndex)) { + resultIndex = LocalScalarFromToken(resultNameTokenPtr, envPtr); + if (resultIndex < 0) { return TCL_ERROR; } if (parsePtr->numWords == 4) { optsNameTokenPtr = TokenAfter(resultNameTokenPtr); - if (!GetLocalScalarIndex(optsNameTokenPtr, envPtr, &optsIndex)) { + optsIndex = LocalScalarFromToken(optsNameTokenPtr, envPtr); + if (optsIndex < 0) { return TCL_ERROR; } } @@ -670,7 +674,8 @@ TclCompileDictSetCmd( */ varTokenPtr = TokenAfter(parsePtr->tokenPtr); - if (!GetLocalScalarIndex(varTokenPtr, envPtr, &dictVarIndex)) { + dictVarIndex = LocalScalarFromToken(varTokenPtr, envPtr); + if (dictVarIndex < 0) { return TCL_ERROR; } @@ -721,7 +726,8 @@ TclCompileDictIncrCmd( */ varTokenPtr = TokenAfter(parsePtr->tokenPtr); - if (!GetLocalScalarIndex(varTokenPtr, envPtr, &dictVarIndex)) { + dictVarIndex = LocalScalarFromToken(varTokenPtr, envPtr); + if (dictVarIndex < 0) { return TCL_ERROR; } @@ -802,13 +808,12 @@ TclCompileDictForCmd( Tcl_Token *varsTokenPtr, *dictTokenPtr, *bodyTokenPtr; int keyVarIndex, valueVarIndex, loopRange, catchRange; int infoIndex, jumpDisplacement, bodyTargetOffset, emptyTargetOffset; - int numVars, endTargetOffset; + int numVars, endTargetOffset, numBytes; + const char *bytes; int savedStackDepth = envPtr->currStackDepth; /* Needed because jumps confuse the stack * space calculator. */ Tcl_Obj *varNameObj, *varListObj = NULL; - Tcl_Token token[2] = {{TCL_TOKEN_SIMPLE_WORD, NULL, 0, 1}, - {TCL_TOKEN_TEXT, NULL, 0, 0}}; DefineLineInformation; /* TIP #280 */ /* @@ -841,15 +846,17 @@ TclCompileDictForCmd( } Tcl_ListObjIndex(NULL, varListObj, 0, &varNameObj); - token[1].start = Tcl_GetStringFromObj(varNameObj, &token[1].size); - if (!GetLocalScalarIndex(token, envPtr, &keyVarIndex)) { + bytes = Tcl_GetStringFromObj(varNameObj, &numBytes); + keyVarIndex = LocalScalar(bytes, numBytes, envPtr); + if (keyVarIndex < 0) { Tcl_DecrRefCount(varListObj); return TCL_ERROR; } Tcl_ListObjIndex(NULL, varListObj, 1, &varNameObj); - token[1].start = Tcl_GetStringFromObj(varNameObj, &token[1].size); - if (!GetLocalScalarIndex(token, envPtr, &valueVarIndex)) { + bytes = Tcl_GetStringFromObj(varNameObj, &numBytes); + valueVarIndex = LocalScalar(bytes, numBytes, envPtr); + if (valueVarIndex < 0) { Tcl_DecrRefCount(varListObj); return TCL_ERROR; } @@ -1020,7 +1027,8 @@ TclCompileDictUpdateCmd( */ dictVarTokenPtr = TokenAfter(parsePtr->tokenPtr); - if (!GetLocalScalarIndex(dictVarTokenPtr, envPtr, &dictIndex)) { + dictIndex = LocalScalarFromToken(dictVarTokenPtr, envPtr); + if (dictIndex < 0) { return TCL_ERROR; } @@ -1051,7 +1059,8 @@ TclCompileDictUpdateCmd( */ tokenPtr = TokenAfter(tokenPtr); - if (!GetLocalScalarIndex(tokenPtr, envPtr, &index)) { + index = LocalScalarFromToken(tokenPtr, envPtr); + if (index < 0) { ckfree((char *) duiPtr); TclStackFree(interp, keyTokenPtrs); return TCL_ERROR; @@ -1161,7 +1170,8 @@ TclCompileDictAppendCmd( */ tokenPtr = TokenAfter(parsePtr->tokenPtr); - if (!GetLocalScalarIndex(tokenPtr, envPtr, &dictVarIndex)) { + dictVarIndex = LocalScalarFromToken(tokenPtr, envPtr); + if (dictVarIndex < 0) { return TCL_ERROR; } @@ -1210,7 +1220,8 @@ TclCompileDictLappendCmd( varTokenPtr = TokenAfter(parsePtr->tokenPtr); keyTokenPtr = TokenAfter(varTokenPtr); valueTokenPtr = TokenAfter(keyTokenPtr); - if (!GetLocalScalarIndex(varTokenPtr, envPtr, &dictVarIndex)) { + dictVarIndex = LocalScalarFromToken(varTokenPtr, envPtr); + if (dictVarIndex < 0) { return TCL_ERROR; } CompileWord(envPtr, keyTokenPtr, interp, 2); @@ -1522,7 +1533,6 @@ TclCompileForeachCmd( * foreach command. Stored in a AuxData * record in the ByteCode. */ Tcl_Token *tokenPtr, *bodyTokenPtr; - Tcl_Token token[2]; unsigned char *jumpPc; JumpFixup jumpFalseFixup; int jumpBackDist, jumpBackOffset, infoIndex, range; @@ -1576,8 +1586,6 @@ TclCompileForeachCmd( */ varListObj = Tcl_NewObj(); - token[0].type = TCL_TOKEN_SIMPLE_WORD; - token[0].numComponents = 1; for (i = 0, tokenPtr = parsePtr->tokenPtr; i < numWords-1; i++, tokenPtr = TokenAfter(tokenPtr)) { @@ -1609,11 +1617,13 @@ TclCompileForeachCmd( for (j = 0; j < numVars; j++) { Tcl_Obj *varNameObj; + int numBytes; + const char *bytes; Tcl_ListObjIndex(NULL, varListObj, j, &varNameObj); - token[1].start = Tcl_GetStringFromObj(varNameObj, &token[1].size); - if (!GetLocalScalarIndex(token, envPtr, - varListPtr->varIndexes + j)) { + bytes = Tcl_GetStringFromObj(varNameObj, &numBytes); + varListPtr->varIndexes[j] = LocalScalar(bytes, numBytes, envPtr); + if (varListPtr->varIndexes[j] < 0) { code = TCL_ERROR; goto done; } @@ -4695,33 +4705,50 @@ TclCompileWhileCmd( /* *---------------------------------------------------------------------- * - * GetLocalScalarIndex -- + * LocalScalar(FromToken) -- * - * Procedure used in the compiling where pushing a variable name is - * necessary (append, lappend, set). + * Get the index into the table of compiled locals that corresponds + * to a local scalar variable name. * * Results: - * Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer - * evaluation to runtime. + * Returns the non-negative integer index value into the table of + * compiled locals corresponding to a local scalar variable name. + * If the arguments passed in do not identify a local scalar variable + * then return -1. * * Side effects: - * Instructions are added to envPtr to execute the "set" command at - * runtime. + * May add an entry into the table of compiled locals. * *---------------------------------------------------------------------- */ static int -GetLocalScalarIndex( +LocalScalarFromToken( Tcl_Token *tokenPtr, - CompileEnv *envPtr, - int *indexPtr) + CompileEnv *envPtr) { - int isSimple, isScalar; + int isSimple, isScalar, index; - PushVarName(NULL, tokenPtr, envPtr, TCL_CREATE_VAR, indexPtr, + PushVarName(NULL, tokenPtr, envPtr, TCL_CREATE_VAR, &index, &isSimple, &isScalar, 0 /* ignored */, NULL /* ignored */); - return (isScalar && *indexPtr >= 0); + if (!isScalar) { + index = -1; + } + return index; +} + +static int +LocalScalar( + const char *bytes, + int numBytes, + CompileEnv *envPtr) +{ + Tcl_Token token[2] = {{TCL_TOKEN_SIMPLE_WORD, NULL, 0, 1}, + {TCL_TOKEN_TEXT, NULL, 0, 0}}; + + token[1].start = bytes; + token[1].size = numBytes; + return LocalScalarFromToken(token, envPtr); } /* @@ -5718,7 +5745,8 @@ TclCompileUpvarCmd( localTokenPtr = TokenAfter(otherTokenPtr); CompileWord(envPtr, otherTokenPtr, interp, i); - if (!GetLocalScalarIndex(localTokenPtr, envPtr, &localIndex)) { + localIndex = LocalScalarFromToken(localTokenPtr, envPtr); + if (localIndex < 0) { return TCL_ERROR; } TclEmitInstInt4(INST_UPVAR, localIndex, envPtr); @@ -5807,7 +5835,8 @@ TclCompileNamespaceCmd( localTokenPtr = TokenAfter(otherTokenPtr); CompileWord(envPtr, otherTokenPtr, interp, i); - if (!GetLocalScalarIndex(localTokenPtr, envPtr, &localIndex)) { + localIndex = LocalScalarFromToken(localTokenPtr, envPtr); + if (localIndex < 0) { return TCL_ERROR; } TclEmitInstInt4(INST_NSUPVAR, localIndex, envPtr); -- cgit v0.12 From 13667e8096fd5ac12f24949644396d9eb0a12620 Mon Sep 17 00:00:00 2001 From: dgp Date: Mon, 22 Dec 2014 15:35:47 +0000 Subject: One more (interp==NULL) shortcut. --- generic/tclCompCmds.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generic/tclCompCmds.c b/generic/tclCompCmds.c index b3568e8..106c293 100644 --- a/generic/tclCompCmds.c +++ b/generic/tclCompCmds.c @@ -4826,7 +4826,7 @@ PushVarName( } } - if ((elName != NULL) && elNameChars) { + if (interp && (elName != NULL) && elNameChars) { /* * An array element, the element name is a simple string: * assemble the corresponding token. -- cgit v0.12 From 3faf4cc3b890c8295557932ae4d896c6624e6af7 Mon Sep 17 00:00:00 2001 From: dgp Date: Mon, 22 Dec 2014 19:57:36 +0000 Subject: More complete use of the TCL_NO_ELEMENT flag to suppress useless actions. --- generic/tclCompCmds.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/generic/tclCompCmds.c b/generic/tclCompCmds.c index 30c1318..ee9209a 100644 --- a/generic/tclCompCmds.c +++ b/generic/tclCompCmds.c @@ -3313,7 +3313,7 @@ TclPushVarName( } } - if ((elName != NULL) && elNameChars) { + if (!(flags & TCL_NO_ELEMENT) && (elName != NULL) && elNameChars) { /* * An array element, the element name is a simple string: * assemble the corresponding token. @@ -3366,7 +3366,8 @@ TclPushVarName( remainingChars = (varTokenPtr[2].start - p) - 1; elNameChars = (varTokenPtr[n].start-p) + varTokenPtr[n].size - 1; - if (remainingChars) { + if (!(flags & TCL_NO_ELEMENT)) { + if (remainingChars) { /* * Make a first token with the extra characters in the first * token. @@ -3386,13 +3387,14 @@ TclPushVarName( memcpy(elemTokenPtr+1, varTokenPtr+2, (n-1) * sizeof(Tcl_Token)); - } else { + } else { /* * Use the already available tokens. */ elemTokenPtr = &varTokenPtr[2]; elemTokenCount = n - 1; + } } } } -- cgit v0.12 From 7ac39417f17cf6027ca26576c86d3cf9147ad1e7 Mon Sep 17 00:00:00 2001 From: dgp Date: Mon, 22 Dec 2014 20:13:29 +0000 Subject: Use (interp == NULL) argument to TclPushVarName() to signal that no compiling is desired. Only a lookup of an index into the compiled variable table. --- generic/tclCompCmds.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/generic/tclCompCmds.c b/generic/tclCompCmds.c index ee9209a..18071b1 100644 --- a/generic/tclCompCmds.c +++ b/generic/tclCompCmds.c @@ -3328,7 +3328,7 @@ TclPushVarName( elemTokenCount = 1; } } - } else if (((n = varTokenPtr->numComponents) > 1) + } else if (interp && ((n = varTokenPtr->numComponents) > 1) && (varTokenPtr[1].type == TCL_TOKEN_TEXT) && (varTokenPtr[n].type == TCL_TOKEN_TEXT) && (varTokenPtr[n].start[varTokenPtr[n].size - 1] == ')')) { @@ -3429,7 +3429,7 @@ TclPushVarName( localIndex = -1; } } - if (localIndex < 0) { + if (interp && localIndex < 0) { PushLiteral(envPtr, name, nameChars); } @@ -3446,7 +3446,7 @@ TclPushVarName( PushStringLiteral(envPtr, ""); } } - } else { + } else if (interp) { /* * The var name isn't simple: compile and push it. */ -- cgit v0.12 From 2cbec4bf44fad8591fa06185d8cf3f28dd1526a2 Mon Sep 17 00:00:00 2001 From: dgp Date: Mon, 22 Dec 2014 20:27:14 +0000 Subject: Convert the LocalScalar*() macros to rest on TclPushVarName rather than on TclIsLocalScalar(). --- generic/tclCompCmds.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ generic/tclCompile.h | 10 ++++++---- 2 files changed, 54 insertions(+), 4 deletions(-) diff --git a/generic/tclCompCmds.c b/generic/tclCompCmds.c index 18071b1..bde07bb 100644 --- a/generic/tclCompCmds.c +++ b/generic/tclCompCmds.c @@ -3234,6 +3234,54 @@ TclCompileFormatCmd( /* *---------------------------------------------------------------------- * + * TclLocalScalarFromToken -- + * + * Get the index into the table of compiled locals that corresponds + * to a local scalar variable name. + * + * Results: + * Returns the non-negative integer index value into the table of + * compiled locals corresponding to a local scalar variable name. + * If the arguments passed in do not identify a local scalar variable + * then return -1. + * + * Side effects: + * May add an entery into the table of compiled locals. + * + *---------------------------------------------------------------------- + */ + +int +TclLocalScalarFromToken( + Tcl_Token *tokenPtr, + CompileEnv *envPtr) +{ + int isScalar, index; + + TclPushVarName(NULL, tokenPtr, envPtr, TCL_NO_ELEMENT, &index, &isScalar); + if (!isScalar) { + index = -1; + } + return index; +} + +int +TclLocalScalar( + const char *bytes, + int numBytes, + CompileEnv *envPtr) +{ + Tcl_Token token[2] = {{TCL_TOKEN_SIMPLE_WORD, NULL, 0, 1}, + {TCL_TOKEN_TEXT, NULL, 0, 0}}; + + token[1].start = bytes; + token[1].size = numBytes; + return TclLocalScalarFromToken(token, envPtr); +} + +/* + *---------------------------------------------------------------------- + * * TclPushVarName -- * * Procedure used in the compiling where pushing a variable name is diff --git a/generic/tclCompile.h b/generic/tclCompile.h index 51f0b34..c6c7a7c 100644 --- a/generic/tclCompile.h +++ b/generic/tclCompile.h @@ -1151,6 +1151,10 @@ MODULE_SCOPE void TclFinalizeLoopExceptionRange(CompileEnv *envPtr, MODULE_SCOPE char * TclLiteralStats(LiteralTable *tablePtr); MODULE_SCOPE int TclLog2(int value); #endif +MODULE_SCOPE int TclLocalScalar(const char *bytes, int numBytes, + CompileEnv *envPtr); +MODULE_SCOPE int TclLocalScalarFromToken(Tcl_Token *tokenPtr, + CompileEnv *envPtr); MODULE_SCOPE void TclOptimizeBytecode(void *envPtr); #ifdef TCL_COMPILE_DEBUG MODULE_SCOPE void TclPrintByteCodeObj(Tcl_Interp *interp, @@ -1678,11 +1682,9 @@ MODULE_SCOPE int TclPushProcCallFrame(ClientData clientData, #define AnonymousLocal(envPtr) \ (TclFindCompiledLocal(NULL, /*nameChars*/ 0, /*create*/ 1, (envPtr))) #define LocalScalar(chars,len,envPtr) \ - (!TclIsLocalScalar((chars), (len)) ? -1 : \ - TclFindCompiledLocal((chars), (len), /*create*/ 1, (envPtr))) + TclLocalScalar(chars, len, envPtr) #define LocalScalarFromToken(tokenPtr,envPtr) \ - ((tokenPtr)->type != TCL_TOKEN_SIMPLE_WORD ? -1 : \ - LocalScalar((tokenPtr)[1].start, (tokenPtr)[1].size, (envPtr))) + TclLocalScalarFromToken(tokenPtr, envPtr) /* * Flags bits used by TclPushVarName. -- cgit v0.12 From 49e7d0262bb9fcc94ce092927df43261350e319a Mon Sep 17 00:00:00 2001 From: dgp Date: Tue, 23 Dec 2014 01:28:30 +0000 Subject: Revise CompileEachloopCmd() to use LocalScalar() in place of TclIsLocalScalar(). --- generic/tclCompCmds.c | 119 +++++++++++++++++--------------------------------- 1 file changed, 40 insertions(+), 79 deletions(-) diff --git a/generic/tclCompCmds.c b/generic/tclCompCmds.c index bde07bb..ec398b6 100644 --- a/generic/tclCompCmds.c +++ b/generic/tclCompCmds.c @@ -2527,25 +2527,17 @@ CompileEachloopCmd( * (TCL_EACH_*) */ { Proc *procPtr = envPtr->procPtr; - ForeachInfo *infoPtr; /* Points to the structure describing this + ForeachInfo *infoPtr=NULL; /* Points to the structure describing this * foreach command. Stored in a AuxData * record in the ByteCode. */ Tcl_Token *tokenPtr, *bodyTokenPtr; int jumpBackOffset, infoIndex, range; - int numWords, numLists, numVars, loopIndex, i, j, code; + int numWords, numLists, i, j, code = TCL_OK; + Tcl_Obj *varListObj = NULL; DefineLineInformation; /* TIP #280 */ /* - * We parse the variable list argument words and create two arrays: - * varcList[i] is number of variables in i-th var list. - * varvList[i] points to array of var names in i-th var list. - */ - - int *varcList; - const char ***varvList; - - /* * If the foreach command isn't in a procedure, don't compile it inline: * the payoff is too small. */ @@ -2573,105 +2565,73 @@ CompileEachloopCmd( } /* - * Allocate storage for the varcList and varvList arrays if necessary. + * Create and initialize the ForeachInfo and ForeachVarList data + * structures describing this command. Then create a AuxData record + * pointing to the ForeachInfo structure. */ numLists = (numWords - 2)/2; - varcList = TclStackAlloc(interp, numLists * sizeof(int)); - memset(varcList, 0, numLists * sizeof(int)); - varvList = (const char ***) TclStackAlloc(interp, - numLists * sizeof(const char **)); - memset((char*) varvList, 0, numLists * sizeof(const char **)); + infoPtr = ckalloc(sizeof(ForeachInfo) + + (numLists - 1) * sizeof(ForeachVarList *)); + infoPtr->numLists = 0; /* Count this up as we go */ /* - * Break up each var list and set the varcList and varvList arrays. Don't + * Parse each var list into sequence of var names. Don't * compile the foreach inline if any var name needs substitutions or isn't * a scalar, or if any var list needs substitutions. */ - loopIndex = 0; + varListObj = Tcl_NewObj(); for (i = 0, tokenPtr = parsePtr->tokenPtr; i < numWords-1; i++, tokenPtr = TokenAfter(tokenPtr)) { - Tcl_DString varList; + ForeachVarList *varListPtr; + int numVars; if (i%2 != 1) { continue; } - if (tokenPtr->type != TCL_TOKEN_SIMPLE_WORD) { - code = TCL_ERROR; - goto done; - } - - /* - * Lots of copying going on here. Need a ListObj wizard to show a - * better way. - */ - - Tcl_DStringInit(&varList); - TclDStringAppendToken(&varList, &tokenPtr[1]); - code = Tcl_SplitList(NULL, Tcl_DStringValue(&varList), - &varcList[loopIndex], &varvList[loopIndex]); - Tcl_DStringFree(&varList); - if (code != TCL_OK) { - code = TCL_ERROR; - goto done; - } - numVars = varcList[loopIndex]; /* * If the variable list is empty, we can enter an infinite loop when - * the interpreted version would not. Take care to ensure this does - * not happen. [Bug 1671138] + * the interpreted version would not. Take care to ensure this does + * not happen. [Bug 1671138] */ - if (numVars == 0) { + if (!TclWordKnownAtCompileTime(tokenPtr, varListObj) || + TCL_OK != Tcl_ListObjLength(NULL, varListObj, &numVars) || + numVars == 0) { code = TCL_ERROR; goto done; } - for (j = 0; j < numVars; j++) { - const char *varName = varvList[loopIndex][j]; + varListPtr = ckalloc(sizeof(ForeachVarList) + + (numVars - 1) * sizeof(int)); + varListPtr->numVars = numVars; + infoPtr->varLists[i/2] = varListPtr; + infoPtr->numLists++; - if (!TclIsLocalScalar(varName, (int) strlen(varName))) { + for (j = 0; j < numVars; j++) { + Tcl_Obj *varNameObj; + const char *bytes; + int numBytes, varIndex; + + Tcl_ListObjIndex(NULL, varListObj, j, &varNameObj); + bytes = Tcl_GetStringFromObj(varNameObj, &numBytes); + varIndex = LocalScalar(bytes, numBytes, envPtr); + if (varIndex < 0) { code = TCL_ERROR; goto done; } + varListPtr->varIndexes[j] = varIndex; } - loopIndex++; + Tcl_SetObjLength(varListObj, 0); } /* * We will compile the foreach command. */ - code = TCL_OK; - - /* - * Create and initialize the ForeachInfo and ForeachVarList data - * structures describing this command. Then create a AuxData record - * pointing to the ForeachInfo structure. - */ - - infoPtr = ckalloc(sizeof(ForeachInfo) - + (numLists - 1) * sizeof(ForeachVarList *)); - infoPtr->numLists = numLists; - for (loopIndex = 0; loopIndex < numLists; loopIndex++) { - ForeachVarList *varListPtr; - - numVars = varcList[loopIndex]; - varListPtr = ckalloc(sizeof(ForeachVarList) - + (numVars - 1) * sizeof(int)); - varListPtr->numVars = numVars; - for (j = 0; j < numVars; j++) { - const char *varName = varvList[loopIndex][j]; - int nameChars = strlen(varName); - - varListPtr->varIndexes[j] = TclFindCompiledLocal(varName, - nameChars, /*create*/ 1, envPtr); - } - infoPtr->varLists[loopIndex] = varListPtr; - } infoIndex = TclCreateAuxData(infoPtr, &tclNewForeachInfoType, envPtr); /* @@ -2743,13 +2703,14 @@ CompileEachloopCmd( } done: - for (loopIndex = 0; loopIndex < numLists; loopIndex++) { - if (varvList[loopIndex] != NULL) { - ckfree(varvList[loopIndex]); + if (code == TCL_ERROR) { + if (infoPtr) { + FreeForeachInfo(infoPtr); } } - TclStackFree(interp, (void *)varvList); - TclStackFree(interp, varcList); + if (varListObj) { + Tcl_DecrRefCount(varListObj); + } return code; } -- cgit v0.12 From b0078c812949591757520d79106eae38f21d33f0 Mon Sep 17 00:00:00 2001 From: dgp Date: Tue, 23 Dec 2014 02:12:59 +0000 Subject: Eliminate TclIsLocalScalar(). No callers left. --- generic/tclInt.h | 1 - generic/tclParse.c | 50 -------------------------------------------------- 2 files changed, 51 deletions(-) diff --git a/generic/tclInt.h b/generic/tclInt.h index 995da48..3f84717 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -2985,7 +2985,6 @@ MODULE_SCOPE void TclInitNotifier(void); MODULE_SCOPE void TclInitObjSubsystem(void); MODULE_SCOPE void TclInitSubsystems(void); MODULE_SCOPE int TclInterpReady(Tcl_Interp *interp); -MODULE_SCOPE int TclIsLocalScalar(const char *src, int len); MODULE_SCOPE int TclIsSpaceProc(char byte); MODULE_SCOPE int TclIsBareword(char byte); MODULE_SCOPE Tcl_Obj * TclJoinPath(int elements, Tcl_Obj * const objv[]); diff --git a/generic/tclParse.c b/generic/tclParse.c index ca12be5..5524979 100644 --- a/generic/tclParse.c +++ b/generic/tclParse.c @@ -2526,56 +2526,6 @@ TclObjCommandComplete( } /* - *---------------------------------------------------------------------- - * - * TclIsLocalScalar -- - * - * Check to see if a given string is a legal scalar variable name with no - * namespace qualifiers or substitutions. - * - * Results: - * Returns 1 if the variable is a local scalar. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -int -TclIsLocalScalar( - const char *src, - int len) -{ - const char *p; - const char *lastChar = src + (len - 1); - - for (p=src ; p<=lastChar ; p++) { - if ((CHAR_TYPE(*p) != TYPE_NORMAL) - && (CHAR_TYPE(*p) != TYPE_COMMAND_END)) { - /* - * TCL_COMMAND_END is returned for the last character of the - * string. By this point we know it isn't an array or namespace - * reference. - */ - - return 0; - } - if (*p == '(') { - if (*lastChar == ')') { /* We have an array element */ - return 0; - } - } else if (*p == ':') { - if ((p != lastChar) && *(p+1) == ':') { /* qualified name */ - return 0; - } - } - } - - return 1; -} - -/* * Local Variables: * mode: c * c-basic-offset: 4 -- cgit v0.12 From ef6f1ba2c34bd3243b54d46d23d37392d7bf34ba Mon Sep 17 00:00:00 2001 From: dgp Date: Tue, 23 Dec 2014 02:41:54 +0000 Subject: Use more suitable variable name pushers. --- generic/tclCompCmds.c | 6 +++--- generic/tclCompCmdsGR.c | 16 ++++++---------- 2 files changed, 9 insertions(+), 13 deletions(-) diff --git a/generic/tclCompCmds.c b/generic/tclCompCmds.c index ec398b6..6a22a30 100644 --- a/generic/tclCompCmds.c +++ b/generic/tclCompCmds.c @@ -177,9 +177,9 @@ TclCompileAppendCmd( */ varTokenPtr = TokenAfter(parsePtr->tokenPtr); - PushVarNameWord(interp, varTokenPtr, envPtr, TCL_NO_ELEMENT, - &localIndex, &isScalar, 1); - if (!isScalar || localIndex < 0) { + + localIndex = LocalScalarFromToken(varTokenPtr, envPtr); + if (localIndex < 0) { return TCL_ERROR; } diff --git a/generic/tclCompCmdsGR.c b/generic/tclCompCmdsGR.c index 98407f7..e2fb43d 100644 --- a/generic/tclCompCmdsGR.c +++ b/generic/tclCompCmdsGR.c @@ -2044,7 +2044,7 @@ TclCompileNamespaceUpvarCmd( CompileEnv *envPtr) /* Holds resulting instructions. */ { Tcl_Token *tokenPtr, *otherTokenPtr, *localTokenPtr; - int isScalar, localIndex, numWords, i; + int localIndex, numWords, i; DefineLineInformation; /* TIP #280 */ if (envPtr->procPtr == NULL) { @@ -2079,10 +2079,8 @@ TclCompileNamespaceUpvarCmd( localTokenPtr = TokenAfter(otherTokenPtr); CompileWord(envPtr, otherTokenPtr, interp, i); - PushVarNameWord(interp, localTokenPtr, envPtr, 0, - &localIndex, &isScalar, i+1); - - if ((localIndex < 0) || !isScalar) { + localIndex = LocalScalarFromToken(localTokenPtr, envPtr); + if (localIndex < 0) { return TCL_ERROR; } TclEmitInstInt4( INST_NSUPVAR, localIndex, envPtr); @@ -2763,7 +2761,7 @@ TclCompileUpvarCmd( CompileEnv *envPtr) /* Holds resulting instructions. */ { Tcl_Token *tokenPtr, *otherTokenPtr, *localTokenPtr; - int isScalar, localIndex, numWords, i; + int localIndex, numWords, i; DefineLineInformation; /* TIP #280 */ Tcl_Obj *objPtr; @@ -2826,10 +2824,8 @@ TclCompileUpvarCmd( localTokenPtr = TokenAfter(otherTokenPtr); CompileWord(envPtr, otherTokenPtr, interp, i); - PushVarNameWord(interp, localTokenPtr, envPtr, 0, - &localIndex, &isScalar, i+1); - - if ((localIndex < 0) || !isScalar) { + localIndex = LocalScalarFromToken(localTokenPtr, envPtr); + if (localIndex < 0) { return TCL_ERROR; } TclEmitInstInt4( INST_UPVAR, localIndex, envPtr); -- cgit v0.12 From 7134cd9399b41471ebbd9126bab51e0ffd6cd9db Mon Sep 17 00:00:00 2001 From: dgp Date: Tue, 23 Dec 2014 16:57:02 +0000 Subject: Use the new TCL_ENCODING_CHAR_LIMIT flag to have the encoding system manage the max chars to read constraint. --- generic/tclIO.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index 79aa667..9bbf2a6 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -5977,16 +5977,21 @@ ReadChars( */ while (1) { - int dstDecoded, dstRead, dstWrote, srcRead, numChars; + int dstDecoded, dstRead, dstWrote, srcRead, numChars, code; + int flags = statePtr->inputEncodingFlags | TCL_ENCODING_NO_TERMINATE; + + if (charsToRead > 0) { + flags |= TCL_ENCODING_CHAR_LIMIT; + numChars = charsToRead; + } /* * Perform the encoding transformation. Read no more than * srcLen bytes, write no more than dstLimit bytes. */ - int code = Tcl_ExternalToUtf(NULL, encoding, src, srcLen, - (statePtr->inputEncodingFlags | TCL_ENCODING_NO_TERMINATE) - & (bufPtr->nextPtr ? ~0 : ~TCL_ENCODING_END), + code = Tcl_ExternalToUtf(NULL, encoding, src, srcLen, + flags & (bufPtr->nextPtr ? ~0 : ~TCL_ENCODING_END), &statePtr->inputEncodingState, dst, dstLimit, &srcRead, &dstDecoded, &numChars); @@ -6161,6 +6166,8 @@ ReadChars( if (charsToRead > 0 && numChars > charsToRead) { /* + * TODO: This cannot happen anymore. + * * We read more chars than allowed. Reset limits to * prevent that and try again. Don't forget the extra * padding of TCL_UTF_MAX bytes demanded by the -- cgit v0.12 From 5a6443d00ed0e3d2c040b88d322ad08a51fcbfc9 Mon Sep 17 00:00:00 2001 From: dgp Date: Tue, 23 Dec 2014 17:13:13 +0000 Subject: Support TCL_ENCODING_CHAR_LIMIT in the BinaryProc driver. --- generic/tclEncoding.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/generic/tclEncoding.c b/generic/tclEncoding.c index 2a766d1..5c5254b 100644 --- a/generic/tclEncoding.c +++ b/generic/tclEncoding.c @@ -2131,6 +2131,9 @@ BinaryProc( if (dstLen < 0) { dstLen = 0; } + if ((flags & TCL_ENCODING_CHAR_LIMIT) && srcLen > *dstCharsPtr) { + srcLen = *dstCharsPtr; + } if (srcLen > dstLen) { srcLen = dstLen; result = TCL_CONVERT_NOSPACE; -- cgit v0.12 From 360b5c41eed8a2bc3d2b80f23ca1cdd98fe6e56f Mon Sep 17 00:00:00 2001 From: dgp Date: Tue, 23 Dec 2014 17:26:07 +0000 Subject: Support TCL_ENCODING_CHAR_LIMIT in the UtfToUtfProc driver. --- generic/tclEncoding.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/generic/tclEncoding.c b/generic/tclEncoding.c index 5c5254b..f92cabb 100644 --- a/generic/tclEncoding.c +++ b/generic/tclEncoding.c @@ -2294,7 +2294,7 @@ UtfToUtfProc( { const char *srcStart, *srcEnd, *srcClose; const char *dstStart, *dstEnd; - int result, numChars; + int result, numChars, charLimit = INT_MAX; Tcl_UniChar ch; result = TCL_OK; @@ -2305,11 +2305,14 @@ UtfToUtfProc( if ((flags & TCL_ENCODING_END) == 0) { srcClose -= TCL_UTF_MAX; } + if (flags & TCL_ENCODING_CHAR_LIMIT) { + charLimit = *dstCharsPtr; + } dstStart = dst; dstEnd = dst + dstLen - TCL_UTF_MAX; - for (numChars = 0; src < srcEnd; numChars++) { + for (numChars = 0; src < srcEnd && numChars <= charLimit; numChars++) { if ((src > srcClose) && (!Tcl_UtfCharComplete(src, srcEnd - src))) { /* * If there is more string to follow, this will ensure that the -- cgit v0.12 From b6fecacc22a9ba5f13cbab794af7dcc46ebc5bc3 Mon Sep 17 00:00:00 2001 From: dgp Date: Tue, 23 Dec 2014 17:46:05 +0000 Subject: Support TCL_ENCODING_CHAR_LIMIT in the UnicodeToUtfProc driver. --- generic/tclEncoding.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/generic/tclEncoding.c b/generic/tclEncoding.c index f92cabb..0fe224e 100644 --- a/generic/tclEncoding.c +++ b/generic/tclEncoding.c @@ -2408,9 +2408,12 @@ UnicodeToUtfProc( { const char *srcStart, *srcEnd; const char *dstEnd, *dstStart; - int result, numChars; + int result, numChars, charLimit = INT_MAX; Tcl_UniChar ch; + if (flags & TCL_ENCODING_CHAR_LIMIT) { + charLimit = *dstCharsPtr; + } result = TCL_OK; if ((srcLen % sizeof(Tcl_UniChar)) != 0) { result = TCL_CONVERT_MULTIBYTE; @@ -2424,7 +2427,7 @@ UnicodeToUtfProc( dstStart = dst; dstEnd = dst + dstLen - TCL_UTF_MAX; - for (numChars = 0; src < srcEnd; numChars++) { + for (numChars = 0; src < srcEnd && numChars <= charLimit; numChars++) { if (dst > dstEnd) { result = TCL_CONVERT_NOSPACE; break; -- cgit v0.12 From a3babfe12a8c12394c0ae2e1a4bf6f4da3e88cbe Mon Sep 17 00:00:00 2001 From: dgp Date: Tue, 23 Dec 2014 17:48:36 +0000 Subject: Support TCL_ENCODING_CHAR_LIMIT in the Iso88591ToUtfProc driver. --- generic/tclEncoding.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/generic/tclEncoding.c b/generic/tclEncoding.c index 0fe224e..3df720d 100644 --- a/generic/tclEncoding.c +++ b/generic/tclEncoding.c @@ -2826,8 +2826,11 @@ Iso88591ToUtfProc( { const char *srcStart, *srcEnd; const char *dstEnd, *dstStart; - int result, numChars; + int result, numChars, charLimit = INT_MAX; + if (flags & TCL_ENCODING_CHAR_LIMIT) { + charLimit = *dstCharsPtr; + } srcStart = src; srcEnd = src + srcLen; @@ -2835,7 +2838,7 @@ Iso88591ToUtfProc( dstEnd = dst + dstLen - TCL_UTF_MAX; result = TCL_OK; - for (numChars = 0; src < srcEnd; numChars++) { + for (numChars = 0; src < srcEnd && numChars <= charLimit; numChars++) { Tcl_UniChar ch; if (dst > dstEnd) { -- cgit v0.12 From 1ddabb17f9dbbd2e67b3b2fb230413c7abc6fec8 Mon Sep 17 00:00:00 2001 From: dgp Date: Tue, 23 Dec 2014 17:53:21 +0000 Subject: Support TCL_ENCODING_CHAR_LIMIT in TableToUtfProc and EscapeToUtfProc drivers. --- generic/tclEncoding.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/generic/tclEncoding.c b/generic/tclEncoding.c index 3df720d..179ca17 100644 --- a/generic/tclEncoding.c +++ b/generic/tclEncoding.c @@ -2595,12 +2595,15 @@ TableToUtfProc( { const char *srcStart, *srcEnd; const char *dstEnd, *dstStart, *prefixBytes; - int result, byte, numChars; + int result, byte, numChars, charLimit = INT_MAX; Tcl_UniChar ch; const unsigned short *const *toUnicode; const unsigned short *pageZero; TableEncodingData *dataPtr = clientData; + if (flags & TCL_ENCODING_CHAR_LIMIT) { + charLimit = *dstCharsPtr; + } srcStart = src; srcEnd = src + srcLen; @@ -2612,7 +2615,7 @@ TableToUtfProc( pageZero = toUnicode[0]; result = TCL_OK; - for (numChars = 0; src < srcEnd; numChars++) { + for (numChars = 0; src < srcEnd && numChars <= charLimit; numChars++) { if (dst > dstEnd) { result = TCL_CONVERT_NOSPACE; break; @@ -3054,9 +3057,12 @@ EscapeToUtfProc( const char *prefixBytes, *tablePrefixBytes, *srcStart, *srcEnd; const unsigned short *const *tableToUnicode; const Encoding *encodingPtr; - int state, result, numChars; + int state, result, numChars, charLimit = INT_MAX; const char *dstStart, *dstEnd; + if (flags & TCL_ENCODING_CHAR_LIMIT) { + charLimit = *dstCharsPtr; + } result = TCL_OK; tablePrefixBytes = NULL; /* lint. */ tableToUnicode = NULL; /* lint. */ @@ -3074,7 +3080,7 @@ EscapeToUtfProc( state = 0; } - for (numChars = 0; src < srcEnd; ) { + for (numChars = 0; src < srcEnd && numChars <= charLimit; ) { int byte, hi, lo, ch; if (dst > dstEnd) { -- cgit v0.12 From 42c1a1e15a94212b34ff9baa9b0f02622acece5d Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 2 Jan 2015 15:19:23 +0000 Subject: Revert use of the install-headers target. Tcl 8.5 has no such target. --- macosx/GNUmakefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/macosx/GNUmakefile b/macosx/GNUmakefile index 3598b3a..7d19fc6 100644 --- a/macosx/GNUmakefile +++ b/macosx/GNUmakefile @@ -100,7 +100,7 @@ INSTALL_TARGET := install export CPPROG := cp -p -INSTALL_TARGETS = install-binaries install-headers install-libraries +INSTALL_TARGETS = install-binaries install-libraries ifeq (${EMBEDDED_BUILD},) INSTALL_TARGETS += install-private-headers endif -- cgit v0.12 From f16ec6e776a225afc140af0387b7819427358ba3 Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 2 Jan 2015 22:42:12 +0000 Subject: Now that we're using TCL_ENCODING_NO_TERMINATE - be careful about acting on the contents of dst -- they could be leftovers. Only check bytes reported to have been written and take care to get the assertions right. --- generic/tclIO.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index 9bbf2a6..a9091af 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -6198,9 +6198,8 @@ ReadChars( * empty string. */ - if (dst[0] == '\n') { + if (dstRead == 1 && dst[0] == '\n') { assert(statePtr->inputTranslation == TCL_TRANSLATE_AUTO); - assert(dstRead == 1); goto consume; } -- cgit v0.12 From 52d37c087d8566c82644d7b61a6dac58999a16a7 Mon Sep 17 00:00:00 2001 From: bch Date: Tue, 20 Jan 2015 23:40:23 +0000 Subject: assert() on missing definitions for Tcl_ChannelCreate() required struct Tcl_ChannelType{} fields. --- generic/tclIO.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/generic/tclIO.c b/generic/tclIO.c index a9091af..596ba3f 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -1548,6 +1548,15 @@ Tcl_CreateChannel( */ assert(sizeof(Tcl_ChannelTypeVersion) == sizeof(Tcl_DriverBlockModeProc *)); + assert(NULL!=typePtr->closeProc); + assert(NULL!=typePtr->inputProc); + assert(NULL!=typePtr->outputProc); + assert(NULL!=typePtr->watchProc); + assert(NULL!=typePtr->truncateProc); + assert(NULL!=typePtr->getHandleProc); + if (NULL!=typePtr->wideSeekProc) { + assert(NULL!=typePtr->seekProc && "Must define seekProc if defining wideSeekProc"); + } /* * JH: We could subsequently memset these to 0 to avoid the numerous -- cgit v0.12 From acad5814798a290c3c8bbdeffa55b4e24f3579b2 Mon Sep 17 00:00:00 2001 From: bch Date: Wed, 21 Jan 2015 00:21:18 +0000 Subject: truncateProc *can* be NULL --- generic/tclIO.c | 1 - 1 file changed, 1 deletion(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index 596ba3f..eb33106 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -1552,7 +1552,6 @@ Tcl_CreateChannel( assert(NULL!=typePtr->inputProc); assert(NULL!=typePtr->outputProc); assert(NULL!=typePtr->watchProc); - assert(NULL!=typePtr->truncateProc); assert(NULL!=typePtr->getHandleProc); if (NULL!=typePtr->wideSeekProc) { assert(NULL!=typePtr->seekProc && "Must define seekProc if defining wideSeekProc"); -- cgit v0.12 From 4d5ff6cd13d58d6399e7ff7310a8ec2634ee5ec7 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Mon, 26 Jan 2015 20:47:23 +0000 Subject: Fix [df08482b042a16007f256bfbaaacfbe0def01074|df08482b04]: Double defined INFINITY in regguts.h --- generic/regcomp.c | 14 +++++++------- generic/regexec.c | 4 ++-- generic/regguts.h | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/generic/regcomp.c b/generic/regcomp.c index 8880318..77f2f20 100644 --- a/generic/regcomp.c +++ b/generic/regcomp.c @@ -996,13 +996,13 @@ parseqatom( switch (v->nexttype) { case '*': m = 0; - n = INFINITY; + n = DUPINF; qprefer = (v->nextvalue) ? LONGER : SHORTER; NEXT(); break; case '+': m = 1; - n = INFINITY; + n = DUPINF; qprefer = (v->nextvalue) ? LONGER : SHORTER; NEXT(); break; @@ -1019,7 +1019,7 @@ parseqatom( if (SEE(DIGIT)) { n = scannum(v); } else { - n = INFINITY; + n = DUPINF; } if (m > n) { ERR(REG_BADBR); @@ -1217,8 +1217,8 @@ parseqatom( */ dupnfa(v->nfa, atom->begin, atom->end, s, atom->begin); - assert(m >= 1 && m != INFINITY && n >= 1); - repeat(v, s, atom->begin, m-1, (n == INFINITY) ? n : n-1); + assert(m >= 1 && m != DUPINF && n >= 1); + repeat(v, s, atom->begin, m-1, (n == DUPINF) ? n : n-1); f = COMBINE(qprefer, atom->flags); t = subre(v, '.', f, s, atom->end); /* prefix and atom */ NOERR(); @@ -1323,7 +1323,7 @@ repeat( #define SOME 2 #define INF 3 #define PAIR(x, y) ((x)*4 + (y)) -#define REDUCE(x) ( ((x) == INFINITY) ? INF : (((x) > 1) ? SOME : (x)) ) +#define REDUCE(x) ( ((x) == DUPINF) ? INF : (((x) > 1) ? SOME : (x)) ) const int rm = REDUCE(m); const int rn = REDUCE(n); struct state *s, *s2; @@ -2108,7 +2108,7 @@ stdump( } if (t->min != 1 || t->max != 1) { fprintf(f, " {%d,", t->min); - if (t->max != INFINITY) { + if (t->max != DUPINF) { fprintf(f, "%d", t->max); } fprintf(f, "}"); diff --git a/generic/regexec.c b/generic/regexec.c index 205fcc2..f3be137 100644 --- a/generic/regexec.c +++ b/generic/regexec.c @@ -1117,7 +1117,7 @@ cbrdissect( */ i = 0; - for (p = begin; p <= stop && (i < max || max == INFINITY); p += len) { + for (p = begin; p <= stop && (i < max || max == DUPINF); p += len) { if ((*v->g->compare)(paren, p, len) != 0) { break; } @@ -1132,7 +1132,7 @@ cbrdissect( if (p != end) { /* didn't consume all of it */ return REG_NOMATCH; } - if (min <= i && (i <= max || max == INFINITY)) { + if (min <= i && (i <= max || max == DUPINF)) { return REG_OKAY; } return REG_NOMATCH; /* out of range */ diff --git a/generic/regguts.h b/generic/regguts.h index 42654eb..ac625d5 100644 --- a/generic/regguts.h +++ b/generic/regguts.h @@ -116,7 +116,7 @@ #define xxx 1 #define DUPMAX _POSIX2_RE_DUP_MAX -#define INFINITY (DUPMAX+1) +#define DUPINF (DUPMAX+1) #define REMAGIC 0xfed7 /* magic number for main struct */ -- cgit v0.12 From 2f36a2d3491daec49498178ed26a70e629304a8d Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 29 Jan 2015 17:37:59 +0000 Subject: Protect against extension variable resolvers that fail to play by the post-Var Reform rules. --- generic/tclVar.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/generic/tclVar.c b/generic/tclVar.c index a6f6cf4..33071ae 100644 --- a/generic/tclVar.c +++ b/generic/tclVar.c @@ -3914,7 +3914,8 @@ Tcl_GetVariableFullName( } else if (iPtr->varFramePtr->procPtr) { int index = varPtr - iPtr->varFramePtr->compiledLocals; - if (index < iPtr->varFramePtr->numCompiledLocals) { + if (index >= 0 + && index < iPtr->varFramePtr->numCompiledLocals) { namePtr = localName(iPtr->varFramePtr, index); Tcl_AppendObjToObj(objPtr, namePtr); } -- cgit v0.12 From 8ee4bdf94d73b352621e92007ed58ed72389adc7 Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 29 Jan 2015 18:34:50 +0000 Subject: Test for bug [08872796bc]. --- tests/io.test | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/tests/io.test b/tests/io.test index d533957..e4dc522 100644 --- a/tests/io.test +++ b/tests/io.test @@ -8419,6 +8419,25 @@ test io-73.3 {[5adc350683] [gets] after EOF} -setup { removeFile io-73.3 } -result {1 1 {more data} 0 {} 1} +test io-73.4 {[5adc350683] [read] after EOF} -setup { + set fn [makeFile {} io-73.4] + set rfd [open $fn r] + set wfd [open $fn a] + chan configure $wfd -buffering line + read $rfd +} -body { + set result [eof $rfd] + puts $wfd "more data" + lappend result [eof $rfd] + lappend result [read $rfd] + lappend result [eof $rfd] +} -cleanup { + close $wfd + close $rfd + removeFile io-73.4 +} -result {1 1 {more data +} 1} + # ### ### ### ######### ######### ######### # cleanup -- cgit v0.12 From 3f9555d4c2af861ded30792fc8a9c35b23187a2c Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 29 Jan 2015 18:39:11 +0000 Subject: Fix [08872796bc] --- generic/tclIO.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index a9091af..86ec27a 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -5735,8 +5735,8 @@ DoReadChars( chanPtr = statePtr->topChanPtr; TclChannelPreserve((Tcl_Channel)chanPtr); - /* Must clear the BLOCKED flag here since we check before reading */ - ResetFlag(statePtr, CHANNEL_BLOCKED); + /* Must clear the BLOCKED|EOF flags here since we check before reading */ + ResetFlag(statePtr, CHANNEL_BLOCKED|CHANNEL_EOF); for (copied = 0; (unsigned) toRead > 0; ) { copiedNow = -1; if (statePtr->inQueueHead != NULL) { -- cgit v0.12 From 4b3f548c27a261486fcf98dc1fae95b0e06193db Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 5 Feb 2015 18:17:07 +0000 Subject: Bump to version 8.5.18. --- README | 2 +- generic/tcl.h | 4 ++-- library/init.tcl | 2 +- tools/tcl.wse.in | 2 +- unix/configure | 2 +- unix/configure.in | 2 +- unix/tcl.spec | 2 +- win/configure | 2 +- win/configure.in | 2 +- 9 files changed, 10 insertions(+), 10 deletions(-) diff --git a/README b/README index 425ca16..6d5a9be 100644 --- a/README +++ b/README @@ -1,5 +1,5 @@ README: Tcl - This is the Tcl 8.5.17 source distribution. + This is the Tcl 8.5.18 source distribution. http://sourceforge.net/projects/tcl/files/Tcl/ You can get any source release of Tcl from the URL above. diff --git a/generic/tcl.h b/generic/tcl.h index 98cd577..464f205 100644 --- a/generic/tcl.h +++ b/generic/tcl.h @@ -58,10 +58,10 @@ extern "C" { #define TCL_MAJOR_VERSION 8 #define TCL_MINOR_VERSION 5 #define TCL_RELEASE_LEVEL TCL_FINAL_RELEASE -#define TCL_RELEASE_SERIAL 17 +#define TCL_RELEASE_SERIAL 18 #define TCL_VERSION "8.5" -#define TCL_PATCH_LEVEL "8.5.17" +#define TCL_PATCH_LEVEL "8.5.18" /* * The following definitions set up the proper options for Windows compilers. diff --git a/library/init.tcl b/library/init.tcl index 5004e0c..4981cd6 100644 --- a/library/init.tcl +++ b/library/init.tcl @@ -16,7 +16,7 @@ if {[info commands package] == ""} { error "version mismatch: library\nscripts expect Tcl version 7.5b1 or later but the loaded version is\nonly [info patchlevel]" } -package require -exact Tcl 8.5.17 +package require -exact Tcl 8.5.18 # Compute the auto path to use in this interpreter. # The values on the path come from several locations: diff --git a/tools/tcl.wse.in b/tools/tcl.wse.in index e1810ef..0c1ee4c 100644 --- a/tools/tcl.wse.in +++ b/tools/tcl.wse.in @@ -12,7 +12,7 @@ item: Global Log Pathname=%MAINDIR%\INSTALL.LOG Message Font=MS Sans Serif Font Size=8 - Disk Label=tcl8.5.16 + Disk Label=tcl8.5.18 Disk Filename=setup Patch Flags=0000000000000001 Patch Threshold=85 diff --git a/unix/configure b/unix/configure index 1264916..7a1ab59 100755 --- a/unix/configure +++ b/unix/configure @@ -1335,7 +1335,7 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu TCL_VERSION=8.5 TCL_MAJOR_VERSION=8 TCL_MINOR_VERSION=5 -TCL_PATCH_LEVEL=".17" +TCL_PATCH_LEVEL=".18" VERSION=${TCL_VERSION} #------------------------------------------------------------------------ diff --git a/unix/configure.in b/unix/configure.in index 22c8985..e9f5aa5 100644 --- a/unix/configure.in +++ b/unix/configure.in @@ -25,7 +25,7 @@ m4_ifdef([SC_USE_CONFIG_HEADERS], [ TCL_VERSION=8.5 TCL_MAJOR_VERSION=8 TCL_MINOR_VERSION=5 -TCL_PATCH_LEVEL=".17" +TCL_PATCH_LEVEL=".18" VERSION=${TCL_VERSION} #------------------------------------------------------------------------ diff --git a/unix/tcl.spec b/unix/tcl.spec index 4b6a6a0..940fd1e 100644 --- a/unix/tcl.spec +++ b/unix/tcl.spec @@ -4,7 +4,7 @@ Name: tcl Summary: Tcl scripting language development environment -Version: 8.5.17 +Version: 8.5.18 Release: 2 License: BSD Group: Development/Languages diff --git a/win/configure b/win/configure index dc24431..99519a8 100755 --- a/win/configure +++ b/win/configure @@ -1311,7 +1311,7 @@ SHELL=/bin/sh TCL_VERSION=8.5 TCL_MAJOR_VERSION=8 TCL_MINOR_VERSION=5 -TCL_PATCH_LEVEL=".17" +TCL_PATCH_LEVEL=".18" VER=$TCL_MAJOR_VERSION$TCL_MINOR_VERSION TCL_DDE_VERSION=1.3 diff --git a/win/configure.in b/win/configure.in index 14d9b0f..88270cf 100644 --- a/win/configure.in +++ b/win/configure.in @@ -14,7 +14,7 @@ SHELL=/bin/sh TCL_VERSION=8.5 TCL_MAJOR_VERSION=8 TCL_MINOR_VERSION=5 -TCL_PATCH_LEVEL=".17" +TCL_PATCH_LEVEL=".18" VER=$TCL_MAJOR_VERSION$TCL_MINOR_VERSION TCL_DDE_VERSION=1.3 -- cgit v0.12 From 2fabe1cead1b5b6dd2fa65191162d9d7f41d8881 Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 5 Feb 2015 19:23:35 +0000 Subject: Backport of channel mem leak fix that got missed before. --- generic/tclIO.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index b3af1f5..5a25243 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -166,6 +166,7 @@ static ChannelBuffer * AllocChannelBuffer(int length); static void PreserveChannelBuffer(ChannelBuffer *bufPtr); static void ReleaseChannelBuffer(ChannelBuffer *bufPtr); static int IsShared(ChannelBuffer *bufPtr); +static void ChannelFree(Channel *chanPtr); static void ChannelTimerProc(ClientData clientData); static int ChanRead(Channel *chanPtr, char *dst, int dstSize); static int CheckChannelErrors(ChannelState *statePtr, @@ -1819,6 +1820,16 @@ TclChannelRelease( } } +static void +ChannelFree( + Channel *chanPtr) +{ + if (chanPtr->refCount == 0) { + ckfree((char *)chanPtr); + return; + } + chanPtr->typePtr = NULL; +} /* *---------------------------------------------------------------------- @@ -1977,7 +1988,7 @@ Tcl_UnstackChannel( interp, 0); } - chanPtr->typePtr = NULL; + ChannelFree(chanPtr); UpdateInterest(statePtr->topChanPtr); @@ -2916,7 +2927,8 @@ CloseChannel( statePtr->topChanPtr = downChanPtr; downChanPtr->upChanPtr = NULL; - chanPtr->typePtr = NULL; + + ChannelFree(chanPtr); return Tcl_Close(interp, (Tcl_Channel) downChanPtr); } @@ -2927,7 +2939,7 @@ CloseChannel( * stack, make sure to free the ChannelState structure associated with it. */ - chanPtr->typePtr = NULL; + ChannelFree(chanPtr); Tcl_EventuallyFree(statePtr, TCL_DYNAMIC); -- cgit v0.12 From 4d7ebbdc945fab1431d84f7d6b469e833dea4d5b Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 6 Feb 2015 19:56:56 +0000 Subject: update changes --- changes | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/changes b/changes index 6a617fa..69355a4 100644 --- a/changes +++ b/changes @@ -7906,3 +7906,24 @@ of Tcl_Channel (porter) 2014-10-18 (bug)[10dc6d] fix [gets] on non-blocking channels (fassel,porter) --- Released 8.5.17, October 25, 2014 --- http://core.tcl.tk/tcl/ for details + +2014-10-26 Support for Windows 10 (nijtmans) + +2014-10-31 (bug)[dcc034] restore [open comX: r+] (lll,nijtmans) + +2014-11-06 (bug)[5adc35] Stop forcing EOF to be permanent (porter) + +2014-12-03 (bug)[0c043a] Fix compiled [set var($) val] (porter) + +2014-12-04 (bug)[d2ffcc] Limit $... and bareword parsing to ASCII (ladayaroslav,porter) + *** POTENTIAL INCOMPATIBILITY *** + +2014-12-10 tzdata updated to Olson's tzdata2014j (venkat) + +2015-01-26 (bug)[df0848] Trouble with INFINITY macro (dower,nijtmans) + +2015-01-29 (bug) Stop crashes when extension var resolvers misbehave (porter) + +2015-02-05 (bug) Plug stacked channel memleak (porter) + +--- Released 8.5.18, February 28, 2015 --- http://core.tcl.tk/tcl/ for details -- cgit v0.12 From 02cc7437b244b37fbba3c278abf9835c6bd7109a Mon Sep 17 00:00:00 2001 From: bch Date: Sat, 7 Feb 2015 21:19:05 +0000 Subject: switch raw assert() to Tcl_Panic() per discussion w/ dkf --- generic/tclIO.c | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index 025708b..702e2a0 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -1548,13 +1548,23 @@ Tcl_CreateChannel( */ assert(sizeof(Tcl_ChannelTypeVersion) == sizeof(Tcl_DriverBlockModeProc *)); - assert(NULL!=typePtr->closeProc); - assert(NULL!=typePtr->inputProc); - assert(NULL!=typePtr->outputProc); - assert(NULL!=typePtr->watchProc); - assert(NULL!=typePtr->getHandleProc); - if (NULL!=typePtr->wideSeekProc) { - assert(NULL!=typePtr->seekProc && "Must define seekProc if defining wideSeekProc"); + if (NULL == typePtr->closeProc) + Tcl_Panic("Required closeProc is unset."); + + if (NULL == typePtr->inputProc) + Tcl_Panic("Required inputProc is unset."); + + if (NULL == typePtr->outputProc) + Tcl_Panic("Required outputProc is unset."); + + if (NULL == typePtr->watchProc) + Tcl_Panic("Required watchProc is unset."); + + if (NULL == typePtr->getHandleProc) + Tcl_Panic("Required getHandleProc is unset."); + + if ((NULL!=typePtr->wideSeekProc) && (NULL == typePtr->seekProc)) { + Tcl_Panic("Must define seekProc if defining wideSeekProc"); } /* -- cgit v0.12 From 4214c7a3a945dc09ed6023d87a28a2a0f85e1157 Mon Sep 17 00:00:00 2001 From: bch Date: Sun, 8 Feb 2015 05:04:33 +0000 Subject: inputProc and outputProc tests run conditionally on TCL_READABLE, TCL_WRITABLE mask --- generic/tclIO.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index 702e2a0..0ba864a 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -1551,10 +1551,10 @@ Tcl_CreateChannel( if (NULL == typePtr->closeProc) Tcl_Panic("Required closeProc is unset."); - if (NULL == typePtr->inputProc) + if ((TCL_READABLE & mask) && (NULL == typePtr->inputProc)) Tcl_Panic("Required inputProc is unset."); - if (NULL == typePtr->outputProc) + if ((TCL_WRITABLE & mask) && (NULL == typePtr->outputProc)) Tcl_Panic("Required outputProc is unset."); if (NULL == typePtr->watchProc) -- cgit v0.12 From f6b7fa43d6cf40a22f2d7813226a32ae5ab2146d Mon Sep 17 00:00:00 2001 From: venkat Date: Wed, 11 Feb 2015 00:19:01 +0000 Subject: merge tzdata2015a from ietf.org --- library/tzdata/Africa/Asmera | 6 +- library/tzdata/America/Cancun | 171 +------------------------------------ library/tzdata/America/Santiago | 171 +------------------------------------ library/tzdata/Antarctica/Palmer | 171 +------------------------------------ library/tzdata/Asia/Aden | 7 +- library/tzdata/Asia/Bahrain | 8 +- library/tzdata/Asia/Kuwait | 7 +- library/tzdata/Asia/Muscat | 7 +- library/tzdata/Atlantic/Reykjavik | 11 ++- library/tzdata/Pacific/Easter | 172 +------------------------------------- 10 files changed, 27 insertions(+), 704 deletions(-) diff --git a/library/tzdata/Africa/Asmera b/library/tzdata/Africa/Asmera index 931c36d..ca8d123 100644 --- a/library/tzdata/Africa/Asmera +++ b/library/tzdata/Africa/Asmera @@ -1,5 +1,5 @@ # created by tools/tclZIC.tcl - do not edit -if {![info exists TZData(Africa/Asmara)]} { - LoadTimeZoneFile Africa/Asmara +if {![info exists TZData(Africa/Nairobi)]} { + LoadTimeZoneFile Africa/Nairobi } -set TZData(:Africa/Asmera) $TZData(:Africa/Asmara) +set TZData(:Africa/Asmera) $TZData(:Africa/Nairobi) diff --git a/library/tzdata/America/Cancun b/library/tzdata/America/Cancun index 1620b15..fe5a060 100644 --- a/library/tzdata/America/Cancun +++ b/library/tzdata/America/Cancun @@ -43,174 +43,5 @@ set TZData(:America/Cancun) { {1382857200 -21600 0 CST} {1396771200 -18000 1 CDT} {1414306800 -21600 0 CST} - {1428220800 -18000 1 CDT} - {1445756400 -21600 0 CST} - {1459670400 -18000 1 CDT} - {1477810800 -21600 0 CST} - {1491120000 -18000 1 CDT} - {1509260400 -21600 0 CST} - {1522569600 -18000 1 CDT} - {1540710000 -21600 0 CST} - {1554624000 -18000 1 CDT} - {1572159600 -21600 0 CST} - {1586073600 -18000 1 CDT} - {1603609200 -21600 0 CST} - {1617523200 -18000 1 CDT} - {1635663600 -21600 0 CST} - {1648972800 -18000 1 CDT} - {1667113200 -21600 0 CST} - {1680422400 -18000 1 CDT} - {1698562800 -21600 0 CST} - {1712476800 -18000 1 CDT} - {1730012400 -21600 0 CST} - {1743926400 -18000 1 CDT} - {1761462000 -21600 0 CST} - {1775376000 -18000 1 CDT} - {1792911600 -21600 0 CST} - {1806825600 -18000 1 CDT} - {1824966000 -21600 0 CST} - {1838275200 -18000 1 CDT} - {1856415600 -21600 0 CST} - {1869724800 -18000 1 CDT} - {1887865200 -21600 0 CST} - {1901779200 -18000 1 CDT} - {1919314800 -21600 0 CST} - {1933228800 -18000 1 CDT} - {1950764400 -21600 0 CST} - {1964678400 -18000 1 CDT} - {1982818800 -21600 0 CST} - {1996128000 -18000 1 CDT} - {2014268400 -21600 0 CST} - {2027577600 -18000 1 CDT} - {2045718000 -21600 0 CST} - {2059027200 -18000 1 CDT} - {2077167600 -21600 0 CST} - {2091081600 -18000 1 CDT} - {2108617200 -21600 0 CST} - {2122531200 -18000 1 CDT} - {2140066800 -21600 0 CST} - {2153980800 -18000 1 CDT} - {2172121200 -21600 0 CST} - {2185430400 -18000 1 CDT} - {2203570800 -21600 0 CST} - {2216880000 -18000 1 CDT} - {2235020400 -21600 0 CST} - {2248934400 -18000 1 CDT} - {2266470000 -21600 0 CST} - {2280384000 -18000 1 CDT} - {2297919600 -21600 0 CST} - {2311833600 -18000 1 CDT} - {2329369200 -21600 0 CST} - {2343283200 -18000 1 CDT} - {2361423600 -21600 0 CST} - {2374732800 -18000 1 CDT} - {2392873200 -21600 0 CST} - {2406182400 -18000 1 CDT} - {2424322800 -21600 0 CST} - {2438236800 -18000 1 CDT} - {2455772400 -21600 0 CST} - {2469686400 -18000 1 CDT} - {2487222000 -21600 0 CST} - {2501136000 -18000 1 CDT} - {2519276400 -21600 0 CST} - {2532585600 -18000 1 CDT} - {2550726000 -21600 0 CST} - {2564035200 -18000 1 CDT} - {2582175600 -21600 0 CST} - {2596089600 -18000 1 CDT} - {2613625200 -21600 0 CST} - {2627539200 -18000 1 CDT} - {2645074800 -21600 0 CST} - {2658988800 -18000 1 CDT} - {2676524400 -21600 0 CST} - {2690438400 -18000 1 CDT} - {2708578800 -21600 0 CST} - {2721888000 -18000 1 CDT} - {2740028400 -21600 0 CST} - {2753337600 -18000 1 CDT} - {2771478000 -21600 0 CST} - {2785392000 -18000 1 CDT} - {2802927600 -21600 0 CST} - {2816841600 -18000 1 CDT} - {2834377200 -21600 0 CST} - {2848291200 -18000 1 CDT} - {2866431600 -21600 0 CST} - {2879740800 -18000 1 CDT} - {2897881200 -21600 0 CST} - {2911190400 -18000 1 CDT} - {2929330800 -21600 0 CST} - {2942640000 -18000 1 CDT} - {2960780400 -21600 0 CST} - {2974694400 -18000 1 CDT} - {2992230000 -21600 0 CST} - {3006144000 -18000 1 CDT} - {3023679600 -21600 0 CST} - {3037593600 -18000 1 CDT} - {3055734000 -21600 0 CST} - {3069043200 -18000 1 CDT} - {3087183600 -21600 0 CST} - {3100492800 -18000 1 CDT} - {3118633200 -21600 0 CST} - {3132547200 -18000 1 CDT} - {3150082800 -21600 0 CST} - {3163996800 -18000 1 CDT} - {3181532400 -21600 0 CST} - {3195446400 -18000 1 CDT} - {3212982000 -21600 0 CST} - {3226896000 -18000 1 CDT} - {3245036400 -21600 0 CST} - {3258345600 -18000 1 CDT} - {3276486000 -21600 0 CST} - {3289795200 -18000 1 CDT} - {3307935600 -21600 0 CST} - {3321849600 -18000 1 CDT} - {3339385200 -21600 0 CST} - {3353299200 -18000 1 CDT} - {3370834800 -21600 0 CST} - {3384748800 -18000 1 CDT} - {3402889200 -21600 0 CST} - {3416198400 -18000 1 CDT} - {3434338800 -21600 0 CST} - {3447648000 -18000 1 CDT} - {3465788400 -21600 0 CST} - {3479702400 -18000 1 CDT} - {3497238000 -21600 0 CST} - {3511152000 -18000 1 CDT} - {3528687600 -21600 0 CST} - {3542601600 -18000 1 CDT} - {3560137200 -21600 0 CST} - {3574051200 -18000 1 CDT} - {3592191600 -21600 0 CST} - {3605500800 -18000 1 CDT} - {3623641200 -21600 0 CST} - {3636950400 -18000 1 CDT} - {3655090800 -21600 0 CST} - {3669004800 -18000 1 CDT} - {3686540400 -21600 0 CST} - {3700454400 -18000 1 CDT} - {3717990000 -21600 0 CST} - {3731904000 -18000 1 CDT} - {3750044400 -21600 0 CST} - {3763353600 -18000 1 CDT} - {3781494000 -21600 0 CST} - {3794803200 -18000 1 CDT} - {3812943600 -21600 0 CST} - {3826252800 -18000 1 CDT} - {3844393200 -21600 0 CST} - {3858307200 -18000 1 CDT} - {3875842800 -21600 0 CST} - {3889756800 -18000 1 CDT} - {3907292400 -21600 0 CST} - {3921206400 -18000 1 CDT} - {3939346800 -21600 0 CST} - {3952656000 -18000 1 CDT} - {3970796400 -21600 0 CST} - {3984105600 -18000 1 CDT} - {4002246000 -21600 0 CST} - {4016160000 -18000 1 CDT} - {4033695600 -21600 0 CST} - {4047609600 -18000 1 CDT} - {4065145200 -21600 0 CST} - {4079059200 -18000 1 CDT} - {4096594800 -21600 0 CST} + {1422777600 -18000 0 EST} } diff --git a/library/tzdata/America/Santiago b/library/tzdata/America/Santiago index 44be9f8..29c2a93 100644 --- a/library/tzdata/America/Santiago +++ b/library/tzdata/America/Santiago @@ -118,174 +118,5 @@ set TZData(:America/Santiago) { {1378612800 -10800 1 CLST} {1398567600 -14400 0 CLT} {1410062400 -10800 1 CLST} - {1430017200 -14400 0 CLT} - {1441512000 -10800 1 CLST} - {1461466800 -14400 0 CLT} - {1472961600 -10800 1 CLST} - {1492916400 -14400 0 CLT} - {1504411200 -10800 1 CLST} - {1524970800 -14400 0 CLT} - {1535860800 -10800 1 CLST} - {1556420400 -14400 0 CLT} - {1567915200 -10800 1 CLST} - {1587870000 -14400 0 CLT} - {1599364800 -10800 1 CLST} - {1619319600 -14400 0 CLT} - {1630814400 -10800 1 CLST} - {1650769200 -14400 0 CLT} - {1662264000 -10800 1 CLST} - {1682218800 -14400 0 CLT} - {1693713600 -10800 1 CLST} - {1714273200 -14400 0 CLT} - {1725768000 -10800 1 CLST} - {1745722800 -14400 0 CLT} - {1757217600 -10800 1 CLST} - {1777172400 -14400 0 CLT} - {1788667200 -10800 1 CLST} - {1808622000 -14400 0 CLT} - {1820116800 -10800 1 CLST} - {1840071600 -14400 0 CLT} - {1851566400 -10800 1 CLST} - {1872126000 -14400 0 CLT} - {1883016000 -10800 1 CLST} - {1903575600 -14400 0 CLT} - {1915070400 -10800 1 CLST} - {1935025200 -14400 0 CLT} - {1946520000 -10800 1 CLST} - {1966474800 -14400 0 CLT} - {1977969600 -10800 1 CLST} - {1997924400 -14400 0 CLT} - {2009419200 -10800 1 CLST} - {2029374000 -14400 0 CLT} - {2040868800 -10800 1 CLST} - {2061428400 -14400 0 CLT} - {2072318400 -10800 1 CLST} - {2092878000 -14400 0 CLT} - {2104372800 -10800 1 CLST} - {2124327600 -14400 0 CLT} - {2135822400 -10800 1 CLST} - {2155777200 -14400 0 CLT} - {2167272000 -10800 1 CLST} - {2187226800 -14400 0 CLT} - {2198721600 -10800 1 CLST} - {2219281200 -14400 0 CLT} - {2230171200 -10800 1 CLST} - {2250730800 -14400 0 CLT} - {2262225600 -10800 1 CLST} - {2282180400 -14400 0 CLT} - {2293675200 -10800 1 CLST} - {2313630000 -14400 0 CLT} - {2325124800 -10800 1 CLST} - {2345079600 -14400 0 CLT} - {2356574400 -10800 1 CLST} - {2376529200 -14400 0 CLT} - {2388024000 -10800 1 CLST} - {2408583600 -14400 0 CLT} - {2419473600 -10800 1 CLST} - {2440033200 -14400 0 CLT} - {2451528000 -10800 1 CLST} - {2471482800 -14400 0 CLT} - {2482977600 -10800 1 CLST} - {2502932400 -14400 0 CLT} - {2514427200 -10800 1 CLST} - {2534382000 -14400 0 CLT} - {2545876800 -10800 1 CLST} - {2565831600 -14400 0 CLT} - {2577326400 -10800 1 CLST} - {2597886000 -14400 0 CLT} - {2609380800 -10800 1 CLST} - {2629335600 -14400 0 CLT} - {2640830400 -10800 1 CLST} - {2660785200 -14400 0 CLT} - {2672280000 -10800 1 CLST} - {2692234800 -14400 0 CLT} - {2703729600 -10800 1 CLST} - {2723684400 -14400 0 CLT} - {2735179200 -10800 1 CLST} - {2755738800 -14400 0 CLT} - {2766628800 -10800 1 CLST} - {2787188400 -14400 0 CLT} - {2798683200 -10800 1 CLST} - {2818638000 -14400 0 CLT} - {2830132800 -10800 1 CLST} - {2850087600 -14400 0 CLT} - {2861582400 -10800 1 CLST} - {2881537200 -14400 0 CLT} - {2893032000 -10800 1 CLST} - {2912986800 -14400 0 CLT} - {2924481600 -10800 1 CLST} - {2945041200 -14400 0 CLT} - {2955931200 -10800 1 CLST} - {2976490800 -14400 0 CLT} - {2987985600 -10800 1 CLST} - {3007940400 -14400 0 CLT} - {3019435200 -10800 1 CLST} - {3039390000 -14400 0 CLT} - {3050884800 -10800 1 CLST} - {3070839600 -14400 0 CLT} - {3082334400 -10800 1 CLST} - {3102894000 -14400 0 CLT} - {3113784000 -10800 1 CLST} - {3134343600 -14400 0 CLT} - {3145838400 -10800 1 CLST} - {3165793200 -14400 0 CLT} - {3177288000 -10800 1 CLST} - {3197242800 -14400 0 CLT} - {3208737600 -10800 1 CLST} - {3228692400 -14400 0 CLT} - {3240187200 -10800 1 CLST} - {3260142000 -14400 0 CLT} - {3271636800 -10800 1 CLST} - {3292196400 -14400 0 CLT} - {3303086400 -10800 1 CLST} - {3323646000 -14400 0 CLT} - {3335140800 -10800 1 CLST} - {3355095600 -14400 0 CLT} - {3366590400 -10800 1 CLST} - {3386545200 -14400 0 CLT} - {3398040000 -10800 1 CLST} - {3417994800 -14400 0 CLT} - {3429489600 -10800 1 CLST} - {3449444400 -14400 0 CLT} - {3460939200 -10800 1 CLST} - {3481498800 -14400 0 CLT} - {3492993600 -10800 1 CLST} - {3512948400 -14400 0 CLT} - {3524443200 -10800 1 CLST} - {3544398000 -14400 0 CLT} - {3555892800 -10800 1 CLST} - {3575847600 -14400 0 CLT} - {3587342400 -10800 1 CLST} - {3607297200 -14400 0 CLT} - {3618792000 -10800 1 CLST} - {3639351600 -14400 0 CLT} - {3650241600 -10800 1 CLST} - {3670801200 -14400 0 CLT} - {3682296000 -10800 1 CLST} - {3702250800 -14400 0 CLT} - {3713745600 -10800 1 CLST} - {3733700400 -14400 0 CLT} - {3745195200 -10800 1 CLST} - {3765150000 -14400 0 CLT} - {3776644800 -10800 1 CLST} - {3796599600 -14400 0 CLT} - {3808094400 -10800 1 CLST} - {3828654000 -14400 0 CLT} - {3839544000 -10800 1 CLST} - {3860103600 -14400 0 CLT} - {3871598400 -10800 1 CLST} - {3891553200 -14400 0 CLT} - {3903048000 -10800 1 CLST} - {3923002800 -14400 0 CLT} - {3934497600 -10800 1 CLST} - {3954452400 -14400 0 CLT} - {3965947200 -10800 1 CLST} - {3986506800 -14400 0 CLT} - {3997396800 -10800 1 CLST} - {4017956400 -14400 0 CLT} - {4029451200 -10800 1 CLST} - {4049406000 -14400 0 CLT} - {4060900800 -10800 1 CLST} - {4080855600 -14400 0 CLT} - {4092350400 -10800 1 CLST} + {1430017200 -10800 0 CLT} } diff --git a/library/tzdata/Antarctica/Palmer b/library/tzdata/Antarctica/Palmer index e87b171..f12528b 100644 --- a/library/tzdata/Antarctica/Palmer +++ b/library/tzdata/Antarctica/Palmer @@ -81,174 +81,5 @@ set TZData(:Antarctica/Palmer) { {1378612800 -10800 1 CLST} {1398567600 -14400 0 CLT} {1410062400 -10800 1 CLST} - {1430017200 -14400 0 CLT} - {1441512000 -10800 1 CLST} - {1461466800 -14400 0 CLT} - {1472961600 -10800 1 CLST} - {1492916400 -14400 0 CLT} - {1504411200 -10800 1 CLST} - {1524970800 -14400 0 CLT} - {1535860800 -10800 1 CLST} - {1556420400 -14400 0 CLT} - {1567915200 -10800 1 CLST} - {1587870000 -14400 0 CLT} - {1599364800 -10800 1 CLST} - {1619319600 -14400 0 CLT} - {1630814400 -10800 1 CLST} - {1650769200 -14400 0 CLT} - {1662264000 -10800 1 CLST} - {1682218800 -14400 0 CLT} - {1693713600 -10800 1 CLST} - {1714273200 -14400 0 CLT} - {1725768000 -10800 1 CLST} - {1745722800 -14400 0 CLT} - {1757217600 -10800 1 CLST} - {1777172400 -14400 0 CLT} - {1788667200 -10800 1 CLST} - {1808622000 -14400 0 CLT} - {1820116800 -10800 1 CLST} - {1840071600 -14400 0 CLT} - {1851566400 -10800 1 CLST} - {1872126000 -14400 0 CLT} - {1883016000 -10800 1 CLST} - {1903575600 -14400 0 CLT} - {1915070400 -10800 1 CLST} - {1935025200 -14400 0 CLT} - {1946520000 -10800 1 CLST} - {1966474800 -14400 0 CLT} - {1977969600 -10800 1 CLST} - {1997924400 -14400 0 CLT} - {2009419200 -10800 1 CLST} - {2029374000 -14400 0 CLT} - {2040868800 -10800 1 CLST} - {2061428400 -14400 0 CLT} - {2072318400 -10800 1 CLST} - {2092878000 -14400 0 CLT} - {2104372800 -10800 1 CLST} - {2124327600 -14400 0 CLT} - {2135822400 -10800 1 CLST} - {2155777200 -14400 0 CLT} - {2167272000 -10800 1 CLST} - {2187226800 -14400 0 CLT} - {2198721600 -10800 1 CLST} - {2219281200 -14400 0 CLT} - {2230171200 -10800 1 CLST} - {2250730800 -14400 0 CLT} - {2262225600 -10800 1 CLST} - {2282180400 -14400 0 CLT} - {2293675200 -10800 1 CLST} - {2313630000 -14400 0 CLT} - {2325124800 -10800 1 CLST} - {2345079600 -14400 0 CLT} - {2356574400 -10800 1 CLST} - {2376529200 -14400 0 CLT} - {2388024000 -10800 1 CLST} - {2408583600 -14400 0 CLT} - {2419473600 -10800 1 CLST} - {2440033200 -14400 0 CLT} - {2451528000 -10800 1 CLST} - {2471482800 -14400 0 CLT} - {2482977600 -10800 1 CLST} - {2502932400 -14400 0 CLT} - {2514427200 -10800 1 CLST} - {2534382000 -14400 0 CLT} - {2545876800 -10800 1 CLST} - {2565831600 -14400 0 CLT} - {2577326400 -10800 1 CLST} - {2597886000 -14400 0 CLT} - {2609380800 -10800 1 CLST} - {2629335600 -14400 0 CLT} - {2640830400 -10800 1 CLST} - {2660785200 -14400 0 CLT} - {2672280000 -10800 1 CLST} - {2692234800 -14400 0 CLT} - {2703729600 -10800 1 CLST} - {2723684400 -14400 0 CLT} - {2735179200 -10800 1 CLST} - {2755738800 -14400 0 CLT} - {2766628800 -10800 1 CLST} - {2787188400 -14400 0 CLT} - {2798683200 -10800 1 CLST} - {2818638000 -14400 0 CLT} - {2830132800 -10800 1 CLST} - {2850087600 -14400 0 CLT} - {2861582400 -10800 1 CLST} - {2881537200 -14400 0 CLT} - {2893032000 -10800 1 CLST} - {2912986800 -14400 0 CLT} - {2924481600 -10800 1 CLST} - {2945041200 -14400 0 CLT} - {2955931200 -10800 1 CLST} - {2976490800 -14400 0 CLT} - {2987985600 -10800 1 CLST} - {3007940400 -14400 0 CLT} - {3019435200 -10800 1 CLST} - {3039390000 -14400 0 CLT} - {3050884800 -10800 1 CLST} - {3070839600 -14400 0 CLT} - {3082334400 -10800 1 CLST} - {3102894000 -14400 0 CLT} - {3113784000 -10800 1 CLST} - {3134343600 -14400 0 CLT} - {3145838400 -10800 1 CLST} - {3165793200 -14400 0 CLT} - {3177288000 -10800 1 CLST} - {3197242800 -14400 0 CLT} - {3208737600 -10800 1 CLST} - {3228692400 -14400 0 CLT} - {3240187200 -10800 1 CLST} - {3260142000 -14400 0 CLT} - {3271636800 -10800 1 CLST} - {3292196400 -14400 0 CLT} - {3303086400 -10800 1 CLST} - {3323646000 -14400 0 CLT} - {3335140800 -10800 1 CLST} - {3355095600 -14400 0 CLT} - {3366590400 -10800 1 CLST} - {3386545200 -14400 0 CLT} - {3398040000 -10800 1 CLST} - {3417994800 -14400 0 CLT} - {3429489600 -10800 1 CLST} - {3449444400 -14400 0 CLT} - {3460939200 -10800 1 CLST} - {3481498800 -14400 0 CLT} - {3492993600 -10800 1 CLST} - {3512948400 -14400 0 CLT} - {3524443200 -10800 1 CLST} - {3544398000 -14400 0 CLT} - {3555892800 -10800 1 CLST} - {3575847600 -14400 0 CLT} - {3587342400 -10800 1 CLST} - {3607297200 -14400 0 CLT} - {3618792000 -10800 1 CLST} - {3639351600 -14400 0 CLT} - {3650241600 -10800 1 CLST} - {3670801200 -14400 0 CLT} - {3682296000 -10800 1 CLST} - {3702250800 -14400 0 CLT} - {3713745600 -10800 1 CLST} - {3733700400 -14400 0 CLT} - {3745195200 -10800 1 CLST} - {3765150000 -14400 0 CLT} - {3776644800 -10800 1 CLST} - {3796599600 -14400 0 CLT} - {3808094400 -10800 1 CLST} - {3828654000 -14400 0 CLT} - {3839544000 -10800 1 CLST} - {3860103600 -14400 0 CLT} - {3871598400 -10800 1 CLST} - {3891553200 -14400 0 CLT} - {3903048000 -10800 1 CLST} - {3923002800 -14400 0 CLT} - {3934497600 -10800 1 CLST} - {3954452400 -14400 0 CLT} - {3965947200 -10800 1 CLST} - {3986506800 -14400 0 CLT} - {3997396800 -10800 1 CLST} - {4017956400 -14400 0 CLT} - {4029451200 -10800 1 CLST} - {4049406000 -14400 0 CLT} - {4060900800 -10800 1 CLST} - {4080855600 -14400 0 CLT} - {4092350400 -10800 1 CLST} + {1430017200 -10800 0 CLT} } diff --git a/library/tzdata/Asia/Aden b/library/tzdata/Asia/Aden index 399d9f0..5c5515e 100644 --- a/library/tzdata/Asia/Aden +++ b/library/tzdata/Asia/Aden @@ -1,6 +1,5 @@ # created by tools/tclZIC.tcl - do not edit - -set TZData(:Asia/Aden) { - {-9223372036854775808 10794 0 LMT} - {-631162794 10800 0 AST} +if {![info exists TZData(Asia/Riyadh)]} { + LoadTimeZoneFile Asia/Riyadh } +set TZData(:Asia/Aden) $TZData(:Asia/Riyadh) diff --git a/library/tzdata/Asia/Bahrain b/library/tzdata/Asia/Bahrain index d4b7d2c..aab5b7d 100644 --- a/library/tzdata/Asia/Bahrain +++ b/library/tzdata/Asia/Bahrain @@ -1,7 +1,5 @@ # created by tools/tclZIC.tcl - do not edit - -set TZData(:Asia/Bahrain) { - {-9223372036854775808 12140 0 LMT} - {-1577935340 14400 0 GST} - {76190400 10800 0 AST} +if {![info exists TZData(Asia/Qatar)]} { + LoadTimeZoneFile Asia/Qatar } +set TZData(:Asia/Bahrain) $TZData(:Asia/Qatar) diff --git a/library/tzdata/Asia/Kuwait b/library/tzdata/Asia/Kuwait index 15d26db..e618c56 100644 --- a/library/tzdata/Asia/Kuwait +++ b/library/tzdata/Asia/Kuwait @@ -1,6 +1,5 @@ # created by tools/tclZIC.tcl - do not edit - -set TZData(:Asia/Kuwait) { - {-9223372036854775808 11516 0 LMT} - {-631163516 10800 0 AST} +if {![info exists TZData(Asia/Riyadh)]} { + LoadTimeZoneFile Asia/Riyadh } +set TZData(:Asia/Kuwait) $TZData(:Asia/Riyadh) diff --git a/library/tzdata/Asia/Muscat b/library/tzdata/Asia/Muscat index a69b880..fdd34c1 100644 --- a/library/tzdata/Asia/Muscat +++ b/library/tzdata/Asia/Muscat @@ -1,6 +1,5 @@ # created by tools/tclZIC.tcl - do not edit - -set TZData(:Asia/Muscat) { - {-9223372036854775808 14064 0 LMT} - {-1577937264 14400 0 GST} +if {![info exists TZData(Asia/Dubai)]} { + LoadTimeZoneFile Asia/Dubai } +set TZData(:Asia/Muscat) $TZData(:Asia/Dubai) diff --git a/library/tzdata/Atlantic/Reykjavik b/library/tzdata/Atlantic/Reykjavik index f0248ad..ad7f0db 100644 --- a/library/tzdata/Atlantic/Reykjavik +++ b/library/tzdata/Atlantic/Reykjavik @@ -1,15 +1,18 @@ # created by tools/tclZIC.tcl - do not edit set TZData(:Atlantic/Reykjavik) { - {-9223372036854775808 -5244 0 LMT} - {-4197047556 -5268 0 RMT} - {-1956609132 -3600 0 IST} + {-9223372036854775808 -5280 0 LMT} + {-1956609120 -3600 0 IST} {-1668211200 0 1 ISST} {-1647212400 -3600 0 IST} {-1636675200 0 1 ISST} {-1613430000 -3600 0 IST} + {-1605139200 0 1 ISST} + {-1581894000 -3600 0 IST} + {-1539561600 0 1 ISST} + {-1531350000 -3600 0 IST} {-968025600 0 1 ISST} - {-949615200 -3600 0 IST} + {-952293600 -3600 0 IST} {-942008400 0 1 ISST} {-920239200 -3600 0 IST} {-909957600 0 1 ISST} diff --git a/library/tzdata/Pacific/Easter b/library/tzdata/Pacific/Easter index 000c6d1..f76594a 100644 --- a/library/tzdata/Pacific/Easter +++ b/library/tzdata/Pacific/Easter @@ -36,6 +36,7 @@ set TZData(:Pacific/Easter) { {340171200 -21600 1 EASST} {353473200 -25200 0 EAST} {371620800 -21600 1 EASST} + {384836400 -18000 0 EAST} {384922800 -21600 0 EAST} {403070400 -18000 1 EASST} {416372400 -21600 0 EAST} @@ -102,174 +103,5 @@ set TZData(:Pacific/Easter) { {1378612800 -18000 1 EASST} {1398567600 -21600 0 EAST} {1410062400 -18000 1 EASST} - {1430017200 -21600 0 EAST} - {1441512000 -18000 1 EASST} - {1461466800 -21600 0 EAST} - {1472961600 -18000 1 EASST} - {1492916400 -21600 0 EAST} - {1504411200 -18000 1 EASST} - {1524970800 -21600 0 EAST} - {1535860800 -18000 1 EASST} - {1556420400 -21600 0 EAST} - {1567915200 -18000 1 EASST} - {1587870000 -21600 0 EAST} - {1599364800 -18000 1 EASST} - {1619319600 -21600 0 EAST} - {1630814400 -18000 1 EASST} - {1650769200 -21600 0 EAST} - {1662264000 -18000 1 EASST} - {1682218800 -21600 0 EAST} - {1693713600 -18000 1 EASST} - {1714273200 -21600 0 EAST} - {1725768000 -18000 1 EASST} - {1745722800 -21600 0 EAST} - {1757217600 -18000 1 EASST} - {1777172400 -21600 0 EAST} - {1788667200 -18000 1 EASST} - {1808622000 -21600 0 EAST} - {1820116800 -18000 1 EASST} - {1840071600 -21600 0 EAST} - {1851566400 -18000 1 EASST} - {1872126000 -21600 0 EAST} - {1883016000 -18000 1 EASST} - {1903575600 -21600 0 EAST} - {1915070400 -18000 1 EASST} - {1935025200 -21600 0 EAST} - {1946520000 -18000 1 EASST} - {1966474800 -21600 0 EAST} - {1977969600 -18000 1 EASST} - {1997924400 -21600 0 EAST} - {2009419200 -18000 1 EASST} - {2029374000 -21600 0 EAST} - {2040868800 -18000 1 EASST} - {2061428400 -21600 0 EAST} - {2072318400 -18000 1 EASST} - {2092878000 -21600 0 EAST} - {2104372800 -18000 1 EASST} - {2124327600 -21600 0 EAST} - {2135822400 -18000 1 EASST} - {2155777200 -21600 0 EAST} - {2167272000 -18000 1 EASST} - {2187226800 -21600 0 EAST} - {2198721600 -18000 1 EASST} - {2219281200 -21600 0 EAST} - {2230171200 -18000 1 EASST} - {2250730800 -21600 0 EAST} - {2262225600 -18000 1 EASST} - {2282180400 -21600 0 EAST} - {2293675200 -18000 1 EASST} - {2313630000 -21600 0 EAST} - {2325124800 -18000 1 EASST} - {2345079600 -21600 0 EAST} - {2356574400 -18000 1 EASST} - {2376529200 -21600 0 EAST} - {2388024000 -18000 1 EASST} - {2408583600 -21600 0 EAST} - {2419473600 -18000 1 EASST} - {2440033200 -21600 0 EAST} - {2451528000 -18000 1 EASST} - {2471482800 -21600 0 EAST} - {2482977600 -18000 1 EASST} - {2502932400 -21600 0 EAST} - {2514427200 -18000 1 EASST} - {2534382000 -21600 0 EAST} - {2545876800 -18000 1 EASST} - {2565831600 -21600 0 EAST} - {2577326400 -18000 1 EASST} - {2597886000 -21600 0 EAST} - {2609380800 -18000 1 EASST} - {2629335600 -21600 0 EAST} - {2640830400 -18000 1 EASST} - {2660785200 -21600 0 EAST} - {2672280000 -18000 1 EASST} - {2692234800 -21600 0 EAST} - {2703729600 -18000 1 EASST} - {2723684400 -21600 0 EAST} - {2735179200 -18000 1 EASST} - {2755738800 -21600 0 EAST} - {2766628800 -18000 1 EASST} - {2787188400 -21600 0 EAST} - {2798683200 -18000 1 EASST} - {2818638000 -21600 0 EAST} - {2830132800 -18000 1 EASST} - {2850087600 -21600 0 EAST} - {2861582400 -18000 1 EASST} - {2881537200 -21600 0 EAST} - {2893032000 -18000 1 EASST} - {2912986800 -21600 0 EAST} - {2924481600 -18000 1 EASST} - {2945041200 -21600 0 EAST} - {2955931200 -18000 1 EASST} - {2976490800 -21600 0 EAST} - {2987985600 -18000 1 EASST} - {3007940400 -21600 0 EAST} - {3019435200 -18000 1 EASST} - {3039390000 -21600 0 EAST} - {3050884800 -18000 1 EASST} - {3070839600 -21600 0 EAST} - {3082334400 -18000 1 EASST} - {3102894000 -21600 0 EAST} - {3113784000 -18000 1 EASST} - {3134343600 -21600 0 EAST} - {3145838400 -18000 1 EASST} - {3165793200 -21600 0 EAST} - {3177288000 -18000 1 EASST} - {3197242800 -21600 0 EAST} - {3208737600 -18000 1 EASST} - {3228692400 -21600 0 EAST} - {3240187200 -18000 1 EASST} - {3260142000 -21600 0 EAST} - {3271636800 -18000 1 EASST} - {3292196400 -21600 0 EAST} - {3303086400 -18000 1 EASST} - {3323646000 -21600 0 EAST} - {3335140800 -18000 1 EASST} - {3355095600 -21600 0 EAST} - {3366590400 -18000 1 EASST} - {3386545200 -21600 0 EAST} - {3398040000 -18000 1 EASST} - {3417994800 -21600 0 EAST} - {3429489600 -18000 1 EASST} - {3449444400 -21600 0 EAST} - {3460939200 -18000 1 EASST} - {3481498800 -21600 0 EAST} - {3492993600 -18000 1 EASST} - {3512948400 -21600 0 EAST} - {3524443200 -18000 1 EASST} - {3544398000 -21600 0 EAST} - {3555892800 -18000 1 EASST} - {3575847600 -21600 0 EAST} - {3587342400 -18000 1 EASST} - {3607297200 -21600 0 EAST} - {3618792000 -18000 1 EASST} - {3639351600 -21600 0 EAST} - {3650241600 -18000 1 EASST} - {3670801200 -21600 0 EAST} - {3682296000 -18000 1 EASST} - {3702250800 -21600 0 EAST} - {3713745600 -18000 1 EASST} - {3733700400 -21600 0 EAST} - {3745195200 -18000 1 EASST} - {3765150000 -21600 0 EAST} - {3776644800 -18000 1 EASST} - {3796599600 -21600 0 EAST} - {3808094400 -18000 1 EASST} - {3828654000 -21600 0 EAST} - {3839544000 -18000 1 EASST} - {3860103600 -21600 0 EAST} - {3871598400 -18000 1 EASST} - {3891553200 -21600 0 EAST} - {3903048000 -18000 1 EASST} - {3923002800 -21600 0 EAST} - {3934497600 -18000 1 EASST} - {3954452400 -21600 0 EAST} - {3965947200 -18000 1 EASST} - {3986506800 -21600 0 EAST} - {3997396800 -18000 1 EASST} - {4017956400 -21600 0 EAST} - {4029451200 -18000 1 EASST} - {4049406000 -21600 0 EAST} - {4060900800 -18000 1 EASST} - {4080855600 -21600 0 EAST} - {4092350400 -18000 1 EASST} + {1430017200 -18000 0 EAST} } -- cgit v0.12 From fc506f9ca941f66152940a0e4821c9308427aa91 Mon Sep 17 00:00:00 2001 From: dkf Date: Wed, 11 Feb 2015 15:56:27 +0000 Subject: Even clearer failure messages. --- generic/tclIO.c | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index 0ba864a..aabae0b 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -1548,23 +1548,24 @@ Tcl_CreateChannel( */ assert(sizeof(Tcl_ChannelTypeVersion) == sizeof(Tcl_DriverBlockModeProc *)); - if (NULL == typePtr->closeProc) - Tcl_Panic("Required closeProc is unset."); - - if ((TCL_READABLE & mask) && (NULL == typePtr->inputProc)) - Tcl_Panic("Required inputProc is unset."); - - if ((TCL_WRITABLE & mask) && (NULL == typePtr->outputProc)) - Tcl_Panic("Required outputProc is unset."); - - if (NULL == typePtr->watchProc) - Tcl_Panic("Required watchProc is unset."); - - if (NULL == typePtr->getHandleProc) - Tcl_Panic("Required getHandleProc is unset."); - + assert(typePtr->typeName != NULL); + if (NULL == typePtr->closeProc) { + Tcl_Panic("channel type %s must define closeProc", typePtr->typeName); + } + if ((TCL_READABLE & mask) && (NULL == typePtr->inputProc)) { + Tcl_Panic("channel type %s must define inputProc when used for reader channel", typePtr->typeName); + } + if ((TCL_WRITABLE & mask) && (NULL == typePtr->outputProc)) { + Tcl_Panic("channel type %s must define outputProc when used for writer channel", typePtr->typeName); + } + if (NULL == typePtr->watchProc) { + Tcl_Panic("channel type %s must define watchProc", typePtr->typeName); + } + if (NULL == typePtr->getHandleProc) { + Tcl_Panic("channel type %s must define getHandleProc", typePtr->typeName); + } if ((NULL!=typePtr->wideSeekProc) && (NULL == typePtr->seekProc)) { - Tcl_Panic("Must define seekProc if defining wideSeekProc"); + Tcl_Panic("channel type %s must define seekProc if defining wideSeekProc", typePtr->typeName); } /* -- cgit v0.12 From 48650316e3373be33455bab6db0a33546169c906 Mon Sep 17 00:00:00 2001 From: aspect Date: Thu, 19 Feb 2015 02:34:43 +0000 Subject: (core ticket [32b6159246]) Fix for [lreplace l x y] where y 0 && idx2 > 0 && idx2 < idx1) { + if (idx1 >= 0 && idx2 > 0 && idx2 < idx1) { idx2 = idx1 - 1; } else if (idx1 < 0 && idx2 < 0 && idx2 < idx1) { idx2 = idx1 - 1; diff --git a/tests/lreplace.test b/tests/lreplace.test index b976788..44f3ac2 100644 --- a/tests/lreplace.test +++ b/tests/lreplace.test @@ -137,6 +137,12 @@ test lreplace-4.1 {Bug ccc2c2cc98: lreplace edge case} { test lreplace-4.2 {Bug ccc2c2cc98: lreplace edge case} { lreplace { } 1 1 } {} +test lreplace-4.3 {lreplace edge case} { + lreplace {1 2 3} 2 0 +} {1 2 3} +test lreplace-4.4 {lreplace edge case} { + lreplace {1 2 3 4 5} 3 1 +} {1 2 3 4 5} # cleanup catch {unset foo} -- cgit v0.12 From b8674e42d217b1b7ed6d7a1d89dc42a59902b108 Mon Sep 17 00:00:00 2001 From: aspect Date: Thu, 19 Feb 2015 02:42:13 +0000 Subject: handle [lreplace l x y ...] where y Date: Thu, 19 Feb 2015 06:29:18 +0000 Subject: undo erroneous change in [1fa2e32e07] --- generic/tclCompCmdsGR.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generic/tclCompCmdsGR.c b/generic/tclCompCmdsGR.c index e7f6473..b77c43c 100644 --- a/generic/tclCompCmdsGR.c +++ b/generic/tclCompCmdsGR.c @@ -1551,7 +1551,7 @@ TclCompileLreplaceCmd( idx1 = 0; goto replaceTail; } else { - if (idx1 >= 0 && idx2 > 0 && idx2 < idx1) { + if (idx1 > 0 && idx2 > 0 && idx2 < idx1) { idx2 = idx1 - 1; } else if (idx1 < 0 && idx2 < 0 && idx2 < idx1) { idx2 = idx1 - 1; -- cgit v0.12 From 87e36a4aa9f5a7afcfe25350805190088a6468ff Mon Sep 17 00:00:00 2001 From: bch Date: Thu, 19 Feb 2015 19:16:37 +0000 Subject: backout backwards-incompatible experiment that was accidentally committed --- generic/tclIORChan.c | 30 +----------------------------- 1 file changed, 1 insertion(+), 29 deletions(-) diff --git a/generic/tclIORChan.c b/generic/tclIORChan.c index 0f7f021..21c766e 100644 --- a/generic/tclIORChan.c +++ b/generic/tclIORChan.c @@ -30,8 +30,6 @@ /* * Signatures of all functions used in the C layer of the reflection. */ -static int ReflectGetHandle( ClientData instanceData, - int direction, ClientData *handlePtr); static int ReflectClose(ClientData clientData, Tcl_Interp *interp); @@ -70,7 +68,7 @@ static const Tcl_ChannelType tclRChannelType = { ReflectSetOption, /* Set options. NULL'able */ ReflectGetOption, /* Get options. NULL'able */ ReflectWatch, /* Initialize notifier */ - ReflectGetHandle, /* Get OS handle from the channel. */ + NULL, /* Get OS handle from the channel. NULL'able */ NULL, /* No close2 support. NULL'able */ ReflectBlock, /* Set blocking/nonblocking. NULL'able */ NULL, /* Flush channel. Not used by core. NULL'able */ @@ -1646,32 +1644,6 @@ ReflectWatch( /* *---------------------------------------------------------------------- * - * ReflectGetHandle -- - * - * This function is invoked to return OS channel handles, or EINVAL - * if not applicable or otherwise invalid. - * - * Results: - * EINVAL. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -int -ReflectGetHandle( - ClientData instanceData, - int direction, - ClientData *handlePtr) -{ - return EINVAL; -} - -/* - *---------------------------------------------------------------------- - * * ReflectBlock -- * * This function is invoked to tell the channel which blocking behaviour -- cgit v0.12 From 2919fd522137a679ca6de20c893a8a45dc750a52 Mon Sep 17 00:00:00 2001 From: bch Date: Thu, 19 Feb 2015 22:01:36 +0000 Subject: per ticket [e08c2c407b053bbfaab] (and stray code related to [84f208762f172e]) adj code to passing test suite --- generic/tclIO.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index aabae0b..c4757ea 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -1561,9 +1561,6 @@ Tcl_CreateChannel( if (NULL == typePtr->watchProc) { Tcl_Panic("channel type %s must define watchProc", typePtr->typeName); } - if (NULL == typePtr->getHandleProc) { - Tcl_Panic("channel type %s must define getHandleProc", typePtr->typeName); - } if ((NULL!=typePtr->wideSeekProc) && (NULL == typePtr->seekProc)) { Tcl_Panic("channel type %s must define seekProc if defining wideSeekProc", typePtr->typeName); } -- cgit v0.12 From 28fe834bc3ec4966f987250b14d1dfb1cb41bd58 Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 20 Feb 2015 19:29:20 +0000 Subject: [e08c2c407b] The getHandleProc routine in the Tcl_Channel struct is optional. Update the docs to make that clear. --- doc/CrtChannel.3 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/CrtChannel.3 b/doc/CrtChannel.3 index 21b5c37..969267d 100644 --- a/doc/CrtChannel.3 +++ b/doc/CrtChannel.3 @@ -343,7 +343,7 @@ typedef struct Tcl_ChannelType { It is not necessary to provide implementations for all channel operations. Those which are not necessary may be set to NULL in the struct: \fIblockModeProc\fR, \fIseekProc\fR, \fIsetOptionProc\fR, -\fIgetOptionProc\fR, and \fIclose2Proc\fR, in addition to +\fIgetOptionProc\fR, \fIgetHandleProc\fR, and \fIclose2Proc\fR, in addition to \fIflushProc\fR, \fIhandlerProc\fR, \fIthreadActionProc\fR, and \fItruncateProc\fR. Other functions that cannot be implemented in a meaningful way should return \fBEINVAL\fR when called, to indicate -- cgit v0.12 From 75e1a827852a9d308b696b39b1f164dca54a70de Mon Sep 17 00:00:00 2001 From: dgp Date: Tue, 24 Feb 2015 15:08:02 +0000 Subject: update changes --- changes | 2 ++ 1 file changed, 2 insertions(+) diff --git a/changes b/changes index 69355a4..960732a 100644 --- a/changes +++ b/changes @@ -7926,4 +7926,6 @@ of Tcl_Channel (porter) 2015-02-05 (bug) Plug stacked channel memleak (porter) +2015-02-11 tzdata updated to Olson's tzdata2015a (venkat) + --- Released 8.5.18, February 28, 2015 --- http://core.tcl.tk/tcl/ for details -- cgit v0.12 From 7e79080ed7bb9d1531c703b34cccad1ccee84dd7 Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 26 Feb 2015 16:57:59 +0000 Subject: Bump to 8.6.4. --- README | 2 +- generic/tcl.h | 4 ++-- library/init.tcl | 2 +- unix/configure.in | 2 +- unix/tcl.spec | 2 +- win/configure.in | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/README b/README index 0fb128d..f63e0e7 100644 --- a/README +++ b/README @@ -1,5 +1,5 @@ README: Tcl - This is the Tcl 8.6.3 source distribution. + This is the Tcl 8.6.4 source distribution. http://sourceforge.net/projects/tcl/files/Tcl/ You can get any source release of Tcl from the URL above. diff --git a/generic/tcl.h b/generic/tcl.h index 95f2b3f..ae425bb 100644 --- a/generic/tcl.h +++ b/generic/tcl.h @@ -56,10 +56,10 @@ extern "C" { #define TCL_MAJOR_VERSION 8 #define TCL_MINOR_VERSION 6 #define TCL_RELEASE_LEVEL TCL_FINAL_RELEASE -#define TCL_RELEASE_SERIAL 3 +#define TCL_RELEASE_SERIAL 4 #define TCL_VERSION "8.6" -#define TCL_PATCH_LEVEL "8.6.3" +#define TCL_PATCH_LEVEL "8.6.4" /* *---------------------------------------------------------------------------- diff --git a/library/init.tcl b/library/init.tcl index f1f7704..05ac4a3 100644 --- a/library/init.tcl +++ b/library/init.tcl @@ -16,7 +16,7 @@ if {[info commands package] == ""} { error "version mismatch: library\nscripts expect Tcl version 7.5b1 or later but the loaded version is\nonly [info patchlevel]" } -package require -exact Tcl 8.6.3 +package require -exact Tcl 8.6.4 # Compute the auto path to use in this interpreter. # The values on the path come from several locations: diff --git a/unix/configure.in b/unix/configure.in index e44d554..c7b0edc 100644 --- a/unix/configure.in +++ b/unix/configure.in @@ -25,7 +25,7 @@ m4_ifdef([SC_USE_CONFIG_HEADERS], [ TCL_VERSION=8.6 TCL_MAJOR_VERSION=8 TCL_MINOR_VERSION=6 -TCL_PATCH_LEVEL=".3" +TCL_PATCH_LEVEL=".4" VERSION=${TCL_VERSION} EXTRA_INSTALL_BINARIES=${EXTRA_INSTALL_BINARIES:-"@:"} diff --git a/unix/tcl.spec b/unix/tcl.spec index 81f31da..1b8693f 100644 --- a/unix/tcl.spec +++ b/unix/tcl.spec @@ -4,7 +4,7 @@ Name: tcl Summary: Tcl scripting language development environment -Version: 8.6.3 +Version: 8.6.4 Release: 2 License: BSD Group: Development/Languages diff --git a/win/configure.in b/win/configure.in index 1bf901a..99d78f2 100644 --- a/win/configure.in +++ b/win/configure.in @@ -14,7 +14,7 @@ SHELL=/bin/sh TCL_VERSION=8.6 TCL_MAJOR_VERSION=8 TCL_MINOR_VERSION=6 -TCL_PATCH_LEVEL=".3" +TCL_PATCH_LEVEL=".4" VER=$TCL_MAJOR_VERSION$TCL_MINOR_VERSION TCL_DDE_VERSION=1.4 -- cgit v0.12 From ec9c80bba98db7bd3069c9ad66e7a5adfcc32e58 Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 26 Feb 2015 16:58:52 +0000 Subject: autoconf-2.59 --- unix/configure | 2 +- win/configure | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/unix/configure b/unix/configure index a9837d9..6f5311c 100755 --- a/unix/configure +++ b/unix/configure @@ -1335,7 +1335,7 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu TCL_VERSION=8.6 TCL_MAJOR_VERSION=8 TCL_MINOR_VERSION=6 -TCL_PATCH_LEVEL=".3" +TCL_PATCH_LEVEL=".4" VERSION=${TCL_VERSION} EXTRA_INSTALL_BINARIES=${EXTRA_INSTALL_BINARIES:-"@:"} diff --git a/win/configure b/win/configure index b270648..bdfa908 100755 --- a/win/configure +++ b/win/configure @@ -1311,7 +1311,7 @@ SHELL=/bin/sh TCL_VERSION=8.6 TCL_MAJOR_VERSION=8 TCL_MINOR_VERSION=6 -TCL_PATCH_LEVEL=".3" +TCL_PATCH_LEVEL=".4" VER=$TCL_MAJOR_VERSION$TCL_MINOR_VERSION TCL_DDE_VERSION=1.4 -- cgit v0.12 From dfc57be3b18b7f7e023eb104bbc321809dc93429 Mon Sep 17 00:00:00 2001 From: ashok Date: Mon, 2 Mar 2015 08:54:14 +0000 Subject: Deleted Win95/98-specific documentation as those platforms have long been unsupported. --- doc/Encoding.3 | 48 ++++++----------------------------------- doc/exec.n | 67 +--------------------------------------------------------- doc/file.n | 8 +++---- doc/glob.n | 8 +------ doc/open.n | 4 ++-- doc/tcltest.n | 8 ------- doc/tclvars.n | 9 ++------ 7 files changed, 16 insertions(+), 136 deletions(-) diff --git a/doc/Encoding.3 b/doc/Encoding.3 index 1478c35..6664b3b 100644 --- a/doc/Encoding.3 +++ b/doc/Encoding.3 @@ -257,47 +257,13 @@ is filled with the corresponding number of bytes that were stored in .PP \fBTcl_WinUtfToTChar\fR and \fBTcl_WinTCharToUtf\fR are Windows-only convenience -functions for converting between UTF-8 and Windows strings. On Windows 95 -(as with the Unix operating system), -all strings exchanged between Tcl and the operating system are -.QW "char" -based. On Windows NT, some strings exchanged between Tcl and the -operating system are -.QW "char" -oriented while others are in Unicode. By -convention, in Windows a TCHAR is a character in the ANSI code page -on Windows 95 and a Unicode character on Windows NT. -.PP -If you planned to use the same -.QW "char" -based interfaces on both Windows -95 and Windows NT, you could use \fBTcl_UtfToExternal\fR and -\fBTcl_ExternalToUtf\fR (or their \fBTcl_DString\fR equivalents) with an -encoding of NULL (the current system encoding). On the other hand, -if you planned to use the Unicode interface when running on Windows NT -and the -.QW "char" -interfaces when running on Windows 95, you would have -to perform the following type of test over and over in your program -(as represented in pseudo-code): -.PP -.CS -if (running NT) { - encoding <- Tcl_GetEncoding("unicode"); - nativeBuffer <- Tcl_UtfToExternal(encoding, utfBuffer); - Tcl_FreeEncoding(encoding); -} else { - nativeBuffer <- Tcl_UtfToExternal(NULL, utfBuffer); -} -.CE -.PP -\fBTcl_WinUtfToTChar\fR and \fBTcl_WinTCharToUtf\fR automatically -handle this test and use the proper encoding based on the current -operating system. \fBTcl_WinUtfToTChar\fR returns a pointer to -a TCHAR string, and \fBTcl_WinTCharToUtf\fR expects a TCHAR string -pointer as the \fIsrc\fR string. Otherwise, these functions -behave identically to \fBTcl_UtfToExternalDString\fR and -\fBTcl_ExternalToUtfDString\fR. +functions for converting between UTF-8 and Windows strings +based on the TCHAR type which is by convention +a Unicode character on Windows NT. +These functions are essentially wrappers around +\fBTcl_UtfToExternalDString\fR and +\fBTcl_ExternalToUtfDString\fR that convert to and from the +Unicode encoding. .PP \fBTcl_GetEncodingName\fR is roughly the inverse of \fBTcl_GetEncoding\fR. Given an \fIencoding\fR, the return value is the \fIname\fR argument that diff --git a/doc/exec.n b/doc/exec.n index c3f316b..5b27e40 100644 --- a/doc/exec.n +++ b/doc/exec.n @@ -269,17 +269,13 @@ present, as is done when launching applications under wish. It is desirable to have console applications hidden and detached. This is a designed-in limitation as \fBexec\fR wants to communicate over pipes. The Expect extension addresses this issue when communicating with a TUI application. -.RE -.TP -\fBWindows NT\fR -. +.PP When attempting to execute an application, \fBexec\fR first searches for the name as it was specified. Then, in order, \fB.com\fR, \fB.exe\fR, and \fB.bat\fR are appended to the end of the specified name and it searches for the longer name. If a directory name was not specified as part of the application name, the following directories are automatically searched in order when attempting to locate the application: -.RS .IP \(bu 3 The directory from which the Tcl executable was loaded. .IP \(bu 3 @@ -299,67 +295,6 @@ the caller must prepend the desired command with because built-in commands are not implemented using executables. .RE .TP -\fBWindows 9x\fR -. -When attempting to execute an application, \fBexec\fR first searches for -the name as it was specified. Then, in order, \fB.com\fR, \fB.exe\fR, and -\fB.bat\fR are appended to the end of the specified name and it searches -for the longer name. If a directory name was not specified as part of the -application name, the following directories are automatically searched in -order when attempting to locate the application: -.RS -.IP \(bu 3 -The directory from which the Tcl executable was loaded. -.IP \(bu 3 -The current directory. -.IP \(bu 3 -The Windows 9x system directory. -.IP \(bu 3 -The Windows 9x home directory. -.IP \(bu 3 -The directories listed in the path. -.RE -.RS -.PP -In order to execute shell built-in commands like \fBdir\fR and \fBcopy\fR, -the caller must prepend the desired command with -.QW "\fBcommand.com /c\0\fR" -because built-in commands are not implemented using executables. -.PP -Once a 16-bit DOS application has read standard input from a console and -then quit, all subsequently run 16-bit DOS applications will see the -standard input as already closed. 32-bit applications do not have this -problem and will run correctly, even after a 16-bit DOS application thinks -that standard input is closed. There is no known workaround for this bug -at this time. -.PP -Redirection between the \fBNUL:\fR device and a 16-bit application does not -always work. When redirecting from \fBNUL:\fR, some applications may hang, -others will get an infinite stream of -.QW 0x01 -bytes, and some will actually -correctly get an immediate end-of-file; the behavior seems to depend upon -something compiled into the application itself. When redirecting greater than -4K or so to \fBNUL:\fR, some applications will hang. The above problems do not -happen with 32-bit applications. -.PP -All DOS 16-bit applications are run synchronously. All standard input from -a pipe to a 16-bit DOS application is collected into a temporary file; the -other end of the pipe must be closed before the 16-bit DOS application -begins executing. All standard output or error from a 16-bit DOS -application to a pipe is collected into temporary files; the application -must terminate before the temporary files are redirected to the next stage -of the pipeline. This is due to a workaround for a Windows 95 bug in the -implementation of pipes, and is how the standard Windows 95 DOS shell -handles pipes itself. -.PP -Certain applications, such as \fBcommand.com\fR, should not be executed -interactively. Applications which directly access the console window, -rather than reading from their standard input and writing to their standard -output may fail, hang Tcl, or even hang the system if their own private -console window is not available to them. -.RE -.TP \fBUnix\fR (including Mac OS X) . The \fBexec\fR command is fully functional and works as described. diff --git a/doc/file.n b/doc/file.n index 5ff45fd..4c6465a 100644 --- a/doc/file.n +++ b/doc/file.n @@ -241,11 +241,9 @@ as relative to the cwd). Furthermore, paths are always expanded to absolute form. When creating links on filesystems that either do not support any links, or do not support the specific type requested, an -error message will be returned. In particular Windows 95, 98 and ME do -not support any links at present, but most Unix platforms support both -symbolic and hard links (the latter for files only) and Windows -NT/2000/XP (on NTFS drives) support symbolic -directory links and hard file links. +error message will be returned. Most Unix platforms support both +symbolic and hard links (the latter for files only). Windows +supports symbolic directory links and hard file links on NTFS drives. .RE .TP \fBfile lstat \fIname varName\fR diff --git a/doc/glob.n b/doc/glob.n index 86e450b..a2cbce2 100644 --- a/doc/glob.n +++ b/doc/glob.n @@ -204,13 +204,7 @@ of the form it refers to the home directory of the user whose account information resides on the specified NT domain server. Otherwise, user account information is obtained from -the local computer. On Windows 95 and 98, \fBglob\fR accepted patterns -like -.QW .../ -and -.QW ..../ -for successively higher up parent directories, but later versions of -Windows do not accept these forms. +the local computer. .PP Since the backslash character has a special meaning to the glob command, glob patterns containing Windows style path separators need diff --git a/doc/open.n b/doc/open.n index 7fccdf1..3012460 100644 --- a/doc/open.n +++ b/doc/open.n @@ -370,9 +370,8 @@ works for serial ports from 1 to 9. An attempt to open a serial port that does not exist or has a number greater than 9 will fail. An alternate form of opening serial ports is to use the filename \fB//./comX\fR, where X is any number that corresponds to a serial port. -.RS .PP -. +.RS When running Tcl interactively, there may be some strange interactions between the real console, if one is present, and a command pipeline that uses standard input or output. If a command pipeline is opened for reading, some @@ -384,6 +383,7 @@ application are competing for the console at the same time. If the command pipeline is started from a script, so that Tcl is not accessing the console, or if the command pipeline does not use standard input or output, but is redirected from or to a file, then the above problems do not occur. +.RE .TP \fBUnix\fR\0\0\0\0\0\0\0 . diff --git a/doc/tcltest.n b/doc/tcltest.n index 8d2398b..29265be 100644 --- a/doc/tcltest.n +++ b/doc/tcltest.n @@ -642,14 +642,6 @@ This test can only be run on any Windows platform. . This test can only be run on any Windows NT platform. .TP -\fI95\fR -. -This test can only be run on any Windows 95 platform. -.TP -\fI98\fR -. -This test can only be run on any Windows 98 platform. -.TP \fImac\fR . This test can only be run on any Mac platform. diff --git a/doc/tclvars.n b/doc/tclvars.n index 48ab83a..a8fba47 100644 --- a/doc/tclvars.n +++ b/doc/tclvars.n @@ -308,18 +308,13 @@ is the value returned by \fBuname -m\fR. \fBos\fR . The name of the operating system running on this machine, -such as \fBWindows 95\fR, \fBWindows NT\fR, or \fBSunOS\fR. +such as \fBWindows NT\fR or \fBSunOS\fR. On UNIX machines, this is the value returned by \fBuname -s\fR. -On Windows 95 and Windows 98, the value returned will be \fBWindows -95\fR to provide better backwards compatibility to Windows 95; to -distinguish between the two, check the \fBosVersion\fR. .TP \fBosVersion\fR . The version number for the operating system running on this machine. -On UNIX machines, this is the value returned by \fBuname -r\fR. On -Windows 95, the version will be 4.0; on Windows 98, the version will -be 4.10. +On UNIX machines, this is the value returned by \fBuname -r\fR. .TP \fBpathSeparator\fR .VS 8.6 -- cgit v0.12 From 4a22756b41bef17492d6e93ba24261ccf45bf36c Mon Sep 17 00:00:00 2001 From: dgp Date: Tue, 3 Mar 2015 21:29:08 +0000 Subject: update changes --- changes | 16 ++++++++++++++++ tests/lreplace.test | 2 +- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/changes b/changes index d92c340..fc11542 100644 --- a/changes +++ b/changes @@ -8498,13 +8498,29 @@ include ::oo::class (fellows) 2014-12-03 (bug)[0c043a] Fix compiled [set var($) val] (porter) +2014-12-04 (bug)[d2ffcc] Limit $... and bareword parsing to ASCII (ladayaroslav,porter) + *** POTENTIAL INCOMPATIBILITY *** + +2014-12-06 (bug)[c6cd4a] Win: hang in async socket connection (shults,nadkarni) + +2014-12-10 tzdata updated to Olson's tzdata2014j (venkat) + +2014-12-13 fix header files installation on OS X (houben) 2014-12-17 (TIP 427) [fconfigure $h -connecting, -peername, -sockname] (oehlmann,rmax) +2014-12-18 (bug)[af08c8] Crash in full finalize encoding teardown (porter) + +2014-12-18 (bug)[7c187a] [chan copy] crash (io-53.17) (benno,porter) +2015-01-26 (bug)[df0848] Trouble with INFINITY macro (dower,nijtmans) +2015-01-29 (bug) Stop crashes when extension var resolvers misbehave (porter) +2015-01-29 (bug)[088727] [read] past EOF (io-73.4) (fenugrec,porter) +2015-02-11 tzdata updated to Olson's tzdata2015a (venkat) +2015-02-20 (bug)[32b615] Fix compiled [lreplace] (lreplace-4.[345]) (aspect) --- Released 8.6.4, March 12, 2015 --- http://core.tcl.tk/tcl/ for details diff --git a/tests/lreplace.test b/tests/lreplace.test index d5c51ae..d1319c6 100644 --- a/tests/lreplace.test +++ b/tests/lreplace.test @@ -143,7 +143,7 @@ test lreplace-4.3 {lreplace edge case} { test lreplace-4.4 {lreplace edge case} { lreplace {1 2 3 4 5} 3 1 } {1 2 3 4 5} -test lreplace-4.4 {lreplace edge case} { +test lreplace-4.5 {lreplace edge case} { lreplace {1 2 3 4 5} 3 0 _ } {1 2 3 _ 4 5} -- cgit v0.12 From 07bc28e627a938cbb74b2c7d3043300a73594747 Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 6 Mar 2015 14:17:48 +0000 Subject: update release date --- changes | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changes b/changes index 960732a..22242cb 100644 --- a/changes +++ b/changes @@ -7928,4 +7928,4 @@ of Tcl_Channel (porter) 2015-02-11 tzdata updated to Olson's tzdata2015a (venkat) ---- Released 8.5.18, February 28, 2015 --- http://core.tcl.tk/tcl/ for details +--- Released 8.5.18, March 6, 2015 --- http://core.tcl.tk/tcl/ for details -- cgit v0.12 From f14d6cb130c0864c353116cf10296f6e8ab7206c Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 6 Mar 2015 14:38:38 +0000 Subject: products of "make dist" --- unix/tclConfig.h.in | 26 ++++++-------------------- 1 file changed, 6 insertions(+), 20 deletions(-) diff --git a/unix/tclConfig.h.in b/unix/tclConfig.h.in index 710949f..9774ce9 100644 --- a/unix/tclConfig.h.in +++ b/unix/tclConfig.h.in @@ -4,9 +4,6 @@ #ifndef _TCLCONFIG #define _TCLCONFIG -/* Define if building universal (internal helper macro) */ -#undef AC_APPLE_UNIVERSAL_BUILD - /* Is pthread_attr_get_np() declared in ? */ #undef ATTRGETNP_NOT_DECLARED @@ -199,10 +196,10 @@ /* Is 'struct stat64' in ? */ #undef HAVE_STRUCT_STAT64 -/* Define to 1 if `st_blksize' is a member of `struct stat'. */ +/* Define to 1 if `st_blksize' is member of `struct stat'. */ #undef HAVE_STRUCT_STAT_ST_BLKSIZE -/* Define to 1 if `st_blocks' is a member of `struct stat'. */ +/* Define to 1 if `st_blocks' is member of `struct stat'. */ #undef HAVE_STRUCT_STAT_ST_BLOCKS /* Define to 1 if you have the header file. */ @@ -337,9 +334,6 @@ /* Define to the one symbol short name of this package. */ #undef PACKAGE_TARNAME -/* Define to the home page for this package. */ -#undef PACKAGE_URL - /* Define to the version of this package. */ #undef PACKAGE_VERSION @@ -433,17 +427,9 @@ /* Should we use vfork() instead of fork()? */ #undef USE_VFORK -/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most - significant byte first (like Motorola and SPARC, unlike Intel). */ -#if defined AC_APPLE_UNIVERSAL_BUILD -# if defined __BIG_ENDIAN__ -# define WORDS_BIGENDIAN 1 -# endif -#else -# ifndef WORDS_BIGENDIAN -# undef WORDS_BIGENDIAN -# endif -#endif +/* Define to 1 if your processor stores words with the most significant byte + first (like Motorola and SPARC, unlike Intel and VAX). */ +#undef WORDS_BIGENDIAN /* Are Darwin SUSv3 extensions available? */ #undef _DARWIN_C_SOURCE @@ -498,7 +484,7 @@ /* Define to `int' if does not define. */ #undef pid_t -/* Define to `unsigned int' if does not define. */ +/* Define to `unsigned' if does not define. */ #undef size_t /* Define as int if socklen_t is not available */ -- cgit v0.12 From 97739f4d0991c924d42fdd9f57567e7ebe4686ce Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 6 Mar 2015 14:59:11 +0000 Subject: repair nroff breakage --- doc/open.n | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/open.n b/doc/open.n index 7216607..a9da946 100644 --- a/doc/open.n +++ b/doc/open.n @@ -352,6 +352,7 @@ application are competing for the console at the same time. If the command pipeline is started from a script, so that Tcl is not accessing the console, or if the command pipeline does not use standard input or output, but is redirected from or to a file, then the above problems do not occur. +.RE .TP \fBUnix\fR\0\0\0\0\0\0\0 Valid values for \fIfileName\fR to open a serial port are generally of the -- cgit v0.12 From 761a093174bac2446c636f737cf4275c99af5922 Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 6 Mar 2015 15:06:02 +0000 Subject: repair nroff breakage --- doc/open.n | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/open.n b/doc/open.n index 7216607..a9da946 100644 --- a/doc/open.n +++ b/doc/open.n @@ -352,6 +352,7 @@ application are competing for the console at the same time. If the command pipeline is started from a script, so that Tcl is not accessing the console, or if the command pipeline does not use standard input or output, but is redirected from or to a file, then the above problems do not occur. +.RE .TP \fBUnix\fR\0\0\0\0\0\0\0 Valid values for \fIfileName\fR to open a serial port are generally of the -- cgit v0.12 From f396811dd5ddd0df8a3b1a6f211caa4da185c6c4 Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 6 Mar 2015 19:43:42 +0000 Subject: product of a make dist --- unix/tclConfig.h.in | 26 ++++++-------------------- 1 file changed, 6 insertions(+), 20 deletions(-) diff --git a/unix/tclConfig.h.in b/unix/tclConfig.h.in index e55dcd0..10ae12f 100644 --- a/unix/tclConfig.h.in +++ b/unix/tclConfig.h.in @@ -4,9 +4,6 @@ #ifndef _TCLCONFIG #define _TCLCONFIG -/* Define if building universal (internal helper macro) */ -#undef AC_APPLE_UNIVERSAL_BUILD - /* Is gettimeofday() actually declared in ? */ #undef GETTOD_NOT_DECLARED @@ -214,10 +211,10 @@ /* Is 'struct stat64' in ? */ #undef HAVE_STRUCT_STAT64 -/* Define to 1 if `st_blksize' is a member of `struct stat'. */ +/* Define to 1 if `st_blksize' is member of `struct stat'. */ #undef HAVE_STRUCT_STAT_ST_BLKSIZE -/* Define to 1 if `st_blocks' is a member of `struct stat'. */ +/* Define to 1 if `st_blocks' is member of `struct stat'. */ #undef HAVE_STRUCT_STAT_ST_BLOCKS /* Define to 1 if you have the header file. */ @@ -361,9 +358,6 @@ /* Define to the one symbol short name of this package. */ #undef PACKAGE_TARNAME -/* Define to the home page for this package. */ -#undef PACKAGE_URL - /* Define to the version of this package. */ #undef PACKAGE_VERSION @@ -442,17 +436,9 @@ /* Should we use vfork() instead of fork()? */ #undef USE_VFORK -/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most - significant byte first (like Motorola and SPARC, unlike Intel). */ -#if defined AC_APPLE_UNIVERSAL_BUILD -# if defined __BIG_ENDIAN__ -# define WORDS_BIGENDIAN 1 -# endif -#else -# ifndef WORDS_BIGENDIAN -# undef WORDS_BIGENDIAN -# endif -#endif +/* Define to 1 if your processor stores words with the most significant byte + first (like Motorola and SPARC, unlike Intel and VAX). */ +#undef WORDS_BIGENDIAN /* Are Darwin SUSv3 extensions available? */ #undef _DARWIN_C_SOURCE @@ -507,7 +493,7 @@ /* Define to `int' if does not define. */ #undef pid_t -/* Define to `unsigned int' if does not define. */ +/* Define to `unsigned' if does not define. */ #undef size_t /* Define as int if socklen_t is not available */ -- cgit v0.12 From 4f07b1824423cc3d59b4e9475474c4833ccbfb6b Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 6 Mar 2015 19:48:31 +0000 Subject: `make html` must tolerate bundled packages using configure.ac over configure.in. --- tools/tcltk-man2html.tcl | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tools/tcltk-man2html.tcl b/tools/tcltk-man2html.tcl index 89e8e5c..1ceceb9 100755 --- a/tools/tcltk-man2html.tcl +++ b/tools/tcltk-man2html.tcl @@ -667,7 +667,11 @@ try { # ... but try to extract (name, version) from subdir contents try { - set f [open [file join $pkgsDir $dir configure.in]] + try { + set f [open [file join $pkgsDir $dir configure.in]] + } trap {POSIX ENOENT} {} { + set f [open [file join $pkgsDir $dir configure.ac]] + } foreach line [split [read $f] \n] { if {2 == [scan $line \ { AC_INIT ( [%[^]]] , [%[^]]] ) } n v]} { -- cgit v0.12 From 8c7378b541bedd8db42bd51c39e93de342833280 Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 6 Mar 2015 19:55:38 +0000 Subject: .RS/.RE balance --- doc/socket.n | 1 - 1 file changed, 1 deletion(-) diff --git a/doc/socket.n b/doc/socket.n index 492ca66..275771d 100644 --- a/doc/socket.n +++ b/doc/socket.n @@ -190,7 +190,6 @@ sockets, this option returns a list of three elements; these are the address, the host name and the port to which the peer socket is connected or bound. If the host name cannot be computed, the second element of the list is identical to the address, its first element. -.RE .TP \fB\-connecting\fR . -- cgit v0.12 From 544df0c1b80d0d889677b4b9e3aab4eb6b511779 Mon Sep 17 00:00:00 2001 From: Kevin Walzer Date: Tue, 10 Mar 2015 14:41:03 +0000 Subject: Fix or at least improvement for Tcl/Tk Cocoa event loop by forcing Tcl_ServiceAll() event processing: http://core.tcl.tk/tk/tktview/3028676fffffffffffffffffffffffffffffffff --- macosx/tclMacOSXNotify.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/macosx/tclMacOSXNotify.c b/macosx/tclMacOSXNotify.c index ef80192..9b7bd1a 100644 --- a/macosx/tclMacOSXNotify.c +++ b/macosx/tclMacOSXNotify.c @@ -1412,7 +1412,8 @@ UpdateWaitingListAndServiceEvents( (tsdPtr->runLoopNestingLevel > 1 || !tsdPtr->runLoopRunning)) { tsdPtr->runLoopServicingEvents = 1; - while (Tcl_ServiceAll() && tsdPtr->waitTime == 0) {} + /* This call seems to simply force event processing through and prevents hangups that have long been observed with Tk-Cocoa. */ + Tcl_ServiceAll(); tsdPtr->runLoopServicingEvents = 0; } break; -- cgit v0.12 From 2c4d707b8f438379df1a35a200e8ec3780b3ba7e Mon Sep 17 00:00:00 2001 From: Kevin Walzer Date: Tue, 10 Mar 2015 14:44:47 +0000 Subject: Fix or at least improvement for Tcl/Tk Cocoa event loop by forcing Tcl_ServiceAll() event processing: http://core.tcl.tk/tk/tktview/3028676fffffffffffffffffffffffffffffffff --- macosx/tclMacOSXNotify.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/macosx/tclMacOSXNotify.c b/macosx/tclMacOSXNotify.c index fb3c848..2252ec1 100644 --- a/macosx/tclMacOSXNotify.c +++ b/macosx/tclMacOSXNotify.c @@ -1377,7 +1377,8 @@ UpdateWaitingListAndServiceEvents( if (tsdPtr->runLoopTimer && !tsdPtr->runLoopServicingEvents && (tsdPtr->runLoopNestingLevel > 1 || !tsdPtr->runLoopRunning)) { tsdPtr->runLoopServicingEvents = 1; - while (Tcl_ServiceAll() && tsdPtr->waitTime == 0) {} + /* This call seems to simply force event processing through and prevents hangups that have long been observed with Tk-Cocoa. */ + Tcl_ServiceAll(); tsdPtr->runLoopServicingEvents = 0; } break; -- cgit v0.12 From 74708147baa286b9ee3e7d6c5796b082f3758a1e Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 11 Mar 2015 12:30:39 +0000 Subject: update changes --- changes | 3 +++ 1 file changed, 3 insertions(+) diff --git a/changes b/changes index fc11542..8dffa37 100644 --- a/changes +++ b/changes @@ -8523,4 +8523,7 @@ include ::oo::class (fellows) 2015-02-20 (bug)[32b615] Fix compiled [lreplace] (lreplace-4.[345]) (aspect) +2015-03-10 (enhancement) Revise OS X notifier for better Cocoa (walzer) + *** POTENTIAL INCOMPATIBILITY *** + --- Released 8.6.4, March 12, 2015 --- http://core.tcl.tk/tcl/ for details -- cgit v0.12 From b2c41c81e4080d7e8636328c58f27ed15b70c29b Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 13 Mar 2015 16:55:39 +0000 Subject: The STRICT directive influences how #include "windows.h" works. This is not a generic concern. Move it over the tclWinPort.h. --- generic/tcl.h | 10 ---------- win/tclWinPort.h | 2 ++ 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/generic/tcl.h b/generic/tcl.h index ae425bb..f09315b 100644 --- a/generic/tcl.h +++ b/generic/tcl.h @@ -77,16 +77,6 @@ extern "C" { #endif /* - * STRICT: See MSDN Article Q83456 - */ - -#ifdef _WIN32 -# ifndef STRICT -# define STRICT -# endif -#endif /* _WIN32 */ - -/* * Utility macros: STRINGIFY takes an argument and wraps it in "" (double * quotation marks), JOIN joins two arguments. */ diff --git a/win/tclWinPort.h b/win/tclWinPort.h index ca6b2bf..1b23ee3 100644 --- a/win/tclWinPort.h +++ b/win/tclWinPort.h @@ -33,7 +33,9 @@ #endif #define WIN32_LEAN_AND_MEAN +#define STRICT /* See MSDN Article Q83456 */ #include +#undef STRICT #undef WIN32_LEAN_AND_MEAN /* Compatibility to older visual studio / windows platform SDK */ -- cgit v0.12 From f399206c210a987dad1e8f87fe889eeb1ffe00f2 Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 13 Mar 2015 17:14:16 +0000 Subject: Upon further review, due the order of #include of headers, we do not have a history of a #define STRICT active when the #include "windows.h" in tclWinPort.h happens. Don't want to start something new now. --- win/tclAppInit.c | 2 ++ win/tclWinPort.h | 2 -- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/win/tclAppInit.c b/win/tclAppInit.c index a6c1a67..e06eaf5 100644 --- a/win/tclAppInit.c +++ b/win/tclAppInit.c @@ -16,7 +16,9 @@ #include "tcl.h" #define WIN32_LEAN_AND_MEAN +#define STRICT /* See MSDN Article Q83456 */ #include +#undef STRICT #undef WIN32_LEAN_AND_MEAN #include #include diff --git a/win/tclWinPort.h b/win/tclWinPort.h index 1b23ee3..ca6b2bf 100644 --- a/win/tclWinPort.h +++ b/win/tclWinPort.h @@ -33,9 +33,7 @@ #endif #define WIN32_LEAN_AND_MEAN -#define STRICT /* See MSDN Article Q83456 */ #include -#undef STRICT #undef WIN32_LEAN_AND_MEAN /* Compatibility to older visual studio / windows platform SDK */ -- cgit v0.12 From 50426ba9c5cb0fa954959ab5b810695b6bf20111 Mon Sep 17 00:00:00 2001 From: ashok Date: Thu, 19 Mar 2015 10:41:28 +0000 Subject: Ticket [e66e444440]. Modified ReadConsoleBytes to handle Ctrl-C / Ctrl-Break and not return 0 bytes indicating EOF for those cases. --- win/tclWinConsole.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/win/tclWinConsole.c b/win/tclWinConsole.c index 63150ef..7380003 100644 --- a/win/tclWinConsole.c +++ b/win/tclWinConsole.c @@ -220,8 +220,20 @@ ReadConsoleBytes( BOOL result; int tcharsize = sizeof(TCHAR); - result = ReadConsole(hConsole, lpBuffer, nbytes / tcharsize, &ntchars, - NULL); + /* + * If user types a Ctrl-Break or Ctrl-C, ReadConsole will return + * success with ntchars == 0 and GetLastError() will be + * ERROR_OPERATION_ABORTED. We do not want to treat this case + * as EOF so we will loop around again. If no Ctrl signal handlers + * have been established, the default signal OS handler in a separate + * thread will terminate the program. If a Ctrl signal handler + * has been established (through an extension for example), it + * will run and take whatever action it deems appropriate. + */ + do { + result = ReadConsole(hConsole, lpBuffer, nbytes / tcharsize, &ntchars, + NULL); + } while (result && ntchars == 0 && GetLastError() == ERROR_OPERATION_ABORTED); if (nbytesread != NULL) { *nbytesread = ntchars * tcharsize; } -- cgit v0.12 From 1292a0d927e1e406c26efa91c7f8b36087b2b767 Mon Sep 17 00:00:00 2001 From: dgp Date: Sat, 21 Mar 2015 00:31:29 +0000 Subject: [d87cb18205] Let compiled ensembles handle tailcalls properly. --- generic/tclExecute.c | 1 - tests/nre.test | 21 +++++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/generic/tclExecute.c b/generic/tclExecute.c index b9da8fc..322bd20 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -3186,7 +3186,6 @@ TEBCresume( TEBC_YIELD(); TclNRAddCallback(interp, TclClearRootEnsemble, NULL,NULL,NULL,NULL); - TclSkipTailcall(interp); return TclNREvalObjEx(interp, objPtr, TCL_EVAL_INVOKE, NULL, INT_MIN); /* diff --git a/tests/nre.test b/tests/nre.test index b5eb032..e512eac 100644 --- a/tests/nre.test +++ b/tests/nre.test @@ -151,6 +151,27 @@ test nre-4.1 {ensembles are not recursive} -setup { testnrelevels } -result {{0 2 1 1} 0} +test nre-4.2 {(compiled) ensembles do not break tailcall} -setup { + # Fix Bug d87cb18205 + proc b {} { + tailcall append result first + } + set map [namespace ensemble configure ::dict -map] + dict set map a b + namespace ensemble configure ::dict -map $map + proc demo {} { + dict a + append result second + } +} -body { + demo +} -cleanup { + rename demo {} + namespace ensemble configure ::dict -map [dict remove $map a] + unset map + rename b {} +} -result firstsecond + test nre-5.1 {[namespace eval] is not recursive} -setup { namespace eval ::foo { setabs -- cgit v0.12 From 7dbf5ed0b0e60ff40474e45e7b0eb498d4eed3b9 Mon Sep 17 00:00:00 2001 From: Miguel Sofer Date: Sat, 21 Mar 2015 15:08:35 +0000 Subject: adding a test to reveal a problem with the fix of bug d87cb182053fd79b3 --- tests/tailcall.test | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/tests/tailcall.test b/tests/tailcall.test index 2d04f82..26f3cbf 100644 --- a/tests/tailcall.test +++ b/tests/tailcall.test @@ -147,6 +147,36 @@ test tailcall-0.5 {tailcall is constant space} -constraints testnrelevels -setup rename b {} } -result {0 0 0 0 0 0} +test tailcall-0.5.1 {tailcall is constant space} -constraints testnrelevels -setup { + # + # This test is related to [bug d87cb182053fd79b3]: the fix to that bug was + # to remove a call to TclSkipTailcall, which caused a violation of the + # constant-space property of tailcall in that particular + # configuration. This test was added to detect that, and insure that the + # problem is fixed. + # + + proc b i { + if {$i == 1} { + depthDiff + } + if {[incr i] > 10} { + return [depthDiff] + } + tailcall dict b $i + } + set map0 [namespace ensemble configure dict -map] + set map $map0 + dict set map b b + namespace ensemble configure dict -map $map +} -body { + dict b 0 +} -cleanup { + rename b {} + namespace ensemble configure dict -map $map0 + unset map map0 +} -result {0 0 0 0 0 0} + test tailcall-0.6 {tailcall is constant space} -constraints {testnrelevels knownBug} -setup { # # This test fails because ns-unknown is not NR-enabled -- cgit v0.12 From 2cc11d4918127e3ad2d7af5100ddf40c62cdb7f9 Mon Sep 17 00:00:00 2001 From: Miguel Sofer Date: Mon, 23 Mar 2015 00:33:07 +0000 Subject: completing the fix for bug d87cb182053fd79b3 --- generic/tclExecute.c | 1 + 1 file changed, 1 insertion(+) diff --git a/generic/tclExecute.c b/generic/tclExecute.c index 322bd20..4790ba3 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -3185,6 +3185,7 @@ TEBCresume( pc += 6; TEBC_YIELD(); + TclMarkTailcall(interp); TclNRAddCallback(interp, TclClearRootEnsemble, NULL,NULL,NULL,NULL); return TclNREvalObjEx(interp, objPtr, TCL_EVAL_INVOKE, NULL, INT_MIN); -- cgit v0.12 -- cgit v0.12 From d4166a6b3a790e67fedc6e636715146d4526972a Mon Sep 17 00:00:00 2001 From: Miguel Sofer Date: Mon, 23 Mar 2015 02:11:30 +0000 Subject: updated, improved tailcall comments --- generic/tclBasic.c | 45 +++++++++++++++++++++------------------------ 1 file changed, 21 insertions(+), 24 deletions(-) diff --git a/generic/tclBasic.c b/generic/tclBasic.c index 361ed49..e92e8e9 100644 --- a/generic/tclBasic.c +++ b/generic/tclBasic.c @@ -4142,8 +4142,9 @@ TclNREvalObjv( /* * data[1] stores a marker for use by tailcalls; it will be set to 1 by - * command redirectors (imports, alias, ensembles) so that tailcalls - * finishes the source command and not just the target. + * command redirectors (imports, alias, ensembles) so that tailcall skips + * this callback (that marks the end of the target command) and goes back + * to the end of the source command. */ if (iPtr->deferredCallbacks) { @@ -4406,7 +4407,7 @@ NRCommand( iPtr->numLevels--; /* - * If there is a tailcall, schedule it + * If there is a tailcall, schedule it next */ if (data[1] && (data[1] != INT2PTR(1))) { @@ -8170,27 +8171,24 @@ Tcl_NRCmdSwap( } /***************************************************************************** - * Stuff for tailcalls + * Tailcall related code ***************************************************************************** * - * Just to show that IT CAN BE DONE! The precise semantics are not simple, - * require more thought. Possibly need a new Tcl return code to do it right? - * Questions include: - * (1) How is the objc/objv tailcall to be run? My current thinking is that - * it should essentially be - * [tailcall a b c] <=> [uplevel 1 [list a b c]] - * with two caveats - * (a) the current frame is dropped first, after running all pending - * cleanup tasks and saving its namespace - * (b) 'a' is looked up in the returning frame's namespace, but the - * command is run in the context to which we are returning - * Current implementation does this if [tailcall] is called from within - * a proc, errors otherwise. - * (2) Should a tailcall bypass [catch] in the returning frame? Current - * implementation does not (or does it? Changed, test!) - it causes an - * error. - * - * FIXME NRE! + * The steps of the tailcall dance are as follows: + * + * 1. when [tailcall] is invoked, it stores the corresponding callback in + * the current CallFrame and returns TCL_RETURN + * 2. when the CallFrame is popped, it calls TclSetTailcall to store the + * callback in the proper NRCommand callback - the spot where the command + * that pushed the CallFrame is completely cleaned up + * 3. The NRCommand schedules the tailcall callback to run immediately after + * NRCommand returns + * + * One delicate point is to properly define the NRCommand where the tailcall + * will execute. There are functions whose purpose is to help define the + * precise spot: TclMarkTailcall ("this is the spot") and TclSkipTailcall + * ("skip the next command: we are redirecting to it, tailcalls should run + * after WE return"), TclPushTailcallPoint (special for OO). */ void @@ -8282,8 +8280,7 @@ TclNRTailcallObjCmd( /* * Create the callback to actually evaluate the tailcalled * command, then set it in the varFrame so that PopCallFrame can use it - * at the proper time. Being lazy: exploit the TclNRAddCallBack macro to - * build the callback. + * at the proper time. */ if (objc > 1) { -- cgit v0.12 From ee626d59092153c963025c23f39e9c1fdb49ac77 Mon Sep 17 00:00:00 2001 From: Miguel Sofer Date: Mon, 23 Mar 2015 13:43:37 +0000 Subject: more comments --- generic/tclBasic.c | 44 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 42 insertions(+), 2 deletions(-) diff --git a/generic/tclBasic.c b/generic/tclBasic.c index e92e8e9..16e7a5d 100644 --- a/generic/tclBasic.c +++ b/generic/tclBasic.c @@ -8181,8 +8181,8 @@ Tcl_NRCmdSwap( * 2. when the CallFrame is popped, it calls TclSetTailcall to store the * callback in the proper NRCommand callback - the spot where the command * that pushed the CallFrame is completely cleaned up - * 3. The NRCommand schedules the tailcall callback to run immediately after - * NRCommand returns + * 3. when the NRCommand callback runs, it schedules the tailcall callback + * to run immediately after it returns * * One delicate point is to properly define the NRCommand where the tailcall * will execute. There are functions whose purpose is to help define the @@ -8222,6 +8222,18 @@ TclPushTailcallPoint( ((Interp *) interp)->numLevels++; } + +/* + *---------------------------------------------------------------------- + * + * TclSetTailcall -- + * + * Splice a tailcall command in the proper spot of the NRE callback + * stack, so that it runs at the right time. + * + *---------------------------------------------------------------------- + */ + void TclSetTailcall( Tcl_Interp *interp, @@ -8246,6 +8258,23 @@ TclSetTailcall( runPtr->data[1] = listPtr; } + +/* + *---------------------------------------------------------------------- + * + * TclNRTailcallObjCmd -- + * + * Prepare the tailcall as a list and store it in the current + * varFrame. When the frame is later popped the tailcall will be spliced + * at the proper place. + * + * Results: + * The first NRCommand callback that is not marked to be skipped is + * updated so that its data[1] field contains the tailcall list. + * + *---------------------------------------------------------------------- + */ + int TclNRTailcallObjCmd( ClientData clientData, @@ -8305,6 +8334,17 @@ TclNRTailcallObjCmd( return TCL_RETURN; } + +/* + *---------------------------------------------------------------------- + * + * TclNRTailcallEval -- + * + * This NREcallback actually causes the tailcall to be evaluated. + * + *---------------------------------------------------------------------- + */ + int TclNRTailcallEval( ClientData data[], -- cgit v0.12 From 63e0947392fd8ac318ca20cd083dfc8d9eb85199 Mon Sep 17 00:00:00 2001 From: Miguel Sofer Date: Mon, 23 Mar 2015 16:05:04 +0000 Subject: fix comments describing tailcall implementation --- generic/tclBasic.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/generic/tclBasic.c b/generic/tclBasic.c index 16e7a5d..f6f66ed 100644 --- a/generic/tclBasic.c +++ b/generic/tclBasic.c @@ -8289,9 +8289,9 @@ TclNRTailcallObjCmd( return TCL_ERROR; } - if (!(iPtr->varFramePtr->isProcCallFrame & 1)) { /* or is upleveled */ + if (!(iPtr->varFramePtr->isProcCallFrame & 1)) { Tcl_SetObjResult(interp, Tcl_NewStringObj( - "tailcall can only be called from a proc or lambda", -1)); + "tailcall can only be called from a proc, lambda or method", -1)); Tcl_SetErrorCode(interp, "TCL", "TAILCALL", "ILLEGAL", NULL); return TCL_ERROR; } -- cgit v0.12 From cd70770139e4e257dca9e5575f3cfb4b15512594 Mon Sep 17 00:00:00 2001 From: dgp Date: Tue, 24 Mar 2015 17:34:05 +0000 Subject: Tcl source code already assumes the file is available. (See tcl/libtommath/tommath.h .) So dispose of all the configuration shenanigans pretending we want to support systems that lack one. --- compat/limits.h | 22 -------- generic/tcl.h | 16 +++--- unix/configure | 152 ---------------------------------------------------- unix/tcl.m4 | 4 -- unix/tclConfig.h.in | 6 --- unix/tclUnixPort.h | 6 +-- 6 files changed, 7 insertions(+), 199 deletions(-) delete mode 100644 compat/limits.h diff --git a/compat/limits.h b/compat/limits.h deleted file mode 100644 index 2cb082b..0000000 --- a/compat/limits.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * limits.h -- - * - * This is a dummy header file to #include in Tcl when there - * is no limits.h in /usr/include. There are only a few - * definitions here; also see tclPort.h, which already - * #defines some of the things here if they're not arleady - * defined. - * - * Copyright (c) 1991 The Regents of the University of California. - * Copyright (c) 1994 Sun Microsystems, Inc. - * - * See the file "license.terms" for information on usage and redistribution - * of this file, and for a DISCLAIMER OF ALL WARRANTIES. - */ - -#define LONG_MIN 0x80000000 -#define LONG_MAX 0x7fffffff -#define INT_MIN 0x80000000 -#define INT_MAX 0x7fffffff -#define SHRT_MIN 0x8000 -#define SHRT_MAX 0x7fff diff --git a/generic/tcl.h b/generic/tcl.h index f09315b..5eff4d6 100644 --- a/generic/tcl.h +++ b/generic/tcl.h @@ -392,16 +392,12 @@ typedef long LONG; * Don't know what platform it is and configure hasn't discovered what is * going on for us. Try to guess... */ -# ifdef NO_LIMITS_H -# error please define either TCL_WIDE_INT_TYPE or TCL_WIDE_INT_IS_LONG -# else /* !NO_LIMITS_H */ -# include -# if (INT_MAX < LONG_MAX) -# define TCL_WIDE_INT_IS_LONG 1 -# else -# define TCL_WIDE_INT_TYPE long long -# endif -# endif /* NO_LIMITS_H */ +# include +# if (INT_MAX < LONG_MAX) +# define TCL_WIDE_INT_IS_LONG 1 +# else +# define TCL_WIDE_INT_TYPE long long +# endif # endif /* _WIN32 */ #endif /* !TCL_WIDE_INT_TYPE & !TCL_WIDE_INT_IS_LONG */ #ifdef TCL_WIDE_INT_IS_LONG diff --git a/unix/configure b/unix/configure index 6f5311c..cb46f8d 100755 --- a/unix/configure +++ b/unix/configure @@ -3332,158 +3332,6 @@ _ACEOF fi - 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 -/* 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 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 -_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: 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 - 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 -#define HAVE_LIMITS_H 1 -_ACEOF - -else - -cat >>confdefs.h <<\_ACEOF -#define NO_LIMITS_H 1 -_ACEOF - -fi - - 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 diff --git a/unix/tcl.m4 b/unix/tcl.m4 index 277fe0b..25c2699 100644 --- a/unix/tcl.m4 +++ b/unix/tcl.m4 @@ -2158,7 +2158,6 @@ dnl # preprocessing tests use only CPPFLAGS. # Defines some of the following vars: # NO_DIRENT_H # NO_VALUES_H -# HAVE_LIMITS_H or NO_LIMITS_H # NO_STDLIB_H # NO_STRING_H # NO_SYS_WAIT_H @@ -2198,9 +2197,6 @@ closedir(d); AC_CHECK_HEADER(float.h, , [AC_DEFINE(NO_FLOAT_H, 1, [Do we have ?])]) AC_CHECK_HEADER(values.h, , [AC_DEFINE(NO_VALUES_H, 1, [Do we have ?])]) - AC_CHECK_HEADER(limits.h, - [AC_DEFINE(HAVE_LIMITS_H, 1, [Do we have ?])], - [AC_DEFINE(NO_LIMITS_H, 1, [Do we have ?])]) AC_CHECK_HEADER(stdlib.h, tcl_ok=1, tcl_ok=0) AC_EGREP_HEADER(strtol, stdlib.h, , tcl_ok=0) AC_EGREP_HEADER(strtoul, stdlib.h, , tcl_ok=0) diff --git a/unix/tclConfig.h.in b/unix/tclConfig.h.in index 10ae12f..a4ab3e5 100644 --- a/unix/tclConfig.h.in +++ b/unix/tclConfig.h.in @@ -127,9 +127,6 @@ /* Define to 1 if you have the header file. */ #undef HAVE_LIBKERN_OSATOMIC_H -/* Do we have ? */ -#undef HAVE_LIMITS_H - /* Define to 1 if you have the `localtime_r' function. */ #undef HAVE_LOCALTIME_R @@ -313,9 +310,6 @@ /* Do we have a usable 'isnan'? */ #undef NO_ISNAN -/* Do we have ? */ -#undef NO_LIMITS_H - /* Do we have memmove()? */ #undef NO_MEMMOVE diff --git a/unix/tclUnixPort.h b/unix/tclUnixPort.h index f64d453..a9983be 100644 --- a/unix/tclUnixPort.h +++ b/unix/tclUnixPort.h @@ -144,11 +144,7 @@ typedef off_t Tcl_SeekOffset; #if HAVE_INTTYPES_H # include #endif -#ifdef NO_LIMITS_H -# include "../compat/limits.h" -#else -# include -#endif +#include #if HAVE_STDINT_H # include #endif -- cgit v0.12 From bc7e4c5d682aa821d2007ffcbf404b59e3474542 Mon Sep 17 00:00:00 2001 From: dgp Date: Tue, 24 Mar 2015 18:27:09 +0000 Subject: There's no need to constrain the declaration of Tcl_GetMemoryInfo(). --- generic/tcl.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/generic/tcl.h b/generic/tcl.h index 5eff4d6..297b42c 100644 --- a/generic/tcl.h +++ b/generic/tcl.h @@ -2422,9 +2422,7 @@ EXTERN void Tcl_MainEx(int argc, char **argv, Tcl_AppInitProc *appInitProc, Tcl_Interp *interp); EXTERN const char * Tcl_PkgInitStubsCheck(Tcl_Interp *interp, const char *version, int exact); -#if defined(TCL_THREADS) && defined(USE_THREAD_ALLOC) EXTERN void Tcl_GetMemoryInfo(Tcl_DString *dsPtr); -#endif /* *---------------------------------------------------------------------------- -- cgit v0.12 From c6e6569dfeb8eeb4bf2558bb370a16eb861065f0 Mon Sep 17 00:00:00 2001 From: dkf Date: Sat, 4 Apr 2015 11:47:53 +0000 Subject: Don't fetch values we don't need. --- generic/tclExecute.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generic/tclExecute.c b/generic/tclExecute.c index 4790ba3..f2f475a 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -5591,7 +5591,7 @@ TEBCresume( TclNewObj(objResultPtr); } else if (TclIsPureByteArray(valuePtr)) { objResultPtr = Tcl_NewByteArrayObj( - Tcl_GetByteArrayFromObj(valuePtr, &length)+index, 1); + Tcl_GetByteArrayFromObj(valuePtr, NULL)+index, 1); } else if (valuePtr->bytes && length == valuePtr->length) { objResultPtr = Tcl_NewStringObj((const char *) valuePtr->bytes+index, 1); -- cgit v0.12 From 7fc61f369bd93fb2745878679eebe7024c3cf97b Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 8 Apr 2015 14:37:58 +0000 Subject: Proposed fix. --- generic/tclExecute.c | 1 + 1 file changed, 1 insertion(+) diff --git a/generic/tclExecute.c b/generic/tclExecute.c index f2f475a..feff85b 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -4946,6 +4946,7 @@ TEBCresume( pc += pcAdjustment; TEBC_YIELD(); + TclMarkTailcall(interp); oPtr = contextPtr->oPtr; if (oPtr->flags & FILTER_HANDLING) { TclNRAddCallback(interp, FinalizeOONextFilter, -- cgit v0.12 From 6d6afda39de86db3c4b0f0479432b0f61529a785 Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 8 Apr 2015 16:42:33 +0000 Subject: Correction suggested by miguel. Passes test suite and fixes bug demos. --- generic/tclExecute.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generic/tclExecute.c b/generic/tclExecute.c index feff85b..43c2b08 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -4946,7 +4946,7 @@ TEBCresume( pc += pcAdjustment; TEBC_YIELD(); - TclMarkTailcall(interp); + TclPushTailcallPoint(interp); oPtr = contextPtr->oPtr; if (oPtr->flags & FILTER_HANDLING) { TclNRAddCallback(interp, FinalizeOONextFilter, -- cgit v0.12 From 3d5869fb4bb012a0188d91ec25d638fdde7342b0 Mon Sep 17 00:00:00 2001 From: Miguel Sofer Date: Wed, 8 Apr 2015 19:08:57 +0000 Subject: improve comments for TclMarkTailcall and friends --- generic/tclBasic.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/generic/tclBasic.c b/generic/tclBasic.c index f6f66ed..1220239 100644 --- a/generic/tclBasic.c +++ b/generic/tclBasic.c @@ -8186,9 +8186,16 @@ Tcl_NRCmdSwap( * * One delicate point is to properly define the NRCommand where the tailcall * will execute. There are functions whose purpose is to help define the - * precise spot: TclMarkTailcall ("this is the spot") and TclSkipTailcall - * ("skip the next command: we are redirecting to it, tailcalls should run - * after WE return"), TclPushTailcallPoint (special for OO). + * precise spot: + * TclMarkTailcall: if the NEXT command to be pushed tailcalls, execution + * should continue right here + * TclSkipTailcall: if the NEXT command to be pushed tailcalls, execution + * should continue after the CURRENT command is fully returned ("skip + * the next command: we are redirecting to it, tailcalls should run + * after WE return") + * TclPushTailcallPoint: the search for a tailcalling spot cannot traverse + * this point. This is special for OO, as some of the oo constructs + * that behave like commands may not push an NRCommand callback. */ void -- cgit v0.12 From 1f2fb4cf5b60563c5a489e4b4cbdbe5e334dc248 Mon Sep 17 00:00:00 2001 From: dkf Date: Thu, 9 Apr 2015 09:20:29 +0000 Subject: Squelch otherwise-unavoidable OSX warnings. It's like magic! --- unix/tclLoadDyld.c | 1 + 1 file changed, 1 insertion(+) diff --git a/unix/tclLoadDyld.c b/unix/tclLoadDyld.c index 50c283d..8b7dc58 100644 --- a/unix/tclLoadDyld.c +++ b/unix/tclLoadDyld.c @@ -48,6 +48,7 @@ #endif /* TCL_DYLD_USE_DLFCN */ #if TCL_DYLD_USE_NSMODULE || defined(TCL_LOAD_FROM_MEMORY) +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" #include #include #include -- cgit v0.12 From 805cd597f906a608d30e585e9b6dd57c38f4eadc Mon Sep 17 00:00:00 2001 From: dkf Date: Thu, 9 Apr 2015 09:27:00 +0000 Subject: Don't warn about warnings that are suppressed correctly now. --- unix/Makefile.in | 1 - 1 file changed, 1 deletion(-) diff --git a/unix/Makefile.in b/unix/Makefile.in index 311fdb2..ad6034f 100644 --- a/unix/Makefile.in +++ b/unix/Makefile.in @@ -1200,7 +1200,6 @@ tclLoadDld.o: $(UNIX_DIR)/tclLoadDld.c $(CC) -c $(CC_SWITCHES) $(UNIX_DIR)/tclLoadDld.c tclLoadDyld.o: $(UNIX_DIR)/tclLoadDyld.c - @echo Warnings are expected from compiling tclLoadDyld.c: deprecated API use $(CC) -c $(CC_SWITCHES) $(UNIX_DIR)/tclLoadDyld.c tclLoadNone.o: $(GENERIC_DIR)/tclLoadNone.c -- cgit v0.12 From de7a370d58a13c3542e37e1ead987b3fa7eb65b8 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Fri, 10 Apr 2015 09:23:39 +0000 Subject: Fix [a0a251e4e478977334da51e346cddff8ec3fbf52|a0a251e4e4]: tcl 8.6.4 compilation on windows with msys and VS2013 fails --- win/Makefile.in | 9 +++++---- win/configure | 6 +++--- win/configure.in | 6 +++--- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/win/Makefile.in b/win/Makefile.in index 325b365..71d3fe6 100644 --- a/win/Makefile.in +++ b/win/Makefile.in @@ -110,6 +110,7 @@ GENERIC_DIR_NATIVE = $(shell $(CYGPATH) '$(GENERIC_DIR)' | sed 's!\\!/!g') TOMMATH_DIR_NATIVE = $(shell $(CYGPATH) '$(TOMMATH_DIR)' | sed 's!\\!/!g') WIN_DIR_NATIVE = $(shell $(CYGPATH) '$(WIN_DIR)' | sed 's!\\!/!g') ROOT_DIR_NATIVE = $(shell $(CYGPATH) '$(ROOT_DIR)' | sed 's!\\!/!g') +ZLIB_DIR_NATIVE = $(shell $(CYGPATH) '$(ZLIB_DIR)' | sed 's!\\!/!g') #GENERIC_DIR_NATIVE = $(GENERIC_DIR) #TOMMATH_DIR_NATIVE = $(TOMMATH_DIR) #WIN_DIR_NATIVE = $(WIN_DIR) @@ -189,10 +190,10 @@ SHELL = @SHELL@ RM = rm -f COPY = cp -CC_SWITCHES = ${CFLAGS} ${CFLAGS_WARNING} ${TCL_SHLIB_CFLAGS} -I"${ZLIB_DIR}" \ --I"${GENERIC_DIR_NATIVE}" -DTCL_TOMMATH -DMP_PREC=4 -I"${TOMMATH_DIR_NATIVE}" \ --I"${WIN_DIR_NATIVE}" ${AC_FLAGS} \ -${COMPILE_DEBUG_FLAGS} ${NO_DEPRECATED_FLAGS} +CC_SWITCHES = ${CFLAGS} ${CFLAGS_WARNING} ${TCL_SHLIB_CFLAGS} \ +-I"${ZLIB_DIR_NATIVE}" -I"${GENERIC_DIR_NATIVE}" -DTCL_TOMMATH \ +-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@ diff --git a/win/configure b/win/configure index bdfa908..2401002 100755 --- a/win/configure +++ b/win/configure @@ -4364,12 +4364,12 @@ if test "$tcl_ok" = "yes"; then if test "$GCC" == "yes"; then - ZLIB_LIBS=\${ZLIB_DIR}/win64/libz.dll.a + ZLIB_LIBS=\${ZLIB_DIR_NATIVE}/win64/libz.dll.a else - ZLIB_LIBS=\${ZLIB_DIR}/win64/zdll.lib + ZLIB_LIBS=\${ZLIB_DIR_NATIVE}/win64/zdll.lib fi @@ -4377,7 +4377,7 @@ fi else - ZLIB_LIBS=\${ZLIB_DIR}/win32/zdll.lib + ZLIB_LIBS=\${ZLIB_DIR_NATIVE}/win32/zdll.lib fi diff --git a/win/configure.in b/win/configure.in index 99d78f2..fc487d0 100644 --- a/win/configure.in +++ b/win/configure.in @@ -130,12 +130,12 @@ 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_NATIVE}/win64/libz.dll.a]) ], [ - AC_SUBST(ZLIB_LIBS,[\${ZLIB_DIR}/win64/zdll.lib]) + AC_SUBST(ZLIB_LIBS,[\${ZLIB_DIR_NATIVE}/win64/zdll.lib]) ]) ], [ - AC_SUBST(ZLIB_LIBS,[\${ZLIB_DIR}/win32/zdll.lib]) + AC_SUBST(ZLIB_LIBS,[\${ZLIB_DIR_NATIVE}/win32/zdll.lib]) ]) ], [ AC_SUBST(ZLIB_OBJS,[\${ZLIB_OBJS}]) -- cgit v0.12 From 7f030a6b44b94199f8a6a2ff0c09423452545d1d Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 15 Apr 2015 19:57:41 +0000 Subject: Revise the zippy dance that pushes Blocks and Tcl_Objs back the shared pool so that the overal operation remains a FIFO. This help preserve cache locality where it exists. The price (for now) is a bit more time walking to the end of free lists. If this is important, the addition of a lastPtr field could fix it without difficulty. --- generic/tclThreadAlloc.c | 100 ++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 85 insertions(+), 15 deletions(-) diff --git a/generic/tclThreadAlloc.c b/generic/tclThreadAlloc.c index 560556d..92bec44 100644 --- a/generic/tclThreadAlloc.c +++ b/generic/tclThreadAlloc.c @@ -135,6 +135,7 @@ static int GetBlocks(Cache *cachePtr, int bucket); static Block * Ptr2Block(char *ptr); static char * Block2Ptr(Block *blockPtr, int bucket, unsigned int reqSize); static void MoveObjs(Cache *fromPtr, Cache *toPtr, int numMove); +static void PutObjs(Cache *fromPtr, int numMove); /* * Local variables defined in this file and initialized at startup. @@ -271,9 +272,7 @@ TclFreeAllocCache( */ if (cachePtr->numObjects > 0) { - Tcl_MutexLock(objLockPtr); - MoveObjs(cachePtr, sharedPtr, cachePtr->numObjects); - Tcl_MutexUnlock(objLockPtr); + PutObjs(cachePtr, cachePtr->numObjects); } /* @@ -632,9 +631,7 @@ TclThreadFreeObj( */ if (cachePtr->numObjects > NOBJHIGH) { - Tcl_MutexLock(objLockPtr); - MoveObjs(cachePtr, sharedPtr, NOBJALLOC); - Tcl_MutexUnlock(objLockPtr); + PutObjs(cachePtr, NOBJALLOC); } } @@ -739,6 +736,60 @@ MoveObjs( /* *---------------------------------------------------------------------- * + * PutObjs -- + * + * Move Tcl_Obj's from thread cache to shared cache. + * + * Results: + * None. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +static void +PutObjs( + Cache *fromPtr, + int numMove) +{ + int keep = fromPtr->numObjects - numMove; + Tcl_Obj *firstPtr, *lastPtr; + + fromPtr->numObjects = keep; + firstPtr = fromPtr->firstObjPtr; + if (keep == 0) { + fromPtr->firstObjPtr = NULL; + } else { + do { + lastPtr = firstPtr; + firstPtr = firstPtr->internalRep.twoPtrValue.ptr1; + } while (--keep > 0); + lastPtr->internalRep.twoPtrValue.ptr1 = NULL; + } + + /* TODO: We could avoid this walk to lastPtr if we kept a lastPtr field */ + lastPtr = firstPtr; + while (lastPtr->internalRep.twoPtrValue.ptr1) { + lastPtr = lastPtr->internalRep.twoPtrValue.ptr1; + } + + /* + * Move all objects as a block - they are already linked to each other, we + * just have to update the first and last. + */ + + Tcl_MutexLock(objLockPtr); + lastPtr->internalRep.twoPtrValue.ptr1 = sharedPtr->firstObjPtr; + sharedPtr->firstObjPtr = firstPtr; + sharedPtr->numObjects += numMove; + Tcl_MutexUnlock(objLockPtr); +} + +/* + *---------------------------------------------------------------------- + * * Block2Ptr, Ptr2Block -- * * Convert between internal blocks and user pointers. @@ -848,20 +899,39 @@ PutBlocks( int bucket, int numMove) { - register Block *lastPtr, *firstPtr; - register int n = numMove; - /* - * Before acquiring the lock, walk the block list to find the last block - * to be moved. + * We have numFree. Want to shed numMove. So compute how many + * Blocks to keep. */ - firstPtr = lastPtr = cachePtr->buckets[bucket].firstPtr; - while (--n > 0) { + int keep = cachePtr->buckets[bucket].numFree - numMove; + Block *lastPtr, *firstPtr; + + cachePtr->buckets[bucket].numFree = keep; + firstPtr = cachePtr->buckets[bucket].firstPtr; + if (keep == 0) { + cachePtr->buckets[bucket].firstPtr = NULL; + } else { + do { + lastPtr = firstPtr; + firstPtr = firstPtr->nextBlock; + } while (--keep > 0); + lastPtr->nextBlock = NULL; + } + + /* + * firstPtr now points to the first Block to return to shared. + */ + + /* TODO: We could avoid this walk to lastPtr if we kept a lastPtr field */ + lastPtr = firstPtr; + while (lastPtr->nextBlock) { lastPtr = lastPtr->nextBlock; } - cachePtr->buckets[bucket].firstPtr = lastPtr->nextBlock; - cachePtr->buckets[bucket].numFree -= numMove; + + /* + * lastPtr now points to the last Block to return to shared. + */ /* * Aquire the lock and place the list of blocks at the front of the shared -- cgit v0.12 From c472223773e4ec8b4b9f80de4db13cf06b92e942 Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 16 Apr 2015 12:27:04 +0000 Subject: Reduce the list walking by keeping lastPtr fields. --- generic/tclInt.h | 3 ++- generic/tclThreadAlloc.c | 63 +++++++++++++++++++++++++++--------------------- 2 files changed, 37 insertions(+), 29 deletions(-) diff --git a/generic/tclInt.h b/generic/tclInt.h index 3f84717..c89f053 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -4116,7 +4116,8 @@ MODULE_SCOPE void TclpFreeAllocCache(void *); AllocCache *cachePtr; \ if (((interp) == NULL) || \ ((cachePtr = ((Interp *)(interp))->allocCache), \ - (cachePtr->numObjects >= ALLOC_NOBJHIGH))) { \ + ((cachePtr->numObjects == 0) || \ + (cachePtr->numObjects >= ALLOC_NOBJHIGH)))) { \ TclThreadFreeObj(objPtr); \ } else { \ (objPtr)->internalRep.twoPtrValue.ptr1 = cachePtr->firstObjPtr; \ diff --git a/generic/tclThreadAlloc.c b/generic/tclThreadAlloc.c index 92bec44..3267a0d 100644 --- a/generic/tclThreadAlloc.c +++ b/generic/tclThreadAlloc.c @@ -84,6 +84,7 @@ typedef union Block { typedef struct Bucket { Block *firstPtr; /* First block available */ + Block *lastPtr; /* End of block list */ long numFree; /* Number of blocks available */ /* All fields below for accounting only */ @@ -107,6 +108,7 @@ typedef struct Cache { Tcl_ThreadId owner; /* Which thread's cache is this? */ Tcl_Obj *firstObjPtr; /* List of free objects for thread */ int numObjects; /* Number of objects for thread */ + Tcl_Obj *lastPtr; /* Last object in this cache */ int totalAssigned; /* Total space assigned to thread */ Bucket buckets[NBUCKETS]; /* The buckets for this thread */ } Cache; @@ -414,6 +416,9 @@ TclpFree( cachePtr->buckets[bucket].totalAssigned -= blockPtr->blockReqSize; blockPtr->nextBlock = cachePtr->buckets[bucket].firstPtr; cachePtr->buckets[bucket].firstPtr = blockPtr; + if (cachePtr->buckets[bucket].numFree == 0) { + cachePtr->buckets[bucket].lastPtr = blockPtr; + } cachePtr->buckets[bucket].numFree++; cachePtr->buckets[bucket].numInserts++; @@ -571,11 +576,13 @@ TclThreadAllocObj(void) if (newObjsPtr == NULL) { Tcl_Panic("alloc: could not allocate %d new objects", numMove); } + cachePtr->lastPtr = newObjsPtr + numMove - 1; + objPtr = cachePtr->firstObjPtr; /* NULL */ while (--numMove >= 0) { - objPtr = &newObjsPtr[numMove]; - objPtr->internalRep.twoPtrValue.ptr1 = cachePtr->firstObjPtr; - cachePtr->firstObjPtr = objPtr; + newObjsPtr[numMove].internalRep.twoPtrValue.ptr1 = objPtr; + objPtr = newObjsPtr + numMove; } + cachePtr->firstObjPtr = newObjsPtr; } } @@ -623,6 +630,9 @@ TclThreadFreeObj( objPtr->internalRep.twoPtrValue.ptr1 = cachePtr->firstObjPtr; cachePtr->firstObjPtr = objPtr; + if (cachePtr->numObjects == 0) { + cachePtr->lastPtr = objPtr; + } cachePtr->numObjects++; /* @@ -729,7 +739,8 @@ MoveObjs( * just have to update the first and last. */ - objPtr->internalRep.twoPtrValue.ptr1 = toPtr->firstObjPtr; + toPtr->lastPtr = objPtr; + objPtr->internalRep.twoPtrValue.ptr1 = toPtr->firstObjPtr; /* NULL */ toPtr->firstObjPtr = fromFirstObjPtr; } @@ -755,7 +766,7 @@ PutObjs( int numMove) { int keep = fromPtr->numObjects - numMove; - Tcl_Obj *firstPtr, *lastPtr; + Tcl_Obj *firstPtr, *lastPtr = NULL; fromPtr->numObjects = keep; firstPtr = fromPtr->firstObjPtr; @@ -769,22 +780,21 @@ PutObjs( lastPtr->internalRep.twoPtrValue.ptr1 = NULL; } - /* TODO: We could avoid this walk to lastPtr if we kept a lastPtr field */ - lastPtr = firstPtr; - while (lastPtr->internalRep.twoPtrValue.ptr1) { - lastPtr = lastPtr->internalRep.twoPtrValue.ptr1; - } - /* * Move all objects as a block - they are already linked to each other, we * just have to update the first and last. */ Tcl_MutexLock(objLockPtr); - lastPtr->internalRep.twoPtrValue.ptr1 = sharedPtr->firstObjPtr; + fromPtr->lastPtr->internalRep.twoPtrValue.ptr1 = sharedPtr->firstObjPtr; sharedPtr->firstObjPtr = firstPtr; + if (sharedPtr->numObjects == 0) { + sharedPtr->lastPtr = fromPtr->lastPtr; + } sharedPtr->numObjects += numMove; Tcl_MutexUnlock(objLockPtr); + + fromPtr->lastPtr = lastPtr; } /* @@ -905,7 +915,7 @@ PutBlocks( */ int keep = cachePtr->buckets[bucket].numFree - numMove; - Block *lastPtr, *firstPtr; + Block *lastPtr = NULL, *firstPtr; cachePtr->buckets[bucket].numFree = keep; firstPtr = cachePtr->buckets[bucket].firstPtr; @@ -919,30 +929,23 @@ PutBlocks( lastPtr->nextBlock = NULL; } - /* - * firstPtr now points to the first Block to return to shared. - */ - - /* TODO: We could avoid this walk to lastPtr if we kept a lastPtr field */ - lastPtr = firstPtr; - while (lastPtr->nextBlock) { - lastPtr = lastPtr->nextBlock; - } - - /* - * lastPtr now points to the last Block to return to shared. - */ - /* * Aquire the lock and place the list of blocks at the front of the shared * cache bucket. */ LockBucket(cachePtr, bucket); - lastPtr->nextBlock = sharedPtr->buckets[bucket].firstPtr; + cachePtr->buckets[bucket].lastPtr->nextBlock + = sharedPtr->buckets[bucket].firstPtr; sharedPtr->buckets[bucket].firstPtr = firstPtr; + if (sharedPtr->buckets[bucket].numFree == 0) { + sharedPtr->buckets[bucket].lastPtr + = cachePtr->buckets[bucket].lastPtr; + } sharedPtr->buckets[bucket].numFree += numMove; UnlockBucket(cachePtr, bucket); + + cachePtr->buckets[bucket].lastPtr = lastPtr; } /* @@ -989,6 +992,8 @@ GetBlocks( if (n >= sharedPtr->buckets[bucket].numFree) { cachePtr->buckets[bucket].firstPtr = sharedPtr->buckets[bucket].firstPtr; + cachePtr->buckets[bucket].lastPtr = + sharedPtr->buckets[bucket].lastPtr; cachePtr->buckets[bucket].numFree = sharedPtr->buckets[bucket].numFree; sharedPtr->buckets[bucket].firstPtr = NULL; @@ -1002,6 +1007,7 @@ GetBlocks( blockPtr = blockPtr->nextBlock; } sharedPtr->buckets[bucket].firstPtr = blockPtr->nextBlock; + cachePtr->buckets[bucket].lastPtr = blockPtr; blockPtr->nextBlock = NULL; } } @@ -1053,6 +1059,7 @@ GetBlocks( ((char *) blockPtr + bucketInfo[bucket].blockSize); blockPtr = blockPtr->nextBlock; } + cachePtr->buckets[bucket].lastPtr = blockPtr; blockPtr->nextBlock = NULL; } return 1; -- cgit v0.12 From c3f11e774127c4045f36116d4b7d02fc0869546c Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Mon, 20 Apr 2015 10:35:20 +0000 Subject: Fix [8065d178229d8d335eee64d36ada37c4dedf2579|8065d17822]: Duplicate -DNDEBUG in compiler command with --disable-symbols --- unix/Makefile.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/unix/Makefile.in b/unix/Makefile.in index ad6034f..46ff5cd 100644 --- a/unix/Makefile.in +++ b/unix/Makefile.in @@ -96,7 +96,7 @@ CFLAGS_WARNING = @CFLAGS_WARNING@ # The default switches for optimization or debugging CFLAGS_DEBUG = @CFLAGS_DEBUG@ -CFLAGS_OPTIMIZE = -DNDEBUG @CFLAGS_OPTIMIZE@ +CFLAGS_OPTIMIZE = @CFLAGS_OPTIMIZE@ # To change the compiler switches, for example to change from optimization to # debugging symbols, change the following line: -- cgit v0.12 From 1590eb50c516f4fdf7b89882a806258d01bcbee1 Mon Sep 17 00:00:00 2001 From: oehhar Date: Thu, 23 Apr 2015 11:21:41 +0000 Subject: Open linked folder shared on Windows - Patch [19ea026e43] --- win/tclWinFile.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) mode change 100644 => 100755 win/tclWinFile.c diff --git a/win/tclWinFile.c b/win/tclWinFile.c old mode 100644 new mode 100755 index 76cd561..fe30c55 --- a/win/tclWinFile.c +++ b/win/tclWinFile.c @@ -704,7 +704,7 @@ NativeReadReparse( HANDLE hFile; DWORD returnedLength; - hFile = (*tclWinProcs->createFileProc)(linkDirPath, desiredAccess, 0, + hFile = (*tclWinProcs->createFileProc)(linkDirPath, desiredAccess, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS, NULL); -- cgit v0.12 From ae445193f4014a405dad671de52f4b4aae4959d9 Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 24 Apr 2015 15:47:58 +0000 Subject: Fix UtfToUtfProc() to remove the potential to read beyond end of input buffer. --- generic/tclEncoding.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generic/tclEncoding.c b/generic/tclEncoding.c index 1842fb6..54a49aa 100644 --- a/generic/tclEncoding.c +++ b/generic/tclEncoding.c @@ -2283,7 +2283,7 @@ UtfToUtfProc( *dst++ = *src++; } else if (pureNullMode == 1 && UCHAR(*src) == 0xc0 && - UCHAR(*(src+1)) == 0x80) { + (src + 1 < srcEnd) && UCHAR(*(src+1)) == 0x80) { /* * Convert 0xc080 to real nulls when we are in output mode. */ -- cgit v0.12 From 5ecd3fa2b65f897feccd280c1a04ca9f8f7c6f0a Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 24 Apr 2015 20:06:27 +0000 Subject: [879a0747be] Repair handling of incomplete multi-byte chars at the ends of input buffers. Also properly reset input encoding flags when cycling through a fleeting EOF condition. --- generic/tclIO.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++------- tests/io.test | 52 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 106 insertions(+), 7 deletions(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index 5a25243..2a20889 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -386,7 +386,11 @@ ChanRead( * Each read op must set the blocked and eof states anew, not let * the effect of prior reads leak through. */ + if (GotFlag(chanPtr->state, CHANNEL_EOF)) { + chanPtr->state->inputEncodingFlags |= TCL_ENCODING_START; + } ResetFlag(chanPtr->state, CHANNEL_BLOCKED | CHANNEL_EOF); + chanPtr->state->inputEncodingFlags &= ~TCL_ENCODING_END; if (WillRead(chanPtr) < 0) { return -1; } @@ -395,7 +399,11 @@ ChanRead( dst, dstSize, &result); /* Stop any flag leakage through stacked channel levels */ + if (GotFlag(chanPtr->state, CHANNEL_EOF)) { + chanPtr->state->inputEncodingFlags |= TCL_ENCODING_START; + } ResetFlag(chanPtr->state, CHANNEL_BLOCKED | CHANNEL_EOF); + chanPtr->state->inputEncodingFlags &= ~TCL_ENCODING_END; if (bytesRead > 0) { /* * If we get a short read, signal up that we may be BLOCKED. @@ -5301,7 +5309,11 @@ DoReadChars( /* Special handling for zero-char read request. */ if (toRead == 0) { + if (GotFlag(statePtr, CHANNEL_EOF)) { + statePtr->inputEncodingFlags |= TCL_ENCODING_START; + } ResetFlag(statePtr, CHANNEL_BLOCKED|CHANNEL_EOF); + statePtr->inputEncodingFlags &= ~TCL_ENCODING_END; UpdateInterest(chanPtr); return 0; } @@ -5314,7 +5326,11 @@ DoReadChars( TclChannelPreserve((Tcl_Channel)chanPtr); /* Must clear the BLOCKED flag here since we check before reading */ + if (GotFlag(statePtr, CHANNEL_EOF)) { + statePtr->inputEncodingFlags |= TCL_ENCODING_START; + } ResetFlag(statePtr, CHANNEL_BLOCKED|CHANNEL_EOF); + statePtr->inputEncodingFlags &= ~TCL_ENCODING_END; for (copied = 0; (unsigned) toRead > 0; ) { copiedNow = -1; if (statePtr->inQueueHead != NULL) { @@ -5557,16 +5573,28 @@ ReadChars( dstLimit = dstNeeded + 1; while (1) { - int dstDecoded, dstRead, dstWrote, srcRead, numChars; + int dstDecoded, dstRead, dstWrote, srcRead, numChars, code; /* * Perform the encoding transformation. Read no more than * srcLen bytes, write no more than dstLimit bytes. + * + * Some trickiness with encoding flags here. We do not want + * the end of a buffer to be treated as the end of all input + * when the presence of bytes in a next buffer are already + * known to exist. This is checked with an assert() because + * so far no test case causing the assertion to be false has + * been created. The normal operations of channel reading + * appear to cause EOF and TCL_ENCODING_END setting to appear + * only in situations where there are no further bytes in + * any buffers. */ - int code = Tcl_ExternalToUtf(NULL, encoding, src, srcLen, - statePtr->inputEncodingFlags & (bufPtr->nextPtr - ? ~0 : ~TCL_ENCODING_END), &statePtr->inputEncodingState, + assert(bufPtr->nextPtr == NULL || BytesLeft(bufPtr->nextPtr) == 0 + || (statePtr->inputEncodingFlags & TCL_ENCODING_END) == 0); + + code = Tcl_ExternalToUtf(NULL, encoding, src, srcLen, + statePtr->inputEncodingFlags, &statePtr->inputEncodingState, dst, dstLimit, &srcRead, &dstDecoded, &numChars); /* @@ -5684,9 +5712,12 @@ ReadChars( statePtr->inputEncodingFlags = savedIEFlags; statePtr->inputEncodingState = savedState; + assert(bufPtr->nextPtr == NULL + || BytesLeft(bufPtr->nextPtr) == 0 || 0 == + (statePtr->inputEncodingFlags & TCL_ENCODING_END)); + Tcl_ExternalToUtf(NULL, encoding, src, srcLen, - statePtr->inputEncodingFlags & (bufPtr->nextPtr - ? ~0 : ~TCL_ENCODING_END), &statePtr->inputEncodingState, + statePtr->inputEncodingFlags, &statePtr->inputEncodingState, buffer, TCL_UTF_MAX + 2, &read, &decoded, &count); if (count == 2) { @@ -6060,9 +6091,13 @@ Tcl_Ungets( /* * Clear the EOF flags, and clear the BLOCKED bit. */ - + + if (GotFlag(statePtr, CHANNEL_EOF)) { + statePtr->inputEncodingFlags |= TCL_ENCODING_START; + } ResetFlag(statePtr, CHANNEL_BLOCKED | CHANNEL_STICKY_EOF | CHANNEL_EOF | INPUT_SAW_CR); + statePtr->inputEncodingFlags &= ~TCL_ENCODING_END; bufPtr = AllocChannelBuffer(len); memcpy(InsertPoint(bufPtr), str, (size_t) len); @@ -6432,8 +6467,12 @@ Tcl_Seek( * point. Also clear CR related flags. */ + if (GotFlag(statePtr, CHANNEL_EOF)) { + statePtr->inputEncodingFlags |= TCL_ENCODING_START; + } statePtr->flags &= ~(CHANNEL_EOF | CHANNEL_STICKY_EOF | CHANNEL_BLOCKED | INPUT_SAW_CR); + statePtr->inputEncodingFlags &= ~TCL_ENCODING_END; /* * If the channel is in asynchronous output mode, switch it back to @@ -7550,8 +7589,12 @@ Tcl_SetChannelOption( * ahead'. Ditto for blocked. */ + if (GotFlag(statePtr, CHANNEL_EOF)) { + statePtr->inputEncodingFlags |= TCL_ENCODING_START; + } statePtr->flags &= ~(CHANNEL_EOF | CHANNEL_STICKY_EOF | CHANNEL_BLOCKED); + statePtr->inputEncodingFlags &= ~TCL_ENCODING_END; return TCL_OK; } else if (HaveOpt(1, "-translation")) { @@ -8981,7 +9024,11 @@ DoRead( /* Special handling for zero-char read request. */ if (bytesToRead == 0) { + if (GotFlag(statePtr, CHANNEL_EOF)) { + statePtr->inputEncodingFlags |= TCL_ENCODING_START; + } ResetFlag(statePtr, CHANNEL_BLOCKED|CHANNEL_EOF); + statePtr->inputEncodingFlags &= ~TCL_ENCODING_END; UpdateInterest(chanPtr); return 0; } diff --git a/tests/io.test b/tests/io.test index e4dc522..d199206 100644 --- a/tests/io.test +++ b/tests/io.test @@ -1511,6 +1511,39 @@ test io-12.7 {ReadChars: too many chars read [bc5b790099]} { } close $c } {} +test io-12.8 {ReadChars: multibyte chars split} { + set f [open $path(test1) w] + fconfigure $f -translation binary + puts -nonewline $f [string repeat a 9]\xc2\xa0 + close $f + set f [open $path(test1)] + fconfigure $f -encoding utf-8 -buffersize 10 + set in [read $f] + close $f + scan [string index $in end] %c +} 160 +test io-12.9 {ReadChars: multibyte chars split} { + set f [open $path(test1) w] + fconfigure $f -translation binary + puts -nonewline $f [string repeat a 9]\xc2 + close $f + set f [open $path(test1)] + fconfigure $f -encoding utf-8 -buffersize 10 + set in [read $f] + close $f + scan [string index $in end] %c +} 194 +test io-12.10 {ReadChars: multibyte chars split} { + set f [open $path(test1) w] + fconfigure $f -translation binary + puts -nonewline $f [string repeat a 9]\xc2 + close $f + set f [open $path(test1)] + fconfigure $f -encoding utf-8 -buffersize 11 + set in [read $f] + close $f + scan [string index $in end] %c +} 194 test io-13.1 {TranslateInputEOL: cr mode} {} { set f [open $path(test1) w] @@ -8438,6 +8471,25 @@ test io-73.4 {[5adc350683] [read] after EOF} -setup { } -result {1 1 {more data } 1} +test io-73.5 {effect of eof on encoding end flags} -setup { + set fn [makeFile {} io-73.5] + set rfd [open $fn r] + set wfd [open $fn a] + chan configure $wfd -buffering none -translation binary + chan configure $rfd -buffersize 5 -encoding utf-8 + read $rfd +} -body { + set result [eof $rfd] + puts -nonewline $wfd "more\u00c2\u00a0data" + lappend result [eof $rfd] + lappend result [read $rfd] + lappend result [eof $rfd] +} -cleanup { + close $wfd + close $rfd + removeFile io-73.5 +} -result [list 1 1 more\u00a0data 1] + # ### ### ### ######### ######### ######### # cleanup -- cgit v0.12 From f108505a5b7fb6dd640bd29fbae0995ca789aacb Mon Sep 17 00:00:00 2001 From: venkat Date: Wed, 29 Apr 2015 07:54:51 +0000 Subject: Update to tzdata2015d from ietf.org --- library/tzdata/Africa/Cairo | 180 --------------- library/tzdata/America/Adak | 466 +++++++++++++++++++-------------------- library/tzdata/America/Antigua | 8 +- library/tzdata/America/Cayman | 8 +- library/tzdata/America/Montreal | 367 +----------------------------- library/tzdata/America/Santiago | 18 +- library/tzdata/Antarctica/Palmer | 4 +- library/tzdata/Asia/Choibalsan | 171 ++++++++++++++ library/tzdata/Asia/Gaza | 342 ++++++++++++++-------------- library/tzdata/Asia/Hebron | 342 ++++++++++++++-------------- library/tzdata/Asia/Hovd | 170 ++++++++++++++ library/tzdata/Asia/Ulaanbaatar | 170 ++++++++++++++ library/tzdata/Europe/Volgograd | 38 ++-- library/tzdata/Pacific/Easter | 16 +- library/tzdata/Pacific/Midway | 11 +- library/tzdata/Pacific/Saipan | 10 +- 16 files changed, 1136 insertions(+), 1185 deletions(-) diff --git a/library/tzdata/Africa/Cairo b/library/tzdata/Africa/Cairo index f453da2..aaeec54 100644 --- a/library/tzdata/Africa/Cairo +++ b/library/tzdata/Africa/Cairo @@ -129,184 +129,4 @@ set TZData(:Africa/Cairo) { {1403816400 7200 0 EET} {1406844000 10800 1 EEST} {1411678800 7200 0 EET} - {1429826400 10800 1 EEST} - {1434056400 7200 0 EET} - {1437688800 10800 1 EEST} - {1443128400 7200 0 EET} - {1461880800 10800 1 EEST} - {1464901200 7200 0 EET} - {1467928800 10800 1 EEST} - {1475182800 7200 0 EET} - {1493330400 10800 1 EEST} - {1495746000 7200 0 EET} - {1498773600 10800 1 EEST} - {1506632400 7200 0 EET} - {1524780000 10800 1 EEST} - {1525986000 7200 0 EET} - {1529013600 10800 1 EEST} - {1538082000 7200 0 EET} - {1556229600 10800 1 EEST} - {1556830800 7200 0 EET} - {1559858400 10800 1 EEST} - {1569531600 7200 0 EET} - {1590703200 10800 1 EEST} - {1600981200 7200 0 EET} - {1620943200 10800 1 EEST} - {1633035600 7200 0 EET} - {1651788000 10800 1 EEST} - {1664485200 7200 0 EET} - {1682632800 10800 1 EEST} - {1695934800 7200 0 EET} - {1714082400 10800 1 EEST} - {1727384400 7200 0 EET} - {1745532000 10800 1 EEST} - {1758834000 7200 0 EET} - {1776981600 10800 1 EEST} - {1790283600 7200 0 EET} - {1809036000 10800 1 EEST} - {1822338000 7200 0 EET} - {1840485600 10800 1 EEST} - {1853787600 7200 0 EET} - {1871935200 10800 1 EEST} - {1885237200 7200 0 EET} - {1903384800 10800 1 EEST} - {1916686800 7200 0 EET} - {1934834400 10800 1 EEST} - {1948136400 7200 0 EET} - {1966888800 10800 1 EEST} - {1980190800 7200 0 EET} - {1998338400 10800 1 EEST} - {2011640400 7200 0 EET} - {2029788000 10800 1 EEST} - {2043090000 7200 0 EET} - {2061237600 10800 1 EEST} - {2074539600 7200 0 EET} - {2092687200 10800 1 EEST} - {2105989200 7200 0 EET} - {2124136800 10800 1 EEST} - {2137438800 7200 0 EET} - {2156191200 10800 1 EEST} - {2169493200 7200 0 EET} - {2187640800 10800 1 EEST} - {2200942800 7200 0 EET} - {2219090400 10800 1 EEST} - {2232392400 7200 0 EET} - {2250540000 10800 1 EEST} - {2263842000 7200 0 EET} - {2281989600 10800 1 EEST} - {2295291600 7200 0 EET} - {2313439200 10800 1 EEST} - {2326741200 7200 0 EET} - {2345493600 10800 1 EEST} - {2358795600 7200 0 EET} - {2376943200 10800 1 EEST} - {2390245200 7200 0 EET} - {2408392800 10800 1 EEST} - {2421694800 7200 0 EET} - {2439842400 10800 1 EEST} - {2453144400 7200 0 EET} - {2471292000 10800 1 EEST} - {2484594000 7200 0 EET} - {2503346400 10800 1 EEST} - {2516648400 7200 0 EET} - {2534796000 10800 1 EEST} - {2548098000 7200 0 EET} - {2566245600 10800 1 EEST} - {2579547600 7200 0 EET} - {2597695200 10800 1 EEST} - {2610997200 7200 0 EET} - {2629144800 10800 1 EEST} - {2642446800 7200 0 EET} - {2660594400 10800 1 EEST} - {2673896400 7200 0 EET} - {2692648800 10800 1 EEST} - {2705950800 7200 0 EET} - {2724098400 10800 1 EEST} - {2737400400 7200 0 EET} - {2755548000 10800 1 EEST} - {2768850000 7200 0 EET} - {2786997600 10800 1 EEST} - {2800299600 7200 0 EET} - {2818447200 10800 1 EEST} - {2831749200 7200 0 EET} - {2850501600 10800 1 EEST} - {2863803600 7200 0 EET} - {2881951200 10800 1 EEST} - {2895253200 7200 0 EET} - {2913400800 10800 1 EEST} - {2926702800 7200 0 EET} - {2944850400 10800 1 EEST} - {2958152400 7200 0 EET} - {2976300000 10800 1 EEST} - {2989602000 7200 0 EET} - {3007749600 10800 1 EEST} - {3021051600 7200 0 EET} - {3039804000 10800 1 EEST} - {3053106000 7200 0 EET} - {3071253600 10800 1 EEST} - {3084555600 7200 0 EET} - {3102703200 10800 1 EEST} - {3116005200 7200 0 EET} - {3134152800 10800 1 EEST} - {3147454800 7200 0 EET} - {3165602400 10800 1 EEST} - {3178904400 7200 0 EET} - {3197052000 10800 1 EEST} - {3210354000 7200 0 EET} - {3229106400 10800 1 EEST} - {3242408400 7200 0 EET} - {3260556000 10800 1 EEST} - {3273858000 7200 0 EET} - {3292005600 10800 1 EEST} - {3305307600 7200 0 EET} - {3323455200 10800 1 EEST} - {3336757200 7200 0 EET} - {3354904800 10800 1 EEST} - {3368206800 7200 0 EET} - {3386959200 10800 1 EEST} - {3400261200 7200 0 EET} - {3418408800 10800 1 EEST} - {3431710800 7200 0 EET} - {3449858400 10800 1 EEST} - {3463160400 7200 0 EET} - {3481308000 10800 1 EEST} - {3494610000 7200 0 EET} - {3512757600 10800 1 EEST} - {3526059600 7200 0 EET} - {3544207200 10800 1 EEST} - {3557509200 7200 0 EET} - {3576261600 10800 1 EEST} - {3589563600 7200 0 EET} - {3607711200 10800 1 EEST} - {3621013200 7200 0 EET} - {3639160800 10800 1 EEST} - {3652462800 7200 0 EET} - {3670610400 10800 1 EEST} - {3683912400 7200 0 EET} - {3702060000 10800 1 EEST} - {3715362000 7200 0 EET} - {3734114400 10800 1 EEST} - {3747416400 7200 0 EET} - {3765564000 10800 1 EEST} - {3778866000 7200 0 EET} - {3797013600 10800 1 EEST} - {3810315600 7200 0 EET} - {3828463200 10800 1 EEST} - {3841765200 7200 0 EET} - {3859912800 10800 1 EEST} - {3873214800 7200 0 EET} - {3891362400 10800 1 EEST} - {3904664400 7200 0 EET} - {3923416800 10800 1 EEST} - {3936718800 7200 0 EET} - {3954866400 10800 1 EEST} - {3968168400 7200 0 EET} - {3986316000 10800 1 EEST} - {3999618000 7200 0 EET} - {4017765600 10800 1 EEST} - {4031067600 7200 0 EET} - {4049215200 10800 1 EEST} - {4062517200 7200 0 EET} - {4080664800 10800 1 EEST} - {4093966800 7200 0 EET} } diff --git a/library/tzdata/America/Adak b/library/tzdata/America/Adak index f3c5e5c..bd5d5ab 100644 --- a/library/tzdata/America/Adak +++ b/library/tzdata/America/Adak @@ -40,237 +40,237 @@ set TZData(:America/Adak) { {388587600 -36000 1 BDT} {404913600 -39600 0 BST} {420037200 -36000 1 BDT} - {439034400 -36000 0 HAST} - {452088000 -32400 1 HADT} - {467809200 -36000 0 HAST} - {483537600 -32400 1 HADT} - {499258800 -36000 0 HAST} - {514987200 -32400 1 HADT} - {530708400 -36000 0 HAST} - {544622400 -32400 1 HADT} - {562158000 -36000 0 HAST} - {576072000 -32400 1 HADT} - {594212400 -36000 0 HAST} - {607521600 -32400 1 HADT} - {625662000 -36000 0 HAST} - {638971200 -32400 1 HADT} - {657111600 -36000 0 HAST} - {671025600 -32400 1 HADT} - {688561200 -36000 0 HAST} - {702475200 -32400 1 HADT} - {720010800 -36000 0 HAST} - {733924800 -32400 1 HADT} - {752065200 -36000 0 HAST} - {765374400 -32400 1 HADT} - {783514800 -36000 0 HAST} - {796824000 -32400 1 HADT} - {814964400 -36000 0 HAST} - {828878400 -32400 1 HADT} - {846414000 -36000 0 HAST} - {860328000 -32400 1 HADT} - {877863600 -36000 0 HAST} - {891777600 -32400 1 HADT} - {909313200 -36000 0 HAST} - {923227200 -32400 1 HADT} - {941367600 -36000 0 HAST} - {954676800 -32400 1 HADT} - {972817200 -36000 0 HAST} - {986126400 -32400 1 HADT} - {1004266800 -36000 0 HAST} - {1018180800 -32400 1 HADT} - {1035716400 -36000 0 HAST} - {1049630400 -32400 1 HADT} - {1067166000 -36000 0 HAST} - {1081080000 -32400 1 HADT} - {1099220400 -36000 0 HAST} - {1112529600 -32400 1 HADT} - {1130670000 -36000 0 HAST} - {1143979200 -32400 1 HADT} - {1162119600 -36000 0 HAST} - {1173614400 -32400 1 HADT} - {1194174000 -36000 0 HAST} - {1205064000 -32400 1 HADT} - {1225623600 -36000 0 HAST} - {1236513600 -32400 1 HADT} - {1257073200 -36000 0 HAST} - {1268568000 -32400 1 HADT} - {1289127600 -36000 0 HAST} - {1300017600 -32400 1 HADT} - {1320577200 -36000 0 HAST} - {1331467200 -32400 1 HADT} - {1352026800 -36000 0 HAST} - {1362916800 -32400 1 HADT} - {1383476400 -36000 0 HAST} - {1394366400 -32400 1 HADT} - {1414926000 -36000 0 HAST} - {1425816000 -32400 1 HADT} - {1446375600 -36000 0 HAST} - {1457870400 -32400 1 HADT} - {1478430000 -36000 0 HAST} - {1489320000 -32400 1 HADT} - {1509879600 -36000 0 HAST} - {1520769600 -32400 1 HADT} - {1541329200 -36000 0 HAST} - {1552219200 -32400 1 HADT} - {1572778800 -36000 0 HAST} - {1583668800 -32400 1 HADT} - {1604228400 -36000 0 HAST} - {1615723200 -32400 1 HADT} - {1636282800 -36000 0 HAST} - {1647172800 -32400 1 HADT} - {1667732400 -36000 0 HAST} - {1678622400 -32400 1 HADT} - {1699182000 -36000 0 HAST} - {1710072000 -32400 1 HADT} - {1730631600 -36000 0 HAST} - {1741521600 -32400 1 HADT} - {1762081200 -36000 0 HAST} - {1772971200 -32400 1 HADT} - {1793530800 -36000 0 HAST} - {1805025600 -32400 1 HADT} - {1825585200 -36000 0 HAST} - {1836475200 -32400 1 HADT} - {1857034800 -36000 0 HAST} - {1867924800 -32400 1 HADT} - {1888484400 -36000 0 HAST} - {1899374400 -32400 1 HADT} - {1919934000 -36000 0 HAST} - {1930824000 -32400 1 HADT} - {1951383600 -36000 0 HAST} - {1962878400 -32400 1 HADT} - {1983438000 -36000 0 HAST} - {1994328000 -32400 1 HADT} - {2014887600 -36000 0 HAST} - {2025777600 -32400 1 HADT} - {2046337200 -36000 0 HAST} - {2057227200 -32400 1 HADT} - {2077786800 -36000 0 HAST} - {2088676800 -32400 1 HADT} - {2109236400 -36000 0 HAST} - {2120126400 -32400 1 HADT} - {2140686000 -36000 0 HAST} - {2152180800 -32400 1 HADT} - {2172740400 -36000 0 HAST} - {2183630400 -32400 1 HADT} - {2204190000 -36000 0 HAST} - {2215080000 -32400 1 HADT} - {2235639600 -36000 0 HAST} - {2246529600 -32400 1 HADT} - {2267089200 -36000 0 HAST} - {2277979200 -32400 1 HADT} - {2298538800 -36000 0 HAST} - {2309428800 -32400 1 HADT} - {2329988400 -36000 0 HAST} - {2341483200 -32400 1 HADT} - {2362042800 -36000 0 HAST} - {2372932800 -32400 1 HADT} - {2393492400 -36000 0 HAST} - {2404382400 -32400 1 HADT} - {2424942000 -36000 0 HAST} - {2435832000 -32400 1 HADT} - {2456391600 -36000 0 HAST} - {2467281600 -32400 1 HADT} - {2487841200 -36000 0 HAST} - {2499336000 -32400 1 HADT} - {2519895600 -36000 0 HAST} - {2530785600 -32400 1 HADT} - {2551345200 -36000 0 HAST} - {2562235200 -32400 1 HADT} - {2582794800 -36000 0 HAST} - {2593684800 -32400 1 HADT} - {2614244400 -36000 0 HAST} - {2625134400 -32400 1 HADT} - {2645694000 -36000 0 HAST} - {2656584000 -32400 1 HADT} - {2677143600 -36000 0 HAST} - {2688638400 -32400 1 HADT} - {2709198000 -36000 0 HAST} - {2720088000 -32400 1 HADT} - {2740647600 -36000 0 HAST} - {2751537600 -32400 1 HADT} - {2772097200 -36000 0 HAST} - {2782987200 -32400 1 HADT} - {2803546800 -36000 0 HAST} - {2814436800 -32400 1 HADT} - {2834996400 -36000 0 HAST} - {2846491200 -32400 1 HADT} - {2867050800 -36000 0 HAST} - {2877940800 -32400 1 HADT} - {2898500400 -36000 0 HAST} - {2909390400 -32400 1 HADT} - {2929950000 -36000 0 HAST} - {2940840000 -32400 1 HADT} - {2961399600 -36000 0 HAST} - {2972289600 -32400 1 HADT} - {2992849200 -36000 0 HAST} - {3003739200 -32400 1 HADT} - {3024298800 -36000 0 HAST} - {3035793600 -32400 1 HADT} - {3056353200 -36000 0 HAST} - {3067243200 -32400 1 HADT} - {3087802800 -36000 0 HAST} - {3098692800 -32400 1 HADT} - {3119252400 -36000 0 HAST} - {3130142400 -32400 1 HADT} - {3150702000 -36000 0 HAST} - {3161592000 -32400 1 HADT} - {3182151600 -36000 0 HAST} - {3193041600 -32400 1 HADT} - {3213601200 -36000 0 HAST} - {3225096000 -32400 1 HADT} - {3245655600 -36000 0 HAST} - {3256545600 -32400 1 HADT} - {3277105200 -36000 0 HAST} - {3287995200 -32400 1 HADT} - {3308554800 -36000 0 HAST} - {3319444800 -32400 1 HADT} - {3340004400 -36000 0 HAST} - {3350894400 -32400 1 HADT} - {3371454000 -36000 0 HAST} - {3382948800 -32400 1 HADT} - {3403508400 -36000 0 HAST} - {3414398400 -32400 1 HADT} - {3434958000 -36000 0 HAST} - {3445848000 -32400 1 HADT} - {3466407600 -36000 0 HAST} - {3477297600 -32400 1 HADT} - {3497857200 -36000 0 HAST} - {3508747200 -32400 1 HADT} - {3529306800 -36000 0 HAST} - {3540196800 -32400 1 HADT} - {3560756400 -36000 0 HAST} - {3572251200 -32400 1 HADT} - {3592810800 -36000 0 HAST} - {3603700800 -32400 1 HADT} - {3624260400 -36000 0 HAST} - {3635150400 -32400 1 HADT} - {3655710000 -36000 0 HAST} - {3666600000 -32400 1 HADT} - {3687159600 -36000 0 HAST} - {3698049600 -32400 1 HADT} - {3718609200 -36000 0 HAST} - {3730104000 -32400 1 HADT} - {3750663600 -36000 0 HAST} - {3761553600 -32400 1 HADT} - {3782113200 -36000 0 HAST} - {3793003200 -32400 1 HADT} - {3813562800 -36000 0 HAST} - {3824452800 -32400 1 HADT} - {3845012400 -36000 0 HAST} - {3855902400 -32400 1 HADT} - {3876462000 -36000 0 HAST} - {3887352000 -32400 1 HADT} - {3907911600 -36000 0 HAST} - {3919406400 -32400 1 HADT} - {3939966000 -36000 0 HAST} - {3950856000 -32400 1 HADT} - {3971415600 -36000 0 HAST} - {3982305600 -32400 1 HADT} - {4002865200 -36000 0 HAST} - {4013755200 -32400 1 HADT} - {4034314800 -36000 0 HAST} - {4045204800 -32400 1 HADT} - {4065764400 -36000 0 HAST} - {4076654400 -32400 1 HADT} - {4097214000 -36000 0 HAST} + {439034400 -36000 0 HST} + {452088000 -32400 1 HDT} + {467809200 -36000 0 HST} + {483537600 -32400 1 HDT} + {499258800 -36000 0 HST} + {514987200 -32400 1 HDT} + {530708400 -36000 0 HST} + {544622400 -32400 1 HDT} + {562158000 -36000 0 HST} + {576072000 -32400 1 HDT} + {594212400 -36000 0 HST} + {607521600 -32400 1 HDT} + {625662000 -36000 0 HST} + {638971200 -32400 1 HDT} + {657111600 -36000 0 HST} + {671025600 -32400 1 HDT} + {688561200 -36000 0 HST} + {702475200 -32400 1 HDT} + {720010800 -36000 0 HST} + {733924800 -32400 1 HDT} + {752065200 -36000 0 HST} + {765374400 -32400 1 HDT} + {783514800 -36000 0 HST} + {796824000 -32400 1 HDT} + {814964400 -36000 0 HST} + {828878400 -32400 1 HDT} + {846414000 -36000 0 HST} + {860328000 -32400 1 HDT} + {877863600 -36000 0 HST} + {891777600 -32400 1 HDT} + {909313200 -36000 0 HST} + {923227200 -32400 1 HDT} + {941367600 -36000 0 HST} + {954676800 -32400 1 HDT} + {972817200 -36000 0 HST} + {986126400 -32400 1 HDT} + {1004266800 -36000 0 HST} + {1018180800 -32400 1 HDT} + {1035716400 -36000 0 HST} + {1049630400 -32400 1 HDT} + {1067166000 -36000 0 HST} + {1081080000 -32400 1 HDT} + {1099220400 -36000 0 HST} + {1112529600 -32400 1 HDT} + {1130670000 -36000 0 HST} + {1143979200 -32400 1 HDT} + {1162119600 -36000 0 HST} + {1173614400 -32400 1 HDT} + {1194174000 -36000 0 HST} + {1205064000 -32400 1 HDT} + {1225623600 -36000 0 HST} + {1236513600 -32400 1 HDT} + {1257073200 -36000 0 HST} + {1268568000 -32400 1 HDT} + {1289127600 -36000 0 HST} + {1300017600 -32400 1 HDT} + {1320577200 -36000 0 HST} + {1331467200 -32400 1 HDT} + {1352026800 -36000 0 HST} + {1362916800 -32400 1 HDT} + {1383476400 -36000 0 HST} + {1394366400 -32400 1 HDT} + {1414926000 -36000 0 HST} + {1425816000 -32400 1 HDT} + {1446375600 -36000 0 HST} + {1457870400 -32400 1 HDT} + {1478430000 -36000 0 HST} + {1489320000 -32400 1 HDT} + {1509879600 -36000 0 HST} + {1520769600 -32400 1 HDT} + {1541329200 -36000 0 HST} + {1552219200 -32400 1 HDT} + {1572778800 -36000 0 HST} + {1583668800 -32400 1 HDT} + {1604228400 -36000 0 HST} + {1615723200 -32400 1 HDT} + {1636282800 -36000 0 HST} + {1647172800 -32400 1 HDT} + {1667732400 -36000 0 HST} + {1678622400 -32400 1 HDT} + {1699182000 -36000 0 HST} + {1710072000 -32400 1 HDT} + {1730631600 -36000 0 HST} + {1741521600 -32400 1 HDT} + {1762081200 -36000 0 HST} + {1772971200 -32400 1 HDT} + {1793530800 -36000 0 HST} + {1805025600 -32400 1 HDT} + {1825585200 -36000 0 HST} + {1836475200 -32400 1 HDT} + {1857034800 -36000 0 HST} + {1867924800 -32400 1 HDT} + {1888484400 -36000 0 HST} + {1899374400 -32400 1 HDT} + {1919934000 -36000 0 HST} + {1930824000 -32400 1 HDT} + {1951383600 -36000 0 HST} + {1962878400 -32400 1 HDT} + {1983438000 -36000 0 HST} + {1994328000 -32400 1 HDT} + {2014887600 -36000 0 HST} + {2025777600 -32400 1 HDT} + {2046337200 -36000 0 HST} + {2057227200 -32400 1 HDT} + {2077786800 -36000 0 HST} + {2088676800 -32400 1 HDT} + {2109236400 -36000 0 HST} + {2120126400 -32400 1 HDT} + {2140686000 -36000 0 HST} + {2152180800 -32400 1 HDT} + {2172740400 -36000 0 HST} + {2183630400 -32400 1 HDT} + {2204190000 -36000 0 HST} + {2215080000 -32400 1 HDT} + {2235639600 -36000 0 HST} + {2246529600 -32400 1 HDT} + {2267089200 -36000 0 HST} + {2277979200 -32400 1 HDT} + {2298538800 -36000 0 HST} + {2309428800 -32400 1 HDT} + {2329988400 -36000 0 HST} + {2341483200 -32400 1 HDT} + {2362042800 -36000 0 HST} + {2372932800 -32400 1 HDT} + {2393492400 -36000 0 HST} + {2404382400 -32400 1 HDT} + {2424942000 -36000 0 HST} + {2435832000 -32400 1 HDT} + {2456391600 -36000 0 HST} + {2467281600 -32400 1 HDT} + {2487841200 -36000 0 HST} + {2499336000 -32400 1 HDT} + {2519895600 -36000 0 HST} + {2530785600 -32400 1 HDT} + {2551345200 -36000 0 HST} + {2562235200 -32400 1 HDT} + {2582794800 -36000 0 HST} + {2593684800 -32400 1 HDT} + {2614244400 -36000 0 HST} + {2625134400 -32400 1 HDT} + {2645694000 -36000 0 HST} + {2656584000 -32400 1 HDT} + {2677143600 -36000 0 HST} + {2688638400 -32400 1 HDT} + {2709198000 -36000 0 HST} + {2720088000 -32400 1 HDT} + {2740647600 -36000 0 HST} + {2751537600 -32400 1 HDT} + {2772097200 -36000 0 HST} + {2782987200 -32400 1 HDT} + {2803546800 -36000 0 HST} + {2814436800 -32400 1 HDT} + {2834996400 -36000 0 HST} + {2846491200 -32400 1 HDT} + {2867050800 -36000 0 HST} + {2877940800 -32400 1 HDT} + {2898500400 -36000 0 HST} + {2909390400 -32400 1 HDT} + {2929950000 -36000 0 HST} + {2940840000 -32400 1 HDT} + {2961399600 -36000 0 HST} + {2972289600 -32400 1 HDT} + {2992849200 -36000 0 HST} + {3003739200 -32400 1 HDT} + {3024298800 -36000 0 HST} + {3035793600 -32400 1 HDT} + {3056353200 -36000 0 HST} + {3067243200 -32400 1 HDT} + {3087802800 -36000 0 HST} + {3098692800 -32400 1 HDT} + {3119252400 -36000 0 HST} + {3130142400 -32400 1 HDT} + {3150702000 -36000 0 HST} + {3161592000 -32400 1 HDT} + {3182151600 -36000 0 HST} + {3193041600 -32400 1 HDT} + {3213601200 -36000 0 HST} + {3225096000 -32400 1 HDT} + {3245655600 -36000 0 HST} + {3256545600 -32400 1 HDT} + {3277105200 -36000 0 HST} + {3287995200 -32400 1 HDT} + {3308554800 -36000 0 HST} + {3319444800 -32400 1 HDT} + {3340004400 -36000 0 HST} + {3350894400 -32400 1 HDT} + {3371454000 -36000 0 HST} + {3382948800 -32400 1 HDT} + {3403508400 -36000 0 HST} + {3414398400 -32400 1 HDT} + {3434958000 -36000 0 HST} + {3445848000 -32400 1 HDT} + {3466407600 -36000 0 HST} + {3477297600 -32400 1 HDT} + {3497857200 -36000 0 HST} + {3508747200 -32400 1 HDT} + {3529306800 -36000 0 HST} + {3540196800 -32400 1 HDT} + {3560756400 -36000 0 HST} + {3572251200 -32400 1 HDT} + {3592810800 -36000 0 HST} + {3603700800 -32400 1 HDT} + {3624260400 -36000 0 HST} + {3635150400 -32400 1 HDT} + {3655710000 -36000 0 HST} + {3666600000 -32400 1 HDT} + {3687159600 -36000 0 HST} + {3698049600 -32400 1 HDT} + {3718609200 -36000 0 HST} + {3730104000 -32400 1 HDT} + {3750663600 -36000 0 HST} + {3761553600 -32400 1 HDT} + {3782113200 -36000 0 HST} + {3793003200 -32400 1 HDT} + {3813562800 -36000 0 HST} + {3824452800 -32400 1 HDT} + {3845012400 -36000 0 HST} + {3855902400 -32400 1 HDT} + {3876462000 -36000 0 HST} + {3887352000 -32400 1 HDT} + {3907911600 -36000 0 HST} + {3919406400 -32400 1 HDT} + {3939966000 -36000 0 HST} + {3950856000 -32400 1 HDT} + {3971415600 -36000 0 HST} + {3982305600 -32400 1 HDT} + {4002865200 -36000 0 HST} + {4013755200 -32400 1 HDT} + {4034314800 -36000 0 HST} + {4045204800 -32400 1 HDT} + {4065764400 -36000 0 HST} + {4076654400 -32400 1 HDT} + {4097214000 -36000 0 HST} } diff --git a/library/tzdata/America/Antigua b/library/tzdata/America/Antigua index 5433e9b..be0c88e 100644 --- a/library/tzdata/America/Antigua +++ b/library/tzdata/America/Antigua @@ -1,7 +1,5 @@ # created by tools/tclZIC.tcl - do not edit - -set TZData(:America/Antigua) { - {-9223372036854775808 -14832 0 LMT} - {-1825098768 -18000 0 EST} - {-599598000 -14400 0 AST} +if {![info exists TZData(America/Port_of_Spain)]} { + LoadTimeZoneFile America/Port_of_Spain } +set TZData(:America/Antigua) $TZData(:America/Port_of_Spain) diff --git a/library/tzdata/America/Cayman b/library/tzdata/America/Cayman index 3e2e3cc..92ce5e2 100644 --- a/library/tzdata/America/Cayman +++ b/library/tzdata/America/Cayman @@ -1,7 +1,5 @@ # created by tools/tclZIC.tcl - do not edit - -set TZData(:America/Cayman) { - {-9223372036854775808 -19532 0 LMT} - {-2524502068 -18431 0 KMT} - {-1827687169 -18000 0 EST} +if {![info exists TZData(America/Panama)]} { + LoadTimeZoneFile America/Panama } +set TZData(:America/Cayman) $TZData(:America/Panama) diff --git a/library/tzdata/America/Montreal b/library/tzdata/America/Montreal index bebe7dc..0ead8ee 100644 --- a/library/tzdata/America/Montreal +++ b/library/tzdata/America/Montreal @@ -1,366 +1,5 @@ # created by tools/tclZIC.tcl - do not edit - -set TZData(:America/Montreal) { - {-9223372036854775808 -17656 0 LMT} - {-2713892744 -18000 0 EST} - {-1665334800 -14400 1 EDT} - {-1662753600 -18000 0 EST} - {-1640977200 -18000 0 EST} - {-1632070800 -14400 1 EDT} - {-1615140000 -18000 0 EST} - {-1609441200 -18000 0 EST} - {-1601742600 -14400 1 EDT} - {-1583775000 -18000 0 EST} - {-1567355400 -14400 1 EDT} - {-1554053400 -18000 0 EST} - {-1535907600 -14400 1 EDT} - {-1522603800 -18000 0 EST} - {-1504458000 -14400 1 EDT} - {-1491154200 -18000 0 EST} - {-1439830800 -14400 1 EDT} - {-1428255000 -18000 0 EST} - {-1409504400 -14400 1 EDT} - {-1396805400 -18000 0 EST} - {-1378054800 -14400 1 EDT} - {-1365355800 -18000 0 EST} - {-1346612400 -14400 1 EDT} - {-1333915200 -18000 0 EST} - {-1315162800 -14400 1 EDT} - {-1301860800 -18000 0 EST} - {-1283713200 -14400 1 EDT} - {-1270411200 -18000 0 EST} - {-1252263600 -14400 1 EDT} - {-1238961600 -18000 0 EST} - {-1220814000 -14400 1 EDT} - {-1207512000 -18000 0 EST} - {-1188759600 -14400 1 EDT} - {-1176062400 -18000 0 EST} - {-1157310000 -14400 1 EDT} - {-1144008000 -18000 0 EST} - {-1125860400 -14400 1 EDT} - {-1112558400 -18000 0 EST} - {-1094410800 -14400 1 EDT} - {-1081108800 -18000 0 EST} - {-1062961200 -14400 1 EDT} - {-1049659200 -18000 0 EST} - {-1031511600 -14400 1 EDT} - {-1018209600 -18000 0 EST} - {-1000062000 -14400 1 EDT} - {-986760000 -18000 0 EST} - {-968007600 -14400 1 EDT} - {-955310400 -18000 0 EST} - {-936558000 -14400 1 EDT} - {-880218000 -14400 0 EWT} - {-769395600 -14400 1 EPT} - {-765396000 -18000 0 EST} - {-757364400 -18000 0 EST} - {-747248400 -14400 1 EDT} - {-733946400 -18000 0 EST} - {-715798800 -14400 1 EDT} - {-702496800 -18000 0 EST} - {-684349200 -14400 1 EDT} - {-671047200 -18000 0 EST} - {-652899600 -14400 1 EDT} - {-636573600 -18000 0 EST} - {-620845200 -14400 1 EDT} - {-605124000 -18000 0 EST} - {-589395600 -14400 1 EDT} - {-576093600 -18000 0 EST} - {-557946000 -14400 1 EDT} - {-544644000 -18000 0 EST} - {-526496400 -14400 1 EDT} - {-513194400 -18000 0 EST} - {-495046800 -14400 1 EDT} - {-481744800 -18000 0 EST} - {-463597200 -14400 1 EDT} - {-450295200 -18000 0 EST} - {-431542800 -14400 1 EDT} - {-418240800 -18000 0 EST} - {-400093200 -14400 1 EDT} - {-384372000 -18000 0 EST} - {-368643600 -14400 1 EDT} - {-352922400 -18000 0 EST} - {-337194000 -14400 1 EDT} - {-321472800 -18000 0 EST} - {-305744400 -14400 1 EDT} - {-289418400 -18000 0 EST} - {-273690000 -14400 1 EDT} - {-257968800 -18000 0 EST} - {-242240400 -14400 1 EDT} - {-226519200 -18000 0 EST} - {-210790800 -14400 1 EDT} - {-195069600 -18000 0 EST} - {-179341200 -14400 1 EDT} - {-163620000 -18000 0 EST} - {-147891600 -14400 1 EDT} - {-131565600 -18000 0 EST} - {-116442000 -14400 1 EDT} - {-100116000 -18000 0 EST} - {-84387600 -14400 1 EDT} - {-68666400 -18000 0 EST} - {-52938000 -14400 1 EDT} - {-37216800 -18000 0 EST} - {-21488400 -14400 1 EDT} - {-5767200 -18000 0 EST} - {9961200 -14400 1 EDT} - {25682400 -18000 0 EST} - {41410800 -14400 1 EDT} - {57736800 -18000 0 EST} - {73465200 -14400 1 EDT} - {89186400 -18000 0 EST} - {104914800 -14400 1 EDT} - {120636000 -18000 0 EST} - {126248400 -18000 0 EST} - {136364400 -14400 1 EDT} - {152085600 -18000 0 EST} - {167814000 -14400 1 EDT} - {183535200 -18000 0 EST} - {199263600 -14400 1 EDT} - {215589600 -18000 0 EST} - {230713200 -14400 1 EDT} - {247039200 -18000 0 EST} - {262767600 -14400 1 EDT} - {278488800 -18000 0 EST} - {294217200 -14400 1 EDT} - {309938400 -18000 0 EST} - {325666800 -14400 1 EDT} - {341388000 -18000 0 EST} - {357116400 -14400 1 EDT} - {372837600 -18000 0 EST} - {388566000 -14400 1 EDT} - {404892000 -18000 0 EST} - {420015600 -14400 1 EDT} - {436341600 -18000 0 EST} - {452070000 -14400 1 EDT} - {467791200 -18000 0 EST} - {483519600 -14400 1 EDT} - {499240800 -18000 0 EST} - {514969200 -14400 1 EDT} - {530690400 -18000 0 EST} - {544604400 -14400 1 EDT} - {562140000 -18000 0 EST} - {576054000 -14400 1 EDT} - {594194400 -18000 0 EST} - {607503600 -14400 1 EDT} - {625644000 -18000 0 EST} - {638953200 -14400 1 EDT} - {657093600 -18000 0 EST} - {671007600 -14400 1 EDT} - {688543200 -18000 0 EST} - {702457200 -14400 1 EDT} - {719992800 -18000 0 EST} - {733906800 -14400 1 EDT} - {752047200 -18000 0 EST} - {765356400 -14400 1 EDT} - {783496800 -18000 0 EST} - {796806000 -14400 1 EDT} - {814946400 -18000 0 EST} - {828860400 -14400 1 EDT} - {846396000 -18000 0 EST} - {860310000 -14400 1 EDT} - {877845600 -18000 0 EST} - {891759600 -14400 1 EDT} - {909295200 -18000 0 EST} - {923209200 -14400 1 EDT} - {941349600 -18000 0 EST} - {954658800 -14400 1 EDT} - {972799200 -18000 0 EST} - {986108400 -14400 1 EDT} - {1004248800 -18000 0 EST} - {1018162800 -14400 1 EDT} - {1035698400 -18000 0 EST} - {1049612400 -14400 1 EDT} - {1067148000 -18000 0 EST} - {1081062000 -14400 1 EDT} - {1099202400 -18000 0 EST} - {1112511600 -14400 1 EDT} - {1130652000 -18000 0 EST} - {1143961200 -14400 1 EDT} - {1162101600 -18000 0 EST} - {1173596400 -14400 1 EDT} - {1194156000 -18000 0 EST} - {1205046000 -14400 1 EDT} - {1225605600 -18000 0 EST} - {1236495600 -14400 1 EDT} - {1257055200 -18000 0 EST} - {1268550000 -14400 1 EDT} - {1289109600 -18000 0 EST} - {1299999600 -14400 1 EDT} - {1320559200 -18000 0 EST} - {1331449200 -14400 1 EDT} - {1352008800 -18000 0 EST} - {1362898800 -14400 1 EDT} - {1383458400 -18000 0 EST} - {1394348400 -14400 1 EDT} - {1414908000 -18000 0 EST} - {1425798000 -14400 1 EDT} - {1446357600 -18000 0 EST} - {1457852400 -14400 1 EDT} - {1478412000 -18000 0 EST} - {1489302000 -14400 1 EDT} - {1509861600 -18000 0 EST} - {1520751600 -14400 1 EDT} - {1541311200 -18000 0 EST} - {1552201200 -14400 1 EDT} - {1572760800 -18000 0 EST} - {1583650800 -14400 1 EDT} - {1604210400 -18000 0 EST} - {1615705200 -14400 1 EDT} - {1636264800 -18000 0 EST} - {1647154800 -14400 1 EDT} - {1667714400 -18000 0 EST} - {1678604400 -14400 1 EDT} - {1699164000 -18000 0 EST} - {1710054000 -14400 1 EDT} - {1730613600 -18000 0 EST} - {1741503600 -14400 1 EDT} - {1762063200 -18000 0 EST} - {1772953200 -14400 1 EDT} - {1793512800 -18000 0 EST} - {1805007600 -14400 1 EDT} - {1825567200 -18000 0 EST} - {1836457200 -14400 1 EDT} - {1857016800 -18000 0 EST} - {1867906800 -14400 1 EDT} - {1888466400 -18000 0 EST} - {1899356400 -14400 1 EDT} - {1919916000 -18000 0 EST} - {1930806000 -14400 1 EDT} - {1951365600 -18000 0 EST} - {1962860400 -14400 1 EDT} - {1983420000 -18000 0 EST} - {1994310000 -14400 1 EDT} - {2014869600 -18000 0 EST} - {2025759600 -14400 1 EDT} - {2046319200 -18000 0 EST} - {2057209200 -14400 1 EDT} - {2077768800 -18000 0 EST} - {2088658800 -14400 1 EDT} - {2109218400 -18000 0 EST} - {2120108400 -14400 1 EDT} - {2140668000 -18000 0 EST} - {2152162800 -14400 1 EDT} - {2172722400 -18000 0 EST} - {2183612400 -14400 1 EDT} - {2204172000 -18000 0 EST} - {2215062000 -14400 1 EDT} - {2235621600 -18000 0 EST} - {2246511600 -14400 1 EDT} - {2267071200 -18000 0 EST} - {2277961200 -14400 1 EDT} - {2298520800 -18000 0 EST} - {2309410800 -14400 1 EDT} - {2329970400 -18000 0 EST} - {2341465200 -14400 1 EDT} - {2362024800 -18000 0 EST} - {2372914800 -14400 1 EDT} - {2393474400 -18000 0 EST} - {2404364400 -14400 1 EDT} - {2424924000 -18000 0 EST} - {2435814000 -14400 1 EDT} - {2456373600 -18000 0 EST} - {2467263600 -14400 1 EDT} - {2487823200 -18000 0 EST} - {2499318000 -14400 1 EDT} - {2519877600 -18000 0 EST} - {2530767600 -14400 1 EDT} - {2551327200 -18000 0 EST} - {2562217200 -14400 1 EDT} - {2582776800 -18000 0 EST} - {2593666800 -14400 1 EDT} - {2614226400 -18000 0 EST} - {2625116400 -14400 1 EDT} - {2645676000 -18000 0 EST} - {2656566000 -14400 1 EDT} - {2677125600 -18000 0 EST} - {2688620400 -14400 1 EDT} - {2709180000 -18000 0 EST} - {2720070000 -14400 1 EDT} - {2740629600 -18000 0 EST} - {2751519600 -14400 1 EDT} - {2772079200 -18000 0 EST} - {2782969200 -14400 1 EDT} - {2803528800 -18000 0 EST} - {2814418800 -14400 1 EDT} - {2834978400 -18000 0 EST} - {2846473200 -14400 1 EDT} - {2867032800 -18000 0 EST} - {2877922800 -14400 1 EDT} - {2898482400 -18000 0 EST} - {2909372400 -14400 1 EDT} - {2929932000 -18000 0 EST} - {2940822000 -14400 1 EDT} - {2961381600 -18000 0 EST} - {2972271600 -14400 1 EDT} - {2992831200 -18000 0 EST} - {3003721200 -14400 1 EDT} - {3024280800 -18000 0 EST} - {3035775600 -14400 1 EDT} - {3056335200 -18000 0 EST} - {3067225200 -14400 1 EDT} - {3087784800 -18000 0 EST} - {3098674800 -14400 1 EDT} - {3119234400 -18000 0 EST} - {3130124400 -14400 1 EDT} - {3150684000 -18000 0 EST} - {3161574000 -14400 1 EDT} - {3182133600 -18000 0 EST} - {3193023600 -14400 1 EDT} - {3213583200 -18000 0 EST} - {3225078000 -14400 1 EDT} - {3245637600 -18000 0 EST} - {3256527600 -14400 1 EDT} - {3277087200 -18000 0 EST} - {3287977200 -14400 1 EDT} - {3308536800 -18000 0 EST} - {3319426800 -14400 1 EDT} - {3339986400 -18000 0 EST} - {3350876400 -14400 1 EDT} - {3371436000 -18000 0 EST} - {3382930800 -14400 1 EDT} - {3403490400 -18000 0 EST} - {3414380400 -14400 1 EDT} - {3434940000 -18000 0 EST} - {3445830000 -14400 1 EDT} - {3466389600 -18000 0 EST} - {3477279600 -14400 1 EDT} - {3497839200 -18000 0 EST} - {3508729200 -14400 1 EDT} - {3529288800 -18000 0 EST} - {3540178800 -14400 1 EDT} - {3560738400 -18000 0 EST} - {3572233200 -14400 1 EDT} - {3592792800 -18000 0 EST} - {3603682800 -14400 1 EDT} - {3624242400 -18000 0 EST} - {3635132400 -14400 1 EDT} - {3655692000 -18000 0 EST} - {3666582000 -14400 1 EDT} - {3687141600 -18000 0 EST} - {3698031600 -14400 1 EDT} - {3718591200 -18000 0 EST} - {3730086000 -14400 1 EDT} - {3750645600 -18000 0 EST} - {3761535600 -14400 1 EDT} - {3782095200 -18000 0 EST} - {3792985200 -14400 1 EDT} - {3813544800 -18000 0 EST} - {3824434800 -14400 1 EDT} - {3844994400 -18000 0 EST} - {3855884400 -14400 1 EDT} - {3876444000 -18000 0 EST} - {3887334000 -14400 1 EDT} - {3907893600 -18000 0 EST} - {3919388400 -14400 1 EDT} - {3939948000 -18000 0 EST} - {3950838000 -14400 1 EDT} - {3971397600 -18000 0 EST} - {3982287600 -14400 1 EDT} - {4002847200 -18000 0 EST} - {4013737200 -14400 1 EDT} - {4034296800 -18000 0 EST} - {4045186800 -14400 1 EDT} - {4065746400 -18000 0 EST} - {4076636400 -14400 1 EDT} - {4097196000 -18000 0 EST} +if {![info exists TZData(America/Toronto)]} { + LoadTimeZoneFile America/Toronto } +set TZData(:America/Montreal) $TZData(:America/Toronto) diff --git a/library/tzdata/America/Santiago b/library/tzdata/America/Santiago index 29c2a93..b6d9b38 100644 --- a/library/tzdata/America/Santiago +++ b/library/tzdata/America/Santiago @@ -3,9 +3,9 @@ set TZData(:America/Santiago) { {-9223372036854775808 -16966 0 LMT} {-2524504634 -16966 0 SMT} - {-1893439034 -18000 0 CLT} + {-1892661434 -18000 0 CLT} {-1688410800 -16966 0 SMT} - {-1619983034 -14400 0 CLT} + {-1619205434 -14400 0 CLT} {-1593806400 -16966 0 SMT} {-1335986234 -18000 0 CLT} {-1335985200 -14400 1 CLST} @@ -18,13 +18,13 @@ set TZData(:America/Santiago) { {-1222977600 -18000 0 CLT} {-1209754800 -14400 1 CLST} {-1191355200 -18000 0 CLT} - {-1178132400 -14400 1 CLST} + {-1178132400 -14400 0 CLT} {-870552000 -18000 0 CLT} - {-865278000 -14400 1 CLST} - {-740520000 -14400 1 CLST} - {-736376400 -18000 0 CLT} + {-865278000 -14400 0 CLT} + {-740520000 -10800 1 CLST} + {-736376400 -14400 0 CLT} {-718056000 -18000 0 CLT} - {-713646000 -14400 0 CLT} + {-713649600 -14400 0 CLT} {-36619200 -10800 1 CLST} {-23922000 -14400 0 CLT} {-3355200 -10800 1 CLST} @@ -65,10 +65,10 @@ set TZData(:America/Santiago) { {545194800 -14400 0 CLT} {560923200 -10800 1 CLST} {574225200 -14400 0 CLT} - {591768000 -10800 1 CLST} + {592372800 -10800 1 CLST} {605674800 -14400 0 CLT} {624427200 -10800 1 CLST} - {637729200 -14400 0 CLT} + {637124400 -14400 0 CLT} {653457600 -10800 1 CLST} {668574000 -14400 0 CLT} {687326400 -10800 1 CLST} diff --git a/library/tzdata/Antarctica/Palmer b/library/tzdata/Antarctica/Palmer index f12528b..2c43861 100644 --- a/library/tzdata/Antarctica/Palmer +++ b/library/tzdata/Antarctica/Palmer @@ -28,10 +28,10 @@ set TZData(:Antarctica/Palmer) { {545194800 -14400 0 CLT} {560923200 -10800 1 CLST} {574225200 -14400 0 CLT} - {591768000 -10800 1 CLST} + {592372800 -10800 1 CLST} {605674800 -14400 0 CLT} {624427200 -10800 1 CLST} - {637729200 -14400 0 CLT} + {637124400 -14400 0 CLT} {653457600 -10800 1 CLST} {668574000 -14400 0 CLT} {687326400 -10800 1 CLST} diff --git a/library/tzdata/Asia/Choibalsan b/library/tzdata/Asia/Choibalsan index 3d42617..2bcf7f7 100644 --- a/library/tzdata/Asia/Choibalsan +++ b/library/tzdata/Asia/Choibalsan @@ -48,4 +48,175 @@ set TZData(:Asia/Choibalsan) { {1127491200 32400 0 CHOT} {1143219600 36000 1 CHOST} {1159545600 32400 0 CHOT} + {1206889200 28800 0 CHOT} + {1427479200 32400 1 CHOST} + {1443193200 28800 0 CHOT} + {1458928800 32400 1 CHOST} + {1474642800 28800 0 CHOT} + {1490378400 32400 1 CHOST} + {1506697200 28800 0 CHOT} + {1522432800 32400 1 CHOST} + {1538146800 28800 0 CHOT} + {1553882400 32400 1 CHOST} + {1569596400 28800 0 CHOT} + {1585332000 32400 1 CHOST} + {1601046000 28800 0 CHOT} + {1616781600 32400 1 CHOST} + {1632495600 28800 0 CHOT} + {1648231200 32400 1 CHOST} + {1663945200 28800 0 CHOT} + {1679680800 32400 1 CHOST} + {1695999600 28800 0 CHOT} + {1711735200 32400 1 CHOST} + {1727449200 28800 0 CHOT} + {1743184800 32400 1 CHOST} + {1758898800 28800 0 CHOT} + {1774634400 32400 1 CHOST} + {1790348400 28800 0 CHOT} + {1806084000 32400 1 CHOST} + {1821798000 28800 0 CHOT} + {1837533600 32400 1 CHOST} + {1853852400 28800 0 CHOT} + {1869588000 32400 1 CHOST} + {1885302000 28800 0 CHOT} + {1901037600 32400 1 CHOST} + {1916751600 28800 0 CHOT} + {1932487200 32400 1 CHOST} + {1948201200 28800 0 CHOT} + {1963936800 32400 1 CHOST} + {1979650800 28800 0 CHOT} + {1995386400 32400 1 CHOST} + {2011100400 28800 0 CHOT} + {2026836000 32400 1 CHOST} + {2043154800 28800 0 CHOT} + {2058890400 32400 1 CHOST} + {2074604400 28800 0 CHOT} + {2090340000 32400 1 CHOST} + {2106054000 28800 0 CHOT} + {2121789600 32400 1 CHOST} + {2137503600 28800 0 CHOT} + {2153239200 32400 1 CHOST} + {2168953200 28800 0 CHOT} + {2184688800 32400 1 CHOST} + {2200402800 28800 0 CHOT} + {2216743200 32400 1 CHOST} + {2232457200 28800 0 CHOT} + {2248192800 32400 1 CHOST} + {2263906800 28800 0 CHOT} + {2279642400 32400 1 CHOST} + {2295356400 28800 0 CHOT} + {2311092000 32400 1 CHOST} + {2326806000 28800 0 CHOT} + {2342541600 32400 1 CHOST} + {2358255600 28800 0 CHOT} + {2373991200 32400 1 CHOST} + {2390310000 28800 0 CHOT} + {2406045600 32400 1 CHOST} + {2421759600 28800 0 CHOT} + {2437495200 32400 1 CHOST} + {2453209200 28800 0 CHOT} + {2468944800 32400 1 CHOST} + {2484658800 28800 0 CHOT} + {2500394400 32400 1 CHOST} + {2516108400 28800 0 CHOT} + {2531844000 32400 1 CHOST} + {2547558000 28800 0 CHOT} + {2563293600 32400 1 CHOST} + {2579612400 28800 0 CHOT} + {2595348000 32400 1 CHOST} + {2611062000 28800 0 CHOT} + {2626797600 32400 1 CHOST} + {2642511600 28800 0 CHOT} + {2658247200 32400 1 CHOST} + {2673961200 28800 0 CHOT} + {2689696800 32400 1 CHOST} + {2705410800 28800 0 CHOT} + {2721146400 32400 1 CHOST} + {2737465200 28800 0 CHOT} + {2753200800 32400 1 CHOST} + {2768914800 28800 0 CHOT} + {2784650400 32400 1 CHOST} + {2800364400 28800 0 CHOT} + {2816100000 32400 1 CHOST} + {2831814000 28800 0 CHOT} + {2847549600 32400 1 CHOST} + {2863263600 28800 0 CHOT} + {2878999200 32400 1 CHOST} + {2894713200 28800 0 CHOT} + {2910448800 32400 1 CHOST} + {2926767600 28800 0 CHOT} + {2942503200 32400 1 CHOST} + {2958217200 28800 0 CHOT} + {2973952800 32400 1 CHOST} + {2989666800 28800 0 CHOT} + {3005402400 32400 1 CHOST} + {3021116400 28800 0 CHOT} + {3036852000 32400 1 CHOST} + {3052566000 28800 0 CHOT} + {3068301600 32400 1 CHOST} + {3084015600 28800 0 CHOT} + {3100356000 32400 1 CHOST} + {3116070000 28800 0 CHOT} + {3131805600 32400 1 CHOST} + {3147519600 28800 0 CHOT} + {3163255200 32400 1 CHOST} + {3178969200 28800 0 CHOT} + {3194704800 32400 1 CHOST} + {3210418800 28800 0 CHOT} + {3226154400 32400 1 CHOST} + {3241868400 28800 0 CHOT} + {3257604000 32400 1 CHOST} + {3273922800 28800 0 CHOT} + {3289658400 32400 1 CHOST} + {3305372400 28800 0 CHOT} + {3321108000 32400 1 CHOST} + {3336822000 28800 0 CHOT} + {3352557600 32400 1 CHOST} + {3368271600 28800 0 CHOT} + {3384007200 32400 1 CHOST} + {3399721200 28800 0 CHOT} + {3415456800 32400 1 CHOST} + {3431170800 28800 0 CHOT} + {3446906400 32400 1 CHOST} + {3463225200 28800 0 CHOT} + {3478960800 32400 1 CHOST} + {3494674800 28800 0 CHOT} + {3510410400 32400 1 CHOST} + {3526124400 28800 0 CHOT} + {3541860000 32400 1 CHOST} + {3557574000 28800 0 CHOT} + {3573309600 32400 1 CHOST} + {3589023600 28800 0 CHOT} + {3604759200 32400 1 CHOST} + {3621078000 28800 0 CHOT} + {3636813600 32400 1 CHOST} + {3652527600 28800 0 CHOT} + {3668263200 32400 1 CHOST} + {3683977200 28800 0 CHOT} + {3699712800 32400 1 CHOST} + {3715426800 28800 0 CHOT} + {3731162400 32400 1 CHOST} + {3746876400 28800 0 CHOT} + {3762612000 32400 1 CHOST} + {3778326000 28800 0 CHOT} + {3794061600 32400 1 CHOST} + {3810380400 28800 0 CHOT} + {3826116000 32400 1 CHOST} + {3841830000 28800 0 CHOT} + {3857565600 32400 1 CHOST} + {3873279600 28800 0 CHOT} + {3889015200 32400 1 CHOST} + {3904729200 28800 0 CHOT} + {3920464800 32400 1 CHOST} + {3936178800 28800 0 CHOT} + {3951914400 32400 1 CHOST} + {3967628400 28800 0 CHOT} + {3983968800 32400 1 CHOST} + {3999682800 28800 0 CHOT} + {4015418400 32400 1 CHOST} + {4031132400 28800 0 CHOT} + {4046868000 32400 1 CHOST} + {4062582000 28800 0 CHOT} + {4078317600 32400 1 CHOST} + {4094031600 28800 0 CHOT} } diff --git a/library/tzdata/Asia/Gaza b/library/tzdata/Asia/Gaza index 8ec9c5b..805b6b7 100644 --- a/library/tzdata/Asia/Gaza +++ b/library/tzdata/Asia/Gaza @@ -104,175 +104,175 @@ set TZData(:Asia/Gaza) { {1364508000 10800 1 EEST} {1380229200 7200 0 EET} {1395957600 10800 1 EEST} - {1411678800 7200 0 EET} - {1427407200 10800 1 EEST} - {1443128400 7200 0 EET} - {1459461600 10800 1 EEST} - {1474578000 7200 0 EET} - {1490911200 10800 1 EEST} - {1506027600 7200 0 EET} - {1522360800 10800 1 EEST} - {1537477200 7200 0 EET} - {1553810400 10800 1 EEST} - {1569531600 7200 0 EET} - {1585260000 10800 1 EEST} - {1600981200 7200 0 EET} - {1616709600 10800 1 EEST} - {1632430800 7200 0 EET} - {1648764000 10800 1 EEST} - {1663880400 7200 0 EET} - {1680213600 10800 1 EEST} - {1695330000 7200 0 EET} - {1711663200 10800 1 EEST} - {1727384400 7200 0 EET} - {1743112800 10800 1 EEST} - {1758834000 7200 0 EET} - {1774562400 10800 1 EEST} - {1790283600 7200 0 EET} - {1806012000 10800 1 EEST} - {1821733200 7200 0 EET} - {1838066400 10800 1 EEST} - {1853182800 7200 0 EET} - {1869516000 10800 1 EEST} - {1884632400 7200 0 EET} - {1900965600 10800 1 EEST} - {1916686800 7200 0 EET} - {1932415200 10800 1 EEST} - {1948136400 7200 0 EET} - {1963864800 10800 1 EEST} - {1979586000 7200 0 EET} - {1995919200 10800 1 EEST} - {2011035600 7200 0 EET} - {2027368800 10800 1 EEST} - {2042485200 7200 0 EET} - {2058818400 10800 1 EEST} - {2073934800 7200 0 EET} - {2090268000 10800 1 EEST} - {2105989200 7200 0 EET} - {2121717600 10800 1 EEST} - {2137438800 7200 0 EET} - {2153167200 10800 1 EEST} - {2168888400 7200 0 EET} - {2185221600 10800 1 EEST} - {2200338000 7200 0 EET} - {2216671200 10800 1 EEST} - {2231787600 7200 0 EET} - {2248120800 10800 1 EEST} - {2263842000 7200 0 EET} - {2279570400 10800 1 EEST} - {2295291600 7200 0 EET} - {2311020000 10800 1 EEST} - {2326741200 7200 0 EET} - {2343074400 10800 1 EEST} - {2358190800 7200 0 EET} - {2374524000 10800 1 EEST} - {2389640400 7200 0 EET} - {2405973600 10800 1 EEST} - {2421090000 7200 0 EET} - {2437423200 10800 1 EEST} - {2453144400 7200 0 EET} - {2468872800 10800 1 EEST} - {2484594000 7200 0 EET} - {2500322400 10800 1 EEST} - {2516043600 7200 0 EET} - {2532376800 10800 1 EEST} - {2547493200 7200 0 EET} - {2563826400 10800 1 EEST} - {2578942800 7200 0 EET} - {2595276000 10800 1 EEST} - {2610997200 7200 0 EET} - {2626725600 10800 1 EEST} - {2642446800 7200 0 EET} - {2658175200 10800 1 EEST} - {2673896400 7200 0 EET} - {2689624800 10800 1 EEST} - {2705346000 7200 0 EET} - {2721679200 10800 1 EEST} - {2736795600 7200 0 EET} - {2753128800 10800 1 EEST} - {2768245200 7200 0 EET} - {2784578400 10800 1 EEST} - {2800299600 7200 0 EET} - {2816028000 10800 1 EEST} - {2831749200 7200 0 EET} - {2847477600 10800 1 EEST} - {2863198800 7200 0 EET} - {2879532000 10800 1 EEST} - {2894648400 7200 0 EET} - {2910981600 10800 1 EEST} - {2926098000 7200 0 EET} - {2942431200 10800 1 EEST} - {2957547600 7200 0 EET} - {2973880800 10800 1 EEST} - {2989602000 7200 0 EET} - {3005330400 10800 1 EEST} - {3021051600 7200 0 EET} - {3036780000 10800 1 EEST} - {3052501200 7200 0 EET} - {3068834400 10800 1 EEST} - {3083950800 7200 0 EET} - {3100284000 10800 1 EEST} - {3115400400 7200 0 EET} - {3131733600 10800 1 EEST} - {3147454800 7200 0 EET} - {3163183200 10800 1 EEST} - {3178904400 7200 0 EET} - {3194632800 10800 1 EEST} - {3210354000 7200 0 EET} - {3226687200 10800 1 EEST} - {3241803600 7200 0 EET} - {3258136800 10800 1 EEST} - {3273253200 7200 0 EET} - {3289586400 10800 1 EEST} - {3304702800 7200 0 EET} - {3321036000 10800 1 EEST} - {3336757200 7200 0 EET} - {3352485600 10800 1 EEST} - {3368206800 7200 0 EET} - {3383935200 10800 1 EEST} - {3399656400 7200 0 EET} - {3415989600 10800 1 EEST} - {3431106000 7200 0 EET} - {3447439200 10800 1 EEST} - {3462555600 7200 0 EET} - {3478888800 10800 1 EEST} - {3494610000 7200 0 EET} - {3510338400 10800 1 EEST} - {3526059600 7200 0 EET} - {3541788000 10800 1 EEST} - {3557509200 7200 0 EET} - {3573237600 10800 1 EEST} - {3588958800 7200 0 EET} - {3605292000 10800 1 EEST} - {3620408400 7200 0 EET} - {3636741600 10800 1 EEST} - {3651858000 7200 0 EET} - {3668191200 10800 1 EEST} - {3683912400 7200 0 EET} - {3699640800 10800 1 EEST} - {3715362000 7200 0 EET} - {3731090400 10800 1 EEST} - {3746811600 7200 0 EET} - {3763144800 10800 1 EEST} - {3778261200 7200 0 EET} - {3794594400 10800 1 EEST} - {3809710800 7200 0 EET} - {3826044000 10800 1 EEST} - {3841160400 7200 0 EET} - {3857493600 10800 1 EEST} - {3873214800 7200 0 EET} - {3888943200 10800 1 EEST} - {3904664400 7200 0 EET} - {3920392800 10800 1 EEST} - {3936114000 7200 0 EET} - {3952447200 10800 1 EEST} - {3967563600 7200 0 EET} - {3983896800 10800 1 EEST} - {3999013200 7200 0 EET} - {4015346400 10800 1 EEST} - {4031067600 7200 0 EET} - {4046796000 10800 1 EEST} - {4062517200 7200 0 EET} - {4078245600 10800 1 EEST} - {4093966800 7200 0 EET} + {1414098000 7200 0 EET} + {1427493600 10800 1 EEST} + {1445547600 7200 0 EET} + {1458943200 10800 1 EEST} + {1476997200 7200 0 EET} + {1490997600 10800 1 EEST} + {1509051600 7200 0 EET} + {1522447200 10800 1 EEST} + {1540501200 7200 0 EET} + {1553896800 10800 1 EEST} + {1571950800 7200 0 EET} + {1585346400 10800 1 EEST} + {1603400400 7200 0 EET} + {1616796000 10800 1 EEST} + {1634850000 7200 0 EET} + {1648245600 10800 1 EEST} + {1666299600 7200 0 EET} + {1680300000 10800 1 EEST} + {1698354000 7200 0 EET} + {1711749600 10800 1 EEST} + {1729803600 7200 0 EET} + {1743199200 10800 1 EEST} + {1761253200 7200 0 EET} + {1774648800 10800 1 EEST} + {1792702800 7200 0 EET} + {1806098400 10800 1 EEST} + {1824152400 7200 0 EET} + {1838152800 10800 1 EEST} + {1856206800 7200 0 EET} + {1869602400 10800 1 EEST} + {1887656400 7200 0 EET} + {1901052000 10800 1 EEST} + {1919106000 7200 0 EET} + {1932501600 10800 1 EEST} + {1950555600 7200 0 EET} + {1963951200 10800 1 EEST} + {1982005200 7200 0 EET} + {1995400800 10800 1 EEST} + {2013454800 7200 0 EET} + {2027455200 10800 1 EEST} + {2045509200 7200 0 EET} + {2058904800 10800 1 EEST} + {2076958800 7200 0 EET} + {2090354400 10800 1 EEST} + {2108408400 7200 0 EET} + {2121804000 10800 1 EEST} + {2139858000 7200 0 EET} + {2153253600 10800 1 EEST} + {2171307600 7200 0 EET} + {2184703200 10800 1 EEST} + {2202757200 7200 0 EET} + {2216757600 10800 1 EEST} + {2234811600 7200 0 EET} + {2248207200 10800 1 EEST} + {2266261200 7200 0 EET} + {2279656800 10800 1 EEST} + {2297710800 7200 0 EET} + {2311106400 10800 1 EEST} + {2329160400 7200 0 EET} + {2342556000 10800 1 EEST} + {2360610000 7200 0 EET} + {2374610400 10800 1 EEST} + {2392664400 7200 0 EET} + {2406060000 10800 1 EEST} + {2424114000 7200 0 EET} + {2437509600 10800 1 EEST} + {2455563600 7200 0 EET} + {2468959200 10800 1 EEST} + {2487013200 7200 0 EET} + {2500408800 10800 1 EEST} + {2518462800 7200 0 EET} + {2531858400 10800 1 EEST} + {2549912400 7200 0 EET} + {2563912800 10800 1 EEST} + {2581966800 7200 0 EET} + {2595362400 10800 1 EEST} + {2613416400 7200 0 EET} + {2626812000 10800 1 EEST} + {2644866000 7200 0 EET} + {2658261600 10800 1 EEST} + {2676315600 7200 0 EET} + {2689711200 10800 1 EEST} + {2707765200 7200 0 EET} + {2721765600 10800 1 EEST} + {2739819600 7200 0 EET} + {2753215200 10800 1 EEST} + {2771269200 7200 0 EET} + {2784664800 10800 1 EEST} + {2802718800 7200 0 EET} + {2816114400 10800 1 EEST} + {2834168400 7200 0 EET} + {2847564000 10800 1 EEST} + {2865618000 7200 0 EET} + {2879013600 10800 1 EEST} + {2897067600 7200 0 EET} + {2911068000 10800 1 EEST} + {2929122000 7200 0 EET} + {2942517600 10800 1 EEST} + {2960571600 7200 0 EET} + {2973967200 10800 1 EEST} + {2992021200 7200 0 EET} + {3005416800 10800 1 EEST} + {3023470800 7200 0 EET} + {3036866400 10800 1 EEST} + {3054920400 7200 0 EET} + {3068316000 10800 1 EEST} + {3086370000 7200 0 EET} + {3100370400 10800 1 EEST} + {3118424400 7200 0 EET} + {3131820000 10800 1 EEST} + {3149874000 7200 0 EET} + {3163269600 10800 1 EEST} + {3181323600 7200 0 EET} + {3194719200 10800 1 EEST} + {3212773200 7200 0 EET} + {3226168800 10800 1 EEST} + {3244222800 7200 0 EET} + {3258223200 10800 1 EEST} + {3276277200 7200 0 EET} + {3289672800 10800 1 EEST} + {3307726800 7200 0 EET} + {3321122400 10800 1 EEST} + {3339176400 7200 0 EET} + {3352572000 10800 1 EEST} + {3370626000 7200 0 EET} + {3384021600 10800 1 EEST} + {3402075600 7200 0 EET} + {3415471200 10800 1 EEST} + {3433525200 7200 0 EET} + {3447525600 10800 1 EEST} + {3465579600 7200 0 EET} + {3478975200 10800 1 EEST} + {3497029200 7200 0 EET} + {3510424800 10800 1 EEST} + {3528478800 7200 0 EET} + {3541874400 10800 1 EEST} + {3559928400 7200 0 EET} + {3573324000 10800 1 EEST} + {3591378000 7200 0 EET} + {3605378400 10800 1 EEST} + {3623432400 7200 0 EET} + {3636828000 10800 1 EEST} + {3654882000 7200 0 EET} + {3668277600 10800 1 EEST} + {3686331600 7200 0 EET} + {3699727200 10800 1 EEST} + {3717781200 7200 0 EET} + {3731176800 10800 1 EEST} + {3749230800 7200 0 EET} + {3762626400 10800 1 EEST} + {3780680400 7200 0 EET} + {3794680800 10800 1 EEST} + {3812734800 7200 0 EET} + {3826130400 10800 1 EEST} + {3844184400 7200 0 EET} + {3857580000 10800 1 EEST} + {3875634000 7200 0 EET} + {3889029600 10800 1 EEST} + {3907083600 7200 0 EET} + {3920479200 10800 1 EEST} + {3938533200 7200 0 EET} + {3951928800 10800 1 EEST} + {3969982800 7200 0 EET} + {3983983200 10800 1 EEST} + {4002037200 7200 0 EET} + {4015432800 10800 1 EEST} + {4033486800 7200 0 EET} + {4046882400 10800 1 EEST} + {4064936400 7200 0 EET} + {4078332000 10800 1 EEST} + {4096386000 7200 0 EET} } diff --git a/library/tzdata/Asia/Hebron b/library/tzdata/Asia/Hebron index 900ffad..9049d93 100644 --- a/library/tzdata/Asia/Hebron +++ b/library/tzdata/Asia/Hebron @@ -103,175 +103,175 @@ set TZData(:Asia/Hebron) { {1364508000 10800 1 EEST} {1380229200 7200 0 EET} {1395957600 10800 1 EEST} - {1411678800 7200 0 EET} - {1427407200 10800 1 EEST} - {1443128400 7200 0 EET} - {1459461600 10800 1 EEST} - {1474578000 7200 0 EET} - {1490911200 10800 1 EEST} - {1506027600 7200 0 EET} - {1522360800 10800 1 EEST} - {1537477200 7200 0 EET} - {1553810400 10800 1 EEST} - {1569531600 7200 0 EET} - {1585260000 10800 1 EEST} - {1600981200 7200 0 EET} - {1616709600 10800 1 EEST} - {1632430800 7200 0 EET} - {1648764000 10800 1 EEST} - {1663880400 7200 0 EET} - {1680213600 10800 1 EEST} - {1695330000 7200 0 EET} - {1711663200 10800 1 EEST} - {1727384400 7200 0 EET} - {1743112800 10800 1 EEST} - {1758834000 7200 0 EET} - {1774562400 10800 1 EEST} - {1790283600 7200 0 EET} - {1806012000 10800 1 EEST} - {1821733200 7200 0 EET} - {1838066400 10800 1 EEST} - {1853182800 7200 0 EET} - {1869516000 10800 1 EEST} - {1884632400 7200 0 EET} - {1900965600 10800 1 EEST} - {1916686800 7200 0 EET} - {1932415200 10800 1 EEST} - {1948136400 7200 0 EET} - {1963864800 10800 1 EEST} - {1979586000 7200 0 EET} - {1995919200 10800 1 EEST} - {2011035600 7200 0 EET} - {2027368800 10800 1 EEST} - {2042485200 7200 0 EET} - {2058818400 10800 1 EEST} - {2073934800 7200 0 EET} - {2090268000 10800 1 EEST} - {2105989200 7200 0 EET} - {2121717600 10800 1 EEST} - {2137438800 7200 0 EET} - {2153167200 10800 1 EEST} - {2168888400 7200 0 EET} - {2185221600 10800 1 EEST} - {2200338000 7200 0 EET} - {2216671200 10800 1 EEST} - {2231787600 7200 0 EET} - {2248120800 10800 1 EEST} - {2263842000 7200 0 EET} - {2279570400 10800 1 EEST} - {2295291600 7200 0 EET} - {2311020000 10800 1 EEST} - {2326741200 7200 0 EET} - {2343074400 10800 1 EEST} - {2358190800 7200 0 EET} - {2374524000 10800 1 EEST} - {2389640400 7200 0 EET} - {2405973600 10800 1 EEST} - {2421090000 7200 0 EET} - {2437423200 10800 1 EEST} - {2453144400 7200 0 EET} - {2468872800 10800 1 EEST} - {2484594000 7200 0 EET} - {2500322400 10800 1 EEST} - {2516043600 7200 0 EET} - {2532376800 10800 1 EEST} - {2547493200 7200 0 EET} - {2563826400 10800 1 EEST} - {2578942800 7200 0 EET} - {2595276000 10800 1 EEST} - {2610997200 7200 0 EET} - {2626725600 10800 1 EEST} - {2642446800 7200 0 EET} - {2658175200 10800 1 EEST} - {2673896400 7200 0 EET} - {2689624800 10800 1 EEST} - {2705346000 7200 0 EET} - {2721679200 10800 1 EEST} - {2736795600 7200 0 EET} - {2753128800 10800 1 EEST} - {2768245200 7200 0 EET} - {2784578400 10800 1 EEST} - {2800299600 7200 0 EET} - {2816028000 10800 1 EEST} - {2831749200 7200 0 EET} - {2847477600 10800 1 EEST} - {2863198800 7200 0 EET} - {2879532000 10800 1 EEST} - {2894648400 7200 0 EET} - {2910981600 10800 1 EEST} - {2926098000 7200 0 EET} - {2942431200 10800 1 EEST} - {2957547600 7200 0 EET} - {2973880800 10800 1 EEST} - {2989602000 7200 0 EET} - {3005330400 10800 1 EEST} - {3021051600 7200 0 EET} - {3036780000 10800 1 EEST} - {3052501200 7200 0 EET} - {3068834400 10800 1 EEST} - {3083950800 7200 0 EET} - {3100284000 10800 1 EEST} - {3115400400 7200 0 EET} - {3131733600 10800 1 EEST} - {3147454800 7200 0 EET} - {3163183200 10800 1 EEST} - {3178904400 7200 0 EET} - {3194632800 10800 1 EEST} - {3210354000 7200 0 EET} - {3226687200 10800 1 EEST} - {3241803600 7200 0 EET} - {3258136800 10800 1 EEST} - {3273253200 7200 0 EET} - {3289586400 10800 1 EEST} - {3304702800 7200 0 EET} - {3321036000 10800 1 EEST} - {3336757200 7200 0 EET} - {3352485600 10800 1 EEST} - {3368206800 7200 0 EET} - {3383935200 10800 1 EEST} - {3399656400 7200 0 EET} - {3415989600 10800 1 EEST} - {3431106000 7200 0 EET} - {3447439200 10800 1 EEST} - {3462555600 7200 0 EET} - {3478888800 10800 1 EEST} - {3494610000 7200 0 EET} - {3510338400 10800 1 EEST} - {3526059600 7200 0 EET} - {3541788000 10800 1 EEST} - {3557509200 7200 0 EET} - {3573237600 10800 1 EEST} - {3588958800 7200 0 EET} - {3605292000 10800 1 EEST} - {3620408400 7200 0 EET} - {3636741600 10800 1 EEST} - {3651858000 7200 0 EET} - {3668191200 10800 1 EEST} - {3683912400 7200 0 EET} - {3699640800 10800 1 EEST} - {3715362000 7200 0 EET} - {3731090400 10800 1 EEST} - {3746811600 7200 0 EET} - {3763144800 10800 1 EEST} - {3778261200 7200 0 EET} - {3794594400 10800 1 EEST} - {3809710800 7200 0 EET} - {3826044000 10800 1 EEST} - {3841160400 7200 0 EET} - {3857493600 10800 1 EEST} - {3873214800 7200 0 EET} - {3888943200 10800 1 EEST} - {3904664400 7200 0 EET} - {3920392800 10800 1 EEST} - {3936114000 7200 0 EET} - {3952447200 10800 1 EEST} - {3967563600 7200 0 EET} - {3983896800 10800 1 EEST} - {3999013200 7200 0 EET} - {4015346400 10800 1 EEST} - {4031067600 7200 0 EET} - {4046796000 10800 1 EEST} - {4062517200 7200 0 EET} - {4078245600 10800 1 EEST} - {4093966800 7200 0 EET} + {1414098000 7200 0 EET} + {1427493600 10800 1 EEST} + {1445547600 7200 0 EET} + {1458943200 10800 1 EEST} + {1476997200 7200 0 EET} + {1490997600 10800 1 EEST} + {1509051600 7200 0 EET} + {1522447200 10800 1 EEST} + {1540501200 7200 0 EET} + {1553896800 10800 1 EEST} + {1571950800 7200 0 EET} + {1585346400 10800 1 EEST} + {1603400400 7200 0 EET} + {1616796000 10800 1 EEST} + {1634850000 7200 0 EET} + {1648245600 10800 1 EEST} + {1666299600 7200 0 EET} + {1680300000 10800 1 EEST} + {1698354000 7200 0 EET} + {1711749600 10800 1 EEST} + {1729803600 7200 0 EET} + {1743199200 10800 1 EEST} + {1761253200 7200 0 EET} + {1774648800 10800 1 EEST} + {1792702800 7200 0 EET} + {1806098400 10800 1 EEST} + {1824152400 7200 0 EET} + {1838152800 10800 1 EEST} + {1856206800 7200 0 EET} + {1869602400 10800 1 EEST} + {1887656400 7200 0 EET} + {1901052000 10800 1 EEST} + {1919106000 7200 0 EET} + {1932501600 10800 1 EEST} + {1950555600 7200 0 EET} + {1963951200 10800 1 EEST} + {1982005200 7200 0 EET} + {1995400800 10800 1 EEST} + {2013454800 7200 0 EET} + {2027455200 10800 1 EEST} + {2045509200 7200 0 EET} + {2058904800 10800 1 EEST} + {2076958800 7200 0 EET} + {2090354400 10800 1 EEST} + {2108408400 7200 0 EET} + {2121804000 10800 1 EEST} + {2139858000 7200 0 EET} + {2153253600 10800 1 EEST} + {2171307600 7200 0 EET} + {2184703200 10800 1 EEST} + {2202757200 7200 0 EET} + {2216757600 10800 1 EEST} + {2234811600 7200 0 EET} + {2248207200 10800 1 EEST} + {2266261200 7200 0 EET} + {2279656800 10800 1 EEST} + {2297710800 7200 0 EET} + {2311106400 10800 1 EEST} + {2329160400 7200 0 EET} + {2342556000 10800 1 EEST} + {2360610000 7200 0 EET} + {2374610400 10800 1 EEST} + {2392664400 7200 0 EET} + {2406060000 10800 1 EEST} + {2424114000 7200 0 EET} + {2437509600 10800 1 EEST} + {2455563600 7200 0 EET} + {2468959200 10800 1 EEST} + {2487013200 7200 0 EET} + {2500408800 10800 1 EEST} + {2518462800 7200 0 EET} + {2531858400 10800 1 EEST} + {2549912400 7200 0 EET} + {2563912800 10800 1 EEST} + {2581966800 7200 0 EET} + {2595362400 10800 1 EEST} + {2613416400 7200 0 EET} + {2626812000 10800 1 EEST} + {2644866000 7200 0 EET} + {2658261600 10800 1 EEST} + {2676315600 7200 0 EET} + {2689711200 10800 1 EEST} + {2707765200 7200 0 EET} + {2721765600 10800 1 EEST} + {2739819600 7200 0 EET} + {2753215200 10800 1 EEST} + {2771269200 7200 0 EET} + {2784664800 10800 1 EEST} + {2802718800 7200 0 EET} + {2816114400 10800 1 EEST} + {2834168400 7200 0 EET} + {2847564000 10800 1 EEST} + {2865618000 7200 0 EET} + {2879013600 10800 1 EEST} + {2897067600 7200 0 EET} + {2911068000 10800 1 EEST} + {2929122000 7200 0 EET} + {2942517600 10800 1 EEST} + {2960571600 7200 0 EET} + {2973967200 10800 1 EEST} + {2992021200 7200 0 EET} + {3005416800 10800 1 EEST} + {3023470800 7200 0 EET} + {3036866400 10800 1 EEST} + {3054920400 7200 0 EET} + {3068316000 10800 1 EEST} + {3086370000 7200 0 EET} + {3100370400 10800 1 EEST} + {3118424400 7200 0 EET} + {3131820000 10800 1 EEST} + {3149874000 7200 0 EET} + {3163269600 10800 1 EEST} + {3181323600 7200 0 EET} + {3194719200 10800 1 EEST} + {3212773200 7200 0 EET} + {3226168800 10800 1 EEST} + {3244222800 7200 0 EET} + {3258223200 10800 1 EEST} + {3276277200 7200 0 EET} + {3289672800 10800 1 EEST} + {3307726800 7200 0 EET} + {3321122400 10800 1 EEST} + {3339176400 7200 0 EET} + {3352572000 10800 1 EEST} + {3370626000 7200 0 EET} + {3384021600 10800 1 EEST} + {3402075600 7200 0 EET} + {3415471200 10800 1 EEST} + {3433525200 7200 0 EET} + {3447525600 10800 1 EEST} + {3465579600 7200 0 EET} + {3478975200 10800 1 EEST} + {3497029200 7200 0 EET} + {3510424800 10800 1 EEST} + {3528478800 7200 0 EET} + {3541874400 10800 1 EEST} + {3559928400 7200 0 EET} + {3573324000 10800 1 EEST} + {3591378000 7200 0 EET} + {3605378400 10800 1 EEST} + {3623432400 7200 0 EET} + {3636828000 10800 1 EEST} + {3654882000 7200 0 EET} + {3668277600 10800 1 EEST} + {3686331600 7200 0 EET} + {3699727200 10800 1 EEST} + {3717781200 7200 0 EET} + {3731176800 10800 1 EEST} + {3749230800 7200 0 EET} + {3762626400 10800 1 EEST} + {3780680400 7200 0 EET} + {3794680800 10800 1 EEST} + {3812734800 7200 0 EET} + {3826130400 10800 1 EEST} + {3844184400 7200 0 EET} + {3857580000 10800 1 EEST} + {3875634000 7200 0 EET} + {3889029600 10800 1 EEST} + {3907083600 7200 0 EET} + {3920479200 10800 1 EEST} + {3938533200 7200 0 EET} + {3951928800 10800 1 EEST} + {3969982800 7200 0 EET} + {3983983200 10800 1 EEST} + {4002037200 7200 0 EET} + {4015432800 10800 1 EEST} + {4033486800 7200 0 EET} + {4046882400 10800 1 EEST} + {4064936400 7200 0 EET} + {4078332000 10800 1 EEST} + {4096386000 7200 0 EET} } diff --git a/library/tzdata/Asia/Hovd b/library/tzdata/Asia/Hovd index 2a87dab..3d200a6 100644 --- a/library/tzdata/Asia/Hovd +++ b/library/tzdata/Asia/Hovd @@ -48,4 +48,174 @@ set TZData(:Asia/Hovd) { {1127498400 25200 0 HOVT} {1143226800 28800 1 HOVST} {1159552800 25200 0 HOVT} + {1427482800 28800 1 HOVST} + {1443196800 25200 0 HOVT} + {1458932400 28800 1 HOVST} + {1474646400 25200 0 HOVT} + {1490382000 28800 1 HOVST} + {1506700800 25200 0 HOVT} + {1522436400 28800 1 HOVST} + {1538150400 25200 0 HOVT} + {1553886000 28800 1 HOVST} + {1569600000 25200 0 HOVT} + {1585335600 28800 1 HOVST} + {1601049600 25200 0 HOVT} + {1616785200 28800 1 HOVST} + {1632499200 25200 0 HOVT} + {1648234800 28800 1 HOVST} + {1663948800 25200 0 HOVT} + {1679684400 28800 1 HOVST} + {1696003200 25200 0 HOVT} + {1711738800 28800 1 HOVST} + {1727452800 25200 0 HOVT} + {1743188400 28800 1 HOVST} + {1758902400 25200 0 HOVT} + {1774638000 28800 1 HOVST} + {1790352000 25200 0 HOVT} + {1806087600 28800 1 HOVST} + {1821801600 25200 0 HOVT} + {1837537200 28800 1 HOVST} + {1853856000 25200 0 HOVT} + {1869591600 28800 1 HOVST} + {1885305600 25200 0 HOVT} + {1901041200 28800 1 HOVST} + {1916755200 25200 0 HOVT} + {1932490800 28800 1 HOVST} + {1948204800 25200 0 HOVT} + {1963940400 28800 1 HOVST} + {1979654400 25200 0 HOVT} + {1995390000 28800 1 HOVST} + {2011104000 25200 0 HOVT} + {2026839600 28800 1 HOVST} + {2043158400 25200 0 HOVT} + {2058894000 28800 1 HOVST} + {2074608000 25200 0 HOVT} + {2090343600 28800 1 HOVST} + {2106057600 25200 0 HOVT} + {2121793200 28800 1 HOVST} + {2137507200 25200 0 HOVT} + {2153242800 28800 1 HOVST} + {2168956800 25200 0 HOVT} + {2184692400 28800 1 HOVST} + {2200406400 25200 0 HOVT} + {2216746800 28800 1 HOVST} + {2232460800 25200 0 HOVT} + {2248196400 28800 1 HOVST} + {2263910400 25200 0 HOVT} + {2279646000 28800 1 HOVST} + {2295360000 25200 0 HOVT} + {2311095600 28800 1 HOVST} + {2326809600 25200 0 HOVT} + {2342545200 28800 1 HOVST} + {2358259200 25200 0 HOVT} + {2373994800 28800 1 HOVST} + {2390313600 25200 0 HOVT} + {2406049200 28800 1 HOVST} + {2421763200 25200 0 HOVT} + {2437498800 28800 1 HOVST} + {2453212800 25200 0 HOVT} + {2468948400 28800 1 HOVST} + {2484662400 25200 0 HOVT} + {2500398000 28800 1 HOVST} + {2516112000 25200 0 HOVT} + {2531847600 28800 1 HOVST} + {2547561600 25200 0 HOVT} + {2563297200 28800 1 HOVST} + {2579616000 25200 0 HOVT} + {2595351600 28800 1 HOVST} + {2611065600 25200 0 HOVT} + {2626801200 28800 1 HOVST} + {2642515200 25200 0 HOVT} + {2658250800 28800 1 HOVST} + {2673964800 25200 0 HOVT} + {2689700400 28800 1 HOVST} + {2705414400 25200 0 HOVT} + {2721150000 28800 1 HOVST} + {2737468800 25200 0 HOVT} + {2753204400 28800 1 HOVST} + {2768918400 25200 0 HOVT} + {2784654000 28800 1 HOVST} + {2800368000 25200 0 HOVT} + {2816103600 28800 1 HOVST} + {2831817600 25200 0 HOVT} + {2847553200 28800 1 HOVST} + {2863267200 25200 0 HOVT} + {2879002800 28800 1 HOVST} + {2894716800 25200 0 HOVT} + {2910452400 28800 1 HOVST} + {2926771200 25200 0 HOVT} + {2942506800 28800 1 HOVST} + {2958220800 25200 0 HOVT} + {2973956400 28800 1 HOVST} + {2989670400 25200 0 HOVT} + {3005406000 28800 1 HOVST} + {3021120000 25200 0 HOVT} + {3036855600 28800 1 HOVST} + {3052569600 25200 0 HOVT} + {3068305200 28800 1 HOVST} + {3084019200 25200 0 HOVT} + {3100359600 28800 1 HOVST} + {3116073600 25200 0 HOVT} + {3131809200 28800 1 HOVST} + {3147523200 25200 0 HOVT} + {3163258800 28800 1 HOVST} + {3178972800 25200 0 HOVT} + {3194708400 28800 1 HOVST} + {3210422400 25200 0 HOVT} + {3226158000 28800 1 HOVST} + {3241872000 25200 0 HOVT} + {3257607600 28800 1 HOVST} + {3273926400 25200 0 HOVT} + {3289662000 28800 1 HOVST} + {3305376000 25200 0 HOVT} + {3321111600 28800 1 HOVST} + {3336825600 25200 0 HOVT} + {3352561200 28800 1 HOVST} + {3368275200 25200 0 HOVT} + {3384010800 28800 1 HOVST} + {3399724800 25200 0 HOVT} + {3415460400 28800 1 HOVST} + {3431174400 25200 0 HOVT} + {3446910000 28800 1 HOVST} + {3463228800 25200 0 HOVT} + {3478964400 28800 1 HOVST} + {3494678400 25200 0 HOVT} + {3510414000 28800 1 HOVST} + {3526128000 25200 0 HOVT} + {3541863600 28800 1 HOVST} + {3557577600 25200 0 HOVT} + {3573313200 28800 1 HOVST} + {3589027200 25200 0 HOVT} + {3604762800 28800 1 HOVST} + {3621081600 25200 0 HOVT} + {3636817200 28800 1 HOVST} + {3652531200 25200 0 HOVT} + {3668266800 28800 1 HOVST} + {3683980800 25200 0 HOVT} + {3699716400 28800 1 HOVST} + {3715430400 25200 0 HOVT} + {3731166000 28800 1 HOVST} + {3746880000 25200 0 HOVT} + {3762615600 28800 1 HOVST} + {3778329600 25200 0 HOVT} + {3794065200 28800 1 HOVST} + {3810384000 25200 0 HOVT} + {3826119600 28800 1 HOVST} + {3841833600 25200 0 HOVT} + {3857569200 28800 1 HOVST} + {3873283200 25200 0 HOVT} + {3889018800 28800 1 HOVST} + {3904732800 25200 0 HOVT} + {3920468400 28800 1 HOVST} + {3936182400 25200 0 HOVT} + {3951918000 28800 1 HOVST} + {3967632000 25200 0 HOVT} + {3983972400 28800 1 HOVST} + {3999686400 25200 0 HOVT} + {4015422000 28800 1 HOVST} + {4031136000 25200 0 HOVT} + {4046871600 28800 1 HOVST} + {4062585600 25200 0 HOVT} + {4078321200 28800 1 HOVST} + {4094035200 25200 0 HOVT} } diff --git a/library/tzdata/Asia/Ulaanbaatar b/library/tzdata/Asia/Ulaanbaatar index fef76ec..93e066c 100644 --- a/library/tzdata/Asia/Ulaanbaatar +++ b/library/tzdata/Asia/Ulaanbaatar @@ -48,4 +48,174 @@ set TZData(:Asia/Ulaanbaatar) { {1127494800 28800 0 ULAT} {1143223200 32400 1 ULAST} {1159549200 28800 0 ULAT} + {1427479200 32400 1 ULAST} + {1443193200 28800 0 ULAT} + {1458928800 32400 1 ULAST} + {1474642800 28800 0 ULAT} + {1490378400 32400 1 ULAST} + {1506697200 28800 0 ULAT} + {1522432800 32400 1 ULAST} + {1538146800 28800 0 ULAT} + {1553882400 32400 1 ULAST} + {1569596400 28800 0 ULAT} + {1585332000 32400 1 ULAST} + {1601046000 28800 0 ULAT} + {1616781600 32400 1 ULAST} + {1632495600 28800 0 ULAT} + {1648231200 32400 1 ULAST} + {1663945200 28800 0 ULAT} + {1679680800 32400 1 ULAST} + {1695999600 28800 0 ULAT} + {1711735200 32400 1 ULAST} + {1727449200 28800 0 ULAT} + {1743184800 32400 1 ULAST} + {1758898800 28800 0 ULAT} + {1774634400 32400 1 ULAST} + {1790348400 28800 0 ULAT} + {1806084000 32400 1 ULAST} + {1821798000 28800 0 ULAT} + {1837533600 32400 1 ULAST} + {1853852400 28800 0 ULAT} + {1869588000 32400 1 ULAST} + {1885302000 28800 0 ULAT} + {1901037600 32400 1 ULAST} + {1916751600 28800 0 ULAT} + {1932487200 32400 1 ULAST} + {1948201200 28800 0 ULAT} + {1963936800 32400 1 ULAST} + {1979650800 28800 0 ULAT} + {1995386400 32400 1 ULAST} + {2011100400 28800 0 ULAT} + {2026836000 32400 1 ULAST} + {2043154800 28800 0 ULAT} + {2058890400 32400 1 ULAST} + {2074604400 28800 0 ULAT} + {2090340000 32400 1 ULAST} + {2106054000 28800 0 ULAT} + {2121789600 32400 1 ULAST} + {2137503600 28800 0 ULAT} + {2153239200 32400 1 ULAST} + {2168953200 28800 0 ULAT} + {2184688800 32400 1 ULAST} + {2200402800 28800 0 ULAT} + {2216743200 32400 1 ULAST} + {2232457200 28800 0 ULAT} + {2248192800 32400 1 ULAST} + {2263906800 28800 0 ULAT} + {2279642400 32400 1 ULAST} + {2295356400 28800 0 ULAT} + {2311092000 32400 1 ULAST} + {2326806000 28800 0 ULAT} + {2342541600 32400 1 ULAST} + {2358255600 28800 0 ULAT} + {2373991200 32400 1 ULAST} + {2390310000 28800 0 ULAT} + {2406045600 32400 1 ULAST} + {2421759600 28800 0 ULAT} + {2437495200 32400 1 ULAST} + {2453209200 28800 0 ULAT} + {2468944800 32400 1 ULAST} + {2484658800 28800 0 ULAT} + {2500394400 32400 1 ULAST} + {2516108400 28800 0 ULAT} + {2531844000 32400 1 ULAST} + {2547558000 28800 0 ULAT} + {2563293600 32400 1 ULAST} + {2579612400 28800 0 ULAT} + {2595348000 32400 1 ULAST} + {2611062000 28800 0 ULAT} + {2626797600 32400 1 ULAST} + {2642511600 28800 0 ULAT} + {2658247200 32400 1 ULAST} + {2673961200 28800 0 ULAT} + {2689696800 32400 1 ULAST} + {2705410800 28800 0 ULAT} + {2721146400 32400 1 ULAST} + {2737465200 28800 0 ULAT} + {2753200800 32400 1 ULAST} + {2768914800 28800 0 ULAT} + {2784650400 32400 1 ULAST} + {2800364400 28800 0 ULAT} + {2816100000 32400 1 ULAST} + {2831814000 28800 0 ULAT} + {2847549600 32400 1 ULAST} + {2863263600 28800 0 ULAT} + {2878999200 32400 1 ULAST} + {2894713200 28800 0 ULAT} + {2910448800 32400 1 ULAST} + {2926767600 28800 0 ULAT} + {2942503200 32400 1 ULAST} + {2958217200 28800 0 ULAT} + {2973952800 32400 1 ULAST} + {2989666800 28800 0 ULAT} + {3005402400 32400 1 ULAST} + {3021116400 28800 0 ULAT} + {3036852000 32400 1 ULAST} + {3052566000 28800 0 ULAT} + {3068301600 32400 1 ULAST} + {3084015600 28800 0 ULAT} + {3100356000 32400 1 ULAST} + {3116070000 28800 0 ULAT} + {3131805600 32400 1 ULAST} + {3147519600 28800 0 ULAT} + {3163255200 32400 1 ULAST} + {3178969200 28800 0 ULAT} + {3194704800 32400 1 ULAST} + {3210418800 28800 0 ULAT} + {3226154400 32400 1 ULAST} + {3241868400 28800 0 ULAT} + {3257604000 32400 1 ULAST} + {3273922800 28800 0 ULAT} + {3289658400 32400 1 ULAST} + {3305372400 28800 0 ULAT} + {3321108000 32400 1 ULAST} + {3336822000 28800 0 ULAT} + {3352557600 32400 1 ULAST} + {3368271600 28800 0 ULAT} + {3384007200 32400 1 ULAST} + {3399721200 28800 0 ULAT} + {3415456800 32400 1 ULAST} + {3431170800 28800 0 ULAT} + {3446906400 32400 1 ULAST} + {3463225200 28800 0 ULAT} + {3478960800 32400 1 ULAST} + {3494674800 28800 0 ULAT} + {3510410400 32400 1 ULAST} + {3526124400 28800 0 ULAT} + {3541860000 32400 1 ULAST} + {3557574000 28800 0 ULAT} + {3573309600 32400 1 ULAST} + {3589023600 28800 0 ULAT} + {3604759200 32400 1 ULAST} + {3621078000 28800 0 ULAT} + {3636813600 32400 1 ULAST} + {3652527600 28800 0 ULAT} + {3668263200 32400 1 ULAST} + {3683977200 28800 0 ULAT} + {3699712800 32400 1 ULAST} + {3715426800 28800 0 ULAT} + {3731162400 32400 1 ULAST} + {3746876400 28800 0 ULAT} + {3762612000 32400 1 ULAST} + {3778326000 28800 0 ULAT} + {3794061600 32400 1 ULAST} + {3810380400 28800 0 ULAT} + {3826116000 32400 1 ULAST} + {3841830000 28800 0 ULAT} + {3857565600 32400 1 ULAST} + {3873279600 28800 0 ULAT} + {3889015200 32400 1 ULAST} + {3904729200 28800 0 ULAT} + {3920464800 32400 1 ULAST} + {3936178800 28800 0 ULAT} + {3951914400 32400 1 ULAST} + {3967628400 28800 0 ULAT} + {3983968800 32400 1 ULAST} + {3999682800 28800 0 ULAT} + {4015418400 32400 1 ULAST} + {4031132400 28800 0 ULAT} + {4046868000 32400 1 ULAST} + {4062582000 28800 0 ULAT} + {4078317600 32400 1 ULAST} + {4094031600 28800 0 ULAT} } diff --git a/library/tzdata/Europe/Volgograd b/library/tzdata/Europe/Volgograd index 8c29c58..d71fb0b 100644 --- a/library/tzdata/Europe/Volgograd +++ b/library/tzdata/Europe/Volgograd @@ -28,43 +28,43 @@ set TZData(:Europe/Volgograd) { {638319600 14400 1 VOLST} {654649200 10800 0 VOLT} {670374000 14400 0 VOLT} - {701820000 14400 0 MSK} + {701820000 14400 0 MSD} {717534000 10800 0 MSK} - {733273200 14400 1 MSK} + {733273200 14400 1 MSD} {748998000 10800 0 MSK} - {764722800 14400 1 MSK} + {764722800 14400 1 MSD} {780447600 10800 0 MSK} - {796172400 14400 1 MSK} + {796172400 14400 1 MSD} {811897200 10800 0 MSK} - {828226800 14400 1 MSK} + {828226800 14400 1 MSD} {846370800 10800 0 MSK} - {859676400 14400 1 MSK} + {859676400 14400 1 MSD} {877820400 10800 0 MSK} - {891126000 14400 1 MSK} + {891126000 14400 1 MSD} {909270000 10800 0 MSK} - {922575600 14400 1 MSK} + {922575600 14400 1 MSD} {941324400 10800 0 MSK} - {954025200 14400 1 MSK} + {954025200 14400 1 MSD} {972774000 10800 0 MSK} - {985474800 14400 1 MSK} + {985474800 14400 1 MSD} {1004223600 10800 0 MSK} - {1017529200 14400 1 MSK} + {1017529200 14400 1 MSD} {1035673200 10800 0 MSK} - {1048978800 14400 1 MSK} + {1048978800 14400 1 MSD} {1067122800 10800 0 MSK} - {1080428400 14400 1 MSK} + {1080428400 14400 1 MSD} {1099177200 10800 0 MSK} - {1111878000 14400 1 MSK} + {1111878000 14400 1 MSD} {1130626800 10800 0 MSK} - {1143327600 14400 1 MSK} + {1143327600 14400 1 MSD} {1162076400 10800 0 MSK} - {1174777200 14400 1 MSK} + {1174777200 14400 1 MSD} {1193526000 10800 0 MSK} - {1206831600 14400 1 MSK} + {1206831600 14400 1 MSD} {1224975600 10800 0 MSK} - {1238281200 14400 1 MSK} + {1238281200 14400 1 MSD} {1256425200 10800 0 MSK} - {1269730800 14400 1 MSK} + {1269730800 14400 1 MSD} {1288479600 10800 0 MSK} {1301180400 14400 0 MSK} {1414274400 10800 0 MSK} diff --git a/library/tzdata/Pacific/Easter b/library/tzdata/Pacific/Easter index f76594a..4b45ba2 100644 --- a/library/tzdata/Pacific/Easter +++ b/library/tzdata/Pacific/Easter @@ -1,14 +1,9 @@ # created by tools/tclZIC.tcl - do not edit set TZData(:Pacific/Easter) { - {-9223372036854775808 -26264 0 LMT} - {-2524495336 -26248 0 EMT} - {-1178124152 -21600 0 EASST} - {-870552000 -25200 0 EAST} - {-865278000 -21600 1 EASST} - {-740520000 -21600 1 EASST} - {-736376400 -25200 0 EAST} - {-718056000 -25200 0 EAST} + {-9223372036854775808 -26248 0 LMT} + {-2524495352 -26248 0 EMT} + {-1178124152 -25200 0 EAST} {-36619200 -21600 1 EASST} {-23922000 -25200 0 EAST} {-3355200 -21600 1 EASST} @@ -36,7 +31,6 @@ set TZData(:Pacific/Easter) { {340171200 -21600 1 EASST} {353473200 -25200 0 EAST} {371620800 -21600 1 EASST} - {384836400 -18000 0 EAST} {384922800 -21600 0 EAST} {403070400 -18000 1 EASST} {416372400 -21600 0 EAST} @@ -50,10 +44,10 @@ set TZData(:Pacific/Easter) { {545194800 -21600 0 EAST} {560923200 -18000 1 EASST} {574225200 -21600 0 EAST} - {591768000 -18000 1 EASST} + {592372800 -18000 1 EASST} {605674800 -21600 0 EAST} {624427200 -18000 1 EASST} - {637729200 -21600 0 EAST} + {637124400 -21600 0 EAST} {653457600 -18000 1 EASST} {668574000 -21600 0 EAST} {687326400 -18000 1 EASST} diff --git a/library/tzdata/Pacific/Midway b/library/tzdata/Pacific/Midway index c07b030..d044569 100644 --- a/library/tzdata/Pacific/Midway +++ b/library/tzdata/Pacific/Midway @@ -1,10 +1,5 @@ # created by tools/tclZIC.tcl - do not edit - -set TZData(:Pacific/Midway) { - {-9223372036854775808 -42568 0 LMT} - {-2177410232 -39600 0 NST} - {-428504400 -36000 1 NDT} - {-420645600 -39600 0 NST} - {-86878800 -39600 0 BST} - {439038000 -39600 0 SST} +if {![info exists TZData(Pacific/Pago_Pago)]} { + LoadTimeZoneFile Pacific/Pago_Pago } +set TZData(:Pacific/Midway) $TZData(:Pacific/Pago_Pago) diff --git a/library/tzdata/Pacific/Saipan b/library/tzdata/Pacific/Saipan index b799298..4e769cd 100644 --- a/library/tzdata/Pacific/Saipan +++ b/library/tzdata/Pacific/Saipan @@ -1,9 +1,5 @@ # created by tools/tclZIC.tcl - do not edit - -set TZData(:Pacific/Saipan) { - {-9223372036854775808 -51420 0 LMT} - {-3944626980 34980 0 LMT} - {-2177487780 32400 0 MPT} - {-7981200 36000 0 MPT} - {977493600 36000 0 ChST} +if {![info exists TZData(Pacific/Guam)]} { + LoadTimeZoneFile Pacific/Guam } +set TZData(:Pacific/Saipan) $TZData(:Pacific/Guam) -- cgit v0.12 From 227d96bf13b6000946069997f593024692a0e015 Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 29 Apr 2015 16:34:33 +0000 Subject: [894da183c8] Fix and test for bug at the point it was introduced. --- generic/tclIO.c | 3 +++ tests/io.test | 33 ++++++++++++++++++++++++++++++++- 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/generic/tclIO.c b/generic/tclIO.c index 4e325ba..10fc377 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -2516,6 +2516,7 @@ FlushChannel( * queue. */ +start: if (((statePtr->curOutPtr != NULL) && IsBufferFull(statePtr->curOutPtr)) || (GotFlag(statePtr, BUFFER_READY) && @@ -2701,6 +2702,8 @@ FlushChannel( (chanPtr->typePtr->watchProc)(chanPtr->instanceData, statePtr->interestMask); } + } else if (statePtr->curOutPtr && BytesLeft(statePtr->curOutPtr)) { + goto start; } /* diff --git a/tests/io.test b/tests/io.test index c7da8e6..53fdaf7 100644 --- a/tests/io.test +++ b/tests/io.test @@ -7142,7 +7142,7 @@ test io-53.4 {CopyData: background write overflow} {stdio unix openpipe fileeven set result "" fileevent $f1 read [namespace code { append result [read $f1 1024] - if {[string length $result] >= [string length $big]} { + if {[string length $result] >= [string length $big]+1} { set x done } }] @@ -7151,6 +7151,37 @@ test io-53.4 {CopyData: background write overflow} {stdio unix openpipe fileeven set big {} set x } done +test io-53.4.1 {Bug 894da183c8} {stdio fcopy} { + set big bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n + variable x + for {set x 0} {$x < 12} {incr x} { + append big $big + } + file delete $path(pipe) + set f1 [open $path(pipe) w] + puts $f1 [list file delete $path(test1)] + puts $f1 { + puts ready + set f [open io-53.4.1 w] + fcopy stdin $f -command { set x } + vwait x + close $f + } + puts $f1 "close \[[list open $path(test1) w]]" + close $f1 + set f1 [open "|[list [interpreter] $path(pipe)]" r+] + set result [gets $f1] + fconfigure $f1 -blocking 0 -buffersize 125000 + puts $f1 $big + fconfigure $f1 -blocking 1 + close $f1 + set big {} + while {[catch {glob $path(test1)}]} {after 50} + file delete $path(test1) + set check [file size io-53.4.1] + file delete io-53.4.1 + set check +} 266241 set result {} proc FcopyTestAccept {sock args} { after 1000 "close $sock" -- cgit v0.12 From d3e04b3a7681476889b2c9a75deed8c65556f178 Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 29 Apr 2015 20:34:26 +0000 Subject: Use joinable threads to avoid thread finalization crashes. --- tests/http.test | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/http.test b/tests/http.test index 81e16a1..2fc0a51 100644 --- a/tests/http.test +++ b/tests/http.test @@ -54,7 +54,7 @@ if {![file exists $httpdFile]} { } if {[info commands testthread] == "testthread" && [file exists $httpdFile]} { - set httpthread [testthread create " + set httpthread [testthread create -joinable " source [list $httpdFile] testthread wait "] @@ -554,6 +554,7 @@ if {[info exists httpthread]} { testthread send -async $httpthread { testthread exit } + testthread join $httpthread } else { close $listen } -- cgit v0.12 From 1754a9a311a61dc8c9af0d29768142e2381ae197 Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 30 Apr 2015 15:31:17 +0000 Subject: Test portability. --- tests/io.test | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/io.test b/tests/io.test index c3e63cc..50c5808 100644 --- a/tests/io.test +++ b/tests/io.test @@ -7389,6 +7389,7 @@ test io-53.4.1 {Bug 894da183c8} {stdio fcopy} { puts $f1 { puts ready set f [open io-53.4.1 w] + chan configure $f -translation lf fcopy stdin $f -command { set x } vwait x close $f @@ -7397,7 +7398,7 @@ test io-53.4.1 {Bug 894da183c8} {stdio fcopy} { close $f1 set f1 [open "|[list [interpreter] $path(pipe)]" r+] set result [gets $f1] - fconfigure $f1 -blocking 0 -buffersize 125000 + fconfigure $f1 -blocking 0 -buffersize 125000 -translation lf puts $f1 $big fconfigure $f1 -blocking 1 close $f1 -- cgit v0.12 From 73deb43f4f54fc07c7025cb47b0cc3a5f9d5466d Mon Sep 17 00:00:00 2001 From: dgp Date: Tue, 12 May 2015 15:00:16 +0000 Subject: Added contributed tests from aspect --- tests/ooNext2.test | 195 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 195 insertions(+) diff --git a/tests/ooNext2.test b/tests/ooNext2.test index 5ecd209..6c4f1ad 100644 --- a/tests/ooNext2.test +++ b/tests/ooNext2.test @@ -866,6 +866,201 @@ test oo-call-3.4 {current call introspection: in destructors} -setup { } -cleanup { root destroy } -result {{{{method ::B method} {method ::A method}} 0} {{{method ::B method} {method ::A method}} 1}} + +# Contributed tests from aspect, related to [0f42ff7871] +# +# dkf's "Principles Leading to a Fix" +# +# A method ought to work "the same" whether or not it has been overridden by +# a subclass. A tailcalled command ought to have as parent stack the same +# thing you'd get with uplevel 1. A subclass will often expect the +# superclass's result to be the result that would be returned if the subclass +# was not there. +# + +# common setup: +# any invocation of bar should emit "abc\nhi\n" then return to its caller +set testopts { + -setup { + oo::class create Foo { + method bar {} { + puts abc + tailcall puts hi + puts xyz + } + } + } + -cleanup { + catch {Foo destroy} + catch {Foo2 destroy} ;# created by some tests + } +} + +# these succeed, showing that without [next] the bug doesn't fire +test next-tailcall-simple-1 "trivial case with one method" {*}$testopts -body { + [Foo create foo] bar +} -output [join {abc hi} \n]\n + +test next-tailcall-simple-2 "my bar" {*}$testopts -body { + oo::define Foo method baz {} { + puts a + my bar + puts b + } + [Foo create foo] baz +} -output [join {a abc hi b} \n]\n + +test next-tailcall-simple-3 "\[self\] bar" {*}$testopts -body { + oo::define Foo method baz {} { + puts a + [self] bar + puts b + } + [Foo create foo] baz +} -output [join {a abc hi b} \n]\n + +test next-tailcall-simple-4 "foo bar" {*}$testopts -body { + oo::define Foo method baz {} { + puts a + foo bar + puts b + } + [Foo create foo] baz +} -output [join {a abc hi b} \n]\n + +# everything from here on uses [next], and fails on 8.6.4 with compilation +test next-tailcall-superclass-1 "next superclass" {*}$testopts -body { + oo::class create Foo2 { + superclass Foo + method bar {} { + puts a + next + puts b + } + } + [Foo2 create foo] bar +} -output [join {a abc hi b} \n]\n + +test next-tailcall-superclass-2 "nextto superclass" {*}$testopts -body { + oo::class create Foo2 { + superclass Foo + method bar {} { + puts a + nextto Foo + puts b + } + } + [Foo2 create foo] bar +} -output [join {a abc hi b} \n]\n + + +test next-tailcall-mixin-1 "class mixin" {*}$testopts -body { + oo::class create Foo2 { + method Bar {} { + puts a + next + puts b + } + filter Bar + } + oo::define Foo mixin Foo2 + Foo create foo + foo bar +} -output [join {a abc hi b} \n]\n + +test next-tailcall-objmixin-1 "object mixin" {*}$testopts -body { + oo::class create Foo2 { + method Bar {} { + puts a + next + puts b + } + filter Bar + } + Foo create foo + oo::objdefine foo mixin Foo2 + foo bar +} -output [join {a abc hi b} \n]\n + +test next-tailcall-filter-1 "filter method" {*}$testopts -body { + oo::define Foo method Filter {} { + puts a + next + puts b + } + oo::define Foo filter Filter + [Foo new] bar +} -output [join {a abc hi b} \n]\n + +test next-tailcall-forward-1 "forward method" {*}$testopts -body { + proc foobar {} { + puts "abc" + tailcall puts "hi" + puts "xyz" + } + oo::define Foo forward foobar foobar + oo::class create Foo2 { + superclass Foo + method foobar {} { + puts a + next + puts b + } + } + [Foo2 new] foobar +} -output [join {a abc hi b} \n]\n + +test next-tailcall-constructor-1 "next in constructor" -body { + oo::class create Foo { + constructor {} { + puts abc + tailcall puts hi + puts xyz + } + } + oo::class create Foo2 { + superclass Foo + constructor {} { + puts a + next + puts b + } + } + list [Foo new] [Foo2 new] + return "" +} -cleanup { + Foo destroy +} -output [join {abc hi a abc hi b} \n]\n + + +test next-tailcall-destructor-1 "next in destructor" -body { + oo::class create Foo { + destructor { + puts abc + tailcall puts hi + puts xyz + } + } + oo::class create Foo2 { + superclass Foo + destructor { + puts a + next + puts b + } + } + Foo create foo + Foo2 create foo2 + foo destroy + foo2 destroy +} -output [join {abc hi a abc hi b} \n]\n + + + + +unset testopts + + cleanupTests return -- cgit v0.12 From 1913208e18b29f26c17c72fdf90fb7e8aaf3b399 Mon Sep 17 00:00:00 2001 From: dkf Date: Thu, 14 May 2015 08:05:37 +0000 Subject: [b9d0434667] Prefer the gzip encoding for transfers. It's less efficient, but it is far more interoperable and that's a more important metric. --- library/http/http.tcl | 2 +- tests/http11.test | 33 ++++++++++++++++++++++++++------- tests/httpd11.tcl | 15 ++++++++------- 3 files changed, 35 insertions(+), 15 deletions(-) diff --git a/library/http/http.tcl b/library/http/http.tcl index a6b2bfd..4870f4a 100644 --- a/library/http/http.tcl +++ b/library/http/http.tcl @@ -739,7 +739,7 @@ proc http::Connected { token proto phost srvurl} { } } if {!$accept_encoding_seen && ![info exists state(-handler)]} { - puts $sock "Accept-Encoding: deflate,gzip,compress" + 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 diff --git a/tests/http11.test b/tests/http11.test index 230ce5a..c9ded0b 100644 --- a/tests/http11.test +++ b/tests/http11.test @@ -70,11 +70,8 @@ proc check_crc {tok args} { return "ok" } -makeFile "test\ -

this is a test

\n\ -[string repeat {

This is a tcl test file.

} 4192]\n\ -" testdoc.html - +makeFile "test

this is a test

\n[string repeat {

This is a tcl test file.

} 4192]\n" testdoc.html + # ------------------------------------------------------------------------- test http11-1.0 "normal request for document " -setup { @@ -447,7 +444,8 @@ test http11-2.10 "-channel,deflate,keepalive" -setup { set chan [open [makeFile {} testfile.tmp] wb+] } -body { set tok [http::geturl http://localhost:$httpd_port/testdoc.html \ - -timeout 5000 -channel $chan -keepalive 1] + -timeout 5000 -channel $chan -keepalive 1 \ + -headers {accept-encoding deflate}] http::wait $tok seek $chan 0 set data [read $chan] @@ -482,6 +480,27 @@ test http11-2.11 "-channel,identity,keepalive" -setup { halt_httpd } -result {ok {HTTP/1.1 200 OK} ok {} {} chunked} +test http11-2.12 "-channel,negotiate,keepalive" -setup { + variable httpd [create_httpd] + set chan [open [makeFile {} testfile.tmp] wb+] +} -body { + set tok [http::geturl http://localhost:$httpd_port/testdoc.html \ + -timeout 5000 -channel $chan -keepalive 1] + http::wait $tok + seek $chan 0 + set data [read $chan] + list [http::status $tok] [http::code $tok] [check_crc $tok $data]\ + [meta $tok connection] [meta $tok content-encoding]\ + [meta $tok transfer-encoding] [meta $tok x-requested-encodings]\ + [expr {[file size testdoc.html]-[file size testfile.tmp]}] +} -cleanup { + http::cleanup $tok + close $chan + removeFile testfile.tmp + halt_httpd +} -result {ok {HTTP/1.1 200 OK} ok {} gzip chunked gzip,deflate,compress 0} + + # ------------------------------------------------------------------------- # # The following tests for the -handler option will require changes in @@ -644,7 +663,7 @@ test http11-4.3 "normal post request, check channel query length" -setup { removeFile testfile.tmp halt_httpd } -result {status ok code {HTTP/1.1 200 OK} crc ok connection close query-length 122880} - + # ------------------------------------------------------------------------- foreach p {create_httpd httpd_read halt_httpd meta check_crc} { diff --git a/tests/httpd11.tcl b/tests/httpd11.tcl index 9c543dc..267f409 100644 --- a/tests/httpd11.tcl +++ b/tests/httpd11.tcl @@ -158,13 +158,13 @@ proc Service {chan addr port} { } if {$protocol eq "HTTP/1.1"} { - if {[string match "*deflate*" [dict get? $meta accept-encoding]]} { - set encoding deflate - } elseif {[string match "*gzip*" [dict get? $meta accept-encoding]]} { - set encoding gzip - } elseif {[string match "*compress*" [dict get? $meta accept-encoding]]} { - set encoding compress - } + foreach enc [split [dict get? $meta accept-encoding] ,] { + set enc [string trim $enc] + if {$enc in {deflate gzip compress}} { + set encoding $enc + break + } + } set transfer chunked } else { set close 1 @@ -189,6 +189,7 @@ proc Service {chan addr port} { if {$close} { Puts $chan "connection: close" } + Puts $chan "x-requested-encodings: [dict get? $meta accept-encoding]" if {$encoding eq "identity"} { Puts $chan "content-length: [string length $data]" } else { -- cgit v0.12 From 6135265f5cb4c7d7123c40447a28ef4cbc052005 Mon Sep 17 00:00:00 2001 From: dkf Date: Thu, 14 May 2015 08:23:52 +0000 Subject: [6a71dbe6ec] Ensure that compression errors log correctly. --- 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 4870f4a..97f6348 100644 --- a/library/http/http.tcl +++ b/library/http/http.tcl @@ -1299,7 +1299,7 @@ proc http::Eof {token {force 0}} { set state(body) [zlib $coding $state(body)] } } err]} { - Log "error doing $coding '$state(body)'" + Log "error doing decompression: $err" return [Finish $token $err] } -- cgit v0.12 From c11a7a6b0838257de896613e697f095289c7025e Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 14 May 2015 11:19:27 +0000 Subject: Bump to http 2.8.9 --- library/http/http.tcl | 2 +- library/http/pkgIndex.tcl | 2 +- unix/Makefile.in | 4 ++-- win/Makefile.in | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/library/http/http.tcl b/library/http/http.tcl index 97f6348..751ca13 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.8 +package provide http 2.8.9 namespace eval http { # Allow resourcing to not clobber existing data diff --git a/library/http/pkgIndex.tcl b/library/http/pkgIndex.tcl index 27ba795..6e0301a 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.8 [list tclPkgSetup $dir http 2.8.8 {{http.tcl source {::http::config ::http::formatQuery ::http::geturl ::http::reset ::http::wait ::http::register ::http::unregister ::http::mapReply}}}] +package ifneeded http 2.8.9 [list tclPkgSetup $dir http 2.8.9 {{http.tcl source {::http::config ::http::formatQuery ::http::geturl ::http::reset ::http::wait ::http::register ::http::unregister ::http::mapReply}}}] diff --git a/unix/Makefile.in b/unix/Makefile.in index 46ff5cd..958e759 100644 --- a/unix/Makefile.in +++ b/unix/Makefile.in @@ -844,8 +844,8 @@ install-libraries: libraries do \ $(INSTALL_DATA) $$i "$(SCRIPT_INSTALL_DIR)"/http1.0; \ done; - @echo "Installing package http 2.8.8 as a Tcl Module"; - @$(INSTALL_DATA) $(TOP_DIR)/library/http/http.tcl "$(SCRIPT_INSTALL_DIR)"/../tcl8/8.6/http-2.8.8.tm; + @echo "Installing package http 2.8.9 as a Tcl Module"; + @$(INSTALL_DATA) $(TOP_DIR)/library/http/http.tcl "$(SCRIPT_INSTALL_DIR)"/../tcl8/8.6/http-2.8.9.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 71d3fe6..168da2e 100644 --- a/win/Makefile.in +++ b/win/Makefile.in @@ -643,8 +643,8 @@ install-libraries: libraries install-tzdata install-msgs do \ $(COPY) "$$j" "$(SCRIPT_INSTALL_DIR)/http1.0"; \ done; - @echo "Installing package http 2.8.8 as a Tcl Module"; - @$(COPY) $(ROOT_DIR)/library/http/http.tcl $(SCRIPT_INSTALL_DIR)/../tcl8/8.6/http-2.8.8.tm; + @echo "Installing package http 2.8.9 as a Tcl Module"; + @$(COPY) $(ROOT_DIR)/library/http/http.tcl $(SCRIPT_INSTALL_DIR)/../tcl8/8.6/http-2.8.9.tm; @echo "Installing library opt0.4 directory"; @for j in $(ROOT_DIR)/library/opt/*.tcl; \ do \ -- cgit v0.12 From c9e70a39012f9deb925aa75ae77b28e1997783e7 Mon Sep 17 00:00:00 2001 From: dkf Date: Fri, 15 May 2015 13:54:52 +0000 Subject: [9dd1bd7a74] Ensure that [self] returns a sensible value in a destructor even when construction didn't complete. --- generic/tclOO.c | 9 +++++++-- tests/oo.test | 25 +++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/generic/tclOO.c b/generic/tclOO.c index 77e668b..e2ef1ae 100644 --- a/generic/tclOO.c +++ b/generic/tclOO.c @@ -1675,10 +1675,13 @@ Tcl_NewObjectInstance( /* * Take care to not delete a deleted object; that would be - * bad. [Bug 2903011] + * bad. [Bug 2903011] Also take care to make sure that we have + * the name of the command before we delete it. [Bug + * 9dd1bd7a74] */ if (!Deleted(oPtr)) { + (void) TclOOObjectName(interp, oPtr); Tcl_DeleteCommandFromToken(interp, oPtr->command); } return NULL; @@ -1821,10 +1824,12 @@ FinalizeAlloc( /* * Take care to not delete a deleted object; that would be bad. [Bug - * 2903011] + * 2903011] Also take care to make sure that we have the name of the + * command before we delete it. [Bug 9dd1bd7a74] */ if (!Deleted(oPtr)) { + (void) TclOOObjectName(interp, oPtr); Tcl_DeleteCommandFromToken(interp, oPtr->command); } DelRef(oPtr); diff --git a/tests/oo.test b/tests/oo.test index 5fa760b..22e6cfb 100644 --- a/tests/oo.test +++ b/tests/oo.test @@ -416,6 +416,31 @@ test oo-2.8 {construction, method calls and ensembles - Bug 3514761} -setup { } -returnCodes error -cleanup { namespace delete k } -result {wrong # args: should be "k next j"} +test oo-2.9 {construction failures and self creation} -setup { + set ::result {} + oo::class create Root +} -body { + oo::class create A { + superclass Root + constructor {} { + lappend ::result "in A" + error "failure in A" + } + destructor {lappend ::result [self]} + } + oo::class create B { + superclass Root + constructor {} { + lappend ::result "in B [self]" + error "failure in B" + } + destructor {lappend ::result [self]} + } + lappend ::result [catch {A create a} msg] $msg + lappend ::result [catch {B create b} msg] $msg +} -cleanup { + Root destroy +} -result {{in A} ::a 1 {failure in A} {in B ::b} ::b 1 {failure in B}} test oo-3.1 {basic test of OO functionality: destructor} -setup { # This is a bit complex because it needs to run in a sub-interp as we're -- cgit v0.12 From 4240cb00f0bbc1b8b0b12f7cce2c3cbf40e5e08f Mon Sep 17 00:00:00 2001 From: dkf Date: Sun, 17 May 2015 12:06:31 +0000 Subject: [ad6696285c] Demonstrate that filters are not called for destructors. --- tests/oo.test | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/tests/oo.test b/tests/oo.test index 22e6cfb..f35b70a 100644 --- a/tests/oo.test +++ b/tests/oo.test @@ -1569,6 +1569,34 @@ test oo-12.7 {OO: filters} -setup { } -cleanup { Aclass destroy } -result {foo {{::Aclass outerfoo} {::Aclass InnerFoo}}} +test oo-12.8 {OO: filters and destructors} -setup { + oo::class create Aclass + Aclass create Aobject + set ::log {} +} -body { + oo::define Aclass { + constructor {} { + lappend ::log "in constructor" + } + destructor { + lappend ::log "in destructor" + } + method bar {} { + lappend ::log "in method" + } + method Boo args { + lappend ::log [self target] + next {*}$args + } + filter Boo + } + set obj [Aclass new] + $obj bar + $obj destroy + return $::log +} -cleanup { + Aclass destroy +} -result {{in constructor} {::Aclass bar} {in method} {::oo::object destroy} {in destructor}} test oo-13.1 {OO: changing an object's class} { oo::class create Aclass -- cgit v0.12 From 8c1c07d4bf8ef15f93238cb560f629416ed89497 Mon Sep 17 00:00:00 2001 From: dkf Date: Sun, 17 May 2015 12:56:06 +0000 Subject: [ad6696285c] Correction of description of filter behaviour with 'unknown'. --- doc/next.n | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/doc/next.n b/doc/next.n index 7dacac2..1ea6eb9 100644 --- a/doc/next.n +++ b/doc/next.n @@ -96,9 +96,11 @@ forward to the proper implementation of the method (which it does by invoking the \fBnext\fR command as filters are inserted into the front of the method call chain) and is responsible for returning the result of \fBnext\fR. .PP -Filters are not invoked when processing an invocation of the \fBunknown\fR -method because of a failure to locate a method implementation, or when -invoking either constructors or destructors. +Filters are invoked when processing an invokation of the \fBunknown\fR +method because of a failure to locate a method implementation, but \fInot\fR +when invoking either constructors or destructors. (Note however that the +\fBdestroy\fR method is a conventional method, and filters are invoked as +normal when it is called.) .SH EXAMPLES .PP This example demonstrates how to use the \fBnext\fR command to call the -- cgit v0.12 From 58f3361635cca55f81c13a4a15c61b8edffdab2e Mon Sep 17 00:00:00 2001 From: dkf Date: Mon, 18 May 2015 07:51:54 +0000 Subject: [c11a51c482] Stop race condition with -accept config option, and allow overriding of it via -headers option. --- library/http/http.tcl | 41 +++++++++++++++++++++++++++++++---------- tests/http.test | 24 +++++++++++++++++++----- 2 files changed, 50 insertions(+), 15 deletions(-) diff --git a/library/http/http.tcl b/library/http/http.tcl index 751ca13..5a05fa0 100644 --- a/library/http/http.tcl +++ b/library/http/http.tcl @@ -566,6 +566,10 @@ proc http::geturl {url args} { # Proxy connections aren't shared among different hosts. set state(socketinfo) $host:$port + # Save the accept types at this point to prevent a race condition. [Bug + # c11a51c482] + set state(accept-types) $http(-accept) + # See if we are supposed to use a previously opened channel. if {$state(-keepalive)} { variable socketmap @@ -637,8 +641,20 @@ proc http::geturl {url args} { return $token } +# http::Connected -- +# +# Callback used when the connection to the HTTP server is actually +# established. +# +# Arguments: +# 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: +# None. -proc http::Connected { token proto phost srvurl} { +proc http::Connected {token proto phost srvurl} { variable http variable urlTypes @@ -691,13 +707,12 @@ proc http::Connected { token proto phost srvurl} { if {[info exists state(-handler)]} { set state(-protocol) 1.0 } + set accept_types_seen 0 if {[catch { puts $sock "$how $srvurl HTTP/$state(-protocol)" - puts $sock "Accept: $http(-accept)" - array set hdrs $state(-headers) - if {[info exists hdrs(Host)]} { + if {[dict exists $state(-headers) Host]} { # Allow Host spoofing. [Bug 928154] - puts $sock "Host: $hdrs(Host)" + puts $sock "Host: [dict get $state(-headers) Host]" } elseif {$port == $defport} { # Don't add port in this case, to handle broken servers. [Bug # #504508] @@ -705,7 +720,6 @@ proc http::Connected { token proto phost srvurl} { } else { puts $sock "Host: $host:$port" } - unset hdrs puts $sock "User-Agent: $http(-useragent)" if {$state(-protocol) == 1.0 && $state(-keepalive)} { puts $sock "Connection: keep-alive" @@ -718,18 +732,21 @@ proc http::Connected { token proto phost srvurl} { } set accept_encoding_seen 0 set content_type_seen 0 - foreach {key value} $state(-headers) { + dict for {key value} $state(-headers) { + set value [string map [list \n "" \r ""] $value] + set key [string map {" " -} [string trim $key]] if {[string equal -nocase $key "host"]} { continue } if {[string equal -nocase $key "accept-encoding"]} { set accept_encoding_seen 1 } + if {[string equal -nocase $key "accept"]} { + set accept_types_seen 1 + } if {[string equal -nocase $key "content-type"]} { set content_type_seen 1 } - set value [string map [list \n "" \r ""] $value] - set key [string trim $key] if {[string equal -nocase $key "content-length"]} { set contDone 1 set state(querylength) $value @@ -738,6 +755,11 @@ proc http::Connected { token proto phost srvurl} { puts $sock "$key: $value" } } + # Allow overriding the Accept header on a per-connection basis. Useful + # for working with REST services. [Bug c11a51c482] + if {!$accept_types_seen} { + puts $sock "Accept: $state(accept-types)" + } if {!$accept_encoding_seen && ![info exists state(-handler)]} { puts $sock "Accept-Encoding: gzip,deflate,compress" } @@ -795,7 +817,6 @@ proc http::Connected { token proto phost srvurl} { Finish $token $err } } - } # Data access functions: diff --git a/tests/http.test b/tests/http.test index a0a26de..41820cb 100644 --- a/tests/http.test +++ b/tests/http.test @@ -306,7 +306,6 @@ test http-3.13 {http::geturl socket leak test} { for {set i 0} {$i < 3} {incr i} { catch {http::geturl $badurl -timeout 5000} } - # No extra channels should be taken expr {[llength [file channels]] == $chanCount} } 1 @@ -372,11 +371,11 @@ test http-3.27 {http::geturl: -headers override -type} -body { http::data $token } -cleanup { http::cleanup $token -} -match regexp -result {(?n)Accept \*/\* -Host .* +} -match regexp -result {(?n)Host .* User-Agent .* Connection close Content-Type {text/plain;charset=utf-8} +Accept \*/\* Accept-Encoding .* Content-Length 5} test http-3.28 {http::geturl: -headers override -type default} -body { @@ -385,11 +384,11 @@ test http-3.28 {http::geturl: -headers override -type default} -body { http::data $token } -cleanup { http::cleanup $token -} -match regexp -result {(?n)Accept \*/\* -Host .* +} -match regexp -result {(?n)Host .* User-Agent .* Connection close Content-Type {text/plain;charset=utf-8} +Accept \*/\* Accept-Encoding .* Content-Length 5} test http-3.29 {http::geturl IPv6 address} -body { @@ -418,6 +417,21 @@ test http-3.31 {http::geturl fragment without path} -body { } -cleanup { catch { http::cleanup $token } } -result 200 +# Bug c11a51c482 +test http-3.32 {http::geturl: -headers override -accept default} -body { + set token [http::geturl $url/headers -query dummy \ + -headers [list "Accept" "text/plain,application/tcl-test-value"]] + http::data $token +} -cleanup { + http::cleanup $token +} -match regexp -result {(?n)Host .* +User-Agent .* +Connection close +Accept text/plain,application/tcl-test-value +Accept-Encoding .* +Content-Type application/x-www-form-urlencoded +Content-Length 5} + test http-4.1 {http::Event} -body { set token [http::geturl $url -keepalive 0] upvar #0 $token data -- cgit v0.12 From fdf990faf546306bbc55b4ad6fcd0d4922b303ef Mon Sep 17 00:00:00 2001 From: dkf Date: Mon, 18 May 2015 08:20:43 +0000 Subject: [11250a236d] Made the documentation of non-greediness overrides more obvious. --- doc/re_syntax.n | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/doc/re_syntax.n b/doc/re_syntax.n index 46a180d..7988071 100644 --- a/doc/re_syntax.n +++ b/doc/re_syntax.n @@ -683,9 +683,33 @@ earlier in the RE taking priority over ones starting later. Note that outer subexpressions thus take priority over their component subexpressions. .PP -Note that the quantifiers \fB{1,1}\fR and \fB{1,1}?\fR can be used to +The quantifiers \fB{1,1}\fR and \fB{1,1}?\fR can be used to force longest and shortest preference, respectively, on a subexpression or a whole RE. +.RS +.PP +\fBNOTE:\fR This means that you can usually make a RE be non-greedy overall by +putting \fB{1,1}?\fR after one of the first non-constraint atoms or +parenthesized sub-expressions in it. \fIIt pays to experiment\fR with the +placing of this non-greediness override on a suitable range of input texts +when you are writing a RE if you are using this level of complexity. +.PP +For example, this regular expression is non-greedy, and will match the +shortest substring possible given that +.QW \fBabc\fR +will be matched as early as possible (the quantifier does not change that): +.PP +.CS +ab{1,1}?c.*x.*cba +.CE +.PP +The atom +.QW \fBa\fR +has no greediness preference, we explicitly give one for +.QW \fBb\fR , +and the remaining quantifiers are overridden to be non-greedy by the preceding +non-greedy quantifier. +.RE .PP Match lengths are measured in characters, not collating elements. An empty string is considered longer than no match at all. For example, -- cgit v0.12 From 6be68f173f6cd81cb735935f722576ac2a7d7274 Mon Sep 17 00:00:00 2001 From: dgp Date: Tue, 19 May 2015 19:22:48 +0000 Subject: Don't cause string rep generation in [list ... ] bytecode. Candidate for merge to trunk to simplify bytecode. --- generic/tclCompCmdsGR.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/generic/tclCompCmdsGR.c b/generic/tclCompCmdsGR.c index b77c43c..3a25978 100644 --- a/generic/tclCompCmdsGR.c +++ b/generic/tclCompCmdsGR.c @@ -1210,20 +1210,21 @@ TclCompileListCmd( valueTokenPtr = TokenAfter(valueTokenPtr); } if (listObj != NULL) { - int len; - const char *bytes = Tcl_GetStringFromObj(listObj, &len); +// int len; +// const char *bytes = Tcl_GetStringFromObj(listObj, &len); - PushLiteral(envPtr, bytes, len); - Tcl_DecrRefCount(listObj); - if (len > 0) { +// PushLiteral(envPtr, bytes, len); + TclEmitPush(TclAddLiteralObj(envPtr, listObj, NULL), envPtr); +// Tcl_DecrRefCount(listObj); +// if (len > 0) { /* * Force list interpretation! */ - TclEmitOpcode( INST_DUP, envPtr); - TclEmitOpcode( INST_LIST_LENGTH, envPtr); - TclEmitOpcode( INST_POP, envPtr); - } +// TclEmitOpcode( INST_DUP, envPtr); +// TclEmitOpcode( INST_LIST_LENGTH, envPtr); +// TclEmitOpcode( INST_POP, envPtr); +// } return TCL_OK; } -- cgit v0.12 From acdb6bc3845dc9b36f2f691c34871563ad3071e9 Mon Sep 17 00:00:00 2001 From: dkf Date: Tue, 19 May 2015 20:29:47 +0000 Subject: Tidier version. --- generic/tclCompCmdsGR.c | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/generic/tclCompCmdsGR.c b/generic/tclCompCmdsGR.c index 3a25978..b9c655b 100644 --- a/generic/tclCompCmdsGR.c +++ b/generic/tclCompCmdsGR.c @@ -1210,21 +1210,7 @@ TclCompileListCmd( valueTokenPtr = TokenAfter(valueTokenPtr); } if (listObj != NULL) { -// int len; -// const char *bytes = Tcl_GetStringFromObj(listObj, &len); - -// PushLiteral(envPtr, bytes, len); - TclEmitPush(TclAddLiteralObj(envPtr, listObj, NULL), envPtr); -// Tcl_DecrRefCount(listObj); -// if (len > 0) { - /* - * Force list interpretation! - */ - -// TclEmitOpcode( INST_DUP, envPtr); -// TclEmitOpcode( INST_LIST_LENGTH, envPtr); -// TclEmitOpcode( INST_POP, envPtr); -// } + TclEmitPush(TclAddLiteralObj(envPtr, listObj, NULL), envPtr); return TCL_OK; } -- cgit v0.12 From babd0b88a06e19c7bc397a51309a84420a42068e Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 20 May 2015 15:12:50 +0000 Subject: [29044ba23f] Remove RANLIB as part of library installation. At best it's redundant to the RANLIB already done as part of library build. At worst, it conflicts with needs of cross-compiling. Thanks Erik Leunissen. --- unix/Makefile.in | 4 ---- unix/configure | 3 +-- unix/tcl.m4 | 3 +-- 3 files changed, 2 insertions(+), 8 deletions(-) diff --git a/unix/Makefile.in b/unix/Makefile.in index 958e759..18c90fa 100644 --- a/unix/Makefile.in +++ b/unix/Makefile.in @@ -783,10 +783,6 @@ install-strip: INSTALL_PROGRAM="$(INSTALL_PROGRAM) ${INSTALL_STRIP_PROGRAM}" \ INSTALL_LIBRARY="$(INSTALL_LIBRARY) ${INSTALL_STRIP_LIBRARY}" -# Note: before running ranlib below, must cd to target directory because some -# ranlibs write to current directory, and this might not always be possible -# (e.g. if installing as root). - install-binaries: binaries @for i in "$(LIB_INSTALL_DIR)" "$(BIN_INSTALL_DIR)" \ "$(CONFIG_INSTALL_DIR)"; \ diff --git a/unix/configure b/unix/configure index cb46f8d..a7a0bec 100755 --- a/unix/configure +++ b/unix/configure @@ -8856,15 +8856,14 @@ else if test "$RANLIB" = ""; then MAKE_LIB='$(STLIB_LD) $@ ${OBJS}' - INSTALL_LIB='$(INSTALL_LIBRARY) $(LIB_FILE) "$(LIB_INSTALL_DIR)/$(LIB_FILE)"' else MAKE_LIB='${STLIB_LD} $@ ${OBJS} ; ${RANLIB} $@' - INSTALL_LIB='$(INSTALL_LIBRARY) $(LIB_FILE) "$(LIB_INSTALL_DIR)/$(LIB_FILE)" ; (cd "$(LIB_INSTALL_DIR)" ; $(RANLIB) $(LIB_FILE))' fi + INSTALL_LIB='$(INSTALL_LIBRARY) $(LIB_FILE) "$(LIB_INSTALL_DIR)/$(LIB_FILE)"' fi diff --git a/unix/tcl.m4 b/unix/tcl.m4 index 25c2699..a6f4241 100644 --- a/unix/tcl.m4 +++ b/unix/tcl.m4 @@ -2060,11 +2060,10 @@ dnl # preprocessing tests use only CPPFLAGS. AS_IF([test "$RANLIB" = ""], [ MAKE_LIB='$(STLIB_LD) [$]@ ${OBJS}' - INSTALL_LIB='$(INSTALL_LIBRARY) $(LIB_FILE) "$(LIB_INSTALL_DIR)/$(LIB_FILE)"' ], [ MAKE_LIB='${STLIB_LD} [$]@ ${OBJS} ; ${RANLIB} [$]@' - INSTALL_LIB='$(INSTALL_LIBRARY) $(LIB_FILE) "$(LIB_INSTALL_DIR)/$(LIB_FILE)" ; (cd "$(LIB_INSTALL_DIR)" ; $(RANLIB) $(LIB_FILE))' ]) + INSTALL_LIB='$(INSTALL_LIBRARY) $(LIB_FILE) "$(LIB_INSTALL_DIR)/$(LIB_FILE)"' ]) # Stub lib does not depend on shared/static configuration -- cgit v0.12 From 2ce1ce01c52c274fe9d0411c6fdc7d7dab9b79f0 Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 20 May 2015 15:15:46 +0000 Subject: Missed a bit --- unix/configure | 3 +-- unix/tcl.m4 | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/unix/configure b/unix/configure index a7a0bec..0b42510 100755 --- a/unix/configure +++ b/unix/configure @@ -8872,15 +8872,14 @@ fi 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)"' else MAKE_STUB_LIB='${STLIB_LD} $@ ${STUB_LIB_OBJS} ; ${RANLIB} $@' - INSTALL_STUB_LIB='$(INSTALL_LIBRARY) $(STUB_LIB_FILE) "$(LIB_INSTALL_DIR)/$(STUB_LIB_FILE)" ; (cd "$(LIB_INSTALL_DIR)" ; $(RANLIB) $(STUB_LIB_FILE))' fi + INSTALL_STUB_LIB='$(INSTALL_LIBRARY) $(STUB_LIB_FILE) "$(LIB_INSTALL_DIR)/$(STUB_LIB_FILE)"' # 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 diff --git a/unix/tcl.m4 b/unix/tcl.m4 index a6f4241..67c442c 100644 --- a/unix/tcl.m4 +++ b/unix/tcl.m4 @@ -2069,11 +2069,10 @@ dnl # preprocessing tests use only CPPFLAGS. # Stub lib does not depend on shared/static configuration AS_IF([test "$RANLIB" = ""], [ MAKE_STUB_LIB='${STLIB_LD} [$]@ ${STUB_LIB_OBJS}' - INSTALL_STUB_LIB='$(INSTALL_LIBRARY) $(STUB_LIB_FILE) "$(LIB_INSTALL_DIR)/$(STUB_LIB_FILE)"' ], [ MAKE_STUB_LIB='${STLIB_LD} [$]@ ${STUB_LIB_OBJS} ; ${RANLIB} [$]@' - INSTALL_STUB_LIB='$(INSTALL_LIBRARY) $(STUB_LIB_FILE) "$(LIB_INSTALL_DIR)/$(STUB_LIB_FILE)" ; (cd "$(LIB_INSTALL_DIR)" ; $(RANLIB) $(STUB_LIB_FILE))' ]) + INSTALL_STUB_LIB='$(INSTALL_LIBRARY) $(STUB_LIB_FILE) "$(LIB_INSTALL_DIR)/$(STUB_LIB_FILE)"' # 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 -- cgit v0.12 From 907aebaab8fa670337c01ce70b784d5805e01f77 Mon Sep 17 00:00:00 2001 From: andreask Date: Fri, 22 May 2015 20:21:48 +0000 Subject: Moved Tcl_Obj* objThreadMap release tracking to a location where regular packages will call through, enabling their full tracking by the core, and thus avoiding the "expected to create new entry for object map" panic seen otherwise. --- generic/tclObj.c | 46 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 32 insertions(+), 14 deletions(-) diff --git a/generic/tclObj.c b/generic/tclObj.c index 96a4082..037bd76 100644 --- a/generic/tclObj.c +++ b/generic/tclObj.c @@ -1315,6 +1315,38 @@ TclFreeObj( register Tcl_Obj *objPtr) /* The object to be freed. */ { register Tcl_ObjType *typePtr = objPtr->typePtr; +# ifdef TCL_THREADS + /* + * Check to make sure that the Tcl_Obj was allocated by the current + * thread. Don't do this check when shutting down since thread local + * storage can be finalized before the last Tcl_Obj is freed. + */ + + if (!TclInExit()) { + Tcl_HashTable *tablePtr; + Tcl_HashEntry *hPtr; + ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); + + tablePtr = tsdPtr->objThreadMap; + if (!tablePtr) { + Tcl_Panic("TclFreeObj: object table not initialized"); + } + hPtr = Tcl_FindHashEntry(tablePtr, (char *) objPtr); + if (hPtr) { + /* + * As the Tcl_Obj is going to be deleted we remove the entry. + */ + + ObjData *objData = Tcl_GetHashValue(hPtr); + + if (objData != NULL) { + ckfree((char *) objData); + } + + Tcl_DeleteHashEntry(hPtr); + } + } +# endif /* * This macro declares a variable, so must come here... @@ -3715,20 +3747,6 @@ Tcl_DbDecrRefCount( "Trying to decr ref count of " "Tcl_Obj allocated in another thread"); } - - /* - * If the Tcl_Obj is going to be deleted, remove the entry. - */ - - if ((objPtr->refCount - 1) <= 0) { - ObjData *objData = Tcl_GetHashValue(hPtr); - - if (objData != NULL) { - ckfree((char *) objData); - } - - Tcl_DeleteHashEntry(hPtr); - } } # endif #endif -- cgit v0.12 From 17420ef9f04b1e785a91da0d8e10a36eed8a9079 Mon Sep 17 00:00:00 2001 From: Joe Mistachkin Date: Fri, 22 May 2015 23:26:29 +0000 Subject: Minor compilation issue fix, make sure variable declaration (via macro) is first. --- generic/tclObj.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/generic/tclObj.c b/generic/tclObj.c index 037bd76..36687fa 100644 --- a/generic/tclObj.c +++ b/generic/tclObj.c @@ -1315,6 +1315,13 @@ TclFreeObj( register Tcl_Obj *objPtr) /* The object to be freed. */ { register Tcl_ObjType *typePtr = objPtr->typePtr; + + /* + * This macro declares a variable, so must come here... + */ + + ObjInitDeletionContext(context); + # ifdef TCL_THREADS /* * Check to make sure that the Tcl_Obj was allocated by the current @@ -1349,12 +1356,6 @@ TclFreeObj( # endif /* - * This macro declares a variable, so must come here... - */ - - ObjInitDeletionContext(context); - - /* * Check for a double free of the same value. This is slightly tricky * because it is customary to free a Tcl_Obj when its refcount falls * either from 1 to 0, or from 0 to -1. Falling from -1 to -2, though, -- cgit v0.12 From d93aaadc5e22d899f2d7cfc7b663e6fd02d5bb1a Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Mon, 25 May 2015 19:15:25 +0000 Subject: Remove useless code, trying to sync win32 environment variables with cygwin's. cygwin1.dll is responsible for doing that. Taken over from cygwin's tcl fork. --- generic/tclEnv.c | 100 +---------------------------------------------------- unix/tclUnixPort.h | 3 -- 2 files changed, 1 insertion(+), 102 deletions(-) diff --git a/generic/tclEnv.c b/generic/tclEnv.c index f2395e6..caa80f1 100644 --- a/generic/tclEnv.c +++ b/generic/tclEnv.c @@ -43,11 +43,6 @@ static char * EnvTraceProc(ClientData clientData, Tcl_Interp *interp, static void ReplaceString(const char *oldStr, char *newStr); MODULE_SCOPE void TclSetEnv(const char *name, const char *value); MODULE_SCOPE void TclUnsetEnv(const char *name); - -#if defined(__CYGWIN__) - static void TclCygwinPutenv(char *string); -# define putenv TclCygwinPutenv -#endif /* *---------------------------------------------------------------------- @@ -394,7 +389,7 @@ TclUnsetEnv( * that no = should be included, and Windows requires it. */ -#if defined(__WIN32__) || defined(__CYGWIN__) +#if defined(__WIN32__) string = ckalloc((unsigned) length+2); memcpy(string, name, (size_t) length); string[length] = '='; @@ -688,99 +683,6 @@ TclFinalizeEnvironment(void) } } -#if defined(__CYGWIN__) - -/* - * When using cygwin, when an environment variable changes, we need to synch - * with both the cygwin environment (in case the application C code calls - * fork) and the Windows environment (in case the application TCL code calls - * exec, which calls the Windows CreateProcess function). - */ -DLLIMPORT extern void __stdcall SetEnvironmentVariableA(const char*, const char *); - -static void -TclCygwinPutenv( - char *str) -{ - char *name, *value; - - /* - * Get the name and value, so that we can change the environment variable - * for Windows. - */ - - name = alloca(strlen(str) + 1); - strcpy(name, str); - for (value=name ; *value!='=' && *value!='\0' ; ++value) { - /* Empty body */ - } - if (*value == '\0') { - /* Can't happen. */ - return; - } - *value = '\0'; - ++value; - if (*value == '\0') { - value = NULL; - } - - /* - * Set the cygwin environment variable. - */ - -#undef putenv - if (value == NULL) { - unsetenv(name); - } else { - putenv(str); - } - - /* - * Before changing the environment variable in Windows, if this is PATH, - * we need to convert the value back to a Windows style path. - * - * FIXME: The calling program may know it is running under windows, and - * may have set the path to a Windows path, or, worse, appended or - * prepended a Windows path to PATH. - */ - - if (strcmp(name, "PATH") != 0) { - /* - * If this is Path, eliminate any PATH variable, to prevent any - * confusion. - */ - - if (strcmp(name, "Path") == 0) { - SetEnvironmentVariableA("PATH", NULL); - unsetenv("PATH"); - } - - SetEnvironmentVariableA(name, value); - } else { - char *buf; - - /* - * Eliminate any Path variable, to prevent any confusion. - */ - - SetEnvironmentVariableA("Path", NULL); - unsetenv("Path"); - - if (value == NULL) { - buf = NULL; - } else { - int size; - - size = cygwin_conv_path_list(0, value, NULL, 0); - buf = alloca(size + 1); - cygwin_conv_path_list(0, value, buf, size); - } - - SetEnvironmentVariableA(name, buf); - } -} -#endif /* __CYGWIN__ */ - /* * Local Variables: * mode: c diff --git a/unix/tclUnixPort.h b/unix/tclUnixPort.h index 08a4f44..965014e 100644 --- a/unix/tclUnixPort.h +++ b/unix/tclUnixPort.h @@ -91,9 +91,6 @@ typedef off_t Tcl_SeekOffset; const char *, int, const char *, const char *); __declspec(dllimport) extern int cygwin_conv_path(int, const void *, void *, int); - __declspec(dllimport) extern int cygwin_conv_path_list(int, const void *, void *, int); -# define USE_PUTENV 1 -# define USE_PUTENV_FOR_UNSET 1 /* On Cygwin, the environment is imported from the Cygwin DLL. */ #ifndef __x86_64__ # define environ __cygwin_environ -- cgit v0.12 From 8c32ef71daf836ec84bf6b3ee987e92d4dde7101 Mon Sep 17 00:00:00 2001 From: dkf Date: Tue, 26 May 2015 10:16:24 +0000 Subject: Added missing marker for incompatibility. --- changes | 1 + 1 file changed, 1 insertion(+) diff --git a/changes b/changes index 8dffa37..57f8f52 100644 --- a/changes +++ b/changes @@ -8455,6 +8455,7 @@ include ::oo::class (fellows) 2014-08-28 (bug)[b9e1a3] Correct Method Search Order (nadkarni,fellows) => TclOO 1.0.3 + *** POTENTIAL INCOMPATIBILITY *** 2014-09-05 (bug)[ccc2c2] Regression [lreplace {} 1 1] (bron,fellows) -- cgit v0.12 From 94d9bfa88474d1d56b1a6df53849706c7261e743 Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 3 Jun 2015 12:26:38 +0000 Subject: [268b23df11] When GetSrcInfoForPc() returns NULL, make sure it also sets the length to a non-positive value so nothing tries to read offsets from a NULL pointer. --- generic/tclExecute.c | 14 ++++++-------- tests/execute.test | 14 ++++++++++++++ 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/generic/tclExecute.c b/generic/tclExecute.c index 43c2b08..5957951 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -9995,10 +9995,8 @@ GetSrcInfoForPc( int bestSrcLength = -1; /* Initialized to avoid compiler warning. */ int bestCmdIdx = -1; - if ((pcOffset < 0) || (pcOffset >= codePtr->numCodeBytes)) { - if (pcBeg != NULL) *pcBeg = NULL; - return NULL; - } + /* The pc must point within the bytecode */ + assert ((pcOffset >= 0) && (pcOffset < codePtr->numCodeBytes)); /* * Decode the code and source offset and length for each command. The @@ -10083,10 +10081,6 @@ GetSrcInfoForPc( *pcBeg = prev; } - if (bestDist == INT_MAX) { - return NULL; - } - if (lengthPtr != NULL) { *lengthPtr = bestSrcLength; } @@ -10095,6 +10089,10 @@ GetSrcInfoForPc( *cmdIdxPtr = bestCmdIdx; } + if (bestDist == INT_MAX) { + return NULL; + } + return (codePtr->source + bestSrcOffset); } diff --git a/tests/execute.test b/tests/execute.test index 94af158..aaf4bc0 100644 --- a/tests/execute.test +++ b/tests/execute.test @@ -1043,6 +1043,20 @@ test execute-11.1 {Bug 3142026: GrowEvaluationStack off-by-one} -setup { } -cleanup { interp delete slave } -result ok + +test execute-11.2 {Bug 268b23df11} -setup { + proc zero {} {return 0} + proc crash {} {expr {abs([zero])}} + proc noop args {} + trace add execution crash enterstep noop +} -body { + crash +} -cleanup { + trace remove execution crash enterstep noop + rename noop {} + rename crash {} + rename zero {} +} -result 0 # cleanup if {[info commands testobj] != {}} { -- cgit v0.12 From aef7e0d6d9f5049697120bcb960865db92b14055 Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 3 Jun 2015 17:40:10 +0000 Subject: Put the ellipsis inside, not outside, the close quote. --- generic/tclDisassemble.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/generic/tclDisassemble.c b/generic/tclDisassemble.c index b3753c31..0a325b3 100644 --- a/generic/tclDisassemble.c +++ b/generic/tclDisassemble.c @@ -842,10 +842,10 @@ PrintSourceToObj( continue; } } - Tcl_AppendToObj(appendObj, "\"", -1); if (*p != '\0') { Tcl_AppendToObj(appendObj, "...", -1); } + Tcl_AppendToObj(appendObj, "\"", -1); } /* -- cgit v0.12 From 6f63d23863d8c38063f6a6689706fa8e9fae2469 Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 3 Jun 2015 19:08:15 +0000 Subject: [268b23df11] Revised patch to create phony source string when the original script does not actually contain the command being invoked. (Example: the tcl::mathfunc::* command invoked via [expr] interpretation) --- generic/tclExecute.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/generic/tclExecute.c b/generic/tclExecute.c index 5957951..4a6c009 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -8235,6 +8235,7 @@ TEBCresume( bytes = GetSrcInfoForPc(pc, codePtr, &length, NULL, NULL); opnd = TclGetUInt4AtPtr(pc+1); pc += (opnd-1); + assert(bytes); PUSH_OBJECT(Tcl_NewStringObj(bytes, length)); goto instEvalStk; } @@ -9900,7 +9901,12 @@ TclGetSourceFromFrame( cfPtr->cmd = GetSrcInfoForPc((unsigned char *) cfPtr->data.tebc.pc, codePtr, &cfPtr->len, NULL, NULL); } - cfPtr->cmdObj = Tcl_NewStringObj(cfPtr->cmd, cfPtr->len); + if (cfPtr->cmd) { + cfPtr->cmdObj = Tcl_NewStringObj(cfPtr->cmd, cfPtr->len); + } else { + cfPtr->cmdObj = Tcl_NewListObj(objc, objv); + cfPtr->cmd = Tcl_GetStringFromObj(cfPtr->cmdObj, &cfPtr->len); + } Tcl_IncrRefCount(cfPtr->cmdObj); } return cfPtr->cmdObj; @@ -10081,6 +10087,10 @@ GetSrcInfoForPc( *pcBeg = prev; } + if (bestDist == INT_MAX) { + return NULL; + } + if (lengthPtr != NULL) { *lengthPtr = bestSrcLength; } @@ -10089,10 +10099,6 @@ GetSrcInfoForPc( *cmdIdxPtr = bestCmdIdx; } - if (bestDist == INT_MAX) { - return NULL; - } - return (codePtr->source + bestSrcOffset); } -- cgit v0.12 From 2e307120931a7073a581e319769d14fdb657f534 Mon Sep 17 00:00:00 2001 From: Joe Mistachkin Date: Fri, 5 Jun 2015 19:58:42 +0000 Subject: Fix typo in three thread tests. --- tests/thread.test | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/thread.test b/tests/thread.test index f32ef61..6032bae 100644 --- a/tests/thread.test +++ b/tests/thread.test @@ -564,7 +564,7 @@ test thread-7.14 {cancel: vwait} -constraints {thread drainEventQueue} -setup { unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted } -body { set serverthread [thread::create -joinable \ - [string map [list %ID [thread::id]] { + [string map [list %ID% [thread::id]] { if {![info exists foo]} then { # signal the primary thread that we are ready # to be canceled now (we are running). @@ -616,7 +616,7 @@ test thread-7.16 {cancel: expr} -constraints {thread drainEventQueue} -setup { unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted } -body { set serverthread [thread::create -joinable \ - [string map [list %ID [thread::id]] { + [string map [list %ID% [thread::id]] { set i [interp create] $i eval "package require -exact Thread [package present Thread]" $i eval { @@ -1372,7 +1372,7 @@ test thread-7.37 {cancel: send async thread cancel nested catch inside pure insi unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted } -body { set serverthread [thread::create -joinable \ - [string map [list %ID [thread::id]] { + [string map [list %ID% [thread::id]] { proc foobar {} { set catch catch set while while -- cgit v0.12 From 51bbc67659e00bbfe9d7253b82dbea13841c12d2 Mon Sep 17 00:00:00 2001 From: dgp Date: Mon, 8 Jun 2015 17:17:14 +0000 Subject: Stop telling lie about command delete traces. --- doc/TraceCmd.3 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/TraceCmd.3 b/doc/TraceCmd.3 index 7ff26e4..ed7f365 100644 --- a/doc/TraceCmd.3 +++ b/doc/TraceCmd.3 @@ -76,7 +76,7 @@ created. \fIClientData\fR typically points to an application-specific data structure that describes what to do when \fIproc\fR is invoked. \fIOldName\fR gives the name of the command being renamed, and \fInewName\fR gives the name that the command is being renamed to (or -an empty string or NULL when the command is being deleted.) +NULL when the command is being deleted.) \fIFlags\fR is an OR'ed combination of bits potentially providing several pieces of information. One of the bits \fBTCL_TRACE_RENAME\fR and \fBTCL_TRACE_DELETE\fR will be set in \fIflags\fR to indicate which -- cgit v0.12 From 2d6d821ea46c7d154c792103be52269f36cbb884 Mon Sep 17 00:00:00 2001 From: hypnotoad Date: Wed, 10 Jun 2015 21:53:47 +0000 Subject: Patch to add support for higher baud rates under Unix Ticket [e770d92d76]] --- unix/tclUnixChan.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/unix/tclUnixChan.c b/unix/tclUnixChan.c index a1fe090..b4b2739 100644 --- a/unix/tclUnixChan.c +++ b/unix/tclUnixChan.c @@ -988,6 +988,39 @@ static const struct {int baud; speed_t speed;} speeds[] = { #ifdef B460800 {460800, B460800}, #endif +#ifdef B500000 + {500000, B500000}, +#endif +#ifdef B576000 + {576000, B576000}, +#endif +#ifdef B921600 + {921600, B921600}, +#endif +#ifdef B1000000 + {1000000, B1000000}, +#endif +#ifdef B1152000 + {1152000, B1152000}, +#endif +#ifdef B1500000 + {1500000,B1500000}, +#endif +#ifdef B2000000 + {2000000, B2000000}, +#endif +#ifdef B2500000 + {2500000,B2500000}, +#endif +#ifdef B3000000 + {3000000,B3000000}, +#endif +#ifdef B3500000 + {3500000,B3500000}, +#endif +#ifdef B4000000 + {4000000,B4000000}, +#endif {-1, 0} }; -- cgit v0.12 From e99979bfcfa11a59f05746da9d5e2961ef21c5c8 Mon Sep 17 00:00:00 2001 From: Joe Mistachkin Date: Thu, 11 Jun 2015 02:47:41 +0000 Subject: Plug memory leaks in the Tcl_ZlibInflate() error handling code. Fix for ticket [478c446889]. --- generic/tclZlib.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/generic/tclZlib.c b/generic/tclZlib.c index 956e3f9..c5ccc72 100644 --- a/generic/tclZlib.c +++ b/generic/tclZlib.c @@ -1757,6 +1757,7 @@ Tcl_ZlibInflate( if (headerPtr) { e = inflateGetHeader(&stream, headerPtr); if (e != Z_OK) { + inflateEnd(&stream); goto error; } } @@ -1780,7 +1781,7 @@ Tcl_ZlibInflate( if ((stream.avail_in == 0) && (stream.avail_out > 0)) { e = Z_STREAM_ERROR; - goto error; + break; } newBufferSize = bufferSize + 5 * stream.avail_in; if (newBufferSize == bufferSize) { -- cgit v0.12 From ea9f9ac81ed1924402c16e0bd4674a065acb80b8 Mon Sep 17 00:00:00 2001 From: aspect Date: Tue, 16 Jun 2015 00:41:39 +0000 Subject: fix for a4cb3f06c4fe - bug introduced in 32b61592465 --- generic/tclCompCmdsGR.c | 2 +- tests/lreplace.test | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/generic/tclCompCmdsGR.c b/generic/tclCompCmdsGR.c index b77c43c..8d8f2cc 100644 --- a/generic/tclCompCmdsGR.c +++ b/generic/tclCompCmdsGR.c @@ -1501,7 +1501,7 @@ TclCompileLreplaceCmd( return TCL_ERROR; } - if(idx2 != INDEX_END && idx2 < idx1) { + if(idx2 != INDEX_END && idx2 >= 0 && idx2 < idx1) { idx2 = idx1-1; } diff --git a/tests/lreplace.test b/tests/lreplace.test index d1319c6..cf0ae51 100644 --- a/tests/lreplace.test +++ b/tests/lreplace.test @@ -146,6 +146,9 @@ test lreplace-4.4 {lreplace edge case} { test lreplace-4.5 {lreplace edge case} { lreplace {1 2 3 4 5} 3 0 _ } {1 2 3 _ 4 5} +test lreplace-4.6 {lreplace end-x: bug a4cb3f06c4} { + lreplace {0 1 2 3 4} 0 end-2 +} {3 4} # cleanup catch {unset foo} -- cgit v0.12 From e008d75c192dae4c3d66b2f653c8c67c16fa157a Mon Sep 17 00:00:00 2001 From: aspect Date: Tue, 16 Jun 2015 03:33:22 +0000 Subject: lreplace: more tests, doc improvement --- doc/lreplace.n | 2 +- tests/lreplace.test | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/doc/lreplace.n b/doc/lreplace.n index 7bba543..d19f0cd 100644 --- a/doc/lreplace.n +++ b/doc/lreplace.n @@ -35,7 +35,7 @@ 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 at the point specified by \fIfirst\fR +will be inserted into the list before the point specified by \fIfirst\fR with no elements being deleted. .PP The \fIelement\fR arguments specify zero or more new arguments to diff --git a/tests/lreplace.test b/tests/lreplace.test index cf0ae51..ea88c07 100644 --- a/tests/lreplace.test +++ b/tests/lreplace.test @@ -149,6 +149,39 @@ test lreplace-4.5 {lreplace edge case} { test lreplace-4.6 {lreplace end-x: bug a4cb3f06c4} { lreplace {0 1 2 3 4} 0 end-2 } {3 4} +test lreplace-4.6.1 {lreplace end-x: bug a4cb3f06c4} { + lreplace {0 1 2 3 4} 0 end-2 a b c +} {a b c 3 4} +test lreplace-4.7 {lreplace with two end-indexes: increasing} { + lreplace {0 1 2 3 4} end-2 end-1 +} {0 1 4} +test lreplace-4.7.1 {lreplace with two end-indexes: increasing} { + lreplace {0 1 2 3 4} end-2 end-1 a b c +} {0 1 a b c 4} +test lreplace-4.8 {lreplace with two end-indexes: equal} { + lreplace {0 1 2 3 4} end-2 end-2 +} {0 1 3 4} +test lreplace-4.8.1 {lreplace with two end-indexes: equal} { + lreplace {0 1 2 3 4} end-2 end-2 a b c +} {0 1 a b c 3 4} +test lreplace-4.9 {lreplace with two end-indexes: decreasing} { + lreplace {0 1 2 3 4} end-2 end-3 +} {0 1 2 3 4} +test lreplace-4.9.1 {lreplace with two end-indexes: decreasing} { + lreplace {0 1 2 3 4} end-2 end-3 a b c +} {0 1 a b c 2 3 4} +test lreplace-4.10 {lreplace with two equal indexes} { + lreplace {0 1 2 3 4} 2 2 +} {0 1 3 4} +test lreplace-4.10.1 {lreplace with two equal indexes} { + lreplace {0 1 2 3 4} 2 2 a b c +} {0 1 a b c 3 4} +test lreplace-4.11 {lreplace end index first} { + lreplace {0 1 2 3 4} end-2 1 a b c +} {0 1 a b c 2 3 4} +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} # cleanup catch {unset foo} -- cgit v0.12 From e6c567a325651e8b157aca03154ce73e72cf55a7 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Thu, 18 Jun 2015 12:24:53 +0000 Subject: Upgrade all internal Unicode tables from Unicode 7.0 to Unicode 8.0 --- generic/regc_locale.c | 501 +++++++-------- generic/tclUniData.c | 1633 +++++++++++++++++++++++++------------------------ 2 files changed, 1090 insertions(+), 1044 deletions(-) diff --git a/generic/regc_locale.c b/generic/regc_locale.c index e056078..2a4248e 100644 --- a/generic/regc_locale.c +++ b/generic/regc_locale.c @@ -140,7 +140,7 @@ static const crange alphaRangeTable[] = { {0x3f7, 0x481}, {0x48a, 0x52f}, {0x531, 0x556}, {0x561, 0x587}, {0x5d0, 0x5ea}, {0x5f0, 0x5f2}, {0x620, 0x64a}, {0x671, 0x6d3}, {0x6fa, 0x6fc}, {0x712, 0x72f}, {0x74d, 0x7a5}, {0x7ca, 0x7ea}, - {0x800, 0x815}, {0x840, 0x858}, {0x8a0, 0x8b2}, {0x904, 0x939}, + {0x800, 0x815}, {0x840, 0x858}, {0x8a0, 0x8b4}, {0x904, 0x939}, {0x958, 0x961}, {0x971, 0x980}, {0x985, 0x98c}, {0x993, 0x9a8}, {0x9aa, 0x9b0}, {0x9b6, 0x9b9}, {0x9df, 0x9e1}, {0xa05, 0xa0a}, {0xa13, 0xa28}, {0xa2a, 0xa30}, {0xa59, 0xa5c}, {0xa72, 0xa74}, @@ -148,55 +148,58 @@ static const crange alphaRangeTable[] = { {0xab5, 0xab9}, {0xb05, 0xb0c}, {0xb13, 0xb28}, {0xb2a, 0xb30}, {0xb35, 0xb39}, {0xb5f, 0xb61}, {0xb85, 0xb8a}, {0xb8e, 0xb90}, {0xb92, 0xb95}, {0xba8, 0xbaa}, {0xbae, 0xbb9}, {0xc05, 0xc0c}, - {0xc0e, 0xc10}, {0xc12, 0xc28}, {0xc2a, 0xc39}, {0xc85, 0xc8c}, - {0xc8e, 0xc90}, {0xc92, 0xca8}, {0xcaa, 0xcb3}, {0xcb5, 0xcb9}, - {0xd05, 0xd0c}, {0xd0e, 0xd10}, {0xd12, 0xd3a}, {0xd7a, 0xd7f}, - {0xd85, 0xd96}, {0xd9a, 0xdb1}, {0xdb3, 0xdbb}, {0xdc0, 0xdc6}, - {0xe01, 0xe30}, {0xe40, 0xe46}, {0xe94, 0xe97}, {0xe99, 0xe9f}, - {0xea1, 0xea3}, {0xead, 0xeb0}, {0xec0, 0xec4}, {0xedc, 0xedf}, - {0xf40, 0xf47}, {0xf49, 0xf6c}, {0xf88, 0xf8c}, {0x1000, 0x102a}, - {0x1050, 0x1055}, {0x105a, 0x105d}, {0x106e, 0x1070}, {0x1075, 0x1081}, - {0x10a0, 0x10c5}, {0x10d0, 0x10fa}, {0x10fc, 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}, - {0x1380, 0x138f}, {0x13a0, 0x13f4}, {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, 0x18a8}, - {0x18b0, 0x18f5}, {0x1900, 0x191e}, {0x1950, 0x196d}, {0x1970, 0x1974}, - {0x1980, 0x19ab}, {0x19c1, 0x19c7}, {0x1a00, 0x1a16}, {0x1a20, 0x1a54}, - {0x1b05, 0x1b33}, {0x1b45, 0x1b4b}, {0x1b83, 0x1ba0}, {0x1bba, 0x1be5}, - {0x1c00, 0x1c23}, {0x1c4d, 0x1c4f}, {0x1c5a, 0x1c7d}, {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, 0x312d}, {0x3131, 0x318e}, {0x31a0, 0x31ba}, {0x31f0, 0x31ff}, - {0x3400, 0x4db5}, {0x4e00, 0x9fcc}, {0xa000, 0xa48c}, {0xa4d0, 0xa4fd}, - {0xa500, 0xa60c}, {0xa610, 0xa61f}, {0xa640, 0xa66e}, {0xa67f, 0xa69d}, - {0xa6a0, 0xa6e5}, {0xa717, 0xa71f}, {0xa722, 0xa788}, {0xa78b, 0xa78e}, - {0xa790, 0xa7ad}, {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, 0xab5f}, {0xabc0, 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} + {0xc0e, 0xc10}, {0xc12, 0xc28}, {0xc2a, 0xc39}, {0xc58, 0xc5a}, + {0xc85, 0xc8c}, {0xc8e, 0xc90}, {0xc92, 0xca8}, {0xcaa, 0xcb3}, + {0xcb5, 0xcb9}, {0xd05, 0xd0c}, {0xd0e, 0xd10}, {0xd12, 0xd3a}, + {0xd5f, 0xd61}, {0xd7a, 0xd7f}, {0xd85, 0xd96}, {0xd9a, 0xdb1}, + {0xdb3, 0xdbb}, {0xdc0, 0xdc6}, {0xe01, 0xe30}, {0xe40, 0xe46}, + {0xe94, 0xe97}, {0xe99, 0xe9f}, {0xea1, 0xea3}, {0xead, 0xeb0}, + {0xec0, 0xec4}, {0xedc, 0xedf}, {0xf40, 0xf47}, {0xf49, 0xf6c}, + {0xf88, 0xf8c}, {0x1000, 0x102a}, {0x1050, 0x1055}, {0x105a, 0x105d}, + {0x106e, 0x1070}, {0x1075, 0x1081}, {0x10a0, 0x10c5}, {0x10d0, 0x10fa}, + {0x10fc, 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}, {0x1380, 0x138f}, {0x13a0, 0x13f5}, + {0x13f8, 0x13fd}, {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, 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}, {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, 0x312d}, + {0x3131, 0x318e}, {0x31a0, 0x31ba}, {0x31f0, 0x31ff}, {0x3400, 0x4db5}, + {0x4e00, 0x9fd5}, {0xa000, 0xa48c}, {0xa4d0, 0xa4fd}, {0xa500, 0xa60c}, + {0xa610, 0xa61f}, {0xa640, 0xa66e}, {0xa67f, 0xa69d}, {0xa6a0, 0xa6e5}, + {0xa717, 0xa71f}, {0xa722, 0xa788}, {0xa78b, 0xa7ad}, {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}, {0xdc00, 0xdc3e}, {0xdc40, 0xdc7e}, + {0xde80, 0xdebe}, {0xdec0, 0xdefe}, {0xdf00, 0xdf3e}, {0xdf40, 0xdf7e}, + {0xdf80, 0xdfbe}, {0xdfc0, 0xdffe}, {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 TCL_UTF_MAX > 4 ,{0x10000, 0x1000b}, {0x1000d, 0x10026}, {0x10028, 0x1003a}, {0x1003f, 0x1004d}, {0x10050, 0x1005d}, {0x10080, 0x100fa}, {0x10280, 0x1029c}, {0x102a0, 0x102d0}, @@ -204,30 +207,33 @@ static const crange alphaRangeTable[] = { {0x10380, 0x1039d}, {0x103a0, 0x103c3}, {0x103c8, 0x103cf}, {0x10400, 0x1049d}, {0x10500, 0x10527}, {0x10530, 0x10563}, {0x10600, 0x10736}, {0x10740, 0x10755}, {0x10760, 0x10767}, {0x10800, 0x10805}, {0x1080a, 0x10835}, {0x1083f, 0x10855}, - {0x10860, 0x10876}, {0x10880, 0x1089e}, {0x10900, 0x10915}, {0x10920, 0x10939}, - {0x10980, 0x109b7}, {0x10a10, 0x10a13}, {0x10a15, 0x10a17}, {0x10a19, 0x10a33}, - {0x10a60, 0x10a7c}, {0x10a80, 0x10a9c}, {0x10ac0, 0x10ac7}, {0x10ac9, 0x10ae4}, - {0x10b00, 0x10b35}, {0x10b40, 0x10b55}, {0x10b60, 0x10b72}, {0x10b80, 0x10b91}, - {0x10c00, 0x10c48}, {0x11003, 0x11037}, {0x11083, 0x110af}, {0x110d0, 0x110e8}, - {0x11103, 0x11126}, {0x11150, 0x11172}, {0x11183, 0x111b2}, {0x111c1, 0x111c4}, - {0x11200, 0x11211}, {0x11213, 0x1122b}, {0x112b0, 0x112de}, {0x11305, 0x1130c}, - {0x11313, 0x11328}, {0x1132a, 0x11330}, {0x11335, 0x11339}, {0x1135d, 0x11361}, - {0x11480, 0x114af}, {0x11580, 0x115ae}, {0x11600, 0x1162f}, {0x11680, 0x116aa}, - {0x118a0, 0x118df}, {0x11ac0, 0x11af8}, {0x12000, 0x12398}, {0x13000, 0x1342e}, - {0x16800, 0x16a38}, {0x16a40, 0x16a5e}, {0x16ad0, 0x16aed}, {0x16b00, 0x16b2f}, - {0x16b40, 0x16b43}, {0x16b63, 0x16b77}, {0x16b7d, 0x16b8f}, {0x16f00, 0x16f44}, - {0x16f93, 0x16f9f}, {0x1bc00, 0x1bc6a}, {0x1bc70, 0x1bc7c}, {0x1bc80, 0x1bc88}, - {0x1bc90, 0x1bc99}, {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, 0x1d6c0}, - {0x1d6c2, 0x1d6da}, {0x1d6dc, 0x1d6fa}, {0x1d6fc, 0x1d714}, {0x1d716, 0x1d734}, - {0x1d736, 0x1d74e}, {0x1d750, 0x1d76e}, {0x1d770, 0x1d788}, {0x1d78a, 0x1d7a8}, - {0x1d7aa, 0x1d7c2}, {0x1d7c4, 0x1d7cb}, {0x1e800, 0x1e8c4}, {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}, {0x20000, 0x2a6d6}, {0x2a700, 0x2b734}, {0x2b740, 0x2b81d}, + {0x10860, 0x10876}, {0x10880, 0x1089e}, {0x108e0, 0x108f2}, {0x10900, 0x10915}, + {0x10920, 0x10939}, {0x10980, 0x109b7}, {0x10a10, 0x10a13}, {0x10a15, 0x10a17}, + {0x10a19, 0x10a33}, {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}, {0x11480, 0x114af}, + {0x11580, 0x115ae}, {0x115d8, 0x115db}, {0x11600, 0x1162f}, {0x11680, 0x116aa}, + {0x11700, 0x11719}, {0x118a0, 0x118df}, {0x11ac0, 0x11af8}, {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}, + {0x1bc00, 0x1bc6a}, {0x1bc70, 0x1bc7c}, {0x1bc80, 0x1bc88}, {0x1bc90, 0x1bc99}, + {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, 0x1d6c0}, {0x1d6c2, 0x1d6da}, + {0x1d6dc, 0x1d6fa}, {0x1d6fc, 0x1d714}, {0x1d716, 0x1d734}, {0x1d736, 0x1d74e}, + {0x1d750, 0x1d76e}, {0x1d770, 0x1d788}, {0x1d78a, 0x1d7a8}, {0x1d7aa, 0x1d7c2}, + {0x1d7c4, 0x1d7cb}, {0x1e800, 0x1e8c4}, {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}, + {0x20000, 0x2a6d6}, {0x2a700, 0x2b734}, {0x2b740, 0x2b81d}, {0x2b820, 0x2cea1}, {0x2f800, 0x2fa1d} #endif }; @@ -240,27 +246,27 @@ static const chr alphaCharTable[] = { 0x6ff, 0x710, 0x7b1, 0x7f4, 0x7f5, 0x7fa, 0x81a, 0x824, 0x828, 0x93d, 0x950, 0x98f, 0x990, 0x9b2, 0x9bd, 0x9ce, 0x9dc, 0x9dd, 0x9f0, 0x9f1, 0xa0f, 0xa10, 0xa32, 0xa33, 0xa35, 0xa36, 0xa38, - 0xa39, 0xa5e, 0xab2, 0xab3, 0xabd, 0xad0, 0xae0, 0xae1, 0xb0f, - 0xb10, 0xb32, 0xb33, 0xb3d, 0xb5c, 0xb5d, 0xb71, 0xb83, 0xb99, - 0xb9a, 0xb9c, 0xb9e, 0xb9f, 0xba3, 0xba4, 0xbd0, 0xc3d, 0xc58, - 0xc59, 0xc60, 0xc61, 0xcbd, 0xcde, 0xce0, 0xce1, 0xcf1, 0xcf2, - 0xd3d, 0xd4e, 0xd60, 0xd61, 0xdbd, 0xe32, 0xe33, 0xe81, 0xe82, - 0xe84, 0xe87, 0xe88, 0xe8a, 0xe8d, 0xea5, 0xea7, 0xeaa, 0xeab, - 0xeb2, 0xeb3, 0xebd, 0xec6, 0xf00, 0x103f, 0x1061, 0x1065, 0x1066, - 0x108e, 0x10c7, 0x10cd, 0x1258, 0x12c0, 0x17d7, 0x17dc, 0x18aa, 0x1aa7, - 0x1bae, 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, 0xa7b0, 0xa7b1, 0xa8fb, 0xa9cf, 0xaa7a, - 0xaab1, 0xaab5, 0xaab6, 0xaac0, 0xaac2, 0xab64, 0xab65, 0xfb1d, 0xfb3e, - 0xfb40, 0xfb41, 0xfb43, 0xfb44 + 0xa39, 0xa5e, 0xab2, 0xab3, 0xabd, 0xad0, 0xae0, 0xae1, 0xaf9, + 0xb0f, 0xb10, 0xb32, 0xb33, 0xb3d, 0xb5c, 0xb5d, 0xb71, 0xb83, + 0xb99, 0xb9a, 0xb9c, 0xb9e, 0xb9f, 0xba3, 0xba4, 0xbd0, 0xc3d, + 0xc60, 0xc61, 0xcbd, 0xcde, 0xce0, 0xce1, 0xcf1, 0xcf2, 0xd3d, + 0xd4e, 0xdbd, 0xe32, 0xe33, 0xe81, 0xe82, 0xe84, 0xe87, 0xe88, + 0xe8a, 0xe8d, 0xea5, 0xea7, 0xeaa, 0xeab, 0xeb2, 0xeb3, 0xebd, + 0xec6, 0xf00, 0x103f, 0x1061, 0x1065, 0x1066, 0x108e, 0x10c7, 0x10cd, + 0x1258, 0x12c0, 0x17d7, 0x17dc, 0x18aa, 0x1aa7, 0x1bae, 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 #if TCL_UTF_MAX > 4 - ,0x1003c, 0x1003d, 0x10808, 0x10837, 0x10838, 0x1083c, 0x109be, 0x109bf, 0x10a00, - 0x11176, 0x111da, 0x1130f, 0x11310, 0x11332, 0x11333, 0x1133d, 0x114c4, 0x114c5, - 0x114c7, 0x11644, 0x118ff, 0x16f50, 0x1b000, 0x1b001, 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 + ,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, 0x16f50, + 0x1b000, 0x1b001, 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 }; @@ -309,8 +315,8 @@ static const crange digitRangeTable[] = { #if TCL_UTF_MAX > 4 ,{0x104a0, 0x104a9}, {0x11066, 0x1106f}, {0x110f0, 0x110f9}, {0x11136, 0x1113f}, {0x111d0, 0x111d9}, {0x112f0, 0x112f9}, {0x114d0, 0x114d9}, {0x11650, 0x11659}, - {0x116c0, 0x116c9}, {0x118e0, 0x118e9}, {0x16a60, 0x16a69}, {0x16b50, 0x16b59}, - {0x1d7ce, 0x1d7ff} + {0x116c0, 0x116c9}, {0x11730, 0x11739}, {0x118e0, 0x118e9}, {0x16a60, 0x16a69}, + {0x16b50, 0x16b59}, {0x1d7ce, 0x1d7ff} #endif }; @@ -342,8 +348,9 @@ static const crange punctRangeTable[] = { #if TCL_UTF_MAX > 4 ,{0x10100, 0x10102}, {0x10a50, 0x10a58}, {0x10af0, 0x10af6}, {0x10b39, 0x10b3f}, {0x10b99, 0x10b9c}, {0x11047, 0x1104d}, {0x110be, 0x110c1}, {0x11140, 0x11143}, - {0x111c5, 0x111c8}, {0x11238, 0x1123d}, {0x115c1, 0x115c9}, {0x11641, 0x11643}, - {0x12470, 0x12474}, {0x16b37, 0x16b3b} + {0x111c5, 0x111c9}, {0x111dd, 0x111df}, {0x11238, 0x1123d}, {0x115c1, 0x115d7}, + {0x11641, 0x11643}, {0x1173c, 0x1173e}, {0x12470, 0x12474}, {0x16b37, 0x16b3b}, + {0x1da87, 0x1da8b} #endif }; @@ -359,12 +366,13 @@ static const chr punctCharTable[] = { 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, 0xa92e, 0xa92f, 0xa95f, 0xa9de, 0xa9df, 0xaade, 0xaadf, - 0xaaf0, 0xaaf1, 0xabeb, 0xfd3e, 0xfd3f, 0xfe63, 0xfe68, 0xfe6a, 0xfe6b, - 0xff1a, 0xff1b, 0xff1f, 0xff20, 0xff3f, 0xff5b, 0xff5d + 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 TCL_UTF_MAX > 4 ,0x1039f, 0x103d0, 0x1056f, 0x10857, 0x1091f, 0x1093f, 0x10a7f, 0x110bb, 0x110bc, - 0x11174, 0x11175, 0x111cd, 0x114c6, 0x16a6e, 0x16a6f, 0x16af5, 0x16b44, 0x1bc9f + 0x11174, 0x11175, 0x111cd, 0x111db, 0x112a9, 0x114c6, 0x16a6e, 0x16a6f, 0x16af5, + 0x16b44, 0x1bc9f #endif }; @@ -375,14 +383,14 @@ static const chr punctCharTable[] = { */ static const crange spaceRangeTable[] = { - {0x9, 0xd}, {0x2000, 0x200a} + {0x9, 0xd}, {0x2000, 0x200b} }; #define NUM_SPACE_RANGE (sizeof(spaceRangeTable)/sizeof(crange)) static const chr spaceCharTable[] = { 0x20, 0xa0, 0x1680, 0x180e, 0x2028, 0x2029, 0x202f, 0x205f, - 0x3000 + 0x2060, 0x3000, 0xfeff }; #define NUM_SPACE_CHAR (sizeof(spaceCharTable)/sizeof(chr)) @@ -395,23 +403,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}, {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}, {0xfb00, 0xfb06}, - {0xfb13, 0xfb17}, {0xff41, 0xff5a} + {0x3ef, 0x3f3}, {0x430, 0x45f}, {0x561, 0x587}, {0x13f8, 0x13fd}, + {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 TCL_UTF_MAX > 4 - ,{0x10428, 0x1044f}, {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} + ,{0x10428, 0x1044f}, {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} #endif }; @@ -481,7 +491,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, - 0xa7fa, 0xab64, 0xab65 + 0xa7b5, 0xa7b7, 0xa7fa #if TCL_UTF_MAX > 4 ,0x1d4bb, 0x1d7cb #endif @@ -498,20 +508,20 @@ 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}, - {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, 0xa7ad}, {0xff21, 0xff3a} + {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, 0xa7ad}, {0xa7b0, 0xa7b4}, {0xff21, 0xff3a} #if TCL_UTF_MAX > 4 - ,{0x10400, 0x10427}, {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} + ,{0x10400, 0x10427}, {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} #endif }; @@ -580,8 +590,7 @@ 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, 0xa7b0, - 0xa7b1 + 0xa79a, 0xa79c, 0xa79e, 0xa7a0, 0xa7a2, 0xa7a4, 0xa7a6, 0xa7a8, 0xa7b6 #if TCL_UTF_MAX > 4 ,0x1d49c, 0x1d49e, 0x1d49f, 0x1d4a2, 0x1d4a5, 0x1d4a6, 0x1d504, 0x1d505, 0x1d538, 0x1d539, 0x1d546, 0x1d7ca @@ -600,8 +609,8 @@ static const crange graphRangeTable[] = { {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}, {0x8a0, 0x8b2}, - {0x8e4, 0x983}, {0x985, 0x98c}, {0x993, 0x9a8}, {0x9aa, 0x9b0}, + {0x800, 0x82d}, {0x830, 0x83e}, {0x840, 0x85b}, {0x8a0, 0x8b4}, + {0x8e3, 0x983}, {0x985, 0x98c}, {0x993, 0x9a8}, {0x9aa, 0x9b0}, {0x9b6, 0x9b9}, {0x9bc, 0x9c4}, {0x9cb, 0x9ce}, {0x9df, 0x9e3}, {0x9e6, 0x9fb}, {0xa01, 0xa03}, {0xa05, 0xa0a}, {0xa13, 0xa28}, {0xa2a, 0xa30}, {0xa3e, 0xa42}, {0xa4b, 0xa4d}, {0xa59, 0xa5c}, @@ -614,66 +623,67 @@ static const crange graphRangeTable[] = { {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}, {0xc60, 0xc63}, {0xc66, 0xc6f}, - {0xc78, 0xc7f}, {0xc81, 0xc83}, {0xc85, 0xc8c}, {0xc8e, 0xc90}, - {0xc92, 0xca8}, {0xcaa, 0xcb3}, {0xcb5, 0xcb9}, {0xcbc, 0xcc4}, - {0xcc6, 0xcc8}, {0xcca, 0xccd}, {0xce0, 0xce3}, {0xce6, 0xcef}, - {0xd01, 0xd03}, {0xd05, 0xd0c}, {0xd0e, 0xd10}, {0xd12, 0xd3a}, - {0xd3d, 0xd44}, {0xd46, 0xd48}, {0xd4a, 0xd4e}, {0xd60, 0xd63}, - {0xd66, 0xd75}, {0xd79, 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, 0x13f4}, {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, 0x1c7f}, {0x1cc0, 0x1cc7}, - {0x1cd0, 0x1cf6}, {0x1d00, 0x1df5}, {0x1dfc, 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, 0x20bd}, - {0x20d0, 0x20f0}, {0x2100, 0x2189}, {0x2190, 0x23fa}, {0x2400, 0x2426}, - {0x2440, 0x244a}, {0x2460, 0x2b73}, {0x2b76, 0x2b95}, {0x2b98, 0x2bb9}, - {0x2bbd, 0x2bc8}, {0x2bca, 0x2bd1}, {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, 0x2e42}, {0x2e80, 0x2e99}, {0x2e9b, 0x2ef3}, {0x2f00, 0x2fd5}, - {0x2ff0, 0x2ffb}, {0x3001, 0x303f}, {0x3041, 0x3096}, {0x3099, 0x30ff}, - {0x3105, 0x312d}, {0x3131, 0x318e}, {0x3190, 0x31ba}, {0x31c0, 0x31e3}, - {0x31f0, 0x321e}, {0x3220, 0x32fe}, {0x3300, 0x4db5}, {0x4dc0, 0x9fcc}, - {0xa000, 0xa48c}, {0xa490, 0xa4c6}, {0xa4d0, 0xa62b}, {0xa640, 0xa69d}, - {0xa69f, 0xa6f7}, {0xa700, 0xa78e}, {0xa790, 0xa7ad}, {0xa7f7, 0xa82b}, - {0xa830, 0xa839}, {0xa840, 0xa877}, {0xa880, 0xa8c4}, {0xa8ce, 0xa8d9}, - {0xa8e0, 0xa8fb}, {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, 0xab5f}, {0xabc0, 0xabed}, {0xabf0, 0xabf9}, {0xac00, 0xd7a3}, - {0xd7b0, 0xd7c6}, {0xd7cb, 0xd7fb}, {0xdc00, 0xdc3e}, {0xdc40, 0xdc7e}, - {0xdc80, 0xdcbe}, {0xdcc0, 0xdcfe}, {0xdd80, 0xddbe}, {0xddc0, 0xddfe}, - {0xde80, 0xdebe}, {0xdec0, 0xdefe}, {0xdf00, 0xdf3e}, {0xdf40, 0xdf7e}, + {0xc46, 0xc48}, {0xc4a, 0xc4d}, {0xc58, 0xc5a}, {0xc60, 0xc63}, + {0xc66, 0xc6f}, {0xc78, 0xc7f}, {0xc81, 0xc83}, {0xc85, 0xc8c}, + {0xc8e, 0xc90}, {0xc92, 0xca8}, {0xcaa, 0xcb3}, {0xcb5, 0xcb9}, + {0xcbc, 0xcc4}, {0xcc6, 0xcc8}, {0xcca, 0xccd}, {0xce0, 0xce3}, + {0xce6, 0xcef}, {0xd01, 0xd03}, {0xd05, 0xd0c}, {0xd0e, 0xd10}, + {0xd12, 0xd3a}, {0xd3d, 0xd44}, {0xd46, 0xd48}, {0xd4a, 0xd4e}, + {0xd5f, 0xd63}, {0xd66, 0xd75}, {0xd79, 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, 0x1c7f}, {0x1cc0, 0x1cc7}, {0x1cd0, 0x1cf6}, {0x1d00, 0x1df5}, + {0x1dfc, 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, 0x20be}, {0x20d0, 0x20f0}, {0x2100, 0x218b}, + {0x2190, 0x23fa}, {0x2400, 0x2426}, {0x2440, 0x244a}, {0x2460, 0x2b73}, + {0x2b76, 0x2b95}, {0x2b98, 0x2bb9}, {0x2bbd, 0x2bc8}, {0x2bca, 0x2bd1}, + {0x2bec, 0x2bef}, {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, 0x2e42}, + {0x2e80, 0x2e99}, {0x2e9b, 0x2ef3}, {0x2f00, 0x2fd5}, {0x2ff0, 0x2ffb}, + {0x3001, 0x303f}, {0x3041, 0x3096}, {0x3099, 0x30ff}, {0x3105, 0x312d}, + {0x3131, 0x318e}, {0x3190, 0x31ba}, {0x31c0, 0x31e3}, {0x31f0, 0x321e}, + {0x3220, 0x32fe}, {0x3300, 0x4db5}, {0x4dc0, 0x9fd5}, {0xa000, 0xa48c}, + {0xa490, 0xa4c6}, {0xa4d0, 0xa62b}, {0xa640, 0xa6f7}, {0xa700, 0xa7ad}, + {0xa7b0, 0xa7b7}, {0xa7f7, 0xa82b}, {0xa830, 0xa839}, {0xa840, 0xa877}, + {0xa880, 0xa8c4}, {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}, + {0xdc00, 0xdc3e}, {0xdc40, 0xdc7e}, {0xdc80, 0xdcbe}, {0xdcc0, 0xdcfe}, + {0xdd00, 0xdd3e}, {0xdd40, 0xdd7e}, {0xdd80, 0xddbe}, {0xddc0, 0xddfe}, + {0xde00, 0xde3e}, {0xde40, 0xde7e}, {0xde80, 0xdebe}, {0xdec0, 0xdefe}, + {0xdf00, 0xdf3e}, {0xdf40, 0xdf7e}, {0xdf80, 0xdfbe}, {0xdfc0, 0xdffe}, {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, 0xfe2d}, {0xfe30, 0xfe52}, {0xfe54, 0xfe66}, {0xfe68, 0xfe6b}, - {0xfe70, 0xfe74}, {0xfe76, 0xfefc}, {0xff01, 0xffbe}, {0xffc2, 0xffc7}, - {0xffca, 0xffcf}, {0xffd2, 0xffd7}, {0xffda, 0xffdc}, {0xffe0, 0xffe6}, - {0xffe8, 0xffee} + {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 TCL_UTF_MAX > 4 ,{0x10000, 0x1000b}, {0x1000d, 0x10026}, {0x10028, 0x1003a}, {0x1003f, 0x1004d}, {0x10050, 0x1005d}, {0x10080, 0x100fa}, {0x10100, 0x10102}, {0x10107, 0x10133}, @@ -683,45 +693,48 @@ static const crange graphRangeTable[] = { {0x10400, 0x1049d}, {0x104a0, 0x104a9}, {0x10500, 0x10527}, {0x10530, 0x10563}, {0x10600, 0x10736}, {0x10740, 0x10755}, {0x10760, 0x10767}, {0x10800, 0x10805}, {0x1080a, 0x10835}, {0x1083f, 0x10855}, {0x10857, 0x1089e}, {0x108a7, 0x108af}, - {0x10900, 0x1091b}, {0x1091f, 0x10939}, {0x10980, 0x109b7}, {0x10a00, 0x10a03}, - {0x10a0c, 0x10a13}, {0x10a15, 0x10a17}, {0x10a19, 0x10a33}, {0x10a38, 0x10a3a}, - {0x10a3f, 0x10a47}, {0x10a50, 0x10a58}, {0x10a60, 0x10a9f}, {0x10ac0, 0x10ae6}, - {0x10aeb, 0x10af6}, {0x10b00, 0x10b35}, {0x10b39, 0x10b55}, {0x10b58, 0x10b72}, - {0x10b78, 0x10b91}, {0x10b99, 0x10b9c}, {0x10ba9, 0x10baf}, {0x10c00, 0x10c48}, - {0x10e60, 0x10e7e}, {0x11000, 0x1104d}, {0x11052, 0x1106f}, {0x1107f, 0x110bc}, - {0x110be, 0x110c1}, {0x110d0, 0x110e8}, {0x110f0, 0x110f9}, {0x11100, 0x11134}, - {0x11136, 0x11143}, {0x11150, 0x11176}, {0x11180, 0x111c8}, {0x111d0, 0x111da}, - {0x111e1, 0x111f4}, {0x11200, 0x11211}, {0x11213, 0x1123d}, {0x112b0, 0x112ea}, - {0x112f0, 0x112f9}, {0x11301, 0x11303}, {0x11305, 0x1130c}, {0x11313, 0x11328}, - {0x1132a, 0x11330}, {0x11335, 0x11339}, {0x1133c, 0x11344}, {0x1134b, 0x1134d}, - {0x1135d, 0x11363}, {0x11366, 0x1136c}, {0x11370, 0x11374}, {0x11480, 0x114c7}, - {0x114d0, 0x114d9}, {0x11580, 0x115b5}, {0x115b8, 0x115c9}, {0x11600, 0x11644}, - {0x11650, 0x11659}, {0x11680, 0x116b7}, {0x116c0, 0x116c9}, {0x118a0, 0x118f2}, - {0x11ac0, 0x11af8}, {0x12000, 0x12398}, {0x12400, 0x1246e}, {0x12470, 0x12474}, - {0x13000, 0x1342e}, {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}, {0x1bc00, 0x1bc6a}, {0x1bc70, 0x1bc7c}, - {0x1bc80, 0x1bc88}, {0x1bc90, 0x1bc99}, {0x1bc9c, 0x1bc9f}, {0x1d000, 0x1d0f5}, - {0x1d100, 0x1d126}, {0x1d129, 0x1d172}, {0x1d17b, 0x1d1dd}, {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, 0x1d7ff}, {0x1e800, 0x1e8c4}, {0x1e8c7, 0x1e8d6}, + {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}, {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, 0x1123d}, + {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}, + {0x11480, 0x114c7}, {0x114d0, 0x114d9}, {0x11580, 0x115b5}, {0x115b8, 0x115dd}, + {0x11600, 0x11644}, {0x11650, 0x11659}, {0x11680, 0x116b7}, {0x116c0, 0x116c9}, + {0x11700, 0x11719}, {0x1171d, 0x1172b}, {0x11730, 0x1173f}, {0x118a0, 0x118f2}, + {0x11ac0, 0x11af8}, {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}, + {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}, {0x1e800, 0x1e8c4}, {0x1e8c7, 0x1e8d6}, {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, 0x1f19a}, - {0x1f1e6, 0x1f202}, {0x1f210, 0x1f23a}, {0x1f240, 0x1f248}, {0x1f300, 0x1f32c}, - {0x1f330, 0x1f37d}, {0x1f380, 0x1f3ce}, {0x1f3d4, 0x1f3f7}, {0x1f400, 0x1f4fe}, - {0x1f500, 0x1f54a}, {0x1f550, 0x1f579}, {0x1f57b, 0x1f5a3}, {0x1f5a5, 0x1f642}, - {0x1f645, 0x1f6cf}, {0x1f6e0, 0x1f6ec}, {0x1f6f0, 0x1f6f3}, {0x1f700, 0x1f773}, - {0x1f780, 0x1f7d4}, {0x1f800, 0x1f80b}, {0x1f810, 0x1f847}, {0x1f850, 0x1f859}, - {0x1f860, 0x1f887}, {0x1f890, 0x1f8ad}, {0x20000, 0x2a6d6}, {0x2a700, 0x2b734}, - {0x2b740, 0x2b81d}, {0x2f800, 0x2fa1d}, {0xe0100, 0xe01ef} + {0x1f1e6, 0x1f202}, {0x1f210, 0x1f23a}, {0x1f240, 0x1f248}, {0x1f300, 0x1f579}, + {0x1f57b, 0x1f5a3}, {0x1f5a5, 0x1f6d0}, {0x1f6e0, 0x1f6ec}, {0x1f6f0, 0x1f6f3}, + {0x1f700, 0x1f773}, {0x1f780, 0x1f7d4}, {0x1f800, 0x1f80b}, {0x1f810, 0x1f847}, + {0x1f850, 0x1f859}, {0x1f860, 0x1f887}, {0x1f890, 0x1f8ad}, {0x1f910, 0x1f918}, + {0x1f980, 0x1f984}, {0x20000, 0x2a6d6}, {0x2a700, 0x2b734}, {0x2b740, 0x2b81d}, + {0x2b820, 0x2cea1}, {0x2f800, 0x2fa1d}, {0xe0100, 0xe01ef} #endif }; @@ -731,23 +744,23 @@ 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, 0xc58, 0xc59, 0xcd5, - 0xcd6, 0xcde, 0xcf1, 0xcf2, 0xd57, 0xd82, 0xd83, 0xdbd, 0xdca, - 0xdd6, 0xe81, 0xe82, 0xe84, 0xe87, 0xe88, 0xe8a, 0xe8d, 0xea5, - 0xea7, 0xeaa, 0xeab, 0xec6, 0x10c7, 0x10cd, 0x1258, 0x12c0, 0x1772, - 0x1773, 0x1940, 0x1cf8, 0x1cf9, 0x1f59, 0x1f5b, 0x1f5d, 0x2070, 0x2071, - 0x2d27, 0x2d2d, 0x2d6f, 0x2d70, 0xa7b0, 0xa7b1, 0xab64, 0xab65, 0xfb3e, - 0xfb40, 0xfb41, 0xfb43, 0xfb44, 0xfffc, 0xfffd + 0xad0, 0xaf9, 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, 0xd57, 0xd82, 0xd83, 0xdbd, 0xdca, 0xdd6, + 0xe81, 0xe82, 0xe84, 0xe87, 0xe88, 0xe8a, 0xe8d, 0xea5, 0xea7, + 0xeaa, 0xeab, 0xec6, 0x10c7, 0x10cd, 0x1258, 0x12c0, 0x1772, 0x1773, + 0x1940, 0x1cf8, 0x1cf9, 0x1f59, 0x1f5b, 0x1f5d, 0x2070, 0x2071, 0x2d27, + 0x2d2d, 0x2d6f, 0x2d70, 0xfb3e, 0xfb40, 0xfb41, 0xfb43, 0xfb44, 0xfffc, + 0xfffd #if TCL_UTF_MAX > 4 - ,0x1003c, 0x1003d, 0x101a0, 0x1056f, 0x10808, 0x10837, 0x10838, 0x1083c, 0x1093f, - 0x109be, 0x109bf, 0x10a05, 0x10a06, 0x111cd, 0x1130f, 0x11310, 0x11332, 0x11333, - 0x11347, 0x11348, 0x11357, 0x118ff, 0x16a6e, 0x16a6f, 0x1b000, 0x1b001, 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, 0x1eef0, 0x1eef1, 0x1f250, 0x1f251 + ,0x1003c, 0x1003d, 0x101a0, 0x1056f, 0x10808, 0x10837, 0x10838, 0x1083c, 0x108f4, + 0x108f5, 0x1093f, 0x10a05, 0x10a06, 0x11288, 0x1130f, 0x11310, 0x11332, 0x11333, + 0x11347, 0x11348, 0x11350, 0x11357, 0x118ff, 0x16a6e, 0x16a6f, 0x1b000, 0x1b001, + 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, 0x1eef0, 0x1eef1, 0x1f250, 0x1f251, 0x1f9c0 #endif }; diff --git a/generic/tclUniData.c b/generic/tclUniData.c index 78e7d17..d2f66fe 100644 --- a/generic/tclUniData.c +++ b/generic/tclUniData.c @@ -36,29 +36,29 @@ static const unsigned short pageMap[] = { 3200, 1792, 3232, 3264, 3296, 1792, 3328, 3360, 3392, 3424, 3456, 3488, 3520, 1792, 1344, 3552, 3584, 3616, 3648, 3680, 3712, 3744, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 3776, 1344, 3808, 3840, - 3872, 1344, 3904, 1344, 3936, 3968, 4000, 1344, 1344, 4032, 4064, 1344, + 3872, 1344, 3904, 1344, 3936, 3968, 4000, 4032, 4032, 4064, 4096, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, - 1344, 1344, 1344, 1344, 1344, 4096, 4128, 1344, 1344, 4160, 4192, 4224, - 4256, 4288, 1344, 4320, 4352, 4384, 4416, 1344, 4448, 4480, 1344, 4512, - 1344, 4544, 4576, 4608, 4640, 4672, 1344, 4704, 4736, 4768, 4800, 1344, - 4832, 4864, 4896, 4928, 1792, 1792, 4960, 4992, 5024, 5056, 5088, 5120, - 1344, 5152, 1344, 5184, 5216, 5248, 1792, 1792, 5280, 5312, 5344, 5376, - 5408, 5440, 5472, 5408, 704, 5504, 224, 224, 224, 224, 5536, 224, 224, - 224, 5568, 5600, 5632, 5664, 5696, 5728, 5760, 5792, 5824, 5856, 5888, - 5920, 5952, 5984, 6016, 6048, 6080, 6112, 6144, 6176, 6208, 6240, 6272, - 6304, 6336, 6336, 6336, 6336, 6336, 6336, 6336, 6336, 6368, 6400, 4768, - 6432, 6464, 6496, 6528, 6560, 4768, 6592, 6624, 6656, 6688, 6720, 6752, - 6784, 4768, 4768, 4768, 4768, 4768, 6816, 6848, 6880, 4768, 4768, 4768, - 6912, 4768, 4768, 4768, 4768, 4768, 4768, 4768, 6944, 6976, 4768, 7008, - 7040, 4768, 4768, 4768, 4768, 4768, 4768, 4768, 4768, 6336, 6336, 6336, - 6336, 7072, 6336, 7104, 7136, 6336, 6336, 6336, 6336, 6336, 6336, 6336, - 6336, 4768, 7168, 7200, 7232, 7264, 7296, 7328, 1792, 7360, 7392, 7424, - 7456, 224, 224, 224, 7488, 7520, 7552, 1344, 7584, 7616, 7648, 7648, - 704, 7680, 7712, 7744, 1792, 7776, 4768, 4768, 7808, 4768, 4768, 4768, - 4768, 4768, 4768, 7840, 7872, 7904, 7936, 3136, 1344, 7968, 4064, 1344, - 8000, 8032, 8064, 1344, 1344, 8096, 8128, 4768, 8160, 8192, 8224, 8256, - 4768, 8224, 8288, 4768, 8192, 4768, 4768, 4768, 4768, 4768, 4768, 4768, - 4768, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 1344, 1344, 1344, 1344, 1344, 4128, 4160, 1344, 1344, 4192, 4224, 4256, + 4288, 4320, 1344, 4352, 4384, 4416, 4448, 1344, 4480, 4512, 1344, 4544, + 1344, 4576, 4608, 4640, 4672, 4704, 1344, 4736, 4768, 4800, 4832, 1344, + 4864, 4896, 4928, 4960, 1792, 1792, 4992, 5024, 5056, 5088, 5120, 5152, + 1344, 5184, 1344, 5216, 5248, 5280, 1792, 1792, 5312, 5344, 5376, 5408, + 5440, 5472, 5504, 5440, 704, 5536, 224, 224, 224, 224, 5568, 224, 224, + 224, 5600, 5632, 5664, 5696, 5728, 5760, 5792, 5824, 5856, 5888, 5920, + 5952, 5984, 6016, 6048, 6080, 6112, 6144, 6176, 6208, 6240, 6272, 6304, + 6336, 6368, 6368, 6368, 6368, 6368, 6368, 6368, 6368, 6400, 6432, 4800, + 6464, 6496, 6528, 6560, 6592, 4800, 6624, 6656, 6688, 6720, 6752, 6784, + 6816, 4800, 4800, 4800, 4800, 4800, 6848, 6880, 6912, 4800, 4800, 4800, + 6944, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 6976, 7008, 4800, 7040, + 7072, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 6368, 6368, 6368, + 6368, 7104, 6368, 7136, 7168, 6368, 6368, 6368, 6368, 6368, 6368, 6368, + 6368, 4800, 7200, 7232, 7264, 7296, 7328, 7360, 7392, 7424, 7456, 7488, + 7520, 224, 224, 224, 7552, 7584, 7616, 1344, 7648, 7680, 7712, 7712, + 704, 7744, 7776, 7808, 1792, 7840, 4800, 4800, 7872, 4800, 4800, 4800, + 4800, 4800, 4800, 7904, 7936, 7968, 8000, 3136, 1344, 8032, 4096, 1344, + 8064, 8096, 8128, 1344, 1344, 8160, 8192, 4800, 8224, 8256, 8288, 8320, + 4800, 8288, 8352, 4800, 8256, 4800, 4800, 4800, 4800, 4800, 4800, 4800, + 4800, 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, @@ -75,7 +75,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, 4544, 4768, 4768, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 1344, 1344, 4576, 4800, 4800, 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, @@ -129,16 +129,16 @@ 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, 8320, - 1792, 8352, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 4576, + 1792, 8384, 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, 8384, 4768, 8416, 5248, 1344, 1344, 1344, 1344, 1344, 1344, 1344, - 1344, 8448, 8480, 224, 8512, 8544, 1344, 1344, 8576, 8608, 8640, 224, - 8672, 8704, 8736, 1792, 8768, 8800, 8832, 1344, 8864, 8896, 8928, 8960, - 8992, 1632, 9024, 9056, 9088, 1888, 9120, 9152, 9184, 1344, 9216, 9248, - 9280, 1344, 9312, 9344, 9376, 9408, 9440, 9472, 9504, 1792, 1792, 1344, - 9536, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 1344, 8416, 4800, 8448, 5280, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 1344, 8480, 8512, 224, 8544, 8576, 1344, 1344, 8608, 8640, 8672, 224, + 8704, 8736, 8768, 1792, 8800, 8832, 8864, 1344, 8896, 8928, 8960, 8992, + 9024, 1632, 9056, 9088, 9120, 1888, 9152, 9184, 9216, 1344, 9248, 9280, + 9312, 1344, 9344, 9376, 9408, 9440, 9472, 9504, 9536, 9568, 9568, 1344, + 9600, 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, @@ -167,77 +167,72 @@ 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, 9568, 9600, 9632, 9664, 9664, 9664, 9664, 9664, 9664, 9664, - 9664, 9664, 9664, 9664, 9664, 9664, 9664, 9664, 9664, 9664, 9664, 9664, - 9664, 9664, 9664, 9664, 9664, 9664, 9664, 9664, 9664, 9664, 9664, 9664, - 9664, 9664, 9664, 9664, 9664, 9664, 9664, 9664, 9664, 9664, 9664, 9664, - 9664, 9664, 9664, 9664, 9664, 9664, 9664, 9664, 9664, 9664, 9664, 9664, - 9664, 9664, 9664, 9664, 9664, 9664, 9664, 9664, 9664, 9696, 9696, 9696, - 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, - 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, - 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, - 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, - 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, - 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, - 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, - 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, - 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, - 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, - 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, - 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, - 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, - 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, - 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, - 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, 9696, - 9696, 9696, 9696, 9696, 9696, 1344, 1344, 1344, 1344, 1344, 1344, 1344, - 1344, 1344, 1344, 1344, 9728, 1344, 1344, 9760, 1792, 9792, 9824, 9856, - 1344, 1344, 9888, 9920, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, - 1344, 1344, 9952, 9984, 1344, 10016, 1344, 10048, 10080, 10112, 10144, - 10176, 10208, 1344, 1344, 1344, 10240, 10272, 64, 10304, 10336, 10368, - 4576, 10400, 10432 + 1344, 1344, 9632, 9664, 9696, 9728, 9728, 9728, 9728, 9728, 9728, 9728, + 9728, 9728, 9728, 9728, 9728, 9728, 9728, 9728, 9728, 9728, 9728, 9728, + 9728, 9728, 9728, 9728, 9728, 9728, 9728, 9728, 9728, 9728, 9728, 9728, + 9728, 9728, 9728, 9728, 9728, 9728, 9728, 9728, 9728, 9728, 9728, 9728, + 9728, 9728, 9728, 9728, 9728, 9728, 9728, 9728, 9728, 9728, 9728, 9728, + 9728, 9728, 9728, 9728, 9728, 9728, 9728, 9728, 9728, 9760, 9760, 9760, + 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, + 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, + 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, + 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, + 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, + 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, + 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, + 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, + 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, + 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, + 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, + 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, + 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, + 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, + 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, + 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, 9760, + 9760, 9760, 9760, 9760, 9760, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 1344, 1344, 1344, 1344, 9792, 1344, 1344, 9824, 1792, 9856, 9888, 9920, + 1344, 1344, 9952, 9984, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 1344, 1344, 10016, 10048, 1344, 10080, 1344, 10112, 10144, 10176, 10208, + 10240, 10272, 1344, 1344, 1344, 10304, 10336, 64, 10368, 10400, 10432, + 4608, 10464, 10496 #if TCL_UTF_MAX > 3 - ,10464, 10496, 10528, 1792, 1344, 1344, 1344, 8128, 10560, 10592, 10624, - 10656, 10688, 10720, 10752, 10784, 1792, 1792, 1792, 1792, 9088, 1344, - 10816, 10848, 1344, 10880, 10912, 10944, 10976, 1344, 11008, 1792, - 11040, 11072, 11104, 1344, 11136, 11168, 1792, 1792, 1344, 11200, 1344, - 11232, 1792, 1792, 1792, 1792, 1344, 1344, 1344, 1344, 1344, 1344, - 1344, 1344, 1344, 7616, 4544, 10048, 1792, 1792, 1792, 1792, 11264, - 11296, 11328, 11360, 4576, 11392, 1792, 1792, 11424, 11456, 1792, 1792, - 1344, 11488, 1792, 1792, 11520, 11552, 11584, 11616, 11648, 1792, 11680, - 11712, 1344, 11744, 11776, 11808, 11840, 11872, 1792, 1792, 1344, 1344, - 11904, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 11936, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 11968, 12000, 12032, - 12064, 5088, 12096, 12128, 12160, 12192, 12224, 12256, 12288, 5088, - 12320, 12352, 12384, 12416, 12448, 1792, 1792, 1792, 9984, 12480, 12512, - 2400, 2304, 12544, 12576, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1344, 12608, 12640, 1792, 1792, 1792, 1792, 1792, 1344, 12672, - 12704, 1792, 1344, 12736, 12768, 1792, 1344, 12800, 11168, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 12832, 12864, 12896, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1344, 12928, 1792, 1792, 1792, + ,10528, 10560, 10592, 1792, 1344, 1344, 1344, 8192, 10624, 10656, 10688, + 10720, 10752, 10784, 10816, 10848, 1792, 1792, 1792, 1792, 9120, 1344, + 10880, 10912, 1344, 10944, 10976, 11008, 11040, 1344, 11072, 1792, + 11104, 11136, 11168, 1344, 11200, 11232, 1792, 1792, 1344, 11264, 1344, + 11296, 1792, 1792, 1792, 1792, 1344, 1344, 1344, 1344, 1344, 1344, + 1344, 1344, 1344, 7680, 4576, 10112, 1792, 1792, 1792, 1792, 11328, + 11360, 11392, 11424, 4608, 11456, 1792, 11488, 11520, 11552, 1792, + 1792, 1344, 11584, 11616, 6688, 11648, 11680, 11712, 11744, 11776, + 1792, 11808, 11840, 1344, 11872, 11904, 11936, 11968, 12000, 1792, + 1792, 1344, 1344, 12032, 1792, 12064, 12096, 12128, 12160, 1792, 1792, + 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 12192, 1792, + 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 12224, + 12256, 12288, 12320, 5120, 12352, 12384, 12416, 12448, 12480, 12512, + 12544, 5120, 12576, 12608, 12640, 12672, 12704, 1792, 1792, 12736, + 12768, 12800, 12832, 12864, 2304, 12896, 12928, 1792, 1792, 1792, 1792, + 1792, 1792, 1792, 1792, 1344, 12960, 12992, 1792, 1792, 1792, 1792, + 1792, 1344, 13024, 13056, 1792, 1344, 13088, 13120, 1792, 1344, 13152, + 11232, 1792, 13184, 13216, 1792, 1792, 1792, 1792, 1792, 1792, 1792, + 1792, 1792, 1792, 1792, 13248, 13280, 13312, 1792, 1792, 1792, 1792, + 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1344, 13344, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 1792, 1792, 1792, 1792, 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, 12928, 1792, 1792, 1792, 10624, 10624, - 10624, 12960, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, + 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 9824, 1792, 1792, 1792, + 10688, 10688, 10688, 13376, 1344, 1344, 1344, 1344, 1344, 1344, 13408, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 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, 12992, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, + 1792, 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, 13440, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, @@ -248,6 +243,9 @@ static const unsigned short pageMap[] = { 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, + 1792, 1792, 1792, 1792, 1792, 1792, 1344, 1344, 1344, 1344, 1344, 1344, + 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 13472, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, @@ -267,13 +265,14 @@ static const unsigned short pageMap[] = { 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, - 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 12928, 4576, - 13024, 1792, 1792, 9984, 13056, 1344, 13088, 13120, 13152, 13184, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1344, 1344, 13216, 13248, 13280, 1792, 1792, 1792, 1792, + 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1344, 1344, 1344, 1344, 1344, + 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, + 13344, 4608, 13504, 1792, 1792, 10048, 13536, 1344, 13568, 13600, 13632, + 13664, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, + 1792, 1792, 1792, 1792, 1792, 1344, 1344, 13696, 13728, 13760, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, @@ -315,17 +314,17 @@ static const unsigned short pageMap[] = { 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 13312, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, + 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 13792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1344, 1344, 1344, 13344, - 13376, 13408, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, + 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1344, + 1344, 1344, 13824, 13856, 13888, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, @@ -337,14 +336,16 @@ static const unsigned short pageMap[] = { 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 4768, 4768, 4768, 4768, 4768, 4768, 4768, 7840, 4768, 13440, - 4768, 13472, 13504, 13536, 13568, 1792, 4768, 4768, 13600, 1792, 1792, - 1792, 1792, 1792, 4768, 4768, 13632, 13664, 1792, 1792, 1792, 1792, - 13696, 13728, 13760, 13792, 13824, 13856, 13888, 13920, 13952, 13984, - 14016, 14048, 14080, 13696, 13728, 14112, 13792, 14144, 14176, 14208, - 13920, 14240, 14272, 14304, 14336, 14368, 14400, 14432, 14464, 14496, - 14528, 14560, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, + 1792, 1792, 1792, 1792, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 7904, + 4800, 13920, 4800, 13952, 13984, 14016, 4800, 14048, 4800, 4800, 14080, + 1792, 1792, 1792, 1792, 1792, 4800, 4800, 14112, 14144, 1792, 1792, + 1792, 1792, 14176, 14208, 14240, 14272, 14304, 14336, 14368, 14400, + 14432, 14464, 14496, 14528, 14560, 14176, 14208, 14592, 14272, 14624, + 14656, 14688, 14400, 14720, 14752, 14784, 14816, 14848, 14880, 14912, + 14944, 14976, 15008, 15040, 4800, 4800, 4800, 4800, 4800, 4800, 4800, + 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 4800, 704, 15072, 704, + 15104, 15136, 15168, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, @@ -353,24 +354,23 @@ static const unsigned short pageMap[] = { 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1344, - 1344, 1344, 1344, 1344, 1344, 14592, 1792, 1792, 1792, 1792, 1792, + 1792, 1792, 1344, 1344, 1344, 1344, 1344, 1344, 15200, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 14624, 14656, 14688, 14720, 14752, 14784, 1792, 14816, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 4768, 14848, 4768, 4768, 7808, - 14880, 14912, 7840, 14944, 14976, 4768, 14848, 15008, 1792, 1792, 15040, - 15072, 15008, 15104, 1792, 1792, 1792, 1792, 1792, 4768, 15136, 4768, - 13568, 4768, 4768, 15168, 15200, 4768, 4768, 4768, 4768, 4768, 4768, - 4768, 8192, 4768, 4768, 15232, 7776, 4768, 15264, 4768, 4768, 4768, - 4768, 15296, 4768, 4768, 4768, 15328, 15360, 4768, 4768, 4768, 7808, - 4768, 4768, 15392, 1792, 14848, 4768, 15424, 4768, 15456, 15488, 1792, + 1792, 1792, 1792, 15232, 15264, 15296, 15328, 15360, 15392, 1792, 15424, + 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 4800, 15456, 4800, + 4800, 7872, 15488, 15520, 7904, 15552, 15584, 4800, 15456, 15616, 1792, + 1792, 15648, 15680, 15616, 15712, 1792, 1792, 1792, 1792, 1792, 4800, + 4800, 4800, 4800, 4800, 4800, 4800, 15744, 4800, 4800, 4800, 4800, + 4800, 4800, 4800, 4800, 4800, 4800, 4800, 7840, 4800, 15776, 4800, + 4800, 4800, 4800, 4800, 4800, 4800, 4800, 15808, 15840, 4800, 4800, + 4800, 7872, 4800, 4800, 15872, 1792, 15456, 4800, 15904, 4800, 15936, + 15968, 1792, 1792, 16000, 1792, 1792, 1792, 16032, 1792, 10784, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 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, @@ -481,9 +481,8 @@ 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, 7616, - 1792, 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, 7680, 1792, 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, @@ -492,23 +491,24 @@ 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, 4032, 1344, - 1344, 1344, 1344, 1344, 1344, 11136, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, + 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, 1824, 1344, 1344, 1344, 1344, 1344, 1344, 11200, 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, + 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, 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, 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, 13792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, @@ -536,8 +536,8 @@ static const unsigned short pageMap[] = { 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, - 1792, 1792, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, - 1344, 1344, 1344, 1344, 1344, 1344, 11136 + 1792, 1792, 1792, 1792, 1792, 1792, 1344, 1344, 1344, 1344, 1344, 1344, + 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 11200 #endif /* TCL_UTF_MAX > 3 */ }; @@ -582,328 +582,331 @@ static const unsigned char groupMap[] = { 73, 74, 21, 75, 76, 21, 77, 78, 21, 21, 76, 21, 79, 80, 21, 21, 81, 21, 21, 21, 21, 21, 21, 21, 82, 21, 21, 83, 21, 21, 83, 21, 21, 21, 84, 83, 85, 86, 86, 87, 21, 21, 21, 21, 21, 88, 21, 15, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 89, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 90, 90, 90, 90, 11, 11, 11, 11, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 90, 90, 90, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 90, 90, 90, 90, 90, 11, 11, 11, 11, 11, 11, 11, 90, - 11, 90, 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, 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, 92, 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, 23, 24, 23, - 24, 90, 11, 23, 24, 0, 0, 90, 42, 42, 42, 3, 93, 0, 0, 0, 0, 11, 11, - 94, 3, 95, 95, 95, 0, 96, 0, 97, 97, 21, 10, 10, 10, 10, 10, 10, 10, + 21, 21, 21, 21, 21, 89, 90, 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, 91, 91, 91, 91, 91, 91, 91, 11, 11, 11, 11, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 91, 91, 91, 91, 91, 11, 11, 11, 11, 11, 11, 11, 91, + 11, 91, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 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, 93, 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, 23, 24, 23, + 24, 91, 11, 23, 24, 0, 0, 91, 42, 42, 42, 3, 94, 0, 0, 0, 0, 11, 11, + 95, 3, 96, 96, 96, 0, 97, 0, 98, 98, 21, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 0, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 98, 99, 99, 99, 21, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 100, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 101, 102, 102, 103, 104, 105, 106, 106, 106, 107, 108, 109, 23, - 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, - 23, 24, 23, 24, 23, 24, 110, 111, 112, 113, 114, 115, 7, 23, 24, 116, - 23, 24, 21, 54, 54, 54, 117, 117, 117, 117, 117, 117, 117, 117, 117, - 117, 117, 117, 117, 117, 117, 117, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 99, 100, 100, 100, 21, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 101, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 102, 103, 103, 104, 105, 106, 107, 107, 107, 108, 109, 110, + 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, + 24, 23, 24, 23, 24, 23, 24, 111, 112, 113, 114, 115, 116, 7, 23, 24, + 117, 23, 24, 21, 54, 54, 54, 118, 118, 118, 118, 118, 118, 118, 118, + 118, 118, 118, 118, 118, 118, 118, 118, 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, + 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, 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, - 111, 111, 111, 111, 111, 111, 23, 24, 14, 91, 91, 91, 91, 91, 118, - 118, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, - 23, 24, 23, 24, 23, 24, 119, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, - 23, 24, 23, 24, 120, 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, 23, 24, 0, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 0, - 0, 90, 3, 3, 3, 3, 3, 3, 0, 122, 122, 122, 122, 122, 122, 122, 122, + 13, 13, 13, 13, 13, 13, 112, 112, 112, 112, 112, 112, 112, 112, 112, + 112, 112, 112, 112, 112, 112, 112, 23, 24, 14, 92, 92, 92, 92, 92, + 119, 119, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, + 24, 23, 24, 23, 24, 23, 24, 120, 23, 24, 23, 24, 23, 24, 23, 24, 23, + 24, 23, 24, 23, 24, 121, 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, 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, - 122, 122, 21, 0, 3, 8, 0, 0, 14, 14, 4, 0, 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, 8, 91, 3, 91, 91, 3, 91, 91, 3, 91, 0, 0, 0, 0, + 0, 0, 91, 3, 3, 3, 3, 3, 3, 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, 21, 0, 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, 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, 91, 91, 91, 91, 91, 91, 91, - 91, 91, 91, 91, 3, 17, 0, 3, 3, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 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, 90, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, - 91, 91, 91, 91, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 3, 3, 3, 3, 15, 15, 91, + 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, - 15, 3, 15, 91, 91, 91, 91, 91, 91, 91, 17, 14, 91, 91, 91, 91, 91, - 91, 90, 90, 91, 91, 14, 91, 91, 91, 91, 15, 15, 9, 9, 9, 9, 9, 9, 9, + 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, 91, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 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, 15, - 15, 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, 0, 0, 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, 15, 15, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 15, 0, 0, 0, + 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, 91, 91, - 91, 91, 91, 91, 91, 91, 91, 90, 90, 14, 3, 3, 3, 90, 0, 0, 0, 0, 0, + 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, 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, 90, 91, 91, 91, 91, 91, 91, 91, - 91, 91, 90, 91, 91, 91, 90, 91, 91, 91, 91, 91, 0, 0, 3, 3, 3, 3, 3, + 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, 91, - 91, 91, 0, 0, 3, 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, 92, + 92, 92, 0, 0, 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, 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, 0, 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, 123, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 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, 123, 91, 15, 123, 123, - 123, 91, 91, 91, 91, 91, 91, 91, 91, 123, 123, 123, 123, 91, 123, 123, - 15, 91, 91, 91, 91, 91, 91, 91, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 91, 91, 3, 3, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 3, 90, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 91, 123, 123, 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, - 91, 15, 123, 123, 123, 91, 91, 91, 91, 0, 0, 123, 123, 0, 0, 123, 123, - 91, 15, 0, 0, 0, 0, 0, 0, 0, 0, 123, 0, 0, 0, 0, 15, 15, 0, 15, 15, - 15, 91, 91, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 15, 15, 4, 4, 18, 18, - 18, 18, 18, 18, 14, 4, 0, 0, 0, 0, 0, 91, 91, 123, 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, 15, 15, 15, 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, 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, 0, 0, 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, 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, 91, 0, 123, - 123, 123, 91, 91, 0, 0, 0, 0, 91, 91, 0, 0, 91, 91, 91, 0, 0, 0, 91, - 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, 91, 91, 15, 15, 15, 91, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 91, 91, 123, 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, 91, 15, 123, 123, 123, 91, - 91, 91, 91, 91, 0, 91, 91, 123, 0, 123, 123, 91, 0, 0, 15, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 91, 91, 0, 0, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 91, 123, 123, 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, 91, 15, 123, 91, 123, 91, 91, 91, 91, 0, - 0, 123, 123, 0, 0, 123, 123, 91, 0, 0, 0, 0, 0, 0, 0, 0, 91, 123, 0, - 0, 0, 0, 15, 15, 0, 15, 15, 15, 91, 91, 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, 91, 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, 123, 123, 91, 123, 123, 0, 0, 0, 123, 123, 123, 0, 123, - 123, 123, 91, 0, 0, 15, 0, 0, 0, 0, 0, 0, 123, 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, 91, 123, 123, 123, 0, 15, - 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 0, 15, 15, 15, 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, 0, + 0, 0, 0, 0, 0, 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, 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, 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, 0, 92, 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, 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, 124, 124, 124, 124, 0, 92, 124, + 124, 0, 124, 124, 92, 92, 0, 0, 0, 0, 0, 0, 0, 124, 124, 0, 0, 0, 0, + 0, 0, 0, 15, 0, 15, 15, 92, 92, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 0, 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, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 0, 0, 15, 124, 124, 124, 92, 92, 92, 92, 0, 124, + 124, 124, 0, 124, 124, 124, 92, 15, 0, 0, 0, 0, 0, 0, 0, 0, 124, 0, + 0, 0, 0, 0, 0, 0, 15, 15, 15, 92, 92, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 18, 18, 18, 18, 18, 18, 0, 0, 0, 14, 15, 15, 15, 15, 15, 15, + 0, 0, 124, 124, 0, 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, 15, 15, 15, 15, 15, 0, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 0, 0, 15, 15, 15, 15, 15, 15, + 15, 0, 0, 0, 92, 0, 0, 0, 0, 124, 124, 124, 92, 92, 92, 0, 92, 0, 124, + 124, 124, 124, 124, 124, 124, 124, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 0, 0, 124, 124, 3, 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, - 0, 0, 0, 15, 91, 91, 91, 123, 123, 123, 123, 0, 91, 91, 91, 0, 91, - 91, 91, 91, 0, 0, 0, 0, 0, 0, 0, 91, 91, 0, 15, 15, 0, 0, 0, 0, 0, - 0, 15, 15, 91, 91, 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, 0, 91, 123, 123, 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, 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, 91, 15, 123, 91, 123, 123, 123, 123, 123, 0, 91, 123, 123, 0, 123, - 123, 91, 91, 0, 0, 0, 0, 0, 0, 0, 123, 123, 0, 0, 0, 0, 0, 0, 0, 15, - 0, 15, 15, 91, 91, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 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, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 0, 0, 15, 123, 123, 123, 91, 91, 91, 91, 0, 123, 123, 123, - 0, 123, 123, 123, 91, 15, 0, 0, 0, 0, 0, 0, 0, 0, 123, 0, 0, 0, 0, - 0, 0, 0, 0, 15, 15, 91, 91, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 18, - 18, 18, 18, 18, 18, 0, 0, 0, 14, 15, 15, 15, 15, 15, 15, 0, 0, 123, - 123, 0, 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, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 0, 15, 0, 0, 15, 15, 15, 15, 15, 15, 15, 0, 0, - 0, 91, 0, 0, 0, 0, 123, 123, 123, 91, 91, 91, 0, 91, 0, 123, 123, 123, - 123, 123, 123, 123, 123, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 0, 0, 123, 123, 3, 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, 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, 91, 91, - 91, 91, 91, 91, 91, 0, 0, 0, 0, 4, 15, 15, 15, 15, 15, 15, 90, 91, - 91, 91, 91, 91, 91, 91, 91, 3, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 3, 3, - 0, 0, 0, 0, 0, 15, 15, 0, 15, 0, 0, 15, 15, 0, 15, 0, 0, 15, 0, 0, - 0, 0, 0, 0, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, - 15, 0, 15, 0, 15, 0, 0, 15, 15, 0, 15, 15, 15, 15, 91, 15, 15, 91, - 91, 91, 91, 91, 91, 0, 91, 91, 15, 0, 0, 15, 15, 15, 15, 15, 0, 90, - 0, 91, 91, 91, 91, 91, 91, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, - 15, 15, 15, 15, 15, 14, 14, 14, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 14, 3, 14, 14, 14, 91, 91, 14, 14, 14, 14, 14, 14, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 14, 91, - 14, 91, 14, 91, 5, 6, 5, 6, 123, 123, 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, 0, 0, 0, 0, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, - 91, 91, 91, 123, 91, 91, 91, 91, 91, 3, 91, 91, 15, 15, 15, 15, 15, - 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 0, 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, 0, 14, 14, - 14, 14, 14, 14, 14, 14, 91, 14, 14, 14, 14, 14, 14, 0, 14, 14, 3, 3, - 3, 3, 3, 14, 14, 14, 14, 3, 3, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 123, 123, 91, 91, 91, 91, 123, 91, 91, 91, 91, - 91, 91, 123, 91, 91, 123, 123, 91, 91, 15, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 3, 3, 3, 3, 3, 3, 15, 15, 15, 15, 15, 15, 123, 123, 91, 91, 15, - 15, 15, 15, 91, 91, 91, 15, 123, 123, 123, 15, 15, 123, 123, 123, 123, - 123, 123, 123, 15, 15, 15, 91, 91, 91, 91, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 91, 123, 123, 91, 91, 123, 123, 123, 123, - 123, 123, 91, 15, 123, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 123, 123, 123, - 91, 14, 14, 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, 124, 124, 124, 124, 0, - 124, 0, 0, 0, 0, 0, 124, 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, 92, 15, + 15, 92, 92, 92, 92, 92, 92, 92, 0, 0, 0, 0, 4, 15, 15, 15, 15, 15, + 15, 91, 92, 92, 92, 92, 92, 92, 92, 92, 3, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 3, 3, 0, 0, 0, 0, 0, 15, 15, 0, 15, 0, 0, 15, 15, 0, 15, 0, 0, + 15, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, + 0, 15, 15, 15, 0, 15, 0, 15, 0, 0, 15, 15, 0, 15, 15, 15, 15, 92, 15, + 15, 92, 92, 92, 92, 92, 92, 0, 92, 92, 15, 0, 0, 15, 15, 15, 15, 15, + 0, 91, 0, 92, 92, 92, 92, 92, 92, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 0, 0, 15, 15, 15, 15, 15, 14, 14, 14, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 14, 3, 14, 14, 14, 92, 92, 14, 14, 14, 14, 14, 14, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 14, 92, 14, 92, 14, 92, 5, 6, 5, 6, 124, 124, 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, 0, 0, 0, 0, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 124, 92, 92, 92, 92, 92, 3, 92, 92, 15, 15, 15, + 15, 15, 92, 92, 92, 92, 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, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 0, + 14, 14, 14, 14, 14, 14, 14, 14, 92, 14, 14, 14, 14, 14, 14, 0, 14, + 14, 3, 3, 3, 3, 3, 14, 14, 14, 14, 3, 3, 0, 0, 0, 0, 0, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 124, 124, 92, 92, 92, 92, 124, 92, + 92, 92, 92, 92, 92, 124, 92, 92, 124, 124, 92, 92, 15, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 3, 3, 3, 3, 3, 3, 15, 15, 15, 15, 15, 15, 124, 124, + 92, 92, 15, 15, 15, 15, 92, 92, 92, 15, 124, 124, 124, 15, 15, 124, + 124, 124, 124, 124, 124, 124, 15, 15, 15, 92, 92, 92, 92, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 92, 124, 124, 92, 92, 124, + 124, 124, 124, 124, 124, 92, 15, 124, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 124, 124, 124, 92, 14, 14, 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, 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, - 3, 90, 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, 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, - 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, 91, 91, 91, 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, 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, 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, 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, - 3, 3, 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, 125, 125, 125, 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, 91, 91, 91, 0, 0, 0, + 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, 91, 91, 91, 3, 3, 0, 0, 0, 0, 0, 0, 0, + 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, 91, 91, 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, 91, 91, 0, 0, + 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, 91, 91, 123, 91, 91, 91, 91, - 91, 91, 91, 123, 123, 123, 123, 123, 123, 123, 123, 91, 123, 123, 91, - 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 3, 3, 3, 90, 3, 3, 3, 4, 15, - 91, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 18, 18, 18, + 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, 91, 91, 91, 17, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, - 0, 0, 0, 0, 15, 15, 15, 90, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 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, 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, 15, 15, 15, 15, 91, 15, 0, 0, 0, 0, 0, 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, 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, 91, 91, 91, 123, 123, 123, 123, 91, 91, 123, 123, - 123, 0, 0, 0, 0, 123, 123, 91, 123, 123, 123, 123, 123, 123, 91, 91, - 91, 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, 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, 123, 123, 123, 123, 123, 123, 123, 123, - 123, 123, 123, 123, 123, 123, 123, 123, 123, 15, 15, 15, 15, 15, 15, - 15, 123, 123, 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, + 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, 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, 123, 123, 91, 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, 123, 91, 123, 91, 91, 91, 91, 91, 91, 91, 0, 91, 123, 91, 123, - 123, 91, 91, 91, 91, 91, 91, 91, 91, 123, 123, 123, 123, 123, 123, - 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 0, 0, 91, 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, 90, 3, 3, 3, 3, 3, 3, 0, 0, 91, 91, 91, - 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 118, 0, 91, 91, 91, 91, - 123, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 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, 123, 91, - 91, 91, 91, 91, 123, 91, 123, 123, 123, 123, 123, 91, 123, 123, 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, 91, 91, 91, - 91, 91, 91, 91, 91, 91, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, - 91, 91, 123, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 123, - 91, 91, 91, 91, 123, 123, 91, 91, 123, 91, 91, 91, 15, 15, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 91, 123, 91, 91, 123, 123, 123, 91, 123, 91, 91, 91, 123, 123, 0, 0, - 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 15, 15, 15, 15, 123, 123, 123, 123, 123, - 123, 123, 123, 91, 91, 91, 91, 91, 91, 91, 91, 123, 123, 91, 91, 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, 90, 90, 90, 90, 90, 90, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 0, 0, 0, 0, 0, 0, 0, 0, 91, 91, 91, 3, 91, 91, 91, 91, 91, 91, 91, - 91, 91, 91, 91, 91, 91, 123, 91, 91, 91, 91, 91, 91, 91, 15, 15, 15, - 15, 91, 15, 15, 15, 15, 123, 123, 91, 15, 15, 0, 91, 91, 0, 0, 0, 0, - 0, 0, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 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, 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, 0, 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, 90, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 90, 90, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 90, 126, 21, 21, 21, 127, 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, 90, 90, 90, 90, 90, 91, 91, 91, 91, 91, 91, 91, 91, 91, - 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 0, 0, 0, 0, 0, - 0, 91, 91, 91, 91, 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, 128, 21, - 21, 129, 21, 130, 130, 130, 130, 130, 130, 130, 130, 131, 131, 131, - 131, 131, 131, 131, 131, 130, 130, 130, 130, 130, 130, 0, 0, 131, 131, - 131, 131, 131, 131, 0, 0, 130, 130, 130, 130, 130, 130, 130, 130, 131, - 131, 131, 131, 131, 131, 131, 131, 130, 130, 130, 130, 130, 130, 130, - 130, 131, 131, 131, 131, 131, 131, 131, 131, 130, 130, 130, 130, 130, - 130, 0, 0, 131, 131, 131, 131, 131, 131, 0, 0, 21, 130, 21, 130, 21, - 130, 21, 130, 0, 131, 0, 131, 0, 131, 0, 131, 130, 130, 130, 130, 130, - 130, 130, 130, 131, 131, 131, 131, 131, 131, 131, 131, 132, 132, 133, - 133, 133, 133, 134, 134, 135, 135, 136, 136, 137, 137, 0, 0, 130, 130, - 130, 130, 130, 130, 130, 130, 138, 138, 138, 138, 138, 138, 138, 138, - 130, 130, 130, 130, 130, 130, 130, 130, 138, 138, 138, 138, 138, 138, - 138, 138, 130, 130, 130, 130, 130, 130, 130, 130, 138, 138, 138, 138, - 138, 138, 138, 138, 130, 130, 21, 139, 21, 0, 21, 21, 131, 131, 140, - 140, 141, 11, 142, 11, 11, 11, 21, 139, 21, 0, 21, 21, 143, 143, 143, - 143, 141, 11, 11, 11, 130, 130, 21, 21, 0, 0, 21, 21, 131, 131, 144, - 144, 0, 11, 11, 11, 130, 130, 21, 21, 21, 112, 21, 21, 131, 131, 145, - 145, 116, 11, 11, 11, 0, 0, 21, 139, 21, 0, 21, 21, 146, 146, 147, - 147, 141, 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, 148, 149, 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, 90, 0, 0, - 18, 18, 18, 18, 18, 18, 7, 7, 7, 5, 6, 90, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 7, 7, 7, 5, 6, 0, 90, 90, 90, 90, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 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, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 91, 91, 91, 91, 91, 91, 91, 91, 91, - 91, 91, 91, 91, 118, 118, 118, 118, 91, 118, 118, 118, 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, 14, 14, 106, 14, 14, 14, 14, 106, 14, 14, 21, 106, 106, - 106, 21, 21, 106, 106, 106, 21, 14, 106, 14, 14, 7, 106, 106, 106, - 106, 106, 14, 14, 14, 14, 14, 14, 106, 14, 150, 14, 106, 14, 151, 152, - 106, 106, 14, 21, 106, 106, 153, 106, 21, 15, 15, 15, 15, 21, 14, 14, - 21, 21, 106, 106, 7, 7, 7, 7, 7, 106, 21, 21, 21, 21, 14, 7, 14, 14, - 154, 14, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, 155, - 155, 155, 155, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, 156, - 156, 156, 156, 156, 156, 125, 125, 125, 23, 24, 125, 125, 125, 125, - 18, 0, 0, 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, + 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, 91, + 91, 91, 91, 91, 91, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 91, 128, 21, 21, 21, 129, 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, 0, 0, 0, 0, 0, 0, 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, 130, 21, 21, 131, + 21, 132, 132, 132, 132, 132, 132, 132, 132, 133, 133, 133, 133, 133, + 133, 133, 133, 132, 132, 132, 132, 132, 132, 0, 0, 133, 133, 133, 133, + 133, 133, 0, 0, 132, 132, 132, 132, 132, 132, 132, 132, 133, 133, 133, + 133, 133, 133, 133, 133, 132, 132, 132, 132, 132, 132, 132, 132, 133, + 133, 133, 133, 133, 133, 133, 133, 132, 132, 132, 132, 132, 132, 0, + 0, 133, 133, 133, 133, 133, 133, 0, 0, 21, 132, 21, 132, 21, 132, 21, + 132, 0, 133, 0, 133, 0, 133, 0, 133, 132, 132, 132, 132, 132, 132, + 132, 132, 133, 133, 133, 133, 133, 133, 133, 133, 134, 134, 135, 135, + 135, 135, 136, 136, 137, 137, 138, 138, 139, 139, 0, 0, 132, 132, 132, + 132, 132, 132, 132, 132, 140, 140, 140, 140, 140, 140, 140, 140, 132, + 132, 132, 132, 132, 132, 132, 132, 140, 140, 140, 140, 140, 140, 140, + 140, 132, 132, 132, 132, 132, 132, 132, 132, 140, 140, 140, 140, 140, + 140, 140, 140, 132, 132, 21, 141, 21, 0, 21, 21, 133, 133, 142, 142, + 143, 11, 144, 11, 11, 11, 21, 141, 21, 0, 21, 21, 145, 145, 145, 145, + 143, 11, 11, 11, 132, 132, 21, 21, 0, 0, 21, 21, 133, 133, 146, 146, + 0, 11, 11, 11, 132, 132, 21, 21, 21, 113, 21, 21, 133, 133, 147, 147, + 117, 11, 11, 11, 0, 0, 21, 141, 21, 0, 21, 21, 148, 148, 149, 149, + 143, 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, 150, 151, 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, 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, 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, 152, 14, 107, 14, 153, 154, 107, + 107, 14, 21, 107, 107, 155, 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, 156, + 14, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, + 157, 157, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, + 158, 158, 158, 158, 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, 14, 14, 14, 14, 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, 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, 14, 14, 14, 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, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 14, 14, @@ -927,11 +930,11 @@ 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, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 157, 157, 157, 157, 157, 157, 157, - 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, 157, - 157, 157, 157, 157, 157, 158, 158, 158, 158, 158, 158, 158, 158, 158, - 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, - 158, 158, 158, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 14, 14, 14, 14, 14, 14, 14, 14, 159, 159, 159, 159, 159, 159, 159, + 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, + 159, 159, 159, 159, 159, 160, 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 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, @@ -961,179 +964,182 @@ static const unsigned char groupMap[] = { 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 0, 122, 122, 122, 122, 122, 122, 122, + 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, 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, 23, - 24, 159, 160, 161, 162, 163, 23, 24, 23, 24, 23, 24, 164, 165, 166, - 167, 21, 23, 24, 21, 23, 24, 21, 21, 21, 21, 21, 90, 90, 168, 168, - 23, 24, 23, 24, 21, 14, 14, 14, 14, 14, 14, 23, 24, 23, 24, 91, 91, - 91, 23, 24, 0, 0, 0, 0, 0, 3, 3, 3, 3, 18, 3, 3, 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, 169, 169, 169, 169, 169, 169, - 169, 169, 169, 169, 169, 169, 0, 169, 0, 0, 0, 0, 0, 169, 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, 90, 3, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 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, 90, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 8, 8, 3, 3, 3, - 3, 8, 3, 5, 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, 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, + 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, + 123, 123, 123, 123, 0, 23, 24, 161, 162, 163, 164, 165, 23, 24, 23, + 24, 23, 24, 166, 167, 168, 169, 21, 23, 24, 21, 23, 24, 21, 21, 21, + 21, 21, 91, 91, 170, 170, 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, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, + 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, + 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 0, 171, 0, 0, + 0, 0, 0, 171, 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, 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, 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, 90, 15, 125, 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, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 91, 91, 91, 91, 123, 123, 8, 90, - 90, 90, 90, 90, 14, 14, 125, 125, 125, 90, 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, 91, 91, 11, 11, 90, 90, 15, 15, 15, 15, 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, 90, 90, 90, 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, + 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, 15, 15, 15, 15, 15, 15, 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, 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, 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, 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, - 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, + 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, 0, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 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, 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, 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, 90, 15, + 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, 15, 15, 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, 15, 15, 15, 15, 15, 15, 15, 90, 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, 91, 118, 118, 118, 3, 91, 91, 91, 91, 91, 91, 91, - 91, 91, 91, 3, 90, 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, 90, - 90, 0, 91, 15, 15, 15, 15, 15, 15, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 91, 91, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 11, + 15, 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, 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, 11, 11, 90, 90, 90, 90, 90, 90, 90, 90, 90, 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, 90, 21, 21, 21, 21, 21, - 21, 21, 21, 23, 24, 23, 24, 170, 23, 24, 23, 24, 23, 24, 23, 24, 23, - 24, 90, 11, 11, 23, 24, 171, 21, 0, 23, 24, 23, 24, 21, 21, 23, 24, + 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, 172, 173, 174, 175, 0, 0, 176, 177, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 24, 23, 24, 23, 24, 23, 24, 23, 24, 91, 21, 21, 21, 21, 21, 21, 21, + 21, 23, 24, 23, 24, 172, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 91, + 11, 11, 23, 24, 173, 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, 174, + 175, 176, 177, 0, 0, 178, 179, 180, 181, 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, 0, 15, 90, 90, 21, 15, 15, 15, 15, 15, 15, 15, 91, 15, - 15, 15, 91, 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, 123, 123, 91, - 91, 123, 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, 123, 123, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, - 123, 123, 123, 123, 91, 0, 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, 91, 91, 91, 91, 91, 91, 91, 91, - 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 15, 15, 15, 15, 15, 15, 3, - 3, 3, 15, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 91, 91, 91, 91, 91, 91, - 91, 91, 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, 91, 91, 91, 91, 91, 91, 91, 91, - 91, 91, 91, 123, 123, 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, 91, 123, 123, 91, - 91, 91, 91, 123, 123, 91, 123, 123, 123, 123, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 0, 90, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, - 3, 3, 15, 15, 15, 15, 15, 91, 90, 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, 91, 91, 91, 91, 91, 91, 123, 123, 91, 91, 123, - 123, 91, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 91, 15, 15, 15, - 15, 15, 15, 15, 15, 91, 123, 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, 90, 15, 15, 15, 15, 15, 15, 14, 14, 14, 15, 123, 91, 123, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 91, 15, 91, 91, 91, 15, 15, 91, 91, 15, 15, 15, 15, 15, 91, 91, - 15, 91, 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, 90, 3, 3, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 123, 91, 91, 123, 123, 3, 3, 15, 90, 90, 123, 91, 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, + 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, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, + 124, 124, 124, 92, 0, 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, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 11, 90, 90, 90, 90, 0, 0, 0, 0, 21, 21, 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, 123, 123, 91, 123, 123, 91, 123, 123, 3, 123, 91, - 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, 15, 0, - 0, 0, 0, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, - 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, - 178, 178, 178, 178, 178, 178, 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, 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, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 182, 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, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, + 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, + 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, + 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 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, 15, 0, 0, 0, 0, 184, 184, 184, + 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, + 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, + 184, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, + 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, + 185, 185, 185, 185, 185, 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, + 21, 21, 21, 21, 21, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 21, + 21, 21, 21, 0, 0, 0, 0, 0, 15, 92, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 7, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, + 15, 15, 15, 15, 0, 15, 0, 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, 15, + 15, 15, 15, 15, 15, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 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, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 6, 5, 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, 15, 15, 15, - 15, 0, 0, 0, 0, 0, 0, 21, 21, 21, 21, 21, 21, 21, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 21, 21, 21, 21, 21, 0, 0, 0, 0, 0, 15, 91, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 7, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 0, 15, 0, 15, 15, 0, 15, - 15, 0, 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, 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, 4, + 14, 0, 0, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 3, 3, 3, 3, 3, 3, 3, 5, 6, 3, 0, 0, 0, 0, 0, 0, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 3, 8, 8, 12, 12, 5, + 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 3, 3, 5, 6, 3, 3, 3, 3, + 12, 12, 12, 3, 3, 3, 0, 3, 3, 3, 3, 8, 5, 6, 5, 6, 5, 6, 3, 3, 3, 7, + 8, 7, 7, 7, 0, 3, 4, 3, 3, 0, 0, 0, 0, 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, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 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, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 6, - 5, 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, 17, 0, 3, 3, 3, 4, 3, 3, 3, 5, 6, 3, 7, 3, 8, 3, + 3, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 3, 3, 7, 7, 7, 3, 11, 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, 5, 7, 6, 7, 5, 6, 3, 5, 6, 3, 3, 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, 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, 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, 4, 14, 0, 0, 91, 91, 91, 91, 91, 91, - 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 3, 3, 3, 3, 3, 3, 3, 5, 6, - 3, 0, 0, 0, 0, 0, 0, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, - 91, 91, 0, 0, 3, 8, 8, 12, 12, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, - 5, 6, 5, 6, 3, 3, 5, 6, 3, 3, 3, 3, 12, 12, 12, 3, 3, 3, 0, 3, 3, 3, - 3, 8, 5, 6, 5, 6, 5, 6, 3, 3, 3, 7, 8, 7, 7, 7, 0, 3, 4, 3, 3, 0, 0, - 0, 0, 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, 15, 15, 0, 0, 17, 0, 3, 3, - 3, 4, 3, 3, 3, 5, 6, 3, 7, 3, 8, 3, 3, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 3, 3, 7, 7, 7, 3, 11, 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, 5, 7, 6, 7, - 5, 6, 3, 5, 6, 3, 3, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 90, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 90, 90, 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, 15, 15, 15, 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 + 15, 15, 91, 91, 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, 15, 15, 15, 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 #if TCL_UTF_MAX > 3 ,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, @@ -1144,10 +1150,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, 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, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 18, + 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, 18, 18, 18, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 18, 18, 14, 0, 0, 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, 0, @@ -1155,25 +1161,25 @@ static const unsigned char groupMap[] = { 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, 91, 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, 91, 18, + 14, 14, 92, 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, 92, 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, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 125, 15, 15, 15, 15, 15, 15, 15, 15, - 125, 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, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 91, 91, 91, 91, 91, 0, 0, 0, 0, + 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, 125, 125, 125, - 125, 125, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 180, 180, 180, 180, 180, 180, - 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, - 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, - 180, 180, 180, 180, 180, 180, 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, 181, 181, 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, 3, 127, 127, 127, + 127, 127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 186, 186, 186, 186, 186, 186, + 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, + 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, + 186, 186, 186, 186, 186, 186, 187, 187, 187, 187, 187, 187, 187, 187, + 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, + 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, + 187, 187, 187, 187, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 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, 0, 0, 0, 0, 0, @@ -1190,236 +1196,262 @@ static const unsigned char groupMap[] = { 15, 15, 15, 15, 15, 15, 15, 15, 15, 14, 14, 18, 18, 18, 18, 18, 18, 18, 0, 0, 0, 0, 0, 0, 0, 18, 18, 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, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 18, 18, - 18, 18, 18, 18, 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, 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, 0, 0, 0, 0, 0, 0, 15, 15, - 15, 91, 91, 91, 0, 91, 91, 0, 0, 0, 0, 0, 91, 91, 91, 91, 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, 91, 91, 91, 0, 0, 0, 0, 91, 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, - 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, 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, 15, 15, 91, 91, - 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, 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, 0, 15, 15, 0, 0, 0, + 0, 0, 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, 15, 18, 18, 18, 18, 18, 18, + 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, 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, 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, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 18, 18, 15, 15, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 0, 0, 18, 18, 18, 18, + 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, 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, 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, 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, + 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, 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, 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, 102, + 102, 102, 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, 0, 123, 91, 123, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 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, - 15, 15, 15, 15, 15, 15, 15, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, - 91, 91, 91, 91, 91, 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, 91, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 123, 123, 123, 91, 91, 91, 91, 123, 123, 91, 91, 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, 91, 91, 91, 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, 15, 15, 15, 15, 15, 91, 91, 91, 91, 91, 123, 91, 91, 91, - 91, 91, 91, 91, 91, 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, 15, 15, 15, 15, 15, 15, 15, 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, 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, 123, 123, 123, 91, 91, 91, 91, 91, 91, 91, 91, 91, - 123, 123, 15, 15, 15, 15, 3, 3, 3, 3, 0, 0, 0, 0, 3, 0, 0, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 15, 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, 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, 123, 123, - 123, 91, 91, 91, 123, 123, 91, 123, 91, 91, 3, 3, 3, 3, 3, 3, 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, 91, 123, 123, - 123, 91, 91, 91, 91, 91, 91, 91, 91, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 91, 123, 123, 123, 123, 0, 0, 123, - 123, 0, 0, 123, 123, 123, 0, 0, 0, 0, 0, 0, 0, 0, 0, 123, 0, 0, 0, - 0, 0, 15, 15, 15, 15, 15, 123, 123, 0, 0, 91, 91, 91, 91, 91, 91, 91, - 0, 0, 0, 91, 91, 91, 91, 91, 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, 123, 123, 123, - 91, 91, 91, 91, 91, 91, 123, 91, 123, 123, 123, 123, 91, 91, 123, 91, - 91, 15, 15, 3, 15, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, + 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, 15, 15, 15, 15, 15, 15, 15, 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, 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, + 15, 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, 0, 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, 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, 123, 123, 123, 91, 91, 91, 91, 0, 0, 123, 123, 123, - 123, 91, 91, 123, 91, 91, 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, 0, 0, 0, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 123, 123, 123, 91, - 91, 91, 91, 91, 91, 91, 91, 123, 123, 91, 123, 91, 91, 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, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 91, 123, 91, - 123, 123, 91, 91, 91, 91, 91, 91, 123, 91, 0, 0, 0, 0, 0, 0, 0, 0, + 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, 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, 15, 15, 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, 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, + 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, 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, 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, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 0, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, + 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, 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, 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, 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, 91, 91, 91, - 91, 91, 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, 91, 91, 91, 91, 91, 91, 91, 3, - 3, 3, 3, 3, 14, 14, 14, 14, 90, 90, 90, 90, 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, 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, 123, 123, 123, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 91, 91, 91, 91, 90, 90, 90, 90, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 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, 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, - 91, 91, 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, 123, 123, 91, 91, 91, - 14, 14, 14, 123, 123, 123, 123, 123, 123, 17, 17, 17, 17, 17, 17, 17, - 17, 91, 91, 91, 91, 91, 91, 91, 91, 14, 14, 91, 91, 91, 91, 91, 91, - 91, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 91, 91, 91, - 91, 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, 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, + 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, 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, 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, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 14, - 14, 91, 91, 91, 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, 106, 106, - 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, - 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 21, 21, 21, 21, 21, + 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, 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, 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, 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, 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, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, - 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, - 106, 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, 106, 106, 106, 106, 106, 106, - 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, - 106, 106, 106, 106, 106, 106, 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, 106, - 0, 106, 106, 0, 0, 106, 0, 0, 106, 106, 0, 0, 106, 106, 106, 106, 0, - 106, 106, 106, 106, 106, 106, 106, 106, 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, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, - 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 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, 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, 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, 21, 21, 21, 21, 106, 106, 0, 106, 106, 106, 106, 0, - 0, 106, 106, 106, 106, 106, 106, 106, 106, 0, 106, 106, 106, 106, 106, - 106, 106, 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, 106, 106, 0, 106, 106, - 106, 106, 0, 106, 106, 106, 106, 106, 0, 106, 0, 0, 0, 106, 106, 106, - 106, 106, 106, 106, 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, 106, 106, - 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, - 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 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, 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, 21, 21, 21, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, - 106, 106, 106, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 106, 106, 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, 106, - 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, - 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 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, 106, 106, 106, 106, 106, 106, 106, 106, 106, - 106, 106, 106, 106, 106, 106, 106, 21, 21, 21, 21, 21, 21, 0, 0, 106, - 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, - 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 7, 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, 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, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 7, 21, 21, 21, 21, 21, 21, 106, 106, 106, 106, 106, - 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, - 106, 106, 106, 106, 106, 106, 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, 106, 106, 106, 106, 106, 106, 106, 106, 106, - 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, - 106, 106, 7, 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, 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, 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, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, - 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 7, 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, 106, 106, 106, - 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, - 106, 106, 106, 106, 106, 106, 106, 106, 7, 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, 106, 21, 0, 0, 9, 9, 9, 9, 9, 9, + 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, + 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, 9, 9, 9, 9, 9, 15, - 15, 15, 15, 15, 0, 0, 18, 18, 18, 18, 18, 18, 18, 18, 18, 91, 91, 91, - 91, 91, 91, 91, 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, 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, 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, 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, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, + 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, + 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, 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, 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, 0, 0, 0, 0, 0, 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, 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, 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, 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, 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, 0, 0, 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, 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, 14, 14, 14, 14, 14, 14, 14, 0, - 0, 0, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 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, 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, 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, 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, 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, 14, 14, + 14, 14, 14, 14, 0, 0, 0, 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, 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, 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, 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, 14, 14, + 14, 14, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0 #endif /* TCL_UTF_MAX > 3 */ }; @@ -1450,18 +1482,19 @@ static const int groups[] = { -2759550, -2760062, 53890, 52866, 52610, 51842, 52098, -10833534, -10832510, 53122, -10823550, -10830718, 53634, 54146, -2750078, -10829950, -2751614, 54658, 54914, -2745982, 55938, -10824062, - 17794, 55682, 18306, 56194, -10817918, 4, 6, -21370, 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, - 10, -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, 18, 17, - 10305, 10370 + 17794, 55682, 18306, 56194, -10818686, -10817918, 4, 6, -21370, + 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, -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 }; #if TCL_UTF_MAX > 3 -- cgit v0.12 From ad6cba5a8e20b73326e32fd7168a550c2a4090c7 Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 18 Jun 2015 17:26:59 +0000 Subject: From aspect, several edge case coverage tests. --- tests/lreplace.test | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/tests/lreplace.test b/tests/lreplace.test index 55bad37..50610dc 100644 --- a/tests/lreplace.test +++ b/tests/lreplace.test @@ -130,6 +130,58 @@ test lreplace-3.1 {lreplace won't modify shared argument objects} { p } "a b c" +test lreplace-4.1 {Bug ccc2c2cc98: lreplace edge case} { + lreplace {} 1 1 +} {} +test lreplace-4.2 {Bug ccc2c2cc98: lreplace edge case} { + lreplace { } 1 1 +} {} +test lreplace-4.3 {lreplace edge case} { + lreplace {1 2 3} 2 0 +} {1 2 3} +test lreplace-4.4 {lreplace edge case} { + lreplace {1 2 3 4 5} 3 1 +} {1 2 3 4 5} +test lreplace-4.5 {lreplace edge case} { + lreplace {1 2 3 4 5} 3 0 _ +} {1 2 3 _ 4 5} +test lreplace-4.6 {lreplace end-x: bug a4cb3f06c4} { + lreplace {0 1 2 3 4} 0 end-2 +} {3 4} +test lreplace-4.6.1 {lreplace end-x: bug a4cb3f06c4} { + lreplace {0 1 2 3 4} 0 end-2 a b c +} {a b c 3 4} +test lreplace-4.7 {lreplace with two end-indexes: increasing} { + lreplace {0 1 2 3 4} end-2 end-1 +} {0 1 4} +test lreplace-4.7.1 {lreplace with two end-indexes: increasing} { + lreplace {0 1 2 3 4} end-2 end-1 a b c +} {0 1 a b c 4} +test lreplace-4.8 {lreplace with two end-indexes: equal} { + lreplace {0 1 2 3 4} end-2 end-2 +} {0 1 3 4} +test lreplace-4.8.1 {lreplace with two end-indexes: equal} { + lreplace {0 1 2 3 4} end-2 end-2 a b c +} {0 1 a b c 3 4} +test lreplace-4.9 {lreplace with two end-indexes: decreasing} { + lreplace {0 1 2 3 4} end-2 end-3 +} {0 1 2 3 4} +test lreplace-4.9.1 {lreplace with two end-indexes: decreasing} { + lreplace {0 1 2 3 4} end-2 end-3 a b c +} {0 1 a b c 2 3 4} +test lreplace-4.10 {lreplace with two equal indexes} { + lreplace {0 1 2 3 4} 2 2 +} {0 1 3 4} +test lreplace-4.10.1 {lreplace with two equal indexes} { + lreplace {0 1 2 3 4} 2 2 a b c +} {0 1 a b c 3 4} +test lreplace-4.11 {lreplace end index first} { + lreplace {0 1 2 3 4} end-2 1 a b c +} {0 1 a b c 2 3 4} +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} + # cleanup catch {unset foo} ::tcltest::cleanupTests -- cgit v0.12