Compare commits
75
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a744556f14 | ||
|
|
fd4bc0f106 | ||
|
|
cca7f018e0 | ||
|
|
6597355ad8 | ||
|
|
f4549b8fc4 | ||
|
|
c9ae8d64d3 | ||
|
|
7716fd3e46 | ||
|
|
128e4211ae | ||
|
|
88b2f7f06e | ||
|
|
12945e9a16 | ||
|
|
2803a8a055 | ||
|
|
29ae06c2d3 | ||
|
|
8f95efa4cf | ||
|
|
cbc312324e | ||
|
|
03ecb591a6 | ||
|
|
6bb7b1e15d | ||
|
|
a2e12b4377 | ||
|
|
6d9846f8c9 | ||
|
|
666deab1ea | ||
|
|
bb9e19e6eb | ||
|
|
ea8a9ba071 | ||
|
|
430c9bc178 | ||
|
|
e7e7bafe96 | ||
|
|
9c349ce2e2 | ||
|
|
e7f9c9c822 | ||
|
|
e7d2bb4c60 | ||
|
|
83fcae9bbe | ||
|
|
d5961a83e0 | ||
|
|
9c6b83d5b1 | ||
|
|
8a115927af | ||
|
|
68cab10668 | ||
|
|
c28c2d5b9a | ||
|
|
78f85049ff | ||
|
|
a30f092ea3 | ||
|
|
4f13f826e4 | ||
|
|
1c54736c0d | ||
|
|
f9dd75e79c | ||
|
|
d423ce0c06 | ||
|
|
76b954ec41 | ||
|
|
c45f1130d1 | ||
|
|
0891bbbcbb | ||
|
|
05feb2c73f | ||
|
|
0e49a49b8f | ||
|
|
9daddcaad7 | ||
|
|
57dc79f34e | ||
|
|
6799b19771 | ||
|
|
413a0c2501 | ||
|
|
8a7b73aed2 | ||
|
|
76007824cc | ||
|
|
db5995b2b8 | ||
|
|
9083b5bf61 | ||
|
|
7f1d218ef8 | ||
|
|
4ad593f2bf | ||
|
|
cdacc33cbb | ||
|
|
f7157671ce | ||
|
|
b004b21242 | ||
|
|
fad447d516 | ||
|
|
437c149fe1 | ||
|
|
ffb2a3d9b4 | ||
|
|
4b5edf953c | ||
|
|
01a1be21e0 | ||
|
|
0eb33efc7a | ||
|
|
53baa9e5c4 | ||
|
|
af735a0ba9 | ||
|
|
a7b60b26f1 | ||
|
|
d6bd07fecc | ||
|
|
f497ce9a95 | ||
|
|
414163addc | ||
|
|
71fd534215 | ||
|
|
b8bcc352ea | ||
|
|
f04eef80d7 | ||
|
|
2de2d8678f | ||
|
|
d5e04d6200 | ||
|
|
6d14b815b2 | ||
|
|
ed18777278 |
+10
-4
@@ -26,6 +26,7 @@
|
||||
*- jumpTable testing
|
||||
*- syntax (?)
|
||||
*- returnCodeBranch
|
||||
*- tclooNext, tclooNextClass
|
||||
*/
|
||||
|
||||
#include "tclInt.h"
|
||||
@@ -437,6 +438,8 @@ static const TalInstDesc TalInstructionTable[] = {
|
||||
{"nop", ASSEM_1BYTE, INST_NOP, 0, 0},
|
||||
{"not", ASSEM_1BYTE, INST_LNOT, 1, 1},
|
||||
{"nsupvar", ASSEM_LVT4, INST_NSUPVAR, 2, 1},
|
||||
{"numericType", ASSEM_1BYTE, INST_NUM_TYPE, 1, 1},
|
||||
{"originCmd", ASSEM_1BYTE, INST_ORIGIN_COMMAND, 1, 1},
|
||||
{"over", ASSEM_OVER, INST_OVER, INT_MIN,-1-1},
|
||||
{"pop", ASSEM_1BYTE, INST_POP, 1, 0},
|
||||
{"pushReturnCode", ASSEM_1BYTE, INST_PUSH_RETURN_CODE, 0, 1},
|
||||
@@ -453,9 +456,9 @@ static const TalInstDesc TalInstructionTable[] = {
|
||||
| INST_STORE_ARRAY4), 2, 1},
|
||||
{"storeArrayStk", ASSEM_1BYTE, INST_STORE_ARRAY_STK, 3, 1},
|
||||
{"storeStk", ASSEM_1BYTE, INST_STORE_STK, 2, 1},
|
||||
{"strLower", ASSEM_1BYTE, INST_STR_LOWER, 1, 1},
|
||||
{"strTitle", ASSEM_1BYTE, INST_STR_TITLE, 1, 1},
|
||||
{"strUpper", ASSEM_1BYTE, INST_STR_UPPER, 1, 1},
|
||||
{"strcaseLower", ASSEM_1BYTE, INST_STR_LOWER, 1, 1},
|
||||
{"strcaseTitle", ASSEM_1BYTE, INST_STR_TITLE, 1, 1},
|
||||
{"strcaseUpper", ASSEM_1BYTE, INST_STR_UPPER, 1, 1},
|
||||
{"strcmp", ASSEM_1BYTE, INST_STR_CMP, 2, 1},
|
||||
{"strcat", ASSEM_CONCAT1, INST_STR_CONCAT1, INT_MIN,1},
|
||||
{"streq", ASSEM_1BYTE, INST_STR_EQ, 2, 1},
|
||||
@@ -466,6 +469,7 @@ static const TalInstDesc TalInstructionTable[] = {
|
||||
{"strmatch", ASSEM_BOOL, INST_STR_MATCH, 2, 1},
|
||||
{"strneq", ASSEM_1BYTE, INST_STR_NEQ, 2, 1},
|
||||
{"strrange", ASSEM_1BYTE, INST_STR_RANGE, 3, 1},
|
||||
{"strreplace", ASSEM_1BYTE, INST_STR_REPLACE, 4, 1},
|
||||
{"strrfind", ASSEM_1BYTE, INST_STR_FIND_LAST, 2, 1},
|
||||
{"strtrim", ASSEM_1BYTE, INST_STR_TRIM, 2, 1},
|
||||
{"strtrimLeft", ASSEM_1BYTE, INST_STR_TRIM_LEFT, 2, 1},
|
||||
@@ -475,6 +479,7 @@ static const TalInstDesc TalInstructionTable[] = {
|
||||
{"tclooIsObject", ASSEM_1BYTE, INST_TCLOO_IS_OBJECT, 1, 1},
|
||||
{"tclooNamespace", ASSEM_1BYTE, INST_TCLOO_NS, 1, 1},
|
||||
{"tclooSelf", ASSEM_1BYTE, INST_TCLOO_SELF, 0, 1},
|
||||
{"tryCvtToBoolean", ASSEM_1BYTE, INST_TRY_CVT_TO_BOOLEAN,1, 2},
|
||||
{"tryCvtToNumeric", ASSEM_1BYTE, INST_TRY_CVT_TO_NUMERIC,1, 1},
|
||||
{"uminus", ASSEM_1BYTE, INST_UMINUS, 1, 1},
|
||||
{"unset", ASSEM_BOOL_LVT4,INST_UNSET_SCALAR, 0, 0},
|
||||
@@ -514,7 +519,8 @@ static const unsigned char NonThrowingByteCodes[] = {
|
||||
INST_RESOLVE_COMMAND, /* 154 */
|
||||
INST_STR_TRIM, INST_STR_TRIM_LEFT, INST_STR_TRIM_RIGHT, /* 166-168 */
|
||||
INST_CONCAT_STK, /* 169 */
|
||||
INST_STR_UPPER, INST_STR_LOWER, INST_STR_TITLE /* 170-172 */
|
||||
INST_STR_UPPER, INST_STR_LOWER, INST_STR_TITLE, /* 170-172 */
|
||||
INST_NUM_TYPE /* 180 */
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
+10
-15
@@ -215,7 +215,7 @@ static const CmdInfo builtInCmds[] = {
|
||||
{"continue", Tcl_ContinueObjCmd, TclCompileContinueCmd, NULL, CMD_IS_SAFE},
|
||||
{"coroutine", NULL, NULL, TclNRCoroutineObjCmd, CMD_IS_SAFE},
|
||||
{"error", Tcl_ErrorObjCmd, TclCompileErrorCmd, NULL, CMD_IS_SAFE},
|
||||
{"eval", Tcl_EvalObjCmd, NULL, TclNREvalObjCmd, CMD_IS_SAFE},
|
||||
{"eval", Tcl_EvalObjCmd, TclCompileEvalCmd, TclNREvalObjCmd, CMD_IS_SAFE},
|
||||
{"expr", Tcl_ExprObjCmd, TclCompileExprCmd, TclNRExprObjCmd, CMD_IS_SAFE},
|
||||
{"for", Tcl_ForObjCmd, TclCompileForCmd, TclNRForObjCmd, CMD_IS_SAFE},
|
||||
{"foreach", Tcl_ForeachObjCmd, TclCompileForeachCmd, TclNRForeachCmd, CMD_IS_SAFE},
|
||||
@@ -259,7 +259,7 @@ static const CmdInfo builtInCmds[] = {
|
||||
{"variable", Tcl_VariableObjCmd, TclCompileVariableCmd, NULL, CMD_IS_SAFE},
|
||||
{"while", Tcl_WhileObjCmd, TclCompileWhileCmd, TclNRWhileObjCmd, CMD_IS_SAFE},
|
||||
{"yield", NULL, TclCompileYieldCmd, TclNRYieldObjCmd, CMD_IS_SAFE},
|
||||
{"yieldto", NULL, NULL, TclNRYieldToObjCmd, CMD_IS_SAFE},
|
||||
{"yieldto", NULL, TclCompileYieldToCmd, TclNRYieldToObjCmd, CMD_IS_SAFE},
|
||||
|
||||
/*
|
||||
* Commands in the OS-interface. Note that many of these are unsafe.
|
||||
@@ -8416,8 +8416,7 @@ TclNRYieldToObjCmd(
|
||||
{
|
||||
CoroutineData *corPtr = iPtr->execEnvPtr->corPtr;
|
||||
Tcl_Obj *listPtr, *nsObjPtr;
|
||||
Tcl_Namespace *nsPtr = (Tcl_Namespace *) iPtr->varFramePtr->nsPtr;
|
||||
Tcl_Namespace *ns1Ptr;
|
||||
Tcl_Namespace *nsPtr = TclGetCurrentNamespace(interp);
|
||||
|
||||
if (objc < 2) {
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "command ?arg ...?");
|
||||
@@ -8431,11 +8430,13 @@ TclNRYieldToObjCmd(
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Add the tailcall in the caller env, then just yield.
|
||||
*
|
||||
* This is essentially code from TclNRTailcallObjCmd
|
||||
*/
|
||||
if (((Namespace *) nsPtr)->flags & NS_DYING) {
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"yieldto called in deleted namespace", -1));
|
||||
Tcl_SetErrorCode(interp, "TCL", "COROUTINE", "YIELDTO_IN_DELETED",
|
||||
NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Add the tailcall in the caller env, then just yield.
|
||||
@@ -8444,15 +8445,9 @@ TclNRYieldToObjCmd(
|
||||
*/
|
||||
|
||||
listPtr = Tcl_NewListObj(objc, objv);
|
||||
|
||||
nsObjPtr = Tcl_NewStringObj(nsPtr->fullName, -1);
|
||||
if ((TCL_OK != TclGetNamespaceFromObj(interp, nsObjPtr, &ns1Ptr))
|
||||
|| (nsPtr != ns1Ptr)) {
|
||||
Tcl_Panic("yieldto failed to find the proper namespace");
|
||||
}
|
||||
TclListObjSetElement(interp, listPtr, 0, nsObjPtr);
|
||||
|
||||
|
||||
/*
|
||||
* Add the callback in the caller's env, then instruct TEBC to yield.
|
||||
*/
|
||||
|
||||
+2
-35
@@ -18,6 +18,7 @@
|
||||
|
||||
#include "tclInt.h"
|
||||
#include "tclRegexp.h"
|
||||
#include "tclStringTrim.h"
|
||||
|
||||
static inline Tcl_Obj * During(Tcl_Interp *interp, int resultCode,
|
||||
Tcl_Obj *oldOptions, Tcl_Obj *errorInfo);
|
||||
@@ -31,40 +32,6 @@ static int TryPostHandler(ClientData data[], Tcl_Interp *interp,
|
||||
int result);
|
||||
static int UniCharIsAscii(int character);
|
||||
static int UniCharIsHexDigit(int character);
|
||||
|
||||
/*
|
||||
* 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]
|
||||
*
|
||||
* Synch with tclCompCmdsSZ.c
|
||||
*/
|
||||
|
||||
#define DEFAULT_TRIM_SET \
|
||||
"\x09\x0a\x0b\x0c\x0d " /* ASCII */\
|
||||
"\xc0\x80" /* nul (U+0000) */\
|
||||
"\xc2\x85" /* next line (U+0085) */\
|
||||
"\xc2\xa0" /* non-breaking space (U+00a0) */\
|
||||
"\xe1\x9a\x80" /* ogham space mark (U+1680) */ \
|
||||
"\xe1\xa0\x8e" /* mongolian vowel separator (U+180e) */\
|
||||
"\xe2\x80\x80" /* en quad (U+2000) */\
|
||||
"\xe2\x80\x81" /* em quad (U+2001) */\
|
||||
"\xe2\x80\x82" /* en space (U+2002) */\
|
||||
"\xe2\x80\x83" /* em space (U+2003) */\
|
||||
"\xe2\x80\x84" /* three-per-em space (U+2004) */\
|
||||
"\xe2\x80\x85" /* four-per-em space (U+2005) */\
|
||||
"\xe2\x80\x86" /* six-per-em space (U+2006) */\
|
||||
"\xe2\x80\x87" /* figure space (U+2007) */\
|
||||
"\xe2\x80\x88" /* punctuation space (U+2008) */\
|
||||
"\xe2\x80\x89" /* thin space (U+2009) */\
|
||||
"\xe2\x80\x8a" /* hair space (U+200a) */\
|
||||
"\xe2\x80\x8b" /* zero width space (U+200b) */\
|
||||
"\xe2\x80\xa8" /* line separator (U+2028) */\
|
||||
"\xe2\x80\xa9" /* paragraph separator (U+2029) */\
|
||||
"\xe2\x80\xaf" /* narrow no-break space (U+202f) */\
|
||||
"\xe2\x81\x9f" /* medium mathematical space (U+205f) */\
|
||||
"\xe2\x81\xa0" /* word joiner (U+2060) */\
|
||||
"\xe3\x80\x80" /* ideographic space (U+3000) */\
|
||||
"\xef\xbb\xbf" /* zero width no-break space (U+feff) */
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
@@ -3332,7 +3299,7 @@ TclInitStringCmd(
|
||||
{"equal", StringEqualCmd, TclCompileStringEqualCmd, NULL, NULL, 0},
|
||||
{"first", StringFirstCmd, TclCompileStringFirstCmd, NULL, NULL, 0},
|
||||
{"index", StringIndexCmd, TclCompileStringIndexCmd, NULL, NULL, 0},
|
||||
{"is", StringIsCmd, NULL, NULL, NULL, 0},
|
||||
{"is", StringIsCmd, TclCompileStringIsCmd, NULL, NULL, 0},
|
||||
{"last", StringLastCmd, TclCompileStringLastCmd, NULL, NULL, 0},
|
||||
{"length", StringLenCmd, TclCompileStringLenCmd, NULL, NULL, 0},
|
||||
{"map", StringMapCmd, TclCompileStringMapCmd, NULL, NULL, 0},
|
||||
|
||||
+66
-9
@@ -65,13 +65,6 @@ const AuxDataType tclDictUpdateInfoType = {
|
||||
FreeDictUpdateInfo, /* freeProc */
|
||||
PrintDictUpdateInfo /* printProc */
|
||||
};
|
||||
|
||||
/*
|
||||
* The definition of what whitespace is stripped when [concat]enating. Must be
|
||||
* kept in synch with tclUtil.c
|
||||
*/
|
||||
|
||||
#define CONCAT_WS " \f\v\r\t\n"
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
@@ -285,7 +278,7 @@ TclCompileArraySetCmd(
|
||||
|
||||
if (isDataValid && !isDataEven) {
|
||||
PushStringLiteral(envPtr, "list must have an even number of elements");
|
||||
PushStringLiteral(envPtr, "-errorCode {TCL ARGUMENT FORMAT}");
|
||||
PushStringLiteral(envPtr, "-errorcode {TCL ARGUMENT FORMAT}");
|
||||
TclEmitInstInt4(INST_RETURN_IMM, TCL_ERROR, envPtr);
|
||||
TclEmitInt4( 0, envPtr);
|
||||
goto done;
|
||||
@@ -380,7 +373,7 @@ TclCompileArraySetCmd(
|
||||
offsetFwd = CurrentOffset(envPtr);
|
||||
TclEmitInstInt1(INST_JUMP_FALSE1, 0, envPtr);
|
||||
PushStringLiteral(envPtr, "list must have an even number of elements");
|
||||
PushStringLiteral(envPtr, "-errorCode {TCL ARGUMENT FORMAT}");
|
||||
PushStringLiteral(envPtr, "-errorcode {TCL ARGUMENT FORMAT}");
|
||||
TclEmitInstInt4(INST_RETURN_IMM, TCL_ERROR, envPtr);
|
||||
TclEmitInt4( 0, envPtr);
|
||||
TclAdjustStackDepth(-1, envPtr);
|
||||
@@ -2213,6 +2206,70 @@ TclCompileErrorCmd(
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* TclCompileEvalCmd --
|
||||
*
|
||||
* Procedure called to compile the "eval" command.
|
||||
*
|
||||
* Results:
|
||||
* Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
|
||||
* evaluation to runtime.
|
||||
*
|
||||
* Side effects:
|
||||
* Instructions are added to envPtr to execute the "eval" command at
|
||||
* runtime.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int
|
||||
TclCompileEvalCmd(
|
||||
Tcl_Interp *interp, /* Used for context. */
|
||||
Tcl_Parse *parsePtr, /* Points to a parse structure for the command
|
||||
* created by Tcl_ParseCommand. */
|
||||
Command *cmdPtr, /* Points to defintion of command being
|
||||
* compiled. */
|
||||
CompileEnv *envPtr) /* Holds resulting instructions. */
|
||||
{
|
||||
Tcl_Token *tokenPtr;
|
||||
DefineLineInformation; /* TIP #280 */
|
||||
int i;
|
||||
|
||||
/*
|
||||
* Error case: no arguments at all.
|
||||
*/
|
||||
|
||||
if (parsePtr->numWords < 2) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
tokenPtr = TokenAfter(parsePtr->tokenPtr);
|
||||
|
||||
/*
|
||||
* Must push, concatenate (when more than one word) and eval. Note that
|
||||
* when we evaluate, we must first duplicate to ensure that a reference to
|
||||
* the script is kept for the duration of the evaluation.
|
||||
*/
|
||||
|
||||
for (i=1 ; i<parsePtr->numWords ; i++) {
|
||||
CompileWord(envPtr, tokenPtr, interp, i);
|
||||
tokenPtr = TokenAfter(tokenPtr);
|
||||
}
|
||||
|
||||
if (i > 2) {
|
||||
TclEmitInstInt4( INST_CONCAT_STK, i-1, envPtr);
|
||||
}
|
||||
|
||||
TclEmitOpcode( INST_DUP, envPtr);
|
||||
TclEmitOpcode( INST_EVAL_STK, envPtr);
|
||||
TclEmitInstInt4( INST_REVERSE, 2, envPtr);
|
||||
TclEmitOpcode( INST_POP, envPtr);
|
||||
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
|
||||
@@ -1955,6 +1955,28 @@ TclCompileNamespaceCodeCmd(
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
int
|
||||
TclCompileNamespaceOriginCmd(
|
||||
Tcl_Interp *interp, /* Used for error reporting. */
|
||||
Tcl_Parse *parsePtr, /* Points to a parse structure for the command
|
||||
* created by Tcl_ParseCommand. */
|
||||
Command *cmdPtr, /* Points to defintion of command being
|
||||
* compiled. */
|
||||
CompileEnv *envPtr) /* Holds resulting instructions. */
|
||||
{
|
||||
Tcl_Token *tokenPtr;
|
||||
DefineLineInformation; /* TIP #280 */
|
||||
|
||||
if (parsePtr->numWords != 2) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
tokenPtr = TokenAfter(parsePtr->tokenPtr);
|
||||
|
||||
CompileWord(envPtr, tokenPtr, interp, 1);
|
||||
TclEmitOpcode( INST_ORIGIN_COMMAND, envPtr);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
int
|
||||
TclCompileNamespaceQualifiersCmd(
|
||||
Tcl_Interp *interp, /* Used for error reporting. */
|
||||
@@ -3017,6 +3039,66 @@ IndexTailVarIfKnown(
|
||||
return localIndex;
|
||||
}
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------
|
||||
*
|
||||
* TclCompileObjectNextCmd, TclCompileObjectSelfCmd --
|
||||
*
|
||||
* Compilations of the TclOO utility commands [next] and [self].
|
||||
*
|
||||
* ----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int
|
||||
TclCompileObjectNextCmd(
|
||||
Tcl_Interp *interp, /* Used for error reporting. */
|
||||
Tcl_Parse *parsePtr, /* Points to a parse structure for the command
|
||||
* created by Tcl_ParseCommand. */
|
||||
Command *cmdPtr, /* Points to defintion of command being
|
||||
* compiled. */
|
||||
CompileEnv *envPtr) /* Holds resulting instructions. */
|
||||
{
|
||||
DefineLineInformation; /* TIP #280 */
|
||||
Tcl_Token *tokenPtr = parsePtr->tokenPtr;
|
||||
int i;
|
||||
|
||||
if (parsePtr->numWords > 255) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
for (i=0 ; i<parsePtr->numWords ; i++) {
|
||||
CompileWord(envPtr, tokenPtr, interp, i);
|
||||
tokenPtr = TokenAfter(tokenPtr);
|
||||
}
|
||||
TclEmitInstInt1( INST_TCLOO_NEXT, i, envPtr);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
int
|
||||
TclCompileObjectNextToCmd(
|
||||
Tcl_Interp *interp, /* Used for error reporting. */
|
||||
Tcl_Parse *parsePtr, /* Points to a parse structure for the command
|
||||
* created by Tcl_ParseCommand. */
|
||||
Command *cmdPtr, /* Points to defintion of command being
|
||||
* compiled. */
|
||||
CompileEnv *envPtr) /* Holds resulting instructions. */
|
||||
{
|
||||
DefineLineInformation; /* TIP #280 */
|
||||
Tcl_Token *tokenPtr = parsePtr->tokenPtr;
|
||||
int i;
|
||||
|
||||
if (parsePtr->numWords < 2 || parsePtr->numWords > 255) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
for (i=0 ; i<parsePtr->numWords ; i++) {
|
||||
CompileWord(envPtr, tokenPtr, interp, i);
|
||||
tokenPtr = TokenAfter(tokenPtr);
|
||||
}
|
||||
TclEmitInstInt1( INST_TCLOO_NEXT_CLASS, i, envPtr);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
int
|
||||
TclCompileObjectSelfCmd(
|
||||
Tcl_Interp *interp, /* Used for error reporting. */
|
||||
|
||||
+364
-36
@@ -17,6 +17,7 @@
|
||||
|
||||
#include "tclInt.h"
|
||||
#include "tclCompile.h"
|
||||
#include "tclStringTrim.h"
|
||||
|
||||
/*
|
||||
* Prototypes for procedures defined later in this file:
|
||||
@@ -423,6 +424,284 @@ TclCompileStringIndexCmd(
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
int
|
||||
TclCompileStringIsCmd(
|
||||
Tcl_Interp *interp, /* Used for error reporting. */
|
||||
Tcl_Parse *parsePtr, /* Points to a parse structure for the command
|
||||
* created by Tcl_ParseCommand. */
|
||||
Command *cmdPtr, /* Points to defintion of command being
|
||||
* compiled. */
|
||||
CompileEnv *envPtr) /* Holds resulting instructions. */
|
||||
{
|
||||
DefineLineInformation; /* TIP #280 */
|
||||
Tcl_Token *tokenPtr = TokenAfter(parsePtr->tokenPtr);
|
||||
static const char *const isClasses[] = {
|
||||
"alnum", "alpha", "ascii", "control",
|
||||
"boolean", "digit", "double", "entier",
|
||||
"false", "graph", "integer", "list",
|
||||
"lower", "print", "punct", "space",
|
||||
"true", "upper", "wideinteger", "wordchar",
|
||||
"xdigit", NULL
|
||||
};
|
||||
enum isClasses {
|
||||
STR_IS_ALNUM, STR_IS_ALPHA, STR_IS_ASCII, STR_IS_CONTROL,
|
||||
STR_IS_BOOL, STR_IS_DIGIT, STR_IS_DOUBLE, STR_IS_ENTIER,
|
||||
STR_IS_FALSE, STR_IS_GRAPH, STR_IS_INT, STR_IS_LIST,
|
||||
STR_IS_LOWER, STR_IS_PRINT, STR_IS_PUNCT, STR_IS_SPACE,
|
||||
STR_IS_TRUE, STR_IS_UPPER, STR_IS_WIDE, STR_IS_WORD,
|
||||
STR_IS_XDIGIT
|
||||
};
|
||||
int t, range, allowEmpty = 0, end;
|
||||
InstStringClassType strClassType;
|
||||
Tcl_Obj *isClass;
|
||||
|
||||
if (parsePtr->numWords < 3 || parsePtr->numWords > 6) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
isClass = Tcl_NewObj();
|
||||
if (!TclWordKnownAtCompileTime(tokenPtr, isClass)) {
|
||||
Tcl_DecrRefCount(isClass);
|
||||
return TCL_ERROR;
|
||||
} else if (Tcl_GetIndexFromObj(interp, isClass, isClasses, "class", 0,
|
||||
&t) != TCL_OK) {
|
||||
Tcl_DecrRefCount(isClass);
|
||||
TclCompileSyntaxError(interp, envPtr);
|
||||
return TCL_OK;
|
||||
}
|
||||
Tcl_DecrRefCount(isClass);
|
||||
|
||||
#define GotLiteral(tokenPtr, word) \
|
||||
((tokenPtr)->type == TCL_TOKEN_SIMPLE_WORD && \
|
||||
(tokenPtr)[1].size > 1 && \
|
||||
(tokenPtr)[1].start[0] == word[0] && \
|
||||
strncmp((tokenPtr)[1].start, (word), (tokenPtr)[1].size) == 0)
|
||||
|
||||
/*
|
||||
* Cannot handle the -failindex option at all, and that's the only legal
|
||||
* way to have more than 4 arguments.
|
||||
*/
|
||||
|
||||
if (parsePtr->numWords != 3 && parsePtr->numWords != 4) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
tokenPtr = TokenAfter(tokenPtr);
|
||||
if (parsePtr->numWords == 3) {
|
||||
allowEmpty = 1;
|
||||
} else {
|
||||
if (!GotLiteral(tokenPtr, "-strict")) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
tokenPtr = TokenAfter(tokenPtr);
|
||||
}
|
||||
#undef GotLiteral
|
||||
|
||||
/*
|
||||
* Compile the code. There are several main classes of check here.
|
||||
* 1. Character classes
|
||||
* 2. Booleans
|
||||
* 3. Integers
|
||||
* 4. Floats
|
||||
* 5. Lists
|
||||
*/
|
||||
|
||||
CompileWord(envPtr, tokenPtr, interp, parsePtr->numWords-1);
|
||||
|
||||
switch ((enum isClasses) t) {
|
||||
case STR_IS_ALNUM:
|
||||
strClassType = STR_CLASS_ALNUM;
|
||||
goto compileStrClass;
|
||||
case STR_IS_ALPHA:
|
||||
strClassType = STR_CLASS_ALPHA;
|
||||
goto compileStrClass;
|
||||
case STR_IS_ASCII:
|
||||
strClassType = STR_CLASS_ASCII;
|
||||
goto compileStrClass;
|
||||
case STR_IS_CONTROL:
|
||||
strClassType = STR_CLASS_CONTROL;
|
||||
goto compileStrClass;
|
||||
case STR_IS_DIGIT:
|
||||
strClassType = STR_CLASS_DIGIT;
|
||||
goto compileStrClass;
|
||||
case STR_IS_GRAPH:
|
||||
strClassType = STR_CLASS_GRAPH;
|
||||
goto compileStrClass;
|
||||
case STR_IS_LOWER:
|
||||
strClassType = STR_CLASS_LOWER;
|
||||
goto compileStrClass;
|
||||
case STR_IS_PRINT:
|
||||
strClassType = STR_CLASS_PRINT;
|
||||
goto compileStrClass;
|
||||
case STR_IS_PUNCT:
|
||||
strClassType = STR_CLASS_PUNCT;
|
||||
goto compileStrClass;
|
||||
case STR_IS_SPACE:
|
||||
strClassType = STR_CLASS_SPACE;
|
||||
goto compileStrClass;
|
||||
case STR_IS_UPPER:
|
||||
strClassType = STR_CLASS_UPPER;
|
||||
goto compileStrClass;
|
||||
case STR_IS_WORD:
|
||||
strClassType = STR_CLASS_WORD;
|
||||
goto compileStrClass;
|
||||
case STR_IS_XDIGIT:
|
||||
strClassType = STR_CLASS_XDIGIT;
|
||||
compileStrClass:
|
||||
if (allowEmpty) {
|
||||
OP1( STR_CLASS, strClassType);
|
||||
} else {
|
||||
int over, over2;
|
||||
|
||||
OP( DUP);
|
||||
OP1( STR_CLASS, strClassType);
|
||||
JUMP1( JUMP_TRUE, over);
|
||||
OP( POP);
|
||||
PUSH( "0");
|
||||
JUMP1( JUMP, over2);
|
||||
FIXJUMP1(over);
|
||||
PUSH( "");
|
||||
OP( STR_NEQ);
|
||||
FIXJUMP1(over2);
|
||||
}
|
||||
return TCL_OK;
|
||||
|
||||
case STR_IS_BOOL:
|
||||
case STR_IS_FALSE:
|
||||
case STR_IS_TRUE:
|
||||
OP( TRY_CVT_TO_BOOLEAN);
|
||||
switch (t) {
|
||||
int over, over2;
|
||||
|
||||
case STR_IS_BOOL:
|
||||
if (allowEmpty) {
|
||||
JUMP1( JUMP_TRUE, over);
|
||||
PUSH( "");
|
||||
OP( STR_EQ);
|
||||
JUMP1( JUMP, over2);
|
||||
FIXJUMP1(over);
|
||||
OP( POP);
|
||||
PUSH( "1");
|
||||
FIXJUMP1(over2);
|
||||
} else {
|
||||
OP4( REVERSE, 2);
|
||||
OP( POP);
|
||||
}
|
||||
return TCL_OK;
|
||||
case STR_IS_TRUE:
|
||||
JUMP1( JUMP_TRUE, over);
|
||||
if (allowEmpty) {
|
||||
PUSH( "");
|
||||
OP( STR_EQ);
|
||||
} else {
|
||||
OP( POP);
|
||||
PUSH( "0");
|
||||
}
|
||||
FIXJUMP1( over);
|
||||
OP( LNOT);
|
||||
OP( LNOT);
|
||||
return TCL_OK;
|
||||
case STR_IS_FALSE:
|
||||
JUMP1( JUMP_TRUE, over);
|
||||
if (allowEmpty) {
|
||||
PUSH( "");
|
||||
OP( STR_NEQ);
|
||||
} else {
|
||||
OP( POP);
|
||||
PUSH( "1");
|
||||
}
|
||||
FIXJUMP1( over);
|
||||
OP( LNOT);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
case STR_IS_DOUBLE: {
|
||||
int satisfied, isEmpty;
|
||||
|
||||
if (allowEmpty) {
|
||||
OP( DUP);
|
||||
PUSH( "");
|
||||
OP( STR_EQ);
|
||||
JUMP1( JUMP_TRUE, isEmpty);
|
||||
OP( NUM_TYPE);
|
||||
JUMP1( JUMP_TRUE, satisfied);
|
||||
PUSH( "0");
|
||||
JUMP1( JUMP, end);
|
||||
FIXJUMP1( isEmpty);
|
||||
OP( POP);
|
||||
FIXJUMP1( satisfied);
|
||||
} else {
|
||||
OP( NUM_TYPE);
|
||||
JUMP1( JUMP_TRUE, satisfied);
|
||||
PUSH( "0");
|
||||
JUMP1( JUMP, end);
|
||||
TclAdjustStackDepth(-1, envPtr);
|
||||
FIXJUMP1( satisfied);
|
||||
}
|
||||
PUSH( "1");
|
||||
FIXJUMP1( end);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
case STR_IS_INT:
|
||||
case STR_IS_WIDE:
|
||||
case STR_IS_ENTIER:
|
||||
if (allowEmpty) {
|
||||
int testNumType;
|
||||
|
||||
OP( DUP);
|
||||
OP( NUM_TYPE);
|
||||
OP( DUP);
|
||||
JUMP1( JUMP_TRUE, testNumType);
|
||||
OP( POP);
|
||||
PUSH( "");
|
||||
OP( STR_EQ);
|
||||
JUMP1( JUMP, end);
|
||||
TclAdjustStackDepth(1, envPtr);
|
||||
FIXJUMP1( testNumType);
|
||||
OP4( REVERSE, 2);
|
||||
OP( POP);
|
||||
} else {
|
||||
OP( NUM_TYPE);
|
||||
OP( DUP);
|
||||
JUMP1( JUMP_FALSE, end);
|
||||
}
|
||||
|
||||
switch (t) {
|
||||
case STR_IS_INT:
|
||||
PUSH( "1");
|
||||
OP( EQ);
|
||||
break;
|
||||
case STR_IS_WIDE:
|
||||
PUSH( "2");
|
||||
OP( LE);
|
||||
break;
|
||||
case STR_IS_ENTIER:
|
||||
PUSH( "3");
|
||||
OP( LE);
|
||||
break;
|
||||
}
|
||||
FIXJUMP1( end);
|
||||
return TCL_OK;
|
||||
|
||||
case STR_IS_LIST:
|
||||
range = TclCreateExceptRange(CATCH_EXCEPTION_RANGE, envPtr);
|
||||
OP4( BEGIN_CATCH4, range);
|
||||
ExceptionRangeStarts(envPtr, range);
|
||||
OP( DUP);
|
||||
OP( LIST_LENGTH);
|
||||
OP( POP);
|
||||
ExceptionRangeEnds(envPtr, range);
|
||||
ExceptionRangeTarget(envPtr, range, catchOffset);
|
||||
OP( POP);
|
||||
OP( PUSH_RETURN_CODE);
|
||||
OP( END_CATCH);
|
||||
OP( LNOT);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
return TclCompileBasicMin0ArgCmd(interp, parsePtr, cmdPtr, envPtr);
|
||||
}
|
||||
|
||||
int
|
||||
TclCompileStringMatchCmd(
|
||||
Tcl_Interp *interp, /* Used for error reporting. */
|
||||
@@ -700,8 +979,8 @@ TclCompileStringReplaceCmd(
|
||||
|
||||
/*
|
||||
* We handle these replacements specially: first character (where
|
||||
* idx1=idx2=0) and suffixes (where idx1=idx2=INDEX_END). Anything else
|
||||
* and the semantics get rather screwy.
|
||||
* idx1=idx2=0) and last character (where idx1=idx2=INDEX_END). Anything
|
||||
* else and the semantics get rather screwy.
|
||||
*/
|
||||
|
||||
if (idx1 == 0 && idx2 == 0) {
|
||||
@@ -787,37 +1066,6 @@ TclCompileStringReplaceCmd(
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Synch with tclCmdMZ.c
|
||||
*/
|
||||
|
||||
#define DEFAULT_TRIM_SET \
|
||||
"\x09\x0a\x0b\x0c\x0d " /* ASCII */\
|
||||
"\xc0\x80" /* nul (U+0000) */\
|
||||
"\xc2\x85" /* next line (U+0085) */\
|
||||
"\xc2\xa0" /* non-breaking space (U+00a0) */\
|
||||
"\xe1\x9a\x80" /* ogham space mark (U+1680) */ \
|
||||
"\xe1\xa0\x8e" /* mongolian vowel separator (U+180e) */\
|
||||
"\xe2\x80\x80" /* en quad (U+2000) */\
|
||||
"\xe2\x80\x81" /* em quad (U+2001) */\
|
||||
"\xe2\x80\x82" /* en space (U+2002) */\
|
||||
"\xe2\x80\x83" /* em space (U+2003) */\
|
||||
"\xe2\x80\x84" /* three-per-em space (U+2004) */\
|
||||
"\xe2\x80\x85" /* four-per-em space (U+2005) */\
|
||||
"\xe2\x80\x86" /* six-per-em space (U+2006) */\
|
||||
"\xe2\x80\x87" /* figure space (U+2007) */\
|
||||
"\xe2\x80\x88" /* punctuation space (U+2008) */\
|
||||
"\xe2\x80\x89" /* thin space (U+2009) */\
|
||||
"\xe2\x80\x8a" /* hair space (U+200a) */\
|
||||
"\xe2\x80\x8b" /* zero width space (U+200b) */\
|
||||
"\xe2\x80\xa8" /* line separator (U+2028) */\
|
||||
"\xe2\x80\xa9" /* paragraph separator (U+2029) */\
|
||||
"\xe2\x80\xaf" /* narrow no-break space (U+202f) */\
|
||||
"\xe2\x81\x9f" /* medium mathematical space (U+205f) */\
|
||||
"\xe2\x81\xa0" /* word joiner (U+2060) */\
|
||||
"\xe3\x80\x80" /* ideographic space (U+3000) */\
|
||||
"\xef\xbb\xbf" /* zero width no-break space (U+feff) */
|
||||
|
||||
int
|
||||
TclCompileStringTrimLCmd(
|
||||
Tcl_Interp *interp, /* Used for error reporting. */
|
||||
@@ -840,7 +1088,7 @@ TclCompileStringTrimLCmd(
|
||||
tokenPtr = TokenAfter(tokenPtr);
|
||||
CompileWord(envPtr, tokenPtr, interp, 2);
|
||||
} else {
|
||||
PushLiteral(envPtr, DEFAULT_TRIM_SET, strlen(DEFAULT_TRIM_SET));
|
||||
PushStringLiteral(envPtr, DEFAULT_TRIM_SET);
|
||||
}
|
||||
OP( STR_TRIM_LEFT);
|
||||
return TCL_OK;
|
||||
@@ -868,7 +1116,7 @@ TclCompileStringTrimRCmd(
|
||||
tokenPtr = TokenAfter(tokenPtr);
|
||||
CompileWord(envPtr, tokenPtr, interp, 2);
|
||||
} else {
|
||||
PushLiteral(envPtr, DEFAULT_TRIM_SET, strlen(DEFAULT_TRIM_SET));
|
||||
PushStringLiteral(envPtr, DEFAULT_TRIM_SET);
|
||||
}
|
||||
OP( STR_TRIM_RIGHT);
|
||||
return TCL_OK;
|
||||
@@ -896,7 +1144,7 @@ TclCompileStringTrimCmd(
|
||||
tokenPtr = TokenAfter(tokenPtr);
|
||||
CompileWord(envPtr, tokenPtr, interp, 2);
|
||||
} else {
|
||||
PushLiteral(envPtr, DEFAULT_TRIM_SET, strlen(DEFAULT_TRIM_SET));
|
||||
PushStringLiteral(envPtr, DEFAULT_TRIM_SET);
|
||||
}
|
||||
OP( STR_TRIM);
|
||||
return TCL_OK;
|
||||
@@ -968,6 +1216,41 @@ TclCompileStringToTitleCmd(
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Support definitions for the [string is] compilation.
|
||||
*/
|
||||
|
||||
static int
|
||||
UniCharIsAscii(
|
||||
int character)
|
||||
{
|
||||
return (character >= 0) && (character < 0x80);
|
||||
}
|
||||
|
||||
static int
|
||||
UniCharIsHexDigit(
|
||||
int character)
|
||||
{
|
||||
return (character >= 0) && (character < 0x80) && isxdigit(character);
|
||||
}
|
||||
|
||||
StringClassDesc const tclStringClassTable[] = {
|
||||
{"alnum", Tcl_UniCharIsAlnum},
|
||||
{"alpha", Tcl_UniCharIsAlpha},
|
||||
{"ascii", UniCharIsAscii},
|
||||
{"control", Tcl_UniCharIsControl},
|
||||
{"digit", Tcl_UniCharIsDigit},
|
||||
{"graph", Tcl_UniCharIsGraph},
|
||||
{"lower", Tcl_UniCharIsLower},
|
||||
{"print", Tcl_UniCharIsPrint},
|
||||
{"punct", Tcl_UniCharIsPunct},
|
||||
{"space", Tcl_UniCharIsSpace},
|
||||
{"upper", Tcl_UniCharIsUpper},
|
||||
{"word", Tcl_UniCharIsWordChar},
|
||||
{"xdigit", UniCharIsHexDigit},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
@@ -3474,6 +3757,51 @@ TclCompileYieldCmd(
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* TclCompileYieldToCmd --
|
||||
*
|
||||
* Procedure called to compile the "yieldto" command.
|
||||
*
|
||||
* Results:
|
||||
* Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
|
||||
* evaluation to runtime.
|
||||
*
|
||||
* Side effects:
|
||||
* Instructions are added to envPtr to execute the "yieldto" command at
|
||||
* runtime.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int
|
||||
TclCompileYieldToCmd(
|
||||
Tcl_Interp *interp, /* Used for error reporting. */
|
||||
Tcl_Parse *parsePtr, /* Points to a parse structure for the command
|
||||
* created by Tcl_ParseCommand. */
|
||||
Command *cmdPtr, /* Points to defintion of command being
|
||||
* compiled. */
|
||||
CompileEnv *envPtr) /* Holds resulting instructions. */
|
||||
{
|
||||
DefineLineInformation; /* TIP #280 */
|
||||
Tcl_Token *tokenPtr = TokenAfter(parsePtr->tokenPtr);
|
||||
int i;
|
||||
|
||||
if (parsePtr->numWords < 2) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
OP( NS_CURRENT);
|
||||
for (i = 1 ; i < parsePtr->numWords ; i++) {
|
||||
CompileWord(envPtr, tokenPtr, interp, i);
|
||||
tokenPtr = TokenAfter(tokenPtr);
|
||||
}
|
||||
OP4( LIST, i);
|
||||
OP( YIELD_TO_INVOKE);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
|
||||
+48
-4
@@ -493,6 +493,7 @@ InstructionDesc const tclInstructionTable[] = {
|
||||
* qualified version, or produces the empty string if no such command
|
||||
* exists. Never generates errors.
|
||||
* Stack: ... cmdName => ... fullCmdName */
|
||||
|
||||
{"tclooSelf", 1, +1, 0, {OPERAND_NONE}},
|
||||
/* Push the identity of the current TclOO object (i.e., the name of
|
||||
* its current public access command) on the stack. */
|
||||
@@ -594,23 +595,61 @@ InstructionDesc const tclInstructionTable[] = {
|
||||
* is number of values to concatenate.
|
||||
* Operation: push concat(stk1 stk2 ... stktop) */
|
||||
|
||||
{"strUpper", 1, 0, 0, {OPERAND_NONE}},
|
||||
{"strcaseUpper", 1, 0, 0, {OPERAND_NONE}},
|
||||
/* [string toupper] core: converts whole string to upper case using
|
||||
* the default (extended "C" locale) rules.
|
||||
* Stack: ... string => ... newString */
|
||||
{"strLower", 1, 0, 0, {OPERAND_NONE}},
|
||||
{"strcaseLower", 1, 0, 0, {OPERAND_NONE}},
|
||||
/* [string tolower] core: converts whole string to upper case using
|
||||
* the default (extended "C" locale) rules.
|
||||
* Stack: ... string => ... newString */
|
||||
{"strTitle", 1, 0, 0, {OPERAND_NONE}},
|
||||
{"strcaseTitle", 1, 0, 0, {OPERAND_NONE}},
|
||||
/* [string totitle] core: converts whole string to upper case using
|
||||
* the default (extended "C" locale) rules.
|
||||
* Stack: ... string => ... newString */
|
||||
{"strReplace", 1, -3, 0, {OPERAND_NONE}},
|
||||
{"strreplace", 1, -3, 0, {OPERAND_NONE}},
|
||||
/* [string replace] core: replaces a non-empty range of one string
|
||||
* with the contents of another.
|
||||
* Stack: ... string fromIdx toIdx replacement => ... newString */
|
||||
|
||||
{"originCmd", 1, 0, 0, {OPERAND_NONE}},
|
||||
/* Reports which command was the origin (via namespace import chain)
|
||||
* of the command named on the top of the stack.
|
||||
* Stack: ... cmdName => ... fullOriginalCmdName */
|
||||
|
||||
{"tclooNext", 2, INT_MIN, 1, {OPERAND_UINT1}},
|
||||
/* Call the next item on the TclOO call chain, passing opnd arguments
|
||||
* (min 1, max 255, *includes* "next"). The result of the invoked
|
||||
* method implementation will be pushed on the stack in place of the
|
||||
* arguments (similar to invokeStk).
|
||||
* Stack: ... "next" arg2 arg3 -- argN => ... result */
|
||||
{"tclooNextClass", 2, INT_MIN, 1, {OPERAND_UINT1}},
|
||||
/* Call the following item on the TclOO call chain defined by class
|
||||
* className, passing opnd arguments (min 2, max 255, *includes*
|
||||
* "nextto" and the class name). The result of the invoked method
|
||||
* implementation will be pushed on the stack in place of the
|
||||
* arguments (similar to invokeStk).
|
||||
* Stack: ... "nextto" className arg3 arg4 -- argN => ... result */
|
||||
|
||||
{"yieldToInvoke", 1, 0, 0, {OPERAND_NONE}},
|
||||
/* Makes the current coroutine yield the value at the top of the
|
||||
* stack, invoking the given command/args with resolution in the given
|
||||
* namespace (all packed into a list), and places the list of values
|
||||
* that are the response back on top of the stack when it resumes.
|
||||
* Stack: ... [list ns cmd arg1 ... argN] => ... resumeList */
|
||||
|
||||
{"numericType", 1, 0, 0, {OPERAND_NONE}},
|
||||
/* Pushes the numeric type code of the word at the top of the stack.
|
||||
* Stack: ... value => ... typeCode */
|
||||
{"tryCvtToBoolean", 1, +1, 0, {OPERAND_NONE}},
|
||||
/* Try converting stktop to boolean if possible. No errors.
|
||||
* Stack: ... value => ... value isStrictBool */
|
||||
{"strclass", 2, 0, 1, {OPERAND_SCLS1}},
|
||||
/* See if all the characters of the given string are a member of the
|
||||
* specified (by opnd) character class. Note that an empty string will
|
||||
* satisfy the class check (standard definition of "all").
|
||||
* Stack: ... stringValue => ... boolean */
|
||||
|
||||
{NULL, 0, 0, 0, {OPERAND_NONE}}
|
||||
};
|
||||
|
||||
@@ -5058,6 +5097,11 @@ FormatInstruction(
|
||||
}
|
||||
Tcl_AppendPrintfToObj(bufferObj, "%%v%u ", (unsigned) opnd);
|
||||
break;
|
||||
case OPERAND_SCLS1:
|
||||
opnd = TclGetUInt1AtPtr(pc+numBytes); numBytes++;
|
||||
Tcl_AppendPrintfToObj(bufferObj, "%s ",
|
||||
tclStringClassTable[opnd].name);
|
||||
break;
|
||||
case OPERAND_NONE:
|
||||
default:
|
||||
break;
|
||||
|
||||
+50
-2
@@ -751,6 +751,8 @@ typedef struct ByteCode {
|
||||
#define INST_INFO_LEVEL_NUM 152
|
||||
#define INST_INFO_LEVEL_ARGS 153
|
||||
#define INST_RESOLVE_COMMAND 154
|
||||
|
||||
/* For compilation relating to TclOO */
|
||||
#define INST_TCLOO_SELF 155
|
||||
#define INST_TCLOO_CLASS 156
|
||||
#define INST_TCLOO_NS 157
|
||||
@@ -786,8 +788,19 @@ typedef struct ByteCode {
|
||||
#define INST_STR_TITLE 176
|
||||
#define INST_STR_REPLACE 177
|
||||
|
||||
#define INST_ORIGIN_COMMAND 178
|
||||
|
||||
#define INST_TCLOO_NEXT 179
|
||||
#define INST_TCLOO_NEXT_CLASS 180
|
||||
|
||||
#define INST_YIELD_TO_INVOKE 181
|
||||
|
||||
#define INST_NUM_TYPE 182
|
||||
#define INST_TRY_CVT_TO_BOOLEAN 183
|
||||
#define INST_STR_CLASS 184
|
||||
|
||||
/* The last opcode */
|
||||
#define LAST_INST_OPCODE 177
|
||||
#define LAST_INST_OPCODE 184
|
||||
|
||||
/*
|
||||
* Table describing the Tcl bytecode instructions: their name (for displaying
|
||||
@@ -812,8 +825,9 @@ typedef enum InstOperandType {
|
||||
* variable table. */
|
||||
OPERAND_LVT4, /* Four byte unsigned index into the local
|
||||
* variable table. */
|
||||
OPERAND_AUX4 /* Four byte unsigned index into the aux data
|
||||
OPERAND_AUX4, /* Four byte unsigned index into the aux data
|
||||
* table. */
|
||||
OPERAND_SCLS1 /* Index into tclStringClassTable. */
|
||||
} InstOperandType;
|
||||
|
||||
typedef struct InstructionDesc {
|
||||
@@ -831,6 +845,40 @@ typedef struct InstructionDesc {
|
||||
|
||||
MODULE_SCOPE InstructionDesc const tclInstructionTable[];
|
||||
|
||||
/*
|
||||
* Constants used by INST_STRING_CLASS to indicate character classes. These
|
||||
* correspond closely by name with what [string is] can support, but there is
|
||||
* no requirement to keep the values the same.
|
||||
*/
|
||||
|
||||
typedef enum InstStringClassType {
|
||||
STR_CLASS_ALNUM, /* Unicode alphabet or digit characters. */
|
||||
STR_CLASS_ALPHA, /* Unicode alphabet characters. */
|
||||
STR_CLASS_ASCII, /* Characters in range U+000000..U+00007F. */
|
||||
STR_CLASS_CONTROL, /* Unicode control characters. */
|
||||
STR_CLASS_DIGIT, /* Unicode digit characters. */
|
||||
STR_CLASS_GRAPH, /* Unicode printing characters, excluding
|
||||
* space. */
|
||||
STR_CLASS_LOWER, /* Unicode lower-case alphabet characters. */
|
||||
STR_CLASS_PRINT, /* Unicode printing characters, including
|
||||
* spaces. */
|
||||
STR_CLASS_PUNCT, /* Unicode punctuation characters. */
|
||||
STR_CLASS_SPACE, /* Unicode space characters. */
|
||||
STR_CLASS_UPPER, /* Unicode upper-case alphabet characters. */
|
||||
STR_CLASS_WORD, /* Unicode word (alphabetic, digit, connector
|
||||
* punctuation) characters. */
|
||||
STR_CLASS_XDIGIT /* Characters that can be used as digits in
|
||||
* hexadecimal numbers ([0-9A-Fa-f]). */
|
||||
} InstStringClassType;
|
||||
|
||||
typedef struct StringClassDesc {
|
||||
const char *name; /* Name of the class. */
|
||||
int (*comparator)(int); /* Function to test if a single unicode
|
||||
* character is a member of the class. */
|
||||
} StringClassDesc;
|
||||
|
||||
MODULE_SCOPE StringClassDesc const tclStringClassTable[];
|
||||
|
||||
/*
|
||||
* Compilation of some Tcl constructs such as if commands and the logical or
|
||||
* (||) and logical and (&&) operators in expressions requires the generation
|
||||
|
||||
+896
-459
File diff suppressed because it is too large
Load Diff
@@ -3493,6 +3493,9 @@ MODULE_SCOPE int TclCompileEnsemble(Tcl_Interp *interp,
|
||||
MODULE_SCOPE int TclCompileErrorCmd(Tcl_Interp *interp,
|
||||
Tcl_Parse *parsePtr, Command *cmdPtr,
|
||||
struct CompileEnv *envPtr);
|
||||
MODULE_SCOPE int TclCompileEvalCmd(Tcl_Interp *interp,
|
||||
Tcl_Parse *parsePtr, Command *cmdPtr,
|
||||
struct CompileEnv *envPtr);
|
||||
MODULE_SCOPE int TclCompileExprCmd(Tcl_Interp *interp,
|
||||
Tcl_Parse *parsePtr, Command *cmdPtr,
|
||||
struct CompileEnv *envPtr);
|
||||
@@ -3571,6 +3574,9 @@ MODULE_SCOPE int TclCompileNamespaceCodeCmd(Tcl_Interp *interp,
|
||||
MODULE_SCOPE int TclCompileNamespaceCurrentCmd(Tcl_Interp *interp,
|
||||
Tcl_Parse *parsePtr, Command *cmdPtr,
|
||||
struct CompileEnv *envPtr);
|
||||
MODULE_SCOPE int TclCompileNamespaceOriginCmd(Tcl_Interp *interp,
|
||||
Tcl_Parse *parsePtr, Command *cmdPtr,
|
||||
struct CompileEnv *envPtr);
|
||||
MODULE_SCOPE int TclCompileNamespaceQualifiersCmd(Tcl_Interp *interp,
|
||||
Tcl_Parse *parsePtr, Command *cmdPtr,
|
||||
struct CompileEnv *envPtr);
|
||||
@@ -3586,6 +3592,12 @@ MODULE_SCOPE int TclCompileNamespaceWhichCmd(Tcl_Interp *interp,
|
||||
MODULE_SCOPE int TclCompileNoOp(Tcl_Interp *interp,
|
||||
Tcl_Parse *parsePtr, Command *cmdPtr,
|
||||
struct CompileEnv *envPtr);
|
||||
MODULE_SCOPE int TclCompileObjectNextCmd(Tcl_Interp *interp,
|
||||
Tcl_Parse *parsePtr, Command *cmdPtr,
|
||||
struct CompileEnv *envPtr);
|
||||
MODULE_SCOPE int TclCompileObjectNextToCmd(Tcl_Interp *interp,
|
||||
Tcl_Parse *parsePtr, Command *cmdPtr,
|
||||
struct CompileEnv *envPtr);
|
||||
MODULE_SCOPE int TclCompileObjectSelfCmd(Tcl_Interp *interp,
|
||||
Tcl_Parse *parsePtr, Command *cmdPtr,
|
||||
struct CompileEnv *envPtr);
|
||||
@@ -3613,6 +3625,9 @@ MODULE_SCOPE int TclCompileStringFirstCmd(Tcl_Interp *interp,
|
||||
MODULE_SCOPE int TclCompileStringIndexCmd(Tcl_Interp *interp,
|
||||
Tcl_Parse *parsePtr, Command *cmdPtr,
|
||||
struct CompileEnv *envPtr);
|
||||
MODULE_SCOPE int TclCompileStringIsCmd(Tcl_Interp *interp,
|
||||
Tcl_Parse *parsePtr, Command *cmdPtr,
|
||||
struct CompileEnv *envPtr);
|
||||
MODULE_SCOPE int TclCompileStringLastCmd(Tcl_Interp *interp,
|
||||
Tcl_Parse *parsePtr, Command *cmdPtr,
|
||||
struct CompileEnv *envPtr);
|
||||
@@ -3679,6 +3694,9 @@ MODULE_SCOPE int TclCompileWhileCmd(Tcl_Interp *interp,
|
||||
MODULE_SCOPE int TclCompileYieldCmd(Tcl_Interp *interp,
|
||||
Tcl_Parse *parsePtr, Command *cmdPtr,
|
||||
struct CompileEnv *envPtr);
|
||||
MODULE_SCOPE int TclCompileYieldToCmd(Tcl_Interp *interp,
|
||||
Tcl_Parse *parsePtr, Command *cmdPtr,
|
||||
struct CompileEnv *envPtr);
|
||||
MODULE_SCOPE int TclCompileBasic0ArgCmd(Tcl_Interp *interp,
|
||||
Tcl_Parse *parsePtr, Command *cmdPtr,
|
||||
struct CompileEnv *envPtr);
|
||||
|
||||
+1
-1
@@ -171,7 +171,7 @@ static const EnsembleImplMap defaultNamespaceMap[] = {
|
||||
{"forget", NamespaceForgetCmd, TclCompileBasicMin0ArgCmd, NULL, NULL, 0},
|
||||
{"import", NamespaceImportCmd, TclCompileBasicMin0ArgCmd, NULL, NULL, 0},
|
||||
{"inscope", NamespaceInscopeCmd, NULL, NRNamespaceInscopeCmd, NULL, 0},
|
||||
{"origin", NamespaceOriginCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
|
||||
{"origin", NamespaceOriginCmd, TclCompileNamespaceOriginCmd, NULL, NULL, 0},
|
||||
{"parent", NamespaceParentCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0},
|
||||
{"path", NamespacePathCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0},
|
||||
{"qualifiers", NamespaceQualifiersCmd, TclCompileNamespaceQualifiersCmd, NULL, NULL, 0},
|
||||
|
||||
+6
-4
@@ -437,10 +437,12 @@ InitFoundation(
|
||||
* ensemble.
|
||||
*/
|
||||
|
||||
Tcl_CreateObjCommand(interp, "::oo::Helpers::next", TclOONextObjCmd, NULL,
|
||||
NULL);
|
||||
Tcl_CreateObjCommand(interp, "::oo::Helpers::nextto", TclOONextToObjCmd,
|
||||
NULL, NULL);
|
||||
cmdPtr = (Command *) Tcl_NRCreateCommand(interp, "::oo::Helpers::next",
|
||||
NULL, TclOONextObjCmd, NULL, NULL);
|
||||
cmdPtr->compileProc = TclCompileObjectNextCmd;
|
||||
cmdPtr = (Command *) Tcl_NRCreateCommand(interp, "::oo::Helpers::nextto",
|
||||
NULL, TclOONextToObjCmd, NULL, NULL);
|
||||
cmdPtr->compileProc = TclCompileObjectNextToCmd;
|
||||
cmdPtr = (Command *) Tcl_CreateObjCommand(interp, "::oo::Helpers::self",
|
||||
TclOOSelfObjCmd, NULL, NULL);
|
||||
cmdPtr->compileProc = TclCompileObjectSelfCmd;
|
||||
|
||||
+25
-18
@@ -17,16 +17,11 @@
|
||||
#include "tclOOInt.h"
|
||||
|
||||
static inline Tcl_Object *AddConstructionFinalizer(Tcl_Interp *interp);
|
||||
static int AfterNRDestructor(ClientData data[],
|
||||
Tcl_Interp *interp, int result);
|
||||
static int DecrRefsPostClassConstructor(ClientData data[],
|
||||
Tcl_Interp *interp, int result);
|
||||
static int FinalizeConstruction(ClientData data[],
|
||||
Tcl_Interp *interp, int result);
|
||||
static int FinalizeEval(ClientData data[],
|
||||
Tcl_Interp *interp, int result);
|
||||
static int RestoreFrame(ClientData data[],
|
||||
Tcl_Interp *interp, int result);
|
||||
static Tcl_NRPostProc AfterNRDestructor;
|
||||
static Tcl_NRPostProc DecrRefsPostClassConstructor;
|
||||
static Tcl_NRPostProc FinalizeConstruction;
|
||||
static Tcl_NRPostProc FinalizeEval;
|
||||
static Tcl_NRPostProc NextRestoreFrame;
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------
|
||||
@@ -808,7 +803,7 @@ TclOONextObjCmd(
|
||||
* that this is like [uplevel 1] and not [eval].
|
||||
*/
|
||||
|
||||
TclNRAddCallback(interp, RestoreFrame, framePtr, NULL, NULL, NULL);
|
||||
TclNRAddCallback(interp, NextRestoreFrame, framePtr, NULL,NULL,NULL);
|
||||
iPtr->varFramePtr = framePtr->callerVarPtr;
|
||||
return TclNRObjectContextInvokeNext(interp, context, objc, objv, 1);
|
||||
}
|
||||
@@ -826,6 +821,7 @@ TclOONextToObjCmd(
|
||||
CallContext *contextPtr;
|
||||
int i;
|
||||
Tcl_Object object;
|
||||
const char *methodType;
|
||||
|
||||
/*
|
||||
* Start with sanity checks on the calling context to make sure that we
|
||||
@@ -877,8 +873,8 @@ TclOONextToObjCmd(
|
||||
* context. Note that this is like [uplevel 1] and not [eval].
|
||||
*/
|
||||
|
||||
TclNRAddCallback(interp, RestoreFrame, framePtr, contextPtr,
|
||||
INT2PTR(contextPtr->index), NULL);
|
||||
TclNRAddCallback(interp, NextRestoreFrame, framePtr,
|
||||
contextPtr, INT2PTR(contextPtr->index), NULL);
|
||||
contextPtr->index = i-1;
|
||||
iPtr->varFramePtr = framePtr->callerVarPtr;
|
||||
return TclNRObjectContextInvokeNext(interp,
|
||||
@@ -891,24 +887,35 @@ TclOONextToObjCmd(
|
||||
* is on the chain but unreachable, or not on the chain at all.
|
||||
*/
|
||||
|
||||
if (contextPtr->callPtr->flags & CONSTRUCTOR) {
|
||||
methodType = "constructor";
|
||||
} else if (contextPtr->callPtr->flags & DESTRUCTOR) {
|
||||
methodType = "destructor";
|
||||
} else {
|
||||
methodType = "method";
|
||||
}
|
||||
|
||||
for (i=contextPtr->index ; i>=0 ; i--) {
|
||||
struct MInvoke *miPtr = contextPtr->callPtr->chain + i;
|
||||
|
||||
if (!miPtr->isFilter && miPtr->mPtr->declaringClassPtr == classPtr) {
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"method implementation by \"%s\" not reachable from here",
|
||||
TclGetString(objv[1])));
|
||||
"%s implementation by \"%s\" not reachable from here",
|
||||
methodType, TclGetString(objv[1])));
|
||||
Tcl_SetErrorCode(interp, "TCL", "OO", "CLASS_NOT_REACHABLE",
|
||||
NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
}
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"method has no non-filter implementation by \"%s\"",
|
||||
TclGetString(objv[1])));
|
||||
"%s has no non-filter implementation by \"%s\"",
|
||||
methodType, TclGetString(objv[1])));
|
||||
Tcl_SetErrorCode(interp, "TCL", "OO", "CLASS_NOT_THERE", NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
static int
|
||||
RestoreFrame(
|
||||
NextRestoreFrame(
|
||||
ClientData data[],
|
||||
Tcl_Interp *interp,
|
||||
int result)
|
||||
|
||||
+32
-40
@@ -1855,9 +1855,39 @@ InterpProcNR2(
|
||||
}
|
||||
|
||||
/*
|
||||
* Process the result code.
|
||||
* Free the stack-allocated compiled locals and CallFrame. It is important
|
||||
* to pop the call frame without freeing it first: the compiledLocals
|
||||
* cannot be freed before the frame is popped, as the local variables must
|
||||
* be deleted. But the compiledLocals must be freed first, as they were
|
||||
* allocated later on the stack.
|
||||
*/
|
||||
|
||||
if (result != TCL_OK) {
|
||||
goto process;
|
||||
}
|
||||
|
||||
done:
|
||||
if (TCL_DTRACE_PROC_RESULT_ENABLED()) {
|
||||
int l = iPtr->varFramePtr->isProcCallFrame & FRAME_IS_LAMBDA ? 1 : 0;
|
||||
Tcl_Obj *r = Tcl_GetObjResult(interp);
|
||||
|
||||
TCL_DTRACE_PROC_RESULT(l < iPtr->varFramePtr->objc ?
|
||||
TclGetString(iPtr->varFramePtr->objv[l]) : NULL, result,
|
||||
TclGetString(r), r);
|
||||
}
|
||||
|
||||
freePtr = iPtr->framePtr;
|
||||
Tcl_PopCallFrame(interp); /* Pop but do not free. */
|
||||
TclStackFree(interp, freePtr->compiledLocals);
|
||||
/* Free compiledLocals. */
|
||||
TclStackFree(interp, freePtr); /* Free CallFrame. */
|
||||
return result;
|
||||
|
||||
/*
|
||||
* Process any non-TCL_OK result code.
|
||||
*/
|
||||
|
||||
process:
|
||||
switch (result) {
|
||||
case TCL_RETURN:
|
||||
/*
|
||||
@@ -1892,46 +1922,8 @@ InterpProcNR2(
|
||||
*/
|
||||
|
||||
errorProc(interp, procNameObj);
|
||||
|
||||
default:
|
||||
/*
|
||||
* Process other results (OK and non-standard) by doing nothing
|
||||
* special, skipping directly to the code afterwards that cleans up
|
||||
* associated memory.
|
||||
*
|
||||
* Non-standard results are processed by passing them through quickly.
|
||||
* This means they all work as exceptions, unwinding the stack quickly
|
||||
* and neatly. Who knows how well they are handled by third-party code
|
||||
* though...
|
||||
*/
|
||||
|
||||
(void) 0; /* do nothing */
|
||||
}
|
||||
|
||||
if (TCL_DTRACE_PROC_RESULT_ENABLED()) {
|
||||
int l = iPtr->varFramePtr->isProcCallFrame & FRAME_IS_LAMBDA ? 1 : 0;
|
||||
Tcl_Obj *r = Tcl_GetObjResult(interp);
|
||||
|
||||
TCL_DTRACE_PROC_RESULT(l < iPtr->varFramePtr->objc ?
|
||||
TclGetString(iPtr->varFramePtr->objv[l]) : NULL, result,
|
||||
TclGetString(r), r);
|
||||
}
|
||||
|
||||
/*
|
||||
* Free the stack-allocated compiled locals and CallFrame. It is important
|
||||
* to pop the call frame without freeing it first: the compiledLocals
|
||||
* cannot be freed before the frame is popped, as the local variables must
|
||||
* be deleted. But the compiledLocals must be freed first, as they were
|
||||
* allocated later on the stack.
|
||||
*/
|
||||
|
||||
freePtr = iPtr->framePtr;
|
||||
Tcl_PopCallFrame(interp); /* Pop but do not free. */
|
||||
TclStackFree(interp, freePtr->compiledLocals);
|
||||
/* Free compiledLocals. */
|
||||
TclStackFree(interp, freePtr); /* Free CallFrame. */
|
||||
|
||||
return result;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* tclStringTrim.h --
|
||||
*
|
||||
* This file contains the definition of what characters are to be trimmed
|
||||
* from a string by [string trim] by default. It's only needed by Tcl's
|
||||
* implementation; it does not form a public or private API at all.
|
||||
*
|
||||
* Copyright (c) 1987-1993 The Regents of the University of California.
|
||||
* Copyright (c) 1994-1997 Sun Microsystems, Inc.
|
||||
* Copyright (c) 1998-2000 Scriptics Corporation.
|
||||
* Copyright (c) 2002 ActiveState Corporation.
|
||||
* Copyright (c) 2003-2013 Donal K. Fellows.
|
||||
*
|
||||
* See the file "license.terms" for information on usage and redistribution of
|
||||
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
*/
|
||||
|
||||
#ifndef TCL_STRING_TRIM_H
|
||||
#define TCL_STRING_TRIM_H
|
||||
|
||||
/*
|
||||
* 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]
|
||||
*/
|
||||
|
||||
#define DEFAULT_TRIM_SET \
|
||||
"\x09\x0a\x0b\x0c\x0d " /* ASCII */\
|
||||
"\xc0\x80" /* nul (U+0000) */\
|
||||
"\xc2\x85" /* next line (U+0085) */\
|
||||
"\xc2\xa0" /* non-breaking space (U+00a0) */\
|
||||
"\xe1\x9a\x80" /* ogham space mark (U+1680) */ \
|
||||
"\xe1\xa0\x8e" /* mongolian vowel separator (U+180e) */\
|
||||
"\xe2\x80\x80" /* en quad (U+2000) */\
|
||||
"\xe2\x80\x81" /* em quad (U+2001) */\
|
||||
"\xe2\x80\x82" /* en space (U+2002) */\
|
||||
"\xe2\x80\x83" /* em space (U+2003) */\
|
||||
"\xe2\x80\x84" /* three-per-em space (U+2004) */\
|
||||
"\xe2\x80\x85" /* four-per-em space (U+2005) */\
|
||||
"\xe2\x80\x86" /* six-per-em space (U+2006) */\
|
||||
"\xe2\x80\x87" /* figure space (U+2007) */\
|
||||
"\xe2\x80\x88" /* punctuation space (U+2008) */\
|
||||
"\xe2\x80\x89" /* thin space (U+2009) */\
|
||||
"\xe2\x80\x8a" /* hair space (U+200a) */\
|
||||
"\xe2\x80\x8b" /* zero width space (U+200b) */\
|
||||
"\xe2\x80\xa8" /* line separator (U+2028) */\
|
||||
"\xe2\x80\xa9" /* paragraph separator (U+2029) */\
|
||||
"\xe2\x80\xaf" /* narrow no-break space (U+202f) */\
|
||||
"\xe2\x81\x9f" /* medium mathematical space (U+205f) */\
|
||||
"\xe2\x81\xa0" /* word joiner (U+2060) */\
|
||||
"\xe3\x80\x80" /* ideographic space (U+3000) */\
|
||||
"\xef\xbb\xbf" /* zero width no-break space (U+feff) */
|
||||
|
||||
/*
|
||||
* The whitespace trimming set used when [concat]enating. This is a subset of
|
||||
* the above, and deliberately so.
|
||||
*/
|
||||
|
||||
#define CONCAT_TRIM_SET " \f\v\r\t\n"
|
||||
|
||||
#endif /* TCL_STRING_TRIM_H */
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: c
|
||||
* c-basic-offset: 4
|
||||
* fill-column: 78
|
||||
* End:
|
||||
*/
|
||||
+10
-6
@@ -14,6 +14,7 @@
|
||||
|
||||
#include "tclInt.h"
|
||||
#include "tclParse.h"
|
||||
#include "tclStringTrim.h"
|
||||
#include <math.h>
|
||||
|
||||
/*
|
||||
@@ -1768,8 +1769,7 @@ TclTrimLeft(
|
||||
*/
|
||||
|
||||
/* The whitespace characters trimmed during [concat] operations */
|
||||
#define CONCAT_WS " \f\v\r\t\n"
|
||||
#define CONCAT_WS_SIZE (int) (sizeof(CONCAT_WS "") - 1)
|
||||
#define CONCAT_WS_SIZE (int) (sizeof(CONCAT_TRIM_SET "") - 1)
|
||||
|
||||
char *
|
||||
Tcl_Concat(
|
||||
@@ -1825,7 +1825,8 @@ Tcl_Concat(
|
||||
* Trim away the leading whitespace.
|
||||
*/
|
||||
|
||||
trim = TclTrimLeft(element, elemLength, CONCAT_WS, CONCAT_WS_SIZE);
|
||||
trim = TclTrimLeft(element, elemLength, CONCAT_TRIM_SET,
|
||||
CONCAT_WS_SIZE);
|
||||
element += trim;
|
||||
elemLength -= trim;
|
||||
|
||||
@@ -1834,7 +1835,8 @@ Tcl_Concat(
|
||||
* a final backslash character.
|
||||
*/
|
||||
|
||||
trim = TclTrimRight(element, elemLength, CONCAT_WS, CONCAT_WS_SIZE);
|
||||
trim = TclTrimRight(element, elemLength, CONCAT_TRIM_SET,
|
||||
CONCAT_WS_SIZE);
|
||||
trim -= trim && (element[elemLength - trim - 1] == '\\');
|
||||
elemLength -= trim;
|
||||
|
||||
@@ -1959,7 +1961,8 @@ Tcl_ConcatObj(
|
||||
* Trim away the leading whitespace.
|
||||
*/
|
||||
|
||||
trim = TclTrimLeft(element, elemLength, CONCAT_WS, CONCAT_WS_SIZE);
|
||||
trim = TclTrimLeft(element, elemLength, CONCAT_TRIM_SET,
|
||||
CONCAT_WS_SIZE);
|
||||
element += trim;
|
||||
elemLength -= trim;
|
||||
|
||||
@@ -1968,7 +1971,8 @@ Tcl_ConcatObj(
|
||||
* a final backslash character.
|
||||
*/
|
||||
|
||||
trim = TclTrimRight(element, elemLength, CONCAT_WS, CONCAT_WS_SIZE);
|
||||
trim = TclTrimRight(element, elemLength, CONCAT_TRIM_SET,
|
||||
CONCAT_WS_SIZE);
|
||||
trim -= trim && (element[elemLength - trim - 1] == '\\');
|
||||
elemLength -= trim;
|
||||
|
||||
|
||||
+87
-5
@@ -1,4 +1,4 @@
|
||||
# Commands covered: coroutine, yield, [info coroutine]
|
||||
# Commands covered: coroutine, yield, yieldto, [info coroutine]
|
||||
#
|
||||
# This file contains a collection of tests for experimental commands that are
|
||||
# found in ::tcl::unsupported. The tests will migrate to normal test files
|
||||
@@ -612,7 +612,6 @@ test coroutine-7.3 {yielding between coroutines} -body {
|
||||
} -cleanup {
|
||||
catch {rename juggler ""}
|
||||
} -result {{{a b c d e} ::j1 {a b c d} ::j2 {a b c} ::j3 {a b} ::j1 a ::j2} {} {} {}}
|
||||
|
||||
test coroutine-7.4 {Bug 8ff0cb9fe1} -setup {
|
||||
proc foo {a b} {catch yield; return 1}
|
||||
} -cleanup {
|
||||
@@ -620,7 +619,6 @@ test coroutine-7.4 {Bug 8ff0cb9fe1} -setup {
|
||||
} -body {
|
||||
coroutine demo lsort -command foo {a b}
|
||||
} -result {b a}
|
||||
|
||||
test coroutine-7.5 {return codes} {
|
||||
set result {}
|
||||
foreach code {0 1 2 3 4 5} {
|
||||
@@ -628,14 +626,12 @@ test coroutine-7.5 {return codes} {
|
||||
}
|
||||
set result
|
||||
} {0 1 2 3 4 5}
|
||||
|
||||
test coroutine-7.6 {Early yield crashes} {
|
||||
proc foo args {}
|
||||
trace add execution foo enter {catch yield}
|
||||
coroutine demo foo
|
||||
rename foo {}
|
||||
} {}
|
||||
|
||||
test coroutine-7.7 {Bug 2486550} -setup {
|
||||
interp hide {} yield
|
||||
} -body {
|
||||
@@ -644,6 +640,92 @@ test coroutine-7.7 {Bug 2486550} -setup {
|
||||
demo
|
||||
interp expose {} yield
|
||||
} -result ok
|
||||
test coroutine-7.8 {yieldto context nuke: Bug a90d9331bc} -setup {
|
||||
namespace eval cotest {}
|
||||
set ::result ""
|
||||
} -body {
|
||||
proc cotest::body {} {
|
||||
lappend ::result a
|
||||
yield OUT
|
||||
lappend ::result b
|
||||
yieldto ::return -level 0 123
|
||||
lappend ::result c
|
||||
return
|
||||
}
|
||||
lappend ::result [coroutine cotest cotest::body]
|
||||
namespace delete cotest
|
||||
namespace eval cotest {}
|
||||
lappend ::result [cotest]
|
||||
cotest
|
||||
return $result
|
||||
} -returnCodes error -cleanup {
|
||||
catch {namespace delete ::cotest}
|
||||
catch {rename cotest ""}
|
||||
} -result {yieldto called in deleted namespace}
|
||||
test coroutine-7.9 {yieldto context nuke: Bug a90d9331bc} -setup {
|
||||
namespace eval cotest {}
|
||||
set ::result ""
|
||||
} -body {
|
||||
proc cotest::body {} {
|
||||
set y ::yieldto
|
||||
lappend ::result a
|
||||
yield OUT
|
||||
lappend ::result b
|
||||
$y ::return -level 0 123
|
||||
lappend ::result c
|
||||
return
|
||||
}
|
||||
lappend ::result [coroutine cotest cotest::body]
|
||||
namespace delete cotest
|
||||
namespace eval cotest {}
|
||||
lappend ::result [cotest]
|
||||
cotest
|
||||
return $result
|
||||
} -returnCodes error -cleanup {
|
||||
catch {namespace delete ::cotest}
|
||||
catch {rename cotest ""}
|
||||
} -result {yieldto called in deleted namespace}
|
||||
test coroutine-7.10 {yieldto context nuke: Bug a90d9331bc} -setup {
|
||||
namespace eval cotest {}
|
||||
set ::result ""
|
||||
} -body {
|
||||
proc cotest::body {} {
|
||||
lappend ::result a
|
||||
yield OUT
|
||||
lappend ::result b
|
||||
yieldto ::return -level 0 -cotest [namespace delete ::cotest] 123
|
||||
lappend ::result c
|
||||
return
|
||||
}
|
||||
lappend ::result [coroutine cotest cotest::body]
|
||||
lappend ::result [cotest]
|
||||
cotest
|
||||
return $result
|
||||
} -returnCodes error -cleanup {
|
||||
catch {namespace delete ::cotest}
|
||||
catch {rename cotest ""}
|
||||
} -result {yieldto called in deleted namespace}
|
||||
test coroutine-7.11 {yieldto context nuke: Bug a90d9331bc} -setup {
|
||||
namespace eval cotest {}
|
||||
set ::result ""
|
||||
} -body {
|
||||
proc cotest::body {} {
|
||||
set y ::yieldto
|
||||
lappend ::result a
|
||||
yield OUT
|
||||
lappend ::result b
|
||||
$y ::return -level 0 -cotest [namespace delete ::cotest] 123
|
||||
lappend ::result c
|
||||
return
|
||||
}
|
||||
lappend ::result [coroutine cotest cotest::body]
|
||||
lappend ::result [cotest]
|
||||
cotest
|
||||
return $result
|
||||
} -returnCodes error -cleanup {
|
||||
catch {namespace delete ::cotest}
|
||||
catch {rename cotest ""}
|
||||
} -result {yieldto called in deleted namespace}
|
||||
|
||||
|
||||
# cleanup
|
||||
|
||||
+5
-3
@@ -1035,6 +1035,7 @@ IOHDR=$(GENERIC_DIR)/tclIO.h
|
||||
MATHHDRS=$(GENERIC_DIR)/tommath.h $(GENERIC_DIR)/tclTomMath.h
|
||||
PARSEHDR=$(GENERIC_DIR)/tclParse.h
|
||||
NREHDR=$(GENERIC_DIR)/tclInt.h
|
||||
TRIMHDR=$(GENERIC_DIR)/tclStringTrim.h
|
||||
|
||||
regcomp.o: $(REGHDRS) $(GENERIC_DIR)/regcomp.c $(GENERIC_DIR)/regc_lex.c \
|
||||
$(GENERIC_DIR)/regc_color.c $(GENERIC_DIR)/regc_locale.c \
|
||||
@@ -1080,7 +1081,7 @@ tclCmdAH.o: $(GENERIC_DIR)/tclCmdAH.c
|
||||
tclCmdIL.o: $(GENERIC_DIR)/tclCmdIL.c $(TCLREHDRS)
|
||||
$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclCmdIL.c
|
||||
|
||||
tclCmdMZ.o: $(GENERIC_DIR)/tclCmdMZ.c $(TCLREHDRS)
|
||||
tclCmdMZ.o: $(GENERIC_DIR)/tclCmdMZ.c $(TCLREHDRS) $(TRIMHDR)
|
||||
$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclCmdMZ.c
|
||||
|
||||
tclDate.o: $(GENERIC_DIR)/tclDate.c
|
||||
@@ -1092,7 +1093,7 @@ tclCompCmds.o: $(GENERIC_DIR)/tclCompCmds.c $(COMPILEHDR)
|
||||
tclCompCmdsGR.o: $(GENERIC_DIR)/tclCompCmdsGR.c $(COMPILEHDR)
|
||||
$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclCompCmdsGR.c
|
||||
|
||||
tclCompCmdsSZ.o: $(GENERIC_DIR)/tclCompCmdsSZ.c $(COMPILEHDR)
|
||||
tclCompCmdsSZ.o: $(GENERIC_DIR)/tclCompCmdsSZ.c $(COMPILEHDR) $(TRIMHDR)
|
||||
$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclCompCmdsSZ.c
|
||||
|
||||
tclCompExpr.o: $(GENERIC_DIR)/tclCompExpr.c $(COMPILEHDR)
|
||||
@@ -1195,6 +1196,7 @@ tclLoadDld.o: $(UNIX_DIR)/tclLoadDld.c
|
||||
$(CC) -c $(CC_SWITCHES) $(UNIX_DIR)/tclLoadDld.c
|
||||
|
||||
tclLoadDyld.o: $(UNIX_DIR)/tclLoadDyld.c
|
||||
@echo Warnings are expected from compiling tclLoadDyld.c: deprecated API use
|
||||
$(CC) -c $(CC_SWITCHES) $(UNIX_DIR)/tclLoadDyld.c
|
||||
|
||||
tclLoadNone.o: $(GENERIC_DIR)/tclLoadNone.c
|
||||
@@ -1308,7 +1310,7 @@ tclStubInit.o: $(GENERIC_DIR)/tclStubInit.c
|
||||
tclTrace.o: $(GENERIC_DIR)/tclTrace.c
|
||||
$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclTrace.c
|
||||
|
||||
tclUtil.o: $(GENERIC_DIR)/tclUtil.c $(PARSEHDR)
|
||||
tclUtil.o: $(GENERIC_DIR)/tclUtil.c $(PARSEHDR) $(TRIMHDR)
|
||||
$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclUtil.c
|
||||
|
||||
tclUtf.o: $(GENERIC_DIR)/tclUtf.c $(GENERIC_DIR)/tclUniData.c
|
||||
|
||||
Reference in New Issue
Block a user