summaryrefslogtreecommitdiffstats
path: root/generic/tclCmdIL.c
diff options
context:
space:
mode:
Diffstat (limited to 'generic/tclCmdIL.c')
-rw-r--r--generic/tclCmdIL.c2858
1 files changed, 769 insertions, 2089 deletions
diff --git a/generic/tclCmdIL.c b/generic/tclCmdIL.c
index de96267..02e5812 100644
--- a/generic/tclCmdIL.c
+++ b/generic/tclCmdIL.c
@@ -3,15 +3,15 @@
*
* This file contains the top-level command routines for most of the Tcl
* built-in commands whose names begin with the letters I through L. It
- * contains only commands in the generic core (i.e., those that don't
+ * contains only commands in the generic core (i.e. those that don't
* depend much upon UNIX facilities).
*
- * Copyright © 1987-1993 The Regents of the University of California.
- * Copyright © 1993-1997 Lucent Technologies.
- * Copyright © 1994-1997 Sun Microsystems, Inc.
- * Copyright © 1998-1999 Scriptics Corporation.
- * Copyright © 2001 Kevin B. Kenny. All rights reserved.
- * Copyright © 2005 Donal K. Fellows.
+ * Copyright (c) 1987-1993 The Regents of the University of California.
+ * Copyright (c) 1993-1997 Lucent Technologies.
+ * Copyright (c) 1994-1997 Sun Microsystems, Inc.
+ * Copyright (c) 1998-1999 by Scriptics Corporation.
+ * Copyright (c) 2001 by Kevin B. Kenny. All rights reserved.
+ * Copyright (c) 2005 Donal K. Fellows.
*
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
@@ -19,9 +19,6 @@
#include "tclInt.h"
#include "tclRegexp.h"
-#include "tclTomMath.h"
-#include <math.h>
-#include <assert.h>
/*
* During execution of the "lsort" command, structures of the following type
@@ -30,16 +27,13 @@
*/
typedef struct SortElement {
- union { /* The value that we sorting by. */
- const char *strValuePtr;
- Tcl_WideInt wideValue;
+ union {
+ char *strValuePtr;
+ long intValue;
double doubleValue;
Tcl_Obj *objValuePtr;
- } collationKey;
- union { /* Object being sorted, or its index. */
- Tcl_Obj *objPtr;
- Tcl_Size index;
- } payload;
+ } index;
+ Tcl_Obj *objPtr; /* Object being sorted, or its index. */
struct SortElement *nextPtr;/* Next element in the list, or NULL for end
* of list. */
} SortElement;
@@ -50,6 +44,7 @@ typedef struct SortElement {
*/
typedef int (*SortStrCmpFn_t) (const char *, const char *);
+typedef int (*SortMemCmpFn_t) (const void *, const void *, size_t);
/*
* The "lsort" command needs to pass certain information down to the function
@@ -58,21 +53,20 @@ typedef int (*SortStrCmpFn_t) (const char *, const char *);
* The following structure is used to pass this information.
*/
-typedef struct {
+typedef struct SortInfo {
int isIncreasing; /* Nonzero means sort in increasing order. */
int sortMode; /* The sort mode. One of SORTMODE_* values
* defined below. */
Tcl_Obj *compareCmdPtr; /* The Tcl comparison command when sortMode is
- * SORTMODE_COMMAND. Preinitialized to hold
+ * SORTMODE_COMMAND. Pre-initialized to hold
* base of command. */
int *indexv; /* If the -index option was specified, this
- * holds an encoding of the indexes contained
- * in the list supplied as an argument to
- * that option.
+ * holds the indexes contained in the list
+ * supplied as an argument to that option.
* NULL if no indexes supplied, and points to
* singleIndex field when only one
* supplied. */
- Tcl_Size indexc; /* Number of indexes in indexv array. */
+ int indexc; /* Number of indexes in indexv array. */
int singleIndex; /* Static space for common index case. */
int unique;
int numElements;
@@ -96,51 +90,57 @@ typedef struct {
#define SORTMODE_ASCII_NC 8
/*
- * Definitions for [lseq] command
+ * Magic values for the index field of the SortInfo structure. Note that the
+ * index "end-1" will be translated to SORTIDX_END-1, etc.
*/
-static const char *const seq_operations[] = {
- "..", "to", "count", "by", NULL
-};
-typedef enum Sequence_Operators {
- LSEQ_DOTS, LSEQ_TO, LSEQ_COUNT, LSEQ_BY
-} SequenceOperators;
-static const char *const seq_step_keywords[] = {"by", NULL};
-typedef enum Step_Operators {
- STEP_BY = 4
-} SequenceByMode;
-typedef enum Sequence_Decoded {
- NoneArg, NumericArg, RangeKeywordArg, ByKeywordArg
-} SequenceDecoded;
+
+#define SORTIDX_NONE -1 /* Not indexed; use whole value. */
+#define SORTIDX_END -2 /* Indexed from end. */
/*
* Forward declarations for procedures defined in this file:
*/
-static int DictionaryCompare(const char *left, const char *right);
-static Tcl_NRPostProc IfConditionCallback;
-static Tcl_ObjCmdProc InfoArgsCmd;
-static Tcl_ObjCmdProc InfoBodyCmd;
-static Tcl_ObjCmdProc InfoCmdCountCmd;
-static Tcl_ObjCmdProc InfoCommandsCmd;
-static Tcl_ObjCmdProc InfoCompleteCmd;
-static Tcl_ObjCmdProc InfoDefaultCmd;
-/* TIP #348 - New 'info' subcommand 'errorstack' */
-static Tcl_ObjCmdProc InfoErrorStackCmd;
+static int DictionaryCompare(char *left, char *right);
+static int InfoArgsCmd(ClientData dummy, Tcl_Interp *interp,
+ int objc, Tcl_Obj *const objv[]);
+static int InfoBodyCmd(ClientData dummy, Tcl_Interp *interp,
+ int objc, Tcl_Obj *const objv[]);
+static int InfoCmdCountCmd(ClientData dummy, Tcl_Interp *interp,
+ int objc, Tcl_Obj *const objv[]);
+static int InfoCommandsCmd(ClientData dummy, Tcl_Interp *interp,
+ int objc, Tcl_Obj *const objv[]);
+static int InfoCompleteCmd(ClientData dummy, Tcl_Interp *interp,
+ int objc, Tcl_Obj *const objv[]);
+static int InfoDefaultCmd(ClientData dummy, Tcl_Interp *interp,
+ int objc, Tcl_Obj *const objv[]);
/* TIP #280 - New 'info' subcommand 'frame' */
-static Tcl_ObjCmdProc InfoFrameCmd;
-static Tcl_ObjCmdProc InfoFunctionsCmd;
-static Tcl_ObjCmdProc InfoHostnameCmd;
-static Tcl_ObjCmdProc InfoLevelCmd;
-static Tcl_ObjCmdProc InfoLibraryCmd;
-static Tcl_ObjCmdProc InfoLoadedCmd;
-static Tcl_ObjCmdProc InfoNameOfExecutableCmd;
-static Tcl_ObjCmdProc InfoPatchLevelCmd;
-static Tcl_ObjCmdProc InfoProcsCmd;
-static Tcl_ObjCmdProc InfoScriptCmd;
-static Tcl_ObjCmdProc InfoSharedlibCmd;
-static Tcl_ObjCmdProc InfoCmdTypeCmd;
-static Tcl_ObjCmdProc InfoTclVersionCmd;
-static SortElement * MergeLists(SortElement *leftPtr, SortElement *rightPtr,
+static int InfoFrameCmd(ClientData dummy, Tcl_Interp *interp,
+ int objc, Tcl_Obj *const objv[]);
+static int InfoFunctionsCmd(ClientData dummy, Tcl_Interp *interp,
+ int objc, Tcl_Obj *const objv[]);
+static int InfoHostnameCmd(ClientData dummy, Tcl_Interp *interp,
+ int objc, Tcl_Obj *const objv[]);
+static int InfoLevelCmd(ClientData dummy, Tcl_Interp *interp,
+ int objc, Tcl_Obj *const objv[]);
+static int InfoLibraryCmd(ClientData dummy, Tcl_Interp *interp,
+ int objc, Tcl_Obj *const objv[]);
+static int InfoLoadedCmd(ClientData dummy, Tcl_Interp *interp,
+ int objc, Tcl_Obj *const objv[]);
+static int InfoNameOfExecutableCmd(ClientData dummy,
+ Tcl_Interp *interp, int objc,
+ Tcl_Obj *const objv[]);
+static int InfoPatchLevelCmd(ClientData dummy, Tcl_Interp *interp,
+ int objc, Tcl_Obj *const objv[]);
+static int InfoProcsCmd(ClientData dummy, Tcl_Interp *interp,
+ int objc, Tcl_Obj *const objv[]);
+static int InfoScriptCmd(ClientData dummy, Tcl_Interp *interp,
+ int objc, Tcl_Obj *const objv[]);
+static int InfoSharedlibCmd(ClientData dummy, Tcl_Interp *interp,
+ int objc, Tcl_Obj *const objv[]);
+static int InfoTclVersionCmd(ClientData dummy, Tcl_Interp *interp,
+ int objc, Tcl_Obj *const objv[]);
+static SortElement * MergeLists(SortElement *leftPtr, SortElement *rightPtr,
SortInfo *infoPtr);
static int SortCompare(SortElement *firstPtr, SortElement *second,
SortInfo *infoPtr);
@@ -153,32 +153,29 @@ static Tcl_Obj * SelectObjFromSublist(Tcl_Obj *firstPtr,
*/
static const EnsembleImplMap defaultInfoMap[] = {
- {"args", InfoArgsCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
- {"body", InfoBodyCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
- {"cmdcount", InfoCmdCountCmd, TclCompileBasic0ArgCmd, NULL, NULL, 0},
- {"cmdtype", InfoCmdTypeCmd, TclCompileBasic1ArgCmd, NULL, NULL, 1},
- {"commands", InfoCommandsCmd, TclCompileInfoCommandsCmd, NULL, NULL, 0},
- {"complete", InfoCompleteCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
- {"coroutine", TclInfoCoroutineCmd, TclCompileInfoCoroutineCmd, NULL, NULL, 0},
- {"default", InfoDefaultCmd, TclCompileBasic3ArgCmd, NULL, NULL, 0},
- {"errorstack", InfoErrorStackCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0},
- {"exists", TclInfoExistsCmd, TclCompileInfoExistsCmd, NULL, NULL, 0},
- {"frame", InfoFrameCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0},
- {"functions", InfoFunctionsCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0},
- {"globals", TclInfoGlobalsCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0},
- {"hostname", InfoHostnameCmd, TclCompileBasic0ArgCmd, NULL, NULL, 0},
- {"level", InfoLevelCmd, TclCompileInfoLevelCmd, NULL, NULL, 0},
- {"library", InfoLibraryCmd, TclCompileBasic0ArgCmd, NULL, NULL, 0},
- {"loaded", InfoLoadedCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0},
- {"locals", TclInfoLocalsCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0},
- {"nameofexecutable", InfoNameOfExecutableCmd, TclCompileBasic0ArgCmd, NULL, NULL, 1},
- {"patchlevel", InfoPatchLevelCmd, TclCompileBasic0ArgCmd, NULL, NULL, 0},
- {"procs", InfoProcsCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0},
- {"script", InfoScriptCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0},
- {"sharedlibextension", InfoSharedlibCmd, TclCompileBasic0ArgCmd, NULL, NULL, 0},
- {"tclversion", InfoTclVersionCmd, TclCompileBasic0ArgCmd, NULL, NULL, 0},
- {"vars", TclInfoVarsCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0},
- {NULL, NULL, NULL, NULL, NULL, 0}
+ {"args", InfoArgsCmd, NULL},
+ {"body", InfoBodyCmd, NULL},
+ {"cmdcount", InfoCmdCountCmd, NULL},
+ {"commands", InfoCommandsCmd, NULL},
+ {"complete", InfoCompleteCmd, NULL},
+ {"default", InfoDefaultCmd, NULL},
+ {"exists", TclInfoExistsCmd, TclCompileInfoExistsCmd},
+ {"frame", InfoFrameCmd, NULL},
+ {"functions", InfoFunctionsCmd, NULL},
+ {"globals", TclInfoGlobalsCmd, NULL},
+ {"hostname", InfoHostnameCmd, NULL},
+ {"level", InfoLevelCmd, NULL},
+ {"library", InfoLibraryCmd, NULL},
+ {"loaded", InfoLoadedCmd, NULL},
+ {"locals", TclInfoLocalsCmd, NULL},
+ {"nameofexecutable", InfoNameOfExecutableCmd, NULL},
+ {"patchlevel", InfoPatchLevelCmd, NULL},
+ {"procs", InfoProcsCmd, NULL},
+ {"script", InfoScriptCmd, NULL},
+ {"sharedlibextension", InfoSharedlibCmd, NULL},
+ {"tclversion", InfoTclVersionCmd, NULL},
+ {"vars", TclInfoVarsCmd, NULL},
+ {NULL, NULL, NULL}
};
/*
@@ -204,71 +201,45 @@ static const EnsembleImplMap defaultInfoMap[] = {
int
Tcl_IfObjCmd(
- void *clientData,
- Tcl_Interp *interp, /* Current interpreter. */
- int objc, /* Number of arguments. */
- Tcl_Obj *const objv[]) /* Argument objects. */
-{
- return Tcl_NRCallObjProc(interp, TclNRIfObjCmd, clientData, objc, objv);
-}
-
-int
-TclNRIfObjCmd(
- TCL_UNUSED(void *),
+ ClientData dummy, /* Not used. */
Tcl_Interp *interp, /* Current interpreter. */
int objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
{
- Tcl_Obj *boolObj;
-
- if (objc <= 1) {
- Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "wrong # args: no expression after \"%s\" argument",
- TclGetString(objv[0])));
- Tcl_SetErrorCode(interp, "TCL", "WRONGARGS", (void *)NULL);
- return TCL_ERROR;
- }
-
- /*
- * At this point, objv[1] refers to the main expression to test. The
- * arguments after the expression must be "then" (optional) and a script
- * to execute if the expression is true.
- */
-
- TclNewObj(boolObj);
- Tcl_NRAddCallback(interp, IfConditionCallback, INT2PTR(objc),
- (void *) objv, INT2PTR(1), boolObj);
- return Tcl_NRExprObj(interp, objv[1], boolObj);
-}
-
-static int
-IfConditionCallback(
- void *data[],
- Tcl_Interp *interp,
- int result)
-{
+ int thenScriptIndex = 0; /* "then" script to be evaled after syntax
+ * check. */
Interp *iPtr = (Interp *) interp;
- int objc = PTR2INT(data[0]);
- Tcl_Obj *const *objv = (Tcl_Obj *const *)data[1];
- int i = PTR2INT(data[2]);
- Tcl_Obj *boolObj = (Tcl_Obj *)data[3];
- int value, thenScriptIndex = 0;
- const char *clause;
-
- if (result != TCL_OK) {
- TclDecrRefCount(boolObj);
- return result;
- }
- if (Tcl_GetBooleanFromObj(interp, boolObj, &value) != TCL_OK) {
- TclDecrRefCount(boolObj);
- return TCL_ERROR;
- }
- TclDecrRefCount(boolObj);
+ int i, result, value;
+ char *clause;
+ i = 1;
while (1) {
+ /*
+ * At this point in the loop, objv and objc refer to an expression to
+ * test, either for the main expression or an expression following an
+ * "elseif". The arguments after the expression must be "then"
+ * (optional) and a script to execute if the expression is true.
+ */
+
+ if (i >= objc) {
+ clause = TclGetString(objv[i-1]);
+ Tcl_AppendResult(interp, "wrong # args: ",
+ "no expression after \"", clause, "\" argument", NULL);
+ return TCL_ERROR;
+ }
+ if (!thenScriptIndex) {
+ result = Tcl_ExprBooleanObj(interp, objv[i], &value);
+ if (result != TCL_OK) {
+ return result;
+ }
+ }
i++;
if (i >= objc) {
- goto missingScript;
+ missingScript:
+ clause = TclGetString(objv[i-1]);
+ Tcl_AppendResult(interp, "wrong # args: ",
+ "no script following \"", clause, "\" argument", NULL);
+ return TCL_ERROR;
}
clause = TclGetString(objv[i]);
if ((i < objc) && (strcmp(clause, "then") == 0)) {
@@ -294,37 +265,17 @@ IfConditionCallback(
* TIP #280. Make invoking context available to branch.
*/
- return TclNREvalObjEx(interp, objv[thenScriptIndex], 0,
+ return TclEvalObjEx(interp, objv[thenScriptIndex], 0,
iPtr->cmdFramePtr, thenScriptIndex);
}
return TCL_OK;
}
clause = TclGetString(objv[i]);
- if ((clause[0] != 'e') || (strcmp(clause, "elseif") != 0)) {
- break;
- }
- i++;
-
- /*
- * At this point in the loop, objv and objc refer to an expression to
- * test, either for the main expression or an expression following an
- * "elseif". The arguments after the expression must be "then"
- * (optional) and a script to execute if the expression is true.
- */
-
- if (i >= objc) {
- Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "wrong # args: no expression after \"%s\" argument",
- clause));
- Tcl_SetErrorCode(interp, "TCL", "WRONGARGS", (void *)NULL);
- return TCL_ERROR;
- }
- if (!thenScriptIndex) {
- TclNewObj(boolObj);
- Tcl_NRAddCallback(interp, IfConditionCallback, data[0], data[1],
- INT2PTR(i), boolObj);
- return Tcl_NRExprObj(interp, objv[i], boolObj);
+ if ((clause[0] == 'e') && (strcmp(clause, "elseif") == 0)) {
+ i++;
+ continue;
}
+ break;
}
/*
@@ -336,14 +287,14 @@ IfConditionCallback(
if (strcmp(clause, "else") == 0) {
i++;
if (i >= objc) {
- goto missingScript;
+ Tcl_AppendResult(interp, "wrong # args: ",
+ "no script following \"else\" argument", NULL);
+ return TCL_ERROR;
}
}
if (i < objc - 1) {
- Tcl_SetObjResult(interp, Tcl_NewStringObj(
- "wrong # args: extra words after \"else\" clause in \"if\" command",
- -1));
- Tcl_SetErrorCode(interp, "TCL", "WRONGARGS", (void *)NULL);
+ Tcl_AppendResult(interp, "wrong # args: ",
+ "extra words after \"else\" clause in \"if\" command", NULL);
return TCL_ERROR;
}
if (thenScriptIndex) {
@@ -351,17 +302,10 @@ IfConditionCallback(
* TIP #280. Make invoking context available to branch/else.
*/
- return TclNREvalObjEx(interp, objv[thenScriptIndex], 0,
+ return TclEvalObjEx(interp, objv[thenScriptIndex], 0,
iPtr->cmdFramePtr, thenScriptIndex);
}
- return TclNREvalObjEx(interp, objv[i], 0, iPtr->cmdFramePtr, i);
-
- missingScript:
- Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "wrong # args: no script following \"%s\" argument",
- TclGetString(objv[i-1])));
- Tcl_SetErrorCode(interp, "TCL", "WRONGARGS", (void *)NULL);
- return TCL_ERROR;
+ return TclEvalObjEx(interp, objv[i], 0, iPtr->cmdFramePtr, i);
}
/*
@@ -387,7 +331,7 @@ IfConditionCallback(
int
Tcl_IncrObjCmd(
- TCL_UNUSED(void *),
+ ClientData dummy, /* Not used. */
Tcl_Interp *interp, /* Current interpreter. */
int objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
@@ -402,7 +346,7 @@ Tcl_IncrObjCmd(
if (objc == 3) {
incrPtr = objv[2];
} else {
- TclNewIntObj(incrPtr, 1);
+ incrPtr = Tcl_NewIntObj(1);
}
Tcl_IncrRefCount(incrPtr);
newValuePtr = TclIncrObjVar2(interp, objv[1], NULL,
@@ -431,7 +375,7 @@ Tcl_IncrObjCmd(
* documentation for details on what it does.
*
* Results:
- * Handle for the info command, or NULL on failure.
+ * FIXME
*
* Side effects:
* none
@@ -468,13 +412,13 @@ TclInitInfoCmd(
static int
InfoArgsCmd(
- TCL_UNUSED(void *),
+ ClientData dummy, /* Not used. */
Tcl_Interp *interp, /* Current interpreter. */
int objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
{
- Interp *iPtr = (Interp *) interp;
- const char *name;
+ register Interp *iPtr = (Interp *) interp;
+ char *name;
Proc *procPtr;
CompiledLocal *localPtr;
Tcl_Obj *listObjPtr;
@@ -487,9 +431,7 @@ InfoArgsCmd(
name = TclGetString(objv[1]);
procPtr = TclFindProc(iPtr, name);
if (procPtr == NULL) {
- Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "\"%s\" isn't a procedure", name));
- Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "PROCEDURE", name, (void *)NULL);
+ Tcl_AppendResult(interp, "\"", name, "\" isn't a procedure", NULL);
return TCL_ERROR;
}
@@ -531,15 +473,15 @@ InfoArgsCmd(
static int
InfoBodyCmd(
- TCL_UNUSED(void *),
+ ClientData dummy, /* Not used. */
Tcl_Interp *interp, /* Current interpreter. */
int objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
{
- Interp *iPtr = (Interp *) interp;
- const char *name, *bytes;
+ register Interp *iPtr = (Interp *) interp;
+ char *name;
Proc *procPtr;
- Tcl_Size numBytes;
+ Tcl_Obj *bodyPtr, *resultPtr;
if (objc != 2) {
Tcl_WrongNumArgs(interp, 1, objv, "procname");
@@ -549,9 +491,7 @@ InfoBodyCmd(
name = TclGetString(objv[1]);
procPtr = TclFindProc(iPtr, name);
if (procPtr == NULL) {
- Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "\"%s\" isn't a procedure", name));
- Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "PROCEDURE", name, (void *)NULL);
+ Tcl_AppendResult(interp, "\"", name, "\" isn't a procedure", NULL);
return TCL_ERROR;
}
@@ -564,8 +504,18 @@ InfoBodyCmd(
* the object do not invalidate the internal rep.
*/
- bytes = TclGetStringFromObj(procPtr->bodyPtr, &numBytes);
- Tcl_SetObjResult(interp, Tcl_NewStringObj(bytes, numBytes));
+ bodyPtr = procPtr->bodyPtr;
+ if (bodyPtr->bytes == NULL) {
+ /*
+ * The string rep might not be valid if the procedure has never been
+ * run before. [Bug #545644]
+ */
+
+ (void) TclGetString(bodyPtr);
+ }
+ resultPtr = Tcl_NewStringObj(bodyPtr->bytes, bodyPtr->length);
+
+ Tcl_SetObjResult(interp, resultPtr);
return TCL_OK;
}
@@ -592,7 +542,7 @@ InfoBodyCmd(
static int
InfoCmdCountCmd(
- TCL_UNUSED(void *),
+ ClientData dummy, /* Not used. */
Tcl_Interp *interp, /* Current interpreter. */
int objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
@@ -604,7 +554,7 @@ InfoCmdCountCmd(
return TCL_ERROR;
}
- Tcl_SetObjResult(interp, Tcl_NewWideIntObj(iPtr->cmdCount));
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(iPtr->cmdCount));
return TCL_OK;
}
@@ -634,14 +584,14 @@ InfoCmdCountCmd(
static int
InfoCommandsCmd(
- TCL_UNUSED(void *),
+ ClientData dummy, /* Not used. */
Tcl_Interp *interp, /* Current interpreter. */
int objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
{
- const char *cmdName, *pattern;
+ char *cmdName, *pattern;
const char *simplePattern;
- Tcl_HashEntry *entryPtr;
+ register Tcl_HashEntry *entryPtr;
Tcl_HashSearch search;
Namespace *nsPtr;
Namespace *globalNsPtr = (Namespace *) Tcl_GetGlobalNamespace(interp);
@@ -649,7 +599,7 @@ InfoCommandsCmd(
Tcl_Obj *listPtr, *elemObjPtr;
int specificNsInPattern = 0;/* Init. to avoid compiler warning. */
Tcl_Command cmd;
- Tcl_Size i;
+ int i;
/*
* Get the pattern and find the "effective namespace" in which to list
@@ -672,8 +622,8 @@ InfoCommandsCmd(
Namespace *dummy1NsPtr, *dummy2NsPtr;
pattern = TclGetString(objv[1]);
- TclGetNamespaceForQualName(interp, pattern, NULL, 0, &nsPtr,
- &dummy1NsPtr, &dummy2NsPtr, &simplePattern);
+ TclGetNamespaceForQualName(interp, pattern, (Namespace *) NULL, 0,
+ &nsPtr, &dummy1NsPtr, &dummy2NsPtr, &simplePattern);
if (nsPtr != NULL) { /* We successfully found the pattern's ns. */
specificNsInPattern = (strcmp(simplePattern, pattern) != 0);
@@ -709,11 +659,11 @@ InfoCommandsCmd(
entryPtr = Tcl_FindHashEntry(&nsPtr->cmdTable, simplePattern);
if (entryPtr != NULL) {
if (specificNsInPattern) {
- cmd = (Tcl_Command)Tcl_GetHashValue(entryPtr);
- TclNewObj(elemObjPtr);
+ cmd = (Tcl_Command) Tcl_GetHashValue(entryPtr);
+ elemObjPtr = Tcl_NewObj();
Tcl_GetCommandFullName(interp, cmd, elemObjPtr);
} else {
- cmdName = (const char *)Tcl_GetHashKey(&nsPtr->cmdTable, entryPtr);
+ cmdName = Tcl_GetHashKey(&nsPtr->cmdTable, entryPtr);
elemObjPtr = Tcl_NewStringObj(cmdName, -1);
}
Tcl_ListObjAppendElement(interp, listPtr, elemObjPtr);
@@ -740,7 +690,7 @@ InfoCommandsCmd(
entryPtr = Tcl_FindHashEntry(tablePtr, simplePattern);
}
if (entryPtr != NULL) {
- cmdName = (const char *)Tcl_GetHashKey(tablePtr, entryPtr);
+ cmdName = Tcl_GetHashKey(tablePtr, entryPtr);
Tcl_ListObjAppendElement(interp, listPtr,
Tcl_NewStringObj(cmdName, -1));
Tcl_SetObjResult(interp, listPtr);
@@ -756,12 +706,12 @@ InfoCommandsCmd(
entryPtr = Tcl_FirstHashEntry(&nsPtr->cmdTable, &search);
while (entryPtr != NULL) {
- cmdName = (const char *)Tcl_GetHashKey(&nsPtr->cmdTable, entryPtr);
+ cmdName = Tcl_GetHashKey(&nsPtr->cmdTable, entryPtr);
if ((simplePattern == NULL)
|| Tcl_StringMatch(cmdName, simplePattern)) {
if (specificNsInPattern) {
- cmd = (Tcl_Command)Tcl_GetHashValue(entryPtr);
- TclNewObj(elemObjPtr);
+ cmd = (Tcl_Command) Tcl_GetHashValue(entryPtr);
+ elemObjPtr = Tcl_NewObj();
Tcl_GetCommandFullName(interp, cmd, elemObjPtr);
} else {
elemObjPtr = Tcl_NewStringObj(cmdName, -1);
@@ -782,7 +732,7 @@ InfoCommandsCmd(
if ((nsPtr != globalNsPtr) && !specificNsInPattern) {
entryPtr = Tcl_FirstHashEntry(&globalNsPtr->cmdTable, &search);
while (entryPtr != NULL) {
- cmdName = (const char *)Tcl_GetHashKey(&globalNsPtr->cmdTable, entryPtr);
+ cmdName = Tcl_GetHashKey(&globalNsPtr->cmdTable, entryPtr);
if ((simplePattern == NULL)
|| Tcl_StringMatch(cmdName, simplePattern)) {
if (Tcl_FindHashEntry(&nsPtr->cmdTable,cmdName) == NULL) {
@@ -813,13 +763,13 @@ InfoCommandsCmd(
entryPtr = Tcl_FirstHashEntry(&nsPtr->cmdTable, &search);
while (entryPtr != NULL) {
- cmdName = (const char *)Tcl_GetHashKey(&nsPtr->cmdTable, entryPtr);
+ cmdName = Tcl_GetHashKey(&nsPtr->cmdTable, entryPtr);
if ((simplePattern == NULL)
|| Tcl_StringMatch(cmdName, simplePattern)) {
elemObjPtr = Tcl_NewStringObj(cmdName, -1);
Tcl_ListObjAppendElement(interp, listPtr, elemObjPtr);
(void) Tcl_CreateHashEntry(&addedCommandsTable,
- elemObjPtr, &isNew);
+ (char *)elemObjPtr, &isNew);
}
entryPtr = Tcl_NextHashEntry(&search);
}
@@ -839,12 +789,12 @@ InfoCommandsCmd(
}
entryPtr = Tcl_FirstHashEntry(&pathNsPtr->cmdTable, &search);
while (entryPtr != NULL) {
- cmdName = (const char *)Tcl_GetHashKey(&pathNsPtr->cmdTable, entryPtr);
+ cmdName = Tcl_GetHashKey(&pathNsPtr->cmdTable, entryPtr);
if ((simplePattern == NULL)
|| Tcl_StringMatch(cmdName, simplePattern)) {
elemObjPtr = Tcl_NewStringObj(cmdName, -1);
(void) Tcl_CreateHashEntry(&addedCommandsTable,
- elemObjPtr, &isNew);
+ (char *) elemObjPtr, &isNew);
if (isNew) {
Tcl_ListObjAppendElement(interp, listPtr, elemObjPtr);
} else {
@@ -866,7 +816,7 @@ InfoCommandsCmd(
if (!foundGlobal) {
entryPtr = Tcl_FirstHashEntry(&globalNsPtr->cmdTable, &search);
while (entryPtr != NULL) {
- cmdName = (const char *)Tcl_GetHashKey(&globalNsPtr->cmdTable, entryPtr);
+ cmdName = Tcl_GetHashKey(&globalNsPtr->cmdTable, entryPtr);
if ((simplePattern == NULL)
|| Tcl_StringMatch(cmdName, simplePattern)) {
elemObjPtr = Tcl_NewStringObj(cmdName, -1);
@@ -911,7 +861,7 @@ InfoCommandsCmd(
static int
InfoCompleteCmd(
- TCL_UNUSED(void *),
+ ClientData dummy, /* Not used. */
Tcl_Interp *interp, /* Current interpreter. */
int objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
@@ -948,13 +898,13 @@ InfoCompleteCmd(
static int
InfoDefaultCmd(
- TCL_UNUSED(void *),
+ ClientData dummy, /* Not used. */
Tcl_Interp *interp, /* Current interpreter. */
int objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
{
Interp *iPtr = (Interp *) interp;
- const char *procName, *argName;
+ char *procName, *argName, *varName;
Proc *procPtr;
CompiledLocal *localPtr;
Tcl_Obj *valueObjPtr;
@@ -969,10 +919,7 @@ InfoDefaultCmd(
procPtr = TclFindProc(iPtr, procName);
if (procPtr == NULL) {
- Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "\"%s\" isn't a procedure", procName));
- Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "PROCEDURE", procName,
- (void *)NULL);
+ Tcl_AppendResult(interp, "\"", procName, "\" isn't a procedure",NULL);
return TCL_ERROR;
}
@@ -982,80 +929,33 @@ InfoDefaultCmd(
&& (strcmp(argName, localPtr->name) == 0)) {
if (localPtr->defValuePtr != NULL) {
valueObjPtr = Tcl_ObjSetVar2(interp, objv[3], NULL,
- localPtr->defValuePtr, TCL_LEAVE_ERR_MSG);
+ localPtr->defValuePtr, 0);
if (valueObjPtr == NULL) {
- return TCL_ERROR;
+ goto defStoreError;
}
- Tcl_SetObjResult(interp, Tcl_NewWideIntObj(1));
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(1));
} else {
- Tcl_Obj *nullObjPtr;
-
- TclNewObj(nullObjPtr);
+ Tcl_Obj *nullObjPtr = Tcl_NewObj();
valueObjPtr = Tcl_ObjSetVar2(interp, objv[3], NULL,
- nullObjPtr, TCL_LEAVE_ERR_MSG);
+ nullObjPtr, 0);
if (valueObjPtr == NULL) {
- return TCL_ERROR;
+ goto defStoreError;
}
- Tcl_SetObjResult(interp, Tcl_NewWideIntObj(0));
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(0));
}
return TCL_OK;
}
}
- Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "procedure \"%s\" doesn't have an argument \"%s\"",
- procName, argName));
- Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "ARGUMENT", argName, (void *)NULL);
+ Tcl_AppendResult(interp, "procedure \"", procName,
+ "\" doesn't have an argument \"", argName, "\"", NULL);
return TCL_ERROR;
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * InfoErrorStackCmd --
- *
- * Called to implement the "info errorstack" command that returns information
- * about the last error's call stack. Handles the following syntax:
- *
- * info errorstack ?interp?
- *
- * Results:
- * Returns TCL_OK if successful and TCL_ERROR if there is an error.
- *
- * Side effects:
- * Returns a result in the interpreter's result object. If there is an
- * error, the result is an error message.
- *
- *----------------------------------------------------------------------
- */
-
-static int
-InfoErrorStackCmd(
- TCL_UNUSED(void *),
- Tcl_Interp *interp, /* Current interpreter. */
- int objc, /* Number of arguments. */
- Tcl_Obj *const objv[]) /* Argument objects. */
-{
- Tcl_Interp *target;
- Interp *iPtr;
-
- if ((objc != 1) && (objc != 2)) {
- Tcl_WrongNumArgs(interp, 1, objv, "?interp?");
- return TCL_ERROR;
- }
-
- target = interp;
- if (objc == 2) {
- target = Tcl_GetChild(interp, TclGetString(objv[1]));
- if (target == NULL) {
- return TCL_ERROR;
- }
- }
-
- iPtr = (Interp *) target;
- Tcl_SetObjResult(interp, iPtr->errorStack);
- return TCL_OK;
+ defStoreError:
+ varName = TclGetString(objv[3]);
+ Tcl_AppendResult(interp, "couldn't store default value in variable \"",
+ varName, "\"", NULL);
+ return TCL_ERROR;
}
/*
@@ -1080,12 +980,12 @@ InfoErrorStackCmd(
int
TclInfoExistsCmd(
- TCL_UNUSED(void *),
+ ClientData dummy, /* Not used. */
Tcl_Interp *interp, /* Current interpreter. */
int objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
{
- const char *varName;
+ char *varName;
Var *varPtr;
if (objc != 2) {
@@ -1125,53 +1025,28 @@ TclInfoExistsCmd(
static int
InfoFrameCmd(
- TCL_UNUSED(void *),
+ ClientData dummy, /* Not used. */
Tcl_Interp *interp, /* Current interpreter. */
int objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
{
Interp *iPtr = (Interp *) interp;
- int level, code = TCL_OK;
- CmdFrame *framePtr, **cmdFramePtrPtr = &iPtr->cmdFramePtr;
- CoroutineData *corPtr = iPtr->execEnvPtr->corPtr;
- int topLevel = 0;
-
- if (objc > 2) {
- Tcl_WrongNumArgs(interp, 1, objv, "?number?");
- return TCL_ERROR;
- }
-
- while (corPtr) {
- while (*cmdFramePtrPtr) {
- topLevel++;
- cmdFramePtrPtr = &((*cmdFramePtrPtr)->nextPtr);
- }
- if (corPtr->caller.cmdFramePtr) {
- *cmdFramePtrPtr = corPtr->caller.cmdFramePtr;
- }
- corPtr = corPtr->callerEEPtr->corPtr;
- }
- topLevel += (*cmdFramePtrPtr)->level;
-
- if (topLevel != iPtr->cmdFramePtr->level) {
- framePtr = iPtr->cmdFramePtr;
- while (framePtr) {
- framePtr->level = topLevel--;
- framePtr = framePtr->nextPtr;
- }
- if (topLevel) {
- Tcl_Panic("Broken frame level calculation");
- }
- topLevel = iPtr->cmdFramePtr->level;
- }
+ int level;
+ CmdFrame *framePtr;
if (objc == 1) {
/*
* Just "info frame".
*/
- Tcl_SetObjResult(interp, Tcl_NewWideIntObj(topLevel));
- goto done;
+ int levels =
+ (iPtr->cmdFramePtr == NULL ? 0 : iPtr->cmdFramePtr->level);
+
+ Tcl_SetObjResult(interp, Tcl_NewIntObj (levels));
+ return TCL_OK;
+ } else if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, "?number?");
+ return TCL_ERROR;
}
/*
@@ -1179,62 +1054,40 @@ InfoFrameCmd(
*/
if (TclGetIntFromObj(interp, objv[1], &level) != TCL_OK) {
- code = TCL_ERROR;
- goto done;
+ return TCL_ERROR;
}
+ if (level <= 0) {
+ /*
+ * Negative levels are adressing relative to the current frame's
+ * depth.
+ */
- if ((level > topLevel) || (level <= - topLevel)) {
- levelError:
- Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "bad level \"%s\"", TclGetString(objv[1])));
- Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "LEVEL",
- TclGetString(objv[1]), (void *)NULL);
- code = TCL_ERROR;
- goto done;
- }
+ if (iPtr->cmdFramePtr == NULL) {
+ levelError:
+ Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "bad level \"",
+ TclGetString(objv[1]), "\"", NULL);
+ return TCL_ERROR;
+ }
- /*
- * Let us convert to relative so that we know how many levels to go back
- */
+ /*
+ * Convert to absolute.
+ */
- if (level > 0) {
- level -= topLevel;
+ level += iPtr->cmdFramePtr->level;
}
- framePtr = iPtr->cmdFramePtr;
- while (++level <= 0) {
- framePtr = framePtr->nextPtr;
- if (!framePtr) {
- goto levelError;
+ for (framePtr = iPtr->cmdFramePtr; framePtr != NULL;
+ framePtr = framePtr->nextPtr) {
+ if (framePtr->level == level) {
+ break;
}
}
+ if (framePtr == NULL) {
+ goto levelError;
+ }
Tcl_SetObjResult(interp, TclInfoFrame(interp, framePtr));
-
- done:
- cmdFramePtrPtr = &iPtr->cmdFramePtr;
- corPtr = iPtr->execEnvPtr->corPtr;
- while (corPtr) {
- CmdFrame *endPtr = corPtr->caller.cmdFramePtr;
-
- if (endPtr) {
- if (*cmdFramePtrPtr == endPtr) {
- *cmdFramePtrPtr = NULL;
- } else {
- CmdFrame *runPtr = *cmdFramePtrPtr;
-
- while (runPtr->nextPtr != endPtr) {
- runPtr->level -= endPtr->level;
- runPtr = runPtr->nextPtr;
- }
- runPtr->level = 1;
- runPtr->nextPtr = NULL;
- }
- cmdFramePtrPtr = &corPtr->caller.cmdFramePtr;
- }
- corPtr = corPtr->callerEEPtr->corPtr;
- }
- return code;
+ return TCL_OK;
}
/*
@@ -1259,21 +1112,21 @@ TclInfoFrame(
CmdFrame *framePtr) /* Frame to get info for. */
{
Interp *iPtr = (Interp *) interp;
- Tcl_Obj *tmpObj;
- Tcl_Obj *lv[20] = {NULL}; /* Keep uptodate when more keys are added to
+ Tcl_Obj *lv[20]; /* Keep uptodate when more keys are added to
* the dict. */
int lc = 0;
/*
* This array is indexed by the TCL_LOCATION_... values, except
* for _LAST.
*/
- static const char *const typeString[TCL_LOCATION_LAST] = {
+ static const char *typeString[TCL_LOCATION_LAST] = {
"eval", "eval", "eval", "precompiled", "source", "proc"
};
- Proc *procPtr = framePtr->framePtr ? framePtr->framePtr->procPtr : NULL;
- int needsFree = -1;
+ Tcl_Obj *tmpObj;
+ Proc *procPtr =
+ framePtr->framePtr ? framePtr->framePtr->procPtr : NULL;
- /*
+ /*
* Pull the information and construct the dictionary to return, as list.
* Regarding use of the CmdFrame fields see tclInt.h, and its definition.
*/
@@ -1291,12 +1144,28 @@ TclInfoFrame(
*/
ADD_PAIR("type", Tcl_NewStringObj(typeString[framePtr->type], -1));
- if (framePtr->line) {
- ADD_PAIR("line", Tcl_NewWideIntObj(framePtr->line[0]));
- } else {
- ADD_PAIR("line", Tcl_NewWideIntObj(1));
- }
- ADD_PAIR("cmd", TclGetSourceFromFrame(framePtr, 0, NULL));
+ ADD_PAIR("line", Tcl_NewIntObj(framePtr->line[0]));
+ ADD_PAIR("cmd", Tcl_NewStringObj(framePtr->cmd.str.cmd,
+ framePtr->cmd.str.len));
+ break;
+
+ case TCL_LOCATION_EVAL_LIST:
+ /*
+ * List optimized evaluation. Type, line, cmd, the latter through
+ * listPtr, possibly a frame.
+ */
+
+ ADD_PAIR("type", Tcl_NewStringObj(typeString[framePtr->type], -1));
+ ADD_PAIR("line", Tcl_NewIntObj(1));
+
+ /*
+ * We put a duplicate of the command list obj into the result to
+ * ensure that the 'pure List'-property of the command itself is not
+ * destroyed. Otherwise the query here would disable the list
+ * optimization path in Tcl_EvalObjEx.
+ */
+
+ ADD_PAIR("cmd", Tcl_DuplicateObj(framePtr->cmd.listPtr));
break;
case TCL_LOCATION_PREBC:
@@ -1312,8 +1181,9 @@ TclInfoFrame(
* Execution of bytecode. Talk to the BC engine to fill out the frame.
*/
- CmdFrame *fPtr = (CmdFrame *)TclStackAlloc(interp, sizeof(CmdFrame));
+ CmdFrame *fPtr;
+ fPtr = (CmdFrame *) TclStackAlloc(interp, sizeof(CmdFrame));
*fPtr = *framePtr;
/*
@@ -1331,7 +1201,7 @@ TclInfoFrame(
ADD_PAIR("type", Tcl_NewStringObj(typeString[fPtr->type], -1));
if (fPtr->line) {
- ADD_PAIR("line", Tcl_NewWideIntObj(fPtr->line[0]));
+ ADD_PAIR("line", Tcl_NewIntObj(fPtr->line[0]));
}
if (fPtr->type == TCL_LOCATION_SOURCE) {
@@ -1344,10 +1214,8 @@ TclInfoFrame(
Tcl_DecrRefCount(fPtr->data.eval.path);
}
- ADD_PAIR("cmd", TclGetSourceFromFrame(fPtr, 0, NULL));
- if (fPtr->cmdObj && framePtr->cmdObj == NULL) {
- needsFree = lc - 1;
- }
+ ADD_PAIR("cmd",
+ Tcl_NewStringObj(fPtr->cmd.str.cmd, fPtr->cmd.str.len));
TclStackFree(interp, fPtr);
break;
}
@@ -1358,7 +1226,7 @@ TclInfoFrame(
*/
ADD_PAIR("type", Tcl_NewStringObj(typeString[framePtr->type], -1));
- ADD_PAIR("line", Tcl_NewWideIntObj(framePtr->line[0]));
+ ADD_PAIR("line", Tcl_NewIntObj(framePtr->line[0]));
ADD_PAIR("file", framePtr->data.eval.path);
/*
@@ -1366,7 +1234,8 @@ TclInfoFrame(
* the result list object.
*/
- ADD_PAIR("cmd", TclGetSourceFromFrame(framePtr, 0, NULL));
+ ADD_PAIR("cmd", Tcl_NewStringObj(framePtr->cmd.str.cmd,
+ framePtr->cmd.str.len));
break;
case TCL_LOCATION_PROC:
@@ -1383,19 +1252,22 @@ TclInfoFrame(
Tcl_HashEntry *namePtr = procPtr->cmdPtr->hPtr;
if (namePtr) {
- Tcl_Obj *procNameObj;
-
/*
* This is a regular command.
*/
- TclNewObj(procNameObj);
- Tcl_GetCommandFullName(interp, (Tcl_Command) procPtr->cmdPtr,
- procNameObj);
- ADD_PAIR("proc", procNameObj);
+ char *procName = Tcl_GetHashKey(namePtr->tablePtr, namePtr);
+ char *nsName = procPtr->cmdPtr->nsPtr->fullName;
+
+ ADD_PAIR("proc", Tcl_NewStringObj(nsName, -1));
+
+ if (strcmp(nsName, "::") != 0) {
+ Tcl_AppendToObj(lv[lc-1], "::", -1);
+ }
+ Tcl_AppendToObj(lv[lc-1], procName, -1);
} else if (procPtr->cmdPtr->clientData) {
- ExtraFrameInfo *efiPtr = (ExtraFrameInfo *)procPtr->cmdPtr->clientData;
- Tcl_Size i;
+ ExtraFrameInfo *efiPtr = procPtr->cmdPtr->clientData;
+ int i;
/*
* This is a non-standard command. Luckily, it's told us how to
@@ -1408,7 +1280,7 @@ TclInfoFrame(
lv[lc++] =
efiPtr->fields[i].proc(efiPtr->fields[i].clientData);
} else {
- lv[lc++] = (Tcl_Obj *)efiPtr->fields[i].clientData;
+ lv[lc++] = efiPtr->fields[i].clientData;
}
}
}
@@ -1429,17 +1301,13 @@ TclInfoFrame(
int c = framePtr->framePtr->level;
int t = iPtr->varFramePtr->level;
- ADD_PAIR("level", Tcl_NewWideIntObj(t - c));
+ ADD_PAIR("level", Tcl_NewIntObj(t - c));
break;
}
}
}
- tmpObj = Tcl_NewListObj(lc, lv);
- if (needsFree >= 0) {
- Tcl_DecrRefCount(lv[needsFree]);
- }
- return tmpObj;
+ return Tcl_NewListObj(lc, lv);
}
/*
@@ -1465,7 +1333,7 @@ TclInfoFrame(
static int
InfoFunctionsCmd(
- TCL_UNUSED(void *),
+ ClientData dummy, /* Not used. */
Tcl_Interp *interp, /* Current interpreter. */
int objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
@@ -1530,7 +1398,7 @@ InfoFunctionsCmd(
static int
InfoHostnameCmd(
- TCL_UNUSED(void *),
+ ClientData dummy, /* Not used. */
Tcl_Interp *interp, /* Current interpreter. */
int objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
@@ -1547,10 +1415,7 @@ InfoHostnameCmd(
Tcl_SetObjResult(interp, Tcl_NewStringObj(name, -1));
return TCL_OK;
}
-
- Tcl_SetObjResult(interp, Tcl_NewStringObj(
- "unable to determine name of host", -1));
- Tcl_SetErrorCode(interp, "TCL", "OPERATION", "HOSTNAME", "UNKNOWN", (void *)NULL);
+ Tcl_SetResult(interp, "unable to determine name of host", TCL_STATIC);
return TCL_ERROR;
}
@@ -1576,7 +1441,7 @@ InfoHostnameCmd(
static int
InfoLevelCmd(
- TCL_UNUSED(void *),
+ ClientData dummy, /* Not used. */
Tcl_Interp *interp, /* Current interpreter. */
int objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
@@ -1584,7 +1449,7 @@ InfoLevelCmd(
Interp *iPtr = (Interp *) interp;
if (objc == 1) { /* Just "info level" */
- Tcl_SetObjResult(interp, Tcl_NewWideIntObj(iPtr->varFramePtr->level));
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(iPtr->varFramePtr->level));
return TCL_OK;
}
@@ -1620,10 +1485,8 @@ InfoLevelCmd(
return TCL_ERROR;
levelError:
- Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "bad level \"%s\"", TclGetString(objv[1])));
- Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "LEVEL",
- TclGetString(objv[1]), (void *)NULL);
+ Tcl_AppendResult(interp, "bad level \"", TclGetString(objv[1]), "\"",
+ NULL);
return TCL_ERROR;
}
@@ -1650,7 +1513,7 @@ InfoLevelCmd(
static int
InfoLibraryCmd(
- TCL_UNUSED(void *),
+ ClientData dummy, /* Not used. */
Tcl_Interp *interp, /* Current interpreter. */
int objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
@@ -1662,15 +1525,12 @@ InfoLibraryCmd(
return TCL_ERROR;
}
- libDirName = Tcl_GetVar2(interp, "tcl_library", NULL, TCL_GLOBAL_ONLY);
+ libDirName = Tcl_GetVar(interp, "tcl_library", TCL_GLOBAL_ONLY);
if (libDirName != NULL) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(libDirName, -1));
return TCL_OK;
}
-
- Tcl_SetObjResult(interp, Tcl_NewStringObj(
- "no library has been specified for Tcl", -1));
- Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "VARIABLE", "tcl_library", (void *)NULL);
+ Tcl_SetResult(interp, "no library has been specified for Tcl",TCL_STATIC);
return TCL_ERROR;
}
@@ -1697,29 +1557,24 @@ InfoLibraryCmd(
static int
InfoLoadedCmd(
- TCL_UNUSED(void *),
+ ClientData dummy, /* Not used. */
Tcl_Interp *interp, /* Current interpreter. */
int objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
{
- const char *interpName, *packageName;
+ char *interpName;
- if (objc > 3) {
- Tcl_WrongNumArgs(interp, 1, objv, "?interp? ?packageName?");
+ if ((objc != 1) && (objc != 2)) {
+ Tcl_WrongNumArgs(interp, 1, objv, "?interp?");
return TCL_ERROR;
}
- if (objc < 2) { /* Get loaded pkgs in all interpreters. */
+ if (objc == 1) { /* Get loaded pkgs in all interpreters. */
interpName = NULL;
} else { /* Get pkgs just in specified interp. */
interpName = TclGetString(objv[1]);
}
- if (objc < 3) { /* Get loaded files in all packages. */
- packageName = NULL;
- } else { /* Get pkgs just in specified interp. */
- packageName = TclGetString(objv[2]);
- }
- return TclGetLoadedLibraries(interp, interpName, packageName);
+ return TclGetLoadedPackages(interp, interpName);
}
/*
@@ -1745,7 +1600,7 @@ InfoLoadedCmd(
static int
InfoNameOfExecutableCmd(
- TCL_UNUSED(void *),
+ ClientData dummy, /* Not used. */
Tcl_Interp *interp, /* Current interpreter. */
int objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
@@ -1781,7 +1636,7 @@ InfoNameOfExecutableCmd(
static int
InfoPatchLevelCmd(
- TCL_UNUSED(void *),
+ ClientData dummy, /* Not used. */
Tcl_Interp *interp, /* Current interpreter. */
int objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
@@ -1793,7 +1648,7 @@ InfoPatchLevelCmd(
return TCL_ERROR;
}
- patchlevel = Tcl_GetVar2(interp, "tcl_patchLevel", NULL,
+ patchlevel = Tcl_GetVar(interp, "tcl_patchLevel",
(TCL_GLOBAL_ONLY | TCL_LEAVE_ERR_MSG));
if (patchlevel != NULL) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(patchlevel, -1));
@@ -1828,12 +1683,12 @@ InfoPatchLevelCmd(
static int
InfoProcsCmd(
- TCL_UNUSED(void *),
+ ClientData dummy, /* Not used. */
Tcl_Interp *interp, /* Current interpreter. */
int objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
{
- const char *cmdName, *pattern;
+ char *cmdName, *pattern;
const char *simplePattern;
Namespace *nsPtr;
#ifdef INFO_PROCS_SEARCH_GLOBAL_NS
@@ -1842,7 +1697,7 @@ InfoProcsCmd(
Namespace *currNsPtr = (Namespace *) Tcl_GetCurrentNamespace(interp);
Tcl_Obj *listPtr, *elemObjPtr;
int specificNsInPattern = 0;/* Init. to avoid compiler warning. */
- Tcl_HashEntry *entryPtr;
+ register Tcl_HashEntry *entryPtr;
Tcl_HashSearch search;
Command *cmdPtr, *realCmdPtr;
@@ -1867,8 +1722,9 @@ InfoProcsCmd(
Namespace *dummy1NsPtr, *dummy2NsPtr;
pattern = TclGetString(objv[1]);
- TclGetNamespaceForQualName(interp, pattern, NULL, /*flags*/ 0, &nsPtr,
- &dummy1NsPtr, &dummy2NsPtr, &simplePattern);
+ TclGetNamespaceForQualName(interp, pattern, (Namespace *) NULL,
+ /*flags*/ 0, &nsPtr, &dummy1NsPtr, &dummy2NsPtr,
+ &simplePattern);
if (nsPtr != NULL) { /* We successfully found the pattern's ns. */
specificNsInPattern = (strcmp(simplePattern, pattern) != 0);
@@ -1894,7 +1750,7 @@ InfoProcsCmd(
if (simplePattern != NULL && TclMatchIsTrivial(simplePattern)) {
entryPtr = Tcl_FindHashEntry(&nsPtr->cmdTable, simplePattern);
if (entryPtr != NULL) {
- cmdPtr = (Command *)Tcl_GetHashValue(entryPtr);
+ cmdPtr = (Command *) Tcl_GetHashValue(entryPtr);
if (!TclIsProc(cmdPtr)) {
realCmdPtr = (Command *)
@@ -1905,7 +1761,7 @@ InfoProcsCmd(
} else {
simpleProcOK:
if (specificNsInPattern) {
- TclNewObj(elemObjPtr);
+ elemObjPtr = Tcl_NewObj();
Tcl_GetCommandFullName(interp, (Tcl_Command) cmdPtr,
elemObjPtr);
} else {
@@ -1919,22 +1775,22 @@ InfoProcsCmd(
{
entryPtr = Tcl_FirstHashEntry(&nsPtr->cmdTable, &search);
while (entryPtr != NULL) {
- cmdName = (const char *)Tcl_GetHashKey(&nsPtr->cmdTable, entryPtr);
+ cmdName = Tcl_GetHashKey(&nsPtr->cmdTable, entryPtr);
if ((simplePattern == NULL)
|| Tcl_StringMatch(cmdName, simplePattern)) {
- cmdPtr = (Command *)Tcl_GetHashValue(entryPtr);
+ cmdPtr = (Command *) Tcl_GetHashValue(entryPtr);
if (!TclIsProc(cmdPtr)) {
realCmdPtr = (Command *)
- TclGetOriginalCommand((Tcl_Command)cmdPtr);
+ TclGetOriginalCommand((Tcl_Command) cmdPtr);
if (realCmdPtr != NULL && TclIsProc(realCmdPtr)) {
goto procOK;
}
} else {
procOK:
if (specificNsInPattern) {
- TclNewObj(elemObjPtr);
- Tcl_GetCommandFullName(interp, (Tcl_Command)cmdPtr,
+ elemObjPtr = Tcl_NewObj();
+ Tcl_GetCommandFullName(interp, (Tcl_Command) cmdPtr,
elemObjPtr);
} else {
elemObjPtr = Tcl_NewStringObj(cmdName, -1);
@@ -1957,7 +1813,7 @@ InfoProcsCmd(
/*
* If "info procs" worked like "info commands", returning the commands
* also seen in the global namespace, then you would include this
- * code. As this could break backwards compatibility with 8.0-8.2, we
+ * code. As this could break backwards compatibilty with 8.0-8.2, we
* decided not to "fix" it in 8.3, leaving the behavior slightly
* different.
*/
@@ -1965,11 +1821,11 @@ InfoProcsCmd(
if ((nsPtr != globalNsPtr) && !specificNsInPattern) {
entryPtr = Tcl_FirstHashEntry(&globalNsPtr->cmdTable, &search);
while (entryPtr != NULL) {
- cmdName = (const char *)Tcl_GetHashKey(&globalNsPtr->cmdTable, entryPtr);
+ cmdName = Tcl_GetHashKey(&globalNsPtr->cmdTable, entryPtr);
if ((simplePattern == NULL)
|| Tcl_StringMatch(cmdName, simplePattern)) {
if (Tcl_FindHashEntry(&nsPtr->cmdTable,cmdName) == NULL) {
- cmdPtr = (Command *)Tcl_GetHashValue(entryPtr);
+ cmdPtr = (Command *) Tcl_GetHashValue(entryPtr);
realCmdPtr = (Command *) TclGetOriginalCommand(
(Tcl_Command) cmdPtr);
@@ -2015,13 +1871,12 @@ InfoProcsCmd(
static int
InfoScriptCmd(
- TCL_UNUSED(void *),
+ ClientData dummy, /* Not used. */
Tcl_Interp *interp, /* Current interpreter. */
int objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
{
Interp *iPtr = (Interp *) interp;
-
if ((objc != 1) && (objc != 2)) {
Tcl_WrongNumArgs(interp, 1, objv, "?filename?");
return TCL_ERROR;
@@ -2063,7 +1918,7 @@ InfoScriptCmd(
static int
InfoSharedlibCmd(
- TCL_UNUSED(void *),
+ ClientData dummy, /* Not used. */
Tcl_Interp *interp, /* Current interpreter. */
int objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
@@ -2101,7 +1956,7 @@ InfoSharedlibCmd(
static int
InfoTclVersionCmd(
- TCL_UNUSED(void *),
+ ClientData dummy, /* Not used. */
Tcl_Interp *interp, /* Current interpreter. */
int objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
@@ -2125,60 +1980,6 @@ InfoTclVersionCmd(
/*
*----------------------------------------------------------------------
*
- * InfoCmdTypeCmd --
- *
- * Called to implement the "info cmdtype" command that returns the type
- * of a given command. Handles the following syntax:
- *
- * info cmdtype cmdName
- *
- * Results:
- * Returns TCL_OK if successful and TCL_ERROR if there is an error.
- *
- * Side effects:
- * Returns a type name. If there is an error, the result is an error
- * message.
- *
- *----------------------------------------------------------------------
- */
-
-static int
-InfoCmdTypeCmd(
- TCL_UNUSED(void *),
- Tcl_Interp *interp, /* Current interpreter. */
- int objc, /* Number of arguments. */
- Tcl_Obj *const objv[]) /* Argument objects. */
-{
- Tcl_Command command;
-
- if (objc != 2) {
- Tcl_WrongNumArgs(interp, 1, objv, "commandName");
- return TCL_ERROR;
- }
- command = Tcl_FindCommand(interp, TclGetString(objv[1]), NULL,
- TCL_LEAVE_ERR_MSG);
- if (command == NULL) {
- return TCL_ERROR;
- }
-
- /*
- * There's one special case: safe interpreters can't see aliases as
- * aliases as they're part of the security mechanisms.
- */
-
- if (Tcl_IsSafe(interp)
- && (((Command *) command)->objProc == TclAliasObjCmd)) {
- Tcl_AppendResult(interp, "native", (void *)NULL);
- } else {
- Tcl_SetObjResult(interp,
- Tcl_NewStringObj(TclGetCommandTypeName(command), -1));
- }
- return TCL_OK;
-}
-
-/*
- *----------------------------------------------------------------------
- *
* Tcl_JoinObjCmd --
*
* This procedure is invoked to process the "join" Tcl command. See the
@@ -2195,14 +1996,13 @@ InfoCmdTypeCmd(
int
Tcl_JoinObjCmd(
- TCL_UNUSED(void *),
+ ClientData dummy, /* Not used. */
Tcl_Interp *interp, /* Current interpreter. */
int objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* The argument objects. */
{
- Tcl_Size length, listLen;
- int isArithSeries = 0;
- Tcl_Obj *resObjPtr = NULL, *joinObjPtr, **elemPtrs;
+ int listLen, i;
+ Tcl_Obj *resObjPtr, *joinObjPtr, **elemPtrs;
if ((objc < 2) || (objc > 3)) {
Tcl_WrongNumArgs(interp, 1, objv, "list ?joinString?");
@@ -2214,88 +2014,24 @@ Tcl_JoinObjCmd(
* pointer to its array of element pointers.
*/
- if (TclHasInternalRep(objv[1],&tclArithSeriesType)) {
- isArithSeries = 1;
- listLen = TclArithSeriesObjLength(objv[1]);
- } else {
- if (TclListObjGetElements(interp, objv[1], &listLen,
+ if (TclListObjGetElements(interp, objv[1], &listLen,
&elemPtrs) != TCL_OK) {
- return TCL_ERROR;
- }
- }
-
- if (listLen == 0) {
- /* No elements to join; default empty result is correct. */
- return TCL_OK;
- }
- if (listLen == 1) {
- /* One element; return it */
- if (isArithSeries) {
- Tcl_Obj *valueObj = TclArithSeriesObjIndex(interp, objv[1], 0);
- if (valueObj == NULL) {
- return TCL_ERROR;
- }
- Tcl_SetObjResult(interp, valueObj);
- } else {
- Tcl_SetObjResult(interp, elemPtrs[0]);
- }
- return TCL_OK;
+ return TCL_ERROR;
}
joinObjPtr = (objc == 2) ? Tcl_NewStringObj(" ", 1) : objv[2];
Tcl_IncrRefCount(joinObjPtr);
- (void) TclGetStringFromObj(joinObjPtr, &length);
- if (length == 0) {
- resObjPtr = TclStringCat(interp, listLen, elemPtrs, 0);
- } else {
- Tcl_Size i;
-
- TclNewObj(resObjPtr);
- if (isArithSeries) {
- Tcl_Obj *valueObj;
- for (i = 0; i < listLen; i++) {
- if (i > 0) {
-
- /*
- * NOTE: This code is relying on Tcl_AppendObjToObj() **NOT**
- * to shimmer joinObjPtr. If it did, then the case where
- * objv[1] and objv[2] are the same value would not be safe.
- * Accessing elemPtrs would crash.
- */
-
- Tcl_AppendObjToObj(resObjPtr, joinObjPtr);
- }
- valueObj = TclArithSeriesObjIndex(interp, objv[1], i);
- if (valueObj == NULL) {
- return TCL_ERROR;
- }
- Tcl_AppendObjToObj(resObjPtr, valueObj);
- Tcl_DecrRefCount(valueObj);
- }
- } else {
- for (i = 0; i < listLen; i++) {
- if (i > 0) {
-
- /*
- * NOTE: This code is relying on Tcl_AppendObjToObj() **NOT**
- * to shimmer joinObjPtr. If it did, then the case where
- * objv[1] and objv[2] are the same value would not be safe.
- * Accessing elemPtrs would crash.
- */
-
- Tcl_AppendObjToObj(resObjPtr, joinObjPtr);
- }
- Tcl_AppendObjToObj(resObjPtr, elemPtrs[i]);
- }
+ resObjPtr = Tcl_NewObj();
+ for (i = 0; i < listLen; i++) {
+ if (i > 0) {
+ Tcl_AppendObjToObj(resObjPtr, joinObjPtr);
}
+ Tcl_AppendObjToObj(resObjPtr, elemPtrs[i]);
}
Tcl_DecrRefCount(joinObjPtr);
- if (resObjPtr) {
- Tcl_SetObjResult(interp, resObjPtr);
- return TCL_OK;
- }
- return TCL_ERROR;
+ Tcl_SetObjResult(interp, resObjPtr);
+ return TCL_OK;
}
/*
@@ -2317,19 +2053,18 @@ Tcl_JoinObjCmd(
int
Tcl_LassignObjCmd(
- TCL_UNUSED(void *),
+ ClientData dummy, /* Not used. */
Tcl_Interp *interp, /* Current interpreter. */
int objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
{
Tcl_Obj *listCopyPtr;
Tcl_Obj **listObjv; /* The contents of the list. */
- Tcl_Size listObjc; /* The length of the list. */
- Tcl_Size origListObjc; /* Original length */
+ int listObjc; /* The length of the list. */
int code = TCL_OK;
- if (objc < 2) {
- Tcl_WrongNumArgs(interp, 1, objv, "list ?varName ...?");
+ if (objc < 3) {
+ Tcl_WrongNumArgs(interp, 1, objv, "list varName ?varName ...?");
return TCL_ERROR;
}
@@ -2337,30 +2072,26 @@ Tcl_LassignObjCmd(
if (listCopyPtr == NULL) {
return TCL_ERROR;
}
- Tcl_IncrRefCount(listCopyPtr); /* Important! fs */
TclListObjGetElements(NULL, listCopyPtr, &listObjc, &listObjv);
- origListObjc = listObjc;
objc -= 2;
objv += 2;
while (code == TCL_OK && objc > 0 && listObjc > 0) {
- if (Tcl_ObjSetVar2(interp, *objv++, NULL, *listObjv++,
- TCL_LEAVE_ERR_MSG) == NULL) {
+ if (NULL == Tcl_ObjSetVar2(interp, *objv++, NULL,
+ *listObjv++, TCL_LEAVE_ERR_MSG)) {
code = TCL_ERROR;
}
- objc--;
- listObjc--;
+ objc--; listObjc--;
}
if (code == TCL_OK && objc > 0) {
Tcl_Obj *emptyObj;
-
TclNewObj(emptyObj);
Tcl_IncrRefCount(emptyObj);
while (code == TCL_OK && objc-- > 0) {
- if (Tcl_ObjSetVar2(interp, *objv++, NULL, emptyObj,
- TCL_LEAVE_ERR_MSG) == NULL) {
+ if (NULL == Tcl_ObjSetVar2(interp, *objv++, NULL,
+ emptyObj, TCL_LEAVE_ERR_MSG)) {
code = TCL_ERROR;
}
}
@@ -2368,13 +2099,7 @@ Tcl_LassignObjCmd(
}
if (code == TCL_OK && listObjc > 0) {
- Tcl_Obj *resultObjPtr = TclListObjRange(
- interp, listCopyPtr, origListObjc - listObjc, origListObjc - 1);
- if (resultObjPtr == NULL) {
- code = TCL_ERROR;
- } else {
- Tcl_SetObjResult(interp, resultObjPtr);
- }
+ Tcl_SetObjResult(interp, Tcl_NewListObj(listObjc, listObjv));
}
Tcl_DecrRefCount(listCopyPtr);
@@ -2400,15 +2125,16 @@ Tcl_LassignObjCmd(
int
Tcl_LindexObjCmd(
- TCL_UNUSED(void *),
+ ClientData dummy, /* Not used. */
Tcl_Interp *interp, /* Current interpreter. */
int objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
{
+
Tcl_Obj *elemPtr; /* Pointer to the element being extracted. */
if (objc < 2) {
- Tcl_WrongNumArgs(interp, 1, objv, "list ?index ...?");
+ Tcl_WrongNumArgs(interp, 1, objv, "list ?index...?");
return TCL_ERROR;
}
@@ -2431,11 +2157,11 @@ Tcl_LindexObjCmd(
if (elemPtr == NULL) {
return TCL_ERROR;
+ } else {
+ Tcl_SetObjResult(interp, elemPtr);
+ Tcl_DecrRefCount(elemPtr);
+ return TCL_OK;
}
-
- Tcl_SetObjResult(interp, elemPtr);
- Tcl_DecrRefCount(elemPtr);
- return TCL_OK;
}
/*
@@ -2458,17 +2184,16 @@ Tcl_LindexObjCmd(
int
Tcl_LinsertObjCmd(
- TCL_UNUSED(void *),
+ ClientData dummy, /* Not used. */
Tcl_Interp *interp, /* Current interpreter. */
- int objc, /* Number of arguments. */
+ register int objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
{
Tcl_Obj *listPtr;
- Tcl_Size len, index;
- int result;
+ int index, len, result;
- if (objc < 3) {
- Tcl_WrongNumArgs(interp, 1, objv, "list index ?element ...?");
+ if (objc < 4) {
+ Tcl_WrongNumArgs(interp, 1, objv, "list index element ?element ...?");
return TCL_ERROR;
}
@@ -2541,10 +2266,10 @@ Tcl_LinsertObjCmd(
int
Tcl_ListObjCmd(
- TCL_UNUSED(void *),
+ ClientData dummy, /* Not used. */
Tcl_Interp *interp, /* Current interpreter. */
- int objc, /* Number of arguments. */
- Tcl_Obj *const objv[])
+ register int objc, /* Number of arguments. */
+ register Tcl_Obj *const objv[])
/* The argument objects. */
{
/*
@@ -2553,7 +2278,7 @@ Tcl_ListObjCmd(
*/
if (objc > 1) {
- Tcl_SetObjResult(interp, Tcl_NewListObj(objc-1, &objv[1]));
+ Tcl_SetObjResult(interp, Tcl_NewListObj((objc-1), &(objv[1])));
}
return TCL_OK;
}
@@ -2577,15 +2302,13 @@ Tcl_ListObjCmd(
int
Tcl_LlengthObjCmd(
- TCL_UNUSED(void *),
+ ClientData dummy, /* Not used. */
Tcl_Interp *interp, /* Current interpreter. */
int objc, /* Number of arguments. */
- Tcl_Obj *const objv[])
+ register Tcl_Obj *const objv[])
/* Argument objects. */
{
- Tcl_Size listLen;
- int result;
- Tcl_Obj *objPtr;
+ int listLen, result;
if (objc != 2) {
Tcl_WrongNumArgs(interp, 1, objv, "list");
@@ -2602,110 +2325,7 @@ Tcl_LlengthObjCmd(
* length.
*/
- TclNewUIntObj(objPtr, listLen);
- Tcl_SetObjResult(interp, objPtr);
- return TCL_OK;
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * Tcl_LpopObjCmd --
- *
- * This procedure is invoked to process the "lpop" Tcl command. See the
- * user documentation for details on what it does.
- *
- * Results:
- * A standard Tcl object result.
- *
- * Side effects:
- * See the user documentation.
- *
- *----------------------------------------------------------------------
- */
-
-int
-Tcl_LpopObjCmd(
- TCL_UNUSED(void *),
- Tcl_Interp *interp, /* Current interpreter. */
- int objc, /* Number of arguments. */
- Tcl_Obj *const objv[])
- /* Argument objects. */
-{
- Tcl_Size listLen;
- int result;
- Tcl_Obj *elemPtr, *stored;
- Tcl_Obj *listPtr, **elemPtrs;
-
- if (objc < 2) {
- Tcl_WrongNumArgs(interp, 1, objv, "listvar ?index?");
- return TCL_ERROR;
- }
-
- listPtr = Tcl_ObjGetVar2(interp, objv[1], NULL, TCL_LEAVE_ERR_MSG);
- if (listPtr == NULL) {
- return TCL_ERROR;
- }
-
- result = TclListObjGetElements(interp, listPtr, &listLen, &elemPtrs);
- if (result != TCL_OK) {
- return result;
- }
-
- /*
- * First, extract the element to be returned.
- * TclLindexFlat adds a ref count which is handled.
- */
-
- if (objc == 2) {
- if (!listLen) {
- /* empty list, throw the same error as with index "end" */
- Tcl_SetObjResult(interp, Tcl_NewStringObj(
- "index \"end\" out of range", -1));
- Tcl_SetErrorCode(interp, "TCL", "VALUE", "INDEX"
- "OUTOFRANGE", (void *)NULL);
- return TCL_ERROR;
- }
- elemPtr = elemPtrs[listLen - 1];
- Tcl_IncrRefCount(elemPtr);
- } else {
- elemPtr = TclLindexFlat(interp, listPtr, objc-2, objv+2);
-
- if (elemPtr == NULL) {
- return TCL_ERROR;
- }
- }
- Tcl_SetObjResult(interp, elemPtr);
- Tcl_DecrRefCount(elemPtr);
-
- /*
- * Second, remove the element.
- * TclLsetFlat adds a ref count which is handled.
- */
-
- if (objc == 2) {
- if (Tcl_IsShared(listPtr)) {
- listPtr = TclListObjCopy(NULL, listPtr);
- }
- result = Tcl_ListObjReplace(interp, listPtr, listLen - 1, 1, 0, NULL);
- if (result != TCL_OK) {
- return result;
- }
- Tcl_IncrRefCount(listPtr);
- } else {
- listPtr = TclLsetFlat(interp, listPtr, objc-2, objv+2, NULL);
-
- if (listPtr == NULL) {
- return TCL_ERROR;
- }
- }
-
- stored = Tcl_ObjSetVar2(interp, objv[1], NULL, listPtr, TCL_LEAVE_ERR_MSG);
- Tcl_DecrRefCount(listPtr);
- if (stored == NULL) {
- return TCL_ERROR;
- }
-
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(listLen));
return TCL_OK;
}
@@ -2728,198 +2348,58 @@ Tcl_LpopObjCmd(
int
Tcl_LrangeObjCmd(
- TCL_UNUSED(void *),
+ ClientData notUsed, /* Not used. */
Tcl_Interp *interp, /* Current interpreter. */
int objc, /* Number of arguments. */
- Tcl_Obj *const objv[])
+ register Tcl_Obj *const objv[])
/* Argument objects. */
{
- int result;
- Tcl_Size listLen, first, last;
+ Tcl_Obj *listPtr, **elemPtrs;
+ int listLen, first, result;
+
if (objc != 4) {
Tcl_WrongNumArgs(interp, 1, objv, "list first last");
return TCL_ERROR;
}
- result = TclListObjLength(interp, objv[1], &listLen);
- if (result != TCL_OK) {
- return result;
- }
-
- result = TclGetIntForIndexM(interp, objv[2], /*endValue*/ listLen - 1,
- &first);
- if (result != TCL_OK) {
- return result;
- }
-
- result = TclGetIntForIndexM(interp, objv[3], /*endValue*/ listLen - 1,
- &last);
- if (result != TCL_OK) {
- return result;
- }
-
- if (TclHasInternalRep(objv[1],&tclArithSeriesType)) {
- Tcl_Obj *rangeObj;
- rangeObj = TclArithSeriesObjRange(interp, objv[1], first, last);
- if (rangeObj) {
- Tcl_SetObjResult(interp, rangeObj);
- } else {
- return TCL_ERROR;
- }
- } else {
- Tcl_Obj *resultObj = TclListObjRange(interp, objv[1], first, last);
- if (resultObj == NULL) {
- return TCL_ERROR;
- }
- Tcl_SetObjResult(interp, resultObj);
- }
- return TCL_OK;
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * Tcl_LremoveObjCmd --
- *
- * This procedure is invoked to process the "lremove" Tcl command. See the
- * user documentation for details on what it does.
- *
- * Results:
- * A standard Tcl object result.
- *
- * Side effects:
- * See the user documentation.
- *
- *----------------------------------------------------------------------
- */
-
-static int
-LremoveIndexCompare(
- const void *el1Ptr,
- const void *el2Ptr)
-{
- Tcl_Size idx1 = *((const Tcl_Size *) el1Ptr);
- Tcl_Size idx2 = *((const Tcl_Size *) el2Ptr);
-
- /*
- * This will put the larger element first.
- */
-
- return (idx1 < idx2) ? 1 : (idx1 > idx2) ? -1 : 0;
-}
-
-int
-Tcl_LremoveObjCmd(
- TCL_UNUSED(void *),
- Tcl_Interp *interp, /* Current interpreter. */
- int objc, /* Number of arguments. */
- Tcl_Obj *const objv[]) /* Argument objects. */
-{
- Tcl_Size i, idxc, prevIdx, first, num;
- Tcl_Size *idxv, listLen;
- Tcl_Obj *listObj;
- int copied = 0, status = TCL_OK;
-
/*
- * Parse the arguments.
+ * Make sure the list argument is a list object and get its length and a
+ * pointer to its array of element pointers.
*/
- if (objc < 2) {
- Tcl_WrongNumArgs(interp, 1, objv, "list ?index ...?");
- return TCL_ERROR;
- }
-
- listObj = objv[1];
- if (TclListObjLength(interp, listObj, &listLen) != TCL_OK) {
+ listPtr = TclListObjCopy(interp, objv[1]);
+ if (listPtr == NULL) {
return TCL_ERROR;
}
+ TclListObjGetElements(NULL, listPtr, &listLen, &elemPtrs);
- idxc = objc - 2;
- if (idxc == 0) {
- Tcl_SetObjResult(interp, listObj);
- return TCL_OK;
- }
- idxv = (Tcl_Size *)ckalloc((objc - 2) * sizeof(*idxv));
- for (i = 2; i < objc; i++) {
- status = (TclGetIntForIndexM(interp, objv[i], /*endValue*/ listLen - 1,
- &idxv[i - 2]) != TCL_OK);
- if (status != TCL_OK) {
- goto done;
- }
- }
-
- /*
- * Sort the indices, large to small so that when we remove an index we
- * don't change the indices still to be processed.
- */
-
- if (idxc > 1) {
- qsort(idxv, idxc, sizeof(*idxv), LremoveIndexCompare);
- }
-
- /*
- * Make our working copy, then do the actual removes piecemeal.
- */
-
- if (Tcl_IsShared(listObj)) {
- listObj = TclListObjCopy(NULL, listObj);
- copied = 1;
- }
- num = 0;
- first = listLen;
- for (i = 0, prevIdx = -1 ; i < idxc ; i++) {
- Tcl_Size idx = idxv[i];
-
- /*
- * Repeated index and sanity check.
- */
+ result = TclGetIntForIndexM(interp, objv[2], /*endValue*/ listLen - 1,
+ &first);
+ if (result == TCL_OK) {
+ int last;
- if (idx == prevIdx) {
- continue;
- }
- prevIdx = idx;
- if (idx < 0 || idx >= listLen) {
- continue;
+ if (first < 0) {
+ first = 0;
}
- /*
- * Coalesce adjacent removes to reduce the number of copies.
- */
+ result = TclGetIntForIndexM(interp, objv[3], /*endValue*/ listLen - 1,
+ &last);
+ if (result == TCL_OK) {
+ if (last >= listLen) {
+ last = (listLen - 1);
+ }
- if (num == 0) {
- num = 1;
- first = idx;
- } else if (idx + 1 == first) {
- num++;
- first = idx;
- } else {
- /*
- * Note that this operation can't fail now; we know we have a list
- * and we're only ever contracting that list.
- */
+ if (first <= last) {
+ int numElems = (last - first + 1);
- status = Tcl_ListObjReplace(interp, listObj, first, num, 0, NULL);
- if (status != TCL_OK) {
- goto done;
- }
- listLen -= num;
- num = 1;
- first = idx;
- }
- }
- if (num != 0) {
- status = Tcl_ListObjReplace(interp, listObj, first, num, 0, NULL);
- if (status != TCL_OK) {
- if (copied) {
- Tcl_DecrRefCount(listObj);
+ Tcl_SetObjResult(interp,
+ Tcl_NewListObj(numElems, &(elemPtrs[first])));
}
- goto done;
}
}
- Tcl_SetObjResult(interp, listObj);
-done:
- ckfree(idxv);
- return status;
+
+ Tcl_DecrRefCount(listPtr);
+ return result;
}
/*
@@ -2941,33 +2421,30 @@ done:
int
Tcl_LrepeatObjCmd(
- TCL_UNUSED(ClientData),
+ ClientData dummy, /* Not used. */
Tcl_Interp *interp, /* Current interpreter. */
- int objc, /* Number of arguments. */
- Tcl_Obj *const objv[])
+ register int objc, /* Number of arguments. */
+ register Tcl_Obj *const objv[])
/* The argument objects. */
{
- Tcl_WideInt elementCount, i;
- Tcl_Size totalElems;
- Tcl_Obj *listPtr, **dataArray = NULL;
+ int elementCount, i, totalElems;
+ Tcl_Obj *listPtr, **dataArray;
+ List *listRepPtr;
/*
* Check arguments for legality:
- * lrepeat count ?value ...?
+ * lrepeat posInt value ?value ...?
*/
- if (objc < 2) {
- Tcl_WrongNumArgs(interp, 1, objv, "count ?value ...?");
+ if (objc < 3) {
+ Tcl_WrongNumArgs(interp, 1, objv, "positiveCount value ?value ...?");
return TCL_ERROR;
}
- if (TCL_OK != TclGetWideIntFromObj(interp, objv[1], &elementCount)) {
+ if (TCL_ERROR == TclGetIntFromObj(interp, objv[1], &elementCount)) {
return TCL_ERROR;
}
- if (elementCount < 0) {
- Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "bad count \"%" TCL_LL_MODIFIER "d\": must be integer >= 0", elementCount));
- Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LREPEAT", "NEGARG",
- (void *)NULL);
+ if (elementCount < 1) {
+ Tcl_AppendResult(interp, "must have a count of at least 1", NULL);
return TCL_ERROR;
}
@@ -2980,10 +2457,9 @@ Tcl_LrepeatObjCmd(
/* Final sanity check. Do not exceed limits on max list length. */
- if (elementCount && objc > LIST_MAX/elementCount) {
+ if (objc > LIST_MAX/elementCount) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "max length of a Tcl list (%" TCL_SIZE_MODIFIER "d elements) exceeded", LIST_MAX));
- Tcl_SetErrorCode(interp, "TCL", "MEMORY", (void *)NULL);
+ "max length of a Tcl list (%d elements) exceeded", LIST_MAX));
return TCL_ERROR;
}
totalElems = objc * elementCount;
@@ -2994,17 +2470,9 @@ Tcl_LrepeatObjCmd(
*/
listPtr = Tcl_NewListObj(totalElems, NULL);
- if (totalElems) {
- ListRep listRep;
- ListObjGetRep(listPtr, &listRep);
- dataArray = ListRepElementsBase(&listRep);
- listRep.storePtr->numUsed = totalElems;
- if (listRep.spanPtr) {
- /* Future proofing in case Tcl_NewListObj returns a span */
- listRep.spanPtr->spanStart = listRep.storePtr->firstUsed;
- listRep.spanPtr->spanLength = listRep.storePtr->numUsed;
- }
- }
+ listRepPtr = ListRepPtr(listPtr);
+ listRepPtr->elemCount = elementCount*objc;
+ dataArray = &listRepPtr->elements;
/*
* Set the elements. Note that we handle the common degenerate case of a
@@ -3013,16 +2481,15 @@ Tcl_LrepeatObjCmd(
* number of times.
*/
- CLANG_ASSERT(dataArray || totalElems == 0 );
if (objc == 1) {
- Tcl_Obj *tmpPtr = objv[0];
+ register Tcl_Obj *tmpPtr = objv[0];
tmpPtr->refCount += elementCount;
for (i=0 ; i<elementCount ; i++) {
dataArray[i] = tmpPtr;
}
} else {
- Tcl_Size j, k = 0;
+ int j, k = 0;
for (i=0 ; i<elementCount ; i++) {
for (j=0 ; j<objc ; j++) {
@@ -3056,18 +2523,17 @@ Tcl_LrepeatObjCmd(
int
Tcl_LreplaceObjCmd(
- TCL_UNUSED(void *),
+ ClientData dummy, /* Not used. */
Tcl_Interp *interp, /* Current interpreter. */
int objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
{
- Tcl_Obj *listPtr;
- Tcl_Size numToDelete, listLen, first, last;
- int result;
+ register Tcl_Obj *listPtr;
+ int first, last, listLen, numToDelete, result;
if (objc < 4) {
Tcl_WrongNumArgs(interp, 1, objv,
- "list first last ?element ...?");
+ "list first last ?element element ...?");
return TCL_ERROR;
}
@@ -3092,17 +2558,27 @@ Tcl_LreplaceObjCmd(
return result;
}
- if (first == TCL_INDEX_NONE) {
- first = 0;
- } else if (first > listLen) {
- first = listLen;
+ if (first < 0) {
+ first = 0;
}
+ /*
+ * Complain if the user asked for a start element that is greater than the
+ * list length. This won't ever trigger for the "end-*" case as that will
+ * be properly constrained by TclGetIntForIndex because we use listLen-1
+ * (to allow for replacing the last elem).
+ */
+
+ if ((first >= listLen) && (listLen > 0)) {
+ Tcl_AppendResult(interp, "list doesn't contain element ",
+ TclGetString(objv[2]), NULL);
+ return TCL_ERROR;
+ }
if (last >= listLen) {
- last = listLen - 1;
+ last = (listLen - 1);
}
if (first <= last) {
- numToDelete = (unsigned)last - (unsigned)first + 1; /* See [3d3124d01d] */
+ numToDelete = (last - first + 1);
} else {
numToDelete = 0;
}
@@ -3126,7 +2602,7 @@ Tcl_LreplaceObjCmd(
*/
if (TCL_OK != Tcl_ListObjReplace(interp, listPtr, first, numToDelete,
- objc-4, objv+4)) {
+ objc-4, &(objv[4]))) {
return TCL_ERROR;
}
@@ -3157,66 +2633,40 @@ Tcl_LreplaceObjCmd(
int
Tcl_LreverseObjCmd(
- TCL_UNUSED(void *),
+ ClientData clientData, /* Not used. */
Tcl_Interp *interp, /* Current interpreter. */
int objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument values. */
{
Tcl_Obj **elemv;
- Tcl_Size elemc, i, j;
+ int elemc, i, j;
if (objc != 2) {
Tcl_WrongNumArgs(interp, 1, objv, "list");
return TCL_ERROR;
}
-
- /*
- * Handle ArithSeries special case - don't shimmer a series into a list
- * just to reverse it.
- */
- if (TclHasInternalRep(objv[1],&tclArithSeriesType)) {
- Tcl_Obj *resObj = TclArithSeriesObjReverse(interp, objv[1]);
- if (resObj) {
- Tcl_SetObjResult(interp, resObj);
- return TCL_OK;
- } else {
- return TCL_ERROR;
- }
- } /* end ArithSeries */
-
- /* True List */
- if (TclListObjLength(interp, objv[1], &elemc) != TCL_OK) {
+ if (TclListObjGetElements(interp, objv[1], &elemc, &elemv) != TCL_OK) {
return TCL_ERROR;
}
/*
- * If the list is empty, just return it. [Bug 1876793]
+ * If the list is empty, just return it [Bug 1876793]
*/
if (!elemc) {
Tcl_SetObjResult(interp, objv[1]);
return TCL_OK;
}
- if (TclListObjGetElements(interp, objv[1], &elemc, &elemv) != TCL_OK) {
- return TCL_ERROR;
- }
if (Tcl_IsShared(objv[1])
- || ListObjRepIsShared(objv[1])) { /* Bug 1675044 */
+ || (ListRepPtr(objv[1])->refCount > 1)) { /* Bug 1675044 */
Tcl_Obj *resultObj, **dataArray;
- ListRep listRep;
+ List *listRepPtr;
resultObj = Tcl_NewListObj(elemc, NULL);
-
- /* Modify the internal rep in-place */
- ListObjGetRep(resultObj, &listRep);
- listRep.storePtr->numUsed = elemc;
- dataArray = ListRepElementsBase(&listRep);
- if (listRep.spanPtr) {
- /* Future proofing */
- listRep.spanPtr->spanStart = listRep.storePtr->firstUsed;
- listRep.spanPtr->spanLength = listRep.storePtr->numUsed;
- }
+ listRepPtr = ListRepPtr(resultObj);
+ listRepPtr->elemCount = elemc;
+ dataArray = &listRepPtr->elements;
for (i=0,j=elemc-1 ; i<elemc ; i++,j--) {
dataArray[j] = elemv[i];
@@ -3262,37 +2712,33 @@ Tcl_LreverseObjCmd(
int
Tcl_LsearchObjCmd(
- TCL_UNUSED(void *),
+ ClientData clientData, /* Not used. */
Tcl_Interp *interp, /* Current interpreter. */
int objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument values. */
{
- const char *bytes, *patternBytes;
- int match, result=TCL_OK, bisect;
- Tcl_Size i, length, listc, elemLen, start, index;
- Tcl_Size groupSize, groupOffset, lower, upper;
- int allocatedIndexVector = 0;
- int dataType, isIncreasing;
- Tcl_WideInt patWide, objWide, wide;
+ char *bytes, *patternBytes;
+ int i, match, mode, index, result, listc, length, elemLen;
+ int dataType, isIncreasing, lower, upper, patInt, objInt, offset;
int allMatches, inlineReturn, negatedMatch, returnSubindices, noCase;
double patDouble, objDouble;
SortInfo sortInfo;
Tcl_Obj *patObj, **listv, *listPtr, *startPtr, *itemPtr;
- SortStrCmpFn_t strCmpFn = TclUtfCmp;
+ SortStrCmpFn_t strCmpFn = strcmp;
Tcl_RegExp regexp = NULL;
- static const char *const options[] = {
- "-all", "-ascii", "-bisect", "-decreasing", "-dictionary",
+ static const char *options[] = {
+ "-all", "-ascii", "-decreasing", "-dictionary",
"-exact", "-glob", "-increasing", "-index",
"-inline", "-integer", "-nocase", "-not",
- "-real", "-regexp", "-sorted", "-start", "-stride",
+ "-real", "-regexp", "-sorted", "-start",
"-subindices", NULL
};
- enum lsearchoptions {
- LSEARCH_ALL, LSEARCH_ASCII, LSEARCH_BISECT, LSEARCH_DECREASING,
- LSEARCH_DICTIONARY, LSEARCH_EXACT, LSEARCH_GLOB, LSEARCH_INCREASING,
- LSEARCH_INDEX, LSEARCH_INLINE, LSEARCH_INTEGER, LSEARCH_NOCASE,
- LSEARCH_NOT, LSEARCH_REAL, LSEARCH_REGEXP, LSEARCH_SORTED,
- LSEARCH_START, LSEARCH_STRIDE, LSEARCH_SUBINDICES
+ enum options {
+ LSEARCH_ALL, LSEARCH_ASCII, LSEARCH_DECREASING, LSEARCH_DICTIONARY,
+ LSEARCH_EXACT, LSEARCH_GLOB, LSEARCH_INCREASING, LSEARCH_INDEX,
+ LSEARCH_INLINE, LSEARCH_INTEGER, LSEARCH_NOCASE, LSEARCH_NOT,
+ LSEARCH_REAL, LSEARCH_REGEXP, LSEARCH_SORTED, LSEARCH_START,
+ LSEARCH_SUBINDICES
};
enum datatypes {
ASCII, DICTIONARY, INTEGER, REAL
@@ -3300,7 +2746,6 @@ Tcl_LsearchObjCmd(
enum modes {
EXACT, GLOB, REGEXP, SORTED
};
- enum modes mode;
mode = GLOB;
dataType = ASCII;
@@ -3309,12 +2754,9 @@ Tcl_LsearchObjCmd(
inlineReturn = 0;
returnSubindices = 0;
negatedMatch = 0;
- bisect = 0;
listPtr = NULL;
startPtr = NULL;
- groupSize = 1;
- groupOffset = 0;
- start = 0;
+ offset = 0;
noCase = 0;
sortInfo.compareCmdPtr = NULL;
sortInfo.isIncreasing = 1;
@@ -3325,27 +2767,28 @@ Tcl_LsearchObjCmd(
sortInfo.indexc = 0;
if (objc < 3) {
- Tcl_WrongNumArgs(interp, 1, objv, "?-option value ...? list pattern");
+ Tcl_WrongNumArgs(interp, 1, objv, "?options? list pattern");
return TCL_ERROR;
}
for (i = 1; i < objc-2; i++) {
if (Tcl_GetIndexFromObj(interp, objv[i], options, "option", 0, &index)
!= TCL_OK) {
- result = TCL_ERROR;
- goto done;
+ if (startPtr != NULL) {
+ Tcl_DecrRefCount(startPtr);
+ }
+ if (sortInfo.indexc > 1) {
+ ckfree((char *) sortInfo.indexv);
+ }
+ return TCL_ERROR;
}
- switch ((enum lsearchoptions) index) {
+ switch ((enum options) index) {
case LSEARCH_ALL: /* -all */
allMatches = 1;
break;
case LSEARCH_ASCII: /* -ascii */
dataType = ASCII;
break;
- case LSEARCH_BISECT: /* -bisect */
- mode = SORTED;
- bisect = 1;
- break;
case LSEARCH_DECREASING: /* -decreasing */
isIncreasing = 0;
sortInfo.isIncreasing = 0;
@@ -3396,14 +2839,13 @@ Tcl_LsearchObjCmd(
if (startPtr != NULL) {
Tcl_DecrRefCount(startPtr);
- startPtr = NULL;
}
if (i > objc-4) {
- Tcl_SetObjResult(interp, Tcl_NewStringObj(
- "missing starting index", -1));
- Tcl_SetErrorCode(interp, "TCL", "ARGUMENT", "MISSING", (void *)NULL);
- result = TCL_ERROR;
- goto done;
+ if (sortInfo.indexc > 1) {
+ ckfree((char *) sortInfo.indexv);
+ }
+ Tcl_AppendResult(interp, "missing starting index", NULL);
+ return TCL_ERROR;
}
i++;
if (objv[i] == objv[objc - 2]) {
@@ -3417,48 +2859,24 @@ Tcl_LsearchObjCmd(
startPtr = Tcl_DuplicateObj(objv[i]);
} else {
startPtr = objv[i];
+ Tcl_IncrRefCount(startPtr);
}
- Tcl_IncrRefCount(startPtr);
- break;
- case LSEARCH_STRIDE: /* -stride */
- if (i > objc-4) {
- Tcl_SetObjResult(interp, Tcl_NewStringObj(
- "\"-stride\" option must be "
- "followed by stride length", -1));
- Tcl_SetErrorCode(interp, "TCL", "ARGUMENT", "MISSING", (void *)NULL);
- result = TCL_ERROR;
- goto done;
- }
- if (Tcl_GetWideIntFromObj(interp, objv[i+1], &wide) != TCL_OK) {
- result = TCL_ERROR;
- goto done;
- }
- if ((wide < 1) || (wide > LIST_MAX)) {
- Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "stride length must be between 1 and %d", LIST_MAX));
- Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LSEARCH",
- "BADSTRIDE", (void *)NULL);
- result = TCL_ERROR;
- goto done;
- }
- groupSize = wide;
- i++;
break;
case LSEARCH_INDEX: { /* -index */
Tcl_Obj **indices;
- Tcl_Size j;
+ int j;
- if (allocatedIndexVector) {
- TclStackFree(interp, sortInfo.indexv);
- allocatedIndexVector = 0;
+ if (sortInfo.indexc > 1) {
+ ckfree((char *) sortInfo.indexv);
}
if (i > objc-4) {
- Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ if (startPtr != NULL) {
+ Tcl_DecrRefCount(startPtr);
+ }
+ Tcl_AppendResult(interp,
"\"-index\" option must be followed by list index",
- -1));
- Tcl_SetErrorCode(interp, "TCL", "ARGUMENT", "MISSING", (void *)NULL);
- result = TCL_ERROR;
- goto done;
+ NULL);
+ return TCL_ERROR;
}
/*
@@ -3470,8 +2888,10 @@ Tcl_LsearchObjCmd(
i++;
if (TclListObjGetElements(interp, objv[i],
&sortInfo.indexc, &indices) != TCL_OK) {
- result = TCL_ERROR;
- goto done;
+ if (startPtr != NULL) {
+ Tcl_DecrRefCount(startPtr);
+ }
+ return TCL_ERROR;
}
switch (sortInfo.indexc) {
case 0:
@@ -3482,9 +2902,7 @@ Tcl_LsearchObjCmd(
break;
default:
sortInfo.indexv = (int *)
- TclStackAlloc(interp, sizeof(int) * sortInfo.indexc);
- allocatedIndexVector = 1; /* Cannot use indexc field, as it
- * might be decreased by 1 later. */
+ ckalloc(sizeof(int) * sortInfo.indexc);
}
/*
@@ -3494,25 +2912,15 @@ Tcl_LsearchObjCmd(
*/
for (j=0 ; j<sortInfo.indexc ; j++) {
- int encoded = 0;
- if (TclIndexEncode(interp, indices[j], TCL_INDEX_NONE,
- TCL_INDEX_NONE, &encoded) != TCL_OK) {
- result = TCL_ERROR;
- }
- if (encoded == (int)TCL_INDEX_NONE) {
- Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "index \"%s\" out of range",
- TclGetString(indices[j])));
- Tcl_SetErrorCode(interp, "TCL", "VALUE", "INDEX"
- "OUTOFRANGE", (void *)NULL);
- result = TCL_ERROR;
- }
- if (result == TCL_ERROR) {
+ if (TclGetIntForIndexM(interp, indices[j], SORTIDX_END,
+ &sortInfo.indexv[j]) != TCL_OK) {
+ if (sortInfo.indexc > 1) {
+ ckfree((char *) sortInfo.indexv);
+ }
Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
- "\n (-index option item number %" TCL_SIZE_MODIFIER "d)", j));
- goto done;
+ "\n (-index option item number %d)", j));
+ return TCL_ERROR;
}
- sortInfo.indexv[j] = encoded;
}
break;
}
@@ -3524,24 +2932,15 @@ Tcl_LsearchObjCmd(
*/
if (returnSubindices && sortInfo.indexc==0) {
- Tcl_SetObjResult(interp, Tcl_NewStringObj(
- "-subindices cannot be used without -index option", -1));
- Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LSEARCH",
- "BAD_OPTION_MIX", (void *)NULL);
- result = TCL_ERROR;
- goto done;
- }
-
- if (bisect && (allMatches || negatedMatch)) {
- Tcl_SetObjResult(interp, Tcl_NewStringObj(
- "-bisect is not compatible with -all or -not", -1));
- Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LSEARCH",
- "BAD_OPTION_MIX", (void *)NULL);
- result = TCL_ERROR;
- goto done;
+ if (startPtr != NULL) {
+ Tcl_DecrRefCount(startPtr);
+ }
+ Tcl_AppendResult(interp,
+ "-subindices cannot be used without -index option", NULL);
+ return TCL_ERROR;
}
- if (mode == REGEXP) {
+ if ((enum modes) mode == REGEXP) {
/*
* We can shimmer regexp/list if listv[i] == pattern, so get the
* regexp rep before the list rep. First time round, omit the interp
@@ -3564,8 +2963,13 @@ Tcl_LsearchObjCmd(
}
if (regexp == NULL) {
- result = TCL_ERROR;
- goto done;
+ if (startPtr != NULL) {
+ Tcl_DecrRefCount(startPtr);
+ }
+ if (sortInfo.indexc > 1) {
+ ckfree((char *) sortInfo.indexv);
+ }
+ return TCL_ERROR;
}
}
@@ -3576,51 +2980,13 @@ Tcl_LsearchObjCmd(
result = TclListObjGetElements(interp, objv[objc - 2], &listc, &listv);
if (result != TCL_OK) {
- goto done;
- }
-
- /*
- * Check for sanity when grouping elements of the overall list together
- * because of the -stride option. [TIP #351]
- */
-
- if (groupSize > 1) {
- if (listc % groupSize) {
- Tcl_SetObjResult(interp, Tcl_NewStringObj(
- "list size must be a multiple of the stride length",
- -1));
- Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LSEARCH", "BADSTRIDE",
- (void *)NULL);
- result = TCL_ERROR;
- goto done;
+ if (startPtr != NULL) {
+ Tcl_DecrRefCount(startPtr);
}
- if (sortInfo.indexc > 0) {
- /*
- * Use the first value in the list supplied to -index as the
- * offset of the element within each group by which to sort.
- */
-
- groupOffset = TclIndexDecode(sortInfo.indexv[0], groupSize - 1);
- if (groupOffset < 0 || groupOffset >= groupSize) {
- Tcl_SetObjResult(interp, Tcl_NewStringObj(
- "when used with \"-stride\", the leading \"-index\""
- " value must be within the group", -1));
- Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LSEARCH",
- "BADINDEX", (void *)NULL);
- result = TCL_ERROR;
- goto done;
- }
- if (sortInfo.indexc == 1) {
- sortInfo.indexc = 0;
- sortInfo.indexv = NULL;
- } else {
- sortInfo.indexc--;
-
- for (i = 0; i < sortInfo.indexc; i++) {
- sortInfo.indexv[i] = sortInfo.indexv[i+1];
- }
- }
+ if (sortInfo.indexc > 1) {
+ ckfree((char *) sortInfo.indexv);
}
+ return result;
}
/*
@@ -3628,12 +2994,16 @@ Tcl_LsearchObjCmd(
*/
if (startPtr) {
- result = TclGetIntForIndexM(interp, startPtr, listc-1, &start);
+ result = TclGetIntForIndexM(interp, startPtr, listc-1, &offset);
+ Tcl_DecrRefCount(startPtr);
if (result != TCL_OK) {
- goto done;
+ if (sortInfo.indexc > 1) {
+ ckfree((char *) sortInfo.indexv);
+ }
+ return result;
}
- if (start == TCL_INDEX_NONE) {
- start = TCL_INDEX_START;
+ if (offset < 0) {
+ offset = 0;
}
/*
@@ -3641,37 +3011,34 @@ Tcl_LsearchObjCmd(
* "did not match anything at all" result straight away. [Bug 1374778]
*/
- if (start >= listc) {
+ if (offset > listc-1) {
+ if (sortInfo.indexc > 1) {
+ ckfree((char *) sortInfo.indexv);
+ }
if (allMatches || inlineReturn) {
Tcl_ResetResult(interp);
} else {
- TclNewIntObj(itemPtr, -1);
- Tcl_SetObjResult(interp, itemPtr);
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(-1));
}
- goto done;
- }
-
- /*
- * If start points within a group, it points to the start of the group.
- */
-
- if (groupSize > 1) {
- start -= (start % groupSize);
+ return TCL_OK;
}
}
patObj = objv[objc - 1];
patternBytes = NULL;
- if (mode == EXACT || mode == SORTED) {
+ if ((enum modes) mode == EXACT || (enum modes) mode == SORTED) {
switch ((enum datatypes) dataType) {
case ASCII:
case DICTIONARY:
patternBytes = TclGetStringFromObj(patObj, &length);
break;
case INTEGER:
- result = TclGetWideIntFromObj(interp, patObj, &patWide);
+ result = TclGetIntFromObj(interp, patObj, &patInt);
if (result != TCL_OK) {
- goto done;
+ if (sortInfo.indexc > 1) {
+ ckfree((char *) sortInfo.indexv);
+ }
+ return result;
}
/*
@@ -3684,7 +3051,10 @@ Tcl_LsearchObjCmd(
case REAL:
result = Tcl_GetDoubleFromObj(interp, patObj, &patDouble);
if (result != TCL_OK) {
- goto done;
+ if (sortInfo.indexc > 1) {
+ ckfree((char *) sortInfo.indexv);
+ }
+ return result;
}
/*
@@ -3707,7 +3077,7 @@ Tcl_LsearchObjCmd(
index = -1;
match = 0;
- if (mode == SORTED && !allMatches && !negatedMatch) {
+ if ((enum modes) mode == SORTED && !allMatches && !negatedMatch) {
/*
* If the data is sorted, we can do a more intelligent search. Note
* that there is no point in being smart when -all was specified; in
@@ -3715,23 +3085,20 @@ Tcl_LsearchObjCmd(
* sense in doing this when the match sense is inverted.
*/
- /*
- * With -stride, lower, upper and i are kept as multiples of groupSize.
- */
-
- lower = start - groupSize;
+ lower = offset - 1;
upper = listc;
- while (lower + groupSize != upper && sortInfo.resultCode == TCL_OK) {
+ while (lower + 1 != upper && sortInfo.resultCode == TCL_OK) {
i = (lower + upper)/2;
- i -= i % groupSize;
if (sortInfo.indexc != 0) {
- itemPtr = SelectObjFromSublist(listv[i+groupOffset], &sortInfo);
+ itemPtr = SelectObjFromSublist(listv[i], &sortInfo);
if (sortInfo.resultCode != TCL_OK) {
- result = sortInfo.resultCode;
- goto done;
+ if (sortInfo.indexc > 1) {
+ ckfree((char *) sortInfo.indexv);
+ }
+ return sortInfo.resultCode;
}
} else {
- itemPtr = listv[i+groupOffset];
+ itemPtr = listv[i];
}
switch ((enum datatypes) dataType) {
case ASCII:
@@ -3743,13 +3110,16 @@ Tcl_LsearchObjCmd(
match = DictionaryCompare(patternBytes, bytes);
break;
case INTEGER:
- result = TclGetWideIntFromObj(interp, itemPtr, &objWide);
+ result = TclGetIntFromObj(interp, itemPtr, &objInt);
if (result != TCL_OK) {
- goto done;
+ if (sortInfo.indexc > 1) {
+ ckfree((char *) sortInfo.indexv);
+ }
+ return result;
}
- if (patWide == objWide) {
+ if (patInt == objInt) {
match = 0;
- } else if (patWide < objWide) {
+ } else if (patInt < objInt) {
match = -1;
} else {
match = 1;
@@ -3758,7 +3128,10 @@ Tcl_LsearchObjCmd(
case REAL:
result = Tcl_GetDoubleFromObj(interp, itemPtr, &objDouble);
if (result != TCL_OK) {
- goto done;
+ if (sortInfo.indexc > 1) {
+ ckfree((char *) sortInfo.indexv);
+ }
+ return result;
}
if (patDouble == objDouble) {
match = 0;
@@ -3773,25 +3146,19 @@ Tcl_LsearchObjCmd(
/*
* Normally, binary search is written to stop when it finds a
* match. If there are duplicates of an element in the list,
- * our first match might not be the first occurrence.
+ * our first match might not be the first occurance.
* Consider: 0 0 0 1 1 1 2 2 2
*
- * To maintain consistency with standard lsearch semantics, we
- * must find the leftmost occurrence of the pattern in the
+ * To maintain consistancy with standard lsearch semantics, we
+ * must find the leftmost occurance of the pattern in the
* list. Thus we don't just stop searching here. This
* variation means that a search always makes log n
* comparisons (normal binary search might "get lucky" with an
* early comparison).
- *
- * In bisect mode though, we want the last of equals.
*/
index = i;
- if (bisect) {
- lower = i;
- } else {
- upper = i;
- }
+ upper = i;
} else if (match > 0) {
if (isIncreasing) {
lower = i;
@@ -3806,9 +3173,7 @@ Tcl_LsearchObjCmd(
}
}
}
- if (bisect && index < 0) {
- index = lower;
- }
+
} else {
/*
* We need to do a linear search, because (at least one) of:
@@ -3820,22 +3185,24 @@ Tcl_LsearchObjCmd(
if (allMatches) {
listPtr = Tcl_NewListObj(0, NULL);
}
- for (i = start; i < listc; i += groupSize) {
+ for (i = offset; i < listc; i++) {
match = 0;
- if (sortInfo.indexc != 0) {
- itemPtr = SelectObjFromSublist(listv[i+groupOffset], &sortInfo);
+ if (sortInfo.indexc != 0) {
+ itemPtr = SelectObjFromSublist(listv[i], &sortInfo);
if (sortInfo.resultCode != TCL_OK) {
if (listPtr != NULL) {
Tcl_DecrRefCount(listPtr);
}
- result = sortInfo.resultCode;
- goto done;
+ if (sortInfo.indexc > 1) {
+ ckfree((char *) sortInfo.indexv);
+ }
+ return sortInfo.resultCode;
}
} else {
- itemPtr = listv[i+groupOffset];
+ itemPtr = listv[i];
}
-
- switch (mode) {
+
+ switch ((enum modes) mode) {
case SORTED:
case EXACT:
switch ((enum datatypes) dataType) {
@@ -3850,7 +3217,8 @@ Tcl_LsearchObjCmd(
if (noCase) {
match = (TclUtfCasecmp(bytes, patternBytes) == 0);
} else {
- match = (memcmp(bytes, patternBytes, length) == 0);
+ match = (memcmp(bytes, patternBytes,
+ (size_t) length) == 0);
}
}
break;
@@ -3861,14 +3229,17 @@ Tcl_LsearchObjCmd(
break;
case INTEGER:
- result = TclGetWideIntFromObj(interp, itemPtr, &objWide);
+ result = TclGetIntFromObj(interp, itemPtr, &objInt);
if (result != TCL_OK) {
if (listPtr != NULL) {
Tcl_DecrRefCount(listPtr);
}
- goto done;
+ if (sortInfo.indexc > 1) {
+ ckfree((char *) sortInfo.indexv);
+ }
+ return result;
}
- match = (objWide == patWide);
+ match = (objInt == patInt);
break;
case REAL:
@@ -3877,7 +3248,10 @@ Tcl_LsearchObjCmd(
if (listPtr) {
Tcl_DecrRefCount(listPtr);
}
- goto done;
+ if (sortInfo.indexc > 1) {
+ ckfree((char *) sortInfo.indexv);
+ }
+ return result;
}
match = (objDouble == patDouble);
break;
@@ -3896,8 +3270,10 @@ Tcl_LsearchObjCmd(
if (listPtr != NULL) {
Tcl_DecrRefCount(listPtr);
}
- result = TCL_ERROR;
- goto done;
+ if (sortInfo.indexc > 1) {
+ ckfree((char *) sortInfo.indexv);
+ }
+ return TCL_ERROR;
}
break;
}
@@ -3921,28 +3297,22 @@ Tcl_LsearchObjCmd(
*/
if (returnSubindices && (sortInfo.indexc != 0)) {
- itemPtr = SelectObjFromSublist(listv[i+groupOffset],
- &sortInfo);
- Tcl_ListObjAppendElement(interp, listPtr, itemPtr);
- } else if (groupSize > 1) {
- Tcl_ListObjReplace(interp, listPtr, LIST_MAX, 0,
- groupSize, &listv[i]);
+ itemPtr = SelectObjFromSublist(listv[i], &sortInfo);
} else {
itemPtr = listv[i];
- Tcl_ListObjAppendElement(interp, listPtr, itemPtr);
}
+ Tcl_ListObjAppendElement(interp, listPtr, itemPtr);
} else if (returnSubindices) {
- Tcl_Size j;
+ int j;
- TclNewIndexObj(itemPtr, i+groupOffset);
+ itemPtr = Tcl_NewIntObj(i);
for (j=0 ; j<sortInfo.indexc ; j++) {
- Tcl_Obj *elObj;
- TclNewIndexObj(elObj, TclIndexDecode(sortInfo.indexv[j], listc));
- Tcl_ListObjAppendElement(interp, itemPtr, elObj);
+ Tcl_ListObjAppendElement(interp, itemPtr,
+ Tcl_NewIntObj(sortInfo.indexv[j]));
}
Tcl_ListObjAppendElement(interp, listPtr, itemPtr);
} else {
- Tcl_ListObjAppendElement(interp, listPtr, Tcl_NewWideIntObj(i));
+ Tcl_ListObjAppendElement(interp, listPtr, Tcl_NewIntObj(i));
}
}
}
@@ -3955,19 +3325,16 @@ Tcl_LsearchObjCmd(
Tcl_SetObjResult(interp, listPtr);
} else if (!inlineReturn) {
if (returnSubindices) {
- Tcl_Size j;
+ int j;
- TclNewIndexObj(itemPtr, index+groupOffset);
+ itemPtr = Tcl_NewIntObj(index);
for (j=0 ; j<sortInfo.indexc ; j++) {
- Tcl_Obj *elObj;
- TclNewIndexObj(elObj, TclIndexDecode(sortInfo.indexv[j], listc));
- Tcl_ListObjAppendElement(interp, itemPtr, elObj);
+ Tcl_ListObjAppendElement(interp, itemPtr,
+ Tcl_NewIntObj(sortInfo.indexv[j]));
}
Tcl_SetObjResult(interp, itemPtr);
} else {
- Tcl_Obj *elObj;
- TclNewIndexObj(elObj, index);
- Tcl_SetObjResult(interp, elObj);
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(index));
}
} else if (index < 0) {
/*
@@ -3975,431 +3342,19 @@ Tcl_LsearchObjCmd(
* default...
*/
- Tcl_ResetResult(interp);
+ Tcl_SetObjResult(interp, Tcl_NewObj());
} else {
- if (returnSubindices) {
- Tcl_SetObjResult(interp, SelectObjFromSublist(listv[i+groupOffset],
- &sortInfo));
- } else if (groupSize > 1) {
- Tcl_SetObjResult(interp, Tcl_NewListObj(groupSize, &listv[index]));
- } else {
- Tcl_SetObjResult(interp, listv[index]);
- }
+ Tcl_SetObjResult(interp, listv[index]);
}
- result = TCL_OK;
/*
* Cleanup the index list array.
*/
- done:
- if (startPtr != NULL) {
- Tcl_DecrRefCount(startPtr);
- }
- if (allocatedIndexVector) {
- TclStackFree(interp, sortInfo.indexv);
- }
- return result;
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * SequenceIdentifyArgument --
- * (for [lseq] command)
- *
- * Given a Tcl_Obj, identify if it is a keyword or a number
- *
- * Return Value
- * 0 - failure, unexpected value
- * 1 - value is a number
- * 2 - value is an operand keyword
- * 3 - value is a by keyword
- *
- * The decoded value will be assigned to the appropriate
- * pointer, if supplied.
- */
-
-static SequenceDecoded
-SequenceIdentifyArgument(
- Tcl_Interp *interp, /* for error reporting */
- Tcl_Obj *argPtr, /* Argument to decode */
- Tcl_Obj **numValuePtr, /* Return numeric value */
- int *keywordIndexPtr) /* Return keyword enum */
-{
- int status;
- SequenceOperators opmode;
- SequenceByMode bymode;
- void *clientData;
-
- status = Tcl_GetNumberFromObj(NULL, argPtr, &clientData, keywordIndexPtr);
- if (status == TCL_OK) {
- if (numValuePtr) {
- *numValuePtr = argPtr;
- }
- return NumericArg;
- } else {
- /* Check for an index expression */
- long value;
- double dvalue;
- Tcl_Obj *exprValueObj;
- int keyword;
- Tcl_InterpState savedstate;
- savedstate = Tcl_SaveInterpState(interp, status);
- if (Tcl_ExprLongObj(interp, argPtr, &value) != TCL_OK) {
- status = Tcl_RestoreInterpState(interp, savedstate);
- exprValueObj = argPtr;
- } else {
- // Determine if expression is double or int
- if (Tcl_ExprDoubleObj(interp, argPtr, &dvalue) != TCL_OK) {
- keyword = TCL_NUMBER_INT;
- exprValueObj = argPtr;
- } else {
- if (floor(dvalue) == dvalue) {
- TclNewIntObj(exprValueObj, value);
- keyword = TCL_NUMBER_INT;
- } else {
- TclNewDoubleObj(exprValueObj, dvalue);
- keyword = TCL_NUMBER_DOUBLE;
- }
- }
- status = Tcl_RestoreInterpState(interp, savedstate);
- if (numValuePtr) {
- *numValuePtr = exprValueObj;
- }
- if (keywordIndexPtr) {
- *keywordIndexPtr = keyword ;// type of expression result
- }
- return NumericArg;
- }
- }
-
- status = Tcl_GetIndexFromObj(NULL, argPtr, seq_operations,
- "range operation", 0, &opmode);
- if (status == TCL_OK) {
- if (keywordIndexPtr) {
- *keywordIndexPtr = opmode;
- }
- return RangeKeywordArg;
- }
-
- status = Tcl_GetIndexFromObj(NULL, argPtr, seq_step_keywords,
- "step keyword", 0, &bymode);
- if (status == TCL_OK) {
- if (keywordIndexPtr) {
- *keywordIndexPtr = bymode;
- }
- return ByKeywordArg;
- }
- return NoneArg;
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * Tcl_LseqObjCmd --
- *
- * This procedure is invoked to process the "lseq" Tcl command.
- * See the user documentation for details on what it does.
- *
- * Enumerated possible argument patterns:
- *
- * 1:
- * lseq n
- * 2:
- * lseq n n
- * 3:
- * lseq n n n
- * lseq n 'to' n
- * lseq n 'count' n
- * lseq n 'by' n
- * 4:
- * lseq n 'to' n n
- * lseq n n 'by' n
- * lseq n 'count' n n
- * 5:
- * lseq n 'to' n 'by' n
- * lseq n 'count' n 'by' n
- *
- * Results:
- * A standard Tcl object result.
- *
- * Side effects:
- * See the user documentation.
- *
- *----------------------------------------------------------------------
- */
-
-int
-Tcl_LseqObjCmd(
- TCL_UNUSED(void *),
- Tcl_Interp *interp, /* Current interpreter. */
- int objc, /* Number of arguments. */
- Tcl_Obj *const objv[]) /* The argument objects. */
-{
- Tcl_Obj *elementCount = NULL;
- Tcl_Obj *start = NULL, *end = NULL, *step = NULL;
- Tcl_WideInt values[5];
- Tcl_Obj *numValues[5];
- Tcl_Obj *numberObj;
- int status, keyword, useDoubles = 0;
- Tcl_Obj *arithSeriesPtr;
- SequenceOperators opmode;
- SequenceDecoded decoded;
- int i, arg_key = 0, value_i = 0;
- // Default constants
- Tcl_Obj *zero = Tcl_NewIntObj(0);
- Tcl_Obj *one = Tcl_NewIntObj(1);
-
- /*
- * Create a decoding key by looping through the arguments and identify
- * what kind of argument each one is. Encode each argument as a decimal
- * digit.
- */
- if (objc > 6) {
- /* Too many arguments */
- arg_key=0;
- } else for (i=1; i<objc; i++) {
- arg_key = (arg_key * 10);
- numValues[value_i] = NULL;
- decoded = SequenceIdentifyArgument(interp, objv[i], &numberObj, &keyword);
- switch (decoded) {
-
- case NoneArg:
- /*
- * Unrecognizable argument
- * Reproduce operation error message
- */
- status = Tcl_GetIndexFromObj(interp, objv[i], seq_operations,
- "operation", 0, &opmode);
- goto done;
-
- case NumericArg:
- arg_key += NumericArg;
- numValues[value_i] = numberObj;
- Tcl_IncrRefCount(numValues[value_i]);
- values[value_i] = keyword; // This is the TCL_NUMBER_* value
- useDoubles = useDoubles ? useDoubles : keyword == TCL_NUMBER_DOUBLE;
- value_i++;
- break;
-
- case RangeKeywordArg:
- arg_key += RangeKeywordArg;
- values[value_i] = keyword;
- value_i++;
- break;
-
- case ByKeywordArg:
- arg_key += ByKeywordArg;
- values[value_i] = keyword;
- value_i++;
- break;
-
- default:
- arg_key += 9; // Error state
- value_i++;
- break;
- }
- }
-
- /*
- * The key encoding defines a valid set of arguments, or indicates an
- * error condition; process the values accordningly.
- */
- switch (arg_key) {
-
-/* No argument */
- case 0:
- Tcl_WrongNumArgs(interp, 1, objv,
- "n ??op? n ??by? n??");
- status = TCL_ERROR;
- goto done;
- break;
-
-/* lseq n */
- case 1:
- start = zero;
- elementCount = numValues[0];
- end = NULL;
- step = one;
- break;
-
-/* lseq n n */
- case 11:
- start = numValues[0];
- end = numValues[1];
- break;
-
-/* lseq n n n */
- case 111:
- start = numValues[0];
- end = numValues[1];
- step = numValues[2];
- break;
-
-/* lseq n 'to' n */
-/* lseq n 'count' n */
-/* lseq n 'by' n */
- case 121:
- opmode = (SequenceOperators)values[1];
- switch (opmode) {
- case LSEQ_DOTS:
- case LSEQ_TO:
- start = numValues[0];
- end = numValues[2];
- break;
- case LSEQ_BY:
- start = zero;
- elementCount = numValues[0];
- step = numValues[2];
- break;
- case LSEQ_COUNT:
- start = numValues[0];
- elementCount = numValues[2];
- step = one;
- break;
- default:
- status = TCL_ERROR;
- goto done;
- }
- break;
-
-/* lseq n 'to' n n */
-/* lseq n 'count' n n */
- case 1211:
- opmode = (SequenceOperators)values[1];
- switch (opmode) {
- case LSEQ_DOTS:
- case LSEQ_TO:
- start = numValues[0];
- end = numValues[2];
- step = numValues[3];
- break;
- case LSEQ_COUNT:
- start = numValues[0];
- elementCount = numValues[2];
- step = numValues[3];
- break;
- case LSEQ_BY:
- /* Error case */
- status = TCL_ERROR;
- goto done;
- break;
- default:
- status = TCL_ERROR;
- goto done;
- break;
- }
- break;
-
-/* lseq n n 'by' n */
- case 1121:
- start = numValues[0];
- end = numValues[1];
- opmode = (SequenceOperators)values[2];
- switch (opmode) {
- case LSEQ_BY:
- step = numValues[3];
- break;
- case LSEQ_DOTS:
- case LSEQ_TO:
- case LSEQ_COUNT:
- default:
- status = TCL_ERROR;
- goto done;
- break;
- }
- break;
-
-/* lseq n 'to' n 'by' n */
-/* lseq n 'count' n 'by' n */
- case 12121:
- start = numValues[0];
- opmode = (SequenceOperators)values[3];
- switch (opmode) {
- case LSEQ_BY:
- step = numValues[4];
- break;
- default:
- status = TCL_ERROR;
- goto done;
- break;
- }
- opmode = (SequenceOperators)values[1];
- switch (opmode) {
- case LSEQ_DOTS:
- case LSEQ_TO:
- start = numValues[0];
- end = numValues[2];
- break;
- case LSEQ_COUNT:
- start = numValues[0];
- elementCount = numValues[2];
- break;
- default:
- status = TCL_ERROR;
- goto done;
- break;
- }
- break;
-
-/* Error cases: incomplete arguments */
- case 12:
- opmode = (SequenceOperators)values[1]; goto KeywordError; break;
- case 112:
- opmode = (SequenceOperators)values[2]; goto KeywordError; break;
- case 1212:
- opmode = (SequenceOperators)values[3]; goto KeywordError; break;
- KeywordError:
- status = TCL_ERROR;
- switch (opmode) {
- case LSEQ_DOTS:
- case LSEQ_TO:
- Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "missing \"to\" value."));
- break;
- case LSEQ_COUNT:
- Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "missing \"count\" value."));
- break;
- case LSEQ_BY:
- Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "missing \"by\" value."));
- break;
- }
- status = TCL_ERROR;
- goto done;
- break;
-
-/* All other argument errors */
- default:
- Tcl_WrongNumArgs(interp, 1, objv, "n ??op? n ??by? n??");
- status = TCL_ERROR;
- goto done;
- break;
- }
-
- /*
- * Success! Now lets create the series object.
- */
- status = TclNewArithSeriesObj(interp, &arithSeriesPtr,
- useDoubles, start, end, step, elementCount);
-
- if (status == TCL_OK) {
- Tcl_SetObjResult(interp, arithSeriesPtr);
+ if (sortInfo.indexc > 1) {
+ ckfree((char *) sortInfo.indexv);
}
-
- done:
- // Free number arguments.
- while (--value_i>=0) {
- if (numValues[value_i]) Tcl_DecrRefCount(numValues[value_i]);
- }
-
- // Free constants
- Tcl_DecrRefCount(zero);
- Tcl_DecrRefCount(one);
-
- return status;
+ return TCL_OK;
}
/*
@@ -4421,7 +3376,7 @@ Tcl_LseqObjCmd(
int
Tcl_LsetObjCmd(
- TCL_UNUSED(void *),
+ ClientData clientData, /* Not used. */
Tcl_Interp *interp, /* Current interpreter. */
int objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument values. */
@@ -4434,8 +3389,7 @@ Tcl_LsetObjCmd(
*/
if (objc < 3) {
- Tcl_WrongNumArgs(interp, 1, objv,
- "listVar ?index? ?index ...? value");
+ Tcl_WrongNumArgs(interp, 1, objv, "listVar ?index? ?index...? value");
return TCL_ERROR;
}
@@ -4443,7 +3397,8 @@ Tcl_LsetObjCmd(
* Look up the list variable's value.
*/
- listPtr = Tcl_ObjGetVar2(interp, objv[1], NULL, TCL_LEAVE_ERR_MSG);
+ listPtr = Tcl_ObjGetVar2(interp, objv[1], (Tcl_Obj *) NULL,
+ TCL_LEAVE_ERR_MSG);
if (listPtr == NULL) {
return TCL_ERROR;
}
@@ -4506,40 +3461,36 @@ Tcl_LsetObjCmd(
int
Tcl_LsortObjCmd(
- TCL_UNUSED(ClientData),
+ ClientData clientData, /* Not used. */
Tcl_Interp *interp, /* Current interpreter. */
int objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument values. */
{
int i, j, index, indices, length, nocase = 0, indexc;
int sortMode = SORTMODE_ASCII;
- int group, groupSize, groupOffset, idx, allocatedIndexVector = 0;
Tcl_Obj *resultPtr, *cmdPtr, **listObjPtrs, *listObj, *indexPtr;
- size_t elmArrSize;
- Tcl_WideInt wide;
- SortElement *elementArray = NULL, *elementPtr;
+ SortElement *elementArray, *elementPtr;
SortInfo sortInfo; /* Information about this sort that needs to
* be passed to the comparison function. */
-# define MAXCALLOC 1024000
-# define NUM_LISTS 30
- SortElement *subList[NUM_LISTS+1];
- /* This array holds pointers to temporary
- * lists built during the merge sort. Element
- * i of the array holds a list of length
- * 2**i. */
- static const char *const switches[] = {
+ static const char *switches[] = {
"-ascii", "-command", "-decreasing", "-dictionary", "-increasing",
- "-index", "-indices", "-integer", "-nocase", "-real", "-stride",
- "-unique", NULL
+ "-index", "-indices", "-integer", "-nocase", "-real", "-unique", NULL
};
enum Lsort_Switches {
LSORT_ASCII, LSORT_COMMAND, LSORT_DECREASING, LSORT_DICTIONARY,
LSORT_INCREASING, LSORT_INDEX, LSORT_INDICES, LSORT_INTEGER,
- LSORT_NOCASE, LSORT_REAL, LSORT_STRIDE, LSORT_UNIQUE
+ LSORT_NOCASE, LSORT_REAL, LSORT_UNIQUE
};
+ /*
+ * The subList array below holds pointers to temporary lists built during
+ * the merge sort. Element i of the array holds a list of length 2**i.
+ */
+# define NUM_LISTS 30
+ SortElement *subList[NUM_LISTS+1];
+
if (objc < 2) {
- Tcl_WrongNumArgs(interp, 1, objv, "?-option value ...? list");
+ Tcl_WrongNumArgs(interp, 1, objv, "?options? list");
return TCL_ERROR;
}
@@ -4553,31 +3504,30 @@ Tcl_LsortObjCmd(
sortInfo.indexc = 0;
sortInfo.unique = 0;
sortInfo.interp = interp;
- sortInfo.resultCode = TCL_OK;
+ sortInfo.resultCode = TCL_OK;
cmdPtr = NULL;
indices = 0;
- group = 0;
- groupSize = 1;
- groupOffset = 0;
- indexPtr = NULL;
for (i = 1; i < objc-1; i++) {
if (Tcl_GetIndexFromObj(interp, objv[i], switches, "option", 0,
&index) != TCL_OK) {
- sortInfo.resultCode = TCL_ERROR;
- goto done;
+ if (sortInfo.indexc > 1) {
+ ckfree((char *) sortInfo.indexv);
+ }
+ return TCL_ERROR;
}
switch ((enum Lsort_Switches) index) {
case LSORT_ASCII:
sortInfo.sortMode = SORTMODE_ASCII;
break;
case LSORT_COMMAND:
- if (i == objc-2) {
- Tcl_SetObjResult(interp, Tcl_NewStringObj(
+ if (i == (objc-2)) {
+ if (sortInfo.indexc > 1) {
+ ckfree((char *) sortInfo.indexv);
+ }
+ Tcl_AppendResult(interp,
"\"-command\" option must be followed "
- "by comparison command", -1));
- Tcl_SetErrorCode(interp, "TCL", "ARGUMENT", "MISSING", (void *)NULL);
- sortInfo.resultCode = TCL_ERROR;
- goto done;
+ "by comparison command", NULL);
+ return TCL_ERROR;
}
sortInfo.sortMode = SORTMODE_COMMAND;
cmdPtr = objv[i+1];
@@ -4593,52 +3543,54 @@ Tcl_LsortObjCmd(
sortInfo.isIncreasing = 1;
break;
case LSORT_INDEX: {
- Tcl_Size sortindex;
- Tcl_Obj **indexv;
+ Tcl_Obj **indices;
- if (i == objc-2) {
- Tcl_SetObjResult(interp, Tcl_NewStringObj(
- "\"-index\" option must be followed by list index",
- -1));
- Tcl_SetErrorCode(interp, "TCL", "ARGUMENT", "MISSING", (void *)NULL);
- sortInfo.resultCode = TCL_ERROR;
- goto done;
+ if (sortInfo.indexc > 1) {
+ ckfree((char *) sortInfo.indexv);
}
- if (TclListObjGetElements(interp, objv[i+1], &sortindex,
- &indexv) != TCL_OK) {
- sortInfo.resultCode = TCL_ERROR;
- goto done;
+ if (i == (objc-2)) {
+ Tcl_AppendResult(interp, "\"-index\" option must be "
+ "followed by list index", NULL);
+ return TCL_ERROR;
}
/*
- * Check each of the indices for syntactic correctness. Note that
- * we do not store the converted values here because we do not
- * know if this is the only -index option yet and so we can't
- * allocate any space; that happens after the scan through all the
- * options is done.
+ * Take copy to prevent shimmering problems.
*/
- for (j=0 ; j<sortindex ; j++) {
- int encoded = 0;
- int result = TclIndexEncode(interp, indexv[j],
- TCL_INDEX_NONE, TCL_INDEX_NONE, &encoded);
-
- if ((result == TCL_OK) && (encoded == (int)TCL_INDEX_NONE)) {
- Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "index \"%s\" out of range",
- TclGetString(indexv[j])));
- Tcl_SetErrorCode(interp, "TCL", "VALUE", "INDEX"
- "OUTOFRANGE", (void *)NULL);
- result = TCL_ERROR;
- }
- if (result == TCL_ERROR) {
+ if (TclListObjGetElements(interp, objv[i+1], &sortInfo.indexc,
+ &indices) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ switch (sortInfo.indexc) {
+ case 0:
+ sortInfo.indexv = NULL;
+ break;
+ case 1:
+ sortInfo.indexv = &sortInfo.singleIndex;
+ break;
+ default:
+ sortInfo.indexv = (int *)
+ ckalloc(sizeof(int) * sortInfo.indexc);
+ }
+
+ /*
+ * Fill the array by parsing each index. We don't know whether
+ * their scale is sensible yet, but we at least perform the
+ * syntactic check here.
+ */
+
+ for (j=0 ; j<sortInfo.indexc ; j++) {
+ if (TclGetIntForIndexM(interp, indices[j], SORTIDX_END,
+ &sortInfo.indexv[j]) != TCL_OK) {
+ if (sortInfo.indexc > 1) {
+ ckfree((char *) sortInfo.indexv);
+ }
Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
"\n (-index option item number %d)", j));
- sortInfo.resultCode = TCL_ERROR;
- goto done;
+ return TCL_ERROR;
}
}
- indexPtr = objv[i+1];
i++;
break;
}
@@ -4657,67 +3609,12 @@ Tcl_LsortObjCmd(
case LSORT_INDICES:
indices = 1;
break;
- case LSORT_STRIDE:
- if (i == objc-2) {
- Tcl_SetObjResult(interp, Tcl_NewStringObj(
- "\"-stride\" option must be "
- "followed by stride length", -1));
- Tcl_SetErrorCode(interp, "TCL", "ARGUMENT", "MISSING", (void *)NULL);
- sortInfo.resultCode = TCL_ERROR;
- goto done;
- }
- if (Tcl_GetWideIntFromObj(interp, objv[i+1], &wide) != TCL_OK) {
- sortInfo.resultCode = TCL_ERROR;
- goto done;
- }
- if ((wide < 2) || (wide > LIST_MAX)) {
- Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "stride length must be between 2 and %d", LIST_MAX));
- Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LSORT",
- "BADSTRIDE", (void *)NULL);
- sortInfo.resultCode = TCL_ERROR;
- goto done;
- }
- groupSize = wide;
- group = 1;
- i++;
- break;
}
}
if (nocase && (sortInfo.sortMode == SORTMODE_ASCII)) {
sortInfo.sortMode = SORTMODE_ASCII_NC;
}
- /*
- * Now extract the -index list for real, if present. No failures are
- * expected here; the values are all of the right type or convertible to
- * it.
- */
-
- if (indexPtr) {
- Tcl_Obj **indexv;
-
- TclListObjGetElements(interp, indexPtr, &sortInfo.indexc, &indexv);
- switch (sortInfo.indexc) {
- case 0:
- sortInfo.indexv = NULL;
- break;
- case 1:
- sortInfo.indexv = &sortInfo.singleIndex;
- break;
- default:
- sortInfo.indexv = (int *)
- TclStackAlloc(interp, sizeof(int) * sortInfo.indexc);
- allocatedIndexVector = 1; /* Cannot use indexc field, as it
- * might be decreased by 1 later. */
- }
- for (j=0 ; j<sortInfo.indexc ; j++) {
- /* Prescreened values, no errors or out of range possible */
- TclIndexEncode(NULL, indexv[j], TCL_INDEX_NONE,
- TCL_INDEX_NONE, &sortInfo.indexv[j]);
- }
- }
-
listObj = objv[objc-1];
if (sortInfo.sortMode == SORTMODE_COMMAND) {
@@ -4732,8 +3629,10 @@ Tcl_LsortObjCmd(
listObj = TclListObjCopy(interp, listObj);
if (listObj == NULL) {
- sortInfo.resultCode = TCL_ERROR;
- goto done;
+ if (sortInfo.indexc > 1) {
+ ckfree((char *) sortInfo.indexv);
+ }
+ return TCL_ERROR;
}
/*
@@ -4750,80 +3649,22 @@ Tcl_LsortObjCmd(
TclDecrRefCount(listObj);
Tcl_IncrRefCount(newObjPtr);
TclDecrRefCount(newObjPtr);
- sortInfo.resultCode = TCL_ERROR;
- goto done;
+ if (sortInfo.indexc > 1) {
+ ckfree((char *) sortInfo.indexv);
+ }
+ return TCL_ERROR;
}
- TclNewObj(newObjPtr);
- Tcl_ListObjAppendElement(interp, newCommandPtr, newObjPtr);
+ Tcl_ListObjAppendElement(interp, newCommandPtr, Tcl_NewObj());
sortInfo.compareCmdPtr = newCommandPtr;
}
- if (TclHasInternalRep(listObj,&tclArithSeriesType)) {
- sortInfo.resultCode = TclArithSeriesGetElements(interp,
- listObj, &length, &listObjPtrs);
- } else {
- sortInfo.resultCode = TclListObjGetElements(interp, listObj,
+ sortInfo.resultCode = TclListObjGetElements(interp, listObj,
&length, &listObjPtrs);
- }
if (sortInfo.resultCode != TCL_OK || length <= 0) {
goto done;
}
-
- /*
- * Check for sanity when grouping elements of the overall list together
- * because of the -stride option. [TIP #326]
- */
-
- if (group) {
- if (length % groupSize) {
- Tcl_SetObjResult(interp, Tcl_NewStringObj(
- "list size must be a multiple of the stride length",
- -1));
- Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LSORT", "BADSTRIDE",
- (void *)NULL);
- sortInfo.resultCode = TCL_ERROR;
- goto done;
- }
- length = length / groupSize;
- if (sortInfo.indexc > 0) {
- /*
- * Use the first value in the list supplied to -index as the
- * offset of the element within each group by which to sort.
- */
-
- groupOffset = TclIndexDecode(sortInfo.indexv[0], groupSize - 1);
- if (groupOffset < 0 || groupOffset >= groupSize) {
- Tcl_SetObjResult(interp, Tcl_NewStringObj(
- "when used with \"-stride\", the leading \"-index\""
- " value must be within the group", -1));
- Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LSORT",
- "BADINDEX", (void *)NULL);
- sortInfo.resultCode = TCL_ERROR;
- goto done;
- }
- if (sortInfo.indexc == 1) {
- sortInfo.indexc = 0;
- sortInfo.indexv = NULL;
- } else {
- sortInfo.indexc--;
-
- /*
- * Do not shrink the actual memory block used; that doesn't
- * work with TclStackAlloc-allocated memory. [Bug 2918962]
- *
- * TODO: Consider a pointer increment to replace this
- * array shift.
- */
-
- for (i = 0; i < sortInfo.indexc; i++) {
- sortInfo.indexv[i] = sortInfo.indexv[i+1];
- }
- }
- }
- }
-
sortInfo.numElements = length;
-
+
indexc = sortInfo.indexc;
sortMode = sortInfo.sortMode;
if ((sortMode == SORTMODE_ASCII_NC)
@@ -4831,7 +3672,7 @@ Tcl_LsortObjCmd(
/*
* For this function's purpose all string-based modes are equivalent
*/
-
+
sortMode = SORTMODE_ASCII;
}
@@ -4840,7 +3681,7 @@ Tcl_LsortObjCmd(
* contain a sorted sublist of length 2**i. Use one extra subList at the
* end, always at NULL, to indicate the end of the lists.
*/
-
+
for (j=0 ; j<=NUM_LISTS ; j++) {
subList[j] = NULL;
}
@@ -4850,77 +3691,57 @@ Tcl_LsortObjCmd(
* begins sorting it into the sublists as it appears.
*/
- elmArrSize = length * sizeof(SortElement);
- if (elmArrSize <= MAXCALLOC) {
- elementArray = (SortElement *)ckalloc(elmArrSize);
- } else {
- elementArray = (SortElement *)malloc(elmArrSize);
- }
- if (!elementArray) {
- Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "no enough memory to proccess sort of %d items", length));
- Tcl_SetErrorCode(interp, "TCL", "MEMORY", (void *)NULL);
- sortInfo.resultCode = TCL_ERROR;
- goto done;
- }
+ elementArray = (SortElement *) ckalloc( length * sizeof(SortElement));
- for (i=0; i < length; i++) {
- idx = groupSize * i + groupOffset;
+ for (i=0; i < length; i++){
if (indexc) {
/*
* If this is an indexed sort, retrieve the corresponding element
*/
- indexPtr = SelectObjFromSublist(listObjPtrs[idx], &sortInfo);
+ indexPtr = SelectObjFromSublist(listObjPtrs[i], &sortInfo);
if (sortInfo.resultCode != TCL_OK) {
- goto done;
+ goto done1;
}
} else {
- indexPtr = listObjPtrs[idx];
+ indexPtr = listObjPtrs[i];
}
/*
* Determine the "value" of this object for sorting purposes
*/
-
+
if (sortMode == SORTMODE_ASCII) {
- elementArray[i].collationKey.strValuePtr = TclGetString(indexPtr);
+ elementArray[i].index.strValuePtr = TclGetString(indexPtr);
} else if (sortMode == SORTMODE_INTEGER) {
- Tcl_WideInt a;
-
- if (TclGetWideIntFromObj(sortInfo.interp, indexPtr, &a) != TCL_OK) {
+ long a;
+ if (TclGetLongFromObj(sortInfo.interp, indexPtr, &a) != TCL_OK) {
sortInfo.resultCode = TCL_ERROR;
- goto done;
+ goto done1;
}
- elementArray[i].collationKey.wideValue = a;
+ elementArray[i].index.intValue = a;
} else if (sortMode == SORTMODE_REAL) {
double a;
-
- if (Tcl_GetDoubleFromObj(sortInfo.interp, indexPtr,
- &a) != TCL_OK) {
+ if (Tcl_GetDoubleFromObj(sortInfo.interp, indexPtr, &a) != TCL_OK) {
sortInfo.resultCode = TCL_ERROR;
- goto done;
+ goto done1;
}
- elementArray[i].collationKey.doubleValue = a;
+ elementArray[i].index.doubleValue = a;
} else {
- elementArray[i].collationKey.objValuePtr = indexPtr;
+ elementArray[i].index.objValuePtr = indexPtr;
}
/*
* Determine the representation of this element in the result: either
* the objPtr itself, or its index in the original list.
*/
-
- if (indices || group) {
- elementArray[i].payload.index = idx;
- } else {
- elementArray[i].payload.objPtr = listObjPtrs[idx];
- }
+
+ elementArray[i].objPtr = (indices ? INT2PTR(i) : listObjPtrs[i]);
/*
- * Merge this element in the preexisting sublists (and merge together
+ * Merge this element in the pre-existing sublists (and merge together
* sublists when we have two of the same size).
*/
-
+
elementArray[i].nextPtr = NULL;
elementPtr = &elementArray[i];
for (j=0 ; subList[j] ; j++) {
@@ -4936,74 +3757,53 @@ Tcl_LsortObjCmd(
/*
* Merge all sublists
*/
-
+
elementPtr = subList[0];
for (j=1 ; j<NUM_LISTS ; j++) {
elementPtr = MergeLists(subList[j], elementPtr, &sortInfo);
}
+
/*
* Now store the sorted elements in the result list.
*/
-
+
if (sortInfo.resultCode == TCL_OK) {
- ListRep listRep;
+ List *listRepPtr;
Tcl_Obj **newArray, *objPtr;
-
- resultPtr = Tcl_NewListObj(sortInfo.numElements * groupSize, NULL);
- ListObjGetRep(resultPtr, &listRep);
- newArray = ListRepElementsBase(&listRep);
- if (group) {
- for (i=0; elementPtr!=NULL ; elementPtr=elementPtr->nextPtr) {
- idx = elementPtr->payload.index;
- for (j = 0; j < groupSize; j++) {
- if (indices) {
- TclNewIndexObj(objPtr, idx + j - groupOffset);
- newArray[i++] = objPtr;
- Tcl_IncrRefCount(objPtr);
- } else {
- objPtr = listObjPtrs[idx + j - groupOffset];
- newArray[i++] = objPtr;
- Tcl_IncrRefCount(objPtr);
- }
- }
- }
- } else if (indices) {
- for (i=0; elementPtr != NULL ; elementPtr = elementPtr->nextPtr) {
- TclNewIndexObj(objPtr, elementPtr->payload.index);
+ int i;
+
+ resultPtr = Tcl_NewListObj(sortInfo.numElements, NULL);
+ listRepPtr = ListRepPtr(resultPtr);
+ newArray = &listRepPtr->elements;
+ if (indices) {
+ for (i = 0; elementPtr != NULL ; elementPtr = elementPtr->nextPtr){
+ objPtr = Tcl_NewIntObj(PTR2INT(elementPtr->objPtr));
newArray[i++] = objPtr;
Tcl_IncrRefCount(objPtr);
}
} else {
- for (i=0; elementPtr != NULL ; elementPtr = elementPtr->nextPtr) {
- objPtr = elementPtr->payload.objPtr;
+ for (i = 0; elementPtr != NULL ; elementPtr = elementPtr->nextPtr){
+ objPtr = elementPtr->objPtr;
newArray[i++] = objPtr;
Tcl_IncrRefCount(objPtr);
}
}
- listRep.storePtr->numUsed = i;
- if (listRep.spanPtr) {
- listRep.spanPtr->spanStart = listRep.storePtr->firstUsed;
- listRep.spanPtr->spanLength = listRep.storePtr->numUsed;
- }
+ listRepPtr->elemCount = i;
Tcl_SetObjResult(interp, resultPtr);
}
+ done1:
+ ckfree((char *)elementArray);
+
done:
if (sortMode == SORTMODE_COMMAND) {
TclDecrRefCount(sortInfo.compareCmdPtr);
TclDecrRefCount(listObj);
sortInfo.compareCmdPtr = NULL;
}
- if (allocatedIndexVector) {
- TclStackFree(interp, sortInfo.indexv);
- }
- if (elementArray) {
- if (elmArrSize <= MAXCALLOC) {
- ckfree((char *)elementArray);
- } else {
- free((char *)elementArray);
- }
+ if (sortInfo.indexc > 1) {
+ ckfree((char *) sortInfo.indexv);
}
return sortInfo.resultCode;
}
@@ -5011,123 +3811,6 @@ Tcl_LsortObjCmd(
/*
*----------------------------------------------------------------------
*
- * Tcl_LeditObjCmd --
- *
- * This procedure is invoked to process the "ledit" Tcl command. See the
- * user documentation for details on what it does.
- *
- * Results:
- * A standard Tcl result.
- *
- * Side effects:
- * See the user documentation.
- *
- *----------------------------------------------------------------------
- */
-
-int
-Tcl_LeditObjCmd(
- TCL_UNUSED(void *),
- Tcl_Interp *interp, /* Current interpreter. */
- int objc, /* Number of arguments. */
- Tcl_Obj *const objv[]) /* Argument values. */
-{
- Tcl_Obj *listPtr; /* Pointer to the list being altered. */
- Tcl_Obj *finalValuePtr; /* Value finally assigned to the variable. */
- int createdNewObj;
- int result;
- Tcl_Size first;
- Tcl_Size last;
- Tcl_Size listLen;
- Tcl_Size numToDelete;
-
- if (objc < 4) {
- Tcl_WrongNumArgs(interp, 1, objv,
- "listVar first last ?element ...?");
- return TCL_ERROR;
- }
-
- listPtr = Tcl_ObjGetVar2(interp, objv[1], NULL, TCL_LEAVE_ERR_MSG);
- if (listPtr == NULL) {
- return TCL_ERROR;
- }
-
- /*
- * TODO - refactor the index extraction into a common function shared
- * by Tcl_{Lrange,Lreplace,Ledit}ObjCmd
- */
-
- result = TclListObjLength(interp, listPtr, &listLen);
- if (result != TCL_OK) {
- return result;
- }
-
- result = TclGetIntForIndexM(interp, objv[2], /*end*/ listLen-1, &first);
- if (result != TCL_OK) {
- return result;
- }
-
- result = TclGetIntForIndexM(interp, objv[3], /*end*/ listLen-1, &last);
- if (result != TCL_OK) {
- return result;
- }
-
- if (first == TCL_INDEX_NONE) {
- first = 0;
- } else if (first > listLen) {
- first = listLen;
- }
-
- if (last >= listLen) {
- last = listLen - 1;
- }
- if (first <= last) {
- numToDelete = (unsigned)last - (unsigned)first + 1; /* See [3d3124d01d] */
- } else {
- numToDelete = 0;
- }
-
- if (Tcl_IsShared(listPtr)) {
- listPtr = TclListObjCopy(NULL, listPtr);
- createdNewObj = 1;
- } else {
- createdNewObj = 0;
- }
-
- result =
- Tcl_ListObjReplace(interp, listPtr, first, numToDelete, objc - 4, objv + 4);
- if (result != TCL_OK) {
- if (createdNewObj) {
- Tcl_DecrRefCount(listPtr);
- }
- return result;
- }
-
- /*
- * Tcl_ObjSetVar2 mau return a value different from listPtr in the
- * presence of traces etc.. Note that finalValuePtr will always have a
- * reference count of at least 1 corresponding to the reference from the
- * var. If it is same as listPtr, then ref count will be at least 2
- * since we are incr'ing the latter below (safer when calling
- * Tcl_ObjSetVar2 which can release it in some cases). Note that we
- * leave the incrref of listPtr this late because we want to pass it as
- * unshared to Tcl_ListObjReplace above if possible.
- */
- Tcl_IncrRefCount(listPtr);
- finalValuePtr =
- Tcl_ObjSetVar2(interp, objv[1], NULL, listPtr, TCL_LEAVE_ERR_MSG);
- Tcl_DecrRefCount(listPtr); /* safe irrespective of createdNewObj */
- if (finalValuePtr == NULL) {
- return TCL_ERROR;
- }
-
- Tcl_SetObjResult(interp, finalValuePtr);
- return TCL_OK;
-}
-
-/*
- *----------------------------------------------------------------------
- *
* MergeLists -
*
* This procedure combines two sorted lists of SortElement structures
@@ -5137,23 +3820,21 @@ Tcl_LeditObjCmd(
* The unified list of SortElement structures.
*
* Side effects:
- * If infoPtr->unique is set then infoPtr->numElements may be updated.
+ * If infoPtr->unique is set then infoPtr->numElements may be updated.
* Possibly others, if a user-defined comparison command does something
- * weird.
+ * weird.
*
* Note:
- * If infoPtr->unique is set, the merge assumes that there are no
+ * If infoPtr->unique is set, the merge assumes that there are no
* "repeated" elements in each of the left and right lists. In that case,
* if any element of the left list is equivalent to one in the right list
* it is omitted from the merged list.
- *
- * This simplified mechanism works because of the special way our
- * MergeSort creates the sublists to be merged and will fail to eliminate
- * all repeats in the general case where they are already present in
- * either the left or right list. A general code would need to skip
- * adjacent initial repeats in the left and right lists before comparing
- * their initial elements, at each step.
- *
+ * This simplified mechanism works because of the special way
+ * our MergeSort creates the sublists to be merged and will fail to
+ * eliminate all repeats in the general case where they are already
+ * present in either the left or right list. A general code would need to
+ * skip adjacent initial repeats in the left and right lists before
+ * comparing their initial elements, at each step.
*----------------------------------------------------------------------
*/
@@ -5234,7 +3915,7 @@ MergeLists(
* ordering between two elements.
*
* Results:
- * A negative results means the first element comes before the
+ * A negative results means the the first element comes before the
* second, and a positive results means that the second element should
* come first. A result of zero means the two elements are equal and it
* doesn't matter which comes first.
@@ -5255,29 +3936,29 @@ SortCompare(
int order = 0;
if (infoPtr->sortMode == SORTMODE_ASCII) {
- order = TclUtfCmp(elemPtr1->collationKey.strValuePtr,
- elemPtr2->collationKey.strValuePtr);
+ order = strcmp(elemPtr1->index.strValuePtr,
+ elemPtr2->index.strValuePtr);
} else if (infoPtr->sortMode == SORTMODE_ASCII_NC) {
- order = TclUtfCasecmp(elemPtr1->collationKey.strValuePtr,
- elemPtr2->collationKey.strValuePtr);
+ order = TclUtfCasecmp(elemPtr1->index.strValuePtr,
+ elemPtr2->index.strValuePtr);
} else if (infoPtr->sortMode == SORTMODE_DICTIONARY) {
- order = DictionaryCompare(elemPtr1->collationKey.strValuePtr,
- elemPtr2->collationKey.strValuePtr);
+ order = DictionaryCompare(elemPtr1->index.strValuePtr,
+ elemPtr2->index.strValuePtr);
} else if (infoPtr->sortMode == SORTMODE_INTEGER) {
- Tcl_WideInt a, b;
+ long a, b;
- a = elemPtr1->collationKey.wideValue;
- b = elemPtr2->collationKey.wideValue;
+ a = elemPtr1->index.intValue;
+ b = elemPtr2->index.intValue;
order = ((a >= b) - (a <= b));
} else if (infoPtr->sortMode == SORTMODE_REAL) {
double a, b;
- a = elemPtr1->collationKey.doubleValue;
- b = elemPtr2->collationKey.doubleValue;
+ a = elemPtr1->index.doubleValue;
+ b = elemPtr2->index.doubleValue;
order = ((a >= b) - (a <= b));
} else {
Tcl_Obj **objv, *paramObjv[2];
- Tcl_Size objc;
+ int objc;
Tcl_Obj *objPtr1, *objPtr2;
if (infoPtr->resultCode != TCL_OK) {
@@ -5285,14 +3966,14 @@ SortCompare(
* Once an error has occurred, skip any future comparisons so as
* to preserve the error message in sortInterp->result.
*/
-
+
return 0;
}
- objPtr1 = elemPtr1->collationKey.objValuePtr;
- objPtr2 = elemPtr2->collationKey.objValuePtr;
-
+ objPtr1 = elemPtr1->index.objValuePtr;
+ objPtr2 = elemPtr2->index.objValuePtr;
+
paramObjv[0] = objPtr1;
paramObjv[1] = objPtr2;
@@ -5310,7 +3991,8 @@ SortCompare(
infoPtr->resultCode = Tcl_EvalObjv(infoPtr->interp, objc, objv, 0);
if (infoPtr->resultCode != TCL_OK) {
- Tcl_AddErrorInfo(infoPtr->interp, "\n (-compare command)");
+ Tcl_AddErrorInfo(infoPtr->interp,
+ "\n (-compare command)");
return 0;
}
@@ -5320,10 +4002,9 @@ SortCompare(
if (TclGetIntFromObj(infoPtr->interp,
Tcl_GetObjResult(infoPtr->interp), &order) != TCL_OK) {
- Tcl_SetObjResult(infoPtr->interp, Tcl_NewStringObj(
- "-compare command returned non-integer result", -1));
- Tcl_SetErrorCode(infoPtr->interp, "TCL", "OPERATION", "LSORT",
- "COMPARISONFAILED", (void *)NULL);
+ Tcl_ResetResult(infoPtr->interp);
+ Tcl_AppendResult(infoPtr->interp,
+ "-compare command returned non-integer result", NULL);
infoPtr->resultCode = TCL_ERROR;
return 0;
}
@@ -5360,9 +4041,9 @@ SortCompare(
static int
DictionaryCompare(
- const char *left, const char *right) /* The strings to compare. */
+ char *left, char *right) /* The strings to compare. */
{
- int uniLeft = 0, uniRight = 0, uniLeftLower, uniRightLower;
+ Tcl_UniChar uniLeft, uniRight, uniLeftLower, uniRightLower;
int diff, zeros;
int secondaryDiff = 0;
@@ -5377,11 +4058,11 @@ DictionaryCompare(
*/
zeros = 0;
- while ((*right == '0') && isdigit(UCHAR(right[1]))) {
+ while ((*right == '0') && (isdigit(UCHAR(right[1])))) {
right++;
zeros--;
}
- while ((*left == '0') && isdigit(UCHAR(left[1]))) {
+ while ((*left == '0') && (isdigit(UCHAR(left[1])))) {
left++;
zeros++;
}
@@ -5431,12 +4112,12 @@ DictionaryCompare(
*/
if ((*left != '\0') && (*right != '\0')) {
- left += TclUtfToUniChar(left, &uniLeft);
- right += TclUtfToUniChar(right, &uniRight);
+ left += Tcl_UtfToUniChar(left, &uniLeft);
+ right += Tcl_UtfToUniChar(right, &uniRight);
/*
* Convert both chars to lower for the comparison, because
- * dictionary sorts are case-insensitive. Covert to lower, not
+ * dictionary sorts are case insensitve. Covert to lower, not
* upper, so chars between Z and a will sort before A (where most
* other interesting punctuations occur).
*/
@@ -5495,7 +4176,7 @@ SelectObjFromSublist(
SortInfo *infoPtr) /* Information passed from the top-level
* "lsearch" or "lsort" command. */
{
- Tcl_Size i;
+ int i;
/*
* Quick check for case when no "-index" option is there.
@@ -5511,16 +4192,22 @@ SelectObjFromSublist(
*/
for (i=0 ; i<infoPtr->indexc ; i++) {
- Tcl_Size listLen;
- int index;
+ int listLen, index;
Tcl_Obj *currentObj;
if (TclListObjLength(infoPtr->interp, objPtr, &listLen) != TCL_OK) {
infoPtr->resultCode = TCL_ERROR;
return NULL;
}
+ index = infoPtr->indexv[i];
- index = TclIndexDecode(infoPtr->indexv[i], listLen - 1);
+ /*
+ * Adjust for end-based indexing.
+ */
+
+ if (index < SORTIDX_NONE) {
+ index += listLen + 1;
+ }
if (Tcl_ListObjIndex(infoPtr->interp, objPtr, index,
&currentObj) != TCL_OK) {
@@ -5528,18 +4215,12 @@ SelectObjFromSublist(
return NULL;
}
if (currentObj == NULL) {
- if (index == TCL_INDEX_NONE) {
- index = TCL_INDEX_END - infoPtr->indexv[i];
- Tcl_SetObjResult(infoPtr->interp, Tcl_ObjPrintf(
- "element end-%d missing from sublist \"%s\"",
- index, TclGetString(objPtr)));
- } else {
- Tcl_SetObjResult(infoPtr->interp, Tcl_ObjPrintf(
- "element %d missing from sublist \"%s\"",
- index, TclGetString(objPtr)));
- }
- Tcl_SetErrorCode(infoPtr->interp, "TCL", "OPERATION", "LSORT",
- "INDEXFAILED", (void *)NULL);
+ char buffer[TCL_INTEGER_SPACE];
+
+ TclFormatInt(buffer, index);
+ Tcl_AppendResult(infoPtr->interp, "element ", buffer,
+ " missing from sublist \"", TclGetString(objPtr), "\"",
+ NULL);
infoPtr->resultCode = TCL_ERROR;
return NULL;
}
@@ -5553,6 +4234,5 @@ SelectObjFromSublist(
* mode: c
* c-basic-offset: 4
* fill-column: 78
- * tab-width: 8
* End:
*/