Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | Yet more booleans |
|---|---|
| Timelines: | family | ancestors | descendants | both | c-std-update |
| Files: | files | file ages | folders |
| SHA3-256: |
98c372af5425ad2ecea485ae2dae3a7f |
| User & Date: | dkf 2025-08-12 14:14:15.176 |
Context
|
2025-08-17
| ||
| 11:25 | More bools and pieces check-in: 28a7d957c7 user: dkf tags: c-std-update | |
|
2025-08-12
| ||
| 14:14 | Yet more booleans check-in: 98c372af54 user: dkf tags: c-std-update | |
| 10:16 | merge trunk check-in: 1ea33fb12b user: dkf tags: c-std-update | |
Changes
Changes to generic/tclAssembly.c.
| ︙ | ︙ | |||
272 273 274 275 276 277 278 | Tcl_Size objc, Tcl_Obj** objv); static int CreateMirrorNumJumpTable(AssemblyEnv* assemEnvPtr, Tcl_Size objc, Tcl_Obj** objv); static size_t FindLocalVar(AssemblyEnv* envPtr, Tcl_Token** tokenPtrPtr); static int FinishAssembly(AssemblyEnv*); static void FreeAssemblyEnv(AssemblyEnv*); | | | 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 | Tcl_Size objc, Tcl_Obj** objv); static int CreateMirrorNumJumpTable(AssemblyEnv* assemEnvPtr, Tcl_Size objc, Tcl_Obj** objv); static size_t FindLocalVar(AssemblyEnv* envPtr, Tcl_Token** tokenPtrPtr); static int FinishAssembly(AssemblyEnv*); static void FreeAssemblyEnv(AssemblyEnv*); static int GetBooleanOperand(AssemblyEnv*, Tcl_Token**, bool*); static int GetListIndexOperand(AssemblyEnv*, Tcl_Token**, int*); static int GetIntegerOperand(AssemblyEnv*, Tcl_Token**, int*); static int GetNextOperand(AssemblyEnv*, Tcl_Token**, Tcl_Obj**); static void LookForFreshCatches(BasicBlock*, BasicBlock**); static void MoveExceptionRangesToBasicBlock(AssemblyEnv*, Tcl_Size); static AssemblyEnv* NewAssemblyEnv(CompileEnv*, int); static int ProcessCatches(AssemblyEnv*); |
| ︙ | ︙ | |||
1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 |
* instruction */
TalInstType instType; /* Type of the instruction */
Tcl_Obj* operand1Obj = NULL;
/* First operand to the instruction */
const char* operand1; /* String rep of the operand */
Tcl_Size operand1Len; /* String length of the operand */
int opnd; /* Integer representation of an operand */
int litIndex; /* Literal pool index of a constant */
Tcl_Size localVar; /* LVT index of a local variable */
int flags; /* Flags for a basic block */
Tcl_Size infoIndex; /* Index of the jumptable in auxdata */
int status = TCL_ERROR; /* Return value from this function */
/*
| > | 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 |
* instruction */
TalInstType instType; /* Type of the instruction */
Tcl_Obj* operand1Obj = NULL;
/* First operand to the instruction */
const char* operand1; /* String rep of the operand */
Tcl_Size operand1Len; /* String length of the operand */
int opnd; /* Integer representation of an operand */
bool bopnd; /* Boolean representation of an operand */
int litIndex; /* Literal pool index of a constant */
Tcl_Size localVar; /* LVT index of a local variable */
int flags; /* Flags for a basic block */
Tcl_Size infoIndex; /* Index of the jumptable in auxdata */
int status = TCL_ERROR; /* Return value from this function */
/*
|
| ︙ | ︙ | |||
1317 1318 1319 1320 1321 1322 1323 |
break;
case ASSEM_BOOL:
if (parsePtr->numWords != 2) {
Tcl_WrongNumArgs(interp, 1, &instNameObj, "boolean");
goto cleanup;
}
| | | | | | 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 |
break;
case ASSEM_BOOL:
if (parsePtr->numWords != 2) {
Tcl_WrongNumArgs(interp, 1, &instNameObj, "boolean");
goto cleanup;
}
if (GetBooleanOperand(assemEnvPtr, &tokenPtr, &bopnd) != TCL_OK) {
goto cleanup;
}
BBEmitInstInt1(assemEnvPtr, tblIdx, bopnd ? 1 : 0, 0);
break;
case ASSEM_BOOL_LVT:
if (parsePtr->numWords != 3) {
Tcl_WrongNumArgs(interp, 1, &instNameObj, "boolean varName");
goto cleanup;
}
if (GetBooleanOperand(assemEnvPtr, &tokenPtr, &bopnd) != TCL_OK) {
goto cleanup;
}
localVar = FindLocalVar(assemEnvPtr, &tokenPtr);
if (localVar < 0) {
goto cleanup;
}
BBEmitInstInt1(assemEnvPtr, tblIdx, opnd ? 1 : 0, 0);
TclEmitInt4(localVar, envPtr);
break;
case ASSEM_CLOCK_READ:
if (parsePtr->numWords != 2) {
Tcl_WrongNumArgs(interp, 1, &instNameObj, "imm8");
goto cleanup;
|
| ︙ | ︙ | |||
1666 1667 1668 1669 1670 1671 1672 |
break;
case ASSEM_REGEXP:
if (parsePtr->numWords != 2) {
Tcl_WrongNumArgs(interp, 1, &instNameObj, "boolean");
goto cleanup;
}
| | | | 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 |
break;
case ASSEM_REGEXP:
if (parsePtr->numWords != 2) {
Tcl_WrongNumArgs(interp, 1, &instNameObj, "boolean");
goto cleanup;
}
if (GetBooleanOperand(assemEnvPtr, &tokenPtr, &bopnd) != TCL_OK) {
goto cleanup;
}
BBEmitInstInt1(assemEnvPtr, tblIdx,
TCL_REG_ADVANCED | (bopnd ? TCL_REG_NOCASE : 0), 0);
break;
case ASSEM_REVERSE:
if (parsePtr->numWords != 2) {
Tcl_WrongNumArgs(interp, 1, &instNameObj, "count");
goto cleanup;
}
|
| ︙ | ︙ | |||
2184 2185 2186 2187 2188 2189 2190 |
*-----------------------------------------------------------------------------
*/
static int
GetBooleanOperand(
AssemblyEnv* assemEnvPtr, /* Assembly environment */
Tcl_Token** tokenPtrPtr, /* Current token from the parser */
| | | 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 |
*-----------------------------------------------------------------------------
*/
static int
GetBooleanOperand(
AssemblyEnv* assemEnvPtr, /* Assembly environment */
Tcl_Token** tokenPtrPtr, /* Current token from the parser */
bool* result) /* OUTPUT: Boolean extracted from the token */
{
CompileEnv* envPtr = assemEnvPtr->envPtr;
/* Compilation environment */
Tcl_Interp* interp = (Tcl_Interp*) envPtr->iPtr;
/* Tcl interpreter */
Tcl_Token* tokenPtr = *tokenPtrPtr;
/* INOUT: Pointer to the next token in the
|
| ︙ | ︙ |
Changes to generic/tclCmdMZ.c.
| ︙ | ︙ | |||
41 42 43 44 45 46 47 | static Tcl_NRPostProc SwitchPostProc; static Tcl_NRPostProc TryPostBody; static Tcl_NRPostProc TryPostFinal; static Tcl_NRPostProc TryPostHandler; static int UniCharIsAscii(int character); static int UniCharIsHexDigit(int character); static int StringCmpOpts(Tcl_Interp *interp, int objc, | | | 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | static Tcl_NRPostProc SwitchPostProc; static Tcl_NRPostProc TryPostBody; static Tcl_NRPostProc TryPostFinal; static Tcl_NRPostProc TryPostHandler; static int UniCharIsAscii(int character); static int UniCharIsHexDigit(int character); static int StringCmpOpts(Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], bool *nocase, Tcl_Size *reqlength); /* * Default set of characters to trim in [string trim] and friends. This is a * UTF-8 literal string containing all Unicode space characters [TIP #413] */ |
| ︙ | ︙ | |||
141 142 143 144 145 146 147 |
int
Tcl_RegexpObjCmd(
TCL_UNUSED(void *),
Tcl_Interp *interp, /* Current interpreter. */
int objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
{
| | < | < | < | 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 |
int
Tcl_RegexpObjCmd(
TCL_UNUSED(void *),
Tcl_Interp *interp, /* Current interpreter. */
int objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
{
Tcl_Size offset, stringLength, matchLength, i;
int numMatchesSaved, cflags, eflags;
Tcl_RegExp regExpr;
Tcl_Obj *objPtr, *startIndex = NULL, *resultPtr = NULL;
Tcl_RegExpInfo info;
static const char *const options[] = {
"-all", "-about", "-indices", "-inline",
"-expanded", "-line", "-linestop", "-lineanchor",
"-nocase", "-start", "--", NULL
};
enum regexpoptions {
REGEXP_ALL, REGEXP_ABOUT, REGEXP_INDICES, REGEXP_INLINE,
REGEXP_EXPANDED,REGEXP_LINE, REGEXP_LINESTOP,REGEXP_LINEANCHOR,
REGEXP_NOCASE, REGEXP_START, REGEXP_LAST
} index;
bool about = false, doinline = false, indices = false;
cflags = TCL_REG_ADVANCED;
offset = TCL_INDEX_START;
int all = 0;
for (i = 1; i < objc; i++) {
const char *name;
name = TclGetString(objv[i]);
if (name[0] != '-') {
break;
|
| ︙ | ︙ | |||
520 521 522 523 524 525 526 |
enum regsubobjoptions {
REGSUB_ALL, REGSUB_COMMAND, REGSUB_EXPANDED, REGSUB_LINE,
REGSUB_LINESTOP, REGSUB_LINEANCHOR, REGSUB_NOCASE, REGSUB_START,
REGSUB_LAST
} index;
int cflags = TCL_REG_ADVANCED;
| | < | 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 |
enum regsubobjoptions {
REGSUB_ALL, REGSUB_COMMAND, REGSUB_EXPANDED, REGSUB_LINE,
REGSUB_LINESTOP, REGSUB_LINEANCHOR, REGSUB_NOCASE, REGSUB_START,
REGSUB_LAST
} index;
int cflags = TCL_REG_ADVANCED;
bool all = false, command = false;
Tcl_Size offset = TCL_INDEX_START;
Tcl_Obj *resultPtr = NULL;
for (idx = 1; idx < objc; idx++) {
const char *name = TclGetString(objv[idx]);
if (name[0] != '-') {
break;
}
|
| ︙ | ︙ | |||
2641 2642 2643 2644 2645 2646 2647 |
{
/*
* Remember to keep code here in some sync with the byte-compiled versions
* in tclExecute.c (INST_STR_EQ, INST_STR_NEQ and INST_STR_CMP as well as
* the expr string comparison in INST_EQ/INST_NEQ/INST_LT/...).
*/
| < | | < < < < < < < | < < < < < < < < < | | | < < | < < < < < < < < < < < < < < | | | 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 |
{
/*
* Remember to keep code here in some sync with the byte-compiled versions
* in tclExecute.c (INST_STR_EQ, INST_STR_NEQ and INST_STR_CMP as well as
* the expr string comparison in INST_EQ/INST_NEQ/INST_LT/...).
*/
bool nocase;
Tcl_Size reqlength = -1;
int status = StringCmpOpts(interp, objc, objv, &nocase, &reqlength);
if (status != TCL_OK) {
return status;
}
objv += objc-2;
int match = TclStringCmp(objv[0], objv[1], true, nocase, reqlength);
Tcl_SetObjResult(interp, Tcl_NewBooleanObj(!match));
return TCL_OK;
}
/*
*----------------------------------------------------------------------
*
* StringCmpCmd --
|
| ︙ | ︙ | |||
2719 2720 2721 2722 2723 2724 2725 |
{
/*
* Remember to keep code here in some sync with the byte-compiled versions
* in tclExecute.c (INST_STR_EQ, INST_STR_NEQ and INST_STR_CMP as well as
* the expr string comparison in INST_EQ/INST_NEQ/INST_LT/...).
*/
| | | | | | | < < < | | 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 |
{
/*
* Remember to keep code here in some sync with the byte-compiled versions
* in tclExecute.c (INST_STR_EQ, INST_STR_NEQ and INST_STR_CMP as well as
* the expr string comparison in INST_EQ/INST_NEQ/INST_LT/...).
*/
bool nocase;
Tcl_Size reqlength = -1;
int status = StringCmpOpts(interp, objc, objv, &nocase, &reqlength);
if (status != TCL_OK) {
return status;
}
objv += objc-2;
int match = TclStringCmp(objv[0], objv[1], false, nocase, reqlength);
Tcl_SetObjResult(interp, Tcl_NewWideIntObj(match));
return TCL_OK;
}
int
StringCmpOpts(
Tcl_Interp *interp, /* Current interpreter. */
int objc, /* Number of arguments. */
Tcl_Obj *const objv[], /* Argument objects. */
bool *nocase,
Tcl_Size *reqlength)
{
*nocase = false;
if (objc < 3 || objc > 6) {
goto str_cmp_args;
}
for (int i = 1; i < objc-2; i++) {
Tcl_Size length;
const char *string = TclGetStringFromObj(objv[i], &length);
if ((length > 1) && !strncmp(string, "-nocase", length)) {
*nocase = true;
} else if ((length > 1)
&& !strncmp(string, "-length", length)) {
if (i+1 >= objc-2) {
goto str_cmp_args;
}
i++;
Tcl_WideInt wreqlength = -1;
|
| ︙ | ︙ | |||
2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 2789 2790 2791 |
string, "-nocase or -length");
TclSetErrorCode(interp, "TCL", "LOOKUP", "INDEX", "option",
string);
return TCL_ERROR;
}
}
return TCL_OK;
}
/*
*----------------------------------------------------------------------
*
* StringCatCmd --
*
| > > > > > | 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 |
string, "-nocase or -length");
TclSetErrorCode(interp, "TCL", "LOOKUP", "INDEX", "option",
string);
return TCL_ERROR;
}
}
return TCL_OK;
str_cmp_args:
Tcl_WrongNumArgs(interp, 1, objv,
"?-nocase? ?-length int? string1 string2");
return TCL_ERROR;
}
/*
*----------------------------------------------------------------------
*
* StringCatCmd --
*
|
| ︙ | ︙ | |||
4993 4994 4995 4996 4997 4998 4999 |
&len2, &bits2) != TCL_OK) {
continue;
}
if (len2 < len1) {
continue;
}
for (Tcl_Size j=0 ; j<len1 ; j++) {
| | | 4958 4959 4960 4961 4962 4963 4964 4965 4966 4967 4968 4969 4970 4971 4972 |
&len2, &bits2) != TCL_OK) {
continue;
}
if (len2 < len1) {
continue;
}
for (Tcl_Size j=0 ; j<len1 ; j++) {
if (TclStringCmp(bits1[j], bits2[j], true, false,
TCL_INDEX_NONE) != 0) {
/*
* Really want 'continue outerloop;', but C does
* not give us that.
*/
goto didNotMatch;
|
| ︙ | ︙ |
Changes to generic/tclDictObj.c.
| ︙ | ︙ | |||
636 637 638 639 640 641 642 |
const char *nextElem = TclGetStringFromObj(objPtr, &length);
const char *limit = (nextElem + length);
while (nextElem < limit) {
Tcl_Obj *keyPtr, *valuePtr;
const char *elemStart;
Tcl_Size elemSize;
| | | 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 |
const char *nextElem = TclGetStringFromObj(objPtr, &length);
const char *limit = (nextElem + length);
while (nextElem < limit) {
Tcl_Obj *keyPtr, *valuePtr;
const char *elemStart;
Tcl_Size elemSize;
bool literal;
if (TclFindDictElement(interp, nextElem, (limit - nextElem),
&elemStart, &nextElem, &elemSize, &literal) != TCL_OK) {
goto errorInFindDictElement;
}
if (elemStart == limit) {
break;
|
| ︙ | ︙ | |||
3693 3694 3695 3696 3697 3698 3699 |
}
/*
* Pack from local variables back into the dictionary.
*/
varPtr = TclObjLookupVarEx(interp, varName, NULL, TCL_LEAVE_ERR_MSG, "set",
| | | 3693 3694 3695 3696 3697 3698 3699 3700 3701 3702 3703 3704 3705 3706 3707 |
}
/*
* Pack from local variables back into the dictionary.
*/
varPtr = TclObjLookupVarEx(interp, varName, NULL, TCL_LEAVE_ERR_MSG, "set",
/*createPart1*/ true, /*createPart2*/ true, &arrayPtr);
if (varPtr == NULL) {
result = TCL_ERROR;
} else {
result = TclDictWithFinish(interp, varPtr, arrayPtr, varName, NULL, -1,
pathc, pathv, keysPtr);
}
|
| ︙ | ︙ |
Changes to generic/tclEnv.c.
| ︙ | ︙ | |||
122 123 124 125 126 127 128 |
* Find out what elements are currently in the global env array.
*/
TclNewLiteralStringObj(varNamePtr, "env");
Tcl_IncrRefCount(varNamePtr);
Tcl_InitObjHashTable(&namesHash);
varPtr = TclObjLookupVarEx(interp, varNamePtr, NULL, TCL_GLOBAL_ONLY,
| > | | 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 |
* Find out what elements are currently in the global env array.
*/
TclNewLiteralStringObj(varNamePtr, "env");
Tcl_IncrRefCount(varNamePtr);
Tcl_InitObjHashTable(&namesHash);
varPtr = TclObjLookupVarEx(interp, varNamePtr, NULL, TCL_GLOBAL_ONLY,
/*msg*/ NULL, /*createPart1*/ false, /*createPart2*/ false,
&arrayPtr);
TclFindArrayPtrElements(varPtr, &namesHash);
#if defined(_WIN32)
if (tenviron == NULL) {
/*
* When we are started from main(), the _wenviron array could
* be NULL and will be initialized by the first _wgetenv() call.
|
| ︙ | ︙ |
Changes to generic/tclExecute.c.
| ︙ | ︙ | |||
3215 3216 3217 3218 3219 3220 3221 | objResultPtr = varPtr->value.objPtr; TRACE_APPEND_OBJ(objResultPtr); NEXT_INST_F(pcAdjustment, 1, 1); } } varPtr = TclLookupArrayElement(interp, part1Ptr, part2Ptr, | | | 3215 3216 3217 3218 3219 3220 3221 3222 3223 3224 3225 3226 3227 3228 3229 |
objResultPtr = varPtr->value.objPtr;
TRACE_APPEND_OBJ(objResultPtr);
NEXT_INST_F(pcAdjustment, 1, 1);
}
}
varPtr = TclLookupArrayElement(interp, part1Ptr, part2Ptr,
TCL_LEAVE_ERR_MSG, "read", false, true, arrayPtr, varIdx);
if (varPtr == NULL) {
TRACE_ERROR(interp);
goto gotError;
}
cleanup = 1;
goto doCallPtrGetVar;
|
| ︙ | ︙ | |||
3243 3244 3245 3246 3247 3248 3249 |
part2Ptr = NULL;
objPtr = OBJ_AT_TOS; /* variable name */
TRACE("\"%.30s\" => ", O2S(objPtr));
doLoadStk:
part1Ptr = objPtr;
varPtr = TclObjLookupVarEx(interp, part1Ptr, part2Ptr,
| | | | 3243 3244 3245 3246 3247 3248 3249 3250 3251 3252 3253 3254 3255 3256 3257 3258 |
part2Ptr = NULL;
objPtr = OBJ_AT_TOS; /* variable name */
TRACE("\"%.30s\" => ", O2S(objPtr));
doLoadStk:
part1Ptr = objPtr;
varPtr = TclObjLookupVarEx(interp, part1Ptr, part2Ptr,
TCL_LEAVE_ERR_MSG, "read", /*createPart1*/false,
/*createPart2*/true, &arrayPtr);
if (!varPtr) {
TRACE_ERROR(interp);
goto gotError;
}
if (TclIsVarDirectReadable2(varPtr, arrayPtr)) {
/*
|
| ︙ | ︙ | |||
3434 3435 3436 3437 3438 3439 3440 |
TRACE("\"%.30s\" <- \"%.30s\" =>", O2S(part1Ptr),O2S(valuePtr));
} else {
TRACE("\"%.30s(%.30s)\" <- \"%.30s\" => ",
O2S(part1Ptr), O2S(part2Ptr), O2S(valuePtr));
}
#endif
varPtr = TclObjLookupVarEx(interp, objPtr, part2Ptr, TCL_LEAVE_ERR_MSG,
| | | 3434 3435 3436 3437 3438 3439 3440 3441 3442 3443 3444 3445 3446 3447 3448 |
TRACE("\"%.30s\" <- \"%.30s\" =>", O2S(part1Ptr),O2S(valuePtr));
} else {
TRACE("\"%.30s(%.30s)\" <- \"%.30s\" => ",
O2S(part1Ptr), O2S(part2Ptr), O2S(valuePtr));
}
#endif
varPtr = TclObjLookupVarEx(interp, objPtr, part2Ptr, TCL_LEAVE_ERR_MSG,
"set", /*createPart1*/ true, /*createPart2*/ true, &arrayPtr);
if (!varPtr) {
TRACE_ERROR(interp);
goto gotError;
}
cleanup = ((part2Ptr == NULL)? 2 : 3);
pcAdjustment = 1;
varIdx = -1;
|
| ︙ | ︙ | |||
3490 3491 3492 3493 3494 3495 3496 |
arrayPtr = arrayPtr->value.linkPtr;
}
cleanup = 2;
part1Ptr = NULL;
doStoreArrayDirectFailed:
varPtr = TclLookupArrayElement(interp, part1Ptr, part2Ptr,
| | | 3490 3491 3492 3493 3494 3495 3496 3497 3498 3499 3500 3501 3502 3503 3504 |
arrayPtr = arrayPtr->value.linkPtr;
}
cleanup = 2;
part1Ptr = NULL;
doStoreArrayDirectFailed:
varPtr = TclLookupArrayElement(interp, part1Ptr, part2Ptr,
TCL_LEAVE_ERR_MSG, "set", true, true, arrayPtr, varIdx);
if (!varPtr) {
TRACE_ERROR(interp);
goto gotError;
}
goto doCallPtrSetVar;
case INST_LAPPEND_SCALAR:
|
| ︙ | ︙ | |||
3607 3608 3609 3610 3611 3612 3613 |
varPtr = VarHashFindVar(arrayPtr->value.tablePtr, part2Ptr);
if (varPtr && TclIsVarDirectReadable(varPtr)
&& TclIsVarDirectWritable(varPtr)) {
goto lappendListDirect;
}
}
varPtr = TclLookupArrayElement(interp, part1Ptr, part2Ptr,
| | | 3607 3608 3609 3610 3611 3612 3613 3614 3615 3616 3617 3618 3619 3620 3621 |
varPtr = VarHashFindVar(arrayPtr->value.tablePtr, part2Ptr);
if (varPtr && TclIsVarDirectReadable(varPtr)
&& TclIsVarDirectWritable(varPtr)) {
goto lappendListDirect;
}
}
varPtr = TclLookupArrayElement(interp, part1Ptr, part2Ptr,
TCL_LEAVE_ERR_MSG, "set", true, true, arrayPtr, varIdx);
if (varPtr == NULL) {
TRACE_ERROR(interp);
goto gotError;
}
goto lappendListPtr;
case INST_LAPPEND_LIST_ARRAY_STK:
|
| ︙ | ︙ | |||
3662 3663 3664 3665 3666 3667 3668 |
varIdx = -1;
if (TclListObjGetElements(interp, valuePtr, &objc, &objv) != TCL_OK) {
TRACE_ERROR(interp);
goto gotError;
}
DECACHE_STACK_INFO();
varPtr = TclObjLookupVarEx(interp, part1Ptr, part2Ptr,
| | | 3662 3663 3664 3665 3666 3667 3668 3669 3670 3671 3672 3673 3674 3675 3676 |
varIdx = -1;
if (TclListObjGetElements(interp, valuePtr, &objc, &objv) != TCL_OK) {
TRACE_ERROR(interp);
goto gotError;
}
DECACHE_STACK_INFO();
varPtr = TclObjLookupVarEx(interp, part1Ptr, part2Ptr,
TCL_LEAVE_ERR_MSG, "set", true, true, &arrayPtr);
CACHE_STACK_INFO();
if (!varPtr) {
TRACE_ERROR(interp);
goto gotError;
}
lappendListPtr:
|
| ︙ | ︙ | |||
3812 3813 3814 3815 3816 3817 3818 |
part2Ptr = NULL;
objPtr = OBJ_AT_TOS;
TRACE("\"%.30s\" (by %ld) => ", O2S(objPtr), increment);
}
part1Ptr = objPtr;
varIdx = -1;
varPtr = TclObjLookupVarEx(interp, objPtr, part2Ptr,
| | | 3812 3813 3814 3815 3816 3817 3818 3819 3820 3821 3822 3823 3824 3825 3826 |
part2Ptr = NULL;
objPtr = OBJ_AT_TOS;
TRACE("\"%.30s\" (by %ld) => ", O2S(objPtr), increment);
}
part1Ptr = objPtr;
varIdx = -1;
varPtr = TclObjLookupVarEx(interp, objPtr, part2Ptr,
TCL_LEAVE_ERR_MSG, "read", true, true, &arrayPtr);
if (!varPtr) {
DECACHE_STACK_INFO();
Tcl_AddErrorInfo(interp,
"\n (reading value of variable to increment)");
CACHE_STACK_INFO();
TRACE_ERROR(interp);
Tcl_DecrRefCount(incrPtr);
|
| ︙ | ︙ | |||
3854 3855 3856 3857 3858 3859 3860 |
cleanup = 1;
while (TclIsVarLink(arrayPtr)) {
arrayPtr = arrayPtr->value.linkPtr;
}
TRACE("%u \"%.30s\" (by %ld) => ", (unsigned) varIdx, O2S(part2Ptr),
increment);
varPtr = TclLookupArrayElement(interp, part1Ptr, part2Ptr,
| | | 3854 3855 3856 3857 3858 3859 3860 3861 3862 3863 3864 3865 3866 3867 3868 |
cleanup = 1;
while (TclIsVarLink(arrayPtr)) {
arrayPtr = arrayPtr->value.linkPtr;
}
TRACE("%u \"%.30s\" (by %ld) => ", (unsigned) varIdx, O2S(part2Ptr),
increment);
varPtr = TclLookupArrayElement(interp, part1Ptr, part2Ptr,
TCL_LEAVE_ERR_MSG, "read", true, true, arrayPtr, varIdx);
if (!varPtr) {
TRACE_ERROR(interp);
Tcl_DecrRefCount(incrPtr);
goto gotError;
}
goto doIncrVar;
|
| ︙ | ︙ | |||
4049 4050 4051 4052 4053 4054 4055 |
if (TclIsVarArray(arrayPtr) && !ReadTraced(arrayPtr)) {
varPtr = VarHashFindVar(arrayPtr->value.tablePtr, part2Ptr);
if (!varPtr || !ReadTraced(varPtr)) {
goto afterExistsPeephole;
}
}
varPtr = TclLookupArrayElement(interp, NULL, part2Ptr, 0, "access",
| | | 4049 4050 4051 4052 4053 4054 4055 4056 4057 4058 4059 4060 4061 4062 4063 |
if (TclIsVarArray(arrayPtr) && !ReadTraced(arrayPtr)) {
varPtr = VarHashFindVar(arrayPtr->value.tablePtr, part2Ptr);
if (!varPtr || !ReadTraced(varPtr)) {
goto afterExistsPeephole;
}
}
varPtr = TclLookupArrayElement(interp, NULL, part2Ptr, 0, "access",
false, true, arrayPtr, varIdx);
if (varPtr) {
if (ReadTraced(varPtr) || (arrayPtr && ReadTraced(arrayPtr))) {
DECACHE_STACK_INFO();
TclObjCallVarTraces(iPtr, arrayPtr, varPtr, NULL, part2Ptr,
TCL_TRACE_READS, false, varIdx);
CACHE_STACK_INFO();
}
|
| ︙ | ︙ | |||
4081 4082 4083 4084 4085 4086 4087 |
pcAdjustment = 1;
part2Ptr = NULL;
part1Ptr = OBJ_AT_TOS; /* variable name */
TRACE("\"%.30s\" => ", O2S(part1Ptr));
doExistStk:
varPtr = TclObjLookupVarEx(interp, part1Ptr, part2Ptr, 0, "access",
| | | 4081 4082 4083 4084 4085 4086 4087 4088 4089 4090 4091 4092 4093 4094 4095 |
pcAdjustment = 1;
part2Ptr = NULL;
part1Ptr = OBJ_AT_TOS; /* variable name */
TRACE("\"%.30s\" => ", O2S(part1Ptr));
doExistStk:
varPtr = TclObjLookupVarEx(interp, part1Ptr, part2Ptr, 0, "access",
/*createPart1*/false, /*createPart2*/true, &arrayPtr);
if (varPtr) {
if (ReadTraced(varPtr) || (arrayPtr && ReadTraced(arrayPtr))) {
DECACHE_STACK_INFO();
TclObjCallVarTraces(iPtr, arrayPtr, varPtr, part1Ptr, part2Ptr,
TCL_TRACE_READS, false, -1);
CACHE_STACK_INFO();
}
|
| ︙ | ︙ | |||
4189 4190 4191 4192 4193 4194 4195 |
TRACE_APPEND("OK\n");
NEXT_INST_F0(6, 1);
}
}
slowUnsetArray:
DECACHE_STACK_INFO();
varPtr = TclLookupArrayElement(interp, NULL, part2Ptr, flags, "unset",
| | | 4189 4190 4191 4192 4193 4194 4195 4196 4197 4198 4199 4200 4201 4202 4203 |
TRACE_APPEND("OK\n");
NEXT_INST_F0(6, 1);
}
}
slowUnsetArray:
DECACHE_STACK_INFO();
varPtr = TclLookupArrayElement(interp, NULL, part2Ptr, flags, "unset",
false, false, arrayPtr, varIdx);
if (!varPtr) {
if (flags & TCL_LEAVE_ERR_MSG) {
goto errorInUnset;
}
} else if (TclPtrUnsetVarIdx(interp, varPtr, arrayPtr, NULL, part2Ptr,
flags, varIdx) != TCL_OK && (flags & TCL_LEAVE_ERR_MSG)) {
goto errorInUnset;
|
| ︙ | ︙ | |||
4263 4264 4265 4266 4267 4268 4269 |
varIdx = -1;
pcAdjustment = 1;
cleanup = 2;
part1Ptr = OBJ_UNDER_TOS;
objPtr = OBJ_AT_TOS;
TRACE("\"%.30s\" \"%.30s\" => ", O2S(part1Ptr), O2S(objPtr));
varPtr = TclObjLookupVarEx(interp, part1Ptr, NULL, 0, NULL,
| | | 4263 4264 4265 4266 4267 4268 4269 4270 4271 4272 4273 4274 4275 4276 4277 |
varIdx = -1;
pcAdjustment = 1;
cleanup = 2;
part1Ptr = OBJ_UNDER_TOS;
objPtr = OBJ_AT_TOS;
TRACE("\"%.30s\" \"%.30s\" => ", O2S(part1Ptr), O2S(objPtr));
varPtr = TclObjLookupVarEx(interp, part1Ptr, NULL, 0, NULL,
/*createPart1*/true, /*createPart2*/false, &arrayPtr);
doConst:
if (TclIsVarConstant(varPtr)) {
TRACE_APPEND("already constant\n");
NEXT_INST_V(pcAdjustment, cleanup, 0);
}
if (TclIsVarArray(varPtr)) {
msgPart = "variable is array";
|
| ︙ | ︙ | |||
4330 4331 4332 4333 4334 4335 4336 |
case INST_ARRAY_EXISTS_STK:
varIdx = -1;
pcAdjustment = 1;
cleanup = 1;
part1Ptr = OBJ_AT_TOS;
TRACE("\"%.30s\" => ", O2S(part1Ptr));
varPtr = TclObjLookupVarEx(interp, part1Ptr, NULL, 0, NULL,
| | | 4330 4331 4332 4333 4334 4335 4336 4337 4338 4339 4340 4341 4342 4343 4344 |
case INST_ARRAY_EXISTS_STK:
varIdx = -1;
pcAdjustment = 1;
cleanup = 1;
part1Ptr = OBJ_AT_TOS;
TRACE("\"%.30s\" => ", O2S(part1Ptr));
varPtr = TclObjLookupVarEx(interp, part1Ptr, NULL, 0, NULL,
/*createPart1*/false, /*createPart2*/false, &arrayPtr);
doArrayExists:
DECACHE_STACK_INFO();
result = TclCheckArrayTraces(interp, varPtr, arrayPtr, part1Ptr, varIdx);
CACHE_STACK_INFO();
if (result == TCL_ERROR) {
TRACE_ERROR(interp);
goto gotError;
|
| ︙ | ︙ | |||
4366 4367 4368 4369 4370 4371 4372 |
case INST_ARRAY_MAKE_STK:
varIdx = -1;
pcAdjustment = 1;
cleanup = 1;
part1Ptr = OBJ_AT_TOS;
TRACE("\"%.30s\" => ", O2S(part1Ptr));
varPtr = TclObjLookupVarEx(interp, part1Ptr, NULL, TCL_LEAVE_ERR_MSG,
| | | 4366 4367 4368 4369 4370 4371 4372 4373 4374 4375 4376 4377 4378 4379 4380 |
case INST_ARRAY_MAKE_STK:
varIdx = -1;
pcAdjustment = 1;
cleanup = 1;
part1Ptr = OBJ_AT_TOS;
TRACE("\"%.30s\" => ", O2S(part1Ptr));
varPtr = TclObjLookupVarEx(interp, part1Ptr, NULL, TCL_LEAVE_ERR_MSG,
"set", /*createPart1*/true, /*createPart2*/false, &arrayPtr);
if (varPtr == NULL) {
TRACE_ERROR(interp);
goto gotError;
}
doArrayMake:
if (varPtr && !TclIsVarArray(varPtr)) {
if (TclIsVarArrayElement(varPtr) || !TclIsVarUndefined(varPtr)) {
|
| ︙ | ︙ | |||
4423 4424 4425 4426 4427 4428 4429 | /* * Locate the other variable. */ savedFramePtr = iPtr->varFramePtr; iPtr->varFramePtr = framePtr; otherPtr = TclObjLookupVarEx(interp, OBJ_AT_TOS, NULL, | | | | 4423 4424 4425 4426 4427 4428 4429 4430 4431 4432 4433 4434 4435 4436 4437 4438 |
/*
* Locate the other variable.
*/
savedFramePtr = iPtr->varFramePtr;
iPtr->varFramePtr = framePtr;
otherPtr = TclObjLookupVarEx(interp, OBJ_AT_TOS, NULL,
TCL_LEAVE_ERR_MSG, "access", /*createPart1*/ true,
/*createPart2*/ true, &varPtr);
iPtr->varFramePtr = savedFramePtr;
if (!otherPtr) {
TRACE_ERROR(interp);
goto gotError;
}
goto doLinkVars;
|
| ︙ | ︙ | |||
4448 4449 4450 4451 4452 4453 4454 | * Locate the other variable. */ savedNsPtr = iPtr->varFramePtr->nsPtr; iPtr->varFramePtr->nsPtr = (Namespace *) nsPtr; otherPtr = TclObjLookupVarEx(interp, OBJ_AT_TOS, NULL, (TCL_NAMESPACE_ONLY|TCL_LEAVE_ERR_MSG|TCL_AVOID_RESOLVERS), | | | | 4448 4449 4450 4451 4452 4453 4454 4455 4456 4457 4458 4459 4460 4461 4462 4463 4464 4465 4466 4467 4468 4469 4470 4471 4472 4473 4474 |
* Locate the other variable.
*/
savedNsPtr = iPtr->varFramePtr->nsPtr;
iPtr->varFramePtr->nsPtr = (Namespace *) nsPtr;
otherPtr = TclObjLookupVarEx(interp, OBJ_AT_TOS, NULL,
(TCL_NAMESPACE_ONLY|TCL_LEAVE_ERR_MSG|TCL_AVOID_RESOLVERS),
"access", /*createPart1*/ true, /*createPart2*/ true, &varPtr);
iPtr->varFramePtr->nsPtr = savedNsPtr;
if (!otherPtr) {
TRACE_ERROR(interp);
goto gotError;
}
goto doLinkVars;
case INST_VARIABLE:
TRACE("%u, %.30s => ", TclGetUInt4AtPtr(pc + 1), O2S(OBJ_AT_TOS));
otherPtr = TclObjLookupVarEx(interp, OBJ_AT_TOS, NULL,
(TCL_NAMESPACE_ONLY | TCL_LEAVE_ERR_MSG), "access",
/*createPart1*/ true, /*createPart2*/ true, &varPtr);
if (!otherPtr) {
TRACE_ERROR(interp);
goto gotError;
}
/*
* Do the [variable] magic.
|
| ︙ | ︙ | |||
5602 5603 5604 5605 5606 5607 5608 |
case INST_STR_GE:
value2Ptr = OBJ_AT_TOS;
valuePtr = OBJ_UNDER_TOS;
TRACE("\"%.20s\" \"%.20s\" => ", O2S(valuePtr), O2S(value2Ptr));
stringCompare:;
{
| | | | 5602 5603 5604 5605 5606 5607 5608 5609 5610 5611 5612 5613 5614 5615 5616 5617 5618 |
case INST_STR_GE:
value2Ptr = OBJ_AT_TOS;
valuePtr = OBJ_UNDER_TOS;
TRACE("\"%.20s\" \"%.20s\" => ", O2S(valuePtr), O2S(value2Ptr));
stringCompare:;
{
bool checkEq = ((*pc == INST_EQ) || (*pc == INST_NEQ)
|| (*pc == INST_STR_EQ) || (*pc == INST_STR_NEQ));
match = TclStringCmp(valuePtr, value2Ptr, checkEq, false, -1);
}
/*
* Make sure only -1,0,1 is returned
* TODO: consider peephole opt.
*/
|
| ︙ | ︙ | |||
7086 7087 7088 7089 7090 7091 7092 |
}
int match = 1;
for (int index = 0; index < cmpLen && match; index++) {
Tcl_Obj *a = ((Tcl_Size) index < aObjc) ? aObjv[index] : NULL;
Tcl_Obj *b = ((Tcl_Size) index < bObjc) ? bObjv[index] : NULL;
if (a && b) {
| | | 7086 7087 7088 7089 7090 7091 7092 7093 7094 7095 7096 7097 7098 7099 7100 |
}
int match = 1;
for (int index = 0; index < cmpLen && match; index++) {
Tcl_Obj *a = ((Tcl_Size) index < aObjc) ? aObjv[index] : NULL;
Tcl_Obj *b = ((Tcl_Size) index < bObjc) ? bObjv[index] : NULL;
if (a && b) {
match = TclStringCmp(a, b, true, false, -1) == 0;
} else if (a) {
match = TclGetString(a)[0] == '\0';
} else if (b) {
match = TclGetString(b)[0] == '\0';
}
}
TRACE_APPEND("%d\n", match ? 1 : 0);
|
| ︙ | ︙ | |||
7735 7736 7737 7738 7739 7740 7741 |
O2S(varNamePtr), O2S(valuePtr), O2S(keysPtr));
if (TclListObjGetElements(interp, listPtr, &objc, &objv) != TCL_OK) {
TRACE_ERROR(interp);
TclDecrRefCount(keysPtr);
goto gotError;
}
varPtr = TclObjLookupVarEx(interp, varNamePtr, NULL,
| | | 7735 7736 7737 7738 7739 7740 7741 7742 7743 7744 7745 7746 7747 7748 7749 |
O2S(varNamePtr), O2S(valuePtr), O2S(keysPtr));
if (TclListObjGetElements(interp, listPtr, &objc, &objv) != TCL_OK) {
TRACE_ERROR(interp);
TclDecrRefCount(keysPtr);
goto gotError;
}
varPtr = TclObjLookupVarEx(interp, varNamePtr, NULL,
TCL_LEAVE_ERR_MSG, "set", true, true, &arrayPtr);
if (varPtr == NULL) {
TRACE_ERROR(interp);
TclDecrRefCount(keysPtr);
goto gotError;
}
DECACHE_STACK_INFO();
result = TclDictWithFinish(interp, varPtr, arrayPtr, varNamePtr, NULL, -1,
|
| ︙ | ︙ |
Changes to generic/tclInt.h.
| ︙ | ︙ | |||
3357 3358 3359 3360 3361 3362 3363 | Tcl_Namespace *ensembleNamespacePtr, int flags); MODULE_SCOPE void TclDeleteNamespaceVars(Namespace *nsPtr); MODULE_SCOPE void TclDeleteNamespaceChildren(Namespace *nsPtr); MODULE_SCOPE Tcl_Size TclDictGetSize(Tcl_Obj *dictPtr); MODULE_SCOPE int TclFindDictElement(Tcl_Interp *interp, const char *dict, Tcl_Size dictLength, const char **elementPtr, const char **nextPtr, | | | 3357 3358 3359 3360 3361 3362 3363 3364 3365 3366 3367 3368 3369 3370 3371 | Tcl_Namespace *ensembleNamespacePtr, int flags); MODULE_SCOPE void TclDeleteNamespaceVars(Namespace *nsPtr); MODULE_SCOPE void TclDeleteNamespaceChildren(Namespace *nsPtr); MODULE_SCOPE Tcl_Size TclDictGetSize(Tcl_Obj *dictPtr); MODULE_SCOPE int TclFindDictElement(Tcl_Interp *interp, const char *dict, Tcl_Size dictLength, const char **elementPtr, const char **nextPtr, Tcl_Size *sizePtr, bool *literalPtr); MODULE_SCOPE Tcl_Obj * TclDictObjSmartRef(Tcl_Interp *interp, Tcl_Obj *); MODULE_SCOPE int TclDictGet(Tcl_Interp *interp, Tcl_Obj *dictPtr, const char *key, Tcl_Obj **valuePtrPtr); MODULE_SCOPE int TclDictPut(Tcl_Interp *interp, Tcl_Obj *dictPtr, const char *key, Tcl_Obj *valuePtr); MODULE_SCOPE int TclDictPutString(Tcl_Interp *interp, Tcl_Obj *dictPtr, const char *key, const char *value); |
| ︙ | ︙ | |||
3638 3639 3640 3641 3642 3643 3644 | MODULE_SCOPE void TclSpellFix(Tcl_Interp *interp, Tcl_Obj *const *objv, Tcl_Size objc, Tcl_Size subIdx, Tcl_Obj *bad, Tcl_Obj *fix); MODULE_SCOPE void * TclStackRealloc(Tcl_Interp *interp, void *ptr, size_t numBytes); typedef int (*memCmpFn_t)(const void*, const void*, size_t); MODULE_SCOPE int TclStringCmp(Tcl_Obj *value1Ptr, Tcl_Obj *value2Ptr, | | | 3638 3639 3640 3641 3642 3643 3644 3645 3646 3647 3648 3649 3650 3651 3652 | MODULE_SCOPE void TclSpellFix(Tcl_Interp *interp, Tcl_Obj *const *objv, Tcl_Size objc, Tcl_Size subIdx, Tcl_Obj *bad, Tcl_Obj *fix); MODULE_SCOPE void * TclStackRealloc(Tcl_Interp *interp, void *ptr, size_t numBytes); typedef int (*memCmpFn_t)(const void*, const void*, size_t); MODULE_SCOPE int TclStringCmp(Tcl_Obj *value1Ptr, Tcl_Obj *value2Ptr, bool checkEq, bool nocase, Tcl_Size reqlength); MODULE_SCOPE int TclStringMatch(const char *str, Tcl_Size strLen, const char *pattern, int ptnLen, int flags); MODULE_SCOPE int TclStringMatchObj(Tcl_Obj *stringObj, Tcl_Obj *patternObj, int flags); MODULE_SCOPE void TclSubstCompile(Tcl_Interp *interp, const char *bytes, Tcl_Size numBytes, int flags, int line, struct CompileEnv *envPtr); |
| ︙ | ︙ | |||
4049 4050 4051 4052 4053 4054 4055 | * Functions defined in generic/tclVar.c and currently exported only for use * by the bytecode compiler and engine. Some of these could later be placed in * the public interface. */ MODULE_SCOPE Var * TclObjLookupVarEx(Tcl_Interp * interp, Tcl_Obj *part1Ptr, Tcl_Obj *part2Ptr, int flags, | | | | | 4049 4050 4051 4052 4053 4054 4055 4056 4057 4058 4059 4060 4061 4062 4063 4064 4065 4066 4067 4068 | * Functions defined in generic/tclVar.c and currently exported only for use * by the bytecode compiler and engine. Some of these could later be placed in * the public interface. */ MODULE_SCOPE Var * TclObjLookupVarEx(Tcl_Interp * interp, Tcl_Obj *part1Ptr, Tcl_Obj *part2Ptr, int flags, const char *msg, bool createPart1, bool createPart2, Var **arrayPtrPtr); MODULE_SCOPE Var * TclLookupArrayElement(Tcl_Interp *interp, Tcl_Obj *arrayNamePtr, Tcl_Obj *elNamePtr, int flags, const char *msg, bool createPart1, bool createPart2, Var *arrayPtr, Tcl_Size index); MODULE_SCOPE Tcl_Obj * TclPtrGetVarIdx(Tcl_Interp *interp, Var *varPtr, Var *arrayPtr, Tcl_Obj *part1Ptr, Tcl_Obj *part2Ptr, int flags, Tcl_Size index); MODULE_SCOPE Tcl_Obj * TclPtrSetVarIdx(Tcl_Interp *interp, Var *varPtr, Var *arrayPtr, Tcl_Obj *part1Ptr, Tcl_Obj *part2Ptr, Tcl_Obj *newValuePtr, |
| ︙ | ︙ |
Changes to generic/tclNamesp.c.
| ︙ | ︙ | |||
4610 4611 4612 4613 4614 4615 4616 | * Locate the other variable. */ Namespace *savedNsPtr = iPtr->varFramePtr->nsPtr; iPtr->varFramePtr->nsPtr = (Namespace *) nsPtr; Var *arrayPtr, *otherPtr = TclObjLookupVarEx(interp, objv[0], NULL, (TCL_NAMESPACE_ONLY|TCL_LEAVE_ERR_MSG|TCL_AVOID_RESOLVERS), | | | 4610 4611 4612 4613 4614 4615 4616 4617 4618 4619 4620 4621 4622 4623 4624 |
* Locate the other variable.
*/
Namespace *savedNsPtr = iPtr->varFramePtr->nsPtr;
iPtr->varFramePtr->nsPtr = (Namespace *) nsPtr;
Var *arrayPtr, *otherPtr = TclObjLookupVarEx(interp, objv[0], NULL,
(TCL_NAMESPACE_ONLY|TCL_LEAVE_ERR_MSG|TCL_AVOID_RESOLVERS),
"access", /*createPart1*/ true, /*createPart2*/ true, &arrayPtr);
iPtr->varFramePtr->nsPtr = savedNsPtr;
if (otherPtr == NULL) {
return TCL_ERROR;
}
/*
* Create the new variable and link it to otherPtr.
|
| ︙ | ︙ | |||
4974 4975 4976 4977 4978 4979 4980 | TclAppendPrintfToErrorInfo(interp, "\n %s\n\"%.*s%s\"", ((iPtr->errorInfo == NULL) ? "while executing" : "invoked from within"), (overflow ? limit : (int)length), command, (overflow ? "..." : "")); varPtr = TclObjLookupVarEx(interp, iPtr->eiVar, NULL, TCL_GLOBAL_ONLY, | | | 4974 4975 4976 4977 4978 4979 4980 4981 4982 4983 4984 4985 4986 4987 4988 |
TclAppendPrintfToErrorInfo(interp,
"\n %s\n\"%.*s%s\"", ((iPtr->errorInfo == NULL)
? "while executing" : "invoked from within"),
(overflow ? limit : (int)length), command,
(overflow ? "..." : ""));
varPtr = TclObjLookupVarEx(interp, iPtr->eiVar, NULL, TCL_GLOBAL_ONLY,
NULL, false, false, &arrayPtr);
if ((varPtr == NULL) || !TclIsVarTraced(varPtr)) {
/*
* Should not happen.
*/
return;
} else {
|
| ︙ | ︙ |
Changes to generic/tclOOBasic.c.
| ︙ | ︙ | |||
767 768 769 770 771 772 773 |
CallContext *callerContext = (CallContext *) framePtr->clientData;
Method *mPtr = callerContext->callPtr->chain[
callerContext->index].mPtr;
if (mPtr->declaringObjectPtr == oPtr) {
PrivateVariableMapping *pvPtr;
FOREACH_STRUCT(pvPtr, oPtr->privateVariables) {
| | | 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 |
CallContext *callerContext = (CallContext *) framePtr->clientData;
Method *mPtr = callerContext->callPtr->chain[
callerContext->index].mPtr;
if (mPtr->declaringObjectPtr == oPtr) {
PrivateVariableMapping *pvPtr;
FOREACH_STRUCT(pvPtr, oPtr->privateVariables) {
if (!TclStringCmp(pvPtr->variableObj, varName, true, false,
TCL_INDEX_NONE)) {
varName = pvPtr->fullNameObj;
break;
}
}
} else if (mPtr->declaringClassPtr &&
mPtr->declaringClassPtr->privateVariables.num) {
|
| ︙ | ︙ | |||
790 791 792 793 794 795 796 |
break;
}
}
}
if (isInstance) {
PrivateVariableMapping *pvPtr;
FOREACH_STRUCT(pvPtr, clsPtr->privateVariables) {
| | | | 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 |
break;
}
}
}
if (isInstance) {
PrivateVariableMapping *pvPtr;
FOREACH_STRUCT(pvPtr, clsPtr->privateVariables) {
if (!TclStringCmp(pvPtr->variableObj, varName, true,
false, TCL_INDEX_NONE)) {
varName = pvPtr->fullNameObj;
break;
}
}
}
}
}
|
| ︙ | ︙ |
Changes to generic/tclOODefineCmds.c.
| ︙ | ︙ | |||
3339 3340 3341 3342 3343 3344 3345 |
Tcl_Obj *listObj) /* The list of property names we're building */
{
bool present = false, changed = false;
Tcl_Obj *other;
Tcl_SetListObj(listObj, 0, NULL);
FOREACH(other, *propsList) {
| | | 3339 3340 3341 3342 3343 3344 3345 3346 3347 3348 3349 3350 3351 3352 3353 |
Tcl_Obj *listObj) /* The list of property names we're building */
{
bool present = false, changed = false;
Tcl_Obj *other;
Tcl_SetListObj(listObj, 0, NULL);
FOREACH(other, *propsList) {
if (!TclStringCmp(propName, other, true, false, TCL_INDEX_NONE)) {
present = true;
if (!addingProp) {
changed = true;
continue;
}
}
Tcl_ListObjAppendElement(NULL, listObj, other);
|
| ︙ | ︙ |
Changes to generic/tclOOProp.c.
| ︙ | ︙ | |||
704 705 706 707 708 709 710 |
PropNameCompare(
const void *a,
const void *b)
{
Tcl_Obj *first = *(Tcl_Obj **) a;
Tcl_Obj *second = *(Tcl_Obj **) b;
| | | 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 |
PropNameCompare(
const void *a,
const void *b)
{
Tcl_Obj *first = *(Tcl_Obj **) a;
Tcl_Obj *second = *(Tcl_Obj **) b;
return TclStringCmp(first, second, false, false, TCL_INDEX_NONE);
}
static inline void
SortPropList(
Tcl_Obj *list)
{
Tcl_Size ec;
|
| ︙ | ︙ |
Changes to generic/tclStrToD.c.
| ︙ | ︙ | |||
292 293 294 295 296 297 298 | }; /* * Static functions defined in this file. */ static bool AccumulateDecimalDigit(unsigned, int, | | | | | 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 | }; /* * Static functions defined in this file. */ static bool AccumulateDecimalDigit(unsigned, int, Tcl_WideUInt *, mp_int *, bool); static double MakeHighPrecisionDouble(int signum, mp_int *significand, int nSigDigs, int exponent); static double MakeLowPrecisionDouble(int signum, Tcl_WideUInt significand, int nSigDigs, int exponent); #ifdef IEEE_FLOATING_POINT static double MakeNaN(int signum, Tcl_WideUInt tag); #endif static double RefineApproximation(double approx, mp_int *exactSignificand, int exponent); static mp_err MulPow5(mp_int *, unsigned, mp_int *) MP_WUR; static int NormalizeRightward(Tcl_WideUInt *); static int RequiredPrecision(Tcl_WideUInt); static void DoubleToExpAndSig(double, Tcl_WideUInt *, int *, int *); static void TakeAbsoluteValue(Double *, int *); static char * FormatInfAndNaN(Double *, int *, char **); static char * FormatZero(int *, char **); static int ApproximateLog10(Tcl_WideUInt, int, int); static int BetterLog10(double, int, bool *); static void ComputeScale(int, int, int *, int *, int *, int *); static void SetPrecisionLimits(int, int, int *, int *, int *, int *); static char * BumpUp(char *, char *, int *); static int AdjustRange(double *, int); static char * ShorteningQuickFormat(double, int, int, double, char *, int *); static char * StrictQuickFormat(double, int, int, double, char *, int *); static char * QuickConversion(double, int, bool, int, int, int, int, int *, char **); static void CastOutPowersOf2(int *, int *, int *); static char * ShorteningInt64Conversion(Double *, Tcl_WideUInt, int, int, int, int, int, int, int, int, int, int, int, int *, char **); static char * StrictInt64Conversion(Tcl_WideUInt, int, int, int, int, int, int, |
| ︙ | ︙ | |||
1578 1579 1580 1581 1582 1583 1584 |
unsigned digit, /* Digit being scanned. */
int numZeros, /* Count of zero digits preceding the digit
* being scanned. */
Tcl_WideUInt *wideRepPtr, /* Representation of the partial number as a
* wide integer. */
mp_int *bignumRepPtr, /* Representation of the partial number as a
* bignum. */
| | | 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 |
unsigned digit, /* Digit being scanned. */
int numZeros, /* Count of zero digits preceding the digit
* being scanned. */
Tcl_WideUInt *wideRepPtr, /* Representation of the partial number as a
* wide integer. */
mp_int *bignumRepPtr, /* Representation of the partial number as a
* bignum. */
bool bignumFlag) /* True if the number overflowed previous
* to this digit. */
{
/*
* Try wide multiplication first.
*/
if (!bignumFlag) {
|
| ︙ | ︙ | |||
2575 2576 2577 2578 2579 2580 2581 |
*/
static inline int
BetterLog10(
double d, /* Original number to format. */
int k, /* Characteristic(Log base 10) of the
* number. */
| | | | | 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 |
*/
static inline int
BetterLog10(
double d, /* Original number to format. */
int k, /* Characteristic(Log base 10) of the
* number. */
bool *k_check) /* True if k is inexact. */
{
/*
* Performance hack. If k is in the range 0..TEN_PMAX, then we can use a
* powers-of-ten table to check it.
*/
if (k >= 0 && k <= TEN_PMAX) {
if (d < tens[k]) {
k--;
}
*k_check = false;
} else {
*k_check = true;
}
return k;
}
/*
*----------------------------------------------------------------------
*
|
| ︙ | ︙ | |||
2990 2991 2992 2993 2994 2995 2996 |
*----------------------------------------------------------------------
*/
static inline char *
QuickConversion(
double e, /* Number to format. */
int k, /* floor(log10(d)), approximately. */
| | | 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 |
*----------------------------------------------------------------------
*/
static inline char *
QuickConversion(
double e, /* Number to format. */
int k, /* floor(log10(d)), approximately. */
bool k_check, /* false if k is exact, true if it may be too high */
int flags, /* Flags passed to dtoa:
* TCL_DD_SHORTEST */
int len, /* Length of the return value. */
int ilim, /* Number of digits to store. */
int ilim1, /* Number of digits to store if we misguessed
* k. */
int *decpt, /* OUTPUT: Location of the decimal point. */
|
| ︙ | ︙ | |||
3449 3450 3451 3452 3453 3454 3455 |
*/
static inline bool
ShouldBankerRoundUpToNextPowD(
mp_int *b, /* Numerator of the fraction. */
mp_int *m, /* Numerator of the rounding tolerance. */
int sd, /* Common denominator is 2**(sd*MP_DIGIT_BIT). */
| | | 3449 3450 3451 3452 3453 3454 3455 3456 3457 3458 3459 3460 3461 3462 3463 |
*/
static inline bool
ShouldBankerRoundUpToNextPowD(
mp_int *b, /* Numerator of the fraction. */
mp_int *m, /* Numerator of the rounding tolerance. */
int sd, /* Common denominator is 2**(sd*MP_DIGIT_BIT). */
bool isodd, /* True if the integer significand is odd. */
mp_int *temp) /* Work area for the calculation. */
{
/*
* Compare B and S-m - which is the same as comparing B+m and S - which we
* do by computing b+m and doing a bitwhack compare against
* 2**(MP_DIGIT_BIT*sd)
*/
|
| ︙ | ︙ | |||
3833 3834 3835 3836 3837 3838 3839 |
*/
static inline bool
ShouldBankerRoundUp(
mp_int *twor, /* 2x the remainder from thd division that
* produced the last digit. */
mp_int *S, /* Denominator. */
| | | 3833 3834 3835 3836 3837 3838 3839 3840 3841 3842 3843 3844 3845 3846 3847 |
*/
static inline bool
ShouldBankerRoundUp(
mp_int *twor, /* 2x the remainder from thd division that
* produced the last digit. */
mp_int *S, /* Denominator. */
bool isodd) /* True if the last digit is odd. */
{
int r = mp_cmp_mag(twor, S);
switch (r) {
case MP_EQ:
return isodd;
case MP_GT:
|
| ︙ | ︙ | |||
3867 3868 3869 3870 3871 3872 3873 |
static inline bool
ShouldBankerRoundUpToNext(
mp_int *b, /* Remainder from the division that produced
* the last digit. */
mp_int *m, /* Numerator of the rounding tolerance. */
mp_int *S, /* Denominator. */
| | | 3867 3868 3869 3870 3871 3872 3873 3874 3875 3876 3877 3878 3879 3880 3881 |
static inline bool
ShouldBankerRoundUpToNext(
mp_int *b, /* Remainder from the division that produced
* the last digit. */
mp_int *m, /* Numerator of the rounding tolerance. */
mp_int *S, /* Denominator. */
bool isodd) /* True if the integer significand is odd. */
{
int r;
mp_int temp;
/*
* Compare b and S-m: this is the same as comparing B+m and S.
*/
|
| ︙ | ︙ | |||
4381 4382 4383 4384 4385 4386 4387 |
* one character beyond the end of the
* returned string. */
{
Double d; /* Union for deconstructing doubles. */
Tcl_WideUInt bw; /* Integer significand. */
int be; /* Power of 2 by which b must be multiplied */
int bbits; /* Number of bits needed to represent b. */
| | | | 4381 4382 4383 4384 4385 4386 4387 4388 4389 4390 4391 4392 4393 4394 4395 4396 4397 4398 |
* one character beyond the end of the
* returned string. */
{
Double d; /* Union for deconstructing doubles. */
Tcl_WideUInt bw; /* Integer significand. */
int be; /* Power of 2 by which b must be multiplied */
int bbits; /* Number of bits needed to represent b. */
bool denorm; /* True iff the input number was
* denormalized. */
int k; /* Estimate of floor(log10(d)). */
bool k_check; /* True if d is near enough to a power of
* ten that k must be checked. */
int b2, b5, s2, s5; /* Powers of 2 and 5 in the numerator and
* denominator of intermediate results. */
int ilim = -1, ilim1 = -1; /* Number of digits to convert, and number to
* convert if log10(d) has been
* overestimated. */
char *retval; /* Return value from this function. */
|
| ︙ | ︙ |
Changes to generic/tclStringObj.c.
| ︙ | ︙ | |||
3612 3613 3614 3615 3616 3617 3618 |
#endif /* WORDS_BIGENDIAN */
}
int
TclStringCmp(
Tcl_Obj *value1Ptr,
Tcl_Obj *value2Ptr,
| | | | 3612 3613 3614 3615 3616 3617 3618 3619 3620 3621 3622 3623 3624 3625 3626 3627 |
#endif /* WORDS_BIGENDIAN */
}
int
TclStringCmp(
Tcl_Obj *value1Ptr,
Tcl_Obj *value2Ptr,
bool checkEq, /* comparison is only for equality */
bool nocase, /* comparison is not case sensitive */
Tcl_Size reqlength) /* requested length in characters;
* TCL_INDEX_NONE to compare whole strings */
{
const char *s1, *s2;
int empty, match;
Tcl_Size length, s1len = 0, s2len = 0;
memCmpFn_t memCmpFn;
|
| ︙ | ︙ |
Changes to generic/tclUtil.c.
| ︙ | ︙ | |||
127 128 129 130 131 132 133 | static Tcl_HashTable * GetThreadHash(Tcl_ThreadDataKey *keyPtr); static int GetWideForIndex(Tcl_Interp *interp, Tcl_Obj *objPtr, Tcl_WideInt endValue, Tcl_WideInt *widePtr); static int FindElement(Tcl_Interp *interp, const char *string, Tcl_Size stringLength, const char *typeStr, const char *typeCode, const char **elementPtr, const char **nextPtr, Tcl_Size *sizePtr, | | | 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 | static Tcl_HashTable * GetThreadHash(Tcl_ThreadDataKey *keyPtr); static int GetWideForIndex(Tcl_Interp *interp, Tcl_Obj *objPtr, Tcl_WideInt endValue, Tcl_WideInt *widePtr); static int FindElement(Tcl_Interp *interp, const char *string, Tcl_Size stringLength, const char *typeStr, const char *typeCode, const char **elementPtr, const char **nextPtr, Tcl_Size *sizePtr, int *literalIntPtr, bool *literalBoolPtr); /* * The following is the Tcl object type definition for an object that * represents a list index in the form, "end-offset". It is used as a * performance optimization in Tcl_GetIntForIndex. The internal rep is * stored directly in the wideValue, so no memory management is required * for it. This is a caching internalrep, keeping the result of a parse * around. This type is only created from a pre-existing string, so an |
| ︙ | ︙ | |||
534 535 536 537 538 539 540 |
* indicate that the substring of *sizePtr
* bytes starting at **elementPtr is/is not
* the literal list element and therefore
* does not/does require a call to
* TclCopyAndCollapse() by the caller. */
{
return FindElement(interp, list, listLength, "list", "LIST", elementPtr,
| | | | | 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 |
* indicate that the substring of *sizePtr
* bytes starting at **elementPtr is/is not
* the literal list element and therefore
* does not/does require a call to
* TclCopyAndCollapse() by the caller. */
{
return FindElement(interp, list, listLength, "list", "LIST", elementPtr,
nextPtr, sizePtr, literalPtr, NULL);
}
int
TclFindDictElement(
Tcl_Interp *interp, /* Interpreter to use for error reporting. If
* NULL, then no error message is left after
* errors. */
const char *dict, /* Points to the first byte of a string
* containing a Tcl dictionary with zero or
* more keys and values (possibly in
* braces). */
Tcl_Size dictLength, /* Number of bytes in the dict's string. */
const char **elementPtr, /* Where to put address of first significant
* character in the first element (i.e., key
* or value) of dict. */
const char **nextPtr, /* Fill in with location of character just
* after all white space following end of
* element (next arg or end of list). */
Tcl_Size *sizePtr, /* If non-zero, fill in with size of
* element. */
bool *literalPtr) /* If non-zero, fill in with true/false to
* indicate that the substring of *sizePtr
* bytes starting at **elementPtr is/is not
* the literal key or value and therefore
* does not/does require a call to
* TclCopyAndCollapse() by the caller. */
{
return FindElement(interp, dict, dictLength, "dict", "DICTIONARY",
elementPtr, nextPtr, sizePtr, NULL, literalPtr);
}
static int
FindElement(
Tcl_Interp *interp, /* Interpreter to use for error reporting. If
* NULL, then no error message is left after
* errors. */
|
| ︙ | ︙ | |||
587 588 589 590 591 592 593 |
const char **elementPtr, /* Where to put address of first significant
* character in first element. */
const char **nextPtr, /* Fill in with location of character just
* after all white space following end of
* argument (next arg or end of list/dict). */
Tcl_Size *sizePtr, /* If non-NULL, fill in with size of
* element. */
| | > > > > > > | | 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 |
const char **elementPtr, /* Where to put address of first significant
* character in first element. */
const char **nextPtr, /* Fill in with location of character just
* after all white space following end of
* argument (next arg or end of list/dict). */
Tcl_Size *sizePtr, /* If non-NULL, fill in with size of
* element. */
int *literalIntPtr, /* If non-NULL, fill in with non-zero/zero to
* indicate that the substring of *sizePtr
* bytes starting at **elementPtr is/is not
* the literal list/dict element and therefore
* does not/does require a call to
* TclCopyAndCollapse() by the caller. */
bool *literalBoolPtr) /* If non-NULL, fill in with true/false to
* indicate that the substring of *sizePtr
* bytes starting at **elementPtr is/is not
* the literal list/dict element and therefore
* does not/does require a call to
* TclCopyAndCollapse() by the caller. */
{
const char *p = string;
const char *elemStart; /* Points to first byte of first element. */
const char *limit; /* Points just after list/dict's last byte. */
Tcl_Size openBraces = 0; /* Brace nesting level during parse. */
bool inQuotes = false;
Tcl_Size size = 0;
Tcl_Size numChars;
bool literal = true;
const char *p2;
/*
* Skim off leading white space and check for an opening brace or quote.
* We treat embedded NULLs in the list/dict as bytes belonging to a list
* element (or dictionary key or value).
*/
|
| ︙ | ︙ | |||
777 778 779 780 781 782 783 |
p++;
}
*elementPtr = elemStart;
*nextPtr = p;
if (sizePtr != 0) {
*sizePtr = size;
}
| | | > > > | 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 |
p++;
}
*elementPtr = elemStart;
*nextPtr = p;
if (sizePtr != 0) {
*sizePtr = size;
}
if (literalIntPtr) {
*literalIntPtr = literal;
}
if (literalBoolPtr) {
*literalBoolPtr = literal;
}
return TCL_OK;
}
/*
*----------------------------------------------------------------------
*
|
| ︙ | ︙ |
Changes to generic/tclVar.c.
| ︙ | ︙ | |||
187 188 189 190 191 192 193 | } ArrayVarHashTable; /* * Forward references to functions defined later in this file: */ static void AppendLocals(Tcl_Interp *interp, Tcl_Obj *listPtr, | | | | | 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 | } ArrayVarHashTable; /* * Forward references to functions defined later in this file: */ static void AppendLocals(Tcl_Interp *interp, Tcl_Obj *listPtr, Tcl_Obj *patternPtr, bool includeLinks, bool justConstants); static void ArrayPopulateSearch(Tcl_Interp *interp, Tcl_Obj *arrayNameObj, Var *varPtr, ArraySearch *searchPtr); static void ArrayDoneSearch(Interp *iPtr, Var *varPtr, ArraySearch *searchPtr); static Tcl_NRPostProc ArrayForLoopCallback; static Tcl_ObjCmdProc ArrayForNRCmd; static void DeleteSearches(Interp *iPtr, Var *arrayVarPtr); static void DeleteArray(Interp *iPtr, Tcl_Obj *arrayNamePtr, Var *varPtr, int flags, Tcl_Size index); static int LocateArray(Tcl_Interp *interp, Tcl_Obj *name, Var **varPtrPtr, bool *isArrayPtr); static int NotArrayError(Tcl_Interp *interp, Tcl_Obj *name); static Tcl_Var ObjFindNamespaceVar(Tcl_Interp *interp, Tcl_Obj *namePtr, Tcl_Namespace *contextNsPtr, int flags); static int ObjMakeUpvar(Tcl_Interp *interp, CallFrame *framePtr, Tcl_Obj *otherP1Ptr, const char *otherP2, int otherFlags, |
| ︙ | ︙ | |||
229 230 231 232 233 234 235 | /* * Functions defined in this file that may be exported in the future for use * by the bytecode compiler and engine or to the public interface. */ MODULE_SCOPE Var * TclLookupSimpleVar(Tcl_Interp *interp, | | | 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 | /* * Functions defined in this file that may be exported in the future for use * by the bytecode compiler and engine or to the public interface. */ MODULE_SCOPE Var * TclLookupSimpleVar(Tcl_Interp *interp, Tcl_Obj *varNamePtr, int flags, bool create, const char **errMsgPtr, Tcl_Size *indexPtr); static Tcl_DupInternalRepProc DupLocalVarName; static Tcl_FreeInternalRepProc FreeLocalVarName; static Tcl_FreeInternalRepProc FreeParsedVarName; static Tcl_DupInternalRepProc DupParsedVarName; |
| ︙ | ︙ | |||
326 327 328 329 330 331 332 |
}
static int
LocateArray(
Tcl_Interp *interp,
Tcl_Obj *name,
Var **varPtrPtr,
| | | | | 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 |
}
static int
LocateArray(
Tcl_Interp *interp,
Tcl_Obj *name,
Var **varPtrPtr,
bool *isArrayPtr)
{
Var *arrayPtr, *varPtr = TclObjLookupVarEx(interp, name, NULL, /*flags*/ 0,
/*msg*/ NULL, /*createPart1*/ false, /*createPart2*/ false, &arrayPtr);
if (TclCheckArrayTraces(interp, varPtr, arrayPtr, name, -1) == TCL_ERROR) {
return TCL_ERROR;
}
if (varPtrPtr) {
*varPtrPtr = varPtr;
}
if (isArrayPtr) {
*isArrayPtr = varPtr && !TclIsVarUndefined(varPtr)
&& TclIsVarArray(varPtr);
}
return TCL_OK;
}
static Var *
RequireArray(
Tcl_Interp *interp,
Tcl_Obj *arrayNameObj)
{
Var *varPtr;
bool isArray;
if (TCL_ERROR == LocateArray(interp, arrayNameObj, &varPtr, &isArray)) {
return NULL;
}
if (!isArray) {
(void) NotArrayError(interp, arrayNameObj);
return NULL;
|
| ︙ | ︙ | |||
615 616 617 618 619 620 621 |
* parenthesized array element. */
Tcl_Obj *part2Ptr, /* Name of element within array, or NULL. */
int flags, /* Only TCL_GLOBAL_ONLY, TCL_NAMESPACE_ONLY,
* and TCL_LEAVE_ERR_MSG bits matter. */
const char *msg, /* Verb to use in error messages, e.g. "read"
* or "set". Only needed if TCL_LEAVE_ERR_MSG
* is set in flags. */
| | | | | | 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 |
* parenthesized array element. */
Tcl_Obj *part2Ptr, /* Name of element within array, or NULL. */
int flags, /* Only TCL_GLOBAL_ONLY, TCL_NAMESPACE_ONLY,
* and TCL_LEAVE_ERR_MSG bits matter. */
const char *msg, /* Verb to use in error messages, e.g. "read"
* or "set". Only needed if TCL_LEAVE_ERR_MSG
* is set in flags. */
bool createPart1, /* If true, create hash table entry for part 1 of
* name, if it doesn't already exist. If false,
* return error if it doesn't exist. */
bool createPart2, /* If true, create hash table entry for part 2 of
* name, if it doesn't already exist. If false,
* return error if it doesn't exist. */
Var **arrayPtrPtr) /* If the name refers to an element of an
* array, *arrayPtrPtr gets filled in with
* address of array variable. Otherwise this
* is set to NULL. */
{
Interp *iPtr = (Interp *) interp;
|
| ︙ | ︙ | |||
851 852 853 854 855 856 857 |
TclLookupSimpleVar(
Tcl_Interp *interp, /* Interpreter to use for lookup. */
Tcl_Obj *varNamePtr, /* This is a simple variable name that could
* represent a scalar or an array. */
int flags, /* Only TCL_GLOBAL_ONLY, TCL_NAMESPACE_ONLY,
* TCL_AVOID_RESOLVERS and TCL_LEAVE_ERR_MSG
* bits matter. */
| | | | 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 |
TclLookupSimpleVar(
Tcl_Interp *interp, /* Interpreter to use for lookup. */
Tcl_Obj *varNamePtr, /* This is a simple variable name that could
* represent a scalar or an array. */
int flags, /* Only TCL_GLOBAL_ONLY, TCL_NAMESPACE_ONLY,
* TCL_AVOID_RESOLVERS and TCL_LEAVE_ERR_MSG
* bits matter. */
bool create, /* If true, create hash table entry for varname,
* if it doesn't already exist. If false, return
* error if it doesn't exist. */
const char **errMsgPtr,
Tcl_Size *indexPtr)
{
Interp *iPtr = (Interp *) interp;
CallFrame *varFramePtr = iPtr->varFramePtr;
/* Points to the procedure call frame whose
|
| ︙ | ︙ | |||
1094 1095 1096 1097 1098 1099 1100 |
Tcl_Obj *arrayNamePtr, /* This is the name of the array, or NULL if
* index>= 0. */
Tcl_Obj *elNamePtr, /* Name of element within array. */
int flags, /* Only TCL_LEAVE_ERR_MSG bit matters. */
const char *msg, /* Verb to use in error messages, e.g. "read"
* or "set". Only needed if TCL_LEAVE_ERR_MSG
* is set in flags. */
| | | | | | 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 |
Tcl_Obj *arrayNamePtr, /* This is the name of the array, or NULL if
* index>= 0. */
Tcl_Obj *elNamePtr, /* Name of element within array. */
int flags, /* Only TCL_LEAVE_ERR_MSG bit matters. */
const char *msg, /* Verb to use in error messages, e.g. "read"
* or "set". Only needed if TCL_LEAVE_ERR_MSG
* is set in flags. */
bool createArray, /* If true, transform arrayName to be an array if
* it isn't one yet and the transformation is
* possible. If false, return error if it isn't
* already an array. */
bool createElem, /* If true, create hash table entry for the
* element, if it doesn't already exist. If false,
* return error if it doesn't exist. */
Var *arrayPtr, /* Pointer to the array's Var structure. */
Tcl_Size index) /* If >=0, the index of the local array. */
{
int isNew;
Var *varPtr;
|
| ︙ | ︙ | |||
1331 1332 1333 1334 1335 1336 1337 |
/*
* Filter to pass through only the flags this interface supports.
*/
flags &= (TCL_GLOBAL_ONLY|TCL_NAMESPACE_ONLY|TCL_LEAVE_ERR_MSG);
varPtr = TclObjLookupVarEx(interp, part1Ptr, part2Ptr, flags, "read",
| | | 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 |
/*
* Filter to pass through only the flags this interface supports.
*/
flags &= (TCL_GLOBAL_ONLY|TCL_NAMESPACE_ONLY|TCL_LEAVE_ERR_MSG);
varPtr = TclObjLookupVarEx(interp, part1Ptr, part2Ptr, flags, "read",
/*createPart1*/ false, /*createPart2*/ true, &arrayPtr);
if (varPtr == NULL) {
return NULL;
}
return TclPtrGetVarIdx(interp, varPtr, arrayPtr, part1Ptr, part2Ptr,
flags, -1);
}
|
| ︙ | ︙ | |||
1718 1719 1720 1721 1722 1723 1724 |
/*
* Filter to pass through only the flags this interface supports.
*/
flags &= (TCL_GLOBAL_ONLY|TCL_NAMESPACE_ONLY|TCL_LEAVE_ERR_MSG
|TCL_APPEND_VALUE|TCL_LIST_ELEMENT);
varPtr = TclObjLookupVarEx(interp, part1Ptr, part2Ptr, flags, "set",
| | | 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 |
/*
* Filter to pass through only the flags this interface supports.
*/
flags &= (TCL_GLOBAL_ONLY|TCL_NAMESPACE_ONLY|TCL_LEAVE_ERR_MSG
|TCL_APPEND_VALUE|TCL_LIST_ELEMENT);
varPtr = TclObjLookupVarEx(interp, part1Ptr, part2Ptr, flags, "set",
/*createPart1*/ true, /*createPart2*/ true, &arrayPtr);
if (varPtr == NULL) {
if (newValuePtr->refCount == 0) {
Tcl_DecrRefCount(newValuePtr);
}
return NULL;
}
|
| ︙ | ︙ | |||
2153 2154 2155 2156 2157 2158 2159 |
* any of TCL_GLOBAL_ONLY, TCL_NAMESPACE_ONLY,
* TCL_APPEND_VALUE, TCL_LIST_ELEMENT,
* TCL_LEAVE_ERR_MSG. */
{
Var *varPtr, *arrayPtr;
varPtr = TclObjLookupVarEx(interp, part1Ptr, part2Ptr, flags, "read",
| | | 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 |
* any of TCL_GLOBAL_ONLY, TCL_NAMESPACE_ONLY,
* TCL_APPEND_VALUE, TCL_LIST_ELEMENT,
* TCL_LEAVE_ERR_MSG. */
{
Var *varPtr, *arrayPtr;
varPtr = TclObjLookupVarEx(interp, part1Ptr, part2Ptr, flags, "read",
true, true, &arrayPtr);
if (varPtr == NULL) {
Tcl_AddErrorInfo(interp,
"\n (reading value of variable to increment)");
return NULL;
}
return TclPtrIncrObjVarIdx(interp, varPtr, arrayPtr, part1Ptr, part2Ptr,
incrPtr, flags, -1);
|
| ︙ | ︙ | |||
2407 2408 2409 2410 2411 2412 2413 |
int flags) /* OR-ed combination of any of
* TCL_GLOBAL_ONLY, TCL_NAMESPACE_ONLY,
* TCL_LEAVE_ERR_MSG. */
{
Var *varPtr, *arrayPtr;
varPtr = TclObjLookupVarEx(interp, part1Ptr, part2Ptr, flags, "unset",
| | | 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 |
int flags) /* OR-ed combination of any of
* TCL_GLOBAL_ONLY, TCL_NAMESPACE_ONLY,
* TCL_LEAVE_ERR_MSG. */
{
Var *varPtr, *arrayPtr;
varPtr = TclObjLookupVarEx(interp, part1Ptr, part2Ptr, flags, "unset",
/*createPart1*/ false, /*createPart2*/ false, &arrayPtr);
if (varPtr == NULL) {
return TCL_ERROR;
}
return TclPtrUnsetVarIdx(interp, varPtr, arrayPtr, part1Ptr, part2Ptr,
flags, -1);
}
|
| ︙ | ︙ | |||
2848 2849 2850 2851 2852 2853 2854 |
if (objc == 2) {
varValuePtr = Tcl_ObjGetVar2(interp, objv[1], NULL,TCL_LEAVE_ERR_MSG);
if (varValuePtr == NULL) {
return TCL_ERROR;
}
} else {
Var *arrayPtr, *varPtr = TclObjLookupVarEx(interp, objv[1], NULL,
| | | | 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 |
if (objc == 2) {
varValuePtr = Tcl_ObjGetVar2(interp, objv[1], NULL,TCL_LEAVE_ERR_MSG);
if (varValuePtr == NULL) {
return TCL_ERROR;
}
} else {
Var *arrayPtr, *varPtr = TclObjLookupVarEx(interp, objv[1], NULL,
TCL_LEAVE_ERR_MSG, "set", /*createPart1*/ true,
/*createPart2*/ true, &arrayPtr);
if (varPtr == NULL) {
return TCL_ERROR;
}
for (int i=2 ; i<objc ; i++) {
/*
* Note that we do not need to increase the refCount of the Var
* pointers: should a trace delete the variable, the return value
|
| ︙ | ︙ | |||
2944 2945 2946 2947 2948 2949 2950 | /* * Protect the variable pointers around the TclPtrGetVarIdx call * to insure that they remain valid even if the variable was undefined * and unused. */ Var *arrayPtr, *varPtr = TclObjLookupVarEx(interp, objv[1], NULL, | | | | 2944 2945 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 |
/*
* Protect the variable pointers around the TclPtrGetVarIdx call
* to insure that they remain valid even if the variable was undefined
* and unused.
*/
Var *arrayPtr, *varPtr = TclObjLookupVarEx(interp, objv[1], NULL,
TCL_LEAVE_ERR_MSG, "set", /*createPart1*/ true,
/*createPart2*/ true, &arrayPtr);
if (varPtr == NULL) {
return TCL_ERROR;
}
if (TclIsVarInHash(varPtr)) {
VarHashRefCount(varPtr)++;
}
if (arrayPtr && TclIsVarInHash(arrayPtr)) {
|
| ︙ | ︙ | |||
3206 3207 3208 3209 3210 3211 3212 |
/*
* Get the next mapping from the array.
*/
Tcl_Obj *keyObj = NULL;
Tcl_Obj *valueObj = NULL;
Var *arrayPtr, *varPtr = TclObjLookupVarEx(interp, arrayNameObj, NULL, /*flags*/ 0,
| | | 3206 3207 3208 3209 3210 3211 3212 3213 3214 3215 3216 3217 3218 3219 3220 |
/*
* Get the next mapping from the array.
*/
Tcl_Obj *keyObj = NULL;
Tcl_Obj *valueObj = NULL;
Var *arrayPtr, *varPtr = TclObjLookupVarEx(interp, arrayNameObj, NULL, /*flags*/ 0,
/*msg*/ NULL, /*createPart1*/ false, /*createPart2*/ false, &arrayPtr);
if (varPtr == NULL) {
done = TCL_ERROR;
} else {
done = ArrayObjNext(interp, arrayNameObj, varPtr, searchPtr, &keyObj,
&valueObj);
}
|
| ︙ | ︙ | |||
3619 3620 3621 3622 3623 3624 3625 |
Interp *iPtr = (Interp *)interp;
if (objc != 2) {
Tcl_WrongNumArgs(interp, 1, objv, "arrayName");
return TCL_ERROR;
}
| | | | 3619 3620 3621 3622 3623 3624 3625 3626 3627 3628 3629 3630 3631 3632 3633 3634 3635 3636 3637 3638 |
Interp *iPtr = (Interp *)interp;
if (objc != 2) {
Tcl_WrongNumArgs(interp, 1, objv, "arrayName");
return TCL_ERROR;
}
bool isArray;
if (TCL_ERROR == LocateArray(interp, objv[1], NULL, &isArray)) {
return TCL_ERROR;
}
Tcl_SetObjResult(interp, iPtr->execEnvPtr->constants[isArray ? 1 : 0]);
return TCL_OK;
}
/*
*----------------------------------------------------------------------
*
* ArrayGetCmd --
|
| ︙ | ︙ | |||
3668 3669 3670 3671 3672 3673 3674 |
break;
default:
Tcl_WrongNumArgs(interp, 1, objv, "arrayName ?pattern?");
return TCL_ERROR;
}
Var *varPtr;
| | | 3668 3669 3670 3671 3672 3673 3674 3675 3676 3677 3678 3679 3680 3681 3682 |
break;
default:
Tcl_WrongNumArgs(interp, 1, objv, "arrayName ?pattern?");
return TCL_ERROR;
}
Var *varPtr;
bool isArray;
if (TCL_ERROR == LocateArray(interp, varNameObj, &varPtr, &isArray)) {
return TCL_ERROR;
}
/* If not an array, it's an empty result. */
if (!isArray) {
return TCL_OK;
|
| ︙ | ︙ | |||
3814 3815 3816 3817 3818 3819 3820 |
Tcl_Obj *const objv[])
{
static const char *const options[] = {
"-exact", "-glob", "-regexp", NULL
};
enum arrayNamesOptionsEnum {OPT_EXACT, OPT_GLOB, OPT_REGEXP} mode = OPT_GLOB;
Var *varPtr;
| | | 3814 3815 3816 3817 3818 3819 3820 3821 3822 3823 3824 3825 3826 3827 3828 |
Tcl_Obj *const objv[])
{
static const char *const options[] = {
"-exact", "-glob", "-regexp", NULL
};
enum arrayNamesOptionsEnum {OPT_EXACT, OPT_GLOB, OPT_REGEXP} mode = OPT_GLOB;
Var *varPtr;
bool isArray;
if ((objc < 2) || (objc > 4)) {
Tcl_WrongNumArgs(interp, 1, objv, "arrayName ?mode? ?pattern?");
return TCL_ERROR;
}
Tcl_Obj *patternObj = (objc > 2 ? objv[objc-1] : NULL);
|
| ︙ | ︙ | |||
3983 3984 3985 3986 3987 3988 3989 |
if (TCL_ERROR == LocateArray(interp, objv[1], NULL, NULL)) {
return TCL_ERROR;
}
Tcl_Obj *arrayNameObj = objv[1];
Var *arrayPtr, *varPtr = TclObjLookupVarEx(interp, arrayNameObj, NULL,
| | | | 3983 3984 3985 3986 3987 3988 3989 3990 3991 3992 3993 3994 3995 3996 3997 3998 |
if (TCL_ERROR == LocateArray(interp, objv[1], NULL, NULL)) {
return TCL_ERROR;
}
Tcl_Obj *arrayNameObj = objv[1];
Var *arrayPtr, *varPtr = TclObjLookupVarEx(interp, arrayNameObj, NULL,
/*flags*/ TCL_LEAVE_ERR_MSG, /*msg*/ "set", /*createPart1*/ true,
/*createPart2*/ true, &arrayPtr);
if (varPtr == NULL) {
return TCL_ERROR;
}
if (arrayPtr) {
CleanupVar(varPtr, arrayPtr);
TclObjVarErrMsg(interp, arrayNameObj, NULL, "set", NEEDARRAY, -1);
TclSetErrorCode(interp, "TCL", "LOOKUP", "VARNAME",
|
| ︙ | ︙ | |||
4034 4035 4036 4037 4038 4039 4040 |
Tcl_DictObjNext(&search, &keyPtr, &valuePtr, &done)) {
/*
* At this point, it would be nice if the key was directly usable
* by the array. This isn't the case though.
*/
Var *elemVarPtr = TclLookupArrayElement(interp, arrayNameObj,
| | | 4034 4035 4036 4037 4038 4039 4040 4041 4042 4043 4044 4045 4046 4047 4048 |
Tcl_DictObjNext(&search, &keyPtr, &valuePtr, &done)) {
/*
* At this point, it would be nice if the key was directly usable
* by the array. This isn't the case though.
*/
Var *elemVarPtr = TclLookupArrayElement(interp, arrayNameObj,
keyPtr, TCL_LEAVE_ERR_MSG, "set", true, true, varPtr, -1);
if ((elemVarPtr == NULL) ||
(TclPtrSetVarIdx(interp, elemVarPtr, varPtr, arrayNameObj,
keyPtr, valuePtr, TCL_LEAVE_ERR_MSG, -1) == NULL)) {
Tcl_DictObjDone(&search);
return TCL_ERROR;
}
|
| ︙ | ︙ | |||
4082 4083 4084 4085 4086 4087 4088 |
Tcl_Obj *copyListObj = TclListObjCopy(NULL, arrayElemObj);
if (!copyListObj) {
return TCL_ERROR;
}
for (Tcl_Size i=0 ; i<elemLen ; i+=2) {
Var *elemVarPtr = TclLookupArrayElement(interp, arrayNameObj,
| | > | 4082 4083 4084 4085 4086 4087 4088 4089 4090 4091 4092 4093 4094 4095 4096 4097 |
Tcl_Obj *copyListObj = TclListObjCopy(NULL, arrayElemObj);
if (!copyListObj) {
return TCL_ERROR;
}
for (Tcl_Size i=0 ; i<elemLen ; i+=2) {
Var *elemVarPtr = TclLookupArrayElement(interp, arrayNameObj,
elemPtrs[i], TCL_LEAVE_ERR_MSG, "set", true, true, varPtr,
-1);
if ((elemVarPtr == NULL) ||
(TclPtrSetVarIdx(interp, elemVarPtr, varPtr, arrayNameObj,
elemPtrs[i], elemPtrs[i+1], TCL_LEAVE_ERR_MSG,
-1) == NULL)) {
result = TCL_ERROR;
break;
|
| ︙ | ︙ | |||
4149 4150 4151 4152 4153 4154 4155 |
static int
ArraySizeCmd(
TCL_UNUSED(void *),
Tcl_Interp *interp,
int objc,
Tcl_Obj *const objv[])
{
| < < < > > > | 4150 4151 4152 4153 4154 4155 4156 4157 4158 4159 4160 4161 4162 4163 4164 4165 4166 4167 4168 4169 4170 4171 4172 4173 4174 4175 4176 4177 |
static int
ArraySizeCmd(
TCL_UNUSED(void *),
Tcl_Interp *interp,
int objc,
Tcl_Obj *const objv[])
{
if (objc != 2) {
Tcl_WrongNumArgs(interp, 1, objv, "arrayName");
return TCL_ERROR;
}
Var *varPtr;
bool isArray;
if (TCL_ERROR == LocateArray(interp, objv[1], &varPtr, &isArray)) {
return TCL_ERROR;
}
/* We can only iterate over the array if it exists... */
Tcl_WideInt size = 0;
if (isArray) {
/*
* Must iterate in order to get chance to check for present but
* "undefined" entries.
*/
Tcl_HashSearch search;
|
| ︙ | ︙ | |||
4256 4257 4258 4259 4260 4261 4262 |
Tcl_Obj *const objv[])
{
Var *varPtr, *protectedVarPtr;
Tcl_Obj *varNameObj, *patternObj, *nameObj;
Tcl_HashSearch search;
const char *pattern;
int unsetFlags = 0; /* Should this be TCL_LEAVE_ERR_MSG? */
| | | 4257 4258 4259 4260 4261 4262 4263 4264 4265 4266 4267 4268 4269 4270 4271 |
Tcl_Obj *const objv[])
{
Var *varPtr, *protectedVarPtr;
Tcl_Obj *varNameObj, *patternObj, *nameObj;
Tcl_HashSearch search;
const char *pattern;
int unsetFlags = 0; /* Should this be TCL_LEAVE_ERR_MSG? */
bool isArray;
switch (objc) {
case 2:
varNameObj = objv[1];
patternObj = NULL;
break;
case 3:
|
| ︙ | ︙ | |||
4570 4571 4572 4573 4574 4575 4576 |
Tcl_Interp *interp, /* Interpreter containing variables. Used for
* error messages, too. */
Var *otherPtr, /* Pointer to the variable being linked-to. */
Tcl_Obj *myNamePtr, /* Name of variable which will refer to
* otherP1/otherP2. Must be a scalar. */
int myFlags, /* 0, TCL_GLOBAL_ONLY or TCL_NAMESPACE_ONLY:
* indicates scope of myName. */
| | | 4571 4572 4573 4574 4575 4576 4577 4578 4579 4580 4581 4582 4583 4584 4585 |
Tcl_Interp *interp, /* Interpreter containing variables. Used for
* error messages, too. */
Var *otherPtr, /* Pointer to the variable being linked-to. */
Tcl_Obj *myNamePtr, /* Name of variable which will refer to
* otherP1/otherP2. Must be a scalar. */
int myFlags, /* 0, TCL_GLOBAL_ONLY or TCL_NAMESPACE_ONLY:
* indicates scope of myName. */
Tcl_Size index) /* If the variable to be linked is an indexed
* scalar, this is its index. Otherwise, -1 */
{
Interp *iPtr = (Interp *) interp;
CallFrame *varFramePtr = iPtr->varFramePtr;
const char *errMsg, *p, *myName;
Var *varPtr;
|
| ︙ | ︙ | |||
4620 4621 4622 4623 4624 4625 4626 | * upvar purposes: * - Bug #696893 - variable is either proc-local or in the current * namespace; never follow the second (global) resolution path. * - Bug #631741 - do not use special namespace or interp resolvers. */ varPtr = TclLookupSimpleVar(interp, myNamePtr, | | | 4621 4622 4623 4624 4625 4626 4627 4628 4629 4630 4631 4632 4633 4634 4635 |
* upvar purposes:
* - Bug #696893 - variable is either proc-local or in the current
* namespace; never follow the second (global) resolution path.
* - Bug #631741 - do not use special namespace or interp resolvers.
*/
varPtr = TclLookupSimpleVar(interp, myNamePtr,
myFlags|TCL_AVOID_RESOLVERS, /*create*/ true, &errMsg, &index);
if (varPtr == NULL) {
TclObjVarErrMsg(interp, myNamePtr, NULL, "create", errMsg, -1);
TclSetErrorCode(interp, "TCL", "LOOKUP", "VARNAME",
TclGetString(myNamePtr));
return TCL_ERROR;
}
}
|
| ︙ | ︙ | |||
4828 4829 4830 4831 4832 4833 4834 |
if (objc != 3) {
Tcl_WrongNumArgs(interp, 1, objv, "varName value");
return TCL_ERROR;
}
part1Ptr = objv[1];
varPtr = TclObjLookupVarEx(interp, part1Ptr, NULL, TCL_LEAVE_ERR_MSG,
| | | 4829 4830 4831 4832 4833 4834 4835 4836 4837 4838 4839 4840 4841 4842 4843 |
if (objc != 3) {
Tcl_WrongNumArgs(interp, 1, objv, "varName value");
return TCL_ERROR;
}
part1Ptr = objv[1];
varPtr = TclObjLookupVarEx(interp, part1Ptr, NULL, TCL_LEAVE_ERR_MSG,
"const", /*createPart1*/ true, /*createPart2*/ true, &arrayPtr);
if (TclIsVarArray(varPtr)) {
TclObjVarErrMsg(interp, part1Ptr, NULL, "make constant", ISARRAY, -1);
TclSetErrorCode(interp, "TCL", "LOOKUP", "CONST");
return TCL_ERROR;
}
if (TclIsVarArrayElement(varPtr)) {
if (TclIsVarUndefined(varPtr)) {
|
| ︙ | ︙ | |||
5013 5014 5015 5016 5017 5018 5019 | * if necessary. */ varNamePtr = objv[i]; varName = TclGetString(varNamePtr); varPtr = TclObjLookupVarEx(interp, varNamePtr, NULL, (TCL_NAMESPACE_ONLY | TCL_LEAVE_ERR_MSG), "define", | | | 5014 5015 5016 5017 5018 5019 5020 5021 5022 5023 5024 5025 5026 5027 5028 |
* if necessary.
*/
varNamePtr = objv[i];
varName = TclGetString(varNamePtr);
varPtr = TclObjLookupVarEx(interp, varNamePtr, NULL,
(TCL_NAMESPACE_ONLY | TCL_LEAVE_ERR_MSG), "define",
/*createPart1*/ true, /*createPart2*/ false, &arrayPtr);
if (arrayPtr != NULL) {
/*
* Variable cannot be an element in an array. If arrayPtr is
* non-NULL, it is, so throw up an error and return.
*/
|
| ︙ | ︙ | |||
6032 6033 6034 6035 6036 6037 6038 |
Tcl_ListObjAppendElement(interp, listPtr, elemObjPtr);
}
}
varPtr = VarHashNextVar(&search);
}
}
} else if (iPtr->varFramePtr->procPtr != NULL) {
| | | 6033 6034 6035 6036 6037 6038 6039 6040 6041 6042 6043 6044 6045 6046 6047 |
Tcl_ListObjAppendElement(interp, listPtr, elemObjPtr);
}
}
varPtr = VarHashNextVar(&search);
}
}
} else if (iPtr->varFramePtr->procPtr != NULL) {
AppendLocals(interp, listPtr, simplePatternPtr, true, false);
}
if (simplePatternPtr) {
Tcl_DecrRefCount(simplePatternPtr);
}
Tcl_SetObjResult(interp, listPtr);
return TCL_OK;
|
| ︙ | ︙ | |||
6182 6183 6184 6185 6186 6187 6188 |
/*
* Return a list containing names of first the compiled locals (i.e. the
* ones stored in the call frame), then the variables in the local hash
* table (if one exists).
*/
Tcl_Obj *listPtr = Tcl_NewListObj(0, NULL);
| | | 6183 6184 6185 6186 6187 6188 6189 6190 6191 6192 6193 6194 6195 6196 6197 |
/*
* Return a list containing names of first the compiled locals (i.e. the
* ones stored in the call frame), then the variables in the local hash
* table (if one exists).
*/
Tcl_Obj *listPtr = Tcl_NewListObj(0, NULL);
AppendLocals(interp, listPtr, patternPtr, false, false);
Tcl_SetObjResult(interp, listPtr);
return TCL_OK;
}
/*
*----------------------------------------------------------------------
*
|
| ︙ | ︙ | |||
6369 6370 6371 6372 6373 6374 6375 |
}
}
}
}
}
}
} else if (iPtr->varFramePtr->procPtr != NULL) {
| | | 6370 6371 6372 6373 6374 6375 6376 6377 6378 6379 6380 6381 6382 6383 6384 |
}
}
}
}
}
}
} else if (iPtr->varFramePtr->procPtr != NULL) {
AppendLocals(interp, listPtr, simplePatternPtr, true, true);
}
if (simplePatternPtr) {
Tcl_DecrRefCount(simplePatternPtr);
}
Tcl_SetObjResult(interp, listPtr);
return TCL_OK;
|
| ︙ | ︙ | |||
6419 6420 6421 6422 6423 6424 6425 |
}
static void
AppendLocals(
Tcl_Interp *interp, /* Current interpreter. */
Tcl_Obj *listPtr, /* List object to append names to. */
Tcl_Obj *patternPtr, /* Pattern to match against. */
| | | | 6420 6421 6422 6423 6424 6425 6426 6427 6428 6429 6430 6431 6432 6433 6434 6435 |
}
static void
AppendLocals(
Tcl_Interp *interp, /* Current interpreter. */
Tcl_Obj *listPtr, /* List object to append names to. */
Tcl_Obj *patternPtr, /* Pattern to match against. */
bool includeLinks, /* true if upvars should be included. */
bool justConstants) /* true if just constants should be included. */
{
Interp *iPtr = (Interp *) interp;
Tcl_HashTable addedTable;
const char *pattern = patternPtr? TclGetString(patternPtr) : NULL;
Tcl_Size localVarCt = iPtr->varFramePtr->numCompiledLocals;
TclVarHashTable *localVarTablePtr = iPtr->varFramePtr->varTablePtr;
|
| ︙ | ︙ | |||
6749 6750 6751 6752 6753 6754 6755 |
static const char *const options[] = {
"get", "set", "exists", "unset", NULL
};
enum arrayDefaultOptionsEnum {
OPT_GET, OPT_SET, OPT_EXISTS, OPT_UNSET
} option;
Var *varPtr, *arrayPtr;
| | | 6750 6751 6752 6753 6754 6755 6756 6757 6758 6759 6760 6761 6762 6763 6764 |
static const char *const options[] = {
"get", "set", "exists", "unset", NULL
};
enum arrayDefaultOptionsEnum {
OPT_GET, OPT_SET, OPT_EXISTS, OPT_UNSET
} option;
Var *varPtr, *arrayPtr;
bool isArray;
/*
* Parse arguments.
*/
if (objc != 3 && objc != 4) {
Tcl_WrongNumArgs(interp, 1, objv, "option arrayName ?value?");
|
| ︙ | ︙ | |||
6802 6803 6804 6805 6806 6807 6808 | } /* * Attempt to create array if needed. */ varPtr = TclObjLookupVarEx(interp, arrayNameObj, NULL, /*flags*/ TCL_LEAVE_ERR_MSG, /*msg*/ "array default set", | | | 6803 6804 6805 6806 6807 6808 6809 6810 6811 6812 6813 6814 6815 6816 6817 |
}
/*
* Attempt to create array if needed.
*/
varPtr = TclObjLookupVarEx(interp, arrayNameObj, NULL,
/*flags*/ TCL_LEAVE_ERR_MSG, /*msg*/ "array default set",
/*createPart1*/ true, /*createPart2*/ true, &arrayPtr);
if (varPtr == NULL) {
return TCL_ERROR;
}
if (arrayPtr) {
/*
* Not a valid array name.
*/
|
| ︙ | ︙ |