Import Tcl 8.6.11
This commit is contained in:
@@ -167,6 +167,8 @@ static int ParseTokens(const char *src, int numBytes, int mask,
|
||||
int flags, Tcl_Parse *parsePtr);
|
||||
static int ParseWhiteSpace(const char *src, int numBytes,
|
||||
int *incompletePtr, char *typePtr);
|
||||
static int ParseHex(const char *src, int numBytes,
|
||||
int *resultPtr);
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
@@ -234,19 +236,19 @@ Tcl_ParseCommand(
|
||||
* NULL, then no error message is provided. */
|
||||
const char *start, /* First character of string containing one or
|
||||
* more Tcl commands. */
|
||||
register int numBytes, /* Total number of bytes in string. If < 0,
|
||||
int numBytes, /* Total number of bytes in string. If < 0,
|
||||
* the script consists of all bytes up to the
|
||||
* first null character. */
|
||||
int nested, /* Non-zero means this is a nested command:
|
||||
* close bracket should be considered a
|
||||
* command terminator. If zero, then close
|
||||
* bracket has no special meaning. */
|
||||
register Tcl_Parse *parsePtr)
|
||||
Tcl_Parse *parsePtr)
|
||||
/* Structure to fill in with information about
|
||||
* the parsed command; any previous
|
||||
* information in the structure is ignored. */
|
||||
{
|
||||
register const char *src; /* Points to current character in the
|
||||
const char *src; /* Points to current character in the
|
||||
* command. */
|
||||
char type; /* Result returned by CHAR_TYPE(*src). */
|
||||
Tcl_Token *tokenPtr; /* Pointer to token being filled in. */
|
||||
@@ -257,6 +259,10 @@ Tcl_ParseCommand(
|
||||
* point to char after terminating one. */
|
||||
int scanned;
|
||||
|
||||
if (numBytes < 0 && start) {
|
||||
numBytes = strlen(start);
|
||||
}
|
||||
TclParseInit(interp, start, numBytes, parsePtr);
|
||||
if ((start == NULL) && (numBytes != 0)) {
|
||||
if (interp != NULL) {
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
@@ -264,10 +270,6 @@ Tcl_ParseCommand(
|
||||
}
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if (numBytes < 0) {
|
||||
numBytes = strlen(start);
|
||||
}
|
||||
TclParseInit(interp, start, numBytes, parsePtr);
|
||||
parsePtr->commentStart = NULL;
|
||||
parsePtr->commentSize = 0;
|
||||
parsePtr->commandStart = NULL;
|
||||
@@ -682,14 +684,14 @@ TclIsBareword(
|
||||
static int
|
||||
ParseWhiteSpace(
|
||||
const char *src, /* First character to parse. */
|
||||
register int numBytes, /* Max number of bytes to scan. */
|
||||
int numBytes, /* Max number of bytes to scan. */
|
||||
int *incompletePtr, /* Set this boolean memory to true if parsing
|
||||
* indicates an incomplete command. */
|
||||
char *typePtr) /* Points to location to store character type
|
||||
* of character that ends run of whitespace */
|
||||
{
|
||||
register char type = TYPE_NORMAL;
|
||||
register const char *p = src;
|
||||
char type = TYPE_NORMAL;
|
||||
const char *p = src;
|
||||
|
||||
while (1) {
|
||||
while (numBytes && ((type = CHAR_TYPE(*p)) & TYPE_SPACE)) {
|
||||
@@ -754,7 +756,7 @@ TclParseAllWhiteSpace(
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* TclParseHex --
|
||||
* ParseHex --
|
||||
*
|
||||
* Scans a hexadecimal number as a Tcl_UniChar value (e.g., for parsing
|
||||
* \x and \u escape sequences). At most numBytes bytes are scanned.
|
||||
@@ -774,7 +776,7 @@ TclParseAllWhiteSpace(
|
||||
*/
|
||||
|
||||
int
|
||||
TclParseHex(
|
||||
ParseHex(
|
||||
const char *src, /* First character to parse. */
|
||||
int numBytes, /* Max number of byes to scan */
|
||||
int *resultPtr) /* Points to storage provided by caller where
|
||||
@@ -782,12 +784,12 @@ TclParseHex(
|
||||
* conversion is to be written. */
|
||||
{
|
||||
int result = 0;
|
||||
register const char *p = src;
|
||||
const char *p = src;
|
||||
|
||||
while (numBytes--) {
|
||||
unsigned char digit = UCHAR(*p);
|
||||
|
||||
if (!isxdigit(digit) || (result > 0x10fff)) {
|
||||
if (!isxdigit(digit) || (result > 0x10FFF)) {
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -840,8 +842,7 @@ TclParseBackslash(
|
||||
* written. At most TCL_UTF_MAX bytes will be
|
||||
* written there. */
|
||||
{
|
||||
register const char *p = src+1;
|
||||
Tcl_UniChar unichar = 0;
|
||||
const char *p = src+1;
|
||||
int result;
|
||||
int count;
|
||||
char buf[TCL_UTF_MAX] = "";
|
||||
@@ -870,7 +871,7 @@ TclParseBackslash(
|
||||
count = 2;
|
||||
switch (*p) {
|
||||
/*
|
||||
* Note: in the conversions below, use absolute values (e.g., 0xa)
|
||||
* Note: in the conversions below, use absolute values (e.g., 0xA)
|
||||
* rather than symbolic values (e.g. \n) that get converted by the
|
||||
* compiler. It's possible that compilers on some platforms will do
|
||||
* the symbolic conversions differently, which could result in
|
||||
@@ -884,25 +885,25 @@ TclParseBackslash(
|
||||
result = 0x8;
|
||||
break;
|
||||
case 'f':
|
||||
result = 0xc;
|
||||
result = 0xC;
|
||||
break;
|
||||
case 'n':
|
||||
result = 0xa;
|
||||
result = 0xA;
|
||||
break;
|
||||
case 'r':
|
||||
result = 0xd;
|
||||
result = 0xD;
|
||||
break;
|
||||
case 't':
|
||||
result = 0x9;
|
||||
break;
|
||||
case 'v':
|
||||
result = 0xb;
|
||||
result = 0xB;
|
||||
break;
|
||||
case 'x':
|
||||
count += TclParseHex(p+1, (numBytes > 3) ? 2 : numBytes-2, &result);
|
||||
count += ParseHex(p+1, (numBytes > 3) ? 2 : numBytes-2, &result);
|
||||
if (count == 2) {
|
||||
/*
|
||||
* No hexadigits -> This is just "x".
|
||||
* No hexdigits -> This is just "x".
|
||||
*/
|
||||
|
||||
result = 'x';
|
||||
@@ -910,25 +911,42 @@ TclParseBackslash(
|
||||
/*
|
||||
* Keep only the last byte (2 hex digits).
|
||||
*/
|
||||
result = (unsigned char) result;
|
||||
result = UCHAR(result);
|
||||
}
|
||||
break;
|
||||
case 'u':
|
||||
count += TclParseHex(p+1, (numBytes > 5) ? 4 : numBytes-2, &result);
|
||||
count += ParseHex(p+1, (numBytes > 5) ? 4 : numBytes-2, &result);
|
||||
if (count == 2) {
|
||||
/*
|
||||
* No hexadigits -> This is just "u".
|
||||
* No hexdigits -> This is just "u".
|
||||
*/
|
||||
result = 'u';
|
||||
#if TCL_UTF_MAX > 3
|
||||
} else if (((result & 0xFC00) == 0xD800) && (count == 6)
|
||||
&& (p[5] == '\\') && (p[6] == 'u') && (numBytes >= 10)) {
|
||||
/* If high surrogate is immediately followed by a low surrogate
|
||||
* escape, combine them into one character. */
|
||||
int low;
|
||||
int count2 = ParseHex(p+7, 4, &low);
|
||||
if ((count2 == 4) && ((low & 0xFC00) == 0xDC00)) {
|
||||
result = ((result & 0x3FF)<<10 | (low & 0x3FF)) + 0x10000;
|
||||
count += count2 + 2;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
case 'U':
|
||||
count += TclParseHex(p+1, (numBytes > 9) ? 8 : numBytes-2, &result);
|
||||
count += ParseHex(p+1, (numBytes > 9) ? 8 : numBytes-2, &result);
|
||||
if (count == 2) {
|
||||
/*
|
||||
* No hexadigits -> This is just "U".
|
||||
* No hexdigits -> This is just "U".
|
||||
*/
|
||||
result = 'U';
|
||||
#if TCL_UTF_MAX > 3
|
||||
} else if ((result & ~0x7FF) == 0xD800) {
|
||||
/* Upper or lower surrogate, not allowed in this syntax. */
|
||||
result = 0xFFFD;
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
case '\n':
|
||||
@@ -974,16 +992,15 @@ TclParseBackslash(
|
||||
* #217987] test subst-3.2
|
||||
*/
|
||||
|
||||
if (Tcl_UtfCharComplete(p, numBytes - 1)) {
|
||||
count = TclUtfToUniChar(p, &unichar) + 1; /* +1 for '\' */
|
||||
if (TclUCS4Complete(p, numBytes - 1)) {
|
||||
count = TclUtfToUCS4(p, &result) + 1; /* +1 for '\' */
|
||||
} else {
|
||||
char utfBytes[TCL_UTF_MAX];
|
||||
char utfBytes[8];
|
||||
|
||||
memcpy(utfBytes, p, (size_t) (numBytes - 1));
|
||||
memcpy(utfBytes, p, numBytes - 1);
|
||||
utfBytes[numBytes - 1] = '\0';
|
||||
count = TclUtfToUniChar(utfBytes, &unichar) + 1;
|
||||
count = TclUtfToUCS4(utfBytes, &result) + 1;
|
||||
}
|
||||
result = unichar;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -991,13 +1008,12 @@ TclParseBackslash(
|
||||
if (readPtr != NULL) {
|
||||
*readPtr = count;
|
||||
}
|
||||
count = Tcl_UniCharToUtf(result, dst);
|
||||
#if TCL_UTF_MAX > 3
|
||||
if ((result >= 0xD800) && (count < 3)) {
|
||||
count += Tcl_UniCharToUtf(-1, dst + count);
|
||||
#if TCL_UTF_MAX < 4
|
||||
if (result > 0xFFFF) {
|
||||
result = 0xFFFD;
|
||||
}
|
||||
#endif
|
||||
return count;
|
||||
return TclUCS4ToUtf(result, dst);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1021,12 +1037,12 @@ TclParseBackslash(
|
||||
static int
|
||||
ParseComment(
|
||||
const char *src, /* First character to parse. */
|
||||
register int numBytes, /* Max number of bytes to scan. */
|
||||
int numBytes, /* Max number of bytes to scan. */
|
||||
Tcl_Parse *parsePtr) /* Information about parse in progress.
|
||||
* Updated if parsing indicates an incomplete
|
||||
* command. */
|
||||
{
|
||||
register const char *p = src;
|
||||
const char *p = src;
|
||||
|
||||
while (numBytes) {
|
||||
char type;
|
||||
@@ -1105,8 +1121,8 @@ ParseComment(
|
||||
|
||||
static int
|
||||
ParseTokens(
|
||||
register const char *src, /* First character to parse. */
|
||||
register int numBytes, /* Max number of bytes to scan. */
|
||||
const char *src, /* First character to parse. */
|
||||
int numBytes, /* Max number of bytes to scan. */
|
||||
int mask, /* Specifies when to stop parsing. The parse
|
||||
* stops at the first unquoted character whose
|
||||
* CHAR_TYPE contains any of the bits in
|
||||
@@ -1384,7 +1400,7 @@ Tcl_ParseVarName(
|
||||
* NULL, then no error message is provided. */
|
||||
const char *start, /* Start of variable substitution string.
|
||||
* First character must be "$". */
|
||||
register int numBytes, /* Total number of bytes in string. If < 0,
|
||||
int numBytes, /* Total number of bytes in string. If < 0,
|
||||
* the string consists of all bytes up to the
|
||||
* first null character. */
|
||||
Tcl_Parse *parsePtr, /* Structure to fill in with information about
|
||||
@@ -1395,20 +1411,19 @@ Tcl_ParseVarName(
|
||||
* reinitialize it. */
|
||||
{
|
||||
Tcl_Token *tokenPtr;
|
||||
register const char *src;
|
||||
const char *src;
|
||||
int varIndex;
|
||||
unsigned array;
|
||||
|
||||
if ((numBytes == 0) || (start == NULL)) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if (numBytes < 0) {
|
||||
if (numBytes < 0 && start) {
|
||||
numBytes = strlen(start);
|
||||
}
|
||||
|
||||
if (!append) {
|
||||
TclParseInit(interp, start, numBytes, parsePtr);
|
||||
}
|
||||
if ((numBytes == 0) || (start == NULL)) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate one token for the variable, an additional token for the name,
|
||||
@@ -1577,13 +1592,13 @@ Tcl_ParseVarName(
|
||||
const char *
|
||||
Tcl_ParseVar(
|
||||
Tcl_Interp *interp, /* Context for looking up variable. */
|
||||
register const char *start, /* Start of variable substitution. First
|
||||
const char *start, /* Start of variable substitution. First
|
||||
* character must be "$". */
|
||||
const char **termPtr) /* If non-NULL, points to word to fill in with
|
||||
* character just after last one in the
|
||||
* variable specifier. */
|
||||
{
|
||||
register Tcl_Obj *objPtr;
|
||||
Tcl_Obj *objPtr;
|
||||
int code;
|
||||
Tcl_Parse *parsePtr = TclStackAlloc(interp, sizeof(Tcl_Parse));
|
||||
|
||||
@@ -1662,10 +1677,10 @@ Tcl_ParseBraces(
|
||||
* NULL, then no error message is provided. */
|
||||
const char *start, /* Start of string enclosed in braces. The
|
||||
* first character must be {'. */
|
||||
register int numBytes, /* Total number of bytes in string. If < 0,
|
||||
int numBytes, /* Total number of bytes in string. If < 0,
|
||||
* the string consists of all bytes up to the
|
||||
* first null character. */
|
||||
register Tcl_Parse *parsePtr,
|
||||
Tcl_Parse *parsePtr,
|
||||
/* Structure to fill in with information about
|
||||
* the string. */
|
||||
int append, /* Non-zero means append tokens to existing
|
||||
@@ -1678,19 +1693,18 @@ Tcl_ParseBraces(
|
||||
* successful. */
|
||||
{
|
||||
Tcl_Token *tokenPtr;
|
||||
register const char *src;
|
||||
const char *src;
|
||||
int startIndex, level, length;
|
||||
|
||||
if ((numBytes == 0) || (start == NULL)) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if (numBytes < 0) {
|
||||
if (numBytes < 0 && start) {
|
||||
numBytes = strlen(start);
|
||||
}
|
||||
|
||||
if (!append) {
|
||||
TclParseInit(interp, start, numBytes, parsePtr);
|
||||
}
|
||||
if ((numBytes == 0) || (start == NULL)) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
src = start;
|
||||
startIndex = parsePtr->numTokens;
|
||||
@@ -1804,7 +1818,7 @@ Tcl_ParseBraces(
|
||||
*/
|
||||
|
||||
{
|
||||
register int openBrace = 0;
|
||||
int openBrace = 0;
|
||||
|
||||
while (--src > start) {
|
||||
switch (*src) {
|
||||
@@ -1815,7 +1829,7 @@ Tcl_ParseBraces(
|
||||
openBrace = 0;
|
||||
break;
|
||||
case '#' :
|
||||
if (openBrace && TclIsSpaceProc(src[-1])) {
|
||||
if (openBrace && TclIsSpaceProcM(src[-1])) {
|
||||
Tcl_AppendToObj(Tcl_GetObjResult(parsePtr->interp),
|
||||
": possible unbalanced brace in comment", -1);
|
||||
goto error;
|
||||
@@ -1864,10 +1878,10 @@ Tcl_ParseQuotedString(
|
||||
* NULL, then no error message is provided. */
|
||||
const char *start, /* Start of the quoted string. The first
|
||||
* character must be '"'. */
|
||||
register int numBytes, /* Total number of bytes in string. If < 0,
|
||||
int numBytes, /* Total number of bytes in string. If < 0,
|
||||
* the string consists of all bytes up to the
|
||||
* first null character. */
|
||||
register Tcl_Parse *parsePtr,
|
||||
Tcl_Parse *parsePtr,
|
||||
/* Structure to fill in with information about
|
||||
* the string. */
|
||||
int append, /* Non-zero means append tokens to existing
|
||||
@@ -1879,16 +1893,15 @@ Tcl_ParseQuotedString(
|
||||
* the quoted string's terminating close-quote
|
||||
* if the parse succeeds. */
|
||||
{
|
||||
if ((numBytes == 0) || (start == NULL)) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if (numBytes < 0) {
|
||||
if (numBytes < 0 && start) {
|
||||
numBytes = strlen(start);
|
||||
}
|
||||
|
||||
if (!append) {
|
||||
TclParseInit(interp, start, numBytes, parsePtr);
|
||||
}
|
||||
if ((numBytes == 0) || (start == NULL)) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
if (TCL_OK != ParseTokens(start+1, numBytes-1, TYPE_QUOTE, TCL_SUBST_ALL,
|
||||
parsePtr)) {
|
||||
@@ -2159,7 +2172,7 @@ TclSubstTokens(
|
||||
* command, which is refered to by 'script'.
|
||||
* The 'clNextOuter' refers to the current
|
||||
* entry in the table of continuation lines in
|
||||
* this "master script", and the character
|
||||
* this "main script", and the character
|
||||
* offsets are relative to the 'outerScript'
|
||||
* as well.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user