Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8841ba90ee |
+389
-326
@@ -527,33 +527,38 @@ typedef void (Tcl_ThreadCreateProc) (ClientData clientData);
|
||||
* Flag values passed to Tcl_StringCaseMatch.
|
||||
*/
|
||||
|
||||
#define TCL_MATCH_NOCASE (1<<0)
|
||||
enum TclStringCaseMatchFlags {
|
||||
TCL_MATCH_NOCASE = (1<<0)
|
||||
};
|
||||
|
||||
/*
|
||||
* Flag values passed to Tcl_GetRegExpFromObj.
|
||||
*/
|
||||
|
||||
#define TCL_REG_BASIC 000000 /* BREs (convenience). */
|
||||
#define TCL_REG_EXTENDED 000001 /* EREs. */
|
||||
#define TCL_REG_ADVF 000002 /* Advanced features in EREs. */
|
||||
#define TCL_REG_ADVANCED 000003 /* AREs (which are also EREs). */
|
||||
#define TCL_REG_QUOTE 000004 /* No special characters, none. */
|
||||
#define TCL_REG_NOCASE 000010 /* Ignore case. */
|
||||
#define TCL_REG_NOSUB 000020 /* Don't care about subexpressions. */
|
||||
#define TCL_REG_EXPANDED 000040 /* Expanded format, white space &
|
||||
* comments. */
|
||||
#define TCL_REG_NLSTOP 000100 /* \n doesn't match . or [^ ] */
|
||||
#define TCL_REG_NLANCH 000200 /* ^ matches after \n, $ before. */
|
||||
#define TCL_REG_NEWLINE 000300 /* Newlines are line terminators. */
|
||||
#define TCL_REG_CANMATCH 001000 /* Report details on partial/limited
|
||||
* matches. */
|
||||
enum TclRegExpObjFlags {
|
||||
TCL_REG_BASIC = 00000, /* BREs (convenience). */
|
||||
TCL_REG_EXTENDED = 00001, /* EREs. */
|
||||
TCL_REG_ADVF = 00002, /* Advanced features in EREs. */
|
||||
TCL_REG_ADVANCED = 00003, /* AREs (which are also EREs). */
|
||||
TCL_REG_QUOTE = 00004, /* No special characters, none. */
|
||||
TCL_REG_NOCASE = 00010, /* Ignore case. */
|
||||
TCL_REG_NOSUB = 00020, /* Don't care about subexpressions. */
|
||||
TCL_REG_EXPANDED = 00040, /* Expanded format, white space & comments. */
|
||||
TCL_REG_NLSTOP = 00100, /* \n doesn't match . or [^ ] */
|
||||
TCL_REG_NLANCH = 00200, /* ^ matches after \n, $ before. */
|
||||
TCL_REG_NEWLINE = 00300, /* Newlines are line terminators. */
|
||||
TCL_REG_CANMATCH = 01000 /* Report details on partial/limited
|
||||
* matches. */
|
||||
};
|
||||
|
||||
/*
|
||||
* Flags values passed to Tcl_RegExpExecObj.
|
||||
*/
|
||||
|
||||
#define TCL_REG_NOTBOL 0001 /* Beginning of string does not match ^. */
|
||||
#define TCL_REG_NOTEOL 0002 /* End of string does not match $. */
|
||||
enum TclRegExpExecFlags {
|
||||
TCL_REG_NOTBOL = 0001, /* Beginning of string does not match ^. */
|
||||
TCL_REG_NOTEOL = 0002 /* End of string does not match $. */
|
||||
};
|
||||
|
||||
/*
|
||||
* Structures filled in by Tcl_RegExpInfo. Note that all offset values are
|
||||
@@ -592,25 +597,36 @@ typedef struct stat *Tcl_OldStat_;
|
||||
* Tcl_GetObjResult() or Tcl_GetStringResult() to read the interpreter's
|
||||
* result. See the SetResult man page for details. Besides this result, the
|
||||
* command function returns an integer code, which is one of the following:
|
||||
*
|
||||
* TCL_OK Command completed normally; the interpreter's result
|
||||
* contains the command's result.
|
||||
* TCL_ERROR The command couldn't be completed successfully; the
|
||||
* interpreter's result describes what went wrong.
|
||||
* TCL_RETURN The command requests that the current function return;
|
||||
* the interpreter's result contains the function's
|
||||
* return value.
|
||||
* TCL_BREAK The command requests that the innermost loop be
|
||||
* exited; the interpreter's result is meaningless.
|
||||
* TCL_CONTINUE Go on to the next iteration of the current loop; the
|
||||
* interpreter's result is meaningless.
|
||||
*/
|
||||
|
||||
#define TCL_OK 0
|
||||
#define TCL_ERROR 1
|
||||
#define TCL_RETURN 2
|
||||
#define TCL_BREAK 3
|
||||
#define TCL_CONTINUE 4
|
||||
enum TclStandardResultCodes {
|
||||
TCL_OK = 0, /* Command completed normally; the
|
||||
* interpreter's result contains the command's
|
||||
* result. */
|
||||
TCL_ERROR = 1, /* The command couldn't be completed
|
||||
* successfully; the interpreter's result
|
||||
* describes what went wrong. */
|
||||
TCL_RETURN = 2, /* The command requests that the current
|
||||
* function return; the interpreter's result
|
||||
* contains the function's return value. */
|
||||
TCL_BREAK = 3, /* The command requests that the innermost
|
||||
* loop be exited; the interpreter's result is
|
||||
* meaningless (conventionally the empty
|
||||
* string). */
|
||||
TCL_CONTINUE = 4 /* Go on to the next iteration of the current
|
||||
* loop; the interpreter's result is
|
||||
* meaningless (conventionally the empty
|
||||
* string). */
|
||||
|
||||
/*
|
||||
* NOTE: This is NOT a closed set! Application-specific result codes
|
||||
* appear in the wild, usually for doing some sort of "fast exception".
|
||||
* They all behave the same, like an error except that no stack trace is
|
||||
* accumulated in the errorInfo. Because there's no registry of codes
|
||||
* used, they are all reserved to applications; library code cannot safely
|
||||
* use them.
|
||||
*/
|
||||
};
|
||||
|
||||
#if !defined(TCL_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9
|
||||
#define TCL_RESULT_SIZE 200
|
||||
@@ -621,10 +637,12 @@ typedef struct stat *Tcl_OldStat_;
|
||||
* Flags to control what substitutions are performed by Tcl_SubstObj():
|
||||
*/
|
||||
|
||||
#define TCL_SUBST_COMMANDS 001
|
||||
#define TCL_SUBST_VARIABLES 002
|
||||
#define TCL_SUBST_BACKSLASHES 004
|
||||
#define TCL_SUBST_ALL 007
|
||||
enum TclSubstControlFlags {
|
||||
TCL_SUBST_COMMANDS = 001,
|
||||
TCL_SUBST_VARIABLES = 002,
|
||||
TCL_SUBST_BACKSLASHES = 004,
|
||||
TCL_SUBST_ALL = 007
|
||||
};
|
||||
|
||||
/*
|
||||
* Argument descriptors for math function callbacks in expressions:
|
||||
@@ -963,55 +981,56 @@ typedef struct Tcl_DString {
|
||||
|
||||
/*
|
||||
* Flag values passed to Tcl_ConvertElement.
|
||||
* TCL_DONT_USE_BRACES forces it not to enclose the element in braces, but to
|
||||
* use backslash quoting instead.
|
||||
* TCL_DONT_QUOTE_HASH disables the default quoting of the '#' character. It
|
||||
* is safe to leave the hash unquoted when the element is not the first
|
||||
* element of a list, and this flag can be used by the caller to indicate
|
||||
* that condition.
|
||||
*/
|
||||
|
||||
#define TCL_DONT_USE_BRACES 1
|
||||
#define TCL_DONT_QUOTE_HASH 8
|
||||
enum TclConvertElementFlags {
|
||||
TCL_DONT_USE_BRACES = 1, /* Force Tcl_ConvertElement not to enclose the
|
||||
* element in braces, but to use backslash
|
||||
* quoting instead.*/
|
||||
TCL_DONT_QUOTE_HASH = 8 /* Disable the default quoting of the '#'
|
||||
* character. It is safe to leave the hash
|
||||
* unquoted when the element is not the first
|
||||
* element of a list, and this flag can be
|
||||
* used by the caller to indicate that
|
||||
* condition. */
|
||||
};
|
||||
|
||||
/*
|
||||
* Flags that may be passed to Tcl_GetIndexFromObj.
|
||||
* TCL_EXACT disallows abbreviated strings.
|
||||
* TCL_INDEX_TEMP_TABLE disallows caching of lookups. A possible use case is
|
||||
* a table that will not live long enough to make it worthwhile.
|
||||
*/
|
||||
|
||||
#define TCL_EXACT 1
|
||||
#define TCL_INDEX_TEMP_TABLE 2
|
||||
enum TclGetIndexFromObjFlags {
|
||||
TCL_EXACT = 1, /* Disallow abbreviated strings. */
|
||||
TCL_INDEX_TEMP_TABLE = 2 /* Disallow caching of lookups. A possible use
|
||||
* case is a table that will not live long
|
||||
* enough to make it worthwhile. */
|
||||
};
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------------
|
||||
* Flag values passed to Tcl_RecordAndEval, Tcl_EvalObj, Tcl_EvalObjv.
|
||||
* WARNING: these bit choices must not conflict with the bit choices for
|
||||
* evalFlag bits in tclInt.h!
|
||||
*
|
||||
* Meanings:
|
||||
* TCL_NO_EVAL: Just record this command
|
||||
* TCL_EVAL_GLOBAL: Execute script in global namespace
|
||||
* TCL_EVAL_DIRECT: Do not compile this script
|
||||
* TCL_EVAL_INVOKE: Magical Tcl_EvalObjv mode for aliases/ensembles
|
||||
* o Run in iPtr->lookupNsPtr or global namespace
|
||||
* o Cut out of error traces
|
||||
* o Don't reset the flags controlling ensemble
|
||||
* error message rewriting.
|
||||
* TCL_CANCEL_UNWIND: Magical Tcl_CancelEval mode that causes the
|
||||
* stack for the script in progress to be
|
||||
* completely unwound.
|
||||
* TCL_EVAL_NOERR: Do no exception reporting at all, just return
|
||||
* as the caller will report.
|
||||
*/
|
||||
|
||||
#define TCL_NO_EVAL 0x010000
|
||||
#define TCL_EVAL_GLOBAL 0x020000
|
||||
#define TCL_EVAL_DIRECT 0x040000
|
||||
#define TCL_EVAL_INVOKE 0x080000
|
||||
#define TCL_CANCEL_UNWIND 0x100000
|
||||
#define TCL_EVAL_NOERR 0x200000
|
||||
enum TclEvalFlags {
|
||||
TCL_NO_EVAL = 0x010000, /* Just record this command */
|
||||
TCL_EVAL_GLOBAL = 0x020000, /* Execute script in global namespace */
|
||||
TCL_EVAL_DIRECT = 0x040000, /* Do not compile this script */
|
||||
TCL_EVAL_INVOKE = 0x080000, /* Magical Tcl_EvalObjv mode for
|
||||
* aliases/ensembles
|
||||
* o Run in iPtr->lookupNsPtr or global
|
||||
* namespace
|
||||
* o Cut out of error traces
|
||||
* o Don't reset the flags controlling
|
||||
* ensemble error message rewriting. */
|
||||
TCL_CANCEL_UNWIND = 0x100000,
|
||||
/* Magical Tcl_CancelEval mode that causes the
|
||||
* stack for the script in progress to be
|
||||
* completely unwound. */
|
||||
TCL_EVAL_NOERR = 0x200000 /* Do no exception reporting at all, just
|
||||
* return as the caller will report. */
|
||||
};
|
||||
|
||||
/*
|
||||
* Special freeProc values that may be passed to Tcl_SetResult (see the man
|
||||
@@ -1028,45 +1047,48 @@ typedef struct Tcl_DString {
|
||||
* TCL_CANCEL_UNWIND, above.
|
||||
*/
|
||||
|
||||
#define TCL_GLOBAL_ONLY 1
|
||||
#define TCL_NAMESPACE_ONLY 2
|
||||
#define TCL_APPEND_VALUE 4
|
||||
#define TCL_LIST_ELEMENT 8
|
||||
#define TCL_TRACE_READS 0x10
|
||||
#define TCL_TRACE_WRITES 0x20
|
||||
#define TCL_TRACE_UNSETS 0x40
|
||||
#define TCL_TRACE_DESTROYED 0x80
|
||||
|
||||
enum TclVariableFlags {
|
||||
TCL_GLOBAL_ONLY = 1,
|
||||
TCL_NAMESPACE_ONLY = 2,
|
||||
TCL_APPEND_VALUE = 4,
|
||||
TCL_LIST_ELEMENT = 8,
|
||||
TCL_TRACE_READS = 0x10,
|
||||
TCL_TRACE_WRITES = 0x20,
|
||||
TCL_TRACE_UNSETS = 0x40,
|
||||
TCL_TRACE_DESTROYED = 0x80,
|
||||
#if !defined(TCL_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9
|
||||
#define TCL_INTERP_DESTROYED 0x100
|
||||
TCL_INTERP_DESTROYED = 0x100,
|
||||
#endif
|
||||
|
||||
#define TCL_LEAVE_ERR_MSG 0x200
|
||||
#define TCL_TRACE_ARRAY 0x800
|
||||
TCL_LEAVE_ERR_MSG = 0x200,
|
||||
TCL_TRACE_ARRAY = 0x800,
|
||||
#ifndef TCL_REMOVE_OBSOLETE_TRACES
|
||||
/* Required to support old variable/vdelete/vinfo traces. */
|
||||
#define TCL_TRACE_OLD_STYLE 0x1000
|
||||
/* Required to support old variable/vdelete/vinfo traces. */
|
||||
TCL_TRACE_OLD_STYLE = 0x1000,
|
||||
#endif
|
||||
/* Indicate the semantics of the result of a trace. */
|
||||
#define TCL_TRACE_RESULT_DYNAMIC 0x8000
|
||||
#define TCL_TRACE_RESULT_OBJECT 0x10000
|
||||
/* Indicate the semantics of the result of a trace. */
|
||||
TCL_TRACE_RESULT_DYNAMIC = 0x8000,
|
||||
TCL_TRACE_RESULT_OBJECT = 0x10000
|
||||
};
|
||||
|
||||
/*
|
||||
* Flag values for ensemble commands.
|
||||
*/
|
||||
|
||||
#define TCL_ENSEMBLE_PREFIX 0x02/* Flag value to say whether to allow
|
||||
enum TclEnsembleFlags {
|
||||
TCL_ENSEMBLE_PREFIX = 0x02 /* Flag value to say whether to allow
|
||||
* unambiguous prefixes of commands or to
|
||||
* require exact matches for command names. */
|
||||
};
|
||||
|
||||
/*
|
||||
* Flag values passed to command-related functions.
|
||||
*/
|
||||
|
||||
#define TCL_TRACE_RENAME 0x2000
|
||||
#define TCL_TRACE_DELETE 0x4000
|
||||
|
||||
#define TCL_ALLOW_INLINE_COMPILATION 0x20000
|
||||
enum TclCommandFlags {
|
||||
TCL_TRACE_RENAME = 0x2000,
|
||||
TCL_TRACE_DELETE = 0x4000,
|
||||
TCL_ALLOW_INLINE_COMPILATION = 0x20000
|
||||
};
|
||||
|
||||
/*
|
||||
* The TCL_PARSE_PART1 flag is deprecated and has no effect. The part1 is now
|
||||
@@ -1083,28 +1105,30 @@ typedef struct Tcl_DString {
|
||||
* Types for linked variables:
|
||||
*/
|
||||
|
||||
#define TCL_LINK_INT 1
|
||||
#define TCL_LINK_DOUBLE 2
|
||||
#define TCL_LINK_BOOLEAN 3
|
||||
#define TCL_LINK_STRING 4
|
||||
#define TCL_LINK_WIDE_INT 5
|
||||
#define TCL_LINK_CHAR 6
|
||||
#define TCL_LINK_UCHAR 7
|
||||
#define TCL_LINK_SHORT 8
|
||||
#define TCL_LINK_USHORT 9
|
||||
#define TCL_LINK_UINT 10
|
||||
enum TclLinkVariableTypes {
|
||||
TCL_LINK_INT = 1,
|
||||
TCL_LINK_DOUBLE = 2,
|
||||
TCL_LINK_BOOLEAN = 3,
|
||||
TCL_LINK_STRING = 4,
|
||||
TCL_LINK_WIDE_INT = 5,
|
||||
TCL_LINK_CHAR = 6,
|
||||
TCL_LINK_UCHAR = 7,
|
||||
TCL_LINK_SHORT = 8,
|
||||
TCL_LINK_USHORT = 9,
|
||||
TCL_LINK_UINT = 10,
|
||||
TCL_LINK_FLOAT = 13,
|
||||
TCL_LINK_WIDE_UINT = 14,
|
||||
TCL_LINK_CHARS = 15,
|
||||
TCL_LINK_BINARY = 16,
|
||||
#if defined(TCL_WIDE_INT_IS_LONG) || defined(_WIN32) || defined(__CYGWIN__)
|
||||
#define TCL_LINK_LONG ((sizeof(long) != sizeof(int)) ? TCL_LINK_WIDE_INT : TCL_LINK_INT)
|
||||
#define TCL_LINK_ULONG ((sizeof(long) != sizeof(int)) ? TCL_LINK_WIDE_UINT : TCL_LINK_UINT)
|
||||
TCL_LINK_LONG = ((sizeof(long) != sizeof(int)) ? TCL_LINK_WIDE_INT : TCL_LINK_INT),
|
||||
TCL_LINK_ULONG = ((sizeof(long) != sizeof(int)) ? TCL_LINK_WIDE_UINT : TCL_LINK_UINT),
|
||||
#else
|
||||
#define TCL_LINK_LONG 11
|
||||
#define TCL_LINK_ULONG 12
|
||||
TCL_LINK_LONG = 11,
|
||||
TCL_LINK_ULONG = 12,
|
||||
#endif
|
||||
#define TCL_LINK_FLOAT 13
|
||||
#define TCL_LINK_WIDE_UINT 14
|
||||
#define TCL_LINK_CHARS 15
|
||||
#define TCL_LINK_BINARY 16
|
||||
#define TCL_LINK_READ_ONLY 0x80
|
||||
TCL_LINK_READ_ONLY = 0x80
|
||||
};
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------------
|
||||
@@ -1152,21 +1176,23 @@ struct Tcl_HashEntry {
|
||||
|
||||
/*
|
||||
* Flags used in Tcl_HashKeyType.
|
||||
*
|
||||
* TCL_HASH_KEY_RANDOMIZE_HASH -
|
||||
* There are some things, pointers for example
|
||||
* which don't hash well because they do not use
|
||||
* the lower bits. If this flag is set then the
|
||||
* hash table will attempt to rectify this by
|
||||
* randomising the bits and then using the upper
|
||||
* N bits as the index into the table.
|
||||
* TCL_HASH_KEY_SYSTEM_HASH - If this flag is set then all memory internally
|
||||
* allocated for the hash table that is not for an
|
||||
* entry will use the system heap.
|
||||
*/
|
||||
|
||||
#define TCL_HASH_KEY_RANDOMIZE_HASH 0x1
|
||||
#define TCL_HASH_KEY_SYSTEM_HASH 0x2
|
||||
enum TclHashKeyFlags {
|
||||
TCL_HASH_KEY_RANDOMIZE_HASH = 0x1,
|
||||
/* There are some things, pointers for example
|
||||
* which don't hash well because they do not
|
||||
* use the lower bits. If this flag is set
|
||||
* then the hash table will attempt to rectify
|
||||
* this by randomising the bits and then using
|
||||
* the upper N bits as the index into the
|
||||
* table. */
|
||||
TCL_HASH_KEY_SYSTEM_HASH = 0x2
|
||||
/* If this flag is set then all memory
|
||||
* internally allocated for the hash table
|
||||
* that is not for an entry will use the
|
||||
* system heap. */
|
||||
};
|
||||
|
||||
/*
|
||||
* Structure definition for the methods associated with a hash table key type.
|
||||
@@ -1307,12 +1333,14 @@ typedef struct {
|
||||
* events:
|
||||
*/
|
||||
|
||||
#define TCL_DONT_WAIT (1<<1)
|
||||
#define TCL_WINDOW_EVENTS (1<<2)
|
||||
#define TCL_FILE_EVENTS (1<<3)
|
||||
#define TCL_TIMER_EVENTS (1<<4)
|
||||
#define TCL_IDLE_EVENTS (1<<5) /* WAS 0x10 ???? */
|
||||
#define TCL_ALL_EVENTS (~TCL_DONT_WAIT)
|
||||
enum TclDoOneEventFlags {
|
||||
TCL_DONT_WAIT = (1<<1),
|
||||
TCL_WINDOW_EVENTS = (1<<2),
|
||||
TCL_FILE_EVENTS = (1<<3),
|
||||
TCL_TIMER_EVENTS = (1<<4),
|
||||
TCL_IDLE_EVENTS = (1<<5), /* WAS 0x10 ???? */
|
||||
TCL_ALL_EVENTS = (~TCL_DONT_WAIT)
|
||||
};
|
||||
|
||||
/*
|
||||
* The following structure defines a generic event for the Tcl event system.
|
||||
@@ -1341,8 +1369,10 @@ typedef enum {
|
||||
* event routines.
|
||||
*/
|
||||
|
||||
#define TCL_SERVICE_NONE 0
|
||||
#define TCL_SERVICE_ALL 1
|
||||
enum TclServiceModes {
|
||||
TCL_SERVICE_NONE = 0,
|
||||
TCL_SERVICE_ALL = 1
|
||||
};
|
||||
|
||||
/*
|
||||
* The following structure keeps is used to hold a time value, either as an
|
||||
@@ -1371,9 +1401,11 @@ typedef void (Tcl_ScaleTimeProc) (Tcl_Time *timebuf, ClientData clientData);
|
||||
* indicate what sorts of events are of interest:
|
||||
*/
|
||||
|
||||
#define TCL_READABLE (1<<1)
|
||||
#define TCL_WRITABLE (1<<2)
|
||||
#define TCL_EXCEPTION (1<<3)
|
||||
enum TclChannelHandlerFlags {
|
||||
TCL_READABLE = (1<<1),
|
||||
TCL_WRITABLE = (1<<2),
|
||||
TCL_EXCEPTION = (1<<3)
|
||||
};
|
||||
|
||||
/*
|
||||
* Flag values to pass to Tcl_OpenCommandChannel to indicate the disposition
|
||||
@@ -1381,18 +1413,22 @@ typedef void (Tcl_ScaleTimeProc) (Tcl_Time *timebuf, ClientData clientData);
|
||||
* Tcl_GetStdChannel.
|
||||
*/
|
||||
|
||||
#define TCL_STDIN (1<<1)
|
||||
#define TCL_STDOUT (1<<2)
|
||||
#define TCL_STDERR (1<<3)
|
||||
#define TCL_ENFORCE_MODE (1<<4)
|
||||
enum TclOpenCommandChannelFlags {
|
||||
TCL_STDIN = (1<<1),
|
||||
TCL_STDOUT = (1<<2),
|
||||
TCL_STDERR = (1<<3),
|
||||
TCL_ENFORCE_MODE = (1<<4)
|
||||
};
|
||||
|
||||
/*
|
||||
* Bits passed to Tcl_DriverClose2Proc to indicate which side of a channel
|
||||
* should be closed.
|
||||
*/
|
||||
|
||||
#define TCL_CLOSE_READ (1<<1)
|
||||
#define TCL_CLOSE_WRITE (1<<2)
|
||||
enum TclChannelCloseFlags {
|
||||
TCL_CLOSE_READ = (1<<1),
|
||||
TCL_CLOSE_WRITE = (1<<2)
|
||||
};
|
||||
|
||||
/*
|
||||
* Value to use as the closeProc for a channel that supports the close2Proc
|
||||
@@ -1417,8 +1453,10 @@ typedef void (Tcl_ScaleTimeProc) (Tcl_Time *timebuf, ClientData clientData);
|
||||
* TIP #218: Channel Actions, Ids for Tcl_DriverThreadActionProc.
|
||||
*/
|
||||
|
||||
#define TCL_CHANNEL_THREAD_INSERT (0)
|
||||
#define TCL_CHANNEL_THREAD_REMOVE (1)
|
||||
enum TclChannelThreadActionOperations {
|
||||
TCL_CHANNEL_THREAD_INSERT = 0,
|
||||
TCL_CHANNEL_THREAD_REMOVE = 1
|
||||
};
|
||||
|
||||
/*
|
||||
* Typedefs for the various operations in a channel type:
|
||||
@@ -1479,8 +1517,8 @@ typedef struct Tcl_ChannelType {
|
||||
/* Version of the channel type. */
|
||||
Tcl_DriverCloseProc *closeProc;
|
||||
/* Function to call to close the channel, or
|
||||
* NULL or TCL_CLOSE2PROC if the close2Proc should be
|
||||
* used instead. */
|
||||
* NULL or TCL_CLOSE2PROC if the close2Proc
|
||||
* should be used instead. */
|
||||
Tcl_DriverInputProc *inputProc;
|
||||
/* Function to call for input on channel. */
|
||||
Tcl_DriverOutputProc *outputProc;
|
||||
@@ -1547,9 +1585,10 @@ typedef struct Tcl_ChannelType {
|
||||
* to the blockModeProc function in the above structure.
|
||||
*/
|
||||
|
||||
#define TCL_MODE_BLOCKING 0 /* Put channel into blocking mode. */
|
||||
#define TCL_MODE_NONBLOCKING 1 /* Put channel into nonblocking
|
||||
* mode. */
|
||||
enum TclChannelBlockModeFlags {
|
||||
TCL_MODE_BLOCKING = 0, /* Put channel into blocking mode. */
|
||||
TCL_MODE_NONBLOCKING = 1 /* Put channel into nonblocking mode. */
|
||||
};
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------------
|
||||
@@ -1578,27 +1617,33 @@ typedef struct Tcl_GlobTypeData {
|
||||
* Type and permission definitions for glob command.
|
||||
*/
|
||||
|
||||
#define TCL_GLOB_TYPE_BLOCK (1<<0)
|
||||
#define TCL_GLOB_TYPE_CHAR (1<<1)
|
||||
#define TCL_GLOB_TYPE_DIR (1<<2)
|
||||
#define TCL_GLOB_TYPE_PIPE (1<<3)
|
||||
#define TCL_GLOB_TYPE_FILE (1<<4)
|
||||
#define TCL_GLOB_TYPE_LINK (1<<5)
|
||||
#define TCL_GLOB_TYPE_SOCK (1<<6)
|
||||
#define TCL_GLOB_TYPE_MOUNT (1<<7)
|
||||
enum TclGlobTypes {
|
||||
TCL_GLOB_TYPE_BLOCK = (1<<0),
|
||||
TCL_GLOB_TYPE_CHAR = (1<<1),
|
||||
TCL_GLOB_TYPE_DIR = (1<<2),
|
||||
TCL_GLOB_TYPE_PIPE = (1<<3),
|
||||
TCL_GLOB_TYPE_FILE = (1<<4),
|
||||
TCL_GLOB_TYPE_LINK = (1<<5),
|
||||
TCL_GLOB_TYPE_SOCK = (1<<6),
|
||||
TCL_GLOB_TYPE_MOUNT = (1<<7)
|
||||
};
|
||||
|
||||
#define TCL_GLOB_PERM_RONLY (1<<0)
|
||||
#define TCL_GLOB_PERM_HIDDEN (1<<1)
|
||||
#define TCL_GLOB_PERM_R (1<<2)
|
||||
#define TCL_GLOB_PERM_W (1<<3)
|
||||
#define TCL_GLOB_PERM_X (1<<4)
|
||||
enum TclGlobPermissions {
|
||||
TCL_GLOB_PERM_RONLY = (1<<0),
|
||||
TCL_GLOB_PERM_HIDDEN = (1<<1),
|
||||
TCL_GLOB_PERM_R = (1<<2),
|
||||
TCL_GLOB_PERM_W = (1<<3),
|
||||
TCL_GLOB_PERM_X = (1<<4)
|
||||
};
|
||||
|
||||
/*
|
||||
* Flags for the unload callback function.
|
||||
*/
|
||||
|
||||
#define TCL_UNLOAD_DETACH_FROM_INTERPRETER (1<<0)
|
||||
#define TCL_UNLOAD_DETACH_FROM_PROCESS (1<<1)
|
||||
enum TclUnloadFlags {
|
||||
TCL_UNLOAD_DETACH_FROM_INTERPRETER = (1<<0),
|
||||
TCL_UNLOAD_DETACH_FROM_PROCESS = (1<<1)
|
||||
};
|
||||
|
||||
/*
|
||||
* Typedefs for the various filesystem operations:
|
||||
@@ -1804,8 +1849,10 @@ typedef struct Tcl_Filesystem {
|
||||
* TCL_CREATE_HARD_LINK - Create a hard link.
|
||||
*/
|
||||
|
||||
#define TCL_CREATE_SYMBOLIC_LINK 0x01
|
||||
#define TCL_CREATE_HARD_LINK 0x02
|
||||
enum TclFileLinkActions {
|
||||
TCL_CREATE_SYMBOLIC_LINK = 0x01,
|
||||
TCL_CREATE_HARD_LINK = 0x02
|
||||
};
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------------
|
||||
@@ -1848,99 +1895,101 @@ typedef struct Tcl_Token {
|
||||
/*
|
||||
* Type values defined for Tcl_Token structures. These values are defined as
|
||||
* mask bits so that it's easy to check for collections of types.
|
||||
*
|
||||
* TCL_TOKEN_WORD - The token describes one word of a command,
|
||||
* from the first non-blank character of the word
|
||||
* (which may be " or {) up to but not including
|
||||
* the space, semicolon, or bracket that
|
||||
* terminates the word. NumComponents counts the
|
||||
* total number of sub-tokens that make up the
|
||||
* word. This includes, for example, sub-tokens
|
||||
* of TCL_TOKEN_VARIABLE tokens.
|
||||
* TCL_TOKEN_SIMPLE_WORD - This token is just like TCL_TOKEN_WORD except
|
||||
* that the word is guaranteed to consist of a
|
||||
* single TCL_TOKEN_TEXT sub-token.
|
||||
* TCL_TOKEN_TEXT - The token describes a range of literal text
|
||||
* that is part of a word. NumComponents is
|
||||
* always 0.
|
||||
* TCL_TOKEN_BS - The token describes a backslash sequence that
|
||||
* must be collapsed. NumComponents is always 0.
|
||||
* TCL_TOKEN_COMMAND - The token describes a command whose result
|
||||
* must be substituted into the word. The token
|
||||
* includes the enclosing brackets. NumComponents
|
||||
* is always 0.
|
||||
* TCL_TOKEN_VARIABLE - The token describes a variable substitution,
|
||||
* including the dollar sign, variable name, and
|
||||
* array index (if there is one) up through the
|
||||
* right parentheses. NumComponents tells how
|
||||
* many additional tokens follow to represent the
|
||||
* variable name. The first token will be a
|
||||
* TCL_TOKEN_TEXT token that describes the
|
||||
* variable name. If the variable is an array
|
||||
* reference then there will be one or more
|
||||
* additional tokens, of type TCL_TOKEN_TEXT,
|
||||
* TCL_TOKEN_BS, TCL_TOKEN_COMMAND, and
|
||||
* TCL_TOKEN_VARIABLE, that describe the array
|
||||
* index; numComponents counts the total number
|
||||
* of nested tokens that make up the variable
|
||||
* reference, including sub-tokens of
|
||||
* TCL_TOKEN_VARIABLE tokens.
|
||||
* TCL_TOKEN_SUB_EXPR - The token describes one subexpression of an
|
||||
* expression, from the first non-blank character
|
||||
* of the subexpression up to but not including
|
||||
* the space, brace, or bracket that terminates
|
||||
* the subexpression. NumComponents counts the
|
||||
* total number of following subtokens that make
|
||||
* up the subexpression; this includes all
|
||||
* subtokens for any nested TCL_TOKEN_SUB_EXPR
|
||||
* tokens. For example, a numeric value used as a
|
||||
* primitive operand is described by a
|
||||
* TCL_TOKEN_SUB_EXPR token followed by a
|
||||
* TCL_TOKEN_TEXT token. A binary subexpression
|
||||
* is described by a TCL_TOKEN_SUB_EXPR token
|
||||
* followed by the TCL_TOKEN_OPERATOR token for
|
||||
* the operator, then TCL_TOKEN_SUB_EXPR tokens
|
||||
* for the left then the right operands.
|
||||
* TCL_TOKEN_OPERATOR - The token describes one expression operator.
|
||||
* An operator might be the name of a math
|
||||
* function such as "abs". A TCL_TOKEN_OPERATOR
|
||||
* token is always preceded by one
|
||||
* TCL_TOKEN_SUB_EXPR token for the operator's
|
||||
* subexpression, and is followed by zero or more
|
||||
* TCL_TOKEN_SUB_EXPR tokens for the operator's
|
||||
* operands. NumComponents is always 0.
|
||||
* TCL_TOKEN_EXPAND_WORD - This token is just like TCL_TOKEN_WORD except
|
||||
* that it marks a word that began with the
|
||||
* literal character prefix "{*}". This word is
|
||||
* marked to be expanded - that is, broken into
|
||||
* words after substitution is complete.
|
||||
*/
|
||||
|
||||
#define TCL_TOKEN_WORD 1
|
||||
#define TCL_TOKEN_SIMPLE_WORD 2
|
||||
#define TCL_TOKEN_TEXT 4
|
||||
#define TCL_TOKEN_BS 8
|
||||
#define TCL_TOKEN_COMMAND 16
|
||||
#define TCL_TOKEN_VARIABLE 32
|
||||
#define TCL_TOKEN_SUB_EXPR 64
|
||||
#define TCL_TOKEN_OPERATOR 128
|
||||
#define TCL_TOKEN_EXPAND_WORD 256
|
||||
enum TclTokenTypes {
|
||||
TCL_TOKEN_WORD = 1, /* The token describes one word of a command,
|
||||
* from the first non-blank character of the
|
||||
* word (which may be " or {) up to but not
|
||||
* including the space, semicolon, or bracket
|
||||
* that terminates the word. NumComponents
|
||||
* counts the total number of sub-tokens that
|
||||
* make up the word. This includes, for
|
||||
* example, sub-tokens of TCL_TOKEN_VARIABLE
|
||||
* tokens. */
|
||||
TCL_TOKEN_SIMPLE_WORD = 2, /* This token is just like TCL_TOKEN_WORD
|
||||
* except that the word is guaranteed to
|
||||
* consist of a single TCL_TOKEN_TEXT
|
||||
* sub-token. */
|
||||
TCL_TOKEN_TEXT = 4, /* The token describes a range of literal text
|
||||
* that is part of a word. NumComponents is
|
||||
* always 0. */
|
||||
TCL_TOKEN_BS = 8, /* The token describes a backslash sequence
|
||||
* that must be collapsed. NumComponents is
|
||||
* always 0. */
|
||||
TCL_TOKEN_COMMAND = 16, /* The token describes a command whose result
|
||||
* must be substituted into the word. The
|
||||
* token includes the enclosing brackets.
|
||||
* NumComponents is always 0. */
|
||||
TCL_TOKEN_VARIABLE = 32, /* The token describes a variable
|
||||
* substitution, including the dollar sign,
|
||||
* variable name, and array index (if there is
|
||||
* one) up through the right parentheses.
|
||||
* NumComponents tells how many additional
|
||||
* tokens follow to represent the variable
|
||||
* name. The first token will be a
|
||||
* TCL_TOKEN_TEXT token that describes the
|
||||
* variable name. If the variable is an array
|
||||
* reference then there will be one or more
|
||||
* additional tokens, of type TCL_TOKEN_TEXT,
|
||||
* TCL_TOKEN_BS, TCL_TOKEN_COMMAND, and
|
||||
* TCL_TOKEN_VARIABLE, that describe the array
|
||||
* index; numComponents counts the total
|
||||
* number of nested tokens that make up the
|
||||
* variable reference, including sub-tokens of
|
||||
* TCL_TOKEN_VARIABLE tokens. */
|
||||
TCL_TOKEN_SUB_EXPR = 64, /* The token describes one subexpression of an
|
||||
* expression, from the first non-blank
|
||||
* character of the subexpression up to but
|
||||
* not including the space, brace, or bracket
|
||||
* that terminates the subexpression.
|
||||
* NumComponents counts the total number of
|
||||
* following subtokens that make up the
|
||||
* subexpression; this includes all subtokens
|
||||
* for any nested TCL_TOKEN_SUB_EXPR tokens.
|
||||
* For example, a numeric value used as a
|
||||
* primitive operand is described by a
|
||||
* TCL_TOKEN_SUB_EXPR token followed by a
|
||||
* TCL_TOKEN_TEXT token. A binary
|
||||
* subexpression is described by a
|
||||
* TCL_TOKEN_SUB_EXPR token followed by the
|
||||
* TCL_TOKEN_OPERATOR token for the operator,
|
||||
* then TCL_TOKEN_SUB_EXPR tokens for the left
|
||||
* then the right operands. */
|
||||
TCL_TOKEN_OPERATOR = 128, /* The token describes one expression
|
||||
* operator. An operator might be the name of
|
||||
* a math function such as "abs". A
|
||||
* TCL_TOKEN_OPERATOR token is always preceded
|
||||
* by one TCL_TOKEN_SUB_EXPR token for the
|
||||
* operator's subexpression, and is followed
|
||||
* by zero or more TCL_TOKEN_SUB_EXPR tokens
|
||||
* for the operator's operands. NumComponents
|
||||
* is always 0. */
|
||||
TCL_TOKEN_EXPAND_WORD = 256 /* This token is just like TCL_TOKEN_WORD
|
||||
* except that it marks a word that began with
|
||||
* the literal character prefix "{*}". This
|
||||
* word is marked to be expanded - that is,
|
||||
* broken into words after substitution is
|
||||
* complete. */
|
||||
};
|
||||
|
||||
/*
|
||||
* Parsing error types. On any parsing error, one of these values will be
|
||||
* stored in the error field of the Tcl_Parse structure defined below.
|
||||
*/
|
||||
|
||||
#define TCL_PARSE_SUCCESS 0
|
||||
#define TCL_PARSE_QUOTE_EXTRA 1
|
||||
#define TCL_PARSE_BRACE_EXTRA 2
|
||||
#define TCL_PARSE_MISSING_BRACE 3
|
||||
#define TCL_PARSE_MISSING_BRACKET 4
|
||||
#define TCL_PARSE_MISSING_PAREN 5
|
||||
#define TCL_PARSE_MISSING_QUOTE 6
|
||||
#define TCL_PARSE_MISSING_VAR_BRACE 7
|
||||
#define TCL_PARSE_SYNTAX 8
|
||||
#define TCL_PARSE_BAD_NUMBER 9
|
||||
enum TclParsingErrors {
|
||||
TCL_PARSE_SUCCESS = 0,
|
||||
TCL_PARSE_QUOTE_EXTRA = 1,
|
||||
TCL_PARSE_BRACE_EXTRA = 2,
|
||||
TCL_PARSE_MISSING_BRACE = 3,
|
||||
TCL_PARSE_MISSING_BRACKET = 4,
|
||||
TCL_PARSE_MISSING_PAREN = 5,
|
||||
TCL_PARSE_MISSING_QUOTE = 6,
|
||||
TCL_PARSE_MISSING_VAR_BRACE = 7,
|
||||
TCL_PARSE_SYNTAX = 8,
|
||||
TCL_PARSE_BAD_NUMBER = 9
|
||||
};
|
||||
|
||||
/*
|
||||
* A structure of the following type is filled in by Tcl_ParseCommand. It
|
||||
@@ -2035,52 +2084,53 @@ typedef struct Tcl_EncodingType {
|
||||
/*
|
||||
* The following definitions are used as values for the conversion control
|
||||
* flags argument when converting text from one character set to another:
|
||||
*
|
||||
* TCL_ENCODING_START - Signifies that the source buffer is the first
|
||||
* block in a (potentially multi-block) input
|
||||
* stream. Tells the conversion function to reset
|
||||
* to an initial state and perform any
|
||||
* initialization that needs to occur before the
|
||||
* first byte is converted. If the source buffer
|
||||
* contains the entire input stream to be
|
||||
* converted, this flag should be set.
|
||||
* TCL_ENCODING_END - Signifies that the source buffer is the last
|
||||
* block in a (potentially multi-block) input
|
||||
* stream. Tells the conversion routine to
|
||||
* perform any finalization that needs to occur
|
||||
* after the last byte is converted and then to
|
||||
* reset to an initial state. If the source
|
||||
* buffer contains the entire input stream to be
|
||||
* converted, this flag should be set.
|
||||
* TCL_ENCODING_STOPONERROR - If set, the converter returns immediately upon
|
||||
* encountering an invalid byte sequence or a
|
||||
* source character that has no mapping in the
|
||||
* target encoding. If clear, the converter
|
||||
* substitues the problematic character(s) with
|
||||
* one or more "close" characters in the
|
||||
* destination buffer and then continues to
|
||||
* convert the source.
|
||||
* TCL_ENCODING_NO_TERMINATE - If set, Tcl_ExternalToUtf does not append a
|
||||
* terminating NUL byte. Since it does not need
|
||||
* an extra byte for a terminating NUL, it fills
|
||||
* all dstLen bytes with encoded UTF-8 content if
|
||||
* needed. If clear, a byte is reserved in the
|
||||
* dst space for NUL termination, and a
|
||||
* terminating NUL is appended.
|
||||
* TCL_ENCODING_CHAR_LIMIT - If set and dstCharsPtr is not NULL, then
|
||||
* Tcl_ExternalToUtf takes the initial value of
|
||||
* *dstCharsPtr as a limit of the maximum number
|
||||
* of chars to produce in the encoded UTF-8
|
||||
* content. Otherwise, the number of chars
|
||||
* produced is controlled only by other limiting
|
||||
* factors.
|
||||
*/
|
||||
|
||||
#define TCL_ENCODING_START 0x01
|
||||
#define TCL_ENCODING_END 0x02
|
||||
#define TCL_ENCODING_STOPONERROR 0x04
|
||||
#define TCL_ENCODING_NO_TERMINATE 0x08
|
||||
#define TCL_ENCODING_CHAR_LIMIT 0x10
|
||||
enum TclEncodingFlags {
|
||||
TCL_ENCODING_START = 1, /* Signifies that the source buffer is the
|
||||
* first block in a (potentially multi-block)
|
||||
* input stream. Tells the conversion function
|
||||
* to reset to an initial state and perform
|
||||
* any initialization that needs to occur
|
||||
* before the first byte is converted. If the
|
||||
* source buffer contains the entire input
|
||||
* stream to be converted, this flag should be
|
||||
* set. */
|
||||
TCL_ENCODING_END = 2, /* Signifies that the source buffer is the
|
||||
* last block in a (potentially multi-block)
|
||||
* input stream. Tells the conversion routine
|
||||
* to perform any finalization that needs to
|
||||
* occur after the last byte is converted and
|
||||
* then to reset to an initial state. If the
|
||||
* source buffer contains the entire input
|
||||
* stream to be converted, this flag should be
|
||||
* set. */
|
||||
TCL_ENCODING_STOPONERROR = 4,
|
||||
/* If set, the converter returns immediately
|
||||
* upon encountering an invalid byte sequence
|
||||
* or a source character that has no mapping
|
||||
* in the target encoding. If clear, the
|
||||
* converter substitues the problematic
|
||||
* character(s) with one or more "close"
|
||||
* characters in the destination buffer and
|
||||
* then continues to convert the source.*/
|
||||
TCL_ENCODING_NO_TERMINATE = 8,
|
||||
/* If set, Tcl_ExternalToUtf does not append a
|
||||
* terminating NUL byte. Since it does not
|
||||
* need an extra byte for a terminating NUL,
|
||||
* it fills all dstLen bytes with encoded
|
||||
* UTF-8 content if needed. If clear, a byte
|
||||
* is reserved in the dst space for NUL
|
||||
* termination, and a terminating NUL is
|
||||
* appended. */
|
||||
TCL_ENCODING_CHAR_LIMIT = 16/* If set and dstCharsPtr is not NULL, then
|
||||
* Tcl_ExternalToUtf takes the initial value
|
||||
* of *dstCharsPtr as a limit of the maximum
|
||||
* number of chars to produce in the encoded
|
||||
* UTF-8 content. Otherwise, the number of
|
||||
* chars produced is controlled only by other
|
||||
* limiting factors. */
|
||||
};
|
||||
|
||||
/*
|
||||
* The following definitions are the error codes returned by the conversion
|
||||
@@ -2163,8 +2213,10 @@ typedef struct Tcl_Config {
|
||||
* interpreter. Used for Tcl_{Add,Remove}LimitHandler type argument.
|
||||
*/
|
||||
|
||||
#define TCL_LIMIT_COMMANDS 0x01
|
||||
#define TCL_LIMIT_TIME 0x02
|
||||
enum TclLimitHandlerTypes {
|
||||
TCL_LIMIT_COMMANDS = 0x01,
|
||||
TCL_LIMIT_TIME = 0x02
|
||||
};
|
||||
|
||||
/*
|
||||
* Structure containing information about a limit handler to be called when a
|
||||
@@ -2218,15 +2270,17 @@ typedef struct {
|
||||
* documentation for details.
|
||||
*/
|
||||
|
||||
#define TCL_ARGV_CONSTANT 15
|
||||
#define TCL_ARGV_INT 16
|
||||
#define TCL_ARGV_STRING 17
|
||||
#define TCL_ARGV_REST 18
|
||||
#define TCL_ARGV_FLOAT 19
|
||||
#define TCL_ARGV_FUNC 20
|
||||
#define TCL_ARGV_GENFUNC 21
|
||||
#define TCL_ARGV_HELP 22
|
||||
#define TCL_ARGV_END 23
|
||||
enum TclArgvInfoTypes {
|
||||
TCL_ARGV_CONSTANT = 15,
|
||||
TCL_ARGV_INT = 16,
|
||||
TCL_ARGV_STRING = 17,
|
||||
TCL_ARGV_REST = 18,
|
||||
TCL_ARGV_FLOAT = 19,
|
||||
TCL_ARGV_FUNC = 20,
|
||||
TCL_ARGV_GENFUNC = 21,
|
||||
TCL_ARGV_HELP = 22,
|
||||
TCL_ARGV_END = 23
|
||||
};
|
||||
|
||||
/*
|
||||
* Types of callback functions for the TCL_ARGV_FUNC and TCL_ARGV_GENFUNC
|
||||
@@ -2260,18 +2314,20 @@ typedef int (Tcl_ArgvGenFuncProc)(ClientData clientData, Tcl_Interp *interp,
|
||||
* Tcl_ZlibStreamInit functions.
|
||||
*/
|
||||
|
||||
#define TCL_ZLIB_FORMAT_RAW 1
|
||||
#define TCL_ZLIB_FORMAT_ZLIB 2
|
||||
#define TCL_ZLIB_FORMAT_GZIP 4
|
||||
#define TCL_ZLIB_FORMAT_AUTO 8
|
||||
enum TclZlibFlags {
|
||||
TCL_ZLIB_FORMAT_RAW = 1,
|
||||
TCL_ZLIB_FORMAT_ZLIB = 2,
|
||||
TCL_ZLIB_FORMAT_GZIP = 4,
|
||||
TCL_ZLIB_FORMAT_AUTO = 8,
|
||||
|
||||
/*
|
||||
* Constants that describe whether the stream is to operate in compressing or
|
||||
* decompressing mode.
|
||||
*/
|
||||
/*
|
||||
* Constants that describe whether the stream is to operate in compressing
|
||||
* or decompressing mode.
|
||||
*/
|
||||
|
||||
#define TCL_ZLIB_STREAM_DEFLATE 16
|
||||
#define TCL_ZLIB_STREAM_INFLATE 32
|
||||
TCL_ZLIB_STREAM_DEFLATE = 16,
|
||||
TCL_ZLIB_STREAM_INFLATE = 32
|
||||
};
|
||||
|
||||
/*
|
||||
* Constants giving compression levels. Use of TCL_ZLIB_COMPRESS_DEFAULT is
|
||||
@@ -2287,25 +2343,32 @@ typedef int (Tcl_ArgvGenFuncProc)(ClientData clientData, Tcl_Interp *interp,
|
||||
* Constants for types of flushing, used with Tcl_ZlibFlush.
|
||||
*/
|
||||
|
||||
#define TCL_ZLIB_NO_FLUSH 0
|
||||
#define TCL_ZLIB_FLUSH 2
|
||||
#define TCL_ZLIB_FULLFLUSH 3
|
||||
#define TCL_ZLIB_FINALIZE 4
|
||||
enum TclZlibFlushModes {
|
||||
TCL_ZLIB_NO_FLUSH = 0,
|
||||
TCL_ZLIB_FLUSH = 2,
|
||||
TCL_ZLIB_FULLFLUSH = 3,
|
||||
TCL_ZLIB_FINALIZE = 4
|
||||
};
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------------
|
||||
* Definitions needed for the Tcl_LoadFile function. [TIP #416]
|
||||
*/
|
||||
|
||||
#define TCL_LOAD_GLOBAL 1
|
||||
#define TCL_LOAD_LAZY 2
|
||||
enum TclLoadFileFlags {
|
||||
TCL_LOAD_GLOBAL = 1,
|
||||
TCL_LOAD_LAZY = 2
|
||||
};
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------------
|
||||
* Definitions needed for the Tcl_OpenTcpServerEx function. [TIP #456]
|
||||
*/
|
||||
#define TCL_TCPSERVER_REUSEADDR (1<<0)
|
||||
#define TCL_TCPSERVER_REUSEPORT (1<<1)
|
||||
|
||||
enum TclOpenTcpServerFlags {
|
||||
TCL_TCPSERVER_REUSEADDR = (1<<0),
|
||||
TCL_TCPSERVER_REUSEPORT = (1<<1)
|
||||
};
|
||||
|
||||
/*
|
||||
* Constants for special int-typed values, see TIP #494
|
||||
|
||||
+3
-6
@@ -274,19 +274,16 @@ typedef struct ByteArray {
|
||||
* array. */
|
||||
unsigned int allocated; /* The amount of space actually allocated
|
||||
* minus 1 byte. */
|
||||
unsigned char bytes[TCLFLEXARRAY];
|
||||
/* The array of bytes. The actual size of this
|
||||
unsigned char bytes[TCLFLEXARRAY]; /* The array of bytes. The actual size of this
|
||||
* field depends on the 'allocated' field
|
||||
* above. */
|
||||
} ByteArray;
|
||||
|
||||
#define BYTEARRAY_SIZE(len) \
|
||||
(offsetof(ByteArray, bytes) + (len))
|
||||
(offsetof(ByteArray, bytes) + (len))
|
||||
#define GET_BYTEARRAY(irPtr) ((ByteArray *) (irPtr)->twoPtrValue.ptr1)
|
||||
#define SET_BYTEARRAY(irPtr, baPtr) \
|
||||
do { \
|
||||
(irPtr)->twoPtrValue.ptr1 = (void *) (baPtr); \
|
||||
} while (0)
|
||||
(irPtr)->twoPtrValue.ptr1 = (void *) (baPtr)
|
||||
|
||||
int
|
||||
TclIsPureByteArray(
|
||||
|
||||
+1
-1
@@ -86,7 +86,7 @@ typedef struct {
|
||||
* following values.
|
||||
*/
|
||||
|
||||
enum {
|
||||
enum SortModeFlags {
|
||||
SORTMODE_ASCII = 0,
|
||||
SORTMODE_INTEGER = 1,
|
||||
SORTMODE_REAL = 2,
|
||||
|
||||
+290
-291
File diff suppressed because it is too large
Load Diff
+210
-242
@@ -27,31 +27,6 @@ static void CompileReturnInternal(CompileEnv *envPtr,
|
||||
Tcl_Obj *returnOpts);
|
||||
static int IndexTailVarIfKnown(Tcl_Interp *interp,
|
||||
Tcl_Token *varTokenPtr, CompileEnv *envPtr);
|
||||
|
||||
/*
|
||||
* Shorthand macros for instruction issuing.
|
||||
*/
|
||||
|
||||
#define OP(name) TclEmitOpcode(INST_##name, envPtr)
|
||||
#define OP1(name,val) TclEmitInstInt1(INST_##name,(val),envPtr)
|
||||
#define OP4(name,val) TclEmitInstInt4(INST_##name,(val),envPtr)
|
||||
#define OP11(name,val1,val2) TclEmitInstInt11(INST_##name,(val1),(val2),envPtr)
|
||||
#define OP14(name,val1,val2) TclEmitInstInt14(INST_##name,(val1),(val2),envPtr)
|
||||
#define OP44(name,val1,val2) TclEmitInstInt44(INST_##name,(val1),(val2),envPtr)
|
||||
#define PUSH(str) PushStringLiteral(envPtr, str)
|
||||
#define JUMP4(name,var) \
|
||||
(var) = CurrentOffset(envPtr);TclEmitInstInt4(INST_##name##4,0,envPtr)
|
||||
#define FIXJUMP4(var) \
|
||||
TclStoreInt4AtPtr(CurrentOffset(envPtr)-(var),envPtr->codeStart+(var)+1)
|
||||
#define JUMP1(name,var) \
|
||||
(var) = CurrentOffset(envPtr);TclEmitInstInt1(INST_##name##1,0,envPtr)
|
||||
#define FIXJUMP1(var) \
|
||||
TclStoreInt1AtPtr(CurrentOffset(envPtr)-(var),envPtr->codeStart+(var)+1)
|
||||
#define LOAD(idx) \
|
||||
if ((idx)<256) {OP1(LOAD_SCALAR1,(idx));} else {OP4(LOAD_SCALAR4,(idx));}
|
||||
#define STORE(idx) \
|
||||
if ((idx)<256) {OP1(STORE_SCALAR1,(idx));} else {OP4(STORE_SCALAR4,(idx));}
|
||||
#define INVOKE(name) TclEmitInvoke(envPtr,INST_##name)
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
@@ -137,7 +112,7 @@ TclCompileGlobalCmd(
|
||||
* Push the namespace
|
||||
*/
|
||||
|
||||
PUSH( "::");
|
||||
PushStringLiteral(envPtr, "::");
|
||||
|
||||
/*
|
||||
* Loop over the variables.
|
||||
@@ -158,15 +133,15 @@ TclCompileGlobalCmd(
|
||||
*/
|
||||
|
||||
CompileWord(envPtr, varTokenPtr, interp, i);
|
||||
OP4( NSUPVAR, localIndex);
|
||||
TclEmitInstInt4( INST_NSUPVAR, localIndex, envPtr);
|
||||
}
|
||||
|
||||
/*
|
||||
* Pop the namespace, and set the result to empty
|
||||
*/
|
||||
|
||||
OP( POP);
|
||||
PUSH( "");
|
||||
TclEmitOpcode( INST_POP, envPtr);
|
||||
PushStringLiteral(envPtr, "");
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -188,30 +163,6 @@ TclCompileGlobalCmd(
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static inline int
|
||||
IsElseToken(
|
||||
const Tcl_Token *tokenPtr)
|
||||
{
|
||||
return (tokenPtr->size == 4) &&
|
||||
(strncmp(tokenPtr->start, "else", 4) == 0);
|
||||
}
|
||||
|
||||
static inline int
|
||||
IsElseifToken(
|
||||
const Tcl_Token *tokenPtr)
|
||||
{
|
||||
return (tokenPtr->size == 6) &&
|
||||
(strncmp(tokenPtr->start, "elseif", 6) == 0);
|
||||
}
|
||||
|
||||
static inline int
|
||||
IsThenToken(
|
||||
const Tcl_Token *tokenPtr)
|
||||
{
|
||||
return (tokenPtr->size == 4) &&
|
||||
(strncmp(tokenPtr->start, "then", 4) == 0);
|
||||
}
|
||||
|
||||
int
|
||||
TclCompileIfCmd(
|
||||
Tcl_Interp *interp, /* Used for error reporting. */
|
||||
@@ -230,7 +181,8 @@ TclCompileIfCmd(
|
||||
* determined. */
|
||||
Tcl_Token *tokenPtr, *testTokenPtr;
|
||||
int jumpIndex = 0; /* Avoid compiler warning. */
|
||||
int jumpFalseDist, numWords, wordIdx, j, code;
|
||||
int jumpFalseDist, numWords, wordIdx, numBytes, j, code;
|
||||
const char *word;
|
||||
int realCond = 1; /* Set to 0 for static conditions:
|
||||
* "if 0 {..}" */
|
||||
int boolVal; /* Value of static condition. */
|
||||
@@ -268,7 +220,10 @@ TclCompileIfCmd(
|
||||
* Stop looping if the token isn't "if" or "elseif".
|
||||
*/
|
||||
|
||||
if ((tokenPtr == parsePtr->tokenPtr) || IsElseifToken(&tokenPtr[1])) {
|
||||
word = tokenPtr[1].start;
|
||||
numBytes = tokenPtr[1].size;
|
||||
if ((tokenPtr == parsePtr->tokenPtr)
|
||||
|| ((numBytes == 6) && (strncmp(word, "elseif", 6) == 0))) {
|
||||
tokenPtr = TokenAfter(tokenPtr);
|
||||
wordIdx++;
|
||||
} else {
|
||||
@@ -331,12 +286,16 @@ TclCompileIfCmd(
|
||||
code = TCL_ERROR;
|
||||
goto done;
|
||||
}
|
||||
if (IsThenToken(&tokenPtr[1])) {
|
||||
tokenPtr = TokenAfter(tokenPtr);
|
||||
wordIdx++;
|
||||
if (wordIdx >= numWords) {
|
||||
code = TCL_ERROR;
|
||||
goto done;
|
||||
if (tokenPtr->type == TCL_TOKEN_SIMPLE_WORD) {
|
||||
word = tokenPtr[1].start;
|
||||
numBytes = tokenPtr[1].size;
|
||||
if ((numBytes == 4) && (strncmp(word, "then", 4) == 0)) {
|
||||
tokenPtr = TokenAfter(tokenPtr);
|
||||
wordIdx++;
|
||||
if (wordIdx >= numWords) {
|
||||
code = TCL_ERROR;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -404,12 +363,14 @@ TclCompileIfCmd(
|
||||
* an "if 1 {...}" case.
|
||||
*/
|
||||
|
||||
if (wordIdx < numWords) {
|
||||
if ((wordIdx < numWords) && (tokenPtr->type == TCL_TOKEN_SIMPLE_WORD)) {
|
||||
/*
|
||||
* There is an else clause. Skip over the optional "else" word.
|
||||
*/
|
||||
|
||||
if (IsElseToken(&tokenPtr[1])) {
|
||||
word = tokenPtr[1].start;
|
||||
numBytes = tokenPtr[1].size;
|
||||
if ((numBytes == 4) && (strncmp(word, "else", 4) == 0)) {
|
||||
tokenPtr = TokenAfter(tokenPtr);
|
||||
wordIdx++;
|
||||
if (wordIdx >= numWords) {
|
||||
@@ -441,7 +402,7 @@ TclCompileIfCmd(
|
||||
*/
|
||||
|
||||
if (compileScripts) {
|
||||
PUSH("");
|
||||
PushStringLiteral(envPtr, "");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -564,29 +525,31 @@ TclCompileIncrCmd(
|
||||
if (isScalar) { /* Simple scalar variable. */
|
||||
if (localIndex >= 0) {
|
||||
if (haveImmValue) {
|
||||
OP11( INCR_SCALAR1_IMM, localIndex, immValue);
|
||||
TclEmitInstInt1(INST_INCR_SCALAR1_IMM, localIndex, envPtr);
|
||||
TclEmitInt1(immValue, envPtr);
|
||||
} else {
|
||||
OP1( INCR_SCALAR1, localIndex);
|
||||
TclEmitInstInt1(INST_INCR_SCALAR1, localIndex, envPtr);
|
||||
}
|
||||
} else {
|
||||
if (haveImmValue) {
|
||||
OP1( INCR_STK_IMM, immValue);
|
||||
TclEmitInstInt1(INST_INCR_STK_IMM, immValue, envPtr);
|
||||
} else {
|
||||
OP( INCR_STK);
|
||||
TclEmitOpcode( INST_INCR_STK, envPtr);
|
||||
}
|
||||
}
|
||||
} else { /* Simple array variable. */
|
||||
if (localIndex >= 0) {
|
||||
if (haveImmValue) {
|
||||
OP11( INCR_ARRAY1_IMM, localIndex, immValue);
|
||||
TclEmitInstInt1(INST_INCR_ARRAY1_IMM, localIndex, envPtr);
|
||||
TclEmitInt1(immValue, envPtr);
|
||||
} else {
|
||||
OP1( INCR_ARRAY1, localIndex);
|
||||
TclEmitInstInt1(INST_INCR_ARRAY1, localIndex, envPtr);
|
||||
}
|
||||
} else {
|
||||
if (haveImmValue) {
|
||||
OP1( INCR_ARRAY_STK_IMM, immValue);
|
||||
TclEmitInstInt1(INST_INCR_ARRAY_STK_IMM, immValue, envPtr);
|
||||
} else {
|
||||
OP( INCR_ARRAY_STK);
|
||||
TclEmitOpcode( INST_INCR_ARRAY_STK, envPtr);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -661,11 +624,11 @@ TclCompileInfoCommandsCmd(
|
||||
|
||||
/* TODO: Just push the known value */
|
||||
CompileWord(envPtr, tokenPtr, interp, 1);
|
||||
OP( RESOLVE_COMMAND);
|
||||
OP( DUP);
|
||||
OP( STR_LEN);
|
||||
OP1( JUMP_FALSE1, 7);
|
||||
OP4( LIST, 1);
|
||||
TclEmitOpcode( INST_RESOLVE_COMMAND, envPtr);
|
||||
TclEmitOpcode( INST_DUP, envPtr);
|
||||
TclEmitOpcode( INST_STR_LEN, envPtr);
|
||||
TclEmitInstInt1( INST_JUMP_FALSE1, 7, envPtr);
|
||||
TclEmitInstInt4( INST_LIST, 1, envPtr);
|
||||
return TCL_OK;
|
||||
|
||||
notCompilable:
|
||||
@@ -693,7 +656,7 @@ TclCompileInfoCoroutineCmd(
|
||||
* Not much to do; we compile to a single instruction...
|
||||
*/
|
||||
|
||||
OP( COROUTINE_NAME);
|
||||
TclEmitOpcode( INST_COROUTINE_NAME, envPtr);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -730,15 +693,15 @@ TclCompileInfoExistsCmd(
|
||||
|
||||
if (isScalar) {
|
||||
if (localIndex < 0) {
|
||||
OP( EXIST_STK);
|
||||
TclEmitOpcode( INST_EXIST_STK, envPtr);
|
||||
} else {
|
||||
OP4( EXIST_SCALAR, localIndex);
|
||||
TclEmitInstInt4( INST_EXIST_SCALAR, localIndex, envPtr);
|
||||
}
|
||||
} else {
|
||||
if (localIndex < 0) {
|
||||
OP( EXIST_ARRAY_STK);
|
||||
TclEmitOpcode( INST_EXIST_ARRAY_STK, envPtr);
|
||||
} else {
|
||||
OP4( EXIST_ARRAY, localIndex);
|
||||
TclEmitInstInt4( INST_EXIST_ARRAY, localIndex, envPtr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -762,7 +725,7 @@ TclCompileInfoLevelCmd(
|
||||
* Not much to do; we compile to a single instruction...
|
||||
*/
|
||||
|
||||
OP( INFO_LEVEL_NUM);
|
||||
TclEmitOpcode( INST_INFO_LEVEL_NUM, envPtr);
|
||||
} else if (parsePtr->numWords != 2) {
|
||||
return TCL_ERROR;
|
||||
} else {
|
||||
@@ -774,7 +737,7 @@ TclCompileInfoLevelCmd(
|
||||
*/
|
||||
|
||||
CompileWord(envPtr, TokenAfter(parsePtr->tokenPtr), interp, 1);
|
||||
OP( INFO_LEVEL_ARGS);
|
||||
TclEmitOpcode( INST_INFO_LEVEL_ARGS, envPtr);
|
||||
}
|
||||
return TCL_OK;
|
||||
}
|
||||
@@ -794,7 +757,7 @@ TclCompileInfoObjectClassCmd(
|
||||
return TCL_ERROR;
|
||||
}
|
||||
CompileWord(envPtr, tokenPtr, interp, 1);
|
||||
OP( TCLOO_CLASS);
|
||||
TclEmitOpcode( INST_TCLOO_CLASS, envPtr);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -829,7 +792,7 @@ TclCompileInfoObjectIsACmd(
|
||||
*/
|
||||
|
||||
CompileWord(envPtr, tokenPtr, interp, 2);
|
||||
OP( TCLOO_IS_OBJECT);
|
||||
TclEmitOpcode( INST_TCLOO_IS_OBJECT, envPtr);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -848,7 +811,7 @@ TclCompileInfoObjectNamespaceCmd(
|
||||
return TCL_ERROR;
|
||||
}
|
||||
CompileWord(envPtr, tokenPtr, interp, 1);
|
||||
OP( TCLOO_NS);
|
||||
TclEmitOpcode( INST_TCLOO_NS, envPtr);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -927,15 +890,15 @@ TclCompileLappendCmd(
|
||||
|
||||
if (isScalar) {
|
||||
if (localIndex < 0) {
|
||||
OP( LAPPEND_STK);
|
||||
TclEmitOpcode( INST_LAPPEND_STK, envPtr);
|
||||
} else {
|
||||
Emit14Inst( INST_LAPPEND_SCALAR, localIndex, envPtr);
|
||||
Emit14Inst( INST_LAPPEND_SCALAR, localIndex, envPtr);
|
||||
}
|
||||
} else {
|
||||
if (localIndex < 0) {
|
||||
OP( LAPPEND_ARRAY_STK);
|
||||
TclEmitOpcode( INST_LAPPEND_ARRAY_STK, envPtr);
|
||||
} else {
|
||||
Emit14Inst( INST_LAPPEND_ARRAY, localIndex, envPtr);
|
||||
Emit14Inst( INST_LAPPEND_ARRAY, localIndex, envPtr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -950,18 +913,18 @@ TclCompileLappendCmd(
|
||||
CompileWord(envPtr, valueTokenPtr, interp, i);
|
||||
valueTokenPtr = TokenAfter(valueTokenPtr);
|
||||
}
|
||||
OP4( LIST, numWords - 2);
|
||||
TclEmitInstInt4( INST_LIST, numWords - 2, envPtr);
|
||||
if (isScalar) {
|
||||
if (localIndex < 0) {
|
||||
OP( LAPPEND_LIST_STK);
|
||||
TclEmitOpcode( INST_LAPPEND_LIST_STK, envPtr);
|
||||
} else {
|
||||
OP4( LAPPEND_LIST, localIndex);
|
||||
TclEmitInstInt4(INST_LAPPEND_LIST, localIndex, envPtr);
|
||||
}
|
||||
} else {
|
||||
if (localIndex < 0) {
|
||||
OP( LAPPEND_LIST_ARRAY_STK);
|
||||
TclEmitOpcode( INST_LAPPEND_LIST_ARRAY_STK, envPtr);
|
||||
} else {
|
||||
OP4( LAPPEND_LIST_ARRAY, localIndex);
|
||||
TclEmitInstInt4(INST_LAPPEND_LIST_ARRAY, localIndex,envPtr);
|
||||
}
|
||||
}
|
||||
return TCL_OK;
|
||||
@@ -1035,27 +998,27 @@ TclCompileLassignCmd(
|
||||
|
||||
if (isScalar) {
|
||||
if (localIndex >= 0) {
|
||||
OP( DUP);
|
||||
OP4( LIST_INDEX_IMM, idx);
|
||||
TclEmitOpcode( INST_DUP, envPtr);
|
||||
TclEmitInstInt4(INST_LIST_INDEX_IMM, idx, envPtr);
|
||||
Emit14Inst( INST_STORE_SCALAR, localIndex, envPtr);
|
||||
OP( POP);
|
||||
TclEmitOpcode( INST_POP, envPtr);
|
||||
} else {
|
||||
OP4( OVER, 1);
|
||||
OP4( LIST_INDEX_IMM, idx);
|
||||
OP( STORE_STK);
|
||||
OP( POP);
|
||||
TclEmitInstInt4(INST_OVER, 1, envPtr);
|
||||
TclEmitInstInt4(INST_LIST_INDEX_IMM, idx, envPtr);
|
||||
TclEmitOpcode( INST_STORE_STK, envPtr);
|
||||
TclEmitOpcode( INST_POP, envPtr);
|
||||
}
|
||||
} else {
|
||||
if (localIndex >= 0) {
|
||||
OP4( OVER, 1);
|
||||
OP4( LIST_INDEX_IMM, idx);
|
||||
TclEmitInstInt4(INST_OVER, 1, envPtr);
|
||||
TclEmitInstInt4(INST_LIST_INDEX_IMM, idx, envPtr);
|
||||
Emit14Inst( INST_STORE_ARRAY, localIndex, envPtr);
|
||||
OP( POP);
|
||||
TclEmitOpcode( INST_POP, envPtr);
|
||||
} else {
|
||||
OP4( OVER, 2);
|
||||
OP4( LIST_INDEX_IMM, idx);
|
||||
OP( STORE_ARRAY_STK);
|
||||
OP( POP);
|
||||
TclEmitInstInt4(INST_OVER, 2, envPtr);
|
||||
TclEmitInstInt4(INST_LIST_INDEX_IMM, idx, envPtr);
|
||||
TclEmitOpcode( INST_STORE_ARRAY_STK, envPtr);
|
||||
TclEmitOpcode( INST_POP, envPtr);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1064,7 +1027,8 @@ TclCompileLassignCmd(
|
||||
* Generate code to leave the rest of the list on the stack.
|
||||
*/
|
||||
|
||||
OP44( LIST_RANGE_IMM, idx, (int) TCL_INDEX_END);
|
||||
TclEmitInstInt4( INST_LIST_RANGE_IMM, idx, envPtr);
|
||||
TclEmitInt4( (int)TCL_INDEX_END, envPtr);
|
||||
|
||||
return TCL_OK;
|
||||
}
|
||||
@@ -1125,7 +1089,7 @@ TclCompileLindexCmd(
|
||||
*/
|
||||
|
||||
CompileWord(envPtr, valTokenPtr, interp, 1);
|
||||
OP4( LIST_INDEX_IMM, idx);
|
||||
TclEmitInstInt4( INST_LIST_INDEX_IMM, idx, envPtr);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -1151,9 +1115,9 @@ TclCompileLindexCmd(
|
||||
*/
|
||||
|
||||
if (numWords == 3) {
|
||||
OP( LIST_INDEX);
|
||||
TclEmitOpcode( INST_LIST_INDEX, envPtr);
|
||||
} else {
|
||||
OP4( LIST_INDEX_MULTI, numWords - 1);
|
||||
TclEmitInstInt4( INST_LIST_INDEX_MULTI, numWords-1, envPtr);
|
||||
}
|
||||
|
||||
return TCL_OK;
|
||||
@@ -1195,7 +1159,7 @@ TclCompileListCmd(
|
||||
* [list] without arguments just pushes an empty object.
|
||||
*/
|
||||
|
||||
PUSH("");
|
||||
PushStringLiteral(envPtr, "");
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -1232,9 +1196,9 @@ TclCompileListCmd(
|
||||
concat = build = 0;
|
||||
for (i = 1; i < numWords; i++) {
|
||||
if (valueTokenPtr->type == TCL_TOKEN_EXPAND_WORD && build > 0) {
|
||||
OP4( LIST, build);
|
||||
TclEmitInstInt4( INST_LIST, build, envPtr);
|
||||
if (concat) {
|
||||
OP( LIST_CONCAT);
|
||||
TclEmitOpcode( INST_LIST_CONCAT, envPtr);
|
||||
}
|
||||
build = 0;
|
||||
concat = 1;
|
||||
@@ -1242,7 +1206,7 @@ TclCompileListCmd(
|
||||
CompileWord(envPtr, valueTokenPtr, interp, i);
|
||||
if (valueTokenPtr->type == TCL_TOKEN_EXPAND_WORD) {
|
||||
if (concat) {
|
||||
OP( LIST_CONCAT);
|
||||
TclEmitOpcode( INST_LIST_CONCAT, envPtr);
|
||||
} else {
|
||||
concat = 1;
|
||||
}
|
||||
@@ -1252,9 +1216,9 @@ TclCompileListCmd(
|
||||
valueTokenPtr = TokenAfter(valueTokenPtr);
|
||||
}
|
||||
if (build > 0) {
|
||||
OP4( LIST, build);
|
||||
TclEmitInstInt4( INST_LIST, build, envPtr);
|
||||
if (concat) {
|
||||
OP( LIST_CONCAT);
|
||||
TclEmitOpcode( INST_LIST_CONCAT, envPtr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1266,7 +1230,8 @@ TclCompileListCmd(
|
||||
*/
|
||||
|
||||
if (concat && numWords == 2) {
|
||||
OP44( LIST_RANGE_IMM, 0, (int) TCL_INDEX_END);
|
||||
TclEmitInstInt4( INST_LIST_RANGE_IMM, 0, envPtr);
|
||||
TclEmitInt4( (int)TCL_INDEX_END, envPtr);
|
||||
}
|
||||
return TCL_OK;
|
||||
}
|
||||
@@ -1306,7 +1271,7 @@ TclCompileLlengthCmd(
|
||||
varTokenPtr = TokenAfter(parsePtr->tokenPtr);
|
||||
|
||||
CompileWord(envPtr, varTokenPtr, interp, 1);
|
||||
OP( LIST_LENGTH);
|
||||
TclEmitOpcode( INST_LIST_LENGTH, envPtr);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -1344,8 +1309,8 @@ TclCompileLrangeCmd(
|
||||
return TCL_ERROR;
|
||||
}
|
||||
/*
|
||||
* Token was an index value, and we treat all "first" indices before the
|
||||
* list same as the start of the list.
|
||||
* Token was an index value, and we treat all "first" indices
|
||||
* before the list same as the start of the list.
|
||||
*/
|
||||
|
||||
tokenPtr = TokenAfter(tokenPtr);
|
||||
@@ -1353,10 +1318,9 @@ TclCompileLrangeCmd(
|
||||
&idx2) != TCL_OK) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Token was an index value, and we treat all "last" indices after the
|
||||
* list same as the end of the list.
|
||||
* Token was an index value, and we treat all "last" indices
|
||||
* after the list same as the end of the list.
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -1366,7 +1330,8 @@ TclCompileLrangeCmd(
|
||||
*/
|
||||
|
||||
CompileWord(envPtr, listTokenPtr, interp, 1);
|
||||
OP44( LIST_RANGE_IMM, idx1, idx2);
|
||||
TclEmitInstInt4( INST_LIST_RANGE_IMM, idx1, envPtr);
|
||||
TclEmitInt4( idx2, envPtr);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -1407,11 +1372,11 @@ TclCompileLinsertCmd(
|
||||
tokenPtr = TokenAfter(listTokenPtr);
|
||||
|
||||
/*
|
||||
* NOTE: This command treats all inserts at indices before the list the
|
||||
* same as inserts at the start of the list, and all inserts after the
|
||||
* list the same as inserts at the end of the list. We make that
|
||||
* transformation here so we can use the optimized bytecode as much as
|
||||
* possible.
|
||||
* NOTE: This command treats all inserts at indices before the list
|
||||
* the same as inserts at the start of the list, and all inserts
|
||||
* after the list the same as inserts at the end of the list. We
|
||||
* make that transformation here so we can use the optimized bytecode
|
||||
* as much as possible.
|
||||
*/
|
||||
if (TclGetIndexFromToken(tokenPtr, TCL_INDEX_START, TCL_INDEX_END,
|
||||
&idx) != TCL_OK) {
|
||||
@@ -1427,7 +1392,8 @@ TclCompileLinsertCmd(
|
||||
|
||||
CompileWord(envPtr, listTokenPtr, interp, 1);
|
||||
if (parsePtr->numWords == 3) {
|
||||
OP44( LIST_RANGE_IMM, 0, (int) TCL_INDEX_END);
|
||||
TclEmitInstInt4( INST_LIST_RANGE_IMM, 0, envPtr);
|
||||
TclEmitInt4( (int)TCL_INDEX_END, envPtr);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -1435,13 +1401,13 @@ TclCompileLinsertCmd(
|
||||
tokenPtr = TokenAfter(tokenPtr);
|
||||
CompileWord(envPtr, tokenPtr, interp, i);
|
||||
}
|
||||
OP4( LIST, i - 3);
|
||||
TclEmitInstInt4( INST_LIST, i - 3, envPtr);
|
||||
|
||||
if (idx == (int) TCL_INDEX_START) {
|
||||
OP4( REVERSE, 2);
|
||||
OP( LIST_CONCAT);
|
||||
} else if (idx == (int) TCL_INDEX_END) {
|
||||
OP( LIST_CONCAT);
|
||||
if (idx == (int)TCL_INDEX_START) {
|
||||
TclEmitInstInt4( INST_REVERSE, 2, envPtr);
|
||||
TclEmitOpcode( INST_LIST_CONCAT, envPtr);
|
||||
} else if (idx == (int)TCL_INDEX_END) {
|
||||
TclEmitOpcode( INST_LIST_CONCAT, envPtr);
|
||||
} else {
|
||||
/*
|
||||
* Here we handle two ranges for idx. First when idx > 0, we
|
||||
@@ -1458,12 +1424,14 @@ TclCompileLinsertCmd(
|
||||
if (idx < (int)TCL_INDEX_END) {
|
||||
idx++;
|
||||
}
|
||||
OP4( OVER, 1);
|
||||
OP44( LIST_RANGE_IMM, 0, idx - 1);
|
||||
OP4( REVERSE, 3);
|
||||
OP44( LIST_RANGE_IMM, idx, (int) TCL_INDEX_END);
|
||||
OP( LIST_CONCAT);
|
||||
OP( LIST_CONCAT);
|
||||
TclEmitInstInt4( INST_OVER, 1, envPtr);
|
||||
TclEmitInstInt4( INST_LIST_RANGE_IMM, 0, envPtr);
|
||||
TclEmitInt4( idx - 1, envPtr);
|
||||
TclEmitInstInt4( INST_REVERSE, 3, envPtr);
|
||||
TclEmitInstInt4( INST_LIST_RANGE_IMM, idx, envPtr);
|
||||
TclEmitInt4( (int)TCL_INDEX_END, envPtr);
|
||||
TclEmitOpcode( INST_LIST_CONCAT, envPtr);
|
||||
TclEmitOpcode( INST_LIST_CONCAT, envPtr);
|
||||
}
|
||||
|
||||
return TCL_OK;
|
||||
@@ -1534,17 +1502,13 @@ TclCompileLreplaceCmd(
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* All paths start with computing/pushing the original value.
|
||||
*/
|
||||
|
||||
/* All paths start with computing/pushing the original value. */
|
||||
CompileWord(envPtr, listTokenPtr, interp, 1);
|
||||
|
||||
/*
|
||||
* Push all the replacement values next so any errors raised in creating
|
||||
* them get raised first.
|
||||
* Push all the replacement values next so any errors raised in
|
||||
* creating them get raised first.
|
||||
*/
|
||||
|
||||
if (parsePtr->numWords > 4) {
|
||||
/* Push the replacement arguments */
|
||||
tokenPtr = TokenAfter(tokenPtr);
|
||||
@@ -1554,7 +1518,7 @@ TclCompileLreplaceCmd(
|
||||
}
|
||||
|
||||
/* Make a list of them... */
|
||||
OP4( LIST, i - 4);
|
||||
TclEmitInstInt4( INST_LIST, i - 4, envPtr);
|
||||
|
||||
emptyPrefix = 0;
|
||||
}
|
||||
@@ -1562,42 +1526,45 @@ TclCompileLreplaceCmd(
|
||||
if ((idx1 == suffixStart) && (parsePtr->numWords == 4)) {
|
||||
/*
|
||||
* This is a "no-op". Example: [lreplace {a b c} 2 0]
|
||||
* We still do a list operation to get list-verification and
|
||||
* canonicalization side effects.
|
||||
* We still do a list operation to get list-verification
|
||||
* and canonicalization side effects.
|
||||
*/
|
||||
OP44( LIST_RANGE_IMM, 0, (int) TCL_INDEX_END);
|
||||
TclEmitInstInt4( INST_LIST_RANGE_IMM, 0, envPtr);
|
||||
TclEmitInt4( (int)TCL_INDEX_END, envPtr);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
if (idx1 != (int) TCL_INDEX_START) {
|
||||
if (idx1 != (int)TCL_INDEX_START) {
|
||||
/* Prefix may not be empty; generate bytecode to push it */
|
||||
if (emptyPrefix) {
|
||||
OP( DUP);
|
||||
TclEmitOpcode( INST_DUP, envPtr);
|
||||
} else {
|
||||
OP4( OVER, 1);
|
||||
TclEmitInstInt4( INST_OVER, 1, envPtr);
|
||||
}
|
||||
OP44( LIST_RANGE_IMM, 0, idx1 - 1);
|
||||
TclEmitInstInt4( INST_LIST_RANGE_IMM, 0, envPtr);
|
||||
TclEmitInt4( idx1 - 1, envPtr);
|
||||
if (!emptyPrefix) {
|
||||
OP4( REVERSE, 2);
|
||||
OP( LIST_CONCAT);
|
||||
TclEmitInstInt4( INST_REVERSE, 2, envPtr);
|
||||
TclEmitOpcode( INST_LIST_CONCAT, envPtr);
|
||||
}
|
||||
emptyPrefix = 0;
|
||||
}
|
||||
|
||||
if (!emptyPrefix) {
|
||||
OP4( REVERSE, 2);
|
||||
TclEmitInstInt4( INST_REVERSE, 2, envPtr);
|
||||
}
|
||||
|
||||
if (suffixStart == (int) TCL_INDEX_NONE) {
|
||||
OP( POP);
|
||||
if (suffixStart == (int)TCL_INDEX_NONE) {
|
||||
TclEmitOpcode( INST_POP, envPtr);
|
||||
if (emptyPrefix) {
|
||||
PUSH( "");
|
||||
PushStringLiteral(envPtr, "");
|
||||
}
|
||||
} else {
|
||||
/* Suffix may not be empty; generate bytecode to push it */
|
||||
OP44( LIST_RANGE_IMM, suffixStart, (int) TCL_INDEX_END);
|
||||
TclEmitInstInt4( INST_LIST_RANGE_IMM, suffixStart, envPtr);
|
||||
TclEmitInt4( (int)TCL_INDEX_END, envPtr);
|
||||
if (!emptyPrefix) {
|
||||
OP( LIST_CONCAT);
|
||||
TclEmitOpcode( INST_LIST_CONCAT, envPtr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1705,7 +1672,7 @@ TclCompileLsetCmd(
|
||||
} else {
|
||||
tempDepth = parsePtr->numWords - 1;
|
||||
}
|
||||
OP4( OVER, tempDepth);
|
||||
TclEmitInstInt4( INST_OVER, tempDepth, envPtr);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1718,7 +1685,7 @@ TclCompileLsetCmd(
|
||||
} else {
|
||||
tempDepth = parsePtr->numWords - 2;
|
||||
}
|
||||
OP4( OVER, tempDepth);
|
||||
TclEmitInstInt4( INST_OVER, tempDepth, envPtr);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1727,13 +1694,13 @@ TclCompileLsetCmd(
|
||||
|
||||
if (isScalar) {
|
||||
if (localIndex < 0) {
|
||||
OP( LOAD_STK);
|
||||
TclEmitOpcode( INST_LOAD_STK, envPtr);
|
||||
} else {
|
||||
LOAD( localIndex);
|
||||
Emit14Inst( INST_LOAD_SCALAR, localIndex, envPtr);
|
||||
}
|
||||
} else {
|
||||
if (localIndex < 0) {
|
||||
OP( LOAD_ARRAY_STK);
|
||||
TclEmitOpcode( INST_LOAD_ARRAY_STK, envPtr);
|
||||
} else {
|
||||
Emit14Inst( INST_LOAD_ARRAY, localIndex, envPtr);
|
||||
}
|
||||
@@ -1744,9 +1711,9 @@ TclCompileLsetCmd(
|
||||
*/
|
||||
|
||||
if (parsePtr->numWords == 4) {
|
||||
OP( LSET_LIST);
|
||||
TclEmitOpcode( INST_LSET_LIST, envPtr);
|
||||
} else {
|
||||
OP4( LSET_FLAT, parsePtr->numWords - 1);
|
||||
TclEmitInstInt4( INST_LSET_FLAT, parsePtr->numWords-1, envPtr);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1755,13 +1722,13 @@ TclCompileLsetCmd(
|
||||
|
||||
if (isScalar) {
|
||||
if (localIndex < 0) {
|
||||
OP( STORE_STK);
|
||||
TclEmitOpcode( INST_STORE_STK, envPtr);
|
||||
} else {
|
||||
STORE( localIndex);
|
||||
Emit14Inst( INST_STORE_SCALAR, localIndex, envPtr);
|
||||
}
|
||||
} else {
|
||||
if (localIndex < 0) {
|
||||
OP( STORE_ARRAY_STK);
|
||||
TclEmitOpcode( INST_STORE_ARRAY_STK, envPtr);
|
||||
} else {
|
||||
Emit14Inst( INST_STORE_ARRAY, localIndex, envPtr);
|
||||
}
|
||||
@@ -1810,7 +1777,7 @@ TclCompileNamespaceCurrentCmd(
|
||||
* Not much to do; we compile to a single instruction...
|
||||
*/
|
||||
|
||||
OP(NS_CURRENT);
|
||||
TclEmitOpcode( INST_NS_CURRENT, envPtr);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -1855,11 +1822,11 @@ TclCompileNamespaceCodeCmd(
|
||||
* the value needs to be determined at runtime for safety.
|
||||
*/
|
||||
|
||||
PUSH( "::namespace");
|
||||
PUSH( "inscope");
|
||||
OP( NS_CURRENT);
|
||||
PushStringLiteral(envPtr, "::namespace");
|
||||
PushStringLiteral(envPtr, "inscope");
|
||||
TclEmitOpcode( INST_NS_CURRENT, envPtr);
|
||||
CompileWord(envPtr, tokenPtr, interp, 1);
|
||||
OP4( LIST, 4);
|
||||
TclEmitInstInt4( INST_LIST, 4, envPtr);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -1880,7 +1847,7 @@ TclCompileNamespaceOriginCmd(
|
||||
tokenPtr = TokenAfter(parsePtr->tokenPtr);
|
||||
|
||||
CompileWord(envPtr, tokenPtr, interp, 1);
|
||||
OP(ORIGIN_COMMAND);
|
||||
TclEmitOpcode( INST_ORIGIN_COMMAND, envPtr);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -1901,21 +1868,21 @@ TclCompileNamespaceQualifiersCmd(
|
||||
}
|
||||
|
||||
CompileWord(envPtr, tokenPtr, interp, 1);
|
||||
PUSH( "0");
|
||||
PUSH( "::");
|
||||
OP4( OVER, 2);
|
||||
OP( STR_FIND_LAST);
|
||||
PushStringLiteral(envPtr, "0");
|
||||
PushStringLiteral(envPtr, "::");
|
||||
TclEmitInstInt4( INST_OVER, 2, envPtr);
|
||||
TclEmitOpcode( INST_STR_FIND_LAST, envPtr);
|
||||
off = CurrentOffset(envPtr);
|
||||
PUSH( "1");
|
||||
OP( SUB);
|
||||
OP4( OVER, 2);
|
||||
OP4( OVER, 1);
|
||||
OP( STR_INDEX);
|
||||
PUSH( ":");
|
||||
OP( STR_EQ);
|
||||
PushStringLiteral(envPtr, "1");
|
||||
TclEmitOpcode( INST_SUB, envPtr);
|
||||
TclEmitInstInt4( INST_OVER, 2, envPtr);
|
||||
TclEmitInstInt4( INST_OVER, 1, envPtr);
|
||||
TclEmitOpcode( INST_STR_INDEX, envPtr);
|
||||
PushStringLiteral(envPtr, ":");
|
||||
TclEmitOpcode( INST_STR_EQ, envPtr);
|
||||
off = off - CurrentOffset(envPtr);
|
||||
OP1( JUMP_TRUE1, off);
|
||||
OP( STR_RANGE);
|
||||
TclEmitInstInt1( INST_JUMP_TRUE1, off, envPtr);
|
||||
TclEmitOpcode( INST_STR_RANGE, envPtr);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -1940,18 +1907,18 @@ TclCompileNamespaceTailCmd(
|
||||
*/
|
||||
|
||||
CompileWord(envPtr, tokenPtr, interp, 1);
|
||||
PUSH( "::");
|
||||
OP4( OVER, 1);
|
||||
OP( STR_FIND_LAST);
|
||||
OP( DUP);
|
||||
PUSH( "0");
|
||||
OP( GE);
|
||||
PushStringLiteral(envPtr, "::");
|
||||
TclEmitInstInt4( INST_OVER, 1, envPtr);
|
||||
TclEmitOpcode( INST_STR_FIND_LAST, envPtr);
|
||||
TclEmitOpcode( INST_DUP, envPtr);
|
||||
PushStringLiteral(envPtr, "0");
|
||||
TclEmitOpcode( INST_GE, envPtr);
|
||||
TclEmitForwardJump(envPtr, TCL_FALSE_JUMP, &jumpFixup);
|
||||
PUSH( "2");
|
||||
OP( ADD);
|
||||
PushStringLiteral(envPtr, "2");
|
||||
TclEmitOpcode( INST_ADD, envPtr);
|
||||
TclFixupForwardJumpToHere(envPtr, &jumpFixup, 127);
|
||||
PUSH( "end");
|
||||
OP( STR_RANGE);
|
||||
PushStringLiteral(envPtr, "end");
|
||||
TclEmitOpcode( INST_STR_RANGE, envPtr);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -2003,15 +1970,15 @@ TclCompileNamespaceUpvarCmd(
|
||||
if (localIndex < 0) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
OP4( NSUPVAR, localIndex);
|
||||
TclEmitInstInt4( INST_NSUPVAR, localIndex, envPtr);
|
||||
}
|
||||
|
||||
/*
|
||||
* Pop the namespace, and set the result to empty
|
||||
*/
|
||||
|
||||
OP( POP);
|
||||
PUSH( "");
|
||||
TclEmitOpcode( INST_POP, envPtr);
|
||||
PushStringLiteral(envPtr, "");
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -2056,7 +2023,7 @@ TclCompileNamespaceWhichCmd(
|
||||
*/
|
||||
|
||||
CompileWord(envPtr, tokenPtr, interp, idx);
|
||||
OP( RESOLVE_COMMAND);
|
||||
TclEmitOpcode( INST_RESOLVE_COMMAND, envPtr);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -2175,7 +2142,7 @@ TclCompileRegexpCmd(
|
||||
* The semantics of regexp are always match on re == "".
|
||||
*/
|
||||
|
||||
PUSH( "1");
|
||||
PushStringLiteral(envPtr, "1");
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -2205,9 +2172,9 @@ TclCompileRegexpCmd(
|
||||
|
||||
if (simple) {
|
||||
if (exact && !nocase) {
|
||||
OP( STR_EQ);
|
||||
TclEmitOpcode( INST_STR_EQ, envPtr);
|
||||
} else {
|
||||
OP1( STR_MATCH, nocase);
|
||||
TclEmitInstInt1( INST_STR_MATCH, nocase, envPtr);
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
@@ -2218,7 +2185,7 @@ TclCompileRegexpCmd(
|
||||
|
||||
int cflags = TCL_REG_ADVANCED | (nocase ? TCL_REG_NOCASE : 0);
|
||||
|
||||
OP1( REGEXP, cflags);
|
||||
TclEmitInstInt1( INST_REGEXP, cflags, envPtr);
|
||||
}
|
||||
|
||||
return TCL_OK;
|
||||
@@ -2385,7 +2352,7 @@ TclCompileRegsubCmd(
|
||||
bytes = TclGetStringFromObj(replacementObj, &len);
|
||||
PushLiteral(envPtr, bytes, len);
|
||||
CompileWord(envPtr, stringTokenPtr, interp, parsePtr->numWords - 2);
|
||||
OP( STR_MAP);
|
||||
TclEmitOpcode( INST_STR_MAP, envPtr);
|
||||
|
||||
done:
|
||||
Tcl_DStringFree(&pattern);
|
||||
@@ -2518,7 +2485,7 @@ TclCompileReturnCmd(
|
||||
* No explict result argument, so default result is empty string.
|
||||
*/
|
||||
|
||||
PUSH( "");
|
||||
PushStringLiteral(envPtr, "");
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2552,7 +2519,7 @@ TclCompileReturnCmd(
|
||||
*/
|
||||
|
||||
Tcl_DecrRefCount(returnOpts);
|
||||
OP( DONE);
|
||||
TclEmitOpcode(INST_DONE, envPtr);
|
||||
TclAdjustStackDepth(1, envPtr);
|
||||
return TCL_OK;
|
||||
}
|
||||
@@ -2583,7 +2550,7 @@ TclCompileReturnCmd(
|
||||
CompileWord(envPtr, wordTokenPtr, interp, objc);
|
||||
wordTokenPtr = TokenAfter(wordTokenPtr);
|
||||
}
|
||||
OP4( LIST, numOptionWords);
|
||||
TclEmitInstInt4(INST_LIST, numOptionWords, envPtr);
|
||||
|
||||
/*
|
||||
* Push the result.
|
||||
@@ -2592,14 +2559,14 @@ TclCompileReturnCmd(
|
||||
if (explicitResult) {
|
||||
CompileWord(envPtr, wordTokenPtr, interp, numWords - 1);
|
||||
} else {
|
||||
PUSH( "");
|
||||
PushStringLiteral(envPtr, "");
|
||||
}
|
||||
|
||||
/*
|
||||
* Issue the RETURN itself.
|
||||
*/
|
||||
|
||||
INVOKE( RETURN_STK);
|
||||
TclEmitInvoke(envPtr, INST_RETURN_STK);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -2629,7 +2596,8 @@ CompileReturnInternal(
|
||||
}
|
||||
|
||||
TclEmitPush(TclAddLiteralObj(envPtr, returnOpts, NULL), envPtr);
|
||||
TclEmitInstInt44(op, code, level, envPtr);
|
||||
TclEmitInstInt4(op, code, envPtr);
|
||||
TclEmitInt4(level, envPtr);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -2708,7 +2676,7 @@ TclCompileUpvarCmd(
|
||||
Tcl_DecrRefCount(objPtr);
|
||||
|
||||
if (newTypePtr != typePtr) {
|
||||
if (numWords % 2) {
|
||||
if (numWords%2) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
/* TODO: Push the known value instead? */
|
||||
@@ -2716,10 +2684,10 @@ TclCompileUpvarCmd(
|
||||
otherTokenPtr = TokenAfter(tokenPtr);
|
||||
i = 2;
|
||||
} else {
|
||||
if (!(numWords % 2)) {
|
||||
if (!(numWords%2)) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
PUSH("1");
|
||||
PushStringLiteral(envPtr, "1");
|
||||
otherTokenPtr = tokenPtr;
|
||||
i = 1;
|
||||
}
|
||||
@@ -2742,15 +2710,15 @@ TclCompileUpvarCmd(
|
||||
if (localIndex < 0) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
OP4( UPVAR, localIndex);
|
||||
TclEmitInstInt4( INST_UPVAR, localIndex, envPtr);
|
||||
}
|
||||
|
||||
/*
|
||||
* Pop the frame index, and set the result to empty
|
||||
*/
|
||||
|
||||
OP( POP);
|
||||
PUSH( "");
|
||||
TclEmitOpcode( INST_POP, envPtr);
|
||||
PushStringLiteral(envPtr, "");
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -2816,7 +2784,7 @@ TclCompileVariableCmd(
|
||||
* IndexTailVarIfKnown() screen. Full CompileWord()
|
||||
* likely does not apply here. Push known value instead. */
|
||||
CompileWord(envPtr, varTokenPtr, interp, i);
|
||||
OP4( VARIABLE, localIndex);
|
||||
TclEmitInstInt4( INST_VARIABLE, localIndex, envPtr);
|
||||
|
||||
if (i + 1 < numWords) {
|
||||
/*
|
||||
@@ -2824,8 +2792,8 @@ TclCompileVariableCmd(
|
||||
*/
|
||||
|
||||
CompileWord(envPtr, valueTokenPtr, interp, i + 1);
|
||||
STORE( localIndex);
|
||||
OP( POP);
|
||||
Emit14Inst( INST_STORE_SCALAR, localIndex, envPtr);
|
||||
TclEmitOpcode( INST_POP, envPtr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2833,7 +2801,7 @@ TclCompileVariableCmd(
|
||||
* Set the result to empty
|
||||
*/
|
||||
|
||||
PUSH( "");
|
||||
PushStringLiteral(envPtr, "");
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -2965,7 +2933,7 @@ TclCompileObjectNextCmd(
|
||||
CompileWord(envPtr, tokenPtr, interp, i);
|
||||
tokenPtr = TokenAfter(tokenPtr);
|
||||
}
|
||||
OP1( TCLOO_NEXT, i);
|
||||
TclEmitInstInt1( INST_TCLOO_NEXT, i, envPtr);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -2989,7 +2957,7 @@ TclCompileObjectNextToCmd(
|
||||
CompileWord(envPtr, tokenPtr, interp, i);
|
||||
tokenPtr = TokenAfter(tokenPtr);
|
||||
}
|
||||
OP1( TCLOO_NEXT_CLASS, i);
|
||||
TclEmitInstInt1( INST_TCLOO_NEXT_CLASS, i, envPtr);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -3002,9 +2970,9 @@ TclCompileObjectSelfCmd(
|
||||
CompileEnv *envPtr) /* Holds resulting instructions. */
|
||||
{
|
||||
/*
|
||||
* We only handle [self], [self object] (which is the same operation) and
|
||||
* [self namespace]. These are the only very common operations on [self]
|
||||
* for which bytecoding is at all reasonable.
|
||||
* We only handle [self] and [self object] (which is the same operation).
|
||||
* These are the only very common operations on [self] for which
|
||||
* bytecoding is at all reasonable.
|
||||
*/
|
||||
|
||||
if (parsePtr->numWords == 1) {
|
||||
@@ -3036,7 +3004,7 @@ TclCompileObjectSelfCmd(
|
||||
* This delegates the entire problem to a single opcode.
|
||||
*/
|
||||
|
||||
OP( TCLOO_SELF);
|
||||
TclEmitOpcode( INST_TCLOO_SELF, envPtr);
|
||||
return TCL_OK;
|
||||
|
||||
compileSelfNamespace:
|
||||
@@ -3049,9 +3017,9 @@ TclCompileObjectSelfCmd(
|
||||
* avoids creating another opcode, so that's all good!
|
||||
*/
|
||||
|
||||
OP( TCLOO_SELF);
|
||||
OP( POP);
|
||||
OP( NS_CURRENT);
|
||||
TclEmitOpcode( INST_TCLOO_SELF, envPtr);
|
||||
TclEmitOpcode( INST_POP, envPtr);
|
||||
TclEmitOpcode( INST_NS_CURRENT, envPtr);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
|
||||
+222
-281
@@ -81,9 +81,12 @@ const AuxDataType tclJumptableInfoType = {
|
||||
#define OP(name) TclEmitOpcode(INST_##name, envPtr)
|
||||
#define OP1(name,val) TclEmitInstInt1(INST_##name,(val),envPtr)
|
||||
#define OP4(name,val) TclEmitInstInt4(INST_##name,(val),envPtr)
|
||||
#define OP14(name,val1,val2) TclEmitInstInt14(INST_##name,(val1),(val2),envPtr)
|
||||
#define OP44(name,val1,val2) TclEmitInstInt44(INST_##name,(val1),(val2),envPtr)
|
||||
#define PUSH(str) PushStringLiteral(envPtr, str)
|
||||
#define OP14(name,val1,val2) \
|
||||
TclEmitInstInt1(INST_##name,(val1),envPtr);TclEmitInt4((val2),envPtr)
|
||||
#define OP44(name,val1,val2) \
|
||||
TclEmitInstInt4(INST_##name,(val1),envPtr);TclEmitInt4((val2),envPtr)
|
||||
#define PUSH(str) \
|
||||
PushStringLiteral(envPtr, str)
|
||||
#define JUMP4(name,var) \
|
||||
(var) = CurrentOffset(envPtr);TclEmitInstInt4(INST_##name##4,0,envPtr)
|
||||
#define FIXJUMP4(var) \
|
||||
@@ -96,60 +99,9 @@ const AuxDataType tclJumptableInfoType = {
|
||||
if ((idx)<256) {OP1(LOAD_SCALAR1,(idx));} else {OP4(LOAD_SCALAR4,(idx));}
|
||||
#define STORE(idx) \
|
||||
if ((idx)<256) {OP1(STORE_SCALAR1,(idx));} else {OP4(STORE_SCALAR4,(idx));}
|
||||
#define INVOKE(name) TclEmitInvoke(envPtr,INST_##name)
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* IsContinuationBody, IsDefaultToken, IsFinallyToken, IsOnToken,
|
||||
* IsTrapToken --
|
||||
*
|
||||
* Helpers for TclCompileSwitchCmd and TclCompileTryCmd to compare tokens
|
||||
* to key literals.
|
||||
*
|
||||
* Results:
|
||||
* Returns 1 if they're equal, 0 if not.
|
||||
*
|
||||
* Side effects:
|
||||
* None.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
#define INVOKE(name) \
|
||||
TclEmitInvoke(envPtr,INST_##name)
|
||||
|
||||
static inline int
|
||||
IsContinuationBody(
|
||||
const Tcl_Token *tokenPtr)
|
||||
{
|
||||
return tokenPtr->size == 1 && tokenPtr->start[0] == '-';
|
||||
}
|
||||
|
||||
static inline int
|
||||
IsDefaultToken(
|
||||
const Tcl_Token *tokenPtr)
|
||||
{
|
||||
return tokenPtr->size == 7 && memcmp(tokenPtr->start, "default", 7) == 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
IsFinallyToken(
|
||||
const Tcl_Token *tokenPtr)
|
||||
{
|
||||
return tokenPtr->size == 7 && memcmp(tokenPtr->start, "finally", 7) == 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
IsOnToken(
|
||||
const Tcl_Token *tokenPtr)
|
||||
{
|
||||
return tokenPtr->size == 2 && memcmp(tokenPtr->start, "on", 2) == 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
IsTrapToken(
|
||||
const Tcl_Token *tokenPtr)
|
||||
{
|
||||
return tokenPtr->size == 4 && memcmp(tokenPtr->start, "trap", 4) == 0;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
@@ -212,33 +164,33 @@ TclCompileSetCmd(
|
||||
* Emit instructions to set/get the variable.
|
||||
*/
|
||||
|
||||
if (isScalar) {
|
||||
if (localIndex < 0) {
|
||||
TclEmitOpcode((isAssignment?
|
||||
INST_STORE_STK : INST_LOAD_STK), envPtr);
|
||||
} else if (localIndex <= 255) {
|
||||
TclEmitInstInt1((isAssignment?
|
||||
INST_STORE_SCALAR1 : INST_LOAD_SCALAR1),
|
||||
localIndex, envPtr);
|
||||
if (isScalar) {
|
||||
if (localIndex < 0) {
|
||||
TclEmitOpcode((isAssignment?
|
||||
INST_STORE_STK : INST_LOAD_STK), envPtr);
|
||||
} else if (localIndex <= 255) {
|
||||
TclEmitInstInt1((isAssignment?
|
||||
INST_STORE_SCALAR1 : INST_LOAD_SCALAR1),
|
||||
localIndex, envPtr);
|
||||
} else {
|
||||
TclEmitInstInt4((isAssignment?
|
||||
INST_STORE_SCALAR4 : INST_LOAD_SCALAR4),
|
||||
localIndex, envPtr);
|
||||
}
|
||||
} else {
|
||||
TclEmitInstInt4((isAssignment?
|
||||
INST_STORE_SCALAR4 : INST_LOAD_SCALAR4),
|
||||
localIndex, envPtr);
|
||||
if (localIndex < 0) {
|
||||
TclEmitOpcode((isAssignment?
|
||||
INST_STORE_ARRAY_STK : INST_LOAD_ARRAY_STK), envPtr);
|
||||
} else if (localIndex <= 255) {
|
||||
TclEmitInstInt1((isAssignment?
|
||||
INST_STORE_ARRAY1 : INST_LOAD_ARRAY1),
|
||||
localIndex, envPtr);
|
||||
} else {
|
||||
TclEmitInstInt4((isAssignment?
|
||||
INST_STORE_ARRAY4 : INST_LOAD_ARRAY4),
|
||||
localIndex, envPtr);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (localIndex < 0) {
|
||||
TclEmitOpcode((isAssignment?
|
||||
INST_STORE_ARRAY_STK : INST_LOAD_ARRAY_STK), envPtr);
|
||||
} else if (localIndex <= 255) {
|
||||
TclEmitInstInt1((isAssignment?
|
||||
INST_STORE_ARRAY1 : INST_LOAD_ARRAY1),
|
||||
localIndex, envPtr);
|
||||
} else {
|
||||
TclEmitInstInt4((isAssignment?
|
||||
INST_STORE_ARRAY4 : INST_LOAD_ARRAY4),
|
||||
localIndex, envPtr);
|
||||
}
|
||||
}
|
||||
|
||||
return TCL_OK;
|
||||
}
|
||||
@@ -277,15 +229,13 @@ TclCompileStringCatCmd(
|
||||
|
||||
/* Trivial case, no arg */
|
||||
|
||||
if (numWords < 2) {
|
||||
PUSH( "");
|
||||
if (numWords<2) {
|
||||
PushStringLiteral(envPtr, "");
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* General case: issue CONCAT1's (by chunks of 254 if needed), folding
|
||||
* contiguous constants along the way.
|
||||
*/
|
||||
/* General case: issue CONCAT1's (by chunks of 254 if needed), folding
|
||||
contiguous constants along the way */
|
||||
|
||||
numArgs = 0;
|
||||
folded = NULL;
|
||||
@@ -313,7 +263,7 @@ TclCompileStringCatCmd(
|
||||
CompileWord(envPtr, wordTokenPtr, interp, i);
|
||||
numArgs ++;
|
||||
if (numArgs >= 254) { /* 254 to take care of the possible +1 of "folded" above */
|
||||
OP1( STR_CONCAT1, numArgs);
|
||||
TclEmitInstInt1(INST_STR_CONCAT1, numArgs, envPtr);
|
||||
numArgs = 1; /* concat pushes 1 obj, the result */
|
||||
}
|
||||
}
|
||||
@@ -329,7 +279,7 @@ TclCompileStringCatCmd(
|
||||
numArgs ++;
|
||||
}
|
||||
if (numArgs > 1) {
|
||||
OP1( STR_CONCAT1, numArgs);
|
||||
TclEmitInstInt1(INST_STR_CONCAT1, numArgs, envPtr);
|
||||
}
|
||||
|
||||
return TCL_OK;
|
||||
@@ -362,7 +312,7 @@ TclCompileStringCmpCmd(
|
||||
CompileWord(envPtr, tokenPtr, interp, 1);
|
||||
tokenPtr = TokenAfter(tokenPtr);
|
||||
CompileWord(envPtr, tokenPtr, interp, 2);
|
||||
OP( STR_CMP);
|
||||
TclEmitOpcode(INST_STR_CMP, envPtr);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -393,7 +343,7 @@ TclCompileStringEqualCmd(
|
||||
CompileWord(envPtr, tokenPtr, interp, 1);
|
||||
tokenPtr = TokenAfter(tokenPtr);
|
||||
CompileWord(envPtr, tokenPtr, interp, 2);
|
||||
OP( STR_EQ);
|
||||
TclEmitOpcode(INST_STR_EQ, envPtr);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -424,7 +374,7 @@ TclCompileStringFirstCmd(
|
||||
CompileWord(envPtr, tokenPtr, interp, 1);
|
||||
tokenPtr = TokenAfter(tokenPtr);
|
||||
CompileWord(envPtr, tokenPtr, interp, 2);
|
||||
OP( STR_FIND);
|
||||
OP(STR_FIND);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -455,7 +405,7 @@ TclCompileStringLastCmd(
|
||||
CompileWord(envPtr, tokenPtr, interp, 1);
|
||||
tokenPtr = TokenAfter(tokenPtr);
|
||||
CompileWord(envPtr, tokenPtr, interp, 2);
|
||||
OP( STR_FIND_LAST);
|
||||
OP(STR_FIND_LAST);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -482,7 +432,7 @@ TclCompileStringIndexCmd(
|
||||
CompileWord(envPtr, tokenPtr, interp, 1);
|
||||
tokenPtr = TokenAfter(tokenPtr);
|
||||
CompileWord(envPtr, tokenPtr, interp, 2);
|
||||
OP( STR_INDEX);
|
||||
TclEmitOpcode(INST_STR_INDEX, envPtr);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -502,28 +452,20 @@ TclCompileStringInsertCmd(
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Compute and push the string in which to insert.
|
||||
*/
|
||||
|
||||
/* Compute and push the string in which to insert */
|
||||
tokenPtr = TokenAfter(parsePtr->tokenPtr);
|
||||
CompileWord(envPtr, tokenPtr, interp, 1);
|
||||
|
||||
/*
|
||||
* See what can be discovered about index at compile time.
|
||||
*/
|
||||
|
||||
/* See what can be discovered about index at compile time */
|
||||
tokenPtr = TokenAfter(tokenPtr);
|
||||
if (TCL_OK != TclGetIndexFromToken(tokenPtr, TCL_INDEX_START,
|
||||
TCL_INDEX_END, &idx)) {
|
||||
|
||||
/* Nothing useful knowable - cease compile; let it direct eval */
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Compute and push the string to be inserted.
|
||||
*/
|
||||
|
||||
/* Compute and push the string to be inserted */
|
||||
tokenPtr = TokenAfter(tokenPtr);
|
||||
CompileWord(envPtr, tokenPtr, interp, 3);
|
||||
|
||||
@@ -550,17 +492,6 @@ TclCompileStringInsertCmd(
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
static inline int
|
||||
GotLiteral(
|
||||
const Tcl_Token *tokenPtr,
|
||||
const char *word)
|
||||
{
|
||||
return (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);
|
||||
}
|
||||
|
||||
int
|
||||
TclCompileStringIsCmd(
|
||||
Tcl_Interp *interp, /* Used for error reporting. */
|
||||
@@ -607,6 +538,12 @@ TclCompileStringIsCmd(
|
||||
}
|
||||
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.
|
||||
@@ -625,6 +562,7 @@ TclCompileStringIsCmd(
|
||||
}
|
||||
tokenPtr = TokenAfter(tokenPtr);
|
||||
}
|
||||
#undef GotLiteral
|
||||
|
||||
/*
|
||||
* Compile the code. There are several main classes of check here.
|
||||
@@ -866,7 +804,12 @@ TclCompileStringMatchCmd(
|
||||
*/
|
||||
|
||||
if (parsePtr->numWords == 4) {
|
||||
if (!GotLiteral(tokenPtr, "-nocase")) {
|
||||
if (tokenPtr->type != TCL_TOKEN_SIMPLE_WORD) {
|
||||
return TclCompileBasic3ArgCmd(interp, parsePtr, cmdPtr, envPtr);
|
||||
}
|
||||
str = tokenPtr[1].start;
|
||||
length = tokenPtr[1].size;
|
||||
if ((length <= 1) || strncmp(str, "-nocase", length)) {
|
||||
/*
|
||||
* Fail at run time, not in compilation.
|
||||
*/
|
||||
@@ -900,7 +843,7 @@ TclCompileStringMatchCmd(
|
||||
}
|
||||
PushLiteral(envPtr, str, length);
|
||||
} else {
|
||||
SetLineInformation(i + 1 + nocase);
|
||||
SetLineInformation(i+1+nocase);
|
||||
CompileTokens(envPtr, tokenPtr, interp);
|
||||
}
|
||||
tokenPtr = TokenAfter(tokenPtr);
|
||||
@@ -911,9 +854,9 @@ TclCompileStringMatchCmd(
|
||||
*/
|
||||
|
||||
if (exactMatch) {
|
||||
OP( STR_EQ);
|
||||
TclEmitOpcode(INST_STR_EQ, envPtr);
|
||||
} else {
|
||||
OP1( STR_MATCH, nocase);
|
||||
TclEmitInstInt1(INST_STR_MATCH, nocase, envPtr);
|
||||
}
|
||||
return TCL_OK;
|
||||
}
|
||||
@@ -951,7 +894,7 @@ TclCompileStringLenCmd(
|
||||
} else {
|
||||
SetLineInformation(1);
|
||||
CompileTokens(envPtr, tokenPtr, interp);
|
||||
OP( STR_LEN);
|
||||
TclEmitOpcode(INST_STR_LEN, envPtr);
|
||||
}
|
||||
TclDecrRefCount(objPtr);
|
||||
return TCL_OK;
|
||||
@@ -1050,7 +993,6 @@ TclCompileStringRangeCmd(
|
||||
&idx1) != TCL_OK) {
|
||||
goto nonConstantIndices;
|
||||
}
|
||||
|
||||
/*
|
||||
* Token parsed as an index expression. We treat all indices before
|
||||
* the string the same as the start of the string.
|
||||
@@ -1067,12 +1009,10 @@ TclCompileStringRangeCmd(
|
||||
&idx2) != TCL_OK) {
|
||||
goto nonConstantIndices;
|
||||
}
|
||||
|
||||
/*
|
||||
* Token parsed as an index expression. We treat all indices after
|
||||
* the string the same as the end of the string.
|
||||
*/
|
||||
|
||||
if (idx2 == (int)TCL_INDEX_NONE) {
|
||||
/* [string range $s $first -1] must be empty string */
|
||||
OP( POP);
|
||||
@@ -1121,7 +1061,6 @@ TclCompileStringReplaceCmd(
|
||||
/*
|
||||
* Check for first index known and useful at compile time.
|
||||
*/
|
||||
|
||||
tokenPtr = TokenAfter(valueTokenPtr);
|
||||
if (TclGetIndexFromToken(tokenPtr, TCL_INDEX_START, TCL_INDEX_NONE,
|
||||
&first) != TCL_OK) {
|
||||
@@ -1131,7 +1070,6 @@ TclCompileStringReplaceCmd(
|
||||
/*
|
||||
* Check for last index known and useful at compile time.
|
||||
*/
|
||||
|
||||
tokenPtr = TokenAfter(tokenPtr);
|
||||
if (TclGetIndexFromToken(tokenPtr, TCL_INDEX_NONE, TCL_INDEX_END,
|
||||
&last) != TCL_OK) {
|
||||
@@ -1139,25 +1077,26 @@ TclCompileStringReplaceCmd(
|
||||
}
|
||||
|
||||
/*
|
||||
* [string replace] is an odd bird. For many arguments it is a
|
||||
* conventional substring replacer. However it also goes out of its way
|
||||
* to become a no-op for many cases where it would be replacing an empty
|
||||
* substring. Precisely, it is a no-op when
|
||||
* [string replace] is an odd bird. For many arguments it is
|
||||
* a conventional substring replacer. However it also goes out
|
||||
* of its way to become a no-op for many cases where it would be
|
||||
* replacing an empty substring. Precisely, it is a no-op when
|
||||
*
|
||||
* (last < first) OR
|
||||
* (last < 0) OR
|
||||
* (end < first)
|
||||
*
|
||||
* For some compile-time values we can detect these cases, and compile
|
||||
* direct to bytecode implementing the no-op.
|
||||
* For some compile-time values we can detect these cases, and
|
||||
* compile direct to bytecode implementing the no-op.
|
||||
*/
|
||||
|
||||
if ((last == (int)TCL_INDEX_NONE) /* Know (last < 0) */
|
||||
|| (first == (int)TCL_INDEX_NONE) /* Know (first > end) */
|
||||
|
||||
/*
|
||||
* Tricky to determine when runtime (last < first) can be certainly
|
||||
* known based on the encoded values. Consider the cases...
|
||||
* Tricky to determine when runtime (last < first) can be
|
||||
* certainly known based on the encoded values. Consider the
|
||||
* cases...
|
||||
*
|
||||
* (first <= TCL_INDEX_END) &&
|
||||
* (last <= TCL_INDEX END) && (last < first) => ACCEPT
|
||||
@@ -1186,72 +1125,74 @@ TclCompileStringReplaceCmd(
|
||||
}
|
||||
|
||||
if (parsePtr->numWords == 5) {
|
||||
/*
|
||||
* When we have a string replacement, we have to take care about not
|
||||
* replacing empty substrings that [string replace] promises not to
|
||||
* replace.
|
||||
*
|
||||
* The remaining index values might be suitable for conventional
|
||||
* string replacement, but only if they cannot possibly meet the
|
||||
* conditions described above at runtime. If there's a chance they
|
||||
* might, we would have to emit bytecode to check and at that point
|
||||
* we're paying more in bytecode execution time than would make things
|
||||
* worthwhile. Trouble is we are very limited in how much we can
|
||||
* detect that at compile time. After decoding, we need, first:
|
||||
*
|
||||
* (first <= end)
|
||||
*
|
||||
* The encoded indices (first <= TCL_INDEX END) and (first ==
|
||||
* TCL_INDEX_NONE) always meets this condition, but any other encoded
|
||||
* first index has some list for which it fails.
|
||||
*
|
||||
* We also need, second:
|
||||
*
|
||||
* (last >= 0)
|
||||
*
|
||||
* The encoded index (last >= TCL_INDEX_START) always meet this
|
||||
* condition but any other encoded last index has some list for which
|
||||
* it fails.
|
||||
*
|
||||
* Finally we need, third:
|
||||
*
|
||||
* (first <= last)
|
||||
*
|
||||
* Considered in combination with the constraints we already have, we
|
||||
* see that we can proceed when (first == TCL_INDEX_NONE). These also
|
||||
* permit simplification of the prefix|replace|suffix construction.
|
||||
* The other constraints, though, interfere with getting a guarantee
|
||||
* that first <= last.
|
||||
*/
|
||||
/*
|
||||
* When we have a string replacement, we have to take care about
|
||||
* not replacing empty substrings that [string replace] promises
|
||||
* not to replace
|
||||
*
|
||||
* The remaining index values might be suitable for conventional
|
||||
* string replacement, but only if they cannot possibly meet the
|
||||
* conditions described above at runtime. If there's a chance they
|
||||
* might, we would have to emit bytecode to check and at that point
|
||||
* we're paying more in bytecode execution time than would make
|
||||
* things worthwhile. Trouble is we are very limited in
|
||||
* how much we can detect that at compile time. After decoding,
|
||||
* we need, first:
|
||||
*
|
||||
* (first <= end)
|
||||
*
|
||||
* The encoded indices (first <= TCL_INDEX END) and
|
||||
* (first == TCL_INDEX_NONE) always meets this condition, but
|
||||
* any other encoded first index has some list for which it fails.
|
||||
*
|
||||
* We also need, second:
|
||||
*
|
||||
* (last >= 0)
|
||||
*
|
||||
* The encoded index (last >= TCL_INDEX_START) always meet this
|
||||
* condition but any other encoded last index has some list for
|
||||
* which it fails.
|
||||
*
|
||||
* Finally we need, third:
|
||||
*
|
||||
* (first <= last)
|
||||
*
|
||||
* Considered in combination with the constraints we already have,
|
||||
* we see that we can proceed when (first == TCL_INDEX_NONE).
|
||||
* These also permit simplification of the prefix|replace|suffix
|
||||
* construction. The other constraints, though, interfere with
|
||||
* getting a guarantee that first <= last.
|
||||
*/
|
||||
|
||||
if ((first == (int)TCL_INDEX_START) && (last >= (int)TCL_INDEX_START)) {
|
||||
/* empty prefix */
|
||||
tokenPtr = TokenAfter(tokenPtr);
|
||||
CompileWord(envPtr, tokenPtr, interp, 4);
|
||||
OP4( REVERSE, 2);
|
||||
if (last == INT_MAX) {
|
||||
OP( POP); /* Pop original */
|
||||
} else {
|
||||
OP44( STR_RANGE_IMM, last + 1, (int)TCL_INDEX_END);
|
||||
OP1( STR_CONCAT1, 2);
|
||||
}
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
if ((last == (int)TCL_INDEX_NONE) && (first <= (int)TCL_INDEX_END)) {
|
||||
OP44( STR_RANGE_IMM, 0, first-1);
|
||||
tokenPtr = TokenAfter(tokenPtr);
|
||||
CompileWord(envPtr, tokenPtr, interp, 4);
|
||||
if ((first == (int)TCL_INDEX_START) && (last >= (int)TCL_INDEX_START)) {
|
||||
/* empty prefix */
|
||||
tokenPtr = TokenAfter(tokenPtr);
|
||||
CompileWord(envPtr, tokenPtr, interp, 4);
|
||||
OP4( REVERSE, 2);
|
||||
if (last == INT_MAX) {
|
||||
OP( POP); /* Pop original */
|
||||
} else {
|
||||
OP44( STR_RANGE_IMM, last + 1, (int)TCL_INDEX_END);
|
||||
OP1( STR_CONCAT1, 2);
|
||||
return TCL_OK;
|
||||
}
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
if ((last == (int)TCL_INDEX_NONE) && (first <= (int)TCL_INDEX_END)) {
|
||||
OP44( STR_RANGE_IMM, 0, first-1);
|
||||
tokenPtr = TokenAfter(tokenPtr);
|
||||
CompileWord(envPtr, tokenPtr, interp, 4);
|
||||
OP1( STR_CONCAT1, 2);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/* FLOW THROUGH TO genericReplace */
|
||||
|
||||
} else {
|
||||
/*
|
||||
* When we have no replacement string to worry about, we may have more
|
||||
* luck, because the forbidden empty string replacements are harmless
|
||||
* when they are replaced by another empty string.
|
||||
* When we have no replacement string to worry about, we may
|
||||
* have more luck, because the forbidden empty string replacements
|
||||
* are harmless when they are replaced by another empty string.
|
||||
*/
|
||||
|
||||
if (first == (int)TCL_INDEX_START) {
|
||||
@@ -1260,7 +1201,7 @@ TclCompileStringReplaceCmd(
|
||||
if (last == (int)TCL_INDEX_END) {
|
||||
/* empty suffix too => empty result */
|
||||
OP( POP); /* Pop original */
|
||||
PUSH( "");
|
||||
PUSH ( "");
|
||||
return TCL_OK;
|
||||
}
|
||||
OP44( STR_RANGE_IMM, last + 1, (int)TCL_INDEX_END);
|
||||
@@ -1280,19 +1221,19 @@ TclCompileStringReplaceCmd(
|
||||
}
|
||||
}
|
||||
|
||||
genericReplace:
|
||||
tokenPtr = TokenAfter(valueTokenPtr);
|
||||
CompileWord(envPtr, tokenPtr, interp, 2);
|
||||
tokenPtr = TokenAfter(tokenPtr);
|
||||
CompileWord(envPtr, tokenPtr, interp, 3);
|
||||
if (parsePtr->numWords == 5) {
|
||||
genericReplace:
|
||||
tokenPtr = TokenAfter(valueTokenPtr);
|
||||
CompileWord(envPtr, tokenPtr, interp, 2);
|
||||
tokenPtr = TokenAfter(tokenPtr);
|
||||
CompileWord(envPtr, tokenPtr, interp, 4);
|
||||
} else {
|
||||
PUSH( "");
|
||||
}
|
||||
OP( STR_REPLACE);
|
||||
return TCL_OK;
|
||||
CompileWord(envPtr, tokenPtr, interp, 3);
|
||||
if (parsePtr->numWords == 5) {
|
||||
tokenPtr = TokenAfter(tokenPtr);
|
||||
CompileWord(envPtr, tokenPtr, interp, 4);
|
||||
} else {
|
||||
PUSH( "");
|
||||
}
|
||||
OP( STR_REPLACE);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
int
|
||||
@@ -1536,14 +1477,12 @@ TclCompileSubstCmd(
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
* TODO: Figure out expansion to cover WordKnownAtCompileTime. The
|
||||
* difficulty is that WKACT makes a copy, and if TclSubstParse below
|
||||
* parses the copy of the original source string, some deep parts of the
|
||||
* compile machinery get upset. They want all pointers stored in
|
||||
* Tcl_Tokens to point back to the same original string.
|
||||
/* TODO: Figure out expansion to cover WordKnownAtCompileTime
|
||||
* The difficulty is that WKACT makes a copy, and if TclSubstParse
|
||||
* below parses the copy of the original source string, some deep
|
||||
* parts of the compile machinery get upset. They want all pointers
|
||||
* stored in Tcl_Tokens to point back to the same original string.
|
||||
*/
|
||||
|
||||
if (wordTokenPtr->type == TCL_TOKEN_SIMPLE_WORD) {
|
||||
code = TclSubstOptions(NULL, numOpts, objv, &flags);
|
||||
}
|
||||
@@ -1600,14 +1539,16 @@ TclSubstCompile(
|
||||
|
||||
for (endTokenPtr = tokenPtr + parse.numTokens;
|
||||
tokenPtr < endTokenPtr; tokenPtr = TokenAfter(tokenPtr)) {
|
||||
int length, catchRange, breakJump;
|
||||
int length, literal, catchRange, breakJump;
|
||||
char buf[4] = "";
|
||||
JumpFixup startFixup, okFixup, returnFixup, breakFixup;
|
||||
JumpFixup continueFixup, otherFixup, endFixup;
|
||||
|
||||
switch (tokenPtr->type) {
|
||||
case TCL_TOKEN_TEXT:
|
||||
PushLiteral(envPtr, tokenPtr->start, tokenPtr->size);
|
||||
literal = TclRegisterLiteral(envPtr,
|
||||
tokenPtr->start, tokenPtr->size, 0);
|
||||
TclEmitPush(literal, envPtr);
|
||||
TclAdvanceLines(&bline, tokenPtr->start,
|
||||
tokenPtr->start + tokenPtr->size);
|
||||
count++;
|
||||
@@ -1615,7 +1556,8 @@ TclSubstCompile(
|
||||
case TCL_TOKEN_BS:
|
||||
length = TclParseBackslash(tokenPtr->start, tokenPtr->size,
|
||||
NULL, buf);
|
||||
PushLiteral(envPtr, buf, length);
|
||||
literal = TclRegisterLiteral(envPtr, buf, length, 0);
|
||||
TclEmitPush(literal, envPtr);
|
||||
count++;
|
||||
continue;
|
||||
case TCL_TOKEN_VARIABLE:
|
||||
@@ -1662,7 +1604,8 @@ TclSubstCompile(
|
||||
TclEmitForwardJump(envPtr, TCL_UNCONDITIONAL_JUMP, &startFixup);
|
||||
|
||||
/* Jump to the end (all BREAKs land here) */
|
||||
JUMP4( JUMP, breakOffset);
|
||||
breakOffset = CurrentOffset(envPtr);
|
||||
TclEmitInstInt4(INST_JUMP4, 0, envPtr);
|
||||
|
||||
/* Start */
|
||||
if (TclFixupForwardJumpToHere(envPtr, &startFixup, 127)) {
|
||||
@@ -1673,7 +1616,7 @@ TclSubstCompile(
|
||||
|
||||
envPtr->line = bline;
|
||||
catchRange = TclCreateExceptRange(CATCH_EXCEPTION_RANGE, envPtr);
|
||||
OP4( BEGIN_CATCH4, catchRange);
|
||||
OP4( BEGIN_CATCH4, catchRange);
|
||||
ExceptionRangeStarts(envPtr, catchRange);
|
||||
|
||||
switch (tokenPtr->type) {
|
||||
@@ -1694,21 +1637,21 @@ TclSubstCompile(
|
||||
ExceptionRangeEnds(envPtr, catchRange);
|
||||
|
||||
/* Substitution produced TCL_OK */
|
||||
OP( END_CATCH);
|
||||
OP( END_CATCH);
|
||||
TclEmitForwardJump(envPtr, TCL_UNCONDITIONAL_JUMP, &okFixup);
|
||||
TclAdjustStackDepth(-1, envPtr);
|
||||
|
||||
/* Exceptional return codes processed here */
|
||||
ExceptionRangeTarget(envPtr, catchRange, catchOffset);
|
||||
OP( PUSH_RETURN_OPTIONS);
|
||||
OP( PUSH_RESULT);
|
||||
OP( PUSH_RETURN_CODE);
|
||||
OP( END_CATCH);
|
||||
OP( RETURN_CODE_BRANCH);
|
||||
OP( PUSH_RETURN_OPTIONS);
|
||||
OP( PUSH_RESULT);
|
||||
OP( PUSH_RETURN_CODE);
|
||||
OP( END_CATCH);
|
||||
OP( RETURN_CODE_BRANCH);
|
||||
|
||||
/* ERROR -> reraise it; NB: can't require BREAK/CONTINUE handling */
|
||||
OP( RETURN_STK);
|
||||
OP( NOP);
|
||||
OP( RETURN_STK);
|
||||
OP( NOP);
|
||||
|
||||
/* RETURN */
|
||||
TclEmitForwardJump(envPtr, TCL_UNCONDITIONAL_JUMP, &returnFixup);
|
||||
@@ -1728,14 +1671,14 @@ TclSubstCompile(
|
||||
Tcl_Panic("TclCompileSubstCmd: bad break jump distance %d",
|
||||
(int) (CurrentOffset(envPtr) - breakFixup.codeOffset));
|
||||
}
|
||||
OP( POP);
|
||||
OP( POP);
|
||||
OP( POP);
|
||||
OP( POP);
|
||||
|
||||
breakJump = CurrentOffset(envPtr) - breakOffset;
|
||||
if (breakJump > 127) {
|
||||
OP4( JUMP4, -breakJump);
|
||||
OP4(JUMP4, -breakJump);
|
||||
} else {
|
||||
OP1( JUMP1, -breakJump);
|
||||
OP1(JUMP1, -breakJump);
|
||||
}
|
||||
|
||||
TclAdjustStackDepth(2, envPtr);
|
||||
@@ -1802,7 +1745,8 @@ TclSubstCompile(
|
||||
|
||||
/* Final target of the multi-jump from all BREAKs */
|
||||
if (breakOffset > 0) {
|
||||
FIXJUMP4(breakOffset);
|
||||
TclUpdateInstInt4AtPc(INST_JUMP4, CurrentOffset(envPtr) - breakOffset,
|
||||
envPtr->codeStart + breakOffset);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2099,7 +2043,8 @@ TclCompileSwitchCmd(
|
||||
* illegal, but this makes the error happen at the right time).
|
||||
*/
|
||||
|
||||
if (IsContinuationBody(bodyToken[numWords-1])) {
|
||||
if (bodyToken[numWords-1]->size == 1 &&
|
||||
bodyToken[numWords-1]->start[0] == '-') {
|
||||
goto freeTemporaries;
|
||||
}
|
||||
|
||||
@@ -2111,10 +2056,7 @@ TclCompileSwitchCmd(
|
||||
* but it handles the most common case well enough.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Both methods push the value to match against onto the stack.
|
||||
*/
|
||||
|
||||
/* Both methods push the value to match against onto the stack. */
|
||||
CompileWord(envPtr, valueTokenPtr, interp, valueIndex);
|
||||
|
||||
if (mode == Switch_Exact) {
|
||||
@@ -2198,8 +2140,8 @@ IssueSwitchChainedTests(
|
||||
foundDefault = 0;
|
||||
for (i=0 ; i<numBodyTokens ; i+=2) {
|
||||
nextArmFixupIndex = -1;
|
||||
if (i != numBodyTokens - 2 ||
|
||||
!IsDefaultToken(bodyToken[numBodyTokens - 2])) {
|
||||
if (i!=numBodyTokens-2 || bodyToken[numBodyTokens-2]->size != 7 ||
|
||||
memcmp(bodyToken[numBodyTokens-2]->start, "default", 7)) {
|
||||
/*
|
||||
* Generate the test for the arm.
|
||||
*/
|
||||
@@ -2281,7 +2223,7 @@ IssueSwitchChainedTests(
|
||||
* ensured earlier; the final body is never a fall-through).
|
||||
*/
|
||||
|
||||
if (IsContinuationBody(bodyToken[i + 1])) {
|
||||
if (bodyToken[i+1]->size==1 && bodyToken[i+1]->start[0]=='-') {
|
||||
if (contFixIndex == -1) {
|
||||
contFixIndex = fixupCount;
|
||||
contFixCount = 0;
|
||||
@@ -2461,8 +2403,8 @@ IssueSwitchJumpTable(
|
||||
* term.
|
||||
*/
|
||||
|
||||
if (i != numBodyTokens - 2 ||
|
||||
!IsDefaultToken(bodyToken[numBodyTokens - 2])) {
|
||||
if (i!=numBodyTokens-2 || bodyToken[numBodyTokens-2]->size != 7 ||
|
||||
memcmp(bodyToken[numBodyTokens-2]->start, "default", 7)) {
|
||||
/*
|
||||
* This is not a default clause, so insert the current location as
|
||||
* a target in the jump table (assuming it isn't already there,
|
||||
@@ -2481,8 +2423,7 @@ IssueSwitchJumpTable(
|
||||
* point to here.
|
||||
*/
|
||||
|
||||
Tcl_SetHashValue(hPtr, (ptrdiff_t)
|
||||
(CurrentOffset(envPtr) - jumpLocation));
|
||||
Tcl_SetHashValue(hPtr, CurrentOffset(envPtr) - jumpLocation);
|
||||
}
|
||||
Tcl_DStringFree(&buffer);
|
||||
} else {
|
||||
@@ -2493,8 +2434,8 @@ IssueSwitchJumpTable(
|
||||
|
||||
foundDefault = 1;
|
||||
isNew = 1;
|
||||
TclStoreInt4AtPtr(CurrentOffset(envPtr) - jumpToDefault,
|
||||
envPtr->codeStart + jumpToDefault + 1);
|
||||
TclStoreInt4AtPtr(CurrentOffset(envPtr)-jumpToDefault,
|
||||
envPtr->codeStart+jumpToDefault+1);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2505,7 +2446,7 @@ IssueSwitchJumpTable(
|
||||
* will also point here, so we advance to the next clause.
|
||||
*/
|
||||
|
||||
if (IsContinuationBody(bodyToken[i + 1])) {
|
||||
if (bodyToken[i+1]->size == 1 && bodyToken[i+1]->start[0] == '-') {
|
||||
mustGenerate = 1;
|
||||
continue;
|
||||
}
|
||||
@@ -2557,7 +2498,7 @@ IssueSwitchJumpTable(
|
||||
*/
|
||||
|
||||
if (!foundDefault) {
|
||||
TclStoreInt4AtPtr(CurrentOffset(envPtr) - jumpToDefault,
|
||||
TclStoreInt4AtPtr(CurrentOffset(envPtr)-jumpToDefault,
|
||||
envPtr->codeStart+jumpToDefault+1);
|
||||
PUSH("");
|
||||
}
|
||||
@@ -2568,8 +2509,8 @@ IssueSwitchJumpTable(
|
||||
*/
|
||||
|
||||
for (i=0 ; i<numRealBodies ; i++) {
|
||||
TclStoreInt4AtPtr(CurrentOffset(envPtr) - finalFixups[i],
|
||||
envPtr->codeStart + finalFixups[i] + 1);
|
||||
TclStoreInt4AtPtr(CurrentOffset(envPtr)-finalFixups[i],
|
||||
envPtr->codeStart+finalFixups[i]+1);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2728,7 +2669,7 @@ TclCompileTailcallCmd(
|
||||
tokenPtr = TokenAfter(tokenPtr);
|
||||
CompileWord(envPtr, tokenPtr, interp, i);
|
||||
}
|
||||
OP1( TAILCALL, parsePtr->numWords);
|
||||
TclEmitInstInt1( INST_TAILCALL, parsePtr->numWords, envPtr);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -2776,10 +2717,9 @@ TclCompileThrowCmd(
|
||||
codeKnown = TclWordKnownAtCompileTime(codeToken, objPtr);
|
||||
|
||||
/*
|
||||
* First we must emit the code to substitute the arguments. This must
|
||||
* come first in case substitution raises errors.
|
||||
* First we must emit the code to substitute the arguments. This
|
||||
* must come first in case substitution raises errors.
|
||||
*/
|
||||
|
||||
if (!codeKnown) {
|
||||
CompileWord(envPtr, codeToken, interp, 1);
|
||||
PUSH( "-errorcode");
|
||||
@@ -2803,7 +2743,6 @@ TclCompileThrowCmd(
|
||||
/*
|
||||
* Simpler bytecodes when we detect invalid arguments at compile time.
|
||||
*/
|
||||
|
||||
if (codeKnown && !codeIsValid) {
|
||||
OP( POP);
|
||||
if (codeIsList) {
|
||||
@@ -2816,9 +2755,9 @@ TclCompileThrowCmd(
|
||||
|
||||
if (!codeKnown) {
|
||||
/*
|
||||
* Argument validity checking has to be done by bytecode at run time.
|
||||
* Argument validity checking has to be done by bytecode at
|
||||
* run time.
|
||||
*/
|
||||
|
||||
OP4( REVERSE, 3);
|
||||
OP( DUP);
|
||||
OP( LIST_LENGTH);
|
||||
@@ -2910,7 +2849,8 @@ TclCompileTryCmd(
|
||||
if (tokenPtr->type != TCL_TOKEN_SIMPLE_WORD) {
|
||||
goto failedToCompile;
|
||||
}
|
||||
if (IsTrapToken(&tokenPtr[1])) {
|
||||
if (tokenPtr[1].size == 4
|
||||
&& !strncmp(tokenPtr[1].start, "trap", 4)) {
|
||||
/*
|
||||
* Parse the list of errorCode words to match against.
|
||||
*/
|
||||
@@ -2927,7 +2867,8 @@ TclCompileTryCmd(
|
||||
}
|
||||
Tcl_ListObjReplace(NULL, tmpObj, 0, 0, 0, NULL);
|
||||
matchClauses[i] = tmpObj;
|
||||
} else if (IsOnToken(&tokenPtr[1])) {
|
||||
} else if (tokenPtr[1].size == 2
|
||||
&& !strncmp(tokenPtr[1].start, "on", 2)) {
|
||||
int code;
|
||||
|
||||
/*
|
||||
@@ -3001,7 +2942,7 @@ TclCompileTryCmd(
|
||||
if (tokenPtr->type != TCL_TOKEN_SIMPLE_WORD) {
|
||||
goto failedToCompile;
|
||||
}
|
||||
if (IsContinuationBody(&tokenPtr[1])) {
|
||||
if (tokenPtr[1].size == 1 && tokenPtr[1].start[0] == '-') {
|
||||
handlerTokens[i] = NULL;
|
||||
} else {
|
||||
handlerTokens[i] = tokenPtr;
|
||||
@@ -3022,8 +2963,8 @@ TclCompileTryCmd(
|
||||
if (numWords == 0) {
|
||||
finallyToken = NULL;
|
||||
} else if (numWords == 2) {
|
||||
if (tokenPtr->type != TCL_TOKEN_SIMPLE_WORD ||
|
||||
!IsFinallyToken(&tokenPtr[1])) {
|
||||
if (tokenPtr->type != TCL_TOKEN_SIMPLE_WORD || tokenPtr[1].size != 7
|
||||
|| strncmp(tokenPtr[1].start, "finally", 7)) {
|
||||
goto failedToCompile;
|
||||
}
|
||||
finallyToken = TokenAfter(tokenPtr);
|
||||
@@ -3928,16 +3869,16 @@ TclCompileWhileCmd(
|
||||
|
||||
jumpDist = CurrentOffset(envPtr) - bodyCodeOffset;
|
||||
if (jumpDist > 127) {
|
||||
OP4(JUMP_TRUE4, -jumpDist);
|
||||
TclEmitInstInt4(INST_JUMP_TRUE4, -jumpDist, envPtr);
|
||||
} else {
|
||||
OP1(JUMP_TRUE1, -jumpDist);
|
||||
TclEmitInstInt1(INST_JUMP_TRUE1, -jumpDist, envPtr);
|
||||
}
|
||||
} else {
|
||||
jumpDist = CurrentOffset(envPtr) - bodyCodeOffset;
|
||||
if (jumpDist > 127) {
|
||||
OP4(JUMP4, -jumpDist);
|
||||
TclEmitInstInt4(INST_JUMP4, -jumpDist, envPtr);
|
||||
} else {
|
||||
OP1(JUMP1, -jumpDist);
|
||||
TclEmitInstInt1(INST_JUMP1, -jumpDist, envPtr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4226,16 +4167,16 @@ CompileComparisonOpCmd(
|
||||
STORE(tmpIndex);
|
||||
TclEmitOpcode(instruction, envPtr);
|
||||
for (words=3 ; words<parsePtr->numWords ;) {
|
||||
LOAD( tmpIndex);
|
||||
LOAD(tmpIndex);
|
||||
tokenPtr = TokenAfter(tokenPtr);
|
||||
CompileWord(envPtr, tokenPtr, interp, words);
|
||||
if (++words < parsePtr->numWords) {
|
||||
STORE( tmpIndex);
|
||||
STORE(tmpIndex);
|
||||
}
|
||||
TclEmitOpcode(instruction, envPtr);
|
||||
}
|
||||
for (; words>3 ; words--) {
|
||||
OP( BITAND);
|
||||
OP( BITAND);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -4243,7 +4184,7 @@ CompileComparisonOpCmd(
|
||||
* might be expensive elsewhere.
|
||||
*/
|
||||
|
||||
OP14( UNSET_SCALAR, 0, tmpIndex);
|
||||
OP14( UNSET_SCALAR, 0, tmpIndex);
|
||||
}
|
||||
return TCL_OK;
|
||||
}
|
||||
@@ -4369,7 +4310,7 @@ TclCompilePowOpCmd(
|
||||
words++;
|
||||
}
|
||||
while (--words > 1) {
|
||||
OP( EXPON);
|
||||
TclEmitOpcode(INST_EXPON, envPtr);
|
||||
}
|
||||
return TCL_OK;
|
||||
}
|
||||
@@ -4569,11 +4510,11 @@ TclCompileMinusOpCmd(
|
||||
CompileWord(envPtr, tokenPtr, interp, words);
|
||||
}
|
||||
if (words == 2) {
|
||||
OP( UMINUS);
|
||||
TclEmitOpcode(INST_UMINUS, envPtr);
|
||||
return TCL_OK;
|
||||
}
|
||||
if (words == 3) {
|
||||
OP( SUB);
|
||||
TclEmitOpcode(INST_SUB, envPtr);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -4582,10 +4523,10 @@ TclCompileMinusOpCmd(
|
||||
* calcuations, including roundoff errors.
|
||||
*/
|
||||
|
||||
OP4( REVERSE, words - 1);
|
||||
TclEmitInstInt4(INST_REVERSE, words-1, envPtr);
|
||||
while (--words > 1) {
|
||||
OP4( REVERSE, 2);
|
||||
OP( SUB);
|
||||
TclEmitInstInt4(INST_REVERSE, 2, envPtr);
|
||||
TclEmitOpcode(INST_SUB, envPtr);
|
||||
}
|
||||
return TCL_OK;
|
||||
}
|
||||
@@ -4610,14 +4551,14 @@ TclCompileDivOpCmd(
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if (parsePtr->numWords == 2) {
|
||||
PUSH( "1.0");
|
||||
PUSH("1.0");
|
||||
}
|
||||
for (words=1 ; words<parsePtr->numWords ; words++) {
|
||||
tokenPtr = TokenAfter(tokenPtr);
|
||||
CompileWord(envPtr, tokenPtr, interp, words);
|
||||
}
|
||||
if (words <= 3) {
|
||||
OP( DIV);
|
||||
TclEmitOpcode(INST_DIV, envPtr);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -4626,10 +4567,10 @@ TclCompileDivOpCmd(
|
||||
* calcuations, including roundoff errors.
|
||||
*/
|
||||
|
||||
OP4( REVERSE, words - 1);
|
||||
TclEmitInstInt4(INST_REVERSE, words-1, envPtr);
|
||||
while (--words > 1) {
|
||||
OP4( REVERSE, 2);
|
||||
OP( DIV);
|
||||
TclEmitInstInt4(INST_REVERSE, 2, envPtr);
|
||||
TclEmitOpcode(INST_DIV, envPtr);
|
||||
}
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
+46
-53
@@ -123,18 +123,18 @@ enum Marks {
|
||||
* store a NODE_TYPE code.
|
||||
*/
|
||||
|
||||
#define NODE_TYPE 0xC0
|
||||
enum NodeTypeFlags {
|
||||
NODE_TYPE = 0xC0,
|
||||
|
||||
/*
|
||||
* The four category values are LEAF, UNARY, and BINARY, explained below, and
|
||||
* "uncategorized", which is used either temporarily, until context determines
|
||||
* which of the other three categories is correct, or for lexemes like
|
||||
* INVALID, which aren't really lexemes at all, but indicators of a parsing
|
||||
* error. Note that the codes must be distinct to distinguish categories, but
|
||||
* need not take the form of a bit array.
|
||||
*/
|
||||
/*
|
||||
* The four category values are LEAF, UNARY, and BINARY, explained below,
|
||||
* and "uncategorized", which is used either temporarily, until context
|
||||
* determines which of the other three categories is correct, or for
|
||||
* lexemes like INVALID, which aren't really lexemes at all, but
|
||||
* indicators of a parsing error. Note that the codes must be distinct to
|
||||
* distinguish categories, but need not take the form of a bit array.
|
||||
*/
|
||||
|
||||
enum {
|
||||
BINARY = 0x40, /* This lexeme is a binary operator. An OpNode
|
||||
* representing it should go into the parse
|
||||
* tree, and two operands should be parsed for
|
||||
@@ -153,9 +153,9 @@ enum {
|
||||
* form of substitution. */
|
||||
};
|
||||
|
||||
/* Uncategorized lexemes */
|
||||
enum LexemeTypes {
|
||||
/* Uncategorized lexemes */
|
||||
|
||||
enum {
|
||||
PLUS = 1, /* Ambiguous. Resolves to UNARY_PLUS or
|
||||
* BINARY_PLUS according to context. */
|
||||
MINUS = 2, /* Ambiguous. Resolves to UNARY_MINUS or
|
||||
@@ -167,27 +167,23 @@ enum {
|
||||
* "=" is encountered. */
|
||||
INVALID = 5, /* A parse error. Used when any punctuation
|
||||
* appears that's not a supported operator. */
|
||||
COMMENT = 6 /* Comment. Lasts to end of line or end of
|
||||
COMMENT = 6, /* Comment. Lasts to end of line or end of
|
||||
* expression, whichever comes first. */
|
||||
};
|
||||
|
||||
/* Leaf lexemes */
|
||||
/* Leaf lexemes */
|
||||
|
||||
enum {
|
||||
NUMBER = (LEAF | 1), /* For literal numbers */
|
||||
SCRIPT = (LEAF | 2), /* Script substitution; [foo] */
|
||||
BOOLEAN = (LEAF | BAREWORD),/* For literal booleans */
|
||||
BRACED = (LEAF | 4), /* Braced string; {foo bar} */
|
||||
VARIABLE = (LEAF | 5), /* Variable substitution; $x */
|
||||
QUOTED = (LEAF | 6), /* Quoted string; "foo $bar [soom]" */
|
||||
EMPTY = (LEAF | 7) /* Used only for an empty argument list to a
|
||||
EMPTY = (LEAF | 7), /* Used only for an empty argument list to a
|
||||
* function. Represents the empty string
|
||||
* within parens in the expression: rand() */
|
||||
};
|
||||
|
||||
/* Unary operator lexemes */
|
||||
/* Unary operator lexemes */
|
||||
|
||||
enum {
|
||||
UNARY_PLUS = (UNARY | PLUS),
|
||||
UNARY_MINUS = (UNARY | MINUS),
|
||||
FUNCTION = (UNARY | BAREWORD),
|
||||
@@ -217,51 +213,49 @@ enum {
|
||||
* matching ")" as its operand. See
|
||||
* CLOSE_PAREN below. */
|
||||
NOT = (UNARY | 6),
|
||||
BIT_NOT = (UNARY | 7)
|
||||
};
|
||||
BIT_NOT = (UNARY | 7),
|
||||
|
||||
/* Binary operator lexemes */
|
||||
/* Binary operator lexemes */
|
||||
|
||||
enum {
|
||||
BINARY_PLUS = (BINARY | PLUS),
|
||||
BINARY_MINUS = (BINARY | MINUS),
|
||||
COMMA = (BINARY | 3), /* The "," operator is a low precedence binary
|
||||
BINARY_PLUS = (BINARY | PLUS),
|
||||
BINARY_MINUS = (BINARY | MINUS),
|
||||
COMMA = (BINARY | 3), /* The "," operator is a low precedence binary
|
||||
* operator that separates the arguments in a
|
||||
* function call. The additional constraint
|
||||
* that this operator can only legally appear
|
||||
* at the right places within a function call
|
||||
* argument list are hard coded within
|
||||
* ParseExpr(). */
|
||||
MULT = (BINARY | 4),
|
||||
DIVIDE = (BINARY | 5),
|
||||
MOD = (BINARY | 6),
|
||||
LESS = (BINARY | 7),
|
||||
GREATER = (BINARY | 8),
|
||||
BIT_AND = (BINARY | 9),
|
||||
BIT_XOR = (BINARY | 10),
|
||||
BIT_OR = (BINARY | 11),
|
||||
QUESTION = (BINARY | 12), /* These two lexemes make up the */
|
||||
COLON = (BINARY | 13), /* ternary conditional operator, $x ? $y : $z.
|
||||
* ParseExpr(). */
|
||||
MULT = (BINARY | 4),
|
||||
DIVIDE = (BINARY | 5),
|
||||
MOD = (BINARY | 6),
|
||||
LESS = (BINARY | 7),
|
||||
GREATER = (BINARY | 8),
|
||||
BIT_AND = (BINARY | 9),
|
||||
BIT_XOR = (BINARY | 10),
|
||||
BIT_OR = (BINARY | 11),
|
||||
QUESTION = (BINARY | 12), /* These two lexemes make up the */
|
||||
COLON = (BINARY | 13), /* ternary conditional operator, $x ? $y : $z.
|
||||
* We treat them as two binary operators to
|
||||
* avoid another lexeme category, and code the
|
||||
* additional constraints directly in
|
||||
* ParseExpr(). For instance, the right
|
||||
* operand of a "?" operator must be a ":"
|
||||
* operator. */
|
||||
LEFT_SHIFT = (BINARY | 14),
|
||||
LEFT_SHIFT = (BINARY | 14),
|
||||
RIGHT_SHIFT = (BINARY | 15),
|
||||
LEQ = (BINARY | 16),
|
||||
GEQ = (BINARY | 17),
|
||||
EQUAL = (BINARY | 18),
|
||||
NEQ = (BINARY | 19),
|
||||
AND = (BINARY | 20),
|
||||
OR = (BINARY | 21),
|
||||
STREQ = (BINARY | 22),
|
||||
STRNEQ = (BINARY | 23),
|
||||
EXPON = (BINARY | 24), /* Unlike the other binary operators, EXPON is
|
||||
LEQ = (BINARY | 16),
|
||||
GEQ = (BINARY | 17),
|
||||
EQUAL = (BINARY | 18),
|
||||
NEQ = (BINARY | 19),
|
||||
AND = (BINARY | 20),
|
||||
OR = (BINARY | 21),
|
||||
STREQ = (BINARY | 22),
|
||||
STRNEQ = (BINARY | 23),
|
||||
EXPON = (BINARY | 24), /* Unlike the other binary operators, EXPON is
|
||||
* right associative and this distinction is
|
||||
* coded directly in ParseExpr(). */
|
||||
IN_LIST = (BINARY | 25),
|
||||
IN_LIST = (BINARY | 25),
|
||||
NOT_IN_LIST = (BINARY | 26),
|
||||
CLOSE_PAREN = (BINARY | 27),/* By categorizing the CLOSE_PAREN lexeme as a
|
||||
* BINARY operator, the normal parsing rules
|
||||
@@ -282,7 +276,7 @@ enum {
|
||||
STR_GT = (BINARY | 29),
|
||||
STR_LEQ = (BINARY | 30),
|
||||
STR_GEQ = (BINARY | 31),
|
||||
END = (BINARY | 32) /* This lexeme represents the end of the
|
||||
END = (BINARY | 32), /* This lexeme represents the end of the
|
||||
* string being parsed. Treating it as a
|
||||
* binary operator follows the same logic as
|
||||
* the CLOSE_PAREN lexeme and END pairs with
|
||||
@@ -2675,10 +2669,9 @@ TclSortingOpCmd(
|
||||
Tcl_SetObjResult(interp, Tcl_NewBooleanObj(1));
|
||||
} else {
|
||||
TclOpCmdClientData *occdPtr = (TclOpCmdClientData *)clientData;
|
||||
Tcl_Obj **litObjv = (Tcl_Obj **) TclStackAlloc(interp,
|
||||
Tcl_Obj **litObjv = (Tcl_Obj **)TclStackAlloc(interp,
|
||||
2 * (objc-2) * sizeof(Tcl_Obj *));
|
||||
OpNode *nodes = (OpNode *)
|
||||
TclStackAlloc(interp, 2 * (objc-2) * sizeof(OpNode));
|
||||
OpNode *nodes = (OpNode *)TclStackAlloc(interp, 2 * (objc-2) * sizeof(OpNode));
|
||||
unsigned char lexeme;
|
||||
int i, lastAnd = 1;
|
||||
Tcl_Obj *const *litObjPtrPtr = litObjv;
|
||||
|
||||
+380
-601
File diff suppressed because it is too large
Load Diff
@@ -53,11 +53,12 @@ static const Tcl_ObjType instNameType = {
|
||||
|
||||
#define InstNameGetIntRep(objPtr, inst) \
|
||||
do { \
|
||||
const Tcl_ObjIntRep *irPtr = \
|
||||
TclFetchIntRep((objPtr), &instNameType); \
|
||||
const Tcl_ObjIntRep *irPtr; \
|
||||
irPtr = TclFetchIntRep((objPtr), &instNameType); \
|
||||
assert(irPtr != NULL); \
|
||||
(inst) = (size_t) irPtr->wideValue; \
|
||||
(inst) = (size_t)irPtr->wideValue; \
|
||||
} while (0)
|
||||
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
|
||||
+11
-12
@@ -116,8 +116,7 @@ typedef struct {
|
||||
* entry in this array is 1, otherwise it is
|
||||
* 0. */
|
||||
int numSubTables; /* Length of following array. */
|
||||
EscapeSubTable subTables[TCLFLEXARRAY];
|
||||
/* Information about each EscapeSubTable used
|
||||
EscapeSubTable subTables[TCLFLEXARRAY];/* Information about each EscapeSubTable used
|
||||
* by this encoding type. The actual size is
|
||||
* as large as necessary to hold all
|
||||
* EscapeSubTables. */
|
||||
@@ -128,7 +127,7 @@ typedef struct {
|
||||
* file.
|
||||
*/
|
||||
|
||||
enum {
|
||||
enum EncodingTypes {
|
||||
ENCODING_SINGLEBYTE = 0,
|
||||
ENCODING_DOUBLEBYTE = 1,
|
||||
ENCODING_MULTIBYTE = 2,
|
||||
@@ -236,7 +235,7 @@ static Tcl_EncodingConvertProc Iso88591ToUtfProc;
|
||||
static const Tcl_ObjType encodingType = {
|
||||
"encoding", FreeEncodingIntRep, DupEncodingIntRep, NULL, NULL
|
||||
};
|
||||
#define EncodingSetIntRep(objPtr, encoding) \
|
||||
#define EncodingSetIntRep(objPtr, encoding) \
|
||||
do { \
|
||||
Tcl_ObjIntRep ir; \
|
||||
ir.twoPtrValue.ptr1 = (encoding); \
|
||||
@@ -244,7 +243,7 @@ static const Tcl_ObjType encodingType = {
|
||||
Tcl_StoreIntRep((objPtr), &encodingType, &ir); \
|
||||
} while (0)
|
||||
|
||||
#define EncodingGetIntRep(objPtr, encoding) \
|
||||
#define EncodingGetIntRep(objPtr, encoding) \
|
||||
do { \
|
||||
const Tcl_ObjIntRep *irPtr; \
|
||||
irPtr = TclFetchIntRep ((objPtr), &encodingType); \
|
||||
@@ -513,16 +512,16 @@ FillEncodingFileMap(void)
|
||||
*---------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
enum {
|
||||
/* This flags must not conflict with other TCL_ENCODING_* flags in tcl.h */
|
||||
TCL_ENCODING_MODIFIED = 0x20, /* Converting NULL bytes to 0xC0 0x80 */
|
||||
|
||||
/* These flags must not conflict with other TCL_ENCODING_* flags in tcl.h */
|
||||
enum EncodingFlags {
|
||||
TCL_ENCODING_MODIFIED = 0x20,
|
||||
/* Converting NULL bytes to 0xC0 0x80 */
|
||||
/*
|
||||
* Since TCL_ENCODING_MODIFIED is only used for utf-8 and TCL_ENCODING_LE
|
||||
* is only used for utf-16/ucs-2, re-use the same value
|
||||
* is only used for utf-16/ucs-2, re-use the same value.
|
||||
*/
|
||||
|
||||
TCL_ENCODING_LE = TCL_ENCODING_MODIFIED /* Little-endian encoding */
|
||||
TCL_ENCODING_LE = TCL_ENCODING_MODIFIED
|
||||
/* Little-endian encoding */
|
||||
};
|
||||
|
||||
void
|
||||
|
||||
+16
-25
@@ -15,7 +15,8 @@
|
||||
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
*/
|
||||
|
||||
#define _BUILD_TCL_EXECUTE 1
|
||||
#define _BUILD_TCL_EXECUTE 1 /* Disable some warnings */
|
||||
|
||||
#include "tclInt.h"
|
||||
#include "tclCompile.h"
|
||||
#include "tclOOInt.h"
|
||||
@@ -208,16 +209,11 @@ typedef struct TEBCdata {
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* These variable-access inline functions have to coincide with those in
|
||||
* tclVar.c
|
||||
* These variable-access macros have to coincide with those in tclVar.c
|
||||
*/
|
||||
|
||||
static inline Var *
|
||||
VarHashGetValue(
|
||||
Tcl_HashEntry *hPtr)
|
||||
{
|
||||
return (Var *) ((char *)hPtr - offsetof(VarInHash, entry));
|
||||
}
|
||||
#define VarHashGetValue(hPtr) \
|
||||
((Var *) ((char *)hPtr - offsetof(VarInHash, entry)))
|
||||
|
||||
static inline Var *
|
||||
VarHashCreateVar(
|
||||
@@ -234,13 +230,8 @@ VarHashCreateVar(
|
||||
return VarHashGetValue(hPtr);
|
||||
}
|
||||
|
||||
static inline Var *
|
||||
VarHashFindVar(
|
||||
TclVarHashTable *tablePtr,
|
||||
Tcl_Obj *key)
|
||||
{
|
||||
return VarHashCreateVar((tablePtr), (key), NULL);
|
||||
}
|
||||
#define VarHashFindVar(tablePtr, key) \
|
||||
VarHashCreateVar((tablePtr), (key), NULL)
|
||||
|
||||
/*
|
||||
* The new macro for ending an instruction; note that a reasonable C-optimiser
|
||||
@@ -272,7 +263,7 @@ VarHashFindVar(
|
||||
#define CHECK_STACK()
|
||||
#endif
|
||||
|
||||
#define NEXT_INST_F(pcAdjustment, nCleanup, resultHandling) \
|
||||
#define NEXT_INST_F(pcAdjustment, nCleanup, resultHandling) \
|
||||
do { \
|
||||
TCL_CT_ASSERT((nCleanup >= 0) && (nCleanup <= 2)); \
|
||||
CHECK_STACK(); \
|
||||
@@ -354,16 +345,16 @@ VarHashFindVar(
|
||||
switch (*pc) { \
|
||||
case INST_JUMP_FALSE1: \
|
||||
NEXT_INST_V(((condition)? 2 : TclGetInt1AtPtr(pc+1)), (cleanup), 0); \
|
||||
break; \
|
||||
break; \
|
||||
case INST_JUMP_TRUE1: \
|
||||
NEXT_INST_V(((condition)? TclGetInt1AtPtr(pc+1) : 2), (cleanup), 0); \
|
||||
break; \
|
||||
break; \
|
||||
case INST_JUMP_FALSE4: \
|
||||
NEXT_INST_V(((condition)? 5 : TclGetInt4AtPtr(pc+1)), (cleanup), 0); \
|
||||
break; \
|
||||
break; \
|
||||
case INST_JUMP_TRUE4: \
|
||||
NEXT_INST_V(((condition)? TclGetInt4AtPtr(pc+1) : 5), (cleanup), 0); \
|
||||
break; \
|
||||
break; \
|
||||
default: \
|
||||
if ((condition) < 0) { \
|
||||
TclNewIntObj(objResultPtr, -1); \
|
||||
@@ -371,12 +362,12 @@ VarHashFindVar(
|
||||
objResultPtr = TCONST((condition) > 0); \
|
||||
} \
|
||||
NEXT_INST_V(0, (cleanup), 1); \
|
||||
break; \
|
||||
break; \
|
||||
} \
|
||||
} while (0)
|
||||
#else /* TCL_COMPILE_DEBUG */
|
||||
#define JUMP_PEEPHOLE_F(condition, pcAdjustment, cleanup) \
|
||||
do { \
|
||||
do{ \
|
||||
if ((condition) < 0) { \
|
||||
TclNewIntObj(objResultPtr, -1); \
|
||||
} else { \
|
||||
@@ -385,7 +376,7 @@ VarHashFindVar(
|
||||
NEXT_INST_F((pcAdjustment), (cleanup), 1); \
|
||||
} while (0)
|
||||
#define JUMP_PEEPHOLE_V(condition, pcAdjustment, cleanup) \
|
||||
do { \
|
||||
do{ \
|
||||
if ((condition) < 0) { \
|
||||
TclNewIntObj(objResultPtr, -1); \
|
||||
} else { \
|
||||
@@ -1009,7 +1000,7 @@ static inline int
|
||||
wordSkip(
|
||||
void *ptr)
|
||||
{
|
||||
int mask = TCL_ALLOCALIGN - 1;
|
||||
int mask = TCL_ALLOCALIGN-1;
|
||||
int base = PTR2INT(ptr) & mask;
|
||||
return (TCL_ALLOCALIGN - base)/sizeof(Tcl_Obj *);
|
||||
}
|
||||
|
||||
+251
-263
File diff suppressed because it is too large
Load Diff
+6
-9
@@ -40,9 +40,9 @@ static Tcl_ExitProc FinalizeIOCmdTSD;
|
||||
static Tcl_TcpAcceptProc AcceptCallbackProc;
|
||||
static Tcl_ObjCmdProc ChanPendingObjCmd;
|
||||
static Tcl_ObjCmdProc ChanTruncateObjCmd;
|
||||
static void RegisterTcpServerInterpCleanup(
|
||||
Tcl_Interp *interp,
|
||||
AcceptCallback *acceptCallbackPtr);
|
||||
static void RegisterTcpServerInterpCleanup(
|
||||
Tcl_Interp *interp,
|
||||
AcceptCallback *acceptCallbackPtr);
|
||||
static Tcl_InterpDeleteProc TcpAcceptCallbacksDeleteProc;
|
||||
static void TcpServerCloseProc(ClientData callbackData);
|
||||
static void UnregisterTcpServerInterpCleanupProc(
|
||||
@@ -1219,8 +1219,7 @@ TcpAcceptCallbacksDeleteProc(
|
||||
|
||||
for (hPtr = Tcl_FirstHashEntry(hTblPtr, &hSearch);
|
||||
hPtr != NULL; hPtr = Tcl_NextHashEntry(&hSearch)) {
|
||||
AcceptCallback *acceptCallbackPtr = (AcceptCallback *)
|
||||
Tcl_GetHashValue(hPtr);
|
||||
AcceptCallback *acceptCallbackPtr = (AcceptCallback *)Tcl_GetHashValue(hPtr);
|
||||
|
||||
acceptCallbackPtr->interp = NULL;
|
||||
}
|
||||
@@ -1308,8 +1307,7 @@ UnregisterTcpServerInterpCleanupProc(
|
||||
Tcl_HashTable *hTblPtr;
|
||||
Tcl_HashEntry *hPtr;
|
||||
|
||||
hTblPtr = (Tcl_HashTable *)
|
||||
Tcl_GetAssocData(interp, "tclTCPAcceptCallbacks", NULL);
|
||||
hTblPtr = (Tcl_HashTable *)Tcl_GetAssocData(interp, "tclTCPAcceptCallbacks", NULL);
|
||||
if (hTblPtr == NULL) {
|
||||
return;
|
||||
}
|
||||
@@ -1637,8 +1635,7 @@ Tcl_SocketObjCmd(
|
||||
port = TclGetString(objv[a]);
|
||||
|
||||
if (server) {
|
||||
AcceptCallback *acceptCallbackPtr = (AcceptCallback *)
|
||||
ckalloc(sizeof(AcceptCallback));
|
||||
AcceptCallback *acceptCallbackPtr = (AcceptCallback *)ckalloc(sizeof(AcceptCallback));
|
||||
|
||||
Tcl_IncrRefCount(script);
|
||||
acceptCallbackPtr->script = script;
|
||||
|
||||
+7
-7
@@ -68,7 +68,7 @@ static int ExecuteCallback(TransformChannelData *ctrl,
|
||||
* the procedure what to do with the result of the script it calls.
|
||||
*/
|
||||
|
||||
enum {
|
||||
enum TransmitAction {
|
||||
TRANSMIT_DONT = 0, /* No transfer to do. */
|
||||
TRANSMIT_DOWN = 1, /* Transfer to the underlying channel. */
|
||||
TRANSMIT_SELF = 2, /* Transfer into our channel. */
|
||||
@@ -80,7 +80,7 @@ enum {
|
||||
* Codes for 'preserve' of 'ExecuteCallback'.
|
||||
*/
|
||||
|
||||
enum {
|
||||
enum PreserveFlags {
|
||||
P_PRESERVE = 1,
|
||||
P_NO_PRESERVE = 0
|
||||
};
|
||||
@@ -973,11 +973,11 @@ TransformWideSeekProc(
|
||||
|
||||
if (parentWideSeekProc == NULL) {
|
||||
/*
|
||||
* We're transferring to narrow seeks at this point; this is a bit
|
||||
* complex because we have to check whether the seek is possible first
|
||||
* (i.e. whether we are losing information in truncating the bits of
|
||||
* the offset). Luckily, there's a defined error for what happens when
|
||||
* trying to go out of the representable range.
|
||||
* We're transferring to narrow seeks at this point; this is a bit complex
|
||||
* because we have to check whether the seek is possible first (i.e.
|
||||
* whether we are losing information in truncating the bits of the
|
||||
* offset). Luckily, there's a defined error for what happens when trying
|
||||
* to go out of the representable range.
|
||||
*/
|
||||
|
||||
#ifndef TCL_NO_DEPRECATED
|
||||
|
||||
+13
-17
@@ -43,13 +43,13 @@ static int ReflectBlock(ClientData clientData, int mode);
|
||||
static void ReflectThread(ClientData clientData, int action);
|
||||
static int ReflectEventRun(Tcl_Event *ev, int flags);
|
||||
static int ReflectEventDelete(Tcl_Event *ev, ClientData cd);
|
||||
#endif /* TCL_THREADS */
|
||||
static long long ReflectSeekWide(ClientData clientData,
|
||||
#endif
|
||||
static long long ReflectSeekWide(ClientData clientData,
|
||||
long long offset, int mode, int *errorCodePtr);
|
||||
#ifndef TCL_NO_DEPRECATED
|
||||
static int ReflectSeek(ClientData clientData, long offset,
|
||||
int mode, int *errorCodePtr);
|
||||
#endif /* !TCL_NO_DEPRECATED */
|
||||
#endif
|
||||
static int ReflectGetOption(ClientData clientData,
|
||||
Tcl_Interp *interp, const char *optionName,
|
||||
Tcl_DString *dsPtr);
|
||||
@@ -106,10 +106,10 @@ typedef struct {
|
||||
* interpreter/thread containing its Tcl
|
||||
* command is gone. */
|
||||
#if TCL_THREADS
|
||||
Tcl_ThreadId thread; /* Thread the 'interp' belongs to.
|
||||
* == Handler thread */
|
||||
Tcl_ThreadId owner; /* Thread owning the structure.
|
||||
* == Channel thread */
|
||||
Tcl_ThreadId thread; /* Thread the 'interp' belongs to. == Handler
|
||||
* thread */
|
||||
Tcl_ThreadId owner; /* Thread owning the structure. == Channel
|
||||
* thread */
|
||||
#endif
|
||||
Tcl_Obj *cmd; /* Callback command prefix */
|
||||
Tcl_Obj *methods; /* Methods to append to command prefix */
|
||||
@@ -690,8 +690,7 @@ TclChanCreateObjCmd(
|
||||
* as the actual channel type.
|
||||
*/
|
||||
|
||||
Tcl_ChannelType *clonePtr = (Tcl_ChannelType *)
|
||||
ckalloc(sizeof(Tcl_ChannelType));
|
||||
Tcl_ChannelType *clonePtr = (Tcl_ChannelType *)ckalloc(sizeof(Tcl_ChannelType));
|
||||
|
||||
memcpy(clonePtr, &tclRChannelType, sizeof(Tcl_ChannelType));
|
||||
|
||||
@@ -897,7 +896,7 @@ TclChanPostEventObjCmd(
|
||||
* have gone seriously haywire.
|
||||
*/
|
||||
|
||||
chan = (Tcl_Channel) Tcl_GetHashValue(hPtr);
|
||||
chan = (Tcl_Channel)Tcl_GetHashValue(hPtr);
|
||||
chanTypePtr = Tcl_GetChannelType(chan);
|
||||
|
||||
/*
|
||||
@@ -1166,7 +1165,7 @@ static int
|
||||
ReflectClose(
|
||||
ClientData clientData,
|
||||
Tcl_Interp *interp,
|
||||
int flags)
|
||||
int flags)
|
||||
{
|
||||
ReflectedChannel *rcPtr = (ReflectedChannel *)clientData;
|
||||
int result; /* Result code for 'close' */
|
||||
@@ -2585,8 +2584,7 @@ static ReflectedChannelMap *
|
||||
GetReflectedChannelMap(
|
||||
Tcl_Interp *interp)
|
||||
{
|
||||
ReflectedChannelMap *rcmPtr = (ReflectedChannelMap *)
|
||||
Tcl_GetAssocData(interp, RCMKEY, NULL);
|
||||
ReflectedChannelMap *rcmPtr = (ReflectedChannelMap *)Tcl_GetAssocData(interp, RCMKEY, NULL);
|
||||
|
||||
if (rcmPtr == NULL) {
|
||||
rcmPtr = (ReflectedChannelMap *)ckalloc(sizeof(ReflectedChannelMap));
|
||||
@@ -2789,8 +2787,7 @@ GetThreadReflectedChannelMap(void)
|
||||
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
|
||||
|
||||
if (!tsdPtr->rcmPtr) {
|
||||
tsdPtr->rcmPtr = (ReflectedChannelMap *)
|
||||
ckalloc(sizeof(ReflectedChannelMap));
|
||||
tsdPtr->rcmPtr = (ReflectedChannelMap *)ckalloc(sizeof(ReflectedChannelMap));
|
||||
Tcl_InitHashTable(&tsdPtr->rcmPtr->map, TCL_STRING_KEYS);
|
||||
Tcl_CreateThreadExitHandler(DeleteThreadReflectedChannelMap, NULL);
|
||||
}
|
||||
@@ -2908,8 +2905,7 @@ DeleteThreadReflectedChannelMap(
|
||||
hPtr != NULL;
|
||||
hPtr = Tcl_FirstHashEntry(&rcmPtr->map, &hSearch)) {
|
||||
Tcl_Channel chan = (Tcl_Channel)Tcl_GetHashValue(hPtr);
|
||||
ReflectedChannel *rcPtr = (ReflectedChannel *)
|
||||
Tcl_GetChannelInstanceData(chan);
|
||||
ReflectedChannel *rcPtr = (ReflectedChannel *)Tcl_GetChannelInstanceData(chan);
|
||||
|
||||
MarkDead(rcPtr);
|
||||
Tcl_DeleteHashEntry(hPtr);
|
||||
|
||||
+12
-17
@@ -476,7 +476,7 @@ static int TransformLimit(ReflectedTransform *rtPtr,
|
||||
* Operation codes for TransformFlush().
|
||||
*/
|
||||
|
||||
enum {
|
||||
enum FlushOperations {
|
||||
FLUSH_WRITE = 1,
|
||||
FLUSH_DISCARD = 0
|
||||
};
|
||||
@@ -1154,7 +1154,6 @@ ReflectInput(
|
||||
(char *) Tcl_SetByteArrayLength(bufObj, toRead), toRead);
|
||||
if (readBytes < 0) {
|
||||
if (Tcl_InputBlocked(rtPtr->parent) && (gotBytes > 0)) {
|
||||
|
||||
/*
|
||||
* Down channel is blocked and offers zero additional bytes.
|
||||
* The nonzero gotBytes already returned makes the total
|
||||
@@ -1177,8 +1176,8 @@ ReflectInput(
|
||||
|
||||
if (readBytes == 0) {
|
||||
/*
|
||||
* Zero returned from Tcl_ReadRaw() always indicates EOF
|
||||
* on the down channel.
|
||||
* Zero returned from Tcl_ReadRaw() always indicates EOF on the
|
||||
* down channel.
|
||||
*/
|
||||
|
||||
rtPtr->eofPending = 1;
|
||||
@@ -1259,7 +1258,7 @@ ReflectOutput(
|
||||
int toWrite,
|
||||
int *errorCodePtr)
|
||||
{
|
||||
ReflectedTransform *rtPtr = (ReflectedTransform *) clientData;
|
||||
ReflectedTransform *rtPtr = (ReflectedTransform *)clientData;
|
||||
|
||||
/*
|
||||
* The following check can be done before thread redirection, because we
|
||||
@@ -2038,7 +2037,6 @@ InvokeTclMethod(
|
||||
* This is complex and ugly, and would be completely unnecessary
|
||||
* if we only added support for a TCL_FORBID_EXCEPTIONS flag.
|
||||
*/
|
||||
|
||||
if (result != TCL_ERROR) {
|
||||
Tcl_Obj *cmd = Tcl_NewListObj(cmdc, rtPtr->argv);
|
||||
int cmdLen;
|
||||
@@ -2111,12 +2109,10 @@ static ReflectedTransformMap *
|
||||
GetReflectedTransformMap(
|
||||
Tcl_Interp *interp)
|
||||
{
|
||||
ReflectedTransformMap *rtmPtr = (ReflectedTransformMap *)
|
||||
Tcl_GetAssocData(interp, RTMKEY, NULL);
|
||||
ReflectedTransformMap *rtmPtr = (ReflectedTransformMap *)Tcl_GetAssocData(interp, RTMKEY, NULL);
|
||||
|
||||
if (rtmPtr == NULL) {
|
||||
rtmPtr = (ReflectedTransformMap *)
|
||||
ckalloc(sizeof(ReflectedTransformMap));
|
||||
rtmPtr = (ReflectedTransformMap *)ckalloc(sizeof(ReflectedTransformMap));
|
||||
Tcl_InitHashTable(&rtmPtr->map, TCL_STRING_KEYS);
|
||||
Tcl_SetAssocData(interp, RTMKEY,
|
||||
(Tcl_InterpDeleteProc *) DeleteReflectedTransformMap, rtmPtr);
|
||||
@@ -2279,8 +2275,7 @@ GetThreadReflectedTransformMap(void)
|
||||
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
|
||||
|
||||
if (!tsdPtr->rtmPtr) {
|
||||
tsdPtr->rtmPtr = (ReflectedTransformMap *)
|
||||
ckalloc(sizeof(ReflectedTransformMap));
|
||||
tsdPtr->rtmPtr = (ReflectedTransformMap *)ckalloc(sizeof(ReflectedTransformMap));
|
||||
Tcl_InitHashTable(&tsdPtr->rtmPtr->map, TCL_STRING_KEYS);
|
||||
Tcl_CreateThreadExitHandler(DeleteThreadReflectedTransformMap, NULL);
|
||||
}
|
||||
@@ -2415,8 +2410,8 @@ ForwardOpToOwnerThread(
|
||||
* Create and initialize the event and data structures.
|
||||
*/
|
||||
|
||||
evPtr = (ForwardingEvent *) ckalloc(sizeof(ForwardingEvent));
|
||||
resultPtr = (ForwardingResult *) ckalloc(sizeof(ForwardingResult));
|
||||
evPtr = (ForwardingEvent *)ckalloc(sizeof(ForwardingEvent));
|
||||
resultPtr = (ForwardingResult *)ckalloc(sizeof(ForwardingResult));
|
||||
|
||||
evPtr->event.proc = ForwardProc;
|
||||
evPtr->resultPtr = resultPtr;
|
||||
@@ -2759,7 +2754,7 @@ static void
|
||||
SrcExitProc(
|
||||
ClientData clientData)
|
||||
{
|
||||
ForwardingEvent *evPtr = (ForwardingEvent *) clientData;
|
||||
ForwardingEvent *evPtr = (ForwardingEvent *)clientData;
|
||||
ForwardingResult *resultPtr;
|
||||
ForwardParam *paramPtr;
|
||||
|
||||
@@ -3230,7 +3225,7 @@ TransformDrain(
|
||||
} else
|
||||
#endif /* TCL_THREADS */
|
||||
{
|
||||
if (InvokeTclMethod(rtPtr, "drain", NULL, NULL, &resObj) != TCL_OK) {
|
||||
if (InvokeTclMethod(rtPtr, "drain", NULL, NULL, &resObj)!=TCL_OK) {
|
||||
Tcl_SetChannelError(rtPtr->chan, resObj);
|
||||
Tcl_DecrRefCount(resObj); /* Remove reference held from invoke */
|
||||
*errorCodePtr = EINVAL;
|
||||
@@ -3285,7 +3280,7 @@ TransformFlush(
|
||||
} else
|
||||
#endif /* TCL_THREADS */
|
||||
{
|
||||
if (InvokeTclMethod(rtPtr, "flush", NULL, NULL, &resObj) != TCL_OK) {
|
||||
if (InvokeTclMethod(rtPtr, "flush", NULL, NULL, &resObj)!=TCL_OK) {
|
||||
Tcl_SetChannelError(rtPtr->chan, resObj);
|
||||
Tcl_DecrRefCount(resObj); /* Remove reference held from invoke */
|
||||
*errorCodePtr = EINVAL;
|
||||
|
||||
+489
-656
File diff suppressed because it is too large
Load Diff
+4
-5
@@ -195,14 +195,14 @@ struct LimitHandler {
|
||||
};
|
||||
|
||||
/*
|
||||
* Values for bits in the LimitHandler flags field.
|
||||
* Values for the LimitHandler flags field.
|
||||
*/
|
||||
|
||||
enum {
|
||||
LIMIT_HANDLER_ACTIVE = 1, /* Whether the handler is currently being
|
||||
enum LimitHandlerFlags {
|
||||
LIMIT_HANDLER_ACTIVE = 0x01,/* Whether the handler is currently being
|
||||
* processed; handlers are never to be entered
|
||||
* reentrantly. */
|
||||
LIMIT_HANDLER_DELETED = 2 /* Whether the handler has been deleted. This
|
||||
LIMIT_HANDLER_DELETED = 0x02/* Whether the handler has been deleted. This
|
||||
* should not normally be observed because
|
||||
* when a handler is deleted it is also
|
||||
* spliced out of the list of handlers, but
|
||||
@@ -276,7 +276,6 @@ static void TimeLimitCallback(ClientData clientData);
|
||||
static Tcl_NRPostProc NRPostInvokeHidden;
|
||||
static Tcl_ObjCmdProc NRInterpCmd;
|
||||
static Tcl_ObjCmdProc NRChildCmd;
|
||||
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
|
||||
+2
-2
@@ -77,9 +77,9 @@ typedef struct Link {
|
||||
* Definitions for flag bits:
|
||||
*/
|
||||
|
||||
enum {
|
||||
enum LinkFlags {
|
||||
LINK_READ_ONLY = 1, /* Errors should be generated if Tcl script
|
||||
* attempts to write variable.*/
|
||||
* attempts to write variable. */
|
||||
LINK_BEING_UPDATED = 2, /* A call to Tcl_UpdateLinkedVar is in
|
||||
* progress for this variable, so trace
|
||||
* callbacks on the variable should be
|
||||
|
||||
+2
-2
@@ -105,9 +105,9 @@ typedef struct {
|
||||
* Tcl_NewInstanceMethod.
|
||||
*/
|
||||
|
||||
enum {
|
||||
TCL_OO_METHOD_UNEXPORTED = 0,
|
||||
enum TclOOVisibilityConstants {
|
||||
TCL_OO_METHOD_PUBLIC = 1,
|
||||
TCL_OO_METHOD_UNEXPORTED = 0,
|
||||
TCL_OO_METHOD_PRIVATE = 0x20
|
||||
};
|
||||
|
||||
|
||||
+82
-113
@@ -51,15 +51,40 @@ typedef struct {
|
||||
* Extra flags used for call chain management.
|
||||
*/
|
||||
|
||||
enum {
|
||||
enum CallChainFlags {
|
||||
DEFINITE_PROTECTED = 0x100000,
|
||||
DEFINITE_PUBLIC = 0x200000,
|
||||
DEFINITE_PUBLIC = 0x200000,
|
||||
BUILDING_MIXINS = 0x400000,
|
||||
TRAVERSED_MIXIN = 0x800000,
|
||||
OBJECT_MIXIN = 0x1000000,
|
||||
KNOWN_STATE = (DEFINITE_PROTECTED | DEFINITE_PUBLIC),
|
||||
SPECIAL = (CONSTRUCTOR | DESTRUCTOR | FORCE_UNKNOWN),
|
||||
BUILDING_MIXINS = 0x400000,
|
||||
TRAVERSED_MIXIN = 0x800000,
|
||||
OBJECT_MIXIN = 0x1000000
|
||||
SPECIAL = (CONSTRUCTOR | DESTRUCTOR | FORCE_UNKNOWN)
|
||||
};
|
||||
#define MIXIN_CONSISTENT(flags) \
|
||||
(((flags) & OBJECT_MIXIN) || \
|
||||
!((flags) & BUILDING_MIXINS) == !((flags) & TRAVERSED_MIXIN))
|
||||
|
||||
/*
|
||||
* Note that the flag bit PRIVATE_METHOD has a confusing name; it's just for
|
||||
* Itcl's special type of private.
|
||||
*/
|
||||
|
||||
#define IS_PUBLIC(mPtr) \
|
||||
(((mPtr)->flags & PUBLIC_METHOD) != 0)
|
||||
#define IS_UNEXPORTED(mPtr) \
|
||||
(((mPtr)->flags & SCOPE_FLAGS) == 0)
|
||||
#define IS_ITCLPRIVATE(mPtr) \
|
||||
(((mPtr)->flags & PRIVATE_METHOD) != 0)
|
||||
#define IS_PRIVATE(mPtr) \
|
||||
(((mPtr)->flags & TRUE_PRIVATE_METHOD) != 0)
|
||||
#define WANT_PUBLIC(flags) \
|
||||
(((flags) & PUBLIC_METHOD) != 0)
|
||||
#define WANT_UNEXPORTED(flags) \
|
||||
(((flags) & (PRIVATE_METHOD | TRUE_PRIVATE_METHOD)) == 0)
|
||||
#define WANT_ITCLPRIVATE(flags) \
|
||||
(((flags) & PRIVATE_METHOD) != 0)
|
||||
#define WANT_PRIVATE(flags) \
|
||||
(((flags) & TRUE_PRIVATE_METHOD) != 0)
|
||||
|
||||
/*
|
||||
* Function declarations for things defined in this file.
|
||||
@@ -130,60 +155,6 @@ static const Tcl_ObjType methodNameType = {
|
||||
NULL
|
||||
};
|
||||
|
||||
/*
|
||||
* Inline functions that test flags.
|
||||
*/
|
||||
|
||||
static inline int
|
||||
MixinConsistent(
|
||||
int flags)
|
||||
{
|
||||
return (flags & OBJECT_MIXIN) ||
|
||||
(!(flags & BUILDING_MIXINS) == !(flags & TRAVERSED_MIXIN));
|
||||
}
|
||||
|
||||
static inline int
|
||||
IsPublic(
|
||||
Method *mPtr)
|
||||
{
|
||||
return (mPtr->flags & PUBLIC_METHOD) != 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
IsUnexported(
|
||||
Method *mPtr)
|
||||
{
|
||||
return (mPtr->flags & SCOPE_FLAGS) == 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
IsPrivate(
|
||||
Method *mPtr)
|
||||
{
|
||||
return (mPtr->flags & TRUE_PRIVATE_METHOD) != 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
WantPublic(
|
||||
int flags)
|
||||
{
|
||||
return (flags & PUBLIC_METHOD) != 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
WantUnexported(
|
||||
int flags)
|
||||
{
|
||||
return (flags & (PRIVATE_METHOD | TRUE_PRIVATE_METHOD)) == 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
WantPrivate(
|
||||
int flags)
|
||||
{
|
||||
return (flags & TRUE_PRIVATE_METHOD) != 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------
|
||||
*
|
||||
@@ -309,16 +280,16 @@ DupMethodNameRep(
|
||||
Tcl_Obj *srcPtr,
|
||||
Tcl_Obj *dstPtr)
|
||||
{
|
||||
StashCallChain(dstPtr, (CallChain *)
|
||||
TclFetchIntRep(srcPtr, &methodNameType)->twoPtrValue.ptr1);
|
||||
StashCallChain(dstPtr,
|
||||
(CallChain *)TclFetchIntRep(srcPtr, &methodNameType)->twoPtrValue.ptr1);
|
||||
}
|
||||
|
||||
static void
|
||||
FreeMethodNameRep(
|
||||
Tcl_Obj *objPtr)
|
||||
{
|
||||
TclOODeleteChain((CallChain *)
|
||||
TclFetchIntRep(objPtr, &methodNameType)->twoPtrValue.ptr1);
|
||||
TclOODeleteChain(
|
||||
(CallChain *)TclFetchIntRep(objPtr, &methodNameType)->twoPtrValue.ptr1);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -452,6 +423,14 @@ FinalizeMethodRefs(
|
||||
* ----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/*
|
||||
* Name the bits used in the names table values.
|
||||
*/
|
||||
enum NameTableFlags {
|
||||
IN_LIST = 1,
|
||||
NO_IMPLEMENTATION = 2
|
||||
};
|
||||
|
||||
int
|
||||
TclOOGetSortedMethodList(
|
||||
Object *oPtr, /* The object to get the method names for. */
|
||||
@@ -483,22 +462,16 @@ TclOOGetSortedMethodList(
|
||||
Tcl_InitObjHashTable(&names);
|
||||
Tcl_InitHashTable(&examinedClasses, TCL_ONE_WORD_KEYS);
|
||||
|
||||
/*
|
||||
* Name the bits used in the names table values.
|
||||
*/
|
||||
#define IN_LIST 1
|
||||
#define NO_IMPLEMENTATION 2
|
||||
|
||||
/*
|
||||
* Process method names due to the object.
|
||||
*/
|
||||
|
||||
if (oPtr->methodsPtr) {
|
||||
FOREACH_HASH(namePtr, mPtr, oPtr->methodsPtr) {
|
||||
if (IsPrivate(mPtr)) {
|
||||
if (IS_PRIVATE(mPtr)) {
|
||||
continue;
|
||||
}
|
||||
if (IsUnexported(mPtr) && !WantUnexported(flags)) {
|
||||
if (IS_UNEXPORTED(mPtr) && !WANT_UNEXPORTED(flags)) {
|
||||
continue;
|
||||
}
|
||||
AddStandardMethodName(flags, namePtr, mPtr, &names);
|
||||
@@ -509,9 +482,9 @@ TclOOGetSortedMethodList(
|
||||
* Process method names due to private methods on the object's class.
|
||||
*/
|
||||
|
||||
if (WantUnexported(flags)) {
|
||||
if (WANT_UNEXPORTED(flags)) {
|
||||
FOREACH_HASH(namePtr, mPtr, &oPtr->selfCls->classMethods) {
|
||||
if (IsUnexported(mPtr)) {
|
||||
if (IS_UNEXPORTED(mPtr)) {
|
||||
AddStandardMethodName(flags, namePtr, mPtr, &names);
|
||||
}
|
||||
}
|
||||
@@ -581,7 +554,7 @@ TclOOGetSortedClassMethodList(
|
||||
* Process private method names if we should. [TIP 500]
|
||||
*/
|
||||
|
||||
if (WantPrivate(flags)) {
|
||||
if (WANT_PRIVATE(flags)) {
|
||||
AddPrivateMethodNames(&clsPtr->classMethods, &names);
|
||||
flags &= ~TRUE_PRIVATE_METHOD;
|
||||
}
|
||||
@@ -645,7 +618,7 @@ SortMethodNames(
|
||||
|
||||
strings = (const char **)ckalloc(sizeof(char *) * namesPtr->numEntries);
|
||||
FOREACH_HASH(namePtr, isWanted, namesPtr) {
|
||||
if (!WantPublic(flags) || (PTR2INT(isWanted) & IN_LIST)) {
|
||||
if (!WANT_PUBLIC(flags) || (PTR2INT(isWanted) & IN_LIST)) {
|
||||
if (PTR2INT(isWanted) & NO_IMPLEMENTATION) {
|
||||
continue;
|
||||
}
|
||||
@@ -796,7 +769,7 @@ AddPrivateMethodNames(
|
||||
Tcl_Obj *namePtr;
|
||||
|
||||
FOREACH_HASH(namePtr, mPtr, methodsTablePtr) {
|
||||
if (IsPrivate(mPtr)) {
|
||||
if (IS_PRIVATE(mPtr)) {
|
||||
int isNew;
|
||||
|
||||
hPtr = Tcl_CreateHashEntry(namesPtr, (char *) namePtr, &isNew);
|
||||
@@ -812,13 +785,13 @@ AddStandardMethodName(
|
||||
Method *mPtr,
|
||||
Tcl_HashTable *namesPtr)
|
||||
{
|
||||
if (!IsPrivate(mPtr)) {
|
||||
if (!IS_PRIVATE(mPtr)) {
|
||||
int isNew;
|
||||
Tcl_HashEntry *hPtr =
|
||||
Tcl_CreateHashEntry(namesPtr, (char *) namePtr, &isNew);
|
||||
|
||||
if (isNew) {
|
||||
int isWanted = (!WantPublic(flags) || IsPublic(mPtr))
|
||||
int isWanted = (!WANT_PUBLIC(flags) || IS_PUBLIC(mPtr))
|
||||
? IN_LIST : 0;
|
||||
|
||||
isWanted |= (mPtr->typePtr == NULL ? NO_IMPLEMENTATION : 0);
|
||||
@@ -866,7 +839,7 @@ AddInstancePrivateToCallContext(
|
||||
hPtr = Tcl_FindHashEntry(oPtr->methodsPtr, (char *) methodName);
|
||||
if (hPtr != NULL) {
|
||||
mPtr = (Method *)Tcl_GetHashValue(hPtr);
|
||||
if (IsPrivate(mPtr)) {
|
||||
if (IS_PRIVATE(mPtr)) {
|
||||
AddMethodToCallChain(mPtr, cbPtr, NULL, NULL, flags);
|
||||
donePrivate = 1;
|
||||
}
|
||||
@@ -916,9 +889,9 @@ AddSimpleChainToCallContext(
|
||||
|
||||
if (hPtr != NULL) {
|
||||
mPtr = (Method *)Tcl_GetHashValue(hPtr);
|
||||
if (!IsPrivate(mPtr)) {
|
||||
if (WantPublic(flags)) {
|
||||
if (!IsPublic(mPtr)) {
|
||||
if (!IS_PRIVATE(mPtr)) {
|
||||
if (WANT_PUBLIC(flags)) {
|
||||
if (!IS_PUBLIC(mPtr)) {
|
||||
blockedUnexported = 1;
|
||||
} else {
|
||||
flags |= DEFINITE_PUBLIC;
|
||||
@@ -946,7 +919,7 @@ AddSimpleChainToCallContext(
|
||||
hPtr = Tcl_FindHashEntry(oPtr->methodsPtr, (char*) methodNameObj);
|
||||
if (hPtr != NULL) {
|
||||
mPtr = (Method *)Tcl_GetHashValue(hPtr);
|
||||
if (!IsPrivate(mPtr)) {
|
||||
if (!IS_PRIVATE(mPtr)) {
|
||||
AddMethodToCallChain(mPtr, cbPtr, doneFilters, filterDecl,
|
||||
flags);
|
||||
}
|
||||
@@ -1009,7 +982,7 @@ AddMethodToCallChain(
|
||||
* This is also where we enforce mixin-consistency.
|
||||
*/
|
||||
|
||||
if (mPtr == NULL || mPtr->typePtr == NULL || !MixinConsistent(flags)) {
|
||||
if (mPtr == NULL || mPtr->typePtr == NULL || !MIXIN_CONSISTENT(flags)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1025,8 +998,8 @@ AddMethodToCallChain(
|
||||
* should be sufficient for [incr Tcl] support though.
|
||||
*/
|
||||
|
||||
if (!WantUnexported(callPtr->flags)
|
||||
&& IsUnexported(mPtr)
|
||||
if (!WANT_UNEXPORTED(callPtr->flags)
|
||||
&& IS_UNEXPORTED(mPtr)
|
||||
&& (mPtr->declaringClassPtr != NULL)
|
||||
&& (mPtr->declaringClassPtr != cbPtr->oPtr->selfCls)) {
|
||||
return;
|
||||
@@ -1186,7 +1159,7 @@ TclOOGetCallContext(
|
||||
if (cacheInThisObj == NULL) {
|
||||
cacheInThisObj = methodNameObj;
|
||||
}
|
||||
if (flags & (SPECIAL|FILTER_HANDLING) || (oPtr->flags & FILTER_HANDLING)) {
|
||||
if (flags&(SPECIAL|FILTER_HANDLING) || (oPtr->flags&FILTER_HANDLING)) {
|
||||
hPtr = NULL;
|
||||
doFilters = 0;
|
||||
|
||||
@@ -1220,7 +1193,7 @@ TclOOGetCallContext(
|
||||
*/
|
||||
|
||||
const Tcl_ObjIntRep *irPtr;
|
||||
const int reuseMask = (WantPublic(flags) ? ~0 : ~PUBLIC_METHOD);
|
||||
const int reuseMask = (WANT_PUBLIC(flags) ? ~0 : ~PUBLIC_METHOD);
|
||||
|
||||
if ((irPtr = TclFetchIntRep(cacheInThisObj, &methodNameType))) {
|
||||
callPtr = (CallChain *)irPtr->twoPtrValue.ptr1;
|
||||
@@ -1248,7 +1221,7 @@ TclOOGetCallContext(
|
||||
}
|
||||
|
||||
if (hPtr != NULL && Tcl_GetHashValue(hPtr) != NULL) {
|
||||
callPtr = (CallChain *) Tcl_GetHashValue(hPtr);
|
||||
callPtr = (CallChain *)Tcl_GetHashValue(hPtr);
|
||||
if (IsStillValid(callPtr, oPtr, flags, reuseMask)) {
|
||||
callPtr->refCount++;
|
||||
goto returnContext;
|
||||
@@ -1260,7 +1233,7 @@ TclOOGetCallContext(
|
||||
doFilters = 1;
|
||||
}
|
||||
|
||||
callPtr = (CallChain *) ckalloc(sizeof(CallChain));
|
||||
callPtr = (CallChain *)ckalloc(sizeof(CallChain));
|
||||
InitCallChain(callPtr, oPtr, flags);
|
||||
|
||||
cb.callChainPtr = callPtr;
|
||||
@@ -1365,7 +1338,7 @@ TclOOGetCallContext(
|
||||
if (oPtr->flags & USE_CLASS_CACHE) {
|
||||
if (oPtr->selfCls->classChainCache == NULL) {
|
||||
oPtr->selfCls->classChainCache =
|
||||
(Tcl_HashTable *) ckalloc(sizeof(Tcl_HashTable));
|
||||
(Tcl_HashTable *)ckalloc(sizeof(Tcl_HashTable));
|
||||
|
||||
Tcl_InitObjHashTable(oPtr->selfCls->classChainCache);
|
||||
}
|
||||
@@ -1373,8 +1346,7 @@ TclOOGetCallContext(
|
||||
(char *) methodNameObj, &i);
|
||||
} else {
|
||||
if (oPtr->chainCache == NULL) {
|
||||
oPtr->chainCache = (Tcl_HashTable *)
|
||||
ckalloc(sizeof(Tcl_HashTable));
|
||||
oPtr->chainCache = (Tcl_HashTable *)ckalloc(sizeof(Tcl_HashTable));
|
||||
|
||||
Tcl_InitObjHashTable(oPtr->chainCache);
|
||||
}
|
||||
@@ -1400,8 +1372,7 @@ TclOOGetCallContext(
|
||||
}
|
||||
|
||||
returnContext:
|
||||
contextPtr = (CallContext *)
|
||||
TclStackAlloc(oPtr->fPtr->interp, sizeof(CallContext));
|
||||
contextPtr = (CallContext *)TclStackAlloc(oPtr->fPtr->interp, sizeof(CallContext));
|
||||
contextPtr->oPtr = oPtr;
|
||||
|
||||
/*
|
||||
@@ -1468,9 +1439,9 @@ TclOOGetStereotypeCallChain(
|
||||
hPtr = Tcl_FindHashEntry(clsPtr->classChainCache,
|
||||
(char *) methodNameObj);
|
||||
if (hPtr != NULL && Tcl_GetHashValue(hPtr) != NULL) {
|
||||
const int reuseMask = (WantPublic(flags) ? ~0 : ~PUBLIC_METHOD);
|
||||
const int reuseMask = (WANT_PUBLIC(flags) ? ~0 : ~PUBLIC_METHOD);
|
||||
|
||||
callPtr = (CallChain *) Tcl_GetHashValue(hPtr);
|
||||
callPtr = (CallChain *)Tcl_GetHashValue(hPtr);
|
||||
if (IsStillValid(callPtr, &obj, flags, reuseMask)) {
|
||||
callPtr->refCount++;
|
||||
return callPtr;
|
||||
@@ -1482,9 +1453,9 @@ TclOOGetStereotypeCallChain(
|
||||
hPtr = NULL;
|
||||
}
|
||||
|
||||
callPtr = (CallChain *) ckalloc(sizeof(CallChain));
|
||||
callPtr = (CallChain *)ckalloc(sizeof(CallChain));
|
||||
memset(callPtr, 0, sizeof(CallChain));
|
||||
callPtr->flags = flags & (PUBLIC_METHOD | PRIVATE_METHOD | FILTER_HANDLING);
|
||||
callPtr->flags = flags & (PUBLIC_METHOD|PRIVATE_METHOD|FILTER_HANDLING);
|
||||
callPtr->epoch = fPtr->epoch;
|
||||
callPtr->objectCreationEpoch = fPtr->tsdPtr->nsCount;
|
||||
callPtr->objectEpoch = clsPtr->thisPtr->epoch;
|
||||
@@ -1537,8 +1508,7 @@ TclOOGetStereotypeCallChain(
|
||||
} else {
|
||||
if (hPtr == NULL) {
|
||||
if (clsPtr->classChainCache == NULL) {
|
||||
clsPtr->classChainCache = (Tcl_HashTable *)
|
||||
ckalloc(sizeof(Tcl_HashTable));
|
||||
clsPtr->classChainCache = (Tcl_HashTable *)ckalloc(sizeof(Tcl_HashTable));
|
||||
Tcl_InitObjHashTable(clsPtr->classChainCache);
|
||||
}
|
||||
hPtr = Tcl_CreateHashEntry(clsPtr->classChainCache,
|
||||
@@ -1601,7 +1571,7 @@ AddClassFiltersToCallContext(
|
||||
* override how filters work to extend their behaviour.
|
||||
*/
|
||||
|
||||
if (MixinConsistent(flags)) {
|
||||
if (MIXIN_CONSISTENT(flags)) {
|
||||
FOREACH(filterObj, clsPtr->filters) {
|
||||
int isNew;
|
||||
|
||||
@@ -1691,7 +1661,7 @@ AddPrivatesFromClassChainToCallContext(
|
||||
if (hPtr != NULL) {
|
||||
Method *mPtr = (Method *)Tcl_GetHashValue(hPtr);
|
||||
|
||||
if (IsPrivate(mPtr)) {
|
||||
if (IS_PRIVATE(mPtr)) {
|
||||
AddMethodToCallChain(mPtr, cbPtr, doneFilters, filterDecl,
|
||||
flags);
|
||||
return 1;
|
||||
@@ -1776,10 +1746,10 @@ AddSimpleClassChainToCallContext(
|
||||
if (hPtr != NULL) {
|
||||
Method *mPtr = (Method *)Tcl_GetHashValue(hPtr);
|
||||
|
||||
if (!IsPrivate(mPtr)) {
|
||||
if (!IS_PRIVATE(mPtr)) {
|
||||
if (!(flags & KNOWN_STATE)) {
|
||||
if (flags & PUBLIC_METHOD) {
|
||||
if (!IsPublic(mPtr)) {
|
||||
if (!IS_PUBLIC(mPtr)) {
|
||||
return privateDanger;
|
||||
}
|
||||
flags |= DEFINITE_PUBLIC;
|
||||
@@ -1854,15 +1824,14 @@ TclOORenderCallChain(
|
||||
* method (or "object" if it is declared on the instance).
|
||||
*/
|
||||
|
||||
objv = (Tcl_Obj **)
|
||||
TclStackAlloc(interp, callPtr->numChain * sizeof(Tcl_Obj *));
|
||||
objv = (Tcl_Obj **)TclStackAlloc(interp, callPtr->numChain * sizeof(Tcl_Obj *));
|
||||
for (i = 0 ; i < callPtr->numChain ; i++) {
|
||||
struct MInvoke *miPtr = &callPtr->chain[i];
|
||||
|
||||
descObjs[0] =
|
||||
miPtr->isFilter ? filterLiteral :
|
||||
callPtr->flags & OO_UNKNOWN_METHOD ? fPtr->unknownMethodNameObj :
|
||||
IsPrivate(miPtr->mPtr) ? privateLiteral :
|
||||
IS_PRIVATE(miPtr->mPtr) ? privateLiteral :
|
||||
methodLiteral;
|
||||
descObjs[1] =
|
||||
callPtr->flags & CONSTRUCTOR ? fPtr->constructorName :
|
||||
@@ -2082,7 +2051,7 @@ AddDefinitionNamespaceToChain(
|
||||
* mixin-consistency.
|
||||
*/
|
||||
|
||||
if (namespaceName == NULL || !MixinConsistent(flags)) {
|
||||
if (namespaceName == NULL || !MIXIN_CONSISTENT(flags)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2123,12 +2092,12 @@ AddDefinitionNamespaceToChain(
|
||||
if (definePtr->num == DEFINE_CHAIN_STATIC_SIZE) {
|
||||
DefineEntry *staticList = definePtr->list;
|
||||
|
||||
definePtr->list = (DefineEntry *)
|
||||
ckalloc(sizeof(DefineEntry) * definePtr->size);
|
||||
definePtr->list =
|
||||
(DefineEntry *)ckalloc(sizeof(DefineEntry) * definePtr->size);
|
||||
memcpy(definePtr->list, staticList,
|
||||
sizeof(DefineEntry) * definePtr->num);
|
||||
} else {
|
||||
definePtr->list = (DefineEntry *) ckrealloc(definePtr->list,
|
||||
definePtr->list = (DefineEntry *)ckrealloc(definePtr->list,
|
||||
sizeof(DefineEntry) * definePtr->size);
|
||||
}
|
||||
}
|
||||
|
||||
+13
-12
@@ -103,18 +103,17 @@ typedef struct ProcedureMethod {
|
||||
|
||||
/*
|
||||
* Flags for use in a ProcedureMethod.
|
||||
*
|
||||
* When the USE_DECLARER_NS flag is set, the method will use the namespace of
|
||||
* the object or class that declared it (or the clone of it, if it was from
|
||||
* such that the implementation of the method came to the particular use)
|
||||
* instead of the namespace of the object on which the method was invoked.
|
||||
* This flag must be distinct from all others that are associated with
|
||||
* methods.
|
||||
*/
|
||||
|
||||
enum {
|
||||
USE_DECLARER_NS = 0x80 /* When the USE_DECLARER_NS flag is set, the
|
||||
* method will use the namespace of the object
|
||||
* or class that declared it (or the clone of
|
||||
* it, if it was from such that the
|
||||
* implementation of the method came to the
|
||||
* particular use) instead of the namespace of
|
||||
* the object on which the method was invoked.
|
||||
* This flag must be distinct from all others
|
||||
* that are associated with methods. */
|
||||
enum ProcedureMethodFlags {
|
||||
USE_DECLARER_NS = 0x80,
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -216,7 +215,7 @@ typedef struct Object {
|
||||
* command. */
|
||||
} Object;
|
||||
|
||||
enum {
|
||||
enum ObjectFlags {
|
||||
OBJECT_DESTRUCTING = 1, /* Indicates that an object is being or has
|
||||
* been destroyed */
|
||||
DESTRUCTOR_CALLED = 2, /* Indicates that evaluation of destructor
|
||||
@@ -423,7 +422,7 @@ typedef struct CallContext {
|
||||
* Bits for the 'flags' field of the call chain.
|
||||
*/
|
||||
|
||||
enum {
|
||||
enum TclCallChainFlags {
|
||||
PUBLIC_METHOD = 0x01, /* This is a public (exported) method. */
|
||||
PRIVATE_METHOD = 0x02, /* This is a private (class's direct instances
|
||||
* only) method. Supports itcl. */
|
||||
@@ -672,7 +671,9 @@ MODULE_SCOPE void TclOOSetupVariableResolver(Tcl_Namespace *nsPtr);
|
||||
* but all arguments are used multiple times and so must have no side effects.
|
||||
*/
|
||||
|
||||
#ifdef DUPLICATE
|
||||
#undef DUPLICATE /* prevent possible conflict with definition in WINAPI nb30.h */
|
||||
#endif /* DUPLICATE */
|
||||
#define DUPLICATE(target,source,type) \
|
||||
do { \
|
||||
size_t len = sizeof(type) * ((target).num=(source).num);\
|
||||
|
||||
+195
-208
@@ -165,19 +165,19 @@ static PendingObjData pendingObjData;
|
||||
static __thread PendingObjData pendingObjData;
|
||||
#define ObjInitDeletionContext(contextPtr) \
|
||||
PendingObjData *const contextPtr = &pendingObjData
|
||||
#else /* TCL_THREADS && !defined(HAVE_FAST_TSD) */
|
||||
#else
|
||||
static Tcl_ThreadDataKey pendingObjDataKey;
|
||||
#define ObjInitDeletionContext(contextPtr) \
|
||||
PendingObjData *const contextPtr = (PendingObjData *) \
|
||||
Tcl_GetThreadData(&pendingObjDataKey, sizeof(PendingObjData))
|
||||
PendingObjData *const contextPtr = \
|
||||
(PendingObjData *)Tcl_GetThreadData(&pendingObjDataKey, sizeof(PendingObjData))
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Macro to pack a bignum's fields in a Tcl_Obj internal rep
|
||||
* Macros to pack/unpack a bignum's fields in a Tcl_Obj internal rep
|
||||
*/
|
||||
|
||||
#define PACK_BIGNUM(bignum, objPtr) \
|
||||
if ((bignum).used > 0x7FFF) { \
|
||||
if ((bignum).used > 0x7FFF) { \
|
||||
mp_int *temp = (mp_int *)ckalloc(sizeof(mp_int)); \
|
||||
*temp = bignum; \
|
||||
(objPtr)->internalRep.twoPtrValue.ptr1 = temp; \
|
||||
@@ -185,28 +185,9 @@ static Tcl_ThreadDataKey pendingObjDataKey;
|
||||
} else if (((bignum).alloc <= 0x7FFF) || (mp_shrink(&(bignum))) == MP_OKAY) { \
|
||||
(objPtr)->internalRep.twoPtrValue.ptr1 = (void *)(bignum).dp; \
|
||||
(objPtr)->internalRep.twoPtrValue.ptr2 = INT2PTR(((bignum).sign << 30) \
|
||||
| ((bignum).alloc << 15) | ((bignum).used)); \
|
||||
| ((bignum).alloc << 15) | ((bignum).used)); \
|
||||
}
|
||||
|
||||
/*
|
||||
* Standard way to report a failure to parse something as an integer. This
|
||||
* would probably be an exception throw if this was C++, but it isn't...
|
||||
*/
|
||||
|
||||
static inline int
|
||||
NotAnInteger(
|
||||
Tcl_Interp *interp,
|
||||
Tcl_Obj *objPtr)
|
||||
{
|
||||
if (interp != NULL) {
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"expected integer but got \"%s\"",
|
||||
TclGetString(objPtr)));
|
||||
Tcl_SetErrorCode(interp, "TCL", "VALUE", "INTEGER", NULL);
|
||||
}
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Prototypes for functions defined later in this file:
|
||||
*/
|
||||
@@ -253,7 +234,7 @@ static const Tcl_ObjType oldBooleanType = {
|
||||
NULL, /* freeIntRepProc */
|
||||
NULL, /* dupIntRepProc */
|
||||
NULL, /* updateStringProc */
|
||||
TclSetBooleanFromAny /* setFromAnyProc */
|
||||
TclSetBooleanFromAny /* setFromAnyProc */
|
||||
};
|
||||
#endif
|
||||
const Tcl_ObjType tclBooleanType = {
|
||||
@@ -261,7 +242,7 @@ const Tcl_ObjType tclBooleanType = {
|
||||
NULL, /* freeIntRepProc */
|
||||
NULL, /* dupIntRepProc */
|
||||
NULL, /* updateStringProc */
|
||||
TclSetBooleanFromAny /* setFromAnyProc */
|
||||
TclSetBooleanFromAny /* setFromAnyProc */
|
||||
};
|
||||
const Tcl_ObjType tclDoubleType = {
|
||||
"double", /* name */
|
||||
@@ -274,8 +255,7 @@ const Tcl_ObjType tclIntType = {
|
||||
#if defined(TCL_NO_DEPRECATED) || TCL_MAJOR_VERSION > 8 || defined(TCL_WIDE_INT_IS_LONG)
|
||||
"int", /* name */
|
||||
#else
|
||||
"wideInt", /* name, keeping maximum compatibility with
|
||||
* Tcl 8.6 on 32-bit platforms*/
|
||||
"wideInt", /* name, keeping maximum compatibility with Tcl 8.6 on 32-bit platforms*/
|
||||
#endif
|
||||
NULL, /* freeIntRepProc */
|
||||
NULL, /* dupIntRepProc */
|
||||
@@ -356,7 +336,7 @@ typedef struct ResolvedCmdName {
|
||||
* reference (not the namespace that contains
|
||||
* the referenced command). NULL if the name
|
||||
* is fully qualified.*/
|
||||
unsigned long refNsId; /* refNsPtr's unique namespace id. Used to
|
||||
unsigned long refNsId; /* refNsPtr's unique namespace id. Used to
|
||||
* verify that refNsPtr is still valid (e.g.,
|
||||
* it's possible that the cmd's containing
|
||||
* namespace was deleted and a new one created
|
||||
@@ -422,7 +402,7 @@ TclInitObjSubsystem(void)
|
||||
Tcl_RegisterObjType(&oldIntType);
|
||||
#endif
|
||||
Tcl_RegisterObjType(&oldBooleanType);
|
||||
#endif /* !defined(TCL_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9 */
|
||||
#endif
|
||||
|
||||
#ifdef TCL_COMPILE_STATS
|
||||
Tcl_MutexLock(&tclObjMutex);
|
||||
@@ -436,7 +416,7 @@ TclInitObjSubsystem(void)
|
||||
}
|
||||
}
|
||||
Tcl_MutexUnlock(&tclObjMutex);
|
||||
#endif /* TCL_COMPILE_STATS */
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -587,8 +567,7 @@ TclContinuationsEnter(
|
||||
ThreadSpecificData *tsdPtr = TclGetContLineTable();
|
||||
Tcl_HashEntry *hPtr =
|
||||
Tcl_CreateHashEntry(tsdPtr->lineCLPtr, objPtr, &newEntry);
|
||||
ContLineLoc *clLocPtr = (ContLineLoc *)
|
||||
ckalloc(offsetof(ContLineLoc, loc) + (num + 1) *sizeof(int));
|
||||
ContLineLoc *clLocPtr = (ContLineLoc *)ckalloc(offsetof(ContLineLoc, loc) + (num + 1) *sizeof(int));
|
||||
|
||||
if (!newEntry) {
|
||||
/*
|
||||
@@ -1049,7 +1028,7 @@ TclDbDumpActiveObjects(
|
||||
TCL_UNUSED(FILE *))
|
||||
{
|
||||
}
|
||||
#endif /* TCL_THREADS && defined(TCL_MEM_DEBUG) */
|
||||
#endif
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
@@ -1347,7 +1326,7 @@ TclFreeObj(
|
||||
Tcl_DeleteHashEntry(hPtr);
|
||||
}
|
||||
}
|
||||
#endif /* TCL_THREADS */
|
||||
# endif
|
||||
|
||||
/*
|
||||
* Check for a double free of the same value. This is slightly tricky
|
||||
@@ -1574,27 +1553,24 @@ TclObjBeingDeleted(
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static inline void
|
||||
SetDuplicateObj(
|
||||
Tcl_Obj *dupPtr,
|
||||
Tcl_Obj *objPtr)
|
||||
{
|
||||
const Tcl_ObjType *typePtr = objPtr->typePtr;
|
||||
const char *bytes = objPtr->bytes;
|
||||
if (bytes) {
|
||||
TclInitStringRep(dupPtr, bytes, objPtr->length);
|
||||
} else {
|
||||
dupPtr->bytes = NULL;
|
||||
#define SetDuplicateObj(dupPtr, objPtr) \
|
||||
{ \
|
||||
const Tcl_ObjType *typePtr = (objPtr)->typePtr; \
|
||||
const char *bytes = (objPtr)->bytes; \
|
||||
if (bytes) { \
|
||||
TclInitStringRep((dupPtr), bytes, (objPtr)->length); \
|
||||
} else { \
|
||||
(dupPtr)->bytes = NULL; \
|
||||
} \
|
||||
if (typePtr) { \
|
||||
if (typePtr->dupIntRepProc) { \
|
||||
typePtr->dupIntRepProc((objPtr), (dupPtr)); \
|
||||
} else { \
|
||||
(dupPtr)->internalRep = (objPtr)->internalRep; \
|
||||
(dupPtr)->typePtr = typePtr; \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
if (typePtr) {
|
||||
if (typePtr->dupIntRepProc) {
|
||||
typePtr->dupIntRepProc(objPtr, dupPtr);
|
||||
} else {
|
||||
dupPtr->internalRep = objPtr->internalRep;
|
||||
dupPtr->typePtr = typePtr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Tcl_Obj *
|
||||
Tcl_DuplicateObj(
|
||||
@@ -1644,7 +1620,7 @@ TclSetDuplicateObj(
|
||||
#undef Tcl_GetString
|
||||
char *
|
||||
Tcl_GetString(
|
||||
Tcl_Obj *objPtr) /* Object whose string rep byte pointer should
|
||||
Tcl_Obj *objPtr) /* Object whose string rep byte pointer should
|
||||
* be returned. */
|
||||
{
|
||||
if (objPtr->bytes == NULL) {
|
||||
@@ -1701,9 +1677,9 @@ Tcl_GetString(
|
||||
#undef Tcl_GetStringFromObj
|
||||
char *
|
||||
Tcl_GetStringFromObj(
|
||||
Tcl_Obj *objPtr, /* Object whose string rep byte pointer should
|
||||
Tcl_Obj *objPtr, /* Object whose string rep byte pointer should
|
||||
* be returned. */
|
||||
int *lengthPtr) /* If non-NULL, the location where the string
|
||||
int *lengthPtr) /* If non-NULL, the location where the string
|
||||
* rep's byte array length should * be stored.
|
||||
* If NULL, no length is stored. */
|
||||
{
|
||||
@@ -1741,9 +1717,9 @@ Tcl_GetStringFromObj(
|
||||
#undef TclGetStringFromObj
|
||||
char *
|
||||
TclGetStringFromObj(
|
||||
Tcl_Obj *objPtr, /* Object whose string rep byte pointer should
|
||||
Tcl_Obj *objPtr, /* Object whose string rep byte pointer should
|
||||
* be returned. */
|
||||
size_t *lengthPtr) /* If non-NULL, the location where the string
|
||||
size_t *lengthPtr) /* If non-NULL, the location where the string
|
||||
* rep's byte array length should * be stored.
|
||||
* If NULL, no length is stored. */
|
||||
{
|
||||
@@ -1781,40 +1757,42 @@ TclGetStringFromObj(
|
||||
}
|
||||
return objPtr->bytes;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* Tcl_InitStringRep --
|
||||
*
|
||||
* This function is called in several configurations to provide all the
|
||||
* tools needed to set an object's string representation. The function is
|
||||
* determined by the arguments.
|
||||
* This function is called in several configurations to provide all
|
||||
* the tools needed to set an object's string representation. The
|
||||
* function is determined by the arguments.
|
||||
*
|
||||
* (objPtr->bytes != NULL && bytes != NULL) || (numBytes < 0)
|
||||
* Invalid call -- panic!
|
||||
*
|
||||
* objPtr->bytes == NULL && bytes == NULL && numBytes >= 0
|
||||
* Allocation only - allocate space for (numBytes+1) chars. Store in
|
||||
* objPtr->bytes and return. Also sets objPtr->length to 0 and
|
||||
* objPtr->bytes[0] to NUL.
|
||||
* Allocation only - allocate space for (numBytes+1) chars.
|
||||
* store in objPtr->bytes and return. Also sets
|
||||
* objPtr->length to 0 and objPtr->bytes[0] to NUL.
|
||||
*
|
||||
* objPtr->bytes == NULL && bytes != NULL && numBytes >= 0
|
||||
* Allocate and copy. bytes is assumed to point to chars to copy into
|
||||
* the string rep. objPtr->length = numBytes. Allocate array of
|
||||
* (numBytes + 1) chars. store in objPtr->bytes. Copy numBytes chars
|
||||
* from bytes to objPtr->bytes; Set objPtr->bytes[numBytes] to NUL
|
||||
* and return objPtr->bytes. Caller must guarantee there are
|
||||
* numBytes chars at bytes to be copied.
|
||||
* Allocate and copy. bytes is assumed to point to chars to
|
||||
* copy into the string rep. objPtr->length = numBytes. Allocate
|
||||
* array of (numBytes + 1) chars. store in objPtr->bytes. Copy
|
||||
* numBytes chars from bytes to objPtr->bytes; Set
|
||||
* objPtr->bytes[numBytes] to NUL and return objPtr->bytes.
|
||||
* Caller must guarantee there are numBytes chars at bytes to
|
||||
* be copied.
|
||||
*
|
||||
* objPtr->bytes != NULL && bytes == NULL && numBytes >= 0
|
||||
* Truncate. Set objPtr->length to numBytes and
|
||||
* objPr->bytes[numBytes] to NUL. Caller has to guarantee that a
|
||||
* prior allocating call allocated enough bytes for this to be
|
||||
* valid. Return objPtr->bytes.
|
||||
* objPr->bytes[numBytes] to NUL. Caller has to guarantee
|
||||
* that a prior allocating call allocated enough bytes for
|
||||
* this to be valid. Return objPtr->bytes.
|
||||
*
|
||||
* Caller is expected to ascertain that the bytes copied into the string
|
||||
* rep make up complete valid UTF-8 characters.
|
||||
* Caller is expected to ascertain that the bytes copied into
|
||||
* the string rep make up complete valid UTF-8 characters.
|
||||
*
|
||||
* Results:
|
||||
* A pointer to the string rep of objPtr.
|
||||
@@ -1827,7 +1805,7 @@ TclGetStringFromObj(
|
||||
|
||||
char *
|
||||
Tcl_InitStringRep(
|
||||
Tcl_Obj *objPtr, /* Object whose string rep is to be set */
|
||||
Tcl_Obj *objPtr, /* Object whose string rep is to be set */
|
||||
const char *bytes,
|
||||
unsigned int numBytes)
|
||||
{
|
||||
@@ -1839,9 +1817,7 @@ Tcl_InitStringRep(
|
||||
|
||||
/* Allocate */
|
||||
if (objPtr->bytes == NULL) {
|
||||
/*
|
||||
* Allocate only as empty - extend later if bytes copied.
|
||||
*/
|
||||
/* Allocate only as empty - extend later if bytes copied */
|
||||
objPtr->length = 0;
|
||||
if (numBytes) {
|
||||
objPtr->bytes = (char *)attemptckalloc(numBytes + 1);
|
||||
@@ -1888,7 +1864,7 @@ Tcl_InitStringRep(
|
||||
|
||||
void
|
||||
Tcl_InvalidateStringRep(
|
||||
Tcl_Obj *objPtr) /* Object whose string rep byte pointer should
|
||||
Tcl_Obj *objPtr) /* Object whose string rep byte pointer should
|
||||
* be freed. */
|
||||
{
|
||||
TclInvalidateStringRep(objPtr);
|
||||
@@ -1908,7 +1884,7 @@ Tcl_InvalidateStringRep(
|
||||
|
||||
int
|
||||
Tcl_HasStringRep(
|
||||
Tcl_Obj *objPtr) /* Object to test */
|
||||
Tcl_Obj *objPtr) /* Object to test */
|
||||
{
|
||||
return TclHasStringRep(objPtr);
|
||||
}
|
||||
@@ -1963,12 +1939,12 @@ Tcl_StoreIntRep(
|
||||
* representation matching a requested type, if any.
|
||||
*
|
||||
* Results:
|
||||
* A read-only pointer to the associated Tcl_ObjIntRep, or NULL if no
|
||||
* such internal representation exists.
|
||||
* A read-only pointer to the associated Tcl_ObjIntRep, or
|
||||
* NULL if no such internal representation exists.
|
||||
*
|
||||
* Side effects:
|
||||
* Calls the freeIntRepProc of the current Tcl_ObjType, if any. Sets the
|
||||
* internalRep and typePtr fields to the submitted values.
|
||||
* Calls the freeIntRepProc of the current Tcl_ObjType, if any.
|
||||
* Sets the internalRep and typePtr fields to the submitted values.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
@@ -1992,8 +1968,8 @@ Tcl_FetchIntRep(
|
||||
* None.
|
||||
*
|
||||
* Side effects:
|
||||
* Calls the freeIntRepProc of the current Tcl_ObjType, if any. Sets
|
||||
* typePtr field to NULL.
|
||||
* Calls the freeIntRepProc of the current Tcl_ObjType, if any.
|
||||
* Sets typePtr field to NULL.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
@@ -2011,9 +1987,9 @@ Tcl_FreeIntRep(
|
||||
* Tcl_NewBooleanObj --
|
||||
*
|
||||
* This function is normally called when not debugging: i.e., when
|
||||
* TCL_MEM_DEBUG is not defined. It creates a new Tcl_Obj and initializes
|
||||
* it from the argument boolean value. A nonzero "boolValue" is coerced
|
||||
* to 1.
|
||||
* TCL_MEM_DEBUG is not defined. It creates a new Tcl_Obj and
|
||||
* initializes it from the argument boolean value. A nonzero "boolValue"
|
||||
* is coerced to 1.
|
||||
*
|
||||
* When TCL_MEM_DEBUG is defined, this function just returns the result
|
||||
* of calling the debugging version Tcl_DbNewLongObj.
|
||||
@@ -2033,7 +2009,7 @@ Tcl_FreeIntRep(
|
||||
|
||||
Tcl_Obj *
|
||||
Tcl_NewBooleanObj(
|
||||
int boolValue) /* Boolean used to initialize new object. */
|
||||
int boolValue) /* Boolean used to initialize new object. */
|
||||
{
|
||||
return Tcl_DbNewWideIntObj(boolValue!=0, "unknown", 0);
|
||||
}
|
||||
@@ -2042,7 +2018,7 @@ Tcl_NewBooleanObj(
|
||||
|
||||
Tcl_Obj *
|
||||
Tcl_NewBooleanObj(
|
||||
int boolValue) /* Boolean used to initialize new object. */
|
||||
int boolValue) /* Boolean used to initialize new object. */
|
||||
{
|
||||
Tcl_Obj *objPtr;
|
||||
|
||||
@@ -2083,7 +2059,7 @@ Tcl_NewBooleanObj(
|
||||
|
||||
Tcl_Obj *
|
||||
Tcl_DbNewBooleanObj(
|
||||
int boolValue, /* Boolean used to initialize new object. */
|
||||
int boolValue, /* Boolean used to initialize new object. */
|
||||
const char *file, /* The name of the source file calling this
|
||||
* function; used for debugging. */
|
||||
int line) /* Line number in the source file; used for
|
||||
@@ -2133,8 +2109,8 @@ Tcl_DbNewBooleanObj(
|
||||
#undef Tcl_SetBooleanObj
|
||||
void
|
||||
Tcl_SetBooleanObj(
|
||||
Tcl_Obj *objPtr, /* Object whose internal rep to init. */
|
||||
int boolValue) /* Boolean used to set object's value. */
|
||||
Tcl_Obj *objPtr, /* Object whose internal rep to init. */
|
||||
int boolValue) /* Boolean used to set object's value. */
|
||||
{
|
||||
if (Tcl_IsShared(objPtr)) {
|
||||
Tcl_Panic("%s called with shared object", "Tcl_SetBooleanObj");
|
||||
@@ -2166,8 +2142,8 @@ Tcl_SetBooleanObj(
|
||||
int
|
||||
Tcl_GetBooleanFromObj(
|
||||
Tcl_Interp *interp, /* Used for error reporting if not NULL. */
|
||||
Tcl_Obj *objPtr, /* The object from which to get boolean. */
|
||||
int *boolPtr) /* Place to store resulting boolean. */
|
||||
Tcl_Obj *objPtr, /* The object from which to get boolean. */
|
||||
int *boolPtr) /* Place to store resulting boolean. */
|
||||
{
|
||||
do {
|
||||
if (objPtr->typePtr == &tclIntType) {
|
||||
@@ -2232,7 +2208,7 @@ Tcl_GetBooleanFromObj(
|
||||
int
|
||||
TclSetBooleanFromAny(
|
||||
Tcl_Interp *interp, /* Used for error reporting if not NULL. */
|
||||
Tcl_Obj *objPtr) /* The object to convert. */
|
||||
Tcl_Obj *objPtr) /* The object to convert. */
|
||||
{
|
||||
/*
|
||||
* For some "pure" numeric Tcl_ObjTypes (no string rep), we can determine
|
||||
@@ -2468,7 +2444,7 @@ Tcl_NewDoubleObj(
|
||||
|
||||
Tcl_Obj *
|
||||
Tcl_DbNewDoubleObj(
|
||||
double dblValue, /* Double used to initialize the object. */
|
||||
double dblValue, /* Double used to initialize the object. */
|
||||
const char *file, /* The name of the source file calling this
|
||||
* function; used for debugging. */
|
||||
int line) /* Line number in the source file; used for
|
||||
@@ -2489,7 +2465,7 @@ Tcl_DbNewDoubleObj(
|
||||
|
||||
Tcl_Obj *
|
||||
Tcl_DbNewDoubleObj(
|
||||
double dblValue, /* Double used to initialize the object. */
|
||||
double dblValue, /* Double used to initialize the object. */
|
||||
TCL_UNUSED(const char *) /*file*/,
|
||||
TCL_UNUSED(int) /*line*/)
|
||||
{
|
||||
@@ -2517,8 +2493,8 @@ Tcl_DbNewDoubleObj(
|
||||
|
||||
void
|
||||
Tcl_SetDoubleObj(
|
||||
Tcl_Obj *objPtr, /* Object whose internal rep to init. */
|
||||
double dblValue) /* Double used to set the object's value. */
|
||||
Tcl_Obj *objPtr, /* Object whose internal rep to init. */
|
||||
double dblValue) /* Double used to set the object's value. */
|
||||
{
|
||||
if (Tcl_IsShared(objPtr)) {
|
||||
Tcl_Panic("%s called with shared object", "Tcl_SetDoubleObj");
|
||||
@@ -2550,8 +2526,8 @@ Tcl_SetDoubleObj(
|
||||
int
|
||||
Tcl_GetDoubleFromObj(
|
||||
Tcl_Interp *interp, /* Used for error reporting if not NULL. */
|
||||
Tcl_Obj *objPtr, /* The object from which to get a double. */
|
||||
double *dblPtr) /* Place to store resulting double. */
|
||||
Tcl_Obj *objPtr, /* The object from which to get a double. */
|
||||
double *dblPtr) /* Place to store resulting double. */
|
||||
{
|
||||
do {
|
||||
if (objPtr->typePtr == &tclDoubleType) {
|
||||
@@ -2634,7 +2610,7 @@ SetDoubleFromAny(
|
||||
|
||||
static void
|
||||
UpdateStringOfDouble(
|
||||
Tcl_Obj *objPtr) /* Double obj with string rep to update. */
|
||||
Tcl_Obj *objPtr) /* Double obj with string rep to update. */
|
||||
{
|
||||
char *dst = Tcl_InitStringRep(objPtr, NULL, TCL_DOUBLE_SPACE);
|
||||
|
||||
@@ -2680,7 +2656,7 @@ UpdateStringOfDouble(
|
||||
|
||||
Tcl_Obj *
|
||||
Tcl_NewIntObj(
|
||||
int intValue) /* Int used to initialize the new object. */
|
||||
int intValue) /* Int used to initialize the new object. */
|
||||
{
|
||||
return Tcl_DbNewWideIntObj((long)intValue, "unknown", 0);
|
||||
}
|
||||
@@ -2689,7 +2665,7 @@ Tcl_NewIntObj(
|
||||
|
||||
Tcl_Obj *
|
||||
Tcl_NewIntObj(
|
||||
int intValue) /* Int used to initialize the new object. */
|
||||
int intValue) /* Int used to initialize the new object. */
|
||||
{
|
||||
Tcl_Obj *objPtr;
|
||||
|
||||
@@ -2720,8 +2696,8 @@ Tcl_NewIntObj(
|
||||
#undef Tcl_SetIntObj
|
||||
void
|
||||
Tcl_SetIntObj(
|
||||
Tcl_Obj *objPtr, /* Object whose internal rep to init. */
|
||||
int intValue) /* Integer used to set object's value. */
|
||||
Tcl_Obj *objPtr, /* Object whose internal rep to init. */
|
||||
int intValue) /* Integer used to set object's value. */
|
||||
{
|
||||
if (Tcl_IsShared(objPtr)) {
|
||||
Tcl_Panic("%s called with shared object", "Tcl_SetIntObj");
|
||||
@@ -2760,8 +2736,8 @@ Tcl_SetIntObj(
|
||||
int
|
||||
Tcl_GetIntFromObj(
|
||||
Tcl_Interp *interp, /* Used for error reporting if not NULL. */
|
||||
Tcl_Obj *objPtr, /* The object from which to get a int. */
|
||||
int *intPtr) /* Place to store resulting int. */
|
||||
Tcl_Obj *objPtr, /* The object from which to get a int. */
|
||||
int *intPtr) /* Place to store resulting int. */
|
||||
{
|
||||
#if (LONG_MAX == INT_MAX)
|
||||
return TclGetLongFromObj(interp, objPtr, (long *) intPtr);
|
||||
@@ -2832,7 +2808,7 @@ SetIntFromAny(
|
||||
|
||||
static void
|
||||
UpdateStringOfInt(
|
||||
Tcl_Obj *objPtr) /* Int object whose string rep to update. */
|
||||
Tcl_Obj *objPtr) /* Int object whose string rep to update. */
|
||||
{
|
||||
char *dst = Tcl_InitStringRep( objPtr, NULL, TCL_INTEGER_SPACE);
|
||||
|
||||
@@ -2844,7 +2820,7 @@ UpdateStringOfInt(
|
||||
#if !defined(TCL_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9 && !defined(TCL_WIDE_INT_IS_LONG)
|
||||
static void
|
||||
UpdateStringOfOldInt(
|
||||
Tcl_Obj *objPtr) /* Int object whose string rep to update. */
|
||||
Tcl_Obj *objPtr) /* Int object whose string rep to update. */
|
||||
{
|
||||
char *dst = Tcl_InitStringRep( objPtr, NULL, TCL_INTEGER_SPACE);
|
||||
|
||||
@@ -2890,8 +2866,8 @@ UpdateStringOfOldInt(
|
||||
|
||||
Tcl_Obj *
|
||||
Tcl_NewLongObj(
|
||||
long longValue) /* Long integer used to initialize the new
|
||||
* object. */
|
||||
long longValue) /* Long integer used to initialize the
|
||||
* new object. */
|
||||
{
|
||||
return Tcl_DbNewWideIntObj(longValue, "unknown", 0);
|
||||
}
|
||||
@@ -2900,8 +2876,8 @@ Tcl_NewLongObj(
|
||||
|
||||
Tcl_Obj *
|
||||
Tcl_NewLongObj(
|
||||
long longValue) /* Long integer used to initialize the new
|
||||
* object. */
|
||||
long longValue) /* Long integer used to initialize the
|
||||
* new object. */
|
||||
{
|
||||
Tcl_Obj *objPtr;
|
||||
|
||||
@@ -2949,7 +2925,7 @@ Tcl_NewLongObj(
|
||||
|
||||
Tcl_Obj *
|
||||
Tcl_DbNewLongObj(
|
||||
long longValue, /* Long integer used to initialize the new
|
||||
long longValue, /* Long integer used to initialize the new
|
||||
* object. */
|
||||
const char *file, /* The name of the source file calling this
|
||||
* function; used for debugging. */
|
||||
@@ -2971,7 +2947,7 @@ Tcl_DbNewLongObj(
|
||||
|
||||
Tcl_Obj *
|
||||
Tcl_DbNewLongObj(
|
||||
long longValue, /* Long integer used to initialize the new
|
||||
long longValue, /* Long integer used to initialize the new
|
||||
* object. */
|
||||
TCL_UNUSED(const char *) /*file*/,
|
||||
TCL_UNUSED(int) /*line*/)
|
||||
@@ -3003,8 +2979,8 @@ Tcl_DbNewLongObj(
|
||||
#undef Tcl_SetLongObj
|
||||
void
|
||||
Tcl_SetLongObj(
|
||||
Tcl_Obj *objPtr, /* Object whose internal rep to init. */
|
||||
long longValue) /* Long integer used to initialize the
|
||||
Tcl_Obj *objPtr, /* Object whose internal rep to init. */
|
||||
long longValue) /* Long integer used to initialize the
|
||||
* object's value. */
|
||||
{
|
||||
if (Tcl_IsShared(objPtr)) {
|
||||
@@ -3039,8 +3015,8 @@ Tcl_SetLongObj(
|
||||
int
|
||||
Tcl_GetLongFromObj(
|
||||
Tcl_Interp *interp, /* Used for error reporting if not NULL. */
|
||||
Tcl_Obj *objPtr, /* The object from which to get a long. */
|
||||
long *longPtr) /* Place to store resulting long. */
|
||||
Tcl_Obj *objPtr, /* The object from which to get a long. */
|
||||
long *longPtr) /* Place to store resulting long. */
|
||||
{
|
||||
do {
|
||||
#ifdef TCL_WIDE_INT_IS_LONG
|
||||
@@ -3067,9 +3043,15 @@ Tcl_GetLongFromObj(
|
||||
}
|
||||
goto tooLarge;
|
||||
}
|
||||
#endif /* TCL_WIDE_INT_IS_LONG */
|
||||
#endif
|
||||
if (objPtr->typePtr == &tclDoubleType) {
|
||||
return NotAnInteger(interp, objPtr);
|
||||
if (interp != NULL) {
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"expected integer but got \"%s\"",
|
||||
TclGetString(objPtr)));
|
||||
Tcl_SetErrorCode(interp, "TCL", "VALUE", "INTEGER", NULL);
|
||||
}
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if (objPtr->typePtr == &tclBignumType) {
|
||||
/*
|
||||
@@ -3079,6 +3061,7 @@ Tcl_GetLongFromObj(
|
||||
* values in the unsigned long range will fit in a long.
|
||||
*/
|
||||
|
||||
{
|
||||
mp_int big;
|
||||
unsigned long scratch, value = 0;
|
||||
unsigned char *bytes = (unsigned char *) &scratch;
|
||||
@@ -3087,7 +3070,7 @@ Tcl_GetLongFromObj(
|
||||
TclUnpackBignum(objPtr, big);
|
||||
if (mp_to_ubin(&big, bytes, sizeof(long), &numBytes) == MP_OKAY) {
|
||||
while (numBytes-- > 0) {
|
||||
value = (value << CHAR_BIT) | *bytes++;
|
||||
value = (value << CHAR_BIT) | *bytes++;
|
||||
}
|
||||
if (big.sign) {
|
||||
if (value <= 1 + (unsigned long)LONG_MAX) {
|
||||
@@ -3101,20 +3084,21 @@ Tcl_GetLongFromObj(
|
||||
}
|
||||
}
|
||||
}
|
||||
goto tooLarge;
|
||||
}
|
||||
#ifndef TCL_WIDE_INT_IS_LONG
|
||||
tooLarge:
|
||||
#endif
|
||||
if (interp != NULL) {
|
||||
const char *s = "integer value too large to represent";
|
||||
Tcl_Obj *msg = Tcl_NewStringObj(s, -1);
|
||||
|
||||
Tcl_SetObjResult(interp, msg);
|
||||
Tcl_SetErrorCode(interp, "ARITH", "IOVERFLOW", s, NULL);
|
||||
}
|
||||
return TCL_ERROR;
|
||||
}
|
||||
} while (TclParseNumber(interp, objPtr, "integer", NULL, -1, NULL,
|
||||
TCL_PARSE_INTEGER_ONLY) == TCL_OK);
|
||||
return TCL_ERROR;
|
||||
|
||||
tooLarge:
|
||||
if (interp != NULL) {
|
||||
const char *s = "integer value too large to represent";
|
||||
Tcl_Obj *msg = Tcl_NewStringObj(s, -1);
|
||||
|
||||
Tcl_SetObjResult(interp, msg);
|
||||
Tcl_SetErrorCode(interp, "ARITH", "IOVERFLOW", s, NULL);
|
||||
}
|
||||
TCL_PARSE_INTEGER_ONLY)==TCL_OK);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
@@ -3256,7 +3240,7 @@ Tcl_DbNewWideIntObj(
|
||||
|
||||
void
|
||||
Tcl_SetWideIntObj(
|
||||
Tcl_Obj *objPtr, /* Object w. internal rep to init. */
|
||||
Tcl_Obj *objPtr, /* Object w. internal rep to init. */
|
||||
Tcl_WideInt wideValue)
|
||||
/* Wide integer used to initialize the
|
||||
* object's value. */
|
||||
@@ -3292,7 +3276,7 @@ Tcl_SetWideIntObj(
|
||||
int
|
||||
Tcl_GetWideIntFromObj(
|
||||
Tcl_Interp *interp, /* Used for error reporting if not NULL. */
|
||||
Tcl_Obj *objPtr, /* Object from which to get a wide int. */
|
||||
Tcl_Obj *objPtr, /* Object from which to get a wide int. */
|
||||
Tcl_WideInt *wideIntPtr)
|
||||
/* Place to store resulting long. */
|
||||
{
|
||||
@@ -3302,7 +3286,13 @@ Tcl_GetWideIntFromObj(
|
||||
return TCL_OK;
|
||||
}
|
||||
if (objPtr->typePtr == &tclDoubleType) {
|
||||
return NotAnInteger(interp, objPtr);
|
||||
if (interp != NULL) {
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"expected integer but got \"%s\"",
|
||||
TclGetString(objPtr)));
|
||||
Tcl_SetErrorCode(interp, "TCL", "VALUE", "INTEGER", NULL);
|
||||
}
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if (objPtr->typePtr == &tclBignumType) {
|
||||
/*
|
||||
@@ -3333,20 +3323,17 @@ Tcl_GetWideIntFromObj(
|
||||
}
|
||||
}
|
||||
}
|
||||
goto tooLarge;
|
||||
if (interp != NULL) {
|
||||
const char *s = "integer value too large to represent";
|
||||
Tcl_Obj *msg = Tcl_NewStringObj(s, -1);
|
||||
|
||||
Tcl_SetObjResult(interp, msg);
|
||||
Tcl_SetErrorCode(interp, "ARITH", "IOVERFLOW", s, NULL);
|
||||
}
|
||||
return TCL_ERROR;
|
||||
}
|
||||
} while (TclParseNumber(interp, objPtr, "integer", NULL, -1, NULL,
|
||||
TCL_PARSE_INTEGER_ONLY) == TCL_OK);
|
||||
return TCL_ERROR;
|
||||
|
||||
tooLarge:
|
||||
if (interp != NULL) {
|
||||
const char *s = "integer value too large to represent";
|
||||
Tcl_Obj *msg = Tcl_NewStringObj(s, -1);
|
||||
|
||||
Tcl_SetObjResult(interp, msg);
|
||||
Tcl_SetErrorCode(interp, "ARITH", "IOVERFLOW", s, NULL);
|
||||
}
|
||||
TCL_PARSE_INTEGER_ONLY)==TCL_OK);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
@@ -3384,7 +3371,13 @@ TclGetWideBitsFromObj(
|
||||
return TCL_OK;
|
||||
}
|
||||
if (objPtr->typePtr == &tclDoubleType) {
|
||||
return NotAnInteger(interp, objPtr);
|
||||
if (interp != NULL) {
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"expected integer but got \"%s\"",
|
||||
TclGetString(objPtr)));
|
||||
Tcl_SetErrorCode(interp, "TCL", "VALUE", "INTEGER", NULL);
|
||||
}
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if (objPtr->typePtr == &tclBignumType) {
|
||||
mp_int big;
|
||||
@@ -3410,7 +3403,7 @@ TclGetWideBitsFromObj(
|
||||
return TCL_OK;
|
||||
}
|
||||
} while (TclParseNumber(interp, objPtr, "integer", NULL, -1, NULL,
|
||||
TCL_PARSE_INTEGER_ONLY) == TCL_OK);
|
||||
TCL_PARSE_INTEGER_ONLY)==TCL_OK);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
@@ -3650,13 +3643,11 @@ GetBignumFromObj(
|
||||
objPtr->internalRep.twoPtrValue.ptr1 = NULL;
|
||||
objPtr->internalRep.twoPtrValue.ptr2 = NULL;
|
||||
objPtr->typePtr = NULL;
|
||||
|
||||
/*
|
||||
* TODO: If objPtr has a string rep, this leaves it
|
||||
* undisturbed. Not clear that's proper. Pure bignum values
|
||||
* are converted to empty string.
|
||||
* TODO: If objPtr has a string rep, this leaves
|
||||
* it undisturbed. Not clear that's proper. Pure
|
||||
* bignum values are converted to empty string.
|
||||
*/
|
||||
|
||||
if (objPtr->bytes == NULL) {
|
||||
TclInitStringRep(objPtr, NULL, 0);
|
||||
}
|
||||
@@ -3671,10 +3662,16 @@ GetBignumFromObj(
|
||||
return TCL_OK;
|
||||
}
|
||||
if (objPtr->typePtr == &tclDoubleType) {
|
||||
return NotAnInteger(interp, objPtr);
|
||||
if (interp != NULL) {
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"expected integer but got \"%s\"",
|
||||
TclGetString(objPtr)));
|
||||
Tcl_SetErrorCode(interp, "TCL", "VALUE", "INTEGER", NULL);
|
||||
}
|
||||
return TCL_ERROR;
|
||||
}
|
||||
} while (TclParseNumber(interp, objPtr, "integer", NULL, -1, NULL,
|
||||
TCL_PARSE_INTEGER_ONLY) == TCL_OK);
|
||||
TCL_PARSE_INTEGER_ONLY)==TCL_OK);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
@@ -3912,8 +3909,7 @@ TclGetNumberFromObj(
|
||||
#undef Tcl_IncrRefCount
|
||||
void
|
||||
Tcl_IncrRefCount(
|
||||
Tcl_Obj *objPtr) /* The object we are registering a reference
|
||||
* to. */
|
||||
Tcl_Obj *objPtr) /* The object we are registering a reference to. */
|
||||
{
|
||||
++(objPtr)->refCount;
|
||||
}
|
||||
@@ -3934,8 +3930,7 @@ Tcl_IncrRefCount(
|
||||
#undef Tcl_DecrRefCount
|
||||
void
|
||||
Tcl_DecrRefCount(
|
||||
Tcl_Obj *objPtr) /* The object we are releasing a reference
|
||||
* to. */
|
||||
Tcl_Obj *objPtr) /* The object we are releasing a reference to. */
|
||||
{
|
||||
if (objPtr->refCount-- <= 1) {
|
||||
TclFreeObj(objPtr);
|
||||
@@ -3958,7 +3953,7 @@ Tcl_DecrRefCount(
|
||||
#undef Tcl_IsShared
|
||||
int
|
||||
Tcl_IsShared(
|
||||
Tcl_Obj *objPtr) /* The object to test for being shared. */
|
||||
Tcl_Obj *objPtr) /* The object to test for being shared. */
|
||||
{
|
||||
return ((objPtr)->refCount > 1);
|
||||
}
|
||||
@@ -3987,7 +3982,7 @@ Tcl_IsShared(
|
||||
#ifdef TCL_MEM_DEBUG
|
||||
void
|
||||
Tcl_DbIncrRefCount(
|
||||
Tcl_Obj *objPtr, /* The object we are registering a reference
|
||||
Tcl_Obj *objPtr, /* The object we are registering a reference
|
||||
* to. */
|
||||
const char *file, /* The name of the source file calling this
|
||||
* function; used for debugging. */
|
||||
@@ -4060,7 +4055,7 @@ Tcl_DbIncrRefCount(
|
||||
#ifdef TCL_MEM_DEBUG
|
||||
void
|
||||
Tcl_DbDecrRefCount(
|
||||
Tcl_Obj *objPtr, /* The object we are releasing a reference
|
||||
Tcl_Obj *objPtr, /* The object we are releasing a reference
|
||||
* to. */
|
||||
const char *file, /* The name of the source file calling this
|
||||
* function; used for debugging. */
|
||||
@@ -4103,7 +4098,7 @@ Tcl_DbDecrRefCount(
|
||||
#else /* !TCL_MEM_DEBUG */
|
||||
void
|
||||
Tcl_DbDecrRefCount(
|
||||
Tcl_Obj *objPtr, /* The object we are releasing a reference
|
||||
Tcl_Obj *objPtr, /* The object we are releasing a reference
|
||||
* to. */
|
||||
TCL_UNUSED(const char *) /*file*/,
|
||||
TCL_UNUSED(int) /*line*/)
|
||||
@@ -4137,7 +4132,7 @@ Tcl_DbDecrRefCount(
|
||||
|
||||
int
|
||||
Tcl_DbIsShared(
|
||||
Tcl_Obj *objPtr, /* The object to test for being shared. */
|
||||
Tcl_Obj *objPtr, /* The object to test for being shared. */
|
||||
#ifdef TCL_MEM_DEBUG
|
||||
const char *file, /* The name of the source file calling this
|
||||
* function; used for debugging. */
|
||||
@@ -4284,9 +4279,7 @@ TclCompareObjKeys(
|
||||
* If the object pointers are the same then they match.
|
||||
* OPT: this comparison was moved to the caller
|
||||
|
||||
if (objPtr1 == objPtr2) {
|
||||
return 1;
|
||||
}
|
||||
if (objPtr1 == objPtr2) return 1;
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -4437,7 +4430,7 @@ Tcl_Command
|
||||
Tcl_GetCommandFromObj(
|
||||
Tcl_Interp *interp, /* The interpreter in which to resolve the
|
||||
* command and to report errors. */
|
||||
Tcl_Obj *objPtr) /* The object containing the command's name.
|
||||
Tcl_Obj *objPtr) /* The object containing the command's name.
|
||||
* If the name starts with "::", will be
|
||||
* looked up in global namespace. Else, looked
|
||||
* up first in the current namespace, then in
|
||||
@@ -4486,10 +4479,9 @@ Tcl_GetCommandFromObj(
|
||||
/*
|
||||
* OK, must create a new internal representation (or fail) as any cache we
|
||||
* had is invalid one way or another.
|
||||
*
|
||||
* See [07d13d99b0a9] why we cannot call SetCmdNameFromAny() directly here.
|
||||
*/
|
||||
|
||||
/* See [07d13d99b0a9] why we cannot call SetCmdNameFromAny() directly here. */
|
||||
if (tclCmdNameType.setFromAnyProc(interp, objPtr) != TCL_OK) {
|
||||
return NULL;
|
||||
}
|
||||
@@ -4539,10 +4531,7 @@ SetCmdNameObj(
|
||||
cmdPtr->refCount++;
|
||||
fillPtr->cmdEpoch = cmdPtr->cmdEpoch;
|
||||
|
||||
/*
|
||||
* NOTE: relying on NULL termination here.
|
||||
*/
|
||||
|
||||
/* NOTE: relying on NULL termination here. */
|
||||
if ((name[0] == ':') && (name[1] == ':')) {
|
||||
/*
|
||||
* Fully qualified names always resolve to same thing. No need
|
||||
@@ -4557,7 +4546,6 @@ SetCmdNameObj(
|
||||
* Record current state of current namespace as the resolution
|
||||
* context of this command name lookup.
|
||||
*/
|
||||
|
||||
Namespace *currNsPtr = iPtr->varFramePtr->nsPtr;
|
||||
|
||||
fillPtr->refNsPtr = currNsPtr;
|
||||
@@ -4578,7 +4566,7 @@ void
|
||||
TclSetCmdNameObj(
|
||||
Tcl_Interp *interp, /* Points to interpreter containing command
|
||||
* that should be cached in objPtr. */
|
||||
Tcl_Obj *objPtr, /* Points to Tcl object to be changed to a
|
||||
Tcl_Obj *objPtr, /* Points to Tcl object to be changed to a
|
||||
* CmdName object. */
|
||||
Command *cmdPtr) /* Points to Command structure that the
|
||||
* CmdName object should refer to. */
|
||||
@@ -4618,28 +4606,28 @@ TclSetCmdNameObj(
|
||||
|
||||
static void
|
||||
FreeCmdNameInternalRep(
|
||||
Tcl_Obj *objPtr) /* CmdName object with internal
|
||||
Tcl_Obj *objPtr) /* CmdName object with internal
|
||||
* representation to free. */
|
||||
{
|
||||
ResolvedCmdName *resPtr = (ResolvedCmdName *)
|
||||
objPtr->internalRep.twoPtrValue.ptr1;
|
||||
ResolvedCmdName *resPtr = (ResolvedCmdName *)objPtr->internalRep.twoPtrValue.ptr1;
|
||||
|
||||
/*
|
||||
* Decrement the reference count of the ResolvedCmdName structure. If
|
||||
* there are no more uses, free the ResolvedCmdName structure.
|
||||
*/
|
||||
/*
|
||||
* Decrement the reference count of the ResolvedCmdName structure. If
|
||||
* there are no more uses, free the ResolvedCmdName structure.
|
||||
*/
|
||||
|
||||
if (resPtr->refCount-- <= 1) {
|
||||
/*
|
||||
* Now free the cached command, unless it is still in its hash table
|
||||
* or if there are other references to it from other cmdName objects.
|
||||
*/
|
||||
if (resPtr->refCount-- <= 1) {
|
||||
/*
|
||||
* Now free the cached command, unless it is still in its hash
|
||||
* table or if there are other references to it from other cmdName
|
||||
* objects.
|
||||
*/
|
||||
|
||||
Command *cmdPtr = resPtr->cmdPtr;
|
||||
Command *cmdPtr = resPtr->cmdPtr;
|
||||
|
||||
TclCleanupCommandMacro(cmdPtr);
|
||||
ckfree(resPtr);
|
||||
}
|
||||
TclCleanupCommandMacro(cmdPtr);
|
||||
ckfree(resPtr);
|
||||
}
|
||||
objPtr->typePtr = NULL;
|
||||
}
|
||||
|
||||
@@ -4666,10 +4654,9 @@ FreeCmdNameInternalRep(
|
||||
static void
|
||||
DupCmdNameInternalRep(
|
||||
Tcl_Obj *srcPtr, /* Object with internal rep to copy. */
|
||||
Tcl_Obj *copyPtr) /* Object with internal rep to set. */
|
||||
Tcl_Obj *copyPtr) /* Object with internal rep to set. */
|
||||
{
|
||||
ResolvedCmdName *resPtr = (ResolvedCmdName *)
|
||||
srcPtr->internalRep.twoPtrValue.ptr1;
|
||||
ResolvedCmdName *resPtr = (ResolvedCmdName *)srcPtr->internalRep.twoPtrValue.ptr1;
|
||||
|
||||
copyPtr->internalRep.twoPtrValue.ptr1 = resPtr;
|
||||
copyPtr->internalRep.twoPtrValue.ptr2 = NULL;
|
||||
@@ -4701,7 +4688,7 @@ DupCmdNameInternalRep(
|
||||
static int
|
||||
SetCmdNameFromAny(
|
||||
Tcl_Interp *interp, /* Used for error reporting if not NULL. */
|
||||
Tcl_Obj *objPtr) /* The object to convert. */
|
||||
Tcl_Obj *objPtr) /* The object to convert. */
|
||||
{
|
||||
const char *name;
|
||||
Command *cmdPtr;
|
||||
@@ -4735,8 +4722,8 @@ SetCmdNameFromAny(
|
||||
resPtr = (ResolvedCmdName *)objPtr->internalRep.twoPtrValue.ptr1;
|
||||
if ((objPtr->typePtr == &tclCmdNameType) && (resPtr->refCount == 1)) {
|
||||
/*
|
||||
* Re-use existing ResolvedCmdName struct when possible. Cleanup the
|
||||
* old fields that need it.
|
||||
* Re-use existing ResolvedCmdName struct when possible.
|
||||
* Cleanup the old fields that need it.
|
||||
*/
|
||||
|
||||
Command *oldCmdPtr = resPtr->cmdPtr;
|
||||
|
||||
+14
-24
@@ -119,7 +119,7 @@ const char tclCharTypeTable[] = {
|
||||
* Prototypes for local functions defined in this file:
|
||||
*/
|
||||
|
||||
static int CommandComplete(const char *script, int numBytes);
|
||||
static int CommandComplete(const char *script, int numBytes);
|
||||
static int ParseComment(const char *src, int numBytes,
|
||||
Tcl_Parse *parsePtr);
|
||||
static int ParseTokens(const char *src, int numBytes, int mask,
|
||||
@@ -197,7 +197,7 @@ Tcl_ParseCommand(
|
||||
* NULL, then no error message is provided. */
|
||||
const char *start, /* First character of string containing one or
|
||||
* more Tcl commands. */
|
||||
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:
|
||||
@@ -209,7 +209,7 @@ Tcl_ParseCommand(
|
||||
* the parsed command; any previous
|
||||
* information in the structure is ignored. */
|
||||
{
|
||||
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. */
|
||||
@@ -786,8 +786,7 @@ TclParseBackslash(
|
||||
* of bytes scanned should be written. */
|
||||
char *dst) /* NULL, or points to buffer where the UTF-8
|
||||
* encoding of the backslash sequence is to be
|
||||
* written. At most 4 bytes will be written
|
||||
* there. */
|
||||
* written. At most 4 bytes will be written there. */
|
||||
{
|
||||
const char *p = src+1;
|
||||
int unichar;
|
||||
@@ -871,14 +870,10 @@ TclParseBackslash(
|
||||
result = 'u';
|
||||
} 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.
|
||||
*/
|
||||
|
||||
/* 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;
|
||||
@@ -893,9 +888,7 @@ TclParseBackslash(
|
||||
*/
|
||||
result = 'U';
|
||||
} else if ((result | 0x7FF) == 0xDFFF) {
|
||||
/*
|
||||
* Upper or lower surrogate, not allowed in this syntax.
|
||||
*/
|
||||
/* Upper or lower surrogate, not allowed in this syntax. */
|
||||
result = 0xFFFD;
|
||||
}
|
||||
break;
|
||||
@@ -961,10 +954,7 @@ TclParseBackslash(
|
||||
}
|
||||
count = Tcl_UniCharToUtf(result, dst);
|
||||
if ((result >= 0xD800) && (count < 3)) {
|
||||
/*
|
||||
* Special case for handling high surrogates.
|
||||
*/
|
||||
|
||||
/* Special case for handling high surrogates. */
|
||||
count += Tcl_UniCharToUtf(-1, dst + count);
|
||||
}
|
||||
return count;
|
||||
@@ -991,7 +981,7 @@ TclParseBackslash(
|
||||
static int
|
||||
ParseComment(
|
||||
const char *src, /* First character to parse. */
|
||||
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. */
|
||||
@@ -1063,8 +1053,8 @@ ParseComment(
|
||||
|
||||
static int
|
||||
ParseTokens(
|
||||
const char *src, /* First character to parse. */
|
||||
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
|
||||
@@ -1534,7 +1524,7 @@ Tcl_ParseVarName(
|
||||
const char *
|
||||
Tcl_ParseVar(
|
||||
Tcl_Interp *interp, /* Context for looking up variable. */
|
||||
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
|
||||
@@ -1619,7 +1609,7 @@ Tcl_ParseBraces(
|
||||
* NULL, then no error message is provided. */
|
||||
const char *start, /* Start of string enclosed in braces. The
|
||||
* first character must be {'. */
|
||||
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,
|
||||
@@ -1820,7 +1810,7 @@ Tcl_ParseQuotedString(
|
||||
* NULL, then no error message is provided. */
|
||||
const char *start, /* Start of the quoted string. The first
|
||||
* character must be '"'. */
|
||||
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,
|
||||
|
||||
+20
-4
@@ -1,9 +1,17 @@
|
||||
/*
|
||||
* Minimal set of shared macro definitions and declarations so that multiple
|
||||
* source files can make use of the parsing table in tclParse.c
|
||||
* tclParse.h --
|
||||
*
|
||||
* This file contains the minimal set of shared macro definitions and
|
||||
* declarations so that multiple source files can make use of the parsing
|
||||
* table in tclParse.c.
|
||||
*
|
||||
* Copyright (c) 2012 by Don Porter
|
||||
*
|
||||
* See the file "license.terms" for information on usage and redistribution of
|
||||
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
*/
|
||||
|
||||
enum {
|
||||
enum ParseTypes {
|
||||
TYPE_NORMAL = 0,
|
||||
TYPE_SPACE = 0x1,
|
||||
TYPE_COMMAND_END = 0x2,
|
||||
@@ -14,6 +22,14 @@ enum {
|
||||
TYPE_BRACE = 0x40
|
||||
};
|
||||
|
||||
#define CHAR_TYPE(c) tclCharTypeTable[(unsigned char)(c)]
|
||||
#define CHAR_TYPE(c) tclCharTypeTable[(unsigned char)(c)]
|
||||
|
||||
MODULE_SCOPE const char tclCharTypeTable[];
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: c
|
||||
* c-basic-offset: 4
|
||||
* fill-column: 78
|
||||
* End:
|
||||
*/
|
||||
|
||||
+27
-38
@@ -77,36 +77,27 @@ typedef struct FsPath {
|
||||
* Flag values for FsPath->flags.
|
||||
*/
|
||||
|
||||
enum {
|
||||
enum FsPathFlags {
|
||||
TCLPATH_APPENDED = 1,
|
||||
TCLPATH_NEEDNORM = 4
|
||||
};
|
||||
|
||||
/*
|
||||
* Define some inline functions to give us convenient fast access to
|
||||
* path-object specific fields.
|
||||
* Define some macros to give us convenient access to path-object specific
|
||||
* fields.
|
||||
*/
|
||||
|
||||
static inline FsPath *
|
||||
PATHOBJ(
|
||||
Tcl_Obj *pathPtr)
|
||||
{
|
||||
return (FsPath *) TclFetchIntRep(pathPtr, &fsPathType)->twoPtrValue.ptr1;
|
||||
}
|
||||
|
||||
static inline void
|
||||
SETPATHOBJ(
|
||||
Tcl_Obj *pathPtr,
|
||||
FsPath *fsPathPtr)
|
||||
{
|
||||
Tcl_ObjIntRep ir;
|
||||
|
||||
ir.twoPtrValue.ptr1 = (void *) fsPathPtr;
|
||||
ir.twoPtrValue.ptr2 = NULL;
|
||||
Tcl_StoreIntRep(pathPtr, &fsPathType, &ir);
|
||||
}
|
||||
|
||||
#define PATHFLAGS(pathPtr) (PATHOBJ(pathPtr)->flags)
|
||||
#define PATHOBJ(pathPtr) \
|
||||
((FsPath *) (TclFetchIntRep((pathPtr), &fsPathType)->twoPtrValue.ptr1))
|
||||
#define SETPATHOBJ(pathPtr,fsPathPtr) \
|
||||
do { \
|
||||
Tcl_ObjIntRep ir; \
|
||||
ir.twoPtrValue.ptr1 = (void *) (fsPathPtr); \
|
||||
ir.twoPtrValue.ptr2 = NULL; \
|
||||
Tcl_StoreIntRep((pathPtr), &fsPathType, &ir); \
|
||||
} while (0)
|
||||
#define PATHFLAGS(pathPtr) \
|
||||
(PATHOBJ(pathPtr)->flags)
|
||||
|
||||
/*
|
||||
*---------------------------------------------------------------------------
|
||||
@@ -156,17 +147,17 @@ TclFSNormalizeAbsolutePath(
|
||||
dirSep = TclGetString(pathPtr);
|
||||
|
||||
if (tclPlatform == TCL_PLATFORM_WINDOWS) {
|
||||
if ( (dirSep[0] == '/' || dirSep[0] == '\\') &&
|
||||
(dirSep[1] == '/' || dirSep[1] == '\\') &&
|
||||
(dirSep[2] == '?') &&
|
||||
(dirSep[3] == '/' || dirSep[3] == '\\')) {
|
||||
if ( (dirSep[0] == '/' || dirSep[0] == '\\')
|
||||
&& (dirSep[1] == '/' || dirSep[1] == '\\')
|
||||
&& (dirSep[2] == '?')
|
||||
&& (dirSep[3] == '/' || dirSep[3] == '\\')) {
|
||||
/* NT extended path */
|
||||
dirSep += 4;
|
||||
|
||||
if ( (dirSep[0] == 'U' || dirSep[0] == 'u') &&
|
||||
(dirSep[1] == 'N' || dirSep[1] == 'n') &&
|
||||
(dirSep[2] == 'C' || dirSep[2] == 'c') &&
|
||||
(dirSep[3] == '/' || dirSep[3] == '\\')) {
|
||||
if ( (dirSep[0] == 'U' || dirSep[0] == 'u')
|
||||
&& (dirSep[1] == 'N' || dirSep[1] == 'n')
|
||||
&& (dirSep[2] == 'C' || dirSep[2] == 'c')
|
||||
&& (dirSep[3] == '/' || dirSep[3] == '\\')) {
|
||||
/* NT extended UNC path */
|
||||
dirSep += 4;
|
||||
}
|
||||
@@ -174,8 +165,8 @@ TclFSNormalizeAbsolutePath(
|
||||
if (dirSep[0] != 0 && dirSep[1] == ':' &&
|
||||
(dirSep[2] == '/' || dirSep[2] == '\\')) {
|
||||
/* Do nothing */
|
||||
} else if ((dirSep[0] == '/' || dirSep[0] == '\\') &&
|
||||
(dirSep[1] == '/' || dirSep[1] == '\\')) {
|
||||
} else if ((dirSep[0] == '/' || dirSep[0] == '\\')
|
||||
&& (dirSep[1] == '/' || dirSep[1] == '\\')) {
|
||||
/*
|
||||
* UNC style path, where we must skip over the first separator,
|
||||
* since the first two segments are actually inseparable.
|
||||
@@ -945,7 +936,7 @@ TclJoinPath(
|
||||
}
|
||||
}
|
||||
|
||||
assert (res == NULL);
|
||||
assert ( res == NULL );
|
||||
|
||||
for (i = 0; i < elements; i++) {
|
||||
int driveNameLength, strEltLen, length;
|
||||
@@ -1120,7 +1111,7 @@ TclJoinPath(
|
||||
Tcl_SetObjLength(res, length);
|
||||
}
|
||||
}
|
||||
assert (res != NULL);
|
||||
assert ( res != NULL );
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -1773,9 +1764,7 @@ Tcl_FSGetNormalizedPath(
|
||||
TclFSNormalizeToUniquePath(interp, copy, cwdLen);
|
||||
}
|
||||
|
||||
/*
|
||||
* Now we need to construct the new path object.
|
||||
*/
|
||||
/* Now we need to construct the new path object. */
|
||||
|
||||
if (pathType == TCL_PATH_RELATIVE) {
|
||||
Tcl_Obj *origDir = fsPathPtr->cwdPtr;
|
||||
|
||||
+11
-15
@@ -16,7 +16,7 @@
|
||||
* Flag values used by Tcl_ScanObjCmd.
|
||||
*/
|
||||
|
||||
enum {
|
||||
enum ScanFlags {
|
||||
SCAN_NOSKIP = 0x1, /* Don't skip blanks. */
|
||||
SCAN_SUPPRESS = 0x2, /* Suppress assignment. */
|
||||
SCAN_UNSIGNED = 0x4, /* Read an unsigned value. */
|
||||
@@ -105,10 +105,9 @@ BuildCharSet(
|
||||
end += TclUtfToUniChar(end, &ch);
|
||||
}
|
||||
|
||||
cset->chars = (Tcl_UniChar *)
|
||||
ckalloc(sizeof(Tcl_UniChar) * (end - format - 1));
|
||||
cset->chars = (Tcl_UniChar *)ckalloc(sizeof(Tcl_UniChar) * (end - format - 1));
|
||||
if (nranges > 0) {
|
||||
cset->ranges = (Range *) ckalloc(sizeof(Range) * nranges);
|
||||
cset->ranges = (Range *)ckalloc(sizeof(Range) * nranges);
|
||||
} else {
|
||||
cset->ranges = NULL;
|
||||
}
|
||||
@@ -264,7 +263,7 @@ ValidateFormat(
|
||||
char *end;
|
||||
Tcl_UniChar ch = 0;
|
||||
int objIndex, xpgSize, nspace = numVars;
|
||||
int *nassign = (int *) TclStackAlloc(interp, nspace * sizeof(int));
|
||||
int *nassign = (int *)TclStackAlloc(interp, nspace * sizeof(int));
|
||||
Tcl_Obj *errorMsg; /* Place to build an error messages. Note that
|
||||
* these are messy operations because we do
|
||||
* not want to use the formatting engine;
|
||||
@@ -481,7 +480,7 @@ ValidateFormat(
|
||||
} else {
|
||||
nspace += 16; /* formerly STATIC_LIST_SIZE */
|
||||
}
|
||||
nassign = (int *) TclStackRealloc(interp, nassign,
|
||||
nassign = (int *)TclStackRealloc(interp, nassign,
|
||||
nspace * sizeof(int));
|
||||
for (i = value; i < nspace; i++) {
|
||||
nassign[i] = 0;
|
||||
@@ -590,7 +589,7 @@ Tcl_ScanObjCmd(
|
||||
}
|
||||
|
||||
format = Tcl_GetString(objv[2]);
|
||||
numVars = objc - 3;
|
||||
numVars = objc-3;
|
||||
|
||||
/*
|
||||
* Check for errors in the format string.
|
||||
@@ -605,7 +604,7 @@ Tcl_ScanObjCmd(
|
||||
*/
|
||||
|
||||
if (totalVars > 0) {
|
||||
objs = (Tcl_Obj **) ckalloc(sizeof(Tcl_Obj *) * totalVars);
|
||||
objs = (Tcl_Obj **)ckalloc(sizeof(Tcl_Obj *) * totalVars);
|
||||
for (i = 0; i < totalVars; i++) {
|
||||
objs[i] = NULL;
|
||||
}
|
||||
@@ -892,15 +891,13 @@ Tcl_ScanObjCmd(
|
||||
/*
|
||||
* Scan an unsigned or signed integer.
|
||||
*/
|
||||
|
||||
TclNewIntObj(objPtr, 0);
|
||||
Tcl_IncrRefCount(objPtr);
|
||||
if (width == 0) {
|
||||
width = ~0;
|
||||
}
|
||||
if (TCL_OK != TclParseNumber(NULL, objPtr, NULL, string, width,
|
||||
&end, TCL_PARSE_INTEGER_ONLY | TCL_PARSE_NO_UNDERSCORE |
|
||||
parseFlag)) {
|
||||
&end, TCL_PARSE_INTEGER_ONLY | TCL_PARSE_NO_UNDERSCORE | parseFlag)) {
|
||||
Tcl_DecrRefCount(objPtr);
|
||||
if (width < 0) {
|
||||
if (*end == '\0') {
|
||||
@@ -983,7 +980,7 @@ Tcl_ScanObjCmd(
|
||||
}
|
||||
#else
|
||||
Tcl_SetWideIntObj(objPtr, (unsigned long)value);
|
||||
#endif /* TCL_WIDE_INT_IS_LONG */
|
||||
#endif
|
||||
} else {
|
||||
TclSetIntObj(objPtr, value);
|
||||
}
|
||||
@@ -1002,8 +999,7 @@ Tcl_ScanObjCmd(
|
||||
width = ~0;
|
||||
}
|
||||
if (TCL_OK != TclParseNumber(NULL, objPtr, NULL, string, width,
|
||||
&end, TCL_PARSE_DECIMAL_ONLY | TCL_PARSE_NO_WHITESPACE |
|
||||
TCL_PARSE_NO_UNDERSCORE)) {
|
||||
&end, TCL_PARSE_DECIMAL_ONLY | TCL_PARSE_NO_WHITESPACE | TCL_PARSE_NO_UNDERSCORE)) {
|
||||
Tcl_DecrRefCount(objPtr);
|
||||
if (width < 0) {
|
||||
if (*end == '\0') {
|
||||
@@ -1027,7 +1023,7 @@ Tcl_ScanObjCmd(
|
||||
if (irPtr) {
|
||||
dvalue = irPtr->doubleValue;
|
||||
} else
|
||||
#endif /* ACCEPT_NAN */
|
||||
#endif
|
||||
{
|
||||
Tcl_DecrRefCount(objPtr);
|
||||
goto done;
|
||||
|
||||
+4
-4
@@ -71,10 +71,11 @@ typedef struct {
|
||||
* The flag 'TCL_TRACE_DESTROYED' may also be used in command execution traces.
|
||||
*/
|
||||
|
||||
enum {
|
||||
enum TraceExecutionFlags {
|
||||
TCL_TRACE_ENTER_DURING_EXEC = 4,
|
||||
/* Trace each command inside the command
|
||||
* currently being traced, before execution.*/
|
||||
* currently being traced, before
|
||||
* execution. */
|
||||
TCL_TRACE_LEAVE_DURING_EXEC = 8,
|
||||
/* Trace each command inside the command
|
||||
* currently being traced, after execution. */
|
||||
@@ -83,8 +84,7 @@ enum {
|
||||
/* The callback function on this trace is
|
||||
* currently executing. Therefore we don't let
|
||||
* further traces execute. */
|
||||
TCL_TRACE_EXEC_DIRECT = 0x20
|
||||
/* This execution trace is triggered directly
|
||||
TCL_TRACE_EXEC_DIRECT = 0x20/* This execution trace is triggered directly
|
||||
* by the command being traced, not because of
|
||||
* an internal trace. */
|
||||
};
|
||||
|
||||
+1
-1
@@ -88,7 +88,7 @@ static ProcessGlobalValue executableName = {
|
||||
*/
|
||||
|
||||
#define COMPAT 1
|
||||
enum {
|
||||
enum FormatListFlags {
|
||||
CONVERT_NONE = 0,
|
||||
CONVERT_BRACE = 2,
|
||||
CONVERT_ESCAPE = 4,
|
||||
|
||||
+71
-258
@@ -21,14 +21,8 @@
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
#endif /* _WIN32*/
|
||||
|
||||
#ifndef EXPOSE_ZIP_COMMENTS
|
||||
/* Tcl API for ZIP comments is disabled for now */
|
||||
#define EXPOSE_ZIP_COMMENTS 0
|
||||
#endif /* !EXPOSE_ZIP_COMMENTS */
|
||||
|
||||
#ifndef MAP_FILE
|
||||
#define MAP_FILE 0
|
||||
#endif /* !MAP_FILE */
|
||||
@@ -36,7 +30,7 @@
|
||||
#define crc32tab crc_table[0]
|
||||
#ifndef TBLS
|
||||
#define TBLS 1
|
||||
#endif /* !TBLS */
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_ZLIB
|
||||
#include "zlib.h"
|
||||
@@ -63,121 +57,60 @@
|
||||
|
||||
/*
|
||||
* Local header of ZIP archive member (at very beginning of each member).
|
||||
*
|
||||
* We'd use structs, except we must work in little-endian even on big-endian
|
||||
* architectures. There isn't a way to tell a known compiler to do that for
|
||||
* us. Also, they're not necessarily aligned, which would be bonus fun.
|
||||
*/
|
||||
|
||||
#if 0
|
||||
struct LocalHeader {
|
||||
uint32_t signature; /* == ZIP_LOCAL_HEADER_SIG */
|
||||
uint16_t version;
|
||||
uint16_t flags;
|
||||
uint16_t compMethod;
|
||||
uint16_t modTime;
|
||||
uint16_t modDate;
|
||||
uint32_t crc32;
|
||||
uint32_t compLen;
|
||||
uint32_t uncompLen;
|
||||
uint32_t pathLen;
|
||||
uint16_t extraLen;
|
||||
};
|
||||
#endif
|
||||
|
||||
#define ZIP_LOCAL_HEADER_SIG 0x04034b50
|
||||
#define ZIP_LOCAL_HEADER_LEN 30
|
||||
enum {
|
||||
ZIP_LOCAL_SIG_OFFS = 0,
|
||||
ZIP_LOCAL_VERSION_OFFS = 4,
|
||||
ZIP_LOCAL_FLAGS_OFFS = 6,
|
||||
ZIP_LOCAL_COMPMETH_OFFS = 8,
|
||||
ZIP_LOCAL_MTIME_OFFS = 10,
|
||||
ZIP_LOCAL_MDATE_OFFS = 12,
|
||||
ZIP_LOCAL_CRC32_OFFS = 14,
|
||||
ZIP_LOCAL_COMPLEN_OFFS = 18,
|
||||
ZIP_LOCAL_UNCOMPLEN_OFFS = 22,
|
||||
ZIP_LOCAL_PATHLEN_OFFS = 26,
|
||||
ZIP_LOCAL_EXTRALEN_OFFS = 28
|
||||
};
|
||||
#define ZIP_LOCAL_SIG_OFFS 0
|
||||
#define ZIP_LOCAL_VERSION_OFFS 4
|
||||
#define ZIP_LOCAL_FLAGS_OFFS 6
|
||||
#define ZIP_LOCAL_COMPMETH_OFFS 8
|
||||
#define ZIP_LOCAL_MTIME_OFFS 10
|
||||
#define ZIP_LOCAL_MDATE_OFFS 12
|
||||
#define ZIP_LOCAL_CRC32_OFFS 14
|
||||
#define ZIP_LOCAL_COMPLEN_OFFS 18
|
||||
#define ZIP_LOCAL_UNCOMPLEN_OFFS 22
|
||||
#define ZIP_LOCAL_PATHLEN_OFFS 26
|
||||
#define ZIP_LOCAL_EXTRALEN_OFFS 28
|
||||
|
||||
/*
|
||||
* Central header of ZIP archive member at end of ZIP file.
|
||||
*/
|
||||
|
||||
#if 0
|
||||
struct CentralHeader {
|
||||
uint32_t signature; /* == ZIP_CENTRAL_HEADER_SIG */
|
||||
uint16_t versionMade;
|
||||
uint16_t version;
|
||||
uint16_t flags;
|
||||
uint16_t compMethod;
|
||||
uint16_t modTime;
|
||||
uint16_t modDate;
|
||||
uint32_t crc32;
|
||||
uint32_t compLen;
|
||||
uint32_t uncompLen;
|
||||
uint16_t pathLen;
|
||||
uint16_t extraLen;
|
||||
uint16_t commentLen;
|
||||
uint16_t diskFile;
|
||||
uint16_t internalAttributes;/* Don't use; always set to 0 */
|
||||
uint32_t externalAttributes;
|
||||
uint32_t localHeaderOffset;
|
||||
};
|
||||
#endif
|
||||
|
||||
#define ZIP_CENTRAL_HEADER_SIG 0x02014b50
|
||||
#define ZIP_CENTRAL_HEADER_LEN 46
|
||||
enum {
|
||||
ZIP_CENTRAL_SIG_OFFS = 0,
|
||||
ZIP_CENTRAL_VERSIONMADE_OFFS = 4,
|
||||
ZIP_CENTRAL_VERSION_OFFS = 6,
|
||||
ZIP_CENTRAL_FLAGS_OFFS = 8,
|
||||
ZIP_CENTRAL_COMPMETH_OFFS = 10,
|
||||
ZIP_CENTRAL_MTIME_OFFS = 12,
|
||||
ZIP_CENTRAL_MDATE_OFFS = 14,
|
||||
ZIP_CENTRAL_CRC32_OFFS = 16,
|
||||
ZIP_CENTRAL_COMPLEN_OFFS = 20,
|
||||
ZIP_CENTRAL_UNCOMPLEN_OFFS = 24,
|
||||
ZIP_CENTRAL_PATHLEN_OFFS = 28,
|
||||
ZIP_CENTRAL_EXTRALEN_OFFS = 30,
|
||||
ZIP_CENTRAL_FCOMMENTLEN_OFFS = 32,
|
||||
ZIP_CENTRAL_DISKFILE_OFFS = 34,
|
||||
ZIP_CENTRAL_IATTR_OFFS = 36,
|
||||
ZIP_CENTRAL_EATTR_OFFS = 38,
|
||||
ZIP_CENTRAL_LOCALHDR_OFFS = 42
|
||||
};
|
||||
#define ZIP_CENTRAL_SIG_OFFS 0
|
||||
#define ZIP_CENTRAL_VERSIONMADE_OFFS 4
|
||||
#define ZIP_CENTRAL_VERSION_OFFS 6
|
||||
#define ZIP_CENTRAL_FLAGS_OFFS 8
|
||||
#define ZIP_CENTRAL_COMPMETH_OFFS 10
|
||||
#define ZIP_CENTRAL_MTIME_OFFS 12
|
||||
#define ZIP_CENTRAL_MDATE_OFFS 14
|
||||
#define ZIP_CENTRAL_CRC32_OFFS 16
|
||||
#define ZIP_CENTRAL_COMPLEN_OFFS 20
|
||||
#define ZIP_CENTRAL_UNCOMPLEN_OFFS 24
|
||||
#define ZIP_CENTRAL_PATHLEN_OFFS 28
|
||||
#define ZIP_CENTRAL_EXTRALEN_OFFS 30
|
||||
#define ZIP_CENTRAL_FCOMMENTLEN_OFFS 32
|
||||
#define ZIP_CENTRAL_DISKFILE_OFFS 34
|
||||
#define ZIP_CENTRAL_IATTR_OFFS 36
|
||||
#define ZIP_CENTRAL_EATTR_OFFS 38
|
||||
#define ZIP_CENTRAL_LOCALHDR_OFFS 42
|
||||
|
||||
/*
|
||||
* Central end signature at very end of ZIP file.
|
||||
*/
|
||||
|
||||
#if 0
|
||||
struct CentralEnd {
|
||||
uint32_t signature; /* == ZIP_CENTRAL_END_SIG */
|
||||
uint16_t diskNumber;
|
||||
uint16_t directoryDisk;
|
||||
uint16_t numEntries;
|
||||
uint16_t totalNumEntries;
|
||||
uint32_t dirSize;
|
||||
uint32_t dirLen;
|
||||
uint16_t commentLen;
|
||||
};
|
||||
#endif
|
||||
|
||||
#define ZIP_CENTRAL_END_SIG 0x06054b50
|
||||
#define ZIP_CENTRAL_END_LEN 22
|
||||
enum {
|
||||
ZIP_CENTRAL_END_SIG_OFFS = 0,
|
||||
ZIP_CENTRAL_DISKNO_OFFS = 4,
|
||||
ZIP_CENTRAL_DISKDIR_OFFS = 6,
|
||||
ZIP_CENTRAL_ENTS_OFFS = 8,
|
||||
ZIP_CENTRAL_TOTALENTS_OFFS = 10,
|
||||
ZIP_CENTRAL_DIRSIZE_OFFS = 12,
|
||||
ZIP_CENTRAL_DIRSTART_OFFS = 16,
|
||||
ZIP_CENTRAL_COMMENTLEN_OFFS = 20
|
||||
};
|
||||
#define ZIP_CENTRAL_END_SIG_OFFS 0
|
||||
#define ZIP_CENTRAL_DISKNO_OFFS 4
|
||||
#define ZIP_CENTRAL_DISKDIR_OFFS 6
|
||||
#define ZIP_CENTRAL_ENTS_OFFS 8
|
||||
#define ZIP_CENTRAL_TOTALENTS_OFFS 10
|
||||
#define ZIP_CENTRAL_DIRSIZE_OFFS 12
|
||||
#define ZIP_CENTRAL_DIRSTART_OFFS 16
|
||||
#define ZIP_CENTRAL_COMMENTLEN_OFFS 20
|
||||
|
||||
#define ZIP_MIN_VERSION 20
|
||||
#define ZIP_COMPMETH_STORED 0
|
||||
@@ -219,6 +152,15 @@ enum {
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* Windows drive letters.
|
||||
*/
|
||||
|
||||
#ifdef _WIN32
|
||||
static const char drvletters[] =
|
||||
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||
#endif /* _WIN32 */
|
||||
|
||||
/*
|
||||
* Mutex to protect localtime(3) when no reentrant version available.
|
||||
*/
|
||||
@@ -249,8 +191,6 @@ typedef struct ZipFile {
|
||||
size_t baseOffset; /* Archive start */
|
||||
size_t passOffset; /* Password start */
|
||||
size_t directoryOffset; /* Archive directory start */
|
||||
char *comment; /* Already converted archive-level comment, if
|
||||
* present. NULL if absent. */
|
||||
unsigned char passBuf[264]; /* Password buffer */
|
||||
size_t numOpen; /* Number of open files on archive */
|
||||
struct ZipEntry *entries; /* List of files in archive */
|
||||
@@ -264,6 +204,7 @@ typedef struct ZipFile {
|
||||
|
||||
/*
|
||||
* In-core description of file contained in mounted ZIP archive.
|
||||
* ZIP_ATTR_
|
||||
*/
|
||||
|
||||
typedef struct ZipEntry {
|
||||
@@ -279,8 +220,6 @@ typedef struct ZipEntry {
|
||||
int timestamp; /* Modification time */
|
||||
int isEncrypted; /* True if data is encrypted */
|
||||
unsigned char *data; /* File data if written */
|
||||
char *comment; /* Already converted file-level comment, if
|
||||
* present. NULL if absent. */
|
||||
struct ZipEntry *next; /* Next file in the same archive */
|
||||
struct ZipEntry *tnext; /* Next top-level dir in archive */
|
||||
} ZipEntry;
|
||||
@@ -892,12 +831,6 @@ CanonicalPath(
|
||||
int haveZipfsPath = 1;
|
||||
|
||||
#ifdef _WIN32
|
||||
/*
|
||||
* Windows drive letters.
|
||||
*/
|
||||
static const char drvletters[] =
|
||||
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||
|
||||
if (tail[0] != '\0' && strchr(drvletters, tail[0]) && tail[1] == ':') {
|
||||
tail += 2;
|
||||
haveZipfsPath = 0;
|
||||
@@ -1180,10 +1113,6 @@ ZipFSCloseArchive(
|
||||
Tcl_Interp *interp, /* Current interpreter. */
|
||||
ZipFile *zf)
|
||||
{
|
||||
if (zf->comment) {
|
||||
ckfree(zf->comment);
|
||||
zf->comment = NULL;
|
||||
}
|
||||
if (zf->nameLength) {
|
||||
ckfree(zf->name);
|
||||
}
|
||||
@@ -1256,7 +1185,6 @@ ZipFSFindTOC(
|
||||
const unsigned char *p, *q;
|
||||
const unsigned char *start = zf->data;
|
||||
const unsigned char *end = zf->data + zf->length;
|
||||
int comlen;
|
||||
|
||||
/*
|
||||
* Scan backwards from the end of the file for the signature. This is
|
||||
@@ -1305,28 +1233,6 @@ ZipFSFindTOC(
|
||||
goto error;
|
||||
}
|
||||
|
||||
/*
|
||||
* Is there a comment?
|
||||
*/
|
||||
|
||||
comlen = ZipReadShort(start, end, p + ZIP_CENTRAL_COMMENTLEN_OFFS);
|
||||
if (comlen) {
|
||||
Tcl_DString ds;
|
||||
const char *c;
|
||||
|
||||
if (p + ZIP_CENTRAL_END_LEN + comlen > end) {
|
||||
ZIPFS_ERROR(interp, "bad zip comment");
|
||||
ZIPFS_ERROR_CODE(interp, "BAD_COMMENT");
|
||||
goto error;
|
||||
}
|
||||
Tcl_DStringInit(&ds);
|
||||
c = DecodeZipEntryText(p + ZIP_CENTRAL_END_LEN, comlen, &ds);
|
||||
comlen = Tcl_DStringLength(&ds) + 1;
|
||||
zf->comment = ckalloc(comlen);
|
||||
memcpy(zf->comment, c, comlen);
|
||||
Tcl_DStringFree(&ds);
|
||||
}
|
||||
|
||||
/*
|
||||
* Where does the central directory start?
|
||||
*/
|
||||
@@ -1352,7 +1258,7 @@ ZipFSFindTOC(
|
||||
zf->directoryOffset = p - zf->data;
|
||||
q = p;
|
||||
for (i = 0; i < zf->numFiles; i++) {
|
||||
int pathlen, extra;
|
||||
int pathlen, comlen, extra;
|
||||
|
||||
if (q + ZIP_CENTRAL_HEADER_LEN > end) {
|
||||
ZIPFS_ERROR(interp, "wrong header length");
|
||||
@@ -1439,7 +1345,6 @@ ZipFSOpenArchive(
|
||||
zf->numFiles = 0;
|
||||
zf->baseOffset = zf->passOffset = 0;
|
||||
zf->ptrToFree = NULL;
|
||||
zf->comment = NULL;
|
||||
zf->passBuf[0] = 0;
|
||||
|
||||
/*
|
||||
@@ -1527,48 +1432,34 @@ ZipMapArchive(
|
||||
ZipFile *zf, /* The archive descriptor structure. */
|
||||
void *handle) /* The OS handle to the open archive. */
|
||||
{
|
||||
#ifdef _WIN32
|
||||
HANDLE hFile = (HANDLE) handle;
|
||||
int readSuccessful;
|
||||
|
||||
/*
|
||||
* Determine the file size.
|
||||
*/
|
||||
|
||||
#ifdef _WIN32
|
||||
HANDLE hFile = (HANDLE) handle;
|
||||
|
||||
# ifdef _WIN64
|
||||
readSuccessful = GetFileSizeEx(hFile, (PLARGE_INTEGER) &zf->length) != 0;
|
||||
# else /* !_WIN64 */
|
||||
zf->length = GetFileSize(hFile, 0);
|
||||
readSuccessful = (zf->length != (size_t) INVALID_FILE_SIZE);
|
||||
# endif /* _WIN64 */
|
||||
#else /* !_WIN32 */
|
||||
int fd = PTR2INT(handle);
|
||||
struct stat st;
|
||||
|
||||
readSuccessful = (fstat(fd, &st) == 0);
|
||||
zf->length = st.st_size;
|
||||
#endif /* _WIN32 */
|
||||
|
||||
if (!readSuccessful) {
|
||||
if (!readSuccessful || (zf->length < ZIP_CENTRAL_END_LEN)) {
|
||||
ZIPFS_POSIX_ERROR(interp, "invalid file size");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if (zf->length < ZIP_CENTRAL_END_LEN) {
|
||||
ZIPFS_ERROR(interp, "illegal file size");
|
||||
ZIPFS_ERROR_CODE(interp, "FILE_SIZE");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Map the file.
|
||||
*/
|
||||
|
||||
#ifdef _WIN32
|
||||
zf->mountHandle = CreateFileMappingW(hFile, 0, PAGE_READONLY, 0,
|
||||
zf->length, 0);
|
||||
if (zf->mountHandle == INVALID_HANDLE_VALUE) {
|
||||
goto badMap;
|
||||
ZIPFS_POSIX_ERROR(interp, "file mapping failed");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
zf->data = (unsigned char *)
|
||||
MapViewOfFile(zf->mountHandle, FILE_MAP_READ, 0, 0, zf->length);
|
||||
@@ -1577,6 +1468,19 @@ ZipMapArchive(
|
||||
return TCL_ERROR;
|
||||
}
|
||||
#else /* !_WIN32 */
|
||||
int fd = PTR2INT(handle);
|
||||
|
||||
/*
|
||||
* Determine the file size.
|
||||
*/
|
||||
|
||||
zf->length = lseek(fd, 0, SEEK_END);
|
||||
if (zf->length == ERROR_LENGTH || zf->length < ZIP_CENTRAL_END_LEN) {
|
||||
ZIPFS_POSIX_ERROR(interp, "invalid file size");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
lseek(fd, 0, SEEK_SET);
|
||||
|
||||
zf->data = (unsigned char *)
|
||||
mmap(0, zf->length, PROT_READ, MAP_FILE | MAP_PRIVATE, fd, 0);
|
||||
if (zf->data == MAP_FAILED) {
|
||||
@@ -1647,7 +1551,7 @@ ZipFSCatalogFilesystem(
|
||||
ZipFile *zf;
|
||||
ZipEntry *z;
|
||||
Tcl_HashEntry *hPtr;
|
||||
Tcl_DString ds, dsm, dsc, fpBuf;
|
||||
Tcl_DString ds, dsm, fpBuf;
|
||||
unsigned char *q;
|
||||
|
||||
/*
|
||||
@@ -1712,7 +1616,6 @@ ZipFSCatalogFilesystem(
|
||||
*/
|
||||
|
||||
*zf = *zf0;
|
||||
zf0->comment = NULL; /* Ownership transferred to zf */
|
||||
zf->mountPoint = (char *) Tcl_GetHashKey(&ZipFS.zipHash, hPtr);
|
||||
Tcl_CreateExitHandler(ZipfsExitHandler, zf);
|
||||
zf->mountPointLen = strlen(zf->mountPoint);
|
||||
@@ -1756,7 +1659,7 @@ ZipFSCatalogFilesystem(
|
||||
int extra, isdir = 0, dosTime, dosDate, nbcompr;
|
||||
size_t offs, pathlen, comlen;
|
||||
unsigned char *lq, *gq = NULL;
|
||||
char *fullpath, *path, *comment = NULL;
|
||||
char *fullpath, *path;
|
||||
|
||||
pathlen = ZipReadShort(start, end, q + ZIP_CENTRAL_PATHLEN_OFFS);
|
||||
comlen = ZipReadShort(start, end, q + ZIP_CENTRAL_FCOMMENTLEN_OFFS);
|
||||
@@ -1770,10 +1673,6 @@ ZipFSCatalogFilesystem(
|
||||
if ((strcmp(path, ".") == 0) || (strcmp(path, "..") == 0)) {
|
||||
goto nextent;
|
||||
}
|
||||
if (comlen) {
|
||||
comment = DecodeZipEntryText(
|
||||
q + ZIP_CENTRAL_HEADER_LEN + pathlen, comlen, &dsc);
|
||||
}
|
||||
lq = zf->data + zf->baseOffset
|
||||
+ ZipReadInt(start, end, q + ZIP_CENTRAL_LOCALHDR_OFFS);
|
||||
if ((lq < start) || (lq + ZIP_LOCAL_HEADER_LEN > end)) {
|
||||
@@ -1832,12 +1731,6 @@ ZipFSCatalogFilesystem(
|
||||
z = AllocateZipEntry();
|
||||
z->depth = CountSlashes(fullpath);
|
||||
z->zipFilePtr = zf;
|
||||
if (comment) {
|
||||
int clen = strlen(comment) + 1;
|
||||
z->comment = ckalloc(clen);
|
||||
memcpy(z->comment, comment, clen);
|
||||
Tcl_DStringFree(&dsc);
|
||||
}
|
||||
z->isDirectory = isdir;
|
||||
z->isEncrypted =
|
||||
(ZipReadShort(start, end, lq + ZIP_LOCAL_FLAGS_OFFS) & 1)
|
||||
@@ -2286,9 +2179,6 @@ TclZipfs_Unmount(
|
||||
if (hPtr) {
|
||||
Tcl_DeleteHashEntry(hPtr);
|
||||
}
|
||||
if (z->comment) {
|
||||
ckfree(z->comment);
|
||||
}
|
||||
if (z->data) {
|
||||
ckfree(z->data);
|
||||
}
|
||||
@@ -2469,10 +2359,8 @@ ZipFSUnmountObjCmd(
|
||||
int objc, /* Number of arguments. */
|
||||
Tcl_Obj *const objv[]) /* Argument objects. */
|
||||
{
|
||||
Tcl_Obj *zipObj;
|
||||
|
||||
if (objc != 2) {
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "mountpoint");
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "zipfile");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
return TclZipfs_Unmount(interp, Tcl_GetString(objv[1]));
|
||||
@@ -3175,7 +3063,7 @@ ZipFSMkZipOrImg(
|
||||
int isMounted = 0;
|
||||
const char *imgName;
|
||||
|
||||
/* TODO: normalize the origin file name */
|
||||
// TODO: normalize the origin file name
|
||||
imgName = (originFile != NULL) ? Tcl_GetString(originFile) :
|
||||
Tcl_GetNameOfExecutable();
|
||||
if (pwlen) {
|
||||
@@ -4079,71 +3967,6 @@ ZipFSTclLibraryObjCmd(
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
*-------------------------------------------------------------------------
|
||||
*
|
||||
* ZipFSCommentObjCmd --
|
||||
*
|
||||
* This procedure is invoked to process the [zipfs comment] command. It
|
||||
* returns the ZIP-level comment of a mounted ZIP, if there is one.
|
||||
* Errors on no such mount. Does nothing in a safe interp.
|
||||
*
|
||||
* Results:
|
||||
* A standard Tcl result.
|
||||
*
|
||||
* Side effects:
|
||||
* None.
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#if EXPOSE_ZIP_COMMENTS
|
||||
static int
|
||||
ZipFSCommentObjCmd(
|
||||
TCL_UNUSED(ClientData),
|
||||
Tcl_Interp *interp, /* Current interpreter. */
|
||||
int objc, /* Number of arguments. */
|
||||
Tcl_Obj *const objv[]) /* Argument objects. */
|
||||
{
|
||||
int result = TCL_OK;
|
||||
|
||||
if (objc != 2) {
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "mountPoint");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if (!Tcl_IsSafe(interp)) {
|
||||
Tcl_DString ds;
|
||||
Tcl_Obj *mountPoint;
|
||||
ZipFile *zf;
|
||||
|
||||
mountPoint = Tcl_FSGetNormalizedPath(interp, objv[1]);
|
||||
if (!mountPoint) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
Tcl_DStringInit(&ds);
|
||||
ReadLock();
|
||||
if (!ZipFS.initialized) {
|
||||
goto noMount;
|
||||
}
|
||||
zf = ZipFSLookupZip(Tcl_GetString(mountPoint));
|
||||
if (!zf) {
|
||||
noMount:
|
||||
ZIPFS_ERROR(interp, "no such mounted zip");
|
||||
ZIPFS_ERROR_CODE(interp, "NO_ZIP");
|
||||
result = TCL_ERROR;
|
||||
goto done;
|
||||
}
|
||||
if (zf->comment) {
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(zf->comment, -1));
|
||||
}
|
||||
done:
|
||||
Unlock();
|
||||
Tcl_DStringFree(&ds);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
#endif /* EXPOSE_ZIP_COMMENTS */
|
||||
|
||||
/*
|
||||
*-------------------------------------------------------------------------
|
||||
*
|
||||
@@ -5498,8 +5321,7 @@ enum ZipFileAttrs {
|
||||
ZIP_ATTR_MOUNT,
|
||||
ZIP_ATTR_ARCHIVE,
|
||||
ZIP_ATTR_PERMISSIONS,
|
||||
ZIP_ATTR_CRC,
|
||||
ZIP_ATTR_COMMENT
|
||||
ZIP_ATTR_CRC
|
||||
};
|
||||
|
||||
static const char *const *
|
||||
@@ -5519,9 +5341,6 @@ ZipFSFileAttrStringsProc(
|
||||
"-archive",
|
||||
"-permissions",
|
||||
"-crc",
|
||||
#if EXPOSE_ZIP_COMMENTS
|
||||
"-comment",
|
||||
#endif /* EXPOSE_ZIP_COMMENTS */
|
||||
NULL,
|
||||
};
|
||||
|
||||
@@ -5595,9 +5414,6 @@ ZipFSFileAttrsGetProc(
|
||||
case ZIP_ATTR_CRC:
|
||||
TclNewIntObj(*objPtrRef, z->crc32);
|
||||
break;
|
||||
case ZIP_ATTR_COMMENT:
|
||||
*objPtrRef = Tcl_NewStringObj(z->zipFilePtr->comment, -1);
|
||||
break;
|
||||
default:
|
||||
ZIPFS_ERROR(interp, "unknown attribute");
|
||||
ZIPFS_ERROR_CODE(interp, "FILE_ATTR");
|
||||
@@ -5811,9 +5627,6 @@ TclZipfs_Init(
|
||||
{"mount_data", ZipFSMountBufferObjCmd, NULL, NULL, NULL, 1},
|
||||
{"unmount", ZipFSUnmountObjCmd, NULL, NULL, NULL, 1},
|
||||
{"mkkey", ZipFSMkKeyObjCmd, NULL, NULL, NULL, 1},
|
||||
#if EXPOSE_ZIP_COMMENTS
|
||||
{"comment", ZipFSCommentObjCmd, NULL, NULL, NULL, 1},
|
||||
#endif /* EXPOSE_ZIP_COMMENTS */
|
||||
{"exists", ZipFSExistsObjCmd, NULL, NULL, NULL, 0},
|
||||
{"info", ZipFSInfoObjCmd, NULL, NULL, NULL, 0},
|
||||
{"list", ZipFSListObjCmd, NULL, NULL, NULL, 0},
|
||||
|
||||
+11
-15
@@ -130,22 +130,18 @@ typedef struct {
|
||||
} ZlibChannelData;
|
||||
|
||||
/*
|
||||
* Value bits for the flags field. Definitions are:
|
||||
* ASYNC - Whether this is an asynchronous channel.
|
||||
* IN_HEADER - Whether the inHeader field has been registered with
|
||||
* the input compressor.
|
||||
* OUT_HEADER - Whether the outputHeader field has been registered
|
||||
* with the output decompressor.
|
||||
* STREAM_DECOMPRESS - Signal decompress pending data.
|
||||
* STREAM_DONE - Flag to signal stream end up to transform input.
|
||||
* Value bits for the flags field:
|
||||
*/
|
||||
|
||||
enum {
|
||||
ASYNC = 0x01,
|
||||
IN_HEADER = 0x02,
|
||||
OUT_HEADER = 0x04,
|
||||
STREAM_DECOMPRESS = 0x08,
|
||||
STREAM_DONE = 0x10
|
||||
enum ZlibChannelFlags {
|
||||
ASYNC = 0x01, /* Whether this is an asynchronous channel. */
|
||||
IN_HEADER = 0x02, /* Whether the inHeader field has been
|
||||
* registered with the input compressor. */
|
||||
OUT_HEADER = 0x04, /* Whether the outputHeader field has been
|
||||
* registered with the output decompressor. */
|
||||
STREAM_DECOMPRESS = 0x08, /* Signal decompress pending data. */
|
||||
STREAM_DONE = 0x10 /* Flag to signal stream end up to transform
|
||||
* input. */
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -216,7 +212,7 @@ static const Tcl_ChannelType zlibChannelType = {
|
||||
ZlibTransformGetOption,
|
||||
ZlibTransformWatch,
|
||||
ZlibTransformGetHandle,
|
||||
ZlibTransformClose, /* close2Proc */
|
||||
ZlibTransformClose, /* close2Proc */
|
||||
ZlibTransformBlockMode,
|
||||
NULL, /* flushProc */
|
||||
ZlibTransformEventHandler,
|
||||
|
||||
@@ -32,12 +32,11 @@ extern int copyfile(const char *from, const char *to,
|
||||
#else /* HAVE_COPYFILE_H */
|
||||
int copyfile(const char *from, const char *to,
|
||||
void *state, uint32_t flags);
|
||||
enum {
|
||||
enum copyfileFlags {
|
||||
COPYFILE_ACL = (1<<0),
|
||||
COPYFILE_XATTR = (1<<2),
|
||||
COPYFILE_NOFOLLOW_SRC = (1<<18)
|
||||
};
|
||||
|
||||
#if defined(HAVE_WEAK_IMPORT) && (MAC_OS_X_VERSION_MIN_REQUIRED < 1040)
|
||||
/* Support for weakly importing copyfile. */
|
||||
#define WEAK_IMPORT_COPYFILE
|
||||
@@ -692,7 +691,7 @@ SetOSTypeFromAny(
|
||||
|
||||
static void
|
||||
UpdateStringOfOSType(
|
||||
Tcl_Obj *objPtr) /* OSType object whose string rep to
|
||||
Tcl_Obj *objPtr) /* OSType object whose string rep to
|
||||
* update. */
|
||||
{
|
||||
const int size = TCL_UTF_MAX * 4;
|
||||
|
||||
+3
-39
@@ -96,7 +96,7 @@ test zipfs-1.3 {zipfs errors} -constraints zipfs -returnCodes error -body {
|
||||
} -result {wrong # args: should be "zipfs mount ?mountpoint? ?zipfile? ?password?"}
|
||||
test zipfs-1.4 {zipfs errors} -constraints zipfs -returnCodes error -body {
|
||||
zipfs unmount a b c d e f
|
||||
} -result {wrong # args: should be "zipfs unmount mountpoint"}
|
||||
} -result {wrong # args: should be "zipfs unmount zipfile"}
|
||||
test zipfs-1.5 {zipfs errors} -constraints zipfs -returnCodes error -body {
|
||||
zipfs mkkey a b c d e f
|
||||
} -result {wrong # args: should be "zipfs mkkey password"}
|
||||
@@ -380,36 +380,6 @@ test zipfs-4.5 {zipfs lmkimg: making image from mounted} -constraints zipfs -set
|
||||
removeFile $targetImage
|
||||
removeFile $addFile
|
||||
} -result {//zipfs://ziptest/test/add.tcl //zipfs://ziptest/test/ok.tcl}
|
||||
if 0 {
|
||||
test zipfs-4.6 {zipfs lmkimg: making image with comment} -constraints zipfs -setup {
|
||||
set baseImage [makeFile "return sourceWorking\n\x1A" base_image.tcl]
|
||||
set targetImage [makeFile "" target_image.tcl]
|
||||
set addFile [makeFile "return mountWorking" add.data]
|
||||
file delete $midImage $targetImage
|
||||
proc addComment {zipfile commentData} {
|
||||
set len [binary format s [string length $commentData]]
|
||||
set f [open $zipfile r+b]
|
||||
try {
|
||||
chan seek $f -2 end
|
||||
puts -nonewline $f $len$commentData
|
||||
} finally {
|
||||
close $f
|
||||
}
|
||||
}
|
||||
} -body {
|
||||
zipfs lmkimg $targetImage [list $addFile test/ok.tcl] {} $baseImage
|
||||
addComment $targetImage "gorp"
|
||||
zipfs mount ziptest $targetImage
|
||||
list [glob -directory //zipfs://ziptest/test *.tcl] \
|
||||
[zipfs comment //zipfs://ziptest/]
|
||||
} -cleanup {
|
||||
zipfs unmount ziptest
|
||||
removeFile $baseImage
|
||||
removeFile $midImage
|
||||
removeFile $targetImage
|
||||
removeFile $addFile
|
||||
} -result {//zipfs://ziptest/test/ok.tcl gorp}
|
||||
}
|
||||
|
||||
test zipfs-5.1 {zipfs mount_data: short data} -constraints zipfs -body {
|
||||
zipfs mount_data gorp {}
|
||||
@@ -420,16 +390,10 @@ test zipfs-5.2 {zipfs mount_data: short data} -constraints zipfs -body {
|
||||
test zipfs-5.3 {zipfs mount_data: short data} -constraints zipfs -body {
|
||||
set data PK\x03\x04.....................................
|
||||
append data PK\x01\x02.....................................
|
||||
append data PK\x05\x06................\x01\x00...................
|
||||
append data PK\x05\x06.....................................
|
||||
zipfs mount_data gorp $data
|
||||
} -returnCodes error -result {bad zip data}
|
||||
test zipfs-5.4 {zipfs mount_data: short data} -constraints zipfs -body {
|
||||
set data PK\x03\x04.....................................
|
||||
append data PK\x01\x02.....................................
|
||||
append data PK\x05\x06................\x00\x01...................
|
||||
zipfs mount_data gorp $data
|
||||
} -returnCodes error -result {bad zip comment}
|
||||
test zipfs-5.5 {zipfs mount_data: bad arg count} -constraints zipfs -body {
|
||||
test zipfs-5.4 {zipfs mount_data: bad arg count} -constraints zipfs -body {
|
||||
zipfs mount_data gorp {} foobar
|
||||
} -returnCodes error -result {wrong # args: should be "zipfs mount_data ?mountpoint? ?data?"}
|
||||
|
||||
|
||||
@@ -175,14 +175,14 @@ static pthread_cond_t notifierCV = PTHREAD_COND_INITIALIZER;
|
||||
* The pollState bits:
|
||||
*/
|
||||
|
||||
enum {
|
||||
POLL_WANT = 0x1, /* Set by each thread before it waits on its
|
||||
enum PollStateFlags {
|
||||
POLL_WANT = 0x1, /* Set by each thread before it waits on its
|
||||
* condition variable. It is checked by the
|
||||
* notifier before it does select. */
|
||||
POLL_DONE = 0x2 /* Set by the notifier if it goes into select
|
||||
* after seeing POLL_WANT. The idea is to
|
||||
* ensure it tries a select with the same bits
|
||||
* the initial thread had set. */
|
||||
* notifier before it does select(). */
|
||||
POLL_DONE = 0x2 /* Set by the notifier if it goes into
|
||||
* select() after seeing POLL_WANT. The idea
|
||||
* is to ensure it tries a select() with the
|
||||
* same bits the initial thread had set. */
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
+1
-1
@@ -57,7 +57,7 @@
|
||||
* TraverseUnixTree() calls the traverseProc()
|
||||
*/
|
||||
|
||||
enum {
|
||||
enum DoTreeOps {
|
||||
DOTREE_PRED = 1, /* pre-order directory */
|
||||
DOTREE_POSTD = 2, /* post-order directory */
|
||||
DOTREE_F = 3, /* regular file */
|
||||
|
||||
+6
-6
@@ -66,7 +66,7 @@ struct TcpState {
|
||||
|
||||
Tcl_TcpAcceptProc *acceptProc;
|
||||
/* Proc to call on accept. */
|
||||
void *acceptProcData; /* The data for the accept proc. */
|
||||
void *acceptProcData; /* The data for the accept proc. */
|
||||
|
||||
/*
|
||||
* Only needed for client sockets
|
||||
@@ -87,10 +87,10 @@ struct TcpState {
|
||||
* structure.
|
||||
*/
|
||||
|
||||
enum {
|
||||
enum TcpStateFlags {
|
||||
TCP_NONBLOCKING = (1<<0), /* Socket with non-blocking I/O */
|
||||
TCP_ASYNC_CONNECT = (1<<1), /* Async connect in progress. */
|
||||
TCP_ASYNC_PENDING = (1<<4), /* TcpConnect was called to process an async
|
||||
TCP_ASYNC_CONNECT = (1<<1), /* Async connect in progress. */
|
||||
TCP_ASYNC_PENDING = (1<<4), /* TcpConnect was called to process an async
|
||||
* connect. This flag indicates that reentry
|
||||
* is still pending */
|
||||
TCP_ASYNC_FAILED = (1<<5) /* An async connect finally failed */
|
||||
@@ -101,7 +101,7 @@ enum {
|
||||
* structure.
|
||||
*/
|
||||
|
||||
enum {
|
||||
enum TcpStateTestFlags {
|
||||
TCP_ASYNC_TEST_MODE = (1<<0)/* Async testing activated. Do not
|
||||
* automatically continue connection
|
||||
* process. */
|
||||
@@ -1078,7 +1078,7 @@ WrapNotify(
|
||||
|
||||
static void
|
||||
TcpWatchProc(
|
||||
void *instanceData, /* The socket state. */
|
||||
void *instanceData, /* The socket state. */
|
||||
int mask) /* Events of interest; an OR-ed combination of
|
||||
* TCL_READABLE, TCL_WRITABLE and
|
||||
* TCL_EXCEPTION. */
|
||||
|
||||
+4
-4
@@ -17,15 +17,15 @@
|
||||
* State flags used in the info structures below.
|
||||
*/
|
||||
|
||||
enum {
|
||||
enum FileStateFlags {
|
||||
FILE_PENDING = (1<<0), /* Message is pending in the queue. */
|
||||
FILE_ASYNC = (1<<1), /* Channel is non-blocking. */
|
||||
FILE_APPEND = (1<<2) /* File is in append mode. */
|
||||
};
|
||||
|
||||
enum {
|
||||
FILE_TYPE_SERIAL = (FILE_TYPE_PIPE + 1),
|
||||
FILE_TYPE_CONSOLE = (FILE_TYPE_PIPE + 2)
|
||||
enum SpecialFileTypes {
|
||||
FILE_TYPE_SERIAL = (FILE_TYPE_PIPE+1),
|
||||
FILE_TYPE_CONSOLE = (FILE_TYPE_PIPE+2)
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
+13
-15
@@ -31,7 +31,7 @@ TCL_DECLARE_MUTEX(consoleMutex)
|
||||
* Bit masks used in the flags field of the ConsoleInfo structure below.
|
||||
*/
|
||||
|
||||
enum {
|
||||
enum ConsoleInfoFlags {
|
||||
CONSOLE_PENDING = (1<<0), /* Message is pending in the queue. */
|
||||
CONSOLE_ASYNC = (1<<1), /* Channel is non-blocking. */
|
||||
CONSOLE_READ_OPS = (1<<4), /* Channel supports read-related ops. */
|
||||
@@ -42,7 +42,7 @@ enum {
|
||||
* Bit masks used in the sharedFlags field of the ConsoleInfo structure below.
|
||||
*/
|
||||
|
||||
enum {
|
||||
enum ConsoleInfoSharedFlags {
|
||||
CONSOLE_EOF = (1<<2), /* Console has reached EOF. */
|
||||
CONSOLE_BUFFERED = (1<<3) /* Data was read into a buffer by the reader
|
||||
* thread. */
|
||||
@@ -223,17 +223,16 @@ ReadConsoleBytes(
|
||||
BOOL result;
|
||||
|
||||
/*
|
||||
* If user types a Ctrl-Break or Ctrl-C, ReadConsole will return
|
||||
* success with ntchars == 0 and GetLastError() will be
|
||||
* ERROR_OPERATION_ABORTED. We do not want to treat this case
|
||||
* as EOF so we will loop around again. If no Ctrl signal handlers
|
||||
* have been established, the default signal OS handler in a separate
|
||||
* thread will terminate the program. If a Ctrl signal handler
|
||||
* has been established (through an extension for example), it
|
||||
* will run and take whatever action it deems appropriate.
|
||||
* If user types a Ctrl-Break or Ctrl-C, ReadConsole will return success
|
||||
* with ntchars == 0 and GetLastError() will be ERROR_OPERATION_ABORTED.
|
||||
* We do not want to treat this case as EOF so we will loop around again.
|
||||
* If no Ctrl signal handlers have been established, the default signal OS
|
||||
* handler in a separate thread will terminate the program. If a Ctrl
|
||||
* signal handler has been established (through an extension for example),
|
||||
* it will run and take whatever action it deems appropriate.
|
||||
*/
|
||||
do {
|
||||
result = ReadConsoleW(hConsole, lpBuffer, nbytes / sizeof(WCHAR),
|
||||
result = ReadConsoleW(hConsole, lpBuffer, nbytes / sizeof(WCHAR),
|
||||
&ntchars, NULL);
|
||||
} while (result && ntchars == 0 &&
|
||||
GetLastError() == ERROR_OPERATION_ABORTED);
|
||||
@@ -760,9 +759,9 @@ ConsoleOutputProc(
|
||||
*errorCode = 0;
|
||||
|
||||
/* avoid blocking if pipe-thread exited */
|
||||
timeout = (infoPtr->flags & CONSOLE_ASYNC) ||
|
||||
timeout = ((infoPtr->flags & CONSOLE_ASYNC) ||
|
||||
!TclPipeThreadIsAlive(&threadInfo->TI) || TclInExit() ||
|
||||
TclInThreadExit() ? 0 : INFINITE;
|
||||
TclInThreadExit()) ? 0 : INFINITE;
|
||||
if (WaitForSingleObject(threadInfo->readyEvent, timeout) == WAIT_TIMEOUT) {
|
||||
/*
|
||||
* The writer thread is blocked waiting for a write to complete and
|
||||
@@ -1043,8 +1042,7 @@ WaitForRead(
|
||||
/* avoid blocking if pipe-thread exited */
|
||||
timeout = (!blocking || !TclPipeThreadIsAlive(&threadInfo->TI)
|
||||
|| TclInExit() || TclInThreadExit()) ? 0 : INFINITE;
|
||||
if (WaitForSingleObject(threadInfo->readyEvent,
|
||||
timeout) == WAIT_TIMEOUT) {
|
||||
if (WaitForSingleObject(threadInfo->readyEvent, timeout) == WAIT_TIMEOUT) {
|
||||
/*
|
||||
* The reader thread is blocked waiting for data and the channel
|
||||
* is in non-blocking mode.
|
||||
|
||||
+11
-23
@@ -84,7 +84,7 @@ static int ddeIsServer = 0;
|
||||
#define TCL_DDE_SERVICE_NAME L"TclEval"
|
||||
#define TCL_DDE_EXECUTE_RESULT L"$TCLEVAL$EXECUTE$RESULT"
|
||||
|
||||
enum {
|
||||
enum TclDdeFlags {
|
||||
DDE_FLAG_ASYNC = 1,
|
||||
DDE_FLAG_BINARY = 2,
|
||||
DDE_FLAG_FORCE = 4
|
||||
@@ -392,13 +392,10 @@ DdeSetServerName(
|
||||
lastSuffix = suffix;
|
||||
if (suffix > 1) {
|
||||
if (suffix == 2) {
|
||||
Tcl_DStringAppend(&dString, (char *)name,
|
||||
wcslen(name) * sizeof(WCHAR));
|
||||
Tcl_DStringAppend(&dString, (char *)L" #",
|
||||
2 * sizeof(WCHAR));
|
||||
Tcl_DStringAppend(&dString, (char *)name, wcslen(name) * sizeof(WCHAR));
|
||||
Tcl_DStringAppend(&dString, (char *)L" #", 2 * sizeof(WCHAR));
|
||||
offset = Tcl_DStringLength(&dString);
|
||||
Tcl_DStringSetLength(&dString,
|
||||
offset + sizeof(WCHAR) * TCL_INTEGER_SPACE);
|
||||
Tcl_DStringSetLength(&dString, offset + sizeof(WCHAR) * TCL_INTEGER_SPACE);
|
||||
actualName = (WCHAR *) Tcl_DStringValue(&dString);
|
||||
}
|
||||
_snwprintf((WCHAR *) (Tcl_DStringValue(&dString) + offset),
|
||||
@@ -1152,14 +1149,12 @@ DdeServicesOnAck(
|
||||
GlobalGetAtomNameW(service, sz, 255);
|
||||
Tcl_DStringInit(&dString);
|
||||
Tcl_WCharToUtfDString(sz, wcslen(sz), &dString);
|
||||
Tcl_ListObjAppendElement(NULL, matchPtr,
|
||||
Tcl_NewStringObj(Tcl_DStringValue(&dString), -1));
|
||||
Tcl_ListObjAppendElement(NULL, matchPtr, Tcl_NewStringObj(Tcl_DStringValue(&dString), -1));
|
||||
Tcl_DStringFree(&dString);
|
||||
GlobalGetAtomNameW(topic, sz, 255);
|
||||
Tcl_DStringInit(&dString);
|
||||
Tcl_WCharToUtfDString(sz, wcslen(sz), &dString);
|
||||
Tcl_ListObjAppendElement(NULL, matchPtr,
|
||||
Tcl_NewStringObj(Tcl_DStringValue(&dString), -1));
|
||||
Tcl_ListObjAppendElement(NULL, matchPtr, Tcl_NewStringObj(Tcl_DStringValue(&dString), -1));
|
||||
Tcl_DStringFree(&dString);
|
||||
|
||||
/*
|
||||
@@ -1585,19 +1580,15 @@ DdeObjCmd(
|
||||
}
|
||||
|
||||
ddeData = DdeCreateDataHandle(ddeInstance, (BYTE *) dataString,
|
||||
(DWORD) dataLength, 0, 0,
|
||||
(flags & DDE_FLAG_BINARY) ? CF_TEXT : CF_UNICODETEXT, 0);
|
||||
(DWORD) dataLength, 0, 0, (flags & DDE_FLAG_BINARY) ? CF_TEXT : CF_UNICODETEXT, 0);
|
||||
if (ddeData != NULL) {
|
||||
if (flags & DDE_FLAG_ASYNC) {
|
||||
DdeClientTransaction((LPBYTE) ddeData, 0xFFFFFFFF, hConv, 0,
|
||||
(flags & DDE_FLAG_BINARY) ? CF_TEXT : CF_UNICODETEXT,
|
||||
XTYP_EXECUTE, TIMEOUT_ASYNC, &ddeResult);
|
||||
(flags & DDE_FLAG_BINARY) ? CF_TEXT : CF_UNICODETEXT, XTYP_EXECUTE, TIMEOUT_ASYNC, &ddeResult);
|
||||
DdeAbandonTransaction(ddeInstance, hConv, ddeResult);
|
||||
} else {
|
||||
ddeReturn = DdeClientTransaction((LPBYTE) ddeData, 0xFFFFFFFF,
|
||||
hConv, 0,
|
||||
(flags & DDE_FLAG_BINARY) ? CF_TEXT : CF_UNICODETEXT,
|
||||
XTYP_EXECUTE, 30000, NULL);
|
||||
hConv, 0, (flags & DDE_FLAG_BINARY) ? CF_TEXT : CF_UNICODETEXT, XTYP_EXECUTE, 30000, NULL);
|
||||
if (ddeReturn == 0) {
|
||||
SetDdeError(interp);
|
||||
result = TCL_ERROR;
|
||||
@@ -1641,8 +1632,7 @@ DdeObjCmd(
|
||||
CP_WINUNICODE);
|
||||
if (ddeItem != NULL) {
|
||||
ddeData = DdeClientTransaction(NULL, 0, hConv, ddeItem,
|
||||
(flags & DDE_FLAG_BINARY) ? CF_TEXT : CF_UNICODETEXT,
|
||||
XTYP_REQUEST, 5000, NULL);
|
||||
(flags & DDE_FLAG_BINARY) ? CF_TEXT : CF_UNICODETEXT, XTYP_REQUEST, 5000, NULL);
|
||||
if (ddeData == NULL) {
|
||||
SetDdeError(interp);
|
||||
result = TCL_ERROR;
|
||||
@@ -1722,9 +1712,7 @@ DdeObjCmd(
|
||||
CP_WINUNICODE);
|
||||
if (ddeItem != NULL) {
|
||||
ddeData = DdeClientTransaction(dataString, (DWORD) length,
|
||||
hConv, ddeItem,
|
||||
(flags & DDE_FLAG_BINARY) ? CF_TEXT : CF_UNICODETEXT,
|
||||
XTYP_POKE, 5000, NULL);
|
||||
hConv, ddeItem, (flags & DDE_FLAG_BINARY) ? CF_TEXT : CF_UNICODETEXT, XTYP_POKE, 5000, NULL);
|
||||
if (ddeData == NULL) {
|
||||
SetDdeError(interp);
|
||||
result = TCL_ERROR;
|
||||
|
||||
+2
-2
@@ -17,11 +17,11 @@
|
||||
* TraverseWinTree() calls the traverseProc()
|
||||
*/
|
||||
|
||||
enum {
|
||||
enum DotreeTypes {
|
||||
DOTREE_PRED = 1, /* pre-order directory */
|
||||
DOTREE_POSTD = 2, /* post-order directory */
|
||||
DOTREE_F = 3, /* regular file */
|
||||
DOTREE_LINK = 4, /* symbolic link */
|
||||
DOTREE_LINK = 4 /* symbolic link */
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
+9
-11
@@ -32,7 +32,7 @@ TCL_DECLARE_MUTEX(pipeMutex)
|
||||
* under windows. There is special case code for the various types.
|
||||
*/
|
||||
|
||||
enum {
|
||||
enum ApplicationTypes {
|
||||
APPL_NONE = 0,
|
||||
APPL_DOS = 1,
|
||||
APPL_WIN3X = 2,
|
||||
@@ -69,20 +69,18 @@ typedef struct ProcInfo {
|
||||
|
||||
static ProcInfo *procList;
|
||||
|
||||
/*
|
||||
* Bit masks used in the flags field of the PipeInfo structure below.
|
||||
*/
|
||||
enum PipeInfoFlags {
|
||||
/*
|
||||
* Bit masks used in the flags field of the PipeInfo structure below.
|
||||
*/
|
||||
|
||||
enum {
|
||||
PIPE_PENDING = (1<<0), /* Message is pending in the queue. */
|
||||
PIPE_ASYNC = (1<<1) /* Channel is non-blocking. */
|
||||
};
|
||||
PIPE_ASYNC = (1<<1), /* Channel is non-blocking. */
|
||||
|
||||
/*
|
||||
* Bit masks used in the sharedFlags field of the PipeInfo structure below.
|
||||
*/
|
||||
/*
|
||||
* Bit masks used in the sharedFlags field of the PipeInfo structure below.
|
||||
*/
|
||||
|
||||
enum {
|
||||
PIPE_EOF = (1<<2), /* Pipe has reached EOF. */
|
||||
PIPE_EXTRABYTE = (1<<3) /* The reader thread has consumed one byte. */
|
||||
};
|
||||
|
||||
+15
-17
@@ -29,30 +29,28 @@ static int initialized = 0;
|
||||
|
||||
TCL_DECLARE_MUTEX(serialMutex)
|
||||
|
||||
/*
|
||||
* Bit masks used in the flags field of the SerialInfo structure below.
|
||||
*/
|
||||
enum SerialInfoFlags {
|
||||
/*
|
||||
* Bit masks used in the flags field of the SerialInfo structure below.
|
||||
*/
|
||||
|
||||
enum {
|
||||
SERIAL_PENDING = (1<<0), /* Message is pending in the queue. */
|
||||
SERIAL_ASYNC = (1<<1) /* Channel is non-blocking. */
|
||||
};
|
||||
SERIAL_ASYNC = (1<<1), /* Channel is non-blocking. */
|
||||
|
||||
/*
|
||||
* Bit masks used in the sharedFlags field of the SerialInfo structure below.
|
||||
*/
|
||||
/*
|
||||
* Bit masks used in the sharedFlags field of the SerialInfo structure
|
||||
* below.
|
||||
*/
|
||||
|
||||
enum {
|
||||
SERIAL_EOF = (1<<2), /* Serial has reached EOF. */
|
||||
SERIAL_ERROR = (1<<4)
|
||||
};
|
||||
SERIAL_ERROR = (1<<4),
|
||||
|
||||
/*
|
||||
* Bit masks used for noting whether to drain or discard output on close. They
|
||||
* are disjoint from each other; at most one may be set at a time.
|
||||
*/
|
||||
/*
|
||||
* Bit masks used for noting whether to drain or discard output on
|
||||
* close. They are disjoint from each other; at most one may be set at a
|
||||
* time.
|
||||
*/
|
||||
|
||||
enum {
|
||||
SERIAL_CLOSE_DRAIN = (1<<6),/* Drain all output on close. */
|
||||
SERIAL_CLOSE_DISCARD = (1<<7),
|
||||
/* Discard all output on close. */
|
||||
|
||||
+22
-19
@@ -174,14 +174,14 @@ struct TcpState {
|
||||
* structure.
|
||||
*/
|
||||
|
||||
enum {
|
||||
enum TcpStateFlags {
|
||||
TCP_NONBLOCKING = (1<<0), /* Socket with non-blocking I/O */
|
||||
TCP_ASYNC_CONNECT = (1<<1), /* Async connect in progress. */
|
||||
SOCKET_EOF = (1<<2), /* A zero read happened on the socket. */
|
||||
SOCKET_EOF = (1<<2), /* A zero read happened on the socket. */
|
||||
SOCKET_PENDING = (1<<3), /* A message has been sent for this socket */
|
||||
TCP_ASYNC_PENDING = (1<<4), /* TcpConnect was called to process an async
|
||||
* connect. This flag indicates that reentry
|
||||
* is still pending */
|
||||
* is still pending. */
|
||||
TCP_ASYNC_FAILED = (1<<5) /* An async connect finally failed */
|
||||
};
|
||||
|
||||
@@ -190,7 +190,7 @@ enum {
|
||||
* structure.
|
||||
*/
|
||||
|
||||
enum {
|
||||
enum TcpStateTestFlags {
|
||||
TCP_ASYNC_TEST_MODE = (1<<0)/* Async testing activated. Do not
|
||||
* automatically continue connection
|
||||
* process */
|
||||
@@ -242,8 +242,7 @@ static WNDCLASSW windowClass;
|
||||
* Static routines for this file:
|
||||
*/
|
||||
|
||||
static int TcpConnect(Tcl_Interp *interp,
|
||||
TcpState *state);
|
||||
static int TcpConnect(Tcl_Interp *interp, TcpState *state);
|
||||
static void InitSockets(void);
|
||||
static TcpState * NewSocketInfo(SOCKET socket);
|
||||
static void SocketExitHandler(ClientData clientData);
|
||||
@@ -318,6 +317,11 @@ static ProcessGlobalValue hostName =
|
||||
SendMessageW((tsdPtr)->hwnd, SOCKET_SELECT, \
|
||||
(WPARAM) (message), (LPARAM) (payload))
|
||||
|
||||
/*
|
||||
* The name of a variable that may be changed to suppress reverse DNS lookups.
|
||||
*/
|
||||
|
||||
#define SUPPRESS_RDNS_VAR "::tcl::unsupported::noReverseDNS"
|
||||
|
||||
/*
|
||||
* Address print debug functions
|
||||
@@ -373,7 +377,8 @@ InitializeHostName(
|
||||
Tcl_DString ds;
|
||||
|
||||
Tcl_DStringInit(&ds);
|
||||
if (GetComputerNameExW(ComputerNamePhysicalDnsFullyQualified, wbuf, &length) != 0) {
|
||||
if (GetComputerNameExW(ComputerNamePhysicalDnsFullyQualified, wbuf,
|
||||
&length) != 0) {
|
||||
/*
|
||||
* Convert string from native to UTF then change to lowercase.
|
||||
*/
|
||||
@@ -1154,11 +1159,13 @@ TcpClose2Proc(
|
||||
* TCL_WRITABLE so this should never be called for a server socket.
|
||||
*/
|
||||
|
||||
if ((flags & TCL_CLOSE_READ) && (shutdown(statePtr->sockets->fd, SD_RECEIVE) == SOCKET_ERROR)) {
|
||||
if ((flags & TCL_CLOSE_READ) &&
|
||||
(shutdown(statePtr->sockets->fd, SD_RECEIVE) == SOCKET_ERROR)) {
|
||||
Tcl_WinConvertError((DWORD) WSAGetLastError());
|
||||
readError = Tcl_GetErrno();
|
||||
}
|
||||
if ((flags & TCL_CLOSE_WRITE) && (shutdown(statePtr->sockets->fd, SD_SEND) == SOCKET_ERROR)) {
|
||||
if ((flags & TCL_CLOSE_WRITE) &&
|
||||
(shutdown(statePtr->sockets->fd, SD_SEND) == SOCKET_ERROR)) {
|
||||
Tcl_WinConvertError((DWORD) WSAGetLastError());
|
||||
writeError = Tcl_GetErrno();
|
||||
}
|
||||
@@ -1301,7 +1308,6 @@ TcpGetOptionProc(
|
||||
SOCKET sock;
|
||||
size_t len = 0;
|
||||
int reverseDNS = 0;
|
||||
#define SUPPRESS_RDNS_VAR "::tcl::unsupported::noReverseDNS"
|
||||
|
||||
/*
|
||||
* Check that WinSock is initialized; do not call it if not, to prevent
|
||||
@@ -1384,8 +1390,7 @@ TcpGetOptionProc(
|
||||
|
||||
if (err) {
|
||||
Tcl_WinConvertError(err);
|
||||
Tcl_DStringAppend(dsPtr, Tcl_ErrnoMsg(Tcl_GetErrno()),
|
||||
-1);
|
||||
Tcl_DStringAppend(dsPtr, Tcl_ErrnoMsg(Tcl_GetErrno()), -1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2445,9 +2450,9 @@ TcpAccept(
|
||||
|
||||
if (statePtr->acceptProc != NULL) {
|
||||
getnameinfo(&(addr.sa), len, host, sizeof(host), port, sizeof(port),
|
||||
NI_NUMERICHOST|NI_NUMERICSERV);
|
||||
NI_NUMERICHOST | NI_NUMERICSERV);
|
||||
statePtr->acceptProc(statePtr->acceptProcData, newInfoPtr->channel,
|
||||
host, atoi(port));
|
||||
host, atoi(port));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3012,8 +3017,7 @@ AddSocketInfoFd(
|
||||
fds->statePtr = statePtr;
|
||||
fds->next = NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
@@ -3068,10 +3072,9 @@ NewSocketInfo(SOCKET socket)
|
||||
|
||||
static int
|
||||
WaitForSocketEvent(
|
||||
TcpState *statePtr, /* Information about this socket. */
|
||||
TcpState *statePtr, /* Information about this socket. */
|
||||
int events, /* Events to look for. May be one of
|
||||
* FD_READ or FD_WRITE.
|
||||
*/
|
||||
* FD_READ or FD_WRITE. */
|
||||
int *errorCodePtr) /* Where to store errors? */
|
||||
{
|
||||
int result = 1;
|
||||
|
||||
+9
-13
@@ -92,7 +92,7 @@ static Tcl_ThreadDataKey dataKey;
|
||||
* State bits for the thread.
|
||||
*/
|
||||
|
||||
enum {
|
||||
enum ThreadStateBits {
|
||||
WIN_THREAD_UNINIT = 0x0, /* Uninitialized. Must be zero because of the
|
||||
* way ThreadSpecificData is created. */
|
||||
WIN_THREAD_RUNNING = 0x1, /* Running, not waiting. */
|
||||
@@ -130,10 +130,10 @@ typedef struct {
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
LPTHREAD_START_ROUTINE lpStartAddress;
|
||||
LPTHREAD_START_ROUTINE lpStartAddress;
|
||||
/* Original startup routine */
|
||||
LPVOID lpParameter; /* Original startup data */
|
||||
unsigned int fpControl; /* Floating point control word from the
|
||||
LPVOID lpParameter; /* Original startup data */
|
||||
unsigned int fpControl; /* Floating point control word from the
|
||||
* main thread */
|
||||
} WinThread;
|
||||
|
||||
@@ -208,7 +208,7 @@ TclpThreadCreate(
|
||||
int flags) /* Flags controlling behaviour of the new
|
||||
* thread. */
|
||||
{
|
||||
WinThread *winThreadPtr; /* Per-thread startup info */
|
||||
WinThread *winThreadPtr; /* Per-thread startup info */
|
||||
HANDLE tHandle;
|
||||
|
||||
winThreadPtr = (WinThread *)ckalloc(sizeof(WinThread));
|
||||
@@ -218,9 +218,9 @@ TclpThreadCreate(
|
||||
|
||||
EnterCriticalSection(&joinLock);
|
||||
|
||||
*idPtr = 0; /* must initialize as Tcl_Thread is a pointer and
|
||||
* on WIN64 sizeof void* != sizeof unsigned
|
||||
*/
|
||||
*idPtr = 0; /* must initialize as Tcl_Thread is a pointer
|
||||
* and on WIN64 sizeof(void*) !=
|
||||
* sizeof(unsigned) */
|
||||
|
||||
#if defined(_MSC_VER) || defined(__MSVCRT__)
|
||||
tHandle = (HANDLE) _beginthreadex(NULL, (unsigned) stackSize,
|
||||
@@ -660,7 +660,7 @@ void
|
||||
Tcl_ConditionWait(
|
||||
Tcl_Condition *condPtr, /* Really (WinCondition **) */
|
||||
Tcl_Mutex *mutexPtr, /* Really (CRITICAL_SECTION **) */
|
||||
const Tcl_Time *timePtr) /* Timeout on waiting period */
|
||||
const Tcl_Time *timePtr) /* Timeout on waiting period */
|
||||
{
|
||||
WinCondition *winCondPtr; /* Per-condition queue head */
|
||||
CRITICAL_SECTION *csPtr; /* Caller's Mutex, after casting */
|
||||
@@ -927,9 +927,6 @@ TclpFinalizeCondition(
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Additions by AOL for specialized thread memory allocator.
|
||||
*/
|
||||
@@ -1031,7 +1028,6 @@ TclpFreeAllocCache(
|
||||
}
|
||||
#endif /* USE_THREAD_ALLOC */
|
||||
|
||||
|
||||
void *
|
||||
TclpThreadCreateKey(void)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user