diff options
-rw-r--r-- | ChangeLog | 27 | ||||
-rw-r--r-- | generic/tclIO.c | 506 | ||||
-rw-r--r-- | generic/tclPkg.c | 906 |
3 files changed, 803 insertions, 636 deletions
@@ -1,29 +1,32 @@ +2006-11-08 Donal K. Fellows <dkf@users.sf.net> + + * generic/tclIO.c, generic/tclPkg.c: Style & clarity rewrites. + 2006-11-07 Andreas Kupries <andreask@activestate.com> - * unix/tclUnixFCmd.c (CopyFile): [SF Tcl Bug 1586470]. Added code - to fall back to a hardwired default block size should the - filesystem report a bogus value. + * unix/tclUnixFCmd.c (CopyFile): Added code to fall back to a + hardwired default block size should the filesystem report a bogus + value. [Bug 1586470] 2006-11-04 Don Porter <dgp@users.sourceforge.net> - * generic/tclStringObj.c: Changed Tcl_ObjPrintf() response to - an invalid format specifier string. No longer panics; now produces - an error message as output. + * generic/tclStringObj.c: Changed Tcl_ObjPrintf() response to an + invalid format specifier string. No longer panics; now produces an + error message as output. TIP#274 IMPLEMENTATION - * generic/tclParseExpr.c: Exponentiation operator is now - * tests/expr.test: right associative. [Patch 1556802] + * generic/tclParseExpr.c: Exponentiation operator is now right + * tests/expr.test: associative. [Patch 1556802] 2006-11-03 Miguel Sofer <msofer@users.sf.net> - * generic/tclBasic.c (TEOVI): fix por possible leak of a Command - in the presence of execution traces that delete it. + * generic/tclBasic.c (TEOVI): fix por possible leak of a Command in + the presence of execution traces that delete it. * generic/tclBasic.c (TEOVI): * tests/trace.test (trace-21.11): fix for [Bug 1590232], execution - traces may cause a second command resolution in the wrong - namespace. + traces may cause a second command resolution in the wrong namespace. 2006-11-03 Donal K. Fellows <donal.k.fellows@manchester.ac.uk> diff --git a/generic/tclIO.c b/generic/tclIO.c index 689447b..9016cef 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -10,7 +10,7 @@ * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tclIO.c,v 1.109 2006/09/28 19:24:52 msofer Exp $ + * RCS: @(#) $Id: tclIO.c,v 1.110 2006/11/08 11:41:44 dkf Exp $ */ #include "tclInt.h" @@ -120,7 +120,7 @@ static int WriteBytes(Channel *chanPtr, CONST char *src, int srcLen); static int WriteChars(Channel *chanPtr, CONST char *src, int srcLen); -static Tcl_Obj * FixLevelCode(Tcl_Obj* msg); +static Tcl_Obj * FixLevelCode(Tcl_Obj *msg); static void SpliceChannel(Tcl_Channel chan); static void CutChannel(Tcl_Channel chan); @@ -177,7 +177,7 @@ TclFinalizeIOSubsystem(void) ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); Channel *chanPtr; /* Iterates over open channels. */ ChannelState *nextCSPtr; /* Iterates over open channels. */ - ChannelState *statePtr; /* state of channel stack */ + ChannelState *statePtr; /* State of channel stack */ /* * Walk all channel state structures known to this thread and @@ -211,6 +211,7 @@ TclFinalizeIOSubsystem(void) * Preserve statePtr from disappearing until we can get the * nextCSPtr below. */ + Tcl_Preserve(statePtr); if (statePtr->refCount <= 0) { /* @@ -248,10 +249,12 @@ TclFinalizeIOSubsystem(void) chanPtr->instanceData = NULL; statePtr->flags |= CHANNEL_DEAD; } + /* * We look for the next pointer now in case we had one closed on up * during the current channel's closeproc (eg: rechan extension) */ + nextCSPtr = statePtr->nextCSPtr; Tcl_Release(statePtr); } @@ -343,7 +346,7 @@ Tcl_GetStdChannel( */ if (tsdPtr->stdinChannel != NULL) { - (void) Tcl_RegisterChannel(NULL, tsdPtr->stdinChannel); + Tcl_RegisterChannel(NULL, tsdPtr->stdinChannel); } } channel = tsdPtr->stdinChannel; @@ -353,7 +356,7 @@ Tcl_GetStdChannel( tsdPtr->stdoutChannel = TclpGetDefaultStdChannel(TCL_STDOUT); tsdPtr->stdoutInitialized = 1; if (tsdPtr->stdoutChannel != NULL) { - (void) Tcl_RegisterChannel(NULL, tsdPtr->stdoutChannel); + Tcl_RegisterChannel(NULL, tsdPtr->stdoutChannel); } } channel = tsdPtr->stdoutChannel; @@ -363,7 +366,7 @@ Tcl_GetStdChannel( tsdPtr->stderrChannel = TclpGetDefaultStdChannel(TCL_STDERR); tsdPtr->stderrInitialized = 1; if (tsdPtr->stderrChannel != NULL) { - (void) Tcl_RegisterChannel(NULL, tsdPtr->stderrChannel); + Tcl_RegisterChannel(NULL, tsdPtr->stderrChannel); } } channel = tsdPtr->stderrChannel; @@ -483,14 +486,12 @@ GetChannelTable( Tcl_HashTable *hTblPtr; /* Hash table of channels. */ Tcl_Channel stdinChan, stdoutChan, stderrChan; - hTblPtr = (Tcl_HashTable *) Tcl_GetAssocData(interp, "tclIO", NULL); + hTblPtr = Tcl_GetAssocData(interp, "tclIO", NULL); if (hTblPtr == NULL) { hTblPtr = (Tcl_HashTable *) ckalloc(sizeof(Tcl_HashTable)); Tcl_InitHashTable(hTblPtr, TCL_STRING_KEYS); - - (void) Tcl_SetAssocData(interp, "tclIO", - (Tcl_InterpDeleteProc *) DeleteChannelTable, - (ClientData) hTblPtr); + Tcl_SetAssocData(interp, "tclIO", + (Tcl_InterpDeleteProc *) DeleteChannelTable, hTblPtr); /* * If the interpreter is trusted (not "safe"), insert channels for @@ -929,7 +930,7 @@ DetachChannel( statePtr = chanPtr->state; if (interp != NULL) { - hTblPtr = (Tcl_HashTable *) Tcl_GetAssocData(interp, "tclIO", NULL); + hTblPtr = Tcl_GetAssocData(interp, "tclIO", NULL); if (hTblPtr == NULL) { return TCL_ERROR; } @@ -1100,6 +1101,7 @@ Tcl_CreateChannel( if (chanName != NULL) { char *tmp = ckalloc((unsigned) (strlen(chanName) + 1)); + statePtr->channelName = tmp; strcpy(tmp, chanName); } else { @@ -1332,6 +1334,7 @@ Tcl_StackChannel( statePtr->csPtr = csPtr; } + /* * Discard any input in the buffers. They are not yet read by the user of * the channel, so they have to go through the new transformation before @@ -1468,6 +1471,7 @@ Tcl_UnstackChannel( if (Tcl_Flush((Tcl_Channel) chanPtr) != TCL_OK) { statePtr->csPtr = csPtr; + /* * TIP #219, Tcl Channel Reflection API. * Move error messages put by the driver into the chan/ip @@ -1475,6 +1479,7 @@ Tcl_UnstackChannel( * to the regular message if nothing was found in the * bypasses. */ + if (!TclChanCaughtErrorBypass(interp, chan) && interp) { Tcl_AppendResult(interp, "could not flush channel \"", Tcl_GetChannelName((Tcl_Channel) chanPtr), "\"", @@ -1627,7 +1632,8 @@ Tcl_Channel Tcl_GetStackedChannel( Tcl_Channel chan) { - Channel *chanPtr = (Channel *) chan; /* The actual channel. */ + Channel *chanPtr = (Channel *) chan; + /* The actual channel. */ return (Tcl_Channel) chanPtr->downChanPtr; } @@ -1654,7 +1660,8 @@ Tcl_Channel Tcl_GetTopChannel( Tcl_Channel chan) { - Channel *chanPtr = (Channel *) chan; /* The actual channel. */ + Channel *chanPtr = (Channel *) chan; + /* The actual channel. */ return (Tcl_Channel) chanPtr->state->topChanPtr; } @@ -1679,7 +1686,8 @@ ClientData Tcl_GetChannelInstanceData( Tcl_Channel chan) /* Channel for which to return client data. */ { - Channel *chanPtr = (Channel *) chan; /* The actual channel. */ + Channel *chanPtr = (Channel *) chan; + /* The actual channel. */ return chanPtr->instanceData; } @@ -1705,7 +1713,8 @@ Tcl_GetChannelThread( Tcl_Channel chan) /* The channel to return the managing thread * for. */ { - Channel *chanPtr = (Channel *) chan; /* The actual channel. */ + Channel *chanPtr = (Channel *) chan; + /* The actual channel. */ return chanPtr->state->managingThread; } @@ -2081,10 +2090,11 @@ FlushChannel( */ if (((statePtr->curOutPtr != NULL) && - (statePtr->curOutPtr->nextAdded == statePtr->curOutPtr->bufLength)) + (statePtr->curOutPtr->nextAdded + == statePtr->curOutPtr->bufLength)) || ((statePtr->flags & BUFFER_READY) && (statePtr->outQueueHead == NULL))) { - statePtr->flags &= (~(BUFFER_READY)); + statePtr->flags &= ~BUFFER_READY; statePtr->curOutPtr->nextPtr = NULL; if (statePtr->outQueueHead == NULL) { statePtr->outQueueHead = statePtr->curOutPtr; @@ -2175,7 +2185,7 @@ FlushChannel( if (statePtr->unreportedError == 0) { statePtr->unreportedError = errorCode; - statePtr->unreportedMsg = msg; + statePtr->unreportedMsg = msg; if (msg != NULL) { Tcl_IncrRefCount(msg); } @@ -2187,7 +2197,7 @@ FlushChannel( statePtr->chanMsg = NULL; if (msg != NULL) { - Tcl_DecrRefCount(msg); + TclDecrRefCount(msg); } } } else { @@ -2199,18 +2209,18 @@ FlushChannel( */ Tcl_SetErrno(errorCode); - if (interp != NULL) { - if (!TclChanCaughtErrorBypass(interp, (Tcl_Channel) chanPtr)) { - /* - * Casting away CONST here is safe because the - * TCL_VOLATILE flag guarantees CONST treatment of the - * Posix error string. - */ + if (interp != NULL && !TclChanCaughtErrorBypass(interp, + (Tcl_Channel) chanPtr)) { + /* + * Casting away CONST here is safe because the + * TCL_VOLATILE flag guarantees CONST treatment of the + * Posix error string. + */ - Tcl_SetResult(interp, - (char *) Tcl_PosixError(interp), TCL_VOLATILE); - } + Tcl_SetResult(interp, (char *) Tcl_PosixError(interp), + TCL_VOLATILE); } + /* * An unreportable bypassed message is kept, for the caller of * Tcl_Seek, Tcl_Write, etc. @@ -2254,7 +2264,7 @@ FlushChannel( if (wroteSome) { return errorCode; } else if (statePtr->outQueueHead == NULL) { - statePtr->flags &= (~(BG_FLUSH_SCHEDULED)); + statePtr->flags &= ~BG_FLUSH_SCHEDULED; (chanPtr->typePtr->watchProc)(chanPtr->instanceData, statePtr->interestMask); } @@ -2360,7 +2370,7 @@ CloseChannel( if (interp != NULL) { Tcl_SetChannelErrorInterp(interp,statePtr->chanMsg); } - Tcl_DecrRefCount(statePtr->chanMsg); + TclDecrRefCount(statePtr->chanMsg); statePtr->chanMsg = NULL; } @@ -2408,13 +2418,14 @@ CloseChannel( if (statePtr->unreportedError != 0) { errorCode = statePtr->unreportedError; - /* TIP #219, Tcl Channel Reflection API. + /* + * TIP #219, Tcl Channel Reflection API. * Move an error message found in the unreported area into the regular * bypass (interp). This kills any message in the channel bypass area. */ if (statePtr->chanMsg != NULL) { - Tcl_DecrRefCount(statePtr->chanMsg); + TclDecrRefCount(statePtr->chanMsg); statePtr->chanMsg = NULL; } if (interp) { @@ -2502,7 +2513,7 @@ CutChannel( * states - used to splice a channel out of * the list on close. */ ChannelState *statePtr = ((Channel *) chan)->state; - /* state of the channel stack. */ + /* State of the channel stack. */ Tcl_DriverThreadActionProc *threadActionProc; /* @@ -2542,13 +2553,13 @@ Tcl_CutChannel( Tcl_Channel chan) /* The channel being added. Must not be * referenced in any interpreter. */ { - Channel* chanPtr = ((Channel*) chan)->state->bottomChanPtr; + Channel *chanPtr = ((Channel *) chan)->state->bottomChanPtr; ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); ChannelState *prevCSPtr; /* Preceding channel state in list of all * states - used to splice a channel out of * the list on close. */ ChannelState *statePtr = chanPtr->state; - /* state of the channel stack. */ + /* State of the channel stack. */ Tcl_DriverThreadActionProc *threadActionProc; /* @@ -2779,7 +2790,7 @@ Tcl_Close( if (interp != NULL) { Tcl_SetChannelErrorInterp(interp,statePtr->chanMsg); } - Tcl_DecrRefCount(statePtr->chanMsg); + TclDecrRefCount(statePtr->chanMsg); statePtr->chanMsg = NULL; } } @@ -2836,7 +2847,7 @@ Tcl_Close( * them into the regular interpreter result. * * Notes: Due to the assertion of CHANNEL_CLOSED in the flags - * "FlushChannel" has called "CloseChannel" and thus freed all the channel + * FlushChannel() has called CloseChannel() and thus freed all the channel * structures. We must not try to access "chan" anymore, hence the NULL * argument in the call below. The only place which may still contain a * message is the interpreter itself, and "CloseChannel" made sure to lift @@ -2982,7 +2993,7 @@ Tcl_Write( */ Channel *chanPtr; - ChannelState *statePtr; /* state info for channel */ + ChannelState *statePtr; /* State info for channel */ statePtr = ((Channel *) chan)->state; chanPtr = statePtr->topChanPtr; @@ -3029,7 +3040,8 @@ Tcl_WriteRaw( * strlen(). */ { Channel *chanPtr = ((Channel *) chan); - ChannelState *statePtr = chanPtr->state; /* state info for channel */ + ChannelState *statePtr = chanPtr->state; + /* State info for channel */ int errorCode, written; if (CheckChannelErrors(statePtr, TCL_WRITABLE | CHANNEL_RAW_MODE) != 0) { @@ -3086,7 +3098,7 @@ Tcl_WriteChars( int len) /* Length of string in bytes, or < 0 for * strlen(). */ { - ChannelState *statePtr; /* state info for channel */ + ChannelState *statePtr; /* State info for channel */ statePtr = ((Channel *) chan)->state; @@ -3132,7 +3144,7 @@ DoWriteChars( * Always use the topmost channel of the stack */ - ChannelState *statePtr; /* state info for channel */ + ChannelState *statePtr; /* State info for channel */ statePtr = chanPtr->state; chanPtr = statePtr->topChanPtr; @@ -3193,7 +3205,7 @@ Tcl_WriteObj( */ Channel *chanPtr; - ChannelState *statePtr; /* state info for channel */ + ChannelState *statePtr; /* State info for channel */ char *src; int srcLen; @@ -3239,7 +3251,8 @@ WriteBytes( CONST char *src, /* Bytes to write. */ int srcLen) /* Number of bytes to write. */ { - ChannelState *statePtr = chanPtr->state; /* state info for channel */ + ChannelState *statePtr = chanPtr->state; + /* State info for channel */ ChannelBuffer *bufPtr; char *dst; int dstMax, sawLF, savedLF, total, dstLen, toWrite; @@ -3328,7 +3341,8 @@ WriteChars( CONST char *src, /* UTF-8 string to write. */ int srcLen) /* Length of UTF-8 string in bytes. */ { - ChannelState *statePtr = chanPtr->state; /* state info for channel */ + ChannelState *statePtr = chanPtr->state; + /* State info for channel */ ChannelBuffer *bufPtr; char *dst, *stage; int saved, savedLF, sawLF, total, dstLen, stageMax, dstWrote; @@ -3413,7 +3427,7 @@ WriteChars( * that we need to stick at the beginning of this buffer. */ - memcpy((VOID *) dst, (VOID *) safe, (size_t) saved); + memcpy(dst, safe, (size_t) saved); bufPtr->nextAdded += saved; dst += saved; dstLen -= saved; @@ -3425,7 +3439,8 @@ WriteChars( &statePtr->outputEncodingState, dst, dstLen + BUFFER_PADDING, &stageRead, &dstWrote, NULL); - /* Fix for SF #506297, reported by Martin Forssen + /* + * Fix for SF #506297, reported by Martin Forssen * <ruric@users.sourceforge.net>. * * The encoding chosen in the script exposing the bug writes out @@ -3470,7 +3485,7 @@ WriteChars( */ saved = bufPtr->nextAdded - bufPtr->bufLength; - memcpy((VOID *) safe, (VOID *) (dst + dstLen), (size_t) saved); + memcpy(safe, dst + dstLen, (size_t) saved); bufPtr->nextAdded = bufPtr->bufLength; } if (CheckFlush(chanPtr, bufPtr, sawLF) != 0) { @@ -3656,7 +3671,9 @@ CheckFlush( int newlineFlag) /* Non-zero if a the channel buffer contains a * newline. */ { - ChannelState *statePtr = chanPtr->state; /* state info for channel */ + ChannelState *statePtr = chanPtr->state; + /* State info for channel */ + /* * The current buffer is ready for output: * 1. if it is full. @@ -3755,7 +3772,8 @@ Tcl_GetsObj( { GetsState gs; Channel *chanPtr = (Channel *) chan; - ChannelState *statePtr = chanPtr->state; /* state info for channel */ + ChannelState *statePtr = chanPtr->state; + /* State info for channel */ ChannelBuffer *bufPtr; int inEofChar, skip, copiedTotal, oldLength, oldFlags, oldRemoved; Tcl_Encoding encoding; @@ -3963,7 +3981,7 @@ Tcl_GetsObj( */ dstEnd = eof; - statePtr->flags |= (CHANNEL_EOF | CHANNEL_STICKY_EOF); + statePtr->flags |= CHANNEL_EOF | CHANNEL_STICKY_EOF; statePtr->inputEncodingFlags |= TCL_ENCODING_END; } if (statePtr->flags & CHANNEL_EOF) { @@ -4091,10 +4109,10 @@ FilterInputBytes( Channel *chanPtr, /* Channel to read. */ GetsState *gsPtr) /* Current state of gets operation. */ { - ChannelState *statePtr = chanPtr->state; /* state info for channel */ + ChannelState *statePtr = chanPtr->state; + /* State info for channel */ ChannelBuffer *bufPtr; - char *raw, *rawStart, *rawEnd; - char *dst; + char *raw, *rawStart, *rawEnd, *dst; int offset, toRead, dstNeeded, spaceLeft, result, rawLen, length; Tcl_Obj *objPtr; #define ENCODING_LINESIZE 20 /* Lower bound on how many bytes to convert at @@ -4228,8 +4246,8 @@ FilterInputBytes( statePtr->inQueueTail = nextPtr; } extra = rawLen - gsPtr->rawRead; - memcpy((VOID *) (nextPtr->buf + BUFFER_PADDING - extra), - (VOID *) (raw + gsPtr->rawRead), (size_t) extra); + memcpy(nextPtr->buf + BUFFER_PADDING - extra, + raw + gsPtr->rawRead, (size_t) extra); nextPtr->nextRemoved -= extra; bufPtr->nextAdded -= extra; } @@ -4268,7 +4286,8 @@ PeekAhead( * UTF-8 characters. */ GetsState *gsPtr) /* Current state of gets operation. */ { - ChannelState *statePtr = chanPtr->state; /* state info for channel */ + ChannelState *statePtr = chanPtr->state; + /* State info for channel */ ChannelBuffer *bufPtr; Tcl_DriverBlockModeProc *blockModeProc; int bytesLeft; @@ -4345,7 +4364,8 @@ CommonGetsCleanup( Channel *chanPtr, Tcl_Encoding encoding) { - ChannelState *statePtr = chanPtr->state; /* state info for channel */ + ChannelState *statePtr = chanPtr->state; + /* State info for channel */ ChannelBuffer *bufPtr, *nextPtr; bufPtr = statePtr->inQueueHead; @@ -4375,8 +4395,8 @@ CommonGetsCleanup( extra = bufPtr->bufLength - bufPtr->nextAdded; if (extra > 0) { - memcpy((VOID *) (bufPtr->buf + bufPtr->nextAdded), - (VOID *) (nextPtr->buf + BUFFER_PADDING - extra), + memcpy(bufPtr->buf + bufPtr->nextAdded, + nextPtr->buf + BUFFER_PADDING - extra, (size_t) extra); bufPtr->nextAdded += extra; nextPtr->nextRemoved = BUFFER_PADDING; @@ -4418,7 +4438,8 @@ Tcl_Read( int bytesToRead) /* Maximum number of bytes to read. */ { Channel *chanPtr = (Channel *) chan; - ChannelState *statePtr = chanPtr->state; /* state info for channel */ + ChannelState *statePtr = chanPtr->state; + /* State info for channel */ /* * This operation should occur at the top of a channel stack. @@ -4462,9 +4483,9 @@ Tcl_ReadRaw( int bytesToRead) /* Maximum number of bytes to read. */ { Channel *chanPtr = (Channel *) chan; - ChannelState *statePtr = chanPtr->state; /* state info for channel */ - int nread, result; - int copied, copiedNow; + ChannelState *statePtr = chanPtr->state; + /* State info for channel */ + int nread, result, copied, copiedNow; /* * The check below does too much because it will reject a call to this @@ -4499,13 +4520,13 @@ Tcl_ReadRaw( if (statePtr->flags & CHANNEL_NONBLOCKING) { goto done; } - statePtr->flags &= (~(CHANNEL_BLOCKED)); + statePtr->flags &= ~CHANNEL_BLOCKED; } #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 + * [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. */ @@ -4541,11 +4562,10 @@ Tcl_ReadRaw( 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 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)) { @@ -4555,8 +4575,8 @@ Tcl_ReadRaw( #ifdef TCL_IO_TRACK_OS_FOR_DRIVER_WITH_BAD_BLOCKING if (nread <= (bytesToRead - copied)) { /* - * [SF Tcl Bug 943274] We have read the available data, - * clear flag. + * [Bug 943274] We have read the available data, clear + * flag. */ statePtr->flags &= ~CHANNEL_HAS_MORE_DATA; @@ -4629,7 +4649,8 @@ Tcl_ReadChars( * of the object. */ { Channel *chanPtr = (Channel *) chan; - ChannelState *statePtr = chanPtr->state; /* state info for channel */ + ChannelState *statePtr = chanPtr->state; + /* State info for channel */ /* * This operation should occur at the top of a channel stack. @@ -4683,7 +4704,8 @@ DoReadChars( * the data will replace the existing contents * of the object. */ { - ChannelState *statePtr = chanPtr->state; /* state info for channel */ + ChannelState *statePtr = chanPtr->state; + /* State info for channel */ ChannelBuffer *bufPtr; int offset, factor, copied, copiedNow, result; Tcl_Encoding encoding; @@ -5001,40 +5023,38 @@ ReadChars( * 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. + * - 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. + * 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. + * 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. + * 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. + (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; @@ -5096,9 +5116,7 @@ ReadChars( /* * 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. - * - * SF #478856. + * 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, @@ -5111,25 +5129,25 @@ ReadChars( 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'. + /* + * 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. + * 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"); + Tcl_Panic("Buffer Underflow, BUFFER_PADDING not enough"); } nextPtr->nextRemoved -= srcLen; - memcpy((VOID *) (nextPtr->buf + nextPtr->nextRemoved), (VOID *) src, - (size_t) srcLen); + memcpy(nextPtr->buf + nextPtr->nextRemoved, src, (size_t) srcLen); RecycleBuffer(statePtr, bufPtr, 0); statePtr->inQueueHead = nextPtr; return ReadChars(statePtr, objPtr, charsToRead, offsetPtr, factorPtr); @@ -5255,7 +5273,7 @@ TranslateInputEOL( switch (statePtr->inputTranslation) { case TCL_TRANSLATE_LF: if (dstStart != srcStart) { - memcpy((VOID *) dstStart, (VOID *) srcStart, (size_t) dstLen); + memcpy(dstStart, srcStart, (size_t) dstLen); } srcLen = dstLen; break; @@ -5263,7 +5281,7 @@ TranslateInputEOL( char *dst, *dstEnd; if (dstStart != srcStart) { - memcpy((VOID *) dstStart, (VOID *) srcStart, (size_t) dstLen); + memcpy(dstStart, srcStart, (size_t) dstLen); } dstEnd = dstStart + dstLen; for (dst = dstStart; dst < dstEnd; dst++) { @@ -5348,7 +5366,7 @@ TranslateInputEOL( * character in the output string. */ - statePtr->flags |= (CHANNEL_EOF | CHANNEL_STICKY_EOF); + statePtr->flags |= CHANNEL_EOF | CHANNEL_STICKY_EOF; statePtr->inputEncodingFlags |= TCL_ENCODING_END; statePtr->flags &= ~(INPUT_SAW_CR | INPUT_NEED_NL); return 1; @@ -5418,7 +5436,7 @@ Tcl_Ungets( if (statePtr->flags & CHANNEL_STICKY_EOF) { goto done; } - statePtr->flags &= (~(CHANNEL_BLOCKED | CHANNEL_EOF)); + statePtr->flags &= ~(CHANNEL_BLOCKED | CHANNEL_EOF); bufPtr = AllocChannelBuffer(len); for (i = 0; i < len; i++) { @@ -5527,7 +5545,8 @@ DiscardInputQueued( int discardSavedBuffers) /* If non-zero, discard all buffers including * last one. */ { - ChannelBuffer *bufPtr, *nxtPtr; /* Loop variables. */ + ChannelBuffer *bufPtr, *nxtPtr; + /* Loop variables. */ bufPtr = statePtr->inQueueHead; statePtr->inQueueHead = NULL; @@ -5573,7 +5592,8 @@ GetInput( 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; /* state info for channel */ + ChannelState *statePtr = chanPtr->state; + /* State info for channel */ /* * Prevent reading from a dead channel -- a channel that has been closed @@ -5628,10 +5648,9 @@ GetInput( statePtr->saveInBufPtr = NULL; /* - * 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. + * 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. */ if ((bufPtr != NULL) @@ -5768,8 +5787,10 @@ Tcl_Seek( Tcl_WideInt offset, /* Offset to seek to. */ int mode) /* Relative to which location to seek? */ { - Channel *chanPtr = (Channel *) chan; /* The real IO channel. */ - ChannelState *statePtr = chanPtr->state; /* state info for channel */ + Channel *chanPtr = (Channel *) chan; + /* The real IO channel. */ + ChannelState *statePtr = chanPtr->state; + /* State info for channel */ int inputBuffered, outputBuffered; /* # bytes held in buffers. */ int result; /* Of device driver operations. */ @@ -5860,9 +5881,9 @@ Tcl_Seek( if (result != 0) { return Tcl_LongAsWide(-1); } - statePtr->flags &= (~(CHANNEL_NONBLOCKING)); + statePtr->flags &= ~CHANNEL_NONBLOCKING; if (statePtr->flags & BG_FLUSH_SCHEDULED) { - statePtr->flags &= (~(BG_FLUSH_SCHEDULED)); + statePtr->flags &= ~BG_FLUSH_SCHEDULED; } } @@ -5953,8 +5974,10 @@ Tcl_WideInt Tcl_Tell( Tcl_Channel chan) /* The channel to return pos for. */ { - Channel *chanPtr = (Channel *) chan; /* The real IO channel. */ - ChannelState *statePtr = chanPtr->state; /* state info for channel */ + Channel *chanPtr = (Channel *) chan; + /* The real IO channel. */ + ChannelState *statePtr = chanPtr->state; + /* State info for channel */ int inputBuffered, outputBuffered; /* # bytes held in buffers. */ int result; /* Of calling device driver. */ @@ -6103,6 +6126,7 @@ Tcl_TruncateChannel( * Feature not supported and it's not emulatable. Pretend it's * returned an EINVAL, a very generic error! */ + Tcl_SetErrno(EINVAL); return TCL_ERROR; } @@ -6112,6 +6136,7 @@ Tcl_TruncateChannel( * We require that the file was opened of writing. Do that check now * so that we only flush if we think we're going to succeed. */ + Tcl_SetErrno(EINVAL); return TCL_ERROR; } @@ -6180,7 +6205,7 @@ CheckChannelErrors( */ if (statePtr->chanMsg != NULL) { - Tcl_DecrRefCount(statePtr->chanMsg); + TclDecrRefCount(statePtr->chanMsg); } statePtr->chanMsg = statePtr->unreportedMsg; statePtr->unreportedMsg = NULL; @@ -6400,7 +6425,7 @@ Tcl_ChannelBuffered( Tcl_Channel chan) /* The channel to query. */ { Channel *chanPtr = (Channel *) chan; - /* real channel structure. */ + /* Real channel structure. */ ChannelBuffer *bufPtr; int bytesBuffered; @@ -6441,10 +6466,7 @@ Tcl_SetChannelBufferSize( * not accept the requested size and leave the current buffer size. */ - if (sz < 1) { - return; - } - if (sz > (1024 * 1024)) { + if (sz < 1 || sz > 1024*1024) { return; } @@ -6587,7 +6609,8 @@ Tcl_GetChannelOption( size_t len; /* Length of optionName string. */ char optionVal[128]; /* Buffer for sprintf. */ Channel *chanPtr = (Channel *) chan; - ChannelState *statePtr = chanPtr->state; /* state info for channel */ + ChannelState *statePtr = chanPtr->state; + /* State info for channel */ int flags; /* @@ -6819,8 +6842,10 @@ Tcl_SetChannelOption( CONST char *optionName, /* Which option to set? */ CONST char *newValue) /* New value for option. */ { - Channel *chanPtr = (Channel *) chan; /* The real IO channel. */ - ChannelState *statePtr = chanPtr->state; /* state info for channel */ + Channel *chanPtr = (Channel *) chan; + /* The real IO channel. */ + ChannelState *statePtr = chanPtr->state; + /* State info for channel */ size_t len; /* Length of optionName string. */ int argc; CONST char **argv; @@ -6873,14 +6898,14 @@ Tcl_SetChannelOption( len = strlen(newValue); if ((newValue[0] == 'f') && (strncmp(newValue, "full", len) == 0)) { statePtr->flags &= - (~(CHANNEL_UNBUFFERED|CHANNEL_LINEBUFFERED)); + ~(CHANNEL_UNBUFFERED|CHANNEL_LINEBUFFERED); } else if ((newValue[0] == 'l') && (strncmp(newValue, "line", len) == 0)) { - statePtr->flags &= (~(CHANNEL_UNBUFFERED)); + statePtr->flags &= ~CHANNEL_UNBUFFERED; statePtr->flags |= CHANNEL_LINEBUFFERED; } else if ((newValue[0] == 'n') && (strncmp(newValue, "none", len) == 0)) { - statePtr->flags &= (~(CHANNEL_LINEBUFFERED)); + statePtr->flags &= ~CHANNEL_LINEBUFFERED; statePtr->flags |= CHANNEL_UNBUFFERED; } else { if (interp) { @@ -7035,8 +7060,7 @@ Tcl_SetChannelOption( if (translation != statePtr->inputTranslation) { statePtr->inputTranslation = translation; - statePtr->flags &= ~(INPUT_SAW_CR); - statePtr->flags &= ~(CHANNEL_NEED_MORE_DATA); + statePtr->flags &= ~(INPUT_SAW_CR | CHANNEL_NEED_MORE_DATA); UpdateInterest(chanPtr); } } @@ -7096,14 +7120,13 @@ Tcl_SetChannelOption( RecycleBuffer(statePtr, statePtr->saveInBufPtr, 1); statePtr->saveInBufPtr = NULL; } - if (statePtr->inQueueHead != NULL) { - if ((statePtr->inQueueHead->nextPtr == NULL) - && (statePtr->inQueueHead->nextAdded == - statePtr->inQueueHead->nextRemoved)) { - RecycleBuffer(statePtr, statePtr->inQueueHead, 1); - statePtr->inQueueHead = NULL; - statePtr->inQueueTail = NULL; - } + if ((statePtr->inQueueHead != NULL) + && (statePtr->inQueueHead->nextPtr == NULL) + && (statePtr->inQueueHead->nextAdded == + statePtr->inQueueHead->nextRemoved)) { + RecycleBuffer(statePtr, statePtr->inQueueHead, 1); + statePtr->inQueueHead = NULL; + statePtr->inQueueTail = NULL; } /* @@ -7145,7 +7168,8 @@ CleanupChannelHandlers( Tcl_Interp *interp, Channel *chanPtr) { - ChannelState *statePtr = chanPtr->state; /* state info for channel */ + ChannelState *statePtr = chanPtr->state; + /* State info for channel */ EventScriptRecord *sPtr, *prevPtr, *nextPtr; /* @@ -7200,7 +7224,8 @@ Tcl_NotifyChannel( * which events were detected. */ { Channel *chanPtr = (Channel *) channel; - ChannelState *statePtr = chanPtr->state; /* state info for channel */ + ChannelState *statePtr = chanPtr->state; + /* State info for channel */ ChannelHandler *chPtr; ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); NextChannelHandler nh; @@ -7346,7 +7371,8 @@ static void UpdateInterest( Channel *chanPtr) /* Channel to update. */ { - ChannelState *statePtr = chanPtr->state; /* state info for channel */ + ChannelState *statePtr = chanPtr->state; + /* State info for channel */ int mask = statePtr->interestMask; /* @@ -7443,7 +7469,8 @@ ChannelTimerProc( ClientData clientData) { Channel *chanPtr = (Channel *) clientData; - ChannelState *statePtr = chanPtr->state; /* state info for channel */ + ChannelState *statePtr = chanPtr->state; + /* State info for channel */ if (!(statePtr->flags & CHANNEL_NEED_MORE_DATA) && (statePtr->interestMask & TCL_READABLE) @@ -7522,7 +7549,8 @@ Tcl_CreateChannelHandler( { ChannelHandler *chPtr; Channel *chanPtr = (Channel *) chan; - ChannelState *statePtr = chanPtr->state; /* state info for channel */ + ChannelState *statePtr = chanPtr->state; + /* State info for channel */ /* * Check whether this channel handler is not already registered. If it is @@ -7595,7 +7623,8 @@ Tcl_DeleteChannelHandler( ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); ChannelHandler *chPtr, *prevChPtr; Channel *chanPtr = (Channel *) chan; - ChannelState *statePtr = chanPtr->state; /* state info for channel */ + ChannelState *statePtr = chanPtr->state; + /* State info for channel */ NextChannelHandler *nhPtr; /* @@ -7681,7 +7710,8 @@ DeleteScriptRecord( int mask) /* Events in mask must exactly match mask of * script to delete. */ { - ChannelState *statePtr = chanPtr->state; /* state info for channel */ + ChannelState *statePtr = chanPtr->state; + /* State info for channel */ EventScriptRecord *esPtr, *prevEsPtr; for (esPtr = statePtr->scriptRecordPtr, prevEsPtr = NULL; esPtr != NULL; @@ -7730,7 +7760,8 @@ CreateScriptRecord( * invoked. */ Tcl_Obj *scriptPtr) /* Pointer to script object. */ { - ChannelState *statePtr = chanPtr->state; /* state info for channel */ + ChannelState *statePtr = chanPtr->state; + /* State info for channel */ EventScriptRecord *esPtr; for (esPtr=statePtr->scriptRecordPtr; esPtr!=NULL; esPtr=esPtr->nextPtr) { @@ -7844,7 +7875,7 @@ Tcl_FileEventObjCmd( Tcl_Obj *CONST objv[]) /* Argument objects. */ { Channel *chanPtr; /* The channel to create the handler for. */ - ChannelState *statePtr; /* state info for channel */ + ChannelState *statePtr; /* State info for channel */ Tcl_Channel chan; /* The opaque type for the channel. */ char *chanName; int modeIndex; /* Index of mode argument. */ @@ -7862,7 +7893,7 @@ Tcl_FileEventObjCmd( } mask = maskArray[modeIndex]; - chanName = Tcl_GetString(objv[1]); + chanName = TclGetString(objv[1]); chan = Tcl_GetChannel(interp, chanName, NULL); if (chan == (Tcl_Channel) NULL) { return TCL_ERROR; @@ -7895,7 +7926,7 @@ Tcl_FileEventObjCmd( * If we are supposed to delete a stored script, do so. */ - if (*(Tcl_GetString(objv[3])) == '\0') { + if (*(TclGetString(objv[3])) == '\0') { DeleteScriptRecord(interp, chanPtr, mask); return TCL_OK; } @@ -8048,15 +8079,14 @@ CopyData( int mask) /* Current channel event flags. */ { Tcl_Interp *interp; - Tcl_Obj *cmdPtr, *errObj = NULL, *bufObj = NULL; - Tcl_Obj* msg = NULL; + Tcl_Obj *cmdPtr, *errObj = NULL, *bufObj = NULL, *msg = NULL; Tcl_Channel inChan, outChan; ChannelState *inStatePtr, *outStatePtr; int result = TCL_OK, size, total, sizeb; char *buffer; - - int inBinary, outBinary, sameEncoding; /* Encoding control */ - int underflow; /* input underflow */ + int inBinary, outBinary, sameEncoding; + /* Encoding control */ + int underflow; /* Input underflow */ inChan = (Tcl_Channel) csPtr->readPtr; outChan = (Tcl_Channel) csPtr->writePtr; @@ -8113,9 +8143,10 @@ CopyData( if (inBinary || sameEncoding) { size = DoRead(inStatePtr->topChanPtr, csPtr->buffer, sizeb); } else { - size = DoReadChars(inStatePtr->topChanPtr, bufObj, sizeb, 0 /* No append */); + size = DoReadChars(inStatePtr->topChanPtr, bufObj, sizeb, + 0 /* No append */); } - underflow = (size >= 0) && (size < sizeb); /* input underflow */ + underflow = (size >= 0) && (size < sizeb); /* Input underflow */ if (size < 0) { readError: @@ -8173,9 +8204,13 @@ CopyData( } if (inBinary || sameEncoding) { - /* Both read and write counted bytes */ + /* + * Both read and write counted bytes. + */ + size = sizeb; - } /* else : Read counted characters, write counted bytes, i.e. size != sizeb */ + } /* else: Read counted characters, write counted bytes, i.e. + * size != sizeb */ if (sizeb < 0) { writeError: @@ -8329,7 +8364,8 @@ DoRead( char *bufPtr, /* Where to store input read. */ int toRead) /* Maximum number of bytes to read. */ { - ChannelState *statePtr = chanPtr->state; /* state info for channel */ + 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 @@ -8358,7 +8394,7 @@ DoRead( if (statePtr->flags & CHANNEL_NONBLOCKING) { goto done; } - statePtr->flags &= (~(CHANNEL_BLOCKED)); + statePtr->flags &= ~CHANNEL_BLOCKED; } result = GetInput(chanPtr); if (result != 0) { @@ -8370,7 +8406,7 @@ DoRead( } } - statePtr->flags &= (~(CHANNEL_BLOCKED)); + statePtr->flags &= ~CHANNEL_BLOCKED; /* * Update the notifier state so we don't block while there is still data @@ -8443,8 +8479,7 @@ CopyAndTranslateBuffer( if (bytesInBuffer < space) { space = bytesInBuffer; } - memcpy((VOID *) result, (VOID *) (bufPtr->buf + bufPtr->nextRemoved), - (size_t) space); + memcpy(result, bufPtr->buf + bufPtr->nextRemoved, (size_t) space); bufPtr->nextRemoved += space; copied = space; break; @@ -8463,8 +8498,7 @@ CopyAndTranslateBuffer( if (bytesInBuffer < space) { space = bytesInBuffer; } - memcpy((VOID *) result, (VOID *) (bufPtr->buf + bufPtr->nextRemoved), - (size_t) space); + memcpy(result, bufPtr->buf + bufPtr->nextRemoved, (size_t) space); bufPtr->nextRemoved += space; copied = space; @@ -8494,15 +8528,14 @@ CopyAndTranslateBuffer( } /* - * Copy the current chunk and replace "\r\n" with "\n" - * (but not standalone "\r"!). + * Copy the current chunk and replace "\r\n" with "\n" (but not + * standalone "\r"!). */ if (bytesInBuffer < space) { space = bytesInBuffer; } - memcpy((VOID *) result, (VOID *) (bufPtr->buf + bufPtr->nextRemoved), - (size_t) space); + memcpy(result, bufPtr->buf + bufPtr->nextRemoved, (size_t) space); bufPtr->nextRemoved += space; copied = space; @@ -8542,8 +8575,7 @@ CopyAndTranslateBuffer( if (bytesInBuffer < space) { space = bytesInBuffer; } - memcpy((VOID *) result, (VOID *) (bufPtr->buf + bufPtr->nextRemoved), - (size_t) space); + memcpy(result, bufPtr->buf + bufPtr->nextRemoved, (size_t) space); bufPtr->nextRemoved += space; copied = space; @@ -8584,7 +8616,7 @@ CopyAndTranslateBuffer( * caller. */ - statePtr->flags |= (CHANNEL_EOF | CHANNEL_STICKY_EOF); + statePtr->flags |= CHANNEL_EOF | CHANNEL_STICKY_EOF; statePtr->inputEncodingFlags |= TCL_ENCODING_END; copied = i; break; @@ -8674,8 +8706,7 @@ CopyBuffer( space = bytesInBuffer; } - memcpy((VOID *) result, (VOID *) (bufPtr->buf + bufPtr->nextRemoved), - (size_t) space); + memcpy(result, bufPtr->buf + bufPtr->nextRemoved, (size_t) space); bufPtr->nextRemoved += space; copied = space; @@ -8731,7 +8762,8 @@ DoWrite( CONST char *src, /* Data to write. */ int srcLen) /* Number of bytes to write. */ { - ChannelState *statePtr = chanPtr->state; /* state info for channel */ + ChannelState *statePtr = chanPtr->state; + /* State info for channel */ ChannelBuffer *outBufPtr; /* Current output buffer. */ int foundNewline; /* Did we find a newline in output? */ char *dPtr; @@ -8783,11 +8815,11 @@ DoWrite( switch (statePtr->outputTranslation) { case TCL_TRANSLATE_LF: srcCopied = destCopied; - memcpy((VOID *) destPtr, (VOID *) src, (size_t) destCopied); + memcpy(destPtr, src, (size_t) destCopied); break; case TCL_TRANSLATE_CR: srcCopied = destCopied; - memcpy((VOID *) destPtr, (VOID *) src, (size_t) destCopied); + memcpy(destPtr, src, (size_t) destCopied); for (dPtr = destPtr; dPtr < destPtr + destCopied; dPtr++) { if (*dPtr == '\n') { *dPtr = '\r'; @@ -9021,8 +9053,9 @@ SetBlockMode( int mode) /* One of TCL_MODE_BLOCKING or * TCL_MODE_NONBLOCKING. */ { - ChannelState *statePtr = chanPtr->state; /* state info for channel */ int result = 0; + ChannelState *statePtr = chanPtr->state; + /* State info for channel */ result = StackSetBlockMode(chanPtr, mode); if (result != 0) { @@ -9055,7 +9088,7 @@ SetBlockMode( return TCL_ERROR; } if (mode == TCL_MODE_BLOCKING) { - statePtr->flags &= (~(CHANNEL_NONBLOCKING | BG_FLUSH_SCHEDULED)); + statePtr->flags &= ~(CHANNEL_NONBLOCKING | BG_FLUSH_SCHEDULED); } else { statePtr->flags |= CHANNEL_NONBLOCKING; } @@ -9110,8 +9143,8 @@ Tcl_GetChannelNamesEx( { ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); ChannelState *statePtr; - CONST char *name; /* name for channel */ - Tcl_Obj *resultPtr; /* pointer to result object */ + CONST char *name; /* Name for channel */ + Tcl_Obj *resultPtr; /* Pointer to result object */ Tcl_HashTable *hTblPtr; /* Hash table of channels. */ Tcl_HashEntry *hPtr; /* Search variable. */ Tcl_HashSearch hSearch; /* Search variable. */ @@ -9205,7 +9238,7 @@ Tcl_IsChannelRegistered( chanPtr = ((Channel *) chan)->state->bottomChanPtr; statePtr = chanPtr->state; - hTblPtr = (Tcl_HashTable *) Tcl_GetAssocData(interp, "tclIO", NULL); + hTblPtr = Tcl_GetAssocData(interp, "tclIO", NULL); if (hTblPtr == NULL) { return 0; } @@ -9336,7 +9369,8 @@ Tcl_ChannelName( Tcl_ChannelTypeVersion Tcl_ChannelVersion( - Tcl_ChannelType *chanTypePtr) /* Pointer to channel type. */ + Tcl_ChannelType *chanTypePtr) + /* Pointer to channel type. */ { if (chanTypePtr->version == TCL_CHANNEL_VERSION_2) { return TCL_CHANNEL_VERSION_2; @@ -9400,7 +9434,8 @@ HaveVersion( Tcl_DriverBlockModeProc * Tcl_ChannelBlockModeProc( - Tcl_ChannelType *chanTypePtr) /* Pointer to channel type. */ + Tcl_ChannelType *chanTypePtr) + /* Pointer to channel type. */ { if (HaveVersion(chanTypePtr, TCL_CHANNEL_VERSION_2)) { return chanTypePtr->blockModeProc; @@ -9431,7 +9466,8 @@ Tcl_ChannelBlockModeProc( Tcl_DriverCloseProc * Tcl_ChannelCloseProc( - Tcl_ChannelType *chanTypePtr) /* Pointer to channel type. */ + Tcl_ChannelType *chanTypePtr) + /* Pointer to channel type. */ { return chanTypePtr->closeProc; } @@ -9454,7 +9490,8 @@ Tcl_ChannelCloseProc( Tcl_DriverClose2Proc * Tcl_ChannelClose2Proc( - Tcl_ChannelType *chanTypePtr) /* Pointer to channel type. */ + Tcl_ChannelType *chanTypePtr) + /* Pointer to channel type. */ { return chanTypePtr->close2Proc; } @@ -9477,7 +9514,8 @@ Tcl_ChannelClose2Proc( Tcl_DriverInputProc * Tcl_ChannelInputProc( - Tcl_ChannelType *chanTypePtr) /* Pointer to channel type. */ + Tcl_ChannelType *chanTypePtr) + /* Pointer to channel type. */ { return chanTypePtr->inputProc; } @@ -9500,7 +9538,8 @@ Tcl_ChannelInputProc( Tcl_DriverOutputProc * Tcl_ChannelOutputProc( - Tcl_ChannelType *chanTypePtr) /* Pointer to channel type. */ + Tcl_ChannelType *chanTypePtr) + /* Pointer to channel type. */ { return chanTypePtr->outputProc; } @@ -9523,7 +9562,8 @@ Tcl_ChannelOutputProc( Tcl_DriverSeekProc * Tcl_ChannelSeekProc( - Tcl_ChannelType *chanTypePtr) /* Pointer to channel type. */ + Tcl_ChannelType *chanTypePtr) + /* Pointer to channel type. */ { return chanTypePtr->seekProc; } @@ -9546,7 +9586,8 @@ Tcl_ChannelSeekProc( Tcl_DriverSetOptionProc * Tcl_ChannelSetOptionProc( - Tcl_ChannelType *chanTypePtr) /* Pointer to channel type. */ + Tcl_ChannelType *chanTypePtr) + /* Pointer to channel type. */ { return chanTypePtr->setOptionProc; } @@ -9569,7 +9610,8 @@ Tcl_ChannelSetOptionProc( Tcl_DriverGetOptionProc * Tcl_ChannelGetOptionProc( - Tcl_ChannelType *chanTypePtr) /* Pointer to channel type. */ + Tcl_ChannelType *chanTypePtr) + /* Pointer to channel type. */ { return chanTypePtr->getOptionProc; } @@ -9592,7 +9634,8 @@ Tcl_ChannelGetOptionProc( Tcl_DriverWatchProc * Tcl_ChannelWatchProc( - Tcl_ChannelType *chanTypePtr) /* Pointer to channel type. */ + Tcl_ChannelType *chanTypePtr) + /* Pointer to channel type. */ { return chanTypePtr->watchProc; } @@ -9615,7 +9658,8 @@ Tcl_ChannelWatchProc( Tcl_DriverGetHandleProc * Tcl_ChannelGetHandleProc( - Tcl_ChannelType *chanTypePtr) /* Pointer to channel type. */ + Tcl_ChannelType *chanTypePtr) + /* Pointer to channel type. */ { return chanTypePtr->getHandleProc; } @@ -9638,7 +9682,8 @@ Tcl_ChannelGetHandleProc( Tcl_DriverFlushProc * Tcl_ChannelFlushProc( - Tcl_ChannelType *chanTypePtr) /* Pointer to channel type. */ + Tcl_ChannelType *chanTypePtr) + /* Pointer to channel type. */ { if (HaveVersion(chanTypePtr, TCL_CHANNEL_VERSION_2)) { return chanTypePtr->flushProc; @@ -9665,7 +9710,8 @@ Tcl_ChannelFlushProc( Tcl_DriverHandlerProc * Tcl_ChannelHandlerProc( - Tcl_ChannelType *chanTypePtr) /* Pointer to channel type. */ + Tcl_ChannelType *chanTypePtr) + /* Pointer to channel type. */ { if (HaveVersion(chanTypePtr, TCL_CHANNEL_VERSION_2)) { return chanTypePtr->handlerProc; @@ -9692,7 +9738,8 @@ Tcl_ChannelHandlerProc( Tcl_DriverWideSeekProc * Tcl_ChannelWideSeekProc( - Tcl_ChannelType *chanTypePtr) /* Pointer to channel type. */ + Tcl_ChannelType *chanTypePtr) + /* Pointer to channel type. */ { if (HaveVersion(chanTypePtr, TCL_CHANNEL_VERSION_3)) { return chanTypePtr->wideSeekProc; @@ -9720,7 +9767,8 @@ Tcl_ChannelWideSeekProc( Tcl_DriverThreadActionProc * Tcl_ChannelThreadActionProc( - Tcl_ChannelType *chanTypePtr) /* Pointer to channel type. */ + Tcl_ChannelType *chanTypePtr) + /* Pointer to channel type. */ { if (HaveVersion(chanTypePtr, TCL_CHANNEL_VERSION_4)) { return chanTypePtr->threadActionProc; @@ -9754,7 +9802,7 @@ Tcl_SetChannelErrorInterp( Interp *iPtr = (Interp *) interp; if (iPtr->chanMsg != NULL) { - Tcl_DecrRefCount(iPtr->chanMsg); + TclDecrRefCount(iPtr->chanMsg); iPtr->chanMsg = NULL; } @@ -9787,10 +9835,10 @@ Tcl_SetChannelError( Tcl_Channel chan, /* Channel to store the data into. */ Tcl_Obj *msg) /* Error message to store. */ { - ChannelState* statePtr = ((Channel*) chan)->state; + ChannelState *statePtr = ((Channel *) chan)->state; if (statePtr->chanMsg != NULL) { - Tcl_DecrRefCount(statePtr->chanMsg); + TclDecrRefCount(statePtr->chanMsg); statePtr->chanMsg = NULL; } @@ -9824,15 +9872,10 @@ static Tcl_Obj * FixLevelCode( Tcl_Obj *msg) { - int lc; - Tcl_Obj **lv; - int explicitResult; - int numOptions; - int lcn; - Tcl_Obj **lvn; + int explicitResult, numOptions, lc, lcn; + Tcl_Obj **lv, **lvn; int res, i, j, val, lignore, cignore; - Tcl_Obj *newlevel = NULL; - Tcl_Obj *newcode = NULL; + Tcl_Obj *newlevel = NULL, *newcode = NULL; /* ASSERT msg != NULL */ @@ -9841,9 +9884,9 @@ FixLevelCode( * * Syntax = (option value)... ?message? * - * Bad syntax causes a panic. Because the other side uses + * Bad message syntax causes a panic, because the other side uses * Tcl_GetReturnOptions and list construction functions to marshall the - * information. + * information. Hence an error means that we've got serious breakage. */ res = Tcl_ListObjGetElements(NULL, msg, &lc, &lv); @@ -10034,7 +10077,8 @@ Tcl_GetChannelError( Tcl_DriverTruncateProc * Tcl_ChannelTruncateProc( - Tcl_ChannelType *chanTypePtr) /* Pointer to channel type. */ + Tcl_ChannelType *chanTypePtr) + /* Pointer to channel type. */ { if (HaveVersion(chanTypePtr, TCL_CHANNEL_VERSION_5)) { return chanTypePtr->truncateProc; diff --git a/generic/tclPkg.c b/generic/tclPkg.c index 0814677..7e148d1 100644 --- a/generic/tclPkg.c +++ b/generic/tclPkg.c @@ -10,7 +10,7 @@ * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tclPkg.c,v 1.23 2006/11/02 15:58:08 dgp Exp $ + * RCS: @(#) $Id: tclPkg.c,v 1.24 2006/11/08 11:41:44 dkf Exp $ * * TIP #268. * Heavily rewritten to handle the extend version numbers, and extended @@ -55,25 +55,37 @@ typedef struct Package { * Prototypes for functions defined in this file: */ -static int CheckVersionAndConvert(Tcl_Interp *interp, CONST char *string, - char** internal, int* stable); - +static int CheckVersionAndConvert(Tcl_Interp *interp, + CONST char *string, char **internal, int *stable); static int CompareVersions(char *v1i, char *v2i, - int *isMajorPtr); -static int CheckRequirement(Tcl_Interp *interp, CONST char *string); -static int CheckAllRequirements(Tcl_Interp* interp, - int reqc, Tcl_Obj *CONST reqv[]); + int *isMajorPtr); +static int CheckRequirement(Tcl_Interp *interp, + CONST char *string); +static int CheckAllRequirements(Tcl_Interp *interp, int reqc, + Tcl_Obj *CONST reqv[]); static int RequirementSatisfied(char *havei, CONST char *req); -static int AllRequirementsSatisfied(char *havei, - int reqc, Tcl_Obj *CONST reqv[]); -static void AddRequirementsToResult(Tcl_Interp* interp, - int reqc, Tcl_Obj *CONST reqv[]); -static void AddRequirementsToDString(Tcl_DString* dstring, - int reqc, Tcl_Obj *CONST reqv[]); +static int AllRequirementsSatisfied(char *havei, int reqc, + Tcl_Obj *CONST reqv[]); +static void AddRequirementsToResult(Tcl_Interp *interp, int reqc, + Tcl_Obj *CONST reqv[]); +static void AddRequirementsToDString(Tcl_DString *dstring, + int reqc, Tcl_Obj *CONST reqv[]); static Package * FindPackage(Tcl_Interp *interp, CONST char *name); -static Tcl_Obj* ExactRequirement(CONST char* version); +static Tcl_Obj * ExactRequirement(CONST char *version); static void VersionCleanupProc(ClientData clientData, Tcl_Interp *interp); + +/* + * Helper macros. + */ + +#define DupBlock(v,s,len) \ + ((v) = ckalloc(len), memcpy((v),(s),(len))) +#define DupString(v,s) \ + do { \ + unsigned local__len = (unsigned) (strlen(s) + 1); \ + DupBlock((v),(s),local__len); \ + } while (0) /* *---------------------------------------------------------------------- @@ -103,7 +115,7 @@ Tcl_PkgProvide( CONST char *name, /* Name of package. */ CONST char *version) /* Version string for package. */ { - return Tcl_PkgProvideEx(interp, name, version, (ClientData) NULL); + return Tcl_PkgProvideEx(interp, name, version, NULL); } int @@ -116,28 +128,27 @@ Tcl_PkgProvideEx( * for C callback function table) */ { Package *pkgPtr; - char* pvi; - char* vi; + char *pvi, *vi; int res; pkgPtr = FindPackage(interp, name); if (pkgPtr->version == NULL) { - pkgPtr->version = ckalloc((unsigned) (strlen(version) + 1)); - strcpy(pkgPtr->version, version); + DupString(pkgPtr->version, version); pkgPtr->clientData = clientData; return TCL_OK; } - if (CheckVersionAndConvert (interp, pkgPtr->version, &pvi, NULL) != TCL_OK) { + if (CheckVersionAndConvert(interp, pkgPtr->version, &pvi, + NULL) != TCL_OK) { return TCL_ERROR; - } else if (CheckVersionAndConvert (interp, version, &vi, NULL) != TCL_OK) { - Tcl_Free (pvi); + } else if (CheckVersionAndConvert(interp, version, &vi, NULL) != TCL_OK) { + ckfree(pvi); return TCL_ERROR; } res = CompareVersions(pvi, vi, NULL); - Tcl_Free (pvi); - Tcl_Free (vi); + ckfree(pvi); + ckfree(vi); if (res == 0) { if (clientData != NULL) { @@ -286,21 +297,22 @@ Tcl_PkgRequireEx( res = Tcl_PkgRequireProc(interp, name, 0, NULL, clientDataPtr); } else { if (exact) { - ov = ExactRequirement (version); + ov = ExactRequirement(version); } else { - ov = Tcl_NewStringObj (version,-1); + ov = Tcl_NewStringObj(version, -1); } - Tcl_IncrRefCount (ov); + Tcl_IncrRefCount(ov); res = Tcl_PkgRequireProc(interp, name, 1, &ov, clientDataPtr); - Tcl_DecrRefCount (ov); + TclDecrRefCount(ov); } if (res != TCL_OK) { return NULL; } - /* This function returns the version string explictly, and leaves the + /* + * This function returns the version string explictly, and leaves the * interpreter result empty. However "Tcl_PkgRequireProc" above returned * the version through the interpreter result. Simply resetting the result * now potentially deletes the string (obj), and the pointer to its string @@ -310,22 +322,21 @@ Tcl_PkgRequireEx( * dangle. It will be a leak however if nothing is done. So the next time * we come through here we delete the object remembered by this call, as * we can then be sure that there is no pointer to its string around - * anymore. Beyond that we have a deletion function which cleans up the last - * remembered object which was not cleaned up directly, here. + * anymore. Beyond that we have a deletion function which cleans up the + * last remembered object which was not cleaned up directly, here. */ - ov = (Tcl_Obj*) Tcl_GetAssocData (interp, "tcl/Tcl_PkgRequireEx", NULL); + ov = (Tcl_Obj *) Tcl_GetAssocData(interp, "tcl/Tcl_PkgRequireEx", NULL); if (ov != NULL) { - Tcl_DecrRefCount (ov); + TclDecrRefCount(ov); } - ov = Tcl_GetObjResult (interp); - Tcl_IncrRefCount (ov); - Tcl_SetAssocData(interp, "tcl/Tcl_PkgRequireEx", VersionCleanupProc, - (ClientData) ov); - Tcl_ResetResult (interp); + ov = Tcl_GetObjResult(interp); + Tcl_IncrRefCount(ov); + Tcl_SetAssocData(interp, "tcl/Tcl_PkgRequireEx", VersionCleanupProc, ov); + Tcl_ResetResult(interp); - return Tcl_GetString (ov); + return TclGetString(ov); } int @@ -333,19 +344,22 @@ Tcl_PkgRequireProc( Tcl_Interp *interp, /* Interpreter in which package is now * available. */ CONST char *name, /* Name of desired package. */ - int reqc, /* Requirements constraining the desired version. */ - Tcl_Obj *CONST reqv[], /* 0 means to use the latest version available. */ + int reqc, /* Requirements constraining the desired + * version. */ + Tcl_Obj *CONST reqv[], /* 0 means to use the latest version + * available. */ ClientData *clientDataPtr) { Interp *iPtr = (Interp *) interp; Package *pkgPtr; - PkgAvail *availPtr, *bestPtr, *bestStablePtr; - char *availVersion, *bestVersion; /* Internal rep. of versions */ - int availStable; + PkgAvail *availPtr, *bestPtr, *bestStablePtr; + char *availVersion, *bestVersion; + /* Internal rep. of versions */ + int availStable; char *script; int code, satisfies, pass; Tcl_DString command; - char* pkgVersionI; + char *pkgVersionI; /* * It can take up to three passes to find the package: one pass to run the @@ -354,7 +368,7 @@ Tcl_PkgRequireProc( * the "package ifneeded" script. */ - for (pass = 1; ; pass++) { + for (pass=1 ;; pass++) { pkgPtr = FindPackage(interp, name); if (pkgPtr->version != NULL) { break; @@ -368,28 +382,28 @@ Tcl_PkgRequireProc( if (pkgPtr->clientData != NULL) { Tcl_AppendResult(interp, "circular package dependency: ", "attempt to provide ", name, " ", - (char *)(pkgPtr->clientData), " requires ", name, NULL); - AddRequirementsToResult (interp, reqc, reqv); + (char *) pkgPtr->clientData, " requires ", name, NULL); + AddRequirementsToResult(interp, reqc, reqv); return TCL_ERROR; } /* * The package isn't yet present. Search the list of available - * versions and invoke the script for the best available version. - * We are actually locating the best, and the best stable version. - * One of them is then chosen based on the selection mode. + * versions and invoke the script for the best available version. We + * are actually locating the best, and the best stable version. One of + * them is then chosen based on the selection mode. */ - bestPtr = NULL; - bestStablePtr = NULL; - bestVersion = NULL; + bestPtr = NULL; + bestStablePtr = NULL; + bestVersion = NULL; - for (availPtr = pkgPtr->availPtr; - availPtr != NULL; - availPtr = availPtr->nextPtr) { - if (CheckVersionAndConvert (interp, availPtr->version, - &availVersion, &availStable) != TCL_OK) { - /* The provided version number is has invalid syntax. This + for (availPtr = pkgPtr->availPtr; availPtr != NULL; + availPtr = availPtr->nextPtr) { + if (CheckVersionAndConvert(interp, availPtr->version, + &availVersion, &availStable) != TCL_OK) { + /* + * The provided version number is has invalid syntax. This * should not happen. This should have been caught by the * 'package ifneeded' registering the package. */ @@ -398,24 +412,33 @@ Tcl_PkgRequireProc( } if (bestPtr != NULL) { - int res = CompareVersions (availVersion, bestVersion, NULL); + int res = CompareVersions(availVersion, bestVersion, NULL); + /* Note: Use internal reps! */ if (res <= 0) { - /* The version of the package sought is not as good as the - * currently selected version. Ignore it. */ - Tcl_Free (availVersion); + /* + * The version of the package sought is not as good as the + * currently selected version. Ignore it. + */ + + ckfree(availVersion); availVersion = NULL; continue; } } - /* We have found a version which is better than our max. */ + /* + * We have found a version which is better than our max. + */ if (reqc > 0) { - /* Check satisfaction of requirements */ - satisfies = AllRequirementsSatisfied (availVersion, reqc, reqv); + /* + * Check satisfaction of requirements. + */ + + satisfies = AllRequirementsSatisfied(availVersion,reqc,reqv); if (!satisfies) { - Tcl_Free (availVersion); + ckfree(availVersion); availVersion = NULL; continue; } @@ -423,10 +446,13 @@ Tcl_PkgRequireProc( bestPtr = availPtr; - if (bestVersion != NULL) Tcl_Free (bestVersion); + if (bestVersion != NULL) { + ckfree(bestVersion); + } bestVersion = availVersion; - /* If this new best version is stable then it also has to be + /* + * If this new best version is stable then it also has to be * better than the max stable version found so far. */ @@ -436,15 +462,17 @@ Tcl_PkgRequireProc( } if (bestVersion != NULL) { - Tcl_Free (bestVersion); + ckfree(bestVersion); } - /* Now choose a version among the two best. For 'latest' we simply + /* + * Now choose a version among the two best. For 'latest' we simply * take (actually keep) the best. For 'stable' we take the best * stable, if there is any, or the best if there is nothing stable. */ - if ((iPtr->packagePrefer == PKG_PREFER_STABLE) && (bestStablePtr != NULL)) { + if ((iPtr->packagePrefer == PKG_PREFER_STABLE) + && (bestStablePtr != NULL)) { bestPtr = bestStablePtr; } @@ -455,6 +483,7 @@ Tcl_PkgRequireProc( * script itself from deletion and (b) don't assume that bestPtr * will still exist when the script completes. */ + CONST char *versionToProvide = bestPtr->version; script = bestPtr->script; @@ -474,26 +503,28 @@ Tcl_PkgRequireProc( " failed: no version of package ", name, " provided", NULL); } else { - char* pvi; - char* vi; + char *pvi, *vi; int res; - if (CheckVersionAndConvert (interp, pkgPtr->version, &pvi, NULL) != TCL_OK) { + if (CheckVersionAndConvert(interp, pkgPtr->version, &pvi, + NULL) != TCL_OK) { code = TCL_ERROR; - } else if (CheckVersionAndConvert (interp, versionToProvide, &vi, NULL) != TCL_OK) { - Tcl_Free (pvi); + } else if (CheckVersionAndConvert(interp, + versionToProvide, &vi, NULL) != TCL_OK) { + ckfree(pvi); code = TCL_ERROR; } else { res = CompareVersions(pvi, vi, NULL); - Tcl_Free (pvi); - Tcl_Free (vi); + ckfree(pvi); + ckfree(vi); if (res != 0) { code = TCL_ERROR; - Tcl_AppendResult(interp, "attempt to provide package ", - name, " ", versionToProvide, " failed: package ", - name, " ", pkgPtr->version, " provided instead", - NULL); + Tcl_AppendResult(interp, + "attempt to provide package ", name, " ", + versionToProvide, " failed: package ", + name, " ", pkgPtr->version, + " provided instead", NULL); } } } @@ -502,8 +533,8 @@ Tcl_PkgRequireProc( Tcl_ResetResult(interp); Tcl_AppendResult(interp, "attempt to provide package ", name, " ", versionToProvide, " failed: ", - "bad return code: ", Tcl_GetString(codePtr), NULL); - Tcl_DecrRefCount(codePtr); + "bad return code: ", TclGetString(codePtr), NULL); + TclDecrRefCount(codePtr); code = TCL_ERROR; } @@ -516,16 +547,16 @@ Tcl_PkgRequireProc( if (code != TCL_OK) { /* - * Take a non-TCL_OK code from the script as an - * indication the package wasn't loaded properly, - * so the package system should not remember an - * improper load. + * Take a non-TCL_OK code from the script as an indication the + * package wasn't loaded properly, so the package system + * should not remember an improper load. * - * This is consistent with our returning NULL. - * If we're not willing to tell our caller we - * got a particular version, we shouldn't store - * that version for telling future callers either. + * This is consistent with our returning NULL. If we're not + * willing to tell our caller we got a particular version, we + * shouldn't store that version for telling future callers + * either. */ + if (pkgPtr->version != NULL) { ckfree(pkgPtr->version); pkgPtr->version = NULL; @@ -562,12 +593,13 @@ Tcl_PkgRequireProc( Tcl_Obj *codePtr = Tcl_NewIntObj(code); Tcl_ResetResult(interp); Tcl_AppendResult(interp, "bad return code: ", - Tcl_GetString(codePtr), NULL); + TclGetString(codePtr), NULL); Tcl_DecrRefCount(codePtr); code = TCL_ERROR; } if (code == TCL_ERROR) { - Tcl_AddErrorInfo(interp, "\n (\"package unknown\" script)"); + Tcl_AddErrorInfo(interp, + "\n (\"package unknown\" script)"); return TCL_ERROR; } Tcl_ResetResult(interp); @@ -588,23 +620,23 @@ Tcl_PkgRequireProc( if (reqc == 0) { satisfies = 1; } else { - CheckVersionAndConvert (interp, pkgPtr->version, &pkgVersionI, NULL); - satisfies = AllRequirementsSatisfied (pkgVersionI, reqc, reqv); + CheckVersionAndConvert(interp, pkgPtr->version, &pkgVersionI, NULL); + satisfies = AllRequirementsSatisfied(pkgVersionI, reqc, reqv); - Tcl_Free (pkgVersionI); + ckfree(pkgVersionI); } if (satisfies) { if (clientDataPtr) { *clientDataPtr = pkgPtr->clientData; } - Tcl_SetObjResult (interp, Tcl_NewStringObj (pkgPtr->version, -1)); + Tcl_SetObjResult(interp, Tcl_NewStringObj(pkgPtr->version, -1)); return TCL_OK; } - Tcl_AppendResult(interp, "version conflict for package \"", - name, "\": have ", pkgPtr->version, ", need", NULL); - AddRequirementsToResult (interp, reqc, reqv); + Tcl_AppendResult(interp, "version conflict for package \"", name, + "\": have ", pkgPtr->version, ", need", NULL); + AddRequirementsToResult(interp, reqc, reqv); return TCL_ERROR; } @@ -665,10 +697,9 @@ Tcl_PkgPresentEx( hPtr = Tcl_FindHashEntry(&iPtr->packageTable, name); if (hPtr) { - pkgPtr = (Package *) Tcl_GetHashValue(hPtr); + pkgPtr = Tcl_GetHashValue(hPtr); if (pkgPtr->version != NULL) { - char* pvi; - char* vi; + char *pvi, *vi; int thisIsMajor; /* @@ -684,16 +715,18 @@ Tcl_PkgPresentEx( return pkgPtr->version; } - if (CheckVersionAndConvert (interp, pkgPtr->version, &pvi, NULL) != TCL_OK) { + if (CheckVersionAndConvert(interp, pkgPtr->version, &pvi, + NULL) != TCL_OK) { return NULL; - } else if (CheckVersionAndConvert (interp, version, &vi, NULL) != TCL_OK) { - Tcl_Free (pvi); + } else if (CheckVersionAndConvert(interp, version, &vi, + NULL) != TCL_OK) { + ckfree(pvi); return NULL; } result = CompareVersions(pvi, vi, &thisIsMajor); - Tcl_Free (pvi); - Tcl_Free (vi); + ckfree(pvi); + ckfree(vi); satisfies = (result == 0) || ((result == 1) && !thisIsMajor); @@ -762,9 +795,7 @@ Tcl_PackageObjCmd( Tcl_HashSearch search; Tcl_HashTable *tablePtr; CONST char *version; - char *argv2, *argv3, *argv4; - char* iva = NULL; - char* ivb = NULL; + char *argv2, *argv3, *argv4, *iva = NULL, *ivb = NULL; if (objc < 2) { Tcl_WrongNumArgs(interp, 1, objv, "option ?arg arg ...?"); @@ -780,12 +811,12 @@ Tcl_PackageObjCmd( char *keyString; for (i = 2; i < objc; i++) { - keyString = Tcl_GetString(objv[i]); + keyString = TclGetString(objv[i]); hPtr = Tcl_FindHashEntry(&iPtr->packageTable, keyString); if (hPtr == NULL) { continue; } - pkgPtr = (Package *) Tcl_GetHashValue(hPtr); + pkgPtr = Tcl_GetHashValue(hPtr); Tcl_DeleteHashEntry(hPtr); if (pkgPtr->version != NULL) { ckfree(pkgPtr->version); @@ -802,47 +833,45 @@ Tcl_PackageObjCmd( break; } case PKG_IFNEEDED: { - int length; - char* argv3i; - char* avi; - int res; + int length, res; + char *argv3i, *avi; if ((objc != 4) && (objc != 5)) { Tcl_WrongNumArgs(interp, 2, objv, "package version ?script?"); return TCL_ERROR; } - argv3 = Tcl_GetString(objv[3]); + argv3 = TclGetString(objv[3]); if (CheckVersionAndConvert(interp, argv3, &argv3i, NULL) != TCL_OK) { return TCL_ERROR; } - argv2 = Tcl_GetString(objv[2]); + argv2 = TclGetString(objv[2]); if (objc == 4) { hPtr = Tcl_FindHashEntry(&iPtr->packageTable, argv2); if (hPtr == NULL) { - Tcl_Free (argv3i); + ckfree(argv3i); return TCL_OK; } - pkgPtr = (Package *) Tcl_GetHashValue(hPtr); + pkgPtr = Tcl_GetHashValue(hPtr); } else { pkgPtr = FindPackage(interp, argv2); } argv3 = Tcl_GetStringFromObj(objv[3], &length); - for (availPtr = pkgPtr->availPtr, prevPtr = NULL; - availPtr != NULL; - prevPtr = availPtr, availPtr = availPtr->nextPtr) { + for (availPtr = pkgPtr->availPtr, prevPtr = NULL; availPtr != NULL; + prevPtr = availPtr, availPtr = availPtr->nextPtr) { - if (CheckVersionAndConvert (interp, availPtr->version, &avi, NULL) != TCL_OK) { - Tcl_Free (argv3i); + if (CheckVersionAndConvert(interp, availPtr->version, &avi, + NULL) != TCL_OK) { + ckfree(argv3i); return TCL_ERROR; } res = CompareVersions(avi, argv3i, NULL); - Tcl_Free (avi); + ckfree(avi); if (res == 0){ if (objc == 4) { - Tcl_Free (argv3i); + ckfree(argv3i); Tcl_SetResult(interp, availPtr->script, TCL_VOLATILE); return TCL_OK; } @@ -850,15 +879,14 @@ Tcl_PackageObjCmd( break; } } - Tcl_Free (argv3i); + ckfree(argv3i); if (objc == 4) { return TCL_OK; } if (availPtr == NULL) { availPtr = (PkgAvail *) ckalloc(sizeof(PkgAvail)); - availPtr->version = ckalloc((unsigned) (length + 1)); - strcpy(availPtr->version, argv3); + DupBlock(availPtr->version, argv3, (unsigned) length + 1); if (prevPtr == NULL) { availPtr->nextPtr = pkgPtr->availPtr; @@ -869,8 +897,7 @@ Tcl_PackageObjCmd( } } argv4 = Tcl_GetStringFromObj(objv[4], &length); - availPtr->script = ckalloc((unsigned) (length + 1)); - strcpy(availPtr->script, argv4); + DupBlock(availPtr->script, argv4, (unsigned) length + 1); break; } case PKG_NAMES: @@ -881,7 +908,7 @@ Tcl_PackageObjCmd( tablePtr = &iPtr->packageTable; for (hPtr = Tcl_FirstHashEntry(tablePtr, &search); hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) { - pkgPtr = (Package *) Tcl_GetHashValue(hPtr); + pkgPtr = Tcl_GetHashValue(hPtr); if ((pkgPtr->version != NULL) || (pkgPtr->availPtr != NULL)) { Tcl_AppendElement(interp, Tcl_GetHashKey(tablePtr, hPtr)); } @@ -893,7 +920,7 @@ Tcl_PackageObjCmd( Tcl_WrongNumArgs(interp, 2, objv, "?-exact? package ?version?"); return TCL_ERROR; } - argv2 = Tcl_GetString(objv[2]); + argv2 = TclGetString(objv[2]); if ((argv2[0] == '-') && (strcmp(argv2, "-exact") == 0)) { exact = 1; } else { @@ -901,15 +928,16 @@ Tcl_PackageObjCmd( } version = NULL; if (objc == (4 + exact)) { - version = Tcl_GetString(objv[3 + exact]); - if (CheckVersionAndConvert(interp, version, NULL, NULL) != TCL_OK) { + version = TclGetString(objv[3 + exact]); + if (CheckVersionAndConvert(interp, version, NULL, + NULL) != TCL_OK) { return TCL_ERROR; } } else if ((objc != 3) || exact) { goto presentSyntax; } if (exact) { - argv3 = Tcl_GetString(objv[3]); + argv3 = TclGetString(objv[3]); version = Tcl_PkgPresent(interp, argv3, version, exact); } else { version = Tcl_PkgPresent(interp, argv2, version, exact); @@ -917,25 +945,25 @@ Tcl_PackageObjCmd( if (version == NULL) { return TCL_ERROR; } - Tcl_SetObjResult( interp, Tcl_NewStringObj( version, -1 ) ); + Tcl_SetObjResult(interp, Tcl_NewStringObj(version, -1)); break; case PKG_PROVIDE: if ((objc != 3) && (objc != 4)) { Tcl_WrongNumArgs(interp, 2, objv, "package ?version?"); return TCL_ERROR; } - argv2 = Tcl_GetString(objv[2]); + argv2 = TclGetString(objv[2]); if (objc == 3) { hPtr = Tcl_FindHashEntry(&iPtr->packageTable, argv2); if (hPtr != NULL) { - pkgPtr = (Package *) Tcl_GetHashValue(hPtr); + pkgPtr = Tcl_GetHashValue(hPtr); if (pkgPtr->version != NULL) { Tcl_SetResult(interp, pkgPtr->version, TCL_VOLATILE); } } return TCL_OK; } - argv3 = Tcl_GetString(objv[3]); + argv3 = TclGetString(objv[3]); if (CheckVersionAndConvert(interp, argv3, NULL, NULL) != TCL_OK) { return TCL_ERROR; } @@ -943,38 +971,42 @@ Tcl_PackageObjCmd( case PKG_REQUIRE: if (objc < 3) { requireSyntax: - Tcl_WrongNumArgs(interp, 2, objv, "?-exact? package ?requirement...?"); + Tcl_WrongNumArgs(interp, 2, objv, + "?-exact? package ?requirement...?"); return TCL_ERROR; } version = NULL; - argv2 = Tcl_GetString(objv[2]); + argv2 = TclGetString(objv[2]); if ((argv2[0] == '-') && (strcmp(argv2, "-exact") == 0)) { - Tcl_Obj* ov; + Tcl_Obj *ov; int res; if (objc != 5) { goto requireSyntax; } - version = Tcl_GetString(objv[4]); - if (CheckVersionAndConvert(interp, version, NULL, NULL) != TCL_OK) { + version = TclGetString(objv[4]); + if (CheckVersionAndConvert(interp, version, NULL, + NULL) != TCL_OK) { return TCL_ERROR; } - /* Create a new-style requirement for the exact version. */ + /* + * Create a new-style requirement for the exact version. + */ - ov = ExactRequirement (version); + ov = ExactRequirement(version); version = NULL; - argv3 = Tcl_GetString(objv[3]); + argv3 = TclGetString(objv[3]); - Tcl_IncrRefCount (ov); + Tcl_IncrRefCount(ov); res = Tcl_PkgRequireProc(interp, argv3, 1, &ov, NULL); - Tcl_DecrRefCount (ov); + TclDecrRefCount(ov); return res; } else { - if (CheckAllRequirements (interp, objc-3, objv+3) != TCL_OK) { + if (CheckAllRequirements(interp, objc-3, objv+3) != TCL_OK) { return TCL_ERROR; } @@ -996,8 +1028,7 @@ Tcl_PackageObjCmd( if (argv2[0] == 0) { iPtr->packageUnknown = NULL; } else { - iPtr->packageUnknown = (char *) ckalloc((unsigned) (length+1)); - strcpy(iPtr->packageUnknown, argv2); + DupBlock(iPtr->packageUnknown, argv2, (unsigned) length+1); } } else { Tcl_WrongNumArgs(interp, 2, objv, "?command?"); @@ -1006,31 +1037,40 @@ Tcl_PackageObjCmd( break; } case PKG_PREFER: { - /* See tclInt.h for the enum, just before Interp */ static CONST char *pkgPreferOptions[] = { "latest", "stable", NULL }; + /* + * See tclInt.h for the enum, just before Interp. + */ + if (objc > 3) { Tcl_WrongNumArgs(interp, 2, objv, "?latest|stable?"); return TCL_ERROR; - } + } else if (objc == 3) { + /* + * Seting the value. + */ - if (objc == 3) { - /* Set value. */ + int newPref; - int new; - if (Tcl_GetIndexFromObj(interp, objv[2], pkgPreferOptions, "preference", 0, - &new) != TCL_OK) { + if (Tcl_GetIndexFromObj(interp, objv[2], pkgPreferOptions, + "preference", 0, &newPref) != TCL_OK) { return TCL_ERROR; } - if (new < iPtr->packagePrefer) { - iPtr->packagePrefer = new; + if (newPref < iPtr->packagePrefer) { + iPtr->packagePrefer = newPref; } } - /* Always return current value. */ - Tcl_SetObjResult(interp, Tcl_NewStringObj (pkgPreferOptions [iPtr->packagePrefer], -1)); + + /* + * Always return current value. + */ + + Tcl_SetObjResult(interp, + Tcl_NewStringObj(pkgPreferOptions[iPtr->packagePrefer], -1)); break; } case PKG_VCOMPARE: @@ -1038,29 +1078,39 @@ Tcl_PackageObjCmd( Tcl_WrongNumArgs(interp, 2, objv, "version1 version2"); return TCL_ERROR; } - argv3 = Tcl_GetString(objv[3]); - argv2 = Tcl_GetString(objv[2]); - if ((CheckVersionAndConvert (interp, argv2, &iva, NULL) != TCL_OK) || - (CheckVersionAndConvert (interp, argv3, &ivb, NULL) != TCL_OK)) { - if (iva != NULL) { Tcl_Free (iva); } - /* ivb cannot be set in this branch */ + argv3 = TclGetString(objv[3]); + argv2 = TclGetString(objv[2]); + if (CheckVersionAndConvert(interp, argv2, &iva, NULL) != TCL_OK || + CheckVersionAndConvert(interp, argv3, &ivb, NULL) != TCL_OK) { + if (iva != NULL) { + ckfree(iva); + } + + /* + * ivb cannot be set in this branch. + */ + return TCL_ERROR; } - /* Comparison is done on the internal representation */ - Tcl_SetObjResult(interp,Tcl_NewIntObj(CompareVersions(iva, ivb, NULL))); - Tcl_Free (iva); - Tcl_Free (ivb); + /* + * Comparison is done on the internal representation. + */ + + Tcl_SetObjResult(interp, + Tcl_NewIntObj(CompareVersions(iva, ivb, NULL))); + ckfree(iva); + ckfree(ivb); break; case PKG_VERSIONS: if (objc != 3) { Tcl_WrongNumArgs(interp, 2, objv, "package"); return TCL_ERROR; } - argv2 = Tcl_GetString(objv[2]); + argv2 = TclGetString(objv[2]); hPtr = Tcl_FindHashEntry(&iPtr->packageTable, argv2); if (hPtr != NULL) { - pkgPtr = (Package *) Tcl_GetHashValue(hPtr); + pkgPtr = Tcl_GetHashValue(hPtr); for (availPtr = pkgPtr->availPtr; availPtr != NULL; availPtr = availPtr->nextPtr) { Tcl_AppendElement(interp, availPtr->version); @@ -1068,23 +1118,24 @@ Tcl_PackageObjCmd( } break; case PKG_VSATISFIES: { - char* argv2i = NULL; + char *argv2i = NULL; if (objc < 4) { - Tcl_WrongNumArgs(interp, 2, objv, "version requirement requirement..."); + Tcl_WrongNumArgs(interp, 2, objv, + "version requirement requirement..."); return TCL_ERROR; } - argv2 = Tcl_GetString(objv[2]); - if ((CheckVersionAndConvert(interp, argv2, &argv2i, NULL) != TCL_OK)) { + argv2 = TclGetString(objv[2]); + if (CheckVersionAndConvert(interp, argv2, &argv2i, NULL) != TCL_OK) { return TCL_ERROR; - } else if (CheckAllRequirements (interp, objc-3, objv+3) != TCL_OK) { - Tcl_Free (argv2i); + } else if (CheckAllRequirements(interp, objc-3, objv+3) != TCL_OK) { + ckfree(argv2i); return TCL_ERROR; } - satisfies = AllRequirementsSatisfied (argv2i, objc-3, objv+3); - Tcl_Free (argv2i); + satisfies = AllRequirementsSatisfied(argv2i, objc-3, objv+3); + ckfree(argv2i); Tcl_SetObjResult(interp, Tcl_NewBooleanObj(satisfies)); break; @@ -1120,18 +1171,18 @@ FindPackage( { Interp *iPtr = (Interp *) interp; Tcl_HashEntry *hPtr; - int new; + int isNew; Package *pkgPtr; - hPtr = Tcl_CreateHashEntry(&iPtr->packageTable, name, &new); - if (new) { + hPtr = Tcl_CreateHashEntry(&iPtr->packageTable, name, &isNew); + if (isNew) { pkgPtr = (Package *) ckalloc(sizeof(Package)); pkgPtr->version = NULL; pkgPtr->availPtr = NULL; pkgPtr->clientData = NULL; Tcl_SetHashValue(hPtr, pkgPtr); } else { - pkgPtr = (Package *) Tcl_GetHashValue(hPtr); + pkgPtr = Tcl_GetHashValue(hPtr); } return pkgPtr; } @@ -1164,7 +1215,7 @@ TclFreePackageInfo( for (hPtr = Tcl_FirstHashEntry(&iPtr->packageTable, &search); hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) { - pkgPtr = (Package *) Tcl_GetHashValue(hPtr); + pkgPtr = Tcl_GetHashValue(hPtr); if (pkgPtr->version != NULL) { ckfree(pkgPtr->version); } @@ -1188,9 +1239,9 @@ TclFreePackageInfo( * * CheckVersionAndConvert -- * - * This function checks to see whether a version number has valid - * syntax. It also generates a semi-internal representation (string - * rep of a list of numbers). + * This function checks to see whether a version number has valid syntax. + * It also generates a semi-internal representation (string rep of a list + * of numbers). * * Results: * If string is a properly formed version number the TCL_OK is returned. @@ -1205,27 +1256,29 @@ TclFreePackageInfo( static int CheckVersionAndConvert( - Tcl_Interp *interp, /* Used for error reporting. */ - CONST char *string, /* Supposedly a version number, which is - * groups of decimal digits separated by - * dots. */ - char** internal, /* Internal normalized representation */ - int* stable) /* Flag: Version is (un)stable. */ + Tcl_Interp *interp, /* Used for error reporting. */ + CONST char *string, /* Supposedly a version number, which is + * groups of decimal digits separated by + * dots. */ + char **internal, /* Internal normalized representation */ + int *stable) /* Flag: Version is (un)stable. */ { CONST char *p = string; char prevChar; int hasunstable = 0; - /* 4* assuming that each char is a separator (a,b become ' -x '). + /* + * 4* assuming that each char is a separator (a,b become ' -x '). * 4+ to have spce for an additional -2 at the end */ - char* ibuf = ckalloc (4+4*strlen(string)); - char* ip = ibuf; + char *ibuf = ckalloc(4 + 4*strlen(string)); + char *ip = ibuf; - /* Basic rules + /* + * Basic rules * (1) First character has to be a digit. * (2) All other characters have to be a digit or '.' * (3) Two '.'s may not follow each other. - + * * TIP 268, Modified rules * (1) s.a. * (2) All other characters have to be a digit, 'a', 'b', or '.' @@ -1234,43 +1287,58 @@ CheckVersionAndConvert( * (5) Neither 'a', nor 'b' may occur before or after a '.' */ - if (!isdigit(UCHAR(*p))) { /* INTL: digit */ + if (!isdigit(UCHAR(*p))) { /* INTL: digit */ goto error; } *ip++ = *p; for (prevChar = *p, p++; *p != 0; p++) { - if ( - (!isdigit(UCHAR(*p))) && - (((*p != '.') && (*p != 'a') && (*p != 'b')) || - ((hasunstable && ((*p == 'a') || (*p == 'b'))) || - (((prevChar == 'a') || (prevChar == 'b') || (prevChar == '.')) && (*p == '.')) || - (((*p == 'a') || (*p == 'b') || (*p == '.')) && (prevChar == '.')))) - ) { - /* INTL: digit */ + if (!isdigit(UCHAR(*p)) && /* INTL: digit */ + ((*p!='.' && *p!='a' && *p!='b') || + ((hasunstable && (*p=='a' || *p=='b')) || + ((prevChar=='a' || prevChar=='b' || prevChar=='.') + && (*p=='.')) || + ((*p=='a' || *p=='b' || *p=='.') && prevChar=='.')))) { goto error; } - if ((*p == 'a') || (*p == 'b')) { hasunstable = 1 ; } + if (*p == 'a' || *p == 'b') { + hasunstable = 1; + } - /* Translation to the internal rep. Regular version chars are copied + /* + * Translation to the internal rep. Regular version chars are copied * as is. The separators are translated to numerics. The new separator - * for all parts is space. */ + * for all parts is space. + */ - if (*p == '.') { *ip++ = ' '; *ip++ = '0'; *ip++ = ' '; } - else if (*p == 'a') { *ip++ = ' '; *ip++ = '-'; *ip++ = '2'; *ip++ = ' '; } - else if (*p == 'b') { *ip++ = ' '; *ip++ = '-'; *ip++ = '1'; *ip++ = ' '; } - else { *ip++ = *p; } + if (*p == '.') { + *ip++ = ' '; + *ip++ = '0'; + *ip++ = ' '; + } else if (*p == 'a') { + *ip++ = ' '; + *ip++ = '-'; + *ip++ = '2'; + *ip++ = ' '; + } else if (*p == 'b') { + *ip++ = ' '; + *ip++ = '-'; + *ip++ = '1'; + *ip++ = ' '; + } else { + *ip++ = *p; + } prevChar = *p; } - if ((prevChar != '.') && (prevChar != 'a') && (prevChar != 'b')) { + if (prevChar!='.' && prevChar!='a' && prevChar!='b') { *ip = '\0'; if (internal != NULL) { *internal = ibuf; } else { - ckfree (ibuf); + ckfree(ibuf); } if (stable != NULL) { *stable = !hasunstable; @@ -1279,7 +1347,7 @@ CheckVersionAndConvert( } error: - ckfree (ibuf); + ckfree(ibuf); Tcl_AppendResult(interp, "expected version number but got \"", string, "\"", NULL); return TCL_ERROR; @@ -1306,30 +1374,29 @@ CheckVersionAndConvert( static int CompareVersions( - char *v1, /* Versions strings, of form 2.1.3 (any number */ - char *v2, /* of version numbers). */ - int *isMajorPtr) /* If non-null, the word pointed to is filled - * in with a 0/1 value. 1 means that the difference - * occured in the first element. */ + char *v1, char *v2, /* Versions strings, of form 2.1.3 (any number + * of version numbers). */ + int *isMajorPtr) /* If non-null, the word pointed to is filled + * in with a 0/1 value. 1 means that the + * difference occured in the first element. */ { - int thisIsMajor; - int res, flip; - char* s1, *e1, *s2, *e2, o1, o2; + int thisIsMajor, res, flip; + char *s1, *e1, *s2, *e2, o1, o2; /* * Each iteration of the following loop processes one number from each - * string, terminated by a " " (space). If those numbers don't match then the - * comparison is over; otherwise, we loop back for the next number. + * string, terminated by a " " (space). If those numbers don't match then + * the comparison is over; otherwise, we loop back for the next number. * * TIP 268. * This is identical the function 'ComparePkgVersion', but using the new * space separator as used by the internal rep of version numbers. The * special separators 'a' and 'b' have already been dealt with in - * 'CheckVersionAndConvert', they were translated into numbers as - * well. This keeps the comparison sane. Otherwise we would have to - * compare numerics, the separators, and also deal with the special case - * of end-of-string compared to separators. The semi-list rep we get here - * is much easier to handle, as it is still regular. + * 'CheckVersionAndConvert', they were translated into numbers as well. + * This keeps the comparison sane. Otherwise we would have to compare + * numerics, the separators, and also deal with the special case of + * end-of-string compared to separators. The semi-list rep we get here is + * much easier to handle, as it is still regular. * * Rewritten to not compute a numeric value for the extracted version * number, but do string comparison. Skip any leading zeros for that to @@ -1342,13 +1409,17 @@ CompareVersions( while (1) { /* - * Parse one decimal number from the front of each string. - * Skip leading zeros. Terminate found number for upcoming - * string-wise comparison, if needed. + * Parse one decimal number from the front of each string. Skip + * leading zeros. Terminate found number for upcoming string-wise + * comparison, if needed. */ - while ((*s1 != 0) && (*s1 == '0')) { s1 ++; } - while ((*s2 != 0) && (*s2 == '0')) { s2 ++; } + while ((*s1 != 0) && (*s1 == '0')) { + s1++; + } + while ((*s2 != 0) && (*s2 == '0')) { + s2++; + } /* * s1, s2 now point to the beginnings of the numbers to compare. Test @@ -1371,8 +1442,8 @@ CompareVersions( if ((*s1 == '-') && (*s2 == '-')) { /* a < b => -a > -b, etc. */ - s1 ++; - s2 ++; + s1++; + s2++; flip = 1; } else { flip = 0; @@ -1383,12 +1454,18 @@ CompareVersions( * numbers end. */ - e1 = s1; while ((*e1 != 0) && (*e1 != ' ')) { e1 ++; } - e2 = s2; while ((*e2 != 0) && (*e2 != ' ')) { e2 ++; } + e1 = s1; + while ((*e1 != 0) && (*e1 != ' ')) { + e1++; + } + e2 = s2; + while ((*e2 != 0) && (*e2 != ' ')) { + e2++; + } /* * s1 .. e1 and s2 .. e2 now bracket the numbers to compare. Insert - * terminators, compare, and restore actual contents. First however + * terminators, compare, and restore actual contents. First however * another shortcut. Compare lengths. Shorter string is smaller * number! Thus we strcmp only strings of identical length. */ @@ -1398,10 +1475,12 @@ CompareVersions( } else if ((e2-s2) < (e1-s1)) { res = 1; } else { - o1 = *e1 ; *e1 = '\0'; - o2 = *e2 ; *e2 = '\0'; + o1 = *e1; + *e1 = '\0'; + o2 = *e2; + *e2 = '\0'; - res = strcmp (s1, s2); + res = strcmp(s1, s2); res = (res < 0) ? -1 : (res ? 1 : 0); *e1 = o1; @@ -1414,7 +1493,9 @@ CompareVersions( */ if (res != 0) { - if (flip) res = -res; + if (flip) { + res = -res; + } break; } @@ -1452,13 +1533,12 @@ CompareVersions( * * CheckAllRequirements -- * - * This function checks to see whether all requirements in a set - * have valid syntax. + * This function checks to see whether all requirements in a set have + * valid syntax. * * Results: - * TCL_OK is returned if all requirements are valid. - * Otherwise TCL_ERROR is returned and an error message - * is left in the interp's result. + * TCL_OK is returned if all requirements are valid. Otherwise TCL_ERROR + * is returned and an error message is left in the interp's result. * * Side effects: * May modify the interpreter result. @@ -1468,13 +1548,14 @@ CompareVersions( static int CheckAllRequirements( - Tcl_Interp* interp, - int reqc, /* Requirements to check. */ + Tcl_Interp *interp, + int reqc, /* Requirements to check. */ Tcl_Obj *CONST reqv[]) { int i; + for (i = 0; i < reqc; i++) { - if ((CheckRequirement(interp, Tcl_GetString(reqv[i])) != TCL_OK)) { + if ((CheckRequirement(interp, TclGetString(reqv[i])) != TCL_OK)) { return TCL_ERROR; } } @@ -1504,44 +1585,52 @@ CheckRequirement( Tcl_Interp *interp, /* Used for error reporting. */ CONST char *string) /* Supposedly a requirement. */ { - /* Syntax of requirement = version - * = version-version - * = version- + /* + * Syntax of requirement = version + * = version-version + * = version- */ - char* dash = NULL; - char* buf; + char *dash = NULL, *buf; - dash = strchr (string, '-'); + dash = strchr(string, '-'); if (dash == NULL) { - /* no dash found, has to be a simple version */ - return CheckVersionAndConvert (interp, string, NULL, NULL); + /* + * no dash found, has to be a simple version. + */ + + return CheckVersionAndConvert(interp, string, NULL, NULL); } - if (strchr (dash+1, '-') != NULL) { - /* More dashes found after the first. This is wrong. */ - Tcl_AppendResult(interp, "expected versionMin-versionMax but got \"", string, - "\"", NULL); + + if (strchr(dash+1, '-') != NULL) { + /* + * More dashes found after the first. This is wrong. + */ + + Tcl_AppendResult(interp, "expected versionMin-versionMax but got \"", + string, "\"", NULL); return TCL_ERROR; } - /* Exactly one dash is present. Copy the string, split at the location of + /* + * Exactly one dash is present. Copy the string, split at the location of * dash and check that both parts are versions. Note that the max part can * be empty. */ - buf = strdup (string); - dash = buf + (dash - string); - *dash = '\0'; /* buf now <=> min part */ - dash ++; /* dash now <=> max part */ + DupString(buf, string); + dash = buf + (dash - string); + *dash = '\0'; /* buf now <=> min part */ + dash++; /* dash now <=> max part */ if ((CheckVersionAndConvert(interp, buf, NULL, NULL) != TCL_OK) || - ((*dash != '\0') && - (CheckVersionAndConvert(interp, dash, NULL, NULL) != TCL_OK))) { - free (buf); + ((*dash != '\0') && + (CheckVersionAndConvert(interp, dash, NULL, NULL) != TCL_OK))) { + ckfree(buf); return TCL_ERROR; } - free (buf); + ckfree(buf); return TCL_OK; } @@ -1563,12 +1652,15 @@ CheckRequirement( static void AddRequirementsToResult( - Tcl_Interp* interp, - int reqc, /* Requirements constraining the desired version. */ - Tcl_Obj *CONST reqv[]) /* 0 means to use the latest version available. */ + Tcl_Interp *interp, + int reqc, /* Requirements constraining the desired + * version. */ + Tcl_Obj *CONST reqv[]) /* 0 means to use the latest version + * available. */ { if (reqc > 0) { int i; + for (i = 0; i < reqc; i++) { Tcl_AppendResult(interp, " ", TclGetString(reqv[i]), NULL); } @@ -1593,15 +1685,18 @@ AddRequirementsToResult( static void AddRequirementsToDString( - Tcl_DString* dstring, - int reqc, /* Requirements constraining the desired version. */ - Tcl_Obj *CONST reqv[]) /* 0 means to use the latest version available. */ + Tcl_DString *dsPtr, + int reqc, /* Requirements constraining the desired + * version. */ + Tcl_Obj *CONST reqv[]) /* 0 means to use the latest version + * available. */ { if (reqc > 0) { int i; + for (i = 0; i < reqc; i++) { - Tcl_DStringAppend(dstring, " ", 1); - Tcl_DStringAppend(dstring, TclGetString(reqv[i]), -1); + Tcl_DStringAppend(dsPtr, " ", 1); + Tcl_DStringAppend(dsPtr, TclGetString(reqv[i]), -1); } } } @@ -1611,14 +1706,13 @@ AddRequirementsToDString( * * AllRequirementSatisfied -- * - * This function checks to see whether a version satisfies at - * least one of a set of requirements. + * This function checks to see whether a version satisfies at least one + * of a set of requirements. * * Results: - * If the requirements are satisfied 1 is returned. - * Otherwise 0 is returned. The function assumes - * that all pieces have valid syntax. And is allowed - * to make that assumption. + * If the requirements are satisfied 1 is returned. Otherwise 0 is + * returned. The function assumes that all pieces have valid syntax. And + * is allowed to make that assumption. * * Side effects: * None. @@ -1628,17 +1722,21 @@ AddRequirementsToDString( static int AllRequirementsSatisfied( - char* availVersionI, /* Candidate version to check against the requirements */ - int reqc, /* Requirements constraining the desired version. */ - Tcl_Obj *CONST reqv[]) /* 0 means to use the latest version available. */ + char *availVersionI, /* Candidate version to check against the + * requirements. */ + int reqc, /* Requirements constraining the desired + * version. */ + Tcl_Obj *CONST reqv[]) /* 0 means to use the latest version + * available. */ { - int i, satisfies; + int i; - for (satisfies = i = 0; i < reqc; i++) { - satisfies = RequirementSatisfied(availVersionI, Tcl_GetString(reqv[i])); - if (satisfies) break; + for (i = 0; i < reqc; i++) { + if (RequirementSatisfied(availVersionI, TclGetString(reqv[i]))) { + return 1; + } } - return satisfies; + return 0; } /* @@ -1649,10 +1747,9 @@ AllRequirementsSatisfied( * This function checks to see whether a version satisfies a requirement. * * Results: - * If the requirement is satisfied 1 is returned. - * Otherwise 0 is returned. The function assumes - * that all pieces have valid syntax. And is allowed - * to make that assumption. + * If the requirement is satisfied 1 is returned. Otherwise 0 is + * returned. The function assumes that all pieces have valid syntax, and + * is allowed to make that assumption. * * Side effects: * None. @@ -1662,79 +1759,84 @@ AllRequirementsSatisfied( static int RequirementSatisfied( - char *havei, /* Version string, of candidate package we have */ - CONST char *req) /* Requirement string the candidate has to satisfy */ + char *havei, /* Version string, of candidate package we + * have. */ + CONST char *req) /* Requirement string the candidate has to + * satisfy. */ { - /* The have candidate is already in internal rep. */ + /* + * The have candidate is already in internal rep. + */ int satisfied, res; - char* dash = NULL; - char* buf, *min, *max; + char *dash = NULL, *buf, *min, *max; - dash = strchr (req, '-'); + dash = strchr(req, '-'); if (dash == NULL) { - /* No dash found, is a simple version, fallback to regular check. - * The 'CheckVersionAndConvert' cannot fail. We pad the requirement with + /* + * No dash found, is a simple version, fallback to regular check. The + * 'CheckVersionAndConvert' cannot fail. We pad the requirement with * 'a0', i.e '-2' before doing the comparison to properly accept * unstables as well. */ - char* reqi = NULL; + char *reqi = NULL; int thisIsMajor; - CheckVersionAndConvert (NULL, req, &reqi, NULL); - strcat (reqi, " -2"); - res = CompareVersions(havei, reqi, &thisIsMajor); + CheckVersionAndConvert(NULL, req, &reqi, NULL); + strcat(reqi, " -2"); + res = CompareVersions(havei, reqi, &thisIsMajor); satisfied = (res == 0) || ((res == 1) && !thisIsMajor); - Tcl_Free (reqi); + ckfree(reqi); return satisfied; } - /* Exactly one dash is present (Assumption of valid syntax). Copy the req, - * split at the location of dash and check that both parts are - * versions. Note that the max part can be empty. + /* + * Exactly one dash is present (Assumption of valid syntax). Copy the req, + * split at the location of dash and check that both parts are versions. + * Note that the max part can be empty. */ - buf = strdup (req); - dash = buf + (dash - req); - *dash = '\0'; /* buf now <=> min part */ - dash ++; /* dash now <=> max part */ + DupString(buf, req); + dash = buf + (dash - req); + *dash = '\0'; /* buf now <=> min part */ + dash++; /* dash now <=> max part */ if (*dash == '\0') { - /* We have a min, but no max. For the comparison we generate the + /* + * We have a min, but no max. For the comparison we generate the * internal rep, padded with 'a0' i.e. '-2'. */ - /* No max part, unbound */ - - CheckVersionAndConvert (NULL, buf, &min, NULL); - strcat (min, " -2"); + CheckVersionAndConvert(NULL, buf, &min, NULL); + strcat(min, " -2"); satisfied = (CompareVersions(havei, min, NULL) >= 0); - Tcl_Free (min); - free (buf); + ckfree(min); + ckfree(buf); return satisfied; } - /* We have both min and max, and generate their internal reps. - * When identical we compare as is, otherwise we pad with 'a0' - * to ove the range a bit. + /* + * We have both min and max, and generate their internal reps. When + * identical we compare as is, otherwise we pad with 'a0' to ove the range + * a bit. */ - CheckVersionAndConvert (NULL, buf, &min, NULL); - CheckVersionAndConvert (NULL, dash, &max, NULL); + CheckVersionAndConvert(NULL, buf, &min, NULL); + CheckVersionAndConvert(NULL, dash, &max, NULL); if (CompareVersions(min, max, NULL) == 0) { satisfied = (CompareVersions(min, havei, NULL) == 0); } else { - strcat (min, " -2"); - strcat (max, " -2"); + strcat(min, " -2"); + strcat(max, " -2"); satisfied = ((CompareVersions(min, havei, NULL) <= 0) && - (CompareVersions(havei, max, NULL) < 0)); + (CompareVersions(havei, max, NULL) < 0)); } - Tcl_Free (min); - Tcl_Free (max); - free (buf); + ckfree(min); + ckfree(max); + ckfree(buf); return satisfied; } @@ -1743,9 +1845,9 @@ RequirementSatisfied( * * ExactRequirement -- * - * This function is the core for the translation of -exact requests. - * It translates the request of the version into a range of versions. - * The translation was chosen for backwards compatibility. + * This function is the core for the translation of -exact requests. It + * translates the request of the version into a range of versions. The + * translation was chosen for backwards compatibility. * * Results: * A Tcl_Obj containing the version range as string. @@ -1756,17 +1858,18 @@ RequirementSatisfied( *---------------------------------------------------------------------- */ -static Tcl_Obj* -ExactRequirement(version) - CONST char* version; +static Tcl_Obj * +ExactRequirement( + CONST char *version) { - /* A -exact request for a version X.y is translated into the range + /* + * A -exact request for a version X.y is translated into the range * X.y-X.(y+1). For example -exact 8.4 means the range "8.4-8.5". * * This translation was chosen to prevent packages which currently use a * 'package require -exact tclversion' from being affected by the core now - * registering itself as 8.4.x (patchlevel) instead of 8.4 - * (version). Examples are tbcload, compiler, and ITcl. + * registering itself as 8.4.x (patchlevel) instead of 8.4 (version). + * Examples are tbcload, compiler, and ITcl. * * Translating -exact 8.4 to the range "8.4-8.4" instead would require us * and everyone else to rebuild these packages to require -exact 8.4.14, @@ -1774,53 +1877,70 @@ ExactRequirement(version) * issue with effects similar to the bugfix made in 8.5 now requiring * ifneeded and provided versions to match. Instead we have chosen to * interpret exactness to not be exactly equal, but to be exact only - * within the specified level, and allowing variation in the deeper - * level. More examples: + * within the specified level, and allowing variation in the deeper level. + * More examples: * - * -exact 8 => "8-9" + * -exact 8 => "8-9" * -exact 8.4 => "8.4-8.5" * -exact 8.4.14 => "8.4.14-8.4.15" * -exact 8.0a2 => "8.0a2-8.0a3" */ - char* iv; - int lc, i; - CONST char** lv; - char buf [30]; - Tcl_Obj* o = Tcl_NewStringObj (version,-1); - Tcl_AppendStringsToObj (o, "-", NULL); + char *iv, buf[30]; + int lc, i; + CONST char **lv; + Tcl_Obj *objPtr = Tcl_NewStringObj(version, -1); + + Tcl_AppendStringsToObj(objPtr, "-", NULL); - /* Assuming valid syntax here */ - CheckVersionAndConvert (NULL, version, &iv, NULL); + /* + * Assuming valid syntax here. + */ - /* Split the list into components */ - Tcl_SplitList (NULL, iv, &lc, &lv); + CheckVersionAndConvert(NULL, version, &iv, NULL); - /* Iterate over the components and make them parts of the result. Except - * for the last, which is handled separately, to allow the - * incrementation. + /* + * Split the list into components. + */ + + Tcl_SplitList(NULL, iv, &lc, &lv); + + /* + * Iterate over the components and make them parts of the result. Except + * for the last, which is handled separately, to allow the incrementation. */ for (i=0; i < (lc-1); i++) { - /* Regular component */ - Tcl_AppendStringsToObj (o, lv[i], NULL); - /* Separator component */ - i ++; - if (0 == strcmp ("-1", lv[i])) { - Tcl_AppendStringsToObj (o, "b", NULL); - } else if (0 == strcmp ("-2", lv[i])) { - Tcl_AppendStringsToObj (o, "a", NULL); + /* + * Regular component. + */ + + Tcl_AppendStringsToObj(objPtr, lv[i], NULL); + + /* + * Separator component. + */ + + i++; + if (0 == strcmp("-1", lv[i])) { + Tcl_AppendStringsToObj(objPtr, "b", NULL); + } else if (0 == strcmp("-2", lv[i])) { + Tcl_AppendStringsToObj(objPtr, "a", NULL); } else { - Tcl_AppendStringsToObj (o, ".", NULL); + Tcl_AppendStringsToObj(objPtr, ".", NULL); } } - /* Regular component, last */ - sprintf (buf, "%d", atoi (lv [lc-1]) + 1); - Tcl_AppendStringsToObj (o, buf, NULL); - ckfree ((char*) iv); - ckfree ((char*) lv); - return o; + /* + * Regular component, last. + */ + + sprintf(buf, "%d", atoi(lv[lc-1]) + 1); + Tcl_AppendStringsToObj(objPtr, buf, NULL); + + ckfree((char *) iv); + ckfree((char *) lv); + return objPtr; } /* @@ -1842,14 +1962,14 @@ ExactRequirement(version) */ static void -VersionCleanupProc ( +VersionCleanupProc( ClientData clientData, /* Pointer to remembered version string object * for interp. */ Tcl_Interp *interp) /* Interpreter that is being deleted. */ { - Tcl_Obj* ov = (Tcl_Obj*) clientData; + Tcl_Obj *ov = clientData; if (ov != NULL) { - Tcl_DecrRefCount (ov); + TclDecrRefCount(ov); } } |