summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/Eval.38
-rw-r--r--doc/NRE.3260
-rw-r--r--generic/tcl.h6
-rw-r--r--generic/tclAssembly.c2
-rw-r--r--generic/tclBasic.c33
-rw-r--r--generic/tclCmdIL.c3
-rw-r--r--generic/tclCmdMZ.c52
-rw-r--r--generic/tclDecls.h17
-rw-r--r--generic/tclDictObj.c9
-rw-r--r--generic/tclDisassemble.c6
-rw-r--r--generic/tclExecute.c681
-rw-r--r--generic/tclGet.c2
-rw-r--r--generic/tclInt.decls2
-rw-r--r--generic/tclInt.h108
-rw-r--r--generic/tclIntDecls.h4
-rw-r--r--generic/tclObj.c248
-rw-r--r--generic/tclPkg.c720
-rw-r--r--generic/tclProc.c4
-rw-r--r--generic/tclScan.c4
-rw-r--r--[-rwxr-xr-x]generic/tclStrToD.c48
-rw-r--r--generic/tclStringObj.c205
-rw-r--r--generic/tclStubInit.c3
-rw-r--r--generic/tclTestObj.c8
-rw-r--r--generic/tclTimer.c35
-rw-r--r--generic/tclUtil.c25
-rw-r--r--generic/tclZlib.c2
-rw-r--r--library/http1.0/http.tcl377
-rw-r--r--library/http1.0/pkgIndex.tcl11
-rw-r--r--tests/httpold.test300
-rw-r--r--tests/package.test12
-rw-r--r--unix/Makefile.in9
-rw-r--r--win/Makefile.in7
-rw-r--r--win/makefile.vc3
33 files changed, 975 insertions, 2239 deletions
diff --git a/doc/Eval.3 b/doc/Eval.3
index 7fd7bfa..a094019 100644
--- a/doc/Eval.3
+++ b/doc/Eval.3
@@ -160,10 +160,10 @@ it is faster to execute the script directly.
.TP 23
\fBTCL_EVAL_GLOBAL\fR
.
-If this flag is set, the script is processed at global level. This
-means that it is evaluated in the global namespace and its variable
-context consists of global variables only (it ignores any Tcl
-procedures that are active).
+If this flag is set, the script is evaluated in the global namespace instead of
+the current namespace and its variable context consists of global variables
+only (it ignores any Tcl procedures that are active).
+.\" TODO: document TCL_EVAL_INVOKE and TCL_EVAL_NOERR.
.SH "MISCELLANEOUS DETAILS"
.PP
diff --git a/doc/NRE.3 b/doc/NRE.3
index ff0d108..6078a53 100644
--- a/doc/NRE.3
+++ b/doc/NRE.3
@@ -1,5 +1,6 @@
.\"
.\" Copyright (c) 2008 by Kevin B. Kenny.
+.\" Copyright (c) 2018 by Nathan Coulter.
.\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
@@ -38,43 +39,39 @@ void
.SH ARGUMENTS
.AS Tcl_CmdDeleteProc *interp in
.AP Tcl_Interp *interp in
-Interpreter in which to create or evaluate a command.
+The relevant Interpreter.
.AP char *cmdName in
-Name of a new command to create.
+Name of the command to create.
.AP Tcl_ObjCmdProc *proc in
-Implementation of a command that will be called whenever \fIcmdName\fR
-is invoked as a command in the unoptimized way.
+Called in order to evaluate a command. Is often just a small wrapper that uses
+\fBTcl_NRCallObjProc\fR to call \fInreProc\fR using a new trampoline. Behaves
+in the same way as the \fIproc\fR argument to \fBTcl_CreateObjCommand\fR(3)
+(\fIq.v.\fR).
.AP Tcl_ObjCmdProc *nreProc in
-Implementation of a command that will be called whenever \fIcmdName\fR
-is invoked and requested to conserve the C stack.
+Called instead of \fIproc\fR when a trampoline is already in use.
.AP ClientData clientData in
-Arbitrary one-word value that will be passed to \fIproc\fR, \fInreProc\fR,
-\fIdeleteProc\fR and \fIobjProc\fR.
+Arbitrary one-word value passed to \fIproc\fR, \fInreProc\fR, \fIdeleteProc\fR
+and \fIobjProc\fR.
.AP Tcl_CmdDeleteProc *deleteProc in/out
-Procedure to call before \fIcmdName\fR is deleted from the interpreter.
-This procedure allows for command-specific cleanup. If \fIdeleteProc\fR
-is \fBNULL\fR, then no procedure is called before the command is deleted.
+Called before \fIcmdName\fR is deleted from the interpreter, allowing for
+command-specific cleanup. May be NULL.
.AP int objc in
-Count of parameters provided to the implementation of a command.
+Number of items in \fIobjv\fR.
.AP Tcl_Obj **objv in
-Pointer to an array of Tcl values. Each value holds the value of a
-single word in the command to execute.
+Words in the command.
.AP Tcl_Obj *objPtr in
-Pointer to a Tcl_Obj whose value is a script or expression to execute.
+A script or expression to evaluate.
.AP int flags in
-ORed combination of flag bits that specify additional options.
-\fBTCL_EVAL_GLOBAL\fR is the only flag that is currently supported.
-.\" TODO: This is a lie. But kbk didn't grasp TCL_EVAL_INVOKE and
-.\" TCL_EVAL_NOERR well enough to document them.
+As described for \fITcl_EvalObjv\fR.
+.PP
.AP Tcl_Command cmd in
-Token for a command that is to be used instead of the currently
-executing command.
+Token to use instead of one derived from the first word of \fIobjv\fR in order
+to evaluate a command.
.AP Tcl_Obj *resultPtr out
-Pointer to an unshared Tcl_Obj where the result of expression
-evaluation is written.
+Pointer to an unshared Tcl_Obj where the result of the evaluation is stored if
+the return code is TCL_OK.
.AP Tcl_NRPostProc *postProcPtr in
-Pointer to a function that will be invoked when the command currently
-executing in the interpreter designated by \fIinterp\fR completes.
+A function to push.
.AP ClientData data0 in
.AP ClientData data1 in
.AP ClientData data2 in
@@ -84,98 +81,51 @@ to the function designated by \fIpostProcPtr\fR when it is invoked.
.BE
.SH DESCRIPTION
.PP
-This series of C functions provides an interface whereby commands that
-are implemented in C can be evaluated, and invoke Tcl commands scripts
-and scripts, without consuming space on the C stack. The non-recursive
-evaluation is done by installing a \fItrampoline\fR, a small piece of
-code that invokes a command or script, and then executes a series of
-callbacks when the command or script returns.
-.PP
-The \fBTcl_NRCreateCommand\fR function creates a Tcl command in the
-interpreter designated by \fIinterp\fR that is prepared to handle
-nonrecursive evaluation with a trampoline. The \fIcmdName\fR argument
-gives the name of the new command. If \fIcmdName\fR contains any
-namespace qualifiers, then the new command is added to the specified
-namespace; otherwise, it is added to the global namespace. \fIproc\fR
-gives the procedure that will be called when the interpreter wishes to
-evaluate the command in an unoptimized manner, and \fInreProc\fR is
-the procedure that will be called when the interpreter wishes to
-evaluate the command using a trampoline. \fIdeleteProc\fR is a
-function that will be called before the command is deleted from the
-interpreter. When any of the three functions is invoked, it is passed
-the \fIclientData\fR parameter.
-.PP
-\fBTcl_NRCreateCommand\fR deletes any existing command
-\fIname\fR already associated with the interpreter
-(however see below for an exception where the existing command
-is not deleted).
-It returns a token that may be used to refer
-to the command in subsequent calls to \fBTcl_GetCommandName\fR.
-If \fBTcl_NRCreateCommand\fR is called for an interpreter that is in
-the process of being deleted, then it does not create a new command,
-does not delete any existing command of the same name, and returns NULL.
-.PP
-The \fIproc\fR and \fInreProc\fR function are expected to conform to
-all the rules set forth for the \fIproc\fR argument to
-\fBTcl_CreateObjCommand\fR(3) (\fIq.v.\fR).
-.PP
-When a command that is written to cope with evaluation via trampoline
-is invoked without a trampoline on the stack, it will usually respond
-to the invocation by creating a trampoline and calling the
-trampoline-enabled implementation of the same command. This call is done by
-means of \fBTcl_NRCallObjProc\fR. In the call to
-\fBTcl_NRCallObjProc\fR, the \fIinterp\fR, \fIclientData\fR,
-\fIobjc\fR and \fIobjv\fR parameters should be the same ones that were
-passed to \fIproc\fR. The \fInreProc\fR parameter should designate the
-trampoline-enabled implementation of the command.
-.PP
-\fBTcl_NREvalObj\fR arranges for the script contained in \fIobjPtr\fR
-to be evaluated in the interpreter designated by \fIinterp\fR after
-the current command (which must be trampoline-enabled) returns. It is
-the method by which a command may invoke a script without consuming
-space on the C stack. Similarly, \fBTcl_NREvalObjv\fR arranges to
-invoke a single Tcl command whose words have already been separated
-and substituted. The \fIobjc\fR and \fIobjv\fR parameters give the
-words of the command to be evaluated when execution reaches the
-trampoline.
-.PP
-\fBTcl_NRCmdSwap\fR allows for trampoline evaluation of a command whose
-resolution is already known. The \fIcmd\fR parameter gives a
-\fBTcl_Command\fR token (returned from \fBTcl_CreateObjCommand\fR or
-\fBTcl_GetCommandFromObj\fR) identifying the command to be invoked in
-the trampoline; this command must match the word in \fIobjv[0]\fR.
-The remaining arguments are as for \fBTcl_NREvalObjv\fR.
-.PP
-\fBTcl_NREvalObj\fR, \fBTcl_NREvalObjv\fR and \fBTcl_NRCmdSwap\fR
-all accept a \fIflags\fR parameter, which is an OR-ed-together set of
-bits to control evaluation. At the present time, the only supported flag
-available to callers is \fBTCL_EVAL_GLOBAL\fR.
-.\" TODO: Again, this is a lie. Do we want to explain TCL_EVAL_INVOKE
-.\" and TCL_EVAL_NOERR?
-If the \fBTCL_EVAL_GLOBAL\fR flag is set, the script or command is
-evaluated in the global namespace. If it is not set, it is evaluated
-in the current namespace.
-.PP
-\fBTcl_NRExprObj\fR arranges for the expression contained in \fIobjPtr\fR
-to be evaluated in the interpreter designated by \fIinterp\fR after
-the current command (which must be trampoline-enabled) returns. It is
-the method by which a command may evaluate a Tcl expression without consuming
-space on the C stack. The argument \fIresultPtr\fR is a pointer to an
-unshared Tcl_Obj where the result of expression evaluation is to be written.
-If expression evaluation returns any code other than TCL_OK, the
-\fIresultPtr\fR value is left untouched.
-.PP
-All of the routines return \fBTCL_OK\fR if command or expression invocation
-has been scheduled successfully. If for any reason the scheduling cannot
-be completed (for example, if the interpreter is unable to find
-the requested command), they return \fBTCL_ERROR\fR with an
-appropriate message left in the interpreter's result.
-.PP
-\fBTcl_NRAddCallback\fR arranges to have a C function called when the
-current trampoline-enabled command in the Tcl interpreter designated
-by \fIinterp\fR returns. The \fIpostProcPtr\fR argument is a pointer
-to the callback function, which must have arguments and return value
-consistent with the \fBTcl_NRPostProc\fR data type:
+These functions provide an interface to the function stack that an interpreter
+iterates through to evaluate commands. The routine behind a command is
+implemented by an initial function and any additional functions that the
+routine pushes onto the stack as it progresses. The interpreter itself pushes
+functions onto the stack to react to the end of a routine and to exercise other
+forms of control such as switching between in-progress stacks and the
+evaluation of other scripts at additional levels without adding frames to the C
+stack. To execute a routine, the initial function for the routine is called
+and then a small bit of code called a \fItrampoline\fR iteratively takes
+functions off the stack and calls them, using the value of the last call as the
+value of the routine.
+.PP
+\fBTcl_NRCallObjProc\fR calls \fInreProc\fR using a new trampoline.
+.PP
+\fBTcl_NRCreateCommand\fR, an alternative to \fBTcl_CreateObjCommand\fR,
+resolves \fIcmdName\fR, which may contain namespace qualifiers, relative to the
+current namespace, creates a command by that name, and returns a token for the
+command which may be used in subsequent calls to \fBTcl_GetCommandName\fR.
+Except for a few cases noted below any existing command by the same name is
+first deleted. If \fIinterp\fR is in the process of being deleted
+\fBTcl_NRCreateCommand\fR does not create any command, does not delete any
+command, and returns NULL.
+.PP
+\fBTcl_NREvalObj\fR pushes a function that is like \fBTcl_EvalObjEx\fR but
+consumes no space on the C stack.
+.PP
+\fBTcl_NREvalObjv\fR pushes a function that is like \fBTcl_EvalObjv\fR but
+consumes no space on the C stack.
+.PP
+\fBTcl_NRCmdSwap\fR is like \fBTcl_NREvalObjv\fR, but uses \fIcmd\fR, a token
+previously returned by \fBTcl_CreateObjCommand\fR or
+\fBTcl_GetCommandFromObj\fR, instead of resolving the first word of \fIobjv\fR.
+. The name of this command must be the same as \fIobjv[0]\fR.
+.PP
+\fBTcl_NRExprObj\fR pushes a function that evaluates \fIobjPtr\fR as an
+expression in the same manner as \fBTcl_ExprObj\fR but without consuming space
+on the C stack.
+.PP
+All of the functions return \fBTCL_OK\fR if the evaluation of the script,
+command, or expression has been scheduled successfully. Otherwise (for example
+if the command name cannot be resolved), they return \fBTCL_ERROR\fR and store
+a message as the interpreter's result.
+.PP
+\fBTcl_NRAddCallback\fR pushes \fIpostProcPtr\fR. The signature for
+\fBTcl_NRPostProc\fR is:
.PP
.CS
typedef int
@@ -185,25 +135,13 @@ typedef int
int \fIresult\fR);
.CE
.PP
-When the trampoline invokes the callback function, the \fIdata\fR
-parameter will point to an array containing the four one-word
-quantities that were passed to \fBTcl_NRAddCallback\fR in the
-\fIdata0\fR through \fIdata3\fR parameters. The Tcl interpreter will
-be designated by the \fIinterp\fR parameter, and the \fIresult\fR
-parameter will contain the result (\fBTCL_OK\fR, \fBTCL_ERROR\fR,
-\fBTCL_RETURN\fR, \fBTCL_BREAK\fR or \fBTCL_CONTINUE\fR) that was
-returned by the command evaluation. The callback function is expected,
-in turn, either to return a \fIresult\fR to control further evaluation.
-.PP
-Multiple \fBTcl_NRAddCallback\fR invocations may request multiple
-callbacks, which may be to the same or different callback
-functions. If multiple callbacks are requested, they are executed in
-last-in, first-out order, that is, the most recently requested
-callback is executed first.
+\fIdata\fR is a pointer to an array containing \fIdata0\fR through \fIdata3\fR.
+\fIresult\fR is the value returned by the previous function implementing part
+the routine.
.SH EXAMPLE
.PP
-The usual pattern for Tcl commands that invoke other Tcl commands
-is something like:
+The following command uses \fBTcl_EvalObjEx\fR, which consumes space on the C
+stack, to evalute a script:
.PP
.CS
int
@@ -228,28 +166,17 @@ int
\fITheCmdOldObjProc\fR, clientData, TheCmdDeleteProc);
.CE
.PP
-To enable a command like this one for trampoline-based evaluation,
-it must be split into three pieces:
-.IP \(bu
-A non-trampoline implementation, \fITheCmdNewObjProc\fR,
-which will simply create a trampoline
-and invoke the trampoline-based implementation.
-.IP \(bu
-A trampoline-enabled implementation, \fITheCmdNRObjProc\fR. This
-function will perform the initialization, request that the trampoline
-call the postprocessing routine after command evaluation, and finally,
-request that the trampoline call the inner command.
-.IP \(bu
-A postprocessing routine, \fITheCmdPostProc\fR. This function will
-perform the postprocessing formerly done after the return from the
-inner command in \fITheCmdObjProc\fR.
-.PP
-The non-trampoline implementation is simple and stylized, containing
-a single statement:
+To avoid consuming space on the C stack, \fITheCmdOldObjProc\fR is renamed to
+\fITheCmdNRObjProc\fR and the postprocessing step is split into a separate
+function, \fITheCmdPostProc\fR, which is pushed onto the function stack.
+\fITcl_EvalObjEx\fR is replaced with \fITcl_NREvalObj\fR, which uses a
+trampoline instead of consuming space on the C stack. A new version of
+\fITheCmdOldObjProc\fR is just a a wrapper that uses \fBTcl_NRCallObjProc\fR to
+call \fITheCmdNRObjProc\fR:
.PP
.CS
int
-\fITheCmdNewObjProc\fR(
+\fITheCmdOldObjProc\fR(
ClientData clientData,
Tcl_Interp *interp,
int objc,
@@ -260,9 +187,6 @@ int
}
.CE
.PP
-The trampoline-enabled implementation requests postprocessing,
-and returns to the trampoline requesting command evaluation.
-.PP
.CS
int
\fITheCmdNRObjProc\fR
@@ -284,9 +208,6 @@ int
}
.CE
.PP
-The postprocessing procedure does whatever the original command did
-upon return from the inner evaluation.
-.PP
.CS
int
\fITheCmdNRPostProc\fR(
@@ -303,26 +224,13 @@ int
}
.CE
.PP
-If \fItheCommand\fR is a command that results in multiple commands or
-scripts being evaluated, its postprocessing routine may schedule
-additional postprocessing and then request another command evaluation
-by means of \fBTcl_NREvalObj\fR or one of the other evaluation
-routines. Looping and sequencing constructs may be implemented in this way.
-.PP
-Finally, to install a trampoline-enabled command in the interpreter,
-\fBTcl_NRCreateCommand\fR is used in place of
-\fBTcl_CreateObjCommand\fR. It accepts two command procedures instead
-of one. The first is for use when no trampoline is yet on the stack,
-and the second is for use when there is already a trampoline in place.
+Any function comprising a routine can push other functions, making it possible
+implement looping and sequencing constructs using the function stack.
.PP
-.CS
-\fBTcl_NRCreateCommand\fR(interp, "theCommand",
- \fITheCmdNewObjProc\fR, \fITheCmdNRObjProc\fR, clientData,
- TheCmdDeleteProc);
-.CE
.SH "SEE ALSO"
Tcl_CreateCommand(3), Tcl_CreateObjCommand(3), Tcl_EvalObjEx(3), Tcl_GetCommandFromObj(3), Tcl_ExprObj(3)
.SH KEYWORDS
stackless, nonrecursive, execute, command, global, value, result, script
.SH COPYRIGHT
-Copyright (c) 2008 by Kevin B. Kenny
+Copyright (c) 2008 by Kevin B. Kenny.
+Copyright (c) 2018 by Nathan Coulter.
diff --git a/generic/tcl.h b/generic/tcl.h
index 9e4208a..0de866a 100644
--- a/generic/tcl.h
+++ b/generic/tcl.h
@@ -2359,15 +2359,9 @@ EXTERN void Tcl_GetMemoryInfo(Tcl_DString *dsPtr);
# undef Tcl_NewDoubleObj
# define Tcl_NewDoubleObj(val) \
Tcl_DbNewDoubleObj(val, __FILE__, __LINE__)
-# undef Tcl_NewIntObj
-# define Tcl_NewIntObj(val) \
- Tcl_DbNewLongObj(val, __FILE__, __LINE__)
# undef Tcl_NewListObj
# define Tcl_NewListObj(objc, objv) \
Tcl_DbNewListObj(objc, objv, __FILE__, __LINE__)
-# undef Tcl_NewLongObj
-# define Tcl_NewLongObj(val) \
- Tcl_DbNewLongObj(val, __FILE__, __LINE__)
# undef Tcl_NewObj
# define Tcl_NewObj() \
Tcl_DbNewObj(__FILE__, __LINE__)
diff --git a/generic/tclAssembly.c b/generic/tclAssembly.c
index 4c5ae68..bdca74c 100644
--- a/generic/tclAssembly.c
+++ b/generic/tclAssembly.c
@@ -4266,7 +4266,7 @@ AddBasicBlockRangeToErrorInfo(
Tcl_AppendObjToErrorInfo(interp, lineNo);
Tcl_AddErrorInfo(interp, " and ");
if (bbPtr->successor1 != NULL) {
- TclSetLongObj(lineNo, bbPtr->successor1->startLine);
+ TclSetIntObj(lineNo, bbPtr->successor1->startLine);
Tcl_AppendObjToErrorInfo(interp, lineNo);
} else {
Tcl_AddErrorInfo(interp, "end of assembly code");
diff --git a/generic/tclBasic.c b/generic/tclBasic.c
index 7fdcb24..42a1ccf 100644
--- a/generic/tclBasic.c
+++ b/generic/tclBasic.c
@@ -219,7 +219,7 @@ static const CmdInfo builtInCmds[] = {
{"lsearch", Tcl_LsearchObjCmd, NULL, NULL, CMD_IS_SAFE},
{"lset", Tcl_LsetObjCmd, TclCompileLsetCmd, NULL, CMD_IS_SAFE},
{"lsort", Tcl_LsortObjCmd, NULL, NULL, CMD_IS_SAFE},
- {"package", Tcl_PackageObjCmd, NULL, NULL, CMD_IS_SAFE},
+ {"package", Tcl_PackageObjCmd, NULL, TclNRPackageObjCmd, CMD_IS_SAFE},
{"proc", Tcl_ProcObjCmd, NULL, NULL, CMD_IS_SAFE},
{"regexp", Tcl_RegexpObjCmd, TclCompileRegexpCmd, NULL, CMD_IS_SAFE},
{"regsub", Tcl_RegsubObjCmd, TclCompileRegsubCmd, NULL, CMD_IS_SAFE},
@@ -5971,7 +5971,6 @@ Tcl_ExprLongObj(
resultPtr = Tcl_NewBignumObj(&big);
/* FALLTHROUGH */
}
- case TCL_NUMBER_LONG:
case TCL_NUMBER_WIDE:
case TCL_NUMBER_BIG:
result = TclGetLongFromObj(interp, resultPtr, ptr);
@@ -6898,12 +6897,12 @@ ExprAbsFunc(
return TCL_ERROR;
}
- if (type == TCL_NUMBER_LONG) {
- long l = *((const long *) ptr);
+ if (type == TCL_NUMBER_WIDE) {
+ Tcl_WideInt l = *((const Tcl_WideInt *) ptr);
- if (l > (long)0) {
+ if (l > (Tcl_WideInt)0) {
goto unChanged;
- } else if (l == (long)0) {
+ } else if (l == (Tcl_WideInt)0) {
const char *string = objv[1]->bytes;
if (string) {
while (*string != '0') {
@@ -6915,11 +6914,11 @@ ExprAbsFunc(
}
}
goto unChanged;
- } else if (l == LONG_MIN) {
- TclInitBignumFromLong(&big, l);
+ } else if (l == LLONG_MIN) {
+ TclInitBignumFromWideInt(&big, l);
goto tooLarge;
}
- Tcl_SetObjResult(interp, Tcl_NewLongObj(-l));
+ Tcl_SetObjResult(interp, Tcl_NewWideIntObj(-l));
return TCL_OK;
}
@@ -6943,22 +6942,6 @@ ExprAbsFunc(
return TCL_OK;
}
-#ifndef TCL_WIDE_INT_IS_LONG
- if (type == TCL_NUMBER_WIDE) {
- Tcl_WideInt w = *((const Tcl_WideInt *) ptr);
-
- if (w >= (Tcl_WideInt)0) {
- goto unChanged;
- }
- if (w == LLONG_MIN) {
- TclInitBignumFromWideInt(&big, w);
- goto tooLarge;
- }
- Tcl_SetObjResult(interp, Tcl_NewWideIntObj(-w));
- return TCL_OK;
- }
-#endif
-
if (type == TCL_NUMBER_BIG) {
if (mp_cmp_d((const mp_int *) ptr, 0) == MP_LT) {
Tcl_GetBignumFromObj(NULL, objv[1], &big);
diff --git a/generic/tclCmdIL.c b/generic/tclCmdIL.c
index 4fb89e3..df93b79 100644
--- a/generic/tclCmdIL.c
+++ b/generic/tclCmdIL.c
@@ -2193,8 +2193,7 @@ Tcl_JoinObjCmd(
(void) Tcl_GetStringFromObj(joinObjPtr, &length);
if (length == 0) {
- TclStringCatObjv(interp, /* inPlace */ 0, listLen, elemPtrs,
- &resObjPtr);
+ resObjPtr = TclStringCat(interp, listLen, elemPtrs, 0);
} else {
int i;
diff --git a/generic/tclCmdMZ.c b/generic/tclCmdMZ.c
index a206cc5..1b49e5f 100644
--- a/generic/tclCmdMZ.c
+++ b/generic/tclCmdMZ.c
@@ -1335,16 +1335,8 @@ StringFirstCmd(
if (TCL_OK != TclGetIntForIndexM(interp, objv[3], size - 1, &start)) {
return TCL_ERROR;
}
-
- if (start < 0) {
- start = 0;
- }
- if (start >= size) {
- Tcl_SetObjResult(interp, Tcl_NewIntObj(-1));
- return TCL_OK;
- }
}
- Tcl_SetObjResult(interp, Tcl_NewIntObj(TclStringFind(objv[1],
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(TclStringFirst(objv[1],
objv[2], start)));
return TCL_OK;
}
@@ -1388,14 +1380,6 @@ StringLastCmd(
if (TCL_OK != TclGetIntForIndexM(interp, objv[3], size - 1, &last)) {
return TCL_ERROR;
}
-
- if (last < 0) {
- Tcl_SetObjResult(interp, Tcl_NewIntObj(-1));
- return TCL_OK;
- }
- if (last >= size) {
- last = size - 1;
- }
}
Tcl_SetObjResult(interp, Tcl_NewIntObj(TclStringLast(objv[1],
objv[2], last)));
@@ -1605,9 +1589,6 @@ StringIsCmd(
/* TODO */
if ((objPtr->typePtr == &tclDoubleType) ||
(objPtr->typePtr == &tclIntType) ||
-#ifndef TCL_WIDE_INT_IS_LONG
- (objPtr->typePtr == &tclWideIntType) ||
-#endif
(objPtr->typePtr == &tclBignumType)) {
break;
}
@@ -1642,9 +1623,6 @@ StringIsCmd(
goto failedIntParse;
case STR_IS_ENTIER:
if ((objPtr->typePtr == &tclIntType) ||
-#ifndef TCL_WIDE_INT_IS_LONG
- (objPtr->typePtr == &tclWideIntType) ||
-#endif
(objPtr->typePtr == &tclBignumType)) {
break;
}
@@ -2294,11 +2272,12 @@ StringReptCmd(
return TCL_OK;
}
- if (TCL_OK != TclStringRepeat(interp, objv[1], count, &resultPtr)) {
- return TCL_ERROR;
+ resultPtr = TclStringRepeat(interp, objv[1], count, TCL_STRING_IN_PLACE);
+ if (resultPtr) {
+ Tcl_SetObjResult(interp, resultPtr);
+ return TCL_OK;
}
- Tcl_SetObjResult(interp, resultPtr);
- return TCL_OK;
+ return TCL_ERROR;
}
/*
@@ -2397,7 +2376,7 @@ StringRevCmd(
return TCL_ERROR;
}
- Tcl_SetObjResult(interp, TclStringObjReverse(objv[1]));
+ Tcl_SetObjResult(interp, TclStringReverse(objv[1], TCL_STRING_IN_PLACE));
return TCL_OK;
}
@@ -2846,7 +2825,6 @@ StringCatCmd(
int objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
{
- int code;
Tcl_Obj *objResultPtr;
if (objc < 2) {
@@ -2856,23 +2834,15 @@ StringCatCmd(
*/
return TCL_OK;
}
- if (objc == 2) {
- /*
- * Other trivial case, single arg, just return it.
- */
- Tcl_SetObjResult(interp, objv[1]);
- return TCL_OK;
- }
- code = TclStringCatObjv(interp, /* inPlace */ 1, objc-1, objv+1,
- &objResultPtr);
+ objResultPtr = TclStringCat(interp, objc-1, objv+1, TCL_STRING_IN_PLACE);
- if (code == TCL_OK) {
+ if (objResultPtr) {
Tcl_SetObjResult(interp, objResultPtr);
return TCL_OK;
}
- return code;
+ return TCL_ERROR;
}
/*
@@ -4310,7 +4280,7 @@ TclNRTryObjCmd(
}
info[0] = objv[i]; /* type */
- TclNewLongObj(info[1], code); /* returnCode */
+ TclNewIntObj(info[1], code); /* returnCode */
if (info[2] == NULL) { /* errorCodePrefix */
TclNewObj(info[2]);
}
diff --git a/generic/tclDecls.h b/generic/tclDecls.h
index 995878c..030b76e 100644
--- a/generic/tclDecls.h
+++ b/generic/tclDecls.h
@@ -3866,20 +3866,14 @@ extern const TclStubs *tclStubsPtr;
* possible. Tcl 9 must find a better solution, but that cannot be done
* without introducing a binary incompatibility.
*/
-# undef Tcl_DbNewLongObj
# undef Tcl_GetLongFromObj
-# undef Tcl_NewLongObj
-# undef Tcl_SetLongObj
# undef Tcl_ExprLong
# undef Tcl_ExprLongObj
# undef Tcl_UniCharNcmp
# undef Tcl_UtfNcmp
# undef Tcl_UtfNcasecmp
# undef Tcl_UniCharNcasecmp
-# define Tcl_DbNewLongObj ((Tcl_Obj*(*)(long,const char*,int))Tcl_DbNewWideIntObj)
# define Tcl_GetLongFromObj ((int(*)(Tcl_Interp*,Tcl_Obj*,long*))Tcl_GetWideIntFromObj)
-# define Tcl_NewLongObj ((Tcl_Obj*(*)(long))Tcl_NewWideIntObj)
-# define Tcl_SetLongObj ((void(*)(Tcl_Obj*,long))Tcl_SetWideIntObj)
# define Tcl_ExprLong TclExprLong
static inline int TclExprLong(Tcl_Interp *interp, const char *string, long *ptr){
int intValue;
@@ -3905,6 +3899,17 @@ extern const TclStubs *tclStubsPtr;
# endif
#endif
+#undef Tcl_NewLongObj
+#define Tcl_NewLongObj(value) Tcl_NewWideIntObj((long)(value))
+#undef Tcl_NewIntObj
+#define Tcl_NewIntObj(value) Tcl_NewWideIntObj((int)(value))
+#undef Tcl_DbNewLongObj
+#define Tcl_DbNewLongObj(value, file, line) Tcl_DbNewWideIntObj((long)(value), file, line)
+#undef Tcl_SetIntObj
+#define Tcl_SetIntObj(objPtr, value) Tcl_SetWideIntObj(objPtr, (int)(value))
+#undef Tcl_SetLongObj
+#define Tcl_SetLongObj(objPtr, value) Tcl_SetWideIntObj(objPtr, (long)(value))
+
/*
* Deprecated Tcl procedures:
*/
diff --git a/generic/tclDictObj.c b/generic/tclDictObj.c
index e9018db..0404b8d 100644
--- a/generic/tclDictObj.c
+++ b/generic/tclDictObj.c
@@ -2309,9 +2309,12 @@ DictAppendCmd(
if (objc == 4) {
appendObjPtr = objv[3];
- } else if (TCL_OK != TclStringCatObjv(interp, /* inPlace */ 1,
- objc-3, objv+3, &appendObjPtr)) {
- return TCL_ERROR;
+ } else {
+ appendObjPtr = TclStringCat(interp, objc-3, objv+3,
+ TCL_STRING_IN_PLACE);
+ if (appendObjPtr == NULL) {
+ return TCL_ERROR;
+ }
}
}
diff --git a/generic/tclDisassemble.c b/generic/tclDisassemble.c
index 3d95a0d..7181164 100644
--- a/generic/tclDisassemble.c
+++ b/generic/tclDisassemble.c
@@ -797,7 +797,7 @@ TclNewInstNameObj(
Tcl_Obj *objPtr = Tcl_NewObj();
objPtr->typePtr = &tclInstNameType;
- objPtr->internalRep.longValue = (long) inst;
+ objPtr->internalRep.wideValue = (long) inst;
objPtr->bytes = NULL;
return objPtr;
@@ -817,7 +817,7 @@ static void
UpdateStringOfInstName(
Tcl_Obj *objPtr)
{
- int inst = objPtr->internalRep.longValue;
+ int inst = objPtr->internalRep.wideValue;
char *s, buf[20];
int len;
@@ -825,7 +825,7 @@ UpdateStringOfInstName(
sprintf(buf, "inst_%d", inst);
s = buf;
} else {
- s = (char *) tclInstructionTable[objPtr->internalRep.longValue].name;
+ s = (char *) tclInstructionTable[objPtr->internalRep.wideValue].name;
}
len = strlen(s);
objPtr->bytes = ckalloc(len + 1);
diff --git a/generic/tclExecute.c b/generic/tclExecute.c
index 9b9c3fa..f82ee6f 100644
--- a/generic/tclExecute.c
+++ b/generic/tclExecute.c
@@ -267,7 +267,7 @@ VarHashCreateVar(
NEXT_INST_F(((condition)? TclGetInt4AtPtr(pc+1) : 5), (cleanup), 0); \
default: \
if ((condition) < 0) { \
- TclNewLongObj(objResultPtr, -1); \
+ TclNewIntObj(objResultPtr, -1); \
} else { \
objResultPtr = TCONST((condition) > 0); \
} \
@@ -288,7 +288,7 @@ VarHashCreateVar(
NEXT_INST_V(((condition)? TclGetInt4AtPtr(pc+1) : 5), (cleanup), 0); \
default: \
if ((condition) < 0) { \
- TclNewLongObj(objResultPtr, -1); \
+ TclNewIntObj(objResultPtr, -1); \
} else { \
objResultPtr = TCONST((condition) > 0); \
} \
@@ -299,7 +299,7 @@ VarHashCreateVar(
#define JUMP_PEEPHOLE_F(condition, pcAdjustment, cleanup) \
do{ \
if ((condition) < 0) { \
- TclNewLongObj(objResultPtr, -1); \
+ TclNewIntObj(objResultPtr, -1); \
} else { \
objResultPtr = TCONST((condition) > 0); \
} \
@@ -308,7 +308,7 @@ VarHashCreateVar(
#define JUMP_PEEPHOLE_V(condition, pcAdjustment, cleanup) \
do{ \
if ((condition) < 0) { \
- TclNewLongObj(objResultPtr, -1); \
+ TclNewIntObj(objResultPtr, -1); \
} else { \
objResultPtr = TCONST((condition) > 0); \
} \
@@ -440,28 +440,8 @@ VarHashCreateVar(
* ClientData *ptrPtr, int *tPtr);
*/
-#ifdef TCL_WIDE_INT_IS_LONG
#define GetNumberFromObj(interp, objPtr, ptrPtr, tPtr) \
(((objPtr)->typePtr == &tclIntType) \
- ? (*(tPtr) = TCL_NUMBER_LONG, \
- *(ptrPtr) = (ClientData) \
- (&((objPtr)->internalRep.longValue)), TCL_OK) : \
- ((objPtr)->typePtr == &tclDoubleType) \
- ? (((TclIsNaN((objPtr)->internalRep.doubleValue)) \
- ? (*(tPtr) = TCL_NUMBER_NAN) \
- : (*(tPtr) = TCL_NUMBER_DOUBLE)), \
- *(ptrPtr) = (ClientData) \
- (&((objPtr)->internalRep.doubleValue)), TCL_OK) : \
- (((objPtr)->bytes != NULL) && ((objPtr)->length == 0)) \
- ? TCL_ERROR : \
- TclGetNumberFromObj((interp), (objPtr), (ptrPtr), (tPtr)))
-#else /* !TCL_WIDE_INT_IS_LONG */
-#define GetNumberFromObj(interp, objPtr, ptrPtr, tPtr) \
- (((objPtr)->typePtr == &tclIntType) \
- ? (*(tPtr) = TCL_NUMBER_LONG, \
- *(ptrPtr) = (ClientData) \
- (&((objPtr)->internalRep.longValue)), TCL_OK) : \
- ((objPtr)->typePtr == &tclWideIntType) \
? (*(tPtr) = TCL_NUMBER_WIDE, \
*(ptrPtr) = (ClientData) \
(&((objPtr)->internalRep.wideValue)), TCL_OK) : \
@@ -474,7 +454,6 @@ VarHashCreateVar(
(((objPtr)->bytes != NULL) && ((objPtr)->length == 0)) \
? TCL_ERROR : \
TclGetNumberFromObj((interp), (objPtr), (ptrPtr), (tPtr)))
-#endif /* TCL_WIDE_INT_IS_LONG */
/*
* Macro used in this file to save a function call for common uses of
@@ -485,8 +464,9 @@ VarHashCreateVar(
*/
#define TclGetBooleanFromObj(interp, objPtr, boolPtr) \
- ((((objPtr)->typePtr == &tclIntType) \
- || ((objPtr)->typePtr == &tclBooleanType)) \
+ (((objPtr)->typePtr == &tclIntType) \
+ ? (*(boolPtr) = ((objPtr)->internalRep.wideValue!=0), TCL_OK) \
+ : ((objPtr)->typePtr == &tclBooleanType) \
? (*(boolPtr) = ((objPtr)->internalRep.longValue!=0), TCL_OK) \
: Tcl_GetBooleanFromObj((interp), (objPtr), (boolPtr)))
@@ -518,40 +498,6 @@ VarHashCreateVar(
* Auxiliary tables used to compute powers of small integers.
*/
-#if (LONG_MAX == 0x7fffffff)
-
-/*
- * Maximum base that, when raised to powers 2, 3, ... 8, fits in a 32-bit
- * signed integer.
- */
-
-static const long MaxBase32[] = {46340, 1290, 215, 73, 35, 21, 14};
-static const size_t MaxBase32Size = sizeof(MaxBase32)/sizeof(long);
-
-/*
- * Table giving 3, 4, ..., 11, raised to the powers 9, 10, ..., as far as they
- * fit in a 32-bit signed integer. Exp32Index[i] gives the starting index of
- * powers of i+3; Exp32Value[i] gives the corresponding powers.
- */
-
-static const unsigned short Exp32Index[] = {
- 0, 11, 18, 23, 26, 29, 31, 32, 33
-};
-static const size_t Exp32IndexSize =
- sizeof(Exp32Index) / sizeof(unsigned short);
-static const long Exp32Value[] = {
- 19683, 59049, 177147, 531441, 1594323, 4782969, 14348907, 43046721,
- 129140163, 387420489, 1162261467, 262144, 1048576, 4194304,
- 16777216, 67108864, 268435456, 1073741824, 1953125, 9765625,
- 48828125, 244140625, 1220703125, 10077696, 60466176, 362797056,
- 40353607, 282475249, 1977326743, 134217728, 1073741824, 387420489,
- 1000000000
-};
-static const size_t Exp32ValueSize = sizeof(Exp32Value)/sizeof(long);
-#endif /* LONG_MAX == 0x7fffffff -- 32 bit machine */
-
-#if (LONG_MAX > 0x7fffffff) || !defined(TCL_WIDE_INT_IS_LONG)
-
/*
* Maximum base that, when raised to powers 2, 3, ..., 16, fits in a
* Tcl_WideInt.
@@ -655,7 +601,6 @@ static const Tcl_WideInt Exp64Value[] = {
(Tcl_WideInt)371293*371293*371293*13*13
};
static const size_t Exp64ValueSize = sizeof(Exp64Value) / sizeof(Tcl_WideInt);
-#endif /* (LONG_MAX > 0x7fffffff) || !defined(TCL_WIDE_INT_IS_LONG) */
/*
* Markers for ExecuteExtendedBinaryMathOp.
@@ -848,9 +793,9 @@ TclCreateExecEnv(
+ (size_t) (size-1) * sizeof(Tcl_Obj *));
eePtr->execStackPtr = esPtr;
- TclNewLongObj(eePtr->constants[0], 0);
+ TclNewIntObj(eePtr->constants[0], 0);
Tcl_IncrRefCount(eePtr->constants[0]);
- TclNewLongObj(eePtr->constants[1], 1);
+ TclNewIntObj(eePtr->constants[1], 1);
Tcl_IncrRefCount(eePtr->constants[1]);
eePtr->interp = interp;
eePtr->callbackPtr = NULL;
@@ -1817,37 +1762,6 @@ TclIncrObj(
return TCL_ERROR;
}
- if ((type1 == TCL_NUMBER_LONG) && (type2 == TCL_NUMBER_LONG)) {
- long augend = *((const long *) ptr1);
- long addend = *((const long *) ptr2);
- long sum = augend + addend;
-
- /*
- * Overflow when (augend and sum have different sign) and (augend and
- * addend have the same sign). This is encapsulated in the Overflowing
- * macro.
- */
-
- if (!Overflowing(augend, addend, sum)) {
- TclSetLongObj(valuePtr, sum);
- return TCL_OK;
- }
-#ifndef TCL_WIDE_INT_IS_LONG
- {
- Tcl_WideInt w1 = (Tcl_WideInt) augend;
- Tcl_WideInt w2 = (Tcl_WideInt) addend;
-
- /*
- * We know the sum value is outside the long range, so we use the
- * macro form that doesn't range test again.
- */
-
- TclSetWideIntObj(valuePtr, w1 + w2);
- return TCL_OK;
- }
-#endif
- }
-
if ((type1 == TCL_NUMBER_DOUBLE) || (type1 == TCL_NUMBER_NAN)) {
/*
* Produce error message (reparse?!)
@@ -1865,7 +1779,6 @@ TclIncrObj(
return TCL_ERROR;
}
-#ifndef TCL_WIDE_INT_IS_LONG
if ((type1 != TCL_NUMBER_BIG) && (type2 != TCL_NUMBER_BIG)) {
Tcl_WideInt w1, w2, sum;
@@ -1878,11 +1791,10 @@ TclIncrObj(
*/
if (!Overflowing(w1, w2, sum)) {
- Tcl_SetWideIntObj(valuePtr, sum);
+ TclSetIntObj(valuePtr, sum);
return TCL_OK;
}
}
-#endif
Tcl_TakeBignumFromObj(interp, valuePtr, &value);
Tcl_GetBignumFromObj(interp, incrPtr, &incr);
@@ -2624,9 +2536,9 @@ TEBCresume(
case INST_STR_CONCAT1:
opnd = TclGetUInt1AtPtr(pc+1);
-
- if (TCL_OK != TclStringCatObjv(interp, /* inPlace */ 1,
- opnd, &OBJ_AT_DEPTH(opnd-1), &objResultPtr)) {
+ objResultPtr = TclStringCat(interp, opnd, &OBJ_AT_DEPTH(opnd-1),
+ TCL_STRING_IN_PLACE);
+ if (objResultPtr == NULL) {
TRACE_ERROR(interp);
goto gotError;
}
@@ -3481,9 +3393,7 @@ TEBCresume(
{
Tcl_Obj *incrPtr;
-#ifndef TCL_WIDE_INT_IS_LONG
Tcl_WideInt w;
-#endif
long increment;
case INST_INCR_SCALAR1:
@@ -3582,9 +3492,9 @@ TEBCresume(
objPtr = varPtr->value.objPtr;
if (GetNumberFromObj(NULL, objPtr, &ptr, &type) == TCL_OK) {
- if (type == TCL_NUMBER_LONG) {
- long augend = *((const long *)ptr);
- long sum = augend + increment;
+ if (type == TCL_NUMBER_WIDE) {
+ Tcl_WideInt augend = *((const Tcl_WideInt *)ptr);
+ Tcl_WideInt sum = augend + increment;
/*
* Overflow when (augend and sum have different sign) and
@@ -3596,16 +3506,15 @@ TEBCresume(
TRACE(("%u %ld => ", opnd, increment));
if (Tcl_IsShared(objPtr)) {
objPtr->refCount--; /* We know it's shared. */
- TclNewLongObj(objResultPtr, sum);
+ TclNewIntObj(objResultPtr, sum);
Tcl_IncrRefCount(objResultPtr);
varPtr->value.objPtr = objResultPtr;
} else {
objResultPtr = objPtr;
- TclSetLongObj(objPtr, sum);
+ TclSetIntObj(objPtr, sum);
}
goto doneIncr;
}
-#ifndef TCL_WIDE_INT_IS_LONG
w = (Tcl_WideInt)augend;
TRACE(("%u %ld => ", opnd, increment));
@@ -3622,44 +3531,10 @@ TEBCresume(
* use macro form that doesn't range test again.
*/
- TclSetWideIntObj(objPtr, w+increment);
+ TclSetIntObj(objPtr, w+increment);
}
goto doneIncr;
-#endif
- } /* end if (type == TCL_NUMBER_LONG) */
-#ifndef TCL_WIDE_INT_IS_LONG
- if (type == TCL_NUMBER_WIDE) {
- Tcl_WideInt sum;
-
- w = *((const Tcl_WideInt *) ptr);
- sum = w + increment;
-
- /*
- * Check for overflow.
- */
-
- if (!Overflowing(w, increment, sum)) {
- TRACE(("%u %ld => ", opnd, increment));
- if (Tcl_IsShared(objPtr)) {
- objPtr->refCount--; /* We know it's shared. */
- objResultPtr = Tcl_NewWideIntObj(sum);
- Tcl_IncrRefCount(objResultPtr);
- varPtr->value.objPtr = objResultPtr;
- } else {
- objResultPtr = objPtr;
-
- /*
- * We *do not* know the sum value is outside the
- * long range (wide + long can yield long); use
- * the function call that checks range.
- */
-
- Tcl_SetWideIntObj(objPtr, sum);
- }
- goto doneIncr;
- }
- }
-#endif
+ } /* end if (type == TCL_NUMBER_WIDE) */
}
if (Tcl_IsShared(objPtr)) {
objPtr->refCount--; /* We know it's shared */
@@ -3669,7 +3544,7 @@ TEBCresume(
} else {
objResultPtr = objPtr;
}
- TclNewLongObj(incrPtr, increment);
+ TclNewIntObj(incrPtr, increment);
if (TclIncrObj(interp, objResultPtr, incrPtr) != TCL_OK) {
Tcl_DecrRefCount(incrPtr);
TRACE_ERROR(interp);
@@ -3683,7 +3558,7 @@ TEBCresume(
* All other cases, flow through to generic handling.
*/
- TclNewLongObj(incrPtr, increment);
+ TclNewIntObj(incrPtr, increment);
Tcl_IncrRefCount(incrPtr);
doIncrScalar:
@@ -4381,7 +4256,7 @@ TEBCresume(
NEXT_INST_F(1, 0, 1);
}
case INST_INFO_LEVEL_NUM:
- TclNewLongObj(objResultPtr, iPtr->varFramePtr->level);
+ TclNewIntObj(objResultPtr, iPtr->varFramePtr->level);
TRACE_WITH_OBJ(("=> "), objResultPtr);
NEXT_INST_F(1, 0, 1);
case INST_INFO_LEVEL_ARGS: {
@@ -4750,7 +4625,7 @@ TEBCresume(
TRACE_ERROR(interp);
goto gotError;
}
- TclNewLongObj(objResultPtr, length);
+ TclNewIntObj(objResultPtr, length);
TRACE_APPEND(("%d\n", length));
NEXT_INST_F(1, 1, 1);
@@ -5221,7 +5096,7 @@ TEBCresume(
case INST_STR_LEN:
valuePtr = OBJ_AT_TOS;
length = Tcl_GetCharLength(valuePtr);
- TclNewLongObj(objResultPtr, length);
+ TclNewIntObj(objResultPtr, length);
TRACE(("\"%.20s\" => %d\n", O2S(valuePtr), length));
NEXT_INST_F(1, 1, 1);
@@ -5572,11 +5447,11 @@ TEBCresume(
NEXT_INST_V(1, 3, 1);
case INST_STR_FIND:
- match = TclStringFind(OBJ_UNDER_TOS, OBJ_AT_TOS, 0);
+ match = TclStringFirst(OBJ_UNDER_TOS, OBJ_AT_TOS, 0);
TRACE(("%.20s %.20s => %d\n",
O2S(OBJ_UNDER_TOS), O2S(OBJ_AT_TOS), match));
- TclNewLongObj(objResultPtr, match);
+ TclNewIntObj(objResultPtr, match);
NEXT_INST_F(1, 2, 1);
case INST_STR_FIND_LAST:
@@ -5584,7 +5459,7 @@ TEBCresume(
TRACE(("%.20s %.20s => %d\n",
O2S(OBJ_UNDER_TOS), O2S(OBJ_AT_TOS), match));
- TclNewLongObj(objResultPtr, match);
+ TclNewIntObj(objResultPtr, match);
NEXT_INST_F(1, 2, 1);
case INST_STR_CLASS:
@@ -5757,28 +5632,20 @@ TEBCresume(
{
ClientData ptr1, ptr2;
int type1, type2;
- long l1, l2, lResult;
+ Tcl_WideInt w1, w2, wResult;
case INST_NUM_TYPE:
if (GetNumberFromObj(NULL, OBJ_AT_TOS, &ptr1, &type1) != TCL_OK) {
type1 = 0;
- } else if (type1 == TCL_NUMBER_LONG) {
- /* value is between LONG_MIN and LONG_MAX */
- /* [string is integer] is -UINT_MAX to UINT_MAX range */
- int i;
-
- if (Tcl_GetIntFromObj(NULL, OBJ_AT_TOS, &i) != TCL_OK) {
- type1 = TCL_NUMBER_WIDE;
- }
-#ifndef TCL_WIDE_INT_IS_LONG
} else if (type1 == TCL_NUMBER_WIDE) {
/* value is between WIDE_MIN and WIDE_MAX */
+ /* [string is integer] is -UINT_MAX to UINT_MAX range */
/* [string is wideinteger] is -UWIDE_MAX to UWIDE_MAX range */
int i;
+
if (Tcl_GetIntFromObj(NULL, OBJ_AT_TOS, &i) == TCL_OK) {
type1 = TCL_NUMBER_LONG;
}
-#endif
} else if (type1 == TCL_NUMBER_BIG) {
/* value is an integer outside the WIDE_MIN to WIDE_MAX range */
/* [string is wideinteger] is -UWIDE_MAX to UWIDE_MAX range */
@@ -5788,7 +5655,7 @@ TEBCresume(
type1 = TCL_NUMBER_WIDE;
}
}
- TclNewLongObj(objResultPtr, type1);
+ TclNewIntObj(objResultPtr, type1);
TRACE(("\"%.20s\" => %d\n", O2S(OBJ_AT_TOS), type1));
NEXT_INST_F(1, 1, 1);
@@ -5823,10 +5690,10 @@ TEBCresume(
compare = MP_EQ;
goto convertComparison;
}
- if ((type1 == TCL_NUMBER_LONG) && (type2 == TCL_NUMBER_LONG)) {
- l1 = *((const long *)ptr1);
- l2 = *((const long *)ptr2);
- compare = (l1 < l2) ? MP_LT : ((l1 > l2) ? MP_GT : MP_EQ);
+ if ((type1 == TCL_NUMBER_WIDE) && (type2 == TCL_NUMBER_WIDE)) {
+ w1 = *((const Tcl_WideInt *)ptr1);
+ w2 = *((const Tcl_WideInt *)ptr2);
+ compare = (w1 < w2) ? MP_LT : ((w1 > w2) ? MP_GT : MP_EQ);
} else {
compare = TclCompareTwoNumbers(valuePtr, value2Ptr);
}
@@ -5902,17 +5769,17 @@ TEBCresume(
* Check for common, simple case.
*/
- if ((type1 == TCL_NUMBER_LONG) && (type2 == TCL_NUMBER_LONG)) {
- l1 = *((const long *)ptr1);
- l2 = *((const long *)ptr2);
+ if ((type1 == TCL_NUMBER_WIDE) && (type2 == TCL_NUMBER_WIDE)) {
+ w1 = *((const Tcl_WideInt *)ptr1);
+ w2 = *((const Tcl_WideInt *)ptr2);
switch (*pc) {
case INST_MOD:
- if (l2 == 0) {
+ if (w2 == 0) {
TRACE(("%s %s => DIVIDE BY ZERO\n", O2S(valuePtr),
O2S(value2Ptr)));
goto divideByZero;
- } else if ((l2 == 1) || (l2 == -1)) {
+ } else if ((w2 == 1) || (w2 == -1)) {
/*
* Div. by |1| always yields remainder of 0.
*/
@@ -5921,7 +5788,7 @@ TEBCresume(
objResultPtr = TCONST(0);
TRACE(("%s\n", O2S(objResultPtr)));
NEXT_INST_F(1, 2, 1);
- } else if (l1 == 0) {
+ } else if (w1 == 0) {
/*
* 0 % (non-zero) always yields remainder of 0.
*/
@@ -5931,24 +5798,24 @@ TEBCresume(
TRACE(("%s\n", O2S(objResultPtr)));
NEXT_INST_F(1, 2, 1);
} else {
- lResult = l1 / l2;
+ wResult = w1 / w2;
/*
* Force Tcl's integer division rules.
* TODO: examine for logic simplification
*/
- if ((lResult < 0 || (lResult == 0 &&
- ((l1 < 0 && l2 > 0) || (l1 > 0 && l2 < 0)))) &&
- (lResult * l2 != l1)) {
- lResult -= 1;
+ if ((wResult < 0 || (wResult == 0 &&
+ ((w1 < 0 && w2 > 0) || (w1 > 0 && w2 < 0)))) &&
+ (wResult * w2 != w1)) {
+ wResult -= 1;
}
- lResult = l1 - l2*lResult;
- goto longResultOfArithmetic;
+ wResult = w1 - w2*wResult;
+ goto wideResultOfArithmetic;
}
case INST_RSHIFT:
- if (l2 < 0) {
+ if (w2 < 0) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"negative shift argument", -1));
#ifdef ERROR_CODE_FOR_EARLY_DETECTED_ARITH_ERROR
@@ -5959,7 +5826,7 @@ TEBCresume(
CACHE_STACK_INFO();
#endif /* ERROR_CODE_FOR_EARLY_DETECTED_ARITH_ERROR */
goto gotError;
- } else if (l1 == 0) {
+ } else if (w1 == 0) {
TRACE(("%s %s => ", O2S(valuePtr), O2S(value2Ptr)));
objResultPtr = TCONST(0);
TRACE(("%s\n", O2S(objResultPtr)));
@@ -5969,7 +5836,7 @@ TEBCresume(
* Quickly force large right shifts to 0 or -1.
*/
- if (l2 >= (long)(CHAR_BIT*sizeof(long))) {
+ if (w2 >= (Tcl_WideInt)(CHAR_BIT*sizeof(long))) {
/*
* We assume that INT_MAX is much larger than the
* number of bits in a long. This is a pretty safe
@@ -5978,10 +5845,10 @@ TEBCresume(
*/
TRACE(("%s %s => ", O2S(valuePtr), O2S(value2Ptr)));
- if (l1 > 0L) {
+ if (w1 > 0L) {
objResultPtr = TCONST(0);
} else {
- TclNewLongObj(objResultPtr, -1);
+ TclNewIntObj(objResultPtr, -1);
}
TRACE(("%s\n", O2S(objResultPtr)));
NEXT_INST_F(1, 2, 1);
@@ -5991,12 +5858,12 @@ TEBCresume(
* Handle shifts within the native long range.
*/
- lResult = l1 >> ((int) l2);
- goto longResultOfArithmetic;
+ wResult = w1 >> ((int) w2);
+ goto wideResultOfArithmetic;
}
case INST_LSHIFT:
- if (l2 < 0) {
+ if (w2 < 0) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"negative shift argument", -1));
#ifdef ERROR_CODE_FOR_EARLY_DETECTED_ARITH_ERROR
@@ -6007,12 +5874,12 @@ TEBCresume(
CACHE_STACK_INFO();
#endif /* ERROR_CODE_FOR_EARLY_DETECTED_ARITH_ERROR */
goto gotError;
- } else if (l1 == 0) {
+ } else if (w1 == 0) {
TRACE(("%s %s => ", O2S(valuePtr), O2S(value2Ptr)));
objResultPtr = TCONST(0);
TRACE(("%s\n", O2S(objResultPtr)));
NEXT_INST_F(1, 2, 1);
- } else if (l2 > (long) INT_MAX) {
+ } else if (w2 > (Tcl_WideInt) INT_MAX) {
/*
* Technically, we could hold the value (1 << (INT_MAX+1))
* in an mp_int, but since we're using mp_mul_2d() to do
@@ -6030,17 +5897,17 @@ TEBCresume(
#endif /* ERROR_CODE_FOR_EARLY_DETECTED_ARITH_ERROR */
goto gotError;
} else {
- int shift = (int) l2;
+ int shift = (int) w2;
/*
* Handle shifts within the native long range.
*/
- if ((size_t) shift < CHAR_BIT*sizeof(long) && (l1 != 0)
- && !((l1>0 ? l1 : ~l1) &
+ if ((size_t) shift < CHAR_BIT*sizeof(long) && (w1 != 0)
+ && !((w1>0 ? w1 : ~w1) &
-(1L<<(CHAR_BIT*sizeof(long) - 1 - shift)))) {
- lResult = l1 << shift;
- goto longResultOfArithmetic;
+ wResult = w1 << shift;
+ goto wideResultOfArithmetic;
}
}
@@ -6052,23 +5919,14 @@ TEBCresume(
break;
case INST_BITAND:
- lResult = l1 & l2;
- goto longResultOfArithmetic;
+ wResult = w1 & w2;
+ goto wideResultOfArithmetic;
case INST_BITOR:
- lResult = l1 | l2;
- goto longResultOfArithmetic;
+ wResult = w1 | w2;
+ goto wideResultOfArithmetic;
case INST_BITXOR:
- lResult = l1 ^ l2;
- longResultOfArithmetic:
- TRACE(("%s %s => ", O2S(valuePtr), O2S(value2Ptr)));
- if (Tcl_IsShared(valuePtr)) {
- TclNewLongObj(objResultPtr, lResult);
- TRACE(("%s\n", O2S(objResultPtr)));
- NEXT_INST_F(1, 2, 1);
- }
- TclSetLongObj(valuePtr, lResult);
- TRACE(("%s\n", O2S(valuePtr)));
- NEXT_INST_F(1, 1, 0);
+ wResult = w1 ^ w2;
+ goto wideResultOfArithmetic;
}
}
@@ -6151,18 +6009,13 @@ TEBCresume(
* an external function.
*/
- if ((type1 == TCL_NUMBER_LONG) && (type2 == TCL_NUMBER_LONG)) {
- Tcl_WideInt w1, w2, wResult;
-
- l1 = *((const long *)ptr1);
- l2 = *((const long *)ptr2);
+ if ((type1 == TCL_NUMBER_WIDE) && (type2 == TCL_NUMBER_WIDE)) {
+ w1 = *((const Tcl_WideInt *)ptr1);
+ w2 = *((const Tcl_WideInt *)ptr2);
switch (*pc) {
case INST_ADD:
- w1 = (Tcl_WideInt) l1;
- w2 = (Tcl_WideInt) l2;
wResult = w1 + w2;
-#ifdef TCL_WIDE_INT_IS_LONG
/*
* Check for overflow.
*/
@@ -6170,14 +6023,10 @@ TEBCresume(
if (Overflowing(w1, w2, wResult)) {
goto overflow;
}
-#endif
goto wideResultOfArithmetic;
case INST_SUB:
- w1 = (Tcl_WideInt) l1;
- w2 = (Tcl_WideInt) l2;
wResult = w1 - w2;
-#ifdef TCL_WIDE_INT_IS_LONG
/*
* Must check for overflow. The macro tests for overflows in
* sums by looking at the sign bits. As we have a subtraction
@@ -6191,7 +6040,6 @@ TEBCresume(
if (Overflowing(w1, ~w2, wResult)) {
goto overflow;
}
-#endif
wideResultOfArithmetic:
TRACE(("%s %s => ", O2S(valuePtr), O2S(value2Ptr)));
if (Tcl_IsShared(valuePtr)) {
@@ -6199,45 +6047,45 @@ TEBCresume(
TRACE(("%s\n", O2S(objResultPtr)));
NEXT_INST_F(1, 2, 1);
}
- Tcl_SetWideIntObj(valuePtr, wResult);
+ TclSetIntObj(valuePtr, wResult);
TRACE(("%s\n", O2S(valuePtr)));
NEXT_INST_F(1, 1, 0);
case INST_DIV:
- if (l2 == 0) {
+ if (w2 == 0) {
TRACE(("%s %s => DIVIDE BY ZERO\n",
O2S(valuePtr), O2S(value2Ptr)));
goto divideByZero;
- } else if ((l1 == LONG_MIN) && (l2 == -1)) {
+ } else if ((w1 == LLONG_MIN) && (w2 == -1)) {
/*
- * Can't represent (-LONG_MIN) as a long.
+ * Can't represent (-LLONG_MIN) as a long.
*/
goto overflow;
}
- lResult = l1 / l2;
+ wResult = w1 / w2;
/*
* Force Tcl's integer division rules.
* TODO: examine for logic simplification
*/
- if (((lResult < 0) || ((lResult == 0) &&
- ((l1 < 0 && l2 > 0) || (l1 > 0 && l2 < 0)))) &&
- ((lResult * l2) != l1)) {
- lResult -= 1;
+ if (((wResult < 0) || ((wResult == 0) &&
+ ((w1 < 0 && w2 > 0) || (w1 > 0 && w2 < 0)))) &&
+ ((wResult * w2) != w1)) {
+ wResult -= 1;
}
- goto longResultOfArithmetic;
+ goto wideResultOfArithmetic;
case INST_MULT:
if (((sizeof(long) >= 2*sizeof(int))
- && (l1 <= INT_MAX) && (l1 >= INT_MIN)
- && (l2 <= INT_MAX) && (l2 >= INT_MIN))
+ && (w1 <= INT_MAX) && (w1 >= INT_MIN)
+ && (w2 <= INT_MAX) && (w2 >= INT_MIN))
|| ((sizeof(long) >= 2*sizeof(short))
- && (l1 <= SHRT_MAX) && (l1 >= SHRT_MIN)
- && (l2 <= SHRT_MAX) && (l2 >= SHRT_MIN))) {
- lResult = l1 * l2;
- goto longResultOfArithmetic;
+ && (w1 <= SHRT_MAX) && (w1 >= SHRT_MIN)
+ && (w2 <= SHRT_MAX) && (w2 >= SHRT_MIN))) {
+ wResult = w1 * w2;
+ goto wideResultOfArithmetic;
}
}
@@ -6304,14 +6152,14 @@ TEBCresume(
CACHE_STACK_INFO();
goto gotError;
}
- if (type1 == TCL_NUMBER_LONG) {
- l1 = *((const long *) ptr1);
+ if (type1 == TCL_NUMBER_WIDE) {
+ w1 = *((const Tcl_WideInt *) ptr1);
if (Tcl_IsShared(valuePtr)) {
- TclNewLongObj(objResultPtr, ~l1);
+ TclNewIntObj(objResultPtr, ~w1);
TRACE_APPEND(("%s\n", O2S(objResultPtr)));
NEXT_INST_F(1, 1, 1);
}
- TclSetLongObj(valuePtr, ~l1);
+ TclSetIntObj(valuePtr, ~w1);
TRACE_APPEND(("%s\n", O2S(valuePtr)));
NEXT_INST_F(1, 0, 0);
}
@@ -6341,15 +6189,15 @@ TEBCresume(
/* -NaN => NaN */
TRACE_APPEND(("%s\n", O2S(valuePtr)));
NEXT_INST_F(1, 0, 0);
- case TCL_NUMBER_LONG:
- l1 = *((const long *) ptr1);
- if (l1 != LONG_MIN) {
+ case TCL_NUMBER_WIDE:
+ w1 = *((const Tcl_WideInt *) ptr1);
+ if (w1 != LLONG_MIN) {
if (Tcl_IsShared(valuePtr)) {
- TclNewLongObj(objResultPtr, -l1);
+ TclNewIntObj(objResultPtr, -w1);
TRACE_APPEND(("%s\n", O2S(objResultPtr)));
NEXT_INST_F(1, 1, 1);
}
- TclSetLongObj(valuePtr, -l1);
+ TclSetIntObj(valuePtr, -w1);
TRACE_APPEND(("%s\n", O2S(valuePtr)));
NEXT_INST_F(1, 0, 0);
}
@@ -6510,10 +6358,10 @@ TEBCresume(
oldValuePtr = iterVarPtr->value.objPtr;
if (oldValuePtr == NULL) {
- TclNewLongObj(iterVarPtr->value.objPtr, -1);
+ TclNewIntObj(iterVarPtr->value.objPtr, -1);
Tcl_IncrRefCount(iterVarPtr->value.objPtr);
} else {
- TclSetLongObj(oldValuePtr, -1);
+ TclSetIntObj(oldValuePtr, -1);
}
TRACE(("%u => loop iter count temp %d\n", opnd, iterTmpIndex));
@@ -6547,8 +6395,8 @@ TEBCresume(
iterVarPtr = LOCAL(infoPtr->loopCtTemp);
valuePtr = iterVarPtr->value.objPtr;
- iterNum = valuePtr->internalRep.longValue + 1;
- TclSetLongObj(valuePtr, iterNum);
+ iterNum = valuePtr->internalRep.wideValue + 1;
+ TclSetIntObj(valuePtr, iterNum);
/*
* Check whether all value lists are exhausted and we should stop the
@@ -6881,7 +6729,7 @@ TEBCresume(
NEXT_INST_F(1, 0, -1);
case INST_PUSH_RETURN_CODE:
- TclNewLongObj(objResultPtr, result);
+ TclNewIntObj(objResultPtr, result);
TRACE(("=> %u\n", result));
NEXT_INST_F(1, 0, 1);
@@ -7547,7 +7395,6 @@ TEBCresume(
default:
Tcl_Panic("clockRead instruction with unknown clock#");
}
- /* TclNewWideObj(objResultPtr, wval); doesn't exist */
objResultPtr = Tcl_NewWideIntObj(wval);
TRACE_WITH_OBJ(("=> "), objResultPtr);
NEXT_INST_F(2, 0, 1);
@@ -7979,19 +7826,11 @@ ExecuteExtendedBinaryMathOp(
Tcl_Obj *valuePtr, /* The first operand on the stack. */
Tcl_Obj *value2Ptr) /* The second operand on the stack. */
{
-#define LONG_RESULT(l) \
- if (Tcl_IsShared(valuePtr)) { \
- TclNewLongObj(objResultPtr, l); \
- return objResultPtr; \
- } else { \
- Tcl_SetLongObj(valuePtr, l); \
- return NULL; \
- }
#define WIDE_RESULT(w) \
if (Tcl_IsShared(valuePtr)) { \
return Tcl_NewWideIntObj(w); \
} else { \
- Tcl_SetWideIntObj(valuePtr, w); \
+ TclSetIntObj(valuePtr, w); \
return NULL; \
}
#define BIG_RESULT(b) \
@@ -8013,7 +7852,6 @@ ExecuteExtendedBinaryMathOp(
int type1, type2;
ClientData ptr1, ptr2;
double d1, d2, dResult;
- long l1, l2, lResult;
Tcl_WideInt w1, w2, wResult;
mp_int big1, big2, bigResult, bigRemainder;
Tcl_Obj *objResultPtr;
@@ -8027,13 +7865,13 @@ ExecuteExtendedBinaryMathOp(
case INST_MOD:
/* TODO: Attempts to re-use unshared operands on stack */
- l2 = 0; /* silence gcc warning */
- if (type2 == TCL_NUMBER_LONG) {
- l2 = *((const long *)ptr2);
- if (l2 == 0) {
+ w2 = 0; /* silence gcc warning */
+ if (type2 == TCL_NUMBER_WIDE) {
+ w2 = *((const Tcl_WideInt *)ptr2);
+ if (w2 == 0) {
return DIVIDED_BY_ZERO;
}
- if ((l2 == 1) || (l2 == -1)) {
+ if ((w2 == 1) || (w2 == -1)) {
/*
* Div. by |1| always yields remainder of 0.
*/
@@ -8041,7 +7879,6 @@ ExecuteExtendedBinaryMathOp(
return constants[0];
}
}
-#ifndef TCL_WIDE_INT_IS_LONG
if (type1 == TCL_NUMBER_WIDE) {
w1 = *((const Tcl_WideInt *)ptr1);
if (type2 != TCL_NUMBER_BIG) {
@@ -8086,7 +7923,6 @@ ExecuteExtendedBinaryMathOp(
mp_clear(&big2);
return NULL;
}
-#endif
Tcl_GetBignumFromObj(NULL, valuePtr, &big1);
Tcl_GetBignumFromObj(NULL, value2Ptr, &big2);
mp_init(&bigResult);
@@ -8113,14 +7949,9 @@ ExecuteExtendedBinaryMathOp(
*/
switch (type2) {
- case TCL_NUMBER_LONG:
- invalid = (*((const long *)ptr2) < 0L);
- break;
-#ifndef TCL_WIDE_INT_IS_LONG
case TCL_NUMBER_WIDE:
invalid = (*((const Tcl_WideInt *)ptr2) < (Tcl_WideInt)0);
break;
-#endif
case TCL_NUMBER_BIG:
Tcl_TakeBignumFromObj(NULL, value2Ptr, &big2);
invalid = (mp_cmp_d(&big2, 0) == MP_LT);
@@ -8140,7 +7971,7 @@ ExecuteExtendedBinaryMathOp(
* Zero shifted any number of bits is still zero.
*/
- if ((type1==TCL_NUMBER_LONG) && (*((const long *)ptr1) == (long)0)) {
+ if ((type1==TCL_NUMBER_WIDE) && (*((const Tcl_WideInt *)ptr1) == (Tcl_WideInt)0)) {
return constants[0];
}
@@ -8153,8 +7984,8 @@ ExecuteExtendedBinaryMathOp(
* counterparts, leading to incorrect results.
*/
- if ((type2 != TCL_NUMBER_LONG)
- || (*((const long *)ptr2) > (long) INT_MAX)) {
+ if ((type2 != TCL_NUMBER_WIDE)
+ || (*((const Tcl_WideInt *)ptr2) > (long) INT_MAX)) {
/*
* Technically, we could hold the value (1 << (INT_MAX+1)) in
* an mp_int, but since we're using mp_mul_2d() to do the
@@ -8166,7 +7997,7 @@ ExecuteExtendedBinaryMathOp(
"integer value too large to represent", -1));
return GENERAL_ARITHMETIC_ERROR;
}
- shift = (int)(*((const long *)ptr2));
+ shift = (int)(*((const Tcl_WideInt *)ptr2));
/*
* Handle shifts within the native wide range.
@@ -8186,8 +8017,8 @@ ExecuteExtendedBinaryMathOp(
* Quickly force large right shifts to 0 or -1.
*/
- if ((type2 != TCL_NUMBER_LONG)
- || (*(const long *)ptr2 > INT_MAX)) {
+ if ((type2 != TCL_NUMBER_WIDE)
+ || (*(const Tcl_WideInt *)ptr2 > INT_MAX)) {
/*
* Again, technically, the value to be shifted could be an
* mp_int so huge that a right shift by (INT_MAX+1) bits could
@@ -8197,14 +8028,9 @@ ExecuteExtendedBinaryMathOp(
*/
switch (type1) {
- case TCL_NUMBER_LONG:
- zero = (*(const long *)ptr1 > 0L);
- break;
-#ifndef TCL_WIDE_INT_IS_LONG
case TCL_NUMBER_WIDE:
zero = (*(const Tcl_WideInt *)ptr1 > (Tcl_WideInt)0);
break;
-#endif
case TCL_NUMBER_BIG:
Tcl_TakeBignumFromObj(NULL, valuePtr, &big1);
zero = (mp_cmp_d(&big1, 0) == MP_GT);
@@ -8217,11 +8043,10 @@ ExecuteExtendedBinaryMathOp(
if (zero) {
return constants[0];
}
- LONG_RESULT(-1);
+ WIDE_RESULT(-1);
}
- shift = (int)(*(const long *)ptr2);
+ shift = (int)(*(const Tcl_WideInt *)ptr2);
-#ifndef TCL_WIDE_INT_IS_LONG
/*
* Handle shifts within the native wide range.
*/
@@ -8232,11 +8057,10 @@ ExecuteExtendedBinaryMathOp(
if (w1 >= (Tcl_WideInt)0) {
return constants[0];
}
- LONG_RESULT(-1);
+ WIDE_RESULT(-1);
}
WIDE_RESULT(w1 >> shift);
}
-#endif
}
Tcl_TakeBignumFromObj(NULL, valuePtr, &big1);
@@ -8404,7 +8228,6 @@ ExecuteExtendedBinaryMathOp(
BIG_RESULT(&bigResult);
}
-#ifndef TCL_WIDE_INT_IS_LONG
if ((type1 == TCL_NUMBER_WIDE) || (type2 == TCL_NUMBER_WIDE)) {
TclGetWideIntFromObj(NULL, valuePtr, &w1);
TclGetWideIntFromObj(NULL, value2Ptr, &w2);
@@ -8425,25 +8248,24 @@ ExecuteExtendedBinaryMathOp(
}
WIDE_RESULT(wResult);
}
-#endif
- l1 = *((const long *)ptr1);
- l2 = *((const long *)ptr2);
+ w1 = *((const Tcl_WideInt *)ptr1);
+ w2 = *((const Tcl_WideInt *)ptr2);
switch (opcode) {
case INST_BITAND:
- lResult = l1 & l2;
+ wResult = w1 & w2;
break;
case INST_BITOR:
- lResult = l1 | l2;
+ wResult = w1 | w2;
break;
case INST_BITXOR:
- lResult = l1 ^ l2;
+ wResult = w1 ^ w2;
break;
default:
/* Unused, here to silence compiler warning. */
- lResult = 0;
+ wResult = 0;
}
- LONG_RESULT(lResult);
+ WIDE_RESULT(wResult);
case INST_EXPON: {
int oddExponent = 0, negativeExponent = 0;
@@ -8459,16 +8281,16 @@ ExecuteExtendedBinaryMathOp(
dResult = pow(d1, d2);
goto doubleResult;
}
- l1 = l2 = 0;
- if (type2 == TCL_NUMBER_LONG) {
- l2 = *((const long *) ptr2);
- if (l2 == 0) {
+ w2 = 0;
+ if (type2 == TCL_NUMBER_WIDE) {
+ w2 = *((const Tcl_WideInt *) ptr2);
+ if (w2 == 0) {
/*
* Anything to the zero power is 1.
*/
return constants[1];
- } else if (l2 == 1) {
+ } else if (w2 == 1) {
/*
* Anything to the first power is itself
*/
@@ -8478,17 +8300,11 @@ ExecuteExtendedBinaryMathOp(
}
switch (type2) {
- case TCL_NUMBER_LONG:
- negativeExponent = (l2 < 0);
- oddExponent = (int) (l2 & 1);
- break;
-#ifndef TCL_WIDE_INT_IS_LONG
case TCL_NUMBER_WIDE:
w2 = *((const Tcl_WideInt *)ptr2);
negativeExponent = (w2 < 0);
oddExponent = (int) (w2 & (Tcl_WideInt)1);
break;
-#endif
case TCL_NUMBER_BIG:
Tcl_TakeBignumFromObj(NULL, value2Ptr, &big2);
negativeExponent = (mp_cmp_d(&big2, 0) == MP_LT);
@@ -8498,12 +8314,12 @@ ExecuteExtendedBinaryMathOp(
break;
}
- if (type1 == TCL_NUMBER_LONG) {
- l1 = *((const long *)ptr1);
+ if (type1 == TCL_NUMBER_WIDE) {
+ w1 = *((const Tcl_WideInt *)ptr1);
}
if (negativeExponent) {
- if (type1 == TCL_NUMBER_LONG) {
- switch (l1) {
+ if (type1 == TCL_NUMBER_WIDE) {
+ switch (w1) {
case 0:
/*
* Zero to a negative power is div by zero error.
@@ -8512,7 +8328,7 @@ ExecuteExtendedBinaryMathOp(
return EXPONENT_OF_ZERO;
case -1:
if (oddExponent) {
- LONG_RESULT(-1);
+ WIDE_RESULT(-1);
}
/* fallthrough */
case 1:
@@ -8532,8 +8348,8 @@ ExecuteExtendedBinaryMathOp(
return constants[0];
}
- if (type1 == TCL_NUMBER_LONG) {
- switch (l1) {
+ if (type1 == TCL_NUMBER_WIDE) {
+ switch (w1) {
case 0:
/*
* Zero to a positive power is zero.
@@ -8550,7 +8366,7 @@ ExecuteExtendedBinaryMathOp(
if (!oddExponent) {
return constants[1];
}
- LONG_RESULT(-1);
+ WIDE_RESULT(-1);
}
}
@@ -8559,141 +8375,58 @@ ExecuteExtendedBinaryMathOp(
* which means the max exponent value is 2**28-1 = 0x0fffffff =
* 268435455, which fits into a signed 32 bit int which is within the
* range of the long int type. This means any numeric Tcl_Obj value
- * not using TCL_NUMBER_LONG type must hold a value larger than we
+ * not using TCL_NUMBER_WIDE type must hold a value larger than we
* accept.
*/
- if (type2 != TCL_NUMBER_LONG) {
+ if (type2 != TCL_NUMBER_WIDE) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"exponent too large", -1));
return GENERAL_ARITHMETIC_ERROR;
}
- if (type1 == TCL_NUMBER_LONG) {
- if (l1 == 2) {
+ if (type1 == TCL_NUMBER_WIDE) {
+ if (w1 == 2) {
/*
* Reduce small powers of 2 to shifts.
*/
- if ((unsigned long) l2 < CHAR_BIT * sizeof(long) - 1) {
- LONG_RESULT(1L << l2);
+ if ((Tcl_WideUInt) w2 < (Tcl_WideUInt) CHAR_BIT*sizeof(Tcl_WideInt) - 1) {
+ WIDE_RESULT(((Tcl_WideInt) 1) << (int)w2);
}
-#if !defined(TCL_WIDE_INT_IS_LONG)
- if ((unsigned long)l2 < CHAR_BIT*sizeof(Tcl_WideInt) - 1) {
- WIDE_RESULT(((Tcl_WideInt) 1) << l2);
- }
-#endif
goto overflowExpon;
}
- if (l1 == -2) {
+ if (w1 == -2) {
int signum = oddExponent ? -1 : 1;
/*
* Reduce small powers of 2 to shifts.
*/
- if ((unsigned long) l2 < CHAR_BIT * sizeof(long) - 1) {
- LONG_RESULT(signum * (1L << l2));
+ if ((Tcl_WideUInt)w2 < CHAR_BIT*sizeof(Tcl_WideInt) - 1){
+ WIDE_RESULT(signum * (((Tcl_WideInt) 1) << (int) w2));
}
-#if !defined(TCL_WIDE_INT_IS_LONG)
- if ((unsigned long)l2 < CHAR_BIT*sizeof(Tcl_WideInt) - 1){
- WIDE_RESULT(signum * (((Tcl_WideInt) 1) << l2));
- }
-#endif
goto overflowExpon;
}
-#if (LONG_MAX == 0x7fffffff)
- if (l2 - 2 < (long)MaxBase32Size
- && l1 <= MaxBase32[l2 - 2]
- && l1 >= -MaxBase32[l2 - 2]) {
- /*
- * Small powers of 32-bit integers.
- */
-
- lResult = l1 * l1; /* b**2 */
- switch (l2) {
- case 2:
- break;
- case 3:
- lResult *= l1; /* b**3 */
- break;
- case 4:
- lResult *= lResult; /* b**4 */
- break;
- case 5:
- lResult *= lResult; /* b**4 */
- lResult *= l1; /* b**5 */
- break;
- case 6:
- lResult *= l1; /* b**3 */
- lResult *= lResult; /* b**6 */
- break;
- case 7:
- lResult *= l1; /* b**3 */
- lResult *= lResult; /* b**6 */
- lResult *= l1; /* b**7 */
- break;
- case 8:
- lResult *= lResult; /* b**4 */
- lResult *= lResult; /* b**8 */
- break;
- }
- LONG_RESULT(lResult);
- }
-
- if (l1 - 3 >= 0 && l1 -2 < (long)Exp32IndexSize
- && l2 - 2 < (long)(Exp32ValueSize + MaxBase32Size)) {
- base = Exp32Index[l1 - 3]
- + (unsigned short) (l2 - 2 - MaxBase32Size);
- if (base < Exp32Index[l1 - 2]) {
- /*
- * 32-bit number raised to intermediate power, done by
- * table lookup.
- */
-
- LONG_RESULT(Exp32Value[base]);
- }
- }
- if (-l1 - 3 >= 0 && -l1 - 2 < (long)Exp32IndexSize
- && l2 - 2 < (long)(Exp32ValueSize + MaxBase32Size)) {
- base = Exp32Index[-l1 - 3]
- + (unsigned short) (l2 - 2 - MaxBase32Size);
- if (base < Exp32Index[-l1 - 2]) {
- /*
- * 32-bit number raised to intermediate power, done by
- * table lookup.
- */
-
- lResult = (oddExponent) ?
- -Exp32Value[base] : Exp32Value[base];
- LONG_RESULT(lResult);
- }
- }
-#endif
}
-#if (LONG_MAX > 0x7fffffff) || !defined(TCL_WIDE_INT_IS_LONG)
- if (type1 == TCL_NUMBER_LONG) {
- w1 = l1;
-#ifndef TCL_WIDE_INT_IS_LONG
- } else if (type1 == TCL_NUMBER_WIDE) {
+ if (type1 == TCL_NUMBER_WIDE) {
w1 = *((const Tcl_WideInt *) ptr1);
-#endif
} else {
goto overflowExpon;
}
- if (l2 - 2 < (long)MaxBase64Size
- && w1 <= MaxBase64[l2 - 2]
- && w1 >= -MaxBase64[l2 - 2]) {
+ if (w2 - 2 < (long)MaxBase64Size
+ && w1 <= MaxBase64[w2 - 2]
+ && w1 >= -MaxBase64[w2 - 2]) {
/*
* Small powers of integers whose result is wide.
*/
wResult = w1 * w1; /* b**2 */
- switch (l2) {
+ switch (w2) {
case 2:
break;
case 3:
- wResult *= l1; /* b**3 */
+ wResult *= w1; /* b**3 */
break;
case 4:
wResult *= wResult; /* b**4 */
@@ -8770,9 +8503,9 @@ ExecuteExtendedBinaryMathOp(
*/
if (w1 - 3 >= 0 && w1 - 2 < (long)Exp64IndexSize
- && l2 - 2 < (long)(Exp64ValueSize + MaxBase64Size)) {
+ && w2 - 2 < (long)(Exp64ValueSize + MaxBase64Size)) {
base = Exp64Index[w1 - 3]
- + (unsigned short) (l2 - 2 - MaxBase64Size);
+ + (unsigned short) (w2 - 2 - MaxBase64Size);
if (base < Exp64Index[w1 - 2]) {
/*
* 64-bit number raised to intermediate power, done by
@@ -8784,9 +8517,9 @@ ExecuteExtendedBinaryMathOp(
}
if (-w1 - 3 >= 0 && -w1 - 2 < (long)Exp64IndexSize
- && l2 - 2 < (long)(Exp64ValueSize + MaxBase64Size)) {
+ && w2 - 2 < (long)(Exp64ValueSize + MaxBase64Size)) {
base = Exp64Index[-w1 - 3]
- + (unsigned short) (l2 - 2 - MaxBase64Size);
+ + (unsigned short) (w2 - 2 - MaxBase64Size);
if (base < Exp64Index[-w1 - 2]) {
/*
* 64-bit number raised to intermediate power, done by
@@ -8797,7 +8530,6 @@ ExecuteExtendedBinaryMathOp(
WIDE_RESULT(wResult);
}
}
-#endif
overflowExpon:
Tcl_TakeBignumFromObj(NULL, value2Ptr, &big2);
@@ -8877,9 +8609,7 @@ ExecuteExtendedBinaryMathOp(
switch (opcode) {
case INST_ADD:
wResult = w1 + w2;
-#ifndef TCL_WIDE_INT_IS_LONG
if ((type1 == TCL_NUMBER_WIDE) || (type2 == TCL_NUMBER_WIDE))
-#endif
{
/*
* Check for overflow.
@@ -8893,9 +8623,7 @@ ExecuteExtendedBinaryMathOp(
case INST_SUB:
wResult = w1 - w2;
-#ifndef TCL_WIDE_INT_IS_LONG
if ((type1 == TCL_NUMBER_WIDE) || (type2 == TCL_NUMBER_WIDE))
-#endif
{
/*
* Must check for overflow. The macro tests for overflows
@@ -8915,8 +8643,7 @@ ExecuteExtendedBinaryMathOp(
break;
case INST_MULT:
- if ((type1 != TCL_NUMBER_LONG) || (type2 != TCL_NUMBER_LONG)
- || (sizeof(Tcl_WideInt) < 2*sizeof(long))) {
+ if ((w1 < INT_MIN) || (w1 > INT_MAX) || (w2 < INT_MIN) || (w2 > INT_MAX)) {
goto overflowBasic;
}
wResult = w1 * w2;
@@ -9019,12 +8746,10 @@ ExecuteExtendedUnaryMathOp(
switch (opcode) {
case INST_BITNOT:
-#ifndef TCL_WIDE_INT_IS_LONG
if (type == TCL_NUMBER_WIDE) {
w = *((const Tcl_WideInt *) ptr);
WIDE_RESULT(~w);
}
-#endif
Tcl_TakeBignumFromObj(NULL, valuePtr, &big);
/* ~a = - a - 1 */
mp_neg(&big, &big);
@@ -9034,14 +8759,6 @@ ExecuteExtendedUnaryMathOp(
switch (type) {
case TCL_NUMBER_DOUBLE:
DOUBLE_RESULT(-(*((const double *) ptr)));
- case TCL_NUMBER_LONG:
- w = (Tcl_WideInt) (*((const long *) ptr));
- if (w != LLONG_MIN) {
- WIDE_RESULT(-w);
- }
- TclInitBignumFromLong(&big, *(const long *) ptr);
- break;
-#ifndef TCL_WIDE_INT_IS_LONG
case TCL_NUMBER_WIDE:
w = *((const Tcl_WideInt *) ptr);
if (w != LLONG_MIN) {
@@ -9049,7 +8766,6 @@ ExecuteExtendedUnaryMathOp(
}
TclInitBignumFromWideInt(&big, w);
break;
-#endif
default:
Tcl_TakeBignumFromObj(NULL, valuePtr, &big);
}
@@ -9060,7 +8776,6 @@ ExecuteExtendedUnaryMathOp(
Tcl_Panic("unexpected opcode");
return NULL;
}
-#undef LONG_RESULT
#undef WIDE_RESULT
#undef BIG_RESULT
#undef DOUBLE_RESULT
@@ -9092,31 +8807,22 @@ TclCompareTwoNumbers(
ClientData ptr1, ptr2;
mp_int big1, big2;
double d1, d2, tmp;
- long l1, l2;
-#ifndef TCL_WIDE_INT_IS_LONG
Tcl_WideInt w1, w2;
-#endif
(void) GetNumberFromObj(NULL, valuePtr, &ptr1, &type1);
(void) GetNumberFromObj(NULL, value2Ptr, &ptr2, &type2);
switch (type1) {
- case TCL_NUMBER_LONG:
- l1 = *((const long *)ptr1);
+ case TCL_NUMBER_WIDE:
+ w1 = *((const Tcl_WideInt *)ptr1);
switch (type2) {
- case TCL_NUMBER_LONG:
- l2 = *((const long *)ptr2);
- longCompare:
- return (l1 < l2) ? MP_LT : ((l1 > l2) ? MP_GT : MP_EQ);
-#ifndef TCL_WIDE_INT_IS_LONG
case TCL_NUMBER_WIDE:
w2 = *((const Tcl_WideInt *)ptr2);
- w1 = (Tcl_WideInt)l1;
- goto wideCompare;
-#endif
+ wideCompare:
+ return (w1 < w2) ? MP_LT : ((w1 > w2) ? MP_GT : MP_EQ);
case TCL_NUMBER_DOUBLE:
d2 = *((const double *)ptr2);
- d1 = (double) l1;
+ d1 = (double) w1;
/*
* If the double has a fractional part, or if the long can be
@@ -9124,7 +8830,7 @@ TclCompareTwoNumbers(
* doubles.
*/
- if (DBL_MANT_DIG > CHAR_BIT*sizeof(long) || l1 == (long) d1
+ if (DBL_MANT_DIG > CHAR_BIT*sizeof(Tcl_WideInt) || w1 == (Tcl_WideInt) d1
|| modf(d2, &tmp) != 0.0) {
goto doubleCompare;
}
@@ -9147,44 +8853,6 @@ TclCompareTwoNumbers(
if (d2 > (double)LONG_MAX) {
return MP_LT;
}
- l2 = (long) d2;
- goto longCompare;
- case TCL_NUMBER_BIG:
- Tcl_TakeBignumFromObj(NULL, value2Ptr, &big2);
- if (mp_cmp_d(&big2, 0) == MP_LT) {
- compare = MP_GT;
- } else {
- compare = MP_LT;
- }
- mp_clear(&big2);
- return compare;
- }
-
-#ifndef TCL_WIDE_INT_IS_LONG
- case TCL_NUMBER_WIDE:
- w1 = *((const Tcl_WideInt *)ptr1);
- switch (type2) {
- case TCL_NUMBER_WIDE:
- w2 = *((const Tcl_WideInt *)ptr2);
- wideCompare:
- return (w1 < w2) ? MP_LT : ((w1 > w2) ? MP_GT : MP_EQ);
- case TCL_NUMBER_LONG:
- l2 = *((const long *)ptr2);
- w2 = (Tcl_WideInt)l2;
- goto wideCompare;
- case TCL_NUMBER_DOUBLE:
- d2 = *((const double *)ptr2);
- d1 = (double) w1;
- if (DBL_MANT_DIG > CHAR_BIT*sizeof(Tcl_WideInt)
- || w1 == (Tcl_WideInt) d1 || modf(d2, &tmp) != 0.0) {
- goto doubleCompare;
- }
- if (d2 < (double)LLONG_MIN) {
- return MP_GT;
- }
- if (d2 > (double)LLONG_MAX) {
- return MP_LT;
- }
w2 = (Tcl_WideInt) d2;
goto wideCompare;
case TCL_NUMBER_BIG:
@@ -9197,7 +8865,6 @@ TclCompareTwoNumbers(
mp_clear(&big2);
return compare;
}
-#endif
case TCL_NUMBER_DOUBLE:
d1 = *((const double *)ptr1);
@@ -9206,22 +8873,6 @@ TclCompareTwoNumbers(
d2 = *((const double *)ptr2);
doubleCompare:
return (d1 < d2) ? MP_LT : ((d1 > d2) ? MP_GT : MP_EQ);
- case TCL_NUMBER_LONG:
- l2 = *((const long *)ptr2);
- d2 = (double) l2;
- if (DBL_MANT_DIG > CHAR_BIT*sizeof(long) || l2 == (long) d2
- || modf(d1, &tmp) != 0.0) {
- goto doubleCompare;
- }
- if (d1 < (double)LONG_MIN) {
- return MP_LT;
- }
- if (d1 > (double)LONG_MAX) {
- return MP_GT;
- }
- l1 = (long) d1;
- goto longCompare;
-#ifndef TCL_WIDE_INT_IS_LONG
case TCL_NUMBER_WIDE:
w2 = *((const Tcl_WideInt *)ptr2);
d2 = (double) w2;
@@ -9237,7 +8888,6 @@ TclCompareTwoNumbers(
}
w1 = (Tcl_WideInt) d1;
goto wideCompare;
-#endif
case TCL_NUMBER_BIG:
if (TclIsInfinite(d1)) {
return (d1 > 0.0) ? MP_GT : MP_LT;
@@ -9265,10 +8915,7 @@ TclCompareTwoNumbers(
case TCL_NUMBER_BIG:
Tcl_TakeBignumFromObj(NULL, valuePtr, &big1);
switch (type2) {
-#ifndef TCL_WIDE_INT_IS_LONG
case TCL_NUMBER_WIDE:
-#endif
- case TCL_NUMBER_LONG:
compare = mp_cmp_d(&big1, 0);
mp_clear(&big1);
return compare;
diff --git a/generic/tclGet.c b/generic/tclGet.c
index 97e8c7b..727db0a 100644
--- a/generic/tclGet.c
+++ b/generic/tclGet.c
@@ -142,7 +142,7 @@ Tcl_GetBoolean(
Tcl_Panic("invalid sharing of Tcl_Obj on C stack");
}
if (code == TCL_OK) {
- *boolPtr = obj.internalRep.longValue;
+ *boolPtr = obj.internalRep.wideValue;
}
return code;
}
diff --git a/generic/tclInt.decls b/generic/tclInt.decls
index 35116da..08cc863 100644
--- a/generic/tclInt.decls
+++ b/generic/tclInt.decls
@@ -115,7 +115,7 @@ declare 23 {
}
# Replaced with macro (see tclInt.h) in Tcl 8.5.0, restored in 8.5.10
declare 24 {
- int TclFormatInt(char *buffer, long n)
+ int TclFormatInt(char *buffer, Tcl_WideInt n)
}
declare 25 {
void TclFreePackageInfo(Interp *iPtr)
diff --git a/generic/tclInt.h b/generic/tclInt.h
index 7996100..08632b0 100644
--- a/generic/tclInt.h
+++ b/generic/tclInt.h
@@ -2392,34 +2392,32 @@ typedef struct List {
* WARNING: these macros eval their args more than once.
*/
+#if (LONG_MAX == LLONG_MAX)
#define TclGetLongFromObj(interp, objPtr, longPtr) \
(((objPtr)->typePtr == &tclIntType) \
- ? ((*(longPtr) = (objPtr)->internalRep.longValue), TCL_OK) \
+ ? ((*(longPtr) = (objPtr)->internalRep.wideValue), TCL_OK) \
: Tcl_GetLongFromObj((interp), (objPtr), (longPtr)))
-
-#if (LONG_MAX == INT_MAX)
-#define TclGetIntFromObj(interp, objPtr, intPtr) \
- (((objPtr)->typePtr == &tclIntType) \
- ? ((*(intPtr) = (objPtr)->internalRep.longValue), TCL_OK) \
- : Tcl_GetIntFromObj((interp), (objPtr), (intPtr)))
-#define TclGetIntForIndexM(interp, objPtr, endValue, idxPtr) \
- (((objPtr)->typePtr == &tclIntType) \
- ? ((*(idxPtr) = (objPtr)->internalRep.longValue), TCL_OK) \
- : TclGetIntForIndex((interp), (objPtr), (endValue), (idxPtr)))
#else
+#define TclGetLongFromObj(interp, objPtr, longPtr) \
+ (((objPtr)->typePtr == &tclIntType \
+ && (objPtr)->internalRep.wideValue >= -(Tcl_WideInt)(ULONG_MAX) \
+ && (objPtr)->internalRep.wideValue <= (Tcl_WideInt)(ULONG_MAX)) \
+ ? ((*(longPtr) = (long)(objPtr)->internalRep.wideValue), TCL_OK) \
+ : Tcl_GetLongFromObj((interp), (objPtr), (longPtr)))
+#endif
+
#define TclGetIntFromObj(interp, objPtr, intPtr) \
(((objPtr)->typePtr == &tclIntType \
- && (objPtr)->internalRep.longValue >= -(Tcl_WideInt)(UINT_MAX) \
- && (objPtr)->internalRep.longValue <= (Tcl_WideInt)(UINT_MAX)) \
- ? ((*(intPtr) = (objPtr)->internalRep.longValue), TCL_OK) \
+ && (objPtr)->internalRep.wideValue >= -(Tcl_WideInt)(UINT_MAX) \
+ && (objPtr)->internalRep.wideValue <= (Tcl_WideInt)(UINT_MAX)) \
+ ? ((*(intPtr) = (objPtr)->internalRep.wideValue), TCL_OK) \
: Tcl_GetIntFromObj((interp), (objPtr), (intPtr)))
#define TclGetIntForIndexM(interp, objPtr, endValue, idxPtr) \
(((objPtr)->typePtr == &tclIntType \
- && (objPtr)->internalRep.longValue >= INT_MIN \
- && (objPtr)->internalRep.longValue <= INT_MAX) \
- ? ((*(idxPtr) = (objPtr)->internalRep.longValue), TCL_OK) \
+ && (objPtr)->internalRep.wideValue >= INT_MIN \
+ && (objPtr)->internalRep.wideValue <= INT_MAX) \
+ ? ((*(idxPtr) = (objPtr)->internalRep.wideValue), TCL_OK) \
: TclGetIntForIndex((interp), (objPtr), (endValue), (idxPtr)))
-#endif
/*
* Macro used to save a function call for common uses of
@@ -2429,21 +2427,11 @@ typedef struct List {
* Tcl_WideInt *wideIntPtr);
*/
-#ifdef TCL_WIDE_INT_IS_LONG
#define TclGetWideIntFromObj(interp, objPtr, wideIntPtr) \
(((objPtr)->typePtr == &tclIntType) \
? (*(wideIntPtr) = (Tcl_WideInt) \
- ((objPtr)->internalRep.longValue), TCL_OK) : \
+ ((objPtr)->internalRep.wideValue), TCL_OK) : \
Tcl_GetWideIntFromObj((interp), (objPtr), (wideIntPtr)))
-#else /* !TCL_WIDE_INT_IS_LONG */
-#define TclGetWideIntFromObj(interp, objPtr, wideIntPtr) \
- (((objPtr)->typePtr == &tclWideIntType) \
- ? (*(wideIntPtr) = (objPtr)->internalRep.wideValue, TCL_OK) : \
- ((objPtr)->typePtr == &tclIntType) \
- ? (*(wideIntPtr) = (Tcl_WideInt) \
- ((objPtr)->internalRep.longValue), TCL_OK) : \
- Tcl_GetWideIntFromObj((interp), (objPtr), (wideIntPtr)))
-#endif /* TCL_WIDE_INT_IS_LONG */
/*
* Flag values for TclTraceDictPath().
@@ -2669,9 +2657,6 @@ MODULE_SCOPE const Tcl_ObjType tclDictType;
MODULE_SCOPE const Tcl_ObjType tclProcBodyType;
MODULE_SCOPE const Tcl_ObjType tclStringType;
MODULE_SCOPE const Tcl_ObjType tclEnsembleCmdType;
-#ifndef TCL_WIDE_INT_IS_LONG
-MODULE_SCOPE const Tcl_ObjType tclWideIntType;
-#endif
MODULE_SCOPE const Tcl_ObjType tclRegexpType;
MODULE_SCOPE Tcl_ObjType tclCmdNameType;
@@ -2721,6 +2706,7 @@ MODULE_SCOPE Tcl_ObjCmdProc TclNRForObjCmd;
MODULE_SCOPE Tcl_ObjCmdProc TclNRForeachCmd;
MODULE_SCOPE Tcl_ObjCmdProc TclNRIfObjCmd;
MODULE_SCOPE Tcl_ObjCmdProc TclNRLmapCmd;
+MODULE_SCOPE Tcl_ObjCmdProc TclNRPackageObjCmd;
MODULE_SCOPE Tcl_ObjCmdProc TclNRSourceObjCmd;
MODULE_SCOPE Tcl_ObjCmdProc TclNRSubstObjCmd;
MODULE_SCOPE Tcl_ObjCmdProc TclNRSwitchObjCmd;
@@ -3126,20 +3112,10 @@ MODULE_SCOPE void TclSpellFix(Tcl_Interp *interp,
Tcl_Obj *bad, Tcl_Obj *fix);
MODULE_SCOPE void * TclStackRealloc(Tcl_Interp *interp, void *ptr,
int numBytes);
-MODULE_SCOPE int TclStringCatObjv(Tcl_Interp *interp, int inPlace,
- int objc, Tcl_Obj *const objv[],
- Tcl_Obj **objPtrPtr);
-MODULE_SCOPE int TclStringFind(Tcl_Obj *needle, Tcl_Obj *haystack,
- int start);
-MODULE_SCOPE int TclStringLast(Tcl_Obj *needle, Tcl_Obj *haystack,
- int last);
MODULE_SCOPE int TclStringMatch(const char *str, int strLen,
const char *pattern, int ptnLen, int flags);
MODULE_SCOPE int TclStringMatchObj(Tcl_Obj *stringObj,
Tcl_Obj *patternObj, int flags);
-MODULE_SCOPE Tcl_Obj * TclStringObjReverse(Tcl_Obj *objPtr);
-MODULE_SCOPE int TclStringRepeat(Tcl_Interp *interp, Tcl_Obj *objPtr,
- int count, Tcl_Obj **objPtrPtr);
MODULE_SCOPE void TclSubstCompile(Tcl_Interp *interp, const char *bytes,
int numBytes, int flags, int line,
struct CompileEnv *envPtr);
@@ -3940,6 +3916,26 @@ MODULE_SCOPE int TclCompileAssembleCmd(Tcl_Interp *interp,
struct CompileEnv *envPtr);
/*
+ * Routines that provide the [string] ensemble functionality. Possible
+ * candidates for public interface.
+ */
+
+MODULE_SCOPE Tcl_Obj * TclStringCat(Tcl_Interp *interp, int objc,
+ Tcl_Obj *const objv[], int flags);
+MODULE_SCOPE int TclStringFirst(Tcl_Obj *needle, Tcl_Obj *haystack,
+ int start);
+MODULE_SCOPE int TclStringLast(Tcl_Obj *needle, Tcl_Obj *haystack,
+ int last);
+MODULE_SCOPE Tcl_Obj * TclStringRepeat(Tcl_Interp *interp, Tcl_Obj *objPtr,
+ int count, int flags);
+MODULE_SCOPE Tcl_Obj * TclStringReverse(Tcl_Obj *objPtr, int flags);
+
+/* Flag values for the [string] ensemble functions. */
+
+#define TCL_STRING_MATCH_NOCASE TCL_MATCH_NOCASE /* (1<<0) in tcl.h */
+#define TCL_STRING_IN_PLACE (1<<1)
+
+/*
* Functions defined in generic/tclVar.c and currently exported only for use
* by the bytecode compiler and engine. Some of these could later be placed in
* the public interface.
@@ -4503,30 +4499,19 @@ MODULE_SCOPE Tcl_PackageInitProc Procbodytest_SafeInit;
* core. They should only be called on unshared objects. The ANSI C
* "prototypes" for these macros are:
*
- * MODULE_SCOPE void TclSetLongObj(Tcl_Obj *objPtr, long longValue);
- * MODULE_SCOPE void TclSetWideIntObj(Tcl_Obj *objPtr, Tcl_WideInt w);
+ * MODULE_SCOPE void TclSetIntObj(Tcl_Obj *objPtr, Tcl_WideInt w);
* MODULE_SCOPE void TclSetDoubleObj(Tcl_Obj *objPtr, double d);
*----------------------------------------------------------------
*/
-#define TclSetLongObj(objPtr, i) \
+#define TclSetIntObj(objPtr, i) \
do { \
TclInvalidateStringRep(objPtr); \
TclFreeIntRep(objPtr); \
- (objPtr)->internalRep.longValue = (long)(i); \
+ (objPtr)->internalRep.wideValue = (Tcl_WideInt)(i); \
(objPtr)->typePtr = &tclIntType; \
} while (0)
-#ifndef TCL_WIDE_INT_IS_LONG
-#define TclSetWideIntObj(objPtr, w) \
- do { \
- TclInvalidateStringRep(objPtr); \
- TclFreeIntRep(objPtr); \
- (objPtr)->internalRep.wideValue = (Tcl_WideInt)(w); \
- (objPtr)->typePtr = &tclWideIntType; \
- } while (0)
-#endif
-
#define TclSetDoubleObj(objPtr, d) \
do { \
TclInvalidateStringRep(objPtr); \
@@ -4541,8 +4526,7 @@ MODULE_SCOPE Tcl_PackageInitProc Procbodytest_SafeInit;
* types, avoiding the corresponding function calls in time critical parts of
* the core. The ANSI C "prototypes" for these macros are:
*
- * MODULE_SCOPE void TclNewLongObj(Tcl_Obj *objPtr, long l);
- * MODULE_SCOPE void TclNewWideObj(Tcl_Obj *objPtr, Tcl_WideInt w);
+ * MODULE_SCOPE void TclNewIntObj(Tcl_Obj *objPtr, Tcl_WideInt w);
* MODULE_SCOPE void TclNewDoubleObj(Tcl_Obj *objPtr, double d);
* MODULE_SCOPE void TclNewStringObj(Tcl_Obj *objPtr, const char *s, int len);
* MODULE_SCOPE void TclNewLiteralStringObj(Tcl_Obj*objPtr, const char *sLiteral);
@@ -4551,13 +4535,13 @@ MODULE_SCOPE Tcl_PackageInitProc Procbodytest_SafeInit;
*/
#ifndef TCL_MEM_DEBUG
-#define TclNewLongObj(objPtr, i) \
+#define TclNewIntObj(objPtr, i) \
do { \
TclIncrObjsAllocated(); \
TclAllocObjStorage(objPtr); \
(objPtr)->refCount = 0; \
(objPtr)->bytes = NULL; \
- (objPtr)->internalRep.longValue = (long)(i); \
+ (objPtr)->internalRep.wideValue = (Tcl_WideInt)(i); \
(objPtr)->typePtr = &tclIntType; \
TCL_DTRACE_OBJ_CREATE(objPtr); \
} while (0)
@@ -4584,8 +4568,8 @@ MODULE_SCOPE Tcl_PackageInitProc Procbodytest_SafeInit;
} while (0)
#else /* TCL_MEM_DEBUG */
-#define TclNewLongObj(objPtr, l) \
- (objPtr) = Tcl_NewLongObj(l)
+#define TclNewIntObj(objPtr, w) \
+ (objPtr) = Tcl_NewWideIntObj(w)
#define TclNewDoubleObj(objPtr, d) \
(objPtr) = Tcl_NewDoubleObj(d)
diff --git a/generic/tclIntDecls.h b/generic/tclIntDecls.h
index 85353f9..eae2e9b 100644
--- a/generic/tclIntDecls.h
+++ b/generic/tclIntDecls.h
@@ -94,7 +94,7 @@ EXTERN int TclFindElement(Tcl_Interp *interp,
/* 23 */
EXTERN Proc * TclFindProc(Interp *iPtr, const char *procName);
/* 24 */
-EXTERN int TclFormatInt(char *buffer, long n);
+EXTERN int TclFormatInt(char *buffer, Tcl_WideInt n);
/* 25 */
EXTERN void TclFreePackageInfo(Interp *iPtr);
/* Slot 26 is reserved */
@@ -608,7 +608,7 @@ typedef struct TclIntStubs {
void (*reserved21)(void);
int (*tclFindElement) (Tcl_Interp *interp, const char *listStr, int listLength, const char **elementPtr, const char **nextPtr, int *sizePtr, int *bracePtr); /* 22 */
Proc * (*tclFindProc) (Interp *iPtr, const char *procName); /* 23 */
- int (*tclFormatInt) (char *buffer, long n); /* 24 */
+ int (*tclFormatInt) (char *buffer, Tcl_WideInt n); /* 24 */
void (*tclFreePackageInfo) (Interp *iPtr); /* 25 */
void (*reserved26)(void);
void (*reserved27)(void);
diff --git a/generic/tclObj.c b/generic/tclObj.c
index 9c69dff..2f154df 100644
--- a/generic/tclObj.c
+++ b/generic/tclObj.c
@@ -210,9 +210,8 @@ static int SetDoubleFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr);
static int SetIntFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr);
static void UpdateStringOfDouble(Tcl_Obj *objPtr);
static void UpdateStringOfInt(Tcl_Obj *objPtr);
-#ifndef TCL_WIDE_INT_IS_LONG
-static void UpdateStringOfWideInt(Tcl_Obj *objPtr);
-static int SetWideIntFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr);
+#if !defined(TCL_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9 && !defined(TCL_WIDE_INT_IS_LONG)
+static void UpdateStringOfOldInt(Tcl_Obj *objPtr);
#endif
static void FreeBignum(Tcl_Obj *objPtr);
static void DupBignum(Tcl_Obj *objPtr, Tcl_Obj *copyPtr);
@@ -257,19 +256,23 @@ const Tcl_ObjType tclDoubleType = {
SetDoubleFromAny /* setFromAnyProc */
};
const Tcl_ObjType tclIntType = {
+#if defined(TCL_NO_DEPRECATED) || TCL_MAJOR_VERSION > 8 || defined(TCL_WIDE_INT_IS_LONG)
"int", /* name */
+#else
+ "wideInt", /* name, keeping maximum compatibility with Tcl 8.6 on 32-bit platforms*/
+#endif
NULL, /* freeIntRepProc */
NULL, /* dupIntRepProc */
UpdateStringOfInt, /* updateStringProc */
SetIntFromAny /* setFromAnyProc */
};
-#ifndef TCL_WIDE_INT_IS_LONG
-const Tcl_ObjType tclWideIntType = {
- "wideInt", /* name */
+#if !defined(TCL_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9 && !defined(TCL_WIDE_INT_IS_LONG)
+static const Tcl_ObjType oldIntType = {
+ "int", /* name */
NULL, /* freeIntRepProc */
NULL, /* dupIntRepProc */
- UpdateStringOfWideInt, /* updateStringProc */
- SetWideIntFromAny /* setFromAnyProc */
+ UpdateStringOfOldInt, /* updateStringProc */
+ SetIntFromAny /* setFromAnyProc */
};
#endif
const Tcl_ObjType tclBignumType = {
@@ -389,7 +392,6 @@ TclInitObjSubsystem(void)
Tcl_RegisterObjType(&tclByteArrayType);
Tcl_RegisterObjType(&tclDoubleType);
Tcl_RegisterObjType(&tclEndOffsetType);
- Tcl_RegisterObjType(&tclIntType);
Tcl_RegisterObjType(&tclStringType);
Tcl_RegisterObjType(&tclListType);
Tcl_RegisterObjType(&tclDictType);
@@ -398,11 +400,6 @@ TclInitObjSubsystem(void)
Tcl_RegisterObjType(&tclRegexpType);
Tcl_RegisterObjType(&tclProcBodyType);
- /* For backward compatibility only ... */
-#ifndef TCL_WIDE_INT_IS_LONG
- Tcl_RegisterObjType(&tclWideIntType);
-#endif
-
#ifdef TCL_COMPILE_STATS
Tcl_MutexLock(&tclObjMutex);
tclObjsAlloced = 0;
@@ -1754,7 +1751,7 @@ Tcl_NewBooleanObj(
{
register Tcl_Obj *objPtr;
- TclNewLongObj(objPtr, boolValue!=0);
+ TclNewIntObj(objPtr, boolValue!=0);
return objPtr;
}
#endif /* TCL_MEM_DEBUG */
@@ -1802,7 +1799,7 @@ Tcl_DbNewBooleanObj(
TclDbNewObj(objPtr, file, line);
objPtr->bytes = NULL;
- objPtr->internalRep.longValue = (boolValue != 0);
+ objPtr->internalRep.wideValue = (boolValue != 0);
objPtr->typePtr = &tclIntType;
return objPtr;
}
@@ -1849,7 +1846,7 @@ Tcl_SetBooleanObj(
Tcl_Panic("%s called with shared object", "Tcl_SetBooleanObj");
}
- TclSetLongObj(objPtr, boolValue!=0);
+ TclSetIntObj(objPtr, boolValue!=0);
}
#endif /* TCL_NO_DEPRECATED */
@@ -1880,7 +1877,7 @@ Tcl_GetBooleanFromObj(
{
do {
if (objPtr->typePtr == &tclIntType) {
- *boolPtr = (objPtr->internalRep.longValue != 0);
+ *boolPtr = (objPtr->internalRep.wideValue != 0);
return TCL_OK;
}
if (objPtr->typePtr == &tclBooleanType) {
@@ -1908,12 +1905,6 @@ Tcl_GetBooleanFromObj(
*boolPtr = 1;
return TCL_OK;
}
-#ifndef TCL_WIDE_INT_IS_LONG
- if (objPtr->typePtr == &tclWideIntType) {
- *boolPtr = (objPtr->internalRep.wideValue != 0);
- return TCL_OK;
- }
-#endif
} while ((ParseBoolean(objPtr) == TCL_OK) || (TCL_OK ==
TclParseNumber(interp, objPtr, "boolean value", NULL,-1,NULL,0)));
return TCL_ERROR;
@@ -1952,7 +1943,7 @@ TclSetBooleanFromAny(
if (objPtr->bytes == NULL) {
if (objPtr->typePtr == &tclIntType) {
- switch (objPtr->internalRep.longValue) {
+ switch (objPtr->internalRep.wideValue) {
case 0L: case 1L:
return TCL_OK;
}
@@ -1963,12 +1954,6 @@ TclSetBooleanFromAny(
goto badBoolean;
}
-#ifndef TCL_WIDE_INT_IS_LONG
- if (objPtr->typePtr == &tclWideIntType) {
- goto badBoolean;
- }
-#endif
-
if (objPtr->typePtr == &tclDoubleType) {
goto badBoolean;
}
@@ -2105,7 +2090,7 @@ ParseBoolean(
numericBoolean:
TclFreeIntRep(objPtr);
- objPtr->internalRep.longValue = newBool;
+ objPtr->internalRep.wideValue = newBool;
objPtr->typePtr = &tclIntType;
return TCL_OK;
}
@@ -2286,7 +2271,7 @@ Tcl_GetDoubleFromObj(
return TCL_OK;
}
if (objPtr->typePtr == &tclIntType) {
- *dblPtr = objPtr->internalRep.longValue;
+ *dblPtr = (double) objPtr->internalRep.wideValue;
return TCL_OK;
}
if (objPtr->typePtr == &tclBignumType) {
@@ -2296,12 +2281,6 @@ Tcl_GetDoubleFromObj(
*dblPtr = TclBignumToDouble(&big);
return TCL_OK;
}
-#ifndef TCL_WIDE_INT_IS_LONG
- if (objPtr->typePtr == &tclWideIntType) {
- *dblPtr = (double) objPtr->internalRep.wideValue;
- return TCL_OK;
- }
-#endif
} while (SetDoubleFromAny(interp, objPtr) == TCL_OK);
return TCL_ERROR;
}
@@ -2418,7 +2397,7 @@ Tcl_NewIntObj(
{
register Tcl_Obj *objPtr;
- TclNewLongObj(objPtr, intValue);
+ TclNewIntObj(objPtr, intValue);
return objPtr;
}
#endif /* if TCL_MEM_DEBUG */
@@ -2451,7 +2430,7 @@ Tcl_SetIntObj(
Tcl_Panic("%s called with shared object", "Tcl_SetIntObj");
}
- TclSetLongObj(objPtr, intValue);
+ TclSetIntObj(objPtr, intValue);
}
/*
@@ -2532,9 +2511,8 @@ SetIntFromAny(
Tcl_Interp *interp, /* Tcl interpreter */
Tcl_Obj *objPtr) /* Pointer to the object to convert */
{
- long l;
-
- return TclGetLongFromObj(interp, objPtr, &l);
+ Tcl_WideInt w;
+ return Tcl_GetWideIntFromObj(interp, objPtr, &w);
}
/*
@@ -2563,12 +2541,28 @@ UpdateStringOfInt(
char buffer[TCL_INTEGER_SPACE];
register int len;
+ len = TclFormatInt(buffer, objPtr->internalRep.wideValue);
+
+ objPtr->bytes = ckalloc(len + 1);
+ memcpy(objPtr->bytes, buffer, (unsigned) len + 1);
+ objPtr->length = len;
+}
+
+#if !defined(TCL_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9 && !defined(TCL_WIDE_INT_IS_LONG)
+static void
+UpdateStringOfOldInt(
+ register Tcl_Obj *objPtr) /* Int object whose string rep to update. */
+{
+ char buffer[TCL_INTEGER_SPACE];
+ register int len;
+
len = TclFormatInt(buffer, objPtr->internalRep.longValue);
objPtr->bytes = ckalloc(len + 1);
memcpy(objPtr->bytes, buffer, (unsigned) len + 1);
objPtr->length = len;
}
+#endif
/*
*----------------------------------------------------------------------
@@ -2600,8 +2594,8 @@ UpdateStringOfInt(
*----------------------------------------------------------------------
*/
-#ifdef TCL_MEM_DEBUG
#undef Tcl_NewLongObj
+#ifdef TCL_MEM_DEBUG
Tcl_Obj *
Tcl_NewLongObj(
@@ -2620,7 +2614,7 @@ Tcl_NewLongObj(
{
register Tcl_Obj *objPtr;
- TclNewLongObj(objPtr, longValue);
+ TclNewIntObj(objPtr, longValue);
return objPtr;
}
#endif /* if TCL_MEM_DEBUG */
@@ -2657,6 +2651,7 @@ Tcl_NewLongObj(
*----------------------------------------------------------------------
*/
+#undef Tcl_DbNewLongObj
#ifdef TCL_MEM_DEBUG
Tcl_Obj *
@@ -2673,7 +2668,7 @@ Tcl_DbNewLongObj(
TclDbNewObj(objPtr, file, line);
objPtr->bytes = NULL;
- objPtr->internalRep.longValue = longValue;
+ objPtr->internalRep.wideValue = longValue;
objPtr->typePtr = &tclIntType;
return objPtr;
}
@@ -2711,6 +2706,7 @@ Tcl_DbNewLongObj(
*----------------------------------------------------------------------
*/
+#undef Tcl_SetLongObj
void
Tcl_SetLongObj(
register Tcl_Obj *objPtr, /* Object whose internal rep to init. */
@@ -2721,7 +2717,7 @@ Tcl_SetLongObj(
Tcl_Panic("%s called with shared object", "Tcl_SetLongObj");
}
- TclSetLongObj(objPtr, longValue);
+ TclSetIntObj(objPtr, longValue);
}
/*
@@ -2752,12 +2748,13 @@ Tcl_GetLongFromObj(
register long *longPtr) /* Place to store resulting long. */
{
do {
+#if (LONG_MAX == LLONG_MAX)
if (objPtr->typePtr == &tclIntType) {
- *longPtr = objPtr->internalRep.longValue;
+ *longPtr = objPtr->internalRep.wideValue;
return TCL_OK;
}
-#ifndef TCL_WIDE_INT_IS_LONG
- if (objPtr->typePtr == &tclWideIntType) {
+#else
+ if (objPtr->typePtr == &tclIntType) {
/*
* We return any integer in the range -ULONG_MAX to ULONG_MAX
* converted to a long, ignoring overflow. The rule preserves
@@ -2814,7 +2811,7 @@ Tcl_GetLongFromObj(
return TCL_OK;
}
}
-#ifndef TCL_WIDE_INT_IS_LONG
+#if (LONG_MAX != LLONG_MAX)
tooLarge:
#endif
if (interp != NULL) {
@@ -2830,49 +2827,6 @@ Tcl_GetLongFromObj(
TCL_PARSE_INTEGER_ONLY)==TCL_OK);
return TCL_ERROR;
}
-#ifndef TCL_WIDE_INT_IS_LONG
-
-/*
- *----------------------------------------------------------------------
- *
- * UpdateStringOfWideInt --
- *
- * Update the string representation for a wide integer object. Note: this
- * function does not free an existing old string rep so storage will be
- * lost if this has not already been done.
- *
- * Results:
- * None.
- *
- * Side effects:
- * The object's string is set to a valid string that results from the
- * wideInt-to-string conversion.
- *
- *----------------------------------------------------------------------
- */
-
-static void
-UpdateStringOfWideInt(
- register Tcl_Obj *objPtr) /* Int object whose string rep to update. */
-{
- char buffer[TCL_INTEGER_SPACE+2];
- register unsigned len;
- register Tcl_WideInt wideVal = objPtr->internalRep.wideValue;
-
- /*
- * Note that sprintf will generate a compiler warning under Mingw claiming
- * %I64 is an unknown format specifier. Just ignore this warning. We can't
- * use %L as the format specifier since that gets printed as a 32 bit
- * value.
- */
-
- sprintf(buffer, "%" TCL_LL_MODIFIER "d", wideVal);
- len = strlen(buffer);
- objPtr->bytes = ckalloc(len + 1);
- memcpy(objPtr->bytes, buffer, len + 1);
- objPtr->length = len;
-}
-#endif /* !TCL_WIDE_INT_IS_LONG */
/*
*----------------------------------------------------------------------
@@ -2922,7 +2876,7 @@ Tcl_NewWideIntObj(
register Tcl_Obj *objPtr;
TclNewObj(objPtr);
- Tcl_SetWideIntObj(objPtr, wideValue);
+ TclSetIntObj(objPtr, wideValue);
return objPtr;
}
#endif /* if TCL_MEM_DEBUG */
@@ -2974,7 +2928,7 @@ Tcl_DbNewWideIntObj(
register Tcl_Obj *objPtr;
TclDbNewObj(objPtr, file, line);
- Tcl_SetWideIntObj(objPtr, wideValue);
+ TclSetIntObj(objPtr, wideValue);
return objPtr;
}
@@ -3023,19 +2977,7 @@ Tcl_SetWideIntObj(
Tcl_Panic("%s called with shared object", "Tcl_SetWideIntObj");
}
- if ((wideValue >= (Tcl_WideInt) LONG_MIN)
- && (wideValue <= (Tcl_WideInt) LONG_MAX)) {
- TclSetLongObj(objPtr, (long) wideValue);
- } else {
-#ifndef TCL_WIDE_INT_IS_LONG
- TclSetWideIntObj(objPtr, wideValue);
-#else
- mp_int big;
-
- TclInitBignumFromWideInt(&big, wideValue);
- Tcl_SetBignumObj(objPtr, &big);
-#endif
- }
+ TclSetIntObj(objPtr, wideValue);
}
/*
@@ -3067,14 +3009,8 @@ Tcl_GetWideIntFromObj(
/* Place to store resulting long. */
{
do {
-#ifndef TCL_WIDE_INT_IS_LONG
- if (objPtr->typePtr == &tclWideIntType) {
- *wideIntPtr = objPtr->internalRep.wideValue;
- return TCL_OK;
- }
-#endif
if (objPtr->typePtr == &tclIntType) {
- *wideIntPtr = (Tcl_WideInt) objPtr->internalRep.longValue;
+ *wideIntPtr = objPtr->internalRep.wideValue;
return TCL_OK;
}
if (objPtr->typePtr == &tclDoubleType) {
@@ -3127,33 +3063,6 @@ Tcl_GetWideIntFromObj(
TCL_PARSE_INTEGER_ONLY)==TCL_OK);
return TCL_ERROR;
}
-#ifndef TCL_WIDE_INT_IS_LONG
-
-/*
- *----------------------------------------------------------------------
- *
- * SetWideIntFromAny --
- *
- * Attempts to force the internal representation for a Tcl object to
- * tclWideIntType, specifically.
- *
- * Results:
- * The return value is a standard object Tcl result. If an error occurs
- * during conversion, an error message is left in the interpreter's
- * result unless "interp" is NULL.
- *
- *----------------------------------------------------------------------
- */
-
-static int
-SetWideIntFromAny(
- Tcl_Interp *interp, /* Tcl interpreter */
- Tcl_Obj *objPtr) /* Pointer to the object to convert */
-{
- Tcl_WideInt w;
- return Tcl_GetWideIntFromObj(interp, objPtr, &w);
-}
-#endif /* !TCL_WIDE_INT_IS_LONG */
/*
*----------------------------------------------------------------------
@@ -3396,16 +3305,10 @@ GetBignumFromObj(
return TCL_OK;
}
if (objPtr->typePtr == &tclIntType) {
- TclInitBignumFromLong(bignumValue, objPtr->internalRep.longValue);
- return TCL_OK;
- }
-#ifndef TCL_WIDE_INT_IS_LONG
- if (objPtr->typePtr == &tclWideIntType) {
TclInitBignumFromWideInt(bignumValue,
objPtr->internalRep.wideValue);
return TCL_OK;
}
-#endif
if (objPtr->typePtr == &tclDoubleType) {
if (interp != NULL) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
@@ -3515,36 +3418,11 @@ Tcl_SetBignumObj(
Tcl_Panic("%s called with shared object", "Tcl_SetBignumObj");
}
if ((size_t) bignumValue->used
- <= (CHAR_BIT * sizeof(long) + DIGIT_BIT - 1) / DIGIT_BIT) {
- unsigned long value = 0, numBytes = sizeof(long);
- long scratch;
- unsigned char *bytes = (unsigned char *) &scratch;
-
- if (mp_to_unsigned_bin_n(bignumValue, bytes, &numBytes) != MP_OKAY) {
- goto tooLargeForLong;
- }
- while (numBytes-- > 0) {
- value = (value << CHAR_BIT) | *bytes++;
- }
- if (value > (((~(unsigned long)0) >> 1) + bignumValue->sign)) {
- goto tooLargeForLong;
- }
- if (bignumValue->sign) {
- TclSetLongObj(objPtr, -(long)value);
- } else {
- TclSetLongObj(objPtr, (long)value);
- }
- mp_clear(bignumValue);
- return;
- }
- tooLargeForLong:
-#ifndef TCL_WIDE_INT_IS_LONG
- if ((size_t) bignumValue->used
- <= (CHAR_BIT * sizeof(Tcl_WideInt) + DIGIT_BIT - 1) / DIGIT_BIT) {
+ <= (CHAR_BIT * sizeof(Tcl_WideUInt) + DIGIT_BIT - 1) / DIGIT_BIT) {
Tcl_WideUInt value = 0;
- unsigned long numBytes = sizeof(Tcl_WideInt);
- Tcl_WideInt scratch;
- unsigned char *bytes = (unsigned char *)&scratch;
+ unsigned long numBytes = sizeof(Tcl_WideUInt);
+ Tcl_WideUInt scratch;
+ unsigned char *bytes = (unsigned char *) &scratch;
if (mp_to_unsigned_bin_n(bignumValue, bytes, &numBytes) != MP_OKAY) {
goto tooLargeForWide;
@@ -3556,15 +3434,14 @@ Tcl_SetBignumObj(
goto tooLargeForWide;
}
if (bignumValue->sign) {
- TclSetWideIntObj(objPtr, -(Tcl_WideInt)value);
+ TclSetIntObj(objPtr, -(Tcl_WideInt)value);
} else {
- TclSetWideIntObj(objPtr, (Tcl_WideInt)value);
+ TclSetIntObj(objPtr, (Tcl_WideInt)value);
}
mp_clear(bignumValue);
return;
}
tooLargeForWide:
-#endif
TclInvalidateStringRep(objPtr);
TclFreeIntRep(objPtr);
TclSetBignumIntRep(objPtr, bignumValue);
@@ -3646,17 +3523,10 @@ TclGetNumberFromObj(
return TCL_OK;
}
if (objPtr->typePtr == &tclIntType) {
- *typePtr = TCL_NUMBER_LONG;
- *clientDataPtr = &objPtr->internalRep.longValue;
- return TCL_OK;
- }
-#ifndef TCL_WIDE_INT_IS_LONG
- if (objPtr->typePtr == &tclWideIntType) {
*typePtr = TCL_NUMBER_WIDE;
*clientDataPtr = &objPtr->internalRep.wideValue;
return TCL_OK;
}
-#endif
if (objPtr->typePtr == &tclBignumType) {
static Tcl_ThreadDataKey bignumKey;
mp_int *bigPtr = Tcl_GetThreadData(&bignumKey,
diff --git a/generic/tclPkg.c b/generic/tclPkg.c
index 12b7067..080b82d 100644
--- a/generic/tclPkg.c
+++ b/generic/tclPkg.c
@@ -65,6 +65,18 @@ typedef struct {
const void *clientData; /* Client data. */
} Package;
+typedef struct Require {
+ void * clientDataPtr;
+ const char *name;
+ Package *pkgPtr;
+ char *versionToProvide;
+} Require;
+
+typedef struct RequireProcArgs {
+ const char *name;
+ void *clientDataPtr;
+} RequireProcArgs;
+
/*
* Prototypes for functions defined in this file:
*/
@@ -85,9 +97,15 @@ static void AddRequirementsToResult(Tcl_Interp *interp, int reqc,
static void AddRequirementsToDString(Tcl_DString *dstring,
int reqc, Tcl_Obj *const reqv[]);
static Package * FindPackage(Tcl_Interp *interp, const char *name);
-static int PkgRequireCore(Tcl_Interp *interp, const char *name,
- int reqc, Tcl_Obj *const reqv[],
- void *clientDataPtr);
+static int PkgRequireCore(ClientData data[], Tcl_Interp *interp, int result);
+static int PkgRequireCoreFinal(ClientData data[], Tcl_Interp *interp, int result);
+static int PkgRequireCoreCleanup(ClientData data[], Tcl_Interp *interp, int result);
+static int PkgRequireCoreStep1(ClientData data[], Tcl_Interp *interp, int result);
+static int PkgRequireCoreStep2(ClientData data[], Tcl_Interp *interp, int result);
+static int TclNRPkgRequireProc(ClientData clientData, Tcl_Interp *interp, int reqc, Tcl_Obj *const reqv[]);
+static int SelectPackage(ClientData data[], Tcl_Interp *interp, int result);
+static int SelectPackageFinal(ClientData data[], Tcl_Interp *interp, int result);
+static int TclNRPackageObjCmdCleanup(ClientData data[], Tcl_Interp *interp, int result);
/*
* Helper macros.
@@ -399,361 +417,429 @@ Tcl_PkgRequireProc(
* available. */
void *clientDataPtr)
{
+ RequireProcArgs args;
+ args.name = name;
+ args.clientDataPtr = clientDataPtr;
+ return Tcl_NRCallObjProc(interp, TclNRPkgRequireProc, (void *)&args, reqc, reqv);
+}
+
+static int
+TclNRPkgRequireProc(
+ ClientData clientData,
+ Tcl_Interp *interp,
+ int reqc,
+ Tcl_Obj *const reqv[]) {
+ RequireProcArgs *args = clientData;
+ Tcl_NRAddCallback(interp, PkgRequireCore, (void *)args->name, INT2PTR(reqc), (void *)reqv, args->clientDataPtr);
+ return TCL_OK;
+}
+
+static int
+PkgRequireCore(ClientData data[], Tcl_Interp *interp, int result)
+{
+ const char *name = data[0];
+ int reqc = PTR2INT(data[1]);
+ Tcl_Obj *const *reqv = data[2];
int code = CheckAllRequirements(interp, reqc, reqv);
+ Require *reqPtr;
if (code != TCL_OK) {
return code;
}
- return PkgRequireCore(interp, name, reqc, reqv, clientDataPtr);
+ reqPtr = ckalloc(sizeof(Require));
+ Tcl_NRAddCallback(interp, PkgRequireCoreCleanup, reqPtr, NULL, NULL, NULL);
+ reqPtr->clientDataPtr = data[3];
+ reqPtr->name = name;
+ reqPtr->pkgPtr = FindPackage(interp, name);
+ if (reqPtr->pkgPtr->version == NULL) {
+ Tcl_NRAddCallback(interp, SelectPackage, reqPtr, INT2PTR(reqc), (void *)reqv, PkgRequireCoreStep1);
+ } else {
+ Tcl_NRAddCallback(interp, PkgRequireCoreFinal, reqPtr, INT2PTR(reqc), (void *)reqv, NULL);
+ }
+ return TCL_OK;
}
-int
-PkgRequireCore(
- 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. */
- void *clientDataPtr)
-{
- Interp *iPtr = (Interp *) interp;
- Package *pkgPtr;
- PkgAvail *availPtr, *bestPtr, *bestStablePtr;
- char *availVersion, *bestVersion, *bestStableVersion;
- /* Internal rep. of versions */
- int availStable, code, satisfies, pass;
- char *script, *pkgVersionI;
+static int
+PkgRequireCoreStep1(ClientData data[], Tcl_Interp *interp, int result) {
Tcl_DString command;
+ char *script;
+ Require *reqPtr = data[0];
+ int reqc = PTR2INT(data[1]);
+ Tcl_Obj **const reqv = data[2];
+ const char *name = reqPtr->name /* Name of desired package. */;
+ if (reqPtr->pkgPtr->version == NULL) {
+ /*
+ * The package is not in the database. If there is a "package unknown"
+ * command, invoke it.
+ */
+
+ script = ((Interp *) interp)->packageUnknown;
+ if (script == NULL) {
+ Tcl_NRAddCallback(interp, PkgRequireCoreFinal, reqPtr, INT2PTR(reqc), (void *)reqv, NULL);
+ } else {
+ Tcl_DStringInit(&command);
+ Tcl_DStringAppend(&command, script, -1);
+ Tcl_DStringAppendElement(&command, name);
+ AddRequirementsToDString(&command, reqc, reqv);
+
+ Tcl_NRAddCallback(interp, PkgRequireCoreStep2, reqPtr, INT2PTR(reqc), (void *)reqv, NULL);
+ Tcl_NREvalObj(interp,
+ Tcl_NewStringObj(Tcl_DStringValue(&command), Tcl_DStringLength(&command)),
+ TCL_EVAL_GLOBAL
+ );
+ Tcl_DStringFree(&command);
+ }
+ return TCL_OK;
+ } else {
+ Tcl_NRAddCallback(interp, PkgRequireCoreFinal, reqPtr, INT2PTR(reqc), (void *)reqv, NULL);
+ }
+ return TCL_OK;
+}
+
+static int
+PkgRequireCoreStep2(ClientData data[], Tcl_Interp *interp, int result) {
+ Require *reqPtr = data[0];
+ int reqc = PTR2INT(data[1]);
+ Tcl_Obj **const reqv = data[2];
+ const char *name = reqPtr->name /* Name of desired package. */;
+ if ((result != TCL_OK) && (result != TCL_ERROR)) {
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "bad return code: %d", result));
+ Tcl_SetErrorCode(interp, "TCL", "PACKAGE", "BADRESULT", NULL);
+ result = TCL_ERROR;
+ }
+ if (result == TCL_ERROR) {
+ Tcl_AddErrorInfo(interp,
+ "\n (\"package unknown\" script)");
+ return result;
+ }
+ Tcl_ResetResult(interp);
+ /* pkgPtr may now be invalid, so refresh it. */
+ reqPtr->pkgPtr = FindPackage(interp, name);
+ Tcl_NRAddCallback(interp, SelectPackage, reqPtr, INT2PTR(reqc), (void *)reqv, PkgRequireCoreFinal);
+ return TCL_OK;
+}
+
+static int
+PkgRequireCoreFinal(ClientData data[], Tcl_Interp *interp, int result) {
+ Require *reqPtr = data[0];
+ int reqc = PTR2INT(data[1]), satisfies;
+ Tcl_Obj **const reqv = data[2];
+ char *pkgVersionI;
+ void *clientDataPtr = reqPtr->clientDataPtr;
+ const char *name = reqPtr->name /* Name of desired package. */;
+ if (reqPtr->pkgPtr->version == NULL) {
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "can't find package %s", name));
+ Tcl_SetErrorCode(interp, "TCL", "PACKAGE", "UNFOUND", NULL);
+ AddRequirementsToResult(interp, reqc, reqv);
+ return TCL_ERROR;
+ }
/*
- * It can take up to three passes to find the package: one pass to run the
- * "package unknown" script, one to run the "package ifneeded" script for
- * a specific version, and a final pass to lookup the package loaded by
- * the "package ifneeded" script.
+ * Ensure that the provided version meets the current requirements.
*/
- for (pass=1 ;; pass++) {
- pkgPtr = FindPackage(interp, name);
- if (pkgPtr->version != NULL) {
- break;
- }
+ if (reqc != 0) {
+ CheckVersionAndConvert(interp, reqPtr->pkgPtr->version, &pkgVersionI, NULL);
+ satisfies = SomeRequirementSatisfied(pkgVersionI, reqc, reqv);
- /*
- * Check whether we're already attempting to load some version of this
- * package (circular dependency detection).
- */
+ ckfree(pkgVersionI);
- if (pkgPtr->clientData != NULL) {
+ if (!satisfies) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "circular package dependency:"
- " attempt to provide %s %s requires %s",
- name, (char *) pkgPtr->clientData, name));
+ "version conflict for package \"%s\": have %s, need",
+ name, reqPtr->pkgPtr->version));
+ Tcl_SetErrorCode(interp, "TCL", "PACKAGE", "VERSIONCONFLICT",
+ NULL);
AddRequirementsToResult(interp, reqc, reqv);
- Tcl_SetErrorCode(interp, "TCL", "PACKAGE", "CIRCULARITY", NULL);
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.
- */
+ if (clientDataPtr) {
+ const void **ptr = (const void **) clientDataPtr;
- bestPtr = NULL;
- bestStablePtr = NULL;
- bestVersion = NULL;
- bestStableVersion = NULL;
+ *ptr = reqPtr->pkgPtr->clientData;
+ }
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(reqPtr->pkgPtr->version, -1));
+ return TCL_OK;
+}
- for (availPtr = pkgPtr->availPtr; availPtr != NULL;
- availPtr = availPtr->nextPtr) {
- if (CheckVersionAndConvert(interp, availPtr->version,
- &availVersion, &availStable) != TCL_OK) {
- /*
- * The provided version number has invalid syntax. This
- * should not happen. This should have been caught by the
- * 'package ifneeded' registering the package.
- */
+static int
+PkgRequireCoreCleanup(ClientData data[], Tcl_Interp *interp, int result) {
+ ckfree(data[0]);
+ return result;
+}
- continue;
- }
+
+static int
+SelectPackage(ClientData data[], Tcl_Interp *interp, int result) {
+ PkgAvail *availPtr, *bestPtr, *bestStablePtr;
+ char *availVersion, *bestVersion, *bestStableVersion;
+ /* Internal rep. of versions */
+ int availStable, satisfies;
+ Require *reqPtr = data[0];
+ int reqc = PTR2INT(data[1]);
+ Tcl_Obj **const reqv = data[2];
+ const char *name = reqPtr->name;
+ Package *pkgPtr = reqPtr->pkgPtr;
+ Interp *iPtr = (Interp *) interp;
- /* Check satisfaction of requirements before considering the current version further. */
- if (reqc > 0) {
- satisfies = SomeRequirementSatisfied(availVersion, reqc, reqv);
- if (!satisfies) {
- ckfree(availVersion);
- availVersion = NULL;
- continue;
- }
- }
+ /*
+ * Check whether we're already attempting to load some version of this
+ * package (circular dependency detection).
+ */
+
+ if (pkgPtr->clientData != NULL) {
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "circular package dependency:"
+ " attempt to provide %s %s requires %s",
+ name, (char *) pkgPtr->clientData, name));
+ AddRequirementsToResult(interp, reqc, reqv);
+ Tcl_SetErrorCode(interp, "TCL", "PACKAGE", "CIRCULARITY", NULL);
+ return TCL_ERROR;
+ }
- if (bestPtr != NULL) {
- int res = CompareVersions(availVersion, bestVersion, NULL);
+ /*
+ * 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.
+ */
- /*
- * Note: Used internal reps in the comparison!
- */
+ bestPtr = NULL;
+ bestStablePtr = NULL;
+ bestVersion = NULL;
+ bestStableVersion = NULL;
- if (res > 0) {
- /*
- * The version of the package sought is better than the
- * currently selected version.
- */
- ckfree(bestVersion);
- bestVersion = NULL;
- goto newbest;
- }
- } else {
- newbest:
- /* We have found a version which is better than our max. */
+ for (availPtr = pkgPtr->availPtr; availPtr != NULL;
+ availPtr = availPtr->nextPtr) {
+ if (CheckVersionAndConvert(interp, availPtr->version,
+ &availVersion, &availStable) != TCL_OK) {
+ /*
+ * The provided version number has invalid syntax. This
+ * should not happen. This should have been caught by the
+ * 'package ifneeded' registering the package.
+ */
- bestPtr = availPtr;
- CheckVersionAndConvert(interp, bestPtr->version, &bestVersion, NULL);
- }
+ continue;
+ }
- if (!availStable) {
+ /* Check satisfaction of requirements before considering the current version further. */
+ if (reqc > 0) {
+ satisfies = SomeRequirementSatisfied(availVersion, reqc, reqv);
+ if (!satisfies) {
ckfree(availVersion);
availVersion = NULL;
continue;
}
+ }
+
+ if (bestPtr != NULL) {
+ int res = CompareVersions(availVersion, bestVersion, NULL);
- if (bestStablePtr != NULL) {
- int res = CompareVersions(availVersion, bestStableVersion, NULL);
+ /*
+ * Note: Used internal reps in the comparison!
+ */
+ if (res > 0) {
/*
- * Note: Used internal reps in the comparison!
+ * The version of the package sought is better than the
+ * currently selected version.
*/
-
- if (res > 0) {
- /*
- * This stable version of the package sought is better
- * than the currently selected stable version.
- */
- ckfree(bestStableVersion);
- bestStableVersion = NULL;
- goto newstable;
- }
- } else {
- newstable:
- /* We have found a stable version which is better than our max stable. */
- bestStablePtr = availPtr;
- CheckVersionAndConvert(interp, bestStablePtr->version, &bestStableVersion, NULL);
+ ckfree(bestVersion);
+ bestVersion = NULL;
+ goto newbest;
}
+ } else {
+ newbest:
+ /* We have found a version which is better than our max. */
+
+ bestPtr = availPtr;
+ CheckVersionAndConvert(interp, bestPtr->version, &bestVersion, NULL);
+ }
+ if (!availStable) {
ckfree(availVersion);
availVersion = NULL;
- } /* end for */
-
- /*
- * Clean up memorized internal reps, if any.
- */
-
- if (bestVersion != NULL) {
- ckfree(bestVersion);
- bestVersion = NULL;
+ continue;
}
- if (bestStableVersion != NULL) {
- ckfree(bestStableVersion);
- bestStableVersion = NULL;
- }
+ if (bestStablePtr != NULL) {
+ int res = CompareVersions(availVersion, bestStableVersion, NULL);
- /*
- * 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)) {
- bestPtr = bestStablePtr;
- }
-
- if (bestPtr != NULL) {
/*
- * We found an ifneeded script for the package. Be careful while
- * executing it: this could cause reentrancy, so (a) protect the
- * script itself from deletion and (b) don't assume that bestPtr
- * will still exist when the script completes.
+ * Note: Used internal reps in the comparison!
*/
- char *versionToProvide = bestPtr->version;
- PkgFiles *pkgFiles;
- PkgName *pkgName;
- script = bestPtr->script;
-
- pkgPtr->clientData = versionToProvide;
- Tcl_Preserve(versionToProvide);
- Tcl_Preserve(script);
- pkgFiles = TclInitPkgFiles(interp);
- /* Push "ifneeded" package name in "tclPkgFiles" assocdata. */
- pkgName = ckalloc(sizeof(PkgName) + strlen(name));
- pkgName->nextPtr = pkgFiles->names;
- strcpy(pkgName->name, name);
- pkgFiles->names = pkgName;
- if (bestPtr->pkgIndex) {
- TclPkgFileSeen(interp, bestPtr->pkgIndex);
- }
- code = Tcl_EvalEx(interp, script, -1, TCL_EVAL_GLOBAL);
- /* Pop the "ifneeded" package name from "tclPkgFiles" assocdata*/
- pkgFiles->names = pkgName->nextPtr;
- ckfree(pkgName);
- Tcl_Release(script);
-
- pkgPtr = FindPackage(interp, name);
- if (code == TCL_OK) {
- Tcl_ResetResult(interp);
- if (pkgPtr->version == NULL) {
- code = TCL_ERROR;
- Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "attempt to provide package %s %s failed:"
- " no version of package %s provided",
- name, versionToProvide, name));
- Tcl_SetErrorCode(interp, "TCL", "PACKAGE", "UNPROVIDED",
- NULL);
- } else {
- char *pvi, *vi;
-
- if (CheckVersionAndConvert(interp, pkgPtr->version, &pvi,
- NULL) != TCL_OK) {
- code = TCL_ERROR;
- } else if (CheckVersionAndConvert(interp,
- versionToProvide, &vi, NULL) != TCL_OK) {
- ckfree(pvi);
- code = TCL_ERROR;
- } else {
- int res = CompareVersions(pvi, vi, NULL);
-
- ckfree(pvi);
- ckfree(vi);
- if (res != 0) {
- code = TCL_ERROR;
- Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "attempt to provide package %s %s failed:"
- " package %s %s provided instead",
- name, versionToProvide,
- name, pkgPtr->version));
- Tcl_SetErrorCode(interp, "TCL", "PACKAGE",
- "WRONGPROVIDE", NULL);
- }
- }
- }
- } else if (code != TCL_ERROR) {
- Tcl_Obj *codePtr = Tcl_NewIntObj(code);
-
- Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "attempt to provide package %s %s failed:"
- " bad return code: %s",
- name, versionToProvide, TclGetString(codePtr)));
- Tcl_SetErrorCode(interp, "TCL", "PACKAGE", "BADRESULT", NULL);
- TclDecrRefCount(codePtr);
- code = TCL_ERROR;
- }
-
- if (code == TCL_ERROR) {
- Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
- "\n (\"package ifneeded %s %s\" script)",
- name, versionToProvide));
- }
- Tcl_Release(versionToProvide);
-
- if (code != TCL_OK) {
+ if (res > 0) {
/*
- * 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 stable version of the package sought is better
+ * than the currently selected stable version.
*/
-
- if (pkgPtr->version != NULL) {
- ckfree(pkgPtr->version);
- pkgPtr->version = NULL;
- }
- pkgPtr->clientData = NULL;
- return code;
+ ckfree(bestStableVersion);
+ bestStableVersion = NULL;
+ goto newstable;
}
-
- break;
- }
-
- /*
- * The package is not in the database. If there is a "package unknown"
- * command, invoke it (but only on the first pass; after that, we
- * should not get here in the first place).
- */
-
- if (pass > 1) {
- break;
+ } else {
+ newstable:
+ /* We have found a stable version which is better than our max stable. */
+ bestStablePtr = availPtr;
+ CheckVersionAndConvert(interp, bestStablePtr->version, &bestStableVersion, NULL);
}
- script = ((Interp *) interp)->packageUnknown;
- if (script != NULL) {
- Tcl_DStringInit(&command);
- Tcl_DStringAppend(&command, script, -1);
- Tcl_DStringAppendElement(&command, name);
- AddRequirementsToDString(&command, reqc, reqv);
+ ckfree(availVersion);
+ availVersion = NULL;
+ } /* end for */
- code = Tcl_EvalEx(interp, Tcl_DStringValue(&command),
- Tcl_DStringLength(&command), TCL_EVAL_GLOBAL);
- Tcl_DStringFree(&command);
+ /*
+ * Clean up memorized internal reps, if any.
+ */
- if ((code != TCL_OK) && (code != TCL_ERROR)) {
- Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "bad return code: %d", code));
- Tcl_SetErrorCode(interp, "TCL", "PACKAGE", "BADRESULT", NULL);
- code = TCL_ERROR;
- }
- if (code == TCL_ERROR) {
- Tcl_AddErrorInfo(interp,
- "\n (\"package unknown\" script)");
- return code;
- }
- Tcl_ResetResult(interp);
- }
+ if (bestVersion != NULL) {
+ ckfree(bestVersion);
+ bestVersion = NULL;
}
- if (pkgPtr->version == NULL) {
- Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "can't find package %s", name));
- Tcl_SetErrorCode(interp, "TCL", "PACKAGE", "UNFOUND", NULL);
- AddRequirementsToResult(interp, reqc, reqv);
- return TCL_ERROR;
+ if (bestStableVersion != NULL) {
+ ckfree(bestStableVersion);
+ bestStableVersion = NULL;
}
/*
- * At this point we know that the package is present. Make sure that the
- * provided version meets the current requirements.
+ * 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 (reqc != 0) {
- CheckVersionAndConvert(interp, pkgPtr->version, &pkgVersionI, NULL);
- satisfies = SomeRequirementSatisfied(pkgVersionI, reqc, reqv);
+ if ((iPtr->packagePrefer == PKG_PREFER_STABLE)
+ && (bestStablePtr != NULL)) {
+ bestPtr = bestStablePtr;
+ }
- ckfree(pkgVersionI);
+ if (bestPtr == NULL) {
+ Tcl_NRAddCallback(interp, data[3], reqPtr, INT2PTR(reqc), (void *)reqv, NULL);
+ } else {
+ /*
+ * We found an ifneeded script for the package. Be careful while
+ * executing it: this could cause reentrancy, so (a) protect the
+ * script itself from deletion and (b) don't assume that bestPtr
+ * will still exist when the script completes.
+ */
- if (!satisfies) {
+ char *versionToProvide = bestPtr->version;
+ Tcl_Preserve(versionToProvide);
+ pkgPtr->clientData = versionToProvide;
+ if (bestPtr->pkgIndex) {
+ TclPkgFileSeen(interp, bestPtr->pkgIndex);
+ }
+ reqPtr->versionToProvide = versionToProvide;
+ Tcl_NRAddCallback(interp, SelectPackageFinal, reqPtr, INT2PTR(reqc), (void *)reqv, data[3]);
+ Tcl_NREvalObj(interp, Tcl_NewStringObj(bestPtr->script, -1), TCL_EVAL_GLOBAL);
+ }
+ return TCL_OK;
+}
+
+static int
+SelectPackageFinal(ClientData data[], Tcl_Interp *interp, int result) {
+ Require *reqPtr = data[0];
+ int reqc = PTR2INT(data[1]);
+ Tcl_Obj **const reqv = data[2];
+ const char *name = reqPtr->name;
+ char *versionToProvide = reqPtr->versionToProvide;
+
+ PkgFiles *pkgFiles;
+ PkgName *pkgName;
+
+ pkgFiles = TclInitPkgFiles(interp);
+ /* Push "ifneeded" package name in "tclPkgFiles" assocdata. */
+ pkgName = ckalloc(sizeof(PkgName) + strlen(name));
+ pkgName->nextPtr = pkgFiles->names;
+ strcpy(pkgName->name, name);
+ pkgFiles->names = pkgName;
+
+ /* Pop the "ifneeded" package name from "tclPkgFiles" assocdata*/
+ pkgFiles->names = pkgName->nextPtr;
+ ckfree(pkgName);
+
+ reqPtr->pkgPtr = FindPackage(interp, name);
+ if (result == TCL_OK) {
+ Tcl_ResetResult(interp);
+ if (reqPtr->pkgPtr->version == NULL) {
+ result = TCL_ERROR;
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "version conflict for package \"%s\": have %s, need",
- name, pkgPtr->version));
- Tcl_SetErrorCode(interp, "TCL", "PACKAGE", "VERSIONCONFLICT",
+ "attempt to provide package %s %s failed:"
+ " no version of package %s provided",
+ name, versionToProvide, name));
+ Tcl_SetErrorCode(interp, "TCL", "PACKAGE", "UNPROVIDED",
NULL);
- AddRequirementsToResult(interp, reqc, reqv);
- return TCL_ERROR;
+ } else {
+ char *pvi, *vi;
+
+ if (CheckVersionAndConvert(interp, reqPtr->pkgPtr->version, &pvi,
+ NULL) != TCL_OK) {
+ result = TCL_ERROR;
+ } else if (CheckVersionAndConvert(interp,
+ versionToProvide, &vi, NULL) != TCL_OK) {
+ ckfree(pvi);
+ result = TCL_ERROR;
+ } else {
+ int res = CompareVersions(pvi, vi, NULL);
+
+ ckfree(pvi);
+ ckfree(vi);
+ if (res != 0) {
+ result = TCL_ERROR;
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "attempt to provide package %s %s failed:"
+ " package %s %s provided instead",
+ name, versionToProvide,
+ name, reqPtr->pkgPtr->version));
+ Tcl_SetErrorCode(interp, "TCL", "PACKAGE",
+ "WRONGPROVIDE", NULL);
+ }
+ }
}
+ } else if (result != TCL_ERROR) {
+ Tcl_Obj *codePtr = Tcl_NewIntObj(result);
+
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "attempt to provide package %s %s failed:"
+ " bad return code: %s",
+ name, versionToProvide, TclGetString(codePtr)));
+ Tcl_SetErrorCode(interp, "TCL", "PACKAGE", "BADRESULT", NULL);
+ TclDecrRefCount(codePtr);
+ result = TCL_ERROR;
}
- if (clientDataPtr) {
- const void **ptr = (const void **) clientDataPtr;
+ if (result == TCL_ERROR) {
+ Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
+ "\n (\"package ifneeded %s %s\" script)",
+ name, versionToProvide));
+ }
+ Tcl_Release(versionToProvide);
- *ptr = pkgPtr->clientData;
+ if (result != 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.
+ *
+ * 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 (reqPtr->pkgPtr->version != NULL) {
+ ckfree(reqPtr->pkgPtr->version);
+ reqPtr->pkgPtr->version = NULL;
+ }
+ reqPtr->pkgPtr->clientData = NULL;
+ return result;
}
- Tcl_SetObjResult(interp, Tcl_NewStringObj(pkgPtr->version, -1));
+
+ Tcl_NRAddCallback(interp, data[3], reqPtr, INT2PTR(reqc), (void *)reqv, NULL);
return TCL_OK;
}
@@ -860,10 +946,19 @@ Tcl_PkgPresentEx(
*
*----------------------------------------------------------------------
*/
+int
+Tcl_PackageObjCmd(
+ ClientData dummy, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument objects. */
+{
+ return Tcl_NRCallObjProc(interp, TclNRPackageObjCmd, NULL, objc, objv);
+}
/* ARGSUSED */
int
-Tcl_PackageObjCmd(
+TclNRPackageObjCmd(
ClientData dummy, /* Not used. */
Tcl_Interp *interp, /* Current interpreter. */
int objc, /* Number of arguments. */
@@ -880,7 +975,7 @@ Tcl_PackageObjCmd(
PKG_VERSIONS, PKG_VSATISFIES
};
Interp *iPtr = (Interp *) interp;
- int optionIndex, exact, i, satisfies;
+ int optionIndex, exact, i, newobjc, satisfies;
PkgAvail *availPtr, *prevPtr;
Package *pkgPtr;
Tcl_HashEntry *hPtr;
@@ -889,6 +984,7 @@ Tcl_PackageObjCmd(
const char *version;
const char *argv2, *argv3, *argv4;
char *iva = NULL, *ivb = NULL;
+ Tcl_Obj *objvListPtr, **newObjvPtr;
if (objc < 2) {
Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?");
@@ -1134,7 +1230,6 @@ Tcl_PackageObjCmd(
argv2 = TclGetString(objv[2]);
if ((argv2[0] == '-') && (strcmp(argv2, "-exact") == 0)) {
Tcl_Obj *ov;
- int res;
if (objc != 5) {
goto requireSyntax;
@@ -1151,20 +1246,42 @@ Tcl_PackageObjCmd(
*/
ov = Tcl_NewStringObj(version, -1);
+ Tcl_IncrRefCount(ov);
Tcl_AppendStringsToObj(ov, "-", version, NULL);
version = NULL;
argv3 = TclGetString(objv[3]);
+ Tcl_IncrRefCount(objv[3]);
- Tcl_IncrRefCount(ov);
- res = Tcl_PkgRequireProc(interp, argv3, 1, &ov, NULL);
- TclDecrRefCount(ov);
- return res;
+ objvListPtr = Tcl_NewListObj(0, NULL);
+ Tcl_IncrRefCount(objvListPtr);
+ Tcl_ListObjAppendElement(interp, objvListPtr, ov);
+ Tcl_ListObjGetElements(interp, objvListPtr, &newobjc, &newObjvPtr);
+
+ Tcl_NRAddCallback(interp, TclNRPackageObjCmdCleanup, objv[3], objvListPtr, NULL, NULL);
+ Tcl_NRAddCallback(interp, PkgRequireCore, (void *)argv3, INT2PTR(newobjc), newObjvPtr, NULL);
+ return TCL_OK;
} else {
+ int i, newobjc = objc-3;
+ Tcl_Obj *const *newobjv = objv + 3;
if (CheckAllRequirements(interp, objc-3, objv+3) != TCL_OK) {
return TCL_ERROR;
}
+ objvListPtr = Tcl_NewListObj(0, NULL);
+ Tcl_IncrRefCount(objvListPtr);
+ Tcl_IncrRefCount(objv[2]);
+ for (i = 0; i < newobjc; i++) {
+
+ /*
+ * Tcl_Obj structures may have come from another interpreter,
+ * so duplicate them.
+ */
- return Tcl_PkgRequireProc(interp, argv2, objc-3, objv+3, NULL);
+ Tcl_ListObjAppendElement(interp, objvListPtr, Tcl_DuplicateObj(newobjv[i]));
+ }
+ Tcl_ListObjGetElements(interp, objvListPtr, &newobjc, &newObjvPtr);
+ Tcl_NRAddCallback(interp, TclNRPackageObjCmdCleanup, objv[2], objvListPtr, NULL, NULL);
+ Tcl_NRAddCallback(interp, PkgRequireCore, (void *)argv2, INT2PTR(newobjc), newObjvPtr, NULL);
+ return TCL_OK;
}
break;
case PKG_UNKNOWN: {
@@ -1304,6 +1421,13 @@ Tcl_PackageObjCmd(
}
return TCL_OK;
}
+
+static int
+TclNRPackageObjCmdCleanup(ClientData data[], Tcl_Interp *interp, int result) {
+ TclDecrRefCount((Tcl_Obj *)data[0]);
+ TclDecrRefCount((Tcl_Obj *)data[1]);
+ return result;
+}
/*
*----------------------------------------------------------------------
diff --git a/generic/tclProc.c b/generic/tclProc.c
index da729ef..03a2880 100644
--- a/generic/tclProc.c
+++ b/generic/tclProc.c
@@ -790,7 +790,7 @@ TclObjGetFrame(
level = curLevel - level;
result = 1;
} else if (objPtr->typePtr == &levelReferenceType) {
- level = (int) objPtr->internalRep.longValue;
+ level = (int) objPtr->internalRep.wideValue;
result = 1;
} else {
name = TclGetString(objPtr);
@@ -798,7 +798,7 @@ TclObjGetFrame(
if (TCL_OK == Tcl_GetInt(NULL, name+1, &level) && level >= 0) {
TclFreeIntRep(objPtr);
objPtr->typePtr = &levelReferenceType;
- objPtr->internalRep.longValue = level;
+ objPtr->internalRep.wideValue = level;
result = 1;
} else {
result = -1;
diff --git a/generic/tclScan.c b/generic/tclScan.c
index 2544c22..0cd23d8 100644
--- a/generic/tclScan.c
+++ b/generic/tclScan.c
@@ -942,7 +942,7 @@ Tcl_ScanObjCmd(
(Tcl_WideUInt)wideValue);
Tcl_SetStringObj(objPtr, buf, -1);
} else {
- Tcl_SetWideIntObj(objPtr, wideValue);
+ TclSetIntObj(objPtr, wideValue);
}
} else if (!(flags & SCAN_BIG)) {
if (TclGetLongFromObj(NULL, objPtr, &value) != TCL_OK) {
@@ -956,7 +956,7 @@ Tcl_ScanObjCmd(
sprintf(buf, "%lu", value); /* INTL: ISO digit */
Tcl_SetStringObj(objPtr, buf, -1);
} else {
- Tcl_SetLongObj(objPtr, value);
+ TclSetIntObj(objPtr, value);
}
}
objs[objIndex++] = objPtr;
diff --git a/generic/tclStrToD.c b/generic/tclStrToD.c
index a26c361..5cf6969 100755..100644
--- a/generic/tclStrToD.c
+++ b/generic/tclStrToD.c
@@ -1208,32 +1208,18 @@ TclParseNumber(
}
}
if (!octalSignificandOverflow) {
- if (octalSignificandWide >
- (Tcl_WideUInt)(((~(unsigned long)0) >> 1) + signum)) {
-#ifndef TCL_WIDE_INT_IS_LONG
- if (octalSignificandWide <= (MOST_BITS + signum)) {
- objPtr->typePtr = &tclWideIntType;
- if (signum) {
- objPtr->internalRep.wideValue =
- - (Tcl_WideInt) octalSignificandWide;
- } else {
- objPtr->internalRep.wideValue =
- (Tcl_WideInt) octalSignificandWide;
- }
- break;
- }
-#endif
+ if (octalSignificandWide > (MOST_BITS + signum)) {
TclInitBignumFromWideUInt(&octalSignificandBig,
octalSignificandWide);
octalSignificandOverflow = 1;
} else {
objPtr->typePtr = &tclIntType;
if (signum) {
- objPtr->internalRep.longValue =
- - (long) octalSignificandWide;
+ objPtr->internalRep.wideValue =
+ - (Tcl_WideInt) octalSignificandWide;
} else {
- objPtr->internalRep.longValue =
- (long) octalSignificandWide;
+ objPtr->internalRep.wideValue =
+ (Tcl_WideInt) octalSignificandWide;
}
}
}
@@ -1255,32 +1241,18 @@ TclParseNumber(
}
returnInteger:
if (!significandOverflow) {
- if (significandWide >
- (Tcl_WideUInt)(((~(unsigned long)0) >> 1) + signum)) {
-#ifndef TCL_WIDE_INT_IS_LONG
- if (significandWide <= MOST_BITS+signum) {
- objPtr->typePtr = &tclWideIntType;
- if (signum) {
- objPtr->internalRep.wideValue =
- - (Tcl_WideInt) significandWide;
- } else {
- objPtr->internalRep.wideValue =
- (Tcl_WideInt) significandWide;
- }
- break;
- }
-#endif
+ if (significandWide > MOST_BITS+signum) {
TclInitBignumFromWideUInt(&significandBig,
significandWide);
significandOverflow = 1;
} else {
objPtr->typePtr = &tclIntType;
if (signum) {
- objPtr->internalRep.longValue =
- - (long) significandWide;
+ objPtr->internalRep.wideValue =
+ - (Tcl_WideInt) significandWide;
} else {
- objPtr->internalRep.longValue =
- (long) significandWide;
+ objPtr->internalRep.wideValue =
+ (Tcl_WideInt) significandWide;
}
}
}
diff --git a/generic/tclStringObj.c b/generic/tclStringObj.c
index c370a85..4829338 100644
--- a/generic/tclStringObj.c
+++ b/generic/tclStringObj.c
@@ -140,8 +140,8 @@ GrowStringBuffer(
objPtr->bytes = NULL;
}
if (flag == 0 || stringPtr->allocated > 0) {
- attempt = 2 * needed;
- if (attempt >= 0) {
+ if (needed <= INT_MAX / 2) {
+ attempt = 2 * needed;
ptr = attemptckrealloc(objPtr->bytes, attempt + 1);
}
if (ptr == NULL) {
@@ -190,8 +190,8 @@ GrowUnicodeBuffer(
* Subsequent appends - apply the growth algorithm.
*/
- attempt = 2 * needed;
- if (attempt >= 0 && attempt <= STRING_MAXCHARS) {
+ if (needed <= STRING_MAXCHARS / 2) {
+ attempt = 2 * needed;
ptr = stringAttemptRealloc(stringPtr, attempt);
}
if (ptr == NULL) {
@@ -2682,23 +2682,24 @@ TclGetStringStorage(
* Performs the [string repeat] function.
*
* Results:
- * A standard Tcl result.
+ * A (Tcl_Obj *) pointing to the result value, or NULL in case of an
+ * error.
*
* Side effects:
- * Writes to *objPtrPtr the address of Tcl_Obj that is concatenation
- * of count copies of the value in objPtr.
+ * On error, when interp is not NULL, error information is left in it.
*
*---------------------------------------------------------------------------
*/
-int
+Tcl_Obj *
TclStringRepeat(
Tcl_Interp *interp,
Tcl_Obj *objPtr,
int count,
- Tcl_Obj **objPtrPtr)
+ int flags)
{
Tcl_Obj *objResultPtr;
+ int inPlace = flags & TCL_STRING_IN_PLACE;
int length = 0, unichar = 0, done = 1;
int binary = TclIsPureByteArray(objPtr);
@@ -2733,8 +2734,7 @@ TclStringRepeat(
if (length == 0) {
/* Any repeats of empty is empty. */
- *objPtrPtr = objPtr;
- return TCL_OK;
+ return objPtr;
}
if (count > INT_MAX/length) {
@@ -2743,13 +2743,13 @@ TclStringRepeat(
"max size for a Tcl value (%d bytes) exceeded", INT_MAX));
Tcl_SetErrorCode(interp, "TCL", "MEMORY", NULL);
}
- return TCL_ERROR;
+ return NULL;
}
if (binary) {
/* Efficiently produce a pure byte array result */
- objResultPtr = Tcl_IsShared(objPtr) ? Tcl_DuplicateObj(objPtr)
- : objPtr;
+ objResultPtr = (!inPlace || Tcl_IsShared(objPtr)) ?
+ Tcl_DuplicateObj(objPtr) : objPtr;
Tcl_SetByteArrayLength(objResultPtr, count*length); /* PANIC? */
Tcl_SetByteArrayLength(objResultPtr, length);
@@ -2762,7 +2762,7 @@ TclStringRepeat(
(count - done) * length);
} else if (unichar) {
/* Efficiently produce a pure Tcl_UniChar array result */
- if (Tcl_IsShared(objPtr)) {
+ if (!inPlace || Tcl_IsShared(objPtr)) {
objResultPtr = Tcl_NewUnicodeObj(Tcl_GetUnicode(objPtr), length);
} else {
TclInvalidateStringRep(objPtr);
@@ -2777,7 +2777,7 @@ TclStringRepeat(
(Tcl_WideUInt)STRING_SIZE(count*length)));
Tcl_SetErrorCode(interp, "TCL", "MEMORY", NULL);
}
- return TCL_ERROR;
+ return NULL;
}
Tcl_SetObjLength(objResultPtr, length);
while (count - done > done) {
@@ -2788,7 +2788,7 @@ TclStringRepeat(
(count - done) * length);
} else {
/* Efficiently concatenate string reps */
- if (Tcl_IsShared(objPtr)) {
+ if (!inPlace || Tcl_IsShared(objPtr)) {
objResultPtr = Tcl_NewStringObj(Tcl_GetString(objPtr), length);
} else {
TclFreeIntRep(objPtr);
@@ -2801,7 +2801,7 @@ TclStringRepeat(
count*length));
Tcl_SetErrorCode(interp, "TCL", "MEMORY", NULL);
}
- return TCL_ERROR;
+ return NULL;
}
Tcl_SetObjLength(objResultPtr, length);
while (count - done > done) {
@@ -2811,47 +2811,45 @@ TclStringRepeat(
Tcl_AppendToObj(objResultPtr, Tcl_GetString(objResultPtr),
(count - done) * length);
}
- *objPtrPtr = objResultPtr;
- return TCL_OK;
+ return objResultPtr;
}
/*
*---------------------------------------------------------------------------
*
- * TclStringCatObjv --
+ * TclStringCat --
*
* Performs the [string cat] function.
*
* Results:
- * A standard Tcl result.
+ * A (Tcl_Obj *) pointing to the result value, or NULL in case of an
+ * error.
*
* Side effects:
- * Writes to *objPtrPtr the address of Tcl_Obj that is concatenation
- * of all objc values in objv.
+ * On error, when interp is not NULL, error information is left in it.
*
*---------------------------------------------------------------------------
*/
-int
-TclStringCatObjv(
+Tcl_Obj *
+TclStringCat(
Tcl_Interp *interp,
- int inPlace,
int objc,
Tcl_Obj * const objv[],
- Tcl_Obj **objPtrPtr)
+ int flags)
{
Tcl_Obj *objResultPtr, * const *ov;
int oc, length = 0, binary = 1;
int allowUniChar = 1, requestUniChar = 0;
int first = objc - 1; /* Index of first value possibly not empty */
int last = 0; /* Index of last value possibly not empty */
+ int inPlace = flags & TCL_STRING_IN_PLACE;
/* assert ( objc >= 0 ) */
if (objc <= 1) {
/* Only one or no objects; return first or empty */
- *objPtrPtr = objc ? objv[0] : Tcl_NewObj();
- return TCL_OK;
+ return objc ? objv[0] : Tcl_NewObj();
}
/* assert ( objc >= 2 ) */
@@ -3028,8 +3026,7 @@ TclStringCatObjv(
if (last <= first /*|| length == 0 */) {
/* Only one non-empty value or zero length; return first */
/* NOTE: (length == 0) implies (last <= first) */
- *objPtrPtr = objv[first];
- return TCL_OK;
+ return objv[first];
}
objv += first; objc = (last - first + 1);
@@ -3083,7 +3080,7 @@ TclStringCatObjv(
(Tcl_WideUInt)STRING_SIZE(length)));
Tcl_SetErrorCode(interp, "TCL", "MEMORY", NULL);
}
- return TCL_ERROR;
+ return NULL;
}
dst = Tcl_GetUnicode(objResultPtr) + start;
} else {
@@ -3100,7 +3097,7 @@ TclStringCatObjv(
(Tcl_WideUInt)STRING_SIZE(length)));
Tcl_SetErrorCode(interp, "TCL", "MEMORY", NULL);
}
- return TCL_ERROR;
+ return NULL;
}
dst = Tcl_GetUnicode(objResultPtr);
}
@@ -3131,7 +3128,7 @@ TclStringCatObjv(
length));
Tcl_SetErrorCode(interp, "TCL", "MEMORY", NULL);
}
- return TCL_ERROR;
+ return NULL;
}
dst = Tcl_GetString(objResultPtr) + start;
@@ -3147,7 +3144,7 @@ TclStringCatObjv(
length));
Tcl_SetErrorCode(interp, "TCL", "MEMORY", NULL);
}
- return TCL_ERROR;
+ return NULL;
}
dst = Tcl_GetString(objResultPtr);
}
@@ -3162,8 +3159,7 @@ TclStringCatObjv(
}
}
}
- *objPtrPtr = objResultPtr;
- return TCL_OK;
+ return objResultPtr;
overflow:
if (interp) {
@@ -3171,13 +3167,13 @@ TclStringCatObjv(
"max size for a Tcl value (%d bytes) exceeded", INT_MAX));
Tcl_SetErrorCode(interp, "TCL", "MEMORY", NULL);
}
- return TCL_ERROR;
+ return NULL;
}
/*
*---------------------------------------------------------------------------
*
- * TclStringFind --
+ * TclStringFirst --
*
* Implements the [string first] operation.
*
@@ -3193,20 +3189,20 @@ TclStringCatObjv(
*/
int
-TclStringFind(
+TclStringFirst(
Tcl_Obj *needle,
Tcl_Obj *haystack,
int start)
{
int lh, ln = Tcl_GetCharLength(needle);
+ if (start < 0) {
+ start = 0;
+ }
if (ln == 0) {
- /*
- * We don't find empty substrings. Bizarre!
- *
- * TODO: When we one day make this a true substring
- * finder, change this to "return 0"
- */
+ /* We don't find empty substrings. Bizarre!
+ * Whenever this routine is turned into a proper substring
+ * finder, change to `return start` after limits imposed. */
return -1;
}
@@ -3214,51 +3210,46 @@ TclStringFind(
unsigned char *end, *try, *bh;
unsigned char *bn = Tcl_GetByteArrayFromObj(needle, &ln);
+ /* Find bytes in bytes */
bh = Tcl_GetByteArrayFromObj(haystack, &lh);
end = bh + lh;
try = bh + start;
while (try + ln <= end) {
- try = memchr(try, bn[0], end - try);
-
+ /*
+ * Look for the leading byte of the needle in the haystack
+ * starting at try and stopping when there's not enough room
+ * for the needle left.
+ */
+ try = memchr(try, bn[0], (end + 1 - ln) - try);
if (try == NULL) {
+ /* Leading byte not found -> needle cannot be found. */
return -1;
}
+ /* Leading byte found, check rest of needle. */
if (0 == memcmp(try+1, bn+1, ln-1)) {
+ /* Checks! Return the successful index. */
return (try - bh);
}
+ /* Rest of needle match failed; Iterate to continue search. */
try++;
}
return -1;
}
/*
- * Check if we have two strings of single-byte characters. If we have, we
- * can use strstr() to do the search. Note that we can sometimes have
- * multibyte characters when the string could be minimally represented
- * using single byte characters; we can't assume that a mismatch here
- * means no match.
+ * TODO: It might be nice to support some cases where it is not
+ * necessary to shimmer to &tclStringType to compute the result,
+ * and instead operate just on the objPtr->bytes values directly.
+ * However, we also do not want the answer to change based on the
+ * code pathway, or if it does we want that to be for some values
+ * we explicitly decline to support. Getting there will involve
+ * locking down in practice more firmly just what encodings produce
+ * what supported results for the objPtr->bytes values. For now,
+ * do only the well-defined Tcl_UniChar array search.
*/
- lh = Tcl_GetCharLength(haystack);
- if (haystack->bytes && (lh == haystack->length) && needle->bytes
- && (ln == needle->length)) {
- /*
- * Both haystack and needle are all single-byte chars.
- */
-
- char *found = strstr(haystack->bytes + start, needle->bytes);
-
- if (found) {
- return (found - haystack->bytes);
- } else {
- return -1;
- }
- } else {
- /*
- * Do the search on the unicode representation for simplicity.
- */
-
+ {
Tcl_UniChar *try, *end, *uh;
Tcl_UniChar *un = Tcl_GetUnicodeFromObj(needle, &ln);
@@ -3306,24 +3297,24 @@ TclStringLast(
* We don't find empty substrings. Bizarre!
*
* TODO: When we one day make this a true substring
- * finder, change this to "return 0"
+ * finder, change this to "return last", after limitation.
*/
return -1;
}
- if (ln > last + 1) {
+ lh = Tcl_GetCharLength(haystack);
+ if (last >= lh) {
+ last = lh - 1;
+ }
+
+ if (last < ln - 1) {
return -1;
}
if (TclIsPureByteArray(needle) && TclIsPureByteArray(haystack)) {
- unsigned char *try, *bh;
+ unsigned char *try, *bh = Tcl_GetByteArrayFromObj(haystack, &lh);
unsigned char *bn = Tcl_GetByteArrayFromObj(needle, &ln);
- bh = Tcl_GetByteArrayFromObj(haystack, &lh);
-
- if (last + 1 > lh) {
- last = lh - 1;
- }
try = bh + last + 1 - ln;
while (try >= bh) {
if ((*try == bn[0])
@@ -3335,38 +3326,10 @@ TclStringLast(
return -1;
}
- lh = Tcl_GetCharLength(haystack);
- if (last + 1 > lh) {
- last = lh - 1;
- }
- if (haystack->bytes && (lh == haystack->length)) {
- /* haystack is all single-byte chars */
-
- if (needle->bytes && (ln == needle->length)) {
- /* needle is also all single-byte chars */
-
- char *try = haystack->bytes + last + 1 - ln;
- while (try >= haystack->bytes) {
- if ((*try == needle->bytes[0])
- && (0 == memcmp(try+1, needle->bytes + 1, ln - 1))) {
- return (try - haystack->bytes);
- }
- try--;
- }
- return -1;
- } else {
- /*
- * Cannot find substring with a multi-byte char inside
- * a string with no multi-byte chars.
- */
- return -1;
- }
- } else {
- Tcl_UniChar *try, *uh;
+ {
+ Tcl_UniChar *try, *uh = Tcl_GetUnicodeFromObj(haystack, &lh);
Tcl_UniChar *un = Tcl_GetUnicodeFromObj(needle, &ln);
- uh = Tcl_GetUnicodeFromObj(haystack, &lh);
-
try = uh + last + 1 - ln;
while (try >= uh) {
if ((*try == un[0])
@@ -3382,14 +3345,14 @@ TclStringLast(
/*
*---------------------------------------------------------------------------
*
- * TclStringObjReverse --
+ * TclStringReverse --
*
* Implements the [string reverse] operation.
*
* Results:
- * An unshared Tcl value which is the [string reverse] of the argument
- * supplied. When sharing rules permit, the returned value might be the
- * argument with modifications done in place.
+ * A Tcl value which is the [string reverse] of the argument supplied.
+ * When sharing rules permit and the caller requests, the returned value
+ * might be the argument with modifications done in place.
*
* Side effects:
* May allocate a new Tcl_Obj.
@@ -3420,17 +3383,19 @@ ReverseBytes(
}
Tcl_Obj *
-TclStringObjReverse(
- Tcl_Obj *objPtr)
+TclStringReverse(
+ Tcl_Obj *objPtr,
+ int flags)
{
String *stringPtr;
Tcl_UniChar ch = 0;
+ int inPlace = flags & TCL_STRING_IN_PLACE;
if (TclIsPureByteArray(objPtr)) {
int numBytes;
unsigned char *from = Tcl_GetByteArrayFromObj(objPtr, &numBytes);
- if (Tcl_IsShared(objPtr)) {
+ if (!inPlace || Tcl_IsShared(objPtr)) {
objPtr = Tcl_NewByteArrayObj(NULL, numBytes);
}
ReverseBytes(Tcl_GetByteArrayFromObj(objPtr, NULL), from, numBytes);
@@ -3444,7 +3409,7 @@ TclStringObjReverse(
Tcl_UniChar *from = Tcl_GetUnicode(objPtr);
Tcl_UniChar *src = from + stringPtr->numChars;
- if (Tcl_IsShared(objPtr)) {
+ if (!inPlace || Tcl_IsShared(objPtr)) {
Tcl_UniChar *to;
/*
@@ -3473,7 +3438,7 @@ TclStringObjReverse(
int numBytes = objPtr->length;
char *to, *from = objPtr->bytes;
- if (Tcl_IsShared(objPtr)) {
+ if (!inPlace || Tcl_IsShared(objPtr)) {
objPtr = Tcl_NewObj();
Tcl_SetObjLength(objPtr, numBytes);
}
diff --git a/generic/tclStubInit.c b/generic/tclStubInit.c
index fcdc546..2506da3 100644
--- a/generic/tclStubInit.c
+++ b/generic/tclStubInit.c
@@ -31,6 +31,7 @@
#undef Tcl_NewIntObj
#undef Tcl_NewListObj
#undef Tcl_NewLongObj
+#undef Tcl_DbNewLongObj
#undef Tcl_NewObj
#undef Tcl_NewStringObj
#undef Tcl_DumpActiveMemory
@@ -151,7 +152,7 @@ static Tcl_Obj *dbNewLongObj(
TclDbNewObj(objPtr, file, line);
objPtr->bytes = NULL;
- objPtr->internalRep.longValue = (long) intValue;
+ objPtr->internalRep.wideValue = (long) intValue;
objPtr->typePtr = &tclIntType;
return objPtr;
#else
diff --git a/generic/tclTestObj.c b/generic/tclTestObj.c
index 5627608..547792a 100644
--- a/generic/tclTestObj.c
+++ b/generic/tclTestObj.c
@@ -1088,6 +1088,9 @@ TestobjCmd(
Tcl_SetObjResult(interp, Tcl_NewStringObj("none", -1));
} else {
typeName = objv[2]->typePtr->name;
+#ifndef TCL_WIDE_INT_IS_LONG
+ if (!strcmp(typeName, "wideInt")) typeName = "int";
+#endif
Tcl_SetObjResult(interp, Tcl_NewStringObj(typeName, -1));
}
} else if (strcmp(subCmd, "refcount") == 0) {
@@ -1115,6 +1118,11 @@ TestobjCmd(
}
if (varPtr[varIndex]->typePtr == NULL) { /* a string! */
Tcl_AppendToObj(Tcl_GetObjResult(interp), "string", -1);
+#ifndef TCL_WIDE_INT_IS_LONG
+ } else if (!strcmp(varPtr[varIndex]->typePtr->name, "wideInt")) {
+ Tcl_AppendToObj(Tcl_GetObjResult(interp),
+ "int", -1);
+#endif
} else {
Tcl_AppendToObj(Tcl_GetObjResult(interp),
varPtr[varIndex]->typePtr->name, -1);
diff --git a/generic/tclTimer.c b/generic/tclTimer.c
index 3467305..54854d0 100644
--- a/generic/tclTimer.c
+++ b/generic/tclTimer.c
@@ -819,9 +819,6 @@ Tcl_AfterObjCmd(
*/
if (objv[1]->typePtr == &tclIntType
-#ifndef TCL_WIDE_INT_IS_LONG
- || objv[1]->typePtr == &tclWideIntType
-#endif
|| objv[1]->typePtr == &tclBignumType
|| (Tcl_GetIndexFromObj(NULL, objv[1], afterSubCmds, "", 0,
&index) != TCL_OK)) {
@@ -1045,37 +1042,27 @@ AfterDelay(
if (iPtr->limit.timeEvent == NULL
|| TCL_TIME_BEFORE(endTime, iPtr->limit.time)) {
diff = TCL_TIME_DIFF_MS_CEILING(endTime, now);
-#ifndef TCL_WIDE_INT_IS_LONG
- if (diff > LONG_MAX) {
- diff = LONG_MAX;
- }
-#endif
if (diff > TCL_TIME_MAXIMUM_SLICE) {
diff = TCL_TIME_MAXIMUM_SLICE;
}
- if (diff == 0 && TCL_TIME_BEFORE(now, endTime)) {
- diff = 1;
- }
+ if (diff == 0 && TCL_TIME_BEFORE(now, endTime)) {
+ diff = 1;
+ }
if (diff > 0) {
- Tcl_Sleep((long) diff);
- if (diff < SLEEP_OFFLOAD_GETTIMEOFDAY) {
- break;
- }
+ Tcl_Sleep((int) diff);
+ if (diff < SLEEP_OFFLOAD_GETTIMEOFDAY) {
+ break;
+ }
} else {
- break;
- }
+ break;
+ }
} else {
diff = TCL_TIME_DIFF_MS(iPtr->limit.time, now);
-#ifndef TCL_WIDE_INT_IS_LONG
- if (diff > LONG_MAX) {
- diff = LONG_MAX;
- }
-#endif
if (diff > TCL_TIME_MAXIMUM_SLICE) {
diff = TCL_TIME_MAXIMUM_SLICE;
}
if (diff > 0) {
- Tcl_Sleep((long) diff);
+ Tcl_Sleep((int) diff);
}
if (Tcl_AsyncReady()) {
if (Tcl_AsyncInvoke(interp, TCL_OK) != TCL_OK) {
@@ -1089,7 +1076,7 @@ AfterDelay(
return TCL_ERROR;
}
}
- Tcl_GetTime(&now);
+ Tcl_GetTime(&now);
} while (TCL_TIME_BEFORE(now, endTime));
return TCL_OK;
}
diff --git a/generic/tclUtil.c b/generic/tclUtil.c
index 7b969af..527e41a 100644
--- a/generic/tclUtil.c
+++ b/generic/tclUtil.c
@@ -3221,9 +3221,9 @@ int
TclFormatInt(
char *buffer, /* Points to the storage into which the
* formatted characters are written. */
- long n) /* The integer to format. */
+ Tcl_WideInt n) /* The integer to format. */
{
- long intVal;
+ Tcl_WideInt intVal;
int i;
int numFormatted, j;
const char *digits = "0123456789";
@@ -3246,7 +3246,7 @@ TclFormatInt(
intVal = -n; /* [Bug 3390638] Workaround for*/
if (n == -n || intVal == n) { /* broken compiler optimizers. */
- return sprintf(buffer, "%ld", n);
+ return sprintf(buffer, "%" TCL_LL_MODIFIER "d", n);
}
/*
@@ -3335,7 +3335,7 @@ TclGetIntForIndex(
* be converted to one, use it.
*/
- *indexPtr = endValue + objPtr->internalRep.longValue;
+ *indexPtr = endValue + objPtr->internalRep.wideValue;
return TCL_OK;
}
@@ -3426,9 +3426,9 @@ UpdateStringOfEndOffset(
register int len = 3;
memcpy(buffer, "end", 4);
- if (objPtr->internalRep.longValue != 0) {
+ if (objPtr->internalRep.wideValue != 0) {
buffer[len++] = '-';
- len += TclFormatInt(buffer+len, -(objPtr->internalRep.longValue));
+ len += TclFormatInt(buffer+len, -(objPtr->internalRep.wideValue));
}
objPtr->bytes = ckalloc((unsigned) len+1);
memcpy(objPtr->bytes, buffer, (unsigned) len+1);
@@ -3458,7 +3458,7 @@ SetEndOffsetFromAny(
Tcl_Interp *interp, /* Tcl interpreter or NULL */
Tcl_Obj *objPtr) /* Pointer to the object to parse */
{
- int offset; /* Offset in the "end-offset" expression */
+ Tcl_WideInt offset; /* Offset in the "end-offset" expression */
register const char *bytes; /* String rep of the object */
int length; /* Length of the object's string rep */
@@ -3494,15 +3494,20 @@ SetEndOffsetFromAny(
} else if ((length > 4) && ((bytes[3] == '-') || (bytes[3] == '+'))) {
/*
* This is our limited string expression evaluator. Pass everything
- * after "end-" to Tcl_GetInt, then reverse for offset.
+ * after "end-" to TclParseNumber.
*/
if (TclIsSpaceProc(bytes[4])) {
goto badIndexFormat;
}
- if (Tcl_GetInt(interp, bytes+4, &offset) != TCL_OK) {
+ if (TclParseNumber(NULL, objPtr, NULL, bytes+4, length-4, NULL,
+ TCL_PARSE_INTEGER_ONLY) != TCL_OK) {
return TCL_ERROR;
}
+ if (objPtr->typePtr != &tclIntType) {
+ goto badIndexFormat;
+ }
+ offset = objPtr->internalRep.wideValue;
if (bytes[3] == '-') {
offset = -offset;
}
@@ -3526,7 +3531,7 @@ SetEndOffsetFromAny(
*/
TclFreeIntRep(objPtr);
- objPtr->internalRep.longValue = offset;
+ objPtr->internalRep.wideValue = offset;
objPtr->typePtr = &tclEndOffsetType;
return TCL_OK;
diff --git a/generic/tclZlib.c b/generic/tclZlib.c
index 33eebd1..994bcef 100644
--- a/generic/tclZlib.c
+++ b/generic/tclZlib.c
@@ -373,7 +373,7 @@ ConvertErrorToList(
default:
TclNewLiteralStringObj(objv[2], "UNKNOWN");
- TclNewLongObj(objv[3], code);
+ TclNewIntObj(objv[3], code);
return Tcl_NewListObj(4, objv);
}
}
diff --git a/library/http1.0/http.tcl b/library/http1.0/http.tcl
deleted file mode 100644
index 8329de4..0000000
--- a/library/http1.0/http.tcl
+++ /dev/null
@@ -1,377 +0,0 @@
-# http.tcl
-# Client-side HTTP for GET, POST, and HEAD commands.
-# These routines can be used in untrusted code that uses the Safesock
-# security policy.
-# These procedures use a callback interface to avoid using vwait,
-# which is not defined in the safe base.
-#
-# See the http.n man page for documentation
-
-package provide http 1.0
-
-array set http {
- -accept */*
- -proxyhost {}
- -proxyport {}
- -useragent {Tcl http client package 1.0}
- -proxyfilter httpProxyRequired
-}
-proc http_config {args} {
- global http
- set options [lsort [array names http -*]]
- set usage [join $options ", "]
- if {[llength $args] == 0} {
- set result {}
- foreach name $options {
- lappend result $name $http($name)
- }
- return $result
- }
- regsub -all -- - $options {} options
- set pat ^-([join $options |])$
- if {[llength $args] == 1} {
- set flag [lindex $args 0]
- if {[regexp -- $pat $flag]} {
- return $http($flag)
- } else {
- return -code error "Unknown option $flag, must be: $usage"
- }
- } else {
- foreach {flag value} $args {
- if {[regexp -- $pat $flag]} {
- set http($flag) $value
- } else {
- return -code error "Unknown option $flag, must be: $usage"
- }
- }
- }
-}
-
- proc httpFinish { token {errormsg ""} } {
- upvar #0 $token state
- global errorInfo errorCode
- if {[string length $errormsg] != 0} {
- set state(error) [list $errormsg $errorInfo $errorCode]
- set state(status) error
- }
- catch {close $state(sock)}
- catch {after cancel $state(after)}
- if {[info exists state(-command)]} {
- if {[catch {eval $state(-command) {$token}} err]} {
- if {[string length $errormsg] == 0} {
- set state(error) [list $err $errorInfo $errorCode]
- set state(status) error
- }
- }
- unset state(-command)
- }
-}
-proc http_reset { token {why reset} } {
- upvar #0 $token state
- set state(status) $why
- catch {fileevent $state(sock) readable {}}
- httpFinish $token
- if {[info exists state(error)]} {
- set errorlist $state(error)
- unset state(error)
- eval error $errorlist
- }
-}
-proc http_get { url args } {
- global http
- if {![info exists http(uid)]} {
- set http(uid) 0
- }
- set token http#[incr http(uid)]
- upvar #0 $token state
- http_reset $token
- array set state {
- -blocksize 8192
- -validate 0
- -headers {}
- -timeout 0
- state header
- meta {}
- currentsize 0
- totalsize 0
- type text/html
- body {}
- status ""
- }
- set options {-blocksize -channel -command -handler -headers \
- -progress -query -validate -timeout}
- set usage [join $options ", "]
- regsub -all -- - $options {} options
- set pat ^-([join $options |])$
- foreach {flag value} $args {
- if {[regexp $pat $flag]} {
- # Validate numbers
- if {[info exists state($flag)] && \
- [regexp {^[0-9]+$} $state($flag)] && \
- ![regexp {^[0-9]+$} $value]} {
- return -code error "Bad value for $flag ($value), must be integer"
- }
- set state($flag) $value
- } else {
- return -code error "Unknown option $flag, can be: $usage"
- }
- }
- if {! [regexp -nocase {^(http://)?([^/:]+)(:([0-9]+))?(/.*)?$} $url \
- x proto host y port srvurl]} {
- error "Unsupported URL: $url"
- }
- if {[string length $port] == 0} {
- set port 80
- }
- if {[string length $srvurl] == 0} {
- set srvurl /
- }
- if {[string length $proto] == 0} {
- set url http://$url
- }
- set state(url) $url
- if {![catch {$http(-proxyfilter) $host} proxy]} {
- set phost [lindex $proxy 0]
- set pport [lindex $proxy 1]
- }
- if {$state(-timeout) > 0} {
- set state(after) [after $state(-timeout) [list http_reset $token timeout]]
- }
- if {[info exists phost] && [string length $phost]} {
- set srvurl $url
- set s [socket $phost $pport]
- } else {
- set s [socket $host $port]
- }
- set state(sock) $s
-
- # Send data in cr-lf format, but accept any line terminators
-
- fconfigure $s -translation {auto crlf} -buffersize $state(-blocksize)
-
- # The following is disallowed in safe interpreters, but the socket
- # is already in non-blocking mode in that case.
-
- catch {fconfigure $s -blocking off}
- set len 0
- set how GET
- if {[info exists state(-query)]} {
- set len [string length $state(-query)]
- if {$len > 0} {
- set how POST
- }
- } elseif {$state(-validate)} {
- set how HEAD
- }
- puts $s "$how $srvurl HTTP/1.0"
- puts $s "Accept: $http(-accept)"
- puts $s "Host: $host"
- puts $s "User-Agent: $http(-useragent)"
- foreach {key value} $state(-headers) {
- regsub -all \[\n\r\] $value {} value
- set key [string trim $key]
- if {[string length $key]} {
- puts $s "$key: $value"
- }
- }
- if {$len > 0} {
- puts $s "Content-Length: $len"
- puts $s "Content-Type: application/x-www-form-urlencoded"
- puts $s ""
- fconfigure $s -translation {auto binary}
- puts -nonewline $s $state(-query)
- } else {
- puts $s ""
- }
- flush $s
- fileevent $s readable [list httpEvent $token]
- if {! [info exists state(-command)]} {
- http_wait $token
- }
- return $token
-}
-proc http_data {token} {
- upvar #0 $token state
- return $state(body)
-}
-proc http_status {token} {
- upvar #0 $token state
- return $state(status)
-}
-proc http_code {token} {
- upvar #0 $token state
- return $state(http)
-}
-proc http_size {token} {
- upvar #0 $token state
- return $state(currentsize)
-}
-
- proc httpEvent {token} {
- upvar #0 $token state
- set s $state(sock)
-
- if {[eof $s]} {
- httpEof $token
- return
- }
- if {$state(state) == "header"} {
- set n [gets $s line]
- if {$n == 0} {
- set state(state) body
- if {![regexp -nocase ^text $state(type)]} {
- # Turn off conversions for non-text data
- fconfigure $s -translation binary
- if {[info exists state(-channel)]} {
- fconfigure $state(-channel) -translation binary
- }
- }
- if {[info exists state(-channel)] &&
- ![info exists state(-handler)]} {
- # Initiate a sequence of background fcopies
- fileevent $s readable {}
- httpCopyStart $s $token
- }
- } elseif {$n > 0} {
- if {[regexp -nocase {^content-type:(.+)$} $line x type]} {
- set state(type) [string trim $type]
- }
- if {[regexp -nocase {^content-length:(.+)$} $line x length]} {
- set state(totalsize) [string trim $length]
- }
- if {[regexp -nocase {^([^:]+):(.+)$} $line x key value]} {
- lappend state(meta) $key $value
- } elseif {[regexp ^HTTP $line]} {
- set state(http) $line
- }
- }
- } else {
- if {[catch {
- if {[info exists state(-handler)]} {
- set n [eval $state(-handler) {$s $token}]
- } else {
- set block [read $s $state(-blocksize)]
- set n [string length $block]
- if {$n >= 0} {
- append state(body) $block
- }
- }
- if {$n >= 0} {
- incr state(currentsize) $n
- }
- } err]} {
- httpFinish $token $err
- } else {
- if {[info exists state(-progress)]} {
- eval $state(-progress) {$token $state(totalsize) $state(currentsize)}
- }
- }
- }
-}
- proc httpCopyStart {s token} {
- upvar #0 $token state
- if {[catch {
- fcopy $s $state(-channel) -size $state(-blocksize) -command \
- [list httpCopyDone $token]
- } err]} {
- httpFinish $token $err
- }
-}
- proc httpCopyDone {token count {error {}}} {
- upvar #0 $token state
- set s $state(sock)
- incr state(currentsize) $count
- if {[info exists state(-progress)]} {
- eval $state(-progress) {$token $state(totalsize) $state(currentsize)}
- }
- if {([string length $error] != 0)} {
- httpFinish $token $error
- } elseif {[eof $s]} {
- httpEof $token
- } else {
- httpCopyStart $s $token
- }
-}
- proc httpEof {token} {
- upvar #0 $token state
- if {$state(state) == "header"} {
- # Premature eof
- set state(status) eof
- } else {
- set state(status) ok
- }
- set state(state) eof
- httpFinish $token
-}
-proc http_wait {token} {
- upvar #0 $token state
- if {![info exists state(status)] || [string length $state(status)] == 0} {
- vwait $token\(status)
- }
- if {[info exists state(error)]} {
- set errorlist $state(error)
- unset state(error)
- eval error $errorlist
- }
- return $state(status)
-}
-
-# Call http_formatQuery with an even number of arguments, where the first is
-# a name, the second is a value, the third is another name, and so on.
-
-proc http_formatQuery {args} {
- set result ""
- set sep ""
- foreach i $args {
- append result $sep [httpMapReply $i]
- if {$sep != "="} {
- set sep =
- } else {
- set sep &
- }
- }
- return $result
-}
-
-# do x-www-urlencoded character mapping
-# The spec says: "non-alphanumeric characters are replaced by '%HH'"
-# 1 leave alphanumerics characters alone
-# 2 Convert every other character to an array lookup
-# 3 Escape constructs that are "special" to the tcl parser
-# 4 "subst" the result, doing all the array substitutions
-
- proc httpMapReply {string} {
- global httpFormMap
- set alphanumeric a-zA-Z0-9
- if {![info exists httpFormMap]} {
-
- for {set i 1} {$i <= 256} {incr i} {
- set c [format %c $i]
- if {![string match \[$alphanumeric\] $c]} {
- set httpFormMap($c) %[format %.2x $i]
- }
- }
- # These are handled specially
- array set httpFormMap {
- " " + \n %0d%0a
- }
- }
- regsub -all \[^$alphanumeric\] $string {$httpFormMap(&)} string
- regsub -all \n $string {\\n} string
- regsub -all \t $string {\\t} string
- regsub -all {[][{})\\]\)} $string {\\&} string
- return [subst $string]
-}
-
-# Default proxy filter.
- proc httpProxyRequired {host} {
- global http
- if {[info exists http(-proxyhost)] && [string length $http(-proxyhost)]} {
- if {![info exists http(-proxyport)] || ![string length $http(-proxyport)]} {
- set http(-proxyport) 8080
- }
- return [list $http(-proxyhost) $http(-proxyport)]
- } else {
- return {}
- }
-}
diff --git a/library/http1.0/pkgIndex.tcl b/library/http1.0/pkgIndex.tcl
deleted file mode 100644
index ab6170f..0000000
--- a/library/http1.0/pkgIndex.tcl
+++ /dev/null
@@ -1,11 +0,0 @@
-# Tcl package index file, version 1.0
-# This file is generated by the "pkg_mkIndex" command
-# and sourced either when an application starts up or
-# by a "package unknown" script. It invokes the
-# "package ifneeded" command to set up package-related
-# information so that packages will be loaded automatically
-# in response to "package require" commands. When this
-# script is sourced, the variable $dir must contain the
-# full path name of this file's directory.
-
-package ifneeded http 1.0 [list tclPkgSetup $dir http 1.0 {{http.tcl source {httpCopyDone httpCopyStart httpEof httpEvent httpFinish httpMapReply httpProxyRequired http_code http_config http_data http_formatQuery http_get http_reset http_size http_status http_wait}}}]
diff --git a/tests/httpold.test b/tests/httpold.test
deleted file mode 100644
index dda0189..0000000
--- a/tests/httpold.test
+++ /dev/null
@@ -1,300 +0,0 @@
-# -*- tcl -*-
-# Commands covered: http_config, http_get, http_wait, http_reset
-#
-# This file contains a collection of tests for the http script library.
-# Sourcing this file into Tcl runs the tests and
-# generates output for errors. No output means no errors were found.
-#
-# Copyright (c) 1991-1993 The Regents of the University of California.
-# Copyright (c) 1994-1996 Sun Microsystems, Inc.
-# Copyright (c) 1998-1999 by Scriptics Corporation.
-#
-# See the file "license.terms" for information on usage and redistribution
-# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
-
-if {[lsearch [namespace children] ::tcltest] == -1} {
- package require tcltest
- namespace import -force ::tcltest::*
-}
-
-if {[catch {package require http 1.0}]} {
- if {[info exists httpold]} {
- catch {puts "Cannot load http 1.0 package"}
- ::tcltest::cleanupTests
- return
- } else {
- catch {puts "Running http 1.0 tests in slave interp"}
- set interp [interp create httpold]
- $interp eval [list set httpold "running"]
- $interp eval [list set argv $argv]
- $interp eval [list source [info script]]
- interp delete $interp
- ::tcltest::cleanupTests
- return
- }
-}
-
-if {$::tcl_platform(os) eq "Darwin"} {
- # Name resolution often a problem on OSX; not focus of HTTP package anyway
- set HOST localhost
-} else {
- set HOST [info hostname]
-}
-
-set bindata "This is binary data\x0d\x0amore\x0dmore\x0amore\x00null"
-catch {unset data}
-
-##
-## The httpd script implement a stub http server
-##
-source [file join [file dirname [info script]] httpd]
-
-if [catch {httpd_init 0} listen] {
- puts "Cannot start http server, http test skipped"
- catch {unset port}
- ::tcltest::cleanupTests
- return
-}
-
-test httpold-1.1 {http_config} {
- http_config
-} {-accept */* -proxyfilter httpProxyRequired -proxyhost {} -proxyport {} -useragent {Tcl http client package 1.0}}
-
-test httpold-1.2 {http_config} {
- http_config -proxyfilter
-} httpProxyRequired
-
-test httpold-1.3 {http_config} {
- catch {http_config -junk}
-} 1
-
-test httpold-1.4 {http_config} {
- http_config -proxyhost nowhere.come -proxyport 8080 -proxyfilter myFilter -useragent "Tcl Test Suite"
- set x [http_config]
- http_config -proxyhost {} -proxyport {} -proxyfilter httpProxyRequired \
- -useragent "Tcl http client package 1.0"
- set x
-} {-accept */* -proxyfilter myFilter -proxyhost nowhere.come -proxyport 8080 -useragent {Tcl Test Suite}}
-
-test httpold-1.5 {http_config} {
- catch {http_config -proxyhost {} -junk 8080}
-} 1
-
-test httpold-2.1 {http_reset} {
- catch {http_reset http#1}
-} 0
-
-test httpold-3.1 {http_get} {
- catch {http_get -bogus flag}
-} 1
-test httpold-3.2 {http_get} {
- catch {http_get http:junk} err
- set err
-} {Unsupported URL: http:junk}
-
-set url ${::HOST}:$port
-test httpold-3.3 {http_get} {
- set token [http_get $url]
- http_data $token
-} "<html><head><title>HTTP/1.0 TEST</title></head><body>
-<h1>Hello, World!</h1>
-<h2>GET /</h2>
-</body></html>"
-
-set tail /a/b/c
-set url ${::HOST}:$port/a/b/c
-set binurl ${::HOST}:$port/binary
-
-test httpold-3.4 {http_get} {
- set token [http_get $url]
- http_data $token
-} "<html><head><title>HTTP/1.0 TEST</title></head><body>
-<h1>Hello, World!</h1>
-<h2>GET $tail</h2>
-</body></html>"
-
-proc selfproxy {host} {
- global port
- return [list ${::HOST} $port]
-}
-test httpold-3.5 {http_get} {
- http_config -proxyfilter selfproxy
- set token [http_get $url]
- http_config -proxyfilter httpProxyRequired
- http_data $token
-} "<html><head><title>HTTP/1.0 TEST</title></head><body>
-<h1>Hello, World!</h1>
-<h2>GET http://$url</h2>
-</body></html>"
-
-test httpold-3.6 {http_get} {
- http_config -proxyfilter bogus
- set token [http_get $url]
- http_config -proxyfilter httpProxyRequired
- http_data $token
-} "<html><head><title>HTTP/1.0 TEST</title></head><body>
-<h1>Hello, World!</h1>
-<h2>GET $tail</h2>
-</body></html>"
-
-test httpold-3.7 {http_get} {
- set token [http_get $url -headers {Pragma no-cache}]
- http_data $token
-} "<html><head><title>HTTP/1.0 TEST</title></head><body>
-<h1>Hello, World!</h1>
-<h2>GET $tail</h2>
-</body></html>"
-
-test httpold-3.8 {http_get} {
- set token [http_get $url -query Name=Value&Foo=Bar]
- http_data $token
-} "<html><head><title>HTTP/1.0 TEST</title></head><body>
-<h1>Hello, World!</h1>
-<h2>POST $tail</h2>
-<h2>Query</h2>
-<dl>
-<dt>Name<dd>Value
-<dt>Foo<dd>Bar
-</dl>
-</body></html>"
-
-test httpold-3.9 {http_get} {
- set token [http_get $url -validate 1]
- http_code $token
-} "HTTP/1.0 200 OK"
-
-
-test httpold-4.1 {httpEvent} {
- set token [http_get $url]
- upvar #0 $token data
- array set meta $data(meta)
- expr ($data(totalsize) == $meta(Content-Length))
-} 1
-
-test httpold-4.2 {httpEvent} {
- set token [http_get $url]
- upvar #0 $token data
- array set meta $data(meta)
- string compare $data(type) [string trim $meta(Content-Type)]
-} 0
-
-test httpold-4.3 {httpEvent} {
- set token [http_get $url]
- http_code $token
-} {HTTP/1.0 200 Data follows}
-
-test httpold-4.4 {httpEvent} {
- set testfile [makeFile "" testfile]
- set out [open $testfile w]
- set token [http_get $url -channel $out]
- close $out
- set in [open $testfile]
- set x [read $in]
- close $in
- removeFile $testfile
- set x
-} "<html><head><title>HTTP/1.0 TEST</title></head><body>
-<h1>Hello, World!</h1>
-<h2>GET $tail</h2>
-</body></html>"
-
-test httpold-4.5 {httpEvent} {
- set testfile [makeFile "" testfile]
- set out [open $testfile w]
- set token [http_get $url -channel $out]
- close $out
- upvar #0 $token data
- removeFile $testfile
- expr $data(currentsize) == $data(totalsize)
-} 1
-
-test httpold-4.6 {httpEvent} {
- set testfile [makeFile "" testfile]
- set out [open $testfile w]
- set token [http_get $binurl -channel $out]
- close $out
- set in [open $testfile]
- fconfigure $in -translation binary
- set x [read $in]
- close $in
- removeFile $testfile
- set x
-} "$bindata$binurl"
-
-proc myProgress {token total current} {
- global progress httpLog
- if {[info exists httpLog] && $httpLog} {
- puts "progress $total $current"
- }
- set progress [list $total $current]
-}
-if 0 {
- # This test hangs on Windows95 because the client never gets EOF
- set httpLog 1
- test httpold-4.6 {httpEvent} {
- set token [http_get $url -blocksize 50 -progress myProgress]
- set progress
- } {111 111}
-}
-test httpold-4.7 {httpEvent} {
- set token [http_get $url -progress myProgress]
- set progress
-} {111 111}
-test httpold-4.8 {httpEvent} {
- set token [http_get $url]
- http_status $token
-} {ok}
-test httpold-4.9 {httpEvent} {
- set token [http_get $url -progress myProgress]
- http_code $token
-} {HTTP/1.0 200 Data follows}
-test httpold-4.10 {httpEvent} {
- set token [http_get $url -progress myProgress]
- http_size $token
-} {111}
-test httpold-4.11 {httpEvent} {
- set token [http_get $url -timeout 1 -command {#}]
- http_reset $token
- http_status $token
-} {reset}
-test httpold-4.12 {httpEvent} {
- update
- set x {}
- after 500 {lappend x ok}
- set token [http_get $url -timeout 1 -command {lappend x fail}]
- vwait x
- list [http_status $token] $x
-} {timeout ok}
-
-test httpold-5.1 {http_formatQuery} {
- http_formatQuery name1 value1 name2 "value two"
-} {name1=value1&name2=value+two}
-
-test httpold-5.2 {http_formatQuery} {
- http_formatQuery name1 ~bwelch name2 \xa1\xa2\xa2
-} {name1=%7ebwelch&name2=%a1%a2%a2}
-
-test httpold-5.3 {http_formatQuery} {
- http_formatQuery lines "line1\nline2\nline3"
-} {lines=line1%0d%0aline2%0d%0aline3}
-
-test httpold-6.1 {httpProxyRequired} {
- update
- http_config -proxyhost ${::HOST} -proxyport $port
- set token [http_get $url]
- http_wait $token
- http_config -proxyhost {} -proxyport {}
- upvar #0 $token data
- set data(body)
-} "<html><head><title>HTTP/1.0 TEST</title></head><body>
-<h1>Hello, World!</h1>
-<h2>GET http://$url</h2>
-</body></html>"
-
-# cleanup
-catch {unset url}
-catch {unset port}
-catch {unset data}
-close $listen
-::tcltest::cleanupTests
-return
diff --git a/tests/package.test b/tests/package.test
index bb938b8..2843701 100644
--- a/tests/package.test
+++ b/tests/package.test
@@ -625,6 +625,18 @@ test pkg-3.53 {Tcl_PkgRequire procedure, picking best stable version} -constrain
package require t
set x
} -result {1.1}
+test package-3.54 {Tcl_PkgRequire procedure, coroutine support} -setup {
+ package forget t
+} -body {
+ coroutine coro1 apply {{} {
+ package ifneeded t 2.1 {
+ yield
+ package provide t 2.1
+ }
+ package require t 2.1
+ }}
+ list [catch {coro1} msg] $msg
+} -match glob -result {0 2.1}
test package-4.1 {Tcl_PackageCmd procedure} -returnCodes error -body {
diff --git a/unix/Makefile.in b/unix/Makefile.in
index 396db2e..d8744fd 100644
--- a/unix/Makefile.in
+++ b/unix/Makefile.in
@@ -829,7 +829,7 @@ install-libraries: libraries
else true; \
fi; \
done;
- @for i in opt0.4 http1.0 encoding ../tcl9 ../tcl9/9.0 ../tcl9/9.0/platform; \
+ @for i in opt0.4 encoding ../tcl9 ../tcl9/9.0 ../tcl9/9.0/platform; \
do \
if [ ! -d "$(SCRIPT_INSTALL_DIR)"/$$i ] ; then \
echo "Making directory $(SCRIPT_INSTALL_DIR)/$$i"; \
@@ -843,11 +843,6 @@ install-libraries: libraries
do \
$(INSTALL_DATA) $$i "$(SCRIPT_INSTALL_DIR)"; \
done;
- @echo "Installing package http1.0 files to $(SCRIPT_INSTALL_DIR)/http1.0/";
- @for i in $(TOP_DIR)/library/http1.0/*.tcl ; \
- do \
- $(INSTALL_DATA) $$i "$(SCRIPT_INSTALL_DIR)"/http1.0; \
- done;
@echo "Installing package http 2.8.12 as a Tcl Module";
@$(INSTALL_DATA) $(TOP_DIR)/library/http/http.tcl "$(SCRIPT_INSTALL_DIR)"/../tcl9/9.0/http-2.8.12.tm;
@echo "Installing package opt0.4 files to $(SCRIPT_INSTALL_DIR)/opt0.4/";
@@ -2010,7 +2005,7 @@ dist: $(UNIX_DIR)/configure $(UNIX_DIR)/tclConfig.h.in $(UNIX_DIR)/tcl.pc.in $(M
@mkdir $(DISTDIR)/library
cp -p $(TOP_DIR)/license.terms $(TOP_DIR)/library/*.tcl \
$(TOP_DIR)/library/tclIndex $(DISTDIR)/library
- for i in http1.0 http opt msgcat reg dde tcltest platform; \
+ for i in http opt msgcat reg dde tcltest platform; \
do \
mkdir $(DISTDIR)/library/$$i ;\
cp -p $(TOP_DIR)/library/$$i/*.tcl $(DISTDIR)/library/$$i; \
diff --git a/win/Makefile.in b/win/Makefile.in
index e8b0ff6..a05572b 100644
--- a/win/Makefile.in
+++ b/win/Makefile.in
@@ -630,7 +630,7 @@ install-libraries: libraries install-tzdata install-msgs
else true; \
fi; \
done;
- @for i in http1.0 opt0.4 encoding ../tcl9 ../tcl9/9.0 ../tcl9/9.0/platform; \
+ @for i in opt0.4 encoding ../tcl9 ../tcl9/9.0 ../tcl9/9.0/platform; \
do \
if [ ! -d $(SCRIPT_INSTALL_DIR)/$$i ] ; then \
echo "Making directory $(SCRIPT_INSTALL_DIR)/$$i"; \
@@ -652,11 +652,6 @@ install-libraries: libraries install-tzdata install-msgs
do \
$(COPY) "$$i" "$(SCRIPT_INSTALL_DIR)"; \
done;
- @echo "Installing library http1.0 directory";
- @for j in $(ROOT_DIR)/library/http1.0/*.tcl; \
- do \
- $(COPY) "$$j" "$(SCRIPT_INSTALL_DIR)/http1.0"; \
- done;
@echo "Installing package http 2.8.12 as a Tcl Module";
@$(COPY) $(ROOT_DIR)/library/http/http.tcl $(SCRIPT_INSTALL_DIR)/../tcl9/9.0/http-2.8.12.tm;
@echo "Installing library opt0.4 directory";
diff --git a/win/makefile.vc b/win/makefile.vc
index ab53ec3..f29d940 100644
--- a/win/makefile.vc
+++ b/win/makefile.vc
@@ -854,9 +854,6 @@ install-libraries: tclConfig tcl-nmake install-msgs install-tzdata
@$(CPY) "$(WINDIR)\targets.vc" "$(LIB_INSTALL_DIR)\nmake\"
@$(CPY) "$(WINDIR)\nmakehlp.c" "$(LIB_INSTALL_DIR)\nmake\"
@$(CPY) "$(OUT_DIR)\tcl.nmake" "$(LIB_INSTALL_DIR)\nmake\"
- @echo Installing library http1.0 directory
- @$(CPY) "$(ROOT)\library\http1.0\*.tcl" \
- "$(SCRIPT_INSTALL_DIR)\http1.0\"
@echo Installing library opt0.4 directory
@$(CPY) "$(ROOT)\library\opt\*.tcl" \
"$(SCRIPT_INSTALL_DIR)\opt0.4\"